import { KNOWN_CONFIG_TABLE_KEYS, OPERATOR_LABELS, TABLE_SERVER_CONFIG } from "../../shared/constants.js"; import { boolLabel, fmtDate, listPreview, normalizeReferenceMeta, roleLabel, statusKindLabel, statusLabel } from "../../shared/utils.js"; export function ConfigSection(props) { const { token, tables, dictionaries, configActiveKey, activeConfigTableState, activeConfigMeta, genericConfigHeaders, canCreateInConfig, canUpdateInConfig, canDeleteInConfig, statusDesignerTopicCode, statusDesignerCards, getTableLabel, getFieldDef, getFilterValuePreview, resolveReferenceLabel, resolveTableConfig, getStatus, loadCurrentConfigTable, openCreateRecordModal, openFilterModal, removeFilterChip, openFilterEditModal, toggleTableSort, openEditRecordModal, deleteRecord, loadStatusDesignerTopic, openCreateStatusTransitionForTopic, loadPrevPage, loadNextPage, loadAllRows, FilterToolbarComponent, DataTableComponent, TablePagerComponent, StatusLineComponent, IconButtonComponent, UserAvatarComponent, } = props; const FilterToolbar = FilterToolbarComponent; const DataTable = DataTableComponent; const TablePager = TablePagerComponent; const StatusLine = StatusLineComponent; const IconButton = IconButtonComponent; const UserAvatar = UserAvatarComponent; return ( <>

Справочники

{configActiveKey ? getTableLabel(configActiveKey) : "Справочник не выбран"}

{configActiveKey ? getTableLabel(configActiveKey) : "Справочник не выбран"}

{canCreateInConfig && configActiveKey ? ( ) : null}
openFilterModal(configActiveKey)} onRemove={(index) => removeFilterChip(configActiveKey, index)} onEdit={(index) => openFilterEditModal(configActiveKey, index)} getChipLabel={(clause) => { const fieldDef = getFieldDef(configActiveKey, clause.field); return ( (fieldDef ? fieldDef.label : clause.field) + " " + OPERATOR_LABELS[clause.op] + " " + getFilterValuePreview(configActiveKey, clause) ); }} /> {configActiveKey === "topics" ? ( toggleTableSort("topics", field)} sortClause={(tables.topics.sort && tables.topics.sort[0]) || TABLE_SERVER_CONFIG.topics.sort[0]} renderRow={(row) => ( {row.code || "-"} {row.name || "-"} {boolLabel(row.enabled)} {String(row.sort_order ?? 0)}
openEditRecordModal("topics", row)} /> deleteRecord("topics", row.id)} tone="danger" />
)} /> ) : null} {configActiveKey === "quotes" ? ( toggleTableSort("quotes", field)} sortClause={(tables.quotes.sort && tables.quotes.sort[0]) || TABLE_SERVER_CONFIG.quotes.sort[0]} renderRow={(row) => ( {row.author || "-"} {row.text || "-"} {row.source || "-"} {boolLabel(row.is_active)} {String(row.sort_order ?? 0)} {fmtDate(row.created_at)}
openEditRecordModal("quotes", row)} /> deleteRecord("quotes", row.id)} tone="danger" />
)} /> ) : null} {configActiveKey === "statuses" ? ( toggleTableSort("statuses", field)} sortClause={(tables.statuses.sort && tables.statuses.sort[0]) || TABLE_SERVER_CONFIG.statuses.sort[0]} renderRow={(row) => ( {row.code || "-"} {row.name || "-"} {resolveReferenceLabel({ table: "status_groups", value_field: "id", label_field: "name" }, row.status_group_id)} {statusKindLabel(row.kind)} {boolLabel(row.enabled)} {String(row.sort_order ?? 0)} {boolLabel(row.is_terminal)} {row.invoice_template || "-"}
openEditRecordModal("statuses", row)} /> deleteRecord("statuses", row.id)} tone="danger" />
)} /> ) : null} {configActiveKey === "formFields" ? ( toggleTableSort("formFields", field)} sortClause={(tables.formFields.sort && tables.formFields.sort[0]) || TABLE_SERVER_CONFIG.formFields.sort[0]} renderRow={(row) => ( {row.key || "-"} {row.label || "-"} {row.type || "-"} {boolLabel(row.required)} {boolLabel(row.enabled)} {String(row.sort_order ?? 0)}
openEditRecordModal("formFields", row)} /> deleteRecord("formFields", row.id)} tone="danger" />
)} /> ) : null} {configActiveKey === "topicRequiredFields" ? ( toggleTableSort("topicRequiredFields", field)} sortClause={ (tables.topicRequiredFields.sort && tables.topicRequiredFields.sort[0]) || TABLE_SERVER_CONFIG.topicRequiredFields.sort[0] } renderRow={(row) => ( {row.topic_code || "-"} {row.field_key || "-"} {boolLabel(row.required)} {boolLabel(row.enabled)} {String(row.sort_order ?? 0)} {fmtDate(row.created_at)}
openEditRecordModal("topicRequiredFields", row)} /> deleteRecord("topicRequiredFields", row.id)} tone="danger" />
)} /> ) : null} {configActiveKey === "topicDataTemplates" ? ( toggleTableSort("topicDataTemplates", field)} sortClause={ (tables.topicDataTemplates.sort && tables.topicDataTemplates.sort[0]) || TABLE_SERVER_CONFIG.topicDataTemplates.sort[0] } renderRow={(row) => ( {row.topic_code || "-"} {row.key || "-"} {row.label || "-"} {row.description || "-"} {boolLabel(row.required)} {boolLabel(row.enabled)} {String(row.sort_order ?? 0)} {fmtDate(row.created_at)}
openEditRecordModal("topicDataTemplates", row)} /> deleteRecord("topicDataTemplates", row.id)} tone="danger" />
)} /> ) : null} {configActiveKey === "statusTransitions" ? ( <>

Конструктор маршрута статусов

Ветвления, возвраты, SLA и требования к данным/файлам на каждом переходе.

{statusDesignerCards.length ? (
{statusDesignerCards.map((card) => (
{card.name} {card.code}
{card.isTerminal ? Терминальный : null}
{card.outgoing.length ? (
    {card.outgoing.map((link) => (
  • ))}
) : (

Нет исходящих переходов

)}
))}
) : (

Для выбранной темы переходы пока не настроены.

)}
toggleTableSort("statusTransitions", field)} sortClause={ (tables.statusTransitions.sort && tables.statusTransitions.sort[0]) || TABLE_SERVER_CONFIG.statusTransitions.sort[0] } renderRow={(row) => ( {row.topic_code || "-"} {statusLabel(row.from_status)} {statusLabel(row.to_status)} {row.sla_hours == null ? "-" : String(row.sla_hours)} {listPreview(row.required_data_keys, "-")} {listPreview(row.required_mime_types, "-")} {boolLabel(row.enabled)} {String(row.sort_order ?? 0)}
openEditRecordModal("statusTransitions", row)} /> deleteRecord("statusTransitions", row.id)} tone="danger" />
)} /> ) : null} {configActiveKey === "users" ? ( toggleTableSort("users", field)} sortClause={(tables.users.sort && tables.users.sort[0]) || TABLE_SERVER_CONFIG.users.sort[0]} renderRow={(row) => (
{row.name || "-"}
{row.email || "-"} {roleLabel(row.role)} {resolveReferenceLabel({ table: "topics", value_field: "code", label_field: "name" }, row.primary_topic_code)} {row.default_rate == null ? "-" : String(row.default_rate)} {row.salary_percent == null ? "-" : String(row.salary_percent)} {boolLabel(row.is_active)} {row.responsible || "-"} {fmtDate(row.created_at)}
openEditRecordModal("users", row)} /> deleteRecord("users", row.id)} tone="danger" />
)} /> ) : null} {configActiveKey === "userTopics" ? ( toggleTableSort("userTopics", field)} sortClause={(tables.userTopics.sort && tables.userTopics.sort[0]) || TABLE_SERVER_CONFIG.userTopics.sort[0]} renderRow={(row) => { const lawyer = (dictionaries.users || []).find((item) => String(item.id) === String(row.admin_user_id)); const lawyerLabel = lawyer ? (lawyer.name || lawyer.email || row.admin_user_id) : row.admin_user_id || "-"; return ( {lawyerLabel} {row.topic_code || "-"} {row.responsible || "-"} {fmtDate(row.created_at)}
openEditRecordModal("userTopics", row)} /> deleteRecord("userTopics", row.id)} tone="danger" />
); }} /> ) : null} {configActiveKey && !KNOWN_CONFIG_TABLE_KEYS.has(configActiveKey) ? ( toggleTableSort(configActiveKey, field)} sortClause={ (activeConfigTableState.sort && activeConfigTableState.sort[0]) || ((resolveTableConfig(configActiveKey)?.sort || [])[0]) } renderRow={(row) => ( {(activeConfigMeta?.columns || []).map((column) => { const key = String(column.name || ""); const value = row[key]; if (column.kind === "boolean") return {boolLabel(Boolean(value))}; if (column.kind === "date" || column.kind === "datetime") return {fmtDate(value)}; if (column.kind === "json") return {value == null ? "-" : JSON.stringify(value)}; const reference = normalizeReferenceMeta(column.reference); if (reference) return {resolveReferenceLabel(reference, value)}; return {value == null || value === "" ? "-" : String(value)}; })} {canUpdateInConfig || canDeleteInConfig ? (
{canUpdateInConfig ? ( openEditRecordModal(configActiveKey, row)} /> ) : null} {canDeleteInConfig ? ( deleteRecord(configActiveKey, row.id)} tone="danger" /> ) : null}
) : null} )} /> ) : null} loadPrevPage(configActiveKey)} onNext={() => loadNextPage(configActiveKey)} onLoadAll={() => loadAllRows(configActiveKey)} />
); } export default ConfigSection;