Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/flat-squids-bow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"saleor-dashboard": patch
---

You can now save,update and delete filter presets on product types list
14 changes: 7 additions & 7 deletions locale/defaultMessages.json
Original file line number Diff line number Diff line change
Expand Up @@ -582,10 +582,6 @@
"context": "expiry date section header",
"string": "Expiry date"
},
"1KSqnn": {
"context": "tab name",
"string": "All Product Types"
},
"1LBYpE": {
"context": "dialog header",
"string": "Delete Menus"
Expand Down Expand Up @@ -1675,6 +1671,9 @@
"context": "navigation section name",
"string": "Navigation"
},
"9CC8JI": {
"string": "Search product types..."
},
"9CEu8k": {
"context": "modal button images upload",
"string": "Upload Images"
Expand Down Expand Up @@ -7270,6 +7269,10 @@
"ivJ1qt": {
"string": "Manage your permission groups and their permissions"
},
"ivmwpV": {
"context": "tab name",
"string": "All product types"
},
"ixjvkM": {
"string": "We’ve created your default token. Make sure to copy your new personal access token now. You won’t be able to see it again."
},
Expand Down Expand Up @@ -8572,9 +8575,6 @@
"context": "expires in label",
"string": "Expires in"
},
"rpFdD1": {
"string": "Search Product Type"
},
"rqiCWU": {
"string": "Saved changes"
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,32 +1,30 @@
// @ts-strict-ignore
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question: can we get rid of this? or is it still needed for some reason?
if so we can add a comment ;)

import { ListFilters } from "@dashboard/components/AppLayout/ListFilters";
import { TopNav } from "@dashboard/components/AppLayout/TopNav";
import { Button } from "@dashboard/components/Button";
import { DashboardCard } from "@dashboard/components/Card";
import FilterBar from "@dashboard/components/FilterBar";
import { configurationMenuUrl } from "@dashboard/configuration";
import { FilterPresetsSelect } from "@dashboard/components/FilterPresetsSelect";
import { ListPageLayout } from "@dashboard/components/Layouts";
import { ProductTypeFragment } from "@dashboard/graphql";
import useNavigator from "@dashboard/hooks/useNavigator";
import { sectionNames } from "@dashboard/intl";
import ProductTypeList from "@dashboard/productTypes/components/ProductTypeList/ProductTypeList";
import { productTypeAddUrl, ProductTypeListUrlSortField } from "@dashboard/productTypes/urls";
import React from "react";
import { Box, Button, ChevronRightIcon } from "@saleor/macaw-ui-next";
import React, { useState } from "react";
import { FormattedMessage, useIntl } from "react-intl";

import {
FilterPageProps,
ListActions,
PageListProps,
SortPage,
TabPageProps,
} from "../../../types";
import { FilterPageProps, ListActions, PageListProps, SortPage } from "../../../types";
import { createFilterStructure, ProductTypeFilterKeys, ProductTypeListFilterOpts } from "./filters";

