feat(v2 docker widget): Fixes column-resize squashing (#6646)
* fix(dataTable): resizing a column no longer squashes the others mantine-datatable's built-in column resize keeps the table's total width fixed by shrinking every other column to compensate, which collapses columns toward zero in a narrow widget (open upstream issue, no fix: icflorescu/mantine-datatable#discussions-757). Replaced it with our own resize handle that only ever changes the width of the column being dragged - the table grows and scrolls horizontally instead. Shared via usePersistedTableLayout, so docker, downloads, and beszel-system-table all get it. * feat(docker): enable hold-Shift advanced focus preview The widget already renders differently for displayMode="advanced", but was missing supportsAdvancedFocus: true, so the board never offered the hold-Shift preview for it - matching downloads and media-server, which both set this flag. * style(docker): tighten row density, decouple icon size from row height Circular avatar, denser row/footer padding, and action icons rendered larger than their button via absolute positioning so they don't inflate row height (the button stays small and fixed - it repeats once per row, so any growth there multiplies across every visible container). * fix(data-table): harden shared column resizing * fix(data-table): account for board scaling * fix(data-table): compact shared headers * fix(data-table): fit columns to widget * fix(downloads): simplify advanced details * test(widgets): align Docker advanced focus * fix(downloads): widen expanded details --------- Co-authored-by: ajnart <thomas@ajnart.dev>
This commit is contained in:
1 parent
9b406d5d83
commit
002381d294
13 files changed
+270
-62
No files matched your search
@@ -4836,70 +4836,70 @@
|
||||
},
|
||||
"items": {
|
||||
"actions": {
|
||||
"columnTitle": "Controls"
|
||||
"columnTitle": "Actions"
|
||||
},
|
||||
"added": {
|
||||
"columnTitle": "Added",
|
||||
"detailsTitle": "Date Added"
|
||||
"detailsTitle": "Added"
|
||||
},
|
||||
"category": {
|
||||
"columnTitle": "Extras",
|
||||
"detailsTitle": "Categories (Or extra information)"
|
||||
"columnTitle": "Category",
|
||||
"detailsTitle": "Category"
|
||||
},
|
||||
"downSpeed": {
|
||||
"columnTitle": "Down",
|
||||
"detailsTitle": "Download Speed"
|
||||
"detailsTitle": "Down"
|
||||
},
|
||||
"index": {
|
||||
"columnTitle": "#",
|
||||
"detailsTitle": "Current index within client"
|
||||
"detailsTitle": "Index"
|
||||
},
|
||||
"id": {
|
||||
"columnTitle": "Id",
|
||||
"detailsTitle": "Item ID"
|
||||
"columnTitle": "ID",
|
||||
"detailsTitle": "ID"
|
||||
},
|
||||
"integration": {
|
||||
"columnTitle": "Integration"
|
||||
"columnTitle": "Source"
|
||||
},
|
||||
"name": {
|
||||
"columnTitle": "Job name"
|
||||
"columnTitle": "Name"
|
||||
},
|
||||
"progress": {
|
||||
"columnTitle": "Progress",
|
||||
"detailsTitle": "Download Progress"
|
||||
"detailsTitle": "Progress"
|
||||
},
|
||||
"ratio": {
|
||||
"columnTitle": "Ratio",
|
||||
"detailsTitle": "Torrent ratio (received/sent)"
|
||||
"detailsTitle": "Ratio"
|
||||
},
|
||||
"received": {
|
||||
"columnTitle": "Total down",
|
||||
"detailsTitle": "Total downloaded"
|
||||
"columnTitle": "Down",
|
||||
"detailsTitle": "Downloaded"
|
||||
},
|
||||
"sent": {
|
||||
"columnTitle": "Total up",
|
||||
"detailsTitle": "Total Uploaded"
|
||||
"columnTitle": "Up",
|
||||
"detailsTitle": "Uploaded"
|
||||
},
|
||||
"size": {
|
||||
"columnTitle": "File Size",
|
||||
"detailsTitle": "Total Size of selection/files"
|
||||
"columnTitle": "Size",
|
||||
"detailsTitle": "Size"
|
||||
},
|
||||
"state": {
|
||||
"columnTitle": "State",
|
||||
"detailsTitle": "Job State"
|
||||
"detailsTitle": "State"
|
||||
},
|
||||
"time": {
|
||||
"columnTitle": "Finish time",
|
||||
"detailsTitle": "Time since/to completion",
|
||||
"columnTitle": "ETA",
|
||||
"detailsTitle": "ETA",
|
||||
"eta": "ETA"
|
||||
},
|
||||
"type": {
|
||||
"columnTitle": "Type",
|
||||
"detailsTitle": "Download Client type"
|
||||
"detailsTitle": "Type"
|
||||
},
|
||||
"upSpeed": {
|
||||
"columnTitle": "Up",
|
||||
"detailsTitle": "Upload Speed"
|
||||
"detailsTitle": "Up"
|
||||
}
|
||||
},
|
||||
"states": {
|
||||
|
||||
@@ -12,11 +12,18 @@
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.homarr-data-table .mantine-datatable-table {
|
||||
width: 100% !important;
|
||||
max-width: 100%;
|
||||
table-layout: fixed !important;
|
||||
}
|
||||
|
||||
.homarr-data-table .mantine-datatable-table tbody tr:hover {
|
||||
background-color: color-mix(in srgb, var(--mantine-color-default-hover) 40%, transparent) !important;
|
||||
}
|
||||
|
||||
.homarr-data-table th {
|
||||
padding: 0;
|
||||
white-space: nowrap;
|
||||
background-color: color-mix(in srgb, var(--mantine-color-body) 60%, transparent) !important;
|
||||
backdrop-filter: blur(8px);
|
||||
@@ -28,6 +35,13 @@
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
/* Lets a cell's content (e.g. an oversized action icon) visually overflow its own box without
|
||||
growing it - used to make a per-row icon look bigger without inflating row height, since the
|
||||
icon is pulled out of flow via absolute positioning rather than actually being a bigger cell. */
|
||||
.homarr-data-table td.docker-actions-cell {
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.homarr-data-table td .mantine-Text-root,
|
||||
.homarr-data-table td .mantine-Group-root {
|
||||
white-space: nowrap;
|
||||
@@ -40,6 +54,25 @@
|
||||
transition: opacity 150ms ease-out;
|
||||
}
|
||||
|
||||
.homarr-data-table .mantine-datatable-header-cell-sortable-group {
|
||||
gap: 0;
|
||||
}
|
||||
|
||||
.homarr-data-table .mantine-datatable-header-cell-draggable-action-icon {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.homarr-data-table .mantine-datatable-header-cell-sortable-unsorted-icon {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.homarr-data-table .mantine-datatable-header-cell-draggable-action-icon svg,
|
||||
.homarr-data-table .mantine-datatable-header-cell-sortable-text svg,
|
||||
.homarr-data-table .mantine-datatable-header-cell-sortable-icon svg {
|
||||
width: var(--mantine-font-size-md);
|
||||
height: var(--mantine-font-size-md);
|
||||
}
|
||||
|
||||
.homarr-data-table th:hover .mantine-datatable-header-cell-sortable-icon,
|
||||
.homarr-data-table th:hover .mantine-datatable-header-cell-draggable-action-icon,
|
||||
.homarr-data-table .mantine-datatable-header-cell-draggable-action-icon:focus-visible,
|
||||
|
||||
@@ -2,10 +2,24 @@
|
||||
|
||||
import "./homarr-data-table.css";
|
||||
|
||||
import type { DataTableProps } from "mantine-datatable";
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
||||
import type { DataTableColumn, DataTableProps } from "mantine-datatable";
|
||||
import { DataTable } from "mantine-datatable";
|
||||
|
||||
const fallbackColumnWidth = 60;
|
||||
|
||||
const getColumnWidth = (width: string | number | undefined): number => {
|
||||
if (typeof width === "number" && Number.isFinite(width) && width > 0) return width;
|
||||
if (typeof width === "string") {
|
||||
const parsedWidth = Number.parseFloat(width);
|
||||
if (Number.isFinite(parsedWidth) && parsedWidth > 0) return parsedWidth;
|
||||
}
|
||||
return fallbackColumnWidth;
|
||||
};
|
||||
|
||||
type HomarrDataTableProps<T> = DataTableProps<T> & {
|
||||
columns: DataTableColumn<T>[];
|
||||
groups?: never;
|
||||
isEditMode: boolean;
|
||||
cellPadding: string;
|
||||
rowCursor?: "auto" | "default";
|
||||
@@ -16,11 +30,78 @@ export function HomarrDataTable<T>({
|
||||
cellPadding,
|
||||
rowCursor = "auto",
|
||||
className,
|
||||
columns,
|
||||
defaultColumnProps,
|
||||
onMouseDownCapture,
|
||||
scrollAreaProps,
|
||||
style,
|
||||
...props
|
||||
}: HomarrDataTableProps<T>) {
|
||||
const [resizePreviewWidths, setResizePreviewWidths] = useState<Record<string, number>>();
|
||||
const removeResizeListeners = useRef<() => void>(() => undefined);
|
||||
useEffect(() => () => removeResizeListeners.current(), []);
|
||||
|
||||
const handleMouseDownCapture = useCallback(
|
||||
(event: React.MouseEvent<HTMLTableElement>) => {
|
||||
onMouseDownCapture?.(event);
|
||||
const target = event.target;
|
||||
if (!(target instanceof Element)) return;
|
||||
|
||||
const handle = target.closest(".mantine-datatable-header-resizable-handle");
|
||||
const currentCell = handle?.closest<HTMLTableCellElement>("th[data-accessor]");
|
||||
const headerRow = currentCell?.parentElement;
|
||||
if (!currentCell || !headerRow) return;
|
||||
|
||||
const cells = Array.from(headerRow.querySelectorAll<HTMLTableCellElement>("th[data-accessor]"));
|
||||
const currentIndex = cells.indexOf(currentCell);
|
||||
const nextCell = cells[currentIndex + 1];
|
||||
const currentAccessor = currentCell.dataset.accessor;
|
||||
const nextAccessor = nextCell?.dataset.accessor;
|
||||
if (!nextCell || !currentAccessor || !nextAccessor) return;
|
||||
|
||||
const widths = Object.fromEntries(
|
||||
cells.flatMap((cell) => {
|
||||
const accessor = cell.dataset.accessor;
|
||||
if (!accessor) return [];
|
||||
return [[accessor, cell.getBoundingClientRect().width]];
|
||||
}),
|
||||
);
|
||||
const currentWidth = widths[currentAccessor];
|
||||
const nextWidth = widths[nextAccessor];
|
||||
if (currentWidth === undefined || nextWidth === undefined) return;
|
||||
|
||||
const visualScale = currentCell.getBoundingClientRect().width / currentCell.offsetWidth;
|
||||
const minimumWidth = fallbackColumnWidth * visualScale;
|
||||
const startX = event.clientX;
|
||||
|
||||
removeResizeListeners.current();
|
||||
const handleMouseMove = (moveEvent: MouseEvent) => {
|
||||
const delta = Math.min(
|
||||
nextWidth - minimumWidth,
|
||||
Math.max(minimumWidth - currentWidth, moveEvent.clientX - startX),
|
||||
);
|
||||
setResizePreviewWidths({
|
||||
...widths,
|
||||
[currentAccessor]: currentWidth + delta,
|
||||
[nextAccessor]: nextWidth - delta,
|
||||
});
|
||||
};
|
||||
const handleResizeEnd = () => {
|
||||
removeResizeListeners.current();
|
||||
requestAnimationFrame(() => requestAnimationFrame(() => setResizePreviewWidths(undefined)));
|
||||
};
|
||||
removeResizeListeners.current = () => {
|
||||
window.removeEventListener("mousemove", handleMouseMove);
|
||||
window.removeEventListener("mouseup", handleResizeEnd);
|
||||
window.removeEventListener("blur", handleResizeEnd);
|
||||
};
|
||||
window.addEventListener("mousemove", handleMouseMove);
|
||||
window.addEventListener("mouseup", handleResizeEnd);
|
||||
window.addEventListener("blur", handleResizeEnd);
|
||||
},
|
||||
[onMouseDownCapture],
|
||||
);
|
||||
|
||||
const mergedClassName = [
|
||||
"homarr-data-table",
|
||||
rowCursor === "default" ? "homarr-data-table-row-cursor-default" : undefined,
|
||||
@@ -28,6 +109,26 @@ export function HomarrDataTable<T>({
|
||||
]
|
||||
.filter(Boolean)
|
||||
.join(" ");
|
||||
const fittedColumns = useMemo(() => {
|
||||
const visibleColumns = columns.filter(({ hidden }) => !hidden);
|
||||
const getRenderedWidth = (column: DataTableColumn<T>) =>
|
||||
resizePreviewWidths?.[String(column.accessor)] ?? getColumnWidth(column.width);
|
||||
const totalWidth = visibleColumns.reduce((total, column) => total + getRenderedWidth(column), 0);
|
||||
if (totalWidth <= 0) return columns;
|
||||
|
||||
return columns.map((column) => {
|
||||
if (column.hidden) return column;
|
||||
|
||||
const width = `${(getRenderedWidth(column) / totalWidth) * 100}%`;
|
||||
const fittedWidth = { width, minWidth: width, maxWidth: width };
|
||||
const cellsStyle = column.cellsStyle ?? defaultColumnProps?.cellsStyle;
|
||||
return {
|
||||
...column,
|
||||
titleStyle: [column.titleStyle, fittedWidth],
|
||||
cellsStyle: (record: T, index: number) => [cellsStyle?.(record, index), fittedWidth, { padding: cellPadding }],
|
||||
};
|
||||
});
|
||||
}, [cellPadding, columns, defaultColumnProps?.cellsStyle, resizePreviewWidths]);
|
||||
|
||||
return (
|
||||
<DataTable<T>
|
||||
@@ -42,6 +143,8 @@ export function HomarrDataTable<T>({
|
||||
textSelectionDisabled
|
||||
height="100%"
|
||||
{...props}
|
||||
columns={fittedColumns}
|
||||
onMouseDownCapture={handleMouseDownCapture}
|
||||
className={mergedClassName}
|
||||
style={[{ pointerEvents: isEditMode ? "none" : undefined }, style]}
|
||||
defaultColumnProps={{
|
||||
|
||||
@@ -107,7 +107,7 @@ export const parseColumnWidths = (value: string, columnAccessors: readonly strin
|
||||
}
|
||||
};
|
||||
|
||||
export const usePersistedTableLayout = <T>({
|
||||
export const usePersistedTableLayout = <T,>({
|
||||
columns,
|
||||
columnAccessors,
|
||||
columnOrder,
|
||||
|
||||
@@ -39,7 +39,6 @@ describe("supportsAdvancedFocus", () => {
|
||||
beszelSystemStatsDefinition,
|
||||
beszelSystemTableDefinition,
|
||||
customApiDefinition,
|
||||
dockerDefinition,
|
||||
indexerManagerDefinition,
|
||||
notebookDefinition,
|
||||
])("keeps non-enhanced widgets compact", (widgetDefinition) => {
|
||||
@@ -49,6 +48,7 @@ describe("supportsAdvancedFocus", () => {
|
||||
test("requires an explicit opt-in", () => {
|
||||
expect(supportsAdvancedFocus({})).toBe(false);
|
||||
expect(supportsAdvancedFocus(clockDefinition)).toBe(true);
|
||||
expect(supportsAdvancedFocus(dockerDefinition)).toBe(true);
|
||||
expect(supportsAdvancedFocus(downloadsDefinition)).toBe(true);
|
||||
});
|
||||
});
|
||||
@@ -69,6 +69,18 @@ interface ContainerActionHandlers {
|
||||
const columnAccessors = ["name", "state", "host", "cpuUsage", "memoryUsage", "actions"] as const;
|
||||
const containerMenuWidth = 240;
|
||||
|
||||
// The *button* sizes stay small and fixed - row height is set by the tallest cell, and the
|
||||
// actions button is repeated once per row, so any growth here multiplies across every row and
|
||||
// tanks how many containers fit on screen. The *icon* sizes are rendered larger than their
|
||||
// button via absolute positioning (see ContainerMenuButton/footer refresh below) - an
|
||||
// absolutely-positioned element is removed from normal flow, so it doesn't count toward its
|
||||
// ancestor's height even though it visually overflows the button. This lets the icon look
|
||||
// properly sized without the button (and therefore the row) growing to match.
|
||||
const rowActionButtonSize = 22;
|
||||
const rowActionIconVisualSize = 32;
|
||||
const footerRefreshButtonSize = 24;
|
||||
const footerRefreshIconVisualSize = 30;
|
||||
|
||||
const createContainerLogsPath = (container: Pick<DockerContainer, "endpointId" | "id" | "name">) =>
|
||||
`/manage/tools/docker/logs/${container.id}?name=${encodeURIComponent(container.name)}&endpointId=${encodeURIComponent(container.endpointId)}`;
|
||||
|
||||
@@ -83,7 +95,13 @@ const ContainerStateBadge = ({ state }: { state: ContainerState }) => {
|
||||
const t = useScopedI18n("docker.field.state.option");
|
||||
|
||||
return (
|
||||
<Badge size="xs" radius="sm" variant="light" color={containerStateColorMap[state]}>
|
||||
<Badge
|
||||
size="xs"
|
||||
radius="sm"
|
||||
variant="light"
|
||||
color={containerStateColorMap[state]}
|
||||
styles={{ label: { lineHeight: 1.2 } }}
|
||||
>
|
||||
{t(state)}
|
||||
</Badge>
|
||||
);
|
||||
@@ -126,16 +144,15 @@ const createColumns = (
|
||||
<Group gap="xs" wrap="nowrap" style={{ overflow: "hidden" }}>
|
||||
{inlineState && <ContainerStateDot state={container.state} />}
|
||||
<Avatar
|
||||
variant="outline"
|
||||
radius="sm"
|
||||
size={20}
|
||||
radius="xl"
|
||||
size={24}
|
||||
styles={{ image: { objectFit: "contain" } }}
|
||||
src={container.iconUrl}
|
||||
style={{ flexShrink: 0 }}
|
||||
>
|
||||
{container.name.at(0)?.toUpperCase()}
|
||||
</Avatar>
|
||||
<Text size="sm" truncate>
|
||||
<Text size="sm" lh={1.2} truncate>
|
||||
{container.name}
|
||||
</Text>
|
||||
</Group>
|
||||
@@ -191,8 +208,12 @@ const createColumns = (
|
||||
{
|
||||
accessor: "actions",
|
||||
title: "",
|
||||
width: 44,
|
||||
width: rowActionButtonSize + 18,
|
||||
textAlign: "right",
|
||||
// The default `.homarr-data-table td { overflow: hidden }` (needed for name/host ellipsis
|
||||
// truncation) would clip the actions icon's intentional visual overflow - opt this one
|
||||
// cell out of it.
|
||||
cellsClassName: "docker-actions-cell",
|
||||
render: (container) => <ContainerMenuButton container={container} handlers={handlers} />,
|
||||
},
|
||||
];
|
||||
@@ -407,7 +428,7 @@ export default function DockerWidget({
|
||||
<Box style={{ flex: 1, minHeight: 0 }}>
|
||||
<HomarrDataTable
|
||||
isEditMode={isEditMode}
|
||||
cellPadding={width < 400 ? "2px 8px" : "4px 8px"}
|
||||
cellPadding="2px 8px"
|
||||
rowCursor="default"
|
||||
fetching={isFetching && containers.length === 0}
|
||||
fz={width < 400 ? "xs" : "sm"}
|
||||
@@ -431,38 +452,43 @@ export default function DockerWidget({
|
||||
style={{
|
||||
borderTop: "0.0625rem solid var(--border-color)",
|
||||
}}
|
||||
p={4}
|
||||
py={2}
|
||||
px={8}
|
||||
wrap="nowrap"
|
||||
>
|
||||
<Group gap={4} wrap="nowrap">
|
||||
<IconBrandDocker size="var(--mantine-font-size-xl)" style={{ flexShrink: 0 }} />
|
||||
<Text size="sm" truncate>
|
||||
<IconBrandDocker size="var(--mantine-font-size-md)" style={{ flexShrink: 0 }} />
|
||||
<Text size="xs" truncate>
|
||||
{t("table.footer", { count: containers.length.toString() })}
|
||||
</Text>
|
||||
</Group>
|
||||
|
||||
<Group gap="sm" wrap="nowrap" justify="flex-end" style={{ minWidth: 0 }}>
|
||||
{footerVisibility.cpu && (
|
||||
<Text size="sm" style={{ whiteSpace: "nowrap" }}>
|
||||
<Text size="xs" style={{ whiteSpace: "nowrap" }}>
|
||||
{t("table.totalCpu", { cpu: totals.cpu.toFixed(2) })}
|
||||
</Text>
|
||||
)}
|
||||
{footerVisibility.memory && (
|
||||
<Text size="sm" style={{ whiteSpace: "nowrap" }}>
|
||||
<Text size="xs" style={{ whiteSpace: "nowrap" }}>
|
||||
{t("table.totalMemory", { memory: formatBytes(totals.memory) })}
|
||||
</Text>
|
||||
)}
|
||||
<Tooltip label={t("table.refresh.lastUpdated", { when: relativeTime })}>
|
||||
<ActionIcon
|
||||
className={actionTargetClasses.root}
|
||||
size="sm"
|
||||
size={footerRefreshButtonSize}
|
||||
variant="transparent"
|
||||
c="var(--mantine-color-text)"
|
||||
loading={isFetching || refreshInventory.isPending}
|
||||
onClick={() => refreshInventory.mutate()}
|
||||
aria-label={t("table.refresh.lastUpdated", { when: relativeTime })}
|
||||
style={{ position: "relative", overflow: "visible" }}
|
||||
>
|
||||
<IconRefresh size="var(--mantine-font-size-md)" />
|
||||
<IconRefresh
|
||||
size={footerRefreshIconVisualSize}
|
||||
style={{ position: "absolute", top: "50%", left: "50%", transform: "translate(-50%, -50%)" }}
|
||||
/>
|
||||
</ActionIcon>
|
||||
</Tooltip>
|
||||
</Group>
|
||||
@@ -492,11 +518,18 @@ function ContainerMenuButton({
|
||||
className={actionTargetClasses.root}
|
||||
variant="subtle"
|
||||
color="gray"
|
||||
size="sm"
|
||||
size={rowActionButtonSize}
|
||||
aria-label={t("title")}
|
||||
onClick={(event) => event.stopPropagation()}
|
||||
style={{ position: "relative", overflow: "visible" }}
|
||||
>
|
||||
<IconDots size="var(--mantine-font-size-md)" />
|
||||
{/* Rendered larger than the button and pulled out of flow via absolute positioning,
|
||||
so it looks properly sized without the button - and therefore the row - growing
|
||||
to match (row height is set by the tallest cell, and this button repeats per row). */}
|
||||
<IconDots
|
||||
size={rowActionIconVisualSize}
|
||||
style={{ position: "absolute", top: "50%", left: "50%", transform: "translate(-50%, -50%)" }}
|
||||
/>
|
||||
</ActionIcon>
|
||||
</Menu.Target>
|
||||
<Menu.Dropdown w={containerMenuWidth} miw={containerMenuWidth} maw={containerMenuWidth}>
|
||||
|
||||
@@ -26,6 +26,7 @@ const columnTranslationKeyMap = {
|
||||
|
||||
export const { definition, componentLoader } = createWidgetDefinition("dockerContainers", {
|
||||
icon: IconBrandDocker,
|
||||
supportsAdvancedFocus: true,
|
||||
queryKey: [["docker", "getContainers"]],
|
||||
refetchInterval: 30,
|
||||
createOptions() {
|
||||
|
||||
@@ -793,7 +793,9 @@ export default function DownloadClientsWidget({
|
||||
animateOpacity: true,
|
||||
transitionTimingFunction: "ease-out",
|
||||
},
|
||||
content: ({ record, collapse }) => <ExpandedRow item={record} collapse={collapse} />,
|
||||
content: ({ record, collapse }) => (
|
||||
<ExpandedRow item={record} collapse={collapse} />
|
||||
),
|
||||
}}
|
||||
onScroll={() => {
|
||||
if (contextMenu) closeContextMenu();
|
||||
@@ -869,7 +871,13 @@ function buildHoverTooltip(record: ExtendedDownloadClientItem, t: DownloadsT): R
|
||||
);
|
||||
}
|
||||
|
||||
function ExpandedRow({ item, collapse }: { item: ExtendedDownloadClientItem; collapse: () => void }) {
|
||||
function ExpandedRow({
|
||||
item,
|
||||
collapse,
|
||||
}: {
|
||||
item: ExtendedDownloadClientItem;
|
||||
collapse: () => void;
|
||||
}) {
|
||||
const t = useScopedI18n("widget.downloads");
|
||||
const locale = useCurrentIntlLocale();
|
||||
const progressPercent = Math.floor(item.progress * 100);
|
||||
@@ -891,13 +899,13 @@ function ExpandedRow({ item, collapse }: { item: ExtendedDownloadClientItem; col
|
||||
thickness={5}
|
||||
roundCaps
|
||||
sections={[{ value: progressPercent, color: progressColor(item.state, item.progress) }]}
|
||||
label={<Text ta="center" fw={700} style={{ fontSize: 10 }}>{`${progressPercent}%`}</Text>}
|
||||
label={<Text size="xs" ta="center" fw={700}>{`${progressPercent}%`}</Text>}
|
||||
/>
|
||||
|
||||
<Stack gap={4} style={{ flex: 1 }}>
|
||||
<Group gap="xs" wrap="nowrap">
|
||||
<Avatar size={16} radius={0} src={getIconUrl(item.integration.kind)} />
|
||||
<Text size="xs" fw={600} truncate>
|
||||
<Stack gap="xs" style={{ flex: 1, minWidth: 0 }}>
|
||||
<Group gap="xs" wrap="nowrap" style={{ minWidth: 0 }}>
|
||||
<Avatar size="var(--mantine-font-size-md)" radius={0} src={getIconUrl(item.integration.kind)} />
|
||||
<Text size="sm" fw={600} truncate style={{ minWidth: 0 }}>
|
||||
{item.name}
|
||||
</Text>
|
||||
<Badge size="xs" variant="light" color={stateColorMap[item.state]} ml="auto" style={{ flexShrink: 0 }}>
|
||||
@@ -905,7 +913,7 @@ function ExpandedRow({ item, collapse }: { item: ExtendedDownloadClientItem; col
|
||||
</Badge>
|
||||
</Group>
|
||||
|
||||
<SimpleGrid cols={3} spacing={4} verticalSpacing={2}>
|
||||
<SimpleGrid cols={3} spacing="xs" verticalSpacing={4} style={{ minWidth: 0 }}>
|
||||
<DetailPair
|
||||
label={t("items.size.detailsTitle")}
|
||||
value={`${formatBytes(item.received)} / ${formatBytes(item.size)}`}
|
||||
@@ -957,17 +965,17 @@ function DetailPair({
|
||||
color?: string;
|
||||
}) {
|
||||
return (
|
||||
<Group gap={4} wrap="nowrap">
|
||||
<Text size="xs" c="dimmed" style={{ whiteSpace: "nowrap", fontSize: 10 }}>
|
||||
<Stack gap={0} style={{ minWidth: 0, overflow: "hidden" }}>
|
||||
<Text size="xs" c="dimmed" truncate>
|
||||
{label}:
|
||||
</Text>
|
||||
<Group gap={2} wrap="nowrap">
|
||||
<Group gap={2} wrap="nowrap" style={{ minWidth: 0 }}>
|
||||
{icon}
|
||||
<Text size="xs" fw={500} c={color} truncate style={{ fontSize: 10 }}>
|
||||
<Text size="sm" fw={500} c={color} truncate style={{ minWidth: 0 }}>
|
||||
{value}
|
||||
</Text>
|
||||
</Group>
|
||||
</Group>
|
||||
</Stack>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { describe, expect, test } from "vitest";
|
||||
|
||||
import {
|
||||
DOWNLOAD_COLUMN_ACCESSORS,
|
||||
ADVANCED_DOWNLOAD_COLUMN_ACCESSORS,
|
||||
filterDownloadItemsByStatus,
|
||||
getAvailableDownloadStates,
|
||||
getDownloadColumnAccessors,
|
||||
@@ -25,8 +25,8 @@ describe("downloads filters", () => {
|
||||
});
|
||||
|
||||
describe("downloads advanced columns", () => {
|
||||
test("uses every column in advanced mode without changing the compact selection", () => {
|
||||
expect(getDownloadColumnAccessors(["name"], true)).toEqual(DOWNLOAD_COLUMN_ACCESSORS);
|
||||
test("uses summary columns in advanced mode without changing the compact selection", () => {
|
||||
expect(getDownloadColumnAccessors(["name"], true)).toEqual(ADVANCED_DOWNLOAD_COLUMN_ACCESSORS);
|
||||
expect(getDownloadColumnAccessors(["name"], false)).toEqual(["name"]);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -20,6 +20,17 @@ export const DOWNLOAD_COLUMN_ACCESSORS = [
|
||||
"type",
|
||||
] as const satisfies readonly (keyof ExtendedDownloadClientItem)[];
|
||||
|
||||
export const ADVANCED_DOWNLOAD_COLUMN_ACCESSORS = [
|
||||
"name",
|
||||
"progress",
|
||||
"size",
|
||||
"downSpeed",
|
||||
"upSpeed",
|
||||
"time",
|
||||
"state",
|
||||
"integration",
|
||||
] as const satisfies readonly (typeof DOWNLOAD_COLUMN_ACCESSORS)[number][];
|
||||
|
||||
type DownloadColumnAccessor = (typeof DOWNLOAD_COLUMN_ACCESSORS)[number];
|
||||
|
||||
export function getDownloadsStatsDisplay(showCompactStats: boolean, isAdvanced: boolean) {
|
||||
@@ -33,7 +44,7 @@ export function getDownloadColumnAccessors(
|
||||
configuredColumns: readonly DownloadColumnAccessor[],
|
||||
isAdvanced: boolean,
|
||||
): readonly DownloadColumnAccessor[] {
|
||||
return isAdvanced ? DOWNLOAD_COLUMN_ACCESSORS : configuredColumns;
|
||||
return isAdvanced ? ADVANCED_DOWNLOAD_COLUMN_ACCESSORS : configuredColumns;
|
||||
}
|
||||
|
||||
export function filterDownloadItemsByStatus<T extends { state: DownloadState }>(
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
diff --git a/dist/index.js b/dist/index.js
|
||||
index 1ac8241b321236fb9f43feb9405151da1fd3d975..9fb5fff13b2bfd2d1db4a7d16003f1fa9e0fb699 100644
|
||||
--- a/dist/index.js
|
||||
+++ b/dist/index.js
|
||||
@@ -1,2 +1,2 @@
|
||||
-"use strict";"use client";var pr=Object.create;var Dt=Object.defineProperty;var fr=Object.getOwnPropertyDescriptor;var br=Object.getOwnPropertyNames;var gr=Object.getPrototypeOf,Tr=Object.prototype.hasOwnProperty;var hr=(e,t)=>{for(var n in t)Dt(e,n,{get:t[n],enumerable:!0})},Rn=(e,t,n,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let a of br(t))!Tr.call(e,a)&&a!==n&&Dt(e,a,{get:()=>t[a],enumerable:!(o=fr(t,a))||o.enumerable});return e};var q=(e,t,n)=>(n=e!=null?pr(gr(e)):{},Rn(t||!e||!e.__esModule?Dt(n,"default",{value:e,enumerable:!0}):n,e)),Cr=e=>Rn(Dt({},"__esModule",{value:!0}),e);var xr={};hr(xr,{DataTable:()=>ra,DataTableDraggableRow:()=>sa,calculateColSpan:()=>it,differenceBy:()=>an,flattenColumns:()=>Xe,getGroupsAtDepth:()=>vt,getMaxGroupDepth:()=>xt,getRecordId:()=>F,getValueAtPath:()=>Rt,hasStringAccessor:()=>rt,humanize:()=>Ie,needsRightBorder:()=>rn,reorderRecords:()=>yr,sanitizeStoredArray:()=>pe,swapRecords:()=>Pr,uniqBy:()=>lt,useDataTableColumns:()=>ln});module.exports=Cr(xr);var Bt=require("@mantine/core"),Wt=require("@mantine/hooks"),Tn=q(require("clsx")),J=require("react");var xn=require("@mantine/core");function V(e,t,n){return e?(0,xn.parseThemeColor)({color:typeof e=="object"?e[n]:e,theme:t}).value:void 0}function vn({theme:e,c:t,backgroundColor:n,borderColor:o,rowBorderColor:a,stripedColor:r,highlightOnHoverColor:l}){return{"--mantine-datatable-color-light":V(t,e,"light"),"--mantine-datatable-color-dark":V(t,e,"dark"),"--mantine-datatable-background-color-light":V(n,e,"light"),"--mantine-datatable-background-color-dark":V(n,e,"dark"),"--mantine-datatable-border-color-light":V(o,e,"light"),"--mantine-datatable-border-color-dark":V(o,e,"dark"),"--mantine-datatable-row-border-color-light":V(a,e,"light"),"--mantine-datatable-row-border-color-dark":V(a,e,"dark"),"--mantine-datatable-striped-color-light":V(r,e,"light"),"--mantine-datatable-striped-color-dark":V(r,e,"dark"),"--mantine-datatable-highlight-on-hover-color-light":V(l,e,"light"),"--mantine-datatable-highlight-on-hover-color-dark":V(l,e,"dark")}}function wt({theme:e,paginationActiveTextColor:t,paginationActiveBackgroundColor:n}){return{"--mantine-datatable-pagination-active-text-color-light":V(t,e,"light"),"--mantine-datatable-pagination-active-text-color-dark":V(t,e,"dark"),"--mantine-datatable-pagination-active-background-color-light":V(n,e,"light"),"--mantine-datatable-pagination-active-background-color-dark":V(n,e,"dark")}}function Mn({theme:e,color:t,backgroundColor:n}){return{"--mantine-datatable-row-color-light":V(t,e,"light"),"--mantine-datatable-row-color-dark":V(t,e,"dark"),"--mantine-datatable-row-background-color-light":V(n,e,"light"),"--mantine-datatable-row-background-color-dark":V(n,e,"dark")}}var en=require("react");var kn=require("@mantine/core"),[En,$e]=(0,kn.createSafeContext)("useDataTableColumnsContext must be used within DataTableColumnProvider");var Ln=require("react/jsx-runtime"),tn=e=>{let{children:t,columnsOrder:n,setColumnsOrder:o,columnsToggle:a,setColumnsToggle:r,columnsPinning:l,setColumnsPinning:s,resetColumnsOrder:c,resetColumnsToggle:m,resetColumnsPinning:i,setColumnWidth:u,setMultipleColumnWidths:p,resetColumnsWidth:T,beginResize:d,endResize:S,pinnedMap:b}=e,[C,E]=(0,en.useState)(""),[D,L]=(0,en.useState)("");return(0,Ln.jsx)(En,{value:{sourceColumn:C,setSourceColumn:E,targetColumn:D,setTargetColumn:L,columnsToggle:a,setColumnsToggle:r,columnsPinning:l,setColumnsPinning:s,swapColumns:()=>{if(!n||!o||!C||!D)return;let f=b.get(C),h=b.get(D);if(f?.logicalSide!==h?.logicalSide)return;let w=n.indexOf(C),M=n.indexOf(D);if(w!==-1&&M!==-1){let g=[...n],[R]=g.splice(w,1);g.splice(M,0,R),o(g)}},resetColumnsOrder:c,resetColumnsToggle:m,resetColumnsPinning:i,setColumnWidth:u,setMultipleColumnWidths:p,resetColumnsWidth:T,beginResize:d,endResize:S},children:t})};var nn=require("react/jsx-runtime");function In(){return(0,nn.jsx)("tr",{className:"mantine-datatable-empty-row",children:(0,nn.jsx)("td",{})})}var St=require("@mantine/core");var be=require("react/jsx-runtime");function Nn(){return(0,be.jsxs)("svg",{width:"24",height:"24",viewBox:"0 0 24 24",strokeWidth:"2",stroke:"currentColor",fill:"none",strokeLinecap:"round",strokeLinejoin:"round",children:[(0,be.jsx)("path",{stroke:"none",d:"M0 0h24v24H0z",fill:"none"}),(0,be.jsx)("path",{d:"M12.983 8.978c3.955 -.182 7.017 -1.446 7.017 -2.978c0 -1.657 -3.582 -3 -8 -3c-1.661 0 -3.204 .19 -4.483 .515m-2.783 1.228c-.471 .382 -.734 .808 -.734 1.257c0 1.22 1.944 2.271 4.734 2.74"}),(0,be.jsx)("path",{d:"M4 6v6c0 1.657 3.582 3 8 3c.986 0 1.93 -.067 2.802 -.19m3.187 -.82c1.251 -.53 2.011 -1.228 2.011 -1.99v-6"}),(0,be.jsx)("path",{d:"M4 12v6c0 1.657 3.582 3 8 3c3.217 0 5.991 -.712 7.261 -1.74m.739 -3.26v-4"}),(0,be.jsx)("path",{d:"M3 3l18 18"})]})}var me=require("react/jsx-runtime");function Hn({icon:e,text:t,active:n,children:o}){return(0,me.jsx)(St.Center,{className:"mantine-datatable-empty-state","data-active":n||void 0,children:o||(0,me.jsxs)(me.Fragment
Line truncated
|
||||
+"use strict";"use client";var pr=Object.create;var Dt=Object.defineProperty;var fr=Object.getOwnPropertyDescriptor;var br=Object.getOwnPropertyNames;var gr=Object.getPrototypeOf,Tr=Object.prototype.hasOwnProperty;var hr=(e,t)=>{for(var n in t)Dt(e,n,{get:t[n],enumerable:!0})},Rn=(e,t,n,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let a of br(t))!Tr.call(e,a)&&a!==n&&Dt(e,a,{get:()=>t[a],enumerable:!(o=fr(t,a))||o.enumerable});return e};var q=(e,t,n)=>(n=e!=null?pr(gr(e)):{},Rn(t||!e||!e.__esModule?Dt(n,"default",{value:e,enumerable:!0}):n,e)),Cr=e=>Rn(Dt({},"__esModule",{value:!0}),e);var xr={};hr(xr,{DataTable:()=>ra,DataTableDraggableRow:()=>sa,calculateColSpan:()=>it,differenceBy:()=>an,flattenColumns:()=>Xe,getGroupsAtDepth:()=>vt,getMaxGroupDepth:()=>xt,getRecordId:()=>F,getValueAtPath:()=>Rt,hasStringAccessor:()=>rt,humanize:()=>Ie,needsRightBorder:()=>rn,reorderRecords:()=>yr,sanitizeStoredArray:()=>pe,swapRecords:()=>Pr,uniqBy:()=>lt,useDataTableColumns:()=>ln});module.exports=Cr(xr);var Bt=require("@mantine/core"),Wt=require("@mantine/hooks"),Tn=q(require("clsx")),J=require("react");var xn=require("@mantine/core");function V(e,t,n){return e?(0,xn.parseThemeColor)({color:typeof e=="object"?e[n]:e,theme:t}).value:void 0}function vn({theme:e,c:t,backgroundColor:n,borderColor:o,rowBorderColor:a,stripedColor:r,highlightOnHoverColor:l}){return{"--mantine-datatable-color-light":V(t,e,"light"),"--mantine-datatable-color-dark":V(t,e,"dark"),"--mantine-datatable-background-color-light":V(n,e,"light"),"--mantine-datatable-background-color-dark":V(n,e,"dark"),"--mantine-datatable-border-color-light":V(o,e,"light"),"--mantine-datatable-border-color-dark":V(o,e,"dark"),"--mantine-datatable-row-border-color-light":V(a,e,"light"),"--mantine-datatable-row-border-color-dark":V(a,e,"dark"),"--mantine-datatable-striped-color-light":V(r,e,"light"),"--mantine-datatable-striped-color-dark":V(r,e,"dark"),"--mantine-datatable-highlight-on-hover-color-light":V(l,e,"light"),"--mantine-datatable-highlight-on-hover-color-dark":V(l,e,"dark")}}function wt({theme:e,paginationActiveTextColor:t,paginationActiveBackgroundColor:n}){return{"--mantine-datatable-pagination-active-text-color-light":V(t,e,"light"),"--mantine-datatable-pagination-active-text-color-dark":V(t,e,"dark"),"--mantine-datatable-pagination-active-background-color-light":V(n,e,"light"),"--mantine-datatable-pagination-active-background-color-dark":V(n,e,"dark")}}function Mn({theme:e,color:t,backgroundColor:n}){return{"--mantine-datatable-row-color-light":V(t,e,"light"),"--mantine-datatable-row-color-dark":V(t,e,"dark"),"--mantine-datatable-row-background-color-light":V(n,e,"light"),"--mantine-datatable-row-background-color-dark":V(n,e,"dark")}}var en=require("react");var kn=require("@mantine/core"),[En,$e]=(0,kn.createSafeContext)("useDataTableColumnsContext must be used within DataTableColumnProvider");var Ln=require("react/jsx-runtime"),tn=e=>{let{children:t,columnsOrder:n,setColumnsOrder:o,columnsToggle:a,setColumnsToggle:r,columnsPinning:l,setColumnsPinning:s,resetColumnsOrder:c,resetColumnsToggle:m,resetColumnsPinning:i,setColumnWidth:u,setMultipleColumnWidths:p,resetColumnsWidth:T,beginResize:d,endResize:S,pinnedMap:b}=e,[C,E]=(0,en.useState)(""),[D,L]=(0,en.useState)("");return(0,Ln.jsx)(En,{value:{sourceColumn:C,setSourceColumn:E,targetColumn:D,setTargetColumn:L,columnsToggle:a,setColumnsToggle:r,columnsPinning:l,setColumnsPinning:s,swapColumns:()=>{if(!n||!o||!C||!D)return;let f=b.get(C),h=b.get(D);if(f?.logicalSide!==h?.logicalSide)return;let w=n.indexOf(C),M=n.indexOf(D);if(w!==-1&&M!==-1){let g=[...n],[R]=g.splice(w,1);g.splice(M,0,R),o(g)}},resetColumnsOrder:c,resetColumnsToggle:m,resetColumnsPinning:i,setColumnWidth:u,setMultipleColumnWidths:p,resetColumnsWidth:T,beginResize:d,endResize:S},children:t})};var nn=require("react/jsx-runtime");function In(){return(0,nn.jsx)("tr",{className:"mantine-datatable-empty-row",children:(0,nn.jsx)("td",{})})}var St=require("@mantine/core");var be=require("react/jsx-runtime");function Nn(){return(0,be.jsxs)("svg",{width:"24",height:"24",viewBox:"0 0 24 24",strokeWidth:"2",stroke:"currentColor",fill:"none",strokeLinecap:"round",strokeLinejoin:"round",children:[(0,be.jsx)("path",{stroke:"none",d:"M0 0h24v24H0z",fill:"none"}),(0,be.jsx)("path",{d:"M12.983 8.978c3.955 -.182 7.017 -1.446 7.017 -2.978c0 -1.657 -3.582 -3 -8 -3c-1.661 0 -3.204 .19 -4.483 .515m-2.783 1.228c-.471 .382 -.734 .808 -.734 1.257c0 1.22 1.944 2.271 4.734 2.74"}),(0,be.jsx)("path",{d:"M4 6v6c0 1.657 3.582 3 8 3c.986 0 1.93 -.067 2.802 -.19m3.187 -.82c1.251 -.53 2.011 -1.228 2.011 -1.99v-6"}),(0,be.jsx)("path",{d:"M4 12v6c0 1.657 3.582 3 8 3c3.217 0 5.991 -.712 7.261 -1.74m.739 -3.26v-4"}),(0,be.jsx)("path",{d:"M3 3l18 18"})]})}var me=require("react/jsx-runtime");function Hn({icon:e,text:t,active:n,children:o}){return(0,me.jsx)(St.Center,{className:"mantine-datatable-empty-state","data-active":n||void 0,children:o||(0,me.jsxs)(me.Fragment
Line truncated
|
||||
//# sourceMappingURL=index.js.map
|
||||
\ No newline at end of file
|
||||
diff --git a/dist/index.mjs b/dist/index.mjs
|
||||
index bfbf1cdbdd176b5776f553075da709115855384a..9583f1c5db65568d77f2dc468ab2d9841175623b 100644
|
||||
--- a/dist/index.mjs
|
||||
+++ b/dist/index.mjs
|
||||
@@ -1,2 +1,2 @@
|
||||
-"use client";import{Box as Wl,Table as Bl}from"@mantine/core";import{useMergedRef as Ht}from"@mantine/hooks";import Co from"clsx";import{useCallback as At,useEffect as Vl,useLayoutEffect as Gl,useMemo as Fl,useRef as lt}from"react";import{parseThemeColor as Sa}from"@mantine/core";function W(e,t,n){return e?Sa({color:typeof e=="object"?e[n]:e,theme:t}).value:void 0}function Ft({theme:e,c:t,backgroundColor:n,borderColor:o,rowBorderColor:a,stripedColor:r,highlightOnHoverColor:l}){return{"--mantine-datatable-color-light":W(t,e,"light"),"--mantine-datatable-color-dark":W(t,e,"dark"),"--mantine-datatable-background-color-light":W(n,e,"light"),"--mantine-datatable-background-color-dark":W(n,e,"dark"),"--mantine-datatable-border-color-light":W(o,e,"light"),"--mantine-datatable-border-color-dark":W(o,e,"dark"),"--mantine-datatable-row-border-color-light":W(a,e,"light"),"--mantine-datatable-row-border-color-dark":W(a,e,"dark"),"--mantine-datatable-striped-color-light":W(r,e,"light"),"--mantine-datatable-striped-color-dark":W(r,e,"dark"),"--mantine-datatable-highlight-on-hover-color-light":W(l,e,"light"),"--mantine-datatable-highlight-on-hover-color-dark":W(l,e,"dark")}}function We({theme:e,paginationActiveTextColor:t,paginationActiveBackgroundColor:n}){return{"--mantine-datatable-pagination-active-text-color-light":W(t,e,"light"),"--mantine-datatable-pagination-active-text-color-dark":W(t,e,"dark"),"--mantine-datatable-pagination-active-background-color-light":W(n,e,"light"),"--mantine-datatable-pagination-active-background-color-dark":W(n,e,"dark")}}function $t({theme:e,color:t,backgroundColor:n}){return{"--mantine-datatable-row-color-light":W(t,e,"light"),"--mantine-datatable-row-color-dark":W(t,e,"dark"),"--mantine-datatable-row-background-color-light":W(n,e,"light"),"--mantine-datatable-row-background-color-dark":W(n,e,"dark")}}import{useState as Ut}from"react";import{createSafeContext as Ra}from"@mantine/core";var[Xt,Pe]=Ra("useDataTableColumnsContext must be used within DataTableColumnProvider");import{jsx as xa}from"react/jsx-runtime";var Ct=e=>{let{children:t,columnsOrder:n,setColumnsOrder:o,columnsToggle:a,setColumnsToggle:r,columnsPinning:l,setColumnsPinning:s,resetColumnsOrder:c,resetColumnsToggle:m,resetColumnsPinning:i,setColumnWidth:u,setMultipleColumnWidths:p,resetColumnsWidth:T,beginResize:d,endResize:S,pinnedMap:b}=e,[C,E]=Ut(""),[D,L]=Ut("");return xa(Xt,{value:{sourceColumn:C,setSourceColumn:E,targetColumn:D,setTargetColumn:L,columnsToggle:a,setColumnsToggle:r,columnsPinning:l,setColumnsPinning:s,swapColumns:()=>{if(!n||!o||!C||!D)return;let f=b.get(C),h=b.get(D);if(f?.logicalSide!==h?.logicalSide)return;let w=n.indexOf(C),M=n.indexOf(D);if(w!==-1&&M!==-1){let g=[...n],[R]=g.splice(w,1);g.splice(M,0,R),o(g)}},resetColumnsOrder:c,resetColumnsToggle:m,resetColumnsPinning:i,setColumnWidth:u,setMultipleColumnWidths:p,resetColumnsWidth:T,beginResize:d,endResize:S},children:t})};import{jsx as Qt}from"react/jsx-runtime";function Kt(){return Qt("tr",{className:"mantine-datatable-empty-row",children:Qt("td",{})})}import{Center as Ma,Text as ka}from"@mantine/core";import{jsx as Le,jsxs as va}from"react/jsx-runtime";function jt(){return va("svg",{width:"24",height:"24",viewBox:"0 0 24 24",strokeWidth:"2",stroke:"currentColor",fill:"none",strokeLinecap:"round",strokeLinejoin:"round",children:[Le("path",{stroke:"none",d:"M0 0h24v24H0z",fill:"none"}),Le("path",{d:"M12.983 8.978c3.955 -.182 7.017 -1.446 7.017 -2.978c0 -1.657 -3.582 -3 -8 -3c-1.661 0 -3.204 .19 -4.483 .515m-2.783 1.228c-.471 .382 -.734 .808 -.734 1.257c0 1.22 1.944 2.271 4.734 2.74"}),Le("path",{d:"M4 6v6c0 1.657 3.582 3 8 3c.986 0 1.93 -.067 2.802 -.19m3.187 -.82c1.251 -.53 2.011 -1.228 2.011 -1.99v-6"}),Le("path",{d:"M4 12v6c0 1.657 3.582 3 8 3c3.217 0 5.991 -.712 7.261 -1.74m.739 -3.26v-4"}),Le("path",{d:"M3 3l18 18"})]})}import{Fragment as Ea,jsx as Be,jsxs as La}from"react/jsx-runtime";function Jt({icon:e,text:t,active:n,children:o}){return Be(Ma,{className:"mantine-datatable-empty-state","data-active":n||void 0,children:o||La(Ea,{children:[e||Be("div",{className:"mantine-datatable-empty-state-icon",children:Be(jt,{})}),Be(ka,{component:"div",size:"sm",c:"dimmed",children:t})]})})}import{TableTfoot as dr,TableTr as mr}from"@mantine/core";import pr from"clsx";import{TableTh as lr}from"@mantine/core";import ir from"clsx";import{useCallback as fi,useRef as bi,useState as gi}from"react";import{useLocalStorage as Ia}from"@mantine/hooks";import{useEffect as Na,useMemo as Yt}from"react";function De(e){let t=e.replace(/([a-z\d])([A-Z]+)/g,"$1 $2").replace(/\W|_/g," ").trim().toLowerCase();return`${t.charAt(0).toUpperCase()}${t.slice(1)}`}function Z(e,t,n){return!Array.isArray(e)||n&&!e.every(n)?t:e}function Ve(e){return typeof e=="object"&&e!==null&&typeof e.accessor=="string"}function qt(e,t,n){return e.filter(o=>!t.map(n).includes(n(o)))}function Ge(e,t){return e.filter((n,o,a)=>o===a.findIndex(r=>t(n)===t(r)))}function yt(e,t){return t?t.match(/
Line truncated
|
||||
+"use client";import{Box as Wl,Table as Bl}from"@mantine/core";import{useMergedRef as Ht}from"@mantine/hooks";import Co from"clsx";import{useCallback as At,useEffect as Vl,useLayoutEffect as Gl,useMemo as Fl,useRef as lt}from"react";import{parseThemeColor as Sa}from"@mantine/core";function W(e,t,n){return e?Sa({color:typeof e=="object"?e[n]:e,theme:t}).value:void 0}function Ft({theme:e,c:t,backgroundColor:n,borderColor:o,rowBorderColor:a,stripedColor:r,highlightOnHoverColor:l}){return{"--mantine-datatable-color-light":W(t,e,"light"),"--mantine-datatable-color-dark":W(t,e,"dark"),"--mantine-datatable-background-color-light":W(n,e,"light"),"--mantine-datatable-background-color-dark":W(n,e,"dark"),"--mantine-datatable-border-color-light":W(o,e,"light"),"--mantine-datatable-border-color-dark":W(o,e,"dark"),"--mantine-datatable-row-border-color-light":W(a,e,"light"),"--mantine-datatable-row-border-color-dark":W(a,e,"dark"),"--mantine-datatable-striped-color-light":W(r,e,"light"),"--mantine-datatable-striped-color-dark":W(r,e,"dark"),"--mantine-datatable-highlight-on-hover-color-light":W(l,e,"light"),"--mantine-datatable-highlight-on-hover-color-dark":W(l,e,"dark")}}function We({theme:e,paginationActiveTextColor:t,paginationActiveBackgroundColor:n}){return{"--mantine-datatable-pagination-active-text-color-light":W(t,e,"light"),"--mantine-datatable-pagination-active-text-color-dark":W(t,e,"dark"),"--mantine-datatable-pagination-active-background-color-light":W(n,e,"light"),"--mantine-datatable-pagination-active-background-color-dark":W(n,e,"dark")}}function $t({theme:e,color:t,backgroundColor:n}){return{"--mantine-datatable-row-color-light":W(t,e,"light"),"--mantine-datatable-row-color-dark":W(t,e,"dark"),"--mantine-datatable-row-background-color-light":W(n,e,"light"),"--mantine-datatable-row-background-color-dark":W(n,e,"dark")}}import{useState as Ut}from"react";import{createSafeContext as Ra}from"@mantine/core";var[Xt,Pe]=Ra("useDataTableColumnsContext must be used within DataTableColumnProvider");import{jsx as xa}from"react/jsx-runtime";var Ct=e=>{let{children:t,columnsOrder:n,setColumnsOrder:o,columnsToggle:a,setColumnsToggle:r,columnsPinning:l,setColumnsPinning:s,resetColumnsOrder:c,resetColumnsToggle:m,resetColumnsPinning:i,setColumnWidth:u,setMultipleColumnWidths:p,resetColumnsWidth:T,beginResize:d,endResize:S,pinnedMap:b}=e,[C,E]=Ut(""),[D,L]=Ut("");return xa(Xt,{value:{sourceColumn:C,setSourceColumn:E,targetColumn:D,setTargetColumn:L,columnsToggle:a,setColumnsToggle:r,columnsPinning:l,setColumnsPinning:s,swapColumns:()=>{if(!n||!o||!C||!D)return;let f=b.get(C),h=b.get(D);if(f?.logicalSide!==h?.logicalSide)return;let w=n.indexOf(C),M=n.indexOf(D);if(w!==-1&&M!==-1){let g=[...n],[R]=g.splice(w,1);g.splice(M,0,R),o(g)}},resetColumnsOrder:c,resetColumnsToggle:m,resetColumnsPinning:i,setColumnWidth:u,setMultipleColumnWidths:p,resetColumnsWidth:T,beginResize:d,endResize:S},children:t})};import{jsx as Qt}from"react/jsx-runtime";function Kt(){return Qt("tr",{className:"mantine-datatable-empty-row",children:Qt("td",{})})}import{Center as Ma,Text as ka}from"@mantine/core";import{jsx as Le,jsxs as va}from"react/jsx-runtime";function jt(){return va("svg",{width:"24",height:"24",viewBox:"0 0 24 24",strokeWidth:"2",stroke:"currentColor",fill:"none",strokeLinecap:"round",strokeLinejoin:"round",children:[Le("path",{stroke:"none",d:"M0 0h24v24H0z",fill:"none"}),Le("path",{d:"M12.983 8.978c3.955 -.182 7.017 -1.446 7.017 -2.978c0 -1.657 -3.582 -3 -8 -3c-1.661 0 -3.204 .19 -4.483 .515m-2.783 1.228c-.471 .382 -.734 .808 -.734 1.257c0 1.22 1.944 2.271 4.734 2.74"}),Le("path",{d:"M4 6v6c0 1.657 3.582 3 8 3c.986 0 1.93 -.067 2.802 -.19m3.187 -.82c1.251 -.53 2.011 -1.228 2.011 -1.99v-6"}),Le("path",{d:"M4 12v6c0 1.657 3.582 3 8 3c3.217 0 5.991 -.712 7.261 -1.74m.739 -3.26v-4"}),Le("path",{d:"M3 3l18 18"})]})}import{Fragment as Ea,jsx as Be,jsxs as La}from"react/jsx-runtime";function Jt({icon:e,text:t,active:n,children:o}){return Be(Ma,{className:"mantine-datatable-empty-state","data-active":n||void 0,children:o||La(Ea,{children:[e||Be("div",{className:"mantine-datatable-empty-state-icon",children:Be(jt,{})}),Be(ka,{component:"div",size:"sm",c:"dimmed",children:t})]})})}import{TableTfoot as dr,TableTr as mr}from"@mantine/core";import pr from"clsx";import{TableTh as lr}from"@mantine/core";import ir from"clsx";import{useCallback as fi,useRef as bi,useState as gi}from"react";import{useLocalStorage as Ia}from"@mantine/hooks";import{useEffect as Na,useMemo as Yt}from"react";function De(e){let t=e.replace(/([a-z\d])([A-Z]+)/g,"$1 $2").replace(/\W|_/g," ").trim().toLowerCase();return`${t.charAt(0).toUpperCase()}${t.slice(1)}`}function Z(e,t,n){return!Array.isArray(e)||n&&!e.every(n)?t:e}function Ve(e){return typeof e=="object"&&e!==null&&typeof e.accessor=="string"}function qt(e,t,n){return e.filter(o=>!t.map(n).includes(n(o)))}function Ge(e,t){return e.filter((n,o,a)=>o===a.findIndex(r=>t(n)===t(r)))}function yt(e,t){return t?t.match(/
Line truncated
|
||||
//# sourceMappingURL=index.mjs.map
|
||||
Generated
+4
-3
@@ -704,6 +704,7 @@ overrides:
|
||||
|
||||
patchedDependencies:
|
||||
'@types/node-unifi': 5e6ae51e2a17a7f9729bfa30b0eb3d0842a5810ac6db47603ab4a6efa1ed84c5
|
||||
mantine-datatable@9.3.1: 8b83a773610215e619e3f5acbec2d26fb6f27b089852e2bc754d10d8515c1254
|
||||
trpc-to-openapi: 2ca3c16af0fcca0c736697ad4fe553a14f794524fa9ce0d5c3e8ee4aea76090c
|
||||
|
||||
importers:
|
||||
@@ -1209,7 +1210,7 @@ importers:
|
||||
version: 3.10.1
|
||||
mantine-datatable:
|
||||
specifier: 'catalog:'
|
||||
version: 9.3.1(@mantine/core@9.4.1(@mantine/hooks@9.4.1(react@19.2.7))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(@mantine/hooks@9.4.1(react@19.2.7))(clsx@2.1.1)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)
|
||||
version: 9.3.1(patch_hash=8b83a773610215e619e3f5acbec2d26fb6f27b089852e2bc754d10d8515c1254)(@mantine/core@9.4.1(@mantine/hooks@9.4.1(react@19.2.7))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(@mantine/hooks@9.4.1(react@19.2.7))(clsx@2.1.1)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)
|
||||
mantine-react-table:
|
||||
specifier: 'catalog:'
|
||||
version: mantine-react-table-open@9.0.3(@mantine/core@9.4.1(@mantine/hooks@9.4.1(react@19.2.7))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(@mantine/dates@9.4.1(@mantine/core@9.4.1(@mantine/hooks@9.4.1(react@19.2.7))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(@mantine/hooks@9.4.1(react@19.2.7))(dayjs@1.11.21)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(@mantine/hooks@9.4.1(react@19.2.7))(@tabler/icons-react@3.44.0(react@19.2.7))(clsx@2.1.1)(dayjs@1.11.21)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)
|
||||
@@ -2984,7 +2985,7 @@ importers:
|
||||
version: 1.24.0(react@19.2.7)
|
||||
mantine-datatable:
|
||||
specifier: 'catalog:'
|
||||
version: 9.3.1(@mantine/core@9.4.1(@mantine/hooks@9.4.1(react@19.2.7))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(@mantine/hooks@9.4.1(react@19.2.7))(clsx@2.1.1)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)
|
||||
version: 9.3.1(patch_hash=8b83a773610215e619e3f5acbec2d26fb6f27b089852e2bc754d10d8515c1254)(@mantine/core@9.4.1(@mantine/hooks@9.4.1(react@19.2.7))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(@mantine/hooks@9.4.1(react@19.2.7))(clsx@2.1.1)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)
|
||||
mantine-react-table:
|
||||
specifier: 'catalog:'
|
||||
version: mantine-react-table-open@9.0.3(@mantine/core@9.4.1(@mantine/hooks@9.4.1(react@19.2.7))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(@mantine/dates@9.4.1(@mantine/core@9.4.1(@mantine/hooks@9.4.1(react@19.2.7))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(@mantine/hooks@9.4.1(react@19.2.7))(dayjs@1.11.21)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(@mantine/hooks@9.4.1(react@19.2.7))(@tabler/icons-react@3.44.0(react@19.2.7))(clsx@2.1.1)(dayjs@1.11.21)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)
|
||||
@@ -28633,7 +28634,7 @@ snapshots:
|
||||
dependencies:
|
||||
semver: 7.8.5
|
||||
|
||||
mantine-datatable@9.3.1(@mantine/core@9.4.1(@mantine/hooks@9.4.1(react@19.2.7))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(@mantine/hooks@9.4.1(react@19.2.7))(clsx@2.1.1)(react-dom@19.2.7(react@19.2.7))(react@19.2.7):
|
||||
mantine-datatable@9.3.1(patch_hash=8b83a773610215e619e3f5acbec2d26fb6f27b089852e2bc754d10d8515c1254)(@mantine/core@9.4.1(@mantine/hooks@9.4.1(react@19.2.7))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(@mantine/hooks@9.4.1(react@19.2.7))(clsx@2.1.1)(react-dom@19.2.7(react@19.2.7))(react@19.2.7):
|
||||
dependencies:
|
||||
'@mantine/core': 9.4.1(@mantine/hooks@9.4.1(react@19.2.7))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)
|
||||
'@mantine/hooks': 9.4.1(react@19.2.7)
|
||||
|
||||
@@ -280,6 +280,7 @@ overrides:
|
||||
"vite@>=5.0.0 <=5.4.18": ">=8.1.4"
|
||||
patchedDependencies:
|
||||
"@types/node-unifi": "patches/@types__node-unifi.patch"
|
||||
mantine-datatable@9.3.1: patches/mantine-datatable@9.3.1.patch
|
||||
"trpc-to-openapi": "patches/trpc-to-openapi.patch"
|
||||
|
||||
allowUnusedPatches: true
|
||||
|
||||
Reference in new issue
Block a user