Use react-intl

This commit is contained in:
Dominik Żegleń 2019-08-16 21:32:42 +02:00 committed by dominik-zeglen
parent fe57528820
commit 77da4694ac
13 changed files with 655 additions and 486 deletions

View file

@ -1,10 +1,6 @@
import {
createStyles,
Theme,
withStyles,
WithStyles
} from "@material-ui/core/styles";
import { Theme } from "@material-ui/core/styles";
import TextField from "@material-ui/core/TextField";
import makeStyles from "@material-ui/styles/makeStyles";
import React from "react";
import Button from "@material-ui/core/Button";
@ -15,12 +11,12 @@ import Hr from "@saleor/components/Hr";
import ImageTile from "@saleor/components/ImageTile";
import ImageUpload from "@saleor/components/ImageUpload";
import Skeleton from "@saleor/components/Skeleton";
import i18n from "../../../i18n";
import { commonMessages } from "@saleor/intl";
import { FormattedMessage, useIntl } from "react-intl";
import { CategoryDetails_category_backgroundImage } from "../../types/CategoryDetails";
import { FormData } from "../CategoryUpdatePage";
const styles = (theme: Theme) =>
createStyles({
const useStyles = makeStyles((theme: Theme) => ({
fileField: {
display: "none"
},
@ -41,9 +37,9 @@ const styles = (theme: Theme) =>
position: "relative",
width: 148
}
});
}));
export interface CategoryBackgroundProps extends WithStyles<typeof styles> {
export interface CategoryBackgroundProps {
data: FormData;
image: CategoryDetails_category_backgroundImage;
onChange: (event: React.ChangeEvent<any>) => void;
@ -51,43 +47,38 @@ export interface CategoryBackgroundProps extends WithStyles<typeof styles> {
onImageUpload: (file: File) => void;
}
export const CategoryBackground = withStyles(styles)(
class CategoryBackgroundComponent extends React.Component<
CategoryBackgroundProps,
{}
> {
imgInputAnchor = React.createRef<HTMLInputElement>();
const CategoryBackground: React.FC<CategoryBackgroundProps> = props => {
const classes = useStyles(props);
const intl = useIntl();
const anchor = React.useRef<HTMLInputElement>();
clickImgInput = () => this.imgInputAnchor.current.click();
const { data, onImageUpload, image, onChange, onImageDelete } = props;
const handleImageUploadButtonClick = () => anchor.current.click();
render() {
const {
classes,
data,
onImageUpload,
image,
onChange,
onImageDelete
} = this.props;
return (
<Card>
<CardTitle
title={i18n.t("Background image (optional)")}
title={intl.formatMessage({
defaultMessage: "Background image (optional)",
description: "section header",
id: "categoryBackgroundHeader"
})}
toolbar={
<>
<Button
variant="text"
color="primary"
onClick={this.clickImgInput}
onClick={handleImageUploadButtonClick}
>
{i18n.t("Upload image")}
<FormattedMessage {...commonMessages.uploadImage} />
</Button>
<input
className={classes.fileField}
id="fileUpload"
onChange={event => onImageUpload(event.target.files[0])}
type="file"
ref={this.imgInputAnchor}
ref={anchor}
/>
</>
}
@ -114,8 +105,8 @@ export const CategoryBackground = withStyles(styles)(
<CardContent>
<TextField
name="backgroundImageAlt"
label={i18n.t("Description")}
helperText={i18n.t("Optional")}
label={intl.formatMessage(commonMessages.description)}
helperText={intl.formatMessage(commonMessages.optionalField)}
value={data.backgroundImageAlt}
onChange={onChange}
fullWidth
@ -126,8 +117,6 @@ export const CategoryBackground = withStyles(styles)(
)}
</Card>
);
}
}
);
};
CategoryBackground.displayName = "CategoryBackground";
export default CategoryBackground;

View file

@ -1,5 +1,6 @@
import { ContentState, convertToRaw, RawDraftContentState } from "draft-js";
import React from "react";
import { useIntl } from "react-intl";
import AppHeader from "@saleor/components/AppHeader";
import { CardSpacer } from "@saleor/components/CardSpacer";
@ -9,7 +10,7 @@ import Form from "@saleor/components/Form";
import PageHeader from "@saleor/components/PageHeader";
import SaveButtonBar from "@saleor/components/SaveButtonBar";
import SeoForm from "@saleor/components/SeoForm";
import i18n from "../../../i18n";
import { commonMessages, sectionNames } from "@saleor/intl";
import { UserError } from "../../../types";
import CategoryDetailsForm from "../../components/CategoryDetailsForm";
@ -43,7 +44,9 @@ export const CategoryCreatePage: React.StatelessComponent<
onBack,
errors: userErrors,
saveButtonBarState
}) => (
}) => {
const intl = useIntl();
return (
<Form
onSubmit={onSubmit}
initial={initialData}
@ -52,8 +55,16 @@ export const CategoryCreatePage: React.StatelessComponent<
>
{({ data, change, errors, submit, hasChanged }) => (
<Container>
<AppHeader onBack={onBack}>{i18n.t("Categories")}</AppHeader>
<PageHeader title={i18n.t("Add Category")} />
<AppHeader onBack={onBack}>
{intl.formatMessage(sectionNames.categories)}
</AppHeader>
<PageHeader
title={intl.formatMessage({
defaultMessage: "Create New Category",
description: "page header",
id: "categoryCreatePageHeader"
})}
/>
<div>
<CategoryDetailsForm
disabled={disabled}
@ -63,9 +74,11 @@ export const CategoryCreatePage: React.StatelessComponent<
/>
<CardSpacer />
<SeoForm
helperText={i18n.t(
"Add search engine title and description to make this product easier to find"
)}
helperText={intl.formatMessage({
defaultMessage:
"Add search engine title and description to make this category easier to find",
id: "categoryCreatePageSeo"
})}
title={data.seoTitle}
titlePlaceholder={data.name}
description={data.seoDescription}
@ -77,9 +90,6 @@ export const CategoryCreatePage: React.StatelessComponent<
<SaveButtonBar
onCancel={onBack}
onSave={submit}
labels={{
save: i18n.t("Save category")
}}
state={saveButtonBarState}
disabled={disabled || !hasChanged}
/>
@ -88,5 +98,6 @@ export const CategoryCreatePage: React.StatelessComponent<
)}
</Form>
);
};
CategoryCreatePage.displayName = "CategoryCreatePage";
export default CategoryCreatePage;

