@iobroker/gui-components 10.3.14 → 10.3.16
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 +12 -1
- package/build/Components/AnimatedIcons/IconBell.d.ts +21 -0
- package/build/Components/AnimatedIcons/IconBell.js +50 -0
- package/build/Components/AnimatedIcons/IconBell.js.map +1 -0
- package/build/Components/AnimatedIcons/IconConnectionState.d.ts +19 -0
- package/build/Components/AnimatedIcons/IconConnectionState.js +25 -0
- package/build/Components/AnimatedIcons/IconConnectionState.js.map +1 -0
- package/build/Components/AnimatedIcons/IconExpertMode.d.ts +22 -0
- package/build/Components/AnimatedIcons/IconExpertMode.js +47 -0
- package/build/Components/AnimatedIcons/IconExpertMode.js.map +1 -0
- package/build/Components/AnimatedIcons/IconFolder.d.ts +22 -0
- package/build/Components/AnimatedIcons/IconFolder.js +29 -0
- package/build/Components/AnimatedIcons/IconFolder.js.map +1 -0
- package/build/Components/AnimatedIcons/IconMenuArrow.d.ts +23 -0
- package/build/Components/AnimatedIcons/IconMenuArrow.js +26 -0
- package/build/Components/AnimatedIcons/IconMenuArrow.js.map +1 -0
- package/build/Components/AnimatedIcons/IconPlayPause.d.ts +23 -0
- package/build/Components/AnimatedIcons/IconPlayPause.js +25 -0
- package/build/Components/AnimatedIcons/IconPlayPause.js.map +1 -0
- package/build/Components/AnimatedIcons/IconRefresh.d.ts +23 -0
- package/build/Components/AnimatedIcons/IconRefresh.js +86 -0
- package/build/Components/AnimatedIcons/IconRefresh.js.map +1 -0
- package/build/Components/AnimatedIcons/IconResult.d.ts +21 -0
- package/build/Components/AnimatedIcons/IconResult.js +36 -0
- package/build/Components/AnimatedIcons/IconResult.js.map +1 -0
- package/build/Components/AnimatedIcons/IconStatusLed.d.ts +25 -0
- package/build/Components/AnimatedIcons/IconStatusLed.js +58 -0
- package/build/Components/AnimatedIcons/IconStatusLed.js.map +1 -0
- package/build/Components/AnimatedIcons/IconTrash.d.ts +20 -0
- package/build/Components/AnimatedIcons/IconTrash.js +23 -0
- package/build/Components/AnimatedIcons/IconTrash.js.map +1 -0
- package/build/Components/AnimatedIcons/common.d.ts +31 -0
- package/build/Components/AnimatedIcons/common.js +164 -0
- package/build/Components/AnimatedIcons/common.js.map +1 -0
- package/build/Components/FileBrowser.js +4 -5
- package/build/Components/FileBrowser.js.map +1 -1
- package/build/Components/Loaders/Community.d.ts +13 -2
- package/build/Components/Loaders/Community.js +176 -243
- package/build/Components/Loaders/Community.js.map +1 -1
- package/build/Components/Loaders/CommunityLegacy.d.ts +32 -0
- package/build/Components/Loaders/CommunityLegacy.js +266 -0
- package/build/Components/Loaders/CommunityLegacy.js.map +1 -0
- package/build/Components/ObjectBrowser/ObjectBrowserClass.d.ts +18 -0
- package/build/Components/ObjectBrowser/ObjectBrowserClass.js +131 -3
- package/build/Components/ObjectBrowser/ObjectBrowserClass.js.map +1 -1
- package/build/Components/ObjectBrowser/dialogs.js +2 -2
- package/build/Components/ObjectBrowser/dialogs.js.map +1 -1
- package/build/Components/ObjectBrowser/renderLeaf.js +48 -8
- package/build/Components/ObjectBrowser/renderLeaf.js.map +1 -1
- package/build/Components/ObjectBrowser/rowAnimation.d.ts +9 -0
- package/build/Components/ObjectBrowser/rowAnimation.js +122 -0
- package/build/Components/ObjectBrowser/rowAnimation.js.map +1 -0
- package/build/Components/ObjectBrowser/toolbar.js +5 -4
- package/build/Components/ObjectBrowser/toolbar.js.map +1 -1
- package/build/Components/ObjectBrowser/utils.d.ts +2 -0
- package/build/Components/ObjectBrowser/utils.js +2 -0
- package/build/Components/ObjectBrowser/utils.js.map +1 -1
- package/build/Components/SaveCloseButtons.d.ts +12 -1
- package/build/Components/SaveCloseButtons.js +38 -2
- package/build/Components/SaveCloseButtons.js.map +1 -1
- package/build/index.d.ts +13 -0
- package/build/index.js +12 -0
- package/build/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright 2018-2024 Denis Haev (bluefox) <dogafox@gmail.com>
|
|
3
|
+
*
|
|
4
|
+
* MIT License
|
|
5
|
+
*
|
|
6
|
+
* Previous loader of the community edition, replaced by `LoaderCommunity` in 2026-11.
|
|
7
|
+
*/
|
|
8
|
+
import React, { useEffect } from 'react';
|
|
9
|
+
const loaderStyles = `
|
|
10
|
+
/**
|
|
11
|
+
* Copyright 2018-2024 Denis Haev (bluefox) <dogafox@gmail.com>
|
|
12
|
+
*
|
|
13
|
+
* MIT License
|
|
14
|
+
*
|
|
15
|
+
**/
|
|
16
|
+
|
|
17
|
+
.logo-background-light, .logo-background-colored {
|
|
18
|
+
background: white;
|
|
19
|
+
}
|
|
20
|
+
.logo-background-dark, .logo-background-blue {
|
|
21
|
+
background: black;
|
|
22
|
+
}
|
|
23
|
+
.logo-div {
|
|
24
|
+
position: absolute;
|
|
25
|
+
top: 50%;
|
|
26
|
+
left: 50%;
|
|
27
|
+
-ms-transform: translateX(-50%) translateY(-50%);
|
|
28
|
+
-webkit-transform: translate(-50%,-50%);
|
|
29
|
+
transform: translate(-50%,-50%);
|
|
30
|
+
overflow: hidden;
|
|
31
|
+
border-radius: 50%;
|
|
32
|
+
z-index: 2;
|
|
33
|
+
}
|
|
34
|
+
.logo-border {
|
|
35
|
+
/*border-color: #164477;*/
|
|
36
|
+
border-top-color: #3399CC;
|
|
37
|
+
border-left-color: #164477;
|
|
38
|
+
border-bottom-color: #164477;
|
|
39
|
+
border-right-color: #164477;
|
|
40
|
+
border-radius: 50%;
|
|
41
|
+
border-style: solid;
|
|
42
|
+
box-sizing: border-box;
|
|
43
|
+
width: 100%;
|
|
44
|
+
height: 100%;
|
|
45
|
+
position: absolute;
|
|
46
|
+
}
|
|
47
|
+
.logo-top {
|
|
48
|
+
position: absolute;
|
|
49
|
+
width: 4.5%;
|
|
50
|
+
height: 16%;
|
|
51
|
+
top: 0;
|
|
52
|
+
z-index: 2;
|
|
53
|
+
}
|
|
54
|
+
.logo-i {
|
|
55
|
+
position: absolute;
|
|
56
|
+
width: 14.5%;
|
|
57
|
+
height: 60%;
|
|
58
|
+
top: 20%;
|
|
59
|
+
left: 42%;
|
|
60
|
+
background: #3399CC;
|
|
61
|
+
}
|
|
62
|
+
.logo-i-top {
|
|
63
|
+
position: absolute;
|
|
64
|
+
width: 14.5%;
|
|
65
|
+
height: 4%;
|
|
66
|
+
left: 42%;
|
|
67
|
+
background: #3399CC;
|
|
68
|
+
border-radius: 100%;
|
|
69
|
+
}
|
|
70
|
+
.logo-back {
|
|
71
|
+
width: 100%;
|
|
72
|
+
height: 100%;
|
|
73
|
+
z-index: 0;
|
|
74
|
+
overflow: hidden;
|
|
75
|
+
}
|
|
76
|
+
@keyframes logo-grow {
|
|
77
|
+
0% {
|
|
78
|
+
width: 230px;
|
|
79
|
+
height: 230px;
|
|
80
|
+
transform: translate(-50%,-50%) scale(1);
|
|
81
|
+
opacity: 1
|
|
82
|
+
}
|
|
83
|
+
99% {
|
|
84
|
+
width: 230px;
|
|
85
|
+
height: 230px;
|
|
86
|
+
transform: translate(-50%,-50%) scale(10);
|
|
87
|
+
opacity: 0;
|
|
88
|
+
}
|
|
89
|
+
100% {
|
|
90
|
+
width: 0;
|
|
91
|
+
height: 0;
|
|
92
|
+
opacity: 0;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
@keyframes logo-spin { 100% { -webkit-transform: rotate(360deg); transform: rotate(360deg); } }
|
|
96
|
+
@keyframes logo-color-inside-light {
|
|
97
|
+
0% {
|
|
98
|
+
background: #FEFEFE;
|
|
99
|
+
}
|
|
100
|
+
100% {
|
|
101
|
+
background: #3399CC;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
@keyframes logo-color-inside-dark {
|
|
105
|
+
0% {
|
|
106
|
+
background: #030303;
|
|
107
|
+
}
|
|
108
|
+
100% {
|
|
109
|
+
background: #3399CC;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
@keyframes logo-color-inside-colored {
|
|
113
|
+
0% {
|
|
114
|
+
background: #FEFEFE;
|
|
115
|
+
}
|
|
116
|
+
100% {
|
|
117
|
+
background: #3399CC;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
@keyframes logo-color-inside-blue {
|
|
121
|
+
0% {
|
|
122
|
+
background: #030303;
|
|
123
|
+
}
|
|
124
|
+
100% {
|
|
125
|
+
background: #3399CC;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
@keyframes logo-color-outside-light {
|
|
130
|
+
0% {
|
|
131
|
+
border-color: #FEFEFE;
|
|
132
|
+
}
|
|
133
|
+
100% {
|
|
134
|
+
border-top-color: #3399CC;
|
|
135
|
+
border-left-color: #164477;
|
|
136
|
+
border-bottom-color: #164477;
|
|
137
|
+
border-right-color: #164477;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
@keyframes logo-color-outside-dark {
|
|
141
|
+
0% {
|
|
142
|
+
border-color: #040404;
|
|
143
|
+
}
|
|
144
|
+
100% {
|
|
145
|
+
border-top-color: #3399CC;
|
|
146
|
+
border-left-color: #164477;
|
|
147
|
+
border-bottom-color: #164477;
|
|
148
|
+
border-right-color: #164477;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
@keyframes logo-color-outside-colored {
|
|
152
|
+
0% {
|
|
153
|
+
border-color: #FEFEFE;
|
|
154
|
+
}
|
|
155
|
+
100% {
|
|
156
|
+
border-top-color: #3399CC;
|
|
157
|
+
border-left-color: #164477;
|
|
158
|
+
border-bottom-color: #164477;
|
|
159
|
+
border-right-color: #164477;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
@keyframes logo-color-outside-blue {
|
|
163
|
+
0% {
|
|
164
|
+
border-color: #040404;
|
|
165
|
+
}
|
|
166
|
+
100% {
|
|
167
|
+
border-top-color: #3399CC;
|
|
168
|
+
border-left-color: #164477;
|
|
169
|
+
border-bottom-color: #164477;
|
|
170
|
+
border-right-color: #164477;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
.logo-animate-wait {
|
|
175
|
+
animation: logo-color-outside 1.5s, logo-spin 1.5s linear infinite;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
.logo-animate-grow-light {
|
|
179
|
+
background: #DDD;
|
|
180
|
+
}
|
|
181
|
+
.logo-animate-grow-dark {
|
|
182
|
+
background: #1d1d1d;
|
|
183
|
+
}
|
|
184
|
+
.logo-animate-grow-colored {
|
|
185
|
+
background: #DDD;
|
|
186
|
+
}
|
|
187
|
+
.logo-animate-grow-blue {
|
|
188
|
+
background: #1d1d1d;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
.logo-animate-grow {
|
|
192
|
+
display: inline-block;
|
|
193
|
+
text-align: center;
|
|
194
|
+
z-index: 1;
|
|
195
|
+
top: 50%;
|
|
196
|
+
left: 50%;
|
|
197
|
+
-ms-transform: translateX(-50%) translateY(-50%);
|
|
198
|
+
-webkit-transform: translate(-50%,-50%);
|
|
199
|
+
transform: translate(-50%,-50%);
|
|
200
|
+
width: 245px;
|
|
201
|
+
height: 245px;
|
|
202
|
+
border-radius: 50%;
|
|
203
|
+
position: absolute;
|
|
204
|
+
animation: logo-grow 1s 1 ease forwards;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
.logo-animate-color-inside-light {
|
|
208
|
+
animation: logo-color-inside-light 2.5s;
|
|
209
|
+
}
|
|
210
|
+
.logo-animate-color-inside-dark {
|
|
211
|
+
animation: logo-color-inside-dark 2.5s;
|
|
212
|
+
}
|
|
213
|
+
.logo-animate-color-inside-colored {
|
|
214
|
+
animation: logo-color-inside-colored 2.5s;
|
|
215
|
+
}
|
|
216
|
+
.logo-animate-color-inside-blue {
|
|
217
|
+
animation: logo-color-inside-blue 2.5s;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
.logo-animate-color-outside-light {
|
|
221
|
+
animation: logo-color-outside-light 1.5s;
|
|
222
|
+
}
|
|
223
|
+
.logo-animate-color-outside-dark {
|
|
224
|
+
animation: logo-color-outside-dark 1.5s;
|
|
225
|
+
}
|
|
226
|
+
.logo-animate-color-outside-colored {
|
|
227
|
+
animation: logo-color-outside-colored 1.5s;
|
|
228
|
+
}
|
|
229
|
+
.logo-animate-color-outside-blue {
|
|
230
|
+
animation: logo-color-outside-blue 1.5s;
|
|
231
|
+
}
|
|
232
|
+
`;
|
|
233
|
+
export function LoaderCommunityLegacy(props) {
|
|
234
|
+
useEffect(() => {
|
|
235
|
+
if (!window.document.getElementById('loader-iobroker-component')) {
|
|
236
|
+
const style = window.document.createElement('style');
|
|
237
|
+
style.setAttribute('id', 'loader-iobroker-component');
|
|
238
|
+
style.innerHTML = loaderStyles;
|
|
239
|
+
window.document.head.appendChild(style);
|
|
240
|
+
}
|
|
241
|
+
}, []);
|
|
242
|
+
const size = props.size || 234;
|
|
243
|
+
const theme = props.themeName || props.theme || props.themeType || 'light';
|
|
244
|
+
return (React.createElement("div", { className: `logo-back logo-background-${theme}`, style: {
|
|
245
|
+
backgroundImage: props.backgroundImage && props.backgroundImage !== '@@loginBackgroundImage@@'
|
|
246
|
+
? props.backgroundImage
|
|
247
|
+
: window.loadingBackgroundImage && window.loadingBackgroundImage !== '@@loginBackgroundImage@@'
|
|
248
|
+
? `url(${window.loadingBackgroundImage})`
|
|
249
|
+
: undefined,
|
|
250
|
+
backgroundColor: props.backgroundColor && props.backgroundColor !== '@@loginBackgroundColor@@'
|
|
251
|
+
? props.backgroundColor
|
|
252
|
+
: window.loadingBackgroundColor && window.loadingBackgroundColor !== '@@loginBackgroundColor@@'
|
|
253
|
+
? window.loadingBackgroundColor
|
|
254
|
+
: undefined,
|
|
255
|
+
backgroundSize: 'cover',
|
|
256
|
+
} }, window.loadingHideLogo === 'true' ? null : (React.createElement(React.Fragment, null,
|
|
257
|
+
React.createElement("div", { className: "logo-div", style: { width: size, height: size } },
|
|
258
|
+
React.createElement("div", { className: `logo-top logo-background-${theme}`, style: { left: '37%' } }),
|
|
259
|
+
React.createElement("div", { className: `logo-top logo-background-${theme}`, style: { left: '57%' } }),
|
|
260
|
+
React.createElement("div", { className: `logo-border logo-background-${theme} logo-animate-wait`, style: { borderWidth: size * 0.132 } }),
|
|
261
|
+
React.createElement("div", { className: `logo-i logo-animate-color-inside-${theme}` }),
|
|
262
|
+
React.createElement("div", { className: `logo-i-top logo-animate-color-inside-${theme}`, style: { top: '18%' } }),
|
|
263
|
+
React.createElement("div", { className: `logo-i-top logo-animate-color-inside-${theme}`, style: { bottom: '18%' } })),
|
|
264
|
+
React.createElement("div", { className: `logo-animate-grow logo-animate-grow-${theme}`, style: { width: size + 11, height: size + 11 } })))));
|
|
265
|
+
}
|
|
266
|
+
//# sourceMappingURL=CommunityLegacy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CommunityLegacy.js","sourceRoot":"./src/","sources":["Components/Loaders/CommunityLegacy.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n * Copyright 2018-2024 Denis Haev (bluefox) <dogafox@gmail.com>\n *\n * MIT License\n *\n * Previous loader of the community edition, replaced by `LoaderCommunity` in 2026-11.\n */\nimport React, { useEffect } from 'react';\nimport type { ThemeName, ThemeType } from '../../types';\n\ndeclare global {\n interface Window {\n loadingBackgroundImage: undefined | string;\n loadingBackgroundColor: undefined | string;\n loadingHideLogo: undefined | 'true';\n }\n}\n\nconst loaderStyles = `\n/**\n * Copyright 2018-2024 Denis Haev (bluefox) <dogafox@gmail.com>\n *\n * MIT License\n *\n **/\n\n.logo-background-light, .logo-background-colored {\n background: white;\n}\n.logo-background-dark, .logo-background-blue {\n background: black;\n}\n.logo-div {\n position: absolute;\n top: 50%;\n left: 50%;\n -ms-transform: translateX(-50%) translateY(-50%);\n -webkit-transform: translate(-50%,-50%);\n transform: translate(-50%,-50%);\n overflow: hidden;\n border-radius: 50%;\n z-index: 2;\n}\n.logo-border {\n /*border-color: #164477;*/\n border-top-color: #3399CC;\n border-left-color: #164477;\n border-bottom-color: #164477;\n border-right-color: #164477;\n border-radius: 50%;\n border-style: solid;\n box-sizing: border-box;\n width: 100%;\n height: 100%;\n position: absolute;\n}\n.logo-top {\n position: absolute;\n width: 4.5%;\n height: 16%;\n top: 0;\n z-index: 2;\n}\n.logo-i {\n position: absolute;\n width: 14.5%;\n height: 60%;\n top: 20%;\n left: 42%;\n background: #3399CC;\n}\n.logo-i-top {\n position: absolute;\n width: 14.5%;\n height: 4%;\n left: 42%;\n background: #3399CC;\n border-radius: 100%;\n}\n.logo-back {\n width: 100%;\n height: 100%;\n z-index: 0;\n overflow: hidden;\n}\n@keyframes logo-grow {\n 0% {\n width: 230px;\n height: 230px;\n transform: translate(-50%,-50%) scale(1);\n opacity: 1\n }\n 99% {\n width: 230px;\n height: 230px;\n transform: translate(-50%,-50%) scale(10);\n opacity: 0;\n }\n 100% {\n width: 0;\n height: 0;\n opacity: 0;\n }\n}\n@keyframes logo-spin { 100% { -webkit-transform: rotate(360deg); transform: rotate(360deg); } }\n@keyframes logo-color-inside-light {\n 0% {\n background: #FEFEFE;\n }\n 100% {\n background: #3399CC;\n }\n}\n@keyframes logo-color-inside-dark {\n 0% {\n background: #030303;\n }\n 100% {\n background: #3399CC;\n }\n}\n@keyframes logo-color-inside-colored {\n 0% {\n background: #FEFEFE;\n }\n 100% {\n background: #3399CC;\n }\n}\n@keyframes logo-color-inside-blue {\n 0% {\n background: #030303;\n }\n 100% {\n background: #3399CC;\n }\n}\n\n@keyframes logo-color-outside-light {\n 0% {\n border-color: #FEFEFE;\n }\n 100% {\n border-top-color: #3399CC;\n border-left-color: #164477;\n border-bottom-color: #164477;\n border-right-color: #164477;\n }\n}\n@keyframes logo-color-outside-dark {\n 0% {\n border-color: #040404;\n }\n 100% {\n border-top-color: #3399CC;\n border-left-color: #164477;\n border-bottom-color: #164477;\n border-right-color: #164477;\n }\n}\n@keyframes logo-color-outside-colored {\n 0% {\n border-color: #FEFEFE;\n }\n 100% {\n border-top-color: #3399CC;\n border-left-color: #164477;\n border-bottom-color: #164477;\n border-right-color: #164477;\n }\n}\n@keyframes logo-color-outside-blue {\n 0% {\n border-color: #040404;\n }\n 100% {\n border-top-color: #3399CC;\n border-left-color: #164477;\n border-bottom-color: #164477;\n border-right-color: #164477;\n }\n}\n\n.logo-animate-wait {\n animation: logo-color-outside 1.5s, logo-spin 1.5s linear infinite;\n}\n\n.logo-animate-grow-light {\n background: #DDD;\n}\n.logo-animate-grow-dark {\n background: #1d1d1d;\n}\n.logo-animate-grow-colored {\n background: #DDD;\n}\n.logo-animate-grow-blue {\n background: #1d1d1d;\n}\n\n.logo-animate-grow {\n display: inline-block;\n text-align: center;\n z-index: 1;\n top: 50%;\n left: 50%;\n -ms-transform: translateX(-50%) translateY(-50%);\n -webkit-transform: translate(-50%,-50%);\n transform: translate(-50%,-50%);\n width: 245px;\n height: 245px;\n border-radius: 50%;\n position: absolute;\n animation: logo-grow 1s 1 ease forwards;\n}\n\n.logo-animate-color-inside-light {\n animation: logo-color-inside-light 2.5s;\n}\n.logo-animate-color-inside-dark {\n animation: logo-color-inside-dark 2.5s;\n}\n.logo-animate-color-inside-colored {\n animation: logo-color-inside-colored 2.5s;\n}\n.logo-animate-color-inside-blue {\n animation: logo-color-inside-blue 2.5s;\n}\n\n.logo-animate-color-outside-light {\n animation: logo-color-outside-light 1.5s;\n}\n.logo-animate-color-outside-dark {\n animation: logo-color-outside-dark 1.5s;\n}\n.logo-animate-color-outside-colored {\n animation: logo-color-outside-colored 1.5s;\n}\n.logo-animate-color-outside-blue {\n animation: logo-color-outside-blue 1.5s;\n}\n`;\n\ninterface LoaderProps {\n /** The size in pixels of this loader. */\n size?: number;\n /** The chosen theme type. */\n themeType?: ThemeType;\n /** Theme name */\n themeName?: ThemeName;\n /** @deprecated Theme name. use themeName instead */\n theme?: ThemeName;\n /** Background color */\n backgroundColor?: string;\n /** Background image URL */\n backgroundImage?: string;\n}\n\nexport function LoaderCommunityLegacy(props: LoaderProps): React.JSX.Element {\n useEffect(() => {\n if (!window.document.getElementById('loader-iobroker-component')) {\n const style = window.document.createElement('style');\n style.setAttribute('id', 'loader-iobroker-component');\n style.innerHTML = loaderStyles;\n window.document.head.appendChild(style);\n }\n }, []);\n\n const size = props.size || 234;\n const theme = props.themeName || props.theme || props.themeType || 'light';\n return (\n <div\n className={`logo-back logo-background-${theme}`}\n style={{\n backgroundImage:\n props.backgroundImage && props.backgroundImage !== '@@loginBackgroundImage@@'\n ? props.backgroundImage\n : window.loadingBackgroundImage && window.loadingBackgroundImage !== '@@loginBackgroundImage@@'\n ? `url(${window.loadingBackgroundImage})`\n : undefined,\n backgroundColor:\n props.backgroundColor && props.backgroundColor !== '@@loginBackgroundColor@@'\n ? props.backgroundColor\n : window.loadingBackgroundColor && window.loadingBackgroundColor !== '@@loginBackgroundColor@@'\n ? window.loadingBackgroundColor\n : undefined,\n backgroundSize: 'cover',\n }}\n >\n {window.loadingHideLogo === 'true' ? null : (\n <>\n <div\n className=\"logo-div\"\n style={{ width: size, height: size }}\n >\n <div\n className={`logo-top logo-background-${theme}`}\n style={{ left: '37%' }}\n />\n <div\n className={`logo-top logo-background-${theme}`}\n style={{ left: '57%' }}\n />\n <div\n className={`logo-border logo-background-${theme} logo-animate-wait`}\n style={{ borderWidth: size * 0.132 }}\n />\n <div className={`logo-i logo-animate-color-inside-${theme}`} />\n <div\n className={`logo-i-top logo-animate-color-inside-${theme}`}\n style={{ top: '18%' }}\n />\n <div\n className={`logo-i-top logo-animate-color-inside-${theme}`}\n style={{ bottom: '18%' }}\n />\n </div>\n <div\n className={`logo-animate-grow logo-animate-grow-${theme}`}\n style={{ width: size + 11, height: size + 11 }}\n />\n </>\n )}\n </div>\n );\n}\n"]}
|
|
@@ -97,6 +97,20 @@ export declare class ObjectBrowserClass extends Component<ObjectBrowserProps, Ob
|
|
|
97
97
|
private windowLast;
|
|
98
98
|
/** id -> how often the state of this row has changed. Part of the memo key of the row */
|
|
99
99
|
readonly rowStateVersion: Record<string, number>;
|
|
100
|
+
/**
|
|
101
|
+
* id -> last change of a number (arrow up or down) or of a boolean (the value flips), see `renderColumnValue`.
|
|
102
|
+
* `shown` is the time the row showed it first, so a row that is rendered again continues the animation.
|
|
103
|
+
*/
|
|
104
|
+
readonly valueTrends: Record<string, {
|
|
105
|
+
dir: 'up' | 'down' | 'toggle';
|
|
106
|
+
ts: number;
|
|
107
|
+
shown?: number;
|
|
108
|
+
}>;
|
|
109
|
+
/** The running animations of an unfolded or folding node (see `rowAnimation.ts`) */
|
|
110
|
+
private rowAnimations;
|
|
111
|
+
/** The node whose children slide under its row at the moment; they are removed when that ends */
|
|
112
|
+
private foldingId;
|
|
113
|
+
private foldTimer;
|
|
100
114
|
private stateVersionCounter;
|
|
101
115
|
private selectFirst;
|
|
102
116
|
/** Last navigation that was applied from `navigateTo` or reported via `onNavigateTo` (loop guard). */
|
|
@@ -349,6 +363,10 @@ export declare class ObjectBrowserClass extends Component<ObjectBrowserProps, Ob
|
|
|
349
363
|
*/
|
|
350
364
|
getToolbar(): JSX.Element;
|
|
351
365
|
toggleExpanded(id: string): void;
|
|
366
|
+
/** The fold animation ended (or is cut short): remove the children of the node now */
|
|
367
|
+
private applyFold;
|
|
368
|
+
/** Ends a running fold or unfold animation at once */
|
|
369
|
+
private finishRowAnimations;
|
|
352
370
|
onCopy(e: React.MouseEvent, text: string | undefined): void;
|
|
353
371
|
renderTooltipAccessControl(acl: ioBroker.StateACL): null | JSX.Element;
|
|
354
372
|
renderColumnButtons(id: string, item: TreeItem): (JSX.Element | null)[] | JSX.Element | null;
|
|
@@ -17,13 +17,14 @@ import { Utils } from '../Utils'; // @iobroker/gui-components/Components/Utils
|
|
|
17
17
|
import { TabContainer } from '../TabContainer';
|
|
18
18
|
import { TabContent } from '../TabContent';
|
|
19
19
|
import { TabHeader } from '../TabHeader';
|
|
20
|
-
import { ROW_HEIGHT, applyFilter, buildTree, findNode, formatValue, generateFile, getName, colVar, widthFromContainer, growVar, getSelectIdIconFromObjects, setCustomValue, } from './utils';
|
|
20
|
+
import { ROW_HEIGHT, TREND_DURATION, applyFilter, buildTree, findNode, formatValue, generateFile, getName, colVar, widthFromContainer, growVar, getSelectIdIconFromObjects, setCustomValue, } from './utils';
|
|
21
21
|
import { HistoryChart } from './HistoryChart';
|
|
22
22
|
import { styles } from './styles';
|
|
23
23
|
import * as dialogs from './dialogs';
|
|
24
24
|
import * as toolbar from './toolbar';
|
|
25
25
|
import * as leaf from './renderLeaf';
|
|
26
26
|
import * as contextMenu from './contextMenu';
|
|
27
|
+
import * as rowAnimation from './rowAnimation';
|
|
27
28
|
import { DEFAULT_DATE_FORMAT, DEFAULT_FILTER, ITEM_LEVEL, MIN_COLUMN_WIDTHS, SCREEN_WIDTHS, } from './constants';
|
|
28
29
|
export { getSelectIdIconFromObjects };
|
|
29
30
|
let objectsAlreadyLoaded = false;
|
|
@@ -123,6 +124,16 @@ export class ObjectBrowserClass extends Component {
|
|
|
123
124
|
windowLast = 0;
|
|
124
125
|
/** id -> how often the state of this row has changed. Part of the memo key of the row */
|
|
125
126
|
rowStateVersion = {};
|
|
127
|
+
/**
|
|
128
|
+
* id -> last change of a number (arrow up or down) or of a boolean (the value flips), see `renderColumnValue`.
|
|
129
|
+
* `shown` is the time the row showed it first, so a row that is rendered again continues the animation.
|
|
130
|
+
*/
|
|
131
|
+
valueTrends = {};
|
|
132
|
+
/** The running animations of an unfolded or folding node (see `rowAnimation.ts`) */
|
|
133
|
+
rowAnimations = [];
|
|
134
|
+
/** The node whose children slide under its row at the moment; they are removed when that ends */
|
|
135
|
+
foldingId = null;
|
|
136
|
+
foldTimer = null;
|
|
126
137
|
stateVersionCounter = 0;
|
|
127
138
|
selectFirst;
|
|
128
139
|
/** Last navigation that was applied from `navigateTo` or reported via `onNavigateTo` (loop guard). */
|
|
@@ -764,6 +775,14 @@ export class ObjectBrowserClass extends Component {
|
|
|
764
775
|
window.cancelAnimationFrame(this.scrollFrame);
|
|
765
776
|
this.scrollFrame = null;
|
|
766
777
|
}
|
|
778
|
+
// a fold animation must not update the state after the component was destroyed
|
|
779
|
+
this.foldingId = null;
|
|
780
|
+
if (this.foldTimer) {
|
|
781
|
+
clearTimeout(this.foldTimer);
|
|
782
|
+
this.foldTimer = null;
|
|
783
|
+
}
|
|
784
|
+
this.rowAnimations.forEach(animation => animation.cancel());
|
|
785
|
+
this.rowAnimations = [];
|
|
767
786
|
// the timers must not fire after the component was destroyed
|
|
768
787
|
if (this.unsubscribeTimer) {
|
|
769
788
|
clearTimeout(this.unsubscribeTimer);
|
|
@@ -1059,6 +1078,16 @@ export class ObjectBrowserClass extends Component {
|
|
|
1059
1078
|
item.data.state = undefined;
|
|
1060
1079
|
}
|
|
1061
1080
|
}
|
|
1081
|
+
const oldVal = oldState?.val;
|
|
1082
|
+
const newVal = state?.val;
|
|
1083
|
+
if (typeof oldVal === 'number' && typeof newVal === 'number' && oldVal !== newVal) {
|
|
1084
|
+
if (!Number.isNaN(oldVal) && !Number.isNaN(newVal)) {
|
|
1085
|
+
this.valueTrends[id] = { dir: newVal > oldVal ? 'up' : 'down', ts: Date.now() };
|
|
1086
|
+
}
|
|
1087
|
+
}
|
|
1088
|
+
else if (typeof oldVal === 'boolean' && typeof newVal === 'boolean' && oldVal !== newVal) {
|
|
1089
|
+
this.valueTrends[id] = { dir: 'toggle', ts: Date.now() };
|
|
1090
|
+
}
|
|
1062
1091
|
if (state) {
|
|
1063
1092
|
this.states[id] = state;
|
|
1064
1093
|
}
|
|
@@ -1775,7 +1804,10 @@ export class ObjectBrowserClass extends Component {
|
|
|
1775
1804
|
return toolbar.getToolbar(this);
|
|
1776
1805
|
}
|
|
1777
1806
|
toggleExpanded(id) {
|
|
1778
|
-
|
|
1807
|
+
// a node that is still folding is folded now, this toggle builds on it
|
|
1808
|
+
const folding = this.foldingId;
|
|
1809
|
+
this.finishRowAnimations();
|
|
1810
|
+
const expanded = this.state.expanded.filter(item => item !== folding);
|
|
1779
1811
|
const pos = expanded.indexOf(id);
|
|
1780
1812
|
if (pos === -1) {
|
|
1781
1813
|
expanded.push(id);
|
|
@@ -1785,7 +1817,50 @@ export class ObjectBrowserClass extends Component {
|
|
|
1785
1817
|
expanded.splice(pos, 1);
|
|
1786
1818
|
}
|
|
1787
1819
|
this.localStorage.setItem(`${this.props.dialogName || 'App'}.objectExpanded`, JSON.stringify(expanded));
|
|
1788
|
-
|
|
1820
|
+
if (pos === -1) {
|
|
1821
|
+
// the children are rendered after this update: let them slide out from under the row
|
|
1822
|
+
this.setState({ expanded }, () => {
|
|
1823
|
+
this.rowAnimations = rowAnimation.unfold(this.tableRef.current, id);
|
|
1824
|
+
});
|
|
1825
|
+
return;
|
|
1826
|
+
}
|
|
1827
|
+
const animations = rowAnimation.fold(this.tableRef.current, id, () => this.applyFold());
|
|
1828
|
+
if (animations) {
|
|
1829
|
+
// the children slide under the row first and are removed when the animation ends
|
|
1830
|
+
this.rowAnimations = animations;
|
|
1831
|
+
this.foldingId = id;
|
|
1832
|
+
// a hidden tab does not run animations: fold anyway
|
|
1833
|
+
this.foldTimer = setTimeout(() => this.applyFold(), 600);
|
|
1834
|
+
}
|
|
1835
|
+
else {
|
|
1836
|
+
this.setState({ expanded });
|
|
1837
|
+
}
|
|
1838
|
+
}
|
|
1839
|
+
/** The fold animation ended (or is cut short): remove the children of the node now */
|
|
1840
|
+
applyFold() {
|
|
1841
|
+
const id = this.foldingId;
|
|
1842
|
+
if (id === null) {
|
|
1843
|
+
return;
|
|
1844
|
+
}
|
|
1845
|
+
this.foldingId = null;
|
|
1846
|
+
if (this.foldTimer) {
|
|
1847
|
+
clearTimeout(this.foldTimer);
|
|
1848
|
+
this.foldTimer = null;
|
|
1849
|
+
}
|
|
1850
|
+
const animations = this.rowAnimations;
|
|
1851
|
+
this.rowAnimations = [];
|
|
1852
|
+
// the animations hold the rows in their end position until the children are really gone
|
|
1853
|
+
this.setState(state => ({ expanded: state.expanded.filter(item => item !== id) }), () => animations.forEach(animation => animation.cancel()));
|
|
1854
|
+
}
|
|
1855
|
+
/** Ends a running fold or unfold animation at once */
|
|
1856
|
+
finishRowAnimations() {
|
|
1857
|
+
if (this.foldingId !== null) {
|
|
1858
|
+
this.applyFold();
|
|
1859
|
+
}
|
|
1860
|
+
else {
|
|
1861
|
+
this.rowAnimations.forEach(animation => animation.cancel());
|
|
1862
|
+
this.rowAnimations = [];
|
|
1863
|
+
}
|
|
1789
1864
|
}
|
|
1790
1865
|
onCopy(e, text) {
|
|
1791
1866
|
e.stopPropagation();
|
|
@@ -2832,6 +2907,59 @@ export class ObjectBrowserClass extends Component {
|
|
|
2832
2907
|
.newValueBrowser-light {
|
|
2833
2908
|
animation: newValueAnimation-light 2s ease-in-out;
|
|
2834
2909
|
}
|
|
2910
|
+
.iob-ob-trend {
|
|
2911
|
+
display: inline-flex;
|
|
2912
|
+
align-self: center;
|
|
2913
|
+
flex-shrink: 0;
|
|
2914
|
+
width: 0.85em;
|
|
2915
|
+
height: 0.85em;
|
|
2916
|
+
margin-left: 4px;
|
|
2917
|
+
opacity: 0;
|
|
2918
|
+
animation: iob-ob-trend-up ${TREND_DURATION}ms ease-out forwards;
|
|
2919
|
+
}
|
|
2920
|
+
.iob-ob-trend svg {
|
|
2921
|
+
width: 100%;
|
|
2922
|
+
height: 100%;
|
|
2923
|
+
fill: currentColor;
|
|
2924
|
+
}
|
|
2925
|
+
.iob-ob-trend-up {
|
|
2926
|
+
color: ${this.props.themeType === 'dark' ? '#66bb6a' : '#2e7d32'};
|
|
2927
|
+
}
|
|
2928
|
+
.iob-ob-trend-down {
|
|
2929
|
+
color: ${this.props.themeType === 'dark' ? '#ef5350' : '#c62828'};
|
|
2930
|
+
animation-name: iob-ob-trend-down;
|
|
2931
|
+
}
|
|
2932
|
+
@keyframes iob-ob-trend-up {
|
|
2933
|
+
0% { opacity: 0; transform: translateY(45%); }
|
|
2934
|
+
12% { opacity: 1; transform: none; }
|
|
2935
|
+
80% { opacity: 1; }
|
|
2936
|
+
100% { opacity: 0; }
|
|
2937
|
+
}
|
|
2938
|
+
@keyframes iob-ob-trend-down {
|
|
2939
|
+
0% { opacity: 0; transform: translateY(-45%); }
|
|
2940
|
+
12% { opacity: 1; transform: none; }
|
|
2941
|
+
80% { opacity: 1; }
|
|
2942
|
+
100% { opacity: 0; }
|
|
2943
|
+
}
|
|
2944
|
+
.newValueBrowser-dark.iob-ob-flip {
|
|
2945
|
+
animation: iob-ob-flip 0.32s cubic-bezier(0.3, 1.4, 0.5, 1), newValueAnimation-dark 2s ease-in-out;
|
|
2946
|
+
}
|
|
2947
|
+
.newValueBrowser-light.iob-ob-flip {
|
|
2948
|
+
animation: iob-ob-flip 0.32s cubic-bezier(0.3, 1.4, 0.5, 1), newValueAnimation-light 2s ease-in-out;
|
|
2949
|
+
}
|
|
2950
|
+
@keyframes iob-ob-flip {
|
|
2951
|
+
0% { transform: perspective(60px) rotateX(90deg); opacity: 0.3; }
|
|
2952
|
+
100% { transform: none; opacity: 1; }
|
|
2953
|
+
}
|
|
2954
|
+
@media (prefers-reduced-motion: reduce) {
|
|
2955
|
+
.iob-ob-trend { animation-name: iob-ob-trend-fade; }
|
|
2956
|
+
.newValueBrowser-dark.iob-ob-flip { animation: newValueAnimation-dark 2s ease-in-out; }
|
|
2957
|
+
.newValueBrowser-light.iob-ob-flip { animation: newValueAnimation-light 2s ease-in-out; }
|
|
2958
|
+
@keyframes iob-ob-trend-fade {
|
|
2959
|
+
0%, 80% { opacity: 1; }
|
|
2960
|
+
100% { opacity: 0; }
|
|
2961
|
+
}
|
|
2962
|
+
}
|
|
2835
2963
|
.highlight-link .iob-link {
|
|
2836
2964
|
text-decoration: underline;
|
|
2837
2965
|
cursor: pointer;
|