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.
Files changed (81) hide show
  1. package/assets/{VanillaJSONEditor-XGIlS4LL.js → VanillaJSONEditor-BsNSMuiI.js} +1 -1
  2. package/assets/add-BOrwsLPk.js +1 -0
  3. package/assets/{add-form-BLdLojfl.js → add-form-GQVVok4z.js} +1 -1
  4. package/assets/add-group-ClEk5H3m.js +1 -0
  5. package/assets/{add-group-form-_VEBFz_S.js → add-group-form-9dIdiUu3.js} +1 -1
  6. package/assets/add-user-BCfcjTsJ.js +1 -0
  7. package/assets/{add-user-form-BFAFyXuz.js → add-user-form-CKEPuXAX.js} +1 -1
  8. package/assets/{app-CXlohNEv.css → app-DcyaNUqI.css} +1 -1
  9. package/assets/{app-layout-NMKA6xAa.js → app-layout-MF9D28sb.js} +1 -1
  10. package/assets/{app-sidebar-C4Y6TSY3.js → app-sidebar-CBCrH_5b.js} +1 -1
  11. package/assets/app-sidebar-header-CT58bBx6.js +1 -0
  12. package/assets/app.js +2 -2
  13. package/assets/{breadcrumbs-D0gGjNVI.js → breadcrumbs-DXFXn-ln.js} +1 -1
  14. package/assets/{catalog-CEVSwmj8.js → catalog-h5-oFEgK.js} +2 -2
  15. package/assets/{dashboard-jLbWzL7K.js → dashboard-Ca0PxrpJ.js} +2 -2
  16. package/assets/{date-picker-SAfAWPoh.js → date-picker-lh34xHZl.js} +1 -1
  17. package/assets/{del-modal-Dj3n8iVJ.js → del-modal-CwKNFb9U.js} +1 -1
  18. package/assets/{field-renderer-BlBZuSiD.css → field-renderer-BkNaSbkZ.css} +1 -1
  19. package/assets/field-renderer-C-zyBIEM.js +411 -0
  20. package/assets/{form-CYsLdORv.js → form-B30gc4iL.js} +1 -1
  21. package/assets/form-xJzl5esP.js +1 -0
  22. package/assets/{handsontable-Dxb-hF7-.js → handsontable-CpTuVOqA.js} +1 -1
  23. package/assets/home-BrMSrnA_.js +2 -0
  24. package/assets/{icon-DQL8h8HI.js → icon-CS1X91Nz.js} +1 -1
  25. package/assets/{init-user-DZtnQ7VL.js → init-user--38KZHls.js} +1 -1
  26. package/assets/{input-error-BztTAmHq.js → input-error-BkhNs96U.js} +1 -1
  27. package/assets/list-Da5LZQoi.js +1 -0
  28. package/assets/{list-table-Du8TTXit.js → list-table-CSB-cBZ7.js} +1 -1
  29. package/assets/{login-2THGmUHc.js → login-BsyYLvZs.js} +1 -1
  30. package/assets/manifest.json +102 -80
  31. package/assets/{material-icon-CPvFwV5P.js → material-icon-08xik4mg.js} +1 -1
  32. package/assets/module-DF806s6D.js +1 -0
  33. package/assets/{monaco-editor-9fDiyfuW.js → monaco-editor-Cp_1Q01C.js} +1 -1
  34. package/assets/{multi-select-e4PqgWYn.js → multi-select-Dd_ADH13.js} +1 -1
  35. package/assets/nav-footer-CiLx5SB9.js +1 -0
  36. package/assets/nav-main-DgWcOcOI.js +1 -0
  37. package/assets/{nav-user-BWl2j-y-.js → nav-user-Cud95A62.js} +1 -1
  38. package/assets/{pagination-render-D6MBqi0B.js → pagination-render-CsKj8TwQ.js} +1 -1
  39. package/assets/{register-Dks3YdiZ.js → register-CQhM1bKw.js} +1 -1
  40. package/assets/theme-switcher-BJSJk_M4.js +1 -0
  41. package/assets/{toast-editor-1Pul3oMs.js → toast-editor-B9DGyj0_.js} +1 -1
  42. package/assets/use-appearance-CXP5cHaQ.js +1 -0
  43. package/assets/{user-info-DTsggabP.js → user-info-BSOJr6JQ.js} +1 -1
  44. package/assets/{user-menu-content-Dnh2qpwQ.js → user-menu-content-BcKOjCpg.js} +1 -1
  45. package/assets/welcome-Dq1qVeCh.js +1 -0
  46. package/helpers/inertiaAddHelper.d.ts +1 -1
  47. package/helpers/inertiaAddHelper.js +4 -0
  48. package/lib/Adminizer.js +2 -2
  49. package/lib/media-manager/DefaultMediaManager.d.ts +18 -0
  50. package/lib/media-manager/DefaultMediaManager.js +96 -125
  51. package/lib/media-manager/Items.d.ts +45 -0
  52. package/lib/media-manager/Items.js +273 -334
  53. package/lib/v4/DataAccessor.d.ts +1 -0
  54. package/lib/v4/DataAccessor.js +15 -8
  55. package/lib/v4/inertia/inertiaAdapter.js +1 -1
  56. package/lib/v4/model/adapter/sequelize.js +28 -19
  57. package/lib/v4/model/adapter/waterline.js +12 -4
  58. package/lib/v4/widgets/abstractCustom.d.ts +1 -1
  59. package/models/MediaManagerAP.d.ts +62 -0
  60. package/models/MediaManagerAP.js +45 -0
  61. package/models/MediaManagerAssociationsAP.d.ts +38 -0
  62. package/models/MediaManagerAssociationsAP.js +27 -0
  63. package/models/MediaManagerMetaAP.d.ts +30 -0
  64. package/models/MediaManagerMetaAP.js +21 -0
  65. package/package.json +10 -5
  66. package/system/bindMediaManager.d.ts +2 -0
  67. package/system/bindMediaManager.js +14 -20
  68. package/system/bindModels.js +3 -3
  69. package/assets/add-BzeOQ-DB.js +0 -1
  70. package/assets/add-group-Bx2s4UXM.js +0 -1
  71. package/assets/add-user-C3BY-sey.js +0 -1
  72. package/assets/app-sidebar-header-DQnbMxfM.js +0 -1
  73. package/assets/field-renderer-C7qCVvAC.js +0 -407
  74. package/assets/form-DjAQC5zI.js +0 -1
  75. package/assets/home-DfUM0yKC.js +0 -2
  76. package/assets/list-B1FodBkq.js +0 -1
  77. package/assets/module-D55s6p7N.js +0 -1
  78. package/assets/nav-footer-B7wjmsPb.js +0 -1
  79. package/assets/nav-main-Cx1BkIzi.js +0 -1
  80. package/assets/use-appearance-J8J2w43p.js +0 -1
  81. package/assets/welcome-HFROxPwP.js +0 -1
