adminizer 4.1.0-commit.d8a06d3 → 4.1.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.
- package/Readme.md +46 -0
- package/assets/{VanillaJSONEditor-D-Lx670g.js → VanillaJSONEditor-DfRefswH.js} +104 -104
- package/assets/add-CJ1-zeA1.js +1 -0
- package/assets/add-form-CbNl0wdS.js +1 -0
- package/assets/add-group-form-Bt_Dx9wm.js +1 -0
- package/assets/add-group-pIFJV5qL.js +1 -0
- package/assets/add-user-D2US8hL_.js +1 -0
- package/assets/add-user-form-Bt8Jy6S2.js +1 -0
- package/assets/{app-WTooYWC3.css → app-B6cCPfWk.css} +1 -1
- package/assets/app-layout-B86jl9bH.js +1 -0
- package/assets/app-shell-CiGyzQ0C.js +1 -0
- package/assets/app-sidebar-Bz-SRwBg.js +1 -0
- package/assets/app-sidebar-header-7CNCx7Rs.js +11 -0
- package/assets/app.js +45 -37
- package/assets/breadcrumbs-_jhtTcOi.js +1 -0
- package/assets/catalog-CON6moaA.js +16 -0
- package/assets/catalog-Cc6Mk9sX.css +1 -0
- package/assets/checkbox-CQdZw5mb.js +1 -0
- package/assets/dashboard-es9ZT8qk.js +3 -0
- package/assets/{date-picker-DI1cCO7K.js → date-picker-Dz-d-YWX.js} +2 -2
- package/assets/debounce-qdyXyOeG.js +1 -0
- package/assets/del-modal-D0mrZvki.js +11 -0
- package/assets/dialog-stack-BiMbfm58.js +1 -0
- package/assets/dropdown-menu-BSBcRiXx.js +1 -0
- package/assets/{field-renderer-DVHZF6HS.js → field-renderer-B6hFAeiU.js} +3 -3
- package/assets/form-Buslty7y.js +1 -0
- package/assets/form-aqiRmPix.js +1 -0
- package/assets/{geo-json-BjiyTtMu.js → geo-json-BKmYmu3d.js} +2 -2
- package/assets/{handsontable-4mjU_b0n.js → handsontable-B8xVeMAQ.js} +5 -5
- package/assets/home-Dr72Jk-w.js +2 -0
- package/assets/icon-B-a7xg54.js +1 -0
- package/assets/index-B68_akQe.js +1 -0
- package/assets/index-B7-xTDyy.js +1 -0
- package/assets/index-BJFFlCSo.js +1 -0
- package/assets/{index-Cw5o84pO.js → index-BOuMo_nl.js} +3 -3
- package/assets/index-BzOcGsBq.js +1 -0
- package/assets/index-CFbQ2Rv0.js +1 -0
- package/assets/{index-D5ir9iUV.js → index-Cq31rrfZ.js} +1 -1
- package/assets/{index-Cgp8OfuI.js → index-D5UDXTFs.js} +1 -1
- package/assets/index-oxIQWAdI.js +41 -0
- package/assets/init-user-5H689LP0.js +1 -0
- package/assets/input-CSJjrf2i.js +1 -0
- package/assets/input-error-CK92Shhm.js +1 -0
- package/assets/label-Muj0-Efy.js +1 -0
- package/assets/list-Cvh7zbyG.js +1 -0
- package/assets/list-table-Bs_vbQiV.js +52 -0
- package/assets/login-DliJrjMQ.js +6 -0
- package/assets/manifest.json +575 -673
- package/assets/material-icon-BRS58Qpk.js +1 -0
- package/assets/module-CjG21VCT.js +1 -0
- package/assets/{monaco-editor-CJs0_GlD.js → monaco-editor-9fDiyfuW.js} +2 -2
- package/assets/{multi-select-BvRpAW8r.js → multi-select-CMQIJ0JT.js} +2 -2
- package/assets/nav-footer-IGMn9NiE.js +1 -0
- package/assets/nav-main-DBE4rMiZ.js +1 -0
- package/assets/nav-user-CjyLRyq-.js +1 -0
- package/assets/pagination-render-DUAq2klc.js +1 -0
- package/assets/popover-C_cww-4_.js +1 -0
- package/assets/register-UzQn3J0g.js +1 -0
- package/assets/{select-BWepUw-9.js → select-DzBno-dc.js} +2 -2
- package/assets/{sidebar-CAHsHdjM.js → sidebar-Dc4iqfu-.js} +2 -2
- package/assets/skeleton-Dkmj2o2Z.js +1 -0
- package/assets/sonner-De1t71Gj.js +1 -0
- package/assets/{toast-editor-CMK7QtF1.js → toast-editor-1Pul3oMs.js} +2 -2
- package/assets/tooltip-CwPrC-HD.js +1 -0
- package/assets/use-appearance-J8J2w43p.js +1 -0
- package/assets/use-window-size-DLSEoR6e.js +1 -0
- package/assets/{user-info-DFrmpJ4y.js → user-info-8RyDk7qh.js} +2 -2
- package/assets/user-menu-content-CpxTLH56.js +6 -0
- package/assets/welcome-BYKI6yO-.js +1 -0
- package/controllers/add.js +8 -8
- package/controllers/catalog/Catalog.d.ts +1 -1
- package/controllers/catalog/Catalog.js +40 -35
- package/controllers/catalog/FrontentCatalogAdapter.d.ts +36 -26
- package/controllers/catalog/FrontentCatalogAdapter.js +71 -72
- package/controllers/edit.js +8 -11
- package/controllers/list.js +2 -2
- package/controllers/login.js +16 -7
- package/controllers/navigation/edit.js +1 -1
- package/controllers/remove.js +1 -1
- package/controllers/view.js +1 -1
- package/helpers/JsUtils.d.ts +1 -0
- package/helpers/JsUtils.js +3 -0
- package/helpers/accessRightsHelper.d.ts +3 -0
- package/helpers/accessRightsHelper.js +27 -4
- package/helpers/controllerHelper.js +39 -18
- package/helpers/fieldsHelper.d.ts +3 -2
- package/helpers/fieldsHelper.js +5 -1
- package/helpers/inertiaAddHelper.d.ts +4 -5
- package/helpers/inertiaAddHelper.js +25 -7
- package/helpers/inertiaFromHelper.js +1 -1
- package/helpers/inertiaMenuHelper.d.ts +1 -1
- package/helpers/inertiaMenuHelper.js +1 -1
- package/helpers/menuHelper.d.ts +8 -3
- package/helpers/menuHelper.js +26 -17
- package/index.d.ts +2 -6
- package/index.js +5 -6
- package/interfaces/adminpanelConfig.d.ts +35 -30
- package/interfaces/global.d.ts +5 -2
- package/interfaces/types.d.ts +1 -1
- package/lib/Adminizer.d.ts +9 -3
- package/lib/Adminizer.js +32 -16
- package/lib/media-manager/Items.js +0 -3
- package/lib/requestProcessor.js +10 -3
- package/lib/v4/DataAccessor.d.ts +3 -1
- package/lib/v4/DataAccessor.js +43 -18
- package/lib/v4/I18n.js +2 -0
- package/lib/{catalog → v4/catalog}/AbstractCatalog.d.ts +89 -60
- package/lib/{catalog → v4/catalog}/AbstractCatalog.js +59 -54
- package/lib/v4/catalog/Navigation.d.ts +43 -0
- package/lib/v4/catalog/Navigation.js +457 -0
- package/lib/{controls → v4/controls}/AbstractControls.d.ts +1 -1
- package/lib/{controls → v4/controls}/codeEditor/MonacoEditor.d.ts +1 -1
- package/lib/{controls → v4/controls}/geojsoneditor/GeoEditor.d.ts +1 -1
- package/lib/{controls → v4/controls}/jsoneditor/JsonEditor.d.ts +1 -1
- package/lib/{controls → v4/controls}/markdown/ToastUiEditor.d.ts +1 -1
- package/lib/{controls → v4/controls}/table/Handsontable.d.ts +1 -1
- package/lib/{controls → v4/controls}/wysiwyg/CKeditor.d.ts +1 -1
- package/lib/{datatable → v4/datatable}/NodeTable.d.ts +3 -3
- package/lib/{datatable → v4/datatable}/NodeTable.js +8 -5
- package/lib/v4/model/AbstractModel.d.ts +5 -1
- package/lib/v4/model/AbstractModel.js +2 -1
- package/lib/v4/model/ModelHandler.js +1 -3
- package/lib/v4/model/adapter/sequelize.d.ts +8 -0
- package/lib/v4/model/adapter/sequelize.js +274 -133
- package/lib/v4/model/adapter/waterline.js +5 -2
- package/lib/{widgets → v4/widgets}/abstractLink.d.ts +1 -1
- package/lib/{widgets → v4/widgets}/abstractWidgetBase.d.ts +1 -1
- package/lib/{widgets → v4/widgets}/widgetHandler.d.ts +11 -4
- package/lib/{widgets → v4/widgets}/widgetHandler.js +1 -1
- package/models/NavigationAP.d.ts +2 -3
- package/models/NavigationAP.js +5 -6
- package/models/UserAP.d.ts +2 -3
- package/package.json +17 -6
- package/system/Router.js +8 -11
- package/system/bindAccessRights.js +0 -4
- package/system/bindControls.js +6 -6
- package/system/bindDev.js +1 -0
- package/system/bindInertia.js +9 -4
- package/system/bindMediaManager.js +0 -1
- package/system/bindModels.js +9 -6
- package/system/bindNavigation.d.ts +2 -0
- package/system/bindNavigation.js +42 -42
- package/system/bindReqFunctions.js +0 -1
- package/system/defaults.js +13 -6
- package/translations/ar.json +70 -1
- package/translations/cn.json +70 -1
- package/translations/de.json +71 -3
- package/translations/en.json +70 -102
- package/translations/es.json +70 -1
- package/translations/fr.json +70 -1
- package/translations/hi.json +70 -1
- package/translations/jp.json +70 -1
- package/translations/ko.json +70 -1
- package/translations/pt.json +70 -1
- package/translations/ru.json +71 -103
- package/translations/ua.json +70 -1
- package/translations/uz.json +72 -0
- package/translations/vi.json +70 -1
- package/assets/add-BP_u3Tjl.js +0 -1
- package/assets/add-form-nffmiYTh.js +0 -1
- package/assets/add-group-D4vcHlm-.js +0 -1
- package/assets/add-group-form-gNJW11-q.js +0 -1
- package/assets/add-user-DWh3Nas0.js +0 -1
- package/assets/add-user-form-BJ0FsZYJ.js +0 -1
- package/assets/app-layout-DYsRFUuP.js +0 -1
- package/assets/app-shell-Dd9Eknik.js +0 -1
- package/assets/app-sidebar-BOmu6-Sl.js +0 -1
- package/assets/app-sidebar-header-CoXSzWxk.js +0 -11
- package/assets/breadcrumbs-BmAq4fHT.js +0 -1
- package/assets/button-C9B_5Jf_.js +0 -1
- package/assets/checkbox-Fg27sL_1.js +0 -1
- package/assets/compiler-runtime-hB6dAw2d.js +0 -9
- package/assets/dashboard-BACj996r.js +0 -3
- package/assets/dropdown-menu-Bhj17ENm.js +0 -1
- package/assets/form-BgWdwvz1.js +0 -1
- package/assets/form-DgtErfln.js +0 -1
- package/assets/home-CHntBHJa.js +0 -2
- package/assets/icon-Dt0vBgDO.js +0 -1
- package/assets/index-B8BS9wMC.js +0 -1
- package/assets/index-BC0yfOHo.js +0 -1
- package/assets/index-BKCgnGj_.js +0 -1
- package/assets/index-BbXEMx9n.js +0 -1
- package/assets/index-BykbU6Ee.js +0 -41
- package/assets/index-CaJgc5EZ.js +0 -1
- package/assets/index-DrWfGwtf.js +0 -1
- package/assets/init-user-JfCKJ5Ce.js +0 -1
- package/assets/input-CvRbIbk4.js +0 -1
- package/assets/input-error-DMK7cAt7.js +0 -1
- package/assets/label-CSLFe9Bz.js +0 -1
- package/assets/list-B2Oa5O_Q.js +0 -1
- package/assets/list-table-DA9MhywL.js +0 -62
- package/assets/login-DQwGtdis.js +0 -6
- package/assets/material-icon-BJg8o_fs.js +0 -1
- package/assets/module-DWXp59Vg.js +0 -1
- package/assets/nav-footer-Bs4dmN1d.js +0 -1
- package/assets/nav-main-Bq3IMk4C.js +0 -1
- package/assets/nav-user-CbB22J5O.js +0 -1
- package/assets/pagination-render-DuXDDbC_.js +0 -1
- package/assets/popover-DtoGI2b1.js +0 -1
- package/assets/register-BSogVF0h.js +0 -1
- package/assets/skeleton-COOcAA8f.js +0 -1
- package/assets/sonner-BI0IFOQN.js +0 -1
- package/assets/tooltip-DHwpLKOI.js +0 -1
- package/assets/use-appearance-DRfIqTgw.js +0 -1
- package/assets/use-window-size-h0Sh_NvX.js +0 -1
- package/assets/user-menu-content-DPXQdERj.js +0 -6
- package/assets/utils-DjqsqOe8.js +0 -1
- package/assets/welcome-B4WCIXKf.js +0 -1
- package/controllers/processInstallFinalize.d.ts +0 -1
- package/controllers/processInstallFinalize.js +0 -16
- package/controllers/processInstallStep.d.ts +0 -0
- package/controllers/processInstallStep.js +0 -122
- package/lib/catalog/Navigation.d.ts +0 -0
- package/lib/catalog/Navigation.js +0 -532
- package/lib/installStepper/InstallStepAbstract.d.ts +0 -52
- package/lib/installStepper/InstallStepAbstract.js +0 -69
- package/lib/installStepper/finalizeStep.d.ts +0 -21
- package/lib/installStepper/finalizeStep.js +0 -48
- package/lib/installStepper/installStepper.d.ts +0 -40
- package/lib/installStepper/installStepper.js +0 -195
- package/models/MediaManagerAP.d.ts +0 -62
- package/models/MediaManagerAP.js +0 -45
- package/models/MediaManagerAssociationsAP.d.ts +0 -38
- package/models/MediaManagerAssociationsAP.js +0 -27
- package/models/MediaManagerMetaAP.d.ts +0 -30
- package/models/MediaManagerMetaAP.js +0 -21
- package/system/bindInstallStepper.d.ts +0 -2
- package/system/bindInstallStepper.js +0 -23
- /package/lib/{catalog → v4/catalog}/CatalogHandler.d.ts +0 -0
- /package/lib/{catalog → v4/catalog}/CatalogHandler.js +0 -0
- /package/lib/{controls → v4/controls}/AbstractControls.js +0 -0
- /package/lib/{controls → v4/controls}/ControlsHandler.d.ts +0 -0
- /package/lib/{controls → v4/controls}/ControlsHandler.js +0 -0
- /package/lib/{controls → v4/controls}/codeEditor/MonacoEditor.js +0 -0
- /package/lib/{controls → v4/controls}/geojsoneditor/GeoEditor.js +0 -0
- /package/lib/{controls → v4/controls}/jsoneditor/JsonEditor.js +0 -0
- /package/lib/{controls → v4/controls}/markdown/ToastUiEditor.js +0 -0
- /package/lib/{controls → v4/controls}/table/Handsontable.js +0 -0
- /package/lib/{controls → v4/controls}/wysiwyg/CKeditor.js +0 -0
- /package/lib/{inertia → v4/inertia}/flash.d.ts +0 -0
- /package/lib/{inertia → v4/inertia}/flash.js +0 -0
- /package/lib/{inertia → v4/inertia}/inertiaAdapter.d.ts +0 -0
- /package/lib/{inertia → v4/inertia}/inertiaAdapter.js +0 -0
- /package/lib/{widgets → v4/widgets}/abstractAction.d.ts +0 -0
- /package/lib/{widgets → v4/widgets}/abstractAction.js +0 -0
- /package/lib/{widgets → v4/widgets}/abstractCustom.d.ts +0 -0
- /package/lib/{widgets → v4/widgets}/abstractCustom.js +0 -0
- /package/lib/{widgets → v4/widgets}/abstractInfo.d.ts +0 -0
- /package/lib/{widgets → v4/widgets}/abstractInfo.js +0 -0
- /package/lib/{widgets → v4/widgets}/abstractLink.js +0 -0
- /package/lib/{widgets → v4/widgets}/abstractSwitch.d.ts +0 -0
- /package/lib/{widgets → v4/widgets}/abstractSwitch.js +0 -0
- /package/lib/{widgets → v4/widgets}/abstractWidgetBase.js +0 -0
|
@@ -3,6 +3,64 @@ 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 generateAssociationsFromSchema(models, schemas) {
|
|
7
|
+
for (const modelName in schemas) {
|
|
8
|
+
const schema = schemas[modelName];
|
|
9
|
+
const model = models[modelName];
|
|
10
|
+
if (!model)
|
|
11
|
+
continue;
|
|
12
|
+
for (const fieldName in schema) {
|
|
13
|
+
const field = schema[fieldName];
|
|
14
|
+
if (field.collection && field.via) {
|
|
15
|
+
const targetModel = models[field.collection];
|
|
16
|
+
const targetSchema = schemas[field.collection];
|
|
17
|
+
const inverseField = targetSchema?.[field.via];
|
|
18
|
+
const throughTableName = [modelName, field.collection].sort().join("");
|
|
19
|
+
// 💡 M:N связь
|
|
20
|
+
if (inverseField && inverseField.collection === modelName) {
|
|
21
|
+
model.belongsToMany(targetModel, {
|
|
22
|
+
through: throughTableName,
|
|
23
|
+
as: fieldName,
|
|
24
|
+
foreignKey: `${modelName}Id`,
|
|
25
|
+
otherKey: `${field.collection}Id`
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
// 💡 O:M связь (один ко многим)
|
|
29
|
+
else {
|
|
30
|
+
model.hasMany(targetModel, {
|
|
31
|
+
as: fieldName,
|
|
32
|
+
foreignKey: `${modelName}Id`,
|
|
33
|
+
});
|
|
34
|
+
targetModel.belongsTo(model, {
|
|
35
|
+
as: field.via,
|
|
36
|
+
foreignKey: `${modelName}Id`,
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
// 💡 O:1 или 1:1 (belongsTo)
|
|
41
|
+
if (field.model) {
|
|
42
|
+
const targetModel = models[field.model];
|
|
43
|
+
if (!targetModel)
|
|
44
|
+
continue;
|
|
45
|
+
// Avoid naming collision by making FK explicit: `${fieldName}Id`
|
|
46
|
+
const foreignKey = `${fieldName}Id`;
|
|
47
|
+
const alias = fieldName;
|
|
48
|
+
// Если поле уже существует — избегаем конфликта
|
|
49
|
+
if (model.rawAttributes[alias]) {
|
|
50
|
+
model.belongsTo(targetModel, {
|
|
51
|
+
as: alias,
|
|
52
|
+
foreignKey,
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
model.belongsTo(targetModel, {
|
|
57
|
+
foreignKey: alias, // если нет конфликта, можно использовать alias как FK
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
6
64
|
function resolveType(type) {
|
|
7
65
|
const sqlType = typeof type.toString === "function"
|
|
8
66
|
? type.toString().toLowerCase()
|
|
@@ -38,18 +96,20 @@ export function mapSequelizeToWaterline(model) {
|
|
|
38
96
|
switch (assoc.associationType) {
|
|
39
97
|
case "BelongsTo": {
|
|
40
98
|
const a = assoc;
|
|
99
|
+
result[a.foreignKey]["primaryKeyForAssociation"] = true;
|
|
41
100
|
result[alias] = {
|
|
42
101
|
type: "association",
|
|
43
|
-
model: a.target.name
|
|
102
|
+
model: a.target.name,
|
|
44
103
|
via: a.foreignKey,
|
|
45
104
|
};
|
|
46
105
|
break;
|
|
47
106
|
}
|
|
48
107
|
case "HasOne": {
|
|
49
108
|
const a = assoc;
|
|
109
|
+
result[a.foreignKey]["primaryKeyForAssociation"] = true;
|
|
50
110
|
result[alias] = {
|
|
51
111
|
type: "association",
|
|
52
|
-
model: a.target.name
|
|
112
|
+
model: a.target.name,
|
|
53
113
|
via: a.foreignKey,
|
|
54
114
|
};
|
|
55
115
|
break;
|
|
@@ -58,7 +118,7 @@ export function mapSequelizeToWaterline(model) {
|
|
|
58
118
|
const a = assoc;
|
|
59
119
|
result[alias] = {
|
|
60
120
|
type: "association-many",
|
|
61
|
-
collection: a.target.name
|
|
121
|
+
collection: a.target.name,
|
|
62
122
|
via: a.foreignKey,
|
|
63
123
|
};
|
|
64
124
|
break;
|
|
@@ -67,7 +127,7 @@ export function mapSequelizeToWaterline(model) {
|
|
|
67
127
|
const a = assoc;
|
|
68
128
|
result[alias] = {
|
|
69
129
|
type: "association-many",
|
|
70
|
-
collection: a.target.name
|
|
130
|
+
collection: a.target.name,
|
|
71
131
|
via: a.otherKey,
|
|
72
132
|
};
|
|
73
133
|
break;
|
|
@@ -78,113 +138,109 @@ export function mapSequelizeToWaterline(model) {
|
|
|
78
138
|
}
|
|
79
139
|
return result;
|
|
80
140
|
}
|
|
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
|
-
// }
|
|
97
|
-
/** SequelizeModel — реализация модели, совместимая с AbstractModel */
|
|
98
141
|
function capitalize(str) {
|
|
99
142
|
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
100
143
|
}
|
|
101
|
-
function convertCriteriaToSequelize(criteria) {
|
|
102
|
-
// console.debug("waterline criteria", criteria)
|
|
103
|
-
const result = {};
|
|
104
|
-
for (const key in criteria) {
|
|
105
|
-
const value = criteria[key];
|
|
106
|
-
if (value === undefined ||
|
|
107
|
-
value === null ||
|
|
108
|
-
(typeof value === "object" && Object.keys(value).length === 0)) {
|
|
109
|
-
continue;
|
|
110
|
-
}
|
|
111
|
-
if (typeof value === "object" && !Array.isArray(value)) {
|
|
112
|
-
const operatorEntries = Object.entries(value)
|
|
113
|
-
.filter(([_, v]) => v !== undefined && v !== null)
|
|
114
|
-
.map(([op, val]) => {
|
|
115
|
-
switch (op) {
|
|
116
|
-
case "contains": return [Op.like, `%${val}%`];
|
|
117
|
-
case "startsWith": return [Op.startsWith, val];
|
|
118
|
-
case "endsWith": return [Op.endsWith, val];
|
|
119
|
-
case ">": return [Op.gt, val];
|
|
120
|
-
case ">=": return [Op.gte, val];
|
|
121
|
-
case "<": return [Op.lt, val];
|
|
122
|
-
case "<=": return [Op.lte, val];
|
|
123
|
-
case "!=": return [Op.ne, val];
|
|
124
|
-
case "in": return [Op.in, val];
|
|
125
|
-
case "nin": return [Op.notIn, val];
|
|
126
|
-
default: return [Op.eq, val];
|
|
127
|
-
}
|
|
128
|
-
});
|
|
129
|
-
if (operatorEntries.length > 0) {
|
|
130
|
-
result[key] = Object.fromEntries(operatorEntries);
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
else {
|
|
134
|
-
result[key] = value;
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
return result;
|
|
138
|
-
}
|
|
139
|
-
function convertWaterlineCriteriaToSequelizeOptions(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)
|
|
166
|
-
const { where = {}, skip, limit, sort } = criteria;
|
|
167
|
-
const result = {
|
|
168
|
-
where: convertCriteriaToSequelize(where),
|
|
169
|
-
};
|
|
170
|
-
if (typeof skip === "number") {
|
|
171
|
-
result.offset = skip;
|
|
172
|
-
}
|
|
173
|
-
if (typeof limit === "number") {
|
|
174
|
-
result.limit = limit;
|
|
175
|
-
}
|
|
176
|
-
if (typeof sort === "string") {
|
|
177
|
-
const [field, direction] = sort.trim().split(/\s+/);
|
|
178
|
-
result.order = [[field, direction?.toUpperCase() === "DESC" ? "DESC" : "ASC"]];
|
|
179
|
-
}
|
|
180
|
-
return result;
|
|
181
|
-
}
|
|
182
144
|
export class SequelizeModel extends AbstractModel {
|
|
183
145
|
model;
|
|
184
146
|
constructor(modelName, model) {
|
|
185
147
|
super(modelName, mapSequelizeToWaterline(model), model.primaryKeyAttribute, model.name);
|
|
186
148
|
this.model = model;
|
|
187
149
|
}
|
|
150
|
+
_convertCriteriaToSequelize(criteria) {
|
|
151
|
+
const result = {};
|
|
152
|
+
for (const key in criteria) {
|
|
153
|
+
const value = criteria[key];
|
|
154
|
+
if (value === undefined ||
|
|
155
|
+
value === null ||
|
|
156
|
+
(typeof value === "object" && Object.keys(value).length === 0)) {
|
|
157
|
+
continue;
|
|
158
|
+
}
|
|
159
|
+
// 🧠 Заменяем ключ на `via`, если это ассоциация
|
|
160
|
+
const attr = this.attributes?.[key];
|
|
161
|
+
let targetKey = key;
|
|
162
|
+
if (attr?.type === "association" && attr.via) {
|
|
163
|
+
targetKey = attr.via;
|
|
164
|
+
}
|
|
165
|
+
if (typeof value === "object" && !Array.isArray(value)) {
|
|
166
|
+
const operatorEntries = Object.entries(value)
|
|
167
|
+
.filter(([_, v]) => v !== undefined && v !== null)
|
|
168
|
+
.map(([op, val]) => {
|
|
169
|
+
switch (op) {
|
|
170
|
+
case "contains": return [Op.like, `%${val}%`];
|
|
171
|
+
case "startsWith": return [Op.startsWith, val];
|
|
172
|
+
case "endsWith": return [Op.endsWith, val];
|
|
173
|
+
case ">": return [Op.gt, val];
|
|
174
|
+
case ">=": return [Op.gte, val];
|
|
175
|
+
case "<": return [Op.lt, val];
|
|
176
|
+
case "<=": return [Op.lte, val];
|
|
177
|
+
case "!=": return [Op.ne, val];
|
|
178
|
+
case "in": return [Op.in, val];
|
|
179
|
+
case "nin": return [Op.notIn, val];
|
|
180
|
+
default: return [Op.eq, val];
|
|
181
|
+
}
|
|
182
|
+
});
|
|
183
|
+
if (operatorEntries.length > 0) {
|
|
184
|
+
result[targetKey] = Object.fromEntries(operatorEntries);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
else {
|
|
188
|
+
result[targetKey] = value;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
return result;
|
|
192
|
+
}
|
|
193
|
+
_convertWaterlineCriteriaToSequelizeOptions(criteria) {
|
|
194
|
+
// console.debug("WATERLINE CRITERIA (raw):", criteria);
|
|
195
|
+
const { where: nestedWhere, skip, limit, sort, ...rest } = criteria;
|
|
196
|
+
const rawWhere = (nestedWhere && Object.keys(nestedWhere).length > 0)
|
|
197
|
+
? nestedWhere
|
|
198
|
+
: rest;
|
|
199
|
+
// console.debug("WATERLINE CRITERIA: using rawWhere =", rawWhere);
|
|
200
|
+
const where = this._convertCriteriaToSequelize(rawWhere);
|
|
201
|
+
const result = { where };
|
|
202
|
+
if (typeof skip === "number") {
|
|
203
|
+
result.offset = skip;
|
|
204
|
+
// console.debug("→ offset =", skip);
|
|
205
|
+
}
|
|
206
|
+
if (typeof limit === "number") {
|
|
207
|
+
result.limit = limit;
|
|
208
|
+
// console.debug("→ limit =", limit);
|
|
209
|
+
}
|
|
210
|
+
if (typeof sort === "string") {
|
|
211
|
+
const [field, dir] = sort.trim().split(/\s+/);
|
|
212
|
+
result.order = [[field, dir?.toUpperCase() === "DESC" ? "DESC" : "ASC"]];
|
|
213
|
+
// console.debug("→ order =", result.order);
|
|
214
|
+
}
|
|
215
|
+
return result;
|
|
216
|
+
}
|
|
217
|
+
async _assignAssociations(instance, assocData) {
|
|
218
|
+
for (const [alias, ids] of Object.entries(assocData)) {
|
|
219
|
+
const assoc = this.model.associations[alias];
|
|
220
|
+
if (!assoc)
|
|
221
|
+
continue;
|
|
222
|
+
//@ts-ignore
|
|
223
|
+
const { set: setAccessor, add: addAccessor } = assoc.accessors;
|
|
224
|
+
if (Array.isArray(ids)) {
|
|
225
|
+
if (typeof instance[setAccessor] === 'function') {
|
|
226
|
+
await instance[setAccessor](ids);
|
|
227
|
+
continue;
|
|
228
|
+
}
|
|
229
|
+
if (typeof instance[addAccessor] === 'function') {
|
|
230
|
+
for (const id of ids) {
|
|
231
|
+
await instance[addAccessor](id);
|
|
232
|
+
}
|
|
233
|
+
continue;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
if (typeof instance[setAccessor] === 'function') {
|
|
237
|
+
await instance[setAccessor](ids);
|
|
238
|
+
}
|
|
239
|
+
else if (typeof instance[addAccessor] === 'function') {
|
|
240
|
+
await instance[addAccessor](ids);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
188
244
|
// --- CREATE ---
|
|
189
245
|
async _create(data) {
|
|
190
246
|
// console.clear()
|
|
@@ -253,7 +309,7 @@ export class SequelizeModel extends AbstractModel {
|
|
|
253
309
|
// --- FIND ONE ---
|
|
254
310
|
async _findOne(criteria) {
|
|
255
311
|
// console.debug(">> _findOne: входные критерии:", criteria);
|
|
256
|
-
const { where } =
|
|
312
|
+
const { where } = this._convertWaterlineCriteriaToSequelizeOptions(criteria);
|
|
257
313
|
const includes = this._buildIncludes();
|
|
258
314
|
// console.debug(">> _findOne: преобразованные where:", where);
|
|
259
315
|
// console.debug(">> _findOne: includes:", includes);
|
|
@@ -278,7 +334,7 @@ export class SequelizeModel extends AbstractModel {
|
|
|
278
334
|
async _find(criteria = {}, options = {}) {
|
|
279
335
|
const assocNames = Object.keys(this.model.associations);
|
|
280
336
|
// console.debug(">> _find: входные criteria:", criteria, "options:", options);
|
|
281
|
-
const { where, limit, offset, order } =
|
|
337
|
+
const { where, limit, offset, order } = this._convertWaterlineCriteriaToSequelizeOptions(criteria);
|
|
282
338
|
const includes = options.populate
|
|
283
339
|
? options.populate.map(([field, opts]) => ({ association: field, ...opts }))
|
|
284
340
|
: assocNames.map(a => ({ association: a }));
|
|
@@ -290,20 +346,13 @@ export class SequelizeModel extends AbstractModel {
|
|
|
290
346
|
// includes,
|
|
291
347
|
// });
|
|
292
348
|
let instances;
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
});
|
|
301
|
-
// console.debug(">> _find: получено моделей:", instances.length);
|
|
302
|
-
}
|
|
303
|
-
catch (err) {
|
|
304
|
-
// console.error("!! _find: ошибка в findAll:", err);
|
|
305
|
-
throw err;
|
|
306
|
-
}
|
|
349
|
+
instances = await this.model.findAll({
|
|
350
|
+
where,
|
|
351
|
+
limit,
|
|
352
|
+
offset,
|
|
353
|
+
order,
|
|
354
|
+
include: includes
|
|
355
|
+
});
|
|
307
356
|
for (const inst of instances) {
|
|
308
357
|
//For each association, we call getxxx () once again
|
|
309
358
|
for (const alias of assocNames) {
|
|
@@ -329,28 +378,81 @@ export class SequelizeModel extends AbstractModel {
|
|
|
329
378
|
}
|
|
330
379
|
// --- UPDATE ONE ---
|
|
331
380
|
async _updateOne(criteria, data) {
|
|
332
|
-
const { where } =
|
|
381
|
+
const { where } = this._convertWaterlineCriteriaToSequelizeOptions(criteria);
|
|
333
382
|
const record = await this.model.findOne({ where });
|
|
334
|
-
if (!record)
|
|
383
|
+
if (!record)
|
|
335
384
|
return null;
|
|
385
|
+
const assocNames = Object.keys(this.model.associations);
|
|
386
|
+
const plainData = {};
|
|
387
|
+
const assocData = {};
|
|
388
|
+
for (const [key, val] of Object.entries(data)) {
|
|
389
|
+
if (assocNames.includes(key)) {
|
|
390
|
+
assocData[key] = val;
|
|
391
|
+
}
|
|
392
|
+
else {
|
|
393
|
+
plainData[key] = val;
|
|
394
|
+
}
|
|
336
395
|
}
|
|
337
|
-
await record.update(
|
|
338
|
-
|
|
339
|
-
|
|
396
|
+
await record.update(plainData);
|
|
397
|
+
await this._assignAssociations(record, assocData);
|
|
398
|
+
await record.reload({ include: Object.values(this.model.associations) });
|
|
399
|
+
return record.get({ plain: true });
|
|
340
400
|
}
|
|
341
401
|
// --- UPDATE MANY ---
|
|
342
402
|
async _update(criteria, data) {
|
|
343
|
-
const { where } =
|
|
344
|
-
|
|
345
|
-
const
|
|
346
|
-
|
|
403
|
+
const { where } = this._convertWaterlineCriteriaToSequelizeOptions(criteria);
|
|
404
|
+
const assocNames = Object.keys(this.model.associations);
|
|
405
|
+
const plainData = {};
|
|
406
|
+
const assocData = {};
|
|
407
|
+
for (const [key, val] of Object.entries(data)) {
|
|
408
|
+
if (assocNames.includes(key)) {
|
|
409
|
+
assocData[key] = val;
|
|
410
|
+
}
|
|
411
|
+
else {
|
|
412
|
+
plainData[key] = val;
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
const records = await this.model.findAll({ where });
|
|
416
|
+
for (const record of records) {
|
|
417
|
+
await record.update(plainData);
|
|
418
|
+
await this._assignAssociations(record, assocData);
|
|
419
|
+
}
|
|
420
|
+
const reloaded = await this.model.findAll({
|
|
421
|
+
where,
|
|
422
|
+
include: Object.values(this.model.associations)
|
|
423
|
+
});
|
|
424
|
+
return reloaded.map(r => r.get({ plain: true }));
|
|
347
425
|
}
|
|
348
426
|
// --- DESTROY ONE ---
|
|
349
427
|
async _destroyOne(criteria) {
|
|
350
|
-
const { where } =
|
|
428
|
+
const { where } = this._convertWaterlineCriteriaToSequelizeOptions(criteria);
|
|
351
429
|
const record = await this.model.findOne({ where });
|
|
352
|
-
if (!record)
|
|
430
|
+
if (!record)
|
|
353
431
|
return null;
|
|
432
|
+
const assocNames = Object.keys(this.model.associations);
|
|
433
|
+
for (const alias of assocNames) {
|
|
434
|
+
const assoc = this.model.associations[alias];
|
|
435
|
+
// @ts-ignore: accessors should exist
|
|
436
|
+
const getAccessor = assoc.accessors?.get;
|
|
437
|
+
if (typeof record[getAccessor] === "function") {
|
|
438
|
+
try {
|
|
439
|
+
const related = await record[getAccessor]();
|
|
440
|
+
// 🧹 Удаляем связанные записи
|
|
441
|
+
if (Array.isArray(related)) {
|
|
442
|
+
for (const r of related) {
|
|
443
|
+
if (typeof r.destroy === "function") {
|
|
444
|
+
await r.destroy();
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
else if (related && typeof related.destroy === "function") {
|
|
449
|
+
await related.destroy();
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
catch (e) {
|
|
453
|
+
// console.warn(`Failed to fetch/delete relation "${alias}":`, e);
|
|
454
|
+
}
|
|
455
|
+
}
|
|
354
456
|
}
|
|
355
457
|
const raw = record.get({ plain: true });
|
|
356
458
|
await record.destroy();
|
|
@@ -358,15 +460,44 @@ export class SequelizeModel extends AbstractModel {
|
|
|
358
460
|
}
|
|
359
461
|
// --- DESTROY MANY ---
|
|
360
462
|
async _destroy(criteria) {
|
|
361
|
-
const { where } =
|
|
463
|
+
const { where } = this._convertWaterlineCriteriaToSequelizeOptions(criteria);
|
|
362
464
|
const records = await this.model.findAll({ where });
|
|
465
|
+
const assocNames = Object.keys(this.model.associations);
|
|
466
|
+
for (const record of records) {
|
|
467
|
+
for (const alias of assocNames) {
|
|
468
|
+
const assoc = this.model.associations[alias];
|
|
469
|
+
// 🛑 Не трогаем родительские связи
|
|
470
|
+
if (assoc.associationType === "BelongsTo")
|
|
471
|
+
continue;
|
|
472
|
+
// @ts-ignore accessor exists
|
|
473
|
+
const getAccessor = assoc.accessors?.get;
|
|
474
|
+
if (typeof record[getAccessor] === "function") {
|
|
475
|
+
try {
|
|
476
|
+
const related = await record[getAccessor]();
|
|
477
|
+
if (Array.isArray(related)) {
|
|
478
|
+
for (const rel of related) {
|
|
479
|
+
if (typeof rel.destroy === "function") {
|
|
480
|
+
await rel.destroy();
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
else if (related && typeof related.destroy === "function") {
|
|
485
|
+
await related.destroy();
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
catch (e) {
|
|
489
|
+
// console.warn(`Failed to delete relation ${alias}:`, e);
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
}
|
|
363
494
|
const raw = records.map(r => r.get({ plain: true }));
|
|
364
495
|
await this.model.destroy({ where });
|
|
365
496
|
return raw;
|
|
366
497
|
}
|
|
367
498
|
// --- COUNT ---
|
|
368
499
|
async _count(criteria = {}) {
|
|
369
|
-
const { where } =
|
|
500
|
+
const { where } = this._convertWaterlineCriteriaToSequelizeOptions(criteria);
|
|
370
501
|
const result = await this.model.count({ where });
|
|
371
502
|
return result;
|
|
372
503
|
}
|
|
@@ -400,13 +531,23 @@ export class SequelizeAdapter extends AbstractAdapter {
|
|
|
400
531
|
/**Registration of system models*/
|
|
401
532
|
static async registerSystemModels(sequelize) {
|
|
402
533
|
const modelsDir = path.resolve(import.meta.dirname, "../../../../models");
|
|
403
|
-
|
|
534
|
+
let files = fs.readdirSync(modelsDir).filter(f => f.endsWith(".js"));
|
|
535
|
+
if (!files.length) {
|
|
536
|
+
files = fs.readdirSync(modelsDir).filter(f => f.endsWith(".ts") && !f.endsWith(".d.ts"));
|
|
537
|
+
}
|
|
538
|
+
if (!files.length) {
|
|
539
|
+
throw `Model files not found in dir ${modelsDir}`;
|
|
540
|
+
}
|
|
541
|
+
const schemas = {};
|
|
404
542
|
for (const file of files) {
|
|
405
543
|
const modelName = path.basename(file, path.extname(file));
|
|
406
544
|
const filePath = path.resolve(modelsDir, file);
|
|
407
|
-
const
|
|
545
|
+
const mod = await import(pathToFileURL(filePath).href);
|
|
546
|
+
const definition = mod.default;
|
|
547
|
+
schemas[modelName] = definition;
|
|
408
548
|
generateSequelizeModel(sequelize, modelName, definition);
|
|
409
549
|
}
|
|
550
|
+
generateAssociationsFromSchema(sequelize.models, schemas);
|
|
410
551
|
await sequelize.sync();
|
|
411
552
|
}
|
|
412
553
|
}
|
|
@@ -90,10 +90,13 @@ export class WaterlineAdapter extends AbstractAdapter {
|
|
|
90
90
|
/** Method that processes custom waterline model creation. Is used for system models. Replaces beforeCreate method in waterline */
|
|
91
91
|
static async registerSystemModels(waterlineORM) {
|
|
92
92
|
const systemModelsDir = path.resolve(import.meta.dirname, "../../../../models");
|
|
93
|
-
|
|
93
|
+
let systemModelsFiles = fs.readdirSync(systemModelsDir).filter(file => file.endsWith(".js"));
|
|
94
|
+
if (!systemModelsFiles.length) {
|
|
95
|
+
systemModelsFiles = fs.readdirSync(systemModelsDir).filter(file => file.endsWith(".ts") && !file.endsWith(".d.ts"));
|
|
96
|
+
}
|
|
94
97
|
// Register adminizer system models
|
|
95
98
|
await Promise.all(systemModelsFiles.map(async (file) => {
|
|
96
|
-
const modelName = path.basename(file
|
|
99
|
+
const modelName = path.basename(file).replace(/\.(ts|js)$/, "");
|
|
97
100
|
const systemModelPath = path.resolve(systemModelsDir, file);
|
|
98
101
|
const adminizerModel = (await import(pathToFileURL(systemModelPath).href)).default;
|
|
99
102
|
const waterlineLikeModel = generateWaterlineModel(modelName, adminizerModel);
|
|
@@ -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 "
|
|
7
|
-
import { Adminizer } from "
|
|
6
|
+
import { AdminpanelIcon } from "../../../interfaces/adminpanelConfig";
|
|
7
|
+
import { Adminizer } from "../../Adminizer";
|
|
8
8
|
import { UserAP } from "models/UserAP";
|
|
9
|
-
import { I18n } from "../
|
|
9
|
+
import { I18n } from "../I18n";
|
|
10
10
|
export type WidgetType = (SwitcherBase | InfoBase | ActionBase | LinkBase | CustomBase);
|
|
11
11
|
export interface WidgetConfig {
|
|
12
12
|
id: string;
|
|
@@ -36,6 +36,13 @@ export interface WidgetLayoutItem {
|
|
|
36
36
|
i: string;
|
|
37
37
|
id: string;
|
|
38
38
|
}
|
|
39
|
+
export interface WidgetsLayouts {
|
|
40
|
+
lg: WidgetLayoutItem[];
|
|
41
|
+
md: WidgetLayoutItem[];
|
|
42
|
+
sm: WidgetLayoutItem[];
|
|
43
|
+
xs: WidgetLayoutItem[];
|
|
44
|
+
xxs: WidgetLayoutItem[];
|
|
45
|
+
}
|
|
39
46
|
export declare class WidgetHandler {
|
|
40
47
|
private widgets;
|
|
41
48
|
adminizer: Adminizer;
|
|
@@ -46,7 +53,7 @@ export declare class WidgetHandler {
|
|
|
46
53
|
getAll(user: UserAP, i18n: I18n): Promise<WidgetConfig[]>;
|
|
47
54
|
getWidgetsDB(id: number, auth: boolean, i18n: I18n): Promise<{
|
|
48
55
|
widgets: WidgetConfig[];
|
|
49
|
-
layout:
|
|
56
|
+
layout: WidgetsLayouts;
|
|
50
57
|
}>;
|
|
51
58
|
setWidgetsDB(id: number, body: {
|
|
52
59
|
widgets: WidgetConfig[];
|
|
@@ -124,7 +124,7 @@ export class WidgetHandler {
|
|
|
124
124
|
}
|
|
125
125
|
async getWidgetsDB(id, auth, i18n) {
|
|
126
126
|
let user;
|
|
127
|
-
let result = { widgets: [], layout: [] };
|
|
127
|
+
let result = { widgets: [], layout: { lg: [], md: [], sm: [], xs: [], xxs: [] } };
|
|
128
128
|
if (!auth) {
|
|
129
129
|
// TODO refactor CRUD functions for DataAccessor usage
|
|
130
130
|
user = await this.adminizer.modelHandler.model.get("UserAP")?.["_findOne"]({ login: this.adminizer.config.administrator?.login ?? 'admin' });
|
package/models/NavigationAP.d.ts
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
declare const _default: {
|
|
2
2
|
id: {
|
|
3
3
|
type: string;
|
|
4
|
-
|
|
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;
|
package/models/NavigationAP.js
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
export default {
|
|
2
2
|
id: {
|
|
3
|
-
type: "
|
|
4
|
-
|
|
5
|
-
|
|
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",
|
package/models/UserAP.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { WidgetConfig } from "lib/widgets/widgetHandler";
|
|
1
|
+
import { WidgetConfig, WidgetsLayouts } from "lib/v4/widgets/widgetHandler";
|
|
2
2
|
import { GroupAP } from "./GroupAP";
|
|
3
|
-
import { WidgetLayoutItem } from "../assets/js/types";
|
|
4
3
|
declare const _default: {
|
|
5
4
|
id: {
|
|
6
5
|
type: string;
|
|
@@ -71,7 +70,7 @@ export interface UserAP {
|
|
|
71
70
|
groups?: GroupAP[];
|
|
72
71
|
widgets?: {
|
|
73
72
|
widgets: WidgetConfig[];
|
|
74
|
-
layout:
|
|
73
|
+
layout: WidgetsLayouts;
|
|
75
74
|
};
|
|
76
75
|
isConfirmed?: boolean;
|
|
77
76
|
}
|