Introduce new column picker in Order Draft list (#3869)

This commit is contained in:
Paweł Chyła 2023-07-10 11:28:25 +02:00 committed by GitHub
parent 0ea8f32378
commit 391b429fce
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 93 additions and 84 deletions

View file

@ -0,0 +1,5 @@
---
"saleor-dashboard": minor
---
Introduce new column picker in Order Draft list datagrid

View file

@ -81,6 +81,7 @@ export const defaultListSettings: AppListViewSettings = {
}, },
[ListViews.DRAFT_LIST]: { [ListViews.DRAFT_LIST]: {
rowNumber: PAGINATE_BY, rowNumber: PAGINATE_BY,
columns: ["number", "date", "customer", "total"],
}, },
[ListViews.NAVIGATION_LIST]: { [ListViews.NAVIGATION_LIST]: {
rowNumber: PAGINATE_BY, rowNumber: PAGINATE_BY,

View file

@ -1,32 +1,34 @@
// @ts-strict-ignore import { ColumnPicker } from "@dashboard/components/Datagrid/ColumnPicker/ColumnPicker";
import ColumnPicker from "@dashboard/components/ColumnPicker/ColumnPicker"; import { useColumns } from "@dashboard/components/Datagrid/ColumnPicker/useColumns";
import Datagrid from "@dashboard/components/Datagrid/Datagrid"; import Datagrid from "@dashboard/components/Datagrid/Datagrid";
import { useColumnsDefault } from "@dashboard/components/Datagrid/hooks/useColumnsDefault";
import { import {
DatagridChangeStateContext, DatagridChangeStateContext,
useDatagridChangeState, useDatagridChangeState,
} from "@dashboard/components/Datagrid/hooks/useDatagridChange"; } from "@dashboard/components/Datagrid/hooks/useDatagridChange";
import { TablePaginationWithContext } from "@dashboard/components/TablePagination"; import { TablePaginationWithContext } from "@dashboard/components/TablePagination";
import { OrderDraftListQuery } from "@dashboard/graphql";
import useLocale from "@dashboard/hooks/useLocale"; import useLocale from "@dashboard/hooks/useLocale";
import { OrderDraft } from "@dashboard/orders/types";
import { OrderDraftListUrlSortField, orderUrl } from "@dashboard/orders/urls"; import { OrderDraftListUrlSortField, orderUrl } from "@dashboard/orders/urls";
import { ListProps, RelayToFlat, SortPage } from "@dashboard/types"; import { ListProps, SortPage } from "@dashboard/types";
import { Item } from "@glideapps/glide-data-grid"; import { Item } from "@glideapps/glide-data-grid";
import { Box } from "@saleor/macaw-ui/next"; import { Box } from "@saleor/macaw-ui/next";
import React, { useCallback, useMemo } from "react"; import React, { useCallback, useMemo } from "react";
import { useIntl } from "react-intl"; import { useIntl } from "react-intl";
import { createGetCellContent, getColumns } from "./datagrid"; import {
createGetCellContent,
orderDraftListStaticColumnsAdapter,
} from "./datagrid";
import { messages } from "./messages"; import { messages } from "./messages";
import { canBeSorted } from "./utils"; import { canBeSorted } from "./utils";
interface OrderDraftListDatagridProps interface OrderDraftListDatagridProps
extends ListProps, extends ListProps,
SortPage<OrderDraftListUrlSortField> { SortPage<OrderDraftListUrlSortField> {
orders: RelayToFlat<OrderDraftListQuery["draftOrders"]>; orders: OrderDraft[];
hasRowHover?: boolean; hasRowHover?: boolean;
onRowClick?: (id: string) => void; onRowClick?: (id: string) => void;
onSelectOrderDraftIds; onSelectOrderDraftIds: (ids: number[], clearSelection: () => void) => void;
} }
export const OrderDraftListDatagrid = ({ export const OrderDraftListDatagrid = ({
@ -44,33 +46,40 @@ export const OrderDraftListDatagrid = ({
const { locale } = useLocale(); const { locale } = useLocale();
const datagridState = useDatagridChangeState(); const datagridState = useDatagridChangeState();
const availableColumns = useMemo(() => getColumns(intl, sort), [intl, sort]); const handleColumnChange = useCallback(
picked => {
if (onUpdateListSettings) {
onUpdateListSettings("columns", picked.filter(Boolean));
}
},
[onUpdateListSettings],
);
const { const memoizedStaticColumns = useMemo(
columns, () => orderDraftListStaticColumnsAdapter(intl, sort),
availableColumnsChoices, [intl, sort],
columnChoices, );
defaultColumns,
onColumnMoved, const { handlers, staticColumns, visibleColumns, selectedColumns } =
onColumnResize, useColumns({
onColumnsChange, staticColumns: memoizedStaticColumns,
picker, selectedColumns: settings?.columns ?? [],
} = useColumnsDefault(availableColumns); onSave: handleColumnChange,
});
// eslint-disable-next-line react-hooks/exhaustive-deps
const getCellContent = useCallback( const getCellContent = useCallback(
createGetCellContent({ orders, columns, locale }), createGetCellContent({ orders, columns: visibleColumns, locale }),
[columns, locale, orders], [visibleColumns, locale, orders],
); );
const handleHeaderClick = useCallback( const handleHeaderClick = useCallback(
(col: number) => { (col: number) => {
const columnName = columns[col].id as OrderDraftListUrlSortField; const columnName = visibleColumns[col].id as OrderDraftListUrlSortField;
if (canBeSorted(columnName)) { if (canBeSorted(columnName)) {
onSort(columnName); onSort(columnName);
} }
}, },
[columns, onSort], [visibleColumns, onSort],
); );
const handleRowClick = useCallback( const handleRowClick = useCallback(
@ -102,7 +111,7 @@ export const OrderDraftListDatagrid = ({
freezeColumns={1} freezeColumns={1}
hasRowHover={hasRowHover} hasRowHover={hasRowHover}
loading={disabled} loading={disabled}
availableColumns={columns} availableColumns={visibleColumns}
verticalBorder={col => col > 0} verticalBorder={col => col > 0}
getCellContent={getCellContent} getCellContent={getCellContent}
getCellError={() => false} getCellError={() => false}
@ -111,27 +120,16 @@ export const OrderDraftListDatagrid = ({
rows={orders?.length ?? 0} rows={orders?.length ?? 0}
selectionActions={() => null} selectionActions={() => null}
onRowSelectionChange={onSelectOrderDraftIds} onRowSelectionChange={onSelectOrderDraftIds}
onColumnMoved={onColumnMoved} onColumnResize={handlers.onResize}
onColumnResize={onColumnResize} onColumnMoved={handlers.onMove}
onHeaderClicked={handleHeaderClick} onHeaderClicked={handleHeaderClick}
onRowClick={handleRowClick} onRowClick={handleRowClick}
rowAnchor={handleRowAnchor} rowAnchor={handleRowAnchor}
renderColumnPicker={defaultProps => ( renderColumnPicker={() => (
<ColumnPicker <ColumnPicker
{...defaultProps} staticColumns={staticColumns}
IconButtonProps={{ selectedColumns={selectedColumns}
...defaultProps.IconButtonProps, onSave={handlers.onChange}
disabled: orders.length === 0,
}}
availableColumns={availableColumnsChoices}
initialColumns={columnChoices}
defaultColumns={defaultColumns}
onSave={onColumnsChange}
hasMore={false}
loading={false}
onFetchMore={() => undefined}
onQueryChange={picker.setQuery}
query={picker.query}
/> />
)} )}
/> />

View file

@ -1,5 +1,4 @@
import { OrderDraftListQuery } from "@dashboard/graphql"; import { OrderDraft } from "@dashboard/orders/types";
import { RelayToFlat } from "@dashboard/types";
import { getCustomerName } from "./datagrid"; import { getCustomerName } from "./datagrid";
@ -11,7 +10,7 @@ describe("getCustomerName", () => {
firstName: "John", firstName: "John",
lastName: "Doe", lastName: "Doe",
}, },
} as RelayToFlat<NonNullable<OrderDraftListQuery["draftOrders"]>>[number]; } as OrderDraft;
// Act // Act
const result = getCustomerName(data); const result = getCustomerName(data);
@ -27,7 +26,7 @@ describe("getCustomerName", () => {
city: "New York", city: "New York",
}, },
userEmail: "john@doe.com", userEmail: "john@doe.com",
} as RelayToFlat<NonNullable<OrderDraftListQuery["draftOrders"]>>[number]; } as OrderDraft;
// Act // Act
const result = getCustomerName(data); const result = getCustomerName(data);
@ -38,9 +37,7 @@ describe("getCustomerName", () => {
it("should return - when no user email and billing address", () => { it("should return - when no user email and billing address", () => {
// Arrange // Arrange
const data = {} as RelayToFlat< const data = {} as OrderDraft;
NonNullable<OrderDraftListQuery["draftOrders"]>
>[number];
// Act // Act
const result = getCustomerName(data); const result = getCustomerName(data);

View file

@ -1,12 +1,11 @@
// @ts-strict-ignore
import { import {
moneyCell, moneyCell,
readonlyTextCell, readonlyTextCell,
} from "@dashboard/components/Datagrid/customCells/cells"; } from "@dashboard/components/Datagrid/customCells/cells";
import { AvailableColumn } from "@dashboard/components/Datagrid/types"; import { AvailableColumn } from "@dashboard/components/Datagrid/types";
import { Locale } from "@dashboard/components/Locale"; import { Locale } from "@dashboard/components/Locale";
import { OrderDraftListQuery } from "@dashboard/graphql"; import { OrderDraft } from "@dashboard/orders/types";
import { RelayToFlat, Sort } from "@dashboard/types"; import { Sort } from "@dashboard/types";
import { getColumnSortDirectionIcon } from "@dashboard/utils/columns/getColumnSortDirectionIcon"; import { getColumnSortDirectionIcon } from "@dashboard/utils/columns/getColumnSortDirectionIcon";
import { GridCell, Item } from "@glideapps/glide-data-grid"; import { GridCell, Item } from "@glideapps/glide-data-grid";
import moment from "moment"; import moment from "moment";
@ -14,32 +13,35 @@ import { IntlShape } from "react-intl";
import { columnsMessages } from "./messages"; import { columnsMessages } from "./messages";
export const getColumns = (intl: IntlShape, sort: Sort): AvailableColumn[] => [ export const orderDraftListStaticColumnsAdapter = (
{ intl: IntlShape,
id: "number", sort: Sort,
title: intl.formatMessage(columnsMessages.number), ): AvailableColumn[] =>
width: 100, [
icon: getColumnSortDirectionIcon(sort, "number"), {
}, id: "number",
{ title: intl.formatMessage(columnsMessages.number),
id: "date", width: 100,
title: intl.formatMessage(columnsMessages.date), },
width: 200, {
icon: getColumnSortDirectionIcon(sort, "date"), id: "date",
}, title: intl.formatMessage(columnsMessages.date),
{ width: 200,
id: "customer", },
title: intl.formatMessage(columnsMessages.customer), {
width: 200, id: "customer",
icon: getColumnSortDirectionIcon(sort, "customer"), title: intl.formatMessage(columnsMessages.customer),
}, width: 200,
{ },
id: "total", {
title: intl.formatMessage(columnsMessages.total), id: "total",
width: 200, title: intl.formatMessage(columnsMessages.total),
icon: getColumnSortDirectionIcon(sort, "total"), width: 200,
}, },
]; ].map(column => ({
...column,
icon: getColumnSortDirectionIcon(sort, column.id),
}));
export const createGetCellContent = export const createGetCellContent =
({ ({
@ -47,15 +49,15 @@ export const createGetCellContent =
locale, locale,
columns, columns,
}: { }: {
orders: RelayToFlat<OrderDraftListQuery["draftOrders"]>; orders: OrderDraft[];
columns: AvailableColumn[]; columns: AvailableColumn[];
locale: Locale; locale: Locale;
}) => }) =>
([column, row]: Item): GridCell => { ([column, row]: Item): GridCell => {
const rowData = orders[row]; const rowData: OrderDraft | undefined = orders[row];
const columnId = columns[column]?.id; const columnId = columns[column]?.id;
if (!columnId) { if (!columnId || !rowData) {
return readonlyTextCell(""); return readonlyTextCell("");
} }
@ -76,12 +78,12 @@ export const createGetCellContent =
readonly: true, readonly: true,
}, },
); );
default:
return readonlyTextCell("");
} }
}; };
export function getCustomerName( export function getCustomerName(rowData: OrderDraft) {
rowData: RelayToFlat<OrderDraftListQuery["draftOrders"]>[number],
) {
if (rowData?.billingAddress?.firstName && rowData?.billingAddress?.lastName) { if (rowData?.billingAddress?.firstName && rowData?.billingAddress?.lastName) {
return `${rowData.billingAddress.firstName} ${rowData.billingAddress.lastName}`; return `${rowData.billingAddress.firstName} ${rowData.billingAddress.lastName}`;
} }

View file

@ -1,10 +1,12 @@
import { import {
MarkAsPaidStrategyEnum, MarkAsPaidStrategyEnum,
OrderDetailsFragment, OrderDetailsFragment,
OrderDraftListQuery,
OrderRefundDataQuery, OrderRefundDataQuery,
TransactionEventFragment, TransactionEventFragment,
TransactionItemFragment, TransactionItemFragment,
} from "@dashboard/graphql"; } from "@dashboard/graphql";
import { RelayToFlat } from "@dashboard/types";
/** Check if order has transactions & feature flag enabled */ /** Check if order has transactions & feature flag enabled */
export const orderHasTransactions = (order: OrderDetailsFragment): boolean => export const orderHasTransactions = (order: OrderDetailsFragment): boolean =>
@ -38,6 +40,10 @@ export type OrderRefundSharedType = Pick<
keyof OrderRefundData keyof OrderRefundData
>; >;
export type OrderDraft = RelayToFlat<
NonNullable<OrderDraftListQuery["draftOrders"]>
>[number];
/** Type of the trasaction event (e.g. CHARGE_SUCCESS -> CHARGE) */ /** Type of the trasaction event (e.g. CHARGE_SUCCESS -> CHARGE) */
export type TransactionEventType = export type TransactionEventType =
| "REFUND" | "REFUND"