@pareto-engineering/design-system 5.2.0 → 5.3.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.
- package/dist/cjs/a/Charts/AreaChart/AreaChart.js +61 -5
- package/dist/cjs/a/Charts/AreaChart/styles.scss +22 -0
- package/dist/cjs/a/Charts/BarChart/BarChart.js +1 -0
- package/dist/cjs/a/Charts/Common/CustomLegend/CustomLegend.js +23 -5
- package/dist/cjs/a/Charts/Common/CustomLegend/styles.scss +10 -2
- package/dist/cjs/a/Charts/Common/CustomTooltipContent/CustomTooltipContent.js +139 -42
- package/dist/cjs/a/Charts/Common/CustomTooltipContent/styles.scss +4 -0
- package/dist/cjs/a/Charts/PieChart/PieChart.js +39 -8
- package/dist/cjs/a/Charts/PieChart/styles.scss +88 -0
- package/dist/cjs/a/HamburgerButton/styles.scss +151 -9
- package/dist/cjs/a/ThroughPutIndicator/ThroughPutIndicator.js +78 -0
- package/dist/cjs/a/ThroughPutIndicator/index.js +13 -0
- package/dist/cjs/a/ThroughPutIndicator/styles.scss +35 -0
- package/dist/cjs/a/ToggleSwitch/ToggleSwitch.js +2 -1
- package/dist/cjs/a/ToggleSwitch/styles.scss +9 -2
- package/dist/cjs/a/Tooltip/Tooltip.js +19 -2
- package/dist/cjs/a/Tooltip/styles.scss +32 -4
- package/dist/cjs/a/XMLEditor/XMLEditor.js +4 -1
- package/dist/cjs/a/index.js +8 -1
- package/dist/cjs/f/FormInput/FormInput.js +7 -1
- package/dist/cjs/f/fields/ToggleInput/ToggleInput.js +126 -0
- package/dist/cjs/f/fields/ToggleInput/index.js +13 -0
- package/dist/cjs/f/fields/ToggleInput/styles.scss +22 -0
- package/dist/cjs/f/fields/index.js +8 -1
- package/dist/cjs/utils/formatting.js +27 -18
- package/dist/cjs/utils/index.js +6 -0
- package/dist/es/a/Charts/AreaChart/AreaChart.js +62 -6
- package/dist/es/a/Charts/AreaChart/styles.scss +22 -0
- package/dist/es/a/Charts/BarChart/BarChart.js +1 -0
- package/dist/es/a/Charts/Common/CustomLegend/CustomLegend.js +23 -5
- package/dist/es/a/Charts/Common/CustomLegend/styles.scss +10 -2
- package/dist/es/a/Charts/Common/CustomTooltipContent/CustomTooltipContent.js +128 -40
- package/dist/es/a/Charts/Common/CustomTooltipContent/styles.scss +4 -0
- package/dist/es/a/Charts/PieChart/PieChart.js +39 -8
- package/dist/es/a/Charts/PieChart/styles.scss +88 -0
- package/dist/es/a/HamburgerButton/styles.scss +151 -9
- package/dist/es/a/ThroughPutIndicator/ThroughPutIndicator.js +66 -0
- package/dist/es/a/ThroughPutIndicator/index.js +2 -0
- package/dist/es/a/ThroughPutIndicator/styles.scss +35 -0
- package/dist/es/a/ToggleSwitch/ToggleSwitch.js +2 -1
- package/dist/es/a/ToggleSwitch/styles.scss +9 -2
- package/dist/es/a/Tooltip/Tooltip.js +31 -12
- package/dist/es/a/Tooltip/styles.scss +32 -4
- package/dist/es/a/XMLEditor/XMLEditor.js +6 -3
- package/dist/es/a/index.js +2 -1
- package/dist/es/f/FormInput/FormInput.js +8 -2
- package/dist/es/f/fields/ToggleInput/ToggleInput.js +116 -0
- package/dist/es/f/fields/ToggleInput/index.js +2 -0
- package/dist/es/f/fields/ToggleInput/styles.scss +22 -0
- package/dist/es/f/fields/index.js +2 -1
- package/dist/es/utils/formatting.js +25 -17
- package/dist/es/utils/index.js +1 -1
- package/package.json +7 -6
- package/src/ui/a/Charts/AreaChart/AreaChart.jsx +74 -9
- package/src/ui/a/Charts/AreaChart/styles.scss +22 -0
- package/src/ui/a/Charts/BarChart/BarChart.jsx +1 -0
- package/src/ui/a/Charts/Common/CustomLegend/CustomLegend.jsx +26 -3
- package/src/ui/a/Charts/Common/CustomLegend/styles.scss +10 -2
- package/src/ui/a/Charts/Common/CustomTooltipContent/CustomTooltipContent.jsx +132 -48
- package/src/ui/a/Charts/Common/CustomTooltipContent/styles.scss +4 -0
- package/src/ui/a/Charts/PieChart/PieChart.jsx +54 -16
- package/src/ui/a/Charts/PieChart/styles.scss +88 -0
- package/src/ui/a/HamburgerButton/styles.scss +151 -9
- package/src/ui/a/ThroughPutIndicator/ThroughPutIndicator.jsx +90 -0
- package/src/ui/a/ThroughPutIndicator/index.js +2 -0
- package/src/ui/a/ThroughPutIndicator/styles.scss +35 -0
- package/src/ui/a/ToggleSwitch/ToggleSwitch.jsx +1 -1
- package/src/ui/a/ToggleSwitch/styles.scss +9 -2
- package/src/ui/a/Tooltip/Tooltip.jsx +55 -26
- package/src/ui/a/Tooltip/styles.scss +32 -4
- package/src/ui/a/XMLEditor/XMLEditor.jsx +15 -2
- package/src/ui/a/index.js +1 -0
- package/src/ui/f/FormInput/FormInput.jsx +11 -0
- package/src/ui/f/fields/ToggleInput/ToggleInput.jsx +140 -0
- package/src/ui/f/fields/ToggleInput/index.js +2 -0
- package/src/ui/f/fields/ToggleInput/styles.scss +22 -0
- package/src/ui/f/fields/index.js +1 -0
- package/src/ui/utils/formatting.js +38 -29
- package/src/ui/utils/index.js +1 -1
- package/tests/__snapshots__/Storyshots.test.js.snap +433 -160
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/* @pareto-engineering/generator-front 1.1.1-alpha.3 */
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import PropTypes from 'prop-types';
|
|
4
|
+
import { useField } from 'formik';
|
|
5
|
+
import styleNames from '@pareto-engineering/bem/exports';
|
|
6
|
+
import { ToggleSwitch } from "../../../a";
|
|
7
|
+
import { FormLabel, FormDescription } from "../../common";
|
|
8
|
+
import "./styles.scss";
|
|
9
|
+
|
|
10
|
+
// Local Definitions
|
|
11
|
+
const baseClassName = styleNames.base;
|
|
12
|
+
const componentClassName = 'toggle-input';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Toggle input field component that wraps ToggleSwitch for use with Formik
|
|
16
|
+
*/
|
|
17
|
+
const ToggleInput = ({
|
|
18
|
+
id,
|
|
19
|
+
className: userClassName,
|
|
20
|
+
style,
|
|
21
|
+
name,
|
|
22
|
+
label,
|
|
23
|
+
color,
|
|
24
|
+
labelColor,
|
|
25
|
+
validate,
|
|
26
|
+
description,
|
|
27
|
+
disabled,
|
|
28
|
+
optional,
|
|
29
|
+
size
|
|
30
|
+
// ...otherProps
|
|
31
|
+
}) => {
|
|
32
|
+
const [field,, helpers] = useField({
|
|
33
|
+
name,
|
|
34
|
+
validate,
|
|
35
|
+
type: 'checkbox'
|
|
36
|
+
});
|
|
37
|
+
const handleChange = () => {
|
|
38
|
+
helpers.setValue(!field.value);
|
|
39
|
+
};
|
|
40
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
41
|
+
id: id,
|
|
42
|
+
className: [baseClassName, componentClassName, userClassName, `y-${color}`].filter(e => e).join(' '),
|
|
43
|
+
style: style
|
|
44
|
+
}, /*#__PURE__*/React.createElement(FormLabel, {
|
|
45
|
+
name: name,
|
|
46
|
+
color: labelColor,
|
|
47
|
+
optional: optional
|
|
48
|
+
}, label), /*#__PURE__*/React.createElement("div", {
|
|
49
|
+
className: "toggle-wrapper"
|
|
50
|
+
}, /*#__PURE__*/React.createElement(ToggleSwitch, {
|
|
51
|
+
checked: Boolean(field.value),
|
|
52
|
+
handleOnChange: handleChange,
|
|
53
|
+
inputId: name,
|
|
54
|
+
size: size,
|
|
55
|
+
disabled: disabled
|
|
56
|
+
})), /*#__PURE__*/React.createElement(FormDescription, {
|
|
57
|
+
className: "s-1",
|
|
58
|
+
description: description,
|
|
59
|
+
name: name
|
|
60
|
+
}));
|
|
61
|
+
};
|
|
62
|
+
ToggleInput.propTypes = {
|
|
63
|
+
/**
|
|
64
|
+
* The HTML id for this element
|
|
65
|
+
*/
|
|
66
|
+
id: PropTypes.string,
|
|
67
|
+
/**
|
|
68
|
+
* The HTML class names for this element
|
|
69
|
+
*/
|
|
70
|
+
className: PropTypes.string,
|
|
71
|
+
/**
|
|
72
|
+
* The React-written, css properties for this element.
|
|
73
|
+
*/
|
|
74
|
+
style: PropTypes.objectOf(PropTypes.string),
|
|
75
|
+
/**
|
|
76
|
+
* The input name (html - and Formik state)
|
|
77
|
+
*/
|
|
78
|
+
name: PropTypes.string.isRequired,
|
|
79
|
+
/**
|
|
80
|
+
* The input label
|
|
81
|
+
*/
|
|
82
|
+
label: PropTypes.string.isRequired,
|
|
83
|
+
/**
|
|
84
|
+
* The input label color
|
|
85
|
+
*/
|
|
86
|
+
labelColor: PropTypes.string,
|
|
87
|
+
/**
|
|
88
|
+
* The input field validator function
|
|
89
|
+
*/
|
|
90
|
+
validate: PropTypes.func,
|
|
91
|
+
/**
|
|
92
|
+
* Input description
|
|
93
|
+
*/
|
|
94
|
+
description: PropTypes.string,
|
|
95
|
+
/**
|
|
96
|
+
* Whether the toggle input should be disabled
|
|
97
|
+
*/
|
|
98
|
+
disabled: PropTypes.bool,
|
|
99
|
+
/**
|
|
100
|
+
* The text input color
|
|
101
|
+
*/
|
|
102
|
+
color: PropTypes.string,
|
|
103
|
+
/**
|
|
104
|
+
* Whether the input is optional or not
|
|
105
|
+
*/
|
|
106
|
+
optional: PropTypes.bool,
|
|
107
|
+
/**
|
|
108
|
+
* The size of the toggle switch
|
|
109
|
+
*/
|
|
110
|
+
size: PropTypes.string
|
|
111
|
+
};
|
|
112
|
+
ToggleInput.defaultProps = {
|
|
113
|
+
color: 'paragraph',
|
|
114
|
+
disabled: false
|
|
115
|
+
};
|
|
116
|
+
export default ToggleInput;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/* @pareto-engineering/generator-front 1.1.1-alpha.3 */
|
|
2
|
+
|
|
3
|
+
@use "@pareto-engineering/bem";
|
|
4
|
+
@use "@pareto-engineering/styles/src/mixins";
|
|
5
|
+
@use "@pareto-engineering/styles/src/globals" as *;
|
|
6
|
+
|
|
7
|
+
.#{bem.$base}.toggle-input {
|
|
8
|
+
display: flex;
|
|
9
|
+
flex-direction: column;
|
|
10
|
+
|
|
11
|
+
> .#{bem.$base}.form-label {
|
|
12
|
+
margin-bottom: var(--gap);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
> .toggle-wrapper {
|
|
16
|
+
align-items: center;
|
|
17
|
+
display: flex;
|
|
18
|
+
margin-bottom: calc(var(--gap) / 2);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
|
|
@@ -10,4 +10,5 @@ export { QueryChoices } from "./QueryChoices";
|
|
|
10
10
|
export { LinkInput } from "./LinkInput";
|
|
11
11
|
export { EditorInput } from "./EditorInput";
|
|
12
12
|
export { LatexPreviewInput, convertLatexToHtml } from "./LatexPreviewInput";
|
|
13
|
-
export { FileUpload, fileUploadOptions, getFileType, getFileTypeFromUrl } from "./FileUpload";
|
|
13
|
+
export { FileUpload, fileUploadOptions, getFileType, getFileTypeFromUrl } from "./FileUpload";
|
|
14
|
+
export { ToggleInput } from "./ToggleInput";
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export const DATE_FORMATS = {
|
|
2
2
|
HUMAN_READABLE: 'human_readable',
|
|
3
|
+
HUMAN_READABLE_WITH_TIME: 'human_readable_with_time',
|
|
3
4
|
TIME: 'time',
|
|
4
5
|
DATETIME: 'datetime',
|
|
5
6
|
CHART_DATE: 'chart_date',
|
|
@@ -42,23 +43,6 @@ export const formatTime = seconds => {
|
|
|
42
43
|
if (parts.length === 0) return '0s';
|
|
43
44
|
return parts.join(' ');
|
|
44
45
|
};
|
|
45
|
-
const parseDate = input => {
|
|
46
|
-
if (input instanceof Date) return input;
|
|
47
|
-
if (typeof input === 'number') return new Date(input);
|
|
48
|
-
if (typeof input === 'string') {
|
|
49
|
-
if (isTimeSliceFormat(input)) {
|
|
50
|
-
return createTimeFromSlice(input);
|
|
51
|
-
}
|
|
52
|
-
const parsed = new Date(input);
|
|
53
|
-
if (isValidDate(parsed)) return parsed;
|
|
54
|
-
const timestamp = parseInt(input, 10);
|
|
55
|
-
if (!Number.isNaN(timestamp)) {
|
|
56
|
-
const date = new Date(timestamp * 1000);
|
|
57
|
-
if (isValidDate(date)) return date;
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
return null;
|
|
61
|
-
};
|
|
62
46
|
const formatStrategies = {
|
|
63
47
|
[DATE_FORMATS.CHART_DATE]: date => {
|
|
64
48
|
const monthDay = date.toLocaleDateString('en-US', {
|
|
@@ -75,8 +59,32 @@ const formatStrategies = {
|
|
|
75
59
|
day: 'numeric',
|
|
76
60
|
timeZone: 'UTC'
|
|
77
61
|
}),
|
|
62
|
+
[DATE_FORMATS.HUMAN_READABLE_WITH_TIME]: date => date.toLocaleString('en-US', {
|
|
63
|
+
year: 'numeric',
|
|
64
|
+
month: 'short',
|
|
65
|
+
day: 'numeric',
|
|
66
|
+
hour: '2-digit',
|
|
67
|
+
timeZone: 'UTC'
|
|
68
|
+
}),
|
|
78
69
|
default: date => date.toISOString()
|
|
79
70
|
};
|
|
71
|
+
export const parseDate = input => {
|
|
72
|
+
if (input instanceof Date) return input;
|
|
73
|
+
if (typeof input === 'number') return new Date(input);
|
|
74
|
+
if (typeof input === 'string') {
|
|
75
|
+
if (isTimeSliceFormat(input)) {
|
|
76
|
+
return createTimeFromSlice(input);
|
|
77
|
+
}
|
|
78
|
+
const parsed = new Date(input);
|
|
79
|
+
if (isValidDate(parsed)) return parsed;
|
|
80
|
+
const timestamp = parseInt(input, 10);
|
|
81
|
+
if (!Number.isNaN(timestamp)) {
|
|
82
|
+
const date = new Date(timestamp * 1000);
|
|
83
|
+
if (isValidDate(date)) return date;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return null;
|
|
87
|
+
};
|
|
80
88
|
export const formatDate = (input, format = DATE_FORMATS.HUMAN_READABLE) => {
|
|
81
89
|
try {
|
|
82
90
|
if (typeof input === 'string' && isTimeSliceFormat(input)) {
|
package/dist/es/utils/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export { useWindowSize, useDynamicPosition, useOutsideClick } from "./hooks";
|
|
2
|
-
export { formatTime, formatDate, DATE_FORMATS, snakeCaseToTitleCase } from "./formatting";
|
|
2
|
+
export { formatTime, formatDate, DATE_FORMATS, parseDate, snakeCaseToTitleCase } from "./formatting";
|
|
3
3
|
export { applyCharacterLimit } from "./applyCharacterLimit";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pareto-engineering/design-system",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.3.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "dist/cjs/index.js",
|
|
6
6
|
"module": "dist/es/index.js",
|
|
@@ -45,7 +45,8 @@
|
|
|
45
45
|
"css-loader": "^6.7.3",
|
|
46
46
|
"identity-obj-proxy": "^3.0.0",
|
|
47
47
|
"jest-environment-jsdom": "^29.5.0",
|
|
48
|
-
"sass
|
|
48
|
+
"sass": "^1.85.1",
|
|
49
|
+
"sass-loader": "^16.0.5",
|
|
49
50
|
"storybook": "^7.0.6",
|
|
50
51
|
"style-loader": "^3.3.2"
|
|
51
52
|
},
|
|
@@ -59,9 +60,9 @@
|
|
|
59
60
|
"@lexical/selection": "0.12.2",
|
|
60
61
|
"@lexical/table": "0.12.2",
|
|
61
62
|
"@lexical/utils": "0.12.2",
|
|
62
|
-
"@pareto-engineering/assets": "^5.
|
|
63
|
-
"@pareto-engineering/bem": "^5.
|
|
64
|
-
"@pareto-engineering/styles": "^5.
|
|
63
|
+
"@pareto-engineering/assets": "^5.3.0",
|
|
64
|
+
"@pareto-engineering/bem": "^5.3.0",
|
|
65
|
+
"@pareto-engineering/styles": "^5.3.0",
|
|
65
66
|
"@pareto-engineering/utils": "^5.0.0",
|
|
66
67
|
"better-react-mathjax": "^2.0.3",
|
|
67
68
|
"codemirror": "^6.0.1",
|
|
@@ -87,5 +88,5 @@
|
|
|
87
88
|
"remark-math": "^6.0.0"
|
|
88
89
|
},
|
|
89
90
|
"browserslist": "> 2%",
|
|
90
|
-
"gitHead": "
|
|
91
|
+
"gitHead": "74dc91892e6471a3c42e65ce673c62693ce943f5"
|
|
91
92
|
}
|
|
@@ -16,7 +16,11 @@ import {
|
|
|
16
16
|
|
|
17
17
|
import styleNames from '@pareto-engineering/bem/exports'
|
|
18
18
|
|
|
19
|
-
import {
|
|
19
|
+
import {
|
|
20
|
+
formatTime, formatDate, DATE_FORMATS, parseDate,
|
|
21
|
+
} from 'ui/utils'
|
|
22
|
+
|
|
23
|
+
import { ThroughPutIndicator } from '../../ThroughPutIndicator'
|
|
20
24
|
|
|
21
25
|
import { CustomLegend, CustomTooltipContent, YLabelsDropDown } from '../Common'
|
|
22
26
|
|
|
@@ -26,6 +30,34 @@ const baseClassName = styleNames.base
|
|
|
26
30
|
|
|
27
31
|
const componentClassName = 'area-chart'
|
|
28
32
|
|
|
33
|
+
/**
|
|
34
|
+
* Determines whether to show only date or date with time based on the data range
|
|
35
|
+
*
|
|
36
|
+
* @param {Array} data - The chart data array
|
|
37
|
+
* @param {string} xKey - The key for the x-axis values (dates)
|
|
38
|
+
* @returns {boolean} - True if only date should be shown, false if date and time should be shown
|
|
39
|
+
*/
|
|
40
|
+
const shouldShowOnlyDate = (data, xKey) => {
|
|
41
|
+
if (!data || data.length < 2 || !xKey) return true
|
|
42
|
+
|
|
43
|
+
// Extract dates from the data
|
|
44
|
+
const dates = data.map((item) => parseDate(item[xKey])).filter((date) => date !== null)
|
|
45
|
+
|
|
46
|
+
if (dates.length < 2) return true
|
|
47
|
+
|
|
48
|
+
// Sort dates chronologically
|
|
49
|
+
dates.sort((a, b) => a.getTime() - b.getTime())
|
|
50
|
+
|
|
51
|
+
// Calculate the difference in days between the first and last date
|
|
52
|
+
const firstDate = dates[0]
|
|
53
|
+
const lastDate = dates[dates.length - 1]
|
|
54
|
+
const diffInMs = lastDate.getTime() - firstDate.getTime()
|
|
55
|
+
const diffInDays = diffInMs / (1000 * 60 * 60 * 24)
|
|
56
|
+
|
|
57
|
+
// If the data spans less than 4 days, show only date
|
|
58
|
+
return diffInDays > 4
|
|
59
|
+
}
|
|
60
|
+
|
|
29
61
|
const AreaChart = ({
|
|
30
62
|
id,
|
|
31
63
|
className: userClassName,
|
|
@@ -42,6 +74,8 @@ const AreaChart = ({
|
|
|
42
74
|
isTimeFormat,
|
|
43
75
|
dateFormat,
|
|
44
76
|
capitalizedLegend,
|
|
77
|
+
isWorkerSubmissionChart,
|
|
78
|
+
totalSubmissions,
|
|
45
79
|
}) => {
|
|
46
80
|
const allYLabels = yKeys.map((key) => ({
|
|
47
81
|
label:key,
|
|
@@ -55,9 +89,11 @@ const AreaChart = ({
|
|
|
55
89
|
const min = Math.min(...yValues.flat())
|
|
56
90
|
const max = Math.max(...yValues.flat())
|
|
57
91
|
const margin = (max - min) * 0.1
|
|
58
|
-
return [min - margin, max + margin]
|
|
92
|
+
return [Math.max(min - margin, 0), max + margin]
|
|
59
93
|
}
|
|
60
94
|
|
|
95
|
+
const showOnlyDate = shouldShowOnlyDate(data, xKey)
|
|
96
|
+
|
|
61
97
|
return (
|
|
62
98
|
<div
|
|
63
99
|
id={id}
|
|
@@ -71,13 +107,22 @@ const AreaChart = ({
|
|
|
71
107
|
>
|
|
72
108
|
<div className="chart-header">
|
|
73
109
|
<h3>{title}</h3>
|
|
110
|
+
|
|
74
111
|
<YLabelsDropDown
|
|
75
112
|
allYLabels={allYLabels}
|
|
76
113
|
selectedYLabels={selectedYLabels}
|
|
77
114
|
setSelectedYLabels={setSelectedYLabels}
|
|
78
115
|
/>
|
|
79
116
|
</div>
|
|
117
|
+
|
|
118
|
+
{isWorkerSubmissionChart && (
|
|
119
|
+
<div className="worker-submissions-total-percentage-container">
|
|
120
|
+
<p className="total-submissions-text">{totalSubmissions}</p>
|
|
121
|
+
<ThroughPutIndicator data={data} keyName="reserved" />
|
|
122
|
+
</div>
|
|
123
|
+
)}
|
|
80
124
|
<CustomLegend
|
|
125
|
+
key={id}
|
|
81
126
|
colorsArray={colors}
|
|
82
127
|
yKeysArray={yKeys}
|
|
83
128
|
capitalizedLegend={capitalizedLegend}
|
|
@@ -91,7 +136,12 @@ const AreaChart = ({
|
|
|
91
136
|
axisLine={false}
|
|
92
137
|
tickLine={false}
|
|
93
138
|
tickCount={3}
|
|
94
|
-
tickFormatter={(value) =>
|
|
139
|
+
tickFormatter={(value) => {
|
|
140
|
+
if (showOnlyDate) {
|
|
141
|
+
return formatDate(value, dateFormat)
|
|
142
|
+
}
|
|
143
|
+
return formatDate(value, DATE_FORMATS.HUMAN_READABLE_WITH_TIME)
|
|
144
|
+
}}
|
|
95
145
|
/>
|
|
96
146
|
<YAxis
|
|
97
147
|
domain={yAxisBounds}
|
|
@@ -111,6 +161,9 @@ const AreaChart = ({
|
|
|
111
161
|
if (isTimeFormat) {
|
|
112
162
|
return formatTime(value)
|
|
113
163
|
}
|
|
164
|
+
if (isWorkerSubmissionChart) {
|
|
165
|
+
return Math.round(value)
|
|
166
|
+
}
|
|
114
167
|
return value.toFixed(2)
|
|
115
168
|
}}
|
|
116
169
|
/>
|
|
@@ -227,15 +280,27 @@ AreaChart.propTypes = {
|
|
|
227
280
|
* The type of format for the datetime value
|
|
228
281
|
*/
|
|
229
282
|
dateFormat:PropTypes.oneOf(Object.values(DATE_FORMATS)),
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* Flag on whether the chart is a worker submission chart or not
|
|
286
|
+
*/
|
|
287
|
+
isWorkerSubmissionChart:PropTypes.bool,
|
|
288
|
+
|
|
289
|
+
/**
|
|
290
|
+
* Total submissions
|
|
291
|
+
*/
|
|
292
|
+
totalSubmissions:PropTypes.number,
|
|
230
293
|
}
|
|
231
294
|
|
|
232
295
|
AreaChart.defaultProps = {
|
|
233
|
-
filled
|
|
234
|
-
width
|
|
235
|
-
height
|
|
236
|
-
capitalizedLegend:false,
|
|
237
|
-
isTimeFormat
|
|
238
|
-
dateFormat
|
|
296
|
+
filled :false,
|
|
297
|
+
width :'100%',
|
|
298
|
+
height :300,
|
|
299
|
+
capitalizedLegend :false,
|
|
300
|
+
isTimeFormat :false,
|
|
301
|
+
dateFormat :DATE_FORMATS.HUMAN_READABLE,
|
|
302
|
+
isWorkerSubmissionChart:false,
|
|
303
|
+
|
|
239
304
|
}
|
|
240
305
|
|
|
241
306
|
export default AreaChart
|
|
@@ -26,6 +26,17 @@ $default-text-font-size: calc(var(--s-1) * 1rem);
|
|
|
26
26
|
}
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
+
.worker-submissions-total-percentage-container {
|
|
30
|
+
align-items: center;
|
|
31
|
+
display: flex;
|
|
32
|
+
gap: 1rem;
|
|
33
|
+
justify-content: flex-start;
|
|
34
|
+
|
|
35
|
+
.total-submissions-text {
|
|
36
|
+
font-size: calc($default-text-font-size * 2);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
29
40
|
/* stylelint-disable selector-max-compound-selectors -- nested elements */
|
|
30
41
|
.recharts-wrapper {
|
|
31
42
|
.recharts-surface {
|
|
@@ -46,3 +57,14 @@ $default-text-font-size: calc(var(--s-1) * 1rem);
|
|
|
46
57
|
}
|
|
47
58
|
}
|
|
48
59
|
}
|
|
60
|
+
|
|
61
|
+
.worker-submissions-total-percentage-container {
|
|
62
|
+
align-items: center;
|
|
63
|
+
display: flex;
|
|
64
|
+
gap: 1rem;
|
|
65
|
+
justify-content: flex-start;
|
|
66
|
+
|
|
67
|
+
.total-submissions-text {
|
|
68
|
+
font-size: calc($default-text-font-size * 2);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
@@ -12,6 +12,11 @@ const baseClassName = styleNames.base
|
|
|
12
12
|
|
|
13
13
|
const componentClassName = 'custom-legend'
|
|
14
14
|
|
|
15
|
+
const toCurrency = (value) => {
|
|
16
|
+
const formatter = new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' })
|
|
17
|
+
return formatter.format(value)
|
|
18
|
+
}
|
|
19
|
+
|
|
15
20
|
const CustomLegend = ({
|
|
16
21
|
id,
|
|
17
22
|
className: userClassName,
|
|
@@ -21,6 +26,8 @@ const CustomLegend = ({
|
|
|
21
26
|
getLegendItemTitle,
|
|
22
27
|
getLegendItemSubtitle,
|
|
23
28
|
capitalizedLegend,
|
|
29
|
+
subtitleToCurrency,
|
|
30
|
+
isPayOutChart,
|
|
24
31
|
}) => (
|
|
25
32
|
<div
|
|
26
33
|
id={id}
|
|
@@ -46,11 +53,21 @@ const CustomLegend = ({
|
|
|
46
53
|
? snakeCaseToTitleCase(getLegendItemTitle(key))
|
|
47
54
|
: getLegendItemTitle(key)
|
|
48
55
|
}
|
|
56
|
+
|
|
49
57
|
</span>
|
|
50
58
|
</div>
|
|
51
|
-
<
|
|
52
|
-
|
|
53
|
-
|
|
59
|
+
<div className="sub-title-percentage-container">
|
|
60
|
+
<span className="sub-title">
|
|
61
|
+
{subtitleToCurrency
|
|
62
|
+
? toCurrency(getLegendItemSubtitle(key))
|
|
63
|
+
: getLegendItemSubtitle(key)}
|
|
64
|
+
</span>
|
|
65
|
+
{ Object.prototype.hasOwnProperty.call(key, 'percentage') && !isPayOutChart && (
|
|
66
|
+
<span className="percentage-title">
|
|
67
|
+
{`${key?.percentage}%`}
|
|
68
|
+
</span>
|
|
69
|
+
)}
|
|
70
|
+
</div>
|
|
54
71
|
</div>
|
|
55
72
|
))}
|
|
56
73
|
</div>
|
|
@@ -96,6 +113,11 @@ CustomLegend.propTypes = {
|
|
|
96
113
|
* Flag on whether to capitalize legend keys
|
|
97
114
|
*/
|
|
98
115
|
capitalizedLegend:PropTypes.bool,
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Flag on whether to convert the subtitle to currency
|
|
119
|
+
*/
|
|
120
|
+
subtitleToCurrency:PropTypes.bool,
|
|
99
121
|
}
|
|
100
122
|
|
|
101
123
|
CustomLegend.defaultProps = {
|
|
@@ -104,6 +126,7 @@ CustomLegend.defaultProps = {
|
|
|
104
126
|
/* eslint-disable no-unused-vars */
|
|
105
127
|
getLegendItemSubtitle:() => {},
|
|
106
128
|
capitalizedLegend :false,
|
|
129
|
+
subtitleToCurrency :false,
|
|
107
130
|
}
|
|
108
131
|
|
|
109
132
|
export default CustomLegend
|
|
@@ -24,7 +24,6 @@ $default-box-shadow: 0 4px 16px 0 var(--soft-shadow);
|
|
|
24
24
|
min-width: fit-content;
|
|
25
25
|
|
|
26
26
|
.item {
|
|
27
|
-
box-shadow: $default-box-shadow;
|
|
28
27
|
padding-top: $default-padding;
|
|
29
28
|
}
|
|
30
29
|
}
|
|
@@ -55,12 +54,21 @@ $default-box-shadow: 0 4px 16px 0 var(--soft-shadow);
|
|
|
55
54
|
}
|
|
56
55
|
}
|
|
57
56
|
|
|
57
|
+
|
|
58
|
+
|
|
58
59
|
.sub-title {
|
|
59
60
|
color: var(--heading);
|
|
60
61
|
display: flex;
|
|
61
62
|
font-size: calc($default-text-font-size * 1.2);
|
|
62
63
|
font-weight: 500;
|
|
63
|
-
justify-content: flex-
|
|
64
|
+
justify-content: flex-start;
|
|
65
|
+
margin-left: 1rem;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
.percentage-title {
|
|
69
|
+
color: var(--paragraph);
|
|
70
|
+
font-size: calc($default-text-font-size * .75);
|
|
71
|
+
justify-content: flex-start;
|
|
64
72
|
}
|
|
65
73
|
}
|
|
66
74
|
}
|