form-craft-package 1.7.9-dev.2 → 1.7.10-dev.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 (50) hide show
  1. package/index.ts +4 -1
  2. package/package.json +4 -4
  3. package/src/api/client.ts +10 -0
  4. package/src/components/common/countdown.tsx +44 -0
  5. package/src/components/common/custom-hooks/index.ts +2 -0
  6. package/src/components/common/custom-hooks/use-breadcrumb.hook.ts +18 -0
  7. package/src/components/common/custom-hooks/use-check-element-conditions.hook.ts +3 -2
  8. package/src/components/common/custom-hooks/use-dayjs-extender.hook.ts +8 -0
  9. package/src/components/common/custom-hooks/use-many-to-many-connector.hook.ts +2 -3
  10. package/src/components/common/custom-hooks/use-notification.hook.tsx +1 -1
  11. package/src/components/common/custom-hooks/use-window-width.hook.ts +6 -4
  12. package/src/components/common/loading-skeletons/details.tsx +61 -6
  13. package/src/components/common/loading-skeletons/index.tsx +10 -2
  14. package/src/components/form/1-list/index.tsx +32 -17
  15. package/src/components/form/1-list/table-header.tsx +29 -55
  16. package/src/components/form/1-list/table.tsx +3 -5
  17. package/src/components/form/2-details/index.tsx +26 -26
  18. package/src/components/form/layout-renderer/1-row/index.tsx +9 -7
  19. package/src/components/form/layout-renderer/3-element/1-dynamic-button/index.tsx +25 -19
  20. package/src/components/form/layout-renderer/3-element/1-dynamic-button/use-button-navigate.hook.tsx +11 -5
  21. package/src/components/form/layout-renderer/3-element/1-dynamic-button/use-custom-function-call.hook.ts +22 -0
  22. package/src/components/form/layout-renderer/3-element/1-dynamic-button/use-generate-report.hook.tsx +2 -2
  23. package/src/components/form/layout-renderer/3-element/2-field-element.tsx +40 -6
  24. package/src/components/form/layout-renderer/3-element/5-re-captcha.tsx +1 -1
  25. package/src/components/form/layout-renderer/3-element/6-signature.tsx +2 -3
  26. package/src/components/form/layout-renderer/3-element/8-fields-with-options.tsx +142 -61
  27. package/src/components/form/layout-renderer/3-element/9-form-data-render.tsx +34 -27
  28. package/src/components/form/layout-renderer/3-element/index.tsx +3 -0
  29. package/src/components/index.tsx +2 -0
  30. package/src/components/modals/pdf-preview.modal.tsx +41 -0
  31. package/src/constants.ts +1 -0
  32. package/src/enums/form.enum.ts +8 -7
  33. package/src/enums/index.ts +1 -0
  34. package/src/functions/forms/conditional-rule-validator.ts +2 -0
  35. package/src/functions/forms/data-render-functions.tsx +21 -6
  36. package/src/functions/forms/get-data-list-option-value.ts +3 -3
  37. package/src/functions/forms/index.ts +33 -4
  38. package/src/functions/forms/linked-form-joins.ts +19 -0
  39. package/src/functions/reports/create-blob-url.ts +16 -0
  40. package/src/functions/reports/index.tsx +1 -0
  41. package/src/types/forms/data-list/filter-config.ts +5 -16
  42. package/src/types/forms/data-list/index.ts +2 -0
  43. package/src/types/forms/index.ts +0 -1
  44. package/src/types/forms/layout-elements/data-render-config.ts +5 -5
  45. package/src/types/forms/layout-elements/field-option-source.ts +25 -10
  46. package/src/types/forms/layout-elements/index.ts +7 -1
  47. package/src/types/forms/layout-elements/style.ts +0 -4
  48. package/src/types/forms/relationship/index.ts +6 -6
  49. package/src/types/index.ts +2 -0
  50. package/src/functions/forms/breadcrumb-handlers.ts +0 -21
@@ -1,11 +1,14 @@
1
- import { DEFAULT_LAYOUT_CONFIG, NEW_FORM_DATA_IDENTIFIER } from '../../constants'
1
+ import { BSON_DATA_IDENTIFIER_PREFIXES, DEFAULT_LAYOUT_CONFIG, NEW_FORM_DATA_IDENTIFIER } from '../../constants'
2
2
  import { ElementTypeEnum, FieldElementOptionSourceEnum } from '../../enums'
