@rosoftlab/rdict 1.0.1-alpha-7 → 1.0.1-alpha-10

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 i5$2 from '@angular/common';
1
+ import * as i6$2 from '@angular/common';
2
2
  import { CommonModule } from '@angular/common';
3
3
  import * as i0 from '@angular/core';
4
4
  import { Injectable, Inject, Component, NgModule, forwardRef, ViewChild, Input, EventEmitter, ElementRef, ViewEncapsulation, Output, InjectionToken } from '@angular/core';
@@ -6,56 +6,203 @@ import * as i1$1 from '@angular/router';
6
6
  import { RouterModule, UrlSegment, NavigationStart } from '@angular/router';
7
7
  import * as i2 from '@ngx-translate/core';
8
8
  import { TranslateModule, TranslateService } from '@ngx-translate/core';
9
- import * as i4 from '@progress/kendo-angular-buttons';
10
- import { ButtonsModule } from '@progress/kendo-angular-buttons';
9
+ import * as i5 from '@progress/kendo-angular-buttons';
10
+ import { ButtonsModule, KENDO_BUTTONS } from '@progress/kendo-angular-buttons';
11
11
  import { KENDO_SVGICON } from '@progress/kendo-angular-icons';
12
- import * as i5 from '@progress/kendo-angular-layout';
12
+ import * as i6 from '@progress/kendo-angular-layout';
13
13
  import { LayoutModule } from '@progress/kendo-angular-layout';
14
- import * as i7 from '@progress/kendo-angular-toolbar';
15
- import { ToolBarModule, ToolBarToolComponent, KENDO_TOOLBAR } from '@progress/kendo-angular-toolbar';
14
+ import * as i8 from '@progress/kendo-angular-toolbar';
15
+ import { ToolBarModule, KENDO_TOOLBAR, ToolBarToolComponent } from '@progress/kendo-angular-toolbar';
16
16
  import * as allIcons from '@progress/kendo-svg-icons';
17
- import { menuIcon } from '@progress/kendo-svg-icons';
18
- import { BehaviorSubject, map } from 'rxjs';
17
+ import { menuIcon, saveIcon, pencilIcon, trashIcon, plusIcon } from '@progress/kendo-svg-icons';
18
+ import { Subject, from, mergeMap, map, Observable } from 'rxjs';
19
+ import { v4 } from 'uuid';
19
20
  import { io } from 'socket.io-client';
20
- import * as msgpackParser from 'socket.io-msgpack-parser';
21
21
  import * as i1 from '@rosoftlab/core';
22
22
  import { BaseModel, Attribute, BaseModelConfig, BaseService } from '@rosoftlab/core';
23
23
  import { __decorate, __metadata } from 'tslib';
24
- import * as i5$1 from '@angular/forms';
25
- import { FormGroup, ReactiveFormsModule } from '@angular/forms';
26
- import * as i4$1 from '@ngx-formly/core';
24
+ import * as i7 from '@angular/forms';
25
+ import { FormGroup, FormControl, ReactiveFormsModule } from '@angular/forms';
26
+ import * as i6$1 from '@ngx-formly/core';
27
27
  import { FORMLY_CONFIG, FormlyModule } from '@ngx-formly/core';
28
28
  import { FormlyKendoModule } from '@ngx-formly/kendo';
29
- import * as i6 from '@progress/kendo-angular-grid';
29
+ import * as i2$1 from '@progress/kendo-angular-dialog';
30
+ import { DialogCloseResult, KENDO_DIALOG } from '@progress/kendo-angular-dialog';
31
+ import * as i3 from '@progress/kendo-angular-notification';
32
+ import * as i7$1 from '@progress/kendo-angular-grid';
30
33
  import { KENDO_GRID } from '@progress/kendo-angular-grid';
34
+ import * as i1$2 from '@progress/kendo-angular-label';
31
35
  import { KENDO_LABEL } from '@progress/kendo-angular-label';
32
36
 
37
+ class SocketService {
38
+ constructor(socketUrl) {
39
+ this.socketUrl = socketUrl;
40
+ // Replace with your actual server URL
41
+ // this.socket.on("connect", () => {
42
+ // const engine = this.socket.io.engine;
43
+ // (engine.transport.name); // in most cases, prints "polling"
44
+ // engine.once("upgrade", () => {
45
+ // // called when the transport is upgraded (i.e. from HTTP long-polling to WebSocket)
46
+ // (engine.transport.name); // in most cases, prints "websocket"
47
+ // });
48
+ // });
49
+ }
50
+ initSocket(authToken) {
51
+ if (this.socket == null && authToken !== null) {
52
+ this.socket = io(this.socketUrl, {
53
+ withCredentials: true,
54
+ // parser: msgpackParser,
55
+ auth: {
56
+ token: authToken, // Include the authentication token
57
+ }
58
+ // ,
59
+ // query: {
60
+ // "access_token": authToken
61
+ // }
62
+ });
63
+ // const originalEmit = this.socket.emit;
64
+ // this.socket.emit = (event, ...args) => {
65
+ // // Transform dates before sending
66
+ // const transformedData = this.transformDatesForEncoding(args[0]);
67
+ // originalEmit.call(this.socket, event, transformedData);
68
+ // return this.socket;
69
+ // };
70
+ // Intercept incoming data and apply date transformation
71
+ // this.socket.onAny((event, data) => {
72
+ // const transformedData = this.transformDatesForDecoding(data);
73
+ // this.socket.emit(event, transformedData); // Emit the transformed data back
74
+ // });
75
+ }
76
+ }
77
+ getInitialData() {
78
+ return new Promise((resolve, reject) => {
79
+ this.socket.on('init', (data) => {
80
+ if (data) {
81
+ resolve(data["dict_data"]);
82
+ }
83
+ else {
84
+ reject('No data received from init event');
85
+ }
86
+ });
87
+ });
88
+ }
89
+ getSetEvent(rdict) {
90
+ this.socket.on('set', (data) => {
91
+ // (rdict.get('__guid'), data, this.socket.id)
92
+ if (rdict.get('__guid') === data.did) {
93
+ // ('Set the data')
94
+ rdict.asyncSet(data.key, data.value, false);
95
+ }
96
+ });
97
+ }
98
+ getDeleteEvent(rdict) {
99
+ this.socket.on('delete', (data) => {
100
+ // (rdict.get('__guid'), data, this.socket.id)
101
+ if (rdict.get('__guid') === data.did) {
102
+ // ('Set the data')
103
+ rdict.asyncDelete(data.key, false);
104
+ }
105
+ });
106
+ }
107
+ // Emit the 'lazy_load' event with callback to get the response
108
+ requestLazyLoad(did, key) {
109
+ return new Promise((resolve, reject) => {
110
+ this.socket.emit('lazy_load', { did, key }, (response) => {
111
+ if (response && response.error) {
112
+ reject(response.error); // Handle error if present
113
+ }
114
+ else {
115
+ resolve(response); // Resolve with the response data
116
+ }
117
+ });
118
+ });
119
+ }
120
+ // Emit the 'set' event to update the data on the server
121
+ emitSet(did, key, value) {
122
+ return new Promise((resolve, reject) => {
123
+ this.socket.emit('set', { did, key, value }, (response) => {
124
+ if (response && response.error) {
125
+ reject(response.error);
126
+ }
127
+ else {
128
+ resolve();
129
+ }
130
+ });
131
+ });
132
+ }
133
+ // Emit the 'set' event to update the data on the server
134
+ emitDelete(did, key) {
135
+ return new Promise((resolve, reject) => {
136
+ this.socket.emit('delete', { did, key }, (response) => {
137
+ if (response && response.error) {
138
+ reject(response.error);
139
+ }
140
+ else {
141
+ resolve();
142
+ }
143
+ });
144
+ });
145
+ }
146
+ transformDatesForEncoding(obj) {
147
+ if (obj instanceof Date) {
148
+ return { __date__: obj.toISOString() };
149
+ }
150
+ else if (Array.isArray(obj)) {
151
+ return obj.map(this.transformDatesForEncoding);
152
+ }
153
+ else if (obj !== null && typeof obj === "object") {
154
+ return Object.keys(obj).reduce((acc, key) => {
155
+ acc[key] = this.transformDatesForEncoding(obj[key]);
156
+ return acc;
157
+ }, {});
158
+ }
159
+ return obj;
160
+ }
161
+ transformDatesForDecoding(obj) {
162
+ if (typeof obj === "object" && obj !== null) {
163
+ if ("__date__" in obj) {
164
+ return new Date(obj.__date__);
165
+ }
166
+ return Object.keys(obj).reduce((acc, key) => {
167
+ acc[key] = this.transformDatesForDecoding(obj[key]);
168
+ return acc;
169
+ }, {});
170
+ }
171
+ return obj;
172
+ }
173
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: SocketService, deps: [{ token: SOCKET_URL }], target: i0.ɵɵFactoryTarget.Injectable }); }
174
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: SocketService, providedIn: 'root' }); }
175
+ }
176
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: SocketService, decorators: [{
177
+ type: Injectable,
178
+ args: [{
179
+ providedIn: 'root'
180
+ }]
181
+ }], ctorParameters: () => [{ type: undefined, decorators: [{
182
+ type: Inject,
183
+ args: [SOCKET_URL]
184
+ }] }] });
185
+
186
+ // import { mergeMap } from 'rxjs/operators';
33
187
  class ReactiveDictionary extends Map {
34
- static { this.instance = new Map; }
35
- constructor(socketService, authToken) {
188
+ static { this.instance = new Map(); }
189
+ constructor(socketService) {
36
190
  super();
37
- this.changes$ = new BehaviorSubject(null);
191
+ this.changes$ = new Subject();
192
+ this.deletes$ = new Subject();
38
193
  this.isInitialized = false;
39
194
  this._authToken = null;
40
- this._authToken = authToken;
41
195
  this._socketService = socketService;
196
+ // this._socketService.initSocket(authToken)
197
+ // this._socketService.getSetEvent(this)
198
+ }
199
+ async initialize(authToken) {
200
+ this._authToken = authToken;
42
201
  this._socketService.initSocket(authToken);
43
202
  this._socketService.getSetEvent(this);
203
+ this._socketService.getDeleteEvent(this);
204
+ await this.asyncInit();
44
205
  }
45
- // Method to get the singleton instance
46
- static getInstance(socketService, authToken, instance_key) {
47
- if (!instance_key)
48
- instance_key = 'root';
49
- if (!ReactiveDictionary.instance.has(instance_key)) {
50
- ReactiveDictionary.instance.set(instance_key, new ReactiveDictionary(socketService, authToken));
51
- }
52
- const instance = ReactiveDictionary.instance.get(instance_key);
53
- if (!instance) {
54
- throw new Error(`No instance found for key: ${instance_key}`); // Handle undefined case
55
- }
56
- return instance; // Now TypeScript knows 'instance' is not undefined
57
- }
58
- // str_keys(): string[] {
59
206
  keys() {
60
207
  const excludedKeys = ['__guid', '__type']; // Key to exclude
61
208
  const iterator = super.keys();
@@ -76,8 +223,8 @@ class ReactiveDictionary extends Map {
76
223
  return { value: key, done: false }; // Return the valid key
77
224
  }
78
225
  } while (true); // Continue until a valid key is found
79
- }
80
- })
226
+ },
227
+ }),
81
228
  };
