@empty-complete-org/medusa-product-attributes 0.11.0 → 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 +88 -51
- package/.medusa/server/src/admin/index.mjs +88 -51
- package/.medusa/server/src/api/admin/category/[categoryId]/custom-attributes/route.js +24 -1
- package/.medusa/server/src/api/admin/category/[categoryId]/custom-attributes/route.js.map +1 -1
- 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/.medusa/server/src/modules/product-attributes/service.d.ts +1 -0
- package/.medusa/server/src/modules/product-attributes/service.js +18 -0
- package/.medusa/server/src/modules/product-attributes/service.js.map +1 -1
- 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
|
}) => {
|
|
@@ -34,6 +34,8 @@ const CategoryAttributeTemplatesWidget = ({
|
|
|
34
34
|
queryFn: () => sdk.client.fetch(`/admin/category/${categoryId}/custom-attributes`)
|
|
35
35
|
});
|
|
36
36
|
const attributes = (result == null ? void 0 : result.category_custom_attributes) ?? [];
|
|
37
|
+
const ownAttributes = attributes.filter((a) => !a.inherited);
|
|
38
|
+
const inheritedAttributes = attributes.filter((a) => a.inherited);
|
|
37
39
|
const createMutation = reactQuery.useMutation({
|
|
38
40
|
mutationFn: (body) => sdk.client.fetch(`/admin/category/${categoryId}/custom-attributes`, {
|
|
39
41
|
method: "POST",
|
|
@@ -63,9 +65,11 @@ const CategoryAttributeTemplatesWidget = ({
|
|
|
63
65
|
if (!addForm.label.trim()) return;
|
|
64
66
|
createMutation.mutate({
|
|
65
67
|
label: addForm.label.trim(),
|
|
66
|
-
type: addForm.type
|
|
68
|
+
type: addForm.type,
|
|
69
|
+
unit: addForm.type === "number" && addForm.unit.trim() ? addForm.unit.trim() : null
|
|
67
70
|
});
|
|
68
71
|
};
|
|
72
|
+
const typeLabel = (t) => t === "text" ? "Текст" : t === "number" ? "Число" : t === "file" ? "Файл" : t === "boolean" ? "Да/Нет" : t;
|
|
69
73
|
return /* @__PURE__ */ jsxRuntime.jsxs(ui.Container, { className: "divide-y p-0", children: [
|
|
70
74
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between px-6 py-4", children: [
|
|
71
75
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { level: "h2", children: "Атрибуты" }),
|
|
@@ -81,60 +85,81 @@ const CategoryAttributeTemplatesWidget = ({
|
|
|
81
85
|
] }),
|
|
82
86
|
isLoading && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-6 py-4", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-muted text-sm", children: "Загрузка…" }) }),
|
|
83
87
|
isError && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-6 py-4", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-error text-sm", children: "Не удалось загрузить атрибуты." }) }),
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
(
|
|
87
|
-
"div",
|
|
88
|
-
{
|
|
89
|
-
className: "flex items-center gap-3 px-6 py-3 text-sm",
|
|
90
|
-
children: [
|
|
91
|
-
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex-1 text-ui-fg-base", children: [
|
|
92
|
-
"Удалить «",
|
|
93
|
-
attr.label,
|
|
94
|
-
"»?"
|
|
95
|
-
] }),
|
|
96
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
97
|
-
ui.Button,
|
|
98
|
-
{
|
|
99
|
-
size: "small",
|
|
100
|
-
variant: "danger",
|
|
101
|
-
onClick: () => deleteMutation.mutate(attr.id),
|
|
102
|
-
isLoading: deleteMutation.isPending,
|
|
103
|
-
children: "Удалить"
|
|
104
|
-
}
|
|
105
|
-
),
|
|
106
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
107
|
-
ui.Button,
|
|
108
|
-
{
|
|
109
|
-
size: "small",
|
|
110
|
-
variant: "secondary",
|
|
111
|
-
onClick: () => setConfirmDeleteId(null),
|
|
112
|
-
children: "Отмена"
|
|
113
|
-
}
|
|
114
|
-
)
|
|
115
|
-
]
|
|
116
|
-
},
|
|
117
|
-
attr.id
|
|
118
|
-
) : /* @__PURE__ */ jsxRuntime.jsxs(
|
|
88
|
+
inheritedAttributes.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
89
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-6 py-2 bg-ui-bg-subtle", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", weight: "plus", className: "text-ui-fg-muted uppercase", children: "Унаследованные" }) }),
|
|
90
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "divide-y", children: inheritedAttributes.map((attr) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
119
91
|
"div",
|
|
120
92
|
{
|
|
121
93
|
className: "flex items-center gap-3 px-6 py-3",
|
|
122
94
|
children: [
|
|
123
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-1 text-sm text-ui-fg-
|
|
124
|
-
/* @__PURE__ */ jsxRuntime.
|
|
125
|
-
|
|
126
|
-
"
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
className: "text-xs text-ui-fg-error hover:underline",
|
|
130
|
-
children: "Удалить"
|
|
131
|
-
}
|
|
132
|
-
)
|
|
95
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-1 text-sm text-ui-fg-subtle", children: attr.label }),
|
|
96
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.Badge, { size: "2xsmall", color: "grey", children: [
|
|
97
|
+
typeLabel(attr.type),
|
|
98
|
+
attr.unit ? `, ${attr.unit}` : ""
|
|
99
|
+
] }),
|
|
100
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Badge, { size: "2xsmall", color: "blue", children: "из родителя" })
|
|
133
101
|
]
|
|
134
102
|
},
|
|
135
103
|
attr.id
|
|
136
|
-
)
|
|
137
|
-
|
|
104
|
+
)) })
|
|
105
|
+
] }),
|
|
106
|
+
ownAttributes.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
107
|
+
inheritedAttributes.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-6 py-2 bg-ui-bg-subtle", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", weight: "plus", className: "text-ui-fg-muted uppercase", children: "Свои" }) }),
|
|
108
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "divide-y", children: ownAttributes.map(
|
|
109
|
+
(attr) => confirmDeleteId === attr.id ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
110
|
+
"div",
|
|
111
|
+
{
|
|
112
|
+
className: "flex items-center gap-3 px-6 py-3 text-sm",
|
|
113
|
+
children: [
|
|
114
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex-1 text-ui-fg-base", children: [
|
|
115
|
+
"Удалить «",
|
|
116
|
+
attr.label,
|
|
117
|
+
"»?"
|
|
118
|
+
] }),
|
|
119
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
120
|
+
ui.Button,
|
|
121
|
+
{
|
|
122
|
+
size: "small",
|
|
123
|
+
variant: "danger",
|
|
124
|
+
onClick: () => deleteMutation.mutate(attr.id),
|
|
125
|
+
isLoading: deleteMutation.isPending,
|
|
126
|
+
children: "Удалить"
|
|
127
|
+
}
|
|
128
|
+
),
|
|
129
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
130
|
+
ui.Button,
|
|
131
|
+
{
|
|
132
|
+
size: "small",
|
|
133
|
+
variant: "secondary",
|
|
134
|
+
onClick: () => setConfirmDeleteId(null),
|
|
135
|
+
children: "Отмена"
|
|
136
|
+
}
|
|
137
|
+
)
|
|
138
|
+
]
|
|
139
|
+
},
|
|
140
|
+
attr.id
|
|
141
|
+
) : /* @__PURE__ */ jsxRuntime.jsxs(
|
|
142
|
+
"div",
|
|
143
|
+
{
|
|
144
|
+
className: "flex items-center gap-3 px-6 py-3",
|
|
145
|
+
children: [
|
|
146
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-1 text-sm text-ui-fg-base", children: attr.label }),
|
|
147
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Badge, { size: "2xsmall", color: "grey", children: typeLabel(attr.type) }),
|
|
148
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
149
|
+
"button",
|
|
150
|
+
{
|
|
151
|
+
onClick: () => setConfirmDeleteId(attr.id),
|
|
152
|
+
className: "text-xs text-ui-fg-error hover:underline",
|
|
153
|
+
children: "Удалить"
|
|
154
|
+
}
|
|
155
|
+
)
|
|
156
|
+
]
|
|
157
|
+
},
|
|
158
|
+
attr.id
|
|
159
|
+
)
|
|
160
|
+
) })
|
|
161
|
+
] }),
|
|
162
|
+
!isLoading && !isError && attributes.length === 0 && !showAddForm && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-6 py-4", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-muted text-sm", children: "Нет атрибутов. Добавьте первый." }) }),
|
|
138
163
|
showAddForm && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 px-6 py-3", children: [
|
|
139
164
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
140
165
|
ui.Input,
|
|
@@ -152,15 +177,27 @@ const CategoryAttributeTemplatesWidget = ({
|
|
|
152
177
|
value: addForm.type,
|
|
153
178
|
onChange: (e) => setAddForm((f) => ({
|
|
154
179
|
...f,
|
|
155
|
-
type: e.target.value
|
|
180
|
+
type: e.target.value,
|
|
181
|
+
unit: e.target.value === "number" ? f.unit : ""
|
|
156
182
|
})),
|
|
157
183
|
className: "h-8 rounded border border-ui-border-base bg-ui-bg-base px-2 text-sm",
|
|
158
184
|
children: [
|
|
159
185
|
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "text", children: "Текст" }),
|
|
160
|
-
/* @__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: "Да/Нет" })
|
|
161
189
|
]
|
|
162
190
|
}
|
|
163
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
|
+
),
|
|
164
201
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
165
202
|
ui.Button,
|
|
166
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
|
}) => {
|
|
@@ -31,6 +31,8 @@ const CategoryAttributeTemplatesWidget = ({
|
|
|
31
31
|
queryFn: () => sdk.client.fetch(`/admin/category/${categoryId}/custom-attributes`)
|
|
32
32
|
});
|
|
33
33
|
const attributes = (result == null ? void 0 : result.category_custom_attributes) ?? [];
|
|
34
|
+
const ownAttributes = attributes.filter((a) => !a.inherited);
|
|
35
|
+
const inheritedAttributes = attributes.filter((a) => a.inherited);
|
|
34
36
|
const createMutation = useMutation({
|
|
35
37
|
mutationFn: (body) => sdk.client.fetch(`/admin/category/${categoryId}/custom-attributes`, {
|
|
36
38
|
method: "POST",
|
|
@@ -60,9 +62,11 @@ const CategoryAttributeTemplatesWidget = ({
|
|
|
60
62
|
if (!addForm.label.trim()) return;
|
|
61
63
|
createMutation.mutate({
|
|
62
64
|
label: addForm.label.trim(),
|
|
63
|
-
type: addForm.type
|
|
65
|
+
type: addForm.type,
|
|
66
|
+
unit: addForm.type === "number" && addForm.unit.trim() ? addForm.unit.trim() : null
|
|
64
67
|
});
|
|
65
68
|
};
|
|
69
|
+
const typeLabel = (t) => t === "text" ? "Текст" : t === "number" ? "Число" : t === "file" ? "Файл" : t === "boolean" ? "Да/Нет" : t;
|
|
66
70
|
return /* @__PURE__ */ jsxs(Container, { className: "divide-y p-0", children: [
|
|
67
71
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between px-6 py-4", children: [
|
|
68
72
|
/* @__PURE__ */ jsx(Heading, { level: "h2", children: "Атрибуты" }),
|
|
@@ -78,60 +82,81 @@ const CategoryAttributeTemplatesWidget = ({
|
|
|
78
82
|
] }),
|
|
79
83
|
isLoading && /* @__PURE__ */ jsx("div", { className: "px-6 py-4", children: /* @__PURE__ */ jsx(Text, { className: "text-ui-fg-muted text-sm", children: "Загрузка…" }) }),
|
|
80
84
|
isError && /* @__PURE__ */ jsx("div", { className: "px-6 py-4", children: /* @__PURE__ */ jsx(Text, { className: "text-ui-fg-error text-sm", children: "Не удалось загрузить атрибуты." }) }),
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
(
|
|
84
|
-
"div",
|
|
85
|
-
{
|
|
86
|
-
className: "flex items-center gap-3 px-6 py-3 text-sm",
|
|
87
|
-
children: [
|
|
88
|
-
/* @__PURE__ */ jsxs("span", { className: "flex-1 text-ui-fg-base", children: [
|
|
89
|
-
"Удалить «",
|
|
90
|
-
attr.label,
|
|
91
|
-
"»?"
|
|
92
|
-
] }),
|
|
93
|
-
/* @__PURE__ */ jsx(
|
|
94
|
-
Button,
|
|
95
|
-
{
|
|
96
|
-
size: "small",
|
|
97
|
-
variant: "danger",
|
|
98
|
-
onClick: () => deleteMutation.mutate(attr.id),
|
|
99
|
-
isLoading: deleteMutation.isPending,
|
|
100
|
-
children: "Удалить"
|
|
101
|
-
}
|
|
102
|
-
),
|
|
103
|
-
/* @__PURE__ */ jsx(
|
|
104
|
-
Button,
|
|
105
|
-
{
|
|
106
|
-
size: "small",
|
|
107
|
-
variant: "secondary",
|
|
108
|
-
onClick: () => setConfirmDeleteId(null),
|
|
109
|
-
children: "Отмена"
|
|
110
|
-
}
|
|
111
|
-
)
|
|
112
|
-
]
|
|
113
|
-
},
|
|
114
|
-
attr.id
|
|
115
|
-
) : /* @__PURE__ */ jsxs(
|
|
85
|
+
inheritedAttributes.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
86
|
+
/* @__PURE__ */ jsx("div", { className: "px-6 py-2 bg-ui-bg-subtle", children: /* @__PURE__ */ jsx(Text, { size: "xsmall", weight: "plus", className: "text-ui-fg-muted uppercase", children: "Унаследованные" }) }),
|
|
87
|
+
/* @__PURE__ */ jsx("div", { className: "divide-y", children: inheritedAttributes.map((attr) => /* @__PURE__ */ jsxs(
|
|
116
88
|
"div",
|
|
117
89
|
{
|
|
118
90
|
className: "flex items-center gap-3 px-6 py-3",
|
|
119
91
|
children: [
|
|
120
|
-
/* @__PURE__ */ jsx("span", { className: "flex-1 text-sm text-ui-fg-
|
|
121
|
-
/* @__PURE__ */
|
|
122
|
-
|
|
123
|
-
"
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
className: "text-xs text-ui-fg-error hover:underline",
|
|
127
|
-
children: "Удалить"
|
|
128
|
-
}
|
|
129
|
-
)
|
|
92
|
+
/* @__PURE__ */ jsx("span", { className: "flex-1 text-sm text-ui-fg-subtle", children: attr.label }),
|
|
93
|
+
/* @__PURE__ */ jsxs(Badge, { size: "2xsmall", color: "grey", children: [
|
|
94
|
+
typeLabel(attr.type),
|
|
95
|
+
attr.unit ? `, ${attr.unit}` : ""
|
|
96
|
+
] }),
|
|
97
|
+
/* @__PURE__ */ jsx(Badge, { size: "2xsmall", color: "blue", children: "из родителя" })
|
|
130
98
|
]
|
|
131
99
|
},
|
|
132
100
|
attr.id
|
|
133
|
-
)
|
|
134
|
-
|
|
101
|
+
)) })
|
|
102
|
+
] }),
|
|
103
|
+
ownAttributes.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
104
|
+
inheritedAttributes.length > 0 && /* @__PURE__ */ jsx("div", { className: "px-6 py-2 bg-ui-bg-subtle", children: /* @__PURE__ */ jsx(Text, { size: "xsmall", weight: "plus", className: "text-ui-fg-muted uppercase", children: "Свои" }) }),
|
|
105
|
+
/* @__PURE__ */ jsx("div", { className: "divide-y", children: ownAttributes.map(
|
|
106
|
+
(attr) => confirmDeleteId === attr.id ? /* @__PURE__ */ jsxs(
|
|
107
|
+
"div",
|
|
108
|
+
{
|
|
109
|
+
className: "flex items-center gap-3 px-6 py-3 text-sm",
|
|
110
|
+
children: [
|
|
111
|
+
/* @__PURE__ */ jsxs("span", { className: "flex-1 text-ui-fg-base", children: [
|
|
112
|
+
"Удалить «",
|
|
113
|
+
attr.label,
|
|
114
|
+
"»?"
|
|
115
|
+
] }),
|
|
116
|
+
/* @__PURE__ */ jsx(
|
|
117
|
+
Button,
|
|
118
|
+
{
|
|
119
|
+
size: "small",
|
|
120
|
+
variant: "danger",
|
|
121
|
+
onClick: () => deleteMutation.mutate(attr.id),
|
|
122
|
+
isLoading: deleteMutation.isPending,
|
|
123
|
+
children: "Удалить"
|
|
124
|
+
}
|
|
125
|
+
),
|
|
126
|
+
/* @__PURE__ */ jsx(
|
|
127
|
+
Button,
|
|
128
|
+
{
|
|
129
|
+
size: "small",
|
|
130
|
+
variant: "secondary",
|
|
131
|
+
onClick: () => setConfirmDeleteId(null),
|
|
132
|
+
children: "Отмена"
|
|
133
|
+
}
|
|
134
|
+
)
|
|
135
|
+
]
|
|
136
|
+
},
|
|
137
|
+
attr.id
|
|
138
|
+
) : /* @__PURE__ */ jsxs(
|
|
139
|
+
"div",
|
|
140
|
+
{
|
|
141
|
+
className: "flex items-center gap-3 px-6 py-3",
|
|
142
|
+
children: [
|
|
143
|
+
/* @__PURE__ */ jsx("span", { className: "flex-1 text-sm text-ui-fg-base", children: attr.label }),
|
|
144
|
+
/* @__PURE__ */ jsx(Badge, { size: "2xsmall", color: "grey", children: typeLabel(attr.type) }),
|
|
145
|
+
/* @__PURE__ */ jsx(
|
|
146
|
+
"button",
|
|
147
|
+
{
|
|
148
|
+
onClick: () => setConfirmDeleteId(attr.id),
|
|
149
|
+
className: "text-xs text-ui-fg-error hover:underline",
|
|
150
|
+
children: "Удалить"
|
|
151
|
+
}
|
|
152
|
+
)
|
|
153
|
+
]
|
|
154
|
+
},
|
|
155
|
+
attr.id
|
|
156
|
+
)
|
|
157
|
+
) })
|
|
158
|
+
] }),
|
|
159
|
+
!isLoading && !isError && attributes.length === 0 && !showAddForm && /* @__PURE__ */ jsx("div", { className: "px-6 py-4", children: /* @__PURE__ */ jsx(Text, { className: "text-ui-fg-muted text-sm", children: "Нет атрибутов. Добавьте первый." }) }),
|
|
135
160
|
showAddForm && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 px-6 py-3", children: [
|
|
136
161
|
/* @__PURE__ */ jsx(
|
|
137
162
|
Input,
|
|
@@ -149,15 +174,27 @@ const CategoryAttributeTemplatesWidget = ({
|
|
|
149
174
|
value: addForm.type,
|
|
150
175
|
onChange: (e) => setAddForm((f) => ({
|
|
151
176
|
...f,
|
|
152
|
-
type: e.target.value
|
|
177
|
+
type: e.target.value,
|
|
178
|
+
unit: e.target.value === "number" ? f.unit : ""
|
|
153
179
|
})),
|
|
154
180
|
className: "h-8 rounded border border-ui-border-base bg-ui-bg-base px-2 text-sm",
|
|
155
181
|
children: [
|
|
156
182
|
/* @__PURE__ */ jsx("option", { value: "text", children: "Текст" }),
|
|
157
|
-
/* @__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: "Да/Нет" })
|
|
158
186
|
]
|
|
159
187
|
}
|
|
160
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
|
+
),
|
|
161
198
|
/* @__PURE__ */ jsx(
|
|
162
199
|
Button,
|
|
163
200
|
{
|
|
@@ -3,11 +3,34 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.GET = GET;
|
|
4
4
|
exports.POST = POST;
|
|
5
5
|
exports.PATCH = PATCH;
|
|
6
|
+
const utils_1 = require("@medusajs/framework/utils");
|
|
6
7
|
const product_attributes_1 = require("../../../../../modules/product-attributes");
|
|
8
|
+
/**
|
|
9
|
+
* Walk up the category tree, starting from `leafId`, collecting ids of the
|
|
10
|
+
* category itself and all of its ancestors. Ordered leaf → root.
|
|
11
|
+
*
|
|
12
|
+
* A hard cap of 20 levels guards against cycles in malformed data.
|
|
13
|
+
*/
|
|
14
|
+
async function resolveAncestorChain(productService, leafId) {
|
|
15
|
+
const chain = [];
|
|
16
|
+
let currentId = leafId;
|
|
17
|
+
let depth = 0;
|
|
18
|
+
while (currentId && depth < 20) {
|
|
19
|
+
chain.push(currentId);
|
|
20
|
+
const category = await productService.retrieveProductCategory(currentId, {
|
|
21
|
+
select: ["id", "parent_category_id"],
|
|
22
|
+
});
|
|
23
|
+
currentId = category?.parent_category_id ?? null;
|
|
24
|
+
depth++;
|
|
25
|
+
}
|
|
26
|
+
return chain;
|
|
27
|
+
}
|
|
7
28
|
async function GET(req, res) {
|
|
8
29
|
const { categoryId } = req.params;
|
|
9
30
|
const service = req.scope.resolve(product_attributes_1.CUSTOM_ATTRIBUTE_MODULE);
|
|
10
|
-
const
|
|
31
|
+
const productService = req.scope.resolve(utils_1.Modules.PRODUCT);
|
|
32
|
+
const categoryIds = await resolveAncestorChain(productService, categoryId);
|
|
33
|
+
const category_custom_attributes = await service.getAttributesByCategoryIds(categoryIds);
|
|
11
34
|
res.json({ category_custom_attributes });
|
|
12
35
|
}
|
|
13
36
|
async function POST(req, res) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"route.js","sourceRoot":"","sources":["../../../../../../../../src/api/admin/category/[categoryId]/custom-attributes/route.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"route.js","sourceRoot":"","sources":["../../../../../../../../src/api/admin/category/[categoryId]/custom-attributes/route.ts"],"names":[],"mappings":";;AA6BA,kBASC;AAED,oBAoBC;AAED,sBAcC;AA3ED,qDAAmD;AACnD,kFAAmF;AAGnF;;;;;GAKG;AACH,KAAK,UAAU,oBAAoB,CACjC,cAAmB,EACnB,MAAc;IAEd,MAAM,KAAK,GAAa,EAAE,CAAA;IAC1B,IAAI,SAAS,GAAkB,MAAM,CAAA;IACrC,IAAI,KAAK,GAAG,CAAC,CAAA;IACb,OAAO,SAAS,IAAI,KAAK,GAAG,EAAE,EAAE,CAAC;QAC/B,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;QACrB,MAAM,QAAQ,GAAQ,MAAM,cAAc,CAAC,uBAAuB,CAAC,SAAS,EAAE;YAC5E,MAAM,EAAE,CAAC,IAAI,EAAE,oBAAoB,CAAC;SACrC,CAAC,CAAA;QACF,SAAS,GAAI,QAAQ,EAAE,kBAAoC,IAAI,IAAI,CAAA;QACnE,KAAK,EAAE,CAAA;IACT,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC;AAEM,KAAK,UAAU,GAAG,CAAC,GAAkB,EAAE,GAAmB;IAC/D,MAAM,EAAE,UAAU,EAAE,GAAG,GAAG,CAAC,MAAM,CAAA;IACjC,MAAM,OAAO,GAA2B,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,4CAAuB,CAAC,CAAA;IAClF,MAAM,cAAc,GAAG,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,eAAO,CAAC,OAAO,CAAC,CAAA;IAEzD,MAAM,WAAW,GAAG,MAAM,oBAAoB,CAAC,cAAc,EAAE,UAAU,CAAC,CAAA;IAC1E,MAAM,0BAA0B,GAAG,MAAM,OAAO,CAAC,0BAA0B,CAAC,WAAW,CAAC,CAAA;IAExF,GAAG,CAAC,IAAI,CAAC,EAAE,0BAA0B,EAAE,CAAC,CAAA;AAC1C,CAAC;AAEM,KAAK,UAAU,IAAI,CAAC,GAAkB,EAAE,GAAmB;IAChE,MAAM,EAAE,UAAU,EAAE,GAAG,GAAG,CAAC,MAAM,CAAA;IACjC,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,GAAG,CAAC,IAK7C,CAAA;IAED,MAAM,OAAO,GAA2B,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,4CAAuB,CAAC,CAAA;IAElF,MAAM,yBAAyB,GAAG,MAAM,OAAO,CAAC,uBAAuB,CAAC;QACtE,KAAK;QACL,IAAI,EAAE,IAAI,IAAI,MAAM;QACpB,IAAI,EAAE,IAAI,IAAI,IAAI;QAClB,WAAW,EAAE,UAAU;QACvB,UAAU;KACX,CAAC,CAAA;IAEF,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,yBAAyB,EAAE,CAAC,CAAA;AACrD,CAAC;AAEM,KAAK,UAAU,KAAK,CAAC,GAAkB,EAAE,GAAmB;IACjE,MAAM,OAAO,GAA2B,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,4CAAuB,CAAC,CAAA;IAClF,MAAM,EAAE,EAAE,EAAE,GAAG,IAAI,EAAE,GAAG,GAAG,CAAC,IAO3B,CAAA;IAED,MAAM,yBAAyB,GAAG,MAAM,OAAO,CAAC,uBAAuB,CAAC,EAAE,EAAE,IAAI,CAAC,CAAA;IAEjF,GAAG,CAAC,IAAI,CAAC,EAAE,yBAAyB,EAAE,CAAC,CAAA;AACzC,CAAC"}
|
|
@@ -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"}
|
|
@@ -63,6 +63,7 @@ declare class CustomAttributeService extends CustomAttributeService_base {
|
|
|
63
63
|
updated_at: Date;
|
|
64
64
|
deleted_at: Date | null;
|
|
65
65
|
}[]>;
|
|
66
|
+
getAttributesByCategoryIds(categoryIds: string[]): Promise<any[]>;
|
|
66
67
|
createCategoryAttribute(data: {
|
|
67
68
|
label: string;
|
|
68
69
|
type: string;
|
|
@@ -19,6 +19,24 @@ class CustomAttributeService extends (0, utils_1.MedusaService)(models) {
|
|
|
19
19
|
deleted_at: null,
|
|
20
20
|
});
|
|
21
21
|
}
|
|
22
|
+
async getAttributesByCategoryIds(categoryIds) {
|
|
23
|
+
if (!categoryIds || categoryIds.length === 0) {
|
|
24
|
+
return [];
|
|
25
|
+
}
|
|
26
|
+
// @ts-ignore - method generated by MedusaService
|
|
27
|
+
const attributes = await this.listCategoryCustomAttributes({
|
|
28
|
+
category_id: categoryIds,
|
|
29
|
+
deleted_at: null,
|
|
30
|
+
});
|
|
31
|
+
// First id in the list is the leaf category — its attributes are "own",
|
|
32
|
+
// everything else is inherited from an ancestor.
|
|
33
|
+
const leafId = categoryIds[0];
|
|
34
|
+
return attributes.map((attr) => ({
|
|
35
|
+
...attr,
|
|
36
|
+
inherited: attr.category_id !== leafId,
|
|
37
|
+
source_category_id: attr.category_id,
|
|
38
|
+
}));
|
|
39
|
+
}
|
|
22
40
|
async createCategoryAttribute(data) {
|
|
23
41
|
const key = this.generateKey(data.label);
|
|
24
42
|
// @ts-ignore - method generated by MedusaService
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service.js","sourceRoot":"","sources":["../../../../../src/modules/product-attributes/service.ts"],"names":[],"mappings":";;;;;AAAA,qDAAyD;AACzD,mGAAwE;AACxE,iGAAsE;AAEtE,MAAM,MAAM,GAAG;IACb,uBAAuB,EAAvB,mCAAuB;IACvB,sBAAsB,EAAtB,kCAAsB;CACvB,CAAA;AAID,2EAA2E;AAC3E,MAAM,sBAAuB,SAAQ,IAAA,qBAAa,EAAC,MAAM,CAAC;IACxD,KAAK,CAAC,qBAAqB,CAAC,UAAkB;QAC5C,iDAAiD;QACjD,OAAO,MAAM,IAAI,CAAC,4BAA4B,CAAC;YAC7C,WAAW,EAAE,UAAU;YACvB,UAAU,EAAE,IAAI;SACjB,CAAC,CAAA;IACJ,CAAC;IAED,KAAK,CAAC,uBAAuB,CAAC,IAO7B;QACC,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QACxC,iDAAiD;QACjD,OAAO,MAAM,IAAI,CAAC,8BAA8B,CAAC;YAC/C,GAAG,IAAI;YACP,GAAG;YACH,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,IAAI;YACvB,WAAW,EAAE,IAAI,CAAC,WAAW,IAAI,KAAK;YACtC,UAAU,EAAE,IAAI,CAAC,UAAU,IAAI,CAAC;SACjC,CAAC,CAAA;IACJ,CAAC;IAED,KAAK,CAAC,uBAAuB,CAC3B,EAAU,EACV,IAMC;QAED,MAAM,UAAU,GAAwB,EAAE,GAAG,IAAI,EAAE,CAAA;QACnD,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACf,UAAU,CAAC,GAAG,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QAC/C,CAAC;QACD,iDAAiD;QACjD,OAAO,MAAM,IAAI,CAAC,8BAA8B,CAAC,CAAC,EAAE,EAAE,EAAE,GAAG,UAAU,EAAE,CAAC,CAAC,CAAA;IAC3E,CAAC;IAED,KAAK,CAAC,sBAAsB,CAAC,IAM5B;QACC,iDAAiD;QACjD,OAAO,MAAM,IAAI,CAAC,6BAA6B,CAAC,IAAI,CAAC,CAAA;IACvD,CAAC;IAED,KAAK,CAAC,sBAAsB,CAC1B,EAAU,EACV,IAKC;QAED,iDAAiD;QACjD,OAAO,MAAM,IAAI,CAAC,6BAA6B,CAAC,CAAC,EAAE,EAAE,EAAE,GAAG,IAAI,EAAE,CAAC,CAAC,CAAA;IACpE,CAAC;IAED,KAAK,CAAC,oBAAoB,CAAC,SAAiB;QAC1C,iDAAiD;QACjD,OAAO,MAAM,IAAI,CAAC,2BAA2B,CAAC;YAC5C,UAAU,EAAE,SAAS;YACrB,UAAU,EAAE,IAAI;SACjB,EAAE;YACD,SAAS,EAAE,CAAC,2BAA2B,CAAC;SACzC,CAAC,CAAA;IACJ,CAAC;IAEO,WAAW,CAAC,KAAa;QAC/B,OAAO,KAAK;aACT,WAAW,EAAE;aACb,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC;aAC3B,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAA;IAC1B,CAAC;CACF;AAED,kBAAe,sBAAsB,CAAA"}
|
|
1
|
+
{"version":3,"file":"service.js","sourceRoot":"","sources":["../../../../../src/modules/product-attributes/service.ts"],"names":[],"mappings":"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"}
|
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
|
},
|