@deviceinsight/ng-ui-components 7.22.0 → 7.23.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/README.md +104 -9
- package/dist/index.cjs +122 -139
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +122 -139
- package/dist/index.js.map +1 -1
- package/dist/types/__mocks__/i18n.d.ts.map +1 -1
- package/dist/types/components/chart/Chart.d.ts +11 -3
- package/dist/types/components/chart/Chart.d.ts.map +1 -1
- package/dist/types/components/chart/Chart.stories.d.ts +7 -7
- package/dist/types/components/chart/Chart.stories.d.ts.map +1 -1
- package/dist/types/components/colorpicker/ColorTextInput.d.ts.map +1 -1
- package/dist/types/components/colorpicker/GradientColorPicker.stories.d.ts.map +1 -1
- package/dist/types/components/colorpicker/GridColorPicker.stories.d.ts.map +1 -1
- package/dist/types/components/contentHeader/ContentHeader.d.ts.map +1 -1
- package/dist/types/components/contentHeader/ContentHeader.stories.d.ts.map +1 -1
- package/dist/types/components/infobox/InfoBox.d.ts.map +1 -1
- package/dist/types/components/infobox/InfoBox.stories.d.ts.map +1 -1
- package/dist/types/components/input/DateInput.d.ts.map +1 -1
- package/dist/types/components/input/DateInput.stories.d.ts +2 -1
- package/dist/types/components/input/DateInput.stories.d.ts.map +1 -1
- package/dist/types/components/input/DateTimeInput.d.ts.map +1 -1
- package/dist/types/components/input/DateTimeInput.stories.d.ts +12 -11
- package/dist/types/components/input/DateTimeInput.stories.d.ts.map +1 -1
- package/dist/types/components/input/SelectWithSearch.d.ts.map +1 -1
- package/dist/types/components/input/SelectWithSearch.stories.d.ts.map +1 -1
- package/dist/types/components/input/SelectWithSearchAsync.d.ts +5 -1
- package/dist/types/components/input/SelectWithSearchAsync.d.ts.map +1 -1
- package/dist/types/components/input/SelectWithSearchAsync.stories.d.ts.map +1 -1
- package/dist/types/components/input/UrnInput.d.ts.map +1 -1
- package/dist/types/components/input/UrnInput.stories.d.ts.map +1 -1
- package/dist/types/components/input/ValidatedTextInput.d.ts.map +1 -1
- package/dist/types/components/input/ValidatedTextInput.stories.d.ts.map +1 -1
- package/dist/types/components/link/RouteLink.stories.d.ts.map +1 -1
- package/dist/types/components/multiMenu/MultiMenu.stories.d.ts.map +1 -1
- package/dist/types/components/multiMenu/components/MultiMenuContext.d.ts.map +1 -1
- package/dist/types/components/multiMenu/components/MultiMenuItem.d.ts.map +1 -1
- package/dist/types/components/pagination/Pagination.d.ts.map +1 -1
- package/dist/types/components/pagination/Pagination.stories.d.ts.map +1 -1
- package/dist/types/components/periodpicker/PeriodPicker.stories.d.ts.map +1 -1
- package/dist/types/components/periodpicker/components/MonthPicker.d.ts.map +1 -1
- package/dist/types/components/periodpicker/periods.d.ts.map +1 -1
- package/dist/types/components/prompt/Prompt.stories.d.ts.map +1 -1
- package/dist/types/components/reactable/Reactable.d.ts.map +1 -1
- package/dist/types/components/reactable/Reactable.stories.d.ts.map +1 -1
- package/dist/types/components/reactable/helpers/ReactableTableFilterRow.d.ts.map +1 -1
- package/dist/types/components/reactable/helpers/ReactableTableHeader.d.ts +1 -1
- package/dist/types/components/reactable/helpers/ReactableTableHeader.d.ts.map +1 -1
- package/dist/types/components/reactable/helpers/ReactableTableRow.d.ts.map +1 -1
- package/dist/types/components/reactable/helpers/ReactableTextFilter.d.ts.map +1 -1
- package/dist/types/components/reactableWithClientSidePagination/ReactableWithClientSidePagination.d.ts +7 -1
- package/dist/types/components/reactableWithClientSidePagination/ReactableWithClientSidePagination.d.ts.map +1 -1
- package/dist/types/components/reactableWithClientSidePagination/ReactableWithClientSidePagination.stories.d.ts.map +1 -1
- package/dist/types/components/slider/RcSliderWithTooltip.d.ts.map +1 -1
- package/dist/types/components/slider/Slider.d.ts.map +1 -1
- package/dist/types/components/slider/Slider.stories.d.ts.map +1 -1
- package/dist/types/components/svg/SvgImage.d.ts.map +1 -1
- package/dist/types/components/svg/SvgImage.stories.d.ts.map +1 -1
- package/dist/types/components/svg/utils/getMutableNodeList.d.ts.map +1 -1
- package/dist/types/components/svg/utils/getSvgElement.d.ts +1 -1
- package/dist/types/components/svg/utils/getSvgElement.d.ts.map +1 -1
- package/dist/types/components/svg/utils/transformPositionModifications.d.ts +1 -1
- package/dist/types/components/svg/utils/transformPositionModifications.d.ts.map +1 -1
- package/dist/types/components/svg/utils/validateSvg.d.ts +1 -1
- package/dist/types/components/svg/utils/validateSvg.d.ts.map +1 -1
- package/dist/types/components/tabs/RouteTabs.stories.d.ts.map +1 -1
- package/dist/types/components/treeview/TreeView.d.ts +9 -4
- package/dist/types/components/treeview/TreeView.d.ts.map +1 -1
- package/dist/types/components/treeview/TreeView.stories.d.ts.map +1 -1
- package/dist/types/components/treeview/components/Node.d.ts +2 -5
- package/dist/types/components/treeview/components/Node.d.ts.map +1 -1
- package/dist/types/components/treeview/components/NodeInfo.d.ts.map +1 -1
- package/dist/types/components/upload/FileUpload.d.ts.map +1 -1
- package/dist/types/components/upload/FileUpload.stories.d.ts.map +1 -1
- package/dist/types/components/upload/ImageUpload.d.ts +2 -2
- package/dist/types/components/upload/ImageUpload.d.ts.map +1 -1
- package/dist/types/components/upload/ImageUpload.stories.d.ts +11 -11
- package/dist/types/components/upload/ImageUpload.stories.d.ts.map +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/modules/messageBox/MessageBox.stories.d.ts.map +1 -1
- package/dist/types/modules/messageBox/messageBox.d.ts.map +1 -1
- package/dist/types/modules/utils/uuidGen.d.ts.map +1 -1
- package/package.json +12 -16
package/README.md
CHANGED
|
@@ -1,18 +1,109 @@
|
|
|
1
|
+
# General
|
|
2
|
+
|
|
3
|
+
This project contains the higher-level React components shared by
|
|
4
|
+
[NG-UI](https://gitlab.device-insight.com/ng-ui/ng-ui) and custom projects.
|
|
5
|
+
It is published as `@deviceinsight/ng-ui-components` and builds on
|
|
6
|
+
`@deviceinsight/ng-ui-basic-components` and `@deviceinsight/ng-ui-api-client`.
|
|
7
|
+
|
|
8
|
+
The package is ESM-first (`dist/index.js`) with a CommonJS build (`dist/index.cjs`)
|
|
9
|
+
and type declarations (`dist/types/index.d.ts`). The bundled stylesheet is exported
|
|
10
|
+
separately and has to be imported by the consuming project:
|
|
11
|
+
|
|
12
|
+
```ts
|
|
13
|
+
import '@deviceinsight/ng-ui-components/style.css';
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
`react`, `react-dom`, `i18next`, `react-i18next` and `react-router-dom` are peer
|
|
17
|
+
dependencies and have to be provided by the consuming project.
|
|
18
|
+
|
|
19
|
+
## Contents
|
|
20
|
+
|
|
21
|
+
`src/index.ts` is the public API. It currently exports:
|
|
22
|
+
|
|
23
|
+
- **Inputs** — `DateInput`, `DateTimeInput`, `UrnInput`, `ValidatedTextInput`,
|
|
24
|
+
`SelectWithSearch`, `SelectWithSearchAsync`, `PeriodPicker`, `Slider`
|
|
25
|
+
- **Data display** — `Reactable`, `ReactableWithClientSidePagination`, `Pagination`,
|
|
26
|
+
`TreeView` (plus `getTreeNodePathById`), `Chart`, `InfoBox`, `ContentHeader`
|
|
27
|
+
- **Color pickers** — `ColorPicker` / `GridColorPicker`, `GradientColorPicker`
|
|
28
|
+
- **Navigation** — `RouteLink`, `RouteTabs`, `MultiMenu`, `MultiMenuItem`
|
|
29
|
+
- **Upload** — `FileUpload`, `ImageUpload`
|
|
30
|
+
- **SVG** — `SvgImage` and the helpers `getSvgElement`, `getMutableNodeList`,
|
|
31
|
+
`validateSvg`
|
|
32
|
+
- **Prompt** — `withPrompt`
|
|
33
|
+
- **Message box** — `messageBoxSuccess`, `messageBoxInfo`, `messageBoxWarn`,
|
|
34
|
+
`messageBoxError`, `messageBoxDismissSingle`, `messageBoxDismissGroup`,
|
|
35
|
+
`messageBoxDismissAll`, `setGlobalMessageBoxOptions`,
|
|
36
|
+
`setGlobalErrorMessageBoxOptions`, `MessageBoxContainer`
|
|
37
|
+
- **Utilities** — `uuidV4`, `nanoid10`, `initializeTranslation`
|
|
38
|
+
- the accompanying types (`ReactableProps`, `ReactableColumnDef`, `Period`,
|
|
39
|
+
`SvgImageProps`, `PaginationSettings`, …)
|
|
40
|
+
|
|
41
|
+
Translations live in `src/i18n` and are set up by calling `initializeTranslation`.
|
|
42
|
+
`src/modules` holds non-component code (message box, utils), `src/styles` the
|
|
43
|
+
stylesheet, `src/utils` shared helpers.
|
|
44
|
+
|
|
45
|
+
# Development
|
|
46
|
+
|
|
47
|
+
Node is pinned via `.nvmrc` (see also the `engines` field in `package.json`).
|
|
48
|
+
|
|
49
|
+
```shell
|
|
50
|
+
npm install
|
|
51
|
+
npm run storybook # dev server on http://localhost:6006
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Available scripts:
|
|
55
|
+
|
|
56
|
+
| Script | Description |
|
|
57
|
+
| ------------------------- | -------------------------------------------------------------------------- |
|
|
58
|
+
| `npm run build` | Cleans `dist`, bundles with Vite and emits types via `tsconfig.types.json` |
|
|
59
|
+
| `npm test` | Runs the Vitest suite (watch mode by default, `--run` for a single pass) |
|
|
60
|
+
| `npm run watch` | Rebuilds and runs `yalc push` on every successful compile |
|
|
61
|
+
| `npm run clean` | Removes `dist` |
|
|
62
|
+
| `npm run storybook` | Starts Storybook on port 6006 |
|
|
63
|
+
| `npm run build-storybook` | Builds the static Storybook |
|
|
64
|
+
| `npm run typecheck` | `tsc --noEmit` |
|
|
65
|
+
| `npm run lint` | Lints with oxlint and checks formatting with Prettier |
|
|
66
|
+
| `npm run prettier` | Formats the sources and `.mdx` files |
|
|
67
|
+
| `npm run scan` | Vulnerability scan via `audit-ci` using `scan-config.json5` |
|
|
68
|
+
|
|
69
|
+
Tests use Vitest with `happy-dom` and Testing Library; the setup lives in
|
|
70
|
+
`vitest.setup.tsx` and the config in `vitest.config.mts`. Components are additionally
|
|
71
|
+
exercised via Storybook stories (`*.stories.tsx`).
|
|
72
|
+
|
|
73
|
+
Commits are checked by a husky `pre-commit` hook that runs `lint-staged`
|
|
74
|
+
(prettier on the staged files).
|
|
75
|
+
|
|
76
|
+
`CHANGELOG.md` is maintained per version. Renovate dependency updates append their
|
|
77
|
+
entry automatically via the `postUpgradeTasks` hook in `renovate.json`, which calls
|
|
78
|
+
`./update-changelog.sh <depName> <currentVersion> <newVersion>`.
|
|
79
|
+
|
|
1
80
|
# Linking for local development
|
|
2
81
|
|
|
3
|
-
We recommend using `yalc` tool for linking
|
|
82
|
+
We recommend using the `yalc` tool for linking `@deviceinsight/ng-ui-components`. It's because `yalc` generates exactly the same package as
|
|
4
83
|
it would be published to the npm registry, especially it removes files that should be ignored and their existence cause
|
|
5
|
-
problems when we use `
|
|
84
|
+
problems when we use `npm link`.
|
|
6
85
|
|
|
7
86
|
Here's how to do the linking:
|
|
8
87
|
|
|
9
88
|
```shell
|
|
10
|
-
|
|
89
|
+
npm run build
|
|
90
|
+
npx yalc publish
|
|
11
91
|
|
|
12
92
|
# in the project where you want to link this library to:
|
|
13
|
-
yalc link "@deviceinsight/ng-ui-components"
|
|
93
|
+
npx yalc link "@deviceinsight/ng-ui-components"
|
|
14
94
|
```
|
|
15
95
|
|
|
96
|
+
# CI
|
|
97
|
+
|
|
98
|
+
`.gitlab-ci.yml` installs the dependencies and then runs `test`, `scan`, `lint` and
|
|
99
|
+
`typecheck` on every branch except `main`. On `develop` the `pages` job publishes the
|
|
100
|
+
static Storybook to GitLab Pages. The `publish` job runs for `develop` and for tags:
|
|
101
|
+
`-SNAPSHOT` versions are published to the internal Nexus registry under the `next`
|
|
102
|
+
tag, releases go to the public npm registry. A release older than the currently
|
|
103
|
+
published `latest` is published under a `hotfix-<major>.<minor>` tag so that `latest`
|
|
104
|
+
is not moved backwards. `publish_alpha` is a manual job that publishes an alpha
|
|
105
|
+
prerelease of the `VERSION` variable to the internal registry under `next`.
|
|
106
|
+
|
|
16
107
|
# Releasing the library using git flow
|
|
17
108
|
|
|
18
109
|
## Prerequisites
|
|
@@ -24,7 +115,8 @@ The git flow tools need to be installed. This depends on your operating system.
|
|
|
24
115
|
They can be also installed from the git repo: https://github.com/petervanderdoes/gitflow-avh
|
|
25
116
|
|
|
26
117
|
After git flow is installed, the repo needs to be initialized. Run `git flow init` and answer every
|
|
27
|
-
question with the default (press Enter/Return).
|
|
118
|
+
question with the default (press Enter/Return). The script verifies that the branches
|
|
119
|
+
are named `main` and `develop`.
|
|
28
120
|
|
|
29
121
|
## Building a release
|
|
30
122
|
|
|
@@ -34,9 +126,8 @@ To build a release of this library, execute `./release.sh`, which consists of th
|
|
|
34
126
|
|
|
35
127
|
Vulnerabilities can occur at any time.
|
|
36
128
|
To be sure, the pipeline for the branches and the tags created
|
|
37
|
-
in the release process will not fail,
|
|
38
|
-
release
|
|
39
|
-
To do this, run:
|
|
129
|
+
in the release process will not fail, the script runs the checks locally before building the
|
|
130
|
+
release:
|
|
40
131
|
|
|
41
132
|
```
|
|
42
133
|
npm install
|
|
@@ -44,12 +135,16 @@ npm run scan
|
|
|
44
135
|
npm run test
|
|
45
136
|
```
|
|
46
137
|
|
|
138
|
+
If `package-lock.json` changed during the install, the script commits it.
|
|
139
|
+
|
|
47
140
|
### Building the release
|
|
48
141
|
|
|
49
142
|
1. Switch to develop branch and make sure both main and develop are current:
|
|
50
143
|
|
|
51
144
|
`git checkout develop && git pull && git fetch origin main:main`
|
|
52
145
|
|
|
146
|
+
The script also aborts if the workarea is dirty or if `develop` has unpushed commits.
|
|
147
|
+
|
|
53
148
|
2. Get the upcoming release from `package.json` and start the release:
|
|
54
149
|
|
|
55
150
|
`git flow release start $RELEASE_VERSION`, e.g. `git flow release start 1.2.0`.
|
|
@@ -86,7 +181,7 @@ so that the version is e.g. `1.2.0-SNAPSHOT`.
|
|
|
86
181
|
|
|
87
182
|
5.2. Run `npm install`.
|
|
88
183
|
|
|
89
|
-
5.
|
|
184
|
+
5.3. Commit `package.json` and `package-lock.json`. Commit message should be `Starting $NEW_SNAPSHOT_VERSION`, e.g. `Starting 1.2.0`.
|
|
90
185
|
|
|
91
186
|
6. Push the branches and the tag:
|
|
92
187
|
|
package/dist/index.cjs
CHANGED
|
@@ -411,9 +411,11 @@ var ValidatedTextInput = class extends react.Component {
|
|
|
411
411
|
//#region src/components/colorpicker/ColorTextInput.tsx
|
|
412
412
|
function ColorTextInput({ value, pattern, onChange, placeholder, style }) {
|
|
413
413
|
const [text, setText] = (0, react.useState)(value);
|
|
414
|
-
(0, react.
|
|
414
|
+
const [lastValue, setLastValue] = (0, react.useState)(value);
|
|
415
|
+
if (value !== lastValue) {
|
|
416
|
+
setLastValue(value);
|
|
415
417
|
setText(value);
|
|
416
|
-
}
|
|
418
|
+
}
|
|
417
419
|
function handleChange(value, valid) {
|
|
418
420
|
setText(value);
|
|
419
421
|
if (valid) onChange(value);
|
|
@@ -544,9 +546,7 @@ function inputToTzDate(value, pattern, timezone) {
|
|
|
544
546
|
var DateInput = (0, react.forwardRef)(({ value, clearable, inline, readOnly, wrapperClassName, onChange, locale, timezone, ...otherProps }, ref) => {
|
|
545
547
|
const [pattern, setPattern] = (0, react.useState)(dayjs.default.localeData().longDateFormat("L"));
|
|
546
548
|
const { t } = useTranslation();
|
|
547
|
-
const [valid, setValid] = (0, react.useState)(false);
|
|
548
549
|
const [popupOpen, setPopupOpen] = (0, react.useState)(false);
|
|
549
|
-
const [inputText, setInputText] = (0, react.useState)("");
|
|
550
550
|
const debouncedSetPopupActive = (0, react.useMemo)(() => (0, lodash.debounce)(setPopupOpen, 30), []);
|
|
551
551
|
(0, react.useEffect)(() => {
|
|
552
552
|
const language = locale ?? i18next.default.language;
|
|
@@ -564,17 +564,22 @@ var DateInput = (0, react.forwardRef)(({ value, clearable, inline, readOnly, wra
|
|
|
564
564
|
t,
|
|
565
565
|
timezone
|
|
566
566
|
]);
|
|
567
|
-
(0, react.
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
567
|
+
const [valid, setValid] = (0, react.useState)(() => isInputValid(value, pattern));
|
|
568
|
+
const [inputText, setInputText] = (0, react.useState)(() => value == null ? "" : formattedDate(value));
|
|
569
|
+
const [lastInput, setLastInput] = (0, react.useState)({
|
|
570
|
+
value,
|
|
571
|
+
pattern,
|
|
572
|
+
timezone
|
|
573
|
+
});
|
|
574
|
+
if (!Object.is(value, lastInput.value) || pattern !== lastInput.pattern || timezone !== lastInput.timezone) {
|
|
575
|
+
setLastInput({
|
|
576
|
+
value,
|
|
577
|
+
pattern,
|
|
578
|
+
timezone
|
|
579
|
+
});
|
|
580
|
+
setInputText(value == null ? "" : formattedDate(value));
|
|
572
581
|
setValid(isInputValid(value, pattern));
|
|
573
|
-
}
|
|
574
|
-
(0, react.useEffect)(() => {
|
|
575
|
-
dayjs.default.locale(locale ?? i18next.default.language);
|
|
576
|
-
setPattern(dayjs.default.localeData().longDateFormat("L"));
|
|
577
|
-
}, [locale]);
|
|
582
|
+
}
|
|
578
583
|
const handleInputTextChange = (text) => {
|
|
579
584
|
setInputText(text);
|
|
580
585
|
if (text) {
|
|
@@ -1114,7 +1119,6 @@ var Node = class Node extends react.Component {
|
|
|
1114
1119
|
super(..._args);
|
|
1115
1120
|
this.state = {
|
|
1116
1121
|
expanded: false,
|
|
1117
|
-
selectionState: this.getSelectionState(),
|
|
1118
1122
|
isLoading: false
|
|
1119
1123
|
};
|
|
1120
1124
|
this.toggleExpand = () => {
|
|
@@ -1140,28 +1144,23 @@ var Node = class Node extends react.Component {
|
|
|
1140
1144
|
* @param {Props} prevProps
|
|
1141
1145
|
* @param {State} prevState
|
|
1142
1146
|
*/
|
|
1143
|
-
shouldComponentUpdate(
|
|
1144
|
-
const { selectedNodes:
|
|
1145
|
-
const { expanded:
|
|
1147
|
+
shouldComponentUpdate(nextProps, nextState) {
|
|
1148
|
+
const { selectedNodes: nextSelectedNodes, treeSize: nextTreeSize } = nextProps;
|
|
1149
|
+
const { expanded: nextExpanded, isLoading: nextIsLoading } = nextState;
|
|
1146
1150
|
const { selectedNodes, node, treeSize } = this.props;
|
|
1147
|
-
const { expanded,
|
|
1148
|
-
|
|
1149
|
-
if (
|
|
1150
|
-
if (
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
componentDidMount() {
|
|
1154
|
-
this.setState({ selectionState: this.getSelectionState() });
|
|
1155
|
-
}
|
|
1156
|
-
componentDidUpdate() {
|
|
1157
|
-
this.setState({ selectionState: this.getSelectionState() });
|
|
1151
|
+
const { expanded, isLoading } = this.state;
|
|
1152
|
+
const selectionStateChanged = this.getSelectionState(this.props) !== this.getSelectionState(nextProps);
|
|
1153
|
+
if (isLoading !== nextIsLoading) return true;
|
|
1154
|
+
if (treeSize !== nextTreeSize) return true;
|
|
1155
|
+
if (this.isLeaf()) return selectedNodes.includes(node.id) && !nextSelectedNodes.includes(node.id) || !selectedNodes.includes(node.id) && nextSelectedNodes.includes(node.id) || selectionStateChanged;
|
|
1156
|
+
else return selectedNodes.length !== nextSelectedNodes.length || expanded !== nextExpanded || selectionStateChanged;
|
|
1158
1157
|
}
|
|
1159
1158
|
isLeaf() {
|
|
1160
1159
|
const { node } = this.props;
|
|
1161
1160
|
return node.children === void 0;
|
|
1162
1161
|
}
|
|
1163
|
-
getSelectionState() {
|
|
1164
|
-
const { node, selectedNodes } =
|
|
1162
|
+
getSelectionState(props = this.props) {
|
|
1163
|
+
const { node, selectedNodes } = props;
|
|
1165
1164
|
if (this.isLeaf()) return selectedNodes.includes(node.id) ? SelectionState.ALL : SelectionState.NONE;
|
|
1166
1165
|
else {
|
|
1167
1166
|
const leafIds = getAllLeafIds(node);
|
|
@@ -1173,7 +1172,8 @@ var Node = class Node extends react.Component {
|
|
|
1173
1172
|
}
|
|
1174
1173
|
render() {
|
|
1175
1174
|
const { node, isLastChild, ...commonNodeProps } = this.props;
|
|
1176
|
-
const { expanded,
|
|
1175
|
+
const { expanded, isLoading } = this.state;
|
|
1176
|
+
const selectionState = this.getSelectionState();
|
|
1177
1177
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1178
1178
|
className: "node",
|
|
1179
1179
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(NodeInfo, {
|
|
@@ -1204,19 +1204,15 @@ var Node = class Node extends react.Component {
|
|
|
1204
1204
|
var TreeView = class extends react.Component {
|
|
1205
1205
|
constructor(..._args) {
|
|
1206
1206
|
super(..._args);
|
|
1207
|
+
this.convert = convertToTree(this.props.dataSetConfig);
|
|
1208
|
+
this.initialTree = this.initTree(this.props.treeData);
|
|
1207
1209
|
this.state = {
|
|
1208
1210
|
treeData: this.props.treeData,
|
|
1209
|
-
tree:
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
path: "/",
|
|
1214
|
-
originalNode: {}
|
|
1215
|
-
},
|
|
1216
|
-
treeSize: 0,
|
|
1217
|
-
selectedNodes: this.props.selectedNodes || []
|
|
1211
|
+
tree: this.initialTree,
|
|
1212
|
+
treeSize: getTreeSize(this.initialTree),
|
|
1213
|
+
selectedNodes: this.props.selectedNodes || [],
|
|
1214
|
+
lastSelectedNodes: this.props.selectedNodes || []
|
|
1218
1215
|
};
|
|
1219
|
-
this.convert = convertToTree(this.props.dataSetConfig);
|
|
1220
1216
|
this.selectNodes = (nodes) => {
|
|
1221
1217
|
const { onSelect } = this.props;
|
|
1222
1218
|
const { selectedNodes } = this.state;
|
|
@@ -1264,19 +1260,15 @@ var TreeView = class extends react.Component {
|
|
|
1264
1260
|
});
|
|
1265
1261
|
};
|
|
1266
1262
|
}
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
componentDidUpdate(prevProps) {
|
|
1277
|
-
const { selectedNodes: prevNodes } = prevProps;
|
|
1278
|
-
const { selectedNodes } = this.props;
|
|
1279
|
-
if (selectedNodes && prevNodes && prevNodes.length !== selectedNodes.length) this.setState({ selectedNodes });
|
|
1263
|
+
static {
|
|
1264
|
+
this.getDerivedStateFromProps = (props, state) => {
|
|
1265
|
+
const { selectedNodes } = props;
|
|
1266
|
+
if (selectedNodes && selectedNodes.length !== state.lastSelectedNodes.length) return {
|
|
1267
|
+
selectedNodes,
|
|
1268
|
+
lastSelectedNodes: selectedNodes
|
|
1269
|
+
};
|
|
1270
|
+
return null;
|
|
1271
|
+
};
|
|
1280
1272
|
}
|
|
1281
1273
|
initTree(treeData) {
|
|
1282
1274
|
return {
|
|
@@ -1353,9 +1345,11 @@ function Pagination({ onChangePage, page, totalPages, onChangeSize, size }) {
|
|
|
1353
1345
|
(0, react.useEffect)(() => {
|
|
1354
1346
|
changePageDebouncedRef.current = (0, lodash.debounce)(onChangePage, 500);
|
|
1355
1347
|
}, [onChangePage]);
|
|
1356
|
-
(0, react.
|
|
1348
|
+
const [lastPage, setLastPage] = (0, react.useState)(page);
|
|
1349
|
+
if (page !== lastPage) {
|
|
1350
|
+
setLastPage(page);
|
|
1357
1351
|
setPageRaw(`${page + 1}`);
|
|
1358
|
-
}
|
|
1352
|
+
}
|
|
1359
1353
|
function goToFirstPage() {
|
|
1360
1354
|
onChangePage(0);
|
|
1361
1355
|
}
|
|
@@ -1575,8 +1569,10 @@ var SelectWithSearch = class extends react.Component {
|
|
|
1575
1569
|
value: this.state.inputValue,
|
|
1576
1570
|
label: this.state.inputValue
|
|
1577
1571
|
};
|
|
1578
|
-
this.setState((prevState) => ({
|
|
1579
|
-
|
|
1572
|
+
this.setState((prevState) => ({
|
|
1573
|
+
options: [newItem, ...prevState.options],
|
|
1574
|
+
inputValue: null
|
|
1575
|
+
}));
|
|
1580
1576
|
onChange(newItem);
|
|
1581
1577
|
});
|
|
1582
1578
|
}
|
|
@@ -2100,16 +2096,27 @@ var ReactableWithClientSidePagination = class extends react.Component {
|
|
|
2100
2096
|
this.state = {
|
|
2101
2097
|
paginationSettings: paginationSettings || DEFAULT_PAGINATION_SETTINGS,
|
|
2102
2098
|
filterSettings: {},
|
|
2103
|
-
filteredItems: null
|
|
2099
|
+
filteredItems: null,
|
|
2100
|
+
lastSettings: paginationSettings
|
|
2104
2101
|
};
|
|
2105
2102
|
}
|
|
2106
2103
|
componentDidUpdate(prevProps) {
|
|
2107
2104
|
const { items } = this.props;
|
|
2108
2105
|
const { items: prevItems } = prevProps;
|
|
2109
|
-
const settings = this.props.paginationSettings || this.props.initialPaginationSettings;
|
|
2110
|
-
const prevSettings = prevProps.paginationSettings || prevProps.initialPaginationSettings;
|
|
2111
2106
|
if (items && prevItems && items.length !== prevItems.length) this.calculatePageNumber(items, this.state.paginationSettings);
|
|
2112
|
-
|
|
2107
|
+
}
|
|
2108
|
+
static {
|
|
2109
|
+
this.getDerivedStateFromProps = (props, state) => {
|
|
2110
|
+
const settings = props.paginationSettings || props.initialPaginationSettings;
|
|
2111
|
+
if (settings && !(0, lodash.isEqual)(settings, state.lastSettings)) return {
|
|
2112
|
+
lastSettings: settings,
|
|
2113
|
+
paginationSettings: {
|
|
2114
|
+
...settings,
|
|
2115
|
+
page: 0
|
|
2116
|
+
}
|
|
2117
|
+
};
|
|
2118
|
+
return null;
|
|
2119
|
+
};
|
|
2113
2120
|
}
|
|
2114
2121
|
render() {
|
|
2115
2122
|
const { uniqueItemKey, isLoading, columnDefs, rowDef, tableName, clickable, selectable, selectedItems, onChangeSize } = this.props;
|
|
@@ -2292,20 +2299,17 @@ var ImageUpload = class extends react.Component {
|
|
|
2292
2299
|
constructor(..._args) {
|
|
2293
2300
|
super(..._args);
|
|
2294
2301
|
this.state = {
|
|
2295
|
-
|
|
2302
|
+
dragOverUrl: void 0,
|
|
2296
2303
|
file: null
|
|
2297
2304
|
};
|
|
2298
2305
|
this.handleDragOver = () => {
|
|
2299
|
-
this.setState({
|
|
2306
|
+
this.setState({ dragOverUrl: this.props.imageUrl });
|
|
2300
2307
|
};
|
|
2301
2308
|
}
|
|
2302
|
-
componentDidUpdate(prevProps) {
|
|
2303
|
-
if (prevProps.imageUrl !== this.props.imageUrl) this.setState({ dragOverPreview: false });
|
|
2304
|
-
}
|
|
2305
2309
|
render() {
|
|
2306
2310
|
const { accept, imageUrl, imageSize, onSelectFile, onRemoveFile, onDownloadFile, ...otherProps } = this.props;
|
|
2307
|
-
const {
|
|
2308
|
-
if (imageUrl && !
|
|
2311
|
+
const { dragOverUrl, file } = this.state;
|
|
2312
|
+
if (imageUrl && !(dragOverUrl !== void 0 && dragOverUrl === imageUrl) && file) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PreviewImage, {
|
|
2309
2313
|
url: imageUrl,
|
|
2310
2314
|
imageSize,
|
|
2311
2315
|
onRemoveFile: () => onRemoveFile?.(file),
|
|
@@ -2315,7 +2319,10 @@ var ImageUpload = class extends react.Component {
|
|
|
2315
2319
|
else return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(FileUpload, {
|
|
2316
2320
|
...otherProps,
|
|
2317
2321
|
onRemoveFile: (file) => {
|
|
2318
|
-
this.setState({
|
|
2322
|
+
this.setState({
|
|
2323
|
+
file: null,
|
|
2324
|
+
dragOverUrl: void 0
|
|
2325
|
+
});
|
|
2319
2326
|
onRemoveFile?.(file);
|
|
2320
2327
|
},
|
|
2321
2328
|
onSelectFile: (file) => {
|
|
@@ -2394,9 +2401,17 @@ var formatTime = (timezone, date) => {
|
|
|
2394
2401
|
var DateTimeInput = (0, react.forwardRef)(({ timestamp, timezone, warning, readOnly = false, onChange, ...otherProps }, ref) => {
|
|
2395
2402
|
const [time, setTime] = (0, react.useState)(formatTime(timezone, timestamp));
|
|
2396
2403
|
const timeValue = time == null ? formatTime(timezone, timestamp) : time;
|
|
2397
|
-
(0, react.
|
|
2404
|
+
const [lastInput, setLastInput] = (0, react.useState)({
|
|
2405
|
+
timestamp,
|
|
2406
|
+
timezone
|
|
2407
|
+
});
|
|
2408
|
+
if (timestamp !== lastInput.timestamp || timezone !== lastInput.timezone) {
|
|
2409
|
+
setLastInput({
|
|
2410
|
+
timestamp,
|
|
2411
|
+
timezone
|
|
2412
|
+
});
|
|
2398
2413
|
setTime(formatTime(timezone, timestamp));
|
|
2399
|
-
}
|
|
2414
|
+
}
|
|
2400
2415
|
function handleChangeDate(date, fromTextField) {
|
|
2401
2416
|
const currentDate = dayjs.default.tz(timestamp, timezone);
|
|
2402
2417
|
onChange(dayjs.default.tz(date, timezone).set("hour", currentDate.hour()).set("minute", currentDate.minute()).set("second", currentDate.second()).set("millisecond", currentDate.millisecond()).valueOf(), fromTextField);
|
|
@@ -2515,7 +2530,13 @@ var SelectWithSearchAsync = class extends react.Component {
|
|
|
2515
2530
|
const { currentItem } = this.state;
|
|
2516
2531
|
if (value && (!currentItem || currentItem.value !== value)) {
|
|
2517
2532
|
if (!this.reloadItemFromCache()) searchById(value).then(this.addBackendItemToCache);
|
|
2518
|
-
}
|
|
2533
|
+
}
|
|
2534
|
+
}
|
|
2535
|
+
static {
|
|
2536
|
+
this.getDerivedStateFromProps = (props, state) => {
|
|
2537
|
+
if (!props.value && state.currentItem) return { currentItem: null };
|
|
2538
|
+
return null;
|
|
2539
|
+
};
|
|
2519
2540
|
}
|
|
2520
2541
|
render() {
|
|
2521
2542
|
const { clearable, noResultsMessage, disabled, menuPortalTarget } = this.props;
|
|
@@ -2801,7 +2822,7 @@ function Menu({ onChange, onShowCustomPeriod, periodName, timezone }) {
|
|
|
2801
2822
|
const [visible, setVisible] = (0, react.useState)(false);
|
|
2802
2823
|
const [showDatePicker, setShowDatePicker] = (0, react.useState)(false);
|
|
2803
2824
|
const [showMonthPicker, setShowMonthPicker] = (0, react.useState)(false);
|
|
2804
|
-
const [datePickerDate, setDatePickerDate] = (0, react.useState)(Date.now());
|
|
2825
|
+
const [datePickerDate, setDatePickerDate] = (0, react.useState)(() => Date.now());
|
|
2805
2826
|
function setPeriod(period) {
|
|
2806
2827
|
onChange(period);
|
|
2807
2828
|
setVisible(false);
|
|
@@ -3227,17 +3248,18 @@ function sortModifications(modifications) {
|
|
|
3227
3248
|
//#endregion
|
|
3228
3249
|
//#region src/components/svg/SvgImage.tsx
|
|
3229
3250
|
function useGlobalStyleElement() {
|
|
3230
|
-
const
|
|
3251
|
+
const [styleElement] = (0, react.useState)(() => {
|
|
3252
|
+
const element = document.createElement("style");
|
|
3253
|
+
element.appendChild(document.createTextNode(""));
|
|
3254
|
+
return element;
|
|
3255
|
+
});
|
|
3231
3256
|
(0, react.useEffect)(() => {
|
|
3232
|
-
const styleElement = document.createElement("style");
|
|
3233
|
-
styleElement.appendChild(document.createTextNode(""));
|
|
3234
3257
|
if (document && document.head) document.head.appendChild(styleElement);
|
|
3235
|
-
styleElementRef.current = styleElement;
|
|
3236
3258
|
return () => {
|
|
3237
|
-
if (document && document.head
|
|
3259
|
+
if (document && document.head) document.head.removeChild(styleElement);
|
|
3238
3260
|
};
|
|
3239
|
-
}, []);
|
|
3240
|
-
return
|
|
3261
|
+
}, [styleElement]);
|
|
3262
|
+
return styleElement;
|
|
3241
3263
|
}
|
|
3242
3264
|
function SvgImage({ imageData, modifications, onConflict }) {
|
|
3243
3265
|
const svgWrapperRef = (0, react.useRef)(null);
|
|
@@ -3326,9 +3348,10 @@ var getClickConfiguration = (onClick) => {
|
|
|
3326
3348
|
var Chart = class extends react.Component {
|
|
3327
3349
|
constructor(..._args) {
|
|
3328
3350
|
super(..._args);
|
|
3329
|
-
this.state = {};
|
|
3351
|
+
this.state = { titleApplied: false };
|
|
3330
3352
|
this.chart = null;
|
|
3331
3353
|
this.ro = null;
|
|
3354
|
+
this.titleTimeoutId = void 0;
|
|
3332
3355
|
this.handleChart = (chart) => {
|
|
3333
3356
|
this.chart = chart;
|
|
3334
3357
|
this.ro = new ResizeObserver(() => {
|
|
@@ -3338,8 +3361,16 @@ var Chart = class extends react.Component {
|
|
|
3338
3361
|
};
|
|
3339
3362
|
}
|
|
3340
3363
|
componentDidMount() {
|
|
3364
|
+
this.titleTimeoutId = setTimeout(() => this.setState({ titleApplied: true }), 0);
|
|
3365
|
+
}
|
|
3366
|
+
/**
|
|
3367
|
+
* Builds the Highcharts configuration from the props. Everything here is derived, so it is
|
|
3368
|
+
* rebuilt while rendering rather than mirrored into state.
|
|
3369
|
+
*/
|
|
3370
|
+
buildOptions() {
|
|
3341
3371
|
const { type, title, items, tooltipTitle, valueFormatter, onClick } = this.props;
|
|
3342
|
-
this.
|
|
3372
|
+
const { titleApplied } = this.state;
|
|
3373
|
+
return {
|
|
3343
3374
|
...initialOptions,
|
|
3344
3375
|
plotOptions: {
|
|
3345
3376
|
...initialOptions.plotOptions,
|
|
@@ -3356,44 +3387,12 @@ var Chart = class extends react.Component {
|
|
|
3356
3387
|
...initialOptions.legend,
|
|
3357
3388
|
enabled: type === "pie"
|
|
3358
3389
|
},
|
|
3359
|
-
yAxis: {
|
|
3360
|
-
...initialOptions.yAxis,
|
|
3361
|
-
enabled: type === "column",
|
|
3362
|
-
title: { text: title || "" }
|
|
3363
|
-
},
|
|
3364
|
-
series: [{
|
|
3365
|
-
type,
|
|
3366
|
-
innerSize: "50%",
|
|
3367
|
-
data: items.map(({ label, value }) => [label, value])
|
|
3368
|
-
}]
|
|
3369
|
-
});
|
|
3370
|
-
setTimeout(() => {
|
|
3371
|
-
this.setState({ title: {
|
|
3372
|
-
...initialOptions.title,
|
|
3373
|
-
text: type === "column" ? "" : title || ""
|
|
3374
|
-
} });
|
|
3375
|
-
}, 0);
|
|
3376
|
-
}
|
|
3377
|
-
componentDidUpdate(prevProps) {
|
|
3378
|
-
const { type, title, items, tooltipTitle, valueFormatter, onClick } = this.props;
|
|
3379
|
-
if (title !== prevProps.title) this.setState({
|
|
3380
3390
|
title: {
|
|
3381
|
-
...
|
|
3382
|
-
text: type
|
|
3383
|
-
},
|
|
3384
|
-
yAxis: {
|
|
3385
|
-
...this.state.yAxis,
|
|
3386
|
-
title: { text: title || "" }
|
|
3387
|
-
}
|
|
3388
|
-
});
|
|
3389
|
-
if (type !== prevProps.type) this.setState({
|
|
3390
|
-
legend: {
|
|
3391
|
-
...this.state.legend,
|
|
3392
|
-
enabled: type === "pie"
|
|
3391
|
+
...initialOptions.title,
|
|
3392
|
+
text: titleApplied && type !== "column" ? title || "" : ""
|
|
3393
3393
|
},
|
|
3394
|
-
title: { text: type === "column" ? "" : title || "" },
|
|
3395
3394
|
yAxis: {
|
|
3396
|
-
...
|
|
3395
|
+
...initialOptions.yAxis,
|
|
3397
3396
|
enabled: type === "column",
|
|
3398
3397
|
title: { text: type === "column" ? title || "" : "" }
|
|
3399
3398
|
},
|
|
@@ -3402,35 +3401,19 @@ var Chart = class extends react.Component {
|
|
|
3402
3401
|
innerSize: "50%",
|
|
3403
3402
|
data: items.map(({ label, value }) => [label, value])
|
|
3404
3403
|
}]
|
|
3405
|
-
}
|
|
3406
|
-
if (!(0, lodash.isEqual)(items, prevProps.items)) this.setState({ series: [{
|
|
3407
|
-
type,
|
|
3408
|
-
innerSize: "50%",
|
|
3409
|
-
data: items.map(({ label, value }) => [label, value])
|
|
3410
|
-
}] });
|
|
3411
|
-
if (tooltipTitle !== prevProps.tooltipTitle || valueFormatter !== prevProps.valueFormatter || onClick !== prevProps.onClick) this.setState({
|
|
3412
|
-
tooltip: {
|
|
3413
|
-
...initialOptions.tooltip,
|
|
3414
|
-
formatter() {
|
|
3415
|
-
const format = valueFormatter || ((value) => value);
|
|
3416
|
-
return createTooltip(tooltipTitle || "", this.point.name, format(this.point.y));
|
|
3417
|
-
}
|
|
3418
|
-
},
|
|
3419
|
-
plotOptions: {
|
|
3420
|
-
...initialOptions.plotOptions,
|
|
3421
|
-
...getClickConfiguration(onClick)
|
|
3422
|
-
}
|
|
3423
|
-
});
|
|
3404
|
+
};
|
|
3424
3405
|
}
|
|
3425
3406
|
componentWillUnmount() {
|
|
3407
|
+
clearTimeout(this.titleTimeoutId);
|
|
3426
3408
|
if (this.ro && this.chart?.renderTo) this.ro.unobserve(this.chart.renderTo);
|
|
3427
3409
|
this.chart = null;
|
|
3428
3410
|
this.ro = null;
|
|
3429
3411
|
}
|
|
3430
3412
|
render() {
|
|
3413
|
+
const built = this.buildOptions();
|
|
3431
3414
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(highcharts_react_official.default, {
|
|
3432
3415
|
highcharts: highcharts.default,
|
|
3433
|
-
options: this.props.updateOptions ? this.props.updateOptions(
|
|
3416
|
+
options: this.props.updateOptions ? this.props.updateOptions(built) : built,
|
|
3434
3417
|
containerProps: { className: this.props.className },
|
|
3435
3418
|
callback: this.handleChart
|
|
3436
3419
|
});
|