@iobroker/adapter-react-v5 6.1.9 → 6.1.10
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/Components/FileBrowser.js +24 -19
- package/Components/FileViewer.js +14 -5
- package/Components/ObjectBrowser.d.ts +2 -0
- package/Components/ObjectBrowser.js +185 -86
- package/README.md +15 -18
- package/package.json +7 -7
- package/src/Components/FileBrowser.tsx +48 -28
- package/src/Components/FileViewer.tsx +14 -5
- package/src/Components/ObjectBrowser.tsx +224 -107
package/README.md
CHANGED
|
@@ -744,40 +744,34 @@ The best practice is to replace `padding` with `p` and `margin` with `m`, so you
|
|
|
744
744
|
|
|
745
745
|
- Modify `classes`:
|
|
746
746
|
Before: `<Dialog classes={{ scrollPaper: this.props.classes.dialog, paper: this.props.classes.paper }}>`
|
|
747
|
-
|
|
748
|
-
After: `<Dialog sx={{ '&.MuiDialog-scrollPaper': styles.dialog, '& .MuiDialog-paper': styles.paper }}>`
|
|
747
|
+
After: `<Dialog sx={{ '&.MuiDialog-scrollPaper': styles.dialog, '& .MuiDialog-paper': styles.paper }}>`,
|
|
749
748
|
|
|
750
749
|
Before: `<Dialog classes={{ scrollPaper: this.props.classes.dialog, paper: this.props.classes.paper }}>`
|
|
751
|
-
|
|
752
750
|
After: `<Dialog sx={{ '&.MuiDialog-scrollPaper': styles.dialog, '& .MuiDialog-paper': styles.paper }}>`
|
|
753
751
|
|
|
754
|
-
Before: `<ListItem classes={{ root:
|
|
755
|
-
|
|
752
|
+
Before: `<ListItem classes={{ root: this.props.classes.listItem }} >`,
|
|
756
753
|
After: `<ListItem sx={{ '&.MuiListItem-root': styles.listItem }} >`
|
|
757
754
|
|
|
758
|
-
Before: `<Typography component="h2" variant="h6" classes={{ root:
|
|
759
|
-
|
|
755
|
+
Before: `<Typography component="h2" variant="h6" classes={{ root: this.props.classes.typography }}>`,
|
|
760
756
|
After: `<Typography component="h2" variant="h6" sx={{ '&.MuiTypography-root': styles.typography }}>`
|
|
761
757
|
|
|
762
|
-
Before: `<Badge classes={{ 'badge':
|
|
763
|
-
|
|
758
|
+
Before: `<Badge classes={{ 'badge': this.props.classes.expertBadge }}>`,
|
|
764
759
|
After: `<Badge sx={{ '& .MuiBadge-badge': styles.expertBadge }}>`
|
|
765
760
|
|
|
766
|
-
Before: `<Tab classes={{ selected:
|
|
767
|
-
|
|
761
|
+
Before: `<Tab classes={{ selected: this.props.classes..selected }} />`,
|
|
768
762
|
After: `<Tab sx={{ '&.Mui-selected': styles.selected }} />`
|
|
769
763
|
|
|
770
|
-
Before: `<
|
|
771
|
-
|
|
772
|
-
After: `<Tooltip title={this.props.t('ra_Refresh tree')} componentsProps={{ popper: { sx: { pointerEvents: 'none' } } }}>`
|
|
773
|
-
Or: `<Tooltip title={this.props.t('ra_Refresh tree')} componentsProps={{ popper: { sx: styles.tooltip } }}>`
|
|
764
|
+
Before: `<Tabs classes={{ indicator: this.props.classes.indicator }} />`,
|
|
765
|
+
After: `<Tabs sx={{ '& .MuiTabs-indicator': styles.indicator }} />`
|
|
774
766
|
|
|
775
|
-
Before
|
|
767
|
+
Before: `<Tooltip title={this.props.t('ra_Refresh tree')} classes={{ popper: this.props.classes.tooltip }}>`,
|
|
768
|
+
After: `<Tooltip title={this.props.t('ra_Refresh tree')} componentsProps={{ popper: { sx: { pointerEvents: 'none' } } }}>`,
|
|
769
|
+
Or: `<Tooltip title={this.props.t('ra_Refresh tree')} componentsProps={{ popper: { sx: styles.tooltip } }}>`
|
|
776
770
|
|
|
771
|
+
Before. `<AccordionSummary classes={{ root: this.props.classes.rootStyle, content: this.props.classes.content }}>`,
|
|
777
772
|
After. `<AccordionSummary sx={{ '&.MuiAccordionSummary-root': styles.rootStyle, '& .MuiAccordionSummary-content': styles.content }}>`
|
|
778
773
|
|
|
779
|
-
Before. `<Drawer classes={{ paper:
|
|
780
|
-
|
|
774
|
+
Before. `<Drawer classes={{ paper: this.props.classes.paperStyle }}>`,
|
|
781
775
|
After. `<Drawer sx={{ '& .MuiDrawer-paper': styles.paperStyle }}>`
|
|
782
776
|
|
|
783
777
|
<!--
|
|
@@ -786,6 +780,9 @@ The best practice is to replace `padding` with `p` and `margin` with `m`, so you
|
|
|
786
780
|
-->
|
|
787
781
|
|
|
788
782
|
## Changelog
|
|
783
|
+
### 6.1.10 (2024-08-30)
|
|
784
|
+
* (bluefox) Updated the object browser
|
|
785
|
+
|
|
789
786
|
### 6.1.9 (2024-08-14)
|
|
790
787
|
* (bluefox) Updated JSON schema
|
|
791
788
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@iobroker/adapter-react-v5",
|
|
3
|
-
"version": "6.1.
|
|
3
|
+
"version": "6.1.10",
|
|
4
4
|
"description": "React classes to develop admin interfaces for ioBroker with react.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Denis Haev (bluefox)",
|
|
@@ -27,16 +27,16 @@
|
|
|
27
27
|
"homepage": "https://github.com/ioBroker/adapter-react-v5#readme",
|
|
28
28
|
"devDependencies": {},
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@emotion/react": "^11.13.
|
|
30
|
+
"@emotion/react": "^11.13.3",
|
|
31
31
|
"@emotion/styled": "^11.13.0",
|
|
32
32
|
"@iobroker/socket-client": "^2.4.18",
|
|
33
|
-
"@iobroker/types": "^6.0.
|
|
34
|
-
"@iobroker/js-controller-common": "^6.0.
|
|
35
|
-
"@iobroker/js-controller-common-db": "^6.0.
|
|
33
|
+
"@iobroker/types": "^6.0.11",
|
|
34
|
+
"@iobroker/js-controller-common": "^6.0.11",
|
|
35
|
+
"@iobroker/js-controller-common-db": "^6.0.11",
|
|
36
36
|
"@mui/icons-material": "^5.16.7",
|
|
37
37
|
"@mui/material": "^5.16.7",
|
|
38
|
-
"@mui/x-date-pickers": "^7.
|
|
39
|
-
"@sentry/browser": "^8.
|
|
38
|
+
"@mui/x-date-pickers": "^7.14.0",
|
|
39
|
+
"@sentry/browser": "^8.26.0",
|
|
40
40
|
"cronstrue": "^2.50.0",
|
|
41
41
|
"react-color": "^2.19.3",
|
|
42
42
|
"react-colorful": "^5.6.1",
|
|
@@ -9,7 +9,6 @@ import Dropzone from 'react-dropzone';
|
|
|
9
9
|
|
|
10
10
|
import {
|
|
11
11
|
LinearProgress,
|
|
12
|
-
Hidden,
|
|
13
12
|
ListItemIcon,
|
|
14
13
|
ListItemText,
|
|
15
14
|
Menu,
|
|
@@ -226,10 +225,10 @@ const styles: Record<string, any> = {
|
|
|
226
225
|
fontSize: '1rem',
|
|
227
226
|
verticalAlign: 'top',
|
|
228
227
|
flexGrow: 1,
|
|
228
|
+
textOverflow: 'ellipsis',
|
|
229
|
+
whiteSpace: 'nowrap',
|
|
230
|
+
overflow: 'hidden',
|
|
229
231
|
'@media screen and (max-width: 500px)': {
|
|
230
|
-
whiteSpace: 'nowrap',
|
|
231
|
-
overflow: 'hidden',
|
|
232
|
-
textOverflow: 'ellipsis',
|
|
233
232
|
textAlign: 'end',
|
|
234
233
|
direction: 'rtl',
|
|
235
234
|
},
|
|
@@ -433,7 +432,9 @@ const USER_DATA = '0_userdata.0';
|
|
|
433
432
|
|
|
434
433
|
function getParentDir(dir: string | null): string {
|
|
435
434
|
const parts = (dir || '').split('/');
|
|
436
|
-
parts.length
|
|
435
|
+
if (parts.length) {
|
|
436
|
+
parts.pop();
|
|
437
|
+
}
|
|
437
438
|
return parts.join('/');
|
|
438
439
|
}
|
|
439
440
|
|
|
@@ -637,7 +638,7 @@ export class FileBrowserClass extends Component<FileBrowserProps, FileBrowserSta
|
|
|
637
638
|
expanded = expanded.filter(id => id.startsWith(`${this.limitToPath}/`) ||
|
|
638
639
|
id === this.limitToPath || this.limitToPath?.startsWith(`${id}/`));
|
|
639
640
|
}
|
|
640
|
-
} catch
|
|
641
|
+
} catch {
|
|
641
642
|
expanded = [];
|
|
642
643
|
}
|
|
643
644
|
|
|
@@ -770,7 +771,7 @@ export class FileBrowserClass extends Component<FileBrowserProps, FileBrowserSta
|
|
|
770
771
|
scrollToSelected() {
|
|
771
772
|
if (this.mounted) {
|
|
772
773
|
const el = document.getElementById(this.state.selected);
|
|
773
|
-
el
|
|
774
|
+
el?.scrollIntoView();
|
|
774
775
|
}
|
|
775
776
|
}
|
|
776
777
|
|
|
@@ -780,7 +781,9 @@ export class FileBrowserClass extends Component<FileBrowserProps, FileBrowserSta
|
|
|
780
781
|
.catch(error => console.error(`Cannot load folders: ${error}`));
|
|
781
782
|
|
|
782
783
|
this.supportSubscribes = await this.props.socket.checkFeatureSupported('BINARY_STATE_EVENT');
|
|
783
|
-
|
|
784
|
+
if (this.supportSubscribes) {
|
|
785
|
+
await this.props.socket.subscribeFiles('*', '*', this.onFileChange);
|
|
786
|
+
}
|
|
784
787
|
}
|
|
785
788
|
|
|
786
789
|
componentWillUnmount() {
|
|
@@ -844,7 +847,9 @@ export class FileBrowserClass extends Component<FileBrowserProps, FileBrowserSta
|
|
|
844
847
|
adapter,
|
|
845
848
|
relPath,
|
|
846
849
|
});
|
|
847
|
-
!this.browseListRunning
|
|
850
|
+
if (!this.browseListRunning) {
|
|
851
|
+
this.processBrowseList();
|
|
852
|
+
}
|
|
848
853
|
}
|
|
849
854
|
});
|
|
850
855
|
}
|
|
@@ -1252,22 +1257,26 @@ export class FileBrowserClass extends Component<FileBrowserProps, FileBrowserSta
|
|
|
1252
1257
|
{isUserData ? this.props.t('ra_User files') : item.name}
|
|
1253
1258
|
</Box>
|
|
1254
1259
|
|
|
1255
|
-
<
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1260
|
+
<Box
|
|
1261
|
+
component="div"
|
|
1262
|
+
style={styles[`itemSize${this.state.viewType}`]}
|
|
1263
|
+
sx={{ display: { md: 'inline-block', sm: 'none' } }}
|
|
1264
|
+
>
|
|
1265
|
+
{this.state.viewType === TABLE && this.state.folders[item.id]
|
|
1266
|
+
? this.state.folders[item.id].length
|
|
1267
|
+
: ''}
|
|
1268
|
+
</Box>
|
|
1262
1269
|
|
|
1263
|
-
<
|
|
1270
|
+
<Box
|
|
1271
|
+
component="div"
|
|
1272
|
+
sx={{ display: { md: 'inline-block', sm: 'none' } }}
|
|
1273
|
+
>
|
|
1264
1274
|
{this.state.viewType === TABLE && this.props.expertMode ? this.formatAcl(item.acl) : null}
|
|
1265
|
-
</
|
|
1275
|
+
</Box>
|
|
1276
|
+
|
|
1277
|
+
{this.state.viewType === TABLE && this.props.expertMode ?
|
|
1278
|
+
<Box component="div" sx={{ ...styles.itemDeleteButtonTable, display: { md: 'inline-block', sm: 'none' } }} /> : null}
|
|
1266
1279
|
|
|
1267
|
-
<Hidden smDown>
|
|
1268
|
-
{this.state.viewType === TABLE && this.props.expertMode ?
|
|
1269
|
-
<Box component="div" sx={styles[`itemDeleteButton${this.state.viewType}`]} /> : null}
|
|
1270
|
-
</Hidden>
|
|
1271
1280
|
{this.state.viewType === TABLE && this.props.allowDownload ?
|
|
1272
1281
|
<div style={styles[`itemDownloadEmpty${this.state.viewType}`]} /> : null}
|
|
1273
1282
|
|
|
@@ -1482,11 +1491,22 @@ export class FileBrowserClass extends Component<FileBrowserProps, FileBrowserSta
|
|
|
1482
1491
|
:
|
|
1483
1492
|
this.getFileIcon(ext)}
|
|
1484
1493
|
<Box component="div" sx={styles[`itemName${this.state.viewType}`]}>{item.name}</Box>
|
|
1485
|
-
<
|
|
1486
|
-
|
|
1494
|
+
<Box
|
|
1495
|
+
component="div"
|
|
1496
|
+
sx={{ display: { md: 'inline-block', sm: 'none' } }}
|
|
1497
|
+
>
|
|
1498
|
+
{this.formatSize(item.size)}
|
|
1499
|
+
</Box>
|
|
1500
|
+
<Box
|
|
1501
|
+
component="div"
|
|
1502
|
+
sx={{ display: { md: 'inline-block', sm: 'none' } }}
|
|
1503
|
+
>
|
|
1487
1504
|
{this.state.viewType === TABLE && this.props.expertMode ? this.formatAcl(item.acl) : null}
|
|
1488
|
-
</
|
|
1489
|
-
<
|
|
1505
|
+
</Box>
|
|
1506
|
+
<Box
|
|
1507
|
+
component="div"
|
|
1508
|
+
sx={{ display: { md: 'inline-block', sm: 'none' } }}
|
|
1509
|
+
>
|
|
1490
1510
|
{this.state.viewType === TABLE && this.props.expertMode && FileBrowserClass.getEditFile(ext) ?
|
|
1491
1511
|
<IconButton
|
|
1492
1512
|
aria-label="edit"
|
|
@@ -1506,14 +1526,14 @@ export class FileBrowserClass extends Component<FileBrowserProps, FileBrowserSta
|
|
|
1506
1526
|
this.props.onSelect(item.id, true, !!this.state.folders[item.id]);
|
|
1507
1527
|
}
|
|
1508
1528
|
}}
|
|
1509
|
-
sx={styles
|
|
1529
|
+
sx={styles.itemDeleteButtonTable}
|
|
1510
1530
|
size="large"
|
|
1511
1531
|
>
|
|
1512
1532
|
<EditIcon fontSize="small" />
|
|
1513
1533
|
</IconButton>
|
|
1514
1534
|
:
|
|
1515
1535
|
<Box component="div" sx={styles[`itemDeleteButton${this.state.viewType}`]} />}
|
|
1516
|
-
</
|
|
1536
|
+
</Box>
|
|
1517
1537
|
{/* eslint-disable-next-line jsx-a11y/control-has-associated-label */}
|
|
1518
1538
|
{this.state.viewType === TABLE && this.props.allowDownload ? <Box
|
|
1519
1539
|
component="a"
|
|
@@ -148,7 +148,7 @@ class FileViewer extends Component<FileViewerProps, FileViewerState> {
|
|
|
148
148
|
newState.copyPossible = true;
|
|
149
149
|
try {
|
|
150
150
|
fileData = atob(bufferToBase64((data as { data: Buffer; type: string }).data, true));
|
|
151
|
-
} catch
|
|
151
|
+
} catch {
|
|
152
152
|
console.error('Cannot convert base64 to string');
|
|
153
153
|
fileData = '';
|
|
154
154
|
}
|
|
@@ -185,21 +185,30 @@ class FileViewer extends Component<FileViewerProps, FileViewerState> {
|
|
|
185
185
|
const adapter = parts[0];
|
|
186
186
|
const name = parts.splice(1).join('/');
|
|
187
187
|
|
|
188
|
-
this.props.supportSubscribes
|
|
188
|
+
if (this.props.supportSubscribes) {
|
|
189
|
+
this.props.socket.subscribeFiles(adapter, name, this.onFileChanged);
|
|
190
|
+
}
|
|
189
191
|
}
|
|
190
192
|
|
|
191
193
|
componentWillUnmount() {
|
|
192
|
-
|
|
194
|
+
if (this.timeout) {
|
|
195
|
+
clearTimeout(this.timeout);
|
|
196
|
+
this.timeout = null;
|
|
197
|
+
}
|
|
193
198
|
const parts = this.props.href.split('/');
|
|
194
199
|
parts.splice(0, 2);
|
|
195
200
|
const adapter = parts[0];
|
|
196
201
|
const name = parts.splice(1).join('/');
|
|
197
|
-
this.props.supportSubscribes
|
|
202
|
+
if (this.props.supportSubscribes) {
|
|
203
|
+
this.props.socket.subscribeFiles(adapter, name, this.onFileChanged);
|
|
204
|
+
}
|
|
198
205
|
}
|
|
199
206
|
|
|
200
207
|
onFileChanged = (id: string, fileName: string, size: number | null) => {
|
|
201
208
|
if (!this.state.changed) {
|
|
202
|
-
|
|
209
|
+
if (this.timeout) {
|
|
210
|
+
clearTimeout(this.timeout);
|
|
211
|
+
}
|
|
203
212
|
this.timeout = setTimeout(() => {
|
|
204
213
|
this.timeout = null;
|
|
205
214
|
if (size === null) {
|