|
|
@@ -14,7 +14,7 @@ import {
|
|
|
VisibilityState,
|
|
|
} from '@tanstack/react-table';
|
|
|
import { Trash2 } from 'lucide-react';
|
|
|
-import { useState } from 'react';
|
|
|
+import { useMemo, useState } from 'react';
|
|
|
import {
|
|
|
couponCodeSelectorPromotionListDocument,
|
|
|
draftOrderEligibleShippingMethodsDocument,
|
|
|
@@ -70,91 +70,100 @@ export function EditOrderTable({
|
|
|
const [columnVisibility, setColumnVisibility] = useState<VisibilityState>({});
|
|
|
const { t } = useLingui();
|
|
|
const currencyCode = order.currencyCode;
|
|
|
- const columns: ColumnDef<OrderLineFragment & { customFields?: Record<string, any> }>[] = [
|
|
|
- {
|
|
|
- header: '',
|
|
|
- accessorKey: 'featuredAsset',
|
|
|
- cell: ({ row }) => {
|
|
|
- const asset = row.original.featuredAsset;
|
|
|
- const removing = row.original.quantity === 0;
|
|
|
- return <VendureImage className={removing ? 'opacity-50' : ''} asset={asset} preset="tiny" />;
|
|
|
+ const columns: ColumnDef<OrderLineFragment & { customFields?: Record<string, any> }>[] = useMemo(
|
|
|
+ () => [
|
|
|
+ {
|
|
|
+ header: '',
|
|
|
+ accessorKey: 'featuredAsset',
|
|
|
+ cell: ({ row }) => {
|
|
|
+ const asset = row.original.featuredAsset;
|
|
|
+ const removing = row.original.quantity === 0;
|
|
|
+ return (
|
|
|
+ <VendureImage className={removing ? 'opacity-50' : ''} asset={asset} preset="tiny" />
|
|
|
+ );
|
|
|
+ },
|
|
|
},
|
|
|
- },
|
|
|
- {
|
|
|
- header: t`Product`,
|
|
|
- accessorKey: 'productVariant.name',
|
|
|
- cell: ({ row }) => {
|
|
|
- const value = row.original.productVariant.name;
|
|
|
- const removing = row.original.quantity === 0;
|
|
|
- return <div className={removing ? 'text-muted-foreground' : ''}>{value}</div>;
|
|
|
+ {
|
|
|
+ header: t`Product`,
|
|
|
+ accessorKey: 'productVariant.name',
|
|
|
+ cell: ({ row }) => {
|
|
|
+ const value = row.original.productVariant.name;
|
|
|
+ const removing = row.original.quantity === 0;
|
|
|
+ return <div className={removing ? 'text-muted-foreground' : ''}>{value}</div>;
|
|
|
+ },
|
|
|
},
|
|
|
- },
|
|
|
- {
|
|
|
- header: t`SKU`,
|
|
|
- accessorKey: 'productVariant.sku',
|
|
|
- },
|
|
|
- {
|
|
|
- header: t`Unit price`,
|
|
|
- accessorKey: 'unitPriceWithTax',
|
|
|
- cell: ({ row }) => {
|
|
|
- const value = row.original.unitPriceWithTax;
|
|
|
- const netValue = row.original.unitPrice;
|
|
|
- return <MoneyGrossNet priceWithTax={value} price={netValue} currencyCode={currencyCode} />;
|
|
|
+ {
|
|
|
+ header: t`SKU`,
|
|
|
+ accessorKey: 'productVariant.sku',
|
|
|
},
|
|
|
- },
|
|
|
- {
|
|
|
- header: t`Quantity`,
|
|
|
- accessorKey: 'quantity',
|
|
|
- cell: ({ row }) => {
|
|
|
- return (
|
|
|
- <div className="flex gap-2">
|
|
|
- <Input
|
|
|
- type="number"
|
|
|
- value={row.original.quantity}
|
|
|
- min={0}
|
|
|
- onChange={e =>
|
|
|
- onAdjustLine({
|
|
|
- lineId: row.original.id,
|
|
|
- quantity: e.target.valueAsNumber,
|
|
|
- customFields: row.original.customFields,
|
|
|
- })
|
|
|
- }
|
|
|
- />
|
|
|
- <Button
|
|
|
- variant="outline"
|
|
|
- type="button"
|
|
|
- size="icon"
|
|
|
- disabled={row.original.quantity === 0}
|
|
|
- onClick={() => onRemoveLine({ lineId: row.original.id })}
|
|
|
- >
|
|
|
- <Trash2 />
|
|
|
- </Button>
|
|
|
- {row.original.customFields && (
|
|
|
- <OrderLineCustomFieldsForm
|
|
|
- onUpdate={customFields => {
|
|
|
+ {
|
|
|
+ header: t`Unit price`,
|
|
|
+ accessorKey: 'unitPriceWithTax',
|
|
|
+ cell: ({ row }) => {
|
|
|
+ const value = row.original.unitPriceWithTax;
|
|
|
+ const netValue = row.original.unitPrice;
|
|
|
+ return (
|
|
|
+ <MoneyGrossNet priceWithTax={value} price={netValue} currencyCode={currencyCode} />
|
|
|
+ );
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ header: t`Quantity`,
|
|
|
+ accessorKey: 'quantity',
|
|
|
+ cell: ({ row }) => {
|
|
|
+ return (
|
|
|
+ <div className="flex gap-2">
|
|
|
+ <Input
|
|
|
+ type="number"
|
|
|
+ value={row.original.quantity}
|
|
|
+ min={0}
|
|
|
+ onChange={e =>
|
|
|
onAdjustLine({
|
|
|
lineId: row.original.id,
|
|
|
- quantity: row.original.quantity,
|
|
|
- customFields: customFields,
|
|
|
- });
|
|
|
- }}
|
|
|
- value={row.original.customFields}
|
|
|
+ quantity: e.target.valueAsNumber,
|
|
|
+ customFields: row.original.customFields,
|
|
|
+ })
|
|
|
+ }
|
|
|
/>
|
|
|
- )}
|
|
|
- </div>
|
|
|
- );
|
|
|
+ <Button
|
|
|
+ variant="outline"
|
|
|
+ type="button"
|
|
|
+ size="icon"
|
|
|
+ disabled={row.original.quantity === 0}
|
|
|
+ onClick={() => onRemoveLine({ lineId: row.original.id })}
|
|
|
+ >
|
|
|
+ <Trash2 />
|
|
|
+ </Button>
|
|
|
+ {row.original.customFields && (
|
|
|
+ <OrderLineCustomFieldsForm
|
|
|
+ onUpdate={customFields => {
|
|
|
+ onAdjustLine({
|
|
|
+ lineId: row.original.id,
|
|
|
+ quantity: row.original.quantity,
|
|
|
+ customFields: customFields,
|
|
|
+ });
|
|
|
+ }}
|
|
|
+ value={row.original.customFields}
|
|
|
+ />
|
|
|
+ )}
|
|
|
+ </div>
|
|
|
+ );
|
|
|
+ },
|
|
|
},
|
|
|
- },
|
|
|
- {
|
|
|
- header: t`Total`,
|
|
|
- accessorKey: 'linePriceWithTax',
|
|
|
- cell: ({ row }) => {
|
|
|
- const value = row.original.linePriceWithTax;
|
|
|
- const netValue = row.original.linePrice;
|
|
|
- return <MoneyGrossNet priceWithTax={value} price={netValue} currencyCode={currencyCode} />;
|
|
|
+ {
|
|
|
+ header: t`Total`,
|
|
|
+ accessorKey: 'linePriceWithTax',
|
|
|
+ cell: ({ row }) => {
|
|
|
+ const value = row.original.linePriceWithTax;
|
|
|
+ const netValue = row.original.linePrice;
|
|
|
+ return (
|
|
|
+ <MoneyGrossNet priceWithTax={value} price={netValue} currencyCode={currencyCode} />
|
|
|
+ );
|
|
|
+ },
|
|
|
},
|
|
|
- },
|
|
|
- ];
|
|
|
+ ],
|
|
|
+ [],
|
|
|
+ );
|
|
|
|
|
|
const data = order.lines;
|
|
|
|