@fixefy/fixefy-ui-components 0.0.37 → 0.0.39

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 (103) hide show
  1. package/.prettierrc.json +10 -0
  2. package/.swcrc +20 -0
  3. package/build/FxTag/FxTag.js +41 -0
  4. package/build/FxTag/fxtag_types.d.js +4 -0
  5. package/build/FxTag/index.js +20 -0
  6. package/build/FxTag/styles/tag.styles.js +94 -0
  7. package/package.json +7 -7
  8. package/src/FxActionsTray/FxActionsTray.tsx +293 -0
  9. package/src/FxActionsTray/actions_tray_types.d.ts +15 -0
  10. package/src/FxActionsTray/index.ts +3 -0
  11. package/src/FxActionsTray/styles/actions_tray.styles.tsx +90 -0
  12. package/src/FxAggregationsBar/FxAggregations.tsx +32 -0
  13. package/src/FxAggregationsBar/aggregations_types.d.ts +21 -0
  14. package/src/FxAggregationsBar/helpers/structureReader.tsx +66 -0
  15. package/src/FxAggregationsBar/index.ts +2 -0
  16. package/src/FxAggregationsBar/operations/query.ts +64 -0
  17. package/src/FxAsyncDropdown/FxAsyncDropdown.tsx +362 -0
  18. package/src/FxAsyncDropdown/async_dropdown_types.d.ts +40 -0
  19. package/src/FxAsyncDropdown/helpers/helpers.ts +105 -0
  20. package/src/FxAsyncDropdown/index.ts +2 -0
  21. package/src/FxAsyncDropdown/styles/dropdown.styles.tsx +162 -0
  22. package/src/FxAvatar/FxAvatar.tsx +50 -0
  23. package/src/FxAvatar/avatar_types.d.ts +11 -0
  24. package/src/FxAvatar/helpers/stringToColor.ts +16 -0
  25. package/src/FxAvatar/index.ts +2 -0
  26. package/src/FxAvatar/styles/avatar.styles.tsx +82 -0
  27. package/src/FxButton/FxButton.tsx +11 -0
  28. package/src/FxButton/index.ts +2 -0
  29. package/src/FxButton/styles/button.styles.jsx +16 -0
  30. package/src/FxButton/styles/button.styles.tsx +14 -0
  31. package/src/FxChip/FxChip.tsx +14 -0
  32. package/src/FxChip/chip_types.d.ts +34 -0
  33. package/src/FxChip/index.ts +2 -0
  34. package/src/FxChip/styles/chip.styles.tsx +51 -0
  35. package/src/FxIcon/FxIcon.tsx +34 -0
  36. package/src/FxIcon/content/dynamic_icon.tsx +3 -0
  37. package/src/FxIcon/content/index.ts +2 -0
  38. package/src/FxIcon/content/lazy_icon.tsx +48 -0
  39. package/src/FxIcon/icon_types.d.ts +10 -0
  40. package/src/FxIcon/index.ts +2 -0
  41. package/src/FxModal/FxModal.tsx +44 -0
  42. package/src/FxModal/index.ts +2 -0
  43. package/src/FxModal/modal_types.d.ts +10 -0
  44. package/src/FxModal/styles/modal.style.tsx +40 -0
  45. package/src/FxNotes/FxNotes.tsx +165 -0
  46. package/src/FxNotes/helpers/stringToColor.ts +19 -0
  47. package/src/FxNotes/index.ts +2 -0
  48. package/src/FxNotes/note_types.d.ts +12 -0
  49. package/src/FxNotes/operations/queries.ts +21 -0
  50. package/src/FxNotes/styles/notes.styles.tsx +135 -0
  51. package/src/FxNumberField/FxNumberField.tsx +37 -0
  52. package/src/FxNumberField/index.ts +2 -0
  53. package/src/FxNumberField/number_field_types.d.ts +7 -0
  54. package/src/FxNumberField/styles/number_field.styles.ts +85 -0
  55. package/src/FxProgressCircle/FxProgressCircle.tsx +40 -0
  56. package/src/FxProgressCircle/index.ts +2 -0
  57. package/src/FxProgressCircle/progress_circle_types.d.ts +9 -0
  58. package/src/FxProgressCircle/styles/progress_circle.styles.tsx +33 -0
  59. package/src/FxProgressCounter/ProgressCounter.tsx +81 -0
  60. package/src/FxProgressCounter/index.ts +2 -0
  61. package/src/FxProgressCounter/progress_counter_types.d.ts +10 -0
  62. package/src/FxProgressCounter/styles/progress_counter.styles.ts +40 -0
  63. package/src/FxScore/FxScore.tsx +75 -0
  64. package/src/FxScore/index.ts +2 -0
  65. package/src/FxScore/score_types.d.ts +16 -0
  66. package/src/FxScore/styles/score.styles.ts +42 -0
  67. package/src/FxShowMore/FxShowMore.tsx +60 -0
  68. package/src/FxShowMore/index.ts +2 -0
  69. package/src/FxShowMore/show_more_types.d.ts +8 -0
  70. package/src/FxShowMore/styles/show_more.styles.ts +67 -0
  71. package/src/FxSlider/FxSlider.tsx +8 -0
  72. package/src/FxSlider/index.ts +2 -0
  73. package/src/FxSlider/slider_types.d.ts +3 -0
  74. package/src/FxStatisticsBar/FxStatisticsBar.tsx +112 -0
  75. package/src/FxStatisticsBar/index.ts +2 -0
  76. package/src/FxStatisticsBar/statistics_bar_types.d.ts +8 -0
  77. package/src/FxStatisticsBar/styles/statistics.styles.ts +41 -0
  78. package/src/FxStatusBar/FxStatusBar.tsx +66 -0
  79. package/src/FxStatusBar/helpers/constants.ts +12 -0
  80. package/src/FxStatusBar/index.ts +2 -0
  81. package/src/FxStatusBar/status_bar_types.d.ts +14 -0
  82. package/src/FxStatusBar/styles/statusBar.styles.tsx +67 -0
  83. package/src/FxStyledComponents/index.tsx +196 -0
  84. package/src/FxTag/FxTag.tsx +14 -0
  85. package/src/FxTag/fxtag_types.d.ts +4 -0
  86. package/src/FxTag/index.ts +2 -0
  87. package/src/FxTag/styles/tag.styles.tsx +24 -0
  88. package/src/FxTextField/FxTextField.tsx +117 -0
  89. package/src/FxTextField/index.ts +2 -0
  90. package/src/FxTextField/text_field_types.d.ts +20 -0
  91. package/src/FxTodo/FxTodo.tsx +58 -0
  92. package/src/FxTodo/index.ts +2 -0
  93. package/src/FxTodo/styles/todo.styles.tsx +113 -0
  94. package/src/FxTodo/todo_types.d.ts +19 -0
  95. package/src/FxWizard/FxWizard.tsx +56 -0
  96. package/src/FxWizard/WizardContext.tsx +108 -0
  97. package/src/FxWizard/index.ts +3 -0
  98. package/src/FxWizard/styles/wizard.styles.tsx +22 -0
  99. package/src/FxWizard/wizard_types.d.ts +37 -0
  100. package/src/index.ts +23 -0
  101. package/tsconfig.json +22 -0
  102. package/webpack.config.js +35 -0
  103. package/yarn-error.log +95 -0
