UNPKG

@tomino/dynamic-form-semantic-ui

Version:

Semantic UI form renderer based on dynamic form generation

162 lines 9.43 kB
import * as React from 'react'; import * as propertyHandlers from './property_panel.handlers'; import { observer } from 'mobx-react'; import { config } from '@tomino/dynamic-form'; import { groupByArray, debounce } from '@tomino/toolbelt'; import { pointer, names, prop } from '../../common'; import { renderElements } from '../../properties/control_factory_helpers'; import { Help } from '../../properties/help_view'; import { EditorContext } from '../editor_context'; import { Message, Button, Icon } from 'semantic-ui-react'; import { pad12, paneContent, margin12, searchableSidePane } from '../editor_styles'; import { schemaPanel, schemaHandlers } from '../schema/schema_panel'; import { styledPropertyView } from './property_styles'; import { propertyPanel } from './property_panel'; import { findSchema, createPath } from '../editor_common'; import { DeleteSchema } from '../dataset/dataset_modals'; import { getValue } from '../../helpers'; import { Input } from 'semantic-ui-react'; export const RenderProps = ({ props, activeElement, groupName, handlers, filter }) => { let i = 0; const groups = groupByArray(props, x => x.group || (x.props.display === 'group' ? i++ : '')); const editorState = React.useContext(EditorContext); return (React.createElement(React.Fragment, null, groups.map((g, i) => (React.createElement(React.Fragment, { key: g.key + i }, renderElements(editorState, g.key && (!g.values[0].props || g.values[0].props.display !== 'group') ? [ { control: 'Group', props: { text: g.key || groupName }, elements: g.values } ] : g.values, activeElement.props, handlers, null, editorState, activeElement.uid, filter)))))); }; function buildElementBreadcrumbs(context, props, activeElement) { let breadcrumbs; if (activeElement) { let label = getValue(props, context, 'label'); breadcrumbs = [ React.createElement("span", { key: "last", style: { fontWeight: 'normal' } }, activeElement.control, label && ` - ${label}`) ]; breadcrumbs.push(React.createElement(Icon, { key: "lastIcon", name: "chevron right" })); let parent = activeElement.parent; let index = 0; while (parent != null && parent !== context.form) { let current = parent; if (parent.control) { if (breadcrumbs.length > 5) { breadcrumbs.push('...'); return breadcrumbs; } breadcrumbs.push(React.createElement("span", { key: index, className: pointer, onClick: () => context.project.state.setElement(current, context.schema) }, parent.control)); breadcrumbs.push(React.createElement(Icon, { key: 'Icon' + index++, name: "chevron right" })); } parent = parent.parent; } breadcrumbs.push(React.createElement("span", { key: "first" }, "Element")); } return breadcrumbs; } function buildSchemaBreadcrumbs(activeElement, state) { let breadcrumbs; if (activeElement) { breadcrumbs = [ React.createElement("span", { key: "last", style: { fontWeight: 'normal' } }, activeElement.title) ]; breadcrumbs.push(React.createElement(Icon, { key: "lastIcon", name: "chevron right" })); let parent = activeElement.parent; let index = 0; while (parent != null && parent !== state.schema) { let current = parent; breadcrumbs.push(React.createElement("span", { key: index, className: pointer, onClick: () => state.project.state.setSchema(current, current.title) }, current.title)); breadcrumbs.push(React.createElement(Icon, { key: 'Icon' + index++, name: "chevron right" })); parent = parent.parent; } breadcrumbs.push(React.createElement("span", { key: "first" }, "Schema")); } return breadcrumbs; } export const PropertyEditor = observer(() => { const context = React.useContext(EditorContext); const [filter, setFilter] = React.useState(''); const [searchProperty, setSearchProperty] = React.useState(''); const debouncedSet = React.useMemo(() => debounce(setSearchProperty, 400), []); const handleSearch = React.useCallback((_, props) => { setFilter(props.value); debouncedSet(props.value); }, [debouncedSet]); const { selectedElement, selectedSchema } = context.state; context.state.selectedSchemaName; const handlers = React.useMemo(() => { let result = propertyHandlers; if (context.editorCatalogue) { for (let key of Object.keys(context.editorCatalogue.components)) { const component = context.editorCatalogue.components[key]; if (component.handlers) { result = { ...result, ...component.handlers }; } } } return result; }, [context.editorCatalogue]); const activeElement = selectedElement && selectedElement.control !== 'EditorCell' && selectedElement.control !== '' && selectedElement.control !== null ? selectedElement : null; let activeSchema = prop(activeElement) ? findSchema(activeElement, context.project.schema, context) : selectedSchema; const editorElement = activeElement && context.editorCatalogue && context.editorCatalogue.components[activeElement.control]; const parentEditorElement = activeElement && activeElement.parent && context.editorCatalogue && context.editorCatalogue.components[activeElement.parent.control]; const editorProps = React.useMemo(() => editorElement ? context .cachedProps(editorElement) .filter(p => p.group === 'Editor') .concat(context.editorProps) : [], [context, editorElement]); const componentProps = React.useMemo(() => editorElement ? context.cachedProps(editorElement).filter(p => p.group !== 'Editor') : [], [context, editorElement]); const childProps = parentEditorElement ? context.cachedChildProps(parentEditorElement) : []; if (activeElement && !editorElement) { throw new Error(`Control '${activeElement.control}' does not exists in the catalogue`); } let props = { catalogue: context.editorCatalogue, owner: activeElement, handlers, formElement: activeElement }; let breadcrumbs = activeElement ? (buildElementBreadcrumbs(context, props, activeElement).reverse()) : activeSchema ? (buildSchemaBreadcrumbs(activeSchema, context).reverse()) : (React.createElement("span", null, "Properties")); return (React.createElement("div", { className: names(paneContent(context.theme), styledPropertyView(context.theme)) }, React.createElement("div", { className: "paneHeader" }, React.createElement("div", { className: "text breadcrumbs" }, React.createElement("div", null, breadcrumbs))), React.createElement("div", { className: "property-table-row" }, React.createElement(Input, { transparent: true, inverted: true, icon: "search", iconPosition: "left", size: "mini", fluid: true, placeholder: "Filter properties ...", className: "searchInput", value: filter, onChange: handleSearch })), React.createElement("div", { className: names(searchableSidePane) }, activeElement && (React.createElement(React.Fragment, null, !editorElement.provider && (React.createElement(RenderProps, { activeElement: activeElement, props: propertyPanel, groupName: "General", handlers: handlers, filter: searchProperty })), editorElement.props && (React.createElement(RenderProps, { activeElement: activeElement, props: componentProps, groupName: "Control", handlers: handlers, filter: searchProperty })), parentEditorElement && parentEditorElement.childProps && (React.createElement(RenderProps, { activeElement: activeElement, props: childProps, groupName: "Layout", handlers: handlers, filter: searchProperty })), React.createElement(RenderProps, { activeElement: activeElement, props: editorProps, groupName: "Editor", handlers: handlers, filter: searchProperty }))), activeElement && !activeSchema && prop(activeElement) && (React.createElement(Message, { className: margin12, error: true, content: `Schema not found at: ${createPath(activeElement, context).join(' > ')}` })), activeSchema && renderElements(context, schemaPanel, activeSchema, schemaHandlers, null, context, activeSchema.title, searchProperty), (activeElement || activeSchema) && React.createElement(Help, { owner: activeElement }), React.createElement("div", { className: pad12 }, activeElement && activeElement.parent.parent && (!activeElement.props || !activeElement.props.locked) && (React.createElement(Button, { onClick: context.project.state.deleteActiveElement, content: config.i18n `Delete`, icon: "trash" })), selectedSchema && React.createElement(DeleteSchema, { schema: selectedSchema }))))); }); PropertyEditor.displayName = 'PropertyEditor'; //# sourceMappingURL=property_view.js.map