form-craft-package 1.6.1 → 1.7.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.
Files changed (37) hide show
  1. package/package.json +3 -1
  2. package/src/components/form/1-list/index.tsx +2 -6
  3. package/src/components/form/1-list/table-header.tsx +2 -2
  4. package/src/components/form/1-list/table.tsx +19 -5
  5. package/src/components/form/2-details/index.tsx +10 -5
  6. package/src/components/form/3-preview/index.tsx +2 -6
  7. package/src/components/form/layout-renderer/1-row/header-render.tsx +2 -2
  8. package/src/components/form/layout-renderer/1-row/header.tsx +2 -2
  9. package/src/components/form/layout-renderer/1-row/index.tsx +4 -4
  10. package/src/components/form/layout-renderer/2-col/index.tsx +8 -8
  11. package/src/components/form/layout-renderer/3-element/1-dynamic-button/use-create-data.hook.ts +1 -1
  12. package/src/components/form/layout-renderer/3-element/1-dynamic-button/use-generate-report.hook.tsx +2 -2
  13. package/src/components/form/layout-renderer/3-element/9-form-data-render.tsx +3 -3
  14. package/src/components/form/layout-renderer/3-element/index.tsx +2 -2
  15. package/src/components/index.tsx +1 -0
  16. package/src/components/modals/report-filters.modal/helper-functions.ts +426 -0
  17. package/src/components/modals/report-filters.modal/index.tsx +348 -0
  18. package/src/components/report/1-list/index.tsx +49 -0
  19. package/src/constants.ts +92 -0
  20. package/src/enums/companies/index.ts +6 -0
  21. package/src/enums/form.enum.ts +2 -48
  22. package/src/enums/index.ts +52 -0
  23. package/src/enums/report.enum.ts +54 -0
  24. package/src/functions/forms/data-render-functions.tsx +2 -2
  25. package/src/functions/forms/index.ts +8 -8
  26. package/src/functions/index.ts +1 -0
  27. package/src/functions/reports/index.tsx +184 -0
  28. package/src/types/companies/index.ts +19 -100
  29. package/src/types/companies/site-layout/authenticated/index.tsx +142 -104
  30. package/src/types/forms/data-list/index.ts +1 -6
  31. package/src/types/forms/index.ts +8 -69
  32. package/src/types/forms/layout-elements/evaluation-config.ts +7 -1
  33. package/src/types/forms/layout-elements/index.ts +43 -8
  34. package/src/types/forms/layout-elements/report-table.ts +66 -0
  35. package/src/types/forms/layout-elements/style.ts +1 -1
  36. package/src/types/index.ts +78 -0
  37. package/src/types/reports/index.ts +45 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "form-craft-package",
3
- "version": "1.6.1",
3
+ "version": "1.7.0",
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.6",
16
16
  "ajv": "^8.17.1",
17
+ "pdfmake": "^0.2.18",
17
18
  "react-google-recaptcha": "^3.1.0",
18
19
  "react-signature-canvas": "^1.0.7"
19
20
  },
@@ -31,6 +32,7 @@
31
32
  },
