dynamic-modal
Version:
The dynamic-modal is a solution of creation different modals into project using a json configuration file
106 lines (105 loc) • 6.29 kB
JavaScript
'use client';
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const jsx_runtime_1 = require("react/jsx-runtime");
const react_1 = require("react");
const use_render_if_1 = __importDefault(require("../../hooks/use-render-if"));
const component_state_1 = require("../../context/component/component-state");
const use_live_data_1 = __importDefault(require("../../hooks/use-live-data"));
const react_hook_form_1 = require("react-hook-form");
const MakeTable = ({ element, watch, control, setValue }) => {
const [liveSearching, setLiveSearching] = (0, react_1.useState)(false);
const [selected, setSelected] = (0, react_1.useState)('');
const [rowSelected, setRowSelected] = (0, react_1.useState)(new Map());
const { Select } = (0, react_1.useContext)(component_state_1.ComponentStateContext);
const { Button } = (0, react_1.useContext)(component_state_1.ComponentStateContext);
const { selectTitleName, selectValueName, selectActionName, selectPlaceholder, renderIf, columns, name: elementName, data, liveData: elementLiveData, style, buttonStyle } = element;
const { checkLiveData, liveData, setLiveData } = (0, use_live_data_1.default)({
elementLiveData,
});
const { checkRender, render, setRender } = (0, use_render_if_1.default)({
elementRenderIf: renderIf,
});
const addToTable = (0, react_1.useCallback)((selected) => {
if (selected === '')
return;
const elementSelected = data.find((e) => e[selectValueName] === selected);
if (elementSelected) {
const currentElements = new Map(rowSelected.entries());
currentElements.set(selected, elementSelected);
setValue(elementName, Array.from(currentElements.values()));
setRowSelected(currentElements);
setSelected('');
}
}, [data, rowSelected, setRowSelected, setSelected]);
const tableButtonAction = (0, react_1.useCallback)((row, isDeleteAction, action) => {
const id = row[selectValueName];
if (isDeleteAction) {
const currentElements = new Map(rowSelected.entries());
currentElements.delete(id);
setRowSelected(currentElements);
return;
}
if (action)
action(row);
}, [rowSelected, setRowSelected]);
(0, react_1.useEffect)(() => {
const { unsubscribe } = watch((formData, { name, type }) => {
if (!name)
return;
if (renderIf) {
checkRender(formData, { name, type }).then((renderStatus) => {
if (renderStatus === undefined || renderStatus === null)
return;
if (render !== renderStatus) {
setRender(!!renderStatus);
}
});
}
if (elementLiveData) {
setLiveSearching(true);
checkLiveData(formData, { name, type })
.then((options) => {
if (options === undefined || options === null)
return;
setLiveData(options);
})
.finally(() => {
setLiveSearching(false);
});
}
});
return () => unsubscribe();
}, [watch, render, liveData]);
if (!render)
return null;
const selectOptions = (0, react_1.useMemo)(() => {
return data.map((e) => {
const id = e[selectValueName];
const name = e[selectTitleName];
return {
id,
name
};
});
}, [data]);
const keyColumns = (0, react_1.useMemo)(() => {
return columns.map((e) => e.title);
}, [columns]);
const tableData = (0, react_1.useMemo)(() => {
return Array.from(rowSelected.values());
}, [rowSelected]);
return ((0, jsx_runtime_1.jsxs)("div", { className: 'flex flex-col gap-2', style: { ...style }, children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex w-full justify-between gap-4", children: [(0, jsx_runtime_1.jsx)(react_hook_form_1.Controller, { control: control, name: elementName, defaultValue: [], render: ({ field: { value } }) => ((0, jsx_runtime_1.jsx)("input", { type: 'hidden', value: value })) }), (0, jsx_runtime_1.jsx)(Select, { name: 'table-select-field', placeholder: selectPlaceholder, isSearch: true, value: selected, invalid: false, options: liveData || selectOptions, liveSearching: liveSearching, onChange: (selected) => {
setSelected(selected);
} }), (0, jsx_runtime_1.jsx)(Button, { style: buttonStyle, text: selectActionName, onClick: () => addToTable(selected) })] }), (0, jsx_runtime_1.jsxs)("table", { className: "text-[11px] w-full shadow-md sm:rounded-lg", children: [(0, jsx_runtime_1.jsx)("thead", { className: "sticky top-0 text-gray-700 bg-gray-50 text-center z-10", children: (0, jsx_runtime_1.jsx)("tr", { children: keyColumns.map((title) => ((0, jsx_runtime_1.jsx)("th", { scope: 'col', className: 'px-6 py-3', children: title }))) }) }), (0, jsx_runtime_1.jsx)("tbody", { children: tableData.map((row, index) => {
return ((0, jsx_runtime_1.jsx)("tr", { className: "bg-white border-b hover:bg-gray-50 text-center", children: columns.map(({ Icon, isButton, action, isDeleteAction, style, ...column }) => {
if (!isButton)
return ((0, jsx_runtime_1.jsx)("td", { className: 'px-6 py-4', style: style, children: row[column.key] ?? '' }));
return ((0, jsx_runtime_1.jsx)("td", { children: (0, jsx_runtime_1.jsx)("button", { className: 'p-2 rounded-md text-lg', onClick: () => { tableButtonAction(row, isDeleteAction, action); }, style: style, children: Icon && (0, jsx_runtime_1.jsx)(Icon, {}) }) }));
}) }, `row-${row[selectValueName]}-i-${index}`));
}) })] })] }));
};
exports.default = MakeTable;