@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.
- package/fesm2022/rosoftlab-rdict.mjs +721 -333
- package/fesm2022/rosoftlab-rdict.mjs.map +1 -1
- package/lib/components/layouts/full/full.component.d.ts +4 -5
- package/lib/components/rdict-crud/rdict-crud.component.d.ts +23 -7
- package/lib/components/rdict-generic-table/rdict-generic-table.component.d.ts +22 -8
- package/lib/reactive-dictionary.d.ts +17 -4
- package/lib/services/index.d.ts +0 -1
- package/lib/services/material-dialog.service.d.ts +17 -0
- package/lib/services/socket.service.d.ts +4 -0
- package/package.json +2 -2
- package/lib/services/ws-auth.service.d.ts +0 -9
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as
|
|
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
|
|
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
|
|
12
|
+
import * as i6 from '@progress/kendo-angular-layout';
|
|
13
13
|
import { LayoutModule } from '@progress/kendo-angular-layout';
|
|
14
|
-
import * as
|
|
15
|
-
import { ToolBarModule,
|
|
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 {
|
|
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
|
|
25
|
-
import { FormGroup, ReactiveFormsModule } from '@angular/forms';
|
|
26
|
-
import * as
|
|
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
|
|
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
|
|
188
|
+
static { this.instance = new Map(); }
|
|
189
|
+
constructor(socketService) {
|
|
36
190
|
super();
|
|
37
|
-
this.changes$ = new
|
|
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
|
|
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
|
-
|
|
166
|
-
|
|
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
|
-
|
|
171
|
-
|
|
172
|
-
if (
|
|
173
|
-
|
|
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
|
-
|
|
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
|
-
|
|
181
|
-
|
|
182
|
-
|
|
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) =>
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
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
|
|
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
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
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
|
-
|
|
219
|
-
if (
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
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
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
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
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
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
|
-
|
|
254
|
-
|
|
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
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
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
|
-
|
|
280
|
-
|
|
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:
|
|
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:
|
|
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,
|
|
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.
|
|
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:
|
|
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:
|
|
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:
|
|
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.
|
|
660
|
-
this.
|
|
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
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
this.
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
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
|
-
|
|
955
|
+
getModelFields() {
|
|
680
956
|
if (this.rdictModel) {
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
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
|
-
|
|
692
|
-
|
|
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
|
-
|
|
703
|
-
|
|
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,
|
|
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.
|
|
743
|
-
this.
|
|
744
|
-
this.
|
|
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.
|
|
795
|
-
|
|
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
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
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
|
-
|
|
822
|
-
});
|
|
823
|
-
this.dataSource = result; //new MatTableDataSource(result);
|
|
1225
|
+
}
|
|
824
1226
|
}
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
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
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
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
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
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:
|
|
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\"
|
|
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:
|
|
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\"
|
|
950
|
-
}], ctorParameters: () => [{ type: i1$1.Router }, { type: i1$1.ActivatedRoute }, { type: i2.TranslateService }, { type: i0.Injector }, { type:
|
|
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
|
|
1384
|
+
export { FullComponent, GenericRdictTableComponent, Menu, RdictCrudComponent, ReactiveDictionary, Right, SOCKET_URL, SocketService, User, UserService };
|
|
997
1385
|
//# sourceMappingURL=rosoftlab-rdict.mjs.map
|