adminizer 4.1.0-build.26 → 4.1.0-build.28

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.
Files changed (155) hide show
  1. package/assets/{VanillaJSONEditor-D-Lx670g.js → VanillaJSONEditor-DKF_Ft1S.js} +96 -96
  2. package/assets/add-BA0ZgbVP.js +1 -0
  3. package/assets/add-form-D5PNdz6X.js +1 -0
  4. package/assets/add-group-BqvmQRDY.js +1 -0
  5. package/assets/{add-group-form-gNJW11-q.js → add-group-form-D1P6v9Fm.js} +1 -1
  6. package/assets/add-user-C31g3pXW.js +1 -0
  7. package/assets/{add-user-form-BJ0FsZYJ.js → add-user-form-DyczuE4l.js} +1 -1
  8. package/assets/{app-C3OdwOHy.css → app-ClS67l37.css} +1 -1
  9. package/assets/app-layout-CQTlWDgg.js +1 -0
  10. package/assets/{app-shell-Dd9Eknik.js → app-shell-B4pzTbiN.js} +1 -1
  11. package/assets/{app-sidebar-BOmu6-Sl.js → app-sidebar-DX9Shcd3.js} +1 -1
  12. package/assets/{app-sidebar-header-CoXSzWxk.js → app-sidebar-header-BcZ0JSSJ.js} +1 -1
  13. package/assets/app.js +9 -9
  14. package/assets/{breadcrumbs-BmAq4fHT.js → breadcrumbs-DIhfOCvh.js} +1 -1
  15. package/assets/{button-C9B_5Jf_.js → button-DleSKY4-.js} +1 -1
  16. package/assets/catalog-BHbLV-zr.js +12 -0
  17. package/assets/catalog-CZUI8zho.css +1 -0
  18. package/assets/{checkbox-Fg27sL_1.js → checkbox-DgmLwxEt.js} +1 -1
  19. package/assets/{compiler-runtime-hB6dAw2d.js → compiler-runtime-CMDe02AS.js} +1 -1
  20. package/assets/dashboard-BiycZ-vC.js +3 -0
  21. package/assets/{date-picker-DI1cCO7K.js → date-picker-Cb6A4Zx_.js} +1 -1
  22. package/assets/dialog-stack-DU4Ow4Oa.js +1 -0
  23. package/assets/{dropdown-menu-Bhj17ENm.js → dropdown-menu-D3vlxbLx.js} +1 -1
  24. package/assets/{field-renderer-DVHZF6HS.js → field-renderer-CW8TLtlI.js} +3 -3
  25. package/assets/form-CLP53RtV.js +1 -0
  26. package/assets/{form-DgtErfln.js → form-CwSId-Cu.js} +1 -1
  27. package/assets/{geo-json-BjiyTtMu.js → geo-json-BNgLxoVs.js} +1 -1
  28. package/assets/group-add-Brshb-tH.js +1 -0
  29. package/assets/{handsontable-4mjU_b0n.js → handsontable-BI4C0OBe.js} +1 -1
  30. package/assets/home-BRJ6eKVn.js +2 -0
  31. package/assets/{icon-Dt0vBgDO.js → icon-DLHMhF_-.js} +1 -1
  32. package/assets/{index-Cgp8OfuI.js → index-BRQOFOzQ.js} +1 -1
  33. package/assets/{index-BykbU6Ee.js → index-BZZx7KCI.js} +1 -1
  34. package/assets/{index-Cw5o84pO.js → index-BpVWRzP4.js} +2 -2
  35. package/assets/{index-BbXEMx9n.js → index-Bz0y23v2.js} +1 -1
  36. package/assets/index-C148XJoK.js +1 -0
  37. package/assets/{index-CaJgc5EZ.js → index-C8anOJBB.js} +1 -1
  38. package/assets/{index-BKCgnGj_.js → index-CS5ssiKu.js} +1 -1
  39. package/assets/{index-B8BS9wMC.js → index-CsMwA9pu.js} +1 -1
  40. package/assets/{index-DrWfGwtf.js → index-HZzILD42.js} +1 -1
  41. package/assets/{index-BC0yfOHo.js → index-kzaPFHKt.js} +1 -1
  42. package/assets/{init-user-JfCKJ5Ce.js → init-user-VMPNdivw.js} +1 -1
  43. package/assets/{input-CvRbIbk4.js → input-CZTX-THl.js} +1 -1
  44. package/assets/{input-error-DMK7cAt7.js → input-error-DpUrcJaR.js} +1 -1
  45. package/assets/item-add-1duKvWXz.js +1 -0
  46. package/assets/{label-CSLFe9Bz.js → label-B1wVTLjK.js} +1 -1
  47. package/assets/list-C07llS61.js +1 -0
  48. package/assets/{list-table-DA9MhywL.js → list-table-Bh8E-zkN.js} +11 -16
  49. package/assets/{login-DQwGtdis.js → login-Dl59_ycU.js} +1 -1
  50. package/assets/manifest.json +716 -566
  51. package/assets/{material-icon-BJg8o_fs.js → material-icon-C9IuCi5R.js} +1 -1
  52. package/assets/module-DwX7rlQ2.js +1 -0
  53. package/assets/{monaco-editor-CJs0_GlD.js → monaco-editor-DjLNSn-O.js} +1 -1
  54. package/assets/{multi-select-BvRpAW8r.js → multi-select-CvcWwfki.js} +2 -2
  55. package/assets/{nav-footer-Bs4dmN1d.js → nav-footer-C7_pEHmX.js} +1 -1
  56. package/assets/{nav-main-Bq3IMk4C.js → nav-main-CwwCPIYf.js} +1 -1
  57. package/assets/{nav-user-CbB22J5O.js → nav-user-K0xXPEmb.js} +1 -1
  58. package/assets/{pagination-render-DuXDDbC_.js → pagination-render-BYBw11L4.js} +1 -1
  59. package/assets/pencil-CewBKDRo.js +6 -0
  60. package/assets/{popover-DtoGI2b1.js → popover-vHKm7zkm.js} +1 -1
  61. package/assets/{register-BSogVF0h.js → register-CRsK6KgL.js} +1 -1
  62. package/assets/{select-BWepUw-9.js → select-Bs9mijkr.js} +2 -2
  63. package/assets/{sidebar-CAHsHdjM.js → sidebar-DflSp1X1.js} +1 -1
  64. package/assets/{skeleton-COOcAA8f.js → skeleton-C6UluiCK.js} +1 -1
  65. package/assets/{sonner-BI0IFOQN.js → sonner-Cn7ueXZc.js} +1 -1
  66. package/assets/{toast-editor-CMK7QtF1.js → toast-editor-FNxkBiFw.js} +1 -1
  67. package/assets/{tooltip-DHwpLKOI.js → tooltip-BlR1mf2V.js} +1 -1
  68. package/assets/{use-appearance-DRfIqTgw.js → use-appearance-CL1-5ZfQ.js} +1 -1
  69. package/assets/{use-window-size-h0Sh_NvX.js → use-window-size-ciZdUHrJ.js} +1 -1
  70. package/assets/{user-info-DFrmpJ4y.js → user-info-qduQAMOl.js} +2 -2
  71. package/assets/{user-menu-content-DPXQdERj.js → user-menu-content-Cjq658jE.js} +2 -2
  72. package/assets/welcome-CbHEVD33.js +1 -0
  73. package/controllers/add.js +6 -7
  74. package/controllers/catalog/Catalog.d.ts +1 -1
  75. package/controllers/catalog/Catalog.js +40 -32
  76. package/controllers/catalog/FrontentCatalogAdapter.d.ts +43 -21
  77. package/controllers/catalog/FrontentCatalogAdapter.js +49 -29
  78. package/controllers/edit.js +1 -1
  79. package/controllers/list.js +1 -1
  80. package/helpers/accessRightsHelper.js +4 -0
  81. package/helpers/inertiaAddHelper.d.ts +1 -1
  82. package/helpers/inertiaFromHelper.js +1 -1
  83. package/helpers/menuHelper.js +3 -2
  84. package/index.d.ts +2 -2
  85. package/index.js +2 -2
  86. package/interfaces/global.d.ts +2 -2
  87. package/lib/Adminizer.d.ts +2 -2
  88. package/lib/Adminizer.js +4 -4
  89. package/lib/requestProcessor.js +10 -3
  90. package/lib/v4/DataAccessor.js +4 -4
  91. package/lib/{catalog → v4/catalog}/AbstractCatalog.d.ts +87 -31
  92. package/lib/{catalog → v4/catalog}/AbstractCatalog.js +38 -33
  93. package/lib/v4/catalog/Navigation.d.ts +43 -0
  94. package/lib/v4/catalog/Navigation.js +462 -0
  95. package/lib/{controls → v4/controls}/AbstractControls.d.ts +1 -1
  96. package/lib/{controls → v4/controls}/codeEditor/MonacoEditor.d.ts +1 -1
  97. package/lib/{controls → v4/controls}/geojsoneditor/GeoEditor.d.ts +1 -1
  98. package/lib/{controls → v4/controls}/jsoneditor/JsonEditor.d.ts +1 -1
  99. package/lib/{controls → v4/controls}/markdown/ToastUiEditor.d.ts +1 -1
  100. package/lib/{controls → v4/controls}/table/Handsontable.d.ts +1 -1
  101. package/lib/{controls → v4/controls}/wysiwyg/CKeditor.d.ts +1 -1
  102. package/lib/{datatable → v4/datatable}/NodeTable.d.ts +3 -3
  103. package/lib/v4/model/adapter/sequelize.js +4 -4
  104. package/lib/{widgets → v4/widgets}/abstractLink.d.ts +1 -1
  105. package/lib/{widgets → v4/widgets}/abstractWidgetBase.d.ts +1 -1
  106. package/lib/{widgets → v4/widgets}/widgetHandler.d.ts +3 -3
  107. package/models/NavigationAP.d.ts +2 -3
  108. package/models/NavigationAP.js +5 -6
  109. package/models/UserAP.d.ts +1 -1
  110. package/package.json +3 -1
  111. package/system/Router.js +2 -2
  112. package/system/bindControls.js +6 -6
  113. package/system/bindInertia.js +2 -2
  114. package/system/bindNavigation.d.ts +2 -0
  115. package/system/bindNavigation.js +42 -41
  116. package/assets/add-BP_u3Tjl.js +0 -1
  117. package/assets/add-form-nffmiYTh.js +0 -1
  118. package/assets/add-group-D4vcHlm-.js +0 -1
  119. package/assets/add-user-DWh3Nas0.js +0 -1
  120. package/assets/app-layout-DYsRFUuP.js +0 -1
  121. package/assets/dashboard-Ddh74NBQ.js +0 -3
  122. package/assets/form-BgWdwvz1.js +0 -1
  123. package/assets/home-CHntBHJa.js +0 -2
  124. package/assets/list-B2Oa5O_Q.js +0 -1
  125. package/assets/module-DWXp59Vg.js +0 -1
  126. package/assets/welcome-B4WCIXKf.js +0 -1
  127. package/lib/catalog/Navigation.d.ts +0 -0
  128. package/lib/catalog/Navigation.js +0 -531
  129. /package/lib/{catalog → v4/catalog}/CatalogHandler.d.ts +0 -0
  130. /package/lib/{catalog → v4/catalog}/CatalogHandler.js +0 -0
  131. /package/lib/{controls → v4/controls}/AbstractControls.js +0 -0
  132. /package/lib/{controls → v4/controls}/ControlsHandler.d.ts +0 -0
  133. /package/lib/{controls → v4/controls}/ControlsHandler.js +0 -0
  134. /package/lib/{controls → v4/controls}/codeEditor/MonacoEditor.js +0 -0
  135. /package/lib/{controls → v4/controls}/geojsoneditor/GeoEditor.js +0 -0
  136. /package/lib/{controls → v4/controls}/jsoneditor/JsonEditor.js +0 -0
  137. /package/lib/{controls → v4/controls}/markdown/ToastUiEditor.js +0 -0
  138. /package/lib/{controls → v4/controls}/table/Handsontable.js +0 -0
  139. /package/lib/{controls → v4/controls}/wysiwyg/CKeditor.js +0 -0
  140. /package/lib/{datatable → v4/datatable}/NodeTable.js +0 -0
  141. /package/lib/{inertia → v4/inertia}/flash.d.ts +0 -0
  142. /package/lib/{inertia → v4/inertia}/flash.js +0 -0
  143. /package/lib/{inertia → v4/inertia}/inertiaAdapter.d.ts +0 -0
  144. /package/lib/{inertia → v4/inertia}/inertiaAdapter.js +0 -0
  145. /package/lib/{widgets → v4/widgets}/abstractAction.d.ts +0 -0
  146. /package/lib/{widgets → v4/widgets}/abstractAction.js +0 -0
  147. /package/lib/{widgets → v4/widgets}/abstractCustom.d.ts +0 -0
  148. /package/lib/{widgets → v4/widgets}/abstractCustom.js +0 -0
  149. /package/lib/{widgets → v4/widgets}/abstractInfo.d.ts +0 -0
  150. /package/lib/{widgets → v4/widgets}/abstractInfo.js +0 -0
  151. /package/lib/{widgets → v4/widgets}/abstractLink.js +0 -0
  152. /package/lib/{widgets → v4/widgets}/abstractSwitch.d.ts +0 -0
  153. /package/lib/{widgets → v4/widgets}/abstractSwitch.js +0 -0
  154. /package/lib/{widgets → v4/widgets}/abstractWidgetBase.js +0 -0
  155. /package/lib/{widgets → v4/widgets}/widgetHandler.js +0 -0