export interface ProductTypeListPageProps
extends PageListProps,
ListActions,
FilterPageProps<ProductTypeFilterKeys, ProductTypeListFilterOpts>,
SortPage<ProductTypeListUrlSortField>,
TabPageProps {
Omit<FilterPageProps<ProductTypeFilterKeys, ProductTypeListFilterOpts>, "onTabDelete">,
SortPage<ProductTypeListUrlSortField> {
productTypes: ProductTypeFragment[];
onTabUpdate: (tabName: string) => void;
onTabDelete: (id: number) => void;
hasPresetsChanged: () => boolean;
}

const ProductTypeListPage: React.FC<ProductTypeListPageProps> = ({
Expand All @@ -39,44 +37,80 @@
onTabChange,
onTabDelete,
onTabSave,
onTabUpdate,
tabs,
hasPresetsChanged,
disabled,
...listProps
}) => {
const intl = useIntl();
const structure = createFilterStructure(intl, filterOpts);
const navigate = useNavigator();
const [isFilterPresetOpen, setFilterPresetOpen] = useState(false);
const filterStructure = createFilterStructure(intl, filterOpts);

Check warning on line 49 in src/productTypes/components/ProductTypeListPage/ProductTypeListPage.tsx

View check run for this annotation

Codecov / codecov/patch

src/productTypes/components/ProductTypeListPage/ProductTypeListPage.tsx#L47-L49

Added lines #L47 - L49 were not covered by tests

return (
<>
<TopNav href={configurationMenuUrl} title={intl.formatMessage(sectionNames.productTypes)}>
<Button variant="primary" href={productTypeAddUrl()} data-test-id="add-product-type">
<FormattedMessage id="gksZwp" defaultMessage="Create product type" description="button" />
</Button>
<ListPageLayout>
<TopNav
withoutBorder
isAlignToRight={false}
title={intl.formatMessage(sectionNames.productTypes)}
>
<Box __flex={1} display="flex" justifyContent="space-between" alignItems="center">
<Box display="flex">
<Box marginX={3} display="flex" alignItems="center">
<ChevronRightIcon />
</Box>

<FilterPresetsSelect
presetsChanged={hasPresetsChanged()}
onSelect={onTabChange}
onRemove={onTabDelete}
onUpdate={onTabUpdate}
savedPresets={tabs}
activePreset={currentTab}
onSelectAll={onAll}
onSave={onTabSave}
isOpen={isFilterPresetOpen}
onOpenChange={setFilterPresetOpen}
selectAllLabel={intl.formatMessage({
id: "ivmwpV",
defaultMessage: "All product types",
description: "tab name",
})}
/>
</Box>
<Box>
<Button
disabled={disabled}
variant="primary"
onClick={() => navigate(productTypeAddUrl())}

Check warning on line 86 in src/productTypes/components/ProductTypeListPage/ProductTypeListPage.tsx

View check run for this annotation

Codecov / codecov/patch

src/productTypes/components/ProductTypeListPage/ProductTypeListPage.tsx#L86

Added line #L86 was not covered by tests
data-test-id="create-product-type"
>
<FormattedMessage
id="gksZwp"
defaultMessage="Create product type"
description="button"
/>
</Button>
</Box>
</Box>
</TopNav>
<DashboardCard>
<FilterBar
allTabLabel={intl.formatMessage({
id: "1KSqnn",
defaultMessage: "All Product Types",
description: "tab name",
})}
currentTab={currentTab}
filterStructure={structure}

<DashboardCard gap={0}>
<ListFilters
initialSearch={initialSearch}
onSearchChange={onSearchChange}
searchPlaceholder={intl.formatMessage({
id: "rpFdD1",
defaultMessage: "Search Product Type",
id: "9CC8JI",
defaultMessage: "Search product types...",
})}
tabs={tabs}
onAll={onAll}
onFilterChange={onFilterChange}
onSearchChange={onSearchChange}
onTabChange={onTabChange}
onTabDelete={onTabDelete}
onTabSave={onTabSave}
filterStructure={filterStructure}
/>
<ProductTypeList {...listProps} />

<ProductTypeList {...listProps} disabled={disabled} />
</DashboardCard>
</>
</ListPageLayout>
);
};

Expand Down
73 changes: 33 additions & 40 deletions src/productTypes/views/ProductTypeList/ProductTypeList.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
// @ts-strict-ignore
import DeleteFilterTabDialog from "@dashboard/components/DeleteFilterTabDialog";
import SaveFilterTabDialog, {
SaveFilterTabDialogFormData,
} from "@dashboard/components/SaveFilterTabDialog";
import SaveFilterTabDialog from "@dashboard/components/SaveFilterTabDialog";
import { useProductTypeBulkDeleteMutation, useProductTypeListQuery } from "@dashboard/graphql";
import useBulkActions from "@dashboard/hooks/useBulkActions";
import { useFilterPresets } from "@dashboard/hooks/useFilterPresets";
import useListSettings from "@dashboard/hooks/useListSettings";
import useNavigator from "@dashboard/hooks/useNavigator";
import useNotifier from "@dashboard/hooks/useNotifier";
Expand Down Expand Up @@ -33,16 +32,7 @@ import {
ProductTypeListUrlDialog,
ProductTypeListUrlQueryParams,
} from "../../urls";
import {
deleteFilterTab,
getActiveFilters,
getFilterOpts,
getFilterQueryParam,
getFiltersCurrentTab,
getFilterTabs,
getFilterVariables,
saveFilterTab,
} from "./filters";
import { getFilterOpts, getFilterQueryParam, getFilterVariables, storageUtils } from "./filters";
import { getSortQueryVariables } from "./sort";

interface ProductTypeListProps {
Expand Down Expand Up @@ -77,8 +67,6 @@ export const ProductTypeList: React.FC<ProductTypeListProps> = ({ params }) => {
displayLoader: true,
variables: queryVariables,
});
const tabs = getFilterTabs();
const currentTab = getFiltersCurrentTab(params, tabs);
const [changeFilters, resetFilters, handleSearchChange] = createFilterHandlers({
cleanupFn: reset,
createUrl: productTypeListUrl,
Expand All @@ -90,24 +78,24 @@ export const ProductTypeList: React.FC<ProductTypeListProps> = ({ params }) => {
ProductTypeListUrlDialog,
ProductTypeListUrlQueryParams
>(navigate, productTypeListUrl, params);
const handleTabChange = (tab: number) => {
reset();
navigate(
productTypeListUrl({
activeTab: tab.toString(),
...getFilterTabs()[tab - 1].data,
}),
);
};
const handleTabDelete = () => {
deleteFilterTab(currentTab);
reset();
navigate(productTypeListUrl());
};
const handleTabSave = (data: SaveFilterTabDialogFormData) => {
saveFilterTab(data.name, getActiveFilters(params));
handleTabChange(tabs.length + 1);
};

const {
selectedPreset,
presets,
hasPresetsChanged,
onPresetChange,
onPresetDelete,
onPresetSave,
onPresetUpdate,
setPresetIdToDelete,
getPresetNameToDelete,
} = useFilterPresets({
params,
reset,
getUrl: productTypeListUrl,
storageUtils,
});

const paginationValues = usePaginator({
pageInfo: maybe(() => data.productTypes.pageInfo),
paginationState,
Expand Down Expand Up @@ -150,16 +138,20 @@ export const ProductTypeList: React.FC<ProductTypeListProps> = ({ params }) => {
return (
<PaginatorContext.Provider value={paginationValues}>
<ProductTypeListPage
currentTab={currentTab}
currentTab={selectedPreset}
filterOpts={getFilterOpts(params)}
initialSearch={params.query || ""}
onSearchChange={handleSearchChange}
onFilterChange={changeFilters}
onAll={resetFilters}
onTabChange={handleTabChange}
onTabDelete={() => openModal("delete-search")}
onTabChange={onPresetChange}
onTabDelete={(id: number) => {
setPresetIdToDelete(id);
openModal("delete-search");
}}
onTabSave={() => openModal("save-search")}
tabs={tabs.map(tab => tab.name)}
onTabUpdate={onPresetUpdate}
tabs={presets.map(tab => tab.name)}
disabled={loading}
productTypes={productTypesData}
onSort={handleSort}
Expand All @@ -182,6 +174,7 @@ export const ProductTypeList: React.FC<ProductTypeListProps> = ({ params }) => {
<DeleteIcon />
</IconButton>
}
hasPresetsChanged={hasPresetsChanged}
/>
{productTypesData && (
<TypeDeleteWarningDialog
Expand All @@ -197,14 +190,14 @@ export const ProductTypeList: React.FC<ProductTypeListProps> = ({ params }) => {
open={params.action === "save-search"}
confirmButtonState="default"
onClose={closeModal}
onSubmit={handleTabSave}
onSubmit={onPresetSave}
/>
<DeleteFilterTabDialog
open={params.action === "delete-search"}
confirmButtonState="default"
onClose={closeModal}
onSubmit={handleTabDelete}
tabName={maybe(() => tabs[currentTab - 1].name, "...")}
onSubmit={onPresetDelete}
tabName={getPresetNameToDelete()}
/>
</PaginatorContext.Provider>
);
Expand Down
3 changes: 1 addition & 2 deletions src/productTypes/views/ProductTypeList/filters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,7 @@ export function getFilterQueryParam(
}
}

export const { deleteFilterTab, getFilterTabs, saveFilterTab } =
createFilterTabUtils<ProductTypeListUrlFilters>(PRODUCT_TYPE_FILTERS_KEY);
export const storageUtils = createFilterTabUtils<string>(PRODUCT_TYPE_FILTERS_KEY);

export const { areFiltersApplied, getActiveFilters, getFiltersCurrentTab } = createFilterUtils<
ProductTypeListUrlQueryParams,
Expand Down
Loading