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 metadata = (data == null ? void 0 : data.metadata) ?? {};
156
- const [baselineMetadata, setBaselineMetadata] = react.useState(metadata);
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
- setBaselineMetadata(metadata);
160
- }, [metadata]);
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 hasMetadata = (data == null ? void 0 : data.metadata) && Object.keys(data.metadata).length > 0;
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 currentMetadataString = hasMetadata ? JSON.stringify(data.metadata) : "";
687
+ const currentMetadata = (data == null ? void 0 : data.metadata) ?? {};
688
+ const currentMetadataString = JSON.stringify(currentMetadata);
641
689
  const metadataChanged = currentMetadataString !== metadataStringRef.current;
642
- if (hasMetadata && descriptorsLoaded && sameOrder && (notInitialized || metadataChanged)) {
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, useRef } from "react";
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 metadata = (data == null ? void 0 : data.metadata) ?? {};
155
- const [baselineMetadata, setBaselineMetadata] = useState(metadata);
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
- setBaselineMetadata(metadata);
159
- }, [metadata]);
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 hasMetadata = (data == null ? void 0 : data.metadata) && Object.keys(data.metadata).length > 0;
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 currentMetadataString = hasMetadata ? JSON.stringify(data.metadata) : "";
686
+ const currentMetadata = (data == null ? void 0 : data.metadata) ?? {};
687
+ const currentMetadataString = JSON.stringify(currentMetadata);
640
688
  const metadataChanged = currentMetadataString !== metadataStringRef.current;
641
- if (hasMetadata && descriptorsLoaded && sameOrder && (notInitialized || metadataChanged)) {
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);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "medusa-product-helper",
3
- "version": "0.0.25",
3
+ "version": "0.0.27",
4
4
  "description": "A starter for Medusa plugins.",
5
5
  "author": "Medusa (https://medusajs.com)",
6
6
  "license": "MIT",