Add search to translations
This commit is contained in:
parent
3974b23b15
commit
f9285cec60
23 changed files with 333 additions and 171 deletions
98
src/components/Filter/FilterSearch.tsx
Normal file
98
src/components/Filter/FilterSearch.tsx
Normal file
|
@ -0,0 +1,98 @@
|
|||
import { Theme } from "@material-ui/core/styles";
|
||||
import { makeStyles } from "@material-ui/styles";
|
||||
import React from "react";
|
||||
import { FormattedMessage } from "react-intl";
|
||||
|
||||
import { SearchPageProps } from "../../types";
|
||||
import Debounce from "../Debounce";
|
||||
import { FilterActionsOnlySearch } from "../Filter/FilterActions";
|
||||
import Hr from "../Hr";
|
||||
import Link from "../Link";
|
||||
|
||||
export interface FilterSearchProps extends SearchPageProps {
|
||||
displaySearchAction: "save" | "delete" | null;
|
||||
searchPlaceholder: string;
|
||||
onSearchDelete?: () => void;
|
||||
onSearchSave?: () => void;
|
||||
}
|
||||
|
||||
const useStyles = makeStyles(
|
||||
(theme: Theme) => ({
|
||||
tabAction: {
|
||||
display: "inline-block"
|
||||
},
|
||||
tabActionContainer: {
|
||||
borderBottom: "1px solid #e8e8e8",
|
||||
display: "flex",
|
||||
justifyContent: "flex-end",
|
||||
marginTop: theme.spacing.unit,
|
||||
padding: `0 ${theme.spacing.unit * 3}px ${theme.spacing.unit}px`
|
||||
}
|
||||
}),
|
||||
{
|
||||
name: "FilterSearch"
|
||||
}
|
||||
);
|
||||
|
||||
const FilterSearch: React.FC<FilterSearchProps> = props => {
|
||||
const {
|
||||
displaySearchAction,
|
||||
initialSearch,
|
||||
onSearchChange,
|
||||
onSearchDelete,
|
||||
onSearchSave,
|
||||
searchPlaceholder
|
||||
} = props;
|
||||
const classes = useStyles(props);
|
||||
const [search, setSearch] = React.useState(initialSearch);
|
||||
React.useEffect(() => setSearch(initialSearch), [initialSearch]);
|
||||
|
||||
return (
|
||||
<Debounce debounceFn={onSearchChange}>
|
||||
{debounceSearchChange => {
|
||||
const handleSearchChange = (event: React.ChangeEvent<any>) => {
|
||||
const value = event.target.value;
|
||||
setSearch(value);
|
||||
debounceSearchChange(value);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<FilterActionsOnlySearch
|
||||
{...props}
|
||||
placeholder={searchPlaceholder}
|
||||
search={search}
|
||||
onSearchChange={handleSearchChange}
|
||||
/>
|
||||
{!!displaySearchAction ? (
|
||||
<div className={classes.tabActionContainer}>
|
||||
<div className={classes.tabAction}>
|
||||
{displaySearchAction === "save" ? (
|
||||
<Link onClick={onSearchSave}>
|
||||
<FormattedMessage
|
||||
defaultMessage="Save Custom Search"
|
||||
description="button"
|
||||
/>
|
||||
</Link>
|
||||
) : (
|
||||
<Link onClick={onSearchDelete}>
|
||||
<FormattedMessage
|
||||
defaultMessage="Delete Search"
|
||||
description="button"
|
||||
/>
|
||||
</Link>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<Hr />
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}}
|
||||
</Debounce>
|
||||
);
|
||||
};
|
||||
|
||||
FilterSearch.displayName = "FilterSearch";
|
||||
export default FilterSearch;
|
|
@ -1,13 +1,8 @@
|
|||
import { Theme } from "@material-ui/core/styles";
|
||||
import { makeStyles } from "@material-ui/styles";
|
||||
import React from "react";
|
||||
import { FormattedMessage, useIntl } from "react-intl";
|
||||
import { useIntl } from "react-intl";
|
||||
|
||||
import { SearchPageProps, TabPageProps } from "@saleor/types";
|
||||
import Debounce from "../Debounce";
|
||||
import { FilterActionsOnlySearch } from "../Filter/FilterActions";
|
||||
import Hr from "../Hr";
|
||||
import Link from "../Link";
|
||||
import FilterSearch from "../Filter/FilterSearch";
|
||||
import FilterTabs, { FilterTab } from "../TableFilter";
|
||||
|
||||
export interface SearchBarProps extends SearchPageProps, TabPageProps {
|
||||
|
@ -15,24 +10,6 @@ export interface SearchBarProps extends SearchPageProps, TabPageProps {
|
|||
searchPlaceholder: string;
|
||||
}
|
||||
|
||||
const useStyles = makeStyles(
|
||||
(theme: Theme) => ({
|
||||
tabAction: {
|
||||
display: "inline-block"
|
||||
},
|
||||
tabActionContainer: {
|
||||
borderBottom: "1px solid #e8e8e8",
|
||||
display: "flex",
|
||||
justifyContent: "flex-end",
|
||||
marginTop: theme.spacing.unit,
|
||||
padding: `0 ${theme.spacing.unit * 3}px ${theme.spacing.unit}px`
|
||||
}
|
||||
}),
|
||||
{
|
||||
name: "SearchBar"
|
||||
}
|
||||
);
|
||||
|
||||
const SearchBar: React.FC<SearchBarProps> = props => {
|
||||
const {
|
||||
allTabLabel,
|
||||
|
@ -46,7 +23,6 @@ const SearchBar: React.FC<SearchBarProps> = props => {
|
|||
onTabDelete,
|
||||
onTabSave
|
||||
} = props;
|
||||
const classes = useStyles(props);
|
||||
const [search, setSearch] = React.useState(initialSearch);
|
||||
const intl = useIntl();
|
||||
React.useEffect(() => setSearch(initialSearch), [initialSearch]);
|
||||
|
@ -73,49 +49,14 @@ const SearchBar: React.FC<SearchBarProps> = props => {
|
|||
/>
|
||||
)}
|
||||
</FilterTabs>
|
||||
<Debounce debounceFn={onSearchChange}>
|
||||
{debounceSearchChange => {
|
||||
const handleSearchChange = (event: React.ChangeEvent<any>) => {
|
||||
const value = event.target.value;
|
||||
setSearch(value);
|
||||
debounceSearchChange(value);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<FilterActionsOnlySearch
|
||||
{...props}
|
||||
placeholder={searchPlaceholder}
|
||||
search={search}
|
||||
onSearchChange={handleSearchChange}
|
||||
/>
|
||||
{!!search || (tabs && tabs.length > 0 && currentTab !== 0) ? (
|
||||
<div className={classes.tabActionContainer}>
|
||||
<div className={classes.tabAction}>
|
||||
{isCustom ? (
|
||||
<Link onClick={onTabSave}>
|
||||
<FormattedMessage
|
||||
defaultMessage="Save Custom Search"
|
||||
description="button"
|
||||
/>
|
||||
</Link>
|
||||
) : (
|
||||
<Link onClick={onTabDelete}>
|
||||
<FormattedMessage
|
||||
defaultMessage="Delete Search"
|
||||
description="button"
|
||||
/>
|
||||
</Link>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<Hr />
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}}
|
||||
</Debounce>
|
||||
<FilterSearch
|
||||
displaySearchAction={!!search ? (isCustom ? "save" : "delete") : null}
|
||||
initialSearch={initialSearch}
|
||||
searchPlaceholder={searchPlaceholder}
|
||||
onSearchChange={onSearchChange}
|
||||
onSearchDelete={onTabDelete}
|
||||
onSearchSave={onTabSave}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -1,17 +1,19 @@
|
|||
import Card from "@material-ui/core/Card";
|
||||
import React from "react";
|
||||
import { useIntl } from "react-intl";
|
||||
import { IntlShape, useIntl } from "react-intl";
|
||||
|
||||
import AppHeader from "@saleor/components/AppHeader";
|
||||
import Container from "@saleor/components/Container";
|
||||
import FilterSearch from "@saleor/components/Filter/FilterSearch";
|
||||
import PageHeader from "@saleor/components/PageHeader";
|
||||
// tslint:disable no-submodule-imports
|
||||
import { ShopInfo_shop_languages } from "@saleor/components/Shop/types/ShopInfo";
|
||||
import FilterTabs, { FilterTab } from "@saleor/components/TableFilter";
|
||||
import { maybe } from "@saleor/misc";
|
||||
import { SearchPageProps } from "@saleor/types";
|
||||
import { TranslatableEntities } from "../../urls";
|
||||
|
||||
export interface TranslationsEntitiesListPageProps {
|
||||
export interface TranslationsEntitiesListPageProps extends SearchPageProps {
|
||||
children: React.ReactNode;
|
||||
filters: TranslationsEntitiesFilters;
|
||||
language: ShopInfo_shop_languages;
|
||||
|
@ -31,10 +33,66 @@ export interface TranslationsEntitiesFilters {
|
|||
|
||||
export type TranslationsEntitiesListFilterTab = keyof typeof TranslatableEntities;
|
||||
|
||||
function getSearchPlaceholder(
|
||||
tab: TranslationsEntitiesListFilterTab,
|
||||
intl: IntlShape
|
||||
): string {
|
||||
switch (tab) {
|
||||
case "categories":
|
||||
return intl.formatMessage({
|
||||
defaultMessage: "Search Category"
|
||||
});
|
||||
|
||||
case "collections":
|
||||
return intl.formatMessage({
|
||||
defaultMessage: "Search Collection"
|
||||
});
|
||||
|
||||
case "products":
|
||||
return intl.formatMessage({
|
||||
defaultMessage: "Search Product"
|
||||
});
|
||||
|
||||
case "sales":
|
||||
return intl.formatMessage({
|
||||
defaultMessage: "Search Sale"
|
||||
});
|
||||
|
||||
case "vouchers":
|
||||
return intl.formatMessage({
|
||||
defaultMessage: "Search Voucher"
|
||||
});
|
||||
|
||||
case "pages":
|
||||
return intl.formatMessage({
|
||||
defaultMessage: "Search Page"
|
||||
});
|
||||
|
||||
case "productTypes":
|
||||
return intl.formatMessage({
|
||||
defaultMessage: "Search Product Type"
|
||||
});
|
||||
|
||||
default:
|
||||
return "...";
|
||||
}
|
||||
}
|
||||
|
||||
const tabs: TranslationsEntitiesListFilterTab[] = [
|
||||
"categories",
|
||||
"collections",
|
||||
"products",
|
||||
"sales",
|
||||
"vouchers",
|
||||
"pages",
|
||||
"productTypes"
|
||||
];
|
||||
|
||||
const TranslationsEntitiesListPage: React.StatelessComponent<
|
||||
TranslationsEntitiesListPageProps
|
||||
> = ({ filters, language, onBack, children }) => {
|
||||
> = ({ filters, language, onBack, children, ...searchProps }) => {
|
||||
const intl = useIntl();
|
||||
const currentTab = tabs.indexOf(filters.current);
|
||||
|
||||
return (
|
||||
<Container>
|
||||
|
@ -55,17 +113,7 @@ const TranslationsEntitiesListPage: React.StatelessComponent<
|
|||
)}
|
||||
/>
|
||||
<Card>
|
||||
<FilterTabs
|
||||
currentTab={([
|
||||
"categories",
|
||||
"collections",
|
||||
"products",
|
||||
"sales",
|
||||
"vouchers",
|
||||
"pages",
|
||||
"productTypes"
|
||||
] as TranslationsEntitiesListFilterTab[]).indexOf(filters.current)}
|
||||
>
|
||||
<FilterTabs currentTab={currentTab}>
|
||||
<FilterTab
|
||||
label={intl.formatMessage({
|
||||
defaultMessage: "Categories"
|
||||
|
@ -109,6 +157,11 @@ const TranslationsEntitiesListPage: React.StatelessComponent<
|
|||
onClick={filters.onProductTypesTabClick}
|
||||
/>
|
||||
</FilterTabs>
|
||||
<FilterSearch
|
||||
displaySearchAction={null}
|
||||
searchPlaceholder={getSearchPlaceholder(filters.current, intl)}
|
||||
{...searchProps}
|
||||
/>
|
||||
{children}
|
||||
</Card>
|
||||
</Container>
|
||||
|
|
|
@ -18,9 +18,7 @@ import TranslationsCategoriesComponent, {
|
|||
import TranslationsCollectionsComponent, {
|
||||
TranslationsCollectionsQueryParams
|
||||
} from "./views/TranslationsCollections";
|
||||
import TranslationsEntitiesComponent, {
|
||||
TranslationsEntitiesListQueryParams
|
||||
} from "./views/TranslationsEntities";
|
||||
import TranslationsEntitiesComponent from "./views/TranslationsEntities";
|
||||
import TranslationsLanguageList from "./views/TranslationsLanguageList";
|
||||
import TranslationsPagesComponent, {
|
||||
TranslationsPagesQueryParams
|
||||
|
@ -46,15 +44,11 @@ const TranslationsEntities: React.FC<TranslationsEntitiesRouteProps> = ({
|
|||
match
|
||||
}) => {
|
||||
const qs = parseQs(location.search.substr(1));
|
||||
const params: TranslationsEntitiesListQueryParams = {
|
||||
after: qs.after,
|
||||
before: qs.before,
|
||||
tab: qs.tab
|
||||
};
|
||||
|
||||
return (
|
||||
<TranslationsEntitiesComponent
|
||||
language={match.params.languageCode}
|
||||
params={params}
|
||||
params={qs}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -217,8 +217,15 @@ const categoryTranslations = gql`
|
|||
$after: String
|
||||
$last: Int
|
||||
$before: String
|
||||
$filter: CategoryFilterInput
|
||||
) {
|
||||
categories(before: $before, after: $after, first: $first, last: $last) {
|
||||
categories(
|
||||
before: $before
|
||||
after: $after
|
||||
first: $first
|
||||
last: $last
|
||||
filter: $filter
|
||||
) {
|
||||
edges {
|
||||
node {
|
||||
...CategoryTranslationFragment
|
||||
|
@ -244,8 +251,15 @@ const collectionTranslations = gql`
|
|||
$after: String
|
||||
$last: Int
|
||||
$before: String
|
||||
$filter: CollectionFilterInput
|
||||
) {
|
||||
collections(before: $before, after: $after, first: $first, last: $last) {
|
||||
collections(
|
||||
before: $before
|
||||
after: $after
|
||||
first: $first
|
||||
last: $last
|
||||
filter: $filter
|
||||
) {
|
||||
edges {
|
||||
node {
|
||||
...CollectionTranslationFragment
|
||||
|
@ -271,8 +285,15 @@ const productTranslations = gql`
|
|||
$after: String
|
||||
$last: Int
|
||||
$before: String
|
||||
$filter: ProductFilterInput
|
||||
) {
|
||||
products(before: $before, after: $after, first: $first, last: $last) {
|
||||
products(
|
||||
before: $before
|
||||
after: $after
|
||||
first: $first
|
||||
last: $last
|
||||
filter: $filter
|
||||
) {
|
||||
edges {
|
||||
node {
|
||||
...ProductTranslationFragment
|
||||
|
@ -298,8 +319,15 @@ const pageTranslations = gql`
|
|||
$after: String
|
||||
$last: Int
|
||||
$before: String
|
||||
$filter: PageFilterInput
|
||||
) {
|
||||
pages(before: $before, after: $after, first: $first, last: $last) {
|
||||
pages(
|
||||
before: $before
|
||||
after: $after
|
||||
first: $first
|
||||
last: $last
|
||||
filter: $filter
|
||||
) {
|
||||
edges {
|
||||
node {
|
||||
...PageTranslationFragment
|
||||
|
@ -325,8 +353,15 @@ const voucherTranslations = gql`
|
|||
$after: String
|
||||
$last: Int
|
||||
$before: String
|
||||
$filter: VoucherFilterInput
|
||||
) {
|
||||
vouchers(before: $before, after: $after, first: $first, last: $last) {
|
||||
vouchers(
|
||||
before: $before
|
||||
after: $after
|
||||
first: $first
|
||||
last: $last
|
||||
filter: $filter
|
||||
) {
|
||||
edges {
|
||||
node {
|
||||
...VoucherTranslationFragment
|
||||
|
@ -352,8 +387,15 @@ const saleTranslations = gql`
|
|||
$after: String
|
||||
$last: Int
|
||||
$before: String
|
||||
$filter: SaleFilterInput
|
||||
) {
|
||||
sales(before: $before, after: $after, first: $first, last: $last) {
|
||||
sales(
|
||||
before: $before
|
||||
after: $after
|
||||
first: $first
|
||||
last: $last
|
||||
filter: $filter
|
||||
) {
|
||||
edges {
|
||||
node {
|
||||
...SaleTranslationFragment
|
||||
|
@ -379,8 +421,15 @@ const productTypeTranslations = gql`
|
|||
$after: String
|
||||
$last: Int
|
||||
$before: String
|
||||
$filter: ProductTypeFilterInput
|
||||
) {
|
||||
productTypes(before: $before, after: $after, first: $first, last: $last) {
|
||||
productTypes(
|
||||
before: $before
|
||||
after: $after
|
||||
first: $first
|
||||
last: $last
|
||||
filter: $filter
|
||||
) {
|
||||
edges {
|
||||
node {
|
||||
...ProductTypeTranslationFragment
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/* eslint-disable */
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
import { LanguageCodeEnum } from "./../../types/globalTypes";
|
||||
import { LanguageCodeEnum, CategoryFilterInput } from "./../../types/globalTypes";
|
||||
|
||||
// ====================================================
|
||||
// GraphQL query operation: CategoryTranslations
|
||||
|
@ -62,4 +62,5 @@ export interface CategoryTranslationsVariables {
|
|||
after?: string | null;
|
||||
last?: number | null;
|
||||
before?: string | null;
|
||||
filter?: CategoryFilterInput | null;
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/* eslint-disable */
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
import { LanguageCodeEnum } from "./../../types/globalTypes";
|
||||
import { LanguageCodeEnum, CollectionFilterInput } from "./../../types/globalTypes";
|
||||
|
||||
// ====================================================
|
||||
// GraphQL query operation: CollectionTranslations
|
||||
|
@ -62,4 +62,5 @@ export interface CollectionTranslationsVariables {
|
|||
after?: string | null;
|
||||
last?: number | null;
|
||||
before?: string | null;
|
||||
filter?: CollectionFilterInput | null;
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/* eslint-disable */
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
import { LanguageCodeEnum } from "./../../types/globalTypes";
|
||||
import { LanguageCodeEnum, PageFilterInput } from "./../../types/globalTypes";
|
||||
|
||||
// ====================================================
|
||||
// GraphQL query operation: PageTranslations
|
||||
|
@ -63,4 +63,5 @@ export interface PageTranslationsVariables {
|
|||
after?: string | null;
|
||||
last?: number | null;
|
||||
before?: string | null;
|
||||
filter?: PageFilterInput | null;
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/* eslint-disable */
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
import { LanguageCodeEnum } from "./../../types/globalTypes";
|
||||
import { LanguageCodeEnum, ProductFilterInput } from "./../../types/globalTypes";
|
||||
|
||||
// ====================================================
|
||||
// GraphQL query operation: ProductTranslations
|
||||
|
@ -63,4 +63,5 @@ export interface ProductTranslationsVariables {
|
|||
after?: string | null;
|
||||
last?: number | null;
|
||||
before?: string | null;
|
||||
filter?: ProductFilterInput | null;
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/* eslint-disable */
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
import { LanguageCodeEnum } from "./../../types/globalTypes";
|
||||
import { LanguageCodeEnum, ProductTypeFilterInput } from "./../../types/globalTypes";
|
||||
|
||||
// ====================================================
|
||||
// GraphQL query operation: ProductTypeTranslations
|
||||
|
@ -99,4 +99,5 @@ export interface ProductTypeTranslationsVariables {
|
|||
after?: string | null;
|
||||
last?: number | null;
|
||||
before?: string | null;
|
||||
filter?: ProductTypeFilterInput | null;
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/* eslint-disable */
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
import { LanguageCodeEnum } from "./../../types/globalTypes";
|
||||
import { LanguageCodeEnum, SaleFilterInput } from "./../../types/globalTypes";
|
||||
|
||||
// ====================================================
|
||||
// GraphQL query operation: SaleTranslations
|
||||
|
@ -57,4 +57,5 @@ export interface SaleTranslationsVariables {
|
|||
after?: string | null;
|
||||
last?: number | null;
|
||||
before?: string | null;
|
||||
filter?: SaleFilterInput | null;
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/* eslint-disable */
|
||||
// This file was automatically generated and should not be edited.
|
||||
|
||||
import { LanguageCodeEnum } from "./../../types/globalTypes";
|
||||
import { LanguageCodeEnum, VoucherFilterInput } from "./../../types/globalTypes";
|
||||
|
||||
// ====================================================
|
||||
// GraphQL query operation: VoucherTranslations
|
||||
|
@ -57,4 +57,5 @@ export interface VoucherTranslationsVariables {
|
|||
after?: string | null;
|
||||
last?: number | null;
|
||||
before?: string | null;
|
||||
filter?: VoucherFilterInput | null;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
import { stringify as stringifyQs } from "qs";
|
||||
import urlJoin from "url-join";
|
||||
|
||||
import { Pagination } from "@saleor/types";
|
||||
import { TranslationsEntitiesListFilterTab } from "./components/TranslationsEntitiesListPage";
|
||||
|
||||
export enum TranslatableEntities {
|
||||
categories = "categories",
|
||||
products = "products",
|
||||
|
@ -18,12 +21,15 @@ export const languageListUrl = translationsSection;
|
|||
|
||||
export const languageEntitiesPath = (code: string) =>
|
||||
urlJoin(translationsSection, code);
|
||||
export const languageEntitiesUrl = (code: string, tab?: TranslatableEntities) =>
|
||||
languageEntitiesPath(code) +
|
||||
"?" +
|
||||
stringifyQs({
|
||||
tab
|
||||
});
|
||||
export type LanguageEntitiesUrlQueryParams = Pagination &
|
||||
Partial<{
|
||||
query: string;
|
||||
tab: TranslationsEntitiesListFilterTab;
|
||||
}>;
|
||||
export const languageEntitiesUrl = (
|
||||
code: string,
|
||||
params: LanguageEntitiesUrlQueryParams
|
||||
) => languageEntitiesPath(code) + "?" + stringifyQs(params);
|
||||
|
||||
export const languageEntityPath = (
|
||||
code: string,
|
||||
|
|
|
@ -104,10 +104,9 @@ const TranslationsCategories: React.FC<TranslationsCategoriesProps> = ({
|
|||
saveButtonState={saveButtonState}
|
||||
onBack={() =>
|
||||
navigate(
|
||||
languageEntitiesUrl(
|
||||
languageCode,
|
||||
TranslatableEntities.categories
|
||||
)
|
||||
languageEntitiesUrl(languageCode, {
|
||||
tab: TranslatableEntities.categories
|
||||
})
|
||||
)
|
||||
}
|
||||
onEdit={onEdit}
|
||||
|
|
|
@ -109,10 +109,9 @@ const TranslationsCollections: React.FC<TranslationsCollectionsProps> = ({
|
|||
onDiscard={onDiscard}
|
||||
onBack={() =>
|
||||
navigate(
|
||||
languageEntitiesUrl(
|
||||
languageCode,
|
||||
TranslatableEntities.collections
|
||||
)
|
||||
languageEntitiesUrl(languageCode, {
|
||||
tab: TranslatableEntities.collections
|
||||
})
|
||||
)
|
||||
}
|
||||
onLanguageChange={lang =>
|
||||
|
|
|
@ -8,11 +8,8 @@ import usePaginator, {
|
|||
import useShop from "@saleor/hooks/useShop";
|
||||
import { PAGINATE_BY } from "../../config";
|
||||
import { maybe } from "../../misc";
|
||||
import { Pagination } from "../../types";
|
||||
import TranslationsEntitiesList from "../components/TranslationsEntitiesList";
|
||||
import TranslationsEntitiesListPage, {
|
||||
TranslationsEntitiesListFilterTab
|
||||
} from "../components/TranslationsEntitiesListPage";
|
||||
import TranslationsEntitiesListPage from "../components/TranslationsEntitiesListPage";
|
||||
import {
|
||||
TypedCategoryTranslations,
|
||||
TypedCollectionTranslations,
|
||||
|
@ -24,18 +21,16 @@ import {
|
|||
} from "../queries";
|
||||
import { AttributeTranslationFragment } from "../types/AttributeTranslationFragment";
|
||||
import {
|
||||
languageEntitiesUrl,
|
||||
LanguageEntitiesUrlQueryParams,
|
||||
languageEntityUrl,
|
||||
languageListUrl,
|
||||
TranslatableEntities
|
||||
} from "../urls";
|
||||
|
||||
export type TranslationsEntitiesListQueryParams = Pagination & {
|
||||
tab: TranslationsEntitiesListFilterTab;
|
||||
};
|
||||
|
||||
interface TranslationsEntitiesProps {
|
||||
language: string;
|
||||
params: TranslationsEntitiesListQueryParams;
|
||||
params: LanguageEntitiesUrlQueryParams;
|
||||
}
|
||||
|
||||
function sumTranslations(
|
||||
|
@ -128,9 +123,29 @@ const TranslationsEntities: React.FC<TranslationsEntitiesProps> = ({
|
|||
shop.languages.find(languageFromList => languageFromList.code === language)
|
||||
);
|
||||
const paginationState = createPaginationState(PAGINATE_BY, params);
|
||||
const queryVariables = React.useMemo(
|
||||
() => ({
|
||||
...paginationState,
|
||||
filter: {
|
||||
search: params.query
|
||||
},
|
||||
language: language as any
|
||||
}),
|
||||
[params]
|
||||
);
|
||||
|
||||
return (
|
||||
<TranslationsEntitiesListPage
|
||||
initialSearch={params.query || ""}
|
||||
onSearchChange={query =>
|
||||
navigate(
|
||||
languageEntitiesUrl(language, {
|
||||
...params,
|
||||
query
|
||||
}),
|
||||
true
|
||||
)
|
||||
}
|
||||
filters={{
|
||||
current: params.tab,
|
||||
...filterCallbacks
|
||||
|
@ -139,9 +154,7 @@ const TranslationsEntities: React.FC<TranslationsEntitiesProps> = ({
|
|||
onBack={() => navigate(languageListUrl)}
|
||||
>
|
||||
{params.tab === "categories" ? (
|
||||
<TypedCategoryTranslations
|
||||
variables={{ language: language as any, ...paginationState }}
|
||||
>
|
||||
<TypedCategoryTranslations variables={queryVariables}>
|
||||
{({ data, loading }) => {
|
||||
const { loadNextPage, loadPreviousPage, pageInfo } = paginate(
|
||||
maybe(() => data.categories.pageInfo),
|
||||
|
@ -191,9 +204,7 @@ const TranslationsEntities: React.FC<TranslationsEntitiesProps> = ({
|
|||
}}
|
||||
</TypedCategoryTranslations>
|
||||
) : params.tab === "products" ? (
|
||||
<TypedProductTranslations
|
||||
variables={{ language: language as any, ...paginationState }}
|
||||
>
|
||||
<TypedProductTranslations variables={queryVariables}>
|
||||
{({ data, loading }) => {
|
||||
const { loadNextPage, loadPreviousPage, pageInfo } = paginate(
|
||||
maybe(() => data.products.pageInfo),
|
||||
|
@ -243,9 +254,7 @@ const TranslationsEntities: React.FC<TranslationsEntitiesProps> = ({
|
|||
}}
|
||||
</TypedProductTranslations>
|
||||
) : params.tab === "collections" ? (
|
||||
<TypedCollectionTranslations
|
||||
variables={{ language: language as any, ...paginationState }}
|
||||
>
|
||||
<TypedCollectionTranslations variables={queryVariables}>
|
||||
{({ data, loading }) => {
|
||||
const { loadNextPage, loadPreviousPage, pageInfo } = paginate(
|
||||
maybe(() => data.collections.pageInfo),
|
||||
|
@ -295,9 +304,7 @@ const TranslationsEntities: React.FC<TranslationsEntitiesProps> = ({
|
|||
}}
|
||||
</TypedCollectionTranslations>
|
||||
) : params.tab === "sales" ? (
|
||||
<TypedSaleTranslations
|
||||
variables={{ language: language as any, ...paginationState }}
|
||||
>
|
||||
<TypedSaleTranslations variables={queryVariables}>
|
||||
{({ data, loading }) => {
|
||||
const { loadNextPage, loadPreviousPage, pageInfo } = paginate(
|
||||
maybe(() => data.sales.pageInfo),
|
||||
|
@ -335,9 +342,7 @@ const TranslationsEntities: React.FC<TranslationsEntitiesProps> = ({
|
|||
}}
|
||||
</TypedSaleTranslations>
|
||||
) : params.tab === "vouchers" ? (
|
||||
<TypedVoucherTranslations
|
||||
variables={{ language: language as any, ...paginationState }}
|
||||
>
|
||||
<TypedVoucherTranslations variables={queryVariables}>
|
||||
{({ data, loading }) => {
|
||||
const { loadNextPage, loadPreviousPage, pageInfo } = paginate(
|
||||
maybe(() => data.vouchers.pageInfo),
|
||||
|
@ -379,9 +384,7 @@ const TranslationsEntities: React.FC<TranslationsEntitiesProps> = ({
|
|||
}}
|
||||
</TypedVoucherTranslations>
|
||||
) : params.tab === "pages" ? (
|
||||
<TypedPageTranslations
|
||||
variables={{ language: language as any, ...paginationState }}
|
||||
>
|
||||
<TypedPageTranslations variables={queryVariables}>
|
||||
{({ data, loading }) => {
|
||||
const { loadNextPage, loadPreviousPage, pageInfo } = paginate(
|
||||
maybe(() => data.pages.pageInfo),
|
||||
|
@ -427,9 +430,7 @@ const TranslationsEntities: React.FC<TranslationsEntitiesProps> = ({
|
|||
}}
|
||||
</TypedPageTranslations>
|
||||
) : params.tab === "productTypes" ? (
|
||||
<TypedProductTypeTranslations
|
||||
variables={{ language: language as any, ...paginationState }}
|
||||
>
|
||||
<TypedProductTypeTranslations variables={queryVariables}>
|
||||
{({ data, loading }) => {
|
||||
const { loadNextPage, loadPreviousPage, pageInfo } = paginate(
|
||||
maybe(() => data.productTypes.pageInfo),
|
||||
|
|
|
@ -14,7 +14,7 @@ const TranslationsLanguageList: React.FC = () => {
|
|||
<TranslationsLanguageListPage
|
||||
languages={maybe(() => shop.languages)}
|
||||
// onAdd={undefined}
|
||||
onRowClick={code => navigate(languageEntitiesUrl(code))}
|
||||
onRowClick={code => navigate(languageEntitiesUrl(code, {}))}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -104,10 +104,9 @@ const TranslationsPages: React.FC<TranslationsPagesProps> = ({
|
|||
saveButtonState={saveButtonState}
|
||||
onBack={() =>
|
||||
navigate(
|
||||
languageEntitiesUrl(
|
||||
languageCode,
|
||||
TranslatableEntities.pages
|
||||
)
|
||||
languageEntitiesUrl(languageCode, {
|
||||
tab: TranslatableEntities.pages
|
||||
})
|
||||
)
|
||||
}
|
||||
onEdit={onEdit}
|
||||
|
|
|
@ -144,10 +144,9 @@ const TranslationsProductTypes: React.FC<TranslationsProductTypesProps> = ({
|
|||
saveButtonState={saveButtonState}
|
||||
onBack={() =>
|
||||
navigate(
|
||||
languageEntitiesUrl(
|
||||
languageCode,
|
||||
TranslatableEntities.productTypes
|
||||
)
|
||||
languageEntitiesUrl(languageCode, {
|
||||
tab: TranslatableEntities.productTypes
|
||||
})
|
||||
)
|
||||
}
|
||||
onEdit={onEdit}
|
||||
|
|
|
@ -104,10 +104,9 @@ const TranslationsProducts: React.FC<TranslationsProductsProps> = ({
|
|||
saveButtonState={saveButtonState}
|
||||
onBack={() =>
|
||||
navigate(
|
||||
languageEntitiesUrl(
|
||||
languageCode,
|
||||
TranslatableEntities.products
|
||||
)
|
||||
languageEntitiesUrl(languageCode, {
|
||||
tab: TranslatableEntities.products
|
||||
})
|
||||
)
|
||||
}
|
||||
onEdit={onEdit}
|
||||
|
|
|
@ -98,10 +98,9 @@ const TranslationsSales: React.FC<TranslationsSalesProps> = ({
|
|||
saveButtonState={saveButtonState}
|
||||
onBack={() =>
|
||||
navigate(
|
||||
languageEntitiesUrl(
|
||||
languageCode,
|
||||
TranslatableEntities.sales
|
||||
)
|
||||
languageEntitiesUrl(languageCode, {
|
||||
tab: TranslatableEntities.sales
|
||||
})
|
||||
)
|
||||
}
|
||||
onEdit={onEdit}
|
||||
|
|
|
@ -101,10 +101,9 @@ const TranslationsVouchers: React.FC<TranslationsVouchersProps> = ({
|
|||
saveButtonState={saveButtonState}
|
||||
onBack={() =>
|
||||
navigate(
|
||||
languageEntitiesUrl(
|
||||
languageCode,
|
||||
TranslatableEntities.vouchers
|
||||
)
|
||||
languageEntitiesUrl(languageCode, {
|
||||
tab: TranslatableEntities.vouchers
|
||||
})
|
||||
)
|
||||
}
|
||||
onEdit={onEdit}
|
||||
|
|
|
@ -187,6 +187,16 @@ export enum PermissionEnum {
|
|||
MANAGE_USERS = "MANAGE_USERS",
|
||||
}
|
||||
|
||||
export enum ProductTypeConfigurable {
|
||||
CONFIGURABLE = "CONFIGURABLE",
|
||||
SIMPLE = "SIMPLE",
|
||||
}
|
||||
|
||||
export enum ProductTypeEnum {
|
||||
DIGITAL = "DIGITAL",
|
||||
SHIPPABLE = "SHIPPABLE",
|
||||
}
|
||||
|
||||
export enum SaleType {
|
||||
FIXED = "FIXED",
|
||||
PERCENTAGE = "PERCENTAGE",
|
||||
|
@ -520,6 +530,10 @@ export interface OrderUpdateShippingInput {
|
|||
shippingMethod?: string | null;
|
||||
}
|
||||
|
||||
export interface PageFilterInput {
|
||||
search?: string | null;
|
||||
}
|
||||
|
||||
export interface PageInput {
|
||||
slug?: string | null;
|
||||
title?: string | null;
|
||||
|
@ -560,6 +574,12 @@ export interface ProductFilterInput {
|
|||
minimalPrice?: PriceRangeInput | null;
|
||||
}
|
||||
|
||||
export interface ProductTypeFilterInput {
|
||||
search?: string | null;
|
||||
configurable?: ProductTypeConfigurable | null;
|
||||
productType?: ProductTypeEnum | null;
|
||||
}
|
||||
|
||||
export interface ProductTypeInput {
|
||||
name?: string | null;
|
||||
hasVariants?: boolean | null;
|
||||
|
|
Loading…
Reference in a new issue