@homefile/components-v2 2.9.4 → 2.11.0
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/forms/dynamicForm/DynamicForm.d.ts +1 -1
- package/dist/components/forms/dynamicForm/DynamicForm.js +6 -4
- package/dist/components/forms/dynamicForm/fields/AIGridField.d.ts +2 -0
- package/dist/components/forms/dynamicForm/fields/AIGridField.js +37 -0
- package/dist/components/forms/dynamicForm/fields/GridField.d.ts +2 -2
- package/dist/components/forms/dynamicForm/fields/GridField.js +5 -3
- package/dist/components/forms/dynamicForm/fields/SingleImage.d.ts +2 -0
- package/dist/components/forms/dynamicForm/fields/SingleImage.js +17 -0
- package/dist/components/forms/dynamicForm/fields/index.d.ts +2 -0
- package/dist/components/forms/dynamicForm/fields/index.js +2 -0
- package/dist/components/icons/Camera.js +2 -2
- package/dist/components/inputs/MobileFileUploader.d.ts +1 -1
- package/dist/components/inputs/MobileFileUploader.js +2 -2
- package/dist/hooks/folderPanel/useFilesUploader.d.ts +1 -1
- package/dist/hooks/folderPanel/useFilesUploader.js +1 -1
- package/dist/interfaces/forms/dynamicForm/DynamicForm.interface.d.ts +3 -2
- package/dist/interfaces/forms/dynamicForm/fields/FileField.interface.d.ts +2 -1
- package/dist/interfaces/forms/dynamicForm/fields/GridField.interface.d.ts +14 -0
- package/dist/interfaces/forms/dynamicForm/fields/GridField.interface.js +1 -0
- package/dist/interfaces/forms/dynamicForm/fields/index.d.ts +1 -0
- package/dist/interfaces/forms/dynamicForm/fields/index.js +1 -0
- package/dist/interfaces/inputs/EditFileUploader.interface.d.ts +1 -0
- package/dist/mocks/forms/dynamicForm.mock.js +30 -2
- package/dist/stories/forms/dynamicForm/DynamicForm.stories.js +2 -1
- package/package.json +1 -1
- package/src/components/forms/dynamicForm/DynamicForm.tsx +19 -1
- package/src/components/forms/dynamicForm/fields/AIGridField.tsx +72 -0
- package/src/components/forms/dynamicForm/fields/GridField.tsx +14 -3
- package/src/components/forms/dynamicForm/fields/SingleImage.tsx +54 -0
- package/src/components/forms/dynamicForm/fields/index.ts +2 -0
- package/src/components/icons/Camera.tsx +29 -3
- package/src/components/inputs/MobileFileUploader.tsx +4 -1
- package/src/hooks/folderPanel/useFilesUploader.ts +2 -2
- package/src/interfaces/forms/dynamicForm/DynamicForm.interface.ts +10 -1
- package/src/interfaces/forms/dynamicForm/fields/FileField.interface.ts +2 -1
- package/src/interfaces/forms/dynamicForm/fields/GridField.interface.ts +16 -0
- package/src/interfaces/forms/dynamicForm/fields/index.ts +1 -0
- package/src/interfaces/inputs/EditFileUploader.interface.ts +1 -0
- package/src/mocks/forms/dynamicForm.mock.ts +30 -2
- package/src/stories/forms/dynamicForm/DynamicForm.stories.tsx +2 -1
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { DynamicFormI } from '../../../interfaces';
|
|
2
|
-
export declare const DynamicForm: ({ callback, displayImages, form: fields, menuItems, onRemoveImage, onUpload, showTitle, title, uploadingFieldId, ...props }: DynamicFormI) => import("react/jsx-runtime").JSX.Element;
|
|
2
|
+
export declare const DynamicForm: ({ callback, displayImages, form: fields, menuItems, onAISend, onRemoveImage, onUpload, showTitle, title, uploadingFieldId, ...props }: DynamicFormI) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -10,15 +10,15 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
10
10
|
return t;
|
|
11
11
|
};
|
|
12
12
|
import { createElement as _createElement } from "react";
|
|
13
|
-
import { jsx as _jsx,
|
|
13
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
14
14
|
import { FormProvider } from 'react-hook-form';
|
|
15
15
|
import { t } from 'i18next';
|
|
16
16
|
import { Box, Stack, Text } from '@chakra-ui/react';
|
|
17
|
-
import { HiddenFieldSection, GroupField, TextField, TextAreaField, SelectField, RatingField, GridField, FieldWithDelete, FileField, SwitchField, DateField, NumberField, CurrencyField, TileBody, CheckboxGroupField, CheckboxAgreement, } from '../..';
|
|
17
|
+
import { HiddenFieldSection, GroupField, TextField, TextAreaField, SelectField, RatingField, GridField, FieldWithDelete, FileField, SwitchField, DateField, NumberField, CurrencyField, TileBody, CheckboxGroupField, CheckboxAgreement, AIGridField, } from '../..';
|
|
18
18
|
import { useDynamicForm } from '../../../hooks';
|
|
19
19
|
import { fieldIcons } from '../../../helpers';
|
|
20
20
|
export const DynamicForm = (_a) => {
|
|
21
|
-
var { callback, displayImages, form: fields, menuItems, onRemoveImage, onUpload, showTitle = true, title, uploadingFieldId } = _a, props = __rest(_a, ["callback", "displayImages", "form", "menuItems", "onRemoveImage", "onUpload", "showTitle", "title", "uploadingFieldId"]);
|
|
21
|
+
var { callback, displayImages, form: fields, menuItems, onAISend, onRemoveImage, onUpload, showTitle = true, title, uploadingFieldId } = _a, props = __rest(_a, ["callback", "displayImages", "form", "menuItems", "onAISend", "onRemoveImage", "onUpload", "showTitle", "title", "uploadingFieldId"]);
|
|
22
22
|
const { form, visibleFields, hiddenFields, handleAddAll, handleAdd, handleFilesUpload, handleRemove, } = useDynamicForm({ fields, onUpload });
|
|
23
23
|
return (_jsxs(Stack, { bg: "lightBlue.1", spacing: "0", h: "full", overflowX: "hidden", children: [showTitle && (_jsx(Box, { px: "base", pt: "4", pb: "2", borderBottom: "1px dashed", borderColor: "lightBlue.6", children: _jsx(Text, { fontFamily: "secondary", children: title !== null && title !== void 0 ? title : t('forms.itemDetails') }) })), _jsx(FormProvider, Object.assign({}, form, { children: _jsx(_Fragment, { children: visibleFields === null || visibleFields === void 0 ? void 0 : visibleFields.map((field) => {
|
|
24
24
|
const { canBeHidden, children, description, icon, id, name, options, type, value, } = field;
|
|
@@ -26,7 +26,7 @@ export const DynamicForm = (_a) => {
|
|
|
26
26
|
id,
|
|
27
27
|
value,
|
|
28
28
|
icon: icon ? fieldIcons[icon] : undefined,
|
|
29
|
-
placeholder: (name
|
|
29
|
+
placeholder: Boolean(name) ? name : description,
|
|
30
30
|
};
|
|
31
31
|
const fieldWithDeleteBaseProps = {
|
|
32
32
|
id,
|
|
@@ -62,6 +62,8 @@ export const DynamicForm = (_a) => {
|
|
|
62
62
|
case 'rating':
|
|
63
63
|
return (_createElement(FieldWithDelete, Object.assign({}, fieldWithDeleteBaseProps, { key: id }),
|
|
64
64
|
_jsx(RatingField, Object.assign({}, baseProps))));
|
|
65
|
+
case 'ai-grid':
|
|
66
|
+
return (_jsxs(Stack, { p: "base", spacing: "base", bg: "lightBlue.2", children: [description && (_jsx(Text, { fontFamily: "secondary", children: description })), _jsx(AIGridField, Object.assign({}, baseProps, { onRemove: onRemoveImage, onUpload: (files) => handleFilesUpload({ id, files }), onAISend: onAISend, children: children }))] }, id));
|
|
65
67
|
case 'grid':
|
|
66
68
|
return (_createElement(FieldWithDelete, Object.assign({}, fieldWithDeleteBaseProps, { key: id }),
|
|
67
69
|
_jsx(GridField, Object.assign({}, baseProps, { children: children }))));
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useFormContext } from 'react-hook-form';
|
|
3
|
+
import { Flex, IconButton, Text } from '@chakra-ui/react';
|
|
4
|
+
import { TextField, SingleImage, Plus } from '../../..';
|
|
5
|
+
import { fieldIcons } from '../../../../helpers';
|
|
6
|
+
import { colors } from '../../../../theme/colors';
|
|
7
|
+
export const AIGridField = ({ children, onAISend, onRemove, onUpload, }) => {
|
|
8
|
+
var _a, _b, _c, _d, _e, _f;
|
|
9
|
+
const { watch } = useFormContext();
|
|
10
|
+
const textChild = children === null || children === void 0 ? void 0 : children.find(({ type }) => type === 'text' || type === 'string');
|
|
11
|
+
const textProps = {
|
|
12
|
+
id: (_a = textChild === null || textChild === void 0 ? void 0 : textChild.id) !== null && _a !== void 0 ? _a : '',
|
|
13
|
+
value: (_b = textChild === null || textChild === void 0 ? void 0 : textChild.value) !== null && _b !== void 0 ? _b : '',
|
|
14
|
+
placeholder: (_c = textChild === null || textChild === void 0 ? void 0 : textChild.name) !== null && _c !== void 0 ? _c : textChild === null || textChild === void 0 ? void 0 : textChild.description,
|
|
15
|
+
icon: (textChild === null || textChild === void 0 ? void 0 : textChild.icon)
|
|
16
|
+
? fieldIcons[textChild.icon]
|
|
17
|
+
: undefined,
|
|
18
|
+
};
|
|
19
|
+
const imageField = children === null || children === void 0 ? void 0 : children.find(({ type }) => type === 'ai-image');
|
|
20
|
+
const imageProps = {
|
|
21
|
+
id: (_d = imageField === null || imageField === void 0 ? void 0 : imageField.id) !== null && _d !== void 0 ? _d : '',
|
|
22
|
+
value: (_e = imageField === null || imageField === void 0 ? void 0 : imageField.value) !== null && _e !== void 0 ? _e : '',
|
|
23
|
+
placeholder: (_f = imageField === null || imageField === void 0 ? void 0 : imageField.name) !== null && _f !== void 0 ? _f : imageField === null || imageField === void 0 ? void 0 : imageField.description,
|
|
24
|
+
icon: (imageField === null || imageField === void 0 ? void 0 : imageField.icon)
|
|
25
|
+
? fieldIcons[imageField.icon]
|
|
26
|
+
: undefined,
|
|
27
|
+
};
|
|
28
|
+
const code = watch(String(textChild === null || textChild === void 0 ? void 0 : textChild.id));
|
|
29
|
+
const handleAISend = () => {
|
|
30
|
+
const form = {
|
|
31
|
+
code,
|
|
32
|
+
image: imageField === null || imageField === void 0 ? void 0 : imageField.value,
|
|
33
|
+
};
|
|
34
|
+
onAISend === null || onAISend === void 0 ? void 0 : onAISend(form);
|
|
35
|
+
};
|
|
36
|
+
return (_jsxs(Flex, { align: "center", gap: "base", children: [_jsx(SingleImage, Object.assign({}, imageProps, { onUpload: onUpload, onRemove: onRemove, value: imageField === null || imageField === void 0 ? void 0 : imageField.value })), _jsx(Text, { fontFamily: "secondary", textAlign: "center", children: "OR" }), _jsx(TextField, Object.assign({}, textProps)), _jsx(IconButton, { "aria-label": "Add new address line", variant: "iconOutlined", icon: _jsx(Plus, { size: 28, stroke: colors.blue[3] }), onClick: handleAISend, h: "input.md", disabled: !(code === null || code === void 0 ? void 0 : code.length) && !(imageField === null || imageField === void 0 ? void 0 : imageField.value) })] }));
|
|
37
|
+
};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export declare const GridField: ({ children }:
|
|
1
|
+
import { GridFieldI } from '../../../../interfaces';
|
|
2
|
+
export declare const GridField: ({ children, onRemove, onUpload }: GridFieldI) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { createElement as _createElement } from "react";
|
|
3
3
|
import { Flex } from '@chakra-ui/react';
|
|
4
|
-
import { DateField, NumberField, TextField, SelectField, CurrencyField, } from '../../..';
|
|
4
|
+
import { DateField, NumberField, TextField, SelectField, CurrencyField, SingleImage, } from '../../..';
|
|
5
5
|
import { fieldIcons } from '../../../../helpers';
|
|
6
|
-
export const GridField = ({ children }) => {
|
|
6
|
+
export const GridField = ({ children, onRemove, onUpload }) => {
|
|
7
7
|
return (_jsx(Flex, { align: "stretch", gap: "base", children: children === null || children === void 0 ? void 0 : children.map(({ id, description, name, value, type, options = [], icon }) => {
|
|
8
8
|
const baseProps = {
|
|
9
9
|
id,
|
|
10
10
|
value,
|
|
11
|
-
placeholder:
|
|
11
|
+
placeholder: name && name !== '' ? name : description,
|
|
12
12
|
icon: icon ? fieldIcons[icon] : undefined,
|
|
13
13
|
};
|
|
14
14
|
switch (type) {
|
|
@@ -27,6 +27,8 @@ export const GridField = ({ children }) => {
|
|
|
27
27
|
return _createElement(SelectField, Object.assign({}, baseProps, { key: id, options: options }));
|
|
28
28
|
case 'telephone':
|
|
29
29
|
return _createElement(TextField, Object.assign({}, baseProps, { key: id, type: "tel" }));
|
|
30
|
+
case 'ai-image':
|
|
31
|
+
return (_createElement(SingleImage, Object.assign({}, baseProps, { key: id, onUpload: onUpload, onRemove: onRemove, value: value })));
|
|
30
32
|
default:
|
|
31
33
|
return null;
|
|
32
34
|
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { AspectRatio, Box, Flex, IconButton, Image } from '@chakra-ui/react';
|
|
3
|
+
import { colors } from '../../../../theme/colors';
|
|
4
|
+
import { Close, MobileFileUploader } from '../../..';
|
|
5
|
+
import { handleMapFile } from '../../../../utils';
|
|
6
|
+
export const SingleImage = ({ onRemove, onUpload, uploading = false, value, }) => {
|
|
7
|
+
const handleInputChange = (event) => {
|
|
8
|
+
var _a;
|
|
9
|
+
const fileList = (_a = event.target.files) !== null && _a !== void 0 ? _a : [];
|
|
10
|
+
const files = Array.from(fileList);
|
|
11
|
+
if (files.length > 0) {
|
|
12
|
+
const selectedFiles = handleMapFile({ files });
|
|
13
|
+
onUpload === null || onUpload === void 0 ? void 0 : onUpload(selectedFiles);
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
return (_jsxs(Flex, { gap: "2", align: "center", h: "input.md", children: [_jsx(MobileFileUploader, { handleInputChange: handleInputChange, "aria-label": "upload image", minW: "72px" }), value && (_jsxs(Box, { position: "relative", minW: "30px", children: [_jsx(IconButton, { variant: "ghost", "aria-label": "close", maxW: "fit-content", onClick: () => onRemove === null || onRemove === void 0 ? void 0 : onRemove(value), icon: _jsx(Close, { size: 11, stroke: colors.error['2'] }), disabled: uploading, position: "absolute", bg: "neutral.white", p: "0.5", borderRadius: "full", top: "-2", right: "-2", zIndex: "1" }), _jsx(AspectRatio, { maxW: "100%", ratio: 1, children: _jsx(Image, { src: value, objectFit: "cover", alt: "image" }) })] }))] }));
|
|
17
|
+
};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export * from './AIGridField';
|
|
1
2
|
export * from './CheckboxAgreement';
|
|
2
3
|
export * from './CheckboxGroupField';
|
|
3
4
|
export * from './CurrencyField';
|
|
@@ -13,6 +14,7 @@ export * from './SwitchField';
|
|
|
13
14
|
export * from './RatingField';
|
|
14
15
|
export * from './SelectField';
|
|
15
16
|
export * from './SingleFields';
|
|
17
|
+
export * from './SingleImage';
|
|
16
18
|
export * from './TextAreaField';
|
|
17
19
|
export * from './TextField';
|
|
18
20
|
export * from './TileBodyFields';
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export * from './AIGridField';
|
|
1
2
|
export * from './CheckboxAgreement';
|
|
2
3
|
export * from './CheckboxGroupField';
|
|
3
4
|
export * from './CurrencyField';
|
|
@@ -13,6 +14,7 @@ export * from './SwitchField';
|
|
|
13
14
|
export * from './RatingField';
|
|
14
15
|
export * from './SelectField';
|
|
15
16
|
export * from './SingleFields';
|
|
17
|
+
export * from './SingleImage';
|
|
16
18
|
export * from './TextAreaField';
|
|
17
19
|
export * from './TextField';
|
|
18
20
|
export * from './TileBodyFields';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { colors } from '../../theme/colors';
|
|
3
3
|
export const Camera = ({ stroke = colors.blue[3], size = 24 }) => {
|
|
4
|
-
return (_jsx("svg", { xmlns: "http://www.w3.org/2000/svg", width: size, height: size,
|
|
4
|
+
return (_jsx("svg", { xmlns: "http://www.w3.org/2000/svg", width: size, height: size, viewBox: "0 0 26.734 22.146", children: _jsxs("g", { id: "Icon_feather-camera", "data-name": "Icon feather-camera", transform: "translate(-0.75 -3.75)", children: [_jsx("path", { id: "Caminho_17678", "data-name": "Caminho 17678", d: "M26.735,22.852a2.294,2.294,0,0,1-2.294,2.294H3.794A2.294,2.294,0,0,1,1.5,22.852V10.235A2.294,2.294,0,0,1,3.794,7.941H8.382L10.676,4.5h6.882l2.294,3.441H24.44a2.294,2.294,0,0,1,2.294,2.294Z", transform: "translate(0 0)", fill: "none", stroke: stroke, strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "1.5" }), _jsx("path", { id: "Caminho_17679", "data-name": "Caminho 17679", d: "M21.176,18.088A4.588,4.588,0,1,1,16.588,13.5,4.588,4.588,0,0,1,21.176,18.088Z", transform: "translate(-2.471 -2.118)", fill: "none", stroke: stroke, strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "1.5" })] }) }));
|
|
5
5
|
};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { EditFileUploaderI } from '../../interfaces';
|
|
2
|
-
export declare const MobileFileUploader: ({ handleInputChange, ...props }: EditFileUploaderI) => import("react/jsx-runtime").JSX.Element;
|
|
2
|
+
export declare const MobileFileUploader: ({ handleInputChange, multiple, ...props }: EditFileUploaderI) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -15,7 +15,7 @@ import { t } from 'i18next';
|
|
|
15
15
|
import { IconButton } from '@chakra-ui/react';
|
|
16
16
|
import { Camera } from '..';
|
|
17
17
|
export const MobileFileUploader = (_a) => {
|
|
18
|
-
var { handleInputChange } = _a, props = __rest(_a, ["handleInputChange"]);
|
|
18
|
+
var { handleInputChange, multiple = true } = _a, props = __rest(_a, ["handleInputChange", "multiple"]);
|
|
19
19
|
const hiddenFileInput = useRef(null);
|
|
20
|
-
return (_jsxs(_Fragment, { children: [_jsx(IconButton, Object.assign({}, props, { variant: "iconOutlined", h: "
|
|
20
|
+
return (_jsxs(_Fragment, { children: [_jsx(IconButton, Object.assign({}, props, { variant: "iconOutlined", minH: "40px", h: "full", icon: _jsx(Camera, {}), onClick: () => { var _a; return (_a = hiddenFileInput === null || hiddenFileInput === void 0 ? void 0 : hiddenFileInput.current) === null || _a === void 0 ? void 0 : _a.click(); } })), _jsx("input", { style: { display: 'none' }, accept: "image/*", type: "file", name: "imageUpload", ref: hiddenFileInput, placeholder: t('addMedia.placeholder'), onChange: handleInputChange, multiple: multiple })] }));
|
|
21
21
|
};
|
|
@@ -35,7 +35,7 @@ export const useFilesUploader = ({ onUpload, uploading, displayImages = [], }) =
|
|
|
35
35
|
}
|
|
36
36
|
}, [hasError]);
|
|
37
37
|
useEffect(() => {
|
|
38
|
-
onUpload(acceptedFiles);
|
|
38
|
+
onUpload === null || onUpload === void 0 ? void 0 : onUpload(acceptedFiles);
|
|
39
39
|
}, [acceptedFiles]);
|
|
40
40
|
useEffect(() => {
|
|
41
41
|
setIsUploading(uploading);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { FolderFileI, MenuItemI, PartnerFooterI, TileCtaI } from '../..';
|
|
2
|
-
export type KindTypes = 'checkbox' | 'checkbox-agreement' | 'checkbox-group' | 'currency' | 'date' | 'email' | 'file' | 'grid' | 'group' | 'hidden' | 'notes' | 'number' | 'radio' | 'rating' | 'select' | 'string' | 'switch' | 'telephone' | 'text' | 'textarea' | 'default' | UIKindTypes | HomeItemTypes;
|
|
1
|
+
import { AIGridFieldI, FolderFileI, MenuItemI, PartnerFooterI, TileCtaI } from '../..';
|
|
2
|
+
export type KindTypes = 'ai-image' | 'ai-grid' | 'checkbox' | 'checkbox-agreement' | 'checkbox-group' | 'currency' | 'date' | 'email' | 'file' | 'grid' | 'group' | 'hidden' | 'notes' | 'number' | 'radio' | 'rating' | 'select' | 'string' | 'switch' | 'telephone' | 'text' | 'textarea' | 'default' | UIKindTypes | HomeItemTypes;
|
|
3
3
|
export type UIKindTypes = 'tile-body' | 'tile-body-logo' | 'tile-body-header' | 'tile-body-section' | 'tile-body-section-grid' | 'tile-form' | 'tile-body-action' | 'vertical-icon' | 'primary-cta' | 'secondary-cta';
|
|
4
4
|
export type HomeItemTypes = 'appliances' | 'images' | 'guidelines' | 'item-related' | 'item-icon-btn';
|
|
5
5
|
export type IconTypes = 'barcode' | 'battery' | 'billing' | 'book' | 'book-opened' | 'calc' | 'calendar' | 'check' | 'co2' | 'contact' | 'date' | 'default' | 'detector' | 'electricity' | 'goldbars' | 'heart' | 'image' | 'notes' | 'palette' | 'people' | 'price' | 'rating' | 'receipt' | 'registry' | 'sprinkler' | 'tools' | 'wind' | '68' | 'calendar2' | 'water' | 'calendar-drop' | 'umbrella' | 'heater' | 'roof' | 'foundation' | 'solar-panel' | 'pool' | 'drop' | 'mobile-drop' | 'light' | 'plate' | 'pressure-washer' | 'house' | 'target' | 'title' | 'company' | UIIconTypes;
|
|
@@ -25,6 +25,7 @@ export interface DynamicFormI extends Partial<PartnerFooterI> {
|
|
|
25
25
|
displayImages?: string[];
|
|
26
26
|
form: ReportI[];
|
|
27
27
|
menuItems?: MenuItemI[];
|
|
28
|
+
onAISend?: AIGridFieldI['onAISend'];
|
|
28
29
|
onRemoveImage?: (file: string) => void;
|
|
29
30
|
onUpload?: (filesByFieldId: Record<string, FolderFileI[]>) => void;
|
|
30
31
|
showTitle?: boolean;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { FolderFileI, ReportI } from '../../..';
|
|
2
2
|
export interface FileFieldI extends Pick<ReportI, 'description' | 'icon'> {
|
|
3
3
|
onRemove?: (file: string) => void;
|
|
4
|
-
onUpload
|
|
4
|
+
onUpload?: (files: FolderFileI[]) => void;
|
|
5
5
|
uploading?: boolean;
|
|
6
6
|
displayImages?: string[];
|
|
7
|
+
value?: string;
|
|
7
8
|
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { FolderFileI, ReportI } from '../../..';
|
|
2
|
+
export interface GridFieldI {
|
|
3
|
+
children: ReportI['children'];
|
|
4
|
+
onRemove?: (file: string) => void;
|
|
5
|
+
onUpload?: (files: FolderFileI[]) => void;
|
|
6
|
+
}
|
|
7
|
+
export interface AIGridFieldI extends GridFieldI {
|
|
8
|
+
onAISend?: (form?: AIFormI) => void;
|
|
9
|
+
}
|
|
10
|
+
interface AIFormI {
|
|
11
|
+
code?: string;
|
|
12
|
+
image?: string;
|
|
13
|
+
}
|
|
14
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -2,6 +2,7 @@ export * from './DateField.interface';
|
|
|
2
2
|
export * from './FieldDescription.interface';
|
|
3
3
|
export * from './FieldWithDelete.interface';
|
|
4
4
|
export * from './FileField.interface';
|
|
5
|
+
export * from './GridField.interface';
|
|
5
6
|
export * from './GroupField.interface';
|
|
6
7
|
export * from './RatingField.interface';
|
|
7
8
|
export * from './SelectField.interface';
|
|
@@ -2,6 +2,7 @@ export * from './DateField.interface';
|
|
|
2
2
|
export * from './FieldDescription.interface';
|
|
3
3
|
export * from './FieldWithDelete.interface';
|
|
4
4
|
export * from './FileField.interface';
|
|
5
|
+
export * from './GridField.interface';
|
|
5
6
|
export * from './GroupField.interface';
|
|
6
7
|
export * from './RatingField.interface';
|
|
7
8
|
export * from './SelectField.interface';
|
|
@@ -9,6 +9,34 @@ export const formFieldsMock = [
|
|
|
9
9
|
type: 'checkbox-agreement',
|
|
10
10
|
visible: true,
|
|
11
11
|
},
|
|
12
|
+
{
|
|
13
|
+
id: faker.database.mongodbObjectId(),
|
|
14
|
+
name: 'ai form',
|
|
15
|
+
description: 'Add item details',
|
|
16
|
+
value: false,
|
|
17
|
+
type: 'ai-grid',
|
|
18
|
+
visible: true,
|
|
19
|
+
children: [
|
|
20
|
+
{
|
|
21
|
+
id: faker.database.mongodbObjectId(),
|
|
22
|
+
name: 'Model or Serial',
|
|
23
|
+
description: faker.lorem.sentence(),
|
|
24
|
+
comments: faker.lorem.sentence(),
|
|
25
|
+
value: '',
|
|
26
|
+
type: 'text',
|
|
27
|
+
visible: true,
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
id: faker.database.mongodbObjectId(),
|
|
31
|
+
name: 'uploder',
|
|
32
|
+
description: faker.lorem.sentence(),
|
|
33
|
+
comments: faker.lorem.sentence(),
|
|
34
|
+
value: faker.image.urlPicsumPhotos(),
|
|
35
|
+
type: 'ai-image',
|
|
36
|
+
visible: true,
|
|
37
|
+
},
|
|
38
|
+
],
|
|
39
|
+
},
|
|
12
40
|
{
|
|
13
41
|
id: faker.database.mongodbObjectId(),
|
|
14
42
|
name: '',
|
|
@@ -137,7 +165,7 @@ export const formFieldsMock = [
|
|
|
137
165
|
name: 'Purchase Date',
|
|
138
166
|
description: faker.lorem.sentence(),
|
|
139
167
|
comments: faker.lorem.sentence(),
|
|
140
|
-
value:
|
|
168
|
+
value: '',
|
|
141
169
|
type: 'date',
|
|
142
170
|
visible: true,
|
|
143
171
|
},
|
|
@@ -240,7 +268,7 @@ export const formFieldsMock = [
|
|
|
240
268
|
name: 'Due Date',
|
|
241
269
|
description: faker.lorem.sentence(),
|
|
242
270
|
comments: faker.lorem.sentence(),
|
|
243
|
-
value:
|
|
271
|
+
value: '',
|
|
244
272
|
type: 'date',
|
|
245
273
|
visible: true,
|
|
246
274
|
icon: 'date',
|
|
@@ -19,6 +19,7 @@ export default {
|
|
|
19
19
|
faker.image.urlPicsumPhotos(),
|
|
20
20
|
faker.image.urlPicsumPhotos(),
|
|
21
21
|
],
|
|
22
|
+
onAiSend: action('onAiSend'),
|
|
22
23
|
onUpload: action('onUpload'),
|
|
23
24
|
menuItems: menuMock,
|
|
24
25
|
socialLinks: socialLinksMock,
|
|
@@ -26,7 +27,7 @@ export default {
|
|
|
26
27
|
},
|
|
27
28
|
};
|
|
28
29
|
export const DynamicFormComponent = (args) => {
|
|
29
|
-
return (_jsx(Box, { p: "base", bg: "neutral.white", w: ['full', '500px'], children: _jsx(DynamicForm, Object.assign({}, args, { form: formFieldsMock })) }));
|
|
30
|
+
return (_jsx(Box, { p: "base", bg: "neutral.white", w: ['full', '500px'], children: _jsx(DynamicForm, Object.assign({}, args, { form: formFieldsMock, showTitle: false })) }));
|
|
30
31
|
};
|
|
31
32
|
export const DynamicUIFormComponent = (args) => {
|
|
32
33
|
return (_jsx(Box, { m: "base", w: ['full', '320px'], children: _jsx(DynamicForm, Object.assign({}, args, { form: tileUIMock, showTitle: false, callback: action('callback') })) }));
|
package/package.json
CHANGED
|
@@ -19,6 +19,7 @@ import {
|
|
|
19
19
|
TileBody,
|
|
20
20
|
CheckboxGroupField,
|
|
21
21
|
CheckboxAgreement,
|
|
22
|
+
AIGridField,
|
|
22
23
|
} from '@/components'
|
|
23
24
|
import { useDynamicForm } from '@/hooks'
|
|
24
25
|
import { fieldIcons } from '@/helpers'
|
|
@@ -28,6 +29,7 @@ export const DynamicForm = ({
|
|
|
28
29
|
displayImages,
|
|
29
30
|
form: fields,
|
|
30
31
|
menuItems,
|
|
32
|
+
onAISend,
|
|
31
33
|
onRemoveImage,
|
|
32
34
|
onUpload,
|
|
33
35
|
showTitle = true,
|
|
@@ -77,7 +79,7 @@ export const DynamicForm = ({
|
|
|
77
79
|
id,
|
|
78
80
|
value,
|
|
79
81
|
icon: icon ? (fieldIcons[icon] as IconTypes) : undefined,
|
|
80
|
-
placeholder: (name
|
|
82
|
+
placeholder: Boolean(name) ? name : description,
|
|
81
83
|
}
|
|
82
84
|
const fieldWithDeleteBaseProps = {
|
|
83
85
|
id,
|
|
@@ -140,6 +142,22 @@ export const DynamicForm = ({
|
|
|
140
142
|
<RatingField {...baseProps} />
|
|
141
143
|
</FieldWithDelete>
|
|
142
144
|
)
|
|
145
|
+
case 'ai-grid':
|
|
146
|
+
return (
|
|
147
|
+
<Stack key={id} p="base" spacing="base" bg="lightBlue.2">
|
|
148
|
+
{description && (
|
|
149
|
+
<Text fontFamily="secondary">{description}</Text>
|
|
150
|
+
)}
|
|
151
|
+
<AIGridField
|
|
152
|
+
{...baseProps}
|
|
153
|
+
onRemove={onRemoveImage}
|
|
154
|
+
onUpload={(files) => handleFilesUpload({ id, files })}
|
|
155
|
+
onAISend={onAISend}
|
|
156
|
+
>
|
|
157
|
+
{children}
|
|
158
|
+
</AIGridField>
|
|
159
|
+
</Stack>
|
|
160
|
+
)
|
|
143
161
|
case 'grid':
|
|
144
162
|
return (
|
|
145
163
|
<FieldWithDelete {...fieldWithDeleteBaseProps} key={id}>
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { useFormContext } from 'react-hook-form'
|
|
2
|
+
import { Flex, IconButton, Text } from '@chakra-ui/react'
|
|
3
|
+
import { IconTypes, AIGridFieldI } from '@/interfaces'
|
|
4
|
+
import { TextField, SingleImage, Plus } from '@/components'
|
|
5
|
+
import { fieldIcons } from '@/helpers'
|
|
6
|
+
import { colors } from '@/theme/colors'
|
|
7
|
+
|
|
8
|
+
export const AIGridField = ({
|
|
9
|
+
children,
|
|
10
|
+
onAISend,
|
|
11
|
+
onRemove,
|
|
12
|
+
onUpload,
|
|
13
|
+
}: AIGridFieldI) => {
|
|
14
|
+
const { watch } = useFormContext()
|
|
15
|
+
|
|
16
|
+
const textChild = children?.find(
|
|
17
|
+
({ type }) => type === 'text' || type === 'string'
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
const textProps = {
|
|
21
|
+
id: textChild?.id ?? '',
|
|
22
|
+
value: textChild?.value ?? '',
|
|
23
|
+
placeholder: textChild?.name ?? textChild?.description,
|
|
24
|
+
icon: textChild?.icon
|
|
25
|
+
? (fieldIcons[textChild.icon] as IconTypes)
|
|
26
|
+
: undefined,
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const imageField = children?.find(({ type }) => type === 'ai-image')
|
|
30
|
+
|
|
31
|
+
const imageProps = {
|
|
32
|
+
id: imageField?.id ?? '',
|
|
33
|
+
value: imageField?.value ?? '',
|
|
34
|
+
placeholder: imageField?.name ?? imageField?.description,
|
|
35
|
+
icon: imageField?.icon
|
|
36
|
+
? (fieldIcons[imageField.icon] as IconTypes)
|
|
37
|
+
: undefined,
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const code = watch(String(textChild?.id))
|
|
41
|
+
|
|
42
|
+
const handleAISend = () => {
|
|
43
|
+
const form = {
|
|
44
|
+
code,
|
|
45
|
+
image: imageField?.value as string,
|
|
46
|
+
}
|
|
47
|
+
onAISend?.(form)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return (
|
|
51
|
+
<Flex align="center" gap="base">
|
|
52
|
+
<SingleImage
|
|
53
|
+
{...imageProps}
|
|
54
|
+
onUpload={onUpload}
|
|
55
|
+
onRemove={onRemove}
|
|
56
|
+
value={imageField?.value as string}
|
|
57
|
+
/>
|
|
58
|
+
<Text fontFamily="secondary" textAlign="center">
|
|
59
|
+
OR
|
|
60
|
+
</Text>
|
|
61
|
+
<TextField {...textProps} />
|
|
62
|
+
<IconButton
|
|
63
|
+
aria-label="Add new address line"
|
|
64
|
+
variant="iconOutlined"
|
|
65
|
+
icon={<Plus size={28} stroke={colors.blue[3]} />}
|
|
66
|
+
onClick={handleAISend}
|
|
67
|
+
h="input.md"
|
|
68
|
+
disabled={!code?.length && !imageField?.value}
|
|
69
|
+
/>
|
|
70
|
+
</Flex>
|
|
71
|
+
)
|
|
72
|
+
}
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
import { Flex } from '@chakra-ui/react'
|
|
2
|
-
import { IconTypes,
|
|
2
|
+
import { IconTypes, GridFieldI } from '@/interfaces'
|
|
3
3
|
import {
|
|
4
4
|
DateField,
|
|
5
5
|
NumberField,
|
|
6
6
|
TextField,
|
|
7
7
|
SelectField,
|
|
8
8
|
CurrencyField,
|
|
9
|
+
SingleImage,
|
|
9
10
|
} from '@/components'
|
|
10
11
|
import { fieldIcons } from '@/helpers'
|
|
11
12
|
|
|
12
|
-
export const GridField = ({ children }:
|
|
13
|
+
export const GridField = ({ children, onRemove, onUpload }: GridFieldI) => {
|
|
13
14
|
return (
|
|
14
15
|
<Flex align="stretch" gap="base">
|
|
15
16
|
{children?.map(
|
|
@@ -17,7 +18,7 @@ export const GridField = ({ children }: Pick<ReportI, 'children'>) => {
|
|
|
17
18
|
const baseProps = {
|
|
18
19
|
id,
|
|
19
20
|
value,
|
|
20
|
-
placeholder:
|
|
21
|
+
placeholder: name && name !== '' ? name : description,
|
|
21
22
|
icon: icon ? (fieldIcons[icon] as IconTypes) : undefined,
|
|
22
23
|
}
|
|
23
24
|
|
|
@@ -45,6 +46,16 @@ export const GridField = ({ children }: Pick<ReportI, 'children'>) => {
|
|
|
45
46
|
return <SelectField {...baseProps} key={id} options={options} />
|
|
46
47
|
case 'telephone':
|
|
47
48
|
return <TextField {...baseProps} key={id} type="tel" />
|
|
49
|
+
case 'ai-image':
|
|
50
|
+
return (
|
|
51
|
+
<SingleImage
|
|
52
|
+
{...baseProps}
|
|
53
|
+
key={id}
|
|
54
|
+
onUpload={onUpload}
|
|
55
|
+
onRemove={onRemove}
|
|
56
|
+
value={value as string}
|
|
57
|
+
/>
|
|
58
|
+
)
|
|
48
59
|
default:
|
|
49
60
|
return null
|
|
50
61
|
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { ChangeEvent } from 'react'
|
|
2
|
+
import { AspectRatio, Box, Flex, IconButton, Image } from '@chakra-ui/react'
|
|
3
|
+
import { colors } from '@/theme/colors'
|
|
4
|
+
import { Close, MobileFileUploader } from '@/components'
|
|
5
|
+
import { FileFieldI } from '@/interfaces'
|
|
6
|
+
import { handleMapFile } from '@/utils'
|
|
7
|
+
|
|
8
|
+
export const SingleImage = ({
|
|
9
|
+
onRemove,
|
|
10
|
+
onUpload,
|
|
11
|
+
uploading = false,
|
|
12
|
+
value,
|
|
13
|
+
}: FileFieldI) => {
|
|
14
|
+
const handleInputChange = (event: ChangeEvent<HTMLInputElement>) => {
|
|
15
|
+
const fileList = event.target.files ?? []
|
|
16
|
+
const files = Array.from(fileList)
|
|
17
|
+
if (files.length > 0) {
|
|
18
|
+
const selectedFiles = handleMapFile({ files })
|
|
19
|
+
onUpload?.(selectedFiles)
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
return (
|
|
24
|
+
<Flex gap="2" align="center" h="input.md">
|
|
25
|
+
<MobileFileUploader
|
|
26
|
+
handleInputChange={handleInputChange}
|
|
27
|
+
aria-label="upload image"
|
|
28
|
+
minW="72px"
|
|
29
|
+
/>
|
|
30
|
+
{value && (
|
|
31
|
+
<Box position="relative" minW="30px">
|
|
32
|
+
<IconButton
|
|
33
|
+
variant="ghost"
|
|
34
|
+
aria-label="close"
|
|
35
|
+
maxW="fit-content"
|
|
36
|
+
onClick={() => onRemove?.(value)}
|
|
37
|
+
icon={<Close size={11} stroke={colors.error['2']} />}
|
|
38
|
+
disabled={uploading}
|
|
39
|
+
position="absolute"
|
|
40
|
+
bg="neutral.white"
|
|
41
|
+
p="0.5"
|
|
42
|
+
borderRadius="full"
|
|
43
|
+
top="-2"
|
|
44
|
+
right="-2"
|
|
45
|
+
zIndex="1"
|
|
46
|
+
/>
|
|
47
|
+
<AspectRatio maxW="100%" ratio={1}>
|
|
48
|
+
<Image src={value} objectFit="cover" alt="image" />
|
|
49
|
+
</AspectRatio>
|
|
50
|
+
</Box>
|
|
51
|
+
)}
|
|
52
|
+
</Flex>
|
|
53
|
+
)
|
|
54
|
+
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export * from './AIGridField'
|
|
1
2
|
export * from './CheckboxAgreement'
|
|
2
3
|
export * from './CheckboxGroupField'
|
|
3
4
|
export * from './CurrencyField'
|
|
@@ -13,6 +14,7 @@ export * from './SwitchField'
|
|
|
13
14
|
export * from './RatingField'
|
|
14
15
|
export * from './SelectField'
|
|
15
16
|
export * from './SingleFields'
|
|
17
|
+
export * from './SingleImage'
|
|
16
18
|
export * from './TextAreaField'
|
|
17
19
|
export * from './TextField'
|
|
18
20
|
export * from './TileBodyFields'
|
|
@@ -6,10 +6,36 @@ export const Camera = ({ stroke = colors.blue[3], size = 24 }) => {
|
|
|
6
6
|
xmlns="http://www.w3.org/2000/svg"
|
|
7
7
|
width={size}
|
|
8
8
|
height={size}
|
|
9
|
-
|
|
10
|
-
viewBox="0 0 256 256"
|
|
9
|
+
viewBox="0 0 26.734 22.146"
|
|
11
10
|
>
|
|
12
|
-
<
|
|
11
|
+
<g
|
|
12
|
+
id="Icon_feather-camera"
|
|
13
|
+
data-name="Icon feather-camera"
|
|
14
|
+
transform="translate(-0.75 -3.75)"
|
|
15
|
+
>
|
|
16
|
+
<path
|
|
17
|
+
id="Caminho_17678"
|
|
18
|
+
data-name="Caminho 17678"
|
|
19
|
+
d="M26.735,22.852a2.294,2.294,0,0,1-2.294,2.294H3.794A2.294,2.294,0,0,1,1.5,22.852V10.235A2.294,2.294,0,0,1,3.794,7.941H8.382L10.676,4.5h6.882l2.294,3.441H24.44a2.294,2.294,0,0,1,2.294,2.294Z"
|
|
20
|
+
transform="translate(0 0)"
|
|
21
|
+
fill="none"
|
|
22
|
+
stroke={stroke}
|
|
23
|
+
strokeLinecap="round"
|
|
24
|
+
strokeLinejoin="round"
|
|
25
|
+
strokeWidth="1.5"
|
|
26
|
+
/>
|
|
27
|
+
<path
|
|
28
|
+
id="Caminho_17679"
|
|
29
|
+
data-name="Caminho 17679"
|
|
30
|
+
d="M21.176,18.088A4.588,4.588,0,1,1,16.588,13.5,4.588,4.588,0,0,1,21.176,18.088Z"
|
|
31
|
+
transform="translate(-2.471 -2.118)"
|
|
32
|
+
fill="none"
|
|
33
|
+
stroke={stroke}
|
|
34
|
+
strokeLinecap="round"
|
|
35
|
+
strokeLinejoin="round"
|
|
36
|
+
strokeWidth="1.5"
|
|
37
|
+
/>
|
|
38
|
+
</g>
|
|
13
39
|
</svg>
|
|
14
40
|
)
|
|
15
41
|
}
|
|
@@ -6,6 +6,7 @@ import { EditFileUploaderI } from '@/interfaces'
|
|
|
6
6
|
|
|
7
7
|
export const MobileFileUploader = ({
|
|
8
8
|
handleInputChange,
|
|
9
|
+
multiple = true,
|
|
9
10
|
...props
|
|
10
11
|
}: EditFileUploaderI) => {
|
|
11
12
|
const hiddenFileInput = useRef<HTMLInputElement | null>(null)
|
|
@@ -14,7 +15,8 @@ export const MobileFileUploader = ({
|
|
|
14
15
|
<IconButton
|
|
15
16
|
{...props}
|
|
16
17
|
variant="iconOutlined"
|
|
17
|
-
|
|
18
|
+
minH="40px"
|
|
19
|
+
h="full"
|
|
18
20
|
icon={<Camera />}
|
|
19
21
|
onClick={() => hiddenFileInput?.current?.click()}
|
|
20
22
|
/>
|
|
@@ -26,6 +28,7 @@ export const MobileFileUploader = ({
|
|
|
26
28
|
ref={hiddenFileInput}
|
|
27
29
|
placeholder={t('addMedia.placeholder')}
|
|
28
30
|
onChange={handleInputChange}
|
|
31
|
+
multiple={multiple}
|
|
29
32
|
/>
|
|
30
33
|
</>
|
|
31
34
|
)
|
|
@@ -5,7 +5,7 @@ import { useEffect, useState } from 'react'
|
|
|
5
5
|
import { useDropzone } from 'react-dropzone'
|
|
6
6
|
|
|
7
7
|
interface FilesUploaderHookI {
|
|
8
|
-
onUpload
|
|
8
|
+
onUpload?: (files: FolderFileI[]) => void
|
|
9
9
|
uploading: boolean
|
|
10
10
|
displayImages?: string[]
|
|
11
11
|
}
|
|
@@ -55,7 +55,7 @@ export const useFilesUploader = ({
|
|
|
55
55
|
}, [hasError])
|
|
56
56
|
|
|
57
57
|
useEffect(() => {
|
|
58
|
-
onUpload(acceptedFiles)
|
|
58
|
+
onUpload?.(acceptedFiles)
|
|
59
59
|
}, [acceptedFiles])
|
|
60
60
|
|
|
61
61
|
useEffect(() => {
|
|
@@ -1,6 +1,14 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
AIGridFieldI,
|
|
3
|
+
FolderFileI,
|
|
4
|
+
MenuItemI,
|
|
5
|
+
PartnerFooterI,
|
|
6
|
+
TileCtaI,
|
|
7
|
+
} from '@/interfaces'
|
|
2
8
|
|
|
3
9
|
export type KindTypes =
|
|
10
|
+
| 'ai-image'
|
|
11
|
+
| 'ai-grid'
|
|
4
12
|
| 'checkbox'
|
|
5
13
|
| 'checkbox-agreement'
|
|
6
14
|
| 'checkbox-group'
|
|
@@ -125,6 +133,7 @@ export interface DynamicFormI extends Partial<PartnerFooterI> {
|
|
|
125
133
|
displayImages?: string[]
|
|
126
134
|
form: ReportI[]
|
|
127
135
|
menuItems?: MenuItemI[]
|
|
136
|
+
onAISend?: AIGridFieldI['onAISend']
|
|
128
137
|
onRemoveImage?: (file: string) => void
|
|
129
138
|
onUpload?: (filesByFieldId: Record<string, FolderFileI[]>) => void
|
|
130
139
|
showTitle?: boolean
|
|
@@ -2,7 +2,8 @@ import { FolderFileI, ReportI } from '@/interfaces'
|
|
|
2
2
|
|
|
3
3
|
export interface FileFieldI extends Pick<ReportI, 'description' | 'icon'> {
|
|
4
4
|
onRemove?: (file: string) => void
|
|
5
|
-
onUpload
|
|
5
|
+
onUpload?: (files: FolderFileI[]) => void
|
|
6
6
|
uploading?: boolean
|
|
7
7
|
displayImages?: string[]
|
|
8
|
+
value?: string
|
|
8
9
|
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { FolderFileI, ReportI } from '@/interfaces'
|
|
2
|
+
|
|
3
|
+
export interface GridFieldI {
|
|
4
|
+
children: ReportI['children']
|
|
5
|
+
onRemove?: (file: string) => void
|
|
6
|
+
onUpload?: (files: FolderFileI[]) => void
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface AIGridFieldI extends GridFieldI {
|
|
10
|
+
onAISend?: (form?: AIFormI) => void
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
interface AIFormI {
|
|
14
|
+
code?: string
|
|
15
|
+
image?: string
|
|
16
|
+
}
|
|
@@ -2,6 +2,7 @@ export * from './DateField.interface'
|
|
|
2
2
|
export * from './FieldDescription.interface'
|
|
3
3
|
export * from './FieldWithDelete.interface'
|
|
4
4
|
export * from './FileField.interface'
|
|
5
|
+
export * from './GridField.interface'
|
|
5
6
|
export * from './GroupField.interface'
|
|
6
7
|
export * from './RatingField.interface'
|
|
7
8
|
export * from './SelectField.interface'
|
|
@@ -12,6 +12,34 @@ export const formFieldsMock: ReportI[] = [
|
|
|
12
12
|
type: 'checkbox-agreement',
|
|
13
13
|
visible: true,
|
|
14
14
|
},
|
|
15
|
+
{
|
|
16
|
+
id: faker.database.mongodbObjectId(),
|
|
17
|
+
name: 'ai form',
|
|
18
|
+
description: 'Add item details',
|
|
19
|
+
value: false,
|
|
20
|
+
type: 'ai-grid',
|
|
21
|
+
visible: true,
|
|
22
|
+
children: [
|
|
23
|
+
{
|
|
24
|
+
id: faker.database.mongodbObjectId(),
|
|
25
|
+
name: 'Model or Serial',
|
|
26
|
+
description: faker.lorem.sentence(),
|
|
27
|
+
comments: faker.lorem.sentence(),
|
|
28
|
+
value: '',
|
|
29
|
+
type: 'text',
|
|
30
|
+
visible: true,
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
id: faker.database.mongodbObjectId(),
|
|
34
|
+
name: 'uploder',
|
|
35
|
+
description: faker.lorem.sentence(),
|
|
36
|
+
comments: faker.lorem.sentence(),
|
|
37
|
+
value: faker.image.urlPicsumPhotos(),
|
|
38
|
+
type: 'ai-image',
|
|
39
|
+
visible: true,
|
|
40
|
+
},
|
|
41
|
+
],
|
|
42
|
+
},
|
|
15
43
|
{
|
|
16
44
|
id: faker.database.mongodbObjectId(),
|
|
17
45
|
name: '',
|
|
@@ -140,7 +168,7 @@ export const formFieldsMock: ReportI[] = [
|
|
|
140
168
|
name: 'Purchase Date',
|
|
141
169
|
description: faker.lorem.sentence(),
|
|
142
170
|
comments: faker.lorem.sentence(),
|
|
143
|
-
value:
|
|
171
|
+
value: '',
|
|
144
172
|
type: 'date',
|
|
145
173
|
visible: true,
|
|
146
174
|
},
|
|
@@ -243,7 +271,7 @@ export const formFieldsMock: ReportI[] = [
|
|
|
243
271
|
name: 'Due Date',
|
|
244
272
|
description: faker.lorem.sentence(),
|
|
245
273
|
comments: faker.lorem.sentence(),
|
|
246
|
-
value:
|
|
274
|
+
value: '',
|
|
247
275
|
type: 'date',
|
|
248
276
|
visible: true,
|
|
249
277
|
icon: 'date',
|
|
@@ -21,6 +21,7 @@ export default {
|
|
|
21
21
|
faker.image.urlPicsumPhotos(),
|
|
22
22
|
faker.image.urlPicsumPhotos(),
|
|
23
23
|
],
|
|
24
|
+
onAiSend: action('onAiSend'),
|
|
24
25
|
onUpload: action('onUpload'),
|
|
25
26
|
menuItems: menuMock,
|
|
26
27
|
socialLinks: socialLinksMock,
|
|
@@ -31,7 +32,7 @@ export default {
|
|
|
31
32
|
export const DynamicFormComponent = (args: DynamicFormI) => {
|
|
32
33
|
return (
|
|
33
34
|
<Box p="base" bg="neutral.white" w={['full', '500px']}>
|
|
34
|
-
<DynamicForm {...args} form={formFieldsMock} />
|
|
35
|
+
<DynamicForm {...args} form={formFieldsMock} showTitle={false} />
|
|
35
36
|
</Box>
|
|
36
37
|
)
|
|
37
38
|
}
|