@@ -0,0 +1,462 @@
1
+ import { AbstractCatalog, AbstractGroup, AbstractItem } from "./AbstractCatalog";
2
+ import { v4 as uuid } from "uuid";
3
+ import { Adminizer } from "../../Adminizer";
4
+ class StorageService {
5
+ storageMap = new Map();
6
+ id;
7
+ model;
8
+ adminizer;
9
+ constructor(adminizer, id, model) {
10
+ this.adminizer = adminizer;
11
+ this.id = id;
12
+ this.model = model.toLowerCase();
13
+ this.initModel();
14
+ }
15
+ async initModel() {
16
+ // Direct call by model adapter
17
+ const navigation = await this.adminizer.modelHandler.model.get(this.model)["_findOne"]({ label: this.id });
18
+ if (navigation) {
19
+ Adminizer.log.info(`Found existing navigation: ${this.id}`);
20
+ await this.populateFromTree(navigation.tree);
21
+ }
22
+ else {
23
+ const newNavigation = { label: this.id, tree: [] };
24
+ // Direct call by model adapter
25
+ await this.adminizer.modelHandler.model.get(this.model)["_create"](newNavigation);
26
+ Adminizer.log.info(`Created a new navigation: ${this.id}`);
27
+ }
28
+ }
29
+ getId() {
30
+ return this.id;
31
+ }
32
+ async buildTree() {
33
+ const rootElements = await this.findElementsByParentId(null, null);
34
+ const buildSubTree = async (elements) => {
35
+ const tree = [];
36
+ for (const element of elements) {
37
+ const children = await this.findElementsByParentId(element.id, null);
38
+ tree.push({
39
+ ...element,
40
+ children: await buildSubTree(children)
41
+ });
42
+ }
43
+ return tree;
44
+ };
45
+ let tree = await buildSubTree(rootElements);
46
+ function sortTree(items) {
47
+ items.sort((a, b) => a.sortOrder - b.sortOrder);
48
+ for (let i = 0; i < items.length; i++) {
49
+ const item = items[i];
50
+ if (item.children) {
51
+ sortTree(item.children);
52
+ }
53
+ }
54
+ }
55
+ sortTree(tree);
56
+ return tree;
57
+ }
58
+ async populateFromTree(tree) {
59
+ const traverseTree = async (node, parentId = null) => {
60
+ const { children, ...itemData } = node;
61
+ const item = { ...itemData, parentId };
62
+ await this.setElement(item.id, item);
63
+ if (children && children.length > 0) {
64
+ for (const child of children) {
65
+ await traverseTree(child, item.id);
66
+ }
67
+ }
68
+ };
69
+ for (const node of tree) {
70
+ await traverseTree(node);
71
+ }
72
+ }
73
+ async setElement(id, item) {
74
+ this.storageMap.set(item.id, item);
75
+ await this.saveToDB();
76
+ // This like fetch in DB
77
+ return this.findElementById(item.id);
78
+ }
79
+ async removeElementById(id) {
80
+ this.storageMap.delete(id);
81
+ setTimeout(async () => {
82
+ await this.saveToDB();
83
+ }, 500);
84
+ }
85
+ async findElementById(id) {
86
+ return this.storageMap.get(id);
87
+ }
88
+ async findElementByModelId(modelId) {
89
+ const elements = [];
90
+ for (const item of this.storageMap.values()) {
91
+ if (item.modelId === modelId) {
92
+ elements.push(item);
93
+ }
94
+ }
95
+ return elements;
96
+ }
97
+ async saveToDB() {
98
+ let tree = await this.buildTree();
99
+ console.log({ label: this.id }, { tree: tree });
100
+ try {
101
+ // Direct call by model adapter
102
+ await this.adminizer.modelHandler.model.get(this.model)["_update"]({ label: this.id }, { tree: tree });
103
+ }
104
+ catch (e) {
105
+ console.log(e);
106
+ throw 'navigation model update error';
107
+ }
108
+ }
109
+ async findElementsByParentId(parentId, type) {
110
+ const elements = [];
111
+ for (const item of this.storageMap.values()) {
112
+ if (type === null && item.parentId === parentId) {
113
+ elements.push(item);
114
+ continue;
115
+ }
116
+ if (item.parentId === parentId && item.type === type) {
117
+ elements.push(item);
118
+ }
119
+ }
120
+ return elements;
121
+ }
122
+ async getAllElements() {
123
+ return Array.from(this.storageMap.values());
124
+ }
125
+ async search(s, type) {
126
+ const lowerCaseQuery = s.toLowerCase(); // Convert query to lowercase for case-insensitive search
127
+ const matchedElements = [];
128
+ for (const item of this.storageMap.values()) {
129
+ // Check if item type matches the specified type
130
+ if (item.type === type) {
131
+ // Search by name
132
+ if (item.name.toLowerCase().includes(lowerCaseQuery)) {
133
+ matchedElements.push(item);
134
+ }
135
+ }
136
+ }
137
+ return matchedElements;
138
+ }
139
+ }
140
+ export class StorageServices {
141
+ static storages = [];
142
+ static add(storage) {
143
+ this.storages.push(storage);
144
+ }
145
+ static get(id) {
146
+ return this.storages.find(storage => storage.getId() === id);
147
+ }
148
+ static getAll() {
149
+ return this.storages;
150
+ }
151
+ }
152
+ export class Navigation extends AbstractCatalog {
153
+ name = 'Navigation';
154
+ slug = 'navigation';
155
+ icon = "box";
156
+ actionHandlers = [];
157
+ idList = [];
158
+ constructor(adminizer, config) {
159
+ let items = [];
160
+ for (const configElement of config.items) {
161
+ items.push(new NavigationItem(adminizer, configElement.title, configElement.model, config.model, configElement.urlPath));
162
+ }
163
+ items.push(new NavigationGroup(adminizer, config.groupField));
164
+ items.push(new LinkItem(adminizer));
165
+ for (const section of config.sections) {
166
+ StorageServices.add(new StorageService(adminizer, section, config.model));
167
+ }
168
+ super(adminizer, items);
169
+ this.movingGroupsRootOnly = config.movingGroupsRootOnly;
170
+ this.idList = config.sections ?? [];
171
+ }
172
+ async getIdList() {
173
+ return this.idList;
174
+ }
175
+ }
176
+ class NavigationItem extends AbstractItem {
177
+ allowedRoot = true;
178
+ icon;
179
+ name;
180
+ type;
181
+ model;
182
+ navigationModel;
183
+ actionHandlers = [];
184
+ urlPath;
185
+ adminizer;
186
+ constructor(adminizer, name, model, navigationModel, urlPath) {
187
+ super();
188
+ this.name = name;
189
+ this.navigationModel = navigationModel;
190
+ this.model = model.toLowerCase();
191
+ this.type = model.toLowerCase();
192
+ this.urlPath = urlPath;
193
+ let configModel = adminizer.config.models[this.model];
194
+ this.icon = configModel?.icon ?? 'file';
195
+ this.adminizer = adminizer;
196
+ }
197
+ async create(data, catalogId) {
198
+ let storage = StorageServices.get(catalogId);
199
+ let storageData = null;
200
+ if (data._method === 'select') {
201
+ // Direct call by model adapter
202
+ let record = await this.adminizer.modelHandler.model.get(this.model)["_findOne"]({ id: data.record });
203
+ storageData = await this.dataPreparation({
204
+ record: record,
205
+ parentId: data.parentId,
206
+ targetBlank: data.targetBlank
207
+ }, catalogId);
208
+ }
209
+ else {
210
+ storageData = await this.dataPreparation(data, catalogId);
211
+ }
212
+ return await storage.setElement(data.id, storageData);
213
+ }
214
+ async dataPreparation(data, catalogId, sortOrder) {
215
+ let storage = StorageServices.get(catalogId);
216
+ let urlPath = eval('`' + this.urlPath + '`');
217
+ let parentId = data.parentId ? data.parentId : 0; // changed from null to 0
218
+ return {
219
+ id: uuid(),
220
+ modelId: data.record.id,
221
+ targetBlank: data.targetBlank ?? data.record.targetBlank,
222
+ name: data.record.name ?? data.record.title ?? data.record.id,
223
+ parentId: parentId,
224
+ sortOrder: sortOrder ?? (await storage.findElementsByParentId(parentId, null)).length,
225
+ icon: this.icon,
226
+ type: this.type,
227
+ urlPath: urlPath
228
+ };
229
+ }
230
+ async updateModelItems(modelId, data, catalogId) {
231
+ let storage = StorageServices.get(catalogId);
232
+ let items = await storage.findElementByModelId(modelId);
233
+ let urlPath = eval('`' + this.urlPath + '`');
234
+ for (const item of items) {
235
+ item.name = data.record.name;
236
+ item.urlPath = urlPath;
237
+ if (item.id === data.record.treeId) {
238
+ item.targetBlank = data.record.targetBlank;
239
+ }
240
+ await storage.setElement(item.id, item);
241
+ }
242
+ return Promise.resolve(undefined);
243
+ }
244
+ async update(itemId, data, catalogId) {
245
+ let storage = StorageServices.get(catalogId);
246
+ return await storage.setElement(itemId, data);
247
+ }
248
+ async deleteItem(itemId, catalogId) {
249
+ let storage = StorageServices.get(catalogId);
250
+ return await storage.removeElementById(itemId);
251
+ }
252
+ async find(itemId, catalogId) {
253
+ let storage = StorageServices.get(catalogId);
254
+ return await storage.findElementById(itemId);
255
+ }
256
+ /**
257
+ * @deprecated reason: migration for intertia
258
+ * // TODO: need passing custom React module
259
+ */
260
+ async getAddHTML(req) {
261
+ let type = 'navigation.item';
262
+ // Direct call by model adapter
263
+ let itemsDB = await this.adminizer.modelHandler.model.get(this.model)["_find"]({});
264
+ let items = itemsDB.map((item) => {
265
+ return {
266
+ id: item.id,
267
+ name: item.name ?? item.title ?? item.id
268
+ };
269
+ });
270
+ return {
271
+ type: type,
272
+ data: {
273
+ items: items,
274
+ model: this.model,
275
+ labels: {
276
+ selectTitle: `${req.i18n.__('Select')} ${req.i18n.__(this.name + 's')}`,
277
+ createTitle: `${req.i18n.__('create new')} ${req.i18n.__(this.name + 's')}`,
278
+ OR: req.i18n.__('OR')
279
+ }
280
+ }
281
+ };
282
+ }
283
+ async getChilds(parentId, catalogId) {
284
+ let storage = StorageServices.get(catalogId);
285
+ return await storage.findElementsByParentId(parentId, this.type);
286
+ }
287
+ /**
288
+ * @deprecated reason: migration for intertia
289
+ * // TODO: need passing custom React module
290
+ */
291
+ async getEditHTML(id, catalogId, req, modelId) {
292
+ let item = await this.find(id, catalogId);
293
+ let type = 'html';
294
+ // This dirty hack is here because the field of view is disappearing
295
+ req.i18n.setLocale(req.user.locale);
296
+ const __ = (s) => {
297
+ return req.i18n.__(s);
298
+ };
299
+ return Promise.resolve({
300
+ type: type,
301
+ // data: ejs.render(fs.readFileSync(ViewsHelper.getViewPath('./../../views/ejs/navigation/itemHTMLEdit.ejs'), 'utf8'), {item: item, __: __})
302
+ data: ''
303
+ });
304
+ }
305
+ async search(s, catalogId) {
306
+ let storage = StorageServices.get(catalogId);
307
+ return await storage.search(s, this.type);
308
+ }
309
+ }
310
+ class NavigationGroup extends AbstractGroup {
311
+ allowedRoot = true;
312
+ name = "Group";
313
+ groupField;
314
+ adminizer;
315
+ constructor(adminizer, groupField) {
316
+ super();
317
+ this.groupField = groupField;
318
+ this.adminizer = adminizer;
319
+ }
320
+ async create(data, catalogId) {
321
+ let storage = StorageServices.get(catalogId);
322
+ let storageData = await this.dataPreparation(data, catalogId);
323
+ delete data.name;
324
+ delete data.parentId;
325
+ storageData = { ...storageData, ...data };
326
+ return await storage.setElement(storageData.id, storageData);
327
+ }
328
+ async dataPreparation(data, catalogId, sortOrder) {
329
+ let storage = StorageServices.get(catalogId);
330
+ let parentId = data.parentId ? data.parentId : 0; // changed from null to 0
331
+ return {
332
+ id: uuid(),
333
+ name: data.name,
334
+ targetBlank: data.targetBlank,
335
+ parentId: parentId,
336
+ sortOrder: sortOrder ?? (await storage.findElementsByParentId(parentId, null)).length,
337
+ icon: this.icon,
338
+ type: this.type
339
+ };
340
+ }
341
+ async deleteItem(itemId, catalogId) {
342
+ let storage = StorageServices.get(catalogId);
343
+ return await storage.removeElementById(itemId);
344
+ }
345
+ async find(itemId, catalogId) {
346
+ let storage = StorageServices.get(catalogId);
347
+ return await storage.findElementById(itemId);
348
+ }
349
+ async update(itemId, data, catalogId) {
350
+ let storage = StorageServices.get(catalogId);
351
+ return await storage.setElement(itemId, data);
352
+ }
353
+ async updateModelItems(modelId, data, catalogId) {
354
+ let storage = StorageServices.get(catalogId);
355
+ return await storage.setElement(modelId, data);
356
+ }
357
+ /**
358
+ * @deprecated reason: migration for intertia
359
+ * // TODO: need passing custom React module
360
+ */
361
+ getAddHTML(req) {
362
+ let type = 'navigation.group';
363
+ let resItems = [];
364
+ if (this.groupField.length) {
365
+ resItems = this.groupField.map((field) => {
366
+ return {
367
+ name: field.name,
368
+ required: field.required
369
+ };
370
+ });
371
+ }
372
+ return Promise.resolve({
373
+ type: type,
374
+ data: {
375
+ items: resItems,
376
+ labels: {
377
+ openInNewWindow: req.i18n.__('Open in a new window'),
378
+ title: req.i18n.__('Title'),
379
+ save: req.i18n.__('Save')
380
+ }
381
+ }
382
+ });
383
+ }
384
+ async getChilds(parentId, catalogId) {
385
+ let storage = StorageServices.get(catalogId);
386
+ return await storage.findElementsByParentId(parentId, this.type);
387
+ }
388
+ /**
389
+ * @deprecated reason: migration for intertia
390
+ * // TODO: need passing custom React module
391
+ */
392
+ async getEditHTML(id, catalogId, req, modelId) {
393
+ let type = 'html';
394
+ let item = await this.find(id, catalogId);
395
+ // This dirty hack is here because the field of view is disappearing
396
+ req.i18n.setLocale(req.user.locale);
397
+ const __ = (s) => {
398
+ return req.i18n.__(s);
399
+ };
400
+ return Promise.resolve({
401
+ type: type,
402
+ // data: ejs.render(fs.readFileSync(ViewsHelper.getViewPath('./../../views/ejs/navigation/GroupHTMLEdit.ejs'), 'utf8'), {
403
+ // fields: this.groupField,
404
+ // item: item,
405
+ // __: __
406
+ // }),
407
+ data: ''
408
+ });
409
+ }
410
+ async search(s, catalogId) {
411
+ let storage = StorageServices.get(catalogId);
412
+ return await storage.search(s, this.type);
413
+ }
414
+ }
415
+ class LinkItem extends NavigationGroup {
416
+ allowedRoot = true;
417
+ icon = 'external-link-alt';
418
+ name = 'Link';
419
+ type = 'link';
420
+ isGroup = false;
421
+ constructor(adminizer) {
422
+ super(adminizer, []);
423
+ }
424
+ /**
425
+ * @deprecated reason: migration for intertia
426
+ * // TODO: need passing custom React module
427
+ */
428
+ // @ts-ignore
429
+ getAddHTML(req) {
430
+ let type = 'html';
431
+ req.i18n.setLocale(req.user.locale);
432
+ const __ = (s) => {
433
+ return req.i18n.__(s);
434
+ };
435
+ return Promise.resolve({
436
+ type: type,
437
+ // data: ejs.render(fs.readFileSync(ViewsHelper.getViewPath('./../../views/ejs/navigation/LinkItemAdd.ejs'), 'utf8'), {__: __}),
438
+ data: ''
439
+ });
440
+ }
441
+ /**
442
+ * @deprecated reason: migration for intertia
443
+ * // TODO: need passing custom React module
444
+ */
445
+ async getEditHTML(id, catalogId, req) {
446
+ let type = 'html';
447
+ let item = await this.find(id, catalogId);
448
+ req.i18n.setLocale(req.user.locale);
449
+ const __ = (s) => {
450
+ return req.i18n.__(s);
451
+ };
452
+ return Promise.resolve({
453
+ type: type,
454
+ // data: ejs.render(fs.readFileSync(ViewsHelper.getViewPath('./../../views/ejs/navigation/LinkItemEdit.ejs'), 'utf8'), {
455
+ // fields: this.groupField,
456
+ // item: item,
457
+ // __: __
458
+ // }),
459
+ data: ''
460
+ });
461
+ }
462
+ }
@@ -1,4 +1,4 @@
1
- import { Adminizer } from "../Adminizer";
1
+ import { Adminizer } from "../../Adminizer";
2
2
  export type ControlType = 'wysiwyg' | 'jsonEditor' | 'geoJson' | 'markdown' | 'table' | 'codeEditor';
