@rosoftlab/rdict 1.0.3-alpha-2 → 1.0.4-alpha-1

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.
@@ -1,4 +1,4 @@
1
- import * as i6$2 from '@angular/common';
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 i8 from '@progress/kendo-angular-toolbar';
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, tap, map } from 'rxjs';
18
+ import { Subject, fromEvent, Observable, defer, mergeMap, filter, race, first, map, timeout, from, tap, catchError, throwError, 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,13 +29,15 @@ 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 i7$1 from '@progress/kendo-angular-grid';
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) {
40
+ this.disconnect$ = new Subject();
39
41
  this.socketUrl = socketUrl;
40
42
  // Replace with your actual server URL
41
43
  // this.socket.on("connect", () => {
@@ -50,12 +52,22 @@ class SocketService {
50
52
  initSocket(authToken) {
51
53
  if (this.socket == null && authToken !== null) {
52
54
  this.socket = io(this.socketUrl, {
55
+ reconnectionDelayMax: 10000,
56
+ transports: ['websocket'],
53
57
  withCredentials: true,
58
+ //ackTimeout: 60000,
59
+ timeout: 60000,
60
+ //retries: 50,
54
61
  // parser: msgpackParser,
55
62
  auth: {
56
63
  token: authToken // Include the authentication token
57
64
  }
58
65
  });
66
+ this.result$ = fromEvent(this.socket, 'function_result');
67
+ this.error$ = fromEvent(this.socket, 'function_error');
68
+ this.disconnected$ = fromEvent(this.socket, 'disconnect');
69
+ // When socket disconnects, push to our teardown subject
70
+ this.disconnected$.subscribe(() => this.disconnect$.next());
59
71
  }
60
72
  }
61
73
  getInitialData() {
@@ -121,7 +133,8 @@ class SocketService {
121
133
  observer.error(response.error);
122
134
  }
123
135
  else {
124
- observer.next(response);
136
+ const transformedResponse = this.convertDates(response);
137
+ observer.next(transformedResponse);
125
138
  observer.complete();
126
139
  }
127
140
  });
@@ -132,29 +145,27 @@ class SocketService {
132
145
  };
133
146
  });
134
147
  }
