medusa-product-helper 0.0.24 → 0.0.26
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.
|
@@ -152,23 +152,61 @@ const useOrderMetadataConfig = () => useMetadataConfig("order");
|
|
|
152
152
|
const CONFIG_DOCS_URL$2 = "https://docs.medusajs.com/admin/extension-points/widgets#product-category-details";
|
|
153
153
|
const CategoryMetadataTableWidget = ({ data }) => {
|
|
154
154
|
const { data: descriptors = [], isPending, isError } = useCategoryMetadataConfig();
|
|
155
|
-
const
|
|
156
|
-
const [baselineMetadata, setBaselineMetadata] = react.useState(
|
|
155
|
+
const categoryId = (data == null ? void 0 : data.id) ?? void 0;
|
|
156
|
+
const [baselineMetadata, setBaselineMetadata] = react.useState(
|
|
157
|
+
(data == null ? void 0 : data.metadata) ?? {}
|
|
158
|
+
);
|
|
157
159
|
const queryClient = reactQuery.useQueryClient();
|
|
160
|
+
const previousCategoryIdRef = react.useRef(categoryId);
|
|
161
|
+
const isInitializedRef = react.useRef(false);
|
|
162
|
+
const dataRef = react.useRef(data);
|
|
163
|
+
const descriptorsRef = react.useRef(descriptors);
|
|
164
|
+
react.useEffect(() => {
|
|
165
|
+
dataRef.current = data;
|
|
166
|
+
descriptorsRef.current = descriptors;
|
|
167
|
+
}, [data, descriptors]);
|
|
168
|
+
react.useEffect(() => {
|
|
169
|
+
var _a;
|
|
170
|
+
if (previousCategoryIdRef.current === categoryId && isInitializedRef.current) {
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
const categoryIdChanged = previousCategoryIdRef.current !== categoryId;
|
|
174
|
+
if (categoryIdChanged || !isInitializedRef.current) {
|
|
175
|
+
const currentMetadata = (data == null ? void 0 : data.metadata) ?? ((_a = dataRef.current) == null ? void 0 : _a.metadata) ?? {};
|
|
176
|
+
const currentDescriptors = descriptorsRef.current.length > 0 ? descriptorsRef.current : descriptors;
|
|
177
|
+
if (currentDescriptors.length === 0) {
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
previousCategoryIdRef.current = categoryId;
|
|
181
|
+
setBaselineMetadata(currentMetadata);
|
|
182
|
+
const newInitialState = buildInitialFormState(currentDescriptors, currentMetadata);
|
|
183
|
+
setValues(newInitialState);
|
|
184
|
+
isInitializedRef.current = true;
|
|
185
|
+
}
|
|
186
|
+
}, [categoryId]);
|
|
187
|
+
const metadataStringRef = react.useRef("");
|
|
158
188
|
react.useEffect(() => {
|
|
159
|
-
|
|
160
|
-
|
|
189
|
+
const hasCategoryData = !!data;
|
|
190
|
+
const descriptorsLoaded = descriptors.length > 0;
|
|
191
|
+
const sameCategory = previousCategoryIdRef.current === categoryId;
|
|
192
|
+
const notInitialized = !isInitializedRef.current;
|
|
193
|
+
const currentMetadata = (data == null ? void 0 : data.metadata) ?? {};
|
|
194
|
+
const currentMetadataString = JSON.stringify(currentMetadata);
|
|
195
|
+
const metadataChanged = currentMetadataString !== metadataStringRef.current;
|
|
196
|
+
if (hasCategoryData && descriptorsLoaded && sameCategory && (notInitialized || metadataChanged)) {
|
|
197
|
+
const newInitialState = buildInitialFormState(descriptors, currentMetadata);
|
|
198
|
+
setBaselineMetadata(currentMetadata);
|
|
199
|
+
setValues(newInitialState);
|
|
200
|
+
metadataStringRef.current = currentMetadataString;
|
|
201
|
+
isInitializedRef.current = true;
|
|
202
|
+
}
|
|
203
|
+
}, [data, descriptors.length, categoryId]);
|
|
161
204
|
const initialState = react.useMemo(
|
|
162
205
|
() => buildInitialFormState(descriptors, baselineMetadata),
|
|
163
206
|
[descriptors, baselineMetadata]
|
|
164
207
|
);
|
|
165
|
-
const [values, setValues] = react.useState(
|
|
166
|
-
initialState
|
|
167
|
-
);
|
|
208
|
+
const [values, setValues] = react.useState({});
|
|
168
209
|
const [isSaving, setIsSaving] = react.useState(false);
|
|
169
|
-
react.useEffect(() => {
|
|
170
|
-
setValues(initialState);
|
|
171
|
-
}, [initialState]);
|
|
172
210
|
const errors = react.useMemo(() => {
|
|
173
211
|
return descriptors.reduce((acc, descriptor) => {
|
|
174
212
|
const error = validateValueForDescriptor(descriptor, values[descriptor.key]);
|
|
@@ -234,6 +272,15 @@ const CategoryMetadataTableWidget = ({ data }) => {
|
|
|
234
272
|
await queryClient.invalidateQueries({
|
|
235
273
|
queryKey: ["product-categories"]
|
|
236
274
|
});
|
|
275
|
+
await queryClient.invalidateQueries({
|
|
276
|
+
queryKey: ["product-category", data.id]
|
|
277
|
+
});
|
|
278
|
+
if (data.id) {
|
|
279
|
+
queryClient.refetchQueries({
|
|
280
|
+
queryKey: ["product-category", data.id]
|
|
281
|
+
}).catch(() => {
|
|
282
|
+
});
|
|
283
|
+
}
|
|
237
284
|
} catch (error) {
|
|
238
285
|
ui.toast.error(error instanceof Error ? error.message : "Save failed");
|
|
239
286
|
} finally {
|
|
@@ -248,7 +295,7 @@ const CategoryMetadataTableWidget = ({ data }) => {
|
|
|
248
295
|
] }),
|
|
249
296
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle", children: "Structured metadata mapped to the keys you configured in the plugin options." })
|
|
250
297
|
] }),
|
|
251
|
-
isPending ? /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-[160px] w-full" }) : isError ? /* @__PURE__ */ jsxRuntime.jsxs(ui.InlineTip, { variant: "error", label: "Configuration unavailable", children: [
|
|
298
|
+
isPending || !isInitializedRef.current || Object.keys(values).length === 0 ? /* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-[160px] w-full" }) : isError ? /* @__PURE__ */ jsxRuntime.jsxs(ui.InlineTip, { variant: "error", label: "Configuration unavailable", children: [
|
|
252
299
|
"Unable to load metadata configuration for this plugin. Confirm that the plugin is registered with options in ",
|
|
253
300
|
/* @__PURE__ */ jsxRuntime.jsx("code", { children: "medusa-config.ts" }),
|
|
254
301
|
"."
|
|
@@ -1017,14 +1064,14 @@ const ProductMetadataTableWidget = ({ data }) => {
|
|
|
1017
1064
|
}, [productId]);
|
|
1018
1065
|
const metadataStringRef = react.useRef("");
|
|
1019
1066
|
react.useEffect(() => {
|
|
1020
|
-
const
|
|
1067
|
+
const hasProductData = !!data;
|
|
1021
1068
|
const descriptorsLoaded = descriptors.length > 0;
|
|
1022
1069
|
const sameProduct = previousProductIdRef.current === productId;
|
|
1023
1070
|
const notInitialized = !isInitializedRef.current;
|
|
1024
|
-
const
|
|
1071
|
+
const currentMetadata = (data == null ? void 0 : data.metadata) ?? {};
|
|
1072
|
+
const currentMetadataString = JSON.stringify(currentMetadata);
|
|
1025
1073
|
const metadataChanged = currentMetadataString !== metadataStringRef.current;
|
|
1026
|
-
if (
|
|
1027
|
-
const currentMetadata = data.metadata ?? {};
|
|
1074
|
+
if (hasProductData && descriptorsLoaded && sameProduct && (notInitialized || metadataChanged)) {
|
|
1028
1075
|
const newInitialState = buildInitialFormState(descriptors, currentMetadata);
|
|
1029
1076
|
setBaselineMetadata(currentMetadata);
|
|
1030
1077
|
setValues(newInitialState);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsxs, jsx, Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { defineWidgetConfig } from "@medusajs/admin-sdk";
|
|
3
3
|
import { Container, Heading, Badge, Text, Skeleton, InlineTip, Button, Switch, Textarea, Input, toast } from "@medusajs/ui";
|
|
4
|
-
import { useState, useEffect, useMemo
|
|
4
|
+
import { useState, useRef, useEffect, useMemo } from "react";
|
|
5
5
|
import { useQuery, useQueryClient } from "@tanstack/react-query";
|
|
6
6
|
const METADATA_FIELD_TYPES = ["number", "text", "file", "bool"];
|
|
7
7
|
const VALID_FIELD_TYPES = new Set(METADATA_FIELD_TYPES);
|
|
@@ -151,23 +151,61 @@ const useOrderMetadataConfig = () => useMetadataConfig("order");
|
|
|
151
151
|
const CONFIG_DOCS_URL$2 = "https://docs.medusajs.com/admin/extension-points/widgets#product-category-details";
|
|
152
152
|
const CategoryMetadataTableWidget = ({ data }) => {
|
|
153
153
|
const { data: descriptors = [], isPending, isError } = useCategoryMetadataConfig();
|
|
154
|
-
const
|
|
155
|
-
const [baselineMetadata, setBaselineMetadata] = useState(
|
|
154
|
+
const categoryId = (data == null ? void 0 : data.id) ?? void 0;
|
|
155
|
+
const [baselineMetadata, setBaselineMetadata] = useState(
|
|
156
|
+
(data == null ? void 0 : data.metadata) ?? {}
|
|
157
|
+
);
|
|
156
158
|
const queryClient = useQueryClient();
|
|
159
|
+
const previousCategoryIdRef = useRef(categoryId);
|
|
160
|
+
const isInitializedRef = useRef(false);
|
|
161
|
+
const dataRef = useRef(data);
|
|
162
|
+
const descriptorsRef = useRef(descriptors);
|
|
163
|
+
useEffect(() => {
|
|
164
|
+
dataRef.current = data;
|
|
165
|
+
descriptorsRef.current = descriptors;
|
|
166
|
+
}, [data, descriptors]);
|
|
167
|
+
useEffect(() => {
|
|
168
|
+
var _a;
|
|
169
|
+
if (previousCategoryIdRef.current === categoryId && isInitializedRef.current) {
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
const categoryIdChanged = previousCategoryIdRef.current !== categoryId;
|
|
173
|
+
if (categoryIdChanged || !isInitializedRef.current) {
|
|
174
|
+
const currentMetadata = (data == null ? void 0 : data.metadata) ?? ((_a = dataRef.current) == null ? void 0 : _a.metadata) ?? {};
|
|
175
|
+
const currentDescriptors = descriptorsRef.current.length > 0 ? descriptorsRef.current : descriptors;
|
|
176
|
+
if (currentDescriptors.length === 0) {
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
previousCategoryIdRef.current = categoryId;
|
|
180
|
+
setBaselineMetadata(currentMetadata);
|
|
181
|
+
const newInitialState = buildInitialFormState(currentDescriptors, currentMetadata);
|
|
182
|
+
setValues(newInitialState);
|
|
183
|
+
isInitializedRef.current = true;
|
|
184
|
+
}
|
|
185
|
+
}, [categoryId]);
|
|
186
|
+
const metadataStringRef = useRef("");
|
|
157
187
|
useEffect(() => {
|
|
158
|
-
|
|
159
|
-
|
|
188
|
+
const hasCategoryData = !!data;
|
|
189
|
+
const descriptorsLoaded = descriptors.length > 0;
|
|
190
|
+
const sameCategory = previousCategoryIdRef.current === categoryId;
|
|
191
|
+
const notInitialized = !isInitializedRef.current;
|
|
192
|
+
const currentMetadata = (data == null ? void 0 : data.metadata) ?? {};
|
|
193
|
+
const currentMetadataString = JSON.stringify(currentMetadata);
|
|
194
|
+
const metadataChanged = currentMetadataString !== metadataStringRef.current;
|
|
195
|
+
if (hasCategoryData && descriptorsLoaded && sameCategory && (notInitialized || metadataChanged)) {
|
|
196
|
+
const newInitialState = buildInitialFormState(descriptors, currentMetadata);
|
|
197
|
+
setBaselineMetadata(currentMetadata);
|
|
198
|
+
setValues(newInitialState);
|
|
199
|
+
metadataStringRef.current = currentMetadataString;
|
|
200
|
+
isInitializedRef.current = true;
|
|
201
|
+
}
|
|
202
|
+
}, [data, descriptors.length, categoryId]);
|
|
160
203
|
const initialState = useMemo(
|
|
161
204
|
() => buildInitialFormState(descriptors, baselineMetadata),
|
|
162
205
|
[descriptors, baselineMetadata]
|
|
163
206
|
);
|
|
164
|
-
const [values, setValues] = useState(
|
|
165
|
-
initialState
|
|
166
|
-
);
|
|
207
|
+
const [values, setValues] = useState({});
|
|
167
208
|
const [isSaving, setIsSaving] = useState(false);
|
|
168
|
-
useEffect(() => {
|
|
169
|
-
setValues(initialState);
|
|
170
|
-
}, [initialState]);
|
|
171
209
|
const errors = useMemo(() => {
|
|
172
210
|
return descriptors.reduce((acc, descriptor) => {
|
|
173
211
|
const error = validateValueForDescriptor(descriptor, values[descriptor.key]);
|
|
@@ -233,6 +271,15 @@ const CategoryMetadataTableWidget = ({ data }) => {
|
|
|
233
271
|
await queryClient.invalidateQueries({
|
|
234
272
|
queryKey: ["product-categories"]
|
|
235
273
|
});
|
|
274
|
+
await queryClient.invalidateQueries({
|
|
275
|
+
queryKey: ["product-category", data.id]
|
|
276
|
+
});
|
|
277
|
+
if (data.id) {
|
|
278
|
+
queryClient.refetchQueries({
|
|
279
|
+
queryKey: ["product-category", data.id]
|
|
280
|
+
}).catch(() => {
|
|
281
|
+
});
|
|
282
|
+
}
|
|
236
283
|
} catch (error) {
|
|
237
284
|
toast.error(error instanceof Error ? error.message : "Save failed");
|
|
238
285
|
} finally {
|
|
@@ -247,7 +294,7 @@ const CategoryMetadataTableWidget = ({ data }) => {
|
|
|
247
294
|
] }),
|
|
248
295
|
/* @__PURE__ */ jsx(Text, { className: "text-ui-fg-subtle", children: "Structured metadata mapped to the keys you configured in the plugin options." })
|
|
249
296
|
] }),
|
|
250
|
-
isPending ? /* @__PURE__ */ jsx(Skeleton, { className: "h-[160px] w-full" }) : isError ? /* @__PURE__ */ jsxs(InlineTip, { variant: "error", label: "Configuration unavailable", children: [
|
|
297
|
+
isPending || !isInitializedRef.current || Object.keys(values).length === 0 ? /* @__PURE__ */ jsx(Skeleton, { className: "h-[160px] w-full" }) : isError ? /* @__PURE__ */ jsxs(InlineTip, { variant: "error", label: "Configuration unavailable", children: [
|
|
251
298
|
"Unable to load metadata configuration for this plugin. Confirm that the plugin is registered with options in ",
|
|
252
299
|
/* @__PURE__ */ jsx("code", { children: "medusa-config.ts" }),
|
|
253
300
|
"."
|
|
@@ -1016,14 +1063,14 @@ const ProductMetadataTableWidget = ({ data }) => {
|
|
|
1016
1063
|
}, [productId]);
|
|
1017
1064
|
const metadataStringRef = useRef("");
|
|
1018
1065
|
useEffect(() => {
|
|
1019
|
-
const
|
|
1066
|
+
const hasProductData = !!data;
|
|
1020
1067
|
const descriptorsLoaded = descriptors.length > 0;
|
|
1021
1068
|
const sameProduct = previousProductIdRef.current === productId;
|
|
1022
1069
|
const notInitialized = !isInitializedRef.current;
|
|
1023
|
-
const
|
|
1070
|
+
const currentMetadata = (data == null ? void 0 : data.metadata) ?? {};
|
|
1071
|
+
const currentMetadataString = JSON.stringify(currentMetadata);
|
|
1024
1072
|
const metadataChanged = currentMetadataString !== metadataStringRef.current;
|
|
1025
|
-
if (
|
|
1026
|
-
const currentMetadata = data.metadata ?? {};
|
|
1073
|
+
if (hasProductData && descriptorsLoaded && sameProduct && (notInitialized || metadataChanged)) {
|
|
1027
1074
|
const newInitialState = buildInitialFormState(descriptors, currentMetadata);
|
|
1028
1075
|
setBaselineMetadata(currentMetadata);
|
|
1029
1076
|
setValues(newInitialState);
|