82
229
  return filteredIterator;
83
230
  }
@@ -98,7 +245,8 @@ class ReactiveDictionary extends Map {
98
245
  const lazyLoadData = await this.lazyLoadSync(this.get('__guid'), key);
99
246
  // console.log(lazyLoadData)
100
247
  if (lazyLoadData) {
101
- const dict = new ReactiveDictionary(this._socketService, this._authToken);
248
+ const dict = new ReactiveDictionary(this._socketService);
249
+ dict.initialize(this._authToken);
102
250
  await dict.asyncInit(lazyLoadData.data);
103
251
  this.set(key, dict);
104
252
  return dict;
@@ -107,15 +255,34 @@ class ReactiveDictionary extends Map {
107
255
  }
108
256
  return value;
109
257
  }
258
+ else {
259
+ const dict = new ReactiveDictionary(this._socketService);
260
+ dict.initialize(this._authToken);
261
+ dict.set('__guid', v4());
262
+ dict.set('__type', 'dict');
263
+ this.set(key, dict);
264
+ await this._socketService.emitSet(this.get('__guid'), key, this.transform_for_serialization(dict));
265
+ return dict;
266
+ }
110
267
  }
111
268
  else {
112
- const obj = await this.asyncGet(keys[0]);
269
+ const obj = (await this.asyncGet(keys[0]));
113
270
  if (obj)
114
271
  return await obj.asyncGet(keys.slice(1).join('.'));
115
272
  else
116
273
  return null;
117
274
  }
118
275
  }
276
+ transform_for_serialization(value) {
277
+ // Transform a value to a format that can be serialized.
278
+ const dict_type = value['__type'];
279
+ if (dict_type === 'lazy')
280
+ return { __type: 'lazy' };
281
+ else if (value instanceof ReactiveDictionary)
282
+ return { __type: 'dict', __guid: value.get('__guid') };
283
+ else
284
+ return value;
285
+ }
119
286
  // Asynchronous method to set a value by key
