Bladeren bron

fix(dashboard): Allow column selection on recent orders

Michael Bromley 4 maanden geleden
bovenliggende
commit
182c0b7205

+ 12 - 32
packages/dashboard/src/app/routes/_authenticated/_orders/orders.tsx

@@ -1,6 +1,9 @@
-import { Money } from '@/vdb/components/data-display/money.js';
 import { DetailPageButton } from '@/vdb/components/shared/detail-page-button.js';
-import { Badge } from '@/vdb/components/ui/badge.js';
+import {
+    CustomerCell,
+    OrderMoneyCell,
+    OrderStateCell,
+} from '@/vdb/components/shared/table-cell/order-table-cell-components.js';
 import { Button } from '@/vdb/components/ui/button.js';
 import { PageActionBarRight } from '@/vdb/framework/layout-engine/page-layout.js';
 import { ListPage } from '@/vdb/framework/page/list-page.js';
@@ -9,7 +12,7 @@ import { ResultOf } from '@/vdb/graphql/graphql.js';
 import { useServerConfig } from '@/vdb/hooks/use-server-config.js';
 import { Trans } from '@/vdb/lib/trans.js';
 import { useMutation } from '@tanstack/react-query';
-import { createFileRoute, Link, useNavigate } from '@tanstack/react-router';
+import { createFileRoute, useNavigate } from '@tanstack/react-router';
 import { PlusIcon } from 'lucide-react';
 import { createDraftOrderDocument, orderListDocument } from './orders.graphql.js';
 