3
3
  export * from './create-form-rules'
4
4
  export * from './data-render-functions'
5
5
  export * from './extended-json-handlers'
6
6
  export * from './form-schema-validator'
7
7
  export * from './get-element-props'
8
+ export * from './linked-form-joins'
9
+ export * from './convert-number-into-words'
8
10
  import { CancelToken } from 'axios'
11
+ import client from '../../api/client'
9
12
  import {
10
13
  IFilterNested,
11
14
  IDndLayoutElement,
@@ -13,7 +16,6 @@ import {
13
16
  IDynamicForm,
14
17
  IFormDataApiReqConfig,
15
18
  } from '../../types'
16
- import client from '../../api/client'
17
19
 
18
20
  export const extractFiltersFromLayout = (elements: { [key: string]: IDndLayoutElement }) => {
19
21
  const filters: IFilterNested = {}
@@ -29,7 +31,16 @@ export const extractFiltersFromLayout = (elements: { [key: string]: IDndLayoutEl
29
31
  })
30
32
  } else if (el.props && 'filter' in el.props && el.props.filter) {
31
33
  filters[el.key] = el.props.filter
32
- ? { ...el.props.filter, isDateFilter: [ElementTypeEnum.DatePicker].includes(el.elementType) }
34
+ ? {
35
+ ...el.props.filter,
36
+ bsonDataType: el.elementType.includes(BSON_DATA_IDENTIFIER_PREFIXES.ObjectId)
37
+ ? BSON_DATA_IDENTIFIER_PREFIXES.ObjectId
38
+ : el.elementType.includes(BSON_DATA_IDENTIFIER_PREFIXES.Number)
39
+ ? BSON_DATA_IDENTIFIER_PREFIXES.Number
40
+ : el.elementType.includes(BSON_DATA_IDENTIFIER_PREFIXES.Date)
41
+ ? BSON_DATA_IDENTIFIER_PREFIXES.Date
42
+ : undefined,
43
+ }
33
44
  : undefined
34
45
  }
35
46
  })
@@ -39,7 +50,7 @@ export const extractFiltersFromLayout = (elements: { [key: string]: IDndLayoutEl
39
50
 
40
51
  /** --------------------------------------------------------------------------------------------------------- */
41
52
 
42
- export const getFlexContainerStyle = (display?: IGridContainerConfig) => {
53
+ export const getGridContainerStyle = (display?: IGridContainerConfig) => {
43
54
  if (!display) return DEFAULT_LAYOUT_CONFIG
44
55
 
45
56
  return display
@@ -173,6 +184,14 @@ export async function fetchFormDataAsLookup(
173
184
  /** --------------------------------------------------------------------------------------------------------- */
174
185
 
175
186
  export const getProjectionKey = (key: string): string => key.replace(/\./g, '_')
187
+ export const revertProjectionKey = (key?: string): string => {
188
+ if (!key || typeof key !== 'string') return ''
189
+
190
+ const segments = key.split('__')
191
+ const replaced = segments.map((segment) => segment.replace(/_/g, '.'))
192
+
193
+ return replaced.join('__')
194
+ }
176
195
 
177
196
  /** --------------------------------------------------------------------------------------------------------- */
178
197
 
@@ -185,6 +204,16 @@ export const getIdEqualsQuery = (alias: number | string = '', id: string = '') =
185
204
 
186
205
  /** --------------------------------------------------------------------------------------------------------- */
187
206
 
207
+ export const getEqualsFalseyQuery = (field: string) => ({ [field]: { $in: [false, null, '', 0] } })
208
+
209
+ /** --------------------------------------------------------------------------------------------------------- */
210
+
188
211
  export const isValidMongoDbId = (id?: string) => id && (id === NEW_FORM_DATA_IDENTIFIER || /^[0-9a-fA-F]{24}$/.test(id))
189
212
 
190
213
  /** --------------------------------------------------------------------------------------------------------- */
214
+
215
+ export const isNewFormDataPage = (formDataId?: string) => !formDataId || formDataId === NEW_FORM_DATA_IDENTIFIER
216
+
217
+ /** --------------------------------------------------------------------------------------------------------- */
218
+
219
+ /** --------------------------------------------------------------------------------------------------------- */
@@ -0,0 +1,19 @@
1
+ import { IFormJoin } from '../../types'
2
+
3
+ export function mergeJoins(joinsList: IFormJoin[][]): IFormJoin[] {
4
+ const seen = new Set<string>()
5
+ const merged: IFormJoin[] = []
6
+
7
+ for (const joins of joinsList) {
8
+ if (!Array.isArray(joins)) continue
9
+
10
+ for (const j of joins) {
11
+ if (!seen.has(j.alias)) {
12
+ seen.add(j.alias)
13
+ merged.push(j)
14
+ }
15
+ }
16
+ }
17
+
18
+ return merged
19
+ }
@@ -0,0 +1,16 @@
1
+ export function createBlobUrlOrDownload(data: any, fileName: string, autoDownload = false): string {
2
+ const blob = new Blob([data], { type: 'application/pdf' })
3
+ const url = URL.createObjectURL(blob)
4
+
5
+ if (autoDownload) {
6
+ const link = document.createElement('a')
7
+ link.href = url
8
+ link.setAttribute('download', fileName)
9
+
10
+ document.body.appendChild(link)
11
+ link.click()
12
+ document.body.removeChild(link)
13
+ }
14
+
15
+ return url
16
+ }
@@ -1,3 +1,4 @@
1
+ export * from './create-blob-url'
1
2
  import { getProjectionKey } from '..'
2
3
  import { ElementTypeEnum, ReportLayoutLineTypeEnum, ReportLayoutSectionTypeEnum } from '../../enums'
3
4
  import { IDndLayoutCol, IDndLayoutRow, IDndLayoutStructure, IReportTableLayoutStyle } from '../../types'
@@ -1,27 +1,16 @@
1
+ import { IFormJoin } from '..'
1
2
  import { FilterConfigTypeEnum } from '../../../enums'
2
3
 
3
- export type IFilterConfig = INoFilterConfig | IFilterByAuthUser | IFilterByLinkedForm | IFilterCustom
4
+ export type IFilterConfig = INoFilterConfig | IFilterCustom
4
5
  export interface INoFilterConfig {
5
6
  type: FilterConfigTypeEnum.NoFilter
6
7
  }
7
- export interface IFilterByAuthUser {
8
- type: FilterConfigTypeEnum.ByAuthUser
9
- config?: { [key: string]: any }
10
- }
11
- export interface IFilterByLinkedForm {
12
- type: FilterConfigTypeEnum.ByLinkedForm
13
- relationshipPath: IFilterByLinkedFormRelPath[]
14
- }
15
- export interface IFilterByLinkedFormRelPath {
16
- formId: number
17
- foreignKey: string
18
- // parentForeignKey?: string
19
- field?: string
20
- }
21
8
  export interface IFilterCustom {
22
9
  type: FilterConfigTypeEnum.Custom
23
10
  config: { [key: string]: any }
24
- isDateFilter?: boolean
11
+ bsonDataType?: string
12
+ joins?: IFormJoin[]
13
+ conditionFormBranches?: string[]
25
14
  }
26
15
 
27
16
  export interface IFilterSimple {
@@ -2,9 +2,11 @@ export * from './filter-config'
2
2
  import { ReactNode } from 'react'
3
3
  import { AlignTypeEnum, DeviceBreakpointEnum, MongoDbSortOrderEnum } from '../../../enums'
4
4
  import { IDataRenderConfig } from '../layout-elements'
5
+ import { IFormJoin } from '..'
5
6
 
6
7
  export interface IFormDataListColumn {
7
8
  key: string
9
+ joins: IFormJoin[]
8
10
  label: string
9
11
  order: number
10
12
  optionFieldPath?: string
@@ -21,7 +21,6 @@ export interface IFormDataListConfig {
21
21
  listType: FormDataListViewTypeEnum
22
22
  columns: IFormDataListColumn[]
23
23
  header: IDndLayoutStructure_Responsive
24
- formJoins: IFormJoin[]
25
24
  pagination?: IFormDataListPagination
26
25
  title?: string
27
26
  showCount?: boolean
@@ -4,27 +4,27 @@ import { CountryEnum, DataRenderTypeEnum } from '../../../enums'
4
4
  export type IDataRenderConfig =
5
5
  | IDataRender_Default
6
6
  | IDataRender_Number
7
- | IDataRender_NumberInWords
8
7
  | IDataRender_Currency
9
8
  | IDataRender_Image
10
9
  // | IDataRender_PhoneNumber
11
10
  | IDataRender_Date
12
11
  | IDataRender_Buttons
13
12
  | IDataRender_Conditional
13
+ | IDataRender_Tags
14
14
 
15
15
  export interface IDataRender_Default {
16
16
  type: DataRenderTypeEnum.Default
17
17
  }
18
18
 
19
+ export interface IDataRender_Tags {
20
+ type: DataRenderTypeEnum.Tags
21
+ }
22
+
19
23
  export interface IDataRender_Number {
20
24
  type: DataRenderTypeEnum.Number
21
25
  decimalPoint?: number
22
26
  }
23
27
 
24
- export interface IDataRender_NumberInWords {
25
- type: DataRenderTypeEnum.NumberInWords
26
- }
27
-
28
28
  export interface IDataRender_Currency {
29
29
  type: DataRenderTypeEnum.Currency
30
30
  country: CountryEnum
@@ -1,11 +1,12 @@
1
- import { IFilterConfig } from '..'
1
+ import { IDataRenderConfig, IFilterConfig, IFormJoin } from '..'
2
2
  import { FieldElementOptionSourceEnum } from '../../../enums'
3
3
 
4
4
  export type IFieldElementOptionSource =
5
5
  | IOptionSourceConstant
6
- | IOptionSourceForm
6
+ | IOptionSourceDynamicForm
7
7
  | IOptionSourceReadFromDetails
8
8
  | IOptionSourceLinkedForm
9
+ | IOptionSourceAny
9
10
 
10
11
  export interface IOptionSourceConstant {
11
12
  type: FieldElementOptionSourceEnum.Static
@@ -18,14 +19,10 @@ export interface IFormLayoutFieldOption {
18
19
  filter?: IFilterConfig
19
20
  }
20
21
 
21
- export interface IOptionSourceForm {
22
+ export interface IOptionSourceDynamicForm extends IOptionSourceFormFields {
22
23
  type: FieldElementOptionSourceEnum.DynamicForm
23
- form: IOptionSourceFormInfo
24
- }
25
- export interface IOptionSourceFormInfo {
26
- id: number
27
- formName: string
28
- field: string
24
+ formId: number
25
+ formName?: string
29
26
  }
30
27
 
31
28
  export interface IOptionSourceReadFromDetails {
@@ -34,6 +31,24 @@ export interface IOptionSourceReadFromDetails {
34
31
  optionFieldPath: string
35
32
  }
36
33
 
37
- export interface IOptionSourceLinkedForm {
34
+ export interface IOptionSourceLinkedForm extends IOptionSourceFormFields {
38
35
  type: FieldElementOptionSourceEnum.LinkedForm
36
+ baseFormId: number
37
+ joins: IFormJoin[]
38
+ formName?: string
39
+ }
40
+
41
+ export interface IOptionSourceAny {
42
+ type: FieldElementOptionSourceEnum.Any
43
+ }
44
+
45
+ export interface IOptionSourceFormFields {
46
+ field: string
47
+ field1_RC?: IDataRenderConfig
48
+ field2?: string
49
+ field2_RC?: IDataRenderConfig
50
+ field3?: string
51
+ field3_RC?: IDataRenderConfig
52
+ field4?: string
53
+ field4_RC?: IDataRenderConfig
39
54
  }
@@ -201,6 +201,12 @@ export interface IContainerElement extends BaseFormLayoutElement {
201
201
 
202
202
  /** -------------------------------------------------------------------------------------------- */
203
203
 
204
+ export interface IPlaceholderElement extends BaseFormLayoutElement {
205
+ elementType: ElementTypeEnum.Placeholder
206
+ }
207
+
208
+ /** -------------------------------------------------------------------------------------------- */
209
+
204
210
  export interface IReportTableElement extends BaseFormLayoutElement {
205
211
  elementType: ElementTypeEnum.ReportTable
206
212
  style?: ICssStyle | ICssStylePerBreakpoint
@@ -289,7 +295,7 @@ export interface IFormDataLoadElement extends BaseFormLayoutElement {
289
295
  export interface IFormDataLoadElementProps {
290
296
  hasNoLabel?: boolean
291
297
  baseFormId: number
292
- displayConfigFormId: number
298
+ m2mRelFormId?: number
293
299
  displayConfigId: string
294
300
  joins: IFormJoin[]
295
301
  filter?: IFilterConfig
@@ -9,10 +9,6 @@ export type IGridContainerConfig = {
9
9
  columnsGaps?: string[]
10
10
  }
11
11
 
12
- export type FlexItemConfig = {
13
- gap?: string
14
- }
15
-
16
12
  export type ICssStyle = {
17
13
  [key: string]: any
18
14
  }
@@ -1,7 +1,7 @@
1
1
  import { IDataListSorter, IFilterConfig, IFormDataListConfig } from '..'
2
2
  import { FormRelationshipEnum, NewFormViewTypeEnum } from '../../../enums'
3
3
 
4
- export type IFormRelationshipConfig = IFormRelationshipConfig_ManyToMany | IFormRelationshipConfig_Others
4
+ export type IFormRelationshipConfig = IFormRelationshipConfig_OneToMany | IFormRelationshipConfig_Others
5
5
 
6
6
  interface IFormRelationshipConfig_Base {
7
7
  formId: number
@@ -10,14 +10,14 @@ interface IFormRelationshipConfig_Base {
10
10
  viewType?: NewFormViewTypeEnum
11
11
  displayConfigs?: IRelationshipDisplayConfig[]
12
12
  }
13
- export interface IFormRelationshipConfig_ManyToMany extends IFormRelationshipConfig_Base {
14
- type: FormRelationshipEnum.ManyToMany
15
- foreignKey2: string
16
- relationshipFormId: number
13
+ export interface IFormRelationshipConfig_OneToMany extends IFormRelationshipConfig_Base {
14
+ type: FormRelationshipEnum.OneToMany
15
+ m2mTargetFormId?: number
16
+ m2mTargetFormFK?: string
17
17
  }
18
18
 
19
19
  export interface IFormRelationshipConfig_Others extends IFormRelationshipConfig_Base {
20
- type: FormRelationshipEnum.ManyToOne | FormRelationshipEnum.OneToMany | FormRelationshipEnum.OneToOne
20
+ type: FormRelationshipEnum.ManyToOne | FormRelationshipEnum.OneToOne
21
21
  }
22
22
 
23
23
  export type IRelationshipDisplayConfig = {
@@ -16,6 +16,7 @@ import {
16
16
  IListElement,
17
17
  INumberInputElement,
18
18
  IPickerElement,
19
+ IPlaceholderElement,
19
20
  IRadioElement,
20
21
  IReadFieldDataElement,
21
22
  IReCaptchaElement,
@@ -80,3 +81,4 @@ export type IDndLayoutElement =
80
81
  | IListElement
81
82
  | IImageElement
82
83
  | IBreadcrumbElement
84
+ | IPlaceholderElement
@@ -1,21 +0,0 @@
1
- import { IFormJoin } from '../../types'
2
-
3
- export const getForeignKeysFromBreadcrumb = (breadcrumb: {
4
- [key: string]: any
5
- }): { foreignKey?: string; foreignKey2?: string } => {
6
- if (!breadcrumb || !breadcrumb.manyToManyRelInfo) return {}
7
-
8
- const form1Join = (breadcrumb.formJoins as IFormJoin[]).find(
9
- (j) => j.formId === breadcrumb.manyToManyRelInfo.currentFormId,
10
- )
11
- const localFieldSplit = form1Join?.localField.split('.') ?? []
12
- const foreignKey = localFieldSplit[localFieldSplit.length - 1]
13
-
14
- const form2Join = (breadcrumb.formJoins as IFormJoin[]).find(
15
- (j) => j.formId === breadcrumb.manyToManyRelInfo.otherFormId,
16
- )
17
- const localField2Split = form2Join?.localField.split('.') ?? []
18
- const foreignKey2 = localField2Split[localField2Split.length - 1]
19
-
20
- return { foreignKey, foreignKey2 }
21
- }