@rosoftlab/rdict 1.0.3-alpha-1 → 1.0.3-alpha-3
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/fesm2022/rosoftlab-rdict.mjs +336 -22
- package/fesm2022/rosoftlab-rdict.mjs.map +1 -1
- package/lib/components/rdict-generic-table/rdict-generic-table.component.d.ts +22 -4
- package/lib/components/rdict-generic-table/rdict-kendo.d.ts +4 -0
- package/lib/reactive-dictionary.d.ts +1 -1
- package/lib/services/socket.service.d.ts +1 -0
- package/package.json +2 -2
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as i7$1 from '@angular/common';
|
|
2
2
|
import { CommonModule } from '@angular/common';
|
|
3
3
|
import * as i0 from '@angular/core';
|
|
4
4
|
import { Inject, Injectable, Component, NgModule, HostBinding, forwardRef, Input, ViewChild, EventEmitter, ElementRef, Output, ViewEncapsulation, InjectionToken } from '@angular/core';
|
|
@@ -11,11 +11,11 @@ import { ButtonsModule, KENDO_BUTTONS } from '@progress/kendo-angular-buttons';
|
|
|
11
11
|
import { KENDO_SVGICON } from '@progress/kendo-angular-icons';
|
|
12
12
|
import * as i6 from '@progress/kendo-angular-layout';
|
|
13
13
|
import { LayoutModule } from '@progress/kendo-angular-layout';
|
|
14
|
-
import * as
|
|
14
|
+
import * as i9 from '@progress/kendo-angular-toolbar';
|
|
15
15
|
import { ToolBarModule, KENDO_TOOLBAR, ToolBarToolComponent } from '@progress/kendo-angular-toolbar';
|
|
16
16
|
import * as allIcons from '@progress/kendo-svg-icons';
|
|
17
17
|
import { menuIcon, saveIcon, arrowLeftIcon, pencilIcon, trashIcon, plusIcon } from '@progress/kendo-svg-icons';
|
|
18
|
-
import { Observable, Subject, from, mergeMap, catchError, throwError,
|
|
18
|
+
import { Observable, Subject, from, mergeMap, tap, catchError, throwError, map, BehaviorSubject } from 'rxjs';
|
|
19
19
|
import { v4 } from 'uuid';
|
|
20
20
|
import { io } from 'socket.io-client';
|
|
21
21
|
import * as i2$1 from '@progress/kendo-angular-dialog';
|
|
@@ -29,10 +29,11 @@ import { FormGroup, FormControl, ReactiveFormsModule } from '@angular/forms';
|
|
|
29
29
|
import * as i6$1 from '@ngx-formly/core';
|
|
30
30
|
import { FORMLY_CONFIG, FormlyModule } from '@ngx-formly/core';
|
|
31
31
|
import { FormlyKendoModule } from '@ngx-formly/kendo';
|
|
32
|
-
import * as
|
|
32
|
+
import * as i8 from '@progress/kendo-angular-grid';
|
|
33
33
|
import { KENDO_GRID } from '@progress/kendo-angular-grid';
|
|
34
34
|
import * as i1$1 from '@progress/kendo-angular-label';
|
|
35
35
|
import { KENDO_LABEL } from '@progress/kendo-angular-label';
|
|
36
|
+
import * as i6$2 from '@progress/kendo-angular-intl';
|
|
36
37
|
|
|
37
38
|
class SocketService {
|
|
38
39
|
constructor(socketUrl) {
|
|
@@ -121,7 +122,8 @@ class SocketService {
|
|
|
121
122
|
observer.error(response.error);
|
|
122
123
|
}
|
|
123
124
|
else {
|
|
124
|
-
|
|
125
|
+
const transformedResponse = this.convertDates(response);
|
|
126
|
+
observer.next(transformedResponse);
|
|
125
127
|
observer.complete();
|
|
126
128
|
}
|
|
127
129
|
});
|
|
@@ -132,6 +134,28 @@ class SocketService {
|
|
|
132
134
|
};
|
|
133
135
|
});
|
|
134
136
|
}
|
|
137
|
+
convertDates(obj) {
|
|
138
|
+
if (obj === null || obj === undefined)
|
|
139
|
+
return obj;
|
|
140
|
+
if (Array.isArray(obj)) {
|
|
141
|
+
return obj.map((item) => this.convertDates(item));
|
|
142
|
+
}
|
|
143
|
+
if (typeof obj === 'object') {
|
|
144
|
+
const newObj = {};
|
|
145
|
+
for (const key of Object.keys(obj)) {
|
|
146
|
+
const value = obj[key];
|
|
147
|
+
// detect ISO date strings
|
|
148
|
+
if (typeof value === 'string' && /^\d{4}-\d{2}-\d{2}[ T]\d/.test(value)) {
|
|
149
|
+
newObj[key] = new Date(value.replace(' ', 'T')); // replace space with T for safety
|
|
150
|
+
}
|
|
151
|
+
else {
|
|
152
|
+
newObj[key] = this.convertDates(value); // recurse
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
return newObj;
|
|
156
|
+
}
|
|
157
|
+
return obj;
|
|
158
|
+
}
|
|
135
159
|
executeFunction(did, functionName, args = [], kwargs = {}) {
|
|
136
160
|
const payload = {
|
|
137
161
|
did,
|
|
@@ -494,18 +518,16 @@ class ReactiveDictionary extends Map {
|
|
|
494
518
|
}
|
|
495
519
|
getFilteredView(key, request) {
|
|
496
520
|
const guid = this.get('__guid'); // however you’re retrieving it
|
|
497
|
-
return this._socketService.requestFilteredData(guid, key, request).pipe(
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
// }),
|
|
502
|
-
catchError((err) => {
|
|
521
|
+
return this._socketService.requestFilteredData(guid, key, request).pipe(tap((data) => {
|
|
522
|
+
// you can still inspect/log the data here if you like
|
|
523
|
+
// console.log('received filtered view:', data);
|
|
524
|
+
}), catchError((err) => {
|
|
503
525
|
console.error('Error fetching filtered view:', err);
|
|
504
526
|
// re-throw so subscribers can handle it
|
|
505
527
|
return throwError(() => err);
|
|
506
528
|
}));
|
|
507
529
|
}
|
|
508
|
-
executeFunction(
|
|
530
|
+
executeFunction(functionName, args = [], kwargs = {}) {
|
|
509
531
|
const guid = this.get('__guid'); // however you’re retrieving it
|
|
510
532
|
return this._socketService.executeFunction(guid, functionName, args, kwargs).pipe(tap((data) => {
|
|
511
533
|
// you can still inspect/log the data here if you like
|
|
@@ -1123,7 +1145,7 @@ class RdictCrudComponent {
|
|
|
1123
1145
|
}
|
|
1124
1146
|
}
|
|
1125
1147
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.8", ngImport: i0, type: RdictCrudComponent, deps: [{ token: i1.Router }, { token: i1.ActivatedRoute }, { token: i2.TranslateService }, { token: ReactiveDictionary }, { token: i4.LocalFileService }, { token: MaterialDialogService }, { token: i4.RouteHistoryService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1126
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.8", type: RdictCrudComponent, isStandalone: true, selector: "app-rdict-crud", host: { properties: { "class": "this.hostClasses" } }, ngImport: i0, template: "<kendo-toolbar>\r\n <kendo-toolbar-button text=\"Back\" showText=\"both\" [svgIcon]=\"backIcon\" showIcon=\"both\" themeColor=\"primary\"\r\n [disabled]=\"false\" (click)=\"onBack()\">\r\n </kendo-toolbar-button>\r\n <kendo-toolbar-spacer></kendo-toolbar-spacer>\r\n <kendo-toolbar-button text=\"Save\" showText=\"both\" [svgIcon]=\"saveIcon\" showIcon=\"both\" themeColor=\"success\"\r\n [disabled]=\"false\" (click)=\"onSave()\">\r\n </kendo-toolbar-button>\r\n</kendo-toolbar>\r\n\r\n <form [formGroup]=\"baseForm\" (ngSubmit)=\"onSubmit(model)\">\r\n <formly-form [form]=\"baseForm\" [fields]=\"fields\" [model]=\"model\" [options]=\"options\"></formly-form>\r\n </form>\r\n<div kendoDialogContainer></div>", styles: ["::ng-deep formly-field{padding:.3rem;display:block}\n"], dependencies: [{ kind: "ngmodule", type: FormlyModule }, { kind: "component", type: i6$1.FormlyForm, selector: "formly-form", inputs: ["form", "model", "fields", "options"], outputs: ["modelChange"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i7.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i7.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i7.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: FormlyKendoModule }, { kind: "ngmodule", type: TranslateModule }, { kind: "ngmodule", type: CrudFormlyTransaltionModule }, { kind: "component", type:
|
|
1148
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.8", type: RdictCrudComponent, isStandalone: true, selector: "app-rdict-crud", host: { properties: { "class": "this.hostClasses" } }, ngImport: i0, template: "<kendo-toolbar>\r\n <kendo-toolbar-button text=\"Back\" showText=\"both\" [svgIcon]=\"backIcon\" showIcon=\"both\" themeColor=\"primary\"\r\n [disabled]=\"false\" (click)=\"onBack()\">\r\n </kendo-toolbar-button>\r\n <kendo-toolbar-spacer></kendo-toolbar-spacer>\r\n <kendo-toolbar-button text=\"Save\" showText=\"both\" [svgIcon]=\"saveIcon\" showIcon=\"both\" themeColor=\"success\"\r\n [disabled]=\"false\" (click)=\"onSave()\">\r\n </kendo-toolbar-button>\r\n</kendo-toolbar>\r\n\r\n <form [formGroup]=\"baseForm\" (ngSubmit)=\"onSubmit(model)\">\r\n <formly-form [form]=\"baseForm\" [fields]=\"fields\" [model]=\"model\" [options]=\"options\"></formly-form>\r\n </form>\r\n<div kendoDialogContainer></div>", styles: ["::ng-deep formly-field{padding:.3rem;display:block}\n"], dependencies: [{ kind: "ngmodule", type: FormlyModule }, { kind: "component", type: i6$1.FormlyForm, selector: "formly-form", inputs: ["form", "model", "fields", "options"], outputs: ["modelChange"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i7.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i7.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i7.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: FormlyKendoModule }, { kind: "ngmodule", type: TranslateModule }, { kind: "ngmodule", type: CrudFormlyTransaltionModule }, { kind: "component", type: i9.ToolBarComponent, selector: "kendo-toolbar", inputs: ["overflow", "resizable", "popupSettings", "fillMode", "tabindex", "size", "tabIndex"], outputs: ["open", "close"], exportAs: ["kendoToolBar"] }, { kind: "component", type: i9.ToolBarButtonComponent, selector: "kendo-toolbar-button", inputs: ["showText", "showIcon", "text", "style", "className", "title", "disabled", "toggleable", "look", "togglable", "selected", "fillMode", "themeColor", "icon", "iconClass", "svgIcon", "imageUrl"], outputs: ["click", "pointerdown", "selectedChange"], exportAs: ["kendoToolBarButton"] }, { kind: "component", type: i9.ToolBarSpacerComponent, selector: "kendo-toolbar-spacer", exportAs: ["kendoToolBarSpacer"] }, { kind: "directive", type: i2$1.DialogContainerDirective, selector: "[kendoDialogContainer]" }] }); }
|
|
1127
1149
|
}
|
|
1128
1150
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.8", ngImport: i0, type: RdictCrudComponent, decorators: [{
|
|
1129
1151
|
type: Component,
|
|
@@ -1144,6 +1166,205 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.8", ngImpor
|
|
|
1144
1166
|
args: ['class']
|
|
1145
1167
|
}] } });
|
|
1146
1168
|
|
|
1169
|
+
/** Main mapper */
|
|
1170
|
+
function kendoToFilterRequest(e) {
|
|
1171
|
+
const { skip = 0, take = 0, sort, filter, group } = e ?? e;
|
|
1172
|
+
const page_size = take || undefined;
|
|
1173
|
+
const page = take ? Math.floor(skip / take) + 1 : undefined;
|
|
1174
|
+
return {
|
|
1175
|
+
page,
|
|
1176
|
+
page_size,
|
|
1177
|
+
sorts: kendoSortsToDict(sort),
|
|
1178
|
+
filters: kendoFilterToSieve(filter),
|
|
1179
|
+
group_by: kendoGroupToArray(group)
|
|
1180
|
+
// distinctColumns: fill if you use a “distinct” mode in your API
|
|
1181
|
+
};
|
|
1182
|
+
}
|
|
1183
|
+
/* ------------------------------- Sorts ---------------------------------- */
|
|
1184
|
+
function kendoSortsToDict(sorts) {
|
|
1185
|
+
if (!sorts?.length)
|
|
1186
|
+
return undefined;
|
|
1187
|
+
const result = {};
|
|
1188
|
+
for (const s of sorts) {
|
|
1189
|
+
if (!s.field)
|
|
1190
|
+
continue;
|
|
1191
|
+
result[s.field] = (s.dir ?? 'asc');
|
|
1192
|
+
}
|
|
1193
|
+
return result;
|
|
1194
|
+
}
|
|
1195
|
+
/* ---------------- GroupBy as array ---------------- */
|
|
1196
|
+
function kendoGroupToArray(group) {
|
|
1197
|
+
if (!group?.length)
|
|
1198
|
+
return undefined;
|
|
1199
|
+
return group.map((g) => g.field);
|
|
1200
|
+
}
|
|
1201
|
+
/* ------------------------------ Filters --------------------------------- */
|
|
1202
|
+
/**
|
|
1203
|
+
* Converts Kendo filter tree to a Sieve filter string.
|
|
1204
|
+
* Notes (Sieve):
|
|
1205
|
+
* - Clause is {Name}{Operator}{Value}, AND with commas, simple OR via:
|
|
1206
|
+
* - multiple names: (Field1|Field2)opValue
|
|
1207
|
+
* - multiple values: Field@=a|b
|
|
1208
|
+
* - Operators: ==, !=, >, <, >=, <=, @= (contains), _= (starts), _-= (ends),
|
|
1209
|
+
* and case-insensitive variants like @=* etc. :contentReference[oaicite:1]{index=1}
|
|
1210
|
+
*/
|
|
1211
|
+
function kendoFilterToSieve(node) {
|
|
1212
|
+
if (!node)
|
|
1213
|
+
return undefined;
|
|
1214
|
+
if (isLeaf(node)) {
|
|
1215
|
+
const op = mapOperator(node.operator, !!node.ignoreCase, node.value);
|
|
1216
|
+
if (!op)
|
|
1217
|
+
return undefined; // unsupported operator (e.g., isnull/isnotnull)
|
|
1218
|
+
const name = node.field;
|
|
1219
|
+
const value = formatSieveValue(node.value);
|
|
1220
|
+
return `${name}${op}${value}`;
|
|
1221
|
+
}
|
|
1222
|
+
// Composite: best-effort mapping.
|
|
1223
|
+
// AND → comma-join
|
|
1224
|
+
// OR → try to compress same-field same-op OR into value pipes; otherwise fall back to (Field1|Field2)opValue when viable.
|
|
1225
|
+
const parts = node.filters.map((f) => kendoFilterToSieve(f)).filter(Boolean);
|
|
1226
|
+
if (!parts.length)
|
|
1227
|
+
return undefined;
|
|
1228
|
+
if (node.logic === 'and') {
|
|
1229
|
+
return parts.join(',');
|
|
1230
|
+
}
|
|
1231
|
+
// OR logic – try simple compressions; if not possible, return a comma-joined set of grouped OR chunks when possible.
|
|
1232
|
+
// Heuristic: if all parts share the same {field,op} with different values → merge via value pipes.
|
|
1233
|
+
const parsed = parts.map(parseClause).filter(Boolean);
|
|
1234
|
+
if (parsed.length && allSame(parsed, (c) => `${c.name}|${c.op}`)) {
|
|
1235
|
+
const { name, op } = parsed[0];
|
|
1236
|
+
const pipedValues = parsed.map((c) => c.value).join('|');
|
|
1237
|
+
return `${name}${op}${pipedValues}`;
|
|
1238
|
+
}
|
|
1239
|
+
// If all parts share same {op,value} but different fields → (A|B)opV
|
|
1240
|
+
if (parsed.length && allSame(parsed, (c) => `${c.op}|${c.value}`)) {
|
|
1241
|
+
const fields = parsed.map((c) => c.name).join('|');
|
|
1242
|
+
const { op, value } = parsed[0];
|
|
1243
|
+
return `(${fields})${op}${value}`;
|
|
1244
|
+
}
|
|
1245
|
+
// Fallback: join with Sieve’s AND (comma). (General mixed OR trees can’t always be represented in Sieve DSL.
|
|
1246
|
+
// If you need exact semantics, consider adding a custom Sieve filter.) :contentReference[oaicite:2]{index=2}
|
|
1247
|
+
return parts.join(',');
|
|
1248
|
+
}
|
|
1249
|
+
/* ----------------------------- Helpers ---------------------------------- */
|
|
1250
|
+
function isLeaf(f) {
|
|
1251
|
+
return f.filters === undefined;
|
|
1252
|
+
}
|
|
1253
|
+
// Map Kendo operators to Sieve operators (case-insensitive variants when ignoreCase=true)
|
|
1254
|
+
function mapOperator(kendoOp, ignoreCase, value) {
|
|
1255
|
+
// Kendo operators list: eq, neq, lt, lte, gt, gte, contains, doesnotcontain, startswith, endswith,
|
|
1256
|
+
// isnull, isnotnull, isempty, isnotempty
|
|
1257
|
+
// Sieve operators: ==, !=, <, <=, >, >=, @=, !@=, _=, _-=, and their * variants for case-insensitive. :contentReference[oaicite:3]{index=3}
|
|
1258
|
+
const strOps = {
|
|
1259
|
+
contains: '@=',
|
|
1260
|
+
doesnotcontain: '!@=',
|
|
1261
|
+
startswith: '_=',
|
|
1262
|
+
endswith: '_-='
|
|
1263
|
+
};
|
|
1264
|
+
const base = (() => {
|
|
1265
|
+
switch (kendoOp) {
|
|
1266
|
+
case 'eq':
|
|
1267
|
+
return '==';
|
|
1268
|
+
case 'neq':
|
|
1269
|
+
return '!=';
|
|
1270
|
+
case 'lt':
|
|
1271
|
+
return '<';
|
|
1272
|
+
case 'lte':
|
|
1273
|
+
return '<=';
|
|
1274
|
+
case 'gt':
|
|
1275
|
+
return '>';
|
|
1276
|
+
case 'gte':
|
|
1277
|
+
return '>=';
|
|
1278
|
+
case 'contains':
|
|
1279
|
+
return strOps.contains;
|
|
1280
|
+
case 'doesnotcontain':
|
|
1281
|
+
return strOps.doesnotcontain;
|
|
1282
|
+
case 'startswith':
|
|
1283
|
+
return strOps.startswith;
|
|
1284
|
+
case 'endswith':
|
|
1285
|
+
return strOps.endswith;
|
|
1286
|
+
case 'isempty':
|
|
1287
|
+
return '=='; // value should be ''
|
|
1288
|
+
case 'isnotempty':
|
|
1289
|
+
return '!='; // value should be ''
|
|
1290
|
+
// isnull / isnotnull don’t have a native Sieve op. Recommend a custom filter on the API.
|
|
1291
|
+
case 'isnull':
|
|
1292
|
+
case 'isnotnull':
|
|
1293
|
+
return undefined;
|
|
1294
|
+
default:
|
|
1295
|
+
return undefined;
|
|
1296
|
+
}
|
|
1297
|
+
})();
|
|
1298
|
+
if (!base)
|
|
1299
|
+
return undefined;
|
|
1300
|
+
// Promote to case-insensitive *only* for string-y ops when requested
|
|
1301
|
+
const isStringy = ['@=', '!@=', '_=', '_-='].includes(base) || typeof value === 'string';
|
|
1302
|
+
if (ignoreCase && isStringy) {
|
|
1303
|
+
// Sieve: case-insensitive variants add a trailing * (e.g., @=*). :contentReference[oaicite:4]{index=4}
|
|
1304
|
+
return base.endsWith('*') ? base : `${base}*`;
|
|
1305
|
+
}
|
|
1306
|
+
return base;
|
|
1307
|
+
}
|
|
1308
|
+
function formatSieveValue(v) {
|
|
1309
|
+
if (v === '' || v === null || v === undefined)
|
|
1310
|
+
return '';
|
|
1311
|
+
if (v instanceof Date)
|
|
1312
|
+
return toISO(v);
|
|
1313
|
+
// Kendo may send dates as strings – try to detect ISO-like and pass through
|
|
1314
|
+
if (typeof v === 'string' && isDateLike(v))
|
|
1315
|
+
return v;
|
|
1316
|
+
if (typeof v === 'string')
|
|
1317
|
+
return escapeSieve(v);
|
|
1318
|
+
if (typeof v === 'number' || typeof v === 'bigint' || typeof v === 'boolean')
|
|
1319
|
+
return String(v);
|
|
1320
|
+
// Arrays can appear with “in” like semantics via OR; join with pipes
|
|
1321
|
+
if (Array.isArray(v))
|
|
1322
|
+
return v.map(formatSieveValue).join('|');
|
|
1323
|
+
// Fallback to JSON (rare)
|
|
1324
|
+
return escapeSieve(JSON.stringify(v));
|
|
1325
|
+
}
|
|
1326
|
+
function toISO(d) {
|
|
1327
|
+
// Prefer full ISO so the API can parse reliably
|
|
1328
|
+
// return new Date(d).toISOString();
|
|
1329
|
+
const y = d.getFullYear();
|
|
1330
|
+
const m = String(d.getMonth() + 1).padStart(2, '0');
|
|
1331
|
+
const day = String(d.getDate()).padStart(2, '0');
|
|
1332
|
+
const hh = String(d.getHours()).padStart(2, '0');
|
|
1333
|
+
const mm = String(d.getMinutes()).padStart(2, '0');
|
|
1334
|
+
const ss = String(d.getSeconds()).padStart(2, '0');
|
|
1335
|
+
return `${y}-${m}-${day}T${hh}:${mm}:${ss}`;
|
|
1336
|
+
}
|
|
1337
|
+
function isDateLike(s) {
|
|
1338
|
+
// very lenient check
|
|
1339
|
+
return /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}/.test(s);
|
|
1340
|
+
}
|
|
1341
|
+
function escapeSieve(s) {
|
|
1342
|
+
// Sieve escaping: backslash to escape commas and pipes (and the backslash itself). :contentReference[oaicite:5]{index=5}
|
|
1343
|
+
return s.replace(/([\\,|])/g, '\\$1');
|
|
1344
|
+
}
|
|
1345
|
+
/** Parses "NameOPValue" (no commas) into {name,op,value} */
|
|
1346
|
+
function parseClause(clause) {
|
|
1347
|
+
// Operators (longer first)
|
|
1348
|
+
const ops = ['==*', '!=*', '@=*', '!@=*', '_=*', '!_=*', '_-=*', '==', '!=', '>=', '<=', '>', '<', '@=', '!@=', '_=', '_-='];
|
|
1349
|
+
for (const op of ops) {
|
|
1350
|
+
const idx = clause.indexOf(op);
|
|
1351
|
+
if (idx > 0) {
|
|
1352
|
+
return {
|
|
1353
|
+
name: clause.slice(0, idx),
|
|
1354
|
+
op,
|
|
1355
|
+
value: clause.slice(idx + op.length)
|
|
1356
|
+
};
|
|
1357
|
+
}
|
|
1358
|
+
}
|
|
1359
|
+
return null;
|
|
1360
|
+
}
|
|
1361
|
+
function allSame(arr, key) {
|
|
1362
|
+
if (!arr.length)
|
|
1363
|
+
return true;
|
|
1364
|
+
const k0 = key(arr[0]);
|
|
1365
|
+
return arr.every((a) => key(a) === k0);
|
|
1366
|
+
}
|
|
1367
|
+
|
|
1147
1368
|
class RdictTableTitle extends ToolBarToolComponent {
|
|
1148
1369
|
constructor() {
|
|
1149
1370
|
super();
|
|
@@ -1179,7 +1400,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.8", ngImpor
|
|
|
1179
1400
|
}] } });
|
|
1180
1401
|
|
|
1181
1402
|
class GenericRdictTableComponent {
|
|
1182
|
-
constructor(router, route, translate, injector, localFileService, rdict, dialogService) {
|
|
1403
|
+
constructor(router, route, translate, injector, localFileService, rdict, dialogService, intl) {
|
|
1183
1404
|
this.router = router;
|
|
1184
1405
|
this.route = route;
|
|
1185
1406
|
this.translate = translate;
|
|
@@ -1187,6 +1408,7 @@ class GenericRdictTableComponent {
|
|
|
1187
1408
|
this.localFileService = localFileService;
|
|
1188
1409
|
this.rdict = rdict;
|
|
1189
1410
|
this.dialogService = dialogService;
|
|
1411
|
+
this.intl = intl;
|
|
1190
1412
|
this.editOnClick = false;
|
|
1191
1413
|
this.editOnDblClick = false;
|
|
1192
1414
|
this.data = [];
|
|
@@ -1211,6 +1433,11 @@ class GenericRdictTableComponent {
|
|
|
1211
1433
|
this.svgEdit = pencilIcon;
|
|
1212
1434
|
this.svgDelete = trashIcon;
|
|
1213
1435
|
this.svgAdd = plusIcon;
|
|
1436
|
+
this.state = {
|
|
1437
|
+
skip: 0,
|
|
1438
|
+
take: 30
|
|
1439
|
+
};
|
|
1440
|
+
this.stateChange = new BehaviorSubject(this.state);
|
|
1214
1441
|
}
|
|
1215
1442
|
async ngOnInit() {
|
|
1216
1443
|
this.setValueFromSnapshot(this, this.route.snapshot, 'model', null);
|
|
@@ -1219,7 +1446,7 @@ class GenericRdictTableComponent {
|
|
|
1219
1446
|
this.setValueFromSnapshot(this, this.route.snapshot, 'searchFields', null);
|
|
1220
1447
|
this.setValueFromSnapshot(this, this.route.snapshot, 'customInclude', null);
|
|
1221
1448
|
this.setValueFromSnapshot(this, this.route.snapshot, 'defaultSort', null);
|
|
1222
|
-
this.setValueFromSnapshot(this, this.route.snapshot, 'defaultSortDirection',
|
|
1449
|
+
this.setValueFromSnapshot(this, this.route.snapshot, 'defaultSortDirection', null);
|
|
1223
1450
|
this.setValueFromSnapshot(this, this.route.snapshot, 'deletePropertyName', 'name');
|
|
1224
1451
|
this.setValueFromSnapshot(this, this.route.snapshot, 'defaultFilter', null);
|
|
1225
1452
|
this.setValueFromSnapshot(this, this.route.snapshot, 'showHeader', true);
|
|
@@ -1231,6 +1458,9 @@ class GenericRdictTableComponent {
|
|
|
1231
1458
|
this.setValueFromSnapshot(this, this.route.snapshot, 'editOnDblClick', false);
|
|
1232
1459
|
this.setValueFromSnapshot(this, this.route.snapshot, 'editColumn', null);
|
|
1233
1460
|
this.setValueFromSnapshot(this, this.route.snapshot, 'fileLayout', '');
|
|
1461
|
+
this.setValueFromSnapshot(this, this.route.snapshot, 'useView', false);
|
|
1462
|
+
this.setValueFromSnapshot(this, this.route.snapshot, 'pageable', false);
|
|
1463
|
+
this.setValueFromSnapshot(this, this.route.snapshot, 'pageSizes ', [10, 20, 30, 50, 100]);
|
|
1234
1464
|
const currentUrlSegments = this.router.url.split('/').map((segment) => new UrlSegment(segment, {}));
|
|
1235
1465
|
this.basePath = currentUrlSegments.map((segment) => segment.path).join('/');
|
|
1236
1466
|
const filteredSegments = currentUrlSegments.filter((segment) => segment.path !== '');
|
|
@@ -1244,9 +1474,20 @@ class GenericRdictTableComponent {
|
|
|
1244
1474
|
// Perform actions or update component as needed
|
|
1245
1475
|
}
|
|
1246
1476
|
});
|
|
1477
|
+
if (this.useView) {
|
|
1478
|
+
if (this.defaultSort) {
|
|
1479
|
+
this.state.sort = this.defaultSort;
|
|
1480
|
+
}
|
|
1481
|
+
await this.getParentDict();
|
|
1482
|
+
}
|
|
1247
1483
|
this.getListLayout();
|
|
1248
1484
|
this.loadData();
|
|
1249
1485
|
}
|
|
1486
|
+
async getParentDict() {
|
|
1487
|
+
const lastDotIndex = this.dictPath.lastIndexOf('.');
|
|
1488
|
+
const parentPath = lastDotIndex !== -1 ? this.dictPath.substring(0, lastDotIndex) : this.dictPath;
|
|
1489
|
+
this.parentDict = await this.rdict.asyncGet(parentPath);
|
|
1490
|
+
}
|
|
1250
1491
|
setValueFromSnapshot(component, snapshot, key, defaultValue) {
|
|
1251
1492
|
if (component[key] === undefined) {
|
|
1252
1493
|
let dataFromSnapshot = snapshot.data[key];
|
|
@@ -1256,7 +1497,11 @@ class GenericRdictTableComponent {
|
|
|
1256
1497
|
component[key] = dataFromSnapshot !== undefined ? dataFromSnapshot : defaultValue;
|
|
1257
1498
|
}
|
|
1258
1499
|
}
|
|
1259
|
-
|
|
1500
|
+
loadData() {
|
|
1501
|
+
if (this.useView) {
|
|
1502
|
+
this.loadDataView();
|
|
1503
|
+
return;
|
|
1504
|
+
}
|
|
1260
1505
|
this.rdict.get$(this.dictPath).subscribe({
|
|
1261
1506
|
next: (rdictData) => {
|
|
1262
1507
|
this.tableRdict = rdictData;
|
|
@@ -1282,6 +1527,22 @@ class GenericRdictTableComponent {
|
|
|
1282
1527
|
error: (err) => console.error('Error:', err.message)
|
|
1283
1528
|
});
|
|
1284
1529
|
}
|
|
1530
|
+
loadDataView() {
|
|
1531
|
+
//Get the parent path
|
|
1532
|
+
// const request = {
|
|
1533
|
+
// filters: '',
|
|
1534
|
+
// sorts: { import_date: 'desc' },
|
|
1535
|
+
// page: Math.floor(this.state.skip / this.state.take) + 1,
|
|
1536
|
+
// page_size: this.state.take
|
|
1537
|
+
// };
|
|
1538
|
+
const request = kendoToFilterRequest(this.state);
|
|
1539
|
+
this.parentDict.getFilteredView(this.model, request).subscribe({
|
|
1540
|
+
next: (view) => {
|
|
1541
|
+
// console.log('View:', view);
|
|
1542
|
+
this.dataSource = view;
|
|
1543
|
+
}
|
|
1544
|
+
});
|
|
1545
|
+
}
|
|
1285
1546
|
onChangeEvent(changes) {
|
|
1286
1547
|
if (changes) {
|
|
1287
1548
|
const key = changes?.key;
|
|
@@ -1357,6 +1618,7 @@ class GenericRdictTableComponent {
|
|
|
1357
1618
|
}
|
|
1358
1619
|
return item;
|
|
1359
1620
|
});
|
|
1621
|
+
// console.log('All columns:', this.allColumns);
|
|
1360
1622
|
//Get reference columns
|
|
1361
1623
|
const referenceColumns = this.allColumns.filter((item) => item.reference !== undefined && item.reference !== null);
|
|
1362
1624
|
if (referenceColumns.length > 0) {
|
|
@@ -1417,17 +1679,69 @@ class GenericRdictTableComponent {
|
|
|
1417
1679
|
}
|
|
1418
1680
|
if (column.type == 'reference') {
|
|
1419
1681
|
const value = this.referenceData.get(column.reference)?.get(item[column.propertyName])?.[column.referenceProperty] ?? item[column.propertyName];
|
|
1682
|
+
return this.formatValue(value, column.format);
|
|
1420
1683
|
return value;
|
|
1421
1684
|
}
|
|
1422
1685
|
else {
|
|
1423
|
-
return item[column.propertyName];
|
|
1686
|
+
return this.formatValue(item[column.propertyName], column.format);
|
|
1424
1687
|
}
|
|
1425
1688
|
}
|
|
1426
|
-
|
|
1427
|
-
|
|
1689
|
+
filterChange(filter) {
|
|
1690
|
+
// console.log(filter);
|
|
1691
|
+
// this.loadData();
|
|
1692
|
+
}
|
|
1693
|
+
dataStateChange(state) {
|
|
1694
|
+
this.state = state;
|
|
1695
|
+
this.loadData();
|
|
1696
|
+
}
|
|
1697
|
+
pageChange(state) {
|
|
1698
|
+
console.log('State:', state);
|
|
1699
|
+
this.stateChange.next(state);
|
|
1700
|
+
}
|
|
1701
|
+
formatValue(value, format) {
|
|
1702
|
+
if (value === null || value === undefined || !format) {
|
|
1703
|
+
return value ?? '';
|
|
1704
|
+
}
|
|
1705
|
+
// Accept both "{0:...}" and plain "..." patterns
|
|
1706
|
+
const inner = this.extractFormat(format);
|
|
1707
|
+
// Heuristics: date vs number
|
|
1708
|
+
if (this.looksLikeDateFormat(inner)) {
|
|
1709
|
+
const d = value instanceof Date ? value : new Date(value);
|
|
1710
|
+
return isNaN(d.getTime()) ? value : this.intl.formatDate(d, inner);
|
|
1711
|
+
}
|
|
1712
|
+
const num = typeof value === 'number' ? value : Number(value);
|
|
1713
|
+
if (!Number.isNaN(num)) {
|
|
1714
|
+
// supports "n", "n2", "c", "p", etc. and custom patterns
|
|
1715
|
+
return this.intl.formatNumber(num, inner);
|
|
1716
|
+
}
|
|
1717
|
+
// Fallback: return as-is if not a date/number
|
|
1718
|
+
return value;
|
|
1719
|
+
}
|
|
1720
|
+
extractFormat(fmt) {
|
|
1721
|
+
const m = fmt.match(/^\{0:([^}]+)\}$/);
|
|
1722
|
+
return m ? m[1] : fmt;
|
|
1723
|
+
}
|
|
1724
|
+
looksLikeDateFormat(f) {
|
|
1725
|
+
// crude but effective: typical date tokens
|
|
1726
|
+
return /d|M|y|H|h|m|s|E|a/.test(f) && !/^[cnp]/i.test(f);
|
|
1727
|
+
}
|
|
1728
|
+
inferFilterType(col) {
|
|
1729
|
+
if (!col)
|
|
1730
|
+
return 'text';
|
|
1731
|
+
const f = this.extractFormat(col.format || '');
|
|
1732
|
+
if (this.looksLikeDateFormat(f))
|
|
1733
|
+
return 'date';
|
|
1734
|
+
if (/^(n\d*|c|p\d*|n)$/i.test(f))
|
|
1735
|
+
return 'numeric'; // Kendo number patterns
|
|
1736
|
+
if (col.type === 'boolean')
|
|
1737
|
+
return 'boolean';
|
|
1738
|
+
return 'text';
|
|
1739
|
+
}
|
|
1740
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.8", ngImport: i0, type: GenericRdictTableComponent, deps: [{ token: i1.Router }, { token: i1.ActivatedRoute }, { token: i2.TranslateService }, { token: i0.Injector }, { token: i4.LocalFileService }, { token: ReactiveDictionary }, { token: MaterialDialogService }, { token: i6$2.IntlService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1741
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.8", type: GenericRdictTableComponent, isStandalone: true, selector: "rsl-rdict-generic-table", inputs: { showSerach: "showSerach", searchFields: "searchFields", customInclude: "customInclude", defaultSort: "defaultSort", deletePropertyName: "deletePropertyName", defaultFilter: "defaultFilter", showHeader: "showHeader", hasAdd: "hasAdd", canDelete: "canDelete", canEdit: "canEdit", editOnClick: "editOnClick", editOnDblClick: "editOnDblClick" }, outputs: { selectedObject: "selectedObject", click: "click", editModel: "editModel" }, providers: [], viewQueries: [{ propertyName: "filter", first: true, predicate: ElementRef, descendants: true }], ngImport: i0, template: "<kendo-grid [data]=\"dataSource\" [sortable]=\"true\" [filterable]=\"showSerach\" [resizable]=\"true\" (add)=\"addHandler()\"\r\n (edit)=\"editHandler($event)\" (remove)=\"removeHandler($event)\"\r\n (filterChange)=\"filterChange($event)\"\r\n (dataStateChange)=\"dataStateChange($event)\"\r\n \r\n [pageable]=\"{pageSizes:pageSizes}\" [pageSize]=\"state.take\"\r\n [skip]=\"state.skip\" [sort]=\"state.sort\" >\r\n <kendo-toolbar>\r\n <table-title text=\"{{title}}\"></table-title>\r\n <kendo-toolbar-messages>Test</kendo-toolbar-messages>\r\n <!-- <kendo-toolbar-separator></kendo-toolbar-separator> -->\r\n <kendo-toolbar-spacer></kendo-toolbar-spacer>\r\n <kendo-toolbar-button *ngIf=\"hasAdd\" kendoButton [svgIcon]=\"svgAdd\" text=\"Add new\" kendoGridAddTool></kendo-toolbar-button>\r\n </kendo-toolbar>\r\n\r\n <!-- <kendo-toolbar>\r\n \r\n <kendo-toolbar-spacer></kendo-toolbar-spacer>\r\n <button kendoGridAddCommand type=\"button\">Add new</button>\r\n </kendo-toolbar> -->\r\n <!-- <kendo-grid-column *ngFor=\"let column of allColumns\" field=\"{{ column.propertyName }}\"\r\n title=\" {{column.translateKey | translate}}\">\r\n </kendo-grid-column> -->\r\n\r\n <kendo-grid-column *ngFor=\"let column of allColumns\" [field]=\"column.propertyName\"\r\n [title]=\"column.translateKey | translate\" [format]=\"column.format\" [filter]=\"inferFilterType(column)\">\r\n <!-- Use ng-template to customize the column content -->\r\n <ng-template *ngIf=\"column.isEditLink; else defaultTemplate\" kendoGridCellTemplate let-dataItem>\r\n <!-- Create a link that calls editHandler(dataItem) -->\r\n <a href=\"javascript:void(0)\" (click)=\"edit(dataItem)\" class=\"edit-link\">\r\n {{ getCellValue(dataItem,column) }}\r\n </a>\r\n </ng-template>\r\n \r\n <!-- <ng-template *ngIf=\"column.type=='reference'; else defaultTemplate\" kendoGridCellTemplate let-dataItem>\r\n <a href=\"javascript:void(0)\" (click)=\"edit(dataItem)\" class=\"edit-link\">\r\n {{ getCellValue$(dataItem,column) | async }}\r\n </a>\r\n </ng-template> -->\r\n <!-- Default template for non-link columns -->\r\n <ng-template #defaultTemplate kendoGridCellTemplate let-dataItem>\r\n {{ getCellValue(dataItem,column) }}\r\n </ng-template>\r\n </kendo-grid-column>\r\n\r\n\r\n <kendo-grid-command-column *ngIf=\"canEdit && canDelete\" title=\"\" [width]=\"100\">\r\n <ng-template kendoGridCellTemplate>\r\n <!-- <button kendoButton kendoGridEditCommand [svgIcon]=\"svgEdit\" themeColor=\"light\" ></button>\r\n <button kendoButton kendoGridRemoveCommand [svgIcon]=\"svgDelete\" themeColor=\"error\"></button> -->\r\n <button *ngIf=\"canEdit\" kendoGridEditCommand [svgIcon]=\"svgEdit\" themeColor=\"light\"></button>\r\n <button *ngIf=\"canDelete\" kendoGridRemoveCommand [svgIcon]=\"svgDelete\" themeColor=\"error\"></button>\r\n </ng-template>\r\n </kendo-grid-command-column>\r\n</kendo-grid>\r\n<div kendoDialogContainer></div>", styles: [".edit-link{color:#00f!important;text-decoration:underline!important;cursor:pointer!important}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i7$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i7$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: RouterModule }, { kind: "ngmodule", type:
|
|
1428
1742
|
// MatPaginatorModule,
|
|
1429
1743
|
// MatTableModule,
|
|
1430
|
-
TranslateModule }, { kind: "pipe", type: i2.TranslatePipe, name: "translate" }, { kind: "component", type:
|
|
1744
|
+
TranslateModule }, { kind: "pipe", type: i2.TranslatePipe, name: "translate" }, { kind: "component", type: i8.GridComponent, selector: "kendo-grid", inputs: ["data", "pageSize", "height", "rowHeight", "detailRowHeight", "skip", "scrollable", "selectable", "sort", "size", "trackBy", "filter", "group", "virtualColumns", "filterable", "sortable", "pageable", "groupable", "gridResizable", "rowReorderable", "navigable", "navigatable", "autoSize", "rowClass", "rowSticky", "rowSelected", "isRowSelectable", "cellSelected", "resizable", "reorderable", "loading", "columnMenu", "hideHeader", "isDetailExpanded", "isGroupExpanded"], outputs: ["filterChange", "pageChange", "groupChange", "sortChange", "selectionChange", "rowReorder", "dataStateChange", "groupExpand", "groupCollapse", "detailExpand", "detailCollapse", "edit", "cancel", "save", "remove", "add", "cellClose", "cellClick", "pdfExport", "excelExport", "columnResize", "columnReorder", "columnVisibilityChange", "columnLockedChange", "columnStickyChange", "scrollBottom", "contentScroll"], exportAs: ["kendoGrid"] }, { kind: "directive", type: i8.GridToolbarFocusableDirective, selector: " [kendoGridToolbarFocusable], [kendoGridAddCommand], [kendoGridCancelCommand], [kendoGridEditCommand], [kendoGridRemoveCommand], [kendoGridSaveCommand], [kendoGridExcelCommand], [kendoGridPDFCommand] " }, { kind: "component", type: i8.ColumnComponent, selector: "kendo-grid-column", inputs: ["field", "format", "sortable", "groupable", "editor", "filter", "filterable", "editable"] }, { kind: "directive", type: i8.FocusableDirective, selector: "[kendoGridFocusable], [kendoGridEditCommand], [kendoGridRemoveCommand], [kendoGridSaveCommand], [kendoGridCancelCommand], [kendoGridSelectionCheckbox] ", inputs: ["kendoGridFocusable"] }, { kind: "component", type: i8.CommandColumnComponent, selector: "kendo-grid-command-column" }, { kind: "directive", type: i8.CellTemplateDirective, selector: "[kendoGridCellTemplate]" }, { kind: "component", type: i8.EditCommandDirective, selector: "[kendoGridEditCommand]" }, { kind: "component", type: i8.RemoveCommandDirective, selector: "[kendoGridRemoveCommand]" }, { kind: "directive", type: i8.AddCommandToolbarDirective, selector: "[kendoGridAddTool]" }, { kind: "component", type: i9.ToolBarComponent, selector: "kendo-toolbar", inputs: ["overflow", "resizable", "popupSettings", "fillMode", "tabindex", "size", "tabIndex"], outputs: ["open", "close"], exportAs: ["kendoToolBar"] }, { kind: "component", type: i9.ToolbarCustomMessagesComponent, selector: "kendo-toolbar-messages" }, { kind: "component", type: i9.ToolBarButtonComponent, selector: "kendo-toolbar-button", inputs: ["showText", "showIcon", "text", "style", "className", "title", "disabled", "toggleable", "look", "togglable", "selected", "fillMode", "themeColor", "icon", "iconClass", "svgIcon", "imageUrl"], outputs: ["click", "pointerdown", "selectedChange"], exportAs: ["kendoToolBarButton"] }, { kind: "component", type: i9.ToolBarSpacerComponent, selector: "kendo-toolbar-spacer", exportAs: ["kendoToolBarSpacer"] }, { kind: "directive", type: i2$1.DialogContainerDirective, selector: "[kendoDialogContainer]" }, { kind: "component", type: RdictTableTitle, selector: "table-title", inputs: ["text"] }], encapsulation: i0.ViewEncapsulation.None }); }
|
|
1431
1745
|
}
|
|
1432
1746
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.8", ngImport: i0, type: GenericRdictTableComponent, decorators: [{
|
|
1433
1747
|
type: Component,
|
|
@@ -1443,8 +1757,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.8", ngImpor
|
|
|
1443
1757
|
KENDO_BUTTONS,
|
|
1444
1758
|
KENDO_DIALOG,
|
|
1445
1759
|
RdictTableTitle
|
|
1446
|
-
], providers: [], template: "<kendo-grid
|
|
1447
|
-
}], ctorParameters: () => [{ type: i1.Router }, { type: i1.ActivatedRoute }, { type: i2.TranslateService }, { type: i0.Injector }, { type: i4.LocalFileService }, { type: ReactiveDictionary }, { type: MaterialDialogService }], propDecorators: { showSerach: [{
|
|
1760
|
+
], providers: [], template: "<kendo-grid [data]=\"dataSource\" [sortable]=\"true\" [filterable]=\"showSerach\" [resizable]=\"true\" (add)=\"addHandler()\"\r\n (edit)=\"editHandler($event)\" (remove)=\"removeHandler($event)\"\r\n (filterChange)=\"filterChange($event)\"\r\n (dataStateChange)=\"dataStateChange($event)\"\r\n \r\n [pageable]=\"{pageSizes:pageSizes}\" [pageSize]=\"state.take\"\r\n [skip]=\"state.skip\" [sort]=\"state.sort\" >\r\n <kendo-toolbar>\r\n <table-title text=\"{{title}}\"></table-title>\r\n <kendo-toolbar-messages>Test</kendo-toolbar-messages>\r\n <!-- <kendo-toolbar-separator></kendo-toolbar-separator> -->\r\n <kendo-toolbar-spacer></kendo-toolbar-spacer>\r\n <kendo-toolbar-button *ngIf=\"hasAdd\" kendoButton [svgIcon]=\"svgAdd\" text=\"Add new\" kendoGridAddTool></kendo-toolbar-button>\r\n </kendo-toolbar>\r\n\r\n <!-- <kendo-toolbar>\r\n \r\n <kendo-toolbar-spacer></kendo-toolbar-spacer>\r\n <button kendoGridAddCommand type=\"button\">Add new</button>\r\n </kendo-toolbar> -->\r\n <!-- <kendo-grid-column *ngFor=\"let column of allColumns\" field=\"{{ column.propertyName }}\"\r\n title=\" {{column.translateKey | translate}}\">\r\n </kendo-grid-column> -->\r\n\r\n <kendo-grid-column *ngFor=\"let column of allColumns\" [field]=\"column.propertyName\"\r\n [title]=\"column.translateKey | translate\" [format]=\"column.format\" [filter]=\"inferFilterType(column)\">\r\n <!-- Use ng-template to customize the column content -->\r\n <ng-template *ngIf=\"column.isEditLink; else defaultTemplate\" kendoGridCellTemplate let-dataItem>\r\n <!-- Create a link that calls editHandler(dataItem) -->\r\n <a href=\"javascript:void(0)\" (click)=\"edit(dataItem)\" class=\"edit-link\">\r\n {{ getCellValue(dataItem,column) }}\r\n </a>\r\n </ng-template>\r\n \r\n <!-- <ng-template *ngIf=\"column.type=='reference'; else defaultTemplate\" kendoGridCellTemplate let-dataItem>\r\n <a href=\"javascript:void(0)\" (click)=\"edit(dataItem)\" class=\"edit-link\">\r\n {{ getCellValue$(dataItem,column) | async }}\r\n </a>\r\n </ng-template> -->\r\n <!-- Default template for non-link columns -->\r\n <ng-template #defaultTemplate kendoGridCellTemplate let-dataItem>\r\n {{ getCellValue(dataItem,column) }}\r\n </ng-template>\r\n </kendo-grid-column>\r\n\r\n\r\n <kendo-grid-command-column *ngIf=\"canEdit && canDelete\" title=\"\" [width]=\"100\">\r\n <ng-template kendoGridCellTemplate>\r\n <!-- <button kendoButton kendoGridEditCommand [svgIcon]=\"svgEdit\" themeColor=\"light\" ></button>\r\n <button kendoButton kendoGridRemoveCommand [svgIcon]=\"svgDelete\" themeColor=\"error\"></button> -->\r\n <button *ngIf=\"canEdit\" kendoGridEditCommand [svgIcon]=\"svgEdit\" themeColor=\"light\"></button>\r\n <button *ngIf=\"canDelete\" kendoGridRemoveCommand [svgIcon]=\"svgDelete\" themeColor=\"error\"></button>\r\n </ng-template>\r\n </kendo-grid-command-column>\r\n</kendo-grid>\r\n<div kendoDialogContainer></div>", styles: [".edit-link{color:#00f!important;text-decoration:underline!important;cursor:pointer!important}\n"] }]
|
|
1761
|
+
}], ctorParameters: () => [{ type: i1.Router }, { type: i1.ActivatedRoute }, { type: i2.TranslateService }, { type: i0.Injector }, { type: i4.LocalFileService }, { type: ReactiveDictionary }, { type: MaterialDialogService }, { type: i6$2.IntlService }], propDecorators: { showSerach: [{
|
|
1448
1762
|
type: Input
|
|
1449
1763
|
}], searchFields: [{
|
|
1450
1764
|
type: Input
|