View file

@ -11,8 +11,9 @@ import {
WithStyles
} from "@material-ui/core/styles";
import React from "react";
import { FormattedMessage } from "react-intl";
import i18n from "../../../i18n";
import { commonMessages } from "@saleor/intl";
const styles = (theme: Theme) =>
createStyles({
@ -36,27 +37,35 @@ const CategoryDeleteDialog = withStyles(styles, {
name: "CategoryDeleteDialog"
})(({ classes, name, open, onConfirm, onClose }: CategoryDeleteDialogProps) => (
<Dialog onClose={onClose} open={open}>
<DialogTitle>{i18n.t("Delete category", { context: "title" })}</DialogTitle>
<DialogTitle>
<FormattedMessage
defaultMessage="Delete category"
description="dialog title"
id="categoryDeleteDialogTitle"
/>
</DialogTitle>
<DialogContent>
<DialogContentText
dangerouslySetInnerHTML={{
__html: i18n.t(
"Are you sure you want to remove <strong>{{name}}</strong>?",
{ name }
)
<DialogContentText>
<FormattedMessage
defaultMessage="Are you sure you want to remove {name}?"
description="delete category"
id="<categoryDeleteDialogContent<"
values={{
name: <strong>{name}</strong>
}}
/>
</DialogContentText>
</DialogContent>
<DialogActions>
<Button onClick={onClose}>
{i18n.t("Cancel", { context: "button" })}
<FormattedMessage {...commonMessages.cancel} />
</Button>
<Button
className={classes.deleteButton}
variant="contained"
onClick={onConfirm}
>
{i18n.t("Delete category", { context: "button" })}
<FormattedMessage {...commonMessages.save} />
</Button>
</DialogActions>
</Dialog>

View file

@ -4,11 +4,12 @@ import { createStyles, withStyles, WithStyles } from "@material-ui/core/styles";
import TextField from "@material-ui/core/TextField";
import { RawDraftContentState } from "draft-js";
import React from "react";
import { useIntl } from "react-intl";
import CardTitle from "@saleor/components/CardTitle";
import FormSpacer from "@saleor/components/FormSpacer";
import RichTextEditor from "@saleor/components/RichTextEditor";
import i18n from "../../../i18n";
import { commonMessages } from "@saleor/intl";
import { maybe } from "../../../misc";
import { CategoryDetails_category } from "../../types/CategoryDetails";
@ -40,15 +41,23 @@ export const CategoryDetailsForm = withStyles(styles, {
onChange,
errors
}: CategoryDetailsFormProps) => {
const intl = useIntl();
return (
<Card>
<CardTitle title={i18n.t("General information")} />
<CardTitle
title={intl.formatMessage(commonMessages.generalInformations)}
/>
<CardContent>
<>
<div>
<TextField
classes={{ root: classes.root }}
label={i18n.t("Name")}
label={intl.formatMessage({
defaultMessage: "Name",
description: "category name",
id: "categoryDetailsFormNameInputLabel"
})}
name="name"
disabled={disabled}
value={data && data.name}
@ -62,7 +71,7 @@ export const CategoryDetailsForm = withStyles(styles, {
disabled={disabled}
error={!!errors.descriptionJson}
helperText={errors.descriptionJson}
label={i18n.t("Description")}
label={intl.formatMessage(commonMessages.description)}
initial={maybe(() => JSON.parse(category.descriptionJson))}
name="description"
onChange={onChange}

View file

@ -12,13 +12,13 @@ import TableCell from "@material-ui/core/TableCell";
import TableFooter from "@material-ui/core/TableFooter";
import TableRow from "@material-ui/core/TableRow";
import React from "react";
import { FormattedMessage, useIntl } from "react-intl";
import CardTitle from "@saleor/components/CardTitle";
import Checkbox from "@saleor/components/Checkbox";
import Skeleton from "@saleor/components/Skeleton";
import TableHead from "@saleor/components/TableHead";
import TablePagination from "@saleor/components/TablePagination";
import i18n from "@saleor/i18n";
import { renderCollection } from "@saleor/misc";
import { ListActions, ListProps } from "@saleor/types";
@ -87,14 +87,25 @@ const CategoryList = withStyles(styles, { name: "CategoryList" })(
onPreviousPage,
onUpdateListSettings,
onRowClick
}: CategoryListProps) => (
}: CategoryListProps) => {
const intl = useIntl();
return (
<Card>
{!isRoot && (
<CardTitle
title={i18n.t("All Subcategories")}
title={intl.formatMessage({
defaultMessage: "All Subcategories",
description: "section header",
id: "categoryListSubcategoriesSectionHeader"
})}
toolbar={
<Button color="primary" variant="text" onClick={onAdd}>
{i18n.t("Add subcategory")}
<FormattedMessage
defaultMessage="Add subcategory"
description="button"
id="categoryListAddSubcategoryButton"
/>
</Button>
}
/>
@ -109,13 +120,25 @@ const CategoryList = withStyles(styles, { name: "CategoryList" })(
toolbar={toolbar}
>
<TableCell className={classes.colName}>
{i18n.t("Category Name", { context: "object" })}
<FormattedMessage
defaultMessage="Category Name"
description="category list: name column header"
id="categoryListNameColumnHeader"
/>
</TableCell>
<TableCell className={classes.colSubcategories}>
{i18n.t("Subcategories", { context: "object" })}
<FormattedMessage
defaultMessage="Subcategories"
description="category list: subcategories column header"
id="categoryListSubcategoriesColumnHeader"
/>
</TableCell>
<TableCell className={classes.colProducts}>
{i18n.t("No. Products", { context: "object" }).replace(" ", "\xa0")}
<FormattedMessage
defaultMessage="No. Products"
description="category list: number of products column header"
id="categoryListNumberOfProductsColumnHeader"
/>
</TableCell>
</TableHead>
<TableFooter>
@ -123,7 +146,9 @@ const CategoryList = withStyles(styles, { name: "CategoryList" })(
<TablePagination
colSpan={numberOfColumns}
settings={settings}
hasNextPage={pageInfo && !disabled ? pageInfo.hasNextPage : false}
hasNextPage={
pageInfo && !disabled ? pageInfo.hasNextPage : false
}
onNextPage={onNextPage}
onUpdateListSettings={onUpdateListSettings}
hasPreviousPage={
@ -182,9 +207,17 @@ const CategoryList = withStyles(styles, { name: "CategoryList" })(
() => (
<TableRow>
<TableCell colSpan={numberOfColumns}>
{isRoot
? i18n.t("No categories found")
: i18n.t("No subcategories found")}
{isRoot ? (
<FormattedMessage
defaultMessage="No categories found"
id="categoryListNoCategories"
/>
) : (
<FormattedMessage
defaultMessage="No subcategories found"
id="categoryListNoSubcategories"
/>
)}
</TableCell>
</TableRow>
)
@ -192,7 +225,8 @@ const CategoryList = withStyles(styles, { name: "CategoryList" })(
</TableBody>
</Table>
</Card>
)
);
}
);
CategoryList.displayName = "CategoryList";
export default CategoryList;

View file

@ -1,10 +1,11 @@
import Button from "@material-ui/core/Button";
import AddIcon from "@material-ui/icons/Add";
import React from "react";
import { FormattedMessage, useIntl } from "react-intl";
import Container from "@saleor/components/Container";
import PageHeader from "@saleor/components/PageHeader";
import i18n from "@saleor/i18n";
import { sectionNames } from "@saleor/intl";
import { ListActions, PageListProps } from "@saleor/types";
import CategoryList from "../CategoryList";
@ -36,11 +37,18 @@ export const CategoryListPage: React.StatelessComponent<CategoryTableProps> = ({
toggle,
toggleAll,
toolbar
}) => (
}) => {
const intl = useIntl();
return (
<Container>
<PageHeader title={i18n.t("Categories")}>
<PageHeader title={intl.formatMessage(sectionNames.categories)}>
<Button color="primary" variant="contained" onClick={onAdd}>
{i18n.t("Add category")} <AddIcon />
<FormattedMessage
defaultMessage="Add category"
description="button"
id="categoryListPageAddCategoryButton"
/>
<AddIcon />
</Button>
</PageHeader>
<CategoryList
@ -62,5 +70,6 @@ export const CategoryListPage: React.StatelessComponent<CategoryTableProps> = ({
/>
</Container>
);
};
CategoryListPage.displayName = "CategoryListPage";
export default CategoryListPage;

View file

@ -13,13 +13,13 @@ import TableFooter from "@material-ui/core/TableFooter";
import TableHead from "@material-ui/core/TableHead";
import TableRow from "@material-ui/core/TableRow";
import React from "react";
import { FormattedMessage, useIntl } from "react-intl";
import CardTitle from "@saleor/components/CardTitle";
import Skeleton from "@saleor/components/Skeleton";
import TableCellAvatar from "@saleor/components/TableCellAvatar";
import TablePagination from "@saleor/components/TablePagination";
import i18n from "../../../i18n";
import { maybe, renderCollection } from "../../../misc";
import { maybe, renderCollection } from "@saleor/misc";
const styles = (theme: Theme) =>
createStyles({
@ -61,13 +61,24 @@ export const ProductList = withStyles(styles, { name: "ProductList" })(
onNextPage,
onPreviousPage,
onRowClick
}: ProductListProps) => (
}: ProductListProps) => {
const intl = useIntl();
return (
<Card>
<CardTitle
title={i18n.t("Products")}
title={intl.formatMessage({
defaultMessage: "Products",
description: "section header",
id: "categoryProductsHeader"
})}
toolbar={
<Button variant="text" color="primary" onClick={onAddProduct}>
{i18n.t("Add product")}
<FormattedMessage
defaultMessage="Add product"
description="button"
id="categoryProductsAddProductButton"
/>
</Button>
}
/>
@ -76,9 +87,19 @@ export const ProductList = withStyles(styles, { name: "ProductList" })(
<TableRow>
{(products === undefined || products.length > 0) && <TableCell />}
<TableCell className={classes.textLeft}>
{i18n.t("Name", { context: "object" })}
<FormattedMessage
defaultMessage="Name"
description="product list: product name column header"
id="categoryProductsNameHeader"
/>
</TableCell>
<TableCell>
<FormattedMessage
defaultMessage="Type"
description="product list: product type column header"
id="categoryProductsTypeHeader"
/>
</TableCell>
<TableCell>{i18n.t("Type", { context: "object" })}</TableCell>
</TableRow>
</TableHead>
<TableFooter>
@ -123,14 +144,20 @@ export const ProductList = withStyles(styles, { name: "ProductList" })(
),
() => (
<TableRow>
<TableCell colSpan={3}>{i18n.t("No products found")}</TableCell>
<TableCell colSpan={3}>
<FormattedMessage
defaultMessage="No products found"
id="categoryProductsNoProducts"
/>
</TableCell>
</TableRow>
)
)}
</TableBody>
</Table>
</Card>
)
);
}
);
ProductList.displayName = "CategoryProductList";
export default ProductList;

View file

@ -1,10 +1,10 @@
import Button from "@material-ui/core/Button";
import Card from "@material-ui/core/Card";
import React from "react";
import { FormattedMessage, useIntl } from "react-intl";
import CardTitle from "@saleor/components/CardTitle";
import ProductList from "@saleor/components/ProductList";
import i18n from "../../../i18n";
import { ListActions, PageListProps } from "../../../types";
import { CategoryDetails_category_products_edges_node } from "../../types/CategoryDetails";
@ -29,13 +29,28 @@ export const CategoryProductsCard: React.StatelessComponent<
toggle,
toggleAll,
toolbar
}) => (
}) => {
const intl = useIntl();
return (
<Card>
<CardTitle
title={i18n.t("Products in {{ categoryName }}", { categoryName })}
title={intl.formatMessage(
{
defaultMessage: "Products in {name}",
description: "products in category section header",
id: "categoryProductsCardHeader"
},
{
name: categoryName
}
)}
toolbar={
<Button color="primary" variant="text" onClick={onAdd}>
{i18n.t("Add product")}
<FormattedMessage
defaultMessage="Add product"
description="button"
id="categoryProductsCardAddProductButton"
/>
</Button>
}
/>
@ -58,6 +73,7 @@ export const CategoryProductsCard: React.StatelessComponent<
/>
</Card>
);
};
CategoryProductsCard.displayName = "CategoryProductsCard";
export default CategoryProductsCard;

View file

@ -1,5 +1,6 @@
import { RawDraftContentState } from "draft-js";
import React from "react";
import { useIntl, FormattedMessage } from "react-intl";
import AppHeader from "@saleor/components/AppHeader";
import { CardSpacer } from "@saleor/components/CardSpacer";
@ -10,7 +11,6 @@ import PageHeader from "@saleor/components/PageHeader";
import SaveButtonBar from "@saleor/components/SaveButtonBar";
import SeoForm from "@saleor/components/SeoForm";
import { Tab, TabContainer } from "@saleor/components/Tab";
import i18n from "../../../i18n";
import { maybe } from "../../../misc";
import { TabListActions, UserError } from "../../../types";
import CategoryDetailsForm from "../../components/CategoryDetailsForm";
@ -96,6 +96,7 @@ export const CategoryUpdatePage: React.StatelessComponent<
toggle,
toggleAll
}: CategoryUpdatePageProps) => {
const intl = useIntl();
const initialData: FormData = category
? {
backgroundImageAlt: maybe(() => category.backgroundImage.alt, ""),
@ -139,9 +140,11 @@ export const CategoryUpdatePage: React.StatelessComponent<
/>
<CardSpacer />
<SeoForm
helperText={i18n.t(
"Add search engine title and description to make this category easier to find"
)}
helperText={intl.formatMessage({
defaultMessage:
"Add search engine title and description to make this category easier to find",
id: "categoryUpdatePageSeo"
})}
title={data.seoTitle}
titlePlaceholder={data.name}
description={data.seoDescription}
@ -156,13 +159,21 @@ export const CategoryUpdatePage: React.StatelessComponent<
isActive={currentTab === CategoryPageTab.categories}
changeTab={changeTab}
>
{i18n.t("Subcategories")}
<FormattedMessage
defaultMessage="Subcategories"
description="category list: number of subcategories column header"
id="categoryUpdatePageSubcategoriesColumnHeader"
/>
</CategoriesTab>
<ProductsTab
isActive={currentTab === CategoryPageTab.products}
changeTab={changeTab}
>
{i18n.t("Products")}
<FormattedMessage
defaultMessage="Products"
description="category list: number of products column header"
id="categoryUpdatePageProductsColumnHeader"
/>
</ProductsTab>
</TabContainer>
<CardSpacer />
@ -204,9 +215,6 @@ export const CategoryUpdatePage: React.StatelessComponent<
onCancel={onBack}
onDelete={onDelete}
onSave={submit}
labels={{
delete: i18n.t("Delete category")
}}
state={saveButtonBarState}
disabled={disabled || !hasChanged}
/>

View file

@ -1,9 +1,9 @@
import React from "react";
import { useIntl } from "react-intl";
import { WindowTitle } from "@saleor/components/WindowTitle";
import useNavigator from "@saleor/hooks/useNavigator";
import useNotifier from "@saleor/hooks/useNotifier";
import i18n from "../../i18n";
import { getMutationState, maybe } from "../../misc";
import CategoryCreatePage from "../components/CategoryCreatePage";
import { TypedCategoryCreateMutation } from "../mutations";
@ -19,10 +19,16 @@ export const CategoryCreateView: React.StatelessComponent<
> = ({ parentId }) => {
const navigate = useNavigator();
const notify = useNotifier();
const intl = useIntl();
const handleSuccess = (data: CategoryCreate) => {
if (data.categoryCreate.errors.length === 0) {
notify({ text: i18n.t("Category created") });
notify({
text: intl.formatMessage({
defaultMessage: "Category created",
id: "categoryCreateCategoryCreated"
})
});
navigate(categoryUrl(data.categoryCreate.category.id));
}
};
@ -42,7 +48,13 @@ export const CategoryCreateView: React.StatelessComponent<
return (
<>
<WindowTitle title={i18n.t("Create category")} />
<WindowTitle
title={intl.formatMessage({
defaultMessage: "Create category",
description: "window title",
id: "categoryCreateWindowTitle"
})}
/>
<CategoryCreatePage
saveButtonBarState={formTransitionState}
errors={errors}

View file

@ -2,6 +2,7 @@ import DialogContentText from "@material-ui/core/DialogContentText";
import IconButton from "@material-ui/core/IconButton";
import DeleteIcon from "@material-ui/icons/Delete";
import React from "react";
import { FormattedMessage, useIntl } from "react-intl";
import ActionDialog from "@saleor/components/ActionDialog";
import { WindowTitle } from "@saleor/components/WindowTitle";
@ -12,7 +13,6 @@ import usePaginator, {
createPaginationState
} from "@saleor/hooks/usePaginator";
import { PAGINATE_BY } from "../../config";
import i18n from "../../i18n";
import { getMutationState, maybe } from "../../misc";
import { TypedProductBulkDeleteMutation } from "../../products/mutations";
import { productBulkDelete } from "../../products/types/productBulkDelete";
@ -59,12 +59,14 @@ export const CategoryDetails: React.StatelessComponent<
const { isSelected, listElements, reset, toggle, toggleAll } = useBulkActions(
params.ids
);
const intl = useIntl();
const handleCategoryDelete = (data: CategoryDelete) => {
if (data.categoryDelete.errors.length === 0) {
notify({
text: i18n.t("Category deleted", {
context: "notification"
text: intl.formatMessage({
defaultMessage: "Category deleted",
id: "categoryDetailsCategoryDeleted"
})
});
navigate(categoryListUrl());
@ -140,7 +142,10 @@ export const CategoryDetails: React.StatelessComponent<
if (data.categoryBulkDelete.errors.length === 0) {
closeModal();
notify({
text: i18n.t("Categories removed")
text: intl.formatMessage({
defaultMessage: "Categories removed",
id: "categoryDetailsCategoriesRemoved"
})
});
refetch();
reset();
@ -151,7 +156,10 @@ export const CategoryDetails: React.StatelessComponent<
if (data.productBulkDelete.errors.length === 0) {
closeModal();
notify({
text: i18n.t("Products removed")
text: intl.formatMessage({
defaultMessage: "Products removed",
id: "categoryDetailsProductsRemoved"
})
});
refetch();
reset();
@ -319,32 +327,43 @@ export const CategoryDetails: React.StatelessComponent<
deleteCategory({ variables: { id } })
}
open={params.action === "delete"}
title={i18n.t("Delete category", {
context: "modal title"
title={intl.formatMessage({
defaultMessage: "Delete category",
description: "dialog title",
id:
"categoryDetailsDeleteCategoryDialogTitle"
})}
variant="delete"
>
<DialogContentText
dangerouslySetInnerHTML={{
__html: i18n.t(
"Are you sure you want to remove <strong>{{ categoryName }}</strong>? <br /> ",
{
categoryName: maybe(
() => data.category.name
),
context: "modal message"
}
<DialogContentText>
<FormattedMessage
defaultMessage="Are you sure you want to remove {name}?"
description="remove category"
id="categoryDetailsDeleteCategoryDialogContent"
values={{
name: (
<strong>
{maybe(
() => data.category.name,
"..."
)}
</strong>
)
}}
/>
</DialogContentText>
<DialogContentText>
{i18n.t(
"Remember that this will also remove all products assigned to this category."
)}
<FormattedMessage
defaultMessage="Remember that this will also remove all products assigned to this category."
id="categoryDetailsDeleteCategoryDialogContentAdditionalText"
/>
</DialogContentText>
</ActionDialog>
<ActionDialog
open={params.action === "delete-categories"}
open={
params.action === "delete-categories" &&
maybe(() => params.ids.length > 0)
}
confirmButtonState={
categoryBulkDeleteMutationState
}
@ -354,27 +373,30 @@ export const CategoryDetails: React.StatelessComponent<
variables: { ids: params.ids }
})
}
title={i18n.t("Remove categories")}
title={intl.formatMessage({
defaultMessage: "Remove categories",
description: "dialog title",
id:
"categoryDetailsDeleteSubcategoriesDialogTitle"
})}
variant="delete"
>
<DialogContentText
dangerouslySetInnerHTML={{
__html: i18n.t(
"Are you sure you want to remove <strong>{{ number }}</strong> categories?",
{
number: maybe(
() =>
params.ids.length.toString(),
"..."
)
}
<DialogContentText>
<FormattedMessage
defaultMessage="Are you sure you want to remove {number} categories?"
id="categoryDetailsDeleteCategoriesDialogContent"
values={{
number: (
<strong>{params.ids.length}</strong>
)
}}
/>
</DialogContentText>
<DialogContentText>
{i18n.t(
"Remember that this will also remove all products assigned to this category."
)}
<FormattedMessage
defaultMessage="Remember that this will also remove all products assigned to this category."
id="categoryDetailsDeleteCategoriesDialogContentAdditionalText"
/>
</DialogContentText>
</ActionDialog>
<ActionDialog
@ -388,23 +410,26 @@ export const CategoryDetails: React.StatelessComponent<
variables: { ids: params.ids }
})
}
title={i18n.t("Remove products")}
title={intl.formatMessage({
defaultMessage: "Remove products",
description: "dialog title",
id:
"categoryDetailsDeleteProductsDialogTitle"
})}
variant="delete"
>
<DialogContentText
dangerouslySetInnerHTML={{
__html: i18n.t(
"Are you sure you want to remove <strong>{{ number }}</strong> products?",
{
number: maybe(
() =>
params.ids.length.toString(),
"..."
)
}
{" "}
<DialogContentText>
<FormattedMessage
defaultMessage="Are you sure you want to remove {number} products?"
id="categoryDetailsDeleteProductsDialogContent"
values={{
number: (
<strong>{params.ids.length}</strong>
)
}}
/>
</DialogContentText>
</ActionDialog>
</>
);

View file

@ -2,6 +2,7 @@ import DialogContentText from "@material-ui/core/DialogContentText";
import IconButton from "@material-ui/core/IconButton";
import DeleteIcon from "@material-ui/icons/Delete";
import React from "react";
import { FormattedMessage, useIntl } from "react-intl";
import ActionDialog from "@saleor/components/ActionDialog";
import useBulkActions from "@saleor/hooks/useBulkActions";
@ -10,7 +11,6 @@ import useNavigator from "@saleor/hooks/useNavigator";
import usePaginator, {
createPaginationState
} from "@saleor/hooks/usePaginator";
import i18n from "@saleor/i18n";
import { getMutationState, maybe } from "@saleor/misc";
import { ListViews } from "@saleor/types";
import { CategoryListPage } from "../components/CategoryListPage/CategoryListPage";
@ -39,6 +39,8 @@ export const CategoryList: React.StatelessComponent<CategoryListProps> = ({
const { updateListSettings, settings } = useListSettings(
ListViews.CATEGORY_LIST
);
const intl = useIntl();
const paginationState = createPaginationState(settings.rowNumber, params);
return (
<TypedRootCategoriesQuery displayLoader variables={paginationState}>
@ -124,26 +126,25 @@ export const CategoryList: React.StatelessComponent<CategoryListProps> = ({
})
}
open={params.action === "delete"}
title={i18n.t("Remove categories")}
title={intl.formatMessage({
defaultMessage: "Remove categories",
description: "dialog title",
id: "categoryListDeleteSubcategoriesDialogTitle"
})}
variant="delete"
>
<DialogContentText
dangerouslySetInnerHTML={{
__html: i18n.t(
"Are you sure you want to remove <strong>{{ number }}</strong> categories?",
{
number: maybe(
() => params.ids.length.toString(),
"..."
)
}
)
<FormattedMessage
defaultMessage="Are you sure you want to remove {number} categories?"
id="categoryListDeleteCategoriesDialogContent"
values={{
number: <strong>{params.ids.length}</strong>
}}
/>
<DialogContentText>
{i18n.t(
"Remember that this will also remove all products assigned to this category."
)}
<FormattedMessage
defaultMessage="Remember that this will also remove all products assigned to this category."
id="categoryListDeleteCategoriesDialogContentAdditionalText"
/>
</DialogContentText>
</ActionDialog>
</>

View file

@ -9,10 +9,19 @@ export const commonMessages = defineMessages({
defaultMessage: "Confirm",
id: "confirm"
},
description: {
defaultMessage: "Description",
id: "description"
},
generalInformations: {
defaultMessage: "General Informations",
id: "generalInformations"
},
optionalField: {
defaultMessage: "Optional",
description: "field is optional",
id: "optionalField"
},
properties: {
defaultMessage: "Properties",
id: "properties"
@ -24,6 +33,11 @@ export const commonMessages = defineMessages({
savedChanges: {
defaultMessage: "Saved changes",
id: "savedChanges"
},
uploadImage: {
defaultMessage: "Upload image",
description: "button",
id: "uploadImage"
}
});
@ -32,5 +46,10 @@ export const sectionNames = defineMessages({
defaultMessage: "Attributes",
description: "attributes section name",
id: "attributes"
},
categories: {
defaultMessage: "Categories",
description: "categories section name",
id: "categories"
}
});