120
287
  async asyncSet(key, value, emmit_event = true) {
121
288
  if (emmit_event) {
@@ -129,12 +296,29 @@ class ReactiveDictionary extends Map {
129
296
  this.set(key, value);
130
297
  this.changes$.next({ key, value });
131
298
  }
299
+ async asyncDelete(key, emmit_event = true) {
300
+ if (this.has(key)) {
301
+ if (emmit_event) {
302
+ try {
303
+ await this._socketService.emitDelete(this.get('__guid'), key);
304
+ }
305
+ catch (error) {
306
+ console.error('Error emitting set event:', error);
307
+ }
308
+ }
309
+ this.delete(key);
310
+ this.deletes$.next({ key });
311
+ }
312
+ }
313
+ deleteAsObservable(key, emmit_event = true) {
314
+ return from(this.asyncDelete(key, emmit_event));
315
+ }
132
316
  // Asynchronous method to initialize with a set of key-value pairs
133
317
  async asyncInit(initialData) {
134
318
  if (!this.isInitialized) {
135
319
  try {
136
320
  // If initial data is not provided, fetch it
137
- const data = initialData || await this._socketService.getInitialData();
321
+ const data = initialData || (await this._socketService.getInitialData());
138
322
  // this.known_dicts.set(data.__guid,data);
139
323
  // Set the initial properties on the proxy
140
324
  for (const [key, value] of Object.entries(data)) {
@@ -160,134 +344,168 @@ class ReactiveDictionary extends Map {
160
344
  getPlainObject() {
161
345
  const plainObject = {};
162
346
  this.forEach((value, key) => {
163
- if (value instanceof ReactiveDictionary)
347
+ if (value instanceof ReactiveDictionary) {
164
348
  plainObject[key] = value.getPlainObject();
165
- else
166
- plainObject[key] = value; // Add key-value pairs to the plain object
349
+ }
350
+ else if (typeof value === 'string') {
351
+ const formattedValue = value
352
+ .replace(/'/g, '"') // Convert single quotes to double quotes
353
+ .replace(/\bNone\b/g, 'null') // Replace None with null
354
+ .replace(/\bFalse\b/g, 'false') // Replace False with false
355
+ .replace(/\bTrue\b/g, 'true'); // Replace True with true
356
+ try {
357
+ const parsedValue = JSON.parse(formattedValue, this.jsonDateReviver);
358
+ plainObject[key] = parsedValue;
359
+ }
360
+ catch {
361
+ plainObject[key] = value; // Keep as string if not valid JSON
362
+ }
363
+ }
364
+ else {
365
+ plainObject[key] = value;
366
+ }
167
367
  });
168
368
  return plainObject; // Return the plain object
169
369
  }
170
- async getTable(key) {
171
- const data = await this.asyncGet(key); // Get rooms from the ReactiveDictionary
172
- if (!data) {
173
- return []; // Return an empty array if data is undefined
370
+ jsonDateReviver(key, value) {
371
+ // Check if the value is a valid ISO date string
372
+ if (typeof value === 'string' &&
373
+ /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/.test(value)) {
374
+ return new Date(value); // Convert to JavaScript Date object
174
375
  }
175
- // Filter and get only entries that are instances of ReactiveDictionary
176
- const result = await Promise.all(Array.from(data.entries()).map(async (key) => await data.asyncGet(key[0])) // Get data from asyncGet
177
- ) || []; // Return an empty array if the above yields undefined
178
- return result.filter((entry) => entry instanceof ReactiveDictionary);
376
+ return value;
179
377
  }
180
- async getTableWithoutGuid(key) {
181
- const data = await this.asyncGet(key); // Get rooms from the ReactiveDictionary
182
- if (!data) {
378
+ getAsObservable(key) {
379
+ return from(this.asyncGet(key));
380
+ }
381
+ getTableAsObservable(key, data = null) {
382
+ return from(this.getTable(key, data)).pipe(mergeMap((dictionary) => {
383
+ if (!Array.isArray(dictionary)) {
384
+ throw new Error('Expected an array but received something else');
385
+ }
386
+ const isArrayOfReactiveDictionaries = dictionary.every((item) => item instanceof ReactiveDictionary);
387
+ if (!isArrayOfReactiveDictionaries) {
388
+ throw new Error('Expected an array of ReactiveDictionary instances but received something else');
389
+ }
390
+ // ✅ WRAP THIS IN from(...) to make it emit real data, not a Promise
391
+ return from(this.processTableData(dictionary));
392
+ }));
393
+ }
394
+ async getTable(key, data = null) {
395
+ if (!data)
396
+ data = await this.asyncGet(key); // Get rooms from the ReactiveDictionary
397
+ if (!data)
183
398
  return []; // Return an empty array if data is undefined
184
- }
399
+ console.log('getTable', data);
185
400
  // Filter and get only entries that are instances of ReactiveDictionary
186
- const result = await Promise.all(Array.from(data.entries()).map(async (key) => await data.asyncGet(key[0])) // Get data from asyncGet
187
- ) || []; // Return an empty array if the above yields undefined
188
- var filteredResults = result.filter((entry) => entry instanceof ReactiveDictionary);
189
- return filteredResults.map(dictionary => {
190
- // Convert Map to object and filter out __guid
191
- const filteredObject = {};
192
- for (const [key, value] of dictionary.entries()) {
193
- if (key !== '__guid') {
194
- filteredObject[key] = value;
195
- }
401
+ const result = (await Promise.all(Array.from(data.entries()).map(async (key, index) => {
402
+ const entry = (await data.asyncGet(key[0]));
403
+ if (entry instanceof ReactiveDictionary) {
404
+ entry.set('__idx', key[0]);
196
405
  }
197
- return filteredObject;
198
- });
199
- }
200
- onChanges() {
201
- return this.changes$.asObservable();
406
+ return entry;
407
+ }))) || []; // Return an empty array if the above yields undefined
408
+ return result.filter((entry) => entry instanceof ReactiveDictionary);
202
409
  }
203
- }
204
-
205
- class SocketService {
206
- constructor(socketUrl) {
207
- this.socketUrl = socketUrl;
208
- // Replace with your actual server URL
209
- // this.socket.on("connect", () => {
210
- // const engine = this.socket.io.engine;
211
- // (engine.transport.name); // in most cases, prints "polling"
212
- // engine.once("upgrade", () => {
213
- // // called when the transport is upgraded (i.e. from HTTP long-polling to WebSocket)
214
- // (engine.transport.name); // in most cases, prints "websocket"
215
- // });
216
- // });
410
+ async getTableWithoutGuid(key) {
411
+ const data = await this.asyncGet(key);
412
+ if (!data)
413
+ return [];
414
+ // Reuse the common processing logic
415
+ return this.processTableData(data);
217
416
  }
218
- initSocket(authToken) {
219
- if (this.socket == null && authToken !== null) {
220
- this.socket = io(this.socketUrl, {
221
- withCredentials: true,
222
- parser: msgpackParser,
223
- auth: {
224
- token: authToken, // Include the authentication token
225
- },
226
- query: {
227
- "access_token": authToken
417
+ async processTableData(data) {
418
+ if (data instanceof ReactiveDictionary) {
419
+ const result = (await Promise.all(Array.from(data.entries()).map(async ([key]) => {
420
+ const entry = (await data.asyncGet(key));
421
+ if (entry instanceof ReactiveDictionary) {
422
+ entry.set('__idx', key);
228
423
  }
424
+ return entry;
425
+ }))) || [];
426
+ return result
427
+ .filter((entry) => entry instanceof ReactiveDictionary)
428
+ .map((dictionary) => {
429
+ const filteredObject = {};
430
+ for (const [key, value] of dictionary.entries()) {
431
+ if (key !== '__guid') {
432
+ filteredObject[key] = value;
433
+ }
434
+ }
435
+ return filteredObject;
229
436
  });
230
437
  }
231
- }
232
- getInitialData() {
233
- return new Promise((resolve, reject) => {
234
- this.socket.on('init', (data) => {
235
- if (data) {
236
- resolve(data["dict_data"]);
237
- }
238
- else {
239
- reject('No data received from init event');
438
+ else if (Array.isArray(data)) {
439
+ // Directly process array of ReactiveDictionary instances
440
+ return data.map((dictionary) => {
441
+ const filteredObject = {};
442
+ for (const [key, value] of dictionary.entries()) {
443
+ if (key !== '__guid') {
444
+ filteredObject[key] = value;
445
+ }
240
446
  }
447
+ return filteredObject;
241
448
  });
242
- });
449
+ }
450
+ else {
451
+ console.warn('processTableData received unexpected data:', data);
452
+ return [];
453
+ }
243
454
  }
244
- getSetEvent(rdict) {
245
- this.socket.on('set', (data) => {
246
- // (rdict.get('__guid'), data, this.socket.id)
247
- if (rdict.get('__guid') === data.did) {
248
- // ('Set the data')
249
- rdict.asyncSet(data.key, data.value, false);
250
- }
251
- });
455
+ // async processTableData(data: any): Promise<any[]> {
456
+ // // Filter and get only entries that are instances of ReactiveDictionary
457
+ // const result = await Promise.all(
458
+ // Array.from(data.entries()).map(async ([key]) => {
459
+ // const entry = await data.asyncGet(key) as ReactiveDictionary
460
+ // if (entry instanceof ReactiveDictionary) {
461
+ // entry.set('__idx', key);
462
+ // }
463
+ // return entry;
464
+ // })
465
+ // ) || [];
466
+ // // Filter out entries that are not ReactiveDictionary instances
467
+ // const filteredResults = result.filter((entry: any) => entry instanceof ReactiveDictionary);
468
+ // // Remove __guid from each dictionary and return the plain object
469
+ // return filteredResults.map(dictionary => {
470
+ // const filteredObject: Record<string, any> = {};
471
+ // for (const [key, value] of dictionary.entries()) {
472
+ // if (key !== '__guid') {
473
+ // filteredObject[key] = value;
474
+ // }
475
+ // }
476
+ // return filteredObject;
477
+ // });
478
+ // }
479
+ onChanges() {
480
+ return this.changes$.asObservable();
252
481
  }
253
- // Emit the 'lazy_load' event with callback to get the response
254
- requestLazyLoad(did, key) {
255
- return new Promise((resolve, reject) => {
256
- this.socket.emit('lazy_load', { did, key }, (response) => {
257
- if (response && response.error) {
258
- reject(response.error); // Handle error if present
259
- }
260
- else {
261
- resolve(response); // Resolve with the response data
262
- }
263
- });
264
- });
482
+ onDelete() {
483
+ return this.deletes$.asObservable();
265
484
  }
266
- // Emit the 'set' event to update the data on the server
267
- emitSet(did, key, value) {
268
- return new Promise((resolve, reject) => {
269
- this.socket.emit('set', { did, key, value }, (response) => {
270
- if (response && response.error) {
271
- reject(response.error);
272
- }
273
- else {
274
- resolve();
275
- }
276
- });
277
- });
485
+ async update(record, key = null) {
486
+ if (!key)
487
+ key = this.size.toString();
488
+ const dict = await this.asyncGet(key);
489
+ for (const key in record) {
490
+ if (record.hasOwnProperty(key)) {
491
+ const currentValue = await dict.asyncGet(key);
492
+ if (currentValue !== record[key])
493
+ await dict.asyncSet(key, record[key]);
494
+ }
495
+ }
278
496
  }
279
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: SocketService, deps: [{ token: SOCKET_URL }], target: i0.ɵɵFactoryTarget.Injectable }); }
280
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: SocketService, providedIn: 'root' }); }
497
+ modelFormList(property, value) {
498
+ return this.get('__modelFormList');
499
+ }
500
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: ReactiveDictionary, deps: [{ token: SocketService }], target: i0.ɵɵFactoryTarget.Injectable }); }
501
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: ReactiveDictionary, providedIn: 'root' }); }
281
502
  }
282
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: SocketService, decorators: [{
503
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: ReactiveDictionary, decorators: [{
283
504
  type: Injectable,
284
505
  args: [{
285
- providedIn: 'root'
506
+ providedIn: 'root', // This makes the service a singleton and available throughout the app
286
507
  }]
287
- }], ctorParameters: () => [{ type: undefined, decorators: [{
288
- type: Inject,
289
- args: [SOCKET_URL]
290
- }] }] });
508
+ }], ctorParameters: () => [{ type: SocketService }] });
291
509
 
292
510
  let Menu = class Menu extends BaseModel {
293
511
  };
@@ -459,39 +677,19 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.3", ngImpor
459
677
  }]
460
678
  }], ctorParameters: () => [{ type: i1.DatastoreCore }] });
461
679
 
462
- class WsAuthService {
463
- constructor() {
464
- this.token = null;
465
- }
466
- get Token() {
467
- return this.token;
468
- }
469
- set Token(token) {
470
- this.token = token;
471
- }
472
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: WsAuthService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
473
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: WsAuthService, providedIn: 'root' }); }
474
- }
475
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: WsAuthService, decorators: [{
476
- type: Injectable,
477
- args: [{
478
- providedIn: 'root'
479
- }]
480
- }], ctorParameters: () => [] });
481
-
482
680
  class FullComponent {
483
- constructor(userService, router, socketService, translate, wsAuthService) {
681
+ constructor(userService, router, translate, rdict) {
484
682
  this.userService = userService;
485
683
  this.router = router;
486
- this.socketService = socketService;
487
684
  this.translate = translate;
488
- this.wsAuthService = wsAuthService;
685
+ this.rdict = rdict;
489
686
  this.selected = "Inbox";
490
687
  this.menuSvg = menuIcon;
491
688
  this.expandedIndices = [2];
492
689
  this.hasItems = false;
493
690
  this.items = [];
494
691
  this.icons = allIcons;
692
+ //private rdict: ReactiveDictionary | undefined;
495
693
  this.apptitle = "Test";
496
694
  this.isItemExpanded = (item) => {
497
695
  return this.expandedIndices.indexOf(item.id) >= 0;
@@ -499,9 +697,6 @@ class FullComponent {
499
697
  this.getMenu();
500
698
  }
501
699
  async ngOnInit() {
502
- this.rdict = ReactiveDictionary.getInstance(this.socketService, this.wsAuthService.Token);
503
- if (this.rdict.size == 0)
504
- await this.rdict.asyncInit();
505
700
  this.apptitle = await this.rdict.asyncGet("appname");
506
701
  }
507
702
  getMenu() {
@@ -555,8 +750,8 @@ class FullComponent {
555
750
  });
556
751
  return drawerItems;
557
752
  }
558
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: FullComponent, deps: [{ token: UserService }, { token: i1$1.Router }, { token: SocketService }, { token: i2.TranslateService }, { token: WsAuthService }], target: i0.ɵɵFactoryTarget.Component }); }
559
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.1.3", type: FullComponent, isStandalone: true, selector: "rdict-full", ngImport: i0, template: "<div class=\"custom-toolbar\">\r\n <button kendoButton [svgIcon]=\"menuSvg\" fillMode=\"flat\" (click)=\"drawer.toggle()\"></button>\r\n <!-- <kendo-toolbar-button icon=\"menu\" themeColor=\"tertiary\" (click)=\"drawer.toggle()\"> </kendo-toolbar-button> -->\r\n <span class=\"app-title\">{{apptitle}}</span>\r\n</div>\r\n<kendo-drawer-container>\r\n <kendo-drawer #drawer [items]=\"items\" mode=\"push\" [mini]=\"true\" [expanded]=\"true\" (select)=\"onSelect($event)\"\r\n [autoCollapse]=\"false\" [isItemExpanded]=\"isItemExpanded\">\r\n <!-- <ng-template kendoDrawerItemTemplate let-item>\r\n <div *ngIf=\"item.path !== ''\" class=\"k-drawer-link\" [routerLink]=\"item.path\">\r\n <kendo-svgicon [icon]=\"item.svgIcon\"></kendo-svgicon>\r\n <span>{{ item.text }}</span>\r\n </div>\r\n <div *ngIf=\"item.path == ''\" class=\"k-drawer-link\" >\r\n <kendo-svgicon [icon]=\"item.svgIcon\"></kendo-svgicon>\r\n <span>{{ item.text }}</span>\r\n </div>\r\n </ng-template> -->\r\n </kendo-drawer>\r\n\r\n <kendo-drawer-content>\r\n <router-outlet></router-outlet>\r\n <!-- <div>{{selected}}</div> -->\r\n <!-- <my-content [selectedItem]=\"selected\"></my-content> -->\r\n </kendo-drawer-content>\r\n</kendo-drawer-container>", styles: ["html,body,rdict-full{padding:0;height:100%}rdict-full{display:flex;flex-direction:column}kendo-drawer-container{flex:1 1 auto;overflow-y:auto}.k-icon{font-size:20px}.custom-toolbar{width:100%;background-color:#f6f6f6;line-height:10px;border-bottom:inset;border-bottom-width:1px;color:#656565}.custom-toolbar button{margin:3px 0 3px 8px}.app-title{margin-left:20px;font-weight:700;font-size:17px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: RouterModule }, { kind: "directive", type: i1$1.RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "ngmodule", type: ButtonsModule }, { kind: "component", type: i4.ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon", "primary", "look"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "ngmodule", type: ToolBarModule }, { kind: "ngmodule", type: LayoutModule }, { kind: "component", type: i5.DrawerComponent, selector: "kendo-drawer", inputs: ["mode", "position", "mini", "expanded", "width", "miniWidth", "autoCollapse", "items", "isItemExpanded", "animation"], outputs: ["expand", "collapse", "select", "expandedChange"], exportAs: ["kendoDrawer"] }, { kind: "component", type: i5.DrawerContainerComponent, selector: "kendo-drawer-container" }, { kind: "component", type: i5.DrawerContentComponent, selector: "kendo-drawer-content" }] }); }
753
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: FullComponent, deps: [{ token: UserService }, { token: i1$1.Router }, { token: i2.TranslateService }, { token: ReactiveDictionary }], target: i0.ɵɵFactoryTarget.Component }); }
754
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.1.3", type: FullComponent, isStandalone: true, selector: "rdict-full", ngImport: i0, template: "<div class=\"custom-toolbar\">\r\n <button kendoButton [svgIcon]=\"menuSvg\" fillMode=\"flat\" (click)=\"drawer.toggle()\"></button>\r\n <!-- <kendo-toolbar-button icon=\"menu\" themeColor=\"tertiary\" (click)=\"drawer.toggle()\"> </kendo-toolbar-button> -->\r\n <span class=\"app-title\">{{apptitle}}</span>\r\n</div>\r\n<kendo-drawer-container>\r\n <kendo-drawer #drawer [items]=\"items\" mode=\"push\" [mini]=\"true\" [expanded]=\"true\" (select)=\"onSelect($event)\"\r\n [autoCollapse]=\"false\" [isItemExpanded]=\"isItemExpanded\">\r\n <!-- <ng-template kendoDrawerItemTemplate let-item>\r\n <div *ngIf=\"item.path !== ''\" class=\"k-drawer-link\" [routerLink]=\"item.path\">\r\n <kendo-svgicon [icon]=\"item.svgIcon\"></kendo-svgicon>\r\n <span>{{ item.text }}</span>\r\n </div>\r\n <div *ngIf=\"item.path == ''\" class=\"k-drawer-link\" >\r\n <kendo-svgicon [icon]=\"item.svgIcon\"></kendo-svgicon>\r\n <span>{{ item.text }}</span>\r\n </div>\r\n </ng-template> -->\r\n </kendo-drawer>\r\n\r\n <kendo-drawer-content>\r\n <router-outlet></router-outlet>\r\n <!-- <div>{{selected}}</div> -->\r\n <!-- <my-content [selectedItem]=\"selected\"></my-content> -->\r\n </kendo-drawer-content>\r\n</kendo-drawer-container>", styles: ["html,body,rdict-full{padding:0;height:100%}rdict-full{display:flex;flex-direction:column}kendo-drawer-container{flex:1 1 auto;overflow-y:auto}.k-icon{font-size:20px}.custom-toolbar{width:100%;background-color:#f6f6f6;line-height:10px;border-bottom:inset;border-bottom-width:1px;color:#656565}.custom-toolbar button{margin:3px 0 3px 8px}.app-title{margin-left:20px;font-weight:700;font-size:17px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: RouterModule }, { kind: "directive", type: i1$1.RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "ngmodule", type: ButtonsModule }, { kind: "component", type: i5.ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon", "primary", "look"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "ngmodule", type: ToolBarModule }, { kind: "ngmodule", type: LayoutModule }, { kind: "component", type: i6.DrawerComponent, selector: "kendo-drawer", inputs: ["mode", "position", "mini", "expanded", "width", "miniWidth", "autoCollapse", "items", "isItemExpanded", "animation"], outputs: ["expand", "collapse", "select", "expandedChange"], exportAs: ["kendoDrawer"] }, { kind: "component", type: i6.DrawerContainerComponent, selector: "kendo-drawer-container" }, { kind: "component", type: i6.DrawerContentComponent, selector: "kendo-drawer-content" }] }); }
560
755
  }
