tnx-shared 5.3.145 → 5.3.146

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.
@@ -28271,6 +28271,573 @@ UserOnlineDetailsService.ctorParameters = () => [
28271
28271
  { type: UserService }
28272
28272
  ];
28273
28273
 
28274
+ class HighPerformanceService {
28275
+ constructor(_signalrService, _commonService, _httpClient, _moduleConfigService) {
28276
+ this._signalrService = _signalrService;
28277
+ this._commonService = _commonService;
28278
+ this._httpClient = _httpClient;
28279
+ this._moduleConfigService = _moduleConfigService;
28280
+ }
28281
+ createProcess(queueName, callBackOnMessage = null, data = null, returnSequenceNumber = false) {
28282
+ const internalClientKey = this._commonService.guid();
28283
+ const model = {
28284
+ queueName,
28285
+ data,
28286
+ clientKey: internalClientKey
28287
+ };
28288
+ this._signalrService.start(null, internalClientKey, (data) => {
28289
+ if (callBackOnMessage) {
28290
+ callBackOnMessage(data);
28291
+ }
28292
+ this._signalrService.unSubscribeViewCode(null, internalClientKey);
28293
+ });
28294
+ return new Promise((resolve) => __awaiter(this, void 0, void 0, function* () {
28295
+ this.env = this._moduleConfigService.getConfig().environment;
28296
+ const highPerformanceEndpoint = `${this.env.apiDomain.highPerformanceEndpoint}/HighPerformance/DoWork?returnSequenceNumber=${returnSequenceNumber}`;
28297
+ try {
28298
+ const rs = yield this._httpClient.post(highPerformanceEndpoint, model).toPromise();
28299
+ if (rs.success) {
28300
+ resolve(rs.data);
28301
+ }
28302
+ }
28303
+ catch (_a) {
28304
+ }
28305
+ resolve(null);
28306
+ }));
28307
+ }
28308
+ cancelProcess(queueName, uniqueKey) {
28309
+ return __awaiter(this, void 0, void 0, function* () {
28310
+ try {
28311
+ const highPerformanceEndpoint = `${this.env.apiDomain.highPerformanceEndpoint}/HighPerformance/CancelWork?queueName=${queueName}&uniqueKey=${uniqueKey}`;
28312
+ const rs = yield this._httpClient.post(highPerformanceEndpoint, {}).toPromise();
28313
+ if (rs.success) {
28314
+ return rs.data;
28315
+ }
28316
+ }
28317
+ catch (_a) {
28318
+ }
28319
+ return false;
28320
+ });
28321
+ }
28322
+ }
28323
+ HighPerformanceService.ɵprov = i0.ɵɵdefineInjectable({ factory: function HighPerformanceService_Factory() { return new HighPerformanceService(i0.ɵɵinject(SignalRService), i0.ɵɵinject(CommonService), i0.ɵɵinject(i1$1.HttpClient), i0.ɵɵinject(ModuleConfigService)); }, token: HighPerformanceService, providedIn: "root" });
28324
+ HighPerformanceService.decorators = [
28325
+ { type: Injectable, args: [{
28326
+ providedIn: 'root'
28327
+ },] }
28328
+ ];
28329
+ HighPerformanceService.ctorParameters = () => [
28330
+ { type: SignalRService },
28331
+ { type: CommonService },
28332
+ { type: HttpClient },
28333
+ { type: ModuleConfigService }
28334
+ ];
28335
+
28336
+ class TemplateService {
28337
+ constructor(_moduleConfigService, _httpClient, _printService, _fileService, _notifierService, _crudService, _commonService) {
28338
+ this._httpClient = _httpClient;
28339
+ this._printService = _printService;
28340
+ this._fileService = _fileService;
28341
+ this._notifierService = _notifierService;
28342
+ this._crudService = _crudService;
28343
+ this._commonService = _commonService;
28344
+ this._moduleConfig = _moduleConfigService.getConfig();
28345
+ this.environment = this._moduleConfig.environment;
28346
+ this.serviceUri = `${this.environment.apiDomain.templateEndpoint}/template`;
28347
+ }
28348
+ laTexToBase64Image(laTex, font = 54) {
28349
+ const api = `${this.serviceUri}/LatexToBase64`;
28350
+ return this._httpClient.post(api, { laTex, font }).toPromise();
28351
+ }
28352
+ /**
28353
+ * Description: Xuất file sử dụng thư viện CX, xuất xong tự động mở popup để lưu file.
28354
+ */
28355
+ exportCxExcelByCode(model) {
28356
+ const url = `${this.serviceUri}/ExportCxExcelByCode`;
28357
+ this.setFileInfo(model);
28358
+ return this._httpClient
28359
+ .post(url, model, { responseType: 'blob' })
28360
+ .toPromise()
28361
+ .then(res => {
28362
+ FileSaver.saveAs(res, this.getFullFileName(model.fileName || model.code));
28363
+ }).catch((err) => __awaiter(this, void 0, void 0, function* () {
28364
+ const errorText = yield err.error.text();
28365
+ this._crudService.processErrorResponse(JSON.parse(errorText || ''));
28366
+ }));
28367
+ }
28368
+ exportManyCxExcelByCode(model) {
28369
+ const url = `${this.serviceUri}/ExportManyCxExcelByCode`;
28370
+ this.setManyFileInfo(model);
28371
+ return this._httpClient
28372
+ .post(url, model)
28373
+ .toPromise()
28374
+ .then(res => {
28375
+ if (res.success) {
28376
+ this._fileService.downloadFolder(res.data.folderId);
28377
+ }
28378
+ else {
28379
+ this._crudService.processErrorResponse(res);
28380
+ }
28381
+ }).catch((err) => __awaiter(this, void 0, void 0, function* () {
28382
+ const errorText = yield err.error.text();
28383
+ this._crudService.processErrorResponse(JSON.parse(errorText || ''));
28384
+ }));
28385
+ }
28386
+ getFullFileName(fileName, extension = TemplateConstant.EXCEL_EXTENSION) {
28387
+ return `${fileName}${extension}`;
28388
+ }
28389
+ /**
28390
+ * Description: Export sử dung ClosedXml.Report (Cx) với signalR, sử dụng cho file dữ liệu lớn.
28391
+ * Param: model chứa
28392
+ * - code : code của template cấu hình bên Quản trị > Biểu mẫu > Biểu mẫu excel.
28393
+ * - data : object chứa dữ liệu đã chuyền thành dạng json.
28394
+ * - fileName: tên file sau khi export.
28395
+ * - topic: guid dùng để subscribe.
28396
+ */
28397
+ ExportCxExcelByCodeWithSignalR(model) {
28398
+ return __awaiter(this, void 0, void 0, function* () {
28399
+ const url = `${this.serviceUri}/ExportCxExcelByCodeWithSignalR`;
28400
+ return this._httpClient.post(url, model)
28401
+ .toPromise();
28402
+ });
28403
+ }
28404
+ /**
28405
+ * Description: Export sử dung ClosedXml.Report (Cx) với HighPerformanceService, sử dụng cho file dữ liệu lớn.
28406
+ * Param: model chứa
28407
+ * - code : code của template cấu hình bên Quản trị > Biểu mẫu > Biểu mẫu excel.
28408
+ * - data : object chứa dữ liệu đã chuyền thành dạng json.
28409
+ * - fileName: tên file sau khi export.
28410
+ * - queueName: queue của topic.
28411
+ * - uniqueKey: unique key cho task.
28412
+ */
28413
+ ExportCxExcelByCodeWithHPS(model) {
28414
+ return __awaiter(this, void 0, void 0, function* () {
28415
+ const url = `${this.serviceUri}/ExportWithHighPerformanceService`;
28416
+ return this._httpClient.post(url, model)
28417
+ .toPromise();
28418
+ });
28419
+ }
28420
+ exportCxExcelByCodePromise(model) {
28421
+ return __awaiter(this, void 0, void 0, function* () {
28422
+ const url = `${this.serviceUri}/ExportCxExcelByCode`;
28423
+ return this._httpClient
28424
+ .post(url, model, { responseType: 'blob' })
28425
+ .toPromise();
28426
+ });
28427
+ }
28428
+ fillTemplateByCodeAndGetPdf(templateCode, data, onLoadingDataPdf = null, onEndLoadingDataPdf = null) {
28429
+ const url = `${this.serviceUri}/fillWordByTemplateCode/${templateCode}?isPrint=true`;
28430
+ return this._httpClient
28431
+ .post(url, data)
28432
+ .toPromise().then(res => {
28433
+ if (res.data) {
28434
+ this._printService.printBase64Pdf(res.data, onLoadingDataPdf, onEndLoadingDataPdf);
28435
+ }
28436
+ });
28437
+ }
28438
+ fillWordByTemplateCodeMultiData(templateCode, data, onLoadingDataPdf = null, onEndLoadingDataPdf = null) {
28439
+ const url = `${this.serviceUri}/fillWordByTemplateCodeMultiData/${templateCode}?isPrint=true`;
28440
+ return this._httpClient
28441
+ .post(url, data)
28442
+ .toPromise().then(res => {
28443
+ if (res.data) {
28444
+ this._printService.printBase64Pdf(res.data, onLoadingDataPdf, onEndLoadingDataPdf);
28445
+ }
28446
+ });
28447
+ }
28448
+ setFileInfo(model) {
28449
+ model.data = model.data ? model.data : JSON.stringify(model.dataObject);
28450
+ delete model.dataObject;
28451
+ }
28452
+ setManyFileInfo(manyModel) {
28453
+ let hasModel = manyModel && manyModel.lstFileInfo && manyModel.lstFileInfo.length;
28454
+ if (!hasModel) {
28455
+ return;
28456
+ }
28457
+ manyModel.lstFileInfo.forEach(fileInfo => {
28458
+ this.setFileInfo(fileInfo);
28459
+ fileInfo.fileName = `${fileInfo.fileName}_${this._commonService.guid()}.${TemplateConstant.EXCEL_EXTENSION}`;
28460
+ });
28461
+ }
28462
+ /**
28463
+ * Export dữ liệu không dùng template.
28464
+ */
28465
+ exportCxExcel(model) {
28466
+ const url = `${this.serviceUri}/ExportCxExcel`;
28467
+ return this._httpClient
28468
+ .post(url, model, { responseType: 'blob' })
28469
+ .toPromise()
28470
+ .then(res => {
28471
+ FileSaver.saveAs(res, this.getFullFileName(model.fileName || 'Export'));
28472
+ }).catch((err) => __awaiter(this, void 0, void 0, function* () {
28473
+ const errorText = yield err.error.text();
28474
+ this._crudService.processErrorResponse(JSON.parse(errorText || ''));
28475
+ }));
28476
+ }
28477
+ exportCxExcelPromise(model) {
28478
+ return __awaiter(this, void 0, void 0, function* () {
28479
+ const url = `${this.serviceUri}/ExportCxExcel`;
28480
+ return this._httpClient
28481
+ .post(url, model, { responseType: 'blob' })
28482
+ .toPromise();
28483
+ });
28484
+ }
28485
+ }
28486
+ TemplateService.ɵprov = i0.ɵɵdefineInjectable({ factory: function TemplateService_Factory() { return new TemplateService(i0.ɵɵinject(ModuleConfigService), i0.ɵɵinject(i1$1.HttpClient), i0.ɵɵinject(PrintService), i0.ɵɵinject(FileExplorerService), i0.ɵɵinject(NotifierService), i0.ɵɵinject(CrudService), i0.ɵɵinject(CommonService)); }, token: TemplateService, providedIn: "root" });
28487
+ TemplateService.decorators = [
28488
+ { type: Injectable, args: [{
28489
+ providedIn: 'root'
28490
+ },] }
28491
+ ];
28492
+ TemplateService.ctorParameters = () => [
28493
+ { type: ModuleConfigService },
28494
+ { type: HttpClient },
28495
+ { type: PrintService },
28496
+ { type: FileExplorerService },
28497
+ { type: NotifierService },
28498
+ { type: CrudService },
28499
+ { type: CommonService }
28500
+ ];
28501
+
28502
+ class JobItem {
28503
+ constructor(code, data, fileName = 'BaoCao', status = REPORT_QUEUE_CONSTANT.statuses.Waiting) {
28504
+ // Loại export.
28505
+ this._type = JobTypes.SingnalR;
28506
+ this._code = code;
28507
+ const datepipe = new DatePipe('en-US');
28508
+ let formattedDate = datepipe.transform(new Date(), 'ddMMyyyy_hhmmss');
28509
+ this._fileName = `${fileName}_${formattedDate}${TemplateConstant.EXCEL_EXTENSION}`;
28510
+ this._data = data || {};
28511
+ this._status = status;
28512
+ }
28513
+ }
28514
+ class REPORT_QUEUE_CONSTANT {
28515
+ }
28516
+ REPORT_QUEUE_CONSTANT.statuses = {
28517
+ Waiting: 1,
28518
+ Exporting: 2,
28519
+ Success: 3,
28520
+ Error: 4,
28521
+ Downloaded: 5
28522
+ };
28523
+ REPORT_QUEUE_CONSTANT.dicStatus = new SimpleDictionary([
28524
+ new SimpleDicItem(REPORT_QUEUE_CONSTANT.statuses.Waiting, 'Chờ để xử lý'),
28525
+ new SimpleDicItem(REPORT_QUEUE_CONSTANT.statuses.Exporting, 'Đang xử lý'),
28526
+ new SimpleDicItem(REPORT_QUEUE_CONSTANT.statuses.Success, 'Tải xuống'),
28527
+ new SimpleDicItem(REPORT_QUEUE_CONSTANT.statuses.Error, 'Xuất file chưa thành công'),
28528
+ new SimpleDicItem(REPORT_QUEUE_CONSTANT.statuses.Downloaded, 'Đã tải'),
28529
+ ]);
28530
+ var JobTypes;
28531
+ (function (JobTypes) {
28532
+ JobTypes[JobTypes["Normal"] = 1] = "Normal";
28533
+ JobTypes[JobTypes["SingnalR"] = 2] = "SingnalR";
28534
+ JobTypes[JobTypes["Many"] = 3] = "Many"; // Export nhiều file cùng một lúc và nén vào file zip, mỗi file có thể là các loại biểu mẫu khác nhau.
28535
+ })(JobTypes || (JobTypes = {}));
28536
+ class ExportJob {
28537
+ constructor(templateCode, // code template cấu hình bên quản trị
28538
+ dataPromise, // promise dùng để lấy dữ liệu, trả về dạng ResponseResult
28539
+ fileName, // tên của file được lưu
28540
+ rootName = '', // tên thuộc tính của lst dữ liệu ngoài cùng
28541
+ cb = null, // dùng để xử lý dữ liệu sau khi lấy xong
28542
+ type = JobTypes.Normal // Loại export.
28543
+ ) {
28544
+ this.templateCode = templateCode;
28545
+ this.dataPromise = dataPromise;
28546
+ this.fileName = fileName;
28547
+ this.rootName = rootName;
28548
+ this.cb = cb;
28549
+ this.type = type;
28550
+ }
28551
+ }
28552
+
28553
+ class ReportQueueComponent {
28554
+ constructor(_notifierService, _commonService, _fileService, _tempateService, _signalRService, _highPerformanceService, _crudService) {
28555
+ this._notifierService = _notifierService;
28556
+ this._commonService = _commonService;
28557
+ this._fileService = _fileService;
28558
+ this._tempateService = _tempateService;
28559
+ this._signalRService = _signalRService;
28560
+ this._highPerformanceService = _highPerformanceService;
28561
+ this._crudService = _crudService;
28562
+ this.name = 'reportQueue';
28563
+ this.header = 'Xuất báo cáo';
28564
+ this.autoDownload = false;
28565
+ this.maxNameLength = 40;
28566
+ this.expand = true;
28567
+ this.queueName = 'REPORT_QUEUE';
28568
+ this.hub = 'CommonHub';
28569
+ this.dicStatus = REPORT_QUEUE_CONSTANT.dicStatus;
28570
+ this.statuses = REPORT_QUEUE_CONSTANT.statuses;
28571
+ this._queue = [];
28572
+ this.maxHeight = 200;
28573
+ this.itemHeight = 50;
28574
+ this.popupHeight = this.itemHeight;
28575
+ }
28576
+ ngOnInit() {
28577
+ if (this.parentDataModel && this.name) {
28578
+ this.parentDataModel[this.name] = this;
28579
+ }
28580
+ }
28581
+ toggleExpand() {
28582
+ this.expand = !this.expand;
28583
+ }
28584
+ /**
28585
+ * Thêm job vào để thực hiện
28586
+ */
28587
+ addJob(exportJob) {
28588
+ return __awaiter(this, void 0, void 0, function* () {
28589
+ var foundIndex = this._queue.findIndex(job => job._code == exportJob.templateCode && job._status == this.statuses.Exporting);
28590
+ if (foundIndex !== -1) {
28591
+ this._notifierService.showWarning("File cùng loại đang được xử lý, thử lại sau khi xử lý xong!");
28592
+ return;
28593
+ }
28594
+ var job = new JobItem(exportJob.templateCode, {}, exportJob.fileName || exportJob.templateCode, this.statuses.Exporting);
28595
+ this._queue.push(job);
28596
+ this.updatePopupHeight();
28597
+ setTimeout(() => {
28598
+ this.scrollbar.scrollToBottom();
28599
+ }, 100);
28600
+ var rsData = yield exportJob.dataPromise;
28601
+ if (rsData.data == null) {
28602
+ job._status = this.statuses.Error;
28603
+ return this._crudService.processErrorResponse(rsData);
28604
+ }
28605
+ if (exportJob.cb) {
28606
+ job._data = exportJob.cb(rsData.data);
28607
+ }
28608
+ else if (exportJob.rootName) {
28609
+ job._data[exportJob.rootName] = rsData.data;
28610
+ }
28611
+ else {
28612
+ job._data = rsData.data;
28613
+ }
28614
+ switch (exportJob.type) {
28615
+ case JobTypes.Normal:
28616
+ this.Export(job);
28617
+ break;
28618
+ case JobTypes.SingnalR:
28619
+ this.ExportWithSignalR(job);
28620
+ break;
28621
+ case JobTypes.Many:
28622
+ break;
28623
+ }
28624
+ });
28625
+ }
28626
+ /**
28627
+ * Thêm job vào để thực hiện
28628
+ * - templateCode: code template cấu hình bên quản trị
28629
+ * - data: dữ liệu export
28630
+ * - fileName: tên của file được lưu
28631
+ * - useSignalR: thay vì gọi request và chờ đến khi thực hiện xong
28632
+ * trả về binaryFile thì tạo tiến trình riêng để export, và dùng signalR thông
28633
+ * báo kết quả export, trả về fileId để tải.
28634
+ */
28635
+ addJobWithData(templateCode, data, fileName, useSignalR = false) {
28636
+ return __awaiter(this, void 0, void 0, function* () {
28637
+ var foundIndex = this._queue.findIndex(job => job._code == templateCode && job._status == this.statuses.Exporting);
28638
+ if (foundIndex !== -1) {
28639
+ this._notifierService.showWarning("File cùng loại đang được xử lý, thử lại sau khi xử lý xong!");
28640
+ return;
28641
+ }
28642
+ var job = new JobItem(templateCode, data, fileName || templateCode, this.statuses.Exporting);
28643
+ this._queue.push(job);
28644
+ if (useSignalR) {
28645
+ this.ExportWithSignalR(job);
28646
+ }
28647
+ else {
28648
+ this.Export(job);
28649
+ }
28650
+ });
28651
+ }
28652
+ Export(job) {
28653
+ return __awaiter(this, void 0, void 0, function* () {
28654
+ this._tempateService.exportCxExcelByCodePromise({ code: job._code, data: JSON.stringify(job._data), fileName: job._fileName })
28655
+ .then(file => {
28656
+ job._status = this.statuses.Success;
28657
+ job._binaryFile = file;
28658
+ if (this.autoDownload) {
28659
+ this.download(job);
28660
+ }
28661
+ }).catch((err) => __awaiter(this, void 0, void 0, function* () {
28662
+ job._status = this.statuses.Error;
28663
+ const errorText = yield err.error.text();
28664
+ this._crudService.processErrorResponse(JSON.parse(errorText || ''));
28665
+ }));
28666
+ });
28667
+ }
28668
+ ExportWithSignalR(job) {
28669
+ return __awaiter(this, void 0, void 0, function* () {
28670
+ const topic = this._commonService.guid();
28671
+ job._uniqueKey = topic;
28672
+ this._signalRService.start(this.hub, topic, (message) => {
28673
+ var rs = JSON.parse(message);
28674
+ if (rs.success) {
28675
+ job._status = this.statuses.Success;
28676
+ job._fileId = rs.data;
28677
+ if (this.autoDownload) {
28678
+ this.download(job);
28679
+ }
28680
+ }
28681
+ else {
28682
+ job._status = this.statuses.Error;
28683
+ this._crudService.processErrorResponse(rs);
28684
+ }
28685
+ });
28686
+ this._tempateService.ExportCxExcelByCodeWithSignalR({ code: job._code, data: JSON.stringify(job._data), fileName: job._fileName, topic: topic })
28687
+ .then(rs => {
28688
+ if (!rs.success) {
28689
+ job._status = this.statuses.Error;
28690
+ this._crudService.processErrorResponse(rs);
28691
+ }
28692
+ }).catch((err) => __awaiter(this, void 0, void 0, function* () {
28693
+ job._status = this.statuses.Error;
28694
+ this._crudService.processErrorResponse(err.error);
28695
+ }));
28696
+ ;
28697
+ });
28698
+ }
28699
+ ExportCxExcelByCodeWithHPS(job) {
28700
+ return __awaiter(this, void 0, void 0, function* () {
28701
+ this._highPerformanceService.createProcess(this.queueName, (arrMessage) => {
28702
+ var message = arrMessage.pop();
28703
+ var rs = JSON.parse(message);
28704
+ if (rs.success) {
28705
+ job._status = this.statuses.Success;
28706
+ job._fileId = rs.data;
28707
+ if (this.autoDownload) {
28708
+ this._fileService.downloadFile(job._fileId);
28709
+ job._status = this.statuses.Downloaded;
28710
+ job._fileId = null;
28711
+ }
28712
+ }
28713
+ else {
28714
+ job._status = this.statuses.Error;
28715
+ this._crudService.processErrorResponse(rs);
28716
+ }
28717
+ }).then(rs => {
28718
+ job._uniqueKey = rs;
28719
+ this._tempateService.ExportCxExcelByCodeWithHPS({
28720
+ code: job._code,
28721
+ data: JSON.stringify(job._data),
28722
+ fileName: job._fileName,
28723
+ topic: this.queueName,
28724
+ uniqueKey: job._uniqueKey
28725
+ }).then(rs => {
28726
+ if (!rs.success) {
28727
+ job._status = this.statuses.Error;
28728
+ this._crudService.processErrorResponse(rs);
28729
+ }
28730
+ }, err => {
28731
+ job._status = this.statuses.Error;
28732
+ console.log("Lỗi gọi api server export");
28733
+ });
28734
+ }, err => {
28735
+ job._status = this.statuses.Error;
28736
+ console.log("Lỗi gọi HPS service :(");
28737
+ });
28738
+ });
28739
+ }
28740
+ download(job) {
28741
+ if (job._status == this.statuses.Downloaded) {
28742
+ return;
28743
+ }
28744
+ if (job._fileId) {
28745
+ this._fileService.downloadFile(job._fileId, false, job._fileName);
28746
+ }
28747
+ else if (job._binaryFile) {
28748
+ FileSaver.saveAs(job._binaryFile, job._fileName);
28749
+ }
28750
+ job._status = this.statuses.Downloaded;
28751
+ job._binaryFile = null;
28752
+ job._fileId = null;
28753
+ }
28754
+ showQueue() {
28755
+ let show = this._queue && this._queue.length > 0;
28756
+ return show;
28757
+ }
28758
+ getName(job) {
28759
+ var name = job._fileName.length > this.maxNameLength ? `${job._fileName.substr(0, this.maxNameLength - 10)}[...]${TemplateConstant.EXCEL_EXTENSION}` : job._fileName;
28760
+ return name;
28761
+ }
28762
+ cancelJob(job) {
28763
+ let foundIndex = this._queue.findIndex(j => j._code == job._code);
28764
+ if (foundIndex == -1) {
28765
+ return;
28766
+ }
28767
+ let foundJob = this._queue[foundIndex];
28768
+ if (foundJob._status == this.statuses.Exporting) {
28769
+ this._notifierService
28770
+ .showConfirm('File này đang được xử lý. Bạn có muốn dừng lại?', 'Hủy xuất file')
28771
+ .then(rs => {
28772
+ if (!rs) {
28773
+ return;
28774
+ }
28775
+ let needUnsubscribe = foundJob._type == JobTypes.SingnalR && foundJob._uniqueKey;
28776
+ if (needUnsubscribe) {
28777
+ this._signalRService.unSubscribeViewCode(foundJob._uniqueKey, this.hub);
28778
+ }
28779
+ this._queue.splice(foundIndex, 1);
28780
+ this.updatePopupHeight();
28781
+ });
28782
+ }
28783
+ else if (foundJob._status != this.statuses.Exporting) {
28784
+ this._queue.splice(foundIndex, 1);
28785
+ this.updatePopupHeight();
28786
+ }
28787
+ }
28788
+ close() {
28789
+ var hasExporting = this._queue && this._queue.filter(item => item._status == this.statuses.Exporting).length > 0;
28790
+ if (hasExporting) {
28791
+ this._notifierService
28792
+ .showConfirm('Có file đang được xử lý. Bạn có muốn dừng lại?', 'Hủy xuất file')
28793
+ .then(rs => {
28794
+ if (!rs) {
28795
+ return;
28796
+ }
28797
+ let needUnsubscribe = false;
28798
+ this._queue.forEach(job => {
28799
+ needUnsubscribe = job._type == JobTypes.SingnalR && job._uniqueKey;
28800
+ if (needUnsubscribe) {
28801
+ this._signalRService.unSubscribeViewCode(job._uniqueKey, this.hub);
28802
+ }
28803
+ });
28804
+ this._queue = [];
28805
+ this.updatePopupHeight();
28806
+ });
28807
+ }
28808
+ else {
28809
+ this._queue = [];
28810
+ }
28811
+ }
28812
+ updatePopupHeight() {
28813
+ let height = (this._queue || []).length * this.itemHeight;
28814
+ this.popupHeight = height > this.maxHeight ? this.maxHeight : height;
28815
+ }
28816
+ }
28817
+ ReportQueueComponent.decorators = [
28818
+ { type: Component, args: [{
28819
+ selector: 'report-queue',
28820
+ template: "<div class=\"rq-container\" *ngIf=\"showQueue()\">\n <div class=\"rq-header\">\n <div>{{header | translate}}</div>\n <div>\n\n <p-checkbox [(ngModel)]=\"autoDownload\" binary=\"true\" pTooltip=\"T\u1EF1 \u0111\u1ED9ng t\u1EA3i\" tooltipPosition=\"left\">\n </p-checkbox>\n\n <a href=\"javascript:;\" (click)=\"toggleExpand()\" pTooltip=\"{{expand ? 'Thu g\u1ECDn' : 'M\u1EDF r\u1ED9ng'}}\"\n tooltipPosition=\"left\">\n <i class=\"fas\" [ngClass]=\"{'fa-compress' : expand, 'fa-expand': !expand}\"></i>\n </a>\n\n <a href=\"javascript:;\" (click)=\"close()\" pTooltip=\"\u0110\u00F3ng\">\n <i class=\"fas fa-times\"></i>\n </a>\n </div>\n </div>\n <div class=\"rq-body\" *ngIf=\"expand\">\n <tn-custom-scrollbar [style]=\"{'height.px': popupHeight}\" #scrollbar>\n <div class=\"re-job\" *ngFor=\"let job of _queue\">\n <div class=\"re-job-title\">\n <div>{{getName(job)}}</div>\n <div>\n <a href=\"javascript:;\" (click)=\"cancelJob(job)\">\n <i class=\"fas fa-times\"></i>\n </a>\n </div>\n </div>\n <div class=\"re-job-result\"\n [ngClass]=\"{'job-success': job._status == statuses.Success, 'job-error': job._status == statuses.Error, 'job-exporting' : job._status == statuses.Exporting, 'job-downloaded': job._status == statuses.Downloaded}\">\n <span *ngIf=\"job._status != statuses.Success && job._status != statuses.Exporting\">\n {{dicStatus.get(job._status) | translate}}\n </span>\n\n <span *ngIf=\"job._status == statuses.Exporting\">\n <div class=\"loader\"></div>\n {{dicStatus.get(job._status) | translate}}\n </span>\n\n <a href=\"javascript:;\" (click)=\"download(job)\" class=\"job-success\"\n *ngIf=\"job._status == statuses.Success\">\n <i class=\"fas fa-download\"></i> {{dicStatus.get(job._status) | translate}}\n </a>\n </div>\n </div>\n </tn-custom-scrollbar>\n </div>\n</div>\n",
28821
+ styles: ["::ng-deep .rq-container{width:350px;border:1px solid #3192e1;border-radius:3px;background-color:#fff}::ng-deep .rq-container .rq-header{background-color:#3192e1;padding:5px 10px;display:flex;border-radius:3px 3px 0 0;color:#fff;font-weight:400;font-size:15px}::ng-deep .rq-container .rq-header>div:first-child{flex-grow:1}::ng-deep .rq-container .rq-header>div:last-child>a{font-weight:200;margin-left:10px;color:#fff}::ng-deep .rq-container .rq-header>div:last-child>a>i{font-size:13px}::ng-deep .rq-container .rq-header>div:last-child .ui-chkbox-box{width:14px;height:14px;margin-top:-2px}::ng-deep .rq-container .rq-header>div:last-child .ui-chkbox-icon{font-size:13px;line-height:13px}::ng-deep .rq-container .rq-body .re-job{padding:6px 10px;display:flex;flex-direction:column}::ng-deep .rq-container .rq-body .re-job:first-child{padding-top:6px}::ng-deep .rq-container .rq-body .re-job .re-job-title{display:flex;font-size:13px}::ng-deep .rq-container .rq-body .re-job .re-job-title>div:first-child{flex-grow:1;padding-bottom:3px}::ng-deep .rq-container .rq-body .re-job .re-job-title>div a{color:#3192e1}::ng-deep .rq-container .rq-body .re-job .re-job-result{font-size:11px}::ng-deep .rq-container .rq-body .re-job .re-job-result>span{display:flex;align-items:center;height:20px}::ng-deep .rq-container .rq-body .re-job .re-job-result.job-exporting{color:#3192e1}::ng-deep .rq-container .rq-body .re-job .re-job-result.job-exporting>span>div{margin-right:5px}::ng-deep .rq-container .rq-body .re-job .re-job-result.job-success{color:#1ab91a}::ng-deep .rq-container .rq-body .re-job .re-job-result.job-success>a>i{margin-right:2px}::ng-deep .rq-container .rq-body .re-job .re-job-result.job-error{color:#e95353}::ng-deep .rq-container .rq-body .re-job .re-job-result.job-downloaded{color:#b2b2b2}::ng-deep .loader{border-radius:50%;border:2px solid #bcdbf5;border-top-color:#3192e1;width:12px;height:12px;animation:spin 1s linear infinite;display:inline-block}@keyframes spin{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}:host{position:absolute;bottom:1px;right:2px;z-index:1000}"]
28822
+ },] }
28823
+ ];
28824
+ ReportQueueComponent.ctorParameters = () => [
28825
+ { type: NotifierService },
28826
+ { type: CommonService },
28827
+ { type: FileExplorerService },
28828
+ { type: TemplateService },
28829
+ { type: SignalRService },
28830
+ { type: HighPerformanceService },
28831
+ { type: CrudService }
28832
+ ];
28833
+ ReportQueueComponent.propDecorators = {
28834
+ parentDataModel: [{ type: Input }],
28835
+ name: [{ type: Input }],
28836
+ header: [{ type: Input }],
28837
+ autoDownload: [{ type: Input }],
28838
+ scrollbar: [{ type: ViewChild, args: ['scrollbar',] }]
28839
+ };
28840
+
28274
28841
  class CommonAppComponentComponent {
28275
28842
  constructor(document, _globalService, _commonService, renderer, translate, _oauthService, _authenService, _userService, _router, _title, _signalRService, _storageUpdatedService, _applicationContext, _componentContextService, _activatedRoute, _deviceDetectorService, _cd, _tnClientService, _coreConfigService, _notifierService, _entityMetadataService, _moduleConfigService, _menuService, _primengConfig, _storageService, _permissionService, _userOnlineDetailsService, _customizeUiService) {
28276
28843
  var _a;
@@ -28306,7 +28873,6 @@ class CommonAppComponentComponent {
28306
28873
  this.allowAnonymous = false;
28307
28874
  this.autoRenderMenu = true;
28308
28875
  this.onUserLoaded = new EventEmitter();
28309
- // routerOutlet: TemplateRef<any>;
28310
28876
  this._unsubscribeAll = new Subject();
28311
28877
  // rootVersionDeploy = '1.3';
28312
28878
  this.currentRoute = '';
@@ -28581,8 +29147,8 @@ class CommonAppComponentComponent {
28581
29147
  ngAfterViewInit() {
28582
29148
  this._cd.detach();
28583
29149
  this.detectChanges();
28584
- // const root = this._applicationContext.getRootContext();
28585
- // root.reportQueue = this.reportQueue;
29150
+ const root = this._applicationContext.getRootContext();
29151
+ root.reportQueue = this.reportQueue;
28586
29152
  this.menuModel = this._menuService.getMenuItems();
28587
29153
  }
28588
29154
  defaultRedirect() {
@@ -28900,7 +29466,7 @@ class CommonAppComponentComponent {
28900
29466
  CommonAppComponentComponent.decorators = [
28901
29467
  { type: Component, args: [{
28902
29468
  selector: 'common-app-component',
28903
- template: "<ng-container *ngIf=\"!pageLoaded\">\n <ng-container [ngSwitch]=\"layoutLoadingPage\">\n <ng-container *ngSwitchDefault>\n <loading-page-v1></loading-page-v1>\n </ng-container>\n </ng-container>\n</ng-container>\n\n\n<div *ngIf=\"pageLoaded\" [style.display]=\"pageLoaded ? '' : 'none'\" class=\"layout-wrapper\"\n (click)=\"_commonService.onLayoutClick()\" [ngClass]=\"{'menu-layout-static': !_commonService.isOverlay(),\n 'menu-layout-overlay': _commonService.isOverlay(),\n 'layout-menu-overlay-active': _commonService.overlayMenuActive,\n 'menu-layout-horizontal': _commonService.isHorizontal(),\n 'menu-layout-slim': _commonService.isSlim(),\n 'layout-menu-static-desktop-inactive': _commonService.staticMenuDesktopInactive,\n 'layout-menu-static-desktop-active': !_commonService.staticMenuDesktopInactive,\n 'layout-menu-static-mobile-inactive': !_commonService.staticMenuMobileActive,\n 'layout-menu-static-mobile-active': _commonService.staticMenuMobileActive,\n 'layout-menu-static-inactive': _commonService.staticMenuDesktopInactive,\n 'layout-menu-static-active': _commonService.staticMenuMobileActive,\n 'show-menu-icon-inactive': showMenuIconInactive}\">\n\n <app-topbar *ngIf=\"_globalService.getHeaderState()\"></app-topbar>\n\n <div *ngIf=\"_globalService.getMenuState()\" class=\"layout-menu-container\"\n [ngClass]=\"{'layout-menu-dark':_commonService.darkMenu}\" (click)=\"_commonService.onMenuClick($event)\">\n <app-root-menu></app-root-menu>\n <div class=\"layout-menu-block\">\n <tn-custom-scrollbar #scrollbar [style]=\"{'padding-top': '16px'}\">\n <app-inline-profile *ngIf=\"_commonService.profileMode == 'inline' &&!_commonService.isHorizontal()\">\n </app-inline-profile>\n <ng-container *ngIf=\"!showMenuIconInactive\">\n <app-menu [autoRenderMenu]=\"autoRenderMenu\" [reset]=\"_commonService.resetMenu\"\n (onMenuActive)=\"handleMenuActive($event)\"></app-menu>\n </ng-container>\n <ng-container *ngIf=\"showMenuIconInactive\">\n <app-menu-v2 [autoRenderMenu]=\"autoRenderMenu\" [reset]=\"_commonService.resetMenu\"\n (onMenuActive)=\"handleMenuActive($event)\"></app-menu-v2>\n </ng-container>\n </tn-custom-scrollbar>\n </div>\n <div class=\"search-area layout-menu-search-area\">\n <p-autoComplete class=\"search-input\" field=\"label\" [style]=\"{'width':'100%'}\" [suggestions]=\"searchMenuResult\"\n (completeMethod)=\"onSearchMenu($event)\" [autoHighlight]=\"true\" [placeholder]=\"'T\u00ECm ki\u1EBFm ch\u1EE9c n\u0103ng' | translate\"\n [delay]=\"200\" [scrollHeight]=\"'400px'\" [readonly]=\"!(menuModel && menuModel.length)\"\n [(ngModel)]=\"searchMenuInput\" (onSelect)=\"onSelectMenuSuggestion($event)\" (onFocus)=\"searchIconClick()\">\n <ng-template let-item pTemplate=\"item\">\n <div innerHTML=\"{{ item.label | highlight : searchMenuInput}}\"></div>\n </ng-template>\n </p-autoComplete>\n <span class=\"icon-search\" (click)=\"searchIconClick()\"><i class=\"pi pi-search\"></i></span>\n </div>\n </div>\n\n <div [class]=\"'layout-main'\" [ngClass]=\"{'no-header': _globalService.getHeaderState() ? false : true}\">\n <router-outlet></router-outlet>\n </div>\n\n <div class=\"layout-mask\"></div>\n\n <!-- <report-queue [header]=\"'Xu\u1EA5t d\u1EEF li\u1EC7u'\">\n </report-queue> -->\n</div>\n<div class=\"waiting-box\" [class.show]=\"waiting\">\n <div class=\"overlay\"></div>\n <div class=\"content-loading\">\n <div class=\"lds-ellipsis\">\n <div></div>\n <div></div>\n <div></div>\n <div></div>\n </div>\n <div class=\"message-loading\">\n <span *ngFor=\"let x of messageWaiting\">{{x}}</span>\n </div>\n </div>\n</div>\n<p-toast [position]=\"'top-right'\" [autoZIndex]=\"true\"></p-toast>\n<p-confirmDialog #cd [closable]=\"false\">\n <p-footer>\n <button #okButton type=\"button\" pButton icon=\"pi pi-check\" class=\"p-button-rounded p-button-text\" label=\"\u0110\u1ED3ng \u00FD\"\n (keydown.shift.tab)=\"focusTrap($event, false)\" (click)=\"cd.accept()\"></button>\n <button *ngIf=\"showRejectConfirm\" #cancelButton type=\"button\" pButton\n class=\"p-button-rounded p-button-text p-button-secondary\" icon=\"pi pi-times\" label=\"B\u1ECF qua\"\n (keydown.tab)=\"focusTrap($event, true)\" (click)=\"cd.reject()\"></button>\n </p-footer>\n</p-confirmDialog>\n<!-- <user-action-manager></user-action-manager> -->\n<permission-utils *ngIf=\"rootData.showPermissionUtils\"></permission-utils>\n<ng-template #abc>\n <div>1</div>\n</ng-template>\n<ng-template #def>\n <div>2</div>\n</ng-template>\n",
29469
+ template: "<ng-container *ngIf=\"!pageLoaded\">\n <ng-container [ngSwitch]=\"layoutLoadingPage\">\n <ng-container *ngSwitchDefault>\n <loading-page-v1></loading-page-v1>\n </ng-container>\n </ng-container>\n</ng-container>\n\n<div *ngIf=\"pageLoaded\" [style.display]=\"pageLoaded ? '' : 'none'\" class=\"layout-wrapper\"\n (click)=\"_commonService.onLayoutClick()\" [ngClass]=\"{'menu-layout-static': !_commonService.isOverlay(),\n 'menu-layout-overlay': _commonService.isOverlay(),\n 'layout-menu-overlay-active': _commonService.overlayMenuActive,\n 'menu-layout-horizontal': _commonService.isHorizontal(),\n 'menu-layout-slim': _commonService.isSlim(),\n 'layout-menu-static-desktop-inactive': _commonService.staticMenuDesktopInactive,\n 'layout-menu-static-desktop-active': !_commonService.staticMenuDesktopInactive,\n 'layout-menu-static-mobile-inactive': !_commonService.staticMenuMobileActive,\n 'layout-menu-static-mobile-active': _commonService.staticMenuMobileActive,\n 'layout-menu-static-inactive': _commonService.staticMenuDesktopInactive,\n 'layout-menu-static-active': _commonService.staticMenuMobileActive,\n 'show-menu-icon-inactive': showMenuIconInactive}\">\n\n <app-topbar *ngIf=\"_globalService.getHeaderState()\"></app-topbar>\n\n <div *ngIf=\"_globalService.getMenuState()\" class=\"layout-menu-container\"\n [ngClass]=\"{'layout-menu-dark':_commonService.darkMenu}\" (click)=\"_commonService.onMenuClick($event)\">\n <app-root-menu></app-root-menu>\n <div class=\"layout-menu-block\">\n <tn-custom-scrollbar #scrollbar [style]=\"{'padding-top': '16px'}\">\n <app-inline-profile *ngIf=\"_commonService.profileMode == 'inline' &&!_commonService.isHorizontal()\">\n </app-inline-profile>\n <ng-container *ngIf=\"!showMenuIconInactive\">\n <app-menu [autoRenderMenu]=\"autoRenderMenu\" [reset]=\"_commonService.resetMenu\"\n (onMenuActive)=\"handleMenuActive($event)\"></app-menu>\n </ng-container>\n <ng-container *ngIf=\"showMenuIconInactive\">\n <app-menu-v2 [autoRenderMenu]=\"autoRenderMenu\" [reset]=\"_commonService.resetMenu\"\n (onMenuActive)=\"handleMenuActive($event)\"></app-menu-v2>\n </ng-container>\n </tn-custom-scrollbar>\n </div>\n <div class=\"search-area layout-menu-search-area\">\n <p-autoComplete class=\"search-input\" field=\"label\" [style]=\"{'width':'100%'}\"\n [suggestions]=\"searchMenuResult\" (completeMethod)=\"onSearchMenu($event)\" [autoHighlight]=\"true\"\n [placeholder]=\"'T\u00ECm ki\u1EBFm ch\u1EE9c n\u0103ng' | translate\" [delay]=\"200\" [scrollHeight]=\"'400px'\"\n [readonly]=\"!(menuModel && menuModel.length)\" [(ngModel)]=\"searchMenuInput\"\n (onSelect)=\"onSelectMenuSuggestion($event)\" (onFocus)=\"searchIconClick()\">\n <ng-template let-item pTemplate=\"item\">\n <div innerHTML=\"{{ item.label | highlight : searchMenuInput}}\"></div>\n </ng-template>\n </p-autoComplete>\n <span class=\"icon-search\" (click)=\"searchIconClick()\"><i class=\"pi pi-search\"></i></span>\n </div>\n </div>\n\n <div [class]=\"'layout-main'\" [ngClass]=\"{'no-header': _globalService.getHeaderState() ? false : true}\">\n <router-outlet></router-outlet>\n </div>\n\n <div class=\"layout-mask\"></div>\n\n <report-queue [header]=\"'Xu\u1EA5t d\u1EEF li\u1EC7u'\">\n </report-queue>\n</div>\n<div class=\"waiting-box\" [class.show]=\"waiting\">\n <div class=\"overlay\"></div>\n <div class=\"content-loading\">\n <div class=\"lds-ellipsis\">\n <div></div>\n <div></div>\n <div></div>\n <div></div>\n </div>\n <div class=\"message-loading\">\n <span *ngFor=\"let x of messageWaiting\">{{x}}</span>\n </div>\n </div>\n</div>\n<p-toast [position]=\"'top-right'\" [autoZIndex]=\"true\"></p-toast>\n<p-confirmDialog #cd [closable]=\"false\">\n <p-footer>\n <button #okButton type=\"button\" pButton icon=\"pi pi-check\" class=\"p-button-rounded p-button-text\"\n [label]=\"cd.acceptButtonLabel\" (keydown.shift.tab)=\"focusTrap($event, false)\"\n (click)=\"cd.accept()\"></button>\n <button *ngIf=\"showRejectConfirm\" #cancelButton type=\"button\" pButton\n class=\"p-button-rounded p-button-text p-button-secondary\" icon=\"pi pi-times\" [label]=\"cd.rejectButtonLabel\"\n (keydown.tab)=\"focusTrap($event, true)\" (click)=\"cd.reject()\"></button>\n </p-footer>\n</p-confirmDialog>\n<!-- <user-action-manager></user-action-manager> -->\n<permission-utils *ngIf=\"rootData.showPermissionUtils\"></permission-utils>\n<ng-template #abc>\n <div>1</div>\n</ng-template>\n<ng-template #def>\n <div>2</div>\n</ng-template>\n",
28904
29470
  providers: [ComponentContextService, EntityMetadataService],
28905
29471
  styles: [".layout-menu-search-area{position:relative}.icon-search{background-color:transparent;box-shadow:none;position:absolute;right:0;top:0;color:#888;width:30px;font-size:14px;height:100%;display:flex;align-items:center;justify-content:center}.layout-menu-static-inactive .search-area{margin-left:-303px}.layout-menu-container{overflow:hidden;display:flex;flex-direction:column;top:60px;bottom:0;height:auto}.layout-menu-block{display:flex;overflow:hidden;flex:1}.layout-menu-block>tn-custom-scrollbar{width:100%}::ng-deep .layout-menu-search-area .ui-inputtext{width:calc(100% + 1px);border-radius:0;border-color:#dadada;padding-right:40px}::ng-deep .layout-menu-search-area .ui-inputtext:not(:focus){box-shadow:none}::ng-deep .layout-menu-search-area input{width:100%;border-radius:0;border-left:0;border-right:0}::ng-deep .layout-menu-search-area .p-autocomplete-panel{max-width:100%}::ng-deep .layout-menu-search-area .p-autocomplete-item{white-space:normal}::ng-deep .layout-menu-search-area .p-autocomplete-item mark{background-color:var(--tn-primary-color);padding:0;color:#fff;border-radius:0}.waiting-box{position:fixed;top:0;left:0;width:100%;height:100%;z-index:9999;display:none}.waiting-box .overlay{background-color:red;background-color:hsla(0,0%,42.7%,.5019607843137255);width:100%;height:100%}.waiting-box .content-loading{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);text-align:center}.waiting-box .content-loading .lds-ellipsis{display:inline-block;position:relative;width:80px;height:60px}.waiting-box .content-loading .lds-ellipsis div{position:absolute;top:33px;width:13px;height:13px;border-radius:50%;background:#fff;animation-timing-function:cubic-bezier(0,1,1,0)}.waiting-box .content-loading .lds-ellipsis div:first-child{left:8px;animation:lds-ellipsis1 .6s infinite}.waiting-box .content-loading .lds-ellipsis div:nth-child(2){left:8px;animation:lds-ellipsis2 .6s infinite}.waiting-box .content-loading .lds-ellipsis div:nth-child(3){left:32px;animation:lds-ellipsis2 .6s infinite}.waiting-box .content-loading .lds-ellipsis div:nth-child(4){left:56px;animation:lds-ellipsis3 .6s infinite}.waiting-box .message-loading{font-size:1.75em}.waiting-box .message-loading span{color:#fff;animation:message-opacity 1s infinite;margin-right:1px}.waiting-box .message-loading span:last-child{margin-right:0}.waiting-box .message-loading span:nth-child(16n+1){animation-delay:0;animation-delay:0s}.waiting-box .message-loading span:nth-child(16n+2){animation-delay:.1s}.waiting-box .message-loading span:nth-child(16n+3){animation-delay:.2s}.waiting-box .message-loading span:nth-child(16n+4){animation-delay:.3s}.waiting-box .message-loading span:nth-child(16n+5){animation-delay:.4s}.waiting-box .message-loading span:nth-child(16n+6){animation-delay:.5s}.waiting-box .message-loading span:nth-child(16n+7){animation-delay:.6s}.waiting-box .message-loading span:nth-child(16n+8){animation-delay:.7s}.waiting-box .message-loading span:nth-child(16n+9){animation-delay:.8s}.waiting-box .message-loading span:nth-child(16n+10){animation-delay:.9s}.waiting-box .message-loading span:nth-child(16n+11){animation-delay:1s}.waiting-box .message-loading span:nth-child(16n+12){animation-delay:1.1s}.waiting-box .message-loading span:nth-child(16n+13){animation-delay:1.2s}.waiting-box .message-loading span:nth-child(16n+14){animation-delay:1.3s}.waiting-box .message-loading span:nth-child(16n+15){animation-delay:1.4s}.waiting-box .message-loading span:nth-child(16n+16){animation-delay:1.5s}.waiting-box.show{display:block}::ng-deep common-app-component .show-menu-icon-inactive .layout-menu-container .rootMenu,::ng-deep common-app-component .show-menu-icon-inactive .layout-menu-container .rootMenu>.icon,::ng-deep common-app-component .show-menu-icon-inactive .layout-menu-container .rootMenu>label,::ng-deep common-app-component .show-menu-icon-inactive .layout-menu li .active-menuitem-2,::ng-deep common-app-component .show-menu-icon-inactive .layout-menu li a,::ng-deep common-app-component .show-menu-icon-inactive .layout-menu li a .menu-icon{transition:all .3s}::ng-deep common-app-component .show-menu-icon-inactive .layout-menu li a i.menuitem-toggle-icon{transition:all .2s}::ng-deep common-app-component .show-menu-icon-inactive .layout-menu li{min-height:3.1em;position:relative}::ng-deep common-app-component .show-menu-icon-inactive .layout-menu li a{position:relative}::ng-deep common-app-component .show-menu-icon-inactive .layout-menu li a .menu-icon{position:absolute;left:0;top:0;bottom:0;display:flex;align-items:center;background-color:#fff}::ng-deep common-app-component .show-menu-icon-inactive .layout-menu li a .menu-label{margin-left:40px}::ng-deep common-app-component .show-menu-icon-inactive .layout-menu li i[level=\"1\"]:first-child{flex:0 0 40px}::ng-deep common-app-component .show-menu-icon-inactive .layout-menu li ul li a .menu-icon{padding-left:30px}::ng-deep common-app-component .show-menu-icon-inactive .layout-menu li ul li a .menu-icon i{margin-right:0!important}::ng-deep common-app-component .show-menu-icon-inactive .layout-menu li ul li ul li a .menu-icon{padding-left:30px}::ng-deep common-app-component .show-menu-icon-inactive .layout-menu li ul li ul li a .menu-icon i{margin-right:0!important}::ng-deep common-app-component .show-menu-icon-inactive .layout-menu li ul li ul ul li a .menu-icon{padding-left:30px}::ng-deep common-app-component .show-menu-icon-inactive .layout-menu li ul li ul ul li a .menu-icon i{margin-right:0!important}::ng-deep common-app-component .show-menu-icon-inactive .layout-menu li ul li ul ul ul li a .menu-icon{padding-left:30px}::ng-deep common-app-component .show-menu-icon-inactive .layout-menu li ul li ul ul ul li a .menu-icon i{margin-right:0!important}::ng-deep common-app-component .show-menu-icon-inactive .layout-menu li ul li ul ul ul ul li a .menu-icon{padding-left:30px}::ng-deep common-app-component .show-menu-icon-inactive .layout-menu li ul li ul ul ul ul li a .menu-icon i{margin-right:0!important}::ng-deep common-app-component .show-menu-icon-inactive .layout-menu>.active-menuitem>.active-menuitem-routerlink>span.menu-icon:first-child{background-color:#e8e8e8!important}::ng-deep common-app-component .show-menu-icon-inactive .layout-menu li a:hover .menu-icon{background-color:#f4f4f4}@media (min-width:1025px){::ng-deep common-app-component .show-menu-icon-inactive.layout-menu-static-inactive .layout-menu-container{margin-left:-245px!important}::ng-deep common-app-component .show-menu-icon-inactive.layout-menu-static-inactive .layout-menu-container .rootMenu>.icon{left:245px}::ng-deep common-app-component .show-menu-icon-inactive.layout-menu-static-inactive .layout-menu-container:hover{margin-left:0!important}::ng-deep common-app-component .show-menu-icon-inactive.layout-menu-static-inactive .layout-menu-container:hover .layout-menu li a .menu-icon,::ng-deep common-app-component .show-menu-icon-inactive.layout-menu-static-inactive .layout-menu-container:hover .rootMenu>.icon{left:0}::ng-deep common-app-component .show-menu-icon-inactive.layout-menu-static-inactive .layout-menu-container:hover .layout-menu li ul li a .menu-icon{padding-left:30px;left:0}::ng-deep common-app-component .show-menu-icon-inactive.layout-menu-static-inactive .layout-menu-container:hover .layout-menu li ul li ul li a .menu-icon{padding-left:45px;left:0}::ng-deep common-app-component .show-menu-icon-inactive.layout-menu-static-inactive .layout-menu-container:hover .layout-menu li ul li ul ul li a .menu-icon{padding-left:60px;left:0}::ng-deep common-app-component .show-menu-icon-inactive.layout-menu-static-inactive .layout-menu-container:hover .layout-menu li ul li ul ul ul li a .menu-icon{padding-left:75px;left:0}::ng-deep common-app-component .show-menu-icon-inactive.layout-menu-static-inactive .layout-menu-container:hover .layout-menu li ul li ul ul ul ul li a .menu-icon{padding-left:90px;left:0}::ng-deep common-app-component .show-menu-icon-inactive.layout-menu-static-inactive .layout-menu-container:hover i.menuitem-toggle-icon{visibility:visible}::ng-deep common-app-component .show-menu-icon-inactive.layout-menu-static-inactive .layout-menu-container:hover~.layout-main{margin-left:285px!important}::ng-deep common-app-component .show-menu-icon-inactive.layout-menu-static-inactive .layout-main{margin-left:40px!important}::ng-deep common-app-component .show-menu-icon-inactive.layout-menu-static-inactive .layout-menu li a .menu-icon{left:245px;padding-left:0}::ng-deep common-app-component .show-menu-icon-inactive.layout-menu-static-inactive .layout-menu li a .menu-icon i{flex:0 0 40px}::ng-deep common-app-component .show-menu-icon-inactive.layout-menu-static-inactive .layout-menu li a i.menuitem-toggle-icon{visibility:hidden}}::ng-deep common-app-component .show-menu-icon-inactive .tn-l-left-menu-toggle{padding:13px}::ng-deep common-app-component .show-menu-icon-inactive .ripplelink>span>i{padding:0 10px!important}::ng-deep common-app-component .show-menu-icon-inactive .ripplelink>span>i .menuitem-toggle-icon{margin-left:10px!important}::ng-deep common-app-component .show-menu-icon-inactive .icon-search{width:38px}@keyframes lds-ellipsis1{0%{transform:scale(0)}to{transform:scale(1)}}@keyframes lds-ellipsis3{0%{transform:scale(1)}to{transform:scale(0)}}@keyframes lds-ellipsis2{0%{transform:translate(0)}to{transform:translate(24px)}}@keyframes message-opacity{0%{opacity:1}50%{opacity:.5}to{opacity:1}}"]
28906
29472
  },] }
@@ -28938,6 +29504,7 @@ CommonAppComponentComponent.ctorParameters = () => [
28938
29504
  CommonAppComponentComponent.propDecorators = {
28939
29505
  okButton: [{ type: ViewChild, args: ['okButton',] }],
28940
29506
  cancelButton: [{ type: ViewChild, args: ['cancelButton',] }],
29507
+ reportQueue: [{ type: ViewChild, args: [ReportQueueComponent,] }],
28941
29508
  scrollBarMenu: [{ type: ViewChild, args: ['scrollbar',] }],
28942
29509
  children: [{ type: ViewChildren, args: [TemplateRef,] }],
28943
29510
  showQuickNote: [{ type: Input }],
@@ -40515,68 +41082,6 @@ GuardService.ctorParameters = () => [
40515
41082
  { type: NotifierService }
40516
41083
  ];
40517
41084
 
40518
- class HighPerformanceService {
40519
- constructor(_signalrService, _commonService, _httpClient, _moduleConfigService) {
40520
- this._signalrService = _signalrService;
40521
- this._commonService = _commonService;
40522
- this._httpClient = _httpClient;
40523
- this._moduleConfigService = _moduleConfigService;
40524
- }
40525
- createProcess(queueName, callBackOnMessage = null, data = null, returnSequenceNumber = false) {
40526
- const internalClientKey = this._commonService.guid();
40527
- const model = {
40528
- queueName,
40529
- data,
40530
- clientKey: internalClientKey
40531
- };
40532
- this._signalrService.start(null, internalClientKey, (data) => {
40533
- if (callBackOnMessage) {
40534
- callBackOnMessage(data);
40535
- }
40536
- this._signalrService.unSubscribeViewCode(null, internalClientKey);
40537
- });
40538
- return new Promise((resolve) => __awaiter(this, void 0, void 0, function* () {
40539
- this.env = this._moduleConfigService.getConfig().environment;
40540
- const highPerformanceEndpoint = `${this.env.apiDomain.highPerformanceEndpoint}/HighPerformance/DoWork?returnSequenceNumber=${returnSequenceNumber}`;
40541
- try {
40542
- const rs = yield this._httpClient.post(highPerformanceEndpoint, model).toPromise();
40543
- if (rs.success) {
40544
- resolve(rs.data);
40545
- }
40546
- }
40547
- catch (_a) {
40548
- }
40549
- resolve(null);
40550
- }));
40551
- }
40552
- cancelProcess(queueName, uniqueKey) {
40553
- return __awaiter(this, void 0, void 0, function* () {
40554
- try {
40555
- const highPerformanceEndpoint = `${this.env.apiDomain.highPerformanceEndpoint}/HighPerformance/CancelWork?queueName=${queueName}&uniqueKey=${uniqueKey}`;
40556
- const rs = yield this._httpClient.post(highPerformanceEndpoint, {}).toPromise();
40557
- if (rs.success) {
40558
- return rs.data;
40559
- }
40560
- }
40561
- catch (_a) {
40562
- }
40563
- return false;
40564
- });
40565
- }
40566
- }
40567
- HighPerformanceService.ɵprov = i0.ɵɵdefineInjectable({ factory: function HighPerformanceService_Factory() { return new HighPerformanceService(i0.ɵɵinject(SignalRService), i0.ɵɵinject(CommonService), i0.ɵɵinject(i1$1.HttpClient), i0.ɵɵinject(ModuleConfigService)); }, token: HighPerformanceService, providedIn: "root" });
40568
- HighPerformanceService.decorators = [
40569
- { type: Injectable, args: [{
40570
- providedIn: 'root'
40571
- },] }
40572
- ];
40573
- HighPerformanceService.ctorParameters = () => [
40574
- { type: SignalRService },
40575
- { type: CommonService },
40576
- { type: HttpClient },
40577
- { type: ModuleConfigService }
40578
- ];
40579
-
40580
41085
  class ImageService {
40581
41086
  constructor(_moduleConfigService) {
40582
41087
  this._moduleConfigService = _moduleConfigService;
@@ -40726,231 +41231,65 @@ class RandomDataService {
40726
41231
  }
40727
41232
  return result;
40728
41233
  }
40729
- randomString(lengthOfString) {
40730
- if (lengthOfString < 3)
40731
- lengthOfString = 3;
40732
- // if (lengthOfString > 8) lengthOfString = 8;
40733
- var text = '';
40734
- var possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890 ';
40735
- for (var i = 0; i < lengthOfString; i++) {
40736
- text += possible[Math.floor(Math.random() * possible.length)];
40737
- }
40738
- return text;
40739
- }
40740
- }
40741
- RandomDataService.ɵprov = i0.ɵɵdefineInjectable({ factory: function RandomDataService_Factory() { return new RandomDataService(); }, token: RandomDataService, providedIn: "root" });
40742
- RandomDataService.decorators = [
40743
- { type: Injectable, args: [{
40744
- providedIn: 'root'
40745
- },] }
40746
- ];
40747
- RandomDataService.ctorParameters = () => [];
40748
-
40749
- class TemplateTextV4Service extends BaseService {
40750
- constructor(_moduleConfigService, _httpClient, _printService, _fileV4Service, _notifierService, _crudService, _commonService, injector) {
40751
- super(_httpClient, injector, `${_moduleConfigService.getConfig().environment.v4.apiDomain.templateEndpoint}/templateText`);
40752
- this._httpClient = _httpClient;
40753
- this._printService = _printService;
40754
- this._fileV4Service = _fileV4Service;
40755
- this._notifierService = _notifierService;
40756
- this._crudService = _crudService;
40757
- this._commonService = _commonService;
40758
- this.injector = injector;
40759
- }
40760
- compileContentByCode(code, data) {
40761
- const url = `${this.serviceUri}/CompileContentByCode/${code}`;
40762
- return this.defaultPost(url, data);
40763
- }
40764
- compileSingle(data) {
40765
- const url = `${this.serviceUri}/CompileSingle`;
40766
- return this.defaultPost(url, data);
40767
- }
40768
- compileMany(data) {
40769
- const url = `${this.serviceUri}/CompileMany`;
40770
- return this.defaultPost(url, data);
40771
- }
40772
- }
40773
- TemplateTextV4Service.ɵprov = i0.ɵɵdefineInjectable({ factory: function TemplateTextV4Service_Factory() { return new TemplateTextV4Service(i0.ɵɵinject(ModuleConfigService), i0.ɵɵinject(i1$1.HttpClient), i0.ɵɵinject(PrintService), i0.ɵɵinject(FileV4Service), i0.ɵɵinject(NotifierService), i0.ɵɵinject(CrudService), i0.ɵɵinject(CommonService), i0.ɵɵinject(i0.INJECTOR)); }, token: TemplateTextV4Service, providedIn: "root" });
40774
- TemplateTextV4Service.decorators = [
40775
- { type: Injectable, args: [{
40776
- providedIn: 'root'
40777
- },] }
40778
- ];
40779
- TemplateTextV4Service.ctorParameters = () => [
40780
- { type: ModuleConfigService },
40781
- { type: HttpClient },
40782
- { type: PrintService },
40783
- { type: FileV4Service },
40784
- { type: NotifierService },
40785
- { type: CrudService },
40786
- { type: CommonService },
40787
- { type: Injector }
40788
- ];
40789
-
40790
- class TemplateService {
40791
- constructor(_moduleConfigService, _httpClient, _printService, _fileService, _notifierService, _crudService, _commonService) {
40792
- this._httpClient = _httpClient;
40793
- this._printService = _printService;
40794
- this._fileService = _fileService;
40795
- this._notifierService = _notifierService;
40796
- this._crudService = _crudService;
40797
- this._commonService = _commonService;
40798
- this._moduleConfig = _moduleConfigService.getConfig();
40799
- this.environment = this._moduleConfig.environment;
40800
- this.serviceUri = `${this.environment.apiDomain.templateEndpoint}/template`;
40801
- }
40802
- laTexToBase64Image(laTex, font = 54) {
40803
- const api = `${this.serviceUri}/LatexToBase64`;
40804
- return this._httpClient.post(api, { laTex, font }).toPromise();
40805
- }
40806
- /**
40807
- * Description: Xuất file sử dụng thư viện CX, xuất xong tự động mở popup để lưu file.
40808
- */
40809
- exportCxExcelByCode(model) {
40810
- const url = `${this.serviceUri}/ExportCxExcelByCode`;
40811
- this.setFileInfo(model);
40812
- return this._httpClient
40813
- .post(url, model, { responseType: 'blob' })
40814
- .toPromise()
40815
- .then(res => {
40816
- FileSaver.saveAs(res, this.getFullFileName(model.fileName || model.code));
40817
- }).catch((err) => __awaiter(this, void 0, void 0, function* () {
40818
- const errorText = yield err.error.text();
40819
- this._crudService.processErrorResponse(JSON.parse(errorText || ''));
40820
- }));
40821
- }
40822
- exportManyCxExcelByCode(model) {
40823
- const url = `${this.serviceUri}/ExportManyCxExcelByCode`;
40824
- this.setManyFileInfo(model);
40825
- return this._httpClient
40826
- .post(url, model)
40827
- .toPromise()
40828
- .then(res => {
40829
- if (res.success) {
40830
- this._fileService.downloadFolder(res.data.folderId);
40831
- }
40832
- else {
40833
- this._crudService.processErrorResponse(res);
40834
- }
40835
- }).catch((err) => __awaiter(this, void 0, void 0, function* () {
40836
- const errorText = yield err.error.text();
40837
- this._crudService.processErrorResponse(JSON.parse(errorText || ''));
40838
- }));
40839
- }
40840
- getFullFileName(fileName, extension = TemplateConstant.EXCEL_EXTENSION) {
40841
- return `${fileName}${extension}`;
40842
- }
40843
- /**
40844
- * Description: Export sử dung ClosedXml.Report (Cx) với signalR, sử dụng cho file dữ liệu lớn.
40845
- * Param: model chứa
40846
- * - code : code của template cấu hình bên Quản trị > Biểu mẫu > Biểu mẫu excel.
40847
- * - data : object chứa dữ liệu đã chuyền thành dạng json.
40848
- * - fileName: tên file sau khi export.
40849
- * - topic: guid dùng để subscribe.
40850
- */
40851
- ExportCxExcelByCodeWithSignalR(model) {
40852
- return __awaiter(this, void 0, void 0, function* () {
40853
- const url = `${this.serviceUri}/ExportCxExcelByCodeWithSignalR`;
40854
- return this._httpClient.post(url, model)
40855
- .toPromise();
40856
- });
40857
- }
40858
- /**
40859
- * Description: Export sử dung ClosedXml.Report (Cx) với HighPerformanceService, sử dụng cho file dữ liệu lớn.
40860
- * Param: model chứa
40861
- * - code : code của template cấu hình bên Quản trị > Biểu mẫu > Biểu mẫu excel.
40862
- * - data : object chứa dữ liệu đã chuyền thành dạng json.
40863
- * - fileName: tên file sau khi export.
40864
- * - queueName: queue của topic.
40865
- * - uniqueKey: unique key cho task.
40866
- */
40867
- ExportCxExcelByCodeWithHPS(model) {
40868
- return __awaiter(this, void 0, void 0, function* () {
40869
- const url = `${this.serviceUri}/ExportWithHighPerformanceService`;
40870
- return this._httpClient.post(url, model)
40871
- .toPromise();
40872
- });
40873
- }
40874
- exportCxExcelByCodePromise(model) {
40875
- return __awaiter(this, void 0, void 0, function* () {
40876
- const url = `${this.serviceUri}/ExportCxExcelByCode`;
40877
- return this._httpClient
40878
- .post(url, model, { responseType: 'blob' })
40879
- .toPromise();
40880
- });
40881
- }
40882
- fillTemplateByCodeAndGetPdf(templateCode, data, onLoadingDataPdf = null, onEndLoadingDataPdf = null) {
40883
- const url = `${this.serviceUri}/fillWordByTemplateCode/${templateCode}?isPrint=true`;
40884
- return this._httpClient
40885
- .post(url, data)
40886
- .toPromise().then(res => {
40887
- if (res.data) {
40888
- this._printService.printBase64Pdf(res.data, onLoadingDataPdf, onEndLoadingDataPdf);
40889
- }
40890
- });
40891
- }
40892
- fillWordByTemplateCodeMultiData(templateCode, data, onLoadingDataPdf = null, onEndLoadingDataPdf = null) {
40893
- const url = `${this.serviceUri}/fillWordByTemplateCodeMultiData/${templateCode}?isPrint=true`;
40894
- return this._httpClient
40895
- .post(url, data)
40896
- .toPromise().then(res => {
40897
- if (res.data) {
40898
- this._printService.printBase64Pdf(res.data, onLoadingDataPdf, onEndLoadingDataPdf);
40899
- }
40900
- });
41234
+ randomString(lengthOfString) {
41235
+ if (lengthOfString < 3)
41236
+ lengthOfString = 3;
41237
+ // if (lengthOfString > 8) lengthOfString = 8;
41238
+ var text = '';
41239
+ var possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890 ';
41240
+ for (var i = 0; i < lengthOfString; i++) {
41241
+ text += possible[Math.floor(Math.random() * possible.length)];
41242
+ }
41243
+ return text;
40901
41244
  }
40902
- setFileInfo(model) {
40903
- model.data = model.data ? model.data : JSON.stringify(model.dataObject);
40904
- delete model.dataObject;
41245
+ }
41246
+ RandomDataService.ɵprov = i0.ɵɵdefineInjectable({ factory: function RandomDataService_Factory() { return new RandomDataService(); }, token: RandomDataService, providedIn: "root" });
41247
+ RandomDataService.decorators = [
41248
+ { type: Injectable, args: [{
41249
+ providedIn: 'root'
41250
+ },] }
41251
+ ];
41252
+ RandomDataService.ctorParameters = () => [];
41253
+
41254
+ class TemplateTextV4Service extends BaseService {
41255
+ constructor(_moduleConfigService, _httpClient, _printService, _fileV4Service, _notifierService, _crudService, _commonService, injector) {
41256
+ super(_httpClient, injector, `${_moduleConfigService.getConfig().environment.v4.apiDomain.templateEndpoint}/templateText`);
41257
+ this._httpClient = _httpClient;
41258
+ this._printService = _printService;
41259
+ this._fileV4Service = _fileV4Service;
41260
+ this._notifierService = _notifierService;
41261
+ this._crudService = _crudService;
41262
+ this._commonService = _commonService;
41263
+ this.injector = injector;
40905
41264
  }
40906
- setManyFileInfo(manyModel) {
40907
- let hasModel = manyModel && manyModel.lstFileInfo && manyModel.lstFileInfo.length;
40908
- if (!hasModel) {
40909
- return;
40910
- }
40911
- manyModel.lstFileInfo.forEach(fileInfo => {
40912
- this.setFileInfo(fileInfo);
40913
- fileInfo.fileName = `${fileInfo.fileName}_${this._commonService.guid()}.${TemplateConstant.EXCEL_EXTENSION}`;
40914
- });
41265
+ compileContentByCode(code, data) {
41266
+ const url = `${this.serviceUri}/CompileContentByCode/${code}`;
41267
+ return this.defaultPost(url, data);
40915
41268
  }
40916
- /**
40917
- * Export dữ liệu không dùng template.
40918
- */
40919
- exportCxExcel(model) {
40920
- const url = `${this.serviceUri}/ExportCxExcel`;
40921
- return this._httpClient
40922
- .post(url, model, { responseType: 'blob' })
40923
- .toPromise()
40924
- .then(res => {
40925
- FileSaver.saveAs(res, this.getFullFileName(model.fileName || 'Export'));
40926
- }).catch((err) => __awaiter(this, void 0, void 0, function* () {
40927
- const errorText = yield err.error.text();
40928
- this._crudService.processErrorResponse(JSON.parse(errorText || ''));
40929
- }));
41269
+ compileSingle(data) {
41270
+ const url = `${this.serviceUri}/CompileSingle`;
41271
+ return this.defaultPost(url, data);
40930
41272
  }
40931
- exportCxExcelPromise(model) {
40932
- return __awaiter(this, void 0, void 0, function* () {
40933
- const url = `${this.serviceUri}/ExportCxExcel`;
40934
- return this._httpClient
40935
- .post(url, model, { responseType: 'blob' })
40936
- .toPromise();
40937
- });
41273
+ compileMany(data) {
41274
+ const url = `${this.serviceUri}/CompileMany`;
41275
+ return this.defaultPost(url, data);
40938
41276
  }
40939
41277
  }
40940
- TemplateService.ɵprov = i0.ɵɵdefineInjectable({ factory: function TemplateService_Factory() { return new TemplateService(i0.ɵɵinject(ModuleConfigService), i0.ɵɵinject(i1$1.HttpClient), i0.ɵɵinject(PrintService), i0.ɵɵinject(FileExplorerService), i0.ɵɵinject(NotifierService), i0.ɵɵinject(CrudService), i0.ɵɵinject(CommonService)); }, token: TemplateService, providedIn: "root" });
40941
- TemplateService.decorators = [
41278
+ TemplateTextV4Service.ɵprov = i0.ɵɵdefineInjectable({ factory: function TemplateTextV4Service_Factory() { return new TemplateTextV4Service(i0.ɵɵinject(ModuleConfigService), i0.ɵɵinject(i1$1.HttpClient), i0.ɵɵinject(PrintService), i0.ɵɵinject(FileV4Service), i0.ɵɵinject(NotifierService), i0.ɵɵinject(CrudService), i0.ɵɵinject(CommonService), i0.ɵɵinject(i0.INJECTOR)); }, token: TemplateTextV4Service, providedIn: "root" });
41279
+ TemplateTextV4Service.decorators = [
40942
41280
  { type: Injectable, args: [{
40943
41281
  providedIn: 'root'
40944
41282
  },] }
40945
41283
  ];
40946
- TemplateService.ctorParameters = () => [
41284
+ TemplateTextV4Service.ctorParameters = () => [
40947
41285
  { type: ModuleConfigService },
40948
41286
  { type: HttpClient },
40949
41287
  { type: PrintService },
40950
- { type: FileExplorerService },
41288
+ { type: FileV4Service },
40951
41289
  { type: NotifierService },
40952
41290
  { type: CrudService },
40953
- { type: CommonService }
41291
+ { type: CommonService },
41292
+ { type: Injector }
40954
41293
  ];
40955
41294
 
40956
41295
  class UniqueNumberService {
@@ -46859,192 +47198,44 @@ class MaskComponent {
46859
47198
  }
46860
47199
  }
46861
47200
  else {
46862
- this.value = null;
46863
- }
46864
- }
46865
- numberToStringVN(number) {
46866
- return this._numberPipe.transform(number, '', 'vi-VN');
46867
- }
46868
- registerOnChange(fn) {
46869
- this.onChange = fn;
46870
- }
46871
- registerOnTouched(fn) {
46872
- this.onTouched = fn;
46873
- }
46874
- setDisabledState(isDisabled) {
46875
- if (!isDisabled)
46876
- this.disabled = null;
46877
- else
46878
- this.disabled = true;
46879
- }
46880
- }
46881
- MaskComponent.decorators = [
46882
- { type: Component, args: [{
46883
- selector: 'tn-mask',
46884
- template: "<ng-container *ngIf=\"viewMode\">\n <div class=\"tn-mask-viewMode\">\n <span *ngIf=\"prefix\">{{prefix}}</span>\n <span *ngIf=\"autoFormat\">{{value | number}}</span>\n <span *ngIf=\"!autoFormat\">{{value}}</span>\n <span *ngIf=\"suffix\">({{suffix}})</span>\n </div>\n</ng-container>\n<ng-container *ngIf=\"!viewMode\">\n <div class=\"p-inputgroup\">\n <span *ngIf=\"prefix\" class=\"p-inputgroup-addon\">{{prefix}}</span>\n <input type=\"text\" pInputText [placeholder]=\"_placeholder\" [attr.disabled]=\"disabled ? true : null\"\n [mask]=\"getMaskByType(maskType)\" [thousandSeparator]=\"thousandSeperator\" [class]=\"inputStyleClass\"\n [decimalMarker]=\"decimalMarker\" [(ngModel)]=\"value\" (focus)=\"handleFocus()\" (blur)=\"handleBlur()\"\n (change)=\"handleChangedValue()\" />\n <span *ngIf=\"suffix\" class=\"p-inputgroup-addon\">({{suffix}})</span>\n </div>\n</ng-container>",
46885
- providers: [
46886
- {
46887
- provide: NG_VALUE_ACCESSOR,
46888
- useExisting: forwardRef(() => MaskComponent),
46889
- multi: true
46890
- },
46891
- DecimalPipe
46892
- ],
46893
- styles: [".tn-mask-viewMode>span{margin-right:3px}.tn-mask-viewMode>span:last-child{margin-right:0}"]
46894
- },] }
46895
- ];
46896
- MaskComponent.ctorParameters = () => [
46897
- { type: DecimalPipe }
46898
- ];
46899
- MaskComponent.propDecorators = {
46900
- maskType: [{ type: Input }],
46901
- placeholder: [{ type: Input }],
46902
- disabled: [{ type: Input }],
46903
- suffix: [{ type: Input }],
46904
- prefix: [{ type: Input }],
46905
- min: [{ type: Input }],
46906
- max: [{ type: Input }],
46907
- decimalPlaces: [{ type: Input }],
46908
- viewMode: [{ type: Input }],
46909
- inputStyleClass: [{ type: Input }],
46910
- autoFormat: [{ type: Input }],
46911
- onInit: [{ type: Output }],
46912
- onFocus: [{ type: Output }],
46913
- onBlur: [{ type: Output }],
46914
- onChanged: [{ type: Output }]
46915
- };
46916
-
46917
- class NumberPickerRangeComponent {
46918
- constructor(_numberPipe) {
46919
- this._numberPipe = _numberPipe;
46920
- this.model = [null, null];
46921
- this.readonly = false;
46922
- this.maskType = 'decimal';
46923
- this.placeholder = '';
46924
- this.disabled = null;
46925
- this.suffix = '';
46926
- this.prefix = '';
46927
- this.decimalPlaces = 2;
46928
- this.onInit = new EventEmitter();
46929
- this.focus = new EventEmitter();
46930
- this.enterSmart = new EventEmitter();
46931
- this.enter = new EventEmitter();
46932
- this.blur = new EventEmitter();
46933
- this.change = new EventEmitter();
46934
- this.placeholerTu = 'Từ';
46935
- this.placeholerDen = 'Đến';
46936
- }
46937
- ngOnInit() {
46938
- this.onInit.emit(this);
46939
- if (this.placeholder) {
46940
- this.placeholerTu = `${this.placeholder} từ`;
46941
- this.placeholerDen = `${this.placeholder} đến`;
46942
- }
46943
- }
46944
- clear() {
46945
- const re = (this.model[0] != null && this.model[0] !== '') || (this.model[1] != null && this.model[1] !== '');
46946
- this.model = [null, null];
46947
- this.onChange(this.model);
46948
- return re;
46949
- }
46950
- writeValue(obj) {
46951
- if (obj != null && obj != '')
46952
- this.model = obj;
46953
- else
46954
- this.model = [null, null];
46955
- }
46956
- registerOnChange(fn) {
46957
- this.onChange = fn;
46958
- }
46959
- registerOnTouched(fn) {
46960
- this.onTouched = fn;
46961
- }
46962
- setDisabledState(isDisabled) {
46963
- if (!isDisabled)
46964
- this.disabled = null;
46965
- else
46966
- this.disabled = true;
46967
- }
46968
- getMaskByType(maskType) {
46969
- if (maskType === 'decimal')
46970
- return `separator.${this.decimalPlaces}`;
46971
- return 'separator.0';
46972
- }
46973
- getThousandSeperator() {
46974
- if (this.maskType === 'intWithoutMask')
46975
- return '';
46976
- return '.';
46977
- }
46978
- checkValueInRange() {
46979
- // if (!this.model || this.maskType != 'int') {
46980
- // return;
46981
- // }
46982
- if (this.min) {
46983
- const min = Number(this.min);
46984
- if (Number(this.model[0]) < min)
46985
- this.model[0] = min;
46986
- if (Number(this.model[1]) < min)
46987
- this.model[1] = min;
46988
- }
46989
- if (this.max) {
46990
- const max = Number(this.max);
46991
- if (Number(this.model[0]) > max)
46992
- this.model[0] = max;
46993
- if (Number(this.model[1]) > max)
46994
- this.model[1] = max;
46995
- }
46996
- }
46997
- onChanged(evt) {
46998
- this.enter.next(evt);
46999
- this.compareAndEmit();
47000
- }
47001
- onFocus(evt, index) {
47002
- this.focus.emit({
47003
- event: evt,
47004
- index
47005
- });
47006
- }
47007
- compareAndEmit() {
47008
- this.checkValueInRange();
47009
- let value = [null, null];
47010
- if (this.model[0]) {
47011
- value[0] = Number(this.model[0]);
47012
- if (this.model[1]) {
47013
- value[1] = Number(this.model[1]);
47014
- if (value[0] > value[1]) {
47015
- value = value.reverse();
47016
- }
47017
- }
47018
- }
47019
- else {
47020
- if (this.model[1])
47021
- value[1] = Number(this.model[1]);
47022
- }
47023
- this.onChange(value);
47024
- this.model[0] = value[0];
47025
- this.model[1] = value[1];
47026
- this.change.emit(value);
47201
+ this.value = null;
47202
+ }
47203
+ }
47204
+ numberToStringVN(number) {
47205
+ return this._numberPipe.transform(number, '', 'vi-VN');
47206
+ }
47207
+ registerOnChange(fn) {
47208
+ this.onChange = fn;
47209
+ }
47210
+ registerOnTouched(fn) {
47211
+ this.onTouched = fn;
47212
+ }
47213
+ setDisabledState(isDisabled) {
47214
+ if (!isDisabled)
47215
+ this.disabled = null;
47216
+ else
47217
+ this.disabled = true;
47027
47218
  }
47028
47219
  }
47029
- NumberPickerRangeComponent.decorators = [
47220
+ MaskComponent.decorators = [
47030
47221
  { type: Component, args: [{
47031
- selector: 'tn-number-picker-range',
47032
- template: "<div class=\"tn-number-picker-range\">\n <input type=\"text\" placeholder=\"{{placeholerTu}}\" [attr.disabled]=\"disabled ? true : null\"\n [mask]=\"getMaskByType(maskType)\" [thousandSeparator]=\"getThousandSeperator()\" pInputText [(ngModel)]=\"model[0]\"\n (change)=\"onChanged($event)\" (focus)=\"onFocus($event, 0)\" />\n <span>-</span>\n <input type=\"text\" placeholder=\"{{placeholerDen}}\" [attr.disabled]=\"disabled ? true : null\"\n [mask]=\"getMaskByType(maskType)\" [thousandSeparator]=\"getThousandSeperator()\" pInputText [(ngModel)]=\"model[1]\"\n (change)=\"onChanged($event)\" (focus)=\"onFocus($event, 1)\" />\n</div>",
47222
+ selector: 'tn-mask',
47223
+ template: "<ng-container *ngIf=\"viewMode\">\n <div class=\"tn-mask-viewMode\">\n <span *ngIf=\"prefix\">{{prefix}}</span>\n <span *ngIf=\"autoFormat\">{{value | number}}</span>\n <span *ngIf=\"!autoFormat\">{{value}}</span>\n <span *ngIf=\"suffix\">({{suffix}})</span>\n </div>\n</ng-container>\n<ng-container *ngIf=\"!viewMode\">\n <div class=\"p-inputgroup\">\n <span *ngIf=\"prefix\" class=\"p-inputgroup-addon\">{{prefix}}</span>\n <input type=\"text\" pInputText [placeholder]=\"_placeholder\" [attr.disabled]=\"disabled ? true : null\"\n [mask]=\"getMaskByType(maskType)\" [thousandSeparator]=\"thousandSeperator\" [class]=\"inputStyleClass\"\n [decimalMarker]=\"decimalMarker\" [(ngModel)]=\"value\" (focus)=\"handleFocus()\" (blur)=\"handleBlur()\"\n (change)=\"handleChangedValue()\" />\n <span *ngIf=\"suffix\" class=\"p-inputgroup-addon\">({{suffix}})</span>\n </div>\n</ng-container>",
47033
47224
  providers: [
47034
47225
  {
47035
47226
  provide: NG_VALUE_ACCESSOR,
47036
- useExisting: forwardRef(() => NumberPickerRangeComponent),
47227
+ useExisting: forwardRef(() => MaskComponent),
47037
47228
  multi: true
47038
- }
47229
+ },
47230
+ DecimalPipe
47039
47231
  ],
47040
- styles: [".tn-number-picker-range{display:flex}.tn-number-picker-range>span{flex:0 0 16px;display:inline-flex;align-items:center;justify-content:center}::ng-deep .tn-number-picker-range .p-inputtext{flex:0 0 calc(50% - 8px);width:calc(50% - 8px)}"]
47232
+ styles: [".tn-mask-viewMode>span{margin-right:3px}.tn-mask-viewMode>span:last-child{margin-right:0}"]
47041
47233
  },] }
47042
47234
  ];
47043
- NumberPickerRangeComponent.ctorParameters = () => [
47235
+ MaskComponent.ctorParameters = () => [
47044
47236
  { type: DecimalPipe }
47045
47237
  ];
47046
- NumberPickerRangeComponent.propDecorators = {
47047
- readonly: [{ type: Input }],
47238
+ MaskComponent.propDecorators = {
47048
47239
  maskType: [{ type: Input }],
47049
47240
  placeholder: [{ type: Input }],
47050
47241
  disabled: [{ type: Input }],
@@ -47053,821 +47244,630 @@ NumberPickerRangeComponent.propDecorators = {
47053
47244
  min: [{ type: Input }],
47054
47245
  max: [{ type: Input }],
47055
47246
  decimalPlaces: [{ type: Input }],
47247
+ viewMode: [{ type: Input }],
47248
+ inputStyleClass: [{ type: Input }],
47249
+ autoFormat: [{ type: Input }],
47056
47250
  onInit: [{ type: Output }],
47057
- focus: [{ type: Output }],
47058
- enterSmart: [{ type: Output }],
47059
- enter: [{ type: Output }],
47060
- blur: [{ type: Output }],
47061
- change: [{ type: Output }]
47251
+ onFocus: [{ type: Output }],
47252
+ onBlur: [{ type: Output }],
47253
+ onChanged: [{ type: Output }]
47062
47254
  };
47063
47255
 
47064
- class PagingNextBackOnlyComponent {
47065
- constructor() {
47066
- this.onNext = new EventEmitter();
47067
- this.onPrev = new EventEmitter();
47068
- this.onLatest = new EventEmitter();
47069
- this.onRefresh = new EventEmitter();
47070
- this.onOldest = new EventEmitter();
47071
- this.onChangeLimitPage = new EventEmitter();
47072
- this.onChanged = new EventEmitter();
47256
+ class NumberPickerRangeComponent {
47257
+ constructor(_numberPipe) {
47258
+ this._numberPipe = _numberPipe;
47259
+ this.model = [null, null];
47260
+ this.readonly = false;
47261
+ this.maskType = 'decimal';
47262
+ this.placeholder = '';
47263
+ this.disabled = null;
47264
+ this.suffix = '';
47265
+ this.prefix = '';
47266
+ this.decimalPlaces = 2;
47267
+ this.onInit = new EventEmitter();
47268
+ this.focus = new EventEmitter();
47269
+ this.enterSmart = new EventEmitter();
47270
+ this.enter = new EventEmitter();
47271
+ this.blur = new EventEmitter();
47272
+ this.change = new EventEmitter();
47273
+ this.placeholerTu = 'Từ';
47274
+ this.placeholerDen = 'Đến';
47073
47275
  }
47074
47276
  ngOnInit() {
47075
- this.pageSizeOld = this.setting.pageSetting.pageSize;
47076
- }
47077
- getFirstIndex() {
47078
- return (this.setting.pageSetting.page - 1) * this.setting.pageSetting.pageSize + 1;
47079
- }
47080
- getLastIndex() {
47081
- let temp = this.setting.pageSetting.page * this.setting.pageSetting.pageSize;
47082
- if (temp > this.model.total)
47083
- temp = this.model.total;
47084
- return temp;
47085
- }
47086
- goLatest(evt) {
47087
- if (this.isFirst() || this.model.loading)
47088
- return;
47089
- if (this.setting.pageSetting.pageSize == 0) {
47090
- this.setting.pageSetting.pageSize = 1;
47091
- }
47092
- if (this.setting.pageSetting.pageSize > 1000) {
47093
- this.setting.pageSetting.pageSize = 1000;
47094
- }
47095
- this.setting.pageSetting.page = 1;
47096
- this.op.hide();
47097
- this.onLatest.next(evt);
47098
- this.onChanged.emit();
47099
- }
47100
- goPrev(evt) {
47101
- if (this.isFirst() || this.model.loading)
47102
- return;
47103
- if (this.setting.pageSetting.page > 1) {
47104
- this.setting.pageSetting.page--;
47105
- }
47106
- this.op.hide();
47107
- this.onPrev.next(evt);
47108
- this.onChanged.emit();
47109
- }
47110
- isFirst() {
47111
- return this.setting.pageSetting.page <= 1;
47112
- }
47113
- goNext(evt) {
47114
- if (this.isLast() || this.model.loading)
47115
- return;
47116
- this.setting.pageSetting.page++;
47117
- this.op.hide();
47118
- this.onNext.next(evt);
47119
- this.onChanged.emit();
47120
- }
47121
- isLast() {
47122
- return this.model.total <= 0 || this.getLastIndex() == this.model.total;
47123
- }
47124
- goOldest(evt) {
47125
- if (this.isLast() || this.model.loading)
47126
- return;
47127
- this.setting.pageSetting.page = Math.ceil(this.model.total / this.setting.pageSetting.pageSize);
47128
- this.onOldest.next(evt);
47129
- this.onChanged.emit();
47130
- }
47131
- saveChangeHandle() {
47132
- if (!this.setting.pageSetting.pageSize || this.setting.pageSetting.pageSize.toString() == '0') {
47133
- this.setting.pageSetting.pageSize = this.pageSizeOld;
47277
+ this.onInit.emit(this);
47278
+ if (this.placeholder) {
47279
+ this.placeholerTu = `${this.placeholder} từ`;
47280
+ this.placeholerDen = `${this.placeholder} đến`;
47134
47281
  }
47135
- this.pageSizeOld = this.setting.pageSetting.pageSize;
47136
- this.goLatest(null);
47137
- this.onChangeLimitPage.next(null);
47138
- this.onChanged.emit();
47139
- }
47140
- handleOverlayShow(evt, targetOverlay) {
47141
- }
47142
- refresh(event) {
47143
- }
47144
- }
47145
- PagingNextBackOnlyComponent.decorators = [
47146
- { type: Component, args: [{
47147
- selector: 'paging-next-back-only',
47148
- template: "<div class=\"paging-container\" [ngClass]=\"ngClass\">\n <div class=\"paging-info\">\n <ng-container>\n <div *ngIf=\"getFirstIndex()<=model.total && !setting.hiddenTextPage\" #targetOverlay\n class=\"paging-item paging-info-detail\" (click)=\"op.toggle($event)\">\n {{getFirstIndex()}} -\n {{getLastIndex()}}\n trong {{model.total}}\n </div>\n <div *ngIf=\"(getFirstIndex()>model.total || model.total == 0) && !setting.hiddenTextPage\"\n class=\"paging-item paging-info-detail\">\n Kh\u00F4ng t\u00ECm th\u1EA5y d\u1EEF li\u1EC7u\n </div>\n <div class=\"paging-item text\" [class.disabled]=\"model.loading\" (click)=\"goPrev($event)\"\n style=\"margin-right: 5px;\" pTooltip=\"{{'Trang tr\u01B0\u1EDBc' | translate}}\" tooltipPosition=\"top\"\n [class.disabled]=\"isFirst()\">\n <a href=\"javascript:\" tabindex=\"{{isFirst()?'-1':''}}\"><i class=\"pi pi-chevron-left\"></i></a>\n </div>\n <div class=\"block-page-size\">\n <tn-mask [maskType]=\"'int'\" [min]=\"1\" [max]=\"1000\" [disabled]=\"model.loading ? true : null\"\n [(ngModel)]=\"setting.pageSetting.pageSize\" (onChanged)=\"saveChangeHandle()\"\n (keyup.enter)=\"saveChangeHandle()\">\n </tn-mask>\n </div>\n <div class=\"paging-item text\" [class.disabled]=\"model.loading\" (click)=\"goNext($event)\"\n style=\"margin-left: 5px;\" pTooltip=\"{{'Trang sau' | translate}}\" tooltipPosition=\"left\"\n [class.disabled]=\"isLast()\">\n <a href=\"javascript:\" tabindex=\"{{isLast()?'-1':''}}\"><i class=\"pi pi-chevron-right\"></i></a>\n </div>\n </ng-container>\n </div>\n</div>\n\n<p-overlayPanel #op [styleClass]=\"'paging-advance-overlay'\" [appendTo]=\"'body'\"\n (onShow)=\"handleOverlayShow($event, targetOverlay)\">\n <ul class=\"paging-advance\">\n <li [class.disabled]=\"isFirst()\" (click)=\"goLatest($event)\">Trang \u0111\u1EA7u ti\u00EAn</li>\n <li [class.disabled]=\"isLast()\" (click)=\"goOldest($event)\">Trang cu\u1ED1i c\u00F9ng</li>\n </ul>\n</p-overlayPanel>",
47149
- styles: [".paging-item a{color:#495057}.paging-item:hover{cursor:pointer}.paging-item:hover a{color:#333}.paging-item.disabled a{color:#bdbdbd}.paging-info-detail{padding:2px .5rem 0;text-align:center;line-height:30px;border-radius:7px;min-width:100px;font-size:.9em}.paging-item.text{line-height:32px;border-radius:50%;width:32px;height:32px;text-align:center;position:relative;display:inline-block;transform:perspective(1px);overflow:hidden}.paging-item.text:before{content:\"\";position:absolute;top:0;left:0;bottom:0;right:0;background:#e6e6e6;z-index:-1;transform:scale(0);transition:all .3s cubic-bezier(.4,.34,.01,.97);border-radius:50%}.paging-item.text:hover:before{transform:scale(1)}.paging-item.text>a{display:flex;justify-content:center;align-items:center;width:100%;height:100%}.paging-info-detail{border-radius:5px;position:relative;display:inline-block;transform:perspective(1px);overflow:hidden}.paging-info-detail:before{content:\"\";position:absolute;top:0;left:0;bottom:0;right:0;background:#e6e6e6;z-index:-1;transform:scale(0);transition:all .3s cubic-bezier(.4,.34,.01,.97);border-radius:5px}.paging-info-detail:hover:before{transform:scale(1)}.paging-item.disabled:hover:before{content:none}.paging-item.disabled:hover{background-color:#fff;cursor:default}.paging-item.disabled:hover a{cursor:default}.paging-info{display:flex;justify-content:flex-end;align-items:center}.item-setting{font-size:18px}.item-setting a{color:#555}.item-setting a:hover{color:#333}.paging-advance{list-style:none;padding-left:0;margin:3px 0}.paging-advance li{width:150px;padding-left:15px;line-height:30px}.paging-advance li.disabled{color:#bdbdbd;outline:none}.paging-advance li.disabled:hover{cursor:default;background:none}.paging-advance li:hover{cursor:pointer;background:#e6e6e6}::ng-deep .paging-advance-overlay{margin-left:30px}::ng-deep .paging-advance-overlay .p-overlaypanel-content{padding:0}::ng-deep paging-next-back-only .block-page-size{display:inline-block;width:60px}::ng-deep paging-next-back-only .block-page-size .p-inputtext{width:100%;text-align:center;padding-left:5px;padding-right:5px}::ng-deep paging-next-back-only .tn-mask-disabled{padding:5px;border:1px solid #ddd;border-radius:4px;display:flex;justify-content:center;line-height:20px}"]
47150
- },] }
47151
- ];
47152
- PagingNextBackOnlyComponent.ctorParameters = () => [];
47153
- PagingNextBackOnlyComponent.propDecorators = {
47154
- op: [{ type: ViewChild, args: ['op', { static: true },] }],
47155
- model: [{ type: Input }],
47156
- setting: [{ type: Input }],
47157
- ngClass: [{ type: Input }],
47158
- onNext: [{ type: Output }],
47159
- onPrev: [{ type: Output }],
47160
- onLatest: [{ type: Output }],
47161
- onRefresh: [{ type: Output }],
47162
- onOldest: [{ type: Output }],
47163
- onChangeLimitPage: [{ type: Output }],
47164
- onChanged: [{ type: Output }]
47165
- };
47166
-
47167
- class QrCodeGeneratorComponent {
47168
- constructor() {
47169
- this.width = 120;
47170
- this._data = '';
47171
- this.defaultText = 'empty';
47172
- }
47173
- set data(value) {
47174
- this._data = value;
47175
- this.convert();
47176
47282
  }
47177
- ngOnInit() {
47178
- this.convert();
47283
+ clear() {
47284
+ const re = (this.model[0] != null && this.model[0] !== '') || (this.model[1] != null && this.model[1] !== '');
47285
+ this.model = [null, null];
47286
+ this.onChange(this.model);
47287
+ return re;
47179
47288
  }
47180
- convert() {
47181
- if (!this._data) {
47182
- this._data = this.defaultText;
47183
- }
47184
- toCanvas(this.canvasElement.nativeElement, this._data, {
47185
- width: this.width
47186
- }, (error) => {
47187
- if (error)
47188
- console.error(error);
47189
- });
47289
+ writeValue(obj) {
47290
+ if (obj != null && obj != '')
47291
+ this.model = obj;
47292
+ else
47293
+ this.model = [null, null];
47190
47294
  }
47191
- download() {
47192
- const link = document.createElement('a');
47193
- link.download = 'qrcode.png';
47194
- link.href = this.canvasElement.nativeElement.toDataURL();
47195
- link.click();
47196
- link.remove();
47295
+ registerOnChange(fn) {
47296
+ this.onChange = fn;
47197
47297
  }
47198
- }
47199
- QrCodeGeneratorComponent.decorators = [
47200
- { type: Component, args: [{
47201
- selector: 'app-qr-code-generator',
47202
- template: "<div class=\"qr-code-generator\" [style.width.px]=\"width\" [style.height.px]=\"width\">\n <canvas #canvasElement width=\"100%\" height=\"100%\"></canvas>\n <div class=\"mask\">\n <span class=\"icon-download fa fa-download\" pTooltip=\"B\u1EA5m \u0111\u1EC3 t\u1EA3i v\u1EC1\" tooltipPosition=\"top\"\n (click)=\"download()\"></span>\n </div>\n</div>",
47203
- styles: [".qr-code-generator{position:relative}.qr-code-generator .mask{display:none;position:absolute;top:0;left:0;width:100%;height:100%;background:hsla(0,0%,50.2%,.8392156862745098);border-radius:3px}.qr-code-generator .mask .icon-download{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);cursor:pointer;color:#00ff2b;font-size:2rem}.qr-code-generator:hover .mask{display:initial}"]
47204
- },] }
47205
- ];
47206
- QrCodeGeneratorComponent.ctorParameters = () => [];
47207
- QrCodeGeneratorComponent.propDecorators = {
47208
- canvasElement: [{ type: ViewChild, args: ['canvasElement', { static: true },] }],
47209
- width: [{ type: Input }],
47210
- data: [{ type: Input }]
47211
- };
47212
-
47213
- class RadioButtonListComponent {
47214
- constructor(_crudService, _deviceDetectorService) {
47215
- this._crudService = _crudService;
47216
- this._deviceDetectorService = _deviceDetectorService;
47217
- this.onInit = new EventEmitter();
47218
- this.valueChange = new EventEmitter();
47219
- this.onChanged = new EventEmitter();
47220
- this.onDataSourceLoaded = new EventEmitter();
47221
- this.adjustValue = new EventEmitter();
47222
- this.onReady = new EventEmitter();
47223
- this.funcReturnValue = value => value;
47224
- this.dataSourceInternal = [];
47225
- this.hideTransitionOptions = '195ms ease-in';
47226
- this.showTransitionOptions = '225ms ease-out';
47227
- this.classCheckBox = 'p-col-horizontal';
47228
- this._hasLoadedDatasource = false;
47298
+ registerOnTouched(fn) {
47299
+ this.onTouched = fn;
47229
47300
  }
47230
- set dataSource(value) {
47231
- this.bindingDataSource(value);
47301
+ setDisabledState(isDisabled) {
47302
+ if (!isDisabled)
47303
+ this.disabled = null;
47304
+ else
47305
+ this.disabled = true;
47232
47306
  }
47233
- set value(value) {
47234
- if (this._value != value) {
47235
- this._value = value;
47236
- this.setSelectedValue();
47237
- }
47307
+ getMaskByType(maskType) {
47308
+ if (maskType === 'decimal')
47309
+ return `separator.${this.decimalPlaces}`;
47310
+ return 'separator.0';
47238
47311
  }
47239
- ngOnInit() {
47240
- this.control._component = this;
47241
- this.setDefaultSetting();
47242
- if (this.control.baseService) {
47243
- this._getData();
47244
- }
47245
- if (this.control.layout == 'vertical') {
47246
- this.classCheckBox = 'p-row';
47247
- }
47248
- if (!this._deviceDetectorService.isDesktop()) {
47249
- this.hideTransitionOptions = this.showTransitionOptions = '';
47250
- }
47251
- this.onInit.emit(this);
47312
+ getThousandSeperator() {
47313
+ if (this.maskType === 'intWithoutMask')
47314
+ return '';
47315
+ return '.';
47252
47316
  }
47253
- setDefaultSetting() {
47254
- if (this.control.returnType == 'value') {
47255
- this.funcReturnValue = (value) => {
47256
- if (value == null)
47257
- return null;
47258
- return value[this.control.valueField];
47259
- };
47317
+ checkValueInRange() {
47318
+ // if (!this.model || this.maskType != 'int') {
47319
+ // return;
47320
+ // }
47321
+ if (this.min) {
47322
+ const min = Number(this.min);
47323
+ if (Number(this.model[0]) < min)
47324
+ this.model[0] = min;
47325
+ if (Number(this.model[1]) < min)
47326
+ this.model[1] = min;
47260
47327
  }
47261
- else {
47262
- this.funcReturnValue = value => value;
47328
+ if (this.max) {
47329
+ const max = Number(this.max);
47330
+ if (Number(this.model[0]) > max)
47331
+ this.model[0] = max;
47332
+ if (Number(this.model[1]) > max)
47333
+ this.model[1] = max;
47263
47334
  }
47264
47335
  }
47265
- bindingDataSource(sources) {
47266
- const oldValue = this._value;
47267
- let hasValueInSource = false;
47268
- if (sources != null && sources.length > 0) {
47269
- this._hasLoadedDatasource = true;
47270
- const arr = [];
47271
- for (let item of sources) {
47272
- item = this.reStructureItemObject(item);
47273
- if (this._value != null
47274
- && this._value !== ''
47275
- && (item.value[this.control.valueField] == this._value || item.value[this.control.valueField] == this._value[this.control.valueField])) {
47276
- this._value = item.value;
47277
- hasValueInSource = true;
47336
+ onChanged(evt) {
47337
+ this.enter.next(evt);
47338
+ this.compareAndEmit();
47339
+ }
47340
+ onFocus(evt, index) {
47341
+ this.focus.emit({
47342
+ event: evt,
47343
+ index
47344
+ });
47345
+ }
47346
+ compareAndEmit() {
47347
+ this.checkValueInRange();
47348
+ let value = [null, null];
47349
+ if (this.model[0]) {
47350
+ value[0] = Number(this.model[0]);
47351
+ if (this.model[1]) {
47352
+ value[1] = Number(this.model[1]);
47353
+ if (value[0] > value[1]) {
47354
+ value = value.reverse();
47278
47355
  }
47279
- arr.push(item);
47280
- }
47281
- this.dataSourceInternal = arr;
47282
- if (!hasValueInSource) {
47283
- this._value = null;
47284
47356
  }
47285
47357
  }
47286
47358
  else {
47287
- this.dataSourceInternal = [];
47288
- }
47289
- if (this._hasLoadedDatasource) {
47290
- // Lưu ý if ở dưới không được đổi thành oldValue != this._value
47291
- // Vì giá trị của this._value sẽ được correcting ở trên (id => object) nên so sánh sẽ khác nhau
47292
- if ((oldValue != null && this._value == null)
47293
- || (oldValue == null && this._value != null)) {
47294
- this.fireChangedEvent();
47295
- }
47296
- else if (this._value != oldValue) {
47297
- this.adjustValue2WayBinding();
47298
- }
47299
- this.onReady.emit(this.control.field);
47359
+ if (this.model[1])
47360
+ value[1] = Number(this.model[1]);
47300
47361
  }
47301
- this.checkReady();
47362
+ this.onChange(value);
47363
+ this.model[0] = value[0];
47364
+ this.model[1] = value[1];
47365
+ this.change.emit(value);
47302
47366
  }
47303
- setSelectedValue() {
47304
- if (this._hasLoadedDatasource) {
47305
- const oldValue = this._value;
47306
- let hasValueInSource = false;
47307
- if (this.dataSourceInternal != null && this.dataSourceInternal.length > 0) {
47308
- for (const item of this.dataSourceInternal) {
47309
- if (this._value != null
47310
- && this._value !== ''
47311
- && (item.value[this.control.valueField] == this._value || item.value[this.control.valueField] == this._value[this.control.valueField])) {
47312
- this._value = item.value;
47313
- hasValueInSource = true;
47314
- break;
47367
+ }
47368
+ NumberPickerRangeComponent.decorators = [
47369
+ { type: Component, args: [{
47370
+ selector: 'tn-number-picker-range',
47371
+ template: "<div class=\"tn-number-picker-range\">\n <input type=\"text\" placeholder=\"{{placeholerTu}}\" [attr.disabled]=\"disabled ? true : null\"\n [mask]=\"getMaskByType(maskType)\" [thousandSeparator]=\"getThousandSeperator()\" pInputText [(ngModel)]=\"model[0]\"\n (change)=\"onChanged($event)\" (focus)=\"onFocus($event, 0)\" />\n <span>-</span>\n <input type=\"text\" placeholder=\"{{placeholerDen}}\" [attr.disabled]=\"disabled ? true : null\"\n [mask]=\"getMaskByType(maskType)\" [thousandSeparator]=\"getThousandSeperator()\" pInputText [(ngModel)]=\"model[1]\"\n (change)=\"onChanged($event)\" (focus)=\"onFocus($event, 1)\" />\n</div>",
47372
+ providers: [
47373
+ {
47374
+ provide: NG_VALUE_ACCESSOR,
47375
+ useExisting: forwardRef(() => NumberPickerRangeComponent),
47376
+ multi: true
47315
47377
  }
47316
- }
47317
- if (!hasValueInSource) {
47318
- this._value = null;
47319
- }
47320
- }
47321
- if ((oldValue != null && this._value == null)
47322
- || (oldValue == null && this._value != null)) {
47323
- this.fireChangedEvent();
47324
- }
47325
- else if (this._value != oldValue) {
47326
- this.adjustValue2WayBinding();
47327
- }
47328
- }
47329
- this.checkReady();
47330
- }
47331
- reStructureItemObject(item) {
47332
- const temp = { value: item };
47333
- if (this.control.funcGetLabel) {
47334
- temp.label = this.control.funcGetLabel(item);
47335
- }
47336
- else {
47337
- temp.label = item[this.control.displayField];
47338
- }
47339
- temp.value._dropdownvalue = this.control.valueField;
47340
- return temp;
47378
+ ],
47379
+ styles: [".tn-number-picker-range{display:flex}.tn-number-picker-range>span{flex:0 0 16px;display:inline-flex;align-items:center;justify-content:center}::ng-deep .tn-number-picker-range .p-inputtext{flex:0 0 calc(50% - 8px);width:calc(50% - 8px)}"]
47380
+ },] }
47381
+ ];
47382
+ NumberPickerRangeComponent.ctorParameters = () => [
47383
+ { type: DecimalPipe }
47384
+ ];
47385
+ NumberPickerRangeComponent.propDecorators = {
47386
+ readonly: [{ type: Input }],
47387
+ maskType: [{ type: Input }],
47388
+ placeholder: [{ type: Input }],
47389
+ disabled: [{ type: Input }],
47390
+ suffix: [{ type: Input }],
47391
+ prefix: [{ type: Input }],
47392
+ min: [{ type: Input }],
47393
+ max: [{ type: Input }],
47394
+ decimalPlaces: [{ type: Input }],
47395
+ onInit: [{ type: Output }],
47396
+ focus: [{ type: Output }],
47397
+ enterSmart: [{ type: Output }],
47398
+ enter: [{ type: Output }],
47399
+ blur: [{ type: Output }],
47400
+ change: [{ type: Output }]
47401
+ };
47402
+
47403
+ class PagingNextBackOnlyComponent {
47404
+ constructor() {
47405
+ this.onNext = new EventEmitter();
47406
+ this.onPrev = new EventEmitter();
47407
+ this.onLatest = new EventEmitter();
47408
+ this.onRefresh = new EventEmitter();
47409
+ this.onOldest = new EventEmitter();
47410
+ this.onChangeLimitPage = new EventEmitter();
47411
+ this.onChanged = new EventEmitter();
47341
47412
  }
47342
- _getData(filterParents) {
47343
- return __awaiter(this, void 0, void 0, function* () {
47344
- if (this.control.baseService) {
47345
- if (!filterParents)
47346
- filterParents = [];
47347
- yield this._getDataSource(filterParents);
47348
- }
47349
- });
47413
+ ngOnInit() {
47414
+ this.pageSizeOld = this.setting.pageSetting.pageSize;
47350
47415
  }
47351
- _getDataSource(filterFromParents) {
47352
- return __awaiter(this, void 0, void 0, function* () {
47353
- const filters = yield this.filterProcess(filterFromParents);
47354
- const dropdownOptions = this._crudService.createDropdownOptions(this.control);
47355
- let dataSource;
47356
- if (this.control.baseService instanceof MasterDataService) {
47357
- dataSource = yield this.control.baseService.getDataDropdownByFilter(this.control.groupCode, null, filters, dropdownOptions);
47358
- }
47359
- else {
47360
- if (this.control.isTree) {
47361
- dataSource = yield this.control.baseService.getTreeDataDropdownByFilter(filters, this.control.fieldTree, this.control.valueParentRoot, dropdownOptions);
47362
- }
47363
- else {
47364
- dataSource = yield this.control.baseService.getDataDropdownByFilter(filters, dropdownOptions);
47365
- }
47366
- }
47367
- this.bindingDataSource(dataSource);
47368
- if (this.control.fireCallBackInside) {
47369
- if (this.control.callbackDataFinish) {
47370
- this.control.callbackDataFinish({
47371
- data: dataSource,
47372
- elm: this
47373
- });
47374
- }
47375
- }
47376
- else {
47377
- this.onDataSourceLoaded.emit({
47378
- dataSource,
47379
- elm: this
47380
- });
47381
- }
47382
- });
47416
+ getFirstIndex() {
47417
+ return (this.setting.pageSetting.page - 1) * this.setting.pageSetting.pageSize + 1;
47383
47418
  }
47384
- filterProcess(filterFromParents) {
47385
- return __awaiter(this, void 0, void 0, function* () {
47386
- const filters = filterFromParents;
47387
- yield appendDefaultFilter(filters, this.control.defaultFilters);
47388
- if (this.control.modifyFilter) {
47389
- yield this.control.modifyFilter(filters, this);
47390
- }
47391
- return filters;
47392
- });
47419
+ getLastIndex() {
47420
+ let temp = this.setting.pageSetting.page * this.setting.pageSetting.pageSize;
47421
+ if (temp > this.model.total)
47422
+ temp = this.model.total;
47423
+ return temp;
47393
47424
  }
47394
- checkReady() {
47395
- if (this.control.onAdjustedValue
47396
- && this._hasLoadedDatasource
47397
- && this._value != null) {
47398
- this.fireAdjustValueEvent();
47425
+ goLatest(evt) {
47426
+ if (this.isFirst() || this.model.loading)
47427
+ return;
47428
+ if (this.setting.pageSetting.pageSize == 0) {
47429
+ this.setting.pageSetting.pageSize = 1;
47430
+ }
47431
+ if (this.setting.pageSetting.pageSize > 1000) {
47432
+ this.setting.pageSetting.pageSize = 1000;
47399
47433
  }
47434
+ this.setting.pageSetting.page = 1;
47435
+ this.op.hide();
47436
+ this.onLatest.next(evt);
47437
+ this.onChanged.emit();
47400
47438
  }
47401
- getValueReturn() {
47402
- return this.funcReturnValue(this._value);
47439
+ goPrev(evt) {
47440
+ if (this.isFirst() || this.model.loading)
47441
+ return;
47442
+ if (this.setting.pageSetting.page > 1) {
47443
+ this.setting.pageSetting.page--;
47444
+ }
47445
+ this.op.hide();
47446
+ this.onPrev.next(evt);
47447
+ this.onChanged.emit();
47403
47448
  }
47404
- checkInitedControl() {
47405
- // Nếu chưa chạy qua init thì k fire event gì cả
47406
- return !!this.control._component;
47449
+ isFirst() {
47450
+ return this.setting.pageSetting.page <= 1;
47407
47451
  }
47408
- fireChangedEvent() {
47409
- // Nếu chưa chạy qua init thì k fire event gì cả
47410
- if (!this.checkInitedControl())
47452
+ goNext(evt) {
47453
+ if (this.isLast() || this.model.loading)
47411
47454
  return;
47412
- const valueReturn = this.getValueReturn();
47413
- this.valueChange.emit(valueReturn);
47414
- this.onChanged.emit(valueReturn);
47455
+ this.setting.pageSetting.page++;
47456
+ this.op.hide();
47457
+ this.onNext.next(evt);
47458
+ this.onChanged.emit();
47415
47459
  }
47416
- fireAdjustValueEvent() {
47417
- // Nếu chưa chạy qua init thì k fire event gì cả
47418
- if (!this.checkInitedControl())
47419
- return;
47420
- const valueReturn = this.getValueReturn();
47421
- this.adjustValue.next(valueReturn);
47460
+ isLast() {
47461
+ return this.model.total <= 0 || this.getLastIndex() == this.model.total;
47422
47462
  }
47423
- adjustValue2WayBinding() {
47424
- if (!this.checkInitedControl())
47463
+ goOldest(evt) {
47464
+ if (this.isLast() || this.model.loading)
47425
47465
  return;
47426
- const valueReturn = this.getValueReturn();
47427
- this.valueChange.emit(valueReturn);
47466
+ this.setting.pageSetting.page = Math.ceil(this.model.total / this.setting.pageSetting.pageSize);
47467
+ this.onOldest.next(evt);
47468
+ this.onChanged.emit();
47428
47469
  }
47429
- change(event) {
47430
- this.fireChangedEvent();
47470
+ saveChangeHandle() {
47471
+ if (!this.setting.pageSetting.pageSize || this.setting.pageSetting.pageSize.toString() == '0') {
47472
+ this.setting.pageSetting.pageSize = this.pageSizeOld;
47473
+ }
47474
+ this.pageSizeOld = this.setting.pageSetting.pageSize;
47475
+ this.goLatest(null);
47476
+ this.onChangeLimitPage.next(null);
47477
+ this.onChanged.emit();
47478
+ }
47479
+ handleOverlayShow(evt, targetOverlay) {
47480
+ }
47481
+ refresh(event) {
47431
47482
  }
47432
47483
  }
47433
- RadioButtonListComponent.decorators = [
47484
+ PagingNextBackOnlyComponent.decorators = [
47434
47485
  { type: Component, args: [{
47435
- selector: 'radio-button-list',
47436
- template: "<div class=\"p-grid tn-check-box-list\" [class.flex-end]=\"control.align == 'right'\"\n [class.flex-center]=\"control.align == 'center'\">\n <div [class]=\"classCheckBox\" *ngFor=\"let chk of dataSourceInternal\">\n <p-radioButton [disabled]=\"disabled ? true : null\" [label]=\"chk.label\" [value]=\"chk.value\"\n [(ngModel)]=\"_value\" (onClick)=\"change($event)\">\n </p-radioButton>\n </div>\n</div>\n",
47437
- styles: [".tn-check-box-list.p-grid{margin-bottom:-.5em}.btn-clear{height:30px;cursor:pointer;border:none;background:#337ab7;color:#fff;border-radius:3px;padding:0 10px;margin:1px .5em 0}.p-col-horizontal{padding:.5em}::ng-deep .tn-check-box-list{position:relative}::ng-deep .tn-check-box-list.flex-end{justify-content:flex-end}::ng-deep .tn-check-box-list.flex-center{justify-content:center}::ng-deep .tn-check-box-list label{cursor:pointer}"]
47486
+ selector: 'paging-next-back-only',
47487
+ template: "<div class=\"paging-container\" [ngClass]=\"ngClass\">\n <div class=\"paging-info\">\n <ng-container>\n <div *ngIf=\"getFirstIndex()<=model.total && !setting.hiddenTextPage\" #targetOverlay\n class=\"paging-item paging-info-detail\" (click)=\"op.toggle($event)\">\n {{getFirstIndex()}} -\n {{getLastIndex()}}\n trong {{model.total}}\n </div>\n <div *ngIf=\"(getFirstIndex()>model.total || model.total == 0) && !setting.hiddenTextPage\"\n class=\"paging-item paging-info-detail\">\n Kh\u00F4ng t\u00ECm th\u1EA5y d\u1EEF li\u1EC7u\n </div>\n <div class=\"paging-item text\" [class.disabled]=\"model.loading\" (click)=\"goPrev($event)\"\n style=\"margin-right: 5px;\" pTooltip=\"{{'Trang tr\u01B0\u1EDBc' | translate}}\" tooltipPosition=\"top\"\n [class.disabled]=\"isFirst()\">\n <a href=\"javascript:\" tabindex=\"{{isFirst()?'-1':''}}\"><i class=\"pi pi-chevron-left\"></i></a>\n </div>\n <div class=\"block-page-size\">\n <tn-mask [maskType]=\"'int'\" [min]=\"1\" [max]=\"1000\" [disabled]=\"model.loading ? true : null\"\n [(ngModel)]=\"setting.pageSetting.pageSize\" (onChanged)=\"saveChangeHandle()\"\n (keyup.enter)=\"saveChangeHandle()\">\n </tn-mask>\n </div>\n <div class=\"paging-item text\" [class.disabled]=\"model.loading\" (click)=\"goNext($event)\"\n style=\"margin-left: 5px;\" pTooltip=\"{{'Trang sau' | translate}}\" tooltipPosition=\"left\"\n [class.disabled]=\"isLast()\">\n <a href=\"javascript:\" tabindex=\"{{isLast()?'-1':''}}\"><i class=\"pi pi-chevron-right\"></i></a>\n </div>\n </ng-container>\n </div>\n</div>\n\n<p-overlayPanel #op [styleClass]=\"'paging-advance-overlay'\" [appendTo]=\"'body'\"\n (onShow)=\"handleOverlayShow($event, targetOverlay)\">\n <ul class=\"paging-advance\">\n <li [class.disabled]=\"isFirst()\" (click)=\"goLatest($event)\">Trang \u0111\u1EA7u ti\u00EAn</li>\n <li [class.disabled]=\"isLast()\" (click)=\"goOldest($event)\">Trang cu\u1ED1i c\u00F9ng</li>\n </ul>\n</p-overlayPanel>",
47488
+ styles: [".paging-item a{color:#495057}.paging-item:hover{cursor:pointer}.paging-item:hover a{color:#333}.paging-item.disabled a{color:#bdbdbd}.paging-info-detail{padding:2px .5rem 0;text-align:center;line-height:30px;border-radius:7px;min-width:100px;font-size:.9em}.paging-item.text{line-height:32px;border-radius:50%;width:32px;height:32px;text-align:center;position:relative;display:inline-block;transform:perspective(1px);overflow:hidden}.paging-item.text:before{content:\"\";position:absolute;top:0;left:0;bottom:0;right:0;background:#e6e6e6;z-index:-1;transform:scale(0);transition:all .3s cubic-bezier(.4,.34,.01,.97);border-radius:50%}.paging-item.text:hover:before{transform:scale(1)}.paging-item.text>a{display:flex;justify-content:center;align-items:center;width:100%;height:100%}.paging-info-detail{border-radius:5px;position:relative;display:inline-block;transform:perspective(1px);overflow:hidden}.paging-info-detail:before{content:\"\";position:absolute;top:0;left:0;bottom:0;right:0;background:#e6e6e6;z-index:-1;transform:scale(0);transition:all .3s cubic-bezier(.4,.34,.01,.97);border-radius:5px}.paging-info-detail:hover:before{transform:scale(1)}.paging-item.disabled:hover:before{content:none}.paging-item.disabled:hover{background-color:#fff;cursor:default}.paging-item.disabled:hover a{cursor:default}.paging-info{display:flex;justify-content:flex-end;align-items:center}.item-setting{font-size:18px}.item-setting a{color:#555}.item-setting a:hover{color:#333}.paging-advance{list-style:none;padding-left:0;margin:3px 0}.paging-advance li{width:150px;padding-left:15px;line-height:30px}.paging-advance li.disabled{color:#bdbdbd;outline:none}.paging-advance li.disabled:hover{cursor:default;background:none}.paging-advance li:hover{cursor:pointer;background:#e6e6e6}::ng-deep .paging-advance-overlay{margin-left:30px}::ng-deep .paging-advance-overlay .p-overlaypanel-content{padding:0}::ng-deep paging-next-back-only .block-page-size{display:inline-block;width:60px}::ng-deep paging-next-back-only .block-page-size .p-inputtext{width:100%;text-align:center;padding-left:5px;padding-right:5px}::ng-deep paging-next-back-only .tn-mask-disabled{padding:5px;border:1px solid #ddd;border-radius:4px;display:flex;justify-content:center;line-height:20px}"]
47438
47489
  },] }
47439
47490
  ];
47440
- RadioButtonListComponent.ctorParameters = () => [
47441
- { type: CrudService },
47442
- { type: DeviceDetectorService }
47443
- ];
47444
- RadioButtonListComponent.propDecorators = {
47445
- control: [{ type: Input }],
47446
- dataSource: [{ type: Input }],
47447
- value: [{ type: Input }],
47448
- disabled: [{ type: Input }],
47449
- onInit: [{ type: Output }],
47450
- valueChange: [{ type: Output }],
47451
- onChanged: [{ type: Output }],
47452
- onDataSourceLoaded: [{ type: Output }],
47453
- adjustValue: [{ type: Output }],
47454
- onReady: [{ type: Output }]
47491
+ PagingNextBackOnlyComponent.ctorParameters = () => [];
47492
+ PagingNextBackOnlyComponent.propDecorators = {
47493
+ op: [{ type: ViewChild, args: ['op', { static: true },] }],
47494
+ model: [{ type: Input }],
47495
+ setting: [{ type: Input }],
47496
+ ngClass: [{ type: Input }],
47497
+ onNext: [{ type: Output }],
47498
+ onPrev: [{ type: Output }],
47499
+ onLatest: [{ type: Output }],
47500
+ onRefresh: [{ type: Output }],
47501
+ onOldest: [{ type: Output }],
47502
+ onChangeLimitPage: [{ type: Output }],
47503
+ onChanged: [{ type: Output }]
47455
47504
  };
47456
47505
 
47457
- class ReferenceTextBoxComponent extends ComponentBase {
47458
- constructor(injector) {
47459
- super(injector);
47460
- this.onInit = new EventEmitter();
47461
- this.data = '';
47462
- this.ready = false;
47463
- }
47464
- set value(value) {
47465
- this._value = value;
47466
- this.checkAndGetData();
47467
- }
47468
- set dataSource(value) {
47469
- if (!value)
47470
- return;
47471
- this._dataSource = value;
47472
- }
47473
- get dataSource() {
47474
- return this._dataSource;
47506
+ class QrCodeGeneratorComponent {
47507
+ constructor() {
47508
+ this.width = 120;
47509
+ this._data = '';
47510
+ this.defaultText = 'empty';
47475
47511
  }
47476
- get value() {
47477
- return this._value;
47512
+ set data(value) {
47513
+ this._data = value;
47514
+ this.convert();
47478
47515
  }
47479
47516
  ngOnInit() {
47480
- this.control._component = this;
47481
- this.ready = true;
47482
- this.checkAndGetData();
47483
- this.onInit.emit(this);
47517
+ this.convert();
47484
47518
  }
47485
- checkAndGetData() {
47486
- return __awaiter(this, void 0, void 0, function* () {
47487
- this.data = '';
47488
- if (!this.ready
47489
- || this._value == null
47490
- || !this.control
47491
- || (!this.control.baseService && !this.dataSource))
47492
- return;
47493
- let item = null;
47494
- if (this.control.baseService && this.control.baseService instanceof BaseService) {
47495
- item = (yield this.control.baseService.getDetailByFilter([
47496
- this.newFilter(this.control.valueField, Operator.equal, this.value)
47497
- ])).data;
47498
- }
47499
- else if (this.dataSource) {
47500
- item = this.dataSource.find(x => x[this.control.valueField] == this.value);
47501
- }
47502
- else {
47503
- // TODO: xử lý lấy dữ liệu detail của master data
47504
- item = null;
47505
- }
47506
- if (item == null)
47507
- return;
47508
- if (this.control.funcGetLabel) {
47509
- this.data = this.control.funcGetLabel(item);
47510
- }
47511
- else {
47512
- this.data = item[this.control.displayField];
47513
- }
47519
+ convert() {
47520
+ if (!this._data) {
47521
+ this._data = this.defaultText;
47522
+ }
47523
+ toCanvas(this.canvasElement.nativeElement, this._data, {
47524
+ width: this.width
47525
+ }, (error) => {
47526
+ if (error)
47527
+ console.error(error);
47514
47528
  });
47515
47529
  }
47530
+ download() {
47531
+ const link = document.createElement('a');
47532
+ link.download = 'qrcode.png';
47533
+ link.href = this.canvasElement.nativeElement.toDataURL();
47534
+ link.click();
47535
+ link.remove();
47536
+ }
47516
47537
  }
47517
- ReferenceTextBoxComponent.decorators = [
47538
+ QrCodeGeneratorComponent.decorators = [
47518
47539
  { type: Component, args: [{
47519
- selector: 'reference-textbox',
47520
- template: "<div class=\"p-inputgroup\" *ngIf=\"control.suffix\">\n <input [placeholder]=\"control.placeholder\" disabled=\"true\" pInputText type='text' [ngModel]=\"data\" />\n <span class=\"p-inputgroup-addon\">({{control.suffix}})</span>\n</div>\n<input *ngIf=\"!control.suffix\" [placeholder]=\"control.placeholder\" disabled=\"true\" pInputText type='text'\n [ngModel]=\"data\" />",
47521
- styles: [""]
47540
+ selector: 'app-qr-code-generator',
47541
+ template: "<div class=\"qr-code-generator\" [style.width.px]=\"width\" [style.height.px]=\"width\">\n <canvas #canvasElement width=\"100%\" height=\"100%\"></canvas>\n <div class=\"mask\">\n <span class=\"icon-download fa fa-download\" pTooltip=\"B\u1EA5m \u0111\u1EC3 t\u1EA3i v\u1EC1\" tooltipPosition=\"top\"\n (click)=\"download()\"></span>\n </div>\n</div>",
47542
+ styles: [".qr-code-generator{position:relative}.qr-code-generator .mask{display:none;position:absolute;top:0;left:0;width:100%;height:100%;background:hsla(0,0%,50.2%,.8392156862745098);border-radius:3px}.qr-code-generator .mask .icon-download{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);cursor:pointer;color:#00ff2b;font-size:2rem}.qr-code-generator:hover .mask{display:initial}"]
47522
47543
  },] }
47523
47544
  ];
47524
- ReferenceTextBoxComponent.ctorParameters = () => [
47525
- { type: Injector }
47526
- ];
47527
- ReferenceTextBoxComponent.propDecorators = {
47528
- control: [{ type: Input }],
47529
- value: [{ type: Input }],
47530
- dataSource: [{ type: Input }],
47531
- onInit: [{ type: Output }]
47545
+ QrCodeGeneratorComponent.ctorParameters = () => [];
47546
+ QrCodeGeneratorComponent.propDecorators = {
47547
+ canvasElement: [{ type: ViewChild, args: ['canvasElement', { static: true },] }],
47548
+ width: [{ type: Input }],
47549
+ data: [{ type: Input }]
47532
47550
  };
47533
47551
 
47534
- class JobItem {
47535
- constructor(code, data, fileName = 'BaoCao', status = REPORT_QUEUE_CONSTANT.statuses.Waiting) {
47536
- // Loại export.
47537
- this._type = JobTypes.SingnalR;
47538
- this._code = code;
47539
- const datepipe = new DatePipe('en-US');
47540
- let formattedDate = datepipe.transform(new Date(), 'ddMMyyyy_hhmmss');
47541
- this._fileName = `${fileName}_${formattedDate}${TemplateConstant.EXCEL_EXTENSION}`;
47542
- this._data = data || {};
47543
- this._status = status;
47544
- }
47545
- }
47546
- class REPORT_QUEUE_CONSTANT {
47547
- }
47548
- REPORT_QUEUE_CONSTANT.statuses = {
47549
- Waiting: 1,
47550
- Exporting: 2,
47551
- Success: 3,
47552
- Error: 4,
47553
- Downloaded: 5
47554
- };
47555
- REPORT_QUEUE_CONSTANT.dicStatus = new SimpleDictionary([
47556
- new SimpleDicItem(REPORT_QUEUE_CONSTANT.statuses.Waiting, 'Chờ để xử lý'),
47557
- new SimpleDicItem(REPORT_QUEUE_CONSTANT.statuses.Exporting, 'Đang xử lý'),
47558
- new SimpleDicItem(REPORT_QUEUE_CONSTANT.statuses.Success, 'Tải xuống'),
47559
- new SimpleDicItem(REPORT_QUEUE_CONSTANT.statuses.Error, 'Xuất file chưa thành công'),
47560
- new SimpleDicItem(REPORT_QUEUE_CONSTANT.statuses.Downloaded, 'Đã tải'),
47561
- ]);
47562
- var JobTypes;
47563
- (function (JobTypes) {
47564
- JobTypes[JobTypes["Normal"] = 1] = "Normal";
47565
- JobTypes[JobTypes["SingnalR"] = 2] = "SingnalR";
47566
- JobTypes[JobTypes["Many"] = 3] = "Many"; // Export nhiều file cùng một lúc và nén vào file zip, mỗi file có thể là các loại biểu mẫu khác nhau.
47567
- })(JobTypes || (JobTypes = {}));
47568
- class ExportJob {
47569
- constructor(templateCode, // code template cấu hình bên quản trị
47570
- dataPromise, // promise dùng để lấy dữ liệu, trả về dạng ResponseResult
47571
- fileName, // tên của file được lưu
47572
- rootName = '', // tên thuộc tính của lst dữ liệu ngoài cùng
47573
- cb = null, // dùng để xử lý dữ liệu sau khi lấy xong
47574
- type = JobTypes.Normal // Loại export.
47575
- ) {
47576
- this.templateCode = templateCode;
47577
- this.dataPromise = dataPromise;
47578
- this.fileName = fileName;
47579
- this.rootName = rootName;
47580
- this.cb = cb;
47581
- this.type = type;
47552
+ class RadioButtonListComponent {
47553
+ constructor(_crudService, _deviceDetectorService) {
47554
+ this._crudService = _crudService;
47555
+ this._deviceDetectorService = _deviceDetectorService;
47556
+ this.onInit = new EventEmitter();
47557
+ this.valueChange = new EventEmitter();
47558
+ this.onChanged = new EventEmitter();
47559
+ this.onDataSourceLoaded = new EventEmitter();
47560
+ this.adjustValue = new EventEmitter();
47561
+ this.onReady = new EventEmitter();
47562
+ this.funcReturnValue = value => value;
47563
+ this.dataSourceInternal = [];
47564
+ this.hideTransitionOptions = '195ms ease-in';
47565
+ this.showTransitionOptions = '225ms ease-out';
47566
+ this.classCheckBox = 'p-col-horizontal';
47567
+ this._hasLoadedDatasource = false;
47582
47568
  }
47583
- }
47584
-
47585
- class ReportQueueComponent {
47586
- constructor(_notifierService, _commonService, _fileService, _tempateService, _signalRService, _highPerformanceService, _crudService) {
47587
- this._notifierService = _notifierService;
47588
- this._commonService = _commonService;
47589
- this._fileService = _fileService;
47590
- this._tempateService = _tempateService;
47591
- this._signalRService = _signalRService;
47592
- this._highPerformanceService = _highPerformanceService;
47593
- this._crudService = _crudService;
47594
- this.name = 'reportQueue';
47595
- this.header = 'Xuất báo cáo';
47596
- this.autoDownload = false;
47597
- this.maxNameLength = 40;
47598
- this.expand = true;
47599
- this.queueName = 'REPORT_QUEUE';
47600
- this.hub = 'CommonHub';
47601
- this.dicStatus = REPORT_QUEUE_CONSTANT.dicStatus;
47602
- this.statuses = REPORT_QUEUE_CONSTANT.statuses;
47603
- this._queue = [];
47604
- this.maxHeight = 200;
47605
- this.itemHeight = 50;
47606
- this.popupHeight = this.itemHeight;
47569
+ set dataSource(value) {
47570
+ this.bindingDataSource(value);
47571
+ }
47572
+ set value(value) {
47573
+ if (this._value != value) {
47574
+ this._value = value;
47575
+ this.setSelectedValue();
47576
+ }
47607
47577
  }
47608
47578
  ngOnInit() {
47609
- if (this.parentDataModel && this.name) {
47610
- this.parentDataModel[this.name] = this;
47579
+ this.control._component = this;
47580
+ this.setDefaultSetting();
47581
+ if (this.control.baseService) {
47582
+ this._getData();
47611
47583
  }
47584
+ if (this.control.layout == 'vertical') {
47585
+ this.classCheckBox = 'p-row';
47586
+ }
47587
+ if (!this._deviceDetectorService.isDesktop()) {
47588
+ this.hideTransitionOptions = this.showTransitionOptions = '';
47589
+ }
47590
+ this.onInit.emit(this);
47612
47591
  }
47613
- toggleExpand() {
47614
- this.expand = !this.expand;
47592
+ setDefaultSetting() {
47593
+ if (this.control.returnType == 'value') {
47594
+ this.funcReturnValue = (value) => {
47595
+ if (value == null)
47596
+ return null;
47597
+ return value[this.control.valueField];
47598
+ };
47599
+ }
47600
+ else {
47601
+ this.funcReturnValue = value => value;
47602
+ }
47615
47603
  }
47616
- /**
47617
- * Thêm job vào để thực hiện
47618
- */
47619
- addJob(exportJob) {
47620
- return __awaiter(this, void 0, void 0, function* () {
47621
- var foundIndex = this._queue.findIndex(job => job._code == exportJob.templateCode && job._status == this.statuses.Exporting);
47622
- if (foundIndex !== -1) {
47623
- this._notifierService.showWarning("File cùng loại đang được xử lý, thử lại sau khi xử lý xong!");
47624
- return;
47625
- }
47626
- var job = new JobItem(exportJob.templateCode, {}, exportJob.fileName || exportJob.templateCode, this.statuses.Exporting);
47627
- this._queue.push(job);
47628
- this.updatePopupHeight();
47629
- setTimeout(() => {
47630
- this.scrollbar.scrollToBottom();
47631
- }, 100);
47632
- var rsData = yield exportJob.dataPromise;
47633
- if (rsData.data == null) {
47634
- job._status = this.statuses.Error;
47635
- return this._crudService.processErrorResponse(rsData);
47636
- }
47637
- if (exportJob.cb) {
47638
- job._data = exportJob.cb(rsData.data);
47604
+ bindingDataSource(sources) {
47605
+ const oldValue = this._value;
47606
+ let hasValueInSource = false;
47607
+ if (sources != null && sources.length > 0) {
47608
+ this._hasLoadedDatasource = true;
47609
+ const arr = [];
47610
+ for (let item of sources) {
47611
+ item = this.reStructureItemObject(item);
47612
+ if (this._value != null
47613
+ && this._value !== ''
47614
+ && (item.value[this.control.valueField] == this._value || item.value[this.control.valueField] == this._value[this.control.valueField])) {
47615
+ this._value = item.value;
47616
+ hasValueInSource = true;
47617
+ }
47618
+ arr.push(item);
47639
47619
  }
47640
- else if (exportJob.rootName) {
47641
- job._data[exportJob.rootName] = rsData.data;
47620
+ this.dataSourceInternal = arr;
47621
+ if (!hasValueInSource) {
47622
+ this._value = null;
47642
47623
  }
47643
- else {
47644
- job._data = rsData.data;
47624
+ }
47625
+ else {
47626
+ this.dataSourceInternal = [];
47627
+ }
47628
+ if (this._hasLoadedDatasource) {
47629
+ // Lưu ý if ở dưới không được đổi thành oldValue != this._value
47630
+ // Vì giá trị của this._value sẽ được correcting ở trên (id => object) nên so sánh sẽ khác nhau
47631
+ if ((oldValue != null && this._value == null)
47632
+ || (oldValue == null && this._value != null)) {
47633
+ this.fireChangedEvent();
47645
47634
  }
47646
- switch (exportJob.type) {
47647
- case JobTypes.Normal:
47648
- this.Export(job);
47649
- break;
47650
- case JobTypes.SingnalR:
47651
- this.ExportWithSignalR(job);
47652
- break;
47653
- case JobTypes.Many:
47654
- break;
47635
+ else if (this._value != oldValue) {
47636
+ this.adjustValue2WayBinding();
47655
47637
  }
47656
- });
47638
+ this.onReady.emit(this.control.field);
47639
+ }
47640
+ this.checkReady();
47657
47641
  }
47658
- /**
47659
- * Thêm job vào để thực hiện
47660
- * - templateCode: code template cấu hình bên quản trị
47661
- * - data: dữ liệu export
47662
- * - fileName: tên của file được lưu
47663
- * - useSignalR: thay gọi request và chờ đến khi thực hiện xong
47664
- * trả về binaryFile thì tạo tiến trình riêng để export, và dùng signalR thông
47665
- * báo kết quả export, trả về fileId để tải.
47666
- */
47667
- addJobWithData(templateCode, data, fileName, useSignalR = false) {
47668
- return __awaiter(this, void 0, void 0, function* () {
47669
- var foundIndex = this._queue.findIndex(job => job._code == templateCode && job._status == this.statuses.Exporting);
47670
- if (foundIndex !== -1) {
47671
- this._notifierService.showWarning("File cùng loại đang được xử lý, thử lại sau khi xử lý xong!");
47672
- return;
47642
+ setSelectedValue() {
47643
+ if (this._hasLoadedDatasource) {
47644
+ const oldValue = this._value;
47645
+ let hasValueInSource = false;
47646
+ if (this.dataSourceInternal != null && this.dataSourceInternal.length > 0) {
47647
+ for (const item of this.dataSourceInternal) {
47648
+ if (this._value != null
47649
+ && this._value !== ''
47650
+ && (item.value[this.control.valueField] == this._value || item.value[this.control.valueField] == this._value[this.control.valueField])) {
47651
+ this._value = item.value;
47652
+ hasValueInSource = true;
47653
+ break;
47654
+ }
47655
+ }
47656
+ if (!hasValueInSource) {
47657
+ this._value = null;
47658
+ }
47673
47659
  }
47674
- var job = new JobItem(templateCode, data, fileName || templateCode, this.statuses.Exporting);
47675
- this._queue.push(job);
47676
- if (useSignalR) {
47677
- this.ExportWithSignalR(job);
47660
+ if ((oldValue != null && this._value == null)
47661
+ || (oldValue == null && this._value != null)) {
47662
+ this.fireChangedEvent();
47678
47663
  }
47679
- else {
47680
- this.Export(job);
47664
+ else if (this._value != oldValue) {
47665
+ this.adjustValue2WayBinding();
47681
47666
  }
47682
- });
47667
+ }
47668
+ this.checkReady();
47683
47669
  }
47684
- Export(job) {
47670
+ reStructureItemObject(item) {
47671
+ const temp = { value: item };
47672
+ if (this.control.funcGetLabel) {
47673
+ temp.label = this.control.funcGetLabel(item);
47674
+ }
47675
+ else {
47676
+ temp.label = item[this.control.displayField];
47677
+ }
47678
+ temp.value._dropdownvalue = this.control.valueField;
47679
+ return temp;
47680
+ }
47681
+ _getData(filterParents) {
47685
47682
  return __awaiter(this, void 0, void 0, function* () {
47686
- this._tempateService.exportCxExcelByCodePromise({ code: job._code, data: JSON.stringify(job._data), fileName: job._fileName })
47687
- .then(file => {
47688
- job._status = this.statuses.Success;
47689
- job._binaryFile = file;
47690
- if (this.autoDownload) {
47691
- this.download(job);
47692
- }
47693
- }).catch((err) => __awaiter(this, void 0, void 0, function* () {
47694
- job._status = this.statuses.Error;
47695
- const errorText = yield err.error.text();
47696
- this._crudService.processErrorResponse(JSON.parse(errorText || ''));
47697
- }));
47683
+ if (this.control.baseService) {
47684
+ if (!filterParents)
47685
+ filterParents = [];
47686
+ yield this._getDataSource(filterParents);
47687
+ }
47698
47688
  });
47699
47689
  }
47700
- ExportWithSignalR(job) {
47690
+ _getDataSource(filterFromParents) {
47701
47691
  return __awaiter(this, void 0, void 0, function* () {
47702
- const topic = this._commonService.guid();
47703
- job._uniqueKey = topic;
47704
- this._signalRService.start(this.hub, topic, (message) => {
47705
- var rs = JSON.parse(message);
47706
- if (rs.success) {
47707
- job._status = this.statuses.Success;
47708
- job._fileId = rs.data;
47709
- if (this.autoDownload) {
47710
- this.download(job);
47711
- }
47692
+ const filters = yield this.filterProcess(filterFromParents);
47693
+ const dropdownOptions = this._crudService.createDropdownOptions(this.control);
47694
+ let dataSource;
47695
+ if (this.control.baseService instanceof MasterDataService) {
47696
+ dataSource = yield this.control.baseService.getDataDropdownByFilter(this.control.groupCode, null, filters, dropdownOptions);
47697
+ }
47698
+ else {
47699
+ if (this.control.isTree) {
47700
+ dataSource = yield this.control.baseService.getTreeDataDropdownByFilter(filters, this.control.fieldTree, this.control.valueParentRoot, dropdownOptions);
47712
47701
  }
47713
47702
  else {
47714
- job._status = this.statuses.Error;
47715
- this._crudService.processErrorResponse(rs);
47703
+ dataSource = yield this.control.baseService.getDataDropdownByFilter(filters, dropdownOptions);
47716
47704
  }
47717
- });
47718
- this._tempateService.ExportCxExcelByCodeWithSignalR({ code: job._code, data: JSON.stringify(job._data), fileName: job._fileName, topic: topic })
47719
- .then(rs => {
47720
- if (!rs.success) {
47721
- job._status = this.statuses.Error;
47722
- this._crudService.processErrorResponse(rs);
47705
+ }
47706
+ this.bindingDataSource(dataSource);
47707
+ if (this.control.fireCallBackInside) {
47708
+ if (this.control.callbackDataFinish) {
47709
+ this.control.callbackDataFinish({
47710
+ data: dataSource,
47711
+ elm: this
47712
+ });
47723
47713
  }
47724
- }).catch((err) => __awaiter(this, void 0, void 0, function* () {
47725
- job._status = this.statuses.Error;
47726
- this._crudService.processErrorResponse(err.error);
47727
- }));
47728
- ;
47714
+ }
47715
+ else {
47716
+ this.onDataSourceLoaded.emit({
47717
+ dataSource,
47718
+ elm: this
47719
+ });
47720
+ }
47729
47721
  });
47730
47722
  }
47731
- ExportCxExcelByCodeWithHPS(job) {
47723
+ filterProcess(filterFromParents) {
47732
47724
  return __awaiter(this, void 0, void 0, function* () {
47733
- this._highPerformanceService.createProcess(this.queueName, (arrMessage) => {
47734
- var message = arrMessage.pop();
47735
- var rs = JSON.parse(message);
47736
- if (rs.success) {
47737
- job._status = this.statuses.Success;
47738
- job._fileId = rs.data;
47739
- if (this.autoDownload) {
47740
- this._fileService.downloadFile(job._fileId);
47741
- job._status = this.statuses.Downloaded;
47742
- job._fileId = null;
47743
- }
47744
- }
47745
- else {
47746
- job._status = this.statuses.Error;
47747
- this._crudService.processErrorResponse(rs);
47748
- }
47749
- }).then(rs => {
47750
- job._uniqueKey = rs;
47751
- this._tempateService.ExportCxExcelByCodeWithHPS({
47752
- code: job._code,
47753
- data: JSON.stringify(job._data),
47754
- fileName: job._fileName,
47755
- topic: this.queueName,
47756
- uniqueKey: job._uniqueKey
47757
- }).then(rs => {
47758
- if (!rs.success) {
47759
- job._status = this.statuses.Error;
47760
- this._crudService.processErrorResponse(rs);
47761
- }
47762
- }, err => {
47763
- job._status = this.statuses.Error;
47764
- console.log("Lỗi gọi api server export");
47765
- });
47766
- }, err => {
47767
- job._status = this.statuses.Error;
47768
- console.log("Lỗi gọi HPS service :(");
47769
- });
47725
+ const filters = filterFromParents;
47726
+ yield appendDefaultFilter(filters, this.control.defaultFilters);
47727
+ if (this.control.modifyFilter) {
47728
+ yield this.control.modifyFilter(filters, this);
47729
+ }
47730
+ return filters;
47770
47731
  });
47771
47732
  }
47772
- download(job) {
47773
- if (job._status == this.statuses.Downloaded) {
47774
- return;
47775
- }
47776
- if (job._fileId) {
47777
- this._fileService.downloadFile(job._fileId, false, job._fileName);
47778
- }
47779
- else if (job._binaryFile) {
47780
- FileSaver.saveAs(job._binaryFile, job._fileName);
47733
+ checkReady() {
47734
+ if (this.control.onAdjustedValue
47735
+ && this._hasLoadedDatasource
47736
+ && this._value != null) {
47737
+ this.fireAdjustValueEvent();
47781
47738
  }
47782
- job._status = this.statuses.Downloaded;
47783
- job._binaryFile = null;
47784
- job._fileId = null;
47785
47739
  }
47786
- showQueue() {
47787
- let show = this._queue && this._queue.length > 0;
47788
- return show;
47740
+ getValueReturn() {
47741
+ return this.funcReturnValue(this._value);
47789
47742
  }
47790
- getName(job) {
47791
- var name = job._fileName.length > this.maxNameLength ? `${job._fileName.substr(0, this.maxNameLength - 10)}[...]${TemplateConstant.EXCEL_EXTENSION}` : job._fileName;
47792
- return name;
47743
+ checkInitedControl() {
47744
+ // Nếu chưa chạy qua init thì k fire event cả
47745
+ return !!this.control._component;
47793
47746
  }
47794
- cancelJob(job) {
47795
- let foundIndex = this._queue.findIndex(j => j._code == job._code);
47796
- if (foundIndex == -1) {
47747
+ fireChangedEvent() {
47748
+ // Nếu chưa chạy qua init thì k fire event gì cả
47749
+ if (!this.checkInitedControl())
47797
47750
  return;
47798
- }
47799
- let foundJob = this._queue[foundIndex];
47800
- if (foundJob._status == this.statuses.Exporting) {
47801
- this._notifierService
47802
- .showConfirm('File này đang được xử lý. Bạn có muốn dừng lại?', 'Hủy xuất file')
47803
- .then(rs => {
47804
- if (!rs) {
47805
- return;
47806
- }
47807
- let needUnsubscribe = foundJob._type == JobTypes.SingnalR && foundJob._uniqueKey;
47808
- if (needUnsubscribe) {
47809
- this._signalRService.unSubscribeViewCode(foundJob._uniqueKey, this.hub);
47810
- }
47811
- this._queue.splice(foundIndex, 1);
47812
- this.updatePopupHeight();
47813
- });
47814
- }
47815
- else if (foundJob._status != this.statuses.Exporting) {
47816
- this._queue.splice(foundIndex, 1);
47817
- this.updatePopupHeight();
47818
- }
47751
+ const valueReturn = this.getValueReturn();
47752
+ this.valueChange.emit(valueReturn);
47753
+ this.onChanged.emit(valueReturn);
47819
47754
  }
47820
- close() {
47821
- var hasExporting = this._queue && this._queue.filter(item => item._status == this.statuses.Exporting).length > 0;
47822
- if (hasExporting) {
47823
- this._notifierService
47824
- .showConfirm('Có file đang được xử lý. Bạn có muốn dừng lại?', 'Hủy xuất file')
47825
- .then(rs => {
47826
- if (!rs) {
47827
- return;
47828
- }
47829
- let needUnsubscribe = false;
47830
- this._queue.forEach(job => {
47831
- needUnsubscribe = job._type == JobTypes.SingnalR && job._uniqueKey;
47832
- if (needUnsubscribe) {
47833
- this._signalRService.unSubscribeViewCode(job._uniqueKey, this.hub);
47834
- }
47835
- });
47836
- this._queue = [];
47837
- this.updatePopupHeight();
47838
- });
47839
- }
47840
- else {
47841
- this._queue = [];
47842
- }
47755
+ fireAdjustValueEvent() {
47756
+ // Nếu chưa chạy qua init thì k fire event cả
47757
+ if (!this.checkInitedControl())
47758
+ return;
47759
+ const valueReturn = this.getValueReturn();
47760
+ this.adjustValue.next(valueReturn);
47843
47761
  }
47844
- updatePopupHeight() {
47845
- let height = (this._queue || []).length * this.itemHeight;
47846
- this.popupHeight = height > this.maxHeight ? this.maxHeight : height;
47762
+ adjustValue2WayBinding() {
47763
+ if (!this.checkInitedControl())
47764
+ return;
47765
+ const valueReturn = this.getValueReturn();
47766
+ this.valueChange.emit(valueReturn);
47767
+ }
47768
+ change(event) {
47769
+ this.fireChangedEvent();
47847
47770
  }
47848
47771
  }
47849
- ReportQueueComponent.decorators = [
47772
+ RadioButtonListComponent.decorators = [
47850
47773
  { type: Component, args: [{
47851
- selector: 'report-queue',
47852
- template: "<div class=\"rq-container\" *ngIf=\"showQueue()\">\n <div class=\"rq-header\">\n <div>{{header | translate}}</div>\n <div>\n\n <p-checkbox [(ngModel)]=\"autoDownload\" binary=\"true\" pTooltip=\"T\u1EF1 \u0111\u1ED9ng t\u1EA3i\" tooltipPosition=\"left\">\n </p-checkbox>\n\n <a href=\"javascript:;\" (click)=\"toggleExpand()\" pTooltip=\"{{expand ? 'Thu g\u1ECDn' : 'M\u1EDF r\u1ED9ng'}}\"\n tooltipPosition=\"left\">\n <i class=\"fas\" [ngClass]=\"{'fa-compress' : expand, 'fa-expand': !expand}\"></i>\n </a>\n\n <a href=\"javascript:;\" (click)=\"close()\" pTooltip=\"\u0110\u00F3ng\">\n <i class=\"fas fa-times\"></i>\n </a>\n </div>\n </div>\n <div class=\"rq-body\" *ngIf=\"expand\">\n <tn-custom-scrollbar [style]=\"{'height.px': popupHeight}\" #scrollbar>\n <div class=\"re-job\" *ngFor=\"let job of _queue\">\n <div class=\"re-job-title\">\n <div>{{getName(job)}}</div>\n <div>\n <a href=\"javascript:;\" (click)=\"cancelJob(job)\">\n <i class=\"fas fa-times\"></i>\n </a>\n </div>\n </div>\n <div class=\"re-job-result\"\n [ngClass]=\"{'job-success': job._status == statuses.Success, 'job-error': job._status == statuses.Error, 'job-exporting' : job._status == statuses.Exporting, 'job-downloaded': job._status == statuses.Downloaded}\">\n <span *ngIf=\"job._status != statuses.Success && job._status != statuses.Exporting\">\n {{dicStatus.get(job._status) | translate}}\n </span>\n\n <span *ngIf=\"job._status == statuses.Exporting\">\n <div class=\"loader\"></div>\n {{dicStatus.get(job._status) | translate}}\n </span>\n\n <a href=\"javascript:;\" (click)=\"download(job)\" class=\"job-success\"\n *ngIf=\"job._status == statuses.Success\">\n <i class=\"fas fa-download\"></i> {{dicStatus.get(job._status) | translate}}\n </a>\n </div>\n </div>\n </tn-custom-scrollbar>\n </div>\n</div>\n",
47853
- styles: ["::ng-deep .rq-container{width:350px;border:1px solid #3192e1;border-radius:3px;background-color:#fff}::ng-deep .rq-container .rq-header{background-color:#3192e1;padding:5px 10px;display:flex;border-radius:3px 3px 0 0;color:#fff;font-weight:400;font-size:15px}::ng-deep .rq-container .rq-header>div:first-child{flex-grow:1}::ng-deep .rq-container .rq-header>div:last-child>a{font-weight:200;margin-left:10px;color:#fff}::ng-deep .rq-container .rq-header>div:last-child>a>i{font-size:13px}::ng-deep .rq-container .rq-header>div:last-child .ui-chkbox-box{width:14px;height:14px;margin-top:-2px}::ng-deep .rq-container .rq-header>div:last-child .ui-chkbox-icon{font-size:13px;line-height:13px}::ng-deep .rq-container .rq-body .re-job{padding:6px 10px;display:flex;flex-direction:column}::ng-deep .rq-container .rq-body .re-job:first-child{padding-top:6px}::ng-deep .rq-container .rq-body .re-job .re-job-title{display:flex;font-size:13px}::ng-deep .rq-container .rq-body .re-job .re-job-title>div:first-child{flex-grow:1;padding-bottom:3px}::ng-deep .rq-container .rq-body .re-job .re-job-title>div a{color:#3192e1}::ng-deep .rq-container .rq-body .re-job .re-job-result{font-size:11px}::ng-deep .rq-container .rq-body .re-job .re-job-result>span{display:flex;align-items:center;height:20px}::ng-deep .rq-container .rq-body .re-job .re-job-result.job-exporting{color:#3192e1}::ng-deep .rq-container .rq-body .re-job .re-job-result.job-exporting>span>div{margin-right:5px}::ng-deep .rq-container .rq-body .re-job .re-job-result.job-success{color:#1ab91a}::ng-deep .rq-container .rq-body .re-job .re-job-result.job-success>a>i{margin-right:2px}::ng-deep .rq-container .rq-body .re-job .re-job-result.job-error{color:#e95353}::ng-deep .rq-container .rq-body .re-job .re-job-result.job-downloaded{color:#b2b2b2}::ng-deep .loader{border-radius:50%;border:2px solid #bcdbf5;border-top-color:#3192e1;width:12px;height:12px;animation:spin 1s linear infinite;display:inline-block}@keyframes spin{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}:host{position:absolute;bottom:1px;right:2px;z-index:1000}"]
47774
+ selector: 'radio-button-list',
47775
+ template: "<div class=\"p-grid tn-check-box-list\" [class.flex-end]=\"control.align == 'right'\"\n [class.flex-center]=\"control.align == 'center'\">\n <div [class]=\"classCheckBox\" *ngFor=\"let chk of dataSourceInternal\">\n <p-radioButton [disabled]=\"disabled ? true : null\" [label]=\"chk.label\" [value]=\"chk.value\"\n [(ngModel)]=\"_value\" (onClick)=\"change($event)\">\n </p-radioButton>\n </div>\n</div>\n",
47776
+ styles: [".tn-check-box-list.p-grid{margin-bottom:-.5em}.btn-clear{height:30px;cursor:pointer;border:none;background:#337ab7;color:#fff;border-radius:3px;padding:0 10px;margin:1px .5em 0}.p-col-horizontal{padding:.5em}::ng-deep .tn-check-box-list{position:relative}::ng-deep .tn-check-box-list.flex-end{justify-content:flex-end}::ng-deep .tn-check-box-list.flex-center{justify-content:center}::ng-deep .tn-check-box-list label{cursor:pointer}"]
47854
47777
  },] }
47855
47778
  ];
47856
- ReportQueueComponent.ctorParameters = () => [
47857
- { type: NotifierService },
47858
- { type: CommonService },
47859
- { type: FileExplorerService },
47860
- { type: TemplateService },
47861
- { type: SignalRService },
47862
- { type: HighPerformanceService },
47863
- { type: CrudService }
47779
+ RadioButtonListComponent.ctorParameters = () => [
47780
+ { type: CrudService },
47781
+ { type: DeviceDetectorService }
47864
47782
  ];
47865
- ReportQueueComponent.propDecorators = {
47866
- parentDataModel: [{ type: Input }],
47867
- name: [{ type: Input }],
47868
- header: [{ type: Input }],
47869
- autoDownload: [{ type: Input }],
47870
- scrollbar: [{ type: ViewChild, args: ['scrollbar',] }]
47783
+ RadioButtonListComponent.propDecorators = {
47784
+ control: [{ type: Input }],
47785
+ dataSource: [{ type: Input }],
47786
+ value: [{ type: Input }],
47787
+ disabled: [{ type: Input }],
47788
+ onInit: [{ type: Output }],
47789
+ valueChange: [{ type: Output }],
47790
+ onChanged: [{ type: Output }],
47791
+ onDataSourceLoaded: [{ type: Output }],
47792
+ adjustValue: [{ type: Output }],
47793
+ onReady: [{ type: Output }]
47794
+ };
47795
+
47796
+ class ReferenceTextBoxComponent extends ComponentBase {
47797
+ constructor(injector) {
47798
+ super(injector);
47799
+ this.onInit = new EventEmitter();
47800
+ this.data = '';
47801
+ this.ready = false;
47802
+ }
47803
+ set value(value) {
47804
+ this._value = value;
47805
+ this.checkAndGetData();
47806
+ }
47807
+ set dataSource(value) {
47808
+ if (!value)
47809
+ return;
47810
+ this._dataSource = value;
47811
+ }
47812
+ get dataSource() {
47813
+ return this._dataSource;
47814
+ }
47815
+ get value() {
47816
+ return this._value;
47817
+ }
47818
+ ngOnInit() {
47819
+ this.control._component = this;
47820
+ this.ready = true;
47821
+ this.checkAndGetData();
47822
+ this.onInit.emit(this);
47823
+ }
47824
+ checkAndGetData() {
47825
+ return __awaiter(this, void 0, void 0, function* () {
47826
+ this.data = '';
47827
+ if (!this.ready
47828
+ || this._value == null
47829
+ || !this.control
47830
+ || (!this.control.baseService && !this.dataSource))
47831
+ return;
47832
+ let item = null;
47833
+ if (this.control.baseService && this.control.baseService instanceof BaseService) {
47834
+ item = (yield this.control.baseService.getDetailByFilter([
47835
+ this.newFilter(this.control.valueField, Operator.equal, this.value)
47836
+ ])).data;
47837
+ }
47838
+ else if (this.dataSource) {
47839
+ item = this.dataSource.find(x => x[this.control.valueField] == this.value);
47840
+ }
47841
+ else {
47842
+ // TODO: xử lý lấy dữ liệu detail của master data
47843
+ item = null;
47844
+ }
47845
+ if (item == null)
47846
+ return;
47847
+ if (this.control.funcGetLabel) {
47848
+ this.data = this.control.funcGetLabel(item);
47849
+ }
47850
+ else {
47851
+ this.data = item[this.control.displayField];
47852
+ }
47853
+ });
47854
+ }
47855
+ }
47856
+ ReferenceTextBoxComponent.decorators = [
47857
+ { type: Component, args: [{
47858
+ selector: 'reference-textbox',
47859
+ template: "<div class=\"p-inputgroup\" *ngIf=\"control.suffix\">\n <input [placeholder]=\"control.placeholder\" disabled=\"true\" pInputText type='text' [ngModel]=\"data\" />\n <span class=\"p-inputgroup-addon\">({{control.suffix}})</span>\n</div>\n<input *ngIf=\"!control.suffix\" [placeholder]=\"control.placeholder\" disabled=\"true\" pInputText type='text'\n [ngModel]=\"data\" />",
47860
+ styles: [""]
47861
+ },] }
47862
+ ];
47863
+ ReferenceTextBoxComponent.ctorParameters = () => [
47864
+ { type: Injector }
47865
+ ];
47866
+ ReferenceTextBoxComponent.propDecorators = {
47867
+ control: [{ type: Input }],
47868
+ value: [{ type: Input }],
47869
+ dataSource: [{ type: Input }],
47870
+ onInit: [{ type: Output }]
47871
47871
  };
47872
47872
 
47873
47873
  class SettingsRowComponent extends ComponentBase {
@@ -57274,5 +57274,5 @@ class Pair {
57274
57274
  * Generated bundle index. Do not edit.
57275
57275
  */
57276
57276
 
57277
- export { AccessDeniedComponent, Action, ActionChoYKienBase, ActionThuHoiBase, ActionUpdateModel, AddressControlSchema, AddressService, AdvanceSearchData, AdvanceSearchSetting, AnnouncementReadsService, AnnouncementsService, AppComponentBase, AppListService, ApplicationContextService, ApprovalPipe, ArrayPair, AtLeastOneRowTableValidator, AuthenService, AuthorizeDirective, AutoCompleteControlSchema, AutoCompletePickerControlSchema, AutocompleteDatasourceComponent, AvatarUploaderComponent, BaseCauHinhWorkflowComponent, BaseCongViecComponent, BaseCongViecFormComponent, BaseDmLinhVucCongViecComponent, BaseDmLoaiCongViecComponent, BaseDmPriorityComponent, BaseMenuService, BaseModule, BaseService, BooleanFormatPipe, ButtonControlSchema, ButtonPermission, ButtonPermissions, ButtonTextActionCongViec, CONFIG_CALENDAR_VIETNAMESE, CalculationEngineService, CanBoHoSoService, CanBo_HoSo_CoCauToChucService, CauHinhWorkflowService, CccdValidator, CellExcel, ChatBoxComponent, ChatSendMessageBoxComponent, CheckBoxListControlSchema, CheckControlVisibleService, CheckDuplicateFieldsValidator, CheckDuplicateValidator, CheckboxControlSchema, ChipsControlSchema, ClientV5Service, CoCauToChucControlSchema, CoCauToChucNewService, CoCauToChucPickerComponent, CoCauToChucPickerControlSchema, CoCauToChucPickerControlSchemaNew, CoCauToChucService, CodeValidator, ColorBlack, ColorControlSchema, ColorPickerControlSchema, ColorWhite, Column, ColumnSchemaBase, ColumnSetting, ColumnSettingDetail, ComCtxConstants, CommandType, CommonAppComponentComponent, CommonDashboardComponent, CommonErrorCode, CommonSearchFormComponent, CommonService, CompareValidator, ComponentBase, ComponentBaseWithButton, ComponentConstants, ComponentContextService, ConditionalBuilderService, CongViecLienQuanService, CongViecNextFirstStepComponent, CongViecPickerControlSchema, CongViecService, ContainerSchema, ControlTreeNode, ControlType, ConvertMoneyToWordPipe, CoreConfigService, CrudBase, CrudFormComponent, CrudFormCustomFunction, CrudFormData, CrudFormSetting, CrudListComponent, CrudListConfig, CrudListCustomFunction, CrudListData, CrudListHelper, CrudListSetting, CrudService, CustomControlSchema, CustomRouterService, CustomizeUiModel, CustomizeUiService, DanhmucApiService, DataExcel, DataFormBase, DataListBase, DataSourceControlSchema, DataSourceGioiTinh, DataSourcePermissionBase, DataSourceStateType, DataSourceTargetType, DataSourceUserRule, DataSourceUserSender, DataSourceWorkflowCheckboxOption, DataSourceWorkflowCoreStatus, DataType, DateCompareValidator, DateTimeControlSchema, DateTimeRangeControlSchema, DbOrganizationOrganizationService, DbOrganizationPositionService, Deadline, DeadlineType, DhvinhGuardService, DialogModel, DmChucVuService, DmLinhVucCongViecService, DmLoaiCongViecService, DmPriorityService, DomService, DownloadLinkService, DropdownComponent, DropdownControlSchema, DropdownOptions, DummyWorkflowCode, DynamicComponentService, ENUM_DON_VI_HANH_CHINH, EXPLORER_TYPES, EXPORT_VERSION_V4, EXPORT_VERSION_V5, EditFileCommand, EditorControlSchema, EformService, EmailValidator, EntityMedataDataSetting, EntityMetadataService, EntityPickerColumn, EntityPickerControlSchema, EntityWorkflowType, EnumActionType, EnumAppSwitcherCode, EnumCanBo, EnumControlPickerType, EnumFileLayout, EnumGetRefType, EnumGioiTinh, EnumHocHamHocVi, EnumLoaiDanhSachCongViec, EnumLoaiVanBanBase$1 as EnumLoaiVanBanBase, EnumPermissionType, EnumProcessWorkflowType, EnumStateByMenuCongViec, EnumStateType, EnumTargetType, EnumTypeSplash, EnumUserRule, EnumUserSource, EnumWFNhomTrangThai, EnumWorkflowCheckboxOption, EnumWorkflowCoreCodeSettingKey, EnumWorkflowHistoryStatus, ErrorType, EventData, EventType, ExactOneValueInTableValidator, ExportAllMode, ExportItem, ExportItemType, ExportItemsMode, ExportManyModel, ExportManyResultModel, ExportModel, ExportService, ExportWithoutTemplateModel, Extension, ExtensionsConst, FILE_TYPES, FederationService, FieldCheckboxCrudList, FieldColExpandCrudList, FieldColReorderCrudList, FieldDefineHasTask, FieldDefineIsTaskFormControl, FieldDefineIsWorkflowControl, FieldFunctionCrudList, FieldIndexInDataSource, FieldOrderCrudList, FieldRowSpan, FieldWorkflowCodeInCrudForm, FileDataService, FileExplorerService, FileExtensions, FileManagerComponent, FileManagerControlSchema, FileManagerMode, FileManagerSetting, FileObjectService, FilePickerDialogComponent, FilePickerSetting, FileType, FileTypeFlag, FileUploadComponent, FileUploadControlSchema, FileUploadMode, FileUploadSetting, FileV4Service, Filter, FolderService, FormControlBase, FormControlBaseWithService, FormSchemaBase, FormSchemaBaseWithService, FormState, Gender, GenerateLinkDownloadDTO, GenericGuardChildService, GenericGuardService, GlobalService, GmailCorrector, GridInfo, GuardService, GuardSvService, HeightType, HighPerformanceService, HighlightPipe, HoSoDoiTacService, HtmlFormatPipe, HttpOptions, ImageService, ImageUploaderControlSchema, Include, JsPlumbOption, KeyFieldGetRefType, KeyFilterStateByMenuCongViec, KeyFlashShow, KeyFunctionReload, KeyValueComponent, KeyValueControlSchema, LabelSchema, LabelWFNhomTrangThai, LabelWorkflowCoreStatus, LengthValidator, ListHelperService, LoaiPhieuDeXuat, LocalCacheService, LowerCorrector, MA_THONG_BAO_PHAN_HE, MaActionBatDauQuyTrinh, ManagerType, MaskControlSchema, MasterDataItem, MasterDataPipe, MasterDataService, MenuService, MenuSource, MergeConfigModel, MethodResult, ModelKySoDonVi, ModelSchema, ModuleConfigService, MultiTranslateHttpLoader, MultipleReferenceDataFormatPipe, NameValidator, NodeService, NotificationObjectType, NotificationService, NotifierService, NotifierType, NumberCompareValidator, NumberOnlyValidator, NumberRangeControlSchema, Operator, OrganizationFormatPipe, OrganizationNameFormatPipe, OrganizationPickerControlSchema, OrganizationService, OrganizationsFormatPipe, PageInfo, PageSetting, Pair, PassportValidator, PasswordValidator, Pattern, PercentControlSchema, PermissionBase, PermissionConstant, PermissionService, PermissionStorage, PermissionTypes, PermissionUtilsComponent, PersonalSetting, PhanQuyenModel, PhoneNumberValidator, PhoneValidator, PopupSize, PositionService, PrintService, PublicFunction, QueryBuilderComponent, QueryBuilderGroupComponent, QueryBuilderRuleComponent, QueryGroup, QueryRule, RELOAD_FILE_LIST, RadioButtonListControlSchema, RandomDataService, RefField, ReferenceDataFormatPipe, ReferenceTextControlSchema, RegexSplitFieldByItem, ReponseResult, RequiredFieldsValidator, RequiredValidator, RowColorOption, RowExcel, SHARE_COMPONENT_ID, SHARE_EVENT, SafeHtmlPipe, SafeStylePipe, SafeUrlPipe, SameValueValidator, ScalarValueValidator, SchemaBase, SecurePipe, ServiceFileUploadComponent, ServiceRequestModel, ServiceRequestModelV5, SessionTypes, SharedFolderType, SignalRService, SimpleDicItem, SimpleDictionary, Sort, SortDirs, SpanControlSchema, SplashComponentComponent, StartupBusinessComponentBase, StateComponent, StateMachineTopic, StateMachinesConnectionMetadataComponent, StateMachinesDesignerComponent, StateMachinesService, StateMetadataComponent, Status, StatusAction, StatusGroup, StatusOption, StatusOrg, StatusUser, StorageService, StorageUpdatedService, StringCompareOption, StringFormatPipe, SummaryPipe, SwitchControlSchema, TBL_DM_COSODAOTAO_CONSTS, TBL_DM_PHONGHOC_CONSTS, TBL_KTX_NGUOITHUE_HOSO, TBL_TS_PHIEUDEXUAT, TBL_TS_TAISANCODINH_CONSTS, TabViewData, TableSchema, TagSeparator, TaiLieuComponent, TaxCodeValidator, TemplateConstant, TemplateControlSchema, TemplateInstanceService, TemplateService, TemplateTextItem, TemplateTextMany, TemplateTextV4Service, TemplateType, TemplateV4Service, TenContainer, TextAlign, TextAreaControlSchema, TextControlSchema, TextControlSchemaWithService, TitleSchema, TnClientCommand, TnClientService, TnComponentConfig, TnCustomScrollbarComponent, TnDatePipe, TnMenu, TnMenuItem, TnReorderableColumnDirective, TnReorderableRowDirective, TnSortIcon, TnSortableColumnDirective, TnTreeTableToggler, TnUser, TnxSharedModule, TopicReloadCongViecV5, TopicReloadCountCongViecV5, TopicReloadNotification, TrangThaiMasterData, TrangThais, TreeDataOption, TreeListBase, TreeNode, TrimCorrector, TrimEndCorrector, TrimStartCorrector, TypeDanhMucAPI, UniqueFieldInTableValidator, UniqueNumberService, UpperCorrector, UserGroupRealService, UserGroupService, UserOnlineDetailsService, UserPickerControlSchema, UserPickerDialogComponent, UserPublicInfo, UserService, UserType, UserV5Service, Validation, ValueType, VanBanPickerControlSchema, ViewContainerRefDirective, VirtualBaseService, WorkflowConfigAdvance, WorkflowCoreStatusEnum, WorkflowFieldStateCode, WorkflowHistoryService, WorkflowPermissionDetailService, WorkflowPickerComponent, WorkflowService, WorkflowSetting, WorkflowSettingNew, WorkflowSettingsService, WrapPickerControlSchema, addDay, addZero, appendDefaultFilter, clearAll, clone, cloneOld, coreDeclaration, coreModuleImport, coreProvider, createJsPlumnInstance, createOrgPickerControl, createOrgPickerControlNew, createRolePickerControl, createUserGroupPickerControl, createUserPickerControl, dataSourceIcon, dateDiff, fileTypeSource, genQueryFromFilters, getDateFromStringDateVN, getDayOfWeek, getEnvironmentByName, getEnvironmentData, getListMenuByName, getMenuData, getMonday, getStringDate, getStringDateTime, getStringDateVN, getStringDateVNLocal, getTimeSpan, isArray, isBoolean, isDate, isFunction, isLiteralObject, isNumber, isObjectOld, isRegular, isSimpleType, isString, isValidDate, isValidTime, keyUserSurveyLocal, loadRemoteModule, loadRemotePageModule, mapProperty, maximumPageSize, mergeJSON, mergeJSONOld, moduleConfigFunc, monthDiff, multipleSort, romanize, setMetadataConnection, setMetadataState, translateStateMachine, ɵ10, ɵ11, ɵ12, ɵ13, ɵ14, ɵ15, ɵ5, ɵ6, ɵ7, ɵ8, ɵ9, LoggerService as ɵa, DropdownService as ɵb, ProcessWorkflowFormComponent as ɵba, CongViecDinhKemService as ɵbb, CongViecThayDoiService as ɵbc, AddressComponent as ɵbd, AfterViewCheckedComponent as ɵbe, AdvanceSearchComponent as ɵbf, AutoCompletePickerComponent as ɵbg, ImageUploaderComponent as ɵbh, CheckBoxListComponent as ɵbi, CoCauToChucPickerListComponent as ɵbj, CoCauToChucPickerListNewComponent as ɵbk, FormBuilderComponent as ɵbl, BaseCongViecTestComponent as ɵbm, BaseCauHinhWorkflowDetailComponent as ɵbn, BaseDmLoaiCongViecFormComponent as ɵbo, BaseDmLinhVucCongViecFormComponent as ɵbp, BaseDmPriorityFormComponent as ɵbq, BaseCongviecDinhkemComponent as ɵbr, BaseCongviecDinhkemFormComponent as ɵbs, DatetimePickerComponent as ɵbt, DatetimePickerRangeComponent as ɵbu, DynamicNodeComponent as ɵbv, EntityPickerBoxComponent as ɵbw, EntityPickerDataComponent as ɵbx, EntityPickerSelectedComponent as ɵby, EntityPickerComponent as ɵbz, EntityPickerService as ɵc, EntityPickerDialogComponent as ɵca, EntityPickerTreeDataComponent as ɵcb, EntityPickerTreeSelectedComponent as ɵcc, EntityPermissionComponent as ɵcd, EquationEditorComponent as ɵce, MaskComponent as ɵcf, NumberPickerRangeComponent as ɵcg, PagingNextBackOnlyComponent as ɵch, RadioButtonListComponent as ɵci, VanBanPickerComponent as ɵcj, VanBanDenService as ɵck, VanBanDiService as ɵcl, VanBanPickerDialogComponent as ɵcm, VanbanDiPickerComponent as ɵcn, VanbanDenPickerComponent as ɵco, CongViecPickerComponent as ɵcp, ReportQueueComponent as ɵcq, SettingsComponent as ɵcr, SettingsRowComponent as ɵcs, SettingsWorkflowComponent as ɵct, SettingsWorkflowNo1Component as ɵcu, SimpleWorkflowFormComponent as ɵcv, ProcessWorkflowTargetComponent as ɵcw, ChoYKienFormComponent as ɵcx, SplashComponentV1Component as ɵcy, SplashComponentV2Component as ɵcz, ExceptionHandlerService as ɵd, SplashComponentV3Component as ɵda, SplashComponentV4Component as ɵdb, StateMachinesConnectionReceiverComponent as ɵdc, StateMachinesConnectionReceiverConditionComponent as ɵdd, StateMachinesConnectionReceiverDepartmentComponent as ɵde, StateMachinesConnectionReceiverGroupComponent as ɵdf, StateMachinesConnectionReceiverUserComponent as ɵdg, StateMachinesConnectionReceiverRoleComponent as ɵdh, StateMachinesConnectionSenderComponent as ɵdi, StartWorkflowComponent as ɵdj, ShareLinkByPermissionComponent as ɵdk, WorkflowSettingNewComponent as ɵdl, PermissionSharingComponent as ɵdm, WorkflowPermissionService as ɵdn, TnCheckboxComponent as ɵdo, TnDialogComponent as ɵdp, TnColorPickerComponent as ɵdq, TnTinymceComponent as ɵdr, TnTabViewComponent as ɵds, TableDetailFormComponent as ɵdt, FileIconPipe as ɵdu, FileSizePipe as ɵdv, QuickAddFormComponent as ɵdw, PreventShiftTabDirective as ɵdx, TnTemplateDirective as ɵdy, UserPickerComponent as ɵdz, CanBo_HoSoService as ɵe, UserPickerBoxComponent as ɵea, CoCauToChucTestService as ɵeb, TnAppHelpComponent as ɵec, PathNameService as ɵed, HelperCurrentPageComponent as ɵee, TnAppNotificationListComponent as ɵef, TnAppNotificationComponent as ɵeg, FolderFormComponent as ɵeh, FileFormComponent as ɵei, FileViewerComponent as ɵej, FileVersionListComponent as ɵek, ViewDetailComponent as ɵel, WorkflowHistoryComponent as ɵem, WorkflowHistoryDialogComponent as ɵen, WorkflowHistoryNewComponent as ɵeo, WorkflowSettingComponent as ɵep, WorkflowSettingDialogComponent as ɵeq, WorkflowPermissionComponent as ɵer, WorkflowPermissionFormComponent as ɵes, ReferenceTextBoxComponent as ɵet, QrCodeGeneratorComponent as ɵeu, AddNewsComponent as ɵev, ArticleService as ɵew, NewsCategoryService as ɵex, UniversalLinkProcessorComponent as ɵey, SignatureDetailComponent as ɵez, ListBase as ɵf, KySoSimDanhSachChuKyComponent as ɵfa, KySoSimChuKyUserService as ɵfb, FileKySoSimComponent as ɵfc, KySoSimSignPDFService as ɵfd, TaiLieuCuaToiComponent as ɵfe, KhaiThacTaiLieuDungChungComponent as ɵff, DanhMucDungChungService as ɵfg, TnTemplateComponent as ɵfh, DropdownSettingFormComponent as ɵfi, CheckReadyComponent as ɵfj, WorkflowButtonComponent as ɵfk, TnAccordionTabComponent as ɵfl, AppTopBarBaseComponent as ɵfm, AppTopBarV1Component as ɵfn, AppTopBarV2Component as ɵfo, AppTopBarV3Component as ɵfp, AppTopBarV4Component as ɵfq, LoadingPageV1Component as ɵfr, AppRootMenuComponent as ɵfs, AppFooterComponent as ɵft, AppProfileComponent as ɵfu, AppSubMenuComponent as ɵfv, AppMenuComponent as ɵfw, AppSubMenuV2Component as ɵfx, AppMenuV2Component as ɵfy, ListComponentBase as ɵg, TreeTableComponent as ɵh, NotFoundComponent as ɵi, SendAccessTokenInterceptor as ɵj, LogInterceptor as ɵk, PermissionUtilsInterceptor as ɵl, TraceInterceptor as ɵm, EntityWorkflowSettingService as ɵn, EntityWorkflowHistoryService as ɵo, EntityPermissionService as ɵp, ChatService as ɵq, MyDriveService as ɵr, ContentsService as ɵs, StatusExtendsService as ɵt, MessageBoardService as ɵu, FileExplorerNewService as ɵv, FileVersionService as ɵw, FileManagerService as ɵx, DM_ChucVuService as ɵy, RoleService as ɵz };
57277
+ export { AccessDeniedComponent, Action, ActionChoYKienBase, ActionThuHoiBase, ActionUpdateModel, AddressControlSchema, AddressService, AdvanceSearchData, AdvanceSearchSetting, AnnouncementReadsService, AnnouncementsService, AppComponentBase, AppListService, ApplicationContextService, ApprovalPipe, ArrayPair, AtLeastOneRowTableValidator, AuthenService, AuthorizeDirective, AutoCompleteControlSchema, AutoCompletePickerControlSchema, AutocompleteDatasourceComponent, AvatarUploaderComponent, BaseCauHinhWorkflowComponent, BaseCongViecComponent, BaseCongViecFormComponent, BaseDmLinhVucCongViecComponent, BaseDmLoaiCongViecComponent, BaseDmPriorityComponent, BaseMenuService, BaseModule, BaseService, BooleanFormatPipe, ButtonControlSchema, ButtonPermission, ButtonPermissions, ButtonTextActionCongViec, CONFIG_CALENDAR_VIETNAMESE, CalculationEngineService, CanBoHoSoService, CanBo_HoSo_CoCauToChucService, CauHinhWorkflowService, CccdValidator, CellExcel, ChatBoxComponent, ChatSendMessageBoxComponent, CheckBoxListControlSchema, CheckControlVisibleService, CheckDuplicateFieldsValidator, CheckDuplicateValidator, CheckboxControlSchema, ChipsControlSchema, ClientV5Service, CoCauToChucControlSchema, CoCauToChucNewService, CoCauToChucPickerComponent, CoCauToChucPickerControlSchema, CoCauToChucPickerControlSchemaNew, CoCauToChucService, CodeValidator, ColorBlack, ColorControlSchema, ColorPickerControlSchema, ColorWhite, Column, ColumnSchemaBase, ColumnSetting, ColumnSettingDetail, ComCtxConstants, CommandType, CommonAppComponentComponent, CommonDashboardComponent, CommonErrorCode, CommonSearchFormComponent, CommonService, CompareValidator, ComponentBase, ComponentBaseWithButton, ComponentConstants, ComponentContextService, ConditionalBuilderService, CongViecLienQuanService, CongViecNextFirstStepComponent, CongViecPickerControlSchema, CongViecService, ContainerSchema, ControlTreeNode, ControlType, ConvertMoneyToWordPipe, CoreConfigService, CrudBase, CrudFormComponent, CrudFormCustomFunction, CrudFormData, CrudFormSetting, CrudListComponent, CrudListConfig, CrudListCustomFunction, CrudListData, CrudListHelper, CrudListSetting, CrudService, CustomControlSchema, CustomRouterService, CustomizeUiModel, CustomizeUiService, DanhmucApiService, DataExcel, DataFormBase, DataListBase, DataSourceControlSchema, DataSourceGioiTinh, DataSourcePermissionBase, DataSourceStateType, DataSourceTargetType, DataSourceUserRule, DataSourceUserSender, DataSourceWorkflowCheckboxOption, DataSourceWorkflowCoreStatus, DataType, DateCompareValidator, DateTimeControlSchema, DateTimeRangeControlSchema, DbOrganizationOrganizationService, DbOrganizationPositionService, Deadline, DeadlineType, DhvinhGuardService, DialogModel, DmChucVuService, DmLinhVucCongViecService, DmLoaiCongViecService, DmPriorityService, DomService, DownloadLinkService, DropdownComponent, DropdownControlSchema, DropdownOptions, DummyWorkflowCode, DynamicComponentService, ENUM_DON_VI_HANH_CHINH, EXPLORER_TYPES, EXPORT_VERSION_V4, EXPORT_VERSION_V5, EditFileCommand, EditorControlSchema, EformService, EmailValidator, EntityMedataDataSetting, EntityMetadataService, EntityPickerColumn, EntityPickerControlSchema, EntityWorkflowType, EnumActionType, EnumAppSwitcherCode, EnumCanBo, EnumControlPickerType, EnumFileLayout, EnumGetRefType, EnumGioiTinh, EnumHocHamHocVi, EnumLoaiDanhSachCongViec, EnumLoaiVanBanBase$1 as EnumLoaiVanBanBase, EnumPermissionType, EnumProcessWorkflowType, EnumStateByMenuCongViec, EnumStateType, EnumTargetType, EnumTypeSplash, EnumUserRule, EnumUserSource, EnumWFNhomTrangThai, EnumWorkflowCheckboxOption, EnumWorkflowCoreCodeSettingKey, EnumWorkflowHistoryStatus, ErrorType, EventData, EventType, ExactOneValueInTableValidator, ExportAllMode, ExportItem, ExportItemType, ExportItemsMode, ExportManyModel, ExportManyResultModel, ExportModel, ExportService, ExportWithoutTemplateModel, Extension, ExtensionsConst, FILE_TYPES, FederationService, FieldCheckboxCrudList, FieldColExpandCrudList, FieldColReorderCrudList, FieldDefineHasTask, FieldDefineIsTaskFormControl, FieldDefineIsWorkflowControl, FieldFunctionCrudList, FieldIndexInDataSource, FieldOrderCrudList, FieldRowSpan, FieldWorkflowCodeInCrudForm, FileDataService, FileExplorerService, FileExtensions, FileManagerComponent, FileManagerControlSchema, FileManagerMode, FileManagerSetting, FileObjectService, FilePickerDialogComponent, FilePickerSetting, FileType, FileTypeFlag, FileUploadComponent, FileUploadControlSchema, FileUploadMode, FileUploadSetting, FileV4Service, Filter, FolderService, FormControlBase, FormControlBaseWithService, FormSchemaBase, FormSchemaBaseWithService, FormState, Gender, GenerateLinkDownloadDTO, GenericGuardChildService, GenericGuardService, GlobalService, GmailCorrector, GridInfo, GuardService, GuardSvService, HeightType, HighPerformanceService, HighlightPipe, HoSoDoiTacService, HtmlFormatPipe, HttpOptions, ImageService, ImageUploaderControlSchema, Include, JsPlumbOption, KeyFieldGetRefType, KeyFilterStateByMenuCongViec, KeyFlashShow, KeyFunctionReload, KeyValueComponent, KeyValueControlSchema, LabelSchema, LabelWFNhomTrangThai, LabelWorkflowCoreStatus, LengthValidator, ListHelperService, LoaiPhieuDeXuat, LocalCacheService, LowerCorrector, MA_THONG_BAO_PHAN_HE, MaActionBatDauQuyTrinh, ManagerType, MaskControlSchema, MasterDataItem, MasterDataPipe, MasterDataService, MenuService, MenuSource, MergeConfigModel, MethodResult, ModelKySoDonVi, ModelSchema, ModuleConfigService, MultiTranslateHttpLoader, MultipleReferenceDataFormatPipe, NameValidator, NodeService, NotificationObjectType, NotificationService, NotifierService, NotifierType, NumberCompareValidator, NumberOnlyValidator, NumberRangeControlSchema, Operator, OrganizationFormatPipe, OrganizationNameFormatPipe, OrganizationPickerControlSchema, OrganizationService, OrganizationsFormatPipe, PageInfo, PageSetting, Pair, PassportValidator, PasswordValidator, Pattern, PercentControlSchema, PermissionBase, PermissionConstant, PermissionService, PermissionStorage, PermissionTypes, PermissionUtilsComponent, PersonalSetting, PhanQuyenModel, PhoneNumberValidator, PhoneValidator, PopupSize, PositionService, PrintService, PublicFunction, QueryBuilderComponent, QueryBuilderGroupComponent, QueryBuilderRuleComponent, QueryGroup, QueryRule, RELOAD_FILE_LIST, RadioButtonListControlSchema, RandomDataService, RefField, ReferenceDataFormatPipe, ReferenceTextControlSchema, RegexSplitFieldByItem, ReponseResult, RequiredFieldsValidator, RequiredValidator, RowColorOption, RowExcel, SHARE_COMPONENT_ID, SHARE_EVENT, SafeHtmlPipe, SafeStylePipe, SafeUrlPipe, SameValueValidator, ScalarValueValidator, SchemaBase, SecurePipe, ServiceFileUploadComponent, ServiceRequestModel, ServiceRequestModelV5, SessionTypes, SharedFolderType, SignalRService, SimpleDicItem, SimpleDictionary, Sort, SortDirs, SpanControlSchema, SplashComponentComponent, StartupBusinessComponentBase, StateComponent, StateMachineTopic, StateMachinesConnectionMetadataComponent, StateMachinesDesignerComponent, StateMachinesService, StateMetadataComponent, Status, StatusAction, StatusGroup, StatusOption, StatusOrg, StatusUser, StorageService, StorageUpdatedService, StringCompareOption, StringFormatPipe, SummaryPipe, SwitchControlSchema, TBL_DM_COSODAOTAO_CONSTS, TBL_DM_PHONGHOC_CONSTS, TBL_KTX_NGUOITHUE_HOSO, TBL_TS_PHIEUDEXUAT, TBL_TS_TAISANCODINH_CONSTS, TabViewData, TableSchema, TagSeparator, TaiLieuComponent, TaxCodeValidator, TemplateConstant, TemplateControlSchema, TemplateInstanceService, TemplateService, TemplateTextItem, TemplateTextMany, TemplateTextV4Service, TemplateType, TemplateV4Service, TenContainer, TextAlign, TextAreaControlSchema, TextControlSchema, TextControlSchemaWithService, TitleSchema, TnClientCommand, TnClientService, TnComponentConfig, TnCustomScrollbarComponent, TnDatePipe, TnMenu, TnMenuItem, TnReorderableColumnDirective, TnReorderableRowDirective, TnSortIcon, TnSortableColumnDirective, TnTreeTableToggler, TnUser, TnxSharedModule, TopicReloadCongViecV5, TopicReloadCountCongViecV5, TopicReloadNotification, TrangThaiMasterData, TrangThais, TreeDataOption, TreeListBase, TreeNode, TrimCorrector, TrimEndCorrector, TrimStartCorrector, TypeDanhMucAPI, UniqueFieldInTableValidator, UniqueNumberService, UpperCorrector, UserGroupRealService, UserGroupService, UserOnlineDetailsService, UserPickerControlSchema, UserPickerDialogComponent, UserPublicInfo, UserService, UserType, UserV5Service, Validation, ValueType, VanBanPickerControlSchema, ViewContainerRefDirective, VirtualBaseService, WorkflowConfigAdvance, WorkflowCoreStatusEnum, WorkflowFieldStateCode, WorkflowHistoryService, WorkflowPermissionDetailService, WorkflowPickerComponent, WorkflowService, WorkflowSetting, WorkflowSettingNew, WorkflowSettingsService, WrapPickerControlSchema, addDay, addZero, appendDefaultFilter, clearAll, clone, cloneOld, coreDeclaration, coreModuleImport, coreProvider, createJsPlumnInstance, createOrgPickerControl, createOrgPickerControlNew, createRolePickerControl, createUserGroupPickerControl, createUserPickerControl, dataSourceIcon, dateDiff, fileTypeSource, genQueryFromFilters, getDateFromStringDateVN, getDayOfWeek, getEnvironmentByName, getEnvironmentData, getListMenuByName, getMenuData, getMonday, getStringDate, getStringDateTime, getStringDateVN, getStringDateVNLocal, getTimeSpan, isArray, isBoolean, isDate, isFunction, isLiteralObject, isNumber, isObjectOld, isRegular, isSimpleType, isString, isValidDate, isValidTime, keyUserSurveyLocal, loadRemoteModule, loadRemotePageModule, mapProperty, maximumPageSize, mergeJSON, mergeJSONOld, moduleConfigFunc, monthDiff, multipleSort, romanize, setMetadataConnection, setMetadataState, translateStateMachine, ɵ10, ɵ11, ɵ12, ɵ13, ɵ14, ɵ15, ɵ5, ɵ6, ɵ7, ɵ8, ɵ9, LoggerService as ɵa, DropdownService as ɵb, RoleService as ɵba, ProcessWorkflowFormComponent as ɵbb, CongViecDinhKemService as ɵbc, CongViecThayDoiService as ɵbd, AddressComponent as ɵbe, AfterViewCheckedComponent as ɵbf, AdvanceSearchComponent as ɵbg, AutoCompletePickerComponent as ɵbh, ImageUploaderComponent as ɵbi, CheckBoxListComponent as ɵbj, CoCauToChucPickerListComponent as ɵbk, CoCauToChucPickerListNewComponent as ɵbl, FormBuilderComponent as ɵbm, BaseCongViecTestComponent as ɵbn, BaseCauHinhWorkflowDetailComponent as ɵbo, BaseDmLoaiCongViecFormComponent as ɵbp, BaseDmLinhVucCongViecFormComponent as ɵbq, BaseDmPriorityFormComponent as ɵbr, BaseCongviecDinhkemComponent as ɵbs, BaseCongviecDinhkemFormComponent as ɵbt, DatetimePickerComponent as ɵbu, DatetimePickerRangeComponent as ɵbv, DynamicNodeComponent as ɵbw, EntityPickerBoxComponent as ɵbx, EntityPickerDataComponent as ɵby, EntityPickerSelectedComponent as ɵbz, EntityPickerService as ɵc, EntityPickerComponent as ɵca, EntityPickerDialogComponent as ɵcb, EntityPickerTreeDataComponent as ɵcc, EntityPickerTreeSelectedComponent as ɵcd, EntityPermissionComponent as ɵce, EquationEditorComponent as ɵcf, MaskComponent as ɵcg, NumberPickerRangeComponent as ɵch, PagingNextBackOnlyComponent as ɵci, RadioButtonListComponent as ɵcj, VanBanPickerComponent as ɵck, VanBanDenService as ɵcl, VanBanDiService as ɵcm, VanBanPickerDialogComponent as ɵcn, VanbanDiPickerComponent as ɵco, VanbanDenPickerComponent as ɵcp, CongViecPickerComponent as ɵcq, SettingsComponent as ɵcr, SettingsRowComponent as ɵcs, SettingsWorkflowComponent as ɵct, SettingsWorkflowNo1Component as ɵcu, SimpleWorkflowFormComponent as ɵcv, ProcessWorkflowTargetComponent as ɵcw, ChoYKienFormComponent as ɵcx, SplashComponentV1Component as ɵcy, SplashComponentV2Component as ɵcz, ExceptionHandlerService as ɵd, SplashComponentV3Component as ɵda, SplashComponentV4Component as ɵdb, StateMachinesConnectionReceiverComponent as ɵdc, StateMachinesConnectionReceiverConditionComponent as ɵdd, StateMachinesConnectionReceiverDepartmentComponent as ɵde, StateMachinesConnectionReceiverGroupComponent as ɵdf, StateMachinesConnectionReceiverUserComponent as ɵdg, StateMachinesConnectionReceiverRoleComponent as ɵdh, StateMachinesConnectionSenderComponent as ɵdi, StartWorkflowComponent as ɵdj, ShareLinkByPermissionComponent as ɵdk, WorkflowSettingNewComponent as ɵdl, PermissionSharingComponent as ɵdm, WorkflowPermissionService as ɵdn, TnCheckboxComponent as ɵdo, TnDialogComponent as ɵdp, TnColorPickerComponent as ɵdq, TnTinymceComponent as ɵdr, TnTabViewComponent as ɵds, TableDetailFormComponent as ɵdt, FileIconPipe as ɵdu, FileSizePipe as ɵdv, QuickAddFormComponent as ɵdw, PreventShiftTabDirective as ɵdx, TnTemplateDirective as ɵdy, UserPickerComponent as ɵdz, CanBo_HoSoService as ɵe, UserPickerBoxComponent as ɵea, CoCauToChucTestService as ɵeb, TnAppHelpComponent as ɵec, PathNameService as ɵed, HelperCurrentPageComponent as ɵee, TnAppNotificationListComponent as ɵef, TnAppNotificationComponent as ɵeg, FolderFormComponent as ɵeh, FileFormComponent as ɵei, FileViewerComponent as ɵej, FileVersionListComponent as ɵek, ViewDetailComponent as ɵel, WorkflowHistoryComponent as ɵem, WorkflowHistoryDialogComponent as ɵen, WorkflowHistoryNewComponent as ɵeo, WorkflowSettingComponent as ɵep, WorkflowSettingDialogComponent as ɵeq, WorkflowPermissionComponent as ɵer, WorkflowPermissionFormComponent as ɵes, ReferenceTextBoxComponent as ɵet, QrCodeGeneratorComponent as ɵeu, AddNewsComponent as ɵev, ArticleService as ɵew, NewsCategoryService as ɵex, UniversalLinkProcessorComponent as ɵey, SignatureDetailComponent as ɵez, ListBase as ɵf, KySoSimDanhSachChuKyComponent as ɵfa, KySoSimChuKyUserService as ɵfb, FileKySoSimComponent as ɵfc, KySoSimSignPDFService as ɵfd, TaiLieuCuaToiComponent as ɵfe, KhaiThacTaiLieuDungChungComponent as ɵff, DanhMucDungChungService as ɵfg, TnTemplateComponent as ɵfh, DropdownSettingFormComponent as ɵfi, CheckReadyComponent as ɵfj, WorkflowButtonComponent as ɵfk, TnAccordionTabComponent as ɵfl, AppTopBarBaseComponent as ɵfm, AppTopBarV1Component as ɵfn, AppTopBarV2Component as ɵfo, AppTopBarV3Component as ɵfp, AppTopBarV4Component as ɵfq, LoadingPageV1Component as ɵfr, AppRootMenuComponent as ɵfs, AppFooterComponent as ɵft, AppProfileComponent as ɵfu, AppSubMenuComponent as ɵfv, AppMenuComponent as ɵfw, AppSubMenuV2Component as ɵfx, AppMenuV2Component as ɵfy, ListComponentBase as ɵg, TreeTableComponent as ɵh, NotFoundComponent as ɵi, SendAccessTokenInterceptor as ɵj, LogInterceptor as ɵk, PermissionUtilsInterceptor as ɵl, TraceInterceptor as ɵm, EntityWorkflowSettingService as ɵn, EntityWorkflowHistoryService as ɵo, EntityPermissionService as ɵp, ChatService as ɵq, MyDriveService as ɵr, ContentsService as ɵs, StatusExtendsService as ɵt, MessageBoardService as ɵu, FileExplorerNewService as ɵv, ReportQueueComponent as ɵw, FileVersionService as ɵx, FileManagerService as ɵy, DM_ChucVuService as ɵz };
57278
57278
  //# sourceMappingURL=tnx-shared.js.map