underpost 3.2.5 → 3.2.8
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/.github/workflows/release.cd.yml +1 -2
- package/CHANGELOG.md +251 -1
- package/CLI-HELP.md +26 -13
- package/Dockerfile +0 -4
- package/README.md +3 -3
- package/bin/build.js +13 -3
- package/bin/deploy.js +570 -1
- package/bin/file.js +5 -0
- package/conf.js +11 -2
- package/jsconfig.json +1 -1
- package/manifests/cronjobs/dd-cron/dd-cron-backup.yaml +1 -1
- package/manifests/cronjobs/dd-cron/dd-cron-dns.yaml +1 -1
- package/manifests/deployment/dd-default-development/deployment.yaml +2 -6
- package/manifests/deployment/dd-test-development/deployment.yaml +136 -66
- package/manifests/deployment/dd-test-development/proxy.yaml +41 -5
- package/package.json +20 -11
- package/src/api/core/core.controller.js +10 -10
- package/src/api/core/core.service.js +10 -10
- package/src/api/default/default.controller.js +10 -10
- package/src/api/default/default.service.js +10 -10
- package/src/api/document/document.controller.js +12 -12
- package/src/api/document/document.model.js +10 -16
- package/src/api/file/file.controller.js +8 -8
- package/src/api/file/file.model.js +10 -10
- package/src/api/file/file.service.js +36 -36
- package/src/api/test/test.controller.js +8 -8
- package/src/api/test/test.service.js +8 -8
- package/src/api/user/guest.service.js +99 -0
- package/src/api/user/user.controller.js +6 -6
- package/src/api/user/user.model.js +8 -13
- package/src/api/user/user.service.js +3 -20
- package/src/cli/deploy.js +33 -30
- package/src/cli/fs.js +62 -5
- package/src/cli/image.js +43 -1
- package/src/cli/index.js +5 -1
- package/src/cli/release.js +57 -1
- package/src/cli/repository.js +35 -3
- package/src/cli/run.js +300 -35
- package/src/cli/ssh.js +1 -1
- package/src/cli/static.js +43 -115
- package/src/client/Default.index.js +21 -33
- package/src/client/components/core/404.js +4 -4
- package/src/client/components/core/500.js +4 -4
- package/src/client/components/core/Account.js +73 -60
- package/src/client/components/core/AgGrid.js +23 -33
- package/src/client/components/core/Alert.js +12 -13
- package/src/client/components/core/AppStore.js +1 -1
- package/src/client/components/core/Auth.js +20 -32
- package/src/client/components/core/Badge.js +7 -13
- package/src/client/components/core/BtnIcon.js +15 -17
- package/src/client/components/core/CalendarCore.js +42 -63
- package/src/client/components/core/Chat.js +13 -15
- package/src/client/components/core/ClientEvents.js +87 -0
- package/src/client/components/core/ColorPaletteElement.js +309 -0
- package/src/client/components/core/Content.js +17 -14
- package/src/client/components/core/Css.js +15 -71
- package/src/client/components/core/CssCore.js +12 -16
- package/src/client/components/core/D3Chart.js +4 -4
- package/src/client/components/core/Docs.js +60 -59
- package/src/client/components/core/DropDown.js +69 -91
- package/src/client/components/core/EventBus.js +92 -0
- package/src/client/components/core/EventsUI.js +14 -17
- package/src/client/components/core/FileExplorer.js +102 -234
- package/src/client/components/core/FullScreen.js +47 -75
- package/src/client/components/core/Input.js +24 -69
- package/src/client/components/core/Keyboard.js +25 -18
- package/src/client/components/core/KeyboardAvoidance.js +145 -0
- package/src/client/components/core/LoadingAnimation.js +25 -31
- package/src/client/components/core/LogIn.js +41 -41
- package/src/client/components/core/LogOut.js +23 -14
- package/src/client/components/core/Modal.js +397 -176
- package/src/client/components/core/NotificationManager.js +14 -18
- package/src/client/components/core/Panel.js +54 -50
- package/src/client/components/core/PanelForm.js +25 -125
- package/src/client/components/core/Polyhedron.js +110 -214
- package/src/client/components/core/PublicProfile.js +39 -32
- package/src/client/components/core/Recover.js +52 -48
- package/src/client/components/core/Responsive.js +88 -32
- package/src/client/components/core/RichText.js +9 -18
- package/src/client/components/core/Router.js +24 -3
- package/src/client/components/core/SearchBox.js +37 -37
- package/src/client/components/core/SignUp.js +39 -30
- package/src/client/components/core/SocketIo.js +31 -2
- package/src/client/components/core/SocketIoHandler.js +6 -6
- package/src/client/components/core/ToggleSwitch.js +8 -20
- package/src/client/components/core/ToolTip.js +5 -17
- package/src/client/components/core/Translate.js +56 -59
- package/src/client/components/core/Validator.js +26 -16
- package/src/client/components/core/Wallet.js +15 -26
- package/src/client/components/core/Worker.js +140 -25
- package/src/client/components/core/windowGetDimensions.js +7 -7
- package/src/client/components/default/{MenuDefault.js → AppShellDefault.js} +87 -87
- package/src/client/components/default/CssDefault.js +12 -12
- package/src/client/components/default/LogInDefault.js +6 -4
- package/src/client/components/default/LogOutDefault.js +6 -4
- package/src/client/components/default/RouterDefault.js +47 -0
- package/src/client/components/default/SettingsDefault.js +4 -4
- package/src/client/components/default/SignUpDefault.js +6 -4
- package/src/client/components/default/TranslateDefault.js +3 -3
- package/src/client/services/core/core.service.js +17 -49
- package/src/client/services/default/default.management.js +139 -242
- package/src/client/services/default/default.service.js +10 -16
- package/src/client/services/document/document.service.js +14 -19
- package/src/client/services/file/file.service.js +8 -13
- package/src/client/services/test/test.service.js +8 -13
- package/src/client/services/user/guest.service.js +79 -0
- package/src/client/services/user/user.management.js +5 -5
- package/src/client/services/user/user.service.js +14 -20
- package/src/client/ssr/body/404.js +3 -3
- package/src/client/ssr/body/500.js +3 -3
- package/src/client/ssr/body/CacheControl.js +5 -2
- package/src/client/ssr/body/DefaultSplashScreen.js +19 -12
- package/src/client/ssr/mailer/DefaultRecoverEmail.js +19 -20
- package/src/client/ssr/mailer/DefaultVerifyEmail.js +15 -16
- package/src/client/ssr/offline/Maintenance.js +12 -11
- package/src/client/ssr/offline/NoNetworkConnection.js +3 -3
- package/src/client/ssr/pages/Test.js +2 -2
- package/src/client/sw/core.sw.js +212 -0
- package/src/index.js +1 -1
- package/src/runtime/express/Dockerfile +4 -4
- package/src/runtime/lampp/Dockerfile +8 -7
- package/src/runtime/wp/Dockerfile +11 -17
- package/src/server/client-build-docs.js +45 -46
- package/src/server/client-build.js +334 -60
- package/src/server/client-formatted.js +47 -16
- package/src/server/conf.js +5 -4
- package/src/server/ipfs-client.js +232 -91
- package/src/server/process.js +13 -27
- package/src/server/start.js +6 -3
- package/src/server/valkey.js +134 -235
- package/tsconfig.docs.json +15 -0
- package/typedoc.json +20 -0
- package/jsdoc.json +0 -52
- package/src/client/components/core/ColorPalette.js +0 -5267
- package/src/client/components/core/JoyStick.js +0 -80
- package/src/client/components/default/RoutesDefault.js +0 -49
- package/src/client/sw/default.sw.js +0 -127
- package/src/client/sw/template.sw.js +0 -84
|
@@ -10,44 +10,39 @@ import { Translate } from '../../components/core/Translate.js';
|
|
|
10
10
|
import { getQueryParams, listenQueryParamsChange, RouterEvents, setQueryParams } from '../../components/core/Router.js';
|
|
11
11
|
import { s } from '../../components/core/VanillaJs.js';
|
|
12
12
|
import { DefaultService } from './default.service.js';
|
|
13
|
-
|
|
14
13
|
const logger = loggerFactory(import.meta);
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
columnDefs: [
|
|
14
|
+
class DefaultOptions {
|
|
15
|
+
static idModal = 'modal-default-management';
|
|
16
|
+
static serviceId = 'default-management';
|
|
17
|
+
static entity = 'default';
|
|
18
|
+
static columnDefs = [
|
|
21
19
|
{ field: '0', headerName: '0', cellClassRules: { 'row-new-highlight': (params) => true } },
|
|
22
20
|
{ field: '1', headerName: '1' },
|
|
23
21
|
{ field: '2', headerName: '2' },
|
|
24
22
|
{ field: 'createdAt', headerName: 'createdAt', cellDataType: 'date', editable: false },
|
|
25
23
|
{ field: 'updatedAt', headerName: 'updatedAt', cellDataType: 'date', editable: false },
|
|
26
|
-
]
|
|
27
|
-
defaultColKeyFocus
|
|
28
|
-
ServiceProvider
|
|
29
|
-
permissions
|
|
24
|
+
];
|
|
25
|
+
static defaultColKeyFocus = '0';
|
|
26
|
+
static ServiceProvider = DefaultService;
|
|
27
|
+
static permissions = {
|
|
30
28
|
add: true,
|
|
31
29
|
remove: true,
|
|
32
30
|
reload: true,
|
|
33
|
-
}
|
|
34
|
-
paginationOptions
|
|
31
|
+
};
|
|
32
|
+
static paginationOptions = {
|
|
35
33
|
limitOptions: [10, 20, 50, 100],
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
34
|
+
};
|
|
35
|
+
}
|
|
39
36
|
const columnDefFormatter = (obj, columnDefs, customFormat) => {
|
|
40
37
|
for (const colDef of columnDefs)
|
|
41
38
|
switch (colDef.cellDataType) {
|
|
42
39
|
case 'date': {
|
|
43
40
|
const value = obj[colDef.field];
|
|
44
|
-
|
|
45
41
|
// Do NOT default missing/blank dates to "now" — render as empty instead.
|
|
46
42
|
if (value === null || value === undefined || value === '') {
|
|
47
43
|
obj[colDef.field] = null;
|
|
48
44
|
break;
|
|
49
45
|
}
|
|
50
|
-
|
|
51
46
|
const date = new Date(value);
|
|
52
47
|
obj[colDef.field] = isNaN(date.getTime()) ? null : date;
|
|
53
48
|
break;
|
|
@@ -59,69 +54,64 @@ const columnDefFormatter = (obj, columnDefs, customFormat) => {
|
|
|
59
54
|
}
|
|
60
55
|
return customFormat ? customFormat(obj) : obj;
|
|
61
56
|
};
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
Tokens: {},
|
|
57
|
+
class DefaultManagement {
|
|
58
|
+
static Tokens = {};
|
|
65
59
|
// Helper functions for managing serviceOptions ID filter
|
|
66
|
-
setIdFilter
|
|
67
|
-
if (!
|
|
68
|
-
|
|
60
|
+
static setIdFilter(id, itemId) {
|
|
61
|
+
if (!DefaultManagement.Tokens[id]) {
|
|
62
|
+
DefaultManagement.Tokens[id] = {};
|
|
69
63
|
}
|
|
70
|
-
if (!
|
|
71
|
-
|
|
64
|
+
if (!DefaultManagement.Tokens[id].serviceOptions) {
|
|
65
|
+
DefaultManagement.Tokens[id].serviceOptions = {};
|
|
72
66
|
}
|
|
73
|
-
if (!
|
|
74
|
-
|
|
67
|
+
if (!DefaultManagement.Tokens[id].serviceOptions.get) {
|
|
68
|
+
DefaultManagement.Tokens[id].serviceOptions.get = {};
|
|
75
69
|
}
|
|
76
|
-
|
|
77
|
-
}
|
|
78
|
-
clearIdFilter
|
|
79
|
-
if (
|
|
80
|
-
delete
|
|
70
|
+
DefaultManagement.Tokens[id].serviceOptions.get.id = itemId;
|
|
71
|
+
}
|
|
72
|
+
static clearIdFilter(id) {
|
|
73
|
+
if (DefaultManagement.Tokens[id]?.serviceOptions?.get?.id) {
|
|
74
|
+
delete DefaultManagement.Tokens[id].serviceOptions.get.id;
|
|
81
75
|
}
|
|
82
|
-
}
|
|
83
|
-
getIdFilter
|
|
84
|
-
return
|
|
85
|
-
}
|
|
86
|
-
waitGridReady
|
|
76
|
+
}
|
|
77
|
+
static getIdFilter(id) {
|
|
78
|
+
return DefaultManagement.Tokens[id]?.serviceOptions?.get?.id ?? undefined;
|
|
79
|
+
}
|
|
80
|
+
static waitGridReady(id) {
|
|
87
81
|
return new Promise((resolve) => {
|
|
88
|
-
if (
|
|
89
|
-
return resolve(
|
|
82
|
+
if (DefaultManagement.Tokens[id]?.gridApi) {
|
|
83
|
+
return resolve(DefaultManagement.Tokens[id].gridApi);
|
|
90
84
|
}
|
|
91
|
-
if (!
|
|
92
|
-
|
|
93
|
-
delete
|
|
85
|
+
if (!DefaultManagement.Tokens[id].readyGridEvent) DefaultManagement.Tokens[id].readyGridEvent = {};
|
|
86
|
+
DefaultManagement.Tokens[id].readyGridEvent['waitGridReady'] = (params) => {
|
|
87
|
+
delete DefaultManagement.Tokens[id].readyGridEvent['waitGridReady'];
|
|
94
88
|
resolve(params.api);
|
|
95
89
|
};
|
|
96
90
|
});
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
if (!
|
|
100
|
-
|
|
91
|
+
}
|
|
92
|
+
static async runIsolated(id, callback) {
|
|
93
|
+
if (!DefaultManagement.Tokens[id]) return await callback();
|
|
94
|
+
DefaultManagement.Tokens[id].isProcessingQueryChange = true;
|
|
101
95
|
try {
|
|
102
96
|
return await callback();
|
|
103
97
|
} finally {
|
|
104
|
-
|
|
98
|
+
DefaultManagement.Tokens[id].isProcessingQueryChange = false;
|
|
105
99
|
}
|
|
106
|
-
}
|
|
107
|
-
|
|
100
|
+
}
|
|
101
|
+
static async loadTable(id, options = {}) {
|
|
108
102
|
options = { reload: true, force: true, createHistory: false, skipUrlUpdate: false, ...options };
|
|
109
103
|
try {
|
|
110
|
-
if (!
|
|
104
|
+
if (!DefaultManagement.Tokens[id]) {
|
|
111
105
|
logger.warn(`DefaultManagement loadTable - Token not found for id: ${id}`);
|
|
112
106
|
return;
|
|
113
107
|
}
|
|
114
|
-
const { serviceId, columnDefs, customFormat, gridId } =
|
|
115
|
-
|
|
116
|
-
let
|
|
117
|
-
let
|
|
118
|
-
let
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
let sortModel = this.Tokens[id].sortModel || [];
|
|
122
|
-
|
|
123
|
-
const gridApi = this.Tokens[id].gridApi || AgGrid.grids[gridId];
|
|
124
|
-
|
|
108
|
+
const { serviceId, columnDefs, customFormat, gridId } = DefaultManagement.Tokens[id];
|
|
109
|
+
let _page = DefaultManagement.Tokens[id].page;
|
|
110
|
+
let _limit = DefaultManagement.Tokens[id].limit;
|
|
111
|
+
let _id = DefaultManagement.getIdFilter(id);
|
|
112
|
+
let filterModel = DefaultManagement.Tokens[id].filterModel || {};
|
|
113
|
+
let sortModel = DefaultManagement.Tokens[id].sortModel || [];
|
|
114
|
+
const gridApi = DefaultManagement.Tokens[id].gridApi || AgGrid.grids[gridId];
|
|
125
115
|
if (gridApi) {
|
|
126
116
|
filterModel = gridApi.getFilterModel() || {};
|
|
127
117
|
const columnState = gridApi.getColumnState();
|
|
@@ -132,11 +122,9 @@ const DefaultManagement = {
|
|
|
132
122
|
.sort((a, b) => (a.sortIndex || 0) - (b.sortIndex || 0));
|
|
133
123
|
}
|
|
134
124
|
}
|
|
135
|
-
|
|
136
125
|
// Clean up filterModel and sortModel for URL params
|
|
137
126
|
const filterModelStr = Object.keys(filterModel).length > 0 ? JSON.stringify(filterModel) : null;
|
|
138
127
|
const sortModelStr = sortModel.length > 0 ? JSON.stringify(sortModel) : null;
|
|
139
|
-
|
|
140
128
|
// Update URL parameters to reflect current grid state
|
|
141
129
|
// Use pushState (createHistory) for filter/sort changes to enable browser back/forward
|
|
142
130
|
// Skip URL update when handling browser navigation to avoid interfering with history
|
|
@@ -150,9 +138,8 @@ const DefaultManagement = {
|
|
|
150
138
|
};
|
|
151
139
|
setQueryParams(urlParams, { replace: !options.createHistory });
|
|
152
140
|
}
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
const last = this.Tokens[id].lastOptions;
|
|
141
|
+
if (!options.force && DefaultManagement.Tokens[id].lastOptions) {
|
|
142
|
+
const last = DefaultManagement.Tokens[id].lastOptions;
|
|
156
143
|
if (
|
|
157
144
|
_page === last.page &&
|
|
158
145
|
_limit === last.limit &&
|
|
@@ -164,31 +151,26 @@ const DefaultManagement = {
|
|
|
164
151
|
return;
|
|
165
152
|
}
|
|
166
153
|
}
|
|
167
|
-
|
|
154
|
+
DefaultManagement.Tokens[id].lastOptions = {
|
|
168
155
|
page: _page,
|
|
169
156
|
limit: _limit,
|
|
170
157
|
id: _id,
|
|
171
158
|
filterModel,
|
|
172
159
|
sortModel,
|
|
173
160
|
};
|
|
174
|
-
|
|
175
161
|
// Update tokens with current state
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
162
|
+
DefaultManagement.Tokens[id].filterModel = filterModel;
|
|
163
|
+
DefaultManagement.Tokens[id].sortModel = sortModel;
|
|
179
164
|
const queryOptions = {
|
|
180
165
|
page: _page,
|
|
181
166
|
limit: _limit,
|
|
182
167
|
};
|
|
183
|
-
|
|
184
168
|
if (_id) {
|
|
185
169
|
queryOptions.id = _id;
|
|
186
170
|
}
|
|
187
|
-
|
|
188
171
|
if (filterModel && Object.keys(filterModel).length > 0) {
|
|
189
172
|
queryOptions.filterModel = filterModel;
|
|
190
173
|
}
|
|
191
|
-
|
|
192
174
|
if (sortModel && sortModel.length > 0) {
|
|
193
175
|
queryOptions.sortModel = sortModel;
|
|
194
176
|
// Legacy simple sort support
|
|
@@ -197,7 +179,6 @@ const DefaultManagement = {
|
|
|
197
179
|
queryOptions.asc = sortModel[0].sort === 'asc' ? '1' : '0';
|
|
198
180
|
}
|
|
199
181
|
}
|
|
200
|
-
|
|
201
182
|
logger.info(`Loading table ${serviceId}`, {
|
|
202
183
|
id,
|
|
203
184
|
idFilter: _id,
|
|
@@ -205,16 +186,13 @@ const DefaultManagement = {
|
|
|
205
186
|
limit: _limit,
|
|
206
187
|
hasFilters: Object.keys(filterModel).length > 0,
|
|
207
188
|
});
|
|
208
|
-
|
|
209
|
-
if (!this.Tokens[id] || !this.Tokens[id].ServiceProvider) {
|
|
189
|
+
if (!DefaultManagement.Tokens[id] || !DefaultManagement.Tokens[id].ServiceProvider) {
|
|
210
190
|
logger.warn(`DefaultManagement loadTable ${serviceId} - ServiceProvider not found for token ${id}`);
|
|
211
191
|
return;
|
|
212
192
|
}
|
|
213
|
-
|
|
214
|
-
const result = await this.Tokens[id].ServiceProvider.get(queryOptions);
|
|
193
|
+
const result = await DefaultManagement.Tokens[id].ServiceProvider.get(queryOptions);
|
|
215
194
|
if (result.status === 'success') {
|
|
216
195
|
let data, total, page, totalPages;
|
|
217
|
-
|
|
218
196
|
// Handle both single object (when querying by ID) and paginated array responses
|
|
219
197
|
if (queryOptions.id && result.data && !Array.isArray(result.data.data)) {
|
|
220
198
|
// Single object response when filtering by ID
|
|
@@ -226,24 +204,23 @@ const DefaultManagement = {
|
|
|
226
204
|
// Paginated array response
|
|
227
205
|
({ data = [], total = 0, page = 1, totalPages = 1 } = result.data || {});
|
|
228
206
|
}
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
this.Tokens[id].totalPages = totalPages;
|
|
207
|
+
DefaultManagement.Tokens[id].total = total;
|
|
208
|
+
DefaultManagement.Tokens[id].page = page;
|
|
209
|
+
DefaultManagement.Tokens[id].totalPages = totalPages;
|
|
233
210
|
const rowDataScope = data.map((row) => columnDefFormatter(row, columnDefs, customFormat));
|
|
234
211
|
if (options.reload) {
|
|
235
|
-
const grid = AgGrid.grids[
|
|
212
|
+
const grid = AgGrid.grids[DefaultManagement.Tokens[id].gridId];
|
|
236
213
|
if (grid && grid.setGridOption) {
|
|
237
214
|
grid.setGridOption('rowData', rowDataScope);
|
|
238
215
|
} else {
|
|
239
216
|
logger.warn(`Grid ${gridId} not found or not ready for setGridOption`);
|
|
240
217
|
}
|
|
241
218
|
}
|
|
242
|
-
const paginationComp = s(`#ag-pagination-${
|
|
219
|
+
const paginationComp = s(`#ag-pagination-${DefaultManagement.Tokens[id].gridId}`);
|
|
243
220
|
if (paginationComp) {
|
|
244
|
-
paginationComp.setAttribute('current-page',
|
|
245
|
-
paginationComp.setAttribute('total-pages',
|
|
246
|
-
paginationComp.setAttribute('total-items',
|
|
221
|
+
paginationComp.setAttribute('current-page', DefaultManagement.Tokens[id].page);
|
|
222
|
+
paginationComp.setAttribute('total-pages', DefaultManagement.Tokens[id].totalPages);
|
|
223
|
+
paginationComp.setAttribute('total-items', DefaultManagement.Tokens[id].total);
|
|
247
224
|
} else {
|
|
248
225
|
logger.warn(`Pagination component not found for grid ${gridId}`);
|
|
249
226
|
}
|
|
@@ -253,7 +230,7 @@ const DefaultManagement = {
|
|
|
253
230
|
await DefaultManagement.Tokens[id].readyRowDataEvent[event](rowDataScope);
|
|
254
231
|
}, 1);
|
|
255
232
|
// Update clear filter button visibility
|
|
256
|
-
|
|
233
|
+
DefaultManagement.updateClearFilterButtonVisibility(id);
|
|
257
234
|
} else {
|
|
258
235
|
logger.error(`Failed to load table ${serviceId}:`, result);
|
|
259
236
|
}
|
|
@@ -261,30 +238,27 @@ const DefaultManagement = {
|
|
|
261
238
|
logger.error(`Error in loadTable for ${id}:`, error);
|
|
262
239
|
throw error;
|
|
263
240
|
}
|
|
264
|
-
}
|
|
265
|
-
hasActiveFilters
|
|
266
|
-
const gridId =
|
|
241
|
+
}
|
|
242
|
+
static hasActiveFilters(id) {
|
|
243
|
+
const gridId = DefaultManagement.Tokens[id]?.gridId;
|
|
267
244
|
if (!gridId) return false;
|
|
268
|
-
|
|
269
245
|
const gridApi = AgGrid.grids[gridId];
|
|
270
246
|
const filterModel = gridApi ? gridApi.getFilterModel() : {};
|
|
271
|
-
const idFilter =
|
|
272
|
-
const sortModel =
|
|
273
|
-
|
|
247
|
+
const idFilter = DefaultManagement.getIdFilter(id);
|
|
248
|
+
const sortModel = DefaultManagement.Tokens[id]?.sortModel || [];
|
|
274
249
|
return Object.keys(filterModel).length > 0 || !!idFilter || sortModel.length > 0;
|
|
275
|
-
}
|
|
276
|
-
updateClearFilterButtonVisibility
|
|
250
|
+
}
|
|
251
|
+
static updateClearFilterButtonVisibility(id) {
|
|
277
252
|
const clearFilterBtn = s(`.management-table-btn-clear-filter-${id}`);
|
|
278
253
|
if (!clearFilterBtn) return;
|
|
279
|
-
|
|
280
|
-
if (this.hasActiveFilters(id)) {
|
|
254
|
+
if (DefaultManagement.hasActiveFilters(id)) {
|
|
281
255
|
clearFilterBtn.classList.remove('hide');
|
|
282
256
|
} else {
|
|
283
257
|
clearFilterBtn.classList.add('hide');
|
|
284
258
|
}
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
const gridApi = AgGrid.grids[
|
|
259
|
+
}
|
|
260
|
+
static async refreshTable(id) {
|
|
261
|
+
const gridApi = AgGrid.grids[DefaultManagement.Tokens[id].gridId];
|
|
288
262
|
if (gridApi) {
|
|
289
263
|
// Use refreshCells with change detection for optimal performance
|
|
290
264
|
// This is preferred over redrawRows() as it only updates changed cells
|
|
@@ -293,13 +267,13 @@ const DefaultManagement = {
|
|
|
293
267
|
suppressFlash: false, // Show flash animation for changed cells (requires enableCellChangeFlash)
|
|
294
268
|
});
|
|
295
269
|
}
|
|
296
|
-
}
|
|
297
|
-
|
|
270
|
+
}
|
|
271
|
+
static async instance(options = DefaultOptions) {
|
|
298
272
|
if (!options) options = DefaultOptions;
|
|
299
273
|
const { serviceId, columnDefs, entity, defaultColKeyFocus, ServiceProvider, permissions, paginationOptions } =
|
|
300
274
|
options;
|
|
301
|
-
logger.info('DefaultManagement
|
|
302
|
-
const id = options?.idModal ? options.idModal : getId(
|
|
275
|
+
logger.info('DefaultManagement instance', options);
|
|
276
|
+
const id = options?.idModal ? options.idModal : getId(DefaultManagement.Tokens, `${serviceId}-`);
|
|
303
277
|
const gridId = `${serviceId}-grid-${id}`;
|
|
304
278
|
const queryParamsListenerId = `default-management-${id}`;
|
|
305
279
|
const queryParams = getQueryParams();
|
|
@@ -307,7 +281,6 @@ const DefaultManagement = {
|
|
|
307
281
|
const defaultLimit = paginationOptions?.limitOptions?.[0] || 10;
|
|
308
282
|
const limit = parseInt(queryParams.limit) || defaultLimit;
|
|
309
283
|
const urlId = queryParams.id || undefined;
|
|
310
|
-
|
|
311
284
|
let filterModel = {};
|
|
312
285
|
let sortModel = [];
|
|
313
286
|
try {
|
|
@@ -316,17 +289,14 @@ const DefaultManagement = {
|
|
|
316
289
|
} catch (e) {
|
|
317
290
|
logger.warn('Error parsing filter/sort model from URL', e);
|
|
318
291
|
}
|
|
319
|
-
|
|
320
292
|
// Enhance column definitions for Date filtering and ensure colId
|
|
321
293
|
const enhancedColumnDefs = columnDefs.map((col) => {
|
|
322
294
|
const enhancedCol = {
|
|
323
295
|
...col,
|
|
324
296
|
colId: col.field, // Ensure colId matches field
|
|
325
297
|
};
|
|
326
|
-
|
|
327
298
|
if (enhancedCol.cellDataType === 'date' || enhancedCol.filter === 'agDateColumnFilter') {
|
|
328
299
|
enhancedCol.filter = 'agDateColumnFilter';
|
|
329
|
-
|
|
330
300
|
// Value getter to ensure date is properly parsed
|
|
331
301
|
if (!enhancedCol.valueGetter) {
|
|
332
302
|
enhancedCol.valueGetter = (params) => {
|
|
@@ -336,7 +306,6 @@ const DefaultManagement = {
|
|
|
336
306
|
return isNaN(date.getTime()) ? null : date;
|
|
337
307
|
};
|
|
338
308
|
}
|
|
339
|
-
|
|
340
309
|
// Value formatter for display
|
|
341
310
|
if (!enhancedCol.valueFormatter) {
|
|
342
311
|
enhancedCol.valueFormatter = (params) => {
|
|
@@ -350,7 +319,6 @@ const DefaultManagement = {
|
|
|
350
319
|
});
|
|
351
320
|
};
|
|
352
321
|
}
|
|
353
|
-
|
|
354
322
|
enhancedCol.filterParams = {
|
|
355
323
|
comparator: (filterLocalDateAtMidnight, cellValue) => {
|
|
356
324
|
if (cellValue == null) return -1;
|
|
@@ -374,27 +342,21 @@ const DefaultManagement = {
|
|
|
374
342
|
}
|
|
375
343
|
return enhancedCol;
|
|
376
344
|
});
|
|
377
|
-
|
|
378
345
|
class RemoveActionGridRenderer {
|
|
379
346
|
eGui;
|
|
380
347
|
tokens;
|
|
381
|
-
|
|
382
348
|
async init(params) {
|
|
383
349
|
this.eGui = document.createElement('div');
|
|
384
350
|
this.tokens = {};
|
|
385
351
|
const { rowIndex } = params;
|
|
386
352
|
const { createdAt, updatedAt } = params.data;
|
|
387
|
-
|
|
388
353
|
const cellRenderId = getId(this.tokens, `${serviceId}-`);
|
|
389
354
|
this.tokens[cellRenderId] = {};
|
|
390
|
-
|
|
391
|
-
this.eGui.innerHTML = html` ${await BtnIcon.Render({
|
|
355
|
+
this.eGui.innerHTML = html` ${await BtnIcon.instance({
|
|
392
356
|
label: html`<div class="abs center">
|
|
393
357
|
<i class="fas fa-times"></i>
|
|
394
358
|
</div> `,
|
|
395
|
-
class: `in fll section-mp management-table-btn-mini management-table-btn-remove-${id}-${cellRenderId} ${
|
|
396
|
-
!params.data._id ? 'hide' : ''
|
|
397
|
-
}`,
|
|
359
|
+
class: `in fll section-mp management-table-btn-mini management-table-btn-remove-${id}-${cellRenderId} ${!params.data._id ? 'hide' : ''}`,
|
|
398
360
|
})}`;
|
|
399
361
|
setTimeout(() => {
|
|
400
362
|
EventsUI.onClick(
|
|
@@ -404,7 +366,7 @@ const DefaultManagement = {
|
|
|
404
366
|
html: async () => {
|
|
405
367
|
return html`
|
|
406
368
|
<div class="in section-mp" style="text-align: center">
|
|
407
|
-
${Translate.
|
|
369
|
+
${Translate.instance('confirm-delete-item')}
|
|
408
370
|
${Object.keys(params.data).length > 0
|
|
409
371
|
? html`<br />
|
|
410
372
|
"${options.defaultColKeyFocus
|
|
@@ -420,9 +382,8 @@ const DefaultManagement = {
|
|
|
420
382
|
let result;
|
|
421
383
|
if (params.data._id) result = await ServiceProvider.delete({ id: params.data._id });
|
|
422
384
|
else result = { status: 'success' };
|
|
423
|
-
|
|
424
385
|
NotificationManager.Push({
|
|
425
|
-
html: result.status === 'error' ? result.message : Translate.
|
|
386
|
+
html: result.status === 'error' ? result.message : Translate.instance('item-success-delete'),
|
|
426
387
|
status: result.status,
|
|
427
388
|
});
|
|
428
389
|
if (result.status === 'success') {
|
|
@@ -434,7 +395,6 @@ const DefaultManagement = {
|
|
|
434
395
|
if (token.page > newTotalPages && newTotalPages > 0) {
|
|
435
396
|
token.page = newTotalPages;
|
|
436
397
|
}
|
|
437
|
-
|
|
438
398
|
// reload the current page
|
|
439
399
|
await DefaultManagement.loadTable(id, { reload: false });
|
|
440
400
|
}
|
|
@@ -443,16 +403,13 @@ const DefaultManagement = {
|
|
|
443
403
|
);
|
|
444
404
|
});
|
|
445
405
|
}
|
|
446
|
-
|
|
447
406
|
getGui() {
|
|
448
407
|
return this.eGui;
|
|
449
408
|
}
|
|
450
|
-
|
|
451
409
|
refresh(params) {
|
|
452
410
|
return true;
|
|
453
411
|
}
|
|
454
412
|
}
|
|
455
|
-
|
|
456
413
|
const finalColumnDefs = (enhancedColumnDefs || []).concat(
|
|
457
414
|
permissions.remove
|
|
458
415
|
? [
|
|
@@ -466,9 +423,8 @@ const DefaultManagement = {
|
|
|
466
423
|
]
|
|
467
424
|
: [],
|
|
468
425
|
);
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
...this.Tokens[id],
|
|
426
|
+
DefaultManagement.Tokens[id] = {
|
|
427
|
+
...DefaultManagement.Tokens[id],
|
|
472
428
|
...options,
|
|
473
429
|
columnDefs: finalColumnDefs, // Use enhanced definitions including actions
|
|
474
430
|
gridId,
|
|
@@ -481,12 +437,10 @@ const DefaultManagement = {
|
|
|
481
437
|
isInitializing: true, // Flag to prevent double loading during grid ready
|
|
482
438
|
isProcessingQueryChange: false, // Flag to prevent listener recursion
|
|
483
439
|
};
|
|
484
|
-
|
|
485
440
|
// Initialize ID filter from query params if present
|
|
486
441
|
if (urlId) {
|
|
487
|
-
|
|
442
|
+
DefaultManagement.setIdFilter(id, urlId);
|
|
488
443
|
}
|
|
489
|
-
|
|
490
444
|
setQueryParams({
|
|
491
445
|
page,
|
|
492
446
|
limit,
|
|
@@ -494,10 +448,8 @@ const DefaultManagement = {
|
|
|
494
448
|
filterModel: Object.keys(filterModel).length > 0 ? JSON.stringify(filterModel) : null,
|
|
495
449
|
sortModel: sortModel.length > 0 ? JSON.stringify(sortModel) : null,
|
|
496
450
|
});
|
|
497
|
-
|
|
498
451
|
setTimeout(async () => {
|
|
499
452
|
// https://www.ag-grid.com/javascript-data-grid/data-update-transactions/
|
|
500
|
-
|
|
501
453
|
// Initial loadTable is now called in onGridReady after grid is fully initialized
|
|
502
454
|
// {
|
|
503
455
|
// const result = await ServiceProvider.get();
|
|
@@ -516,7 +468,6 @@ const DefaultManagement = {
|
|
|
516
468
|
};
|
|
517
469
|
EventsUI.onClick(`.management-table-btn-add-${id}`, async () => {
|
|
518
470
|
if (options.customEvent && options.customEvent.add) return await options.customEvent.add();
|
|
519
|
-
|
|
520
471
|
const rowObj = {};
|
|
521
472
|
for (const def of columnDefs) {
|
|
522
473
|
rowObj[def.field] = '';
|
|
@@ -527,7 +478,7 @@ const DefaultManagement = {
|
|
|
527
478
|
data: rowObj,
|
|
528
479
|
};
|
|
529
480
|
// NotificationManager.Push({
|
|
530
|
-
// html: result.status === 'error' ? result.message : `${Translate.
|
|
481
|
+
// html: result.status === 'error' ? result.message : `${Translate.instance('success-create-item')}`,
|
|
531
482
|
// status: result.status,
|
|
532
483
|
// });
|
|
533
484
|
if (result.status === 'success') {
|
|
@@ -551,26 +502,20 @@ const DefaultManagement = {
|
|
|
551
502
|
// defaultState: { sort: null },
|
|
552
503
|
// });
|
|
553
504
|
}
|
|
554
|
-
|
|
555
505
|
// https://www.ag-grid.com/javascript-data-grid/cell-editing-start-stop/
|
|
556
|
-
|
|
557
506
|
const pinned = undefined;
|
|
558
507
|
const key = undefined;
|
|
559
|
-
|
|
560
508
|
// setFocusedCell = (
|
|
561
509
|
// rowIndex: number,
|
|
562
510
|
// colKey: string | Column,
|
|
563
511
|
// rowPinned?: RowPinnedType
|
|
564
512
|
// ) => void;
|
|
565
|
-
|
|
566
513
|
// type RowPinnedType =
|
|
567
514
|
// 'top'
|
|
568
515
|
// | 'bottom'
|
|
569
516
|
// | null
|
|
570
517
|
// | undefined
|
|
571
|
-
|
|
572
518
|
AgGrid.grids[gridId].setFocusedCell(0, '0', pinned);
|
|
573
|
-
|
|
574
519
|
// interface StartEditingCellParams {
|
|
575
520
|
// // The row index of the row to start editing
|
|
576
521
|
// rowIndex: number;
|
|
@@ -581,7 +526,6 @@ const DefaultManagement = {
|
|
|
581
526
|
// // The key to pass to the cell editor
|
|
582
527
|
// key?: string;
|
|
583
528
|
// }
|
|
584
|
-
|
|
585
529
|
setTimeout(() => {
|
|
586
530
|
s(`.management-table-btn-save-${id}`).classList.remove('hide');
|
|
587
531
|
// s(`.management-table-btn-stop-${id}`).classList.remove('hide');
|
|
@@ -596,7 +540,6 @@ const DefaultManagement = {
|
|
|
596
540
|
});
|
|
597
541
|
});
|
|
598
542
|
});
|
|
599
|
-
|
|
600
543
|
EventsUI.onClick(`.management-table-btn-stop-${id}`, async () => {
|
|
601
544
|
s(`.management-table-btn-save-${id}`).classList.add('hide');
|
|
602
545
|
// s(`.management-table-btn-stop-${id}`).classList.add('hide');
|
|
@@ -611,7 +554,7 @@ const DefaultManagement = {
|
|
|
611
554
|
html: async () => {
|
|
612
555
|
return html`
|
|
613
556
|
<div class="in section-mp" style="text-align: center;">
|
|
614
|
-
<strong>${Translate.
|
|
557
|
+
<strong>${Translate.instance('confirm-delete-all-data')}</strong>
|
|
615
558
|
</div>
|
|
616
559
|
`;
|
|
617
560
|
},
|
|
@@ -622,60 +565,52 @@ const DefaultManagement = {
|
|
|
622
565
|
if (confirmResult.status === 'cancelled') return;
|
|
623
566
|
const result = await ServiceProvider.delete();
|
|
624
567
|
NotificationManager.Push({
|
|
625
|
-
html: result.status === 'error' ? result.message : Translate.
|
|
568
|
+
html: result.status === 'error' ? result.message : Translate.instance('success-delete-all-items'),
|
|
626
569
|
status: result.status,
|
|
627
570
|
});
|
|
628
571
|
if (result.status === 'success') {
|
|
629
572
|
DefaultManagement.loadTable(id);
|
|
630
573
|
}
|
|
631
574
|
});
|
|
632
|
-
|
|
633
575
|
// Listen to query parameter changes for browser back/forward navigation
|
|
634
576
|
listenQueryParamsChange({
|
|
635
577
|
id: queryParamsListenerId,
|
|
636
578
|
event: (queryParams) => {
|
|
637
579
|
// Prevent recursion - if we're already processing a query change, skip
|
|
638
|
-
if (
|
|
580
|
+
if (DefaultManagement.Tokens[id].isProcessingQueryChange) {
|
|
639
581
|
return;
|
|
640
582
|
}
|
|
641
|
-
|
|
642
583
|
const newPage = parseInt(queryParams.page, 10) || 1;
|
|
643
|
-
const newLimit = parseInt(queryParams.limit, 10) ||
|
|
584
|
+
const newLimit = parseInt(queryParams.limit, 10) || DefaultManagement.Tokens[id].limit || 10;
|
|
644
585
|
const newFilterModel = queryParams.filterModel;
|
|
645
586
|
const newSortModel = queryParams.sortModel;
|
|
646
587
|
const newId = queryParams.id || undefined;
|
|
647
|
-
|
|
648
588
|
let shouldReload = false;
|
|
649
|
-
|
|
650
589
|
// Check if id parameter changed
|
|
651
|
-
const currentId =
|
|
590
|
+
const currentId = DefaultManagement.getIdFilter(id);
|
|
652
591
|
if (newId !== currentId) {
|
|
653
592
|
if (newId) {
|
|
654
|
-
|
|
593
|
+
DefaultManagement.setIdFilter(id, newId);
|
|
655
594
|
} else {
|
|
656
|
-
|
|
595
|
+
DefaultManagement.clearIdFilter(id);
|
|
657
596
|
}
|
|
658
597
|
shouldReload = true;
|
|
659
598
|
}
|
|
660
|
-
|
|
661
599
|
// Check if page or limit changed
|
|
662
|
-
if (newPage !==
|
|
663
|
-
|
|
664
|
-
|
|
600
|
+
if (newPage !== DefaultManagement.Tokens[id].page || newLimit !== DefaultManagement.Tokens[id].limit) {
|
|
601
|
+
DefaultManagement.Tokens[id].page = newPage;
|
|
602
|
+
DefaultManagement.Tokens[id].limit = newLimit;
|
|
665
603
|
shouldReload = true;
|
|
666
604
|
}
|
|
667
|
-
|
|
668
605
|
// Check if filter or sort changed by comparing with actual grid state
|
|
669
606
|
const gridApi = AgGrid.grids[gridId];
|
|
670
607
|
let filterChanged = false;
|
|
671
608
|
let sortChanged = false;
|
|
672
|
-
|
|
673
609
|
if (gridApi) {
|
|
674
610
|
// Get current grid filter state
|
|
675
611
|
const currentGridFilterModel = gridApi.getFilterModel() || {};
|
|
676
612
|
const currentGridFilterStr = JSON.stringify(currentGridFilterModel);
|
|
677
613
|
const newFilterStr = newFilterModel || '{}';
|
|
678
|
-
|
|
679
614
|
// Get current grid sort state
|
|
680
615
|
const currentColumnState = gridApi.getColumnState() || [];
|
|
681
616
|
const currentGridSortModel = currentColumnState
|
|
@@ -684,36 +619,31 @@ const DefaultManagement = {
|
|
|
684
619
|
.sort((a, b) => (a.sortIndex || 0) - (b.sortIndex || 0));
|
|
685
620
|
const currentGridSortStr = JSON.stringify(currentGridSortModel);
|
|
686
621
|
const newSortStr = newSortModel || '[]';
|
|
687
|
-
|
|
688
622
|
filterChanged = currentGridFilterStr !== newFilterStr;
|
|
689
623
|
sortChanged = currentGridSortStr !== newSortStr;
|
|
690
624
|
}
|
|
691
|
-
|
|
692
625
|
if (filterChanged || sortChanged) {
|
|
693
626
|
// Parse and apply the new filter/sort models
|
|
694
627
|
try {
|
|
695
|
-
|
|
628
|
+
DefaultManagement.Tokens[id].filterModel = newFilterModel ? JSON.parse(newFilterModel) : {};
|
|
696
629
|
} catch (e) {
|
|
697
|
-
|
|
630
|
+
DefaultManagement.Tokens[id].filterModel = {};
|
|
698
631
|
}
|
|
699
632
|
try {
|
|
700
|
-
|
|
633
|
+
DefaultManagement.Tokens[id].sortModel = newSortModel ? JSON.parse(newSortModel) : [];
|
|
701
634
|
} catch (e) {
|
|
702
|
-
|
|
635
|
+
DefaultManagement.Tokens[id].sortModel = [];
|
|
703
636
|
}
|
|
704
|
-
|
|
705
637
|
// Apply filters and sorts to the grid
|
|
706
638
|
if (gridApi) {
|
|
707
639
|
// Temporarily disable filter/sort change handlers to prevent recursion
|
|
708
|
-
|
|
709
|
-
|
|
640
|
+
DefaultManagement.Tokens[id].isProcessingQueryChange = true;
|
|
710
641
|
if (filterChanged) {
|
|
711
|
-
gridApi.setFilterModel(
|
|
642
|
+
gridApi.setFilterModel(DefaultManagement.Tokens[id].filterModel);
|
|
712
643
|
}
|
|
713
|
-
|
|
714
644
|
if (sortChanged) {
|
|
715
645
|
// Apply sort model
|
|
716
|
-
const columnState =
|
|
646
|
+
const columnState = DefaultManagement.Tokens[id].sortModel.map((sortItem) => ({
|
|
717
647
|
colId: sortItem.colId,
|
|
718
648
|
sort: sortItem.sort,
|
|
719
649
|
sortIndex: sortItem.sortIndex,
|
|
@@ -729,39 +659,33 @@ const DefaultManagement = {
|
|
|
729
659
|
});
|
|
730
660
|
}
|
|
731
661
|
}
|
|
732
|
-
|
|
733
662
|
// Re-enable handlers after a short delay
|
|
734
663
|
setTimeout(() => {
|
|
735
|
-
|
|
664
|
+
DefaultManagement.Tokens[id].isProcessingQueryChange = false;
|
|
736
665
|
}, 100);
|
|
737
666
|
}
|
|
738
667
|
shouldReload = true;
|
|
739
668
|
}
|
|
740
|
-
|
|
741
669
|
if (shouldReload) {
|
|
742
670
|
// Skip URL update since browser already changed it (back/forward navigation)
|
|
743
671
|
DefaultManagement.loadTable(id, { reload: true, force: true, createHistory: false, skipUrlUpdate: true });
|
|
744
672
|
}
|
|
745
673
|
},
|
|
746
674
|
});
|
|
747
|
-
|
|
748
675
|
EventsUI.onClick(`.management-table-btn-clear-filter-${id}`, async () => {
|
|
749
676
|
try {
|
|
750
677
|
const gridApi = AgGrid.grids[gridId];
|
|
751
|
-
|
|
752
678
|
// Clear all filters
|
|
753
679
|
DefaultManagement.clearIdFilter(id);
|
|
754
680
|
if (gridApi) {
|
|
755
681
|
gridApi.setFilterModel({});
|
|
756
682
|
gridApi.applyColumnState({ defaultState: { sort: null } });
|
|
757
683
|
}
|
|
758
|
-
|
|
759
684
|
// Clear token state
|
|
760
685
|
if (DefaultManagement.Tokens[id]) {
|
|
761
686
|
DefaultManagement.Tokens[id].filterModel = {};
|
|
762
687
|
DefaultManagement.Tokens[id].sortModel = [];
|
|
763
688
|
}
|
|
764
|
-
|
|
765
689
|
// Update URL - keep only page and limit
|
|
766
690
|
const queryParams = getQueryParams();
|
|
767
691
|
setQueryParams({
|
|
@@ -771,12 +695,10 @@ const DefaultManagement = {
|
|
|
771
695
|
sortModel: null,
|
|
772
696
|
id: null,
|
|
773
697
|
});
|
|
774
|
-
|
|
775
698
|
// Reload table
|
|
776
699
|
await DefaultManagement.loadTable(id, { force: true, reload: true });
|
|
777
|
-
|
|
778
700
|
NotificationManager.Push({
|
|
779
|
-
html: Translate.
|
|
701
|
+
html: Translate.instance('success-clear-filter') || 'Filters cleared',
|
|
780
702
|
status: 'success',
|
|
781
703
|
});
|
|
782
704
|
} catch (error) {
|
|
@@ -790,12 +712,10 @@ const DefaultManagement = {
|
|
|
790
712
|
try {
|
|
791
713
|
// Reload data from server
|
|
792
714
|
await DefaultManagement.loadTable(id, { force: true, reload: true });
|
|
793
|
-
|
|
794
715
|
// Other option: Refresh cells to update UI
|
|
795
716
|
// DefaultManagement.refreshTable(id);
|
|
796
|
-
|
|
797
717
|
NotificationManager.Push({
|
|
798
|
-
html: Translate.
|
|
718
|
+
html: Translate.instance('success-reload-data') || 'Data reloaded successfully',
|
|
799
719
|
status: 'success',
|
|
800
720
|
});
|
|
801
721
|
} catch (error) {
|
|
@@ -830,21 +750,17 @@ const DefaultManagement = {
|
|
|
830
750
|
if (queryParams.filterModel) filterModel = JSON.parse(queryParams.filterModel);
|
|
831
751
|
if (queryParams.sortModel) sortModel = JSON.parse(queryParams.sortModel);
|
|
832
752
|
} catch (e) {}
|
|
833
|
-
|
|
834
753
|
const token = DefaultManagement.Tokens[id];
|
|
835
|
-
|
|
836
754
|
if (!token) {
|
|
837
755
|
// Token doesn't exist yet, table hasn't been initialized
|
|
838
756
|
return;
|
|
839
757
|
}
|
|
840
|
-
|
|
841
758
|
// Check if state in URL is different from current state
|
|
842
759
|
const currentId = DefaultManagement.getIdFilter(id);
|
|
843
760
|
const isIdChanged = currentId !== urlId;
|
|
844
761
|
const isPaginationChanged = token.page !== page || token.limit !== limit;
|
|
845
762
|
const isFilterChanged = JSON.stringify(token.filterModel || {}) !== JSON.stringify(filterModel);
|
|
846
763
|
const isSortChanged = JSON.stringify(token.sortModel || []) !== JSON.stringify(sortModel);
|
|
847
|
-
|
|
848
764
|
if (isPaginationChanged || isFilterChanged || isSortChanged || isIdChanged) {
|
|
849
765
|
// Update ID filter from query params
|
|
850
766
|
if (urlId) {
|
|
@@ -852,12 +768,10 @@ const DefaultManagement = {
|
|
|
852
768
|
} else {
|
|
853
769
|
DefaultManagement.clearIdFilter(id);
|
|
854
770
|
}
|
|
855
|
-
|
|
856
771
|
token.page = page;
|
|
857
772
|
token.limit = limit;
|
|
858
773
|
token.filterModel = filterModel;
|
|
859
774
|
token.sortModel = sortModel;
|
|
860
|
-
|
|
861
775
|
// If grid is active, we should update its state to match URL
|
|
862
776
|
const gridApi = AgGrid.grids[gridId];
|
|
863
777
|
if (gridApi && gridApi.setFilterModel && gridApi.applyColumnState) {
|
|
@@ -893,49 +807,41 @@ const DefaultManagement = {
|
|
|
893
807
|
};
|
|
894
808
|
}, 1);
|
|
895
809
|
return html`<div class="fl management-table-toolbar">
|
|
896
|
-
${await BtnIcon.
|
|
897
|
-
class: `in fll section-mp management-table-btn-mini management-table-btn-add-${id} ${
|
|
898
|
-
permissions.add ? '' : 'hide'
|
|
899
|
-
}`,
|
|
810
|
+
${await BtnIcon.instance({
|
|
811
|
+
class: `in fll section-mp management-table-btn-mini management-table-btn-add-${id} ${permissions.add ? '' : 'hide'}`,
|
|
900
812
|
label: html`<div class="abs center btn-add-${id}-label"><i class="fa-solid fa-circle-plus"></i></div> `,
|
|
901
813
|
type: 'button',
|
|
902
814
|
})}
|
|
903
|
-
${await BtnIcon.
|
|
815
|
+
${await BtnIcon.instance({
|
|
904
816
|
class: `in fll section-mp management-table-btn-mini management-table-btn-save-${id} hide`,
|
|
905
817
|
label: html`<div class="abs center btn-save-${id}-label"><i class="fas fa-save"></i></div> `,
|
|
906
818
|
type: 'button',
|
|
907
819
|
})}
|
|
908
|
-
${await BtnIcon.
|
|
820
|
+
${await BtnIcon.instance({
|
|
909
821
|
class: `in fll section-mp management-table-btn-mini management-table-btn-stop-${id} hide`,
|
|
910
822
|
label: html`<div class="abs center btn-save-${id}-label"><i class="fa-solid fa-rectangle-xmark"></i></div> `,
|
|
911
823
|
type: 'button',
|
|
912
824
|
})}
|
|
913
|
-
${await BtnIcon.
|
|
914
|
-
class: `in fll section-mp management-table-btn-mini management-table-btn-clean-${id} ${
|
|
915
|
-
permissions.remove ? '' : 'hide'
|
|
916
|
-
}`,
|
|
825
|
+
${await BtnIcon.instance({
|
|
826
|
+
class: `in fll section-mp management-table-btn-mini management-table-btn-clean-${id} ${permissions.remove ? '' : 'hide'}`,
|
|
917
827
|
label: html`<div class="abs center btn-clean-${id}-label"><i class="fas fa-broom"></i></div> `,
|
|
918
828
|
type: 'button',
|
|
919
829
|
})}
|
|
920
|
-
${await BtnIcon.
|
|
921
|
-
class: `in fll section-mp management-table-btn-mini management-table-btn-clear-filter-${id} ${
|
|
922
|
-
Object.keys(filterModel).length > 0 || sortModel.length > 0 || urlId ? '' : 'hide'
|
|
923
|
-
}`,
|
|
830
|
+
${await BtnIcon.instance({
|
|
831
|
+
class: `in fll section-mp management-table-btn-mini management-table-btn-clear-filter-${id} ${Object.keys(filterModel).length > 0 || sortModel.length > 0 || urlId ? '' : 'hide'}`,
|
|
924
832
|
label: html`<div class="abs center btn-clear-filter-${id}-label">
|
|
925
833
|
<i class="fa-solid fa-filter-circle-xmark"></i>
|
|
926
834
|
</div> `,
|
|
927
835
|
type: 'button',
|
|
928
836
|
})}
|
|
929
|
-
${await BtnIcon.
|
|
930
|
-
class: `in fll section-mp management-table-btn-mini management-table-btn-reload-${id} ${
|
|
931
|
-
permissions.reload ? '' : 'hide'
|
|
932
|
-
}`,
|
|
837
|
+
${await BtnIcon.instance({
|
|
838
|
+
class: `in fll section-mp management-table-btn-mini management-table-btn-reload-${id} ${permissions.reload ? '' : 'hide'}`,
|
|
933
839
|
label: html`<div class="abs center btn-reload-${id}-label"><i class="fas fa-sync-alt"></i></div> `,
|
|
934
840
|
type: 'button',
|
|
935
841
|
})}
|
|
936
842
|
</div>
|
|
937
843
|
<div class="in section-mp">
|
|
938
|
-
${await AgGrid.
|
|
844
|
+
${await AgGrid.instance({
|
|
939
845
|
id: gridId,
|
|
940
846
|
parentModal: options.idModal,
|
|
941
847
|
usePagination: true,
|
|
@@ -964,17 +870,15 @@ const DefaultManagement = {
|
|
|
964
870
|
autoHeight: true,
|
|
965
871
|
},
|
|
966
872
|
onGridReady: async (params) => {
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
await this.Tokens[id].readyGridEvent[key](params);
|
|
873
|
+
DefaultManagement.Tokens[id].gridApi = params.api;
|
|
874
|
+
if (DefaultManagement.Tokens[id].readyGridEvent) {
|
|
875
|
+
for (const key of Object.keys(DefaultManagement.Tokens[id].readyGridEvent)) {
|
|
876
|
+
await DefaultManagement.Tokens[id].readyGridEvent[key](params);
|
|
972
877
|
}
|
|
973
878
|
}
|
|
974
|
-
|
|
975
879
|
params.api.setGridOption('columnDefs', finalColumnDefs);
|
|
976
880
|
// Apply initial state from URL
|
|
977
|
-
const { filterModel, sortModel } =
|
|
881
|
+
const { filterModel, sortModel } = DefaultManagement.Tokens[id];
|
|
978
882
|
if (filterModel && Object.keys(filterModel).length > 0) {
|
|
979
883
|
params.api.setFilterModel(filterModel);
|
|
980
884
|
}
|
|
@@ -988,28 +892,26 @@ const DefaultManagement = {
|
|
|
988
892
|
// Filter/sort state has been applied, this will fetch data from server
|
|
989
893
|
DefaultManagement.loadTable(id).finally(() => {
|
|
990
894
|
// Mark initialization complete to allow future filter/sort events
|
|
991
|
-
|
|
895
|
+
DefaultManagement.Tokens[id].isInitializing = false;
|
|
992
896
|
});
|
|
993
897
|
},
|
|
994
898
|
onFilterChanged: () => {
|
|
995
899
|
// Skip if still initializing (state being applied in onGridReady)
|
|
996
|
-
if (
|
|
900
|
+
if (DefaultManagement.Tokens[id].isInitializing) return;
|
|
997
901
|
// Skip if we're processing a query change from browser navigation
|
|
998
|
-
if (
|
|
902
|
+
if (DefaultManagement.Tokens[id].isProcessingQueryChange) return;
|
|
999
903
|
// Reset to page 1 on filter change
|
|
1000
|
-
|
|
1001
|
-
|
|
904
|
+
DefaultManagement.Tokens[id].page = 1;
|
|
1002
905
|
// Update clear filter button visibility
|
|
1003
906
|
DefaultManagement.updateClearFilterButtonVisibility(id);
|
|
1004
|
-
|
|
1005
907
|
// Create history entry for filter changes
|
|
1006
908
|
DefaultManagement.loadTable(id, { reload: true, force: true, createHistory: true });
|
|
1007
909
|
},
|
|
1008
910
|
onSortChanged: () => {
|
|
1009
911
|
// Skip if still initializing (state being applied in onGridReady)
|
|
1010
|
-
if (
|
|
912
|
+
if (DefaultManagement.Tokens[id].isInitializing) return;
|
|
1011
913
|
// Skip if we're processing a query change from browser navigation
|
|
1012
|
-
if (
|
|
914
|
+
if (DefaultManagement.Tokens[id].isProcessingQueryChange) return;
|
|
1013
915
|
// Update clear filter button visibility
|
|
1014
916
|
DefaultManagement.updateClearFilterButtonVisibility(id);
|
|
1015
917
|
// Create history entry for sort changes
|
|
@@ -1025,7 +927,7 @@ const DefaultManagement = {
|
|
|
1025
927
|
const body = event.data ? event.data : {};
|
|
1026
928
|
const result = await ServiceProvider.put({ id: event.data._id, body });
|
|
1027
929
|
NotificationManager.Push({
|
|
1028
|
-
html: result.status === 'error' ? result.message : `${Translate.
|
|
930
|
+
html: result.status === 'error' ? result.message : `${Translate.instance('success-update-item')}`,
|
|
1029
931
|
status: result.status,
|
|
1030
932
|
});
|
|
1031
933
|
if (result.status === 'success') {
|
|
@@ -1083,26 +985,22 @@ const DefaultManagement = {
|
|
|
1083
985
|
if (!event.data._id) {
|
|
1084
986
|
result = await ServiceProvider.post({ body: event.data });
|
|
1085
987
|
NotificationManager.Push({
|
|
1086
|
-
html: result.status === 'error' ? result.message : `${Translate.
|
|
988
|
+
html: result.status === 'error' ? result.message : `${Translate.instance('success-create-item')}`,
|
|
1087
989
|
status: result.status,
|
|
1088
990
|
});
|
|
1089
991
|
if (result.status === 'success') {
|
|
1090
992
|
// Filter by the newly created row's ID
|
|
1091
993
|
const newItemId = result.data._id;
|
|
1092
|
-
|
|
1093
994
|
// Update UI buttons first
|
|
1094
995
|
s(`.management-table-btn-save-${id}`).classList.add('hide');
|
|
1095
996
|
if (permissions.add) s(`.management-table-btn-add-${id}`).classList.remove('hide');
|
|
1096
997
|
if (permissions.remove) s(`.management-table-btn-clean-${id}`).classList.remove('hide');
|
|
1097
998
|
if (permissions.reload) s(`.management-table-btn-reload-${id}`).classList.remove('hide');
|
|
1098
|
-
|
|
1099
999
|
// Stop editing to avoid triggering other events
|
|
1100
1000
|
AgGrid.grids[gridId].stopEditing();
|
|
1101
|
-
|
|
1102
1001
|
// Set ID filter and reload
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1002
|
+
DefaultManagement.Tokens[id].page = 1;
|
|
1003
|
+
DefaultManagement.setIdFilter(id, newItemId);
|
|
1106
1004
|
setTimeout(async () => {
|
|
1107
1005
|
await DefaultManagement.loadTable(id, { force: true, createHistory: true });
|
|
1108
1006
|
});
|
|
@@ -1117,7 +1015,6 @@ const DefaultManagement = {
|
|
|
1117
1015
|
},
|
|
1118
1016
|
})}
|
|
1119
1017
|
</div>`;
|
|
1120
|
-
}
|
|
1121
|
-
}
|
|
1122
|
-
|
|
1018
|
+
}
|
|
1019
|
+
}
|
|
1123
1020
|
export { DefaultManagement };
|