Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Back links with pagination and filters #5200

Merged
merged 10 commits into from
Oct 14, 2024
5 changes: 5 additions & 0 deletions .changeset/pretty-cobras-remember.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"saleor-dashboard": patch
---

Back buttons now navigate to the list with previously used filters and pagination applied.
5 changes: 5 additions & 0 deletions .changeset/thick-kiwis-study.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"saleor-dashboard": patch
---

When navigating to order details from the order list, the back button will now return you to the previous page with the same filters and pagination applied.
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { Item } from "@glideapps/glide-data-grid";
import { Box } from "@saleor/macaw-ui-next";
import React, { useCallback, useMemo } from "react";
import { useIntl } from "react-intl";
import { useLocation } from "react-router";

import { attributesListStaticColumnsAdapter, createGetCellContent } from "./datagrid";
import { messages } from "./messages";
Expand All @@ -33,6 +34,7 @@ export const AttributeListDatagrid = ({
onUpdateListSettings,
}: AttributeListDatagridProps) => {
const datagridState = useDatagridChangeState();
const location = useLocation();
const navigate = useNavigator();
const intl = useIntl();
const attributesListStaticColumns = useMemo(
Expand Down Expand Up @@ -66,7 +68,11 @@ export const AttributeListDatagrid = ({
const rowData: AttributeFragment = attributes[row];

if (rowData) {
navigate(attributeUrl(rowData.id));
navigate(attributeUrl(rowData.id), {
state: {
prevLocation: location,
},
});
}
},
[attributes],
Expand Down
11 changes: 8 additions & 3 deletions src/attributes/components/AttributePage/AttributePage.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { attributeListUrl } from "@dashboard/attributes/urls";
import { attributeListPath } from "@dashboard/attributes/urls";
import { ATTRIBUTE_TYPES_WITH_DEDICATED_VALUES } from "@dashboard/attributes/utils/data";
import { TopNav } from "@dashboard/components/AppLayout/TopNav";
import CardSpacer from "@dashboard/components/CardSpacer";
Expand All @@ -18,6 +18,7 @@ import {
AttributeTypeEnum,
MeasurementUnitsEnum,
} from "@dashboard/graphql";
import { useBackLinkWithState } from "@dashboard/hooks/useBackLinkWithState";
import { SubmitPromise } from "@dashboard/hooks/useForm";
import useNavigator from "@dashboard/hooks/useNavigator";
import { ListSettings, ReorderAction } from "@dashboard/types";
Expand Down Expand Up @@ -135,6 +136,10 @@ const AttributePage: React.FC<AttributePageProps> = ({
});
};

const attributePageBackLink = useBackLinkWithState({
path: attributeListPath,
});

return (
<Form confirmLeave initial={initialForm} onSubmit={handleSubmit} disabled={disabled}>
{({ change, set, data, isSaveDisabled, submit, errors, setError, clearErrors }) => {
Expand All @@ -144,7 +149,7 @@ const AttributePage: React.FC<AttributePageProps> = ({
<>
<DetailPageLayout>
<TopNav
href={attributeListUrl()}
href={attributePageBackLink}
title={
attribute === null
? intl.formatMessage({
Expand Down Expand Up @@ -207,7 +212,7 @@ const AttributePage: React.FC<AttributePageProps> = ({
<Savebar>
{attribute !== null && <Savebar.DeleteButton onClick={onDelete} />}
<Savebar.Spacer />
<Savebar.CancelButton onClick={() => navigate(attributeListUrl())} />
<Savebar.CancelButton onClick={() => navigate(attributePageBackLink)} />
<Savebar.ConfirmButton
transitionState={saveButtonBarState}
onClick={submit}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { Item } from "@glideapps/glide-data-grid";
import { Box } from "@saleor/macaw-ui-next";
import React, { ReactNode, useCallback, useMemo } from "react";
import { useIntl } from "react-intl";
import { useLocation } from "react-router";

import { categoryListStaticColumnsAdapter, createGetCellContent } from "./datagrid";
import { messages } from "./messages";
Expand All @@ -37,6 +38,7 @@ export const CategoryListDatagrid = ({
selectionActionButton = null,
hasRowHover = true,
}: CategoryListDatagridProps) => {
const location = useLocation();
const datagridState = useDatagridChangeState();
const intl = useIntl();
const memoizedStaticColumns = useMemo(
Expand Down Expand Up @@ -103,6 +105,11 @@ export const CategoryListDatagrid = ({
staticColumns={staticColumns}
/>
)}
navigatorOpts={{
state: {
prevLocation: location,
},
}}
/>

<Box paddingX={6}>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { categoryListUrl, categoryUrl } from "@dashboard/categories/urls";
import { categoryListPath, categoryUrl } from "@dashboard/categories/urls";
import { TopNav } from "@dashboard/components/AppLayout/TopNav";
import { CardSpacer } from "@dashboard/components/CardSpacer";
import { ConfirmButtonTransitionState } from "@dashboard/components/ConfirmButton";
Expand All @@ -8,6 +8,7 @@ import { Savebar } from "@dashboard/components/Savebar";
import { SeoForm } from "@dashboard/components/SeoForm";
import { Tab, TabContainer } from "@dashboard/components/Tab";
import { CategoryDetailsQuery, ProductErrorFragment } from "@dashboard/graphql";
import { useBackLinkWithState } from "@dashboard/hooks/useBackLinkWithState";
import { SubmitPromise } from "@dashboard/hooks/useForm";
import useNavigator from "@dashboard/hooks/useNavigator";
import { sprinkles } from "@saleor/macaw-ui-next";
Expand Down Expand Up @@ -74,7 +75,12 @@ export const CategoryUpdatePage: React.FC<CategoryUpdatePageProps> = ({
}: CategoryUpdatePageProps) => {
const intl = useIntl();
const navigate = useNavigator();
const backHref = category?.parent?.id ? categoryUrl(category?.parent?.id) : categoryListUrl();

const categoryBackListUrl = useBackLinkWithState({
path: categoryListPath,
});

const backHref = category?.parent?.id ? categoryUrl(category?.parent?.id) : categoryBackListUrl;

return (
<CategoryUpdateForm category={category} onSubmit={onSubmit} disabled={disabled}>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// @ts-strict-ignore
import { ChannelCollectionData } from "@dashboard/channels/utils";
import { collectionListUrl } from "@dashboard/collections/urls";
import { collectionListPath } from "@dashboard/collections/urls";
import { TopNav } from "@dashboard/components/AppLayout/TopNav";
import { CardSpacer } from "@dashboard/components/CardSpacer";
import ChannelsAvailabilityCard from "@dashboard/components/ChannelsAvailabilityCard";
Expand All @@ -15,6 +15,7 @@ import {
CollectionErrorFragment,
PermissionEnum,
} from "@dashboard/graphql";
import { useBackLinkWithState } from "@dashboard/hooks/useBackLinkWithState";
import { SubmitPromise } from "@dashboard/hooks/useForm";
import useNavigator from "@dashboard/hooks/useNavigator";
import React from "react";
Expand Down Expand Up @@ -62,6 +63,10 @@ const CollectionDetailsPage: React.FC<CollectionDetailsPageProps> = ({
const intl = useIntl();
const navigate = useNavigator();

const collectionListBackLink = useBackLinkWithState({
path: collectionListPath,
});

return (
<CollectionUpdateForm
collection={collection}
Expand All @@ -72,7 +77,7 @@ const CollectionDetailsPage: React.FC<CollectionDetailsPageProps> = ({
>
{({ change, data, handlers, submit, isSaveDisabled }) => (
<DetailPageLayout>
<TopNav href={collectionListUrl()} title={collection?.name} />
<TopNav href={collectionListBackLink} title={collection?.name} />
<DetailPageLayout.Content>
<CollectionDetails data={data} disabled={disabled} errors={errors} onChange={change} />
<CardSpacer />
Expand Down Expand Up @@ -138,7 +143,7 @@ const CollectionDetailsPage: React.FC<CollectionDetailsPageProps> = ({
<Savebar>
<Savebar.DeleteButton onClick={onCollectionRemove} />
<Savebar.Spacer />
<Savebar.CancelButton onClick={() => navigate(collectionListUrl())} />
<Savebar.CancelButton onClick={() => navigate(collectionListBackLink)} />
<Savebar.ConfirmButton
transitionState={saveButtonBarState}
onClick={submit}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { FilterPageProps, PageListProps, SortPage } from "@dashboard/types";
import { Box, Button, ChevronRightIcon } from "@saleor/macaw-ui-next";
import React, { useState } from "react";
import { FormattedMessage, useIntl } from "react-intl";
import { useLocation } from "react-router";

import { CollectionListDatagrid } from "../CollectionListDatagrid";
import { CollectionFilterKeys, CollectionListFilterOpts, createFilterStructure } from "./filters";
Expand Down Expand Up @@ -59,6 +60,7 @@ const CollectionListPage: React.FC<CollectionListPageProps> = ({
...listProps
}) => {
const intl = useIntl();
const location = useLocation();
const navigate = useNavigator();
const filterStructure = createFilterStructure(intl, filterOpts);
const [isFilterPresetOpen, setFilterPresetOpen] = useState(false);
Expand Down Expand Up @@ -140,7 +142,11 @@ const CollectionListPage: React.FC<CollectionListPageProps> = ({
selectedChannelId={selectedChannelId}
filterDependency={filterDependency}
onRowClick={id => {
navigate(collectionUrl(id));
navigate(collectionUrl(id), {
state: {
prevLocation: location,
},
});
}}
hasRowHover={!isFilterPresetOpen}
rowAnchor={collectionUrl}
Expand Down
6 changes: 4 additions & 2 deletions src/components/Datagrid/Datagrid.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import "@glideapps/glide-data-grid/dist/index.css";

import useNavigator from "@dashboard/hooks/useNavigator";
import useNavigator, { NavigatorOpts } from "@dashboard/hooks/useNavigator";
import { usePreventHistoryBack } from "@dashboard/hooks/usePreventHistoryBack";
import { getCellAction } from "@dashboard/products/components/ProductListDatagrid/datagrid";
import DataEditor, {
Expand Down Expand Up @@ -98,6 +98,7 @@ export interface DatagridProps {
recentlyAddedColumn?: string | null; // Enables scroll to recently added column
onClearRecentlyAddedColumn?: () => void;
renderHeader?: (props: DatagridRenderHeaderProps) => ReactNode;
navigatorOpts?: NavigatorOpts;
}

export const Datagrid: React.FC<DatagridProps> = ({
Expand Down Expand Up @@ -130,6 +131,7 @@ export const Datagrid: React.FC<DatagridProps> = ({
onClearRecentlyAddedColumn,
rowHeight = cellHeight,
renderHeader,
navigatorOpts,
...datagridProps
}): ReactElement => {
const classes = useStyles({ actionButtonPosition });
Expand Down Expand Up @@ -531,7 +533,7 @@ export const Datagrid: React.FC<DatagridProps> = ({
e.preventDefault();

if (e.currentTarget.dataset.reactRouterPath) {
navigate(e.currentTarget.dataset.reactRouterPath);
navigate(e.currentTarget.dataset.reactRouterPath, navigatorOpts);
}
}}
/>
Expand Down
8 changes: 5 additions & 3 deletions src/components/TableRowLink/TableRowLink.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@ import { TableRow, TableRowTypeMap } from "@material-ui/core";
import { makeStyles } from "@saleor/macaw-ui";
import clsx from "clsx";
import React, { forwardRef } from "react";
import { Link } from "react-router-dom";
import { Link, LinkProps } from "react-router-dom";

type MaterialTableRowPropsType = TableRowTypeMap["props"];

type LocationDescriptor = LinkProps["to"];

export interface TableRowLinkProps extends MaterialTableRowPropsType {
children: React.ReactNode;
href?: string;
href?: string | LocationDescriptor;
className?: string;
linkClassName?: string;
onClick?: () => void;
Expand All @@ -28,7 +30,7 @@ const TableRowLink = forwardRef<HTMLTableRowElement, TableRowLinkProps>((props,
const { href, children, linkClassName, onClick, ...restProps } = props;
const classes = useStyles();

if (!href || isExternalURL(href)) {
if (!href || (typeof href === "string" && isExternalURL(href))) {
return (
<TableRow ref={ref} hover={!!onClick} onClick={onClick} {...restProps}>
{children}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@ import { Metadata } from "@dashboard/components/Metadata/Metadata";
import { MetadataFormData } from "@dashboard/components/Metadata/types";
import RequirePermissions from "@dashboard/components/RequirePermissions";
import { Savebar } from "@dashboard/components/Savebar";
import { customerAddressesUrl, customerListUrl } from "@dashboard/customers/urls";
import { customerAddressesUrl, customerListPath } from "@dashboard/customers/urls";
import CustomerGiftCardsCard from "@dashboard/giftCards/components/GiftCardCustomerCard/CustomerGiftCardsCard";
import { AccountErrorFragment, CustomerDetailsQuery, PermissionEnum } from "@dashboard/graphql";
import { useBackLinkWithState } from "@dashboard/hooks/useBackLinkWithState";
import { SubmitPromise } from "@dashboard/hooks/useForm";
import useNavigator from "@dashboard/hooks/useNavigator";
import { sectionNames } from "@dashboard/intl";
Expand Down Expand Up @@ -81,18 +82,22 @@ const CustomerDetailsPage: React.FC<CustomerDetailsPageProps> = ({
customerId,
);

const customerBackLink = useBackLinkWithState({
path: customerListPath,
});

return (
<Form confirmLeave initial={initialForm} onSubmit={onSubmit} disabled={disabled}>
{({ change, data, isSaveDisabled, submit }) => {
const changeMetadata = makeMetadataChangeHandler(change);

return (
<DetailPageLayout>
<TopNav href={customerListUrl()} title={getUserName(customer, true)}>
<TopNav href={customerBackLink} title={getUserName(customer, true)}>
{extensionMenuItems.length > 0 && <CardMenu menuItems={extensionMenuItems} />}
</TopNav>
<DetailPageLayout.Content>
<Backlink href={customerListUrl()}>
<Backlink href={customerBackLink}>
{intl.formatMessage(sectionNames.customers)}
</Backlink>
<CustomerDetails
Expand Down Expand Up @@ -132,7 +137,7 @@ const CustomerDetailsPage: React.FC<CustomerDetailsPageProps> = ({
<Savebar>
<Savebar.DeleteButton onClick={onDelete} />
<Savebar.Spacer />
<Savebar.CancelButton onClick={() => navigate(customerListUrl())} />
<Savebar.CancelButton onClick={() => navigate(customerBackLink)} />
<Savebar.ConfirmButton
transitionState={saveButtonBar}
onClick={submit}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { Item } from "@glideapps/glide-data-grid";
import { Box } from "@saleor/macaw-ui-next";
import React, { useCallback, useMemo } from "react";
import { useIntl } from "react-intl";
import { useLocation } from "react-router";

import { createGetCellContent, customerListStaticColumnsAdapter } from "./datagrid";
import { messages } from "./messages";
Expand Down Expand Up @@ -42,6 +43,7 @@ export const CustomerListDatagrid = ({
onSort,
}: CustomerListDatagridProps) => {
const intl = useIntl();
const location = useLocation();
const datagrid = useDatagridChangeState();
const userPermissions = useUserPermissions();
const hasManageOrdersPermission =
Expand Down Expand Up @@ -135,6 +137,11 @@ export const CustomerListDatagrid = ({
onToggle={handlers.onToggle}
/>
)}
navigatorOpts={{
state: {
prevLocation: location,
},
}}
/>

<Box paddingX={6}>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { TopNav } from "@dashboard/components/AppLayout";
import { ConfirmButtonTransitionState } from "@dashboard/components/ConfirmButton";
import { DetailPageLayout } from "@dashboard/components/Layouts";
import { discountListUrl } from "@dashboard/discounts/discountsUrls";
import { Rule } from "@dashboard/discounts/models";
import { DiscoutFormData } from "@dashboard/discounts/types";
import {
Expand Down Expand Up @@ -38,6 +37,7 @@ export interface DiscountDetailsPageProps {
onRuleDeleteSubmit: (id: string) => void;
ruleDeleteButtonState: ConfirmButtonTransitionState;
onBack: () => void;
backLinkHref: string;
}

export const DiscountDetailsPage = ({
Expand All @@ -55,13 +55,14 @@ export const DiscountDetailsPage = ({
ruleCreateButtonState,
ruleUpdateButtonState,
ruleDeleteButtonState,
backLinkHref,
}: DiscountDetailsPageProps) => {
const intl = useIntl();
const formErrors = getFormErrors(["name"], errors);

return (
<DetailPageLayout gridTemplateColumns={1}>
<TopNav href={discountListUrl()} title={data?.name} />
<TopNav href={backLinkHref} title={data?.name} />
<DetailPageLayout.Content>
<DiscountDetailsForm
data={data}
Expand Down
Loading
Loading