Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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/late-parents-cross.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"saleor-dashboard": patch
---

Collection list filters have been ported to expression filtering. This means you can now use new filters in the Collection list.
11 changes: 11 additions & 0 deletions .featureFlags/collection_filters.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
name: collection_filters
displayName: Collection filtering
enabled: true
payload: "default"
visible: true
---

![new filters](./images/collection-filters.jpg)
Experience the new look and enhanced abilities of new filtering mechanism.
Easily combine any criteria you want, and quickly browse their values.
42 changes: 28 additions & 14 deletions .featureFlags/generated.tsx
Original file line number Diff line number Diff line change
@@ -1,30 +1,35 @@
// @ts-nocheck

import J53093 from "./images/customers-filters.png"
import Q09991 from "./images/discounts-list.png"
import Z15989 from "./images/draft-orders-filters.png"
import C33827 from "./images/gift-cards-filters.png"
import H90846 from "./images/improved_refunds.png"
import A12919 from "./images/page-filters.png"
import X74531 from "./images/vouchers-filters.png"
import W24585 from "./images/collection-filters.jpg"
import L16463 from "./images/customers-filters.png"
import L94878 from "./images/discounts-list.png"
import E09437 from "./images/draft-orders-filters.png"
import E78766 from "./images/gift-cards-filters.png"
import X68306 from "./images/improved_refunds.png"
import E85468 from "./images/page-filters.png"
import B37301 from "./images/vouchers-filters.png"

