tnx-shared 5.1.26 → 5.1.30
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bundles/tnx-shared.umd.js +1999 -249
- package/bundles/tnx-shared.umd.js.map +1 -1
- package/bundles/tnx-shared.umd.min.js +1 -1
- package/bundles/tnx-shared.umd.min.js.map +1 -1
- package/classes/base/data-list-base.d.ts +2 -0
- package/classes/base/data-list-base.d.ts.map +1 -1
- package/classes/form-schema.d.ts +3 -0
- package/classes/form-schema.d.ts.map +1 -1
- package/components/chat/chat-box/chat-box.component.d.ts +102 -0
- package/components/chat/chat-box/chat-box.component.d.ts.map +1 -0
- package/components/chat/chat-box/chat-box.component.ngfactory.d.ts.map +1 -0
- package/components/chat/chat-box/chat-box.component.scss.shim.ngstyle.d.ts.map +1 -0
- package/components/chat/chat-send-message-box/chat-send-message-box.component.d.ts +37 -0
- package/components/chat/chat-send-message-box/chat-send-message-box.component.d.ts.map +1 -0
- package/components/chat/chat-send-message-box/chat-send-message-box.component.ngfactory.d.ts.map +1 -0
- package/components/chat/chat-send-message-box/chat-send-message-box.component.scss.shim.ngstyle.d.ts.map +1 -0
- package/components/chat/common-style.scss.shim.ngstyle.d.ts.map +1 -0
- package/components/chat/models/enums.d.ts +11 -0
- package/components/chat/models/enums.d.ts.map +1 -0
- package/components/chat/models/models.d.ts +10 -0
- package/components/chat/models/models.d.ts.map +1 -0
- package/components/chat/services/chat.service.d.ts +34 -0
- package/components/chat/services/chat.service.d.ts.map +1 -0
- package/components/chat/services/chat.service.ngfactory.d.ts.map +1 -0
- package/components/chat/services/content.service.d.ts +20 -0
- package/components/chat/services/content.service.d.ts.map +1 -0
- package/components/chat/services/content.service.ngfactory.d.ts.map +1 -0
- package/components/chat/services/message-board.service.d.ts +15 -0
- package/components/chat/services/message-board.service.d.ts.map +1 -0
- package/components/chat/services/message-board.service.ngfactory.d.ts.map +1 -0
- package/components/chat/services/status.service.d.ts +14 -0
- package/components/chat/services/status.service.d.ts.map +1 -0
- package/components/chat/services/status.service.ngfactory.d.ts.map +1 -0
- package/components/crud/crud-list/crud-list.component.d.ts +6 -0
- package/components/crud/crud-list/crud-list.component.d.ts.map +1 -1
- package/components/file-explorer/file-manager/file-manager.component.d.ts +6 -0
- package/components/file-explorer/file-manager/file-manager.component.d.ts.map +1 -1
- package/components/file-explorer/models/service-request-model.d.ts +1 -0
- package/components/file-explorer/models/service-request-model.d.ts.map +1 -1
- package/components/statemachines/models/enums.d.ts +4 -0
- package/components/statemachines/models/enums.d.ts.map +1 -1
- package/components/statemachines/statemachines-designer/statemachines-designer.component.d.ts +1 -1
- package/components/statemachines/statemachines-designer/statemachines-designer.component.d.ts.map +1 -1
- package/components/tn-custom-scrollbar/tn-custom-scrollbar.component.d.ts +1 -0
- package/components/tn-custom-scrollbar/tn-custom-scrollbar.component.d.ts.map +1 -1
- package/components/tn-dialog/tn-dialog.component.d.ts +1 -0
- package/components/tn-dialog/tn-dialog.component.d.ts.map +1 -1
- package/components/user-picker/user-picker-dialog/user-picker-dialog.component.d.ts +23 -0
- package/components/user-picker/user-picker-dialog/user-picker-dialog.component.d.ts.map +1 -0
- package/components/user-picker/user-picker-dialog/user-picker-dialog.component.ngfactory.d.ts.map +1 -0
- package/components/user-picker/user-picker-dialog/user-picker-dialog.component.scss.shim.ngstyle.d.ts.map +1 -0
- package/components/workflow/permission-sharing/permission-sharing.component.d.ts +21 -0
- package/components/workflow/permission-sharing/permission-sharing.component.d.ts.map +1 -0
- package/components/workflow/permission-sharing/permission-sharing.component.ngfactory.d.ts.map +1 -0
- package/components/workflow/permission-sharing/permission-sharing.component.scss.shim.ngstyle.d.ts.map +1 -0
- package/components/workflow/services/workflow-permission.service.d.ts +10 -0
- package/components/workflow/services/workflow-permission.service.d.ts.map +1 -0
- package/components/workflow/services/workflow-permission.service.ngfactory.d.ts.map +1 -0
- package/components/workflow/workflow-history-new/workflow-history-new.component.d.ts.map +1 -1
- package/congviec/congviec/congviec-dinhkem/congviec-dinhkem.component.d.ts +6 -2
- package/congviec/congviec/congviec-dinhkem/congviec-dinhkem.component.d.ts.map +1 -1
- package/congviec/congviec/congviec-form/congviec-form.component.d.ts +9 -1
- package/congviec/congviec/congviec-form/congviec-form.component.d.ts.map +1 -1
- package/esm2015/classes/base/data-form-base.js +3 -3
- package/esm2015/classes/base/data-list-base.js +41 -6
- package/esm2015/classes/form-schema.js +1 -1
- package/esm2015/components/chat/chat-box/chat-box.component.js +626 -0
- package/esm2015/components/chat/chat-send-message-box/chat-send-message-box.component.js +245 -0
- package/esm2015/components/chat/models/enums.js +13 -0
- package/esm2015/components/chat/models/models.js +12 -0
- package/esm2015/components/chat/services/chat.service.js +113 -0
- package/esm2015/components/chat/services/content.service.js +57 -0
- package/esm2015/components/chat/services/message-board.service.js +40 -0
- package/esm2015/components/chat/services/status.service.js +36 -0
- package/esm2015/components/crud/crud-list/crud-list.component.js +55 -4
- package/esm2015/components/file-explorer/file-manager/file-manager.component.js +69 -16
- package/esm2015/components/file-explorer/file-viewer/file-viewer.component.js +2 -2
- package/esm2015/components/file-explorer/models/service-request-model.js +5 -2
- package/esm2015/components/statemachines/models/enums.js +6 -1
- package/esm2015/components/tn-custom-scrollbar/tn-custom-scrollbar.component.js +26 -11
- package/esm2015/components/tn-dialog/tn-dialog.component.js +4 -2
- package/esm2015/components/user-picker/user-picker-dialog/user-picker-dialog.component.js +52 -0
- package/esm2015/components/workflow/permission-sharing/permission-sharing.component.js +123 -0
- package/esm2015/components/workflow/services/workflow-permission.service.js +27 -0
- package/esm2015/components/workflow/workflow-history-new/workflow-history-new.component.js +4 -1
- package/esm2015/congviec/cauhinh-workflow/cauhinh-workflow-detail/cauhinh-workflow-detail.component.js +2 -2
- package/esm2015/congviec/congviec/congviec-dinhkem/congviec-dinhkem.component.js +38 -14
- package/esm2015/congviec/congviec/congviec-form/congviec-form.component.js +25 -4
- package/esm2015/congviec/congviec/congviec.component.js +3 -3
- package/esm2015/models/basic-user-info.js +6 -1
- package/esm2015/public-api.js +4 -1
- package/esm2015/services/base.service.js +33 -9
- package/esm2015/services/common.service.js +3 -18
- package/esm2015/services/crud.service.js +56 -41
- package/esm2015/services/notifier.service.js +2 -2
- package/esm2015/services/user.service.js +37 -23
- package/esm2015/tnx-shared.js +49 -43
- package/esm2015/tnx-shared.module.js +10 -2
- package/fesm2015/tnx-shared.js +1705 -202
- package/fesm2015/tnx-shared.js.map +1 -1
- package/models/basic-user-info.d.ts +2 -3
- package/models/basic-user-info.d.ts.map +1 -1
- package/package.json +2 -2
- package/public-api.d.ts +3 -0
- package/public-api.d.ts.map +1 -1
- package/services/base.service.d.ts +5 -1
- package/services/base.service.d.ts.map +1 -1
- package/services/common.service.d.ts +3 -3
- package/services/common.service.d.ts.map +1 -1
- package/services/crud.service.d.ts.map +1 -1
- package/services/notifier.service.d.ts +1 -1
- package/services/notifier.service.d.ts.map +1 -1
- package/services/user.service.d.ts +14 -2
- package/services/user.service.d.ts.map +1 -1
- package/tnx-shared.d.ts +48 -42
- package/tnx-shared.d.ts.map +1 -1
- package/tnx-shared.metadata.json +1 -1
- package/tnx-shared.module.d.ts +5 -1
- package/tnx-shared.module.d.ts.map +1 -1
- package/tnx-shared.module.ngfactory.d.ts.map +1 -1
package/fesm2015/tnx-shared.js
CHANGED
|
@@ -55,6 +55,7 @@ import { ActivatedRoute, Router, NavigationEnd, NavigationStart } from '@angular
|
|
|
55
55
|
import { Subject, ReplaySubject, combineLatest, forkJoin, from } from 'rxjs';
|
|
56
56
|
import { takeUntil, catchError, shareReplay, retry, map, filter, debounceTime, distinctUntilChanged, mergeMap } from 'rxjs/operators';
|
|
57
57
|
import { __awaiter } from 'tslib';
|
|
58
|
+
import { v4 } from 'uuid';
|
|
58
59
|
import stringify from 'fast-safe-stringify';
|
|
59
60
|
import * as moment_ from 'moment';
|
|
60
61
|
import { isObject, sortBy, groupBy } from 'underscore';
|
|
@@ -605,7 +606,7 @@ class NotifierService {
|
|
|
605
606
|
life
|
|
606
607
|
});
|
|
607
608
|
}
|
|
608
|
-
|
|
609
|
+
showWarningByResponse(res) {
|
|
609
610
|
let message = res.message;
|
|
610
611
|
if (!message)
|
|
611
612
|
message = res.error;
|
|
@@ -883,23 +884,7 @@ class CommonService {
|
|
|
883
884
|
this.STORAGE_KEY = 'CLIPBOARD_CONTENT';
|
|
884
885
|
}
|
|
885
886
|
guid() {
|
|
886
|
-
|
|
887
|
-
return Math.floor((1 + Math.random()) * 0x10000)
|
|
888
|
-
.toString(16)
|
|
889
|
-
.substring(1);
|
|
890
|
-
}
|
|
891
|
-
return (s4() +
|
|
892
|
-
s4() +
|
|
893
|
-
'-' +
|
|
894
|
-
s4() +
|
|
895
|
-
'-' +
|
|
896
|
-
s4() +
|
|
897
|
-
'-' +
|
|
898
|
-
s4() +
|
|
899
|
-
'-' +
|
|
900
|
-
s4() +
|
|
901
|
-
s4() +
|
|
902
|
-
s4());
|
|
887
|
+
return v4();
|
|
903
888
|
}
|
|
904
889
|
randomString() {
|
|
905
890
|
return this.guid();
|
|
@@ -4641,16 +4626,16 @@ class CrudService {
|
|
|
4641
4626
|
return Math.ceil(milisecond / 3600000) + ' giờ trước';
|
|
4642
4627
|
}
|
|
4643
4628
|
else {
|
|
4644
|
-
return ('Hôm qua lúc '
|
|
4645
|
-
this.datePipe.transform(datetime, 'HH:mm'));
|
|
4629
|
+
return ('Hôm qua lúc '
|
|
4630
|
+
+ this.datePipe.transform(datetime, 'HH:mm'));
|
|
4646
4631
|
}
|
|
4647
4632
|
}
|
|
4648
4633
|
if (milisecond >= 86400000) {
|
|
4649
|
-
if (datetime.getDate() == now.getDate() - 1
|
|
4650
|
-
datetime.getMonth() == now.getMonth()
|
|
4651
|
-
datetime.getYear() == now.getYear()) {
|
|
4652
|
-
return ('Hôm qua lúc '
|
|
4653
|
-
this.datePipe.transform(datetime, 'HH:mm'));
|
|
4634
|
+
if (datetime.getDate() == now.getDate() - 1
|
|
4635
|
+
&& datetime.getMonth() == now.getMonth()
|
|
4636
|
+
&& datetime.getYear() == now.getYear()) {
|
|
4637
|
+
return ('Hôm qua lúc '
|
|
4638
|
+
+ this.datePipe.transform(datetime, 'HH:mm'));
|
|
4654
4639
|
}
|
|
4655
4640
|
else {
|
|
4656
4641
|
return this.datePipe.transform(datetime, 'dd/MM/yyyy HH:mm');
|
|
@@ -4685,25 +4670,25 @@ class CrudService {
|
|
|
4685
4670
|
return Math.ceil(milisecond / 3600000) + ' giờ nữa';
|
|
4686
4671
|
}
|
|
4687
4672
|
else {
|
|
4688
|
-
return ('Ngày mai lúc '
|
|
4689
|
-
this.datePipe.transform(datetime, 'HH:mm'));
|
|
4673
|
+
return ('Ngày mai lúc '
|
|
4674
|
+
+ this.datePipe.transform(datetime, 'HH:mm'));
|
|
4690
4675
|
}
|
|
4691
4676
|
}
|
|
4692
4677
|
if (milisecond >= 86400000) {
|
|
4693
|
-
if (datetime.getDate() == now.getDate() - 1
|
|
4694
|
-
datetime.getMonth() == now.getMonth()
|
|
4695
|
-
datetime.getYear() == now.getYear()) {
|
|
4696
|
-
return ('Ngày mai lúc '
|
|
4697
|
-
this.datePipe.transform(datetime, 'HH:mm'));
|
|
4698
|
-
}
|
|
4699
|
-
if (datetime.getDate() == now.getDate() - 2
|
|
4700
|
-
datetime.getMonth() == now.getMonth()
|
|
4701
|
-
datetime.getYear() == now.getYear()) {
|
|
4678
|
+
if (datetime.getDate() == now.getDate() - 1
|
|
4679
|
+
&& datetime.getMonth() == now.getMonth()
|
|
4680
|
+
&& datetime.getYear() == now.getYear()) {
|
|
4681
|
+
return ('Ngày mai lúc '
|
|
4682
|
+
+ this.datePipe.transform(datetime, 'HH:mm'));
|
|
4683
|
+
}
|
|
4684
|
+
if (datetime.getDate() == now.getDate() - 2
|
|
4685
|
+
&& datetime.getMonth() == now.getMonth()
|
|
4686
|
+
&& datetime.getYear() == now.getYear()) {
|
|
4702
4687
|
return 'Hai ngày nữa';
|
|
4703
4688
|
}
|
|
4704
|
-
else if (datetime.getDate() == now.getDate() - 3
|
|
4705
|
-
datetime.getMonth() == now.getMonth()
|
|
4706
|
-
datetime.getYear() == now.getYear()) {
|
|
4689
|
+
else if (datetime.getDate() == now.getDate() - 3
|
|
4690
|
+
&& datetime.getMonth() == now.getMonth()
|
|
4691
|
+
&& datetime.getYear() == now.getYear()) {
|
|
4707
4692
|
return 'Ba ngày nữa';
|
|
4708
4693
|
}
|
|
4709
4694
|
else {
|
|
@@ -4723,8 +4708,8 @@ class CrudService {
|
|
|
4723
4708
|
return this.datePipe.transform(datetime, 'dd/MM/yyyy');
|
|
4724
4709
|
}
|
|
4725
4710
|
const now = new Date();
|
|
4726
|
-
if (datetime.getMonth() == now.getMonth()
|
|
4727
|
-
datetime.getYear() == now.getYear()) {
|
|
4711
|
+
if (datetime.getMonth() == now.getMonth()
|
|
4712
|
+
&& datetime.getYear() == now.getYear()) {
|
|
4728
4713
|
const days = datetime.getDate() - now.getDate();
|
|
4729
4714
|
if (days == 0) {
|
|
4730
4715
|
return 'Hôm nay';
|
|
@@ -4755,7 +4740,8 @@ class CrudService {
|
|
|
4755
4740
|
return this.datePipe.transform(datetime, 'dd/MM/yyyy');
|
|
4756
4741
|
}
|
|
4757
4742
|
}
|
|
4758
|
-
hideControlAndLabel() {
|
|
4743
|
+
hideControlAndLabel() {
|
|
4744
|
+
}
|
|
4759
4745
|
buildFilter(field, operator, value) {
|
|
4760
4746
|
return new Filter({ field, operator, value });
|
|
4761
4747
|
}
|
|
@@ -4858,7 +4844,8 @@ class CrudService {
|
|
|
4858
4844
|
this.createDropdownOptions(schema));
|
|
4859
4845
|
}
|
|
4860
4846
|
promise.then(res => {
|
|
4861
|
-
let funcSetValueRow = (rowItem, data) => {
|
|
4847
|
+
let funcSetValueRow = (rowItem, data) => {
|
|
4848
|
+
};
|
|
4862
4849
|
if (schema.funcSetValueRow) {
|
|
4863
4850
|
funcSetValueRow = schema.funcSetValueRow;
|
|
4864
4851
|
}
|
|
@@ -5164,19 +5151,24 @@ class CrudService {
|
|
|
5164
5151
|
this._injector.get(NotifierService).showWarning('Có lỗi xảy ra. Liên hệ quản trị viên để biết thêm chi tiết.');
|
|
5165
5152
|
}
|
|
5166
5153
|
else {
|
|
5167
|
-
if (res.message != null && res.message != '')
|
|
5154
|
+
if (res.message != null && res.message != '') {
|
|
5168
5155
|
this._injector.get(NotifierService).showWarning(res.message);
|
|
5169
|
-
|
|
5156
|
+
}
|
|
5157
|
+
else {
|
|
5170
5158
|
this._injector.get(NotifierService).showWarning(res.error);
|
|
5159
|
+
}
|
|
5171
5160
|
}
|
|
5172
|
-
if (callBackError)
|
|
5161
|
+
if (callBackError) {
|
|
5173
5162
|
callBackError(res);
|
|
5163
|
+
}
|
|
5174
5164
|
return;
|
|
5175
5165
|
}
|
|
5176
|
-
if (message)
|
|
5166
|
+
if (message) {
|
|
5177
5167
|
this._injector.get(NotifierService).showSuccess(message);
|
|
5178
|
-
|
|
5168
|
+
}
|
|
5169
|
+
if (callBack) {
|
|
5179
5170
|
callBack(res);
|
|
5171
|
+
}
|
|
5180
5172
|
}
|
|
5181
5173
|
handleReponsePromise(res, messageSuccess) {
|
|
5182
5174
|
return new Promise((resolve, reject) => {
|
|
@@ -5214,8 +5206,8 @@ class CrudService {
|
|
|
5214
5206
|
}
|
|
5215
5207
|
deQuyReplaceValue(filters, filter, model, rootModel) {
|
|
5216
5208
|
let valueFilter = null;
|
|
5217
|
-
|
|
5218
|
-
|
|
5209
|
+
const sourceField = filter.sourceField;
|
|
5210
|
+
const subField = filter.subField;
|
|
5219
5211
|
const canAccessSubField = (value) => {
|
|
5220
5212
|
return subField != null
|
|
5221
5213
|
&& subField !== ''
|
|
@@ -5223,14 +5215,16 @@ class CrudService {
|
|
|
5223
5215
|
};
|
|
5224
5216
|
if (model.hasOwnProperty(sourceField)) {
|
|
5225
5217
|
valueFilter = model[sourceField];
|
|
5226
|
-
if (canAccessSubField(valueFilter))
|
|
5218
|
+
if (canAccessSubField(valueFilter)) {
|
|
5227
5219
|
valueFilter = valueFilter[subField];
|
|
5220
|
+
}
|
|
5228
5221
|
}
|
|
5229
5222
|
else if (rootModel) {
|
|
5230
5223
|
if (rootModel.hasOwnProperty(sourceField)) {
|
|
5231
5224
|
valueFilter = rootModel[sourceField];
|
|
5232
|
-
if (canAccessSubField(valueFilter))
|
|
5225
|
+
if (canAccessSubField(valueFilter)) {
|
|
5233
5226
|
valueFilter = valueFilter[subField];
|
|
5227
|
+
}
|
|
5234
5228
|
}
|
|
5235
5229
|
else {
|
|
5236
5230
|
const fields = sourceField.split('.');
|
|
@@ -5244,25 +5238,30 @@ class CrudService {
|
|
|
5244
5238
|
break;
|
|
5245
5239
|
}
|
|
5246
5240
|
}
|
|
5247
|
-
if (canAccessSubField(temp))
|
|
5241
|
+
if (canAccessSubField(temp)) {
|
|
5248
5242
|
valueFilter = temp[subField];
|
|
5243
|
+
}
|
|
5249
5244
|
}
|
|
5250
5245
|
}
|
|
5251
|
-
if (filter.logic == null && (valueFilter == null || valueFilter === '' || valueFilter.length == 0))
|
|
5246
|
+
if (filter.logic == null && (valueFilter == null || valueFilter === '' || valueFilter.length == 0)) {
|
|
5252
5247
|
return;
|
|
5248
|
+
}
|
|
5253
5249
|
const tmpFilter = new Filter(filter);
|
|
5254
5250
|
delete tmpFilter.sourceField;
|
|
5255
|
-
if (tmpFilter.funcGetValue)
|
|
5251
|
+
if (tmpFilter.funcGetValue) {
|
|
5256
5252
|
valueFilter = tmpFilter.funcGetValue(valueFilter);
|
|
5253
|
+
}
|
|
5257
5254
|
tmpFilter.value = JSON.stringify(valueFilter);
|
|
5258
5255
|
tmpFilter.filters = [];
|
|
5259
5256
|
if (filter.logic && filter.filters) {
|
|
5260
5257
|
filter.filters.forEach(f => this.deQuyReplaceValue(tmpFilter.filters, f, model, rootModel));
|
|
5261
|
-
if (tmpFilter.filters.length > 0)
|
|
5258
|
+
if (tmpFilter.filters.length > 0) {
|
|
5262
5259
|
filters.push(tmpFilter);
|
|
5260
|
+
}
|
|
5263
5261
|
}
|
|
5264
|
-
else
|
|
5262
|
+
else {
|
|
5265
5263
|
filters.push(tmpFilter);
|
|
5264
|
+
}
|
|
5266
5265
|
}
|
|
5267
5266
|
getWorkflowCoreStatusText(workflowCoreStatusValue) {
|
|
5268
5267
|
const item = DataSourceWorkflowCoreStatus.find(x => x.id == workflowCoreStatusValue);
|
|
@@ -5362,7 +5361,8 @@ class CrudService {
|
|
|
5362
5361
|
if (schema.funcGetLabel) {
|
|
5363
5362
|
funcGetLabel = schema.funcGetLabel;
|
|
5364
5363
|
}
|
|
5365
|
-
let funcSetValueRow = (rowItem, data) => {
|
|
5364
|
+
let funcSetValueRow = (rowItem, data) => {
|
|
5365
|
+
};
|
|
5366
5366
|
let funcGetRefDataRow = (refItems) => {
|
|
5367
5367
|
return refItems.map(item => funcGetLabel(item)).join(`${schema.separator} `);
|
|
5368
5368
|
};
|
|
@@ -5513,14 +5513,17 @@ class BaseService {
|
|
|
5513
5513
|
}
|
|
5514
5514
|
}
|
|
5515
5515
|
});
|
|
5516
|
-
if (apiUrl.indexOf('?') == -1)
|
|
5516
|
+
if (apiUrl.indexOf('?') == -1) {
|
|
5517
5517
|
apiUrl += `?`;
|
|
5518
|
-
|
|
5518
|
+
}
|
|
5519
|
+
else {
|
|
5519
5520
|
apiUrl += `&`;
|
|
5521
|
+
}
|
|
5520
5522
|
apiUrl += `_keySignalr=${topic}`;
|
|
5521
5523
|
this._http.get(apiUrl)
|
|
5522
5524
|
.pipe(shareReplay(this.REPLAY_COUNT), retry(this.RETRY_COUNT), catchError((err) => this.handleError(err, this._injector))).toPromise()
|
|
5523
|
-
.then(res => {
|
|
5525
|
+
.then(res => {
|
|
5526
|
+
})
|
|
5524
5527
|
.catch(err => {
|
|
5525
5528
|
this.unSubscribeSignalR(topic);
|
|
5526
5529
|
reject(err);
|
|
@@ -5541,14 +5544,17 @@ class BaseService {
|
|
|
5541
5544
|
}
|
|
5542
5545
|
}
|
|
5543
5546
|
});
|
|
5544
|
-
if (apiUrl.indexOf('?') == -1)
|
|
5547
|
+
if (apiUrl.indexOf('?') == -1) {
|
|
5545
5548
|
apiUrl += `?`;
|
|
5546
|
-
|
|
5549
|
+
}
|
|
5550
|
+
else {
|
|
5547
5551
|
apiUrl += `&`;
|
|
5552
|
+
}
|
|
5548
5553
|
apiUrl += `_keySignalr=${topic}`;
|
|
5549
5554
|
this._http.post(apiUrl, data)
|
|
5550
5555
|
.pipe(shareReplay(this.REPLAY_COUNT), retry(this.RETRY_COUNT), catchError((err) => this.handleError(err, this._injector))).toPromise()
|
|
5551
|
-
.then(res => {
|
|
5556
|
+
.then(res => {
|
|
5557
|
+
})
|
|
5552
5558
|
.catch(err => {
|
|
5553
5559
|
this.unSubscribeSignalR(topic);
|
|
5554
5560
|
reject(err);
|
|
@@ -5801,8 +5807,12 @@ class BaseService {
|
|
|
5801
5807
|
const url = `${this.serviceUri}/${id}`;
|
|
5802
5808
|
return this.defaultGet(url);
|
|
5803
5809
|
}
|
|
5804
|
-
getDetailWithPermission(id) {
|
|
5805
|
-
const url = `${this.serviceUri}/DetailWithPermission/${id}`;
|
|
5810
|
+
getDetailWithPermission(id, pid = null) {
|
|
5811
|
+
const url = `${this.serviceUri}/DetailWithPermission/${id}?pid=${pid}`;
|
|
5812
|
+
return this.defaultGet(url);
|
|
5813
|
+
}
|
|
5814
|
+
getDetailByPid(pid) {
|
|
5815
|
+
const url = `${this.serviceUri}/DetailWithByPid/${pid}`;
|
|
5806
5816
|
return this.defaultGet(url);
|
|
5807
5817
|
}
|
|
5808
5818
|
getByInstanceId(instanceId) {
|
|
@@ -5855,6 +5865,10 @@ class BaseService {
|
|
|
5855
5865
|
const url = `${this.serviceUri}/${id}`;
|
|
5856
5866
|
return this._http.delete(url).toPromise();
|
|
5857
5867
|
}
|
|
5868
|
+
deleteById(id) {
|
|
5869
|
+
const url = `${this.serviceUri}/${id}`;
|
|
5870
|
+
return this._http.delete(url).pipe(catchError((err) => this.handleError(err, this._injector))).toPromise();
|
|
5871
|
+
}
|
|
5858
5872
|
deleteMany(lstId) {
|
|
5859
5873
|
const url = `${this.serviceUri}/DeleteManyAsync/${lstId}`;
|
|
5860
5874
|
return this._http.delete(url).toPromise();
|
|
@@ -6028,6 +6042,16 @@ class BaseService {
|
|
|
6028
6042
|
choYKien(itemWorkflowHistory) {
|
|
6029
6043
|
return this.defaultPost(`${this.serviceUri}/ChoYKienBase`, itemWorkflowHistory);
|
|
6030
6044
|
}
|
|
6045
|
+
getSharedKey(ids) {
|
|
6046
|
+
return this.defaultPost(`${this.serviceUri}/GetSharedKeyItemBase`, {
|
|
6047
|
+
listGuidValue: ids
|
|
6048
|
+
});
|
|
6049
|
+
}
|
|
6050
|
+
deleteLinkSharing(ids) {
|
|
6051
|
+
return this.defaultPost(`${this.serviceUri}/DeleteLinkSharing`, {
|
|
6052
|
+
listGuidValue: ids
|
|
6053
|
+
});
|
|
6054
|
+
}
|
|
6031
6055
|
rollback(rowData, lstObjectName) {
|
|
6032
6056
|
return this.defaultPost(`${this.serviceUri}/RollbackBase/${rowData.__workflowCode}/${rowData.id}`, {
|
|
6033
6057
|
ListStringValue: lstObjectName
|
|
@@ -7835,6 +7859,12 @@ class UserService extends BaseService {
|
|
|
7835
7859
|
});
|
|
7836
7860
|
}
|
|
7837
7861
|
}
|
|
7862
|
+
/**
|
|
7863
|
+
* Hàm dùng để lấy thông tin cơ bản nhiều người dùng dựa vào userName,
|
|
7864
|
+
* hiện tại chưa có thông tin về đơn vị và chức vụ người dùng để giảm load và vì chưa dùng đến
|
|
7865
|
+
* @param {string} userName
|
|
7866
|
+
* @return {Promise<BasicUserInfo[]>
|
|
7867
|
+
*/
|
|
7838
7868
|
getBasicUserInfoByUserName(userName) {
|
|
7839
7869
|
const storageItem = localStorage.getItem(this.USER_INFO_KEY + '_' + userName);
|
|
7840
7870
|
const user = JSON.parse(storageItem);
|
|
@@ -7863,23 +7893,31 @@ class UserService extends BaseService {
|
|
|
7863
7893
|
}));
|
|
7864
7894
|
}
|
|
7865
7895
|
}
|
|
7866
|
-
|
|
7867
|
-
|
|
7868
|
-
|
|
7869
|
-
|
|
7870
|
-
|
|
7871
|
-
|
|
7872
|
-
|
|
7873
|
-
|
|
7874
|
-
|
|
7875
|
-
|
|
7876
|
-
|
|
7877
|
-
|
|
7878
|
-
|
|
7879
|
-
|
|
7880
|
-
|
|
7881
|
-
|
|
7882
|
-
|
|
7896
|
+
/**
|
|
7897
|
+
* Hàm dùng để lấy thông tin cơ bản nhiều người dùng dựa vào userName,
|
|
7898
|
+
* hiện tại chưa có thông tin về đơn vị và chức vụ người dùng để giảm load và vì chưa dùng đến
|
|
7899
|
+
* @param {string} userNames
|
|
7900
|
+
* @return {Promise<BasicUserInfo[]>
|
|
7901
|
+
*/
|
|
7902
|
+
getBasicUsersInfoByUserNames(userNames) {
|
|
7903
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
7904
|
+
const storageItem = localStorage.getItem(this.USER_INFO_KEY);
|
|
7905
|
+
const userInfos = JSON.parse(storageItem);
|
|
7906
|
+
const check = userInfos ? userNames.indexOf(userInfos['userName']) > -1 : null;
|
|
7907
|
+
if (check) {
|
|
7908
|
+
return userInfos;
|
|
7909
|
+
}
|
|
7910
|
+
else {
|
|
7911
|
+
const svUrl = `${this.serviceUri}/GetBasicUsersInfoByUserNames?userNames=${userNames}`;
|
|
7912
|
+
return yield this._http.get(svUrl).pipe(shareReplay(this.REPLAY_COUNT), retry(this.RETRY_COUNT), catchError((err) => this.handleError(err, this._injector)), map(repsonse => {
|
|
7913
|
+
localStorage.setItem(this.USER_INFO_KEY + '_' + repsonse.data.map(x => {
|
|
7914
|
+
if (x.userName)
|
|
7915
|
+
return x.userName;
|
|
7916
|
+
}), JSON.stringify(repsonse.data));
|
|
7917
|
+
return repsonse.data;
|
|
7918
|
+
})).toPromise().catch(err => []);
|
|
7919
|
+
}
|
|
7920
|
+
});
|
|
7883
7921
|
}
|
|
7884
7922
|
convertListUserIdToString(userIds) {
|
|
7885
7923
|
if (userIds.length > 0) {
|
|
@@ -7887,14 +7925,14 @@ class UserService extends BaseService {
|
|
|
7887
7925
|
}
|
|
7888
7926
|
return ',';
|
|
7889
7927
|
}
|
|
7890
|
-
fillBasicUserInfo(dataSource, propertyName
|
|
7928
|
+
fillBasicUserInfo(dataSource, propertyName) {
|
|
7891
7929
|
dataSource.forEach(item => {
|
|
7892
7930
|
const userId = item[propertyName].id ? item[propertyName].id : item[propertyName];
|
|
7893
7931
|
// tslint:disable-next-line:no-shadowed-variable
|
|
7894
|
-
const user = users.find(user => user.id === userId);
|
|
7895
|
-
if (user) {
|
|
7896
|
-
|
|
7897
|
-
}
|
|
7932
|
+
// const user = users.find(user => user.id === userId);
|
|
7933
|
+
// if (user) {
|
|
7934
|
+
// item[propertyName] = user;
|
|
7935
|
+
// }
|
|
7898
7936
|
});
|
|
7899
7937
|
return dataSource;
|
|
7900
7938
|
}
|
|
@@ -9306,23 +9344,38 @@ class TnCustomScrollbarComponent {
|
|
|
9306
9344
|
const divs = this.elementRef.getElementsByClassName('ps-content');
|
|
9307
9345
|
if (divs && divs.length > 0) {
|
|
9308
9346
|
const contentDiv = divs[0];
|
|
9309
|
-
const
|
|
9310
|
-
if (
|
|
9311
|
-
|
|
9312
|
-
|
|
9313
|
-
|
|
9347
|
+
const scrollYHolder = this.findNext(contentDiv, 'ps__rail-y');
|
|
9348
|
+
if (scrollYHolder) {
|
|
9349
|
+
const scrollYs = scrollYHolder.getElementsByClassName('ps__thumb-y');
|
|
9350
|
+
if (scrollYs && scrollYs.length > 0) {
|
|
9351
|
+
setTimeout(() => {
|
|
9352
|
+
this.checkScrollBar(contentDiv, scrollYs[0]);
|
|
9353
|
+
}, this._intervalTime);
|
|
9354
|
+
}
|
|
9314
9355
|
}
|
|
9315
9356
|
}
|
|
9316
9357
|
}
|
|
9358
|
+
findNext(curentNode, className) {
|
|
9359
|
+
let nextSibling = curentNode.nextSibling;
|
|
9360
|
+
while (nextSibling) {
|
|
9361
|
+
if (nextSibling.classList && nextSibling.classList.contains(className)) {
|
|
9362
|
+
return nextSibling;
|
|
9363
|
+
}
|
|
9364
|
+
nextSibling = nextSibling.nextSibling;
|
|
9365
|
+
}
|
|
9366
|
+
return null;
|
|
9367
|
+
}
|
|
9317
9368
|
checkScrollBar(contentDiv, scrollY) {
|
|
9318
9369
|
try {
|
|
9319
9370
|
const contentHeight = contentDiv.clientHeight;
|
|
9320
9371
|
const holderHeight = contentDiv.parentElement.clientHeight;
|
|
9321
|
-
if (holderHeight
|
|
9322
|
-
|
|
9323
|
-
|
|
9324
|
-
|
|
9325
|
-
|
|
9372
|
+
if (holderHeight > 0) {
|
|
9373
|
+
if (holderHeight >= contentHeight) {
|
|
9374
|
+
scrollY.style.display = 'none';
|
|
9375
|
+
}
|
|
9376
|
+
else {
|
|
9377
|
+
scrollY.style.display = '';
|
|
9378
|
+
}
|
|
9326
9379
|
}
|
|
9327
9380
|
if (this._checkScrollBar) {
|
|
9328
9381
|
setTimeout(() => {
|
|
@@ -14206,7 +14259,7 @@ class DataFormBase extends ComponentBase {
|
|
|
14206
14259
|
}
|
|
14207
14260
|
getObjectDetail() {
|
|
14208
14261
|
return __awaiter(this, void 0, void 0, function* () {
|
|
14209
|
-
return yield this.setting.baseService.getDetailWithPermission(this.model.data.id);
|
|
14262
|
+
return yield this.setting.baseService.getDetailWithPermission(this.model.data.id, this.model.data.pid);
|
|
14210
14263
|
});
|
|
14211
14264
|
}
|
|
14212
14265
|
getDetailCustom() {
|
|
@@ -14293,7 +14346,7 @@ class DataFormBase extends ComponentBase {
|
|
|
14293
14346
|
this.model.data = data;
|
|
14294
14347
|
this.checkPermission(data.basePermission);
|
|
14295
14348
|
if (this.crudForm) {
|
|
14296
|
-
this.crudForm.switchViewMode(
|
|
14349
|
+
this.crudForm.switchViewMode(this.__isFormView);
|
|
14297
14350
|
this.crudForm.data = data;
|
|
14298
14351
|
this.crudForm.setIsLoadedDataEdit(true);
|
|
14299
14352
|
}
|
|
@@ -15851,6 +15904,7 @@ class CrudListComponent extends ComponentBase {
|
|
|
15851
15904
|
this.escape = true;
|
|
15852
15905
|
this.config = new CrudListConfig();
|
|
15853
15906
|
this.enableReorderRow = false;
|
|
15907
|
+
this.disableShare = false;
|
|
15854
15908
|
this.fieldOrder = '_index';
|
|
15855
15909
|
this._style = {};
|
|
15856
15910
|
this._dataSource = [];
|
|
@@ -15928,6 +15982,10 @@ class CrudListComponent extends ComponentBase {
|
|
|
15928
15982
|
this.workflowHistoryModel = new DialogModel({
|
|
15929
15983
|
header: 'Xem lịch sử'
|
|
15930
15984
|
});
|
|
15985
|
+
this.permissionSharingModel = new DialogModel({
|
|
15986
|
+
header: 'Xem danh sách link chia sẻ',
|
|
15987
|
+
popupSize: new PopupSize({ width: 1100, height: 650 }),
|
|
15988
|
+
});
|
|
15931
15989
|
this.congViecModel = new DialogModel({
|
|
15932
15990
|
header: 'Chạy quy trình công việc',
|
|
15933
15991
|
popupSize: new PopupSize({ width: 1100, height: 650 }),
|
|
@@ -16175,8 +16233,10 @@ class CrudListComponent extends ComponentBase {
|
|
|
16175
16233
|
}
|
|
16176
16234
|
this.initColumnSchema(this.setting.cols);
|
|
16177
16235
|
this.createSearchSchema();
|
|
16178
|
-
if (!this.setting.hiddenTrinhKy
|
|
16179
|
-
this.menuButtons
|
|
16236
|
+
if (!this.setting.hiddenTrinhKy || !this.disableShare) {
|
|
16237
|
+
if (!this.menuButtons) {
|
|
16238
|
+
this.menuButtons = () => [];
|
|
16239
|
+
}
|
|
16180
16240
|
}
|
|
16181
16241
|
// Nếu mà ẩn advancesearch => sẽ không có trigger load data từ advance search => phải tự gọi getData ở OnInit
|
|
16182
16242
|
if (this.setting.hiddenAdvanceSearch) {
|
|
@@ -17207,6 +17267,43 @@ class CrudListComponent extends ComponentBase {
|
|
|
17207
17267
|
.catch(err => this.hideWaitBox());
|
|
17208
17268
|
}
|
|
17209
17269
|
}
|
|
17270
|
+
createShareLink() {
|
|
17271
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
17272
|
+
const rowData = this.rowDataCurrent;
|
|
17273
|
+
const dicPermissionId = (yield this.setting.baseService.getSharedKey([rowData.id])).data;
|
|
17274
|
+
if (!dicPermissionId) {
|
|
17275
|
+
this._notifierService.showWarning('Bạn không có quyền chia sẻ bản ghi');
|
|
17276
|
+
}
|
|
17277
|
+
const dicState = yield this.setting.getItemState([rowData]);
|
|
17278
|
+
const shareLink = this.generateShareLink(rowData.id, dicPermissionId[rowData.id], dicState[rowData.id]);
|
|
17279
|
+
this.copyToClipboard(shareLink);
|
|
17280
|
+
this._notifierService.showSuccess('Copy đường dẫn chia sẻ vào clipboard thành công');
|
|
17281
|
+
});
|
|
17282
|
+
}
|
|
17283
|
+
createShareLinkMultiple() {
|
|
17284
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
17285
|
+
const ids = this.model.selectedItems.map(q => q.id);
|
|
17286
|
+
const dicPermissionId = (yield this.setting.baseService.getSharedKey(ids)).data;
|
|
17287
|
+
if (!dicPermissionId) {
|
|
17288
|
+
this._notifierService.showWarning('Bạn không có quyền chia sẻ bản ghi');
|
|
17289
|
+
}
|
|
17290
|
+
const dicState = yield this.setting.getItemState(this.model.selectedItems);
|
|
17291
|
+
let content = '';
|
|
17292
|
+
ids.forEach(id => {
|
|
17293
|
+
content += `${this.generateShareLink(id, dicPermissionId[id], dicState[id])}\n`;
|
|
17294
|
+
});
|
|
17295
|
+
this.copyToClipboard(content);
|
|
17296
|
+
this._notifierService.showSuccess('Copy đường dẫn chia sẻ vào clipboard thành công');
|
|
17297
|
+
});
|
|
17298
|
+
}
|
|
17299
|
+
generateShareLink(id, pid, state) {
|
|
17300
|
+
let result = `${top.location.origin}${top.location.pathname}?pid=${pid}`;
|
|
17301
|
+
result += `serviceCode=${this.setting.baseService.serviceCode}`;
|
|
17302
|
+
result += `&entity=${this.setting.baseService.entityName}`;
|
|
17303
|
+
result += `&entityKey=${id}`;
|
|
17304
|
+
result += `&state=${encodeURIComponent(JSON.stringify(state))}`;
|
|
17305
|
+
return result;
|
|
17306
|
+
}
|
|
17210
17307
|
checkHasPermissionInLastStatus(rowData) {
|
|
17211
17308
|
return __awaiter(this, void 0, void 0, function* () {
|
|
17212
17309
|
const statusKetThuc = this.setting.workflowSetting.statuses.find(q => q.type == EnumWFNhomTrangThai.KET_THUC);
|
|
@@ -17233,6 +17330,9 @@ class CrudListComponent extends ComponentBase {
|
|
|
17233
17330
|
this.buttonContexts.unshift({ label: this.setting.getLabelButtonTrinhKy(rowData), icon: 'pi pi-send', command: this.trinhKy.bind(this) });
|
|
17234
17331
|
}
|
|
17235
17332
|
}
|
|
17333
|
+
if (!this.disableShare) {
|
|
17334
|
+
this.buttonContexts.push({ label: 'Chia sẻ', icon: 'pi pi-link', command: this.createShareLink.bind(this) }, { label: 'Danh sách chia sẻ', icon: 'pi pi-list', command: this.showLinkSharing.bind(this) });
|
|
17335
|
+
}
|
|
17236
17336
|
if (this.buttonContexts.length > 0) {
|
|
17237
17337
|
this._showContextMenu(evt);
|
|
17238
17338
|
}
|
|
@@ -18288,6 +18388,9 @@ class CrudListComponent extends ComponentBase {
|
|
|
18288
18388
|
showSettingsWorkflowNew() {
|
|
18289
18389
|
this.workflowSettingModel.showEditForm = true;
|
|
18290
18390
|
}
|
|
18391
|
+
showLinkSharing() {
|
|
18392
|
+
this.permissionSharingModel.showEditForm = true;
|
|
18393
|
+
}
|
|
18291
18394
|
onSaveWorkflowSettings(event) {
|
|
18292
18395
|
this.setting.workflowSetting = event;
|
|
18293
18396
|
this._commonService.reloadPage();
|
|
@@ -18342,7 +18445,7 @@ CrudListComponent.decorators = [
|
|
|
18342
18445
|
{ type: Component, args: [{
|
|
18343
18446
|
// tslint:disable-next-line: component-selector
|
|
18344
18447
|
selector: 'crud-list',
|
|
18345
|
-
template: "<div #container class=\"custom-card card card-w-title flex-container-fit-child\" [attr.height-type]=\"setting.heightType\"\r\n [ngStyle]=\"_style\">\r\n <div class=\"ui-helper-clearfix crud-list-header-area\">\r\n <div *ngIf=\"searchCustom\" class=\"p-grid ui-fluid custom-p-col custom-search-area\">\r\n <div class=\"p-col-12 main-container-search\">\r\n <div class=\"p-grid main-container-search-inner\">\r\n <ng-container>\r\n <ng-container *ngTemplateOutlet=\"searchCustom; context: {$implicit: this}\"></ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n <div *ngIf=\"!setting.hiddenHeader\" class=\"p-grid ui-fluid custom-p-col page-title-area\">\r\n <div *ngIf=\"!setting.hiddenPageTitle\" class=\"main-title\">\r\n <h1 *ngIf=\"!hasTemplate('customTitle')\">\r\n {{setting.title != null ? setting.title : 'Danh s\u00E1ch ' + setting.objectName}}\r\n </h1>\r\n\r\n <ng-container *ngIf=\"hasTemplate('customTitle')\" [ngTemplateOutlet]=\"getTemplate('customTitle')\"\r\n [ngTemplateOutletContext]=\"{crudList: this}\">\r\n </ng-container>\r\n </div>\r\n\r\n <div *ngIf=\"!setting.hiddenPageSetting\" class=\"paginator-table\">\r\n <paging-next-back-only [model]=\"model\" [setting]=\"setting\" (onOldest)=\"onOldest($event)\"\r\n (onNext)=\"onNext($event)\" (onPrev)=\"onPrev($event)\" (onLatest)=\"onLatest($event)\"\r\n (onChangeLimitPage)=\"savePageSize()\">\r\n </paging-next-back-only>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"fit-content crud-list-body-area\">\r\n <div class=\"crud-list-body-area-inner\" style=\"overflow: unset;\">\r\n <div class=\"flex-container-fit-child\" style=\"overflow: unset;\">\r\n <div *ngIf=\"!setting.hiddenToolbar\" class=\"p-grid crudListToolbar\">\r\n <ng-container>\r\n <div *ngIf=\"!setting.hiddenButtons && hasTemplate('toolbar')\"\r\n [ngClass]=\"setting.hiddenAdvanceSearch ? 'p-md-12 p-lg-12' : 'p-md-7 p-lg-8'\"\r\n class=\"p-col-12 button-group function-topbar custom-toolbar\">\r\n <ng-container\r\n [ngTemplateOutletContext]=\"{selectedItems: model.selectedItems, crudList: this}\"\r\n [ngTemplateOutlet]=\"getTemplate('toolbar')\"></ng-container>\r\n </div>\r\n <div *ngIf=\"!setting.hiddenButtons && !hasTemplate('toolbar')\"\r\n [ngClass]=\"setting.hiddenAdvanceSearch ? 'p-md-12 p-lg-12' : 'p-md-7 p-lg-8'\"\r\n class=\"p-col-12 button-group function-topbar\">\r\n <button *ngIf=\"!hiddenAdd\" type=\"button\" pButton pRipple label=\"Th\u00EAm m\u1EDBi\" icon=\"pi pi-plus\"\r\n class=\"p-button-text\" [disabled]=\"!model.baseReady\" (click)=\"add()\"></button>\r\n <button *ngIf=\"setting.showExportSelectedItems && model.selectedItems.length > 0\"\r\n type=\"button\" pButton pRipple\r\n label=\"Xu\u1EA5t c\u00E1c m\u1EE5c \u0111\u00E3 ch\u1ECDn ({{model.selectedItems.length}})\" icon=\"fas fa-file-excel\"\r\n class=\"p-button-text p-button-success\" (click)=\"xuatCacMucDaChon()\"></button>\r\n <button *ngIf=\"!hiddenDelete && model.selectedItems.length > 0 && !disableMultipleDelete()\"\r\n type=\"button\" pButton pRipple\r\n label=\"{{ 'X\u00F3a' | translate }} ({{model.selectedItems.length}})\" icon=\"pi pi-trash\"\r\n class=\"p-button-text p-button-danger\" (click)=\"deleteMutiple()\"></button>\r\n <button\r\n *ngIf=\"!hiddenCopyLink && model.selectedItems.length > 0 && !disableMultipleCopyLink()\"\r\n label=\"Sao ch\u00E9p li\u00EAn k\u1EBFt\" type=\"button\" pButton pRipple\r\n pTooltip=\"{{'Sao ch\u00E9p li\u00EAn k\u1EBFt' | translate}}\" tooltipPosition=\"top\"\r\n class=\"p-button-rounded p-button-text p-button-info link-or-action\" icon=\"pi pi-link\"\r\n (click)=\"copyLinkMultiple()\"></button>\r\n <ng-container [ngTemplateOutlet]=\"getTemplate('buttonAfterToolbar')\"\r\n [ngTemplateOutletContext]=\"{crudList: this}\"></ng-container>\r\n </div>\r\n </ng-container>\r\n <div *ngIf=\"!setting.hiddenAdvanceSearch\" class=\"p-col-12 advance-search-container\"\r\n [ngClass]=\"setting.hiddenButtons ? 'p-md-12 p-lg-12' : 'p-md-5 p-lg-4'\">\r\n <advance-search #advanceSearch [parentSetting]=\"setting\" [searchInfo]=\"searchInfo\"\r\n [loading]=\"model.loading\" (onSearch)=\"handleSearchAdvs($event)\"\r\n (onInit)=\"handleInitAdvanceSearch($event)\">\r\n </advance-search>\r\n </div>\r\n </div>\r\n <div *ngIf=\"hasTemplate('topGrid')\" class=\"extend-content-top-grid\">\r\n <ng-container [ngTemplateOutletContext]=\"{selectedItems: model.selectedItems, crudList: this}\"\r\n [ngTemplateOutlet]=\"getTemplate('topGrid')\"></ng-container>\r\n </div>\r\n <div class=\"container-table fit-content\" [class.--table-responsive]=\"responsive\">\r\n <div class=\"container-table-inner\">\r\n <ng-container *ngIf=\"!_groupField\">\r\n <tn-custom-scrollbar *ngIf=\"showScrollBar\" #scrollbar [config]=\"configScrollBar\"\r\n [showScrollHorizontal]=\"showScrollHorizontal\">\r\n <ng-container *ngTemplateOutlet=\"tableGetGroupFieldFalse\">\r\n </ng-container>\r\n <ng-container *ngIf=\"hasTemplate('afterCrudList')\">\r\n <ng-container [ngTemplateOutlet]=\"hasTemplate('afterCrudList')\"></ng-container>\r\n </ng-container>\r\n </tn-custom-scrollbar>\r\n <div *ngIf=\"!showScrollBar\">\r\n <ng-container *ngTemplateOutlet=\"tableGetGroupFieldFalse\">\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n <ng-container *ngIf=\"_groupField\">\r\n <tn-custom-scrollbar *ngIf=\"showScrollBar\" #scrollbar [config]=\"configScrollBar\"\r\n [showScrollHorizontal]=\"showScrollHorizontal\">\r\n <ng-container *ngTemplateOutlet=\"tableGetGroupFieldTrue\">\r\n </ng-container>\r\n <ng-container *ngIf=\"hasTemplate('afterCrudList')\">\r\n <ng-container [ngTemplateOutlet]=\"getTemplate('afterCrudList')\"></ng-container>\r\n </ng-container>\r\n </tn-custom-scrollbar>\r\n <div *ngIf=\"!showScrollBar\">\r\n <ng-container *ngTemplateOutlet=\"tableGetGroupFieldTrue\">\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n\r\n <div class=\"table-border-line --top\"></div>\r\n <div class=\"table-border-line --right\"></div>\r\n <div class=\"table-border-line --bottom\"></div>\r\n <div class=\"table-border-line --left\"></div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n<after-view-checked (loaded)=\"handleReady()\"></after-view-checked>\r\n<settings *ngIf=\"_showSettings && !setting.hiddenSetting\" [entityMetadataService]=\"entityMetadataService\"\r\n [parentContext]=\"context\" [parentSetting]=\"setting\" [parentModel]=\"model\" (onSave)=\"onSaveSettings($event)\"\r\n (onCancel)=\"_showSettings = false\">\r\n</settings>\r\n<settings-row *ngIf=\"_showSettingsRowColor && !setting.hiddenSetting\" [entityMetadataService]=\"entityMetadataService\"\r\n [parentContext]=\"context\" [parentSetting]=\"setting\" [parentModel]=\"model\" (onSave)=\"onSaveColorSettings($event)\"\r\n (onCancel)=\"_showSettingsRowColor = false\">\r\n</settings-row>\r\n<workflow-setting-dialog *ngIf=\"_showSettingsWorkflow && !setting.hiddenSettingWorkflow\" [parentSetting]=\"setting\"\r\n [parentContext]=\"context\" [parentModel]=\"model\" (onSaved)=\"onSaveWorkflowSettings($event)\"\r\n (onRemoved)=\"onRemoveWorkflowSettings($event)\" (onCancel)=\"_showSettingsWorkflow = false\"></workflow-setting-dialog>\r\n<tn-dialog *ngIf=\"workflowSettingModel.showEditForm\" [header]=\"'C\u1EA5u h\u00ECnh quy tr\u00ECnh nghi\u1EC7p v\u1EE5' | translate\"\r\n [popupSize]=\"workflowSettingModel.popupSize\" (onHide)=\"workflowSettingModel.showEditForm = false\">\r\n <workflow-setting-new #formBase [parentSetting]=\"setting\" (onSaved)=\"onSaveWorkflowSettingsNew($event)\"\r\n (onCancel)=\"workflowSettingModel.showEditForm = false\"></workflow-setting-new>\r\n</tn-dialog>\r\n<entity-permission *ngIf=\"_showSettingsPermission && !setting.hiddenSettingPermission\" [parentSetting]=\"setting\"\r\n [parentContext]=\"context\" [parentModel]=\"model\" [searchInfo]=\"searchInfo\"\r\n (onCancel)=\"_showSettingsPermission = false\">\r\n</entity-permission>\r\n<p-contextMenu #contextMenu [appendTo]=\"'body'\" [model]=\"buttonContexts\">\r\n</p-contextMenu>\r\n<tn-dialog *ngIf=\"showFormWorkflow\" #dialog [header]=\"headerWorkflow | translate\" [popupSize]=\"popupSizeWorkflow\"\r\n [scrollBarStyleClass]=\"'fit-content'\" (onHide)=\"showFormWorkflow = false\">\r\n <div style=\"height: 100%\">\r\n <simple-workflow-form #formBase [baseService]=\"setting.baseService\" [item]=\"currentItem\"\r\n [action]=\"actionWorkflow\" (onInvalidWorkflow)=\"handleInvalidWF($event)\" (onSaved)=\"handleProcessedWorflow()\"\r\n (onCancel)=\"showFormWorkflow = false\">\r\n </simple-workflow-form>\r\n </div>\r\n</tn-dialog>\r\n<tn-dialog *ngIf=\"processWorkflowModel.showEditForm\" #dialog [header]=\"processWorkflowModel.header | translate\"\r\n [popupSize]=\"processWorkflowModel.popupSize\" [scrollBarStyleClass]=\"'fit-content'\"\r\n (onHide)=\"processWorkflowModel.showEditForm = false\">\r\n <div style=\"height: 100%\">\r\n <process-workflow-form #formBase [businessSetting]=\"setting\" [item]=\"currentItem\"\r\n [workflow]=\"processWorkflowModel.data.workflow\" [action]=\"processWorkflowModel.data.action\"\r\n (onSaved)=\"handleProcessedWorkflowBase()\" (onCancel)=\"processWorkflowModel.showEditForm = false\">\r\n </process-workflow-form>\r\n </div>\r\n</tn-dialog>\r\n<tn-dialog *ngIf=\"choYKienModel.showEditForm\" #dialog [header]=\"choYKienModel.header | translate\"\r\n [popupSize]=\"choYKienModel.popupSize\" [scrollBarStyleClass]=\"'fit-content'\"\r\n (onHide)=\"choYKienModel.showEditForm = false\">\r\n <div style=\"height: 100%\">\r\n <cho-y-kien-form #formBase [bussinessSetting]=\"setting\" [rowItem]=\"choYKienModel.data.rowData\"\r\n (onSaved)=\"choYKienModel.showEditForm = false\" (onCancel)=\"choYKienModel.showEditForm = false\">\r\n </cho-y-kien-form>\r\n </div>\r\n</tn-dialog>\r\n<tn-dialog *ngIf=\"workflowHistoryModel.showEditForm\" #dialog [header]=\"workflowHistoryModel.header | translate\"\r\n [popupSize]=\"workflowHistoryModel.popupSize\" [scrollBarStyleClass]=\"'fit-content'\"\r\n (onHide)=\"workflowHistoryModel.showEditForm = false\">\r\n <div style=\"height: 100%\">\r\n <workflow-history-new #formBase [businessSetting]=\"setting\" [item]=\"currentItem\"\r\n [workflowSetting]=\"workflowHistoryModel.data.workflowSetting\"\r\n (onCancel)=\"workflowHistoryModel.showEditForm = false\">\r\n </workflow-history-new>\r\n </div>\r\n</tn-dialog>\r\n<workflow-history-dialog *ngIf=\"showHistoryWorkflow\" [baseService]=\"setting.baseService\" [item]=\"currentItem\"\r\n [workflowSetting]=\"setting.workflowSetting\" (onHide)=\"handleHideHistoryWorkflow()\">\r\n</workflow-history-dialog>\r\n<tn-dialog *ngIf=\"startWorkflowModel.showEditForm\" #dialog [header]=\"startWorkflowModel.header | translate\"\r\n [popupSize]=\"startWorkflowModel.popupSize\" [scrollBarStyleClass]=\"'fit-content'\"\r\n (onHide)=\"startWorkflowModel.showEditForm = false\">\r\n <div style=\"height: 100%\">\r\n <start-workflow #formBase [workflows]=\"startWorkflowModel.data.workflows\"\r\n [defaultWorkflow]=\"startWorkflowModel.data.defaultWorkflow\"\r\n (onCancel)=\"startWorkflowModel.showEditForm = false\" (onSaved)=\"handleStartWorkflowFromDialog($event)\">\r\n </start-workflow>\r\n </div>\r\n</tn-dialog>\r\n<tn-dialog *ngIf=\"congViecModel.showEditForm\" #dialog [styleClass]=\"'congviec-form tn-form-dialog'\"\r\n [header]=\"congViecModel.header | translate\" [popupSize]=\"congViecModel.popupSize\"\r\n (onHide)=\"congViecModel.showEditForm = false\">\r\n <base-congviec-form #formBase [parentSetting]=\"congViecModel.data.congViecSetting\"\r\n [model]=\"congViecModel.data.model\" (onSaved)=\"congViecModel.showEditForm = false;getData()\"\r\n (onCancel)=\"congViecModel.showEditForm = false\">\r\n </base-congviec-form>\r\n</tn-dialog>\r\n<ng-template #tableGetGroupFieldFalse>\r\n <p-table #table [dataKey]=\"'id'\" [scrollable]=\"pTableScrollable\" [scrollHeight]=\"pTableScrollHeight\"\r\n [columns]=\"setting.cols\" [paginator]=\"false\" [value]=\"_dataSource\" (onSort)=\"onSort($event, table)\"\r\n [class]=\"_tableClass\" [responsive]=\"responsive\" [lazy]=\"lazy\" [loading]=\"model.loading\"\r\n [(selection)]=\"model.selectedItems\" (onRowReorder)=\"handleRowOrdered($event)\">\r\n <ng-template *ngIf=\"header\" pTemplate=\"header\" let-columns>\r\n <ng-container\r\n *ngTemplateOutlet=\"header, context: {$implicit: columns, crudList: this, rowHeaderFilter: rowHeaderFilter, contentTh: contentTh, containerSticky: containerSticky, funcCheckAll: handleCheckAll}\">\r\n </ng-container>\r\n </ng-template>\r\n <ng-template *ngIf=\"!header\" pTemplate=\"header\" let-columns>\r\n <ng-container *ngTemplateOutlet=\"trHeader; context: {$implicit: columns, funcCheckAll: handleCheckAll}\">\r\n </ng-container>\r\n </ng-template>\r\n <ng-template pTemplate=\"body\" let-rowData let-columns=\"columns\" let-index=\"rowIndex\" let-expanded=\"expanded\">\r\n <ng-container\r\n *ngTemplateOutlet=\"trBody; context: {$implicit: rowData, columns: columns, index: index, expanded: expanded, eventSelectRow: handleSelectRow, eventChecked: handleCheckRowData}\">\r\n </ng-container>\r\n <after-view-checked *ngIf=\"index == _dataSource.length - 1\" style=\"display: none;\" [renderKey]=\"_dataSource\"\r\n (loaded)=\"handleTableRendered()\">\r\n </after-view-checked>\r\n </ng-template>\r\n <ng-template *ngIf=\"rowExpansion\" pTemplate=\"rowexpansion\" let-rowData let-expanded=\"expanded\">\r\n <ng-container\r\n *ngTemplateOutlet=\"rowExpansion; context: {rowData: rowData, expanded: expanded, getColSpanGroup: getColSpanGroup}\">\r\n </ng-container>\r\n </ng-template>\r\n <ng-template *ngIf=\"summary\" pTemplate=\"summary\">\r\n <ng-container *ngTemplateOutlet=\"summary\"></ng-container>\r\n </ng-template>\r\n <ng-template *ngIf=\"footer\" pTemplate=\"footer\" let-columns>\r\n <ng-container *ngTemplateOutlet=\"footer; context: {$implicit: columns}\"></ng-container>\r\n </ng-template>\r\n <ng-template *ngIf=\"colgroup\" pTemplate=\"colgroup\" let-columns>\r\n <ng-container *ngTemplateOutlet=\"colgroup; context: {$implicit: columns}\"></ng-container>\r\n </ng-template>\r\n </p-table>\r\n</ng-template>\r\n<ng-template #tableGetGroupFieldTrue>\r\n <p-table #tableGroup [scrollable]=\"pTableScrollable\" [scrollHeight]=\"pTableScrollHeight\" [columns]=\"setting.cols\"\r\n [paginator]=\"false\" [value]=\"_dataSource\" [metaKeySelection]=\"false\" (onSort)=\"onSort($event, tableGroup)\"\r\n [class]=\"_tableClass\" [customSort]=\"true\" [responsive]=\"responsive\" [lazy]=\"true\" [loading]=\"model.loading\"\r\n [(selection)]=\"model.selectedItems\" [expandedRowKeys]=\"model.expandedRowKeys\" [dataKey]=\"_groupField\">\r\n <ng-template *ngIf=\"header\" pTemplate=\"header\" let-columns>\r\n <ng-container\r\n *ngTemplateOutlet=\"header, context: {$implicit: columns, crudList: this, rowHeaderFilter: rowHeaderFilter, contentTh: contentTh, containerSticky: containerSticky, funcCheckAll: handleCheckAll_Group}\">\r\n </ng-container>\r\n </ng-template>\r\n <ng-template *ngIf=\"!header\" pTemplate=\"header\" let-columns>\r\n <ng-container\r\n *ngTemplateOutlet=\"trHeader; context: {$implicit: columns, funcCheckAll: handleCheckAll_Group}\">\r\n </ng-container>\r\n </ng-template>\r\n <ng-template pTemplate=\"body\" let-rowData let-rowIndex=\"rowIndex\" let-expanded=\"expanded\" let-columns=\"columns\">\r\n <tr *ngIf=\"rowGroupMetadata[rowData[_groupField]] && rowGroupMetadata[rowData[_groupField]].index == rowIndex\"\r\n class=\"p-widget-header group-row\" style=\"border: 0px; border-bottom: 1px solid #eee\">\r\n <td *ngIf=\"!setting.hiddenCheckbox\" class=\"center chkbox\" [class.sticky]=\"setting.stickyColumn\">\r\n <p-checkbox [(ngModel)]=\"rowGroupChecked[rowData[_groupField]]\" binary=\"true\"\r\n (onChange)=\"handleCheckRowGroup(rowData)\">\r\n </p-checkbox>\r\n <ng-container *ngTemplateOutlet=\"containerSticky\"></ng-container>\r\n </td>\r\n <ng-container *ngIf=\"!rowGroup\">\r\n <td [colSpan]=\"getColSpanGroup()\" [class]=\"_classRowGroup\">\r\n <div class=\"container-row-group\">\r\n <a href=\"javascript:;\" [pRowToggler]=\"rowData\" class=\"container-row-group-toggle\"\r\n [class.sticky]=\"setting.stickyColumn\">\r\n <i style=\"margin-right:5px\"\r\n [ngClass]=\"expanded ? 'fas fa-fw fa-caret-down' : 'fas fa-fw fa-caret-right'\"></i>\r\n <span class=\"content-row-group\">\r\n <ng-container *ngIf=\"!contentRowGroup\">\r\n <ng-container [ngTemplateOutlet]=\"_contentRowGroup\"\r\n [ngTemplateOutletContext]=\"getContextRowGroup(rowData)\">\r\n </ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"contentRowGroup\">\r\n <ng-container [ngTemplateOutlet]=\"contentRowGroup\"\r\n [ngTemplateOutletContext]=\"getContextRowGroup(rowData)\">\r\n </ng-container>\r\n </ng-container>\r\n </span>\r\n </a>\r\n </div>\r\n </td>\r\n </ng-container>\r\n <ng-container *ngIf=\"rowGroup\">\r\n <ng-container [ngTemplateOutlet]=\"rowGroup\"\r\n [ngTemplateOutletContext]=\"getContextRowGroupRoot(rowData, expanded)\">\r\n </ng-container>\r\n </ng-container>\r\n </tr>\r\n </ng-template>\r\n <ng-template pTemplate=\"rowexpansion\" let-columns=\"columns\" let-rowData let-index=\"rowIndex\">\r\n <ng-container\r\n *ngTemplateOutlet=\"trBody; context: {$implicit: rowData, columns: columns, index: index, expanded: false, eventSelectRow: handleSelectRowGroup, eventChecked: handleCheckRowData_Group}\">\r\n </ng-container>\r\n <after-view-checked *ngIf=\"index == _dataSource.length - 1\" style=\"display: none;\" [renderKey]=\"_dataSource\"\r\n (loaded)=\"handleTableRendered()\">\r\n </after-view-checked>\r\n </ng-template>\r\n <ng-template *ngIf=\"summary\" pTemplate=\"summary\">\r\n <ng-container *ngTemplateOutlet=\"summary\"></ng-container>\r\n </ng-template>\r\n <ng-template *ngIf=\"footer\" pTemplate=\"footer\" let-columns>\r\n <ng-container *ngTemplateOutlet=\"footer; context: {$implicit: columns}\"></ng-container>\r\n </ng-template>\r\n <ng-template *ngIf=\"colgroup\" pTemplate=\"colgroup\" let-columns>\r\n <ng-container *ngTemplateOutlet=\"colgroup; context: {$implicit: columns}\"></ng-container>\r\n </ng-template>\r\n </p-table>\r\n <after-view-checked></after-view-checked>\r\n</ng-template>\r\n<ng-template #trHeader let-columns let-funcCheckAll=\"funcCheckAll\">\r\n <tr class=\"title-row\">\r\n <ng-container *ngIf=\"!setting.hiddenCheckbox\">\r\n <th [style.width]=\"widthCheckbox\" class=\"chkbox link-or-action cell-checkbox\"\r\n [class.sticky]=\"setting.stickyColumn\">\r\n <button *ngIf=\"!hasTemplate('headerCheckbox')\" type=\"button\" pButton pRipple icon=\"pi pi-refresh\"\r\n class=\"p-button-rounded p-button-text btnReload\" pTooltip=\"L\u00E0m m\u1EDBi d\u1EEF li\u1EC7u\" tooltipPosition=\"top\"\r\n [disabled]=\"model.loading\" (click)=\"reload()\"></button>\r\n <ng-container *ngIf=\"hasTemplate('headerCheckbox')\">\r\n <ng-container [ngTemplateOutletContext]=\"{crudList: this}\"\r\n [ngTemplateOutlet]=\"getTemplate('headerCheckbox')\"></ng-container>\r\n </ng-container>\r\n <ng-container *ngTemplateOutlet=\"containerSticky\"></ng-container>\r\n </th>\r\n </ng-container>\r\n <th *ngIf=\"!setting.hiddenOrderColumn\" [style.width]=\"widthOrderColumn\" class=\"stt nopad center\"\r\n [class.sticky]=\"setting.stickyColumn\">\r\n {{ 'TT' |translate}}\r\n <ng-container *ngTemplateOutlet=\"containerSticky\"></ng-container>\r\n </th>\r\n <th *ngIf=\"rowExpansion\" class=\"nopad row-expansion-toggle center\" style=\"width: 2.5rem\"\r\n [class.sticky]=\"setting.stickyColumn\">\r\n <ng-container *ngTemplateOutlet=\"containerSticky\"></ng-container>\r\n </th>\r\n <ng-container *ngFor=\"let col of columns; let i = index\">\r\n <th *ngIf=\"col && col.visible && col.field!='function'\" [ngStyle]=\"col.extendData.headerStyle\"\r\n [pTooltip]=\"col.fullLabel\" tooltipStyleClass=\"unset-width\" [class]=\"col.extendData.headerClass\"\r\n [class.first-th]=\"i==0\" [escape]=\"false\" tooltipPosition=\"top\" [tnSortableColumn]=\"col.field\">\r\n <ng-container *ngTemplateOutlet=\"contentTh; context: {$implicit: col}\"></ng-container>\r\n <ng-container *ngIf=\"col.sort || col.sortClient\">\r\n <ng-container *ngTemplateOutlet=\"sortIcon; context: {field: col.field}\"></ng-container>\r\n </ng-container>\r\n </th>\r\n </ng-container>\r\n <th *ngIf=\"enableReorderRow\" style=\"width: 30px\">\r\n <ng-container *ngTemplateOutlet=\"containerSticky\"></ng-container>\r\n </th>\r\n <ng-container *ngTemplateOutlet=\"colFunctionHeader\"></ng-container>\r\n </tr>\r\n <ng-container *ngTemplateOutlet=\"rowHeaderFilter; context: {columns: columns, funcCheckAll: funcCheckAll}\">\r\n </ng-container>\r\n</ng-template>\r\n<ng-template #rowHeaderFilter let-columns=\"columns\" let-funcCheckAll=\"funcCheckAll\">\r\n <tr class=\"filter-row\" *ngIf=\"!setting.hiddenFilterRow\">\r\n <th *ngIf=\"!setting.hiddenCheckbox\" class=\"chkbox nopad center\" [class.sticky]=\"setting.stickyColumn\"\r\n [class.tricheckbox-custom-false]=\"checkedAll === false\" [style.width]=\"widthCheckbox\">\r\n <p-triStateCheckbox [(ngModel)]=\"checkedAll\" binary=\"true\" (onChange)=\"funcCheckAll()\">\r\n </p-triStateCheckbox>\r\n <ng-container *ngTemplateOutlet=\"containerSticky\"></ng-container>\r\n </th>\r\n <th *ngIf=\"!setting.hiddenOrderColumn\" class=\"stt center v-top\" [class.sticky]=\"setting.stickyColumn\">\r\n <div *ngIf=\"!setting.hiddenSetting\" class=\"pick-color-row\" pTooltip=\"C\u1EA5u h\u00ECnh hi\u1EC3n th\u1ECB m\u00E0u\"\r\n tooltipPosition=\"top\" (click)=\"showSettingRowColor()\">\r\n <div></div>\r\n <div></div>\r\n <div></div>\r\n <div></div>\r\n </div>\r\n <ng-container *ngTemplateOutlet=\"containerSticky\"></ng-container>\r\n </th>\r\n <th *ngIf=\"rowExpansion\" class=\"nopad center row-expansion-toggle\" [class.sticky]=\"setting.stickyColumn\">\r\n <ng-container *ngTemplateOutlet=\"containerSticky\"></ng-container>\r\n </th>\r\n <ng-container *ngFor=\"let col of columns; let i = index\">\r\n <th *ngIf=\"col.visible && col.field != 'function'\" class=\"cell-header-filter center\">\r\n <ng-container *ngIf=\"col.allowFilter\">\r\n <ng-container *ngIf=\"col.templateFilter\">\r\n <ng-container [ngTemplateOutlet]=\"col.templateFilter\"\r\n [ngTemplateOutletContext]=\"{col: col, filterData: filterData, onSearch: onSearch, onShowFilterDropdownPanel: onShowFilterDropdownPanel, onHideFilterDropdownPanel: onHideFilterDropdownPanel}\">\r\n </ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"!col.templateFilter\" [ngSwitch]=\"col.controlType\">\r\n <ng-container *ngSwitchCase=\"'dropdown'\">\r\n <ng-container [ngTemplateOutlet]=\"filterDropdown\"\r\n [ngTemplateOutletContext]=\"{col: col.rawColumn}\">\r\n </ng-container>\r\n </ng-container>\r\n <ng-container *ngSwitchCase=\"'number'\">\r\n <ng-container [ngTemplateOutlet]=\"filterNumber\" [ngTemplateOutletContext]=\"{col: col}\">\r\n </ng-container>\r\n </ng-container>\r\n <ng-container *ngSwitchCase=\"'date'\">\r\n <ng-container [ngTemplateOutlet]=\"filterDate\" [ngTemplateOutletContext]=\"{col: col}\">\r\n </ng-container>\r\n </ng-container>\r\n <ng-container *ngSwitchCase=\"'datetime'\">\r\n <ng-container [ngTemplateOutlet]=\"filterDate\" [ngTemplateOutletContext]=\"{col: col}\">\r\n </ng-container>\r\n </ng-container>\r\n <ng-container *ngSwitchDefault>\r\n <ng-container [ngSwitch]=\"col.dataType\">\r\n <ng-container *ngSwitchCase=\"'int'\">\r\n <ng-container [ngTemplateOutlet]=\"filterNumber\"\r\n [ngTemplateOutletContext]=\"{col: col}\">\r\n </ng-container>\r\n </ng-container>\r\n <ng-container *ngSwitchCase=\"'decimal'\">\r\n <ng-container [ngTemplateOutlet]=\"filterNumber\"\r\n [ngTemplateOutletContext]=\"{col: col}\">\r\n </ng-container>\r\n </ng-container>\r\n <ng-container *ngSwitchCase=\"'date'\">\r\n <ng-container [ngTemplateOutlet]=\"filterDate\"\r\n [ngTemplateOutletContext]=\"{col: col}\">\r\n </ng-container>\r\n </ng-container>\r\n <ng-container *ngSwitchCase=\"'datetime'\">\r\n <ng-container [ngTemplateOutlet]=\"filterDate\"\r\n [ngTemplateOutletContext]=\"{col: col}\">\r\n </ng-container>\r\n </ng-container>\r\n <ng-container *ngSwitchCase=\"'boolean'\">\r\n <ng-container [ngTemplateOutlet]=\"filterBoolean\"\r\n [ngTemplateOutletContext]=\"{col: col}\">\r\n </ng-container>\r\n </ng-container>\r\n <ng-container *ngSwitchDefault>\r\n <ng-container [ngTemplateOutlet]=\"filterText\"\r\n [ngTemplateOutletContext]=\"{col: col}\">\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n <ng-container *ngTemplateOutlet=\"containerSticky\"></ng-container>\r\n </th>\r\n </ng-container>\r\n <th *ngIf=\"enableReorderRow\" style=\"width: 30px\">\r\n <ng-container *ngTemplateOutlet=\"containerSticky\"></ng-container>\r\n </th>\r\n <th *ngIf=\"!setting.hiddenFunctionColumn\" class=\"center setting-cell column-function\"\r\n [class.sticky]=\"setting.stickyColumn\">\r\n <button *ngIf=\"!setting.hiddenSetting\" type=\"button\" pButton pRipple icon=\"pi pi-cog\"\r\n class=\"p-button-rounded p-button-text\" pTooltip=\"C\u1EA5u h\u00ECnh hi\u1EC3n th\u1ECB\" tooltipPosition=\"top\"\r\n (click)=\"showSettings()\"></button>\r\n <button *ngIf=\"!setting.hiddenSettingPermission\" type=\"button\" pButton pRipple icon=\"pi pi-users\"\r\n class=\"p-button-rounded p-button-text\" pTooltip=\"Ph\u00E2n quy\u1EC1n d\u1EEF li\u1EC7u\" tooltipPosition=\"left\"\r\n (click)=\"showSettingsPermission()\"></button>\r\n <button *ngIf=\"!setting.hiddenSettingWorkflow\" type=\"button\" pButton pRipple icon=\"pi pi-sitemap\"\r\n class=\"p-button-rounded p-button-text\" pTooltip=\"C\u1EA5u h\u00ECnh quy tr\u00ECnh\" tooltipPosition=\"left\"\r\n (click)=\"showSettingsWorkflow()\"></button>\r\n <button *ngIf=\"!setting.hiddenSettingWorkflowNew\" type=\"button\" pButton pRipple icon=\"pi pi-sitemap\"\r\n class=\"p-button-rounded p-button-text\" pTooltip=\"C\u1EA5u h\u00ECnh quy tr\u00ECnh\" tooltipPosition=\"left\"\r\n (click)=\"showSettingsWorkflowNew()\"></button>\r\n <ng-container *ngTemplateOutlet=\"containerSticky\"></ng-container>\r\n </th>\r\n </tr>\r\n</ng-template>\r\n<ng-template #colFunctionHeader>\r\n <ng-container *ngIf=\"!setting.hiddenFunctionColumn\">\r\n <th class=\"column-function\" [class.sticky]=\"setting.stickyColumn\"\r\n [style.width]=\"widthFunctionColumn || _widthFunctionColumn\">\r\n <div class=\"cell-header-function\">\r\n <span>{{'GRID.FUNCTION'| translate}}</span>\r\n </div>\r\n <ng-container *ngTemplateOutlet=\"containerSticky\"></ng-container>\r\n </th>\r\n </ng-container>\r\n</ng-template>\r\n<ng-template #contentTh let-col>\r\n <ng-container *ngIf=\"templateHeaderContent[col.field]\">\r\n <ng-container *ngTemplateOutlet=\"templateHeaderContent[col.field]\"></ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"!templateHeaderContent[col.field]\">\r\n {{col.label}}\r\n </ng-container>\r\n <ng-container *ngTemplateOutlet=\"containerSticky\"></ng-container>\r\n</ng-template>\r\n<ng-template #trBody let-rowData let-columns=\"columns\" let-index=\"index\" let-expanded=\"expanded\"\r\n let-eventSelectRow=\"eventSelectRow\" let-eventChecked=\"eventChecked\">\r\n <tr [tnReorderableRow]=\"index\" [attr.rowIndex]=\"index\"\r\n [ngClass]=\"mergeClassObj(rowData, { 'ui-state-highlight': rowData._checked })\" [pTooltip]=\"rowData.tooltip\"\r\n tooltipPosition=\"top\" [tooltipStyleClass]=\"rowData.tooltipClass\" [escape]=\"escape\"\r\n (click)=\"eventSelectRow($event, rowData)\">\r\n <ng-container *ngIf=\"!setting.hiddenCheckbox\">\r\n <td [style.width]=\"widthCheckbox\" class=\"chkbox link-or-action cell-checkbox\"\r\n [class.sticky]=\"setting.stickyColumn\">\r\n <ng-container *ngIf=\"!hasTemplate('checkbox')\">\r\n <p-checkbox [(ngModel)]=\"rowData._checked\" binary=\"true\" (onChange)=\"eventChecked(rowData)\">\r\n </p-checkbox>\r\n </ng-container>\r\n <ng-container *ngIf=\"hasTemplate('checkbox')\">\r\n <ng-container [ngTemplateOutlet]=\"getTemplate('checkbox')\"\r\n [ngTemplateOutletContext]=\"{rowData: rowData, rowIndex: index}\"></ng-container>\r\n </ng-container>\r\n <ng-container *ngTemplateOutlet=\"containerSticky\"></ng-container>\r\n </td>\r\n </ng-container>\r\n <td *ngIf=\"!setting.hiddenOrderColumn && (!rowData.hidden || !rowData.hidden[fieldOrder])\"\r\n [style.width]=\"widthOrderColumn\" class=\"stt\" style=\"text-align: center;\"\r\n [class.sticky]=\"setting.stickyColumn\" [attr.colSpan]=\"rowData.colSpan && rowData.colSpan[fieldOrder]\"\r\n [attr.rowSpan]=\"rowData.rowSpan && rowData.rowSpan[fieldOrder]\">\r\n <span class=\"row-card\" [ngStyle]=\"getBookmarkColor(rowData, columns)\"></span>\r\n {{rowData[fieldOrder]}}\r\n <ng-container *ngTemplateOutlet=\"containerSticky\"></ng-container>\r\n </td>\r\n <td *ngIf=\"rowExpansion\" class=\"no-padding center row-expansion-toggle\" [class.sticky]=\"setting.stickyColumn\">\r\n <ng-container *ngTemplateOutlet=\"iconToggleRowData; context: {rowData: rowData, expanded: expanded}\">\r\n </ng-container>\r\n <ng-container *ngTemplateOutlet=\"containerSticky\"></ng-container>\r\n </td>\r\n <ng-container\r\n *ngTemplateOutlet=\"dynamicColBodys; context: {$implicit: columns, rowData: rowData, index: index, expanded: expanded}\">\r\n </ng-container>\r\n <td *ngIf=\"enableReorderRow\" class=\"no-padding center\">\r\n <i class=\"fas fa-arrows-alt\" style=\"cursor:pointer; padding: 8px; color: #555;\" pReorderableRowHandle></i>\r\n <ng-container *ngTemplateOutlet=\"containerSticky\"></ng-container>\r\n </td>\r\n <ng-container *ngIf=\"!setting.hiddenFunctionColumn\">\r\n <td class=\"text-center column-function\" style=\"text-align: center;\" [class.sticky]=\"setting.stickyColumn\">\r\n <div *ngIf=\"hasTemplate('function')\" class=\"p-toolbar-group-center button-group\">\r\n <ng-container [ngTemplateOutlet]=\"getTemplate('function')\"\r\n [ngTemplateOutletContext]=\"{rowData: rowData, rowIndex: index}\"></ng-container>\r\n <ng-container *ngTemplateOutlet=\"containerSticky\"></ng-container>\r\n </div>\r\n <div *ngIf=\"!hasTemplate('function')\" class=\"p-toolbar-group-center button-group\">\r\n <ng-container [ngTemplateOutletContext]=\"{rowData: rowData, rowIndex: index}\"\r\n [ngTemplateOutlet]=\"getTemplate('buttonBefore')\"></ng-container>\r\n <button *ngIf=\"setting.showVersionButton\" type=\"button\" pButton pRipple icon=\"pi pi-calendar\"\r\n class=\"p-button-rounded p-button-success link-or-action\" pTooltip=\"Xem l\u1ECBch s\u1EED phi\u00EAn b\u1EA3n\"\r\n tooltipPosition=\"top\" (click)=\"showListVersion(rowData)\"></button>\r\n <button *ngIf=\"!rowData.hiddenEdit\" type=\"button\" pButton pRipple [disabled]=\"disableEdit(rowData)\"\r\n pTooltip=\"{{'FORM.EDIT' | translate}}\" tooltipPosition=\"top\"\r\n class=\"p-button-rounded p-button-text p-button-info link-or-action\" icon=\"pi pi-pencil\"\r\n (click)=\"edit(rowData)\"></button>\r\n <button *ngIf=\"!rowData.hiddenDelete\" type=\"button\" pButton pRipple\r\n [disabled]=\"disableDelete(rowData)\" pTooltip=\"{{'FORM.DELETE' | translate}}\"\r\n tooltipPosition=\"top\" class=\"p-button-rounded p-button-text p-button-danger link-or-action\"\r\n icon=\"pi pi-trash\" (click)=\"delete(rowData)\"></button>\r\n <button *ngIf=\"!rowData.hiddenCopyLink\" type=\"button\" pButton pRipple\r\n [disabled]=\"disableCopyLink(rowData)\" pTooltip=\"{{'Sao ch\u00E9p li\u00EAn k\u1EBFt' | translate}}\"\r\n tooltipPosition=\"top\" class=\"p-button-rounded p-button-text p-button-info link-or-action\"\r\n icon=\"pi pi-link\" (click)=\"copyLink(rowData)\"></button>\r\n <button *ngIf=\"this.menuButtons\" type=\"button\" pButton icon=\"pi pi-ellipsis-v\"\r\n class=\"link-or-action p-button-text p-button-info p-button-rounded\" pTooltip=\"Ch\u1EE9c n\u0103ng kh\u00E1c\"\r\n tooltipPosition=\"top\" (click)=\"showContextMenu($event, rowData)\"></button>\r\n </div>\r\n <ng-container *ngTemplateOutlet=\"containerSticky\"></ng-container>\r\n </td>\r\n </ng-container>\r\n </tr>\r\n</ng-template>\r\n<ng-template #dynamicColBodys let-columns let-rowData=\"rowData\" let-index=\"index\" let-expanded=\"expanded\">\r\n <ng-container *ngFor=\"let col of columns; let i = index\">\r\n <ng-container\r\n *ngTemplateOutlet=\"contentTd; context: {$implicit: rowData, col: col, index: index, i: i, expanded: expanded}\">\r\n </ng-container>\r\n </ng-container>\r\n</ng-template>\r\n<ng-template #contentTd let-rowData let-col=\"col\" let-index=\"index\" let-expanded=\"expanded\" let-i=\"i\">\r\n <td *ngIf=\"col && col.visible && col.field != 'function' && (!rowData.hidden || !rowData.hidden[col.field])\"\r\n [attr.colSpan]=\"rowData.colSpan && rowData.colSpan[col.field]\"\r\n [attr.rowSpan]=\"rowData.rowSpan && rowData.rowSpan[col.field]\" [ngStyle]=\"col.extendData.style\"\r\n [class]=\"col.cellClass\" [class.first-td]=\"i == 0\">\r\n <span *ngIf=\"col.pipe\">\r\n <span class=\"p-column-title\" [pTooltip]=\"col.fullLabel\" [escape]=\"false\"\r\n tooltipPosition=\"top\">{{col.label}}</span>\r\n {{rowData['pipe__' + col.field]}}\r\n </span>\r\n <span *ngIf=\"!col.pipe\">\r\n <span class=\"p-column-title\" [pTooltip]=\"col.fullLabel\" [escape]=\"false\"\r\n tooltipPosition=\"top\">{{col.label}}</span>\r\n <span *ngIf=\"setting.showEditLink && col.showEditLink\" [pTooltip]=\"config.tooltipView\" tooltipPosition=\"top\"\r\n class=\"link-or-action\">\r\n <a href=\"javascript:;\" (click)=\"view(rowData)\" [pTooltip]=\"config.tooltipView\" tooltipPosition=\"top\">\r\n <ng-container [ngTemplateOutlet]=\"contentCell\"\r\n [ngTemplateOutletContext]=\"getContextCell(rowData, index, col, expanded, this)\">\r\n </ng-container>\r\n </a>\r\n </span>\r\n <span *ngIf=\"!setting.showEditLink || !col.showEditLink\">\r\n <ng-container [ngTemplateOutlet]=\"contentCell\"\r\n [ngTemplateOutletContext]=\"getContextCell(rowData, index, col, expanded, this)\">\r\n </ng-container>\r\n </span>\r\n </span>\r\n <ng-container *ngTemplateOutlet=\"containerSticky\"></ng-container>\r\n </td>\r\n</ng-template>\r\n<ng-template #contentCell let-col=\"col\" let-rowData=\"rowData\" let-rowIndex=\"rowIndex\" let-field=\"field\"\r\n let-expanded=\"expanded\">\r\n <ng-container *ngIf=\"col.template\">\r\n <ng-container [ngTemplateOutlet]=\"col.template\"\r\n [ngTemplateOutletContext]=\"getContextCell(rowData, rowIndex, col, expanded,this)\">\r\n </ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"!col.template\">\r\n <ng-container [ngSwitch]=\"col.dataType\">\r\n <span *ngSwitchCase=\"'color'\" style=\"display:block;text-align:center;\">\r\n <div pTooltip=\"{{rowData[field]}}\" tooltipPosition=\"top\" [ngStyle]=\"{'background-color':rowData[field]}\"\r\n style=\"width:30px;height:30px;margin:0 auto;\"></div>\r\n </span>\r\n <span *ngSwitchCase=\"'icon'\" style=\"display:block;text-align:center;\">\r\n <i pTooltip=\"{{rowData[field]}}\" tooltipPosition=\"top\" style=\"text-align: center;\"\r\n [ngClass]=\"rowData[field]\"></i>\r\n </span>\r\n <span *ngSwitchCase=\"'date'\" pTooltip=\"{{rowData[field] | date:'dd/MM/yyyy'}}\" tooltipPosition=\"top\">\r\n {{_crudService.renderDate(rowData[field], col.format)}}\r\n </span>\r\n <span *ngSwitchCase=\"'datetime'\" pTooltip=\"{{rowData[field] | date:'dd/MM/yyyy HH:mm'}}\"\r\n tooltipPosition=\"top\">\r\n {{_crudService.renderDateTime(rowData[field], col.format)}}\r\n </span>\r\n <span *ngSwitchCase=\"'user'\" class=\"user\">\r\n {{rowData[field] | userFormat | async}}\r\n </span>\r\n <div *ngSwitchCase=\"'users'\" [innerHTML]=\"rowData[field] | usersFormat | async\">\r\n </div>\r\n <span *ngSwitchCase=\"'int'\">\r\n {{rowData[field]}}\r\n </span>\r\n <span *ngSwitchCase=\"'decimal'\">\r\n {{rowData[field]}}\r\n </span>\r\n <span *ngSwitchCase=\"'boolean'\">\r\n <p-checkbox class=\"boolean-data-type\" [(ngModel)]=\"rowData[field]\" binary=\"true\"\r\n [disabled]=\"col.disableCheckBox\">\r\n </p-checkbox>\r\n </span>\r\n <span *ngSwitchCase=\"'html'\">\r\n <div *ngIf=\"rowData[field]==null?'':rowData[field]\" [innerHTML]=\"rowData[field] | safeHtml\"></div>\r\n </span>\r\n <span *ngSwitchCase=\"'metadataStatus'\">\r\n <span *ngIf=\"rowData['rejectReason']\" class=\"label-danger\" [pTooltip]=\"rowData['rejectReason']\"\r\n tooltipStyleClass=\"unset-width\" [escape]=\"false\" tooltipPosition=\"top\">T\u1EEB ch\u1ED1i</span>\r\n <span *ngIf=\"rowData[field] == '0' && !rowData['rejectReason']\" class=\"label-secondary\">Ch\u01B0a\r\n duy\u1EC7t</span>\r\n <span *ngIf=\"rowData[field] == '1' && !rowData['rejectReason']\" class=\"label-warning\">Ch\u1EDD duy\u1EC7t</span>\r\n <span *ngIf=\"rowData[field] == '2'\" class=\"label-primary\">\u0110\u00E3 duy\u1EC7t</span>\r\n </span>\r\n <ng-container *ngSwitchCase=\"'string'\">\r\n <ng-container *ngTemplateOutlet=\"contentCellString; context: {$implicit: rowData, field: col.field}\">\r\n </ng-container>\r\n </ng-container>\r\n <ng-container *ngSwitchCase=\"null\">\r\n <ng-container *ngTemplateOutlet=\"contentCellString; context: {$implicit: rowData, field: col.field}\">\r\n </ng-container>\r\n </ng-container>\r\n <ng-container *ngSwitchDefault>\r\n <ng-container [ngTemplateOutlet]=\"getComponentByType(col.dataType)\"\r\n [ngTemplateOutletContext]=\"getContextCell(rowData, rowIndex, col, expanded, this)\">\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n</ng-template>\r\n<ng-template #contentCellString let-rowData let-field=\"field\">\r\n <span>\r\n <!-- __sv: Short Value -->\r\n <ng-container *ngIf=\"rowData[field + '__sv']\">\r\n <ng-container *ngIf=\"!rowData[field + '__showFull']\">\r\n {{rowData[field + '__sv']}}\r\n <span class=\"toggle-showfull\" (click)=\"toggleShowFull(rowData, field)\" pTooltip=\"B\u1EA5m \u0111\u1EC3 xem th\u00EAm\"\r\n tooltipPosition=\"top\">[...]</span>\r\n </ng-container>\r\n <ng-container *ngIf=\"rowData[field + '__showFull']\">\r\n {{rowData[field]}}\r\n <span class=\"toggle-showfull\" (click)=\"toggleShowFull(rowData, field)\">Thu g\u1ECDn</span>\r\n </ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"!rowData[field + '__sv']\">\r\n {{rowData[field]}}\r\n </ng-container>\r\n </span>\r\n</ng-template>\r\n<ng-template #iconToggleRowGroup let-rowData=\"rowData\" let-expanded=\"expanded\">\r\n <a href=\"javascript:;\" (click)=\"handleToggleRow(rowData, $event)\">\r\n <i style=\"margin-right:5px\" [ngClass]=\"expanded ? 'fas fa-fw fa-caret-down' : 'fas fa-fw fa-caret-right'\"></i>\r\n </a>\r\n</ng-template>\r\n<ng-template #iconToggleRowData let-rowData=\"rowData\" let-expanded=\"expanded\">\r\n <button type=\"button\" pButton pRipple class=\"link-or-action p-button-text p-button-rounded p-button-plain\"\r\n [icon]=\"expanded ? 'pi pi-chevron-down' : 'pi pi-chevron-right'\"\r\n (click)=\"handleToggleRow(rowData, $event)\"></button>\r\n</ng-template>\r\n<ng-template #_contentRowGroup let-rowData=\"rowData\" let-groupCol=\"groupCol\" let-groupField=\"_groupField\">\r\n <ng-container [ngTemplateOutlet]=\"contentCell\"\r\n [ngTemplateOutletContext]=\"{rowData: rowData, col: groupCol, field: _groupField}\">\r\n </ng-container>\r\n <span> ({{rowGroupMetadata[rowData[_groupField]].size}})</span>\r\n</ng-template>\r\n<ng-template #entityWorkflowStatus let-rowData=\"rowData\">\r\n <div class=\"container-text-workflow\">\r\n <span class=\"content\">{{rowData.statusString ? rowData.statusString : rowData.strcurrentStateCode}}</span>\r\n <button *ngIf=\"!rowData.hiddenWorkflowAction\" type=\"button\" pButton icon=\"pi pi-ellipsis-v\"\r\n class=\"link-or-action p-button-text p-button-rounded\" pTooltip=\"H\u00E0nh \u0111\u1ED9ng\" tooltipPosition=\"top\"\r\n (click)=\"showActionWorkflow($event, rowData)\"></button>\r\n </div>\r\n</ng-template>\r\n<ng-template #trangThaiV5 let-rowData=\"rowData\">\r\n <div class=\"container-text-workflow\">\r\n <button *ngIf=\"!rowData.__workflowCode\" pButton class=\"p-button-text link-or-action\" label=\"B\u1EAFt \u0111\u1EA7u\"\r\n style=\"border: 1px solid #7ca9cd;\" pTooltip=\"B\u1EAFt \u0111\u1EA7u ch\u1EA1y quy tr\u00ECnh\" tooltipPosition=\"top\"\r\n (click)=\"showFormStartWorkflow(rowData)\"></button>\r\n <ng-container *ngIf=\"rowData.__workflowCode\">\r\n <span class=\"content\">{{rowData.__textTrangThai}}</span>\r\n <button *ngIf=\"!rowData.hiddenWorkflowAction\" type=\"button\" pButton icon=\"pi pi-ellipsis-v\"\r\n class=\"link-or-action p-button-text p-button-rounded\" pTooltip=\"H\u00E0nh \u0111\u1ED9ng\" tooltipPosition=\"top\"\r\n [disabled]=\"showingActionWorkflow\" (click)=\"showActionWorkflowNew($event, rowData)\"></button>\r\n </ng-container>\r\n </div>\r\n</ng-template>\r\n<ng-template #viewHistory let-rowData=\"rowData\">\r\n <button pButton icon=\"pi pi-calendar\" class=\"p-button-text p-button-rounded link-or-action\" pTooltip=\"Xem l\u1ECBch s\u1EED\"\r\n tooltipPosition=\"top\" (click)=\"viewHistoryWorkflowNew(rowData)\"></button>\r\n</ng-template>\r\n<ng-template #workflowCoreStatus let-rowData=\"rowData\">\r\n <div class=\"container-text-workflow\">\r\n <a class=\"content\" (click)=\"goToTask($event)\" href=\"javascript:;\">{{rowData.strworkflowCoreStatus}}</a>\r\n </div>\r\n</ng-template>\r\n<ng-template #containerSticky>\r\n <span class=\"fix-sticky top\"></span>\r\n <span class=\"fix-sticky right\"></span>\r\n <!-- <span class=\"fix-sticky bottom\"></span> -->\r\n <span class=\"fix-sticky left\"></span>\r\n</ng-template>\r\n<ng-template #sortIcon let-field=\"field\">\r\n <i class=\"p-sortable-column-icon pi\" style=\"font-size: 0.8em;\"\r\n [ngClass]=\"{'pi-sort-amount-up-alt': field == _sortField && _sortDir === 1, 'pi-sort-amount-down': field == _sortField && _sortDir === -1, 'pi-sort-alt': field != _sortField || _sortDir === 0}\"></i>\r\n</ng-template>\r\n<ng-template #filterDropdown let-col=\"col\">\r\n <div #filterBox style=\"width: 100%; border-radius: 4px;\">\r\n <dropdown *ngIf=\"col && filterSchema.dropdown[col.field]\" [control]=\"filterSchema.dropdown[col.field]\"\r\n [dataSource]=\"filterSchema.dropdown[col.field].dataSource\" [(value)]=\"filterData[col.field]\"\r\n (onHideSmartEvent)=\"onSearch()\" (onShow)=\"onShowFilterDropdownPanel($event)\"\r\n (onHide)=\"onHideFilterDropdownPanel($event)\" (mousedown)=\"initFilterBoxFocus(filterBox)\"></dropdown>\r\n </div>\r\n</ng-template>\r\n<ng-template #filterText let-col=\"col\">\r\n <div #filterBox class=\"text-filter filter-box\" tabindex=\"-1\" (mousedown)=\"initFilterBoxFocus(filterBox)\">\r\n <div tabindex=\"-1\">\r\n <input pInputText type=\"text\" class=\"input-search\" [placeholder]=\"col.label\"\r\n [(ngModel)]=\"filterData[col.field]\" (change)=\"onSearch()\"\r\n (keyup.esc)=\"onClearSearch(filterBox, col.field)\">\r\n </div>\r\n <span [ngClass]=\"{'action-clear': true, 'dirty': filterData[col.field] != null && filterData[col.field] !== ''}\"\r\n [pTooltip]=\"'B\u1ECF filter'\" tooltipPosition=\"top\" (mousedown)=\"onClearSearch(filterBox, col.field)\"\r\n tabindex=\"-1\"><i class=\"pi pi-filter-slash\"></i></span>\r\n <after-view-checked style=\"display: none;\" (loaded)=\"initFilterBoxFocus(filterBox)\">\r\n </after-view-checked>\r\n </div>\r\n</ng-template>\r\n<ng-template #filterNumber let-col=\"col\">\r\n <div #filterBox class=\"number-picker-range filter-box\" tabindex=\"-1\" (mousedown)=\"initFilterBoxFocus(filterBox)\">\r\n <div tabindex=\"-1\">\r\n <tn-number-picker-range #numberRange [maskType]=\"col.dataType\" [(ngModel)]=\"filterData[col.field]\"\r\n [min]=\"col.min\" [max]=\"col.max\" (change)=\"onSearch()\">\r\n </tn-number-picker-range>\r\n </div>\r\n <span\r\n [ngClass]=\"{'action-clear': true, 'dirty': filterData[col.field] && ((filterData[col.field][0] != null && filterData[col.field][0] !== '') || (filterData[col.field][1] != null && filterData[col.field][1] !== ''))}\"\r\n [pTooltip]=\"'B\u1ECF filter'\" tooltipPosition=\"top\" (mousedown)=\"onClearNumberSearch(filterBox, numberRange)\"\r\n tabindex=\"-1\">\r\n <i class=\"pi pi-filter-slash\"></i></span>\r\n <after-view-checked style=\"display: none;\" (loaded)=\"initFilterBoxFocus(filterBox)\">\r\n </after-view-checked>\r\n </div>\r\n</ng-template>\r\n<ng-template #filterDate let-col=\"col\">\r\n <div #filterBox class=\"date-picker-range filter-box\" tabindex=\"-1\" (mousedown)=\"initFilterBoxFocus(filterBox)\">\r\n <div tabindex=\"-1\">\r\n <tn-datetime-picker-range #dateRange [control]=\"filterSchema.dateRange\"\r\n (onChanged)=\"onChangeDateTime($event, col.field)\">\r\n </tn-datetime-picker-range>\r\n </div>\r\n <span\r\n [ngClass]=\"{'action-clear': true, 'dirty': filterData[col.field] && ((filterData[col.field][0] != null && filterData[col.field][0] !== '') || (filterData[col.field][1] != null && filterData[col.field][1] !== ''))}\"\r\n [pTooltip]=\"'B\u1ECF filter'\" tooltipPosition=\"top\"\r\n (mousedown)=\"onClearDateSearch(filterBox, dateRange, col.field)\" tabindex=\"-1\"><i\r\n class=\"pi pi-filter-slash\"></i></span>\r\n <after-view-checked style=\"display: none;\" (loaded)=\"initFilterBoxFocus(filterBox)\">\r\n </after-view-checked>\r\n </div>\r\n</ng-template>\r\n<ng-template #filterBoolean let-col=\"col\">\r\n <div class=\"filter-boolean-box\">\r\n <p-selectButton\r\n [options]=\"[{value: true, label: 'C\u00F3', icon: 'pi pi-check'}, {value: false, label: 'Kh\u00F4ng', icon: 'pi pi-times'}]\"\r\n [multiple]=\"true\" [(ngModel)]=\"filterData[col.field]\" (onChange)=\"onChangeBoolean($event, col.field)\">\r\n <ng-template let-item>\r\n <i style=\"padding: 3px 0;\" [class]=\"item.icon\"></i>\r\n </ng-template>\r\n </p-selectButton>\r\n </div>\r\n</ng-template>",
|
|
18448
|
+
template: "<div #container class=\"custom-card card card-w-title flex-container-fit-child\" [attr.height-type]=\"setting.heightType\"\r\n [ngStyle]=\"_style\">\r\n <div class=\"ui-helper-clearfix crud-list-header-area\">\r\n <div *ngIf=\"searchCustom\" class=\"p-grid ui-fluid custom-p-col custom-search-area\">\r\n <div class=\"p-col-12 main-container-search\">\r\n <div class=\"p-grid main-container-search-inner\">\r\n <ng-container>\r\n <ng-container *ngTemplateOutlet=\"searchCustom; context: {$implicit: this}\"></ng-container>\r\n </ng-container>\r\n </div>\r\n </div>\r\n </div>\r\n <div *ngIf=\"!setting.hiddenHeader\" class=\"p-grid ui-fluid custom-p-col page-title-area\">\r\n <div *ngIf=\"!setting.hiddenPageTitle\" class=\"main-title\">\r\n <h1 *ngIf=\"!hasTemplate('customTitle')\">\r\n {{setting.title != null ? setting.title : 'Danh s\u00E1ch ' + setting.objectName}}\r\n </h1>\r\n\r\n <ng-container *ngIf=\"hasTemplate('customTitle')\" [ngTemplateOutlet]=\"getTemplate('customTitle')\"\r\n [ngTemplateOutletContext]=\"{crudList: this}\">\r\n </ng-container>\r\n </div>\r\n\r\n <div *ngIf=\"!setting.hiddenPageSetting\" class=\"paginator-table\">\r\n <paging-next-back-only [model]=\"model\" [setting]=\"setting\" (onOldest)=\"onOldest($event)\"\r\n (onNext)=\"onNext($event)\" (onPrev)=\"onPrev($event)\" (onLatest)=\"onLatest($event)\"\r\n (onChangeLimitPage)=\"savePageSize()\">\r\n </paging-next-back-only>\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"fit-content crud-list-body-area\">\r\n <div class=\"crud-list-body-area-inner\" style=\"overflow: unset;\">\r\n <div class=\"flex-container-fit-child\" style=\"overflow: unset;\">\r\n <div *ngIf=\"!setting.hiddenToolbar\" class=\"p-grid crudListToolbar\">\r\n <ng-container>\r\n <div *ngIf=\"!setting.hiddenButtons && hasTemplate('toolbar')\"\r\n [ngClass]=\"setting.hiddenAdvanceSearch ? 'p-md-12 p-lg-12' : 'p-md-7 p-lg-8'\"\r\n class=\"p-col-12 button-group function-topbar custom-toolbar\">\r\n <ng-container\r\n [ngTemplateOutletContext]=\"{selectedItems: model.selectedItems, crudList: this}\"\r\n [ngTemplateOutlet]=\"getTemplate('toolbar')\"></ng-container>\r\n </div>\r\n <div *ngIf=\"!setting.hiddenButtons && !hasTemplate('toolbar')\"\r\n [ngClass]=\"setting.hiddenAdvanceSearch ? 'p-md-12 p-lg-12' : 'p-md-7 p-lg-8'\"\r\n class=\"p-col-12 button-group function-topbar\">\r\n <button *ngIf=\"!hiddenAdd\" type=\"button\" pButton pRipple label=\"Th\u00EAm m\u1EDBi\" icon=\"pi pi-plus\"\r\n class=\"p-button-text\" [disabled]=\"!model.baseReady\" (click)=\"add()\"></button>\r\n <button *ngIf=\"setting.showExportSelectedItems && model.selectedItems.length > 0\"\r\n type=\"button\" pButton pRipple\r\n label=\"Xu\u1EA5t c\u00E1c m\u1EE5c \u0111\u00E3 ch\u1ECDn ({{model.selectedItems.length}})\" icon=\"fas fa-file-excel\"\r\n class=\"p-button-text p-button-success\" (click)=\"xuatCacMucDaChon()\"></button>\r\n <button *ngIf=\"!hiddenDelete && model.selectedItems.length > 0 && !disableMultipleDelete()\"\r\n type=\"button\" pButton pRipple\r\n label=\"{{ 'X\u00F3a' | translate }} ({{model.selectedItems.length}})\" icon=\"pi pi-trash\"\r\n class=\"p-button-text p-button-danger\" (click)=\"deleteMutiple()\"></button>\r\n <button\r\n *ngIf=\"!hiddenCopyLink && model.selectedItems.length > 0 && !disableMultipleCopyLink()\"\r\n label=\"Sao ch\u00E9p li\u00EAn k\u1EBFt\" type=\"button\" pButton pRipple\r\n pTooltip=\"{{'Sao ch\u00E9p li\u00EAn k\u1EBFt' | translate}}\" tooltipPosition=\"top\"\r\n class=\"p-button-rounded p-button-text p-button-info link-or-action\" icon=\"pi pi-link\"\r\n (click)=\"copyLinkMultiple()\"></button>\r\n <button *ngIf=\"!disableShare && model.selectedItems.length > 0\" label=\"Chia s\u1EBB li\u00EAn k\u1EBFt\"\r\n type=\"button\" pButton pRipple [pTooltip]=\"'Chia s\u1EBB li\u00EAn k\u1EBFt' | translate\"\r\n tooltipPosition=\"top\"\r\n class=\"p-button-rounded p-button-text p-button-info link-or-action\" icon=\"pi pi-link\"\r\n (click)=\"createShareLinkMultiple()\"></button>\r\n <ng-container [ngTemplateOutlet]=\"getTemplate('buttonAfterToolbar')\"\r\n [ngTemplateOutletContext]=\"{crudList: this}\"></ng-container>\r\n </div>\r\n </ng-container>\r\n <div *ngIf=\"!setting.hiddenAdvanceSearch\" class=\"p-col-12 advance-search-container\"\r\n [ngClass]=\"setting.hiddenButtons ? 'p-md-12 p-lg-12' : 'p-md-5 p-lg-4'\">\r\n <advance-search #advanceSearch [parentSetting]=\"setting\" [searchInfo]=\"searchInfo\"\r\n [loading]=\"model.loading\" (onSearch)=\"handleSearchAdvs($event)\"\r\n (onInit)=\"handleInitAdvanceSearch($event)\">\r\n </advance-search>\r\n </div>\r\n </div>\r\n <div *ngIf=\"hasTemplate('topGrid')\" class=\"extend-content-top-grid\">\r\n <ng-container [ngTemplateOutletContext]=\"{selectedItems: model.selectedItems, crudList: this}\"\r\n [ngTemplateOutlet]=\"getTemplate('topGrid')\"></ng-container>\r\n </div>\r\n <div class=\"container-table fit-content\" [class.--table-responsive]=\"responsive\">\r\n <div class=\"container-table-inner\">\r\n <ng-container *ngIf=\"!_groupField\">\r\n <tn-custom-scrollbar *ngIf=\"showScrollBar\" #scrollbar [config]=\"configScrollBar\"\r\n [showScrollHorizontal]=\"showScrollHorizontal\">\r\n <ng-container *ngTemplateOutlet=\"tableGetGroupFieldFalse\">\r\n </ng-container>\r\n <ng-container *ngIf=\"hasTemplate('afterCrudList')\">\r\n <ng-container [ngTemplateOutlet]=\"hasTemplate('afterCrudList')\"></ng-container>\r\n </ng-container>\r\n </tn-custom-scrollbar>\r\n <div *ngIf=\"!showScrollBar\">\r\n <ng-container *ngTemplateOutlet=\"tableGetGroupFieldFalse\">\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n <ng-container *ngIf=\"_groupField\">\r\n <tn-custom-scrollbar *ngIf=\"showScrollBar\" #scrollbar [config]=\"configScrollBar\"\r\n [showScrollHorizontal]=\"showScrollHorizontal\">\r\n <ng-container *ngTemplateOutlet=\"tableGetGroupFieldTrue\">\r\n </ng-container>\r\n <ng-container *ngIf=\"hasTemplate('afterCrudList')\">\r\n <ng-container [ngTemplateOutlet]=\"getTemplate('afterCrudList')\"></ng-container>\r\n </ng-container>\r\n </tn-custom-scrollbar>\r\n <div *ngIf=\"!showScrollBar\">\r\n <ng-container *ngTemplateOutlet=\"tableGetGroupFieldTrue\">\r\n </ng-container>\r\n </div>\r\n </ng-container>\r\n\r\n <div class=\"table-border-line --top\"></div>\r\n <div class=\"table-border-line --right\"></div>\r\n <div class=\"table-border-line --bottom\"></div>\r\n <div class=\"table-border-line --left\"></div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n<after-view-checked (loaded)=\"handleReady()\"></after-view-checked>\r\n<settings *ngIf=\"_showSettings && !setting.hiddenSetting\" [entityMetadataService]=\"entityMetadataService\"\r\n [parentContext]=\"context\" [parentSetting]=\"setting\" [parentModel]=\"model\" (onSave)=\"onSaveSettings($event)\"\r\n (onCancel)=\"_showSettings = false\">\r\n</settings>\r\n<settings-row *ngIf=\"_showSettingsRowColor && !setting.hiddenSetting\" [entityMetadataService]=\"entityMetadataService\"\r\n [parentContext]=\"context\" [parentSetting]=\"setting\" [parentModel]=\"model\" (onSave)=\"onSaveColorSettings($event)\"\r\n (onCancel)=\"_showSettingsRowColor = false\">\r\n</settings-row>\r\n<workflow-setting-dialog *ngIf=\"_showSettingsWorkflow && !setting.hiddenSettingWorkflow\" [parentSetting]=\"setting\"\r\n [parentContext]=\"context\" [parentModel]=\"model\" (onSaved)=\"onSaveWorkflowSettings($event)\"\r\n (onRemoved)=\"onRemoveWorkflowSettings($event)\" (onCancel)=\"_showSettingsWorkflow = false\"></workflow-setting-dialog>\r\n<tn-dialog *ngIf=\"workflowSettingModel.showEditForm\" [header]=\"'C\u1EA5u h\u00ECnh quy tr\u00ECnh nghi\u1EC7p v\u1EE5' | translate\"\r\n [popupSize]=\"workflowSettingModel.popupSize\" (onHide)=\"workflowSettingModel.showEditForm = false\">\r\n <workflow-setting-new #formBase [parentSetting]=\"setting\" (onSaved)=\"onSaveWorkflowSettingsNew($event)\"\r\n (onCancel)=\"workflowSettingModel.showEditForm = false\"></workflow-setting-new>\r\n</tn-dialog>\r\n<entity-permission *ngIf=\"_showSettingsPermission && !setting.hiddenSettingPermission\" [parentSetting]=\"setting\"\r\n [parentContext]=\"context\" [parentModel]=\"model\" [searchInfo]=\"searchInfo\"\r\n (onCancel)=\"_showSettingsPermission = false\">\r\n</entity-permission>\r\n<p-contextMenu #contextMenu [appendTo]=\"'body'\" [model]=\"buttonContexts\">\r\n</p-contextMenu>\r\n<tn-dialog *ngIf=\"showFormWorkflow\" #dialog [header]=\"headerWorkflow | translate\" [popupSize]=\"popupSizeWorkflow\"\r\n [scrollBarStyleClass]=\"'fit-content'\" (onHide)=\"showFormWorkflow = false\">\r\n <div style=\"height: 100%\">\r\n <simple-workflow-form #formBase [baseService]=\"setting.baseService\" [item]=\"currentItem\"\r\n [action]=\"actionWorkflow\" (onInvalidWorkflow)=\"handleInvalidWF($event)\" (onSaved)=\"handleProcessedWorflow()\"\r\n (onCancel)=\"showFormWorkflow = false\">\r\n </simple-workflow-form>\r\n </div>\r\n</tn-dialog>\r\n<tn-dialog *ngIf=\"processWorkflowModel.showEditForm\" #dialog [header]=\"processWorkflowModel.header | translate\"\r\n [popupSize]=\"processWorkflowModel.popupSize\" [scrollBarStyleClass]=\"'fit-content'\"\r\n (onHide)=\"processWorkflowModel.showEditForm = false\">\r\n <div style=\"height: 100%\">\r\n <process-workflow-form #formBase [businessSetting]=\"setting\" [item]=\"currentItem\"\r\n [workflow]=\"processWorkflowModel.data.workflow\" [action]=\"processWorkflowModel.data.action\"\r\n (onSaved)=\"handleProcessedWorkflowBase()\" (onCancel)=\"processWorkflowModel.showEditForm = false\">\r\n </process-workflow-form>\r\n </div>\r\n</tn-dialog>\r\n<tn-dialog *ngIf=\"choYKienModel.showEditForm\" #dialog [header]=\"choYKienModel.header | translate\"\r\n [popupSize]=\"choYKienModel.popupSize\" [scrollBarStyleClass]=\"'fit-content'\"\r\n (onHide)=\"choYKienModel.showEditForm = false\">\r\n <div style=\"height: 100%\">\r\n <cho-y-kien-form #formBase [bussinessSetting]=\"setting\" [rowItem]=\"choYKienModel.data.rowData\"\r\n (onSaved)=\"choYKienModel.showEditForm = false\" (onCancel)=\"choYKienModel.showEditForm = false\">\r\n </cho-y-kien-form>\r\n </div>\r\n</tn-dialog>\r\n<tn-dialog *ngIf=\"workflowHistoryModel.showEditForm\" #dialog [header]=\"workflowHistoryModel.header | translate\"\r\n [popupSize]=\"workflowHistoryModel.popupSize\" [scrollBarStyleClass]=\"'fit-content'\"\r\n (onHide)=\"workflowHistoryModel.showEditForm = false\">\r\n <div style=\"height: 100%\">\r\n <workflow-history-new #formBase [businessSetting]=\"setting\" [item]=\"currentItem\"\r\n [workflowSetting]=\"workflowHistoryModel.data.workflowSetting\"\r\n (onCancel)=\"workflowHistoryModel.showEditForm = false\">\r\n </workflow-history-new>\r\n </div>\r\n</tn-dialog>\r\n<tn-dialog *ngIf=\"permissionSharingModel.showEditForm\" #dialog [header]=\"permissionSharingModel.header | translate\"\r\n [popupSize]=\"permissionSharingModel.popupSize\" [scrollBarStyleClass]=\"'fit-content'\"\r\n (onHide)=\"permissionSharingModel.showEditForm = false\">\r\n <div style=\"height: 100%\">\r\n <permission-sharing #formBase [item]=\"rowDataCurrent\" [baseService]=\"setting.baseService\"\r\n (onCancel)=\"permissionSharingModel.showEditForm = false\">\r\n </permission-sharing>\r\n </div>\r\n</tn-dialog>\r\n<workflow-history-dialog *ngIf=\"showHistoryWorkflow\" [baseService]=\"setting.baseService\" [item]=\"currentItem\"\r\n [workflowSetting]=\"setting.workflowSetting\" (onHide)=\"handleHideHistoryWorkflow()\">\r\n</workflow-history-dialog>\r\n<tn-dialog *ngIf=\"startWorkflowModel.showEditForm\" #dialog [header]=\"startWorkflowModel.header | translate\"\r\n [popupSize]=\"startWorkflowModel.popupSize\" [scrollBarStyleClass]=\"'fit-content'\"\r\n (onHide)=\"startWorkflowModel.showEditForm = false\">\r\n <div style=\"height: 100%\">\r\n <start-workflow #formBase [workflows]=\"startWorkflowModel.data.workflows\"\r\n [defaultWorkflow]=\"startWorkflowModel.data.defaultWorkflow\"\r\n (onCancel)=\"startWorkflowModel.showEditForm = false\" (onSaved)=\"handleStartWorkflowFromDialog($event)\">\r\n </start-workflow>\r\n </div>\r\n</tn-dialog>\r\n<tn-dialog *ngIf=\"congViecModel.showEditForm\" #dialog [styleClass]=\"'congviec-form tn-form-dialog'\"\r\n [header]=\"congViecModel.header | translate\" [popupSize]=\"congViecModel.popupSize\"\r\n (onHide)=\"congViecModel.showEditForm = false\">\r\n <base-congviec-form #formBase [parentSetting]=\"congViecModel.data.congViecSetting\"\r\n [model]=\"congViecModel.data.model\" (onSaved)=\"congViecModel.showEditForm = false;getData()\"\r\n (onCancel)=\"congViecModel.showEditForm = false\">\r\n </base-congviec-form>\r\n</tn-dialog>\r\n<ng-template #tableGetGroupFieldFalse>\r\n <p-table #table [dataKey]=\"'id'\" [scrollable]=\"pTableScrollable\" [scrollHeight]=\"pTableScrollHeight\"\r\n [columns]=\"setting.cols\" [paginator]=\"false\" [value]=\"_dataSource\" (onSort)=\"onSort($event, table)\"\r\n [class]=\"_tableClass\" [responsive]=\"responsive\" [lazy]=\"lazy\" [loading]=\"model.loading\"\r\n [(selection)]=\"model.selectedItems\" (onRowReorder)=\"handleRowOrdered($event)\">\r\n <ng-template *ngIf=\"header\" pTemplate=\"header\" let-columns>\r\n <ng-container\r\n *ngTemplateOutlet=\"header, context: {$implicit: columns, crudList: this, rowHeaderFilter: rowHeaderFilter, contentTh: contentTh, containerSticky: containerSticky, funcCheckAll: handleCheckAll}\">\r\n </ng-container>\r\n </ng-template>\r\n <ng-template *ngIf=\"!header\" pTemplate=\"header\" let-columns>\r\n <ng-container *ngTemplateOutlet=\"trHeader; context: {$implicit: columns, funcCheckAll: handleCheckAll}\">\r\n </ng-container>\r\n </ng-template>\r\n <ng-template pTemplate=\"body\" let-rowData let-columns=\"columns\" let-index=\"rowIndex\" let-expanded=\"expanded\">\r\n <ng-container\r\n *ngTemplateOutlet=\"trBody; context: {$implicit: rowData, columns: columns, index: index, expanded: expanded, eventSelectRow: handleSelectRow, eventChecked: handleCheckRowData}\">\r\n </ng-container>\r\n <after-view-checked *ngIf=\"index == _dataSource.length - 1\" style=\"display: none;\" [renderKey]=\"_dataSource\"\r\n (loaded)=\"handleTableRendered()\">\r\n </after-view-checked>\r\n </ng-template>\r\n <ng-template *ngIf=\"rowExpansion\" pTemplate=\"rowexpansion\" let-rowData let-expanded=\"expanded\">\r\n <ng-container\r\n *ngTemplateOutlet=\"rowExpansion; context: {rowData: rowData, expanded: expanded, getColSpanGroup: getColSpanGroup}\">\r\n </ng-container>\r\n </ng-template>\r\n <ng-template *ngIf=\"summary\" pTemplate=\"summary\">\r\n <ng-container *ngTemplateOutlet=\"summary\"></ng-container>\r\n </ng-template>\r\n <ng-template *ngIf=\"footer\" pTemplate=\"footer\" let-columns>\r\n <ng-container *ngTemplateOutlet=\"footer; context: {$implicit: columns}\"></ng-container>\r\n </ng-template>\r\n <ng-template *ngIf=\"colgroup\" pTemplate=\"colgroup\" let-columns>\r\n <ng-container *ngTemplateOutlet=\"colgroup; context: {$implicit: columns}\"></ng-container>\r\n </ng-template>\r\n </p-table>\r\n</ng-template>\r\n<ng-template #tableGetGroupFieldTrue>\r\n <p-table #tableGroup [scrollable]=\"pTableScrollable\" [scrollHeight]=\"pTableScrollHeight\" [columns]=\"setting.cols\"\r\n [paginator]=\"false\" [value]=\"_dataSource\" [metaKeySelection]=\"false\" (onSort)=\"onSort($event, tableGroup)\"\r\n [class]=\"_tableClass\" [customSort]=\"true\" [responsive]=\"responsive\" [lazy]=\"true\" [loading]=\"model.loading\"\r\n [(selection)]=\"model.selectedItems\" [expandedRowKeys]=\"model.expandedRowKeys\" [dataKey]=\"_groupField\">\r\n <ng-template *ngIf=\"header\" pTemplate=\"header\" let-columns>\r\n <ng-container\r\n *ngTemplateOutlet=\"header, context: {$implicit: columns, crudList: this, rowHeaderFilter: rowHeaderFilter, contentTh: contentTh, containerSticky: containerSticky, funcCheckAll: handleCheckAll_Group}\">\r\n </ng-container>\r\n </ng-template>\r\n <ng-template *ngIf=\"!header\" pTemplate=\"header\" let-columns>\r\n <ng-container\r\n *ngTemplateOutlet=\"trHeader; context: {$implicit: columns, funcCheckAll: handleCheckAll_Group}\">\r\n </ng-container>\r\n </ng-template>\r\n <ng-template pTemplate=\"body\" let-rowData let-rowIndex=\"rowIndex\" let-expanded=\"expanded\" let-columns=\"columns\">\r\n <tr *ngIf=\"rowGroupMetadata[rowData[_groupField]] && rowGroupMetadata[rowData[_groupField]].index == rowIndex\"\r\n class=\"p-widget-header group-row\" style=\"border: 0px; border-bottom: 1px solid #eee\">\r\n <td *ngIf=\"!setting.hiddenCheckbox\" class=\"center chkbox\" [class.sticky]=\"setting.stickyColumn\">\r\n <p-checkbox [(ngModel)]=\"rowGroupChecked[rowData[_groupField]]\" binary=\"true\"\r\n (onChange)=\"handleCheckRowGroup(rowData)\">\r\n </p-checkbox>\r\n <ng-container *ngTemplateOutlet=\"containerSticky\"></ng-container>\r\n </td>\r\n <ng-container *ngIf=\"!rowGroup\">\r\n <td [colSpan]=\"getColSpanGroup()\" [class]=\"_classRowGroup\">\r\n <div class=\"container-row-group\">\r\n <a href=\"javascript:;\" [pRowToggler]=\"rowData\" class=\"container-row-group-toggle\"\r\n [class.sticky]=\"setting.stickyColumn\">\r\n <i style=\"margin-right:5px\"\r\n [ngClass]=\"expanded ? 'fas fa-fw fa-caret-down' : 'fas fa-fw fa-caret-right'\"></i>\r\n <span class=\"content-row-group\">\r\n <ng-container *ngIf=\"!contentRowGroup\">\r\n <ng-container [ngTemplateOutlet]=\"_contentRowGroup\"\r\n [ngTemplateOutletContext]=\"getContextRowGroup(rowData)\">\r\n </ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"contentRowGroup\">\r\n <ng-container [ngTemplateOutlet]=\"contentRowGroup\"\r\n [ngTemplateOutletContext]=\"getContextRowGroup(rowData)\">\r\n </ng-container>\r\n </ng-container>\r\n </span>\r\n </a>\r\n </div>\r\n </td>\r\n </ng-container>\r\n <ng-container *ngIf=\"rowGroup\">\r\n <ng-container [ngTemplateOutlet]=\"rowGroup\"\r\n [ngTemplateOutletContext]=\"getContextRowGroupRoot(rowData, expanded)\">\r\n </ng-container>\r\n </ng-container>\r\n </tr>\r\n </ng-template>\r\n <ng-template pTemplate=\"rowexpansion\" let-columns=\"columns\" let-rowData let-index=\"rowIndex\">\r\n <ng-container\r\n *ngTemplateOutlet=\"trBody; context: {$implicit: rowData, columns: columns, index: index, expanded: false, eventSelectRow: handleSelectRowGroup, eventChecked: handleCheckRowData_Group}\">\r\n </ng-container>\r\n <after-view-checked *ngIf=\"index == _dataSource.length - 1\" style=\"display: none;\" [renderKey]=\"_dataSource\"\r\n (loaded)=\"handleTableRendered()\">\r\n </after-view-checked>\r\n </ng-template>\r\n <ng-template *ngIf=\"summary\" pTemplate=\"summary\">\r\n <ng-container *ngTemplateOutlet=\"summary\"></ng-container>\r\n </ng-template>\r\n <ng-template *ngIf=\"footer\" pTemplate=\"footer\" let-columns>\r\n <ng-container *ngTemplateOutlet=\"footer; context: {$implicit: columns}\"></ng-container>\r\n </ng-template>\r\n <ng-template *ngIf=\"colgroup\" pTemplate=\"colgroup\" let-columns>\r\n <ng-container *ngTemplateOutlet=\"colgroup; context: {$implicit: columns}\"></ng-container>\r\n </ng-template>\r\n </p-table>\r\n <after-view-checked></after-view-checked>\r\n</ng-template>\r\n<ng-template #trHeader let-columns let-funcCheckAll=\"funcCheckAll\">\r\n <tr class=\"title-row\">\r\n <ng-container *ngIf=\"!setting.hiddenCheckbox\">\r\n <th [style.width]=\"widthCheckbox\" class=\"chkbox link-or-action cell-checkbox\"\r\n [class.sticky]=\"setting.stickyColumn\">\r\n <button *ngIf=\"!hasTemplate('headerCheckbox')\" type=\"button\" pButton pRipple icon=\"pi pi-refresh\"\r\n class=\"p-button-rounded p-button-text btnReload\" pTooltip=\"L\u00E0m m\u1EDBi d\u1EEF li\u1EC7u\" tooltipPosition=\"top\"\r\n [disabled]=\"model.loading\" (click)=\"reload()\"></button>\r\n <ng-container *ngIf=\"hasTemplate('headerCheckbox')\">\r\n <ng-container [ngTemplateOutletContext]=\"{crudList: this}\"\r\n [ngTemplateOutlet]=\"getTemplate('headerCheckbox')\"></ng-container>\r\n </ng-container>\r\n <ng-container *ngTemplateOutlet=\"containerSticky\"></ng-container>\r\n </th>\r\n </ng-container>\r\n <th *ngIf=\"!setting.hiddenOrderColumn\" [style.width]=\"widthOrderColumn\" class=\"stt nopad center\"\r\n [class.sticky]=\"setting.stickyColumn\">\r\n {{ 'TT' |translate}}\r\n <ng-container *ngTemplateOutlet=\"containerSticky\"></ng-container>\r\n </th>\r\n <th *ngIf=\"rowExpansion\" class=\"nopad row-expansion-toggle center\" style=\"width: 2.5rem\"\r\n [class.sticky]=\"setting.stickyColumn\">\r\n <ng-container *ngTemplateOutlet=\"containerSticky\"></ng-container>\r\n </th>\r\n <ng-container *ngFor=\"let col of columns; let i = index\">\r\n <th *ngIf=\"col && col.visible && col.field!='function'\" [ngStyle]=\"col.extendData.headerStyle\"\r\n [pTooltip]=\"col.fullLabel\" tooltipStyleClass=\"unset-width\" [class]=\"col.extendData.headerClass\"\r\n [class.first-th]=\"i==0\" [escape]=\"false\" tooltipPosition=\"top\" [tnSortableColumn]=\"col.field\">\r\n <ng-container *ngTemplateOutlet=\"contentTh; context: {$implicit: col}\"></ng-container>\r\n <ng-container *ngIf=\"col.sort || col.sortClient\">\r\n <ng-container *ngTemplateOutlet=\"sortIcon; context: {field: col.field}\"></ng-container>\r\n </ng-container>\r\n </th>\r\n </ng-container>\r\n <th *ngIf=\"enableReorderRow\" style=\"width: 30px\">\r\n <ng-container *ngTemplateOutlet=\"containerSticky\"></ng-container>\r\n </th>\r\n <ng-container *ngTemplateOutlet=\"colFunctionHeader\"></ng-container>\r\n </tr>\r\n <ng-container *ngTemplateOutlet=\"rowHeaderFilter; context: {columns: columns, funcCheckAll: funcCheckAll}\">\r\n </ng-container>\r\n</ng-template>\r\n<ng-template #rowHeaderFilter let-columns=\"columns\" let-funcCheckAll=\"funcCheckAll\">\r\n <tr class=\"filter-row\" *ngIf=\"!setting.hiddenFilterRow\">\r\n <th *ngIf=\"!setting.hiddenCheckbox\" class=\"chkbox nopad center\" [class.sticky]=\"setting.stickyColumn\"\r\n [class.tricheckbox-custom-false]=\"checkedAll === false\" [style.width]=\"widthCheckbox\">\r\n <p-triStateCheckbox [(ngModel)]=\"checkedAll\" binary=\"true\" (onChange)=\"funcCheckAll()\">\r\n </p-triStateCheckbox>\r\n <ng-container *ngTemplateOutlet=\"containerSticky\"></ng-container>\r\n </th>\r\n <th *ngIf=\"!setting.hiddenOrderColumn\" class=\"stt center v-top\" [class.sticky]=\"setting.stickyColumn\">\r\n <div *ngIf=\"!setting.hiddenSetting\" class=\"pick-color-row\" pTooltip=\"C\u1EA5u h\u00ECnh hi\u1EC3n th\u1ECB m\u00E0u\"\r\n tooltipPosition=\"top\" (click)=\"showSettingRowColor()\">\r\n <div></div>\r\n <div></div>\r\n <div></div>\r\n <div></div>\r\n </div>\r\n <ng-container *ngTemplateOutlet=\"containerSticky\"></ng-container>\r\n </th>\r\n <th *ngIf=\"rowExpansion\" class=\"nopad center row-expansion-toggle\" [class.sticky]=\"setting.stickyColumn\">\r\n <ng-container *ngTemplateOutlet=\"containerSticky\"></ng-container>\r\n </th>\r\n <ng-container *ngFor=\"let col of columns; let i = index\">\r\n <th *ngIf=\"col.visible && col.field != 'function'\" class=\"cell-header-filter center\">\r\n <ng-container *ngIf=\"col.allowFilter\">\r\n <ng-container *ngIf=\"col.templateFilter\">\r\n <ng-container [ngTemplateOutlet]=\"col.templateFilter\"\r\n [ngTemplateOutletContext]=\"{col: col, filterData: filterData, onSearch: onSearch, onShowFilterDropdownPanel: onShowFilterDropdownPanel, onHideFilterDropdownPanel: onHideFilterDropdownPanel}\">\r\n </ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"!col.templateFilter\" [ngSwitch]=\"col.controlType\">\r\n <ng-container *ngSwitchCase=\"'dropdown'\">\r\n <ng-container [ngTemplateOutlet]=\"filterDropdown\"\r\n [ngTemplateOutletContext]=\"{col: col.rawColumn}\">\r\n </ng-container>\r\n </ng-container>\r\n <ng-container *ngSwitchCase=\"'number'\">\r\n <ng-container [ngTemplateOutlet]=\"filterNumber\" [ngTemplateOutletContext]=\"{col: col}\">\r\n </ng-container>\r\n </ng-container>\r\n <ng-container *ngSwitchCase=\"'date'\">\r\n <ng-container [ngTemplateOutlet]=\"filterDate\" [ngTemplateOutletContext]=\"{col: col}\">\r\n </ng-container>\r\n </ng-container>\r\n <ng-container *ngSwitchCase=\"'datetime'\">\r\n <ng-container [ngTemplateOutlet]=\"filterDate\" [ngTemplateOutletContext]=\"{col: col}\">\r\n </ng-container>\r\n </ng-container>\r\n <ng-container *ngSwitchDefault>\r\n <ng-container [ngSwitch]=\"col.dataType\">\r\n <ng-container *ngSwitchCase=\"'int'\">\r\n <ng-container [ngTemplateOutlet]=\"filterNumber\"\r\n [ngTemplateOutletContext]=\"{col: col}\">\r\n </ng-container>\r\n </ng-container>\r\n <ng-container *ngSwitchCase=\"'decimal'\">\r\n <ng-container [ngTemplateOutlet]=\"filterNumber\"\r\n [ngTemplateOutletContext]=\"{col: col}\">\r\n </ng-container>\r\n </ng-container>\r\n <ng-container *ngSwitchCase=\"'date'\">\r\n <ng-container [ngTemplateOutlet]=\"filterDate\"\r\n [ngTemplateOutletContext]=\"{col: col}\">\r\n </ng-container>\r\n </ng-container>\r\n <ng-container *ngSwitchCase=\"'datetime'\">\r\n <ng-container [ngTemplateOutlet]=\"filterDate\"\r\n [ngTemplateOutletContext]=\"{col: col}\">\r\n </ng-container>\r\n </ng-container>\r\n <ng-container *ngSwitchCase=\"'boolean'\">\r\n <ng-container [ngTemplateOutlet]=\"filterBoolean\"\r\n [ngTemplateOutletContext]=\"{col: col}\">\r\n </ng-container>\r\n </ng-container>\r\n <ng-container *ngSwitchDefault>\r\n <ng-container [ngTemplateOutlet]=\"filterText\"\r\n [ngTemplateOutletContext]=\"{col: col}\">\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n <ng-container *ngTemplateOutlet=\"containerSticky\"></ng-container>\r\n </th>\r\n </ng-container>\r\n <th *ngIf=\"enableReorderRow\" style=\"width: 30px\">\r\n <ng-container *ngTemplateOutlet=\"containerSticky\"></ng-container>\r\n </th>\r\n <th *ngIf=\"!setting.hiddenFunctionColumn\" class=\"center setting-cell column-function\"\r\n [class.sticky]=\"setting.stickyColumn\">\r\n <button *ngIf=\"!setting.hiddenSetting\" type=\"button\" pButton pRipple icon=\"pi pi-cog\"\r\n class=\"p-button-rounded p-button-text\" pTooltip=\"C\u1EA5u h\u00ECnh hi\u1EC3n th\u1ECB\" tooltipPosition=\"top\"\r\n (click)=\"showSettings()\"></button>\r\n <button *ngIf=\"!setting.hiddenSettingPermission\" type=\"button\" pButton pRipple icon=\"pi pi-users\"\r\n class=\"p-button-rounded p-button-text\" pTooltip=\"Ph\u00E2n quy\u1EC1n d\u1EEF li\u1EC7u\" tooltipPosition=\"left\"\r\n (click)=\"showSettingsPermission()\"></button>\r\n <button *ngIf=\"!setting.hiddenSettingWorkflow\" type=\"button\" pButton pRipple icon=\"pi pi-sitemap\"\r\n class=\"p-button-rounded p-button-text\" pTooltip=\"C\u1EA5u h\u00ECnh quy tr\u00ECnh\" tooltipPosition=\"left\"\r\n (click)=\"showSettingsWorkflow()\"></button>\r\n <button *ngIf=\"!setting.hiddenSettingWorkflowNew\" type=\"button\" pButton pRipple icon=\"pi pi-sitemap\"\r\n class=\"p-button-rounded p-button-text\" pTooltip=\"C\u1EA5u h\u00ECnh quy tr\u00ECnh\" tooltipPosition=\"left\"\r\n (click)=\"showSettingsWorkflowNew()\"></button>\r\n <ng-container *ngTemplateOutlet=\"containerSticky\"></ng-container>\r\n </th>\r\n </tr>\r\n</ng-template>\r\n<ng-template #colFunctionHeader>\r\n <ng-container *ngIf=\"!setting.hiddenFunctionColumn\">\r\n <th class=\"column-function\" [class.sticky]=\"setting.stickyColumn\"\r\n [style.width]=\"widthFunctionColumn || _widthFunctionColumn\">\r\n <div class=\"cell-header-function\">\r\n <span>{{'GRID.FUNCTION'| translate}}</span>\r\n </div>\r\n <ng-container *ngTemplateOutlet=\"containerSticky\"></ng-container>\r\n </th>\r\n </ng-container>\r\n</ng-template>\r\n<ng-template #contentTh let-col>\r\n <ng-container *ngIf=\"templateHeaderContent[col.field]\">\r\n <ng-container *ngTemplateOutlet=\"templateHeaderContent[col.field]\"></ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"!templateHeaderContent[col.field]\">\r\n {{col.label}}\r\n </ng-container>\r\n <ng-container *ngTemplateOutlet=\"containerSticky\"></ng-container>\r\n</ng-template>\r\n<ng-template #trBody let-rowData let-columns=\"columns\" let-index=\"index\" let-expanded=\"expanded\"\r\n let-eventSelectRow=\"eventSelectRow\" let-eventChecked=\"eventChecked\">\r\n <tr [tnReorderableRow]=\"index\" [attr.rowIndex]=\"index\"\r\n [ngClass]=\"mergeClassObj(rowData, { 'ui-state-highlight': rowData._checked })\" [pTooltip]=\"rowData.tooltip\"\r\n tooltipPosition=\"top\" [tooltipStyleClass]=\"rowData.tooltipClass\" [escape]=\"escape\"\r\n (click)=\"eventSelectRow($event, rowData)\">\r\n <ng-container *ngIf=\"!setting.hiddenCheckbox\">\r\n <td [style.width]=\"widthCheckbox\" class=\"chkbox link-or-action cell-checkbox\"\r\n [class.sticky]=\"setting.stickyColumn\">\r\n <ng-container *ngIf=\"!hasTemplate('checkbox')\">\r\n <p-checkbox [(ngModel)]=\"rowData._checked\" binary=\"true\" (onChange)=\"eventChecked(rowData)\">\r\n </p-checkbox>\r\n </ng-container>\r\n <ng-container *ngIf=\"hasTemplate('checkbox')\">\r\n <ng-container [ngTemplateOutlet]=\"getTemplate('checkbox')\"\r\n [ngTemplateOutletContext]=\"{rowData: rowData, rowIndex: index}\"></ng-container>\r\n </ng-container>\r\n <ng-container *ngTemplateOutlet=\"containerSticky\"></ng-container>\r\n </td>\r\n </ng-container>\r\n <td *ngIf=\"!setting.hiddenOrderColumn && (!rowData.hidden || !rowData.hidden[fieldOrder])\"\r\n [style.width]=\"widthOrderColumn\" class=\"stt\" style=\"text-align: center;\"\r\n [class.sticky]=\"setting.stickyColumn\" [attr.colSpan]=\"rowData.colSpan && rowData.colSpan[fieldOrder]\"\r\n [attr.rowSpan]=\"rowData.rowSpan && rowData.rowSpan[fieldOrder]\">\r\n <span class=\"row-card\" [ngStyle]=\"getBookmarkColor(rowData, columns)\"></span>\r\n {{rowData[fieldOrder]}}\r\n <ng-container *ngTemplateOutlet=\"containerSticky\"></ng-container>\r\n </td>\r\n <td *ngIf=\"rowExpansion\" class=\"no-padding center row-expansion-toggle\" [class.sticky]=\"setting.stickyColumn\">\r\n <ng-container *ngTemplateOutlet=\"iconToggleRowData; context: {rowData: rowData, expanded: expanded}\">\r\n </ng-container>\r\n <ng-container *ngTemplateOutlet=\"containerSticky\"></ng-container>\r\n </td>\r\n <ng-container\r\n *ngTemplateOutlet=\"dynamicColBodys; context: {$implicit: columns, rowData: rowData, index: index, expanded: expanded}\">\r\n </ng-container>\r\n <td *ngIf=\"enableReorderRow\" class=\"no-padding center\">\r\n <i class=\"fas fa-arrows-alt\" style=\"cursor:pointer; padding: 8px; color: #555;\" pReorderableRowHandle></i>\r\n <ng-container *ngTemplateOutlet=\"containerSticky\"></ng-container>\r\n </td>\r\n <ng-container *ngIf=\"!setting.hiddenFunctionColumn\">\r\n <td class=\"text-center column-function\" style=\"text-align: center;\" [class.sticky]=\"setting.stickyColumn\">\r\n <div *ngIf=\"hasTemplate('function')\" class=\"p-toolbar-group-center button-group\">\r\n <ng-container [ngTemplateOutlet]=\"getTemplate('function')\"\r\n [ngTemplateOutletContext]=\"{rowData: rowData, rowIndex: index}\"></ng-container>\r\n <ng-container *ngTemplateOutlet=\"containerSticky\"></ng-container>\r\n </div>\r\n <div *ngIf=\"!hasTemplate('function')\" class=\"p-toolbar-group-center button-group\">\r\n <ng-container [ngTemplateOutletContext]=\"{rowData: rowData, rowIndex: index}\"\r\n [ngTemplateOutlet]=\"getTemplate('buttonBefore')\"></ng-container>\r\n <button *ngIf=\"setting.showVersionButton\" type=\"button\" pButton pRipple icon=\"pi pi-calendar\"\r\n class=\"p-button-rounded p-button-success link-or-action\" pTooltip=\"Xem l\u1ECBch s\u1EED phi\u00EAn b\u1EA3n\"\r\n tooltipPosition=\"top\" (click)=\"showListVersion(rowData)\"></button>\r\n <button *ngIf=\"!rowData.hiddenEdit\" type=\"button\" pButton pRipple [disabled]=\"disableEdit(rowData)\"\r\n pTooltip=\"{{'FORM.EDIT' | translate}}\" tooltipPosition=\"top\"\r\n class=\"p-button-rounded p-button-text p-button-info link-or-action\" icon=\"pi pi-pencil\"\r\n (click)=\"edit(rowData)\"></button>\r\n <button *ngIf=\"!rowData.hiddenDelete\" type=\"button\" pButton pRipple\r\n [disabled]=\"disableDelete(rowData)\" pTooltip=\"{{'FORM.DELETE' | translate}}\"\r\n tooltipPosition=\"top\" class=\"p-button-rounded p-button-text p-button-danger link-or-action\"\r\n icon=\"pi pi-trash\" (click)=\"delete(rowData)\"></button>\r\n <button *ngIf=\"!rowData.hiddenCopyLink\" type=\"button\" pButton pRipple\r\n [disabled]=\"disableCopyLink(rowData)\" pTooltip=\"{{'Sao ch\u00E9p li\u00EAn k\u1EBFt' | translate}}\"\r\n tooltipPosition=\"top\" class=\"p-button-rounded p-button-text p-button-info link-or-action\"\r\n icon=\"pi pi-link\" (click)=\"copyLink(rowData)\"></button>\r\n <button *ngIf=\"this.menuButtons\" type=\"button\" pButton icon=\"pi pi-ellipsis-v\"\r\n class=\"link-or-action p-button-text p-button-info p-button-rounded\" pTooltip=\"Ch\u1EE9c n\u0103ng kh\u00E1c\"\r\n tooltipPosition=\"top\" (click)=\"showContextMenu($event, rowData)\"></button>\r\n </div>\r\n <ng-container *ngTemplateOutlet=\"containerSticky\"></ng-container>\r\n </td>\r\n </ng-container>\r\n </tr>\r\n</ng-template>\r\n<ng-template #dynamicColBodys let-columns let-rowData=\"rowData\" let-index=\"index\" let-expanded=\"expanded\">\r\n <ng-container *ngFor=\"let col of columns; let i = index\">\r\n <ng-container\r\n *ngTemplateOutlet=\"contentTd; context: {$implicit: rowData, col: col, index: index, i: i, expanded: expanded}\">\r\n </ng-container>\r\n </ng-container>\r\n</ng-template>\r\n<ng-template #contentTd let-rowData let-col=\"col\" let-index=\"index\" let-expanded=\"expanded\" let-i=\"i\">\r\n <td *ngIf=\"col && col.visible && col.field != 'function' && (!rowData.hidden || !rowData.hidden[col.field])\"\r\n [attr.colSpan]=\"rowData.colSpan && rowData.colSpan[col.field]\"\r\n [attr.rowSpan]=\"rowData.rowSpan && rowData.rowSpan[col.field]\" [ngStyle]=\"col.extendData.style\"\r\n [class]=\"col.cellClass\" [class.first-td]=\"i == 0\">\r\n <span *ngIf=\"col.pipe\">\r\n <span class=\"p-column-title\" [pTooltip]=\"col.fullLabel\" [escape]=\"false\"\r\n tooltipPosition=\"top\">{{col.label}}</span>\r\n {{rowData['pipe__' + col.field]}}\r\n </span>\r\n <span *ngIf=\"!col.pipe\">\r\n <span class=\"p-column-title\" [pTooltip]=\"col.fullLabel\" [escape]=\"false\"\r\n tooltipPosition=\"top\">{{col.label}}</span>\r\n <span *ngIf=\"setting.showEditLink && col.showEditLink\" [pTooltip]=\"config.tooltipView\" tooltipPosition=\"top\"\r\n class=\"link-or-action\">\r\n <a href=\"javascript:;\" (click)=\"view(rowData)\" [pTooltip]=\"config.tooltipView\" tooltipPosition=\"top\">\r\n <ng-container [ngTemplateOutlet]=\"contentCell\"\r\n [ngTemplateOutletContext]=\"getContextCell(rowData, index, col, expanded, this)\">\r\n </ng-container>\r\n </a>\r\n </span>\r\n <span *ngIf=\"!setting.showEditLink || !col.showEditLink\">\r\n <ng-container [ngTemplateOutlet]=\"contentCell\"\r\n [ngTemplateOutletContext]=\"getContextCell(rowData, index, col, expanded, this)\">\r\n </ng-container>\r\n </span>\r\n </span>\r\n <ng-container *ngTemplateOutlet=\"containerSticky\"></ng-container>\r\n </td>\r\n</ng-template>\r\n<ng-template #contentCell let-col=\"col\" let-rowData=\"rowData\" let-rowIndex=\"rowIndex\" let-field=\"field\"\r\n let-expanded=\"expanded\">\r\n <ng-container *ngIf=\"col.template\">\r\n <ng-container [ngTemplateOutlet]=\"col.template\"\r\n [ngTemplateOutletContext]=\"getContextCell(rowData, rowIndex, col, expanded,this)\">\r\n </ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"!col.template\">\r\n <ng-container [ngSwitch]=\"col.dataType\">\r\n <span *ngSwitchCase=\"'color'\" style=\"display:block;text-align:center;\">\r\n <div pTooltip=\"{{rowData[field]}}\" tooltipPosition=\"top\" [ngStyle]=\"{'background-color':rowData[field]}\"\r\n style=\"width:30px;height:30px;margin:0 auto;\"></div>\r\n </span>\r\n <span *ngSwitchCase=\"'icon'\" style=\"display:block;text-align:center;\">\r\n <i pTooltip=\"{{rowData[field]}}\" tooltipPosition=\"top\" style=\"text-align: center;\"\r\n [ngClass]=\"rowData[field]\"></i>\r\n </span>\r\n <span *ngSwitchCase=\"'date'\" pTooltip=\"{{rowData[field] | date:'dd/MM/yyyy'}}\" tooltipPosition=\"top\">\r\n {{_crudService.renderDate(rowData[field], col.format)}}\r\n </span>\r\n <span *ngSwitchCase=\"'datetime'\" pTooltip=\"{{rowData[field] | date:'dd/MM/yyyy HH:mm'}}\"\r\n tooltipPosition=\"top\">\r\n {{_crudService.renderDateTime(rowData[field], col.format)}}\r\n </span>\r\n <span *ngSwitchCase=\"'user'\" class=\"user\">\r\n {{rowData[field] | userFormat | async}}\r\n </span>\r\n <div *ngSwitchCase=\"'users'\" [innerHTML]=\"rowData[field] | usersFormat | async\">\r\n </div>\r\n <span *ngSwitchCase=\"'int'\">\r\n {{rowData[field]}}\r\n </span>\r\n <span *ngSwitchCase=\"'decimal'\">\r\n {{rowData[field]}}\r\n </span>\r\n <span *ngSwitchCase=\"'boolean'\">\r\n <p-checkbox class=\"boolean-data-type\" [(ngModel)]=\"rowData[field]\" binary=\"true\"\r\n [disabled]=\"col.disableCheckBox\">\r\n </p-checkbox>\r\n </span>\r\n <span *ngSwitchCase=\"'html'\">\r\n <div *ngIf=\"rowData[field]==null?'':rowData[field]\" [innerHTML]=\"rowData[field] | safeHtml\"></div>\r\n </span>\r\n <span *ngSwitchCase=\"'metadataStatus'\">\r\n <span *ngIf=\"rowData['rejectReason']\" class=\"label-danger\" [pTooltip]=\"rowData['rejectReason']\"\r\n tooltipStyleClass=\"unset-width\" [escape]=\"false\" tooltipPosition=\"top\">T\u1EEB ch\u1ED1i</span>\r\n <span *ngIf=\"rowData[field] == '0' && !rowData['rejectReason']\" class=\"label-secondary\">Ch\u01B0a\r\n duy\u1EC7t</span>\r\n <span *ngIf=\"rowData[field] == '1' && !rowData['rejectReason']\" class=\"label-warning\">Ch\u1EDD duy\u1EC7t</span>\r\n <span *ngIf=\"rowData[field] == '2'\" class=\"label-primary\">\u0110\u00E3 duy\u1EC7t</span>\r\n </span>\r\n <ng-container *ngSwitchCase=\"'string'\">\r\n <ng-container *ngTemplateOutlet=\"contentCellString; context: {$implicit: rowData, field: col.field}\">\r\n </ng-container>\r\n </ng-container>\r\n <ng-container *ngSwitchCase=\"null\">\r\n <ng-container *ngTemplateOutlet=\"contentCellString; context: {$implicit: rowData, field: col.field}\">\r\n </ng-container>\r\n </ng-container>\r\n <ng-container *ngSwitchDefault>\r\n <ng-container [ngTemplateOutlet]=\"getComponentByType(col.dataType)\"\r\n [ngTemplateOutletContext]=\"getContextCell(rowData, rowIndex, col, expanded, this)\">\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n </ng-container>\r\n</ng-template>\r\n<ng-template #contentCellString let-rowData let-field=\"field\">\r\n <span>\r\n <!-- __sv: Short Value -->\r\n <ng-container *ngIf=\"rowData[field + '__sv']\">\r\n <ng-container *ngIf=\"!rowData[field + '__showFull']\">\r\n {{rowData[field + '__sv']}}\r\n <span class=\"toggle-showfull\" (click)=\"toggleShowFull(rowData, field)\" pTooltip=\"B\u1EA5m \u0111\u1EC3 xem th\u00EAm\"\r\n tooltipPosition=\"top\">[...]</span>\r\n </ng-container>\r\n <ng-container *ngIf=\"rowData[field + '__showFull']\">\r\n {{rowData[field]}}\r\n <span class=\"toggle-showfull\" (click)=\"toggleShowFull(rowData, field)\">Thu g\u1ECDn</span>\r\n </ng-container>\r\n </ng-container>\r\n <ng-container *ngIf=\"!rowData[field + '__sv']\">\r\n {{rowData[field]}}\r\n </ng-container>\r\n </span>\r\n</ng-template>\r\n<ng-template #iconToggleRowGroup let-rowData=\"rowData\" let-expanded=\"expanded\">\r\n <a href=\"javascript:;\" (click)=\"handleToggleRow(rowData, $event)\">\r\n <i style=\"margin-right:5px\" [ngClass]=\"expanded ? 'fas fa-fw fa-caret-down' : 'fas fa-fw fa-caret-right'\"></i>\r\n </a>\r\n</ng-template>\r\n<ng-template #iconToggleRowData let-rowData=\"rowData\" let-expanded=\"expanded\">\r\n <button type=\"button\" pButton pRipple class=\"link-or-action p-button-text p-button-rounded p-button-plain\"\r\n [icon]=\"expanded ? 'pi pi-chevron-down' : 'pi pi-chevron-right'\"\r\n (click)=\"handleToggleRow(rowData, $event)\"></button>\r\n</ng-template>\r\n<ng-template #_contentRowGroup let-rowData=\"rowData\" let-groupCol=\"groupCol\" let-groupField=\"_groupField\">\r\n <ng-container [ngTemplateOutlet]=\"contentCell\"\r\n [ngTemplateOutletContext]=\"{rowData: rowData, col: groupCol, field: _groupField}\">\r\n </ng-container>\r\n <span> ({{rowGroupMetadata[rowData[_groupField]].size}})</span>\r\n</ng-template>\r\n<ng-template #entityWorkflowStatus let-rowData=\"rowData\">\r\n <div class=\"container-text-workflow\">\r\n <span class=\"content\">{{rowData.statusString ? rowData.statusString : rowData.strcurrentStateCode}}</span>\r\n <button *ngIf=\"!rowData.hiddenWorkflowAction\" type=\"button\" pButton icon=\"pi pi-ellipsis-v\"\r\n class=\"link-or-action p-button-text p-button-rounded\" pTooltip=\"H\u00E0nh \u0111\u1ED9ng\" tooltipPosition=\"top\"\r\n (click)=\"showActionWorkflow($event, rowData)\"></button>\r\n </div>\r\n</ng-template>\r\n<ng-template #trangThaiV5 let-rowData=\"rowData\">\r\n <div class=\"container-text-workflow\">\r\n <button *ngIf=\"!rowData.__workflowCode\" pButton class=\"p-button-text link-or-action\" label=\"B\u1EAFt \u0111\u1EA7u\"\r\n style=\"border: 1px solid #7ca9cd;\" pTooltip=\"B\u1EAFt \u0111\u1EA7u ch\u1EA1y quy tr\u00ECnh\" tooltipPosition=\"top\"\r\n (click)=\"showFormStartWorkflow(rowData)\"></button>\r\n <ng-container *ngIf=\"rowData.__workflowCode\">\r\n <span class=\"content\">{{rowData.__textTrangThai}}</span>\r\n <button *ngIf=\"!rowData.hiddenWorkflowAction\" type=\"button\" pButton icon=\"pi pi-ellipsis-v\"\r\n class=\"link-or-action p-button-text p-button-rounded\" pTooltip=\"H\u00E0nh \u0111\u1ED9ng\" tooltipPosition=\"top\"\r\n [disabled]=\"showingActionWorkflow\" (click)=\"showActionWorkflowNew($event, rowData)\"></button>\r\n </ng-container>\r\n </div>\r\n</ng-template>\r\n<ng-template #viewHistory let-rowData=\"rowData\">\r\n <button pButton icon=\"pi pi-calendar\" class=\"p-button-text p-button-rounded link-or-action\" pTooltip=\"Xem l\u1ECBch s\u1EED\"\r\n tooltipPosition=\"top\" (click)=\"viewHistoryWorkflowNew(rowData)\"></button>\r\n</ng-template>\r\n<ng-template #workflowCoreStatus let-rowData=\"rowData\">\r\n <div class=\"container-text-workflow\">\r\n <a class=\"content\" (click)=\"goToTask($event)\" href=\"javascript:;\">{{rowData.strworkflowCoreStatus}}</a>\r\n </div>\r\n</ng-template>\r\n<ng-template #containerSticky>\r\n <span class=\"fix-sticky top\"></span>\r\n <span class=\"fix-sticky right\"></span>\r\n <!-- <span class=\"fix-sticky bottom\"></span> -->\r\n <span class=\"fix-sticky left\"></span>\r\n</ng-template>\r\n<ng-template #sortIcon let-field=\"field\">\r\n <i class=\"p-sortable-column-icon pi\" style=\"font-size: 0.8em;\"\r\n [ngClass]=\"{'pi-sort-amount-up-alt': field == _sortField && _sortDir === 1, 'pi-sort-amount-down': field == _sortField && _sortDir === -1, 'pi-sort-alt': field != _sortField || _sortDir === 0}\"></i>\r\n</ng-template>\r\n<ng-template #filterDropdown let-col=\"col\">\r\n <div #filterBox style=\"width: 100%; border-radius: 4px;\">\r\n <dropdown *ngIf=\"col && filterSchema.dropdown[col.field]\" [control]=\"filterSchema.dropdown[col.field]\"\r\n [dataSource]=\"filterSchema.dropdown[col.field].dataSource\" [(value)]=\"filterData[col.field]\"\r\n (onHideSmartEvent)=\"onSearch()\" (onShow)=\"onShowFilterDropdownPanel($event)\"\r\n (onHide)=\"onHideFilterDropdownPanel($event)\" (mousedown)=\"initFilterBoxFocus(filterBox)\"></dropdown>\r\n </div>\r\n</ng-template>\r\n<ng-template #filterText let-col=\"col\">\r\n <div #filterBox class=\"text-filter filter-box\" tabindex=\"-1\" (mousedown)=\"initFilterBoxFocus(filterBox)\">\r\n <div tabindex=\"-1\">\r\n <input pInputText type=\"text\" class=\"input-search\" [placeholder]=\"col.label\"\r\n [(ngModel)]=\"filterData[col.field]\" (change)=\"onSearch()\"\r\n (keyup.esc)=\"onClearSearch(filterBox, col.field)\">\r\n </div>\r\n <span [ngClass]=\"{'action-clear': true, 'dirty': filterData[col.field] != null && filterData[col.field] !== ''}\"\r\n [pTooltip]=\"'B\u1ECF filter'\" tooltipPosition=\"top\" (mousedown)=\"onClearSearch(filterBox, col.field)\"\r\n tabindex=\"-1\"><i class=\"pi pi-filter-slash\"></i></span>\r\n <after-view-checked style=\"display: none;\" (loaded)=\"initFilterBoxFocus(filterBox)\">\r\n </after-view-checked>\r\n </div>\r\n</ng-template>\r\n<ng-template #filterNumber let-col=\"col\">\r\n <div #filterBox class=\"number-picker-range filter-box\" tabindex=\"-1\" (mousedown)=\"initFilterBoxFocus(filterBox)\">\r\n <div tabindex=\"-1\">\r\n <tn-number-picker-range #numberRange [maskType]=\"col.dataType\" [(ngModel)]=\"filterData[col.field]\"\r\n [min]=\"col.min\" [max]=\"col.max\" (change)=\"onSearch()\">\r\n </tn-number-picker-range>\r\n </div>\r\n <span\r\n [ngClass]=\"{'action-clear': true, 'dirty': filterData[col.field] && ((filterData[col.field][0] != null && filterData[col.field][0] !== '') || (filterData[col.field][1] != null && filterData[col.field][1] !== ''))}\"\r\n [pTooltip]=\"'B\u1ECF filter'\" tooltipPosition=\"top\" (mousedown)=\"onClearNumberSearch(filterBox, numberRange)\"\r\n tabindex=\"-1\">\r\n <i class=\"pi pi-filter-slash\"></i></span>\r\n <after-view-checked style=\"display: none;\" (loaded)=\"initFilterBoxFocus(filterBox)\">\r\n </after-view-checked>\r\n </div>\r\n</ng-template>\r\n<ng-template #filterDate let-col=\"col\">\r\n <div #filterBox class=\"date-picker-range filter-box\" tabindex=\"-1\" (mousedown)=\"initFilterBoxFocus(filterBox)\">\r\n <div tabindex=\"-1\">\r\n <tn-datetime-picker-range #dateRange [control]=\"filterSchema.dateRange\"\r\n (onChanged)=\"onChangeDateTime($event, col.field)\">\r\n </tn-datetime-picker-range>\r\n </div>\r\n <span\r\n [ngClass]=\"{'action-clear': true, 'dirty': filterData[col.field] && ((filterData[col.field][0] != null && filterData[col.field][0] !== '') || (filterData[col.field][1] != null && filterData[col.field][1] !== ''))}\"\r\n [pTooltip]=\"'B\u1ECF filter'\" tooltipPosition=\"top\"\r\n (mousedown)=\"onClearDateSearch(filterBox, dateRange, col.field)\" tabindex=\"-1\"><i\r\n class=\"pi pi-filter-slash\"></i></span>\r\n <after-view-checked style=\"display: none;\" (loaded)=\"initFilterBoxFocus(filterBox)\">\r\n </after-view-checked>\r\n </div>\r\n</ng-template>\r\n<ng-template #filterBoolean let-col=\"col\">\r\n <div class=\"filter-boolean-box\">\r\n <p-selectButton\r\n [options]=\"[{value: true, label: 'C\u00F3', icon: 'pi pi-check'}, {value: false, label: 'Kh\u00F4ng', icon: 'pi pi-times'}]\"\r\n [multiple]=\"true\" [(ngModel)]=\"filterData[col.field]\" (onChange)=\"onChangeBoolean($event, col.field)\">\r\n <ng-template let-item>\r\n <i style=\"padding: 3px 0;\" [class]=\"item.icon\"></i>\r\n </ng-template>\r\n </p-selectButton>\r\n </div>\r\n</ng-template>",
|
|
18346
18449
|
providers: [DecimalPipe, DatePipe],
|
|
18347
18450
|
styles: [".container-table{display:flex;flex-direction:column;overflow:hidden}.container-table .container-table-inner{display:flex;height:auto;max-height:100%;min-height:60px;position:relative}.container-table-inner>tn-custom-scrollbar{width:100%}.cell-checkbox{text-align:center}.pick-color-row{border:1px solid #d1d1d1;border-radius:2px;bottom:0;cursor:pointer;display:flex;flex-wrap:wrap;height:1.4em;left:0;margin:auto;position:absolute;right:0;top:0;width:1.4em}.pick-color-row>div{background:#84d140;border:1px solid #fff;flex:0 0 50%}.pick-color-row>div:nth-child(2){background:#fc6868}.pick-color-row>div:nth-child(3){background:#fbc02d}.pick-color-row>div:nth-child(4){background:#7dc5ff}.cell-header-function{align-items:center;display:flex}.cell-header-function>span{flex:1 1;text-align:center}.cell-header-function button{height:24px;margin:0;padding:0;width:24px}.group-icon{color:#256aa2;font-weight:400}.group-icon i{font-size:.8em;margin-right:5px}.center{text-align:center!important}.row-card{height:100%;left:0;position:absolute;top:0;width:5px}.column-function{min-width:80px;padding:0}.custom-search-area{background-color:#f2f2f2;margin:-.5em -1em .5em;padding-left:.5em;padding-right:.5em}.main-container-search-inner{margin-bottom:-.5em}.main-title>h1{font-size:1.2em}.filter-row>th:not(.sticky):not(.chkbox){padding:3px!important}.container-text-workflow{align-items:center;display:flex;justify-content:center}.container-text-workflow .link-or-action{color:#2196f3;cursor:pointer}.container-text-workflow .content{flex:1 1}.btnReload{height:2rem;left:50%;position:absolute;top:50%;transform:translate(-50%,calc(-50% - 1px));width:2rem}.toggle-showfull{color:#00f;cursor:pointer;font-size:.8rem;font-weight:700;white-space:nowrap}::ng-deep crud-list .advance-search-container{display:flex;justify-content:flex-end}::ng-deep crud-list advance-search{display:block;flex:1;max-width:400px}::ng-deep crud-list .ps__rail-x,::ng-deep crud-list .ps__rail-y{z-index:5}::ng-deep crud-list .p-datatable .p-datatable-thead>tr>th.cell-fixed-filter{z-index:999}::ng-deep crud-list .p-datatable .p-datatable-thead>tr>th.cell-fixed-filter .fixed-filter{min-width:200px;position:fixed;z-index:10}::ng-deep crud-list .p-datatable .p-datatable-thead>tr>th .container-icon-loading{left:50%;position:absolute;top:50%;transform:translate(-50%,-50%)}::ng-deep crud-list .check-all-custom{height:0;position:absolute;width:0}::ng-deep crud-list .cell-header-filter{position:relative}::ng-deep crud-list .cell-header-filter .tn-dropdown{height:32px}::ng-deep crud-list .cell-header-filter tn-mask .p-inputtext{width:100%}::ng-deep crud-list .cell-header-filter .filter-box{background-color:#fff;border-radius:3px;display:flex;min-width:0}::ng-deep crud-list .cell-header-filter .filter-box>div{border:1px solid #ced4da;border-radius:3px 0 0 3px;border-right:none;flex:1;outline:none;overflow:hidden}::ng-deep crud-list .cell-header-filter .filter-box>span{align-items:center;background:#f5f6f8;border:1px solid #ced4da;color:#6c757d;cursor:pointer;display:inline-flex;flex-basis:32px;height:32px;justify-content:center;min-width:unset;outline:none}::ng-deep crud-list .cell-header-filter .filter-box>span.action-clear{border-radius:0 3px 3px 0}::ng-deep crud-list .cell-header-filter .filter-box>span.action-clear.dirty{color:#008eff}::ng-deep crud-list .cell-header-filter .filter-box input{border:none;box-shadow:none!important;padding-left:5px;padding-right:5px}::ng-deep crud-list .cell-header-filter .filter-box:not(.no-transition){transition:min-width .1s}::ng-deep crud-list .cell-header-filter .filter-box.boolean-filter>div{flex:0 0 109px;width:109px}::ng-deep crud-list .cell-header-filter .p-multiselect-label.p-placeholder{padding-left:.5rem;padding-right:.5rem}::ng-deep crud-list .cell-header-filter.focus-within,::ng-deep crud-list .cell-header-filter:focus-within{z-index:10!important}::ng-deep crud-list .cell-header-filter.focus-within .filter-boolean-box .p-button,::ng-deep crud-list .cell-header-filter:focus-within .filter-boolean-box .p-button{z-index:10}::ng-deep crud-list .cell-header-filter.focus-within .filter-box>div,::ng-deep crud-list .cell-header-filter:focus-within .filter-box>div{border-color:#2196f3;box-shadow:0 0 0 .2rem #a6d5fa;z-index:0}::ng-deep crud-list .cell-header-filter.focus-within .short-filter-box,::ng-deep crud-list .cell-header-filter:focus-within .short-filter-box{box-shadow:5px 0 15px 1px rgba(0,0,0,.27058823529411763);min-width:250px;position:absolute;top:calc(50% - 16px);z-index:2}::ng-deep crud-list .cell-header-filter.focus-within .short-filter-box>div,::ng-deep crud-list .cell-header-filter:focus-within .short-filter-box>div{border-color:#2196f3;box-shadow:0 0 0 .2rem #a6d5fa;flex:1;z-index:0}::ng-deep crud-list .cell-header-filter.focus-within .short-filter-box>span.action-clear,::ng-deep crud-list .cell-header-filter:focus-within .short-filter-box>span.action-clear{display:flex}::ng-deep crud-list .cell-header-filter.focus-within .short-filter-box.boolean-filter,::ng-deep crud-list .cell-header-filter:focus-within .short-filter-box.boolean-filter{min-width:140px}::ng-deep crud-list .cell-header-filter.focus-within .short-filter-box.boolean-filter>div,::ng-deep crud-list .cell-header-filter:focus-within .short-filter-box.boolean-filter>div{flex:0 0 109px;width:109px}::ng-deep crud-list .cell-header-filter.focus-within:nth-last-child(2) .short-filter-box,::ng-deep crud-list .cell-header-filter:focus-within:nth-last-child(2) .short-filter-box{left:50%;transform:translateX(-50%)}::ng-deep crud-list .cell-header-filter:last-child .filter-box{right:3px}::ng-deep crud-list .table-border-line{background-color:#eee;position:absolute;z-index:5}::ng-deep crud-list .table-border-line.--left,::ng-deep crud-list .table-border-line.--right{bottom:0;top:0;width:1px}::ng-deep crud-list .table-border-line.--bottom,::ng-deep crud-list .table-border-line.--top{height:1px;left:0;right:0}::ng-deep crud-list .table-border-line.--left{left:0}::ng-deep crud-list .table-border-line.--right{right:0}::ng-deep crud-list .table-border-line.--top{top:0}::ng-deep crud-list .table-border-line.--bottom{bottom:0}::ng-deep crud-list .filter-boolean-box{text-align:center}::ng-deep crud-list .filter-boolean-box .p-selectbutton{white-space:nowrap}::ng-deep crud-list .custom-search-area crud-form{width:100%}::ng-deep crud-list>p-contextmenu{display:none}@media (max-width:640px){::ng-deep crud-list .--table-responsive .p-datatable-wrapper{padding:1px}}"]
|
|
18348
18451
|
},] }
|
|
@@ -18407,6 +18510,7 @@ CrudListComponent.propDecorators = {
|
|
|
18407
18510
|
templatesFromParent: [{ type: Input }],
|
|
18408
18511
|
childrenFromParent: [{ type: Input }],
|
|
18409
18512
|
menuButtons: [{ type: Input }],
|
|
18513
|
+
disableShare: [{ type: Input }],
|
|
18410
18514
|
fieldOrder: [{ type: Input }],
|
|
18411
18515
|
style: [{ type: Input }],
|
|
18412
18516
|
tableClass: [{ type: Input }],
|
|
@@ -18629,15 +18733,19 @@ class DataListBase extends ComponentBase {
|
|
|
18629
18733
|
}
|
|
18630
18734
|
this.checkAllowTrinhKy = this.checkAllowTrinhKy.bind(this);
|
|
18631
18735
|
this.setting.checkAllowTrinhKy = this.checkAllowTrinhKy;
|
|
18736
|
+
this.setting.getItemState = this.getItemState;
|
|
18737
|
+
this.getItemState = this.getItemState.bind(this);
|
|
18632
18738
|
this.getMenuButtons = this.getMenuButtons.bind(this);
|
|
18633
18739
|
this.loadItemFromQueryParam();
|
|
18634
18740
|
}
|
|
18635
18741
|
loadItemFromQueryParam() {
|
|
18636
18742
|
if (this.loadDetailFromQueryParam === undefined || this.loadDetailFromQueryParam === true) {
|
|
18637
18743
|
let idInQueryString = null;
|
|
18744
|
+
let pid = null; // permission Id được người khác share
|
|
18638
18745
|
if (this._activatedRoute.snapshot
|
|
18639
18746
|
&& this._activatedRoute.snapshot.queryParams) {
|
|
18640
18747
|
idInQueryString = this._activatedRoute.snapshot.queryParams.id;
|
|
18748
|
+
pid = this._activatedRoute.snapshot.queryParams.pid;
|
|
18641
18749
|
}
|
|
18642
18750
|
if (idInQueryString) {
|
|
18643
18751
|
// get detail data
|
|
@@ -18658,8 +18766,30 @@ class DataListBase extends ComponentBase {
|
|
|
18658
18766
|
this._notifierService.showWarning('Không tìm thấy bản ghi cần xem chi tiết');
|
|
18659
18767
|
});
|
|
18660
18768
|
}
|
|
18769
|
+
else if (pid) {
|
|
18770
|
+
this.loadDetailPid(pid);
|
|
18771
|
+
}
|
|
18661
18772
|
}
|
|
18662
18773
|
}
|
|
18774
|
+
loadDetailPid(pid) {
|
|
18775
|
+
this.setting.baseService.getDetailByPid(pid)
|
|
18776
|
+
.then(res => this.handleResponse(res, '', f => {
|
|
18777
|
+
if (!res.data) {
|
|
18778
|
+
this._notifierService.showWarning('Không tìm thấy bản ghi cần xem chi tiết');
|
|
18779
|
+
}
|
|
18780
|
+
if ((res.data.basePermission & PermissionBase.EDIT) == PermissionBase.EDIT
|
|
18781
|
+
|| (res.data.basePermission & PermissionBase.READ) == PermissionBase.READ) {
|
|
18782
|
+
res.data.pid = pid;
|
|
18783
|
+
this._edit(res.data);
|
|
18784
|
+
}
|
|
18785
|
+
else {
|
|
18786
|
+
this._notifierService.showWarning('Bạn không có quyền xem bản ghi');
|
|
18787
|
+
}
|
|
18788
|
+
})).catch(err => {
|
|
18789
|
+
console.error('error on get detail from querystring', err);
|
|
18790
|
+
this._notifierService.showWarning('Không tìm thấy bản ghi cần xem chi tiết');
|
|
18791
|
+
});
|
|
18792
|
+
}
|
|
18663
18793
|
ngAfterViewInit() {
|
|
18664
18794
|
this.handleAfterViewInit();
|
|
18665
18795
|
}
|
|
@@ -18850,6 +18980,15 @@ class DataListBase extends ComponentBase {
|
|
|
18850
18980
|
this.crudList.buildFilterColumn([colForAdmin]);
|
|
18851
18981
|
}
|
|
18852
18982
|
}
|
|
18983
|
+
getItemState(lstRowData) {
|
|
18984
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
18985
|
+
const result = {};
|
|
18986
|
+
lstRowData.forEach(item => {
|
|
18987
|
+
result[item.id] = {};
|
|
18988
|
+
});
|
|
18989
|
+
return result;
|
|
18990
|
+
});
|
|
18991
|
+
}
|
|
18853
18992
|
checkAllowTrinhKy(rowData) {
|
|
18854
18993
|
return __awaiter(this, void 0, void 0, function* () {
|
|
18855
18994
|
return true;
|
|
@@ -18981,6 +19120,7 @@ class DataListBase extends ComponentBase {
|
|
|
18981
19120
|
}
|
|
18982
19121
|
cloneData(rowData) {
|
|
18983
19122
|
return {
|
|
19123
|
+
pid: rowData.pid,
|
|
18984
19124
|
id: rowData[this.setting.entityKey]
|
|
18985
19125
|
};
|
|
18986
19126
|
}
|
|
@@ -19008,7 +19148,7 @@ class DataListBase extends ComponentBase {
|
|
|
19008
19148
|
this._notifierService.showDeleteDataSuccess();
|
|
19009
19149
|
}
|
|
19010
19150
|
else {
|
|
19011
|
-
this._notifierService.
|
|
19151
|
+
this._notifierService.showWarningByResponse(response);
|
|
19012
19152
|
}
|
|
19013
19153
|
}, error => {
|
|
19014
19154
|
this._notifierService.showDeleteDataError();
|
|
@@ -19032,7 +19172,7 @@ class DataListBase extends ComponentBase {
|
|
|
19032
19172
|
this._notifierService.showDeleteDataSuccess();
|
|
19033
19173
|
}
|
|
19034
19174
|
else {
|
|
19035
|
-
this._notifierService.
|
|
19175
|
+
this._notifierService.showWarningByResponse(response);
|
|
19036
19176
|
}
|
|
19037
19177
|
});
|
|
19038
19178
|
}
|
|
@@ -19244,7 +19384,7 @@ class DataListBase extends ComponentBase {
|
|
|
19244
19384
|
const dataStatus = (yield this._workflowPermissionDetailService.getAll([
|
|
19245
19385
|
this.newFilter('itemId', Operator.in, dataSource.map(q => q.id)),
|
|
19246
19386
|
this.newFilter('userId', Operator.equal, userIdCurrent)
|
|
19247
|
-
], 'itemId,userId,trangThai,textTrangThai,workflowCode,
|
|
19387
|
+
], 'itemId,userId,trangThai,textTrangThai,workflowCode,permission')).data;
|
|
19248
19388
|
if (dataStatus == null) {
|
|
19249
19389
|
return this._notifierService.showWarning('Không lấy được thông tin trạng thái hiện tại của bản ghi');
|
|
19250
19390
|
}
|
|
@@ -19257,7 +19397,7 @@ class DataListBase extends ComponentBase {
|
|
|
19257
19397
|
};
|
|
19258
19398
|
}
|
|
19259
19399
|
else {
|
|
19260
|
-
itemStatus = lstItemStatus.find(q => q.
|
|
19400
|
+
itemStatus = lstItemStatus.find(q => (q.permission & PermissionBase.EDIT) == PermissionBase.EDIT);
|
|
19261
19401
|
if (itemStatus == null) {
|
|
19262
19402
|
itemStatus = lstItemStatus[0];
|
|
19263
19403
|
}
|
|
@@ -19265,7 +19405,6 @@ class DataListBase extends ComponentBase {
|
|
|
19265
19405
|
rowItem.__trangThai = itemStatus.trangThai;
|
|
19266
19406
|
rowItem.__textTrangThai = itemStatus.textTrangThai;
|
|
19267
19407
|
rowItem.__workflowCode = itemStatus.workflowCode;
|
|
19268
|
-
rowItem.__allowEdit = itemStatus.allowEdit;
|
|
19269
19408
|
rowItem.__permission = itemStatus.permission;
|
|
19270
19409
|
rowItem.__disableEdit = true;
|
|
19271
19410
|
rowItem.__disableDelete = true;
|
|
@@ -28880,6 +29019,8 @@ class FileManagerComponent extends DataListBase {
|
|
|
28880
29019
|
},
|
|
28881
29020
|
breadcrumbs: []
|
|
28882
29021
|
};
|
|
29022
|
+
this.showAttachLinkBox = false;
|
|
29023
|
+
this.typedLink = '';
|
|
28883
29024
|
this._moduleConfig = this._moduleConfigService.getConfig();
|
|
28884
29025
|
this.apiUploadUrl = this._fileObjectService.getUploadUrl();
|
|
28885
29026
|
this.userId = this._userService.getUserIdCombine();
|
|
@@ -29122,30 +29263,35 @@ class FileManagerComponent extends DataListBase {
|
|
|
29122
29263
|
visible: this._deviceDetectorService.isDesktop()
|
|
29123
29264
|
},
|
|
29124
29265
|
{
|
|
29125
|
-
label: '
|
|
29126
|
-
this.
|
|
29127
|
-
}
|
|
29266
|
+
label: 'Ký số', icon: 'fas fa-signature', command: () => {
|
|
29267
|
+
this.signFile(item);
|
|
29268
|
+
},
|
|
29269
|
+
visible: !this.readonly
|
|
29128
29270
|
},
|
|
29129
29271
|
{
|
|
29130
|
-
label: 'Tải về
|
|
29272
|
+
label: 'Tải về', icon: 'fas fa-download', command: () => {
|
|
29131
29273
|
this.download(item);
|
|
29132
29274
|
}
|
|
29133
29275
|
},
|
|
29134
29276
|
{
|
|
29135
|
-
label: '
|
|
29136
|
-
this.
|
|
29137
|
-
}
|
|
29138
|
-
visible: !this.readonly
|
|
29277
|
+
label: 'Sao chép đường dẫn', icon: 'fas fa-link', command: () => {
|
|
29278
|
+
this.copyDownloadLink(item);
|
|
29279
|
+
}
|
|
29139
29280
|
},
|
|
29140
29281
|
{
|
|
29141
|
-
label: '
|
|
29142
|
-
this.
|
|
29282
|
+
label: 'Đổi tên', icon: 'fas fa-eraser', command: () => {
|
|
29283
|
+
this.renameFile(item);
|
|
29143
29284
|
},
|
|
29144
29285
|
visible: !this.readonly
|
|
29145
29286
|
},
|
|
29146
29287
|
{
|
|
29147
|
-
label: '
|
|
29148
|
-
this.
|
|
29288
|
+
label: 'Xem các phiên bản khác', icon: 'fas fa-history', command: () => {
|
|
29289
|
+
this.openFileVersions(item);
|
|
29290
|
+
}
|
|
29291
|
+
},
|
|
29292
|
+
{
|
|
29293
|
+
label: 'Xóa tệp tin', icon: 'far fa-trash-alt', command: () => {
|
|
29294
|
+
this.deleteFile(item);
|
|
29149
29295
|
},
|
|
29150
29296
|
visible: !this.readonly
|
|
29151
29297
|
}
|
|
@@ -29375,7 +29521,7 @@ class FileManagerComponent extends DataListBase {
|
|
|
29375
29521
|
this._notifierService.showDeleteDataSuccess();
|
|
29376
29522
|
}
|
|
29377
29523
|
else {
|
|
29378
|
-
this._notifierService.
|
|
29524
|
+
this._notifierService.showWarningByResponse(response);
|
|
29379
29525
|
}
|
|
29380
29526
|
});
|
|
29381
29527
|
});
|
|
@@ -29387,6 +29533,24 @@ class FileManagerComponent extends DataListBase {
|
|
|
29387
29533
|
this._downloadLinkService.download(model);
|
|
29388
29534
|
});
|
|
29389
29535
|
}
|
|
29536
|
+
copyDownloadLink(explorerItem) {
|
|
29537
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
29538
|
+
const model = this._downloadLinkService.getGenerateDownloadLinkModel(explorerItem);
|
|
29539
|
+
this._downloadLinkService.generateDownloadLink(model)
|
|
29540
|
+
.then(rs => {
|
|
29541
|
+
if (rs.success) {
|
|
29542
|
+
this._commonService.copyMessage(this._downloadLinkService.getAnonymousDownloadUrl(rs.data));
|
|
29543
|
+
this._notifierService.showSuccess('Đã sao chép vào bộ nhớ tạm. Đường dẫn này sẽ hết hạn sau 60 giây!');
|
|
29544
|
+
}
|
|
29545
|
+
else {
|
|
29546
|
+
this._notifierService.showWarning('Không thể sao chép liên kết tải tệp tin!');
|
|
29547
|
+
}
|
|
29548
|
+
})
|
|
29549
|
+
.catch(err => {
|
|
29550
|
+
this._notifierService.showWarning('Không thể sao chép liên kết tải tệp tin!');
|
|
29551
|
+
});
|
|
29552
|
+
});
|
|
29553
|
+
}
|
|
29390
29554
|
// Tải nhiều thư mục/ tệp.
|
|
29391
29555
|
downloadMultiple() {
|
|
29392
29556
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -29463,7 +29627,7 @@ class FileManagerComponent extends DataListBase {
|
|
|
29463
29627
|
this.data.moving = {};
|
|
29464
29628
|
}
|
|
29465
29629
|
else {
|
|
29466
|
-
this._notifierService.
|
|
29630
|
+
this._notifierService.showWarningByResponse(response);
|
|
29467
29631
|
}
|
|
29468
29632
|
});
|
|
29469
29633
|
}
|
|
@@ -29622,12 +29786,40 @@ class FileManagerComponent extends DataListBase {
|
|
|
29622
29786
|
onRowSelect(evt) {
|
|
29623
29787
|
this.onSelected.emit(this.model.selectedItems);
|
|
29624
29788
|
}
|
|
29789
|
+
addAttachLink() {
|
|
29790
|
+
if (this.typedLink && this.typedLink.length > 0) {
|
|
29791
|
+
const obj = this.parseAttachLink(this.typedLink);
|
|
29792
|
+
if (obj) {
|
|
29793
|
+
// do logic copy file by hash
|
|
29794
|
+
alert(obj);
|
|
29795
|
+
this.typedLink = '';
|
|
29796
|
+
this.showAttachLinkBox = false;
|
|
29797
|
+
this.getFolderContent(this.data.currentFolderId);
|
|
29798
|
+
this._notifierService.showSuccess('Tải thành công!');
|
|
29799
|
+
}
|
|
29800
|
+
else {
|
|
29801
|
+
this._notifierService.showWarning('Không hỗ trợ liên kết từ hệ thống khác hoặc liên kết không đúng!');
|
|
29802
|
+
}
|
|
29803
|
+
}
|
|
29804
|
+
}
|
|
29805
|
+
parseAttachLink(link) {
|
|
29806
|
+
if (link) {
|
|
29807
|
+
const parts = link.split('/file/v5/DownloadLink/Download/');
|
|
29808
|
+
if (parts.length == 2) {
|
|
29809
|
+
return parts[1];
|
|
29810
|
+
}
|
|
29811
|
+
}
|
|
29812
|
+
return null;
|
|
29813
|
+
}
|
|
29814
|
+
focusInput(input) {
|
|
29815
|
+
input.focus();
|
|
29816
|
+
}
|
|
29625
29817
|
}
|
|
29626
29818
|
FileManagerComponent.decorators = [
|
|
29627
29819
|
{ type: Component, args: [{
|
|
29628
29820
|
// tslint:disable-next-line: component-selector
|
|
29629
29821
|
selector: 'file-manager',
|
|
29630
|
-
template: "<div *ngIf=\"layout == _layout.LIST\" class=\"full-layout\">\r\n <div class=\"fm-toolbar\">\r\n <div class=\"fm-toolbar-buttons\">\r\n <ng-container *ngIf=\"!readonly\">\r\n <button *ngIf=\"!hiddenCreateFolder\" pButton pRipple type=\"button\" pTooltip=\"T\u1EA1o th\u01B0 m\u1EE5c m\u1EDBi\"\r\n tooltipPosition=\"top\" icon=\"pi pi-folder\" class=\"p-button-text\" label=\"T\u1EA1o th\u01B0 m\u1EE5c\" iconPos=\"left\"\r\n (click)=\"createFolder()\">\r\n </button>\r\n\r\n <button pButton icon=\"pi pi-cloud-upload\" pTooltip=\"T\u1EA3i t\u1EC7p tin t\u1EEB m\u00E1y t\u00EDnh c\u1EE7a b\u1EA1n\"\r\n tooltipPosition=\"top\" type=\"button\" class=\"p-button-text p-button-primary\" label=\"T\u1EA3i l\u00EAn\"\r\n (click)=\"selectFile()\"></button>\r\n\r\n <button *ngIf=\"canSelect()\" class=\"p-button-text p-button-success\" pButton type=\"button\"\r\n pTooltip=\"Di chuy\u1EC3n th\u01B0 m\u1EE5c/t\u1EC7p tin \u0111\u00E3 ch\u1ECDn\" tooltipPosition=\"top\" icon=\"fas fa-arrows-alt\"\r\n iconPos=\"left\" label=\"Di chuy\u1EC3n\" (click)=\"moveExplorerItems()\">\r\n </button>\r\n\r\n <button *ngIf=\"canSetMove()\" class=\"p-button-text p-button-success\" pButton type=\"button\"\r\n pTooltip=\"Di chuy\u1EC3n th\u01B0 m\u1EE5c/t\u1EC7p tin \u0111\u00E3 ch\u1ECDn t\u1EDBi \u0111\u00E2y\" tooltipPosition=\"top\" icon=\"far fa-hand-paper\"\r\n iconPos=\"left\" label=\"\u0110\u1EB7t t\u1EA1i \u0111\u00E2y\" (click)=\"setMoveExplorerItems()\">\r\n </button>\r\n\r\n <button *ngIf=\"canSetMove()\" icon=\"pi pi-undo\" pButton class=\"p-button-text p-button-secondary\"\r\n type=\"button\" pTooltip=\"B\u1ECF di chuy\u1EC3n th\u01B0 m\u1EE5c/t\u1EC7p tin \u0111\u00E3 ch\u1ECDn\" tooltipPosition=\"top\" label=\"B\u1ECF qua\"\r\n (click)=\"cancelMove()\">\r\n </button>\r\n\r\n <button *ngIf=\"hasSelect()\" pButton type=\"button\"\r\n pTooltip=\"{{ 'X\u00F3a th\u01B0 m\u1EE5c/t\u1EC7p tin \u0111\u00E3 ch\u1ECDn' | translate }}\" tooltipPosition=\"top\" icon=\"pi pi-trash\"\r\n iconPos=\"left\" class=\"p-button-text p-button-danger\" label=\"X\u00F3a\"\r\n (click)=\"deleteMutiple(model.selectedItems)\"></button>\r\n </ng-container>\r\n <button *ngIf=\"readonly && hasSelect()\" class=\"p-button-text p-button-secondary\" pButton type=\"button\"\r\n pTooltip=\"N\u00E9n & t\u1EA3i v\u1EC1\" tooltipPosition=\"top\" icon=\"fas fa-file-archive\" iconPos=\"left\" label=\"T\u1EA3i v\u1EC1\"\r\n (click)=\"downloadMultiple()\">\r\n </button>\r\n </div>\r\n <ng-container *ngTemplateOutlet=\"breadCrumb\"></ng-container>\r\n </div>\r\n\r\n <div class=\"fm-grid\">\r\n <crud-list #crudList [model]=\"model\" [setting]=\"setting\" [dataSource]=\"_dataSource\"\r\n [disableKeypressControl]=\"true\" [showScrollBar]=\"false\" (onReload)=\"_triggerProcessData($event)\"\r\n class=\"--auto-height-content --no-wrapper-padding\" (onRowSelect)=\"onRowSelect($event)\">\r\n\r\n <ng-template #explorerItem let-rowData='rowData' let-col='col'>\r\n <span (click)=\"openObject(rowData)\" class=\"pull-left file-ex-icon\"\r\n [innerHTML]=\"rowData.name | fileIcon : !rowData.isFile\">\r\n </span>\r\n\r\n <span (click)=\"openObject(rowData)\" class=\"{{rowData.class}} file-ex-name\">\r\n {{rowData.name}}\r\n <div class=\"pull-right signature\" (click)=\"viewListSign($event, rowData.signatures)\"\r\n *ngIf=\"rowData.signatures\" pTooltip=\"Xem chi ti\u1EBFt k\u00FD s\u1ED1\" tooltipPosition=\"top\">\r\n <i class=\"fas fa-signature\"></i>\r\n </div>\r\n </span>\r\n </ng-template>\r\n\r\n <ng-template #fileSize let-rowData='rowData'>\r\n <div *ngIf=\"rowData.isFile\">{{rowData.fileSize | fileSize}}</div>\r\n </ng-template>\r\n\r\n <ng-template #function let-rowData=\"rowData\" let-crudList=\"crudList\">\r\n <div class=\"function-list\">\r\n <ng-container *ngIf=\"!readonly\">\r\n <button class=\"p-button-rounded p-button-text link-or-action\" pButton type=\"button\"\r\n tooltipPosition=\"top\" pTooltip=\"{{getButtonTooltip(rowData)}}\"\r\n icon=\"{{getButtonIcon(rowData)}}\" (click)=\"onButtonClick(rowData)\"></button>\r\n\r\n <button class=\"p-button-danger p-button-rounded p-button-text link-or-action\" pButton\r\n type=\"button\" pTooltip=\"X\u00F3a\" tooltipPosition=\"top\" icon=\"pi pi-trash\"\r\n (click)=\"deleteFile(rowData)\"></button>\r\n\r\n\r\n <button type=\"button\" pButton icon=\"pi pi-ellipsis-v\"\r\n class=\"link-or-action p-button-text p-button-rounded link-or-action\" pTooltip=\"Th\u00EAm\"\r\n tooltipPosition=\"top\" (click)=\"showContextMenu($event, rowData)\"></button>\r\n </ng-container>\r\n <button *ngIf=\"readonly\" class=\"p-button-secondary p-button-rounded p-button-text link-or-action\"\r\n pButton type=\"button\" pTooltip=\"T\u1EA3i v\u1EC1\" tooltipPosition=\"top\" icon=\"pi pi-cloud-download\"\r\n (click)=\"download(rowData)\"></button>\r\n </div>\r\n </ng-template>\r\n </crud-list>\r\n </div>\r\n</div>\r\n\r\n<div *ngIf=\"layout == _layout.SIMPLE\" class=\"not-full-layout\" [class.readonly]=\"readonly\">\r\n <div *ngIf=\"!readonly || data.breadcrumbs.length > 0\" class=\"fm-toolbar\">\r\n <div class=\"fm-toolbar-buttons\">\r\n <ng-container *ngIf=\"!readonly\">\r\n <button *ngIf=\"!hiddenCreateFolder\" (click)=\"createFolder()\" pButton pRipple type=\"button\"\r\n pTooltip=\"T\u1EA1o th\u01B0 m\u1EE5c m\u1EDBi\" tooltipPosition=\"top\" icon=\"pi pi-folder\" class=\"p-button-text\"\r\n label=\"T\u1EA1o th\u01B0 m\u1EE5c\" iconPos=\"left\">\r\n </button>\r\n <button type=\"button\" pButton class=\"p-button-text p-button-info link-or-action\"\r\n icon=\"pi pi-cloud-upload\" (click)=\"selectFile()\" label=\"T\u1EA3i l\u00EAn\"></button>\r\n </ng-container>\r\n </div>\r\n <ng-container *ngTemplateOutlet=\"breadCrumb\"></ng-container>\r\n </div>\r\n\r\n <div class=\"nfl-grid\">\r\n <div *ngFor=\"let rowData of _dataSource; index as i\" class=\"nfl-item\">\r\n <div class=\"nfl-no\">\r\n {{i + 1}}.\r\n </div>\r\n\r\n <div class=\"nfl-name\">\r\n <span class=\"pull-left file-ex-icon\" [innerHTML]=\"rowData.name | fileIcon : !rowData.isFile\">\r\n </span>\r\n <!-- <a (click)=\"openObject(rowData)\" class=\"{{rowData.class}} file-ex-name\">\r\n <span>{{rowData.nameWithoutExtension}}</span>\r\n <div *ngIf=\"rowData.signatures\" class=\"signature\" pTooltip=\"Xem chi ti\u1EBFt k\u00FD s\u1ED1\"\r\n tooltipPosition=\"top\" (click)=\"viewListSign($event, rowData.signatures)\">\r\n <i class=\"fas fa-signature\"></i>\r\n </div>\r\n </a>\r\n <a (click)=\"openObject(rowData)\" class=\"file-ex-extension\">{{rowData.extension}}</a> -->\r\n\r\n <a (click)=\"openObject(rowData)\" class=\"{{rowData.class}} file-ex-name\">\r\n <span>\r\n <span>{{rowData.nameWithoutExtension}}</span>\r\n <div *ngIf=\"rowData.signatures\" class=\"signature\" pTooltip=\"Xem chi ti\u1EBFt k\u00FD s\u1ED1\"\r\n tooltipPosition=\"top\" (click)=\"viewListSign($event, rowData.signatures)\">\r\n <i class=\"fas fa-signature\"></i>\r\n </div>\r\n </span>\r\n <span class=\"file-ex-extension\">{{rowData.extension}}</span>\r\n </a>\r\n </div>\r\n\r\n <div *ngIf=\"rowData.isFile\" class=\"nfl-version\">\r\n v{{rowData.currentFileVersion}}\r\n </div>\r\n\r\n <div class=\"nfl-function\">\r\n <ng-container *ngIf=\"!readonly\">\r\n <button class=\"p-button-rounded p-button-text link-or-action\" (click)=\"onButtonClick(rowData)\"\r\n pButton type=\"button\" tooltipPosition=\"top\" pTooltip=\"{{getButtonTooltip(rowData)}}\"\r\n icon=\"{{getButtonIcon(rowData)}}\"></button>\r\n\r\n <button class=\"p-button-danger p-button-rounded p-button-text link-or-action\"\r\n (click)=\"deleteFile(rowData)\" pButton type=\"button\" pTooltip=\"X\u00F3a\" tooltipPosition=\"top\"\r\n icon=\"pi pi-trash\"></button>\r\n\r\n <button type=\"button\" pButton icon=\"pi pi-ellipsis-v\"\r\n class=\"link-or-action p-button-text p-button-rounded link-or-action\" pTooltip=\"Th\u00EAm\"\r\n tooltipPosition=\"top\" (click)=\"showContextMenu($event, rowData)\"></button>\r\n </ng-container>\r\n\r\n <button *ngIf=\"readonly\" class=\"p-button-secondary p-button-rounded p-button-text link-or-action\"\r\n (click)=\"download(rowData)\" pButton type=\"button\" pTooltip=\"T\u1EA3i v\u1EC1\" tooltipPosition=\"top\"\r\n icon=\"pi pi-cloud-download\"></button>\r\n </div>\r\n </div>\r\n <div *ngIf=\"!_dataSource || !_dataSource.length\" class=\"nfl-no-item\">\r\n Ch\u01B0a c\u00F3 t\u00E0i li\u1EC7u \u0111\u01B0\u1EE3c t\u1EA3i l\u00EAn\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<ng-template #breadCrumb>\r\n <div *ngIf=\"data.breadcrumbs.length > 0\" class=\"fm-toolbar-path\">\r\n <p-breadcrumb class=\"customBreadCrumb\" [model]=\"data.breadcrumbs\"></p-breadcrumb>\r\n </div>\r\n</ng-template>\r\n\r\n<p-fileUpload #fileControl [ngStyle]=\"{'display': 'none'}\" mode=\"basic\" [chooseLabel]=\"chooseLabel\" name=\"file\"\r\n [url]=\"apiUploadUrl\" [maxFileSize]=\"maxFileSize\" auto=\"true\"\r\n [invalidFileSizeMessageSummary]=\"invalidFileSizeMessageSummary\"\r\n [invalidFileSizeMessageDetail]=\"invalidFileSizeMessageDetail\"\r\n [invalidFileTypeMessageSummary]=\"invalidFileTypeMessageSummary\"\r\n [invalidFileTypeMessageDetail]=\"invalidFileTypeMessageDetail\"\r\n [invalidFileLimitMessageSummary]=\"invalidFileLimitMessageSummary\"\r\n [invalidFileLimitMessageDetail]=\"invalidFileLimitMessageDetail\" (onProgress)=\"onUploadProgress($event)\"\r\n (onBeforeUpload)=\"onBeforeUpload($event)\" (onSelect)=\"handleSelectFile($event)\" (onUpload)=\"onUploaded($event)\">\r\n</p-fileUpload>\r\n<p-contextMenu #contextMenu [appendTo]=\"'body'\" [model]=\"data.itemsMenuFile\" styleClass=\"fm-contextMenu-panel\">\r\n</p-contextMenu>\r\n\r\n<!-- T\u1EA1o m\u1EDBi/ \u0111\u1ED5i t\u00EAn th\u01B0 m\u1EE5c -->\r\n<tn-dialog *ngIf=\"forms.createFolder.show\" #dialog [styleClass]=\"'address-form'\"\r\n [header]=\"forms.createFolder.header | translate\" [popupSize]=\"forms[formIds.createFolder].popupSize\"\r\n (onHide)=\"onCancelForm(formIds.createFolder)\">\r\n <folder-form #formBase [parentModel]=\"model\" [parentContext]=\"context\"\r\n [model]=\"forms[formIds.createFolder].formData\" (onSaved)=\"onSavedForm(formIds.createFolder)\"\r\n (onCancel)=\"onCancelForm(formIds.createFolder)\">\r\n </folder-form>\r\n</tn-dialog>\r\n\r\n<!-- \u0110\u1ED5i t\u00EAn file -->\r\n<tn-dialog *ngIf=\"forms.renameFile.show\" #dialog [styleClass]=\"'address-form'\"\r\n [header]=\"forms.renameFile.header | translate\" [popupSize]=\"forms[formIds.renameFile].popupSize\"\r\n (onHide)=\"onCancelForm(formIds.renameFile)\">\r\n <file-form #formBase [parentModel]=\"model\" [parentContext]=\"context\" [model]=\"forms[formIds.renameFile].formData\"\r\n (onSaved)=\"onSavedForm(formIds.renameFile)\" (onCancel)=\"onCancelForm(formIds.renameFile)\">\r\n </file-form>\r\n</tn-dialog>\r\n\r\n<!-- Xem file tr\u1EF1c tuy\u1EBFn -->\r\n<file-viewer *ngIf=\"forms.fileViewer.show\" [parentModel]=\"model\" [parentContext]=\"context\"\r\n [model]=\"forms.fileViewer.formData\" (onClose)=\"closeFileViewer()\" [readonly]=\"readonly\">\r\n</file-viewer>\r\n\r\n<!-- Xem phi\u00EAn b\u1EA3n -->\r\n<tn-dialog *ngIf=\"forms.fileVersionList.show\" #dialog [styleClass]=\"'address-form'\"\r\n [header]=\"forms.fileVersionList.header | translate\" [popupSize]=\"forms[formIds.fileVersionList].popupSize\"\r\n (onHide)=\"onCancelForm(formIds.fileVersionList)\">\r\n <file-version-list *ngIf=\"forms.fileVersionList.show\" [parentModel]=\"model\" [parentContext]=\"context\"\r\n [fileId]=\"forms[formIds.fileVersionList].fileId\" [readonly]=\"readonly\">\r\n </file-version-list>\r\n</tn-dialog>\r\n<!--\r\n\r\n<share-file *ngIf=\"forms.shareFile.show\" [parentDataModel]=\"model\" [parentDataContext]=\"context\"\r\n [model]=\"forms.shareFile.formData\">\r\n</share-file>\r\n\r\n<share-folder *ngIf=\"forms.shareFolder.show\" [parentDataModel]=\"model\" [parentDataContext]=\"context\"\r\n [model]=\"forms.shareFolder.formData\">\r\n</share-folder>\r\n\r\n\r\n\r\n<signature-detail *ngIf=\"forms.signatureDetail.show\" [parentDataModel]=\"model\" [parentDataContext]=\"context\"\r\n [model]=\"forms.signatureDetail.formData\">\r\n</signature-detail> -->",
|
|
29822
|
+
template: "<div *ngIf=\"layout == _layout.LIST\" class=\"full-layout\">\r\n <div class=\"fm-toolbar\">\r\n <div class=\"fm-toolbar-buttons\">\r\n <ng-container *ngIf=\"!readonly\">\r\n <button *ngIf=\"!hiddenCreateFolder\" pButton pRipple type=\"button\" pTooltip=\"T\u1EA1o th\u01B0 m\u1EE5c m\u1EDBi\"\r\n tooltipPosition=\"top\" icon=\"pi pi-folder\" class=\"p-button-text\" label=\"T\u1EA1o th\u01B0 m\u1EE5c\" iconPos=\"left\"\r\n (click)=\"createFolder()\">\r\n </button>\r\n\r\n <button pButton icon=\"pi pi-cloud-upload\" pTooltip=\"T\u1EA3i t\u1EC7p tin t\u1EEB m\u00E1y t\u00EDnh c\u1EE7a b\u1EA1n\"\r\n tooltipPosition=\"top\" type=\"button\" class=\"p-button-text p-button-primary\" label=\"T\u1EA3i l\u00EAn\"\r\n (click)=\"selectFile()\"></button>\r\n\r\n <button pButton icon=\"pi pi-link\" pTooltip=\"T\u1EA3i t\u1EEB li\u00EAn k\u1EBFt trong h\u1EC7 th\u1ED1ng\"\r\n tooltipPosition=\"top\" type=\"button\" class=\"p-button-text p-button-primary\" label=\"T\u1EA3i li\u00EAn k\u1EBFt\"\r\n (click)=\"showAttachLinkBox = true\"></button>\r\n\r\n <button *ngIf=\"canSelect()\" class=\"p-button-text p-button-success\" pButton type=\"button\"\r\n pTooltip=\"Di chuy\u1EC3n th\u01B0 m\u1EE5c/t\u1EC7p tin \u0111\u00E3 ch\u1ECDn\" tooltipPosition=\"top\" icon=\"fas fa-arrows-alt\"\r\n iconPos=\"left\" label=\"Di chuy\u1EC3n\" (click)=\"moveExplorerItems()\">\r\n </button>\r\n\r\n <button *ngIf=\"canSetMove()\" class=\"p-button-text p-button-success\" pButton type=\"button\"\r\n pTooltip=\"Di chuy\u1EC3n th\u01B0 m\u1EE5c/t\u1EC7p tin \u0111\u00E3 ch\u1ECDn t\u1EDBi \u0111\u00E2y\" tooltipPosition=\"top\" icon=\"far fa-hand-paper\"\r\n iconPos=\"left\" label=\"\u0110\u1EB7t t\u1EA1i \u0111\u00E2y\" (click)=\"setMoveExplorerItems()\">\r\n </button>\r\n\r\n <button *ngIf=\"canSetMove()\" icon=\"pi pi-undo\" pButton class=\"p-button-text p-button-secondary\"\r\n type=\"button\" pTooltip=\"B\u1ECF di chuy\u1EC3n th\u01B0 m\u1EE5c/t\u1EC7p tin \u0111\u00E3 ch\u1ECDn\" tooltipPosition=\"top\" label=\"B\u1ECF qua\"\r\n (click)=\"cancelMove()\">\r\n </button>\r\n\r\n <button *ngIf=\"hasSelect()\" pButton type=\"button\"\r\n pTooltip=\"{{ 'X\u00F3a th\u01B0 m\u1EE5c/t\u1EC7p tin \u0111\u00E3 ch\u1ECDn' | translate }}\" tooltipPosition=\"top\" icon=\"pi pi-trash\"\r\n iconPos=\"left\" class=\"p-button-text p-button-danger\" label=\"X\u00F3a\"\r\n (click)=\"deleteMutiple(model.selectedItems)\"></button>\r\n </ng-container>\r\n <button *ngIf=\"readonly && hasSelect()\" class=\"p-button-text p-button-secondary\" pButton type=\"button\"\r\n pTooltip=\"N\u00E9n & t\u1EA3i v\u1EC1\" tooltipPosition=\"top\" icon=\"fas fa-file-archive\" iconPos=\"left\" label=\"T\u1EA3i v\u1EC1\"\r\n (click)=\"downloadMultiple()\">\r\n </button>\r\n </div>\r\n <ng-container *ngTemplateOutlet=\"breadCrumb\"></ng-container>\r\n </div>\r\n\r\n <div class=\"fm-grid\">\r\n <crud-list #crudList [model]=\"model\" [setting]=\"setting\" [dataSource]=\"_dataSource\"\r\n [disableKeypressControl]=\"true\" [showScrollBar]=\"false\" (onReload)=\"_triggerProcessData($event)\"\r\n class=\"--auto-height-content --no-wrapper-padding\" (onRowSelect)=\"onRowSelect($event)\">\r\n\r\n <ng-template #explorerItem let-rowData='rowData' let-col='col'>\r\n <span (click)=\"openObject(rowData)\" class=\"pull-left file-ex-icon\"\r\n [innerHTML]=\"rowData.name | fileIcon : !rowData.isFile\">\r\n </span>\r\n\r\n <span (click)=\"openObject(rowData)\" class=\"{{rowData.class}} file-ex-name\">\r\n {{rowData.name}}\r\n <div class=\"pull-right signature\" (click)=\"viewListSign($event, rowData.signatures)\"\r\n *ngIf=\"rowData.signatures\" pTooltip=\"Xem chi ti\u1EBFt k\u00FD s\u1ED1\" tooltipPosition=\"top\">\r\n <i class=\"fas fa-signature\"></i>\r\n </div>\r\n </span>\r\n </ng-template>\r\n\r\n <ng-template #fileSize let-rowData='rowData'>\r\n <div *ngIf=\"rowData.isFile\">{{rowData.fileSize | fileSize}}</div>\r\n </ng-template>\r\n\r\n <ng-template #function let-rowData=\"rowData\" let-crudList=\"crudList\">\r\n <div class=\"function-list\">\r\n <ng-container *ngIf=\"!readonly\">\r\n <button class=\"p-button-rounded p-button-text link-or-action\" pButton type=\"button\"\r\n tooltipPosition=\"top\" pTooltip=\"{{getButtonTooltip(rowData)}}\"\r\n icon=\"{{getButtonIcon(rowData)}}\" (click)=\"onButtonClick(rowData)\"></button>\r\n\r\n <button class=\"p-button-danger p-button-rounded p-button-text link-or-action\" pButton\r\n type=\"button\" pTooltip=\"X\u00F3a\" tooltipPosition=\"top\" icon=\"pi pi-trash\"\r\n (click)=\"deleteFile(rowData)\"></button>\r\n\r\n\r\n <button type=\"button\" pButton icon=\"pi pi-ellipsis-v\"\r\n class=\"link-or-action p-button-text p-button-rounded link-or-action\" pTooltip=\"Th\u00EAm\"\r\n tooltipPosition=\"top\" (click)=\"showContextMenu($event, rowData)\"></button>\r\n </ng-container>\r\n <button *ngIf=\"readonly\" class=\"p-button-secondary p-button-rounded p-button-text link-or-action\"\r\n pButton type=\"button\" pTooltip=\"T\u1EA3i v\u1EC1\" tooltipPosition=\"top\" icon=\"pi pi-cloud-download\"\r\n (click)=\"download(rowData)\"></button>\r\n <button *ngIf=\"readonly\" class=\"p-button-secondary p-button-rounded p-button-text link-or-action\"\r\n pButton type=\"button\" pTooltip=\"Sao ch\u00E9p \u0111\u01B0\u1EDDng d\u1EABn\" tooltipPosition=\"top\" icon=\"pi pi-link\"\r\n (click)=\"copyDownloadLink(rowData)\"></button>\r\n </div>\r\n </ng-template>\r\n </crud-list>\r\n </div>\r\n</div>\r\n\r\n<div *ngIf=\"layout == _layout.SIMPLE\" class=\"not-full-layout\" [class.readonly]=\"readonly\">\r\n <div *ngIf=\"!readonly || data.breadcrumbs.length > 0\" class=\"fm-toolbar\">\r\n <div class=\"fm-toolbar-buttons\">\r\n <ng-container *ngIf=\"!readonly\">\r\n <button *ngIf=\"!hiddenCreateFolder\" (click)=\"createFolder()\" pButton pRipple type=\"button\"\r\n pTooltip=\"T\u1EA1o th\u01B0 m\u1EE5c m\u1EDBi\" tooltipPosition=\"top\" icon=\"pi pi-folder\" class=\"p-button-text\"\r\n label=\"T\u1EA1o th\u01B0 m\u1EE5c\" iconPos=\"left\">\r\n </button>\r\n <button type=\"button\" pButton class=\"p-button-text p-button-info link-or-action\"\r\n icon=\"pi pi-cloud-upload\" (click)=\"selectFile()\" label=\"T\u1EA3i l\u00EAn\"></button>\r\n <button pButton icon=\"pi pi-link\" pTooltip=\"T\u1EA3i t\u1EEB li\u00EAn k\u1EBFt trong h\u1EC7 th\u1ED1ng\"\r\n tooltipPosition=\"top\" type=\"button\" class=\"p-button-text p-button-primary\" label=\"T\u1EA3i li\u00EAn k\u1EBFt\"\r\n (click)=\"showAttachLinkBox = true\"></button>\r\n </ng-container>\r\n </div>\r\n <ng-container *ngTemplateOutlet=\"breadCrumb\"></ng-container>\r\n </div>\r\n\r\n <div class=\"nfl-grid\">\r\n <div *ngFor=\"let rowData of _dataSource; index as i\" class=\"nfl-item\">\r\n <div class=\"nfl-no\">\r\n {{i + 1}}.\r\n </div>\r\n\r\n <div class=\"nfl-name\">\r\n <span class=\"pull-left file-ex-icon\" [innerHTML]=\"rowData.name | fileIcon : !rowData.isFile\">\r\n </span>\r\n <!-- <a (click)=\"openObject(rowData)\" class=\"{{rowData.class}} file-ex-name\">\r\n <span>{{rowData.nameWithoutExtension}}</span>\r\n <div *ngIf=\"rowData.signatures\" class=\"signature\" pTooltip=\"Xem chi ti\u1EBFt k\u00FD s\u1ED1\"\r\n tooltipPosition=\"top\" (click)=\"viewListSign($event, rowData.signatures)\">\r\n <i class=\"fas fa-signature\"></i>\r\n </div>\r\n </a>\r\n <a (click)=\"openObject(rowData)\" class=\"file-ex-extension\">{{rowData.extension}}</a> -->\r\n\r\n <a (click)=\"openObject(rowData)\" class=\"{{rowData.class}} file-ex-name\">\r\n <span>\r\n <span>{{rowData.nameWithoutExtension}}</span>\r\n <div *ngIf=\"rowData.signatures\" class=\"signature\" pTooltip=\"Xem chi ti\u1EBFt k\u00FD s\u1ED1\"\r\n tooltipPosition=\"top\" (click)=\"viewListSign($event, rowData.signatures)\">\r\n <i class=\"fas fa-signature\"></i>\r\n </div>\r\n </span>\r\n <span class=\"file-ex-extension\">{{rowData.extension}}</span>\r\n </a>\r\n </div>\r\n\r\n <div *ngIf=\"rowData.isFile\" class=\"nfl-version\">\r\n v{{rowData.currentFileVersion}}\r\n </div>\r\n\r\n <div class=\"nfl-function\">\r\n <ng-container *ngIf=\"!readonly\">\r\n <button class=\"p-button-rounded p-button-text link-or-action\" (click)=\"onButtonClick(rowData)\"\r\n pButton type=\"button\" tooltipPosition=\"top\" pTooltip=\"{{getButtonTooltip(rowData)}}\"\r\n icon=\"{{getButtonIcon(rowData)}}\"></button>\r\n\r\n <button class=\"p-button-danger p-button-rounded p-button-text link-or-action\"\r\n (click)=\"deleteFile(rowData)\" pButton type=\"button\" pTooltip=\"X\u00F3a\" tooltipPosition=\"top\"\r\n icon=\"pi pi-trash\"></button>\r\n\r\n <button type=\"button\" pButton icon=\"pi pi-ellipsis-v\"\r\n class=\"link-or-action p-button-text p-button-rounded link-or-action\" pTooltip=\"Th\u00EAm\"\r\n tooltipPosition=\"top\" (click)=\"showContextMenu($event, rowData)\"></button>\r\n </ng-container>\r\n\r\n <button *ngIf=\"readonly\" class=\"p-button-secondary p-button-rounded p-button-text link-or-action\"\r\n (click)=\"download(rowData)\" pButton type=\"button\" pTooltip=\"T\u1EA3i v\u1EC1\" tooltipPosition=\"top\"\r\n icon=\"pi pi-cloud-download\"></button>\r\n <button *ngIf=\"readonly\" class=\"p-button-secondary p-button-rounded p-button-text link-or-action\"\r\n pButton type=\"button\" pTooltip=\"Sao ch\u00E9p \u0111\u01B0\u1EDDng d\u1EABn\" tooltipPosition=\"top\" icon=\"pi pi-link\"\r\n (click)=\"copyDownloadLink(rowData)\"></button>\r\n </div>\r\n </div>\r\n <div *ngIf=\"!_dataSource || !_dataSource.length\" class=\"nfl-no-item\">\r\n Ch\u01B0a c\u00F3 t\u00E0i li\u1EC7u \u0111\u01B0\u1EE3c t\u1EA3i l\u00EAn\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<ng-template #breadCrumb>\r\n <div *ngIf=\"data.breadcrumbs.length > 0\" class=\"fm-toolbar-path\">\r\n <p-breadcrumb class=\"customBreadCrumb\" [model]=\"data.breadcrumbs\"></p-breadcrumb>\r\n </div>\r\n</ng-template>\r\n\r\n<p-fileUpload #fileControl [ngStyle]=\"{'display': 'none'}\" mode=\"basic\" [chooseLabel]=\"chooseLabel\" name=\"file\"\r\n [url]=\"apiUploadUrl\" [maxFileSize]=\"maxFileSize\" auto=\"true\"\r\n [invalidFileSizeMessageSummary]=\"invalidFileSizeMessageSummary\"\r\n [invalidFileSizeMessageDetail]=\"invalidFileSizeMessageDetail\"\r\n [invalidFileTypeMessageSummary]=\"invalidFileTypeMessageSummary\"\r\n [invalidFileTypeMessageDetail]=\"invalidFileTypeMessageDetail\"\r\n [invalidFileLimitMessageSummary]=\"invalidFileLimitMessageSummary\"\r\n [invalidFileLimitMessageDetail]=\"invalidFileLimitMessageDetail\" (onProgress)=\"onUploadProgress($event)\"\r\n (onBeforeUpload)=\"onBeforeUpload($event)\" (onSelect)=\"handleSelectFile($event)\" (onUpload)=\"onUploaded($event)\">\r\n</p-fileUpload>\r\n<p-contextMenu #contextMenu [appendTo]=\"'body'\" [model]=\"data.itemsMenuFile\" styleClass=\"fm-contextMenu-panel\">\r\n</p-contextMenu>\r\n\r\n<!-- T\u1EA1o m\u1EDBi/ \u0111\u1ED5i t\u00EAn th\u01B0 m\u1EE5c -->\r\n<tn-dialog *ngIf=\"forms.createFolder.show\" #dialog [styleClass]=\"'address-form'\"\r\n [header]=\"forms.createFolder.header | translate\" [popupSize]=\"forms[formIds.createFolder].popupSize\"\r\n (onHide)=\"onCancelForm(formIds.createFolder)\">\r\n <folder-form #formBase [parentModel]=\"model\" [parentContext]=\"context\"\r\n [model]=\"forms[formIds.createFolder].formData\" (onSaved)=\"onSavedForm(formIds.createFolder)\"\r\n (onCancel)=\"onCancelForm(formIds.createFolder)\">\r\n </folder-form>\r\n</tn-dialog>\r\n\r\n<!-- \u0110\u1ED5i t\u00EAn file -->\r\n<tn-dialog *ngIf=\"forms.renameFile.show\" #dialog [styleClass]=\"'address-form'\"\r\n [header]=\"forms.renameFile.header | translate\" [popupSize]=\"forms[formIds.renameFile].popupSize\"\r\n (onHide)=\"onCancelForm(formIds.renameFile)\">\r\n <file-form #formBase [parentModel]=\"model\" [parentContext]=\"context\" [model]=\"forms[formIds.renameFile].formData\"\r\n (onSaved)=\"onSavedForm(formIds.renameFile)\" (onCancel)=\"onCancelForm(formIds.renameFile)\">\r\n </file-form>\r\n</tn-dialog>\r\n\r\n<!-- Xem file tr\u1EF1c tuy\u1EBFn -->\r\n<file-viewer *ngIf=\"forms.fileViewer.show\" [parentModel]=\"model\" [parentContext]=\"context\"\r\n [model]=\"forms.fileViewer.formData\" (onClose)=\"closeFileViewer()\" [readonly]=\"readonly\">\r\n</file-viewer>\r\n\r\n<!-- Xem phi\u00EAn b\u1EA3n -->\r\n<tn-dialog *ngIf=\"forms.fileVersionList.show\" #dialog [styleClass]=\"'address-form'\"\r\n [header]=\"forms.fileVersionList.header | translate\" [popupSize]=\"forms[formIds.fileVersionList].popupSize\"\r\n (onHide)=\"onCancelForm(formIds.fileVersionList)\">\r\n <file-version-list *ngIf=\"forms.fileVersionList.show\" [parentModel]=\"model\" [parentContext]=\"context\"\r\n [fileId]=\"forms[formIds.fileVersionList].fileId\" [readonly]=\"readonly\">\r\n </file-version-list>\r\n</tn-dialog>\r\n\r\n<tn-dialog *ngIf=\"showAttachLinkBox\" #dialog2 [maximizable]=\"false\"\r\n [header]=\"'Nh\u1EADp li\u00EAn k\u1EBFt' | translate\" [popupSize]=\"{ width: 600, height: 50}\" (onHide)=\"showAttachLinkBox = false; typedLink=''\">\r\n <div class=\"p-col-12\">\r\n <div class=\"p-grid\">\r\n <div class=\"p-md-10\">\r\n <input #input type=\"text\" placeholder=\"Nh\u1EADp li\u00EAn k\u1EBFt sao ch\u00E9p t\u1EEB t\u1EC7p tin kh\u00E1c...\" (keyup.enter)=\"addAttachLink()\" pInputText [(ngModel)]=\"typedLink\" class=\"p-col-12\"/>\r\n </div>\r\n <div class=\"p-md-2\">\r\n <button type=\"button\" (click)=\"addAttachLink()\" [disabled]=\"typedLink != ''? null : true\" pButton class=\"p-button-primary p-col-12\" label=\"Ok\"></button>\r\n </div>\r\n </div>\r\n </div>\r\n <after-view-checked (loaded)=\"focusInput(input)\"></after-view-checked>\r\n</tn-dialog>\r\n<!--\r\n\r\n<share-file *ngIf=\"forms.shareFile.show\" [parentDataModel]=\"model\" [parentDataContext]=\"context\"\r\n [model]=\"forms.shareFile.formData\">\r\n</share-file>\r\n\r\n<share-folder *ngIf=\"forms.shareFolder.show\" [parentDataModel]=\"model\" [parentDataContext]=\"context\"\r\n [model]=\"forms.shareFolder.formData\">\r\n</share-folder>\r\n\r\n\r\n\r\n<signature-detail *ngIf=\"forms.signatureDetail.show\" [parentDataModel]=\"model\" [parentDataContext]=\"context\"\r\n [model]=\"forms.signatureDetail.formData\">\r\n</signature-detail> -->",
|
|
29631
29823
|
providers: [
|
|
29632
29824
|
{
|
|
29633
29825
|
provide: NG_VALUE_ACCESSOR,
|
|
@@ -30341,7 +30533,7 @@ class FileViewerComponent extends ComponentBase {
|
|
|
30341
30533
|
this.onClose.next(true);
|
|
30342
30534
|
}
|
|
30343
30535
|
else {
|
|
30344
|
-
this._notifierService.
|
|
30536
|
+
this._notifierService.showWarningByResponse(response);
|
|
30345
30537
|
}
|
|
30346
30538
|
});
|
|
30347
30539
|
});
|
|
@@ -32837,7 +33029,12 @@ var EnumWorkflowHistoryStatus;
|
|
|
32837
33029
|
EnumWorkflowHistoryStatus[EnumWorkflowHistoryStatus["IN_MAIN_THREAD"] = 0] = "IN_MAIN_THREAD";
|
|
32838
33030
|
EnumWorkflowHistoryStatus[EnumWorkflowHistoryStatus["NOT_IN_MAIN_THREAD"] = 1] = "NOT_IN_MAIN_THREAD";
|
|
32839
33031
|
EnumWorkflowHistoryStatus[EnumWorkflowHistoryStatus["RECALLED"] = 2] = "RECALLED";
|
|
32840
|
-
})(EnumWorkflowHistoryStatus || (EnumWorkflowHistoryStatus = {}));
|
|
33032
|
+
})(EnumWorkflowHistoryStatus || (EnumWorkflowHistoryStatus = {}));
|
|
33033
|
+
var EnumPermissionType;
|
|
33034
|
+
(function (EnumPermissionType) {
|
|
33035
|
+
EnumPermissionType[EnumPermissionType["MAIN"] = 0] = "MAIN";
|
|
33036
|
+
EnumPermissionType[EnumPermissionType["SHARE"] = 1] = "SHARE"; // Bản ghi tạo ra để chia sẻ
|
|
33037
|
+
})(EnumPermissionType || (EnumPermissionType = {}));
|
|
32841
33038
|
|
|
32842
33039
|
const StateMachineTopic = {
|
|
32843
33040
|
CONNECTION_CHANGE: 'CONNECTION_CHANGE'
|
|
@@ -35520,6 +35717,7 @@ class TnDialogComponent {
|
|
|
35520
35717
|
this.closeOnEscape = true;
|
|
35521
35718
|
this.showFooter = true;
|
|
35522
35719
|
this.hiddenSave = true;
|
|
35720
|
+
this.maximizable = true;
|
|
35523
35721
|
this.scrollConfig = { suppressScrollX: true, suppressScrollY: false };
|
|
35524
35722
|
this.scrollStyle = {};
|
|
35525
35723
|
this.onSave = new EventEmitter();
|
|
@@ -35594,7 +35792,7 @@ class TnDialogComponent {
|
|
|
35594
35792
|
TnDialogComponent.decorators = [
|
|
35595
35793
|
{ type: Component, args: [{
|
|
35596
35794
|
selector: 'tn-dialog',
|
|
35597
|
-
template: "<p-dialog #dialog [closeOnEscape]=\"closeOnEscape\" [appendTo]=\"'body'\" [focusOnShow]=\"false\" [focusTrap]=\"false\"\r\n [header]=\"header | translate\" [(visible)]=\"visible\" [modal]=\"modal\" [responsive]=\"true\" [maximizable]=\"
|
|
35795
|
+
template: "<p-dialog #dialog [closeOnEscape]=\"closeOnEscape\" [appendTo]=\"'body'\" [focusOnShow]=\"false\" [focusTrap]=\"false\"\r\n [header]=\"header | translate\" [(visible)]=\"visible\" [modal]=\"modal\" [responsive]=\"true\" [maximizable]=\"maximizable\"\r\n [autoZIndex]=\"true\" [styleClass]=\"styleClass\" [maskStyleClass]=\"maskClass\"\r\n [style]=\"{'width': popupSize.width + 'px', 'min-width': popupSize.width + 'px', 'height': popupSize.height + 'px', 'min-height': popupSize.height + 'px'}\"\r\n (onShow)=\"handleShowDialog($event)\" (onHide)=\"handleHideDialog($event)\" (onShow)=\"handleShowDialog($event)\">\r\n <tn-custom-scrollbar #scrollbar [useDefaultScrollBar]=\"useDefaultScrollBar\" [class]=\"scrollBarStyleClass\"\r\n [config]=\"scrollConfig\" [style]=\"scrollStyle\" class=\"tn-dialog-scrollbar\">\r\n <ng-content></ng-content>\r\n </tn-custom-scrollbar>\r\n <p-footer *ngIf=\"showFooter && formBase && formBase.buttonTemplate\">\r\n <ng-container *ngTemplateOutlet=\"formBase.buttonTemplate\">\r\n </ng-container>\r\n </p-footer>\r\n <p-footer *ngIf=\"showFooter && footer\">\r\n <ng-container *ngTemplateOutlet=\"footer\"></ng-container>\r\n </p-footer>\r\n</p-dialog>",
|
|
35598
35796
|
styles: [""]
|
|
35599
35797
|
},] }
|
|
35600
35798
|
];
|
|
@@ -35622,6 +35820,7 @@ TnDialogComponent.propDecorators = {
|
|
|
35622
35820
|
positionTop: [{ type: Input }],
|
|
35623
35821
|
minY: [{ type: Input }],
|
|
35624
35822
|
hiddenSave: [{ type: Input }],
|
|
35823
|
+
maximizable: [{ type: Input }],
|
|
35625
35824
|
onSave: [{ type: Output }],
|
|
35626
35825
|
onCancel: [{ type: Output }],
|
|
35627
35826
|
onShow: [{ type: Output }],
|
|
@@ -37582,6 +37781,140 @@ ChoYKienFormComponent.propDecorators = {
|
|
|
37582
37781
|
rowItem: [{ type: Input }]
|
|
37583
37782
|
};
|
|
37584
37783
|
|
|
37784
|
+
class WorkflowPermissionService extends BaseService {
|
|
37785
|
+
constructor(http, injector, _moduleConfigService) {
|
|
37786
|
+
super(http, injector, `${_moduleConfigService.getConfig().environment.apiDomain.workflowEndpoint}/WorkflowPermission`);
|
|
37787
|
+
this.entityName = 'WorkflowPermission';
|
|
37788
|
+
this.serviceCode = 'workflow';
|
|
37789
|
+
this.endPoint = _moduleConfigService.getConfig().environment.apiDomain.workflowEndpoint;
|
|
37790
|
+
}
|
|
37791
|
+
}
|
|
37792
|
+
WorkflowPermissionService.ɵprov = ɵɵdefineInjectable({ factory: function WorkflowPermissionService_Factory() { return new WorkflowPermissionService(ɵɵinject(HttpClient), ɵɵinject(INJECTOR), ɵɵinject(ModuleConfigService)); }, token: WorkflowPermissionService, providedIn: "root" });
|
|
37793
|
+
WorkflowPermissionService.decorators = [
|
|
37794
|
+
{ type: Injectable, args: [{
|
|
37795
|
+
providedIn: 'root'
|
|
37796
|
+
},] }
|
|
37797
|
+
];
|
|
37798
|
+
WorkflowPermissionService.ctorParameters = () => [
|
|
37799
|
+
{ type: HttpClient },
|
|
37800
|
+
{ type: Injector },
|
|
37801
|
+
{ type: ModuleConfigService }
|
|
37802
|
+
];
|
|
37803
|
+
|
|
37804
|
+
class PermissionSharingComponent extends DataListBase {
|
|
37805
|
+
constructor(_injector, _workflowPermissionService) {
|
|
37806
|
+
super(_injector);
|
|
37807
|
+
this._injector = _injector;
|
|
37808
|
+
this._workflowPermissionService = _workflowPermissionService;
|
|
37809
|
+
}
|
|
37810
|
+
ngOnInit() {
|
|
37811
|
+
this.setting.baseService = this._workflowPermissionService;
|
|
37812
|
+
this.setting.settingKey = 'permission-sharing';
|
|
37813
|
+
this.setting.title = '';
|
|
37814
|
+
this.setting.heightType = HeightType.dynamic;
|
|
37815
|
+
this.setting.showEditLink = false;
|
|
37816
|
+
this.setting.hiddenToolbar = true;
|
|
37817
|
+
this.setting.hiddenWorkflowColumn = true;
|
|
37818
|
+
this.setting.hiddenSettingWorkflow = true;
|
|
37819
|
+
this.setting.hiddenSettingWorkflowNew = true;
|
|
37820
|
+
this.setting.hiddenSettingPermission = true;
|
|
37821
|
+
this.init();
|
|
37822
|
+
}
|
|
37823
|
+
init() {
|
|
37824
|
+
this.setting.modelSchemas = [
|
|
37825
|
+
new ModelSchema({ field: 'userIdCreated', name: 'Người chia sẻ', fullName: 'Người chia sẻ', description: '' }),
|
|
37826
|
+
new ModelSchema({ field: 'permission', name: 'Quyền', fullName: 'Quyền', description: '' }),
|
|
37827
|
+
new ModelSchema({ field: 'created', name: 'Thời gian', fullName: 'Thời gian', description: '' }),
|
|
37828
|
+
];
|
|
37829
|
+
this.setting.cols = [
|
|
37830
|
+
new ColumnSchemaBase({
|
|
37831
|
+
field: 'userIdCreated',
|
|
37832
|
+
baseService: this._userService,
|
|
37833
|
+
displayField: 'fullNameNew'
|
|
37834
|
+
}),
|
|
37835
|
+
new ColumnSchemaBase({
|
|
37836
|
+
field: 'strPermissions',
|
|
37837
|
+
label: this._translateService.instant('Quyền'),
|
|
37838
|
+
}),
|
|
37839
|
+
new ColumnSchemaBase({
|
|
37840
|
+
field: 'created',
|
|
37841
|
+
dataType: 'datetime',
|
|
37842
|
+
width: '20%'
|
|
37843
|
+
})
|
|
37844
|
+
];
|
|
37845
|
+
this.model.ready = true;
|
|
37846
|
+
super.ngOnInit();
|
|
37847
|
+
}
|
|
37848
|
+
modifyGridInfo(gridInfo) {
|
|
37849
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
37850
|
+
gridInfo.filters.unshift(this.newFilter('itemId', Operator.equal, this.item.id), this.newFilter('type', Operator.equal, EnumPermissionType.SHARE));
|
|
37851
|
+
gridInfo.sorts.unshift(this.newSort('created', -1));
|
|
37852
|
+
});
|
|
37853
|
+
}
|
|
37854
|
+
beforeRenderDataSource(dataSource) {
|
|
37855
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
37856
|
+
const separator = ', ';
|
|
37857
|
+
dataSource.forEach(item => {
|
|
37858
|
+
item.hiddenEdit = true;
|
|
37859
|
+
item.hiddenCopyLink = true;
|
|
37860
|
+
// Tổng hợp quyền của bản ghi
|
|
37861
|
+
let strPermissions = '';
|
|
37862
|
+
if (this.checkHasPermission(item.permission, PermissionBase.READ)) {
|
|
37863
|
+
strPermissions += `xem${separator}`;
|
|
37864
|
+
}
|
|
37865
|
+
if (this.checkHasPermission(item.permission, PermissionBase.EDIT)) {
|
|
37866
|
+
strPermissions += `sửa${separator}`;
|
|
37867
|
+
}
|
|
37868
|
+
if (this.checkHasPermission(item.permission, PermissionBase.DELETE)) {
|
|
37869
|
+
strPermissions += `xóa${separator}`;
|
|
37870
|
+
}
|
|
37871
|
+
if (strPermissions.length > 0) {
|
|
37872
|
+
strPermissions = strPermissions.substring(0, strPermissions.length - separator.length);
|
|
37873
|
+
strPermissions = strPermissions.substring(0, 1).toUpperCase() + strPermissions.substring(1);
|
|
37874
|
+
}
|
|
37875
|
+
item.strPermissions = strPermissions;
|
|
37876
|
+
});
|
|
37877
|
+
});
|
|
37878
|
+
}
|
|
37879
|
+
checkHasPermission(permission, permissionCheck) {
|
|
37880
|
+
return (permission & permissionCheck) == permissionCheck;
|
|
37881
|
+
}
|
|
37882
|
+
delete(item) {
|
|
37883
|
+
this.deletePermissionSharing([item.id]);
|
|
37884
|
+
}
|
|
37885
|
+
deleteMultiple(items) {
|
|
37886
|
+
this.deletePermissionSharing(items.map(q => q.id));
|
|
37887
|
+
}
|
|
37888
|
+
deletePermissionSharing(ids) {
|
|
37889
|
+
if (ids.length == 0) {
|
|
37890
|
+
return this._notifierService.showWarning('Bạn chưa chọn link muốn xóa');
|
|
37891
|
+
}
|
|
37892
|
+
this._notifierService.showConfirm('Bạn có chắc chắn muốn xóa link đã chọn')
|
|
37893
|
+
.then(res => {
|
|
37894
|
+
if (!res)
|
|
37895
|
+
return;
|
|
37896
|
+
this.baseService.deleteLinkSharing(ids)
|
|
37897
|
+
.then(res => this.handleResponse(res, 'Xóa thành công', f => this._triggerProcessData()));
|
|
37898
|
+
});
|
|
37899
|
+
}
|
|
37900
|
+
}
|
|
37901
|
+
PermissionSharingComponent.decorators = [
|
|
37902
|
+
{ type: Component, args: [{
|
|
37903
|
+
selector: 'permission-sharing',
|
|
37904
|
+
template: "<crud-list *ngIf=\"model.ready\" #crudList [model]=\"model\" [setting]=\"setting\" [dataSource]=\"model.dataSource\"\r\n [disableShare]=\"true\" [hiddenCopyLink]=\"true\" [hiddenAdd]=\"true\" (onReload)=\"_triggerProcessData($event)\"\r\n (onAdd)=\"_add($event)\" (onEdit)=\"_edit($event)\" (onView)=\"_view($event)\" (onDelete)=\"delete($event)\"\r\n (onDeleteMultiple)=\"deleteMultiple($event)\" (onReloaded)=\"_handleReloaded($event)\">\r\n</crud-list>",
|
|
37905
|
+
providers: [ComponentContextService],
|
|
37906
|
+
styles: [".state-designer-container>div:first-child{font-size:.9em;font-weight:700;padding:.5em 0}.container-receiver div{margin-bottom:10px}.container-receiver div:last-child{margin-bottom:0}::ng-deep workflow-history-new tr.recalled{opacity:.5}"]
|
|
37907
|
+
},] }
|
|
37908
|
+
];
|
|
37909
|
+
PermissionSharingComponent.ctorParameters = () => [
|
|
37910
|
+
{ type: Injector },
|
|
37911
|
+
{ type: WorkflowPermissionService }
|
|
37912
|
+
];
|
|
37913
|
+
PermissionSharingComponent.propDecorators = {
|
|
37914
|
+
baseService: [{ type: Input }],
|
|
37915
|
+
item: [{ type: Input }]
|
|
37916
|
+
};
|
|
37917
|
+
|
|
37585
37918
|
class CanBoHoSoService extends BaseService {
|
|
37586
37919
|
constructor(http, injector, _moduleConfigService) {
|
|
37587
37920
|
super(http, injector, `${_moduleConfigService.getConfig().environment.apiDomain.canboEndpoint}/${_moduleConfigService.getConfig().environment.apiVersion}/CanBo_HoSo`);
|
|
@@ -38456,6 +38789,9 @@ class WorkflowHistoryNewComponent extends DataListBase {
|
|
|
38456
38789
|
item.jsonModelChange = [];
|
|
38457
38790
|
}
|
|
38458
38791
|
}
|
|
38792
|
+
else if (item.actionCode == ActionThuHoiBase) {
|
|
38793
|
+
item.class = 'recalled';
|
|
38794
|
+
}
|
|
38459
38795
|
}
|
|
38460
38796
|
else if (item.status == EnumWorkflowHistoryStatus.RECALLED) {
|
|
38461
38797
|
item.class = 'recalled';
|
|
@@ -39239,7 +39575,7 @@ class BaseCauHinhWorkflowDetailComponent extends ComponentBase {
|
|
|
39239
39575
|
BaseCauHinhWorkflowDetailComponent.decorators = [
|
|
39240
39576
|
{ type: Component, args: [{
|
|
39241
39577
|
selector: 'base-cauhinh-workflow-detail',
|
|
39242
|
-
template: "<workflow-picker #workflowPicker *ngIf=\"readyGenWorkflow\" #formBase [data]=\"workflowData\" [showButtonSave]=\"true\"\r\n (onSaveSetting)=\"handleSave($event)\"></workflow-picker>\r\n<after-view-checked *ngIf=\"hasCountDown\" (loaded)=\"handleReadyToGetWorkflowData()\">\r\n</after-view-checked
|
|
39578
|
+
template: "<workflow-picker #workflowPicker *ngIf=\"readyGenWorkflow\" #formBase [data]=\"workflowData\" [showButtonSave]=\"true\"\r\n (onSaveSetting)=\"handleSave($event)\"></workflow-picker>\r\n<after-view-checked *ngIf=\"hasCountDown\" (loaded)=\"handleReadyToGetWorkflowData()\">\r\n</after-view-checked>\r\n",
|
|
39243
39579
|
providers: [ComponentContextService],
|
|
39244
39580
|
styles: [".container-task-info .percent-done{background-color:#f0f0f0;border-radius:2px;height:5px;margin-top:5px;overflow:hidden;position:relative}.container-task-info .percent-done .detail{border-radius:2px;color:#fff;font-size:13px;height:5px;left:0;position:absolute;text-align:center;top:0}"]
|
|
39245
39581
|
},] }
|
|
@@ -39410,8 +39746,10 @@ class BaseCongviecDinhkemComponent extends DataListBase {
|
|
|
39410
39746
|
this.fileDataService = fileDataService;
|
|
39411
39747
|
this.formState = FormState.VIEW;
|
|
39412
39748
|
this.layoutFile = EnumFileLayout;
|
|
39413
|
-
this.formModel = {};
|
|
39414
39749
|
this.enumFormState = FormState;
|
|
39750
|
+
this.formModel = {};
|
|
39751
|
+
this.showAttachLinkBox = false;
|
|
39752
|
+
this.typedLink = '';
|
|
39415
39753
|
}
|
|
39416
39754
|
ngOnInit() {
|
|
39417
39755
|
this.setting.objectName = 'mục đính kèm';
|
|
@@ -39491,37 +39829,59 @@ class BaseCongviecDinhkemComponent extends DataListBase {
|
|
|
39491
39829
|
return __awaiter(this, void 0, void 0, function* () {
|
|
39492
39830
|
const content = this._commonService.pasteByStorage();
|
|
39493
39831
|
if (content) {
|
|
39494
|
-
const obj = this.
|
|
39495
|
-
console.log('obj parsed', obj);
|
|
39832
|
+
const obj = this.parseAttachLink(content);
|
|
39496
39833
|
if (obj.length > 0) {
|
|
39497
|
-
this._notifierService.showSuccess('Đang thêm mục đính kèm');
|
|
39498
39834
|
this._congViecDinhKemService.themDinhKemNghiepVu(this.taskId, obj).then(rs => {
|
|
39499
39835
|
if (rs.success) {
|
|
39500
|
-
this._notifierService.showSuccess('Thêm mục đính kèm thành công');
|
|
39836
|
+
this._notifierService.showSuccess('Thêm mục đính kèm thành công!');
|
|
39501
39837
|
this.reload();
|
|
39502
39838
|
this._commonService.clearClipboardStorage();
|
|
39503
39839
|
}
|
|
39504
39840
|
else {
|
|
39505
|
-
this.
|
|
39841
|
+
this.showAttachLinkBox = true;
|
|
39506
39842
|
}
|
|
39507
39843
|
}).catch(err => {
|
|
39508
|
-
|
|
39509
|
-
this._notifierService.showWarning('Thêm mục đính kèm không thành công');
|
|
39844
|
+
this.showAttachLinkBox = true;
|
|
39510
39845
|
});
|
|
39511
39846
|
}
|
|
39512
39847
|
else {
|
|
39513
|
-
this.
|
|
39848
|
+
this.showAttachLinkBox = true;
|
|
39514
39849
|
}
|
|
39515
39850
|
}
|
|
39516
39851
|
else {
|
|
39517
|
-
this.
|
|
39852
|
+
this.showAttachLinkBox = true;
|
|
39518
39853
|
}
|
|
39519
39854
|
});
|
|
39520
39855
|
}
|
|
39856
|
+
addAttachLink() {
|
|
39857
|
+
if (this.typedLink && this.typedLink.length > 0) {
|
|
39858
|
+
const obj = this.parseAttachLink(this.typedLink);
|
|
39859
|
+
if (obj.length > 0) {
|
|
39860
|
+
this._congViecDinhKemService.themDinhKemNghiepVu(this.taskId, obj).then(rs => {
|
|
39861
|
+
if (rs.success) {
|
|
39862
|
+
this._notifierService.showSuccess('Thêm mục đính kèm thành công!');
|
|
39863
|
+
this.showAttachLinkBox = false;
|
|
39864
|
+
this.typedLink = '';
|
|
39865
|
+
this.reload();
|
|
39866
|
+
}
|
|
39867
|
+
else {
|
|
39868
|
+
this._notifierService.showWarning('Liên kết không hợp lệ!');
|
|
39869
|
+
}
|
|
39870
|
+
}).catch(err => {
|
|
39871
|
+
this._notifierService.showWarning('Liên kết không hợp lệ!');
|
|
39872
|
+
});
|
|
39873
|
+
}
|
|
39874
|
+
else {
|
|
39875
|
+
this._notifierService.showWarning('Liên kết không hợp lệ!');
|
|
39876
|
+
}
|
|
39877
|
+
}
|
|
39878
|
+
}
|
|
39879
|
+
focusInput(input) {
|
|
39880
|
+
input.focus();
|
|
39881
|
+
}
|
|
39521
39882
|
// http://localhost:27230/universal-link?serviceCode=congviec&entity=DM_Priority&entityKey=0911f3e7-3db0-4b68-87cd-07d425741e9e&state=&sourcePath=http://localhost:27230/dm-priority
|
|
39522
|
-
|
|
39883
|
+
parseAttachLink(content) {
|
|
39523
39884
|
const links = content.split('\r\n');
|
|
39524
|
-
console.log('links', links);
|
|
39525
39885
|
const op = [];
|
|
39526
39886
|
for (const link of links) {
|
|
39527
39887
|
const temp = link.split('universal-link')[1];
|
|
@@ -39565,7 +39925,7 @@ class BaseCongviecDinhkemComponent extends DataListBase {
|
|
|
39565
39925
|
BaseCongviecDinhkemComponent.decorators = [
|
|
39566
39926
|
{ type: Component, args: [{
|
|
39567
39927
|
selector: 'base-congviec-dinhkem',
|
|
39568
|
-
template: "<crud-list #crudList [model]=\"model\" [setting]=\"setting\" [dataSource]=\"model.dataSource\" [hiddenAdd]=\"true\"\r\n
|
|
39928
|
+
template: "<crud-list #crudList [model]=\"model\" [setting]=\"setting\" [dataSource]=\"model.dataSource\" [hiddenAdd]=\"true\"\r\n [hiddenEdit]=\"true\" [hiddenDelete]=\"true\" [hiddenCopyLink]=\"true\" (onReload)=\"_triggerProcessData($event)\"\r\n (onView)=\"viewLinkItem($event)\" (onDelete)=\"deleteLinkItem($event)\"\r\n (onDeleteMultiple)=\"deleteLinkItemMultiple($event)\" (onReloaded)=\"_unmarkLoading()\">\r\n <ng-template #tieuDe let-rowData=\"rowData\">\r\n {{rowData.tenHienThiDoiTuong}}: [{{rowData.tieuDe}}]\r\n </ng-template>\r\n <ng-template #buttonAfterToolbar>\r\n <button *ngIf=\"formState == enumFormState.EDIT || formState == enumFormState.ADD\" type=\"button\" pButton pRipple\r\n label=\"Th\u00EAm m\u1EDBi\" icon=\"pi pi-plus\" class=\"p-button-text p-button-primary\" (click)=\"themDinhKem()\"></button>\r\n <button type=\"button\"\r\n *ngIf=\"(formState == enumFormState.EDIT || formState == enumFormState.ADD) && model.selectedItems.length > 0\"\r\n pButton pRipple label=\"X\u00F3a\" icon=\"pi pi-trash\" class=\"p-button-rounded p-button-text p-button-danger\"\r\n (click)=\"deleteLinkItemMultiple($event)\"></button>\r\n </ng-template>\r\n <ng-template #function let-rowData=\"rowData\">\r\n <button *ngIf=\"formState == enumFormState.EDIT || formState == enumFormState.ADD\" type=\"button\" pButton pRipple\r\n icon=\"pi pi-trash\" class=\"p-button-rounded p-button-text p-button-danger\" pTooltip=\"H\u1EE7y \u0111\u00EDnh k\u00E8m\"\r\n tooltipPosition=\"top\" (click)=\"deleteLinkItem(rowData)\"></button>\r\n </ng-template>\r\n <ng-template #fileDinhKem let-rowData=\"rowData\">\r\n <file-manager [readonly]=\"true\" [serviceCode]=\"rowData.serviceCode\" [entity]=\"rowData.entity\"\r\n [entityKey]=\"rowData.entityKey\" [layout]=\"layoutFile.SIMPLE\" [fileDataService]=\"fileDataService\">\r\n </file-manager>\r\n </ng-template>\r\n</crud-list>\r\n\r\n<tn-dialog *ngIf=\"showDetailForm\" #dialog [styleClass]=\"'congviec-form tn-form-dialog'\"\r\n [header]=\"setting.popupHeader | translate\" [popupSize]=\"setting.popupSize\" (onHide)=\"showDetailForm = false\">\r\n <base-congviec-dinhkem-form #formBase [taskId]=\"taskId\" [parentModel]=\"model\" [parentContext]=\"context\"\r\n [model]=\"formModel\" (onSaved)=\"showDetailForm = false;crudList.reload()\" (onCancel)=\"_handleCancel($event)\"\r\n (onAfterSaved)=\"onAfterSaved($event)\">\r\n </base-congviec-dinhkem-form>\r\n</tn-dialog>\r\n\r\n<tn-dialog *ngIf=\"showAttachLinkBox\" #dialog2 [maximizable]=\"false\" [header]=\"'Nh\u1EADp li\u00EAn k\u1EBFt' | translate\"\r\n [popupSize]=\"{ width: 600, height: 50}\" (onHide)=\"showAttachLinkBox = false; typedLink=''\">\r\n <div class=\"p-col-12\">\r\n <div class=\"p-grid\">\r\n <div class=\"p-md-10\">\r\n <input #input type=\"text\" placeholder=\"Nh\u1EADp li\u00EAn k\u1EBFt sao ch\u00E9p t\u1EEB ph\u00E2n h\u1EC7 kh\u00E1c...\" pInputText\r\n class=\"p-col-12\" [(ngModel)]=\"typedLink\" (keyup.enter)=\"addAttachLink()\" />\r\n </div>\r\n <div class=\"p-md-2\">\r\n <button type=\"button\" pButton class=\"p-button-primary p-col-12\" label=\"Ok\"\r\n [disabled]=\"typedLink != ''? null : true\" (click)=\"addAttachLink()\"></button>\r\n </div>\r\n </div>\r\n </div>\r\n <after-view-checked (loaded)=\"focusInput(input)\"></after-view-checked>\r\n</tn-dialog>",
|
|
39569
39929
|
providers: [ComponentContextService],
|
|
39570
39930
|
styles: [""]
|
|
39571
39931
|
},] }
|
|
@@ -39668,6 +40028,12 @@ class BaseCongViecFormComponent extends DataFormBase {
|
|
|
39668
40028
|
this.autoFocus = true;
|
|
39669
40029
|
this.enumFormState = FormState;
|
|
39670
40030
|
this.enumLoaiDanhSachCongViec = EnumLoaiDanhSachCongViec;
|
|
40031
|
+
this.users = {
|
|
40032
|
+
taskName: '',
|
|
40033
|
+
assigner: 0,
|
|
40034
|
+
assignee: 0,
|
|
40035
|
+
relatedUsers: [],
|
|
40036
|
+
};
|
|
39671
40037
|
this.tabDataChild = [
|
|
39672
40038
|
{
|
|
39673
40039
|
code: 'fileDinhKem',
|
|
@@ -39683,6 +40049,11 @@ class BaseCongViecFormComponent extends DataFormBase {
|
|
|
39683
40049
|
code: 'taskLienQuan',
|
|
39684
40050
|
icon: 'pi pi-share-alt',
|
|
39685
40051
|
label: 'Công việc liên quan'
|
|
40052
|
+
},
|
|
40053
|
+
{
|
|
40054
|
+
code: 'traoDoiCongViec',
|
|
40055
|
+
icon: 'pi pi-comment',
|
|
40056
|
+
label: 'Trao đổi công việc',
|
|
39686
40057
|
}
|
|
39687
40058
|
];
|
|
39688
40059
|
this.handleChangeLoaiCongViecWhenAdd = (evt) => __awaiter(this, void 0, void 0, function* () {
|
|
@@ -39690,6 +40061,9 @@ class BaseCongViecFormComponent extends DataFormBase {
|
|
|
39690
40061
|
yield this.loadWorkflowByLoaiCongViec(evt, evt.model.id);
|
|
39691
40062
|
}
|
|
39692
40063
|
});
|
|
40064
|
+
this.users.assigner = 0;
|
|
40065
|
+
this.users.assignee = 0;
|
|
40066
|
+
this.users.relatedUsers = [];
|
|
39693
40067
|
}
|
|
39694
40068
|
set tenCongViec(value) {
|
|
39695
40069
|
this._tenCongViec = value;
|
|
@@ -39784,18 +40158,24 @@ class BaseCongViecFormComponent extends DataFormBase {
|
|
|
39784
40158
|
this.setWorkflowDatasource(evt, workflowSetting);
|
|
39785
40159
|
});
|
|
39786
40160
|
}
|
|
39787
|
-
onBeforeSave() {
|
|
39788
|
-
}
|
|
39789
40161
|
onAfterSave(res) {
|
|
39790
40162
|
if (this.model.formState == FormState.ADD && res && res.success && res.data) {
|
|
39791
40163
|
this.onAfterSaved.emit(res.data);
|
|
39792
40164
|
}
|
|
39793
40165
|
}
|
|
40166
|
+
onTabChange(evt) {
|
|
40167
|
+
this.currentTabIndex = evt.index;
|
|
40168
|
+
this.users.taskName = this.model.data.ten;
|
|
40169
|
+
}
|
|
40170
|
+
forcusToFirstInputControl(event) {
|
|
40171
|
+
event.preventDefault();
|
|
40172
|
+
this.context.fireEvent(ComCtxConstants.COMMON.FOCUS_TO_FIRST_INPUT_CONTROL);
|
|
40173
|
+
}
|
|
39794
40174
|
}
|
|
39795
40175
|
BaseCongViecFormComponent.decorators = [
|
|
39796
40176
|
{ type: Component, args: [{
|
|
39797
40177
|
selector: 'base-congviec-form',
|
|
39798
|
-
template: "<crud-form #crudForm [(data)]=\"model.data\" [setting]=\"setting\" [context]=\"context\" [disableCaching]=\"true\"\r\n
|
|
40178
|
+
template: "<crud-form #crudForm [(data)]=\"model.data\" [setting]=\"setting\" [context]=\"context\" [disableCaching]=\"true\"\r\n [autoFocus]=\"autoFocus\" (onFormReady)=\"_handleFormReady($event)\">\r\n</crud-form>\r\n<base-congviec-dinhkem [loadDetailFromQueryParam]=\"false\" [formState]=\"model.formState\" [taskId]=\"model.data.id\">\r\n</base-congviec-dinhkem>\r\n<div class=\"tab-child\">\r\n <tn-tabview [data]=\"tabDataChild\" (onTabChange)=\"onTabChange($event)\">\r\n <ng-template #fileDinhKem>\r\n <file-manager [loadDetailFromQueryParam]=\"false\" [serviceCode]=\"setting.baseService.serviceCode\"\r\n [entity]=\"setting.baseService.entityName\" [entityKey]=\"model.data.id\"\r\n [readonly]=\"model.formState == enumFormState.VIEW\">\r\n </file-manager>\r\n </ng-template>\r\n <ng-template #taskChild>\r\n <div style=\"height: 100%\">\r\n <base-congviec [loadDetailFromQueryParam]=\"false\" [isChildView]=\"true\" [formState]=\"model.formState\"\r\n [loaiDanhSach]=\"enumLoaiDanhSachCongViec.CongViecCon\" [idCongViec]=\"model.data.id\">\r\n </base-congviec>\r\n </div>\r\n </ng-template>\r\n <ng-template #taskLienQuan>\r\n <base-congviec [loadDetailFromQueryParam]=\"false\" [isChildView]=\"true\" [formState]=\"model.formState\"\r\n [loaiDanhSach]=\"enumLoaiDanhSachCongViec.CongViecLienQuan\" [idCongViec]=\"model.data.id\">\r\n </base-congviec>\r\n </ng-template>\r\n <ng-template #traoDoiCongViec>\r\n <div style=\"height: 350px;\">\r\n <chat-box [showSendMessageBox]=\"false\" [serviceCode]=\"'congviec'\" [entity]=\"'congviec'\"\r\n [taskId]=\"model.data.id\" [parentModel]=\"model\" [parentContext]=\"context\"\r\n [users]=\"users\"\r\n ></chat-box>\r\n </div>\r\n <chat-send-message-box [parentContext]=\"context\">\r\n </chat-send-message-box>\r\n </ng-template>\r\n </tn-tabview>\r\n</div>\r\n<ng-template #buttonTemplate>\r\n <button *ngIf=\"!model.data.__disableEdit && !__isFormView\" type=\"button\" pButton icon=\"pi pi-save\"\r\n class=\"p-button-text\" [label]=\"'FORM.SAVE' | translate\" (click)=\"_handleSave($event)\"></button>\r\n <button type=\"button\" pButton icon=\"pi pi-replay\" class=\"p-button-text p-button-secondary\"\r\n [label]=\"'FORM.CANCEL' | translate\" preventTab (click)=\"_handleCancel($event)\"></button>\r\n</ng-template>\r\n",
|
|
39799
40179
|
providers: [ComponentContextService],
|
|
39800
40180
|
styles: [".tab-child{padding:1em}"]
|
|
39801
40181
|
},] }
|
|
@@ -40116,7 +40496,7 @@ class BaseCongViecComponent extends DataListBase {
|
|
|
40116
40496
|
this.reload();
|
|
40117
40497
|
}
|
|
40118
40498
|
else {
|
|
40119
|
-
this._notifierService.
|
|
40499
|
+
this._notifierService.showWarningByResponse(response);
|
|
40120
40500
|
}
|
|
40121
40501
|
}, error => {
|
|
40122
40502
|
this._notifierService.showDeleteDataError();
|
|
@@ -40130,7 +40510,7 @@ class BaseCongViecComponent extends DataListBase {
|
|
|
40130
40510
|
this.reload();
|
|
40131
40511
|
}
|
|
40132
40512
|
else {
|
|
40133
|
-
this._notifierService.
|
|
40513
|
+
this._notifierService.showWarningByResponse(response);
|
|
40134
40514
|
}
|
|
40135
40515
|
}, error => {
|
|
40136
40516
|
this._notifierService.showDeleteDataError();
|
|
@@ -41815,6 +42195,1180 @@ UsersFormatPipe.ctorParameters = () => [
|
|
|
41815
42195
|
{ type: UserService }
|
|
41816
42196
|
];
|
|
41817
42197
|
|
|
42198
|
+
class ServiceRequestModel {
|
|
42199
|
+
constructor(init) {
|
|
42200
|
+
this.service = '';
|
|
42201
|
+
this.entityInstanceId = '';
|
|
42202
|
+
this.parent = null;
|
|
42203
|
+
this.serviceCode = '';
|
|
42204
|
+
this.entity = '';
|
|
42205
|
+
this.entityKey = '';
|
|
42206
|
+
for (const key in init) {
|
|
42207
|
+
this[key] = init[key];
|
|
42208
|
+
}
|
|
42209
|
+
}
|
|
42210
|
+
}
|
|
42211
|
+
|
|
42212
|
+
class ContentsService extends BaseService {
|
|
42213
|
+
constructor(_injector, _httpClient, _moduleConfigService, _fileService) {
|
|
42214
|
+
super(_httpClient, _injector, `${_moduleConfigService.getConfig().environment.apiDomain.chatEndpoint}/${_moduleConfigService.getConfig().environment.apiVersion}/Contents`);
|
|
42215
|
+
this._moduleConfigService = _moduleConfigService;
|
|
42216
|
+
this._fileService = _fileService;
|
|
42217
|
+
this.entityName = 'Contents';
|
|
42218
|
+
this.serviceCode = 'chat';
|
|
42219
|
+
this.endPoint = `${_moduleConfigService.getConfig().environment.apiDomain.chatEndpoint}`;
|
|
42220
|
+
}
|
|
42221
|
+
getByService(model, page = 0) {
|
|
42222
|
+
const { serviceCode, entity, entityKey } = model;
|
|
42223
|
+
const url = `${this.serviceUri}/GetByService?serviceCode=${serviceCode}&entity=${entity}&entityKey=${entityKey}&page=${page}`;
|
|
42224
|
+
return this.defaultGet(url);
|
|
42225
|
+
}
|
|
42226
|
+
getByTaskId(model, taskId) {
|
|
42227
|
+
const { serviceCode, entity, entityKey } = model;
|
|
42228
|
+
const url = `${this.serviceUri}/GetByTaskId?serviceCode=${serviceCode}&entity=${entity}&entityKey=${entityKey}&taskId=${taskId}`;
|
|
42229
|
+
return this.defaultGet(url);
|
|
42230
|
+
}
|
|
42231
|
+
getContentById(data) {
|
|
42232
|
+
let url = `${this.serviceUri}/GetByChatId/${data.instanceId}`;
|
|
42233
|
+
if (data.page) {
|
|
42234
|
+
url += `${url}?page=${data.page}`;
|
|
42235
|
+
}
|
|
42236
|
+
return this.defaultGet(url);
|
|
42237
|
+
}
|
|
42238
|
+
sendMessage(messageContent) {
|
|
42239
|
+
const url = `${this.serviceUri}/SendMessage`;
|
|
42240
|
+
return this.defaultPost(url, messageContent);
|
|
42241
|
+
}
|
|
42242
|
+
markAsReadAllContents(chatId) {
|
|
42243
|
+
const url = `${this.serviceUri}ReadInfo/MarkAsReadAllContents/${chatId}`;
|
|
42244
|
+
return this.defaultPost(url, chatId);
|
|
42245
|
+
}
|
|
42246
|
+
}
|
|
42247
|
+
ContentsService.ɵprov = ɵɵdefineInjectable({ factory: function ContentsService_Factory() { return new ContentsService(ɵɵinject(INJECTOR), ɵɵinject(HttpClient), ɵɵinject(ModuleConfigService), ɵɵinject(FileExplorerService)); }, token: ContentsService, providedIn: "root" });
|
|
42248
|
+
ContentsService.decorators = [
|
|
42249
|
+
{ type: Injectable, args: [{
|
|
42250
|
+
providedIn: 'root'
|
|
42251
|
+
},] }
|
|
42252
|
+
];
|
|
42253
|
+
ContentsService.ctorParameters = () => [
|
|
42254
|
+
{ type: Injector },
|
|
42255
|
+
{ type: HttpClient },
|
|
42256
|
+
{ type: ModuleConfigService },
|
|
42257
|
+
{ type: FileExplorerService }
|
|
42258
|
+
];
|
|
42259
|
+
|
|
42260
|
+
class StatusExtendsService extends BaseService {
|
|
42261
|
+
constructor(_injector, _http, _moduleConfigService) {
|
|
42262
|
+
super(_http, _injector, `${_moduleConfigService.getConfig().environment.apiDomain.chatEndpoint}/${_moduleConfigService.getConfig().environment.apiVersion}/StatusExtends`);
|
|
42263
|
+
this._moduleConfigService = _moduleConfigService;
|
|
42264
|
+
this.entityName = 'StatusExtends';
|
|
42265
|
+
this.serviceCode = 'chat';
|
|
42266
|
+
this.endPoint = `${_moduleConfigService.getConfig().environment.apiDomain.chatEndpoint}`;
|
|
42267
|
+
}
|
|
42268
|
+
insertUserOnline(chatId) {
|
|
42269
|
+
const statusExtends = { chatId: chatId };
|
|
42270
|
+
const url = `${this.serviceUri}/InsertUserOnline`;
|
|
42271
|
+
return this.defaultPost(url, statusExtends);
|
|
42272
|
+
}
|
|
42273
|
+
removeUserOnline(id) {
|
|
42274
|
+
return this.deleteById(id);
|
|
42275
|
+
}
|
|
42276
|
+
}
|
|
42277
|
+
StatusExtendsService.ɵprov = ɵɵdefineInjectable({ factory: function StatusExtendsService_Factory() { return new StatusExtendsService(ɵɵinject(INJECTOR), ɵɵinject(HttpClient), ɵɵinject(ModuleConfigService)); }, token: StatusExtendsService, providedIn: "root" });
|
|
42278
|
+
StatusExtendsService.decorators = [
|
|
42279
|
+
{ type: Injectable, args: [{
|
|
42280
|
+
providedIn: 'root'
|
|
42281
|
+
},] }
|
|
42282
|
+
];
|
|
42283
|
+
StatusExtendsService.ctorParameters = () => [
|
|
42284
|
+
{ type: Injector },
|
|
42285
|
+
{ type: HttpClient },
|
|
42286
|
+
{ type: ModuleConfigService }
|
|
42287
|
+
];
|
|
42288
|
+
|
|
42289
|
+
class ChatService extends BaseService {
|
|
42290
|
+
constructor(_injector, _httpClient, _moduleConfigService, _folderService, _myDriveService, _fileService, _contentService, _statusService) {
|
|
42291
|
+
super(_httpClient, _injector, `${_moduleConfigService.getConfig().environment.apiDomain.chatEndpoint}/${_moduleConfigService.getConfig().environment.apiVersion}/Instances`);
|
|
42292
|
+
this._moduleConfigService = _moduleConfigService;
|
|
42293
|
+
this._folderService = _folderService;
|
|
42294
|
+
this._myDriveService = _myDriveService;
|
|
42295
|
+
this._fileService = _fileService;
|
|
42296
|
+
this._contentService = _contentService;
|
|
42297
|
+
this._statusService = _statusService;
|
|
42298
|
+
this.entityName = 'Instances';
|
|
42299
|
+
this.serviceCode = 'chat';
|
|
42300
|
+
this.SERVICE = 'chat';
|
|
42301
|
+
this.ENTITY_CONTENT = 'contents';
|
|
42302
|
+
this.endPoint = `${_moduleConfigService.getConfig().environment.apiDomain.chatEndpoint}`;
|
|
42303
|
+
}
|
|
42304
|
+
getListAttachment(id) {
|
|
42305
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
42306
|
+
const request = new ServiceRequestModel({
|
|
42307
|
+
service: this.SERVICE,
|
|
42308
|
+
serviceCode: this.SERVICE,
|
|
42309
|
+
entity: this.ENTITY_CONTENT,
|
|
42310
|
+
entityInstanceId: id,
|
|
42311
|
+
entityKey: 'id',
|
|
42312
|
+
});
|
|
42313
|
+
// const result = await this._folderService.getServiceFolderId(request);
|
|
42314
|
+
// if (!result.success || !result.data) {
|
|
42315
|
+
// return [];
|
|
42316
|
+
// }
|
|
42317
|
+
// const folder = await this._folderService.getDetail(result.data);
|
|
42318
|
+
// // const folder = await this._myDriveService.getByFolderId(result.data);
|
|
42319
|
+
// if (result.success) {
|
|
42320
|
+
// if (folder.data.length > 0) {
|
|
42321
|
+
// return folder.data.map(x => {
|
|
42322
|
+
// const item = <any>{
|
|
42323
|
+
// id: x.id,
|
|
42324
|
+
// fileName: x.name,
|
|
42325
|
+
// type: this._commonService.isImage(x.name) ? 'image' : ''
|
|
42326
|
+
// };
|
|
42327
|
+
//
|
|
42328
|
+
// item.url = this._fileService.getFileDownloadUrl(x.id);
|
|
42329
|
+
//
|
|
42330
|
+
// return item;
|
|
42331
|
+
// });
|
|
42332
|
+
// }
|
|
42333
|
+
// }
|
|
42334
|
+
return [];
|
|
42335
|
+
});
|
|
42336
|
+
}
|
|
42337
|
+
getChatId(model) {
|
|
42338
|
+
const { serviceCode, entity, entityKey } = model;
|
|
42339
|
+
const url = `${this.serviceUri}/GetIdByService?serviceCode=${serviceCode}&entity=${entity}&entityKey=${entityKey}`;
|
|
42340
|
+
return this.defaultGet(url);
|
|
42341
|
+
}
|
|
42342
|
+
getChatIdByTask(serviceRequest, taskId) {
|
|
42343
|
+
const { serviceCode, entity, entityKey } = serviceRequest;
|
|
42344
|
+
const url = `${this.serviceUri}/GetIdByTaskId?serviceCode=${serviceCode}&entity=${entity}&entityKey=${entityKey}&taskId=${taskId}`;
|
|
42345
|
+
return this.defaultGet(url);
|
|
42346
|
+
}
|
|
42347
|
+
getByService(model, page = 0) {
|
|
42348
|
+
return this._contentService.getByService(model, page);
|
|
42349
|
+
}
|
|
42350
|
+
getContentByTaskId(serviceRequest, taskId) {
|
|
42351
|
+
return this._contentService.getByTaskId(serviceRequest, taskId);
|
|
42352
|
+
}
|
|
42353
|
+
markAsReadAllContents(chatId) {
|
|
42354
|
+
return this._contentService.markAsReadAllContents(chatId);
|
|
42355
|
+
}
|
|
42356
|
+
sendMessage(messageContent) {
|
|
42357
|
+
return this._contentService.sendMessage(messageContent);
|
|
42358
|
+
}
|
|
42359
|
+
insertUserOnline(chatId) {
|
|
42360
|
+
return this._statusService.insertUserOnline(chatId);
|
|
42361
|
+
}
|
|
42362
|
+
removeUserOnline(id) {
|
|
42363
|
+
return this._statusService.removeUserOnline(id);
|
|
42364
|
+
}
|
|
42365
|
+
}
|
|
42366
|
+
ChatService.ɵprov = ɵɵdefineInjectable({ factory: function ChatService_Factory() { return new ChatService(ɵɵinject(INJECTOR), ɵɵinject(HttpClient), ɵɵinject(ModuleConfigService), ɵɵinject(FolderService), ɵɵinject(MyDriveService), ɵɵinject(FileExplorerService), ɵɵinject(ContentsService), ɵɵinject(StatusExtendsService)); }, token: ChatService, providedIn: "root" });
|
|
42367
|
+
ChatService.decorators = [
|
|
42368
|
+
{ type: Injectable, args: [{
|
|
42369
|
+
providedIn: 'root'
|
|
42370
|
+
},] }
|
|
42371
|
+
];
|
|
42372
|
+
ChatService.ctorParameters = () => [
|
|
42373
|
+
{ type: Injector },
|
|
42374
|
+
{ type: HttpClient },
|
|
42375
|
+
{ type: ModuleConfigService },
|
|
42376
|
+
{ type: FolderService },
|
|
42377
|
+
{ type: MyDriveService },
|
|
42378
|
+
{ type: FileExplorerService },
|
|
42379
|
+
{ type: ContentsService },
|
|
42380
|
+
{ type: StatusExtendsService }
|
|
42381
|
+
];
|
|
42382
|
+
|
|
42383
|
+
class MessageBoardService extends BaseService {
|
|
42384
|
+
constructor(_injector, _http, _moduleConfigService) {
|
|
42385
|
+
super(_http, _injector, `${_moduleConfigService.getConfig().environment.apiDomain.chatEndpoint}/${_moduleConfigService.getConfig().environment.apiVersion}/MessageBoards`);
|
|
42386
|
+
this._moduleConfigService = _moduleConfigService;
|
|
42387
|
+
this.entityName = 'MessageBoards';
|
|
42388
|
+
this.serviceCode = 'chat';
|
|
42389
|
+
this.endPoint = `${this._moduleConfigService.getConfig().environment.apiDomain.chatEndpoint}`;
|
|
42390
|
+
}
|
|
42391
|
+
pinMessage(messageId, pinned, correlationId) {
|
|
42392
|
+
const url = `${this.serviceUri}/PinnedMessage`;
|
|
42393
|
+
return this.defaultPost(url, { pinned: pinned, id: messageId, correlationId: correlationId });
|
|
42394
|
+
}
|
|
42395
|
+
getLatestPinnedMessage(chatId) {
|
|
42396
|
+
const url = `${this.serviceUri}/GetLatestPinnedMessage?chatId=${chatId}`;
|
|
42397
|
+
return this.defaultGet(url);
|
|
42398
|
+
}
|
|
42399
|
+
getListPinnedMessage(chatId) {
|
|
42400
|
+
const url = `${this.serviceUri}/GetListPinnedMessage?chatId=${chatId}`;
|
|
42401
|
+
return this.defaultGet(url);
|
|
42402
|
+
}
|
|
42403
|
+
}
|
|
42404
|
+
MessageBoardService.ɵprov = ɵɵdefineInjectable({ factory: function MessageBoardService_Factory() { return new MessageBoardService(ɵɵinject(INJECTOR), ɵɵinject(HttpClient), ɵɵinject(ModuleConfigService)); }, token: MessageBoardService, providedIn: "root" });
|
|
42405
|
+
MessageBoardService.decorators = [
|
|
42406
|
+
{ type: Injectable, args: [{
|
|
42407
|
+
providedIn: 'root'
|
|
42408
|
+
},] }
|
|
42409
|
+
];
|
|
42410
|
+
MessageBoardService.ctorParameters = () => [
|
|
42411
|
+
{ type: Injector },
|
|
42412
|
+
{ type: HttpClient },
|
|
42413
|
+
{ type: ModuleConfigService }
|
|
42414
|
+
];
|
|
42415
|
+
|
|
42416
|
+
class CheckControlVisibleService {
|
|
42417
|
+
constructor() { }
|
|
42418
|
+
checkDisplayStatus(elem) {
|
|
42419
|
+
return new Promise((resolve, reject) => {
|
|
42420
|
+
this.doCheck(resolve, elem);
|
|
42421
|
+
});
|
|
42422
|
+
}
|
|
42423
|
+
doCheck(resolve, elem) {
|
|
42424
|
+
let timeoutCheckDisplayStatus;
|
|
42425
|
+
timeoutCheckDisplayStatus = setTimeout(() => {
|
|
42426
|
+
this.doCheck(resolve, elem);
|
|
42427
|
+
}, 100);
|
|
42428
|
+
var newStatus = this.isVisible(elem);
|
|
42429
|
+
if (newStatus) {
|
|
42430
|
+
setTimeout(() => {
|
|
42431
|
+
// show control
|
|
42432
|
+
resolve(true);
|
|
42433
|
+
});
|
|
42434
|
+
clearTimeout(timeoutCheckDisplayStatus);
|
|
42435
|
+
}
|
|
42436
|
+
}
|
|
42437
|
+
isVisible(elem) {
|
|
42438
|
+
const style = getComputedStyle(elem);
|
|
42439
|
+
if (style.display === 'none')
|
|
42440
|
+
return false;
|
|
42441
|
+
if (style.visibility !== 'visible')
|
|
42442
|
+
return false;
|
|
42443
|
+
if (+style.opacity < 0.1)
|
|
42444
|
+
return false;
|
|
42445
|
+
if (elem.offsetWidth + elem.offsetHeight + elem.getBoundingClientRect().height +
|
|
42446
|
+
elem.getBoundingClientRect().width === 0) {
|
|
42447
|
+
return false;
|
|
42448
|
+
}
|
|
42449
|
+
const elemCenter = {
|
|
42450
|
+
x: elem.getBoundingClientRect().left + elem.offsetWidth / 2,
|
|
42451
|
+
y: elem.getBoundingClientRect().top + elem.offsetHeight / 2
|
|
42452
|
+
};
|
|
42453
|
+
let pointContainer = document.elementFromPoint(elemCenter.x, elemCenter.y);
|
|
42454
|
+
if (pointContainer) {
|
|
42455
|
+
do {
|
|
42456
|
+
if (pointContainer === elem)
|
|
42457
|
+
return true;
|
|
42458
|
+
} while (pointContainer = pointContainer.parentNode);
|
|
42459
|
+
}
|
|
42460
|
+
return false;
|
|
42461
|
+
}
|
|
42462
|
+
}
|
|
42463
|
+
CheckControlVisibleService.ɵprov = ɵɵdefineInjectable({ factory: function CheckControlVisibleService_Factory() { return new CheckControlVisibleService(); }, token: CheckControlVisibleService, providedIn: "root" });
|
|
42464
|
+
CheckControlVisibleService.decorators = [
|
|
42465
|
+
{ type: Injectable, args: [{
|
|
42466
|
+
providedIn: 'root'
|
|
42467
|
+
},] }
|
|
42468
|
+
];
|
|
42469
|
+
CheckControlVisibleService.ctorParameters = () => [];
|
|
42470
|
+
|
|
42471
|
+
const NEW_MESSAGE = 'NewMessage';
|
|
42472
|
+
const PINNED_CHANGED = 'PinnedChanged';
|
|
42473
|
+
var NotificationType;
|
|
42474
|
+
(function (NotificationType) {
|
|
42475
|
+
NotificationType[NotificationType["NewMessage"] = 0] = "NewMessage";
|
|
42476
|
+
NotificationType[NotificationType["PinnedChanged"] = 1] = "PinnedChanged";
|
|
42477
|
+
})(NotificationType || (NotificationType = {}));
|
|
42478
|
+
var MessageType;
|
|
42479
|
+
(function (MessageType) {
|
|
42480
|
+
MessageType[MessageType["TEXT"] = 0] = "TEXT";
|
|
42481
|
+
MessageType[MessageType["FILE"] = 1] = "FILE";
|
|
42482
|
+
})(MessageType || (MessageType = {}));
|
|
42483
|
+
|
|
42484
|
+
// fix for build prod
|
|
42485
|
+
const moment$1 = moment_;
|
|
42486
|
+
class ChatBoxComponent extends ComponentBase {
|
|
42487
|
+
constructor(injector, _chatService, _messageBoardService, _userService, _checkControlVisible, _signalrService, _fileService, _crudService, _notifierService, _moduleConfigService) {
|
|
42488
|
+
super(injector);
|
|
42489
|
+
this._chatService = _chatService;
|
|
42490
|
+
this._messageBoardService = _messageBoardService;
|
|
42491
|
+
this._userService = _userService;
|
|
42492
|
+
this._checkControlVisible = _checkControlVisible;
|
|
42493
|
+
this._signalrService = _signalrService;
|
|
42494
|
+
this._fileService = _fileService;
|
|
42495
|
+
this._crudService = _crudService;
|
|
42496
|
+
this._notifierService = _notifierService;
|
|
42497
|
+
this._moduleConfigService = _moduleConfigService;
|
|
42498
|
+
this.showSendMessageBox = true;
|
|
42499
|
+
this.userPickerForm = {
|
|
42500
|
+
selectedValue: [],
|
|
42501
|
+
data: null,
|
|
42502
|
+
};
|
|
42503
|
+
this.topic = '';
|
|
42504
|
+
this.firstTime = true;
|
|
42505
|
+
this.multiple = true;
|
|
42506
|
+
this.showAddNoteForm = false;
|
|
42507
|
+
this.fileApi = '';
|
|
42508
|
+
this.peopleAll = [];
|
|
42509
|
+
this.correlationIds = [];
|
|
42510
|
+
this.attachments = [];
|
|
42511
|
+
this.image = '';
|
|
42512
|
+
this.peopleAllUsers = [];
|
|
42513
|
+
this.peopleRelatedUsers = [];
|
|
42514
|
+
this.editFormModel = {};
|
|
42515
|
+
this._moduleConfig = this._moduleConfigService.getConfig();
|
|
42516
|
+
this.environment = this._moduleConfig.environment;
|
|
42517
|
+
this.defaultAvatar = this.environment.appMetadata.main.defaultMaleAvatar;
|
|
42518
|
+
this.fileApi = this.environment.apiDomain.fileEndpoint;
|
|
42519
|
+
this.model.userPickerForm = { popupSize: PopupSize, data: {} };
|
|
42520
|
+
this.model.quickNoteForm = { popupSize: {}, data: {} };
|
|
42521
|
+
this.context.subscribe('QUICK_NOTE_POPUP.CLOSE_POPUP', response => {
|
|
42522
|
+
this.model.editFormModel.showQuickNoteForm = false;
|
|
42523
|
+
});
|
|
42524
|
+
}
|
|
42525
|
+
updateUsers(assignee, assigner, relatedUser) {
|
|
42526
|
+
this.assignee = assignee;
|
|
42527
|
+
this.assigner = assigner;
|
|
42528
|
+
this.relatedUser = relatedUser;
|
|
42529
|
+
let all = [];
|
|
42530
|
+
all.push(assignee);
|
|
42531
|
+
all.push(assigner);
|
|
42532
|
+
if (this.relatedUser.length > 0) {
|
|
42533
|
+
all = all.concat(relatedUser);
|
|
42534
|
+
}
|
|
42535
|
+
this.peopleAll = all.filter((x, i, a) => a.indexOf(x) == i);
|
|
42536
|
+
}
|
|
42537
|
+
ngOnInit() {
|
|
42538
|
+
this.initClassVar();
|
|
42539
|
+
this.getMessages(null);
|
|
42540
|
+
this._chatService.getChatIdByTask(this.serviceRequestModel, this.taskId).then(rs => {
|
|
42541
|
+
if (!rs.success)
|
|
42542
|
+
this._notifierService.showWarning(rs.message);
|
|
42543
|
+
if (!rs.data)
|
|
42544
|
+
return;
|
|
42545
|
+
this.model.id = rs.data;
|
|
42546
|
+
this.rootContext.fireEvent(ComCtxConstants.ROOT.CHAT_INSTANCE_ID_LOADED, this.model.id);
|
|
42547
|
+
this.topic = `chat.${this.model.id}`;
|
|
42548
|
+
this._signalrService.start(null, this.topic, data => this.handleChanges(data));
|
|
42549
|
+
// get pinned message
|
|
42550
|
+
if (this.model.id) {
|
|
42551
|
+
this._messageBoardService.getLatestPinnedMessage(this.model.id).then(rs => {
|
|
42552
|
+
if (rs.data) {
|
|
42553
|
+
this.model.pinnedMessage = rs.data.content;
|
|
42554
|
+
}
|
|
42555
|
+
});
|
|
42556
|
+
}
|
|
42557
|
+
});
|
|
42558
|
+
this.rootContext.subscribe(ComCtxConstants.ROOT.CHAT_MESSAGE_SENDING, (data) => __awaiter(this, void 0, void 0, function* () {
|
|
42559
|
+
this.model.correlationIds.push(data.message.correlationId);
|
|
42560
|
+
if (data.attachments && data.attachments.length > 0) {
|
|
42561
|
+
data.attachments = data.attachments.map(x => {
|
|
42562
|
+
x.url = null;
|
|
42563
|
+
return x;
|
|
42564
|
+
});
|
|
42565
|
+
}
|
|
42566
|
+
const temp = yield this.appendMessage(data.message.messageContent, 'own', 'sending', this.currentUser.userName, data.attachments, data.message.correlationId, false);
|
|
42567
|
+
console.log(temp);
|
|
42568
|
+
}));
|
|
42569
|
+
this.rootContext.subscribe(ComCtxConstants.ROOT.CHAT_MESSAGE_SENT, data => {
|
|
42570
|
+
});
|
|
42571
|
+
this.rootContext.subscribe(ComCtxConstants.ROOT.CHAT_LOAD_MORE, data => {
|
|
42572
|
+
// this.getMessages(this.model.createdFrom);
|
|
42573
|
+
});
|
|
42574
|
+
this.rootContext.subscribe(ComCtxConstants.ROOT.CHAT_SCROLLING, scrolling => {
|
|
42575
|
+
if (scrolling) {
|
|
42576
|
+
this.model.scrolling = true;
|
|
42577
|
+
}
|
|
42578
|
+
else {
|
|
42579
|
+
this.model.scrolling = false;
|
|
42580
|
+
this.model.newMessageNotUpdatedCount = 0;
|
|
42581
|
+
}
|
|
42582
|
+
});
|
|
42583
|
+
this.rootContext.subscribe(ComCtxConstants.ROOT.CHAT_HAS_NEW_MESSAGE_NOT_UPDATED, count => {
|
|
42584
|
+
this.model.scrolling = count !== 0;
|
|
42585
|
+
this.model.newMessageNotUpdatedCount = count;
|
|
42586
|
+
});
|
|
42587
|
+
this.context.subscribe('CLOSE_POPUP', rs => {
|
|
42588
|
+
this.model.userPickerForm.show = false;
|
|
42589
|
+
this.parentContext.fireEvent('TASK.RELATED_USER_CHANGED', rs);
|
|
42590
|
+
});
|
|
42591
|
+
this.parentContext.subscribe('TASK.DATA_CHANGED', rs => {
|
|
42592
|
+
this.updateUsers(rs.assignee, rs.assigner, rs.relatedUser);
|
|
42593
|
+
});
|
|
42594
|
+
}
|
|
42595
|
+
handleChanges(data) {
|
|
42596
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
42597
|
+
const newMessage = JSON.parse(data);
|
|
42598
|
+
if (!newMessage || !newMessage.data) {
|
|
42599
|
+
this._notifierService.showWarning('SYS_ERR_DEV: Lỗi SignalR');
|
|
42600
|
+
return;
|
|
42601
|
+
}
|
|
42602
|
+
switch (newMessage.notificationType) {
|
|
42603
|
+
case NotificationType.NewMessage:
|
|
42604
|
+
case NEW_MESSAGE: {
|
|
42605
|
+
yield this.handleNewMessageNotification(newMessage.data);
|
|
42606
|
+
break;
|
|
42607
|
+
}
|
|
42608
|
+
case NotificationType.PinnedChanged:
|
|
42609
|
+
case PINNED_CHANGED: {
|
|
42610
|
+
const ind = this.model.correlationIds.findIndex(x => x == newMessage.correlationId);
|
|
42611
|
+
if (ind > -1) {
|
|
42612
|
+
this.model.correlationIds.splice(ind, 1);
|
|
42613
|
+
}
|
|
42614
|
+
else {
|
|
42615
|
+
yield this.handlePinnedChangeNotification(newMessage.data);
|
|
42616
|
+
}
|
|
42617
|
+
break;
|
|
42618
|
+
}
|
|
42619
|
+
}
|
|
42620
|
+
});
|
|
42621
|
+
}
|
|
42622
|
+
initClassVar() {
|
|
42623
|
+
this.fileViewerModel = {
|
|
42624
|
+
data: {},
|
|
42625
|
+
showEditForm: false,
|
|
42626
|
+
};
|
|
42627
|
+
this.userPickerControl = new UserPickerControlSchema({
|
|
42628
|
+
field: 'id',
|
|
42629
|
+
label: '',
|
|
42630
|
+
fullLabel: '',
|
|
42631
|
+
multiple: true,
|
|
42632
|
+
hiddenCheck: () => this.userPickerForm.show,
|
|
42633
|
+
});
|
|
42634
|
+
this.serviceRequestModel = {
|
|
42635
|
+
service: this.serviceCode,
|
|
42636
|
+
serviceCode: this.serviceCode,
|
|
42637
|
+
entity: this.entity,
|
|
42638
|
+
entityKey: 'id',
|
|
42639
|
+
entityInstanceId: this.taskId
|
|
42640
|
+
};
|
|
42641
|
+
this.model.dataSource = [];
|
|
42642
|
+
this.model.correlationIds = [];
|
|
42643
|
+
this.model.attachments = [];
|
|
42644
|
+
this.model.maxFileSize = 3000000;
|
|
42645
|
+
this.model.img = {};
|
|
42646
|
+
this.currentUser = this._userService.getCurrentUser();
|
|
42647
|
+
this.peopleAllUsers = [];
|
|
42648
|
+
this.peopleRelatedUsers = [];
|
|
42649
|
+
this.model.editFormModel = [];
|
|
42650
|
+
if (this.users) {
|
|
42651
|
+
this.model.taskName = this.users.taskName;
|
|
42652
|
+
this.updateUsers(this.users.assignee, this.users.assigner, this.users.relatedUsers);
|
|
42653
|
+
this.getRelatedUserInfo();
|
|
42654
|
+
}
|
|
42655
|
+
}
|
|
42656
|
+
getRelatedUserInfo() {
|
|
42657
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
42658
|
+
const peopleRelatedUsers = yield this._userService.getBasicUsersInfo(this.relatedUser.join());
|
|
42659
|
+
if (peopleRelatedUsers == null || peopleRelatedUsers.length == 0) {
|
|
42660
|
+
return;
|
|
42661
|
+
}
|
|
42662
|
+
for (const item of peopleRelatedUsers) {
|
|
42663
|
+
this.peopleRelatedUsers.push({
|
|
42664
|
+
title: item.fullName,
|
|
42665
|
+
label: item.fullName,
|
|
42666
|
+
value: item.id
|
|
42667
|
+
});
|
|
42668
|
+
}
|
|
42669
|
+
});
|
|
42670
|
+
}
|
|
42671
|
+
handlePinnedChangeNotification(data) {
|
|
42672
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
42673
|
+
if (data.pinned) {
|
|
42674
|
+
this.model.pinnedMessage = data.message;
|
|
42675
|
+
}
|
|
42676
|
+
else {
|
|
42677
|
+
this.model.pinnedMessage = null;
|
|
42678
|
+
}
|
|
42679
|
+
});
|
|
42680
|
+
}
|
|
42681
|
+
handleNewMessageNotification(newMessage) {
|
|
42682
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
42683
|
+
const ind = this.model.correlationIds.findIndex(x => x == newMessage.correlationId);
|
|
42684
|
+
if (newMessage.messageType == MessageType.FILE) {
|
|
42685
|
+
newMessage.attachments = yield this._chatService.getListAttachment(newMessage.id);
|
|
42686
|
+
}
|
|
42687
|
+
if (ind === -1) {
|
|
42688
|
+
yield this.appendMessage(newMessage.content, this.getTypeOfMessage(newMessage.createdBy), 'received', newMessage.createdBy, newMessage.attachments, '', true);
|
|
42689
|
+
}
|
|
42690
|
+
else {
|
|
42691
|
+
this.updateMessage(newMessage.correlationId, newMessage);
|
|
42692
|
+
this.model.correlationIds.splice(ind, 1);
|
|
42693
|
+
}
|
|
42694
|
+
});
|
|
42695
|
+
}
|
|
42696
|
+
getMessages(createdFrom) {
|
|
42697
|
+
this._chatService.getContentByTaskId(this.serviceRequestModel, this.taskId).then((rs) => __awaiter(this, void 0, void 0, function* () {
|
|
42698
|
+
const currentUserName = this.currentUser.userName;
|
|
42699
|
+
let nearByCreated = '';
|
|
42700
|
+
let index = 0;
|
|
42701
|
+
let userNames = '';
|
|
42702
|
+
if (!rs.success) {
|
|
42703
|
+
return this._notifierService.showWarning(rs.message);
|
|
42704
|
+
}
|
|
42705
|
+
for (const item of rs.data) {
|
|
42706
|
+
if (item.createdBy && item.createdBy != '')
|
|
42707
|
+
userNames += `${index == 0 ? '' : ','}${item.createdBy}`;
|
|
42708
|
+
if (index === 0)
|
|
42709
|
+
this.model.createdFrom = item.created;
|
|
42710
|
+
item.type = item.createdBy === currentUserName ? 'own' : 'from';
|
|
42711
|
+
if (item.messageType === MessageType.FILE) {
|
|
42712
|
+
item.attachments = yield this._chatService.getListAttachment(item.id);
|
|
42713
|
+
}
|
|
42714
|
+
item.isLastMessageFlow = false;
|
|
42715
|
+
if (item.createdBy !== nearByCreated) {
|
|
42716
|
+
if (+item > -0) {
|
|
42717
|
+
rs.data[+item - 1].isLastMessageFlow = true;
|
|
42718
|
+
}
|
|
42719
|
+
nearByCreated = item.createdBy;
|
|
42720
|
+
item.isFirstMessageFlow = true;
|
|
42721
|
+
}
|
|
42722
|
+
else {
|
|
42723
|
+
item.isFirstMessageFlow = false;
|
|
42724
|
+
}
|
|
42725
|
+
if (+index === rs.data.length - 1)
|
|
42726
|
+
item.isLastMessageFlow = true;
|
|
42727
|
+
index++;
|
|
42728
|
+
}
|
|
42729
|
+
if (createdFrom) {
|
|
42730
|
+
this.model.dataSource = [...rs.data, ...this.model.dataSource];
|
|
42731
|
+
}
|
|
42732
|
+
else {
|
|
42733
|
+
this.model.dataSource = rs.data;
|
|
42734
|
+
}
|
|
42735
|
+
if (userNames != '') {
|
|
42736
|
+
const userInfos = yield this._userService.getBasicUsersInfoByUserNames(userNames);
|
|
42737
|
+
if (userInfos != null) {
|
|
42738
|
+
for (const item of this.model.dataSource) {
|
|
42739
|
+
const user = userInfos.find(x => x.userName == item.createdBy);
|
|
42740
|
+
if (!user) {
|
|
42741
|
+
continue;
|
|
42742
|
+
}
|
|
42743
|
+
item.avatar = user.avatar;
|
|
42744
|
+
item.fullName = user.fullName;
|
|
42745
|
+
}
|
|
42746
|
+
}
|
|
42747
|
+
}
|
|
42748
|
+
this.rootContext.fireEvent(ComCtxConstants.ROOT.CHAT_DATA_LOADED, true);
|
|
42749
|
+
}));
|
|
42750
|
+
}
|
|
42751
|
+
scrollToBottom(speed = 0, force = false, sent) {
|
|
42752
|
+
if (!this.model.scrolling) {
|
|
42753
|
+
this.rootContext.fireEvent(ComCtxConstants.ROOT.CHAT_HAS_NEW_MESSAGE, { speed, force: true });
|
|
42754
|
+
}
|
|
42755
|
+
else if (sent !== false) {
|
|
42756
|
+
this.rootContext.fireEvent(ComCtxConstants.ROOT.CHAT_HAS_NEW_MESSAGE, { speed, force });
|
|
42757
|
+
}
|
|
42758
|
+
}
|
|
42759
|
+
appendMessage(message, type, status, createdBy, attachments = [], correlationId = '', sent) {
|
|
42760
|
+
var _a, _b;
|
|
42761
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
42762
|
+
let fullName = '';
|
|
42763
|
+
let avatar = '';
|
|
42764
|
+
const user = yield this._userService.getBasicUserInfoByUserName(createdBy);
|
|
42765
|
+
fullName = (_a = user.fullName) !== null && _a !== void 0 ? _a : '';
|
|
42766
|
+
avatar = (_b = user.avatar) !== null && _b !== void 0 ? _b : '';
|
|
42767
|
+
if (attachments && attachments.length > 0) {
|
|
42768
|
+
const clonedAttachment = JSON.parse(JSON.stringify(attachments));
|
|
42769
|
+
this.model.dataSource.push({
|
|
42770
|
+
created: new Date(),
|
|
42771
|
+
createdBy: createdBy,
|
|
42772
|
+
fullName: fullName,
|
|
42773
|
+
status: status,
|
|
42774
|
+
type: type,
|
|
42775
|
+
avatar: avatar,
|
|
42776
|
+
attachments: clonedAttachment,
|
|
42777
|
+
correlationId: correlationId,
|
|
42778
|
+
isFirstMessageFlow: false,
|
|
42779
|
+
isLastMessageFlow: false,
|
|
42780
|
+
sent: sent
|
|
42781
|
+
});
|
|
42782
|
+
this.updateFirstOrLastMessage();
|
|
42783
|
+
}
|
|
42784
|
+
if (message && message.trim() != '') {
|
|
42785
|
+
this.model.dataSource.push({
|
|
42786
|
+
created: new Date(),
|
|
42787
|
+
createdBy: createdBy,
|
|
42788
|
+
fullName: fullName,
|
|
42789
|
+
content: message,
|
|
42790
|
+
status: status,
|
|
42791
|
+
type: type,
|
|
42792
|
+
avatar: avatar,
|
|
42793
|
+
correlationId: correlationId,
|
|
42794
|
+
isFirstMessageFlow: false,
|
|
42795
|
+
isLastMessageFlow: false,
|
|
42796
|
+
sent: sent
|
|
42797
|
+
});
|
|
42798
|
+
this.updateFirstOrLastMessage();
|
|
42799
|
+
}
|
|
42800
|
+
return this.model.dataSource;
|
|
42801
|
+
});
|
|
42802
|
+
}
|
|
42803
|
+
updateFirstOrLastMessage() {
|
|
42804
|
+
if (this.model.dataSource.length > 0) {
|
|
42805
|
+
const length = this.model.dataSource.length;
|
|
42806
|
+
if (length === 1) {
|
|
42807
|
+
this.model.dataSource[0].isFirstMessageFlow = true;
|
|
42808
|
+
}
|
|
42809
|
+
else {
|
|
42810
|
+
const createdBy = this.model.dataSource[length - 2].createdBy;
|
|
42811
|
+
const createdBy2 = this.model.dataSource[length - 1].createdBy;
|
|
42812
|
+
if (createdBy !== createdBy2) {
|
|
42813
|
+
this.model.dataSource[length - 2].isLastMessageFlow = true;
|
|
42814
|
+
this.model.dataSource[length - 1].isFirstMessageFlow = true;
|
|
42815
|
+
}
|
|
42816
|
+
else {
|
|
42817
|
+
this.model.dataSource[length - 2].isLastMessageFlow = false;
|
|
42818
|
+
this.model.dataSource[length - 1].isLastMessageFlow = true;
|
|
42819
|
+
}
|
|
42820
|
+
}
|
|
42821
|
+
}
|
|
42822
|
+
}
|
|
42823
|
+
updateMessage(correlationId, message) {
|
|
42824
|
+
const item = this.model.dataSource.find(x => x.correlationId === correlationId);
|
|
42825
|
+
if (item) {
|
|
42826
|
+
if (message.attachments && message.attachments.length > 0) {
|
|
42827
|
+
item.attachments = message.attachments;
|
|
42828
|
+
}
|
|
42829
|
+
item.id = message.id;
|
|
42830
|
+
item.sent = true;
|
|
42831
|
+
}
|
|
42832
|
+
}
|
|
42833
|
+
updateMessageStatus(message, status, errorMessage = '') {
|
|
42834
|
+
const item = this.model.dataSource.find(x => x.message === message);
|
|
42835
|
+
item.status = status;
|
|
42836
|
+
item.errorMessage = errorMessage;
|
|
42837
|
+
}
|
|
42838
|
+
getDisplayStatus(status) {
|
|
42839
|
+
switch (status) {
|
|
42840
|
+
case 'sending':
|
|
42841
|
+
return 'Đang gửi';
|
|
42842
|
+
case 'sent':
|
|
42843
|
+
return 'Đã gửi';
|
|
42844
|
+
default:
|
|
42845
|
+
return '';
|
|
42846
|
+
}
|
|
42847
|
+
}
|
|
42848
|
+
ngOnDestroy() {
|
|
42849
|
+
// unscrible signalr
|
|
42850
|
+
this._signalrService.unSubscribeViewCode(null, this.topic);
|
|
42851
|
+
this.rootContext.unSubscribe(ComCtxConstants.ROOT.CHAT_MESSAGE_SENDING);
|
|
42852
|
+
this.rootContext.unSubscribe(ComCtxConstants.ROOT.CHAT_MESSAGE_SENT);
|
|
42853
|
+
this.rootContext.unSubscribe(ComCtxConstants.ROOT.CHAT_LOAD_MORE);
|
|
42854
|
+
this.rootContext.unSubscribe(ComCtxConstants.ROOT.CHAT_SCROLLING);
|
|
42855
|
+
this.rootContext.unSubscribe(ComCtxConstants.ROOT.CHAT_HAS_NEW_MESSAGE_NOT_UPDATED);
|
|
42856
|
+
super.ngOnDestroy();
|
|
42857
|
+
}
|
|
42858
|
+
getTypeOfMessage(createdBy) {
|
|
42859
|
+
return createdBy === this.currentUser.userName ? 'own' : 'from';
|
|
42860
|
+
}
|
|
42861
|
+
trackByFunc(index, item) {
|
|
42862
|
+
return item.id;
|
|
42863
|
+
}
|
|
42864
|
+
trackAttachmentByFunc(index, item) {
|
|
42865
|
+
return item.fileName;
|
|
42866
|
+
}
|
|
42867
|
+
handlePaste(event) {
|
|
42868
|
+
const objectData = this.getImageClipboardData(event);
|
|
42869
|
+
if (objectData) {
|
|
42870
|
+
this.model.attachments.push({
|
|
42871
|
+
type: 'image',
|
|
42872
|
+
url: objectData.url,
|
|
42873
|
+
data: objectData.blob,
|
|
42874
|
+
fileName: this._commonService.guid() + '.png'
|
|
42875
|
+
});
|
|
42876
|
+
}
|
|
42877
|
+
}
|
|
42878
|
+
getImageClipboardData(e) {
|
|
42879
|
+
for (let i = 0; i < e.clipboardData.items.length; i++) {
|
|
42880
|
+
const item = e.clipboardData.items[i];
|
|
42881
|
+
if (item.type.indexOf('image') != -1) {
|
|
42882
|
+
const imageObj = item.getAsFile();
|
|
42883
|
+
if (imageObj.size < this.model.maxFileSize) {
|
|
42884
|
+
return { url: URL.createObjectURL(imageObj), blob: imageObj };
|
|
42885
|
+
}
|
|
42886
|
+
else {
|
|
42887
|
+
return null;
|
|
42888
|
+
}
|
|
42889
|
+
}
|
|
42890
|
+
}
|
|
42891
|
+
return null;
|
|
42892
|
+
}
|
|
42893
|
+
viewOrDownloadFile(evt, attachmentItem) {
|
|
42894
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
42895
|
+
if (this._fileService.isSupportedViewOnline(attachmentItem.fileName)) {
|
|
42896
|
+
// this.model.fileViewer.data = {};
|
|
42897
|
+
// this.model.fileViewer.data.fileId = attachmentItem.id;
|
|
42898
|
+
// this.model.fileViewer.data.fileName = attachmentItem.fileName;
|
|
42899
|
+
// this.model.fileViewer.data.isFileVersion = false;
|
|
42900
|
+
// this.model.fileViewer.show = true;
|
|
42901
|
+
this.fileViewerModel = {
|
|
42902
|
+
data: {
|
|
42903
|
+
fileId: attachmentItem.id,
|
|
42904
|
+
fileName: attachmentItem.fileName,
|
|
42905
|
+
isFileVersion: false,
|
|
42906
|
+
},
|
|
42907
|
+
showEditForm: true,
|
|
42908
|
+
};
|
|
42909
|
+
}
|
|
42910
|
+
else {
|
|
42911
|
+
top.location.href = yield this.getDownloadLink(attachmentItem);
|
|
42912
|
+
}
|
|
42913
|
+
});
|
|
42914
|
+
}
|
|
42915
|
+
getDownloadLink(file) {
|
|
42916
|
+
return new Promise((resolve, reject) => {
|
|
42917
|
+
const model = new GenerateLinkDownloadDTO();
|
|
42918
|
+
model.fileId = file.id;
|
|
42919
|
+
model.isFileVersion = false;
|
|
42920
|
+
this._fileService.generateLinkDownload(model)
|
|
42921
|
+
.then(response => {
|
|
42922
|
+
const downloadUrl = this._fileService.getAnonymousDownloadUrl(response.data);
|
|
42923
|
+
resolve(downloadUrl);
|
|
42924
|
+
}, error => {
|
|
42925
|
+
throw new Error('Cannot get download link');
|
|
42926
|
+
});
|
|
42927
|
+
});
|
|
42928
|
+
}
|
|
42929
|
+
browseFileFromPersonal() {
|
|
42930
|
+
}
|
|
42931
|
+
browseFileFromComputer() {
|
|
42932
|
+
this.fileElement.advancedFileInput.nativeElement.click();
|
|
42933
|
+
}
|
|
42934
|
+
onSelectFileFromComputer(evt) {
|
|
42935
|
+
try {
|
|
42936
|
+
if (evt.files && evt.files.length > 0) {
|
|
42937
|
+
for (let index = 0; index < evt.files.length; index++) {
|
|
42938
|
+
const fileName = evt.files[index].name;
|
|
42939
|
+
const type = this._commonService.isImage(fileName) ? 'image' : 'file';
|
|
42940
|
+
const attachmentItem = {
|
|
42941
|
+
type: type,
|
|
42942
|
+
data: evt.files[index], fileName: fileName
|
|
42943
|
+
};
|
|
42944
|
+
if (attachmentItem.type == 'image') {
|
|
42945
|
+
attachmentItem.url = evt.files[index].objectURL.changingThisBreaksApplicationSecurity;
|
|
42946
|
+
}
|
|
42947
|
+
this.model.attachments.push(attachmentItem);
|
|
42948
|
+
}
|
|
42949
|
+
}
|
|
42950
|
+
}
|
|
42951
|
+
catch (e) {
|
|
42952
|
+
console.error('error on process select file computer', e);
|
|
42953
|
+
}
|
|
42954
|
+
// this.fileElement.clear();
|
|
42955
|
+
}
|
|
42956
|
+
removeAttachment(item) {
|
|
42957
|
+
const ind = this.model.attachments.findIndex(x => x.url === item.url);
|
|
42958
|
+
this.model.attachments.splice(ind, 1);
|
|
42959
|
+
}
|
|
42960
|
+
hasAttachment(item) {
|
|
42961
|
+
return item.attachments && item.attachments.length > 0;
|
|
42962
|
+
}
|
|
42963
|
+
loadImg(evt, parentIndex, index) {
|
|
42964
|
+
this.model.img[`${parentIndex}${index}`] = true;
|
|
42965
|
+
this.model.img[`${parentIndex}width${index}`] = (evt.target.width + 32) + 'px';
|
|
42966
|
+
}
|
|
42967
|
+
inTheSameTime(i, item, dataSource) {
|
|
42968
|
+
if (i < dataSource.length - 1) {
|
|
42969
|
+
const d1 = new Date(dataSource[i + 1].created);
|
|
42970
|
+
const d2 = new Date(item.created);
|
|
42971
|
+
const ms = d1.getTime() - d2.getTime();
|
|
42972
|
+
return ms < 30000;
|
|
42973
|
+
}
|
|
42974
|
+
return false;
|
|
42975
|
+
}
|
|
42976
|
+
pinMessage(item) {
|
|
42977
|
+
if (this.model.pinnedMessage) {
|
|
42978
|
+
if (this.model.pinnedMessage.id != item.id) {
|
|
42979
|
+
this._notifierService.showConfirm('Bạn có chắc chắn muốn ghim tin nhắn này? Tin nhắn đã ghim trước đó sẽ được bỏ ghim.').then(rs => {
|
|
42980
|
+
if (!rs)
|
|
42981
|
+
return;
|
|
42982
|
+
this.doPin(item, item.id, true);
|
|
42983
|
+
});
|
|
42984
|
+
}
|
|
42985
|
+
else {
|
|
42986
|
+
this.doPin(item, item.id, false);
|
|
42987
|
+
}
|
|
42988
|
+
}
|
|
42989
|
+
else {
|
|
42990
|
+
this.doPin(item, item.id, true);
|
|
42991
|
+
}
|
|
42992
|
+
}
|
|
42993
|
+
doPin(item, id, pinned) {
|
|
42994
|
+
const correlationId = this._commonService.guid();
|
|
42995
|
+
this.model.correlationIds.push(correlationId);
|
|
42996
|
+
this._messageBoardService.pinMessage(id, pinned, correlationId).then(rs => {
|
|
42997
|
+
if (pinned) {
|
|
42998
|
+
this.model.pinnedMessage = item;
|
|
42999
|
+
}
|
|
43000
|
+
else {
|
|
43001
|
+
this.model.pinnedMessage = null;
|
|
43002
|
+
}
|
|
43003
|
+
});
|
|
43004
|
+
}
|
|
43005
|
+
getCurrentUserAvatar(avatar) {
|
|
43006
|
+
if (avatar != null) {
|
|
43007
|
+
return `${this.fileApi}/file/public/${avatar}/Download`;
|
|
43008
|
+
}
|
|
43009
|
+
else {
|
|
43010
|
+
return this.defaultAvatar;
|
|
43011
|
+
}
|
|
43012
|
+
}
|
|
43013
|
+
addPeople() {
|
|
43014
|
+
this.userPickerForm.selectedValue = this.peopleRelatedUsers;
|
|
43015
|
+
this.userPickerForm.multiple = this.multiple;
|
|
43016
|
+
this.userPickerForm.show = true;
|
|
43017
|
+
}
|
|
43018
|
+
quickNote(item) {
|
|
43019
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
43020
|
+
const userResult = yield this._userService.getBasicUserInfo(item.createdBy);
|
|
43021
|
+
this.context.data.noteDataModel = {
|
|
43022
|
+
editFormModel: {
|
|
43023
|
+
showEditForm: true,
|
|
43024
|
+
showQuickNoteForm: true,
|
|
43025
|
+
popupSize: {},
|
|
43026
|
+
data: {
|
|
43027
|
+
name: item.content1,
|
|
43028
|
+
content: '<b>' + userResult.fullName + '</b>' + ' đã chat tại công việc '
|
|
43029
|
+
+ '<b>' + this.model.taskName + '</b>' + ' với nội dung '
|
|
43030
|
+
+ '<b>' + item.content1 + '</b>' + ' vào lúc ' + moment$1(new Date(item.created)).format('YYYY-MM-DD hh:mm:ss A')
|
|
43031
|
+
}
|
|
43032
|
+
}
|
|
43033
|
+
};
|
|
43034
|
+
this.model.editFormModel.showQuickNoteForm = true;
|
|
43035
|
+
this.showAddNoteForm = true;
|
|
43036
|
+
});
|
|
43037
|
+
}
|
|
43038
|
+
onMouseUp(event) {
|
|
43039
|
+
event.cancelBubble = true;
|
|
43040
|
+
event.stopPropagation();
|
|
43041
|
+
}
|
|
43042
|
+
addClassToMessage(item, isPinnedMessage) {
|
|
43043
|
+
let styleClass = '';
|
|
43044
|
+
if (!isPinnedMessage) {
|
|
43045
|
+
if (item.isFirstMessageFlow) {
|
|
43046
|
+
styleClass = 'first';
|
|
43047
|
+
}
|
|
43048
|
+
else if (item.isLastMessageFlow) {
|
|
43049
|
+
styleClass = 'last';
|
|
43050
|
+
}
|
|
43051
|
+
else {
|
|
43052
|
+
styleClass = 'middle';
|
|
43053
|
+
}
|
|
43054
|
+
}
|
|
43055
|
+
if (item.sent == false) {
|
|
43056
|
+
styleClass = 'sending';
|
|
43057
|
+
}
|
|
43058
|
+
return styleClass;
|
|
43059
|
+
}
|
|
43060
|
+
}
|
|
43061
|
+
ChatBoxComponent.decorators = [
|
|
43062
|
+
{ type: Component, args: [{
|
|
43063
|
+
selector: 'chat-box',
|
|
43064
|
+
template: "<div class=\"dashboard\">\r\n <div class=\"chat\">\r\n <div class=\"group-info\">\r\n <a href=\"javascript:\">C\u00F3 {{peopleAll.length}} ng\u01B0\u1EDDi trong nh\u00F3m n\u00E0y</a>\r\n <div class=\"circleButton\" pTooltip=\"Xem to\u00E0n b\u1ED9 \u0111\u00EDnh k\u00E8m\" tooltipPosition=\"top\">\r\n <a href=\"javascript:\"><i class=\"far fa-images\"></i></a>\r\n </div>\r\n <div (click)=\"addPeople()\" class=\"circleButton\" pTooltip=\"Th\u00EAm m\u1EDBi ng\u01B0\u1EDDi v\u00E0o nh\u00F3m\" tooltipPosition=\"top\"\r\n disabled=\"true\">\r\n <a href=\"javascript:\"><i class=\"fas fa-user-plus\"></i></a>\r\n </div>\r\n </div>\r\n <ul #scrollMe [ngClass]=\"{'hasPin': model.pinnedMessage != null}\">\r\n <li *ngIf=\"model.pinnedMessage\" class=\"clearfix pin\" [ngClass]=\"{'message-from': true}\">\r\n <ng-container\r\n *ngTemplateOutlet=\"messageItem; context: { i : -1, item: model.pinnedMessage, isPinnedMessage: true}\">\r\n </ng-container>\r\n </li>\r\n <li *ngFor=\"let item of model.dataSource; let i = index; trackBy: trackByFunc\" class=\"clearfix\"\r\n [ngClass]=\"{ 'message-own': item.type == 'own'}\">\r\n <ng-container *ngTemplateOutlet=\"messageItem; context: { i : i, item: item}\">\r\n </ng-container>\r\n </li>\r\n </ul>\r\n <!-- <chat-send-message-box *ngIf=\"showSendMessageBox\"></chat-send-message-box>-->\r\n <div [ngClass]=\"{'visible2': model.scrolling, 'hidden2': !model.scrolling}\" class=\"scroll-to-bottom\">\r\n <span *ngIf=\"model.newMessageNotUpdatedCount > 0\" (click)=\"scrollToBottom(350, true, null)\">\r\n {{model.newMessageNotUpdatedCount <= 5 ? model.newMessageNotUpdatedCount : '5+' }} </span>\r\n <span (click)=\"scrollToBottom(350, true, null)\" *ngIf=\"model.newMessageNotUpdatedCount == 0\">\r\n <i class=\"fas fa-chevron-down\"></i>\r\n </span>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<file-viewer *ngIf=\"fileViewerModel.showEditForm\" [parentContext]=\"context\" [parentModel]=\"model\"\r\n [model]=\"fileViewerModel\">\r\n</file-viewer>\r\n\r\n<ng-template #messageItem let-i=\"i\" let-isPinnedMessage=\"isPinnedMessage\" let-item=\"item\">\r\n <img *ngIf=\"item.isFirstMessageFlow && item.type != 'own' && !isPinnedMessage && item.avatar != null\" alt=\"\"\r\n class=\"chat-avatar\" src=\"{{getCurrentUserAvatar(item.avatar)}}\">\r\n <p *ngIf=\"(item.isFirstMessageFlow && item.type != 'own') && !isPinnedMessage\" class=\"message-created-by\">\r\n {{item.fullName}}\r\n </p>\r\n <span *ngIf=\"!hasAttachment(item)\">\r\n <!-- [class]=\"addClassToMessage(item, isPinnedMessage)\">-->\r\n <p *ngIf=\"!hasAttachment(item)\" class=\"message-content\">\r\n <i (click)=\"pinMessage(item)\" class=\"fas fa-thumbtack\" style=\"right: 0;\"></i>\r\n <i (click)=\"quickNote(item)\" class=\"fas fa-sticky-note\"></i>\r\n {{item.content}}\r\n </p>\r\n <p *ngIf=\"!isPinnedMessage && (item.isLastMessageFlow || !inTheSameTime(i, item, model.dataSource))\"\r\n class=\"message-created\" pTooltip=\"{{item.created | date:'dd/MM/yyyy HH:mm'}}\"\r\n tooltipPosition=\"{{item.type != 'own'?'right':'left'}}\">\r\n {{_crudService.renderDateTime(item.created)}}\r\n </p>\r\n <p *ngIf=\"isPinnedMessage\" class=\"message-created\">\r\n {{item.createdBy}} \u0111\u00E3 g\u1EEDi l\u00FAc {{item.created | date:'dd/MM/yyyy HH:mm'}}\r\n </p>\r\n </span>\r\n <ng-container *ngIf=\"hasAttachment(item)\">\r\n <ng-container *ngFor=\"let attachmentItem of item.attachments;let index=index\">\r\n <div class=\"file\"\r\n [ngClass]=\"{'first':item.isFirstMessageFlow && index == 0, 'middle':index > 0 || !item.isFirstMessageFlow, 'image' : attachmentItem.type == 'image'}\"\r\n [ngStyle]=\"{'width': model.img[i + 'width' + index]}\">\r\n <p class=\"attachment\">\r\n <span (mouseup)=\"onMouseUp($event)\" class=\"attachment-item\">\r\n <a *ngIf=\"attachmentItem.type != 'image'\" (click)=\"viewOrDownloadFile($event, attachmentItem)\">\r\n <i class=\"fas fa-paperclip\"></i>{{attachmentItem.fileName}}\r\n </a>\r\n <a *ngIf=\"attachmentItem.type == 'image'\" #aElement\r\n [ngClass]=\"{'hidden': !model.img[i + '' + index], 'visible':model.img[i + '' + index]}\"\r\n (click)=\"viewOrDownloadFile($event, attachmentItem)\">\r\n <img class=\"message-img\" (load)=\"loadImg($event, i, index)\"\r\n [src]=\"attachmentItem.url | secure | async\" />\r\n </a>\r\n </span>\r\n </p>\r\n <div style=\"clear: both\"></div>\r\n <p class=\"message-created\" pTooltip=\"{{item.created | date:'dd/MM/yyyy HH:mm'}}\"\r\n tooltipPosition=\"{{item.type != 'own'?'right':'left'}}\">\r\n {{_crudService.renderDateTime(item.created)}}\r\n </p>\r\n </div>\r\n <div style=\"clear: both\"></div>\r\n </ng-container>\r\n </ng-container>\r\n <after-view-checked *ngIf=\"model.dataSource.length == i + 1\" (loading)=\"scrollToBottom(0, false, item.sent)\">\r\n </after-view-checked>\r\n</ng-template>\r\n\r\n<!--<tn-dialog *ngIf=\"userPickerForm.show\" #dialog [styleClass]=\"'tn-form-dialog'\"-->\r\n<!-- [header]=\"'Th\u00EAm m\u1EDBi ng\u01B0\u1EDDi d\u00F9ng' | translate\" [popupSize]=\"userPickerForm.popupSize\"-->\r\n<!-- (onCancel)=\"userPickerForm.show = false\"-->\r\n<!-- (onHide)=\"userPickerForm.show = false\">-->\r\n<!-- <!– <congviec-form #formBase [parentModel]=\"model\" [parentContext]=\"context\" [model]=\"formModel\"–>-->\r\n<!-- <!– (onSaved)=\"showDetailForm = false;crudList.reload()\" (onCancel)=\"_handleCancel($event)\"–>-->\r\n<!-- <!– (onAfterSaved)=\"onAfterSaved($event)\"></congviec-form>–>-->\r\n<!-- <user-picker-box #formBase [control]=\"userPickerControl\"-->\r\n<!-- [(ngModel)]=\"this.peopleAll\" [multiple]=\"userPickerControl.multiple\">-->\r\n<!-- </user-picker-box>-->\r\n<!--</tn-dialog>-->\r\n\r\n\r\n<!--<tn-dialog *ngIf=\"userPickerForm.show\" #dialog [styleClass]=\"'tn-form-dialog'\"-->\r\n<!-- [header]=\"'Th\u00EAm m\u1EDBi ng\u01B0\u1EDDi d\u00F9ng' | translate\" [popupSize]=\"userPickerForm.popupSize\" (onHide)=\"userPickerForm.show == false\">-->\r\n<!-- <!– <congviec-form #formBase [parentModel]=\"model\" [parentContext]=\"context\" [model]=\"formModel\"–>-->\r\n<!-- <!– (onSaved)=\"showDetailForm = false;crudList.reload()\" (onCancel)=\"_handleCancel($event)\"–>-->\r\n<!-- <!– (onAfterSaved)=\"onAfterSaved($event)\"></congviec-form>–>-->\r\n\r\n<!-- <!–<quick-add-form *ngIf=\"model.editFormModel.showQuickNoteForm\" [parentContext]=\"context\"–>-->\r\n<!-- <!– [parentModel]=\"context.data.noteDataModel\"></quick-add-form>–>-->\r\n<!--</tn-dialog>-->",
|
|
43065
|
+
providers: [ComponentContextService, CheckControlVisibleService],
|
|
43066
|
+
styles: [".paging-advance{list-style:none;margin:3px 0;padding-left:0}.paging-advance li{line-height:30;padding-left:15px;width:150px}.paging-advance li.disabled{color:#bdbdbd;outline:none}.paging-advance li.disabled:hover{background:none;cursor:default}.paging-advance li:hover{background:red;cursor:pointer}.paging-advance-overlay .ui-overlaypanel-content{padding:0}.paging-advance-overlay.ui-overlaypanel-shifted:before{left:1.25em;margin-left:-10;right:auto}.paging-advance-overlay.ui-overlaypanel-shifted:after{left:1.25em;margin-left:-8px;right:auto}.chat-avatar{border:2px solid #eee;height:36px}", "@charset \"UTF-8\";@import url(C:\\Users\\vietp\\source\\repos\\5.1\\shared\\AppSharedV5\\node_modules\\@angular\\material\\prebuilt-themes\\indigo-pink.css);@import url(C:\\Users\\vietp\\source\\repos\\5.1\\shared\\AppSharedV5\\node_modules\\jsoneditor\\dist\\jsoneditor.min.css);.flex{display:flex}.flex .fit{flex:1 1}.flex.flex-column{flex-direction:column}.flex.flex-wrap{flex-wrap:wrap}.flex.center-v{align-items:center}.flex.center-all,.flex.center-h{justify-content:center}.flex.center-all{align-items:center}.validate-item{color:#e00000;display:inline-block;font-size:.9em;white-space:nowrap}.tn-scroll-bar.bgWhite>div,.validate-item{background-color:#fff}.label-primary{background-color:#1ab394;padding:2px}.label-danger,.label-primary{border-radius:.25em;color:#fff;display:inline-block;font-size:12px;margin-left:3px;margin-right:3px;min-width:60px}.label-danger{background-color:#ed5565;padding:2px 5px}.label-warning{background-color:#b8860b}.label-secondary,.label-warning{border-radius:.25em;color:#fff;display:inline-block;font-size:12px;margin-left:3px;margin-right:3px;min-width:60px;padding:2px}.label-secondary{background-color:#a9a9a9}.label-done{background-color:#3b1ef7;border-radius:.25em;color:#fff;display:inline-block;font-size:12px;margin-left:3px;margin-right:3px;min-width:60px;padding:2px}.text-navy{color:#1ab394!important}.text-danger{color:red!important}.fa-user-edit{font-size:14px}.flexcolumn{border:1px solid #eee;border-radius:5px;min-height:80px;overflow-x:hidden;overflow-y:hidden}.flexcolumn,.has2ScrollZone2 .flexcolumn{max-height:calc(100vh - 180px)}.headerNoBorder>th{border:none!important;border-bottom:1px solid #eee!important}.cellNoBorder table tr td{border:0!important}.layout-wrapper .layout-main{overflow:hidden;padding:60px 0 0}div.circleButton{border-radius:50%;display:inline-block;height:32px;line-height:32px;margin-bottom:4px;margin-top:4px;overflow:hidden;position:relative;text-align:center;transform:perspective(1px);width:32px}div.circleButton>a{line-height:32px;padding:0!important}div.circleButton>a>i{width:24px!important}div.circleButton:before{background:#e6e6e6;border-radius:50%;bottom:0;content:\"\";left:0;position:absolute;right:0;top:0;transform:scale(0);transition:all .3s cubic-bezier(.4,.34,.01,.97);z-index:-1}div.circleButton:hover:before{transform:scale(1)}.message-notice{background:#e0e0e0;text-align:center}.message-created-by{color:#888;font-size:.82em;font-weight:400;margin-bottom:3px;margin-left:45px;margin-top:5px}.message-created{color:#495057;display:inline-block;font-size:.82em;margin-bottom:0;margin-top:0}.message-own .message-created{padding-left:10px;padding-right:6px}.message-from .message-created{padding-left:6px;padding-right:10px}.message-content{color:#000;line-height:20px;margin-bottom:6px;margin-top:3px;position:relative}.message-content i{display:none}.message-content:hover i{display:block}.message-content:hover{padding-right:20px!important}.chat-box-content{max-height:500px}.attachment-list .attachment-item{-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none;background:#f1f1f1;border:1px solid #ccc;border-radius:8px;box-shadow:1px 2px 3px rgba(0,0,0,.06);float:left;height:84px;margin:8px;overflow:hidden;position:relative;text-align:center;user-select:none;width:84px}.attachment-list .attachment-item img{height:100%;width:100%}.attachment-list .attachment-item span{left:0;padding:5px;position:absolute;top:25px;width:100%;word-break:break-all}.clearfix{clear:both}.dashboard .chat ul li img.message-img{float:none;height:120px;margin-left:0;width:auto}.message-attachment{cursor:pointer;font-size:1.5em;margin:0 5px 0 0;position:relative}.hidden{display:none}.message-input{width:100%}.message-input label{font-size:1.2rem}.remove-file-attachment{background:#495057;border-radius:50%;color:#fff;cursor:pointer;font-size:20px;position:absolute;right:5px;top:5px}.attachment-list{background:#fff;bottom:51px;box-shadow:0 -2px 3px -3px rgba(0,0,0,.21176470588235294);display:none;height:100px;left:-15px;position:absolute;width:calc(100% + 30px)}.attachment-list.attached-file{display:block}.dashboard{margin-bottom:-15px;margin-top:-5px}.dashboard .timeline>.ui-g .ui-g-9 .event-text{color:#555;white-space:nowrap}.dashboard .timeline>.ui-g .ui-g-9 .event-text.event-text2{line-height:18px;padding-left:30px;text-align:justify;white-space:pre-wrap}.dashboard .timeline>.ui-g .ui-g-9 .event-text.event-text2 i{left:20px;margin-top:3px;position:absolute}.new-message{align-items:center;justify-content:center}.dashboard .chat .new-message{border:0;display:flex;margin:0;padding:0;text-align:left}.dashboard .chat .new-message i{color:#495057}.dashboard .chat .new-message .message-attachment{border:0}.dashboard .chat .new-message .button-send{display:inline-block;line-height:40px;position:relative}.dashboard .chat .new-message .button-send .p-button-label{text-align:center}.dashboard .chat .new-message .message-emotion{display:inline-block;height:100%;line-height:40px;text-align:center;width:40px}.dashboard .chat .new-message .message-emotion i{font-size:24px;line-height:inherit}.dashboard .chat .new-message .message-input{width:calc(100% - 155px)}.dashboard .chat ul li.message-from,.dashboard .chat ul li.message-own{padding:0}.dashboard .chat ul li.message-from>span{background-color:#f0e3fd;border:0;border-radius:2px 20px 20px 2px}.dashboard .chat ul li.message-from>.first,.dashboard .chat ul li.message-from>.middle{margin-left:45px!important}.dashboard .chat ul li.message-from>.last{border-radius:2px 20px 20px 20px;margin-left:45px!important}.dashboard .chat ul li.message-from>img{border-radius:50%;margin-top:5px;position:absolute;width:36px}.dashboard .chat ul li.message-own>span{background-color:#def6f8;border:0;border-radius:20px 2px 2px 20px;text-align:right}.dashboard .chat ul li.message-own>span.sending{background-color:#eee}.dashboard .chat ul li.message-own>span.last{border-radius:20px 2px 20px 20px}.dashboard .chat ul li.message-own .attachment span.attachment-item{background-color:#f1f1f1!important;border:0!important;padding-left:0;padding-right:0}.dashboard .chat ul li.message-own .attachment span.attachment-item a{color:#555;cursor:pointer;display:inline-block;font-weight:700}.dashboard .chat ul li.message-own>div.file{background:#f1f1f1;border:1px solid #e4e4e4;border-radius:6px;display:inline-block;margin:1px;overflow:hidden;text-align:right}.dashboard .chat ul li.message-from .attachment span.attachment-item{background-color:#f1f1f1!important;border:0!important;padding-left:0;padding-right:0}.dashboard .chat ul li.message-from .attachment span.attachment-item a{color:#555;cursor:pointer;display:inline-block;font-weight:700}.dashboard .chat ul li.message-from .attachment span.attachment-item a img{margin-right:0}.dashboard .chat ul li.message-from>div.file{background:#f1f1f1;border:1px solid #e4e4e4;border-radius:6px;display:inline-block;margin:1px;overflow:hidden;text-align:left}.dashboard .chat ul li .attachment span.attachment-item a>i{padding-right:8px}.dashboard .chat ul li div.file p.attachment{display:inline-block;margin-bottom:5px}.dashboard .chat ul li.message-from{text-align:left}.dashboard .chat ul li.message-own{text-align:right}.dashboard .chat ul li>div.file.image{height:170px;max-width:100%;padding:15px;transition:width .15s linear;width:220px}.dashboard .chat ul li>div.file.image p.attachment{height:120px}.dashboard .chat ul li>div.file{padding:15px}.dashboard .chat ul li>div.file p,.dashboard .chat ul li>div.file span{display:inline-block;margin:0;padding:0}.visible{opacity:1;transition:opacity .15s linear;visibility:visible}.hidden{opacity:0;transition:visibility 0s .1s,opacity .1s linear;visibility:hidden}.visible2{opacity:1;transition:opacity .35s linear;visibility:visible}.hidden2{opacity:0;transition:visibility 0s .3s,opacity .3s linear;visibility:hidden}.dashboard .chat{position:relative}.dashboard .chat .scroll-to-bottom{bottom:6px;min-height:40px;padding-right:12px;position:sticky;text-align:right}.dashboard .chat .scroll-to-bottom span{background:#495057;border:2px solid #fff;border-radius:50%;box-shadow:0 0 10px rgba(0,0,0,.34901960784313724);color:#fff;cursor:pointer;display:inline-block;font-size:20px;height:35px;line-height:35px;overflow:hidden;text-align:center;width:35px}.dashboard .chat .group-info{line-height:30px;margin:-10px;padding:5px 10px;top:0;z-index:99}.dashboard .chat .group-info,.dashboard .chat .pin{background:#fff;box-shadow:0 0 3px -1px rgba(0,0,0,.21176470588235294);position:sticky}.dashboard .chat .pin{margin-bottom:10px;margin-left:-10px;top:40px;width:calc(100% + 20px);z-index:98}.dashboard .chat ul li.message-from.pin>span,.dashboard .chat ul li.message-own.pin>span{background-color:transparent}.dashboard .chat ul li.message-from.pin>span{margin-left:0}.dashboard .chat .message-content i{color:#495057;cursor:pointer;font-size:11px}.dashboard .chat .pin .message-content i{display:block}.dashboard .chat li.message-from .message-content{padding-left:6px}.dashboard .chat li.message-from .message-content i{padding:5px}.dashboard .chat li.message-own .message-content i{padding:5px;position:absolute;right:-15px}.dashboard .chat .group-info .circleButton{float:right;margin-bottom:0;margin-top:0}.dashboard .chat ul{margin-top:20px;padding:0}.dashboard .chat .new-message .message-input input.ui-inputtext:focus{box-shadow:none;outline:none}.dashboard .chat ul.hasPin{margin-top:10px}.dashboard .chat .group-info a{color:#495057}.normalHtml,.normalHtml b,.normalHtml strong{font-weight:400}.normalHtml{display:inline-block}.avatar-viewer .profile-image{border:1px solid #fff;border-radius:50%;height:40px;margin-top:-6px;width:40px}a.button>i{margin-right:5px}.dashboard .timeline{padding-top:20px}.ui-inputgroup .ui-inputtext{padding-right:0}.new-message .ui-inputtext{width:100%}.full-screen,.full-screen>.p-dialog{height:100%!important;left:0!important;max-height:100%;min-height:unset!important;min-width:100%!important;top:0!important;width:100%!important}#image-view-list.image-gallery-2{background-color:rgba(0,0,0,.4);height:calc(100vh - 41px);margin:-14px auto 0;touch-action:none;width:100%}#image-view-list.image-gallery-2 .image-container{background-color:transparent;border:0;bottom:0;height:85%;margin:auto}#image-view-list.image-gallery-2 .image-container .iv-snap-view{bottom:20px;left:calc(50% - 75px);top:auto}#image-view-list.image-gallery-2 .image-container .iv-image-view img{touch-action:auto}#image-view-list .inline-icon{margin-top:-41px}#image-view-list .footer-info,#image-view-list .material-icons.next,#image-view-list .material-icons.prev{display:none}#image-view-list .options-image-viewer{-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none;margin-right:37px;user-select:none}.mobile-image-viewer-close{color:#fff;cursor:pointer;font-size:x-large;height:42px;line-height:42px;padding-right:7px;padding-top:2px;position:absolute;right:0;text-align:center;top:0;vertical-align:middle;width:37px}.mobile-image-viewer-close:hover{color:#feca37!important}.hide-holder{padding:0}.file-ex-name{word-break:break-all}.box-function{background:#fff;border-radius:0 0 5px 5px;border-top:1px solid #e8e8e8;bottom:0;left:0;padding:8px 30px;position:absolute;text-align:right;width:100%}.box-function button{margin-left:5px}.quick-note-button-holder{bottom:40px;display:none;height:50px;position:absolute;right:50px;width:50px;z-index:99}.quick-note-button{background:#ffc107;border:2px solid #fff;border-radius:50%;box-shadow:0 2px 5px 0 #b9b9b9;color:#fff;display:block;font-size:2em;height:50px;line-height:50px;outline:none;text-align:center;width:50px}.quick-note-button:hover{color:#fff}.all-note-button{background:#ffd24b;border:2px solid #fff;border-radius:50%;box-shadow:0 2px 5px 0 #b9b9b9;color:#fff;display:block;font-size:1.5em;height:40px;line-height:40px;outline:none;position:absolute;right:5px;text-align:center;top:5px;transition:right;transition-duration:.16s;transition-timing-function:ease-in;width:40px;z-index:-1}.all-note-button:hover{color:#fff}.setting-note-button{background:#ffd24b;border:2px solid #fff;border-radius:50%;box-shadow:0 2px 5px 0 #b9b9b9;color:#fff;display:block;font-size:1.5em;height:40px;line-height:40px;outline:none;position:absolute;right:5px;text-align:center;top:5px;transition:right;transition-duration:.16s;transition-timing-function:ease-in;width:40px;z-index:-1}.setting-note-button:hover{color:#fff}.pinned-notes-holder{bottom:20px;display:none;left:20px;position:absolute;width:250px;z-index:98}.pinned-notes{background:transparent;display:block;outline:none;padding:0}.pinned-notes-header{font-size:1rem;font-weight:700}.pinned-notes-setting{position:absolute;right:.5rem}.pinned-note{background-color:#fff1ac;box-shadow:1px 2px 3px rgba(185,139,6,.6313725490196078);font-size:.8rem;margin-bottom:10px;padding:0;position:relative}.pinned-note:last-child{margin-bottom:0}.pinned-notes-minimize-button{background:#ffc003;border:1px solid #fff;border-radius:50%;box-shadow:1px 2px 3px rgba(185,139,6,.6313725490196078);color:#fff;cursor:pointer;height:25px;padding-top:5px;position:absolute;right:-15px;text-align:center;top:-15px;width:25px;z-index:1}.pinned-note-header-line{border:1px solid #fff;box-shadow:1px 1px 2px rgba(0,0,0,.4);height:calc(100% - 1rem);left:3px;margin-bottom:.5rem;margin-top:.5rem;max-height:20px;position:absolute;width:13px}.pinned-note-header-right{cursor:pointer;float:right;margin-left:3px;width:32px}.pinned-note-header-time{font-size:.6rem}.pinned-note-header-button-unpin{display:none;float:left;height:14px;margin-right:2px;opacity:.8;width:14px}.pinned-note-header-button-complete{display:none;padding-top:2px}.pinned-note-body{float:right;padding:.5rem .5rem .5rem 25px;width:100%}.pinned-note-body:hover{background-color:#feeb82}.pinned-note-body:hover .pinned-note-header-time{display:none}.pinned-note-body:hover .pinned-note-header-button-complete,.pinned-note-body:hover .pinned-note-header-button-unpin{display:block}.pinned-note-line-title{color:#333;display:block;font-weight:700;padding-bottom:6px}.pinned-note-line{display:block}.view-port{border-radius:5px;box-shadow:0 0 0 9999px rgba(0,0,0,.5882352941176471);display:none;height:0;width:0;z-index:999}.view-port,.view-port-mask{background:transparent;position:absolute}.view-port-mask{display:block;height:100%;left:0;top:0;width:100%;z-index:9998}.tinymce-control{border:1px solid #ccc;display:none;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;font-size:14px;width:100%}.input-tab-trap{filter:alpha(opacity=0)!important;opacity:0!important;overflow:hidden!important;width:0!important}.color-value input{font-size:.8em;line-height:16px}.dialog-material.mobile{width:100%!important}audio,audio:focus,video,video:focus{outline:none}.iv-image-view img.iv-image{-webkit-animation:fadein .5s;animation:fadein .5s;visibility:hidden!important}@-webkit-keyframes fadein{0%{opacity:0}to{opacity:1}}@keyframes fadein{0%{opacity:0}to{opacity:1}}.iv-image-view img.iv-image.show{visibility:visible!important}.row-line{padding-bottom:0;padding-top:0}.fc-ltr{padding-bottom:7px}.padding-bottom-5px{padding-bottom:5px}.no-margin{margin:0!important}.no-padding{padding:0}.no-padding-left{padding-left:0}.float-left{float:left}body .fc .fc-toolbar .fc-button{background-color:#007ad9;border:1px solid #007ad9;border-radius:3px;color:#fff;font-size:14px;transition:background-color .2s,box-shadow .2s}body .fc .fc-toolbar .fc-button:enabled:hover{background-color:#116fbf;border-color:#116fbf;color:#fff}body .fc .fc-toolbar .fc-button:focus{box-shadow:0 0 0 .2em #8dcdff;outline:0 none;outline-offset:0}body .fc .fc-toolbar .fc-button-group .fc-button{border-radius:0}body .fc .fc-toolbar .fc-button-group .fc-button:first-child{border-bottom-left-radius:3px;border-top-left-radius:3px}body .fc .fc-toolbar .fc-button-group .fc-button:last-child{border-bottom-right-radius:3px;border-top-right-radius:3px}body .fc .fc-toolbar .fc-right .fc-button{border-radius:0}body .fc .fc-toolbar .fc-right .fc-button:first-child{border-bottom-left-radius:3px;border-top-left-radius:3px}body .fc .fc-toolbar .fc-right .fc-button:last-child{border-bottom-right-radius:3px;border-top-right-radius:3px}.fc-toolbar>*>:not(:first-child){margin-left:0}.fc-axis,.fc-dayGridMonth-button,.fc-timeGridDay-button,.fc-timeGridWeek-button,.old-content{line-height:0;text-indent:-9999px}.fc-axis:after,.fc-dayGridMonth-button:after,.fc-timeGridDay-button:after,.fc-timeGridWeek-button:after,.new-content{display:block;line-height:normal;text-indent:0}.fc-dayGridMonth-button:after{content:\"Th\u00E1ng\";padding:.2em}.fc-timeGridWeek-button:after{content:\"Tu\u1EA7n\";padding:.2em}.fc-timeGridDay-button:after{content:\"Ng\u00E0y\";padding:.2em}body .fc th{background-color:#f4f4f4;border:1px solid #c8c8c8;color:#333;padding:.571em 1em}.ui-fluid .button-group button,.ui-fluid .button-group p-button{margin-right:.5em!important;text-align:left;width:auto}.layout-wrapper .layout-menu-container{z-index:97}.base-status,.base-status-aborted,.base-status-approved,.base-status-completed,.base-status-create-new,.base-status-ended,.base-status-high,.base-status-immediately,.base-status-low,.base-status-medium,.base-status-on-conducting,.base-status-on-going,.base-status-pending,.base-status-rejected,.base-status-returned,.base-status-urgent{border-radius:.25em;color:#fff;font-size:.8em;padding:3px;text-align:center}.base-status-create-new{background-color:#f2f2f2;color:#666}.base-status-on-conducting,.base-status-on-going{background-color:#337ab7}.base-status-pending{background-color:#ffba01}.base-status-approved{background-color:#34a835}.base-status-returned{background-color:#ffba01}.base-status-rejected{background-color:#d9534f}.base-status-completed{background-color:#34a835}.base-status-aborted{background-color:#ffba01}.base-status-ended{background-color:#34a835}.base-status-low,.base-status-medium{background-color:#f2f2f2;color:#666}.base-status-high{background-color:#ffba01}.base-status-immediately,.base-status-urgent{background-color:#d9534f}.text-align-center{text-align:center}.font-weight-bold{font-weight:700}.landing-body .landing-menu li a:hover{border-bottom:none}.landing-body .landing-menu li:first-child{margin-left:8px}.crud-form .label-control p{margin:0;padding:0}.crud-form .tn-check-box-list .p-row{display:block;padding:.5em;width:100%}.crud-form dropdown,.crud-form tn-mask{width:100%}.crud-form .tn-dropdown{min-height:32px}.crud-form .tn-dropdown.free-text.horizontal{display:flex}.crud-form .tn-dropdown.free-text.horizontal>div{flex-grow:1;padding-left:.5em;padding-right:.5em}.crud-form .tn-dropdown.free-text.horizontal>div:first-child{padding-left:0}.crud-form .tn-dropdown.free-text.horizontal>div:last-child{padding-right:0}.crud-form .tn-dropdown.free-text.vertical input.ui-inputtext.input-free-text{margin-top:.5em}.crud-form.assessment .label-control{font-weight:700}.crud-form.assessment .label-control.haveIndex{display:block;margin-bottom:5px;padding-left:20px;position:relative}.crud-form.assessment .label-control.haveIndex:before{content:\" \" attr(label-index) \".\";left:0;position:absolute;top:0}.crud-form.assessment .ViewMode{border-bottom:none}.crud-form.assessment .ViewMode .label-control{margin-bottom:0}body .ui-inputtext.min-width{padding:6px}.ps__rail-x,.ps__rail-y{z-index:2}.zIndex5 .ps__rail-x,.zIndex5 .ps__rail-y{z-index:5}.table-sticky table{border-collapse:separate;border-spacing:0}.table-sticky tr td,.table-sticky tr th{border:1px solid #eee!important;border-left:none!important;border-top:none!important}.table-sticky tr td:first-child,.table-sticky tr th:first-child{border-left:1px solid #eee!important}.table-sticky tr td:last-child,.table-sticky tr th:last-child{border-right:none!important}.table-sticky tr:first-child th{border-top:1px solid #eee!important}.table-sticky th{background:#eee}.table-sticky tbody td.disabled{background:#eee!important}.table-sticky tbody td.disabled:not(:last-child){border-right:1px solid #fff!important}.table-sticky.fix-height tr:first-child th{position:sticky;top:0;z-index:2}.container-flex{align-items:center;display:flex}.container-flex>div:first-child{flex:0 0 auto;margin-right:.5em}.container-flex>div:last-child{flex-grow:1}.container-control{display:flex}.container-control>span.label{flex:0 0 auto;padding-right:.5em;padding-top:.5em}.container-control>span.label+*{flex-grow:1;flex-shrink:1;position:relative}.container-control>span.label+* .tn-dropdown,.container-control>span.label+* .ui-autocomplete-multiple,.container-control>span.label+* .ui-inputgroup .ui-inputtext{width:100%}.container-control>span.label+* .validation-container{margin-top:3px}.container-control>span.label+* .validation-container .validate-item{white-space:unset}.container-control>span.label+*>div{left:0;position:absolute;top:0;width:100%}.container-control.no-label>span.label{display:none}.container-control.inline{display:inline-flex}.align-flex-center{align-items:center;display:flex;justify-content:center}@media print{.isPrinting>*{display:none}.isPrinting app-print-layout{display:block}}.layout-wrapper .topbar .topbar-left,.layout-wrapper .topbar .topbar-right{background:#397ac3}#searchResultPanel-holder{padding:0 .5em}.cus-dropdown{line-height:normal;margin-right:1em}.tn-thumbnail{padding:.5rem}.tn-thumbnail.tn-thumbnail.tn-thumbnail{box-sizing:border-box}.fa-10:before{content:\"A+\";font-family:cursive;font-weight:700}.layout-wrapper .topbar .topbar-right #menu-button i{font-size:20px;margin-top:4px}.layout-wrapper .layout-menu li a i.menuitem-toggle-icon{font-size:15px;margin-left:auto}.flex-container-main-content{display:flex;flex-direction:column}.flex-container-main-content>div:last-child{background-color:#f4f4f4;display:flex;flex:1 1;overflow:hidden;position:relative}.flex-container-main-content>div:last-child>div{height:100%;left:0;overflow:hidden;padding-top:.5em;position:absolute;top:0;width:100%}.flex-container-main-content .block-with-button-search{display:flex;justify-content:flex-end}.flex-container-main-content .block-with-button-search>*{margin-left:.5em}.flex-container-main-content .block-with-button-search>input{height:26px;margin-left:0;max-width:200px;width:100%}.flex-container-main-content .block-with-button-search>dropdown{max-width:140px;width:100%}.flex-container-main-content .title-main-component{border-bottom:2px solid #1ca7ff}.clickable-table.clickable-table{cursor:pointer}.main-crud-container{height:calc(100vh - 76px)}.flex-container-fit-child{display:flex;flex-direction:column;height:100%;overflow:hidden}.flex-container-fit-child>div.fit-content{flex:1 1;position:relative}.flex-container-fit-child>div.fit-content>div{height:100%;overflow:auto;position:absolute;width:100%}.waiting-box{display:none;height:100%;left:0;position:fixed;top:0;width:100%;z-index:9999}.waiting-box .overlay{background-color:red;background-color:hsla(0,0%,42.7%,.5019607843137255);height:100%;width:100%}.waiting-box .content-loading{left:50%;position:absolute;top:50%;transform:translate(-50%,-50%)}.waiting-box.show{display:block}.function-topbar>*{vertical-align:top}.function-topbar button{width:auto}.function-topbar p-fileUpload{margin-right:1em}.function-topbar .container-control{display:inline-flex;line-height:normal}.function-topbar .container-control dropdown{width:100%}:focus{outline-color:#a6d5fa!important}address{font-style:normal}body .p-toast .p-toast-message{border-radius:0;border-width:0 0 0 4px!important}.__status span,.status span{font-size:.8rem}p-table.single-check .p-datatable .p-datatable-tbody>tr{cursor:pointer}p-table.single-check .p-datatable .p-datatable-tbody>tr.ui-state-highlight{background:#e3f2fd!important;outline:2px solid #a6d5fa}p-table.single-check .p-datatable .p-datatable-tbody>tr td.sticky .fix-sticky.top{display:none}p-table.multi-check .p-datatable .p-datatable-tbody>tr.ui-state-highlight{background:#e3f2fd!important}p-table.multi-check .p-datatable .p-datatable-tbody>tr.ui-state-highlight td{border-color:#fff}p-table.multi-check .p-datatable .p-datatable-tbody>tr.ui-state-highlight td .fix-sticky{background-color:#fff}.tn-animated-left-arrow-icon,.tn-animated-right-arrow-icon{height:32px;position:relative;width:14px;z-index:10}.tn-animated-right-arrow-icon{-webkit-animation:arrowBounceToRight .8s ease-in-out infinite alternate;animation:arrowBounceToRight .8s ease-in-out infinite alternate}.tn-animated-left-arrow-icon{-webkit-animation:arrowBounceToLeft .8s ease-in-out infinite alternate;animation:arrowBounceToLeft .8s ease-in-out infinite alternate}.tn-animated-left-arrow-icon:after,.tn-animated-left-arrow-icon:before,.tn-animated-right-arrow-icon:after,.tn-animated-right-arrow-icon:before{background-color:#88b0dd;content:\"\";display:block;height:20px;position:absolute;width:5px}.tn-animated-right-arrow-icon:before{left:4px;top:0;transform:rotate(-35deg)}.tn-animated-right-arrow-icon:after{left:4px;top:14px;transform:rotate(35deg)}.tn-animated-left-arrow-icon:before{right:4px;top:0;transform:rotate(35deg)}.tn-animated-left-arrow-icon:after{right:4px;top:14px;transform:rotate(-35deg)}@-webkit-keyframes arrowBounceToLeft{0%{transform:translateX(-3px)}to{transform:translateX(3px)}}@keyframes arrowBounceToLeft{0%{transform:translateX(-3px)}to{transform:translateX(3px)}}@-webkit-keyframes arrowBounceToRight{0%{transform:translateX(3px)}to{transform:translateX(-3px)}}@keyframes arrowBounceToRight{0%{transform:translateX(3px)}to{transform:translateX(-3px)}}.pass{color:#49c949}.not-pass,.pass{margin:5px;text-align:center}.not-pass{color:red}"]
|
|
43067
|
+
},] }
|
|
43068
|
+
];
|
|
43069
|
+
ChatBoxComponent.ctorParameters = () => [
|
|
43070
|
+
{ type: Injector },
|
|
43071
|
+
{ type: ChatService },
|
|
43072
|
+
{ type: MessageBoardService },
|
|
43073
|
+
{ type: UserService },
|
|
43074
|
+
{ type: CheckControlVisibleService },
|
|
43075
|
+
{ type: SignalRService },
|
|
43076
|
+
{ type: FileExplorerService },
|
|
43077
|
+
{ type: CrudService },
|
|
43078
|
+
{ type: NotifierService },
|
|
43079
|
+
{ type: ModuleConfigService }
|
|
43080
|
+
];
|
|
43081
|
+
ChatBoxComponent.propDecorators = {
|
|
43082
|
+
taskId: [{ type: Input }],
|
|
43083
|
+
serviceCode: [{ type: Input }],
|
|
43084
|
+
entity: [{ type: Input }],
|
|
43085
|
+
users: [{ type: Input }],
|
|
43086
|
+
showSendMessageBox: [{ type: Input }],
|
|
43087
|
+
input: [{ type: ViewChild, args: ['input',] }],
|
|
43088
|
+
fileElement: [{ type: ViewChild, args: ['fileElement',] }]
|
|
43089
|
+
};
|
|
43090
|
+
|
|
43091
|
+
// fix for prod build
|
|
43092
|
+
// const objectToFormData = objectToFormData_;
|
|
43093
|
+
class ChatSendMessageBoxComponent extends ComponentBase {
|
|
43094
|
+
constructor(injector, _chatService, _checkControlVisible, _fileExplorerNewService, _notifierService) {
|
|
43095
|
+
super(injector);
|
|
43096
|
+
this._chatService = _chatService;
|
|
43097
|
+
this._checkControlVisible = _checkControlVisible;
|
|
43098
|
+
this._fileExplorerNewService = _fileExplorerNewService;
|
|
43099
|
+
this._notifierService = _notifierService;
|
|
43100
|
+
this.model.driveFileDialog = { popupSize: {} };
|
|
43101
|
+
}
|
|
43102
|
+
ngOnInit() {
|
|
43103
|
+
console.log('inside ChatSendMessageBoxComponent');
|
|
43104
|
+
this.model.dataSource = [];
|
|
43105
|
+
this.model.correlationIds = [];
|
|
43106
|
+
this.model.attachments = [];
|
|
43107
|
+
this.model.maxFileSize = 3000000;
|
|
43108
|
+
this.model.fileViewer = {};
|
|
43109
|
+
this._checkControlVisible.checkDisplayStatus(this.input.nativeElement).then(rs => {
|
|
43110
|
+
this.input.nativeElement.focus();
|
|
43111
|
+
});
|
|
43112
|
+
this.rootContext.subscribe(ComCtxConstants.ROOT.CHAT_INSTANCE_ID_LOADED, data => {
|
|
43113
|
+
if (data) {
|
|
43114
|
+
this.model.id = data;
|
|
43115
|
+
this.chatInstanceId = data;
|
|
43116
|
+
this.notifiUserOnline(this.model.id);
|
|
43117
|
+
}
|
|
43118
|
+
});
|
|
43119
|
+
this.rootContext.subscribe(ComCtxConstants.ROOT.CHAT_MOUSE_UP, data => {
|
|
43120
|
+
if (data) {
|
|
43121
|
+
this.onMouseUp(null);
|
|
43122
|
+
}
|
|
43123
|
+
});
|
|
43124
|
+
this.rootContext.subscribe('DRIVE_FILE_DIALOG.CLOSE_POPUP', response => {
|
|
43125
|
+
if (response != null) {
|
|
43126
|
+
const type = this._commonService.isImage(response.name) ? 'image' : 'file';
|
|
43127
|
+
const attachmentItem = {
|
|
43128
|
+
type: type,
|
|
43129
|
+
fileId: response.id,
|
|
43130
|
+
fileName: response.name
|
|
43131
|
+
};
|
|
43132
|
+
if (attachmentItem.type == 'image') {
|
|
43133
|
+
// Get preview url
|
|
43134
|
+
this._fileExplorerNewService.getImageFileBase64(response.id).then(result => {
|
|
43135
|
+
attachmentItem.url = result;
|
|
43136
|
+
});
|
|
43137
|
+
}
|
|
43138
|
+
this.model.attachments.push(attachmentItem);
|
|
43139
|
+
this.input.nativeElement.focus();
|
|
43140
|
+
this.model.classHasAttachment = 'attached-file';
|
|
43141
|
+
this.rootContext.fireEvent(ComCtxConstants.ROOT.CHAT_MESSAGE_ATTACH_FILE, true);
|
|
43142
|
+
}
|
|
43143
|
+
this.model.driveFileDialog.show = false;
|
|
43144
|
+
});
|
|
43145
|
+
this.rootContext.subscribe(ComCtxConstants.ROOT.DESTROY_TASK_DETAIL_COMPONENT, data => {
|
|
43146
|
+
if (this.model.userOnlineId) {
|
|
43147
|
+
this.removeUserOnline(this.model.userOnlineId);
|
|
43148
|
+
}
|
|
43149
|
+
});
|
|
43150
|
+
}
|
|
43151
|
+
browseFileFromPersonal() {
|
|
43152
|
+
this.model.driveFileDialog = {
|
|
43153
|
+
show: true
|
|
43154
|
+
};
|
|
43155
|
+
}
|
|
43156
|
+
onSendMessage(message) {
|
|
43157
|
+
if ((!message || message.trim() == '') && this.model.attachments.length === 0) {
|
|
43158
|
+
return;
|
|
43159
|
+
}
|
|
43160
|
+
if (!message) {
|
|
43161
|
+
message = '';
|
|
43162
|
+
}
|
|
43163
|
+
message = message.trim();
|
|
43164
|
+
const objToSend = {
|
|
43165
|
+
chatId: this.model.id,
|
|
43166
|
+
messageContent: message,
|
|
43167
|
+
correlationId: this._commonService.guid()
|
|
43168
|
+
};
|
|
43169
|
+
const formData = new FormData();
|
|
43170
|
+
for (const key in objToSend) {
|
|
43171
|
+
formData.append(key, objToSend[key]);
|
|
43172
|
+
}
|
|
43173
|
+
for (const item of this.model.attachments) {
|
|
43174
|
+
// const item = this.model.attachments[itejm];
|
|
43175
|
+
if (item.fileId != null) {
|
|
43176
|
+
formData.append('fileId', item.fileId);
|
|
43177
|
+
}
|
|
43178
|
+
else {
|
|
43179
|
+
if (item.type == 'image') {
|
|
43180
|
+
formData.append('files', item.data, item.fileName);
|
|
43181
|
+
}
|
|
43182
|
+
else {
|
|
43183
|
+
formData.append('files', item.data);
|
|
43184
|
+
}
|
|
43185
|
+
}
|
|
43186
|
+
}
|
|
43187
|
+
this.rootContext.fireEvent(ComCtxConstants.ROOT.CHAT_MESSAGE_SENDING, {
|
|
43188
|
+
message: objToSend,
|
|
43189
|
+
attachments: this.model.attachments
|
|
43190
|
+
});
|
|
43191
|
+
// reset attachment list
|
|
43192
|
+
this.model.attachments.length = 0;
|
|
43193
|
+
this.model.content = '';
|
|
43194
|
+
this.rootContext.fireEvent(ComCtxConstants.ROOT.CHAT_MESSAGE_ATTACH_FILE, false);
|
|
43195
|
+
this.model.classHasAttachment = '';
|
|
43196
|
+
this._chatService.sendMessage(formData).then(rs => {
|
|
43197
|
+
this.rootContext.fireEvent(ComCtxConstants.ROOT.CHAT_MESSAGE_SENT, { message: objToSend, status: true });
|
|
43198
|
+
}).catch((err) => {
|
|
43199
|
+
this.rootContext.fireEvent(ComCtxConstants.ROOT.CHAT_MESSAGE_SENT, {
|
|
43200
|
+
message: objToSend,
|
|
43201
|
+
status: false,
|
|
43202
|
+
error: err.error
|
|
43203
|
+
});
|
|
43204
|
+
this._notifierService.showWarningByResponse(err);
|
|
43205
|
+
});
|
|
43206
|
+
}
|
|
43207
|
+
handlePaste(event) {
|
|
43208
|
+
// console.log(event.clipboardData);
|
|
43209
|
+
const objectData = this.getImageClipboardData(event);
|
|
43210
|
+
if (objectData) {
|
|
43211
|
+
this.model.attachments.push({
|
|
43212
|
+
type: 'image',
|
|
43213
|
+
url: objectData.url,
|
|
43214
|
+
data: objectData.blob, fileName: this._commonService.guid() + '.png'
|
|
43215
|
+
});
|
|
43216
|
+
this.rootContext.fireEvent(ComCtxConstants.ROOT.CHAT_MESSAGE_ATTACH_FILE, true);
|
|
43217
|
+
this.model.classHasAttachment = 'attached-file';
|
|
43218
|
+
}
|
|
43219
|
+
}
|
|
43220
|
+
getImageClipboardData(e) {
|
|
43221
|
+
for (let i = 0; i < e.clipboardData.items.length; i++) {
|
|
43222
|
+
const item = e.clipboardData.items[i];
|
|
43223
|
+
if (item.type.indexOf('image') != -1) {
|
|
43224
|
+
const imageObj = item.getAsFile();
|
|
43225
|
+
if (imageObj.size < this.model.maxFileSize) {
|
|
43226
|
+
return { url: URL.createObjectURL(imageObj), blob: imageObj };
|
|
43227
|
+
}
|
|
43228
|
+
else {
|
|
43229
|
+
return null;
|
|
43230
|
+
}
|
|
43231
|
+
}
|
|
43232
|
+
}
|
|
43233
|
+
return null;
|
|
43234
|
+
}
|
|
43235
|
+
browseFileFromComputer() {
|
|
43236
|
+
this.fileElement.advancedFileInput.nativeElement.click();
|
|
43237
|
+
}
|
|
43238
|
+
onSelectFileFromComputer(evt) {
|
|
43239
|
+
try {
|
|
43240
|
+
if (evt.files && evt.files.length > 0) {
|
|
43241
|
+
for (let index = 0; index < evt.files.length; index++) {
|
|
43242
|
+
const fileName = evt.files[index].name;
|
|
43243
|
+
const type = this._commonService.isImage(fileName) ? 'image' : 'file';
|
|
43244
|
+
const attachmentItem = {
|
|
43245
|
+
type: type,
|
|
43246
|
+
data: evt.files[index], fileName: fileName
|
|
43247
|
+
};
|
|
43248
|
+
if (attachmentItem.type == 'image') {
|
|
43249
|
+
attachmentItem.url = evt.files[index].objectURL.changingThisBreaksApplicationSecurity;
|
|
43250
|
+
}
|
|
43251
|
+
this.model.attachments.push(attachmentItem);
|
|
43252
|
+
}
|
|
43253
|
+
this.input.nativeElement.focus();
|
|
43254
|
+
this.model.classHasAttachment = 'attached-file';
|
|
43255
|
+
this.rootContext.fireEvent(ComCtxConstants.ROOT.CHAT_MESSAGE_ATTACH_FILE, true);
|
|
43256
|
+
}
|
|
43257
|
+
}
|
|
43258
|
+
catch (e) {
|
|
43259
|
+
console.error('error on process select file computer', e);
|
|
43260
|
+
}
|
|
43261
|
+
this.fileElement.clear();
|
|
43262
|
+
}
|
|
43263
|
+
removeAttachment(item) {
|
|
43264
|
+
const attachments = this.model.attachments;
|
|
43265
|
+
const index = attachments.findIndex(x => x.url == item.url);
|
|
43266
|
+
this.model.attachments.splice(index, 1);
|
|
43267
|
+
if (this.model.attachments.length === 0) {
|
|
43268
|
+
this.model.classHasAttachment = '';
|
|
43269
|
+
this.rootContext.fireEvent(ComCtxConstants.ROOT.CHAT_MESSAGE_ATTACH_FILE, false);
|
|
43270
|
+
}
|
|
43271
|
+
}
|
|
43272
|
+
onMouseUp($event) {
|
|
43273
|
+
this.input.nativeElement.focus();
|
|
43274
|
+
}
|
|
43275
|
+
cancelBlur(event) {
|
|
43276
|
+
event.preventDefault();
|
|
43277
|
+
}
|
|
43278
|
+
ngOnDestroy() {
|
|
43279
|
+
this.rootContext.unSubscribe(ComCtxConstants.ROOT.CHAT_INSTANCE_ID_LOADED);
|
|
43280
|
+
this.rootContext.unSubscribe(ComCtxConstants.ROOT.CHAT_MOUSE_UP);
|
|
43281
|
+
}
|
|
43282
|
+
notifiUserOnline(chatId) {
|
|
43283
|
+
this._chatService.insertUserOnline(chatId).then(rs => {
|
|
43284
|
+
if (rs.success) {
|
|
43285
|
+
this.model.userOnlineId = rs.data;
|
|
43286
|
+
}
|
|
43287
|
+
});
|
|
43288
|
+
}
|
|
43289
|
+
removeUserOnline(userOnlineId) {
|
|
43290
|
+
this.chatInstanceId = '';
|
|
43291
|
+
this._chatService.removeUserOnline(userOnlineId).then(rs => {
|
|
43292
|
+
if (rs.success) {
|
|
43293
|
+
this._notifierService.showWarning('Đã bỏ người dùng thành công');
|
|
43294
|
+
}
|
|
43295
|
+
});
|
|
43296
|
+
}
|
|
43297
|
+
clickInputText() {
|
|
43298
|
+
if (this.model.instanceId) {
|
|
43299
|
+
this._chatService.markAsReadAllContents(this.model.id).then(rs => {
|
|
43300
|
+
console.log('markAsReadAllContents');
|
|
43301
|
+
});
|
|
43302
|
+
}
|
|
43303
|
+
}
|
|
43304
|
+
}
|
|
43305
|
+
ChatSendMessageBoxComponent.decorators = [
|
|
43306
|
+
{ type: Component, args: [{
|
|
43307
|
+
selector: 'chat-send-message-box',
|
|
43308
|
+
template: "<div class=\"dashboard\" (mouseup)=\"onMouseUp($event)\">\r\n <div class=\"chat\">\r\n <div class=\"new-message\">\r\n <div class=\"message-emotion\">\r\n <i class=\"far fa-smile\" style=\"color: gray;\" disabled=\"true\"></i>\r\n </div>\r\n <div class=\"message-attachment\" pTooltip=\"\u0110\u00EDnh k\u00E8m file\" tooltipPosition=\"top\" (click)=\"op.toggle($event)\">\r\n <i class=\"fas fa-paperclip\"></i>\r\n </div>\r\n <p-overlayPanel #op [dismissable]=\"true\" [appendTo]=\"'body'\" [styleClass]=\"'paging-advance-overlay'\"\r\n (mouseup)=\"onMouseUp($event)\">\r\n <ul class=\"paging-advance\">\r\n <li (click)=\"browseFileFromPersonal()\">T\u1EEB file c\u00E1 nh\u00E2n</li>\r\n <li (click)=\"browseFileFromComputer()\">T\u1EA3i l\u00EAn t\u1EEB m\u00E1y t\u00EDnh</li>\r\n </ul>\r\n </p-overlayPanel>\r\n <div class=\"message-input p-float-label\">\r\n <input #input pInputText\r\n id=\"message\"\r\n autocomplete=\"off\" autocorrect=\"off\"\r\n spellcheck=\"false\" class=\"ui-inputtext\"\r\n type=\"text\" placeholder=\"N\u1ED9i dung tin nh\u1EAFn\"\r\n [(ngModel)]=\"model.content\"\r\n (keyup.enter)=\"onSendMessage($event.target.value)\" (keydown.shift.tab)=\"cancelBlur($event)\"\r\n (keydown.tab)=\"cancelBlur($event)\" (paste)=\"handlePaste($event)\" (click)=\"clickInputText()\"/>\r\n </div>\r\n <div>\r\n <button pButton class=\"p-button-danger\" icon=\"fas fa-send\" type=\"button\" label=\"G\u1EEDi\"\r\n (click)=\"onSendMessage(model.content)\">\r\n </button>\r\n </div>\r\n </div>\r\n <div class=\"attachment-list\" [ngClass]=\"model.classHasAttachment\">\r\n <tn-custom-scrollbar #scrollbar [style]=\"{'height': '100px'}\">\r\n <div *ngFor=\"let item of model.attachments\" class=\"attachment-item\">\r\n <img *ngIf=\"item.type == 'image'\" [src]=\"item.url | safeUrl\"/>\r\n <span *ngIf=\"item.type == 'file'\">{{item.fileName}}</span>\r\n <i class=\"far fa-times-circle label-danger remove-file-attachment\"\r\n (click)=\"removeAttachment(item)\"></i>\r\n </div>\r\n </tn-custom-scrollbar>\r\n <!-- <div class=\"clearfix\"></div>-->\r\n </div>\r\n </div>\r\n</div>\r\n<p-fileUpload [ngStyle]=\"{'display': 'none'}\" #fileElement (onSelect)=\"onSelectFileFromComputer($event)\"\r\n multiple=\"multiple\" name=\"fileUpload\" [maxFileSize]=\"model.maxFileSize\" auto=\"false\">\r\n</p-fileUpload>\r\n\r\n<!-- <app-drive-file-dialog *ngIf=\"model.driveFileDialog.show\" [parentDataContext]=\"dataContext\"\r\n []=\"model.driveFileDialog\" #driveFileDialog>\r\n</app-drive-file-dialog> -->\r\n",
|
|
43309
|
+
providers: [ComponentContextService],
|
|
43310
|
+
styles: ["", "@charset \"UTF-8\";@import url(C:\\Users\\vietp\\source\\repos\\5.1\\shared\\AppSharedV5\\node_modules\\@angular\\material\\prebuilt-themes\\indigo-pink.css);@import url(C:\\Users\\vietp\\source\\repos\\5.1\\shared\\AppSharedV5\\node_modules\\jsoneditor\\dist\\jsoneditor.min.css);.flex{display:flex}.flex .fit{flex:1 1}.flex.flex-column{flex-direction:column}.flex.flex-wrap{flex-wrap:wrap}.flex.center-v{align-items:center}.flex.center-all,.flex.center-h{justify-content:center}.flex.center-all{align-items:center}.validate-item{color:#e00000;display:inline-block;font-size:.9em;white-space:nowrap}.tn-scroll-bar.bgWhite>div,.validate-item{background-color:#fff}.label-primary{background-color:#1ab394;padding:2px}.label-danger,.label-primary{border-radius:.25em;color:#fff;display:inline-block;font-size:12px;margin-left:3px;margin-right:3px;min-width:60px}.label-danger{background-color:#ed5565;padding:2px 5px}.label-warning{background-color:#b8860b}.label-secondary,.label-warning{border-radius:.25em;color:#fff;display:inline-block;font-size:12px;margin-left:3px;margin-right:3px;min-width:60px;padding:2px}.label-secondary{background-color:#a9a9a9}.label-done{background-color:#3b1ef7;border-radius:.25em;color:#fff;display:inline-block;font-size:12px;margin-left:3px;margin-right:3px;min-width:60px;padding:2px}.text-navy{color:#1ab394!important}.text-danger{color:red!important}.fa-user-edit{font-size:14px}.flexcolumn{border:1px solid #eee;border-radius:5px;min-height:80px;overflow-x:hidden;overflow-y:hidden}.flexcolumn,.has2ScrollZone2 .flexcolumn{max-height:calc(100vh - 180px)}.headerNoBorder>th{border:none!important;border-bottom:1px solid #eee!important}.cellNoBorder table tr td{border:0!important}.layout-wrapper .layout-main{overflow:hidden;padding:60px 0 0}div.circleButton{border-radius:50%;display:inline-block;height:32px;line-height:32px;margin-bottom:4px;margin-top:4px;overflow:hidden;position:relative;text-align:center;transform:perspective(1px);width:32px}div.circleButton>a{line-height:32px;padding:0!important}div.circleButton>a>i{width:24px!important}div.circleButton:before{background:#e6e6e6;border-radius:50%;bottom:0;content:\"\";left:0;position:absolute;right:0;top:0;transform:scale(0);transition:all .3s cubic-bezier(.4,.34,.01,.97);z-index:-1}div.circleButton:hover:before{transform:scale(1)}.message-notice{background:#e0e0e0;text-align:center}.message-created-by{color:#888;font-size:.82em;font-weight:400;margin-bottom:3px;margin-left:45px;margin-top:5px}.message-created{color:#495057;display:inline-block;font-size:.82em;margin-bottom:0;margin-top:0}.message-own .message-created{padding-left:10px;padding-right:6px}.message-from .message-created{padding-left:6px;padding-right:10px}.message-content{color:#000;line-height:20px;margin-bottom:6px;margin-top:3px;position:relative}.message-content i{display:none}.message-content:hover i{display:block}.message-content:hover{padding-right:20px!important}.chat-box-content{max-height:500px}.attachment-list .attachment-item{-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none;background:#f1f1f1;border:1px solid #ccc;border-radius:8px;box-shadow:1px 2px 3px rgba(0,0,0,.06);float:left;height:84px;margin:8px;overflow:hidden;position:relative;text-align:center;user-select:none;width:84px}.attachment-list .attachment-item img{height:100%;width:100%}.attachment-list .attachment-item span{left:0;padding:5px;position:absolute;top:25px;width:100%;word-break:break-all}.clearfix{clear:both}.dashboard .chat ul li img.message-img{float:none;height:120px;margin-left:0;width:auto}.message-attachment{cursor:pointer;font-size:1.5em;margin:0 5px 0 0;position:relative}.hidden{display:none}.message-input{width:100%}.message-input label{font-size:1.2rem}.remove-file-attachment{background:#495057;border-radius:50%;color:#fff;cursor:pointer;font-size:20px;position:absolute;right:5px;top:5px}.attachment-list{background:#fff;bottom:51px;box-shadow:0 -2px 3px -3px rgba(0,0,0,.21176470588235294);display:none;height:100px;left:-15px;position:absolute;width:calc(100% + 30px)}.attachment-list.attached-file{display:block}.dashboard{margin-bottom:-15px;margin-top:-5px}.dashboard .timeline>.ui-g .ui-g-9 .event-text{color:#555;white-space:nowrap}.dashboard .timeline>.ui-g .ui-g-9 .event-text.event-text2{line-height:18px;padding-left:30px;text-align:justify;white-space:pre-wrap}.dashboard .timeline>.ui-g .ui-g-9 .event-text.event-text2 i{left:20px;margin-top:3px;position:absolute}.new-message{align-items:center;justify-content:center}.dashboard .chat .new-message{border:0;display:flex;margin:0;padding:0;text-align:left}.dashboard .chat .new-message i{color:#495057}.dashboard .chat .new-message .message-attachment{border:0}.dashboard .chat .new-message .button-send{display:inline-block;line-height:40px;position:relative}.dashboard .chat .new-message .button-send .p-button-label{text-align:center}.dashboard .chat .new-message .message-emotion{display:inline-block;height:100%;line-height:40px;text-align:center;width:40px}.dashboard .chat .new-message .message-emotion i{font-size:24px;line-height:inherit}.dashboard .chat .new-message .message-input{width:calc(100% - 155px)}.dashboard .chat ul li.message-from,.dashboard .chat ul li.message-own{padding:0}.dashboard .chat ul li.message-from>span{background-color:#f0e3fd;border:0;border-radius:2px 20px 20px 2px}.dashboard .chat ul li.message-from>.first,.dashboard .chat ul li.message-from>.middle{margin-left:45px!important}.dashboard .chat ul li.message-from>.last{border-radius:2px 20px 20px 20px;margin-left:45px!important}.dashboard .chat ul li.message-from>img{border-radius:50%;margin-top:5px;position:absolute;width:36px}.dashboard .chat ul li.message-own>span{background-color:#def6f8;border:0;border-radius:20px 2px 2px 20px;text-align:right}.dashboard .chat ul li.message-own>span.sending{background-color:#eee}.dashboard .chat ul li.message-own>span.last{border-radius:20px 2px 20px 20px}.dashboard .chat ul li.message-own .attachment span.attachment-item{background-color:#f1f1f1!important;border:0!important;padding-left:0;padding-right:0}.dashboard .chat ul li.message-own .attachment span.attachment-item a{color:#555;cursor:pointer;display:inline-block;font-weight:700}.dashboard .chat ul li.message-own>div.file{background:#f1f1f1;border:1px solid #e4e4e4;border-radius:6px;display:inline-block;margin:1px;overflow:hidden;text-align:right}.dashboard .chat ul li.message-from .attachment span.attachment-item{background-color:#f1f1f1!important;border:0!important;padding-left:0;padding-right:0}.dashboard .chat ul li.message-from .attachment span.attachment-item a{color:#555;cursor:pointer;display:inline-block;font-weight:700}.dashboard .chat ul li.message-from .attachment span.attachment-item a img{margin-right:0}.dashboard .chat ul li.message-from>div.file{background:#f1f1f1;border:1px solid #e4e4e4;border-radius:6px;display:inline-block;margin:1px;overflow:hidden;text-align:left}.dashboard .chat ul li .attachment span.attachment-item a>i{padding-right:8px}.dashboard .chat ul li div.file p.attachment{display:inline-block;margin-bottom:5px}.dashboard .chat ul li.message-from{text-align:left}.dashboard .chat ul li.message-own{text-align:right}.dashboard .chat ul li>div.file.image{height:170px;max-width:100%;padding:15px;transition:width .15s linear;width:220px}.dashboard .chat ul li>div.file.image p.attachment{height:120px}.dashboard .chat ul li>div.file{padding:15px}.dashboard .chat ul li>div.file p,.dashboard .chat ul li>div.file span{display:inline-block;margin:0;padding:0}.visible{opacity:1;transition:opacity .15s linear;visibility:visible}.hidden{opacity:0;transition:visibility 0s .1s,opacity .1s linear;visibility:hidden}.visible2{opacity:1;transition:opacity .35s linear;visibility:visible}.hidden2{opacity:0;transition:visibility 0s .3s,opacity .3s linear;visibility:hidden}.dashboard .chat{position:relative}.dashboard .chat .scroll-to-bottom{bottom:6px;min-height:40px;padding-right:12px;position:sticky;text-align:right}.dashboard .chat .scroll-to-bottom span{background:#495057;border:2px solid #fff;border-radius:50%;box-shadow:0 0 10px rgba(0,0,0,.34901960784313724);color:#fff;cursor:pointer;display:inline-block;font-size:20px;height:35px;line-height:35px;overflow:hidden;text-align:center;width:35px}.dashboard .chat .group-info{line-height:30px;margin:-10px;padding:5px 10px;top:0;z-index:99}.dashboard .chat .group-info,.dashboard .chat .pin{background:#fff;box-shadow:0 0 3px -1px rgba(0,0,0,.21176470588235294);position:sticky}.dashboard .chat .pin{margin-bottom:10px;margin-left:-10px;top:40px;width:calc(100% + 20px);z-index:98}.dashboard .chat ul li.message-from.pin>span,.dashboard .chat ul li.message-own.pin>span{background-color:transparent}.dashboard .chat ul li.message-from.pin>span{margin-left:0}.dashboard .chat .message-content i{color:#495057;cursor:pointer;font-size:11px}.dashboard .chat .pin .message-content i{display:block}.dashboard .chat li.message-from .message-content{padding-left:6px}.dashboard .chat li.message-from .message-content i{padding:5px}.dashboard .chat li.message-own .message-content i{padding:5px;position:absolute;right:-15px}.dashboard .chat .group-info .circleButton{float:right;margin-bottom:0;margin-top:0}.dashboard .chat ul{margin-top:20px;padding:0}.dashboard .chat .new-message .message-input input.ui-inputtext:focus{box-shadow:none;outline:none}.dashboard .chat ul.hasPin{margin-top:10px}.dashboard .chat .group-info a{color:#495057}.normalHtml,.normalHtml b,.normalHtml strong{font-weight:400}.normalHtml{display:inline-block}.avatar-viewer .profile-image{border:1px solid #fff;border-radius:50%;height:40px;margin-top:-6px;width:40px}a.button>i{margin-right:5px}.dashboard .timeline{padding-top:20px}.ui-inputgroup .ui-inputtext{padding-right:0}.new-message .ui-inputtext{width:100%}.full-screen,.full-screen>.p-dialog{height:100%!important;left:0!important;max-height:100%;min-height:unset!important;min-width:100%!important;top:0!important;width:100%!important}#image-view-list.image-gallery-2{background-color:rgba(0,0,0,.4);height:calc(100vh - 41px);margin:-14px auto 0;touch-action:none;width:100%}#image-view-list.image-gallery-2 .image-container{background-color:transparent;border:0;bottom:0;height:85%;margin:auto}#image-view-list.image-gallery-2 .image-container .iv-snap-view{bottom:20px;left:calc(50% - 75px);top:auto}#image-view-list.image-gallery-2 .image-container .iv-image-view img{touch-action:auto}#image-view-list .inline-icon{margin-top:-41px}#image-view-list .footer-info,#image-view-list .material-icons.next,#image-view-list .material-icons.prev{display:none}#image-view-list .options-image-viewer{-moz-user-select:none;-ms-user-select:none;-webkit-user-select:none;margin-right:37px;user-select:none}.mobile-image-viewer-close{color:#fff;cursor:pointer;font-size:x-large;height:42px;line-height:42px;padding-right:7px;padding-top:2px;position:absolute;right:0;text-align:center;top:0;vertical-align:middle;width:37px}.mobile-image-viewer-close:hover{color:#feca37!important}.hide-holder{padding:0}.file-ex-name{word-break:break-all}.box-function{background:#fff;border-radius:0 0 5px 5px;border-top:1px solid #e8e8e8;bottom:0;left:0;padding:8px 30px;position:absolute;text-align:right;width:100%}.box-function button{margin-left:5px}.quick-note-button-holder{bottom:40px;display:none;height:50px;position:absolute;right:50px;width:50px;z-index:99}.quick-note-button{background:#ffc107;border:2px solid #fff;border-radius:50%;box-shadow:0 2px 5px 0 #b9b9b9;color:#fff;display:block;font-size:2em;height:50px;line-height:50px;outline:none;text-align:center;width:50px}.quick-note-button:hover{color:#fff}.all-note-button{background:#ffd24b;border:2px solid #fff;border-radius:50%;box-shadow:0 2px 5px 0 #b9b9b9;color:#fff;display:block;font-size:1.5em;height:40px;line-height:40px;outline:none;position:absolute;right:5px;text-align:center;top:5px;transition:right;transition-duration:.16s;transition-timing-function:ease-in;width:40px;z-index:-1}.all-note-button:hover{color:#fff}.setting-note-button{background:#ffd24b;border:2px solid #fff;border-radius:50%;box-shadow:0 2px 5px 0 #b9b9b9;color:#fff;display:block;font-size:1.5em;height:40px;line-height:40px;outline:none;position:absolute;right:5px;text-align:center;top:5px;transition:right;transition-duration:.16s;transition-timing-function:ease-in;width:40px;z-index:-1}.setting-note-button:hover{color:#fff}.pinned-notes-holder{bottom:20px;display:none;left:20px;position:absolute;width:250px;z-index:98}.pinned-notes{background:transparent;display:block;outline:none;padding:0}.pinned-notes-header{font-size:1rem;font-weight:700}.pinned-notes-setting{position:absolute;right:.5rem}.pinned-note{background-color:#fff1ac;box-shadow:1px 2px 3px rgba(185,139,6,.6313725490196078);font-size:.8rem;margin-bottom:10px;padding:0;position:relative}.pinned-note:last-child{margin-bottom:0}.pinned-notes-minimize-button{background:#ffc003;border:1px solid #fff;border-radius:50%;box-shadow:1px 2px 3px rgba(185,139,6,.6313725490196078);color:#fff;cursor:pointer;height:25px;padding-top:5px;position:absolute;right:-15px;text-align:center;top:-15px;width:25px;z-index:1}.pinned-note-header-line{border:1px solid #fff;box-shadow:1px 1px 2px rgba(0,0,0,.4);height:calc(100% - 1rem);left:3px;margin-bottom:.5rem;margin-top:.5rem;max-height:20px;position:absolute;width:13px}.pinned-note-header-right{cursor:pointer;float:right;margin-left:3px;width:32px}.pinned-note-header-time{font-size:.6rem}.pinned-note-header-button-unpin{display:none;float:left;height:14px;margin-right:2px;opacity:.8;width:14px}.pinned-note-header-button-complete{display:none;padding-top:2px}.pinned-note-body{float:right;padding:.5rem .5rem .5rem 25px;width:100%}.pinned-note-body:hover{background-color:#feeb82}.pinned-note-body:hover .pinned-note-header-time{display:none}.pinned-note-body:hover .pinned-note-header-button-complete,.pinned-note-body:hover .pinned-note-header-button-unpin{display:block}.pinned-note-line-title{color:#333;display:block;font-weight:700;padding-bottom:6px}.pinned-note-line{display:block}.view-port{border-radius:5px;box-shadow:0 0 0 9999px rgba(0,0,0,.5882352941176471);display:none;height:0;width:0;z-index:999}.view-port,.view-port-mask{background:transparent;position:absolute}.view-port-mask{display:block;height:100%;left:0;top:0;width:100%;z-index:9998}.tinymce-control{border:1px solid #ccc;display:none;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;font-size:14px;width:100%}.input-tab-trap{filter:alpha(opacity=0)!important;opacity:0!important;overflow:hidden!important;width:0!important}.color-value input{font-size:.8em;line-height:16px}.dialog-material.mobile{width:100%!important}audio,audio:focus,video,video:focus{outline:none}.iv-image-view img.iv-image{-webkit-animation:fadein .5s;animation:fadein .5s;visibility:hidden!important}@-webkit-keyframes fadein{0%{opacity:0}to{opacity:1}}@keyframes fadein{0%{opacity:0}to{opacity:1}}.iv-image-view img.iv-image.show{visibility:visible!important}.row-line{padding-bottom:0;padding-top:0}.fc-ltr{padding-bottom:7px}.padding-bottom-5px{padding-bottom:5px}.no-margin{margin:0!important}.no-padding{padding:0}.no-padding-left{padding-left:0}.float-left{float:left}body .fc .fc-toolbar .fc-button{background-color:#007ad9;border:1px solid #007ad9;border-radius:3px;color:#fff;font-size:14px;transition:background-color .2s,box-shadow .2s}body .fc .fc-toolbar .fc-button:enabled:hover{background-color:#116fbf;border-color:#116fbf;color:#fff}body .fc .fc-toolbar .fc-button:focus{box-shadow:0 0 0 .2em #8dcdff;outline:0 none;outline-offset:0}body .fc .fc-toolbar .fc-button-group .fc-button{border-radius:0}body .fc .fc-toolbar .fc-button-group .fc-button:first-child{border-bottom-left-radius:3px;border-top-left-radius:3px}body .fc .fc-toolbar .fc-button-group .fc-button:last-child{border-bottom-right-radius:3px;border-top-right-radius:3px}body .fc .fc-toolbar .fc-right .fc-button{border-radius:0}body .fc .fc-toolbar .fc-right .fc-button:first-child{border-bottom-left-radius:3px;border-top-left-radius:3px}body .fc .fc-toolbar .fc-right .fc-button:last-child{border-bottom-right-radius:3px;border-top-right-radius:3px}.fc-toolbar>*>:not(:first-child){margin-left:0}.fc-axis,.fc-dayGridMonth-button,.fc-timeGridDay-button,.fc-timeGridWeek-button,.old-content{line-height:0;text-indent:-9999px}.fc-axis:after,.fc-dayGridMonth-button:after,.fc-timeGridDay-button:after,.fc-timeGridWeek-button:after,.new-content{display:block;line-height:normal;text-indent:0}.fc-dayGridMonth-button:after{content:\"Th\u00E1ng\";padding:.2em}.fc-timeGridWeek-button:after{content:\"Tu\u1EA7n\";padding:.2em}.fc-timeGridDay-button:after{content:\"Ng\u00E0y\";padding:.2em}body .fc th{background-color:#f4f4f4;border:1px solid #c8c8c8;color:#333;padding:.571em 1em}.ui-fluid .button-group button,.ui-fluid .button-group p-button{margin-right:.5em!important;text-align:left;width:auto}.layout-wrapper .layout-menu-container{z-index:97}.base-status,.base-status-aborted,.base-status-approved,.base-status-completed,.base-status-create-new,.base-status-ended,.base-status-high,.base-status-immediately,.base-status-low,.base-status-medium,.base-status-on-conducting,.base-status-on-going,.base-status-pending,.base-status-rejected,.base-status-returned,.base-status-urgent{border-radius:.25em;color:#fff;font-size:.8em;padding:3px;text-align:center}.base-status-create-new{background-color:#f2f2f2;color:#666}.base-status-on-conducting,.base-status-on-going{background-color:#337ab7}.base-status-pending{background-color:#ffba01}.base-status-approved{background-color:#34a835}.base-status-returned{background-color:#ffba01}.base-status-rejected{background-color:#d9534f}.base-status-completed{background-color:#34a835}.base-status-aborted{background-color:#ffba01}.base-status-ended{background-color:#34a835}.base-status-low,.base-status-medium{background-color:#f2f2f2;color:#666}.base-status-high{background-color:#ffba01}.base-status-immediately,.base-status-urgent{background-color:#d9534f}.text-align-center{text-align:center}.font-weight-bold{font-weight:700}.landing-body .landing-menu li a:hover{border-bottom:none}.landing-body .landing-menu li:first-child{margin-left:8px}.crud-form .label-control p{margin:0;padding:0}.crud-form .tn-check-box-list .p-row{display:block;padding:.5em;width:100%}.crud-form dropdown,.crud-form tn-mask{width:100%}.crud-form .tn-dropdown{min-height:32px}.crud-form .tn-dropdown.free-text.horizontal{display:flex}.crud-form .tn-dropdown.free-text.horizontal>div{flex-grow:1;padding-left:.5em;padding-right:.5em}.crud-form .tn-dropdown.free-text.horizontal>div:first-child{padding-left:0}.crud-form .tn-dropdown.free-text.horizontal>div:last-child{padding-right:0}.crud-form .tn-dropdown.free-text.vertical input.ui-inputtext.input-free-text{margin-top:.5em}.crud-form.assessment .label-control{font-weight:700}.crud-form.assessment .label-control.haveIndex{display:block;margin-bottom:5px;padding-left:20px;position:relative}.crud-form.assessment .label-control.haveIndex:before{content:\" \" attr(label-index) \".\";left:0;position:absolute;top:0}.crud-form.assessment .ViewMode{border-bottom:none}.crud-form.assessment .ViewMode .label-control{margin-bottom:0}body .ui-inputtext.min-width{padding:6px}.ps__rail-x,.ps__rail-y{z-index:2}.zIndex5 .ps__rail-x,.zIndex5 .ps__rail-y{z-index:5}.table-sticky table{border-collapse:separate;border-spacing:0}.table-sticky tr td,.table-sticky tr th{border:1px solid #eee!important;border-left:none!important;border-top:none!important}.table-sticky tr td:first-child,.table-sticky tr th:first-child{border-left:1px solid #eee!important}.table-sticky tr td:last-child,.table-sticky tr th:last-child{border-right:none!important}.table-sticky tr:first-child th{border-top:1px solid #eee!important}.table-sticky th{background:#eee}.table-sticky tbody td.disabled{background:#eee!important}.table-sticky tbody td.disabled:not(:last-child){border-right:1px solid #fff!important}.table-sticky.fix-height tr:first-child th{position:sticky;top:0;z-index:2}.container-flex{align-items:center;display:flex}.container-flex>div:first-child{flex:0 0 auto;margin-right:.5em}.container-flex>div:last-child{flex-grow:1}.container-control{display:flex}.container-control>span.label{flex:0 0 auto;padding-right:.5em;padding-top:.5em}.container-control>span.label+*{flex-grow:1;flex-shrink:1;position:relative}.container-control>span.label+* .tn-dropdown,.container-control>span.label+* .ui-autocomplete-multiple,.container-control>span.label+* .ui-inputgroup .ui-inputtext{width:100%}.container-control>span.label+* .validation-container{margin-top:3px}.container-control>span.label+* .validation-container .validate-item{white-space:unset}.container-control>span.label+*>div{left:0;position:absolute;top:0;width:100%}.container-control.no-label>span.label{display:none}.container-control.inline{display:inline-flex}.align-flex-center{align-items:center;display:flex;justify-content:center}@media print{.isPrinting>*{display:none}.isPrinting app-print-layout{display:block}}.layout-wrapper .topbar .topbar-left,.layout-wrapper .topbar .topbar-right{background:#397ac3}#searchResultPanel-holder{padding:0 .5em}.cus-dropdown{line-height:normal;margin-right:1em}.tn-thumbnail{padding:.5rem}.tn-thumbnail.tn-thumbnail.tn-thumbnail{box-sizing:border-box}.fa-10:before{content:\"A+\";font-family:cursive;font-weight:700}.layout-wrapper .topbar .topbar-right #menu-button i{font-size:20px;margin-top:4px}.layout-wrapper .layout-menu li a i.menuitem-toggle-icon{font-size:15px;margin-left:auto}.flex-container-main-content{display:flex;flex-direction:column}.flex-container-main-content>div:last-child{background-color:#f4f4f4;display:flex;flex:1 1;overflow:hidden;position:relative}.flex-container-main-content>div:last-child>div{height:100%;left:0;overflow:hidden;padding-top:.5em;position:absolute;top:0;width:100%}.flex-container-main-content .block-with-button-search{display:flex;justify-content:flex-end}.flex-container-main-content .block-with-button-search>*{margin-left:.5em}.flex-container-main-content .block-with-button-search>input{height:26px;margin-left:0;max-width:200px;width:100%}.flex-container-main-content .block-with-button-search>dropdown{max-width:140px;width:100%}.flex-container-main-content .title-main-component{border-bottom:2px solid #1ca7ff}.clickable-table.clickable-table{cursor:pointer}.main-crud-container{height:calc(100vh - 76px)}.flex-container-fit-child{display:flex;flex-direction:column;height:100%;overflow:hidden}.flex-container-fit-child>div.fit-content{flex:1 1;position:relative}.flex-container-fit-child>div.fit-content>div{height:100%;overflow:auto;position:absolute;width:100%}.waiting-box{display:none;height:100%;left:0;position:fixed;top:0;width:100%;z-index:9999}.waiting-box .overlay{background-color:red;background-color:hsla(0,0%,42.7%,.5019607843137255);height:100%;width:100%}.waiting-box .content-loading{left:50%;position:absolute;top:50%;transform:translate(-50%,-50%)}.waiting-box.show{display:block}.function-topbar>*{vertical-align:top}.function-topbar button{width:auto}.function-topbar p-fileUpload{margin-right:1em}.function-topbar .container-control{display:inline-flex;line-height:normal}.function-topbar .container-control dropdown{width:100%}:focus{outline-color:#a6d5fa!important}address{font-style:normal}body .p-toast .p-toast-message{border-radius:0;border-width:0 0 0 4px!important}.__status span,.status span{font-size:.8rem}p-table.single-check .p-datatable .p-datatable-tbody>tr{cursor:pointer}p-table.single-check .p-datatable .p-datatable-tbody>tr.ui-state-highlight{background:#e3f2fd!important;outline:2px solid #a6d5fa}p-table.single-check .p-datatable .p-datatable-tbody>tr td.sticky .fix-sticky.top{display:none}p-table.multi-check .p-datatable .p-datatable-tbody>tr.ui-state-highlight{background:#e3f2fd!important}p-table.multi-check .p-datatable .p-datatable-tbody>tr.ui-state-highlight td{border-color:#fff}p-table.multi-check .p-datatable .p-datatable-tbody>tr.ui-state-highlight td .fix-sticky{background-color:#fff}.tn-animated-left-arrow-icon,.tn-animated-right-arrow-icon{height:32px;position:relative;width:14px;z-index:10}.tn-animated-right-arrow-icon{-webkit-animation:arrowBounceToRight .8s ease-in-out infinite alternate;animation:arrowBounceToRight .8s ease-in-out infinite alternate}.tn-animated-left-arrow-icon{-webkit-animation:arrowBounceToLeft .8s ease-in-out infinite alternate;animation:arrowBounceToLeft .8s ease-in-out infinite alternate}.tn-animated-left-arrow-icon:after,.tn-animated-left-arrow-icon:before,.tn-animated-right-arrow-icon:after,.tn-animated-right-arrow-icon:before{background-color:#88b0dd;content:\"\";display:block;height:20px;position:absolute;width:5px}.tn-animated-right-arrow-icon:before{left:4px;top:0;transform:rotate(-35deg)}.tn-animated-right-arrow-icon:after{left:4px;top:14px;transform:rotate(35deg)}.tn-animated-left-arrow-icon:before{right:4px;top:0;transform:rotate(35deg)}.tn-animated-left-arrow-icon:after{right:4px;top:14px;transform:rotate(-35deg)}@-webkit-keyframes arrowBounceToLeft{0%{transform:translateX(-3px)}to{transform:translateX(3px)}}@keyframes arrowBounceToLeft{0%{transform:translateX(-3px)}to{transform:translateX(3px)}}@-webkit-keyframes arrowBounceToRight{0%{transform:translateX(3px)}to{transform:translateX(-3px)}}@keyframes arrowBounceToRight{0%{transform:translateX(3px)}to{transform:translateX(-3px)}}.pass{color:#49c949}.not-pass,.pass{margin:5px;text-align:center}.not-pass{color:red}"]
|
|
43311
|
+
},] }
|
|
43312
|
+
];
|
|
43313
|
+
ChatSendMessageBoxComponent.ctorParameters = () => [
|
|
43314
|
+
{ type: Injector },
|
|
43315
|
+
{ type: ChatService },
|
|
43316
|
+
{ type: CheckControlVisibleService },
|
|
43317
|
+
{ type: FileExplorerNewService },
|
|
43318
|
+
{ type: NotifierService }
|
|
43319
|
+
];
|
|
43320
|
+
ChatSendMessageBoxComponent.propDecorators = {
|
|
43321
|
+
fileElement: [{ type: ViewChild, args: ['fileElement', { static: false },] }],
|
|
43322
|
+
input: [{ type: ViewChild, args: ['input', { static: true },] }],
|
|
43323
|
+
driveFileDialog: [{ type: ViewChild, args: ['driveFileDialog', { static: false },] }]
|
|
43324
|
+
};
|
|
43325
|
+
|
|
43326
|
+
class UserPickerDialogComponent extends DataListBase {
|
|
43327
|
+
constructor(_userService, _injector) {
|
|
43328
|
+
super(_injector);
|
|
43329
|
+
this._userService = _userService;
|
|
43330
|
+
this.STORAGE_KEY_USER_PICKER_NAME = 'user_picker_storage_name';
|
|
43331
|
+
this.STORAGE_KEY_USER_PICKER_ID_USER = 'user_picker_storage_id_user';
|
|
43332
|
+
this.STORAGE_KEY_USER_PICKER_SEARCH_KEY = 'user_picker_storage_search_key';
|
|
43333
|
+
this.STORAGE_KEY_USER_PICKER_NODE_SELECTED = 'user_picker_storage_node';
|
|
43334
|
+
this.rootTreeNode = [
|
|
43335
|
+
{
|
|
43336
|
+
label: '',
|
|
43337
|
+
data: '-1',
|
|
43338
|
+
expandedIcon: 'pi pi-folder-open',
|
|
43339
|
+
collapsedIcon: 'pi pi-folder',
|
|
43340
|
+
children: []
|
|
43341
|
+
}
|
|
43342
|
+
];
|
|
43343
|
+
this.multiple = false;
|
|
43344
|
+
this.enableCaching = true;
|
|
43345
|
+
this.isFirstLoad = true;
|
|
43346
|
+
this.rootFilter = {};
|
|
43347
|
+
}
|
|
43348
|
+
ngOnInit() {
|
|
43349
|
+
this.setting.baseService = this._userService;
|
|
43350
|
+
super.ngOnInit();
|
|
43351
|
+
}
|
|
43352
|
+
}
|
|
43353
|
+
UserPickerDialogComponent.decorators = [
|
|
43354
|
+
{ type: Component, args: [{
|
|
43355
|
+
selector: 'app-user-picker-dialog',
|
|
43356
|
+
template: "<p>\r\n user-picker-dialog works!\r\n</p>\r\n",
|
|
43357
|
+
providers: [ComponentContextService],
|
|
43358
|
+
styles: [""]
|
|
43359
|
+
},] }
|
|
43360
|
+
];
|
|
43361
|
+
UserPickerDialogComponent.ctorParameters = () => [
|
|
43362
|
+
{ type: UserService },
|
|
43363
|
+
{ type: Injector }
|
|
43364
|
+
];
|
|
43365
|
+
UserPickerDialogComponent.propDecorators = {
|
|
43366
|
+
dialog: [{ type: ViewChild, args: ['dialog',] }],
|
|
43367
|
+
multiple: [{ type: Input }],
|
|
43368
|
+
enableCaching: [{ type: Input }],
|
|
43369
|
+
control: [{ type: Input }]
|
|
43370
|
+
};
|
|
43371
|
+
|
|
41818
43372
|
function coreDeclaration() {
|
|
41819
43373
|
return [
|
|
41820
43374
|
AddressComponent,
|
|
@@ -41890,6 +43444,7 @@ function coreDeclaration() {
|
|
|
41890
43444
|
StartWorkflowComponent,
|
|
41891
43445
|
WorkflowPickerComponent,
|
|
41892
43446
|
WorkflowSettingNewComponent,
|
|
43447
|
+
PermissionSharingComponent,
|
|
41893
43448
|
TnDialogComponent,
|
|
41894
43449
|
TnColorPickerComponent,
|
|
41895
43450
|
TnCustomScrollbarComponent,
|
|
@@ -41956,7 +43511,10 @@ function coreDeclaration() {
|
|
|
41956
43511
|
AddNewsComponent,
|
|
41957
43512
|
CommonDashboardComponent,
|
|
41958
43513
|
NotFoundComponent,
|
|
41959
|
-
UniversalLinkProcessorComponent
|
|
43514
|
+
UniversalLinkProcessorComponent,
|
|
43515
|
+
ChatBoxComponent,
|
|
43516
|
+
ChatSendMessageBoxComponent,
|
|
43517
|
+
UserPickerDialogComponent
|
|
41960
43518
|
];
|
|
41961
43519
|
}
|
|
41962
43520
|
function coreModuleImport() {
|
|
@@ -43122,61 +44680,6 @@ EformService.ctorParameters = () => [
|
|
|
43122
44680
|
{ type: ModuleConfigService }
|
|
43123
44681
|
];
|
|
43124
44682
|
|
|
43125
|
-
class CheckControlVisibleService {
|
|
43126
|
-
constructor() { }
|
|
43127
|
-
checkDisplayStatus(elem) {
|
|
43128
|
-
return new Promise((resolve, reject) => {
|
|
43129
|
-
this.doCheck(resolve, elem);
|
|
43130
|
-
});
|
|
43131
|
-
}
|
|
43132
|
-
doCheck(resolve, elem) {
|
|
43133
|
-
let timeoutCheckDisplayStatus;
|
|
43134
|
-
timeoutCheckDisplayStatus = setTimeout(() => {
|
|
43135
|
-
this.doCheck(resolve, elem);
|
|
43136
|
-
}, 100);
|
|
43137
|
-
var newStatus = this.isVisible(elem);
|
|
43138
|
-
if (newStatus) {
|
|
43139
|
-
setTimeout(() => {
|
|
43140
|
-
// show control
|
|
43141
|
-
resolve(true);
|
|
43142
|
-
});
|
|
43143
|
-
clearTimeout(timeoutCheckDisplayStatus);
|
|
43144
|
-
}
|
|
43145
|
-
}
|
|
43146
|
-
isVisible(elem) {
|
|
43147
|
-
const style = getComputedStyle(elem);
|
|
43148
|
-
if (style.display === 'none')
|
|
43149
|
-
return false;
|
|
43150
|
-
if (style.visibility !== 'visible')
|
|
43151
|
-
return false;
|
|
43152
|
-
if (+style.opacity < 0.1)
|
|
43153
|
-
return false;
|
|
43154
|
-
if (elem.offsetWidth + elem.offsetHeight + elem.getBoundingClientRect().height +
|
|
43155
|
-
elem.getBoundingClientRect().width === 0) {
|
|
43156
|
-
return false;
|
|
43157
|
-
}
|
|
43158
|
-
const elemCenter = {
|
|
43159
|
-
x: elem.getBoundingClientRect().left + elem.offsetWidth / 2,
|
|
43160
|
-
y: elem.getBoundingClientRect().top + elem.offsetHeight / 2
|
|
43161
|
-
};
|
|
43162
|
-
let pointContainer = document.elementFromPoint(elemCenter.x, elemCenter.y);
|
|
43163
|
-
if (pointContainer) {
|
|
43164
|
-
do {
|
|
43165
|
-
if (pointContainer === elem)
|
|
43166
|
-
return true;
|
|
43167
|
-
} while (pointContainer = pointContainer.parentNode);
|
|
43168
|
-
}
|
|
43169
|
-
return false;
|
|
43170
|
-
}
|
|
43171
|
-
}
|
|
43172
|
-
CheckControlVisibleService.ɵprov = ɵɵdefineInjectable({ factory: function CheckControlVisibleService_Factory() { return new CheckControlVisibleService(); }, token: CheckControlVisibleService, providedIn: "root" });
|
|
43173
|
-
CheckControlVisibleService.decorators = [
|
|
43174
|
-
{ type: Injectable, args: [{
|
|
43175
|
-
providedIn: 'root'
|
|
43176
|
-
},] }
|
|
43177
|
-
];
|
|
43178
|
-
CheckControlVisibleService.ctorParameters = () => [];
|
|
43179
|
-
|
|
43180
44683
|
class ImageService {
|
|
43181
44684
|
constructor(_moduleConfigService) {
|
|
43182
44685
|
this._moduleConfigService = _moduleConfigService;
|
|
@@ -43738,5 +45241,5 @@ DynamicComponentService.ctorParameters = () => [
|
|
|
43738
45241
|
* Generated bundle index. Do not edit.
|
|
43739
45242
|
*/
|
|
43740
45243
|
|
|
43741
|
-
export { AccessDeniedComponent, Action, AddressControlSchema, AddressService, AdvanceSearchData, AdvanceSearchSetting, AppComponentBase, AppListService, ApplicationContextService, ApprovalPipe, ArrayPair, AtLeastOneRowTableValidator, AuthenService, AuthorizeDirective, AutoCompleteControlSchema, AutoCompletePickerControlSchema, AutocompleteDatasourceComponent, AvatarUploaderComponent, BaseCauHinhWorkflowComponent, BaseCongViecComponent, BaseCongViecFormComponent, BaseDmLoaiCongViecComponent, BaseDmPriorityComponent, BaseMenuService, BaseModule, BaseService, BooleanFormatPipe, ButtonControlSchema, CONFIG_CALENDAR_VIETNAMESE, CalculationEngineService, CanBoHoSoService, CauHinhWorkflowService, CellExcel, CheckBoxListControlSchema, CheckControlVisibleService, CheckDuplicateFieldsValidator, CheckDuplicateValidator, CheckboxControlSchema, ClientV5Service, CoCauToChucControlSchema, CoCauToChucPickerComponent, CoCauToChucPickerControlSchema, CoCauToChucService, ColorBlack, ColorControlSchema, ColorPickerControlSchema, ColorWhite, Column, ColumnSchemaBase, ColumnSetting, ColumnSettingDetail, ComCtxConstants, CommandType, CommonAppComponentComponent, CommonDashboardComponent, CommonErrorCode, CommonService, CompareValidator, ComponentBase, ComponentConstants, ComponentContextService, ConditionalBuilderService, CongViecLienQuanService, CongViecPickerControlSchema, CongViecService$1 as CongViecService, ContainerSchema, ControlTreeNode, ControlType, ConvertMoneyToWordPipe, CoreConfigService, CrudBase, CrudFormComponent, CrudFormCustomFunction, CrudFormData, CrudFormSetting, CrudListComponent, CrudListConfig, CrudListCustomFunction, CrudListData, CrudListHelper, CrudListSetting, CrudService, CustomControlSchema, CustomRouterService, DanhmucApiService, DataExcel, DataFormBase, DataListBase, DataSourceControlSchema, DataSourceStateType, DataSourceTargetType, DataSourceUserRule, DataSourceUserSender, DataSourceWorkflowCoreStatus, DataType, DateCompareValidator, DateTimeControlSchema, DateTimeRangeControlSchema, DbOrganizationOrganizationService, DbOrganizationPositionService, Deadline, DeadlineType, DhvinhGuardService, DialogModel, DmLoaiCongViecService, DmPriorityService, DomService, DownloadLinkService, DropdownComponent, DropdownControlSchema, DropdownOptions, DynamicComponentService, ENUM_DON_VI_HANH_CHINH, EXPLORER_TYPES, EXPORT_VERSION_V4, EXPORT_VERSION_V5, EditFileCommand, EditorControlSchema, EformService, EmailValidator, EntityMedataDataSetting, EntityMetadataService, EntityPickerColumn, EntityPickerControlSchema, EntityWorkflowType, EnumActionType, EnumControlPickerType, EnumFileLayout, EnumGetRefType, EnumLoaiDanhSachCongViec, EnumStateByMenuCongViec, EnumStateType, EnumTargetType, EnumTypeSplash, EnumUserRule, EnumWFNhomTrangThai, EnumWorkflowCoreCodeSettingKey, EnumWorkflowHistoryStatus, ErrorType, EventData, ExactOneValueInTableValidator, ExportAllMode, ExportItem, ExportItemType, ExportItemsMode, ExportManyModel, ExportManyResultModel, ExportModel, ExportService, ExportWithoutTemplateModel, Extension, FILE_TYPES, FieldDefineIsTaskFormControl, FieldDefineIsWorkflowControl, FileDataService, FileExplorerService, FileManagerComponent, FileManagerControlSchema, FileManagerMode, FileObjectService, FilePickerDialogComponent, FileUploadComponent, FileUploadControlSchema, FileUploadMode, FileV4Service, Filter, FolderService, FormControlBase, FormControlBaseWithService, FormSchemaBase, FormSchemaBaseWithService, FormState, Gender, GenerateLinkDownloadDTO, GenericGuardService, GetRefDataSchema, GlobalService, GmailCorrector, GridInfo, GuardService, GuardSvService, HeightType, HighPerformanceService, HighlightPipe, HtmlFormatPipe, ImageService, KeyFieldGetRefType, KeyFilterStateByMenuCongViec, KeyFlashShow, KeyValueComponent, KeyValueControlSchema, LabelSchema, LabelWFNhomTrangThai, LabelWorkflowCoreStatus, LengthValidator, ListHelperService, LoaiPhieuDeXuat, LocalCacheService, LowerCorrector, MA_THONG_BAO_PHAN_HE, ManagerType, MaskControlSchema, MasterDataItem, MasterDataPipe, MasterDataService, MenuService, MethodResult, ModelSchema, ModuleConfigService, MultiTranslateHttpLoader, MultipleReferenceDataFormatPipe, NodeService, NotificationObjectType, NotificationService, NotifierService, NumberCompareValidator, NumberOnlyValidator, NumberRangeControlSchema, Operator, OrganizationFormatPipe, OrganizationNameFormatPipe, OrganizationPickerControlSchema, OrganizationService, OrganizationsFormatPipe, PageInfo, PageSetting, Pair, Pattern, PercentControlSchema, PermissionBase, PermissionConstant, PermissionService, PermissionStorage, PermissionTypes, PermissionUtilsComponent, PersonalSetting, PhoneNumberValidator, PhoneValidator, PopupSize, PositionService, PrintService, PublicFunction, QueryBuilderComponent, QueryBuilderGroupComponent, QueryBuilderRuleComponent, QueryGroup, QueryRule, RadioButtonListControlSchema, RandomDataService, RefField, ReferenceDataFormatPipe, RegexSplitFieldByItem, RequiredFieldsValidator, RequiredValidator, RowColorOption, RowExcel, SHARE_COMPONENT_ID, SHARE_EVENT, SafeHtmlPipe, SafeStylePipe, SafeUrlPipe, SameValueValidator, SchemaBase, SecurePipe, ServiceFileUploadComponent, SessionTypes, SharedFolderType, SignalRService, SimpleDicItem, SimpleDictionary, Sort, SortDirs, SpanControlSchema, SplashComponentComponent, StartupBusinessComponentBase, StateComponent, StateMachineTopic, StateMachinesConnectionMetadataComponent, StateMachinesDesignerComponent, StateMachinesService, StateMetadataComponent, Status, StatusAction, StatusGroup, StatusOption, StatusOrg, StatusUser, StorageService, StorageUpdatedService, StringFormatPipe, SummaryPipe, SwitchControlSchema, TBL_DM_COSODAOTAO_CONSTS, TBL_DM_PHONGHOC_CONSTS, TBL_KTX_NGUOITHUE_HOSO, TBL_TS_PHIEUDEXUAT, TBL_TS_TAISANCODINH_CONSTS, TableSchema, TagSeparator, TemplateConstant, TemplateControlSchema, TemplateInstanceService, TemplateService, TemplateTextItem, TemplateTextMany, TemplateTextV4Service, TemplateType, TemplateV4Service, TenContainer, TextAlign, TextAreaControlSchema, TextControlSchema, TextControlSchemaWithService, TitleSchema, TnClientCommand, TnClientService, TnComponentConfig, TnCustomScrollbarComponent, TnDatePipe, TnReorderableColumnDirective, TnReorderableRowDirective, TnSortIcon, TnSortableColumnDirective, TnUser, TnxSharedModule, TopicReloadCongViecV5, TopicReloadNotification, TrangThaiMasterData, TrangThais, TreeDataOption, TrimCorrector, TrimEndCorrector, TrimStartCorrector, TypeDanhMucAPI, UniqueFieldInTableValidator, UniqueNumberService, UpperCorrector, UserFormatPipe, UserGroupService, UserPickerControlSchema, UserService, UserV5Service, UsersFormatPipe, Validation, VanBanPickerControlSchema, VirtualBaseService, WorkflowConfigAdvance, WorkflowCoreStatusEnum, WorkflowFieldStateCode, WorkflowPermissionDetailService, WorkflowPickerComponent, WorkflowService, WorkflowSetting, WorkflowSettingNew, WrapPickerControlSchema, addDay, addZero, appendDefaultFilter, clearAll, clone, cloneOld, coreDeclaration, coreModuleImport, coreProvider, createJsPlumnInstance, createOrgPickerControl, createRolePickerControl, createUserGroupPickerControl, createUserPickerControl, dataSourceIcon$1 as dataSourceIcon, dateDiff, genQueryFromFilters, getDateFromStringDateVN, getDayOfWeek, getEnvironmentByName, getEnvironmentData, getListMenuByName, getMenuData, getMonday, getStringDate, getStringDateTime, getStringDateVN, getStringDateVNLocal, getTimeSpan, isArray, isBoolean, isDate, isFunction, isLiteralObject, isNumber, isObjectOld, isRegular, isSimpleType, isString, isValidDate, keyUserSurveyLocal, maximumPageSize, mergeJSON, mergeJSONOld, moduleConfigFunc, multipleSort, romanize, setMetadataConnection, translateStateMachine, ɵ0, ɵ1, ɵ10, ɵ2, ɵ3, ɵ4, ɵ5, ɵ6, ɵ7, ɵ8, ɵ9, AddressComponent as ɵa, DropdownService as ɵb, DynamicNodeComponent as ɵba, EntityPickerBoxComponent as ɵbb, EntityPickerDataComponent as ɵbc, EntityPickerSelectedComponent as ɵbd, EntityPickerComponent as ɵbe, EntityPickerDialogComponent as ɵbf, EntityPermissionComponent as ɵbg, DM_ChucVuService as ɵbh, RoleService as ɵbi, EntityPermissionService as ɵbj, EquationEditorComponent as ɵbk, MaskComponent as ɵbl, NumberPickerRangeComponent as ɵbm, PagingNextBackOnlyComponent as ɵbn, RadioButtonListComponent as ɵbo, VanBanPickerComponent as ɵbp, VanBanDenService as ɵbq, VanBanDiService as ɵbr, VanBanPickerDialogComponent as ɵbs, VanbanDiPickerComponent as ɵbt, VanbanDenPickerComponent as ɵbu, CongViecPickerComponent as ɵbv, CongViecService as ɵbw, TaskWorkflowHistoriesService as ɵbx, SettingsComponent as ɵby, SettingsRowComponent as ɵbz, EntityPickerService as ɵc, SettingsWorkflowComponent as ɵca, SettingsWorkflowNo1Component as ɵcb, SimpleWorkflowFormComponent as ɵcc, ProcessWorkflowFormComponent as ɵcd, WorkflowHistoryService as ɵce, ProcessWorkflowTargetComponent as ɵcf, ChoYKienFormComponent as ɵcg, SplashComponentV1Component as ɵch, StateMachinesConnectionReceiverComponent as ɵci, StateMachinesConnectionReceiverUserComponent as ɵcj, StateMachinesConnectionReceiverDepartmentComponent as ɵck, StateMachinesConnectionReceiverGroupComponent as ɵcl, StateMachinesConnectionReceiverRoleComponent as ɵcm, StateMachinesConnectionSenderComponent as ɵcn, StartWorkflowComponent as ɵco, WorkflowSettingsService as ɵcp, WorkflowSettingNewComponent as ɵcq, TnDialogComponent as ɵcr, TnColorPickerComponent as ɵcs, TnTinymceComponent as ɵct, TnTabViewComponent as ɵcu, TableDetailFormComponent as ɵcv, FileIconPipe as ɵcw, FileSizePipe as ɵcx, QuickAddFormComponent as ɵcy, PreventShiftTabDirective as ɵcz, ExceptionHandlerService as ɵd, TnTemplateDirective as ɵda, UserPickerComponent as ɵdb, UserPickerBoxComponent as ɵdc, TnAppHelpComponent as ɵdd, PathNameService as ɵde, HelperCurrentPageComponent as ɵdf, TnAppNotificationListComponent as ɵdg, TnAppNotificationComponent as ɵdh, MyDriveService as ɵdi, FileVersionService as ɵdj, FileExplorerNewService as ɵdk, FolderFormComponent as ɵdl, FileFormComponent as ɵdm, FileViewerComponent as ɵdn, FileVersionListComponent as ɵdo, WorkflowHistoryComponent as ɵdp, EntityWorkflowHistoryService as ɵdq, WorkflowHistoryDialogComponent as ɵdr, WorkflowHistoryNewComponent as ɵds, WorkflowSettingComponent as ɵdt, EntityWorkflowSettingService as ɵdu, WorkflowSettingDialogComponent as ɵdv, QrCodeGeneratorComponent as ɵdw, AccessDeniedV1Component as ɵdx, AddNewsComponent as ɵdy, ArticleService as ɵdz, CanBo_HoSoService as ɵe, NewsCategoryService as ɵea, NotFoundComponent as ɵeb, UniversalLinkProcessorComponent as ɵec, CheckReadyComponent as ɵed, SendAccessTokenInterceptor as ɵee, LogInterceptor as ɵef, PermissionUtilsInterceptor as ɵeg, AfterViewCheckedComponent as ɵf, AdvanceSearchComponent as ɵg, AppRootMenuComponent as ɵh, AppTopBarComponent as ɵi, AppTopBarV1Component as ɵj, AppProfileComponent as ɵk, AppSubMenuComponent as ɵl, AppMenuComponent as ɵm, AutoCompletePickerComponent as ɵn, CheckBoxListComponent as ɵo, ReportQueueComponent as ɵp, CoCauToChucPickerListComponent as ɵq, BaseCongViecTestComponent as ɵr, BaseCauHinhWorkflowDetailComponent as ɵs, BaseDmLoaiCongViecFormComponent as ɵt, BaseDmPriorityFormComponent as ɵu, BaseCongviecDinhkemComponent as ɵv, CongviecDinhkemService as ɵw, BaseCongviecDinhkemFormComponent as ɵx, DatetimePickerComponent as ɵy, DatetimePickerRangeComponent as ɵz };
|
|
45244
|
+
export { AccessDeniedComponent, Action, AddressControlSchema, AddressService, AdvanceSearchData, AdvanceSearchSetting, AppComponentBase, AppListService, ApplicationContextService, ApprovalPipe, ArrayPair, AtLeastOneRowTableValidator, AuthenService, AuthorizeDirective, AutoCompleteControlSchema, AutoCompletePickerControlSchema, AutocompleteDatasourceComponent, AvatarUploaderComponent, BaseCauHinhWorkflowComponent, BaseCongViecComponent, BaseCongViecFormComponent, BaseDmLoaiCongViecComponent, BaseDmPriorityComponent, BaseMenuService, BaseModule, BaseService, BooleanFormatPipe, ButtonControlSchema, CONFIG_CALENDAR_VIETNAMESE, CalculationEngineService, CanBoHoSoService, CauHinhWorkflowService, CellExcel, ChatBoxComponent, ChatSendMessageBoxComponent, CheckBoxListControlSchema, CheckControlVisibleService, CheckDuplicateFieldsValidator, CheckDuplicateValidator, CheckboxControlSchema, ClientV5Service, CoCauToChucControlSchema, CoCauToChucPickerComponent, CoCauToChucPickerControlSchema, CoCauToChucService, ColorBlack, ColorControlSchema, ColorPickerControlSchema, ColorWhite, Column, ColumnSchemaBase, ColumnSetting, ColumnSettingDetail, ComCtxConstants, CommandType, CommonAppComponentComponent, CommonDashboardComponent, CommonErrorCode, CommonService, CompareValidator, ComponentBase, ComponentConstants, ComponentContextService, ConditionalBuilderService, CongViecLienQuanService, CongViecPickerControlSchema, CongViecService$1 as CongViecService, ContainerSchema, ControlTreeNode, ControlType, ConvertMoneyToWordPipe, CoreConfigService, CrudBase, CrudFormComponent, CrudFormCustomFunction, CrudFormData, CrudFormSetting, CrudListComponent, CrudListConfig, CrudListCustomFunction, CrudListData, CrudListHelper, CrudListSetting, CrudService, CustomControlSchema, CustomRouterService, DanhmucApiService, DataExcel, DataFormBase, DataListBase, DataSourceControlSchema, DataSourceStateType, DataSourceTargetType, DataSourceUserRule, DataSourceUserSender, DataSourceWorkflowCoreStatus, DataType, DateCompareValidator, DateTimeControlSchema, DateTimeRangeControlSchema, DbOrganizationOrganizationService, DbOrganizationPositionService, Deadline, DeadlineType, DhvinhGuardService, DialogModel, DmLoaiCongViecService, DmPriorityService, DomService, DownloadLinkService, DropdownComponent, DropdownControlSchema, DropdownOptions, DynamicComponentService, ENUM_DON_VI_HANH_CHINH, EXPLORER_TYPES, EXPORT_VERSION_V4, EXPORT_VERSION_V5, EditFileCommand, EditorControlSchema, EformService, EmailValidator, EntityMedataDataSetting, EntityMetadataService, EntityPickerColumn, EntityPickerControlSchema, EntityWorkflowType, EnumActionType, EnumControlPickerType, EnumFileLayout, EnumGetRefType, EnumLoaiDanhSachCongViec, EnumPermissionType, EnumStateByMenuCongViec, EnumStateType, EnumTargetType, EnumTypeSplash, EnumUserRule, EnumWFNhomTrangThai, EnumWorkflowCoreCodeSettingKey, EnumWorkflowHistoryStatus, ErrorType, EventData, ExactOneValueInTableValidator, ExportAllMode, ExportItem, ExportItemType, ExportItemsMode, ExportManyModel, ExportManyResultModel, ExportModel, ExportService, ExportWithoutTemplateModel, Extension, FILE_TYPES, FieldDefineIsTaskFormControl, FieldDefineIsWorkflowControl, FileDataService, FileExplorerService, FileManagerComponent, FileManagerControlSchema, FileManagerMode, FileObjectService, FilePickerDialogComponent, FileUploadComponent, FileUploadControlSchema, FileUploadMode, FileV4Service, Filter, FolderService, FormControlBase, FormControlBaseWithService, FormSchemaBase, FormSchemaBaseWithService, FormState, Gender, GenerateLinkDownloadDTO, GenericGuardService, GetRefDataSchema, GlobalService, GmailCorrector, GridInfo, GuardService, GuardSvService, HeightType, HighPerformanceService, HighlightPipe, HtmlFormatPipe, ImageService, KeyFieldGetRefType, KeyFilterStateByMenuCongViec, KeyFlashShow, KeyValueComponent, KeyValueControlSchema, LabelSchema, LabelWFNhomTrangThai, LabelWorkflowCoreStatus, LengthValidator, ListHelperService, LoaiPhieuDeXuat, LocalCacheService, LowerCorrector, MA_THONG_BAO_PHAN_HE, ManagerType, MaskControlSchema, MasterDataItem, MasterDataPipe, MasterDataService, MenuService, MethodResult, ModelSchema, ModuleConfigService, MultiTranslateHttpLoader, MultipleReferenceDataFormatPipe, NodeService, NotificationObjectType, NotificationService, NotifierService, NumberCompareValidator, NumberOnlyValidator, NumberRangeControlSchema, Operator, OrganizationFormatPipe, OrganizationNameFormatPipe, OrganizationPickerControlSchema, OrganizationService, OrganizationsFormatPipe, PageInfo, PageSetting, Pair, Pattern, PercentControlSchema, PermissionBase, PermissionConstant, PermissionService, PermissionStorage, PermissionTypes, PermissionUtilsComponent, PersonalSetting, PhoneNumberValidator, PhoneValidator, PopupSize, PositionService, PrintService, PublicFunction, QueryBuilderComponent, QueryBuilderGroupComponent, QueryBuilderRuleComponent, QueryGroup, QueryRule, RadioButtonListControlSchema, RandomDataService, RefField, ReferenceDataFormatPipe, RegexSplitFieldByItem, RequiredFieldsValidator, RequiredValidator, RowColorOption, RowExcel, SHARE_COMPONENT_ID, SHARE_EVENT, SafeHtmlPipe, SafeStylePipe, SafeUrlPipe, SameValueValidator, SchemaBase, SecurePipe, ServiceFileUploadComponent, SessionTypes, SharedFolderType, SignalRService, SimpleDicItem, SimpleDictionary, Sort, SortDirs, SpanControlSchema, SplashComponentComponent, StartupBusinessComponentBase, StateComponent, StateMachineTopic, StateMachinesConnectionMetadataComponent, StateMachinesDesignerComponent, StateMachinesService, StateMetadataComponent, Status, StatusAction, StatusGroup, StatusOption, StatusOrg, StatusUser, StorageService, StorageUpdatedService, StringFormatPipe, SummaryPipe, SwitchControlSchema, TBL_DM_COSODAOTAO_CONSTS, TBL_DM_PHONGHOC_CONSTS, TBL_KTX_NGUOITHUE_HOSO, TBL_TS_PHIEUDEXUAT, TBL_TS_TAISANCODINH_CONSTS, TableSchema, TagSeparator, TemplateConstant, TemplateControlSchema, TemplateInstanceService, TemplateService, TemplateTextItem, TemplateTextMany, TemplateTextV4Service, TemplateType, TemplateV4Service, TenContainer, TextAlign, TextAreaControlSchema, TextControlSchema, TextControlSchemaWithService, TitleSchema, TnClientCommand, TnClientService, TnComponentConfig, TnCustomScrollbarComponent, TnDatePipe, TnReorderableColumnDirective, TnReorderableRowDirective, TnSortIcon, TnSortableColumnDirective, TnUser, TnxSharedModule, TopicReloadCongViecV5, TopicReloadNotification, TrangThaiMasterData, TrangThais, TreeDataOption, TrimCorrector, TrimEndCorrector, TrimStartCorrector, TypeDanhMucAPI, UniqueFieldInTableValidator, UniqueNumberService, UpperCorrector, UserFormatPipe, UserGroupService, UserPickerControlSchema, UserPickerDialogComponent, UserService, UserV5Service, UsersFormatPipe, Validation, VanBanPickerControlSchema, VirtualBaseService, WorkflowConfigAdvance, WorkflowCoreStatusEnum, WorkflowFieldStateCode, WorkflowPermissionDetailService, WorkflowPickerComponent, WorkflowService, WorkflowSetting, WorkflowSettingNew, WrapPickerControlSchema, addDay, addZero, appendDefaultFilter, clearAll, clone, cloneOld, coreDeclaration, coreModuleImport, coreProvider, createJsPlumnInstance, createOrgPickerControl, createRolePickerControl, createUserGroupPickerControl, createUserPickerControl, dataSourceIcon$1 as dataSourceIcon, dateDiff, genQueryFromFilters, getDateFromStringDateVN, getDayOfWeek, getEnvironmentByName, getEnvironmentData, getListMenuByName, getMenuData, getMonday, getStringDate, getStringDateTime, getStringDateVN, getStringDateVNLocal, getTimeSpan, isArray, isBoolean, isDate, isFunction, isLiteralObject, isNumber, isObjectOld, isRegular, isSimpleType, isString, isValidDate, keyUserSurveyLocal, maximumPageSize, mergeJSON, mergeJSONOld, moduleConfigFunc, multipleSort, romanize, setMetadataConnection, translateStateMachine, ɵ0, ɵ1, ɵ10, ɵ2, ɵ3, ɵ4, ɵ5, ɵ6, ɵ7, ɵ8, ɵ9, AddressComponent as ɵa, DropdownService as ɵb, DynamicNodeComponent as ɵba, EntityPickerBoxComponent as ɵbb, EntityPickerDataComponent as ɵbc, EntityPickerSelectedComponent as ɵbd, EntityPickerComponent as ɵbe, EntityPickerDialogComponent as ɵbf, EntityPermissionComponent as ɵbg, DM_ChucVuService as ɵbh, RoleService as ɵbi, EntityPermissionService as ɵbj, EquationEditorComponent as ɵbk, MaskComponent as ɵbl, NumberPickerRangeComponent as ɵbm, PagingNextBackOnlyComponent as ɵbn, RadioButtonListComponent as ɵbo, VanBanPickerComponent as ɵbp, VanBanDenService as ɵbq, VanBanDiService as ɵbr, VanBanPickerDialogComponent as ɵbs, VanbanDiPickerComponent as ɵbt, VanbanDenPickerComponent as ɵbu, CongViecPickerComponent as ɵbv, CongViecService as ɵbw, TaskWorkflowHistoriesService as ɵbx, SettingsComponent as ɵby, SettingsRowComponent as ɵbz, EntityPickerService as ɵc, SettingsWorkflowComponent as ɵca, SettingsWorkflowNo1Component as ɵcb, SimpleWorkflowFormComponent as ɵcc, ProcessWorkflowFormComponent as ɵcd, WorkflowHistoryService as ɵce, ProcessWorkflowTargetComponent as ɵcf, ChoYKienFormComponent as ɵcg, SplashComponentV1Component as ɵch, StateMachinesConnectionReceiverComponent as ɵci, StateMachinesConnectionReceiverUserComponent as ɵcj, StateMachinesConnectionReceiverDepartmentComponent as ɵck, StateMachinesConnectionReceiverGroupComponent as ɵcl, StateMachinesConnectionReceiverRoleComponent as ɵcm, StateMachinesConnectionSenderComponent as ɵcn, StartWorkflowComponent as ɵco, WorkflowSettingsService as ɵcp, WorkflowSettingNewComponent as ɵcq, PermissionSharingComponent as ɵcr, WorkflowPermissionService as ɵcs, TnDialogComponent as ɵct, TnColorPickerComponent as ɵcu, TnTinymceComponent as ɵcv, TnTabViewComponent as ɵcw, TableDetailFormComponent as ɵcx, FileIconPipe as ɵcy, FileSizePipe as ɵcz, ExceptionHandlerService as ɵd, QuickAddFormComponent as ɵda, PreventShiftTabDirective as ɵdb, TnTemplateDirective as ɵdc, UserPickerComponent as ɵdd, UserPickerBoxComponent as ɵde, TnAppHelpComponent as ɵdf, PathNameService as ɵdg, HelperCurrentPageComponent as ɵdh, TnAppNotificationListComponent as ɵdi, TnAppNotificationComponent as ɵdj, MyDriveService as ɵdk, FileVersionService as ɵdl, FileExplorerNewService as ɵdm, FolderFormComponent as ɵdn, FileFormComponent as ɵdo, FileViewerComponent as ɵdp, FileVersionListComponent as ɵdq, WorkflowHistoryComponent as ɵdr, EntityWorkflowHistoryService as ɵds, WorkflowHistoryDialogComponent as ɵdt, WorkflowHistoryNewComponent as ɵdu, WorkflowSettingComponent as ɵdv, EntityWorkflowSettingService as ɵdw, WorkflowSettingDialogComponent as ɵdx, QrCodeGeneratorComponent as ɵdy, AccessDeniedV1Component as ɵdz, CanBo_HoSoService as ɵe, AddNewsComponent as ɵea, ArticleService as ɵeb, NewsCategoryService as ɵec, NotFoundComponent as ɵed, UniversalLinkProcessorComponent as ɵee, ChatService as ɵef, ContentsService as ɵeg, StatusExtendsService as ɵeh, MessageBoardService as ɵei, CheckReadyComponent as ɵej, SendAccessTokenInterceptor as ɵek, LogInterceptor as ɵel, PermissionUtilsInterceptor as ɵem, AfterViewCheckedComponent as ɵf, AdvanceSearchComponent as ɵg, AppRootMenuComponent as ɵh, AppTopBarComponent as ɵi, AppTopBarV1Component as ɵj, AppProfileComponent as ɵk, AppSubMenuComponent as ɵl, AppMenuComponent as ɵm, AutoCompletePickerComponent as ɵn, CheckBoxListComponent as ɵo, ReportQueueComponent as ɵp, CoCauToChucPickerListComponent as ɵq, BaseCongViecTestComponent as ɵr, BaseCauHinhWorkflowDetailComponent as ɵs, BaseDmLoaiCongViecFormComponent as ɵt, BaseDmPriorityFormComponent as ɵu, BaseCongviecDinhkemComponent as ɵv, CongviecDinhkemService as ɵw, BaseCongviecDinhkemFormComponent as ɵx, DatetimePickerComponent as ɵy, DatetimePickerRangeComponent as ɵz };
|
|
43742
45245
|
//# sourceMappingURL=tnx-shared.js.map
|