@medusajs/dashboard 3.0.0-snapshot-20251215083939 → 3.0.0-snapshot-20251215162333

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.
Files changed (110) hide show
  1. package/dist/{api-key-management-detail-7T6OT2S2.mjs → api-key-management-detail-NRGL7HHX.mjs} +1 -1
  2. package/dist/app.js +144 -155
  3. package/dist/app.mjs +2 -2
  4. package/dist/{campaign-detail-RT3BIGQA.mjs → campaign-detail-22Q6XWGL.mjs} +1 -1
  5. package/dist/{categories-metadata-QHA62GA3.mjs → categories-metadata-J7M3XWI7.mjs} +1 -1
  6. package/dist/{category-detail-TDB4GR5S.mjs → category-detail-RRKJPMEG.mjs} +2 -2
  7. package/dist/{category-products-KRSKJDWS.mjs → category-products-EFZRTCSF.mjs} +2 -2
  8. package/dist/{chunk-WJKYXU6P.mjs → chunk-DK7IWUMK.mjs} +1 -1
  9. package/dist/{chunk-7ESWXA2P.mjs → chunk-GRZSG4EP.mjs} +31 -9
  10. package/dist/{chunk-7ZJK3NWL.mjs → chunk-OHY2N2Q4.mjs} +2 -2
  11. package/dist/{chunk-QCRM6BTM.mjs → chunk-PHLCT2HA.mjs} +1 -1
  12. package/dist/{chunk-6EFHOMPL.mjs → chunk-RL5EYTP6.mjs} +1 -1
  13. package/dist/{chunk-P5TFUYGS.mjs → chunk-YTYDWNYA.mjs} +98 -98
  14. package/dist/{chunk-SKA4MWCK.mjs → chunk-YYOPBKME.mjs} +1 -1
  15. package/dist/{chunk-QBDKK5O4.mjs → chunk-ZMG5B4FG.mjs} +1 -1
  16. package/dist/{collection-add-products-4RJKJ7XJ.mjs → collection-add-products-XUMV6XR7.mjs} +2 -2
  17. package/dist/{collection-detail-IR23ZT2F.mjs → collection-detail-ONRBKJLN.mjs} +2 -2
  18. package/dist/{collection-list-J4OTLQQL.mjs → collection-list-XCC4SIPJ.mjs} +2 -2
  19. package/dist/{collection-metadata-6XWOWMBN.mjs → collection-metadata-QK7MI3D2.mjs} +1 -1
  20. package/dist/{customer-detail-ZHU4NN7E.mjs → customer-detail-FR6J37ZC.mjs} +1 -1
  21. package/dist/{customer-group-detail-NGJXBGGG.mjs → customer-group-detail-YSKSNETG.mjs} +1 -1
  22. package/dist/{customer-group-list-YLAMT3ZQ.mjs → customer-group-list-XBCD4FZH.mjs} +1 -1
  23. package/dist/{customers-add-customer-group-A2EPZW26.mjs → customers-add-customer-group-Q7FMR2Y5.mjs} +1 -1
  24. package/dist/{edit-rules-4UN6YMCZ.mjs → edit-rules-SMVRTCUP.mjs} +1 -1
  25. package/dist/{inventory-create-UB3TTWPQ.mjs → inventory-create-3XONKYMZ.mjs} +1 -1
  26. package/dist/{inventory-detail-FIC7BFZ7.mjs → inventory-detail-6A6GOLB6.mjs} +1 -1
  27. package/dist/{inventory-metadata-WP73FZBX.mjs → inventory-metadata-FNEJ3RAT.mjs} +1 -1
  28. package/dist/{inventory-stock-RR4F6HGF.mjs → inventory-stock-S3ZYYCMZ.mjs} +1 -1
  29. package/dist/{location-detail-MLYCXNYR.mjs → location-detail-N3GUZSY7.mjs} +1 -1
  30. package/dist/{location-fulfillment-providers-CAAUD5VG.mjs → location-fulfillment-providers-WM6DT252.mjs} +2 -2
  31. package/dist/{location-service-zone-shipping-option-create-HHEGEBVB.mjs → location-service-zone-shipping-option-create-MJPH3WKX.mjs} +1 -1
  32. package/dist/{login-C7GZL37K.mjs → login-VNOLI5YG.mjs} +1 -1
  33. package/dist/{order-create-claim-2RQ4SFKM.mjs → order-create-claim-GUYTLVPB.mjs} +1 -1
  34. package/dist/{order-create-edit-JL7FWVNC.mjs → order-create-edit-ODIN6GRW.mjs} +1 -1
  35. package/dist/{order-create-exchange-7EPUMDFZ.mjs → order-create-exchange-ZT5RBRKL.mjs} +1 -1
  36. package/dist/{order-create-fulfillment-5PUUSLCV.mjs → order-create-fulfillment-OWUVTZXW.mjs} +1 -1
  37. package/dist/{order-create-refund-3NYCD4UR.mjs → order-create-refund-Q6HQY42R.mjs} +1 -1
  38. package/dist/{order-create-shipment-PWT3BPP6.mjs → order-create-shipment-WAGGEPRW.mjs} +1 -1
  39. package/dist/{order-detail-CN7VCKHF.mjs → order-detail-HFJONELJ.mjs} +1 -1
  40. package/dist/{order-edit-billing-address-PLAKMBVH.mjs → order-edit-billing-address-UM76J4KX.mjs} +1 -1
  41. package/dist/{order-edit-email-UAP26F5X.mjs → order-edit-email-CL3KNOCM.mjs} +1 -1
  42. package/dist/{order-edit-shipping-address-HAC7UQZS.mjs → order-edit-shipping-address-PIESTGVL.mjs} +1 -1
  43. package/dist/{order-export-ZI4QK6OQ.mjs → order-export-4MZUPMGD.mjs} +1 -1
  44. package/dist/{order-metadata-VQJWKPQC.mjs → order-metadata-FHBB7MTG.mjs} +1 -1
  45. package/dist/{order-receive-return-VTHRRRAB.mjs → order-receive-return-PRVKP6J2.mjs} +1 -1
  46. package/dist/{order-request-transfer-MCWICULW.mjs → order-request-transfer-XSAGRUMT.mjs} +1 -1
  47. package/dist/{price-list-create-KF4BTDBF.mjs → price-list-create-YHXRQSC3.mjs} +2 -2
  48. package/dist/{price-list-detail-UHJWBRBT.mjs → price-list-detail-FR3FQR3H.mjs} +2 -2
  49. package/dist/{price-list-prices-add-YHPWWETC.mjs → price-list-prices-add-GJVI47OY.mjs} +2 -2
  50. package/dist/{product-attributes-CCRPVPA3.mjs → product-attributes-TKCE2M63.mjs} +2 -2
  51. package/dist/{product-create-TIJWWJEC.mjs → product-create-OLDZPMLW.mjs} +2 -2
  52. package/dist/{product-create-variant-EBVDKJA2.mjs → product-create-variant-KEBN5OR7.mjs} +1 -1
  53. package/dist/{product-detail-MFRDWD74.mjs → product-detail-O6QWJIKR.mjs} +2 -2
  54. package/dist/{product-edit-VRUDQ3JT.mjs → product-edit-56XDGDUN.mjs} +2 -2
  55. package/dist/{product-export-DZKMXMUX.mjs → product-export-WUZYHPS5.mjs} +2 -2
  56. package/dist/{product-image-variants-edit-NN76FX7Y.mjs → product-image-variants-edit-Y363J5NG.mjs} +1 -1
  57. package/dist/{product-import-24JJ73RO.mjs → product-import-V3KQN4TV.mjs} +1 -1
  58. package/dist/{product-list-YMCK3X7X.mjs → product-list-DNTS7WUN.mjs} +2 -2
  59. package/dist/{product-metadata-KFBUYD7A.mjs → product-metadata-GL2MVPDI.mjs} +1 -1
  60. package/dist/{product-organization-BYRWH4KK.mjs → product-organization-PNKWRNHC.mjs} +2 -2
  61. package/dist/{product-stock-YEHDIJQI.mjs → product-stock-NYUFMEVG.mjs} +1 -1
  62. package/dist/{product-tag-create-BPU54Y3F.mjs → product-tag-create-PQMDDKWH.mjs} +1 -1
  63. package/dist/{product-tag-detail-SYQWG3AL.mjs → product-tag-detail-EHBB3WUB.mjs} +3 -3
  64. package/dist/{product-tag-edit-5XEMIUW6.mjs → product-tag-edit-K3BBQLJR.mjs} +1 -1
  65. package/dist/{product-tag-list-7SQNKPJQ.mjs → product-tag-list-LSW5FFVN.mjs} +3 -3
  66. package/dist/{product-tag-metadata-ZB56PD4G.mjs → product-tag-metadata-MJH5LH7E.mjs} +1 -1
  67. package/dist/{product-type-detail-RMYDLMPI.mjs → product-type-detail-3VB6AWUW.mjs} +2 -2
  68. package/dist/{product-type-metadata-UKF26V3N.mjs → product-type-metadata-CDJDFFGQ.mjs} +1 -1
  69. package/dist/{product-variant-detail-56MJKJZQ.mjs → product-variant-detail-43T33AQP.mjs} +1 -1
  70. package/dist/{product-variant-edit-PVZNSIIQ.mjs → product-variant-edit-DEZEY2H2.mjs} +1 -1
  71. package/dist/{product-variant-metadata-PNFRS7SQ.mjs → product-variant-metadata-VTZDNWUT.mjs} +1 -1
  72. package/dist/{promotion-create-RGLB6D7K.mjs → promotion-create-HWFNUQXG.mjs} +1 -1
  73. package/dist/{promotion-detail-MCCRIT2M.mjs → promotion-detail-VJB55PJK.mjs} +1 -1
  74. package/dist/{refund-reason-create-JYY2USGC.mjs → refund-reason-create-YHCDEHGQ.mjs} +1 -1
  75. package/dist/{refund-reason-edit-5NFS4TQ7.mjs → refund-reason-edit-CZ5QZ2SZ.mjs} +1 -1
  76. package/dist/{refund-reason-list-SDLJWAV3.mjs → refund-reason-list-URYYYEK6.mjs} +1 -1
  77. package/dist/{region-metadata-YBOCBHWP.mjs → region-metadata-H6XXUQ4S.mjs} +1 -1
  78. package/dist/{reservation-detail-7MXAMP3C.mjs → reservation-detail-LZAQL4XA.mjs} +1 -1
  79. package/dist/{reservation-metadata-6NZUP64D.mjs → reservation-metadata-5HZSDDOK.mjs} +1 -1
  80. package/dist/{sales-channel-add-products-BELGXDPF.mjs → sales-channel-add-products-VH5T3GDA.mjs} +2 -2
  81. package/dist/{sales-channel-detail-FAGKAQK2.mjs → sales-channel-detail-I2ZHVXMG.mjs} +2 -2
  82. package/dist/{sales-channel-list-E5QO23E5.mjs → sales-channel-list-3FV4S2NN.mjs} +1 -1
  83. package/dist/{sales-channel-metadata-AXAQY4MY.mjs → sales-channel-metadata-M364R4RJ.mjs} +1 -1
  84. package/dist/{shipping-option-type-create-YTBF47L7.mjs → shipping-option-type-create-C5WUWON7.mjs} +1 -1
  85. package/dist/{shipping-option-type-detail-XJFVNP2V.mjs → shipping-option-type-detail-PENS2K73.mjs} +2 -2
  86. package/dist/{shipping-option-type-edit-DFXO32AG.mjs → shipping-option-type-edit-CIU5EHRP.mjs} +1 -1
  87. package/dist/{shipping-option-type-list-UI7ZTCO7.mjs → shipping-option-type-list-ZMZMXFME.mjs} +2 -2
  88. package/dist/{shipping-profile-metadata-FGZRQKNN.mjs → shipping-profile-metadata-75G2NNMA.mjs} +1 -1
  89. package/dist/{store-add-locales-3MSEBHQG.mjs → store-add-locales-IZOZP5C6.mjs} +1 -1
  90. package/dist/{store-detail-MLYFQGBC.mjs → store-detail-4IBAEVSD.mjs} +1 -1
  91. package/dist/{store-metadata-ITA6AL6H.mjs → store-metadata-CYXTVJUE.mjs} +1 -1
  92. package/dist/{tax-region-create-AXM2SE4T.mjs → tax-region-create-DWGL4EUT.mjs} +1 -1
  93. package/dist/{tax-region-detail-WFXSRH3U.mjs → tax-region-detail-O2T7BI3V.mjs} +5 -5
  94. package/dist/{tax-region-edit-CZ4EDU4K.mjs → tax-region-edit-EEVEEU2Q.mjs} +1 -1
  95. package/dist/{tax-region-province-detail-4B5GWCY7.mjs → tax-region-province-detail-2W7RXAM5.mjs} +5 -5
  96. package/dist/{tax-region-tax-override-create-GDDSUSHK.mjs → tax-region-tax-override-create-7IM4ZVPH.mjs} +3 -3
  97. package/dist/{tax-region-tax-override-edit-QXCSGDVG.mjs → tax-region-tax-override-edit-3ZT5IZYR.mjs} +4 -4
  98. package/dist/{translation-list-S4477JFR.mjs → translation-list-AFK5MGSH.mjs} +56 -68
  99. package/dist/{translations-edit-S3V7SSDA.mjs → translations-edit-EN47PWTO.mjs} +24 -26
  100. package/dist/{user-metadata-SILGZHTG.mjs → user-metadata-2WPJOEJA.mjs} +1 -1
  101. package/dist/{workflow-execution-detail-GJTST4GO.mjs → workflow-execution-detail-H2AKEZJX.mjs} +1 -1
  102. package/package.json +9 -9
  103. package/src/hooks/api/translations.tsx +61 -31
  104. package/src/routes/translations/translation-list/components/translation-list-section/translation-list-section.tsx +1 -8
  105. package/src/routes/translations/translation-list/components/translations-completion-section/translations-completion-section.tsx +10 -4
  106. package/src/routes/translations/translation-list/translation-list.tsx +66 -68
  107. package/src/routes/translations/translations-edit/components/translations-edit-form/translations-edit-form.tsx +4 -2
  108. package/src/routes/translations/translations-edit/translations-edit.tsx +27 -12
  109. package/src/routes/translations/translations-edit/utils/index.ts +0 -1
  110. package/src/routes/translations/translations-edit/utils/reference-label-map.ts +0 -10