561
756
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: FullComponent, decorators: [{
562
757
  type: Component,
@@ -570,7 +765,64 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.3", ngImpor
570
765
  LayoutModule,
571
766
  KENDO_SVGICON
572
767
  ], template: "<div class=\"custom-toolbar\">\r\n <button kendoButton [svgIcon]=\"menuSvg\" fillMode=\"flat\" (click)=\"drawer.toggle()\"></button>\r\n <!-- <kendo-toolbar-button icon=\"menu\" themeColor=\"tertiary\" (click)=\"drawer.toggle()\"> </kendo-toolbar-button> -->\r\n <span class=\"app-title\">{{apptitle}}</span>\r\n</div>\r\n<kendo-drawer-container>\r\n <kendo-drawer #drawer [items]=\"items\" mode=\"push\" [mini]=\"true\" [expanded]=\"true\" (select)=\"onSelect($event)\"\r\n [autoCollapse]=\"false\" [isItemExpanded]=\"isItemExpanded\">\r\n <!-- <ng-template kendoDrawerItemTemplate let-item>\r\n <div *ngIf=\"item.path !== ''\" class=\"k-drawer-link\" [routerLink]=\"item.path\">\r\n <kendo-svgicon [icon]=\"item.svgIcon\"></kendo-svgicon>\r\n <span>{{ item.text }}</span>\r\n </div>\r\n <div *ngIf=\"item.path == ''\" class=\"k-drawer-link\" >\r\n <kendo-svgicon [icon]=\"item.svgIcon\"></kendo-svgicon>\r\n <span>{{ item.text }}</span>\r\n </div>\r\n </ng-template> -->\r\n </kendo-drawer>\r\n\r\n <kendo-drawer-content>\r\n <router-outlet></router-outlet>\r\n <!-- <div>{{selected}}</div> -->\r\n <!-- <my-content [selectedItem]=\"selected\"></my-content> -->\r\n </kendo-drawer-content>\r\n</kendo-drawer-container>", styles: ["html,body,rdict-full{padding:0;height:100%}rdict-full{display:flex;flex-direction:column}kendo-drawer-container{flex:1 1 auto;overflow-y:auto}.k-icon{font-size:20px}.custom-toolbar{width:100%;background-color:#f6f6f6;line-height:10px;border-bottom:inset;border-bottom-width:1px;color:#656565}.custom-toolbar button{margin:3px 0 3px 8px}.app-title{margin-left:20px;font-weight:700;font-size:17px}\n"] }]
