form-craft-package 1.7.9-dev.1 → 1.7.9-dev.2
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/package.json +2 -1
- package/src/components/common/custom-hooks/use-find-dynamic-form.hook.ts +30 -11
- package/src/components/common/custom-hooks/use-many-to-many-connector.hook.ts +30 -0
- package/src/components/common/not-found.tsx +21 -0
- package/src/components/companies/1-authenticated/change-password.tsx +1 -1
- package/src/components/form/1-list/index.tsx +4 -5
- package/src/components/form/1-list/table-header.tsx +5 -5
- package/src/components/form/1-list/table.tsx +10 -12
- package/src/components/form/2-details/index.tsx +53 -40
- package/src/components/form/layout-renderer/1-row/index.tsx +2 -1
- package/src/components/form/layout-renderer/3-element/1-dynamic-button/index.tsx +57 -87
- package/src/components/form/layout-renderer/3-element/1-dynamic-button/use-button-navigate.hook.tsx +88 -0
- package/src/components/form/layout-renderer/3-element/1-dynamic-button/use-create-data.hook.ts +22 -23
- package/src/components/form/layout-renderer/3-element/1-dynamic-button/use-generate-report.hook.tsx +3 -4
- package/src/components/form/layout-renderer/3-element/1-dynamic-button/use-save-data.hook.ts +2 -2
- package/src/components/form/layout-renderer/3-element/11-breadcrumb.tsx +3 -2
- package/src/components/form/layout-renderer/3-element/2-field-element.tsx +4 -1
- package/src/components/form/layout-renderer/3-element/8-fields-with-options.tsx +9 -12
- package/src/components/form/layout-renderer/3-element/9-form-data-render.tsx +48 -79
- package/src/components/modals/report-filters.modal/helper-functions.ts +3 -6
- package/src/constants.ts +7 -1
- package/src/enums/form.enum.ts +5 -3
- package/src/functions/forms/breadcrumb-handlers.ts +21 -0
- package/src/functions/forms/data-render-functions.tsx +1 -0
- package/src/functions/forms/extended-json-handlers.ts +56 -0
- package/src/functions/forms/index.ts +17 -11
- package/src/functions/reports/index.tsx +2 -1
- package/src/types/forms/index.ts +1 -0
- package/src/types/forms/layout-elements/button.ts +11 -3
- package/src/types/forms/layout-elements/index.ts +6 -2
- package/src/types/forms/layout-elements/sanitization.ts +6 -1
- package/src/types/forms/relationship/index.ts +12 -1
- package/src/functions/forms/json-handlers.ts +0 -19
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "form-craft-package",
|
|
3
|
-
"version": "1.7.9-dev.
|
|
3
|
+
"version": "1.7.9-dev.2",
|
|
4
4
|
"main": "index.ts",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"test": "echo \"Error: no test specified\" && exit 1",
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
"@types/react-google-recaptcha": "^2.1.9",
|
|
15
15
|
"@types/react-signature-canvas": "^1.0.7",
|
|
16
16
|
"ajv": "^8.17.1",
|
|
17
|
+
"bson": "^4.7.2",
|
|
17
18
|
"pdfmake": "^0.2.18",
|
|
18
19
|
"qs": "^6.14.0",
|
|
19
20
|
"react-google-recaptcha": "^3.1.0",
|
|
@@ -1,27 +1,46 @@
|
|
|
1
|
-
import { useState, useEffect } from 'react'
|
|
1
|
+
import { useState, useEffect, useCallback } from 'react'
|
|
2
2
|
import { useParams } from 'react-router-dom'
|
|
3
3
|
import { IDynamicForm } from '../../../types'
|
|
4
4
|
import { LOCAL_STORAGE_KEYS_ENUM } from '../../../enums'
|
|
5
5
|
|
|
6
6
|
export const useFindDynamiForm = () => {
|
|
7
7
|
const { formName } = useParams<{ formName: string }>()
|
|
8
|
-
const [foundItem, setFoundItem] = useState<IDynamicForm |
|
|
8
|
+
const [foundItem, setFoundItem] = useState<IDynamicForm | null | undefined>(undefined)
|
|
9
9
|
|
|
10
10
|
useEffect(() => {
|
|
11
11
|
if (!formName) return
|
|
12
12
|
|
|
13
13
|
try {
|
|
14
|
-
const
|
|
15
|
-
if (
|
|
16
|
-
const
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
|
|
14
|
+
const stored = localStorage.getItem(LOCAL_STORAGE_KEYS_ENUM.DynamicForms)
|
|
15
|
+
if (stored) {
|
|
16
|
+
const list: IDynamicForm[] = JSON.parse(stored)
|
|
17
|
+
const match = list.find((entry) => entry.name.split(' ').join('-').toLowerCase() === formName)
|
|
18
|
+
setFoundItem(match ?? null)
|
|
19
|
+
} else {
|
|
20
|
+
setFoundItem(null)
|
|
20
21
|
}
|
|
21
|
-
} catch (
|
|
22
|
-
console.error('Error reading or parsing
|
|
22
|
+
} catch (err) {
|
|
23
|
+
console.error('Error reading or parsing DynamicForms:', err)
|
|
24
|
+
setFoundItem(null)
|
|
23
25
|
}
|
|
24
26
|
}, [formName])
|
|
25
27
|
|
|
26
|
-
|
|
28
|
+
const getFormById = useCallback((id: number): IDynamicForm | undefined => {
|
|
29
|
+
if (!id) return
|
|
30
|
+
|
|
31
|
+
try {
|
|
32
|
+
const stored = localStorage.getItem(LOCAL_STORAGE_KEYS_ENUM.DynamicForms)
|
|
33
|
+
if (!stored) return undefined
|
|
34
|
+
|
|
35
|
+
const list: IDynamicForm[] = JSON.parse(stored)
|
|
36
|
+
return list.find((entry) => entry.id === id)
|
|
37
|
+
} catch (err) {
|
|
38
|
+
console.error('Error in getFormById reading DynamicForms:', err)
|
|
39
|
+
return
|
|
40
|
+
}
|
|
41
|
+
}, [])
|
|
42
|
+
|
|
43
|
+
const formInfo = foundItem && foundItem.name.split(' ').join('-').toLowerCase() === formName ? foundItem : undefined
|
|
44
|
+
|
|
45
|
+
return { formInfo, getFormById }
|
|
27
46
|
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { useEffect, useMemo } from 'react'
|
|
2
|
+
import { useBreadcrumb } from './use-breadcrumb.hook'
|
|
3
|
+
import { FormInstance } from 'antd'
|
|
4
|
+
import { getForeignKeysFromBreadcrumb } from '../../../functions/forms/breadcrumb-handlers'
|
|
5
|
+
|
|
6
|
+
export const useManyToManyConnector = (formRef: FormInstance) => {
|
|
7
|
+
const { breadcrumbs } = useBreadcrumb()
|
|
8
|
+
|
|
9
|
+
const prevPageBreadcrumb = useMemo(() => {
|
|
10
|
+
if (breadcrumbs.length > 2) {
|
|
11
|
+
const prevPageBreadcrumb = breadcrumbs[breadcrumbs.length - 2]
|
|
12
|
+
const { formDataId, formJoins, manyToManyRelInfo } = prevPageBreadcrumb
|
|
13
|
+
if (!formDataId || !formJoins || !Array.isArray(formJoins) || !manyToManyRelInfo) return
|
|
14
|
+
|
|
15
|
+
return prevPageBreadcrumb
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
return
|
|
19
|
+
}, [breadcrumbs])
|
|
20
|
+
|
|
21
|
+
useEffect(() => {
|
|
22
|
+
if (!prevPageBreadcrumb) return
|
|
23
|
+
|
|
24
|
+
const { foreignKey, foreignKey2 } = getForeignKeysFromBreadcrumb(prevPageBreadcrumb)
|
|
25
|
+
|
|
26
|
+
if (foreignKey && foreignKey2) formRef.setFieldValue(foreignKey, prevPageBreadcrumb.formDataId)
|
|
27
|
+
}, [prevPageBreadcrumb, formRef])
|
|
28
|
+
|
|
29
|
+
return
|
|
30
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Result } from 'antd'
|
|
2
|
+
import { Button_FillerPortal } from './button'
|
|
3
|
+
import { useNavigate } from 'react-router-dom'
|
|
4
|
+
|
|
5
|
+
export default function NotFound() {
|
|
6
|
+
const navigate = useNavigate()
|
|
7
|
+
return (
|
|
8
|
+
<Result
|
|
9
|
+
status="404"
|
|
10
|
+
title="404"
|
|
11
|
+
subTitle="Sorry, the page you visited does not exist."
|
|
12
|
+
extra={
|
|
13
|
+
<div className="grid justify-center grid-cols-[200px]">
|
|
14
|
+
<Button_FillerPortal primary onClick={() => navigate('/d')}>
|
|
15
|
+
Go Back
|
|
16
|
+
</Button_FillerPortal>
|
|
17
|
+
</div>
|
|
18
|
+
}
|
|
19
|
+
/>
|
|
20
|
+
)
|
|
21
|
+
}
|
|
@@ -43,7 +43,7 @@ export const ChangePassword = () => {
|
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
// Validate that the confirm password matches the new password
|
|
46
|
-
const validateConfirmPassword = (_, value: string) => {
|
|
46
|
+
const validateConfirmPassword = (_: any, value: string) => {
|
|
47
47
|
if (!value || value === '') {
|
|
48
48
|
return Promise.resolve()
|
|
49
49
|
}
|
|
@@ -4,9 +4,9 @@ import FormDataListSkeleton_Table from '../../common/loading-skeletons/table'
|
|
|
4
4
|
import { ICustomFunctionCall } from '../layout-renderer/3-element/1-dynamic-button'
|
|
5
5
|
import FormDataListTableComponent, { IDataListLayoutConfig } from './table'
|
|
6
6
|
import { IFormJoin, IFormDataListData, IFormDataListConfig } from '../../../types'
|
|
7
|
+
import { getProjectionKey } from '../../../functions'
|
|
7
8
|
|
|
8
9
|
function FormDataListComponent({
|
|
9
|
-
formName,
|
|
10
10
|
formId,
|
|
11
11
|
userId,
|
|
12
12
|
companyKey,
|
|
@@ -23,7 +23,7 @@ function FormDataListComponent({
|
|
|
23
23
|
const defaultFilterReqDataRef = useRef<IDataListReqData | undefined>(undefined)
|
|
24
24
|
|
|
25
25
|
const attachmentBaseUrl = useMemo(() => `${baseServerUrl}/api/attachment/${companyKey}`, [baseServerUrl, companyKey])
|
|
26
|
-
const headerLayoutContext = { formId, userId, attachmentBaseUrl,
|
|
26
|
+
const headerLayoutContext = { formId, userId, attachmentBaseUrl, companyKey, onCustomFunctionCall }
|
|
27
27
|
|
|
28
28
|
useEffect(() => {
|
|
29
29
|
setLoadings({ initial: true, data: true })
|
|
@@ -45,7 +45,7 @@ function FormDataListComponent({
|
|
|
45
45
|
|
|
46
46
|
if (Array.isArray(columns))
|
|
47
47
|
dataProjectRef.current = columns.reduce(
|
|
48
|
-
(curr, c) => (c.key ? { ...curr, [c.key
|
|
48
|
+
(curr, c) => (c.key ? { ...curr, [getProjectionKey(c.key)]: `$${c.key}` } : curr),
|
|
49
49
|
{},
|
|
50
50
|
)
|
|
51
51
|
if (Array.isArray(formJoins)) formJoinsRef.current = formJoins
|
|
@@ -69,7 +69,7 @@ function FormDataListComponent({
|
|
|
69
69
|
configForFormId: formId,
|
|
70
70
|
dataListConfig: {
|
|
71
71
|
...dataListConfig,
|
|
72
|
-
columns: columns.map((c) => (c.key ? { ...c, key: c.key
|
|
72
|
+
columns: columns.map((c) => (c.key ? { ...c, key: getProjectionKey(c.key) } : c)),
|
|
73
73
|
},
|
|
74
74
|
})
|
|
75
75
|
}
|
|
@@ -127,7 +127,6 @@ function FormDataListComponent({
|
|
|
127
127
|
export { FormDataListComponent }
|
|
128
128
|
|
|
129
129
|
type IFormDataListComponent = {
|
|
130
|
-
formName?: string
|
|
131
130
|
baseServerUrl?: string
|
|
132
131
|
companyKey?: string
|
|
133
132
|
formId?: number
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Form } from 'antd'
|
|
2
2
|
import { ReactNode, useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
|
3
3
|
import dayjs from 'dayjs'
|
|
4
|
-
import { extractFiltersFromLayout } from '../../../functions/forms'
|
|
4
|
+
import { extractFiltersFromLayout, getIdEqualsQuery } from '../../../functions/forms'
|
|
5
5
|
import { DeviceBreakpointEnum, FilterConfigTypeEnum, FormPreservedItemKeys } from '../../../enums'
|
|
6
6
|
import { LayoutRendererRow } from '../layout-renderer/1-row'
|
|
7
7
|
import { VALUE_REPLACEMENT_PLACEHOLDER } from '../../../constants'
|
|
@@ -26,7 +26,7 @@ export default function FormDataListHeaderComponent({
|
|
|
26
26
|
}: IFormDataListHeaderComponent) {
|
|
27
27
|
const [filtersFormRef] = Form.useForm()
|
|
28
28
|
const [filterConfigs, setFilterConfigs] = useState<IFilterNested>({})
|
|
29
|
-
const { userId, formId,
|
|
29
|
+
const { userId, formId, parentFormJoins, formDataId, manyToManyRelInfo, onCustomFunctionCall } = headerLayoutContext
|
|
30
30
|
const isInitialFetchRef = useRef(true)
|
|
31
31
|
|
|
32
32
|
const currentBreakpoint = useGetCurrentBreakpoint()
|
|
@@ -108,8 +108,8 @@ export default function FormDataListHeaderComponent({
|
|
|
108
108
|
}, [filterValues])
|
|
109
109
|
|
|
110
110
|
const formContext = useMemo(
|
|
111
|
-
() => ({ formRef: filtersFormRef,
|
|
112
|
-
[filtersFormRef,
|
|
111
|
+
() => ({ formRef: filtersFormRef, formId, formDataId, parentFormJoins, manyToManyRelInfo }),
|
|
112
|
+
[filtersFormRef, formId, formDataId, parentFormJoins, manyToManyRelInfo],
|
|
113
113
|
)
|
|
114
114
|
|
|
115
115
|
return (
|
|
@@ -172,7 +172,7 @@ const handleFilterValues = async (
|
|
|
172
172
|
|
|
173
173
|
return {
|
|
174
174
|
customFilter: {},
|
|
175
|
-
dynamicFilter: JSON.stringify(
|
|
175
|
+
dynamicFilter: JSON.stringify(getIdEqualsQuery(lastRel.formId, value)),
|
|
176
176
|
}
|
|
177
177
|
}
|
|
178
178
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { useCallback, useEffect, useMemo, useState } from 'react'
|
|
2
2
|
import FormDataListHeaderComponent from './table-header'
|
|
3
3
|
import useDebounced from '../../common/custom-hooks/use-debounce.hook'
|
|
4
|
-
import {
|
|
4
|
+
import { Table } from 'antd'
|
|
5
5
|
import { ICustomFunctionCall } from '../layout-renderer/3-element/1-dynamic-button'
|
|
6
6
|
import { SorterResult } from 'antd/es/table/interface'
|
|
7
7
|
import { generateTableColumns } from '../../../functions/forms'
|
|
@@ -9,8 +9,9 @@ import { useLocation } from 'react-router-dom'
|
|
|
9
9
|
import useGetCurrentBreakpoint from '../../common/custom-hooks/use-window-width.hook'
|
|
10
10
|
import { DeviceBreakpointEnum, FormDataListViewTypeEnum, MongoDbSortOrderEnum } from '../../../enums'
|
|
11
11
|
import { IDataListReqData } from '.'
|
|
12
|
-
import { IFormDataListConfig, IFormDataListData, IFormDataTableColumn
|
|
12
|
+
import { IFormDataListConfig, IFormDataListData, IFormDataTableColumn } from '../../../types'
|
|
13
13
|
import { processOptions } from '../../../functions/forms/get-data-list-option-value'
|
|
14
|
+
import { IFormContext } from '../layout-renderer/1-row'
|
|
14
15
|
|
|
15
16
|
export default function FormDataListTableComponent({
|
|
16
17
|
layoutsConfigs,
|
|
@@ -33,7 +34,9 @@ export default function FormDataListTableComponent({
|
|
|
33
34
|
)
|
|
34
35
|
const [otherConfigs, setOtherConfigs] = useState<Partial<IFormDataListConfig> | undefined>(undefined)
|
|
35
36
|
|
|
36
|
-
|
|
37
|
+
useEffect(() => {
|
|
38
|
+
setFilterReqData(undefined)
|
|
39
|
+
}, [location.pathname])
|
|
37
40
|
|
|
38
41
|
useEffect(() => {
|
|
39
42
|
if (Array.isArray(layoutsConfigs?.dataListConfig.columns)) {
|
|
@@ -64,7 +67,7 @@ export default function FormDataListTableComponent({
|
|
|
64
67
|
async (layoutsConfigs: IDataListLayoutConfig) => {
|
|
65
68
|
const { configForFormId, dataListConfig } = layoutsConfigs!
|
|
66
69
|
|
|
67
|
-
if (configForFormId !== formId) {
|
|
70
|
+
if (configForFormId !== headerLayoutContext.formId) {
|
|
68
71
|
setLoading(false)
|
|
69
72
|
return
|
|
70
73
|
}
|
|
@@ -82,7 +85,7 @@ export default function FormDataListTableComponent({
|
|
|
82
85
|
|
|
83
86
|
setLoading(false)
|
|
84
87
|
},
|
|
85
|
-
[
|
|
88
|
+
[headerLayoutContext, layoutsConfigs],
|
|
86
89
|
)
|
|
87
90
|
|
|
88
91
|
useEffect(() => {
|
|
@@ -170,14 +173,9 @@ type IFormDataListTableComponent = {
|
|
|
170
173
|
|
|
171
174
|
export type IDataListHeaderLayoutContext = {
|
|
172
175
|
userId?: string | number
|
|
173
|
-
formId?: number
|
|
174
176
|
attachmentBaseUrl?: string
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
parentFormJoins?: IFormJoin[]
|
|
178
|
-
formRef?: FormInstance
|
|
179
|
-
companyKey?: string
|
|
180
|
-
} & ICustomFunctionCall
|
|
177
|
+
} & ICustomFunctionCall &
|
|
178
|
+
IFormContext
|
|
181
179
|
|
|
182
180
|
export type IDataListLayoutConfig =
|
|
183
181
|
| {
|
|
@@ -2,17 +2,17 @@ import { Form } from 'antd'
|
|
|
2
2
|
import { useCallback, useEffect, useMemo, useState } from 'react'
|
|
3
3
|
import { IDndLayoutStructure_Responsive, IFormSchema } from '../../../types'
|
|
4
4
|
import { NEW_FORM_DATA_IDENTIFIER } from '../../../constants'
|
|
5
|
-
import { parseJSON } from '../../../functions/forms/json-handlers'
|
|
6
5
|
import { LayoutRendererRow } from '../layout-renderer/1-row'
|
|
7
6
|
import { DynamicFormButtonRender, ICustomFunctionCall } from '../layout-renderer/3-element/1-dynamic-button'
|
|
8
7
|
import FormDataListSkeleton_Details from '../../common/loading-skeletons/details'
|
|
9
8
|
import { useLocation } from 'react-router-dom'
|
|
10
|
-
import {
|
|
11
|
-
import { DeviceBreakpointEnum, FormPreservedItemKeys } from '../../../enums'
|
|
12
|
-
import dayjs from 'dayjs'
|
|
9
|
+
import { fromMongoDbExtendedJSON, isValidMongoDbId, queryParamsToObject } from '../../../functions/forms'
|
|
10
|
+
import { DeviceBreakpointEnum, FormPreservedItemKeys, LOCAL_STORAGE_KEYS_ENUM } from '../../../enums'
|
|
13
11
|
import useGetCurrentBreakpoint from '../../common/custom-hooks/use-window-width.hook'
|
|
14
12
|
import client from '../../../api/client'
|
|
15
13
|
import { useBreadcrumb } from '../../common/custom-hooks/use-breadcrumb.hook'
|
|
14
|
+
import NotFound from '../../common/not-found'
|
|
15
|
+
import { useManyToManyConnector } from '../../common/custom-hooks/use-many-to-many-connector.hook'
|
|
16
16
|
|
|
17
17
|
export default function FormDataDetailsComponent({
|
|
18
18
|
isPublic,
|
|
@@ -30,13 +30,28 @@ export default function FormDataDetailsComponent({
|
|
|
30
30
|
const [formDataRef] = Form.useForm()
|
|
31
31
|
const [loadings, setLoadings] = useState({ layout: true, data: true })
|
|
32
32
|
const [layoutConfig, setLayoutConfig] = useState<IDndLayoutStructure_Responsive>({ elements: {}, layouts: {} })
|
|
33
|
+
const [isNotFound, setIsNotFound] = useState(false)
|
|
34
|
+
useManyToManyConnector(formDataRef)
|
|
33
35
|
|
|
34
36
|
const currentBreakpoint = useGetCurrentBreakpoint()
|
|
35
37
|
|
|
38
|
+
useEffect(() => {
|
|
39
|
+
// for public forms, setting the details form into localStorage, so that buttons work correctly
|
|
40
|
+
if (isPublic)
|
|
41
|
+
localStorage.setItem(LOCAL_STORAGE_KEYS_ENUM.DynamicForms, JSON.stringify([{ id: formId, name: formName }]))
|
|
42
|
+
}, [isPublic, formId, formName])
|
|
43
|
+
|
|
44
|
+
useEffect(() => {
|
|
45
|
+
if (!formDataId || !isValidMongoDbId(formDataId)) setIsNotFound(true)
|
|
46
|
+
}, [formDataId])
|
|
47
|
+
|
|
36
48
|
useEffect(() => {
|
|
37
49
|
const isNewDataPage = formDataId === NEW_FORM_DATA_IDENTIFIER
|
|
38
50
|
const splittedFormName = formName?.split(' ')?.[0] ?? ''
|
|
39
|
-
push({
|
|
51
|
+
push({
|
|
52
|
+
label: isNewDataPage ? `New ${splittedFormName.toLowerCase()}` : `${splittedFormName} details`,
|
|
53
|
+
href: location.pathname,
|
|
54
|
+
})
|
|
40
55
|
}, [location.pathname, formName, formDataId])
|
|
41
56
|
|
|
42
57
|
const layout = useMemo(
|
|
@@ -69,8 +84,9 @@ export default function FormDataDetailsComponent({
|
|
|
69
84
|
}, [formDataRef, baseServerUrl, isPublic])
|
|
70
85
|
|
|
71
86
|
const fetchFormData = useCallback(
|
|
72
|
-
(dFormId?: number
|
|
73
|
-
if (formDataId === NEW_FORM_DATA_IDENTIFIER
|
|
87
|
+
(dFormId?: number) => {
|
|
88
|
+
if (formDataId === NEW_FORM_DATA_IDENTIFIER || !isValidMongoDbId(formDataId))
|
|
89
|
+
setLoadings((c) => ({ ...c, data: false }))
|
|
74
90
|
else {
|
|
75
91
|
if (!dFormId) {
|
|
76
92
|
console.error('Form ID is required to fetch form data')
|
|
@@ -81,18 +97,14 @@ export default function FormDataDetailsComponent({
|
|
|
81
97
|
.then((res) => {
|
|
82
98
|
if (res.status === 200) {
|
|
83
99
|
const { data: jsonData, ...restFormData } = res.data
|
|
84
|
-
let parsedFormData =
|
|
100
|
+
let parsedFormData = JSON.parse(jsonData)
|
|
85
101
|
if (parsedFormData) {
|
|
86
|
-
const fieldsValue: { [key: string]: any } = parsedFormData
|
|
87
|
-
if (dateFields.length > 0)
|
|
88
|
-
Object.entries(parsedFormData).map(([field, value]) => {
|
|
89
|
-
if (dateFields.includes(field) && value) fieldsValue[field] = dayjs(value)
|
|
90
|
-
else fieldsValue[field] = value
|
|
91
|
-
})
|
|
102
|
+
const fieldsValue: { [key: string]: any } = fromMongoDbExtendedJSON(parsedFormData)
|
|
92
103
|
formDataRef.setFieldsValue({ ...restFormData, ...fieldsValue })
|
|
104
|
+
|
|
105
|
+
console.log('FORM DATA FETCH (PARSED)', fieldsValue)
|
|
93
106
|
}
|
|
94
|
-
|
|
95
|
-
}
|
|
107
|
+
} else setIsNotFound(true)
|
|
96
108
|
})
|
|
97
109
|
.finally(() => setLoadings((c) => ({ ...c, data: false })))
|
|
98
110
|
}
|
|
@@ -107,7 +119,7 @@ export default function FormDataDetailsComponent({
|
|
|
107
119
|
.get(endpoint)
|
|
108
120
|
.then((res) => {
|
|
109
121
|
if (res.status === 200) {
|
|
110
|
-
const parsedData: IFormSchema | null =
|
|
122
|
+
const parsedData: IFormSchema | null = JSON.parse(res.data.data)
|
|
111
123
|
if (parsedData) {
|
|
112
124
|
console.log('FORM LAYOUT FETCH (PARSED)', parsedData)
|
|
113
125
|
const { layouts: rawLayouts, elements } = parsedData.detailsConfig
|
|
@@ -119,11 +131,8 @@ export default function FormDataDetailsComponent({
|
|
|
119
131
|
parsedData.generateConfig.submissionPdf,
|
|
120
132
|
)
|
|
121
133
|
setLoadings((c) => ({ ...c, data: false }))
|
|
122
|
-
} else
|
|
123
|
-
const dateFields = extractDateFields(elements)
|
|
134
|
+
} else fetchFormData(formId)
|
|
124
135
|
|
|
125
|
-
fetchFormData(formId, dateFields)
|
|
126
|
-
}
|
|
127
136
|
setLayoutConfig({ elements, layouts: rawLayouts })
|
|
128
137
|
}
|
|
129
138
|
}
|
|
@@ -133,30 +142,34 @@ export default function FormDataDetailsComponent({
|
|
|
133
142
|
}, [formId, formKey, isPublic, formDataRef, fetchFormData])
|
|
134
143
|
|
|
135
144
|
const formContext = useMemo(
|
|
136
|
-
() => ({ formId, formKey, formDataId, formRef: formDataRef,
|
|
137
|
-
[formDataId, formDataRef,
|
|
145
|
+
() => ({ formId, formKey, formDataId, formRef: formDataRef, companyKey }),
|
|
146
|
+
[formDataId, formDataRef, formId, formKey, companyKey],
|
|
138
147
|
)
|
|
139
148
|
|
|
140
149
|
if (loadings.layout || loadings.data) return <FormDataListSkeleton_Details />
|
|
141
150
|
|
|
151
|
+
if (isNotFound) return <NotFound />
|
|
152
|
+
|
|
142
153
|
return (
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
154
|
+
<>
|
|
155
|
+
<Form layout="vertical" name="dynamic_form_data_form" form={formDataRef}>
|
|
156
|
+
{layout.map((row, rowIdx) => (
|
|
157
|
+
<LayoutRendererRow
|
|
158
|
+
key={rowIdx}
|
|
159
|
+
rowData={row}
|
|
160
|
+
formContext={formContext}
|
|
161
|
+
elements={layoutConfig.elements}
|
|
162
|
+
renderButton={(btnProps, conditions) => (
|
|
163
|
+
<DynamicFormButtonRender
|
|
164
|
+
displayStateProps={{ btnProps, conditions, defaultDisabled: true }}
|
|
165
|
+
formContext={formContext}
|
|
166
|
+
onCustomFunctionCall={onCustomFunctionCall}
|
|
167
|
+
/>
|
|
168
|
+
)}
|
|
169
|
+
/>
|
|
170
|
+
))}
|
|
171
|
+
</Form>
|
|
172
|
+
</>
|
|
160
173
|
)
|
|
161
174
|
}
|
|
162
175
|
|
|
@@ -99,8 +99,9 @@ export interface IFormContext {
|
|
|
99
99
|
formDataId?: string
|
|
100
100
|
formRef?: FormInstance
|
|
101
101
|
companyKey?: string
|
|
102
|
-
formName?: string
|
|
102
|
+
formName?: string // only passed in DynamicButton component
|
|
103
103
|
formKey?: string
|
|
104
104
|
formId?: number
|
|
105
105
|
parentFormJoins?: IFormJoin[]
|
|
106
|
+
manyToManyRelInfo?: { middleFormId: number; currentFormId: number; otherFormId: number } | null
|
|
106
107
|
}
|