@@ -2,96 +2,92 @@ import { Container, Heading, Text } from "@medusajs/ui"
2
2
  import { TwoColumnPage } from "../../../components/layout/pages"
3
3
  import { useTranslation } from "react-i18next"
4
4
  import { Buildings } from "@medusajs/icons"
5
- import { useStore } from "../../../hooks/api"
5
+ import {
6
+ useStore,
7
+ useTranslationSettings,
8
+ useTranslationStatistics,
9
+ } from "../../../hooks/api"
6
10
  import { ActiveLocalesSection } from "./components/active-locales-section/active-locales-section"
7
11
  import { TranslationListSection } from "./components/translation-list-section/translation-list-section"
8
12
  import { TranslationsCompletionSection } from "./components/translations-completion-section/translations-completion-section"
9
13
  import { TwoColumnPageSkeleton } from "../../../components/common/skeleton"
14
+ import { useMemo } from "react"
10
15
 
11
16
  export type TranslatableEntity = {
12
- icon: React.ReactNode
13
17
  label: string
14
18
  reference: string
19
+ translatableFields: string[]
15
20
  translatedCount?: number
16
21
  totalCount?: number
17
22
  }
18
23
 
19
- const TRANSLATABLE_ENTITIES: TranslatableEntity[] = [
20
- {
21
- icon: <Buildings />,
22
- label: "Product",
23
- reference: "product",
24
- translatedCount: 4,
25
- totalCount: 96,
26
- },
27
- {
28
- icon: <Buildings />,
29
- label: "Product Variants",
30
- reference: "product_variant",
31
- translatedCount: 4,
32
- totalCount: 200000,
33
- },
34
- {
35
- icon: <Buildings />,
36
- label: "Product Categories",
37
- reference: "product_category",
38
- translatedCount: 96,
39
- totalCount: 96,
40
- },
41
- {
42
- icon: <Buildings />,
43
- label: "Product Collections",
44
- reference: "product_collection",
45
- translatedCount: 4,
46
- totalCount: 96,
47
- },
48
- {
49
- icon: <Buildings />,
50
- label: "Product Types",
51
- reference: "product_type",
52
- translatedCount: 4,
53
- totalCount: 96,
54
- },
55
- {
56
- icon: <Buildings />,
57
- label: "Product Tags",
58
- reference: "product_tag",
59
- translatedCount: 96,
60
- totalCount: 96,
61
- },
62
- {
63
- icon: <Buildings />,
64
- label: "Product Options",
65
- reference: "product_option",
66
- translatedCount: 96,
67
- totalCount: 96,
68
- },
69
- {
70
- icon: <Buildings />,
71
- label: "Product Option Values",
72
- reference: "product_option_value",
73
- translatedCount: 96,
74
- totalCount: 96,
75
- },
76
- ]
77
-
78
24
  export const TranslationList = () => {
79
25
  const { t } = useTranslation()
80
26
 
81
27
  const { store, isPending, isError, error } = useStore()
28
+ const {
29
+ translatable_fields,
30
+ isPending: isTranslationSettingsPending,
31
+ isError: isTranslationSettingsError,
32
+ error: translationSettingsError,
33
+ } = useTranslationSettings()
34
+ const {
35
+ statistics,
36
+ isPending: isTranslationStatisticsPending,
37
+ isError: isTranslationStatisticsError,
38
+ error: translationStatisticsError,
39
+ } = useTranslationStatistics(
40
+ {
41
+ locales:
42
+ store?.supported_locales?.map(
43
+ (suportedLocale) => suportedLocale.locale_code
44
+ ) ?? [],
45
+ entity_types: Object.keys(translatable_fields ?? {}),
46
+ },
47
+ {
48
+ enabled: !!translatable_fields && !!store,
49
+ }
50
+ )
82
51
 
83
- if (isError) {
84
- throw error
52
+ if (isError || isTranslationSettingsError || isTranslationStatisticsError) {
53
+ throw error || translationSettingsError || translationStatisticsError
85
54
  }
86
55
 
87
- const isReady = !!store && !isPending
56
+ const hasLocales = (store?.supported_locales ?? []).length > 0
57
+
58
+ const translatableEntities: TranslatableEntity[] = useMemo(() => {
59
+ if (!translatable_fields || !statistics) {
60
+ return []
61
+ }
62
+
63
+ return Object.entries(translatable_fields).map(([entity, fields]) => {
64
+ const entityStatistics = statistics[entity]
65
+
66
+ return {
67
+ label: entity
68
+ .split("_")
69
+ .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
70
+ .join(" "),
71
+ reference: entity,
72
+ translatableFields: fields,
73
+ translatedCount: entityStatistics.translated,
74
+ totalCount: entityStatistics.expected,
75
+ }
76
+ })
77
+ }, [translatable_fields, statistics])
78
+
79
+ const isReady =
80
+ !!store &&
81
+ !isPending &&
82
+ !isTranslationSettingsPending &&
83
+ !isTranslationStatisticsPending &&
84
+ !!translatable_fields &&
85
+ !!statistics
88
86
 
89
87
  if (!isReady) {
90
88
  return <TwoColumnPageSkeleton sidebarSections={2} />
91
89
  }
92
90
 
93
- const hasLocales = (store?.supported_locales ?? []).length > 0
94
-
95
91
  return (
96
92
  <TwoColumnPage
97
93
  widgets={{
@@ -109,7 +105,7 @@ export const TranslationList = () => {
109
105
  </Text>
110
106
  </Container>
111
107
  <TranslationListSection
112
- entities={TRANSLATABLE_ENTITIES}
108
+ entities={translatableEntities}
113
109
  hasLocales={hasLocales}
114
110
  />
115
111
  </TwoColumnPage.Main>
@@ -121,7 +117,9 @@ export const TranslationList = () => {
121
117
  ) ?? []
122
118
  }
123
119
  ></ActiveLocalesSection>
124
- <TranslationsCompletionSection />
120
+ {statistics && (
121
+ <TranslationsCompletionSection statistics={statistics} />
122
+ )}
125
123
  </TwoColumnPage.Sidebar>
126
124
  </TwoColumnPage>
127
125
  )
@@ -18,7 +18,6 @@ import {
18
18
  import { KeyboundForm } from "../../../../../components/utilities/keybound-form"
19
19
  import { useBatchTranslations } from "../../../../../hooks/api/translations"
20
20
  import { useDocumentDirection } from "../../../../../hooks/use-document-direction"
21
- import { REFERENCE_LABEL_MAP } from "../../utils"
22
21
 
23
22
  /**
24
23
  * Schema for a single locale translation.
@@ -441,7 +440,10 @@ export const TranslationsEditForm = ({
441
440
  <div className="-my-2 w-full border-l">
442
441
  <ProgressTabs.List className="justify-start-start flex w-full items-center">
443
442
  <ProgressTabs.Trigger value={entityType}>
444
- {REFERENCE_LABEL_MAP[entityType]}
443
+ {entityType
444
+ .split("_")
445
+ .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
446
+ .join(" ")}
445
447
  </ProgressTabs.Trigger>
446
448
  </ProgressTabs.List>
447
449
  </div>
@@ -1,5 +1,9 @@
1
1
  import { useNavigate, useSearchParams } from "react-router-dom"
2
- import { useReferenceTranslations, useStore } from "../../../hooks/api"
2
+ import {
3
+ useReferenceTranslations,
4
+ useStore,
5
+ useTranslationSettings,
6
+ } from "../../../hooks/api"
3
7
  import { TranslationsEditForm } from "./components/translations-edit-form"
4
8
  import { useEffect } from "react"
5
9
  import { RouteFocusModal } from "../../../components/modals"
@@ -20,10 +24,16 @@ export const TranslationsEdit = () => {
20
24
  }
21
25
  }, [reference, navigate, isTranslationsEnabled])
22
26
 
27
+ const {
28
+ translatable_fields,
29
+ isPending: isTranslationSettingsPending,
30
+ isError: isTranslationSettingsError,
31
+ error: translationSettingsError,
32
+ } = useTranslationSettings({ entity_type: reference! })
33
+
23
34
  const {
24
35
  translations,
25
36
  references,
26
- translatableFields,
27
37
  fetchNextPage,
28
38
  count,
29
39
  isFetchingNextPage,
@@ -31,10 +41,15 @@ export const TranslationsEdit = () => {
31
41
  isPending,
32
42
  isError,
33
43
  error,
34
- } = useReferenceTranslations(reference!, referenceIdParam, {
35
- placeholderData: keepPreviousData,
36
- })
37
-
44
+ } = useReferenceTranslations(
45
+ reference!,
46
+ translatable_fields?.[reference!] ?? [],
47
+ referenceIdParam,
48
+ {
49
+ enabled: !!translatable_fields && !!reference,
50
+ placeholderData: keepPreviousData,
51
+ }
52
+ )
38
53
  const {
39
54
  store,
40
55
  isPending: isStorePending,
@@ -45,13 +60,14 @@ export const TranslationsEdit = () => {
45
60
  const ready =
46
61
  !isPending &&
47
62
  !!translations &&
48
- !!translatableFields &&
63
+ !!translatable_fields &&
64
+ !isTranslationSettingsPending &&
49
65
  !!references &&
50
66
  !isStorePending &&
51
67
  !!store
52
68
 
53
- if (isError || isStoreError) {
54
- throw error || storeError
69
+ if (isError || isStoreError || isTranslationSettingsError) {
70
+ throw error || storeError || translationSettingsError
55
71
  }
56
72
 
57
73
  return (
@@ -62,9 +78,8 @@ export const TranslationsEdit = () => {
62
78
  references={references}
63
79
  entityType={reference!}
64
80
  availableLocales={store?.supported_locales ?? []}
65
- // TODO: change this to get it from the entity translation config when we have it
66
- translatableFields={translatableFields}
67
- modalFields={translatableFields}
81
+ translatableFields={translatable_fields[reference!]}
82
+ modalFields={translatable_fields[reference!]}
68
83
  fetchNextPage={fetchNextPage}
69
84
  hasNextPage={hasNextPage}
70
85
  isFetchingNextPage={isFetchingNextPage}
@@ -1 +0,0 @@
1
- export * from "./reference-label-map"
@@ -1,10 +0,0 @@
1
- export const REFERENCE_LABEL_MAP: Record<string, string> = {
2
- product: "Products",
3
- product_variant: "Product Variants",
4
- product_category: "Product Categories",
5
- product_collection: "Product Collections",
6
- product_type: "Product Types",
7
- product_tag: "Product Tags",
8
- product_option: "Product Options",
9
- product_option_value: "Product Option Values",
10
- }