adminizer 4.3.0-build.99 → 4.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (163) hide show
  1. package/assets/add-9NSjG6Jx.js +1 -0
  2. package/assets/add-form-uUiOWEy_.js +1 -0
  3. package/assets/add-group-Db0HkA1m.js +1 -0
  4. package/assets/add-group-form-DMz0_Oo9.js +1 -0
  5. package/assets/add-user-BMklpOqf.js +1 -0
  6. package/assets/{add-user-form-DrclnTOd.js → add-user-form-izlXhv2-.js} +1 -1
  7. package/assets/{app-D8oqdt8J.css → app-BJd5vD4i.css} +1 -1
  8. package/assets/app-layout-DcgYmhNb.js +1 -0
  9. package/assets/{app-shell-CHEYhVco.js → app-shell-C8Cnr5Hy.js} +1 -1
  10. package/assets/app-sidebar-HwvXNZzk.js +1 -0
  11. package/assets/app-sidebar-header-C8TTx8yd.js +1 -0
  12. package/assets/app.js +5 -5
  13. package/assets/{breadcrumbs-C439DWrC.js → breadcrumbs-DSMzNYiS.js} +1 -1
  14. package/assets/catalog-C2INmTwI.js +6 -0
  15. package/assets/catalog-D4n6dpGl.css +1 -0
  16. package/assets/{dashboard-Bi5KeZu2.js → dashboard-DwFL6nqn.js} +1 -1
  17. package/assets/{date-picker-DbJ8nHp5.js → date-picker-kW3wZQr_.js} +1 -1
  18. package/assets/{del-modal-_b3CSNHb.js → del-modal-DyIWFflP.js} +1 -1
  19. package/assets/{field-renderer-4obZ_jUo.js → field-renderer-BNQVfOir.js} +3 -3
  20. package/assets/form-CAIoGuhZ.js +1 -0
  21. package/assets/form-NUd-JZJN.js +1 -0
  22. package/assets/{geo-json-CadjdhwW.js → geo-json-YeWQOYnT.js} +1 -1
  23. package/assets/{home-BUoDaWe0.js → home-CteDT1us.js} +2 -2
  24. package/assets/{icon-DM49pZW3.js → icon-DpkedrXG.js} +1 -1
  25. package/assets/{init-user-DNrB8Xt5.js → init-user-DaOvt0vG.js} +1 -1
  26. package/assets/{input-error--IOnWghB.js → input-error-CmXZF6xy.js} +1 -1
  27. package/assets/list-CXQmJbH8.js +1 -0
  28. package/assets/{list-table-BKxxQkCW.js → list-table-BPpHDVPf.js} +4 -4
  29. package/assets/{login-6Xb8bcPq.js → login-DR6fvKtm.js} +1 -1
  30. package/assets/manifest.json +82 -82
  31. package/assets/{material-icon-BedgD2NE.js → material-icon-DwkE6wKL.js} +1 -1
  32. package/assets/media-manager-DYOfUh8F.js +14 -0
  33. package/assets/{module-B4-7WkY5.js → module-BIUqcf4-.js} +1 -1
  34. package/assets/{nav-footer-BwkQkwow.js → nav-footer-B85HLj-j.js} +1 -1
  35. package/assets/{nav-main-9Eb_A0rf.js → nav-main-BqKm87JZ.js} +1 -1
  36. package/assets/nav-user-DuCZNsZX.js +1 -0
  37. package/assets/notification-BQTjxH2H.js +27 -0
  38. package/assets/pagination-render-io0M2m2O.js +1 -0
  39. package/assets/{register-BIyjCy8M.js → register-hJD1ETdf.js} +1 -1
  40. package/assets/{tabs-BK_5wdPA.js → tabs-BhkFoerH.js} +1 -1
  41. package/assets/{theme-switcher-CKiJbMkh.js → theme-switcher-cgyA7_cO.js} +1 -1
  42. package/assets/{toast-editor-BZM5RHph.js → toast-editor-DwRk6WqT.js} +1 -1
  43. package/assets/{user-info-CcYdmjMZ.js → user-info-BGQvqBmO.js} +1 -1
  44. package/assets/{user-menu-content-DbUk8ZeY.js → user-menu-content-BDm88xaM.js} +1 -1
  45. package/assets/welcome-ks57d2us.js +1 -0
  46. package/controllers/add.js +8 -8
  47. package/controllers/addGroup.js +3 -3
  48. package/controllers/addUser.js +3 -3
  49. package/controllers/catalog/Catalog.js +22 -21
  50. package/controllers/catalog/FrontendCatalogAdapter.d.ts +82 -0
  51. package/controllers/catalog/FrontendCatalogAdapter.js +228 -0
  52. package/controllers/catalog/FrontentCatalogAdapter.d.ts +4 -4
  53. package/controllers/catalog/FrontentCatalogAdapter.js +28 -10
  54. package/controllers/ckeditorUpload.js +1 -1
  55. package/controllers/edit.js +21 -12
  56. package/controllers/editGroup.js +3 -3
  57. package/controllers/editUser.js +3 -3
  58. package/controllers/form.js +12 -10
  59. package/controllers/initUser.js +2 -2
  60. package/controllers/list.js +5 -5
  61. package/controllers/login.js +7 -4
  62. package/controllers/media-manager/ThumbController.js +2 -2
  63. package/controllers/media-manager/mediaManagerAdapter.js +2 -2
  64. package/controllers/media-manager/mediaManagerApi.js +2 -3
  65. package/controllers/navigation/edit.js +2 -2
  66. package/controllers/notifications/NotificationController.d.ts +1 -1
  67. package/controllers/notifications/NotificationController.js +6 -5
  68. package/controllers/register.js +1 -1
  69. package/controllers/remove.js +4 -4
  70. package/controllers/view.js +13 -11
  71. package/helpers/accessRightsHelper.js +1 -1
  72. package/helpers/controllerHelper.js +1 -1
  73. package/helpers/fieldsHelper.js +3 -3
  74. package/helpers/formHelper.js +1 -1
  75. package/helpers/inertiaAddHelper.js +3 -4
  76. package/helpers/inertiaFromHelper.js +2 -3
  77. package/helpers/inertiaListHelper.js +1 -1
  78. package/helpers/menuHelper.js +1 -1
  79. package/helpers/translationHelper.js +2 -2
  80. package/index.d.ts +5 -0
  81. package/index.js +31 -26
  82. package/interfaces/adminpanelConfig.d.ts +12 -0
  83. package/lib/Adminizer.d.ts +4 -3
  84. package/lib/Adminizer.js +41 -47
  85. package/lib/DataAccessor.js +3 -3
  86. package/lib/I18n.js +1 -1
  87. package/lib/PolicyManager.js +1 -1
  88. package/lib/catalog/AbstractCatalog.d.ts +6 -4
  89. package/lib/catalog/AbstractCatalog.js +5 -4
  90. package/lib/catalog/Navigation.d.ts +9 -7
  91. package/lib/catalog/Navigation.js +71 -42
  92. package/lib/controls/codeEditor/MonacoEditor.js +1 -1
  93. package/lib/controls/geojsoneditor/GeoEditor.js +1 -1
  94. package/lib/controls/jsoneditor/JsonEditor.js +1 -1
  95. package/lib/controls/markdown/ToastUiEditor.js +1 -1
  96. package/lib/controls/table/Handsontable.js +1 -1
  97. package/lib/controls/wysiwyg/CKeditor.js +1 -1
  98. package/lib/inertia/inertiaAdapter.js +31 -13
  99. package/lib/media-manager/AbstractMediaManager.d.ts +5 -3
  100. package/lib/media-manager/DefaultMediaManager.d.ts +3 -3
  101. package/lib/media-manager/DefaultMediaManager.js +21 -16
  102. package/lib/media-manager/Items.js +7 -6
  103. package/lib/media-manager/MediaManagerHandler.d.ts +3 -3
  104. package/lib/media-manager/MediaManagerHandler.js +4 -4
  105. package/lib/media-manager/Thumb.d.ts +2 -1
  106. package/lib/media-manager/Thumb.js +3 -4
  107. package/lib/media-manager/helpers/MediaManagerHelper.d.ts +7 -2
  108. package/lib/media-manager/helpers/MediaManagerHelper.js +12 -8
  109. package/lib/model/AbstractModel.js +1 -1
  110. package/lib/model/ModelHandler.js +1 -1
  111. package/lib/model/adapter/sequelize.js +1 -1
  112. package/lib/model/adapter/waterline.js +7 -1
  113. package/lib/notifications/AbstractNotificationService.js +1 -1
  114. package/lib/notifications/GeneralNotificationService.js +2 -2
  115. package/lib/notifications/NotificationHandler.js +1 -1
  116. package/lib/notifications/SystemNotificationService.js +2 -2
  117. package/lib/requestProcessor.js +2 -2
  118. package/lib/widgets/abstractAction.js +1 -1
  119. package/lib/widgets/abstractInfo.js +1 -1
  120. package/lib/widgets/abstractLink.js +1 -1
  121. package/lib/widgets/abstractSwitch.js +1 -1
  122. package/migrations/index.js +1 -1
  123. package/migrations/umzugExports.js +1 -1
  124. package/package.json +4 -2
  125. package/system/Router.js +31 -29
  126. package/system/bindAccessRights.js +7 -0
  127. package/system/bindAuthorization.js +4 -4
  128. package/system/bindControls.js +6 -6
  129. package/system/bindCors.d.ts +2 -0
  130. package/system/bindCors.js +41 -0
  131. package/system/bindDashboardWidgets.js +1 -1
  132. package/system/bindForms.js +1 -1
  133. package/system/bindInertia.js +4 -4
  134. package/system/bindMediaManager.js +2 -3
  135. package/system/bindModels.js +1 -1
  136. package/system/bindNavigation.d.ts +1 -1
  137. package/system/bindNavigation.js +34 -36
  138. package/system/bindNotifications.js +7 -7
  139. package/system/bindReqFunctions.js +7 -4
  140. package/system/bindTranslations.js +2 -2
  141. package/system/defaults.js +10 -2
  142. package/translations/ru.json +121 -120
  143. package/ui/components/handsontable.js +6 -3
  144. package/ui/lib/utils.d.ts +1 -0
  145. package/ui/lib/utils.js +16 -0
  146. package/assets/add-1E1UsMVZ.js +0 -1
  147. package/assets/add-form-CGa9QbwE.js +0 -1
  148. package/assets/add-group-7yAK6uFY.js +0 -1
  149. package/assets/add-group-form-BNmpvW8K.js +0 -1
  150. package/assets/add-user-NoYkTfZi.js +0 -1
  151. package/assets/app-layout-i2zN9Rn-.js +0 -1
  152. package/assets/app-sidebar-DeF8WNmW.js +0 -1
  153. package/assets/app-sidebar-header-DdM1EOrb.js +0 -1
  154. package/assets/catalog-B9hdop59.js +0 -6
  155. package/assets/catalog-C71LuRag.css +0 -1
  156. package/assets/form-Bte5kzjB.js +0 -1
  157. package/assets/form-oUlsuu7h.js +0 -1
  158. package/assets/list-C04Krl_W.js +0 -1
  159. package/assets/media-manager-UQT6RhI8.js +0 -14
  160. package/assets/nav-user-CRAfyE-x.js +0 -1
  161. package/assets/notification-ma2x7vka.js +0 -27
  162. package/assets/pagination-render-D3UyVAlr.js +0 -1
  163. package/assets/welcome-cWh1qnl_.js +0 -1
