feat(dashboard): refactor location list UI to use data table (#13571)
* wip: convert location list to a table * chore: changeset * fix: rm search bluring on loading change * feat: translations and palceholders, cleanup, make content more compact * fix: delete message * chore: optimise use memo * fix: update toast * feat: make stock location address searchable * fix: search input blur on load finish
This commit is contained in:
@@ -31,26 +31,26 @@ type DataTableActionProps = {
|
||||
label: string
|
||||
disabled?: boolean
|
||||
} & (
|
||||
| {
|
||||
| {
|
||||
to: string
|
||||
}
|
||||
| {
|
||||
| {
|
||||
onClick: () => void
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
type DataTableActionMenuActionProps = {
|
||||
label: string
|
||||
icon: ReactNode
|
||||
disabled?: boolean
|
||||
} & (
|
||||
| {
|
||||
| {
|
||||
to: string
|
||||
}
|
||||
| {
|
||||
| {
|
||||
onClick: () => void
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
type DataTableActionMenuGroupProps = {
|
||||
actions: DataTableActionMenuActionProps[]
|
||||
@@ -138,15 +138,18 @@ export const DataTable = <TData,>({
|
||||
const isViewConfigEnabled = useFeatureFlag("view_configurations")
|
||||
|
||||
// If view config is disabled, don't use column visibility features
|
||||
const effectiveEnableColumnVisibility = isViewConfigEnabled && enableColumnVisibility
|
||||
const effectiveEnableColumnVisibility =
|
||||
isViewConfigEnabled && enableColumnVisibility
|
||||
const effectiveEnableViewSelector = isViewConfigEnabled && enableViewSelector
|
||||
|
||||
const enableFiltering = filters && filters.length > 0
|
||||
const showFilterMenu = enableFilterMenu !== undefined ? enableFilterMenu : enableFiltering
|
||||
const showFilterMenu =
|
||||
enableFilterMenu !== undefined ? enableFilterMenu : enableFiltering
|
||||
const enableCommands = commands && commands.length > 0
|
||||
const enableSorting = columns.some((column) => column.enableSorting)
|
||||
|
||||
const [columnVisibility, setColumnVisibility] = React.useState<VisibilityState>(initialColumnVisibility)
|
||||
const [columnVisibility, setColumnVisibility] =
|
||||
React.useState<VisibilityState>(initialColumnVisibility)
|
||||
|
||||
// Update column visibility when initial visibility changes
|
||||
React.useEffect(() => {
|
||||
@@ -154,9 +157,12 @@ export const DataTable = <TData,>({
|
||||
const currentKeys = Object.keys(columnVisibility).sort()
|
||||
const newKeys = Object.keys(initialColumnVisibility).sort()
|
||||
|
||||
const hasChanged = currentKeys.length !== newKeys.length ||
|
||||
const hasChanged =
|
||||
currentKeys.length !== newKeys.length ||
|
||||
currentKeys.some((key, index) => key !== newKeys[index]) ||
|
||||
Object.entries(initialColumnVisibility).some(([key, value]) => columnVisibility[key] !== value)
|
||||
Object.entries(initialColumnVisibility).some(
|
||||
([key, value]) => columnVisibility[key] !== value
|
||||
)
|
||||
|
||||
if (hasChanged) {
|
||||
setColumnVisibility(initialColumnVisibility)
|
||||
@@ -164,10 +170,13 @@ export const DataTable = <TData,>({
|
||||
}, [initialColumnVisibility])
|
||||
|
||||
// Wrapper function to handle column visibility changes
|
||||
const handleColumnVisibilityChange = React.useCallback((visibility: VisibilityState) => {
|
||||
setColumnVisibility(visibility)
|
||||
onColumnVisibilityChange?.(visibility)
|
||||
}, [onColumnVisibilityChange])
|
||||
const handleColumnVisibilityChange = React.useCallback(
|
||||
(visibility: VisibilityState) => {
|
||||
setColumnVisibility(visibility)
|
||||
onColumnVisibilityChange?.(visibility)
|
||||
},
|
||||
[onColumnVisibilityChange]
|
||||
)
|
||||
|
||||
// Extract filter IDs for query param management
|
||||
const filterIds = useMemo(() => filters?.map((f) => f.id) ?? [], [filters])
|
||||
@@ -231,7 +240,7 @@ export const DataTable = <TData,>({
|
||||
Array.from(prev.keys()).forEach((key) => {
|
||||
if (prefixedFilterIds.includes(key)) {
|
||||
// Extract the unprefixed key
|
||||
const unprefixedKey = prefix ? key.replace(`${prefix}_`, '') : key
|
||||
const unprefixedKey = prefix ? key.replace(`${prefix}_`, "") : key
|
||||
if (!(unprefixedKey in value)) {
|
||||
prev.delete(key)
|
||||
}
|
||||
@@ -257,11 +266,14 @@ export const DataTable = <TData,>({
|
||||
}, [order])
|
||||
|
||||
// Memoize current configuration to prevent infinite loops
|
||||
const currentConfiguration = useMemo(() => ({
|
||||
filters: filtering,
|
||||
sorting: sorting,
|
||||
search: search,
|
||||
}), [filtering, sorting, search])
|
||||
const currentConfiguration = useMemo(
|
||||
() => ({
|
||||
filters: filtering,
|
||||
sorting: sorting,
|
||||
search: search,
|
||||
}),
|
||||
[filtering, sorting, search]
|
||||
)
|
||||
|
||||
const handleSortingChange = (value: DataTableSortingState) => {
|
||||
setSearchParams((prev) => {
|
||||
@@ -315,42 +327,43 @@ export const DataTable = <TData,>({
|
||||
onRowClick: rowHref ? onRowClick : undefined,
|
||||
pagination: enablePagination
|
||||
? {
|
||||
state: pagination,
|
||||
onPaginationChange: handlePaginationChange,
|
||||
}
|
||||
state: pagination,
|
||||
onPaginationChange: handlePaginationChange,
|
||||
}
|
||||
: undefined,
|
||||
filtering: enableFiltering
|
||||
? {
|
||||
state: filtering,
|
||||
onFilteringChange: handleFilteringChange,
|
||||
}
|
||||
state: filtering,
|
||||
onFilteringChange: handleFilteringChange,
|
||||
}
|
||||
: undefined,
|
||||
sorting: enableSorting
|
||||
? {
|
||||
state: sorting,
|
||||
onSortingChange: handleSortingChange,
|
||||
}
|
||||
state: sorting,
|
||||
onSortingChange: handleSortingChange,
|
||||
}
|
||||
: undefined,
|
||||
search: enableSearch
|
||||
? {
|
||||
state: search,
|
||||
onSearchChange: handleSearchChange,
|
||||
}
|
||||
state: search,
|
||||
onSearchChange: handleSearchChange,
|
||||
}
|
||||
: undefined,
|
||||
rowSelection,
|
||||
isLoading,
|
||||
columnVisibility: effectiveEnableColumnVisibility
|
||||
? {
|
||||
state: columnVisibility,
|
||||
onColumnVisibilityChange: handleColumnVisibilityChange,
|
||||
}
|
||||
: undefined,
|
||||
columnOrder: effectiveEnableColumnVisibility && columnOrder && onColumnOrderChange
|
||||
? {
|
||||
state: columnOrder,
|
||||
onColumnOrderChange: onColumnOrderChange,
|
||||
}
|
||||
state: columnVisibility,
|
||||
onColumnVisibilityChange: handleColumnVisibilityChange,
|
||||
}
|
||||
: undefined,
|
||||
columnOrder:
|
||||
effectiveEnableColumnVisibility && columnOrder && onColumnOrderChange
|
||||
? {
|
||||
state: columnOrder,
|
||||
onColumnOrderChange: onColumnOrderChange,
|
||||
}
|
||||
: undefined,
|
||||
})
|
||||
|
||||
const shouldRenderHeading = heading || subHeading
|
||||
@@ -358,7 +371,9 @@ export const DataTable = <TData,>({
|
||||
return (
|
||||
<UiDataTable
|
||||
instance={instance}
|
||||
className={layout === "fill" ? "h-full [&_tr]:last-of-type:!border-b" : undefined}
|
||||
className={
|
||||
layout === "fill" ? "h-full [&_tr]:last-of-type:!border-b" : undefined
|
||||
}
|
||||
>
|
||||
<UiDataTable.Toolbar
|
||||
className="flex flex-col items-start justify-between gap-2 md:flex-row md:items-center"
|
||||
@@ -397,7 +412,9 @@ export const DataTable = <TData,>({
|
||||
</div>
|
||||
)}
|
||||
{actionMenu && <ActionMenu variant="primary" {...actionMenu} />}
|
||||
{actions && actions.length > 0 && <DataTableActions actions={actions} />}
|
||||
{actions && actions.length > 0 && (
|
||||
<DataTableActions actions={actions} />
|
||||
)}
|
||||
{!actions && action && <DataTableAction {...action} />}
|
||||
</div>
|
||||
</div>
|
||||
@@ -407,7 +424,9 @@ export const DataTable = <TData,>({
|
||||
<UiDataTable.Pagination translations={paginationTranslations} />
|
||||
)}
|
||||
{enableCommands && (
|
||||
<UiDataTable.CommandBar selectedLabel={(count) => `${count} selected`} />
|
||||
<UiDataTable.CommandBar
|
||||
selectedLabel={(count) => `${count} selected`}
|
||||
/>
|
||||
)}
|
||||
</UiDataTable>
|
||||
)
|
||||
@@ -520,4 +539,3 @@ const DataTableActions = ({ actions }: { actions: DataTableActionProps[] }) => {
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user