Древовидные справочники: parent_id, drag&drop, древовидный выбор в полях table

This commit is contained in:
2026-07-12 20:55:30 +03:00
parent 833fa97f56
commit ec08f3222d
10 changed files with 1284 additions and 68 deletions

View File

@@ -490,7 +490,7 @@ export function registerDataTableRoutes(app: import("express").Express): void {
try {
const tableId = parseInt(req.params.tableId);
const table = await storage.getDataTable(tableId, req.organizationId!);
if (!table) {
return res.status(404).json({ error: 'Таблица не найдена' });
}
@@ -500,12 +500,12 @@ export function registerDataTableRoutes(app: import("express").Express): void {
return res.status(403).json({ error: 'Нет прав для добавления строк' });
}
const { values } = req.body;
const { values, parentId } = req.body;
if (!values || !Array.isArray(values)) {
return res.status(400).json({ error: 'Значения обязательны' });
}
const row = await storage.createDataTableRow({ tableId, values });
const row = await storage.createDataTableRow({ tableId, values, parentId: parentId ?? null });
res.status(201).json({ row });
} catch (error) {
console.error('Create table row error:', error);
@@ -514,7 +514,7 @@ export function registerDataTableRoutes(app: import("express").Express): void {
}
);
// Update table row
// Update table row (values and/or hierarchy)
app.patch(['/api/tables/:tableId/rows/:rowId', '/api/directories/:tableId/rows/:rowId'],
authenticateToken,
tenantIsolation,
@@ -523,7 +523,7 @@ export function registerDataTableRoutes(app: import("express").Express): void {
const tableId = parseInt(req.params.tableId);
const rowId = parseInt(req.params.rowId);
const table = await storage.getDataTable(tableId, req.organizationId!);
if (!table) {
return res.status(404).json({ error: 'Таблица не найдена' });
}
@@ -533,16 +533,34 @@ export function registerDataTableRoutes(app: import("express").Express): void {
return res.status(403).json({ error: 'Нет прав для редактирования строк' });
}
const { values } = req.body;
if (!values || !Array.isArray(values)) {
return res.status(400).json({ error: 'Значения обязательны' });
const { values, parentId, position } = req.body;
let row;
if (parentId !== undefined || position !== undefined) {
row = await storage.moveDataTableRow(
rowId,
tableId,
req.organizationId!,
parentId ?? null,
position ?? 0
);
}
if (values !== undefined) {
if (!Array.isArray(values)) {
return res.status(400).json({ error: 'Значения должны быть массивом' });
}
row = await storage.updateDataTableRow(rowId, tableId, req.organizationId!, { values });
}
if (!row) {
return res.status(400).json({ error: 'Не переданы данные для обновления' });
}
const row = await storage.updateDataTableRow(rowId, tableId, req.organizationId!, { values });
res.json({ row });
} catch (error) {
} catch (error: any) {
console.error('Update table row error:', error);
res.status(500).json({ error: 'Ошибка обновления строки' });
res.status(400).json({ error: error.message || 'Ошибка обновления строки' });
}
}
);