573
- }], ctorParameters: () => [{ type: UserService }, { type: i1$1.Router }, { type: SocketService }, { type: i2.TranslateService }, { type: WsAuthService }] });
768
+ }], ctorParameters: () => [{ type: UserService }, { type: i1$1.Router }, { type: i2.TranslateService }, { type: ReactiveDictionary }] });
769
+
770
+ class MaterialDialogService {
771
+ constructor(translate, dialogService, notificationService) {
772
+ this.translate = translate;
773
+ this.dialogService = dialogService;
774
+ this.notificationService = notificationService;
775
+ this.state = {
776
+ content: "Your data has been saved.",
777
+ type: { style: "success", icon: true },
778
+ animation: { type: "slide", duration: 400 },
779
+ hideAfter: 3000,
780
+ };
781
+ }
782
+ confirmDelete() {
783
+ return this.confirm(this.translate.instant("Are you sure you want to delete this record ?"), this.translate.instant("Delete Record"), this.translate.instant("General.Yes"), this.translate.instant("General.No"));
784
+ }
785
+ confirm(content, title, confirmButtonText, cancelButtonText) {
786
+ const dialog = this.dialogService.open({
787
+ title: title || "Confirm",
788
+ content: content || "Are you sure?",
789
+ actions: [
790
+ { text: cancelButtonText || "No", result: false },
791
+ { text: confirmButtonText || "Yes", themeColor: "primary", result: true }
792
+ ],
793
+ width: 450,
794
+ height: 200,
795
+ minWidth: 250,
796
+ });
797
+ // Return an Observable<boolean>
798
+ return new Observable((observer) => {
799
+ dialog.result.subscribe((result) => {
800
+ if (result instanceof DialogCloseResult) {
801
+ // Dialog was closed without an action
802
+ observer.next(false);
803
+ }
804
+ else {
805
+ const actionResult = result;
806
+ observer.next(actionResult.result);
807
+ }
808
+ observer.complete(); // Complete the observable
809
+ });
810
+ });
811
+ }
812
+ showSaveMessage(message) {
813
+ this.state.content = message || "Your data has been saved.";
814
+ this.state.type = { style: "success", icon: true };
815
+ this.notificationService.show(this.state);
816
+ }
817
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: MaterialDialogService, deps: [{ token: i2.TranslateService }, { token: i2$1.DialogService }, { token: i3.NotificationService }], target: i0.ɵɵFactoryTarget.Injectable }); }
818
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: MaterialDialogService, providedIn: 'root' }); }
819
+ }
820
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: MaterialDialogService, decorators: [{
821
+ type: Injectable,
822
+ args: [{
823
+ providedIn: 'root'
824
+ }]
825
+ }], ctorParameters: () => [{ type: i2.TranslateService }, { type: i2$1.DialogService }, { type: i3.NotificationService }] });
574
826
 
575
827
  class TranslateExtension {
576
828
  constructor(translate) {
@@ -639,57 +891,170 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.3", ngImpor
639
891
  }]
640
892
  }] });
641
893
 
