diff --git a/packages/translation/src/lang/en.json b/packages/translation/src/lang/en.json index bd966e5fd..f4cb0479a 100644 --- a/packages/translation/src/lang/en.json +++ b/packages/translation/src/lang/en.json @@ -2440,6 +2440,9 @@ "internalServerError": "Failed to fetch containers stats", "layoutSaveTitle": "Table layout not saved", "layoutSaveMessage": "The Docker table layout could not be saved. Try moving or resizing the column again." + }, + "empty": { + "noContainers": "No containers found" } }, "coolify": { diff --git a/packages/widgets/src/beszel-system-table/component.tsx b/packages/widgets/src/beszel-system-table/component.tsx index d11ced75c..32b1fd5a3 100644 --- a/packages/widgets/src/beszel-system-table/component.tsx +++ b/packages/widgets/src/beszel-system-table/component.tsx @@ -20,6 +20,9 @@ import { } from "lucide-react"; import { clientApi } from "@homarr/api/client"; +import { useSession } from "@homarr/auth/client"; +import { constructBoardPermissions } from "@homarr/auth/shared"; +import { useOptionalBoard } from "@homarr/boards/context"; import { useModalAction } from "@homarr/modals"; import { showErrorNotification } from "@homarr/notifications"; import { useScopedI18n } from "@homarr/translation/client"; @@ -131,6 +134,9 @@ export default function BeszelSystemTableWidget({ }: WidgetComponentProps<"beszelSystemTable">) { const t = useScopedI18n("widget.beszelSystemTable"); const { openModal } = useModalAction(BeszelSystemStatsModal); + const board = useOptionalBoard(); + const { data: session } = useSession(); + const hasChangeAccess = board ? constructBoardPermissions(board, session).hasChangeAccess : false; const { data: results = [], error: systemsError, @@ -148,9 +154,9 @@ export default function BeszelSystemTableWidget({ const persistLayout = useCallback( (newOptions: Partial>) => { setOptions({ newOptions }); - if (boardId && itemId) saveItemOptions({ boardId, itemId, newOptions }); + if (hasChangeAccess && boardId && itemId) saveItemOptions({ boardId, itemId, newOptions }); }, - [boardId, itemId, saveItemOptions, setOptions], + [boardId, hasChangeAccess, itemId, saveItemOptions, setOptions], ); const savedOrder = useMemo(() => parseColumnOrder(options.columnOrder), [options.columnOrder]); diff --git a/packages/widgets/src/docker/component.tsx b/packages/widgets/src/docker/component.tsx index b54332b9d..2a4a31027 100644 --- a/packages/widgets/src/docker/component.tsx +++ b/packages/widgets/src/docker/component.tsx @@ -21,6 +21,9 @@ import { DataTable, useDataTableColumns } from "mantine-datatable"; import type { RouterOutputs } from "@homarr/api"; import { clientApi } from "@homarr/api/client"; +import { useSession } from "@homarr/auth/client"; +import { constructBoardPermissions } from "@homarr/auth/shared"; +import { useOptionalBoard } from "@homarr/boards/context"; import { formatBytes, useTimeAgo } from "@homarr/common"; import type { ContainerState } from "@homarr/docker"; import { containerStateColorMap, cpuUsageColor, memoryUsageColor, safeValue } from "@homarr/docker/shared"; @@ -228,6 +231,9 @@ export default function DockerWidget({ const tWidget = useScopedI18n("widget.dockerContainers"); const router = useRouter(); const { openModal } = useModalAction(AddDockerAppToHomarr); + const board = useOptionalBoard(); + const { data: session } = useSession(); + const hasChangeAccess = board ? constructBoardPermissions(board, session).hasChangeAccess : false; const isTiny = width <= 256; const { data, refetch, isFetching } = clientApi.docker.getContainers.useQuery(); @@ -275,9 +281,9 @@ export default function DockerWidget({ const persistLayout = useCallback( (newOptions: Partial>) => { setOptions({ newOptions }); - if (boardId && itemId) saveItemOptions({ boardId, itemId, newOptions }); + if (hasChangeAccess && boardId && itemId) saveItemOptions({ boardId, itemId, newOptions }); }, - [boardId, itemId, saveItemOptions, setOptions], + [boardId, hasChangeAccess, itemId, saveItemOptions, setOptions], ); const savedOrder = useMemo(() => parseColumnOrder(options.columnOrder), [options.columnOrder]); @@ -424,6 +430,7 @@ export default function DockerWidget({ loaderBackgroundBlur={2} fz={width < 400 ? "xs" : "sm"} records={sortedContainers} + noRecordsText={tWidget("empty.noContainers")} columns={effectiveColumns} storeColumnsKey={storeKey} textSelectionDisabled @@ -603,7 +610,14 @@ function ContainerContextMenu({ onClose(); }} > - +