mirror of
https://github.com/valitydev/dashboard.git
synced 2024-11-06 10:35:21 +00:00
FE-1011: Create range-datepicker (#169)
This commit is contained in:
parent
f8f7257aad
commit
7e84c5269f
54
package-lock.json
generated
54
package-lock.json
generated
@ -6525,8 +6525,7 @@
|
|||||||
"version": "2.1.1",
|
"version": "2.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
|
||||||
"integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
|
"integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
|
||||||
"dev": true,
|
"dev": true
|
||||||
"optional": true
|
|
||||||
},
|
},
|
||||||
"aproba": {
|
"aproba": {
|
||||||
"version": "1.2.0",
|
"version": "1.2.0",
|
||||||
@ -6550,15 +6549,13 @@
|
|||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
|
||||||
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
|
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
|
||||||
"dev": true,
|
"dev": true
|
||||||
"optional": true
|
|
||||||
},
|
},
|
||||||
"brace-expansion": {
|
"brace-expansion": {
|
||||||
"version": "1.1.11",
|
"version": "1.1.11",
|
||||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||||
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"balanced-match": "^1.0.0",
|
"balanced-match": "^1.0.0",
|
||||||
"concat-map": "0.0.1"
|
"concat-map": "0.0.1"
|
||||||
@ -6575,22 +6572,19 @@
|
|||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
|
||||||
"integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
|
"integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
|
||||||
"dev": true,
|
"dev": true
|
||||||
"optional": true
|
|
||||||
},
|
},
|
||||||
"concat-map": {
|
"concat-map": {
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||||
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
|
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
|
||||||
"dev": true,
|
"dev": true
|
||||||
"optional": true
|
|
||||||
},
|
},
|
||||||
"console-control-strings": {
|
"console-control-strings": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
|
||||||
"integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=",
|
"integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=",
|
||||||
"dev": true,
|
"dev": true
|
||||||
"optional": true
|
|
||||||
},
|
},
|
||||||
"core-util-is": {
|
"core-util-is": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
@ -6721,8 +6715,7 @@
|
|||||||
"version": "2.0.3",
|
"version": "2.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
|
||||||
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
|
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
|
||||||
"dev": true,
|
"dev": true
|
||||||
"optional": true
|
|
||||||
},
|
},
|
||||||
"ini": {
|
"ini": {
|
||||||
"version": "1.3.5",
|
"version": "1.3.5",
|
||||||
@ -6736,7 +6729,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
|
||||||
"integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
|
"integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"number-is-nan": "^1.0.0"
|
"number-is-nan": "^1.0.0"
|
||||||
}
|
}
|
||||||
@ -6753,7 +6745,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
|
||||||
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
|
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"brace-expansion": "^1.1.7"
|
"brace-expansion": "^1.1.7"
|
||||||
}
|
}
|
||||||
@ -6762,15 +6753,13 @@
|
|||||||
"version": "0.0.8",
|
"version": "0.0.8",
|
||||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
|
"resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
|
||||||
"integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
|
"integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
|
||||||
"dev": true,
|
"dev": true
|
||||||
"optional": true
|
|
||||||
},
|
},
|
||||||
"minipass": {
|
"minipass": {
|
||||||
"version": "2.3.5",
|
"version": "2.3.5",
|
||||||
"resolved": "https://registry.npmjs.org/minipass/-/minipass-2.3.5.tgz",
|
"resolved": "https://registry.npmjs.org/minipass/-/minipass-2.3.5.tgz",
|
||||||
"integrity": "sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA==",
|
"integrity": "sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"safe-buffer": "^5.1.2",
|
"safe-buffer": "^5.1.2",
|
||||||
"yallist": "^3.0.0"
|
"yallist": "^3.0.0"
|
||||||
@ -6791,7 +6780,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
|
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
|
||||||
"integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
|
"integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"minimist": "0.0.8"
|
"minimist": "0.0.8"
|
||||||
}
|
}
|
||||||
@ -6880,8 +6868,7 @@
|
|||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
|
||||||
"integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
|
"integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
|
||||||
"dev": true,
|
"dev": true
|
||||||
"optional": true
|
|
||||||
},
|
},
|
||||||
"object-assign": {
|
"object-assign": {
|
||||||
"version": "4.1.1",
|
"version": "4.1.1",
|
||||||
@ -6895,7 +6882,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||||
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
|
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"wrappy": "1"
|
"wrappy": "1"
|
||||||
}
|
}
|
||||||
@ -6991,8 +6977,7 @@
|
|||||||
"version": "5.1.2",
|
"version": "5.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||||
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
|
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
|
||||||
"dev": true,
|
"dev": true
|
||||||
"optional": true
|
|
||||||
},
|
},
|
||||||
"safer-buffer": {
|
"safer-buffer": {
|
||||||
"version": "2.1.2",
|
"version": "2.1.2",
|
||||||
@ -7034,7 +7019,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
|
||||||
"integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
|
"integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"code-point-at": "^1.0.0",
|
"code-point-at": "^1.0.0",
|
||||||
"is-fullwidth-code-point": "^1.0.0",
|
"is-fullwidth-code-point": "^1.0.0",
|
||||||
@ -7056,7 +7040,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
|
||||||
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
|
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"ansi-regex": "^2.0.0"
|
"ansi-regex": "^2.0.0"
|
||||||
}
|
}
|
||||||
@ -7105,15 +7088,13 @@
|
|||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||||
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
|
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
|
||||||
"dev": true,
|
"dev": true
|
||||||
"optional": true
|
|
||||||
},
|
},
|
||||||
"yallist": {
|
"yallist": {
|
||||||
"version": "3.0.3",
|
"version": "3.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz",
|
||||||
"integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==",
|
"integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==",
|
||||||
"dev": true,
|
"dev": true
|
||||||
"optional": true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -11270,6 +11251,14 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"saturn-datepicker": {
|
||||||
|
"version": "8.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/saturn-datepicker/-/saturn-datepicker-8.0.1.tgz",
|
||||||
|
"integrity": "sha512-kUmf8xg5oeGAZtgwqfkNY8Dro6EzX0zGIWnAcQ9cfQ+w3xBq4TbjdBUWuEA19rJlvLLP/uH3PAoXG/SHVLYncQ==",
|
||||||
|
"requires": {
|
||||||
|
"tslib": "^1.9.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"saucelabs": {
|
"saucelabs": {
|
||||||
"version": "1.5.0",
|
"version": "1.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/saucelabs/-/saucelabs-1.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/saucelabs/-/saucelabs-1.5.0.tgz",
|
||||||
@ -12977,6 +12966,11 @@
|
|||||||
"object.getownpropertydescriptors": "^2.0.3"
|
"object.getownpropertydescriptors": "^2.0.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"utility-types": {
|
||||||
|
"version": "3.10.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/utility-types/-/utility-types-3.10.0.tgz",
|
||||||
|
"integrity": "sha512-O11mqxmi7wMKCo6HKFt5AhO4BwY3VV68YU07tgxfz8zJTIxr4BpsezN49Ffwy9j3ZpwwJp4fkRwjRzq3uWE6Rg=="
|
||||||
|
},
|
||||||
"utils-merge": {
|
"utils-merge": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
|
||||||
|
@ -62,8 +62,10 @@
|
|||||||
"lodash.template": "^4.4.0",
|
"lodash.template": "^4.4.0",
|
||||||
"moment": "^2.24.0",
|
"moment": "^2.24.0",
|
||||||
"rxjs": "~6.5.4",
|
"rxjs": "~6.5.4",
|
||||||
|
"saturn-datepicker": "8.0.1",
|
||||||
"ts-keycode-enum": "^1.0.6",
|
"ts-keycode-enum": "^1.0.6",
|
||||||
"tslib": "^1.9.0",
|
"tslib": "^1.9.0",
|
||||||
|
"utility-types": "^3.10.0",
|
||||||
"uuid": "^3.3.3",
|
"uuid": "^3.3.3",
|
||||||
"zone.js": "~0.9.1"
|
"zone.js": "~0.9.1"
|
||||||
},
|
},
|
||||||
|
@ -340,6 +340,11 @@ export class ButtonToggleComponent extends _MatButtonToggleMixinBase implements
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@HostBinding('attr.disabled')
|
||||||
|
get attrDisabled() {
|
||||||
|
return this.disabled ? 'disabled' : null;
|
||||||
|
}
|
||||||
|
|
||||||
@HostBinding('class.dsh-button-toggle-disabled')
|
@HostBinding('class.dsh-button-toggle-disabled')
|
||||||
@Input()
|
@Input()
|
||||||
get disabled(): boolean {
|
get disabled(): boolean {
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
|
|
||||||
import { FormatInputModule } from './format-input';
|
import { FormatInputModule } from './format-input';
|
||||||
|
import { RangeDatepickerModule } from './range-datepicker';
|
||||||
|
|
||||||
const EXPORTED_DECLARATIONS = [FormatInputModule];
|
const EXPORTED_DECLARATIONS = [FormatInputModule, RangeDatepickerModule];
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: EXPORTED_DECLARATIONS,
|
imports: EXPORTED_DECLARATIONS,
|
||||||
|
@ -16,5 +16,5 @@ export const binConfig: FormatInputConfig = {
|
|||||||
mask: binMask,
|
mask: binMask,
|
||||||
placeholder: '0000 00',
|
placeholder: '0000 00',
|
||||||
postfix: '** **** ****',
|
postfix: '** **** ****',
|
||||||
getValue: (v: string) => (v ? v.replace(' ', '') : '')
|
toPublicValue: (v: string) => (v ? v.replace(' ', '') : '')
|
||||||
};
|
};
|
||||||
|
@ -7,5 +7,6 @@ export interface FormatInputConfig {
|
|||||||
size?: number;
|
size?: number;
|
||||||
prefix?: string;
|
prefix?: string;
|
||||||
postfix?: string;
|
postfix?: string;
|
||||||
getValue?: (value: any) => any;
|
toPublicValue?: (value: string) => string;
|
||||||
|
toInternalValue?: (value: string) => string;
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,8 @@ export class FormatInputComponent extends CustomFormControl {
|
|||||||
prefix = '';
|
prefix = '';
|
||||||
postfix = '';
|
postfix = '';
|
||||||
size: string = null;
|
size: string = null;
|
||||||
getValue: (v: any) => any;
|
toInternalValue: (v: any) => any;
|
||||||
|
toPublicValue: (v: any) => any;
|
||||||
|
|
||||||
private _format: Type;
|
private _format: Type;
|
||||||
@Input()
|
@Input()
|
||||||
@ -28,9 +29,9 @@ export class FormatInputComponent extends CustomFormControl {
|
|||||||
return this._format;
|
return this._format;
|
||||||
}
|
}
|
||||||
|
|
||||||
setType(type: Type) {
|
private setType(type: Type) {
|
||||||
const c = configs[type];
|
const c = configs[type];
|
||||||
const { placeholder, prefix, postfix, size, mask, getValue } = c;
|
const { placeholder, prefix, postfix, size, mask, toInternalValue, toPublicValue } = c;
|
||||||
const sizeFromPlaceholder = c.sizeFromPlaceholder === undefined ? true : c.sizeFromPlaceholder;
|
const sizeFromPlaceholder = c.sizeFromPlaceholder === undefined ? true : c.sizeFromPlaceholder;
|
||||||
const estimatedSize = sizeFromPlaceholder && !size && placeholder ? placeholder.length : size;
|
const estimatedSize = sizeFromPlaceholder && !size && placeholder ? placeholder.length : size;
|
||||||
|
|
||||||
@ -39,12 +40,15 @@ export class FormatInputComponent extends CustomFormControl {
|
|||||||
this.prefix = this.prepareText(prefix);
|
this.prefix = this.prepareText(prefix);
|
||||||
this.postfix = this.prepareText(postfix);
|
this.postfix = this.prepareText(postfix);
|
||||||
this.mask = mask;
|
this.mask = mask;
|
||||||
if (getValue) {
|
if (toInternalValue) {
|
||||||
this.getValue = getValue;
|
this.toInternalValue = toInternalValue;
|
||||||
|
}
|
||||||
|
if (toPublicValue) {
|
||||||
|
this.toPublicValue = toPublicValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
prepareText(str: string): string {
|
private prepareText(str: string): string {
|
||||||
return (typeof str === 'string' ? str.replace(/ /g, '\xa0') : str) || '';
|
return (typeof str === 'string' ? str.replace(/ /g, '\xa0') : str) || '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,4 +2,5 @@ export * from './form-controls.module';
|
|||||||
export * from './masks';
|
export * from './masks';
|
||||||
export * from './validators';
|
export * from './validators';
|
||||||
export * from './format-input';
|
export * from './format-input';
|
||||||
|
export * from './range-datepicker';
|
||||||
export * from './utils';
|
export * from './utils';
|
||||||
|
@ -0,0 +1,38 @@
|
|||||||
|
@import '~@angular/material/theming';
|
||||||
|
|
||||||
|
@mixin dsh-range-datepicker-theme($theme) {
|
||||||
|
$gray: map-get($theme, gray);
|
||||||
|
$bg: map-get($gray, 200);
|
||||||
|
$foreground: map-get($theme, foreground);
|
||||||
|
$text: map-get($foreground, text);
|
||||||
|
|
||||||
|
.dsh-range-datepicker {
|
||||||
|
&-button {
|
||||||
|
border-color: mat-color($foreground, divider, 0.12);
|
||||||
|
color: $text;
|
||||||
|
|
||||||
|
&:enabled {
|
||||||
|
&:hover,
|
||||||
|
&:active {
|
||||||
|
background-color: $bg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:disabled {
|
||||||
|
color: map-get($foreground, disabled-button);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin dsh-range-datepicker-typography($config) {
|
||||||
|
.dsh-range-datepicker {
|
||||||
|
&-button {
|
||||||
|
font: {
|
||||||
|
family: mat-font-family($config, button);
|
||||||
|
size: mat-font-size($config, button);
|
||||||
|
weight: mat-font-weight($config, button);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
2
src/app/form-controls/range-datepicker/index.ts
Normal file
2
src/app/form-controls/range-datepicker/index.ts
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
export * from './range-datepicker.module';
|
||||||
|
export * from './range-datepicker.component';
|
103
src/app/form-controls/range-datepicker/range-date.pipe.ts
Normal file
103
src/app/form-controls/range-datepicker/range-date.pipe.ts
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
import { Pipe, PipeTransform, Inject, LOCALE_ID } from '@angular/core';
|
||||||
|
import { formatDate } from '@angular/common';
|
||||||
|
import { Moment } from 'moment';
|
||||||
|
import { TranslocoService } from '@ngneat/transloco';
|
||||||
|
import moment from 'moment';
|
||||||
|
|
||||||
|
@Pipe({ name: 'rangeDate' })
|
||||||
|
export class RangeDatePipe implements PipeTransform {
|
||||||
|
constructor(@Inject(LOCALE_ID) private locale: string, private transloco: TranslocoService) {}
|
||||||
|
|
||||||
|
transform({ begin, end }: { begin: Moment; end: Moment }): string {
|
||||||
|
if (begin.isSame(begin.clone().startOf('year'), 'day') && end.isSame(end.clone().endOf('year'), 'day')) {
|
||||||
|
return this.toYearStr(begin, end);
|
||||||
|
}
|
||||||
|
if (begin.isSame(begin.clone().startOf('month'), 'day') && end.isSame(end.clone().endOf('month'), 'day')) {
|
||||||
|
return this.toMonthStr(begin, end);
|
||||||
|
}
|
||||||
|
if (begin.isSame(moment().startOf('week'), 'day') && end.isSame(moment().endOf('week'), 'day')) {
|
||||||
|
return this.rangeDateTranslate('currentWeek');
|
||||||
|
}
|
||||||
|
return this.toDateStr(begin, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 2020 год
|
||||||
|
* С 2019 по 2020 год
|
||||||
|
*/
|
||||||
|
private toYearStr(begin: Moment, end: Moment) {
|
||||||
|
const endStr = `${end.year()} ${this.rangeDateTranslate('year')}`;
|
||||||
|
|
||||||
|
if (begin.isSame(end, 'year')) {
|
||||||
|
return endStr;
|
||||||
|
}
|
||||||
|
|
||||||
|
const fromStr = this.rangeDateTranslate('from');
|
||||||
|
const toStr = this.rangeDateTranslate('to');
|
||||||
|
|
||||||
|
return `${fromStr} ${begin.year()} ${toStr} ${endStr}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Январь
|
||||||
|
* Январь 2020
|
||||||
|
*
|
||||||
|
* С января по март
|
||||||
|
* С января 2019 по март 2019 / С декабря 2019 по март 2020
|
||||||
|
*/
|
||||||
|
private toMonthStr(begin: Moment, end: Moment) {
|
||||||
|
const fromStr = this.rangeDateTranslate('from');
|
||||||
|
const toStr = this.rangeDateTranslate('to');
|
||||||
|
|
||||||
|
const currentYear = this.isCurrentYear(begin, end);
|
||||||
|
const beginStr = this.formatDate(begin, false, true, !currentYear);
|
||||||
|
const endStr = this.formatStandaloneDate(end, false, true, !currentYear);
|
||||||
|
|
||||||
|
if (begin.isSame(end, 'month')) {
|
||||||
|
return this.capitalizeFirstLetter(endStr);
|
||||||
|
}
|
||||||
|
|
||||||
|
return `${fromStr} ${beginStr} ${toStr} ${endStr}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 2 января
|
||||||
|
* 2 января 2020
|
||||||
|
*
|
||||||
|
* Со 2 по 8 марта / Со 2 января по 8 марта
|
||||||
|
* Со 2 по 8 марта 2019 / Со 2 января 2019 по 8 марта 2020
|
||||||
|
*/
|
||||||
|
private toDateStr(begin: Moment, end: Moment) {
|
||||||
|
const fromByDayStr = this.rangeDateTranslate(begin.date() === 2 ? 'fromStartWith2' : 'from');
|
||||||
|
const toStr = this.rangeDateTranslate('to');
|
||||||
|
|
||||||
|
const beginStr = this.formatDate(begin, true, !begin.isSame(end, 'month'), !begin.isSame(end, 'year'));
|
||||||
|
const endStr = this.formatDate(end, true, true, !this.isCurrentYear(begin, end));
|
||||||
|
|
||||||
|
if (begin.isSame(end, 'day')) {
|
||||||
|
return endStr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return `${fromByDayStr} ${beginStr} ${toStr} ${endStr}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
private isCurrentYear(begin: Moment, end: Moment) {
|
||||||
|
return moment().isSame(begin, 'year') && moment().isSame(end, 'year');
|
||||||
|
}
|
||||||
|
|
||||||
|
private capitalizeFirstLetter(str: string) {
|
||||||
|
return str.charAt(0).toUpperCase() + str.slice(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private rangeDateTranslate(key: string) {
|
||||||
|
return this.transloco.translate(`rangeDate.${key}`, null, 'range-datepicker|scoped');
|
||||||
|
}
|
||||||
|
|
||||||
|
private formatDate(date: Moment, d: boolean = false, m: boolean = false, y: boolean = false) {
|
||||||
|
return formatDate(date.toDate(), [d && 'd', m && 'MMMM', y && 'y'].filter(v => v).join(' '), this.locale);
|
||||||
|
}
|
||||||
|
|
||||||
|
private formatStandaloneDate(date: Moment, d: boolean = false, m: boolean = false, y: boolean = false) {
|
||||||
|
return formatDate(date.toDate(), [d && 'd', m && 'LLLL', y && 'y'].filter(v => v).join(' '), this.locale);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,52 @@
|
|||||||
|
<ng-container *transloco="let t; scope: 'range-datepicker'; read: 'rangeDatepicker'">
|
||||||
|
<div fxLayout class="dsh-range-datepicker">
|
||||||
|
<button (click)="back()" class="dsh-range-datepicker-button dsh-range-datepicker-back" [disabled]="isMinDate">
|
||||||
|
<mat-icon>keyboard_arrow_left</mat-icon>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
[matMenuTriggerFor]="menu"
|
||||||
|
fxFlex
|
||||||
|
class="dsh-range-datepicker-button dsh-range-datepicker-input"
|
||||||
|
title="{{ value?.begin | date: 'shortDate' }} - {{ value?.end | date: 'shortDate' }}"
|
||||||
|
>
|
||||||
|
<div class="dsh-range-datepicker-input-content">
|
||||||
|
<ng-container *ngIf="publicValue?.begin && publicValue?.end; else placeholder" [ngSwitch]="period">
|
||||||
|
{{ publicValue | rangeDate }}
|
||||||
|
</ng-container>
|
||||||
|
<ng-template #placeholder>
|
||||||
|
{{ t.selectPeriod }}
|
||||||
|
</ng-template>
|
||||||
|
<input
|
||||||
|
#input
|
||||||
|
matInput
|
||||||
|
[formControl]="formControl"
|
||||||
|
[satDatepicker]="picker"
|
||||||
|
[min]="minDate"
|
||||||
|
[max]="maxDate"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
(click)="forward()"
|
||||||
|
class="dsh-range-datepicker-button dsh-range-datepicker-forward"
|
||||||
|
[disabled]="isMaxDate"
|
||||||
|
>
|
||||||
|
<mat-icon>keyboard_arrow_right</mat-icon>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<mat-menu #menu="matMenu">
|
||||||
|
<button mat-menu-item (click)="selectPeriod('week')">{{ t.select.currentWeek }}</button>
|
||||||
|
<button mat-menu-item (click)="selectPeriod('month')">{{ current | date: 'LLLL' | titlecase }}</button>
|
||||||
|
<button mat-menu-item (click)="selectPeriod('3month')">{{ t.select.threeMonths }}</button>
|
||||||
|
<button mat-menu-item (click)="selectPeriod('year')">
|
||||||
|
{{ t.select.year | translocoParams: { year: current | date: 'y' } }}
|
||||||
|
</button>
|
||||||
|
<mat-divider class="dsh-range-datepicker-menu-divider"></mat-divider>
|
||||||
|
<button mat-menu-item (click)="picker.open(); selectPeriod()">
|
||||||
|
{{ t.select.period }}
|
||||||
|
</button>
|
||||||
|
</mat-menu>
|
||||||
|
|
||||||
|
<sat-datepicker #picker [rangeMode]="true"></sat-datepicker>
|
||||||
|
</ng-container>
|
@ -0,0 +1,69 @@
|
|||||||
|
$height: 50px;
|
||||||
|
$border-radius: 4px;
|
||||||
|
|
||||||
|
:host {
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dsh-range-datepicker {
|
||||||
|
&-button {
|
||||||
|
white-space: nowrap;
|
||||||
|
transition: background-color 0.25s ease-in-out;
|
||||||
|
background-color: transparent;
|
||||||
|
display: block;
|
||||||
|
outline: none;
|
||||||
|
cursor: pointer;
|
||||||
|
border: 1px solid;
|
||||||
|
padding: 0 10px;
|
||||||
|
margin: 0;
|
||||||
|
line-height: $height;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-back,
|
||||||
|
&-forward {
|
||||||
|
width: $height;
|
||||||
|
|
||||||
|
& > * {
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-back {
|
||||||
|
border-top-left-radius: $border-radius;
|
||||||
|
border-bottom-left-radius: $border-radius;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-forward {
|
||||||
|
border-top-right-radius: $border-radius;
|
||||||
|
border-bottom-right-radius: $border-radius;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-input {
|
||||||
|
position: relative;
|
||||||
|
border-left: none;
|
||||||
|
border-right: none;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
input {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
border: none;
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-input-content {
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-menu-divider {
|
||||||
|
width: calc(100% + 20px);
|
||||||
|
transform: translate(-10px, -5px);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,199 @@
|
|||||||
|
import { Component, Input, ViewChild, ElementRef } from '@angular/core';
|
||||||
|
import { MatFormFieldControl } from '@angular/material';
|
||||||
|
import moment, { Moment } from 'moment';
|
||||||
|
import { SatDatepickerRangeValue } from 'saturn-datepicker';
|
||||||
|
import { SetIntersection } from 'utility-types';
|
||||||
|
import { map } from 'rxjs/operators';
|
||||||
|
|
||||||
|
import { CustomFormControl } from '../utils';
|
||||||
|
|
||||||
|
type InternalRange = SatDatepickerRangeValue<Date>;
|
||||||
|
export type Range = SatDatepickerRangeValue<Moment>;
|
||||||
|
|
||||||
|
type MomentPeriod = SetIntersection<moment.unitOfTime.StartOf, 'week' | 'month' | 'year'>;
|
||||||
|
type Period = MomentPeriod | '3month';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'dsh-range-datepicker',
|
||||||
|
templateUrl: 'range-datepicker.component.html',
|
||||||
|
styleUrls: ['range-datepicker.component.scss'],
|
||||||
|
providers: [{ provide: MatFormFieldControl, useExisting: RangeDatepickerComponent }]
|
||||||
|
})
|
||||||
|
export class RangeDatepickerComponent extends CustomFormControl<InternalRange, Range> {
|
||||||
|
minDate = moment()
|
||||||
|
.subtract(15, 'year')
|
||||||
|
.startOf('year')
|
||||||
|
.toDate();
|
||||||
|
@Input()
|
||||||
|
set min(min: Moment) {
|
||||||
|
this.minDate = min.toDate();
|
||||||
|
}
|
||||||
|
get min() {
|
||||||
|
return moment(this.minDate);
|
||||||
|
}
|
||||||
|
|
||||||
|
maxDate = moment()
|
||||||
|
.endOf('day')
|
||||||
|
.toDate();
|
||||||
|
@Input()
|
||||||
|
set max(max: Moment) {
|
||||||
|
this.maxDate = max.toDate();
|
||||||
|
}
|
||||||
|
get max() {
|
||||||
|
return moment(this.maxDate);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ViewChild('input', { static: false })
|
||||||
|
set input(input: ElementRef<HTMLInputElement>) {
|
||||||
|
if (input && input.nativeElement) {
|
||||||
|
this.setInputElement(input.nativeElement);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
current = moment();
|
||||||
|
period: Period = null;
|
||||||
|
formControlSubscription = this.formControl.valueChanges.pipe(map(this.toPublicValue.bind(this))).subscribe(() => {
|
||||||
|
if (!this.period) {
|
||||||
|
this.period = this.takeUnitOfTime();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
get isMaxDate() {
|
||||||
|
return this.publicValue.end.isSameOrAfter(this.max, 'day');
|
||||||
|
}
|
||||||
|
|
||||||
|
get isMinDate() {
|
||||||
|
return this.publicValue.begin.isSameOrBefore(this.min, 'day');
|
||||||
|
}
|
||||||
|
|
||||||
|
toPublicValue({ begin, end }: InternalRange): Range {
|
||||||
|
return { begin: moment(begin), end: moment(end) };
|
||||||
|
}
|
||||||
|
|
||||||
|
toInternalValue({ begin, end }: Range): InternalRange {
|
||||||
|
return { begin: begin.toDate(), end: end.toDate() };
|
||||||
|
}
|
||||||
|
|
||||||
|
back() {
|
||||||
|
const { begin, end } = this.publicValue;
|
||||||
|
switch (this.period) {
|
||||||
|
case 'year': {
|
||||||
|
const newBegin = begin.clone().subtract(1, 'year');
|
||||||
|
this.changeRange(newBegin, newBegin.clone().endOf('year'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case '3month': {
|
||||||
|
const newBegin = begin.clone().subtract(3, 'month');
|
||||||
|
this.changeRange(
|
||||||
|
newBegin,
|
||||||
|
newBegin
|
||||||
|
.clone()
|
||||||
|
.add(2, 'month')
|
||||||
|
.endOf('month')
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case 'month': {
|
||||||
|
const newBegin = begin.clone().subtract(1, 'month');
|
||||||
|
this.changeRange(newBegin, newBegin.clone().endOf('month'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case 'week': {
|
||||||
|
const newBegin = begin.clone().subtract(1, 'week');
|
||||||
|
this.changeRange(newBegin, newBegin.clone().endOf('week'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
const diff = end.diff(begin);
|
||||||
|
this.changeRange(begin.subtract(diff).subtract(1, 'day'), end.subtract(diff).subtract(1, 'day'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
forward() {
|
||||||
|
const { begin, end } = this.publicValue;
|
||||||
|
switch (this.period) {
|
||||||
|
case 'year': {
|
||||||
|
const newBegin = begin.clone().add(1, 'year');
|
||||||
|
this.changeRange(newBegin, newBegin.clone().endOf('year'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case '3month': {
|
||||||
|
const newBegin = begin.clone().add(3, 'month');
|
||||||
|
this.changeRange(
|
||||||
|
newBegin,
|
||||||
|
newBegin
|
||||||
|
.clone()
|
||||||
|
.add(2, 'month')
|
||||||
|
.endOf('month')
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case 'month': {
|
||||||
|
const newBegin = begin.clone().add(1, 'month');
|
||||||
|
this.changeRange(newBegin, newBegin.clone().endOf('month'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case 'week': {
|
||||||
|
const newBegin = begin.clone().add(1, 'week');
|
||||||
|
this.changeRange(newBegin, newBegin.clone().endOf('week'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
const diff = end.diff(begin, 'day');
|
||||||
|
this.changeRange(begin.clone().add(diff + 1, 'day'), end.clone().add(diff + 1, 'day'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
selectPeriod(period: Period = null) {
|
||||||
|
this.period = period;
|
||||||
|
switch (period) {
|
||||||
|
case 'year':
|
||||||
|
this.changeRange(moment().startOf('year'), moment().endOf('year'));
|
||||||
|
break;
|
||||||
|
case '3month':
|
||||||
|
this.changeRange(
|
||||||
|
moment()
|
||||||
|
.subtract(2, 'month')
|
||||||
|
.startOf('month'),
|
||||||
|
moment().endOf('month')
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case 'month':
|
||||||
|
this.changeRange(moment().startOf('month'), moment().endOf('month'));
|
||||||
|
break;
|
||||||
|
case 'week':
|
||||||
|
this.changeRange(moment().startOf('week'), moment().endOf('week'));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private checkIsUnitOfTime(unitOfTime: MomentPeriod, countOfUnits = 1): boolean {
|
||||||
|
const { begin, end } = this.publicValue;
|
||||||
|
const beginOfUnit = begin.clone().startOf(unitOfTime);
|
||||||
|
const expectedEndOfPeriodByBegin = beginOfUnit
|
||||||
|
.clone()
|
||||||
|
.add(countOfUnits - 1, unitOfTime)
|
||||||
|
.endOf(unitOfTime);
|
||||||
|
return begin.isSame(beginOfUnit, 'day') && end.isSame(expectedEndOfPeriodByBegin, 'day');
|
||||||
|
}
|
||||||
|
|
||||||
|
private takeUnitOfTime(): Period {
|
||||||
|
if (this.checkIsUnitOfTime('year')) {
|
||||||
|
return 'year';
|
||||||
|
}
|
||||||
|
if (this.checkIsUnitOfTime('month', 3)) {
|
||||||
|
return '3month';
|
||||||
|
}
|
||||||
|
if (this.checkIsUnitOfTime('month')) {
|
||||||
|
return 'month';
|
||||||
|
}
|
||||||
|
if (this.checkIsUnitOfTime('week')) {
|
||||||
|
return 'week';
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private changeRange(begin: Moment, end: Moment) {
|
||||||
|
this.publicValue = { begin, end };
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,31 @@
|
|||||||
|
import { NgModule } from '@angular/core';
|
||||||
|
import { SatDatepickerModule, SatNativeDateModule } from 'saturn-datepicker';
|
||||||
|
import { MatNativeDateModule, MatMenuModule, MatIconModule, MatInputModule, MatDividerModule } from '@angular/material';
|
||||||
|
import { FlexLayoutModule } from '@angular/flex-layout';
|
||||||
|
import { ReactiveFormsModule } from '@angular/forms';
|
||||||
|
import { CommonModule } from '@angular/common';
|
||||||
|
import { TranslocoModule } from '@ngneat/transloco';
|
||||||
|
|
||||||
|
import { RangeDatepickerComponent } from './range-datepicker.component';
|
||||||
|
import { ButtonToggleModule } from '../../button-toggle';
|
||||||
|
import { RangeDatePipe } from './range-date.pipe';
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
imports: [
|
||||||
|
SatDatepickerModule,
|
||||||
|
SatNativeDateModule,
|
||||||
|
MatNativeDateModule,
|
||||||
|
MatMenuModule,
|
||||||
|
MatIconModule,
|
||||||
|
ButtonToggleModule,
|
||||||
|
FlexLayoutModule,
|
||||||
|
MatInputModule,
|
||||||
|
ReactiveFormsModule,
|
||||||
|
CommonModule,
|
||||||
|
TranslocoModule,
|
||||||
|
MatDividerModule
|
||||||
|
],
|
||||||
|
declarations: [RangeDatepickerComponent, RangeDatePipe],
|
||||||
|
exports: [RangeDatepickerComponent]
|
||||||
|
})
|
||||||
|
export class RangeDatepickerModule {}
|
@ -13,7 +13,8 @@ import {
|
|||||||
Optional,
|
Optional,
|
||||||
Self,
|
Self,
|
||||||
HostListener,
|
HostListener,
|
||||||
OnChanges
|
OnChanges,
|
||||||
|
SimpleChanges
|
||||||
} from '@angular/core';
|
} from '@angular/core';
|
||||||
import uuid from 'uuid';
|
import uuid from 'uuid';
|
||||||
import { AutofillMonitor } from '@angular/cdk/text-field';
|
import { AutofillMonitor } from '@angular/cdk/text-field';
|
||||||
@ -21,8 +22,8 @@ import { Platform } from '@angular/cdk/platform';
|
|||||||
|
|
||||||
import { InputMixinBase } from './input-base';
|
import { InputMixinBase } from './input-base';
|
||||||
|
|
||||||
export class CustomFormControl<T extends any = string> extends InputMixinBase
|
export class CustomFormControl<I extends any = any, P extends any = I> extends InputMixinBase
|
||||||
implements AfterViewInit, ControlValueAccessor, MatFormFieldControl<T>, OnDestroy, DoCheck, OnChanges {
|
implements AfterViewInit, ControlValueAccessor, MatFormFieldControl<I>, OnDestroy, DoCheck, OnChanges {
|
||||||
/** The aria-describedby attribute on the input for improved a11y. */
|
/** The aria-describedby attribute on the input for improved a11y. */
|
||||||
@HostBinding('attr.aria-describedby') _ariaDescribedby: string;
|
@HostBinding('attr.aria-describedby') _ariaDescribedby: string;
|
||||||
|
|
||||||
@ -32,6 +33,7 @@ export class CustomFormControl<T extends any = string> extends InputMixinBase
|
|||||||
|
|
||||||
autofilled = false;
|
autofilled = false;
|
||||||
|
|
||||||
|
protected _disabled = false;
|
||||||
@Input()
|
@Input()
|
||||||
get disabled(): boolean {
|
get disabled(): boolean {
|
||||||
if (this.ngControl && this.ngControl.disabled !== null) {
|
if (this.ngControl && this.ngControl.disabled !== null) {
|
||||||
@ -49,8 +51,8 @@ export class CustomFormControl<T extends any = string> extends InputMixinBase
|
|||||||
this.stateChanges.next();
|
this.stateChanges.next();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
protected _disabled = false;
|
|
||||||
|
|
||||||
|
protected _id: string;
|
||||||
@HostBinding('attr.id')
|
@HostBinding('attr.id')
|
||||||
@Input()
|
@Input()
|
||||||
get id(): string {
|
get id(): string {
|
||||||
@ -59,11 +61,11 @@ export class CustomFormControl<T extends any = string> extends InputMixinBase
|
|||||||
set id(value: string) {
|
set id(value: string) {
|
||||||
this._id = value || `custom-input-${uuid()}`;
|
this._id = value || `custom-input-${uuid()}`;
|
||||||
}
|
}
|
||||||
protected _id: string;
|
|
||||||
|
|
||||||
@Input()
|
@Input()
|
||||||
placeholder: string;
|
placeholder: string;
|
||||||
|
|
||||||
|
protected _required = false;
|
||||||
@Input()
|
@Input()
|
||||||
get required(): boolean {
|
get required(): boolean {
|
||||||
return this._required;
|
return this._required;
|
||||||
@ -71,21 +73,27 @@ export class CustomFormControl<T extends any = string> extends InputMixinBase
|
|||||||
set required(value: boolean) {
|
set required(value: boolean) {
|
||||||
this._required = coerceBooleanProperty(value);
|
this._required = coerceBooleanProperty(value);
|
||||||
}
|
}
|
||||||
protected _required = false;
|
|
||||||
|
|
||||||
protected type = 'text';
|
protected type = 'text';
|
||||||
|
|
||||||
@Input()
|
@Input()
|
||||||
get value(): T {
|
get value() {
|
||||||
return this.formControl.value;
|
return this.formControl.value;
|
||||||
}
|
}
|
||||||
set value(value: T) {
|
set value(value: I) {
|
||||||
this.formControl.setValue(value);
|
this.formControl.setValue(value);
|
||||||
this.stateChanges.next();
|
this.stateChanges.next();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get publicValue() {
|
||||||
|
return this.toPublicValue(this.value);
|
||||||
|
}
|
||||||
|
set publicValue(value: P) {
|
||||||
|
this.value = this.toInternalValue(value);
|
||||||
|
}
|
||||||
|
|
||||||
get details() {
|
get details() {
|
||||||
return this.getDetails(this.value);
|
return this.getDetails(this.publicValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
@HostBinding('class.floating')
|
@HostBinding('class.floating')
|
||||||
@ -93,16 +101,13 @@ export class CustomFormControl<T extends any = string> extends InputMixinBase
|
|||||||
return this.focused || !this.empty;
|
return this.focused || !this.empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
_inputRef = new ElementRef<HTMLInputElement>(null);
|
inputRef = new ElementRef<HTMLInputElement>(null);
|
||||||
get inputRef() {
|
|
||||||
this._inputRef.nativeElement = this.elementRef.nativeElement.querySelector('input');
|
|
||||||
return this._inputRef;
|
|
||||||
}
|
|
||||||
|
|
||||||
get empty(): boolean {
|
get empty(): boolean {
|
||||||
return !this.formControl.value;
|
return !this.formControl.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _focused = false;
|
||||||
get focused(): boolean {
|
get focused(): boolean {
|
||||||
return this._focused;
|
return this._focused;
|
||||||
}
|
}
|
||||||
@ -113,8 +118,8 @@ export class CustomFormControl<T extends any = string> extends InputMixinBase
|
|||||||
|
|
||||||
formControl = new FormControl();
|
formControl = new FormControl();
|
||||||
autocompleteOrigin: MatAutocompleteOrigin;
|
autocompleteOrigin: MatAutocompleteOrigin;
|
||||||
|
monitorsRegistered = false;
|
||||||
|
|
||||||
private _focused = false;
|
|
||||||
private _onTouched: () => void;
|
private _onTouched: () => void;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@ -136,7 +141,7 @@ export class CustomFormControl<T extends any = string> extends InputMixinBase
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnChanges() {
|
ngOnChanges(_changes?: SimpleChanges) {
|
||||||
this.stateChanges.next();
|
this.stateChanges.next();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,15 +155,7 @@ export class CustomFormControl<T extends any = string> extends InputMixinBase
|
|||||||
}
|
}
|
||||||
|
|
||||||
ngAfterViewInit(): void {
|
ngAfterViewInit(): void {
|
||||||
if (this.platform.isBrowser) {
|
this.setInputElement();
|
||||||
this.autofillMonitor.monitor(this.inputRef).subscribe(event => {
|
|
||||||
this.autofilled = event.isAutofilled;
|
|
||||||
this.stateChanges.next();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
this.focusMonitor.monitor(this.elementRef.nativeElement, true).subscribe(focusOrigin => {
|
|
||||||
this.focused = !!focusOrigin;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnDestroy() {
|
ngOnDestroy() {
|
||||||
@ -180,14 +177,29 @@ export class CustomFormControl<T extends any = string> extends InputMixinBase
|
|||||||
this._onTouched();
|
this._onTouched();
|
||||||
}
|
}
|
||||||
|
|
||||||
registerOnChange(onChange: (value: T) => void): void {
|
registerOnChange(onChange: (value: P) => void): void {
|
||||||
this.formControl.valueChanges.subscribe(v => onChange(this.getValue(v)));
|
this.formControl.valueChanges.subscribe(v => onChange(this.toPublicValue(v)));
|
||||||
}
|
}
|
||||||
|
|
||||||
registerOnTouched(onTouched: () => void): void {
|
registerOnTouched(onTouched: () => void): void {
|
||||||
this._onTouched = onTouched;
|
this._onTouched = onTouched;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private registerMonitors() {
|
||||||
|
if (!this.monitorsRegistered && this.inputRef.nativeElement) {
|
||||||
|
this.monitorsRegistered = true;
|
||||||
|
if (this.platform.isBrowser) {
|
||||||
|
this.autofillMonitor.monitor(this.inputRef).subscribe(event => {
|
||||||
|
this.autofilled = event.isAutofilled;
|
||||||
|
this.stateChanges.next();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
this.focusMonitor.monitor(this.elementRef.nativeElement, true).subscribe(focusOrigin => {
|
||||||
|
this.focused = !!focusOrigin;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
setDescribedByIds(ids: string[]): void {
|
setDescribedByIds(ids: string[]): void {
|
||||||
this._ariaDescribedby = ids.join(' ');
|
this._ariaDescribedby = ids.join(' ');
|
||||||
}
|
}
|
||||||
@ -202,15 +214,24 @@ export class CustomFormControl<T extends any = string> extends InputMixinBase
|
|||||||
this.disabled = shouldDisable;
|
this.disabled = shouldDisable;
|
||||||
}
|
}
|
||||||
|
|
||||||
writeValue(value: string): void {
|
setInputElement(input: HTMLInputElement = this.elementRef.nativeElement.querySelector('input')) {
|
||||||
this.formControl.setValue(value, { emitEvent: false });
|
this.inputRef.nativeElement = input;
|
||||||
|
this.registerMonitors();
|
||||||
}
|
}
|
||||||
|
|
||||||
getDetails(value: T) {
|
writeValue(value: P): void {
|
||||||
return value;
|
this.formControl.setValue(this.toInternalValue(value), { emitEvent: false });
|
||||||
}
|
}
|
||||||
|
|
||||||
getValue(value = this.value): T {
|
protected getDetails(value: P): string {
|
||||||
return value;
|
return value as any;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected toInternalValue(value: P): I {
|
||||||
|
return value as any;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected toPublicValue(value: I): P {
|
||||||
|
return value as any;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,22 +6,34 @@
|
|||||||
}"
|
}"
|
||||||
(dshResized)="cardHeight = $event.height"
|
(dshResized)="cardHeight = $event.height"
|
||||||
>
|
>
|
||||||
<div (dshResized)="setBaseContentHeight($event.height)" class="dsh-float-panel-base">
|
<div class="dsh-float-panel-base" (dshResized)="setBaseContentHeight($event.height)">
|
||||||
<div fxLayout fxLayout.lt-md="column" [fxLayoutGap]="layoutGap">
|
<div fxLayout="column" [fxLayoutGap]="layoutGap">
|
||||||
<div fxFlex.gt-sm>
|
<div fxLayout fxLayout.lt-md="column" [fxLayoutGap]="layoutGap">
|
||||||
<ng-content></ng-content>
|
<div fxFlex.gt-sm>
|
||||||
|
<ng-content></ng-content>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
*ngIf="!expanded && floatPanelMore"
|
||||||
|
class="dsh-float-panel-actions"
|
||||||
|
fxLayout
|
||||||
|
fxLayoutAlign="center center"
|
||||||
|
>
|
||||||
|
<button dsh-icon-button (click)="expandToggle()" fxHide.lt-md>
|
||||||
|
<mat-icon svgIcon="keyboard_arrow_down"></mat-icon>
|
||||||
|
</button>
|
||||||
|
<button dsh-button (click)="expandToggle()" fxFlex fxHide.gt-sm>
|
||||||
|
{{ t.showMore }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div *ngIf="!expanded" class="dsh-float-panel-actions" fxLayout fxLayoutAlign="center center">
|
<div fxLayout fxLayoutAlign="center" *ngIf="!floatPanelMore && floatPanelActions">
|
||||||
<button dsh-icon-button (click)="expandToggle()" fxHide.lt-md>
|
<div>
|
||||||
<mat-icon svgIcon="keyboard_arrow_down"></mat-icon>
|
<ng-container *ngTemplateOutlet="floatPanelActions?.templateRef"></ng-container>
|
||||||
</button>
|
</div>
|
||||||
<button dsh-button (click)="expandToggle()" fxFlex fxHide.gt-sm>
|
|
||||||
{{ t.showMore }}
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="dsh-float-panel-more" [@expand]="expandTrigger" *ngIf="expanded">
|
<div class="dsh-float-panel-more" [@expand]="expandTrigger" *ngIf="expanded && floatPanelMore">
|
||||||
<div (dshResized)="setMoreContentHeight($event.height)">
|
<div (dshResized)="setMoreContentHeight($event.height)">
|
||||||
<div fxLayout="column" [fxLayoutGap]="layoutGap">
|
<div fxLayout="column" [fxLayoutGap]="layoutGap">
|
||||||
<div class="dsh-float-panel-more-content">
|
<div class="dsh-float-panel-more-content">
|
||||||
|
@ -29,6 +29,7 @@ import { LastUpdatedModule } from '../operations/last-updated/last-updated.modul
|
|||||||
import { SpinnerModule } from '../../../spinner';
|
import { SpinnerModule } from '../../../spinner';
|
||||||
import { ActionsComponent } from './table/actions';
|
import { ActionsComponent } from './table/actions';
|
||||||
import { CreateReportDialogComponent } from './create-report-dialog';
|
import { CreateReportDialogComponent } from './create-report-dialog';
|
||||||
|
import { FormControlsModule } from '../../../form-controls';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [
|
imports: [
|
||||||
@ -54,7 +55,8 @@ import { CreateReportDialogComponent } from './create-report-dialog';
|
|||||||
SpinnerModule,
|
SpinnerModule,
|
||||||
MatDialogModule,
|
MatDialogModule,
|
||||||
MatSnackBarModule,
|
MatSnackBarModule,
|
||||||
MatMenuModule
|
MatMenuModule,
|
||||||
|
FormControlsModule
|
||||||
],
|
],
|
||||||
declarations: [
|
declarations: [
|
||||||
ReportsComponent,
|
ReportsComponent,
|
||||||
|
@ -1,10 +1,8 @@
|
|||||||
import { Moment } from 'moment';
|
|
||||||
|
|
||||||
import { Report } from '../../../../api-codegen/anapi';
|
import { Report } from '../../../../api-codegen/anapi';
|
||||||
|
import { Range } from '../../../../form-controls';
|
||||||
|
|
||||||
export interface FormParams {
|
export interface FormParams {
|
||||||
fromTime: Moment;
|
date: Range;
|
||||||
toTime: Moment;
|
|
||||||
reportType: Report.ReportTypeEnum;
|
reportType: Report.ReportTypeEnum;
|
||||||
shopID?: string;
|
shopID?: string;
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,8 @@
|
|||||||
|
import { Report } from '../../../../api-codegen/anapi';
|
||||||
|
|
||||||
|
export interface QueryParams {
|
||||||
|
fromTime: string;
|
||||||
|
toTime: string;
|
||||||
|
reportType: Report.ReportTypeEnum;
|
||||||
|
shopID?: string;
|
||||||
|
}
|
@ -1,65 +1,34 @@
|
|||||||
<dsh-float-panel *transloco="let r; scope: 'reports'; read: 'reports'" [formGroup]="form" [(expanded)]="expanded">
|
<dsh-float-panel *transloco="let r; scope: 'reports'; read: 'reports'" [formGroup]="form">
|
||||||
<ng-container *transloco="let t">
|
<dsh-justify-wrapper
|
||||||
<div
|
fxLayout
|
||||||
fxLayout
|
fxLayoutGap="20px"
|
||||||
fxLayout.lt-md="column"
|
fxLayoutAlign="space-between center"
|
||||||
fxLayoutGap="20px"
|
fxLayout.lt-md="column"
|
||||||
fxLayoutAlign="space-between center"
|
fxLayoutAlign.lt-md="space-between stretch"
|
||||||
fxLayoutAlign.lt-md="space-between stretch"
|
*transloco="let t"
|
||||||
>
|
>
|
||||||
<dsh-daterange-selector
|
<dsh-range-datepicker formControlName="date" fxFlex></dsh-range-datepicker>
|
||||||
fxFlex.gt-sm
|
<mat-form-field fxFlex>
|
||||||
[value]="form.value"
|
<mat-label>{{ r.filter.shopID }}</mat-label>
|
||||||
(selectDaterange)="selectDaterange($event)"
|
<mat-select formControlName="shopID">
|
||||||
(selectMore)="expanded = true"
|
<mat-option>
|
||||||
></dsh-daterange-selector>
|
{{ t.any }}
|
||||||
<dsh-justify-wrapper fxFlex.gt-sm fxLayout fxLayout.lt-md="column" fxLayoutGap="20px">
|
</mat-option>
|
||||||
<mat-form-field fxFlex>
|
<mat-option *ngFor="let shopInfo of shopsInfo$ | async" [value]="shopInfo.shopID">
|
||||||
<mat-label>{{ r.filter.shopID }}</mat-label>
|
{{ shopInfo.name }}
|
||||||
<mat-select formControlName="shopID">
|
</mat-option>
|
||||||
<mat-option>
|
</mat-select>
|
||||||
{{ t.any }}
|
</mat-form-field>
|
||||||
</mat-option>
|
<mat-form-field fxFlex>
|
||||||
<mat-option *ngFor="let shopInfo of shopsInfo$ | async" [value]="shopInfo.shopID">
|
<mat-label>{{ r.filter.type }}</mat-label>
|
||||||
{{ shopInfo.name }}
|
<mat-select formControlName="reportType">
|
||||||
</mat-option>
|
<mat-option>
|
||||||
</mat-select>
|
{{ t.any }}
|
||||||
</mat-form-field>
|
</mat-option>
|
||||||
<mat-form-field fxFlex>
|
<mat-option *ngFor="let type of reportTypes" [value]="type">
|
||||||
<mat-label>{{ r.filter.type }}</mat-label>
|
{{ r.type[type] }}
|
||||||
<mat-select formControlName="reportType">
|
</mat-option>
|
||||||
<mat-option>
|
</mat-select>
|
||||||
{{ t.any }}
|
</mat-form-field>
|
||||||
</mat-option>
|
</dsh-justify-wrapper>
|
||||||
<mat-option *ngFor="let type of reportTypes" [value]="type">
|
|
||||||
{{ r.type[type] }}
|
|
||||||
</mat-option>
|
|
||||||
</mat-select>
|
|
||||||
</mat-form-field>
|
|
||||||
</dsh-justify-wrapper>
|
|
||||||
</div>
|
|
||||||
<dsh-float-panel-more>
|
|
||||||
<div fxLayout fxLayout.lt-md="column" fxLayoutGap.gt-sm="20px">
|
|
||||||
<div fxFlex.gt-sm fxLayout fxLayout.xs="column" fxLayoutGap.gt-xs="20px">
|
|
||||||
<mat-form-field fxFlex>
|
|
||||||
<mat-label>{{ t.period.fromTime }}</mat-label>
|
|
||||||
<input required matInput formControlName="fromTime" [matDatepicker]="fromTime" />
|
|
||||||
<mat-datepicker-toggle matSuffix [for]="fromTime"></mat-datepicker-toggle>
|
|
||||||
<mat-datepicker #fromTime></mat-datepicker>
|
|
||||||
</mat-form-field>
|
|
||||||
<mat-form-field fxFlex>
|
|
||||||
<mat-label>{{ t.period.toTime }}</mat-label>
|
|
||||||
<input required matInput formControlName="toTime" [matDatepicker]="toTime" />
|
|
||||||
<mat-datepicker-toggle matSuffix [for]="toTime"></mat-datepicker-toggle>
|
|
||||||
<mat-datepicker #toTime></mat-datepicker>
|
|
||||||
</mat-form-field>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</dsh-float-panel-more>
|
|
||||||
<dsh-float-panel-actions>
|
|
||||||
<button dsh-button (click)="reset()">
|
|
||||||
{{ t.resetSearchParams }}
|
|
||||||
</button>
|
|
||||||
</dsh-float-panel-actions>
|
|
||||||
</ng-container>
|
|
||||||
</dsh-float-panel>
|
</dsh-float-panel>
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import { Component } from '@angular/core';
|
import { Component } from '@angular/core';
|
||||||
|
|
||||||
import { Report } from '../../../../api-codegen/anapi/swagger-codegen';
|
import { Report } from '../../../../api-codegen/anapi/swagger-codegen';
|
||||||
import { SearchFormValue } from '../../operations/search-form-value';
|
|
||||||
import { SearchFormService } from './search-form.service';
|
import { SearchFormService } from './search-form.service';
|
||||||
import { ReportsService } from '../reports.service';
|
import { ReportsService } from '../reports.service';
|
||||||
|
|
||||||
@ -13,16 +12,8 @@ import { ReportsService } from '../reports.service';
|
|||||||
export class SearchFormComponent {
|
export class SearchFormComponent {
|
||||||
form = this.searchFormService.form;
|
form = this.searchFormService.form;
|
||||||
reset = this.searchFormService.reset;
|
reset = this.searchFormService.reset;
|
||||||
|
|
||||||
shopsInfo$ = this.reportsService.shopsInfo$;
|
shopsInfo$ = this.reportsService.shopsInfo$;
|
||||||
|
|
||||||
reportTypes = Object.values(Report.ReportTypeEnum);
|
reportTypes = Object.values(Report.ReportTypeEnum);
|
||||||
|
|
||||||
expanded = false;
|
|
||||||
|
|
||||||
constructor(private searchFormService: SearchFormService, private reportsService: ReportsService) {}
|
constructor(private searchFormService: SearchFormService, private reportsService: ReportsService) {}
|
||||||
|
|
||||||
selectDaterange(v: SearchFormValue) {
|
|
||||||
this.form.patchValue(v);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -8,19 +8,20 @@ import { toSearchParams } from './to-search-params';
|
|||||||
import { FormParams } from './form-params';
|
import { FormParams } from './form-params';
|
||||||
import { toFormValue } from './to-form-value';
|
import { toFormValue } from './to-form-value';
|
||||||
import { toQueryParams } from './to-query-params';
|
import { toQueryParams } from './to-query-params';
|
||||||
|
import { QueryParams } from './query-params';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class SearchFormService {
|
export class SearchFormService {
|
||||||
static defaultParams: FormParams = {
|
defaultParams: FormParams = {
|
||||||
fromTime: moment()
|
|
||||||
.subtract(1, 'month')
|
|
||||||
.startOf('day'),
|
|
||||||
toTime: moment().endOf('day'),
|
|
||||||
shopID: null,
|
shopID: null,
|
||||||
reportType: null
|
reportType: null,
|
||||||
|
date: {
|
||||||
|
begin: moment().startOf('month'),
|
||||||
|
end: moment().endOf('month')
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
form = this.fb.group(SearchFormService.defaultParams);
|
form = this.fb.group(this.defaultParams);
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private fb: FormBuilder,
|
private fb: FormBuilder,
|
||||||
@ -36,7 +37,7 @@ export class SearchFormService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
reset() {
|
reset() {
|
||||||
this.form.setValue(SearchFormService.defaultParams);
|
this.form.setValue(this.defaultParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
private init() {
|
private init() {
|
||||||
@ -46,8 +47,8 @@ export class SearchFormService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private syncQueryParams() {
|
private syncQueryParams() {
|
||||||
const queryParams = this.route.snapshot.queryParams as Record<keyof FormParams, string>;
|
const queryParams = this.route.snapshot.queryParams as QueryParams;
|
||||||
const formValue = toFormValue(queryParams, SearchFormService.defaultParams);
|
const formValue = toFormValue(queryParams, this.defaultParams);
|
||||||
this.form.setValue(formValue);
|
this.form.setValue(formValue);
|
||||||
this.setQueryParams(formValue);
|
this.setQueryParams(formValue);
|
||||||
this.form.valueChanges.subscribe(v => this.setQueryParams(v));
|
this.form.valueChanges.subscribe(v => this.setQueryParams(v));
|
||||||
|
@ -2,16 +2,19 @@ import moment from 'moment';
|
|||||||
|
|
||||||
import { FormParams } from './form-params';
|
import { FormParams } from './form-params';
|
||||||
import { Report } from '../../../../api-codegen/anapi/swagger-codegen';
|
import { Report } from '../../../../api-codegen/anapi/swagger-codegen';
|
||||||
|
import { QueryParams } from './query-params';
|
||||||
|
|
||||||
export function toFormValue(
|
export function toFormValue(
|
||||||
{ fromTime, toTime, reportType, ...params }: Record<keyof FormParams, string>,
|
{ fromTime, toTime, reportType, ...params }: QueryParams,
|
||||||
defaultParams: FormParams
|
defaultParams: FormParams
|
||||||
): FormParams {
|
): FormParams {
|
||||||
return {
|
return {
|
||||||
...defaultParams,
|
...defaultParams,
|
||||||
...params,
|
...params,
|
||||||
fromTime: fromTime ? moment(fromTime) : defaultParams.fromTime,
|
date: {
|
||||||
toTime: toTime ? moment(toTime) : defaultParams.toTime,
|
begin: fromTime ? moment(fromTime) : defaultParams.date.begin,
|
||||||
|
end: toTime ? moment(toTime) : defaultParams.date.end
|
||||||
|
},
|
||||||
reportType: reportType ? (reportType as Report.ReportTypeEnum) : defaultParams.reportType
|
reportType: reportType ? (reportType as Report.ReportTypeEnum) : defaultParams.reportType
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
import { FormParams } from './form-params';
|
import { FormParams } from './form-params';
|
||||||
|
import { QueryParams } from './query-params';
|
||||||
|
|
||||||
export function toQueryParams({ fromTime, toTime, ...params }: FormParams): Partial<Record<keyof FormParams, string>> {
|
export function toQueryParams({ date, ...params }: FormParams): QueryParams {
|
||||||
return {
|
return {
|
||||||
...params,
|
...params,
|
||||||
fromTime: fromTime.utc().format(),
|
fromTime: date.begin.utc().format(),
|
||||||
toTime: toTime.utc().format()
|
toTime: date.end.utc().format()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -2,11 +2,11 @@ import { SearchParams } from '../search-params';
|
|||||||
import { Report } from '../../../../api-codegen/anapi';
|
import { Report } from '../../../../api-codegen/anapi';
|
||||||
import { FormParams } from './form-params';
|
import { FormParams } from './form-params';
|
||||||
|
|
||||||
export function toSearchParams({ reportType, fromTime, toTime, ...params }: FormParams): SearchParams {
|
export function toSearchParams({ reportType, date, ...params }: FormParams): SearchParams {
|
||||||
return {
|
return {
|
||||||
...params,
|
...params,
|
||||||
reportTypes: reportType ? [reportType] : Object.values(Report.ReportTypeEnum),
|
reportTypes: reportType ? [reportType] : Object.values(Report.ReportTypeEnum),
|
||||||
fromTime: fromTime.utc().format(),
|
fromTime: date.begin.utc().format(),
|
||||||
toTime: toTime.utc().format()
|
toTime: date.end.utc().format()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
<mat-icon svgIcon="more_vert"></mat-icon>
|
<mat-icon svgIcon="more_vert"></mat-icon>
|
||||||
</button>
|
</button>
|
||||||
<mat-menu #menu="matMenu">
|
<mat-menu #menu="matMenu">
|
||||||
<button mat-menu-item>
|
<button mat-menu-item (click)="goToReportDetails(report.id)">
|
||||||
{{ t.details }}
|
{{ t.details }}
|
||||||
</button>
|
</button>
|
||||||
</mat-menu>
|
</mat-menu>
|
||||||
|
16
src/assets/i18n/range-datepicker/ru.json
Normal file
16
src/assets/i18n/range-datepicker/ru.json
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"selectPeriod": "Выберите период",
|
||||||
|
"select": {
|
||||||
|
"currentWeek": "Текущая неделя",
|
||||||
|
"threeMonths": "3 месяца",
|
||||||
|
"year": "{{year}} год",
|
||||||
|
"period": "Указать период..."
|
||||||
|
},
|
||||||
|
"rangeDate": {
|
||||||
|
"from": "С",
|
||||||
|
"fromStartWith2": "Со",
|
||||||
|
"to": "по",
|
||||||
|
"currentWeek": "Текущая неделя",
|
||||||
|
"year": "год"
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,5 @@
|
|||||||
@import '~@angular/material/theming';
|
@import '~@angular/material/theming';
|
||||||
|
@import '~saturn-datepicker/bundle.css';
|
||||||
@import './utils/typography';
|
@import './utils/typography';
|
||||||
@import '../app/container/container-theme';
|
@import '../app/container/container-theme';
|
||||||
@import '../app/dropdown/dropdown-theme';
|
@import '../app/dropdown/dropdown-theme';
|
||||||
@ -27,6 +28,7 @@
|
|||||||
@import '../app/dadata/dadata-theme';
|
@import '../app/dadata/dadata-theme';
|
||||||
@import '../app/sections/payment-details/payment-details-theme';
|
@import '../app/sections/payment-details/payment-details-theme';
|
||||||
@import '../app/layout/panel/panel-theme';
|
@import '../app/layout/panel/panel-theme';
|
||||||
|
@import '../app/form-controls/range-datepicker/range-datepicker-theme';
|
||||||
|
|
||||||
@mixin dsh-overrides() {
|
@mixin dsh-overrides() {
|
||||||
@include body-override();
|
@include body-override();
|
||||||
@ -53,6 +55,7 @@
|
|||||||
@include dsh-dadata-autocomplete-typography($config);
|
@include dsh-dadata-autocomplete-typography($config);
|
||||||
@include mat-radio-button-override-typography($config);
|
@include mat-radio-button-override-typography($config);
|
||||||
@include dsh-payment-details-typography($config);
|
@include dsh-payment-details-typography($config);
|
||||||
|
@include dsh-range-datepicker-typography($config);
|
||||||
@include dsh-panel-typography($config);
|
@include dsh-panel-typography($config);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
@import '../../app/sections/invoice-details/payments/payments-theme';
|
@import '../../app/sections/invoice-details/payments/payments-theme';
|
||||||
@import '../../app/sections/payment-section/payouts/payout-panel/payout-panel-theme';
|
@import '../../app/sections/payment-section/payouts/payout-panel/payout-panel-theme';
|
||||||
@import '../../app/layout/panel/panel-theme';
|
@import '../../app/layout/panel/panel-theme';
|
||||||
|
@import '../../app/form-controls/range-datepicker/range-datepicker-theme';
|
||||||
|
|
||||||
@mixin dsh-theme($theme) {
|
@mixin dsh-theme($theme) {
|
||||||
body.#{map-get($theme, name)} {
|
body.#{map-get($theme, name)} {
|
||||||
@ -68,6 +69,7 @@
|
|||||||
@include dsh-details-secondary-title-theme($theme);
|
@include dsh-details-secondary-title-theme($theme);
|
||||||
@include dsh-file-uploader-theme($theme);
|
@include dsh-file-uploader-theme($theme);
|
||||||
@include dsh-panel-theme($theme);
|
@include dsh-panel-theme($theme);
|
||||||
|
@include dsh-range-datepicker-theme($theme);
|
||||||
@include dsh-payout-panel-theme($theme);
|
@include dsh-payout-panel-theme($theme);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user