medusa-product-helper 0.0.25 → 0.0.27
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
|
"."
|
|
@@ -633,14 +680,14 @@ const OrderMetadataTableWidget = ({ data }) => {
|
|
|
633
680
|
}, [orderId]);
|
|
634
681
|
const metadataStringRef = react.useRef("");
|
|
635
682
|
react.useEffect(() => {
|
|
636
|
-
const
|
|
683
|
+
const hasOrderData = !!data;
|
|
637
684
|
const descriptorsLoaded = descriptors.length > 0;
|
|
638
685
|
const sameOrder = previousOrderIdRef.current === orderId;
|
|
639
686
|
const notInitialized = !isInitializedRef.current;
|
|
640
|
-
const
|
|
687
|
+
const currentMetadata = (data == null ? void 0 : data.metadata) ?? {};
|
|
688
|
+
const currentMetadataString = JSON.stringify(currentMetadata);
|
|
641
689
|
const metadataChanged = currentMetadataString !== metadataStringRef.current;
|
|
642
|
-
if (
|
|
643
|
-
const currentMetadata = data.metadata ?? {};
|
|
690
|
+
if (hasOrderData && descriptorsLoaded && sameOrder && (notInitialized || metadataChanged)) {
|
|
644
691
|
const newInitialState = buildInitialFormState(descriptors, currentMetadata);
|
|
645
692
|
setBaselineMetadata(currentMetadata);
|
|
646
693
|
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
|
"."
|
|
@@ -632,14 +679,14 @@ const OrderMetadataTableWidget = ({ data }) => {
|
|
|
632
679
|
}, [orderId]);
|
|
633
680
|
const metadataStringRef = useRef("");
|
|
634
681
|
useEffect(() => {
|
|
635
|
-
const
|
|
682
|
+
const hasOrderData = !!data;
|
|
636
683
|
const descriptorsLoaded = descriptors.length > 0;
|
|
637
684
|
const sameOrder = previousOrderIdRef.current === orderId;
|
|
638
685
|
const notInitialized = !isInitializedRef.current;
|
|
639
|
-
const
|
|
686
|
+
const currentMetadata = (data == null ? void 0 : data.metadata) ?? {};
|
|
687
|
+
const currentMetadataString = JSON.stringify(currentMetadata);
|
|
640
688
|
const metadataChanged = currentMetadataString !== metadataStringRef.current;
|
|
641
|
-
if (
|
|
642
|
-
const currentMetadata = data.metadata ?? {};
|
|
689
|
+
if (hasOrderData && descriptorsLoaded && sameOrder && (notInitialized || metadataChanged)) {
|
|
643
690
|
const newInitialState = buildInitialFormState(descriptors, currentMetadata);
|
|
644
691
|
setBaselineMetadata(currentMetadata);
|
|
645
692
|
setValues(newInitialState);
|