adminizer 4.1.0-commit.ad1476a → 4.1.0-commit.d8a06d3

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 (173) hide show
  1. package/assets/{VanillaJSONEditor-FUe77pIA.js → VanillaJSONEditor-D-Lx670g.js} +1 -1
  2. package/assets/add-BP_u3Tjl.js +1 -0
  3. package/assets/add-form-nffmiYTh.js +1 -0
  4. package/assets/add-group-D4vcHlm-.js +1 -0
  5. package/assets/{add-group-form-dzadPSfL.js → add-group-form-gNJW11-q.js} +1 -1
  6. package/assets/add-user-DWh3Nas0.js +1 -0
  7. package/assets/add-user-form-BJ0FsZYJ.js +1 -0
  8. package/assets/{app-DMmad2-f.css → app-WTooYWC3.css} +1 -1
  9. package/assets/{app-layout-D1m9Kvxq.js → app-layout-DYsRFUuP.js} +1 -1
  10. package/assets/{app-shell-BWMRMkHM.js → app-shell-Dd9Eknik.js} +1 -1
  11. package/assets/app-sidebar-BOmu6-Sl.js +1 -0
  12. package/assets/{app-sidebar-header-DLAFi13E.js → app-sidebar-header-CoXSzWxk.js} +1 -1
  13. package/assets/app.js +2 -2
  14. package/assets/{breadcrumbs-CQNon4Vl.js → breadcrumbs-BmAq4fHT.js} +1 -1
  15. package/assets/{button-CQ9t1kLz.js → button-C9B_5Jf_.js} +1 -1
  16. package/assets/{checkbox-W0nGAXIj.js → checkbox-Fg27sL_1.js} +1 -1
  17. package/assets/{compiler-runtime-tM4jBQ-T.js → compiler-runtime-hB6dAw2d.js} +1 -1
  18. package/assets/dashboard-BACj996r.js +3 -0
  19. package/assets/dashboard-BOltB2Hq.css +1 -0
  20. package/assets/{date-picker-B__dVVqj.js → date-picker-DI1cCO7K.js} +1 -1
  21. package/assets/{dropdown-menu-SEBnEIiL.js → dropdown-menu-Bhj17ENm.js} +1 -1
  22. package/assets/{field-renderer-CapylJU9.js → field-renderer-DVHZF6HS.js} +3 -3
  23. package/assets/form-BgWdwvz1.js +1 -0
  24. package/assets/form-DgtErfln.js +1 -0
  25. package/assets/{geo-json-CwteYDGB.js → geo-json-BjiyTtMu.js} +1 -1
  26. package/assets/{handsontable-BCnjOpBr.js → handsontable-4mjU_b0n.js} +1 -1
  27. package/assets/home-CHntBHJa.js +2 -0
  28. package/assets/{icon-Bz9BMaD0.js → icon-Dt0vBgDO.js} +1 -1
  29. package/assets/index-B8BS9wMC.js +1 -0
  30. package/assets/{index-DEk3sC8d.js → index-BKCgnGj_.js} +1 -1
  31. package/assets/{index-C0SL3SHw.js → index-BykbU6Ee.js} +1 -1
  32. package/assets/index-CaJgc5EZ.js +1 -0
  33. package/assets/{index-BcE9FUM6.js → index-Cgp8OfuI.js} +1 -1
  34. package/assets/{index-DTRTjOmh.js → index-Cw5o84pO.js} +1 -1
  35. package/assets/{init-user-D9mW-g14.js → init-user-JfCKJ5Ce.js} +1 -1
  36. package/assets/{input-DF7Ue23C.js → input-CvRbIbk4.js} +1 -1
  37. package/assets/{input-error-BBygona6.js → input-error-DMK7cAt7.js} +1 -1
  38. package/assets/{label-Z506NKsW.js → label-CSLFe9Bz.js} +1 -1
  39. package/assets/list-B2Oa5O_Q.js +1 -0
  40. package/assets/{list-table-DB1sEQLF.js → list-table-DA9MhywL.js} +5 -5
  41. package/assets/{login-DrGaTWhY.js → login-DQwGtdis.js} +1 -1
  42. package/assets/manifest.json +491 -470
  43. package/assets/{material-icon-CItZiB53.js → material-icon-BJg8o_fs.js} +1 -1
  44. package/assets/module-DWXp59Vg.js +1 -0
  45. package/assets/{monaco-editor-DqAqwxw4.js → monaco-editor-CJs0_GlD.js} +1 -1
  46. package/assets/{multi-select-oabtVhUP.js → multi-select-BvRpAW8r.js} +1 -1
  47. package/assets/{nav-footer-CM-yHiRs.js → nav-footer-Bs4dmN1d.js} +1 -1
  48. package/assets/{nav-main-Q3xofGRT.js → nav-main-Bq3IMk4C.js} +1 -1
  49. package/assets/{nav-user-Ds8i0Pa2.js → nav-user-CbB22J5O.js} +1 -1
  50. package/assets/{pagination-render-B57pOpFy.js → pagination-render-DuXDDbC_.js} +1 -1
  51. package/assets/{popover-I249Gg2O.js → popover-DtoGI2b1.js} +1 -1
  52. package/assets/{register-C9FQIDtS.js → register-BSogVF0h.js} +1 -1
  53. package/assets/{select-D1N8zRPY.js → select-BWepUw-9.js} +1 -1
  54. package/assets/{sidebar-4D-sX2l4.js → sidebar-CAHsHdjM.js} +2 -2
  55. package/assets/skeleton-COOcAA8f.js +1 -0
  56. package/assets/{sonner-Dzckw3U3.js → sonner-BI0IFOQN.js} +1 -1
  57. package/assets/{toast-editor-FbrFd1ft.js → toast-editor-CMK7QtF1.js} +1 -1
  58. package/assets/{tooltip-D2ehgLlB.js → tooltip-DHwpLKOI.js} +1 -1
  59. package/assets/{use-appearance-Co6mO0dV.js → use-appearance-DRfIqTgw.js} +1 -1
  60. package/assets/{use-window-size-B8l6Bpkf.js → use-window-size-h0Sh_NvX.js} +1 -1
  61. package/assets/{user-info-DBYoAJYJ.js → user-info-DFrmpJ4y.js} +1 -1
  62. package/assets/{user-menu-content-qkvdkUVd.js → user-menu-content-DPXQdERj.js} +1 -1
  63. package/assets/welcome-B4WCIXKf.js +1 -0
  64. package/controllers/add.js +2 -2
  65. package/controllers/addGroup.js +2 -4
  66. package/controllers/addUser.js +4 -6
  67. package/controllers/catalog/Catalog.js +2 -2
  68. package/controllers/catalog/FrontentCatalogAdapter.js +1 -2
  69. package/controllers/ckeditorUpload.js +2 -3
  70. package/controllers/dashboard.js +16 -2
  71. package/controllers/edit.js +2 -3
  72. package/controllers/editGroup.js +2 -4
  73. package/controllers/editUser.js +3 -5
  74. package/controllers/form.js +2 -3
  75. package/controllers/getAllWidgets.js +3 -3
  76. package/controllers/initUser.js +1 -2
  77. package/controllers/list.js +4 -4
  78. package/controllers/login.js +31 -15
  79. package/controllers/media-manager/mediaManagerAdapter.js +1 -2
  80. package/controllers/media-manager/mediaManagerApi.js +2 -2
  81. package/controllers/navigation/edit.js +1 -1
  82. package/controllers/processInstallFinalize.js +2 -2
  83. package/controllers/processInstallStep.d.ts +0 -1
  84. package/controllers/processInstallStep.js +122 -132
  85. package/controllers/register.js +1 -4
  86. package/controllers/remove.js +2 -2
  87. package/controllers/timezones.js +1 -1
  88. package/controllers/view.js +2 -2
  89. package/controllers/welcome.js +1 -1
  90. package/controllers/widgets/Action.js +2 -2
  91. package/controllers/widgets/Custom.js +2 -2
  92. package/controllers/widgets/Info.js +2 -2
  93. package/controllers/widgets/switch.js +2 -2
  94. package/controllers/widgetsDB.js +5 -5
  95. package/helpers/accessRightsHelper.d.ts +3 -2
  96. package/helpers/accessRightsHelper.js +1 -1
  97. package/helpers/configHelper.js +2 -1
  98. package/helpers/fieldsHelper.d.ts +1 -1
  99. package/helpers/inertiaActionsHelper.js +1 -1
  100. package/helpers/inertiaAddHelper.d.ts +1 -1
  101. package/helpers/inertiaAddHelper.js +2 -0
  102. package/helpers/inertiaFromHelper.js +2 -0
  103. package/helpers/inertiaGroupHelper.d.ts +4 -2
  104. package/helpers/inertiaGroupHelper.js +1 -1
  105. package/helpers/inertiaListHelper.js +5 -5
  106. package/helpers/inertiaMenuHelper.js +1 -1
  107. package/helpers/inertiaUserHelper.d.ts +7 -1
  108. package/helpers/inertiaUserHelper.js +5 -1
  109. package/index.d.ts +7 -0
  110. package/index.js +7 -0
  111. package/interfaces/adminpanelConfig.d.ts +6 -2
  112. package/interfaces/global.d.ts +5 -26
  113. package/lib/Adminizer.d.ts +2 -0
  114. package/lib/Adminizer.js +17 -1
  115. package/lib/catalog/AbstractCatalog.js +0 -1
  116. package/lib/catalog/Navigation.js +6 -6
  117. package/lib/datatable/NodeTable.js +0 -3
  118. package/lib/inertia/inertiaAdapter.js +0 -1
  119. package/lib/installStepper/installStepper.js +5 -5
  120. package/lib/media-manager/AbstractMediaManager.d.ts +2 -2
  121. package/lib/media-manager/AbstractMediaManager.js +1 -1
  122. package/lib/v4/DataAccessor.d.ts +2 -1
  123. package/lib/v4/DataAccessor.js +2 -2
  124. package/lib/v4/POWCaptcha.js +0 -1
  125. package/lib/v4/PolicyManager.js +0 -1
  126. package/lib/v4/helper/jwt.d.ts +10 -0
  127. package/lib/v4/helper/jwt.js +18 -0
  128. package/lib/v4/model/AbstractModel.js +0 -2
  129. package/lib/v4/model/ModelHandler.js +0 -1
  130. package/lib/v4/model/adapter/sequelize.d.ts +3 -2
  131. package/lib/v4/model/adapter/sequelize.js +250 -58
  132. package/lib/v4/model/adapter/waterline.js +0 -1
  133. package/lib/widgets/abstractAction.d.ts +1 -1
  134. package/lib/widgets/abstractCustom.d.ts +27 -12
  135. package/lib/widgets/abstractCustom.js +8 -2
  136. package/lib/widgets/abstractInfo.d.ts +1 -1
  137. package/lib/widgets/abstractInfo.js +1 -1
  138. package/lib/widgets/abstractLink.d.ts +1 -0
  139. package/lib/widgets/abstractSwitch.d.ts +1 -1
  140. package/lib/widgets/abstractWidgetBase.d.ts +1 -1
  141. package/lib/widgets/widgetHandler.d.ts +20 -3
  142. package/lib/widgets/widgetHandler.js +25 -25
  143. package/models/GroupAP.d.ts +8 -0
  144. package/models/MediaManagerAP.d.ts +16 -0
  145. package/models/MediaManagerAssociationsAP.d.ts +10 -0
  146. package/models/MediaManagerMetaAP.d.ts +8 -0
  147. package/models/NavigationAP.d.ts +5 -0
  148. package/models/UserAP.d.ts +25 -2
  149. package/models/UserAP.js +2 -2
  150. package/package.json +17 -10
  151. package/policies/checkAuth.js +4 -3
  152. package/policies/setLocale.js +2 -2
  153. package/system/Router.js +14 -14
  154. package/system/bindAuthorization.js +4 -5
  155. package/system/bindInertia.js +9 -9
  156. package/system/bindInstallStepper.js +1 -1
  157. package/system/bindReqFunctions.js +16 -0
  158. package/translations/ru.json +17 -8
  159. package/assets/add-ZITr43GJ.js +0 -1
  160. package/assets/add-form-CYOfr0Ef.js +0 -1
  161. package/assets/add-group-B332wN8K.js +0 -1
  162. package/assets/add-user-TC-mYdsB.js +0 -1
  163. package/assets/add-user-form-y2f_1_lM.js +0 -1
  164. package/assets/app-sidebar-BCtaEFGb.js +0 -1
  165. package/assets/dashboard-BR602KhL.js +0 -1
  166. package/assets/form-DOUNk3o2.js +0 -1
  167. package/assets/form-lOKv4Qbw.js +0 -1
  168. package/assets/home-Ch6QfTIt.js +0 -2
  169. package/assets/index-Cdb9ACvz.js +0 -1
  170. package/assets/index-K81GbF6O.js +0 -1
  171. package/assets/list-Qyd7ecQH.js +0 -1
  172. package/assets/module-DBaykv8l.js +0 -1
  173. package/assets/welcome-D2adQ8EU.js +0 -1
