dynamic-modal 1.1.18 → 1.1.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/input-upload/input-upload.js +1 -1
- package/dist/components/make-table/make-table.d.ts +4 -0
- package/dist/components/make-table/make-table.js +146 -0
- package/dist/interfaces/make-button.d.ts +2 -1
- package/dist/interfaces/make-table.d.ts +26 -0
- package/dist/interfaces/make-table.js +2 -0
- package/dist/interfaces/modal.d.ts +2 -1
- package/dist/modal.js +2 -1
- package/package.json +1 -1
- package/src/components/make-table/make-table.tsx +201 -0
- package/src/interfaces/component-state.ts +0 -1
- package/src/interfaces/make-button.ts +2 -1
- package/src/interfaces/make-table.ts +29 -0
- package/src/interfaces/modal.ts +3 -1
- package/src/modal.tsx +8 -0
|
@@ -43,7 +43,7 @@ const InputUpload = ({ onChange, readAsArrayBuffer, read, helpText, label, ...pr
|
|
|
43
43
|
};
|
|
44
44
|
return (react_1.default.createElement("div", { className: "flex flex-col w-full gap-1 text-center" },
|
|
45
45
|
label && (react_1.default.createElement("label", { className: "block mb-2 text-sm font-medium text-gray-900 dark:text-white", htmlFor: `file-input-${props.id}` }, label)),
|
|
46
|
-
react_1.default.createElement("input", { className: "file:transition-all file:delay-150 block w-full text-sm text-slate-500\n file:mr-4 file:py-2 file:px-4 file:rounded-md\n file:border-0 file:text-sm file:font-semibold\n file:bg-gray-100 file:text-blue-600\n hover:file:bg-blue-700 hover:file:text-white cursor-pointer disabled:cursor-not-allowed", "aria-describedby": `file-input-${props.id}-help`, id: `file-input-${props.id}`, type: "file", onChange: onChangeHandler, ...props }),
|
|
46
|
+
react_1.default.createElement("input", { className: "file:transition-all file:delay-150 block w-full text-sm text-slate-500\r\n file:mr-4 file:py-2 file:px-4 file:rounded-md\r\n file:border-0 file:text-sm file:font-semibold\r\n file:bg-gray-100 file:text-blue-600\r\n hover:file:bg-blue-700 hover:file:text-white cursor-pointer disabled:cursor-not-allowed", "aria-describedby": `file-input-${props.id}-help`, id: `file-input-${props.id}`, type: "file", onChange: onChangeHandler, ...props }),
|
|
47
47
|
react_1.default.createElement("p", { className: "mt-1 text-sm text-gray-500 dark:text-gray-300 text-start", id: `file-input-${props.id}-help` }, helpText?.toUpperCase())));
|
|
48
48
|
};
|
|
49
49
|
exports.default = InputUpload;
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
'use client';
|
|
3
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
4
|
+
if (k2 === undefined) k2 = k;
|
|
5
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
6
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
7
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
8
|
+
}
|
|
9
|
+
Object.defineProperty(o, k2, desc);
|
|
10
|
+
}) : (function(o, m, k, k2) {
|
|
11
|
+
if (k2 === undefined) k2 = k;
|
|
12
|
+
o[k2] = m[k];
|
|
13
|
+
}));
|
|
14
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
15
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
16
|
+
}) : function(o, v) {
|
|
17
|
+
o["default"] = v;
|
|
18
|
+
});
|
|
19
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
20
|
+
var ownKeys = function(o) {
|
|
21
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
22
|
+
var ar = [];
|
|
23
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
24
|
+
return ar;
|
|
25
|
+
};
|
|
26
|
+
return ownKeys(o);
|
|
27
|
+
};
|
|
28
|
+
return function (mod) {
|
|
29
|
+
if (mod && mod.__esModule) return mod;
|
|
30
|
+
var result = {};
|
|
31
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
32
|
+
__setModuleDefault(result, mod);
|
|
33
|
+
return result;
|
|
34
|
+
};
|
|
35
|
+
})();
|
|
36
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
37
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
38
|
+
};
|
|
39
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
40
|
+
const react_1 = __importStar(require("react"));
|
|
41
|
+
const use_render_if_1 = __importDefault(require("../../hooks/use-render-if"));
|
|
42
|
+
const component_state_1 = require("../../context/component/component-state");
|
|
43
|
+
const use_live_data_1 = __importDefault(require("../../hooks/use-live-data"));
|
|
44
|
+
const react_hook_form_1 = require("react-hook-form");
|
|
45
|
+
const MakeTable = ({ element, watch, control, setValue }) => {
|
|
46
|
+
const [liveSearching, setLiveSearching] = (0, react_1.useState)(false);
|
|
47
|
+
const [selected, setSelected] = (0, react_1.useState)('');
|
|
48
|
+
const [rowSelected, setRowSelected] = (0, react_1.useState)(new Map());
|
|
49
|
+
const { Select } = (0, react_1.useContext)(component_state_1.ComponentStateContext);
|
|
50
|
+
const { Button } = (0, react_1.useContext)(component_state_1.ComponentStateContext);
|
|
51
|
+
const { selectTitleName, selectValueName, selectActionName, selectPlaceholder, renderIf, columns, name: elementName, data, liveData: elementLiveData, style, buttonStyle } = element;
|
|
52
|
+
const { checkLiveData, liveData, setLiveData } = (0, use_live_data_1.default)({
|
|
53
|
+
elementLiveData,
|
|
54
|
+
});
|
|
55
|
+
const { checkRender, render, setRender } = (0, use_render_if_1.default)({
|
|
56
|
+
elementRenderIf: renderIf,
|
|
57
|
+
});
|
|
58
|
+
const addToTable = (0, react_1.useCallback)((selected) => {
|
|
59
|
+
if (selected === '')
|
|
60
|
+
return;
|
|
61
|
+
const elementSelected = data.find((e) => e[selectValueName] === selected);
|
|
62
|
+
if (elementSelected) {
|
|
63
|
+
const currentElements = new Map(rowSelected.entries());
|
|
64
|
+
currentElements.set(selected, elementSelected);
|
|
65
|
+
setValue(elementName, Array.from(currentElements.values()));
|
|
66
|
+
setRowSelected(currentElements);
|
|
67
|
+
setSelected('');
|
|
68
|
+
}
|
|
69
|
+
}, [data, rowSelected, setRowSelected, setSelected]);
|
|
70
|
+
const tableButtonAction = (0, react_1.useCallback)((row, isDeleteAction, action) => {
|
|
71
|
+
const id = row[selectValueName];
|
|
72
|
+
if (isDeleteAction) {
|
|
73
|
+
const currentElements = new Map(rowSelected.entries());
|
|
74
|
+
currentElements.delete(id);
|
|
75
|
+
setRowSelected(currentElements);
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
if (action)
|
|
79
|
+
action(row);
|
|
80
|
+
}, [rowSelected, setRowSelected]);
|
|
81
|
+
(0, react_1.useEffect)(() => {
|
|
82
|
+
const { unsubscribe } = watch((formData, { name, type }) => {
|
|
83
|
+
if (!name)
|
|
84
|
+
return;
|
|
85
|
+
if (renderIf) {
|
|
86
|
+
checkRender(formData, { name, type }).then((renderStatus) => {
|
|
87
|
+
if (renderStatus === undefined || renderStatus === null)
|
|
88
|
+
return;
|
|
89
|
+
if (render !== renderStatus) {
|
|
90
|
+
setRender(!!renderStatus);
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
if (elementLiveData) {
|
|
95
|
+
setLiveSearching(true);
|
|
96
|
+
checkLiveData(formData, { name, type })
|
|
97
|
+
.then((options) => {
|
|
98
|
+
if (options === undefined || options === null)
|
|
99
|
+
return;
|
|
100
|
+
setLiveData(options);
|
|
101
|
+
})
|
|
102
|
+
.finally(() => {
|
|
103
|
+
setLiveSearching(false);
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
return () => unsubscribe();
|
|
108
|
+
}, [watch, render, liveData]);
|
|
109
|
+
if (!render)
|
|
110
|
+
return null;
|
|
111
|
+
const selectOptions = (0, react_1.useMemo)(() => {
|
|
112
|
+
return data.map((e) => {
|
|
113
|
+
const id = e[selectValueName];
|
|
114
|
+
const name = e[selectTitleName];
|
|
115
|
+
return {
|
|
116
|
+
id,
|
|
117
|
+
name
|
|
118
|
+
};
|
|
119
|
+
});
|
|
120
|
+
}, [data]);
|
|
121
|
+
const keyColumns = (0, react_1.useMemo)(() => {
|
|
122
|
+
return columns.map((e) => e.title);
|
|
123
|
+
}, [columns]);
|
|
124
|
+
const tableData = (0, react_1.useMemo)(() => {
|
|
125
|
+
return Array.from(rowSelected.values());
|
|
126
|
+
}, [rowSelected]);
|
|
127
|
+
return (react_1.default.createElement("div", { className: 'flex flex-col gap-2', style: { ...style } },
|
|
128
|
+
react_1.default.createElement("div", { className: "flex w-full justify-between gap-4" },
|
|
129
|
+
react_1.default.createElement(react_hook_form_1.Controller, { control: control, name: elementName, defaultValue: [], render: ({ field: { value } }) => (react_1.default.createElement("input", { type: 'hidden', value: value })) }),
|
|
130
|
+
react_1.default.createElement(Select, { name: 'table-select-field', placeholder: selectPlaceholder, isSearch: true, value: selected, invalid: false, options: liveData || selectOptions, liveSearching: liveSearching, onChange: (selected) => {
|
|
131
|
+
setSelected(selected);
|
|
132
|
+
} }),
|
|
133
|
+
react_1.default.createElement(Button, { style: buttonStyle, text: selectActionName, onClick: () => addToTable(selected) })),
|
|
134
|
+
react_1.default.createElement("table", { className: "text-[11px] w-full shadow-md sm:rounded-lg" },
|
|
135
|
+
react_1.default.createElement("thead", { className: "sticky top-0 text-gray-700 bg-gray-50 text-center z-10" },
|
|
136
|
+
react_1.default.createElement("tr", null, keyColumns.map((title) => (react_1.default.createElement("th", { scope: 'col', className: 'px-6 py-3' }, title))))),
|
|
137
|
+
react_1.default.createElement("tbody", null, tableData.map((row, index) => {
|
|
138
|
+
return (react_1.default.createElement("tr", { key: `row-${row[selectValueName]}-i-${index}`, className: "bg-white border-b hover:bg-gray-50 text-center" }, columns.map(({ Icon, isButton, action, isDeleteAction, style, ...column }) => {
|
|
139
|
+
if (!isButton)
|
|
140
|
+
return (react_1.default.createElement("td", { className: 'px-6 py-4', style: style }, row[column.key] ?? ''));
|
|
141
|
+
return (react_1.default.createElement("td", null,
|
|
142
|
+
react_1.default.createElement("button", { className: 'p-2 rounded-md text-lg', onClick: () => { tableButtonAction(row, isDeleteAction, action); }, style: style }, Icon && react_1.default.createElement(Icon, null))));
|
|
143
|
+
})));
|
|
144
|
+
})))));
|
|
145
|
+
};
|
|
146
|
+
exports.default = MakeTable;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CSSProperties } from 'react';
|
|
1
|
+
import { CSSProperties, ReactNode } from 'react';
|
|
2
2
|
import { IFieldProps } from './field';
|
|
3
3
|
import { FieldValues, UseFormGetValues } from 'react-hook-form';
|
|
4
4
|
export interface IMakeButton {
|
|
@@ -12,6 +12,7 @@ export interface IMakeButton {
|
|
|
12
12
|
type?: 'button' | 'submit' | 'reset';
|
|
13
13
|
onClick?: (formData: FieldValues) => void;
|
|
14
14
|
color?: string;
|
|
15
|
+
children?: ReactNode;
|
|
15
16
|
}
|
|
16
17
|
export interface IMakeButtonProps extends IFieldProps {
|
|
17
18
|
element: Omit<IMakeButton, 'elementType'>;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { CSSProperties, JSX } from 'react';
|
|
2
|
+
import { IField, IFieldProps } from './field';
|
|
3
|
+
import { IModalLiveDataCondition } from './modal';
|
|
4
|
+
export interface ITableColumn extends Pick<IField, 'style'> {
|
|
5
|
+
title: string;
|
|
6
|
+
key?: string;
|
|
7
|
+
isButton?: boolean;
|
|
8
|
+
isDeleteAction?: boolean;
|
|
9
|
+
Icon?: (props: any) => JSX.Element;
|
|
10
|
+
action?: (row: any) => void;
|
|
11
|
+
}
|
|
12
|
+
export interface IMakeTable extends Omit<IField, 'label' | 'defaultValue' | 'validation' | 'disabled' | 'enableIf' | 'id'> {
|
|
13
|
+
elementType: 'table';
|
|
14
|
+
selectValueName: string;
|
|
15
|
+
selectTitleName: string;
|
|
16
|
+
selectPlaceholder?: string;
|
|
17
|
+
selectActionName: string;
|
|
18
|
+
buttonStyle?: CSSProperties;
|
|
19
|
+
columns: Array<ITableColumn>;
|
|
20
|
+
defaultSelected?: Array<string>;
|
|
21
|
+
data: Array<any>;
|
|
22
|
+
liveData?: IModalLiveDataCondition;
|
|
23
|
+
}
|
|
24
|
+
export interface IMakeTableProps extends Omit<IFieldProps, 'unregister'> {
|
|
25
|
+
element: Omit<IMakeTable, 'elementType'>;
|
|
26
|
+
}
|
|
@@ -10,7 +10,8 @@ import { IOption } from './option';
|
|
|
10
10
|
import { IMakeButton } from './make-button';
|
|
11
11
|
import { IMakeCustomUpload } from './make-custom-upload';
|
|
12
12
|
import { IMakeWatcher } from './make-watcher';
|
|
13
|
-
|
|
13
|
+
import { IMakeTable } from './make-table';
|
|
14
|
+
export type IModalField = IMakeSelect | IMakeInput | IMakeFieldGroup | IMakeTextarea | IMakeToggle | IMakeDescription | IMakeUpload | IMakeCustomUpload | IMakeWatcher | IMakeButton | IMakeTable;
|
|
14
15
|
export type IFormField = IMakeSelect | IMakeInput | IMakeTextarea | IMakeToggle;
|
|
15
16
|
export interface IModalRenderAction {
|
|
16
17
|
action: (data: string, ...args: any[]) => Promise<boolean>;
|
package/dist/modal.js
CHANGED
|
@@ -51,6 +51,7 @@ const make_button_1 = __importDefault(require("./components/make-button/make-but
|
|
|
51
51
|
const component_state_1 = require("./context/component/component-state");
|
|
52
52
|
const make_custom_upload_1 = __importDefault(require("./components/make-custom-upload/make-custom-upload"));
|
|
53
53
|
const make_watcher_1 = __importDefault(require("./components/make-watcher/make-watcher"));
|
|
54
|
+
const make_table_1 = __importDefault(require("./components/make-table/make-table"));
|
|
54
55
|
const Modal = ({ open, close, config }) => {
|
|
55
56
|
const { ModalButtonAction, ModalButtonCancel } = (0, react_1.useContext)(component_state_1.ComponentStateContext);
|
|
56
57
|
const [modalReady, setModalReady] = (0, react_1.useState)(undefined);
|
|
@@ -105,7 +106,7 @@ const Modal = ({ open, close, config }) => {
|
|
|
105
106
|
setValue,
|
|
106
107
|
unregister,
|
|
107
108
|
};
|
|
108
|
-
return elementType === 'input' ? (react_1.default.createElement(make_input_1.default, { ...props, key: `modal-input-${index}`, element: element })) : elementType === 'select' ? (react_1.default.createElement(make_select_1.default, { ...props, key: `modal-select-${index}`, element: element })) : elementType === 'textarea' ? (react_1.default.createElement(make_textarea_1.default, { ...props, key: `modal-textarea-${index}`, element: element })) : elementType === 'toggle' ? (react_1.default.createElement(make_toggle_1.default, { ...props, key: `modal-toggle-${index}`, element: element })) : elementType === 'text' ? (react_1.default.createElement(make_description_1.default, { ...props, key: `modal-text-${index}`, element: element })) : elementType === 'upload' ? (react_1.default.createElement(make_upload_1.default, { ...props, key: `modal-upload-${index}`, element: element })) : elementType === 'custom-upload' ? (react_1.default.createElement(make_custom_upload_1.default, { ...props, key: `modal-custom-upload-${index}`, element: element })) : elementType === 'watcher' ? (react_1.default.createElement(make_watcher_1.default, { ...props, key: `modal-watcher-${index}`, element: element })) : elementType === 'button' ? (react_1.default.createElement(make_button_1.default, { ...props, key: `modal-button-${index}`, element: element, getValues: getValues })) : null;
|
|
109
|
+
return elementType === 'input' ? (react_1.default.createElement(make_input_1.default, { ...props, key: `modal-input-${index}`, element: element })) : elementType === 'select' ? (react_1.default.createElement(make_select_1.default, { ...props, key: `modal-select-${index}`, element: element })) : elementType === 'textarea' ? (react_1.default.createElement(make_textarea_1.default, { ...props, key: `modal-textarea-${index}`, element: element })) : elementType === 'toggle' ? (react_1.default.createElement(make_toggle_1.default, { ...props, key: `modal-toggle-${index}`, element: element })) : elementType === 'text' ? (react_1.default.createElement(make_description_1.default, { ...props, key: `modal-text-${index}`, element: element })) : elementType === 'upload' ? (react_1.default.createElement(make_upload_1.default, { ...props, key: `modal-upload-${index}`, element: element })) : elementType === 'custom-upload' ? (react_1.default.createElement(make_custom_upload_1.default, { ...props, key: `modal-custom-upload-${index}`, element: element })) : elementType === 'watcher' ? (react_1.default.createElement(make_watcher_1.default, { ...props, key: `modal-watcher-${index}`, element: element })) : elementType === 'button' ? (react_1.default.createElement(make_button_1.default, { ...props, key: `modal-button-${index}`, element: element, getValues: getValues })) : elementType === 'table' ? (react_1.default.createElement(make_table_1.default, { ...props, key: `modal-table-${index}`, element: element })) : null;
|
|
109
110
|
};
|
|
110
111
|
const closeHandler = () => {
|
|
111
112
|
if (modalReady?.onClose)
|
package/package.json
CHANGED
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import React, { FC, useCallback, useContext, useEffect, useMemo, useState } from 'react';
|
|
4
|
+
|
|
5
|
+
import useRenderIf from '../../hooks/use-render-if';
|
|
6
|
+
import { IMakeTableProps } from '../../interfaces/make-table';
|
|
7
|
+
import { ComponentStateContext } from '../../context/component/component-state';
|
|
8
|
+
import { IOption } from '../../interfaces/option';
|
|
9
|
+
import useLiveData from '../../hooks/use-live-data';
|
|
10
|
+
import { Controller } from 'react-hook-form';
|
|
11
|
+
|
|
12
|
+
const MakeTable: FC<IMakeTableProps> = ({
|
|
13
|
+
element,
|
|
14
|
+
watch,
|
|
15
|
+
control,
|
|
16
|
+
setValue
|
|
17
|
+
}) => {
|
|
18
|
+
const [liveSearching, setLiveSearching] = useState<boolean>(false);
|
|
19
|
+
const [selected, setSelected] = useState<string>('')
|
|
20
|
+
const [rowSelected, setRowSelected] = useState<Map<string, any>>(new Map())
|
|
21
|
+
|
|
22
|
+
const { Select } = useContext(ComponentStateContext);
|
|
23
|
+
|
|
24
|
+
const { Button } = useContext(ComponentStateContext);
|
|
25
|
+
|
|
26
|
+
const {
|
|
27
|
+
selectTitleName,
|
|
28
|
+
selectValueName,
|
|
29
|
+
selectActionName,
|
|
30
|
+
selectPlaceholder,
|
|
31
|
+
renderIf,
|
|
32
|
+
columns,
|
|
33
|
+
name: elementName,
|
|
34
|
+
data,
|
|
35
|
+
liveData: elementLiveData,
|
|
36
|
+
style,
|
|
37
|
+
buttonStyle
|
|
38
|
+
} = element;
|
|
39
|
+
|
|
40
|
+
const { checkLiveData, liveData, setLiveData } = useLiveData({
|
|
41
|
+
elementLiveData,
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
const { checkRender, render, setRender } = useRenderIf({
|
|
45
|
+
elementRenderIf: renderIf,
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
const addToTable = useCallback((selected: string) => {
|
|
49
|
+
if (selected === '') return
|
|
50
|
+
|
|
51
|
+
const elementSelected: any = data.find((e) => e[selectValueName] === selected)
|
|
52
|
+
|
|
53
|
+
if (elementSelected) {
|
|
54
|
+
const currentElements = new Map(rowSelected.entries())
|
|
55
|
+
currentElements.set(selected, elementSelected)
|
|
56
|
+
setValue(elementName, Array.from(currentElements.values()))
|
|
57
|
+
setRowSelected(currentElements)
|
|
58
|
+
setSelected('')
|
|
59
|
+
}
|
|
60
|
+
}, [data, rowSelected, setRowSelected, setSelected])
|
|
61
|
+
|
|
62
|
+
const tableButtonAction = useCallback((row: any, isDeleteAction?: boolean, action?: (data: any) => void) => {
|
|
63
|
+
const id: string = row[selectValueName]
|
|
64
|
+
|
|
65
|
+
if (isDeleteAction) {
|
|
66
|
+
const currentElements = new Map(rowSelected.entries())
|
|
67
|
+
currentElements.delete(id)
|
|
68
|
+
setRowSelected(currentElements)
|
|
69
|
+
|
|
70
|
+
return
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (action) action(row)
|
|
74
|
+
}, [rowSelected, setRowSelected])
|
|
75
|
+
|
|
76
|
+
useEffect(() => {
|
|
77
|
+
const { unsubscribe } = watch((formData, { name, type }) => {
|
|
78
|
+
if (!name) return;
|
|
79
|
+
|
|
80
|
+
if (renderIf) {
|
|
81
|
+
checkRender(formData, { name, type }).then((renderStatus) => {
|
|
82
|
+
if (renderStatus === undefined || renderStatus === null) return;
|
|
83
|
+
|
|
84
|
+
if (render !== renderStatus) {
|
|
85
|
+
setRender(!!renderStatus);
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
if (elementLiveData) {
|
|
91
|
+
setLiveSearching(true);
|
|
92
|
+
|
|
93
|
+
checkLiveData(formData, { name, type })
|
|
94
|
+
.then((options) => {
|
|
95
|
+
if (options === undefined || options === null) return;
|
|
96
|
+
|
|
97
|
+
setLiveData(options);
|
|
98
|
+
})
|
|
99
|
+
.finally(() => {
|
|
100
|
+
setLiveSearching(false);
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
return () => unsubscribe();
|
|
106
|
+
}, [watch, render, liveData]);
|
|
107
|
+
|
|
108
|
+
if (!render) return null;
|
|
109
|
+
|
|
110
|
+
const selectOptions = useMemo<Array<IOption>>(() => {
|
|
111
|
+
return data.map((e) => {
|
|
112
|
+
const id: string = e[selectValueName]
|
|
113
|
+
const name: string = e[selectTitleName]
|
|
114
|
+
|
|
115
|
+
return {
|
|
116
|
+
id,
|
|
117
|
+
name
|
|
118
|
+
}
|
|
119
|
+
})
|
|
120
|
+
}, [data])
|
|
121
|
+
|
|
122
|
+
const keyColumns = useMemo(() => {
|
|
123
|
+
return columns.map((e) => e.title)
|
|
124
|
+
}, [columns])
|
|
125
|
+
|
|
126
|
+
const tableData = useMemo(() => {
|
|
127
|
+
return Array.from(rowSelected.values())
|
|
128
|
+
}, [rowSelected])
|
|
129
|
+
|
|
130
|
+
return (
|
|
131
|
+
<div className='flex flex-col gap-2' style={{ ...style }}>
|
|
132
|
+
<div className="flex w-full justify-between gap-4">
|
|
133
|
+
<Controller
|
|
134
|
+
control={control}
|
|
135
|
+
name={elementName}
|
|
136
|
+
defaultValue={[]}
|
|
137
|
+
render={({ field: { value } }) => (
|
|
138
|
+
<input type='hidden' value={value} />
|
|
139
|
+
)}
|
|
140
|
+
/>
|
|
141
|
+
<Select
|
|
142
|
+
name='table-select-field'
|
|
143
|
+
placeholder={selectPlaceholder}
|
|
144
|
+
isSearch={true}
|
|
145
|
+
value={selected}
|
|
146
|
+
invalid={false}
|
|
147
|
+
options={liveData || selectOptions}
|
|
148
|
+
liveSearching={liveSearching}
|
|
149
|
+
onChange={(selected: string) => {
|
|
150
|
+
setSelected(selected)
|
|
151
|
+
}}
|
|
152
|
+
/>
|
|
153
|
+
<Button
|
|
154
|
+
style={buttonStyle}
|
|
155
|
+
text={selectActionName}
|
|
156
|
+
onClick={() => addToTable(selected)}
|
|
157
|
+
/>
|
|
158
|
+
</div>
|
|
159
|
+
|
|
160
|
+
<table className="text-[11px] w-full shadow-md sm:rounded-lg">
|
|
161
|
+
<thead className="sticky top-0 text-gray-700 bg-gray-50 text-center z-10">
|
|
162
|
+
<tr>
|
|
163
|
+
{
|
|
164
|
+
keyColumns.map((title) => (
|
|
165
|
+
<th scope='col' className='px-6 py-3'>{title}</th>
|
|
166
|
+
))
|
|
167
|
+
}
|
|
168
|
+
</tr>
|
|
169
|
+
</thead>
|
|
170
|
+
<tbody>
|
|
171
|
+
{
|
|
172
|
+
tableData.map((row, index) => {
|
|
173
|
+
return (
|
|
174
|
+
<tr key={`row-${row[selectValueName]}-i-${index}`} className="bg-white border-b hover:bg-gray-50 text-center">
|
|
175
|
+
{
|
|
176
|
+
columns.map(({ Icon, isButton, action, isDeleteAction, style, ...column }) => {
|
|
177
|
+
if (!isButton)
|
|
178
|
+
return (
|
|
179
|
+
<td className='px-6 py-4' style={style}>{row[column.key!!] ?? ''}</td>
|
|
180
|
+
)
|
|
181
|
+
|
|
182
|
+
return (
|
|
183
|
+
<td>
|
|
184
|
+
<button className='p-2 rounded-md text-lg' onClick={() => { tableButtonAction(row, isDeleteAction, action) }} style={style}>
|
|
185
|
+
{Icon && <Icon />}
|
|
186
|
+
</button>
|
|
187
|
+
</td>
|
|
188
|
+
)
|
|
189
|
+
})
|
|
190
|
+
}
|
|
191
|
+
</tr>
|
|
192
|
+
)
|
|
193
|
+
})
|
|
194
|
+
}
|
|
195
|
+
</tbody>
|
|
196
|
+
</table>
|
|
197
|
+
</div>
|
|
198
|
+
);
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
export default MakeTable;
|
|
@@ -21,7 +21,6 @@ export interface IComponentState {
|
|
|
21
21
|
ModalButtonCancel: FC<Omit<IMakeButton, 'elementType'>>;
|
|
22
22
|
ModalButtonAction: FC<Omit<IMakeButton, 'elementType'>>;
|
|
23
23
|
Button: FC<Omit<IMakeButton, 'elementType'>>;
|
|
24
|
-
//Description: FC<Omit<IMakeDescription, 'elementType'>>
|
|
25
24
|
Input: FC<
|
|
26
25
|
Omit<IMakeInput, 'elementType' | 'validation' | 'renderIf' | 'enableIf'> &
|
|
27
26
|
IComponentAditionalProps
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CSSProperties } from 'react';
|
|
1
|
+
import { CSSProperties, ReactNode } from 'react';
|
|
2
2
|
|
|
3
3
|
import { IFieldProps } from './field';
|
|
4
4
|
import { FieldValues, UseFormGetValues } from 'react-hook-form';
|
|
@@ -14,6 +14,7 @@ export interface IMakeButton {
|
|
|
14
14
|
type?: 'button' | 'submit' | 'reset';
|
|
15
15
|
onClick?: (formData: FieldValues) => void;
|
|
16
16
|
color?: string;
|
|
17
|
+
children?: ReactNode
|
|
17
18
|
}
|
|
18
19
|
|
|
19
20
|
export interface IMakeButtonProps extends IFieldProps {
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { CSSProperties, JSX } from 'react';
|
|
2
|
+
import { IField, IFieldProps } from './field';
|
|
3
|
+
import { IModalLiveDataCondition } from './modal';
|
|
4
|
+
|
|
5
|
+
export interface ITableColumn extends Pick<IField, 'style'>{
|
|
6
|
+
title: string,
|
|
7
|
+
key?: string,
|
|
8
|
+
isButton?: boolean
|
|
9
|
+
isDeleteAction?: boolean
|
|
10
|
+
Icon?: (props: any) => JSX.Element
|
|
11
|
+
action?: (row: any) => void
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface IMakeTable extends Omit<IField, 'label' | 'defaultValue' | 'validation' | 'disabled' | 'enableIf' | 'id'> {
|
|
15
|
+
elementType: 'table';
|
|
16
|
+
selectValueName: string
|
|
17
|
+
selectTitleName: string
|
|
18
|
+
selectPlaceholder?: string
|
|
19
|
+
selectActionName: string
|
|
20
|
+
buttonStyle?: CSSProperties
|
|
21
|
+
columns: Array<ITableColumn>
|
|
22
|
+
defaultSelected?: Array<string>
|
|
23
|
+
data: Array<any>
|
|
24
|
+
liveData?: IModalLiveDataCondition;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface IMakeTableProps extends Omit<IFieldProps, 'unregister'> {
|
|
28
|
+
element: Omit<IMakeTable, 'elementType'>;
|
|
29
|
+
}
|
package/src/interfaces/modal.ts
CHANGED
|
@@ -11,6 +11,7 @@ import { IOption } from './option';
|
|
|
11
11
|
import { IMakeButton } from './make-button';
|
|
12
12
|
import { IMakeCustomUpload } from './make-custom-upload';
|
|
13
13
|
import { IMakeWatcher } from './make-watcher';
|
|
14
|
+
import { IMakeTable } from './make-table';
|
|
14
15
|
|
|
15
16
|
export type IModalField =
|
|
16
17
|
| IMakeSelect
|
|
@@ -22,7 +23,8 @@ export type IModalField =
|
|
|
22
23
|
| IMakeUpload
|
|
23
24
|
| IMakeCustomUpload
|
|
24
25
|
| IMakeWatcher
|
|
25
|
-
| IMakeButton
|
|
26
|
+
| IMakeButton
|
|
27
|
+
| IMakeTable;
|
|
26
28
|
|
|
27
29
|
export type IFormField = IMakeSelect | IMakeInput | IMakeTextarea | IMakeToggle;
|
|
28
30
|
|
package/src/modal.tsx
CHANGED
|
@@ -30,6 +30,8 @@ import MakeCustomUpload from './components/make-custom-upload/make-custom-upload
|
|
|
30
30
|
import { IMakeCustomUpload } from './interfaces/make-custom-upload';
|
|
31
31
|
import MakeWatcher from './components/make-watcher/make-watcher';
|
|
32
32
|
import { IMakeWatcher } from './interfaces/make-watcher';
|
|
33
|
+
import MakeTable from './components/make-table/make-table';
|
|
34
|
+
import { IMakeTable } from './interfaces/make-table';
|
|
33
35
|
|
|
34
36
|
export const Modal = ({ open, close, config }: IModal) => {
|
|
35
37
|
const { ModalButtonAction, ModalButtonCancel } = useContext(
|
|
@@ -175,6 +177,12 @@ export const Modal = ({ open, close, config }: IModal) => {
|
|
|
175
177
|
element={element as IMakeButton}
|
|
176
178
|
getValues={getValues}
|
|
177
179
|
/>
|
|
180
|
+
) : elementType === 'table' ? (
|
|
181
|
+
<MakeTable
|
|
182
|
+
{...props}
|
|
183
|
+
key={`modal-table-${index}`}
|
|
184
|
+
element={element as IMakeTable}
|
|
185
|
+
/>
|
|
178
186
|
) : null;
|
|
179
187
|
};
|
|
180
188
|
|