@@ -0,0 +1,66 @@
1
+ import React from 'react'
2
+
3
+ import { Box, Stack, Divider } from '@mui/material'
4
+
5
+ import { FxScore } from '../../FxScore'
6
+ import { FxStatisticsBar } from '../../FxStatisticsBar'
7
+ import { FxProgressCounter } from '../../FxProgressCounter'
8
+
9
+ export const structureReader = (structure: any, filter: any, collapsed: boolean, initialValues: any) => {
10
+ const { extended, type } = structure
11
+ switch (type) {
12
+ case 'aggregations_primary_container':
13
+ return structure.children.map((child: any, index: number) =>
14
+ child.input_type?.value === 'percentage' ? (
15
+ <FxScore structure={child} key={index} filter={filter} value={initialValues?.score} />
16
+ ) : child.input_type?.value === 'progress' ? (
17
+ <FxProgressCounter structure={child} filter={filter} key={index} values={initialValues} />
18
+ ) : (
19
+ <Box
20
+ sx={{
21
+ display: 'flex',
22
+ justifyContent: 'center',
23
+ alignItems: 'center',
24
+ width: 'fit-content',
25
+ padding: 2,
26
+ borderRadius: 2,
27
+ backgroundColor: extended?.variables?.bg || '#FFFFFF',
28
+ }}
29
+ >
30
+ <FxStatisticsBar
31
+ structure={child}
32
+ key={index}
33
+ filter={filter}
34
+ collapsed={collapsed}
35
+ value={initialValues ? initialValues[child.extended.object_path] : null}
36
+ />
37
+ </Box>
38
+ ),
39
+ )
40
+ case 'aggregations_secondary_container':
41
+ return (
42
+ <Stack
43
+ direction='row'
44
+ divider={<Divider orientation='vertical' flexItem />}
45
+ spacing={2}
46
+ sx={{
47
+ backgroundColor: extended?.variables?.bg || '#FFFFFF',
48
+ borderRadius: '8px',
49
+ padding: '24px 16px',
50
+ }}
51
+ >
52
+ {structure.children.map((child: any, index: number) => {
53
+ return (
54
+ <FxStatisticsBar
55
+ structure={child}
56
+ key={index}
57
+ filter={filter}
58
+ collapsed={collapsed}
59
+ value={initialValues ? initialValues[child.extended.object_path] : null}
60
+ />
61
+ )
62
+ })}
63
+ </Stack>
64
+ )
65
+ }
66
+ }
@@ -0,0 +1,2 @@
1
+ export { FxAggregationsBar } from './FxAggregations'
2
+ export type { AggregationsDataPropsType, AggreationsBarPropsType } from './aggregations_types'
@@ -0,0 +1,64 @@
1
+ import { gql } from 'graphql-tag'
2
+
3
+ export const STRUCTURES = gql`
4
+ query STRUCTURES {
5
+ structure(where: { name: "aggregations_invoice" }) {
6
+ _id
7
+ bundle_name
8
+ name
9
+ title
10
+ type
11
+ input_type {
12
+ name
13
+ value
14
+ }
15
+ readable_id
16
+ extended {
17
+ format
18
+ gql_operation
19
+ title_path
20
+ object_path
21
+ filter
22
+ variables
23
+ }
24
+ children(sort: { index: 1 }) {
25
+ _id
26
+ name
27
+ title
28
+ type
29
+ input_type {
30
+ name
31
+ value
32
+ }
33
+ readable_id
34
+ extended {
35
+ format
36
+ gql_operation
37
+ title_path
38
+ object_path
39
+ filter
40
+ variables
41
+ }
42
+ children(sort: { index: 1 }) {
43
+ _id
44
+ name
45
+ title
46
+ type
47
+ input_type {
48
+ name
49
+ value
50
+ }
51
+ readable_id
52
+ extended {
53
+ format
54
+ gql_operation
55
+ title_path
56
+ object_path
57
+ filter
58
+ variables
59
+ }
60
+ }
61
+ }
62
+ }
63
+ }
64
+ `
@@ -0,0 +1,362 @@
1
+ // @ts-ignore
2
+ import _ from 'lodash'
3
+
4
+ import {
5
+ Close as CloseIcon,
6
+ CheckBox as CheckBoxIcon,
7
+ CheckBoxOutlineBlank as CheckBoxOutlineBlankIcon,
8
+ KeyboardArrowDown as ArrowIcon,
9
+ } from '@mui/icons-material'
10
+
11
+ import { gql } from 'graphql-tag'
12
+ // import { getJPart } from './helpers/helpers'
13
+ import { useLazyQuery } from '@apollo/client'
14
+ import { titleCase } from '@fixefy/fixefy-ui-utils'
15
+ import React, { useEffect, useState, useRef, useImperativeHandle } from 'react'
16
+ import { Button, Checkbox, CircularProgress, useAutocomplete, useTheme, Typography } from '@mui/material'
17
+
18
+ import { Root, InputWrapper, Listbox, StyledClose, StyledListBox, Loading } from './styles/dropdown.styles'
19
+
20
+ import { AsyncDropdownPropsType, Option } from './async_dropdown_types'
21
+
22
+ const icon = <CheckBoxOutlineBlankIcon fontSize='small' />
23
+ const checkedIcon = <CheckBoxIcon fontSize='small' />
24
+
25
+ export const FxAsyncDropdown = React.forwardRef((props: AsyncDropdownPropsType, parentRef) => {
26
+ const ref = useRef(null)
27
+ const theme = useTheme()
28
+
29
+ const [options, setOptions] = useState<Option[]>([])
30
+ const [loadingData, setLoadingData] = useState(false)
31
+ const [isLastPage, setIsLastPage] = useState(false)
32
+ const [searchValue, setSearchValue] = useState<string | null>(null)
33
+ const [hasClearBtn, setHasClearBtn] = useState(false)
34
+ const [page, setPage] = useState(1)
35
+ const [prevPage, setPrevPage] = useState(0)
36
+ const [pageSize] = useState(20)
37
+
38
+ const {
39
+ debug,
40
+ structure,
41
+ onChange,
42
+ onClear,
43
+ renderOptions,
44
+ fetcher,
45
+ initialValue = {},
46
+ multiple,
47
+ disabled,
48
+ type = 'text',
49
+ showSelectedValue,
50
+ ...rest
51
+ } = props
52
+
53
+ const { name, extended, children } = structure
54
+
55
+ const { search_path, variables } = extended
56
+ const { method_name } = variables
57
+
58
+ const [fetch, { data, loading }] = useLazyQuery(gql(fetcher.query), {
59
+ ...fetcher.queryOptions,
60
+ variables: {
61
+ ...fetcher.queryOptions.variables,
62
+ where: searchValue
63
+ ? {
64
+ ...fetcher.queryOptions.variables.where,
65
+ [search_path]: searchValue,
66
+ }
67
+ : {
68
+ ...fetcher.queryOptions.variables.where,
69
+ },
70
+ skip: page * pageSize - pageSize,
71
+ limit: pageSize,
72
+ },
73
+ })
74
+
75
+ const labelOption = structure?.extended?.title_path ?? ('title' as keyof Option)
76
+
77
+ const {
78
+ getRootProps,
79
+ getInputProps,
80
+ getClearProps,
81
+ getListboxProps,
82
+ getOptionProps,
83
+ groupedOptions,
84
+ value,
85
+ popupOpen,
86
+ focused,
87
+ setAnchorEl,
88
+ } = useAutocomplete({
89
+ ...rest,
90
+ defaultValue: initialValue,
91
+ options: options,
92
+ disableCloseOnSelect: !!multiple,
93
+ multiple,
94
+ disabled: disabled,
95
+ isOptionEqualToValue: (option: any, value: any) => {
96
+ return option._id === value._id
97
+ },
98
+ getOptionLabel: (option: Option) => titleCase(option[labelOption] ?? (option.title as any)),
99
+ })
100
+
101
+ const onPopupScroll = _.debounce(() => {
102
+ if (ref && ref.current) {
103
+ //@ts-ignore
104
+ const threshHold = ref.current.scrollHeight / 2
105
+
106
+ //@ts-ignore
107
+ if (ref.current.scrollTop > threshHold && !loadingData && !isLastPage) {
108
+ setLoadingData(true)
109
+ setPage((prevPage) => prevPage + 1)
110
+ setPrevPage((prevPage) => prevPage + 1)
111
+ }
112
+ }
113
+ }, 800)
114
+
115
+ const createTitle = () => {
116
+ if (Array.isArray(value)) {
117
+ if (value && value.length) {
118
+ return `${titleCase(name)} (${value.length})`
119
+ }
120
+ }
121
+ return titleCase(name)
122
+ }
123
+
124
+ const handleSearch = _.debounce((e: React.ChangeEvent<HTMLTextAreaElement | HTMLInputElement>) => {
125
+ setSearchValue(e.target.value)
126
+ setPage(1)
127
+ }, 300)
128
+
129
+ const handleChildrens = ({ structure, ...rest }: { structure: any; onClick: (e: any) => void; startIcon: any }) => {
130
+ let rv = null
131
+ const { type, children } = structure
132
+ debug === true && console.log('handleChildrens', structure)
133
+ switch (type) {
134
+ case 'dropdownOptions':
135
+ case 'dropdown_options': {
136
+ rv = children.map((child: any) =>
137
+ handleChildrens({
138
+ structure: child,
139
+ ...rest,
140
+ }),
141
+ )
142
+ break
143
+ }
144
+ case 'clear': {
145
+ if (!hasClearBtn) {
146
+ setHasClearBtn(true)
147
+ }
148
+ rv = <Button {...rest}>{structure.title}</Button>
149
+ break
150
+ }
151
+ default: {
152
+ break
153
+ }
154
+ }
155
+
156
+ return rv
157
+ }
158
+
159
+ const handleRenderOptions = () => {
160
+ debug === true && console.log('renderOptions: ', renderOptions)
161
+
162
+ if (renderOptions) {
163
+ return (groupedOptions as typeof options).map((option: Option, index: number) => {
164
+ const CustomeComponent = renderOptions(option, index)
165
+ //@ts-ignore
166
+ return React.cloneElement(CustomeComponent, {
167
+ ...getOptionProps({ option, index }),
168
+ })
169
+ })
170
+ } else {
171
+ switch (type) {
172
+ case 'checkbox': {
173
+ return (groupedOptions as typeof options).map((option: Option, index: number) => {
174
+ const isSelected = getOptionProps({
175
+ option,
176
+ index,
177
+ })['aria-selected']
178
+
179
+ return (
180
+ <li {...getOptionProps({ option, index })}>
181
+ <Checkbox
182
+ icon={icon}
183
+ checked={Boolean(isSelected)}
184
+ checkedIcon={checkedIcon}
185
+ sx={{
186
+ mr: 1,
187
+ minWidth: 24,
188
+ minHeight: 24,
189
+ p: 0,
190
+ ['& svg']: { fill: theme.palette.primary.light },
191
+ }}
192
+ />
193
+ <Typography variant='table' color={theme.palette.typography.title}>
194
+ {titleCase(option?.title)}
195
+ </Typography>
196
+ </li>
197
+ )
198
+ })
199
+ }
200
+
201
+ case 'text': {
202
+ return (groupedOptions as typeof options).map((option: Option, index: number) => {
203
+ debug === true &&
204
+ console.log(
205
+ 'renderOptions: ',
206
+ structure?.extended?.title_path,
207
+ option[structure?.extended?.title_path],
208
+ options,
209
+ )
210
+
211
+ return (
212
+ <li {...getOptionProps({ option, index })}>
213
+ <Typography variant='table' color={theme.palette.typography.title}>
214
+ {titleCase(option[structure?.extended?.title_path] ?? option.title)}
215
+ </Typography>
216
+ </li>
217
+ )
218
+ })
219
+ }
220
+
221
+ default: {
222
+ return (groupedOptions as typeof options).map((option: Option, index: number) => {
223
+ debug === true &&
224
+ console.log(
225
+ 'renderOptions: ',
226
+ structure?.extended?.title_path,
227
+ option[structure?.extended?.title_path],
228
+ options,
229
+ )
230
+ return (
231
+ <li {...getOptionProps({ option, index })}>
232
+ <Typography variant='table' color={theme.palette.typography.title}>
233
+ {titleCase(option[structure?.extended?.title_path] ?? option.title)}
234
+ </Typography>
235
+ </li>
236
+ )
237
+ })
238
+ }
239
+ }
240
+ }
241
+ }
242
+
243
+ useImperativeHandle(parentRef, () => ({
244
+ clearDDL: () => {
245
+ //@ts-ignore
246
+ getClearProps()?.onClick(null)
247
+ },
248
+ }))
249
+
250
+ useEffect(() => {
251
+ if (ref && ref.current) {
252
+ //@ts-ignore
253
+ ref.current.addEventListener('scroll', () => onPopupScroll())
254
+ }
255
+ return () => {
256
+ if (ref && ref.current) {
257
+ //@ts-ignore
258
+ ref.current.removeEventListener('scroll', () => onPopupScroll())
259
+ }
260
+ }
261
+ }, [groupedOptions])
262
+
263
+ useEffect(() => {
264
+ onChange && onChange(value, name)
265
+ }, [value])
266
+
267
+ useEffect(() => {
268
+ if (popupOpen && !isLastPage && prevPage < page && !disabled) {
269
+ fetch()
270
+ }
271
+ }, [popupOpen])
272
+
273
+ useEffect(() => {
274
+ if (!disabled) {
275
+ fetch()
276
+ }
277
+ }, [])
278
+
279
+ useEffect(() => {
280
+ if (data && !isLastPage && prevPage < page) {
281
+ const newOptions: Option[] = data[method_name]
282
+
283
+ if (newOptions.length === 0 || newOptions.length < pageSize) {
284
+ setIsLastPage(true)
285
+ }
286
+
287
+ setOptions([...newOptions, ...options])
288
+ setLoadingData(false)
289
+ }
290
+ }, [data])
291
+
292
+ return (
293
+ <Root>
294
+ <InputWrapper
295
+ hasValue={!!(value && Object.keys(value).length)}
296
+ disabled={disabled}
297
+ sx={{
298
+ width: props.styles?.width ?? 180,
299
+ maxWidth: props.styles?.maxWidth ?? 300,
300
+ }}
301
+ {...getRootProps()}
302
+ ref={setAnchorEl}
303
+ className={focused ? 'focused' : ''}
304
+ >
305
+ <input
306
+ {...getInputProps()}
307
+ readOnly
308
+ onChange={(e) => {
309
+ //@ts-ignore
310
+ getInputProps()?.onChange(e)
311
+ handleSearch(e)
312
+ }}
313
+ placeholder={createTitle()}
314
+ value={showSelectedValue ? titleCase(value.title) : undefined}
315
+ />
316
+ {loading ? (
317
+ <Loading>
318
+ <CircularProgress />
319
+ </Loading>
320
+ ) : (
321
+ <ArrowIcon />
322
+ )}
323
+ </InputWrapper>
324
+
325
+ {groupedOptions.length > 0 && !disabled ? (
326
+ <Listbox
327
+ // sx={{
328
+ // width: props.styles?.width ?? 300,
329
+ // maxWidth: props.styles?.maxWidth ?? 300,
330
+ // minWidth: props.styles?.width ?? 300,
331
+ // }}
332
+ {...getListboxProps()}
333
+ >
334
+ <StyledListBox
335
+ sx={{
336
+ ...props.styles?.menuSx,
337
+ // width: props.styles?.width ?? 300,
338
+ }}
339
+ hasClearBtn={children?.length}
340
+ ref={ref}
341
+ >
342
+ {handleRenderOptions()}
343
+ </StyledListBox>
344
+
345
+ {children && children.length ? (
346
+ <StyledClose>
347
+ {handleChildrens({
348
+ structure: children[0],
349
+ onClick: (e: any) => {
350
+ onClear && onClear()
351
+ //@ts-ignore
352
+ getClearProps()?.onClick(e)
353
+ },
354
+ startIcon: <CloseIcon />,
355
+ })}
356
+ </StyledClose>
357
+ ) : null}
358
+ </Listbox>
359
+ ) : null}
360
+ </Root>
361
+ )
362
+ })
@@ -0,0 +1,40 @@
1
+ interface Option {
2
+ title: string
3
+ value: string | number | boolean
4
+ [key: string]: any
5
+ }
6
+
7
+ interface StylesOptions {
8
+ width?: string | number
9
+ maxWidth?: string | number
10
+ inputSx?: object
11
+ menuSx?: object
12
+ }
13
+
14
+ export type AsyncDropdownPropsType = {
15
+ debug?: boolean
16
+ initialValue?: Option | any
17
+ styles?: StylesOptions
18
+ structure: {
19
+ name: string
20
+ extended: {
21
+ title: string
22
+ title_path: string
23
+ search_path: string
24
+ variables: {
25
+ method_name: string
26
+ }
27
+ }
28
+ children: any
29
+ }
30
+ fetcher: {
31
+ query: any
32
+ queryOptions: any
33
+ }
34
+ multiple?: boolean
35
+ onChange?: (value: any, name: string) => void
36
+ type?: 'checkbox' | 'text'
37
+ renderOptions?: (option: Option, index: number) => void
38
+ [x: string]: any
39
+ showSelectedValue?: boolean
40
+ }
@@ -0,0 +1,105 @@
1
+ export const getJPart = (j: any, jsonPath: string, defaultValue?: any): any => {
2
+ // input check - if key is invalid - return error
3
+ if (isObjectValid(j) === false) return defaultValue
4
+
5
+ // convert indexes to properties
6
+ jsonPath = jsonPath.replace(/\[(\w+)\]/g, '.$1')
7
+
8
+ // strip a leading dot
9
+ jsonPath = jsonPath.replace(/^\./, '')
10
+
11
+ // split path by '.'
12
+ let _isArrayValid = false
13
+ let _isStringValid = false
14
+ let currentPathPart: any
15
+ let isLoop = true
16
+
17
+ const pathParts = jsonPath.split('.')
18
+
19
+ for (let i = 0, n = pathParts.length; isLoop && i < n; ++i) {
20
+ currentPathPart = pathParts[i]
21
+ _isStringValid = isStringValid(j)
22
+ _isArrayValid = isArrayValid(j)
23
+
24
+ if (_isStringValid === true || _isArrayValid === true) {
25
+ if (_isStringValid === true) {
26
+ j = JSON.parse(j)
27
+ } else {
28
+ j = j.reduce((acc: Array<any>, cur: any) => {
29
+ const innerJ = getJPart(
30
+ cur,
31
+ pathParts.slice(i).join("."),
32
+ defaultValue,
33
+ );
34
+
35
+ if (isArrayValid(innerJ)) {
36
+ acc.push(...innerJ)
37
+ } else {
38
+ acc.push({
39
+ ...innerJ,
40
+ value: innerJ._id,
41
+ })
42
+ }
43
+
44
+ return acc
45
+ }, [])
46
+
47
+ isLoop = false
48
+ }
49
+ } else {
50
+ if (currentPathPart in j) {
51
+ j = j[currentPathPart]
52
+ } else {
53
+ // if something in the process failed:
54
+ // 1. set the rv as the default value
55
+ // 2. stop the loop`
56
+ j = defaultValue
57
+ isLoop = false
58
+ }
59
+ }
60
+ }
61
+
62
+ return j
63
+ }
64
+
65
+ export const isArrayValid = (arr: any[], minLength: number = 1, maxLength: number = 0): boolean => {
66
+ let rv: boolean =
67
+ isObjectValid(arr) &&
68
+ arr.length >= minLength &&
69
+ //arr instanceof Array
70
+ Object.prototype.toString.call(arr) == '[object Array]'
71
+
72
+ if (maxLength > 0) {
73
+ rv = rv && arr.length <= maxLength
74
+ }
75
+
76
+ return rv
77
+ }
78
+
79
+ export const isObjectValid = (obj: any, isCheckKeys: boolean = false): boolean => {
80
+ let rv: boolean = typeof obj !== 'undefined' && obj !== null
81
+
82
+ if (isCheckKeys) {
83
+ rv = rv && Object.keys(obj).length > 0
84
+ }
85
+
86
+ return rv
87
+ }
88
+
89
+ export const isStringValid = (str: string, minLength: number | null = null, maxLength: number | null = null, isValidateType: boolean = true): boolean => {
90
+ let rv = isObjectValid(str) && str.toString().length > 0 && (isValidateType ? typeof str === 'string' : true)
91
+
92
+ if (rv === false) return false
93
+
94
+ if (minLength && isNaN(minLength) === false && minLength > 0) {
95
+ rv = rv && str.toString().length >= minLength
96
+ }
97
+
98
+ if (rv === false) return false
99
+
100
+ if (maxLength && isNaN(maxLength) === false && maxLength > 0) {
101
+ rv = rv && str.toString().length <= maxLength
102
+ }
103
+
104
+ return rv
105
+ }
@@ -0,0 +1,2 @@
1
+ export { FxAsyncDropdown } from './FxAsyncDropdown'
2
+ export type { AsyncDropdownPropsType } from './async_dropdown_types'