Skip to content

Commit

Permalink
Rework project resources table (#5782)
Browse files Browse the repository at this point in the history
* redo project resources table ui with tanstack

* remove unused

* optional text

* feedback

* truncate header too
  • Loading branch information
lovincyrus authored Sep 26, 2024
1 parent a2d07f6 commit decff29
Show file tree
Hide file tree
Showing 15 changed files with 1,684 additions and 1,332 deletions.
2,423 changes: 1,484 additions & 939 deletions package-lock.json

Large diffs are not rendered by default.

282 changes: 194 additions & 88 deletions web-admin/src/features/projects/status/ProjectResourcesTable.svelte
Original file line number Diff line number Diff line change
@@ -1,116 +1,222 @@
<script lang="ts">
import * as Table from "@rilldata/web-common/components/table-shadcn";
import Tag from "@rilldata/web-common/components/tag/Tag.svelte";
import { prettyResourceKind } from "@rilldata/web-common/features/entity-management/resource-selectors";
import type { V1Resource } from "@rilldata/web-common/runtime-client";
import {
Render,
Subscribe,
createRender,
createTable,
} from "svelte-headless-table";
import { readable } from "svelte/store";
import { writable } from "svelte/store";
import ResourceErrorMessage from "./ResourceErrorMessage.svelte";
import {
getResourceKindTagColor,
prettyReconcileStatus,
} from "./display-utils";
import ArrowDown from "@rilldata/web-common/components/icons/ArrowDown.svelte";
import {
createSvelteTable,
flexRender,
getCoreRowModel,
getSortedRowModel,
} from "@tanstack/svelte-table";
import type {
ColumnDef,
OnChangeFn,
SortingState,
TableOptions,
} from "@tanstack/svelte-table";
export let resources: V1Resource[];
const table = createTable(readable(resources));
let sorting: SortingState = [];
function formatDate(value: string) {
return new Date(value).toLocaleDateString(undefined, {
year: "numeric",
month: "short",
day: "numeric",
hour: "numeric",
minute: "numeric",
});
}
const columns = table.createColumns([
table.column({
accessor: (resource) => resource.meta.name.kind,
const setSorting: OnChangeFn<SortingState> = (updater) => {
if (updater instanceof Function) {
sorting = updater(sorting);
} else {
sorting = updater;
}
options.update((old) => ({
...old,
state: {
...old.state,
sorting,
},
}));
};
const columns: ColumnDef<V1Resource, any>[] = [
{
accessorKey: "title",
header: "Type",
cell: ({ value }) => {
const prettyKind = prettyResourceKind(value);
const color = getResourceKindTagColor(value);
return createRender(Tag, {
enableSorting: false,
cell: ({ row }) => {
const prettyKind = prettyResourceKind(row.original.meta.name.kind);
const color = getResourceKindTagColor(row.original.meta.name.kind);
return flexRender(Tag, {
color,
}).slot(prettyKind);
text: prettyKind,
});
},
}),
table.column({
accessor: (resource) => resource.meta.name.name,
},
{
accessorFn: (row) => row.meta.name.name,
header: "Name",
}),
table.column({
accessor: (resource) => resource.meta.reconcileStatus,
},
{
accessorFn: (row) => row.meta.reconcileStatus,
header: "Execution status",
cell: ({ value }) => prettyReconcileStatus(value),
}),
table.column({
accessor: (resource) => resource.meta.reconcileError,
id: "error",
cell: ({ row }) =>
prettyReconcileStatus(row.original.meta.reconcileStatus),
},
{
accessorFn: (row) => row.meta.reconcileError,
header: "Error",
cell: ({ value }) =>
createRender(ResourceErrorMessage, { message: value }),
}),
table.column({
accessor: (resource) => resource.meta.stateUpdatedOn,
header: "Last refresh",
cell: ({ value }) =>
new Date(value).toLocaleString(undefined, {
month: "short",
day: "numeric",
hour: "numeric",
minute: "numeric",
cell: ({ row }) =>
flexRender(ResourceErrorMessage, {
message: row.original.meta.reconcileError,
}),
}),
table.column({
accessor: (resource) => resource.meta.reconcileOn,
},
{
accessorFn: (row) => row.meta.stateUpdatedOn,
header: "Last refresh",
cell: (info) => {
if (!info.getValue()) return "-";
const date = formatDate(info.getValue() as string);
return date;
},
},
{
accessorFn: (row) => row.meta.reconcileOn,
header: "Next refresh",
cell: ({ value }) => {
if (!value) {
return "-";
}
return new Date(value).toLocaleString(undefined, {
month: "short",
day: "numeric",
hour: "numeric",
minute: "numeric",
});
cell: (info) => {
if (!info.getValue()) return "-";
const date = formatDate(info.getValue() as string);
return date;
},
}),
]);
},
];
const { headerRows, pageRows, tableAttrs, tableBodyAttrs } =
table.createViewModel(columns);
const options = writable<TableOptions<V1Resource>>({
data: resources,
columns: columns,
state: {
sorting,
},
onSortingChange: setSorting,
getCoreRowModel: getCoreRowModel(),
getSortedRowModel: getSortedRowModel(),
});
const table = createSvelteTable(options);
</script>

<div class="border rounded-md">
<Table.Root {...$tableAttrs}>
<Table.Header>
{#each $headerRows as headerRow (headerRow.id)}
<Subscribe rowAttrs={headerRow.attrs()}>
<Table.Row>
{#each headerRow.cells as cell (cell.id)}
<Subscribe attrs={cell.attrs()} let:attrs props={cell.props()}>
<Table.Head {...attrs}>
<Render of={cell.render()} />
</Table.Head>
</Subscribe>
{/each}
</Table.Row>
</Subscribe>
<div class="overflow-x-auto">
<table class="w-full">
<thead>
{#each $table.getHeaderGroups() as headerGroup}
<tr>
{#each headerGroup.headers as header}
<th
colSpan={header.colSpan}
on:click={header.column.getToggleSortingHandler()}
>
{#if !header.isPlaceholder}
<div
class:cursor-pointer={header.column.getCanSort()}
class:select-none={header.column.getCanSort()}
class="font-semibold text-gray-500 flex flex-row items-center gap-x-1 truncate"
>
<svelte:component
this={flexRender(
header.column.columnDef.header,
header.getContext(),
)}
/>
{#if header.column.getIsSorted().toString() === "asc"}
<span>
<ArrowDown flip size="12px" />
</span>
{:else if header.column.getIsSorted().toString() === "desc"}
<span>
<ArrowDown size="12px" />
</span>
{/if}
</div>
{/if}
</th>
{/each}
</tr>
{/each}
</Table.Header>
<Table.Body {...$tableBodyAttrs}>
{#each $pageRows as row (row.id)}
<Subscribe rowAttrs={row.attrs()} let:rowAttrs>
<Table.Row {...rowAttrs}>
{#each row.cells as cell (cell.id)}
<Subscribe attrs={cell.attrs()} let:attrs>
<Table.Cell {...attrs}>
<Render of={cell.render()} />
</Table.Cell>
</Subscribe>
{/each}
</Table.Row>
</Subscribe>
</thead>
<tbody>
{#each $table.getRowModel().rows as row}
<tr>
{#each row.getVisibleCells() as cell}
<td
class={`px-4 py-2 truncate ${cell.column.id === "actions" ? "w-1" : ""}`}
data-label={cell.column.columnDef.header}
>
<svelte:component
this={flexRender(cell.column.columnDef.cell, cell.getContext())}
/>
</td>
{/each}
</tr>
{/each}
</Table.Body>
</Table.Root>
</tbody>
</table>
</div>

<style lang="postcss">
table {
@apply border-separate border-spacing-0;
}
table th,
table td {
@apply border-b border-gray-200;
}
thead tr th {
@apply border-t border-gray-200;
@apply px-4 py-2 text-left;
}
thead tr th:first-child {
@apply border-l rounded-tl-sm;
}
thead tr th:last-child {
@apply border-r rounded-tr-sm;
}
thead tr:last-child th {
@apply border-b;
}
tbody tr {
@apply border-t border-gray-200;
}
tbody tr:first-child {
@apply border-t-0;
}
tbody td {
@apply border-b border-gray-200;
}
tbody td:first-child {
@apply border-l;
}
tbody td:last-child {
@apply border-r;
}
tbody tr:last-child td:first-child {
@apply rounded-bl-sm;
}
tbody tr:last-child td:last-child {
@apply rounded-br-sm;
}
</style>
1 change: 0 additions & 1 deletion web-common/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,6 @@
"storybook": "^7.0.18",
"svelte": "^4.0.0",
"svelte-forms-lib": "^2.0.1",
"svelte-headless-table": "^0.18.1",
"svelte-preprocess": "^5.0.4",
"svelte-radix": "^1.1.0",
"svelte-vega": "^2.2.0",
Expand Down
18 changes: 0 additions & 18 deletions web-common/src/components/table-shadcn/Table.svelte

This file was deleted.

13 changes: 0 additions & 13 deletions web-common/src/components/table-shadcn/TableBody.svelte

This file was deleted.

16 changes: 0 additions & 16 deletions web-common/src/components/table-shadcn/TableCaption.svelte

This file was deleted.

21 changes: 0 additions & 21 deletions web-common/src/components/table-shadcn/TableCell.svelte

This file was deleted.

Loading

1 comment on commit decff29

@github-actions
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.