642
- ;
643
894
  class RdictCrudComponent {
644
- // = [
645
- // {
646
- // key: 'name',
647
- // type: 'input',
648
- // props: {
649
- // label: 'General.Name',
650
- // translate: true,
651
- // required: true,
652
- // }
653
- // },
654
- // ];
655
- constructor(router, route, translate, socketService, wsAuthService) {
895
+ constructor(router, route, translate, rdict, localFileService, dialogService) {
656
896
  this.router = router;
657
897
  this.route = route;
658
898
  this.translate = translate;
659
- this.socketService = socketService;
660
- this.wsAuthService = wsAuthService;
899
+ this.rdict = rdict;
900
+ this.localFileService = localFileService;
901
+ this.dialogService = dialogService;
661
902
  this.baseForm = new FormGroup({});
662
903
  this.model = {};
663
904
  this.options = {};
664
905
  this.fields = [];
906
+ this.saveIcon = saveIcon;
665
907
  }
666
908
  async ngOnInit() {
667
- const currentUrlSegments = this.router.url.split('/').map(segment => new UrlSegment(segment, {}));
668
- this.basePath = currentUrlSegments.map(segment => segment.path).join('/');
669
- const filteredSegments = currentUrlSegments.filter(segment => segment.path !== '');
670
- this.dictPath = filteredSegments.map(segment => segment.path).join('.');
671
- this.rdictModel = filteredSegments.length > 0 ? filteredSegments[filteredSegments.length - 2].path : ''; // Default to empty string if no valid segments
672
- this.rdict = ReactiveDictionary.getInstance(this.socketService, this.wsAuthService.Token);
673
- if (this.rdict.size == 0)
674
- await this.rdict.asyncInit();
675
- await this.getModelFields();
909
+ this.setValueFromSnapshot(this, this.route.snapshot, 'fileLayout', '');
910
+ const currentUrlSegments = this.router.url.split('/').filter(segment => segment !== '' && isNaN(Number(segment)));
911
+ if (['add', 'edit'].includes(currentUrlSegments[currentUrlSegments.length - 1])) {
912
+ currentUrlSegments.pop();
913
+ }
914
+ this.dictPath = currentUrlSegments.join('.');
915
+ this.rdictModel = currentUrlSegments.length > 0 ? currentUrlSegments[currentUrlSegments.length - 1] : '';
916
+ const id = this.route.snapshot.paramMap.get('id');
917
+ this.modelKey = id ?? null;
918
+ this.getModelFields();
919
+ this.getModel();
920
+ }
921
+ setValueFromSnapshot(component, snapshot, key, defaultValue) {
922
+ if (component[key] === undefined) {
923
+ let dataFromSnapshot = snapshot.data[key];
924
+ if (dataFromSnapshot === null || dataFromSnapshot === undefined) {
925
+ dataFromSnapshot = snapshot.params[key];
926
+ }
927
+ component[key] = dataFromSnapshot !== undefined ? dataFromSnapshot : defaultValue;
928
+ }
676
929
  }
677
930
  onSubmit(model) {
931
+ // this.saveModel(this.baseForm)
932
+ }
933
+ getModel() {
934
+ if (this.modelKey) {
935
+ this.rdict.getAsObservable(this.dictPath).subscribe({
936
+ next: value => {
937
+ value.getAsObservable(this.modelKey).subscribe({
938
+ next: modelValue => {
939
+ this.modelRdict = modelValue;
940
+ this.model = this.modelRdict.getPlainObject();
941
+ this.modelRdict.onChanges().subscribe(changes => {
942
+ if (changes) {
943
+ console.log("Changes detected:", changes);
944
+ this.baseForm.get(changes.key).patchValue(changes.value);
945
+ // this.model[changes.key] = changes.value;
946
+ }
947
+ });
948
+ }
949
+ });
950
+ },
951
+ error: err => console.error('Error:', err.message),
952
+ });
953
+ }
678
954
  }
679
- async getModelFields() {
955
+ getModelFields() {
680
956
  if (this.rdictModel) {
681
- const formLayout = await this.rdict.asyncGet("config.models." + this.rdictModel + ".formLayout");
682
- // const tableLayout = await this.rdict.asyncGet("config.models." + this.rdictModel + ".tableLayout");
683
- console.log(formLayout);
684
- // console.log(tableLayout);
685
- if (formLayout) {
686
- this.title = this.translate.instant(formLayout["title"]);
687
- this.fields = formLayout["fields"];
957
+ if (this.fileLayout) {
958
+ //load from file
959
+ this.localFileService.getJsonData(this.fileLayout).subscribe({
960
+ next: value => {
961
+ if (value) {
962
+ const layout = value.find(item => item.model === this.rdictModel);
963
+ this.setLayout(layout?.formLayout);
964
+ }
965
+ },
966
+ error: err => console.error('Error:', err.message),
967
+ });
968
+ }
969
+ else
970
+ this.rdict.getAsObservable("config.models." + this.rdictModel + ".formLayout").subscribe({
971
+ next: formLayout => {
972
+ if (formLayout) {
973
+ this.setLayout(formLayout);
974
+ }
975
+ },
976
+ error: err => console.error('Error:', err.message),
977
+ });
978
+ }
979
+ }
980
+ setLayout(formLayout) {
981
+ this.title = this.translate.instant(formLayout["title"]);
982
+ // console.log(formLayout["fields"]);
983
+ let fieldsTmp = formLayout["fields"];
984
+ this.fields = this.transformFields(fieldsTmp);
985
+ // this.transformJsonToFormlyFields()
986
+ }
987
+ // transformJsonToFormlyFields(json: any[]): FormlyFieldConfig[] {
988
+ // // return json.map(field => {
989
+ // // if (field.type === 'select' && field.props.options) {
990
+ // // field.props.options = this.getSelectData(field.props.options);
991
+ // // }
992
+ // // return {
993
+ // // key: field.key,
994
+ // // type: field.type,
995
+ // // props: field.props,
996
+ // // fieldGroup: field?.fieldGroup
997
+ // // };
998
+ // // });
999
+ // }
1000
+ transformFields(fields) {
1001
+ return fields.map(field => this.transformField(field));
1002
+ }
1003
+ transformField(field) {
1004
+ // Handle the current field
1005
+ if (field.type === 'select' && field.props?.options && typeof field.props.options === 'string') {
1006
+ field.props.options = this.getSelectData(field.props.options);
1007
+ }
1008
+ // Recursively handle fieldGroup
1009
+ if (field.fieldGroup) {
1010
+ field.fieldGroup = this.transformFields(field.fieldGroup);
1011
+ }
1012
+ // Recursively handle fieldArray
1013
+ if (field.fieldArray) {
1014
+ if (typeof field.fieldArray === 'function') {
1015
+ const originalFieldArrayFn = field.fieldArray;
1016
+ field.fieldArray = (fieldConfig) => {
1017
+ const transformedField = this.transformField(originalFieldArrayFn(fieldConfig));
1018
+ return transformedField;
1019
+ };
688
1020
  }
1021
+ else {
1022
+ field.fieldArray = this.transformField(field.fieldArray);
1023
+ }
1024
+ }
1025
+ return field;
1026
+ }
1027
+ async onSave() {
1028
+ await this.saveModel(this.baseForm);
1029
+ }
1030
+ async saveModel(fg) {
1031
+ if (fg.valid) {
1032
+ var dict = await this.rdict.asyncGet(this.dictPath);
1033
+ await dict.update(fg.value, this.modelKey);
1034
+ this.dialogService.showSaveMessage();
1035
+ // console.log(fg.value);
1036
+ }
1037
+ else {
1038
+ this.validateAllFormFields(fg);
689
1039
  }
690
1040
  }
691
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: RdictCrudComponent, deps: [{ token: i1$1.Router }, { token: i1$1.ActivatedRoute }, { token: i2.TranslateService }, { token: SocketService }, { token: WsAuthService }], target: i0.ɵɵFactoryTarget.Component }); }
692
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.1.3", type: RdictCrudComponent, isStandalone: true, selector: "app-rdict-crud", ngImport: i0, template: "<form [formGroup]=\"baseForm\" (ngSubmit)=\"onSubmit(model)\">\r\n <formly-form [form]=\"baseForm\" [fields]=\"fields\" [model]=\"model\" [options]=\"options\"></formly-form>\r\n</form>", styles: [""], dependencies: [{ kind: "ngmodule", type: FormlyModule }, { kind: "component", type: i4$1.FormlyForm, selector: "formly-form", inputs: ["form", "model", "fields", "options"], outputs: ["modelChange"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i5$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i5$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i5$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: FormlyKendoModule }, { kind: "ngmodule", type: TranslateModule }, { kind: "ngmodule", type: CrudFormlyTransaltionModule }] }); }
1041
+ validateAllFormFields(fg) {
1042
+ Object.keys(fg.controls).forEach(field => {
1043
+ // console.log(field);
1044
+ const control = fg.get(field);
1045
+ if (control instanceof FormControl) {
1046
+ control.markAsTouched({ onlySelf: true });
1047
+ }
1048
+ else if (control instanceof FormGroup) {
1049
+ this.validateAllFormFields(control);
1050
+ }
1051
+ });
1052
+ }
1053
+ getSelectData(key) {
1054
+ return this.rdict.getTableAsObservable(key);
1055
+ }
1056
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: RdictCrudComponent, deps: [{ token: i1$1.Router }, { token: i1$1.ActivatedRoute }, { token: i2.TranslateService }, { token: ReactiveDictionary }, { token: i1.LocalFileService }, { token: MaterialDialogService }], target: i0.ɵɵFactoryTarget.Component }); }
1057
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.1.3", type: RdictCrudComponent, isStandalone: true, selector: "app-rdict-crud", ngImport: i0, template: "<kendo-toolbar>\r\n <kendo-toolbar-spacer></kendo-toolbar-spacer>\r\n <kendo-toolbar-button text=\"Save\" showText=\"both\" [svgIcon]=\"saveIcon\" showIcon=\"both\" themeColor=\"primary\"\r\n [disabled]=\"false\" (click)=\"onSave()\">\r\n </kendo-toolbar-button>\r\n</kendo-toolbar>\r\n<form [formGroup]=\"baseForm\" (ngSubmit)=\"onSubmit(model)\">\r\n\r\n <formly-form [form]=\"baseForm\" [fields]=\"fields\" [model]=\"model\" [options]=\"options\"></formly-form>\r\n</form>", styles: [""], 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"] }] }); }
693
1058
  }
694
1059
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: RdictCrudComponent, decorators: [{
695
1060
  type: Component,
@@ -698,9 +1063,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.3", ngImpor
698
1063
  ReactiveFormsModule,
699
1064
  FormlyKendoModule,
700
1065
  TranslateModule,
701
- CrudFormlyTransaltionModule
702
- ], template: "<form [formGroup]=\"baseForm\" (ngSubmit)=\"onSubmit(model)\">\r\n <formly-form [form]=\"baseForm\" [fields]=\"fields\" [model]=\"model\" [options]=\"options\"></formly-form>\r\n</form>" }]
703
- }], ctorParameters: () => [{ type: i1$1.Router }, { type: i1$1.ActivatedRoute }, { type: i2.TranslateService }, { type: SocketService }, { type: WsAuthService }] });
1066
+ CrudFormlyTransaltionModule,
1067
+ KENDO_TOOLBAR
1068
+ ], template: "<kendo-toolbar>\r\n <kendo-toolbar-spacer></kendo-toolbar-spacer>\r\n <kendo-toolbar-button text=\"Save\" showText=\"both\" [svgIcon]=\"saveIcon\" showIcon=\"both\" themeColor=\"primary\"\r\n [disabled]=\"false\" (click)=\"onSave()\">\r\n </kendo-toolbar-button>\r\n</kendo-toolbar>\r\n<form [formGroup]=\"baseForm\" (ngSubmit)=\"onSubmit(model)\">\r\n\r\n <formly-form [form]=\"baseForm\" [fields]=\"fields\" [model]=\"model\" [options]=\"options\"></formly-form>\r\n</form>" }]
1069
+ }], ctorParameters: () => [{ type: i1$1.Router }, { type: i1$1.ActivatedRoute }, { type: i2.TranslateService }, { type: ReactiveDictionary }, { type: i1.LocalFileService }, { type: MaterialDialogService }] });
704
1070
 
705
1071
  class RdictTableTitle extends ToolBarToolComponent {
706
1072
  constructor() {
@@ -712,7 +1078,7 @@ class RdictTableTitle extends ToolBarToolComponent {
712
1078
  <ng-template #toolbarTemplate>
713
1079
  <kendo-label>{{text}}</kendo-label>
714
1080
  </ng-template>
715
- `, isInline: true }); }
1081
+ `, isInline: true, dependencies: [{ kind: "component", type: i1$2.LabelComponent, selector: "kendo-label", inputs: ["text", "for", "optional", "labelCssStyle", "labelCssClass"], exportAs: ["kendoLabel"] }] }); }
716
1082
  }
