@sd-angular/core 1.3.216 → 1.3.218

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.
Files changed (30) hide show
  1. package/bundles/sd-angular-core-date-time.umd.js +14 -6
  2. package/bundles/sd-angular-core-date-time.umd.js.map +1 -1
  3. package/bundles/sd-angular-core-date-time.umd.min.js +1 -1
  4. package/bundles/sd-angular-core-date-time.umd.min.js.map +1 -1
  5. package/bundles/sd-angular-core-input-upload-file.umd.js +54 -3
  6. package/bundles/sd-angular-core-input-upload-file.umd.js.map +1 -1
  7. package/bundles/sd-angular-core-input-upload-file.umd.min.js +2 -2
  8. package/bundles/sd-angular-core-input-upload-file.umd.min.js.map +1 -1
  9. package/bundles/sd-angular-core-table.umd.js +10 -5
  10. package/bundles/sd-angular-core-table.umd.js.map +1 -1
  11. package/bundles/sd-angular-core-table.umd.min.js +2 -2
  12. package/bundles/sd-angular-core-table.umd.min.js.map +1 -1
  13. package/date-time/sd-angular-core-date-time.metadata.json +1 -1
  14. package/date-time/src/lib/date-time.component.d.ts +1 -0
  15. package/esm2015/date-time/src/lib/date-time.component.js +8 -2
  16. package/esm2015/date-time/src/lib/date-time.module.js +6 -2
  17. package/esm2015/input-upload-file/src/lib/input-upload-file.component.js +44 -5
  18. package/esm2015/table/src/lib/table.component.js +8 -2
  19. package/fesm2015/sd-angular-core-date-time.js +12 -2
  20. package/fesm2015/sd-angular-core-date-time.js.map +1 -1
  21. package/fesm2015/sd-angular-core-input-upload-file.js +43 -4
  22. package/fesm2015/sd-angular-core-input-upload-file.js.map +1 -1
  23. package/fesm2015/sd-angular-core-table.js +7 -2
  24. package/fesm2015/sd-angular-core-table.js.map +1 -1
  25. package/input-upload-file/sd-angular-core-input-upload-file.metadata.json +1 -1
  26. package/input-upload-file/src/lib/input-upload-file.component.d.ts +8 -1
  27. package/package.json +1 -1
  28. package/{sd-angular-core-1.3.216.tgz → sd-angular-core-1.3.218.tgz} +0 -0
  29. package/table/sd-angular-core-table.metadata.json +1 -1
  30. package/table/src/lib/table.component.d.ts +3 -0
@@ -18,6 +18,8 @@ import { NgxMatMomentModule } from '@angular-material-components/moment-adapter'
18
18
  import { MatMomentDateModule } from '@angular/material-moment-adapter';
19
19
  import { MatIconModule } from '@angular/material/icon';
20
20
  import { SdPopoverModule } from '@sd-angular/core/popover';
21
+ import { NgxMaterialTimepickerModule } from 'ngx-material-timepicker';
22
+ import { SdButtonModule } from '@sd-angular/core/button';
21
23
 
22
24
  var _date, _name, _form, _subscription;
23
25
  const CUSTOM_DATETIME_FORMATS = {
@@ -152,6 +154,12 @@ class SdDateTime {
152
154
  this.sdChange.emit(null);
153
155
  }
154
156
  };