135
- executeFunction(did, functionName, args = [], kwargs = {}) {
136
- const payload = {
137
- did,
138
- function_name: functionName,
139
- ...(args && args.length ? { args } : {}),
140
- ...(kwargs && Object.keys(kwargs).length ? { kwargs } : {})
141
- };
142
- return new Observable((observer) => {
143
- this.socket.emit('execute_function', payload, (response) => {
144
- if (response && response.error) {
145
- observer.error(response.error);
148
+ convertDates(obj) {
149
+ if (obj === null || obj === undefined)
150
+ return obj;
151
+ if (Array.isArray(obj)) {
152
+ return obj.map((item) => this.convertDates(item));
153
+ }
154
+ if (typeof obj === 'object') {
155
+ const newObj = {};
156
+ for (const key of Object.keys(obj)) {
157
+ const value = obj[key];
158
+ // detect ISO date strings
159
+ if (typeof value === 'string' && /^\d{4}-\d{2}-\d{2}[ T]\d/.test(value)) {
160
+ newObj[key] = new Date(value.replace(' ', 'T')); // replace space with T for safety
146
161
  }
147
162
  else {
148
- observer.next(response);
149
- observer.complete();
163
+ newObj[key] = this.convertDates(value); // recurse
150
164
  }
151
- });
152
- // teardown logic if subscriber unsubscribes before callback fires
153
- return () => {
154
- // no direct way to cancel a single emit/callback in socket.io,
155
- // but you could optionally remove a listener here if you used on(...)
156
- };
157
- });
165
+ }
166
+ return newObj;
167
+ }
168
+ return obj;
158
169
  }
159
170
  // Emit the 'set' event to update the data on the server
160
171
  emitSet(did, key, value) {
@@ -209,6 +220,67 @@ class SocketService {
209
220
  }
210
221
  return obj;
211
222
  }
223
+ //#region executeFunction
224
+ executeFunction_old(did, functionName, args = [], kwargs = {}) {
225
+ const payload = {
226
+ did,
227
+ function_name: functionName,
228
+ ...(args && args.length ? { args } : {}),
229
+ ...(kwargs && Object.keys(kwargs).length ? { kwargs } : {})
230
+ };
231
+ return new Observable((observer) => {
232
+ this.socket.emit('execute_function', payload, (response) => {
233
+ if (response && response.error) {
234
+ observer.error(response.error);
235
+ }
236
+ else {
237
+ observer.next(response);
238
+ observer.complete();
239
+ }
240
+ });
241
+ // teardown logic if subscriber unsubscribes before callback fires
242
+ return () => {
243
+ // no direct way to cancel a single emit/callback in socket.io,
244
+ // but you could optionally remove a listener here if you used on(...)
245
+ };
246
+ });
247
+ }
248
+ executeFunction(did, functionName, args = [], kwargs = {}, waitMs = 120_000, awaitResult = true) {
249
+ const payload = {
250
+ did,
251
+ function_name: functionName,
252
+ ...(args?.length ? { args } : {}),
253
+ ...(kwargs && Object.keys(kwargs).length ? { kwargs } : {})
254
+ };
255
+ const ack$ = new Observable((observer) => {
256
+ this.socket.emit('execute_function', payload, (ack) => {
257
+ observer.next(ack);
258
+ observer.complete();
259
+ });
260
+ return () => { };
261
+ });
262
+ if (!awaitResult) {
263
+ // Return immediately with the server ACK
264
+ return ack$;
265
+ }
266
+ // Wait for function_result / function_error matching the job_id
267
+ return defer(() => ack$).pipe(mergeMap((ack) => {
268
+ if (!ack?.ok || !ack.job_id) {
269
+ const msg = ack?.error ?? 'Bad ACK or missing job_id';
270
+ throw new Error(typeof msg === 'string' ? msg : JSON.stringify(msg));
271
+ }
272
+ const jobId = ack.job_id;
273
+ const jobResult$ = this.result$.pipe(filter((e) => e.job_id === jobId));
274
+ const jobError$ = this.error$.pipe(filter((e) => e.job_id === jobId));
275
+ return race(jobResult$, jobError$).pipe(first(), map((evt) => {
276
+ if (evt?.ok === false) {
277
+ const msg = evt.error ?? `Server error for ${functionName} (job ${jobId})`;
278
+ throw new Error(typeof msg === 'string' ? msg : JSON.stringify(msg));
279
+ }
280
+ return evt.result;
281
+ }));
282
+ }), timeout(waitMs));
283
+ }
212
284
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.8", ngImport: i0, type: SocketService, deps: [{ token: SOCKET_URL }], target: i0.ɵɵFactoryTarget.Injectable }); }
213
285
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.8", ngImport: i0, type: SocketService, providedIn: 'root' }); }
214
286
  }
@@ -494,24 +566,22 @@ class ReactiveDictionary extends Map {
494
566
  }
495
567
  getFilteredView(key, request) {
496
568
  const guid = this.get('__guid'); // however you’re retrieving it
497
- return this._socketService.requestFilteredData(guid, key, request).pipe(
498
- // tap((data) => {
499
- // // you can still inspect/log the data here if you like
500
- // console.log('received filtered view:', data);
501
- // }),
502
- catchError((err) => {
569
+ return this._socketService.requestFilteredData(guid, key, request).pipe(tap((data) => {
570
+ // you can still inspect/log the data here if you like
571
+ // console.log('received filtered view:', data);
572
+ }), catchError((err) => {
503
573
  console.error('Error fetching filtered view:', err);
504
574
  // re-throw so subscribers can handle it
505
575
  return throwError(() => err);
506
576
  }));
507
577
  }
508
- executeFunction(functionName, args = [], kwargs = {}) {
578
+ executeFunction(functionName, args = [], kwargs = {}, waitMs = 120_000, awaitResult = true) {
509
579
  const guid = this.get('__guid'); // however you’re retrieving it
510
- return this._socketService.executeFunction(guid, functionName, args, kwargs).pipe(tap((data) => {
580
+ return this._socketService.executeFunction(guid, functionName, args, kwargs, waitMs, awaitResult).pipe(tap((data) => {
511
581
  // you can still inspect/log the data here if you like
512
- console.log('received filtered view:', data);
582
+ console.log('received execute function:', data);
513
583
  }), catchError((err) => {
514
- console.error('Error fetching filtered view:', err);
584
+ console.error('Error execute function:', err);
515
585
  // re-throw so subscribers can handle it
516
586
  return throwError(() => err);
517
587
  }));
@@ -1123,7 +1193,7 @@ class RdictCrudComponent {
1123
1193
  }
1124
1194
  }
1125
1195
  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: i8.ToolBarComponent, selector: "kendo-toolbar", inputs: ["overflow", "resizable", "popupSettings", "fillMode", "tabindex", "size", "tabIndex"], outputs: ["open", "close"], exportAs: ["kendoToolBar"] }, { kind: "component", type: i8.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: i8.ToolBarSpacerComponent, selector: "kendo-toolbar-spacer", exportAs: ["kendoToolBarSpacer"] }, { kind: "directive", type: i2$1.DialogContainerDirective, selector: "[kendoDialogContainer]" }] }); }
1196
+ 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
1197
  }
1128
1198
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.8", ngImport: i0, type: RdictCrudComponent, decorators: [{
1129
1199
  type: Component,
@@ -1144,6 +1214,205 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.8", ngImpor
1144
1214
  args: ['class']
1145
1215
  }] } });
