Feat/datatable core enhancements (#13193)
**What** This PR adds core DataTable enhancements to support view configurations in the admin dashboard. This is part of a set of stacked PRs to add the feature to Medusa. - Puts handlers in place to update the visible columns in a table and the order in which they appear. - Adds a ViewPills component for displaying and switching between saved view configurations - Integrated view configuration hooks (useViewConfigurations) with the DataTable Note: Column drag-and-drop reordering and the column visibility UI controls are not included in this PR as they require additional UI library updates - which will come in the next PR. Example of what this looks like with the feature flag turned on - note the view pills with "default" in the top. This will expand when the data table behavior adds configuration. <img width="2492" height="758" alt="CleanShot 2025-08-13 at 2 31 35@2x" src="https://github.com/user-attachments/assets/ee770f1c-dae1-49da-b255-1a6d615789de" />
This commit is contained in:
+97
-8
@@ -1,19 +1,108 @@
|
||||
import { Container, Heading } from "@medusajs/ui"
|
||||
import { keepPreviousData } from "@tanstack/react-query"
|
||||
import { useTranslation } from "react-i18next"
|
||||
import { useState, useEffect } from "react"
|
||||
|
||||
import { DataTable } from "../../../../../components/data-table"
|
||||
import { useOrders } from "../../../../../hooks/api/orders"
|
||||
import { useOrderTableColumns } from "../../../../../hooks/table/columns/use-order-table-columns"
|
||||
import { useOrderTableFilters } from "../../../../../hooks/table/filters/use-order-table-filters"
|
||||
import { useOrderTableQuery } from "../../../../../hooks/table/query/use-order-table-query"
|
||||
|
||||
import { DEFAULT_FIELDS } from "../../const"
|
||||
|
||||
const PAGE_SIZE = 20
|
||||
|
||||
export const ConfigurableOrderListTable = () => {
|
||||
const { t } = useTranslation()
|
||||
|
||||
const [columnVisibility, setColumnVisibility] = useState<Record<string, boolean>>({})
|
||||
const [columnOrder, setColumnOrder] = useState<string[]>([])
|
||||
|
||||
const { searchParams, raw } = useOrderTableQuery({
|
||||
pageSize: PAGE_SIZE,
|
||||
})
|
||||
|
||||
const { orders, count, isError, error, isLoading } = useOrders(
|
||||
{
|
||||
fields: DEFAULT_FIELDS,
|
||||
...searchParams,
|
||||
},
|
||||
{
|
||||
placeholderData: keepPreviousData,
|
||||
}
|
||||
)
|
||||
|
||||
const filters = useOrderTableFilters()
|
||||
const columns = useOrderTableColumns({})
|
||||
|
||||
const handleViewChange = (view: any) => {
|
||||
if (view) {
|
||||
// Apply view configuration
|
||||
const visibilityState: Record<string, boolean> = {}
|
||||
const allColumns = columns.map(c => c.id!)
|
||||
|
||||
// Set all columns to hidden first
|
||||
allColumns.forEach(col => {
|
||||
visibilityState[col] = false
|
||||
})
|
||||
|
||||
// Then show only the visible columns from the view
|
||||
if (view.configuration?.visible_columns) {
|
||||
view.configuration.visible_columns.forEach((col: string) => {
|
||||
visibilityState[col] = true
|
||||
})
|
||||
}
|
||||
|
||||
setColumnVisibility(visibilityState)
|
||||
|
||||
if (view.configuration?.column_order) {
|
||||
setColumnOrder(view.configuration.column_order)
|
||||
}
|
||||
} else {
|
||||
// Reset to default (all visible)
|
||||
setColumnVisibility({})
|
||||
setColumnOrder([])
|
||||
}
|
||||
}
|
||||
|
||||
if (isError) {
|
||||
throw error
|
||||
}
|
||||
|
||||
return (
|
||||
<Container className="divide-y p-0">
|
||||
<div className="flex items-center justify-between px-6 py-4">
|
||||
<Heading>{t("orders.domain")}</Heading>
|
||||
</div>
|
||||
<div className="px-6 py-4">
|
||||
<p className="text-ui-fg-muted">
|
||||
View configurations feature is enabled. Full implementation coming soon.
|
||||
</p>
|
||||
</div>
|
||||
<DataTable
|
||||
data={orders ?? []}
|
||||
columns={columns}
|
||||
filters={filters}
|
||||
getRowId={(row) => row.id}
|
||||
rowCount={count}
|
||||
enablePagination
|
||||
enableSearch
|
||||
pageSize={PAGE_SIZE}
|
||||
isLoading={isLoading}
|
||||
layout="fill"
|
||||
heading={t("orders.domain")}
|
||||
enableColumnVisibility={true}
|
||||
initialColumnVisibility={columnVisibility}
|
||||
onColumnVisibilityChange={setColumnVisibility}
|
||||
columnOrder={columnOrder}
|
||||
onColumnOrderChange={setColumnOrder}
|
||||
enableViewSelector={true}
|
||||
entity="orders"
|
||||
onViewChange={handleViewChange}
|
||||
currentColumns={{
|
||||
visible: Object.entries(columnVisibility)
|
||||
.filter(([_, visible]) => visible !== false)
|
||||
.map(([col]) => col),
|
||||
order: columnOrder.length > 0 ? columnOrder : columns.map(c => c.id!).filter(Boolean)
|
||||
}}
|
||||
rowHref={(row) => `/orders/${row.id}`}
|
||||
emptyState={{
|
||||
message: t("orders.list.noRecordsMessage"),
|
||||
}}
|
||||
/>
|
||||
</Container>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user