Last modified: 4/Oct/2024
Table Migration Guide
These examples are exact examples from the MK code
#Columns
#Old Column definition
{
title: <Translation path="sites.thName" />,
dataIndex: 'displayName',
key: 'displayName',
isFixed,
defaultSortOrder: 'ascend',
width: {
min: '170px',
max: '500px',
},
sorter: (a, b) => {
return a.displayName?.localeCompare(b.displayName)
},
render: function displayName(_: unknown, site) {
return (
<DisplayName
site={site}
idCompany={idCompany}
dataTest="table-siteName"
/>
)
},
},
#New Column definition
{ id: 'displayName', header: () => <Translation path="sites.thName" />, accessorKey: 'displayName', isFixed, minSize: 170, maxSize: 500, enableGlobalFilter: true, // to enable this column in global search filterFn: (row, _, term) => row.original.siteLabels?.some(({ name }) => name === term), // function to call when global search cell: ({ row }) => { return ( <DisplayName site={row.original} idCompany={idCompany} dataTest="table-siteName" /> ) }, },
#Search
#Old search config
<Table ... search={getSearchConfig()} /> const getSearchConfig: () => SearchObject<ExtendedSiteData> = () => ({ inputProps: { placeholder: dangerously_getTranslation({ path: 'sites.searchPlaceholder', }), hasAutoFocus: true, }, filter: (value, row) => sitesFilter(value, row, rbac), })
#New search config
<Table3 ... isGlobalFilterEnabled={true} globalFilterOptions={{ placeholder: dangerously_getTranslation({ path: 'sites.searchPlaceholder', }), hasAutoFocus: true, globalFilterFn: (row: any, _: unknown, term: string) => sitesFilter(term, row.original, rbac), }} />
#Filters
#Old filters config
filters={[ { allItemsText: dangerously_getTranslation({ path: 'sites.allLabels', }), filter: (value, row) => row.siteLabels?.some(({ name }) => name === value), filterOptions: siteLabels.map(({ name }) => ({ value: name, label: name, })), }, ]}
#New filters config
isFiltersEnabled={true} filters={[ { allItemsText: dangerously_getTranslation({ path: 'sites.allLabels', }), filterOptions: siteLabels.map(({ name }) => ({ value: name, label: name, })), column: 'displayName', // which columns shouold be filtered with this filter }, ]}
#Row menu
#Old row menu config
const rowMenuItems = (dataSource: ExtendedSiteData[]) => { const rowMenuItems: RowMenuItem<ExtendedSiteData>[] = [] rowMenuItems.push({ label: dangerously_getTranslation({ path: 'sites.labelSite' }), onClick: idSite => setSiteLabelsToEdit(dataSource.filter(({ id }) => id === idSite)), isMenuItemHidden: idSite => !canLabelSite(idSite), }) if (canTransferSite) { rowMenuItems.push({ label: dangerously_getTranslation({ path: 'sites.transferSite' }), onClick: idSite => { const site = dataSource.find(site => site.id === idSite) ?? null const intHostName = site?.environment?.activeContainer.lxdServer?.intHostname || '' const segments = intHostName.split('-') const hostNameLastSegment = segments[segments.length - 1] const isDedicated = hostNameLastSegment ? hostNameLastSegment.startsWith('9') : false if (isDedicated) { setIsDedicatedLxdServer(true) } else { setSiteToTransfer(site) } }, }) } rowMenuItems.push({ label: ( <span style={{ display: 'flex', alignItems: 'center' }}> <Translation path="sites.renameSite" /> </span> ), onClick: idSite => setSiteToRename(dataSource.find(site => site.id === idSite) ?? null), isMenuItemHidden: idSite => !canRenameSite(idSite), }) return rowMenuItems } <Table rowMenu={{ isDisabled: site => site.isIncomingSite || !site.canOpenManage, items: rowMenuItems(dataSource), }} />
#New rowmenu
const rowMenuItems = (dataSource: ExtendedSiteData[]) => { const rowMenuItems: RowMenuItem3<ExtendedSiteData>[] = [] rowMenuItems.push({ label: dangerously_getTranslation({ path: 'sites.labelSite' }), onSelect: row => setSiteLabelsToEdit(dataSource.filter(({ id }) => id === row.id)), isHidden: row => !canLabelSite(row.id), }) if (canTransferSite) { rowMenuItems.push({ label: dangerously_getTranslation({ path: 'sites.transferSite' }), onSelect: row => { const site = dataSource.find(site => site.id === row.id) ?? null const intHostName = site?.environment?.activeContainer.lxdServer?.intHostname || '' const segments = intHostName.split('-') const hostNameLastSegment = segments[segments.length - 1] const isDedicated = hostNameLastSegment ? hostNameLastSegment.startsWith('9') : false if (isDedicated) { setIsDedicatedLxdServer(true) } else { setSiteToTransfer(site) } }, }) } rowMenuItems.push({ label: dangerously_getTranslation({ path: 'sites.renameSite' }), onSelect: row => setSiteToRename(dataSource.find(site => site.id === row.id) ?? null), isHidden: row => !canRenameSite(row.id), }) return rowMenuItems } <Table rowMenu={{ isDisabled: (site: ExtendedSiteData) => site.isIncomingSite || !site.canOpenManage, items: rowMenuItems3(dataSource), }} />
#onRowClick
#Old onRowClick
onRow={site => ({ onClick: e => { if ( e.target instanceof Element && (e.target.nodeName === 'INPUT' || e.target.nodeName === 'svg' || e.target.nodeName === 'LABEL' || e.target.nodeName === 'SPAN') ) { return } if ( (site.isIncomingSite && site.status !== 'deleting') || site.canOpenManage ) { navigate( RouterObject.sites.details.getLink({ idCompany, id: site.id, env: site.environment?.id || 'id', }) ) } }, })}
#New onRowClick
onRowClick={(site: ExtendedSiteData) => {
if (
(site.isIncomingSite && site.status !== 'deleting') ||
site.canOpenManage
) {
navigate(
RouterObject.sites.details.getLink({
idCompany,
id: site.id,
env: site.environment?.id || 'id',
})
)
}
}}
#MultiSelect
#Old multiSelect
multiSelect={
sites.some(({ id }) => canLabelSite(id))
? {
isDisabled: site =>
site.isIncomingSite ||
!site.canOpenManage ||
!canLabelSite(site.id),
selectionLabel: function label(count) {
return (
<Translation
path="sites.sitesSelected"
args={{ count }}
/>
)
},
actionButtonProps: [
{
type: 'secondary',
onClick: setSiteLabelsToEdit,
label: function label(count) {
return (
<Translation
path="sites.labelSites"
args={{ count }}
/>
)
},
},
],
}
: undefined
}
#New multiSelect
multiselect={
sites.some(({ id }) => canLabelSite(id))
? {
isRowDisabled: (site: ExtendedSiteData) =>
site.isIncomingSite ||
!site.canOpenManage ||
!canLabelSite(site.id),
selectionLabel: (count: number) => (
<Translation
path="sites.sitesSelected"
args={{ count }}
/>
),
actions: [
{
type: 'secondary',
onClick: setSiteLabelsToEdit,
label: (rows: ExtendedSiteData[]) => (
<Translation
path="sites.labelSites"
args={{ count: rows.length }}
/>
),
},
],
}
: undefined
}
#Empty
#Old empty
empty={resetFilters => (
<Base>
<Translation path="sites.noSitesWithFilter.text" />{' '}
<Translation
style={{ display: 'inline' }}
as={Link}
href="#"
onClick={() => {
resetFilters()
setLabelFilter(ALL_LABELS_FILTER)
}}
path="sites.noSitesWithFilter.link"
/>
</Base>
)}
#New empty
empty={{
render: (_: unknown, resetFilters: () => void) => (
<Base>
<Translation path="sites.noSitesWithFilter.text" />{' '}
<Translation
style={{ display: 'inline' }}
as={Link}
href="#"
onClick={() => {
resetFilters()
setLabelFilter(ALL_LABELS_FILTER)
}}
path="sites.noSitesWithFilter.link"
/>
</Base>
),
}}
/>
#The following props can be used as the as in the old table
data additionalActions rowClassName isLoading