@pareto-engineering/design-system 5.2.1 → 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 +60 -5
- package/dist/cjs/a/Charts/AreaChart/styles.scss +22 -0
- package/dist/cjs/a/Charts/Common/CustomLegend/CustomLegend.js +19 -5
- package/dist/cjs/a/Charts/Common/CustomTooltipContent/CustomTooltipContent.js +133 -68
- package/dist/cjs/a/Charts/PieChart/PieChart.js +20 -7
- 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/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 +61 -6
- package/dist/es/a/Charts/AreaChart/styles.scss +22 -0
- package/dist/es/a/Charts/Common/CustomLegend/CustomLegend.js +19 -5
- package/dist/es/a/Charts/Common/CustomTooltipContent/CustomTooltipContent.js +122 -66
- package/dist/es/a/Charts/PieChart/PieChart.js +20 -7
- 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/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 +5 -5
- package/src/ui/a/Charts/AreaChart/AreaChart.jsx +73 -9
- package/src/ui/a/Charts/AreaChart/styles.scss +22 -0
- package/src/ui/a/Charts/Common/CustomLegend/CustomLegend.jsx +20 -5
- package/src/ui/a/Charts/Common/CustomTooltipContent/CustomTooltipContent.jsx +126 -79
- package/src/ui/a/Charts/PieChart/PieChart.jsx +38 -17
- 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/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 +7 -1
|
@@ -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",
|
|
@@ -60,9 +60,9 @@
|
|
|
60
60
|
"@lexical/selection": "0.12.2",
|
|
61
61
|
"@lexical/table": "0.12.2",
|
|
62
62
|
"@lexical/utils": "0.12.2",
|
|
63
|
-
"@pareto-engineering/assets": "^5.
|
|
64
|
-
"@pareto-engineering/bem": "^5.
|
|
65
|
-
"@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",
|
|
66
66
|
"@pareto-engineering/utils": "^5.0.0",
|
|
67
67
|
"better-react-mathjax": "^2.0.3",
|
|
68
68
|
"codemirror": "^6.0.1",
|
|
@@ -88,5 +88,5 @@
|
|
|
88
88
|
"remark-math": "^6.0.0"
|
|
89
89
|
},
|
|
90
90
|
"browserslist": "> 2%",
|
|
91
|
-
"gitHead": "
|
|
91
|
+
"gitHead": "74dc91892e6471a3c42e65ce673c62693ce943f5"
|
|
92
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,12 +107,20 @@ 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
|
|
81
125
|
key={id}
|
|
82
126
|
colorsArray={colors}
|
|
@@ -92,7 +136,12 @@ const AreaChart = ({
|
|
|
92
136
|
axisLine={false}
|
|
93
137
|
tickLine={false}
|
|
94
138
|
tickCount={3}
|
|
95
|
-
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
|
+
}}
|
|
96
145
|
/>
|
|
97
146
|
<YAxis
|
|
98
147
|
domain={yAxisBounds}
|
|
@@ -112,6 +161,9 @@ const AreaChart = ({
|
|
|
112
161
|
if (isTimeFormat) {
|
|
113
162
|
return formatTime(value)
|
|
114
163
|
}
|
|
164
|
+
if (isWorkerSubmissionChart) {
|
|
165
|
+
return Math.round(value)
|
|
166
|
+
}
|
|
115
167
|
return value.toFixed(2)
|
|
116
168
|
}}
|
|
117
169
|
/>
|
|
@@ -228,15 +280,27 @@ AreaChart.propTypes = {
|
|
|
228
280
|
* The type of format for the datetime value
|
|
229
281
|
*/
|
|
230
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,
|
|
231
293
|
}
|
|
232
294
|
|
|
233
295
|
AreaChart.defaultProps = {
|
|
234
|
-
filled
|
|
235
|
-
width
|
|
236
|
-
height
|
|
237
|
-
capitalizedLegend:false,
|
|
238
|
-
isTimeFormat
|
|
239
|
-
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
|
+
|
|
240
304
|
}
|
|
241
305
|
|
|
242
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}
|
|
@@ -51,12 +58,14 @@ const CustomLegend = ({
|
|
|
51
58
|
</div>
|
|
52
59
|
<div className="sub-title-percentage-container">
|
|
53
60
|
<span className="sub-title">
|
|
54
|
-
{
|
|
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}%`}
|
|
55
68
|
</span>
|
|
56
|
-
{key.percentage && (
|
|
57
|
-
<span className="percentage-title">
|
|
58
|
-
{`${key.percentage}%`}
|
|
59
|
-
</span>
|
|
60
69
|
)}
|
|
61
70
|
</div>
|
|
62
71
|
</div>
|
|
@@ -104,6 +113,11 @@ CustomLegend.propTypes = {
|
|
|
104
113
|
* Flag on whether to capitalize legend keys
|
|
105
114
|
*/
|
|
106
115
|
capitalizedLegend:PropTypes.bool,
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Flag on whether to convert the subtitle to currency
|
|
119
|
+
*/
|
|
120
|
+
subtitleToCurrency:PropTypes.bool,
|
|
107
121
|
}
|
|
108
122
|
|
|
109
123
|
CustomLegend.defaultProps = {
|
|
@@ -112,6 +126,7 @@ CustomLegend.defaultProps = {
|
|
|
112
126
|
/* eslint-disable no-unused-vars */
|
|
113
127
|
getLegendItemSubtitle:() => {},
|
|
114
128
|
capitalizedLegend :false,
|
|
129
|
+
subtitleToCurrency :false,
|
|
115
130
|
}
|
|
116
131
|
|
|
117
132
|
export default CustomLegend
|