From 034eea0dcdb52c124ebdb1a6d4a439d97e85d8f6 Mon Sep 17 00:00:00 2001 From: Kamil Pastuszka <33246308+kamilpastuszka@users.noreply.github.com> Date: Mon, 9 Aug 2021 16:59:12 +0200 Subject: [PATCH] Add text attribute for product and page translations (#1276) * initial commit * Refactor translation components * Wire up products * Update types * add logic for withChoices flag * refactoring * fixing errors * change in intl.ts * amended Changelog * fix formatting * fixing stuff * Update translations * remove unused declaration * add changes * Fixes * Add newline * Update displayName * Update snapshots Co-authored-by: Jakub Majorek --- CHANGELOG.md | 1 + locale/defaultMessages.json | 45 +++--- src/fragments/translations.ts | 66 ++++++++- .../AttributeTranslationDetailsFragment.ts | 1 + .../types/AttributeTranslationFragment.ts | 2 + ...tributeValueTranslatableContentFragment.ts | 66 +++++++++ .../types/PageTranslationFragment.ts | 29 ++++ .../types/ProductTranslationFragment.ts | 35 ++++- src/intl.ts | 3 + .../TranslationsEntitiesListPage.tsx | 2 +- .../TranslationFields/TranslationFields.tsx | 17 +-- .../TranslationsAttributesPage.tsx} | 118 +++++++-------- .../TranslationsAttributesPage/index.ts | 2 + .../TranslationsEntitiesListPage.tsx | 6 +- .../TranslationsPagesPage.tsx | 39 ++++- .../TranslationsProductTypesPage/index.ts | 2 - .../TranslationsProductsPage.tsx | 38 ++++- src/translations/index.tsx | 16 +-- src/translations/mutations.ts | 1 + src/translations/types.ts | 41 ++++-- .../types/AttributeTranslationDetails.ts | 1 + .../types/AttributeTranslations.ts | 2 + .../types/PageTranslationDetails.ts | 29 ++++ src/translations/types/PageTranslations.ts | 29 ++++ .../types/ProductTranslationDetails.ts | 35 ++++- src/translations/types/ProductTranslations.ts | 35 ++++- .../types/UpdateAttributeValueTranslations.ts | 1 + .../types/UpdatePageTranslations.ts | 29 ++++ src/translations/urls.ts | 2 +- ...ctTypes.tsx => TranslationsAttributes.tsx} | 34 ++--- .../views/TranslationsCategories.tsx | 9 +- .../views/TranslationsCollections.tsx | 9 +- .../views/TranslationsEntities.tsx | 8 +- src/translations/views/TranslationsPages.tsx | 135 +++++++++++------- .../views/TranslationsProducts.tsx | 135 +++++++++++------- src/translations/views/TranslationsSales.tsx | 25 ++-- .../views/TranslationsShippingMethod.tsx | 6 +- .../views/TranslationsVouchers.tsx | 25 ++-- 38 files changed, 781 insertions(+), 298 deletions(-) create mode 100644 src/fragments/types/AttributeValueTranslatableContentFragment.ts rename src/translations/components/{TranslationsProductTypesPage/TranslationsProductTypesPage.tsx => TranslationsAttributesPage/TranslationsAttributesPage.tsx} (55%) create mode 100644 src/translations/components/TranslationsAttributesPage/index.ts delete mode 100644 src/translations/components/TranslationsProductTypesPage/index.ts rename src/translations/views/{TranslationsProductTypes.tsx => TranslationsAttributes.tsx} (88%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 84b498f2f..e6e7a757a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -73,6 +73,7 @@ All notable, unreleased changes to this project will be documented in this file. - Add Metadata for Sale & Voucher - #7653 by @piotrgrundas - Add variant create options dialog - #1238 by @orzechdev - Fix for errors on changing channel availability - #1264 by @krzysztofwolski +- Add text attribute for product and page translations - #1276 by @kamilpastuszka # 2.11.1 diff --git a/locale/defaultMessages.json b/locale/defaultMessages.json index 4f46d0719..228c1901e 100644 --- a/locale/defaultMessages.json +++ b/locale/defaultMessages.json @@ -6668,6 +6668,9 @@ "context": "independent of any particular day, eg. 11:35", "string": "Time" }, + "src_dot_translationAttributes": { + "string": "Attributes" + }, "src_dot_translations": { "context": "translations section name", "string": "Translations" @@ -6688,6 +6691,21 @@ "src_dot_translations_dot_components_dot_TranslationFields_dot_3793796047": { "string": "No translation yet" }, + "src_dot_translations_dot_components_dot_TranslationsAttributesPage_dot_1567737068": { + "context": "attribute values", + "string": "Value {number}" + }, + "src_dot_translations_dot_components_dot_TranslationsAttributesPage_dot_2642976392": { + "string": "Attribute Name" + }, + "src_dot_translations_dot_components_dot_TranslationsAttributesPage_dot_884093025": { + "context": "header", + "string": "Translation Attribute \"{attribute}\" - {languageCode}" + }, + "src_dot_translations_dot_components_dot_TranslationsAttributesPage_dot_values": { + "context": "section name", + "string": "Values" + }, "src_dot_translations_dot_components_dot_TranslationsCategoriesPage_dot_1214235329": { "string": "Category Name" }, @@ -6790,28 +6808,13 @@ "src_dot_translations_dot_components_dot_TranslationsPagesPage_dot_3468022343": { "string": "Search Engine Preview" }, + "src_dot_translations_dot_components_dot_TranslationsPagesPage_dot_4165966072": { + "context": "attribute list", + "string": "Attribute {number}" + }, "src_dot_translations_dot_components_dot_TranslationsPagesPage_dot_432157284": { "string": "Page Title" }, - "src_dot_translations_dot_components_dot_TranslationsProductTypesPage_dot_1567737068": { - "context": "attribute values", - "string": "Value {number}" - }, - "src_dot_translations_dot_components_dot_TranslationsProductTypesPage_dot_2642976392": { - "string": "Attribute Name" - }, - "src_dot_translations_dot_components_dot_TranslationsProductTypesPage_dot_3495336243": { - "context": "attribute richtext value", - "string": "Text" - }, - "src_dot_translations_dot_components_dot_TranslationsProductTypesPage_dot_884093025": { - "context": "header", - "string": "Translation Attribute \"{attribute}\" - {languageCode}" - }, - "src_dot_translations_dot_components_dot_TranslationsProductTypesPage_dot_values": { - "context": "section name", - "string": "Values" - }, "src_dot_translations_dot_components_dot_TranslationsProductsPage_dot_1406947243": { "string": "Search Engine Description" }, @@ -6831,6 +6834,10 @@ "src_dot_translations_dot_components_dot_TranslationsProductsPage_dot_3468022343": { "string": "Search Engine Preview" }, + "src_dot_translations_dot_components_dot_TranslationsProductsPage_dot_4165966072": { + "context": "attribute list", + "string": "Attribute {number}" + }, "src_dot_translations_dot_components_dot_TranslationsSalesPage_dot_3731955064": { "context": "header", "string": "Translation Sale \"{saleName}\" - {languageCode}" diff --git a/src/fragments/translations.ts b/src/fragments/translations.ts index e44b101f1..7cf528e78 100644 --- a/src/fragments/translations.ts +++ b/src/fragments/translations.ts @@ -44,6 +44,7 @@ export const collectionTranslationFragment = gql` } } `; + export const productTranslationFragment = gql` fragment ProductTranslationFragment on ProductTranslatableContent { product { @@ -55,14 +56,31 @@ export const productTranslationFragment = gql` } translation(languageCode: $language) { id + seoTitle + seoDescription + name description language { code language } + } + attributeValues { + id name - seoDescription - seoTitle + richText + attributeValue { + id + } + translation(languageCode: $language) { + id + name + richText + language { + code + language + } + } } } `; @@ -139,6 +157,23 @@ export const pageTranslationFragment = gql` language } } + attributeValues { + id + name + richText + attributeValue { + id + } + translation(languageCode: $language) { + id + name + richText + language { + code + language + } + } + } } `; export const pageTranslatableFragment = gql` @@ -148,7 +183,6 @@ export const pageTranslatableFragment = gql` seoDescription seoTitle title - translation(languageCode: $language) { id content @@ -188,6 +222,8 @@ export const attributeChoicesTranslationFragment = gql` export const attributeTranslationFragment = gql` fragment AttributeTranslationFragment on AttributeTranslatableContent { + id + name translation(languageCode: $language) { id name @@ -203,6 +239,30 @@ export const attributeTranslationFragment = gql` export const attributeTranslationDetailsFragment = gql` ${attributeChoicesTranslationFragment} fragment AttributeTranslationDetailsFragment on AttributeTranslatableContent { + translation(languageCode: $language) { + id + name + } + attribute { + id + name + inputType + withChoices + choices( + first: $firstValues + after: $afterValues + last: $lastValues + before: $beforeValues + ) { + ...AttributeChoicesTranslationFragment + } + } + } +`; + +export const attributeValueTranslatableContentFragment = gql` + ${attributeChoicesTranslationFragment} + fragment AttributeValueTranslatableContentFragment on AttributeTranslatableContent { translation(languageCode: $language) { id name diff --git a/src/fragments/types/AttributeTranslationDetailsFragment.ts b/src/fragments/types/AttributeTranslationDetailsFragment.ts index d0bf25525..4a560a186 100644 --- a/src/fragments/types/AttributeTranslationDetailsFragment.ts +++ b/src/fragments/types/AttributeTranslationDetailsFragment.ts @@ -56,6 +56,7 @@ export interface AttributeTranslationDetailsFragment_attribute { id: string; name: string | null; inputType: AttributeInputTypeEnum | null; + withChoices: boolean; choices: AttributeTranslationDetailsFragment_attribute_choices | null; } diff --git a/src/fragments/types/AttributeTranslationFragment.ts b/src/fragments/types/AttributeTranslationFragment.ts index ccc82453a..b1b5b2dd2 100644 --- a/src/fragments/types/AttributeTranslationFragment.ts +++ b/src/fragments/types/AttributeTranslationFragment.ts @@ -24,6 +24,8 @@ export interface AttributeTranslationFragment_attribute { export interface AttributeTranslationFragment { __typename: "AttributeTranslatableContent"; + id: string; + name: string; translation: AttributeTranslationFragment_translation | null; attribute: AttributeTranslationFragment_attribute | null; } diff --git a/src/fragments/types/AttributeValueTranslatableContentFragment.ts b/src/fragments/types/AttributeValueTranslatableContentFragment.ts new file mode 100644 index 000000000..9a1b4460a --- /dev/null +++ b/src/fragments/types/AttributeValueTranslatableContentFragment.ts @@ -0,0 +1,66 @@ +/* tslint:disable */ +/* eslint-disable */ +// @generated +// This file was automatically generated and should not be edited. + +import { AttributeInputTypeEnum } from "./../../types/globalTypes"; + +// ==================================================== +// GraphQL fragment: AttributeValueTranslatableContentFragment +// ==================================================== + +export interface AttributeValueTranslatableContentFragment_translation { + __typename: "AttributeTranslation"; + id: string; + name: string; +} + +export interface AttributeValueTranslatableContentFragment_attribute_choices_pageInfo { + __typename: "PageInfo"; + endCursor: string | null; + hasNextPage: boolean; + hasPreviousPage: boolean; + startCursor: string | null; +} + +export interface AttributeValueTranslatableContentFragment_attribute_choices_edges_node_translation { + __typename: "AttributeValueTranslation"; + id: string; + name: string; + richText: any | null; +} + +export interface AttributeValueTranslatableContentFragment_attribute_choices_edges_node { + __typename: "AttributeValue"; + id: string; + name: string | null; + richText: any | null; + inputType: AttributeInputTypeEnum | null; + translation: AttributeValueTranslatableContentFragment_attribute_choices_edges_node_translation | null; +} + +export interface AttributeValueTranslatableContentFragment_attribute_choices_edges { + __typename: "AttributeValueCountableEdge"; + cursor: string; + node: AttributeValueTranslatableContentFragment_attribute_choices_edges_node; +} + +export interface AttributeValueTranslatableContentFragment_attribute_choices { + __typename: "AttributeValueCountableConnection"; + pageInfo: AttributeValueTranslatableContentFragment_attribute_choices_pageInfo; + edges: AttributeValueTranslatableContentFragment_attribute_choices_edges[]; +} + +export interface AttributeValueTranslatableContentFragment_attribute { + __typename: "Attribute"; + id: string; + name: string | null; + inputType: AttributeInputTypeEnum | null; + choices: AttributeValueTranslatableContentFragment_attribute_choices | null; +} + +export interface AttributeValueTranslatableContentFragment { + __typename: "AttributeTranslatableContent"; + translation: AttributeValueTranslatableContentFragment_translation | null; + attribute: AttributeValueTranslatableContentFragment_attribute | null; +} diff --git a/src/fragments/types/PageTranslationFragment.ts b/src/fragments/types/PageTranslationFragment.ts index 795c1191f..c6e0b18bd 100644 --- a/src/fragments/types/PageTranslationFragment.ts +++ b/src/fragments/types/PageTranslationFragment.ts @@ -34,8 +34,37 @@ export interface PageTranslationFragment_translation { language: PageTranslationFragment_translation_language; } +export interface PageTranslationFragment_attributeValues_attributeValue { + __typename: "AttributeValue"; + id: string; +} + +export interface PageTranslationFragment_attributeValues_translation_language { + __typename: "LanguageDisplay"; + code: LanguageCodeEnum; + language: string; +} + +export interface PageTranslationFragment_attributeValues_translation { + __typename: "AttributeValueTranslation"; + id: string; + name: string; + richText: any | null; + language: PageTranslationFragment_attributeValues_translation_language; +} + +export interface PageTranslationFragment_attributeValues { + __typename: "AttributeValueTranslatableContent"; + id: string; + name: string; + richText: any | null; + attributeValue: PageTranslationFragment_attributeValues_attributeValue | null; + translation: PageTranslationFragment_attributeValues_translation | null; +} + export interface PageTranslationFragment { __typename: "PageTranslatableContent"; page: PageTranslationFragment_page | null; translation: PageTranslationFragment_translation | null; + attributeValues: PageTranslationFragment_attributeValues[]; } diff --git a/src/fragments/types/ProductTranslationFragment.ts b/src/fragments/types/ProductTranslationFragment.ts index 132857b15..f8f8147e8 100644 --- a/src/fragments/types/ProductTranslationFragment.ts +++ b/src/fragments/types/ProductTranslationFragment.ts @@ -27,15 +27,44 @@ export interface ProductTranslationFragment_translation_language { export interface ProductTranslationFragment_translation { __typename: "ProductTranslation"; id: string; + seoTitle: string | null; + seoDescription: string | null; + name: string | null; description: any | null; language: ProductTranslationFragment_translation_language; - name: string | null; - seoDescription: string | null; - seoTitle: string | null; +} + +export interface ProductTranslationFragment_attributeValues_attributeValue { + __typename: "AttributeValue"; + id: string; +} + +export interface ProductTranslationFragment_attributeValues_translation_language { + __typename: "LanguageDisplay"; + code: LanguageCodeEnum; + language: string; +} + +export interface ProductTranslationFragment_attributeValues_translation { + __typename: "AttributeValueTranslation"; + id: string; + name: string; + richText: any | null; + language: ProductTranslationFragment_attributeValues_translation_language; +} + +export interface ProductTranslationFragment_attributeValues { + __typename: "AttributeValueTranslatableContent"; + id: string; + name: string; + richText: any | null; + attributeValue: ProductTranslationFragment_attributeValues_attributeValue | null; + translation: ProductTranslationFragment_attributeValues_translation | null; } export interface ProductTranslationFragment { __typename: "ProductTranslatableContent"; product: ProductTranslationFragment_product | null; translation: ProductTranslationFragment_translation | null; + attributeValues: ProductTranslationFragment_attributeValues[]; } diff --git a/src/intl.ts b/src/intl.ts index fb66dd9e8..6d750a09f 100644 --- a/src/intl.ts +++ b/src/intl.ts @@ -99,6 +99,9 @@ export const commonMessages = defineMessages({ summary: { defaultMessage: "Summary" }, + translationAttributes: { + defaultMessage: "Attributes" + }, unauthorizedDashboardAccess: { defaultMessage: "Only staff users can access the dashboard" }, diff --git a/src/storybook/stories/translations/TranslationsEntitiesListPage.tsx b/src/storybook/stories/translations/TranslationsEntitiesListPage.tsx index 1402530f0..de91dd547 100644 --- a/src/storybook/stories/translations/TranslationsEntitiesListPage.tsx +++ b/src/storybook/stories/translations/TranslationsEntitiesListPage.tsx @@ -18,7 +18,7 @@ const props: TranslationsEntitiesListPageProps = { onCategoriesTabClick: () => undefined, onCollectionsTabClick: () => undefined, onPagesTabClick: () => undefined, - onProductTypesTabClick: () => undefined, + onAttributesTabClick: () => undefined, onProductsTabClick: () => undefined, onSalesTabClick: () => undefined, onShippingMethodsTabClick: () => undefined, diff --git a/src/translations/components/TranslationFields/TranslationFields.tsx b/src/translations/components/TranslationFields/TranslationFields.tsx index 05093fa63..3f40c0af3 100644 --- a/src/translations/components/TranslationFields/TranslationFields.tsx +++ b/src/translations/components/TranslationFields/TranslationFields.tsx @@ -15,6 +15,7 @@ import Skeleton from "@saleor/components/Skeleton"; import TablePagination from "@saleor/components/TablePagination"; import { buttonMessages } from "@saleor/intl"; import { makeStyles } from "@saleor/macaw-ui"; +import { TranslationField } from "@saleor/translations/types"; import { ListProps } from "@saleor/types"; import classNames from "classnames"; import React from "react"; @@ -24,14 +25,6 @@ import TranslationFieldsLong from "./TranslationFieldsLong"; import TranslationFieldsRich from "./TranslationFieldsRich"; import TranslationFieldsShort from "./TranslationFieldsShort"; -export interface TranslationField { - displayName: string; - name: string; - translation: string; - type: "short" | "long" | "rich"; - value: string; -} - type Pagination = Pick< ListProps, Exclude @@ -47,7 +40,7 @@ export interface TranslationFieldsProps { pagination?: Pagination; onEdit: (field: string) => void; onDiscard: () => void; - onSubmit: (field: string, data: string | OutputData) => void; + onSubmit: (field: TranslationField, data: string | OutputData) => void; } const useStyles = makeStyles( @@ -215,7 +208,7 @@ const TranslationFields: React.FC = props => { initial={field.translation} saveButtonState={saveButtonState} onDiscard={onDiscard} - onSubmit={data => onSubmit(field.name, data)} + onSubmit={data => onSubmit(field, data)} /> ) : field.type === "long" ? ( = props => { initial={field.translation} saveButtonState={saveButtonState} onDiscard={onDiscard} - onSubmit={data => onSubmit(field.name, data)} + onSubmit={data => onSubmit(field, data)} /> ) : ( = props => { initial={field.translation} saveButtonState={saveButtonState} onDiscard={onDiscard} - onSubmit={data => onSubmit(field.name, data)} + onSubmit={data => onSubmit(field, data)} /> ) ) : ( diff --git a/src/translations/components/TranslationsProductTypesPage/TranslationsProductTypesPage.tsx b/src/translations/components/TranslationsAttributesPage/TranslationsAttributesPage.tsx similarity index 55% rename from src/translations/components/TranslationsProductTypesPage/TranslationsProductTypesPage.tsx rename to src/translations/components/TranslationsAttributesPage/TranslationsAttributesPage.tsx index 85671d1cb..9492194d7 100644 --- a/src/translations/components/TranslationsProductTypesPage/TranslationsProductTypesPage.tsx +++ b/src/translations/components/TranslationsAttributesPage/TranslationsAttributesPage.tsx @@ -7,16 +7,16 @@ import { AttributeTranslationDetailsFragment } from "@saleor/fragments/types/Att import { commonMessages, sectionNames } from "@saleor/intl"; import { Backlink } from "@saleor/macaw-ui"; import { getStringOrPlaceholder } from "@saleor/misc"; -import { TranslationsEntitiesPageProps } from "@saleor/translations/types"; +import { + TranslationField, + TranslationsEntitiesPageProps +} from "@saleor/translations/types"; import { ListSettings } from "@saleor/types"; import React from "react"; import { defineMessages, useIntl } from "react-intl"; -import { - AttributeInputTypeEnum, - LanguageCodeEnum -} from "../../../types/globalTypes"; -import TranslationFields, { TranslationField } from "../TranslationFields"; +import { LanguageCodeEnum } from "../../../types/globalTypes"; +import TranslationFields from "../TranslationFields"; export const messages = defineMessages({ values: { @@ -25,7 +25,7 @@ export const messages = defineMessages({ } }); -export interface TranslationsProductTypesPageProps +export interface TranslationsAttributesPageProps extends TranslationsEntitiesPageProps { data: AttributeTranslationDetailsFragment; settings?: ListSettings; @@ -44,7 +44,7 @@ export const fieldNames = { richTextValue: "attributeRichTextValue" }; -const TranslationsProductTypesPage: React.FC = ({ +const TranslationsAttributesPage: React.FC = ({ activeField, disabled, languages, @@ -64,6 +64,8 @@ const TranslationsProductTypesPage: React.FC }) => { const intl = useIntl(); + const withChoices = data?.attribute?.withChoices; + return ( @@ -110,64 +112,50 @@ const TranslationsProductTypesPage: React.FC onSubmit={onSubmit} /> - { - const isRichText = - attributeValue?.inputType === AttributeInputTypeEnum.RICH_TEXT; - const displayName = isRichText - ? intl.formatMessage({ - defaultMessage: "Text", - description: "attribute richtext value" - }) - : intl.formatMessage( - { - defaultMessage: "Value {number}", - description: "attribute values" - }, - { - number: attributeValueIndex + 1 - } - ); + {data?.attribute?.choices.edges.length > 0 && withChoices && ( + { + const displayName = intl.formatMessage( + { + defaultMessage: "Value {number}", + description: "attribute values" + }, + { + number: attributeValueIndex + 1 + } + ); - return { - displayName, - name: `${ - isRichText ? fieldNames.richTextValue : fieldNames.value - }:${attributeValue.id}`, - translation: - (isRichText - ? attributeValue?.translation?.richText - : attributeValue?.translation?.name) || null, - type: (isRichText - ? "rich" - : "short") as TranslationField["type"], - value: isRichText - ? attributeValue?.richText - : attributeValue?.name - }; - } - ) || [] - } - saveButtonState={saveButtonState} - pagination={{ - settings, - onUpdateListSettings, - pageInfo, - onNextPage, - onPreviousPage - }} - onEdit={onEdit} - onDiscard={onDiscard} - onSubmit={onSubmit} - /> + return { + displayName, + name: `${fieldNames.value}:${attributeValue.id}`, + translation: attributeValue?.translation?.name || null, + type: "short" as TranslationField["type"], + value: attributeValue?.name + }; + } + ) || [] + } + saveButtonState={saveButtonState} + pagination={{ + settings, + onUpdateListSettings, + pageInfo, + onNextPage, + onPreviousPage + }} + onEdit={onEdit} + onDiscard={onDiscard} + onSubmit={onSubmit} + /> + )} ); }; -TranslationsProductTypesPage.displayName = "TranslationsProductTypesPage"; -export default TranslationsProductTypesPage; +TranslationsAttributesPage.displayName = "TranslationsAttributesPage"; +export default TranslationsAttributesPage; diff --git a/src/translations/components/TranslationsAttributesPage/index.ts b/src/translations/components/TranslationsAttributesPage/index.ts new file mode 100644 index 000000000..62cf0aa49 --- /dev/null +++ b/src/translations/components/TranslationsAttributesPage/index.ts @@ -0,0 +1,2 @@ +export { default } from "./TranslationsAttributesPage"; +export * from "./TranslationsAttributesPage"; diff --git a/src/translations/components/TranslationsEntitiesListPage/TranslationsEntitiesListPage.tsx b/src/translations/components/TranslationsEntitiesListPage/TranslationsEntitiesListPage.tsx index 1b11a339b..cd21bbfc8 100644 --- a/src/translations/components/TranslationsEntitiesListPage/TranslationsEntitiesListPage.tsx +++ b/src/translations/components/TranslationsEntitiesListPage/TranslationsEntitiesListPage.tsx @@ -25,7 +25,7 @@ export interface TranslationsEntitiesFilters { onSalesTabClick: () => void; onVouchersTabClick: () => void; onPagesTabClick: () => void; - onProductTypesTabClick: () => void; + onAttributesTabClick: () => void; onShippingMethodsTabClick: () => void; } @@ -38,7 +38,7 @@ const tabs: TranslationsEntitiesListFilterTab[] = [ "sales", "vouchers", "pages", - "productTypes", + "attributes", "shippingMethods" ]; @@ -109,7 +109,7 @@ const TranslationsEntitiesListPage: React.FC label={intl.formatMessage({ defaultMessage: "Attributes" })} - onClick={filters.onProductTypesTabClick} + onClick={filters.onAttributesTabClick} /> = ({ @@ -32,7 +33,8 @@ const TranslationsPagesPage: React.FC = ({ onDiscard, onEdit, onLanguageChange, - onSubmit + onSubmit, + onAttributeValueSubmit }) => { const intl = useIntl(); @@ -90,6 +92,7 @@ const TranslationsPagesPage: React.FC = ({ onDiscard={onDiscard} onSubmit={onSubmit} /> + = ({ onDiscard={onDiscard} onSubmit={onSubmit} /> + + {data?.attributeValues?.length > 0 && ( + <> + ({ + id: attrVal.attributeValue.id, + displayName: intl.formatMessage( + { + defaultMessage: "Attribute {number}", + description: "attribute list" + }, + { + number: i + 1 + } + ), + name: attrVal?.name, + translation: attrVal?.translation?.richText || null, + type: "rich" as "rich", + value: attrVal?.richText + })) || [] + } + saveButtonState={saveButtonState} + onEdit={onEdit} + onDiscard={onDiscard} + onSubmit={onAttributeValueSubmit} + /> + + + )} ); }; diff --git a/src/translations/components/TranslationsProductTypesPage/index.ts b/src/translations/components/TranslationsProductTypesPage/index.ts deleted file mode 100644 index 7da3b4204..000000000 --- a/src/translations/components/TranslationsProductTypesPage/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { default } from "./TranslationsProductTypesPage"; -export * from "./TranslationsProductTypesPage"; diff --git a/src/translations/components/TranslationsProductsPage/TranslationsProductsPage.tsx b/src/translations/components/TranslationsProductsPage/TranslationsProductsPage.tsx index a7b0765b2..abe144e81 100644 --- a/src/translations/components/TranslationsProductsPage/TranslationsProductsPage.tsx +++ b/src/translations/components/TranslationsProductsPage/TranslationsProductsPage.tsx @@ -19,6 +19,7 @@ import TranslationFields from "../TranslationFields"; export interface TranslationsProductsPageProps extends TranslationsEntitiesPageProps { data: ProductTranslationFragment; + onAttributeValueSubmit: TranslationsEntitiesPageProps["onSubmit"]; } const TranslationsProductsPage: React.FC = ({ @@ -32,7 +33,8 @@ const TranslationsProductsPage: React.FC = ({ onDiscard, onEdit, onLanguageChange, - onSubmit + onSubmit, + onAttributeValueSubmit }) => { const intl = useIntl(); @@ -123,6 +125,40 @@ const TranslationsProductsPage: React.FC = ({ onDiscard={onDiscard} onSubmit={onSubmit} /> + + {data?.attributeValues?.length > 0 && ( + <> + ({ + id: attrVal.attributeValue.id, + displayName: intl.formatMessage( + { + defaultMessage: "Attribute {number}", + description: "attribute list" + }, + { + number: i + 1 + } + ), + name: attrVal?.name, + translation: attrVal?.translation?.richText || null, + type: "rich" as "rich", + value: attrVal?.richText + })) || [] + } + saveButtonState={saveButtonState} + onEdit={onEdit} + onDiscard={onDiscard} + onSubmit={onAttributeValueSubmit} + /> + + + )} ); }; diff --git a/src/translations/index.tsx b/src/translations/index.tsx index 246ea698b..54b49184a 100644 --- a/src/translations/index.tsx +++ b/src/translations/index.tsx @@ -12,6 +12,9 @@ import { languageListPath, TranslatableEntities } from "./urls"; +import TranslationsAttributesComponent, { + TranslationsAttributesQueryParams +} from "./views/TranslationsAttributes"; import TranslationsCategoriesComponent, { TranslationsCategoriesQueryParams } from "./views/TranslationsCategories"; @@ -26,9 +29,6 @@ import TranslationsPagesComponent, { import TranslationsProductsComponent, { TranslationsProductsQueryParams } from "./views/TranslationsProducts"; -import TranslationsProductTypesComponent, { - TranslationsProductTypesQueryParams -} from "./views/TranslationsProductTypes"; import TranslationsSaleComponent, { TranslationsSalesQueryParams } from "./views/TranslationsSales"; @@ -155,16 +155,16 @@ const TranslationsPages: React.FC = ({ /> ); }; -const TranslationsProductTypes: React.FC = ({ +const TranslationsAttributes: React.FC = ({ location, match }) => { const qs = parseQs(location.search.substr(1)); - const params: TranslationsProductTypesQueryParams = { + const params: TranslationsAttributesQueryParams = { activeField: qs.activeField }; return ( - { exact path={languageEntityPath( ":languageCode", - TranslatableEntities.productTypes, + TranslatableEntities.attributes, ":id" )} - component={TranslationsProductTypes} + component={TranslationsAttributes} /> { + id?: string; + displayName: string; + name: T; + translation: string; + type: "short" | "long" | "rich"; + value: string; +} + export interface TranslationsEntitiesPageProps { activeField: string; disabled: boolean; @@ -12,19 +37,5 @@ export interface TranslationsEntitiesPageProps { onEdit: (field: string) => void; onDiscard: () => void; onLanguageChange: (lang: string) => void; - onSubmit: (field: string, data: string | OutputData) => void; -} - -export enum TranslationInputFieldName { - description = "description", - name = "name", - seoDescription = "seoDescription", - seoTitle = "seoTitle" -} - -export enum PageTranslationInputFieldName { - content = "content", - title = "title", - seoDescription = "seoDescription", - seoTitle = "seoTitle" + onSubmit: (field: TranslationField, data: string | OutputData) => void; } diff --git a/src/translations/types/AttributeTranslationDetails.ts b/src/translations/types/AttributeTranslationDetails.ts index c029fc29a..6f384f555 100644 --- a/src/translations/types/AttributeTranslationDetails.ts +++ b/src/translations/types/AttributeTranslationDetails.ts @@ -60,6 +60,7 @@ export interface AttributeTranslationDetails_translation_AttributeTranslatableCo id: string; name: string | null; inputType: AttributeInputTypeEnum | null; + withChoices: boolean; choices: AttributeTranslationDetails_translation_AttributeTranslatableContent_attribute_choices | null; } diff --git a/src/translations/types/AttributeTranslations.ts b/src/translations/types/AttributeTranslations.ts index 28613e184..2bf219fc1 100644 --- a/src/translations/types/AttributeTranslations.ts +++ b/src/translations/types/AttributeTranslations.ts @@ -28,6 +28,8 @@ export interface AttributeTranslations_translations_edges_node_AttributeTranslat export interface AttributeTranslations_translations_edges_node_AttributeTranslatableContent { __typename: "AttributeTranslatableContent"; + id: string; + name: string; translation: AttributeTranslations_translations_edges_node_AttributeTranslatableContent_translation | null; attribute: AttributeTranslations_translations_edges_node_AttributeTranslatableContent_attribute | null; } diff --git a/src/translations/types/PageTranslationDetails.ts b/src/translations/types/PageTranslationDetails.ts index a46fea373..c1d617df7 100644 --- a/src/translations/types/PageTranslationDetails.ts +++ b/src/translations/types/PageTranslationDetails.ts @@ -38,10 +38,39 @@ export interface PageTranslationDetails_translation_PageTranslatableContent_tran language: PageTranslationDetails_translation_PageTranslatableContent_translation_language; } +export interface PageTranslationDetails_translation_PageTranslatableContent_attributeValues_attributeValue { + __typename: "AttributeValue"; + id: string; +} + +export interface PageTranslationDetails_translation_PageTranslatableContent_attributeValues_translation_language { + __typename: "LanguageDisplay"; + code: LanguageCodeEnum; + language: string; +} + +export interface PageTranslationDetails_translation_PageTranslatableContent_attributeValues_translation { + __typename: "AttributeValueTranslation"; + id: string; + name: string; + richText: any | null; + language: PageTranslationDetails_translation_PageTranslatableContent_attributeValues_translation_language; +} + +export interface PageTranslationDetails_translation_PageTranslatableContent_attributeValues { + __typename: "AttributeValueTranslatableContent"; + id: string; + name: string; + richText: any | null; + attributeValue: PageTranslationDetails_translation_PageTranslatableContent_attributeValues_attributeValue | null; + translation: PageTranslationDetails_translation_PageTranslatableContent_attributeValues_translation | null; +} + export interface PageTranslationDetails_translation_PageTranslatableContent { __typename: "PageTranslatableContent"; page: PageTranslationDetails_translation_PageTranslatableContent_page | null; translation: PageTranslationDetails_translation_PageTranslatableContent_translation | null; + attributeValues: PageTranslationDetails_translation_PageTranslatableContent_attributeValues[]; } export type PageTranslationDetails_translation = PageTranslationDetails_translation_ProductTranslatableContent | PageTranslationDetails_translation_PageTranslatableContent; diff --git a/src/translations/types/PageTranslations.ts b/src/translations/types/PageTranslations.ts index 7dfa09e7d..b15b5fe81 100644 --- a/src/translations/types/PageTranslations.ts +++ b/src/translations/types/PageTranslations.ts @@ -38,10 +38,39 @@ export interface PageTranslations_translations_edges_node_PageTranslatableConten language: PageTranslations_translations_edges_node_PageTranslatableContent_translation_language; } +export interface PageTranslations_translations_edges_node_PageTranslatableContent_attributeValues_attributeValue { + __typename: "AttributeValue"; + id: string; +} + +export interface PageTranslations_translations_edges_node_PageTranslatableContent_attributeValues_translation_language { + __typename: "LanguageDisplay"; + code: LanguageCodeEnum; + language: string; +} + +export interface PageTranslations_translations_edges_node_PageTranslatableContent_attributeValues_translation { + __typename: "AttributeValueTranslation"; + id: string; + name: string; + richText: any | null; + language: PageTranslations_translations_edges_node_PageTranslatableContent_attributeValues_translation_language; +} + +export interface PageTranslations_translations_edges_node_PageTranslatableContent_attributeValues { + __typename: "AttributeValueTranslatableContent"; + id: string; + name: string; + richText: any | null; + attributeValue: PageTranslations_translations_edges_node_PageTranslatableContent_attributeValues_attributeValue | null; + translation: PageTranslations_translations_edges_node_PageTranslatableContent_attributeValues_translation | null; +} + export interface PageTranslations_translations_edges_node_PageTranslatableContent { __typename: "PageTranslatableContent"; page: PageTranslations_translations_edges_node_PageTranslatableContent_page | null; translation: PageTranslations_translations_edges_node_PageTranslatableContent_translation | null; + attributeValues: PageTranslations_translations_edges_node_PageTranslatableContent_attributeValues[]; } export type PageTranslations_translations_edges_node = PageTranslations_translations_edges_node_ProductTranslatableContent | PageTranslations_translations_edges_node_PageTranslatableContent; diff --git a/src/translations/types/ProductTranslationDetails.ts b/src/translations/types/ProductTranslationDetails.ts index b2433f421..d1b76ae81 100644 --- a/src/translations/types/ProductTranslationDetails.ts +++ b/src/translations/types/ProductTranslationDetails.ts @@ -31,17 +31,46 @@ export interface ProductTranslationDetails_translation_ProductTranslatableConten export interface ProductTranslationDetails_translation_ProductTranslatableContent_translation { __typename: "ProductTranslation"; id: string; + seoTitle: string | null; + seoDescription: string | null; + name: string | null; description: any | null; language: ProductTranslationDetails_translation_ProductTranslatableContent_translation_language; - name: string | null; - seoDescription: string | null; - seoTitle: string | null; +} + +export interface ProductTranslationDetails_translation_ProductTranslatableContent_attributeValues_attributeValue { + __typename: "AttributeValue"; + id: string; +} + +export interface ProductTranslationDetails_translation_ProductTranslatableContent_attributeValues_translation_language { + __typename: "LanguageDisplay"; + code: LanguageCodeEnum; + language: string; +} + +export interface ProductTranslationDetails_translation_ProductTranslatableContent_attributeValues_translation { + __typename: "AttributeValueTranslation"; + id: string; + name: string; + richText: any | null; + language: ProductTranslationDetails_translation_ProductTranslatableContent_attributeValues_translation_language; +} + +export interface ProductTranslationDetails_translation_ProductTranslatableContent_attributeValues { + __typename: "AttributeValueTranslatableContent"; + id: string; + name: string; + richText: any | null; + attributeValue: ProductTranslationDetails_translation_ProductTranslatableContent_attributeValues_attributeValue | null; + translation: ProductTranslationDetails_translation_ProductTranslatableContent_attributeValues_translation | null; } export interface ProductTranslationDetails_translation_ProductTranslatableContent { __typename: "ProductTranslatableContent"; product: ProductTranslationDetails_translation_ProductTranslatableContent_product | null; translation: ProductTranslationDetails_translation_ProductTranslatableContent_translation | null; + attributeValues: ProductTranslationDetails_translation_ProductTranslatableContent_attributeValues[]; } export type ProductTranslationDetails_translation = ProductTranslationDetails_translation_CollectionTranslatableContent | ProductTranslationDetails_translation_ProductTranslatableContent; diff --git a/src/translations/types/ProductTranslations.ts b/src/translations/types/ProductTranslations.ts index 2e076dbdb..76d43977e 100644 --- a/src/translations/types/ProductTranslations.ts +++ b/src/translations/types/ProductTranslations.ts @@ -31,17 +31,46 @@ export interface ProductTranslations_translations_edges_node_ProductTranslatable export interface ProductTranslations_translations_edges_node_ProductTranslatableContent_translation { __typename: "ProductTranslation"; id: string; + seoTitle: string | null; + seoDescription: string | null; + name: string | null; description: any | null; language: ProductTranslations_translations_edges_node_ProductTranslatableContent_translation_language; - name: string | null; - seoDescription: string | null; - seoTitle: string | null; +} + +export interface ProductTranslations_translations_edges_node_ProductTranslatableContent_attributeValues_attributeValue { + __typename: "AttributeValue"; + id: string; +} + +export interface ProductTranslations_translations_edges_node_ProductTranslatableContent_attributeValues_translation_language { + __typename: "LanguageDisplay"; + code: LanguageCodeEnum; + language: string; +} + +export interface ProductTranslations_translations_edges_node_ProductTranslatableContent_attributeValues_translation { + __typename: "AttributeValueTranslation"; + id: string; + name: string; + richText: any | null; + language: ProductTranslations_translations_edges_node_ProductTranslatableContent_attributeValues_translation_language; +} + +export interface ProductTranslations_translations_edges_node_ProductTranslatableContent_attributeValues { + __typename: "AttributeValueTranslatableContent"; + id: string; + name: string; + richText: any | null; + attributeValue: ProductTranslations_translations_edges_node_ProductTranslatableContent_attributeValues_attributeValue | null; + translation: ProductTranslations_translations_edges_node_ProductTranslatableContent_attributeValues_translation | null; } export interface ProductTranslations_translations_edges_node_ProductTranslatableContent { __typename: "ProductTranslatableContent"; product: ProductTranslations_translations_edges_node_ProductTranslatableContent_product | null; translation: ProductTranslations_translations_edges_node_ProductTranslatableContent_translation | null; + attributeValues: ProductTranslations_translations_edges_node_ProductTranslatableContent_attributeValues[]; } export type ProductTranslations_translations_edges_node = ProductTranslations_translations_edges_node_CollectionTranslatableContent | ProductTranslations_translations_edges_node_ProductTranslatableContent; diff --git a/src/translations/types/UpdateAttributeValueTranslations.ts b/src/translations/types/UpdateAttributeValueTranslations.ts index 4f164977a..da144a90d 100644 --- a/src/translations/types/UpdateAttributeValueTranslations.ts +++ b/src/translations/types/UpdateAttributeValueTranslations.ts @@ -26,6 +26,7 @@ export interface UpdateAttributeValueTranslations_attributeValueTranslate_attrib __typename: "AttributeValue"; id: string; name: string | null; + richText: any | null; translation: UpdateAttributeValueTranslations_attributeValueTranslate_attributeValue_translation | null; } diff --git a/src/translations/types/UpdatePageTranslations.ts b/src/translations/types/UpdatePageTranslations.ts index 4332ceaaf..999504ec2 100644 --- a/src/translations/types/UpdatePageTranslations.ts +++ b/src/translations/types/UpdatePageTranslations.ts @@ -40,10 +40,39 @@ export interface UpdatePageTranslations_pageTranslate_page_translation { language: UpdatePageTranslations_pageTranslate_page_translation_language; } +export interface UpdatePageTranslations_pageTranslate_page_attributeValues_attributeValue { + __typename: "AttributeValue"; + id: string; +} + +export interface UpdatePageTranslations_pageTranslate_page_attributeValues_translation_language { + __typename: "LanguageDisplay"; + code: LanguageCodeEnum; + language: string; +} + +export interface UpdatePageTranslations_pageTranslate_page_attributeValues_translation { + __typename: "AttributeValueTranslation"; + id: string; + name: string; + richText: any | null; + language: UpdatePageTranslations_pageTranslate_page_attributeValues_translation_language; +} + +export interface UpdatePageTranslations_pageTranslate_page_attributeValues { + __typename: "AttributeValueTranslatableContent"; + id: string; + name: string; + richText: any | null; + attributeValue: UpdatePageTranslations_pageTranslate_page_attributeValues_attributeValue | null; + translation: UpdatePageTranslations_pageTranslate_page_attributeValues_translation | null; +} + export interface UpdatePageTranslations_pageTranslate_page { __typename: "PageTranslatableContent"; page: UpdatePageTranslations_pageTranslate_page_page | null; translation: UpdatePageTranslations_pageTranslate_page_translation | null; + attributeValues: UpdatePageTranslations_pageTranslate_page_attributeValues[]; } export interface UpdatePageTranslations_pageTranslate { diff --git a/src/translations/urls.ts b/src/translations/urls.ts index fb751cb26..0e390e6d9 100644 --- a/src/translations/urls.ts +++ b/src/translations/urls.ts @@ -11,7 +11,7 @@ export enum TranslatableEntities { sales = "sales", vouchers = "vouchers", pages = "pages", - productTypes = "productTypes", + attributes = "attributes", shippingMethods = "shippingMethods" } diff --git a/src/translations/views/TranslationsProductTypes.tsx b/src/translations/views/TranslationsAttributes.tsx similarity index 88% rename from src/translations/views/TranslationsProductTypes.tsx rename to src/translations/views/TranslationsAttributes.tsx index a55a2795b..12f449960 100644 --- a/src/translations/views/TranslationsProductTypes.tsx +++ b/src/translations/views/TranslationsAttributes.tsx @@ -14,14 +14,15 @@ import { useIntl } from "react-intl"; import { getMutationState, maybe } from "../../misc"; import { LanguageCodeEnum } from "../../types/globalTypes"; -import TranslationsProductTypesPage, { +import TranslationsAttributesPage, { fieldNames -} from "../components/TranslationsProductTypesPage"; +} from "../components/TranslationsAttributesPage"; import { TypedUpdateAttributeTranslations, TypedUpdateAttributeValueTranslations } from "../mutations"; import { useAttributeTranslationDetails } from "../queries"; +import { TranslationField } from "../types"; import { UpdateAttributeTranslations } from "../types/UpdateAttributeTranslations"; import { UpdateAttributeValueTranslations } from "../types/UpdateAttributeValueTranslations"; import { @@ -30,16 +31,16 @@ import { TranslatableEntities } from "../urls"; -export interface TranslationsProductTypesQueryParams extends Pagination { +export interface TranslationsAttributesQueryParams extends Pagination { activeField: string; } -export interface TranslationsProductTypesProps { +export interface TranslationsAttributesProps { id: string; languageCode: LanguageCodeEnum; - params: TranslationsProductTypesQueryParams; + params: TranslationsAttributesQueryParams; } -const TranslationsProductTypes: React.FC = ({ +const TranslationsAttributes: React.FC = ({ id, languageCode, params @@ -121,8 +122,11 @@ const TranslationsProductTypes: React.FC = ({ updateAttributeValueTranslations, updateAttributeValueTranslationsOpts ) => { - const handleSubmit = (field: string, data: string | OutputData) => { - const [fieldName, fieldId] = field.split(":"); + const handleSubmit = ( + { name }: TranslationField, + data: string | OutputData + ) => { + const [fieldName, fieldId] = name.split(":"); if (fieldName === fieldNames.attribute) { updateAttributeTranslations({ @@ -168,7 +172,7 @@ const TranslationsProductTypes: React.FC = ({ ); return ( - = ({ onBack={() => navigate( languageEntitiesUrl(languageCode, { - tab: TranslatableEntities.productTypes + tab: TranslatableEntities.attributes }) ) } @@ -189,11 +193,7 @@ const TranslationsProductTypes: React.FC = ({ onDiscard={onDiscard} onLanguageChange={lang => navigate( - languageEntityUrl( - lang, - TranslatableEntities.productTypes, - id - ) + languageEntityUrl(lang, TranslatableEntities.attributes, id) ) } onSubmit={handleSubmit} @@ -211,5 +211,5 @@ const TranslationsProductTypes: React.FC = ({ ); }; -TranslationsProductTypes.displayName = "TranslationsProductTypes"; -export default TranslationsProductTypes; +TranslationsAttributes.displayName = "TranslationsAttributes"; +export default TranslationsAttributes; diff --git a/src/translations/views/TranslationsCategories.tsx b/src/translations/views/TranslationsCategories.tsx index c29fe6e12..7868b9aea 100644 --- a/src/translations/views/TranslationsCategories.tsx +++ b/src/translations/views/TranslationsCategories.tsx @@ -11,7 +11,7 @@ import { LanguageCodeEnum } from "../../types/globalTypes"; import TranslationsCategoriesPage from "../components/TranslationsCategoriesPage"; import { TypedUpdateCategoryTranslations } from "../mutations"; import { useCategoryTranslationDetails } from "../queries"; -import { TranslationInputFieldName } from "../types"; +import { TranslationField, TranslationInputFieldName } from "../types"; import { UpdateCategoryTranslations } from "../types/UpdateCategoryTranslations"; import { languageEntitiesUrl, @@ -69,13 +69,16 @@ const TranslationsCategories: React.FC = ({ {(updateTranslations, updateTranslationsOpts) => { const handleSubmit = ( - fieldName: TranslationInputFieldName, + { name: fieldName }: TranslationField, data: string | OutputData ) => { updateTranslations({ variables: { id, - input: getParsedTranslationInputData({ data, fieldName }), + input: getParsedTranslationInputData({ + data, + fieldName + }), language: languageCode } }); diff --git a/src/translations/views/TranslationsCollections.tsx b/src/translations/views/TranslationsCollections.tsx index efce16ca1..8705d1588 100644 --- a/src/translations/views/TranslationsCollections.tsx +++ b/src/translations/views/TranslationsCollections.tsx @@ -11,7 +11,7 @@ import { LanguageCodeEnum } from "../../types/globalTypes"; import TranslationsCollectionsPage from "../components/TranslationsCollectionsPage"; import { TypedUpdateCollectionTranslations } from "../mutations"; import { useCollectionTranslationDetails } from "../queries"; -import { TranslationInputFieldName } from "../types"; +import { TranslationField, TranslationInputFieldName } from "../types"; import { UpdateCollectionTranslations } from "../types/UpdateCollectionTranslations"; import { languageEntitiesUrl, @@ -70,13 +70,16 @@ const TranslationsCollections: React.FC = ({ {(updateTranslations, updateTranslationsOpts) => { const handleSubmit = ( - fieldName: TranslationInputFieldName, + { name: fieldName }: TranslationField, data: string ) => { updateTranslations({ variables: { id, - input: getParsedTranslationInputData({ data, fieldName }), + input: getParsedTranslationInputData({ + data, + fieldName + }), language: languageCode } }); diff --git a/src/translations/views/TranslationsEntities.tsx b/src/translations/views/TranslationsEntities.tsx index 16f07e353..26cca27c1 100644 --- a/src/translations/views/TranslationsEntities.tsx +++ b/src/translations/views/TranslationsEntities.tsx @@ -76,11 +76,11 @@ const TranslationsEntities: React.FC = ({ tab: TranslatableEntities.pages }) ), - onProductTypesTabClick: () => + onAttributesTabClick: () => navigate( "?" + stringifyQs({ - tab: TranslatableEntities.productTypes + tab: TranslatableEntities.attributes }) ), onProductsTabClick: () => @@ -380,7 +380,7 @@ const TranslationsEntities: React.FC = ({ ); }} - ) : params.tab === "productTypes" ? ( + ) : params.tab === "attributes" ? ( {({ data, loading }) => { const { loadNextPage, loadPreviousPage, pageInfo } = paginate( @@ -403,7 +403,7 @@ const TranslationsEntities: React.FC = ({ navigate( languageEntityUrl( language, - TranslatableEntities.productTypes, + TranslatableEntities.attributes, id ) ) diff --git a/src/translations/views/TranslationsPages.tsx b/src/translations/views/TranslationsPages.tsx index a6f98bae1..8eb2ee01d 100644 --- a/src/translations/views/TranslationsPages.tsx +++ b/src/translations/views/TranslationsPages.tsx @@ -1,3 +1,4 @@ +import { OutputData } from "@editorjs/editorjs"; import useNavigator from "@saleor/hooks/useNavigator"; import useNotifier from "@saleor/hooks/useNotifier"; import useShop from "@saleor/hooks/useShop"; @@ -8,10 +9,12 @@ import { useIntl } from "react-intl"; import { LanguageCodeEnum } from "../../types/globalTypes"; import TranslationsPagesPage from "../components/TranslationsPagesPage"; -import { TypedUpdatePageTranslations } from "../mutations"; +import { + TypedUpdateAttributeValueTranslations, + TypedUpdatePageTranslations +} from "../mutations"; import { usePageTranslationDetails } from "../queries"; -import { PageTranslationInputFieldName } from "../types"; -import { UpdatePageTranslations } from "../types/UpdatePageTranslations"; +import { PageTranslationInputFieldName, TranslationField } from "../types"; import { languageEntitiesUrl, languageEntityUrl, @@ -50,8 +53,9 @@ const TranslationsPages: React.FC = ({ }), true ); - const onUpdate = (data: UpdatePageTranslations) => { - if (data.pageTranslate.errors.length === 0) { + + const onUpdate = (errors: unknown[]) => { + if (errors.length === 0) { pageTranslations.refetch(); notify({ status: "success", @@ -60,57 +64,88 @@ const TranslationsPages: React.FC = ({ navigate("?", true); } }; + const onDiscard = () => { navigate("?", true); }; return ( - - {(updateTranslations, updateTranslationsOpts) => { - const handleSubmit = ( - fieldName: PageTranslationInputFieldName, - data: string - ) => { - updateTranslations({ - variables: { - id, - input: getParsedTranslationInputData({ data, fieldName }), - language: languageCode - } - }); - }; - const translation = pageTranslations?.data?.translation; + onUpdate(data.pageTranslate.errors)} + > + {(updateTranslations, updateTranslationsOpts) => ( + onUpdate(data.attributeValueTranslate.errors)} + > + {updateAttributeValueTranslations => { + const handleSubmit = ( + { + name: fieldName + }: TranslationField, + data: string | any + ) => { + updateTranslations({ + variables: { + id, + input: getParsedTranslationInputData({ + data, + fieldName + }), + language: languageCode + } + }); + }; - return ( - - navigate( - languageEntitiesUrl(languageCode, { - tab: TranslatableEntities.pages - }) - ) - } - onEdit={onEdit} - onDiscard={onDiscard} - onLanguageChange={lang => - navigate(languageEntityUrl(lang, TranslatableEntities.pages, id)) - } - onSubmit={handleSubmit} - data={ - translation?.__typename === "PageTranslatableContent" - ? translation - : null - } - /> - ); - }} + const handleAttributeValueSubmit = ( + { id }: TranslationField, + data: OutputData + ) => { + updateAttributeValueTranslations({ + variables: { + id, + input: { richText: JSON.stringify(data) }, + language: languageCode + } + }); + }; + + const translation = pageTranslations?.data?.translation; + + return ( + + navigate( + languageEntitiesUrl(languageCode, { + tab: TranslatableEntities.pages + }) + ) + } + onEdit={onEdit} + onDiscard={onDiscard} + onLanguageChange={lang => + navigate( + languageEntityUrl(lang, TranslatableEntities.pages, id) + ) + } + onSubmit={handleSubmit} + onAttributeValueSubmit={handleAttributeValueSubmit} + data={ + translation?.__typename === "PageTranslatableContent" + ? translation + : null + } + /> + ); + }} + + )} ); }; diff --git a/src/translations/views/TranslationsProducts.tsx b/src/translations/views/TranslationsProducts.tsx index 984ee4a92..3c62e5768 100644 --- a/src/translations/views/TranslationsProducts.tsx +++ b/src/translations/views/TranslationsProducts.tsx @@ -1,3 +1,4 @@ +import { OutputData } from "@editorjs/editorjs"; import useNavigator from "@saleor/hooks/useNavigator"; import useNotifier from "@saleor/hooks/useNotifier"; import useShop from "@saleor/hooks/useShop"; @@ -9,10 +10,12 @@ import { useIntl } from "react-intl"; import { maybe } from "../../misc"; import { LanguageCodeEnum } from "../../types/globalTypes"; import TranslationsProductsPage from "../components/TranslationsProductsPage"; -import { TypedUpdateProductTranslations } from "../mutations"; +import { + TypedUpdateAttributeValueTranslations, + TypedUpdateProductTranslations +} from "../mutations"; import { useProductTranslationDetails } from "../queries"; -import { TranslationInputFieldName } from "../types"; -import { UpdateProductTranslations } from "../types/UpdateProductTranslations"; +import { TranslationField, TranslationInputFieldName } from "../types"; import { languageEntitiesUrl, languageEntityUrl, @@ -51,8 +54,9 @@ const TranslationsProducts: React.FC = ({ }), true ); - const onUpdate = (data: UpdateProductTranslations) => { - if (data.productTranslate.errors.length === 0) { + + const onUpdate = (errors: unknown[]) => { + if (errors.length === 0) { productTranslations.refetch(); notify({ status: "success", @@ -61,59 +65,86 @@ const TranslationsProducts: React.FC = ({ navigate("?", true); } }; + const onDiscard = () => { navigate("?", true); }; return ( - - {(updateTranslations, updateTranslationsOpts) => { - const handleSubmit = ( - fieldName: TranslationInputFieldName, - data: string - ) => { - updateTranslations({ - variables: { - id, - input: getParsedTranslationInputData({ data, fieldName }), - language: languageCode - } - }); - }; - const translation = productTranslations?.data?.translation; + onUpdate(data.productTranslate.errors)} + > + {(updateTranslations, updateTranslationsOpts) => ( + onUpdate(data.attributeValueTranslate.errors)} + > + {updateAttributeValueTranslations => { + const handleSubmit = ( + { name: fieldName }: TranslationField, + data: string + ) => { + updateTranslations({ + variables: { + id, + input: getParsedTranslationInputData({ + data, + fieldName + }), + language: languageCode + } + }); + }; - return ( - shop.languages, [])} - saveButtonState={updateTranslationsOpts.status} - onBack={() => - navigate( - languageEntitiesUrl(languageCode, { - tab: TranslatableEntities.products - }) - ) - } - onEdit={onEdit} - onDiscard={onDiscard} - onLanguageChange={lang => - navigate( - languageEntityUrl(lang, TranslatableEntities.products, id) - ) - } - onSubmit={handleSubmit} - data={ - translation?.__typename === "ProductTranslatableContent" - ? translation - : null - } - /> - ); - }} + const handleAttributeValueSubmit = ( + { id }: TranslationField, + data: OutputData + ) => { + updateAttributeValueTranslations({ + variables: { + id, + input: { richText: JSON.stringify(data) }, + language: languageCode + } + }); + }; + + const translation = productTranslations?.data?.translation; + + return ( + shop.languages, [])} + saveButtonState={updateTranslationsOpts.status} + onBack={() => + navigate( + languageEntitiesUrl(languageCode, { + tab: TranslatableEntities.products + }) + ) + } + onEdit={onEdit} + onDiscard={onDiscard} + onLanguageChange={lang => + navigate( + languageEntityUrl(lang, TranslatableEntities.products, id) + ) + } + onSubmit={handleSubmit} + onAttributeValueSubmit={handleAttributeValueSubmit} + data={ + translation?.__typename === "ProductTranslatableContent" + ? translation + : null + } + /> + ); + }} + + )} ); }; diff --git a/src/translations/views/TranslationsSales.tsx b/src/translations/views/TranslationsSales.tsx index d4960c1c5..e12b1612d 100644 --- a/src/translations/views/TranslationsSales.tsx +++ b/src/translations/views/TranslationsSales.tsx @@ -6,21 +6,18 @@ import { stringify as stringifyQs } from "qs"; import React from "react"; import { useIntl } from "react-intl"; -import { - LanguageCodeEnum, - NameTranslationInput -} from "../../types/globalTypes"; -import TranslationsSalesPage, { - fieldNames -} from "../components/TranslationsSalesPage"; +import { LanguageCodeEnum } from "../../types/globalTypes"; +import TranslationsSalesPage from "../components/TranslationsSalesPage"; import { TypedUpdateSaleTranslations } from "../mutations"; import { useSaleTranslationDetails } from "../queries"; +import { TranslationField, TranslationInputFieldName } from "../types"; import { UpdateSaleTranslations } from "../types/UpdateSaleTranslations"; import { languageEntitiesUrl, languageEntityUrl, TranslatableEntities } from "../urls"; +import { getParsedTranslationInputData } from "../utils"; export interface TranslationsSalesQueryParams { activeField: string; @@ -70,15 +67,17 @@ const TranslationsSales: React.FC = ({ return ( {(updateTranslations, updateTranslationsOpts) => { - const handleSubmit = (field: string, data: string) => { - const input: NameTranslationInput = {}; - if (field === fieldNames.name) { - input.name = data; - } + const handleSubmit = ( + { name: fieldName }: TranslationField, + data: string + ) => { updateTranslations({ variables: { id, - input, + input: getParsedTranslationInputData({ + data, + fieldName + }), language: languageCode } }); diff --git a/src/translations/views/TranslationsShippingMethod.tsx b/src/translations/views/TranslationsShippingMethod.tsx index 1027fb053..2e65bb1d5 100644 --- a/src/translations/views/TranslationsShippingMethod.tsx +++ b/src/translations/views/TranslationsShippingMethod.tsx @@ -10,7 +10,7 @@ import { LanguageCodeEnum } from "../../types/globalTypes"; import TranslationsShippingMethodPage from "../components/TranslationsShippingMethodPage"; import { TypedUpdateShippingMethodTranslations } from "../mutations"; import { useShippingMethodTranslationDetails } from "../queries"; -import { TranslationInputFieldName } from "../types"; +import { TranslationField, TranslationInputFieldName } from "../types"; import { UpdateShippingMethodTranslations } from "../types/UpdateShippingMethodTranslations"; import { languageEntitiesUrl, @@ -68,13 +68,13 @@ const TranslationsShippingMethod: React.FC = ({ {(updateTranslations, updateTranslationsOpts) => { const handleSubmit = ( - field: TranslationInputFieldName, + { name: fieldName }: TranslationField, data: string ) => { updateTranslations({ variables: { id, - input: getParsedTranslationInputData({ fieldName: field, data }), + input: getParsedTranslationInputData({ fieldName, data }), language: languageCode } }); diff --git a/src/translations/views/TranslationsVouchers.tsx b/src/translations/views/TranslationsVouchers.tsx index e41f9a77b..9f78666d3 100644 --- a/src/translations/views/TranslationsVouchers.tsx +++ b/src/translations/views/TranslationsVouchers.tsx @@ -7,21 +7,18 @@ import React from "react"; import { useIntl } from "react-intl"; import { maybe } from "../../misc"; -import { - LanguageCodeEnum, - NameTranslationInput -} from "../../types/globalTypes"; -import TranslationsVouchersPage, { - fieldNames -} from "../components/TranslationsVouchersPage"; +import { LanguageCodeEnum } from "../../types/globalTypes"; +import TranslationsVouchersPage from "../components/TranslationsVouchersPage"; import { TypedUpdateVoucherTranslations } from "../mutations"; import { useVoucherTranslationDetails } from "../queries"; +import { TranslationField, TranslationInputFieldName } from "../types"; import { UpdateVoucherTranslations } from "../types/UpdateVoucherTranslations"; import { languageEntitiesUrl, languageEntityUrl, TranslatableEntities } from "../urls"; +import { getParsedTranslationInputData } from "../utils"; export interface TranslationsVouchersQueryParams { activeField: string; @@ -71,15 +68,17 @@ const TranslationsVouchers: React.FC = ({ return ( {(updateTranslations, updateTranslationsOpts) => { - const handleSubmit = (field: string, data: string) => { - const input: NameTranslationInput = {}; - if (field === fieldNames.name) { - input.name = data; - } + const handleSubmit = ( + { name: fieldName }: TranslationField, + data: string + ) => { updateTranslations({ variables: { id, - input, + input: getParsedTranslationInputData({ + data, + fieldName + }), language: languageCode } });