1146
1216
 
1217
+ /** Main mapper */
1218
+ function kendoToFilterRequest(e) {
1219
+ const { skip = 0, take = 0, sort, filter, group } = e ?? e;
1220
+ const page_size = take || undefined;
1221
+ const page = take ? Math.floor(skip / take) + 1 : undefined;
1222
+ return {
1223
+ page,
1224
+ page_size,
1225
+ sorts: kendoSortsToDict(sort),
1226
+ filters: kendoFilterToSieve(filter),
1227
+ group_by: kendoGroupToArray(group)
1228
+ // distinctColumns: fill if you use a “distinct” mode in your API
1229
+ };
1230
+ }
1231
+ /* ------------------------------- Sorts ---------------------------------- */
1232
+ function kendoSortsToDict(sorts) {
1233
+ if (!sorts?.length)
1234
+ return undefined;
1235
+ const result = {};
1236
+ for (const s of sorts) {
1237
+ if (!s.field)
1238
+ continue;
1239
+ result[s.field] = (s.dir ?? 'asc');
1240
+ }
1241
+ return result;
1242
+ }
1243
+ /* ---------------- GroupBy as array ---------------- */
1244
+ function kendoGroupToArray(group) {
1245
+ if (!group?.length)
1246
+ return undefined;
1247
+ return group.map((g) => g.field);
1248
+ }
1249
+ /* ------------------------------ Filters --------------------------------- */
1250
+ /**
1251
+ * Converts Kendo filter tree to a Sieve filter string.
1252
+ * Notes (Sieve):
1253
+ * - Clause is {Name}{Operator}{Value}, AND with commas, simple OR via:
1254
+ * - multiple names: (Field1|Field2)opValue
1255
+ * - multiple values: Field@=a|b
1256
+ * - Operators: ==, !=, >, <, >=, <=, @= (contains), _= (starts), _-= (ends),
1257
+ * and case-insensitive variants like @=* etc. :contentReference[oaicite:1]{index=1}
1258
+ */
1259
+ function kendoFilterToSieve(node) {
1260
+ if (!node)
1261
+ return undefined;
1262
+ if (isLeaf(node)) {
1263
+ const op = mapOperator(node.operator, !!node.ignoreCase, node.value);
1264
+ if (!op)
1265
+ return undefined; // unsupported operator (e.g., isnull/isnotnull)
1266
+ const name = node.field;
1267
+ const value = formatSieveValue(node.value);
1268
+ return `${name}${op}${value}`;
1269
+ }
1270
+ // Composite: best-effort mapping.
1271
+ // AND → comma-join
1272
+ // OR → try to compress same-field same-op OR into value pipes; otherwise fall back to (Field1|Field2)opValue when viable.
1273
+ const parts = node.filters.map((f) => kendoFilterToSieve(f)).filter(Boolean);
1274
+ if (!parts.length)
1275
+ return undefined;
1276
+ if (node.logic === 'and') {
1277
+ return parts.join(',');
1278
+ }
1279
+ // OR logic – try simple compressions; if not possible, return a comma-joined set of grouped OR chunks when possible.
1280
+ // Heuristic: if all parts share the same {field,op} with different values → merge via value pipes.
1281
+ const parsed = parts.map(parseClause).filter(Boolean);
1282
+ if (parsed.length && allSame(parsed, (c) => `${c.name}|${c.op}`)) {
1283
+ const { name, op } = parsed[0];
1284
+ const pipedValues = parsed.map((c) => c.value).join('|');
1285
+ return `${name}${op}${pipedValues}`;
1286
+ }
1287
+ // If all parts share same {op,value} but different fields → (A|B)opV
1288
+ if (parsed.length && allSame(parsed, (c) => `${c.op}|${c.value}`)) {
1289
+ const fields = parsed.map((c) => c.name).join('|');
1290
+ const { op, value } = parsed[0];
1291
+ return `(${fields})${op}${value}`;
1292
+ }
1293
+ // Fallback: join with Sieve’s AND (comma). (General mixed OR trees can’t always be represented in Sieve DSL.
1294
+ // If you need exact semantics, consider adding a custom Sieve filter.) :contentReference[oaicite:2]{index=2}
1295
+ return parts.join(',');
1296
+ }
1297
+ /* ----------------------------- Helpers ---------------------------------- */
1298
+ function isLeaf(f) {
1299
+ return f.filters === undefined;
1300
+ }
1301
+ // Map Kendo operators to Sieve operators (case-insensitive variants when ignoreCase=true)
1302
+ function mapOperator(kendoOp, ignoreCase, value) {
1303
+ // Kendo operators list: eq, neq, lt, lte, gt, gte, contains, doesnotcontain, startswith, endswith,
1304
+ // isnull, isnotnull, isempty, isnotempty
1305
+ // Sieve operators: ==, !=, <, <=, >, >=, @=, !@=, _=, _-=, and their * variants for case-insensitive. :contentReference[oaicite:3]{index=3}
1306
+ const strOps = {
1307
+ contains: '@=',
1308
+ doesnotcontain: '!@=',
1309
+ startswith: '_=',
1310
+ endswith: '_-='
1311
+ };
1312
+ const base = (() => {
1313
+ switch (kendoOp) {
1314
+ case 'eq':
1315
+ return '==';
1316
+ case 'neq':
1317
+ return '!=';
1318
+ case 'lt':
1319
+ return '<';
1320
+ case 'lte':
1321
+ return '<=';
1322
+ case 'gt':
1323
+ return '>';
1324
+ case 'gte':
1325
+ return '>=';
1326
+ case 'contains':
1327
+ return strOps.contains;
1328
+ case 'doesnotcontain':
1329
+ return strOps.doesnotcontain;
1330
+ case 'startswith':
1331
+ return strOps.startswith;
1332
+ case 'endswith':
1333
+ return strOps.endswith;
1334
+ case 'isempty':
1335
+ return '=='; // value should be ''
1336
+ case 'isnotempty':
1337
+ return '!='; // value should be ''
1338
+ // isnull / isnotnull don’t have a native Sieve op. Recommend a custom filter on the API.
1339
+ case 'isnull':
1340
+ case 'isnotnull':
1341
+ return undefined;
1342
+ default:
1343
+ return undefined;
1344
+ }
1345
+ })();
1346
+ if (!base)
1347
+ return undefined;
1348
+ // Promote to case-insensitive *only* for string-y ops when requested
1349
+ const isStringy = ['@=', '!@=', '_=', '_-='].includes(base) || typeof value === 'string';
1350
+ if (ignoreCase && isStringy) {
1351
+ // Sieve: case-insensitive variants add a trailing * (e.g., @=*). :contentReference[oaicite:4]{index=4}
1352
+ return base.endsWith('*') ? base : `${base}*`;
1353
+ }
1354
+ return base;
1355
+ }
1356
+ function formatSieveValue(v) {
1357
+ if (v === '' || v === null || v === undefined)
1358
+ return '';
1359
+ if (v instanceof Date)
1360
+ return toISO(v);
1361
+ // Kendo may send dates as strings – try to detect ISO-like and pass through
1362
+ if (typeof v === 'string' && isDateLike(v))
1363
+ return v;
1364
+ if (typeof v === 'string')
1365
+ return escapeSieve(v);
1366
+ if (typeof v === 'number' || typeof v === 'bigint' || typeof v === 'boolean')
1367
+ return String(v);
1368
+ // Arrays can appear with “in” like semantics via OR; join with pipes
1369
+ if (Array.isArray(v))
1370
+ return v.map(formatSieveValue).join('|');
1371
+ // Fallback to JSON (rare)
1372
+ return escapeSieve(JSON.stringify(v));
1373
+ }
1374
+ function toISO(d) {
1375
+ // Prefer full ISO so the API can parse reliably
1376
+ // return new Date(d).toISOString();
1377
+ const y = d.getFullYear();
1378
+ const m = String(d.getMonth() + 1).padStart(2, '0');
1379
+ const day = String(d.getDate()).padStart(2, '0');
1380
+ const hh = String(d.getHours()).padStart(2, '0');
1381
+ const mm = String(d.getMinutes()).padStart(2, '0');
1382
+ const ss = String(d.getSeconds()).padStart(2, '0');
1383
+ return `${y}-${m}-${day}T${hh}:${mm}:${ss}`;
1384
+ }
1385
+ function isDateLike(s) {
1386
+ // very lenient check
1387
+ return /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}/.test(s);
1388
+ }
1389
+ function escapeSieve(s) {
1390
+ // Sieve escaping: backslash to escape commas and pipes (and the backslash itself). :contentReference[oaicite:5]{index=5}
1391
+ return s.replace(/([\\,|])/g, '\\$1');
1392
+ }
1393
+ /** Parses "NameOPValue" (no commas) into {name,op,value} */
1394
+ function parseClause(clause) {
1395
+ // Operators (longer first)
1396
+ const ops = ['==*', '!=*', '@=*', '!@=*', '_=*', '!_=*', '_-=*', '==', '!=', '>=', '<=', '>', '<', '@=', '!@=', '_=', '_-='];
1397
+ for (const op of ops) {
1398
+ const idx = clause.indexOf(op);
1399
+ if (idx > 0) {
1400
+ return {
1401
+ name: clause.slice(0, idx),
1402
+ op,
1403
+ value: clause.slice(idx + op.length)
1404
+ };
1405
+ }
1406
+ }
1407
+ return null;
1408
+ }
1409
+ function allSame(arr, key) {
1410
+ if (!arr.length)
1411
+ return true;
1412
+ const k0 = key(arr[0]);
1413
+ return arr.every((a) => key(a) === k0);
1414
+ }
1415
+
1147
1416
  class RdictTableTitle extends ToolBarToolComponent {
1148
1417
  constructor() {
1149
1418
  super();
@@ -1179,7 +1448,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.8", ngImpor
1179
1448
  }] } });
