@empty-complete-org/medusa-product-attributes 0.11.1 → 0.12.0
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/.medusa/server/src/admin/index.js +22 -6
- package/.medusa/server/src/admin/index.mjs +22 -6
- package/.medusa/server/src/modules/product-attributes/migrations/Migration20260405120000.d.ts +5 -0
- package/.medusa/server/src/modules/product-attributes/migrations/Migration20260405120000.js +73 -0
- package/.medusa/server/src/modules/product-attributes/migrations/Migration20260405120000.js.map +1 -0
- package/package.json +4 -1
|
@@ -14,7 +14,7 @@ const sdk = new Medusa__default.default({
|
|
|
14
14
|
type: "session"
|
|
15
15
|
}
|
|
16
16
|
});
|
|
17
|
-
const emptyForm = () => ({ label: "", type: "text" });
|
|
17
|
+
const emptyForm = () => ({ label: "", type: "text", unit: "" });
|
|
18
18
|
const CategoryAttributeTemplatesWidget = ({
|
|
19
19
|
data
|
|
20
20
|
}) => {
|
|
@@ -65,10 +65,11 @@ const CategoryAttributeTemplatesWidget = ({
|
|
|
65
65
|
if (!addForm.label.trim()) return;
|
|
66
66
|
createMutation.mutate({
|
|
67
67
|
label: addForm.label.trim(),
|
|
68
|
-
type: addForm.type
|
|
68
|
+
type: addForm.type,
|
|
69
|
+
unit: addForm.type === "number" && addForm.unit.trim() ? addForm.unit.trim() : null
|
|
69
70
|
});
|
|
70
71
|
};
|
|
71
|
-
const typeLabel = (t) => t === "text" ? "Текст" : t === "number" ? "Число" : t;
|
|
72
|
+
const typeLabel = (t) => t === "text" ? "Текст" : t === "number" ? "Число" : t === "file" ? "Файл" : t === "boolean" ? "Да/Нет" : t;
|
|
72
73
|
return /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: "divide-y p-0", children: [
|
|
73
74
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between px-6 py-4", children: [
|
|
74
75
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", children: "Атрибуты" }),
|
|
@@ -92,7 +93,10 @@ const CategoryAttributeTemplatesWidget = ({
|
|
|
92
93
|
className: "flex items-center gap-3 px-6 py-3",
|
|
93
94
|
children: [
|
|
94
95
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-1 text-sm text-ui-fg-subtle", children: attr.label }),
|
|
95
|
-
/* @__PURE__ */ jsxRuntime.
|
|
96
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.Badge, { size: "2xsmall", color: "grey", children: [
|
|
97
|
+
typeLabel(attr.type),
|
|
98
|
+
attr.unit ? `, ${attr.unit}` : ""
|
|
99
|
+
] }),
|
|
96
100
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Badge, { size: "2xsmall", color: "blue", children: "из родителя" })
|
|
97
101
|
]
|
|
98
102
|
},
|
|
@@ -173,15 +177,27 @@ const CategoryAttributeTemplatesWidget = ({
|
|
|
173
177
|
value: addForm.type,
|
|
174
178
|
onChange: (e) => setAddForm((f) => ({
|
|
175
179
|
...f,
|
|
176
|
-
type: e.target.value
|
|
180
|
+
type: e.target.value,
|
|
181
|
+
unit: e.target.value === "number" ? f.unit : ""
|
|
177
182
|
})),
|
|
178
183
|
className: "h-8 rounded border border-ui-border-base bg-ui-bg-base px-2 text-sm",
|
|
179
184
|
children: [
|
|
180
185
|
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "text", children: "Текст" }),
|
|
181
|
-
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "number", children: "Число" })
|
|
186
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "number", children: "Число" }),
|
|
187
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "file", children: "Файл" }),
|
|
188
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "boolean", children: "Да/Нет" })
|
|
182
189
|
]
|
|
183
190
|
}
|
|
184
191
|
),
|
|
192
|
+
addForm.type === "number" && /* @__PURE__ */ jsxRuntime.jsx(
|
|
193
|
+
ui.Input,
|
|
194
|
+
{
|
|
195
|
+
value: addForm.unit,
|
|
196
|
+
onChange: (e) => setAddForm((f) => ({ ...f, unit: e.target.value })),
|
|
197
|
+
placeholder: "ед. (кг, м, шт...)",
|
|
198
|
+
className: "w-28 h-8 text-sm"
|
|
199
|
+
}
|
|
200
|
+
),
|
|
185
201
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
186
202
|
ui.Button,
|
|
187
203
|
{
|
|
@@ -11,7 +11,7 @@ const sdk = new Medusa({
|
|
|
11
11
|
type: "session"
|
|
12
12
|
}
|
|
13
13
|
});
|
|
14
|
-
const emptyForm = () => ({ label: "", type: "text" });
|
|
14
|
+
const emptyForm = () => ({ label: "", type: "text", unit: "" });
|
|
15
15
|
const CategoryAttributeTemplatesWidget = ({
|
|
16
16
|
data
|
|
17
17
|
}) => {
|
|
@@ -62,10 +62,11 @@ const CategoryAttributeTemplatesWidget = ({
|
|
|
62
62
|
if (!addForm.label.trim()) return;
|
|
63
63
|
createMutation.mutate({
|
|
64
64
|
label: addForm.label.trim(),
|
|
65
|
-
type: addForm.type
|
|
65
|
+
type: addForm.type,
|
|
66
|
+
unit: addForm.type === "number" && addForm.unit.trim() ? addForm.unit.trim() : null
|
|
66
67
|
});
|
|
67
68
|
};
|
|
68
|
-
const typeLabel = (t) => t === "text" ? "Текст" : t === "number" ? "Число" : t;
|
|
69
|
+
const typeLabel = (t) => t === "text" ? "Текст" : t === "number" ? "Число" : t === "file" ? "Файл" : t === "boolean" ? "Да/Нет" : t;
|
|
69
70
|
return /* @__PURE__ */ jsxs(Container, { className: "divide-y p-0", children: [
|
|
70
71
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between px-6 py-4", children: [
|
|
71
72
|
/* @__PURE__ */ jsx(Heading, { level: "h2", children: "Атрибуты" }),
|
|
@@ -89,7 +90,10 @@ const CategoryAttributeTemplatesWidget = ({
|
|
|
89
90
|
className: "flex items-center gap-3 px-6 py-3",
|
|
90
91
|
children: [
|
|
91
92
|
/* @__PURE__ */ jsx("span", { className: "flex-1 text-sm text-ui-fg-subtle", children: attr.label }),
|
|
92
|
-
/* @__PURE__ */
|
|
93
|
+
/* @__PURE__ */ jsxs(Badge, { size: "2xsmall", color: "grey", children: [
|
|
94
|
+
typeLabel(attr.type),
|
|
95
|
+
attr.unit ? `, ${attr.unit}` : ""
|
|
96
|
+
] }),
|
|
93
97
|
/* @__PURE__ */ jsx(Badge, { size: "2xsmall", color: "blue", children: "из родителя" })
|
|
94
98
|
]
|
|
95
99
|
},
|
|
@@ -170,15 +174,27 @@ const CategoryAttributeTemplatesWidget = ({
|
|
|
170
174
|
value: addForm.type,
|
|
171
175
|
onChange: (e) => setAddForm((f) => ({
|
|
172
176
|
...f,
|
|
173
|
-
type: e.target.value
|
|
177
|
+
type: e.target.value,
|
|
178
|
+
unit: e.target.value === "number" ? f.unit : ""
|
|
174
179
|
})),
|
|
175
180
|
className: "h-8 rounded border border-ui-border-base bg-ui-bg-base px-2 text-sm",
|
|
176
181
|
children: [
|
|
177
182
|
/* @__PURE__ */ jsx("option", { value: "text", children: "Текст" }),
|
|
178
|
-
/* @__PURE__ */ jsx("option", { value: "number", children: "Число" })
|
|
183
|
+
/* @__PURE__ */ jsx("option", { value: "number", children: "Число" }),
|
|
184
|
+
/* @__PURE__ */ jsx("option", { value: "file", children: "Файл" }),
|
|
185
|
+
/* @__PURE__ */ jsx("option", { value: "boolean", children: "Да/Нет" })
|
|
179
186
|
]
|
|
180
187
|
}
|
|
181
188
|
),
|
|
189
|
+
addForm.type === "number" && /* @__PURE__ */ jsx(
|
|
190
|
+
Input,
|
|
191
|
+
{
|
|
192
|
+
value: addForm.unit,
|
|
193
|
+
onChange: (e) => setAddForm((f) => ({ ...f, unit: e.target.value })),
|
|
194
|
+
placeholder: "ед. (кг, м, шт...)",
|
|
195
|
+
className: "w-28 h-8 text-sm"
|
|
196
|
+
}
|
|
197
|
+
),
|
|
182
198
|
/* @__PURE__ */ jsx(
|
|
183
199
|
Button,
|
|
184
200
|
{
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Migration20260405120000 = void 0;
|
|
4
|
+
const migrations_1 = require("@mikro-orm/migrations");
|
|
5
|
+
class Migration20260405120000 extends migrations_1.Migration {
|
|
6
|
+
async up() {
|
|
7
|
+
this.addSql(`
|
|
8
|
+
CREATE TABLE IF NOT EXISTS "category_custom_attribute" (
|
|
9
|
+
"id" text NOT NULL,
|
|
10
|
+
"key" text NOT NULL,
|
|
11
|
+
"type" text NOT NULL DEFAULT 'text',
|
|
12
|
+
"label" text NOT NULL DEFAULT '',
|
|
13
|
+
"unit" text NULL,
|
|
14
|
+
"sort_order" integer NOT NULL DEFAULT 0,
|
|
15
|
+
"category_id" text NOT NULL,
|
|
16
|
+
"is_standard" boolean NOT NULL DEFAULT false,
|
|
17
|
+
"created_at" timestamptz NOT NULL DEFAULT now(),
|
|
18
|
+
"updated_at" timestamptz NOT NULL DEFAULT now(),
|
|
19
|
+
"deleted_at" timestamptz NULL,
|
|
20
|
+
CONSTRAINT "category_custom_attribute_pkey" PRIMARY KEY ("id")
|
|
21
|
+
);
|
|
22
|
+
`);
|
|
23
|
+
this.addSql(`
|
|
24
|
+
CREATE INDEX IF NOT EXISTS "IDX_category_custom_attribute_category_id"
|
|
25
|
+
ON "category_custom_attribute" ("category_id")
|
|
26
|
+
WHERE "deleted_at" IS NULL;
|
|
27
|
+
`);
|
|
28
|
+
this.addSql(`
|
|
29
|
+
CREATE INDEX IF NOT EXISTS "IDX_category_custom_attribute_deleted_at"
|
|
30
|
+
ON "category_custom_attribute" ("deleted_at")
|
|
31
|
+
WHERE "deleted_at" IS NOT NULL;
|
|
32
|
+
`);
|
|
33
|
+
this.addSql(`
|
|
34
|
+
CREATE TABLE IF NOT EXISTS "product_custom_attribute" (
|
|
35
|
+
"id" text NOT NULL,
|
|
36
|
+
"product_id" text NOT NULL,
|
|
37
|
+
"value" text NOT NULL,
|
|
38
|
+
"value_numeric" integer NULL,
|
|
39
|
+
"value_file" text NULL,
|
|
40
|
+
"category_custom_attribute_id" text NOT NULL,
|
|
41
|
+
"created_at" timestamptz NOT NULL DEFAULT now(),
|
|
42
|
+
"updated_at" timestamptz NOT NULL DEFAULT now(),
|
|
43
|
+
"deleted_at" timestamptz NULL,
|
|
44
|
+
CONSTRAINT "product_custom_attribute_pkey" PRIMARY KEY ("id"),
|
|
45
|
+
CONSTRAINT "product_custom_attribute_category_custom_attribute_id_foreign"
|
|
46
|
+
FOREIGN KEY ("category_custom_attribute_id")
|
|
47
|
+
REFERENCES "category_custom_attribute" ("id")
|
|
48
|
+
ON UPDATE CASCADE ON DELETE CASCADE
|
|
49
|
+
);
|
|
50
|
+
`);
|
|
51
|
+
this.addSql(`
|
|
52
|
+
CREATE INDEX IF NOT EXISTS "IDX_product_custom_attribute_product_id"
|
|
53
|
+
ON "product_custom_attribute" ("product_id")
|
|
54
|
+
WHERE "deleted_at" IS NULL;
|
|
55
|
+
`);
|
|
56
|
+
this.addSql(`
|
|
57
|
+
CREATE INDEX IF NOT EXISTS "IDX_product_custom_attribute_category_custom_attribute_id"
|
|
58
|
+
ON "product_custom_attribute" ("category_custom_attribute_id")
|
|
59
|
+
WHERE "deleted_at" IS NULL;
|
|
60
|
+
`);
|
|
61
|
+
this.addSql(`
|
|
62
|
+
CREATE INDEX IF NOT EXISTS "IDX_product_custom_attribute_deleted_at"
|
|
63
|
+
ON "product_custom_attribute" ("deleted_at")
|
|
64
|
+
WHERE "deleted_at" IS NOT NULL;
|
|
65
|
+
`);
|
|
66
|
+
}
|
|
67
|
+
async down() {
|
|
68
|
+
this.addSql(`DROP TABLE IF EXISTS "product_custom_attribute" CASCADE;`);
|
|
69
|
+
this.addSql(`DROP TABLE IF EXISTS "category_custom_attribute" CASCADE;`);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
exports.Migration20260405120000 = Migration20260405120000;
|
|
73
|
+
//# sourceMappingURL=Migration20260405120000.js.map
|
package/.medusa/server/src/modules/product-attributes/migrations/Migration20260405120000.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Migration20260405120000.js","sourceRoot":"","sources":["../../../../../../src/modules/product-attributes/migrations/Migration20260405120000.ts"],"names":[],"mappings":";;;AAAA,sDAAiD;AAEjD,MAAa,uBAAwB,SAAQ,sBAAS;IAC3C,KAAK,CAAC,EAAE;QACf,IAAI,CAAC,MAAM,CAAC;;;;;;;;;;;;;;;KAeX,CAAC,CAAA;QAEF,IAAI,CAAC,MAAM,CAAC;;;;KAIX,CAAC,CAAA;QAEF,IAAI,CAAC,MAAM,CAAC;;;;KAIX,CAAC,CAAA;QAEF,IAAI,CAAC,MAAM,CAAC;;;;;;;;;;;;;;;;;KAiBX,CAAC,CAAA;QAEF,IAAI,CAAC,MAAM,CAAC;;;;KAIX,CAAC,CAAA;QAEF,IAAI,CAAC,MAAM,CAAC;;;;KAIX,CAAC,CAAA;QAEF,IAAI,CAAC,MAAM,CAAC;;;;KAIX,CAAC,CAAA;IACJ,CAAC;IAEQ,KAAK,CAAC,IAAI;QACjB,IAAI,CAAC,MAAM,CAAC,0DAA0D,CAAC,CAAA;QACvE,IAAI,CAAC,MAAM,CAAC,2DAA2D,CAAC,CAAA;IAC1E,CAAC;CACF;AAzED,0DAyEC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@empty-complete-org/medusa-product-attributes",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.0",
|
|
4
4
|
"description": "Custom attributes module for Medusa v2 with support for text, number, file types and units of measurement",
|
|
5
5
|
"author": "empty-complete",
|
|
6
6
|
"license": "MIT",
|
|
@@ -63,6 +63,8 @@
|
|
|
63
63
|
"@medusajs/js-sdk": "^2.13.1",
|
|
64
64
|
"@medusajs/medusa": "^2.13.1",
|
|
65
65
|
"@medusajs/ui": "^4.0.27",
|
|
66
|
+
"@mikro-orm/core": "6.4.16",
|
|
67
|
+
"@mikro-orm/migrations": "6.4.16",
|
|
66
68
|
"@tanstack/react-query": "^5.64.2",
|
|
67
69
|
"@types/jest": "^30.0.0",
|
|
68
70
|
"@types/node": "^20.0.0",
|
|
@@ -71,6 +73,7 @@
|
|
|
71
73
|
"jest": "^30.3.0",
|
|
72
74
|
"react": "^19.0.0",
|
|
73
75
|
"ts-jest": "^29.4.6",
|
|
76
|
+
"ts-node": "^10.9.2",
|
|
74
77
|
"typescript": "^5.0.0",
|
|
75
78
|
"yalc": "^1.0.0-pre.53"
|
|
76
79
|
},
|