feat(docker): add widget options to sort containers (#4636)
This commit is contained in:
@@ -1939,7 +1939,23 @@
|
|||||||
"dockerContainers": {
|
"dockerContainers": {
|
||||||
"name": "Docker stats",
|
"name": "Docker stats",
|
||||||
"description": "Stats of your containers (This widget can only be added with administrator privileges)",
|
"description": "Stats of your containers (This widget can only be added with administrator privileges)",
|
||||||
"option": {},
|
"option": {
|
||||||
|
"enableRowSorting": {
|
||||||
|
"label": "Enable items sorting"
|
||||||
|
},
|
||||||
|
"defaultSort": {
|
||||||
|
"label": "Column used for sorting by default",
|
||||||
|
"option": {
|
||||||
|
"name": "Name",
|
||||||
|
"state": "State",
|
||||||
|
"cpuUsage": "CPU usage",
|
||||||
|
"memoryUsage": "Memory usage"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"descendingDefaultSort": {
|
||||||
|
"label": "Invert sorting"
|
||||||
|
}
|
||||||
|
},
|
||||||
"error": {
|
"error": {
|
||||||
"internalServerError": "Failed to fetch containers stats"
|
"internalServerError": "Failed to fetch containers stats"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ const createColumns = (
|
|||||||
t: ReturnType<typeof useScopedI18n<"docker">>,
|
t: ReturnType<typeof useScopedI18n<"docker">>,
|
||||||
): MRT_ColumnDef<RouterOutputs["docker"]["getContainers"]["containers"][number]>[] => [
|
): MRT_ColumnDef<RouterOutputs["docker"]["getContainers"]["containers"][number]>[] => [
|
||||||
{
|
{
|
||||||
|
id: "name",
|
||||||
accessorKey: "name",
|
accessorKey: "name",
|
||||||
header: t("field.name.label"),
|
header: t("field.name.label"),
|
||||||
Cell({ renderedCellValue, row }) {
|
Cell({ renderedCellValue, row }) {
|
||||||
@@ -70,6 +71,7 @@ const createColumns = (
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
id: "state",
|
||||||
accessorKey: "state",
|
accessorKey: "state",
|
||||||
size: 100,
|
size: 100,
|
||||||
header: t("field.state.label"),
|
header: t("field.state.label"),
|
||||||
@@ -78,6 +80,13 @@ const createColumns = (
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
id: "cpuUsage",
|
||||||
|
sortingFn: (rowA, rowB) => {
|
||||||
|
const cpuUsageA = safeValue(rowA.original.cpuUsage);
|
||||||
|
const cpuUsageB = safeValue(rowB.original.cpuUsage);
|
||||||
|
|
||||||
|
return cpuUsageA - cpuUsageB;
|
||||||
|
},
|
||||||
accessorKey: "cpuUsage",
|
accessorKey: "cpuUsage",
|
||||||
size: 80,
|
size: 80,
|
||||||
header: t("field.stats.cpu.label"),
|
header: t("field.stats.cpu.label"),
|
||||||
@@ -92,6 +101,13 @@ const createColumns = (
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
id: "memoryUsage",
|
||||||
|
sortingFn: (rowA, rowB) => {
|
||||||
|
const memoryUsageA = safeValue(rowA.original.memoryUsage);
|
||||||
|
const memoryUsageB = safeValue(rowB.original.memoryUsage);
|
||||||
|
|
||||||
|
return memoryUsageA - memoryUsageB;
|
||||||
|
},
|
||||||
accessorKey: "memoryUsage",
|
accessorKey: "memoryUsage",
|
||||||
size: 80,
|
size: 80,
|
||||||
header: t("field.stats.memory.label"),
|
header: t("field.stats.memory.label"),
|
||||||
@@ -106,9 +122,11 @@ const createColumns = (
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
id: "actions",
|
||||||
accessorKey: "actions",
|
accessorKey: "actions",
|
||||||
size: 80,
|
size: 80,
|
||||||
header: t("action.title"),
|
header: t("action.title"),
|
||||||
|
enableSorting: false,
|
||||||
Cell({ row }) {
|
Cell({ row }) {
|
||||||
const utils = clientApi.useUtils();
|
const utils = clientApi.useUtils();
|
||||||
// eslint-disable-next-line no-restricted-syntax
|
// eslint-disable-next-line no-restricted-syntax
|
||||||
@@ -168,7 +186,7 @@ const createColumns = (
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
export default function DockerWidget({ width }: WidgetComponentProps<"dockerContainers">) {
|
export default function DockerWidget({ options, width, isEditMode }: WidgetComponentProps<"dockerContainers">) {
|
||||||
const t = useScopedI18n("docker");
|
const t = useScopedI18n("docker");
|
||||||
const isTiny = width <= 256;
|
const isTiny = width <= 256;
|
||||||
|
|
||||||
@@ -192,8 +210,8 @@ export default function DockerWidget({ width }: WidgetComponentProps<"dockerCont
|
|||||||
enablePagination: false,
|
enablePagination: false,
|
||||||
enableTopToolbar: false,
|
enableTopToolbar: false,
|
||||||
enableBottomToolbar: false,
|
enableBottomToolbar: false,
|
||||||
enableSorting: false,
|
|
||||||
enableColumnActions: false,
|
enableColumnActions: false,
|
||||||
|
enableSorting: options.enableRowSorting && !isEditMode,
|
||||||
enableStickyHeader: false,
|
enableStickyHeader: false,
|
||||||
enableColumnOrdering: false,
|
enableColumnOrdering: false,
|
||||||
enableRowSelection: false,
|
enableRowSelection: false,
|
||||||
@@ -203,6 +221,7 @@ export default function DockerWidget({ width }: WidgetComponentProps<"dockerCont
|
|||||||
enableFilters: false,
|
enableFilters: false,
|
||||||
enableHiding: false,
|
enableHiding: false,
|
||||||
initialState: {
|
initialState: {
|
||||||
|
sorting: [{ id: options.defaultSort, desc: options.descendingDefaultSort }],
|
||||||
density: "xs",
|
density: "xs",
|
||||||
},
|
},
|
||||||
mantinePaperProps: {
|
mantinePaperProps: {
|
||||||
|
|||||||
@@ -1,12 +1,35 @@
|
|||||||
import { IconBrandDocker, IconServerOff } from "@tabler/icons-react";
|
import { IconBrandDocker, IconServerOff } from "@tabler/icons-react";
|
||||||
|
|
||||||
|
import type { RouterOutputs } from "@homarr/api";
|
||||||
|
|
||||||
import { createWidgetDefinition } from "../definition";
|
import { createWidgetDefinition } from "../definition";
|
||||||
import { optionsBuilder } from "../options";
|
import { optionsBuilder } from "../options";
|
||||||
|
|
||||||
|
const columnsList = [
|
||||||
|
"name",
|
||||||
|
"state",
|
||||||
|
"cpuUsage",
|
||||||
|
"memoryUsage",
|
||||||
|
] as const satisfies (keyof RouterOutputs["docker"]["getContainers"]["containers"][number])[];
|
||||||
|
|
||||||
export const { definition, componentLoader } = createWidgetDefinition("dockerContainers", {
|
export const { definition, componentLoader } = createWidgetDefinition("dockerContainers", {
|
||||||
icon: IconBrandDocker,
|
icon: IconBrandDocker,
|
||||||
createOptions() {
|
createOptions() {
|
||||||
return optionsBuilder.from(() => ({}));
|
return optionsBuilder.from((factory) => ({
|
||||||
|
enableRowSorting: factory.switch({
|
||||||
|
defaultValue: false,
|
||||||
|
}),
|
||||||
|
defaultSort: factory.select({
|
||||||
|
defaultValue: "name",
|
||||||
|
options: columnsList.map((value) => ({
|
||||||
|
value,
|
||||||
|
label: (t) => t(`widget.dockerContainers.option.defaultSort.option.${value}`),
|
||||||
|
})),
|
||||||
|
}),
|
||||||
|
descendingDefaultSort: factory.switch({
|
||||||
|
defaultValue: false,
|
||||||
|
}),
|
||||||
|
}));
|
||||||
},
|
},
|
||||||
errors: {
|
errors: {
|
||||||
INTERNAL_SERVER_ERROR: {
|
INTERNAL_SERVER_ERROR: {
|
||||||
|
|||||||
Reference in New Issue
Block a user