32
33
  "devDependencies": {
33
34
  "@types/js-cookie": "^3.0.6",
35
+ "@types/pdfmake": "^0.2.11",
34
36
  "@types/react": "^18.3.18",
35
37
  "@types/react-dom": "^18.3.5",
36
38
  "react": "^18.3.1",
@@ -2,10 +2,9 @@ import { useCallback, useEffect, useMemo, useState } from 'react'
2
2
  import client from '../../../functions/axios-handler'
3
3
  import { parseJSON } from '../../../functions/forms/json-handlers'
4
4
  import FormDataListSkeleton_Table from '../../common/loading-skeletons/table'
5
- import { IFormData, IFormDataListConfig, IFormLayoutElement, IFormLayoutRow, IFormSchema } from '../../../types'
5
+ import { IFormData, IFormDataListConfig, IFormSchema, IDndLayoutStructure_Responsive } from '../../../types'
6
6
  import { ICustomFunctionCall } from '../layout-renderer/3-element/1-dynamic-button'
7
7
  import FormDataListTableComponent, { IReqDataConfig } from './table'
8
- import { DeviceBreakpointEnum } from '../../../enums'
9
8
 
10
9
  function FormDataListComponent({
11
10
  formName,
@@ -20,10 +19,7 @@ function FormDataListComponent({
20
19
  const [dataListConfig, setDataListConfig] = useState<
21
20
  | {
22
21
  dataListConfig: IFormDataListConfig & { configForFormId: number }
23
- detailsLayoutConfig: {
24
- elements: { [key: string]: IFormLayoutElement }
25
- layouts: { [key in DeviceBreakpointEnum]?: IFormLayoutRow[] }
26
- }
22
+ detailsLayoutConfig: IDndLayoutStructure_Responsive
27
23
  }
28
24
  | undefined
29
25
  >()
@@ -15,12 +15,12 @@ import {
15
15
  IReqDataConfig,
16
16
  } from './table'
17
17
  import {
18
+ IDndLayoutStructure_Responsive,
18
19
  IFilterByAuthUser,
19
20
  IFilterConfig,
20
21
  IFilterCustom,
21
22
  IFilterNested,
22
23
  IFilterSimple,
23
- IFormDetailsConfig,
24
24
  } from '../../../types'
25
25
 
26
26
  export default function FormDataListHeaderComponent({
@@ -149,7 +149,7 @@ export default function FormDataListHeaderComponent({
149
149
  }
150
150
 
151
151
  type IFormDataListHeaderComponent = {
152
- layoutConfig: IFormDetailsConfig
152
+ layoutConfig: IDndLayoutStructure_Responsive
153
153
  updateReqData: React.Dispatch<React.SetStateAction<IReqDataConfig | undefined>>
154
154
  titleComponent?: ReactNode
155
155
  defaultFilter: IReqDataConfig
@@ -1,5 +1,11 @@
1
1
  import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
2
- import { IDataListParentInfo, IFormData, IFormDataListConfig, IFormDetailsConfig, ITableColumn } from '../../../types'
2
+ import {
3
+ IDataListParentInfo,
4
+ IDndLayoutStructure_Responsive,
5
+ IFormData,
6
+ IFormDataListConfig,
7
+ IFormDataTableColumn,
8
+ } from '../../../types'
3
9
  import FormDataListHeaderComponent from './table-header'
4
10
  import useDebounced from '../../common/custom-hooks/use-debounce.hook'
5
11
  import { FormInstance, Table } from 'antd'
@@ -28,7 +34,9 @@ export default function FormDataListTableComponent({
28
34
  }: IFormDataListTableComponent) {
29
35
  const currentBreakpoint = useGetCurrentBreakpoint()
30
36
  const location = useLocation()
31
- const [tableColumns, setTableColumns] = useState<(ITableColumn & { hideScreens?: DeviceBreakpointEnum[] })[]>([])
37
+ const [tableColumns, setTableColumns] = useState<(IFormDataTableColumn & { hideScreens?: DeviceBreakpointEnum[] })[]>(
38
+ [],
39
+ )
32
40
  const [filterReqData, setFilterReqData, debouncedFilterReqData] = useDebounced<IReqDataConfig | undefined>(
33
41
  undefined,
34
42
  250,
@@ -36,7 +44,10 @@ export default function FormDataListTableComponent({
36
44
  const [otherConfigs, setOtherConfigs] = useState<
37
45
  (Partial<IFormDataListConfig> & { hasNoPagination: boolean }) | undefined
38
46
  >(undefined)
39
- const [headerLayoutConfig, setHeaderLayoutConfig] = useState<IFormDetailsConfig>({ elements: {}, layouts: {} })
47
+ const [headerLayoutConfig, setHeaderLayoutConfig] = useState<IDndLayoutStructure_Responsive>({
48
+ elements: {},
49
+ layouts: {},
50
+ })
40
51
  const [isHandlingSchema, setIsHandlingSchema] = useState(true)
41
52
  const isFinishedHandlingRef = useRef(false)
42
53
 
@@ -57,7 +68,10 @@ export default function FormDataListTableComponent({
57
68
  }, [debouncedFilterReqData])
58
69
 
59
70
  const handleDataListConfig = useCallback(
60
- async (config: IFormDataListConfig & { configForFormId?: number }, layoutConfig?: IFormDetailsConfig) => {
71
+ async (
72
+ config: IFormDataListConfig & { configForFormId?: number },
73
+ layoutConfig?: IDndLayoutStructure_Responsive,
74
+ ) => {
61
75
  if (config.configForFormId && config.configForFormId !== formId) return
62
76
 
63
77
  const {
@@ -183,7 +197,7 @@ export default function FormDataListTableComponent({
183
197
 
184
198
  type IFormDataListTableComponent = {
185
199
  dataListConfig?: IFormDataListConfig & { configForFormId?: number }
186
- detailsLayoutConfig?: IFormDetailsConfig
200
+ detailsLayoutConfig?: IDndLayoutStructure_Responsive
187
201
  dataList: { data: IFormData[]; total: number }
188
202
  parentLoading: boolean
189
203
  loadingBlock?: JSX.Element
@@ -1,6 +1,6 @@
1
1
  import { Form } from 'antd'
2
2
  import { useCallback, useEffect, useMemo, useState } from 'react'
3
- import { IFormLayoutElement, IFormLayoutRow, IFormSchema } from '../../../types'
3
+ import { IDndLayoutStructure_Responsive, IFormSchema } from '../../../types'
4
4
  import { NEW_FORM_DATA_IDENTIFIER } from '../../../constants'
5
5
  import client from '../../../functions/axios-handler'
6
6
  import { parseJSON } from '../../../functions/forms/json-handlers'
@@ -22,14 +22,12 @@ export default function FormDataDetailsComponent({
22
22
  companyKey,
23
23
  baseServerUrl,
24
24
  onCustomFunctionCall,
25
+ initialValues,
25
26
  }: IFormDataDetailsComponent) {
26
27
  const location = useLocation()
27
28
  const [formDataRef] = Form.useForm()
28
29
  const [loadings, setLoadings] = useState({ layout: true, data: true })
29
- const [layoutConfig, setLayoutConfig] = useState<{
30
- elements: { [key: string]: IFormLayoutElement }
31
- layouts: { [key in DeviceBreakpointEnum]?: IFormLayoutRow[] }
32
- }>({ elements: {}, layouts: {} })
30
+ const [layoutConfig, setLayoutConfig] = useState<IDndLayoutStructure_Responsive>({ elements: {}, layouts: {} })
33
31
 
34
32
  const currentBreakpoint = useGetCurrentBreakpoint()
35
33
 
@@ -37,6 +35,12 @@ export default function FormDataDetailsComponent({
37
35
  () => layoutConfig.layouts[currentBreakpoint] ?? layoutConfig.layouts[DeviceBreakpointEnum.Default] ?? [],
38
36
  [layoutConfig.layouts, currentBreakpoint],
39
37
  )
38
+ // Apply initialValues
39
+ useEffect(() => {
40
+ if (initialValues && formDataId === NEW_FORM_DATA_IDENTIFIER) {
41
+ formDataRef.setFieldsValue(initialValues)
42
+ }
43
+ }, [initialValues, formDataId, formDataRef])
40
44
 
41
45
  useEffect(() => {
42
46
  // this is for converting the screen to PDF
@@ -152,6 +156,7 @@ type IFormDataDetailsComponent = {
152
156
  companyKey?: string
153
157
  formDataId: string
154
158
  formName?: string
159
+ initialValues?: Record<string, any>
155
160
  } & (IDataDetailsPublicProps | IDataDetailsPrivateProps) &
156
161
  ICustomFunctionCall
157
162
 
@@ -1,5 +1,5 @@
1
1
  import { Form } from 'antd'
2
- import { IFormLayoutElement, IFormLayoutRow } from '../../../types'
2
+ import { IDndLayoutStructure } from '../../../types'
3
3
  import { FormPreservedItemKeys } from '../../../enums'
4
4
  import { LayoutRendererRow } from '../layout-renderer/1-row'
5
5
  import { DynamicFormButtonRender } from '../layout-renderer/3-element/1-dynamic-button'
@@ -10,11 +10,7 @@ export const FormPreviewComponent = ({
10
10
  layout,
11
11
  elements = {},
12
12
  titleComponent,
13
- }: {
14
- layout: IFormLayoutRow[]
15
- elements: { [key: string]: IFormLayoutElement }
16
- titleComponent?: ReactNode
17
- }) => {
13
+ }: { titleComponent?: ReactNode } & IDndLayoutStructure) => {
18
14
  const [previewFormRef] = Form.useForm()
19
15
  const { infoModal } = useNotification()
20
16
 
@@ -1,5 +1,5 @@
1
1
  import { ReactNode, useState } from 'react'
2
- import { IFormLayoutRowHeader } from '../../../../types'
2
+ import { IFormDndLayoutRowHeader } from '../../../../types'
3
3
  import { Collapse } from 'antd'
4
4
  import RowHeader from './header'
5
5
 
@@ -8,7 +8,7 @@ export const LayoutRowConditionalHeaderRenderer = ({
8
8
  header,
9
9
  }: {
10
10
  children: ReactNode
11
- header: IFormLayoutRowHeader | undefined
11
+ header: IFormDndLayoutRowHeader | undefined
12
12
  }) => {
13
13
  const [isCollapsed, setIsCollapsed] = useState(false)
14
14
 
@@ -1,5 +1,5 @@
1
1
  import { useMemo } from 'react'
2
- import { IFormLayoutRowHeader } from '../../../../types'
2
+ import { IFormDndLayoutRowHeader } from '../../../../types'
3
3
  import { kebabCaseToCamelCase } from '../../../../functions/forms'
4
4
  import { FaCaretDown, FaCaretUp } from 'react-icons/fa6'
5
5
 
@@ -34,7 +34,7 @@ export default function RowHeader({
34
34
  )
35
35
  }
36
36
 
37
- interface IRowHeader extends IFormLayoutRowHeader {
37
+ interface IRowHeader extends IFormDndLayoutRowHeader {
38
38
  isCollapsed?: boolean
39
39
  setIsCollapsed?: () => void
40
40
  }
@@ -6,9 +6,9 @@ import { LayoutRowConditionalHeaderRenderer } from './header-render'
6
6
  import { LayoutRowRepeatableRenderer } from './repeatable-render'
7
7
  import {
8
8
  IButtonElementProps,
9
- IFormLayoutElement,
9
+ IDndLayoutElement,
10
10
  IFormLayoutElementConditions,
11
- IFormLayoutRow,
11
+ IDndLayoutRow,
12
12
  } from '../../../../types'
13
13
 
14
14
  export const LayoutRendererRow = memo(
@@ -67,10 +67,10 @@ export const LayoutRendererRow = memo(
67
67
 
68
68
  interface ILayoutRendererRow {
69
69
  basePath?: (string | number)[]
70
- rowData: IFormLayoutRow
70
+ rowData: IDndLayoutRow
71
71
  titleComponent?: ReactNode
72
72
  formContext: IFormContext
73
- elements: { [key: string]: IFormLayoutElement }
73
+ elements: { [key: string]: IDndLayoutElement }
74
74
  renderButton?: (props: IButtonElementProps, conditions?: IFormLayoutElementConditions) => ReactElement
75
75
  }
76
76
 
@@ -1,13 +1,13 @@
1
1
  import { memo, ReactElement, ReactNode, useEffect, useMemo, useState } from 'react'
2
2
  import { IFormContext, LayoutRendererRow } from '../1-row'
3
- import { FormLayoutNodeEnum } from '../../../../enums'
3
+ import { DndLayoutNodeEnum } from '../../../../enums'
4
4
  import LayoutRendererElementWrapper from '../3-element'
5
5
  import {
6
6
  IButtonElementProps,
7
- IFormLayoutCol,
8
- IFormLayoutElement,
7
+ IDndLayoutCol,
8
+ IDndLayoutElement,
9
9
  IFormLayoutElementConditions,
10
- IFormLayoutRow,
10
+ IDndLayoutRow,
11
11
  } from '../../../../types'
12
12
 
13
13
  function LayoutRendererCol({
@@ -33,8 +33,8 @@ function LayoutRendererCol({
33
33
 
34
34
  return (
35
35
  <div style={{ gap: colStyle.gap, display: isAllChildrenHidden ? 'none' : 'flex', flexDirection: 'column' }}>
36
- {colData.children.map((item: IFormLayoutRow | string) =>
37
- typeof item !== 'string' && item.nodeType === FormLayoutNodeEnum.Row ? (
36
+ {colData.children.map((item: IDndLayoutRow | string) =>
37
+ typeof item !== 'string' && item.nodeType === DndLayoutNodeEnum.Row ? (
38
38
  <LayoutRendererRow
39
39
  key={item.id}
40
40
  basePath={basePath}
@@ -71,9 +71,9 @@ function LayoutRendererCol({
71
71
  export default memo(LayoutRendererCol)
72
72
  interface ILayoutRendererCol {
73
73
  basePath: (string | number)[]
74
- colData: IFormLayoutCol
74
+ colData: IDndLayoutCol
75
75
  titleComponent?: ReactNode
76
- elements: { [key: string]: IFormLayoutElement }
76
+ elements: { [key: string]: IDndLayoutElement }
77
77
  formContext: IFormContext
78
78
  colStyle: { [key: string]: number | string }
79
79
  hideRow: (bool: boolean) => void
@@ -102,7 +102,7 @@ export const useCreateDataWithPdfActions = ({
102
102
  .map((v: any) => (v.isDynamic ? values[v.value] : v.value))
103
103
  .join(submissionPdfConfig.title?.delimiter ?? '') ?? 'submission-pdf'
104
104
 
105
- const res = await client.post(`/api/attachment/pdf/${companyKey}/${blobName}?url=${fullUrl}`)
105
+ const res = await client.post(`/api/template/pdf/${companyKey}/${blobName}?url=${fullUrl}`)
106
106
 
107
107
  if (res.status < 300) onCreateNewData(res.data)
108
108
  })
@@ -55,7 +55,7 @@ export const useGenerateReportAction = ({
55
55
  })
56
56
  .then((res) => {
57
57
  if (res.status === 200) {
58
- setFormData(res.data[0])
58
+ setFormData(res.data.data[0])
59
59
  setTemplateReports(reports)
60
60
  }
61
61
  })
@@ -136,7 +136,7 @@ export const useGenerateReportAction = ({
136
136
 
137
137
  client
138
138
  .post(
139
- `/api/attachment/template/${companyKey}/${selectedTemplateInfo.fileBlobName}`,
139
+ `/api/template/${companyKey}/${selectedTemplateInfo.fileBlobName}`,
140
140
  replacements.map((r) => ({
141
141
  key: r.placeholder,
142
142
  value: r.value?.toString() ?? '-',
@@ -8,10 +8,10 @@ import client from '../../../../functions/axios-handler'
8
8
  import { IFormContext } from '../1-row'
9
9
  import {
10
10
  IDataListParentInfo,
11
+ IDndLayoutStructure_Responsive,
11
12
  IFormData,
12
13
  IFormDataListConfig,
13
14
  IFormDataLoadElementProps,
14
- IFormDetailsConfig,
15
15
  IFormRelationshipConfig,
16
16
  } from '../../../../types'
17
17
 
@@ -30,7 +30,7 @@ export default function LayoutRenderer_LoadFormData({
30
30
  const [displayConfig, setDisplayConfig] = useState<
31
31
  | {
32
32
  dataListConfig: IFormDataListConfig
33
- detailsLayoutConfig: IFormDetailsConfig | undefined
33
+ detailsLayoutConfig: IDndLayoutStructure_Responsive | undefined
34
34
  }
35
35
  | undefined
36
36
  >()
@@ -133,7 +133,7 @@ export default function LayoutRenderer_LoadFormData({
133
133
  })
134
134
  .then((res) => {
135
135
  if (res.status === 200) {
136
- const resData = res.data
136
+ const resData = res.data.data
137
137
 
138
138
  if (!tableHeaderFilters)
139
139
  lastChildInfo.current = {
@@ -3,7 +3,7 @@ import { memo, ReactElement, ReactNode, useEffect, useMemo } from 'react'
3
3
  import {
4
4
  IButtonElementProps,
5
5
  IFormDataLoadElementProps,
6
- IFormLayoutElement,
6
+ IDndLayoutElement,
7
7
  IFormLayoutElementConditions,
8
8
  IReadFieldDataElementProps,
9
9
  } from '../../../../types'
@@ -180,7 +180,7 @@ function LayoutRendererElement({
180
180
 
181
181
  interface ILayoutRendererElement {
182
182
  basePath: (string | number)[]
183
- elementData: IFormLayoutElement
183
+ elementData: IDndLayoutElement
184
184
  titleComponent?: ReactNode
185
185
  formContext: IFormContext
186
186
  renderButton?: (props: IButtonElementProps, conditions?: IFormLayoutElementConditions) => ReactElement
@@ -4,3 +4,4 @@ export * from './form/1-list'
4
4
  export * from './form/2-details'
5
5
  export * from './form/3-preview'
6
6
  export * from './common/button'
7
+ export * from './report/1-list'