1180
1449
 
1181
1450
  class GenericRdictTableComponent {
1182
- constructor(router, route, translate, injector, localFileService, rdict, dialogService) {
1451
+ constructor(router, route, translate, injector, localFileService, rdict, dialogService, intl) {
1183
1452
  this.router = router;
1184
1453
  this.route = route;
1185
1454
  this.translate = translate;
@@ -1187,6 +1456,7 @@ class GenericRdictTableComponent {
1187
1456
  this.localFileService = localFileService;
1188
1457
  this.rdict = rdict;
1189
1458
  this.dialogService = dialogService;
1459
+ this.intl = intl;
1190
1460
  this.editOnClick = false;
1191
1461
  this.editOnDblClick = false;
1192
1462
  this.data = [];
@@ -1211,6 +1481,11 @@ class GenericRdictTableComponent {
1211
1481
  this.svgEdit = pencilIcon;
1212
1482
  this.svgDelete = trashIcon;
1213
1483
  this.svgAdd = plusIcon;
1484
+ this.state = {
1485
+ skip: 0,
1486
+ take: 30
1487
+ };
1488
+ this.stateChange = new BehaviorSubject(this.state);
1214
1489
  }
1215
1490
  async ngOnInit() {
1216
1491
  this.setValueFromSnapshot(this, this.route.snapshot, 'model', null);
@@ -1219,7 +1494,7 @@ class GenericRdictTableComponent {
1219
1494
  this.setValueFromSnapshot(this, this.route.snapshot, 'searchFields', null);
1220
1495
  this.setValueFromSnapshot(this, this.route.snapshot, 'customInclude', null);
1221
1496
  this.setValueFromSnapshot(this, this.route.snapshot, 'defaultSort', null);
1222
- this.setValueFromSnapshot(this, this.route.snapshot, 'defaultSortDirection', '');
1497
+ this.setValueFromSnapshot(this, this.route.snapshot, 'defaultSortDirection', null);
1223
1498
  this.setValueFromSnapshot(this, this.route.snapshot, 'deletePropertyName', 'name');
1224
1499
  this.setValueFromSnapshot(this, this.route.snapshot, 'defaultFilter', null);
1225
1500
  this.setValueFromSnapshot(this, this.route.snapshot, 'showHeader', true);
@@ -1231,6 +1506,9 @@ class GenericRdictTableComponent {
1231
1506
  this.setValueFromSnapshot(this, this.route.snapshot, 'editOnDblClick', false);
1232
1507
  this.setValueFromSnapshot(this, this.route.snapshot, 'editColumn', null);
1233
1508
  this.setValueFromSnapshot(this, this.route.snapshot, 'fileLayout', '');
1509
+ this.setValueFromSnapshot(this, this.route.snapshot, 'useView', false);
1510
+ this.setValueFromSnapshot(this, this.route.snapshot, 'pageable', false);
1511
+ this.setValueFromSnapshot(this, this.route.snapshot, 'pageSizes ', [10, 20, 30, 50, 100]);
1234
1512
  const currentUrlSegments = this.router.url.split('/').map((segment) => new UrlSegment(segment, {}));
1235
1513
  this.basePath = currentUrlSegments.map((segment) => segment.path).join('/');
1236
1514
  const filteredSegments = currentUrlSegments.filter((segment) => segment.path !== '');
@@ -1244,9 +1522,20 @@ class GenericRdictTableComponent {
1244
1522
  // Perform actions or update component as needed
1245
1523
  }
1246
1524
  });
1525
+ if (this.useView) {
1526
+ if (this.defaultSort) {
1527
+ this.state.sort = this.defaultSort;
1528
+ }
1529
+ await this.getParentDict();
1530
+ }
1247
1531
  this.getListLayout();
1248
1532
  this.loadData();
1249
1533
  }
1534
+ async getParentDict() {
1535
+ const lastDotIndex = this.dictPath.lastIndexOf('.');
1536
+ const parentPath = lastDotIndex !== -1 ? this.dictPath.substring(0, lastDotIndex) : this.dictPath;
1537
+ this.parentDict = await this.rdict.asyncGet(parentPath);
1538
+ }
1250
1539
  setValueFromSnapshot(component, snapshot, key, defaultValue) {
1251
1540
  if (component[key] === undefined) {
1252
1541
  let dataFromSnapshot = snapshot.data[key];
@@ -1256,7 +1545,11 @@ class GenericRdictTableComponent {
1256
1545
  component[key] = dataFromSnapshot !== undefined ? dataFromSnapshot : defaultValue;
1257
1546
  }
1258
1547
  }
1259
- async loadData() {
1548
+ loadData() {
1549
+ if (this.useView) {
1550
+ this.loadDataView();
1551
+ return;
1552
+ }
1260
1553
  this.rdict.get$(this.dictPath).subscribe({
1261
1554
  next: (rdictData) => {
1262
1555
  this.tableRdict = rdictData;
@@ -1282,23 +1575,61 @@ class GenericRdictTableComponent {
1282
1575
  error: (err) => console.error('Error:', err.message)
1283
1576
  });
1284
1577
  }
1578
+ loadDataView() {
1579
+ //Get the parent path
1580
+ // const request = {
1581
+ // filters: '',
1582
+ // sorts: { import_date: 'desc' },
1583
+ // page: Math.floor(this.state.skip / this.state.take) + 1,
1584
+ // page_size: this.state.take
1585
+ // };
1586
+ const request = kendoToFilterRequest(this.state);
1587
+ this.parentDict.getFilteredView(this.model, request).subscribe({
1588
+ next: (view) => {
1589
+ // console.log('View:', view);
1590
+ this.dataSource = view;
1591
+ }
1592
+ });
1593
+ }
1285
1594
  onChangeEvent(changes) {
1286
1595
  if (changes) {
1287
1596
  const key = changes?.key;
1288
1597
  const value = changes?.value;
1289
- if (key && value) {
1290
- const index = this.dataSource.findIndex((item) => item.__idx === key);
1291
- if (index > -1) {
1292
- this.dataSource[index] = value;
1598
+ if (key == 'transactions') {
1599
+ //I have receibed transactions update
1600
+ //Update all transactions in the table
1601
+ const transactions = value;
1602
+ for (const [key, value] of Object.entries(transactions)) {
1603
+ const index = this.dataSource.findIndex((item) => item.__idx === key);
1604
+ if (index > -1) {
1605
+ this.dataSource[index] = value;
1606
+ }
1607
+ else {
1608
+ //get the object from rdict
1609
+ // this.tableRdict.get$(key).subscribe({
1610
+ // next: (value) => {
1611
+ // var dd = value.getPlainObject();
1612
+ this.dataSource.push(value);
1613
+ // }
1614
+ // });
1615
+ }
1293
1616
  }
1294
- else {
1295
- //get the object from rdict
1296
- this.tableRdict.get$(key).subscribe({
1297
- next: (value) => {
1298
- var dd = value.getPlainObject();
1299
- this.dataSource.push(dd);
1300
- }
1301
- });
1617
+ }
1618
+ else {
1619
+ if (key && value) {
1620
+ const index = this.dataSource.findIndex((item) => item.__idx === key);
1621
+ if (index > -1) {
1622
+ this.dataSource[index] = value;
1623
+ }
1624
+ else {
1625
+ //get the object from rdict
1626
+ this.tableRdict.get$(key).subscribe({
1627
+ next: (value) => {
1628
+ var dd = value.getPlainObject();
1629
+ this.dataSource.push(dd);
1630
+ }
1631
+ });
1632
+ }
1302
1633
  }
1303
1634
  }
1304
1635
  }
@@ -1357,6 +1688,7 @@ class GenericRdictTableComponent {
1357
1688
  }
1358
1689
  return item;
1359
1690
  });
1691
+ // console.log('All columns:', this.allColumns);
1360
1692
  //Get reference columns
1361
1693
  const referenceColumns = this.allColumns.filter((item) => item.reference !== undefined && item.reference !== null);
1362
1694
  if (referenceColumns.length > 0) {
@@ -1417,17 +1749,69 @@ class GenericRdictTableComponent {
1417
1749
  }
1418
1750
  if (column.type == 'reference') {
1419
1751
  const value = this.referenceData.get(column.reference)?.get(item[column.propertyName])?.[column.referenceProperty] ?? item[column.propertyName];
1752
+ return this.formatValue(value, column.format);
1420
1753
  return value;
1421
1754
  }
1422
1755
  else {
1423
- return item[column.propertyName];
1756
+ return this.formatValue(item[column.propertyName], column.format);
1757
+ }
1758
+ }
1759
+ filterChange(filter) {
1760
+ // console.log(filter);
1761
+ // this.loadData();
1762
+ }
1763
+ dataStateChange(state) {
1764
+ this.state = state;
1765
+ this.loadData();
1766
+ }
1767
+ pageChange(state) {
1768
+ console.log('State:', state);
1769
+ this.stateChange.next(state);
1770
+ }
1771
+ formatValue(value, format) {
1772
+ if (value === null || value === undefined || !format) {
1773
+ return value ?? '';
1424
1774
  }
1775
+ // Accept both "{0:...}" and plain "..." patterns
1776
+ const inner = this.extractFormat(format);
1777
+ // Heuristics: date vs number
1778
+ if (this.looksLikeDateFormat(inner)) {
1779
+ const d = value instanceof Date ? value : new Date(value);
1780
+ return isNaN(d.getTime()) ? value : this.intl.formatDate(d, inner);
1781
+ }
1782
+ const num = typeof value === 'number' ? value : Number(value);
1783
+ if (!Number.isNaN(num)) {
1784
+ // supports "n", "n2", "c", "p", etc. and custom patterns
1785
+ return this.intl.formatNumber(num, inner);
1786
+ }
1787
+ // Fallback: return as-is if not a date/number
1788
+ return value;
1425
1789
  }
1426
- 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 }], target: i0.ɵɵFactoryTarget.Component }); }
1427
- 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 <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\">\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: i6$2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i6$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: RouterModule }, { kind: "ngmodule", type:
1790
+ extractFormat(fmt) {
1791
+ const m = fmt.match(/^\{0:([^}]+)\}$/);
1792
+ return m ? m[1] : fmt;
1793
+ }
1794
+ looksLikeDateFormat(f) {
1795
+ // crude but effective: typical date tokens
1796
+ return /d|M|y|H|h|m|s|E|a/.test(f) && !/^[cnp]/i.test(f);
1797
+ }
1798
+ inferFilterType(col) {
1799
+ if (!col)
1800
+ return 'text';
1801
+ const f = this.extractFormat(col.format || '');
1802
+ if (this.looksLikeDateFormat(f))
1803
+ return 'date';
1804
+ if (/^(n\d*|c|p\d*|n)$/i.test(f))
1805
+ return 'numeric'; // Kendo number patterns
1806
+ if (col.type === 'boolean')
1807
+ return 'boolean';
1808
+ return 'text';
1809
+ }
1810
+ 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 }); }
1811
+ 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
1812
  // MatPaginatorModule,
1429
1813
  // MatTableModule,
1430
- TranslateModule }, { kind: "pipe", type: i2.TranslatePipe, name: "translate" }, { kind: "component", type: i7$1.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: i7$1.GridToolbarFocusableDirective, selector: " [kendoGridToolbarFocusable], [kendoGridAddCommand], [kendoGridCancelCommand], [kendoGridEditCommand], [kendoGridRemoveCommand], [kendoGridSaveCommand], [kendoGridExcelCommand], [kendoGridPDFCommand] " }, { kind: "component", type: i7$1.ColumnComponent, selector: "kendo-grid-column", inputs: ["field", "format", "sortable", "groupable", "editor", "filter", "filterable", "editable"] }, { kind: "directive", type: i7$1.FocusableDirective, selector: "[kendoGridFocusable], [kendoGridEditCommand], [kendoGridRemoveCommand], [kendoGridSaveCommand], [kendoGridCancelCommand], [kendoGridSelectionCheckbox] ", inputs: ["kendoGridFocusable"] }, { kind: "component", type: i7$1.CommandColumnComponent, selector: "kendo-grid-command-column" }, { kind: "directive", type: i7$1.CellTemplateDirective, selector: "[kendoGridCellTemplate]" }, { kind: "component", type: i7$1.EditCommandDirective, selector: "[kendoGridEditCommand]" }, { kind: "component", type: i7$1.RemoveCommandDirective, selector: "[kendoGridRemoveCommand]" }, { kind: "directive", type: i7$1.AddCommandToolbarDirective, selector: "[kendoGridAddTool]" }, { kind: "component", type: i8.ToolBarComponent, selector: "kendo-toolbar", inputs: ["overflow", "resizable", "popupSettings", "fillMode", "tabindex", "size", "tabIndex"], outputs: ["open", "close"], exportAs: ["kendoToolBar"] }, { kind: "component", type: i8.ToolbarCustomMessagesComponent, selector: "kendo-toolbar-messages" }, { kind: "component", type: i8.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: i8.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 }); }
1814
+ 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
1815
  }
1432
1816
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.8", ngImport: i0, type: GenericRdictTableComponent, decorators: [{
1433
1817
  type: Component,
@@ -1443,8 +1827,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.8", ngImpor
1443
1827
  KENDO_BUTTONS,
1444
1828
  KENDO_DIALOG,
1445
1829
  RdictTableTitle
1446
- ], providers: [], template: "<kendo-grid [data]=\"dataSource\" [sortable]=\"true\" [filterable]=\"showSerach\" [resizable]=\"true\" (add)=\"addHandler()\"\r\n (edit)=\"editHandler($event)\" (remove)=\"removeHandler($event)\">\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\">\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"] }]
1447
- }], ctorParameters: () => [{ type: i1.Router }, { type: i1.ActivatedRoute }, { type: i2.TranslateService }, { type: i0.Injector }, { type: i4.LocalFileService }, { type: ReactiveDictionary }, { type: MaterialDialogService }], propDecorators: { showSerach: [{
1830
+ ], 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"] }]
1831
+ }], 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
1832
  type: Input
1449
1833
  }], searchFields: [{
1450
1834
  type: Input