feat: автоматический выбор подсправочника по привязке к строке родителя

This commit is contained in:
2026-07-21 14:24:35 +03:00
parent 2e1652e7ee
commit dee9ae7ad6
2 changed files with 17 additions and 60 deletions

View File

@@ -47,11 +47,6 @@ export default function SubdirectoryFieldConfig({
const subdirectories = subdirectoriesData?.subdirectories || [];
const showSubdirectory = !!field.options?.showSubdirectory;
const selectedSubdirectoryId = field.options?.subdirectoryId as number | undefined;
const selectedSubdirectory = useMemo(() => {
return subdirectories.find((s) => s.id === selectedSubdirectoryId || s.childTableId === selectedSubdirectoryId);
}, [subdirectories, selectedSubdirectoryId]);
const selectedTable = useMemo(() => {
return tablesData?.tables?.find((t) => t.id === tableId);
@@ -65,7 +60,6 @@ export default function SubdirectoryFieldConfig({
tableId: undefined,
displayColumn: undefined,
showSubdirectory: undefined,
subdirectoryId: undefined,
},
});
return;
@@ -78,7 +72,6 @@ export default function SubdirectoryFieldConfig({
tableId: newTableId,
displayColumn: newSelectedTable?.columns?.[0]?.name || undefined,
showSubdirectory: undefined,
subdirectoryId: undefined,
},
});
};
@@ -88,18 +81,6 @@ export default function SubdirectoryFieldConfig({
options: {
...field.options,
showSubdirectory: checked,
subdirectoryId: checked ? field.options?.subdirectoryId : undefined,
},
});
};
const handleSubdirectoryChange = (value: string) => {
const newSubdirectory = value === 'none' ? undefined : subdirectories.find((s) => s.id?.toString() === value || s.childTableId?.toString() === value);
updateField(index, {
options: {
...field.options,
subdirectoryId: newSubdirectory?.id,
childTableId: newSubdirectory?.childTableId,
},
});
};
@@ -178,32 +159,12 @@ export default function SubdirectoryFieldConfig({
</div>
{showSubdirectory && (
<div>
<Label className="text-xs">Подсправочник</Label>
<Select value={selectedSubdirectoryId?.toString() || 'none'} onValueChange={handleSubdirectoryChange}>
<SelectTrigger>
<SelectValue placeholder="Выберите подсправочник" />
</SelectTrigger>
<SelectContent>
<SelectItem value="none">Не выбрано</SelectItem>
{subdirectories.length === 0 && (
<SelectItem value="no-subdirectories" disabled>
Нет привязанных подсправочников
</SelectItem>
)}
{subdirectories.map((sub) => (
<SelectItem key={sub.id} value={sub.id?.toString() || sub.childTableId?.toString() || ''}>
{sub.childTable?.name || `Справочник ${sub.childTableId}`}
</SelectItem>
))}
</SelectContent>
</Select>
{selectedSubdirectory && (
<p className="text-xs text-muted-foreground mt-1">
Подсправочник показывается при выборе привязанных строк родителя.
</p>
)}
</div>
<p className="text-xs text-muted-foreground">
При выборе строки родительского справочника будет показан подсправочник, привязанный к этой строке.
{subdirectories.length > 0
? ` Найдено подсправочников: ${subdirectories.length}.`
: ' Нет привязанных подсправочников.'}
</p>
)}
</div>
)}

View File

@@ -65,7 +65,6 @@ export default function TableFieldWithSubdirectory({
const opts = options && !Array.isArray(options) ? (options as Record<string, any>) : {};
const tableId = opts.tableId as number | undefined;
const showSubdirectory = !!opts.showSubdirectory;
const subdirectoryId = opts.subdirectoryId as number | undefined;
const { data: subdirectoriesData } = useQuery<{ subdirectories: DataTableSubdirectory[] }>({
queryKey: ['/api/directories', tableId, 'subdirectories'],
@@ -77,16 +76,14 @@ export default function TableFieldWithSubdirectory({
staleTime: 60 * 1000,
});
const subdirectory = useMemo(() => {
return subdirectoriesData?.subdirectories?.find((s) => s.id === subdirectoryId);
}, [subdirectoriesData, subdirectoryId]);
const { parentId, childId } = parseTableValue(value);
const isParentLinked = useMemo(() => {
if (!subdirectory || !parentId) return false;
return subdirectory.parentRowIds?.includes(Number(parentId)) ?? false;
}, [subdirectory, parentId]);
const subdirectory = useMemo(() => {
if (!parentId) return undefined;
return subdirectoriesData?.subdirectories?.find((s) =>
s.parentRowIds?.includes(Number(parentId))
);
}, [subdirectoriesData, parentId]);
const handleParentChange = (newParentId: string) => {
onChange(serializeTableValue(newParentId || null, null));
@@ -96,7 +93,7 @@ export default function TableFieldWithSubdirectory({
onChange(serializeTableValue(parentId, newChildId || null));
};
if (!showSubdirectory || !subdirectory || allowMultiple) {
if (!showSubdirectory || allowMultiple) {
const SelectComponent = allowMultiple ? TableFieldMultiSelect : TableFieldSelect;
return (
<SelectComponent
@@ -111,10 +108,9 @@ export default function TableFieldWithSubdirectory({
}
const parentOptions = opts;
const childOptions = {
...opts,
tableId: subdirectory.childTableId,
};
const childOptions = subdirectory
? { ...opts, tableId: subdirectory.childTableId }
: opts;
return (
<div className="space-y-2">
@@ -126,7 +122,7 @@ export default function TableFieldWithSubdirectory({
value={parentId || ''}
onChange={handleParentChange}
/>
{isParentLinked && (
{subdirectory && (
<TableFieldSelect
fieldId={fieldId}
fieldCode={`${fieldCode}_sub`}