717
1083
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: RdictTableTitle, decorators: [{
718
1084
  type: Component,
@@ -720,6 +1086,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.3", ngImpor
720
1086
  providers: [{ provide: ToolBarToolComponent, useExisting: forwardRef(() => RdictTableTitle) }],
721
1087
  selector: 'table-title',
722
1088
  standalone: true,
1089
+ imports: [
1090
+ KENDO_LABEL,
1091
+ ],
723
1092
  template: `
724
1093
  <ng-template #toolbarTemplate>
725
1094
  <kendo-label>{{text}}</kendo-label>
@@ -734,14 +1103,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.3", ngImpor
734
1103
  }] } });
735
1104
 
736
1105
  class GenericRdictTableComponent {
737
- constructor(router, route, translate, injector, socketService, wsAuthService, el) {
1106
+ constructor(router, route, translate, injector, localFileService, rdict, dialogService) {
738
1107
  this.router = router;
739
1108
  this.route = route;
740
1109
  this.translate = translate;
741
1110
  this.injector = injector;
742
- this.socketService = socketService;
743
- this.wsAuthService = wsAuthService;
744
- this.el = el;
1111
+ this.localFileService = localFileService;
1112
+ this.rdict = rdict;
1113
+ this.dialogService = dialogService;
745
1114
  this.editOnClick = false;
746
1115
  this.editOnDblClick = false;
747
1116
  this.data = [];
@@ -761,6 +1130,9 @@ class GenericRdictTableComponent {
761
1130
  // SelectionType = SelectionType;
762
1131
  this.headerHeight = 50;
763
1132
  this.rowHeight = 50;
1133
+ this.svgEdit = pencilIcon;
1134
+ this.svgDelete = trashIcon;
1135
+ this.svgAdd = plusIcon;
764
1136
  }
765
1137
  async ngOnInit() {
766
1138
  this.setValueFromSnapshot(this, this.route.snapshot, 'model', "");
@@ -778,6 +1150,8 @@ class GenericRdictTableComponent {
778
1150
  this.setValueFromSnapshot(this, this.route.snapshot, 'canEdit', true);
779
1151
  this.setValueFromSnapshot(this, this.route.snapshot, 'editOnClick', false);
780
1152
  this.setValueFromSnapshot(this, this.route.snapshot, 'editOnDblClick', false);
1153
+ this.setValueFromSnapshot(this, this.route.snapshot, 'editColumn', null);
1154
+ this.setValueFromSnapshot(this, this.route.snapshot, 'fileLayout', '');
781
1155
  const currentUrlSegments = this.router.url.split('/').map(segment => new UrlSegment(segment, {}));
782
1156
  this.basePath = currentUrlSegments.map(segment => segment.path).join('/');
783
1157
  const filteredSegments = currentUrlSegments.filter(segment => segment.path !== '');
@@ -791,13 +1165,8 @@ class GenericRdictTableComponent {
791
1165
  // Perform actions or update component as needed
792
1166
  }
793
1167
  });
794
- this.rdict = ReactiveDictionary.getInstance(this.socketService, this.wsAuthService.Token);
795
- if (this.rdict.size == 0)
796
- await this.rdict.asyncInit();
797
- await this.getListLayout();
798
- await this.loadData();
799
- // this.isLoading = true;
800
- // this.onScroll(0);
1168
+ this.getListLayout();
1169
+ this.loadData();
801
1170
  }
802
1171
  setValueFromSnapshot(component, snapshot, key, defaultValue) {
803
1172
  if (component[key] === undefined) {
@@ -809,130 +1178,147 @@ class GenericRdictTableComponent {
809
1178
  }
810
1179
  }
811
1180
  async loadData() {
812
- var x = await this.rdict.getTable(this.dictPath);
813
- const result = x.map(dictionary => {
814
- // Convert Map to object and filter out __guid
815
- const filteredObject = {};
816
- for (const [key, value] of dictionary.entries()) {
817
- if (key !== '__guid') {
818
- filteredObject[key] = value;
1181
+ this.rdict.getAsObservable(this.dictPath).subscribe({
1182
+ next: rdictData => {
1183
+ this.tableRdict = rdictData;
1184
+ this.tableRdict.onChanges().subscribe({
1185
+ next: (changes) => {
1186
+ console.log("Changes detected grid:", changes);
1187
+ this.onChangeEvent(changes);
1188
+ }
1189
+ });
1190
+ this.tableRdict.onDelete().subscribe({
1191
+ next: (changes) => {
1192
+ console.log("Delete detected grid:", changes);
1193
+ this.ondDeleteEvent(changes);
1194
+ }
1195
+ });
1196
+ this.rdict.getTableAsObservable(this.dictPath, this.tableRdict).subscribe({
1197
+ next: value => {
1198
+ this.dataSource = value;
1199
+ },
1200
+ error: err => console.error('Error:', err.message),
1201
+ });
1202
+ },
1203
+ error: err => console.error('Error:', err.message),
1204
+ });
1205
+ }
1206
+ onChangeEvent(changes) {
1207
+ if (changes) {
1208
+ const key = changes?.key;
1209
+ const value = changes?.value;
1210
+ if (key && value) {
1211
+ const index = this.dataSource.findIndex((item) => item.__idx === key);
1212
+ if (index > -1) {
1213
+ this.dataSource[index] = value;
1214
+ }
1215
+ else {
1216
+ //get the object from rdict
1217
+ this.tableRdict.getAsObservable(key).subscribe({
1218
+ next: value => {
1219
+ var dd = value.getPlainObject();
1220
+ this.dataSource.push(dd);
1221
+ }
1222
+ });
819
1223
  }
820
1224
  }
821
- return filteredObject;
822
- });
823
- this.dataSource = result; //new MatTableDataSource(result);
1225
+ }
824
1226
  }
825
- // async handleChange(event) {
826
- // this.filterValue = event.target.value.toLowerCase();
827
- // this.data = [];
828
- // this.pageIndex = 1
829
- // this.loadData();
830
- // }
831
- // loadData(event = null) {
832
- // const filters = [];
833
- // let sorts = '';
834
- // this.isLoading = true;
835
- // if (this.defaultSort) {
836
- // if (this.defaultSortDirection === 'desc') {
837
- // sorts = '-' + this.defaultSort;
838
- // } else {
839
- // sorts = this.defaultSort;
840
- // }
841
- // }
842
- // if (this.showSerach) {
843
- // if (this.filterValue) {
844
- // const y = '(' + this.searchFields.replace(',', '|') + ')';
845
- // filters.push(y + '@=*' + this.filterValue);
846
- // }
847
- // }
848
- // if (this.defaultFilter) {
849
- // filters.push(this.defaultFilter)
850
- // }
851
- // setTimeout(() => {
852
- // const filtersValue = filters.join(', ');
853
- // this.modelService.getAll(this.pageIndex, this.pageSize, sorts, filtersValue, this.customInclude).subscribe(
854
- // (response: BaseQueryData<T>) => {
855
- // if (this.pageIndex !== response.getMeta().meta.count) {
856
- // this.pageIndex++
857
- // } else {
858
- // if (event) event.target.disabled = true;
859
- // }
860
- // // if (this.filterValue)
861
- // // this.data = response.getModels();
862
- // // else
863
- // const rows = [...this.data, ...response.getModels()];
864
- // this.data = rows;
865
- // // this.data = this.data.concat();
866
- // if (event) event.target.complete();
867
- // this.isLoading = false;
868
- // })
869
- // }, 700);
870
- // }
871
- // async handleRefresh(event) {
872
- // this.pageIndex = 1
873
- // this.data = [];
874
- // this.loadData();
875
- // event.target.complete();
876
- // }
877
- // onAdd() {
878
- // console.log(this.basePath)
879
- // this.router.navigate([this.basePath + '/add'])
880
- // // this.navCtrl.navigateForward(this.basePath + '/add');
881
- // }
882
- // editModel(model: BaseModelFormly) {
883
- // if (this.canEdit)
884
- // this.router.navigate([this.basePath + '/edit/', model.id]);
885
- // // this.navCtrl.navigateForward(this.basePath + '/edit/' + model.id);
886
- // }
887
- async getListLayout() {
1227
+ ondDeleteEvent(changes) {
1228
+ if (changes) {
1229
+ const key = changes?.key;
1230
+ if (key) {
1231
+ const index = this.dataSource.findIndex((item) => item.__idx === key);
1232
+ if (index > -1) {
1233
+ this.dataSource.splice(index, 1);
1234
+ }
1235
+ // this.tableRdict.delete(key)
1236
+ }
1237
+ }
1238
+ }
1239
+ getListLayout() {
888
1240
  if (this.model) {
889
- this.tableLayout = await this.rdict.asyncGet("config.models." + this.model + ".tableLayout");
890
- const formLayout = await this.rdict.asyncGet("config.models." + this.model + ".formLayout");
891
- console.log(formLayout);
892
- if (this.tableLayout) {
893
- this.title = this.translate.instant(this.tableLayout["title"]);
894
- this.allColumns = this.tableLayout["columns"].map(item => {
895
- if (!item.isTranslated) {
896
- item.name = this.translate.instant(item.translateKey);
897
- item.isTranslated = true;
898
- }
899
- return item;
1241
+ if (this.fileLayout) {
1242
+ //load from file
1243
+ this.localFileService.getJsonData(this.fileLayout).subscribe({
1244
+ next: value => {
1245
+ if (value) {
1246
+ const layout = value.find(item => item.model === this.model);
1247
+ this.setLayout(layout?.tableLayout);
1248
+ }
1249
+ },
1250
+ error: err => console.error('Error:', err.message),
900
1251
  });
901
- this.columns = [];
902
- this.allColumns.sort((a, b) => a.order - b.order);
903
- // if (this.canDelete || this.canEdit) {
904
- // this.allColumns.push({
905
- // // cellTemplate: null,
906
- // name: '',
907
- // // cellClass: 'actions-cell',
908
- // draggable: false,
909
- // sortable: false,
910
- // visible: true
911
- // // width: 100,
912
- // // maxWidth: 100,
913
- // // minWidth: 100
914
- // })
915
- // }
916
- // this.columns = this.allColumns.filter((item: IonicDataTableLayoutConfig) => item.visible);
917
- this.displayedColumns = [];
918
- // if (this.allowReorderItems) {
919
- // this.displayedColumns.push('position')
920
- // }
921
- this.displayedColumns.push.apply(this.displayedColumns, this.allColumns.map(x => x.propertyName));
922
1252
  }
1253
+ else
1254
+ //Use rdict layout
1255
+ this.rdict.getAsObservable("config.models." + this.model + ".tableLayout").subscribe({
1256
+ next: value => {
1257
+ this.setLayout(value);
1258
+ },
1259
+ error: err => console.error('Error:', err.message),
1260
+ });
1261
+ }
1262
+ }
1263
+ setLayout(layout) {
1264
+ if (layout) {
1265
+ this.tableLayout = layout;
1266
+ this.title = this.translate.instant(this.tableLayout["title"]);
1267
+ this.allColumns = this.tableLayout["columns"].map(item => {
1268
+ if (!item.isTranslated) {
1269
+ item.name = this.translate.instant(item.translateKey);
1270
+ item.isTranslated = true;
1271
+ item.isEditLink = false;
1272
+ if (this.editColumn && this.editColumn === item.propertyName) {
1273
+ item.isEditLink = true;
1274
+ }
1275
+ }
1276
+ return item;
1277
+ });
1278
+ this.columns = [];
1279
+ this.allColumns.sort((a, b) => a.order - b.order);
1280
+ this.displayedColumns = [];
1281
+ this.displayedColumns.push.apply(this.displayedColumns, this.allColumns.map(x => x.propertyName));
923
1282
  }
924
1283
  }
925
1284
  addHandler() {
926
- console.log("add");
927
- this.router.navigate([this.basePath + '/add']);
928
- // this.editDataItem = new Product();
929
- // this.isNew = true;
1285
+ this.router.navigate([`${this.basePath}/add`]);
1286
+ }
1287
+ editHandler(args) {
1288
+ this.edit(args.dataItem);
1289
+ // this.editDataItem = args.dataItem;
1290
+ // this.isNew = false;
1291
+ }
1292
+ edit(dataItem) {
1293
+ this.router.navigate([`${this.basePath}/edit/${dataItem.__idx}`]);
1294
+ }
1295
+ removeHandler(args) {
1296
+ this.dialogService.confirmDelete().subscribe({
1297
+ next: (result) => {
1298
+ if (result) {
1299
+ this.tableRdict.deleteAsObservable(args.dataItem.__idx).subscribe({
1300
+ next: (result) => {
1301
+ this.dataSource.splice(args.rowIndex, 1);
1302
+ }
1303
+ });
1304
+ }
1305
+ }
1306
+ });
1307
+ // this.editService.remove(args.dataItem);
1308
+ }
1309
+ getCellValue(item, propertyName) {
1310
+ if (item instanceof ReactiveDictionary) {
1311
+ console.log(item);
1312
+ }
1313
+ else {
1314
+ return item[propertyName];
1315
+ }
930
1316
  }
931
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: GenericRdictTableComponent, deps: [{ token: i1$1.Router }, { token: i1$1.ActivatedRoute }, { token: i2.TranslateService }, { token: i0.Injector }, { token: SocketService }, { token: WsAuthService }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component }); }
932
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.1.3", 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\" \r\n [sortable]=\"true\" \r\n [filterable]=\"showSerach\"\r\n (add)=\"addHandler()\">\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 text=\"Add new\" kendoGridAddTool></kendo-toolbar-button>\r\n </kendo-toolbar>\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</kendo-grid>", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i5$2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "ngmodule", type: RouterModule }, { kind: "ngmodule", type:
1317
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: GenericRdictTableComponent, deps: [{ token: i1$1.Router }, { token: i1$1.ActivatedRoute }, { token: i2.TranslateService }, { token: i0.Injector }, { token: i1.LocalFileService }, { token: ReactiveDictionary }, { token: MaterialDialogService }], target: i0.ɵɵFactoryTarget.Component }); }
1318
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.1.3", 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 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.propertyName) }}\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.propertyName) }}\r\n </ng-template>\r\n </kendo-grid-column>\r\n\r\n\r\n <kendo-grid-command-column 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 kendoGridEditCommand [svgIcon]=\"svgEdit\" themeColor=\"light\"></button>\r\n <button 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:
933
1319
  // MatPaginatorModule,
934
1320
  // MatTableModule,
935
- TranslateModule }, { kind: "pipe", type: i2.TranslatePipe, name: "translate" }, { kind: "component", type: i6.GridComponent, selector: "kendo-grid", inputs: ["data", "pageSize", "height", "rowHeight", "detailRowHeight", "skip", "scrollable", "selectable", "sort", "size", "trackBy", "filter", "group", "virtualColumns", "filterable", "sortable", "pageable", "groupable", "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: "component", type: i6.ColumnComponent, selector: "kendo-grid-column", inputs: ["field", "format", "sortable", "groupable", "editor", "filter", "filterable", "editable"] }, { kind: "directive", type: i6.AddCommandToolbarDirective, selector: "[kendoGridAddTool]" }, { kind: "component", type: i7.ToolBarComponent, selector: "kendo-toolbar", inputs: ["overflow", "resizable", "popupSettings", "fillMode", "tabindex", "size", "tabIndex"], outputs: ["open", "close"], exportAs: ["kendoToolBar"] }, { kind: "component", type: i7.ToolbarCustomMessagesComponent, selector: "kendo-toolbar-messages" }, { kind: "component", type: i7.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: i7.ToolBarSpacerComponent, selector: "kendo-toolbar-spacer", exportAs: ["kendoToolBarSpacer"] }, { kind: "component", type: RdictTableTitle, selector: "table-title", inputs: ["text"] }], encapsulation: i0.ViewEncapsulation.None }); }
1321
+ 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", "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 }); }
936
1322
  }
937
1323
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: GenericRdictTableComponent, decorators: [{
938
1324
  type: Component,
@@ -945,9 +1331,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.3", ngImpor
945
1331
  KENDO_GRID,
946
1332
  KENDO_TOOLBAR,
947
1333
  KENDO_LABEL,
1334
+ KENDO_BUTTONS,
1335
+ KENDO_DIALOG,
948
1336
  RdictTableTitle
949
- ], providers: [], template: "<kendo-grid [data]=\"dataSource\" \r\n [sortable]=\"true\" \r\n [filterable]=\"showSerach\"\r\n (add)=\"addHandler()\">\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 text=\"Add new\" kendoGridAddTool></kendo-toolbar-button>\r\n </kendo-toolbar>\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</kendo-grid>" }]
950
- }], ctorParameters: () => [{ type: i1$1.Router }, { type: i1$1.ActivatedRoute }, { type: i2.TranslateService }, { type: i0.Injector }, { type: SocketService }, { type: WsAuthService }, { type: i0.ElementRef }], propDecorators: { showSerach: [{
1337
+ ], 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 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.propertyName) }}\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.propertyName) }}\r\n </ng-template>\r\n </kendo-grid-column>\r\n\r\n\r\n <kendo-grid-command-column 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 kendoGridEditCommand [svgIcon]=\"svgEdit\" themeColor=\"light\"></button>\r\n <button 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"] }]
1338
+ }], ctorParameters: () => [{ type: i1$1.Router }, { type: i1$1.ActivatedRoute }, { type: i2.TranslateService }, { type: i0.Injector }, { type: i1.LocalFileService }, { type: ReactiveDictionary }, { type: MaterialDialogService }], propDecorators: { showSerach: [{
951
1339
  type: Input
952
1340
  }], searchFields: [{
953
1341
  type: Input
@@ -993,5 +1381,5 @@ const SOCKET_URL = new InjectionToken('SocketUrl');
993
1381
  * Generated bundle index. Do not edit.
994
1382
  */
995
1383
 
996
- export { FullComponent, GenericRdictTableComponent, Menu, RdictCrudComponent, ReactiveDictionary, Right, SOCKET_URL, SocketService, User, UserService, WsAuthService };
1384
+ export { FullComponent, GenericRdictTableComponent, Menu, RdictCrudComponent, ReactiveDictionary, Right, SOCKET_URL, SocketService, User, UserService };
997
1385
  //# sourceMappingURL=rosoftlab-rdict.mjs.map