Use react-intl
This commit is contained in:
parent
fe57528820
commit
77da4694ac
13 changed files with 655 additions and 486 deletions
|
@ -1,10 +1,6 @@
|
||||||
import {
|
import { Theme } from "@material-ui/core/styles";
|
||||||
createStyles,
|
|
||||||
Theme,
|
|
||||||
withStyles,
|
|
||||||
WithStyles
|
|
||||||
} from "@material-ui/core/styles";
|
|
||||||
import TextField from "@material-ui/core/TextField";
|
import TextField from "@material-ui/core/TextField";
|
||||||
|
import makeStyles from "@material-ui/styles/makeStyles";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
import Button from "@material-ui/core/Button";
|
import Button from "@material-ui/core/Button";
|
||||||
|
@ -15,12 +11,12 @@ import Hr from "@saleor/components/Hr";
|
||||||
import ImageTile from "@saleor/components/ImageTile";
|
import ImageTile from "@saleor/components/ImageTile";
|
||||||
import ImageUpload from "@saleor/components/ImageUpload";
|
import ImageUpload from "@saleor/components/ImageUpload";
|
||||||
import Skeleton from "@saleor/components/Skeleton";
|
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 { CategoryDetails_category_backgroundImage } from "../../types/CategoryDetails";
|
||||||
import { FormData } from "../CategoryUpdatePage";
|
import { FormData } from "../CategoryUpdatePage";
|
||||||
|
|
||||||
const styles = (theme: Theme) =>
|
const useStyles = makeStyles((theme: Theme) => ({
|
||||||
createStyles({
|
|
||||||
fileField: {
|
fileField: {
|
||||||
display: "none"
|
display: "none"
|
||||||
},
|
},
|
||||||
|
@ -41,9 +37,9 @@ const styles = (theme: Theme) =>
|
||||||
position: "relative",
|
position: "relative",
|
||||||
width: 148
|
width: 148
|
||||||
}
|
}
|
||||||
});
|
}));
|
||||||
|
|
||||||
export interface CategoryBackgroundProps extends WithStyles<typeof styles> {
|
export interface CategoryBackgroundProps {
|
||||||
data: FormData;
|
data: FormData;
|
||||||
image: CategoryDetails_category_backgroundImage;
|
image: CategoryDetails_category_backgroundImage;
|
||||||
onChange: (event: React.ChangeEvent<any>) => void;
|
onChange: (event: React.ChangeEvent<any>) => void;
|
||||||
|
@ -51,43 +47,38 @@ export interface CategoryBackgroundProps extends WithStyles<typeof styles> {
|
||||||
onImageUpload: (file: File) => void;
|
onImageUpload: (file: File) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const CategoryBackground = withStyles(styles)(
|
const CategoryBackground: React.FC<CategoryBackgroundProps> = props => {
|
||||||
class CategoryBackgroundComponent extends React.Component<
|
const classes = useStyles(props);
|
||||||
CategoryBackgroundProps,
|
const intl = useIntl();
|
||||||
{}
|
const anchor = React.useRef<HTMLInputElement>();
|
||||||
> {
|
|
||||||
imgInputAnchor = React.createRef<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 (
|
return (
|
||||||
<Card>
|
<Card>
|
||||||
<CardTitle
|
<CardTitle
|
||||||
title={i18n.t("Background image (optional)")}
|
title={intl.formatMessage({
|
||||||
|
defaultMessage: "Background image (optional)",
|
||||||
|
description: "section header",
|
||||||
|
id: "categoryBackgroundHeader"
|
||||||
|
})}
|
||||||
toolbar={
|
toolbar={
|
||||||
<>
|
<>
|
||||||
<Button
|
<Button
|
||||||
variant="text"
|
variant="text"
|
||||||
color="primary"
|
color="primary"
|
||||||
onClick={this.clickImgInput}
|
onClick={handleImageUploadButtonClick}
|
||||||
>
|
>
|
||||||
{i18n.t("Upload image")}
|
<FormattedMessage {...commonMessages.uploadImage} />
|
||||||
</Button>
|
</Button>
|
||||||
<input
|
<input
|
||||||
className={classes.fileField}
|
className={classes.fileField}
|
||||||
id="fileUpload"
|
id="fileUpload"
|
||||||
onChange={event => onImageUpload(event.target.files[0])}
|
onChange={event => onImageUpload(event.target.files[0])}
|
||||||
type="file"
|
type="file"
|
||||||
ref={this.imgInputAnchor}
|
ref={anchor}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
|
@ -114,8 +105,8 @@ export const CategoryBackground = withStyles(styles)(
|
||||||
<CardContent>
|
<CardContent>
|
||||||
<TextField
|
<TextField
|
||||||
name="backgroundImageAlt"
|
name="backgroundImageAlt"
|
||||||
label={i18n.t("Description")}
|
label={intl.formatMessage(commonMessages.description)}
|
||||||
helperText={i18n.t("Optional")}
|
helperText={intl.formatMessage(commonMessages.optionalField)}
|
||||||
value={data.backgroundImageAlt}
|
value={data.backgroundImageAlt}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
fullWidth
|
fullWidth
|
||||||
|
@ -126,8 +117,6 @@ export const CategoryBackground = withStyles(styles)(
|
||||||
)}
|
)}
|
||||||
</Card>
|
</Card>
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
}
|
|
||||||
);
|
|
||||||
CategoryBackground.displayName = "CategoryBackground";
|
CategoryBackground.displayName = "CategoryBackground";
|
||||||
export default CategoryBackground;
|
export default CategoryBackground;
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import { ContentState, convertToRaw, RawDraftContentState } from "draft-js";
|
import { ContentState, convertToRaw, RawDraftContentState } from "draft-js";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
import { useIntl } from "react-intl";
|
||||||
|
|
||||||
import AppHeader from "@saleor/components/AppHeader";
|
import AppHeader from "@saleor/components/AppHeader";
|
||||||
import { CardSpacer } from "@saleor/components/CardSpacer";
|
import { CardSpacer } from "@saleor/components/CardSpacer";
|
||||||
|
@ -9,7 +10,7 @@ import Form from "@saleor/components/Form";
|
||||||
import PageHeader from "@saleor/components/PageHeader";
|
import PageHeader from "@saleor/components/PageHeader";
|
||||||
import SaveButtonBar from "@saleor/components/SaveButtonBar";
|
import SaveButtonBar from "@saleor/components/SaveButtonBar";
|
||||||
import SeoForm from "@saleor/components/SeoForm";
|
import SeoForm from "@saleor/components/SeoForm";
|
||||||
import i18n from "../../../i18n";
|
import { commonMessages, sectionNames } from "@saleor/intl";
|
||||||
import { UserError } from "../../../types";
|
import { UserError } from "../../../types";
|
||||||
import CategoryDetailsForm from "../../components/CategoryDetailsForm";
|
import CategoryDetailsForm from "../../components/CategoryDetailsForm";
|
||||||
|
|
||||||
|
@ -43,7 +44,9 @@ export const CategoryCreatePage: React.StatelessComponent<
|
||||||
onBack,
|
onBack,
|
||||||
errors: userErrors,
|
errors: userErrors,
|
||||||
saveButtonBarState
|
saveButtonBarState
|
||||||
}) => (
|
}) => {
|
||||||
|
const intl = useIntl();
|
||||||
|
return (
|
||||||
<Form
|
<Form
|
||||||
onSubmit={onSubmit}
|
onSubmit={onSubmit}
|
||||||
initial={initialData}
|
initial={initialData}
|
||||||
|
@ -52,8 +55,16 @@ export const CategoryCreatePage: React.StatelessComponent<
|
||||||
>
|
>
|
||||||
{({ data, change, errors, submit, hasChanged }) => (
|
{({ data, change, errors, submit, hasChanged }) => (
|
||||||
<Container>
|
<Container>
|
||||||
<AppHeader onBack={onBack}>{i18n.t("Categories")}</AppHeader>
|
<AppHeader onBack={onBack}>
|
||||||
<PageHeader title={i18n.t("Add Category")} />
|
{intl.formatMessage(sectionNames.categories)}
|
||||||
|
</AppHeader>
|
||||||
|
<PageHeader
|
||||||
|
title={intl.formatMessage({
|
||||||
|
defaultMessage: "Create New Category",
|
||||||
|
description: "page header",
|
||||||
|
id: "categoryCreatePageHeader"
|
||||||
|
})}
|
||||||
|
/>
|
||||||
<div>
|
<div>
|
||||||
<CategoryDetailsForm
|
<CategoryDetailsForm
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
|
@ -63,9 +74,11 @@ export const CategoryCreatePage: React.StatelessComponent<
|
||||||
/>
|
/>
|
||||||
<CardSpacer />
|
<CardSpacer />
|
||||||
<SeoForm
|
<SeoForm
|
||||||
helperText={i18n.t(
|
helperText={intl.formatMessage({
|
||||||
"Add search engine title and description to make this product easier to find"
|
defaultMessage:
|
||||||
)}
|
"Add search engine title and description to make this category easier to find",
|
||||||
|
id: "categoryCreatePageSeo"
|
||||||
|
})}
|
||||||
title={data.seoTitle}
|
title={data.seoTitle}
|
||||||
titlePlaceholder={data.name}
|
titlePlaceholder={data.name}
|
||||||
description={data.seoDescription}
|
description={data.seoDescription}
|
||||||
|
@ -77,9 +90,6 @@ export const CategoryCreatePage: React.StatelessComponent<
|
||||||
<SaveButtonBar
|
<SaveButtonBar
|
||||||
onCancel={onBack}
|
onCancel={onBack}
|
||||||
onSave={submit}
|
onSave={submit}
|
||||||
labels={{
|
|
||||||
save: i18n.t("Save category")
|
|
||||||
}}
|
|
||||||
state={saveButtonBarState}
|
state={saveButtonBarState}
|
||||||
disabled={disabled || !hasChanged}
|
disabled={disabled || !hasChanged}
|
||||||
/>
|
/>
|
||||||
|
@ -87,6 +97,7 @@ export const CategoryCreatePage: React.StatelessComponent<
|
||||||
</Container>
|
</Container>
|
||||||
)}
|
)}
|
||||||
</Form>
|
</Form>
|
||||||
);
|
);
|
||||||
|
};
|
||||||
CategoryCreatePage.displayName = "CategoryCreatePage";
|
CategoryCreatePage.displayName = "CategoryCreatePage";
|
||||||
export default CategoryCreatePage;
|
export default CategoryCreatePage;
|
||||||
|
|
|
@ -11,8 +11,9 @@ import {
|
||||||
WithStyles
|
WithStyles
|
||||||
} from "@material-ui/core/styles";
|
} from "@material-ui/core/styles";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
import { FormattedMessage } from "react-intl";
|
||||||
|
|
||||||
import i18n from "../../../i18n";
|
import { commonMessages } from "@saleor/intl";
|
||||||
|
|
||||||
const styles = (theme: Theme) =>
|
const styles = (theme: Theme) =>
|
||||||
createStyles({
|
createStyles({
|
||||||
|
@ -36,27 +37,35 @@ const CategoryDeleteDialog = withStyles(styles, {
|
||||||
name: "CategoryDeleteDialog"
|
name: "CategoryDeleteDialog"
|
||||||
})(({ classes, name, open, onConfirm, onClose }: CategoryDeleteDialogProps) => (
|
})(({ classes, name, open, onConfirm, onClose }: CategoryDeleteDialogProps) => (
|
||||||
<Dialog onClose={onClose} open={open}>
|
<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>
|
<DialogContent>
|
||||||
<DialogContentText
|
<DialogContentText>
|
||||||
dangerouslySetInnerHTML={{
|
<FormattedMessage
|
||||||
__html: i18n.t(
|
defaultMessage="Are you sure you want to remove {name}?"
|
||||||
"Are you sure you want to remove <strong>{{name}}</strong>?",
|
description="delete category"
|
||||||
{ name }
|
id="<categoryDeleteDialogContent<"
|
||||||
)
|
values={{
|
||||||
|
name: <strong>{name}</strong>
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
</DialogContentText>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
<DialogActions>
|
<DialogActions>
|
||||||
<Button onClick={onClose}>
|
<Button onClick={onClose}>
|
||||||
{i18n.t("Cancel", { context: "button" })}
|
<FormattedMessage {...commonMessages.cancel} />
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
className={classes.deleteButton}
|
className={classes.deleteButton}
|
||||||
variant="contained"
|
variant="contained"
|
||||||
onClick={onConfirm}
|
onClick={onConfirm}
|
||||||
>
|
>
|
||||||
{i18n.t("Delete category", { context: "button" })}
|
<FormattedMessage {...commonMessages.save} />
|
||||||
</Button>
|
</Button>
|
||||||
</DialogActions>
|
</DialogActions>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
|
|
|
@ -4,11 +4,12 @@ import { createStyles, withStyles, WithStyles } from "@material-ui/core/styles";
|
||||||
import TextField from "@material-ui/core/TextField";
|
import TextField from "@material-ui/core/TextField";
|
||||||
import { RawDraftContentState } from "draft-js";
|
import { RawDraftContentState } from "draft-js";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
import { useIntl } from "react-intl";
|
||||||
|
|
||||||
import CardTitle from "@saleor/components/CardTitle";
|
import CardTitle from "@saleor/components/CardTitle";
|
||||||
import FormSpacer from "@saleor/components/FormSpacer";
|
import FormSpacer from "@saleor/components/FormSpacer";
|
||||||
import RichTextEditor from "@saleor/components/RichTextEditor";
|
import RichTextEditor from "@saleor/components/RichTextEditor";
|
||||||
import i18n from "../../../i18n";
|
import { commonMessages } from "@saleor/intl";
|
||||||
import { maybe } from "../../../misc";
|
import { maybe } from "../../../misc";
|
||||||
import { CategoryDetails_category } from "../../types/CategoryDetails";
|
import { CategoryDetails_category } from "../../types/CategoryDetails";
|
||||||
|
|
||||||
|
@ -40,15 +41,23 @@ export const CategoryDetailsForm = withStyles(styles, {
|
||||||
onChange,
|
onChange,
|
||||||
errors
|
errors
|
||||||
}: CategoryDetailsFormProps) => {
|
}: CategoryDetailsFormProps) => {
|
||||||
|
const intl = useIntl();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card>
|
<Card>
|
||||||
<CardTitle title={i18n.t("General information")} />
|
<CardTitle
|
||||||
|
title={intl.formatMessage(commonMessages.generalInformations)}
|
||||||
|
/>
|
||||||
<CardContent>
|
<CardContent>
|
||||||
<>
|
<>
|
||||||
<div>
|
<div>
|
||||||
<TextField
|
<TextField
|
||||||
classes={{ root: classes.root }}
|
classes={{ root: classes.root }}
|
||||||
label={i18n.t("Name")}
|
label={intl.formatMessage({
|
||||||
|
defaultMessage: "Name",
|
||||||
|
description: "category name",
|
||||||
|
id: "categoryDetailsFormNameInputLabel"
|
||||||
|
})}
|
||||||
name="name"
|
name="name"
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
value={data && data.name}
|
value={data && data.name}
|
||||||
|
@ -62,7 +71,7 @@ export const CategoryDetailsForm = withStyles(styles, {
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
error={!!errors.descriptionJson}
|
error={!!errors.descriptionJson}
|
||||||
helperText={errors.descriptionJson}
|
helperText={errors.descriptionJson}
|
||||||
label={i18n.t("Description")}
|
label={intl.formatMessage(commonMessages.description)}
|
||||||
initial={maybe(() => JSON.parse(category.descriptionJson))}
|
initial={maybe(() => JSON.parse(category.descriptionJson))}
|
||||||
name="description"
|
name="description"
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
|
|
|
@ -12,13 +12,13 @@ import TableCell from "@material-ui/core/TableCell";
|
||||||
import TableFooter from "@material-ui/core/TableFooter";
|
import TableFooter from "@material-ui/core/TableFooter";
|
||||||
import TableRow from "@material-ui/core/TableRow";
|
import TableRow from "@material-ui/core/TableRow";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
import { FormattedMessage, useIntl } from "react-intl";
|
||||||
|
|
||||||
import CardTitle from "@saleor/components/CardTitle";
|
import CardTitle from "@saleor/components/CardTitle";
|
||||||
import Checkbox from "@saleor/components/Checkbox";
|
import Checkbox from "@saleor/components/Checkbox";
|
||||||
import Skeleton from "@saleor/components/Skeleton";
|
import Skeleton from "@saleor/components/Skeleton";
|
||||||
import TableHead from "@saleor/components/TableHead";
|
import TableHead from "@saleor/components/TableHead";
|
||||||
import TablePagination from "@saleor/components/TablePagination";
|
import TablePagination from "@saleor/components/TablePagination";
|
||||||
import i18n from "@saleor/i18n";
|
|
||||||
import { renderCollection } from "@saleor/misc";
|
import { renderCollection } from "@saleor/misc";
|
||||||
import { ListActions, ListProps } from "@saleor/types";
|
import { ListActions, ListProps } from "@saleor/types";
|
||||||
|
|
||||||
|
@ -87,14 +87,25 @@ const CategoryList = withStyles(styles, { name: "CategoryList" })(
|
||||||
onPreviousPage,
|
onPreviousPage,
|
||||||
onUpdateListSettings,
|
onUpdateListSettings,
|
||||||
onRowClick
|
onRowClick
|
||||||
}: CategoryListProps) => (
|
}: CategoryListProps) => {
|
||||||
|
const intl = useIntl();
|
||||||
|
|
||||||
|
return (
|
||||||
<Card>
|
<Card>
|
||||||
{!isRoot && (
|
{!isRoot && (
|
||||||
<CardTitle
|
<CardTitle
|
||||||
title={i18n.t("All Subcategories")}
|
title={intl.formatMessage({
|
||||||
|
defaultMessage: "All Subcategories",
|
||||||
|
description: "section header",
|
||||||
|
id: "categoryListSubcategoriesSectionHeader"
|
||||||
|
})}
|
||||||
toolbar={
|
toolbar={
|
||||||
<Button color="primary" variant="text" onClick={onAdd}>
|
<Button color="primary" variant="text" onClick={onAdd}>
|
||||||
{i18n.t("Add subcategory")}
|
<FormattedMessage
|
||||||
|
defaultMessage="Add subcategory"
|
||||||
|
description="button"
|
||||||
|
id="categoryListAddSubcategoryButton"
|
||||||
|
/>
|
||||||
</Button>
|
</Button>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
@ -109,13 +120,25 @@ const CategoryList = withStyles(styles, { name: "CategoryList" })(
|
||||||
toolbar={toolbar}
|
toolbar={toolbar}
|
||||||
>
|
>
|
||||||
<TableCell className={classes.colName}>
|
<TableCell className={classes.colName}>
|
||||||
{i18n.t("Category Name", { context: "object" })}
|
<FormattedMessage
|
||||||
|
defaultMessage="Category Name"
|
||||||
|
description="category list: name column header"
|
||||||
|
id="categoryListNameColumnHeader"
|
||||||
|
/>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell className={classes.colSubcategories}>
|
<TableCell className={classes.colSubcategories}>
|
||||||
{i18n.t("Subcategories", { context: "object" })}
|
<FormattedMessage
|
||||||
|
defaultMessage="Subcategories"
|
||||||
|
description="category list: subcategories column header"
|
||||||
|
id="categoryListSubcategoriesColumnHeader"
|
||||||
|
/>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell className={classes.colProducts}>
|
<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>
|
</TableCell>
|
||||||
</TableHead>
|
</TableHead>
|
||||||
<TableFooter>
|
<TableFooter>
|
||||||
|
@ -123,7 +146,9 @@ const CategoryList = withStyles(styles, { name: "CategoryList" })(
|
||||||
<TablePagination
|
<TablePagination
|
||||||
colSpan={numberOfColumns}
|
colSpan={numberOfColumns}
|
||||||
settings={settings}
|
settings={settings}
|
||||||
hasNextPage={pageInfo && !disabled ? pageInfo.hasNextPage : false}
|
hasNextPage={
|
||||||
|
pageInfo && !disabled ? pageInfo.hasNextPage : false
|
||||||
|
}
|
||||||
onNextPage={onNextPage}
|
onNextPage={onNextPage}
|
||||||
onUpdateListSettings={onUpdateListSettings}
|
onUpdateListSettings={onUpdateListSettings}
|
||||||
hasPreviousPage={
|
hasPreviousPage={
|
||||||
|
@ -182,9 +207,17 @@ const CategoryList = withStyles(styles, { name: "CategoryList" })(
|
||||||
() => (
|
() => (
|
||||||
<TableRow>
|
<TableRow>
|
||||||
<TableCell colSpan={numberOfColumns}>
|
<TableCell colSpan={numberOfColumns}>
|
||||||
{isRoot
|
{isRoot ? (
|
||||||
? i18n.t("No categories found")
|
<FormattedMessage
|
||||||
: i18n.t("No subcategories found")}
|
defaultMessage="No categories found"
|
||||||
|
id="categoryListNoCategories"
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<FormattedMessage
|
||||||
|
defaultMessage="No subcategories found"
|
||||||
|
id="categoryListNoSubcategories"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
)
|
)
|
||||||
|
@ -192,7 +225,8 @@ const CategoryList = withStyles(styles, { name: "CategoryList" })(
|
||||||
</TableBody>
|
</TableBody>
|
||||||
</Table>
|
</Table>
|
||||||
</Card>
|
</Card>
|
||||||
)
|
);
|
||||||
|
}
|
||||||
);
|
);
|
||||||
CategoryList.displayName = "CategoryList";
|
CategoryList.displayName = "CategoryList";
|
||||||
export default CategoryList;
|
export default CategoryList;
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
import Button from "@material-ui/core/Button";
|
import Button from "@material-ui/core/Button";
|
||||||
import AddIcon from "@material-ui/icons/Add";
|
import AddIcon from "@material-ui/icons/Add";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
import { FormattedMessage, useIntl } from "react-intl";
|
||||||
|
|
||||||
import Container from "@saleor/components/Container";
|
import Container from "@saleor/components/Container";
|
||||||
import PageHeader from "@saleor/components/PageHeader";
|
import PageHeader from "@saleor/components/PageHeader";
|
||||||
import i18n from "@saleor/i18n";
|
import { sectionNames } from "@saleor/intl";
|
||||||
import { ListActions, PageListProps } from "@saleor/types";
|
import { ListActions, PageListProps } from "@saleor/types";
|
||||||
import CategoryList from "../CategoryList";
|
import CategoryList from "../CategoryList";
|
||||||
|
|
||||||
|
@ -36,11 +37,18 @@ export const CategoryListPage: React.StatelessComponent<CategoryTableProps> = ({
|
||||||
toggle,
|
toggle,
|
||||||
toggleAll,
|
toggleAll,
|
||||||
toolbar
|
toolbar
|
||||||
}) => (
|
}) => {
|
||||||
|
const intl = useIntl();
|
||||||
|
return (
|
||||||
<Container>
|
<Container>
|
||||||
<PageHeader title={i18n.t("Categories")}>
|
<PageHeader title={intl.formatMessage(sectionNames.categories)}>
|
||||||
<Button color="primary" variant="contained" onClick={onAdd}>
|
<Button color="primary" variant="contained" onClick={onAdd}>
|
||||||
{i18n.t("Add category")} <AddIcon />
|
<FormattedMessage
|
||||||
|
defaultMessage="Add category"
|
||||||
|
description="button"
|
||||||
|
id="categoryListPageAddCategoryButton"
|
||||||
|
/>
|
||||||
|
<AddIcon />
|
||||||
</Button>
|
</Button>
|
||||||
</PageHeader>
|
</PageHeader>
|
||||||
<CategoryList
|
<CategoryList
|
||||||
|
@ -61,6 +69,7 @@ export const CategoryListPage: React.StatelessComponent<CategoryTableProps> = ({
|
||||||
toolbar={toolbar}
|
toolbar={toolbar}
|
||||||
/>
|
/>
|
||||||
</Container>
|
</Container>
|
||||||
);
|
);
|
||||||
|
};
|
||||||
CategoryListPage.displayName = "CategoryListPage";
|
CategoryListPage.displayName = "CategoryListPage";
|
||||||
export default CategoryListPage;
|
export default CategoryListPage;
|
||||||
|
|
|
@ -13,13 +13,13 @@ import TableFooter from "@material-ui/core/TableFooter";
|
||||||
import TableHead from "@material-ui/core/TableHead";
|
import TableHead from "@material-ui/core/TableHead";
|
||||||
import TableRow from "@material-ui/core/TableRow";
|
import TableRow from "@material-ui/core/TableRow";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
import { FormattedMessage, useIntl } from "react-intl";
|
||||||
|
|
||||||
import CardTitle from "@saleor/components/CardTitle";
|
import CardTitle from "@saleor/components/CardTitle";
|
||||||
import Skeleton from "@saleor/components/Skeleton";
|
import Skeleton from "@saleor/components/Skeleton";
|
||||||
import TableCellAvatar from "@saleor/components/TableCellAvatar";
|
import TableCellAvatar from "@saleor/components/TableCellAvatar";
|
||||||
import TablePagination from "@saleor/components/TablePagination";
|
import TablePagination from "@saleor/components/TablePagination";
|
||||||
import i18n from "../../../i18n";
|
import { maybe, renderCollection } from "@saleor/misc";
|
||||||
import { maybe, renderCollection } from "../../../misc";
|
|
||||||
|
|
||||||
const styles = (theme: Theme) =>
|
const styles = (theme: Theme) =>
|
||||||
createStyles({
|
createStyles({
|
||||||
|
@ -61,13 +61,24 @@ export const ProductList = withStyles(styles, { name: "ProductList" })(
|
||||||
onNextPage,
|
onNextPage,
|
||||||
onPreviousPage,
|
onPreviousPage,
|
||||||
onRowClick
|
onRowClick
|
||||||
}: ProductListProps) => (
|
}: ProductListProps) => {
|
||||||
|
const intl = useIntl();
|
||||||
|
|
||||||
|
return (
|
||||||
<Card>
|
<Card>
|
||||||
<CardTitle
|
<CardTitle
|
||||||
title={i18n.t("Products")}
|
title={intl.formatMessage({
|
||||||
|
defaultMessage: "Products",
|
||||||
|
description: "section header",
|
||||||
|
id: "categoryProductsHeader"
|
||||||
|
})}
|
||||||
toolbar={
|
toolbar={
|
||||||
<Button variant="text" color="primary" onClick={onAddProduct}>
|
<Button variant="text" color="primary" onClick={onAddProduct}>
|
||||||
{i18n.t("Add product")}
|
<FormattedMessage
|
||||||
|
defaultMessage="Add product"
|
||||||
|
description="button"
|
||||||
|
id="categoryProductsAddProductButton"
|
||||||
|
/>
|
||||||
</Button>
|
</Button>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
@ -76,9 +87,19 @@ export const ProductList = withStyles(styles, { name: "ProductList" })(
|
||||||
<TableRow>
|
<TableRow>
|
||||||
{(products === undefined || products.length > 0) && <TableCell />}
|
{(products === undefined || products.length > 0) && <TableCell />}
|
||||||
<TableCell className={classes.textLeft}>
|
<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>
|
||||||
<TableCell>{i18n.t("Type", { context: "object" })}</TableCell>
|
|
||||||
</TableRow>
|
</TableRow>
|
||||||
</TableHead>
|
</TableHead>
|
||||||
<TableFooter>
|
<TableFooter>
|
||||||
|
@ -123,14 +144,20 @@ export const ProductList = withStyles(styles, { name: "ProductList" })(
|
||||||
),
|
),
|
||||||
() => (
|
() => (
|
||||||
<TableRow>
|
<TableRow>
|
||||||
<TableCell colSpan={3}>{i18n.t("No products found")}</TableCell>
|
<TableCell colSpan={3}>
|
||||||
|
<FormattedMessage
|
||||||
|
defaultMessage="No products found"
|
||||||
|
id="categoryProductsNoProducts"
|
||||||
|
/>
|
||||||
|
</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
)
|
)
|
||||||
)}
|
)}
|
||||||
</TableBody>
|
</TableBody>
|
||||||
</Table>
|
</Table>
|
||||||
</Card>
|
</Card>
|
||||||
)
|
);
|
||||||
|
}
|
||||||
);
|
);
|
||||||
ProductList.displayName = "CategoryProductList";
|
ProductList.displayName = "CategoryProductList";
|
||||||
export default ProductList;
|
export default ProductList;
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import Button from "@material-ui/core/Button";
|
import Button from "@material-ui/core/Button";
|
||||||
import Card from "@material-ui/core/Card";
|
import Card from "@material-ui/core/Card";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
import { FormattedMessage, useIntl } from "react-intl";
|
||||||
|
|
||||||
import CardTitle from "@saleor/components/CardTitle";
|
import CardTitle from "@saleor/components/CardTitle";
|
||||||
import ProductList from "@saleor/components/ProductList";
|
import ProductList from "@saleor/components/ProductList";
|
||||||
import i18n from "../../../i18n";
|
|
||||||
import { ListActions, PageListProps } from "../../../types";
|
import { ListActions, PageListProps } from "../../../types";
|
||||||
import { CategoryDetails_category_products_edges_node } from "../../types/CategoryDetails";
|
import { CategoryDetails_category_products_edges_node } from "../../types/CategoryDetails";
|
||||||
|
|
||||||
|
@ -29,13 +29,28 @@ export const CategoryProductsCard: React.StatelessComponent<
|
||||||
toggle,
|
toggle,
|
||||||
toggleAll,
|
toggleAll,
|
||||||
toolbar
|
toolbar
|
||||||
}) => (
|
}) => {
|
||||||
|
const intl = useIntl();
|
||||||
|
return (
|
||||||
<Card>
|
<Card>
|
||||||
<CardTitle
|
<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={
|
toolbar={
|
||||||
<Button color="primary" variant="text" onClick={onAdd}>
|
<Button color="primary" variant="text" onClick={onAdd}>
|
||||||
{i18n.t("Add product")}
|
<FormattedMessage
|
||||||
|
defaultMessage="Add product"
|
||||||
|
description="button"
|
||||||
|
id="categoryProductsCardAddProductButton"
|
||||||
|
/>
|
||||||
</Button>
|
</Button>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
@ -57,7 +72,8 @@ export const CategoryProductsCard: React.StatelessComponent<
|
||||||
toolbar={toolbar}
|
toolbar={toolbar}
|
||||||
/>
|
/>
|
||||||
</Card>
|
</Card>
|
||||||
);
|
);
|
||||||
|
};
|
||||||
|
|
||||||
CategoryProductsCard.displayName = "CategoryProductsCard";
|
CategoryProductsCard.displayName = "CategoryProductsCard";
|
||||||
export default CategoryProductsCard;
|
export default CategoryProductsCard;
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import { RawDraftContentState } from "draft-js";
|
import { RawDraftContentState } from "draft-js";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
import { useIntl, FormattedMessage } from "react-intl";
|
||||||
|
|
||||||
import AppHeader from "@saleor/components/AppHeader";
|
import AppHeader from "@saleor/components/AppHeader";
|
||||||
import { CardSpacer } from "@saleor/components/CardSpacer";
|
import { CardSpacer } from "@saleor/components/CardSpacer";
|
||||||
|
@ -10,7 +11,6 @@ import PageHeader from "@saleor/components/PageHeader";
|
||||||
import SaveButtonBar from "@saleor/components/SaveButtonBar";
|
import SaveButtonBar from "@saleor/components/SaveButtonBar";
|
||||||
import SeoForm from "@saleor/components/SeoForm";
|
import SeoForm from "@saleor/components/SeoForm";
|
||||||
import { Tab, TabContainer } from "@saleor/components/Tab";
|
import { Tab, TabContainer } from "@saleor/components/Tab";
|
||||||
import i18n from "../../../i18n";
|
|
||||||
import { maybe } from "../../../misc";
|
import { maybe } from "../../../misc";
|
||||||
import { TabListActions, UserError } from "../../../types";
|
import { TabListActions, UserError } from "../../../types";
|
||||||
import CategoryDetailsForm from "../../components/CategoryDetailsForm";
|
import CategoryDetailsForm from "../../components/CategoryDetailsForm";
|
||||||
|
@ -96,6 +96,7 @@ export const CategoryUpdatePage: React.StatelessComponent<
|
||||||
toggle,
|
toggle,
|
||||||
toggleAll
|
toggleAll
|
||||||
}: CategoryUpdatePageProps) => {
|
}: CategoryUpdatePageProps) => {
|
||||||
|
const intl = useIntl();
|
||||||
const initialData: FormData = category
|
const initialData: FormData = category
|
||||||
? {
|
? {
|
||||||
backgroundImageAlt: maybe(() => category.backgroundImage.alt, ""),
|
backgroundImageAlt: maybe(() => category.backgroundImage.alt, ""),
|
||||||
|
@ -139,9 +140,11 @@ export const CategoryUpdatePage: React.StatelessComponent<
|
||||||
/>
|
/>
|
||||||
<CardSpacer />
|
<CardSpacer />
|
||||||
<SeoForm
|
<SeoForm
|
||||||
helperText={i18n.t(
|
helperText={intl.formatMessage({
|
||||||
"Add search engine title and description to make this category easier to find"
|
defaultMessage:
|
||||||
)}
|
"Add search engine title and description to make this category easier to find",
|
||||||
|
id: "categoryUpdatePageSeo"
|
||||||
|
})}
|
||||||
title={data.seoTitle}
|
title={data.seoTitle}
|
||||||
titlePlaceholder={data.name}
|
titlePlaceholder={data.name}
|
||||||
description={data.seoDescription}
|
description={data.seoDescription}
|
||||||
|
@ -156,13 +159,21 @@ export const CategoryUpdatePage: React.StatelessComponent<
|
||||||
isActive={currentTab === CategoryPageTab.categories}
|
isActive={currentTab === CategoryPageTab.categories}
|
||||||
changeTab={changeTab}
|
changeTab={changeTab}
|
||||||
>
|
>
|
||||||
{i18n.t("Subcategories")}
|
<FormattedMessage
|
||||||
|
defaultMessage="Subcategories"
|
||||||
|
description="category list: number of subcategories column header"
|
||||||
|
id="categoryUpdatePageSubcategoriesColumnHeader"
|
||||||
|
/>
|
||||||
</CategoriesTab>
|
</CategoriesTab>
|
||||||
<ProductsTab
|
<ProductsTab
|
||||||
isActive={currentTab === CategoryPageTab.products}
|
isActive={currentTab === CategoryPageTab.products}
|
||||||
changeTab={changeTab}
|
changeTab={changeTab}
|
||||||
>
|
>
|
||||||
{i18n.t("Products")}
|
<FormattedMessage
|
||||||
|
defaultMessage="Products"
|
||||||
|
description="category list: number of products column header"
|
||||||
|
id="categoryUpdatePageProductsColumnHeader"
|
||||||
|
/>
|
||||||
</ProductsTab>
|
</ProductsTab>
|
||||||
</TabContainer>
|
</TabContainer>
|
||||||
<CardSpacer />
|
<CardSpacer />
|
||||||
|
@ -204,9 +215,6 @@ export const CategoryUpdatePage: React.StatelessComponent<
|
||||||
onCancel={onBack}
|
onCancel={onBack}
|
||||||
onDelete={onDelete}
|
onDelete={onDelete}
|
||||||
onSave={submit}
|
onSave={submit}
|
||||||
labels={{
|
|
||||||
delete: i18n.t("Delete category")
|
|
||||||
}}
|
|
||||||
state={saveButtonBarState}
|
state={saveButtonBarState}
|
||||||
disabled={disabled || !hasChanged}
|
disabled={disabled || !hasChanged}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
import { useIntl } from "react-intl";
|
||||||
|
|
||||||
import { WindowTitle } from "@saleor/components/WindowTitle";
|
import { WindowTitle } from "@saleor/components/WindowTitle";
|
||||||
import useNavigator from "@saleor/hooks/useNavigator";
|
import useNavigator from "@saleor/hooks/useNavigator";
|
||||||
import useNotifier from "@saleor/hooks/useNotifier";
|
import useNotifier from "@saleor/hooks/useNotifier";
|
||||||
import i18n from "../../i18n";
|
|
||||||
import { getMutationState, maybe } from "../../misc";
|
import { getMutationState, maybe } from "../../misc";
|
||||||
import CategoryCreatePage from "../components/CategoryCreatePage";
|
import CategoryCreatePage from "../components/CategoryCreatePage";
|
||||||
import { TypedCategoryCreateMutation } from "../mutations";
|
import { TypedCategoryCreateMutation } from "../mutations";
|
||||||
|
@ -19,10 +19,16 @@ export const CategoryCreateView: React.StatelessComponent<
|
||||||
> = ({ parentId }) => {
|
> = ({ parentId }) => {
|
||||||
const navigate = useNavigator();
|
const navigate = useNavigator();
|
||||||
const notify = useNotifier();
|
const notify = useNotifier();
|
||||||
|
const intl = useIntl();
|
||||||
|
|
||||||
const handleSuccess = (data: CategoryCreate) => {
|
const handleSuccess = (data: CategoryCreate) => {
|
||||||
if (data.categoryCreate.errors.length === 0) {
|
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));
|
navigate(categoryUrl(data.categoryCreate.category.id));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -42,7 +48,13 @@ export const CategoryCreateView: React.StatelessComponent<
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<WindowTitle title={i18n.t("Create category")} />
|
<WindowTitle
|
||||||
|
title={intl.formatMessage({
|
||||||
|
defaultMessage: "Create category",
|
||||||
|
description: "window title",
|
||||||
|
id: "categoryCreateWindowTitle"
|
||||||
|
})}
|
||||||
|
/>
|
||||||
<CategoryCreatePage
|
<CategoryCreatePage
|
||||||
saveButtonBarState={formTransitionState}
|
saveButtonBarState={formTransitionState}
|
||||||
errors={errors}
|
errors={errors}
|
||||||
|
|
|
@ -2,6 +2,7 @@ import DialogContentText from "@material-ui/core/DialogContentText";
|
||||||
import IconButton from "@material-ui/core/IconButton";
|
import IconButton from "@material-ui/core/IconButton";
|
||||||
import DeleteIcon from "@material-ui/icons/Delete";
|
import DeleteIcon from "@material-ui/icons/Delete";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
import { FormattedMessage, useIntl } from "react-intl";
|
||||||
|
|
||||||
import ActionDialog from "@saleor/components/ActionDialog";
|
import ActionDialog from "@saleor/components/ActionDialog";
|
||||||
import { WindowTitle } from "@saleor/components/WindowTitle";
|
import { WindowTitle } from "@saleor/components/WindowTitle";
|
||||||
|
@ -12,7 +13,6 @@ import usePaginator, {
|
||||||
createPaginationState
|
createPaginationState
|
||||||
} from "@saleor/hooks/usePaginator";
|
} from "@saleor/hooks/usePaginator";
|
||||||
import { PAGINATE_BY } from "../../config";
|
import { PAGINATE_BY } from "../../config";
|
||||||
import i18n from "../../i18n";
|
|
||||||
import { getMutationState, maybe } from "../../misc";
|
import { getMutationState, maybe } from "../../misc";
|
||||||
import { TypedProductBulkDeleteMutation } from "../../products/mutations";
|
import { TypedProductBulkDeleteMutation } from "../../products/mutations";
|
||||||
import { productBulkDelete } from "../../products/types/productBulkDelete";
|
import { productBulkDelete } from "../../products/types/productBulkDelete";
|
||||||
|
@ -59,12 +59,14 @@ export const CategoryDetails: React.StatelessComponent<
|
||||||
const { isSelected, listElements, reset, toggle, toggleAll } = useBulkActions(
|
const { isSelected, listElements, reset, toggle, toggleAll } = useBulkActions(
|
||||||
params.ids
|
params.ids
|
||||||
);
|
);
|
||||||
|
const intl = useIntl();
|
||||||
|
|
||||||
const handleCategoryDelete = (data: CategoryDelete) => {
|
const handleCategoryDelete = (data: CategoryDelete) => {
|
||||||
if (data.categoryDelete.errors.length === 0) {
|
if (data.categoryDelete.errors.length === 0) {
|
||||||
notify({
|
notify({
|
||||||
text: i18n.t("Category deleted", {
|
text: intl.formatMessage({
|
||||||
context: "notification"
|
defaultMessage: "Category deleted",
|
||||||
|
id: "categoryDetailsCategoryDeleted"
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
navigate(categoryListUrl());
|
navigate(categoryListUrl());
|
||||||
|
@ -140,7 +142,10 @@ export const CategoryDetails: React.StatelessComponent<
|
||||||
if (data.categoryBulkDelete.errors.length === 0) {
|
if (data.categoryBulkDelete.errors.length === 0) {
|
||||||
closeModal();
|
closeModal();
|
||||||
notify({
|
notify({
|
||||||
text: i18n.t("Categories removed")
|
text: intl.formatMessage({
|
||||||
|
defaultMessage: "Categories removed",
|
||||||
|
id: "categoryDetailsCategoriesRemoved"
|
||||||
|
})
|
||||||
});
|
});
|
||||||
refetch();
|
refetch();
|
||||||
reset();
|
reset();
|
||||||
|
@ -151,7 +156,10 @@ export const CategoryDetails: React.StatelessComponent<
|
||||||
if (data.productBulkDelete.errors.length === 0) {
|
if (data.productBulkDelete.errors.length === 0) {
|
||||||
closeModal();
|
closeModal();
|
||||||
notify({
|
notify({
|
||||||
text: i18n.t("Products removed")
|
text: intl.formatMessage({
|
||||||
|
defaultMessage: "Products removed",
|
||||||
|
id: "categoryDetailsProductsRemoved"
|
||||||
|
})
|
||||||
});
|
});
|
||||||
refetch();
|
refetch();
|
||||||
reset();
|
reset();
|
||||||
|
@ -319,32 +327,43 @@ export const CategoryDetails: React.StatelessComponent<
|
||||||
deleteCategory({ variables: { id } })
|
deleteCategory({ variables: { id } })
|
||||||
}
|
}
|
||||||
open={params.action === "delete"}
|
open={params.action === "delete"}
|
||||||
title={i18n.t("Delete category", {
|
title={intl.formatMessage({
|
||||||
context: "modal title"
|
defaultMessage: "Delete category",
|
||||||
|
description: "dialog title",
|
||||||
|
id:
|
||||||
|
"categoryDetailsDeleteCategoryDialogTitle"
|
||||||
})}
|
})}
|
||||||
variant="delete"
|
variant="delete"
|
||||||
>
|
>
|
||||||
<DialogContentText
|
<DialogContentText>
|
||||||
dangerouslySetInnerHTML={{
|
<FormattedMessage
|
||||||
__html: i18n.t(
|
defaultMessage="Are you sure you want to remove {name}?"
|
||||||
"Are you sure you want to remove <strong>{{ categoryName }}</strong>? <br /> ",
|
description="remove category"
|
||||||
{
|
id="categoryDetailsDeleteCategoryDialogContent"
|
||||||
categoryName: maybe(
|
values={{
|
||||||
() => data.category.name
|
name: (
|
||||||
),
|
<strong>
|
||||||
context: "modal message"
|
{maybe(
|
||||||
}
|
() => data.category.name,
|
||||||
|
"..."
|
||||||
|
)}
|
||||||
|
</strong>
|
||||||
)
|
)
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
</DialogContentText>
|
||||||
<DialogContentText>
|
<DialogContentText>
|
||||||
{i18n.t(
|
<FormattedMessage
|
||||||
"Remember that this will also remove all products assigned to this category."
|
defaultMessage="Remember that this will also remove all products assigned to this category."
|
||||||
)}
|
id="categoryDetailsDeleteCategoryDialogContentAdditionalText"
|
||||||
|
/>
|
||||||
</DialogContentText>
|
</DialogContentText>
|
||||||
</ActionDialog>
|
</ActionDialog>
|
||||||
<ActionDialog
|
<ActionDialog
|
||||||
open={params.action === "delete-categories"}
|
open={
|
||||||
|
params.action === "delete-categories" &&
|
||||||
|
maybe(() => params.ids.length > 0)
|
||||||
|
}
|
||||||
confirmButtonState={
|
confirmButtonState={
|
||||||
categoryBulkDeleteMutationState
|
categoryBulkDeleteMutationState
|
||||||
}
|
}
|
||||||
|
@ -354,27 +373,30 @@ export const CategoryDetails: React.StatelessComponent<
|
||||||
variables: { ids: params.ids }
|
variables: { ids: params.ids }
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
title={i18n.t("Remove categories")}
|
title={intl.formatMessage({
|
||||||
|
defaultMessage: "Remove categories",
|
||||||
|
description: "dialog title",
|
||||||
|
id:
|
||||||
|
"categoryDetailsDeleteSubcategoriesDialogTitle"
|
||||||
|
})}
|
||||||
variant="delete"
|
variant="delete"
|
||||||
>
|
>
|
||||||
<DialogContentText
|
<DialogContentText>
|
||||||
dangerouslySetInnerHTML={{
|
<FormattedMessage
|
||||||
__html: i18n.t(
|
defaultMessage="Are you sure you want to remove {number} categories?"
|
||||||
"Are you sure you want to remove <strong>{{ number }}</strong> categories?",
|
id="categoryDetailsDeleteCategoriesDialogContent"
|
||||||
{
|
values={{
|
||||||
number: maybe(
|
number: (
|
||||||
() =>
|
<strong>{params.ids.length}</strong>
|
||||||
params.ids.length.toString(),
|
|
||||||
"..."
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
</DialogContentText>
|
||||||
<DialogContentText>
|
<DialogContentText>
|
||||||
{i18n.t(
|
<FormattedMessage
|
||||||
"Remember that this will also remove all products assigned to this category."
|
defaultMessage="Remember that this will also remove all products assigned to this category."
|
||||||
)}
|
id="categoryDetailsDeleteCategoriesDialogContentAdditionalText"
|
||||||
|
/>
|
||||||
</DialogContentText>
|
</DialogContentText>
|
||||||
</ActionDialog>
|
</ActionDialog>
|
||||||
<ActionDialog
|
<ActionDialog
|
||||||
|
@ -388,23 +410,26 @@ export const CategoryDetails: React.StatelessComponent<
|
||||||
variables: { ids: params.ids }
|
variables: { ids: params.ids }
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
title={i18n.t("Remove products")}
|
title={intl.formatMessage({
|
||||||
|
defaultMessage: "Remove products",
|
||||||
|
description: "dialog title",
|
||||||
|
id:
|
||||||
|
"categoryDetailsDeleteProductsDialogTitle"
|
||||||
|
})}
|
||||||
variant="delete"
|
variant="delete"
|
||||||
>
|
>
|
||||||
<DialogContentText
|
{" "}
|
||||||
dangerouslySetInnerHTML={{
|
<DialogContentText>
|
||||||
__html: i18n.t(
|
<FormattedMessage
|
||||||
"Are you sure you want to remove <strong>{{ number }}</strong> products?",
|
defaultMessage="Are you sure you want to remove {number} products?"
|
||||||
{
|
id="categoryDetailsDeleteProductsDialogContent"
|
||||||
number: maybe(
|
values={{
|
||||||
() =>
|
number: (
|
||||||
params.ids.length.toString(),
|
<strong>{params.ids.length}</strong>
|
||||||
"..."
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
</DialogContentText>
|
||||||
</ActionDialog>
|
</ActionDialog>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
|
@ -2,6 +2,7 @@ import DialogContentText from "@material-ui/core/DialogContentText";
|
||||||
import IconButton from "@material-ui/core/IconButton";
|
import IconButton from "@material-ui/core/IconButton";
|
||||||
import DeleteIcon from "@material-ui/icons/Delete";
|
import DeleteIcon from "@material-ui/icons/Delete";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
import { FormattedMessage, useIntl } from "react-intl";
|
||||||
|
|
||||||
import ActionDialog from "@saleor/components/ActionDialog";
|
import ActionDialog from "@saleor/components/ActionDialog";
|
||||||
import useBulkActions from "@saleor/hooks/useBulkActions";
|
import useBulkActions from "@saleor/hooks/useBulkActions";
|
||||||
|
@ -10,7 +11,6 @@ import useNavigator from "@saleor/hooks/useNavigator";
|
||||||
import usePaginator, {
|
import usePaginator, {
|
||||||
createPaginationState
|
createPaginationState
|
||||||
} from "@saleor/hooks/usePaginator";
|
} from "@saleor/hooks/usePaginator";
|
||||||
import i18n from "@saleor/i18n";
|
|
||||||
import { getMutationState, maybe } from "@saleor/misc";
|
import { getMutationState, maybe } from "@saleor/misc";
|
||||||
import { ListViews } from "@saleor/types";
|
import { ListViews } from "@saleor/types";
|
||||||
import { CategoryListPage } from "../components/CategoryListPage/CategoryListPage";
|
import { CategoryListPage } from "../components/CategoryListPage/CategoryListPage";
|
||||||
|
@ -39,6 +39,8 @@ export const CategoryList: React.StatelessComponent<CategoryListProps> = ({
|
||||||
const { updateListSettings, settings } = useListSettings(
|
const { updateListSettings, settings } = useListSettings(
|
||||||
ListViews.CATEGORY_LIST
|
ListViews.CATEGORY_LIST
|
||||||
);
|
);
|
||||||
|
const intl = useIntl();
|
||||||
|
|
||||||
const paginationState = createPaginationState(settings.rowNumber, params);
|
const paginationState = createPaginationState(settings.rowNumber, params);
|
||||||
return (
|
return (
|
||||||
<TypedRootCategoriesQuery displayLoader variables={paginationState}>
|
<TypedRootCategoriesQuery displayLoader variables={paginationState}>
|
||||||
|
@ -124,26 +126,25 @@ export const CategoryList: React.StatelessComponent<CategoryListProps> = ({
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
open={params.action === "delete"}
|
open={params.action === "delete"}
|
||||||
title={i18n.t("Remove categories")}
|
title={intl.formatMessage({
|
||||||
|
defaultMessage: "Remove categories",
|
||||||
|
description: "dialog title",
|
||||||
|
id: "categoryListDeleteSubcategoriesDialogTitle"
|
||||||
|
})}
|
||||||
variant="delete"
|
variant="delete"
|
||||||
>
|
>
|
||||||
<DialogContentText
|
<FormattedMessage
|
||||||
dangerouslySetInnerHTML={{
|
defaultMessage="Are you sure you want to remove {number} categories?"
|
||||||
__html: i18n.t(
|
id="categoryListDeleteCategoriesDialogContent"
|
||||||
"Are you sure you want to remove <strong>{{ number }}</strong> categories?",
|
values={{
|
||||||
{
|
number: <strong>{params.ids.length}</strong>
|
||||||
number: maybe(
|
|
||||||
() => params.ids.length.toString(),
|
|
||||||
"..."
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<DialogContentText>
|
<DialogContentText>
|
||||||
{i18n.t(
|
<FormattedMessage
|
||||||
"Remember that this will also remove all products assigned to this category."
|
defaultMessage="Remember that this will also remove all products assigned to this category."
|
||||||
)}
|
id="categoryListDeleteCategoriesDialogContentAdditionalText"
|
||||||
|
/>
|
||||||
</DialogContentText>
|
</DialogContentText>
|
||||||
</ActionDialog>
|
</ActionDialog>
|
||||||
</>
|
</>
|
||||||
|
|
27
src/intl.ts
27
src/intl.ts
|
@ -9,11 +9,20 @@ export const commonMessages = defineMessages({
|
||||||
defaultMessage: "Confirm",
|
defaultMessage: "Confirm",
|
||||||
id: "confirm"
|
id: "confirm"
|
||||||
},
|
},
|
||||||
generalInformations:{
|
description: {
|
||||||
defaultMessage: "General Informations",
|
defaultMessage: "Description",
|
||||||
id:"generalInformations"
|
id: "description"
|
||||||
},
|
},
|
||||||
properties:{
|
generalInformations: {
|
||||||
|
defaultMessage: "General Informations",
|
||||||
|
id: "generalInformations"
|
||||||
|
},
|
||||||
|
optionalField: {
|
||||||
|
defaultMessage: "Optional",
|
||||||
|
description: "field is optional",
|
||||||
|
id: "optionalField"
|
||||||
|
},
|
||||||
|
properties: {
|
||||||
defaultMessage: "Properties",
|
defaultMessage: "Properties",
|
||||||
id: "properties"
|
id: "properties"
|
||||||
},
|
},
|
||||||
|
@ -24,6 +33,11 @@ export const commonMessages = defineMessages({
|
||||||
savedChanges: {
|
savedChanges: {
|
||||||
defaultMessage: "Saved changes",
|
defaultMessage: "Saved changes",
|
||||||
id: "savedChanges"
|
id: "savedChanges"
|
||||||
|
},
|
||||||
|
uploadImage: {
|
||||||
|
defaultMessage: "Upload image",
|
||||||
|
description: "button",
|
||||||
|
id: "uploadImage"
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -32,5 +46,10 @@ export const sectionNames = defineMessages({
|
||||||
defaultMessage: "Attributes",
|
defaultMessage: "Attributes",
|
||||||
description: "attributes section name",
|
description: "attributes section name",
|
||||||
id: "attributes"
|
id: "attributes"
|
||||||
|
},
|
||||||
|
categories: {
|
||||||
|
defaultMessage: "Categories",
|
||||||
|
description: "categories section name",
|
||||||
|
id: "categories"
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue