@tomino/dynamic-form-semantic-ui
Version:
Semantic UI form renderer based on dynamic form generation
162 lines • 9.43 kB
JavaScript
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