chore: consolidate platform split checks
Some checks failed
Dependency Audit / dependency-audit (push) Has been cancelled
Module Matrix / module-matrix (push) Has been cancelled

This commit is contained in:
2026-07-10 12:51:19 +02:00
parent 150b720f12
commit 635d25c74c
216 changed files with 23336 additions and 4077 deletions

View File

@@ -0,0 +1,84 @@
import type { CSSProperties, ReactNode } from "react";
export type ConnectionTreeColumn<T> = {
id: string;
header: ReactNode;
width?: string;
align?: "left" | "center" | "right";
render: (row: T, depth: number) => ReactNode;
};
export type ConnectionTreeProps<T> = {
rows: T[];
columns: ConnectionTreeColumn<T>[];
getRowKey: (row: T) => string;
getChildren?: (row: T) => T[];
renderActions?: (row: T, depth: number) => ReactNode;
emptyText?: ReactNode;
className?: string;
rowClassName?: (row: T, depth: number) => string;
};
type FlatRow<T> = {
row: T;
depth: number;
};
export default function ConnectionTree<T>({
rows,
columns,
getRowKey,
getChildren,
renderActions,
emptyText = "i18n:govoplan-core.no_entries_configured.48e7b97c",
className = "",
rowClassName
}: ConnectionTreeProps<T>) {
const flatRows = flattenRows(rows, getChildren);
const gridTemplateColumns = `${columns.map((column) => column.width || "minmax(0, 1fr)").join(" ")} ${renderActions ? "var(--connection-tree-actions-column, 196px)" : ""}`.trim();
return (
<div className={`connection-tree ${className}`.trim()}>
<div className="connection-tree-header" style={{ gridTemplateColumns }}>
{columns.map((column) =>
<div className={`connection-tree-cell ${column.align ? `align-${column.align}` : ""}`.trim()} key={column.id}>
{column.header}
</div>
)}
{renderActions && <div className="connection-tree-cell align-right">i18n:govoplan-core.actions.c3cd636a</div>}
</div>
{flatRows.length === 0 && <div className="connection-tree-empty">{emptyText}</div>}
{flatRows.map(({ row, depth }) => {
const className = ["connection-tree-row", depth > 0 ? "is-child" : "is-parent", rowClassName?.(row, depth) || ""].filter(Boolean).join(" ");
return (
<div className={className} style={{ gridTemplateColumns }} key={getRowKey(row)}>
{columns.map((column, index) =>
<div
className={`connection-tree-cell ${column.align ? `align-${column.align}` : ""} ${index === 0 ? "connection-tree-primary-cell" : ""}`.trim()}
key={column.id}>
{index === 0 ?
<div className="connection-tree-primary-content" style={{ "--connection-tree-depth": String(depth) } as CSSProperties}>
{column.render(row, depth)}
</div> :
column.render(row, depth)
}
</div>
)}
{renderActions && <div className="connection-tree-cell align-right connection-tree-actions">{renderActions(row, depth)}</div>}
</div>);
})}
</div>);
}
function flattenRows<T>(rows: T[], getChildren?: (row: T) => T[]): FlatRow<T>[] {
const result: FlatRow<T>[] = [];
for (const row of rows) {
result.push({ row, depth: 0 });
for (const child of getChildren?.(row) ?? []) {
result.push({ row: child, depth: 1 });
}
}
return result;
}