@tomino/dynamic-form-semantic-ui
Version:
Semantic UI form renderer based on dynamic form generation
200 lines • 10.1 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const React = tslib_1.__importStar(require("react"));
const mobx_react_1 = require("mobx-react");
const semantic_ui_react_1 = require("semantic-ui-react");
const dynamic_form_1 = require("@tomino/dynamic-form");
const error_view_1 = require("./error_view");
const common_1 = require("../common");
const helpers_1 = require("../helpers");
const context_1 = require("../context");
const wrapper_1 = require("../wrapper");
function createDataset(items, parent) {
let schema = {
type: 'object',
properties: {}
};
for (let column of items) {
schema.properties[column.source] = {
type: column.type || 'string'
};
}
return dynamic_form_1.buildDataSet(schema, common_1.toJS(parent));
}
exports.createDataset = createDataset;
exports.tableAddButton = common_1.css `
margin-top: 12px !important;
`;
function hasControl(template, i) {
return template && template.elements && template.elements.length > i && template.elements[i];
}
const tableProps = [
'attached',
'basic',
'inverted',
'celled',
'collapsing',
'compact',
'padded',
'fixed',
'selectable',
'singleLine',
'sortable',
'stackable',
'striped',
'structured',
'textAlign',
'verticalAlign'
];
const TableComponent = props => {
const [editingRow, editRow] = React.useState(-1);
const context = React.useContext(context_1.Context);
const controlProps = props.formElement.props || {};
const { formElement, owner } = controlProps.onCreate
? helpers_1.simpleHandle(props, controlProps.onCreate, context)
: { formElement: props.formElement, owner: props.owner };
const readOnly = props.readOnly;
const list = controlProps.propSource
? props.dataProps[controlProps.propSource]
: helpers_1.getValue(props, context) || [];
const { items, allowAdd, allowDelete, allowEdit, customView } = formElement.props || {};
const edit = React.useCallback((e) => {
editRow(parseInt(e.currentTarget.getAttribute('data-index')));
}, []);
const source = common_1.prop(props.formElement);
const viewTemplate = formElement.elements && formElement.elements.length > 0 && formElement.elements[0];
const editTemplate = formElement.elements && formElement.elements.length > 1 && formElement.elements[1];
const addTemplate = formElement.elements && formElement.elements.length > 2 && formElement.elements[2];
let filteredItems = (items || []).filter(i => i && i.title && i.type && i.source);
const addDataset = React.useMemo(() => {
return createDataset(filteredItems, owner);
}, [items]);
const addRow = React.useCallback(() => {
const data = common_1.toJS(addDataset);
if (formElement.props.onAdd) {
helpers_1.simpleHandle(props, formElement.props.onAdd, context, { data });
}
else if (data.__item) {
owner.addRow(source, data.__item);
}
else {
owner.addRow(source, data);
}
}, [addDataset, context, formElement.props.onAdd, owner, props, source]);
let rowDataset = editingRow >= 0 ? createDataset(items, list[editingRow]) : null;
const cancelEdit = React.useCallback(() => {
editRow(-1);
}, []);
const editRowHandler = React.useCallback(() => {
const data = common_1.toJS(rowDataset);
if (formElement.props.onSave) {
helpers_1.simpleHandle(props, formElement.props.onSave, context, { data });
}
else if (owner && owner.replaceRow) {
const source = helpers_1.valueSource(props.formElement);
owner.replaceRow(source, editingRow, data);
}
else {
alert('You need to define an on save handler');
}
editRow(-1);
}, [context, editingRow, formElement.props.onSave, owner, props, rowDataset]);
const deleteRow = React.useCallback((e) => {
if (formElement.props.onDelete) {
helpers_1.simpleHandle(props, formElement.props.onDelete, context, {
index: parseInt(e.currentTarget.getAttribute('data-index')),
data: list
});
}
else {
owner.removeRowIndex(source, parseInt(e.currentTarget.getAttribute('data-index')));
}
}, [context, formElement.props.onDelete, list, owner, props, source]);
if (!filteredItems || !filteredItems.length) {
return React.createElement("div", null, "You need to define table columns");
}
let simpleArray = filteredItems.length === 1 && filteredItems[0].source === '__item';
if (!list) {
return React.createElement("div", null, "Collection contains no items ...");
}
return (React.createElement(wrapper_1.DynamicComponent, Object.assign({ control: semantic_ui_react_1.Table, controlProps: tableProps }, props),
React.createElement(semantic_ui_react_1.Table.Header, null,
React.createElement(semantic_ui_react_1.Table.Row, null,
filteredItems.map((m, i) => (React.createElement(semantic_ui_react_1.Table.HeaderCell, { key: m.title + i }, m.title))),
!readOnly && (allowEdit || allowDelete || allowAdd) ? React.createElement(semantic_ui_react_1.Table.HeaderCell, null) : null)),
React.createElement(semantic_ui_react_1.Table.Body, null,
list.map((row, i) => (React.createElement(semantic_ui_react_1.Table.Row, { key: i },
editingRow === i
? filteredItems.map((e, i) => {
if (simpleArray) {
const r = row;
row = {
setValue(_s, value) {
owner.replaceRow(source, i, value);
},
getValue() {
return r;
},
getSchema() {
return owner.getSchema().items;
},
isRequired() {
return false;
}
};
}
else {
row = rowDataset;
}
return (React.createElement(semantic_ui_react_1.Table.Cell, { key: i }, props.catalogue.createComponent({ ...props, owner: row, dataProps: owner }, hasControl(editTemplate, i)
? editTemplate.elements[i]
: {
control: 'Input',
props: { value: { source: e.source } }
}, context)));
})
: filteredItems.map((m, j) => {
const value = m.source === '__item' ? row : row[m.source];
return (React.createElement(semantic_ui_react_1.Table.Cell, { key: m.title + j }, customView && hasControl(viewTemplate, j)
? props.catalogue.createComponent({
...props,
owner: row,
dataProps: owner
}, viewTemplate.elements[j], context)
: value && typeof value == 'object'
? '[object]'
: value));
}),
!readOnly && (allowEdit || allowDelete || allowAdd) ? (React.createElement(semantic_ui_react_1.Table.Cell, { collapsing: true },
allowEdit && editingRow === i && (React.createElement(React.Fragment, null,
React.createElement(semantic_ui_react_1.Button, { icon: "close", color: "orange", "data-index": i, onClick: cancelEdit }),
React.createElement(semantic_ui_react_1.Button, { icon: "check", color: "green", "data-index": i, onClick: editRowHandler }))),
allowEdit && editingRow !== i && (React.createElement(semantic_ui_react_1.Button, { icon: "edit", color: "blue", "data-index": i, onClick: edit })),
allowDelete && editingRow !== i && (React.createElement(semantic_ui_react_1.Button, { icon: "trash", color: "red", "data-index": i, onClick: deleteRow })))) : null))),
!readOnly && allowAdd ? (React.createElement(semantic_ui_react_1.Table.Row, null,
filteredItems.map((m, i) => (React.createElement(semantic_ui_react_1.Table.Cell, { key: m.title + i }, props.catalogue.createComponent({ ...props, owner: addDataset, dataProps: owner }, hasControl(addTemplate, i)
? addTemplate.elements[i]
: {
control: 'Input',
props: {
value: { source: m.source },
placeholder: m.title
}
}, context)))),
React.createElement(semantic_ui_react_1.Table.Cell, null,
React.createElement(semantic_ui_react_1.Button, { icon: "plus", color: "blue", onClick: addRow })))) : null),
React.createElement(error_view_1.ErrorView, { owner: props.owner, source: common_1.prop(formElement), pointing: "left" })));
};
exports.TableView = {
Component: mobx_react_1.observer(TableComponent),
toString: (_owner, props, context) => {
const tableList = helpers_1.getValue(props, context);
return tableList
.map((_, i) => `[${i + 1}] ${props.formElement.elements
.map(e => `${helpers_1.getPropValue(props, e, context, 'label')}: ${helpers_1.getPropValue(props, e, context)}`)
.join('\n ')}`)
.join('\n\n');
}
};
//# sourceMappingURL=table_view.js.map