85 lines
3.1 KiB
TypeScript
85 lines
3.1 KiB
TypeScript
import { textDefinition } from '@/component/BasicElements'
|
|
import { numberDefinition } from '@/component/BasicElements/NumberElement'
|
|
import { selectDefinition } from '@/component/BasicElements/SelectElement'
|
|
import { verificationConditionsElementDefinition as verificationConditionsDefinition } from '@/component/VerificationConditionsElement/definition'
|
|
import { buttonGroupDefinition } from '@/entitiy/element/model/implementations/ButtonGroup'
|
|
import { dateDefinition } from '@/entitiy/element/model/implementations/DateElement'
|
|
import { standardsDefinition } from '@/entitiy/element/model/implementations/StandardsElement/definition'
|
|
import { CellTarget } from '@/type/template'
|
|
import { ReactNode } from 'react'
|
|
|
|
export interface ElementDefinition<Config = any, Value = any> {
|
|
type: ElementType
|
|
label: string
|
|
icon: ReactNode
|
|
|
|
/* React-компоненты */
|
|
Editor: React.FC<{ config: Config; onChange(c: Config): void }>
|
|
Preview: React.FC<{ config: Config }>
|
|
Render: React.FC<{ config: Config; value: Value; onChange?(v: Value): void }>
|
|
|
|
/* бизнес-логика */
|
|
defaultConfig: Config
|
|
getInitialValue?(config: Config): Value // получение начальных значений из конфигурации
|
|
mapToCells(config: Config): CellTarget[] // куда пишем данные (для отображения)
|
|
mapToCellValues(
|
|
config: Config,
|
|
value: Value
|
|
): Array<{ target: CellTarget; value: any }> // готовые пары ячейка-значение для записи
|
|
|
|
/* мета */
|
|
version: number
|
|
}
|
|
|
|
export const elementRegistry: Record<ElementType, ElementDefinition> = {} as any
|
|
|
|
// Функция для регистрации элемента
|
|
export function registerElement<T extends ElementType>(
|
|
type: T,
|
|
definition: ElementDefinition
|
|
) {
|
|
elementRegistry[type] = definition
|
|
}
|
|
|
|
// Получить все доступные типы элементов
|
|
export function getAvailableElementTypes(): Array<{
|
|
type: ElementType
|
|
label: string
|
|
icon: ReactNode
|
|
}> {
|
|
return Object.values(elementRegistry).map(({ type, label, icon }) => ({
|
|
type,
|
|
label,
|
|
icon,
|
|
}))
|
|
}
|
|
|
|
// Получить определение элемента по типу
|
|
export function getElementDefinition(
|
|
type: ElementType
|
|
): ElementDefinition | undefined {
|
|
return elementRegistry[type]
|
|
}
|
|
|
|
export const elementDefinitions = {
|
|
text: textDefinition,
|
|
select: selectDefinition,
|
|
number: numberDefinition,
|
|
date: dateDefinition,
|
|
standards: standardsDefinition,
|
|
verification_conditions: verificationConditionsDefinition,
|
|
button_group: buttonGroupDefinition,
|
|
} as const
|
|
|
|
export type ElementType = keyof typeof elementDefinitions
|
|
|
|
export function initializeElementRegistry() {
|
|
registerElement('text', textDefinition)
|
|
registerElement('select', selectDefinition)
|
|
registerElement('number', numberDefinition)
|
|
registerElement('date', dateDefinition)
|
|
registerElement('button_group', buttonGroupDefinition)
|
|
registerElement('standards', standardsDefinition)
|
|
registerElement('verification_conditions', verificationConditionsDefinition)
|
|
}
|