const customers_filters = () => (<><p><img src={J53093} alt="new filters"/>
const collection_filters = () => (<><p><img src={W24585} alt="new filters"/>
Experience the new look and enhanced abilities of new filtering mechanism.
Easily combine any criteria you want, and quickly browse their values.</p>
</>)
const customers_filters = () => (<><p><img src={L16463} alt="new filters"/>
Experience the new look and enhanced abilities of new fitering mechanism.
Easily combine any criteria you want, and quickly browse their values.</p>
</>)
const discounts_rules = () => (<><p><img src={Q09991} alt="Discount rules"/></p>
const discounts_rules = () => (<><p><img src={L94878} alt="Discount rules"/></p>
<p>Apply the new discounts rules to narrow your promotions audience.
Set up conditions and channels that must be fulfilled to apply defined reward.</p>
</>)
const draft_orders_filters = () => (<><p><img src={Z15989} alt="new filters"/>
const draft_orders_filters = () => (<><p><img src={E09437} alt="new filters"/>
Experience the new look and enhanced abilities of new fitering mechanism.
Easily combine any criteria you want, and quickly browse their values.</p>
</>)
const gift_cards_filters = () => (<><p><img src={C33827} alt="new filters"/>
const gift_cards_filters = () => (<><p><img src={E78766} alt="new filters"/>
Experience the new look and enhanced abilities of new fitering mechanism.
Easily combine any criteria you want, and quickly browse their values.</p>
</>)
const improved_refunds = () => (<><p><img src={H90846} alt="Improved refunds"/></p>
const improved_refunds = () => (<><p><img src={X68306} alt="Improved refunds"/></p>
<h3 id="enable-the-enhanced-refund-feature-to-streamline-your-refund-process">Enable the enhanced refund feature to streamline your refund process:</h3>
<ul>
<li><p>• Choose between automatic calculations based on selected items or enter refund amounts directly for overcharges and custom adjustments.</p>
Expand All @@ -34,16 +39,25 @@ const improved_refunds = () => (<><p><img src={H90846} alt="Improved refunds"/><
</ul>

</>)
const pages_filters = () => (<><p><img src={A12919} alt="new filters"/>
const pages_filters = () => (<><p><img src={E85468} alt="new filters"/>
Experience the new look and enhanced abilities of new fitering mechanism.
Easily combine any criteria you want, and quickly browse their values.</p>
</>)
const vouchers_filters = () => (<><p><img src={X74531} alt="new filters"/>
const vouchers_filters = () => (<><p><img src={B37301} alt="new filters"/>
Experience the new look and enhanced abilities of new fitering mechanism.
Easily combine any criteria you want, and quickly browse their values.</p>
</>)

export const AVAILABLE_FLAGS = [{
name: "collection_filters",
displayName: "Collection filtering",
component: collection_filters,
visible: true,
content: {
enabled: true,
payload: "default",
}
},{
name: "customers_filters",
displayName: "Customers filtering",
component: customers_filters,
Expand Down
Binary file added .featureFlags/images/collection-filters.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions locale/defaultMessages.json
Original file line number Diff line number Diff line change
Expand Up @@ -4938,6 +4938,9 @@
"context": "tax classes card header",
"string": "General information"
},
"ThUvIL": {
"string": "Hidden"
Copy link
Member

Choose a reason for hiding this comment

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

suggestion: Let's add context for these strings, e.g.:

Suggested change
"string": "Hidden"
"context": "Collection filter condition",
"string": "Hidden"

},
"TjGYna": {
"context": "product inventory, checkbox",
"string": "Track Inventory"
Expand Down Expand Up @@ -9262,6 +9265,9 @@
"w7jT4W": {
"string": "No channels selected"
},
"w7tf2z": {
"string": "Published"
Copy link
Member

Choose a reason for hiding this comment

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

suggestion: maybe we should use yes/no label values for this? When you look at the condition as a filter, then it looks incorrect:

CleanShot 2025-02-12 at 16 43 49@2x

Published is Published 😅

Copy link
Member

Choose a reason for hiding this comment

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

or maybe we can change the field name to Visibility, so that it becomes:

Visibility is Published
Visibility is Hidden

},
"w9xgN9": {
"context": "see error log label in notification",
"string": "See error log"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { DashboardCard } from "@dashboard/components/Card";
import { getByName } from "@dashboard/components/Filter/utils";
import { FilterPresetsSelect } from "@dashboard/components/FilterPresetsSelect";
import { ListPageLayout } from "@dashboard/components/Layouts";
import { useFlag } from "@dashboard/featureFlags";
import { getPrevLocationState } from "@dashboard/hooks/useBackLinkWithState";
import useNavigator from "@dashboard/hooks/useNavigator";
import { sectionNames } from "@dashboard/intl";
Expand Down Expand Up @@ -65,6 +66,7 @@ const CollectionListPage: React.FC<CollectionListPageProps> = ({
const navigate = useNavigator();
const filterStructure = createFilterStructure(intl, filterOpts);
const [isFilterPresetOpen, setFilterPresetOpen] = useState(false);
const { enabled: isNewCollectionListEnabled } = useFlag("collection_filters");
const filterDependency = filterStructure.find(getByName("channel"));

return (
Expand Down Expand Up @@ -116,27 +118,47 @@ const CollectionListPage: React.FC<CollectionListPageProps> = ({
</TopNav>

<DashboardCard>
<ListFilters
currencySymbol={currencySymbol}
initialSearch={initialSearch}
onFilterChange={onFilterChange}
onFilterAttributeFocus={onFilterAttributeFocus}
onSearchChange={onSearchChange}
filterStructure={filterStructure}
searchPlaceholder={intl.formatMessage({
id: "eRqx44",
defaultMessage: "Search collections...",
})}
actions={
<Box display="flex" gap={4}>
{selectedCollectionIds.length > 0 && (
<BulkDeleteButton onClick={onCollectionsDelete}>
<FormattedMessage defaultMessage="Delete collections" id="FTYkgw" />
</BulkDeleteButton>
)}
</Box>
}
/>
{isNewCollectionListEnabled ? (
<ListFilters
type="expression-filter"
initialSearch={initialSearch}
onSearchChange={onSearchChange}
searchPlaceholder={intl.formatMessage({
id: "eRqx44",
defaultMessage: "Search collections...",
})}
actions={
<Box display="flex" gap={4}>
{selectedCollectionIds.length > 0 && (
<BulkDeleteButton onClick={onCollectionsDelete}>
<FormattedMessage defaultMessage="Delete collections" id="FTYkgw" />
</BulkDeleteButton>
)}
</Box>
}
/>
) : (
<ListFilters
initialSearch={initialSearch}
onSearchChange={onSearchChange}
searchPlaceholder={intl.formatMessage({
id: "eRqx44",
defaultMessage: "Search collections...",
})}
actions={
<Box display="flex" gap={4}>
{selectedCollectionIds.length > 0 && (
<BulkDeleteButton onClick={onCollectionsDelete}>
<FormattedMessage defaultMessage="Delete collections" id="FTYkgw" />
</BulkDeleteButton>
)}
</Box>
}
onFilterChange={onFilterChange}
onFilterAttributeFocus={onFilterAttributeFocus}
filterStructure={filterStructure}
/>
)}

<CollectionListDatagrid
disabled={disabled}
Expand Down
7 changes: 6 additions & 1 deletion src/collections/index.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { ConditionalCollectionFilterProvider } from "@dashboard/components/ConditionalFilter";
import { Route } from "@dashboard/components/Router";
import { sectionNames } from "@dashboard/intl";
import { asSortParams } from "@dashboard/utils/sort";
Expand All @@ -24,7 +25,11 @@ const CollectionList: React.FC<RouteComponentProps<{}>> = ({ location }) => {
const qs = parseQs(location.search.substr(1)) as any;
const params: CollectionListUrlQueryParams = asSortParams(qs, CollectionListUrlSortField);

return <CollectionListView params={params} />;
return (
<ConditionalCollectionFilterProvider locationSearch={location.search}>
<CollectionListView params={params} />
</ConditionalCollectionFilterProvider>
);
};

interface CollectionDetailsRouteProps {
Expand Down
45 changes: 33 additions & 12 deletions src/collections/views/CollectionList/CollectionList.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
// @ts-strict-ignore
import ActionDialog from "@dashboard/components/ActionDialog";
import useAppChannel from "@dashboard/components/AppLayout/AppChannelContext";
import { useConditionalFilterContext } from "@dashboard/components/ConditionalFilter";
import { createCollectionsQueryVariables } from "@dashboard/components/ConditionalFilter/queryVariables";
import DeleteFilterTabDialog from "@dashboard/components/DeleteFilterTabDialog";
import SaveFilterTabDialog from "@dashboard/components/SaveFilterTabDialog";
import { useFlag } from "@dashboard/featureFlags";
import { useCollectionBulkDeleteMutation, useCollectionListQuery } from "@dashboard/graphql";
import { useFilterPresets } from "@dashboard/hooks/useFilterPresets";
import useListSettings from "@dashboard/hooks/useListSettings";
Expand Down Expand Up @@ -44,10 +47,11 @@ export const CollectionList: React.FC<CollectionListProps> = ({ params }) => {
const intl = useIntl();
const notify = useNotifier();
const { updateListSettings, settings } = useListSettings(ListViews.COLLECTION_LIST);
const { enabled: isNewCollectionFilterEnabled } = useFlag("collection_filters");
const { valueProvider } = useConditionalFilterContext();

usePaginationReset(collectionListUrl, params, settings.rowNumber);

const { channel } = useAppChannel(false);
const {
clearRowSelection,
selectedRowIds,
Expand All @@ -62,11 +66,10 @@ export const CollectionList: React.FC<CollectionListProps> = ({ params }) => {
params,
keepActiveTab: true,
});
const { availableChannels } = useAppChannel(false);
const { availableChannels, channel } = useAppChannel(false);
const channelOpts = availableChannels
? mapNodeToChoice(availableChannels, channel => channel.slug)
: null;
const selectedChannel = availableChannels.find(channel => channel.slug === params.channel);
const {
selectedPreset,
presets,
Expand All @@ -84,14 +87,28 @@ export const CollectionList: React.FC<CollectionListProps> = ({ params }) => {
storageUtils,
});
const paginationState = createPaginationState(settings.rowNumber, params);
const queryVariables = React.useMemo(
() => ({
const selectedChannel_legacy = availableChannels.find(channel => channel.slug === params.channel);
const queryVariables = React.useMemo(() => {
if (!isNewCollectionFilterEnabled) {
return {
...paginationState,
filter: getFilterVariables(params),
sort: getSortQueryVariables(params),
channel: selectedChannel_legacy?.slug,
};
}

const { channel, ...variables } = createCollectionsQueryVariables(valueProvider.value);

return {
...paginationState,
filter: getFilterVariables(params),
filter: variables,
sort: getSortQueryVariables(params),
channel: selectedChannel?.slug,
}),
[params, settings.rowNumber],
channel, // Saleor docs say 'channel' in filter is deprecated and should be moved to root
};
}, [params, settings.rowNumber, valueProvider.value, isNewCollectionFilterEnabled]);
const selectedChannel = availableChannels.find(
channel => channel.slug === queryVariables.channel,
);
const { data, refetch } = useCollectionListQuery({
displayLoader: true,
Expand All @@ -111,10 +128,9 @@ export const CollectionList: React.FC<CollectionListProps> = ({ params }) => {
}
},
});
const filterOpts = getFilterOpts(params, channelOpts);

useEffect(() => {
if (!canBeSorted(params.sort, !!selectedChannel)) {
if (!canBeSorted(params.sort, !!queryVariables.channel)) {
navigate(
collectionListUrl({
...params,
Expand Down Expand Up @@ -160,6 +176,11 @@ export const CollectionList: React.FC<CollectionListProps> = ({ params }) => {
clearRowSelection();
}, [selectedRowIds]);

const filterOpts = getFilterOpts(params, channelOpts);
const selectedChannelId = isNewCollectionFilterEnabled
? selectedChannel?.id
: selectedChannel_legacy?.id;

return (
<PaginatorContext.Provider value={paginationValues}>
<CollectionListPage
Expand All @@ -183,7 +204,7 @@ export const CollectionList: React.FC<CollectionListProps> = ({ params }) => {
onSort={handleSort}
onUpdateListSettings={updateListSettings}
sort={getSortParams(params)}
selectedChannelId={selectedChannel?.id}
selectedChannelId={selectedChannelId}
filterOpts={filterOpts}
onFilterChange={changeFilters}
selectedCollectionIds={selectedRowIds}
Expand Down
2 changes: 1 addition & 1 deletion src/components/ConditionalFilter/API/Handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ import { IntlShape } from "react-intl";

import { ItemOption } from "../FilterElement/ConditionValue";
import { LeftOperand } from "../LeftOperandsProvider";
import { getLocalizedLabel } from "./initialState/orders/intl";
import { getLocalizedLabel } from "./intl";

export interface Handler {
fetch: () => Promise<ItemOption[]>;
Expand Down
1 change: 0 additions & 1 deletion src/components/ConditionalFilter/API/index.ts

This file was deleted.

Loading
Loading