3
3
  export interface Path {
4
4
  jsPath: {
@@ -1,5 +1,5 @@
1
1
  import { AbstractControls, ControlType, Config, Path } from "../AbstractControls";
2
- import { Adminizer } from "../../Adminizer";
2
+ import { Adminizer } from "../../../Adminizer";
3
3
  export declare class MonacoEditor extends AbstractControls {
4
4
  readonly config: Config;
5
5
  readonly name: string;
@@ -1,5 +1,5 @@
1
1
  import { AbstractControls, ControlType, Config, Path } from "../AbstractControls";
2
- import { Adminizer } from "../../Adminizer";
2
+ import { Adminizer } from "../../../Adminizer";
3
3
  export declare class GeoEditor extends AbstractControls {
4
4
  readonly config: Config;
5
5
  readonly name: string;
@@ -1,6 +1,6 @@
1
1
  import { AbstractControls, ControlType, Path, Config } from "../AbstractControls";
2
2
  import { EditorOptions } from "@toast-ui/editor/types/editor";
3
- import { Adminizer } from "../../Adminizer";
3
+ import { Adminizer } from "../../../Adminizer";
4
4
  export declare class JsonEditor extends AbstractControls {
5
5
  readonly config: Partial<EditorOptions>;
6
6
  readonly name: string;
@@ -1,6 +1,6 @@
1
1
  import { AbstractControls, ControlType, Path, Config } from "../AbstractControls";
2
2
  import { EditorOptions } from "@toast-ui/editor/types/editor";
3
- import { Adminizer } from "../../Adminizer";
3
+ import { Adminizer } from "../../../Adminizer";
4
4
  export declare class ToastUiEditor extends AbstractControls {
5
5
  readonly config: Partial<EditorOptions>;
6
6
  readonly name: string;
@@ -1,5 +1,5 @@
1
1
  import { AbstractControls, ControlType, Config, Path } from "../AbstractControls";
2
- import { Adminizer } from "../../Adminizer";
2
+ import { Adminizer } from "../../../Adminizer";
3
3
  export declare class Handsontable extends AbstractControls {
4
4
  readonly config: Config;
5
5
  readonly name: string;
@@ -1,5 +1,5 @@
1
1
  import { AbstractControls, ControlType, Config, Path } from "../AbstractControls";
2
- import { Adminizer } from "../../Adminizer";
2
+ import { Adminizer } from "../../../Adminizer";
3
3
  export declare class CKeditor extends AbstractControls {
4
4
  readonly name: string;
5
5
  readonly type: ControlType;
@@ -1,6 +1,6 @@
1
- import { Fields } from '../../helpers/fieldsHelper';
2
- import { AbstractModel } from '../v4/model/AbstractModel';
3
- import { DataAccessor } from "../v4/DataAccessor";
1
+ import { Fields } from '../../../helpers/fieldsHelper';
2
+ import { AbstractModel } from '../model/AbstractModel';
3
+ import { DataAccessor } from "../DataAccessor";
4
4
  interface Request {
5
5
  start: string;
6
6
  length: string;
@@ -99,7 +99,7 @@ export function mapSequelizeToWaterline(model) {
99
99
  result[a.foreignKey]["primaryKeyForAssociation"] = true;
100
100
  result[alias] = {
101
101
  type: "association",
102
- model: a.target.name.toLowerCase(),
102
+ model: a.target.name,
103
103
  via: a.foreignKey,
104
104
  };
105
105
  break;
@@ -109,7 +109,7 @@ export function mapSequelizeToWaterline(model) {
109
109
  result[a.foreignKey]["primaryKeyForAssociation"] = true;
110
110
  result[alias] = {
111
111
  type: "association",
112
- model: a.target.name.toLowerCase(),
112
+ model: a.target.name,
113
113
  via: a.foreignKey,
114
114
  };
115
115
  break;
@@ -118,7 +118,7 @@ export function mapSequelizeToWaterline(model) {
118
118
  const a = assoc;
119
119
  result[alias] = {
120
120
  type: "association-many",
121
- collection: a.target.name.toLowerCase(),
121
+ collection: a.target.name,
122
122
  via: a.foreignKey,
123
123
  };
124
124
  break;
@@ -127,7 +127,7 @@ export function mapSequelizeToWaterline(model) {
127
127
  const a = assoc;
128
128
  result[alias] = {
129
129
  type: "association-many",
130
- collection: a.target.name.toLowerCase(),
130
+ collection: a.target.name,
131
131
  via: a.otherKey,
132
132
  };
133
133
  break;
@@ -1,5 +1,5 @@
1
1
  import BaseWidget from "./abstractWidgetBase";
2
- import { MaterialIcon } from "../../interfaces/MaaterialIcons";
2
+ import { MaterialIcon } from "../../../interfaces/MaaterialIcons";
3
3
  export interface Links {
4
4
  name: string;
5
5
  description: string;
@@ -1,4 +1,4 @@
1
- import { MaterialIcon } from "../../interfaces/MaaterialIcons";
1
+ import { MaterialIcon } from "../../../interfaces/MaaterialIcons";
2
2
  export default abstract class BaseWidget {
3
3
  /** Widget unique id */
4
4
  abstract readonly id: string;
@@ -3,10 +3,10 @@ import InfoBase from "./abstractInfo";
3
3
  import ActionBase from "./abstractAction";
4
4
  import LinkBase from "./abstractLink";
5
5
  import CustomBase from "./abstractCustom";
6
- import { AdminpanelIcon } from "../../interfaces/adminpanelConfig";
7
- import { Adminizer } from "../Adminizer";
6
+ import { AdminpanelIcon } from "../../../interfaces/adminpanelConfig";
7
+ import { Adminizer } from "../../Adminizer";
8
8
  import { UserAP } from "models/UserAP";
9
- import { I18n } from "../v4/I18n";
9
+ import { I18n } from "../I18n";
10
10
  export type WidgetType = (SwitcherBase | InfoBase | ActionBase | LinkBase | CustomBase);
11
11
  export interface WidgetConfig {
12
12
  id: string;
@@ -1,14 +1,13 @@
1
1
  declare const _default: {
2
2
  id: {
3
3
  type: string;
4
- allowNull: boolean;
5
- uuid: boolean;
4
+ autoIncrement: boolean;
6
5
  primaryKey: boolean;
7
- required: boolean;
8
6
  };
9
7
  label: {
10
8
  type: string;
11
9
  required: boolean;
10
+ unique: boolean;
12
11
  };
13
12
  tree: {
14
13
  type: string;
@@ -1,14 +1,13 @@
1
1
  export default {
2
2
  id: {
3
- type: "string",
4
- allowNull: false,
5
- uuid: true,
6
- primaryKey: true,
7
- required: true
3
+ type: "number",
4
+ autoIncrement: true,
5
+ primaryKey: true
8
6
  },
9
7
  label: {
10
8
  type: "string",
11
- required: true
9
+ required: true,
10
+ unique: true
12
11
  },
13
12
  tree: {
14
13
  type: "json",
@@ -1,4 +1,4 @@
1
- import { WidgetConfig, WidgetsLayouts } from "lib/widgets/widgetHandler";
1
+ import { WidgetConfig, WidgetsLayouts } from "lib/v4/widgets/widgetHandler";
2
2
  import { GroupAP } from "./GroupAP";
3
3
  declare const _default: {
4
4
  id: {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "adminizer",
3
3
  "type": "module",
4
- "version": "4.1.0-build.26",
4
+ "version": "4.1.0-build.28",
5
5
  "main": "index.js",
6
6
  "scripts": {
7
7
  "test": "vitest --reporter verbose",
@@ -27,6 +27,7 @@
27
27
  "license": "MIT",
28
28
  "description": "",
29
29
  "dependencies": {
30
+ "@minoru/react-dnd-treeview": "^3.5.2",
30
31
  "body-parser": "^1.20.3",
31
32
  "chalk": "^5.4.1",
32
33
  "cmdk": "^1.1.1",
@@ -42,6 +43,7 @@
42
43
  "multer": "^1.4.5-lts.1",
43
44
  "next-themes": "^0.4.6",
44
45
  "password-hash": "^1.2.2",
46
+ "react-dnd": "^16.0.1",
45
47
  "sharp": "^0.33.5",
46
48
  "typeorm": "^0.3.20",
47
49
  "uuid": "^11.0.5",
package/system/Router.js CHANGED
@@ -66,8 +66,8 @@ export default class Router {
66
66
  /**
67
67
  * Catalog
68
68
  */
69
- adminizer.app.all(`/catalog/:slug/:id`, adminizer.policyManager.bindPolicies(policies, catalogController));
70
- adminizer.app.all(`/catalog/:slug`, adminizer.policyManager.bindPolicies(policies, catalogController));
69
+ adminizer.app.all(`${adminizer.config.routePrefix}/catalog/:slug/:id`, adminizer.policyManager.bindPolicies(policies, catalogController));
70
+ adminizer.app.all(`${adminizer.config.routePrefix}/catalog/:slug`, adminizer.policyManager.bindPolicies(policies, catalogController));
71
71
  /**
72
72
  * Media Manager
73
73
  */