@@ -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
- let _modelConfig = this.adminizer.config.models[modelName];
92
- if (!isObject(_modelConfig))
93
- throw `type error: model config of ${modelName} is ${typeof (this.adminizer.config.models[modelName])} expected object`;
94
- associatedModelConfig = _modelConfig;
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
- if (!model || !this.adminizer.config.models[modelName] || typeof this.adminizer.config.models[modelName] === "boolean") {
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: true,
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: `${modelName}Id`,
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 collision by making FK explicit: `${fieldName}Id`
46
- const foreignKey = `${fieldName}Id`;
54
+ // Avoid naming collisions by using an explicit foreign key
47
55
  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
- });
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
- const modelsDir = path.resolve(import.meta.dirname, "../../../../models");
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
- return this.orm.ontology.collections[modelName];
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.orm.ontology.collections[modelName];
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
- const systemModelsDir = path.resolve(import.meta.dirname, "../../../../models");
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.`);
@@ -1,4 +1,4 @@
1
- import { MaterialIcon } from "material-icons";
1
+ import { MaterialIcon } from "../../../interfaces/MaaterialIcons";
2
2
  export default abstract class CustomBase {
3
3
  /** Widget unique id */
4
4
  abstract readonly id: string;
@@ -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.49",
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 --reporter verbose",
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:sequelize": "cross-env VITE_ENV=dev NO_SEED_DATA=true ORM=sequelize tsx watch --tsconfig ./fixture/tsconfig.json ./fixture/index.ts",
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",
@@ -0,0 +1,2 @@
1
+ import { Adminizer } from "../lib/Adminizer";
2
+ export default function bindMediaManager(adminizer: Adminizer): void;
@@ -1,20 +1,14 @@
1
- "use strict";
2
- // import { DefaultMediaManager } from "../lib/media-manager/DefaultMediaManager";
3
- // import { MediaManagerHandler } from "../lib/media-manager/MediaManagerHandler";
4
- // import {Adminizer} from "../lib/Adminizer";
5
- //
6
- // export default function bindMediaManager(adminizer: Adminizer) {
7
- // adminizer.emitter.on("orm:loaded", async () => {
8
- // try {
9
- // // TODO paths problem, default media manager path should be get by config
10
- // let mediaManager = new DefaultMediaManager(
11
- // adminizer,
12
- // 'default',
13
- // 'media-manager',
14
- // `${process.cwd()}/.tmp/public/media-manager/`)
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
+ }
@@ -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)); // убираем .js/.ts
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
  }
@@ -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};