diff --git a/package-lock.json b/package-lock.json index edd2501aa..1da6257be 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6,7 +6,7 @@ "packages": { "": { "name": "@flanksource/flanksource-ui", - "version": "1.0.810", + "version": "1.0.813", "dependencies": { "@babel/plugin-proposal-private-property-in-object": "^7.21.11", "@clerk/nextjs": "^5.3.0", diff --git a/src/api/types/configs.ts b/src/api/types/configs.ts index 08058a8e6..6596df2c5 100644 --- a/src/api/types/configs.ts +++ b/src/api/types/configs.ts @@ -128,7 +128,7 @@ export interface ConfigAnalysis extends Analysis, CreatedAt, Avatar { export type ConfigSummary = { type: string; analysis?: Record; - changes?: string; + changes?: number; count: number; health: { healthy: number; diff --git a/src/components/Configs/ConfigList/Cells/ConfigListCostCell.tsx b/src/components/Configs/ConfigList/Cells/ConfigListCostCell.tsx index 70b738b2f..4fbb7401e 100644 --- a/src/components/Configs/ConfigList/Cells/ConfigListCostCell.tsx +++ b/src/components/Configs/ConfigList/Cells/ConfigListCostCell.tsx @@ -1,3 +1,4 @@ +import { MRTCellProps } from "@flanksource-ui/ui/MRTDataTable/MRTCellProps"; import { CellContext, Row } from "@tanstack/react-table"; import { MRT_Row } from "mantine-react-table"; import { @@ -9,7 +10,7 @@ import ConfigCostValue from "../../ConfigCosts/ConfigCostValue"; export default function ConfigListCostCell({ row -}: CellContext | CellContext) { +}: MRTCellProps | MRTCellProps) { return ; } /** diff --git a/src/components/Configs/ConfigList/MRTConfigListColumn.tsx b/src/components/Configs/ConfigList/MRTConfigListColumn.tsx index 757634991..4be63d7fb 100644 --- a/src/components/Configs/ConfigList/MRTConfigListColumn.tsx +++ b/src/components/Configs/ConfigList/MRTConfigListColumn.tsx @@ -38,8 +38,8 @@ export const mrtConfigListColumns: MRT_ColumnDef[] = [ ); }, - minSize: 200, - size: 270, + minSize: 300, + size: 400, enableGrouping: true, enableSorting: true, enableHiding: false, @@ -78,7 +78,7 @@ export const mrtConfigListColumns: MRT_ColumnDef[] = [ { header: "Type", accessorKey: "type", - size: 170, + size: 250, enableSorting: true, enableHiding: true, enableColumnActions: false, @@ -89,8 +89,6 @@ export const mrtConfigListColumns: MRT_ColumnDef[] = [ { header: "Status", accessorKey: "health", - minSize: 100, - maxSize: 180, enableSorting: true, enableColumnActions: false, Cell: ({ cell, row }) => { @@ -133,7 +131,6 @@ export const mrtConfigListColumns: MRT_ColumnDef[] = [ return ; }, - size: 70, meta: { cellClassName: "overflow-hidden" }, @@ -149,9 +146,7 @@ export const mrtConfigListColumns: MRT_ColumnDef[] = [ enableFilterByTag filterByTagParamKey="labels" /> - ), - maxSize: 300, - minSize: 100 + ) }, { header: "Analysis", @@ -212,9 +207,7 @@ export const mrtConfigListColumns: MRT_ColumnDef[] = [ /> ); - }, - minSize: 50, - maxSize: 100 + } }, { header: "Cost", @@ -231,38 +224,37 @@ export const mrtConfigListColumns: MRT_ColumnDef[] = [ }, Cell: ({ row }) => { return ; - }, - maxSize: 60 + } }, { header: "Created", accessorKey: "created_at", enableColumnActions: false, Cell: MRTConfigListDateCell, - maxSize: 70 + maxSize: 100 }, { header: "Updated", accessorKey: "updated_at", enableColumnActions: false, Cell: MRTConfigListDateCell, - maxSize: 70 + maxSize: 100 }, { header: "Deleted At", accessorKey: "deleted_at", enableColumnActions: false, Cell: MRTConfigListDateCell, - size: 90, - enableHiding: true + enableHiding: true, + maxSize: 100 }, { header: "Changed", enableColumnActions: false, accessorFn: changeColumnAccessorFN, id: "changed", + maxSize: 100 // sortingFn: changeColumnSortingFN, - size: 180 } ]; diff --git a/src/components/Configs/ConfigSummary/Cells/ConfigSummaryHealthCells.tsx b/src/components/Configs/ConfigSummary/Cells/ConfigSummaryHealthCells.tsx index 666671db0..c8316f608 100644 --- a/src/components/Configs/ConfigSummary/Cells/ConfigSummaryHealthCells.tsx +++ b/src/components/Configs/ConfigSummary/Cells/ConfigSummaryHealthCells.tsx @@ -1,22 +1,22 @@ import { ConfigSummary } from "@flanksource-ui/api/types/configs"; -import { CellContext } from "@tanstack/react-table"; -import { useMemo } from "react"; -import { useSearchParams } from "react-router-dom"; -import { getConfigStatusColor } from "../ConfigSummaryList"; import { Count, CountBar, OrderByColor } from "@flanksource-ui/ui/Icons/ChangeCount"; +import { MRTCellProps } from "@flanksource-ui/ui/MRTDataTable/MRTCellProps"; +import { useMemo } from "react"; +import { useSearchParams } from "react-router-dom"; +import { getConfigStatusColor } from "../ConfigSummaryList"; export function ConfigSummaryHealthCell({ - getValue, + cell, row -}: CellContext) { +}: MRTCellProps) { const [searchParams] = useSearchParams(); - const value = getValue(); + const value = cell.getValue(); const type = row.original.type; const groupBy = searchParams.get("groupBy"); @@ -59,8 +59,8 @@ export function ConfigSummaryHealthCell({ export function ConfigSummaryHealthAggregateCell({ row -}: CellContext) { - const value = row.subRows.reduce( +}: Pick, "row">) { + const value = row.subRows?.reduce( (acc, row) => { const health = row.original.health; if (health) { diff --git a/src/components/Configs/ConfigSummary/Cells/ConfigSummaryTableVirtualAggregateColumn.tsx b/src/components/Configs/ConfigSummary/Cells/ConfigSummaryTableVirtualAggregateColumn.tsx index a91db98d4..cf149be4d 100644 --- a/src/components/Configs/ConfigSummary/Cells/ConfigSummaryTableVirtualAggregateColumn.tsx +++ b/src/components/Configs/ConfigSummary/Cells/ConfigSummaryTableVirtualAggregateColumn.tsx @@ -1,15 +1,17 @@ import { ConfigSummary } from "@flanksource-ui/api/types/configs"; import { Badge } from "@flanksource-ui/ui/Badge/Badge"; -import { CellContext } from "@tanstack/react-table"; -import { IoChevronDown, IoChevronForward } from "react-icons/io5"; +import { MRTCellProps } from "@flanksource-ui/ui/MRTDataTable/MRTCellProps"; import ConfigsTypeIcon from "../../ConfigsTypeIcon"; export function ConfigSummaryTableVirtualAggregateColumn({ row -}: CellContext) { +}: Pick, "row">) { if (row.getCanExpand()) { const groupingValue = row.getGroupingValue(row.groupingColumnId!) as string; - const count = row.subRows.reduce((acc, row) => acc + row.original.count, 0); + const count = row.subRows?.reduce( + (acc, row) => acc + row.original.count, + 0 + ); return (
- {row.getIsExpanded() ? : } {row.groupingColumnId === "type" || row.groupingColumnId === "config_class" ? ( & { + columnId, + cell +}: MRTCellProps & { groupByTags: string[]; columnId: string; }) { const isTag = groupByTags.includes(columnId); - const value = getValue(); + const value = cell.getValue(); return (
) { - const configType = getValue(); +function ConfigSummaryTypeCell({ cell, row }: MRTCellProps) { + const configType = cell.getValue(); const configCount = row.original.count; @@ -52,12 +51,7 @@ function ConfigSummaryTypeCell({ }, [configType]); return ( - +
@@ -71,9 +65,9 @@ function ConfigSummaryTypeCell({ } export function ConfigSummaryAnalysisCell({ - getValue -}: Pick, any>, "getValue">) { - const value = getValue(); + cell +}: Pick, "cell">) { + const value = cell.getValue(); if (!value) { return null; } @@ -142,69 +136,80 @@ function ConfigSummaryAnalysisAggregateCell({ ); } -const configSummaryColumns: ColumnDef[] = [ +const configSummaryColumns: MRT_ColumnDef[] = [ { header: "changes", accessorKey: "changes", - aggregatedCell: ({ getValue }) => { - const value = getValue(); + enableGrouping: false, + enableHiding: false, + AggregatedCell: ({ cell }) => { + const value = cell.getValue(); if (!value) { return null; } return ; }, - cell: ({ getValue }: CellContext) => { - const value = getValue(); + Cell: ({ cell }) => { + const value = cell.getValue(); if (!value) { return null; } return ; - }, - size: 40 + } + // size: 100 }, { header: "Health", accessorKey: "health", - minSize: 50, - maxSize: 100, - cell: ConfigSummaryHealthCell, - aggregatedCell: ConfigSummaryHealthAggregateCell + enableGrouping: false, + enableHiding: false, + // minSize: 50, + // maxSize: 100, + Cell: ConfigSummaryHealthCell, + AggregatedCell: ConfigSummaryHealthAggregateCell }, { header: "analysis", accessorKey: "analysis", - cell: ConfigSummaryAnalysisCell, - aggregatedCell: (props) => ( + enableGrouping: false, + enableHiding: false, + Cell: ConfigSummaryAnalysisCell, + AggregatedCell: (props) => ( // @ts-ignore for some reason the cell type is not being inferred correctly - ), - minSize: 30, - maxSize: 100 + ) + // minSize: 30, + // maxSize: 100 }, { - header: () =>
Cost (30d)
, + header: "Cost (30d)", accessorKey: "cost_total_30d", - cell: ConfigListCostCell, - maxSize: 60 + enableGrouping: false, + enableHiding: false, + Cell: ConfigListCostCell + // maxSize: 60 }, { header: "Created", accessorKey: "created_at", - cell: ConfigListDateCell, - aggregatedCell: "", - maxSize: 40 + enableGrouping: false, + enableHiding: false, + Cell: MRTConfigListDateCell + // maxSize: 40 }, { header: "Updated", accessorKey: "updated_at", - cell: ConfigListDateCell, - aggregatedCell: "", - maxSize: 40 + enableGrouping: false, + enableHiding: false, + Cell: MRTConfigListDateCell + // maxSize: 40 }, { header: "Is Favorite", accessorKey: "isFavorite", - enableHiding: true + enableHiding: true, + id: "favorite" } ]; @@ -233,10 +238,10 @@ export default function ConfigSummaryList({ }, [params]); const handleRowClick = useCallback( - (row: Row) => { + (configSummary: ConfigSummary) => { params.delete("labels"); if (groupBy.includes("type")) { - const { type } = row.original; + const { type } = configSummary; params.set("configType", type); } const tags = groupBy @@ -247,12 +252,12 @@ export default function ConfigSummaryList({ column !== "status" && column !== "config_class" ) - .filter((column) => row.original[column as keyof ConfigSummary]); + .filter((column) => configSummary[column as keyof ConfigSummary]); if (tags.length > 0) { const tagsParam = tags .map((column) => { return `${column}__:__${ - row.original[column as keyof ConfigSummary] + configSummary[column as keyof ConfigSummary] }`; }) .join(","); @@ -269,10 +274,11 @@ export default function ConfigSummaryList({ return { header: column.toLocaleUpperCase(), accessorKey: column, - maxSize: 250, - minSize: 100, - aggregatedCell: ConfigSummaryTableVirtualAggregateColumn, - cell: + enableGrouping: false, + enableHiding: false, + size: 400, + AggregatedCell: ConfigSummaryTableVirtualAggregateColumn, + Cell: column === "type" ? ConfigSummaryTypeCell : (props) => ( @@ -282,7 +288,7 @@ export default function ConfigSummaryList({ columnId={column} /> ) - } satisfies ColumnDef; + } satisfies MRT_ColumnDef; }); return [...newColumns, ...configSummaryColumns]; }, [groupBy, groupByTags]); @@ -291,31 +297,24 @@ export default function ConfigSummaryList({ // isFavorite column const hiddenColumns = useMemo(() => { const list = groupBy.length > 1 ? groupBy.slice(0, groupBy.length - 1) : []; - return [...list, "isFavorite"]; + return [...list, "favorite"]; }, [groupBy]); return ( - 1 ? groupBy.slice(0, groupBy.length - 1) : undefined } - tableSortByState={[ - { - desc: false, - id: "isFavorite" - } - ]} hiddenColumns={hiddenColumns} - handleRowClick={handleRowClick} - tableStyle={{ borderSpacing: "0" }} + onRowClick={handleRowClick} isLoading={isLoading} - className="max-w-full table-auto table-fixed overflow-x-auto" - savePreferences={false} expandAllRows={groupBy[0] === "config_class"} + enableGrouping + disablePagination + defaultSortBy="favorite" /> ); } diff --git a/src/components/Configs/ConfigsTypeIcon.tsx b/src/components/Configs/ConfigsTypeIcon.tsx index ea915f588..f18785797 100644 --- a/src/components/Configs/ConfigsTypeIcon.tsx +++ b/src/components/Configs/ConfigsTypeIcon.tsx @@ -13,7 +13,7 @@ export type ConfigIconProps = { export default function ConfigsTypeIcon({ config, - className = "w-4 h-4", + className = "w-4", showPrimaryIcon = true, showSecondaryIcon = true, showLabel = false, diff --git a/src/ui/DataTable/Hooks/useReactTableSortState.tsx b/src/ui/DataTable/Hooks/useReactTableSortState.tsx index 12100ac45..99b6ca205 100644 --- a/src/ui/DataTable/Hooks/useReactTableSortState.tsx +++ b/src/ui/DataTable/Hooks/useReactTableSortState.tsx @@ -11,7 +11,8 @@ import { useSearchParams } from "react-router-dom"; */ export default function useReactTableSortState( sortByKey = "sortBy", - sortOrderKey = "sortOrder" + sortOrderKey = "sortOrder", + defaultSortBy?: string ): [SortingState, (newSortBy: Updater) => void] { const [searchParams, setSearchParams] = useSearchParams(); @@ -20,6 +21,15 @@ export default function useReactTableSortState( const tableSortByState = useMemo(() => { if (!sortBy || !sortOrder) { + if (defaultSortBy) { + return [ + { + id: defaultSortBy, + desc: false + } + ] as SortingState; + } + return []; } return [ @@ -28,7 +38,7 @@ export default function useReactTableSortState( desc: sortOrder === "desc" } ] satisfies SortingState; - }, [sortBy, sortOrder]); + }, [defaultSortBy, sortBy, sortOrder]); const updateSortByFn = useCallback( (newSortBy: Updater) => { diff --git a/src/ui/MRTDataTable/MRTDataTable.tsx b/src/ui/MRTDataTable/MRTDataTable.tsx index 221afae78..f4486fbd0 100644 --- a/src/ui/MRTDataTable/MRTDataTable.tsx +++ b/src/ui/MRTDataTable/MRTDataTable.tsx @@ -37,6 +37,8 @@ type MRTDataTableProps = {}> = { enableGrouping?: boolean; onGroupingChange?: OnChangeFn; disableHiding?: boolean; + manualGrouping?: boolean; + defaultSortBy?: string; }; export default function MRTDataTable = {}>({ @@ -55,10 +57,16 @@ export default function MRTDataTable = {}>({ groupBy = [], expandAllRows = false, onGroupingChange = () => {}, - disableHiding = false + disableHiding = false, + manualGrouping = false, + defaultSortBy }: MRTDataTableProps) { const { pageIndex, pageSize, setPageIndex } = useReactTablePaginationState(); - const [sortState, setSortState] = useReactTableSortState(); + const [sortState, setSortState] = useReactTableSortState( + undefined, + undefined, + defaultSortBy + ); const table = useMantineReactTable({ data: data, @@ -80,6 +88,7 @@ export default function MRTDataTable = {}>({ enableSorting: true, enableColumnOrdering: false, enableColumnDragging: false, + manualGrouping, manualSorting: enableServerSideSorting, manualPagination: enableServerSidePagination, pageCount: manualPageCount, @@ -129,16 +138,17 @@ export default function MRTDataTable = {}>({ }, {}) }, initialState: { - expanded: expandAllRows ? true : undefined + expanded: expandAllRows ? true : undefined, + sorting: sortState }, mantinePaginationProps: { rowsPerPageOptions: ["50", "100", "200"] }, mantineExpandButtonProps: { - size: "xs" + size: 20 }, mantineExpandAllButtonProps: { - size: "xs" + size: 20 }, renderDetailPanel });