157
+ this.timeChanged = (event) => {
158
+ const value = event;
159
+ this.formControl.setValue(value);
160
+ this.modelChange.emit(value);
161
+ this.sdChange.emit(value);
162
+ };
155
163
  this.clear = ($event) => {
156
164
  $event === null || $event === void 0 ? void 0 : $event.stopPropagation();
157
165
  if (this.formControl.value) {
@@ -305,7 +313,7 @@ _date = new WeakMap(), _name = new WeakMap(), _form = new WeakMap(), _subscripti
305
313
  SdDateTime.decorators = [
306
314
  { type: Component, args: [{
307
315
  selector: 'sd-date-time',
308
- template: "<ng-container *ngIf=\"!appearance && sdLabelDef?.templateRef\">\r\n <ng-container *ngTemplateOutlet=\"sdLabelDef.templateRef\">\r\n </ng-container>\r\n</ng-container>\r\n<label *ngIf=\"!appearance && label && !sdLabelDef?.templateRef\" class=\"d-block mb-0 T14M\">{{label}} <span class=\"text-danger mb-2\"\r\n *ngIf=\"required\">*</span></label>\r\n<div class=\"d-flex align-items-center\" [class.sd-view]=\"sdView?.templateRef\" [class.c-focused]=\"isFocused\"\r\n [class.c-disabled]=\"formControl.disabled\" (click)=\"onClick()\">\r\n <ng-container\r\n *ngIf=\"sdView?.templateRef && !isFocused && !datePicker?.opened && !dateTimePicker?.opened; else default\">\r\n <ng-container *ngTemplateOutlet=\"sdView.templateRef;context: { value: formControl.value }\">\r\n </ng-container>\r\n </ng-container>\r\n <ng-template #default>\r\n <mat-form-field *ngIf=\"type === 'datetime' || type === 'time'\" class=\"sd-md\"\r\n [ngClass]=\"{ 'sd-sm': size === 'sm', 'no-padding-wrapper': disableErrorMessage }\"\r\n [appearance]=\"appearance || 'outline'\">\r\n <mat-label *ngIf=\"appearance && label\">{{ label }}</mat-label>\r\n <input aria-hidden=\"true\" [id]=\"id\" matInput (keyup)=\"onKeyup($event)\" (keydown)=\"onKeyDown($event)\" (dateChange)=\"onChange($event)\" [autocomplete]=\"id\" autocorrect=\"off\"\r\n [formControl]=\"formControl\" [ngxMatDatetimePicker]=\"picker1\"\r\n [placeholder]=\"placeholder || (appearance ? label : '')\" [min]=\"min\" [required]=\"required\" [max]=\"max\"\r\n (focus)=\"onFocus()\" (blur)=\"onBlur()\" [attr.data-qclabel]=\"label\" [attr.data-qcid]=\"qcId\"\r\n [sdPopoverTriggerFor]=\"null\" [sdPopoverDisabled]=\"!disableErrorMessage || formControl.valid\" #input [maxLength]=\"maxlength\"/>\r\n <!-- <mat-icon class=\"pointer sd-suffix-icon\" (click)=\"!formControl?.disabled && picker1.open()\" matSuffix>today\r\n </mat-icon> -->\r\n <mat-icon *ngIf=\"formControl?.value && !required && !formControl.disabled\" class=\"pointer sd-suffix-icon\"\r\n (click)=\"clear($event)\" matSuffix>cancel\r\n </mat-icon>\r\n <mat-datepicker-toggle matSuffix [for]=\"picker1\">\r\n </mat-datepicker-toggle>\r\n <ngx-mat-datetime-picker #picker1 [defaultTime]=\"defaultTime\" [touchUi]=\"isMobileOrTablet\" [showSpinners]=\"false\"\r\n (opened)=\"onFocus()\" (closed)=\"onBlur();focusInputElement()\">\r\n </ngx-mat-datetime-picker>\r\n\r\n <mat-error *ngIf=\"formControl?.errors?.required && formControl?.touched\">\r\n <ng-container *ngIf=\"!disableErrorMessage\">{{ \"This field is required\" | sdTranslate }}</ng-container>\r\n </mat-error>\r\n <mat-error *ngIf=\"formControl?.errors?.matDatetimePickerMin && formControl?.touched && !isFocused\">\r\n <ng-container *ngIf=\"!disableErrorMessage\">{{ \"Min date\" | sdTranslate }}:\r\n <strong>{{ min | date: \"dd/MM/yyyy HH:mm\" }}</strong>\r\n </ng-container>\r\n </mat-error>\r\n <mat-error *ngIf=\"formControl?.errors?.matDatetimePickerMax && formControl?.touched && !isFocused\">\r\n <ng-container *ngIf=\"!disableErrorMessage\">{{ \"Max date\" | sdTranslate }}:\r\n <strong>{{ max | date: \"dd/MM/yyyy HH:mm\" }}</strong>\r\n </ng-container>\r\n </mat-error>\r\n <mat-error *ngIf=\"formControl?.errors?.matDatetimePickerParse && formControl?.touched && !isFocused\">\r\n <ng-container *ngIf=\"!disableErrorMessage\">{{ \"Parse error\" | sdTranslate }}:\r\n <strong>{{ formControl?.errors?.matDatetimePickerParse?.text }}</strong>\r\n </ng-container>\r\n </mat-error>\r\n <mat-error *ngIf=\"formControl?.errors?.customValidator && formControl?.touched && !disableErrorMessage\">\r\n <ng-container *ngIf=\"!disableErrorMessage\">{{ formControl?.errors?.customValidator }}\r\n </ng-container>\r\n </mat-error>\r\n <mat-error *ngIf=\"formControl?.errors?.date && formControl?.touched && !disableErrorMessage\">\r\n <ng-container *ngIf=\"!disableErrorMessage\">{{ formControl?.errors?.date }}\r\n </ng-container>\r\n </mat-error>\r\n <mat-error *ngIf=\"formControl.errors?.inlineError && formControl?.touched && !disableErrorMessage\">\r\n <ng-container *ngIf=\"!disableErrorMessage\">{{inlineError}}</ng-container>\r\n </mat-error>\r\n </mat-form-field>\r\n <mat-form-field *ngIf=\"type === 'date'\" class=\"sd-md\"\r\n [ngClass]=\"{ 'sd-sm': size === 'sm' , 'no-padding-wrapper': disableErrorMessage}\"\r\n [appearance]=\"appearance || 'outline'\">\r\n <mat-label *ngIf=\"appearance && label\">{{ label }}</mat-label>\r\n <input aria-hidden=\"true\" [id]=\"id\" matInput (keyup)=\"onKeyup($event)\" (keydown)=\"onKeyDown($event)\" (dateChange)=\"onChange($event)\" [autocomplete]=\"id\" autocorrect=\"off\"\r\n [formControl]=\"formControl\" [required]=\"required\" [matDatepicker]=\"picker2\"\r\n [placeholder]=\"placeholder || (appearance ? label : '')\" [min]=\"min\" [max]=\"max\" (focus)=\"onFocus()\"\r\n (blur)=\"onBlur()\" [attr.data-qclabel]=\"label\" [attr.data-qcid]=\"qcId\" [sdPopoverTriggerFor]=\"null\"\r\n [sdPopoverDisabled]=\"!disableErrorMessage || formControl.valid\" #input [maxLength]=\"maxlength\" />\r\n <mat-icon *ngIf=\"formControl?.value && !required && !formControl.disabled\" class=\"pointer sd-suffix-icon\"\r\n (click)=\"clear($event)\" matSuffix>cancel\r\n </mat-icon>\r\n\r\n <mat-icon class=\"pointer sd-suffix-icon\" (click)=\"!formControl?.disabled && picker2.open()\" #btn matSuffix>today\r\n </mat-icon>\r\n\r\n <mat-datepicker #picker2 [touchUi]=\"isMobileOrTablet\"></mat-datepicker>\r\n\r\n <mat-error *ngIf=\"formControl?.errors?.required && formControl?.touched\">\r\n <ng-container *ngIf=\"!disableErrorMessage\">{{ \"This field is required\" | sdTranslate }}</ng-container>\r\n </mat-error>\r\n <mat-error *ngIf=\"formControl?.errors?.matDatepickerMin && formControl?.touched && !isFocused\">\r\n <ng-container *ngIf=\"!disableErrorMessage\">{{ \"Min date\" | sdTranslate }}:\r\n <strong>{{ min | date: \"dd/MM/yyyy HH:mm\" }}</strong>\r\n </ng-container>\r\n </mat-error>\r\n <mat-error *ngIf=\"formControl?.errors?.matDatepickerMax && formControl?.touched && !isFocused\">\r\n <ng-container *ngIf=\"!disableErrorMessage\">{{ \"Max date\" | sdTranslate }}:\r\n <strong>{{ max | date: \"dd/MM/yyyy HH:mm\" }}</strong>\r\n </ng-container>\r\n </mat-error>\r\n <mat-error *ngIf=\"formControl?.errors?.matDatetimePickerParse && formControl?.touched && !isFocused\">\r\n <ng-container *ngIf=\"!disableErrorMessage\">{{ \"Parse error\" | sdTranslate }}:\r\n <strong>{{ formControl?.errors?.matDatetimePickerParse?.text }}</strong>\r\n </ng-container>\r\n </mat-error>\r\n <mat-error *ngIf=\"formControl?.errors?.customValidator && formControl?.touched && !disableErrorMessage\">\r\n <ng-container *ngIf=\"!disableErrorMessage\">{{ formControl?.errors?.customValidator }}\r\n </ng-container>\r\n </mat-error>\r\n <mat-error *ngIf=\"formControl?.errors?.date && formControl?.touched && !disableErrorMessage\">\r\n <ng-container *ngIf=\"!disableErrorMessage\">{{ formControl?.errors?.date }}\r\n </ng-container>\r\n </mat-error>\r\n <mat-error *ngIf=\"formControl.errors?.inlineError && formControl?.touched && !disableErrorMessage\">\r\n <ng-container *ngIf=\"!disableErrorMessage\">{{inlineError}}</ng-container>\r\n </mat-error>\r\n </mat-form-field>\r\n <!-- <ngx-mat-timepicker *ngIf=\"type === 'time'\" formControlName=\"name\" [disabled]=\"disabled\" showSpinners=\"false\" stepHour=\"1\"\r\n stepMinute=\"1\" stepSecond=\"1\">\r\n</ngx-mat-timepicker> -->\r\n <mat-form-field *ngIf=\"type === 'month'\" class=\"sd-md\"\r\n [ngClass]=\"{ 'sd-sm': size === 'sm' , 'no-padding-wrapper': disableErrorMessage}\" appearance=\"outline\">\r\n <mat-label *ngIf=\"label\">{{ label }}</mat-label>\r\n <input aria-hidden=\"true\" [id]=\"id\" matInput (keyup)=\"onKeyup($event)\" (keydown)=\"onKeyDown($event)\" (dateChange)=\"onChange($event)\" [autocomplete]=\"id\" autocorrect=\"off\"\r\n [formControl]=\"formControl\" [required]=\"required\" [matDatepicker]=\"pickerMonth\"\r\n [placeholder]=\"placeholder || (appearance ? label : '')\" [min]=\"min\" [max]=\"max\" (focus)=\"onFocus()\"\r\n (blur)=\"onBlur()\" [sdPopoverTriggerFor]=\"null\" [sdPopoverDisabled]=\"!disableErrorMessage || formControl.valid\"\r\n #input />\r\n\r\n <mat-icon *ngIf=\"formControl?.value && !required && !formControl.disabled\" class=\"pointer sd-suffix-icon\"\r\n (click)=\"clear($event)\" matSuffix>cancel\r\n </mat-icon>\r\n <mat-icon class=\"pointer sd-suffix-icon\" (click)=\"!formControl?.disabled && pickerMonth.open()\" #btn matSuffix>\r\n today\r\n </mat-icon>\r\n\r\n <mat-datepicker #pickerMonth [touchUi]=\"isMobileOrTablet\" startView=\"multi-year\"\r\n (monthSelected)=\"setMonthAndYear($event, pickerMonth)\"></mat-datepicker>\r\n\r\n <mat-error *ngIf=\"formControl?.errors?.required && formControl?.touched\">\r\n <ng-container *ngIf=\"!disableErrorMessage\">{{ \"This field is required\" | sdTranslate }}</ng-container>\r\n </mat-error>\r\n <mat-error *ngIf=\"formControl?.errors?.matDatepickerMin && formControl?.touched\">\r\n <ng-container *ngIf=\"!disableErrorMessage\">{{ \"Min date\" | sdTranslate }}:\r\n <strong>{{ min | date: \"dd/MM/yyyy HH:mm\" }}</strong>\r\n </ng-container>\r\n </mat-error>\r\n <mat-error *ngIf=\"formControl?.errors?.matDatepickerMax && formControl?.touched\">\r\n <ng-container *ngIf=\"!disableErrorMessage\">{{ \"Max date\" | sdTranslate }}:\r\n <strong>{{ max | date: \"dd/MM/yyyy HH:mm\" }}</strong>\r\n </ng-container>\r\n </mat-error>\r\n <mat-error *ngIf=\"formControl?.errors?.matDatetimePickerParse && formControl?.touched\">\r\n <ng-container *ngIf=\"!disableErrorMessage\">{{ \"Parse error\" | sdTranslate }}:\r\n <strong>{{ formControl?.errors?.matDatetimePickerParse?.text }}</strong>\r\n </ng-container>\r\n </mat-error>\r\n <mat-error *ngIf=\"formControl?.errors?.customValidator && formControl?.touched && !disableErrorMessage\">\r\n <ng-container *ngIf=\"!disableErrorMessage\">{{ formControl?.errors?.customValidator }}\r\n </ng-container>\r\n </mat-error>\r\n <mat-error *ngIf=\"formControl.errors?.inlineError && formControl?.touched && !disableErrorMessage\">\r\n <ng-container *ngIf=\"!disableErrorMessage\">{{inlineError}}</ng-container>\r\n </mat-error>\r\n </mat-form-field>\r\n </ng-template>\r\n</div>\r\n<!-- <sd-popover #error=\"sdPopover\" type=\"danger\" width=\"300px\">\r\n <span *ngIf=\"formControl.errors?.required\">\r\n {{ \"This field is required\" | sdTranslate }}\r\n </span>\r\n <span *ngIf=\"formControl?.errors?.matDatetimePickerMin\">\r\n {{ \"Min date\" | sdTranslate }}:\r\n <strong>{{ min | date: \"dd/MM/yyyy HH:mm\" }}</strong>\r\n </span>\r\n <span *ngIf=\"formControl?.errors?.matDatetimePickerMax\">\r\n {{ \"Max date\" | sdTranslate }}:\r\n <strong>{{ max | date: \"dd/MM/yyyy HH:mm\" }}</strong>\r\n </span>\r\n <span *ngIf=\"formControl?.errors?.matDatetimePickerParse\">\r\n {{ \"Parse error\" | sdTranslate }}:\r\n <strong>{{ formControl?.errors?.matDatetimePickerParse?.text }}</strong>\r\n </span>\r\n <span *ngIf=\"formControl?.errors?.customValidator\">\r\n {{ formControl?.errors?.customValidator }}\r\n </span>\r\n</sd-popover> -->\r\n",
316
+ template: "<ng-container *ngIf=\"!appearance && sdLabelDef?.templateRef\">\r\n <ng-container *ngTemplateOutlet=\"sdLabelDef.templateRef\"> </ng-container>\r\n</ng-container>\r\n<label *ngIf=\"!appearance && label && !sdLabelDef?.templateRef\" class=\"d-block mb-0 T14M\"\r\n >{{ label }} <span class=\"text-danger mb-2\" *ngIf=\"required\">*</span></label\r\n>\r\n<div\r\n class=\"d-flex align-items-center\"\r\n [class.sd-view]=\"sdView?.templateRef\"\r\n [class.c-focused]=\"isFocused\"\r\n [class.c-disabled]=\"formControl.disabled\"\r\n (click)=\"onClick()\">\r\n <ng-container *ngIf=\"sdView?.templateRef && !isFocused && !datePicker?.opened && !dateTimePicker?.opened; else default\">\r\n <ng-container *ngTemplateOutlet=\"sdView.templateRef; context: { value: formControl.value }\"> </ng-container>\r\n </ng-container>\r\n <ng-template #default>\r\n <mat-form-field\r\n *ngIf=\"type === 'datetime'\"\r\n class=\"sd-md\"\r\n [ngClass]=\"{ 'sd-sm': size === 'sm', 'no-padding-wrapper': disableErrorMessage }\"\r\n [appearance]=\"appearance || 'outline'\">\r\n <mat-label *ngIf=\"appearance && label\">{{ label }}</mat-label>\r\n <input\r\n aria-hidden=\"true\"\r\n [id]=\"id\"\r\n matInput\r\n (keyup)=\"onKeyup($event)\"\r\n (keydown)=\"onKeyDown($event)\"\r\n (dateChange)=\"onChange($event)\"\r\n [autocomplete]=\"id\"\r\n autocorrect=\"off\"\r\n [formControl]=\"formControl\"\r\n [ngxMatDatetimePicker]=\"picker1\"\r\n [placeholder]=\"placeholder || (appearance ? label : '')\"\r\n [min]=\"min\"\r\n [required]=\"required\"\r\n [max]=\"max\"\r\n (focus)=\"onFocus()\"\r\n (blur)=\"onBlur()\"\r\n [attr.data-qclabel]=\"label\"\r\n [attr.data-qcid]=\"qcId\"\r\n [sdPopoverTriggerFor]=\"null\"\r\n [sdPopoverDisabled]=\"!disableErrorMessage || formControl.valid\"\r\n #input\r\n [maxLength]=\"maxlength\" />\r\n <!-- <mat-icon class=\"pointer sd-suffix-icon\" (click)=\"!formControl?.disabled && picker1.open()\" matSuffix>today\r\n </mat-icon> -->\r\n <mat-icon\r\n *ngIf=\"formControl?.value && !required && !formControl.disabled\"\r\n class=\"pointer sd-suffix-icon\"\r\n (click)=\"clear($event)\"\r\n matSuffix\r\n >cancel\r\n </mat-icon>\r\n <mat-datepicker-toggle matSuffix [for]=\"picker1\"> </mat-datepicker-toggle>\r\n <ngx-mat-datetime-picker\r\n #picker1\r\n [defaultTime]=\"defaultTime\"\r\n [touchUi]=\"isMobileOrTablet\"\r\n [showSpinners]=\"false\"\r\n (opened)=\"onFocus()\"\r\n (closed)=\"onBlur(); focusInputElement()\">\r\n </ngx-mat-datetime-picker>\r\n\r\n <mat-error *ngIf=\"formControl?.errors?.required && formControl?.touched\">\r\n <ng-container *ngIf=\"!disableErrorMessage\">{{ 'This field is required' | sdTranslate }}</ng-container>\r\n </mat-error>\r\n <mat-error *ngIf=\"formControl?.errors?.matDatetimePickerMin && formControl?.touched && !isFocused\">\r\n <ng-container *ngIf=\"!disableErrorMessage\"\r\n >{{ 'Min date' | sdTranslate }}:\r\n <strong>{{ min | date : 'dd/MM/yyyy HH:mm' }}</strong>\r\n </ng-container>\r\n </mat-error>\r\n <mat-error *ngIf=\"formControl?.errors?.matDatetimePickerMax && formControl?.touched && !isFocused\">\r\n <ng-container *ngIf=\"!disableErrorMessage\"\r\n >{{ 'Max date' | sdTranslate }}:\r\n <strong>{{ max | date : 'dd/MM/yyyy HH:mm' }}</strong>\r\n </ng-container>\r\n </mat-error>\r\n <mat-error *ngIf=\"formControl?.errors?.matDatetimePickerParse && formControl?.touched && !isFocused\">\r\n <ng-container *ngIf=\"!disableErrorMessage\"\r\n >{{ 'Parse error' | sdTranslate }}:\r\n <strong>{{ formControl?.errors?.matDatetimePickerParse?.text }}</strong>\r\n </ng-container>\r\n </mat-error>\r\n <mat-error *ngIf=\"formControl?.errors?.customValidator && formControl?.touched && !disableErrorMessage\">\r\n <ng-container *ngIf=\"!disableErrorMessage\">{{ formControl?.errors?.customValidator }} </ng-container>\r\n </mat-error>\r\n <mat-error *ngIf=\"formControl?.errors?.date && formControl?.touched && !disableErrorMessage\">\r\n <ng-container *ngIf=\"!disableErrorMessage\">{{ formControl?.errors?.date }} </ng-container>\r\n </mat-error>\r\n <mat-error *ngIf=\"formControl.errors?.inlineError && formControl?.touched && !disableErrorMessage\">\r\n <ng-container *ngIf=\"!disableErrorMessage\">{{ inlineError }}</ng-container>\r\n </mat-error>\r\n </mat-form-field>\r\n <mat-form-field\r\n *ngIf=\"type === 'date'\"\r\n class=\"sd-md\"\r\n [ngClass]=\"{ 'sd-sm': size === 'sm', 'no-padding-wrapper': disableErrorMessage }\"\r\n [appearance]=\"appearance || 'outline'\">\r\n <mat-label *ngIf=\"appearance && label\">{{ label }}</mat-label>\r\n <input\r\n aria-hidden=\"true\"\r\n [id]=\"id\"\r\n matInput\r\n (keyup)=\"onKeyup($event)\"\r\n (keydown)=\"onKeyDown($event)\"\r\n (dateChange)=\"onChange($event)\"\r\n [autocomplete]=\"id\"\r\n autocorrect=\"off\"\r\n [formControl]=\"formControl\"\r\n [required]=\"required\"\r\n [matDatepicker]=\"picker2\"\r\n [placeholder]=\"placeholder || (appearance ? label : '')\"\r\n [min]=\"min\"\r\n [max]=\"max\"\r\n (focus)=\"onFocus()\"\r\n (blur)=\"onBlur()\"\r\n [attr.data-qclabel]=\"label\"\r\n [attr.data-qcid]=\"qcId\"\r\n [sdPopoverTriggerFor]=\"null\"\r\n [sdPopoverDisabled]=\"!disableErrorMessage || formControl.valid\"\r\n #input\r\n [maxLength]=\"maxlength\" />\r\n <mat-icon\r\n *ngIf=\"formControl?.value && !required && !formControl.disabled\"\r\n class=\"pointer sd-suffix-icon\"\r\n (click)=\"clear($event)\"\r\n matSuffix\r\n >cancel\r\n </mat-icon>\r\n\r\n <mat-icon class=\"pointer sd-suffix-icon\" (click)=\"!formControl?.disabled && picker2.open()\" #btn matSuffix>today </mat-icon>\r\n\r\n <mat-datepicker #picker2 [touchUi]=\"isMobileOrTablet\"></mat-datepicker>\r\n\r\n <mat-error *ngIf=\"formControl?.errors?.required && formControl?.touched\">\r\n <ng-container *ngIf=\"!disableErrorMessage\">{{ 'This field is required' | sdTranslate }}</ng-container>\r\n </mat-error>\r\n <mat-error *ngIf=\"formControl?.errors?.matDatepickerMin && formControl?.touched && !isFocused\">\r\n <ng-container *ngIf=\"!disableErrorMessage\"\r\n >{{ 'Min date' | sdTranslate }}:\r\n <strong>{{ min | date : 'dd/MM/yyyy HH:mm' }}</strong>\r\n </ng-container>\r\n </mat-error>\r\n <mat-error *ngIf=\"formControl?.errors?.matDatepickerMax && formControl?.touched && !isFocused\">\r\n <ng-container *ngIf=\"!disableErrorMessage\"\r\n >{{ 'Max date' | sdTranslate }}:\r\n <strong>{{ max | date : 'dd/MM/yyyy HH:mm' }}</strong>\r\n </ng-container>\r\n </mat-error>\r\n <mat-error *ngIf=\"formControl?.errors?.matDatetimePickerParse && formControl?.touched && !isFocused\">\r\n <ng-container *ngIf=\"!disableErrorMessage\"\r\n >{{ 'Parse error' | sdTranslate }}:\r\n <strong>{{ formControl?.errors?.matDatetimePickerParse?.text }}</strong>\r\n </ng-container>\r\n </mat-error>\r\n <mat-error *ngIf=\"formControl?.errors?.customValidator && formControl?.touched && !disableErrorMessage\">\r\n <ng-container *ngIf=\"!disableErrorMessage\">{{ formControl?.errors?.customValidator }} </ng-container>\r\n </mat-error>\r\n <mat-error *ngIf=\"formControl?.errors?.date && formControl?.touched && !disableErrorMessage\">\r\n <ng-container *ngIf=\"!disableErrorMessage\">{{ formControl?.errors?.date }} </ng-container>\r\n </mat-error>\r\n <mat-error *ngIf=\"formControl.errors?.inlineError && formControl?.touched && !disableErrorMessage\">\r\n <ng-container *ngIf=\"!disableErrorMessage\">{{ inlineError }}</ng-container>\r\n </mat-error>\r\n </mat-form-field>\r\n\r\n <mat-form-field\r\n *ngIf=\"type === 'month'\"\r\n class=\"sd-md\"\r\n [ngClass]=\"{ 'sd-sm': size === 'sm', 'no-padding-wrapper': disableErrorMessage }\"\r\n appearance=\"outline\">\r\n <mat-label *ngIf=\"label\">{{ label }}</mat-label>\r\n <input\r\n aria-hidden=\"true\"\r\n [id]=\"id\"\r\n matInput\r\n (keyup)=\"onKeyup($event)\"\r\n (keydown)=\"onKeyDown($event)\"\r\n (dateChange)=\"onChange($event)\"\r\n [autocomplete]=\"id\"\r\n autocorrect=\"off\"\r\n [formControl]=\"formControl\"\r\n [required]=\"required\"\r\n [matDatepicker]=\"pickerMonth\"\r\n [placeholder]=\"placeholder || (appearance ? label : '')\"\r\n [min]=\"min\"\r\n [max]=\"max\"\r\n (focus)=\"onFocus()\"\r\n (blur)=\"onBlur()\"\r\n [sdPopoverTriggerFor]=\"null\"\r\n [sdPopoverDisabled]=\"!disableErrorMessage || formControl.valid\"\r\n #input />\r\n\r\n <mat-icon\r\n *ngIf=\"formControl?.value && !required && !formControl.disabled\"\r\n class=\"pointer sd-suffix-icon\"\r\n (click)=\"clear($event)\"\r\n matSuffix\r\n >cancel\r\n </mat-icon>\r\n <mat-icon class=\"pointer sd-suffix-icon\" (click)=\"!formControl?.disabled && pickerMonth.open()\" #btn matSuffix> today </mat-icon>\r\n\r\n <mat-datepicker\r\n #pickerMonth\r\n [touchUi]=\"isMobileOrTablet\"\r\n startView=\"multi-year\"\r\n (monthSelected)=\"setMonthAndYear($event, pickerMonth)\"></mat-datepicker>\r\n\r\n <mat-error *ngIf=\"formControl?.errors?.required && formControl?.touched\">\r\n <ng-container *ngIf=\"!disableErrorMessage\">{{ 'This field is required' | sdTranslate }}</ng-container>\r\n </mat-error>\r\n <mat-error *ngIf=\"formControl?.errors?.matDatepickerMin && formControl?.touched\">\r\n <ng-container *ngIf=\"!disableErrorMessage\"\r\n >{{ 'Min date' | sdTranslate }}:\r\n <strong>{{ min | date : 'dd/MM/yyyy HH:mm' }}</strong>\r\n </ng-container>\r\n </mat-error>\r\n <mat-error *ngIf=\"formControl?.errors?.matDatepickerMax && formControl?.touched\">\r\n <ng-container *ngIf=\"!disableErrorMessage\"\r\n >{{ 'Max date' | sdTranslate }}:\r\n <strong>{{ max | date : 'dd/MM/yyyy HH:mm' }}</strong>\r\n </ng-container>\r\n </mat-error>\r\n <mat-error *ngIf=\"formControl?.errors?.matDatetimePickerParse && formControl?.touched\">\r\n <ng-container *ngIf=\"!disableErrorMessage\"\r\n >{{ 'Parse error' | sdTranslate }}:\r\n <strong>{{ formControl?.errors?.matDatetimePickerParse?.text }}</strong>\r\n </ng-container>\r\n </mat-error>\r\n <mat-error *ngIf=\"formControl?.errors?.customValidator && formControl?.touched && !disableErrorMessage\">\r\n <ng-container *ngIf=\"!disableErrorMessage\">{{ formControl?.errors?.customValidator }} </ng-container>\r\n </mat-error>\r\n <mat-error *ngIf=\"formControl.errors?.inlineError && formControl?.touched && !disableErrorMessage\">\r\n <ng-container *ngIf=\"!disableErrorMessage\">{{ inlineError }}</ng-container>\r\n </mat-error>\r\n </mat-form-field>\r\n\r\n <ng-container *ngIf=\"type === 'time'\">\r\n \r\n <mat-form-field [appearance]=\"appearance || 'outline'\" class=\"sd-md pt-5\">\r\n <mat-label *ngIf=\"appearance && label\">{{ label }}</mat-label>\r\n <input\r\n [ngxTimepicker]=\"openingTime\"\r\n aria-hidden=\"true\"\r\n [id]=\"id\"\r\n matInput\r\n (keyup)=\"onKeyup($event)\"\r\n (keydown)=\"onKeyDown($event)\"\r\n \r\n [autocomplete]=\"id\"\r\n autocorrect=\"off\"\r\n [formControl]=\"formControl\"\r\n [required]=\"required\"\r\n [placeholder]=\"placeholder || (appearance ? label : '')\"\r\n [min]=\"min\"\r\n [max]=\"max\"\r\n (focus)=\"onFocus()\"\r\n (blur)=\"onBlur()\"\r\n [attr.data-qclabel]=\"label\"\r\n [attr.data-qcid]=\"qcId\"\r\n #input\r\n [format]=\"24\"\r\n />\r\n\r\n <ngx-material-timepicker\r\n #openingTime\r\n [defaultTime]=\"defaultTime\"\r\n (timeChanged)=\"timeChanged($event)\"\r\n [enableKeyboardInput]=\"true\"\r\n [cancelBtnTmpl]=\"cancelBtn\"\r\n [confirmBtnTmpl]=\"confirmBtn\"></ngx-material-timepicker>\r\n\r\n <mat-error *ngIf=\"formControl?.errors?.required && formControl?.touched\">\r\n <ng-container *ngIf=\"!disableErrorMessage\">{{ 'This field is required' | sdTranslate }}</ng-container>\r\n </mat-error>\r\n <mat-error *ngIf=\"formControl.errors?.inlineError && formControl?.touched\">\r\n <ng-container *ngIf=\"!disableErrorMessage\">{{ inlineError }}</ng-container>\r\n </mat-error>\r\n </mat-form-field>\r\n\r\n <ng-template #cancelBtn>\r\n <sd-button title=\"{{ 'Cancel' | sdTranslate }}\" size=\"sm\"></sd-button>\r\n </ng-template>\r\n <ng-template #confirmBtn>\r\n <sd-button class=\"ml-8\" title=\"{{ 'Apply' | sdTranslate }}\" color=\"primary\" size=\"sm\"></sd-button>\r\n </ng-template>\r\n\r\n </ng-container>\r\n </ng-template>\r\n</div>\r\n<!-- <sd-popover #error=\"sdPopover\" type=\"danger\" width=\"300px\">\r\n <span *ngIf=\"formControl.errors?.required\">\r\n {{ \"This field is required\" | sdTranslate }}\r\n </span>\r\n <span *ngIf=\"formControl?.errors?.matDatetimePickerMin\">\r\n {{ \"Min date\" | sdTranslate }}:\r\n <strong>{{ min | date: \"dd/MM/yyyy HH:mm\" }}</strong>\r\n </span>\r\n <span *ngIf=\"formControl?.errors?.matDatetimePickerMax\">\r\n {{ \"Max date\" | sdTranslate }}:\r\n <strong>{{ max | date: \"dd/MM/yyyy HH:mm\" }}</strong>\r\n </span>\r\n <span *ngIf=\"formControl?.errors?.matDatetimePickerParse\">\r\n {{ \"Parse error\" | sdTranslate }}:\r\n <strong>{{ formControl?.errors?.matDatetimePickerParse?.text }}</strong>\r\n </span>\r\n <span *ngIf=\"formControl?.errors?.customValidator\">\r\n {{ formControl?.errors?.customValidator }}\r\n </span>\r\n</sd-popover> -->\r\n",
309
317
  changeDetection: ChangeDetectionStrategy.OnPush,
310
318
  providers: [
311
319
  { provide: MAT_DATE_FORMATS, useValue: ɵ0 },
@@ -365,7 +373,9 @@ SdDateTimeModule.decorators = [
365
373
  NgxMatMomentModule,
366
374
  SdTranslateModule,
367
375
  SdCommonModule,
368
- SdPopoverModule
376
+ SdPopoverModule,
377
+ NgxMaterialTimepickerModule,
378
+ SdButtonModule
369
379
  ],
370
380
  declarations: [
371
381
  SdDateTime
@@ -1 +1 @@
1
- {"version":3,"file":"sd-angular-core-date-time.js","sources":["../../../../projects/sd-core/date-time/src/lib/date-time.component.ts","../../../../projects/sd-core/date-time/src/lib/date-time.module.ts","../../../../projects/sd-core/date-time/sd-angular-core-date-time.ts"],"sourcesContent":["import {\r\n Component,\r\n Input,\r\n EventEmitter,\r\n Output,\r\n OnDestroy,\r\n AfterViewInit,\r\n ChangeDetectorRef,\r\n OnInit,\r\n ViewChild,\r\n ChangeDetectionStrategy,\r\n ContentChild,\r\n ElementRef,\r\n Inject,\r\n Optional\r\n} from '@angular/core';\r\nimport * as uuid from 'uuid';\r\nimport hash from 'object-hash';\r\nimport moment, { Moment } from 'moment';\r\nimport { AbstractControl, FormGroup, NgForm, ValidatorFn, Validators } from '@angular/forms';\r\nimport { DeviceDetectorService } from 'ngx-device-detector';\r\nimport { MatDatepicker, MatDatepickerInputEvent } from '@angular/material/datepicker';\r\nimport { NgxMatDatetimePicker, NGX_MAT_DATE_FORMATS, } from '@angular-material-components/datetime-picker';\r\nimport { MAT_DATE_FORMATS } from '@angular/material/core';\r\nimport { Subscription } from 'rxjs';\r\nimport { FORM_CONFIG, IFormConfiguration, SdFormControl, SdViewDefDirective } from '@sd-angular/core/common';\r\nimport { MatFormFieldAppearance } from '@angular/material/form-field';\r\nimport { SdLabelDefDirective } from '@sd-angular/core/common';\r\n\r\nconst CUSTOM_DATETIME_FORMATS = {\r\n parse: {\r\n dateInput: 'DD/MM/YYYY HH:mm'\r\n },\r\n display: {\r\n dateInput: 'DD/MM/YYYY HH:mm',\r\n monthYearLabel: 'MMM YYYY',\r\n dateA11yLabel: 'LL',\r\n monthYearA11yLabel: 'MMMM YYYY'\r\n }\r\n};\r\nconst CUSTOM_DATE_FORMATS = {\r\n parse: {\r\n dateInput: 'DD/MM/YYYY'\r\n },\r\n display: {\r\n dateInput: 'DD/MM/YYYY',\r\n monthYearLabel: 'MMM YYYY',\r\n dateA11yLabel: 'LL',\r\n monthYearA11yLabel: 'MMMM YYYY'\r\n }\r\n};\r\n@Component({\r\n selector: 'sd-date-time',\r\n templateUrl: './date-time.component.html',\r\n styleUrls: ['./date-time.component.scss'],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n providers: [\r\n { provide: MAT_DATE_FORMATS, useValue: CUSTOM_DATE_FORMATS },\r\n { provide: NGX_MAT_DATE_FORMATS, useValue: CUSTOM_DATETIME_FORMATS }\r\n ]\r\n})\r\nexport class SdDateTime implements OnDestroy, OnInit, AfterViewInit {\r\n id = `I${uuid.v4()}`;\r\n isMobileOrTablet = false;\r\n #date: any;\r\n #name = uuid.v4();\r\n @Input() set name(val: string) {\r\n if (val) {\r\n this.#name = val;\r\n }\r\n }\r\n @Input() appearance: MatFormFieldAppearance;\r\n disableErrorMessage = false;\r\n @Input('disableErrorMessage') set _disableErrorMessage(val: boolean | '') {\r\n this.disableErrorMessage = (val === '') || val;\r\n val = (val === '') || val;\r\n }\r\n formControl = new SdFormControl();\r\n min: Date;\r\n @Input('min') set _min(val: string | Date | number) {\r\n if (Date.isDate(val)) {\r\n this.min = new Date(val);\r\n } else {\r\n this.min = null;\r\n }\r\n }\r\n max: Date;\r\n @Input('max') set _max(val: string | Date | number) {\r\n if (Date.isDate(val)) {\r\n this.max = new Date(val);\r\n } else {\r\n this.max = null;\r\n }\r\n }\r\n @Input() size: 'sm' | 'lg';\r\n #form: FormGroup;\r\n @Input() set form(val: NgForm | FormGroup) {\r\n if (val) {\r\n if (val instanceof NgForm) {\r\n this.#form = val.form;\r\n } else {\r\n this.#form = val;\r\n }\r\n }\r\n }\r\n maxlength: number;\r\n type: 'datetime' | 'date' | 'time' | 'month' = 'datetime';\r\n @Input('type') set _type(val: 'datetime' | 'date' | 'time' | 'month') {\r\n this.type = val || 'datetime';\r\n }\r\n @Input() set disabled(val: boolean | '') {\r\n val = (val === '') || val;\r\n if (val) {\r\n this.formControl.disable();\r\n } else {\r\n this.formControl.enable();\r\n }\r\n }\r\n required = false;\r\n @Input('required') set _required(val: boolean | '') {\r\n this.required = (val === '') || val;\r\n if (this.required) {\r\n this.formControl.setValidators([Validators.required]);\r\n } else {\r\n this.formControl.clearValidators();\r\n }\r\n }\r\n\r\n inlineError: string;\r\n @Input('inlineError') set _inlineError(val: string) {\r\n this.inlineError = val;\r\n // this.#updateValidator();\r\n if (this.inlineError) {\r\n \r\n\r\n this.formControl.setValidators([this.customInlineErrorValidator()]);\r\n this.formControl.updateValueAndValidity();\r\n\r\n } else {\r\n this.formControl.clearValidators();\r\n this.formControl.updateValueAndValidity();\r\n\r\n }\r\n \r\n }\r\n\r\n qcId: string;\r\n label: string;\r\n @Input('label') set _label(val: string) {\r\n this.label = val;\r\n this.qcId = hash({\r\n selector: 'sd-date-time',\r\n label: val\r\n });\r\n };\r\n @Input() placeholder: string;\r\n @Input() defaultTime: any;\r\n @Input() set minDate(val: string | Date) {\r\n if (Date.isDate(val)) {\r\n this.min = new Date(val);\r\n } else {\r\n this.min = null;\r\n }\r\n }\r\n @Input() set maxDate(val: string | Date) {\r\n if (Date.isDate(val)) {\r\n this.max = new Date(val);\r\n } else {\r\n this.max = null;\r\n }\r\n }\r\n @Input() validator: (value: any) => string | Promise<string>;\r\n @Output() sdChange = new EventEmitter();\r\n\r\n @Input() set model(val: any) {\r\n if (!Date.isDate(val)) {\r\n val = null;\r\n }\r\n if (this.#date !== val) {\r\n this.#date = val;\r\n const date = Date.isDate(this.#date) ? moment(Date.toFormat(this.#date, 'MM/dd/yyyy HH:mm:ss'), 'MM/DD/YYYY HH:mm:ss') : null;\r\n this.formControl.setValue(date);\r\n }\r\n }\r\n @Output() modelChange = new EventEmitter();\r\n #subscription = new Subscription();\r\n @ContentChild(SdViewDefDirective) sdView: SdViewDefDirective;\r\n @ContentChild(SdLabelDefDirective) sdLabelDef: SdLabelDefDirective;\r\n @ViewChild('input') input: ElementRef;\r\n @ViewChild(MatDatepicker) datePicker: MatDatepicker<Moment>;\r\n @ViewChild(NgxMatDatetimePicker) dateTimePicker: NgxMatDatetimePicker<Moment>;\r\n isFocused = false;\r\n constructor(\r\n private ref: ChangeDetectorRef,\r\n deviceService: DeviceDetectorService,\r\n @Inject(FORM_CONFIG) @Optional() private formConfig: IFormConfiguration) {\r\n this.isMobileOrTablet = !deviceService.isDesktop();\r\n }\r\n\r\n ngOnDestroy() {\r\n this.#form?.removeControl(this.#name);\r\n this.#subscription.unsubscribe();\r\n }\r\n\r\n ngOnInit() {\r\n this.maxlength = this.type === 'datetime' ? 16 : 10;\r\n this.appearance = this.appearance || this.formConfig?.appearance;\r\n this.#subscription.add(this.formControl.sdChanges.subscribe(() => {\r\n // this.formControl.updateValueAndValidity();\r\n this.ref.markForCheck();\r\n }));\r\n this.#form?.addControl(this.#name, this.formControl);\r\n }\r\n\r\n \r\n // Hàm tạo Validators tùy chỉnh cho inlineError\r\n customInlineErrorValidator(): ValidatorFn {\r\n return (control: AbstractControl): { [key: string]: any } | null => {\r\n return { inlineError: true };\r\n };\r\n }\r\n\r\n ngAfterViewInit() {\r\n }\r\n\r\n onFocus = () => {\r\n this.isFocused = true;\r\n }\r\n\r\n onBlur = () => {\r\n this.isFocused = false;\r\n }\r\n\r\n onClick = () => {\r\n if (this.sdView?.templateRef) {\r\n if (!this.formControl.disabled && !this.isFocused) {\r\n this.focus();\r\n }\r\n }\r\n }\r\n\r\n blur = () => {\r\n this.input?.nativeElement?.blur();\r\n }\r\n\r\n focus = () => {\r\n this.isFocused = true;\r\n setTimeout(() => {\r\n this.input?.nativeElement?.focus();\r\n if (this.type === 'date') {\r\n this.datePicker?.open();\r\n } else {\r\n this.dateTimePicker?.open();\r\n }\r\n //\r\n }, 100);\r\n }\r\n\r\n focusInputElement() {\r\n this.input?.nativeElement?.focus();\r\n }\r\n\r\n isValid: boolean;\r\n onKeyDown = (event: KeyboardEvent) => {\r\n const key = event.keyCode || event.charCode;\r\n let isShift = false;\r\n if (key == 16) {\r\n isShift = true;\r\n }\r\n //Allow only Numeric Keys.\r\n if (((key >= 48 && key <= 57) || key == 8 || key <= 37 || key <= 39 || (key >= 96 && key <= 105) || key == 191 || key == 186 || key == 59) && isShift == false) {\r\n return true;\r\n }\r\n else {\r\n return false;\r\n }\r\n }\r\n\r\n onKeyup = (event) => {\r\n const currentVal: string = event.target.value;\r\n const formControl: AbstractControl = this.formControl;\r\n let regex = /^([1-9]|([012][0-9])|(3[01]))\\/([0]{0,1}[1-9]|1[012])\\/\\d\\d\\d\\d$/g;\r\n\r\n if (this.type === 'datetime' || this.type === 'time') {\r\n regex = /^([1-9]|([012][0-9])|(3[01]))\\/([0]{0,1}[1-9]|1[012])\\/\\d\\d\\d\\d [012]{0,1}[0-9]:[0-6][0-9]$/g;\r\n }\r\n if (this.type === 'month') {\r\n regex = /^([0]{0,1}[1-9]|1[012])\\/\\d\\d\\d\\d [012]{0,1}[0-9]:[0-6][0-9]$/g;\r\n }\r\n\r\n const errorMessage = this.type === 'date' ? 'dd/MM/yyyy' : 'dd/MM/yyyy HH:mm';\r\n if (currentVal && !regex.test(currentVal)) {\r\n setTimeout(() => {\r\n this.isValid = true;\r\n formControl.markAsDirty();\r\n formControl.markAsTouched();\r\n formControl.setErrors({ ...formControl.errors, date: `Chưa đúng định dạng ${errorMessage}` });\r\n }, 0);\r\n\r\n } else {\r\n setTimeout(() => {\r\n this.isValid = false;\r\n formControl.setErrors({ ...formControl.errors, date: null });\r\n this.formControl.updateValueAndValidity();\r\n }, 0);\r\n }\r\n }\r\n\r\n onChange = (event: MatDatepickerInputEvent<Moment>) => {\r\n const value = event.value?.toDate();\r\n if (!this.dateTimePicker) {\r\n this.input?.nativeElement?.focus();\r\n }\r\n if (!this.isValid) {\r\n if (new Date(this.#date) !== value) {\r\n this.modelChange.emit(value);\r\n this.sdChange.emit(value);\r\n }\r\n } else {\r\n this.isValid = false;\r\n this.formControl.setValue(null);\r\n this.modelChange.emit(null);\r\n this.sdChange.emit(null);\r\n }\r\n }\r\n\r\n clear = ($event: any) => {\r\n $event?.stopPropagation();\r\n if (this.formControl.value) {\r\n this.formControl.setValue(null);\r\n this.modelChange.emit(null);\r\n this.sdChange.emit(null);\r\n }\r\n }\r\n\r\n setMonthAndYear = (normalizedMonthAndYear: Moment, datepicker: MatDatepicker<Moment>) => {\r\n const ctrlValue = this.formControl.value || moment();\r\n ctrlValue.month(normalizedMonthAndYear.month());\r\n ctrlValue.year(normalizedMonthAndYear.year());\r\n this.formControl.setValue(ctrlValue);\r\n datepicker.close();\r\n this.modelChange.emit(ctrlValue);\r\n this.sdChange.emit(ctrlValue);\r\n }\r\n}\r\n","import { NgModule } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { FormsModule, ReactiveFormsModule } from '@angular/forms';\r\nimport { MatFormFieldModule } from '@angular/material/form-field';\r\nimport { MatDatepickerModule } from '@angular/material/datepicker';\r\nimport {\r\n NgxMatDatetimePickerModule,\r\n NgxMatTimepickerModule\r\n} from '@angular-material-components/datetime-picker';\r\nimport { SdDateTime } from './date-time.component';\r\nimport { SdTranslateModule } from '@sd-angular/core/translate';\r\nimport { MatInputModule } from '@angular/material/input';\r\nimport { NgxMatMomentModule } from '@angular-material-components/moment-adapter';\r\nimport { MatMomentDateModule } from '@angular/material-moment-adapter';\r\nimport { MatIconModule } from '@angular/material/icon';\r\nimport { SdCommonModule } from '@sd-angular/core/common';\r\nimport { SdPopoverModule } from '@sd-angular/core/popover';\r\n@NgModule({\r\n imports: [\r\n CommonModule,\r\n FormsModule,\r\n ReactiveFormsModule,\r\n MatInputModule,\r\n MatIconModule,\r\n MatFormFieldModule,\r\n MatDatepickerModule,\r\n MatMomentDateModule,\r\n NgxMatDatetimePickerModule,\r\n NgxMatTimepickerModule,\r\n NgxMatMomentModule,\r\n SdTranslateModule,\r\n SdCommonModule,\r\n SdPopoverModule\r\n ],\r\n declarations: [\r\n SdDateTime\r\n ],\r\n exports: [\r\n SdCommonModule,\r\n SdDateTime\r\n ],\r\n providers: [\r\n ]\r\n})\r\nexport class SdDateTimeModule {\r\n\r\n}\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["uuid.v4"],"mappings":"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"}
1
+ {"version":3,"file":"sd-angular-core-date-time.js","sources":["../../../../projects/sd-core/date-time/src/lib/date-time.component.ts","../../../../projects/sd-core/date-time/src/lib/date-time.module.ts","../../../../projects/sd-core/date-time/sd-angular-core-date-time.ts"],"sourcesContent":["import {\r\n Component,\r\n Input,\r\n EventEmitter,\r\n Output,\r\n OnDestroy,\r\n AfterViewInit,\r\n ChangeDetectorRef,\r\n OnInit,\r\n ViewChild,\r\n ChangeDetectionStrategy,\r\n ContentChild,\r\n ElementRef,\r\n Inject,\r\n Optional\r\n} from '@angular/core';\r\nimport * as uuid from 'uuid';\r\nimport hash from 'object-hash';\r\nimport moment, { Moment } from 'moment';\r\nimport { AbstractControl, FormGroup, NgForm, ValidatorFn, Validators } from '@angular/forms';\r\nimport { DeviceDetectorService } from 'ngx-device-detector';\r\nimport { MatDatepicker, MatDatepickerInputEvent } from '@angular/material/datepicker';\r\nimport { NgxMatDatetimePicker, NGX_MAT_DATE_FORMATS, } from '@angular-material-components/datetime-picker';\r\nimport { MAT_DATE_FORMATS } from '@angular/material/core';\r\nimport { Subscription } from 'rxjs';\r\nimport { FORM_CONFIG, IFormConfiguration, SdFormControl, SdViewDefDirective } from '@sd-angular/core/common';\r\nimport { MatFormFieldAppearance } from '@angular/material/form-field';\r\nimport { SdLabelDefDirective } from '@sd-angular/core/common';\r\n\r\nconst CUSTOM_DATETIME_FORMATS = {\r\n parse: {\r\n dateInput: 'DD/MM/YYYY HH:mm'\r\n },\r\n display: {\r\n dateInput: 'DD/MM/YYYY HH:mm',\r\n monthYearLabel: 'MMM YYYY',\r\n dateA11yLabel: 'LL',\r\n monthYearA11yLabel: 'MMMM YYYY'\r\n }\r\n};\r\nconst CUSTOM_DATE_FORMATS = {\r\n parse: {\r\n dateInput: 'DD/MM/YYYY'\r\n },\r\n display: {\r\n dateInput: 'DD/MM/YYYY',\r\n monthYearLabel: 'MMM YYYY',\r\n dateA11yLabel: 'LL',\r\n monthYearA11yLabel: 'MMMM YYYY'\r\n }\r\n};\r\n@Component({\r\n selector: 'sd-date-time',\r\n templateUrl: './date-time.component.html',\r\n styleUrls: ['./date-time.component.scss'],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n providers: [\r\n { provide: MAT_DATE_FORMATS, useValue: CUSTOM_DATE_FORMATS },\r\n { provide: NGX_MAT_DATE_FORMATS, useValue: CUSTOM_DATETIME_FORMATS }\r\n ]\r\n})\r\nexport class SdDateTime implements OnDestroy, OnInit, AfterViewInit {\r\n id = `I${uuid.v4()}`;\r\n isMobileOrTablet = false;\r\n #date: any;\r\n #name = uuid.v4();\r\n @Input() set name(val: string) {\r\n if (val) {\r\n this.#name = val;\r\n }\r\n }\r\n @Input() appearance: MatFormFieldAppearance;\r\n disableErrorMessage = false;\r\n @Input('disableErrorMessage') set _disableErrorMessage(val: boolean | '') {\r\n this.disableErrorMessage = (val === '') || val;\r\n val = (val === '') || val;\r\n }\r\n formControl = new SdFormControl();\r\n min: Date;\r\n @Input('min') set _min(val: string | Date | number) {\r\n if (Date.isDate(val)) {\r\n this.min = new Date(val);\r\n } else {\r\n this.min = null;\r\n }\r\n }\r\n max: Date;\r\n @Input('max') set _max(val: string | Date | number) {\r\n if (Date.isDate(val)) {\r\n this.max = new Date(val);\r\n } else {\r\n this.max = null;\r\n }\r\n }\r\n @Input() size: 'sm' | 'lg';\r\n #form: FormGroup;\r\n @Input() set form(val: NgForm | FormGroup) {\r\n if (val) {\r\n if (val instanceof NgForm) {\r\n this.#form = val.form;\r\n } else {\r\n this.#form = val;\r\n }\r\n }\r\n }\r\n maxlength: number;\r\n type: 'datetime' | 'date' | 'time' | 'month' = 'datetime';\r\n @Input('type') set _type(val: 'datetime' | 'date' | 'time' | 'month') {\r\n this.type = val || 'datetime';\r\n }\r\n @Input() set disabled(val: boolean | '') {\r\n val = (val === '') || val;\r\n if (val) {\r\n this.formControl.disable();\r\n } else {\r\n this.formControl.enable();\r\n }\r\n }\r\n required = false;\r\n @Input('required') set _required(val: boolean | '') {\r\n this.required = (val === '') || val;\r\n if (this.required) {\r\n this.formControl.setValidators([Validators.required]);\r\n } else {\r\n this.formControl.clearValidators();\r\n }\r\n }\r\n\r\n inlineError: string;\r\n @Input('inlineError') set _inlineError(val: string) {\r\n this.inlineError = val;\r\n // this.#updateValidator();\r\n if (this.inlineError) {\r\n \r\n\r\n this.formControl.setValidators([this.customInlineErrorValidator()]);\r\n this.formControl.updateValueAndValidity();\r\n\r\n } else {\r\n this.formControl.clearValidators();\r\n this.formControl.updateValueAndValidity();\r\n\r\n }\r\n \r\n }\r\n\r\n qcId: string;\r\n label: string;\r\n @Input('label') set _label(val: string) {\r\n this.label = val;\r\n this.qcId = hash({\r\n selector: 'sd-date-time',\r\n label: val\r\n });\r\n };\r\n @Input() placeholder: string;\r\n @Input() defaultTime: any;\r\n @Input() set minDate(val: string | Date) {\r\n if (Date.isDate(val)) {\r\n this.min = new Date(val);\r\n } else {\r\n this.min = null;\r\n }\r\n }\r\n @Input() set maxDate(val: string | Date) {\r\n if (Date.isDate(val)) {\r\n this.max = new Date(val);\r\n } else {\r\n this.max = null;\r\n }\r\n }\r\n @Input() validator: (value: any) => string | Promise<string>;\r\n @Output() sdChange = new EventEmitter();\r\n\r\n @Input() set model(val: any) {\r\n if (!Date.isDate(val)) {\r\n val = null;\r\n }\r\n if (this.#date !== val) {\r\n this.#date = val;\r\n const date = Date.isDate(this.#date) ? moment(Date.toFormat(this.#date, 'MM/dd/yyyy HH:mm:ss'), 'MM/DD/YYYY HH:mm:ss') : null;\r\n this.formControl.setValue(date);\r\n }\r\n }\r\n @Output() modelChange = new EventEmitter();\r\n #subscription = new Subscription();\r\n @ContentChild(SdViewDefDirective) sdView: SdViewDefDirective;\r\n @ContentChild(SdLabelDefDirective) sdLabelDef: SdLabelDefDirective;\r\n @ViewChild('input') input: ElementRef;\r\n @ViewChild(MatDatepicker) datePicker: MatDatepicker<Moment>;\r\n @ViewChild(NgxMatDatetimePicker) dateTimePicker: NgxMatDatetimePicker<Moment>;\r\n isFocused = false;\r\n constructor(\r\n private ref: ChangeDetectorRef,\r\n deviceService: DeviceDetectorService,\r\n @Inject(FORM_CONFIG) @Optional() private formConfig: IFormConfiguration) {\r\n this.isMobileOrTablet = !deviceService.isDesktop();\r\n }\r\n\r\n ngOnDestroy() {\r\n this.#form?.removeControl(this.#name);\r\n this.#subscription.unsubscribe();\r\n }\r\n\r\n ngOnInit() {\r\n this.maxlength = this.type === 'datetime' ? 16 : 10;\r\n this.appearance = this.appearance || this.formConfig?.appearance;\r\n this.#subscription.add(this.formControl.sdChanges.subscribe(() => {\r\n // this.formControl.updateValueAndValidity();\r\n this.ref.markForCheck();\r\n }));\r\n this.#form?.addControl(this.#name, this.formControl);\r\n }\r\n\r\n \r\n // Hàm tạo Validators tùy chỉnh cho inlineError\r\n customInlineErrorValidator(): ValidatorFn {\r\n return (control: AbstractControl): { [key: string]: any } | null => {\r\n return { inlineError: true };\r\n };\r\n }\r\n\r\n ngAfterViewInit() {\r\n }\r\n\r\n onFocus = () => {\r\n this.isFocused = true;\r\n }\r\n\r\n onBlur = () => {\r\n this.isFocused = false;\r\n }\r\n\r\n onClick = () => {\r\n if (this.sdView?.templateRef) {\r\n if (!this.formControl.disabled && !this.isFocused) {\r\n this.focus();\r\n }\r\n }\r\n }\r\n\r\n blur = () => {\r\n this.input?.nativeElement?.blur();\r\n }\r\n\r\n focus = () => {\r\n this.isFocused = true;\r\n setTimeout(() => {\r\n this.input?.nativeElement?.focus();\r\n if (this.type === 'date') {\r\n this.datePicker?.open();\r\n } else {\r\n this.dateTimePicker?.open();\r\n }\r\n //\r\n }, 100);\r\n }\r\n\r\n focusInputElement() {\r\n this.input?.nativeElement?.focus();\r\n }\r\n\r\n isValid: boolean;\r\n onKeyDown = (event: KeyboardEvent) => {\r\n const key = event.keyCode || event.charCode;\r\n let isShift = false;\r\n if (key == 16) {\r\n isShift = true;\r\n }\r\n //Allow only Numeric Keys.\r\n if (((key >= 48 && key <= 57) || key == 8 || key <= 37 || key <= 39 || (key >= 96 && key <= 105) || key == 191 || key == 186 || key == 59) && isShift == false) {\r\n return true;\r\n }\r\n else {\r\n return false;\r\n }\r\n }\r\n\r\n onKeyup = (event) => {\r\n const currentVal: string = event.target.value;\r\n const formControl: AbstractControl = this.formControl;\r\n let regex = /^([1-9]|([012][0-9])|(3[01]))\\/([0]{0,1}[1-9]|1[012])\\/\\d\\d\\d\\d$/g;\r\n\r\n if (this.type === 'datetime' || this.type === 'time') {\r\n regex = /^([1-9]|([012][0-9])|(3[01]))\\/([0]{0,1}[1-9]|1[012])\\/\\d\\d\\d\\d [012]{0,1}[0-9]:[0-6][0-9]$/g;\r\n }\r\n if (this.type === 'month') {\r\n regex = /^([0]{0,1}[1-9]|1[012])\\/\\d\\d\\d\\d [012]{0,1}[0-9]:[0-6][0-9]$/g;\r\n }\r\n\r\n const errorMessage = this.type === 'date' ? 'dd/MM/yyyy' : 'dd/MM/yyyy HH:mm';\r\n if (currentVal && !regex.test(currentVal)) {\r\n setTimeout(() => {\r\n this.isValid = true;\r\n formControl.markAsDirty();\r\n formControl.markAsTouched();\r\n formControl.setErrors({ ...formControl.errors, date: `Chưa đúng định dạng ${errorMessage}` });\r\n }, 0);\r\n\r\n } else {\r\n setTimeout(() => {\r\n this.isValid = false;\r\n formControl.setErrors({ ...formControl.errors, date: null });\r\n this.formControl.updateValueAndValidity();\r\n }, 0);\r\n }\r\n }\r\n\r\n onChange = (event: MatDatepickerInputEvent<Moment>) => {\r\n const value = event.value?.toDate();\r\n if (!this.dateTimePicker) {\r\n this.input?.nativeElement?.focus();\r\n }\r\n if (!this.isValid) {\r\n if (new Date(this.#date) !== value) {\r\n this.modelChange.emit(value);\r\n this.sdChange.emit(value);\r\n }\r\n } else {\r\n this.isValid = false;\r\n this.formControl.setValue(null);\r\n this.modelChange.emit(null);\r\n this.sdChange.emit(null);\r\n }\r\n }\r\n\r\n timeChanged = (event) => {\r\n const value = event;\r\n this.formControl.setValue(value);\r\n this.modelChange.emit(value);\r\n this.sdChange.emit(value);\r\n \r\n }\r\n\r\n clear = ($event: any) => {\r\n $event?.stopPropagation();\r\n if (this.formControl.value) {\r\n this.formControl.setValue(null);\r\n this.modelChange.emit(null);\r\n this.sdChange.emit(null);\r\n }\r\n }\r\n\r\n setMonthAndYear = (normalizedMonthAndYear: Moment, datepicker: MatDatepicker<Moment>) => {\r\n const ctrlValue = this.formControl.value || moment();\r\n ctrlValue.month(normalizedMonthAndYear.month());\r\n ctrlValue.year(normalizedMonthAndYear.year());\r\n this.formControl.setValue(ctrlValue);\r\n datepicker.close();\r\n this.modelChange.emit(ctrlValue);\r\n this.sdChange.emit(ctrlValue);\r\n }\r\n}\r\n","import { NgModule } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { FormsModule, ReactiveFormsModule } from '@angular/forms';\r\nimport { MatFormFieldModule } from '@angular/material/form-field';\r\nimport { MatDatepickerModule } from '@angular/material/datepicker';\r\nimport {\r\n NgxMatDatetimePickerModule,\r\n NgxMatTimepickerModule\r\n} from '@angular-material-components/datetime-picker';\r\nimport { SdDateTime } from './date-time.component';\r\nimport { SdTranslateModule } from '@sd-angular/core/translate';\r\nimport { MatInputModule } from '@angular/material/input';\r\nimport { NgxMatMomentModule } from '@angular-material-components/moment-adapter';\r\nimport { MatMomentDateModule } from '@angular/material-moment-adapter';\r\nimport { MatIconModule } from '@angular/material/icon';\r\nimport { SdCommonModule } from '@sd-angular/core/common';\r\nimport { SdPopoverModule } from '@sd-angular/core/popover';\r\nimport { NgxMaterialTimepickerModule } from 'ngx-material-timepicker';\r\nimport { SdButtonModule } from \"@sd-angular/core/button\";\r\n\r\n@NgModule({\r\n imports: [\r\n CommonModule,\r\n FormsModule,\r\n ReactiveFormsModule,\r\n MatInputModule,\r\n MatIconModule,\r\n MatFormFieldModule,\r\n MatDatepickerModule,\r\n MatMomentDateModule,\r\n NgxMatDatetimePickerModule,\r\n NgxMatTimepickerModule,\r\n NgxMatMomentModule,\r\n SdTranslateModule,\r\n SdCommonModule,\r\n SdPopoverModule,\r\n NgxMaterialTimepickerModule,\r\n SdButtonModule\r\n ],\r\n declarations: [\r\n SdDateTime\r\n ],\r\n exports: [\r\n SdCommonModule,\r\n SdDateTime\r\n ],\r\n providers: [\r\n ]\r\n})\r\nexport class SdDateTimeModule {\r\n\r\n}\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["uuid.v4"],"mappings":"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"}
@@ -9,12 +9,12 @@ import { v4 } from 'uuid';
9
9
  import $ from 'jquery';
10
10
  import { Subscription, Subject } from 'rxjs';
11
11
  import { startWith } from 'rxjs/operators';
12
- import { FormControl, FormsModule, ReactiveFormsModule } from '@angular/forms';
12
+ import { FormControl, Validators, FormsModule, ReactiveFormsModule } from '@angular/forms';
13
13
  import { MatFormFieldModule } from '@angular/material/form-field';
14
14
  import { MatInputModule } from '@angular/material/input';
15
15
  import { MatChipsModule } from '@angular/material/chips';
16
16
 
17
- var _model, _subscription, _modelChanges, _validate, _uploadFile, _validator;
17
+ var _model, _subscription, _modelChanges, _updateValidator, _validate, _uploadFile, _validator;
18
18
  class SdInputUploadFiletStateMatcher {
19
19
  constructor(formControl) {
20
20
  this.formControl = formControl;
@@ -37,6 +37,8 @@ class SdInputUploadFile {
37
37
  this.min = 0;
38
38
  this.max = 1;
39
39
  _model.set(this, void 0);
40
+ this.disableErrorMessage = false;
41
+ this.isRequired = false;
40
42
  this.modelChange = new EventEmitter();
41
43
  this.sdChange = new EventEmitter();
42
44
  this.inputControl = new FormControl();
@@ -44,6 +46,23 @@ class SdInputUploadFile {
44
46
  this.matcher = new SdInputUploadFiletStateMatcher(this.formControl);
45
47
  _subscription.set(this, new Subscription());
46
48
  _modelChanges.set(this, new Subject());
49
+ _updateValidator.set(this, () => {
50
+ this.formControl.clearValidators();
51
+ this.formControl.clearAsyncValidators();
52
+ const validators = [];
53
+ const asyncValidators = [];
54
+ if (this.isRequired) {
55
+ validators.push(Validators.required);
56
+ }
57
+ if (this.inlineError) {
58
+ validators.push(this.customInlineErrorValidator());
59
+ }
60
+ this.formControl.setValidators(validators);
61
+ this.formControl.setAsyncValidators(asyncValidators);
62
+ this.formControl.updateValueAndValidity();
63
+ }
64
+ // Hàm tạo Validators tùy chỉnh cho inlineError
65
+ );
47
66
  _validate.set(this, (file) => __awaiter(this, void 0, void 0, function* () {
48
67
  var _a;
49
68
  if (this.type === 'image') {
@@ -179,10 +198,27 @@ class SdInputUploadFile {
179
198
  __classPrivateFieldGet(this, _modelChanges).next(__classPrivateFieldGet(this, _model));
180
199
  }
181
200
  }
201
+ set _disableErrorMessage(val) {
202
+ this.disableErrorMessage = (val === '') || val;
203
+ }
204
+ set _inlineError(val) {
205
+ this.inlineError = val;
206
+ __classPrivateFieldGet(this, _updateValidator).call(this);
207
+ }
208
+ set required(val) {
209
+ this.isRequired = (val === '') || val;
210
+ __classPrivateFieldGet(this, _updateValidator).call(this);
211
+ }
182
212
  ngOnInit() {
183
213
  this.formControl.setValidators([__classPrivateFieldGet(this, _validator)]);
184
214
  this.inputControl.disable();
185
215
  }
216
+ // Hàm tạo Validators tùy chỉnh cho inlineError
217
+ customInlineErrorValidator() {
218
+ return (control) => {
219
+ return { inlineError: true };
220
+ };
221
+ }
186
222
  ngAfterViewInit() {
187
223
  __classPrivateFieldGet(this, _subscription).add(__classPrivateFieldGet(this, _modelChanges).pipe(startWith(__classPrivateFieldGet(this, _model))).subscribe((previewFiles) => {
188
224
  if (Array.isArray(previewFiles)) {
@@ -207,11 +243,11 @@ class SdInputUploadFile {
207
243
  __classPrivateFieldGet(this, _subscription).unsubscribe();
208
244
  }
209
245
  }
210
- _model = new WeakMap(), _subscription = new WeakMap(), _modelChanges = new WeakMap(), _validate = new WeakMap(), _uploadFile = new WeakMap(), _validator = new WeakMap();
246
+ _model = new WeakMap(), _subscription = new WeakMap(), _modelChanges = new WeakMap(), _updateValidator = new WeakMap(), _validate = new WeakMap(), _uploadFile = new WeakMap(), _validator = new WeakMap();
211
247
  SdInputUploadFile.decorators = [
212
248
  { type: Component, args: [{
213
249
  selector: 'sd-input-upload-file',
214
- template: "<mat-form-field class=\"sd-md\" appearance=\"outline\">\r\n <mat-label *ngIf=\"label\">{{label}}</mat-label>\r\n <mat-chip-list [formControl]=\"formControl\" #chipList>\r\n <ng-container *ngFor=\"let item of previewFiles\">\r\n <mat-chip *ngIf=\"item\" [removable]=\"!formControl.disabled\" (removed)=\"onRemove(item)\"\r\n [removable]=\"formControl.disabled\">\r\n <span>{{item.fileName || item.src}}</span>\r\n <mat-icon matChipRemove *ngIf=\"!formControl.disabled\">cancel</mat-icon>\r\n </mat-chip>\r\n </ng-container>\r\n <input [formControl]=\"inputControl\" [placeholder]=\"placeholder || label\" [matChipInputFor]=\"chipList\"\r\n autocomplete=\"off\" [errorStateMatcher]=\"matcher\" matInput>\r\n <mat-icon class=\"pointer sd-suffix-icon\" (click)=\"onUpload()\" matSuffix>file_upload\r\n </mat-icon>\r\n </mat-chip-list>\r\n <mat-error *ngIf=\"formControl?.errors?.min\">\r\n {{formControl?.errors?.min}}\r\n </mat-error>\r\n <mat-error *ngIf=\"formControl?.errors?.max\">\r\n {{formControl?.errors?.max}}\r\n </mat-error>\r\n</mat-form-field>",
250
+ template: "<mat-form-field class=\"sd-md\" appearance=\"outline\">\r\n <mat-label *ngIf=\"label\">{{label}}</mat-label>\r\n <mat-chip-list [formControl]=\"formControl\" #chipList>\r\n <ng-container *ngFor=\"let item of previewFiles\">\r\n <mat-chip *ngIf=\"item\" [removable]=\"!formControl.disabled\" (removed)=\"onRemove(item)\"\r\n [removable]=\"formControl.disabled\">\r\n <span>{{item.fileName || item.src}}</span>\r\n <mat-icon matChipRemove *ngIf=\"!formControl.disabled\">cancel</mat-icon>\r\n </mat-chip>\r\n </ng-container>\r\n <input [formControl]=\"inputControl\" [placeholder]=\"placeholder || label\" [matChipInputFor]=\"chipList\"\r\n autocomplete=\"off\" [errorStateMatcher]=\"matcher\" matInput>\r\n <mat-icon class=\"pointer sd-suffix-icon\" (click)=\"onUpload()\" matSuffix>file_upload\r\n </mat-icon>\r\n </mat-chip-list>\r\n <mat-error *ngIf=\"formControl.errors?.required\">\r\n <ng-container *ngIf=\"!disableErrorMessage\">{{ \"This field is required\" | sdTranslate }}</ng-container>\r\n </mat-error>\r\n <mat-error *ngIf=\"formControl?.errors?.min\">\r\n {{formControl?.errors?.min}}\r\n </mat-error>\r\n <mat-error *ngIf=\"formControl?.errors?.max\">\r\n {{formControl?.errors?.max}}\r\n </mat-error>\r\n <mat-error *ngIf=\"formControl.errors?.inlineError\">\r\n <ng-container *ngIf=\"!disableErrorMessage\">{{inlineError}}</ng-container>\r\n </mat-error>\r\n</mat-form-field>",
215
251
  styles: [":host{display:block;padding-top:5px}"]
216
252
  },] }
217
253
  ];
@@ -232,6 +268,9 @@ SdInputUploadFile.propDecorators = {
232
268
  maxHeight: [{ type: Input }],
233
269
  disabled: [{ type: Input }],
234
270
  model: [{ type: Input }],
271
+ _disableErrorMessage: [{ type: Input, args: ['disableErrorMessage',] }],
272
+ _inlineError: [{ type: Input, args: ['inlineError',] }],
273
+ required: [{ type: Input }],
235
274
  modelChange: [{ type: Output }],
236
275
  sdChange: [{ type: Output }]
237
276
  };
@@ -1 +1 @@
1
- {"version":3,"file":"sd-angular-core-input-upload-file.js","sources":["../../../../projects/sd-core/input-upload-file/src/lib/input-upload-file.component.ts","../../../../projects/sd-core/input-upload-file/src/lib/input-upload-file.module.ts","../../../../projects/sd-core/input-upload-file/src/public-api.ts","../../../../projects/sd-core/input-upload-file/sd-angular-core-input-upload-file.ts"],"sourcesContent":["import {\r\n Component,\r\n Input,\r\n Output,\r\n EventEmitter,\r\n ChangeDetectorRef,\r\n AfterViewInit,\r\n OnInit,\r\n OnDestroy,\r\n} from '@angular/core';\r\nimport * as uuid from 'uuid';\r\nimport $ from 'jquery';\r\nimport { SdNotifyService } from '@sd-angular/core/notify';\r\nimport { SdTranslateService } from '@sd-angular/core/translate';\r\nimport { Subscription, Subject } from 'rxjs';\r\nimport { startWith } from 'rxjs/operators';\r\nimport { ErrorStateMatcher } from '@angular/material/core';\r\nimport { FormControl, FormGroupDirective, NgForm, AbstractControl, ValidatorFn } from '@angular/forms';\r\nclass SdInputUploadFiletStateMatcher implements ErrorStateMatcher {\r\n constructor(private formControl: FormControl) { }\r\n isErrorState(control: FormControl | null, form: FormGroupDirective | NgForm | null): boolean {\r\n const isSubmitted = form && form.submitted;\r\n return !!(this.formControl?.invalid && (this.formControl?.dirty || this.formControl?.touched || isSubmitted));\r\n }\r\n}\r\n@Component({\r\n selector: 'sd-input-upload-file',\r\n templateUrl: './input-upload-file.component.html',\r\n styleUrls: ['./input-upload-file.component.scss']\r\n})\r\nexport class SdInputUploadFile implements OnInit, AfterViewInit, OnDestroy {\r\n id = `I${uuid.v4()}`;\r\n previewFiles: SdPreviewFile[] = [];\r\n @Input() label: string;\r\n @Input() placeholder: string;\r\n @Input() type: 'image' | 'file' = 'file';\r\n @Input() extensions: string[] = [];\r\n @Input() min = 0;\r\n @Input() max = 1;\r\n @Input() maxSize: number;\r\n @Input() maxWidth: number;\r\n @Input() maxHeight: number;\r\n // Optional\r\n @Input() set disabled(val: boolean | '') {\r\n val = (val === '') || val;\r\n if (val) {\r\n this.formControl.disable();\r\n } else {\r\n this.formControl.enable();\r\n }\r\n }\r\n #model: (string | SdPreviewFile)[];\r\n @Input() set model(model: (string | SdPreviewFile)[]) {\r\n if (this.previewFiles !== model && Array.isArray(model)) {\r\n this.#model = model;\r\n this.#modelChanges.next(this.#model);\r\n }\r\n }\r\n @Output() modelChange = new EventEmitter<(string | SdPreviewFile)[]>();\r\n @Output() sdChange = new EventEmitter<(string | SdPreviewFile)[]>();\r\n inputControl = new FormControl();\r\n formControl = new FormControl();\r\n matcher = new SdInputUploadFiletStateMatcher(this.formControl);\r\n #subscription = new Subscription();\r\n #modelChanges = new Subject<(string | SdPreviewFile)[]>();\r\n constructor(\r\n private ref: ChangeDetectorRef,\r\n private notifyService: SdNotifyService,\r\n private translateService: SdTranslateService) {\r\n }\r\n\r\n ngOnInit() {\r\n this.formControl.setValidators([this.#validator]);\r\n this.inputControl.disable();\r\n }\r\n\r\n ngAfterViewInit() {\r\n this.#subscription.add(this.#modelChanges.pipe(startWith(this.#model)).subscribe((previewFiles) => {\r\n if (Array.isArray(previewFiles)) {\r\n this.previewFiles = [];\r\n previewFiles.forEach(previewFile => {\r\n if (typeof (previewFile) === 'string') {\r\n this.previewFiles.push({\r\n file: null,\r\n src: previewFile\r\n })\r\n } else {\r\n this.previewFiles.push(previewFile);\r\n }\r\n });\r\n this.formControl.setValue(this.previewFiles);\r\n this.modelChange.emit(this.previewFiles);\r\n }\r\n }));\r\n }\r\n\r\n ngOnDestroy() {\r\n this.#subscription.unsubscribe();\r\n }\r\n\r\n #validate = async (file: File): Promise<string> => {\r\n if (this.type === 'image') {\r\n if (file.type.split('/')[0] !== 'image') {\r\n return `[${file.name}] ${this.translateService.translate('Uploaded file is not an image')}`;\r\n }\r\n }\r\n if (this.extensions?.length) {\r\n const lastDot = file.name.lastIndexOf('.');\r\n const extension = file.name.substring(lastDot + 1);\r\n if (!this.extensions.some(e => e.toUpperCase() === extension.toUpperCase())) {\r\n return `[${file.name}] ${this.translateService.translate('Uploaded file is not match extension')} ${this.extensions.join(', ')}`;\r\n }\r\n }\r\n if (this.maxSize) {\r\n if (this.maxSize * 1024 * 1024 < file.size) {\r\n return `[${file.name}] ${this.translateService.translate('Max file size')} ${this.maxSize} Mbs`;\r\n }\r\n }\r\n if (this.type === 'image' && (this.maxWidth || this.maxHeight)) {\r\n const message: string = await new Promise(resolve => {\r\n const URL = window.URL || window.webkitURL;\r\n const img = new Image();\r\n img.onload = () => {\r\n if (this.maxWidth && img.width > this.maxWidth) {\r\n resolve(`[${file.name}] ${this.translateService.translate('Max image width')} ${this.maxWidth}px`);\r\n }\r\n if (this.maxHeight && img.height > this.maxHeight) {\r\n resolve(`[${file.name}] ${this.translateService.translate('Max image height')} ${this.maxHeight}px`);\r\n }\r\n resolve(null);\r\n };\r\n img.src = URL.createObjectURL(file);\r\n });\r\n if (message) {\r\n return message;\r\n }\r\n }\r\n return null;\r\n }\r\n\r\n onUpload = () => {\r\n if ($(`#${this.id}`).length) {\r\n $('body').children(`#${this.id}`).remove();\r\n }\r\n if (this.max === 1) {\r\n $('body').append(`<input id=\"${this.id}\" style=\"display: none\" type=\"file\" />`);\r\n } else {\r\n $('body').append(`<input id=\"${this.id}\" style=\"display: none\" type=\"file\" multiple />`);\r\n }\r\n $(`#${this.id}`).on('change', async (evt: any) => {\r\n await this.#uploadFile(evt.target);\r\n $('body').children(`#${this.id}`).remove();\r\n });\r\n $(`#${this.id}`).trigger('click');\r\n }\r\n\r\n #uploadFile = async (target: DataTransfer) => {\r\n if (!target.files.length) {\r\n return;\r\n }\r\n const originFiles = target.files;\r\n const files: File[] = [];\r\n if (originFiles.length + this.previewFiles.length > this.max) {\r\n this.notifyService.notify.warning(`${this.translateService.translate('Max number of files')} ${this.max}`);\r\n return;\r\n }\r\n for (let i = 0; i < originFiles.length; i++) {\r\n let file = originFiles.item(i);\r\n const message = await this.#validate(file);\r\n if (message) {\r\n this.notifyService.notify.warning(message);\r\n return;\r\n }\r\n files.push(file);\r\n }\r\n for (const file of files) {\r\n const lastDot = file.name.lastIndexOf('.');\r\n const extension = file.name.substring(lastDot + 1);\r\n this.previewFiles.push({\r\n file,\r\n src: null,\r\n fileName: file.name,\r\n extension\r\n });\r\n }\r\n this.formControl.setValue(this.previewFiles);\r\n this.sdChange.emit(this.previewFiles);\r\n this.ref.detectChanges();\r\n }\r\n\r\n onRemove = (previewFile: SdPreviewFile): void => {\r\n const idx = this.previewFiles.indexOf(previewFile);\r\n this.previewFiles.splice(idx, 1);\r\n this.formControl.setValue(this.previewFiles, {\r\n emitEvent: false\r\n });\r\n this.formControl.setValue(this.previewFiles);\r\n this.sdChange.emit(this.previewFiles);\r\n }\r\n\r\n #validator = (c: AbstractControl): { [key: string]: any } | null => {\r\n const value = c.value || null;\r\n if (this.min > 0) {\r\n const previewFiles: SdPreviewFile[] = this.formControl.value || [];\r\n if (previewFiles.length < this.min) {\r\n return {\r\n min: `${this.translateService.translate('Please select at least')} ${this.min}`\r\n }\r\n }\r\n }\r\n if (this.max > 0) {\r\n const previewFiles: SdPreviewFile[] = this.formControl.value || [];\r\n if (previewFiles.length > this.max) {\r\n return {\r\n max: `${this.translateService.translate('Please select at most')} ${this.max}`\r\n }\r\n }\r\n }\r\n return null;\r\n };\r\n}\r\n\r\nexport interface SdPreviewFile {\r\n file: File;\r\n src: string | ArrayBuffer;\r\n fileName?: string;\r\n extension?: string;\r\n}\r\n","import { NgModule } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { DeviceDetectorModule } from 'ngx-device-detector';\r\nimport { SdNotifyModule } from '@sd-angular/core/notify';\r\nimport { SdTranslateModule } from '@sd-angular/core/translate';\r\nimport { MatIconModule } from '@angular/material/icon';\r\nimport { SdInputUploadFile } from './input-upload-file.component';\r\nimport { MatFormFieldModule } from '@angular/material/form-field';\r\nimport { MatInputModule } from '@angular/material/input';\r\nimport { MatChipsModule } from '@angular/material/chips';\r\nimport { FormsModule, ReactiveFormsModule } from '@angular/forms';\r\n\r\n@NgModule({\r\n imports: [\r\n CommonModule,\r\n DeviceDetectorModule.forRoot(),\r\n MatFormFieldModule,\r\n MatInputModule,\r\n MatChipsModule,\r\n MatIconModule,\r\n FormsModule,\r\n ReactiveFormsModule,\r\n SdNotifyModule,\r\n SdTranslateModule\r\n ],\r\n declarations: [\r\n SdInputUploadFile\r\n ],\r\n exports: [\r\n SdInputUploadFile\r\n ],\r\n providers: [\r\n ]\r\n})\r\nexport class SdInputUploadFileModule { }\r\n","/*\r\n * Public API Surface of superdev-angular-core\r\n */\r\n\r\nexport * from './lib/input-upload-file.module';\r\nexport * from './lib/input-upload-file.component';\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["uuid.v4"],"mappings":"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"}
1
+ {"version":3,"file":"sd-angular-core-input-upload-file.js","sources":["../../../../projects/sd-core/input-upload-file/src/lib/input-upload-file.component.ts","../../../../projects/sd-core/input-upload-file/src/lib/input-upload-file.module.ts","../../../../projects/sd-core/input-upload-file/src/public-api.ts","../../../../projects/sd-core/input-upload-file/sd-angular-core-input-upload-file.ts"],"sourcesContent":["import {\r\n Component,\r\n Input,\r\n Output,\r\n EventEmitter,\r\n ChangeDetectorRef,\r\n AfterViewInit,\r\n OnInit,\r\n OnDestroy,\r\n} from '@angular/core';\r\nimport * as uuid from 'uuid';\r\nimport $ from 'jquery';\r\nimport { SdNotifyService } from '@sd-angular/core/notify';\r\nimport { SdTranslateService } from '@sd-angular/core/translate';\r\nimport { Subscription, Subject } from 'rxjs';\r\nimport { startWith } from 'rxjs/operators';\r\nimport { ErrorStateMatcher } from '@angular/material/core';\r\nimport { FormControl, FormGroupDirective, NgForm, AbstractControl, ValidatorFn, AsyncValidatorFn, Validators } from '@angular/forms';\r\nclass SdInputUploadFiletStateMatcher implements ErrorStateMatcher {\r\n constructor(private formControl: FormControl) { }\r\n isErrorState(control: FormControl | null, form: FormGroupDirective | NgForm | null): boolean {\r\n const isSubmitted = form && form.submitted;\r\n return !!(this.formControl?.invalid && (this.formControl?.dirty || this.formControl?.touched || isSubmitted));\r\n }\r\n}\r\n@Component({\r\n selector: 'sd-input-upload-file',\r\n templateUrl: './input-upload-file.component.html',\r\n styleUrls: ['./input-upload-file.component.scss']\r\n})\r\nexport class SdInputUploadFile implements OnInit, AfterViewInit, OnDestroy {\r\n id = `I${uuid.v4()}`;\r\n previewFiles: SdPreviewFile[] = [];\r\n @Input() label: string;\r\n @Input() placeholder: string;\r\n @Input() type: 'image' | 'file' = 'file';\r\n @Input() extensions: string[] = [];\r\n @Input() min = 0;\r\n @Input() max = 1;\r\n @Input() maxSize: number;\r\n @Input() maxWidth: number;\r\n @Input() maxHeight: number;\r\n // Optional\r\n @Input() set disabled(val: boolean | '') {\r\n val = (val === '') || val;\r\n if (val) {\r\n this.formControl.disable();\r\n } else {\r\n this.formControl.enable();\r\n }\r\n }\r\n #model: (string | SdPreviewFile)[];\r\n @Input() set model(model: (string | SdPreviewFile)[]) {\r\n if (this.previewFiles !== model && Array.isArray(model)) {\r\n this.#model = model;\r\n this.#modelChanges.next(this.#model);\r\n }\r\n }\r\n disableErrorMessage = false;\r\n @Input('disableErrorMessage') set _disableErrorMessage(val: boolean | '') {\r\n this.disableErrorMessage = (val === '') || val;\r\n }\r\n inlineError: string;\r\n @Input('inlineError') set _inlineError(val: string) {\r\n this.inlineError = val;\r\n this.#updateValidator();\r\n }\r\n\r\n isRequired = false;\r\n @Input() set required(val: boolean | '') {\r\n this.isRequired = (val === '') || val;\r\n this.#updateValidator();\r\n }\r\n\r\n @Output() modelChange = new EventEmitter<(string | SdPreviewFile)[]>();\r\n @Output() sdChange = new EventEmitter<(string | SdPreviewFile)[]>();\r\n inputControl = new FormControl();\r\n formControl = new FormControl();\r\n matcher = new SdInputUploadFiletStateMatcher(this.formControl);\r\n #subscription = new Subscription();\r\n #modelChanges = new Subject<(string | SdPreviewFile)[]>();\r\n constructor(\r\n private ref: ChangeDetectorRef,\r\n private notifyService: SdNotifyService,\r\n private translateService: SdTranslateService) {\r\n }\r\n\r\n ngOnInit() {\r\n this.formControl.setValidators([this.#validator]);\r\n this.inputControl.disable();\r\n }\r\n\r\n \r\n #updateValidator = () => {\r\n\r\n this.formControl.clearValidators();\r\n this.formControl.clearAsyncValidators();\r\n const validators: ValidatorFn[] = [];\r\n const asyncValidators: AsyncValidatorFn[] = [];\r\n if (this.isRequired) {\r\n validators.push(Validators.required);\r\n }\r\n \r\n if (this.inlineError) {\r\n validators.push(this.customInlineErrorValidator());\r\n }\r\n \r\n this.formControl.setValidators(validators);\r\n this.formControl.setAsyncValidators(asyncValidators);\r\n this.formControl.updateValueAndValidity();\r\n }\r\n\r\n \r\n // Hàm tạo Validators tùy chỉnh cho inlineError\r\n customInlineErrorValidator(): ValidatorFn {\r\n return (control: AbstractControl): { [key: string]: any } | null => {\r\n return { inlineError: true };\r\n };\r\n }\r\n\r\n ngAfterViewInit() {\r\n this.#subscription.add(this.#modelChanges.pipe(startWith(this.#model)).subscribe((previewFiles) => {\r\n if (Array.isArray(previewFiles)) {\r\n this.previewFiles = [];\r\n previewFiles.forEach(previewFile => {\r\n if (typeof (previewFile) === 'string') {\r\n this.previewFiles.push({\r\n file: null,\r\n src: previewFile\r\n })\r\n } else {\r\n this.previewFiles.push(previewFile);\r\n }\r\n });\r\n this.formControl.setValue(this.previewFiles);\r\n this.modelChange.emit(this.previewFiles);\r\n }\r\n }));\r\n }\r\n\r\n ngOnDestroy() {\r\n this.#subscription.unsubscribe();\r\n }\r\n\r\n #validate = async (file: File): Promise<string> => {\r\n if (this.type === 'image') {\r\n if (file.type.split('/')[0] !== 'image') {\r\n return `[${file.name}] ${this.translateService.translate('Uploaded file is not an image')}`;\r\n }\r\n }\r\n if (this.extensions?.length) {\r\n const lastDot = file.name.lastIndexOf('.');\r\n const extension = file.name.substring(lastDot + 1);\r\n if (!this.extensions.some(e => e.toUpperCase() === extension.toUpperCase())) {\r\n return `[${file.name}] ${this.translateService.translate('Uploaded file is not match extension')} ${this.extensions.join(', ')}`;\r\n }\r\n }\r\n if (this.maxSize) {\r\n if (this.maxSize * 1024 * 1024 < file.size) {\r\n return `[${file.name}] ${this.translateService.translate('Max file size')} ${this.maxSize} Mbs`;\r\n }\r\n }\r\n if (this.type === 'image' && (this.maxWidth || this.maxHeight)) {\r\n const message: string = await new Promise(resolve => {\r\n const URL = window.URL || window.webkitURL;\r\n const img = new Image();\r\n img.onload = () => {\r\n if (this.maxWidth && img.width > this.maxWidth) {\r\n resolve(`[${file.name}] ${this.translateService.translate('Max image width')} ${this.maxWidth}px`);\r\n }\r\n if (this.maxHeight && img.height > this.maxHeight) {\r\n resolve(`[${file.name}] ${this.translateService.translate('Max image height')} ${this.maxHeight}px`);\r\n }\r\n resolve(null);\r\n };\r\n img.src = URL.createObjectURL(file);\r\n });\r\n if (message) {\r\n return message;\r\n }\r\n }\r\n return null;\r\n }\r\n\r\n onUpload = () => {\r\n if ($(`#${this.id}`).length) {\r\n $('body').children(`#${this.id}`).remove();\r\n }\r\n if (this.max === 1) {\r\n $('body').append(`<input id=\"${this.id}\" style=\"display: none\" type=\"file\" />`);\r\n } else {\r\n $('body').append(`<input id=\"${this.id}\" style=\"display: none\" type=\"file\" multiple />`);\r\n }\r\n $(`#${this.id}`).on('change', async (evt: any) => {\r\n await this.#uploadFile(evt.target);\r\n $('body').children(`#${this.id}`).remove();\r\n });\r\n $(`#${this.id}`).trigger('click');\r\n }\r\n\r\n #uploadFile = async (target: DataTransfer) => {\r\n if (!target.files.length) {\r\n return;\r\n }\r\n const originFiles = target.files;\r\n const files: File[] = [];\r\n if (originFiles.length + this.previewFiles.length > this.max) {\r\n this.notifyService.notify.warning(`${this.translateService.translate('Max number of files')} ${this.max}`);\r\n return;\r\n }\r\n for (let i = 0; i < originFiles.length; i++) {\r\n let file = originFiles.item(i);\r\n const message = await this.#validate(file);\r\n if (message) {\r\n this.notifyService.notify.warning(message);\r\n return;\r\n }\r\n files.push(file);\r\n }\r\n for (const file of files) {\r\n const lastDot = file.name.lastIndexOf('.');\r\n const extension = file.name.substring(lastDot + 1);\r\n this.previewFiles.push({\r\n file,\r\n src: null,\r\n fileName: file.name,\r\n extension\r\n });\r\n }\r\n this.formControl.setValue(this.previewFiles);\r\n this.sdChange.emit(this.previewFiles);\r\n this.ref.detectChanges();\r\n }\r\n\r\n onRemove = (previewFile: SdPreviewFile): void => {\r\n const idx = this.previewFiles.indexOf(previewFile);\r\n this.previewFiles.splice(idx, 1);\r\n this.formControl.setValue(this.previewFiles, {\r\n emitEvent: false\r\n });\r\n this.formControl.setValue(this.previewFiles);\r\n this.sdChange.emit(this.previewFiles);\r\n }\r\n\r\n #validator = (c: AbstractControl): { [key: string]: any } | null => {\r\n const value = c.value || null;\r\n if (this.min > 0) {\r\n const previewFiles: SdPreviewFile[] = this.formControl.value || [];\r\n if (previewFiles.length < this.min) {\r\n return {\r\n min: `${this.translateService.translate('Please select at least')} ${this.min}`\r\n }\r\n }\r\n }\r\n if (this.max > 0) {\r\n const previewFiles: SdPreviewFile[] = this.formControl.value || [];\r\n if (previewFiles.length > this.max) {\r\n return {\r\n max: `${this.translateService.translate('Please select at most')} ${this.max}`\r\n }\r\n }\r\n }\r\n return null;\r\n };\r\n}\r\n\r\nexport interface SdPreviewFile {\r\n file: File;\r\n src: string | ArrayBuffer;\r\n fileName?: string;\r\n extension?: string;\r\n}\r\n","import { NgModule } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { DeviceDetectorModule } from 'ngx-device-detector';\r\nimport { SdNotifyModule } from '@sd-angular/core/notify';\r\nimport { SdTranslateModule } from '@sd-angular/core/translate';\r\nimport { MatIconModule } from '@angular/material/icon';\r\nimport { SdInputUploadFile } from './input-upload-file.component';\r\nimport { MatFormFieldModule } from '@angular/material/form-field';\r\nimport { MatInputModule } from '@angular/material/input';\r\nimport { MatChipsModule } from '@angular/material/chips';\r\nimport { FormsModule, ReactiveFormsModule } from '@angular/forms';\r\n\r\n@NgModule({\r\n imports: [\r\n CommonModule,\r\n DeviceDetectorModule.forRoot(),\r\n MatFormFieldModule,\r\n MatInputModule,\r\n MatChipsModule,\r\n MatIconModule,\r\n FormsModule,\r\n ReactiveFormsModule,\r\n SdNotifyModule,\r\n SdTranslateModule\r\n ],\r\n declarations: [\r\n SdInputUploadFile\r\n ],\r\n exports: [\r\n SdInputUploadFile\r\n ],\r\n providers: [\r\n ]\r\n})\r\nexport class SdInputUploadFileModule { }\r\n","/*\r\n * Public API Surface of superdev-angular-core\r\n */\r\n\r\nexport * from './lib/input-upload-file.module';\r\nexport * from './lib/input-upload-file.component';\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["uuid.v4"],"mappings":"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"}
@@ -5,6 +5,7 @@ import { MatIconModule } from '@angular/material/icon';
5
5
  import { __classPrivateFieldGet, __classPrivateFieldSet, __awaiter } from 'tslib';
6
6
  import { MatPaginator, MatPaginatorIntl, MatPaginatorModule } from '@angular/material/paginator';
7
7
  import { MatSort, MatSortModule } from '@angular/material/sort';
8
+ import { MatTable, MatTableModule } from '@angular/material/table';
8
9
  import { trigger, state, style, transition, animate } from '@angular/animations';
9
10
  import { v4 } from 'uuid';
10
11
  import { BehaviorSubject, Subscription, Subject, isObservable, combineLatest } from 'rxjs';
@@ -19,7 +20,6 @@ import * as hash from 'object-hash';
19
20
  import hash__default from 'object-hash';
20
21
  import { moveItemInArray, DragDropModule } from '@angular/cdk/drag-drop';
21
22
  import { SdLoadingService } from '@sd-angular/core/loading';
22
- import { MatTableModule } from '@angular/material/table';
23
23
  import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
24
24
  import { CdkTableModule, CdkColumnDef } from '@angular/cdk/table';
25
25
  import { MatMenuModule } from '@angular/material/menu';
@@ -1693,6 +1693,10 @@ class SdTable {
1693
1693
  ngOnInit() {
1694
1694
  __classPrivateFieldGet(this, _initCellDef).call(this);
1695
1695
  }
1696
+ ngAfterViewChecked() {
1697
+ if (this.table)
1698
+ this.table.updateStickyColumnStyles();
1699
+ }
1696
1700
  ngAfterViewInit() {
1697
1701
  __classPrivateFieldGet(this, _subscription$1).add(__classPrivateFieldGet(this, _reload).pipe(debounceTime(200), switchMap((data) => __awaiter(this, void 0, void 0, function* () {
1698
1702
  const filterInfo = __classPrivateFieldGet(this, _getFilter).call(this);
@@ -1733,7 +1737,7 @@ _gridId = new WeakMap(), _optionChanges = new WeakMap(), _localItems = new WeakM
1733
1737
  SdTable.decorators = [
1734
1738
  { type: Component, args: [{
1735
1739
  selector: 'sd-table',
1736
- template: "<ng-container *ngIf=\"configuration\">\r\n <sd-table-filter\r\n *ngIf=\"!tableOption.filter?.disabled && filterRegister\"\r\n [filterRegister]=\"filterRegister\"\r\n [filter]=\"tableOption?.filter\"\r\n [columns]=\"configuration.firstColumns\"\r\n [externalFilters]=\"tableOption?.filter?.externalFilters\"\r\n [filterDefs]=\"filterDefs\">\r\n </sd-table-filter>\r\n <ng-container *ngIf=\"items | sdGroup : tableOption; $implicit as groupedItems\">\r\n <div class=\"c-container\">\r\n <div class=\"c-loading\" *ngIf=\"isLoading\">\r\n <mat-spinner></mat-spinner>\r\n </div>\r\n <ng-container>\r\n <div\r\n class=\"c-table\"\r\n sdScroll\r\n [ngStyle]=\"{\r\n 'max-height': tableOption?.style?.maxHeight,\r\n 'min-height': tableOption?.style?.minHeight\r\n }\">\r\n <table mat-table [dataSource]=\"groupedItems\" [trackBy]=\"trackBy\" matSort [matSortDisabled]=\"!tableOption.sort?.enable\" multiTemplateDataRows>\r\n <ng-container matColumnDef=\"sdSubInformation\" sticky>\r\n <td class=\"p-0\" mat-cell *matCellDef=\"let item\" [attr.colspan]=\"configuration.displayedColumns.length\">\r\n <ng-container *ngIf=\"sdSubInformation?.templateRef\">\r\n <ng-container *ngIf=\"tableOption?.expand?.always; else useExpandCollapse\">\r\n <ng-container *ngTemplateOutlet=\"sdSubInformation.templateRef; context: { item: item }\"> </ng-container>\r\n </ng-container>\r\n <ng-template #useExpandCollapse>\r\n <div [@detailExpand]=\"item.isExpanded ? 'expanded' : 'collapsed'\">\r\n <ng-container *ngIf=\"item.isExpanded\">\r\n <ng-container *ngTemplateOutlet=\"sdSubInformation.templateRef; context: { item: item }\"> </ng-container>\r\n </ng-container>\r\n </div>\r\n </ng-template>\r\n </ng-container>\r\n </td>\r\n <td mat-footer-cell *matFooterCellDef></td>\r\n </ng-container>\r\n <ng-container matColumnDef=\"sdSubInformationAction\" stickyEnd>\r\n <th\r\n class=\"p-0\"\r\n mat-header-cell\r\n *matHeaderCellDef\r\n style=\"width: 1px\"\r\n [attr.rowspan]=\"configuration.multipleHeader ? 2 : 1\"></th>\r\n <td mat-cell *matCellDef=\"let element\">\r\n <button\r\n *ngIf=\"!element.isExpanding && !tableOption?.expand?.always\"\r\n mat-icon-button\r\n aria-label=\"Expand & Collapse\"\r\n (click)=\"onExpand(element)\">\r\n <mat-icon *ngIf=\"!element.isExpanded\">expand_more</mat-icon>\r\n <mat-icon *ngIf=\"element.isExpanded\">expand_less</mat-icon>\r\n </button>\r\n <div *ngIf=\"element.isExpanding\" class=\"lds-ring\">\r\n <div></div>\r\n <div></div>\r\n <div></div>\r\n <div></div>\r\n </div>\r\n </td>\r\n </ng-container>\r\n <ng-container matColumnDef=\"sdSelection\" sticky>\r\n <th\r\n class=\"text-center px-15\"\r\n mat-header-cell\r\n *matHeaderCellDef\r\n style=\"min-width: 50px; max-width: 50px\"\r\n [attr.rowspan]=\"configuration.multipleHeader ? 2 : 1\">\r\n <ng-container *ngIf=\"items | selectionVisibleSelectAll : tableOption?.selector | async\">\r\n <mat-checkbox\r\n *ngIf=\"!tableOption.selector?.single\"\r\n class=\"c-selection\"\r\n color=\"primary\"\r\n [(ngModel)]=\"isSelectAll\"\r\n (change)=\"onSelectAll()\">\r\n </mat-checkbox>\r\n </ng-container>\r\n </th>\r\n <td class=\"text-center px-15\" mat-cell *matCellDef=\"let item\" style=\"min-width: 50px; max-width: 50px\">\r\n <ng-container *ngIf=\"item | selectionVisible : tableOption?.selector\">\r\n <mat-checkbox\r\n class=\"c-selection\"\r\n color=\"primary\"\r\n [(ngModel)]=\"item.meta.selector.isSelected\"\r\n (change)=\"onSelect(item)\"\r\n [disabled]=\"selectedTableItems | selectionDisable : item : tableOption?.selector\">\r\n </mat-checkbox>\r\n </ng-container>\r\n </td>\r\n <td mat-footer-cell *matFooterCellDef></td>\r\n </ng-container>\r\n <ng-container matColumnDef=\"sdCommand\" sticky>\r\n <th\r\n class=\"px-8 py-8\"\r\n mat-header-cell\r\n *matHeaderCellDef\r\n style=\"width: 50px\"\r\n [attr.rowspan]=\"configuration.multipleHeader ? 2 : 1\"></th>\r\n <td class=\"px-8\" mat-cell *matCellDef=\"let item\">\r\n <sd-desktop-command [commands]=\"tableOption.commands\" [item]=\"item\"></sd-desktop-command>\r\n </td>\r\n <td mat-footer-cell *matFooterCellDef></td>\r\n </ng-container>\r\n <ng-container matColumnDef=\"sdGroup\">\r\n <th mat-header-cell *matHeaderCellDef class=\"px-8 py-8\" [attr.rowspan]=\"configuration.multipleHeader ? 2 : 1\"></th>\r\n <td class=\"p-0\" mat-cell *matCellDef=\"let item\" [attr.colspan]=\"!item?.sdGroup ? 1 : configuration.displayedColumns.length\">\r\n <div [innerHtml]=\"item?.sdGroup?.htmlTemplate | safeHtml\"></div>\r\n </td>\r\n <td mat-footer-cell *matFooterCellDef></td>\r\n </ng-container>\r\n <ng-container\r\n *ngFor=\"let column of configuration.firstColumns;\"\r\n [matColumnDef]=\"column.field\"\r\n [sticky]=\"configuration.fixedColumn[column.field]\">\r\n <th\r\n mat-header-cell\r\n *matHeaderCellDef\r\n class=\"px-8 py-8 c-th\"\r\n [ngStyle]=\"{ 'min-width': column.width }\"\r\n [attr.rowspan]=\"configuration.multipleHeader && column.type !== 'children-col' ? 2 : 1\"\r\n [attr.colspan]=\"column.type === 'children-col' ? column.children?.length : 1\">\r\n <div>\r\n <div\r\n aria-hidden=\"true\"\r\n mat-sort-header\r\n [disabled]=\"!column.sortable || column.type === 'children-col'\"\r\n [class.text-right]=\"column.align === 'right' || (!column.align && column.type === 'number')\"\r\n [class.text-center]=\"column.align === 'center'\"\r\n [innerHTML]=\"column.titleHtml || column.title\"></div>\r\n <sd-column-inline-filter\r\n *ngIf=\"!tableOption.filter?.disabled && !tableOption.filter?.hideInlineFilter && columnOperator\"\r\n [value]=\"columnFilter[column.field]\"\r\n [(inlineOperator)]=\"columnOperator[column.field]\"\r\n (operatorChange)=\"onOperatorChange(column, $event)\"\r\n [columnFilter]=\"columnFilter\"\r\n [cacheValues]=\"cacheValues\"\r\n [column]=\"column\"\r\n (filterChange)=\"onFilterChange()\">\r\n </sd-column-inline-filter>\r\n </div>\r\n </th>\r\n <td class=\"c-td px-0\" mat-cell *matCellDef=\"let item\">\r\n <sd-desktop-cell\r\n class=\"d-block px-8\"\r\n *ngIf=\"!item?.sdGroup\"\r\n [value]=\"item[column.field]\"\r\n [column]=\"column\"\r\n [item]=\"item\"\r\n [cellDef]=\"cellDef\">\r\n </sd-desktop-cell>\r\n </td>\r\n <td mat-footer-cell *matFooterCellDef>\r\n <ng-container *ngIf=\"footerDef[column.field]\">\r\n <ng-container *ngTemplateOutlet=\"footerDef[column.field].templateRef; context: { items: items, column: column }\">\r\n </ng-container>\r\n </ng-container>\r\n </td>\r\n </ng-container>\r\n <ng-container *ngFor=\"let column of configuration.secondColumns\" [matColumnDef]=\"column.field\">\r\n <th mat-header-cell *matHeaderCellDef mat-sort-header class=\"c-th px-8\" [ngStyle]=\"{ 'min-width': column.width }\">\r\n <div>\r\n <div\r\n [class.text-right]=\"column.align === 'right' || (!column.align && column.type === 'number')\"\r\n [class.text-center]=\"column.align === 'center'\"\r\n [innerHTML]=\"column.titleHtml || column.title\"></div>\r\n <sd-column-inline-filter\r\n *ngIf=\"!tableOption.filter?.disabled && !tableOption.filter?.hideInlineFilter && columnOperator\"\r\n [value]=\"columnFilter[column.field]\"\r\n [(inlineOperator)]=\"columnOperator[column.field]\"\r\n (operatorChange)=\"onOperatorChange(column, $event)\"\r\n [columnFilter]=\"columnFilter\"\r\n [cacheValues]=\"cacheValues\"\r\n [column]=\"column\"\r\n (filterChange)=\"onFilterChange()\">\r\n </sd-column-inline-filter>\r\n </div>\r\n </th>\r\n <td class=\"c-td px-0\" mat-cell *matCellDef=\"let item\">\r\n <sd-desktop-cell\r\n class=\"d-block px-8\"\r\n [value]=\"item[column.field]\"\r\n [column]=\"column\"\r\n [item]=\"item\"\r\n [cellDef]=\"cellDef\">\r\n </sd-desktop-cell>\r\n </td>\r\n <td mat-footer-cell *matFooterCellDef>\r\n <ng-container *ngIf=\"footerDef[column.field]\">\r\n <ng-container *ngTemplateOutlet=\"footerDef[column.field].templateRef; context: { items: items, column: column }\">\r\n </ng-container>\r\n </ng-container>\r\n </td>\r\n </ng-container>\r\n <tr class=\"c-first-header\" mat-header-row *matHeaderRowDef=\"configuration.firstHeaders; sticky: true\"></tr>\r\n <ng-container *ngIf=\"configuration.secondHeaders?.length\">\r\n <tr class=\"c-second-header\" mat-header-row *matHeaderRowDef=\"configuration.secondHeaders; sticky: true\"></tr>\r\n </ng-container>\r\n <tr\r\n mat-row\r\n *matRowDef=\"let row; columns: configuration.displayedColumns\"\r\n matRipple\r\n class=\"c-row\"\r\n [class.selected]=\"row.meta.selector.isSelected\"></tr>\r\n\r\n <tr mat-row *matRowDef=\"let row; columns: ['sdSubInformation']\" class=\"c-detail-row\"></tr>\r\n <ng-container *ngIf=\"hasFooter && configuration.displayedFooters?.length\">\r\n <tr mat-footer-row *matFooterRowDef=\"configuration.displayedFooters; sticky: true\"></tr>\r\n </ng-container>\r\n </table>\r\n </div>\r\n </ng-container>\r\n <div class=\"c-paginator\">\r\n <div class=\"c-action\">\r\n <sd-button\r\n *ngIf=\"tableOption.reload?.visible\"\r\n class=\"mr-8\"\r\n title=\"T\u1EA3i l\u1EA1i\"\r\n icon=\"refresh\"\r\n size=\"sm\"\r\n (action)=\"reload()\"\r\n [disabled]=\"!items?.length\"\r\n type=\"link\">\r\n </sd-button>\r\n <ng-container *ngIf=\"tableOption.export?.visible && items?.length\">\r\n <ng-container *ngIf=\"isExporting; else unExporting\">\r\n <sd-button class=\"mr-10\" [loading]=\"isExporting\" [title]=\"exportTitle | sdTranslate\" icon=\"get_app\" size=\"sm\" type=\"link\">\r\n </sd-button>\r\n </ng-container>\r\n <ng-template #unExporting>\r\n <sd-button class=\"mr-10\" [title]=\"exportTitle | sdTranslate\" icon=\"get_app\" size=\"sm\" [matMenuTriggerFor]=\"menu\" type=\"link\">\r\n </sd-button>\r\n </ng-template>\r\n <mat-menu #menu=\"matMenu\">\r\n <button mat-menu-item (click)=\"exportExcel()\" type=\"button\">\r\n <mat-icon fontSet=\"material-icons-outlined\">file_download</mat-icon>\r\n <span> Xu\u1EA5t excel</span>\r\n </button>\r\n <button mat-menu-item (click)=\"exportCSV()\" type=\"button\">\r\n <mat-icon fontSet=\"material-icons-outlined\">file_download</mat-icon>\r\n <span> Xu\u1EA5t CSV</span>\r\n </button>\r\n </mat-menu>\r\n </ng-container>\r\n <sd-button\r\n *ngIf=\"popupConfiguration\"\r\n class=\"mr-8\"\r\n [title]=\"'Configure' | sdTranslate\"\r\n icon=\"settings\"\r\n size=\"sm\"\r\n (action)=\"popupConfiguration.open()\"\r\n type=\"link\">\r\n </sd-button>\r\n </div>\r\n <mat-paginator\r\n [class.d-none]=\"tableOption.paginate?.hidden\"\r\n [length]=\"total\"\r\n [pageSize]=\"tableOption.paginate?.pageSize\"\r\n [pageSizeOptions]=\"tableOption.paginate?.pages\"\r\n [showFirstLastButtons]=\"tableOption.paginate?.showFirstLastButtons\"></mat-paginator>\r\n </div>\r\n </div>\r\n <sd-table-quick-action [tableOption]=\"tableOption\" [selectedTableItems]=\"selectedTableItems\" (clear)=\"onClearSelection(groupedItems)\">\r\n </sd-table-quick-action>\r\n <sd-popup-configuration *ngIf=\"tableOption?.key && tableOption.config?.visible\" [tableOption]=\"tableOption\"> </sd-popup-configuration>\r\n </ng-container>\r\n</ng-container>\r\n",
1740
+ template: "<ng-container *ngIf=\"configuration\">\r\n <sd-table-filter\r\n *ngIf=\"!tableOption.filter?.disabled && filterRegister\"\r\n [filterRegister]=\"filterRegister\"\r\n [filter]=\"tableOption?.filter\"\r\n [columns]=\"configuration.firstColumns\"\r\n [externalFilters]=\"tableOption?.filter?.externalFilters\"\r\n [filterDefs]=\"filterDefs\">\r\n </sd-table-filter>\r\n <ng-container *ngIf=\"items | sdGroup : tableOption; $implicit as groupedItems\">\r\n <div class=\"c-container\">\r\n <div class=\"c-loading\" *ngIf=\"isLoading\">\r\n <mat-spinner></mat-spinner>\r\n </div>\r\n <ng-container>\r\n <div\r\n class=\"c-table\"\r\n sdScroll\r\n [ngStyle]=\"{\r\n 'max-height': tableOption?.style?.maxHeight,\r\n 'min-height': tableOption?.style?.minHeight\r\n }\">\r\n <table mat-table [dataSource]=\"groupedItems\" [trackBy]=\"trackBy\" matSort [matSortDisabled]=\"!tableOption.sort?.enable\" multiTemplateDataRows>\r\n <ng-container matColumnDef=\"sdSubInformation\" sticky>\r\n <td class=\"p-0\" mat-cell *matCellDef=\"let item\" [attr.colspan]=\"configuration.displayedColumns.length\">\r\n <ng-container *ngIf=\"sdSubInformation?.templateRef\">\r\n <ng-container *ngIf=\"tableOption?.expand?.always; else useExpandCollapse\">\r\n <ng-container *ngTemplateOutlet=\"sdSubInformation.templateRef; context: { item: item }\"> </ng-container>\r\n </ng-container>\r\n <ng-template #useExpandCollapse>\r\n <div [@detailExpand]=\"item.isExpanded ? 'expanded' : 'collapsed'\">\r\n <ng-container *ngIf=\"item.isExpanded\">\r\n <ng-container *ngTemplateOutlet=\"sdSubInformation.templateRef; context: { item: item }\"> </ng-container>\r\n </ng-container>\r\n </div>\r\n </ng-template>\r\n </ng-container>\r\n </td>\r\n <td mat-footer-cell *matFooterCellDef></td>\r\n </ng-container>\r\n <ng-container matColumnDef=\"sdSubInformationAction\" stickyEnd>\r\n <th\r\n class=\"p-0\"\r\n mat-header-cell\r\n *matHeaderCellDef\r\n style=\"width: 1px\"\r\n [attr.rowspan]=\"configuration.multipleHeader ? 2 : 1\"></th>\r\n <td mat-cell *matCellDef=\"let element\">\r\n <button\r\n *ngIf=\"!element.isExpanding && !tableOption?.expand?.always\"\r\n mat-icon-button\r\n aria-label=\"Expand & Collapse\"\r\n (click)=\"onExpand(element)\">\r\n <mat-icon *ngIf=\"!element.isExpanded\">expand_more</mat-icon>\r\n <mat-icon *ngIf=\"element.isExpanded\">expand_less</mat-icon>\r\n </button>\r\n <div *ngIf=\"element.isExpanding\" class=\"lds-ring\">\r\n <div></div>\r\n <div></div>\r\n <div></div>\r\n <div></div>\r\n </div>\r\n </td>\r\n </ng-container>\r\n <ng-container matColumnDef=\"sdSelection\" sticky>\r\n <th\r\n class=\"text-center p-0\"\r\n mat-header-cell\r\n *matHeaderCellDef\r\n [attr.rowspan]=\"configuration.multipleHeader ? 2 : 1\">\r\n <ng-container *ngIf=\"items | selectionVisibleSelectAll : tableOption?.selector | async\">\r\n <mat-checkbox\r\n *ngIf=\"!tableOption.selector?.single\"\r\n class=\"c-selection px-15\"\r\n style=\"min-width: 50px; max-width: 50px\"\r\n color=\"primary\"\r\n [(ngModel)]=\"isSelectAll\"\r\n (change)=\"onSelectAll()\">\r\n </mat-checkbox>\r\n </ng-container>\r\n </th>\r\n <td class=\"text-center p-0\" mat-cell *matCellDef=\"let item\">\r\n <ng-container *ngIf=\"item | selectionVisible : tableOption?.selector\">\r\n <mat-checkbox\r\n class=\"c-selection px-15\"\r\n style=\"min-width: 50px; max-width: 50px\"\r\n color=\"primary\"\r\n [(ngModel)]=\"item.meta.selector.isSelected\"\r\n (change)=\"onSelect(item)\"\r\n [disabled]=\"selectedTableItems | selectionDisable : item : tableOption?.selector\">\r\n </mat-checkbox>\r\n </ng-container>\r\n </td>\r\n <td mat-footer-cell *matFooterCellDef></td>\r\n </ng-container>\r\n <ng-container matColumnDef=\"sdCommand\" sticky>\r\n <th\r\n class=\"p-0\"\r\n mat-header-cell\r\n *matHeaderCellDef\r\n style=\"width: 50px\"\r\n [attr.rowspan]=\"configuration.multipleHeader ? 2 : 1\"></th>\r\n <td class=\"px-8\" mat-cell *matCellDef=\"let item\">\r\n <sd-desktop-command [commands]=\"tableOption.commands\" [item]=\"item\"></sd-desktop-command>\r\n </td>\r\n <td mat-footer-cell *matFooterCellDef></td>\r\n </ng-container>\r\n <ng-container matColumnDef=\"sdGroup\">\r\n <th mat-header-cell *matHeaderCellDef class=\"px-8 py-8\" [attr.rowspan]=\"configuration.multipleHeader ? 2 : 1\"></th>\r\n <td class=\"p-0\" mat-cell *matCellDef=\"let item\" [attr.colspan]=\"!item?.sdGroup ? 1 : configuration.displayedColumns.length\">\r\n <div [innerHtml]=\"item?.sdGroup?.htmlTemplate | safeHtml\"></div>\r\n </td>\r\n <td mat-footer-cell *matFooterCellDef></td>\r\n </ng-container>\r\n <ng-container\r\n *ngFor=\"let column of configuration.firstColumns;\"\r\n [matColumnDef]=\"column.field\"\r\n [sticky]=\"configuration.fixedColumn[column.field]\">\r\n <th\r\n mat-header-cell\r\n *matHeaderCellDef\r\n class=\"px-8 py-8 c-th\"\r\n [ngStyle]=\"{ 'min-width': column.width }\"\r\n [attr.rowspan]=\"configuration.multipleHeader && column.type !== 'children-col' ? 2 : 1\"\r\n [attr.colspan]=\"column.type === 'children-col' ? column.children?.length : 1\">\r\n <div>\r\n <div\r\n aria-hidden=\"true\"\r\n mat-sort-header\r\n [disabled]=\"!column.sortable || column.type === 'children-col'\"\r\n [class.text-right]=\"column.align === 'right' || (!column.align && column.type === 'number')\"\r\n [class.text-center]=\"column.align === 'center'\"\r\n [innerHTML]=\"column.titleHtml || column.title\"></div>\r\n <sd-column-inline-filter\r\n *ngIf=\"!tableOption.filter?.disabled && !tableOption.filter?.hideInlineFilter && columnOperator\"\r\n [value]=\"columnFilter[column.field]\"\r\n [(inlineOperator)]=\"columnOperator[column.field]\"\r\n (operatorChange)=\"onOperatorChange(column, $event)\"\r\n [columnFilter]=\"columnFilter\"\r\n [cacheValues]=\"cacheValues\"\r\n [column]=\"column\"\r\n (filterChange)=\"onFilterChange()\">\r\n </sd-column-inline-filter>\r\n </div>\r\n </th>\r\n <td class=\"c-td px-0\" mat-cell *matCellDef=\"let item\">\r\n <sd-desktop-cell\r\n class=\"d-block px-8\"\r\n *ngIf=\"!item?.sdGroup\"\r\n [value]=\"item[column.field]\"\r\n [column]=\"column\"\r\n [item]=\"item\"\r\n [cellDef]=\"cellDef\">\r\n </sd-desktop-cell>\r\n </td>\r\n <td mat-footer-cell *matFooterCellDef>\r\n <ng-container *ngIf=\"footerDef[column.field]\">\r\n <ng-container *ngTemplateOutlet=\"footerDef[column.field].templateRef; context: { items: items, column: column }\">\r\n </ng-container>\r\n </ng-container>\r\n </td>\r\n </ng-container>\r\n <ng-container *ngFor=\"let column of configuration.secondColumns\" [matColumnDef]=\"column.field\">\r\n <th mat-header-cell *matHeaderCellDef mat-sort-header class=\"c-th px-8\" [ngStyle]=\"{ 'min-width': column.width }\">\r\n <div>\r\n <div\r\n [class.text-right]=\"column.align === 'right' || (!column.align && column.type === 'number')\"\r\n [class.text-center]=\"column.align === 'center'\"\r\n [innerHTML]=\"column.titleHtml || column.title\"></div>\r\n <sd-column-inline-filter\r\n *ngIf=\"!tableOption.filter?.disabled && !tableOption.filter?.hideInlineFilter && columnOperator\"\r\n [value]=\"columnFilter[column.field]\"\r\n [(inlineOperator)]=\"columnOperator[column.field]\"\r\n (operatorChange)=\"onOperatorChange(column, $event)\"\r\n [columnFilter]=\"columnFilter\"\r\n [cacheValues]=\"cacheValues\"\r\n [column]=\"column\"\r\n (filterChange)=\"onFilterChange()\">\r\n </sd-column-inline-filter>\r\n </div>\r\n </th>\r\n <td class=\"c-td px-0\" mat-cell *matCellDef=\"let item\">\r\n <sd-desktop-cell\r\n class=\"d-block px-8\"\r\n [value]=\"item[column.field]\"\r\n [column]=\"column\"\r\n [item]=\"item\"\r\n [cellDef]=\"cellDef\">\r\n </sd-desktop-cell>\r\n </td>\r\n <td mat-footer-cell *matFooterCellDef>\r\n <ng-container *ngIf=\"footerDef[column.field]\">\r\n <ng-container *ngTemplateOutlet=\"footerDef[column.field].templateRef; context: { items: items, column: column }\">\r\n </ng-container>\r\n </ng-container>\r\n </td>\r\n </ng-container>\r\n <tr class=\"c-first-header\" mat-header-row *matHeaderRowDef=\"configuration.firstHeaders; sticky: true\"></tr>\r\n <ng-container *ngIf=\"configuration.secondHeaders?.length\">\r\n <tr class=\"c-second-header\" mat-header-row *matHeaderRowDef=\"configuration.secondHeaders; sticky: true\"></tr>\r\n </ng-container>\r\n <tr\r\n mat-row\r\n *matRowDef=\"let row; columns: configuration.displayedColumns\"\r\n matRipple\r\n class=\"c-row\"\r\n [class.selected]=\"row.meta.selector.isSelected\"></tr>\r\n\r\n <tr mat-row *matRowDef=\"let row; columns: ['sdSubInformation']\" class=\"c-detail-row\"></tr>\r\n <ng-container *ngIf=\"hasFooter && configuration.displayedFooters?.length\">\r\n <tr mat-footer-row *matFooterRowDef=\"configuration.displayedFooters; sticky: true\"></tr>\r\n </ng-container>\r\n </table>\r\n </div>\r\n </ng-container>\r\n <div class=\"c-paginator\">\r\n <div class=\"c-action\">\r\n <sd-button\r\n *ngIf=\"tableOption.reload?.visible\"\r\n class=\"mr-8\"\r\n title=\"T\u1EA3i l\u1EA1i\"\r\n icon=\"refresh\"\r\n size=\"sm\"\r\n (action)=\"reload()\"\r\n [disabled]=\"!items?.length\"\r\n type=\"link\">\r\n </sd-button>\r\n <ng-container *ngIf=\"tableOption.export?.visible && items?.length\">\r\n <ng-container *ngIf=\"isExporting; else unExporting\">\r\n <sd-button class=\"mr-10\" [loading]=\"isExporting\" [title]=\"exportTitle | sdTranslate\" icon=\"get_app\" size=\"sm\" type=\"link\">\r\n </sd-button>\r\n </ng-container>\r\n <ng-template #unExporting>\r\n <sd-button class=\"mr-10\" [title]=\"exportTitle | sdTranslate\" icon=\"get_app\" size=\"sm\" [matMenuTriggerFor]=\"menu\" type=\"link\">\r\n </sd-button>\r\n </ng-template>\r\n <mat-menu #menu=\"matMenu\">\r\n <button mat-menu-item (click)=\"exportExcel()\" type=\"button\">\r\n <mat-icon fontSet=\"material-icons-outlined\">file_download</mat-icon>\r\n <span> Xu\u1EA5t excel</span>\r\n </button>\r\n <button mat-menu-item (click)=\"exportCSV()\" type=\"button\">\r\n <mat-icon fontSet=\"material-icons-outlined\">file_download</mat-icon>\r\n <span> Xu\u1EA5t CSV</span>\r\n </button>\r\n </mat-menu>\r\n </ng-container>\r\n <sd-button\r\n *ngIf=\"popupConfiguration\"\r\n class=\"mr-8\"\r\n [title]=\"'Configure' | sdTranslate\"\r\n icon=\"settings\"\r\n size=\"sm\"\r\n (action)=\"popupConfiguration.open()\"\r\n type=\"link\">\r\n </sd-button>\r\n </div>\r\n <mat-paginator\r\n [class.d-none]=\"tableOption.paginate?.hidden\"\r\n [length]=\"total\"\r\n [pageSize]=\"tableOption.paginate?.pageSize\"\r\n [pageSizeOptions]=\"tableOption.paginate?.pages\"\r\n [showFirstLastButtons]=\"tableOption.paginate?.showFirstLastButtons\"></mat-paginator>\r\n </div>\r\n </div>\r\n <sd-table-quick-action [tableOption]=\"tableOption\" [selectedTableItems]=\"selectedTableItems\" (clear)=\"onClearSelection(groupedItems)\">\r\n </sd-table-quick-action>\r\n <sd-popup-configuration *ngIf=\"tableOption?.key && tableOption.config?.visible\" [tableOption]=\"tableOption\"> </sd-popup-configuration>\r\n </ng-container>\r\n</ng-container>\r\n",
1737
1741
  changeDetection: ChangeDetectionStrategy.OnPush,
1738
1742
  animations: [
1739
1743
  trigger('detailExpand', [
@@ -1755,6 +1759,7 @@ SdTable.ctorParameters = () => [
1755
1759
  { type: SdTableFilterService }
1756
1760
  ];
1757
1761
  SdTable.propDecorators = {
1762
+ table: [{ type: ViewChild, args: [MatTable,] }],
1758
1763
  popupConfiguration: [{ type: ViewChild, args: [SdPopupConfiguration,] }],
1759
1764
  sdScroll: [{ type: ViewChild, args: [SdScrollDirective,] }],
1760
1765
  quickAction: [{ type: ViewChild, args: [SdQuickAction,] }],