tnx-shared 5.3.364 → 5.3.366

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.
@@ -14849,7 +14849,7 @@ class CrudFormComponent extends ComponentBase {
14849
14849
  CrudFormComponent.decorators = [
14850
14850
  { type: Component, args: [{
14851
14851
  selector: 'crud-form',
14852
- template: "<div [class]=\"_styleClass\">\n <form #formElement autocomplete=\"off\" autocorrect=\"off\" spellcheck=\"false\"\n [class]=\"'p-grid form-group crud-form' + (formClass ? ' ' + formClass : '')\"\n (keydown.shift.tab)=\"preventBlur($event)\">\n <div class=\"p-grid p-col-12\" [class.grid]=\"useGridTemplate\" style=\"margin: 0\">\n <ng-container *ngFor=\"let control of setting.schema\">\n <ng-container *ngTemplateOutlet=\"customControl; context: {\n control: control, data: _modelData, parentPath: '', path: control.field, showLabel: control.showLabel,\n mdWidth: control.mdWidth, rowSpan: control.rowSpan\n }\">\n </ng-container>\n </ng-container>\n </div>\n </form>\n</div>\n<p-contextMenu #contextMenu [appendTo]=\"'body'\" [model]=\"buttonContexts\">\n</p-contextMenu>\n<ng-template #customControl let-data=\"data\" let-control=\"control\" let-showLabel=\"showLabel\" let-mdWidth=\"mdWidth\"\n let-rowSpan=\"rowSpan\" let-rowIndex=\"index\" let-path=\"path\" let-parentPath=\"parentPath\" let-tablePath=\"tablePath\">\n <div *ngIf=\"!checkHidden(control, data, path)\" id=\"{{path}}-holder\"\n class=\"p-col-{{control.gWidth}} p-md-{{mdWidth}} row-span-{{rowSpan}} {{control.class}} crud-form-control type-{{control.dataType}}\"\n [class.error]=\"data._errors[control.field].length > 0\"\n [class.not-show-in-box-holder]=\"control.showInBox === false\"\n [class.show-in-box-holder]=\"control.showInBox === true\" [ngStyle]=\"control.style\">\n <div class=\"label\" *ngIf=\"showLabel\">\n <label *ngIf=\"control.label && !control.isHtmlLabel\" [pTooltip]=\"control.fullLabel\"\n tooltipPosition=\"top\">{{control.label}}\n <span *ngIf=\"control.required || control.showIconRequired\" class=\"star-required\">*</span>\n </label>\n <ng-container *ngIf=\"control.label && control.isHtmlLabel\">\n <label [innerHTML]=\"control.label | safeHtml\" [pTooltip]=\"control.fullLabel\" tooltipPosition=\"top\">\n </label>\n <span *ngIf=\"control.required || control.showIconRequired\" class=\"star-required\">*</span>\n </ng-container>\n <span *ngIf=\"control.description\" class=\"control-description\">({{control.description}})</span>\n </div>\n <ng-container [ngSwitch]=\"control.controlType\">\n <ng-container *ngSwitchCase=\"'label'\">\n <ng-container [ngTemplateOutlet]=\"labelControl\"\n [ngTemplateOutletContext]=\"{control: control, data: data}\">\n </ng-container>\n </ng-container>\n <ng-container *ngSwitchCase=\"'title'\">\n <label *ngIf=\"!control.isHtml\" [for]=\"control.for\">{{control.text | translate}}</label>\n <label *ngIf=\"control.isHtml\" [innerHTML]=\"control.text | safeHtml\"></label>\n </ng-container>\n <ng-container *ngSwitchCase=\"'text'\">\n <div class=\"p-inputgroup\" *ngIf=\"control.suffFix\">\n <input [placeholder]=\"control.placeholder\" [tooltipDisabled]=\"control.dataFormat == 'password'\"\n [required]=\"control.validators && control.validators.required\" [pTooltip]=\"data[control.field]\"\n tooltipPosition=\"top\" tooltipStyleClass=\"wrap\"\n [attr.disabled]=\" checkDisabled(data, control) ? true : null\" pInputText\n [type]=\"control.dataFormat\" [max]=\"control.max\" [min]=\"control.min\"\n [maxlength]=\"control.maxLength\" [(ngModel)]=\"data[control.field]\"\n (change)=\"handleFieldValueChange(control, $event, eventType.CHANGE, data, parentPath)\"\n (key.enter)=\"handleFieldValueChange(control, $event, eventType.ENTER, data, parentPath)\" />\n <span class=\"p-inputgroup-addon\">({{control.suffFix}})</span>\n </div>\n <input *ngIf=\"!control.suffFix\" [placeholder]=\"control.placeholder\"\n [tooltipDisabled]=\"control.dataFormat == 'password'\" [pTooltip]=\"data[control.field]\"\n tooltipPosition=\"top\" tooltipStyleClass=\"wrap\"\n [attr.disabled]=\"checkDisabled(data, control) ? true : null\" pInputText [type]=\"control.dataFormat\"\n [max]=\"control.max\" [min]=\"control.min\" [maxlength]=\"control.maxLength\"\n [(ngModel)]=\"data[control.field]\"\n (change)=\"handleFieldValueChange(control, $event, eventType.CHANGE, data, parentPath)\"\n (key.enter)=\"handleFieldValueChange(control, $event, eventType.ENTER, data, parentPath)\" />\n </ng-container>\n <ng-container *ngSwitchCase=\"'htmlPreview'\">\n <html-preview [control]=\"control\" [(ngModel)]=\"data[control.field]\"\n (onChanged)=\"handleFieldValueChange(control, $event, eventType.CHANGE, data, parentPath)\">\n </html-preview>\n </ng-container>\n <ng-container *ngSwitchCase=\"'reference-text'\">\n <reference-textbox [control]=\"control\" [value]=\"data[control.field]\" [dataSource]=\"control.dataSource\"\n (onInit)=\"handleLoadedControl($event, control, parentPath)\"></reference-textbox>\n </ng-container>\n <ng-container *ngSwitchCase=\"'template'\">\n <ng-container [ngTemplateOutlet]=\"control.template\"\n [ngTemplateOutletContext]=\"{$implicit: _rootNode, control: control, data: data, tablePath: tablePath, parentPath: parentPath, rowIndex: rowIndex, funcUpdateModel: updateModelFromExternal}\">\n </ng-container>\n </ng-container>\n <ng-container *ngSwitchCase=\"'content'\">\n <div class=\"control-content label\">\n <span [innerHTML]=\"data[control.field] ? (data[control.field] | safeHtml) : ''\">\n </span>\n </div>\n </ng-container>\n <ng-container *ngSwitchCase=\"'mask'\">\n <tn-mask [prefix]=\"control.prefix\" [decimalPlaces]=\"control.decimalPlaces\" [suffix]=\"control.suffix\"\n [placeholder]=\"control.placeholder\" [disabled]=\"checkDisabled(data, control)\" tooltipPosition=\"top\"\n [tooltipDisabled]=\"control.dataFormat == 'password'\" [pTooltip]=\"data[control.field]\"\n [maskType]=\"control.maskType\" [autoFormat]=\"control.autoFormat\" [min]=\"control.min\"\n [max]=\"control.max\" [(ngModel)]=\"data[control.field]\"\n (onInit)=\"handleLoadedControl($event, control, parentPath)\"\n (onChanged)=\"handleFieldValueChange(control, $event, eventType.CHANGE, data, parentPath)\">\n </tn-mask>\n </ng-container>\n <ng-container *ngSwitchCase=\"'numberrange'\">\n <tn-number-picker-range [decimalPlaces]=\"control.decimalPlaces\"\n [disabled]=\"checkDisabled(data, control)\" [maskType]=\"control.maskType\" [min]=\"control.min\"\n [max]=\"control.max\" [placeholder]=\"control.placeholder\" [(ngModel)]=\"data[control.field]\"\n (onInit)=\"handleLoadedControl($event, control, parentPath)\"\n (change)=\"handleFieldValueChange(control, $event, eventType.CHANGE, data, parentPath)\"\n (blur)=\"handleFieldValueChange(control, $event, eventType.BLUR, data, parentPath)\">\n </tn-number-picker-range>\n </ng-container>\n <ng-container *ngSwitchCase=\"'money'\">\n <input currencyMask [attr.disabled]=\"checkDisabled(data, control) ? true : null\" pInputText type=\"tel\"\n tooltipPosition=\"top\" [pTooltip]=\"data[control.field] | number: '1.0-0'\"\n [options]=\"{prefix: '', thousands: '.', decimal: ',',precision:control.dataFormat === 'money'?0:0 }\"\n [(ngModel)]=\"data[control.field]\"\n (ngModelChange)=\"handleFieldValueChange(control, $event, eventType.CHANGE, data, parentPath)\" />\n </ng-container>\n <ng-container *ngSwitchCase=\"'phoneOrfax'\">\n <input [placeholder]=\"control.dataFormat==='phone'?'(999) 999-9999':'999-999-9999'\"\n [attr.disabled]=\"checkDisabled(data, control) ? true : null\" type=\"tel\" pInputText\n [(ngModel)]=\"data[control.field]\"\n (change)=\"handleFieldValueChange(control, $event, eventType.CHANGE, data, parentPath)\" />\n </ng-container>\n <ng-container *ngSwitchCase=\"'textarea'\">\n <textarea pInputTextarea [rows]=\"control.rows ? control.rows : 5\"\n [attr.disabled]=\"checkDisabled(data, control) ? true : null\" [(ngModel)]=\"data[control.field]\"\n [placeholder]=\"control.placeholder\"\n (keyup)=\"handleKeyUp(control, $event, eventType.CHANGE, data, parentPath)\"\n (change)=\"handleFieldValueChange(control, $event, eventType.CHANGE, data, parentPath)\"></textarea>\n </ng-container>\n <ng-container *ngSwitchCase=\"'editor'\">\n <tn-tinymce *ngIf=\"!checkDisabled(data, control)\"\n [required]=\"control.validators && control.validators.required\" [mode]=\"control.mode\"\n [height]=\"control.height ? control.height : 250\" [languageCode]=\"control.languageCode\"\n [control]=\"control\"\n [disabled]=\"control.disabled || (control.disableCheck && control.disableCheck(model))\"\n [(ngModel)]=\"data[control.field]\" (onInit)=\"handleLoadedControl($event, control, parentPath)\"\n (onKeyUp)=\"handleKeyUp(control, $event, eventType.CHANGE, data, parentPath)\"\n (onChanged)=\"handleFieldValueChange(control, $event, eventType.CHANGE, data, parentPath)\">\n </tn-tinymce>\n <div *ngIf=\"checkDisabled(data, control)\" class=\"html-box\"\n [innerHTML]=\"data[control.field] ? (data[control.field] | safeHtml) : ''\">\n </div>\n </ng-container>\n <ng-container *ngSwitchCase=\"'datetime'\">\n <datetime-picker [disabled]=\"checkDisabled(data, control)\" [control]=\"control\"\n [(ngModel)]=\"data[control.field]\" (onInit)=\"handleLoadedControl($event, control, parentPath)\"\n (onChanged)=\"handleFieldValueChange(control, $event, eventType.CHANGE, data, parentPath)\">\n </datetime-picker>\n </ng-container>\n <ng-container *ngSwitchCase=\"'autocomplete'\">\n <app-autocomplete-datasource [control]=\"control\"\n [suggestions]=\"data._source[control.field] || control.dataSource\" [(ngModel)]=\"data[control.field]\"\n (onInit)=\"handleLoadedControl($event, control, parentPath)\"\n (onValueChanged)=\"handleFieldValueChange(control, $event, eventType.CHANGE, data, parentPath)\">\n </app-autocomplete-datasource>\n </ng-container>\n <ng-container *ngSwitchCase=\"'datetimerange'\">\n <tn-datetime-picker-range [disabled]=\"control.disabled\" [control]=\"control\"\n [(ngModel)]=\"data[control.field]\" (onInit)=\"handleLoadedControl($event, control, parentPath)\"\n (onChanged)=\"handleFieldValueChange(control, $event, eventType.CHANGE, data, parentPath)\">\n </tn-datetime-picker-range>\n </ng-container>\n <ng-container *ngSwitchCase=\"'dropdown'\">\n <dropdown [control]=\"control\" [dataSource]=\"getControlDataSource(control, data)\" [data]=\"data\"\n [(value)]=\"data[control.field]\" (onInit)=\"handleLoadedControl($event, control, parentPath)\"\n (onChanged)=\"handleChangeDropdown(control, $event, eventType.CHANGE, data, parentPath)\"\n (onHideSmartEvent)=\"handleChangeDropdown(control, $event, eventType.HIDE, data, parentPath)\"\n (adjustValue)=\"handleAdjustValueDropdownEvent(control, parentPath)\"\n (onDataSourceLoaded)=\"handleDataSourceLoaded(control, parentPath, $event)\"\n (onReady)=\"handleControlReadyEvent(control, parentPath)\">\n </dropdown>\n </ng-container>\n <ng-container *ngSwitchCase=\"'imageuploader'\">\n <app-image-uploader [loadByEntityKey]=\"control.loadByEntityKey\" [entityKey]=\"control.entityKey\"\n [defaultNoImageUrl]=\"'/assets/images/no-image.jpg'\" [multiple]=\"control.multiple\"\n [disabled]=\"control.disabled\" [isAvatar]=\"control.isAvatar\" [(ngModel)]=\"data[control.field]\"\n (onChanged)=\"handleFieldValueChange(control, $event, eventType.CHANGE, data, parentPath)\"\n (onInit)=\"handleLoadedControl($event, control, parentPath)\">\n <ng-template *ngIf=\"control.templateItems\" #items let-files>\n <ng-container *ngTemplateOutlet=\"control.templateItems; context: {\n $implicit: files\n }\"></ng-container>\n </ng-template>\n <ng-template *ngIf=\"control.templateItem\" #item let-file>\n <ng-container *ngTemplateOutlet=\"control.templateItem; context: {\n $implicit: file\n }\"></ng-container>\n </ng-template>\n </app-image-uploader>\n </ng-container>\n <ng-container *ngSwitchCase=\"'fileManager'\">\n <file-manager *ngIf=\"control.entityKey || data[control.entityKeyField] || control.rootFolderId\"\n [control]=\"control\" [serviceCode]=\"control.serviceCode\" [entity]=\"control.entity\"\n [hiddenCreateFolder]=\"control.hiddenCreateFolder\"\n [entityKey]=\"control.entityKey ? control.entityKey : data[control.entityKeyField]\"\n [readonly]=\"control.disabled\" [layout]=\"control.layout\" [rootFolderId]=\"control.rootFolderId\"\n [maxFileSize]=\"control.maxFileSize\" [inTaiLieu]=\"control.inTaiLieu\"\n [inTaiLieuChung]=\"control.inTaiLieuChung\" [copyToFolderId]=\"control.copyToFolderId\"\n [filePickerSetting]=\"control.filePickerSetting\" [dataForm]=\"data\"\n [invalidFileSizeMessageSummary]=\"control.invalidFileSizeMessageSummary\"\n [invalidFileSizeMessageDetail]=\"control.invalidFileSizeMessageDetail\"\n [invalidFileTypeMessageSummary]=\"control.invalidFileTypeMessageSummary\"\n [invalidFileTypeMessageDetail]=\"control.invalidFileTypeMessageDetail\"\n [invalidFileLimitMessageSummary]=\"control.invalidFileLimitMessageSummary\"\n [invalidFileLimitMessageDetail]=\"control.invalidFileLimitMessageDetail\" [parentSetting]=\"setting\"\n [noFileMessage]=\"control.noFileMessage\" [(value)]=\"data[control.field]\"\n (onInit)=\"handleLoadedControl($event, control, parentPath)\"\n (onSelected)=\"control.onSelected($event)\"\n (onChanged)=\"handleFieldValueChange(control, $event, eventType.CHANGE, data, parentPath)\"\n (onReady)=\"handleControlReadyEvent(control, parentPath)\">\n </file-manager>\n </ng-container>\n <span *ngSwitchCase=\"'fileUpload'\">\n <file-upload [sharedFolderType]=\"control.sharedFolderType\" [maxFileSize]=\"control.maxFileSize\"\n [invalidFileSizeMessageSummary]=\"control.invalidFileSizeMessageSummary\"\n [invalidFileSizeMessageDetail]=\"control.invalidFileSizeMessageDetail\"\n [invalidFileTypeMessageSummary]=\"control.invalidFileTypeMessageSummary\"\n [invalidFileTypeMessageDetail]=\"control.invalidFileTypeMessageDetail\"\n [invalidFileLimitMessageSummary]=\"control.invalidFileLimitMessageSummary\"\n [invalidFileLimitMessageDetail]=\"control.invalidFileLimitMessageDetail\" [control]=\"control\"\n [showDeleteFile]=\"control.showDeleteFile\" [readonly]=\"control.readonly\" [accept]=\"control.accept\"\n [(ngModel)]=\"data[control.field]\" (onInit)=\"handleLoadedControl($event, control, parentPath)\"\n (onChanged)=\"handleFieldValueChange(control, $event, eventType.CHANGE, data, parentPath)\"\n (onRemove)=\"handleFieldValueChange(control, $event, eventType.DELETED, data, parentPath)\">\n </file-upload>\n </span>\n <span *ngSwitchCase=\"'serviceFileUpload'\">\n <service-file-upload *ngIf=\"control.entityKey || data[control.entityKeyField] || control.rootFolderId\"\n [parentContext]=\"context\" [serviceCode]=\"control.serviceCode\" [entity]=\"control.entity\"\n [entityKey]=\"control.entityKey ? control.entityKey : data[control.entityKeyField]\"\n [control]=\"control\" [(ngModel)]=\"data[control.field]\"\n (onInit)=\"handleLoadedControl($event, control, parentPath)\"\n (onChanged)=\"handleFieldValueChange(control, $event, eventType.CHANGE, data, parentPath)\"\n (onRemove)=\"handleFieldValueChange(control, $event, eventType.DELETED, data, parentPath)\">\n </service-file-upload>\n </span>\n <ng-container *ngSwitchCase=\"'user-picker'\">\n <user-picker [control]=\"control\" [disabled]=\"checkDisabled(data, control)\"\n [readOnlyValues]=\"data[control.field + '_readOnly']\" [multiple]=\"control.multiple\"\n [(ngModel)]=\"data[control.field]\" (onInit)=\"handleLoadedControl($event, control, parentPath)\"\n (onChanged)=\"handleFieldValueChange(control, $event, eventType.CHANGE, data, parentPath)\"\n (onReady)=\"handleReadyControlPicker(control, parentPath)\">\n </user-picker>\n </ng-container>\n <ng-container *ngSwitchCase=\"'switch'\">\n <p-inputSwitch [disabled]=\"checkDisabled(data, control)\" [(ngModel)]=\"data[control.field]\"\n (onChange)=\"handleFieldValueChange(control, $event, eventType.CHANGE, data, parentPath)\">\n </p-inputSwitch>\n </ng-container>\n <ng-container *ngSwitchCase=\"'checkbox'\">\n <div [class]=\"control.class\" role=\"checkbox-alone\">\n <p-checkbox [disabled]=\"checkDisabled(data, control)\" [binary]=\"true\"\n [label]=\"control.isCustomLabel ? control.displayLabel : (!control.hiddenLabel ? control.label : null)\"\n [(ngModel)]=\"data[control.field]\"\n (onChange)=\"handleFieldValueChange(control, $event, eventType.CHANGE, data, parentPath)\">\n </p-checkbox>\n <!-- <tn-checkbox [control]=\"control\" [disabled]=\"checkDisabled(data, control)\"\n [(ngModel)]=\"data[control.field]\"\n (onChange)=\"handleFieldValueChange(control, $event, eventType.CHANGE, data, parentPath)\"></tn-checkbox> -->\n </div>\n </ng-container>\n <ng-container *ngSwitchCase=\"'button'\">\n <button type=\"button\" pButton [class]=\"control.btClass\" [icon]=\"control.icon\"\n [label]=\"control.buttonText | translate\" [ngStyle]=\"control.btStyle\" [pTooltip]=\"control.fullLabel\"\n tooltipPosition=\"top\" (click)=\"handleButtonClick(control, $event, parentPath)\"></button>\n </ng-container>\n <ng-container *ngSwitchCase=\"'container'\">\n <div class=\"p-grid p-col-12\" style=\"margin: 0\" [class.not-show-in-box]=\"!control.showInBox\"\n [class.show-in-box]=\"control.showInBox\" [ngStyle]=\"control.boxStyle\">\n <ng-container *ngFor=\"let subControl of control.controls\">\n <ng-container *ngTemplateOutlet=\"customControl; context: {\n control: subControl,\n data: data[control.field],\n parentPath: path,\n rowIndex: rowIndex,\n path: path + '.' + subControl.field,\n showLabel: subControl.showLabel,\n mdWidth: subControl.mdWidth,\n rowSpan: subControl.rowSpan\n }\">\n </ng-container>\n </ng-container>\n </div>\n </ng-container>\n <ng-container *ngSwitchCase=\"'checkboxlist'\">\n <check-box-list [control]=\"control\" [dataSource]=\"data._source[control.field] || control.dataSource\"\n [disabled]=\"checkDisabled(data, control)\" [(ngModel)]=\"data[control.field]\"\n (onInit)=\"handleLoadedControl($event, control, parentPath)\"\n (onSelect)=\"handleFieldValueChange(control, $event, eventType.CHANGE, data, parentPath)\"\n (onReady)=\"handleControlReadyEvent(control, parentPath)\">\n </check-box-list>\n </ng-container>\n <ng-container *ngSwitchCase=\"'radiobuttonlist'\">\n <radio-button-list [control]=\"control\" [dataSource]=\"control.dataSource\"\n [disabled]=\"checkDisabled(data, control)\" [(value)]=\"data[control.field]\"\n (onInit)=\"handleLoadedControl($event, control, parentPath)\"\n (onChanged)=\"handleFieldValueChange(control, $event, eventType.CHANGE, data, parentPath)\"\n (adjustValue)=\"handleAdjustValueDropdownEvent(control, parentPath)\"\n (onReady)=\"handleReadyControlPicker(control, parentPath)\"\n (onDataSourceLoaded)=\"handleDataSourceLoaded(control, parentPath, $event)\">\n </radio-button-list>\n </ng-container>\n <ng-container *ngSwitchCase=\"'colorPicker'\">\n <tn-color-picker [disabled]=\"checkDisabled(data, control)\" [(ngModel)]=\"data[control.field]\"\n (onInit)=\"handleLoadedControl($event, control, parentPath)\"\n (change)=\"handleFieldValueChange(control, $event, eventType.CHANGE, data, parentPath)\">\n </tn-color-picker>\n </ng-container>\n <ng-container *ngSwitchCase=\"'spanControl'\">\n <span *ngIf=\"!control.ishtml\">{{data[control.field]}}</span>\n <span *ngIf=\"control.ishtml\" [innerHTML]=\"data[control.field]\"></span>\n </ng-container>\n <ng-container *ngSwitchCase=\"'colorControl'\">\n <span class=\"show-color-control\" [ngStyle]=\"{ backgroundColor: data[control.sourceField]}\"></span>\n </ng-container>\n <ng-container *ngSwitchCase=\"'address'\">\n <address-picker [control]=\"control\" [showSubLabel]=\"control.showSubLabel\"\n [disabled]=\"checkDisabled(data, control)\" [(data)]=\"data[control.field]\"\n (onInit)=\"handleLoadedControl($event, control, parentPath)\"\n (onSelect)=\"handleFieldValueChange(control, $event, eventType.CHANGE, data, parentPath)\"\n (onReady)=\"handleControlReadyEvent(control, parentPath)\">\n </address-picker>\n </ng-container>\n <ng-container *ngSwitchCase=\"'autocomplete-picker'\">\n <autocomplete-picker [control]=\"control\" [disabled]=\"checkDisabled(data, control)\"\n [required]=\"control.required\" [readOnlyValues]=\"data[control.field + '_readOnly']\"\n [(ngModel)]=\"data[control.field]\" (onInit)=\"handleLoadedControl($event, control, parentPath)\"\n (onChanged)=\"handleFieldValueChange(control, $event, eventType.CHANGE, data, parentPath)\"\n (onReady)=\"handleReadyControlPicker(control, parentPath)\">\n </autocomplete-picker>\n </ng-container>\n <ng-container *ngSwitchCase=\"'cocautochuc'\">\n <cocautochuc-picker [control]=\"control\" [parentOrgId]=\"control.parentOrgId\"\n [disabled]=\"checkDisabled(data, control)\" [parentOrgCode]=\"control.parentOrgCode\"\n [filter]=\"control.filter\" [multiple]=\"control.multiple\" [required]=\"control.required\"\n [isUsingId]=\"control.isUsingId\" [disabledParentItem]=\"control.disabledParentItem\"\n [rootParentId]=\"control.rootParentId\" [(ngModel)]=\"data[control.field]\"\n (onInit)=\"handleLoadedControl($event, control, parentPath)\"\n (onChanged)=\"handleFieldValueChange(control, $event, eventType.CHANGE, data, parentPath)\">\n </cocautochuc-picker>\n </ng-container>\n <ng-container *ngSwitchCase=\"'cocautochuc-picker'\">\n <cocautochuc-picker-list [control]=\"control\" [disabled]=\"checkDisabled(data, control)\"\n [required]=\"control.required\" [readOnlyValues]=\"data[control.field + '_readOnly']\"\n [(ngModel)]=\"data[control.field]\" (onInit)=\"handleLoadedControl($event, control, parentPath)\"\n (onChanged)=\"handleFieldValueChange(control, $event, eventType.CHANGE, data, parentPath)\"\n (onReady)=\"handleReadyControlPicker(control, parentPath)\">\n </cocautochuc-picker-list>\n </ng-container>\n <ng-container *ngSwitchCase=\"'cocautochuc-picker-new'\">\n <cocautochuc-picker-list-new [control]=\"control\" [disabled]=\"checkDisabled(data, control)\"\n [required]=\"control.required\" [readOnlyValues]=\"data[control.field + '_readOnly']\"\n [(ngModel)]=\"data[control.field]\" (onInit)=\"handleLoadedControl($event, control, parentPath)\"\n (onChanged)=\"handleFieldValueChange(control, $event, eventType.CHANGE, data, parentPath)\"\n (onReady)=\"handleReadyControlPicker(control, parentPath)\">\n </cocautochuc-picker-list-new>\n </ng-container>\n <ng-container *ngSwitchCase=\"'vanban'\">\n <vanban-picker [control]=\"control\" [disabled]=\"checkDisabled(data, control)\"\n [required]=\"control.required\" [readOnly]=\"control.readOnly\" [loaiVanBan]=\"control.loaiVanBan\"\n [(ngModel)]=\"data[control.field]\" (onInit)=\"handleLoadedControl($event, control, parentPath)\"\n (onChanged)=\"handleFieldValueChange(control, $event, eventType.CHANGE, data, parentPath)\">\n </vanban-picker>\n </ng-container>\n <ng-container *ngSwitchCase=\"'congviec'\">\n <div>\n <congviec-picker [control]=\"control\" [disabled]=\"checkDisabled(data, control)\"\n [required]=\"control.required\" [(ngModel)]=\"data[control.field]\"\n (onInit)=\"handleLoadedControl($event, control, parentPath)\"\n (onChanged)=\"handleFieldValueChange(control, $event, eventType.CHANGE, data, parentPath)\">\n </congviec-picker>\n </div>\n </ng-container>\n <ng-container *ngSwitchCase=\"'percent'\">\n <div>\n <tn-mask [suffix]=\"'%'\" [placeholder]=\"control.placeholder\" [maskType]=\"'int'\"\n [autoFormat]=\"control.autoFormat\" [min]=\"0\" [max]=\"100\"\n [disabled]=\"checkDisabled(data, control)\" [(ngModel)]=\"data[control.field]\"\n (onInit)=\"handleLoadedControl($event, control, parentPath)\"\n (onChanged)=\"handleFieldValueChange(control, $event, eventType.CHANGE, data, parentPath)\">\n </tn-mask>\n <p-slider [step]=\"1\" [min]=\"0\" [max]=\"100\" [disabled]=\"checkDisabled(data, control)\"\n [(ngModel)]=\"data[control.field]\"\n (onSlideEnd)=\"handleFieldValueChange(control, $event, eventType.CHANGE, data, parentPath)\">\n </p-slider>\n </div>\n </ng-container>\n <ng-container *ngSwitchCase=\"'chips'\">\n <p-chips [disabled]=\"checkDisabled(data, control)\" [(ngModel)]=\"data[control.field]\"\n [placeholder]=\"control.placeholder\"\n (onAdd)=\"handleFieldValueChange(control, $event, eventType.CHANGE, data, parentPath)\"\n (onRemove)=\"handleFieldValueChange(control, $event, eventType.CHANGE, data, parentPath)\"></p-chips>\n </ng-container>\n <ng-container *ngSwitchCase=\"'entity-picker'\">\n <entity-picker [control]=\"control\" [children]=\"children\" [disabled]=\"checkDisabled(data, control)\"\n [required]=\"control.required\" [readOnly]=\"control.readOnly\" [(ngModel)]=\"data[control.field]\"\n (onInit)=\"handleLoadedControl($event, control, parentPath)\"\n (onChanged)=\"handleFieldValueChange(control, $event, eventType.CHANGE, data, parentPath)\">\n </entity-picker>\n </ng-container>\n <ng-container *ngSwitchCase=\"'table'\">\n <div [class]=\"control.class\">\n <tn-custom-scrollbar class=\"--has-border\" [showScrollHorizontal]=\"true\">\n <p-table class=\"new-table scr-table table-control\" [value]=\"data[control.field]\"\n [columns]=\"control.headerTemplate\" [responsive]=\"true\" [scrollable]=\"false\"\n [rowTrackBy]=\"trackByFuncId\"\n (onRowReorder)=\"handleRowOrdered(control, $event, eventType.ROW_REORDER, data, parentPath)\">\n <ng-template pTemplate=\"colgroup\">\n <colgroup>\n <col *ngIf=\"control.showNumber\" style=\"width: 40px\" />\n <ng-container *ngFor=\"let subControl of control.rowTemplate\">\n <col *ngIf=\"subControl && !subControl.hidden && subControl.visibleInList\"\n [style.width]=\"subControl.width\" />\n </ng-container>\n <col *ngIf=\"control.enableReorderRow\" style=\"width: 30px\" />\n <col *ngIf=\"control.showFunction\" [style.width]=\"control.widthFunctionColumn\" />\n </colgroup>\n </ng-template>\n <ng-template *ngIf=\"getComponentByType(_prefixCustomHeader + control.field)\"\n pTemplate=\"header\" let-columns>\n <ng-container\n *ngTemplateOutlet=\"getComponentByType(_prefixCustomHeader + control.field), context: {$implicit: control.headerTemplate, crudForm: this, containerSticky: containerSticky}\">\n </ng-container>\n </ng-template>\n <ng-template *ngIf=\"!getComponentByType(_prefixCustomHeader + control.field)\"\n pTemplate=\"header\" let-rowData let-columns>\n <tr>\n <th *ngIf=\"control.showNumber\" class=\"th-sticky stt\">\n {{ 'TT' |translate}}\n <ng-container *ngTemplateOutlet=\"containerSticky\"></ng-container>\n </th>\n <ng-container *ngFor=\"let subControl of control.rowTemplate\">\n <th *ngIf=\"subControl && !subControl.hidden && subControl.visibleInList\"\n [width]=\"subControl.width\"\n [pTooltip]=\"subControl.fullLabel || subControl.label\" tooltipPosition=\"top\"\n style=\"text-align: center;\">\n {{subControl.label}}\n <span *ngIf=\"subControl.required\" class=\"star-required\">*</span>\n <span *ngIf=\"subControl.description\"\n class=\"subControl-description\">({{subControl.description}})</span>\n <ng-container *ngTemplateOutlet=\"containerSticky\"></ng-container>\n </th>\n </ng-container>\n <th *ngIf=\"control.enableReorderRow\">\n <ng-container *ngTemplateOutlet=\"containerSticky\"></ng-container>\n </th>\n <th *ngIf=\"control.showFunction\" class=\"table-function column-function\">\n <div class=\"cell-header-function\"><span>Ch\u1EE9c n\u0103ng</span></div>\n <ng-container *ngTemplateOutlet=\"containerSticky\"></ng-container>\n </th>\n </tr>\n </ng-template>\n <ng-template pTemplate=\"body\" let-rowData let-ri=\"rowIndex\">\n <tr [pReorderableRow]=\"ri\" [class]=\"rowData.class\"\n (click)=\"handleRowClick(rowData, control)\">\n <td *ngIf=\"control.showNumber\" class=\"stt th-sticky\"\n style=\"text-align: center; vertical-align: inherit\">\n <span>\n {{ri + 1}}\n </span>\n <ng-container *ngTemplateOutlet=\"containerSticky\"></ng-container>\n </td>\n <ng-container *ngFor=\"let subControl of control.rowTemplate; let i = index\">\n <td *ngIf=\"subControl && !subControl.hidden && subControl.visibleInList\"\n [class.control-inside]=\"true\" [class]=\"subControl.class\"\n [ngStyle]=\"{'text-align': getTextAlign(subControl.textAlign), 'vertical-align': 'inherit'}\">\n <span class=\"p-column-title\">{{subControl.label}}</span>\n <ng-template [ngIf]=\"getControlType(subControl) != 'column'\">\n <ng-container *ngTemplateOutlet=\"customControl; context: {\n control: subControl,\n data: rowData,\n index: ri,\n tablePath: path,\n parentPath: path + '[' + ri + ']',\n path: path + '[' + ri + '].' + subControl.field,\n showLabel: false,\n mdWidth: 12,\n rowSpan: 1\n }\">\n </ng-container>\n </ng-template>\n <ng-template [ngIf]=\"getControlType(subControl) == 'column'\">\n <span>{{_modelData[control.field][ri][subControl.field]}}</span>\n </ng-template>\n <ng-container *ngTemplateOutlet=\"containerSticky\"></ng-container>\n </td>\n </ng-container>\n <td *ngIf=\"control.enableReorderRow\" class=\"no-padding center v-center\">\n <i class=\"fas fa-arrows-alt\" style=\"cursor:pointer; padding: 8px; color: #555;\"\n pReorderableRowHandle></i>\n <ng-container *ngTemplateOutlet=\"containerSticky\"></ng-container>\n </td>\n <td *ngIf=\"control.showFunction\" style=\"text-align: center\"\n class=\"column-function text-center\">\n <div *ngIf=\"!control.rowButtonTemplate\"\n class=\"p-toolbar-group-center button-group\">\n <button *ngIf=\"control.showSave\" [disabled]=\"rowData._disableSave\"\n type=\"button\" pButton class=\"p-button-text p-button-rounded\"\n icon=\"pi pi-save\" [pTooltip]=\"'L\u01B0u' | translate\" tooltipPosition=\"top\"\n (click)=\"saveRow(ri, control, path)\"></button>\n <button *ngIf=\"control.showEdit\" [disabled]=\"rowData._disableEdit\"\n type=\"button\" pButton class=\"p-button-text p-button-rounded\"\n icon=\"pi pi-pencil\" [pTooltip]=\"'S\u1EEDa' | translate\" tooltipPosition=\"top\"\n (click)=\"editRow(ri, control, path)\"></button>\n <button *ngIf=\"control.showDelete\" [disabled]=\"rowData._disableDelete\"\n type=\"button\" pButton\n class=\"p-button-text p-button-danger p-button-rounded\"\n icon=\"pi pi-trash\" [pTooltip]=\"'X\u00F3a' | translate\" tooltipPosition=\"top\"\n (click)=\"deleteRow(ri, control, path)\"></button>\n <button *ngIf=\"control.rowButtons\" type=\"button\" pButton\n icon=\"pi pi-ellipsis-v\"\n class=\"link-or-action p-button-text p-button-rounded\"\n pTooltip=\"Ch\u1EE9c n\u0103ng kh\u00E1c\" tooltipPosition=\"top\"\n (click)=\"showContextMenu($event, rowData, control)\"></button>\n </div>\n <div *ngIf=\"control.rowButtonTemplate\"\n class=\"p-toolbar-group-center button-group\">\n <ng-container\n *ngTemplateOutlet=\"control.rowButtonTemplate; context: {rowData: _modelData[control.field][ri], rowIndex: ri, path: path, control: control}\">\n </ng-container>\n </div>\n <ng-container *ngTemplateOutlet=\"containerSticky\"></ng-container>\n </td>\n </tr>\n </ng-template>\n <ng-template *ngIf=\"control.summaryTemplate\" pTemplate=\"summary\" let-rowData>\n <ng-container *ngTemplateOutlet=\"control.summaryTemplate; context: {rowData: rowData}\">\n </ng-container>\n </ng-template>\n </p-table>\n </tn-custom-scrollbar>\n <div *ngIf=\"control.showFooter\" class=\"--table-schema-footer\">\n <button *ngIf=\"control.showAdd\" type=\"button\" pButton style=\"width:auto\" label=\"Th\u00EAm m\u1EDBi\"\n icon=\"pi pi-plus\" class=\"p-button-text\" (click)=\"addNewRow(control, path)\"></button>\n <span *ngIf=\"control.showDialog\" style=\"font-weight: normal;\">\n <p-checkbox label=\"M\u1EDF dialog\" [binary]=\"true\" [(ngModel)]=\"control.showEdit\">\n </p-checkbox>\n </span>\n <button *ngIf=\"control.enableAddMulti\" type=\"button\" pButton\n style=\"width:auto; margin-left:10px;\" label=\"Th\u00EAm nhi\u1EC1u\" icon=\"pi pi-clone\"\n class=\"p-button-text\" (click)=\"addMultiRow(control, 5, path)\"></button>\n <button *ngFor=\"let bt of control.footerButtons\" type=\"button\" pButton [class]=\"bt.class\"\n [icon]=\"bt.icon\" [label]=\"bt.label | translate\" style=\"width:auto; margin-left:10px;\"\n (click)=\"messageRow( -1, control, path)\"></button>\n </div>\n </div>\n </ng-container>\n <ng-container *ngSwitchDefault>\n <ng-container *ngIf=\"control.template\">\n <ng-container [ngTemplateOutlet]=\"control.template\" [ngTemplateOutletContext]=\"{\n crudForm: this, data: data, index: rowIndex, parentPath: parentPath, control: control, changeFunc: handleFieldValueChange\n }\">\n </ng-container>\n </ng-container>\n <ng-container *ngIf=\"!control.template\" [ngTemplateOutlet]=\"getComponentByType(control.field)\"\n [ngTemplateOutletContext]=\"{\n crudForm: this, data: data, index: rowIndex, parentPath: parentPath, control: control, changeFunc: handleFieldValueChange\n }\">\n </ng-container>\n </ng-container>\n <ng-container *ngTemplateOutlet=\"validation; context: {control: control, data: data}\">\n </ng-container>\n <div *ngIf=\"control.message\" class=\"control-message\">\n <span [class]=\"control.messageClass\">{{control.message}}</span>\n </div>\n </ng-container>\n </div>\n</ng-template>\n<ng-template #validation let-control=\"control\" let-data=\"data\">\n <ng-container *ngIf=\"data._errors[control.field].length > 0\">\n <div class=\"error-container\">\n <ng-container *ngFor=\"let error of data._errors[control.field]\">\n <div class=\"error-item\" *ngIf=\"error\">\n <ng-container [ngTemplateOutlet]=\"errorMessage\" [ngTemplateOutletContext]=\"{content: error}\">\n </ng-container>\n </div>\n </ng-container>\n </div>\n </ng-container>\n</ng-template>\n<ng-template #errorMessage let-content=\"content\">\n <div class=\"error-content\">\n <i class=\"pi pi-ban\"></i>\n <span> {{content}}</span>\n </div>\n</ng-template>\n<ng-template #labelControl let-control=\"control\">\n <ng-container>\n <label [class]=\"getLabelClass(control)\" *ngIf=\"!control.isHtml\" [attr.label-index]=\"control.indexLabel\"\n [pTooltip]=\"control.title\" tooltipPosition=\"top\" tooltipStyleClass=\"wrap\" [escape]=\"false\"\n [for]=\"control.for\">{{control.text | translate}}</label>\n <label [class]=\"getLabelClass(control)\" *ngIf=\"control.isHtml\" [innerHTML]=\"control.text | safeHtml\"\n [attr.label-index]=\"control.indexLabel\"></label>\n </ng-container>\n</ng-template>\n<ng-template #containerSticky>\n <span class=\"fix-sticky top\"></span>\n <span class=\"fix-sticky right\"></span>\n <span class=\"fix-sticky left\"></span>\n</ng-template>\n<!-- <ng-template #templateCongViecForm let-control=\"control\">\n <base-congviec-form [control]=\"control\" [parentSetting]=\"congViecSetting\" [tenCongViec]=\"control.data.tenCongViec\">\n </base-congviec-form>\n</ng-template> -->\n<tn-dialog *ngIf=\"tableFormDialogModel.showEditForm\" #dialog [styleClass]=\"'address-form'\"\n [header]=\"tableFormDialogModel.header | translate\" [popupSize]=\"tableFormDialogModel.popupSize\"\n (onHide)=\"tableFormDialogModel.showEditForm = false\">\n <table-detail-form #formBase [parentSetting]=\"setting\" [schema]=\"tableFormSchema\" [data]=\"tableFormDialogModel.data\"\n (onSaved)=\"handleSavedTableRow($event)\" (onCancel)=\"tableFormDialogModel.showEditForm = false\">\n </table-detail-form>\n</tn-dialog>",
14852
+ template: "<div [class]=\"_styleClass\">\n <form #formElement autocomplete=\"off\" autocorrect=\"off\" spellcheck=\"false\"\n [class]=\"'p-grid form-group crud-form' + (formClass ? ' ' + formClass : '')\"\n (keydown.shift.tab)=\"preventBlur($event)\">\n <div class=\"p-grid p-col-12\" [class.grid]=\"useGridTemplate\" style=\"margin: 0\">\n <ng-container *ngFor=\"let control of setting.schema\">\n <ng-container *ngTemplateOutlet=\"customControl; context: {\n control: control, data: _modelData, parentPath: '', path: control.field, showLabel: control.showLabel,\n mdWidth: control.mdWidth, rowSpan: control.rowSpan\n }\">\n </ng-container>\n </ng-container>\n </div>\n </form>\n</div>\n<p-contextMenu #contextMenu [appendTo]=\"'body'\" [model]=\"buttonContexts\">\n</p-contextMenu>\n<ng-template #customControl let-data=\"data\" let-control=\"control\" let-showLabel=\"showLabel\" let-mdWidth=\"mdWidth\"\n let-rowSpan=\"rowSpan\" let-rowIndex=\"index\" let-path=\"path\" let-parentPath=\"parentPath\" let-tablePath=\"tablePath\">\n <div *ngIf=\"!checkHidden(control, data, path)\" id=\"{{path}}-holder\"\n class=\"p-col-{{control.gWidth}} p-md-{{mdWidth}} row-span-{{rowSpan}} {{control.class}} crud-form-control type-{{control.dataType}}\"\n [class.error]=\"data._errors[control.field].length > 0\"\n [class.not-show-in-box-holder]=\"control.showInBox === false\"\n [class.show-in-box-holder]=\"control.showInBox === true\" [ngStyle]=\"control.style\">\n <div class=\"label\" *ngIf=\"showLabel\">\n <label *ngIf=\"control.label && !control.isHtmlLabel\" [pTooltip]=\"control.fullLabel\"\n tooltipPosition=\"top\">{{control.label}}\n <span *ngIf=\"control.required || control.showIconRequired\" class=\"star-required\">*</span>\n </label>\n <ng-container *ngIf=\"control.label && control.isHtmlLabel\">\n <label [innerHTML]=\"control.label | safeHtml\" [pTooltip]=\"control.fullLabel\" tooltipPosition=\"top\">\n </label>\n <span *ngIf=\"control.required || control.showIconRequired\" class=\"star-required\">*</span>\n </ng-container>\n <span *ngIf=\"control.description\" class=\"control-description\">({{control.description}})</span>\n </div>\n <ng-container [ngSwitch]=\"control.controlType\">\n <ng-container *ngSwitchCase=\"'label'\">\n <ng-container [ngTemplateOutlet]=\"labelControl\"\n [ngTemplateOutletContext]=\"{control: control, data: data}\">\n </ng-container>\n </ng-container>\n <ng-container *ngSwitchCase=\"'title'\">\n <label *ngIf=\"!control.isHtml\" [for]=\"control.for\">{{control.text | translate}}</label>\n <label *ngIf=\"control.isHtml\" [innerHTML]=\"control.text | safeHtml\"></label>\n </ng-container>\n <ng-container *ngSwitchCase=\"'text'\">\n <div class=\"p-inputgroup\" *ngIf=\"control.suffFix\">\n <input [placeholder]=\"control.placeholder\" [tooltipDisabled]=\"control.dataFormat == 'password'\"\n [required]=\"control.validators && control.validators.required\" [pTooltip]=\"data[control.field]\"\n tooltipPosition=\"top\" tooltipStyleClass=\"wrap\"\n [attr.disabled]=\" checkDisabled(data, control) ? true : null\" pInputText\n [type]=\"control.dataFormat\" [max]=\"control.max\" [min]=\"control.min\"\n [maxlength]=\"control.maxLength\" [(ngModel)]=\"data[control.field]\"\n (change)=\"handleFieldValueChange(control, $event, eventType.CHANGE, data, parentPath)\"\n (key.enter)=\"handleFieldValueChange(control, $event, eventType.ENTER, data, parentPath)\" />\n <span class=\"p-inputgroup-addon\">({{control.suffFix}})</span>\n </div>\n <input *ngIf=\"!control.suffFix\" [placeholder]=\"control.placeholder\"\n [tooltipDisabled]=\"control.dataFormat == 'password'\" [pTooltip]=\"data[control.field]\"\n tooltipPosition=\"top\" tooltipStyleClass=\"wrap\"\n [attr.disabled]=\"checkDisabled(data, control) ? true : null\" pInputText [type]=\"control.dataFormat\"\n [max]=\"control.max\" [min]=\"control.min\" [maxlength]=\"control.maxLength\"\n [(ngModel)]=\"data[control.field]\"\n (change)=\"handleFieldValueChange(control, $event, eventType.CHANGE, data, parentPath)\"\n (key.enter)=\"handleFieldValueChange(control, $event, eventType.ENTER, data, parentPath)\" />\n </ng-container>\n <ng-container *ngSwitchCase=\"'htmlPreview'\">\n <html-preview [control]=\"control\" [(ngModel)]=\"data[control.field]\"\n (onChanged)=\"handleFieldValueChange(control, $event, eventType.CHANGE, data, parentPath)\">\n </html-preview>\n </ng-container>\n <ng-container *ngSwitchCase=\"'reference-text'\">\n <reference-textbox [control]=\"control\" [value]=\"data[control.field]\" [dataSource]=\"control.dataSource\"\n (onInit)=\"handleLoadedControl($event, control, parentPath)\"></reference-textbox>\n </ng-container>\n <ng-container *ngSwitchCase=\"'template'\">\n <ng-container [ngTemplateOutlet]=\"control.template\"\n [ngTemplateOutletContext]=\"{$implicit: _rootNode, control: control, data: data, tablePath: tablePath, parentPath: parentPath, rowIndex: rowIndex, funcUpdateModel: updateModelFromExternal}\">\n </ng-container>\n </ng-container>\n <ng-container *ngSwitchCase=\"'content'\">\n <div class=\"control-content label\">\n <span [innerHTML]=\"data[control.field] ? (data[control.field] | safeHtml) : ''\">\n </span>\n </div>\n </ng-container>\n <ng-container *ngSwitchCase=\"'mask'\">\n <tn-mask [prefix]=\"control.prefix\" [decimalPlaces]=\"control.decimalPlaces\" [suffix]=\"control.suffix\"\n [placeholder]=\"control.placeholder\" [disabled]=\"checkDisabled(data, control)\" tooltipPosition=\"top\"\n [tooltipDisabled]=\"control.dataFormat == 'password'\" [pTooltip]=\"data[control.field]\"\n [maskType]=\"control.maskType\" [autoFormat]=\"control.autoFormat\" [min]=\"control.min\"\n [max]=\"control.max\" [(ngModel)]=\"data[control.field]\"\n (onInit)=\"handleLoadedControl($event, control, parentPath)\"\n (onChanged)=\"handleFieldValueChange(control, $event, eventType.CHANGE, data, parentPath)\">\n </tn-mask>\n </ng-container>\n <ng-container *ngSwitchCase=\"'numberrange'\">\n <tn-number-picker-range [decimalPlaces]=\"control.decimalPlaces\"\n [disabled]=\"checkDisabled(data, control)\" [maskType]=\"control.maskType\" [min]=\"control.min\"\n [max]=\"control.max\" [placeholder]=\"control.placeholder\" [(ngModel)]=\"data[control.field]\"\n (onInit)=\"handleLoadedControl($event, control, parentPath)\"\n (change)=\"handleFieldValueChange(control, $event, eventType.CHANGE, data, parentPath)\"\n (blur)=\"handleFieldValueChange(control, $event, eventType.BLUR, data, parentPath)\">\n </tn-number-picker-range>\n </ng-container>\n <ng-container *ngSwitchCase=\"'money'\">\n <input currencyMask [attr.disabled]=\"checkDisabled(data, control) ? true : null\" pInputText type=\"tel\"\n tooltipPosition=\"top\" [pTooltip]=\"data[control.field] | number: '1.0-0'\"\n [options]=\"{prefix: '', thousands: '.', decimal: ',',precision:control.dataFormat === 'money'?0:0 }\"\n [(ngModel)]=\"data[control.field]\"\n (ngModelChange)=\"handleFieldValueChange(control, $event, eventType.CHANGE, data, parentPath)\" />\n </ng-container>\n <ng-container *ngSwitchCase=\"'phoneOrfax'\">\n <input [placeholder]=\"control.dataFormat==='phone'?'(999) 999-9999':'999-999-9999'\"\n [attr.disabled]=\"checkDisabled(data, control) ? true : null\" type=\"tel\" pInputText\n [(ngModel)]=\"data[control.field]\"\n (change)=\"handleFieldValueChange(control, $event, eventType.CHANGE, data, parentPath)\" />\n </ng-container>\n <ng-container *ngSwitchCase=\"'textarea'\">\n <textarea pInputTextarea [rows]=\"control.rows ? control.rows : 5\"\n [attr.disabled]=\"checkDisabled(data, control) ? true : null\" [(ngModel)]=\"data[control.field]\"\n [placeholder]=\"control.placeholder\"\n (keyup)=\"handleKeyUp(control, $event, eventType.CHANGE, data, parentPath)\"\n (change)=\"handleFieldValueChange(control, $event, eventType.CHANGE, data, parentPath)\"></textarea>\n </ng-container>\n <ng-container *ngSwitchCase=\"'editor'\">\n <tn-tinymce *ngIf=\"!checkDisabled(data, control)\"\n [required]=\"control.validators && control.validators.required\" [mode]=\"control.mode\"\n [height]=\"control.height ? control.height : 250\" [languageCode]=\"control.languageCode\"\n [control]=\"control\"\n [disabled]=\"control.disabled || (control.disableCheck && control.disableCheck(model))\"\n [(ngModel)]=\"data[control.field]\" (onInit)=\"handleLoadedControl($event, control, parentPath)\"\n (onKeyUp)=\"handleKeyUp(control, $event, eventType.CHANGE, data, parentPath)\"\n (onChanged)=\"handleFieldValueChange(control, $event, eventType.CHANGE, data, parentPath)\">\n </tn-tinymce>\n <div *ngIf=\"checkDisabled(data, control)\" class=\"html-box\"\n [innerHTML]=\"data[control.field] ? (data[control.field] | safeHtml) : ''\">\n </div>\n </ng-container>\n <ng-container *ngSwitchCase=\"'datetime'\">\n <datetime-picker [disabled]=\"checkDisabled(data, control)\" [control]=\"control\"\n [(ngModel)]=\"data[control.field]\" (onInit)=\"handleLoadedControl($event, control, parentPath)\"\n (onChanged)=\"handleFieldValueChange(control, $event, eventType.CHANGE, data, parentPath)\">\n </datetime-picker>\n </ng-container>\n <ng-container *ngSwitchCase=\"'autocomplete'\">\n <app-autocomplete-datasource [control]=\"control\"\n [suggestions]=\"data._source[control.field] || control.dataSource\" [(ngModel)]=\"data[control.field]\"\n (onInit)=\"handleLoadedControl($event, control, parentPath)\"\n (onValueChanged)=\"handleFieldValueChange(control, $event, eventType.CHANGE, data, parentPath)\">\n </app-autocomplete-datasource>\n </ng-container>\n <ng-container *ngSwitchCase=\"'datetimerange'\">\n <tn-datetime-picker-range [disabled]=\"control.disabled\" [control]=\"control\"\n [(ngModel)]=\"data[control.field]\" (onInit)=\"handleLoadedControl($event, control, parentPath)\"\n (onChanged)=\"handleFieldValueChange(control, $event, eventType.CHANGE, data, parentPath)\">\n </tn-datetime-picker-range>\n </ng-container>\n <ng-container *ngSwitchCase=\"'dropdown'\">\n <dropdown [control]=\"control\" [dataSource]=\"getControlDataSource(control, data)\" [data]=\"data\"\n [(value)]=\"data[control.field]\" (onInit)=\"handleLoadedControl($event, control, parentPath)\"\n (onChanged)=\"handleChangeDropdown(control, $event, eventType.CHANGE, data, parentPath)\"\n (onHideSmartEvent)=\"handleChangeDropdown(control, $event, eventType.HIDE, data, parentPath)\"\n (adjustValue)=\"handleAdjustValueDropdownEvent(control, parentPath)\"\n (onDataSourceLoaded)=\"handleDataSourceLoaded(control, parentPath, $event)\"\n (onReady)=\"handleControlReadyEvent(control, parentPath)\">\n </dropdown>\n </ng-container>\n <ng-container *ngSwitchCase=\"'imageuploader'\">\n <app-image-uploader [loadByEntityKey]=\"control.loadByEntityKey\" [entityKey]=\"control.entityKey\"\n [defaultNoImageUrl]=\"'/assets/images/no-image.jpg'\" [multiple]=\"control.multiple\"\n [disabled]=\"control.disabled\" [isAvatar]=\"control.isAvatar\" [(ngModel)]=\"data[control.field]\"\n (onChanged)=\"handleFieldValueChange(control, $event, eventType.CHANGE, data, parentPath)\"\n (onInit)=\"handleLoadedControl($event, control, parentPath)\">\n <ng-template *ngIf=\"control.templateItems\" #items let-files>\n <ng-container *ngTemplateOutlet=\"control.templateItems; context: {\n $implicit: files\n }\"></ng-container>\n </ng-template>\n <ng-template *ngIf=\"control.templateItem\" #item let-file>\n <ng-container *ngTemplateOutlet=\"control.templateItem; context: {\n $implicit: file\n }\"></ng-container>\n </ng-template>\n </app-image-uploader>\n </ng-container>\n <ng-container *ngSwitchCase=\"'fileManager'\">\n <file-manager *ngIf=\"control.entityKey || data[control.entityKeyField] || control.rootFolderId\"\n [control]=\"control\" [serviceCode]=\"control.serviceCode\" [entity]=\"control.entity\"\n [hiddenCreateFolder]=\"control.hiddenCreateFolder\"\n [entityKey]=\"control.entityKey ? control.entityKey : data[control.entityKeyField]\"\n [readonly]=\"control.disabled\" [layout]=\"control.layout\" [rootFolderId]=\"control.rootFolderId\"\n [maxFileSize]=\"control.maxFileSize\" [inTaiLieu]=\"control.inTaiLieu\"\n [inTaiLieuChung]=\"control.inTaiLieuChung\" [copyToFolderId]=\"control.copyToFolderId\"\n [filePickerSetting]=\"control.filePickerSetting\" [dataForm]=\"data\"\n [invalidFileSizeMessageSummary]=\"control.invalidFileSizeMessageSummary\"\n [invalidFileSizeMessageDetail]=\"control.invalidFileSizeMessageDetail\"\n [invalidFileTypeMessageSummary]=\"control.invalidFileTypeMessageSummary\"\n [invalidFileTypeMessageDetail]=\"control.invalidFileTypeMessageDetail\"\n [invalidFileLimitMessageSummary]=\"control.invalidFileLimitMessageSummary\"\n [invalidFileLimitMessageDetail]=\"control.invalidFileLimitMessageDetail\" [parentSetting]=\"setting\"\n [noFileMessage]=\"control.noFileMessage\" [(value)]=\"data[control.field]\"\n (onInit)=\"handleLoadedControl($event, control, parentPath)\"\n (onSelected)=\"control.onSelected($event)\"\n (onChanged)=\"handleFieldValueChange(control, $event, eventType.CHANGE, data, parentPath)\"\n (onReady)=\"handleControlReadyEvent(control, parentPath)\">\n </file-manager>\n </ng-container>\n <span *ngSwitchCase=\"'fileUpload'\">\n <file-upload [sharedFolderType]=\"control.sharedFolderType\" [maxFileSize]=\"control.maxFileSize\"\n [invalidFileSizeMessageSummary]=\"control.invalidFileSizeMessageSummary\"\n [invalidFileSizeMessageDetail]=\"control.invalidFileSizeMessageDetail\"\n [invalidFileTypeMessageSummary]=\"control.invalidFileTypeMessageSummary\"\n [invalidFileTypeMessageDetail]=\"control.invalidFileTypeMessageDetail\"\n [invalidFileLimitMessageSummary]=\"control.invalidFileLimitMessageSummary\"\n [invalidFileLimitMessageDetail]=\"control.invalidFileLimitMessageDetail\" [control]=\"control\"\n [showDeleteFile]=\"control.showDeleteFile\" [readonly]=\"control.readonly\" [accept]=\"control.accept\"\n [(ngModel)]=\"data[control.field]\" (onInit)=\"handleLoadedControl($event, control, parentPath)\"\n (onChanged)=\"handleFieldValueChange(control, $event, eventType.CHANGE, data, parentPath)\"\n (onRemove)=\"handleFieldValueChange(control, $event, eventType.DELETED, data, parentPath)\">\n </file-upload>\n </span>\n <span *ngSwitchCase=\"'serviceFileUpload'\">\n <service-file-upload *ngIf=\"control.entityKey || data[control.entityKeyField] || control.rootFolderId\"\n [parentContext]=\"context\" [serviceCode]=\"control.serviceCode\" [entity]=\"control.entity\"\n [entityKey]=\"control.entityKey ? control.entityKey : data[control.entityKeyField]\"\n [control]=\"control\" [(ngModel)]=\"data[control.field]\"\n (onInit)=\"handleLoadedControl($event, control, parentPath)\"\n (onChanged)=\"handleFieldValueChange(control, $event, eventType.CHANGE, data, parentPath)\"\n (onRemove)=\"handleFieldValueChange(control, $event, eventType.DELETED, data, parentPath)\">\n </service-file-upload>\n </span>\n <ng-container *ngSwitchCase=\"'user-picker'\">\n <user-picker [control]=\"control\" [disabled]=\"checkDisabled(data, control)\"\n [readOnlyValues]=\"data[control.field + '_readOnly']\" [multiple]=\"control.multiple\"\n [(ngModel)]=\"data[control.field]\" (onInit)=\"handleLoadedControl($event, control, parentPath)\"\n (onChanged)=\"handleFieldValueChange(control, $event, eventType.CHANGE, data, parentPath)\"\n (onReady)=\"handleReadyControlPicker(control, parentPath)\">\n </user-picker>\n </ng-container>\n <ng-container *ngSwitchCase=\"'switch'\">\n <p-inputSwitch [disabled]=\"checkDisabled(data, control)\" [(ngModel)]=\"data[control.field]\"\n (onChange)=\"handleFieldValueChange(control, $event, eventType.CHANGE, data, parentPath)\">\n </p-inputSwitch>\n </ng-container>\n <ng-container *ngSwitchCase=\"'checkbox'\">\n <div [class]=\"control.class\" role=\"checkbox-alone\">\n <p-checkbox [disabled]=\"checkDisabled(data, control)\" [binary]=\"true\"\n [label]=\"control.isCustomLabel ? control.displayLabel : (!control.hiddenLabel ? control.label : null)\"\n [(ngModel)]=\"data[control.field]\"\n (onChange)=\"handleFieldValueChange(control, $event, eventType.CHANGE, data, parentPath)\">\n </p-checkbox>\n <!-- <tn-checkbox [control]=\"control\" [disabled]=\"checkDisabled(data, control)\"\n [(ngModel)]=\"data[control.field]\"\n (onChange)=\"handleFieldValueChange(control, $event, eventType.CHANGE, data, parentPath)\"></tn-checkbox> -->\n </div>\n </ng-container>\n <ng-container *ngSwitchCase=\"'button'\">\n <button type=\"button\" pButton [class]=\"control.btClass\" [icon]=\"control.icon\"\n [label]=\"control.buttonText | translate\" [ngStyle]=\"control.btStyle\" [pTooltip]=\"control.fullLabel\"\n tooltipPosition=\"top\" (click)=\"handleButtonClick(control, $event, parentPath)\"></button>\n </ng-container>\n <ng-container *ngSwitchCase=\"'container'\">\n <div class=\"p-grid p-col-12\" style=\"margin: 0\" [class.not-show-in-box]=\"!control.showInBox\"\n [class.show-in-box]=\"control.showInBox\" [ngStyle]=\"control.boxStyle\">\n <ng-container *ngFor=\"let subControl of control.controls\">\n <ng-container *ngTemplateOutlet=\"customControl; context: {\n control: subControl,\n data: data[control.field],\n parentPath: path,\n rowIndex: rowIndex,\n path: path + '.' + subControl.field,\n showLabel: subControl.showLabel,\n mdWidth: subControl.mdWidth,\n rowSpan: subControl.rowSpan\n }\">\n </ng-container>\n </ng-container>\n </div>\n </ng-container>\n <ng-container *ngSwitchCase=\"'checkboxlist'\">\n <check-box-list [control]=\"control\" [dataSource]=\"data._source[control.field] || control.dataSource\"\n [disabled]=\"checkDisabled(data, control)\" [(ngModel)]=\"data[control.field]\"\n (onInit)=\"handleLoadedControl($event, control, parentPath)\"\n (onSelect)=\"handleFieldValueChange(control, $event, eventType.CHANGE, data, parentPath)\"\n (onReady)=\"handleControlReadyEvent(control, parentPath)\">\n </check-box-list>\n </ng-container>\n <ng-container *ngSwitchCase=\"'radiobuttonlist'\">\n <radio-button-list [control]=\"control\" [dataSource]=\"control.dataSource\"\n [disabled]=\"checkDisabled(data, control)\" [(value)]=\"data[control.field]\"\n (onInit)=\"handleLoadedControl($event, control, parentPath)\"\n (onChanged)=\"handleFieldValueChange(control, $event, eventType.CHANGE, data, parentPath)\"\n (adjustValue)=\"handleAdjustValueDropdownEvent(control, parentPath)\"\n (onReady)=\"handleReadyControlPicker(control, parentPath)\"\n (onDataSourceLoaded)=\"handleDataSourceLoaded(control, parentPath, $event)\">\n </radio-button-list>\n </ng-container>\n <ng-container *ngSwitchCase=\"'colorPicker'\">\n <tn-color-picker [disabled]=\"checkDisabled(data, control)\" [(ngModel)]=\"data[control.field]\"\n (onInit)=\"handleLoadedControl($event, control, parentPath)\"\n (change)=\"handleFieldValueChange(control, $event, eventType.CHANGE, data, parentPath)\">\n </tn-color-picker>\n </ng-container>\n <ng-container *ngSwitchCase=\"'spanControl'\">\n <span *ngIf=\"!control.ishtml\">{{data[control.field]}}</span>\n <span *ngIf=\"control.ishtml\" [innerHTML]=\"data[control.field]\"></span>\n </ng-container>\n <ng-container *ngSwitchCase=\"'colorControl'\">\n <span class=\"show-color-control\" [ngStyle]=\"{ backgroundColor: data[control.sourceField]}\"></span>\n </ng-container>\n <ng-container *ngSwitchCase=\"'address'\">\n <address-picker [control]=\"control\" [showSubLabel]=\"control.showSubLabel\"\n [disabled]=\"checkDisabled(data, control)\" [(data)]=\"data[control.field]\"\n (onInit)=\"handleLoadedControl($event, control, parentPath)\"\n (onSelect)=\"handleFieldValueChange(control, $event, eventType.CHANGE, data, parentPath)\"\n (onReady)=\"handleControlReadyEvent(control, parentPath)\">\n </address-picker>\n </ng-container>\n <ng-container *ngSwitchCase=\"'autocomplete-picker'\">\n <autocomplete-picker [control]=\"control\" [disabled]=\"checkDisabled(data, control)\"\n [required]=\"control.required\" [readOnlyValues]=\"data[control.field + '_readOnly']\"\n [(ngModel)]=\"data[control.field]\" (onInit)=\"handleLoadedControl($event, control, parentPath)\"\n (onChanged)=\"handleFieldValueChange(control, $event, eventType.CHANGE, data, parentPath)\"\n (onReady)=\"handleReadyControlPicker(control, parentPath)\">\n </autocomplete-picker>\n </ng-container>\n <ng-container *ngSwitchCase=\"'cocautochuc'\">\n <cocautochuc-picker [control]=\"control\" [parentOrgId]=\"control.parentOrgId\"\n [disabled]=\"checkDisabled(data, control)\" [parentOrgCode]=\"control.parentOrgCode\"\n [filter]=\"control.filter\" [multiple]=\"control.multiple\" [required]=\"control.required\"\n [isUsingId]=\"control.isUsingId\" [disabledParentItem]=\"control.disabledParentItem\"\n [rootParentId]=\"control.rootParentId\" [(ngModel)]=\"data[control.field]\"\n (onInit)=\"handleLoadedControl($event, control, parentPath)\"\n (onChanged)=\"handleFieldValueChange(control, $event, eventType.CHANGE, data, parentPath)\">\n </cocautochuc-picker>\n </ng-container>\n <ng-container *ngSwitchCase=\"'cocautochuc-picker'\">\n <cocautochuc-picker-list [control]=\"control\" [disabled]=\"checkDisabled(data, control)\"\n [required]=\"control.required\" [readOnlyValues]=\"data[control.field + '_readOnly']\"\n [(ngModel)]=\"data[control.field]\" (onInit)=\"handleLoadedControl($event, control, parentPath)\"\n (onChanged)=\"handleFieldValueChange(control, $event, eventType.CHANGE, data, parentPath)\"\n (onReady)=\"handleReadyControlPicker(control, parentPath)\">\n </cocautochuc-picker-list>\n </ng-container>\n <ng-container *ngSwitchCase=\"'cocautochuc-picker-new'\">\n <cocautochuc-picker-list-new [control]=\"control\" [disabled]=\"checkDisabled(data, control)\"\n [required]=\"control.required\" [readOnlyValues]=\"data[control.field + '_readOnly']\"\n [(ngModel)]=\"data[control.field]\" (onInit)=\"handleLoadedControl($event, control, parentPath)\"\n (onChanged)=\"handleFieldValueChange(control, $event, eventType.CHANGE, data, parentPath)\"\n (onReady)=\"handleReadyControlPicker(control, parentPath)\">\n </cocautochuc-picker-list-new>\n </ng-container>\n <ng-container *ngSwitchCase=\"'vanban'\">\n <vanban-picker [control]=\"control\" [disabled]=\"checkDisabled(data, control)\"\n [required]=\"control.required\" [readOnly]=\"control.readOnly\" [loaiVanBan]=\"control.loaiVanBan\"\n [(ngModel)]=\"data[control.field]\" (onInit)=\"handleLoadedControl($event, control, parentPath)\"\n (onChanged)=\"handleFieldValueChange(control, $event, eventType.CHANGE, data, parentPath)\">\n </vanban-picker>\n </ng-container>\n <ng-container *ngSwitchCase=\"'congviec'\">\n <div>\n <congviec-picker [control]=\"control\" [disabled]=\"checkDisabled(data, control)\"\n [required]=\"control.required\" [(ngModel)]=\"data[control.field]\"\n (onInit)=\"handleLoadedControl($event, control, parentPath)\"\n (onChanged)=\"handleFieldValueChange(control, $event, eventType.CHANGE, data, parentPath)\">\n </congviec-picker>\n </div>\n </ng-container>\n <ng-container *ngSwitchCase=\"'percent'\">\n <div>\n <tn-mask [suffix]=\"'%'\" [placeholder]=\"control.placeholder\" [maskType]=\"'int'\"\n [autoFormat]=\"control.autoFormat\" [min]=\"0\" [max]=\"100\"\n [disabled]=\"checkDisabled(data, control)\" [(ngModel)]=\"data[control.field]\"\n (onInit)=\"handleLoadedControl($event, control, parentPath)\"\n (onChanged)=\"handleFieldValueChange(control, $event, eventType.CHANGE, data, parentPath)\">\n </tn-mask>\n <p-slider [step]=\"1\" [min]=\"0\" [max]=\"100\" [disabled]=\"checkDisabled(data, control)\"\n [(ngModel)]=\"data[control.field]\"\n (onSlideEnd)=\"handleFieldValueChange(control, $event, eventType.CHANGE, data, parentPath)\">\n </p-slider>\n </div>\n </ng-container>\n <ng-container *ngSwitchCase=\"'chips'\">\n <p-chips [disabled]=\"checkDisabled(data, control)\" [(ngModel)]=\"data[control.field]\"\n [placeholder]=\"control.placeholder\"\n (onAdd)=\"handleFieldValueChange(control, $event, eventType.CHANGE, data, parentPath)\"\n (onRemove)=\"handleFieldValueChange(control, $event, eventType.CHANGE, data, parentPath)\"></p-chips>\n </ng-container>\n <ng-container *ngSwitchCase=\"'entity-picker'\">\n <entity-picker [control]=\"control\" [children]=\"children\" [disabled]=\"checkDisabled(data, control)\"\n [required]=\"control.required\" [readOnly]=\"control.readOnly\" [(ngModel)]=\"data[control.field]\"\n (onInit)=\"handleLoadedControl($event, control, parentPath)\"\n (onChanged)=\"handleFieldValueChange(control, $event, eventType.CHANGE, data, parentPath)\">\n </entity-picker>\n </ng-container>\n <ng-container *ngSwitchCase=\"'table'\">\n <div [class]=\"control.class\">\n <tn-custom-scrollbar class=\"--has-border\" [showScrollHorizontal]=\"true\">\n <p-table class=\"new-table scr-table table-control\" [value]=\"data[control.field]\"\n [columns]=\"control.headerTemplate\" [responsive]=\"true\" [scrollable]=\"false\"\n [rowTrackBy]=\"trackByFuncId\"\n (onRowReorder)=\"handleRowOrdered(control, $event, eventType.ROW_REORDER, data, parentPath)\">\n <ng-template pTemplate=\"colgroup\">\n <colgroup>\n <col *ngIf=\"control.showNumber\" style=\"width: 40px\" />\n <ng-container *ngFor=\"let subControl of control.rowTemplate\">\n <col *ngIf=\"subControl && !subControl.hidden && subControl.visibleInList\"\n [style.width]=\"subControl.width\" />\n </ng-container>\n <col *ngIf=\"control.enableReorderRow\" style=\"width: 30px\" />\n <col *ngIf=\"control.showFunction\" [style.width]=\"control.widthFunctionColumn\" />\n </colgroup>\n </ng-template>\n <ng-template *ngIf=\"getComponentByType(_prefixCustomHeader + control.field)\"\n pTemplate=\"header\" let-columns>\n <ng-container\n *ngTemplateOutlet=\"getComponentByType(_prefixCustomHeader + control.field), context: {$implicit: control.headerTemplate, crudForm: this, containerSticky: containerSticky}\">\n </ng-container>\n </ng-template>\n <ng-template *ngIf=\"!getComponentByType(_prefixCustomHeader + control.field)\"\n pTemplate=\"header\" let-rowData let-columns>\n <tr>\n <th *ngIf=\"control.showNumber\" class=\"th-sticky stt\">\n {{ 'TT' |translate}}\n <ng-container *ngTemplateOutlet=\"containerSticky\"></ng-container>\n </th>\n <ng-container *ngFor=\"let subControl of control.rowTemplate\">\n <th *ngIf=\"subControl && !subControl.hidden && subControl.visibleInList\"\n [width]=\"subControl.width\"\n [pTooltip]=\"subControl.fullLabel || subControl.label\" tooltipPosition=\"top\"\n style=\"text-align: center;\">\n {{subControl.label}}\n <span *ngIf=\"subControl.required\" class=\"star-required\">*</span>\n <span *ngIf=\"subControl.description\"\n class=\"subControl-description\">({{subControl.description}})</span>\n <ng-container *ngTemplateOutlet=\"containerSticky\"></ng-container>\n </th>\n </ng-container>\n <th *ngIf=\"control.enableReorderRow\">\n <ng-container *ngTemplateOutlet=\"containerSticky\"></ng-container>\n </th>\n <th *ngIf=\"control.showFunction\" class=\"table-function column-function\">\n <div class=\"cell-header-function\"><span>{{'Ch\u1EE9c n\u0103ng'|translate}}</span></div>\n <ng-container *ngTemplateOutlet=\"containerSticky\"></ng-container>\n </th>\n </tr>\n </ng-template>\n <ng-template pTemplate=\"body\" let-rowData let-ri=\"rowIndex\">\n <tr [pReorderableRow]=\"ri\" [class]=\"rowData.class\"\n (click)=\"handleRowClick(rowData, control)\">\n <td *ngIf=\"control.showNumber\" class=\"stt th-sticky\"\n style=\"text-align: center; vertical-align: inherit\">\n <span>\n {{ri + 1}}\n </span>\n <ng-container *ngTemplateOutlet=\"containerSticky\"></ng-container>\n </td>\n <ng-container *ngFor=\"let subControl of control.rowTemplate; let i = index\">\n <td *ngIf=\"subControl && !subControl.hidden && subControl.visibleInList\"\n [class.control-inside]=\"true\" [class]=\"subControl.class\"\n [ngStyle]=\"{'text-align': getTextAlign(subControl.textAlign), 'vertical-align': 'inherit'}\">\n <span class=\"p-column-title\">{{subControl.label}}</span>\n <ng-template [ngIf]=\"getControlType(subControl) != 'column'\">\n <ng-container *ngTemplateOutlet=\"customControl; context: {\n control: subControl,\n data: rowData,\n index: ri,\n tablePath: path,\n parentPath: path + '[' + ri + ']',\n path: path + '[' + ri + '].' + subControl.field,\n showLabel: false,\n mdWidth: 12,\n rowSpan: 1\n }\">\n </ng-container>\n </ng-template>\n <ng-template [ngIf]=\"getControlType(subControl) == 'column'\">\n <span>{{_modelData[control.field][ri][subControl.field]}}</span>\n </ng-template>\n <ng-container *ngTemplateOutlet=\"containerSticky\"></ng-container>\n </td>\n </ng-container>\n <td *ngIf=\"control.enableReorderRow\" class=\"no-padding center v-center\">\n <i class=\"fas fa-arrows-alt\" style=\"cursor:pointer; padding: 8px; color: #555;\"\n pReorderableRowHandle></i>\n <ng-container *ngTemplateOutlet=\"containerSticky\"></ng-container>\n </td>\n <td *ngIf=\"control.showFunction\" style=\"text-align: center\"\n class=\"column-function text-center\">\n <div *ngIf=\"!control.rowButtonTemplate\"\n class=\"p-toolbar-group-center button-group\">\n <button *ngIf=\"control.showSave\" [disabled]=\"rowData._disableSave\"\n type=\"button\" pButton class=\"p-button-text p-button-rounded\"\n icon=\"pi pi-save\" [pTooltip]=\"'L\u01B0u' | translate\" tooltipPosition=\"top\"\n (click)=\"saveRow(ri, control, path)\"></button>\n <button *ngIf=\"control.showEdit\" [disabled]=\"rowData._disableEdit\"\n type=\"button\" pButton class=\"p-button-text p-button-rounded\"\n icon=\"pi pi-pencil\" [pTooltip]=\"'S\u1EEDa' | translate\" tooltipPosition=\"top\"\n (click)=\"editRow(ri, control, path)\"></button>\n <button *ngIf=\"control.showDelete\" [disabled]=\"rowData._disableDelete\"\n type=\"button\" pButton\n class=\"p-button-text p-button-danger p-button-rounded\"\n icon=\"pi pi-trash\" [pTooltip]=\"'X\u00F3a' | translate\" tooltipPosition=\"top\"\n (click)=\"deleteRow(ri, control, path)\"></button>\n <button *ngIf=\"control.rowButtons\" type=\"button\" pButton\n icon=\"pi pi-ellipsis-v\"\n class=\"link-or-action p-button-text p-button-rounded\"\n pTooltip=\"Ch\u1EE9c n\u0103ng kh\u00E1c\" tooltipPosition=\"top\"\n (click)=\"showContextMenu($event, rowData, control)\"></button>\n </div>\n <div *ngIf=\"control.rowButtonTemplate\"\n class=\"p-toolbar-group-center button-group\">\n <ng-container\n *ngTemplateOutlet=\"control.rowButtonTemplate; context: {rowData: _modelData[control.field][ri], rowIndex: ri, path: path, control: control}\">\n </ng-container>\n </div>\n <ng-container *ngTemplateOutlet=\"containerSticky\"></ng-container>\n </td>\n </tr>\n </ng-template>\n <ng-template *ngIf=\"control.summaryTemplate\" pTemplate=\"summary\" let-rowData>\n <ng-container *ngTemplateOutlet=\"control.summaryTemplate; context: {rowData: rowData}\">\n </ng-container>\n </ng-template>\n </p-table>\n </tn-custom-scrollbar>\n <div *ngIf=\"control.showFooter\" class=\"--table-schema-footer\">\n <button *ngIf=\"control.showAdd\" type=\"button\" pButton style=\"width:auto\" label=\"Th\u00EAm m\u1EDBi\"\n icon=\"pi pi-plus\" class=\"p-button-text\" (click)=\"addNewRow(control, path)\"></button>\n <span *ngIf=\"control.showDialog\" style=\"font-weight: normal;\">\n <p-checkbox label=\"M\u1EDF dialog\" [binary]=\"true\" [(ngModel)]=\"control.showEdit\">\n </p-checkbox>\n </span>\n <button *ngIf=\"control.enableAddMulti\" type=\"button\" pButton\n style=\"width:auto; margin-left:10px;\" label=\"Th\u00EAm nhi\u1EC1u\" icon=\"pi pi-clone\"\n class=\"p-button-text\" (click)=\"addMultiRow(control, 5, path)\"></button>\n <button *ngFor=\"let bt of control.footerButtons\" type=\"button\" pButton [class]=\"bt.class\"\n [icon]=\"bt.icon\" [label]=\"bt.label | translate\" style=\"width:auto; margin-left:10px;\"\n (click)=\"messageRow( -1, control, path)\"></button>\n </div>\n </div>\n </ng-container>\n <ng-container *ngSwitchDefault>\n <ng-container *ngIf=\"control.template\">\n <ng-container [ngTemplateOutlet]=\"control.template\" [ngTemplateOutletContext]=\"{\n crudForm: this, data: data, index: rowIndex, parentPath: parentPath, control: control, changeFunc: handleFieldValueChange\n }\">\n </ng-container>\n </ng-container>\n <ng-container *ngIf=\"!control.template\" [ngTemplateOutlet]=\"getComponentByType(control.field)\"\n [ngTemplateOutletContext]=\"{\n crudForm: this, data: data, index: rowIndex, parentPath: parentPath, control: control, changeFunc: handleFieldValueChange\n }\">\n </ng-container>\n </ng-container>\n <ng-container *ngTemplateOutlet=\"validation; context: {control: control, data: data}\">\n </ng-container>\n <div *ngIf=\"control.message\" class=\"control-message\">\n <span [class]=\"control.messageClass\">{{control.message}}</span>\n </div>\n </ng-container>\n </div>\n</ng-template>\n<ng-template #validation let-control=\"control\" let-data=\"data\">\n <ng-container *ngIf=\"data._errors[control.field].length > 0\">\n <div class=\"error-container\">\n <ng-container *ngFor=\"let error of data._errors[control.field]\">\n <div class=\"error-item\" *ngIf=\"error\">\n <ng-container [ngTemplateOutlet]=\"errorMessage\" [ngTemplateOutletContext]=\"{content: error}\">\n </ng-container>\n </div>\n </ng-container>\n </div>\n </ng-container>\n</ng-template>\n<ng-template #errorMessage let-content=\"content\">\n <div class=\"error-content\">\n <i class=\"pi pi-ban\"></i>\n <span> {{content}}</span>\n </div>\n</ng-template>\n<ng-template #labelControl let-control=\"control\">\n <ng-container>\n <label [class]=\"getLabelClass(control)\" *ngIf=\"!control.isHtml\" [attr.label-index]=\"control.indexLabel\"\n [pTooltip]=\"control.title\" tooltipPosition=\"top\" tooltipStyleClass=\"wrap\" [escape]=\"false\"\n [for]=\"control.for\">{{control.text | translate}}</label>\n <label [class]=\"getLabelClass(control)\" *ngIf=\"control.isHtml\" [innerHTML]=\"control.text | safeHtml\"\n [attr.label-index]=\"control.indexLabel\"></label>\n </ng-container>\n</ng-template>\n<ng-template #containerSticky>\n <span class=\"fix-sticky top\"></span>\n <span class=\"fix-sticky right\"></span>\n <span class=\"fix-sticky left\"></span>\n</ng-template>\n<!-- <ng-template #templateCongViecForm let-control=\"control\">\n <base-congviec-form [control]=\"control\" [parentSetting]=\"congViecSetting\" [tenCongViec]=\"control.data.tenCongViec\">\n </base-congviec-form>\n</ng-template> -->\n<tn-dialog *ngIf=\"tableFormDialogModel.showEditForm\" #dialog [styleClass]=\"'address-form'\"\n [header]=\"tableFormDialogModel.header | translate\" [popupSize]=\"tableFormDialogModel.popupSize\"\n (onHide)=\"tableFormDialogModel.showEditForm = false\">\n <table-detail-form #formBase [parentSetting]=\"setting\" [schema]=\"tableFormSchema\" [data]=\"tableFormDialogModel.data\"\n (onSaved)=\"handleSavedTableRow($event)\" (onCancel)=\"tableFormDialogModel.showEditForm = false\">\n </table-detail-form>\n</tn-dialog>",
14853
14853
  providers: [ComponentContextService],
14854
14854
  styles: [".label-only{font-weight:700;margin-bottom:1em}div.label{position:relative}div.label .star-required{color:red;position:absolute;padding-left:.2em;padding-top:.1em}th>span.star-required{color:red;padding-left:.2em;padding-top:.3em}div.type-container.not-show-in-box-holder{padding:0}.--table-schema-footer{display:flex;align-items:center;font-weight:600;padding:.5em;background:#f8f9fa;color:#495057;border:1px solid #e9ecef}.show-in-box{border:1px solid #ced4da;border-radius:5px}.not-show-in-box{padding:0}.view-mode div.label{padding-bottom:3px}.view-mode div.label label{font-weight:700;font-size:.85em}.view-mode>span:not(:empty){display:inline-block;width:100%;padding:5px 0}.view-mode.type-table div.label+div{padding:5px 0}td>.view-mode{display:inline-block;padding:.25rem .5rem}td>.view-mode .view-mode{padding:0}.crud-form-control div[role=checkbox-alone]{margin-top:24px}.crud-form-control div[role=checkbox-alone].mg-top-0{margin-top:0}.crud-form-control .label+div[role=checkbox-alone]{margin-top:11px}.crud-form-control.type-table div[role=checkbox-alone]{margin-top:6px;text-align:center}.crud-form-control.type-table div[role=checkbox-alone].mg-top-0{margin-top:0}.crud-form-control.type-table div[role=checkbox-alone].align-left{text-align:left}.crud-form-control.type-title{font-size:1.2rem;font-weight:700;color:#025ba7;border-bottom:1px solid #cfcfcf;text-transform:uppercase;padding:5px;margin-bottom:5px}.crud-form-control.type-title>.label{margin-bottom:0}.control-description,.crud-form-control .subControl-description{font-size:.8rem;font-weight:700;color:#007eff;margin-bottom:5px}.control-description{padding-left:.75rem}.th-sticky{text-align:center!important;z-index:2!important;position:sticky!important;top:0;background:inherit}.th-sticky.stt{left:0}.cell-header-function{display:flex;align-items:center}.cell-header-function>span{text-align:center;flex:1 1}.cell-header-function button{width:24px;height:24px;padding:0;margin:0}.no-value{font-size:.8em}@keyframes fadeIn{0%{opacity:0;top:-25px}to{opacity:1;top:0}}@keyframes shrink{0%{height:0}to{height:20px}}@media screen and (min-width:40.063em){.label-right{padding-left:2em}}::ng-deep crud-form .crud-form-control .tn-check-box-list{margin-top:5px}::ng-deep crud-form .crud-form-control>div.label{margin-bottom:5px;font-size:.9rem;height:1.15em}::ng-deep crud-form .crud-form-control>div.label+*{width:100%}::ng-deep crud-form .crud-form-control>.error-container .error-item{overflow:visible;animation:shrink .1s;min-height:20px;padding-top:5px}::ng-deep crud-form .crud-form-control>.error-container .error-item .error-content{display:flex;position:relative;color:red;font-size:.9em;animation:fadeIn .1s}::ng-deep crud-form .crud-form-control>.error-container .error-item .error-content i{font-size:.9em;display:flex;padding-top:1px}::ng-deep crud-form .crud-form-control>.error-container .error-item .error-content span{display:flex;padding-left:5px}::ng-deep crud-form .crud-form-control .control-message{margin-top:5px;font-size:.9rem}::ng-deep crud-form .crud-form-control .control-message .green{color:#00af00}::ng-deep crud-form .crud-form-control .control-message .red{color:red}::ng-deep crud-form .crud-form-control .control-message .blue{color:#0095ff}::ng-deep crud-form .crud-form-control.no-label>div.label{display:none}::ng-deep crud-form .crud-form-control.error .p-dropdown,::ng-deep crud-form .crud-form-control.error .p-inputtext,::ng-deep crud-form .crud-form-control.error .p-multiselect,::ng-deep crud-form .crud-form-control.error .tn-dropdown,::ng-deep crud-form .crud-form-control.error input,::ng-deep crud-form .crud-form-control.error select,::ng-deep crud-form .crud-form-control.error textarea{border-color:#ff5722!important}::ng-deep crud-form .crud-form-control.error .p-autocomplete-multiple-container:not(.p-disabled).p-focus,::ng-deep crud-form .crud-form-control.error .p-inputtext:enabled:focus,::ng-deep crud-form .crud-form-control.error .tn-dropdown:not(.p-disabled).p-focus{box-shadow:0 0 0 .2rem #ffc4b3}::ng-deep crud-form .crud-form-control.error div.crud-form-control:not(.error) .p-dropdown,::ng-deep crud-form .crud-form-control.error div.crud-form-control:not(.error) .p-inputtext,::ng-deep crud-form .crud-form-control.error div.crud-form-control:not(.error) .p-multiselect,::ng-deep crud-form .crud-form-control.error div.crud-form-control:not(.error) .tn-dropdown,::ng-deep crud-form .crud-form-control.error div.crud-form-control:not(.error) input,::ng-deep crud-form .crud-form-control.error div.crud-form-control:not(.error) select,::ng-deep crud-form .crud-form-control.error div.crud-form-control:not(.error) textarea{border-color:#ced4da!important}::ng-deep crud-form .crud-form-control.error div.crud-form-control:not(.error) .p-autocomplete-multiple-container:not(.p-disabled).p-focus,::ng-deep crud-form .crud-form-control.error div.crud-form-control:not(.error) .p-dropdown.tn-dropdown.p-focus,::ng-deep crud-form .crud-form-control.error div.crud-form-control:not(.error) .p-inputtext:enabled:focus{box-shadow:0 0 0 .2rem #a6d5fa}::ng-deep crud-form .crud-form-container{padding:.5rem .5rem 0}::ng-deep crud-form .p-datatable .p-datatable-tbody tr td.control-inside,::ng-deep crud-form .p-datatable .p-datatable-tbody tr td.control-inside .show-in-box:not(.crud-form-control),::ng-deep crud-form base-congviec-form crud-form>.crud-form-container{padding:0}@media screen and (min-width:768px){::ng-deep crud-form .grid{display:grid;grid-template-columns:repeat(12,minmax(0,1fr))}::ng-deep crud-form .grid .p-md-1{width:unset;grid-column:span 1}::ng-deep crud-form .grid .p-md-2{width:unset;grid-column:span 2}::ng-deep crud-form .grid .p-md-3{width:unset;grid-column:span 3}::ng-deep crud-form .grid .p-md-4{width:unset;grid-column:span 4}::ng-deep crud-form .grid .p-md-5{width:unset;grid-column:span 5}::ng-deep crud-form .grid .p-md-6{width:unset;grid-column:span 6}::ng-deep crud-form .grid .p-md-7{width:unset;grid-column:span 7}::ng-deep crud-form .grid .p-md-8{width:unset;grid-column:span 8}::ng-deep crud-form .grid .p-md-9{width:unset;grid-column:span 9}::ng-deep crud-form .grid .p-md-10{width:unset;grid-column:span 10}::ng-deep crud-form .grid .p-md-11{width:unset;grid-column:span 11}::ng-deep crud-form .grid .p-md-12{width:unset;grid-column:span 12}::ng-deep crud-form .grid .row-span-1{grid-row:span 1}::ng-deep crud-form .grid .row-span-2{grid-row:span 2}::ng-deep crud-form .grid .row-span-3{grid-row:span 3}::ng-deep crud-form .grid .row-span-4{grid-row:span 4}::ng-deep crud-form .grid .row-span-5{grid-row:span 5}::ng-deep crud-form .grid .row-span-6{grid-row:span 6}::ng-deep crud-form .grid .row-span-7{grid-row:span 7}::ng-deep crud-form .grid .row-span-8{grid-row:span 8}::ng-deep crud-form .grid .row-span-9{grid-row:span 9}::ng-deep crud-form .grid .row-span-10{grid-row:span 10}::ng-deep crud-form .grid .row-span-11{grid-row:span 11}::ng-deep crud-form .grid .row-span-12{grid-row:span 12}::ng-deep crud-form .grid .row-span-13{grid-row:span 13}::ng-deep crud-form .grid .row-span-14{grid-row:span 14}::ng-deep crud-form .grid .row-span-15{grid-row:span 15}::ng-deep crud-form .grid .row-span-16{grid-row:span 16}::ng-deep crud-form .grid .row-span-17{grid-row:span 17}::ng-deep crud-form .grid .row-span-18{grid-row:span 18}::ng-deep crud-form .grid .row-span-19{grid-row:span 19}::ng-deep crud-form .grid .row-span-20{grid-row:span 20}::ng-deep crud-form .grid .row-span-21{grid-row:span 21}::ng-deep crud-form .grid .row-span-22{grid-row:span 22}::ng-deep crud-form .grid .row-span-23{grid-row:span 23}::ng-deep crud-form .grid .row-span-24{grid-row:span 24}::ng-deep crud-form .grid .row-span-25{grid-row:span 25}::ng-deep crud-form .grid .row-span-26{grid-row:span 26}::ng-deep crud-form .grid .row-span-27{grid-row:span 27}::ng-deep crud-form .grid .row-span-28{grid-row:span 28}::ng-deep crud-form .grid .row-span-29{grid-row:span 29}::ng-deep crud-form .grid .row-span-30{grid-row:span 30}::ng-deep crud-form .grid .row-span-31{grid-row:span 31}::ng-deep crud-form .grid .row-span-32{grid-row:span 32}::ng-deep crud-form .grid .row-span-33{grid-row:span 33}::ng-deep crud-form .grid .row-span-34{grid-row:span 34}::ng-deep crud-form .grid .row-span-35{grid-row:span 35}::ng-deep crud-form .grid .row-span-36{grid-row:span 36}::ng-deep crud-form .grid .row-span-37{grid-row:span 37}::ng-deep crud-form .grid .row-span-38{grid-row:span 38}::ng-deep crud-form .grid .row-span-39{grid-row:span 39}::ng-deep crud-form .grid .row-span-40{grid-row:span 40}::ng-deep crud-form .grid .row-span-41{grid-row:span 41}::ng-deep crud-form .grid .row-span-42{grid-row:span 42}::ng-deep crud-form .grid .row-span-43{grid-row:span 43}::ng-deep crud-form .grid .row-span-44{grid-row:span 44}::ng-deep crud-form .grid .row-span-45{grid-row:span 45}::ng-deep crud-form .grid .row-span-46{grid-row:span 46}::ng-deep crud-form .grid .row-span-47{grid-row:span 47}::ng-deep crud-form .grid .row-span-48{grid-row:span 48}::ng-deep crud-form .grid .row-span-49{grid-row:span 49}::ng-deep crud-form .grid .row-span-50{grid-row:span 50}}:host ::ng-deep .tox-tinymce{border:none;border-top:1px solid #ccc;overflow:unset}:host ::ng-deep .tox-tinymce .tox-editor-container{overflow:unset}:host ::ng-deep .tox-tinymce .tox-toolbar{border:1px solid #ccc;border-bottom:none}:host ::ng-deep .tox-tinymce .tox-edit-area{border:1px solid #ccc}:host ::ng-deep .tox-tinymce .tox-edit-area iframe{box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}:host ::ng-deep .tox-tinymce .tox-menubar{border:1px solid #ccc}:host ::ng-deep .tox .tox-edit-area.tinymce-focus{border:1px solid #66afe9;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 3px 0 #66afe9;transition:box-shadow .3s,border-color .3s;transition-property:box-shadow,border-color;transition-duration:.3s,.3s;transition-timing-function:ease,ease;transition-delay:0s,0s}:host ::ng-deep .rq .tox .tox-edit-area{border-left-color:#ff4c46}:host ::ng-deep .table-schema-paging{margin-bottom:40px;display:block}"]
14855
14855
  },] }
@@ -31881,7 +31881,7 @@ FileManagerComponent.decorators = [
31881
31881
  { type: Component, args: [{
31882
31882
  // tslint:disable-next-line: component-selector
31883
31883
  selector: 'file-manager',
31884
- template: "<div *ngIf=\"layout == _layout.LIST\" class=\"full-layout p-grid\">\n <div *ngIf=\"visibleFolder && !control.uploadOnly\" class=\"tree-layout\"\n [class]=\"visibleFolder ? 'p-col-12 p-lg-2' : '' \">\n <div class=\"tree-layout-btn\">\n <button *ngIf=\"!hiddenCreateFolder && !readonly\" pButton pRipple type=\"button\" pTooltip=\"T\u1EA1o th\u01B0 m\u1EE5c m\u1EDBi\"\n tooltipPosition=\"top\" icon=\"pi pi-folder\" class=\"p-button-text\" label=\"T\u1EA1o th\u01B0 m\u1EE5c\" iconPos=\"left\"\n (click)=\"createFolder()\">\n </button>\n </div>\n <div class=\"tree-layout-wrapper\">\n <perfect-scrollbar #scrollbar class=\"defaulFlexColumn treeOrg\" [config]=\"{suppressScrollX : true}\">\n <p-tree class=\"folderTree\" selectionMode=\"single\" [style]=\"{ 'width' : '100%'}\"\n [(selection)]=\"selectedTreeNode\" [value]=\"rootTreeNode\" [contextMenu]=\"contextMenu\"\n (onNodeSelect)=\"nodeSelect($event)\">\n <ng-template let-node pTemplate=\"default\">\n <span [id]=\"node.data\" class=\"custom-node\"\n (contextmenu)=\"showContextMenu($event, node, true)\">{{node.label}}</span>\n </ng-template>\n </p-tree>\n </perfect-scrollbar>\n </div>\n </div>\n <div class=\"fm-grid\" [class]=\"visibleFolder ? 'p-col-12 p-lg-10' : 'p-col-12' \">\n <crud-list #crudList [model]=\"model\" [setting]=\"setting\" [dataSource]=\"_dataSource\"\n [disableKeypressControl]=\"true\" [showScrollBar]=\"false\" class=\"--auto-height-content --no-wrapper-padding\"\n [widthFunctionColumn]=\"'8.2rem'\" [showScrollHorizontal]=\"true\" (onReload)=\"_triggerProcessData($event)\"\n (onRowSelect)=\"onRowSelect($event)\">\n <ng-template #customTitle>\n <ng-container *ngTemplateOutlet=\"breadCrumb\"></ng-container>\n </ng-template>\n <ng-template #toolbar>\n <button *ngIf=\"!control.uploadOnly\" pButton pRipple type=\"button\"\n [pTooltip]=\"visibleFolder == true ? '\u1EA8n c\u00E2y th\u01B0 m\u1EE5c' : 'Hi\u1EC7n c\u00E2y th\u01B0 m\u1EE5c'\" tooltipPosition=\"top\"\n [icon]=\"visibleFolder ? 'far fa-eye-slash': 'far fa-eye'\" class=\"p-button-text\"\n [label]=\"visibleFolder == true ? '\u1EA8n c\u00E2y th\u01B0 m\u1EE5c' : 'Hi\u1EC7n c\u00E2y th\u01B0 m\u1EE5c'\" iconPos=\"left\"\n (click)=\"changeVisibleFolder()\">\n </button>\n\n <button *ngIf=\"!hiddenCreateFolder && !readonly && !visibleFolder && !control.uploadOnly\" pButton\n pRipple type=\"button\" pTooltip=\"T\u1EA1o th\u01B0 m\u1EE5c m\u1EDBi\" tooltipPosition=\"top\" icon=\"pi pi-folder\"\n class=\"p-button-text\" label=\"T\u1EA1o th\u01B0 m\u1EE5c\" iconPos=\"left\" (click)=\"createFolder()\">\n </button>\n\n <button *ngIf=\"!readonly\" pButton icon=\"pi pi-cloud-upload\" pTooltip=\"T\u1EA3i t\u1EC7p tin t\u1EEB m\u00E1y t\u00EDnh c\u1EE7a b\u1EA1n\"\n tooltipPosition=\"top\" type=\"button\" class=\"p-button-text p-button-primary\" label=\"T\u1EA3i l\u00EAn\"\n (click)=\"selectFile()\"></button>\n\n <button *ngIf=\"!readonly && !control.uploadOnly\" pButton icon=\"pi pi-link\"\n pTooltip=\"T\u1EA3i t\u1EEB li\u00EAn k\u1EBFt trong h\u1EC7 th\u1ED1ng\" tooltipPosition=\"top\" type=\"button\"\n class=\"p-button-text p-button-primary\" label=\"T\u1EA3i li\u00EAn k\u1EBFt\"\n (click)=\"showAttachLinkBox = true\"></button>\n\n <button *ngIf=\"!inTaiLieu && !inTaiLieuChung && !readonly && !control.uploadOnly && !filePickerSetting\"\n pButton icon=\"pi pi-book\" pTooltip=\"Sao ch\u00E9p t\u1EEB t\u00E0i li\u1EC7u d\u00F9ng chung ho\u1EB7c c\u00E1 nh\u00E2n\"\n tooltipPosition=\"top\" type=\"button\" class=\"p-button-text\" label=\"T\u00E0i li\u1EC7u\"\n (click)=\"showTaiLieuDungChung = true;\">\n </button>\n\n <button *ngIf=\"filePickerSetting && !filePickerSetting.isHidden\" pButton icon=\"pi pi-book\"\n pTooltip=\"{{filePickerSetting.title}}\" tooltipPosition=\"top\" type=\"button\" class=\"p-button-text\"\n label=\"{{filePickerSetting.title}}\" (click)=\"showPickerTaiLieu()\">\n </button>\n\n <button *ngIf=\"canSelect() && !control.uploadOnly\" class=\"p-button-text p-button-success\" pButton\n type=\"button\" pTooltip=\"Di chuy\u1EC3n th\u01B0 m\u1EE5c/t\u1EC7p tin \u0111\u00E3 ch\u1ECDn\" tooltipPosition=\"top\"\n icon=\"fas fa-arrows-alt\" iconPos=\"left\" label=\"Di chuy\u1EC3n\" (click)=\"moveExplorerItems()\">\n </button>\n\n <button *ngIf=\"canSetMove() && !control.uploadOnly\" class=\"p-button-text p-button-success\" pButton\n type=\"button\" pTooltip=\"Di chuy\u1EC3n th\u01B0 m\u1EE5c/t\u1EC7p tin \u0111\u00E3 ch\u1ECDn t\u1EDBi \u0111\u00E2y\" tooltipPosition=\"top\"\n icon=\"far fa-hand-paper\" iconPos=\"left\" label=\"\u0110\u1EB7t t\u1EA1i \u0111\u00E2y\" (click)=\"setMoveExplorerItems()\">\n </button>\n\n <button *ngIf=\"canSetMove() && !control.uploadOnly\" icon=\"pi pi-undo\" pButton\n class=\"p-button-text p-button-secondary\" type=\"button\"\n pTooltip=\"B\u1ECF di chuy\u1EC3n th\u01B0 m\u1EE5c/t\u1EC7p tin \u0111\u00E3 ch\u1ECDn\" tooltipPosition=\"top\" label=\"B\u1ECF qua\"\n (click)=\"cancelMove()\">\n </button>\n\n <button *ngIf=\"hasSelect() && !readonly\" pButton type=\"button\"\n pTooltip=\"{{ 'X\u00F3a th\u01B0 m\u1EE5c/t\u1EC7p tin \u0111\u00E3 ch\u1ECDn' | translate }}\" tooltipPosition=\"top\" icon=\"pi pi-trash\"\n iconPos=\"left\" class=\"p-button-text p-button-danger\" label=\"X\u00F3a\"\n (click)=\"deleteMutiple(model.selectedItems)\"></button>\n\n <button *ngIf=\"hasSelect() && !control.uploadOnly\" class=\"p-button-text p-button-secondary\" pButton\n type=\"button\" pTooltip=\"N\u00E9n & t\u1EA3i v\u1EC1\" tooltipPosition=\"top\" icon=\"fas fa-file-archive\"\n iconPos=\"left\" label=\"T\u1EA3i v\u1EC1\" (click)=\"downloadMultiple()\">\n </button>\n </ng-template>\n\n <ng-template #explorerItem let-rowData='rowData' let-col='col'>\n <div style=\"display: flex; align-items: center;\">\n <span *ngIf=\"rowData.tailFileUpper != '.JPG'\n && rowData.tailFileUpper != '.JPEG' && rowData.tailFileUpper != '.PNG' \"\n (click)=\"openObject(rowData)\" class=\"pull-left file-ex-icon\" style=\"display: flex;\"\n [innerHTML]=\"rowData.name | fileIcon : !rowData.isFile\">\n </span>\n\n <span *ngIf=\"rowData.isFile && (rowData.tailFileUpper == '.JPG'\n || rowData.tailFileUpper == '.JPEG' || rowData.tailFileUpper == '.PNG' )\"\n (click)=\"openObject(rowData)\" class=\"file-ex-thumbnail\" style=\"display: flex;\">\n <img class=\"thumbnail-img\" [src]=\"getPathImage(rowData.id)\" width=\"50px\" [alt]=\"rowData.name\"\n style=\"margin-right: 7px;\" />\n </span>\n\n <span (click)=\"openObject(rowData)\" class=\"{{rowData.class}} file-ex-name\">\n {{rowData.name}}\n </span>\n\n <span *ngIf=\"rowData.signatures\" class=\"pull-right signature\" pTooltip=\"Xem chi ti\u1EBFt k\u00FD s\u1ED1\"\n tooltipPosition=\"top\" (click)=\"viewListSign($event, rowData.signatures)\">\n <i class=\"fas fa-signature\"></i>\n </span>\n </div>\n </ng-template>\n\n <!-- <ng-template #thumbnail let-rowData=\"rowData\" let-col=\"col\">\n <div style=\"text-align: center;\">\n <img *ngIf=\"rowData.isFile && (rowData.tailFile.toUpperCase() == '.JPG'\n || rowData.tailFile.toUpperCase() == '.JPEG' || rowData.tailFile.toUpperCase() == '.PNG' )\"\n class=\"thumbnail-img\" [src]=\"getPathImage(rowData.id)\" width=\"100px\" [alt]=\"rowData.name\" />\n </div>\n </ng-template> -->\n\n <ng-template #fileSize let-rowData='rowData'>\n <div *ngIf=\"rowData.isFile\">{{rowData.fileSize | fileSize}}</div>\n </ng-template>\n\n <ng-template #function let-rowData=\"rowData\" let-crudList=\"crudList\">\n <div class=\"function-list\">\n <ng-container *ngIf=\"!readonly\">\n <button *ngIf=\"!control.uploadOnly\" class=\"p-button-rounded p-button-text link-or-action\"\n pButton type=\"button\" tooltipPosition=\"top\" pTooltip=\"{{getButtonTooltip(rowData)}}\"\n icon=\"{{getButtonIcon(rowData)}}\" (click)=\"onButtonClick(rowData)\"></button>\n\n <button *ngIf=\"control.showDelete\"\n class=\"p-button-danger p-button-rounded p-button-text link-or-action\" pButton type=\"button\"\n pTooltip=\"X\u00F3a\" tooltipPosition=\"top\" icon=\"pi pi-trash\"\n (click)=\"deleteFile(rowData)\"></button>\n\n <button type=\"button\" pButton icon=\"pi pi-ellipsis-v\"\n class=\"link-or-action p-button-text p-button-rounded\" pTooltip=\"Th\u00EAm\" tooltipPosition=\"top\"\n (click)=\"showContextMenu($event, rowData)\"></button>\n </ng-container>\n <button *ngIf=\"readonly\" class=\"p-button-secondary p-button-rounded p-button-text link-or-action\"\n pButton type=\"button\" pTooltip=\"T\u1EA3i v\u1EC1\" tooltipPosition=\"top\" icon=\"pi pi-cloud-download\"\n (click)=\"download(rowData)\"></button>\n <button *ngIf=\"readonly\" class=\"p-button-secondary p-button-rounded p-button-text link-or-action\"\n pButton type=\"button\" pTooltip=\"Sao ch\u00E9p \u0111\u01B0\u1EDDng d\u1EABn\" tooltipPosition=\"top\" icon=\"pi pi-link\"\n (click)=\"copyDownloadLink(rowData)\"></button>\n </div>\n </ng-template>\n </crud-list>\n </div>\n</div>\n\n<div *ngIf=\"layout == _layout.SIMPLE\" class=\"not-full-layout\" [class.readonly]=\"readonly\">\n <div *ngIf=\"!readonly || data.breadcrumbs.length > 0\" class=\"fm-toolbar\">\n <div class=\"fm-toolbar-buttons\">\n <ng-container *ngIf=\"!readonly\">\n <button *ngIf=\"!hiddenCreateFolder && !control.uploadOnly\" (click)=\"createFolder()\" pButton pRipple\n type=\"button\" pTooltip=\"T\u1EA1o th\u01B0 m\u1EE5c m\u1EDBi\" tooltipPosition=\"top\" icon=\"pi pi-folder\"\n class=\"p-button-text\" label=\"T\u1EA1o th\u01B0 m\u1EE5c\" iconPos=\"left\">\n </button>\n <button type=\"button\" pButton class=\"p-button-text p-button-info link-or-action\"\n icon=\"pi pi-cloud-upload\" (click)=\"selectFile()\" label=\"T\u1EA3i l\u00EAn\"></button>\n <button *ngIf=\"!control.uploadOnly\" pButton icon=\"pi pi-link\" pTooltip=\"T\u1EA3i t\u1EEB li\u00EAn k\u1EBFt trong h\u1EC7 th\u1ED1ng\"\n tooltipPosition=\"top\" type=\"button\" class=\"p-button-text p-button-primary\" label=\"T\u1EA3i li\u00EAn k\u1EBFt\"\n (click)=\"showAttachLinkBox = true\"></button>\n <button *ngIf=\"!inTaiLieu && !control.uploadOnly\" pButton icon=\"pi pi-book\"\n pTooltip=\"T\u00E0i li\u1EC7u d\u00F9ng chung\" tooltipPosition=\"top\" type=\"button\" class=\"p-button-text\"\n label=\"T\u00E0i li\u1EC7u\" (click)=\"showTaiLieuDungChung = true;\">\n </button>\n </ng-container>\n </div>\n <ng-container *ngTemplateOutlet=\"breadCrumb\"></ng-container>\n </div>\n\n <div class=\"nfl-grid\">\n <ng-container *ngIf=\"_dataSource && _dataSource.length > 0\">\n <div *ngFor=\"let rowData of _dataSource; index as i\" class=\"nfl-item\">\n <div class=\"nfl-no\">\n {{i + 1}}.\n </div>\n\n <div class=\"nfl-name\">\n <span class=\"pull-left file-ex-icon\" [innerHTML]=\"rowData.name | fileIcon : !rowData.isFile\">\n </span>\n <a (click)=\"openObject(rowData)\" class=\"{{rowData.class}} file-ex-name\">\n <span>\n <span>{{rowData.name}}</span>\n </span>\n </a>\n </div>\n <div *ngIf=\"rowData.signatures\" class=\"nfl-signature signature\" pTooltip=\"Xem chi ti\u1EBFt k\u00FD s\u1ED1\"\n tooltipPosition=\"top\" (click)=\"viewListSign($event, rowData.signatures)\">\n <i class=\"fas fa-signature\"></i>\n </div>\n <div *ngIf=\"rowData.isFile\" class=\"nfl-version\">\n v{{rowData.currentFileVersion}}\n </div>\n\n <div class=\"nfl-function\">\n <ng-container *ngIf=\"!readonly\">\n <button *ngIf=\"!control.uploadOnly\" class=\"p-button-rounded p-button-text link-or-action\"\n (click)=\"onButtonClick(rowData)\" pButton type=\"button\" tooltipPosition=\"top\"\n pTooltip=\"{{getButtonTooltip(rowData)}}\" icon=\"{{getButtonIcon(rowData)}}\"></button>\n\n <button *ngIf=\"control.showDelete\"\n class=\"p-button-danger p-button-rounded p-button-text link-or-action\"\n (click)=\"deleteFile(rowData)\" pButton type=\"button\" pTooltip=\"X\u00F3a\" tooltipPosition=\"top\"\n icon=\"pi pi-trash\"></button>\n </ng-container>\n\n <button *ngIf=\"readonly\" class=\"p-button-secondary p-button-rounded p-button-text link-or-action\"\n (click)=\"download(rowData)\" pButton type=\"button\" pTooltip=\"T\u1EA3i v\u1EC1\" tooltipPosition=\"top\"\n icon=\"pi pi-cloud-download\"></button>\n <button *ngIf=\"readonly\" class=\"p-button-secondary p-button-rounded p-button-text link-or-action\"\n pButton type=\"button\" pTooltip=\"Sao ch\u00E9p \u0111\u01B0\u1EDDng d\u1EABn\" tooltipPosition=\"top\" icon=\"pi pi-link\"\n (click)=\"copyDownloadLink(rowData)\"></button>\n <button *ngIf=\"rowData.hasContextMenu\" type=\"button\" pButton icon=\"pi pi-ellipsis-v\"\n class=\"link-or-action p-button-text p-button-rounded\" pTooltip=\"Th\u00EAm\" tooltipPosition=\"top\"\n (click)=\"showContextMenu($event, rowData)\"></button>\n </div>\n </div>\n </ng-container>\n <div *ngIf=\"!_dataSource || !_dataSource.length\" class=\"nfl-no-item\">\n {{ noFileMessage }}\n </div>\n </div>\n</div>\n\n<div *ngIf=\"layout == _layout.SIMPLE_FOR_LIST\" class=\"not-full-layout\" [class.readonly]=\"readonly\">\n <div *ngIf=\"!readonly || data.breadcrumbs.length > 0\" class=\"fm-toolbar\">\n <div class=\"fm-toolbar-buttons\">\n <ng-container *ngIf=\"!readonly\">\n <button *ngIf=\"!hiddenCreateFolder && !control.uploadOnly\" (click)=\"createFolder()\" pButton pRipple\n type=\"button\" pTooltip=\"T\u1EA1o th\u01B0 m\u1EE5c m\u1EDBi\" tooltipPosition=\"top\" icon=\"pi pi-folder\"\n class=\"p-button-text\" label=\"T\u1EA1o th\u01B0 m\u1EE5c\" iconPos=\"left\">\n </button>\n <button type=\"button\" pButton class=\"p-button-text p-button-info link-or-action\"\n icon=\"pi pi-cloud-upload\" (click)=\"selectFile()\" label=\"T\u1EA3i l\u00EAn\"></button>\n <button *ngIf=\"!control.uploadOnly\" pButton icon=\"pi pi-link\" pTooltip=\"T\u1EA3i t\u1EEB li\u00EAn k\u1EBFt trong h\u1EC7 th\u1ED1ng\"\n tooltipPosition=\"top\" type=\"button\" class=\"p-button-text p-button-primary\" label=\"T\u1EA3i li\u00EAn k\u1EBFt\"\n (click)=\"showAttachLinkBox = true\"></button>\n <button *ngIf=\"!inTaiLieu && !control.uploadOnly\" pButton icon=\"pi pi-book\"\n pTooltip=\"T\u00E0i li\u1EC7u d\u00F9ng chung\" tooltipPosition=\"top\" type=\"button\" class=\"p-button-text\"\n label=\"T\u00E0i li\u1EC7u\" (click)=\"showTaiLieuDungChung = true;\">\n </button>\n </ng-container>\n </div>\n <ng-container *ngTemplateOutlet=\"breadCrumb\"></ng-container>\n </div>\n\n <div class=\"nfl-grid\">\n <ng-container *ngIf=\"_dataSource && _dataSource.length > 0\">\n <div *ngFor=\"let rowData of _dataSource; index as i\" class=\"nfl-item\">\n <div class=\"nfl-no\">\n {{i + 1}}.\n </div>\n\n <div class=\"nfl-name\">\n <span class=\"pull-left file-ex-icon\" [innerHTML]=\"rowData.name | fileIcon : !rowData.isFile\">\n </span>\n\n <a *ngIf=\"!disabled\" class=\"{{rowData.class}} file-ex-name\" (click)=\"openObject(rowData)\">\n <span>\n <span>{{rowData.name}}</span>\n </span>\n </a>\n\n <a *ngIf=\"disabled\" class=\"{{rowData.class}} file-ex-name\">\n <span>\n <span>{{rowData.name}}</span>\n </span>\n </a>\n </div>\n\n <div class=\"nfl-function\">\n <ng-container *ngIf=\"!readonly\">\n <button *ngIf=\"!control.uploadOnly\" class=\"p-button-rounded p-button-text link-or-action\"\n (click)=\"onButtonClick(rowData)\" pButton type=\"button\" tooltipPosition=\"top\"\n pTooltip=\"{{getButtonTooltip(rowData)}}\" icon=\"{{getButtonIcon(rowData)}}\"></button>\n\n <button *ngIf=\"control.showDelete\"\n class=\"p-button-danger p-button-rounded p-button-text link-or-action\"\n (click)=\"deleteFile(rowData)\" pButton type=\"button\" pTooltip=\"X\u00F3a\" tooltipPosition=\"top\"\n icon=\"pi pi-trash\"></button>\n </ng-container>\n <button type=\"button\" pButton icon=\"pi pi-ellipsis-v\"\n class=\"link-or-action p-button-text p-button-rounded\" pTooltip=\"Th\u00EAm\" tooltipPosition=\"top\"\n [disabled]=\"disabled\" (click)=\"showContextMenu($event, rowData)\"></button>\n </div>\n </div>\n </ng-container>\n <div *ngIf=\"!_dataSource || !_dataSource.length\" class=\"nfl-no-item\">\n {{ noFileMessage }}\n </div>\n </div>\n</div>\n\n<ng-template #breadCrumb>\n <div *ngIf=\"data.breadcrumbs.length > 1\" class=\"fm-toolbar-path\">\n <p-breadcrumb class=\"customBreadCrumb\" [model]=\"data.breadcrumbs\"></p-breadcrumb>\n </div>\n</ng-template>\n\n<p-fileUpload #fileControl [ngStyle]=\"{'display': 'none'}\" mode=\"basic\" [chooseLabel]=\"chooseLabel\" [name]=\"fileInForm\"\n [url]=\"apiUploadUrl\" auto=\"true\" [invalidFileSizeMessageSummary]=\"invalidFileSizeMessageSummary\"\n [invalidFileSizeMessageDetail]=\"invalidFileSizeMessageDetail\"\n [invalidFileTypeMessageSummary]=\"invalidFileTypeMessageSummary\"\n [invalidFileTypeMessageDetail]=\"invalidFileTypeMessageDetail\"\n [invalidFileLimitMessageSummary]=\"invalidFileLimitMessageSummary\"\n [invalidFileLimitMessageDetail]=\"invalidFileLimitMessageDetail\" [accept]=\"accept\" [multiple]=\"control.multiple\"\n (onProgress)=\"onUploadProgress($event)\" (onBeforeUpload)=\"onBeforeUpload($event)\"\n (onSelect)=\"handleSelectFile($event)\" (onUpload)=\"onUploaded($event)\" (onError)=\"handleError($event)\">\n</p-fileUpload>\n<p-contextMenu *ngIf=\"data.itemsMenuFile && data.itemsMenuFile.length > 0\" #contextMenu [appendTo]=\"'body'\"\n [model]=\"data.itemsMenuFile\" styleClass=\"fm-contextMenu-panel\">\n</p-contextMenu>\n\n<!-- T\u1EA1o m\u1EDBi/ \u0111\u1ED5i t\u00EAn th\u01B0 m\u1EE5c -->\n<tn-dialog *ngIf=\"forms.createFolder.show\" #dialog [styleClass]=\"'address-form'\"\n [header]=\"forms.createFolder.header | translate\" [popupSize]=\"forms[formIds.createFolder].popupSize\"\n (onHide)=\"onCancelForm(formIds.createFolder)\">\n <folder-form #formBase [parentModel]=\"model\" [parentContext]=\"context\"\n [model]=\"forms[formIds.createFolder].formData\" (onSaved)=\"onSavedForm(formIds.createFolder)\"\n (onCancel)=\"onCancelForm(formIds.createFolder)\">\n </folder-form>\n</tn-dialog>\n\n<!-- \u0110\u1ED5i t\u00EAn file -->\n<tn-dialog *ngIf=\"forms.renameFile.show\" #dialog [styleClass]=\"'address-form'\"\n [header]=\"forms.renameFile.header | translate\" [popupSize]=\"forms[formIds.renameFile].popupSize\"\n (onHide)=\"onCancelForm(formIds.renameFile)\">\n <file-form #formBase [parentModel]=\"model\" [parentContext]=\"context\" [model]=\"forms[formIds.renameFile].formData\"\n (onSaved)=\"onSavedForm(formIds.renameFile)\" (onCancel)=\"onCancelForm(formIds.renameFile)\">\n </file-form>\n</tn-dialog>\n\n<!-- Xem file tr\u1EF1c tuy\u1EBFn -->\n<file-viewer *ngIf=\"forms.fileViewer.show\" [parentModel]=\"model\" [parentContext]=\"context\" [readonly]=\"readonly\"\n [model]=\"forms.fileViewer.formData\" (onClose)=\"closeFileViewer()\">\n</file-viewer>\n\n<!-- Xem phi\u00EAn b\u1EA3n -->\n<tn-dialog *ngIf=\"forms.fileVersionList.show\" #dialog [styleClass]=\"'address-form'\"\n [header]=\"forms.fileVersionList.header | translate\" [popupSize]=\"forms[formIds.fileVersionList].popupSize\"\n (onHide)=\"onCancelForm(formIds.fileVersionList)\">\n <file-version-list *ngIf=\"forms.fileVersionList.show\" [parentModel]=\"model\" [parentContext]=\"context\"\n [fileId]=\"forms[formIds.fileVersionList].fileId\" [readonly]=\"readonly\"\n (onSetMajorVersion)=\"_triggerProcessData()\">\n </file-version-list>\n</tn-dialog>\n\n<tn-dialog *ngIf=\"showAttachLinkBox\" #dialog2 [maximizable]=\"false\" [header]=\"'Nh\u1EADp li\u00EAn k\u1EBFt' | translate\"\n [popupSize]=\"{ width: 600, height: 50}\" (onHide)=\"showAttachLinkBox = false; typedLink=''\">\n <div class=\"p-col-12\">\n <div class=\"p-grid\">\n <div class=\"p-md-10\">\n <input #input type=\"text\" placeholder=\"Nh\u1EADp li\u00EAn k\u1EBFt sao ch\u00E9p t\u1EEB t\u1EC7p tin kh\u00E1c...\"\n (keyup.enter)=\"addAttachLink()\" pInputText [(ngModel)]=\"typedLink\" class=\"p-col-12\" />\n </div>\n <div class=\"p-md-2\">\n <button type=\"button\" (click)=\"addAttachLink()\" [disabled]=\"typedLink != ''? null : true\" pButton\n class=\"p-button-primary p-col-12\" label=\"Ok\"></button>\n </div>\n </div>\n </div>\n <after-view-checked (loaded)=\"focusInput(input)\"></after-view-checked>\n</tn-dialog>\n\n<tn-dialog #dialog3 *ngIf=\"showTaiLieuDungChung\" [header]=\"'T\u00E0i li\u1EC7u' |translate\"\n [popupSize]=\"{ width:1200, height: 650 }\" (onHide)=\"showTaiLieuDungChung = false\">\n <file-tai-lieu #formBase [originalFolderId]=\"data.currentFolderId\" [filePickerSetting]=\"filePickerSetting\"\n (onSaved)=\"showTaiLieuDungChung = false; this._triggerProcessData()\" (onCancel)=\"showTaiLieuDungChung = false\">\n </file-tai-lieu>\n</tn-dialog>\n\n<!--\n\n<share-file *ngIf=\"forms.shareFile.show\" [parentDataModel]=\"model\" [parentDataContext]=\"context\"\n [model]=\"forms.shareFile.formData\">\n</share-file>\n\n<share-folder *ngIf=\"forms.shareFolder.show\" [parentDataModel]=\"model\" [parentDataContext]=\"context\"\n [model]=\"forms.shareFolder.formData\">\n</share-folder>\n -->\n\n<!-- Xem ch\u1EEF k\u00FD s\u1ED1 -->\n<tn-dialog *ngIf=\"forms.signatureDetail.show\" #dialog [styleClass]=\"'address-form'\"\n [header]=\"forms.signatureDetail.header | translate\" [popupSize]=\"forms[formIds.signatureDetail].popupSize\"\n (onHide)=\"onCancelForm(formIds.signatureDetail)\">\n <signature-detail [parentModel]=\"model\" [parentContext]=\"context\">\n </signature-detail>\n</tn-dialog>\n\n<!--K\u00FD s\u1ED1 sim-->\n<tn-dialog *ngIf=\"forms.kySoSim.show\" #dialog [styleClass]=\"'address-form'\" [header]=\"forms.kySoSim.header | translate\"\n [popupSize]=\"forms.kySoSim.popupSize\" [showFooter]=\"true\" (onHide)=\"onCancelForm(formIds.kySoSim)\">\n <app-file-ky-so-sim #fileKySoSim [parentModel]=\"model\" [parentContext]=\"context\">\n </app-file-ky-so-sim>\n <ng-template #footer>\n <button type=\"button\" pButton icon=\"fas fa-images\" [disabled]=\"model.submitting\" class=\"p-button-text\"\n [label]=\"'Ch\u1ECDn ch\u1EEF k\u00FD' | translate\" (click)=\"chonChuKy()\"></button>\n <button type=\"button\" pButton icon=\"fas fa-signature\" class=\"p-button-text ui-button-success\"\n [disabled]=\"model.submitting\" [label]=\"'Th\u1EF1c hi\u1EC7n k\u00FD' | translate\" (click)=\"kySo()\"></button>\n <button type=\"button\" pButton icon=\"pi pi-replay\" class=\"p-button-text p-button-secondary\"\n [label]=\"'FORM.CANCEL' | translate\" preventTab (click)=\"forms.kySoSim.show=false\"></button>\n </ng-template>\n</tn-dialog>\n\n<!-- Xem chi ti\u1EBFt -->\n<tn-dialog *ngIf=\"forms.viewDetail.show\" #dialog [styleClass]=\"'address-form'\"\n [header]=\"forms.viewDetail.header | translate\" [popupSize]=\"forms[formIds.viewDetail].popupSize\"\n (onHide)=\"onCancelForm(formIds.viewDetail)\">\n <view-detail #formBase [parentModel]=\"model\" [parentContext]=\"context\" [model]=\"forms.viewDetail.formData\"\n (onCancel)=\"onCancelForm(formIds.viewDetail)\">\n </view-detail>\n</tn-dialog>",
31884
+ template: "<div *ngIf=\"layout == _layout.LIST\" class=\"full-layout p-grid\">\n <div *ngIf=\"visibleFolder && !control.uploadOnly\" class=\"tree-layout\"\n [class]=\"visibleFolder ? 'p-col-12 p-lg-2' : '' \">\n <div class=\"tree-layout-btn\">\n <button *ngIf=\"!hiddenCreateFolder && !readonly\" pButton pRipple type=\"button\" pTooltip=\"T\u1EA1o th\u01B0 m\u1EE5c m\u1EDBi\"\n tooltipPosition=\"top\" icon=\"pi pi-folder\" class=\"p-button-text\" label=\"T\u1EA1o th\u01B0 m\u1EE5c\" iconPos=\"left\"\n (click)=\"createFolder()\">\n </button>\n </div>\n <div class=\"tree-layout-wrapper\">\n <perfect-scrollbar #scrollbar class=\"defaulFlexColumn treeOrg\" [config]=\"{suppressScrollX : true}\">\n <p-tree class=\"folderTree\" selectionMode=\"single\" [style]=\"{ 'width' : '100%'}\"\n [(selection)]=\"selectedTreeNode\" [value]=\"rootTreeNode\" [contextMenu]=\"contextMenu\"\n (onNodeSelect)=\"nodeSelect($event)\">\n <ng-template let-node pTemplate=\"default\">\n <span [id]=\"node.data\" class=\"custom-node\"\n (contextmenu)=\"showContextMenu($event, node, true)\">{{node.label}}</span>\n </ng-template>\n </p-tree>\n </perfect-scrollbar>\n </div>\n </div>\n <div class=\"fm-grid\" [class]=\"visibleFolder ? 'p-col-12 p-lg-10' : 'p-col-12' \">\n <crud-list #crudList [model]=\"model\" [setting]=\"setting\" [dataSource]=\"_dataSource\"\n [disableKeypressControl]=\"true\" [showScrollBar]=\"false\" class=\"--auto-height-content --no-wrapper-padding\"\n [widthFunctionColumn]=\"'8.2rem'\" [showScrollHorizontal]=\"true\" (onReload)=\"_triggerProcessData($event)\"\n (onRowSelect)=\"onRowSelect($event)\">\n <ng-template #customTitle>\n <ng-container *ngTemplateOutlet=\"breadCrumb\"></ng-container>\n </ng-template>\n <ng-template #toolbar>\n <button *ngIf=\"!control.uploadOnly\" pButton pRipple type=\"button\"\n [pTooltip]=\"visibleFolder == true ? '\u1EA8n c\u00E2y th\u01B0 m\u1EE5c' : 'Hi\u1EC7n c\u00E2y th\u01B0 m\u1EE5c'\" tooltipPosition=\"top\"\n [icon]=\"visibleFolder ? 'far fa-eye-slash': 'far fa-eye'\" class=\"p-button-text\"\n [label]=\"visibleFolder == true ? '\u1EA8n c\u00E2y th\u01B0 m\u1EE5c' : 'Hi\u1EC7n c\u00E2y th\u01B0 m\u1EE5c'\" iconPos=\"left\"\n (click)=\"changeVisibleFolder()\">\n </button>\n\n <button *ngIf=\"!hiddenCreateFolder && !readonly && !visibleFolder && !control.uploadOnly\" pButton\n pRipple type=\"button\" pTooltip=\"T\u1EA1o th\u01B0 m\u1EE5c m\u1EDBi\" tooltipPosition=\"top\" icon=\"pi pi-folder\"\n class=\"p-button-text\" label=\"T\u1EA1o th\u01B0 m\u1EE5c\" iconPos=\"left\" (click)=\"createFolder()\">\n </button>\n\n <button *ngIf=\"!readonly\" pButton icon=\"pi pi-cloud-upload\" pTooltip=\"T\u1EA3i t\u1EC7p tin t\u1EEB m\u00E1y t\u00EDnh c\u1EE7a b\u1EA1n\"\n tooltipPosition=\"top\" type=\"button\" class=\"p-button-text p-button-primary\" label=\"T\u1EA3i l\u00EAn\"\n (click)=\"selectFile()\"></button>\n\n <button *ngIf=\"!readonly && !control.uploadOnly\" pButton icon=\"pi pi-link\"\n pTooltip=\"T\u1EA3i t\u1EEB li\u00EAn k\u1EBFt trong h\u1EC7 th\u1ED1ng\" tooltipPosition=\"top\" type=\"button\"\n class=\"p-button-text p-button-primary\" label=\"T\u1EA3i li\u00EAn k\u1EBFt\"\n (click)=\"showAttachLinkBox = true\"></button>\n\n <button *ngIf=\"!inTaiLieu && !inTaiLieuChung && !readonly && !control.uploadOnly && !filePickerSetting\"\n pButton icon=\"pi pi-book\" pTooltip=\"Sao ch\u00E9p t\u1EEB t\u00E0i li\u1EC7u d\u00F9ng chung ho\u1EB7c c\u00E1 nh\u00E2n\"\n tooltipPosition=\"top\" type=\"button\" class=\"p-button-text\" label=\"T\u00E0i li\u1EC7u\"\n (click)=\"showTaiLieuDungChung = true;\">\n </button>\n\n <button *ngIf=\"filePickerSetting && !filePickerSetting.isHidden\" pButton icon=\"pi pi-book\"\n pTooltip=\"{{filePickerSetting.title}}\" tooltipPosition=\"top\" type=\"button\" class=\"p-button-text\"\n label=\"{{filePickerSetting.title}}\" (click)=\"showPickerTaiLieu()\">\n </button>\n\n <button *ngIf=\"canSelect() && !control.uploadOnly\" class=\"p-button-text p-button-success\" pButton\n type=\"button\" pTooltip=\"Di chuy\u1EC3n th\u01B0 m\u1EE5c/t\u1EC7p tin \u0111\u00E3 ch\u1ECDn\" tooltipPosition=\"top\"\n icon=\"fas fa-arrows-alt\" iconPos=\"left\" label=\"Di chuy\u1EC3n\" (click)=\"moveExplorerItems()\">\n </button>\n\n <button *ngIf=\"canSetMove() && !control.uploadOnly\" class=\"p-button-text p-button-success\" pButton\n type=\"button\" pTooltip=\"Di chuy\u1EC3n th\u01B0 m\u1EE5c/t\u1EC7p tin \u0111\u00E3 ch\u1ECDn t\u1EDBi \u0111\u00E2y\" tooltipPosition=\"top\"\n icon=\"far fa-hand-paper\" iconPos=\"left\" label=\"\u0110\u1EB7t t\u1EA1i \u0111\u00E2y\" (click)=\"setMoveExplorerItems()\">\n </button>\n\n <button *ngIf=\"canSetMove() && !control.uploadOnly\" icon=\"pi pi-undo\" pButton\n class=\"p-button-text p-button-secondary\" type=\"button\"\n pTooltip=\"B\u1ECF di chuy\u1EC3n th\u01B0 m\u1EE5c/t\u1EC7p tin \u0111\u00E3 ch\u1ECDn\" tooltipPosition=\"top\" label=\"B\u1ECF qua\"\n (click)=\"cancelMove()\">\n </button>\n\n <button *ngIf=\"hasSelect() && !readonly\" pButton type=\"button\"\n pTooltip=\"{{ 'X\u00F3a th\u01B0 m\u1EE5c/t\u1EC7p tin \u0111\u00E3 ch\u1ECDn' | translate }}\" tooltipPosition=\"top\" icon=\"pi pi-trash\"\n iconPos=\"left\" class=\"p-button-text p-button-danger\" label=\"X\u00F3a\"\n (click)=\"deleteMutiple(model.selectedItems)\"></button>\n\n <button *ngIf=\"hasSelect() && !control.uploadOnly\" class=\"p-button-text p-button-secondary\" pButton\n type=\"button\" pTooltip=\"N\u00E9n & t\u1EA3i v\u1EC1\" tooltipPosition=\"top\" icon=\"fas fa-file-archive\"\n iconPos=\"left\" label=\"T\u1EA3i v\u1EC1\" (click)=\"downloadMultiple()\">\n </button>\n </ng-template>\n\n <ng-template #explorerItem let-rowData='rowData' let-col='col'>\n <div style=\"display: flex; align-items: center;\">\n <span *ngIf=\"rowData.tailFileUpper != '.JPG'\n && rowData.tailFileUpper != '.JPEG' && rowData.tailFileUpper != '.PNG' \"\n (click)=\"openObject(rowData)\" class=\"pull-left file-ex-icon\" style=\"display: flex;\"\n [innerHTML]=\"rowData.name | fileIcon : !rowData.isFile\">\n </span>\n\n <span *ngIf=\"rowData.isFile && (rowData.tailFileUpper == '.JPG'\n || rowData.tailFileUpper == '.JPEG' || rowData.tailFileUpper == '.PNG' )\"\n (click)=\"openObject(rowData)\" class=\"file-ex-thumbnail\" style=\"display: flex;\">\n <img class=\"thumbnail-img\" [src]=\"getPathImage(rowData.id)\" width=\"50px\" [alt]=\"rowData.name\"\n style=\"margin-right: 7px;\" />\n </span>\n\n <span (click)=\"openObject(rowData)\" class=\"{{rowData.class}} file-ex-name\">\n {{rowData.name}}\n </span>\n\n <span *ngIf=\"rowData.signatures\" class=\"pull-right signature\" pTooltip=\"Xem chi ti\u1EBFt k\u00FD s\u1ED1\"\n tooltipPosition=\"top\" (click)=\"viewListSign($event, rowData.signatures)\">\n <i class=\"fas fa-signature\"></i>\n </span>\n </div>\n </ng-template>\n\n <!-- <ng-template #thumbnail let-rowData=\"rowData\" let-col=\"col\">\n <div style=\"text-align: center;\">\n <img *ngIf=\"rowData.isFile && (rowData.tailFile.toUpperCase() == '.JPG'\n || rowData.tailFile.toUpperCase() == '.JPEG' || rowData.tailFile.toUpperCase() == '.PNG' )\"\n class=\"thumbnail-img\" [src]=\"getPathImage(rowData.id)\" width=\"100px\" [alt]=\"rowData.name\" />\n </div>\n </ng-template> -->\n\n <ng-template #fileSize let-rowData='rowData'>\n <div *ngIf=\"rowData.isFile\">{{rowData.fileSize | fileSize}}</div>\n </ng-template>\n\n <ng-template #function let-rowData=\"rowData\" let-crudList=\"crudList\">\n <div class=\"function-list\">\n <ng-container *ngIf=\"!readonly\">\n <button *ngIf=\"!control.uploadOnly\" class=\"p-button-rounded p-button-text link-or-action\"\n pButton type=\"button\" tooltipPosition=\"top\" pTooltip=\"{{getButtonTooltip(rowData)}}\"\n icon=\"{{getButtonIcon(rowData)}}\" (click)=\"onButtonClick(rowData)\"></button>\n\n <button *ngIf=\"control.showDelete\"\n class=\"p-button-danger p-button-rounded p-button-text link-or-action\" pButton type=\"button\"\n pTooltip=\"X\u00F3a\" tooltipPosition=\"top\" icon=\"pi pi-trash\"\n (click)=\"deleteFile(rowData)\"></button>\n\n <button type=\"button\" pButton icon=\"pi pi-ellipsis-v\"\n class=\"link-or-action p-button-text p-button-rounded\" pTooltip=\"Th\u00EAm\" tooltipPosition=\"top\"\n (click)=\"showContextMenu($event, rowData)\"></button>\n </ng-container>\n <button *ngIf=\"readonly\" class=\"p-button-secondary p-button-rounded p-button-text link-or-action\"\n pButton type=\"button\" pTooltip=\"T\u1EA3i v\u1EC1\" tooltipPosition=\"top\" icon=\"pi pi-cloud-download\"\n (click)=\"download(rowData)\"></button>\n <button *ngIf=\"readonly\" class=\"p-button-secondary p-button-rounded p-button-text link-or-action\"\n pButton type=\"button\" pTooltip=\"Sao ch\u00E9p \u0111\u01B0\u1EDDng d\u1EABn\" tooltipPosition=\"top\" icon=\"pi pi-link\"\n (click)=\"copyDownloadLink(rowData)\"></button>\n </div>\n </ng-template>\n </crud-list>\n </div>\n</div>\n\n<div *ngIf=\"layout == _layout.SIMPLE\" class=\"not-full-layout\" [class.readonly]=\"readonly\">\n <div *ngIf=\"!readonly || data.breadcrumbs.length > 0\" class=\"fm-toolbar\">\n <div class=\"fm-toolbar-buttons\">\n <ng-container *ngIf=\"!readonly\">\n <button *ngIf=\"!hiddenCreateFolder && !control.uploadOnly\" (click)=\"createFolder()\" pButton pRipple\n type=\"button\" [pTooltip]=\"'T\u1EA1o th\u01B0 m\u1EE5c m\u1EDBi' | translate\" tooltipPosition=\"top\" icon=\"pi pi-folder\"\n class=\"p-button-text\" [label]=\"'T\u1EA1o th\u01B0 m\u1EE5c' | translate\" iconPos=\"left\">\n </button>\n <button type=\"button\" pButton class=\"p-button-text p-button-info link-or-action\"\n [pTooltip]=\"'T\u1EA3i l\u00EAn'| translate\" icon=\"pi pi-cloud-upload\" (click)=\"selectFile()\"\n [label]=\"'T\u1EA3i l\u00EAn'| translate\"></button>\n <button *ngIf=\"!control.uploadOnly\" pButton icon=\"pi pi-link\"\n [pTooltip]=\"'T\u1EA3i t\u1EEB li\u00EAn k\u1EBFt trong h\u1EC7 th\u1ED1ng'| translate\" tooltipPosition=\"top\" type=\"button\"\n class=\"p-button-text p-button-primary\" [label]=\"'T\u1EA3i li\u00EAn k\u1EBFt'| translate\"\n (click)=\"showAttachLinkBox = true\"></button>\n <button *ngIf=\"!inTaiLieu && !control.uploadOnly\" pButton icon=\"pi pi-book\"\n [pTooltip]=\"'T\u00E0i li\u1EC7u d\u00F9ng chung'|translate\" tooltipPosition=\"top\" type=\"button\"\n class=\"p-button-text\" [label]=\"'T\u00E0i li\u1EC7u d\u00F9ng chung'|translate\"\n (click)=\"showTaiLieuDungChung = true;\">\n </button>\n </ng-container>\n </div>\n <ng-container *ngTemplateOutlet=\"breadCrumb\"></ng-container>\n </div>\n\n <div class=\"nfl-grid\">\n <ng-container *ngIf=\"_dataSource && _dataSource.length > 0\">\n <div *ngFor=\"let rowData of _dataSource; index as i\" class=\"nfl-item\">\n <div class=\"nfl-no\">\n {{i + 1}}.\n </div>\n\n <div class=\"nfl-name\">\n <span class=\"pull-left file-ex-icon\" [innerHTML]=\"rowData.name | fileIcon : !rowData.isFile\">\n </span>\n <a (click)=\"openObject(rowData)\" class=\"{{rowData.class}} file-ex-name\">\n <span>\n <span>{{rowData.name}}</span>\n </span>\n </a>\n </div>\n <div *ngIf=\"rowData.signatures\" class=\"nfl-signature signature\" pTooltip=\"Xem chi ti\u1EBFt k\u00FD s\u1ED1\"\n tooltipPosition=\"top\" (click)=\"viewListSign($event, rowData.signatures)\">\n <i class=\"fas fa-signature\"></i>\n </div>\n <div *ngIf=\"rowData.isFile\" class=\"nfl-version\">\n v{{rowData.currentFileVersion}}\n </div>\n\n <div class=\"nfl-function\">\n <ng-container *ngIf=\"!readonly\">\n <button *ngIf=\"!control.uploadOnly\" class=\"p-button-rounded p-button-text link-or-action\"\n (click)=\"onButtonClick(rowData)\" pButton type=\"button\" tooltipPosition=\"top\"\n pTooltip=\"{{getButtonTooltip(rowData)}}\" icon=\"{{getButtonIcon(rowData)}}\"></button>\n\n <button *ngIf=\"control.showDelete\"\n class=\"p-button-danger p-button-rounded p-button-text link-or-action\"\n (click)=\"deleteFile(rowData)\" pButton type=\"button\" pTooltip=\"X\u00F3a\" tooltipPosition=\"top\"\n icon=\"pi pi-trash\"></button>\n </ng-container>\n\n <button *ngIf=\"readonly\" class=\"p-button-secondary p-button-rounded p-button-text link-or-action\"\n (click)=\"download(rowData)\" pButton type=\"button\" pTooltip=\"T\u1EA3i v\u1EC1\" tooltipPosition=\"top\"\n icon=\"pi pi-cloud-download\"></button>\n <button *ngIf=\"readonly\" class=\"p-button-secondary p-button-rounded p-button-text link-or-action\"\n pButton type=\"button\" pTooltip=\"Sao ch\u00E9p \u0111\u01B0\u1EDDng d\u1EABn\" tooltipPosition=\"top\" icon=\"pi pi-link\"\n (click)=\"copyDownloadLink(rowData)\"></button>\n <button *ngIf=\"rowData.hasContextMenu\" type=\"button\" pButton icon=\"pi pi-ellipsis-v\"\n class=\"link-or-action p-button-text p-button-rounded\" pTooltip=\"Th\u00EAm\" tooltipPosition=\"top\"\n (click)=\"showContextMenu($event, rowData)\"></button>\n </div>\n </div>\n </ng-container>\n <div *ngIf=\"!_dataSource || !_dataSource.length\" class=\"nfl-no-item\">\n {{ noFileMessage }}\n </div>\n </div>\n</div>\n\n<div *ngIf=\"layout == _layout.SIMPLE_FOR_LIST\" class=\"not-full-layout\" [class.readonly]=\"readonly\">\n <div *ngIf=\"!readonly || data.breadcrumbs.length > 0\" class=\"fm-toolbar\">\n <div class=\"fm-toolbar-buttons\">\n <ng-container *ngIf=\"!readonly\">\n <button *ngIf=\"!hiddenCreateFolder && !control.uploadOnly\" (click)=\"createFolder()\" pButton pRipple\n type=\"button\" [pTooltip]=\"'T\u1EA1o th\u01B0 m\u1EE5c m\u1EDBi' | translate\" tooltipPosition=\"top\" icon=\"pi pi-folder\"\n class=\"p-button-text\" [label]=\"'T\u1EA1o th\u01B0 m\u1EE5c' | translate\" iconPos=\"left\">\n </button>\n <button type=\"button\" pButton class=\"p-button-text p-button-info link-or-action\"\n icon=\"pi pi-cloud-upload\" (click)=\"selectFile()\" [label]=\"'T\u1EA3i l\u00EAn'| translate\"\n [pTooltip]=\"'T\u1EA3i l\u00EAn'| translate\"></button>\n <button *ngIf=\"!control.uploadOnly\" pButton icon=\"pi pi-link\"\n [pTooltip]=\"'T\u1EA3i t\u1EEB li\u00EAn k\u1EBFt trong h\u1EC7 th\u1ED1ng'| translate\" tooltipPosition=\"top\" type=\"button\"\n class=\"p-button-text p-button-primary\" [label]=\"'T\u1EA3i li\u00EAn k\u1EBFt'| translate\"\n (click)=\"showAttachLinkBox = true\"></button>\n <button *ngIf=\"!inTaiLieu && !control.uploadOnly\" pButton icon=\"pi pi-book\"\n [pTooltip]=\"'T\u00E0i li\u1EC7u d\u00F9ng chung'|translate\" tooltipPosition=\"top\" type=\"button\"\n class=\"p-button-text\" [label]=\"'T\u00E0i li\u1EC7u d\u00F9ng chung'|translate\"\n (click)=\"showTaiLieuDungChung = true;\">\n </button>\n </ng-container>\n </div>\n <ng-container *ngTemplateOutlet=\"breadCrumb\"></ng-container>\n </div>\n\n <div class=\"nfl-grid\">\n <ng-container *ngIf=\"_dataSource && _dataSource.length > 0\">\n <div *ngFor=\"let rowData of _dataSource; index as i\" class=\"nfl-item\">\n <div class=\"nfl-no\">\n {{i + 1}}.\n </div>\n\n <div class=\"nfl-name\">\n <span class=\"pull-left file-ex-icon\" [innerHTML]=\"rowData.name | fileIcon : !rowData.isFile\">\n </span>\n\n <a *ngIf=\"!disabled\" class=\"{{rowData.class}} file-ex-name\" (click)=\"openObject(rowData)\">\n <span>\n <span>{{rowData.name}}</span>\n </span>\n </a>\n\n <a *ngIf=\"disabled\" class=\"{{rowData.class}} file-ex-name\">\n <span>\n <span>{{rowData.name}}</span>\n </span>\n </a>\n </div>\n\n <div class=\"nfl-function\">\n <ng-container *ngIf=\"!readonly\">\n <button *ngIf=\"!control.uploadOnly\" class=\"p-button-rounded p-button-text link-or-action\"\n (click)=\"onButtonClick(rowData)\" pButton type=\"button\" tooltipPosition=\"top\"\n pTooltip=\"{{getButtonTooltip(rowData)}}\" icon=\"{{getButtonIcon(rowData)}}\"></button>\n\n <button *ngIf=\"control.showDelete\"\n class=\"p-button-danger p-button-rounded p-button-text link-or-action\"\n (click)=\"deleteFile(rowData)\" pButton type=\"button\" pTooltip=\"X\u00F3a\" tooltipPosition=\"top\"\n icon=\"pi pi-trash\"></button>\n </ng-container>\n <button type=\"button\" pButton icon=\"pi pi-ellipsis-v\"\n class=\"link-or-action p-button-text p-button-rounded\" pTooltip=\"Th\u00EAm\" tooltipPosition=\"top\"\n [disabled]=\"disabled\" (click)=\"showContextMenu($event, rowData)\"></button>\n </div>\n </div>\n </ng-container>\n <div *ngIf=\"!_dataSource || !_dataSource.length\" class=\"nfl-no-item\">\n {{ noFileMessage }}\n </div>\n </div>\n</div>\n\n<ng-template #breadCrumb>\n <div *ngIf=\"data.breadcrumbs.length > 1\" class=\"fm-toolbar-path\">\n <p-breadcrumb class=\"customBreadCrumb\" [model]=\"data.breadcrumbs\"></p-breadcrumb>\n </div>\n</ng-template>\n\n<p-fileUpload #fileControl [ngStyle]=\"{'display': 'none'}\" mode=\"basic\" [chooseLabel]=\"chooseLabel\" [name]=\"fileInForm\"\n [url]=\"apiUploadUrl\" auto=\"true\" [invalidFileSizeMessageSummary]=\"invalidFileSizeMessageSummary\"\n [invalidFileSizeMessageDetail]=\"invalidFileSizeMessageDetail\"\n [invalidFileTypeMessageSummary]=\"invalidFileTypeMessageSummary\"\n [invalidFileTypeMessageDetail]=\"invalidFileTypeMessageDetail\"\n [invalidFileLimitMessageSummary]=\"invalidFileLimitMessageSummary\"\n [invalidFileLimitMessageDetail]=\"invalidFileLimitMessageDetail\" [accept]=\"accept\" [multiple]=\"control.multiple\"\n (onProgress)=\"onUploadProgress($event)\" (onBeforeUpload)=\"onBeforeUpload($event)\"\n (onSelect)=\"handleSelectFile($event)\" (onUpload)=\"onUploaded($event)\" (onError)=\"handleError($event)\">\n</p-fileUpload>\n<p-contextMenu *ngIf=\"data.itemsMenuFile && data.itemsMenuFile.length > 0\" #contextMenu [appendTo]=\"'body'\"\n [model]=\"data.itemsMenuFile\" styleClass=\"fm-contextMenu-panel\">\n</p-contextMenu>\n\n<!-- T\u1EA1o m\u1EDBi/ \u0111\u1ED5i t\u00EAn th\u01B0 m\u1EE5c -->\n<tn-dialog *ngIf=\"forms.createFolder.show\" #dialog [styleClass]=\"'address-form'\"\n [header]=\"forms.createFolder.header | translate\" [popupSize]=\"forms[formIds.createFolder].popupSize\"\n (onHide)=\"onCancelForm(formIds.createFolder)\">\n <folder-form #formBase [parentModel]=\"model\" [parentContext]=\"context\"\n [model]=\"forms[formIds.createFolder].formData\" (onSaved)=\"onSavedForm(formIds.createFolder)\"\n (onCancel)=\"onCancelForm(formIds.createFolder)\">\n </folder-form>\n</tn-dialog>\n\n<!-- \u0110\u1ED5i t\u00EAn file -->\n<tn-dialog *ngIf=\"forms.renameFile.show\" #dialog [styleClass]=\"'address-form'\"\n [header]=\"forms.renameFile.header | translate\" [popupSize]=\"forms[formIds.renameFile].popupSize\"\n (onHide)=\"onCancelForm(formIds.renameFile)\">\n <file-form #formBase [parentModel]=\"model\" [parentContext]=\"context\" [model]=\"forms[formIds.renameFile].formData\"\n (onSaved)=\"onSavedForm(formIds.renameFile)\" (onCancel)=\"onCancelForm(formIds.renameFile)\">\n </file-form>\n</tn-dialog>\n\n<!-- Xem file tr\u1EF1c tuy\u1EBFn -->\n<file-viewer *ngIf=\"forms.fileViewer.show\" [parentModel]=\"model\" [parentContext]=\"context\" [readonly]=\"readonly\"\n [model]=\"forms.fileViewer.formData\" (onClose)=\"closeFileViewer()\">\n</file-viewer>\n\n<!-- Xem phi\u00EAn b\u1EA3n -->\n<tn-dialog *ngIf=\"forms.fileVersionList.show\" #dialog [styleClass]=\"'address-form'\"\n [header]=\"forms.fileVersionList.header | translate\" [popupSize]=\"forms[formIds.fileVersionList].popupSize\"\n (onHide)=\"onCancelForm(formIds.fileVersionList)\">\n <file-version-list *ngIf=\"forms.fileVersionList.show\" [parentModel]=\"model\" [parentContext]=\"context\"\n [fileId]=\"forms[formIds.fileVersionList].fileId\" [readonly]=\"readonly\"\n (onSetMajorVersion)=\"_triggerProcessData()\">\n </file-version-list>\n</tn-dialog>\n\n<tn-dialog *ngIf=\"showAttachLinkBox\" #dialog2 [maximizable]=\"false\" [header]=\"'Nh\u1EADp li\u00EAn k\u1EBFt' | translate\"\n [popupSize]=\"{ width: 600, height: 50}\" (onHide)=\"showAttachLinkBox = false; typedLink=''\">\n <div class=\"p-col-12\">\n <div class=\"p-grid\">\n <div class=\"p-md-10\">\n <input #input type=\"text\" placeholder=\"Nh\u1EADp li\u00EAn k\u1EBFt sao ch\u00E9p t\u1EEB t\u1EC7p tin kh\u00E1c...\"\n (keyup.enter)=\"addAttachLink()\" pInputText [(ngModel)]=\"typedLink\" class=\"p-col-12\" />\n </div>\n <div class=\"p-md-2\">\n <button type=\"button\" (click)=\"addAttachLink()\" [disabled]=\"typedLink != ''? null : true\" pButton\n class=\"p-button-primary p-col-12\" label=\"Ok\"></button>\n </div>\n </div>\n </div>\n <after-view-checked (loaded)=\"focusInput(input)\"></after-view-checked>\n</tn-dialog>\n\n<tn-dialog #dialog3 *ngIf=\"showTaiLieuDungChung\" [header]=\"'T\u00E0i li\u1EC7u' |translate\"\n [popupSize]=\"{ width:1200, height: 650 }\" (onHide)=\"showTaiLieuDungChung = false\">\n <file-tai-lieu #formBase [originalFolderId]=\"data.currentFolderId\" [filePickerSetting]=\"filePickerSetting\"\n (onSaved)=\"showTaiLieuDungChung = false; this._triggerProcessData()\" (onCancel)=\"showTaiLieuDungChung = false\">\n </file-tai-lieu>\n</tn-dialog>\n\n<!--\n\n<share-file *ngIf=\"forms.shareFile.show\" [parentDataModel]=\"model\" [parentDataContext]=\"context\"\n [model]=\"forms.shareFile.formData\">\n</share-file>\n\n<share-folder *ngIf=\"forms.shareFolder.show\" [parentDataModel]=\"model\" [parentDataContext]=\"context\"\n [model]=\"forms.shareFolder.formData\">\n</share-folder>\n -->\n\n<!-- Xem ch\u1EEF k\u00FD s\u1ED1 -->\n<tn-dialog *ngIf=\"forms.signatureDetail.show\" #dialog [styleClass]=\"'address-form'\"\n [header]=\"forms.signatureDetail.header | translate\" [popupSize]=\"forms[formIds.signatureDetail].popupSize\"\n (onHide)=\"onCancelForm(formIds.signatureDetail)\">\n <signature-detail [parentModel]=\"model\" [parentContext]=\"context\">\n </signature-detail>\n</tn-dialog>\n\n<!--K\u00FD s\u1ED1 sim-->\n<tn-dialog *ngIf=\"forms.kySoSim.show\" #dialog [styleClass]=\"'address-form'\" [header]=\"forms.kySoSim.header | translate\"\n [popupSize]=\"forms.kySoSim.popupSize\" [showFooter]=\"true\" (onHide)=\"onCancelForm(formIds.kySoSim)\">\n <app-file-ky-so-sim #fileKySoSim [parentModel]=\"model\" [parentContext]=\"context\">\n </app-file-ky-so-sim>\n <ng-template #footer>\n <button type=\"button\" pButton icon=\"fas fa-images\" [disabled]=\"model.submitting\" class=\"p-button-text\"\n [label]=\"'Ch\u1ECDn ch\u1EEF k\u00FD' | translate\" (click)=\"chonChuKy()\"></button>\n <button type=\"button\" pButton icon=\"fas fa-signature\" class=\"p-button-text ui-button-success\"\n [disabled]=\"model.submitting\" [label]=\"'Th\u1EF1c hi\u1EC7n k\u00FD' | translate\" (click)=\"kySo()\"></button>\n <button type=\"button\" pButton icon=\"pi pi-replay\" class=\"p-button-text p-button-secondary\"\n [label]=\"'FORM.CANCEL' | translate\" preventTab (click)=\"forms.kySoSim.show=false\"></button>\n </ng-template>\n</tn-dialog>\n\n<!-- Xem chi ti\u1EBFt -->\n<tn-dialog *ngIf=\"forms.viewDetail.show\" #dialog [styleClass]=\"'address-form'\"\n [header]=\"forms.viewDetail.header | translate\" [popupSize]=\"forms[formIds.viewDetail].popupSize\"\n (onHide)=\"onCancelForm(formIds.viewDetail)\">\n <view-detail #formBase [parentModel]=\"model\" [parentContext]=\"context\" [model]=\"forms.viewDetail.formData\"\n (onCancel)=\"onCancelForm(formIds.viewDetail)\">\n </view-detail>\n</tn-dialog>",
31885
31885
  providers: [
31886
31886
  {
31887
31887
  provide: NG_VALUE_ACCESSOR,
@@ -34151,15 +34151,260 @@ UserPickerDialogComponent.propDecorators = {
34151
34151
  control: [{ type: Input }]
34152
34152
  };
34153
34153
 
34154
+ class GenericGuardChildService {
34155
+ constructor(_userService, _permissionService, _router, _injector, _notifierService) {
34156
+ this._userService = _userService;
34157
+ this._permissionService = _permissionService;
34158
+ this._router = _router;
34159
+ this._injector = _injector;
34160
+ this._notifierService = _notifierService;
34161
+ this.storage = sessionStorage;
34162
+ }
34163
+ canActivateChild(route, state) {
34164
+ return new Promise((resolve) => __awaiter(this, void 0, void 0, function* () {
34165
+ const _applicationContext = this._injector.get(ApplicationContextService);
34166
+ const root = _applicationContext.getRootContext();
34167
+ if (state.url == '/') {
34168
+ resolve(true);
34169
+ return;
34170
+ }
34171
+ if ((top.location.href.indexOf('/dashboard') > -1)
34172
+ || (top.location.href.indexOf('/access-denied') > -1)) {
34173
+ resolve(true);
34174
+ return;
34175
+ }
34176
+ // todo: còn case sử dụng biến trong url
34177
+ const service = root.data.currentAppMetadata.code;
34178
+ const permission = `${root.data.currentAppMetadata.code}${state.url.split('#')[0].split('?')[0]}`.toUpperCase();
34179
+ const isAuthorized = yield this._permissionService.isAuthorized(service, permission);
34180
+ if (isAuthorized) {
34181
+ resolve(true);
34182
+ }
34183
+ else {
34184
+ const firstTimeLogin = localStorage.getItem('firstTimeLogin');
34185
+ if (firstTimeLogin && firstTimeLogin !== '' && firstTimeLogin == 'true') {
34186
+ localStorage.removeItem('firstTimeLogin');
34187
+ top.location.href = '/';
34188
+ }
34189
+ else {
34190
+ top.location.href = window['baseHref'] + '/access-denied';
34191
+ }
34192
+ resolve(false);
34193
+ }
34194
+ resolve(true);
34195
+ }));
34196
+ }
34197
+ }
34198
+ GenericGuardChildService.ɵprov = i0.ɵɵdefineInjectable({ factory: function GenericGuardChildService_Factory() { return new GenericGuardChildService(i0.ɵɵinject(UserService), i0.ɵɵinject(PermissionService), i0.ɵɵinject(i3$1.Router), i0.ɵɵinject(i0.INJECTOR), i0.ɵɵinject(NotifierService)); }, token: GenericGuardChildService, providedIn: "root" });
34199
+ GenericGuardChildService.decorators = [
34200
+ { type: Injectable, args: [{
34201
+ providedIn: 'root'
34202
+ },] }
34203
+ ];
34204
+ GenericGuardChildService.ctorParameters = () => [
34205
+ { type: UserService },
34206
+ { type: PermissionService },
34207
+ { type: Router },
34208
+ { type: Injector },
34209
+ { type: NotifierService }
34210
+ ];
34211
+
34212
+ class GenericGuardService {
34213
+ constructor(_permissionService, _injector) {
34214
+ this._permissionService = _permissionService;
34215
+ this._injector = _injector;
34216
+ this.storage = sessionStorage;
34217
+ }
34218
+ canActivate(route, state) {
34219
+ return new Promise((resolve) => __awaiter(this, void 0, void 0, function* () {
34220
+ const _applicationContext = this._injector.get(ApplicationContextService);
34221
+ const root = _applicationContext.getRootContext();
34222
+ if (state.url == '/') {
34223
+ resolve(true);
34224
+ return;
34225
+ }
34226
+ if ((top.location.href.indexOf('/dashboard') > -1)
34227
+ || (top.location.href.indexOf('/access-denied') > -1)) {
34228
+ resolve(true);
34229
+ return;
34230
+ }
34231
+ // todo: còn case sử dụng biến trong url
34232
+ const service = root.data.currentAppMetadata.code;
34233
+ const permission = `${root.data.currentAppMetadata.code}${state.url.split('#')[0].split('?')[0]}`.toUpperCase();
34234
+ const isAuthorized = yield this._permissionService.isAuthorized(service, permission);
34235
+ if (isAuthorized) {
34236
+ resolve(true);
34237
+ }
34238
+ else {
34239
+ // this._notifierService.showWarning('Bạn không có quyền truy cập vào trang này', 'Cảnh báo');
34240
+ const firstTimeLogin = localStorage.getItem('firstTimeLogin');
34241
+ if (firstTimeLogin && firstTimeLogin !== '' && firstTimeLogin == 'true') {
34242
+ localStorage.removeItem('firstTimeLogin');
34243
+ top.location.href = '/';
34244
+ }
34245
+ else {
34246
+ top.location.href = '/access-denied';
34247
+ }
34248
+ resolve(false);
34249
+ }
34250
+ resolve(true);
34251
+ }));
34252
+ }
34253
+ }
34254
+ GenericGuardService.ɵprov = i0.ɵɵdefineInjectable({ factory: function GenericGuardService_Factory() { return new GenericGuardService(i0.ɵɵinject(PermissionService), i0.ɵɵinject(i0.INJECTOR)); }, token: GenericGuardService, providedIn: "root" });
34255
+ GenericGuardService.decorators = [
34256
+ { type: Injectable, args: [{
34257
+ providedIn: 'root'
34258
+ },] }
34259
+ ];
34260
+ GenericGuardService.ctorParameters = () => [
34261
+ { type: PermissionService },
34262
+ { type: Injector }
34263
+ ];
34264
+
34265
+ class StorageService {
34266
+ constructor(_moduleConfigService) {
34267
+ this._moduleConfigService = _moduleConfigService;
34268
+ this.ignoreBuildInCacheKey = /(expires_at|id_token_expires_at|nonce|access_token_stored_at|id_token_stored_at|id_token|access_token|id_token_claims_obj|session_state|granted_scopes)/i;
34269
+ const st = this._moduleConfigService.getConfig().environment.storage;
34270
+ if (st === 'sessionStorage') {
34271
+ this.storage = sessionStorage;
34272
+ }
34273
+ else {
34274
+ this.storage = localStorage;
34275
+ }
34276
+ }
34277
+ setStorage(storage) {
34278
+ this.storage = storage;
34279
+ }
34280
+ getStorage() {
34281
+ return this.storage;
34282
+ }
34283
+ setItem(key, value) {
34284
+ if (!value) {
34285
+ this.storage.setItem(key, null);
34286
+ }
34287
+ if (value instanceof Object) {
34288
+ this.storage.setItem(key, JSON.stringify(value));
34289
+ }
34290
+ else {
34291
+ this.storage.setItem(key, value ? value.toString() : null);
34292
+ }
34293
+ }
34294
+ removeItem(key) {
34295
+ this.storage.removeItem(key);
34296
+ if (key.startsWith('v4_')) {
34297
+ this.storage.removeItem(key.replace('v4_', ''));
34298
+ }
34299
+ else {
34300
+ this.storage.removeItem('v4_' + key);
34301
+ }
34302
+ }
34303
+ removeByPattern(pattern) {
34304
+ this.getCacheKeysByPattern(pattern).forEach(item => {
34305
+ this.removeItem(item);
34306
+ if (item.startsWith('v4_')) {
34307
+ this.storage.removeItem(item.replace('v4_', ''));
34308
+ }
34309
+ else {
34310
+ this.storage.removeItem('v4_' + item);
34311
+ }
34312
+ });
34313
+ }
34314
+ getItem(key) {
34315
+ return this.storage.getItem(key);
34316
+ }
34317
+ getNumber(key, defaultValueIfNull = 0) {
34318
+ const rs = this.getItem(key);
34319
+ if (rs) {
34320
+ return +rs;
34321
+ }
34322
+ return defaultValueIfNull;
34323
+ }
34324
+ getBoolean(key, defaultValueIfNull = false) {
34325
+ const rs = this.getItem(key);
34326
+ if (rs) {
34327
+ return rs.toLowerCase() === 'true';
34328
+ }
34329
+ return defaultValueIfNull;
34330
+ }
34331
+ getObject(key) {
34332
+ const rs = this.getItem(key);
34333
+ if (rs) {
34334
+ return JSON.parse(rs);
34335
+ }
34336
+ return null;
34337
+ }
34338
+ getObjectAny(key) {
34339
+ const rs = this.getItem(key);
34340
+ if (rs) {
34341
+ return JSON.parse(rs);
34342
+ }
34343
+ return null;
34344
+ }
34345
+ getAllCachekeys() {
34346
+ return Object.keys(this.storage).filter(x => !x.match(this.ignoreBuildInCacheKey));
34347
+ }
34348
+ getCacheKeysByPattern(pattern) {
34349
+ return Object.keys(this.storage).filter(x => !x.match(this.ignoreBuildInCacheKey) && this.matchRuleShort(pattern, x));
34350
+ }
34351
+ matchRuleShort(str, rule) {
34352
+ const escapeRegex = (str) => str.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, '\\$1');
34353
+ return new RegExp('^' + rule.split('*').map(escapeRegex).join('.*') + '$').test(str);
34354
+ }
34355
+ // Explanation code
34356
+ matchRuleExpl(str, rule) {
34357
+ // for this solution to work on any string, no matter what characters it has
34358
+ const escapeRegex = (str) => str.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, '\\$1');
34359
+ // "." => Find a single character, except newline or line terminator
34360
+ // ".*" => Matches any string that contains zero or more characters
34361
+ rule = rule.split('*').map(escapeRegex).join('.*');
34362
+ // "^" => Matches any string with the following at the beginning of it
34363
+ // "$" => Matches any string with that in front at the end of it
34364
+ rule = '^' + rule + '$';
34365
+ // Create a regular expression object for matching string
34366
+ const regex = new RegExp(rule);
34367
+ // Returns true if it finds a match, otherwise it returns false
34368
+ return regex.test(str);
34369
+ }
34370
+ }
34371
+ StorageService.ɵprov = i0.ɵɵdefineInjectable({ factory: function StorageService_Factory() { return new StorageService(i0.ɵɵinject(ModuleConfigService)); }, token: StorageService, providedIn: "root" });
34372
+ StorageService.decorators = [
34373
+ { type: Injectable, args: [{
34374
+ providedIn: 'root'
34375
+ },] }
34376
+ ];
34377
+ StorageService.ctorParameters = () => [
34378
+ { type: ModuleConfigService }
34379
+ ];
34380
+
34154
34381
  class CommonLibComponent {
34155
- constructor(_componentContextService) {
34382
+ constructor(_componentContextService, _router, _activatedRoute, _applicationContext, _storageService, _moduleConfigService) {
34156
34383
  this._componentContextService = _componentContextService;
34384
+ this._router = _router;
34385
+ this._activatedRoute = _activatedRoute;
34386
+ this._applicationContext = _applicationContext;
34387
+ this._storageService = _storageService;
34388
+ this._moduleConfigService = _moduleConfigService;
34157
34389
  this.showRejectConfirm = true;
34390
+ this.appCode = '';
34391
+ this.environment = this._moduleConfigService.getConfig().environment;
34392
+ this.appCode = this._moduleConfigService.getConfig().appCode;
34158
34393
  this._componentContextService.subscribe(ComCtxConstants.ROOT.SHOW_REJECT_CONFIRM, data => {
34159
34394
  this.showRejectConfirm = data;
34160
34395
  });
34396
+ this._applicationContext.addRootContext(this._componentContextService, _activatedRoute);
34397
+ this._componentContextService.data.personalize = this._storageService.getObjectAny('personalize');
34398
+ if (!this._componentContextService.data.personalize) {
34399
+ this._componentContextService.data.personalize = {};
34400
+ }
34161
34401
  }
34162
34402
  ngOnInit() {
34403
+ const root = this._applicationContext.getRootContext();
34404
+ this.rootData = root.data;
34405
+ root.data.currentAppMetadata = this.environment.appMetadata.appSwitcher.find(x => x.code.toLowerCase() == this.appCode.toLowerCase());
34406
+ root.data.appOrigin = this.environment.enableBaseHref ? `/${root.data.currentAppMetadata.code.toLowerCase()}/` : '/';
34407
+ this._router.config.forEach(route => this.addGuard(route));
34163
34408
  }
34164
34409
  focusTrap(event, direct) {
34165
34410
  event.preventDefault();
@@ -34170,6 +34415,19 @@ class CommonLibComponent {
34170
34415
  this.cancelButton.nativeElement.focus();
34171
34416
  }
34172
34417
  }
34418
+ addGuard(route) {
34419
+ if (route.path === '' || route.path === '/') {
34420
+ return;
34421
+ }
34422
+ else {
34423
+ if (route.loadChildren) {
34424
+ route.canActivateChild = route.canActivateChild ? route.canActivateChild : [GenericGuardChildService];
34425
+ }
34426
+ else {
34427
+ route.canActivate = route.canActivate ? route.canActivate : [GenericGuardService];
34428
+ }
34429
+ }
34430
+ }
34173
34431
  }
34174
34432
  CommonLibComponent.decorators = [
34175
34433
  { type: Component, args: [{
@@ -34180,7 +34438,12 @@ CommonLibComponent.decorators = [
34180
34438
  },] }
34181
34439
  ];
34182
34440
  CommonLibComponent.ctorParameters = () => [
34183
- { type: ComponentContextService }
34441
+ { type: ComponentContextService },
34442
+ { type: Router },
34443
+ { type: ActivatedRoute },
34444
+ { type: ApplicationContextService },
34445
+ { type: StorageService },
34446
+ { type: ModuleConfigService }
34184
34447
  ];
34185
34448
  CommonLibComponent.propDecorators = {
34186
34449
  okButton: [{ type: ViewChild, args: ['okButton',] }],
@@ -36138,59 +36401,6 @@ EformService.ctorParameters = () => [
36138
36401
  { type: ModuleConfigService }
36139
36402
  ];
36140
36403
 
36141
- class GenericGuardService {
36142
- constructor(_permissionService, _injector) {
36143
- this._permissionService = _permissionService;
36144
- this._injector = _injector;
36145
- this.storage = sessionStorage;
36146
- }
36147
- canActivate(route, state) {
36148
- return new Promise((resolve) => __awaiter(this, void 0, void 0, function* () {
36149
- const _applicationContext = this._injector.get(ApplicationContextService);
36150
- const root = _applicationContext.getRootContext();
36151
- if (state.url == '/') {
36152
- resolve(true);
36153
- return;
36154
- }
36155
- if ((top.location.href.indexOf('/dashboard') > -1)
36156
- || (top.location.href.indexOf('/access-denied') > -1)) {
36157
- resolve(true);
36158
- return;
36159
- }
36160
- // todo: còn case sử dụng biến trong url
36161
- const service = root.data.currentAppMetadata.code;
36162
- const permission = `${root.data.currentAppMetadata.code}${state.url.split('#')[0].split('?')[0]}`.toUpperCase();
36163
- const isAuthorized = yield this._permissionService.isAuthorized(service, permission);
36164
- if (isAuthorized) {
36165
- resolve(true);
36166
- }
36167
- else {
36168
- // this._notifierService.showWarning('Bạn không có quyền truy cập vào trang này', 'Cảnh báo');
36169
- const firstTimeLogin = localStorage.getItem('firstTimeLogin');
36170
- if (firstTimeLogin && firstTimeLogin !== '' && firstTimeLogin == 'true') {
36171
- localStorage.removeItem('firstTimeLogin');
36172
- top.location.href = '/';
36173
- }
36174
- else {
36175
- top.location.href = '/access-denied';
36176
- }
36177
- resolve(false);
36178
- }
36179
- resolve(true);
36180
- }));
36181
- }
36182
- }
36183
- GenericGuardService.ɵprov = i0.ɵɵdefineInjectable({ factory: function GenericGuardService_Factory() { return new GenericGuardService(i0.ɵɵinject(PermissionService), i0.ɵɵinject(i0.INJECTOR)); }, token: GenericGuardService, providedIn: "root" });
36184
- GenericGuardService.decorators = [
36185
- { type: Injectable, args: [{
36186
- providedIn: 'root'
36187
- },] }
36188
- ];
36189
- GenericGuardService.ctorParameters = () => [
36190
- { type: PermissionService },
36191
- { type: Injector }
36192
- ];
36193
-
36194
36404
  class GlobalService {
36195
36405
  constructor() {
36196
36406
  this._state = true;
@@ -36811,122 +37021,6 @@ RandomDataService.decorators = [
36811
37021
  ];
36812
37022
  RandomDataService.ctorParameters = () => [];
36813
37023
 
36814
- class StorageService {
36815
- constructor(_moduleConfigService) {
36816
- this._moduleConfigService = _moduleConfigService;
36817
- this.ignoreBuildInCacheKey = /(expires_at|id_token_expires_at|nonce|access_token_stored_at|id_token_stored_at|id_token|access_token|id_token_claims_obj|session_state|granted_scopes)/i;
36818
- const st = this._moduleConfigService.getConfig().environment.storage;
36819
- if (st === 'sessionStorage') {
36820
- this.storage = sessionStorage;
36821
- }
36822
- else {
36823
- this.storage = localStorage;
36824
- }
36825
- }
36826
- setStorage(storage) {
36827
- this.storage = storage;
36828
- }
36829
- getStorage() {
36830
- return this.storage;
36831
- }
36832
- setItem(key, value) {
36833
- if (!value) {
36834
- this.storage.setItem(key, null);
36835
- }
36836
- if (value instanceof Object) {
36837
- this.storage.setItem(key, JSON.stringify(value));
36838
- }
36839
- else {
36840
- this.storage.setItem(key, value ? value.toString() : null);
36841
- }
36842
- }
36843
- removeItem(key) {
36844
- this.storage.removeItem(key);
36845
- if (key.startsWith('v4_')) {
36846
- this.storage.removeItem(key.replace('v4_', ''));
36847
- }
36848
- else {
36849
- this.storage.removeItem('v4_' + key);
36850
- }
36851
- }
36852
- removeByPattern(pattern) {
36853
- this.getCacheKeysByPattern(pattern).forEach(item => {
36854
- this.removeItem(item);
36855
- if (item.startsWith('v4_')) {
36856
- this.storage.removeItem(item.replace('v4_', ''));
36857
- }
36858
- else {
36859
- this.storage.removeItem('v4_' + item);
36860
- }
36861
- });
36862
- }
36863
- getItem(key) {
36864
- return this.storage.getItem(key);
36865
- }
36866
- getNumber(key, defaultValueIfNull = 0) {
36867
- const rs = this.getItem(key);
36868
- if (rs) {
36869
- return +rs;
36870
- }
36871
- return defaultValueIfNull;
36872
- }
36873
- getBoolean(key, defaultValueIfNull = false) {
36874
- const rs = this.getItem(key);
36875
- if (rs) {
36876
- return rs.toLowerCase() === 'true';
36877
- }
36878
- return defaultValueIfNull;
36879
- }
36880
- getObject(key) {
36881
- const rs = this.getItem(key);
36882
- if (rs) {
36883
- return JSON.parse(rs);
36884
- }
36885
- return null;
36886
- }
36887
- getObjectAny(key) {
36888
- const rs = this.getItem(key);
36889
- if (rs) {
36890
- return JSON.parse(rs);
36891
- }
36892
- return null;
36893
- }
36894
- getAllCachekeys() {
36895
- return Object.keys(this.storage).filter(x => !x.match(this.ignoreBuildInCacheKey));
36896
- }
36897
- getCacheKeysByPattern(pattern) {
36898
- return Object.keys(this.storage).filter(x => !x.match(this.ignoreBuildInCacheKey) && this.matchRuleShort(pattern, x));
36899
- }
36900
- matchRuleShort(str, rule) {
36901
- const escapeRegex = (str) => str.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, '\\$1');
36902
- return new RegExp('^' + rule.split('*').map(escapeRegex).join('.*') + '$').test(str);
36903
- }
36904
- // Explanation code
36905
- matchRuleExpl(str, rule) {
36906
- // for this solution to work on any string, no matter what characters it has
36907
- const escapeRegex = (str) => str.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, '\\$1');
36908
- // "." => Find a single character, except newline or line terminator
36909
- // ".*" => Matches any string that contains zero or more characters
36910
- rule = rule.split('*').map(escapeRegex).join('.*');
36911
- // "^" => Matches any string with the following at the beginning of it
36912
- // "$" => Matches any string with that in front at the end of it
36913
- rule = '^' + rule + '$';
36914
- // Create a regular expression object for matching string
36915
- const regex = new RegExp(rule);
36916
- // Returns true if it finds a match, otherwise it returns false
36917
- return regex.test(str);
36918
- }
36919
- }
36920
- StorageService.ɵprov = i0.ɵɵdefineInjectable({ factory: function StorageService_Factory() { return new StorageService(i0.ɵɵinject(ModuleConfigService)); }, token: StorageService, providedIn: "root" });
36921
- StorageService.decorators = [
36922
- { type: Injectable, args: [{
36923
- providedIn: 'root'
36924
- },] }
36925
- ];
36926
- StorageService.ctorParameters = () => [
36927
- { type: ModuleConfigService }
36928
- ];
36929
-
36930
37024
  class TemplateTextV4Service extends BaseService {
36931
37025
  constructor(_moduleConfigService, _httpClient, _printService, _fileV4Service, _notifierService, _crudService, _commonService, injector) {
36932
37026
  super(_httpClient, injector, `${_moduleConfigService.getConfig().environment.v4.apiDomain.templateEndpoint}/templateText`);
@@ -37907,64 +38001,6 @@ WorkflowService.ctorParameters = () => [
37907
38001
  { type: ModuleConfigService }
37908
38002
  ];
37909
38003
 
37910
- class GenericGuardChildService {
37911
- constructor(_userService, _permissionService, _router, _injector, _notifierService) {
37912
- this._userService = _userService;
37913
- this._permissionService = _permissionService;
37914
- this._router = _router;
37915
- this._injector = _injector;
37916
- this._notifierService = _notifierService;
37917
- this.storage = sessionStorage;
37918
- }
37919
- canActivateChild(route, state) {
37920
- return new Promise((resolve) => __awaiter(this, void 0, void 0, function* () {
37921
- const _applicationContext = this._injector.get(ApplicationContextService);
37922
- const root = _applicationContext.getRootContext();
37923
- if (state.url == '/') {
37924
- resolve(true);
37925
- return;
37926
- }
37927
- if ((top.location.href.indexOf('/dashboard') > -1)
37928
- || (top.location.href.indexOf('/access-denied') > -1)) {
37929
- resolve(true);
37930
- return;
37931
- }
37932
- // todo: còn case sử dụng biến trong url
37933
- const service = root.data.currentAppMetadata.code;
37934
- const permission = `${root.data.currentAppMetadata.code}${state.url.split('#')[0].split('?')[0]}`.toUpperCase();
37935
- const isAuthorized = yield this._permissionService.isAuthorized(service, permission);
37936
- if (isAuthorized) {
37937
- resolve(true);
37938
- }
37939
- else {
37940
- const firstTimeLogin = localStorage.getItem('firstTimeLogin');
37941
- if (firstTimeLogin && firstTimeLogin !== '' && firstTimeLogin == 'true') {
37942
- localStorage.removeItem('firstTimeLogin');
37943
- top.location.href = '/';
37944
- }
37945
- else {
37946
- top.location.href = window['baseHref'] + '/access-denied';
37947
- }
37948
- resolve(false);
37949
- }
37950
- resolve(true);
37951
- }));
37952
- }
37953
- }
37954
- GenericGuardChildService.ɵprov = i0.ɵɵdefineInjectable({ factory: function GenericGuardChildService_Factory() { return new GenericGuardChildService(i0.ɵɵinject(UserService), i0.ɵɵinject(PermissionService), i0.ɵɵinject(i3$1.Router), i0.ɵɵinject(i0.INJECTOR), i0.ɵɵinject(NotifierService)); }, token: GenericGuardChildService, providedIn: "root" });
37955
- GenericGuardChildService.decorators = [
37956
- { type: Injectable, args: [{
37957
- providedIn: 'root'
37958
- },] }
37959
- ];
37960
- GenericGuardChildService.ctorParameters = () => [
37961
- { type: UserService },
37962
- { type: PermissionService },
37963
- { type: Router },
37964
- { type: Injector },
37965
- { type: NotifierService }
37966
- ];
37967
-
37968
38004
  class LatexService {
37969
38005
  constructor(_commonService, _templateInstanceService, _fileObjectService) {
37970
38006
  this._commonService = _commonService;
@@ -47192,6 +47228,29 @@ class TnTinymceComponent extends ComponentBase {
47192
47228
  editor.addShortcut('Alt+N', 'LuiRa', function () {
47193
47229
  editor.execCommand('outdent', false);
47194
47230
  });
47231
+ editor.ui.registry.addMenuButton('Language', {
47232
+ tooltip: 'Language',
47233
+ icon: 'language',
47234
+ fetch: (callback) => {
47235
+ const items = [
47236
+ {
47237
+ type: 'menuitem',
47238
+ text: 'Tiếng Việt',
47239
+ onAction: (_) => {
47240
+ $this.handleChangeLanguage('vi_VN');
47241
+ }
47242
+ },
47243
+ {
47244
+ type: 'menuitem',
47245
+ text: 'English',
47246
+ onAction: (_) => {
47247
+ $this.handleChangeLanguage('en');
47248
+ }
47249
+ },
47250
+ ];
47251
+ callback(items);
47252
+ }
47253
+ });
47195
47254
  },
47196
47255
  mobile: {
47197
47256
  theme: 'silver',
@@ -47202,26 +47261,26 @@ class TnTinymceComponent extends ComponentBase {
47202
47261
  config.plugins = [
47203
47262
  'advlist autolink lists link image charmap print preview anchor textcolor searchreplace visualblocks code fullscreen insertdatetime media table media code lists colorpicker imagetools tabfocus editFileNew addNews'
47204
47263
  ];
47205
- config.toolbar = 'formatselect | bold italic Strikethrough forecolor backcolor | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | table link editFileNew addNews | print removeformat undo redo | fullscreen ';
47206
- config.mobile.toolbar = 'bold italic Strikethrough forecolor backcolor | bullist numlist | fullscreen';
47264
+ config.toolbar = 'formatselect | bold italic Strikethrough forecolor backcolor | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | table link editFileNew addNews | print removeformat undo redo | fullscreen | Language';
47265
+ config.mobile.toolbar = 'bold italic Strikethrough forecolor backcolor | bullist numlist | fullscreen | Language';
47207
47266
  // return config;
47208
47267
  }
47209
47268
  else if (mode == 'medium') {
47210
47269
  config.plugins = ['advlist autolink lists link image charmap print preview anchor textcolor searchreplace visualblocks code fullscreen insertdatetime media table media code lists colorpicker imagetools tabfocus textcolor'];
47211
- config.toolbar = 'formatselect | bold italic Strikethrough forecolor backcolor | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | table link | print removeformat undo redo | fullscreen';
47212
- config.mobile.toolbar = 'bold italic Strikethrough forecolor backcolor | bullist numlist | fullscreen';
47270
+ config.toolbar = 'formatselect | bold italic Strikethrough forecolor backcolor | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | table link | print removeformat undo redo | fullscreen | Language';
47271
+ config.mobile.toolbar = 'bold italic Strikethrough forecolor backcolor | bullist numlist | fullscreen | Language';
47213
47272
  // return config;
47214
47273
  }
47215
47274
  else if (mode == 'simple') {
47216
47275
  config.plugins = ['advlist autolink lists link image charmap print preview anchor textcolor searchreplace visualblocks code fullscreen insertdatetime media table media code lists colorpicker imagetools tabfocus textcolor'];
47217
- config.toolbar = 'bold italic Strikethrough forecolor backcolor | bullist numlist | fullscreen';
47218
- config.mobile.toolbar = 'fullscreen | bold italic Strikethrough forecolor backcolor | bullist numlist';
47276
+ config.toolbar = 'bold italic Strikethrough forecolor backcolor | bullist numlist | fullscreen | Language';
47277
+ config.mobile.toolbar = 'fullscreen | bold italic Strikethrough forecolor backcolor | bullist numlist | Language';
47219
47278
  // return config;
47220
47279
  }
47221
47280
  else {
47222
47281
  config.plugins = ['advlist autolink lists link image charmap print preview anchor textcolor searchreplace visualblocks code fullscreen insertdatetime media table media code lists colorpicker imagetools tabfocus textcolor'];
47223
47282
  // config.toolbar = 'formatselect | bold italic Strikethrough forecolor backcolor| alignleft aligncenter alignright alignjustify | bullist numlist';
47224
- config.toolbar = 'bold italic Strikethrough forecolor backcolor | bullist numlist | fullscreen';
47283
+ config.toolbar = 'bold italic Strikethrough forecolor backcolor | bullist numlist | fullscreen | Language';
47225
47284
  }
47226
47285
  config.paste_data_images = true;
47227
47286
  return config;
@@ -47375,6 +47434,12 @@ class TnTinymceComponent extends ComponentBase {
47375
47434
  const blob = new Blob([int8Array], { type: fileType });
47376
47435
  return blob;
47377
47436
  }
47437
+ handleChangeLanguage(language) {
47438
+ tinymce.EditorManager.execCommand('mceRemoveEditor', true, this.id);
47439
+ const config = this.modes[this.mode];
47440
+ config.language = language;
47441
+ tinymce.init(config);
47442
+ }
47378
47443
  }
47379
47444
  TnTinymceComponent.decorators = [
47380
47445
  { type: Component, args: [{