@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.
Files changed (62) hide show
  1. package/dist/cjs/a/Charts/AreaChart/AreaChart.js +60 -5
  2. package/dist/cjs/a/Charts/AreaChart/styles.scss +22 -0
  3. package/dist/cjs/a/Charts/Common/CustomLegend/CustomLegend.js +19 -5
  4. package/dist/cjs/a/Charts/Common/CustomTooltipContent/CustomTooltipContent.js +133 -68
  5. package/dist/cjs/a/Charts/PieChart/PieChart.js +20 -7
  6. package/dist/cjs/a/ThroughPutIndicator/ThroughPutIndicator.js +78 -0
  7. package/dist/cjs/a/ThroughPutIndicator/index.js +13 -0
  8. package/dist/cjs/a/ThroughPutIndicator/styles.scss +35 -0
  9. package/dist/cjs/a/ToggleSwitch/ToggleSwitch.js +2 -1
  10. package/dist/cjs/a/ToggleSwitch/styles.scss +9 -2
  11. package/dist/cjs/a/Tooltip/Tooltip.js +19 -2
  12. package/dist/cjs/a/Tooltip/styles.scss +32 -4
  13. package/dist/cjs/a/index.js +8 -1
  14. package/dist/cjs/f/FormInput/FormInput.js +7 -1
  15. package/dist/cjs/f/fields/ToggleInput/ToggleInput.js +126 -0
  16. package/dist/cjs/f/fields/ToggleInput/index.js +13 -0
  17. package/dist/cjs/f/fields/ToggleInput/styles.scss +22 -0
  18. package/dist/cjs/f/fields/index.js +8 -1
  19. package/dist/cjs/utils/formatting.js +27 -18
  20. package/dist/cjs/utils/index.js +6 -0
  21. package/dist/es/a/Charts/AreaChart/AreaChart.js +61 -6
  22. package/dist/es/a/Charts/AreaChart/styles.scss +22 -0
  23. package/dist/es/a/Charts/Common/CustomLegend/CustomLegend.js +19 -5
  24. package/dist/es/a/Charts/Common/CustomTooltipContent/CustomTooltipContent.js +122 -66
  25. package/dist/es/a/Charts/PieChart/PieChart.js +20 -7
  26. package/dist/es/a/ThroughPutIndicator/ThroughPutIndicator.js +66 -0
  27. package/dist/es/a/ThroughPutIndicator/index.js +2 -0
  28. package/dist/es/a/ThroughPutIndicator/styles.scss +35 -0
  29. package/dist/es/a/ToggleSwitch/ToggleSwitch.js +2 -1
  30. package/dist/es/a/ToggleSwitch/styles.scss +9 -2
  31. package/dist/es/a/Tooltip/Tooltip.js +31 -12
  32. package/dist/es/a/Tooltip/styles.scss +32 -4
  33. package/dist/es/a/index.js +2 -1
  34. package/dist/es/f/FormInput/FormInput.js +8 -2
  35. package/dist/es/f/fields/ToggleInput/ToggleInput.js +116 -0
  36. package/dist/es/f/fields/ToggleInput/index.js +2 -0
  37. package/dist/es/f/fields/ToggleInput/styles.scss +22 -0
  38. package/dist/es/f/fields/index.js +2 -1
  39. package/dist/es/utils/formatting.js +25 -17
  40. package/dist/es/utils/index.js +1 -1
  41. package/package.json +5 -5
  42. package/src/ui/a/Charts/AreaChart/AreaChart.jsx +73 -9
  43. package/src/ui/a/Charts/AreaChart/styles.scss +22 -0
  44. package/src/ui/a/Charts/Common/CustomLegend/CustomLegend.jsx +20 -5
  45. package/src/ui/a/Charts/Common/CustomTooltipContent/CustomTooltipContent.jsx +126 -79
  46. package/src/ui/a/Charts/PieChart/PieChart.jsx +38 -17
  47. package/src/ui/a/ThroughPutIndicator/ThroughPutIndicator.jsx +90 -0
  48. package/src/ui/a/ThroughPutIndicator/index.js +2 -0
  49. package/src/ui/a/ThroughPutIndicator/styles.scss +35 -0
  50. package/src/ui/a/ToggleSwitch/ToggleSwitch.jsx +1 -1
  51. package/src/ui/a/ToggleSwitch/styles.scss +9 -2
  52. package/src/ui/a/Tooltip/Tooltip.jsx +55 -26
  53. package/src/ui/a/Tooltip/styles.scss +32 -4
  54. package/src/ui/a/index.js +1 -0
  55. package/src/ui/f/FormInput/FormInput.jsx +11 -0
  56. package/src/ui/f/fields/ToggleInput/ToggleInput.jsx +140 -0
  57. package/src/ui/f/fields/ToggleInput/index.js +2 -0
  58. package/src/ui/f/fields/ToggleInput/styles.scss +22 -0
  59. package/src/ui/f/fields/index.js +1 -0
  60. package/src/ui/utils/formatting.js +38 -29
  61. package/src/ui/utils/index.js +1 -1
  62. package/tests/__snapshots__/Storyshots.test.js.snap +7 -1
