import { HttpTypes } from "@medusajs/types" import { Button, Checkbox } from "@medusajs/ui" import { keepPreviousData } from "@tanstack/react-query" import { OnChangeFn, RowSelectionState, createColumnHelper, } from "@tanstack/react-table" import { useEffect, useMemo, useState } from "react" import { useTranslation } from "react-i18next" import { useSearchParams } from "react-router-dom" import { StackedDrawer, StackedFocusModal, } from "../../../../../components/modals" import { _DataTable } from "../../../../../components/table/data-table" import { useProductTypes, useProducts, useShippingOptions, useStockLocations, } from "../../../../../hooks/api" import { useProductTableColumns, useProductTypeTableColumns, } from "../../../../../hooks/table/columns" import { useProductTableFilters, useProductTypeTableFilters, useShippingOptionTableFilters, } from "../../../../../hooks/table/filters" import { useProductTableQuery, useProductTypeTableQuery, useShippingOptionTableQuery, } from "../../../../../hooks/table/query" import { useDataTable } from "../../../../../hooks/use-data-table" import { TaxRateRuleReferenceType } from "../../constants" import { TaxRateRuleReference } from "../../schemas" import { useShippingOptionTableColumns } from "../../../../../hooks/table/columns/use-shipping-option-table-columns" type TargetFormProps = { referenceType: TaxRateRuleReferenceType type: "focus" | "drawer" state: TaxRateRuleReference[] setState: (state: TaxRateRuleReference[]) => void } function initRowSelection(state: TaxRateRuleReference[]) { return state.reduce((acc, reference) => { acc[reference.value] = true return acc }, {} as RowSelectionState) } export const TargetForm = ({ referenceType, type, setState, state, }: TargetFormProps) => { const { t } = useTranslation() const Component = type === "focus" ? StackedFocusModal : StackedDrawer const [intermediate, setIntermediate] = useState(state) const handleSave = () => { setState(intermediate) } return (
) } type TableProps = { referenceType: TaxRateRuleReferenceType initialRowState: RowSelectionState intermediate: TaxRateRuleReference[] setIntermediate: (state: TaxRateRuleReference[]) => void } const Table = ({ referenceType, ...props }: TableProps) => { switch (referenceType) { // case TaxRateRuleReferenceType.CUSTOMER_GROUP: // return case TaxRateRuleReferenceType.PRODUCT: return // case TaxRateRuleReferenceType.PRODUCT_COLLECTION: // return case TaxRateRuleReferenceType.PRODUCT_TYPE: return // case TaxRateRuleReferenceType.PRODUCT_TAG: // return case TaxRateRuleReferenceType.SHIPPING_OPTION: return default: return null } } type TableImplementationProps = { initialRowState: RowSelectionState intermediate: TaxRateRuleReference[] setIntermediate: (state: TaxRateRuleReference[]) => void } const PAGE_SIZE = 50 // const PREFIX_CUSTOMER_GROUP = "cg" // const CustomerGroupTable = ({ // initialRowState, // intermediate, // setIntermediate, // }: TableImplementationProps) => { // const { t } = useTranslation() // const [rowSelection, setRowSelection] = // useState(initialRowState) // useCleanupSearchParams() // const { searchParams, raw } = useCustomerGroupTableQuery({ // pageSize: PAGE_SIZE, // prefix: PREFIX_CUSTOMER_GROUP, // }) // const { customer_groups, count, isLoading, isError, error } = // useCustomerGroups(searchParams, { // placeholderData: keepPreviousData, // }) // const updater: OnChangeFn = (value) => { // const state = typeof value === "function" ? value(rowSelection) : value // const currentIds = Object.keys(rowSelection) // const ids = Object.keys(state) // const newIds = ids.filter((id) => !currentIds.includes(id)) // const removedIds = currentIds.filter((id) => !ids.includes(id)) // const newCustomerGroups = // customer_groups // ?.filter((cg) => newIds.includes(cg.id)) // .map((cg) => ({ value: cg.id, label: cg.name! })) || [] // const filteredIntermediate = intermediate.filter( // (cg) => !removedIds.includes(cg.value) // ) // setIntermediate([...filteredIntermediate, ...newCustomerGroups]) // setRowSelection(state) // } // const filters = useCustomerGroupTableFilters() // const columns = useGroupColumns() // const { table } = useDataTable({ // data: customer_groups || [], // columns, // count, // enablePagination: true, // enableRowSelection: true, // getRowId: (row) => row.id, // rowSelection: { // state: rowSelection, // updater, // }, // pageSize: PAGE_SIZE, // prefix: PREFIX_CUSTOMER_GROUP, // }) // if (isError) { // throw error // } // return ( // <_DataTable // table={table} // columns={columns} // pageSize={PAGE_SIZE} // count={count} // isLoading={isLoading} // filters={filters} // orderBy={[ // { key: "name", label: t("fields.name") }, // { key: "created_at", label: t("fields.createdAt") }, // { key: "updated_at", label: t("fields.updatedAt") }, // ]} // layout="fill" // pagination // search // prefix={PREFIX_CUSTOMER_GROUP} // queryObject={raw} // /> // ) // } // const cgColumnHelper = createColumnHelper() // const useGroupColumns = () => { // const base = useCustomerGroupTableColumns() // return useMemo( // () => [ // cgColumnHelper.display({ // id: "select", // header: ({ table }) => { // return ( // // table.toggleAllPageRowsSelected(!!value) // } // /> // ) // }, // cell: ({ row }) => { // return ( // row.toggleSelected(!!value)} // onClick={(e) => { // e.stopPropagation() // }} // /> // ) // }, // }), // ...base, // ], // [base] // ) // } const PREFIX_PRODUCT = "p" const ProductTable = ({ initialRowState, intermediate, setIntermediate, }: TableImplementationProps) => { const { t } = useTranslation() const [rowSelection, setRowSelection] = useState(initialRowState) useCleanupSearchParams() const { searchParams, raw } = useProductTableQuery({ pageSize: PAGE_SIZE, prefix: PREFIX_PRODUCT, }) const { products, count, isLoading, isError, error } = useProducts( searchParams, { placeholderData: keepPreviousData, } ) const updater: OnChangeFn = (value) => { const state = typeof value === "function" ? value(rowSelection) : value const currentIds = Object.keys(rowSelection) const ids = Object.keys(state) const newIds = ids.filter((id) => !currentIds.includes(id)) const removedIds = currentIds.filter((id) => !ids.includes(id)) const newProducts = products ?.filter((p) => newIds.includes(p.id)) .map((p) => ({ value: p.id, label: p.title!, })) || [] const filteredIntermediate = intermediate.filter( (p) => !removedIds.includes(p.value) ) setIntermediate([...filteredIntermediate, ...newProducts]) setRowSelection(state) } const filters = useProductTableFilters() const columns = useProductColumns() const { table } = useDataTable({ data: products || [], columns, count, enablePagination: true, enableRowSelection: true, getRowId: (row) => row.id, rowSelection: { state: rowSelection, updater, }, pageSize: PAGE_SIZE, prefix: PREFIX_PRODUCT, }) if (isError) { throw error } return ( <_DataTable table={table} columns={columns} pageSize={PAGE_SIZE} count={count} isLoading={isLoading} filters={filters} orderBy={[ { key: "title", label: t("fields.title") }, { key: "created_at", label: t("fields.createdAt") }, { key: "updated_at", label: t("fields.updatedAt") }, ]} layout="fill" pagination search prefix={PREFIX_PRODUCT} queryObject={raw} /> ) } const pColumnHelper = createColumnHelper() const useProductColumns = () => { const base = useProductTableColumns() return useMemo( () => [ pColumnHelper.display({ id: "select", header: ({ table }) => { return ( table.toggleAllPageRowsSelected(!!value) } /> ) }, cell: ({ row }) => { return ( row.toggleSelected(!!value)} onClick={(e) => { e.stopPropagation() }} /> ) }, }), ...base, ], [base] ) } // const PREFIX_PRODUCT_COLLECTION = "pc" // const ProductCollectionTable = ({ // initialRowState, // intermediate, // setIntermediate, // }: TableImplementationProps) => { // const { t } = useTranslation() // const [rowSelection, setRowSelection] = // useState(initialRowState) // useCleanupSearchParams() // const { searchParams, raw } = useCollectionTableQuery({ // pageSize: PAGE_SIZE, // prefix: PREFIX_PRODUCT_COLLECTION, // }) // const { collections, count, isLoading, isError, error } = useCollections( // searchParams, // { // placeholderData: keepPreviousData, // } // ) // const updater: OnChangeFn = (value) => { // const state = typeof value === "function" ? value(rowSelection) : value // const currentIds = Object.keys(rowSelection) // const ids = Object.keys(state) // const newIds = ids.filter((id) => !currentIds.includes(id)) // const removedIds = currentIds.filter((id) => !ids.includes(id)) // const newCollections = // collections // ?.filter((p) => newIds.includes(p.id)) // .map((p) => ({ // value: p.id, // label: p.title, // })) || [] // const filteredIntermediate = intermediate.filter( // (p) => !removedIds.includes(p.value) // ) // setIntermediate([...filteredIntermediate, ...newCollections]) // setRowSelection(state) // } // const filters = useCollectionTableFilters() // const columns = useCollectionColumns() // const { table } = useDataTable({ // data: collections || [], // columns, // count, // enablePagination: true, // enableRowSelection: true, // getRowId: (row) => row.id, // rowSelection: { // state: rowSelection, // updater, // }, // pageSize: PAGE_SIZE, // prefix: PREFIX_PRODUCT_COLLECTION, // }) // if (isError) { // throw error // } // return ( // <_DataTable // table={table} // columns={columns} // pageSize={PAGE_SIZE} // count={count} // isLoading={isLoading} // filters={filters} // orderBy={[ // { key: "title", label: t("fields.title") }, // { key: "created_at", label: t("fields.createdAt") }, // { key: "updated_at", label: t("fields.updatedAt") }, // ]} // layout="fill" // pagination // search // prefix={PREFIX_PRODUCT_COLLECTION} // queryObject={raw} // /> // ) // } // const pcColumnHelper = createColumnHelper() // const useCollectionColumns = () => { // const base = useCollectionTableColumns() // return useMemo( // () => [ // pcColumnHelper.display({ // id: "select", // header: ({ table }) => { // return ( // // table.toggleAllPageRowsSelected(!!value) // } // /> // ) // }, // cell: ({ row }) => { // return ( // row.toggleSelected(!!value)} // onClick={(e) => { // e.stopPropagation() // }} // /> // ) // }, // }), // ...base, // ], // [base] // ) // } const PREFIX_PRODUCT_TYPE = "pt" const ProductTypeTable = ({ initialRowState, intermediate, setIntermediate, }: TableImplementationProps) => { const { t } = useTranslation() const [rowSelection, setRowSelection] = useState(initialRowState) useCleanupSearchParams() const { searchParams, raw } = useProductTypeTableQuery({ pageSize: PAGE_SIZE, prefix: PREFIX_PRODUCT_TYPE, }) const { product_types, count, isLoading, isError, error } = useProductTypes( searchParams, { placeholderData: keepPreviousData, } ) const updater: OnChangeFn = (value) => { const state = typeof value === "function" ? value(rowSelection) : value const currentIds = Object.keys(rowSelection) const ids = Object.keys(state) const newIds = ids.filter((id) => !currentIds.includes(id)) const removedIds = currentIds.filter((id) => !ids.includes(id)) const newTypes = product_types ?.filter((p) => newIds.includes(p.id)) .map((p) => ({ value: p.id, label: p.value, })) || [] const filteredIntermediate = intermediate.filter( (p) => !removedIds.includes(p.value) ) setIntermediate([...filteredIntermediate, ...newTypes]) setRowSelection(state) } const filters = useProductTypeTableFilters() const columns = useProductTypeColumns() const { table } = useDataTable({ data: product_types || [], columns, count, enablePagination: true, enableRowSelection: true, getRowId: (row) => row.id, rowSelection: { state: rowSelection, updater, }, pageSize: PAGE_SIZE, prefix: PREFIX_PRODUCT_TYPE, }) if (isError) { throw error } return ( <_DataTable table={table} columns={columns} pageSize={PAGE_SIZE} count={count} isLoading={isLoading} filters={filters} orderBy={[ { key: "value", label: t("fields.value") }, { key: "created_at", label: t("fields.createdAt") }, { key: "updated_at", label: t("fields.updatedAt") }, ]} layout="fill" pagination search prefix={PREFIX_PRODUCT_TYPE} queryObject={raw} /> ) } const ptColumnHelper = createColumnHelper() const useProductTypeColumns = () => { const base = useProductTypeTableColumns() return useMemo( () => [ ptColumnHelper.display({ id: "select", header: ({ table }) => { return ( table.toggleAllPageRowsSelected(!!value) } /> ) }, cell: ({ row }) => { return ( row.toggleSelected(!!value)} onClick={(e) => { e.stopPropagation() }} /> ) }, }), ...base, ], [base] ) } const PREFIX_SHIPPING_OPTION = "so" const ShippingOptionTable = ({ initialRowState, intermediate, setIntermediate, }: TableImplementationProps) => { const { t } = useTranslation() const [rowSelection, setRowSelection] = useState(initialRowState) useCleanupSearchParams() const { searchParams, raw } = useShippingOptionTableQuery({ pageSize: PAGE_SIZE, prefix: PREFIX_SHIPPING_OPTION, }) const { shipping_options, count, isLoading, isError, error } = useShippingOptions( { ...searchParams, fields: "+service_zone.fulfillment_set.location.*", }, { placeholderData: keepPreviousData, } ) const updater: OnChangeFn = (value) => { const state = typeof value === "function" ? value(rowSelection) : value const currentIds = Object.keys(rowSelection) const ids = Object.keys(state) const newIds = ids.filter((id) => !currentIds.includes(id)) const removedIds = currentIds.filter((id) => !ids.includes(id)) const newShippingOptions = shipping_options ?.filter((p) => newIds.includes(p.id)) .map((p) => ({ value: p.id, label: p.name, })) || [] const filteredIntermediate = intermediate.filter( (p) => !removedIds.includes(p.value) ) setIntermediate([...filteredIntermediate, ...newShippingOptions]) setRowSelection(state) } const { stock_locations } = useStockLocations({ limit: 1000, }) const filters = useShippingOptionTableFilters(stock_locations || []) const columns = useShippingOptionColumns() const { table } = useDataTable({ data: shipping_options || [], columns, count, enablePagination: true, enableRowSelection: true, getRowId: (row) => row.id, rowSelection: { state: rowSelection, updater, }, pageSize: PAGE_SIZE, prefix: PREFIX_SHIPPING_OPTION, }) if (isError) { throw error } return ( <_DataTable table={table} columns={columns} pageSize={PAGE_SIZE} count={count} isLoading={isLoading} filters={filters} orderBy={[ { key: "name", label: t("fields.name") }, { key: "created_at", label: t("fields.createdAt") }, { key: "updated_at", label: t("fields.updatedAt") }, ]} layout="fill" pagination search prefix={PREFIX_SHIPPING_OPTION} queryObject={raw} /> ) } const soColumnHelper = createColumnHelper() const useShippingOptionColumns = () => { const base = useShippingOptionTableColumns() return useMemo( () => [ soColumnHelper.display({ id: "select", header: ({ table }) => { return ( table.toggleAllPageRowsSelected(!!value) } /> ) }, cell: ({ row }) => { return ( row.toggleSelected(!!value)} onClick={(e) => { e.stopPropagation() }} /> ) }, }), ...base, ], [base] ) } // const PREFIX_PRODUCT_TAG = "ptag" // const ProductTagTable = ({ // initialRowState, // intermediate, // setIntermediate, // }: TableImplementationProps) => { // const { t } = useTranslation() // const [rowSelection, setRowSelection] = // useState(initialRowState) // useCleanupSearchParams() // const { searchParams, raw } = useProductTagTableQuery({ // pageSize: PAGE_SIZE, // prefix: PREFIX_PRODUCT_TAG, // }) // const { product_tags, count, isLoading, isError, error } = useProductTags( // searchParams, // { // placeholderData: keepPreviousData, // } // ) // const updater: OnChangeFn = (value) => { // const state = typeof value === "function" ? value(rowSelection) : value // const currentIds = Object.keys(rowSelection) // const ids = Object.keys(state) // const newIds = ids.filter((id) => !currentIds.includes(id)) // const removedIds = currentIds.filter((id) => !ids.includes(id)) // const newTags = // product_tags // ?.filter((p) => newIds.includes(p.id)) // .map((p) => ({ // value: p.id, // label: p.value, // })) || [] // const filteredIntermediate = intermediate.filter( // (p) => !removedIds.includes(p.value) // ) // setIntermediate([...filteredIntermediate, ...newTags]) // setRowSelection(state) // } // const filters = useProductTagTableFilters() // const columns = useProductTagColumns() // const { table } = useDataTable({ // data: product_tags || [], // columns, // count, // enablePagination: true, // enableRowSelection: true, // getRowId: (row) => row.id, // rowSelection: { // state: rowSelection, // updater, // }, // pageSize: PAGE_SIZE, // prefix: PREFIX_PRODUCT_TAG, // }) // if (isError) { // throw error // } // return ( // <_DataTable // table={table} // columns={columns} // pageSize={PAGE_SIZE} // count={count} // isLoading={isLoading} // filters={filters} // orderBy={[ // { key: "value", label: t("fields.value") }, // { key: "created_at", label: t("fields.createdAt") }, // { key: "updated_at", label: t("fields.updatedAt") }, // ]} // layout="fill" // pagination // search // prefix={PREFIX_PRODUCT_TAG} // queryObject={raw} // /> // ) // } // const ptagColumnHelper = createColumnHelper() // const useProductTagColumns = () => { // const base = useProductTagTableColumns() // return useMemo( // () => [ // ptagColumnHelper.display({ // id: "select", // header: ({ table }) => { // return ( // // table.toggleAllPageRowsSelected(!!value) // } // /> // ) // }, // cell: ({ row }) => { // return ( // row.toggleSelected(!!value)} // onClick={(e) => { // e.stopPropagation() // }} // /> // ) // }, // }), // ...base, // ], // [base] // ) // } const useCleanupSearchParams = () => { const [_, setSearchParams] = useSearchParams() useEffect(() => { return () => { setSearchParams({}) } // eslint-disable-next-line react-hooks/exhaustive-deps }, []) }