@pareto-engineering/design-system 5.0.0 → 5.0.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/dist/cjs/a/{AreaChart → Charts/AreaChart}/AreaChart.js +89 -73
- package/dist/cjs/a/Charts/AreaChart/styles.scss +48 -0
- package/dist/cjs/a/Charts/BarChart/BarChart.js +137 -0
- package/dist/cjs/a/Charts/BarChart/index.js +13 -0
- package/dist/cjs/a/Charts/BarChart/styles.scss +48 -0
- package/dist/cjs/a/Charts/Common/CustomLegend/CustomLegend.js +88 -0
- package/dist/cjs/a/Charts/Common/CustomLegend/index.js +13 -0
- package/dist/cjs/a/Charts/Common/CustomLegend/styles.scss +67 -0
- package/dist/cjs/a/Charts/Common/CustomTooltipContent/CustomTooltipContent.js +97 -0
- package/dist/cjs/a/Charts/Common/CustomTooltipContent/index.js +13 -0
- package/dist/cjs/a/Charts/Common/CustomTooltipContent/styles.scss +22 -0
- package/dist/cjs/a/Charts/Common/YLabelsDropDown/YlabelsDropDown.js +97 -0
- package/dist/cjs/a/Charts/Common/YLabelsDropDown/index.js +13 -0
- package/dist/cjs/a/Charts/Common/YLabelsDropDown/styles.scss +89 -0
- package/dist/cjs/a/Charts/Common/index.js +26 -0
- package/dist/cjs/a/Charts/PieChart/PieChart.js +99 -0
- package/dist/cjs/a/Charts/PieChart/index.js +13 -0
- package/dist/cjs/a/Charts/PieChart/styles.scss +48 -0
- package/dist/cjs/a/Charts/index.js +26 -0
- package/dist/cjs/a/Tooltip/styles.scss +1 -1
- package/dist/cjs/a/index.js +14 -2
- package/dist/cjs/f/FormInput/FormInput.js +6 -0
- package/dist/cjs/f/fields/FileUpload/FileUpload.js +18 -4
- package/dist/cjs/f/fields/LatexPreviewInput/LatexPreviewInput.js +78 -0
- package/dist/cjs/f/fields/LatexPreviewInput/convertLatexToHtml.js +46 -0
- package/dist/cjs/f/fields/LatexPreviewInput/index.js +20 -0
- package/dist/cjs/f/fields/LatexPreviewInput/styles.scss +24 -0
- package/dist/cjs/f/fields/index.js +13 -0
- package/dist/cjs/g/FormBuilder/FormBuilder.js +3 -6
- package/dist/cjs/g/FormBuilder/common/Builder/Builder.js +1 -3
- package/dist/cjs/g/FormBuilder/common/Builder/common/InputBuilder/InputBuilder.js +5 -7
- package/dist/cjs/g/FormBuilder/common/Builder/common/Section/Section.js +2 -4
- package/dist/cjs/g/FormBuilder/common/Renderer/Renderer.js +2 -4
- package/dist/cjs/g/FormBuilder/common/Renderer/common/Section/Section.js +2 -10
- package/dist/cjs/utils/formatting.js +119 -0
- package/dist/cjs/utils/index.js +26 -1
- package/dist/es/a/{AreaChart → Charts/AreaChart}/AreaChart.js +88 -69
- package/dist/es/a/Charts/AreaChart/styles.scss +48 -0
- package/dist/es/a/Charts/BarChart/BarChart.js +128 -0
- package/dist/es/a/Charts/BarChart/index.js +1 -0
- package/dist/es/a/Charts/BarChart/styles.scss +48 -0
- package/dist/es/a/Charts/Common/CustomLegend/CustomLegend.js +76 -0
- package/dist/es/a/Charts/Common/CustomLegend/index.js +1 -0
- package/dist/es/a/Charts/Common/CustomLegend/styles.scss +67 -0
- package/dist/es/a/Charts/Common/CustomTooltipContent/CustomTooltipContent.js +87 -0
- package/dist/es/a/Charts/Common/CustomTooltipContent/index.js +1 -0
- package/dist/es/a/Charts/Common/CustomTooltipContent/styles.scss +22 -0
- package/dist/es/a/Charts/Common/YLabelsDropDown/YlabelsDropDown.js +86 -0
- package/dist/es/a/Charts/Common/YLabelsDropDown/index.js +1 -0
- package/dist/es/a/Charts/Common/YLabelsDropDown/styles.scss +89 -0
- package/dist/es/a/Charts/Common/index.js +3 -0
- package/dist/es/a/Charts/PieChart/PieChart.js +89 -0
- package/dist/es/a/Charts/PieChart/index.js +1 -0
- package/dist/es/a/Charts/PieChart/styles.scss +48 -0
- package/dist/es/a/Charts/index.js +3 -0
- package/dist/es/a/Tooltip/styles.scss +1 -1
- package/dist/es/a/index.js +1 -1
- package/dist/es/f/FormInput/FormInput.js +7 -1
- package/dist/es/f/fields/FileUpload/FileUpload.js +18 -4
- package/dist/es/f/fields/LatexPreviewInput/LatexPreviewInput.js +70 -0
- package/dist/es/f/fields/LatexPreviewInput/convertLatexToHtml.js +31 -0
- package/dist/es/f/fields/LatexPreviewInput/index.js +3 -0
- package/dist/es/f/fields/LatexPreviewInput/styles.scss +24 -0
- package/dist/es/f/fields/index.js +1 -0
- package/dist/es/g/FormBuilder/FormBuilder.js +3 -6
- package/dist/es/g/FormBuilder/common/Builder/Builder.js +1 -3
- package/dist/es/g/FormBuilder/common/Builder/common/InputBuilder/InputBuilder.js +5 -7
- package/dist/es/g/FormBuilder/common/Builder/common/Section/Section.js +2 -4
- package/dist/es/g/FormBuilder/common/Renderer/Renderer.js +2 -4
- package/dist/es/g/FormBuilder/common/Renderer/common/Section/Section.js +32 -42
- package/dist/es/utils/formatting.js +109 -0
- package/dist/es/utils/index.js +2 -1
- package/jest.config.js +3 -0
- package/package.json +7 -3
- package/src/stories/a/AreaChart.stories.jsx +1 -1
- package/src/stories/a/BarChart.stories.jsx +89 -0
- package/src/stories/a/PieChart.stories.jsx +53 -0
- package/src/ui/a/{AreaChart → Charts/AreaChart}/AreaChart.jsx +114 -65
- package/src/ui/a/Charts/AreaChart/styles.scss +48 -0
- package/src/ui/a/Charts/BarChart/BarChart.jsx +167 -0
- package/src/ui/a/Charts/BarChart/index.js +1 -0
- package/src/ui/a/Charts/BarChart/styles.scss +48 -0
- package/src/ui/a/Charts/Common/CustomLegend/CustomLegend.jsx +109 -0
- package/src/ui/a/Charts/Common/CustomLegend/index.js +1 -0
- package/src/ui/a/Charts/Common/CustomLegend/styles.scss +67 -0
- package/src/ui/a/Charts/Common/CustomTooltipContent/CustomTooltipContent.jsx +117 -0
- package/src/ui/a/Charts/Common/CustomTooltipContent/index.js +1 -0
- package/src/ui/a/Charts/Common/CustomTooltipContent/styles.scss +22 -0
- package/src/ui/a/Charts/Common/YLabelsDropDown/YlabelsDropDown.jsx +121 -0
- package/src/ui/a/Charts/Common/YLabelsDropDown/index.js +1 -0
- package/src/ui/a/Charts/Common/YLabelsDropDown/styles.scss +89 -0
- package/src/ui/a/Charts/Common/index.js +3 -0
- package/src/ui/a/Charts/PieChart/PieChart.jsx +125 -0
- package/src/ui/a/Charts/PieChart/index.js +1 -0
- package/src/ui/a/Charts/PieChart/styles.scss +48 -0
- package/src/ui/a/Charts/index.js +3 -0
- package/src/ui/a/Tooltip/styles.scss +1 -1
- package/src/ui/a/index.js +1 -1
- package/src/ui/f/FormInput/FormInput.jsx +11 -0
- package/src/ui/f/fields/FileUpload/FileUpload.jsx +24 -4
- package/src/ui/f/fields/LatexPreviewInput/LatexPreviewInput.jsx +91 -0
- package/src/ui/f/fields/LatexPreviewInput/convertLatexToHtml.jsx +38 -0
- package/src/ui/f/fields/LatexPreviewInput/index.js +3 -0
- package/src/ui/f/fields/LatexPreviewInput/styles.scss +24 -0
- package/src/ui/f/fields/index.js +4 -0
- package/src/ui/g/FormBuilder/FormBuilder.jsx +0 -3
- package/src/ui/g/FormBuilder/common/Builder/Builder.jsx +0 -2
- package/src/ui/g/FormBuilder/common/Builder/common/InputBuilder/InputBuilder.jsx +4 -7
- package/src/ui/g/FormBuilder/common/Builder/common/Section/Section.jsx +0 -2
- package/src/ui/g/FormBuilder/common/Renderer/Renderer.jsx +0 -2
- package/src/ui/g/FormBuilder/common/Renderer/common/Section/Section.jsx +49 -64
- package/src/ui/utils/formatting.js +133 -0
- package/src/ui/utils/index.js +3 -0
- package/tests/__snapshots__/Storyshots.test.js.snap +2227 -296
- package/tests/emptyMock.js +3 -0
- package/tests/mockTextEncoder.js +7 -0
- package/tests/test-setup.js +7 -0
- package/dist/cjs/a/AreaChart/styles.scss +0 -89
- package/dist/es/a/AreaChart/styles.scss +0 -89
- package/src/ui/a/AreaChart/styles.scss +0 -89
- /package/dist/cjs/a/{AreaChart → Charts/AreaChart}/index.js +0 -0
- /package/dist/es/a/{AreaChart → Charts/AreaChart}/index.js +0 -0
- /package/src/ui/a/{AreaChart → Charts/AreaChart}/index.js +0 -0
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/* @pareto-engineering/generator-front 1.0.12 */
|
|
2
|
+
import * as React from 'react'
|
|
3
|
+
|
|
4
|
+
import { memo, useMemo } from 'react'
|
|
5
|
+
|
|
6
|
+
import PropTypes from 'prop-types'
|
|
7
|
+
|
|
8
|
+
import styleNames from '@pareto-engineering/bem/exports'
|
|
9
|
+
|
|
10
|
+
import { useFormikContext } from 'formik'
|
|
11
|
+
|
|
12
|
+
import convertLatexToHtml from './convertLatexToHtml'
|
|
13
|
+
|
|
14
|
+
import { TextareaInput } from '../TextareaInput'
|
|
15
|
+
|
|
16
|
+
import './styles.scss'
|
|
17
|
+
|
|
18
|
+
// Local Definitions
|
|
19
|
+
|
|
20
|
+
const baseClassName = styleNames.base
|
|
21
|
+
|
|
22
|
+
const componentClassName = 'latex-preview-input'
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* This is the component description.
|
|
26
|
+
*/
|
|
27
|
+
const LatexPreviewInput = ({
|
|
28
|
+
id,
|
|
29
|
+
className,
|
|
30
|
+
userClassName,
|
|
31
|
+
disabled,
|
|
32
|
+
style,
|
|
33
|
+
...otherProps
|
|
34
|
+
}) => {
|
|
35
|
+
const { name } = otherProps
|
|
36
|
+
|
|
37
|
+
const { values } = useFormikContext()
|
|
38
|
+
|
|
39
|
+
const LatexPreview = useMemo(() => convertLatexToHtml(values[name]), [values[name]])
|
|
40
|
+
|
|
41
|
+
return (
|
|
42
|
+
<div
|
|
43
|
+
id={id}
|
|
44
|
+
className={[
|
|
45
|
+
baseClassName,
|
|
46
|
+
componentClassName,
|
|
47
|
+
userClassName,
|
|
48
|
+
'form-input',
|
|
49
|
+
]
|
|
50
|
+
.filter((e) => e)
|
|
51
|
+
.join(' ')}
|
|
52
|
+
style={style}
|
|
53
|
+
>
|
|
54
|
+
<TextareaInput
|
|
55
|
+
className="preview-child"
|
|
56
|
+
disabled={disabled}
|
|
57
|
+
{...otherProps}
|
|
58
|
+
/>
|
|
59
|
+
{/* eslint-disable-next-line react/no-danger */}
|
|
60
|
+
<div className="latex-container preview-child" dangerouslySetInnerHTML={{ __html: LatexPreview }} />
|
|
61
|
+
</div>
|
|
62
|
+
)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
LatexPreviewInput.propTypes = {
|
|
66
|
+
/**
|
|
67
|
+
* The HTML id for this element
|
|
68
|
+
*/
|
|
69
|
+
id:PropTypes.string,
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* The HTML class names for this element
|
|
73
|
+
*/
|
|
74
|
+
className:PropTypes.string,
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* The React-written, css properties for this element.
|
|
78
|
+
*/
|
|
79
|
+
style:PropTypes.objectOf(PropTypes.string),
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Whether the Form input input should be disabled
|
|
83
|
+
*/
|
|
84
|
+
disabled:PropTypes.bool,
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
LatexPreviewInput.defaultProps = {
|
|
88
|
+
disabled:false,
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export default memo(LatexPreviewInput)
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import * as React from 'react'
|
|
2
|
+
|
|
3
|
+
import ReactMarkdown from 'react-markdown'
|
|
4
|
+
|
|
5
|
+
import RemarkMathPlugin from 'remark-math'
|
|
6
|
+
|
|
7
|
+
import { MathJax, MathJaxContext } from 'better-react-mathjax'
|
|
8
|
+
|
|
9
|
+
import rehypeMathjax from 'rehype-mathjax/svg'
|
|
10
|
+
|
|
11
|
+
import ReactDOMServer from 'react-dom/server'
|
|
12
|
+
|
|
13
|
+
const convertLatexToHtml = (content) => {
|
|
14
|
+
if (content.includes('https://forte-assets.pareto.ai/')) {
|
|
15
|
+
return content
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const processedContent = content.replaceAll(/\\\\/g, '\n\n')
|
|
19
|
+
|
|
20
|
+
const renderedContent = ReactDOMServer.renderToString(
|
|
21
|
+
<MathJaxContext>
|
|
22
|
+
<ReactMarkdown
|
|
23
|
+
remarkPlugins={[RemarkMathPlugin]}
|
|
24
|
+
rehypePlugins={[rehypeMathjax]}
|
|
25
|
+
components={{
|
|
26
|
+
math :({ value }) => <MathJax.Node formula={value} />,
|
|
27
|
+
inlineMath:({ value }) => <MathJax.Node inline formula={value} />,
|
|
28
|
+
}}
|
|
29
|
+
>
|
|
30
|
+
{processedContent}
|
|
31
|
+
</ReactMarkdown>
|
|
32
|
+
</MathJaxContext>,
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
return renderedContent
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export default convertLatexToHtml
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/* @pareto-engineering/generator-front 1.0.12 */
|
|
2
|
+
|
|
3
|
+
@use "@pareto-engineering/bem";
|
|
4
|
+
|
|
5
|
+
$default-margin: 1em;
|
|
6
|
+
|
|
7
|
+
.#{bem.$base}.latex-preview-input {
|
|
8
|
+
display: flex;
|
|
9
|
+
flex-direction: row;
|
|
10
|
+
gap: $default-margin;
|
|
11
|
+
|
|
12
|
+
> .preview-child {
|
|
13
|
+
flex: 1;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
> .latex-container {
|
|
17
|
+
border: 1px solid var(--ui-lines);
|
|
18
|
+
border-radius: var(--theme-default-border-radius);
|
|
19
|
+
margin-top: calc($default-margin * 2.5);
|
|
20
|
+
max-width: 50%;
|
|
21
|
+
overflow: auto;
|
|
22
|
+
padding: 0 $default-margin;
|
|
23
|
+
}
|
|
24
|
+
}
|
package/src/ui/f/fields/index.js
CHANGED
|
@@ -9,6 +9,10 @@ export { Checkbox } from './Checkbox'
|
|
|
9
9
|
export { QueryChoices } from './QueryChoices'
|
|
10
10
|
export { LinkInput } from './LinkInput'
|
|
11
11
|
export { EditorInput } from './EditorInput'
|
|
12
|
+
export {
|
|
13
|
+
LatexPreviewInput,
|
|
14
|
+
convertLatexToHtml,
|
|
15
|
+
} from './LatexPreviewInput'
|
|
12
16
|
export {
|
|
13
17
|
FileUpload,
|
|
14
18
|
fileUploadOptions,
|
|
@@ -36,7 +36,6 @@ const FormBuilder = ({
|
|
|
36
36
|
fileUploadStatus,
|
|
37
37
|
handleFileDelete,
|
|
38
38
|
taskData,
|
|
39
|
-
customInputMap,
|
|
40
39
|
// ...otherProps
|
|
41
40
|
}) => {
|
|
42
41
|
const formattedJson = JSON.stringify(taskData, null, 2)
|
|
@@ -68,7 +67,6 @@ const FormBuilder = ({
|
|
|
68
67
|
onSave={onBuilderFormSave}
|
|
69
68
|
onError={onBuilderError}
|
|
70
69
|
validate={onBuilderValidate}
|
|
71
|
-
customInputMap={customInputMap}
|
|
72
70
|
/>
|
|
73
71
|
)}
|
|
74
72
|
{mode === 'render' && (
|
|
@@ -80,7 +78,6 @@ const FormBuilder = ({
|
|
|
80
78
|
fileUploadStatus={fileUploadStatus}
|
|
81
79
|
handleFileDelete={handleFileDelete}
|
|
82
80
|
onFileUpload={onFileUpload}
|
|
83
|
-
customInputMap={customInputMap}
|
|
84
81
|
/>
|
|
85
82
|
)}
|
|
86
83
|
</div>
|
|
@@ -43,7 +43,6 @@ const Builder = ({
|
|
|
43
43
|
onError,
|
|
44
44
|
validate,
|
|
45
45
|
formBuilderId,
|
|
46
|
-
customInputMap,
|
|
47
46
|
initialValues = {},
|
|
48
47
|
// ...otherProps
|
|
49
48
|
}) => {
|
|
@@ -126,7 +125,6 @@ const Builder = ({
|
|
|
126
125
|
handleDeleteSection={() => handleDeleteSection({
|
|
127
126
|
index, remove, values, setFieldValue,
|
|
128
127
|
})}
|
|
129
|
-
customInputMap={customInputMap}
|
|
130
128
|
/>
|
|
131
129
|
))}
|
|
132
130
|
<div className="section-footer">
|
|
@@ -41,7 +41,6 @@ const InputBuilder = ({
|
|
|
41
41
|
sectionIndex,
|
|
42
42
|
inputIndex,
|
|
43
43
|
onDelete,
|
|
44
|
-
customInputMap,
|
|
45
44
|
// ...otherProps
|
|
46
45
|
}) => {
|
|
47
46
|
const { values, setFieldValue } = useFormikContext()
|
|
@@ -71,8 +70,6 @@ const InputBuilder = ({
|
|
|
71
70
|
setFieldValue(`sections.${sectionIndex}.inputs.${inputIndex}.showSpecificFileTypes`, !input.showSpecificFileTypes)
|
|
72
71
|
}
|
|
73
72
|
|
|
74
|
-
const customInputTypes = customInputMap ? Object.keys(customInputMap) : []
|
|
75
|
-
|
|
76
73
|
return (
|
|
77
74
|
<div
|
|
78
75
|
id={id}
|
|
@@ -130,10 +127,10 @@ const InputBuilder = ({
|
|
|
130
127
|
value:'file',
|
|
131
128
|
label:'File upload',
|
|
132
129
|
},
|
|
133
|
-
|
|
134
|
-
value:
|
|
135
|
-
label:
|
|
136
|
-
}
|
|
130
|
+
{
|
|
131
|
+
value:'latex-preview-input',
|
|
132
|
+
label:'Textbox with LaTeX preview',
|
|
133
|
+
},
|
|
137
134
|
]}
|
|
138
135
|
/>
|
|
139
136
|
<div className="controls">
|
|
@@ -36,7 +36,6 @@ const Section = ({
|
|
|
36
36
|
style,
|
|
37
37
|
index,
|
|
38
38
|
handleDeleteSection,
|
|
39
|
-
customInputMap,
|
|
40
39
|
// ...otherProps
|
|
41
40
|
}) => {
|
|
42
41
|
const { values, setFieldValue } = useFormikContext()
|
|
@@ -70,7 +69,6 @@ const Section = ({
|
|
|
70
69
|
inputIndex={indx}
|
|
71
70
|
onDelete={handleDeleteInput}
|
|
72
71
|
onCopy={handleCopyInput}
|
|
73
|
-
customInputMap={customInputMap}
|
|
74
72
|
/>,
|
|
75
73
|
identifier:input.name,
|
|
76
74
|
}))
|
|
@@ -78,7 +78,6 @@ const Renderer = ({
|
|
|
78
78
|
handleFileDelete,
|
|
79
79
|
onFileUpload,
|
|
80
80
|
shouldUpdateInputStateInRealTime = true,
|
|
81
|
-
customInputMap,
|
|
82
81
|
// ...otherProps
|
|
83
82
|
}) => {
|
|
84
83
|
const [currentSectionIndex, setCurrentSectionIndex] = useState(0)
|
|
@@ -179,7 +178,6 @@ const Renderer = ({
|
|
|
179
178
|
handleFileDelete={handleFileDelete}
|
|
180
179
|
onFileUpload={onFileUpload}
|
|
181
180
|
sectionIndex={sectionIndex}
|
|
182
|
-
customInputMap={customInputMap}
|
|
183
181
|
/>
|
|
184
182
|
)
|
|
185
183
|
))}
|
|
@@ -40,71 +40,56 @@ const Section = ({
|
|
|
40
40
|
handleFileDelete,
|
|
41
41
|
onFileUpload,
|
|
42
42
|
sectionIndex,
|
|
43
|
-
customInputMap,
|
|
44
43
|
// ...otherProps
|
|
45
|
-
}) =>
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
})}
|
|
95
|
-
/>
|
|
96
|
-
) : (
|
|
97
|
-
<CustomInputComponent
|
|
98
|
-
key={input.name}
|
|
99
|
-
{...input}
|
|
100
|
-
disabled={readOnly}
|
|
101
|
-
/>
|
|
102
|
-
)
|
|
103
|
-
)
|
|
104
|
-
})}
|
|
105
|
-
</div>
|
|
106
|
-
)
|
|
107
|
-
}
|
|
44
|
+
}) => (
|
|
45
|
+
<div
|
|
46
|
+
id={id}
|
|
47
|
+
className={[
|
|
48
|
+
baseClassName,
|
|
49
|
+
componentClassName,
|
|
50
|
+
userClassName,
|
|
51
|
+
]
|
|
52
|
+
.filter((e) => e)
|
|
53
|
+
.join(' ')}
|
|
54
|
+
style={style}
|
|
55
|
+
>
|
|
56
|
+
<p className="h3">{title}</p>
|
|
57
|
+
<ExpandableLexicalPreview
|
|
58
|
+
nodes={description}
|
|
59
|
+
name="instructions"
|
|
60
|
+
/>
|
|
61
|
+
{inputs?.map((input, inputIndex) => {
|
|
62
|
+
const isFileInput = input.type === 'file'
|
|
63
|
+
|
|
64
|
+
return (
|
|
65
|
+
<FormInput
|
|
66
|
+
key={input.name}
|
|
67
|
+
{...input}
|
|
68
|
+
disabled={readOnly}
|
|
69
|
+
{...(isFileInput && {
|
|
70
|
+
uploadStatus:fileUploadStatus,
|
|
71
|
+
handleFileDelete,
|
|
72
|
+
onChange :(files) => {
|
|
73
|
+
const filesToUpload = files
|
|
74
|
+
?.filter((file) => file instanceof File)
|
|
75
|
+
.map((file) => ({
|
|
76
|
+
file,
|
|
77
|
+
name :file.name,
|
|
78
|
+
mimeType:file.type,
|
|
79
|
+
type :fileTypeMapper[getFileType(file)] || 'Generic',
|
|
80
|
+
title :file.name,
|
|
81
|
+
sectionIndex,
|
|
82
|
+
inputIndex,
|
|
83
|
+
}))
|
|
84
|
+
|
|
85
|
+
onFileUpload(filesToUpload)
|
|
86
|
+
},
|
|
87
|
+
})}
|
|
88
|
+
/>
|
|
89
|
+
)
|
|
90
|
+
})}
|
|
91
|
+
</div>
|
|
92
|
+
)
|
|
108
93
|
|
|
109
94
|
Section.propTypes = {
|
|
110
95
|
/**
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
export const DATE_FORMATS = {
|
|
2
|
+
HUMAN_READABLE:'human_readable',
|
|
3
|
+
TIME :'time',
|
|
4
|
+
DATETIME :'datetime',
|
|
5
|
+
CHART_DATE :'chart_date',
|
|
6
|
+
CHART_TIME :'chart_time',
|
|
7
|
+
WEEKDAY_DATE :'weekday_date',
|
|
8
|
+
DAY_VIEW :'day_view',
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const isValidDate = (date) => date instanceof Date && !Number.isNaN(date)
|
|
12
|
+
|
|
13
|
+
const isTimeSliceFormat = (input) => {
|
|
14
|
+
const timeSliceRegex = /^([01]?[0-9]|2[0-3]):[0-5][0-9]$/
|
|
15
|
+
return timeSliceRegex.test(input)
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const createTimeFromSlice = (timeSlice) => {
|
|
19
|
+
const [hours, minutes] = timeSlice.split(':').map(Number)
|
|
20
|
+
const date = new Date()
|
|
21
|
+
date.setHours(hours, minutes, 0, 0)
|
|
22
|
+
return date
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const format12Hour = (date) => {
|
|
26
|
+
const hour = date.getHours()
|
|
27
|
+
const ampm = hour >= 12 ? 'PM' : 'AM'
|
|
28
|
+
const hour12 = hour % 12 || 12
|
|
29
|
+
return `${hour12} ${ampm}`
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const shouldShowYear = (date) => {
|
|
33
|
+
const currentYear = new Date().getFullYear()
|
|
34
|
+
return date.getFullYear() !== currentYear
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export const formatTime = (seconds) => {
|
|
38
|
+
if (!seconds) return '0s'
|
|
39
|
+
|
|
40
|
+
const hours = Math.floor(seconds / 3600)
|
|
41
|
+
const minutes = Math.floor((seconds % 3600) / 60)
|
|
42
|
+
const remainingSeconds = Math.floor(seconds % 60)
|
|
43
|
+
|
|
44
|
+
const parts = []
|
|
45
|
+
if (hours > 0) parts.push(`${hours}h`)
|
|
46
|
+
if (minutes > 0 || (hours > 0 && remainingSeconds > 0)) parts.push(`${minutes}m`)
|
|
47
|
+
if (remainingSeconds > 0) parts.push(`${remainingSeconds}s`)
|
|
48
|
+
|
|
49
|
+
// Cater for decimal seconds
|
|
50
|
+
if (parts.length === 0) return '0s'
|
|
51
|
+
|
|
52
|
+
return parts.join(' ')
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const parseDate = (input) => {
|
|
56
|
+
if (input instanceof Date) return input
|
|
57
|
+
if (typeof input === 'number') return new Date(input)
|
|
58
|
+
|
|
59
|
+
if (typeof input === 'string') {
|
|
60
|
+
if (isTimeSliceFormat(input)) {
|
|
61
|
+
return createTimeFromSlice(input)
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const parsed = new Date(input)
|
|
65
|
+
if (isValidDate(parsed)) return parsed
|
|
66
|
+
|
|
67
|
+
const timestamp = parseInt(input, 10)
|
|
68
|
+
if (!Number.isNaN(timestamp)) {
|
|
69
|
+
const date = new Date(timestamp * 1000)
|
|
70
|
+
if (isValidDate(date)) return date
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return null
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const formatStrategies = {
|
|
78
|
+
[DATE_FORMATS.CHART_DATE]:(date) => {
|
|
79
|
+
const monthDay = date.toLocaleDateString('en-US', {
|
|
80
|
+
month :'short',
|
|
81
|
+
day :'numeric',
|
|
82
|
+
timeZone:'UTC',
|
|
83
|
+
})
|
|
84
|
+
return shouldShowYear(date)
|
|
85
|
+
? `${monthDay} ${date.getFullYear()}`
|
|
86
|
+
: monthDay
|
|
87
|
+
},
|
|
88
|
+
|
|
89
|
+
[DATE_FORMATS.CHART_TIME]:(date) => format12Hour(date),
|
|
90
|
+
|
|
91
|
+
[DATE_FORMATS.HUMAN_READABLE]:(date) => date.toLocaleDateString('en-US', {
|
|
92
|
+
year :'numeric',
|
|
93
|
+
month :'short',
|
|
94
|
+
day :'numeric',
|
|
95
|
+
timeZone:'UTC',
|
|
96
|
+
}),
|
|
97
|
+
|
|
98
|
+
default:(date) => date.toISOString(),
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export const formatDate = (input, format = DATE_FORMATS.HUMAN_READABLE) => {
|
|
102
|
+
try {
|
|
103
|
+
if (typeof input === 'string' && isTimeSliceFormat(input)) {
|
|
104
|
+
if (format === DATE_FORMATS.CHART_TIME || format === DATE_FORMATS.TIME) {
|
|
105
|
+
const date = createTimeFromSlice(input)
|
|
106
|
+
if (format === DATE_FORMATS.CHART_TIME) {
|
|
107
|
+
return format12Hour(date)
|
|
108
|
+
}
|
|
109
|
+
return date.toLocaleTimeString('en-US', {
|
|
110
|
+
hour :'2-digit',
|
|
111
|
+
minute :'2-digit',
|
|
112
|
+
timeZone:'UTC',
|
|
113
|
+
})
|
|
114
|
+
}
|
|
115
|
+
return input
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const date = parseDate(input)
|
|
119
|
+
if (!date && (typeof input === 'string' || typeof input === 'number')) {
|
|
120
|
+
return input.toString()
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const formatStrategy = formatStrategies[format] || formatStrategies.default
|
|
124
|
+
return formatStrategy(date)
|
|
125
|
+
} catch (error) {
|
|
126
|
+
return 'Invalid Date'
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
export const snakeCaseToTitleCase = (word) => {
|
|
131
|
+
const result = word.replace(/([A-Z])/g, ' $1')
|
|
132
|
+
return result.charAt(0).toUpperCase() + result.slice(1)
|
|
133
|
+
}
|
package/src/ui/utils/index.js
CHANGED