@@ -7,7 +7,7 @@ $default-size: var(--size, 1.2em);
7
7
  $default-slider-color: var(--slider-color, var(--background-far));
8
8
  $default-slider-border-color: var(--slider-border-color, var(--ui-lines));
9
9
  $default-background-color: var(--slider-background-color, var(--interactive));
10
-
10
+ $default-background-disabled: var(--disabled, var(--background-far));
11
11
  .#{bem.$base}.toggle-switch {
12
12
  background: transparent;
13
13
  border: none;
@@ -21,7 +21,6 @@ $default-background-color: var(--slider-background-color, var(--interactive));
21
21
  }
22
22
 
23
23
  >label {
24
- background: $default-background-color;
25
24
  border-radius: $default-border-radius;
26
25
  cursor: pointer;
27
26
  display: block;
@@ -29,6 +28,14 @@ $default-background-color: var(--slider-background-color, var(--interactive));
29
28
  position: relative;
30
29
  width: calc($default-size * 2);
31
30
 
31
+ &.checked {
32
+ background: $default-background-color;
33
+ }
34
+
35
+ &:not(.checked) {
36
+ background: $default-background-disabled;
37
+ }
38
+
32
39
  &::after {
33
40
  background: $default-slider-color;
34
41
  border: 1px solid $default-slider-border-color;
@@ -4,7 +4,8 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.default = void 0;
7
- var React = _interopRequireWildcard(require("react"));
7
+ var _react = _interopRequireWildcard(require("react"));
8
+ var React = _react;
8
9
  var _propTypes = _interopRequireDefault(require("prop-types"));
9
10
  var _exports = _interopRequireDefault(require("@pareto-engineering/bem/exports"));
10
11
  require("./styles.scss");
@@ -27,12 +28,24 @@ const Tooltip = _ref => {
27
28
  className: userClassName,
28
29
  style,
29
30
  position,
31
+ isFloating,
30
32
  color,
31
33
  description,
32
34
  content,
33
35
  children
34
36
  // ...otherProps
35
37
  } = _ref;
38
+ (0, _react.useEffect)(() => {
39
+ const handleMouseMove = e => {
40
+ document.documentElement.style.setProperty('--mouse-x', `${e.clientX}px`);
41
+ document.documentElement.style.setProperty('--mouse-y', `${e.clientY}px`);
42
+ };
43
+ if (!isFloating) {
44
+ return () => window.removeEventListener('mousemove', handleMouseMove);
45
+ }
46
+ window.addEventListener('mousemove', handleMouseMove);
47
+ return () => window.removeEventListener('mousemove', handleMouseMove);
48
+ }, [isFloating]);
36
49
  return /*#__PURE__*/React.createElement("div", {
37
50
  id: id,
38
51
  className: [baseClassName, componentClassName, userClassName, `x-${color}`].filter(e => e).join(' '),
@@ -41,7 +54,7 @@ const Tooltip = _ref => {
41
54
  className: "tooltip-trigger-wrapper",
42
55
  "aria-describedby": description
43
56
  }, children), /*#__PURE__*/React.createElement("div", {
44
- className: `tooltip-content ${position}`,
57
+ className: ['tooltip-content', position, isFloating ? 'floating' : ''].filter(e => e).join(' '),
45
58
  role: "tooltip",
46
59
  id: description
47
60
  }, content));
@@ -75,6 +88,10 @@ Tooltip.propTypes = {
75
88
  * The position of the tooltip with respect to the trigger element
76
89
  */
77
90
  position: _propTypes.default.oneOf(['top', 'bottom', 'left', 'right']),
91
+ /**
92
+ * Whether or not the tooltip should be floating
93
+ */
94
+ isFloating: _propTypes.default.bool,
78
95
  /**
79
96
  * The base color of the tooltip
80
97
  */
@@ -24,25 +24,53 @@ $default-width: var(--tooltip-width, 20rem);
24
24
  visibility: hidden;
25
25
  z-index: 10;
26
26
 
27
- &.top {
27
+ &.floating.top {
28
+ left: var(--mouse-x);
29
+ position: fixed;
30
+ top: calc(var(--mouse-y) - $default-block-padding);
31
+ transform: translate(-50%, -100%);
32
+ }
33
+
34
+ &.floating.right {
35
+ left: calc(var(--mouse-x) + $default-inline-padding);
36
+ position: fixed;
37
+ top: var(--mouse-y);
38
+ transform: translateY(-50%);
39
+ }
40
+
41
+ &.floating.bottom {
42
+ left: var(--mouse-x);
43
+ position: fixed;
44
+ top: calc(var(--mouse-y) + $default-block-padding);
45
+ transform: translateX(-50%);
46
+ }
47
+
48
+ &.floating.left {
49
+ left: calc(var(--mouse-x) - $default-inline-padding);
50
+ position: fixed;
51
+ top: var(--mouse-y);
52
+ transform: translate(-100%, -50%);
53
+ }
54
+
55
+ &:not(.floating).top {
28
56
  --horizontal: -50%;
29
57
  bottom: calc(100% + $default-block-padding);
30
58
  left: 50%;
31
59
  }
32
60
 
33
- &.right {
61
+ &:not(.floating).right {
34
62
  --vertical: 50%;
35
63
  bottom: 50%;
36
64
  left: calc(100% + $default-inline-padding);
37
65
  }
38
66
 
39
- &.bottom {
67
+ &:not(.floating).bottom {
40
68
  --horizontal: -50%;
41
69
  left: 50%;
42
70
  top: calc(100% + $default-block-padding);
43
71
  }
44
72
 
45
- &.left {
73
+ &:not(.floating).left {
46
74
  --vertical: 50%;
47
75
  bottom: 50%;
48
76
  right: calc(100% + $default-inline-padding);
@@ -177,6 +177,12 @@ Object.defineProperty(exports, "TextSteps", {
177
177
  return _TextSteps.TextSteps;
178
178
  }
179
179
  });
180
+ Object.defineProperty(exports, "ThroughPutIndicator", {
181
+ enumerable: true,
182
+ get: function () {
183
+ return _ThroughPutIndicator.ThroughPutIndicator;
184
+ }
185
+ });
180
186
  Object.defineProperty(exports, "Timestamp", {
181
187
  enumerable: true,
182
188
  get: function () {
@@ -249,4 +255,5 @@ var _ToggleSwitch = require("./ToggleSwitch");
249
255
  var _XMLEditor = require("./XMLEditor");
250
256
  var _DatePicker = require("./DatePicker");
251
257
  var _Tooltip = require("./Tooltip");
252
- var _Charts = require("./Charts");
258
+ var _Charts = require("./Charts");
259
+ var _ThroughPutIndicator = require("./ThroughPutIndicator");
@@ -68,6 +68,12 @@ const FormInput = _ref => {
68
68
  disabled: disabled
69
69
  }, otherProps));
70
70
  }
71
+ if (type === 'toggle') {
72
+ return /*#__PURE__*/React.createElement(_fields.ToggleInput, _extends({
73
+ className: newClassName,
74
+ disabled: disabled
75
+ }, otherProps));
76
+ }
71
77
  if (type === 'query-choices') {
72
78
  return /*#__PURE__*/React.createElement(_fields.QueryChoices, _extends({
73
79
  className: newClassName,
@@ -130,7 +136,7 @@ FormInput.propTypes = {
130
136
  /**
131
137
  * The HTML class names for this element
132
138
  */
133
- type: _propTypes.default.oneOf(['text', 'email', 'password', 'number', 'date', 'datetime', 'month', 'tel', 'hidden', 'select', 'choices', 'textarea', 'query-combobox', 'query-select', 'url', 'rating', 'checkbox',
139
+ type: _propTypes.default.oneOf(['text', 'email', 'password', 'number', 'date', 'datetime', 'month', 'tel', 'hidden', 'select', 'choices', 'textarea', 'query-combobox', 'query-select', 'url', 'rating', 'checkbox', 'toggle',
134
140
  // to be removed
135
141
  'extendedTypeInput']),
136
142
  /**
@@ -0,0 +1,126 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var React = _interopRequireWildcard(require("react"));
8
+ var _propTypes = _interopRequireDefault(require("prop-types"));
9
+ var _formik = require("formik");
10
+ var _exports = _interopRequireDefault(require("@pareto-engineering/bem/exports"));
11
+ var _a = require("../../../a");
12
+ var _common = require("../../common");
13
+ require("./styles.scss");
14
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
15
+ function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
16
+ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
17
+ /* @pareto-engineering/generator-front 1.1.1-alpha.3 */
18
+
19
+ // Local Definitions
20
+ const baseClassName = _exports.default.base;
21
+ const componentClassName = 'toggle-input';
22
+
23
+ /**
24
+ * Toggle input field component that wraps ToggleSwitch for use with Formik
25
+ */
26
+ const ToggleInput = _ref => {
27
+ let {
28
+ id,
29
+ className: userClassName,
30
+ style,
31
+ name,
32
+ label,
33
+ color,
34
+ labelColor,
35
+ validate,
36
+ description,
37
+ disabled,
38
+ optional,
39
+ size
40
+ // ...otherProps
41
+ } = _ref;
42
+ const [field,, helpers] = (0, _formik.useField)({
43
+ name,
44
+ validate,
45
+ type: 'checkbox'
46
+ });
47
+ const handleChange = () => {
48
+ helpers.setValue(!field.value);
49
+ };
50
+ return /*#__PURE__*/React.createElement("div", {
51
+ id: id,
52
+ className: [baseClassName, componentClassName, userClassName, `y-${color}`].filter(e => e).join(' '),
53
+ style: style
54
+ }, /*#__PURE__*/React.createElement(_common.FormLabel, {
55
+ name: name,
56
+ color: labelColor,
57
+ optional: optional
58
+ }, label), /*#__PURE__*/React.createElement("div", {
59
+ className: "toggle-wrapper"
60
+ }, /*#__PURE__*/React.createElement(_a.ToggleSwitch, {
61
+ checked: Boolean(field.value),
62
+ handleOnChange: handleChange,
63
+ inputId: name,
64
+ size: size,
65
+ disabled: disabled
66
+ })), /*#__PURE__*/React.createElement(_common.FormDescription, {
67
+ className: "s-1",
68
+ description: description,
69
+ name: name
70
+ }));
71
+ };
72
+ ToggleInput.propTypes = {
73
+ /**
74
+ * The HTML id for this element
75
+ */
76
+ id: _propTypes.default.string,
77
+ /**
78
+ * The HTML class names for this element
79
+ */
80
+ className: _propTypes.default.string,
81
+ /**
82
+ * The React-written, css properties for this element.
83
+ */
84
+ style: _propTypes.default.objectOf(_propTypes.default.string),
85
+ /**
86
+ * The input name (html - and Formik state)
87
+ */
88
+ name: _propTypes.default.string.isRequired,
89
+ /**
90
+ * The input label
91
+ */
92
+ label: _propTypes.default.string.isRequired,
93
+ /**
94
+ * The input label color
95
+ */
96
+ labelColor: _propTypes.default.string,
97
+ /**
98
+ * The input field validator function
99
+ */
100
+ validate: _propTypes.default.func,
101
+ /**
102
+ * Input description
103
+ */
104
+ description: _propTypes.default.string,
105
+ /**
106
+ * Whether the toggle input should be disabled
107
+ */
108
+ disabled: _propTypes.default.bool,
109
+ /**
110
+ * The text input color
111
+ */
112
+ color: _propTypes.default.string,
113
+ /**
114
+ * Whether the input is optional or not
115
+ */
116
+ optional: _propTypes.default.bool,
117
+ /**
118
+ * The size of the toggle switch
119
+ */
120
+ size: _propTypes.default.string
121
+ };
122
+ ToggleInput.defaultProps = {
123
+ color: 'paragraph',
124
+ disabled: false
125
+ };
126
+ var _default = exports.default = ToggleInput;
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ Object.defineProperty(exports, "ToggleInput", {
7
+ enumerable: true,
8
+ get: function () {
9
+ return _ToggleInput.default;
10
+ }
11
+ });
12
+ var _ToggleInput = _interopRequireDefault(require("./ToggleInput"));
13
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
@@ -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
+
@@ -81,6 +81,12 @@ Object.defineProperty(exports, "TextareaInput", {
81
81
  return _TextareaInput.TextareaInput;
82
82
  }
83
83
  });
84
+ Object.defineProperty(exports, "ToggleInput", {
85
+ enumerable: true,
86
+ get: function () {
87
+ return _ToggleInput.ToggleInput;
88
+ }
89
+ });
84
90
  Object.defineProperty(exports, "convertLatexToHtml", {
85
91
  enumerable: true,
86
92
  get: function () {
@@ -117,4 +123,5 @@ var _QueryChoices = require("./QueryChoices");
117
123
  var _LinkInput = require("./LinkInput");
118
124
  var _EditorInput = require("./EditorInput");
119
125
  var _LatexPreviewInput = require("./LatexPreviewInput");
120
- var _FileUpload = require("./FileUpload");
126
+ var _FileUpload = require("./FileUpload");
127
+ var _ToggleInput = require("./ToggleInput");
@@ -3,9 +3,10 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.snakeCaseToTitleCase = exports.formatTime = exports.formatDate = exports.DATE_FORMATS = void 0;
6
+ exports.snakeCaseToTitleCase = exports.parseDate = exports.formatTime = exports.formatDate = exports.DATE_FORMATS = void 0;
7
7
  const DATE_FORMATS = exports.DATE_FORMATS = {
8
8
  HUMAN_READABLE: 'human_readable',
9
+ HUMAN_READABLE_WITH_TIME: 'human_readable_with_time',
9
10
  TIME: 'time',
10
11
  DATETIME: 'datetime',
11
12
  CHART_DATE: 'chart_date',
@@ -49,23 +50,6 @@ const formatTime = seconds => {
49
50
  return parts.join(' ');
50
51
  };
51
52
  exports.formatTime = formatTime;
52
- const parseDate = input => {
53
- if (input instanceof Date) return input;
54
- if (typeof input === 'number') return new Date(input);
55
- if (typeof input === 'string') {
56
- if (isTimeSliceFormat(input)) {
57
- return createTimeFromSlice(input);
58
- }
59
- const parsed = new Date(input);
60
- if (isValidDate(parsed)) return parsed;
61
- const timestamp = parseInt(input, 10);
62
- if (!Number.isNaN(timestamp)) {
63
- const date = new Date(timestamp * 1000);
64
- if (isValidDate(date)) return date;
65
- }
66
- }
67
- return null;
68
- };
69
53
  const formatStrategies = {
70
54
  [DATE_FORMATS.CHART_DATE]: date => {
71
55
  const monthDay = date.toLocaleDateString('en-US', {
@@ -82,8 +66,33 @@ const formatStrategies = {
82
66
  day: 'numeric',
83
67
  timeZone: 'UTC'
84
68
  }),
69
+ [DATE_FORMATS.HUMAN_READABLE_WITH_TIME]: date => date.toLocaleString('en-US', {
70
+ year: 'numeric',
71
+ month: 'short',
72
+ day: 'numeric',
73
+ hour: '2-digit',
74
+ timeZone: 'UTC'
75
+ }),
85
76
  default: date => date.toISOString()
86
77
  };
78
+ const parseDate = input => {
79
+ if (input instanceof Date) return input;
80
+ if (typeof input === 'number') return new Date(input);
81
+ if (typeof input === 'string') {
82
+ if (isTimeSliceFormat(input)) {
83
+ return createTimeFromSlice(input);
84
+ }
85
+ const parsed = new Date(input);
86
+ if (isValidDate(parsed)) return parsed;
87
+ const timestamp = parseInt(input, 10);
88
+ if (!Number.isNaN(timestamp)) {
89
+ const date = new Date(timestamp * 1000);
90
+ if (isValidDate(date)) return date;
91
+ }
92
+ }
93
+ return null;
94
+ };
95
+ exports.parseDate = parseDate;
87
96
  const formatDate = function (input) {
88
97
  let format = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : DATE_FORMATS.HUMAN_READABLE;
89
98
  try {
@@ -27,6 +27,12 @@ Object.defineProperty(exports, "formatTime", {
27
27
  return _formatting.formatTime;
28
28
  }
29
29
  });
30
+ Object.defineProperty(exports, "parseDate", {
31
+ enumerable: true,
32
+ get: function () {
33
+ return _formatting.parseDate;
34
+ }
35
+ });
30
36
  Object.defineProperty(exports, "snakeCaseToTitleCase", {
31
37
  enumerable: true,
32
38
  get: function () {
@@ -3,11 +3,39 @@ import { useState } from 'react';
3
3
  import PropTypes from 'prop-types';
4
4
  import { AreaChart as RechartsAreaChart, Area, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer } from 'recharts';
5
5
  import styleNames from '@pareto-engineering/bem/exports';
6
- import { formatTime, formatDate, DATE_FORMATS } from "../../../utils";
6
+ import { formatTime, formatDate, DATE_FORMATS, parseDate } from "../../../utils";
7
+ import { ThroughPutIndicator } from "../../ThroughPutIndicator";
7
8
  import { CustomLegend, CustomTooltipContent, YLabelsDropDown } from "../Common";
8
9
  import "./styles.scss";
9
10
  const baseClassName = styleNames.base;
10
11
  const componentClassName = 'area-chart';
12
+
13
+ /**
14
+ * Determines whether to show only date or date with time based on the data range
15
+ *
16
+ * @param {Array} data - The chart data array
17
+ * @param {string} xKey - The key for the x-axis values (dates)
18
+ * @returns {boolean} - True if only date should be shown, false if date and time should be shown
19
+ */
20
+ const shouldShowOnlyDate = (data, xKey) => {
21
+ if (!data || data.length < 2 || !xKey) return true;
22
+
23
+ // Extract dates from the data
24
+ const dates = data.map(item => parseDate(item[xKey])).filter(date => date !== null);
25
+ if (dates.length < 2) return true;
26
+
27
+ // Sort dates chronologically
28
+ dates.sort((a, b) => a.getTime() - b.getTime());
29
+
30
+ // Calculate the difference in days between the first and last date
31
+ const firstDate = dates[0];
32
+ const lastDate = dates[dates.length - 1];
33
+ const diffInMs = lastDate.getTime() - firstDate.getTime();
34
+ const diffInDays = diffInMs / (1000 * 60 * 60 * 24);
35
+
36
+ // If the data spans less than 4 days, show only date
37
+ return diffInDays > 4;
38
+ };
11
39
  const AreaChart = ({
12
40
  id,
13
41
  className: userClassName,
@@ -23,7 +51,9 @@ const AreaChart = ({
23
51
  width,
24
52
  isTimeFormat,
25
53
  dateFormat,
26
- capitalizedLegend
54
+ capitalizedLegend,
55
+ isWorkerSubmissionChart,
56
+ totalSubmissions
27
57
  }) => {
28
58
  const allYLabels = yKeys.map(key => ({
29
59
  label: key,
@@ -35,8 +65,9 @@ const AreaChart = ({
35
65
  const min = Math.min(...yValues.flat());
36
66
  const max = Math.max(...yValues.flat());
37
67
  const margin = (max - min) * 0.1;
38
- return [min - margin, max + margin];
68
+ return [Math.max(min - margin, 0), max + margin];
39
69
  };
70
+ const showOnlyDate = shouldShowOnlyDate(data, xKey);
40
71
  return /*#__PURE__*/React.createElement("div", {
41
72
  id: id,
42
73
  className: [baseClassName, componentClassName, userClassName].filter(e => e).join(' ')
@@ -46,6 +77,13 @@ const AreaChart = ({
46
77
  allYLabels: allYLabels,
47
78
  selectedYLabels: selectedYLabels,
48
79
  setSelectedYLabels: setSelectedYLabels
80
+ })), isWorkerSubmissionChart && /*#__PURE__*/React.createElement("div", {
81
+ className: "worker-submissions-total-percentage-container"
82
+ }, /*#__PURE__*/React.createElement("p", {
83
+ className: "total-submissions-text"
84
+ }, totalSubmissions), /*#__PURE__*/React.createElement(ThroughPutIndicator, {
85
+ data: data,
86
+ keyName: "reserved"
49
87
  })), /*#__PURE__*/React.createElement(CustomLegend, {
50
88
  key: id,
51
89
  colorsArray: colors,
@@ -68,7 +106,12 @@ const AreaChart = ({
68
106
  axisLine: false,
69
107
  tickLine: false,
70
108
  tickCount: 3,
71
- tickFormatter: value => formatDate(value, dateFormat)
109
+ tickFormatter: value => {
110
+ if (showOnlyDate) {
111
+ return formatDate(value, dateFormat);
112
+ }
113
+ return formatDate(value, DATE_FORMATS.HUMAN_READABLE_WITH_TIME);
114
+ }
72
115
  }), /*#__PURE__*/React.createElement(YAxis, {
73
116
  domain: yAxisBounds,
74
117
  scale: "linear",
@@ -92,6 +135,9 @@ const AreaChart = ({
92
135
  if (isTimeFormat) {
93
136
  return formatTime(value);
94
137
  }
138
+ if (isWorkerSubmissionChart) {
139
+ return Math.round(value);
140
+ }
95
141
  return value.toFixed(2);
96
142
  }
97
143
  }), /*#__PURE__*/React.createElement(Tooltip, {
@@ -178,7 +224,15 @@ AreaChart.propTypes = {
178
224
  /**
179
225
  * The type of format for the datetime value
180
226
  */
181
- dateFormat: PropTypes.oneOf(Object.values(DATE_FORMATS))
227
+ dateFormat: PropTypes.oneOf(Object.values(DATE_FORMATS)),
228
+ /**
229
+ * Flag on whether the chart is a worker submission chart or not
230
+ */
231
+ isWorkerSubmissionChart: PropTypes.bool,
232
+ /**
233
+ * Total submissions
234
+ */
235
+ totalSubmissions: PropTypes.number
182
236
  };
183
237
  AreaChart.defaultProps = {
184
238
  filled: false,
@@ -186,6 +240,7 @@ AreaChart.defaultProps = {
186
240
  height: 300,
187
241
  capitalizedLegend: false,
188
242
  isTimeFormat: false,
189
- dateFormat: DATE_FORMATS.HUMAN_READABLE
243
+ dateFormat: DATE_FORMATS.HUMAN_READABLE,
244
+ isWorkerSubmissionChart: false
190
245
  };
191
246
  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
+ }
@@ -5,6 +5,13 @@ import { snakeCaseToTitleCase } from "../../../../utils";
5
5
  import "./styles.scss";
6
6
  const baseClassName = styleNames.base;
7
7
  const componentClassName = 'custom-legend';
8
+ const toCurrency = value => {
9
+ const formatter = new Intl.NumberFormat('en-US', {
10
+ style: 'currency',
11
+ currency: 'USD'
12
+ });
13
+ return formatter.format(value);
14
+ };
8
15
  const CustomLegend = ({
9
16
  id,
10
17
  className: userClassName,
@@ -13,7 +20,9 @@ const CustomLegend = ({
13
20
  orientation,
14
21
  getLegendItemTitle,
15
22
  getLegendItemSubtitle,
16
- capitalizedLegend
23
+ capitalizedLegend,
24
+ subtitleToCurrency,
25
+ isPayOutChart
17
26
  }) => /*#__PURE__*/React.createElement("div", {
18
27
  id: id,
19
28
  className: [baseClassName, componentClassName, userClassName, orientation].filter(e => e).join(' ')
@@ -33,9 +42,9 @@ const CustomLegend = ({
33
42
  className: "sub-title-percentage-container"
34
43
  }, /*#__PURE__*/React.createElement("span", {
35
44
  className: "sub-title"
36
- }, getLegendItemSubtitle(key)), key.percentage && /*#__PURE__*/React.createElement("span", {
45
+ }, subtitleToCurrency ? toCurrency(getLegendItemSubtitle(key)) : getLegendItemSubtitle(key)), Object.prototype.hasOwnProperty.call(key, 'percentage') && !isPayOutChart && /*#__PURE__*/React.createElement("span", {
37
46
  className: "percentage-title"
38
- }, `${key.percentage}%`)))));
47
+ }, `${key?.percentage}%`)))));
39
48
  CustomLegend.propTypes = {
40
49
  /**
41
50
  * The id of the dropdown component.
@@ -68,13 +77,18 @@ CustomLegend.propTypes = {
68
77
  /**
69
78
  * Flag on whether to capitalize legend keys
70
79
  */
71
- capitalizedLegend: PropTypes.bool
80
+ capitalizedLegend: PropTypes.bool,
81
+ /**
82
+ * Flag on whether to convert the subtitle to currency
83
+ */
84
+ subtitleToCurrency: PropTypes.bool
72
85
  };
73
86
  CustomLegend.defaultProps = {
74
87
  orientation: 'horizontal',
75
88
  getLegendItemTitle: key => key,
76
89
  /* eslint-disable no-unused-vars */
77
90
  getLegendItemSubtitle: () => {},
78
- capitalizedLegend: false
91
+ capitalizedLegend: false,
92
+ subtitleToCurrency: false
79
93
  };
80
94
  export default CustomLegend;