adminizer 4.2.0-build.49 → 4.2.0-build.51
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/assets/{VanillaJSONEditor-XGIlS4LL.js → VanillaJSONEditor-BsNSMuiI.js} +1 -1
- package/assets/add-BOrwsLPk.js +1 -0
- package/assets/{add-form-BLdLojfl.js → add-form-GQVVok4z.js} +1 -1
- package/assets/add-group-ClEk5H3m.js +1 -0
- package/assets/{add-group-form-_VEBFz_S.js → add-group-form-9dIdiUu3.js} +1 -1
- package/assets/add-user-BCfcjTsJ.js +1 -0
- package/assets/{add-user-form-BFAFyXuz.js → add-user-form-CKEPuXAX.js} +1 -1
- package/assets/{app-CXlohNEv.css → app-DcyaNUqI.css} +1 -1
- package/assets/{app-layout-NMKA6xAa.js → app-layout-MF9D28sb.js} +1 -1
- package/assets/{app-sidebar-C4Y6TSY3.js → app-sidebar-CBCrH_5b.js} +1 -1
- package/assets/app-sidebar-header-CT58bBx6.js +1 -0
- package/assets/app.js +2 -2
- package/assets/{breadcrumbs-D0gGjNVI.js → breadcrumbs-DXFXn-ln.js} +1 -1
- package/assets/{catalog-CEVSwmj8.js → catalog-h5-oFEgK.js} +2 -2
- package/assets/{dashboard-jLbWzL7K.js → dashboard-Ca0PxrpJ.js} +2 -2
- package/assets/{date-picker-SAfAWPoh.js → date-picker-lh34xHZl.js} +1 -1
- package/assets/{del-modal-Dj3n8iVJ.js → del-modal-CwKNFb9U.js} +1 -1
- package/assets/{field-renderer-BlBZuSiD.css → field-renderer-BkNaSbkZ.css} +1 -1
- package/assets/field-renderer-C-zyBIEM.js +411 -0
- package/assets/{form-CYsLdORv.js → form-B30gc4iL.js} +1 -1
- package/assets/form-xJzl5esP.js +1 -0
- package/assets/{handsontable-Dxb-hF7-.js → handsontable-CpTuVOqA.js} +1 -1
- package/assets/home-BrMSrnA_.js +2 -0
- package/assets/{icon-DQL8h8HI.js → icon-CS1X91Nz.js} +1 -1
- package/assets/{init-user-DZtnQ7VL.js → init-user--38KZHls.js} +1 -1
- package/assets/{input-error-BztTAmHq.js → input-error-BkhNs96U.js} +1 -1
- package/assets/list-Da5LZQoi.js +1 -0
- package/assets/{list-table-Du8TTXit.js → list-table-CSB-cBZ7.js} +1 -1
- package/assets/{login-2THGmUHc.js → login-BsyYLvZs.js} +1 -1
- package/assets/manifest.json +102 -80
- package/assets/{material-icon-CPvFwV5P.js → material-icon-08xik4mg.js} +1 -1
- package/assets/module-DF806s6D.js +1 -0
- package/assets/{monaco-editor-9fDiyfuW.js → monaco-editor-Cp_1Q01C.js} +1 -1
- package/assets/{multi-select-e4PqgWYn.js → multi-select-Dd_ADH13.js} +1 -1
- package/assets/nav-footer-CiLx5SB9.js +1 -0
- package/assets/nav-main-DgWcOcOI.js +1 -0
- package/assets/{nav-user-BWl2j-y-.js → nav-user-Cud95A62.js} +1 -1
- package/assets/{pagination-render-D6MBqi0B.js → pagination-render-CsKj8TwQ.js} +1 -1
- package/assets/{register-Dks3YdiZ.js → register-CQhM1bKw.js} +1 -1
- package/assets/theme-switcher-BJSJk_M4.js +1 -0
- package/assets/{toast-editor-1Pul3oMs.js → toast-editor-B9DGyj0_.js} +1 -1
- package/assets/use-appearance-CXP5cHaQ.js +1 -0
- package/assets/{user-info-DTsggabP.js → user-info-BSOJr6JQ.js} +1 -1
- package/assets/{user-menu-content-Dnh2qpwQ.js → user-menu-content-BcKOjCpg.js} +1 -1
- package/assets/welcome-Dq1qVeCh.js +1 -0
- package/helpers/inertiaAddHelper.d.ts +1 -1
- package/helpers/inertiaAddHelper.js +4 -0
- package/lib/Adminizer.js +2 -2
- package/lib/media-manager/DefaultMediaManager.d.ts +18 -0
- package/lib/media-manager/DefaultMediaManager.js +96 -125
- package/lib/media-manager/Items.d.ts +45 -0
- package/lib/media-manager/Items.js +273 -334
- package/lib/v4/DataAccessor.d.ts +1 -0
- package/lib/v4/DataAccessor.js +15 -8
- package/lib/v4/inertia/inertiaAdapter.js +1 -1
- package/lib/v4/model/adapter/sequelize.js +28 -19
- package/lib/v4/model/adapter/waterline.js +12 -4
- package/lib/v4/widgets/abstractCustom.d.ts +1 -1
- package/models/MediaManagerAP.d.ts +62 -0
- package/models/MediaManagerAP.js +45 -0
- package/models/MediaManagerAssociationsAP.d.ts +38 -0
- package/models/MediaManagerAssociationsAP.js +27 -0
- package/models/MediaManagerMetaAP.d.ts +30 -0
- package/models/MediaManagerMetaAP.js +21 -0
- package/package.json +10 -5
- package/system/bindMediaManager.d.ts +2 -0
- package/system/bindMediaManager.js +14 -20
- package/system/bindModels.js +3 -3
- package/assets/add-BzeOQ-DB.js +0 -1
- package/assets/add-group-Bx2s4UXM.js +0 -1
- package/assets/add-user-C3BY-sey.js +0 -1
- package/assets/app-sidebar-header-DQnbMxfM.js +0 -1
- package/assets/field-renderer-C7qCVvAC.js +0 -407
- package/assets/form-DjAQC5zI.js +0 -1
- package/assets/home-DfUM0yKC.js +0 -2
- package/assets/list-B1FodBkq.js +0 -1
- package/assets/module-D55s6p7N.js +0 -1
- package/assets/nav-footer-B7wjmsPb.js +0 -1
- package/assets/nav-main-Cx1BkIzi.js +0 -1
- package/assets/use-appearance-J8J2w43p.js +0 -1
- package/assets/welcome-HFROxPwP.js +0 -1
package/lib/v4/DataAccessor.js
CHANGED
|
@@ -15,6 +15,12 @@ export class DataAccessor {
|
|
|
15
15
|
this.action = action;
|
|
16
16
|
this.actionVerb = getTokenAction(this.action);
|
|
17
17
|
}
|
|
18
|
+
getModelConfig(modelName) {
|
|
19
|
+
const entry = Object.entries(this.adminizer.config.models)
|
|
20
|
+
.find(([key]) => key.toLowerCase() === modelName.toLowerCase());
|
|
21
|
+
const config = entry ? entry[1] : undefined;
|
|
22
|
+
return isObject(config) ? config : undefined;
|
|
23
|
+
}
|
|
18
24
|
/**
|
|
19
25
|
* Retrieves the fields for the given entity based on action type,
|
|
20
26
|
* taking into account access rights and configuration settings.
|
|
@@ -88,10 +94,13 @@ export class DataAccessor {
|
|
|
88
94
|
const model = this.adminizer.modelHandler.model.get(modelName);
|
|
89
95
|
if (model) {
|
|
90
96
|
populatedModelFieldsConfig = this.getAssociatedFieldsConfig(modelName);
|
|
91
|
-
|
|
92
|
-
if (
|
|
93
|
-
|
|
94
|
-
|
|
97
|
+
const modelCfg = this.getModelConfig(modelName);
|
|
98
|
+
if (modelCfg) {
|
|
99
|
+
associatedModelConfig = modelCfg;
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
Adminizer.log.error(`DataAccessor > getFieldsConfig > Model config not found: ${modelName}`);
|
|
103
|
+
}
|
|
95
104
|
}
|
|
96
105
|
else {
|
|
97
106
|
Adminizer.log.error(`DataAccessor > getFieldsConfig > Model not found: ${modelName} when ${key}`);
|
|
@@ -112,7 +121,8 @@ export class DataAccessor {
|
|
|
112
121
|
}
|
|
113
122
|
getAssociatedFieldsConfig(modelName) {
|
|
114
123
|
const model = this.adminizer.modelHandler.model.get(modelName);
|
|
115
|
-
|
|
124
|
+
const modelConfig = this.getModelConfig(modelName);
|
|
125
|
+
if (!model || !modelConfig) {
|
|
116
126
|
return undefined;
|
|
117
127
|
}
|
|
118
128
|
// Check if user has access to the associated model
|
|
@@ -122,9 +132,6 @@ export class DataAccessor {
|
|
|
122
132
|
return undefined;
|
|
123
133
|
}
|
|
124
134
|
const associatedFields = {};
|
|
125
|
-
const modelConfig = this.adminizer.config.models[modelName];
|
|
126
|
-
if (!isObject(modelConfig))
|
|
127
|
-
throw `Type error ModelConfig should is object`;
|
|
128
135
|
// Get the main fields configuration
|
|
129
136
|
const fieldsConfig = modelConfig.fields || {};
|
|
130
137
|
// Merge action-specific fields configuration if it exists
|
|
@@ -14,7 +14,7 @@ const inertiaExpressAdapter = function ({ version, html, flashMessages, enableRe
|
|
|
14
14
|
const csrfToken = randomBytes(32).toString('hex');
|
|
15
15
|
res.cookie('XSRF-TOKEN', csrfToken, {
|
|
16
16
|
httpOnly: false,
|
|
17
|
-
secure:
|
|
17
|
+
secure: process.env.NODE_ENV === 'production' && process.env.CSRF_COOKIE_INSECURE !== '1',
|
|
18
18
|
sameSite: 'lax',
|
|
19
19
|
});
|
|
20
20
|
// Check CSRF token for non-GET requests
|
|
@@ -27,14 +27,23 @@ function generateAssociationsFromSchema(models, schemas) {
|
|
|
27
27
|
}
|
|
28
28
|
// 💡 O:M связь (один ко многим)
|
|
29
29
|
else {
|
|
30
|
+
let foreignKey = `${modelName}Id`;
|
|
31
|
+
if (field.collection === modelName) {
|
|
32
|
+
foreignKey = `${field.via}Id`;
|
|
33
|
+
}
|
|
30
34
|
model.hasMany(targetModel, {
|
|
31
35
|
as: fieldName,
|
|
32
|
-
foreignKey
|
|
33
|
-
});
|
|
34
|
-
targetModel.belongsTo(model, {
|
|
35
|
-
as: field.via,
|
|
36
|
-
foreignKey: `${modelName}Id`,
|
|
36
|
+
foreignKey,
|
|
37
37
|
});
|
|
38
|
+
const alias = field.via;
|
|
39
|
+
const belongsToOptions = { foreignKey };
|
|
40
|
+
if (targetModel.rawAttributes[alias] || targetModel.associations[alias]) {
|
|
41
|
+
belongsToOptions.as = `${alias}Ref`;
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
belongsToOptions.as = alias;
|
|
45
|
+
}
|
|
46
|
+
targetModel.belongsTo(model, belongsToOptions);
|
|
38
47
|
}
|
|
39
48
|
}
|
|
40
49
|
// 💡 O:1 или 1:1 (belongsTo)
|
|
@@ -42,21 +51,18 @@ function generateAssociationsFromSchema(models, schemas) {
|
|
|
42
51
|
const targetModel = models[field.model];
|
|
43
52
|
if (!targetModel)
|
|
44
53
|
continue;
|
|
45
|
-
// Avoid naming
|
|
46
|
-
const foreignKey = `${fieldName}Id`;
|
|
54
|
+
// Avoid naming collisions by using an explicit foreign key
|
|
47
55
|
const alias = fieldName;
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
});
|
|
54
|
-
}
|
|
55
|
-
else {
|
|
56
|
-
model.belongsTo(targetModel, {
|
|
57
|
-
foreignKey: alias, // если нет конфликта, можно использовать alias как FK
|
|
58
|
-
});
|
|
56
|
+
const foreignKey = `${alias}Id`;
|
|
57
|
+
// Reuse the attribute name unless it already exists on the model or association
|
|
58
|
+
let asName = alias;
|
|
59
|
+
if (model.rawAttributes[alias] || model.associations[alias]) {
|
|
60
|
+
asName = `${alias}Ref`;
|
|
59
61
|
}
|
|
62
|
+
model.belongsTo(targetModel, {
|
|
63
|
+
as: asName,
|
|
64
|
+
foreignKey,
|
|
65
|
+
});
|
|
60
66
|
}
|
|
61
67
|
}
|
|
62
68
|
}
|
|
@@ -530,7 +536,10 @@ export class SequelizeAdapter extends AbstractAdapter {
|
|
|
530
536
|
}
|
|
531
537
|
/**Registration of system models*/
|
|
532
538
|
static async registerSystemModels(sequelize) {
|
|
533
|
-
|
|
539
|
+
let modelsDir = path.resolve(import.meta.dirname, "../../../../models");
|
|
540
|
+
if (!fs.existsSync(modelsDir)) {
|
|
541
|
+
modelsDir = path.resolve(import.meta.dirname, "../../../../src/models");
|
|
542
|
+
}
|
|
534
543
|
let files = fs.readdirSync(modelsDir).filter(f => f.endsWith(".js"));
|
|
535
544
|
if (!files.length) {
|
|
536
545
|
files = fs.readdirSync(modelsDir).filter(f => f.endsWith(".ts") && !f.endsWith(".d.ts"));
|
|
@@ -78,10 +78,14 @@ export class WaterlineAdapter extends AbstractAdapter {
|
|
|
78
78
|
return this.orm.ontology.collections;
|
|
79
79
|
}
|
|
80
80
|
getModel(modelName) {
|
|
81
|
-
|
|
81
|
+
const matchedKey = Object.keys(this.orm.ontology.collections).find(key => key.toLowerCase() === modelName.toLowerCase());
|
|
82
|
+
if (!matchedKey) {
|
|
83
|
+
return undefined;
|
|
84
|
+
}
|
|
85
|
+
return this.orm.ontology.collections[matchedKey];
|
|
82
86
|
}
|
|
83
87
|
getAttributes(modelName) {
|
|
84
|
-
const model = this.
|
|
88
|
+
const model = this.getModel(modelName);
|
|
85
89
|
if (!model) {
|
|
86
90
|
throw new Error(`Model "${modelName}" was not found`);
|
|
87
91
|
}
|
|
@@ -89,7 +93,10 @@ export class WaterlineAdapter extends AbstractAdapter {
|
|
|
89
93
|
}
|
|
90
94
|
/** Method that processes custom waterline model creation. Is used for system models. Replaces beforeCreate method in waterline */
|
|
91
95
|
static async registerSystemModels(waterlineORM) {
|
|
92
|
-
|
|
96
|
+
let systemModelsDir = path.resolve(import.meta.dirname, "../../../../models");
|
|
97
|
+
if (!fs.existsSync(systemModelsDir)) {
|
|
98
|
+
systemModelsDir = path.resolve(import.meta.dirname, "../../../../src/models");
|
|
99
|
+
}
|
|
93
100
|
let systemModelsFiles = fs.readdirSync(systemModelsDir).filter(file => file.endsWith(".js"));
|
|
94
101
|
if (!systemModelsFiles.length) {
|
|
95
102
|
systemModelsFiles = fs.readdirSync(systemModelsDir).filter(file => file.endsWith(".ts") && !file.endsWith(".d.ts"));
|
|
@@ -99,11 +106,12 @@ export class WaterlineAdapter extends AbstractAdapter {
|
|
|
99
106
|
const modelName = path.basename(file).replace(/\.(ts|js)$/, "");
|
|
100
107
|
const systemModelPath = path.resolve(systemModelsDir, file);
|
|
101
108
|
const adminizerModel = (await import(pathToFileURL(systemModelPath).href)).default;
|
|
102
|
-
const waterlineLikeModel = generateWaterlineModel(modelName, adminizerModel);
|
|
109
|
+
const waterlineLikeModel = generateWaterlineModel(modelName, structuredClone(adminizerModel));
|
|
103
110
|
// Register model in Waterline ORM
|
|
104
111
|
waterlineORM.registerModel(waterlineLikeModel);
|
|
105
112
|
}));
|
|
106
113
|
function generateWaterlineModel(modelName, attributes) {
|
|
114
|
+
attributes = JSON.parse(JSON.stringify(attributes));
|
|
107
115
|
const primaryKey = Object.keys(attributes).find(fieldName => attributes[fieldName]?.primaryKey === true);
|
|
108
116
|
if (!primaryKey) {
|
|
109
117
|
throw new Error(`Model "${modelName}" must have a primary key.`);
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { MediaManagerAssociationsAP } from "./MediaManagerAssociationsAP";
|
|
2
|
+
import { MediaManagerMetaAP } from "./MediaManagerMetaAP";
|
|
3
|
+
declare const _default: {
|
|
4
|
+
id: {
|
|
5
|
+
type: string;
|
|
6
|
+
allowNull: boolean;
|
|
7
|
+
uuid: boolean;
|
|
8
|
+
primaryKey: boolean;
|
|
9
|
+
required: boolean;
|
|
10
|
+
};
|
|
11
|
+
parent: {
|
|
12
|
+
model: string;
|
|
13
|
+
};
|
|
14
|
+
variants: {
|
|
15
|
+
collection: string;
|
|
16
|
+
via: string;
|
|
17
|
+
};
|
|
18
|
+
mimeType: {
|
|
19
|
+
type: string;
|
|
20
|
+
};
|
|
21
|
+
path: {
|
|
22
|
+
type: string;
|
|
23
|
+
};
|
|
24
|
+
size: {
|
|
25
|
+
type: string;
|
|
26
|
+
};
|
|
27
|
+
group: {
|
|
28
|
+
type: string;
|
|
29
|
+
};
|
|
30
|
+
tag: {
|
|
31
|
+
type: string;
|
|
32
|
+
};
|
|
33
|
+
url: {
|
|
34
|
+
type: string;
|
|
35
|
+
};
|
|
36
|
+
filename: {
|
|
37
|
+
type: string;
|
|
38
|
+
};
|
|
39
|
+
meta: {
|
|
40
|
+
collection: string;
|
|
41
|
+
via: string;
|
|
42
|
+
};
|
|
43
|
+
modelAssociation: {
|
|
44
|
+
collection: string;
|
|
45
|
+
via: string;
|
|
46
|
+
};
|
|
47
|
+
};
|
|
48
|
+
export default _default;
|
|
49
|
+
export interface MediaManagerAP {
|
|
50
|
+
id: string;
|
|
51
|
+
parent?: MediaManagerAP;
|
|
52
|
+
variants?: MediaManagerAP[];
|
|
53
|
+
mimeType?: string;
|
|
54
|
+
path?: string;
|
|
55
|
+
size?: number;
|
|
56
|
+
group?: string;
|
|
57
|
+
tag?: string;
|
|
58
|
+
url?: string;
|
|
59
|
+
filename?: string;
|
|
60
|
+
meta?: MediaManagerMetaAP[];
|
|
61
|
+
modelAssociation?: MediaManagerAssociationsAP[];
|
|
62
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
id: {
|
|
3
|
+
type: "string",
|
|
4
|
+
allowNull: false,
|
|
5
|
+
uuid: true,
|
|
6
|
+
primaryKey: true,
|
|
7
|
+
required: true
|
|
8
|
+
},
|
|
9
|
+
parent: {
|
|
10
|
+
model: "MediaManagerAP"
|
|
11
|
+
},
|
|
12
|
+
variants: {
|
|
13
|
+
collection: "MediaManagerAP",
|
|
14
|
+
via: "parent"
|
|
15
|
+
},
|
|
16
|
+
mimeType: {
|
|
17
|
+
type: "string"
|
|
18
|
+
},
|
|
19
|
+
path: {
|
|
20
|
+
type: "string"
|
|
21
|
+
},
|
|
22
|
+
size: {
|
|
23
|
+
type: "number"
|
|
24
|
+
},
|
|
25
|
+
group: {
|
|
26
|
+
type: "string"
|
|
27
|
+
},
|
|
28
|
+
tag: {
|
|
29
|
+
type: "string"
|
|
30
|
+
},
|
|
31
|
+
url: {
|
|
32
|
+
type: "string"
|
|
33
|
+
},
|
|
34
|
+
filename: {
|
|
35
|
+
type: "string"
|
|
36
|
+
},
|
|
37
|
+
meta: {
|
|
38
|
+
collection: "MediaManagerMetaAP",
|
|
39
|
+
via: "parent"
|
|
40
|
+
},
|
|
41
|
+
modelAssociation: {
|
|
42
|
+
collection: "MediaManagerAssociationsAP",
|
|
43
|
+
via: "file"
|
|
44
|
+
}
|
|
45
|
+
};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { MediaManagerAP } from "./MediaManagerAP";
|
|
2
|
+
declare const _default: {
|
|
3
|
+
id: {
|
|
4
|
+
type: string;
|
|
5
|
+
allowNull: boolean;
|
|
6
|
+
uuid: boolean;
|
|
7
|
+
primaryKey: boolean;
|
|
8
|
+
required: boolean;
|
|
9
|
+
};
|
|
10
|
+
mediaManagerId: {
|
|
11
|
+
type: string;
|
|
12
|
+
};
|
|
13
|
+
model: {
|
|
14
|
+
type: string;
|
|
15
|
+
};
|
|
16
|
+
modelId: {
|
|
17
|
+
type: string;
|
|
18
|
+
};
|
|
19
|
+
widgetName: {
|
|
20
|
+
type: string;
|
|
21
|
+
};
|
|
22
|
+
sortOrder: {
|
|
23
|
+
type: string;
|
|
24
|
+
};
|
|
25
|
+
file: {
|
|
26
|
+
model: string;
|
|
27
|
+
};
|
|
28
|
+
};
|
|
29
|
+
export default _default;
|
|
30
|
+
export interface MediaManagerAssociationsAP {
|
|
31
|
+
id: string;
|
|
32
|
+
mediaManagerId?: string;
|
|
33
|
+
model?: Record<string, unknown>;
|
|
34
|
+
modelId?: Record<string, unknown>;
|
|
35
|
+
widgetName?: string;
|
|
36
|
+
sortOrder?: number;
|
|
37
|
+
file?: MediaManagerAP;
|
|
38
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
id: {
|
|
3
|
+
type: "string",
|
|
4
|
+
allowNull: false,
|
|
5
|
+
uuid: true,
|
|
6
|
+
primaryKey: true,
|
|
7
|
+
required: true
|
|
8
|
+
},
|
|
9
|
+
mediaManagerId: {
|
|
10
|
+
type: "string"
|
|
11
|
+
},
|
|
12
|
+
model: {
|
|
13
|
+
type: "json"
|
|
14
|
+
},
|
|
15
|
+
modelId: {
|
|
16
|
+
type: "json"
|
|
17
|
+
},
|
|
18
|
+
widgetName: {
|
|
19
|
+
type: "string"
|
|
20
|
+
},
|
|
21
|
+
sortOrder: {
|
|
22
|
+
type: "number"
|
|
23
|
+
},
|
|
24
|
+
file: {
|
|
25
|
+
model: "MediaManagerAP"
|
|
26
|
+
}
|
|
27
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { MediaManagerAP } from "./MediaManagerAP";
|
|
2
|
+
declare const _default: {
|
|
3
|
+
id: {
|
|
4
|
+
type: string;
|
|
5
|
+
allowNull: boolean;
|
|
6
|
+
uuid: boolean;
|
|
7
|
+
primaryKey: boolean;
|
|
8
|
+
required: boolean;
|
|
9
|
+
};
|
|
10
|
+
key: {
|
|
11
|
+
type: string;
|
|
12
|
+
};
|
|
13
|
+
value: {
|
|
14
|
+
type: string;
|
|
15
|
+
};
|
|
16
|
+
isPublic: {
|
|
17
|
+
type: string;
|
|
18
|
+
};
|
|
19
|
+
parent: {
|
|
20
|
+
model: string;
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
export default _default;
|
|
24
|
+
export interface MediaManagerMetaAP {
|
|
25
|
+
id: string;
|
|
26
|
+
key?: string;
|
|
27
|
+
value?: Record<string, unknown>;
|
|
28
|
+
isPublic?: boolean;
|
|
29
|
+
parent?: MediaManagerAP;
|
|
30
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
id: {
|
|
3
|
+
type: "string",
|
|
4
|
+
allowNull: false,
|
|
5
|
+
uuid: true,
|
|
6
|
+
primaryKey: true,
|
|
7
|
+
required: true
|
|
8
|
+
},
|
|
9
|
+
key: {
|
|
10
|
+
type: "string"
|
|
11
|
+
},
|
|
12
|
+
value: {
|
|
13
|
+
type: "json"
|
|
14
|
+
},
|
|
15
|
+
isPublic: {
|
|
16
|
+
type: "boolean"
|
|
17
|
+
},
|
|
18
|
+
parent: {
|
|
19
|
+
model: "MediaManagerAP"
|
|
20
|
+
}
|
|
21
|
+
};
|
package/package.json
CHANGED
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "adminizer",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "4.2.0-build.
|
|
4
|
+
"version": "4.2.0-build.51",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"exports": {
|
|
7
7
|
".": "./index.js",
|
|
8
8
|
"./ui/*": "./dist/ui/components/ui/*.js"
|
|
9
9
|
},
|
|
10
10
|
"scripts": {
|
|
11
|
-
"test": "vitest --
|
|
11
|
+
"test": "vitest --watch=false",
|
|
12
|
+
"test:watch": "vitest --reporter verbose",
|
|
12
13
|
"start": "cross-env NO_SEED_DATA=true ORM=sequelize tsx --tsconfig ./fixture/tsconfig.json ./fixture/index.ts",
|
|
13
|
-
"dev": "cross-env VITE_ENV=dev tsx watch --tsconfig ./fixture/tsconfig.json ./fixture/index.ts",
|
|
14
|
-
"dev:
|
|
14
|
+
"dev": "cross-env VITE_ENV=dev ORM=sequelize tsx watch --tsconfig ./fixture/tsconfig.json ./fixture/index.ts",
|
|
15
|
+
"dev:waterline": "cross-env VITE_ENV=dev ORM=waterline tsx watch --tsconfig ./fixture/tsconfig.json ./fixture/index.ts",
|
|
15
16
|
"build:assets": "vite build",
|
|
16
17
|
"compile:backend": "tsc -p src/tsconfig.json",
|
|
17
18
|
"compile:ui": "tsc -p tsconfig.ui.json",
|
|
@@ -46,10 +47,12 @@
|
|
|
46
47
|
"express": "^4.21.2",
|
|
47
48
|
"express-session": "^1.18.1",
|
|
48
49
|
"jsonwebtoken": "^9.0.2",
|
|
50
|
+
"material-icons": "^1.13.14",
|
|
49
51
|
"multer": "^1.4.5-lts.1",
|
|
50
52
|
"next-themes": "^0.4.6",
|
|
51
53
|
"password-hash": "^1.2.2",
|
|
52
54
|
"react-dnd": "^16.0.1",
|
|
55
|
+
"reflect-metadata": "^0.2.2",
|
|
53
56
|
"sharp": "^0.33.5",
|
|
54
57
|
"typeorm": "^0.3.20",
|
|
55
58
|
"uuid": "^11.0.5",
|
|
@@ -59,6 +62,8 @@
|
|
|
59
62
|
"devDependencies": {
|
|
60
63
|
"@babel/plugin-proposal-decorators": "^7.27.1",
|
|
61
64
|
"@ckeditor/ckeditor5-react": "^9.5.0",
|
|
65
|
+
"@dnd-kit/core": "^6.3.1",
|
|
66
|
+
"@dnd-kit/sortable": "^10.0.0",
|
|
62
67
|
"@eslint/compat": "^1.2.9",
|
|
63
68
|
"@faker-js/faker": "^9.7.0",
|
|
64
69
|
"@handsontable/react": "^15.2.0",
|
|
@@ -110,13 +115,13 @@
|
|
|
110
115
|
"cross-env": "^7.0.3",
|
|
111
116
|
"eslint": "^9.26.0",
|
|
112
117
|
"handsontable": "^15.2.0",
|
|
118
|
+
"image-size": "^2.0.2",
|
|
113
119
|
"isomorphic-webcrypto": "^2.3.8",
|
|
114
120
|
"json-schema": "^0.4.0",
|
|
115
121
|
"leaflet": "^1.9.4",
|
|
116
122
|
"leaflet-draw": "^1.0.4",
|
|
117
123
|
"lodash-es": "^4.17.21",
|
|
118
124
|
"lucide-react": "^0.485.0",
|
|
119
|
-
"material-icons": "^1.13.14",
|
|
120
125
|
"react": "^19.0.0",
|
|
121
126
|
"react-day-picker": "^8.10.1",
|
|
122
127
|
"react-dom": "^19.0.0",
|
|
@@ -1,20 +1,14 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
//
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
//
|
|
16
|
-
// MediaManagerHandler.add(mediaManager)
|
|
17
|
-
// } catch (e) {
|
|
18
|
-
// }
|
|
19
|
-
// })
|
|
20
|
-
// }
|
|
1
|
+
import { DefaultMediaManager } from "../lib/media-manager/DefaultMediaManager";
|
|
2
|
+
import { MediaManagerHandler } from "../lib/media-manager/MediaManagerHandler";
|
|
3
|
+
export default function bindMediaManager(adminizer) {
|
|
4
|
+
adminizer.emitter.on("orm:loaded", async () => {
|
|
5
|
+
try {
|
|
6
|
+
// TODO paths problem, default media manager path should be get by config
|
|
7
|
+
let mediaManager = new DefaultMediaManager(adminizer, 'default', 'media-manager', `${process.cwd()}/.tmp/public/media-manager/`);
|
|
8
|
+
MediaManagerHandler.add(mediaManager);
|
|
9
|
+
}
|
|
10
|
+
catch (e) {
|
|
11
|
+
console.log(e);
|
|
12
|
+
}
|
|
13
|
+
});
|
|
14
|
+
}
|
package/system/bindModels.js
CHANGED
|
@@ -15,7 +15,7 @@ export default async function bindModels(adminizer) {
|
|
|
15
15
|
const systemModelsFiles = fs.readdirSync(systemModelsDir).filter(file => (file.endsWith(".js") || (file.endsWith(".ts") && !file.endsWith(".d.ts"))));
|
|
16
16
|
// Bind system models reading them from ../models and get the whole list of them for further checks
|
|
17
17
|
const systemModels = systemModelsFiles.map((file) => {
|
|
18
|
-
const modelName = path.basename(file, path.extname(file)); //
|
|
18
|
+
const modelName = path.basename(file, path.extname(file)); // remove extension
|
|
19
19
|
const ormAdapter = adminizer.getOrmAdapter(defaultOrmAdapter);
|
|
20
20
|
// Create model adapter instance and add it to model handler
|
|
21
21
|
const registeredModel = ormAdapter.getModel(modelName.toLowerCase());
|
|
@@ -29,14 +29,14 @@ export default async function bindModels(adminizer) {
|
|
|
29
29
|
modelsFromConfig.forEach((modelName) => {
|
|
30
30
|
const modelConfig = Object.entries(adminizer.config.models)
|
|
31
31
|
.find(([key, value]) => value && typeof value !== "boolean" && value.model.toLowerCase() === modelName)?.[1];
|
|
32
|
-
if (!systemModels.includes(modelName)) {
|
|
32
|
+
if (!systemModels.includes(modelName.toLowerCase())) {
|
|
33
33
|
const adapterName = typeof modelConfig !== "boolean" ? modelConfig?.adapter || defaultOrmAdapter : defaultOrmAdapter;
|
|
34
34
|
const ormAdapter = adminizer.getOrmAdapter(adapterName);
|
|
35
35
|
if (!ormAdapter) {
|
|
36
36
|
throw new Error(`Adapter ${adapterName} was not found for model ${modelName}. Please check your configuration`);
|
|
37
37
|
}
|
|
38
38
|
// Create model adapter instance and add it to model handler
|
|
39
|
-
const registeredModel = ormAdapter.getModel(modelName);
|
|
39
|
+
const registeredModel = ormAdapter.getModel(modelName.toLowerCase());
|
|
40
40
|
if (!registeredModel) {
|
|
41
41
|
throw `Bind models > Model not found: ${modelName}`;
|
|
42
42
|
}
|
package/assets/add-BzeOQ-DB.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{c as p,q as i,j as m}from"./app.js";import{A as s}from"./app-layout-NMKA6xAa.js";import e from"./add-form-BLdLojfl.js";import"./app-shell-Dd-kA5uc.js";import"./app-sidebar-C4Y6TSY3.js";import"./nav-main-Cx1BkIzi.js";import"./material-icon-CPvFwV5P.js";import"./app-sidebar-header-DQnbMxfM.js";import"./breadcrumbs-D0gGjNVI.js";import"./nav-user-BWl2j-y-.js";import"./user-info-DTsggabP.js";import"./user-menu-content-Dnh2qpwQ.js";import"./icon-DQL8h8HI.js";import"./use-appearance-J8J2w43p.js";import"./field-renderer-C7qCVvAC.js";import"./dynamic-controls-CSVVCONh.js";import"./multi-select-e4PqgWYn.js";import"./form-state-702tb_BV.js";import"./input-error-BztTAmHq.js";const a=[];function k(){const t=p.c(2),r=i();let o;return t[0]!==r?(o=m.jsx(s,{breadcrumbs:a,children:m.jsx(e,{page:r,catalog:!1})}),t[0]=r,t[1]=o):o=t[1],o}export{k as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{c as m,j as t}from"./app.js";import{A as p}from"./app-layout-NMKA6xAa.js";import i from"./add-group-form-_VEBFz_S.js";import"./app-shell-Dd-kA5uc.js";import"./app-sidebar-C4Y6TSY3.js";import"./nav-main-Cx1BkIzi.js";import"./material-icon-CPvFwV5P.js";import"./app-sidebar-header-DQnbMxfM.js";import"./breadcrumbs-D0gGjNVI.js";import"./nav-user-BWl2j-y-.js";import"./user-info-DTsggabP.js";import"./user-menu-content-Dnh2qpwQ.js";import"./icon-DQL8h8HI.js";import"./use-appearance-J8J2w43p.js";const e=[];function E(){const r=m.c(1);let o;return r[0]===Symbol.for("react.memo_cache_sentinel")?(o=t.jsx(p,{breadcrumbs:e,children:t.jsx(i,{})}),r[0]=o):o=r[0],o}export{E as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{c as m,j as t}from"./app.js";import{A as i}from"./app-layout-NMKA6xAa.js";import p from"./add-user-form-BFAFyXuz.js";import"./app-shell-Dd-kA5uc.js";import"./app-sidebar-C4Y6TSY3.js";import"./nav-main-Cx1BkIzi.js";import"./material-icon-CPvFwV5P.js";import"./app-sidebar-header-DQnbMxfM.js";import"./breadcrumbs-D0gGjNVI.js";import"./nav-user-BWl2j-y-.js";import"./user-info-DTsggabP.js";import"./user-menu-content-Dnh2qpwQ.js";import"./icon-DQL8h8HI.js";import"./use-appearance-J8J2w43p.js";import"./input-error-BztTAmHq.js";const e=[];function R(){const o=m.c(1);let r;return o[0]===Symbol.for("react.memo_cache_sentinel")?(r=t.jsx(i,{breadcrumbs:e,children:t.jsx(p,{})}),o[0]=r):r=o[0],r}export{R as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{c as u,j as s,ae as j,af as g,ag as N,B as w}from"./app.js";import{Breadcrumbs as v}from"./breadcrumbs-D0gGjNVI.js";import{NavUser as S}from"./nav-user-BWl2j-y-.js";import{Icon as x}from"./icon-DQL8h8HI.js";import{u as k}from"./use-appearance-J8J2w43p.js";import"./user-info-DTsggabP.js";import"./user-menu-content-Dnh2qpwQ.js";function C(b){const e=u.c(19),{breadcrumbs:c}=b;let n;e[0]!==c?(n=c===void 0?[]:c,e[0]=c,e[1]=n):n=e[1];const f=n,{appearance:r,updateAppearance:h}=k();let m;e[2]===Symbol.for("react.memo_cache_sentinel")?(m=s.jsx(j,{className:"-ml-1"}),e[2]=m):m=e[2];let t;e[3]!==f?(t=s.jsxs("div",{className:"flex items-center gap-2",children:[m,s.jsx(v,{breadcrumbs:f})]}),e[3]=f,e[4]=t):t=e[4];let a;e[5]!==r||e[6]!==h?(a=()=>h(r==="light"?"dark":"light"),e[5]=r,e[6]=h,e[7]=a):a=e[7];let i;e[8]!==r?(i=r==="light"?s.jsx(x,{iconNode:g,className:"h-2 w-2"}):s.jsx(x,{iconNode:N,className:"h-2 w-2 text-white"}),e[8]=r,e[9]=i):i=e[9];let l;e[10]!==a||e[11]!==i?(l=s.jsx(w,{variant:"ghost",size:"icon",className:"shrink-0 cursor-pointer",onClick:a,children:i}),e[10]=a,e[11]=i,e[12]=l):l=e[12];let p;e[13]===Symbol.for("react.memo_cache_sentinel")?(p=s.jsx(S,{}),e[13]=p):p=e[13];let o;e[14]!==l?(o=s.jsxs("div",{className:"flex gap-4 items-center",children:[l,p]}),e[14]=l,e[15]=o):o=e[15];let d;return e[16]!==t||e[17]!==o?(d=s.jsx("header",{className:"border-sidebar-border/50 flex h-16 shrink-0 items-center gap-2 border-b px-6 transition-[width,height] ease-linear group-has-data-[collapsible=icon]/sidebar-wrapper:h-12 md:px-4",children:s.jsxs("div",{className:"flex justify-between w-full",children:[t,o]})}),e[16]=t,e[17]=o,e[18]=d):d=e[18],d}export{C as AppSidebarHeader};
|