UNPKG

@tomino/dynamic-form-semantic-ui

Version:

Semantic UI form renderer based on dynamic form generation

151 lines 7.55 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const tslib_1 = require("tslib"); const React = tslib_1.__importStar(require("react")); const styles = tslib_1.__importStar(require("./properties_common")); const properties_common_1 = require("./properties_common"); const classnames_1 = tslib_1.__importDefault(require("classnames")); const mobx_react_1 = require("mobx-react"); const common_1 = require("../common"); const mobx_1 = require("mobx"); const dynamic_form_1 = require("@tomino/dynamic-form"); const group_1 = require("./group"); const semantic_ui_react_1 = require("semantic-ui-react"); const editor_context_1 = require("../editor/editor_context"); const helpers_1 = require("../helpers"); function renderControl(options, value, type, placeholder, error, onValueChange, mappingKey, className = '') { return options ? (React.createElement(semantic_ui_react_1.Dropdown, { value: value, "data-value": value, "data-key": mappingKey, search: true, selection: true, fluid: true, name: "type", onChange: onValueChange, className: classnames_1.default('property-search', className, common_1.select, { invalid: error }), options: options })) : (React.createElement("input", { type: type, placeholder: placeholder, onChange: onValueChange, className: classnames_1.default({ invalid: error }), value: value, "data-key": mappingKey, "data-value": value })); } const MapRow = (props) => { const { mappingKey, map, owner, formElement, handlers, source, controlMap } = props; const [currentKey, setKey] = React.useState(mappingKey); const [value, setValue] = React.useState(map.get(mappingKey)); const [error, setError] = React.useState(''); const context = React.useContext(editor_context_1.EditorContext); let keyOptions = helpers_1.getValue({ formElement, owner, handlers, catalogue: null }, context, 'options'); let valueOptions; const editorState = React.useContext(editor_context_1.EditorContext); const editorItem = editorState.editorCatalogue.components[owner.getValue('control')]; let schema; if (editorItem && editorItem.props) { schema = new dynamic_form_1.Schema(editorItem.props); keyOptions = Object.getOwnPropertyNames(schema.properties).map(key => ({ label: schema.properties[key].title, value: key, description: schema.properties[key].description })); if (currentKey) { valueOptions = editorItem.props[currentKey].schema.$enum; if (valueOptions) { valueOptions.forEach(o => (o.key = mappingKey)); } } } const selected = currentKey && keyOptions && keyOptions.find(o => o.value === currentKey); const onKeyChange = mobx_1.action((e, control) => { const originalKey = e.currentTarget.getAttribute('data-key') || ''; const newKey = control.value; const value = e.currentTarget.getAttribute('data-value'); setKey(newKey); if (map.has(newKey)) { owner.setError(source, 'Key exists: ' + newKey); setError(originalKey); return; } owner.mapRemove(source, originalKey); owner.setMapValue(source, newKey, value == null ? '' : value); let mapping = controlMap.find(o => o.key === originalKey); if (mapping) { mapping.key = newKey; } else { controlMap.push({ key: newKey }); } }); const onValueChange = (e) => { const key = e.currentTarget.getAttribute('data-key'); let value = e.currentTarget.value; setValue(value); const source = common_1.prop(formElement); if (schema) { value = schema.properties[key].tryParse(value); owner.setMapValue(source, e.key, value); const mapSource = owner.getValue(source); const mapObject = JSON.parse(JSON.stringify(mapSource)); let result = schema.validate(mapObject); if (result && result.length) { let errorKey = result[0].dataPath.replace(/\//g, ''); owner.setError(source, `${errorKey}: ${result[0].message}`); setError(errorKey); } else { owner.setError(source, ''); setError(''); } } else { owner.setMapValue(source, key, value); } }; const deleteValue = (e) => { const originalKey = e.currentTarget.getAttribute('data-key'); owner.mapRemove(source, originalKey); }; return (React.createElement("div", { className: classnames_1.default(properties_common_1.styledTableRow(editorState.theme), { invalid: error }), onClick: e => { if (selected && selected.description) { owner.setValue('_help', selected.description); e.preventDefault(); e.stopPropagation(); } } }, React.createElement("div", { className: styles.tableRowFull }, renderControl(keyOptions, currentKey, 'text', 'Key', error === currentKey, onKeyChange, mappingKey, 'first gray')), React.createElement("div", { className: styles.tableRowFull }, renderControl(valueOptions, value, (selected && selected.type) || 'text', 'Value', error === currentKey, onValueChange, mappingKey, 'second')), React.createElement("div", { className: styles.tableRowAuto }, React.createElement("button", { className: properties_common_1.addButton(editorState.theme), onClick: deleteValue, "data-key": mappingKey }, "x")))); }; let Map = class Map extends React.Component { constructor() { super(...arguments); this.onClear = () => { this.props.owner.setValue(common_1.prop(this.props.formElement), ''); }; this.addRow = () => { const source = common_1.prop(this.props.formElement); const current = this.props.owner.getValue(source); if (!current || typeof current !== 'object') { this.props.owner.setValue(source, {}); } this.props.owner.setMapValue(source, '', ''); }; } render() { const { formElement, owner, handlers } = this.props; const source = common_1.prop(formElement); const controlMap = []; const map = owner.getValue(source); const lines = []; if (map && typeof map === 'object') { map.forEach((_value, key) => { if (controlMap.every(c => c.key !== key)) { controlMap.push({ key }); } }); for (let i = 0; i < controlMap.length; i++) { const mapping = controlMap[i]; lines.push(React.createElement(MapRow, { key: i, mappingKey: mapping.key, map: map, owner: owner, formElement: formElement, source: source, handlers: handlers, controlMap: controlMap })); } } return (React.createElement(group_1.PropertyHeader, { label: formElement.props && formElement.props.text, buttons: React.createElement("button", { className: "headerButton", onClick: this.addRow }, "+") }, React.createElement("div", { className: properties_common_1.celled(this.context.theme) }, lines.length > 0 ? lines : undefined))); } }; Map.contextType = editor_context_1.EditorContext; Map = tslib_1.__decorate([ mobx_react_1.observer ], Map); exports.Map = Map; //# sourceMappingURL=map.js.map