Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 73 additions & 4 deletions frontend/src/components/App/Home/ClusterTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,17 @@ import Box from '@mui/material/Box';
import Button from '@mui/material/Button';
import { useTheme } from '@mui/material/styles';
import Typography from '@mui/material/Typography';
import { useMemo } from 'react';
import {
MRT_ColumnFiltersState,
MRT_SortingState,
MRT_VisibilityState,
} from 'material-react-table';
import { useCallback, useMemo, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { generatePath, useHistory } from 'react-router-dom';
import { getClusterAppearanceFromMeta } from '../../../helpers/clusterAppearance';
import { isElectron } from '../../../helpers/isElectron';
import { loadTableSettings, storeTableSettings } from '../../../helpers/tableSettings';
import { formatClusterPathParam } from '../../../lib/cluster';
import { useClustersConf, useClustersVersion } from '../../../lib/k8s';
import { ApiError } from '../../../lib/k8s/api/v2/ApiError';
Expand All @@ -34,6 +40,7 @@ import { useTypedSelector } from '../../../redux/hooks';
import { Loader } from '../../common';
import Link from '../../common/Link';
import Table from '../../common/Table';
import { useLocalStorageState } from '../../globalSearch/useLocalStorageState';
import ClusterBadge from '../../Sidebar/ClusterBadge';
import ClusterContextMenu from './ClusterContextMenu';
import { MULTI_HOME_ENABLED } from './config';
Expand Down Expand Up @@ -115,6 +122,8 @@ export interface ClusterTableProps {
/**
* ClusterTable component displays a table of clusters with their status, origin, and version.
*/
const CLUSTER_TABLE_ID = 'home-clusters';

export default function ClusterTable({
customNameClusters,
versions,
Expand All @@ -125,6 +134,54 @@ export default function ClusterTable({
const history = useHistory();
const { t } = useTranslation(['translation']);

const [columnVisibility, setColumnVisibility] = useState<MRT_VisibilityState>(() => {
const visibility: Record<string, boolean> = {};
const stored = loadTableSettings(CLUSTER_TABLE_ID);
stored.forEach(({ id, show }) => (visibility[id] = show));
return visibility;
});

const [sorting, setSorting] = useLocalStorageState<MRT_SortingState>(
`table_sorting.${CLUSTER_TABLE_ID}`,
[{ id: 'name', desc: false }]
);

const [columnFilters, setColumnFilters] = useLocalStorageState<MRT_ColumnFiltersState>(
`table_filters.${CLUSTER_TABLE_ID}`,
[]
);

const handleColumnVisibilityChange = useCallback(
(updater: MRT_VisibilityState | ((old: MRT_VisibilityState) => MRT_VisibilityState)) => {
setColumnVisibility(oldCols => {
const newCols = typeof updater === 'function' ? updater(oldCols) : updater;
const colsToStore = Object.entries(newCols).map(([id, show]) => ({
id,
show: (show ?? true) as boolean,
}));
storeTableSettings(CLUSTER_TABLE_ID, colsToStore);
return newCols;
});
},
[]
);

const handleSortingChange = useCallback(
(updater: MRT_SortingState | ((old: MRT_SortingState) => MRT_SortingState)) => {
setSorting(old => (typeof updater === 'function' ? updater(old) : updater));
},
[setSorting]
);

const handleColumnFiltersChange = useCallback(
(
updater: MRT_ColumnFiltersState | ((old: MRT_ColumnFiltersState) => MRT_ColumnFiltersState)
) => {
setColumnFilters(old => (typeof updater === 'function' ? updater(old) : updater));
},
[setColumnFilters]
);

/**
* Gets the origin of a cluster.
*
Expand Down Expand Up @@ -206,22 +263,29 @@ export default function ClusterTable({
},
},
{
id: 'origin',
header: t('Origin'),
accessorFn: cluster => getOrigin(cluster),
Cell: ({ row: { original } }) => (
<Typography variant="body2">{getOrigin((clusters || {})[original.name])}</Typography>
),
},
{
id: 'status',
header: t('Status'),
accessorFn: cluster =>
errors[cluster?.name] === null ? 'Active' : errors[cluster?.name]?.message,
Cell: ({ row: { original } }) => (
<ClusterStatus error={errors[original.name]} cluster={original} />
),
},
{ header: t('Warnings'), accessorFn: cluster => warningLabels[cluster?.name] },
{
id: 'warnings',
header: t('Warnings'),
accessorFn: cluster => warningLabels[cluster?.name],
},
{
id: 'version',
header: t('glossary|Kubernetes Version'),
accessorFn: ({ name }) => versions[name]?.gitVersion || '⋯',
},
Expand Down Expand Up @@ -250,9 +314,14 @@ export default function ClusterTable({
}
: false
}
initialState={{
sorting: [{ id: 'name', desc: false }],
state={{
columnVisibility,
sorting,
columnFilters,
}}
onColumnVisibilityChange={handleColumnVisibilityChange}
onSortingChange={handleSortingChange}
onColumnFiltersChange={handleColumnFiltersChange}
muiToolbarAlertBannerProps={{
sx: theme => ({
background: theme.palette.background.muted,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,7 @@
</th>
<th
aria-sort="none"
class="MuiTableCell-root MuiTableCell-head MuiTableCell-alignLeft MuiTableCell-sizeMedium css-11ihby4-MuiTableCell-root"
class="MuiTableCell-root MuiTableCell-head MuiTableCell-alignLeft MuiTableCell-sizeMedium css-4ks04s-MuiTableCell-root"
colspan="1"
data-can-sort="true"
data-index="-1"
Expand Down Expand Up @@ -384,7 +384,7 @@
</th>
<th
aria-sort="none"
class="MuiTableCell-root MuiTableCell-head MuiTableCell-alignLeft MuiTableCell-sizeMedium css-9s5e2s-MuiTableCell-root"
class="MuiTableCell-root MuiTableCell-head MuiTableCell-alignLeft MuiTableCell-sizeMedium css-13c0hsi-MuiTableCell-root"
colspan="1"
data-can-sort="true"
data-index="-1"
Expand Down Expand Up @@ -439,7 +439,7 @@
</th>
<th
aria-sort="none"
class="MuiTableCell-root MuiTableCell-head MuiTableCell-alignLeft MuiTableCell-sizeMedium css-usbwln-MuiTableCell-root"
class="MuiTableCell-root MuiTableCell-head MuiTableCell-alignLeft MuiTableCell-sizeMedium css-rymsnu-MuiTableCell-root"
colspan="1"
data-can-sort="true"
data-index="-1"
Expand Down Expand Up @@ -494,7 +494,7 @@
</th>
<th
aria-sort="none"
class="MuiTableCell-root MuiTableCell-head MuiTableCell-alignLeft MuiTableCell-sizeMedium css-19o1a0j-MuiTableCell-root"
class="MuiTableCell-root MuiTableCell-head MuiTableCell-alignLeft MuiTableCell-sizeMedium css-1bc3cd9-MuiTableCell-root"
colspan="1"
data-can-sort="true"
data-index="-1"
Expand Down Expand Up @@ -629,7 +629,7 @@
</a>
</td>
<td
class="MuiTableCell-root MuiTableCell-alignLeft MuiTableCell-sizeMedium css-2wxm0s-MuiTableCell-root"
class="MuiTableCell-root MuiTableCell-alignLeft MuiTableCell-sizeMedium css-1fu0nlf-MuiTableCell-root"
>
<p
class="MuiTypography-root MuiTypography-body2 css-ab4e19-MuiTypography-root"
Expand All @@ -638,7 +638,7 @@
</p>
</td>
<td
class="MuiTableCell-root MuiTableCell-alignLeft MuiTableCell-sizeMedium css-1qzqemr-MuiTableCell-root"
class="MuiTableCell-root MuiTableCell-alignLeft MuiTableCell-sizeMedium css-1n4xkg0-MuiTableCell-root"
>
<div
class="MuiBox-root css-1gtanqs"
Expand All @@ -656,12 +656,12 @@
</div>
</td>
<td
class="MuiTableCell-root MuiTableCell-alignLeft MuiTableCell-sizeMedium css-1yl63d8-MuiTableCell-root"
class="MuiTableCell-root MuiTableCell-alignLeft MuiTableCell-sizeMedium css-17iljsw-MuiTableCell-root"
>
0
</td>
<td
class="MuiTableCell-root MuiTableCell-alignLeft MuiTableCell-sizeMedium css-i01a7i-MuiTableCell-root"
class="MuiTableCell-root MuiTableCell-alignLeft MuiTableCell-sizeMedium css-1qb9npk-MuiTableCell-root"
>
</td>
Expand Down Expand Up @@ -737,7 +737,7 @@
</a>
</td>
<td
class="MuiTableCell-root MuiTableCell-alignLeft MuiTableCell-sizeMedium css-2wxm0s-MuiTableCell-root"
class="MuiTableCell-root MuiTableCell-alignLeft MuiTableCell-sizeMedium css-1fu0nlf-MuiTableCell-root"
>
<p
class="MuiTypography-root MuiTypography-body2 css-ab4e19-MuiTypography-root"
Expand All @@ -746,7 +746,7 @@
</p>
</td>
<td
class="MuiTableCell-root MuiTableCell-alignLeft MuiTableCell-sizeMedium css-1qzqemr-MuiTableCell-root"
class="MuiTableCell-root MuiTableCell-alignLeft MuiTableCell-sizeMedium css-1n4xkg0-MuiTableCell-root"
>
<div
class="MuiBox-root css-1gtanqs"
Expand All @@ -764,12 +764,12 @@
</div>
</td>
<td
class="MuiTableCell-root MuiTableCell-alignLeft MuiTableCell-sizeMedium css-1yl63d8-MuiTableCell-root"
class="MuiTableCell-root MuiTableCell-alignLeft MuiTableCell-sizeMedium css-17iljsw-MuiTableCell-root"
>
0
</td>
<td
class="MuiTableCell-root MuiTableCell-alignLeft MuiTableCell-sizeMedium css-i01a7i-MuiTableCell-root"
class="MuiTableCell-root MuiTableCell-alignLeft MuiTableCell-sizeMedium css-1qb9npk-MuiTableCell-root"
>
</td>
Expand Down Expand Up @@ -845,7 +845,7 @@
</a>
</td>
<td
class="MuiTableCell-root MuiTableCell-alignLeft MuiTableCell-sizeMedium css-2wxm0s-MuiTableCell-root"
class="MuiTableCell-root MuiTableCell-alignLeft MuiTableCell-sizeMedium css-1fu0nlf-MuiTableCell-root"
>
<p
class="MuiTypography-root MuiTypography-body2 css-ab4e19-MuiTypography-root"
Expand All @@ -854,7 +854,7 @@
</p>
</td>
<td
class="MuiTableCell-root MuiTableCell-alignLeft MuiTableCell-sizeMedium css-1qzqemr-MuiTableCell-root"
class="MuiTableCell-root MuiTableCell-alignLeft MuiTableCell-sizeMedium css-1n4xkg0-MuiTableCell-root"
>
<div
class="MuiBox-root css-1gtanqs"
Expand All @@ -872,12 +872,12 @@
</div>
</td>
<td
class="MuiTableCell-root MuiTableCell-alignLeft MuiTableCell-sizeMedium css-1yl63d8-MuiTableCell-root"
class="MuiTableCell-root MuiTableCell-alignLeft MuiTableCell-sizeMedium css-17iljsw-MuiTableCell-root"
>
0
</td>
<td
class="MuiTableCell-root MuiTableCell-alignLeft MuiTableCell-sizeMedium css-i01a7i-MuiTableCell-root"
class="MuiTableCell-root MuiTableCell-alignLeft MuiTableCell-sizeMedium css-1qb9npk-MuiTableCell-root"
>
</td>
Expand Down
39 changes: 1 addition & 38 deletions frontend/src/components/common/Resource/ResourceTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import {
useState,
} from 'react';
import { useTranslation } from 'react-i18next';
import { loadTableSettings, storeTableSettings } from '../../../helpers/tableSettings';
import { useSelectedClusters } from '../../../lib/k8s';
import { ApiError } from '../../../lib/k8s/api/v2/ApiError';
import { KubeObject } from '../../../lib/k8s/KubeObject';
Expand Down Expand Up @@ -209,44 +210,6 @@ function TableFromResourceClass<KubeClass extends KubeObjectClass>(
);
}

/**
* Store the table settings in local storage.
*
* @param tableId - The ID of the table.
* @param columns - The columns to store.
* @returns void
*/
function storeTableSettings(tableId: string, columns: { id?: string; show: boolean }[]) {
if (!tableId) {
console.debug('storeTableSettings: tableId is empty!', new Error().stack);
return;
}

const columnsWithIds = columns.map((c, i) => ({ id: i.toString(), ...c }));
// Delete the entry if there are no settings to store.
if (columnsWithIds.length === 0) {
localStorage.removeItem(`table_settings.${tableId}`);
return;
}
localStorage.setItem(`table_settings.${tableId}`, JSON.stringify(columnsWithIds));
}

/**
* Load the table settings from local storage for a given table ID.
*
* @param tableId - The ID of the table.
* @returns The table settings for the given table ID.
*/
function loadTableSettings(tableId: string): { id: string; show: boolean }[] {
if (!tableId) {
console.debug('loadTableSettings: tableId is empty!', new Error().stack);
return [];
}

const settings = JSON.parse(localStorage.getItem(`table_settings.${tableId}`) || '[]');
return settings;
}

/**
* Here we figure out which columns are visible and not visible
* We can control it using show property in the columns prop {@link ResourceTableColumn}
Expand Down
Loading