@medusajs/dashboard 3.0.0-snapshot-20251215083939 → 3.0.0-snapshot-20251216103925
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/dist/{api-key-management-detail-7T6OT2S2.mjs → api-key-management-detail-NRGL7HHX.mjs} +1 -1
- package/dist/app.css +0 -8
- package/dist/app.js +197 -198
- package/dist/app.mjs +2 -2
- package/dist/{campaign-detail-RT3BIGQA.mjs → campaign-detail-22Q6XWGL.mjs} +1 -1
- package/dist/{categories-metadata-QHA62GA3.mjs → categories-metadata-J7M3XWI7.mjs} +1 -1
- package/dist/{category-detail-TDB4GR5S.mjs → category-detail-RRKJPMEG.mjs} +2 -2
- package/dist/{category-products-KRSKJDWS.mjs → category-products-EFZRTCSF.mjs} +2 -2
- package/dist/{chunk-WJKYXU6P.mjs → chunk-DK7IWUMK.mjs} +1 -1
- package/dist/{chunk-7ESWXA2P.mjs → chunk-GRZSG4EP.mjs} +31 -9
- package/dist/{chunk-P5TFUYGS.mjs → chunk-O7WJSSQR.mjs} +104 -98
- package/dist/{chunk-7ZJK3NWL.mjs → chunk-OHY2N2Q4.mjs} +2 -2
- package/dist/{chunk-QCRM6BTM.mjs → chunk-PHLCT2HA.mjs} +1 -1
- package/dist/{chunk-6EFHOMPL.mjs → chunk-RL5EYTP6.mjs} +1 -1
- package/dist/{chunk-SKA4MWCK.mjs → chunk-YYOPBKME.mjs} +1 -1
- package/dist/{chunk-QBDKK5O4.mjs → chunk-ZMG5B4FG.mjs} +1 -1
- package/dist/{collection-add-products-4RJKJ7XJ.mjs → collection-add-products-XUMV6XR7.mjs} +2 -2
- package/dist/{collection-detail-IR23ZT2F.mjs → collection-detail-ONRBKJLN.mjs} +2 -2
- package/dist/{collection-list-J4OTLQQL.mjs → collection-list-XCC4SIPJ.mjs} +2 -2
- package/dist/{collection-metadata-6XWOWMBN.mjs → collection-metadata-QK7MI3D2.mjs} +1 -1
- package/dist/{customer-detail-ZHU4NN7E.mjs → customer-detail-FR6J37ZC.mjs} +1 -1
- package/dist/{customer-group-detail-NGJXBGGG.mjs → customer-group-detail-YSKSNETG.mjs} +1 -1
- package/dist/{customer-group-list-YLAMT3ZQ.mjs → customer-group-list-XBCD4FZH.mjs} +1 -1
- package/dist/{customers-add-customer-group-A2EPZW26.mjs → customers-add-customer-group-Q7FMR2Y5.mjs} +1 -1
- package/dist/{edit-rules-4UN6YMCZ.mjs → edit-rules-SMVRTCUP.mjs} +1 -1
- package/dist/en.json +3 -0
- package/dist/{inventory-create-UB3TTWPQ.mjs → inventory-create-3XONKYMZ.mjs} +1 -1
- package/dist/{inventory-detail-FIC7BFZ7.mjs → inventory-detail-6A6GOLB6.mjs} +1 -1
- package/dist/{inventory-metadata-WP73FZBX.mjs → inventory-metadata-FNEJ3RAT.mjs} +1 -1
- package/dist/{inventory-stock-RR4F6HGF.mjs → inventory-stock-S3ZYYCMZ.mjs} +1 -1
- package/dist/{location-detail-MLYCXNYR.mjs → location-detail-N3GUZSY7.mjs} +1 -1
- package/dist/{location-fulfillment-providers-CAAUD5VG.mjs → location-fulfillment-providers-WM6DT252.mjs} +2 -2
- package/dist/{location-service-zone-shipping-option-create-HHEGEBVB.mjs → location-service-zone-shipping-option-create-MJPH3WKX.mjs} +1 -1
- package/dist/{login-C7GZL37K.mjs → login-VNOLI5YG.mjs} +1 -1
- package/dist/{order-create-claim-2RQ4SFKM.mjs → order-create-claim-GUYTLVPB.mjs} +1 -1
- package/dist/{order-create-edit-JL7FWVNC.mjs → order-create-edit-ODIN6GRW.mjs} +1 -1
- package/dist/{order-create-exchange-7EPUMDFZ.mjs → order-create-exchange-ZT5RBRKL.mjs} +1 -1
- package/dist/{order-create-fulfillment-5PUUSLCV.mjs → order-create-fulfillment-OWUVTZXW.mjs} +1 -1
- package/dist/{order-create-refund-3NYCD4UR.mjs → order-create-refund-Q6HQY42R.mjs} +1 -1
- package/dist/{order-create-shipment-PWT3BPP6.mjs → order-create-shipment-WAGGEPRW.mjs} +1 -1
- package/dist/{order-detail-CN7VCKHF.mjs → order-detail-HFJONELJ.mjs} +1 -1
- package/dist/{order-edit-billing-address-PLAKMBVH.mjs → order-edit-billing-address-UM76J4KX.mjs} +1 -1
- package/dist/{order-edit-email-UAP26F5X.mjs → order-edit-email-CL3KNOCM.mjs} +1 -1
- package/dist/{order-edit-shipping-address-HAC7UQZS.mjs → order-edit-shipping-address-PIESTGVL.mjs} +1 -1
- package/dist/{order-export-ZI4QK6OQ.mjs → order-export-4MZUPMGD.mjs} +1 -1
- package/dist/{order-metadata-VQJWKPQC.mjs → order-metadata-FHBB7MTG.mjs} +1 -1
- package/dist/{order-receive-return-VTHRRRAB.mjs → order-receive-return-PRVKP6J2.mjs} +1 -1
- package/dist/{order-request-transfer-MCWICULW.mjs → order-request-transfer-XSAGRUMT.mjs} +1 -1
- package/dist/{price-list-create-KF4BTDBF.mjs → price-list-create-YHXRQSC3.mjs} +2 -2
- package/dist/{price-list-detail-UHJWBRBT.mjs → price-list-detail-FR3FQR3H.mjs} +2 -2
- package/dist/{price-list-prices-add-YHPWWETC.mjs → price-list-prices-add-GJVI47OY.mjs} +2 -2
- package/dist/{product-attributes-CCRPVPA3.mjs → product-attributes-QD3BWV5V.mjs} +2 -2
- package/dist/{product-create-TIJWWJEC.mjs → product-create-E2GZYQX4.mjs} +2 -2
- package/dist/{product-create-variant-EBVDKJA2.mjs → product-create-variant-KEBN5OR7.mjs} +1 -1
- package/dist/{product-detail-MFRDWD74.mjs → product-detail-QBGGKRZ2.mjs} +2 -2
- package/dist/{product-edit-VRUDQ3JT.mjs → product-edit-YP4KOQ4T.mjs} +2 -2
- package/dist/{product-export-DZKMXMUX.mjs → product-export-WUZYHPS5.mjs} +2 -2
- package/dist/{product-image-variants-edit-NN76FX7Y.mjs → product-image-variants-edit-Y363J5NG.mjs} +1 -1
- package/dist/{product-import-24JJ73RO.mjs → product-import-V3KQN4TV.mjs} +1 -1
- package/dist/{product-list-YMCK3X7X.mjs → product-list-DNTS7WUN.mjs} +2 -2
- package/dist/{product-metadata-KFBUYD7A.mjs → product-metadata-GL2MVPDI.mjs} +1 -1
- package/dist/{product-organization-BYRWH4KK.mjs → product-organization-H557PLLB.mjs} +2 -2
- package/dist/{product-stock-YEHDIJQI.mjs → product-stock-NYUFMEVG.mjs} +1 -1
- package/dist/{product-tag-create-BPU54Y3F.mjs → product-tag-create-PQMDDKWH.mjs} +1 -1
- package/dist/{product-tag-detail-SYQWG3AL.mjs → product-tag-detail-EHBB3WUB.mjs} +3 -3
- package/dist/{product-tag-edit-5XEMIUW6.mjs → product-tag-edit-K3BBQLJR.mjs} +1 -1
- package/dist/{product-tag-list-7SQNKPJQ.mjs → product-tag-list-LSW5FFVN.mjs} +3 -3
- package/dist/{product-tag-metadata-ZB56PD4G.mjs → product-tag-metadata-MJH5LH7E.mjs} +1 -1
- package/dist/{product-type-detail-RMYDLMPI.mjs → product-type-detail-3VB6AWUW.mjs} +2 -2
- package/dist/{product-type-metadata-UKF26V3N.mjs → product-type-metadata-CDJDFFGQ.mjs} +1 -1
- package/dist/{product-variant-detail-56MJKJZQ.mjs → product-variant-detail-43T33AQP.mjs} +1 -1
- package/dist/{product-variant-edit-PVZNSIIQ.mjs → product-variant-edit-DEZEY2H2.mjs} +1 -1
- package/dist/{product-variant-metadata-PNFRS7SQ.mjs → product-variant-metadata-VTZDNWUT.mjs} +1 -1
- package/dist/{promotion-create-RGLB6D7K.mjs → promotion-create-HWFNUQXG.mjs} +1 -1
- package/dist/{promotion-detail-MCCRIT2M.mjs → promotion-detail-VJB55PJK.mjs} +1 -1
- package/dist/{refund-reason-create-JYY2USGC.mjs → refund-reason-create-YHCDEHGQ.mjs} +1 -1
- package/dist/{refund-reason-edit-5NFS4TQ7.mjs → refund-reason-edit-CZ5QZ2SZ.mjs} +1 -1
- package/dist/{refund-reason-list-SDLJWAV3.mjs → refund-reason-list-URYYYEK6.mjs} +1 -1
- package/dist/{region-metadata-YBOCBHWP.mjs → region-metadata-H6XXUQ4S.mjs} +1 -1
- package/dist/{reservation-detail-7MXAMP3C.mjs → reservation-detail-LZAQL4XA.mjs} +1 -1
- package/dist/{reservation-metadata-6NZUP64D.mjs → reservation-metadata-5HZSDDOK.mjs} +1 -1
- package/dist/{sales-channel-add-products-BELGXDPF.mjs → sales-channel-add-products-VH5T3GDA.mjs} +2 -2
- package/dist/{sales-channel-detail-FAGKAQK2.mjs → sales-channel-detail-I2ZHVXMG.mjs} +2 -2
- package/dist/{sales-channel-list-E5QO23E5.mjs → sales-channel-list-3FV4S2NN.mjs} +1 -1
- package/dist/{sales-channel-metadata-AXAQY4MY.mjs → sales-channel-metadata-M364R4RJ.mjs} +1 -1
- package/dist/{shipping-option-type-create-YTBF47L7.mjs → shipping-option-type-create-C5WUWON7.mjs} +1 -1
- package/dist/{shipping-option-type-detail-XJFVNP2V.mjs → shipping-option-type-detail-PENS2K73.mjs} +2 -2
- package/dist/{shipping-option-type-edit-DFXO32AG.mjs → shipping-option-type-edit-CIU5EHRP.mjs} +1 -1
- package/dist/{shipping-option-type-list-UI7ZTCO7.mjs → shipping-option-type-list-ZMZMXFME.mjs} +2 -2
- package/dist/{shipping-profile-metadata-FGZRQKNN.mjs → shipping-profile-metadata-75G2NNMA.mjs} +1 -1
- package/dist/{store-add-locales-3MSEBHQG.mjs → store-add-locales-IZOZP5C6.mjs} +1 -1
- package/dist/{store-detail-MLYFQGBC.mjs → store-detail-4IBAEVSD.mjs} +1 -1
- package/dist/{store-metadata-ITA6AL6H.mjs → store-metadata-CYXTVJUE.mjs} +1 -1
- package/dist/{tax-region-create-AXM2SE4T.mjs → tax-region-create-DWGL4EUT.mjs} +1 -1
- package/dist/{tax-region-detail-WFXSRH3U.mjs → tax-region-detail-O2T7BI3V.mjs} +5 -5
- package/dist/{tax-region-edit-CZ4EDU4K.mjs → tax-region-edit-EEVEEU2Q.mjs} +1 -1
- package/dist/{tax-region-province-detail-4B5GWCY7.mjs → tax-region-province-detail-2W7RXAM5.mjs} +5 -5
- package/dist/{tax-region-tax-override-create-GDDSUSHK.mjs → tax-region-tax-override-create-7IM4ZVPH.mjs} +3 -3
- package/dist/{tax-region-tax-override-edit-QXCSGDVG.mjs → tax-region-tax-override-edit-3ZT5IZYR.mjs} +4 -4
- package/dist/{translation-list-S4477JFR.mjs → translation-list-IAKEB7MY.mjs} +74 -85
- package/dist/{translations-edit-S3V7SSDA.mjs → translations-edit-QKLE4L5B.mjs} +27 -26
- package/dist/{user-metadata-SILGZHTG.mjs → user-metadata-2WPJOEJA.mjs} +1 -1
- package/dist/{workflow-execution-detail-GJTST4GO.mjs → workflow-execution-detail-H2AKEZJX.mjs} +1 -1
- package/package.json +9 -9
- package/src/hooks/api/translations.tsx +61 -31
- package/src/i18n/translations/$schema.json +12 -3
- package/src/i18n/translations/en.json +3 -0
- package/src/i18n/translations/es.json +3 -0
- package/src/routes/translations/translation-list/components/translation-list-section/translation-list-section.tsx +8 -10
- package/src/routes/translations/translation-list/components/translations-completion-section/translations-completion-section.tsx +16 -10
- package/src/routes/translations/translation-list/translation-list.tsx +71 -68
- package/src/routes/translations/translations-edit/components/translations-edit-form/translations-edit-form.tsx +7 -2
- package/src/routes/translations/translations-edit/translations-edit.tsx +27 -12
- package/src/routes/translations/translations-edit/utils/index.ts +0 -1
- package/src/routes/translations/translations-edit/utils/reference-label-map.ts +0 -10
|
@@ -1,13 +1,7 @@
|
|
|
1
1
|
import { Button, Container, Text } from "@medusajs/ui"
|
|
2
2
|
import { Link } from "react-router-dom"
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
icon: React.ReactNode
|
|
6
|
-
label: string
|
|
7
|
-
reference: string
|
|
8
|
-
translatedCount?: number
|
|
9
|
-
totalCount?: number
|
|
10
|
-
}
|
|
3
|
+
import { TranslatableEntity } from "../../translation-list"
|
|
4
|
+
import { useTranslation } from "react-i18next"
|
|
11
5
|
|
|
12
6
|
type TranslationListSectionProps = {
|
|
13
7
|
entities: TranslatableEntity[]
|
|
@@ -18,6 +12,8 @@ export const TranslationListSection = ({
|
|
|
18
12
|
entities,
|
|
19
13
|
hasLocales = false,
|
|
20
14
|
}: TranslationListSectionProps) => {
|
|
15
|
+
const { t } = useTranslation()
|
|
16
|
+
|
|
21
17
|
return (
|
|
22
18
|
<Container className="divide-y p-0">
|
|
23
19
|
{entities.map((entity) => (
|
|
@@ -29,8 +25,10 @@ export const TranslationListSection = ({
|
|
|
29
25
|
{entity.label}
|
|
30
26
|
</Text>
|
|
31
27
|
<Text size="small" className="text-ui-fg-subtle">
|
|
32
|
-
{(
|
|
33
|
-
|
|
28
|
+
{t("translations.list.metrics", {
|
|
29
|
+
translated: (entity.translatedCount ?? 0).toLocaleString(),
|
|
30
|
+
total: (entity.totalCount ?? 0).toLocaleString(),
|
|
31
|
+
})}
|
|
34
32
|
</Text>
|
|
35
33
|
<Link
|
|
36
34
|
to={`/settings/translations/edit?reference=${entity.reference}`}
|
|
@@ -1,16 +1,22 @@
|
|
|
1
|
+
import { AdminTranslationEntityStatistics } from "@medusajs/types"
|
|
1
2
|
import { Container, Heading, Text } from "@medusajs/ui"
|
|
2
3
|
import { useTranslation } from "react-i18next"
|
|
3
4
|
|
|
4
5
|
type TranslationsCompletionSectionProps = {
|
|
5
|
-
|
|
6
|
-
totalCount?: number
|
|
6
|
+
statistics: Record<string, AdminTranslationEntityStatistics>
|
|
7
7
|
}
|
|
8
8
|
|
|
9
9
|
export const TranslationsCompletionSection = ({
|
|
10
|
-
|
|
11
|
-
totalCount = 0,
|
|
10
|
+
statistics,
|
|
12
11
|
}: TranslationsCompletionSectionProps) => {
|
|
13
12
|
const { t } = useTranslation()
|
|
13
|
+
const { translatedCount, totalCount } = Object.values(statistics).reduce(
|
|
14
|
+
(acc, curr) => ({
|
|
15
|
+
translatedCount: acc.translatedCount + curr.translated,
|
|
16
|
+
totalCount: acc.totalCount + curr.expected,
|
|
17
|
+
}),
|
|
18
|
+
{ totalCount: 0, translatedCount: 0 }
|
|
19
|
+
)
|
|
14
20
|
|
|
15
21
|
const percentage = totalCount > 0 ? (translatedCount / totalCount) * 100 : 0
|
|
16
22
|
const remaining = Math.max(0, totalCount - translatedCount)
|
|
@@ -19,24 +25,24 @@ export const TranslationsCompletionSection = ({
|
|
|
19
25
|
<Container className="flex flex-col gap-y-3 px-6 py-4">
|
|
20
26
|
<div className="flex items-center justify-between">
|
|
21
27
|
<Heading>{t("translations.completion.heading")}</Heading>
|
|
22
|
-
<Text size="small" className="text-ui-fg-subtle">
|
|
28
|
+
<Text size="small" weight="plus" className="text-ui-fg-subtle">
|
|
23
29
|
{translatedCount.toLocaleString()} {t("general.of")}{" "}
|
|
24
30
|
{totalCount.toLocaleString()}
|
|
25
31
|
</Text>
|
|
26
32
|
</div>
|
|
27
33
|
|
|
28
|
-
<div className="flex h-
|
|
34
|
+
<div className="flex h-3 w-full overflow-hidden">
|
|
29
35
|
{percentage > 0 ? (
|
|
30
36
|
<>
|
|
31
37
|
<div
|
|
32
|
-
className="mr-0.5 h-full rounded-
|
|
38
|
+
className="mr-0.5 h-full rounded-sm transition-all"
|
|
33
39
|
style={{
|
|
34
40
|
width: `${percentage}%`,
|
|
35
41
|
backgroundColor: "var(--bg-interactive)",
|
|
36
42
|
}}
|
|
37
43
|
/>
|
|
38
44
|
<div
|
|
39
|
-
className="h-full flex-1 rounded-
|
|
45
|
+
className="h-full flex-1 rounded-sm"
|
|
40
46
|
style={{
|
|
41
47
|
backgroundColor: "var(--bg-interactive)",
|
|
42
48
|
opacity: 0.3,
|
|
@@ -55,10 +61,10 @@ export const TranslationsCompletionSection = ({
|
|
|
55
61
|
</div>
|
|
56
62
|
|
|
57
63
|
<div className="flex items-center justify-between">
|
|
58
|
-
<Text size="small" className="text-ui-fg-subtle">
|
|
64
|
+
<Text size="small" weight="plus" className="text-ui-fg-subtle">
|
|
59
65
|
{percentage.toFixed(1)}%
|
|
60
66
|
</Text>
|
|
61
|
-
<Text size="small" className="text-ui-fg-subtle">
|
|
67
|
+
<Text size="small" weight="plus" className="text-ui-fg-subtle">
|
|
62
68
|
{remaining.toLocaleString()} {t("general.remaining").toLowerCase()}
|
|
63
69
|
</Text>
|
|
64
70
|
</div>
|
|
@@ -2,96 +2,97 @@ 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 {
|
|
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
|
|
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)
|
|
64
|
+
.filter(
|
|
65
|
+
([entity]) =>
|
|
66
|
+
!["product_option", "product_option_value"].includes(entity)
|
|
67
|
+
)
|
|
68
|
+
.map(([entity, fields]) => {
|
|
69
|
+
const entityStatistics = statistics[entity]
|
|
70
|
+
|
|
71
|
+
return {
|
|
72
|
+
label: entity
|
|
73
|
+
.split("_")
|
|
74
|
+
.map((word) => word.charAt(0).toUpperCase() + word.slice(1))
|
|
75
|
+
.join(" "),
|
|
76
|
+
reference: entity,
|
|
77
|
+
translatableFields: fields,
|
|
78
|
+
translatedCount: entityStatistics.translated,
|
|
79
|
+
totalCount: entityStatistics.expected,
|
|
80
|
+
}
|
|
81
|
+
})
|
|
82
|
+
}, [translatable_fields, statistics])
|
|
83
|
+
|
|
84
|
+
const isReady =
|
|
85
|
+
!!store &&
|
|
86
|
+
!isPending &&
|
|
87
|
+
!isTranslationSettingsPending &&
|
|
88
|
+
!isTranslationStatisticsPending &&
|
|
89
|
+
!!translatable_fields &&
|
|
90
|
+
!!statistics
|
|
88
91
|
|
|
89
92
|
if (!isReady) {
|
|
90
93
|
return <TwoColumnPageSkeleton sidebarSections={2} />
|
|
91
94
|
}
|
|
92
95
|
|
|
93
|
-
const hasLocales = (store?.supported_locales ?? []).length > 0
|
|
94
|
-
|
|
95
96
|
return (
|
|
96
97
|
<TwoColumnPage
|
|
97
98
|
widgets={{
|
|
@@ -109,7 +110,7 @@ export const TranslationList = () => {
|
|
|
109
110
|
</Text>
|
|
110
111
|
</Container>
|
|
111
112
|
<TranslationListSection
|
|
112
|
-
entities={
|
|
113
|
+
entities={translatableEntities}
|
|
113
114
|
hasLocales={hasLocales}
|
|
114
115
|
/>
|
|
115
116
|
</TwoColumnPage.Main>
|
|
@@ -121,7 +122,9 @@ export const TranslationList = () => {
|
|
|
121
122
|
) ?? []
|
|
122
123
|
}
|
|
123
124
|
></ActiveLocalesSection>
|
|
124
|
-
|
|
125
|
+
{statistics && (
|
|
126
|
+
<TranslationsCompletionSection statistics={statistics} />
|
|
127
|
+
)}
|
|
125
128
|
</TwoColumnPage.Sidebar>
|
|
126
129
|
</TwoColumnPage>
|
|
127
130
|
)
|
|
@@ -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.
|
|
@@ -234,7 +233,9 @@ function useTranslationsGridColumns({
|
|
|
234
233
|
columnHelper.column({
|
|
235
234
|
id: "original",
|
|
236
235
|
name: "original",
|
|
236
|
+
size: 300,
|
|
237
237
|
header: t("general.original"),
|
|
238
|
+
disableHiding: true,
|
|
238
239
|
cell: (context) => {
|
|
239
240
|
const row = context.row.original
|
|
240
241
|
|
|
@@ -262,6 +263,7 @@ function useTranslationsGridColumns({
|
|
|
262
263
|
return columnHelper.column({
|
|
263
264
|
id: locale.locale_code,
|
|
264
265
|
name: locale.locale.name,
|
|
266
|
+
size: 300,
|
|
265
267
|
header: () => locale.locale.name,
|
|
266
268
|
cell: (context) => {
|
|
267
269
|
const row = context.row.original
|
|
@@ -441,7 +443,10 @@ export const TranslationsEditForm = ({
|
|
|
441
443
|
<div className="-my-2 w-full border-l">
|
|
442
444
|
<ProgressTabs.List className="justify-start-start flex w-full items-center">
|
|
443
445
|
<ProgressTabs.Trigger value={entityType}>
|
|
444
|
-
{
|
|
446
|
+
{entityType
|
|
447
|
+
.split("_")
|
|
448
|
+
.map((word) => word.charAt(0).toUpperCase() + word.slice(1))
|
|
449
|
+
.join(" ")}
|
|
445
450
|
</ProgressTabs.Trigger>
|
|
446
451
|
</ProgressTabs.List>
|
|
447
452
|
</div>
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { useNavigate, useSearchParams } from "react-router-dom"
|
|
2
|
-
import {
|
|
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(
|
|
35
|
-
|
|
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
|
-
!!
|
|
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
|
-
|
|
66
|
-
|
|
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
|
-
}
|