@etsoo/appscript 1.2.47 → 1.2.51
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/cjs/app/CoreApp.d.ts +27 -29
- package/lib/cjs/app/CoreApp.js +49 -58
- package/lib/cjs/bridges/BridgeUtils.d.ts +0 -5
- package/lib/cjs/bridges/BridgeUtils.js +8 -29
- package/lib/cjs/bridges/FlutterHost.d.ts +21 -0
- package/lib/cjs/bridges/FlutterHost.js +30 -0
- package/lib/cjs/bridges/IBridgeHost.d.ts +5 -1
- package/lib/cjs/business/BusinessUtils.d.ts +8 -0
- package/lib/cjs/business/BusinessUtils.js +17 -0
- package/lib/cjs/i18n/en-US.json +15 -0
- package/lib/cjs/i18n/zh-CN.json +15 -0
- package/lib/cjs/i18n/zh-HK.json +15 -0
- package/lib/mjs/app/CoreApp.d.ts +27 -29
- package/lib/mjs/app/CoreApp.js +49 -58
- package/lib/mjs/bridges/BridgeUtils.d.ts +0 -5
- package/lib/mjs/bridges/BridgeUtils.js +8 -29
- package/lib/mjs/bridges/FlutterHost.d.ts +21 -0
- package/lib/mjs/bridges/FlutterHost.js +26 -0
- package/lib/mjs/bridges/IBridgeHost.d.ts +5 -1
- package/lib/mjs/business/BusinessUtils.d.ts +8 -0
- package/lib/mjs/business/BusinessUtils.js +17 -0
- package/lib/mjs/i18n/en-US.json +15 -0
- package/lib/mjs/i18n/zh-CN.json +15 -0
- package/lib/mjs/i18n/zh-HK.json +15 -0
- package/package.json +1 -1
- package/src/app/CoreApp.ts +70 -90
- package/src/bridges/BridgeUtils.ts +8 -37
- package/src/bridges/FlutterHost.ts +40 -0
- package/src/bridges/IBridgeHost.ts +6 -1
- package/src/business/BusinessUtils.ts +20 -0
- package/src/i18n/en-US.json +15 -0
- package/src/i18n/zh-CN.json +15 -0
- package/src/i18n/zh-HK.json +15 -0
package/src/app/CoreApp.ts
CHANGED
|
@@ -83,6 +83,22 @@ export interface RefreshTokenProps<D extends {}> {
|
|
|
83
83
|
showLoading?: boolean;
|
|
84
84
|
}
|
|
85
85
|
|
|
86
|
+
/**
|
|
87
|
+
* App fields
|
|
88
|
+
*/
|
|
89
|
+
const appFields = [
|
|
90
|
+
'headerToken',
|
|
91
|
+
'serversideDeviceId',
|
|
92
|
+
'deviceId',
|
|
93
|
+
'devices',
|
|
94
|
+
'devicePassphrase'
|
|
95
|
+
] as const;
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Basic type template
|
|
99
|
+
*/
|
|
100
|
+
export type IAppFields = { [key in typeof appFields[number]]: string };
|
|
101
|
+
|
|
86
102
|
/**
|
|
87
103
|
* Core application interface
|
|
88
104
|
*/
|
|
@@ -96,6 +112,11 @@ export interface ICoreApp<
|
|
|
96
112
|
*/
|
|
97
113
|
readonly settings: S;
|
|
98
114
|
|
|
115
|
+
/**
|
|
116
|
+
* Fields
|
|
117
|
+
*/
|
|
118
|
+
readonly fields: IAppFields;
|
|
119
|
+
|
|
99
120
|
/**
|
|
100
121
|
* API
|
|
101
122
|
*/
|
|
@@ -502,6 +523,11 @@ export abstract class CoreApp<
|
|
|
502
523
|
*/
|
|
503
524
|
readonly settings: S;
|
|
504
525
|
|
|
526
|
+
/**
|
|
527
|
+
* Fields
|
|
528
|
+
*/
|
|
529
|
+
readonly fields: IAppFields;
|
|
530
|
+
|
|
505
531
|
/**
|
|
506
532
|
* API
|
|
507
533
|
*/
|
|
@@ -632,10 +658,10 @@ export abstract class CoreApp<
|
|
|
632
658
|
*/
|
|
633
659
|
protected get persistedFields() {
|
|
634
660
|
return [
|
|
635
|
-
this.
|
|
636
|
-
this.
|
|
637
|
-
this.
|
|
638
|
-
this.
|
|
661
|
+
this.fields.deviceId,
|
|
662
|
+
this.fields.devicePassphrase,
|
|
663
|
+
this.fields.serversideDeviceId,
|
|
664
|
+
this.fields.headerToken
|
|
639
665
|
];
|
|
640
666
|
}
|
|
641
667
|
|
|
@@ -660,12 +686,15 @@ export abstract class CoreApp<
|
|
|
660
686
|
this.storage = storage;
|
|
661
687
|
this.name = name;
|
|
662
688
|
|
|
663
|
-
//
|
|
664
|
-
this.
|
|
665
|
-
|
|
666
|
-
|
|
689
|
+
// Fields, attach with the name identifier
|
|
690
|
+
this.fields = appFields.reduce(
|
|
691
|
+
(a, v) => ({ ...a, [v]: 'smarterp-' + v + '-' + name }),
|
|
692
|
+
{} as any
|
|
667
693
|
);
|
|
668
694
|
|
|
695
|
+
// Device id
|
|
696
|
+
this._deviceId = storage.getData(this.fields.deviceId, '');
|
|
697
|
+
|
|
669
698
|
// Restore
|
|
670
699
|
this.restore();
|
|
671
700
|
|
|
@@ -687,22 +716,31 @@ export abstract class CoreApp<
|
|
|
687
716
|
private resetKeys() {
|
|
688
717
|
this.storage.clear(
|
|
689
718
|
[
|
|
690
|
-
this.
|
|
691
|
-
this.
|
|
692
|
-
this.
|
|
719
|
+
this.fields.devicePassphrase,
|
|
720
|
+
this.fields.headerToken,
|
|
721
|
+
this.fields.serversideDeviceId
|
|
693
722
|
],
|
|
694
723
|
false
|
|
695
724
|
);
|
|
696
725
|
this.passphrase = '';
|
|
697
726
|
}
|
|
698
727
|
|
|
728
|
+
/**
|
|
729
|
+
* Add app name as identifier
|
|
730
|
+
* @param field Field
|
|
731
|
+
* @returns Result
|
|
732
|
+
*/
|
|
733
|
+
protected addIdentifier(field: string) {
|
|
734
|
+
return field + '-' + this.name;
|
|
735
|
+
}
|
|
736
|
+
|
|
699
737
|
/**
|
|
700
738
|
* Restore settings from persisted source
|
|
701
739
|
*/
|
|
702
740
|
protected restore() {
|
|
703
741
|
// Devices
|
|
704
742
|
const devices = this.storage.getPersistedData<string[]>(
|
|
705
|
-
|
|
743
|
+
this.fields.devices,
|
|
706
744
|
[]
|
|
707
745
|
);
|
|
708
746
|
|
|
@@ -711,10 +749,7 @@ export abstract class CoreApp<
|
|
|
711
749
|
this.storage.copyFrom(this.persistedFields, false);
|
|
712
750
|
|
|
713
751
|
// Reset device id
|
|
714
|
-
this._deviceId = this.storage.getData(
|
|
715
|
-
this.addIdentifier(CoreApp.deviceIdField),
|
|
716
|
-
''
|
|
717
|
-
);
|
|
752
|
+
this._deviceId = this.storage.getData(this.fields.deviceId, '');
|
|
718
753
|
|
|
719
754
|
// Totally new, no data restored
|
|
720
755
|
if (this._deviceId === '') return false;
|
|
@@ -731,7 +766,7 @@ export abstract class CoreApp<
|
|
|
731
766
|
|
|
732
767
|
// this.name to identifier different app's secret
|
|
733
768
|
const passphraseEncrypted = this.storage.getData<string>(
|
|
734
|
-
this.
|
|
769
|
+
this.fields.devicePassphrase
|
|
735
770
|
);
|
|
736
771
|
if (passphraseEncrypted) {
|
|
737
772
|
const passphraseDecrypted = this.decrypt(
|
|
@@ -741,7 +776,7 @@ export abstract class CoreApp<
|
|
|
741
776
|
if (passphraseDecrypted != null) {
|
|
742
777
|
// Add the device to the list
|
|
743
778
|
devices.push(d);
|
|
744
|
-
this.storage.setPersistedData(
|
|
779
|
+
this.storage.setPersistedData(this.fields.devices, devices);
|
|
745
780
|
|
|
746
781
|
this.passphrase = passphraseDecrypted;
|
|
747
782
|
|
|
@@ -761,14 +796,14 @@ export abstract class CoreApp<
|
|
|
761
796
|
persist() {
|
|
762
797
|
// Devices
|
|
763
798
|
const devices = this.storage.getPersistedData<string[]>(
|
|
764
|
-
|
|
799
|
+
this.fields.devices
|
|
765
800
|
);
|
|
766
801
|
if (devices != null) {
|
|
767
802
|
const index = devices.indexOf(this.getDeviceId());
|
|
768
803
|
if (index !== -1) {
|
|
769
804
|
// Remove current device from the list
|
|
770
805
|
devices.splice(index, 1);
|
|
771
|
-
this.storage.setPersistedData(
|
|
806
|
+
this.storage.setPersistedData(this.fields.devices, devices);
|
|
772
807
|
}
|
|
773
808
|
}
|
|
774
809
|
|
|
@@ -776,15 +811,6 @@ export abstract class CoreApp<
|
|
|
776
811
|
this.storage.copyTo(this.persistedFields);
|
|
777
812
|
}
|
|
778
813
|
|
|
779
|
-
/**
|
|
780
|
-
* Add app name as identifier
|
|
781
|
-
* @param field Field
|
|
782
|
-
* @returns Result
|
|
783
|
-
*/
|
|
784
|
-
protected addIdentifier(field: string) {
|
|
785
|
-
return field + '-' + this.name;
|
|
786
|
-
}
|
|
787
|
-
|
|
788
814
|
/**
|
|
789
815
|
* Setup Api
|
|
790
816
|
* @param api Api
|
|
@@ -845,7 +871,7 @@ export abstract class CoreApp<
|
|
|
845
871
|
|
|
846
872
|
// Serverside encrypted device id
|
|
847
873
|
const identifier = this.storage.getData<string>(
|
|
848
|
-
this.
|
|
874
|
+
this.fields.serversideDeviceId
|
|
849
875
|
);
|
|
850
876
|
|
|
851
877
|
// Timestamp
|
|
@@ -890,10 +916,7 @@ export abstract class CoreApp<
|
|
|
890
916
|
if (callback) callback(false);
|
|
891
917
|
|
|
892
918
|
// Clear device id
|
|
893
|
-
this.storage.setData(
|
|
894
|
-
this.addIdentifier(CoreApp.deviceIdField),
|
|
895
|
-
undefined
|
|
896
|
-
);
|
|
919
|
+
this.storage.setData(this.fields.deviceId, undefined);
|
|
897
920
|
|
|
898
921
|
return;
|
|
899
922
|
}
|
|
@@ -919,23 +942,20 @@ export abstract class CoreApp<
|
|
|
919
942
|
|
|
920
943
|
// Update device id and cache it
|
|
921
944
|
this._deviceId = data.deviceId;
|
|
922
|
-
this.storage.setData(
|
|
923
|
-
this.addIdentifier(CoreApp.deviceIdField),
|
|
924
|
-
this._deviceId
|
|
925
|
-
);
|
|
945
|
+
this.storage.setData(this.fields.deviceId, this._deviceId);
|
|
926
946
|
|
|
927
947
|
// Devices
|
|
928
948
|
const devices = this.storage.getPersistedData<string[]>(
|
|
929
|
-
|
|
949
|
+
this.fields.devices,
|
|
930
950
|
[]
|
|
931
951
|
);
|
|
932
952
|
devices.push(this.getDeviceId());
|
|
933
|
-
this.storage.setPersistedData(
|
|
953
|
+
this.storage.setPersistedData(this.fields.devices, devices);
|
|
934
954
|
|
|
935
955
|
// Current passphrase
|
|
936
956
|
this.passphrase = passphrase;
|
|
937
957
|
this.storage.setData(
|
|
938
|
-
this.
|
|
958
|
+
this.fields.devicePassphrase,
|
|
939
959
|
this.encrypt(passphrase, this.name)
|
|
940
960
|
);
|
|
941
961
|
|
|
@@ -981,7 +1001,7 @@ export abstract class CoreApp<
|
|
|
981
1001
|
* @returns Fields
|
|
982
1002
|
*/
|
|
983
1003
|
protected initCallEncryptedUpdateFields(): string[] {
|
|
984
|
-
return [this.
|
|
1004
|
+
return [this.fields.headerToken];
|
|
985
1005
|
}
|
|
986
1006
|
|
|
987
1007
|
/**
|
|
@@ -1009,10 +1029,7 @@ export abstract class CoreApp<
|
|
|
1009
1029
|
// Cover the current value
|
|
1010
1030
|
if (refreshToken !== '') {
|
|
1011
1031
|
if (refreshToken != null) refreshToken = this.encrypt(refreshToken);
|
|
1012
|
-
this.storage.setData(
|
|
1013
|
-
this.addIdentifier(CoreApp.headerTokenField),
|
|
1014
|
-
refreshToken
|
|
1015
|
-
);
|
|
1032
|
+
this.storage.setData(this.fields.headerToken, refreshToken);
|
|
1016
1033
|
}
|
|
1017
1034
|
|
|
1018
1035
|
// Reset tryLogin state
|
|
@@ -1100,10 +1117,7 @@ export abstract class CoreApp<
|
|
|
1100
1117
|
*/
|
|
1101
1118
|
clearCacheData() {
|
|
1102
1119
|
this.clearCacheToken();
|
|
1103
|
-
this.storage.setData(
|
|
1104
|
-
this.addIdentifier(CoreApp.devicePassphraseField),
|
|
1105
|
-
undefined
|
|
1106
|
-
);
|
|
1120
|
+
this.storage.setData(this.fields.devicePassphrase, undefined);
|
|
1107
1121
|
}
|
|
1108
1122
|
|
|
1109
1123
|
/**
|
|
@@ -1111,10 +1125,7 @@ export abstract class CoreApp<
|
|
|
1111
1125
|
*/
|
|
1112
1126
|
clearCacheToken() {
|
|
1113
1127
|
this.cachedRefreshToken = undefined;
|
|
1114
|
-
this.storage.setPersistedData(
|
|
1115
|
-
this.addIdentifier(CoreApp.headerTokenField),
|
|
1116
|
-
undefined
|
|
1117
|
-
);
|
|
1128
|
+
this.storage.setPersistedData(this.fields.headerToken, undefined);
|
|
1118
1129
|
}
|
|
1119
1130
|
|
|
1120
1131
|
/**
|
|
@@ -1426,9 +1437,7 @@ export abstract class CoreApp<
|
|
|
1426
1437
|
getCacheToken(): string | undefined {
|
|
1427
1438
|
// Temp refresh token
|
|
1428
1439
|
if (this.cachedRefreshToken) return this.cachedRefreshToken;
|
|
1429
|
-
return this.storage.getData<string>(
|
|
1430
|
-
this.addIdentifier(CoreApp.headerTokenField)
|
|
1431
|
-
);
|
|
1440
|
+
return this.storage.getData<string>(this.fields.headerToken);
|
|
1432
1441
|
}
|
|
1433
1442
|
|
|
1434
1443
|
/**
|
|
@@ -1462,7 +1471,7 @@ export abstract class CoreApp<
|
|
|
1462
1471
|
const response = this.api.transformResponse(rawResponse);
|
|
1463
1472
|
return this.api.getHeaderValue(
|
|
1464
1473
|
response.headers,
|
|
1465
|
-
|
|
1474
|
+
'SmartERPRefreshToken'
|
|
1466
1475
|
);
|
|
1467
1476
|
}
|
|
1468
1477
|
|
|
@@ -1697,8 +1706,9 @@ export abstract class CoreApp<
|
|
|
1697
1706
|
* Try login, returning false means is loading
|
|
1698
1707
|
* UI get involved while refreshToken not intended
|
|
1699
1708
|
* @param data Additional request data
|
|
1709
|
+
* @param showLoading Show loading bar or not during call
|
|
1700
1710
|
*/
|
|
1701
|
-
async tryLogin<D extends {} = {}>(_data?: D) {
|
|
1711
|
+
async tryLogin<D extends {} = {}>(_data?: D, _showLoading?: boolean) {
|
|
1702
1712
|
if (this._isTryingLogin) return false;
|
|
1703
1713
|
this._isTryingLogin = true;
|
|
1704
1714
|
return true;
|
|
@@ -1714,10 +1724,7 @@ export abstract class CoreApp<
|
|
|
1714
1724
|
this.userData = user;
|
|
1715
1725
|
|
|
1716
1726
|
// Cache the encrypted serverside device id
|
|
1717
|
-
this.storage.setData(
|
|
1718
|
-
this.addIdentifier(CoreApp.serversideDeviceIdField),
|
|
1719
|
-
user.deviceId
|
|
1720
|
-
);
|
|
1727
|
+
this.storage.setData(this.fields.serversideDeviceId, user.deviceId);
|
|
1721
1728
|
|
|
1722
1729
|
if (keep) {
|
|
1723
1730
|
this.authorize(user.token, refreshToken);
|
|
@@ -1764,30 +1771,3 @@ export abstract class CoreApp<
|
|
|
1764
1771
|
);
|
|
1765
1772
|
}
|
|
1766
1773
|
}
|
|
1767
|
-
|
|
1768
|
-
export namespace CoreApp {
|
|
1769
|
-
/**
|
|
1770
|
-
* Response token header field name
|
|
1771
|
-
*/
|
|
1772
|
-
export const headerTokenField = 'SmartERPRefreshToken';
|
|
1773
|
-
|
|
1774
|
-
/**
|
|
1775
|
-
* Serverside device id encrypted field name
|
|
1776
|
-
*/
|
|
1777
|
-
export const serversideDeviceIdField = 'SmartERPServersideDeviceId';
|
|
1778
|
-
|
|
1779
|
-
/**
|
|
1780
|
-
* Device id field name
|
|
1781
|
-
*/
|
|
1782
|
-
export const deviceIdField = 'SmartERPDeviceId';
|
|
1783
|
-
|
|
1784
|
-
/**
|
|
1785
|
-
* Devices field name
|
|
1786
|
-
*/
|
|
1787
|
-
export const devicesField = 'SmartERPDevices';
|
|
1788
|
-
|
|
1789
|
-
/**
|
|
1790
|
-
* Device passphrase field name
|
|
1791
|
-
*/
|
|
1792
|
-
export const devicePassphraseField = 'SmartERPDevicePassphrase';
|
|
1793
|
-
}
|
|
@@ -1,48 +1,19 @@
|
|
|
1
|
+
import { FlutterHost } from './FlutterHost';
|
|
1
2
|
import { IBridgeHost } from './IBridgeHost';
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* Bridge utils
|
|
5
6
|
*/
|
|
6
7
|
export namespace BridgeUtils {
|
|
7
|
-
|
|
8
|
-
* Is electron client
|
|
9
|
-
* @returns Result
|
|
10
|
-
*/
|
|
11
|
-
export function isElectronClient() {
|
|
12
|
-
// Renderer process
|
|
13
|
-
if (
|
|
14
|
-
typeof window !== 'undefined' &&
|
|
15
|
-
typeof window.process === 'object' &&
|
|
16
|
-
(window.process as any).type === 'renderer'
|
|
17
|
-
) {
|
|
18
|
-
return true;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
// Main process
|
|
22
|
-
if (
|
|
23
|
-
typeof process !== 'undefined' &&
|
|
24
|
-
typeof process.versions === 'object' &&
|
|
25
|
-
!!process.versions.electron
|
|
26
|
-
) {
|
|
27
|
-
return true;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
// Detect the user agent when the `nodeIntegration` option is set to true
|
|
31
|
-
if (
|
|
32
|
-
typeof navigator === 'object' &&
|
|
33
|
-
typeof navigator.userAgent === 'string' &&
|
|
34
|
-
navigator.userAgent.indexOf('Electron') >= 0
|
|
35
|
-
) {
|
|
36
|
-
return true;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
return false;
|
|
40
|
-
}
|
|
8
|
+
const g: any = globalThis;
|
|
41
9
|
|
|
42
10
|
/**
|
|
43
11
|
* Bridge host
|
|
44
12
|
*/
|
|
45
|
-
export const host =
|
|
46
|
-
|
|
47
|
-
|
|
13
|
+
export const host =
|
|
14
|
+
typeof g.flutter_inappwebview?.callHandler === 'function'
|
|
15
|
+
? new FlutterHost(g.flutter_inappwebview.callHandler)
|
|
16
|
+
: typeof g.electron === 'object'
|
|
17
|
+
? (g.electron as IBridgeHost)
|
|
18
|
+
: undefined;
|
|
48
19
|
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { IBridgeHost } from './IBridgeHost';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Flutter JavaScript Host
|
|
5
|
+
* https://inappwebview.dev/docs/javascript/communication/
|
|
6
|
+
*/
|
|
7
|
+
export class FlutterHost implements IBridgeHost {
|
|
8
|
+
/**
|
|
9
|
+
* Start Url
|
|
10
|
+
*/
|
|
11
|
+
private startUrl: string | null | undefined;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Constructor
|
|
15
|
+
* @param callHandler Call handler
|
|
16
|
+
*/
|
|
17
|
+
constructor(
|
|
18
|
+
public callHandler: (
|
|
19
|
+
name: string,
|
|
20
|
+
...args: unknown[]
|
|
21
|
+
) => PromiseLike<{} | void>
|
|
22
|
+
) {}
|
|
23
|
+
|
|
24
|
+
changeCulture(locale: string): void {
|
|
25
|
+
this.callHandler('changeCulture', locale);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
exit(): void {
|
|
29
|
+
this.callHandler('exit');
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
getStartUrl(): string | null | undefined {
|
|
33
|
+
return this.startUrl;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
loadApp(name: string, startUrl?: string): void {
|
|
37
|
+
this.startUrl = startUrl;
|
|
38
|
+
this.callHandler('loadApp', name, startUrl);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -13,10 +13,15 @@ export interface IBridgeHost {
|
|
|
13
13
|
*/
|
|
14
14
|
exit(): void;
|
|
15
15
|
|
|
16
|
+
/**
|
|
17
|
+
* Get app start Url / router Url
|
|
18
|
+
*/
|
|
19
|
+
getStartUrl(): string | undefined | null;
|
|
20
|
+
|
|
16
21
|
/**
|
|
17
22
|
* Load application
|
|
18
23
|
* @param name App name
|
|
19
|
-
* @param startUrl Start Url
|
|
24
|
+
* @param startUrl Start Url / router Url
|
|
20
25
|
*/
|
|
21
26
|
loadApp(name: string, startUrl?: string): void;
|
|
22
27
|
}
|
|
@@ -56,6 +56,26 @@ export namespace BusinessUtils {
|
|
|
56
56
|
});
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
+
/**
|
|
60
|
+
* Get 12-month items
|
|
61
|
+
* @param monthLabels Month labels
|
|
62
|
+
* @param startMonth Start month, 0 as Jan.
|
|
63
|
+
* @returns 12 months
|
|
64
|
+
*/
|
|
65
|
+
export function getMonths(monthLabels: string[], startMonth: number = 0) {
|
|
66
|
+
const months: DataTypes.IdLabelItem[] = [];
|
|
67
|
+
|
|
68
|
+
for (let i = 0; i < 12; i++) {
|
|
69
|
+
if (startMonth >= 12) startMonth = 0;
|
|
70
|
+
|
|
71
|
+
months.push({ id: startMonth, label: monthLabels[startMonth] });
|
|
72
|
+
|
|
73
|
+
startMonth++;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return months;
|
|
77
|
+
}
|
|
78
|
+
|
|
59
79
|
/**
|
|
60
80
|
* Get product unit's label
|
|
61
81
|
* Please define the label in culture with key 'unitPC' for ProductUnit.PC like that
|
package/src/i18n/en-US.json
CHANGED
|
@@ -50,6 +50,20 @@
|
|
|
50
50
|
"message": "Message",
|
|
51
51
|
"mobile": "Mobile number",
|
|
52
52
|
"mobilePhones": "Mobile numbers",
|
|
53
|
+
"months": [
|
|
54
|
+
"Jan.",
|
|
55
|
+
"Feb.",
|
|
56
|
+
"Mar.",
|
|
57
|
+
"Apr.",
|
|
58
|
+
"May.",
|
|
59
|
+
"Jun.",
|
|
60
|
+
"Jul.",
|
|
61
|
+
"Aug.",
|
|
62
|
+
"Sep.",
|
|
63
|
+
"Oct.",
|
|
64
|
+
"Nov.",
|
|
65
|
+
"Dec."
|
|
66
|
+
],
|
|
53
67
|
"more": "More",
|
|
54
68
|
"moreTag": "{0} more",
|
|
55
69
|
"name": "Name",
|
|
@@ -67,6 +81,7 @@
|
|
|
67
81
|
"pageNotFound": "Page Not Found",
|
|
68
82
|
"prompt": "Input",
|
|
69
83
|
"pullToRefresh": "Pull down to refresh",
|
|
84
|
+
"quarters": ["Q1", "Q2", "Q3", "Q4"],
|
|
70
85
|
"record": "Record",
|
|
71
86
|
"refresh": "Refresh",
|
|
72
87
|
"refreshing": "Refreshing",
|
package/src/i18n/zh-CN.json
CHANGED
|
@@ -50,6 +50,20 @@
|
|
|
50
50
|
"message": "留言",
|
|
51
51
|
"mobile": "手机号码",
|
|
52
52
|
"mobilePhones": "手机号码",
|
|
53
|
+
"months": [
|
|
54
|
+
"1月",
|
|
55
|
+
"2月",
|
|
56
|
+
"3月",
|
|
57
|
+
"4月",
|
|
58
|
+
"5月",
|
|
59
|
+
"6月",
|
|
60
|
+
"7月",
|
|
61
|
+
"8月",
|
|
62
|
+
"9月",
|
|
63
|
+
"10月",
|
|
64
|
+
"11月",
|
|
65
|
+
"12月"
|
|
66
|
+
],
|
|
53
67
|
"more": "更多",
|
|
54
68
|
"moreTag": "({0}+)",
|
|
55
69
|
"name": "姓名",
|
|
@@ -67,6 +81,7 @@
|
|
|
67
81
|
"pageNotFound": "找不到页面",
|
|
68
82
|
"prompt": "输入",
|
|
69
83
|
"pullToRefresh": "下拉刷新",
|
|
84
|
+
"quarters": ["一季度", "二季度", "三季度", "四季度"],
|
|
70
85
|
"record": "记录",
|
|
71
86
|
"refresh": "刷新",
|
|
72
87
|
"refreshing": "正在刷新",
|
package/src/i18n/zh-HK.json
CHANGED
|
@@ -50,6 +50,20 @@
|
|
|
50
50
|
"message": "留言",
|
|
51
51
|
"mobilePhone": "手機號碼",
|
|
52
52
|
"mobilePhones": "手機號碼",
|
|
53
|
+
"months": [
|
|
54
|
+
"1月",
|
|
55
|
+
"2月",
|
|
56
|
+
"3月",
|
|
57
|
+
"4月",
|
|
58
|
+
"5月",
|
|
59
|
+
"6月",
|
|
60
|
+
"7月",
|
|
61
|
+
"8月",
|
|
62
|
+
"9月",
|
|
63
|
+
"10月",
|
|
64
|
+
"11月",
|
|
65
|
+
"12月"
|
|
66
|
+
],
|
|
53
67
|
"more": "更多",
|
|
54
68
|
"moreTag": "({0}+)",
|
|
55
69
|
"name": "姓名",
|
|
@@ -67,6 +81,7 @@
|
|
|
67
81
|
"pageNotFound": "找不到頁面",
|
|
68
82
|
"prompt": "輸入",
|
|
69
83
|
"pullToRefresh": "下拉刷新",
|
|
84
|
+
"quarters": ["一季度", "二季度", "三季度", "四季度"],
|
|
70
85
|
"record": "記錄",
|
|
71
86
|
"refresh": "刷新",
|
|
72
87
|
"refreshing": "正在刷新",
|