ngx-techlify-core 11.4.6 → 11.4.8-beta.2
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/ngx-techlify-core.umd.js +3096 -2889
- package/bundles/ngx-techlify-core.umd.js.map +1 -1
- package/bundles/ngx-techlify-core.umd.min.js +1 -16
- package/bundles/ngx-techlify-core.umd.min.js.map +1 -1
- package/esm2015/lib/base-model/index.js +4 -0
- package/esm2015/lib/base-model/techlify-form-component.class.js +51 -0
- package/esm2015/lib/base-model/techlify-listing-component.class.js +41 -0
- package/esm2015/lib/base-model/techlify-service.class.js +64 -0
- package/esm2015/lib/entity-files/entity-file-form/entity-file-form.component.js +12 -3
- package/esm2015/lib/entity-files/entity-files-view-all.component.js +47 -21
- package/esm2015/lib/entity-files/entity-files-view-all.module.js +6 -2
- package/esm2015/ngx-techlify-core.js +10 -10
- package/esm2015/public-api.js +2 -1
- package/fesm2015/ngx-techlify-core.js +614 -421
- package/fesm2015/ngx-techlify-core.js.map +1 -1
- package/lib/base-model/index.d.ts +3 -0
- package/lib/base-model/techlify-form-component.class.d.ts +43 -0
- package/lib/base-model/techlify-listing-component.class.d.ts +47 -0
- package/lib/base-model/techlify-service.class.d.ts +52 -0
- package/lib/entity-files/entity-file-form/entity-file-form.component.d.ts +4 -0
- package/lib/entity-files/entity-files-view-all.component.d.ts +11 -4
- package/ngx-techlify-core.d.ts +9 -9
- package/ngx-techlify-core.metadata.json +1 -1
- package/package.json +2 -2
- package/public-api.d.ts +1 -0
|
@@ -5,7 +5,7 @@ import { MatTableDataSource, MatTableModule } from '@angular/material/table';
|
|
|
5
5
|
import { MatSort, MatSortModule } from '@angular/material/sort';
|
|
6
6
|
import { untilDestroyed, UntilDestroy } from '@ngneat/until-destroy';
|
|
7
7
|
import { Location, DatePipe, CommonModule } from '@angular/common';
|
|
8
|
-
import { Validators, FormBuilder, FormControl,
|
|
8
|
+
import { Validators, FormBuilder, NgControl, FormControl, ReactiveFormsModule, FormsModule } from '@angular/forms';
|
|
9
9
|
import { HttpResponse, HttpClient, HttpHandler, HttpClientModule } from '@angular/common/http';
|
|
10
10
|
import { throwError, Observable, Subject, of, from, fromEvent } from 'rxjs';
|
|
11
11
|
import { catchError, debounceTime, distinctUntilChanged, startWith, switchMap, finalize, takeUntil, tap, concatMap, filter } from 'rxjs/operators';
|
|
@@ -33,12 +33,12 @@ import { MatButtonToggleModule } from '@angular/material/button-toggle';
|
|
|
33
33
|
import { FlexLayoutModule } from '@angular/flex-layout';
|
|
34
34
|
import { InfiniteScrollModule } from 'ngx-infinite-scroll';
|
|
35
35
|
import { NgxDocViewerModule } from 'ngx-doc-viewer';
|
|
36
|
+
import { ENTER, COMMA } from '@angular/cdk/keycodes';
|
|
37
|
+
import { MatAutocompleteModule } from '@angular/material/autocomplete';
|
|
36
38
|
import { Editor, NgxEditorModule } from 'ngx-editor';
|
|
37
39
|
import { utils, writeFile, read } from 'xlsx';
|
|
38
40
|
import { DomSanitizer } from '@angular/platform-browser';
|
|
39
41
|
import { diff, formatters } from 'jsondiffpatch';
|
|
40
|
-
import { ENTER, COMMA } from '@angular/cdk/keycodes';
|
|
41
|
-
import { MatAutocompleteModule } from '@angular/material/autocomplete';
|
|
42
42
|
import { MatSlideToggleModule } from '@angular/material/slide-toggle';
|
|
43
43
|
|
|
44
44
|
class ActionPopup {
|
|
@@ -73,6 +73,162 @@ ActionPopupComponent.ctorParameters = () => [
|
|
|
73
73
|
{ type: ActionPopup, decorators: [{ type: Inject, args: [MAT_DIALOG_DATA,] }] }
|
|
74
74
|
];
|
|
75
75
|
|
|
76
|
+
/**
|
|
77
|
+
* Interface used to ensure we have a consistent structure across our form components
|
|
78
|
+
*
|
|
79
|
+
* It also provides some abstraction of repeated code to reduce our codebase size
|
|
80
|
+
*
|
|
81
|
+
* @todo This should be moved to ngx-techlify-core
|
|
82
|
+
*
|
|
83
|
+
* Advantages of this abstract class
|
|
84
|
+
* - Less code, less maintenance, less bugs
|
|
85
|
+
* - more consistent code
|
|
86
|
+
* - comments on more code
|
|
87
|
+
* - save time, save energy
|
|
88
|
+
*/
|
|
89
|
+
class TechlifyFormComponentInterface {
|
|
90
|
+
constructor(formValidatorService) {
|
|
91
|
+
this.formValidatorService = formValidatorService;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Resets the value of a field in the HTML form
|
|
95
|
+
*
|
|
96
|
+
* @param event
|
|
97
|
+
* @param field
|
|
98
|
+
*/
|
|
99
|
+
resetFieldValue(event, field) {
|
|
100
|
+
var _a, _b;
|
|
101
|
+
(_b = (_a = this.form) === null || _a === void 0 ? void 0 : _a.get(field)) === null || _b === void 0 ? void 0 : _b.setValue('');
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Retrieves the value of a field from the HTML form
|
|
105
|
+
*
|
|
106
|
+
* @param field
|
|
107
|
+
* @returns
|
|
108
|
+
*/
|
|
109
|
+
getFieldValue(field) {
|
|
110
|
+
var _a, _b;
|
|
111
|
+
return (_b = (_a = this.form) === null || _a === void 0 ? void 0 : _a.get(field)) === null || _b === void 0 ? void 0 : _b.value;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Method to evaluate form fields
|
|
115
|
+
* */
|
|
116
|
+
isFieldValid(field) {
|
|
117
|
+
return this.formValidatorService.isFieldValid(field, this.form, true);
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Method to find error in form fields
|
|
121
|
+
* */
|
|
122
|
+
getErrorMessage(field) {
|
|
123
|
+
return this.formValidatorService.getErrorMessage(field, this.form, this.errorMessages);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Interface used to ensure we have a consistent structure across our listing pages
|
|
129
|
+
*
|
|
130
|
+
* @todo This should be moved to ngx-techlify-core
|
|
131
|
+
*
|
|
132
|
+
* Advantages of this abstract class
|
|
133
|
+
* - Less code, less maintenance, less bugs
|
|
134
|
+
* - more consistent code
|
|
135
|
+
* - comments on more code
|
|
136
|
+
* - save time, save energy
|
|
137
|
+
*/
|
|
138
|
+
class TechlifyListingControllerInterface {
|
|
139
|
+
constructor() {
|
|
140
|
+
this.models = [];
|
|
141
|
+
this.page = 1;
|
|
142
|
+
this.perPage = 25;
|
|
143
|
+
this.lastPage = 500;
|
|
144
|
+
this.isWorking = false;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Reload all data from page 1
|
|
148
|
+
*/
|
|
149
|
+
reload() {
|
|
150
|
+
this.models = [];
|
|
151
|
+
this.page = 1;
|
|
152
|
+
if (!this.isWorking) {
|
|
153
|
+
this.loadData();
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Can be called when the user is scrolling,
|
|
158
|
+
* to trigger loading a new page of data
|
|
159
|
+
*/
|
|
160
|
+
onScroll() {
|
|
161
|
+
if (!this.isWorking && this.page < this.lastPage) {
|
|
162
|
+
this.page += 1;
|
|
163
|
+
this.loadData();
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Interface used to ensure we have a consistent structure across our listing pages
|
|
170
|
+
*
|
|
171
|
+
* @todo This should be moved to ngx-techlify-core
|
|
172
|
+
*
|
|
173
|
+
* Advantages of this abstract class
|
|
174
|
+
* - Less code, less maintenance, less bugs
|
|
175
|
+
* - more consistent code
|
|
176
|
+
* - comments on more code
|
|
177
|
+
* - save time, save energy
|
|
178
|
+
*/
|
|
179
|
+
class TechlifyServiceBaseClass {
|
|
180
|
+
constructor(http, baseUrl) {
|
|
181
|
+
this.http = http;
|
|
182
|
+
this.baseUrl = "you-forgot-to-set-a-base-url";
|
|
183
|
+
this.baseUrl = baseUrl;
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Loads a set of the model this service is for
|
|
187
|
+
*
|
|
188
|
+
* @param filters Restrictors to filter the set of models
|
|
189
|
+
* @returns
|
|
190
|
+
*/
|
|
191
|
+
index(filters) {
|
|
192
|
+
return this.http.get(`api/${this.baseUrl}`, { params: Object.assign({}, filters) }).toPromise();
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Add a new record to the database
|
|
196
|
+
*
|
|
197
|
+
* @param model The data of the model to add
|
|
198
|
+
* @returns
|
|
199
|
+
*/
|
|
200
|
+
store(model) {
|
|
201
|
+
return this.http.post(`api/${this.baseUrl}`, model).toPromise();
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Load a single model record, often with all relations and related data
|
|
205
|
+
*
|
|
206
|
+
* @param modelId ID of the model to load
|
|
207
|
+
* @returns
|
|
208
|
+
*/
|
|
209
|
+
show(modelId) {
|
|
210
|
+
return this.http.get(`api/${this.baseUrl}/${modelId}`).toPromise();
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Update fields of a single existing model
|
|
214
|
+
*
|
|
215
|
+
* @param model Model to update
|
|
216
|
+
* @returns
|
|
217
|
+
*/
|
|
218
|
+
update(model) {
|
|
219
|
+
return this.http.put(`api/${this.baseUrl}/${model.id}`, model).toPromise();
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Delete a single model
|
|
223
|
+
*
|
|
224
|
+
* @param model Model to delete
|
|
225
|
+
* @returns
|
|
226
|
+
*/
|
|
227
|
+
delete(model) {
|
|
228
|
+
return this.http.delete(`api/${this.baseUrl}/${model.id}`).toPromise();
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
76
232
|
var DataTableComponent_1;
|
|
77
233
|
let DataTableComponent = DataTableComponent_1 = class DataTableComponent {
|
|
78
234
|
constructor() {
|
|
@@ -1118,6 +1274,10 @@ class EntityFileFormComponent {
|
|
|
1118
1274
|
this.entityFileService = entityFileService;
|
|
1119
1275
|
this.alertService = alertService;
|
|
1120
1276
|
this.fileList = [];
|
|
1277
|
+
/**
|
|
1278
|
+
* Should we allow tagging entity-files?
|
|
1279
|
+
*/
|
|
1280
|
+
this.useTechlifyTags = false;
|
|
1121
1281
|
this.createForm();
|
|
1122
1282
|
}
|
|
1123
1283
|
/** Method to create a form **/
|
|
@@ -1132,10 +1292,11 @@ class EntityFileFormComponent {
|
|
|
1132
1292
|
file: ['', Validators.required],
|
|
1133
1293
|
url: ['', Validators.required],
|
|
1134
1294
|
file_size: ['', Validators.required],
|
|
1295
|
+
tag_ids: [[]]
|
|
1135
1296
|
});
|
|
1136
1297
|
}
|
|
1137
1298
|
ngOnInit() {
|
|
1138
|
-
var _a, _b;
|
|
1299
|
+
var _a, _b, _c, _d;
|
|
1139
1300
|
if (this.data.entity) {
|
|
1140
1301
|
this.entityFileGroup.get('entity_type').setValue(this.data.entity.entity_type);
|
|
1141
1302
|
this.entityFileGroup.get('entity_id').setValue(this.data.entity.entity_id);
|
|
@@ -1147,6 +1308,9 @@ class EntityFileFormComponent {
|
|
|
1147
1308
|
if ((_a = this.data) === null || _a === void 0 ? void 0 : _a.hideTitleAndDetails) {
|
|
1148
1309
|
this.hideTitleAndDetails = (_b = this.data) === null || _b === void 0 ? void 0 : _b.hideTitleAndDetails;
|
|
1149
1310
|
}
|
|
1311
|
+
if ((_c = this.data) === null || _c === void 0 ? void 0 : _c.useTechlifyTags) {
|
|
1312
|
+
this.useTechlifyTags = (_d = this.data) === null || _d === void 0 ? void 0 : _d.useTechlifyTags;
|
|
1313
|
+
}
|
|
1150
1314
|
//File dropper config
|
|
1151
1315
|
this.fileConfig = {
|
|
1152
1316
|
fileId: "subjectFile",
|
|
@@ -1177,6 +1341,7 @@ class EntityFileFormComponent {
|
|
|
1177
1341
|
if (this.hideTitleAndDetails) {
|
|
1178
1342
|
model.title = model.file;
|
|
1179
1343
|
}
|
|
1344
|
+
model.tag_ids = model.tag_ids.toString();
|
|
1180
1345
|
const result = this.updateMode
|
|
1181
1346
|
? yield this.entityFileService.updateEntityFile(model)
|
|
1182
1347
|
: yield this.entityFileService.createEntityFile(model);
|
|
@@ -1222,7 +1387,7 @@ class EntityFileFormComponent {
|
|
|
1222
1387
|
EntityFileFormComponent.decorators = [
|
|
1223
1388
|
{ type: Component, args: [{
|
|
1224
1389
|
selector: 'entity-file-form',
|
|
1225
|
-
template: "<form [formGroup]=\"entityFileGroup\" (ngSubmit)=\"submit()\">\n <div fxLayout=\"column\" class=\"mat-typography\">\n <div mat-dialog-title class=\"text-center\">\n <div>Entity File</div>\n </div>\n <div mat-dialog-content fxLayout=\"column\" fxLayoutAlign.=\"start\">\n <ng-container *ngIf=\"!hideTitleAndDetails\">\n <mat-form-field>\n <input type=\"text\" matInput formControlName=\"title\" placeholder=\"Title\" autocomplete=\"off\">\n </mat-form-field>\n <mat-form-field>\n <textarea matInput formControlName=\"details\" placeholder=\"Details\" autocomplete=\"off\"></textarea>\n </mat-form-field>\n </ng-container>\n <ng-template #fileUpload>\n <section fxFlex=\"100%\">\n <div>Entity File*</div>\n <app-file-dropper [config]=\"fileConfig\" (fileChanged)=\"fileChanged($event)\" [fileArray]=\"fileList\">\n </app-file-dropper>\n <div class=\"text-danger\" *ngIf=\"isFieldValid('url')\">\n {{getErrorMessage(\"url\")}}\n </div>\n </section>\n </ng-template>\n <div fxFlex=\"100%\" class=\"mt-2\" *ngIf=\"entityFileGroup.get('url').value;else fileUpload;\">\n <app-document-viewer [file]=\"entityFileGroup.get('file').value\" [fileUrl]=\"entityFileGroup.get('url').value\"\n [config]=\"this.viewerConfig\" (remove)=\"removeFile()\" [disableEdit]=\"updateMode\">\n </app-document-viewer>\n </div>\n <div class=\"mt-4 mb-2\" fxLayout=\"row\" fxLayoutGap=\"30px\" fxLayoutAlign=\"end\" fxFlex=\"100%\">\n <button mat-raised-button type=\"button\" (click)=\"dialogRef.close()\">\n Cancel\n </button>\n <button mat-raised-button type=\"submit\" color=\"primary\">Save</button>\n </div>\n </div>\n </div>\n</form>\n",
|
|
1390
|
+
template: "<form [formGroup]=\"entityFileGroup\" (ngSubmit)=\"submit()\">\n <div fxLayout=\"column\" class=\"mat-typography\">\n <div mat-dialog-title class=\"text-center\">\n <div>Entity File</div>\n </div>\n <div mat-dialog-content fxLayout=\"column\" fxLayoutAlign.=\"start\">\n <ng-container *ngIf=\"!hideTitleAndDetails\">\n <mat-form-field>\n <input type=\"text\" matInput formControlName=\"title\" placeholder=\"Title\" autocomplete=\"off\">\n </mat-form-field>\n <mat-form-field>\n <textarea matInput formControlName=\"details\" placeholder=\"Details\" autocomplete=\"off\"></textarea>\n </mat-form-field>\n </ng-container>\n <ng-container *ngIf=\"useTechlifyTags\">\n <mat-form-field>\n <mat-label>Tag</mat-label>\n <app-techlify-tagger-tag-form-field modelType=\"entity-file\" formControlName=\"tag_ids\"\n [modelId]=\"entityFileGroup.get('id').value\"></app-techlify-tagger-tag-form-field>\n </mat-form-field>\n </ng-container>\n <ng-template #fileUpload>\n <section fxFlex=\"100%\">\n <div>Entity File*</div>\n <app-file-dropper [config]=\"fileConfig\" (fileChanged)=\"fileChanged($event)\" [fileArray]=\"fileList\">\n </app-file-dropper>\n <div class=\"text-danger\" *ngIf=\"isFieldValid('url')\">\n {{getErrorMessage(\"url\")}}\n </div>\n </section>\n </ng-template>\n <div fxFlex=\"100%\" class=\"mt-2\" *ngIf=\"entityFileGroup.get('url').value;else fileUpload;\">\n <app-document-viewer [file]=\"entityFileGroup.get('file').value\" [fileUrl]=\"entityFileGroup.get('url').value\"\n [config]=\"this.viewerConfig\" (remove)=\"removeFile()\" [disableEdit]=\"updateMode\">\n </app-document-viewer>\n </div>\n <div class=\"mt-4 mb-2\" fxLayout=\"row\" fxLayoutGap=\"30px\" fxLayoutAlign=\"end\" fxFlex=\"100%\">\n <button mat-raised-button type=\"button\" (click)=\"dialogRef.close()\">\n Cancel\n </button>\n <button mat-raised-button type=\"submit\" color=\"primary\">Save</button>\n </div>\n </div>\n </div>\n</form>\n",
|
|
1226
1391
|
styles: [""]
|
|
1227
1392
|
},] }
|
|
1228
1393
|
];
|
|
@@ -1236,12 +1401,18 @@ EntityFileFormComponent.ctorParameters = () => [
|
|
|
1236
1401
|
];
|
|
1237
1402
|
|
|
1238
1403
|
let EntityFilesViewAllComponent = class EntityFilesViewAllComponent {
|
|
1239
|
-
constructor(entityFileService, location, alertService, dialog) {
|
|
1404
|
+
constructor(entityFileService, location, alertService, dialog, fb) {
|
|
1240
1405
|
this.entityFileService = entityFileService;
|
|
1241
1406
|
this.location = location;
|
|
1242
1407
|
this.alertService = alertService;
|
|
1243
1408
|
this.dialog = dialog;
|
|
1409
|
+
this.fb = fb;
|
|
1244
1410
|
this.viewOnly = false;
|
|
1411
|
+
this.allowMultipleFiles = false;
|
|
1412
|
+
/**
|
|
1413
|
+
* Should we allow tagging entity-files?
|
|
1414
|
+
*/
|
|
1415
|
+
this.useTechlifyTags = false;
|
|
1245
1416
|
this.title = "File";
|
|
1246
1417
|
this.filters = {};
|
|
1247
1418
|
this.entityFiles = [];
|
|
@@ -1253,11 +1424,14 @@ let EntityFilesViewAllComponent = class EntityFilesViewAllComponent {
|
|
|
1253
1424
|
'uploaded_on',
|
|
1254
1425
|
];
|
|
1255
1426
|
this.isWorking = false;
|
|
1256
|
-
this.search = new FormControl('');
|
|
1257
1427
|
this.page = 1;
|
|
1258
1428
|
this.perPage = 25;
|
|
1259
1429
|
this.lastPage = 0;
|
|
1260
1430
|
this.fileList = [];
|
|
1431
|
+
this.filterFormGroup = this.fb.group({
|
|
1432
|
+
title: [""],
|
|
1433
|
+
tag_ids: [""]
|
|
1434
|
+
});
|
|
1261
1435
|
}
|
|
1262
1436
|
ngOnInit() {
|
|
1263
1437
|
//File dropper config
|
|
@@ -1267,7 +1441,7 @@ let EntityFilesViewAllComponent = class EntityFilesViewAllComponent {
|
|
|
1267
1441
|
styles: {
|
|
1268
1442
|
height: "500px"
|
|
1269
1443
|
},
|
|
1270
|
-
multiple:
|
|
1444
|
+
multiple: this.allowMultipleFiles,
|
|
1271
1445
|
acceptFile: "*",
|
|
1272
1446
|
maxSize: 10,
|
|
1273
1447
|
acceptFileText: "All Files"
|
|
@@ -1286,24 +1460,33 @@ let EntityFilesViewAllComponent = class EntityFilesViewAllComponent {
|
|
|
1286
1460
|
if (this.hideTitleAndDetails) {
|
|
1287
1461
|
this.displayedColumns = this.displayedColumns.filter(x => (x !== 'details') && (x !== 'title'));
|
|
1288
1462
|
}
|
|
1463
|
+
this.listenRoutes();
|
|
1289
1464
|
this.filters = {
|
|
1290
1465
|
entity_type: this.entityType,
|
|
1291
1466
|
entity_id: this.entityId,
|
|
1292
1467
|
title: ""
|
|
1293
1468
|
};
|
|
1294
|
-
this.search.valueChanges.pipe(debounceTime(500), distinctUntilChanged(), untilDestroyed(this)).subscribe(value => {
|
|
1295
|
-
this.filters.title = value;
|
|
1296
|
-
this.reload();
|
|
1297
|
-
});
|
|
1298
1469
|
this.fetchEntityFilesDetails();
|
|
1470
|
+
if (this.useTechlifyTags) {
|
|
1471
|
+
this.displayedColumns.push('tag');
|
|
1472
|
+
}
|
|
1299
1473
|
if (!this.viewOnly) {
|
|
1300
1474
|
this.displayedColumns.push('actions');
|
|
1301
1475
|
}
|
|
1302
1476
|
}
|
|
1477
|
+
listenRoutes() {
|
|
1478
|
+
this.filterFormGroup.valueChanges.pipe(debounceTime(500), untilDestroyed(this))
|
|
1479
|
+
.subscribe(changes => {
|
|
1480
|
+
this.reload();
|
|
1481
|
+
});
|
|
1482
|
+
}
|
|
1303
1483
|
fetchEntityFilesDetails() {
|
|
1304
1484
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1305
1485
|
this.filters.page = this.page;
|
|
1306
1486
|
this.filters.perPage = this.perPage;
|
|
1487
|
+
let formGroup = this.filterFormGroup.value;
|
|
1488
|
+
formGroup.tag_ids = formGroup.tag_ids.toString();
|
|
1489
|
+
this.filters = Object.assign(Object.assign({}, this.filters), formGroup);
|
|
1307
1490
|
this.isWorking = true;
|
|
1308
1491
|
const result = yield this.entityFileService.getEntityFiles(this.filters);
|
|
1309
1492
|
this.lastPage = result.last_page || this.page;
|
|
@@ -1316,7 +1499,8 @@ let EntityFilesViewAllComponent = class EntityFilesViewAllComponent {
|
|
|
1316
1499
|
width: "700px",
|
|
1317
1500
|
data: {
|
|
1318
1501
|
entity: this.filters,
|
|
1319
|
-
hideTitleAndDetails: this.hideTitleAndDetails
|
|
1502
|
+
hideTitleAndDetails: this.hideTitleAndDetails,
|
|
1503
|
+
useTechlifyTags: this.useTechlifyTags,
|
|
1320
1504
|
},
|
|
1321
1505
|
autoFocus: false,
|
|
1322
1506
|
restoreFocus: false
|
|
@@ -1335,7 +1519,8 @@ let EntityFilesViewAllComponent = class EntityFilesViewAllComponent {
|
|
|
1335
1519
|
autoFocus: false,
|
|
1336
1520
|
data: {
|
|
1337
1521
|
file: file,
|
|
1338
|
-
hideTitleAndDetails: this.hideTitleAndDetails
|
|
1522
|
+
hideTitleAndDetails: this.hideTitleAndDetails,
|
|
1523
|
+
useTechlifyTags: this.useTechlifyTags,
|
|
1339
1524
|
} // Any data passed here will be injected into the model
|
|
1340
1525
|
});
|
|
1341
1526
|
dialogRef.afterClosed().subscribe(result => {
|
|
@@ -1376,8 +1561,9 @@ let EntityFilesViewAllComponent = class EntityFilesViewAllComponent {
|
|
|
1376
1561
|
}
|
|
1377
1562
|
}
|
|
1378
1563
|
ngOnDestroy() { }
|
|
1379
|
-
resetFieldValue() {
|
|
1380
|
-
|
|
1564
|
+
resetFieldValue(event, field) {
|
|
1565
|
+
event.stopPropagation();
|
|
1566
|
+
this.filterFormGroup.get(field).setValue("");
|
|
1381
1567
|
}
|
|
1382
1568
|
sizeOf(bytes) {
|
|
1383
1569
|
if (!bytes) {
|
|
@@ -1390,13 +1576,15 @@ let EntityFilesViewAllComponent = class EntityFilesViewAllComponent {
|
|
|
1390
1576
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1391
1577
|
this.fileList = event;
|
|
1392
1578
|
if (this.fileList.length > 0) {
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1579
|
+
yield this.fileList.forEach((file) => __awaiter(this, void 0, void 0, function* () {
|
|
1580
|
+
const result = yield this.entityFileService.uploadEntityFile(file, {
|
|
1581
|
+
entity_type: this.entityType,
|
|
1582
|
+
entity_id: this.entityId,
|
|
1583
|
+
});
|
|
1584
|
+
this.reload();
|
|
1585
|
+
}));
|
|
1397
1586
|
this.fileList = [];
|
|
1398
1587
|
this.alertService.addAlert('Successfull uploaded', 'success');
|
|
1399
|
-
this.reload();
|
|
1400
1588
|
}
|
|
1401
1589
|
});
|
|
1402
1590
|
}
|
|
@@ -1404,7 +1592,7 @@ let EntityFilesViewAllComponent = class EntityFilesViewAllComponent {
|
|
|
1404
1592
|
EntityFilesViewAllComponent.decorators = [
|
|
1405
1593
|
{ type: Component, args: [{
|
|
1406
1594
|
selector: 'app-entity-files-view-all',
|
|
1407
|
-
template: "<div class=\"mat-typography\" *ngIf=\"!displayMode\">\n <div fxLayout=\"row\" fxLayoutGap=\"1rem\">\n <mat-card fxFlex=\"70%\">\n <mat-card-title fxLayout fxLayoutGap=\"1rem\">\n <h3 class=\"font-weight-bold primary-color\" fxLayout=\"center center\">\n <mat-icon>\n <span class=\"material-icons\">\n description\n </span>\n </mat-icon>\n {{title}}s\n </h3>\n <div>\n <button type=\"button\" class=\"mx-1\" mat-raised-button color=\"primary\" (click)=\"addEntityFile()\"\n *ngIf=\"!viewOnly\">\n <mat-icon>\n <span class=\"material-icons\">\n add_circle_outline\n </span>\n </mat-icon>\n {{title}}\n </button>\n </div>\n <mat-form-field *ngIf=\"!removeSearch\" appearance=\"outline\"
|
|
1595
|
+
template: "<div class=\"mat-typography\" *ngIf=\"!displayMode\">\n <div fxLayout=\"row\" fxLayoutGap=\"1rem\">\n <mat-card fxFlex=\"70%\">\n <mat-card-title fxLayout fxLayoutGap=\"1rem\">\n <h3 class=\"font-weight-bold primary-color\" fxLayout=\"center center\">\n <mat-icon>\n <span class=\"material-icons\">\n description\n </span>\n </mat-icon>\n {{title}}s\n </h3>\n <div>\n <button type=\"button\" class=\"mx-1\" mat-raised-button color=\"primary\" (click)=\"addEntityFile()\"\n *ngIf=\"!viewOnly\">\n <mat-icon>\n <span class=\"material-icons\">\n add_circle_outline\n </span>\n </mat-icon>\n {{title}}\n </button>\n </div>\n <form [formGroup]=\"filterFormGroup\" style=\"font-size: 10px;\" fxLayout fxLayoutGap=\"1rem\">\n <mat-form-field *ngIf=\"!removeSearch\" appearance=\"outline\">\n <mat-label>Search</mat-label>\n <input type=\"text\" matInput formControlName=\"title\" placeholder=\"Search\" name=\"title\" autocomplete=\"off\" />\n <button mat-button *ngIf=\"filters.title\" matSuffix mat-icon-button\n (click)=\"resetFieldValue($event, 'title')\">\n <mat-icon>close</mat-icon>\n </button>\n </mat-form-field>\n <mat-form-field appearance=\"outline\" *ngIf=\"useTechlifyTags\">\n <mat-label>Tag</mat-label>\n <app-searchable-selector formControlName=\"tag_ids\" apiUrl=\"api/techlify-tagger-tags\" [multiple]=\"true\"\n placeHolder=\"Tag\">\n </app-searchable-selector>\n <button mat-icon-button matSuffix *ngIf=\"filterFormGroup.get('tag_ids').value.length\"\n (click)=\"resetFieldValue($event, 'tag_ids')\">\n <mat-icon>close</mat-icon>\n </button>\n </mat-form-field>\n </form>\n </mat-card-title>\n <mat-card-content class=\"entity-file-card\">\n <table mat-table [dataSource]=\"entityFiles\" class=\"w-100\" matSort multiTemplateDataRows infiniteScroll\n [infiniteScrollDistance]=\"1.5\" [infiniteScrollThrottle]=\"50\" (scrolled)=\"onScroll()\">\n\n <!-- Index Column -->\n <ng-container matColumnDef=\"index\">\n <th mat-header-cell *matHeaderCellDef> # </th>\n <td mat-cell *matCellDef=\"let element; let i = dataIndex\"> {{ i+1 }} </td>\n </ng-container>\n\n <!-- Title Column -->\n <ng-container matColumnDef=\"title\">\n <th mat-header-cell *matHeaderCellDef> Title </th>\n <td mat-cell *matCellDef=\"let element\">\n <div>\n <span>\n {{element.title}}\n </span>\n <span>\n <a href=\"{{element.url}}\" target=\"_blank\" class=\"text-decoration-none text-muted\">\n <button mat-icon-button type=\"button\">\n <mat-icon>download</mat-icon>\n </button>\n </a>\n </span>\n </div>\n </td>\n </ng-container>\n\n <!-- Details Column -->\n <ng-container matColumnDef=\"details\">\n <th mat-header-cell *matHeaderCellDef> Details </th>\n <td mat-cell *matCellDef=\"let element\"> {{element.details}} </td>\n </ng-container>\n\n <!-- File size Column -->\n <ng-container matColumnDef=\"file_size\">\n <th mat-header-cell *matHeaderCellDef> File Size </th>\n <td mat-cell *matCellDef=\"let element\"> {{ sizeOf(element.file_size)}} </td>\n </ng-container>\n\n <!-- Tags Column -->\n <ng-container matColumnDef=\"tag\">\n <th mat-header-cell *matHeaderCellDef> Tag </th>\n <td mat-cell *matCellDef=\"let element\" class=\"text-muted\">\n <ng-container *ngFor=\"let taggerModel of element.tags\">\n {{taggerModel?.tag?.title}},\n </ng-container>\n </td>\n </ng-container>\n\n <!-- Uploaded On Column -->\n <ng-container matColumnDef=\"uploaded_on\">\n <th mat-header-cell *matHeaderCellDef> Uploaded On </th>\n <td mat-cell *matCellDef=\"let element\">\n <div>\n {{element.created_at | date: 'mediumDate'}}\n </div>\n <div class=\"text-muted\">\n By {{element.creator?.name}}\n </div>\n </td>\n </ng-container>\n\n <!-- Actions Column -->\n <ng-container matColumnDef=\"actions\">\n <th mat-header-cell *matHeaderCellDef> Actions </th>\n <td mat-cell *matCellDef=\"let element\" style=\"min-width:110px\" class=\"text-muted\">\n <button type=\"button\" mat-icon-button (click)=\"editEntityFile(element)\">\n <mat-icon>edit</mat-icon>\n </button>\n <button type=\"button\" mat-icon-button (click)=\"deleteEntityFile(element)\">\n <mat-icon>delete</mat-icon>\n </button>\n </td>\n </ng-container>\n\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: displayedColumns;\"></tr>\n </table>\n </mat-card-content>\n </mat-card>\n <section fxFlex=\"30%\">\n <app-file-dropper [config]=\"fileConfig\" (fileChanged)=\"fileChanged($event)\" [fileArray]=\"fileList\">\n </app-file-dropper>\n </section>\n </div>\n</div>\n\n<div fxLayout=\"row wrap\" fxLayoutGap=\"1rem\" class=\"mat-typography p-4\" *ngIf=\"displayMode\">\n <div *ngFor=\"let efile of entityFiles\">\n <app-document-viewer [file]=\"efile.file\" [fileUrl]=\"efile.url\" [config]=\"this.viewerConfig\" [disableEdit]=\"true\">\n </app-document-viewer>\n <a href=\"{{efile.url}}\" target=\"_blank\">\n <button mat-button type=\"button\">View</button>\n </a>\n </div>\n</div>\n",
|
|
1408
1596
|
styles: [""]
|
|
1409
1597
|
},] }
|
|
1410
1598
|
];
|
|
@@ -1412,7 +1600,8 @@ EntityFilesViewAllComponent.ctorParameters = () => [
|
|
|
1412
1600
|
{ type: EntityFileService },
|
|
1413
1601
|
{ type: Location },
|
|
1414
1602
|
{ type: AlertService },
|
|
1415
|
-
{ type: MatDialog }
|
|
1603
|
+
{ type: MatDialog },
|
|
1604
|
+
{ type: FormBuilder }
|
|
1416
1605
|
];
|
|
1417
1606
|
EntityFilesViewAllComponent.propDecorators = {
|
|
1418
1607
|
entityId: [{ type: Input }],
|
|
@@ -1421,6 +1610,8 @@ EntityFilesViewAllComponent.propDecorators = {
|
|
|
1421
1610
|
removeSearch: [{ type: Input }],
|
|
1422
1611
|
hideTitleAndDetails: [{ type: Input }],
|
|
1423
1612
|
displayMode: [{ type: Input }],
|
|
1613
|
+
allowMultipleFiles: [{ type: Input }],
|
|
1614
|
+
useTechlifyTags: [{ type: Input }],
|
|
1424
1615
|
title: [{ type: Input }]
|
|
1425
1616
|
};
|
|
1426
1617
|
EntityFilesViewAllComponent = __decorate([
|
|
@@ -3118,109 +3309,292 @@ FileDropperModule.decorators = [
|
|
|
3118
3309
|
},] }
|
|
3119
3310
|
];
|
|
3120
3311
|
|
|
3121
|
-
class
|
|
3312
|
+
class TechlifyTaggerTagFormConfigModel {
|
|
3313
|
+
constructor() {
|
|
3314
|
+
this.selectable = true;
|
|
3315
|
+
this.removable = true;
|
|
3316
|
+
this.separatorKeysCodes = [ENTER, COMMA];
|
|
3317
|
+
this.placeholder = 'New Tag..';
|
|
3318
|
+
this.apiUrl = 'api/techlify-tagger-tags';
|
|
3319
|
+
this.createApiUrl = 'api/techlify-tagger-tags';
|
|
3320
|
+
this.isCreateable = true;
|
|
3321
|
+
this.isCacheTags = false;
|
|
3322
|
+
this.isSingle = false;
|
|
3323
|
+
}
|
|
3122
3324
|
}
|
|
3123
|
-
EntityFilesViewAllModule.decorators = [
|
|
3124
|
-
{ type: NgModule, args: [{
|
|
3125
|
-
declarations: [EntityFileFormComponent, EntityFilesViewAllComponent],
|
|
3126
|
-
imports: [
|
|
3127
|
-
CommonModule,
|
|
3128
|
-
FormsModule,
|
|
3129
|
-
ReactiveFormsModule,
|
|
3130
|
-
FlexLayoutModule,
|
|
3131
|
-
FileDropperModule,
|
|
3132
|
-
DocumentViewerModule,
|
|
3133
|
-
InfiniteScrollModule,
|
|
3134
|
-
ActionPopupModule,
|
|
3135
|
-
MaterialModule
|
|
3136
|
-
],
|
|
3137
|
-
exports: [
|
|
3138
|
-
EntityFilesViewAllComponent
|
|
3139
|
-
],
|
|
3140
|
-
entryComponents: [EntityFileFormComponent]
|
|
3141
|
-
},] }
|
|
3142
|
-
];
|
|
3143
3325
|
|
|
3144
|
-
|
|
3145
|
-
|
|
3146
|
-
|
|
3147
|
-
this.
|
|
3148
|
-
this.
|
|
3326
|
+
var TechlifyTaggerTagFormFieldComponent_1;
|
|
3327
|
+
let TechlifyTaggerTagFormFieldComponent = TechlifyTaggerTagFormFieldComponent_1 = class TechlifyTaggerTagFormFieldComponent {
|
|
3328
|
+
constructor(_focusMonitor, _elementRef, httpService, _formField, ngControl) {
|
|
3329
|
+
this._focusMonitor = _focusMonitor;
|
|
3330
|
+
this._elementRef = _elementRef;
|
|
3331
|
+
this.httpService = httpService;
|
|
3332
|
+
this._formField = _formField;
|
|
3333
|
+
this.ngControl = ngControl;
|
|
3334
|
+
this.stateChanges = new Subject();
|
|
3335
|
+
this.focused = false;
|
|
3336
|
+
this.controlType = 'techlify-tagger-form-field';
|
|
3337
|
+
this.id = `techlify-tagger-form-field-${TechlifyTaggerTagFormFieldComponent_1.nextId++}`;
|
|
3338
|
+
this.onChange = (_) => { };
|
|
3339
|
+
this.onTouched = () => { };
|
|
3340
|
+
this.tagInputCtrl = new FormControl();
|
|
3341
|
+
/**Pass the configuration for Techlify Tagger */
|
|
3342
|
+
this.config = new TechlifyTaggerTagFormConfigModel();
|
|
3343
|
+
/**Pass the default list of tags */
|
|
3344
|
+
this._allTags = [];
|
|
3345
|
+
/**Pass the Categories to filter for a model */
|
|
3346
|
+
this.categories = [];
|
|
3347
|
+
this._required = false;
|
|
3348
|
+
this._disabled = false;
|
|
3349
|
+
this._value = [];
|
|
3350
|
+
this.tagInputCtrl.valueChanges
|
|
3351
|
+
.subscribe(filterValue => {
|
|
3352
|
+
this.filterString = filterValue;
|
|
3353
|
+
});
|
|
3354
|
+
//Set Focus Monitor
|
|
3355
|
+
_focusMonitor.monitor(_elementRef, true).subscribe(origin => {
|
|
3356
|
+
if (this.focused && !origin) {
|
|
3357
|
+
this.onTouched();
|
|
3358
|
+
}
|
|
3359
|
+
this.focused = !!origin;
|
|
3360
|
+
this.stateChanges.next();
|
|
3361
|
+
});
|
|
3362
|
+
if (this.ngControl != null) {
|
|
3363
|
+
this.ngControl.valueAccessor = this;
|
|
3364
|
+
}
|
|
3149
3365
|
}
|
|
3150
|
-
|
|
3151
|
-
this.
|
|
3366
|
+
get allTags() {
|
|
3367
|
+
return this._allTags;
|
|
3152
3368
|
}
|
|
3153
|
-
|
|
3154
|
-
this.
|
|
3155
|
-
this.determineView();
|
|
3369
|
+
set allTags(value) {
|
|
3370
|
+
this._allTags = value;
|
|
3156
3371
|
}
|
|
3157
|
-
|
|
3158
|
-
|
|
3159
|
-
this.currentText = this.text;
|
|
3160
|
-
this.isCollapsed = false;
|
|
3161
|
-
this.hideToggle = true;
|
|
3162
|
-
return;
|
|
3163
|
-
}
|
|
3164
|
-
this.hideToggle = false;
|
|
3165
|
-
if (this.isCollapsed == true) {
|
|
3166
|
-
this.currentText = this.text.substring(0, this.maxLength) + "...";
|
|
3167
|
-
}
|
|
3168
|
-
else if (this.isCollapsed == false) {
|
|
3169
|
-
this.currentText = this.text;
|
|
3170
|
-
}
|
|
3372
|
+
get tags() {
|
|
3373
|
+
return this.allTags.filter(x => this.value.some(y => y == x.id));
|
|
3171
3374
|
}
|
|
3172
|
-
|
|
3173
|
-
|
|
3174
|
-
|
|
3175
|
-
|
|
3176
|
-
|
|
3177
|
-
|
|
3178
|
-
|
|
3179
|
-
|
|
3180
|
-
|
|
3181
|
-
|
|
3182
|
-
|
|
3183
|
-
|
|
3184
|
-
|
|
3185
|
-
|
|
3186
|
-
|
|
3187
|
-
|
|
3188
|
-
|
|
3189
|
-
|
|
3190
|
-
|
|
3191
|
-
|
|
3192
|
-
|
|
3193
|
-
|
|
3194
|
-
|
|
3195
|
-
|
|
3196
|
-
|
|
3197
|
-
|
|
3198
|
-
|
|
3199
|
-
|
|
3200
|
-
|
|
3201
|
-
|
|
3202
|
-
|
|
3203
|
-
}
|
|
3204
|
-
|
|
3205
|
-
|
|
3206
|
-
|
|
3207
|
-
|
|
3208
|
-
|
|
3209
|
-
|
|
3210
|
-
|
|
3375
|
+
//Default Getter and Setters for a Form Field Implementation
|
|
3376
|
+
get empty() {
|
|
3377
|
+
return this.value.length == 0;
|
|
3378
|
+
}
|
|
3379
|
+
get shouldLabelFloat() {
|
|
3380
|
+
return this.focused || !this.empty || this.tagInputCtrl.value;
|
|
3381
|
+
}
|
|
3382
|
+
get required() {
|
|
3383
|
+
return this._required;
|
|
3384
|
+
}
|
|
3385
|
+
set required(value) {
|
|
3386
|
+
this._required = coerceBooleanProperty(value);
|
|
3387
|
+
this.stateChanges.next();
|
|
3388
|
+
}
|
|
3389
|
+
get disabled() {
|
|
3390
|
+
return this._disabled;
|
|
3391
|
+
}
|
|
3392
|
+
set disabled(value) {
|
|
3393
|
+
this._disabled = coerceBooleanProperty(value);
|
|
3394
|
+
this._disabled ? this.tagInputCtrl.disable() : this.tagInputCtrl.enable();
|
|
3395
|
+
this.stateChanges.next();
|
|
3396
|
+
}
|
|
3397
|
+
get value() {
|
|
3398
|
+
return this._value;
|
|
3399
|
+
}
|
|
3400
|
+
set value(tagIds) {
|
|
3401
|
+
this._value = tagIds || [];
|
|
3402
|
+
this.stateChanges.next();
|
|
3403
|
+
}
|
|
3404
|
+
get errorState() {
|
|
3405
|
+
return this.tagInputCtrl.dirty && this.required && (this.value.length == 0);
|
|
3406
|
+
}
|
|
3407
|
+
get placeholder() {
|
|
3408
|
+
return this._placeholder;
|
|
3409
|
+
}
|
|
3410
|
+
set placeholder(value) {
|
|
3411
|
+
this._placeholder = value;
|
|
3412
|
+
this.stateChanges.next();
|
|
3413
|
+
}
|
|
3414
|
+
ngOnInit() {
|
|
3415
|
+
}
|
|
3416
|
+
ngOnChanges(changes) {
|
|
3417
|
+
//API to load all tags for the model type
|
|
3418
|
+
if (this.allTags.length == 0) {
|
|
3419
|
+
this.httpService
|
|
3420
|
+
.cache(!this.config.isCacheTags)
|
|
3421
|
+
.get(this.config.apiUrl, {
|
|
3422
|
+
params: {
|
|
3423
|
+
categories: this.categories.join(','),
|
|
3424
|
+
perPage: '1000'
|
|
3425
|
+
}
|
|
3426
|
+
}).pipe(debounceTime(500), untilDestroyed(this)).subscribe((result) => {
|
|
3427
|
+
this.allTags = result.data;
|
|
3428
|
+
});
|
|
3429
|
+
}
|
|
3430
|
+
//API to load only the selected tags for the model
|
|
3431
|
+
if (this.modelId && this.value.length == 0) {
|
|
3432
|
+
//Model Id is passed and no tags are present, so we query db for the avilable tags for the model ID.
|
|
3433
|
+
this.httpService
|
|
3434
|
+
.cache(!this.config.isCacheTags)
|
|
3435
|
+
.get(this.config.apiUrl, {
|
|
3436
|
+
params: {
|
|
3437
|
+
categories: this.categories.join(','),
|
|
3438
|
+
model_type: this.modelType,
|
|
3439
|
+
model_id: this.modelId,
|
|
3440
|
+
perPage: '1000'
|
|
3441
|
+
}
|
|
3442
|
+
}).pipe(debounceTime(500), untilDestroyed(this)).subscribe((result) => {
|
|
3443
|
+
this.value = ((result === null || result === void 0 ? void 0 : result.data) || []).map((x) => x.id);
|
|
3444
|
+
this._handleInput();
|
|
3445
|
+
});
|
|
3446
|
+
}
|
|
3447
|
+
}
|
|
3448
|
+
init() {
|
|
3449
|
+
if (this.modelId && this.allTags.length == 0) {
|
|
3450
|
+
//Model Id is passed and no tags are passed, so we query db for the avilable tags for the model ID.
|
|
3451
|
+
this.httpService
|
|
3452
|
+
.cache(!this.config.isCacheTags)
|
|
3453
|
+
.get(this.config.apiUrl, {
|
|
3454
|
+
params: {
|
|
3455
|
+
categories: this.categories.join(','),
|
|
3456
|
+
model_type: this.modelType,
|
|
3457
|
+
model_id: this.modelId
|
|
3458
|
+
}
|
|
3459
|
+
}).pipe(untilDestroyed(this)).subscribe((result) => {
|
|
3460
|
+
this.allTags = result.data;
|
|
3461
|
+
});
|
|
3462
|
+
}
|
|
3463
|
+
}
|
|
3464
|
+
get filteredTags() {
|
|
3465
|
+
return this._filter();
|
|
3466
|
+
}
|
|
3467
|
+
setDescribedByIds(ids) {
|
|
3468
|
+
// Just a empty implementation for Mat Form Field Interface
|
|
3469
|
+
}
|
|
3470
|
+
onContainerClick() {
|
|
3471
|
+
// Just a empty implementation for Mat Form Field Interface
|
|
3472
|
+
}
|
|
3473
|
+
add(event) {
|
|
3474
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
3475
|
+
const value = (event.value || '').trim();
|
|
3476
|
+
// Add our tag
|
|
3477
|
+
// Validate for single mode
|
|
3478
|
+
if (!this.config.isSingle || (this.value.length === 0)) {
|
|
3479
|
+
if (value && this.config.isCreateable) {
|
|
3480
|
+
const tags = this.allTags;
|
|
3481
|
+
let tag = tags.find((item) => item.title.toLowerCase() == value.toLowerCase());
|
|
3482
|
+
if (!tag) {
|
|
3483
|
+
//No tag present in the list
|
|
3484
|
+
try {
|
|
3485
|
+
const result = yield this.httpService.post(this.config.createApiUrl, {
|
|
3486
|
+
title: value,
|
|
3487
|
+
description: value,
|
|
3488
|
+
category_title: (this.categories.length > 0) ? (this.defaultCreateCategory ? this.defaultCreateCategory : this.categories[0]) : ''
|
|
3489
|
+
}).toPromise();
|
|
3490
|
+
tag = result.item;
|
|
3491
|
+
}
|
|
3492
|
+
catch (error) {
|
|
3493
|
+
return;
|
|
3494
|
+
}
|
|
3495
|
+
this.allTags.push(tag);
|
|
3496
|
+
}
|
|
3497
|
+
else {
|
|
3498
|
+
//Optionally clean the existing value, to avoid duplicate
|
|
3499
|
+
this.remove(tag);
|
|
3500
|
+
}
|
|
3501
|
+
this.value.push(tag.id);
|
|
3502
|
+
this._handleInput();
|
|
3503
|
+
}
|
|
3504
|
+
}
|
|
3505
|
+
// Clear the input value
|
|
3506
|
+
event.input.value = '';
|
|
3507
|
+
this.tagInputCtrl.setValue(null);
|
|
3508
|
+
});
|
|
3509
|
+
}
|
|
3510
|
+
remove(tag) {
|
|
3511
|
+
this.value = this.value.filter(x => x !== tag.id);
|
|
3512
|
+
this._handleInput();
|
|
3513
|
+
}
|
|
3514
|
+
selected(event) {
|
|
3515
|
+
// Validate for single mode
|
|
3516
|
+
if (!this.config.isSingle || (this.value.length === 0)) {
|
|
3517
|
+
//Clean the existing value, to avoid duplicate
|
|
3518
|
+
this.remove({ id: event.option.value });
|
|
3519
|
+
this.value.push(event.option.value);
|
|
3520
|
+
this._handleInput();
|
|
3521
|
+
}
|
|
3522
|
+
this.tagInput.nativeElement.value = '';
|
|
3523
|
+
this.tagInputCtrl.setValue(null);
|
|
3524
|
+
}
|
|
3525
|
+
_filter() {
|
|
3526
|
+
const filterValue = this.filterString ? this.filterString.toString().toLowerCase() : null;
|
|
3527
|
+
const availableTags = this.allTags.filter((tag) => !this.value.some((item) => item == tag.id));
|
|
3528
|
+
return filterValue ? availableTags.filter((tag) => tag.title.toLowerCase().includes(filterValue)) : availableTags;
|
|
3529
|
+
}
|
|
3530
|
+
writeValue(tagIds) {
|
|
3531
|
+
this.value = tagIds || [];
|
|
3532
|
+
}
|
|
3533
|
+
registerOnChange(fn) {
|
|
3534
|
+
this.onChange = fn;
|
|
3535
|
+
}
|
|
3536
|
+
registerOnTouched(fn) {
|
|
3537
|
+
this.onTouched = fn;
|
|
3538
|
+
}
|
|
3539
|
+
setDisabledState(isDisabled) {
|
|
3540
|
+
this.disabled = isDisabled;
|
|
3541
|
+
}
|
|
3542
|
+
_handleInput() {
|
|
3543
|
+
this.onChange(this.value);
|
|
3544
|
+
}
|
|
3545
|
+
ngOnDestroy() {
|
|
3546
|
+
this.stateChanges.complete();
|
|
3547
|
+
this._focusMonitor.stopMonitoring(this._elementRef);
|
|
3548
|
+
}
|
|
3549
|
+
};
|
|
3550
|
+
TechlifyTaggerTagFormFieldComponent.nextId = 0;
|
|
3551
|
+
TechlifyTaggerTagFormFieldComponent.decorators = [
|
|
3552
|
+
{ type: Component, args: [{
|
|
3553
|
+
selector: 'app-techlify-tagger-tag-form-field',
|
|
3554
|
+
template: "<mat-chip-list #chipList aria-label=\"Tag Selection\">\n <mat-chip *ngFor=\"let tag of tags\" [selectable]=\"config.selectable\" [removable]=\"config.removable\"\n (removed)=\"remove(tag)\">\n {{tag.title}}\n <button matChipRemove *ngIf=\"config.removable\" class=\"border-0\">\n <mat-icon class=\"mat-relative-icon\">cancel</mat-icon>\n </button>\n </mat-chip>\n <input placeholder=\"{{config.isCreateable? config.placeholder:''}}\" #tagInput [formControl]=\"tagInputCtrl\"\n [matAutocomplete]=\"auto\" [matChipInputFor]=\"chipList\"\n [matChipInputSeparatorKeyCodes]=\"config.separatorKeysCodes\" (matChipInputTokenEnd)=\"add($event)\"\n #trigger=\"matAutocompleteTrigger\" (click)=\"trigger.openPanel()\">\n</mat-chip-list>\n<mat-autocomplete #auto=\"matAutocomplete\" (optionSelected)=\"selected($event)\">\n <mat-option *ngFor=\"let tag of filteredTags\" [value]=\"tag.id\">\n {{tag.title}}\n </mat-option>\n</mat-autocomplete>",
|
|
3555
|
+
providers: [{ provide: MatFormFieldControl, useExisting: TechlifyTaggerTagFormFieldComponent_1 }],
|
|
3556
|
+
styles: [".mat-relative-icon{font-size:20px;position:relative;right:7px;top:-3px}"]
|
|
3557
|
+
},] }
|
|
3558
|
+
];
|
|
3559
|
+
TechlifyTaggerTagFormFieldComponent.ctorParameters = () => [
|
|
3560
|
+
{ type: FocusMonitor },
|
|
3561
|
+
{ type: ElementRef },
|
|
3562
|
+
{ type: HttpService },
|
|
3563
|
+
{ type: MatFormField, decorators: [{ type: Optional }, { type: Inject, args: [MAT_FORM_FIELD,] }] },
|
|
3564
|
+
{ type: NgControl, decorators: [{ type: Optional }, { type: Self }] }
|
|
3565
|
+
];
|
|
3566
|
+
TechlifyTaggerTagFormFieldComponent.propDecorators = {
|
|
3567
|
+
tagInput: [{ type: ViewChild, args: ['tagInput',] }],
|
|
3568
|
+
config: [{ type: Input }],
|
|
3569
|
+
modelType: [{ type: Input }],
|
|
3570
|
+
modelId: [{ type: Input }],
|
|
3571
|
+
allTags: [{ type: Input }],
|
|
3572
|
+
categories: [{ type: Input }],
|
|
3573
|
+
defaultCreateCategory: [{ type: Input }],
|
|
3574
|
+
required: [{ type: Input }],
|
|
3575
|
+
disabled: [{ type: Input }],
|
|
3576
|
+
value: [{ type: Input }],
|
|
3577
|
+
placeholder: [{ type: Input }]
|
|
3578
|
+
};
|
|
3579
|
+
TechlifyTaggerTagFormFieldComponent = TechlifyTaggerTagFormFieldComponent_1 = __decorate([
|
|
3580
|
+
UntilDestroy()
|
|
3581
|
+
], TechlifyTaggerTagFormFieldComponent);
|
|
3582
|
+
|
|
3583
|
+
class TechlifyTaggerTagFormFieldModule {
|
|
3584
|
+
}
|
|
3585
|
+
TechlifyTaggerTagFormFieldModule.decorators = [
|
|
3586
|
+
{ type: NgModule, args: [{
|
|
3587
|
+
declarations: [
|
|
3588
|
+
TechlifyTaggerTagFormFieldComponent
|
|
3589
|
+
],
|
|
3211
3590
|
imports: [
|
|
3212
3591
|
CommonModule,
|
|
3213
|
-
ReactiveFormsModule,
|
|
3214
|
-
InfiniteScrollModule,
|
|
3215
|
-
FlexLayoutModule,
|
|
3216
|
-
ActionPopupModule,
|
|
3217
3592
|
MaterialModule,
|
|
3218
|
-
|
|
3219
|
-
|
|
3220
|
-
|
|
3221
|
-
NoteListComponent
|
|
3593
|
+
FlexLayoutModule,
|
|
3594
|
+
MatAutocompleteModule,
|
|
3595
|
+
ReactiveFormsModule
|
|
3222
3596
|
],
|
|
3223
|
-
|
|
3597
|
+
exports: [TechlifyTaggerTagFormFieldComponent]
|
|
3224
3598
|
},] }
|
|
3225
3599
|
];
|
|
3226
3600
|
|
|
@@ -3245,28 +3619,136 @@ SearchableSelectorModule.decorators = [
|
|
|
3245
3619
|
},] }
|
|
3246
3620
|
];
|
|
3247
3621
|
|
|
3248
|
-
class
|
|
3622
|
+
class EntityFilesViewAllModule {
|
|
3249
3623
|
}
|
|
3250
|
-
|
|
3624
|
+
EntityFilesViewAllModule.decorators = [
|
|
3251
3625
|
{ type: NgModule, args: [{
|
|
3626
|
+
declarations: [EntityFileFormComponent, EntityFilesViewAllComponent],
|
|
3252
3627
|
imports: [
|
|
3253
3628
|
CommonModule,
|
|
3254
3629
|
FormsModule,
|
|
3630
|
+
ReactiveFormsModule,
|
|
3631
|
+
FlexLayoutModule,
|
|
3632
|
+
FileDropperModule,
|
|
3633
|
+
DocumentViewerModule,
|
|
3634
|
+
InfiniteScrollModule,
|
|
3635
|
+
ActionPopupModule,
|
|
3636
|
+
MaterialModule,
|
|
3637
|
+
TechlifyTaggerTagFormFieldModule,
|
|
3638
|
+
SearchableSelectorModule
|
|
3255
3639
|
],
|
|
3256
|
-
|
|
3257
|
-
|
|
3640
|
+
exports: [
|
|
3641
|
+
EntityFilesViewAllComponent
|
|
3258
3642
|
],
|
|
3259
|
-
|
|
3260
|
-
},] }
|
|
3261
|
-
];
|
|
3262
|
-
|
|
3263
|
-
|
|
3264
|
-
|
|
3265
|
-
|
|
3266
|
-
|
|
3267
|
-
|
|
3268
|
-
|
|
3269
|
-
|
|
3643
|
+
entryComponents: [EntityFileFormComponent]
|
|
3644
|
+
},] }
|
|
3645
|
+
];
|
|
3646
|
+
|
|
3647
|
+
class ReadMoreComponent {
|
|
3648
|
+
constructor() {
|
|
3649
|
+
this.maxLength = 100;
|
|
3650
|
+
this.hideToggle = true;
|
|
3651
|
+
this.isCollapsed = true;
|
|
3652
|
+
}
|
|
3653
|
+
ngOnInit() {
|
|
3654
|
+
this.determineView();
|
|
3655
|
+
}
|
|
3656
|
+
toggleView() {
|
|
3657
|
+
this.isCollapsed = !this.isCollapsed;
|
|
3658
|
+
this.determineView();
|
|
3659
|
+
}
|
|
3660
|
+
determineView() {
|
|
3661
|
+
if (!this.text || this.text.length <= this.maxLength) {
|
|
3662
|
+
this.currentText = this.text;
|
|
3663
|
+
this.isCollapsed = false;
|
|
3664
|
+
this.hideToggle = true;
|
|
3665
|
+
return;
|
|
3666
|
+
}
|
|
3667
|
+
this.hideToggle = false;
|
|
3668
|
+
if (this.isCollapsed == true) {
|
|
3669
|
+
this.currentText = this.text.substring(0, this.maxLength) + "...";
|
|
3670
|
+
}
|
|
3671
|
+
else if (this.isCollapsed == false) {
|
|
3672
|
+
this.currentText = this.text;
|
|
3673
|
+
}
|
|
3674
|
+
}
|
|
3675
|
+
}
|
|
3676
|
+
ReadMoreComponent.decorators = [
|
|
3677
|
+
{ type: Component, args: [{
|
|
3678
|
+
selector: "app-read-more",
|
|
3679
|
+
template: "<div [innerHTML]=\"currentText\"></div>\n<a href=\"javascript:;\" *ngIf=\"!hideToggle\" class=\"primary-color hoverable\" (click)=\"toggleView()\">Read\n {{ isCollapsed ? \"more\" : \"less\" }}</a>",
|
|
3680
|
+
styles: ["div.collapsed{height:250px;overflow:hidden}.primary-color{color:#009fdd!important}"]
|
|
3681
|
+
},] }
|
|
3682
|
+
];
|
|
3683
|
+
ReadMoreComponent.ctorParameters = () => [];
|
|
3684
|
+
ReadMoreComponent.propDecorators = {
|
|
3685
|
+
text: [{ type: Input }],
|
|
3686
|
+
maxLength: [{ type: Input }]
|
|
3687
|
+
};
|
|
3688
|
+
|
|
3689
|
+
class ReadMoreModule {
|
|
3690
|
+
}
|
|
3691
|
+
ReadMoreModule.decorators = [
|
|
3692
|
+
{ type: NgModule, args: [{
|
|
3693
|
+
declarations: [ReadMoreComponent],
|
|
3694
|
+
imports: [
|
|
3695
|
+
CommonModule,
|
|
3696
|
+
MaterialModule,
|
|
3697
|
+
FlexLayoutModule
|
|
3698
|
+
],
|
|
3699
|
+
exports: [
|
|
3700
|
+
ReadMoreComponent
|
|
3701
|
+
]
|
|
3702
|
+
},] }
|
|
3703
|
+
];
|
|
3704
|
+
|
|
3705
|
+
class NoteModule {
|
|
3706
|
+
}
|
|
3707
|
+
NoteModule.decorators = [
|
|
3708
|
+
{ type: NgModule, args: [{
|
|
3709
|
+
declarations: [
|
|
3710
|
+
NoteListComponent,
|
|
3711
|
+
NoteFormComponent,
|
|
3712
|
+
CommentFormComponent,
|
|
3713
|
+
],
|
|
3714
|
+
imports: [
|
|
3715
|
+
CommonModule,
|
|
3716
|
+
ReactiveFormsModule,
|
|
3717
|
+
InfiniteScrollModule,
|
|
3718
|
+
FlexLayoutModule,
|
|
3719
|
+
ActionPopupModule,
|
|
3720
|
+
MaterialModule,
|
|
3721
|
+
ReadMoreModule
|
|
3722
|
+
],
|
|
3723
|
+
exports: [
|
|
3724
|
+
NoteListComponent
|
|
3725
|
+
],
|
|
3726
|
+
entryComponents: [NoteFormComponent]
|
|
3727
|
+
},] }
|
|
3728
|
+
];
|
|
3729
|
+
|
|
3730
|
+
class UtilityModule {
|
|
3731
|
+
}
|
|
3732
|
+
UtilityModule.decorators = [
|
|
3733
|
+
{ type: NgModule, args: [{
|
|
3734
|
+
imports: [
|
|
3735
|
+
CommonModule,
|
|
3736
|
+
FormsModule,
|
|
3737
|
+
],
|
|
3738
|
+
declarations: [
|
|
3739
|
+
NumItemsSelector, NumberSelector,
|
|
3740
|
+
],
|
|
3741
|
+
exports: [NumItemsSelector, NumberSelector]
|
|
3742
|
+
},] }
|
|
3743
|
+
];
|
|
3744
|
+
|
|
3745
|
+
const routes = [];
|
|
3746
|
+
class TimelineFilterRoutingModule {
|
|
3747
|
+
}
|
|
3748
|
+
TimelineFilterRoutingModule.decorators = [
|
|
3749
|
+
{ type: NgModule, args: [{
|
|
3750
|
+
imports: [RouterModule.forChild(routes)],
|
|
3751
|
+
exports: [RouterModule]
|
|
3270
3752
|
},] }
|
|
3271
3753
|
];
|
|
3272
3754
|
|
|
@@ -6087,295 +6569,6 @@ LoginHistoryForUserModule.decorators = [
|
|
|
6087
6569
|
},] }
|
|
6088
6570
|
];
|
|
6089
6571
|
|
|
6090
|
-
class TechlifyTaggerTagFormConfigModel {
|
|
6091
|
-
constructor() {
|
|
6092
|
-
this.selectable = true;
|
|
6093
|
-
this.removable = true;
|
|
6094
|
-
this.separatorKeysCodes = [ENTER, COMMA];
|
|
6095
|
-
this.placeholder = 'New Tag..';
|
|
6096
|
-
this.apiUrl = 'api/techlify-tagger-tags';
|
|
6097
|
-
this.createApiUrl = 'api/techlify-tagger-tags';
|
|
6098
|
-
this.isCreateable = true;
|
|
6099
|
-
this.isCacheTags = false;
|
|
6100
|
-
this.isSingle = false;
|
|
6101
|
-
}
|
|
6102
|
-
}
|
|
6103
|
-
|
|
6104
|
-
var TechlifyTaggerTagFormFieldComponent_1;
|
|
6105
|
-
let TechlifyTaggerTagFormFieldComponent = TechlifyTaggerTagFormFieldComponent_1 = class TechlifyTaggerTagFormFieldComponent {
|
|
6106
|
-
constructor(_focusMonitor, _elementRef, httpService, _formField, ngControl) {
|
|
6107
|
-
this._focusMonitor = _focusMonitor;
|
|
6108
|
-
this._elementRef = _elementRef;
|
|
6109
|
-
this.httpService = httpService;
|
|
6110
|
-
this._formField = _formField;
|
|
6111
|
-
this.ngControl = ngControl;
|
|
6112
|
-
this.stateChanges = new Subject();
|
|
6113
|
-
this.focused = false;
|
|
6114
|
-
this.controlType = 'techlify-tagger-form-field';
|
|
6115
|
-
this.id = `techlify-tagger-form-field-${TechlifyTaggerTagFormFieldComponent_1.nextId++}`;
|
|
6116
|
-
this.onChange = (_) => { };
|
|
6117
|
-
this.onTouched = () => { };
|
|
6118
|
-
this.tagInputCtrl = new FormControl();
|
|
6119
|
-
/**Pass the configuration for Techlify Tagger */
|
|
6120
|
-
this.config = new TechlifyTaggerTagFormConfigModel();
|
|
6121
|
-
/**Pass the default list of tags */
|
|
6122
|
-
this._allTags = [];
|
|
6123
|
-
/**Pass the Categories to filter for a model */
|
|
6124
|
-
this.categories = [];
|
|
6125
|
-
this._required = false;
|
|
6126
|
-
this._disabled = false;
|
|
6127
|
-
this._value = [];
|
|
6128
|
-
this.tagInputCtrl.valueChanges
|
|
6129
|
-
.subscribe(filterValue => {
|
|
6130
|
-
this.filterString = filterValue;
|
|
6131
|
-
});
|
|
6132
|
-
//Set Focus Monitor
|
|
6133
|
-
_focusMonitor.monitor(_elementRef, true).subscribe(origin => {
|
|
6134
|
-
if (this.focused && !origin) {
|
|
6135
|
-
this.onTouched();
|
|
6136
|
-
}
|
|
6137
|
-
this.focused = !!origin;
|
|
6138
|
-
this.stateChanges.next();
|
|
6139
|
-
});
|
|
6140
|
-
if (this.ngControl != null) {
|
|
6141
|
-
this.ngControl.valueAccessor = this;
|
|
6142
|
-
}
|
|
6143
|
-
}
|
|
6144
|
-
get allTags() {
|
|
6145
|
-
return this._allTags;
|
|
6146
|
-
}
|
|
6147
|
-
set allTags(value) {
|
|
6148
|
-
this._allTags = value;
|
|
6149
|
-
}
|
|
6150
|
-
get tags() {
|
|
6151
|
-
return this.allTags.filter(x => this.value.some(y => y == x.id));
|
|
6152
|
-
}
|
|
6153
|
-
//Default Getter and Setters for a Form Field Implementation
|
|
6154
|
-
get empty() {
|
|
6155
|
-
return this.value.length == 0;
|
|
6156
|
-
}
|
|
6157
|
-
get shouldLabelFloat() {
|
|
6158
|
-
return this.focused || !this.empty || this.tagInputCtrl.value;
|
|
6159
|
-
}
|
|
6160
|
-
get required() {
|
|
6161
|
-
return this._required;
|
|
6162
|
-
}
|
|
6163
|
-
set required(value) {
|
|
6164
|
-
this._required = coerceBooleanProperty(value);
|
|
6165
|
-
this.stateChanges.next();
|
|
6166
|
-
}
|
|
6167
|
-
get disabled() {
|
|
6168
|
-
return this._disabled;
|
|
6169
|
-
}
|
|
6170
|
-
set disabled(value) {
|
|
6171
|
-
this._disabled = coerceBooleanProperty(value);
|
|
6172
|
-
this._disabled ? this.tagInputCtrl.disable() : this.tagInputCtrl.enable();
|
|
6173
|
-
this.stateChanges.next();
|
|
6174
|
-
}
|
|
6175
|
-
get value() {
|
|
6176
|
-
return this._value;
|
|
6177
|
-
}
|
|
6178
|
-
set value(tagIds) {
|
|
6179
|
-
this._value = tagIds || [];
|
|
6180
|
-
this.stateChanges.next();
|
|
6181
|
-
}
|
|
6182
|
-
get errorState() {
|
|
6183
|
-
return this.tagInputCtrl.dirty && this.required && (this.value.length == 0);
|
|
6184
|
-
}
|
|
6185
|
-
get placeholder() {
|
|
6186
|
-
return this._placeholder;
|
|
6187
|
-
}
|
|
6188
|
-
set placeholder(value) {
|
|
6189
|
-
this._placeholder = value;
|
|
6190
|
-
this.stateChanges.next();
|
|
6191
|
-
}
|
|
6192
|
-
ngOnInit() {
|
|
6193
|
-
}
|
|
6194
|
-
ngOnChanges(changes) {
|
|
6195
|
-
//API to load all tags for the model type
|
|
6196
|
-
if (this.allTags.length == 0) {
|
|
6197
|
-
this.httpService
|
|
6198
|
-
.cache(!this.config.isCacheTags)
|
|
6199
|
-
.get(this.config.apiUrl, {
|
|
6200
|
-
params: {
|
|
6201
|
-
categories: this.categories.join(','),
|
|
6202
|
-
perPage: '1000'
|
|
6203
|
-
}
|
|
6204
|
-
}).pipe(debounceTime(500), untilDestroyed(this)).subscribe((result) => {
|
|
6205
|
-
this.allTags = result.data;
|
|
6206
|
-
});
|
|
6207
|
-
}
|
|
6208
|
-
//API to load only the selected tags for the model
|
|
6209
|
-
if (this.modelId && this.value.length == 0) {
|
|
6210
|
-
//Model Id is passed and no tags are present, so we query db for the avilable tags for the model ID.
|
|
6211
|
-
this.httpService
|
|
6212
|
-
.cache(!this.config.isCacheTags)
|
|
6213
|
-
.get(this.config.apiUrl, {
|
|
6214
|
-
params: {
|
|
6215
|
-
categories: this.categories.join(','),
|
|
6216
|
-
model_type: this.modelType,
|
|
6217
|
-
model_id: this.modelId,
|
|
6218
|
-
perPage: '1000'
|
|
6219
|
-
}
|
|
6220
|
-
}).pipe(debounceTime(500), untilDestroyed(this)).subscribe((result) => {
|
|
6221
|
-
this.value = ((result === null || result === void 0 ? void 0 : result.data) || []).map((x) => x.id);
|
|
6222
|
-
this._handleInput();
|
|
6223
|
-
});
|
|
6224
|
-
}
|
|
6225
|
-
}
|
|
6226
|
-
init() {
|
|
6227
|
-
if (this.modelId && this.allTags.length == 0) {
|
|
6228
|
-
//Model Id is passed and no tags are passed, so we query db for the avilable tags for the model ID.
|
|
6229
|
-
this.httpService
|
|
6230
|
-
.cache(!this.config.isCacheTags)
|
|
6231
|
-
.get(this.config.apiUrl, {
|
|
6232
|
-
params: {
|
|
6233
|
-
categories: this.categories.join(','),
|
|
6234
|
-
model_type: this.modelType,
|
|
6235
|
-
model_id: this.modelId
|
|
6236
|
-
}
|
|
6237
|
-
}).pipe(untilDestroyed(this)).subscribe((result) => {
|
|
6238
|
-
this.allTags = result.data;
|
|
6239
|
-
});
|
|
6240
|
-
}
|
|
6241
|
-
}
|
|
6242
|
-
get filteredTags() {
|
|
6243
|
-
return this._filter();
|
|
6244
|
-
}
|
|
6245
|
-
setDescribedByIds(ids) {
|
|
6246
|
-
// Just a empty implementation for Mat Form Field Interface
|
|
6247
|
-
}
|
|
6248
|
-
onContainerClick() {
|
|
6249
|
-
// Just a empty implementation for Mat Form Field Interface
|
|
6250
|
-
}
|
|
6251
|
-
add(event) {
|
|
6252
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
6253
|
-
const value = (event.value || '').trim();
|
|
6254
|
-
// Add our tag
|
|
6255
|
-
// Validate for single mode
|
|
6256
|
-
if (!this.config.isSingle || (this.value.length === 0)) {
|
|
6257
|
-
if (value && this.config.isCreateable) {
|
|
6258
|
-
const tags = this.allTags;
|
|
6259
|
-
let tag = tags.find((item) => item.title.toLowerCase() == value.toLowerCase());
|
|
6260
|
-
if (!tag) {
|
|
6261
|
-
//No tag present in the list
|
|
6262
|
-
try {
|
|
6263
|
-
const result = yield this.httpService.post(this.config.createApiUrl, {
|
|
6264
|
-
title: value,
|
|
6265
|
-
description: value,
|
|
6266
|
-
category_title: (this.categories.length > 0) ? (this.defaultCreateCategory ? this.defaultCreateCategory : this.categories[0]) : ''
|
|
6267
|
-
}).toPromise();
|
|
6268
|
-
tag = result.item;
|
|
6269
|
-
}
|
|
6270
|
-
catch (error) {
|
|
6271
|
-
return;
|
|
6272
|
-
}
|
|
6273
|
-
this.allTags.push(tag);
|
|
6274
|
-
}
|
|
6275
|
-
else {
|
|
6276
|
-
//Optionally clean the existing value, to avoid duplicate
|
|
6277
|
-
this.remove(tag);
|
|
6278
|
-
}
|
|
6279
|
-
this.value.push(tag.id);
|
|
6280
|
-
this._handleInput();
|
|
6281
|
-
}
|
|
6282
|
-
}
|
|
6283
|
-
// Clear the input value
|
|
6284
|
-
event.input.value = '';
|
|
6285
|
-
this.tagInputCtrl.setValue(null);
|
|
6286
|
-
});
|
|
6287
|
-
}
|
|
6288
|
-
remove(tag) {
|
|
6289
|
-
this.value = this.value.filter(x => x !== tag.id);
|
|
6290
|
-
this._handleInput();
|
|
6291
|
-
}
|
|
6292
|
-
selected(event) {
|
|
6293
|
-
// Validate for single mode
|
|
6294
|
-
if (!this.config.isSingle || (this.value.length === 0)) {
|
|
6295
|
-
//Clean the existing value, to avoid duplicate
|
|
6296
|
-
this.remove({ id: event.option.value });
|
|
6297
|
-
this.value.push(event.option.value);
|
|
6298
|
-
this._handleInput();
|
|
6299
|
-
}
|
|
6300
|
-
this.tagInput.nativeElement.value = '';
|
|
6301
|
-
this.tagInputCtrl.setValue(null);
|
|
6302
|
-
}
|
|
6303
|
-
_filter() {
|
|
6304
|
-
const filterValue = this.filterString ? this.filterString.toString().toLowerCase() : null;
|
|
6305
|
-
const availableTags = this.allTags.filter((tag) => !this.value.some((item) => item == tag.id));
|
|
6306
|
-
return filterValue ? availableTags.filter((tag) => tag.title.toLowerCase().includes(filterValue)) : availableTags;
|
|
6307
|
-
}
|
|
6308
|
-
writeValue(tagIds) {
|
|
6309
|
-
this.value = tagIds || [];
|
|
6310
|
-
}
|
|
6311
|
-
registerOnChange(fn) {
|
|
6312
|
-
this.onChange = fn;
|
|
6313
|
-
}
|
|
6314
|
-
registerOnTouched(fn) {
|
|
6315
|
-
this.onTouched = fn;
|
|
6316
|
-
}
|
|
6317
|
-
setDisabledState(isDisabled) {
|
|
6318
|
-
this.disabled = isDisabled;
|
|
6319
|
-
}
|
|
6320
|
-
_handleInput() {
|
|
6321
|
-
this.onChange(this.value);
|
|
6322
|
-
}
|
|
6323
|
-
ngOnDestroy() {
|
|
6324
|
-
this.stateChanges.complete();
|
|
6325
|
-
this._focusMonitor.stopMonitoring(this._elementRef);
|
|
6326
|
-
}
|
|
6327
|
-
};
|
|
6328
|
-
TechlifyTaggerTagFormFieldComponent.nextId = 0;
|
|
6329
|
-
TechlifyTaggerTagFormFieldComponent.decorators = [
|
|
6330
|
-
{ type: Component, args: [{
|
|
6331
|
-
selector: 'app-techlify-tagger-tag-form-field',
|
|
6332
|
-
template: "<mat-chip-list #chipList aria-label=\"Tag Selection\">\n <mat-chip *ngFor=\"let tag of tags\" [selectable]=\"config.selectable\" [removable]=\"config.removable\"\n (removed)=\"remove(tag)\">\n {{tag.title}}\n <button matChipRemove *ngIf=\"config.removable\" class=\"border-0\">\n <mat-icon class=\"mat-relative-icon\">cancel</mat-icon>\n </button>\n </mat-chip>\n <input placeholder=\"{{config.isCreateable? config.placeholder:''}}\" #tagInput [formControl]=\"tagInputCtrl\"\n [matAutocomplete]=\"auto\" [matChipInputFor]=\"chipList\"\n [matChipInputSeparatorKeyCodes]=\"config.separatorKeysCodes\" (matChipInputTokenEnd)=\"add($event)\"\n #trigger=\"matAutocompleteTrigger\" (click)=\"trigger.openPanel()\">\n</mat-chip-list>\n<mat-autocomplete #auto=\"matAutocomplete\" (optionSelected)=\"selected($event)\">\n <mat-option *ngFor=\"let tag of filteredTags\" [value]=\"tag.id\">\n {{tag.title}}\n </mat-option>\n</mat-autocomplete>",
|
|
6333
|
-
providers: [{ provide: MatFormFieldControl, useExisting: TechlifyTaggerTagFormFieldComponent_1 }],
|
|
6334
|
-
styles: [".mat-relative-icon{font-size:20px;position:relative;right:7px;top:-3px}"]
|
|
6335
|
-
},] }
|
|
6336
|
-
];
|
|
6337
|
-
TechlifyTaggerTagFormFieldComponent.ctorParameters = () => [
|
|
6338
|
-
{ type: FocusMonitor },
|
|
6339
|
-
{ type: ElementRef },
|
|
6340
|
-
{ type: HttpService },
|
|
6341
|
-
{ type: MatFormField, decorators: [{ type: Optional }, { type: Inject, args: [MAT_FORM_FIELD,] }] },
|
|
6342
|
-
{ type: NgControl, decorators: [{ type: Optional }, { type: Self }] }
|
|
6343
|
-
];
|
|
6344
|
-
TechlifyTaggerTagFormFieldComponent.propDecorators = {
|
|
6345
|
-
tagInput: [{ type: ViewChild, args: ['tagInput',] }],
|
|
6346
|
-
config: [{ type: Input }],
|
|
6347
|
-
modelType: [{ type: Input }],
|
|
6348
|
-
modelId: [{ type: Input }],
|
|
6349
|
-
allTags: [{ type: Input }],
|
|
6350
|
-
categories: [{ type: Input }],
|
|
6351
|
-
defaultCreateCategory: [{ type: Input }],
|
|
6352
|
-
required: [{ type: Input }],
|
|
6353
|
-
disabled: [{ type: Input }],
|
|
6354
|
-
value: [{ type: Input }],
|
|
6355
|
-
placeholder: [{ type: Input }]
|
|
6356
|
-
};
|
|
6357
|
-
TechlifyTaggerTagFormFieldComponent = TechlifyTaggerTagFormFieldComponent_1 = __decorate([
|
|
6358
|
-
UntilDestroy()
|
|
6359
|
-
], TechlifyTaggerTagFormFieldComponent);
|
|
6360
|
-
|
|
6361
|
-
class TechlifyTaggerTagFormFieldModule {
|
|
6362
|
-
}
|
|
6363
|
-
TechlifyTaggerTagFormFieldModule.decorators = [
|
|
6364
|
-
{ type: NgModule, args: [{
|
|
6365
|
-
declarations: [
|
|
6366
|
-
TechlifyTaggerTagFormFieldComponent
|
|
6367
|
-
],
|
|
6368
|
-
imports: [
|
|
6369
|
-
CommonModule,
|
|
6370
|
-
MaterialModule,
|
|
6371
|
-
FlexLayoutModule,
|
|
6372
|
-
MatAutocompleteModule,
|
|
6373
|
-
ReactiveFormsModule
|
|
6374
|
-
],
|
|
6375
|
-
exports: [TechlifyTaggerTagFormFieldComponent]
|
|
6376
|
-
},] }
|
|
6377
|
-
];
|
|
6378
|
-
|
|
6379
6572
|
var TechlifyTaggerTagSelectorComponent_1;
|
|
6380
6573
|
let TechlifyTaggerTagSelectorComponent = TechlifyTaggerTagSelectorComponent_1 = class TechlifyTaggerTagSelectorComponent {
|
|
6381
6574
|
constructor(_focusMonitor, _elementRef, httpService, _formField, ngControl) {
|
|
@@ -6875,5 +7068,5 @@ TechlifyFeatureModule.decorators = [
|
|
|
6875
7068
|
* Generated bundle index. Do not edit.
|
|
6876
7069
|
*/
|
|
6877
7070
|
|
|
6878
|
-
export { ActionPopup, ActionPopupComponent, ActionPopupModule, AlertService, ApiPrefixInterceptor, AuditLogForModelComponent, AuditLogForModelModule, AuditLogForModelRoutingModule, AuditLogListComponent, AuditLogListFilterComponent, AuditLogListFilterModule, AuditLogListFilterRoutingModule, AuditLogListModule, AuditLogListRoutingModule, AuditLogModule, AuditLogRoutingModule, AuditLogViewComponent, AuditLogViewModelComponent, AuditLogViewModelModule, AuditLogViewModelRoutingModule, AuditLogViewModule, AuditLogViewRoutingModule, AuditLogsViewModelComponent, AuditLogsViewModelModule, AuditLogsViewModelRoutingModule, AuthenticationGuard, AuthenticationService, CacheInterceptor, CommentFormComponent, ConfigService, CoreModule, CredentialsService, DataManager, DataTable, DataTableComponent, DataTableModule, DateUtils, DateValidator, DocumentViewerComponent, DocumentViewerModule, EmailSubscriptionForUserComponent, EmailSubscriptionForUserModule, EmailSubscriptionForUserRoutingModule, EmailSubscriptionModule, EmailSubscriptionRoutingModule, EmailSubscriptionTypeFormComponent, EmailSubscriptionTypeFormModule, EmailSubscriptionTypeFormRoutingModule, EmailSubscriptionTypeListComponent, EmailSubscriptionTypeListModule, EmailSubscriptionTypeListRoutingModule, EmailSubscriptionTypeModule, EmailSubscriptionTypeRoutingModule, EmailSubscriptionUserFormComponent, EmailSubscriptionUserFormModule, EmailSubscriptionUserFormRoutingModule, EmailSubscriptionUserListComponent, EmailSubscriptionUserListFilterComponent, EmailSubscriptionUserListFilterModule, EmailSubscriptionUserListFilterRoutingModule, EmailSubscriptionUserListModule, EmailSubscriptionUserListRoutingModule, EmailSubscriptionUserModule, EmailSubscriptionUserRoutingModule, EntityFileFormComponent, EntityFilesViewAllComponent, EntityFilesViewAllModule, ErrorHandlerInterceptor, ErrorHandlerService, ErrorSnackComponent, ExportExcelButtonComponent, ExportExcelModule, FileDropperComponent, FileDropperConfig, FileDropperModule, FormValidatorService, HTTP_DYNAMIC_INTERCEPTORS, HttpCacheService, HttpService, ImportCsvComponent, ImportCsvModule, LoaderComponent, LoaderModule, LogLevel, Logger, LoginHistoryForUserComponent, LoginHistoryForUserModule, LoginHistoryForUserRoutingModule, MatSelectInfiniteScrollDirective, MaterialModule, NoteFormComponent, NoteListComponent, NoteModule, NumItemsSelector, NumberSelector, PageEvent, ReadMoreComponent, ReadMoreModule, RouteReusableStrategy, SearchableSelectorComponent, SearchableSelectorModule, SnackModule, StorageService, SuccessSnackComponent, TechlifyConfig, TechlifyFeatureEnabledDirective, TechlifyFeatureListingComponent, TechlifyFeatureModule, TechlifyFeatureRoutes, TechlifyTaggerTagFormConfigModel, TechlifyTaggerTagFormFieldComponent, TechlifyTaggerTagFormFieldModule, TechlifyTaggerTagSelectorComponent, TechlifyTaggerTagSelectorModule, TechlifyUpdateHistoryModule, TechlifyUpdateModule, Timeline, TimelineFilterComponent, TimelineFilterModule, TokenInterceptor, UpdateNotifierComponent, UpdateNotifierModule, UtilityModule, ViewerConfig, calculateTimeline, esfur, estlr, esulr, SnackModule as ɵa, SuccessSnackComponent as ɵb, NumberSelector as ɵba, TimelineFilterComponent as ɵbb, TimelineFilterRoutingModule as ɵbc, LoaderComponent as ɵbd, EmailSubscriptionUserFormComponent as ɵbe, EmailSubscriptionUserListComponent as ɵbf, AuthenticationGuard as ɵbg, EmailSubscriptionUserListFilterComponent as ɵbh, EmailSubscriptionTypeFormComponent as ɵbi, EmailSubscriptionTypeListComponent as ɵbj, EmailSubscriptionForUserComponent as ɵbk, TechlifyUpdatesListComponent as ɵbl, TechlifyUpdateService as ɵbm, TechlifyUpdateRoutingModule as ɵbn, TechlifyUpdateFormModule as ɵbo, TechlifyUpdateFormComponent as ɵbp, TechlifyUpdateHistoryRoutingModule as ɵbq, TechlifyUpdateHistoryComponent as ɵbr, UpdateNotifierSnackComponent as ɵbs, UpdateViewModule as ɵbt, UpdateViewComponent as ɵbu, DataManager as ɵbv, ErrorHandlerService as ɵbw, FieldMappingComponent as ɵbx, FailedItemsListComponent as ɵby, ImportHistoryListComponent as ɵbz, ErrorSnackComponent as ɵc, ImportSuccessComponent as ɵca, DataImportComponent as ɵcb, StorageService as ɵcc, TechlifyFeatureService as ɵcd, OnOffSwitchComponent as ɵce, HTTP_DYNAMIC_INTERCEPTORS as ɵd, HttpService as ɵe, RouteReusableStrategy as ɵf, ActionPopupComponent as ɵg, ActionPopup as ɵh, DataTableComponent as ɵi, DocumentViewerComponent as ɵj, EntityFileFormComponent as ɵk, FormValidatorService as ɵl, EntityFileService as ɵm, AlertService as ɵn, EntityFilesViewAllComponent as ɵo, FileDropperComponent as ɵp,
|
|
7071
|
+
export { ActionPopup, ActionPopupComponent, ActionPopupModule, AlertService, ApiPrefixInterceptor, AuditLogForModelComponent, AuditLogForModelModule, AuditLogForModelRoutingModule, AuditLogListComponent, AuditLogListFilterComponent, AuditLogListFilterModule, AuditLogListFilterRoutingModule, AuditLogListModule, AuditLogListRoutingModule, AuditLogModule, AuditLogRoutingModule, AuditLogViewComponent, AuditLogViewModelComponent, AuditLogViewModelModule, AuditLogViewModelRoutingModule, AuditLogViewModule, AuditLogViewRoutingModule, AuditLogsViewModelComponent, AuditLogsViewModelModule, AuditLogsViewModelRoutingModule, AuthenticationGuard, AuthenticationService, CacheInterceptor, CommentFormComponent, ConfigService, CoreModule, CredentialsService, DataManager, DataTable, DataTableComponent, DataTableModule, DateUtils, DateValidator, DocumentViewerComponent, DocumentViewerModule, EmailSubscriptionForUserComponent, EmailSubscriptionForUserModule, EmailSubscriptionForUserRoutingModule, EmailSubscriptionModule, EmailSubscriptionRoutingModule, EmailSubscriptionTypeFormComponent, EmailSubscriptionTypeFormModule, EmailSubscriptionTypeFormRoutingModule, EmailSubscriptionTypeListComponent, EmailSubscriptionTypeListModule, EmailSubscriptionTypeListRoutingModule, EmailSubscriptionTypeModule, EmailSubscriptionTypeRoutingModule, EmailSubscriptionUserFormComponent, EmailSubscriptionUserFormModule, EmailSubscriptionUserFormRoutingModule, EmailSubscriptionUserListComponent, EmailSubscriptionUserListFilterComponent, EmailSubscriptionUserListFilterModule, EmailSubscriptionUserListFilterRoutingModule, EmailSubscriptionUserListModule, EmailSubscriptionUserListRoutingModule, EmailSubscriptionUserModule, EmailSubscriptionUserRoutingModule, EntityFileFormComponent, EntityFilesViewAllComponent, EntityFilesViewAllModule, ErrorHandlerInterceptor, ErrorHandlerService, ErrorSnackComponent, ExportExcelButtonComponent, ExportExcelModule, FileDropperComponent, FileDropperConfig, FileDropperModule, FormValidatorService, HTTP_DYNAMIC_INTERCEPTORS, HttpCacheService, HttpService, ImportCsvComponent, ImportCsvModule, LoaderComponent, LoaderModule, LogLevel, Logger, LoginHistoryForUserComponent, LoginHistoryForUserModule, LoginHistoryForUserRoutingModule, MatSelectInfiniteScrollDirective, MaterialModule, NoteFormComponent, NoteListComponent, NoteModule, NumItemsSelector, NumberSelector, PageEvent, ReadMoreComponent, ReadMoreModule, RouteReusableStrategy, SearchableSelectorComponent, SearchableSelectorModule, SnackModule, StorageService, SuccessSnackComponent, TechlifyConfig, TechlifyFeatureEnabledDirective, TechlifyFeatureListingComponent, TechlifyFeatureModule, TechlifyFeatureRoutes, TechlifyFormComponentInterface, TechlifyListingControllerInterface, TechlifyServiceBaseClass, TechlifyTaggerTagFormConfigModel, TechlifyTaggerTagFormFieldComponent, TechlifyTaggerTagFormFieldModule, TechlifyTaggerTagSelectorComponent, TechlifyTaggerTagSelectorModule, TechlifyUpdateHistoryModule, TechlifyUpdateModule, Timeline, TimelineFilterComponent, TimelineFilterModule, TokenInterceptor, UpdateNotifierComponent, UpdateNotifierModule, UtilityModule, ViewerConfig, calculateTimeline, esfur, estlr, esulr, SnackModule as ɵa, SuccessSnackComponent as ɵb, NumberSelector as ɵba, TimelineFilterComponent as ɵbb, TimelineFilterRoutingModule as ɵbc, LoaderComponent as ɵbd, EmailSubscriptionUserFormComponent as ɵbe, EmailSubscriptionUserListComponent as ɵbf, AuthenticationGuard as ɵbg, EmailSubscriptionUserListFilterComponent as ɵbh, EmailSubscriptionTypeFormComponent as ɵbi, EmailSubscriptionTypeListComponent as ɵbj, EmailSubscriptionForUserComponent as ɵbk, TechlifyUpdatesListComponent as ɵbl, TechlifyUpdateService as ɵbm, TechlifyUpdateRoutingModule as ɵbn, TechlifyUpdateFormModule as ɵbo, TechlifyUpdateFormComponent as ɵbp, TechlifyUpdateHistoryRoutingModule as ɵbq, TechlifyUpdateHistoryComponent as ɵbr, UpdateNotifierSnackComponent as ɵbs, UpdateViewModule as ɵbt, UpdateViewComponent as ɵbu, DataManager as ɵbv, ErrorHandlerService as ɵbw, FieldMappingComponent as ɵbx, FailedItemsListComponent as ɵby, ImportHistoryListComponent as ɵbz, ErrorSnackComponent as ɵc, ImportSuccessComponent as ɵca, DataImportComponent as ɵcb, StorageService as ɵcc, TechlifyFeatureService as ɵcd, OnOffSwitchComponent as ɵce, HTTP_DYNAMIC_INTERCEPTORS as ɵd, HttpService as ɵe, RouteReusableStrategy as ɵf, ActionPopupComponent as ɵg, ActionPopup as ɵh, DataTableComponent as ɵi, DocumentViewerComponent as ɵj, EntityFileFormComponent as ɵk, FormValidatorService as ɵl, EntityFileService as ɵm, AlertService as ɵn, EntityFilesViewAllComponent as ɵo, FileDropperComponent as ɵp, SearchableSelectorComponent as ɵq, MatSelectInfiniteScrollDirective as ɵr, NoteListComponent as ɵs, NoteService as ɵt, NoteFormComponent as ɵu, CommentFormComponent as ɵv, CredentialsService as ɵw, ConfigService as ɵx, TechlifyConfig as ɵy, NumItemsSelector as ɵz };
|
|
6879
7072
|
//# sourceMappingURL=ngx-techlify-core.js.map
|