package/lib/I18n.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import fs from "fs";
2
2
  import path from "path";
3
3
  import { vsprintf } from "sprintf-js";
4
- import { Adminizer } from "./Adminizer";
4
+ import { Adminizer } from "./Adminizer.js";
5
5
  export class I18n {
6
6
  devMode;
7
7
  static locales = {};
@@ -1,6 +1,6 @@
1
1
  import * as fs from "fs";
2
2
  import * as path from "path";
3
- import { Adminizer } from "./Adminizer";
3
+ import { Adminizer } from "./Adminizer.js";
4
4
  import { pathToFileURL } from "url";
5
5
  class PolicyManager {
6
6
  _adminizer;
@@ -1,4 +1,5 @@
1
1
  import { Adminizer } from "../Adminizer";
2
+ import { StorageServices } from "./Navigation";
2
3
  /**
3
4
  * Interface `Item` describes the data that the UI will operate on
4
5
  * This is a common interface for all data that is linked to the catalog
@@ -24,6 +25,7 @@ export type _Item_ = {
24
25
  * General Item structure that will be available for all elements, including groups
25
26
  */
26
27
  export declare abstract class BaseItem<T extends Item> {
28
+ storageServices?: StorageServices;
27
29
  abstract readonly type: string;
28
30
  /**
29
31
  * Used for infer T
@@ -90,7 +92,7 @@ export declare abstract class BaseItem<T extends Item> {
90
92
  * @param req
91
93
  */
92
94
  abstract getAddTemplate(req: ReqType): Promise<{
93
- type: 'component' | 'navigation.group' | 'navigation.link' | 'model';
95
+ type: 'component' | 'navigation.group' | 'navigation.link' | 'model' | 'model.link';
94
96
  data: any;
95
97
  }>;
96
98
  /**
@@ -101,7 +103,7 @@ export declare abstract class BaseItem<T extends Item> {
101
103
  * @param modelId
102
104
  */
103
105
  abstract getEditTemplate(id: string | number, catalogId: string, req: ReqType, modelId?: string | number): Promise<{
104
- type: 'component' | 'navigation.group' | 'navigation.link' | 'model';
106
+ type: 'component' | 'navigation.group' | 'navigation.link' | 'model' | 'model.link';
105
107
  data: any;
106
108
  }>;
107
109
  _getChilds(parentId: string | number, catalogId: string, req?: ReqType): Promise<Item[]>;
@@ -230,7 +232,7 @@ export declare abstract class AbstractCatalog {
230
232
  * @param modelId
231
233
  */
232
234
  getEditTemplate(item: Item, id: string | number, req: ReqType, modelId?: string | number): Promise<{
233
- type: "component" | "navigation.group" | "navigation.link" | "model";
235
+ type: "component" | "navigation.group" | "navigation.link" | "model" | "model.link";
234
236
  data: any;
235
237
  }>;
236
238
  /**
@@ -239,7 +241,7 @@ export declare abstract class AbstractCatalog {
239
241
  * @param req
240
242
  */
241
243
  getAddTemplate(item: Item, req: ReqType): Promise<{
242
- type: "component" | "navigation.group" | "navigation.link" | "model";
244
+ type: "component" | "navigation.group" | "navigation.link" | "model" | "model.link";
243
245
  data: any;
244
246
  }>;
245
247
  addActionHandler(actionHandler: ActionHandler): void;
@@ -2,6 +2,7 @@
2
2
  * General Item structure that will be available for all elements, including groups
3
3
  */
4
4
  export class BaseItem {
5
+ storageServices;
5
6
  /**
6
7
  * Array of all global contexts, which will appear for all elements
7
8
  */
@@ -253,7 +254,7 @@ export class AbstractCatalog {
253
254
  * Method for getting group elements
254
255
  */
255
256
  getitemTypes() {
256
- return this.itemTypes.map(({ adminizer, ...rest }) => rest);
257
+ return this.itemTypes.map(({ adminizer, storageServices, ...rest }) => rest);
257
258
  }
258
259
  ;
259
260
  async search(s, hasExtras = true, req) {
@@ -268,7 +269,7 @@ export class AbstractCatalog {
268
269
  const extras = await this.getChilds(item.id, undefined, req);
269
270
  accumulator.push(...extras);
270
271
  }
271
- if (item.parentId === 0)
272
+ if (item.parentId === null)
272
273
  return item;
273
274
  const parentItem = await groupType._find(item.parentId, this.id);
274
275
  if (parentItem) {
@@ -284,7 +285,7 @@ export class AbstractCatalog {
284
285
  foundItems = foundItems.concat(items);
285
286
  }
286
287
  for (const item of foundItems) {
287
- if (item.parentId !== 0) { // changed from null to 0
288
+ if (item.parentId !== null) { // changed from 0 to null
288
289
  await buildTreeUpwards(item, hasExtras);
289
290
  }
290
291
  }
@@ -310,7 +311,7 @@ export class AbstractCatalog {
310
311
  itemMap[item.id] = item;
311
312
  });
312
313
  items.forEach(item => {
313
- if (item.parentId === 0) { // changed from null to 0
314
+ if (item.parentId === null) {
314
315
  tree.push(item);
315
316
  }
316
317
  else {
@@ -5,14 +5,15 @@ export interface NavItem extends Item {
5
5
  urlPath?: string;
6
6
  modelId?: string | number;
7
7
  targetBlank?: boolean;
8
+ visible?: boolean;
8
9
  }
9
- declare class StorageService {
10
+ export declare class StorageService {
10
11
  protected storageMap: Map<string | number, NavItem>;
11
12
  protected id: string;
12
13
  protected model: string;
13
14
  protected readonly adminizer: Adminizer;
14
15
  constructor(adminizer: Adminizer, id: string, model: string);
15
- protected initModel(): Promise<void>;
16
+ initModel(): Promise<void>;
16
17
  getId(): string;
17
18
  buildTree(): Promise<any>;
18
19
  populateFromTree(tree: any[]): Promise<void>;
@@ -26,10 +27,11 @@ declare class StorageService {
26
27
  search(s: string, type: string): Promise<NavItem[]>;
27
28
  }
28
29
  export declare class StorageServices {
29
- protected static storages: StorageService[];
30
- static add(storage: StorageService): void;
31
- static get(id: string): StorageService;
32
- static getAll(): StorageService[];
30
+ protected storages: StorageService[];
31
+ constructor();
32
+ add(storage: StorageService): void;
33
+ get(id: string): StorageService;
34
+ getAll(): StorageService[];
33
35
  }
34
36
  export declare class Navigation extends AbstractCatalog {
35
37
  readonly name: string;
@@ -37,7 +39,7 @@ export declare class Navigation extends AbstractCatalog {
37
39
  readonly icon: string;
38
40
  readonly actionHandlers: ActionHandler[];
39
41
  idList: string[];
42
+ storageServices: StorageServices;
40
43
  constructor(adminizer: Adminizer, config: NavigationConfig);
41
44
  getIdList(): Promise<string[]>;
42
45
  }
43
- export {};
@@ -1,7 +1,7 @@
1
- import { AbstractCatalog, AbstractGroup, AbstractItem } from "./AbstractCatalog";
1
+ import { AbstractCatalog, AbstractGroup, AbstractItem } from "./AbstractCatalog.js";
2
2
  import { v4 as uuid } from "uuid";
3
- import { Adminizer } from "../Adminizer";
4
- class StorageService {
3
+ import { Adminizer } from "../Adminizer.js";
4
+ export class StorageService {
5
5
  storageMap = new Map();
6
6
  id;
7
7
  model;
@@ -30,7 +30,7 @@ class StorageService {
30
30
  return this.id;
31
31
  }
32
32
  async buildTree() {
33
- const rootElements = await this.findElementsByParentId(0, null);
33
+ const rootElements = await this.findElementsByParentId(null, null);
34
34
  const buildSubTree = async (elements) => {
35
35
  const tree = [];
36
36
  for (const element of elements) {
@@ -56,9 +56,9 @@ class StorageService {
56
56
  return tree;
57
57
  }
58
58
  async populateFromTree(tree) {
59
- const traverseTree = async (node, parentId = 0) => {
59
+ const traverseTree = async (node, parentId = null) => {
60
60
  const { children, ...itemData } = node;
61
- const item = { ...itemData, parentId };
61
+ const item = { ...itemData, parentId: itemData.parentId === 0 ? null : itemData.parentId };
62
62
  await this.setElement(item.id, item, true);
63
63
  if (children && children.length > 0) {
64
64
  for (const child of children) {
@@ -109,6 +109,8 @@ class StorageService {
109
109
  async findElementsByParentId(parentId, type) {
110
110
  const elements = [];
111
111
  for (const item of this.storageMap.values()) {
112
+ if (parentId === 0)
113
+ parentId = null;
112
114
  if (type === null && item.parentId === parentId) {
113
115
  elements.push(item);
114
116
  continue;
@@ -138,14 +140,16 @@ class StorageService {
138
140
  }
139
141
  }
140
142
  export class StorageServices {
141
- static storages = [];
142
- static add(storage) {
143
+ storages = [];
144
+ constructor() {
145
+ }
146
+ add(storage) {
143
147
  this.storages.push(storage);
144
148
  }
145
- static get(id) {
149
+ get(id) {
146
150
  return this.storages.find(storage => storage.getId() === id);
147
151
  }
148
- static getAll() {
152
+ getAll() {
149
153
  return this.storages;
150
154
  }
151
155
  }
@@ -155,17 +159,21 @@ export class Navigation extends AbstractCatalog {
155
159
  icon = "box";
156
160
  actionHandlers = [];
157
161
  idList = [];
162
+ storageServices;
158
163
  constructor(adminizer, config) {
159
164
  let items = [];
165
+ const storageServices = new StorageServices();
160
166
  for (const configElement of config.items) {
161
- items.push(new NavigationItem(adminizer, configElement.title, configElement.model, config.model, configElement.urlPath));
167
+ items.push(new NavigationItem(adminizer, configElement.title, configElement.model, config.model, configElement.urlPath, storageServices));
162
168
  }
163
- items.push(new NavigationGroup(adminizer, config.groupField));
164
- items.push(new LinkItem(adminizer));
169
+ items.push(new NavigationGroup(adminizer, config.groupField, storageServices));
170
+ items.push(new LinkItem(adminizer, storageServices));
171
+ super(adminizer, items);
172
+ this.storageServices = storageServices;
173
+ adminizer.storageServices = storageServices;
165
174
  for (const section of config.sections) {
166
- StorageServices.add(new StorageService(adminizer, section, config.model));
175
+ this.storageServices.add(new StorageService(adminizer, section, config.model));
167
176
  }
168
- super(adminizer, items);
169
177
  this.movingGroupsRootOnly = config.movingGroupsRootOnly;
170
178
  this.idList = config.sections ?? [];
171
179
  }
@@ -183,7 +191,7 @@ class NavigationItem extends AbstractItem {
183
191
  actionHandlers = [];
184
192
  urlPath;
185
193
  adminizer;
186
- constructor(adminizer, name, model, navigationModel, urlPath) {
194
+ constructor(adminizer, name, model, navigationModel, urlPath, storageServices) {
187
195
  super();
188
196
  this.name = name;
189
197
  this.navigationModel = navigationModel;
@@ -193,9 +201,10 @@ class NavigationItem extends AbstractItem {
193
201
  let configModel = adminizer.config.models[this.model];
194
202
  this.icon = configModel?.icon ?? 'file_present';
195
203
  this.adminizer = adminizer;
204
+ this.storageServices = storageServices;
196
205
  }
197
206
  async create(data, catalogId) {
198
- let storage = StorageServices.get(catalogId);
207
+ let storage = this.storageServices.get(catalogId);
199
208
  let storageData = null;
200
209
  if (data._method === 'select') {
201
210
  // Direct call by model adapter
@@ -203,7 +212,8 @@ class NavigationItem extends AbstractItem {
203
212
  storageData = await this.dataPreparation({
204
213
  record: record,
205
214
  parentId: data.parentId,
206
- targetBlank: data.targetBlank
215
+ targetBlank: data.targetBlank,
216
+ visible: data.visible
207
217
  }, catalogId);
208
218
  }
209
219
  else {
@@ -212,13 +222,17 @@ class NavigationItem extends AbstractItem {
212
222
  return await storage.setElement(data.id, storageData);
213
223
  }
214
224
  async dataPreparation(data, catalogId, sortOrder) {
215
- let storage = StorageServices.get(catalogId);
225
+ let storage = this.storageServices.get(catalogId);
216
226
  let urlPath = eval('`' + this.urlPath + '`');
217
- let parentId = data.parentId ? data.parentId : 0; // changed from null to 0
227
+ let parentId = data.parentId ? data.parentId : null; // changed from 0 to null
228
+ if (parentId === 0)
229
+ parentId = null;
218
230
  return {
219
231
  id: uuid(),
220
232
  modelId: data.record.id,
221
233
  targetBlank: data.targetBlank ?? data.record.targetBlank,
234
+ visible: data.visible ?? data.record.visible,
235
+ isNavigation: true,
222
236
  name: data.record.name ?? data.record.title ?? data.record.id,
223
237
  parentId: parentId,
224
238
  sortOrder: sortOrder ?? (await storage.findElementsByParentId(parentId, null)).length,
@@ -228,7 +242,7 @@ class NavigationItem extends AbstractItem {
228
242
  };
229
243
  }
230
244
  async updateModelItems(modelId, data, catalogId) {
231
- let storage = StorageServices.get(catalogId);
245
+ let storage = this.storageServices.get(catalogId);
232
246
  let items = await storage.findElementByModelId(modelId);
233
247
  let urlPath = eval('`' + this.urlPath + '`');
234
248
  let response = [];
@@ -237,21 +251,22 @@ class NavigationItem extends AbstractItem {
237
251
  item.urlPath = urlPath;
238
252
  if (item.id === data.record.treeId) {
239
253
  item.targetBlank = data.record.targetBlank;
254
+ item.visible = data.record.visible;
240
255
  }
241
256
  response.push(await storage.setElement(item.id, item));
242
257
  }
243
258
  return response[0];
244
259
  }
245
260
  async update(itemId, data, catalogId) {
246
- let storage = StorageServices.get(catalogId);
261
+ let storage = this.storageServices.get(catalogId);
247
262
  return await storage.setElement(itemId, data);
248
263
  }
249
264
  async deleteItem(itemId, catalogId) {
250
- let storage = StorageServices.get(catalogId);
265
+ let storage = this.storageServices.get(catalogId);
251
266
  return await storage.removeElementById(itemId);
252
267
  }
253
268
  async find(itemId, catalogId) {
254
- let storage = StorageServices.get(catalogId);
269
+ let storage = this.storageServices.get(catalogId);
255
270
  return await storage.findElementById(itemId);
256
271
  }
257
272
  /**
@@ -259,7 +274,7 @@ class NavigationItem extends AbstractItem {
259
274
  * // TODO: need passing custom React module
260
275
  */
261
276
  async getAddTemplate(req) {
262
- let type = 'model';
277
+ let type = 'model.link';
263
278
  // Direct call by model adapter
264
279
  let itemsDB = await this.adminizer.modelHandler.model.get(this.model)["_find"]({});
265
280
  let items = itemsDB.map((item) => {
@@ -278,24 +293,25 @@ class NavigationItem extends AbstractItem {
278
293
  createTitle: `${req.i18n.__('create new')} ${req.i18n.__(this.name + 's')}`,
279
294
  OR: req.i18n.__('OR'),
280
295
  openInNewWindow: req.i18n.__('Open in a new window'),
296
+ visible: req.i18n.__('Visible')
281
297
  }
282
298
  }
283
299
  };
284
300
  }
285
301
  async getChilds(parentId, catalogId) {
286
- let storage = StorageServices.get(catalogId);
302
+ let storage = this.storageServices.get(catalogId);
287
303
  return await storage.findElementsByParentId(parentId, this.type);
288
304
  }
289
305
  async getEditTemplate(id, catalogId, req, modelId) {
290
306
  return Promise.resolve({
291
- type: 'model',
307
+ type: 'model.link',
292
308
  data: {
293
309
  item: await this.find(id, catalogId)
294
310
  }
295
311
  });
296
312
  }
297
313
  async search(s, catalogId) {
298
- let storage = StorageServices.get(catalogId);
314
+ let storage = this.storageServices.get(catalogId);
299
315
  return await storage.search(s, this.type);
300
316
  }
301
317
  }
@@ -304,13 +320,14 @@ class NavigationGroup extends AbstractGroup {
304
320
  name = "Group";
305
321
  groupField;
306
322
  adminizer;
307
- constructor(adminizer, groupField) {
323
+ constructor(adminizer, groupField, storageServices) {
308
324
  super();
309
325
  this.groupField = groupField;
310
326
  this.adminizer = adminizer;
327
+ this.storageServices = storageServices;
311
328
  }
312
329
  async create(data, catalogId) {
313
- let storage = StorageServices.get(catalogId);
330
+ let storage = this.storageServices.get(catalogId);
314
331
  let storageData = await this.dataPreparation(data, catalogId);
315
332
  delete data.name;
316
333
  delete data.parentId;
@@ -318,12 +335,16 @@ class NavigationGroup extends AbstractGroup {
318
335
  return await storage.setElement(storageData.id, storageData);
319
336
  }
320
337
  async dataPreparation(data, catalogId, sortOrder) {
321
- let storage = StorageServices.get(catalogId);
322
- let parentId = data.parentId ? data.parentId : 0; // changed from null to 0
338
+ let storage = this.storageServices.get(catalogId);
339
+ let parentId = data.parentId ? data.parentId : null; // changed from 0 to null
340
+ if (parentId === 0)
341
+ parentId = null;
323
342
  return {
324
343
  id: uuid(),
325
344
  name: data.name,
326
345
  targetBlank: data.targetBlank,
346
+ visible: data.visible,
347
+ isNavigation: true,
327
348
  parentId: parentId,
328
349
  sortOrder: sortOrder ?? (await storage.findElementsByParentId(parentId, null)).length,
329
350
  icon: this.icon,
@@ -331,19 +352,19 @@ class NavigationGroup extends AbstractGroup {
331
352
  };
332
353
  }
333
354
  async deleteItem(itemId, catalogId) {
334
- let storage = StorageServices.get(catalogId);
355
+ let storage = this.storageServices.get(catalogId);
335
356
  return await storage.removeElementById(itemId);
336
357
  }
337
358
  async find(itemId, catalogId) {
338
- let storage = StorageServices.get(catalogId);
359
+ let storage = this.storageServices.get(catalogId);
339
360
  return await storage.findElementById(itemId);
340
361
  }
341
362
  async update(itemId, data, catalogId) {
342
- let storage = StorageServices.get(catalogId);
363
+ let storage = this.storageServices.get(catalogId);
343
364
  return await storage.setElement(itemId, data);
344
365
  }
345
366
  async updateModelItems(modelId, data, catalogId) {
346
- let storage = StorageServices.get(catalogId);
367
+ let storage = this.storageServices.get(catalogId);
347
368
  return await storage.setElement(modelId, data);
348
369
  }
349
370
  getAddTemplate(req) {
@@ -353,6 +374,7 @@ class NavigationGroup extends AbstractGroup {
353
374
  resItems = this.groupField.map((field) => {
354
375
  return {
355
376
  name: field.name,
377
+ label: field.label,
356
378
  required: field.required
357
379
  };
358
380
  });
@@ -363,6 +385,7 @@ class NavigationGroup extends AbstractGroup {
363
385
  items: resItems,
364
386
  labels: {
365
387
  openInNewWindow: req.i18n.__('Open in a new window'),
388
+ visible: req.i18n.__('Visible'),
366
389
  title: req.i18n.__('Title'),
367
390
  save: req.i18n.__('Save')
368
391
  }
@@ -377,6 +400,7 @@ class NavigationGroup extends AbstractGroup {
377
400
  resItems = this.groupField.map((field) => {
378
401
  return {
379
402
  name: field.name,
403
+ label: field.label,
380
404
  required: field.required
381
405
  };
382
406
  });
@@ -388,6 +412,7 @@ class NavigationGroup extends AbstractGroup {
388
412
  item: item,
389
413
  labels: {
390
414
  openInNewWindow: req.i18n.__('Open in a new window'),
415
+ visible: req.i18n.__('Visible'),
391
416
  title: req.i18n.__('Title'),
392
417
  save: req.i18n.__('Save')
393
418
  }
@@ -395,11 +420,11 @@ class NavigationGroup extends AbstractGroup {
395
420
  });
396
421
  }
397
422
  async getChilds(parentId, catalogId) {
398
- let storage = StorageServices.get(catalogId);
423
+ let storage = this.storageServices.get(catalogId);
399
424
  return await storage.findElementsByParentId(parentId, this.type);
400
425
  }
401
426
  async search(s, catalogId) {
402
- let storage = StorageServices.get(catalogId);
427
+ let storage = this.storageServices.get(catalogId);
403
428
  return await storage.search(s, this.type);
404
429
  }
405
430
  }
@@ -409,14 +434,15 @@ class LinkItem extends NavigationGroup {
409
434
  name = 'Link';
410
435
  type = 'link';
411
436
  isGroup = false;
412
- constructor(adminizer) {
413
- super(adminizer, []);
437
+ constructor(adminizer, storageServices) {
438
+ super(adminizer, [], storageServices);
414
439
  }
415
440
  getAddTemplate(req) {
416
441
  let type = 'navigation.link';
417
442
  let resItems = [
418
443
  {
419
- name: req.i18n.__('Link'),
444
+ label: req.i18n.__('Link'),
445
+ name: "link",
420
446
  required: true
421
447
  }
422
448
  ];
@@ -427,6 +453,7 @@ class LinkItem extends NavigationGroup {
427
453
  labels: {
428
454
  title: req.i18n.__('Title'),
429
455
  openInNewWindow: req.i18n.__('Open in a new window'),
456
+ visible: req.i18n.__('Visible'),
430
457
  save: req.i18n.__('Save')
431
458
  }
432
459
  }
@@ -437,7 +464,8 @@ class LinkItem extends NavigationGroup {
437
464
  let type = 'navigation.group';
438
465
  let resItems = [
439
466
  {
440
- name: req.i18n.__('Link'),
467
+ label: req.i18n.__('Link'),
468
+ name: 'link',
441
469
  required: true
442
470
  }
443
471
  ];
@@ -448,6 +476,7 @@ class LinkItem extends NavigationGroup {
448
476
  item: item,
449
477
  labels: {
450
478
  openInNewWindow: req.i18n.__('Open in a new window'),
479
+ visible: req.i18n.__('Visible'),
451
480
  title: req.i18n.__('Title'),
452
481
  save: req.i18n.__('Save')
453
482
  }
@@ -1,4 +1,4 @@
1
- import { AbstractControls } from "../AbstractControls";
1
+ import { AbstractControls } from "../AbstractControls.js";
2
2
  export class MonacoEditor extends AbstractControls {
3
3
  config = {
4
4
  language: "javascript",
@@ -1,4 +1,4 @@
1
- import { AbstractControls } from "../AbstractControls";
1
+ import { AbstractControls } from "../AbstractControls.js";
2
2
  export class GeoEditor extends AbstractControls {
3
3
  config = {
4
4
  mode: "all"
@@ -1,4 +1,4 @@
1
- import { AbstractControls } from "../AbstractControls";
1
+ import { AbstractControls } from "../AbstractControls.js";
2
2
  export class JsonEditor extends AbstractControls {
3
3
  config = {};
4
4
  name = 'jsoneditor';
@@ -1,4 +1,4 @@
1
- import { AbstractControls } from "../AbstractControls";
1
+ import { AbstractControls } from "../AbstractControls.js";
2
2
  export class ToastUiEditor extends AbstractControls {
3
3
  config = {
4
4
  hideModeSwitch: true,
@@ -1,4 +1,4 @@
1
- import { AbstractControls } from "../AbstractControls";
1
+ import { AbstractControls } from "../AbstractControls.js";
2
2
  export class Handsontable extends AbstractControls {
3
3
  config = {
4
4
  rowHeaders: true,
@@ -1,4 +1,4 @@
1
- import { AbstractControls } from "../AbstractControls";
1
+ import { AbstractControls } from "../AbstractControls.js";
2
2
  export class CKeditor extends AbstractControls {
3
3
  name = 'ckeditor';
4
4
  type = 'wysiwyg';
@@ -11,19 +11,24 @@ const inertiaExpressAdapter = function ({ version, html, flashMessages, enableRe
11
11
  }) {
12
12
  return (req, res, next) => {
13
13
  if (csrf.enabled) {
14
- const csrfToken = randomBytes(32).toString('hex');
15
- res.cookie('XSRF-TOKEN', csrfToken, {
16
- httpOnly: false,
17
- secure: process.env.NODE_ENV === 'production' && process.env.CSRF_COOKIE_INSECURE !== '1',
18
- sameSite: 'lax',
19
- });
20
- // Check CSRF token for non-GET requests
21
- if (!['GET', 'HEAD', 'OPTIONS'].includes(req.method)) {
22
- const csrfCookie = req.cookies['XSRF-TOKEN'];
23
- const csrfHeader = req.headers[csrf.headerName || 'x-xsrf-token'];
24
- if (!csrfCookie || !csrfHeader || csrfCookie !== csrfHeader) {
25
- res.status(403).send({ message: 'Invalid CSRF token' });
26
- return;
14
+ const isApiRoute = isApiRequest(req);
15
+ if (!isApiRoute) {
16
+ const csrfToken = randomBytes(32).toString('hex');
17
+ res.cookie('XSRF-TOKEN', csrfToken, {
18
+ httpOnly: false,
19
+ secure: process.env.NODE_ENV === 'production' && process.env.CSRF_COOKIE_INSECURE !== '1',
20
+ sameSite: 'lax',
21
+ });
22
+ // Проверяем CSRF только для не-GET запросов И не-API routes
23
+ if (!['GET', 'HEAD', 'OPTIONS'].includes(req.method)) {
24
+ const csrfCookie = req.cookies['XSRF-TOKEN'];
25
+ const csrfHeader = req.headers[csrf.headerName || 'x-xsrf-token'];
26
+ if (!csrfCookie || !csrfHeader || csrfCookie !== csrfHeader) {
27
+ return res.status(403).json({
28
+ message: 'Invalid CSRF token',
29
+ type: 'csrf_error'
30
+ });
31
+ }
27
32
  }
28
33
  }
29
34
  }
@@ -129,4 +134,17 @@ const inertiaExpressAdapter = function ({ version, html, flashMessages, enableRe
129
134
  return next();
130
135
  };
131
136
  };
137
+ // Вспомогательная функция для определения API routes
138
+ function isApiRequest(req) {
139
+ const adminizer = req.adminizer;
140
+ if (!adminizer?.config?.cors?.enabled) {
141
+ return false;
142
+ }
143
+ const corsConfig = adminizer.config.cors;
144
+ const routePrefix = adminizer.config.routePrefix || '';
145
+ // Создаем базовый путь для API
146
+ const apiBasePath = `${routePrefix}/${corsConfig.path?.replace('*', '')}`;
147
+ // Проверяем начинается ли путь с API base path
148
+ return req.path.startsWith(apiBasePath);
149
+ }
132
150
  export default inertiaExpressAdapter;
@@ -36,8 +36,10 @@ export interface MediaManagerWidgetClientItem extends MediaManagerWidgetItem {
36
36
  url?: string;
37
37
  }
38
38
  export interface MediaManagerWidgetJSON {
39
- list: MediaManagerWidgetItem[];
40
39
  mediaManagerId: string;
40
+ model: string;
41
+ widgetName: string;
42
+ modelId: string | number;
41
43
  }
42
44
  export interface MediaManagerWidgetData {
43
45
  id: string;
@@ -207,8 +209,8 @@ export declare abstract class AbstractMediaManager {
207
209
  /**
208
210
  * widget Id in the model in which the mediafile was added
209
211
  */
210
- modelId: string, widgetName: string): Promise<void>;
211
- abstract getItemsList(items: MediaManagerWidgetItem[]): Promise<MediaManagerWidgetClientItem[]>;
212
+ modelId: number, widgetName: string): Promise<void>;
213
+ abstract getRelations(model: string, widgetName: string, modelId: string | number): Promise<MediaManagerWidgetClientItem[]>;
212
214
  /**
213
215
  * Search all items.
214
216
  * If not this.allowSearch = true then it will not come here
@@ -1,4 +1,4 @@
1
- import { AbstractMediaManager, MediaManagerItem, File, MediaManagerWidgetItem, MediaManagerWidgetData, MediaManagerWidgetClientItem, SortCriteria } from "./AbstractMediaManager";
1
+ import { AbstractMediaManager, MediaManagerItem, File, MediaManagerWidgetData, MediaManagerWidgetClientItem, SortCriteria } from "./AbstractMediaManager";
2
2
  import { Adminizer } from "../Adminizer";
3
3
  export declare class DefaultMediaManager extends AbstractMediaManager {
4
4
  readonly itemTypes: File<MediaManagerItem>[];
@@ -12,6 +12,6 @@ export declare class DefaultMediaManager extends AbstractMediaManager {
12
12
  next: boolean;
13
13
  }>;
14
14
  searchAll(s: string, group: string): Promise<MediaManagerItem[]>;
15
- setRelations(data: MediaManagerWidgetData[], model: string, modelId: string, widgetName: string): Promise<void>;
16
- getItemsList(items: MediaManagerWidgetItem[]): Promise<MediaManagerWidgetClientItem[]>;
15
+ setRelations(data: MediaManagerWidgetData[], model: string, modelId: number, widgetName: string): Promise<void>;
16
+ getRelations(model: string, widgetName: string, modelId: string | number): Promise<MediaManagerWidgetClientItem[]>;
17
17
  }