@@ -3,53 +3,110 @@ import { AbstractAdapter, AbstractModel } from "../AbstractModel";
3
3
  import path from "path";
4
4
  import fs from "fs";
5
5
  import { pathToFileURL } from "url";
6
- function mapSequelizeAttributesToAbstract(attrs) {
6
+ function resolveType(type) {
7
+ const sqlType = typeof type.toString === "function"
8
+ ? type.toString().toLowerCase()
9
+ : "";
10
+ if (sqlType.includes("string") || sqlType.includes("uuid"))
11
+ return "string";
12
+ if (sqlType.includes("int") || sqlType.includes("float") || sqlType.includes("decimal"))
13
+ return "number";
14
+ if (sqlType.includes("bool"))
15
+ return "boolean";
16
+ if (sqlType.includes("json"))
17
+ return "json";
18
+ if (sqlType.includes("date"))
19
+ return "string";
20
+ return "ref";
21
+ }
22
+ export function mapSequelizeToWaterline(model) {
7
23
  const result = {};
8
- for (const key in attrs) {
9
- const attr = attrs[key];
10
- const resolvedType = resolveType(attr.type);
11
- result[key] = {
12
- type: resolvedType,
13
- required: !attr.allowNull,
14
- primaryKey: !!attr.primaryKey,
15
- unique: !!attr.unique,
24
+ const rawAttrs = model.getAttributes();
25
+ for (const name in rawAttrs) {
26
+ const meta = rawAttrs[name];
27
+ result[name] = {
28
+ type: resolveType(meta.type),
29
+ required: meta.allowNull !== undefined ? !meta.allowNull : false,
30
+ allowNull: meta.allowNull,
31
+ unique: !!meta.unique,
32
+ defaultsTo: meta.defaultValue,
33
+ columnName: meta.field || name,
16
34
  };
17
35
  }
18
- return result;
19
- }
20
- function resolveType(type) {
21
- try {
22
- const sqlType = typeof type.toString === "function"
23
- ? type.toString().toLowerCase()
24
- : "";
25
- if (sqlType.includes("string"))
26
- return "string";
27
- if (sqlType.includes("uuid"))
28
- return "string";
29
- if (sqlType.includes("int") || sqlType.includes("float") || sqlType.includes("decimal"))
30
- return "number";
31
- if (sqlType.includes("bool"))
32
- return "boolean";
33
- if (sqlType.includes("json"))
34
- return "json";
35
- if (sqlType.includes("date"))
36
- return "string"; // 👈 фикс: дата как строка
37
- return "ref";
38
- }
39
- catch {
40
- return "ref";
36
+ for (const alias in model.associations) {
37
+ const assoc = model.associations[alias];
38
+ switch (assoc.associationType) {
39
+ case "BelongsTo": {
40
+ const a = assoc;
41
+ result[alias] = {
42
+ type: "association",
43
+ model: a.target.name.toLowerCase(),
44
+ via: a.foreignKey,
45
+ };
46
+ break;
47
+ }
48
+ case "HasOne": {
49
+ const a = assoc;
50
+ result[alias] = {
51
+ type: "association",
52
+ model: a.target.name.toLowerCase(),
53
+ via: a.foreignKey,
54
+ };
55
+ break;
56
+ }
57
+ case "HasMany": {
58
+ const a = assoc;
59
+ result[alias] = {
60
+ type: "association-many",
61
+ collection: a.target.name.toLowerCase(),
62
+ via: a.foreignKey,
63
+ };
64
+ break;
65
+ }
66
+ case "BelongsToMany": {
67
+ const a = assoc;
68
+ result[alias] = {
69
+ type: "association-many",
70
+ collection: a.target.name.toLowerCase(),
71
+ via: a.otherKey,
72
+ };
73
+ break;
74
+ }
75
+ default:
76
+ break;
77
+ }
41
78
  }
79
+ return result;
42
80
  }
81
+ // function resolveType(type: any): AbstractFieldType {
82
+ // try {
83
+ // const sqlType = typeof type.toString === "function"
84
+ // ? type.toString().toLowerCase()
85
+ // : "";
86
+ // if (sqlType.includes("string")) return "string";
87
+ // if (sqlType.includes("uuid")) return "string";
88
+ // if (sqlType.includes("int") || sqlType.includes("float") || sqlType.includes("decimal")) return "number";
89
+ // if (sqlType.includes("bool")) return "boolean";
90
+ // if (sqlType.includes("json")) return "json";
91
+ // if (sqlType.includes("date")) return "string";
92
+ // return "ref";
93
+ // } catch {
94
+ // return "ref";
95
+ // }
96
+ // }
43
97
  /** SequelizeModel — реализация модели, совместимая с AbstractModel */
98
+ function capitalize(str) {
99
+ return str.charAt(0).toUpperCase() + str.slice(1);
100
+ }
44
101
  function convertCriteriaToSequelize(criteria) {
45
- console.log("waterline criteria", criteria);
102
+ // console.debug("waterline criteria", criteria)
46
103
  const result = {};
47
104
  for (const key in criteria) {
48
105
  const value = criteria[key];
49
106
  if (value === undefined ||
50
107
  value === null ||
51
108
  (typeof value === "object" && Object.keys(value).length === 0)) {
52
- continue; // ⛔ пропускаем пустые условия
109
+ continue;
53
110
  }
54
111
  if (typeof value === "object" && !Array.isArray(value)) {
55
112
  const operatorEntries = Object.entries(value)
@@ -80,7 +137,32 @@ function convertCriteriaToSequelize(criteria) {
80
137
  return result;
81
138
  }
82
139
  function convertWaterlineCriteriaToSequelizeOptions(criteria) {
83
- console.log("WATERLINE CRITERIA", criteria);
140
+ // console.debug("WATERLINE CRITERIA (raw):", criteria);
141
+ const { where: nestedWhere, skip, limit, sort, ...rest } = criteria;
142
+ const rawWhere = (nestedWhere && Object.keys(nestedWhere).length > 0)
143
+ ? nestedWhere
144
+ : rest;
145
+ // console.debug("WATERLINE CRITERIA: using rawWhere =", rawWhere);
146
+ const where = convertCriteriaToSequelize(rawWhere);
147
+ // console.debug("convertCriteriaToSequelize →", where);
148
+ const result = { where };
149
+ if (typeof skip === "number") {
150
+ result.offset = skip;
151
+ // console.debug("→ offset =", skip);
152
+ }
153
+ if (typeof limit === "number") {
154
+ result.limit = limit;
155
+ // console.debug("→ limit =", limit);
156
+ }
157
+ if (typeof sort === "string") {
158
+ const [field, dir] = sort.trim().split(/\s+/);
159
+ result.order = [[field, dir?.toUpperCase() === "DESC" ? "DESC" : "ASC"]];
160
+ // console.debug("→ order =", result.order);
161
+ }
162
+ return result;
163
+ }
164
+ function convertWaterlineCriteriaToSequelizeOptions____OLD(criteria) {
165
+ // console.debug("WATERLINE CRITERIA", criteria)
84
166
  const { where = {}, skip, limit, sort } = criteria;
85
167
  const result = {
86
168
  where: convertCriteriaToSequelize(where),
@@ -100,40 +182,150 @@ function convertWaterlineCriteriaToSequelizeOptions(criteria) {
100
182
  export class SequelizeModel extends AbstractModel {
101
183
  model;
102
184
  constructor(modelName, model) {
103
- super(modelName, mapSequelizeAttributesToAbstract(model.getAttributes()), model.primaryKeyAttribute, model.name);
185
+ super(modelName, mapSequelizeToWaterline(model), model.primaryKeyAttribute, model.name);
104
186
  this.model = model;
105
187
  }
106
188
  // --- CREATE ---
107
189
  async _create(data) {
108
- const created = await this.model.create(data);
109
- const result = await this.model.findByPk(created.get(this.primaryKey), { raw: true });
110
- return result;
190
+ // console.clear()
191
+ const assocNames = Object.keys(this.model.associations);
192
+ const plainData = {};
193
+ const assocData = {};
194
+ // console.debug(">> _create: входные данные:", data);
195
+ // console.debug(">> Доступные ассоциации:", assocNames);
196
+ for (const [key, val] of Object.entries(data)) {
197
+ if (assocNames.includes(key)) {
198
+ assocData[key] = val;
199
+ }
200
+ else {
201
+ plainData[key] = val;
202
+ }
203
+ }
204
+ // console.debug(">> Обычные поля для create():", plainData);
205
+ // console.debug(">> Данные ассоциаций:", assocData);
206
+ let instance;
207
+ try {
208
+ instance = await this.model.create(plainData);
209
+ // console.debug(">> Создан экземпляр (без ассоциаций):", instance.toJSON());
210
+ }
211
+ catch (err) {
212
+ // console.error("!! Ошибка при create(plainData):", err);
213
+ throw err;
214
+ }
215
+ // assocData = { example: 5, userAPs: [1,2,3], category: 7, tags: [11,22] }
216
+ // this.model.associations — ваш объект ассоциаций
217
+ for (const [alias, ids] of Object.entries(assocData)) {
218
+ const assoc = this.model.associations[alias];
219
+ if (!assoc) {
220
+ // console.warn(`Association "${alias}" not defined on model`);
221
+ continue;
222
+ }
223
+ // @ts-ignore accessors is present
224
+ const { set: setAccessor, add: addAccessor } = assoc.accessors;
225
+ if (Array.isArray(ids)) {
226
+ if (typeof instance[setAccessor] === 'function') {
227
+ await instance[setAccessor](ids);
228
+ continue;
229
+ }
230
+ if (typeof instance[addAccessor] === 'function') {
231
+ for (const id of ids) {
232
+ await instance[addAccessor](id);
233
+ }
234
+ continue;
235
+ }
236
+ }
237
+ if (typeof instance[setAccessor] === 'function') {
238
+ await instance[setAccessor](ids);
239
+ }
240
+ else if (typeof instance[addAccessor] === 'function') {
241
+ await instance[addAccessor](ids);
242
+ }
243
+ else {
244
+ // console.warn(`No suitable accessor for "${alias}": tried set=${setAccessor}, add=${addAccessor}`);
245
+ }
246
+ }
247
+ await instance.reload({ include: Object.values(this.model.associations) });
248
+ const pk = this.primaryKey;
249
+ const fresh = await this.model.findByPk(instance.get(pk), { include: assocNames.map(a => ({ association: a })) });
250
+ // console.debug(">> Результат после reload:", fresh?.toJSON());
251
+ return fresh;
111
252
  }
112
253
  // --- FIND ONE ---
113
254
  async _findOne(criteria) {
255
+ // console.debug(">> _findOne: входные критерии:", criteria);
114
256
  const { where } = convertWaterlineCriteriaToSequelizeOptions(criteria);
115
- const result = await this.model.findOne({
116
- where,
117
- include: this._buildIncludes(),
118
- raw: true,
119
- });
120
- return result;
257
+ const includes = this._buildIncludes();
258
+ // console.debug(">> _findOne: преобразованные where:", where);
259
+ // console.debug(">> _findOne: includes:", includes);
260
+ let instance = null;
261
+ try {
262
+ instance = await this.model.findOne({ where, include: includes });
263
+ // console.debug(">> _findOne: сырое instance:", instance ? instance.toJSON() : null);
264
+ }
265
+ catch (err) {
266
+ // console.error("!! _findOne: ошибка при вызове findOne:", err);
267
+ throw err;
268
+ }
269
+ if (!instance) {
270
+ // console.debug(">> _findOne: ничего не найдено");
271
+ return null;
272
+ }
273
+ const plain = instance.get({ plain: true });
274
+ // console.debug(">> _findOne: plain результат:", plain);
275
+ return plain;
121
276
  }
122
277
  // --- FIND MANY ---
123
278
  async _find(criteria = {}, options = {}) {
279
+ const assocNames = Object.keys(this.model.associations);
280
+ // console.debug(">> _find: входные criteria:", criteria, "options:", options);
124
281
  const { where, limit, offset, order } = convertWaterlineCriteriaToSequelizeOptions(criteria);
125
- const include = options.populate
282
+ const includes = options.populate
126
283
  ? options.populate.map(([field, opts]) => ({ association: field, ...opts }))
127
- : this._buildIncludes();
128
- const result = await this.model.findAll({
129
- where,
130
- limit,
131
- offset,
132
- order,
133
- include,
134
- raw: true,
135
- });
136
- return result;
284
+ : assocNames.map(a => ({ association: a }));
285
+ // console.debug(">> _find: where, limit, offset, order, includes:", {
286
+ // where,
287
+ // limit,
288
+ // offset,
289
+ // order,
290
+ // includes,
291
+ // });
292
+ let instances;
293
+ try {
294
+ instances = await this.model.findAll({
295
+ where,
296
+ limit,
297
+ offset,
298
+ order,
299
+ include: includes
300
+ });
301
+ // console.debug(">> _find: получено моделей:", instances.length);
302
+ }
303
+ catch (err) {
304
+ // console.error("!! _find: ошибка в findAll:", err);
305
+ throw err;
306
+ }
307
+ for (const inst of instances) {
308
+ //For each association, we call getxxx () once again
309
+ for (const alias of assocNames) {
310
+ // @ts-ignore accessors is present
311
+ const getAccessor = this.model.associations[alias].accessors.get;
312
+ if (typeof inst[getAccessor] === "function") {
313
+ try {
314
+ const related = await inst[getAccessor]();
315
+ const mapped = Array.isArray(related)
316
+ ? related.map((r) => r.toJSON())
317
+ : related?.toJSON();
318
+ // console.debug(`---- get${alias}():`, mapped);
319
+ }
320
+ catch (e) {
321
+ // console.error(`!! ошибка при вызове ${getAccessor}():`, e);
322
+ }
323
+ }
324
+ }
325
+ }
326
+ const plain = instances.map(i => i.get({ plain: true }));
327
+ // console.debug(">> _find: plain результаты:", plain);
328
+ return plain;
137
329
  }
138
330
  // --- UPDATE ONE ---
139
331
  async _updateOne(criteria, data) {
@@ -205,7 +397,7 @@ export class SequelizeAdapter extends AbstractAdapter {
205
397
  const model = this.getModel(modelName);
206
398
  return model?.getAttributes();
207
399
  }
208
- /** Регистрация системных моделей */
400
+ /**Registration of system models*/
209
401
  static async registerSystemModels(sequelize) {
210
402
  const modelsDir = path.resolve(import.meta.dirname, "../../../../models");
211
403
  const files = fs.readdirSync(modelsDir).filter(f => f.endsWith(".js"));
@@ -218,7 +410,7 @@ export class SequelizeAdapter extends AbstractAdapter {
218
410
  await sequelize.sync();
219
411
  }
220
412
  }
221
- /** Генерация модели Sequelize из определения, аналог WaterlineCollection.extend */
413
+ /**Generation of the SEQUELIZE model from the definition, analogue of Waterinecollection.extenD*/
222
414
  function generateSequelizeModel(sequelize, modelName, rawAttributes) {
223
415
  const attributes = {};
224
416
  let primaryKey = null;
@@ -48,7 +48,6 @@ export class WaterlineModel extends AbstractModel {
48
48
  query = query.limit(options.limit);
49
49
  }
50
50
  let result = await query;
51
- console.log(result, "result");
52
51
  return result;
53
52
  }
54
53
  async _updateOne(criteria, data) {
@@ -1,7 +1,7 @@
1
1
  import BaseWidget from "./abstractWidgetBase";
2
2
  export default abstract class ActionBase extends BaseWidget {
3
3
  readonly widgetType = "action";
4
- /** Widget background css (color, Image) */
4
+ /** Widget background css color */
5
5
  abstract readonly backgroundCSS: string | null;
6
6
  abstract action(): Promise<any>;
7
7
  }
@@ -1,13 +1,28 @@
1
- import BaseWidget from "./abstractWidgetBase";
2
- export default abstract class CustomBase extends BaseWidget {
3
- /** Widget background css (color, Image) */
4
- abstract readonly backgroundCSS: string | null;
5
- /** Fullpath script for loading in dashboard in browser */
6
- abstract readonly scriptUrl: string;
7
- /** How widgets processor can call constructor of this widget */
8
- abstract readonly constructorName: string;
9
- /** Options to constuctor */
10
- abstract readonly constructorOption: any;
11
- /** Hide title, icon, description */
12
- abstract readonly hideAdminPanelUI: boolean;
1
+ import { MaterialIcon } from "material-icons";
2
+ export default abstract class CustomBase {
3
+ /** Widget unique id */
4
+ abstract readonly id: string;
5
+ /** Widget Name */
6
+ abstract readonly name: string;
7
+ /** JS module file path */
8
+ abstract readonly jsPath: {
9
+ dev: string;
10
+ production: string;
11
+ };
12
+ /** For group access rights by department */
13
+ abstract readonly department: string;
14
+ /** Widget background css color */
15
+ readonly backgroundCSS: string;
16
+ /** Widget size */
17
+ abstract readonly size: {
18
+ h: number;
19
+ w: number;
20
+ } | null;
21
+ /** Widget description */
22
+ abstract readonly description: string;
23
+ /** Widget icon */
24
+ abstract readonly icon?: MaterialIcon | string;
25
+ readonly widgetType: 'custom';
26
+ routePrefix: string;
27
+ protected constructor(routePrefix: string);
13
28
  }
@@ -1,3 +1,9 @@
1
- import BaseWidget from "./abstractWidgetBase";
2
- export default class CustomBase extends BaseWidget {
1
+ export default class CustomBase {
2
+ /** Widget background css color */
3
+ backgroundCSS;
4
+ widgetType = 'custom';
5
+ routePrefix;
6
+ constructor(routePrefix) {
7
+ this.routePrefix = routePrefix;
8
+ }
3
9
  }
@@ -1,7 +1,7 @@
1
1
  import BaseWidget from "./abstractWidgetBase";
2
2
  export default abstract class InfoBase extends BaseWidget {
3
3
  readonly widgetType = "info";
4
- /** Widget background css (color, Image) */
4
+ /** Widget background css color */
5
5
  readonly backgroundCSS: string;
6
6
  /** Widget size */
7
7
  readonly size: {
@@ -1,7 +1,7 @@
1
1
  import BaseWidget from "./abstractWidgetBase";
2
2
  export default class InfoBase extends BaseWidget {
3
3
  widgetType = "info";
4
- /** Widget background css (color, Image) */
4
+ /** Widget background css color */
5
5
  backgroundCSS;
6
6
  /** Widget size */
7
7
  size = null;
@@ -5,6 +5,7 @@ export interface Links {
5
5
  description: string;
6
6
  icon?: MaterialIcon;
7
7
  link: string;
8
+ linkType: 'self' | 'blank';
8
9
  backgroundCSS: string | null;
9
10
  }
10
11
  export default abstract class LinkBase extends BaseWidget {
@@ -1,7 +1,7 @@
1
1
  import BaseWidget from "./abstractWidgetBase";
2
2
  export default abstract class SwitchBase extends BaseWidget {
3
3
  readonly widgetType = "switcher";
4
- /** Widget background css (color, Image) */
4
+ /** Widget background css color */
5
5
  abstract readonly backgroundCSS: string | null;
6
6
  /** Get current state */
7
7
  abstract getState(): Promise<boolean>;
@@ -23,5 +23,5 @@ export default abstract class BaseWidget {
23
23
  /** Run task */
24
24
  "action" |
25
25
  /** Change location, or open in new tab */
26
- "link" | "custom";
26
+ "link";
27
27
  }
@@ -5,6 +5,8 @@ import LinkBase from "./abstractLink";
5
5
  import CustomBase from "./abstractCustom";
6
6
  import { AdminpanelIcon } from "../../interfaces/adminpanelConfig";
7
7
  import { Adminizer } from "../Adminizer";
8
+ import { UserAP } from "models/UserAP";
9
+ import { I18n } from "../v4/I18n";
8
10
  export type WidgetType = (SwitcherBase | InfoBase | ActionBase | LinkBase | CustomBase);
9
11
  export interface WidgetConfig {
10
12
  id: string;
@@ -16,6 +18,7 @@ export interface WidgetConfig {
16
18
  name: string;
17
19
  backgroundCSS: string;
18
20
  scriptUrl?: string;
21
+ linkType?: 'self' | 'blank';
19
22
  constructorName?: string;
20
23
  constructorOption?: any;
21
24
  size?: {
@@ -25,6 +28,14 @@ export interface WidgetConfig {
25
28
  added?: boolean;
26
29
  hideAdminPanelUI?: boolean;
27
30
  }
31
+ export interface WidgetLayoutItem {
32
+ x: number;
33
+ y: number;
34
+ w: number;
35
+ h: number;
36
+ i: string;
37
+ id: string;
38
+ }
28
39
  export declare class WidgetHandler {
29
40
  private widgets;
30
41
  adminizer: Adminizer;
@@ -32,7 +43,13 @@ export declare class WidgetHandler {
32
43
  add(widget: WidgetType): void;
33
44
  getById(id: string): WidgetType | undefined;
34
45
  removeById(id: string): void;
35
- getAll(user: ModelsAP["UserAP"]): Promise<WidgetConfig[]>;
36
- getWidgetsDB(id: number, auth: boolean): Promise<WidgetConfig[]>;
37
- setWidgetsDB(id: number, widgets: WidgetConfig[], auth: boolean): Promise<number>;
46
+ getAll(user: UserAP, i18n: I18n): Promise<WidgetConfig[]>;
47
+ getWidgetsDB(id: number, auth: boolean, i18n: I18n): Promise<{
48
+ widgets: WidgetConfig[];
49
+ layout: WidgetLayoutItem[];
50
+ }>;
51
+ setWidgetsDB(id: number, body: {
52
+ widgets: WidgetConfig[];
53
+ layout: WidgetLayoutItem[];
54
+ }, auth: boolean): Promise<number>;
38
55
  }