refactor(workspace): restore yaml exports and align docker builds

- return scenario export payloads as yaml to match existing workflows

- harden step reordering flow for drag-and-drop and one-based ui labels

- switch server container to workspace-lockfile installs and root ignore rules
This commit is contained in:
2026-04-10 18:19:38 +03:00
parent 259dac806e
commit de0cbeef7c
18 changed files with 361 additions and 11385 deletions
+41 -21
View File
@@ -1,4 +1,4 @@
import { useState, type ReactNode } from 'react';
import { useState, type HTMLAttributes, type MouseEvent, type ReactNode } from 'react';
import { Pagination } from '../Pagination/Pagination';
import styles from './Table.module.css';
@@ -23,6 +23,8 @@ export interface TableProps<T> {
pageSizeOptions?: number[];
/** Called when a row is clicked */
onRowClick?: (row: T) => void;
/** Optional per-row props, useful for drag-and-drop and row-level attributes */
getRowProps?: (row: T) => HTMLAttributes<HTMLTableRowElement>;
}
export function Table<T>({
@@ -35,6 +37,7 @@ export function Table<T>({
pageSize: defaultPageSize,
pageSizeOptions,
onRowClick,
getRowProps,
}: TableProps<T>) {
const [page, setPage] = useState(1);
const [pageSize, setPageSize] = useState(defaultPageSize ?? 0);
@@ -79,26 +82,43 @@ export function Table<T>({
</td>
</tr>
) : (
visibleData.map((row) => (
<tr
key={rowKey(row)}
className={[styles.tr, onRowClick ? styles.clickable : '']
.filter(Boolean)
.join(' ')}
onClick={onRowClick ? () => onRowClick(row) : undefined}
>
{columns.map((col) => (
<td
key={col.key}
className={styles.td}
style={{ textAlign: col.align ?? 'left' }}
onClick={col.key === 'actions' ? (e) => e.stopPropagation() : undefined}
>
{col.render(row)}
</td>
))}
</tr>
))
visibleData.map((row) => {
const rowProps = getRowProps?.(row);
const mergedClassName = [
styles.tr,
onRowClick ? styles.clickable : '',
rowProps?.className ?? '',
]
.filter(Boolean)
.join(' ');
const handleClick = (event: MouseEvent<HTMLTableRowElement>) => {
rowProps?.onClick?.(event);
if (!event.defaultPrevented) {
onRowClick?.(row);
}
};
return (
<tr
key={rowKey(row)}
{...rowProps}
className={mergedClassName}
onClick={onRowClick || rowProps?.onClick ? handleClick : undefined}
>
{columns.map((col) => (
<td
key={col.key}
className={styles.td}
style={{ textAlign: col.align ?? 'left' }}
onClick={col.key === 'actions' ? (e) => e.stopPropagation() : undefined}
>
{col.render(row)}
</td>
))}
</tr>
);
})
)}
</tbody>
</table>