@@ -58,26 +61,15 @@ function OrderListPage() {
             customizeColumns={{
                 total: {
                     header: 'Total',
-                    cell: ({ cell, row }) => {
-                        const value = cell.getValue();
-                        const currencyCode = row.original.currencyCode;
-                        return <Money value={value} currency={currencyCode} />;
-                    },
+                    cell: OrderMoneyCell,
                 },
                 totalWithTax: {
                     header: 'Total with Tax',
-                    cell: ({ cell, row }) => {
-                        const value = cell.getValue();
-                        const currencyCode = row.original.currencyCode;
-                        return <Money value={value} currency={currencyCode} />;
-                    },
+                    cell: OrderMoneyCell,
                 },
                 state: {
                     header: 'State',
-                    cell: ({ cell }) => {
-                        const value = cell.getValue() as string;
-                        return <Badge variant="outline">{value}</Badge>;
-                    },
+                    cell: OrderStateCell,
                 },
                 code: {
                     header: 'Code',
@@ -89,24 +81,12 @@ function OrderListPage() {
                 },
                 customer: {
                     header: 'Customer',
-                    cell: ({ cell }) => {
-                        const value = cell.getValue();
-                        if (!value) {
-                            return null;
-                        }
-                        return (
-                            <Button asChild variant="ghost">
-                                <Link to={`/customers/${value.id}`}>
-                                    {value.firstName} {value.lastName}
-                                </Link>
-                            </Button>
-                        );
-                    },
+                    cell: CustomerCell,
                 },
                 shippingLines: {
                     header: 'Shipping',
-                    cell: ({ cell }) => {
-                        const value = cell.getValue();
+                    cell: ({ row }) => {
+                        const value = row.original.shippingLines;
                         return <div>{value.map(line => line.shippingMethod.name).join(', ')}</div>;
                     },
                 },

+ 38 - 0
packages/dashboard/src/lib/components/shared/table-cell/order-table-cell-components.tsx

@@ -0,0 +1,38 @@
+import { Money } from '@/vdb/components/data-display/money.js';
+import { DataTableCellComponent } from '@/vdb/components/shared/table-cell/table-cell-types.js';
+import { Badge } from '@/vdb/components/ui/badge.js';
+import { Button } from '@/vdb/components/ui/button.js';
+import { Link } from '@tanstack/react-router';
+
+type CustomerCellData = {
+    customer: {
+        id: string;
+        firstName: string;
+        lastName: string;
+    } | null;
+};
+
+export const CustomerCell: DataTableCellComponent<CustomerCellData> = ({ row }) => {
+    const value = row.original.customer;
+    if (!value) {
+        return null;
+    }
+    return (
+        <Button asChild variant="ghost">
+            <Link to={`/customers/${value.id}`}>
+                {value.firstName} {value.lastName}
+            </Link>
+        </Button>
+    );
+};
+
+export const OrderStateCell: DataTableCellComponent<{ state: string }> = ({ row }) => {
+    const value = row.original.state;
+    return <Badge variant="outline">{value}</Badge>;
+};
+
+export const OrderMoneyCell: DataTableCellComponent<{ currencyCode: string }> = ({ cell, row }) => {
+    const value = cell.getValue();
+    const currencyCode = row.original.currencyCode;
+    return <Money value={value} currency={currencyCode} />;
+};

+ 33 - 0
packages/dashboard/src/lib/components/shared/table-cell/table-cell-types.ts

@@ -0,0 +1,33 @@
+import { CellContext } from '@tanstack/table-core';
+
+/**
+ * @description
+ * This type is used to define re-usable components that can render a table cell in a
+ * DataTable.
+ *
+ * @example
+ * ```ts
+ * type CustomerCellData = {
+ *     customer: {
+ *         id: string;
+ *         firstName: string;
+ *         lastName: string;
+ *     } | null;
+ * };
+ *
+ * export const CustomerCell: DataTableCellComponent<CustomerCellData> = ({ row }) => {
+ *     const value = row.original.customer;
+ *     if (!value) {
+ *         return null;
+ *     }
+ *     return (
+ *         <Button asChild variant="ghost">
+ *             <Link to={`/customers/${value.id}`}>
+ *                 {value.firstName} {value.lastName}
+ *             </Link>
+ *         </Button>
+ *     );
+ * };
+ * ```
+ */
+export type DataTableCellComponent<T> = <Data extends T>(context: CellContext<Data, any>) => any;

+ 10 - 7
packages/dashboard/src/lib/framework/dashboard-widget/latest-orders-widget/index.tsx

@@ -1,4 +1,9 @@
 import { PaginatedListDataTable } from '@/vdb/components/shared/paginated-list-data-table.js';
+import {
+    CustomerCell,
+    OrderMoneyCell,
+    OrderStateCell,
+} from '@/vdb/components/shared/table-cell/order-table-cell-components.js';
 import { Button } from '@/vdb/components/ui/button.js';
 import { useLocalFormat } from '@/vdb/hooks/use-local-format.js';
 import { Link } from '@tanstack/react-router';
@@ -25,7 +30,6 @@ export function LatestOrdersWidget() {
     return (
         <DashboardBaseWidget id={WIDGET_ID} title="Latest Orders" description="Your latest orders">
             <PaginatedListDataTable
-                disableViewOptions
                 page={page}
                 transformVariables={variables => ({
                     ...variables,
@@ -56,7 +60,7 @@ export function LatestOrdersWidget() {
                         header: 'Placed At',
                         cell: ({ row }) => {
                             return (
-                                <span>
+                                <span className="capitalize">
                                     {formatRelative(row.original.orderPlacedAt ?? new Date(), new Date())}
                                 </span>
                             );
@@ -64,12 +68,11 @@ export function LatestOrdersWidget() {
                     },
                     total: {
                         header: 'Total',
-                        cell: ({ row }) => {
-                            return (
-                                <span>{formatCurrency(row.original.total, row.original.currencyCode)}</span>
-                            );
-                        },
+                        cell: OrderMoneyCell,
                     },
+                    totalWithTax: { cell: OrderMoneyCell },
+                    state: { cell: OrderStateCell },
+                    customer: { cell: CustomerCell },
                 }}
                 itemsPerPage={pageSize}
                 sorting={sorting}