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 <majorek.jakub@gmail.com>
This commit is contained in:
parent
8d2021675e
commit
034eea0dcd
38 changed files with 781 additions and 298 deletions
|
@ -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
|
||||
|
||||
|
|
|
@ -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}"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -56,6 +56,7 @@ export interface AttributeTranslationDetailsFragment_attribute {
|
|||
id: string;
|
||||
name: string | null;
|
||||
inputType: AttributeInputTypeEnum | null;
|
||||
withChoices: boolean;
|
||||
choices: AttributeTranslationDetailsFragment_attribute_choices | null;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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[];
|
||||
}
|
||||
|
|
|
@ -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[];
|
||||
}
|
||||
|
|
|
@ -99,6 +99,9 @@ export const commonMessages = defineMessages({
|
|||
summary: {
|
||||
defaultMessage: "Summary"
|
||||
},
|
||||
translationAttributes: {
|
||||
defaultMessage: "Attributes"
|
||||
},
|
||||
unauthorizedDashboardAccess: {
|
||||
defaultMessage: "Only staff users can access the dashboard"
|
||||
},
|
||||
|
|
|
@ -18,7 +18,7 @@ const props: TranslationsEntitiesListPageProps = {
|
|||
onCategoriesTabClick: () => undefined,
|
||||
onCollectionsTabClick: () => undefined,
|
||||
onPagesTabClick: () => undefined,
|
||||
onProductTypesTabClick: () => undefined,
|
||||
onAttributesTabClick: () => undefined,
|
||||
onProductsTabClick: () => undefined,
|
||||
onSalesTabClick: () => undefined,
|
||||
onShippingMethodsTabClick: () => undefined,
|
||||
|
|
|
@ -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<keyof ListProps, "onRowClick" | "disabled">
|
||||
|
@ -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<TranslationFieldsProps> = props => {
|
|||
initial={field.translation}
|
||||
saveButtonState={saveButtonState}
|
||||
onDiscard={onDiscard}
|
||||
onSubmit={data => onSubmit(field.name, data)}
|
||||
onSubmit={data => onSubmit(field, data)}
|
||||
/>
|
||||
) : field.type === "long" ? (
|
||||
<TranslationFieldsLong
|
||||
|
@ -224,7 +217,7 @@ const TranslationFields: React.FC<TranslationFieldsProps> = props => {
|
|||
initial={field.translation}
|
||||
saveButtonState={saveButtonState}
|
||||
onDiscard={onDiscard}
|
||||
onSubmit={data => onSubmit(field.name, data)}
|
||||
onSubmit={data => onSubmit(field, data)}
|
||||
/>
|
||||
) : (
|
||||
<TranslationFieldsRich
|
||||
|
@ -233,7 +226,7 @@ const TranslationFields: React.FC<TranslationFieldsProps> = props => {
|
|||
initial={field.translation}
|
||||
saveButtonState={saveButtonState}
|
||||
onDiscard={onDiscard}
|
||||
onSubmit={data => onSubmit(field.name, data)}
|
||||
onSubmit={data => onSubmit(field, data)}
|
||||
/>
|
||||
)
|
||||
) : (
|
||||
|
|
|
@ -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<TranslationsProductTypesPageProps> = ({
|
||||
const TranslationsAttributesPage: React.FC<TranslationsAttributesPageProps> = ({
|
||||
activeField,
|
||||
disabled,
|
||||
languages,
|
||||
|
@ -64,6 +64,8 @@ const TranslationsProductTypesPage: React.FC<TranslationsProductTypesPageProps>
|
|||
}) => {
|
||||
const intl = useIntl();
|
||||
|
||||
const withChoices = data?.attribute?.withChoices;
|
||||
|
||||
return (
|
||||
<Container>
|
||||
<Backlink onClick={onBack}>
|
||||
|
@ -110,6 +112,7 @@ const TranslationsProductTypesPage: React.FC<TranslationsProductTypesPageProps>
|
|||
onSubmit={onSubmit}
|
||||
/>
|
||||
<CardSpacer />
|
||||
{data?.attribute?.choices.edges.length > 0 && withChoices && (
|
||||
<TranslationFields
|
||||
activeField={activeField}
|
||||
disabled={disabled}
|
||||
|
@ -118,14 +121,7 @@ const TranslationsProductTypesPage: React.FC<TranslationsProductTypesPageProps>
|
|||
fields={
|
||||
data?.attribute?.choices?.edges?.map(
|
||||
({ node: attributeValue }, attributeValueIndex) => {
|
||||
const isRichText =
|
||||
attributeValue?.inputType === AttributeInputTypeEnum.RICH_TEXT;
|
||||
const displayName = isRichText
|
||||
? intl.formatMessage({
|
||||
defaultMessage: "Text",
|
||||
description: "attribute richtext value"
|
||||
})
|
||||
: intl.formatMessage(
|
||||
const displayName = intl.formatMessage(
|
||||
{
|
||||
defaultMessage: "Value {number}",
|
||||
description: "attribute values"
|
||||
|
@ -137,19 +133,10 @@ const TranslationsProductTypesPage: React.FC<TranslationsProductTypesPageProps>
|
|||
|
||||
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
|
||||
name: `${fieldNames.value}:${attributeValue.id}`,
|
||||
translation: attributeValue?.translation?.name || null,
|
||||
type: "short" as TranslationField["type"],
|
||||
value: attributeValue?.name
|
||||
};
|
||||
}
|
||||
) || []
|
||||
|
@ -166,8 +153,9 @@ const TranslationsProductTypesPage: React.FC<TranslationsProductTypesPageProps>
|
|||
onDiscard={onDiscard}
|
||||
onSubmit={onSubmit}
|
||||
/>
|
||||
)}
|
||||
</Container>
|
||||
);
|
||||
};
|
||||
TranslationsProductTypesPage.displayName = "TranslationsProductTypesPage";
|
||||
export default TranslationsProductTypesPage;
|
||||
TranslationsAttributesPage.displayName = "TranslationsAttributesPage";
|
||||
export default TranslationsAttributesPage;
|
|
@ -0,0 +1,2 @@
|
|||
export { default } from "./TranslationsAttributesPage";
|
||||
export * from "./TranslationsAttributesPage";
|
|
@ -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<TranslationsEntitiesListPageProps>
|
|||
label={intl.formatMessage({
|
||||
defaultMessage: "Attributes"
|
||||
})}
|
||||
onClick={filters.onProductTypesTabClick}
|
||||
onClick={filters.onAttributesTabClick}
|
||||
/>
|
||||
<FilterTab
|
||||
label={intl.formatMessage({
|
||||
|
|
|
@ -19,6 +19,7 @@ import TranslationFields from "../TranslationFields";
|
|||
export interface TranslationsPagesPageProps
|
||||
extends TranslationsEntitiesPageProps {
|
||||
data: PageTranslationFragment;
|
||||
onAttributeValueSubmit: TranslationsEntitiesPageProps["onSubmit"];
|
||||
}
|
||||
|
||||
const TranslationsPagesPage: React.FC<TranslationsPagesPageProps> = ({
|
||||
|
@ -32,7 +33,8 @@ const TranslationsPagesPage: React.FC<TranslationsPagesPageProps> = ({
|
|||
onDiscard,
|
||||
onEdit,
|
||||
onLanguageChange,
|
||||
onSubmit
|
||||
onSubmit,
|
||||
onAttributeValueSubmit
|
||||
}) => {
|
||||
const intl = useIntl();
|
||||
|
||||
|
@ -90,6 +92,7 @@ const TranslationsPagesPage: React.FC<TranslationsPagesPageProps> = ({
|
|||
onDiscard={onDiscard}
|
||||
onSubmit={onSubmit}
|
||||
/>
|
||||
|
||||
<CardSpacer />
|
||||
<TranslationFields
|
||||
activeField={activeField}
|
||||
|
@ -123,6 +126,40 @@ const TranslationsPagesPage: React.FC<TranslationsPagesPageProps> = ({
|
|||
onDiscard={onDiscard}
|
||||
onSubmit={onSubmit}
|
||||
/>
|
||||
<CardSpacer />
|
||||
{data?.attributeValues?.length > 0 && (
|
||||
<>
|
||||
<TranslationFields
|
||||
activeField={activeField}
|
||||
disabled={disabled}
|
||||
initialState={true}
|
||||
title={intl.formatMessage(commonMessages.translationAttributes)}
|
||||
fields={
|
||||
data.attributeValues.map((attrVal, i) => ({
|
||||
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}
|
||||
/>
|
||||
<CardSpacer />
|
||||
</>
|
||||
)}
|
||||
</Container>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
export { default } from "./TranslationsProductTypesPage";
|
||||
export * from "./TranslationsProductTypesPage";
|
|
@ -19,6 +19,7 @@ import TranslationFields from "../TranslationFields";
|
|||
export interface TranslationsProductsPageProps
|
||||
extends TranslationsEntitiesPageProps {
|
||||
data: ProductTranslationFragment;
|
||||
onAttributeValueSubmit: TranslationsEntitiesPageProps["onSubmit"];
|
||||
}
|
||||
|
||||
const TranslationsProductsPage: React.FC<TranslationsProductsPageProps> = ({
|
||||
|
@ -32,7 +33,8 @@ const TranslationsProductsPage: React.FC<TranslationsProductsPageProps> = ({
|
|||
onDiscard,
|
||||
onEdit,
|
||||
onLanguageChange,
|
||||
onSubmit
|
||||
onSubmit,
|
||||
onAttributeValueSubmit
|
||||
}) => {
|
||||
const intl = useIntl();
|
||||
|
||||
|
@ -123,6 +125,40 @@ const TranslationsProductsPage: React.FC<TranslationsProductsPageProps> = ({
|
|||
onDiscard={onDiscard}
|
||||
onSubmit={onSubmit}
|
||||
/>
|
||||
<CardSpacer />
|
||||
{data?.attributeValues?.length > 0 && (
|
||||
<>
|
||||
<TranslationFields
|
||||
activeField={activeField}
|
||||
disabled={disabled}
|
||||
initialState={true}
|
||||
title={intl.formatMessage(commonMessages.translationAttributes)}
|
||||
fields={
|
||||
data.attributeValues.map((attrVal, i) => ({
|
||||
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}
|
||||
/>
|
||||
<CardSpacer />
|
||||
</>
|
||||
)}
|
||||
</Container>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -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<TranslationsEntityRouteProps> = ({
|
|||
/>
|
||||
);
|
||||
};
|
||||
const TranslationsProductTypes: React.FC<TranslationsEntityRouteProps> = ({
|
||||
const TranslationsAttributes: React.FC<TranslationsEntityRouteProps> = ({
|
||||
location,
|
||||
match
|
||||
}) => {
|
||||
const qs = parseQs(location.search.substr(1));
|
||||
const params: TranslationsProductTypesQueryParams = {
|
||||
const params: TranslationsAttributesQueryParams = {
|
||||
activeField: qs.activeField
|
||||
};
|
||||
return (
|
||||
<TranslationsProductTypesComponent
|
||||
<TranslationsAttributesComponent
|
||||
id={decodeURIComponent(match.params.id)}
|
||||
languageCode={LanguageCodeEnum[match.params.languageCode]}
|
||||
params={params}
|
||||
|
@ -263,10 +263,10 @@ const TranslationsRouter: React.FC = () => {
|
|||
exact
|
||||
path={languageEntityPath(
|
||||
":languageCode",
|
||||
TranslatableEntities.productTypes,
|
||||
TranslatableEntities.attributes,
|
||||
":id"
|
||||
)}
|
||||
component={TranslationsProductTypes}
|
||||
component={TranslationsAttributes}
|
||||
/>
|
||||
<Route
|
||||
exact
|
||||
|
|
|
@ -276,6 +276,7 @@ const updateAttributeValueTranslations = gql`
|
|||
attributeValue {
|
||||
id
|
||||
name
|
||||
richText
|
||||
translation(languageCode: $language) {
|
||||
id
|
||||
name
|
||||
|
|
|
@ -2,6 +2,31 @@ import { OutputData } from "@editorjs/editorjs";
|
|||
import { ConfirmButtonTransitionState } from "@saleor/components/ConfirmButton";
|
||||
import { ShopInfo_shop_languages } from "@saleor/components/Shop/types/ShopInfo";
|
||||
|
||||
export enum TranslationInputFieldName {
|
||||
description = "description",
|
||||
name = "name",
|
||||
seoDescription = "seoDescription",
|
||||
seoTitle = "seoTitle",
|
||||
richText = "richText"
|
||||
}
|
||||
|
||||
export enum PageTranslationInputFieldName {
|
||||
content = "content",
|
||||
title = "title",
|
||||
seoDescription = "seoDescription",
|
||||
seoTitle = "seoTitle",
|
||||
richText = "richText"
|
||||
}
|
||||
|
||||
export interface TranslationField<T extends string = string> {
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -11,7 +11,7 @@ export enum TranslatableEntities {
|
|||
sales = "sales",
|
||||
vouchers = "vouchers",
|
||||
pages = "pages",
|
||||
productTypes = "productTypes",
|
||||
attributes = "attributes",
|
||||
shippingMethods = "shippingMethods"
|
||||
}
|
||||
|
||||
|
|
|
@ -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<TranslationsProductTypesProps> = ({
|
||||
const TranslationsAttributes: React.FC<TranslationsAttributesProps> = ({
|
||||
id,
|
||||
languageCode,
|
||||
params
|
||||
|
@ -121,8 +122,11 @@ const TranslationsProductTypes: React.FC<TranslationsProductTypesProps> = ({
|
|||
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<TranslationsProductTypesProps> = ({
|
|||
);
|
||||
|
||||
return (
|
||||
<TranslationsProductTypesPage
|
||||
<TranslationsAttributesPage
|
||||
activeField={params.activeField}
|
||||
disabled={
|
||||
attributeTranslations.loading ||
|
||||
|
@ -181,7 +185,7 @@ const TranslationsProductTypes: React.FC<TranslationsProductTypesProps> = ({
|
|||
onBack={() =>
|
||||
navigate(
|
||||
languageEntitiesUrl(languageCode, {
|
||||
tab: TranslatableEntities.productTypes
|
||||
tab: TranslatableEntities.attributes
|
||||
})
|
||||
)
|
||||
}
|
||||
|
@ -189,11 +193,7 @@ const TranslationsProductTypes: React.FC<TranslationsProductTypesProps> = ({
|
|||
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<TranslationsProductTypesProps> = ({
|
|||
</TypedUpdateAttributeTranslations>
|
||||
);
|
||||
};
|
||||
TranslationsProductTypes.displayName = "TranslationsProductTypes";
|
||||
export default TranslationsProductTypes;
|
||||
TranslationsAttributes.displayName = "TranslationsAttributes";
|
||||
export default TranslationsAttributes;
|
|
@ -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<TranslationsCategoriesProps> = ({
|
|||
<TypedUpdateCategoryTranslations onCompleted={onUpdate}>
|
||||
{(updateTranslations, updateTranslationsOpts) => {
|
||||
const handleSubmit = (
|
||||
fieldName: TranslationInputFieldName,
|
||||
{ name: fieldName }: TranslationField<TranslationInputFieldName>,
|
||||
data: string | OutputData
|
||||
) => {
|
||||
updateTranslations({
|
||||
variables: {
|
||||
id,
|
||||
input: getParsedTranslationInputData({ data, fieldName }),
|
||||
input: getParsedTranslationInputData({
|
||||
data,
|
||||
fieldName
|
||||
}),
|
||||
language: languageCode
|
||||
}
|
||||
});
|
||||
|
|
|
@ -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<TranslationsCollectionsProps> = ({
|
|||
<TypedUpdateCollectionTranslations onCompleted={onUpdate}>
|
||||
{(updateTranslations, updateTranslationsOpts) => {
|
||||
const handleSubmit = (
|
||||
fieldName: TranslationInputFieldName,
|
||||
{ name: fieldName }: TranslationField<TranslationInputFieldName>,
|
||||
data: string
|
||||
) => {
|
||||
updateTranslations({
|
||||
variables: {
|
||||
id,
|
||||
input: getParsedTranslationInputData({ data, fieldName }),
|
||||
input: getParsedTranslationInputData({
|
||||
data,
|
||||
fieldName
|
||||
}),
|
||||
language: languageCode
|
||||
}
|
||||
});
|
||||
|
|
|
@ -76,11 +76,11 @@ const TranslationsEntities: React.FC<TranslationsEntitiesProps> = ({
|
|||
tab: TranslatableEntities.pages
|
||||
})
|
||||
),
|
||||
onProductTypesTabClick: () =>
|
||||
onAttributesTabClick: () =>
|
||||
navigate(
|
||||
"?" +
|
||||
stringifyQs({
|
||||
tab: TranslatableEntities.productTypes
|
||||
tab: TranslatableEntities.attributes
|
||||
})
|
||||
),
|
||||
onProductsTabClick: () =>
|
||||
|
@ -380,7 +380,7 @@ const TranslationsEntities: React.FC<TranslationsEntitiesProps> = ({
|
|||
);
|
||||
}}
|
||||
</TypedPageTranslations>
|
||||
) : params.tab === "productTypes" ? (
|
||||
) : params.tab === "attributes" ? (
|
||||
<TypedAttributeTranslations variables={queryVariables}>
|
||||
{({ data, loading }) => {
|
||||
const { loadNextPage, loadPreviousPage, pageInfo } = paginate(
|
||||
|
@ -403,7 +403,7 @@ const TranslationsEntities: React.FC<TranslationsEntitiesProps> = ({
|
|||
navigate(
|
||||
languageEntityUrl(
|
||||
language,
|
||||
TranslatableEntities.productTypes,
|
||||
TranslatableEntities.attributes,
|
||||
id
|
||||
)
|
||||
)
|
||||
|
|
|
@ -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<TranslationsPagesProps> = ({
|
|||
}),
|
||||
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,25 +64,51 @@ const TranslationsPages: React.FC<TranslationsPagesProps> = ({
|
|||
navigate("?", true);
|
||||
}
|
||||
};
|
||||
|
||||
const onDiscard = () => {
|
||||
navigate("?", true);
|
||||
};
|
||||
|
||||
return (
|
||||
<TypedUpdatePageTranslations onCompleted={onUpdate}>
|
||||
{(updateTranslations, updateTranslationsOpts) => {
|
||||
<TypedUpdatePageTranslations
|
||||
onCompleted={data => onUpdate(data.pageTranslate.errors)}
|
||||
>
|
||||
{(updateTranslations, updateTranslationsOpts) => (
|
||||
<TypedUpdateAttributeValueTranslations
|
||||
onCompleted={data => onUpdate(data.attributeValueTranslate.errors)}
|
||||
>
|
||||
{updateAttributeValueTranslations => {
|
||||
const handleSubmit = (
|
||||
fieldName: PageTranslationInputFieldName,
|
||||
data: string
|
||||
{
|
||||
name: fieldName
|
||||
}: TranslationField<PageTranslationInputFieldName>,
|
||||
data: string | any
|
||||
) => {
|
||||
updateTranslations({
|
||||
variables: {
|
||||
id,
|
||||
input: getParsedTranslationInputData({ data, fieldName }),
|
||||
input: getParsedTranslationInputData({
|
||||
data,
|
||||
fieldName
|
||||
}),
|
||||
language: languageCode
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const handleAttributeValueSubmit = (
|
||||
{ id }: TranslationField<PageTranslationInputFieldName>,
|
||||
data: OutputData
|
||||
) => {
|
||||
updateAttributeValueTranslations({
|
||||
variables: {
|
||||
id,
|
||||
input: { richText: JSON.stringify(data) },
|
||||
language: languageCode
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const translation = pageTranslations?.data?.translation;
|
||||
|
||||
return (
|
||||
|
@ -100,9 +130,12 @@ const TranslationsPages: React.FC<TranslationsPagesProps> = ({
|
|||
onEdit={onEdit}
|
||||
onDiscard={onDiscard}
|
||||
onLanguageChange={lang =>
|
||||
navigate(languageEntityUrl(lang, TranslatableEntities.pages, id))
|
||||
navigate(
|
||||
languageEntityUrl(lang, TranslatableEntities.pages, id)
|
||||
)
|
||||
}
|
||||
onSubmit={handleSubmit}
|
||||
onAttributeValueSubmit={handleAttributeValueSubmit}
|
||||
data={
|
||||
translation?.__typename === "PageTranslatableContent"
|
||||
? translation
|
||||
|
@ -111,6 +144,8 @@ const TranslationsPages: React.FC<TranslationsPagesProps> = ({
|
|||
/>
|
||||
);
|
||||
}}
|
||||
</TypedUpdateAttributeValueTranslations>
|
||||
)}
|
||||
</TypedUpdatePageTranslations>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -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<TranslationsProductsProps> = ({
|
|||
}),
|
||||
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,25 +65,49 @@ const TranslationsProducts: React.FC<TranslationsProductsProps> = ({
|
|||
navigate("?", true);
|
||||
}
|
||||
};
|
||||
|
||||
const onDiscard = () => {
|
||||
navigate("?", true);
|
||||
};
|
||||
|
||||
return (
|
||||
<TypedUpdateProductTranslations onCompleted={onUpdate}>
|
||||
{(updateTranslations, updateTranslationsOpts) => {
|
||||
<TypedUpdateProductTranslations
|
||||
onCompleted={data => onUpdate(data.productTranslate.errors)}
|
||||
>
|
||||
{(updateTranslations, updateTranslationsOpts) => (
|
||||
<TypedUpdateAttributeValueTranslations
|
||||
onCompleted={data => onUpdate(data.attributeValueTranslate.errors)}
|
||||
>
|
||||
{updateAttributeValueTranslations => {
|
||||
const handleSubmit = (
|
||||
fieldName: TranslationInputFieldName,
|
||||
{ name: fieldName }: TranslationField<TranslationInputFieldName>,
|
||||
data: string
|
||||
) => {
|
||||
updateTranslations({
|
||||
variables: {
|
||||
id,
|
||||
input: getParsedTranslationInputData({ data, fieldName }),
|
||||
input: getParsedTranslationInputData({
|
||||
data,
|
||||
fieldName
|
||||
}),
|
||||
language: languageCode
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const handleAttributeValueSubmit = (
|
||||
{ id }: TranslationField<TranslationInputFieldName>,
|
||||
data: OutputData
|
||||
) => {
|
||||
updateAttributeValueTranslations({
|
||||
variables: {
|
||||
id,
|
||||
input: { richText: JSON.stringify(data) },
|
||||
language: languageCode
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const translation = productTranslations?.data?.translation;
|
||||
|
||||
return (
|
||||
|
@ -106,6 +134,7 @@ const TranslationsProducts: React.FC<TranslationsProductsProps> = ({
|
|||
)
|
||||
}
|
||||
onSubmit={handleSubmit}
|
||||
onAttributeValueSubmit={handleAttributeValueSubmit}
|
||||
data={
|
||||
translation?.__typename === "ProductTranslatableContent"
|
||||
? translation
|
||||
|
@ -114,6 +143,8 @@ const TranslationsProducts: React.FC<TranslationsProductsProps> = ({
|
|||
/>
|
||||
);
|
||||
}}
|
||||
</TypedUpdateAttributeValueTranslations>
|
||||
)}
|
||||
</TypedUpdateProductTranslations>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -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<TranslationsSalesProps> = ({
|
|||
return (
|
||||
<TypedUpdateSaleTranslations onCompleted={onUpdate}>
|
||||
{(updateTranslations, updateTranslationsOpts) => {
|
||||
const handleSubmit = (field: string, data: string) => {
|
||||
const input: NameTranslationInput = {};
|
||||
if (field === fieldNames.name) {
|
||||
input.name = data;
|
||||
}
|
||||
const handleSubmit = (
|
||||
{ name: fieldName }: TranslationField<TranslationInputFieldName>,
|
||||
data: string
|
||||
) => {
|
||||
updateTranslations({
|
||||
variables: {
|
||||
id,
|
||||
input,
|
||||
input: getParsedTranslationInputData({
|
||||
data,
|
||||
fieldName
|
||||
}),
|
||||
language: languageCode
|
||||
}
|
||||
});
|
||||
|
|
|
@ -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<TranslationsShippingMethodProps> = ({
|
|||
<TypedUpdateShippingMethodTranslations onCompleted={onUpdate}>
|
||||
{(updateTranslations, updateTranslationsOpts) => {
|
||||
const handleSubmit = (
|
||||
field: TranslationInputFieldName,
|
||||
{ name: fieldName }: TranslationField<TranslationInputFieldName>,
|
||||
data: string
|
||||
) => {
|
||||
updateTranslations({
|
||||
variables: {
|
||||
id,
|
||||
input: getParsedTranslationInputData({ fieldName: field, data }),
|
||||
input: getParsedTranslationInputData({ fieldName, data }),
|
||||
language: languageCode
|
||||
}
|
||||
});
|
||||
|
|
|
@ -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<TranslationsVouchersProps> = ({
|
|||
return (
|
||||
<TypedUpdateVoucherTranslations onCompleted={onUpdate}>
|
||||
{(updateTranslations, updateTranslationsOpts) => {
|
||||
const handleSubmit = (field: string, data: string) => {
|
||||
const input: NameTranslationInput = {};
|
||||
if (field === fieldNames.name) {
|
||||
input.name = data;
|
||||
}
|
||||
const handleSubmit = (
|
||||
{ name: fieldName }: TranslationField<TranslationInputFieldName>,
|
||||
data: string
|
||||
) => {
|
||||
updateTranslations({
|
||||
variables: {
|
||||
id,
|
||||
input,
|
||||
input: getParsedTranslationInputData({
|
||||
data,
|
||||
fieldName
|
||||
}),
|
||||
language: languageCode
|
||||
}
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue