mirror of
https://github.com/nowcommunity/nowdatabase.git
synced 2026-10-12 19:13:52 +03:00
Merge remote-tracking branch 'origin/main' into feature/occurrence-country-or-continent-filter
# Please enter a commit message to explain why this merge is necessary, # especially if it merges an updated upstream into a topic branch. # # Lines starting with '#' will be ignored, and an empty message aborts # the commit. Co-authored-by: karilint <19990676+karilint@users.noreply.github.com>
This commit is contained in:
@@ -0,0 +1,20 @@
|
||||
# Table column visibility (and exports)
|
||||
|
||||
Most tables in the application let you **show/hide columns**. This helps when working on smaller screens and when
|
||||
exporting data.
|
||||
|
||||
## Where to find it
|
||||
|
||||
- In a table header, use the **column visibility** button (next to the export/download button).
|
||||
- Some columns may be always visible (they are not hideable).
|
||||
|
||||
## What it does
|
||||
|
||||
- Hiding a column only affects the current table view.
|
||||
- Exported data follows the **current column visibility**: hide columns you do not want included before exporting.
|
||||
|
||||
## Tips
|
||||
|
||||
- If a table is wide, hide non-essential columns to reduce horizontal scrolling.
|
||||
- Use the table help (`?`) for reminders about sorting, filtering, and export behavior.
|
||||
|
||||
@@ -110,6 +110,7 @@ type DetailTabTableReadSelectProps<T extends MRT_RowData> = {
|
||||
clickableRows?: boolean
|
||||
enableColumnFilterModes?: boolean
|
||||
paginationPlacement?: 'top' | 'bottom' | 'both'
|
||||
tableContainerMaxHeight?: string | number
|
||||
}
|
||||
|
||||
type DetailTabTableEditProps<T extends MRT_RowData> = {
|
||||
@@ -126,6 +127,7 @@ type DetailTabTableEditProps<T extends MRT_RowData> = {
|
||||
renderRowActions?: MRT_TableOptions<T>['renderRowActions']
|
||||
muiTableBodyRowProps?: MRT_TableOptions<T>['muiTableBodyRowProps']
|
||||
tableName?: string
|
||||
tableContainerMaxHeight?: string | number
|
||||
}
|
||||
|
||||
type DetailTabTableProps<T extends MRT_RowData> = DetailTabTableReadSelectProps<T> | DetailTabTableEditProps<T>
|
||||
@@ -150,6 +152,7 @@ export const DetailTabTable = <T extends MRT_RowData>(props: DetailTabTableProps
|
||||
enableColumnFilterModes,
|
||||
paginationPlacement,
|
||||
isError,
|
||||
tableContainerMaxHeight = '60vh',
|
||||
} = props
|
||||
|
||||
const resolvedVisibleColumns: MRT_VisibilityState = visibleColumns
|
||||
@@ -177,6 +180,7 @@ export const DetailTabTable = <T extends MRT_RowData>(props: DetailTabTableProps
|
||||
enableColumnFilterModes={enableColumnFilterModes}
|
||||
paginationPlacement={paginationPlacement}
|
||||
isError={isError}
|
||||
tableContainerMaxHeight={tableContainerMaxHeight}
|
||||
/>
|
||||
)
|
||||
}
|
||||
@@ -194,6 +198,7 @@ const DetailTabEditableTable = <T extends MRT_RowData>({
|
||||
renderRowActions,
|
||||
muiTableBodyRowProps,
|
||||
tableName = 'table',
|
||||
tableContainerMaxHeight = '60vh',
|
||||
}: DetailTabTableEditProps<T>) => {
|
||||
const [pagination, setPagination] = useState<MRT_PaginationState>(paginationState ?? defaultEditPagination)
|
||||
|
||||
@@ -214,6 +219,13 @@ const DetailTabEditableTable = <T extends MRT_RowData>({
|
||||
enableRowActions,
|
||||
renderRowActions,
|
||||
muiTableBodyRowProps,
|
||||
muiTableContainerProps: {
|
||||
sx: {
|
||||
maxHeight: tableContainerMaxHeight,
|
||||
overflowY: 'auto',
|
||||
},
|
||||
},
|
||||
enableStickyHeader: true,
|
||||
})
|
||||
|
||||
return (
|
||||
|
||||
@@ -73,6 +73,7 @@ export const TableView = <T extends MRT_RowData>({
|
||||
isError,
|
||||
error,
|
||||
paginationPlacement,
|
||||
tableContainerMaxHeight,
|
||||
}: {
|
||||
data: T[] | undefined
|
||||
columns: MRT_ColumnDef<T>[]
|
||||
@@ -96,6 +97,7 @@ export const TableView = <T extends MRT_RowData>({
|
||||
filterFns?: Record<string, MRT_FilterFn<T>>
|
||||
renderRowActionExtras?: ({ row }: { row: MRT_Row<T> }) => ReactNode
|
||||
paginationPlacement?: 'top' | 'bottom' | 'both'
|
||||
tableContainerMaxHeight?: string | number
|
||||
}) => {
|
||||
const location = useLocation()
|
||||
const {
|
||||
@@ -252,6 +254,15 @@ export const TableView = <T extends MRT_RowData>({
|
||||
columns: columns,
|
||||
data: data || [],
|
||||
muiTableBodyRowProps: clickableRows || selectorFn ? muiTableBodyRowProps : undefined,
|
||||
muiTableContainerProps: tableContainerMaxHeight
|
||||
? {
|
||||
sx: {
|
||||
maxHeight: tableContainerMaxHeight,
|
||||
overflowY: 'auto',
|
||||
},
|
||||
}
|
||||
: undefined,
|
||||
enableStickyHeader: Boolean(tableContainerMaxHeight),
|
||||
state: {
|
||||
columnFilters,
|
||||
showColumnFilters: true,
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
import { describe, expect, it, jest } from '@jest/globals'
|
||||
import '@testing-library/jest-dom'
|
||||
import { fireEvent, render, screen } from '@testing-library/react'
|
||||
import { MemoryRouter } from 'react-router-dom'
|
||||
import { PageContextProvider } from '@/components/Page'
|
||||
import { TableToolBar } from '@/components/TableView/TableToolBar'
|
||||
|
||||
jest.mock('@/components/CrossSearch/CrossSearchExportMenuItem', () => ({
|
||||
CrossSearchExportMenuItem: ({ handleClose }: { handleClose: () => void }) => (
|
||||
<button type="button" onClick={handleClose}>
|
||||
Cross search export
|
||||
</button>
|
||||
),
|
||||
}))
|
||||
|
||||
jest.mock('../../components/CrossSearch/CrossSearchExportMenuItem', () => ({
|
||||
CrossSearchExportMenuItem: ({ handleClose }: { handleClose: () => void }) => (
|
||||
<button type="button" onClick={handleClose}>
|
||||
Cross search export
|
||||
</button>
|
||||
),
|
||||
}))
|
||||
|
||||
const exportRows = jest.fn()
|
||||
|
||||
jest.mock('@/components/TableView/helpers', () => ({
|
||||
exportRows: (...args: unknown[]) => exportRows(...args),
|
||||
}))
|
||||
|
||||
jest.mock('../../components/TableView/helpers', () => ({
|
||||
exportRows: (...args: unknown[]) => exportRows(...args),
|
||||
}))
|
||||
|
||||
const renderToolbar = (props?: Partial<React.ComponentProps<typeof TableToolBar>>) => {
|
||||
const table = {} as never
|
||||
const tableName = 'Test table'
|
||||
|
||||
return render(
|
||||
<MemoryRouter>
|
||||
<PageContextProvider
|
||||
editRights={{}}
|
||||
idFieldName="id"
|
||||
viewName="test"
|
||||
createTitle={() => ''}
|
||||
createSubtitle={() => ''}
|
||||
>
|
||||
<TableToolBar table={table} tableName={tableName} hideLeftButtons={true} {...props} />
|
||||
</PageContextProvider>
|
||||
</MemoryRouter>
|
||||
)
|
||||
}
|
||||
|
||||
describe('TableToolBar', () => {
|
||||
it('renders a column visibility button', () => {
|
||||
renderToolbar()
|
||||
|
||||
expect(screen.getByRole('button', { name: /show\/hide columns/i })).toBeTruthy()
|
||||
})
|
||||
|
||||
it('exports table rows from the export menu', () => {
|
||||
renderToolbar()
|
||||
|
||||
const exportButton = document.querySelector('#export-button')
|
||||
expect(exportButton).toBeTruthy()
|
||||
|
||||
fireEvent.click(exportButton as HTMLElement)
|
||||
|
||||
fireEvent.click(screen.getByRole('menuitem', { name: /export table/i }))
|
||||
|
||||
expect(exportRows).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
|
||||
it('renders the cross-search export menu item when enabled', () => {
|
||||
renderToolbar({ isCrossSearchTable: true })
|
||||
|
||||
const exportButton = document.querySelector('#export-button')
|
||||
expect(exportButton).toBeTruthy()
|
||||
|
||||
fireEvent.click(exportButton as HTMLElement)
|
||||
|
||||
expect(screen.getByRole('button', { name: /cross search export/i })).toBeTruthy()
|
||||
expect(screen.queryByRole('menuitem', { name: /export table/i })).toBeNull()
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user