add export bage

This commit is contained in:
Donghuang 2022-06-23 17:29:32 +08:00
parent b3a3cf5ec8
commit 126575f0bf
60 changed files with 566 additions and 323 deletions

View File

@ -53,7 +53,7 @@ public class ExportTaskServiceSupport
@Override @Override
public void doExport(final String employeeKey) { public void doExport(final String employeeKey) {
val now = Long.valueOf(System.currentTimeMillis()); val now = Long.valueOf(System.currentTimeMillis());
Assert.state(now.equals(LOCK_MAP.putIfAbsent(employeeKey, now)), Assert.state(LOCK_MAP.putIfAbsent(employeeKey, now) == null,
"There is a running export task, please try again later!"); "There is a running export task, please try again later!");
threadPoolTaskExecutor.execute(() ->{ threadPoolTaskExecutor.execute(() ->{

View File

@ -1,37 +1,46 @@
server: server:
port: 8088 port: 8088
spring: spring:
servlet: jackson:
multipart: default-property-inclusion: NON_NULL
max-file-size: 512MB time-zone: GMT+8
max-request-size: 512MB serialization:
write-dates-as-timestamps: true
fail-on-empty-beans: false
servlet:
multipart:
max-file-size: 512MB
max-request-size: 512MB
datasource: datasource:
database-name: ambition-crm database-name: ambition-crm
host: 172.16.4.6 host: 172.16.4.6
password: MySQL2b||!2b password: MySQL2b||!2b
port: 3306 port: 3306
username: root username: root
database: database:
backup-dir: /Users/chyxion/Workspaces/ambition-crm/database_backups backup-dir: /Users/chyxion/Workspaces/ambition-crm/database_backups
restore-shell: /data/program/mysql-backup/bin/mysql_restore.sh restore-shell: /data/program/mysql-backup/bin/mysql_restore.sh
file: file:
base-dir: /Users/donghuang/Documents/Workspaces/ambition-crm/files/ base-dir: /Users/donghuang/Documents/Workspaces/ambition-crm/files/
base-path: http://127.0.0.1:1217/lm-f/ base-path: http://127.0.0.1:1217/lm-f/
export:
location: d:/data/export
tigon: tigon:
shiro: shiro:
session: session:
validation: validation:
scheduler: scheduler:
enabled: true enabled: true
filter-chain: > filter-chain: >
/auth/login=anon /auth/login=anon
/=anon /=anon
/index.html=anon /index.html=anon
/assets/**=anon /assets/**=anon
/f/**=anon /f/**=anon
/**=user /**=user

View File

@ -1,37 +1,46 @@
server: server:
port: 8088 port: 8088
spring: spring:
servlet: jackson:
multipart: default-property-inclusion: NON_NULL
max-file-size: 512MB time-zone: GMT+8
max-request-size: 512MB serialization:
write-dates-as-timestamps: true
fail-on-empty-beans: false
servlet:
multipart:
max-file-size: 512MB
max-request-size: 512MB
datasource: datasource:
database-name: ambition-crm database-name: ambition-crm
host: 172.16.4.6 host: 172.16.4.6
password: MySQL2b||!2b password: MySQL2b||!2b
port: 3306 port: 3306
username: root username: root
database: database:
backup-dir: /Users/chyxion/Workspaces/ambition-crm/database_backups backup-dir: d:/data/database_backups
restore-shell: /data/program/mysql-backup/bin/mysql_restore.sh restore-shell: /data/program/mysql-backup/bin/mysql_restore.sh
file: file:
base-dir: /Users/donghuang/Documents/Workspaces/ambition-crm/files/ base-dir: /Users/donghuang/Documents/Workspaces/ambition-crm/files/
base-path: http://127.0.0.1:1217/lm-f/ base-path: http://127.0.0.1:1217/lm-f/
export:
location: d:/data/export
tigon: tigon:
shiro: shiro:
session: session:
validation: validation:
scheduler: scheduler:
enabled: true enabled: true
filter-chain: > filter-chain: >
/auth/login=anon /auth/login=anon
/=anon /=anon
/index.html=anon /index.html=anon
/assets/**=anon /assets/**=anon
/f/**=anon /f/**=anon
/**=user /**=user

@ -1 +1 @@
Subproject commit 56a42f79cac7f8369bacf51e323242c0ae202e55 Subproject commit 1c57bdaf5ab05684239ea1a1e50d33730095d464

View File

@ -33,7 +33,7 @@ public interface CustomerMapper extends BaseMapper<String, Customer> {
* @return customers * @return customers
*/ */
List<Customer> listForShow( List<Customer> listForShow(
@NotNull @Param("s") Search search, @NotNull @Param(PARAM_SEARCH_KEY) Search search,
@Param("account") String account); @Param("account") String account);
/** /**
@ -67,7 +67,7 @@ public interface CustomerMapper extends BaseMapper<String, Customer> {
* @return count of customers * @return count of customers
*/ */
int countForShow( int countForShow(
@NotNull @Param("s") Search search, @NotNull @Param(PARAM_SEARCH_KEY) Search search,
@Param("account") String account); @Param("account") String account);
List<Map<String, String>> listMs(); List<Map<String, String>> listMs();

View File

@ -234,24 +234,24 @@
<sql id="showFilter"> <sql id="showFilter">
<!-- Application not null --> <!-- Application not null -->
<if test="s.getAttr('APPLICATION_NOT_NULL') != null"> <if test="__search__.getAttr('APPLICATION_NOT_NULL') != null">
join (select distinct customer_id join (select distinct customer_id
from crm_customer_application) app_not_null from crm_customer_application) app_not_null
on customer.id = app_not_null.customer_id on customer.id = app_not_null.customer_id
</if> </if>
<if test="s.getAttr('APPLICATIONS') != null"> <if test="__search__.getAttr('APPLICATIONS') != null">
join (select distinct customer_id join (select distinct customer_id
from crm_customer_application from crm_customer_application
where application_id in where application_id in
<foreach item="appId" collection="s.getAttr('APPLICATIONS')" open="(" close=")" separator=","> <foreach item="appId" collection="__search__.getAttr('APPLICATIONS')" open="(" close=")" separator=",">
#{appId} #{appId}
</foreach> </foreach>
) app ) app
on customer.id = app.customer_id on customer.id = app.customer_id
</if> </if>
<if test="s.getAttr('YTD_SALE') != null"> <if test="__search__.getAttr('YTD_SALE') != null">
left join (select customer_id, max(year) year left join (select customer_id, max(year) year
from crm_customer_year_to_date_sale from crm_customer_year_to_date_sale
where enabled = 1 where enabled = 1

View File

@ -18,12 +18,12 @@ public interface ImportRecordMapper extends BaseMapper<String, ImportRecord> {
* @param search search * @param search search
* @return import records * @return import records
*/ */
List<ImportRecord> listForShow(@Param("s") Search search); List<ImportRecord> listForShow(@Param(PARAM_SEARCH_KEY) Search search);
/** /**
* count for show * count for show
* @param search search * @param search search
* @return count of import records * @return count of import records
*/ */
int countForShow(@Param("s") Search search); int countForShow(@Param(PARAM_SEARCH_KEY) Search search);
} }

View File

@ -20,14 +20,14 @@ public interface WeekGoalMapper extends BaseMapper<String, WeekGoal> {
* @param search search * @param search search
* @return week goals * @return week goals
*/ */
List<WeekGoal> listJoinUser(@Param("s") Search search); List<WeekGoal> listJoinUser(@Param(PARAM_SEARCH_KEY) Search search);
/** /**
* count join user * count join user
* @param search search * @param search search
* @return count of week goals * @return count of week goals
*/ */
int countJoinUser(@Param("s") Search search); int countJoinUser(@Param(PARAM_SEARCH_KEY) Search search);
/** /**
* @return list user * @return list user

View File

@ -37,6 +37,11 @@
<artifactId>tigon-web</artifactId> <artifactId>tigon-web</artifactId>
<scope>${tigon.webmvc.scope}</scope> <scope>${tigon.webmvc.scope}</scope>
</dependency> </dependency>
<dependency>
<groupId>me.chyxion.tigon</groupId>
<artifactId>tigon-mybatis</artifactId>
<scope>provided</scope>
</dependency>
<dependency> <dependency>
<groupId>org.projectlombok</groupId> <groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId> <artifactId>lombok</artifactId>

View File

@ -3,8 +3,12 @@ package me.chyxion.tigon.model;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import java.util.Date; import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
import me.chyxion.tigon.mybatis.NotUpdate; import me.chyxion.tigon.mybatis.NotUpdate;
import org.apache.commons.lang3.StringUtils;
import lombok.experimental.FieldNameConstants; import lombok.experimental.FieldNameConstants;
import me.chyxion.tigon.mybatis.util.EntityUtils;
/** /**
* @version 0.0.1 * @version 0.0.1
@ -43,4 +47,16 @@ public class M1<Id> extends M0<Id> {
super.beforeUpdate(); super.beforeUpdate();
dateUpdated = new Date(); dateUpdated = new Date();
} }
public List<String> cols() {
return EntityUtils.cols(getClass());
}
public List<String> cols(final String table) {
if (StringUtils.isBlank(table)) {
return cols();
}
return cols().stream().map(it -> table + "." + it).collect(Collectors.toList());
}
} }

0
server/launch.sh → server/start.sh Executable file → Normal file
View File

View File

@ -1,14 +1,12 @@
import Ember from 'ember'; import Application from '@ember/application';
import Resolver from './resolver'; import Resolver from './resolver';
import loadInitializers from 'ember-load-initializers'; import loadInitializers from 'ember-load-initializers';
import config from './config/environment'; import config from './config/environment';
import $ from 'jquery'; import $ from 'jquery';
let App;
// Ember.MODEL_FACTORY_INJECTIONS = true; // Ember.MODEL_FACTORY_INJECTIONS = true;
App = Ember.Application.extend({ const App = Application.extend({
modulePrefix: config.modulePrefix, modulePrefix: config.modulePrefix,
podModulePrefix: config.podModulePrefix, podModulePrefix: config.podModulePrefix,
Resolver Resolver

View File

@ -0,0 +1,8 @@
import Component from '@ember/component';
export default Component.extend({
tagName: 'a',
classNames: ['cursor-pointer'],
attributeBindings: ['title', 'href', 'target'],
'data-rel': 'tooltip'
});

View File

@ -1,4 +0,0 @@
import Ember from 'ember';
import BaseComponentMixin from '../mixins/components/base-component';
export default Ember.Component.extend(BaseComponentMixin, {});

View File

@ -1,23 +1,24 @@
import Ember from 'ember'; import { computed } from '@ember/object';
import BaseComponentMixin from '../mixins/components/base-component'; import { alias } from '@ember/object/computed';
import BasicComponent from './basic-component';
export default Ember.Component.extend(BaseComponentMixin, { export default BasicComponent.extend({
'col-width': 6, 'col-width': 6,
colWidth: Ember.computed.alias('col-width'), colWidth: alias('col-width'),
classNameBindings: ['hasError:has-error'], classNameBindings: ['hasError:has-error'],
model: Ember.computed.alias('route.controller.model'), model: alias('route.controller.model'),
errors: Ember.computed.alias('route.controller.errors'), errors: alias('route.controller.errors'),
hasError: Ember.computed('errors', function() { hasError: computed('errors', function() {
return this.get('errors.' + this.get('name')); return this.get('errors.' + this.get('name'));
}), }),
'error-msg': true, 'error-msg': true,
errorMsg: Ember.computed.alias('error-msg'), errorMsg: alias('error-msg'),
'label-class': 'col-xs-12 col-sm-3 col-md-3', 'label-class': 'col-xs-12 col-sm-3 col-md-3',
labelClass: Ember.computed.alias('label-class'), labelClass: alias('label-class'),
'input-class': 'col-xs-12 col-sm-5 col-md-5', 'input-class': 'col-xs-12 col-sm-5 col-md-5',
inputClass: Ember.computed.alias('input-class'), inputClass: alias('input-class'),
'data-scope': 'model', 'data-scope': 'model',
dataScope: Ember.computed.alias('data-scope'), dataScope: alias('data-scope'),
didReceiveAttrs() { didReceiveAttrs() {
let me = this; let me = this;
me._super(...arguments); me._super(...arguments);

View File

@ -9,8 +9,8 @@ export default Component.extend({
routeName: alias('router.currentRouteName'), routeName: alias('router.currentRouteName'),
'trim-index': true, 'trim-index': true,
route: computed('routeName', function() { route: computed('routeName', function() {
let me = this; const me = this;
let routeName = me.get('routeName'); const routeName = me.get('routeName');
return me.getRoute(me.get('trim-index') ? return me.getRoute(me.get('trim-index') ?
routeName.replace(/\.index$/, '') : routeName); routeName.replace(/\.index$/, '') : routeName);
}), }),

View File

@ -1,9 +1,8 @@
import Ember from 'ember'; import { computed } from '@ember/object';
import BaseComponentMixin from '../mixins/components/base-component'; import BasicComponent from './basic-component';
export default Ember.Component.extend(BaseComponentMixin, { export default BasicComponent.extend({
// breadcrumbs: Ember.computed.alias('route.breadcrumbs'), breadcrumbs: computed('route', function() {
breadcrumbs: Ember.computed('route', function() {
let me = this; let me = this;
let breadcrumbs = this.get('route.breadcrumbs'); let breadcrumbs = this.get('route.breadcrumbs');
if (!breadcrumbs) { if (!breadcrumbs) {

View File

@ -1,7 +1,8 @@
import Ember from 'ember'; import Ember from 'ember';
import { alias } from '@ember/object/computed';
export default Ember.Component.extend({ export default Ember.Component.extend({
tagName: 'span', tagName: 'span',
value: Ember.computed.alias('model'), value: alias('model'),
format: 'YYYY-MM-DD H:mm:ss' format: 'YYYY-MM-DD H:mm:ss'
}); });

View File

@ -1,16 +1,15 @@
import Ember from 'ember'; import { alias } from '@ember/object/computed';
import BaseComponent from './basic-component';
import BaseComponent from './base-component';
export default BaseComponent.extend({ export default BaseComponent.extend({
tagName: 'a', tagName: 'a',
attributeBindings: ['title'], attributeBindings: ['title'],
'data-rel': 'tooltip', 'data-rel': 'tooltip',
enabled: Ember.computed.alias('model.enabled'), enabled: alias('model.enabled'),
title: 'Delete', title: 'Delete',
'icon-size-class': 'bigger-120', 'icon-size-class': 'bigger-120',
didReceiveAttrs() { didReceiveAttrs() {
let me = this; const me = this;
me._super(...arguments); me._super(...arguments);
if (me.get('icon-only')) { if (me.get('icon-only')) {
me.set('icon-size-class', 'bigger-130'); me.set('icon-size-class', 'bigger-130');
@ -24,7 +23,7 @@ export default BaseComponent.extend({
} }
}, },
click() { click() {
let me = this; const me = this;
me.dialog.confirm('Are you sure to delete?', () => { me.dialog.confirm('Are you sure to delete?', () => {
me.get('service').del(me.get('model.id')).then(() => { me.get('service').del(me.get('model.id')).then(() => {
me.get('route.controller.model.data').removeObject(me.get('model')); me.get('route.controller.model.data').removeObject(me.get('model'));

View File

@ -1,10 +1,11 @@
import Ember from 'ember'; import { alias } from '@ember/object/computed';
import BaseComponent from './base-component'; import { later } from '@ember/runloop';
import BaseComponent from './basic-component';
import $ from 'jquery'; import $ from 'jquery';
export default BaseComponent.extend({ export default BaseComponent.extend({
'allow-blank': true, 'allow-blank': true,
allowBlank: Ember.computed.alias('allow-blank'), allowBlank: alias('allow-blank'),
type: 'text', type: 'text',
step: 1, // for number step: 1, // for number
'confirm-update': true, 'confirm-update': true,
@ -14,12 +15,12 @@ export default BaseComponent.extend({
const me = this; const me = this;
me.set('oldValue', me.getFieldValue()); me.set('oldValue', me.getFieldValue());
me.set('isEditing', true) me.set('isEditing', true)
Ember.run.later(() => { later(() => {
$('input[type="text"][name="' + me.get('model.id') + '"]', me.element).focus(); $('input[type="text"][name="' + me.get('model.id') + '"]', me.element).focus();
}, 320); }, 320);
}, },
doUpdate() { doUpdate() {
let me = this; const me = this;
if (me.get('isUpdating')) { if (me.get('isUpdating')) {
console.info('Cell Is Updating, Ignore.'); console.info('Cell Is Updating, Ignore.');
return; return;
@ -60,7 +61,7 @@ export default BaseComponent.extend({
return this.get('model.' + this.get('field')); return this.get('model.' + this.get('field'));
}, },
resetValue() { resetValue() {
let me = this; const me = this;
me.set('model.' + me.get('field'), me.get('oldValue')); me.set('model.' + me.get('field'), me.get('oldValue'));
}, },
execUpdate() { execUpdate() {

View File

@ -1,11 +1,10 @@
import Ember from 'ember';
import Component from '@ember/component'; import Component from '@ember/component';
import { computed } from '@ember/object'; import { alias } from '@ember/object/computed';
import $ from 'jquery' import $ from 'jquery'
export default Component.extend({ export default Component.extend({
file: {}, file: {},
value: computed.alias('file.file'), value: alias('file.file'),
'no-file': 'Choose file', 'no-file': 'Choose file',
'btn-choose': 'Choose file', 'btn-choose': 'Choose file',
didReceiveAttrs() { didReceiveAttrs() {

View File

@ -1,6 +1,8 @@
import Ember from 'ember'; import BaseComponent from './basic-component';
import BaseComponent from './base-component'; import { alias } from '@ember/object/computed';
import { computed } from '@ember/object'; import { isArray } from '@ember/array';
import { setProperties } from '@ember/object';
import { isNone } from '@ember/utils';
import { inject as service } from '@ember/service'; import { inject as service } from '@ember/service';
import $ from 'jquery' import $ from 'jquery'
@ -9,12 +11,12 @@ export default BaseComponent.extend({
type: 'create', type: 'create',
form: true, form: true,
state: service('state'), state: service('state'),
successMsg: computed.alias('success-message'), successMsg: alias('success-message'),
postUrl: computed.alias('post-url'), postUrl: alias('post-url'),
backRouteName: computed.alias('back-route'), backRouteName: alias('back-route'),
backRouteParams: computed.alias('back-route-params'), backRouteParams: alias('back-route-params'),
hideGoback: computed.alias('no-goback'), hideGoback: alias('no-goback'),
hideSubmit: computed.alias('no-submit'), hideSubmit: alias('no-submit'),
'back-to-list': false, 'back-to-list': false,
backToList() { backToList() {
const me = this; const me = this;
@ -29,20 +31,20 @@ export default BaseComponent.extend({
transitionToRoute(name, params, queryParams) { transitionToRoute(name, params, queryParams) {
const me = this; const me = this;
let args = [name]; let args = [name];
if (!Ember.isNone(params)) { if (!isNone(params)) {
if (Ember.isArray(params)) { if (isArray(params)) {
args = args.concat(params); args = args.concat(params);
} }
else if (params !== false) { else if (params !== false) {
args.push(params); args.push(params);
} }
} }
Ember.isNone(queryParams) || args.push({queryParams: queryParams}); isNone(queryParams) || args.push({queryParams: queryParams});
me.get('router').transitionTo(...args); me.get('router').transitionTo(...args);
}, },
actions: { actions: {
goback() { goback() {
let me = this; const me = this;
let routeName = me.get('backRouteName'); let routeName = me.get('backRouteName');
if (routeName) { if (routeName) {
me.transitionToRoute(routeName, me.transitionToRoute(routeName,
@ -57,13 +59,13 @@ export default BaseComponent.extend({
} }
}, },
save() { save() {
let me = this; const me = this;
if (!me.validate()) { if (!me.validate()) {
me.dialog.confirm('Are you sure to submit?', () => { me.dialog.confirm('Are you sure to submit?', () => {
me.postData().then((m) => { me.postData().then((m) => {
console.info('Post Model Result: ', m); console.info('Post Model Result: ', m);
// write back // write back
Ember.setProperties(me.getModel(), m); setProperties(me.getModel(), m);
me.alertMessage(); me.alertMessage();
me.send('goback'); me.send('goback');
}); });
@ -75,7 +77,7 @@ export default BaseComponent.extend({
return this.get('type') === 'create'; return this.get('type') === 'create';
}, },
validate() { validate() {
let me = this; const me = this;
let vr = me.get('service').validate( let vr = me.get('service').validate(
me.getModel(), me.get('type') + 'Constraints'); me.getModel(), me.get('type') + 'Constraints');
me.set('route.controller.errors', vr || {}); me.set('route.controller.errors', vr || {});

View File

@ -1,12 +1,13 @@
import Ember from 'ember'; import { computed } from '@ember/object';
import { match } from '@ember/object/computed';
import BaseFormInput from './base-form-input'; import BaseFormInput from './base-form-input';
export default BaseFormInput.extend({ export default BaseFormInput.extend({
classNames: ['form-group'], classNames: ['form-group'],
classNameBindings: ['hasError:has-error'], classNameBindings: ['hasError:has-error'],
hasError: Ember.computed('route.controller.errors', function() { hasError: computed('route.controller.errors', function() {
return this.get('errors.' + this.get('idField')); return this.get('errors.' + this.get('idField'));
}), }),
btnIcon: 'fa-server', btnIcon: 'fa-server',
isFaBtnIcon: Ember.computed.match('btnIcon', /^fa-/) isFaBtnIcon: match('btnIcon', /^fa-/)
}); });

View File

@ -1,10 +1,10 @@
import Component from '@ember/component'; import Component from '@ember/component';
import { computed } from '@ember/object'; import { alias } from '@ember/object/computed';
import $ from 'jquery' import $ from 'jquery'
export default Component.extend({ export default Component.extend({
image: {}, image: {},
value: computed.alias('image.file'), value: alias('image.file'),
didReceiveAttrs() { didReceiveAttrs() {
const me = this; const me = this;
me._super(...arguments); me._super(...arguments);

View File

@ -1,4 +1,4 @@
import Ember from 'ember'; import { once } from '@ember/runloop';
import Component from '@ember/component'; import Component from '@ember/component';
import { computed } from '@ember/object'; import { computed } from '@ember/object';
import $ from 'jquery' import $ from 'jquery'
@ -50,7 +50,7 @@ export default Component.extend({
} }
}); });
Ember.run.once(() => { once(() => {
// add a custom loading icon // add a custom loading icon
$('#cboxLoadingGraphic').html('<i class="ace-icon fa fa-spinner orange fa-spin"></i>'); $('#cboxLoadingGraphic').html('<i class="ace-icon fa fa-spinner orange fa-spin"></i>');
}); });

View File

@ -1,9 +1,9 @@
import Ember from 'ember'; import { alias } from '@ember/object/computed';
import BaseComponentMixin from '../mixins/components/base-component'; import BasicComponent from './basic-component';
export default Ember.Component.extend(BaseComponentMixin, { export default BasicComponent.extend({
tagName: 'label', tagName: 'label',
selectedId: Ember.computed.alias('route.controller.selectedId'), selectedId: alias('route.controller.selectedId'),
selectedModel: Ember.computed.alias('route.controller.selectedModel'), selectedModel: alias('route.controller.selectedModel'),
classNames: ['pos-rel'] classNames: ['pos-rel']
}); });

View File

@ -1,13 +1,17 @@
import Component from '@ember/component'; import Component from '@ember/component';
import { inject as service } from '@ember/service';
import $ from 'jquery' import $ from 'jquery'
export default Component.extend({ export default Component.extend({
elementId: 'main-container', elementId: 'main-container',
classNames: ['main-container'], classNames: ['main-container'],
exportTaskService: service('export-task/service'),
sidebarCollapsed: false, sidebarCollapsed: false,
didInsertElement() { didInsertElement() {
let me = this; const me = this;
me._super(...arguments); me._super(...arguments);
me.get('exportTaskService').startup();
// $('body').removeClass().addClass('login-layout blur-login'); // $('body').removeClass().addClass('login-layout blur-login');
(function($) { (function($) {
basics(); basics();
@ -298,8 +302,6 @@ export default Component.extend({
}) })
} }
//in small devices display navbar dropdowns like modal boxes //in small devices display navbar dropdowns like modal boxes
function smallDeviceDropdowns() { function smallDeviceDropdowns() {
if(ace.vars['old_ie']) return; if(ace.vars['old_ie']) return;

View File

@ -1,8 +1,7 @@
import Component from '@ember/component' import BasicComponent from './basic-component';
import BaseComponentMixin from '../mixins/components/base-component';
import $ from 'jquery' import $ from 'jquery'
export default Component.extend(BaseComponentMixin, { export default BasicComponent.extend({
classNames: ['modal', 'fade'], classNames: ['modal', 'fade'],
'init-modal': true, 'init-modal': true,
'close-to-parent': true, 'close-to-parent': true,

View File

@ -8,8 +8,8 @@ export default Ember.LinkComponent.extend(BaseComponentMixin, {
title: '操作详情', title: '操作详情',
activeClass: '', activeClass: '',
willRender() { willRender() {
let me = this; const me = this;
let params = me.get('params'); const params = me.get('params');
params.unshift(me.get('service.modelName')); params.unshift(me.get('service.modelName'));
params.unshift('op-detail'); params.unshift('op-detail');
params.unshift('操作详情'); params.unshift('操作详情');

View File

@ -1,21 +1,21 @@
import Ember from 'ember'; import BaseComponent from './basic-component';
import BaseComponent from './base-component';
import { computed } from '@ember/object'; import { computed } from '@ember/object';
import { alias } from '@ember/object/computed';
export default BaseComponent.extend({ export default BaseComponent.extend({
classNames: ['widget-toolbox', 'clearfix'], classNames: ['widget-toolbox', 'clearfix'],
total: Ember.computed.alias('route.controller.model.total'), total: alias('route.controller.model.total'),
prevPage: computed('currPage', function() { prevPage: computed('currPage', function() {
return this.get('currPage') - 1 || 1; return this.get('currPage') - 1 || 1;
}), }),
nextPage: computed('currPage', function() { nextPage: computed('currPage', function() {
let me = this; const me = this;
let page = me.get('currPage'); const page = me.get('currPage');
return page + 1 <= me.get('totalPage') ? page + 1 : page; return page + 1 <= me.get('totalPage') ? page + 1 : page;
}), }),
currPage: computed('params.page', function() { currPage: computed('params.page', function() {
let me = this; const me = this;
let currPage = parseInt(me.get('params.page')); const currPage = parseInt(me.get('params.page'));
console.info('Get current page [' + currPage + ']'); console.info('Get current page [' + currPage + ']');
return currPage; return currPage;
}), }),
@ -23,7 +23,7 @@ export default BaseComponent.extend({
const me = this; const me = this;
const totalPage = me.get('totalPage'); const totalPage = me.get('totalPage');
const currPage = me.get('currPage'); const currPage = me.get('currPage');
let pages = []; const pages = [];
if (currPage > 4) { if (currPage > 4) {
pages.push({page: 1, text: 1}); pages.push({page: 1, text: 1});
@ -59,7 +59,7 @@ export default BaseComponent.extend({
allPages: computed('total', function() { allPages: computed('total', function() {
const me = this; const me = this;
const totalPage = me.get('totalPage'); const totalPage = me.get('totalPage');
let pages = []; const pages = [];
let i = 0; let i = 0;
while (++i <= totalPage) { while (++i <= totalPage) {
@ -68,15 +68,15 @@ export default BaseComponent.extend({
return pages; return pages;
}), }),
totalPage: computed('total', function() { totalPage: computed('total', function() {
let me = this; const me = this;
let pageSize = me.get('service.pageSize') || 32; const pageSize = me.get('service.pageSize') || 32;
return parseInt((me.get('total') + pageSize - 1) / pageSize); return parseInt((me.get('total') + pageSize - 1) / pageSize);
}), }),
actions: { actions: {
gotoPage(page) { gotoPage(page) {
let me = this; const me = this;
let router = me.get('router'); const router = me.get('router');
let params = me.get('params'); const params = me.get('params');
console.info('Go to page [' + page + '], params: ', params); console.info('Go to page [' + page + '], params: ', params);
router.transitionTo(me.get('routeName'), page, {queryParams: params}); router.transitionTo(me.get('routeName'), page, {queryParams: params});
} }

View File

@ -1,5 +1,4 @@
import Ember from 'ember'; import BaseComponent from './basic-component';
import BaseComponent from './base-component';
export default BaseComponent.extend({ export default BaseComponent.extend({
tagName: 'a', tagName: 'a',

View File

@ -1,12 +1,12 @@
import Ember from 'ember'; import { oneWay } from '@ember/object/computed';
import BaseComponentMixin from '../mixins/components/base-component'; import BasicComponent from './basic-component';
export default Ember.Component.extend(BaseComponentMixin, { export default BasicComponent.extend({
classNames: ['widget-toolbar', 'no-border', 'no-padding'], classNames: ['widget-toolbar', 'no-border', 'no-padding'],
searchText: Ember.computed.oneWay('route.controller.search'), searchText: oneWay('route.controller.search'),
actions: { actions: {
search() { search() {
let me = this; const me = this;
me.set('route.controller.search', me.get('searchText')); me.set('route.controller.search', me.get('searchText'));
} }
} }

View File

@ -1,43 +1,43 @@
import Ember from 'ember'; import { computed } from '@ember/object';
import BaseComponentMixin from '../mixins/components/base-component'; import BasicComponent from './basic-component';
export default Ember.Component.extend(BaseComponentMixin, { export default BasicComponent.extend({
tagName: 'th', tagName: 'th',
order: Ember.computed('route.controller.orders', function() { order: computed('route.controller.orders', function() {
return this.getDir(); return this.getDir();
}), }),
sorting: Ember.computed.none('order'), sorting: computed.none('order'),
asc: Ember.computed.equal('order', 'asc'), asc: computed.equal('order', 'asc'),
desc: Ember.computed.equal('order', 'desc'), desc: computed.equal('order', 'desc'),
// classNameBindings: ['asc:sorting_asc', 'desc:sorting_desc', 'sorting:sorting'], // classNameBindings: ['asc:sorting_asc', 'desc:sorting_desc', 'sorting:sorting'],
attributeBindings: ['style'], attributeBindings: ['style'],
getDir() { getDir() {
let me = this; const me = this;
let name = me.get('name'); const name = me.get('name');
let orders = me.getOrders(); const orders = me.getOrders();
if (orders && orders.length) { if (orders && orders.length) {
let order = orders.find(order => order.hasOwnProperty(name)); const order = orders.find(order => order.hasOwnProperty(name));
if (order) { if (order) {
return order[name]; return order[name];
} }
} }
}, },
getOrders() { getOrders() {
let me = this; const me = this;
let strOrders = me.get('route.controller.orders'); const strOrders = me.get('route.controller.orders');
if (strOrders) { if (strOrders) {
return JSON.parse(strOrders); return JSON.parse(strOrders);
} }
}, },
actions: { actions: {
sort() { sort() {
let me = this; const me = this;
let orders = me.getOrders() || []; let orders = me.getOrders() || [];
let name = me.get('name'); const name = me.get('name');
if (orders.length) { if (orders.length) {
orders = orders.filter(order => !order.hasOwnProperty(name)); orders = orders.filter(order => !order.hasOwnProperty(name));
} }
let order = {}; const order = {};
order[name] = order[name] =
me.get('order') === 'asc' ? me.get('order') === 'asc' ?
'desc' : 'asc'; 'desc' : 'asc';
@ -46,10 +46,10 @@ export default Ember.Component.extend(BaseComponentMixin, {
me.set('route.controller.orders', JSON.stringify(orders)); me.set('route.controller.orders', JSON.stringify(orders));
}, },
removeSort() { removeSort() {
let me = this; const me = this;
let orders = me.getOrders(); const orders = me.getOrders();
if (orders) { if (orders) {
let name = me.get('name'); const name = me.get('name');
me.set('route.controller.orders', me.set('route.controller.orders',
JSON.stringify(orders.filter(order => !order.hasOwnProperty(name)))); JSON.stringify(orders.filter(order => !order.hasOwnProperty(name))));
} }

View File

@ -1,23 +1,25 @@
import Ember from 'ember'; import Component from '@ember/component';
import { addObserver } from '@ember/object/observers';
import { computed } from '@ember/object';
export default Ember.Component.extend({ export default Component.extend({
tagName: 'span', tagName: 'span',
classNames: ['label', 'label-sm'], classNames: ['label', 'label-sm'],
classNameBindings: ['enabled:label-success:label-warning'], classNameBindings: ['enabled:label-success:label-warning'],
field: 'enabled', field: 'enabled',
name: Ember.computed.alias('field'), name: computed.alias('field'),
didReceiveAttrs() { didReceiveAttrs() {
let me = this; const me = this;
me._super(...arguments); me._super(...arguments);
me.set('enabled', me.get(me.getFieldPath())); me.set('enabled', me.get(me.getFieldPath()));
Ember.addObserver(me, me.getFieldPath(), function() { addObserver(me, me.getFieldPath(), function() {
me.set('enabled', me.get(me.getFieldPath())); me.set('enabled', me.get(me.getFieldPath()));
}); });
}, },
enabledText: '启用', enabledText: '启用',
disabledText: '禁用', disabledText: '禁用',
getFieldPath() { getFieldPath() {
let me = this; const me = this;
return 'model.' + (me.get('field') || 'enabled'); return 'model.' + (me.get('field') || 'enabled');
}, },
}); });

View File

@ -1,5 +1,6 @@
import Ember from 'ember'; import { computed } from '@ember/object';
import BaseComponent from './base-component'; import { alias } from '@ember/object/computed';
import BaseComponent from './basic-component';
export default BaseComponent.extend({ export default BaseComponent.extend({
tagName: 'a', tagName: 'a',
@ -10,13 +11,13 @@ export default BaseComponent.extend({
disabledText: 'Disable', disabledText: 'Disable',
enabledOp: 'enable', enabledOp: 'enable',
disabledOp: 'disable', disabledOp: 'disable',
enabled: Ember.computed.alias('model.enabled'), enabled: alias('model.enabled'),
title: Ember.computed('enabled', function() { title: computed('enabled', function() {
let me = this; let me = this;
return this.get('enabled') ? me.get('disabledText') : me.get('enabledText'); return this.get('enabled') ? me.get('disabledText') : me.get('enabledText');
}), }),
'data-original-title': Ember.computed.alias('title'), 'data-original-title': alias('title'),
op: Ember.computed('enabled', function() { op: computed('enabled', function() {
let me = this; let me = this;
return this.get('enabled') ? return this.get('enabled') ?
me.get('disabledOp') || me.get('disabledText') me.get('disabledOp') || me.get('disabledText')

View File

@ -1,4 +1,4 @@
import BaseComponent from './base-component'; import BaseComponent from './basic-component';
import { alias } from '@ember/object/computed'; import { alias } from '@ember/object/computed';
import { inject as service } from '@ember/service'; import { inject as service } from '@ember/service';

View File

@ -1,19 +1,23 @@
import Ember from 'ember'; import Mixin from '@ember/object/mixin';
import { inject as service } from '@ember/service';
import { alias } from '@ember/object/computed';
import { computed } from '@ember/object';
import { getOwner } from '@ember/application';
export default Ember.Mixin.create({ export default Mixin.create({
toolService: Ember.inject.service('tool-service'), toolService: service('tool-service'),
routeName: Ember.computed.alias('router.currentRouteName'), routeName: alias('router.currentRouteName'),
'trim-index': true, 'trim-index': true,
route: Ember.computed('routeName', function() { route: computed('routeName', function() {
let me = this; let me = this;
let routeName = me.get('routeName'); let routeName = me.get('routeName');
return me.getRoute(me.get('trim-index') ? return me.getRoute(me.get('trim-index') ?
routeName.replace(/\.index$/, '') : routeName); routeName.replace(/\.index$/, '') : routeName);
}), }),
service: Ember.computed('routeName', function() { service: computed('routeName', function() {
return this.getService(); return this.getService();
}), }),
params: Ember.computed('router.location.lastSetURL', function() { params: computed('router.location.lastSetURL', function() {
let me = this; let me = this;
let routeName = me.get('routeName'); let routeName = me.get('routeName');
return me.getRouteParams(me.get('trim-index') ? return me.getRouteParams(me.get('trim-index') ?
@ -23,14 +27,14 @@ export default Ember.Mixin.create({
return this.get('route').paramsFor(routeName); return this.get('route').paramsFor(routeName);
}, },
getRoute(routeName) { getRoute(routeName) {
return Ember.getOwner(this).lookup( return getOwner(this).lookup(
'route:' + (routeName || this.get('routeName'))); 'route:' + (routeName || this.get('routeName')));
}, },
getParentRouteName(routeName) { getParentRouteName(routeName) {
return routeName.replace(/\.[^\.]+$/, ''); return routeName.replace(/\.[^\.]+$/, '');
}, },
getService(name) { getService(name) {
let me = this; const me = this;
return name ? me.get('toolService').getServiceByRouteName(name) : return name ? me.get('toolService').getServiceByRouteName(name) :
me.getRoute().get('service') || me.getRoute().get('service') ||
me.get('toolService').getServiceByRouteName(me.get('routeName')); me.get('toolService').getServiceByRouteName(me.get('routeName'));

View File

@ -1,86 +0,0 @@
import Ember from 'ember';
import $ from 'jquery'
export default Ember.Mixin.create({
store: Ember.inject.service(),
message: Ember.inject.service(),
pageSize: 32,
constraints: {},
createConstraints: null,
updateConstraints: null,
find(params) {
console.debug('Find Model: ', params);
return this._getStore().find(this.get('modelName'), params);
},
list(start, limit, params) {
console.debug('List Models Start: ', start, ', Limit: ', limit, ", Search: ", params);
return this._getStore().list(this.get('modelName'), start, limit, params);
},
listPage(page, params) {
page > 0 || (page = 1);
let me = this;
let pageSize = me.get('pageSize');
return me.list((page - 1) * pageSize, pageSize, params);
},
create(model) {
console.debug('Create Model: ', model);
return this._getStore().create(this.get('modelName'), model);
},
update(model, defaultPromise) {
console.debug('Update Model: ', model);
let me = this;
let p = me._getStore().update(me.get('modelName'), model);
if (defaultPromise) {
p.then((m) => {
console.debug('After Update: ', m);
!(model instanceof FormData) &&
Object.keys(m).forEach((prop) => {
Ember.set(model, prop, m[prop]);
});
me.get('message').alert('Updated successfully');
})
}
return p;
},
del(params) {
console.debug('Update Model: ', params);
return this._getStore().del(this.get('modelName'), params);
},
ajaxGet(path, params) {
return this._getStore().modelAjaxGet(this.get('modelName'), path, params);
},
ajaxPost(path, params) {
return this._getStore().modelAjaxPost(this.get('modelName'), path, params);
},
validate(model, constraints) {
let me = this;
console.debug('Validate Model: ', model);
if (constraints) {
if ($.type(constraints) === 'string') {
constraints = me.get(constraints);
}
else if ($.type(constraints) !== 'object') {
validation = me.get('constraints');
}
}
else {
constraints = me.get('constraints');
}
return validate(model, constraints || me.get('constraints'));
},
createValidate(model) {
console.debug('Create Validate Model: ', model);
let me = this;
let constraints = me.get('createConstraints') || me.get('constraints') || null;
return constraints && validate(model, constraints);
},
updateValidate(model) {
console.debug('Update Validate Model: ', model);
let me = this;
let constraints = me.get('updateConstraints') || me.get('constraints') || null;
return constraints && validate(model, constraints);
},
_getStore() {
return this.get('store');
}
});

View File

@ -80,6 +80,10 @@ Router.map(function() {
this.route('create'); this.route('create');
this.route('edit', {path: '/:id/edit'}); this.route('edit', {path: '/:id/edit'});
}); });
this.route('export-task', function() {
this.route('list', {path: '/list/:page'});
});
}); });
export default Router; export default Router;

View File

@ -12,18 +12,19 @@ export default Route.extend({
} }
}, },
beforeModel: function(transition) { beforeModel: function(transition) {
console.info('Before Application Model.', transition); console.info('Before application model.', transition);
this.transitionIntercept(transition); this.transitionIntercept(transition);
}, },
activate() { activate() {
console.info('Application Activate.'); const me = this;
console.info('Application activate.');
$('body').addClass('no-skin'); $('body').addClass('no-skin');
try{ace.settings.check('navbar', 'fixed');}catch(e){console.log(e)} try{ace.settings.check('navbar', 'fixed');}catch(e){console.log(e)}
try{ace.settings.check('main-container', 'fixed');}catch(e){console.log(e)} try{ace.settings.check('main-container', 'fixed');}catch(e){console.log(e)}
}, },
actions: { actions: {
loading(transition, originRoute) { loading(transition, originRoute) {
console.info('Application Loading...'); console.info('Application loading...');
// var appCtrl = this.controllerFor('application'); // var appCtrl = this.controllerFor('application');
this.router.one('didTransition', function() { this.router.one('didTransition', function() {
// appCtrl.set('loading', false); // appCtrl.set('loading', false);

View File

@ -1,4 +1,6 @@
import Ember from 'ember'; import EmberObject from '@ember/object';
import { observer, set } from '@ember/object';
import BaseListRoute from './../base-list'; import BaseListRoute from './../base-list';
const cols = ['showId', const cols = ['showId',
@ -20,7 +22,7 @@ const cols = ['showId',
]; ];
const config = { const config = {
showAll: false, showAll: false,
showAllChanged: Ember.observer('showAll', function() { showAllChanged: observer('showAll', function() {
let me = this; let me = this;
if (!me.get('lock')) { if (!me.get('lock')) {
let val = me.get('showAll'); let val = me.get('showAll');
@ -29,7 +31,7 @@ const config = {
}); });
} }
}), }),
colChanged: Ember.observer(...cols.concat(function() { colChanged: observer(...cols.concat(function() {
let me = this; let me = this;
me.set('lock', true); me.set('lock', true);
me.set('showAll', cols.map(col => { me.set('showAll', cols.map(col => {
@ -60,7 +62,7 @@ config.countOfShowing = cols.filter(col => {
return config[col]; return config[col];
}).length + 1; }).length + 1;
const TableOptions = Ember.Object.extend(config); const TableOptions = EmberObject.extend(config);
export default BaseListRoute.extend({ export default BaseListRoute.extend({
queryParams: { queryParams: {
@ -87,10 +89,16 @@ export default BaseListRoute.extend({
}, },
actions: { actions: {
expandYtdSales(row) { expandYtdSales(row) {
Ember.set(row, 'expand', true); set(row, 'expand', true);
}, },
collapseYtdSales(row) { collapseYtdSales(row) {
Ember.set(row, 'expand', false); set(row, 'expand', false);
},
asyncExport() {
const me = this;
me.get('service').ajaxPost('async-export').then(msg => {
me.get('message').alert('Export task created.');
});
} }
} }
}); });

View File

@ -0,0 +1,5 @@
import BaseListRoute from './../base-list';
export default BaseListRoute.extend({
breadcrumbs: [{text: 'Export Tasks'}]
});

View File

@ -1,4 +1,3 @@
import Ember from 'ember';
import BaseListRoute from './../base-list'; import BaseListRoute from './../base-list';
export default BaseListRoute.extend({ export default BaseListRoute.extend({

View File

@ -1,4 +1,3 @@
import Ember from 'ember';
import BaseListRoute from './../base-list'; import BaseListRoute from './../base-list';
export default BaseListRoute.extend({ export default BaseListRoute.extend({

View File

@ -0,0 +1,15 @@
import BaseService from '../service';
import $ from 'jquery';
export default BaseService.extend({
modelName: 'ExportTask',
startup: function() {
const me = this;
$.on('WEBSOCKET', function(e, data) {
console.log('Export task: On websocket message trigger.', e, data);
if (data.type == 'EXPORT_TASK_UPDATED') {
me.set('countUndownloaded', data ? data.countUndownloaded : null);
}
});
}
});

View File

@ -1,7 +1,6 @@
import Ember from 'ember'; import BaseService from '../service';
import BaseServiceMixin from '../../mixins/services/base-service';
export default Ember.Service.extend(BaseServiceMixin, { export default BaseService.extend({
modelName: 'ImportRecord', modelName: 'ImportRecord',
pageSize: 128 pageSize: 128
}); });

View File

@ -1,11 +1,20 @@
import Ember from 'ember'; import Service from '@ember/service';
import $ from 'jquery' import $ from 'jquery'
export default Ember.Service.extend({ export default Service.extend({
alert(msg) { alert(msg) {
this._show_alert_(msg); toastr.success(msg);
},
info(msg) {
toastr.info(msg);
}, },
warn(msg) { warn(msg) {
toastr.warning(msg);
},
alert2(msg) {
this._show_alert_(msg);
},
warn2(msg) {
this._show_alert_(msg, '#F6F0F0'); this._show_alert_(msg, '#F6F0F0');
}, },
_show_alert_(msg, bg) { _show_alert_(msg, bg) {

View File

@ -1,4 +1,88 @@
import Ember from 'ember'; import Service from '@ember/service';
import BaseServiceMixin from '../mixins/services/base-service'; import { set } from '@ember/object';
import { typeOf } from '@ember/utils';
import { inject as service } from '@ember/service';
export default Ember.Service.extend(BaseServiceMixin, {}); export default Service.extend({
store: service(),
message: service(),
pageSize: 32,
constraints: {},
createConstraints: null,
updateConstraints: null,
find(params) {
console.debug('Find model: ', params);
return this._getStore().find(this.get('modelName'), params);
},
list(start, limit, params) {
console.debug('List models start: ', start, ', limit: ', limit, ", search: ", params);
return this._getStore().list(this.get('modelName'), start, limit, params);
},
listPage(page, params) {
page > 0 || (page = 1);
let me = this;
let pageSize = me.get('pageSize');
return me.list((page - 1) * pageSize, pageSize, params);
},
create(model) {
console.debug('Create model: ', model);
return this._getStore().create(this.get('modelName'), model);
},
update(model, defaultPromise) {
console.debug('Update model: ', model);
let me = this;
let p = me._getStore().update(me.get('modelName'), model);
if (defaultPromise) {
p.then((m) => {
console.debug('After update: ', m);
!(model instanceof FormData) &&
Object.keys(m).forEach((prop) => {
set(model, prop, m[prop]);
});
me.get('message').alert('Updated successfully');
})
}
return p;
},
del(params) {
console.debug('Update Model: ', params);
return this._getStore().del(this.get('modelName'), params);
},
ajaxGet(path, params) {
return this._getStore().modelAjaxGet(this.get('modelName'), path, params);
},
ajaxPost(path, params) {
return this._getStore().modelAjaxPost(this.get('modelName'), path, params);
},
validate(model, constraints) {
let me = this;
console.debug('Validate model: ', model);
if (constraints) {
if (typeOf(constraints) === 'string') {
constraints = me.get(constraints);
}
else if (typeOf(constraints) !== 'object') {
validation = me.get('constraints');
}
}
else {
constraints = me.get('constraints');
}
return validate(model, constraints || me.get('constraints'));
},
createValidate(model) {
console.debug('Create validate model: ', model);
let me = this;
let constraints = me.get('createConstraints') || me.get('constraints') || null;
return constraints && validate(model, constraints);
},
updateValidate(model) {
console.debug('Update validate model: ', model);
let me = this;
let constraints = me.get('updateConstraints') || me.get('constraints') || null;
return constraints && validate(model, constraints);
},
_getStore() {
return this.get('store');
}
});

View File

@ -1,7 +1,13 @@
import Ember from 'ember'; import Ember from 'ember';
import Service from '@ember/service';
import $ from 'jquery' import $ from 'jquery'
import { Promise } from 'rsvp';
import { dasherize } from '@ember/string';
import { run } from '@ember/runloop';
import { typeOf } from '@ember/utils';
export default Ember.Service.extend({
export default Service.extend({
list(modelName, start, limit, params) { list(modelName, start, limit, params) {
var p = { var p = {
start: start, start: start,
@ -44,14 +50,14 @@ export default Ember.Service.extend({
}, },
_ajax_request(method, url, params) { _ajax_request(method, url, params) {
let me = this; let me = this;
return new Ember.RSVP.Promise((resolve, reject) => { return new Promise((resolve, reject) => {
let paramsType = $.type(params); const paramsType = typeOf(params);
me.ajax[method ? method : 'doGet'](url, me.ajax[method ? method : 'doGet'](url,
paramsType === 'string' || paramsType === 'string' ||
paramsType === 'number' ? paramsType === 'number' ?
{id: params} : params, {id: params} : params,
(data) => { (data) => {
Ember.run(null, resolve, data); run(null, resolve, data);
}, (msg, r) => { }, (msg, r) => {
reject(msg); reject(msg);
me.dialog.error(msg || 'Ajax request erorr caused'); me.dialog.error(msg || 'Ajax request erorr caused');
@ -60,7 +66,7 @@ export default Ember.Service.extend({
}, },
_pathForType(modelName, path) { _pathForType(modelName, path) {
return (/^[a-zA-Z_][a-zA-Z0-9_]+$/.test(modelName) ? return (/^[a-zA-Z_][a-zA-Z0-9_]+$/.test(modelName) ?
Ember.String.dasherize(modelName) : modelName) + dasherize(modelName) : modelName) +
(/^\//.test(path) ? path : '/' + path); (/^\//.test(path) ? path : '/' + path);
} }
}); });

View File

@ -1,12 +1,13 @@
import Ember from 'ember'; import Service from '@ember/service';
import { getOwner } from '@ember/application';
import BaseService from './service'; import BaseService from './service';
import Ajax from './ajax'; import Ajax from './ajax';
import Store from './store'; import Store from './store';
export default Ember.Service.extend({ export default Service.extend({
getServiceByRouteName: function(routeName) { getServiceByRouteName: function(routeName) {
let me = this; let me = this;
let container = Ember.getOwner(me); let container = getOwner(me);
let service = container.lookup('service:' + routeName); let service = container.lookup('service:' + routeName);
console.debug(`No Route Service [${routeName}] Found, Try To Find Model Service`); console.debug(`No Route Service [${routeName}] Found, Try To Find Model Service`);
let indexTrimmedRouteName = null; let indexTrimmedRouteName = null;

View File

@ -1,4 +1,3 @@
import Ember from 'ember';
import BaseService from '../service'; import BaseService from '../service';
export default BaseService.extend({ export default BaseService.extend({

View File

@ -42,7 +42,7 @@ export default Service.extend({
console.info('Websocket connected: ', frame); console.info('Websocket connected: ', frame);
me.set('subscription', client.subscribe('/topic/' + user.id, function(msg) { me.set('subscription', client.subscribe('/topic/' + user.id, function(msg) {
console.info('On websocket message: ', msg); console.info('On websocket message: ', msg);
$.trigger('WEBSOCKET', JSON.parse(msg.body)); $.trigger('WEBSOCKET', [JSON.parse(msg.body)]);
})); }));
me.set('connected', true); me.set('connected', true);
}; };
@ -61,6 +61,10 @@ export default Service.extend({
console.log('Additional details: ', frame.body); console.log('Additional details: ', frame.body);
me.set('connected', false); me.set('connected', false);
}; };
client.onWebSocketClose = function(event) {
console.log('On websocket close.', event);
};
client.activate(); client.activate();
me.set('client', client); me.set('client', client);

View File

@ -107,4 +107,21 @@ input[type="number"] {
word-wrap: break-word; /* Internet Explorer 5.5+ */ word-wrap: break-word; /* Internet Explorer 5.5+ */
background-color: inherit; background-color: inherit;
border: 0; border: 0;
}
.export-task-badge {
position: absolute;
top: 4px;
left: 24px;
width: 14px;
height: 14px;
font-size: 10px;
border-radius: 50%;
color: #fff;
background-color: rgba(255, 0, 0, 0.8);
// rgba(0, 0, 0, 0.7);
display: flex;
justify-content: center;
align-items: center;
} }

View File

@ -0,0 +1 @@
{{yield}}

View File

@ -98,6 +98,13 @@
<span class="menu-text"> Database Backup </span> <span class="menu-text"> Database Backup </span>
</LinkTo> </LinkTo>
</li> </li>
<li>
<LinkTo @route="export-task.list" @model=1>
<i class="menu-icon fa fa-tasks {{if this.exportTaskService.countUndownloaded 'green' 'blue'}}"></i>
<span class="export-task-badge">21</span>
<span class="menu-text"> Export Task {{#if this.exportTaskService.countUndownloaded}}<span class="badge badge-danger">{{this.exportTaskService.countUndownloaded}}</span>{{/if}}</span>
</LinkTo>
</li>
{{/if}} {{/if}}
</ul><!-- /.nav-list --> </ul><!-- /.nav-list -->
@ -153,7 +160,7 @@
<div class="footer-content"> <div class="footer-content">
<span class="bigger-120"> <span class="bigger-120">
<span class="blue bolder">LEMO</span> <span class="blue bolder">LEMO</span>
CHINA &copy; 2017 CHINA &copy; 2017 - 2022
</span> </span>
{{!--&nbsp; &nbsp; {{!--&nbsp; &nbsp;

View File

@ -23,10 +23,10 @@
{{/link-to}} {{/link-to}}
</li> </li>
<li> <li>
<a href="/customer/export" target="_blank"> {{#a-btn click=(route-action 'asyncExport') title='Export Customers'}}
<i class="ace-icon fa fa-download bigger-110"></i> <i class="ace-icon fa fa-download bigger-110"></i>
Export Customers Export Customers
</a> {{/a-btn}}
</li> </li>
{{/if}} {{/if}}
<li> <li>

View File

@ -0,0 +1,71 @@
{{#main-content}}
<div class="widget-box transparent">
{{grid-header search-box=false}}
<div class="widget-body">
<!-- #section:custom/scrollbar -->
<div class="widget-main no-padding table-responsive no-border">
<table class="table table-striped table-bordered table-hover dataTable" style="border: 1px solid #ddd;">
<thead class="thin-border-bottom">
<tr>
{{sortable-th name='dateCreated' text='Date Created' style='min-width: 105px;'}}
<th>
<i class="ace-icon fa fa-exchange bigger-110"></i>
Status
</th>
<th>
File Downloaded
</th>
<th style="min-width: 106px;">
<i class="ace-icon fa fa-cogs bigger-110"></i>
Actions
</th>
</tr>
</thead>
<tbody>
{{#each model.list as |it|}}
<tr>
<td>
{{moment-format it.dateCreated 'M/D/YYYY H:mm:ss'}}
</td>
<td>
{{it.status}}
</td>
<td>
{{status-cell model=it field='downloaded' enabledText='DOWNLOADED' disabledText='NOT DOWNLOAD'}}
</td>
<td>
<div class="hidden-sm hidden-xs btn-group">
{{#link-to 'user.edit' it.id class='btn btn-xs btn-info' data-rel='tooltip' title='Download'}}
<i class="ace-icon fa fa-pencil bigger-120"></i>
Download
{{/link-to}}
</div>
<div class="hidden-md hidden-lg">
<div class="inline pos-rel">
<button class="btn btn-minier btn-primary dropdown-toggle" data-toggle="dropdown" data-position="auto">
<i class="ace-icon fa fa-cog icon-only bigger-110"></i>
</button>
<ul class="dropdown-menu dropdown-only-icon dropdown-yellow dropdown-menu-right dropdown-caret dropdown-close">
<li>
{{#link-to 'user.edit' it.id class='tooltip-info' data-rel='tooltip' title='Download'}}
<span class="blue">
<i class="ace-icon fa fa-pencil-square-o bigger-120"></i>
Download
</span>
{{/link-to}}
</li>
</ul>
</div>
</div>
</td>
</tr>
{{/each}}
</tbody>
</table>
</div>
{{pagination-bar}}
</div>
</div>
{{/main-content}}

View File

@ -0,0 +1,26 @@
import { module, test } from 'qunit';
import { setupRenderingTest } from 'ember-qunit';
import { render } from '@ember/test-helpers';
import { hbs } from 'ember-cli-htmlbars';
module('Integration | Component | a-btn', function(hooks) {
setupRenderingTest(hooks);
test('it renders', async function(assert) {
// Set any properties with this.set('myProperty', 'value');
// Handle any actions with this.set('myAction', function(val) { ... });
await render(hbs`<ABtn />`);
assert.dom(this.element).hasText('');
// Template block usage:
await render(hbs`
<ABtn>
template block text
</ABtn>
`);
assert.dom(this.element).hasText('template block text');
});
});

View File

@ -0,0 +1,11 @@
import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';
module('Unit | Route | export-task/list', function(hooks) {
setupTest(hooks);
test('it exists', function(assert) {
let route = this.owner.lookup('route:export-task/list');
assert.ok(route);
});
});

View File

@ -0,0 +1,12 @@
import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';
module('Unit | Service | export-task/service', function(hooks) {
setupTest(hooks);
// TODO: Replace this with your real tests.
test('it exists', function(assert) {
let service = this.owner.lookup('service:export-task/service');
assert.ok(service);
});
});