@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
|
@@ -67,7 +67,6 @@ import {
|
|
|
67
67
|
PersonOutlined as IconUser,
|
|
68
68
|
Publish as PublishIcon,
|
|
69
69
|
Refresh as RefreshIcon,
|
|
70
|
-
RoomService as PressButtonIcon,
|
|
71
70
|
Router as IconHost,
|
|
72
71
|
Settings as IconConfig,
|
|
73
72
|
SettingsApplications as IconSystem,
|
|
@@ -201,6 +200,8 @@ export interface TreeItemData {
|
|
|
201
200
|
title?: string;
|
|
202
201
|
/** if the item has "write" button (value=true, ack=false) */
|
|
203
202
|
button?: boolean;
|
|
203
|
+
/** If the item has read and write and is boolean */
|
|
204
|
+
switch?: boolean;
|
|
204
205
|
/** if the item has custom settings in `common.custom` */
|
|
205
206
|
hasCustoms?: boolean;
|
|
206
207
|
/** If this item is visible */
|
|
@@ -457,7 +458,7 @@ const styles: Record<string, any> = {
|
|
|
457
458
|
// display: 'inline-block',
|
|
458
459
|
// verticalAlign: 'top',
|
|
459
460
|
},
|
|
460
|
-
//
|
|
461
|
+
// This style is used for simple div. Do not migrate it to "secondary.main"
|
|
461
462
|
cellIdIconFolder: (theme: IobTheme) => ({
|
|
462
463
|
marginRight: 8,
|
|
463
464
|
width: ROW_HEIGHT - 4,
|
|
@@ -600,9 +601,6 @@ const styles: Record<string, any> = {
|
|
|
600
601
|
},
|
|
601
602
|
cellValueButton: {
|
|
602
603
|
marginTop: 5,
|
|
603
|
-
'&:active': {
|
|
604
|
-
transform: 'scale(0.8)',
|
|
605
|
-
},
|
|
606
604
|
},
|
|
607
605
|
cellValueButtonFalse: {
|
|
608
606
|
opacity: 0.3,
|
|
@@ -618,7 +616,7 @@ const styles: Record<string, any> = {
|
|
|
618
616
|
width: '100%',
|
|
619
617
|
height: ROW_HEIGHT,
|
|
620
618
|
fontSize: 16,
|
|
621
|
-
display: '
|
|
619
|
+
display: 'flex',
|
|
622
620
|
overflow: 'hidden',
|
|
623
621
|
textOverflow: 'ellipsis',
|
|
624
622
|
position: 'relative',
|
|
@@ -665,6 +663,7 @@ const styles: Record<string, any> = {
|
|
|
665
663
|
cellValueTextUnit: {
|
|
666
664
|
marginLeft: 4,
|
|
667
665
|
opacity: 0.8,
|
|
666
|
+
display: 'inline-block',
|
|
668
667
|
},
|
|
669
668
|
cellValueTextState: {
|
|
670
669
|
opacity: 0.7,
|
|
@@ -739,7 +738,7 @@ const styles: Record<string, any> = {
|
|
|
739
738
|
cellDetailsName: {
|
|
740
739
|
fontWeight: 'bold',
|
|
741
740
|
marginRight: 8,
|
|
742
|
-
minWidth:
|
|
741
|
+
minWidth: 80,
|
|
743
742
|
},
|
|
744
743
|
|
|
745
744
|
filteredOut: {
|
|
@@ -962,6 +961,15 @@ const styles: Record<string, any> = {
|
|
|
962
961
|
},
|
|
963
962
|
};
|
|
964
963
|
|
|
964
|
+
function ButtonIcon(props?: { style?: React.CSSProperties }) {
|
|
965
|
+
return <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 436 436" style={props?.style} width="24" height="24" className="admin-button">
|
|
966
|
+
<g fill="currentColor">
|
|
967
|
+
<path d="m195.23077,24.30769c-36,3 -67,12 -96,26c-49,24 -82,61 -93,104l-3,11l-1,50c0,46 0,49 2,59l5,20c21,58 84,103 165,116c16,3 53,4 70,2c60,-6 111,-28 147,-64c21,-21 36,-49 40,-74a866,866 0 0 0 1,-104c-3,-18 -6,-28 -13,-43c-26,-52 -87,-90 -162,-101c-16,-2 -48,-3 -63,-2l1,0zm60,23c36,5 70,18 95,35c31,20 51,47 59,77c2,7 2,11 2,25c1,15 0,18 -2,26c-19,69 -104,117 -200,114c-47,-2 -90,-15 -124,-38c-31,-20 -51,-47 -59,-77c-3,-11 -4,-32 -2,-43c8,-42 41,-78 91,-101a260,260 0 0 1 140,-19l0,1zm-221,222c21,26 57,49 95,62c81,27 174,14 239,-32c14,-10 31,-27 41,-41c2,-2 2,-2 2,7c-1,23 -16,50 -38,72c-78,74 -233,74 -311,-1a121,121 0 0 1 -39,-76l0,-6l3,4l8,11z" />
|
|
968
|
+
<path d="m201.23077,47.30769c-40,3 -79,19 -104,44c-55,55 -38,133 37,171c52,26 122,24 172,-5c30,-17 51,-42 58,-71c3,-11 3,-34 0,-45c-6,-23 -21,-44 -40,-60l-27,-16a184,184 0 0 0 -96,-18zm30,21c56,5 100,35 112,75c4,11 4,30 0,41c-8,25 -26,45 -54,59a166,166 0 0 1 -160,-8a98,98 0 0 1 -41,-53c-5,-18 -2,-39 8,-57c23,-39 79,-62 135,-57z" />
|
|
969
|
+
</g>
|
|
970
|
+
</svg>;
|
|
971
|
+
}
|
|
972
|
+
|
|
965
973
|
/**
|
|
966
974
|
* Function that walks through all keys of an object or array and applies a function to each key.
|
|
967
975
|
*/
|
|
@@ -972,10 +980,14 @@ function walkThroughArray(object: any[], iteratee: (result: any[], value: any, k
|
|
|
972
980
|
}
|
|
973
981
|
return copiedObject;
|
|
974
982
|
}
|
|
983
|
+
|
|
975
984
|
/**
|
|
976
985
|
* Function that walks through all keys of an object or array and applies a function to each key.
|
|
977
986
|
*/
|
|
978
|
-
function walkThroughObject(
|
|
987
|
+
function walkThroughObject(
|
|
988
|
+
object: Record<string, any>,
|
|
989
|
+
iteratee: (result: Record<string, any>, value: any, key: string) => void
|
|
990
|
+
): Record<string, any> {
|
|
979
991
|
const copiedObject: Record<string, any> = {};
|
|
980
992
|
for (const key in object) {
|
|
981
993
|
if (Object.prototype.hasOwnProperty.call(object, key)) {
|
|
@@ -1397,7 +1409,9 @@ function getVisibleItems(
|
|
|
1397
1409
|
_result = _result || [];
|
|
1398
1410
|
const data = item.data;
|
|
1399
1411
|
if (data.sumVisibility) {
|
|
1400
|
-
data.id && objects[data.id] && (!type || objects[data.id].type === type)
|
|
1412
|
+
if (data.id && objects[data.id] && (!type || objects[data.id].type === type)) {
|
|
1413
|
+
_result.push(data.id);
|
|
1414
|
+
}
|
|
1401
1415
|
item.children?.forEach(_item =>
|
|
1402
1416
|
getVisibleItems(_item, type, objects, _result));
|
|
1403
1417
|
}
|
|
@@ -1618,6 +1632,8 @@ function buildTree(
|
|
|
1618
1632
|
typeof obj.common.role === 'string' &&
|
|
1619
1633
|
obj.common.role.startsWith('button') &&
|
|
1620
1634
|
obj.common?.write !== false,
|
|
1635
|
+
switch: obj.type === 'state' && obj.common?.type === 'boolean' &&
|
|
1636
|
+
obj.common?.write !== false && obj.common?.read !== false,
|
|
1621
1637
|
},
|
|
1622
1638
|
};
|
|
1623
1639
|
|
|
@@ -1997,7 +2013,7 @@ function formatValue(
|
|
|
1997
2013
|
}
|
|
1998
2014
|
|
|
1999
2015
|
/**
|
|
2000
|
-
* Get
|
|
2016
|
+
* Get CSS style for given state value
|
|
2001
2017
|
*/
|
|
2002
2018
|
function getValueStyle(options: GetValueStyleOptions): { color: string } {
|
|
2003
2019
|
const { state, isExpertMode, isButton } = options;
|
|
@@ -2599,7 +2615,7 @@ export class ObjectBrowserClass extends Component<ObjectBrowserProps, ObjectBrow
|
|
|
2599
2615
|
try {
|
|
2600
2616
|
const lastSelectedItems = JSON.parse(lastSelectedItemStr) as string[];
|
|
2601
2617
|
this.selectFirst = lastSelectedItems[0] || '';
|
|
2602
|
-
} catch
|
|
2618
|
+
} catch {
|
|
2603
2619
|
// ignore
|
|
2604
2620
|
}
|
|
2605
2621
|
} else {
|
|
@@ -2610,7 +2626,7 @@ export class ObjectBrowserClass extends Component<ObjectBrowserProps, ObjectBrow
|
|
|
2610
2626
|
const expandedStr = this.localStorage.getItem(`${props.dialogName || 'App'}.objectExpanded`) || '[]';
|
|
2611
2627
|
try {
|
|
2612
2628
|
expanded = JSON.parse(expandedStr);
|
|
2613
|
-
} catch
|
|
2629
|
+
} catch {
|
|
2614
2630
|
expanded = [];
|
|
2615
2631
|
}
|
|
2616
2632
|
|
|
@@ -2621,7 +2637,7 @@ export class ObjectBrowserClass extends Component<ObjectBrowserProps, ObjectBrow
|
|
|
2621
2637
|
if (filterStr) {
|
|
2622
2638
|
try {
|
|
2623
2639
|
filter = JSON.parse(filterStr);
|
|
2624
|
-
} catch
|
|
2640
|
+
} catch {
|
|
2625
2641
|
filter = { ...DEFAULT_FILTER };
|
|
2626
2642
|
}
|
|
2627
2643
|
} else if (props.defaultFilters && typeof props.defaultFilters === 'object') {
|
|
@@ -2643,7 +2659,9 @@ export class ObjectBrowserClass extends Component<ObjectBrowserProps, ObjectBrow
|
|
|
2643
2659
|
// remove type column if only one type must be selected
|
|
2644
2660
|
if (props.types && props.types.length === 1) {
|
|
2645
2661
|
const pos = this.visibleCols.indexOf('type');
|
|
2646
|
-
pos !== -1
|
|
2662
|
+
if (pos !== -1) {
|
|
2663
|
+
this.visibleCols.splice(pos, 1);
|
|
2664
|
+
}
|
|
2647
2665
|
}
|
|
2648
2666
|
|
|
2649
2667
|
this.possibleCols = SCREEN_WIDTHS.xl.fields;
|
|
@@ -2672,14 +2690,14 @@ export class ObjectBrowserClass extends Component<ObjectBrowserProps, ObjectBrow
|
|
|
2672
2690
|
let columns: string[] | null;
|
|
2673
2691
|
try {
|
|
2674
2692
|
columns = columnsStr ? JSON.parse(columnsStr) : null;
|
|
2675
|
-
} catch
|
|
2693
|
+
} catch {
|
|
2676
2694
|
columns = null;
|
|
2677
2695
|
}
|
|
2678
2696
|
|
|
2679
2697
|
let columnsWidths = null; // this.localStorage.getItem(`${props.dialogName || 'App'}.columnsWidths`);
|
|
2680
2698
|
try {
|
|
2681
2699
|
columnsWidths = columnsWidths ? JSON.parse(columnsWidths) : {};
|
|
2682
|
-
} catch
|
|
2700
|
+
} catch {
|
|
2683
2701
|
columnsWidths = {};
|
|
2684
2702
|
}
|
|
2685
2703
|
|
|
@@ -2700,7 +2718,7 @@ export class ObjectBrowserClass extends Component<ObjectBrowserProps, ObjectBrow
|
|
|
2700
2718
|
statesView = this.props.objectStatesView
|
|
2701
2719
|
? JSON.parse(this.localStorage.getItem(`${props.dialogName || 'App'}.objectStatesView`) || '') || false
|
|
2702
2720
|
: false;
|
|
2703
|
-
} catch
|
|
2721
|
+
} catch {
|
|
2704
2722
|
// ignore
|
|
2705
2723
|
}
|
|
2706
2724
|
|
|
@@ -2824,7 +2842,7 @@ export class ObjectBrowserClass extends Component<ObjectBrowserProps, ObjectBrow
|
|
|
2824
2842
|
});
|
|
2825
2843
|
|
|
2826
2844
|
this.customWidth = true;
|
|
2827
|
-
} catch
|
|
2845
|
+
} catch {
|
|
2828
2846
|
// ignore
|
|
2829
2847
|
}
|
|
2830
2848
|
}
|
|
@@ -2935,7 +2953,9 @@ export class ObjectBrowserClass extends Component<ObjectBrowserProps, ObjectBrow
|
|
|
2935
2953
|
this.objects = objects;
|
|
2936
2954
|
}
|
|
2937
2955
|
|
|
2938
|
-
|
|
2956
|
+
if (props.setObjectsReference) {
|
|
2957
|
+
props.setObjectsReference(this.objects);
|
|
2958
|
+
}
|
|
2939
2959
|
|
|
2940
2960
|
// read default history
|
|
2941
2961
|
this.defaultHistory = this.systemConfig.common.defaultHistory;
|
|
@@ -3024,8 +3044,8 @@ export class ObjectBrowserClass extends Component<ObjectBrowserProps, ObjectBrow
|
|
|
3024
3044
|
expanded.sort();
|
|
3025
3045
|
this.localStorage.setItem(`${this.props.dialogName || 'App'}.objectExpanded`, JSON.stringify(expanded));
|
|
3026
3046
|
this.setState({ expanded }, cb);
|
|
3027
|
-
} else {
|
|
3028
|
-
cb
|
|
3047
|
+
} else if (cb) {
|
|
3048
|
+
cb();
|
|
3029
3049
|
}
|
|
3030
3050
|
}
|
|
3031
3051
|
|
|
@@ -3047,15 +3067,17 @@ export class ObjectBrowserClass extends Component<ObjectBrowserProps, ObjectBrow
|
|
|
3047
3067
|
if (this.state.selected.length === 1 && this.objects[this.state.selected[0]]) {
|
|
3048
3068
|
const name =
|
|
3049
3069
|
Utils.getObjectName(this.objects, this.state.selected[0], null, { language: this.props.lang });
|
|
3050
|
-
|
|
3070
|
+
if (this.props.onSelect) {
|
|
3071
|
+
this.props.onSelect(this.state.selected, name, isDouble);
|
|
3072
|
+
}
|
|
3051
3073
|
}
|
|
3052
3074
|
} else {
|
|
3053
3075
|
this.localStorage.removeItem(`${this.props.dialogName || 'App'}.objectSelected`);
|
|
3054
3076
|
|
|
3055
3077
|
if (this.state.selected.length) {
|
|
3056
3078
|
this.setState({ selected: [] }, () => this.props.onSelect && this.props.onSelect([], ''));
|
|
3057
|
-
} else {
|
|
3058
|
-
this.props.onSelect
|
|
3079
|
+
} else if (this.props.onSelect) {
|
|
3080
|
+
this.props.onSelect([], '');
|
|
3059
3081
|
}
|
|
3060
3082
|
}
|
|
3061
3083
|
}
|
|
@@ -3091,8 +3113,10 @@ export class ObjectBrowserClass extends Component<ObjectBrowserProps, ObjectBrow
|
|
|
3091
3113
|
* Called when component is unmounted.
|
|
3092
3114
|
*/
|
|
3093
3115
|
componentWillUnmount() {
|
|
3094
|
-
|
|
3095
|
-
|
|
3116
|
+
if (this.filterTimer) {
|
|
3117
|
+
clearTimeout(this.filterTimer);
|
|
3118
|
+
this.filterTimer = null;
|
|
3119
|
+
}
|
|
3096
3120
|
window.removeEventListener('contextmenu', this.onContextMenu, true);
|
|
3097
3121
|
|
|
3098
3122
|
if (this.props.objectsWorker) {
|
|
@@ -3130,7 +3154,9 @@ export class ObjectBrowserClass extends Component<ObjectBrowserProps, ObjectBrow
|
|
|
3130
3154
|
}
|
|
3131
3155
|
}
|
|
3132
3156
|
|
|
3133
|
-
|
|
3157
|
+
if (this.props.onObjectDelete) {
|
|
3158
|
+
this.props.onObjectDelete(id, !!item.children?.length, !obj.common?.dontDelete, count + 1);
|
|
3159
|
+
}
|
|
3134
3160
|
}
|
|
3135
3161
|
|
|
3136
3162
|
/**
|
|
@@ -3222,7 +3248,9 @@ export class ObjectBrowserClass extends Component<ObjectBrowserProps, ObjectBrow
|
|
|
3222
3248
|
if (this.state.selected[0] !== toggleItem) {
|
|
3223
3249
|
this.setState({ selected: [toggleItem], selectedNonObject: '', focused: toggleItem }, () => {
|
|
3224
3250
|
this.onAfterSelect(isDouble);
|
|
3225
|
-
|
|
3251
|
+
if (cb) {
|
|
3252
|
+
cb();
|
|
3253
|
+
}
|
|
3226
3254
|
});
|
|
3227
3255
|
} else if (isDouble && this.props.onSelect) {
|
|
3228
3256
|
this.onAfterSelect(isDouble);
|
|
@@ -3231,7 +3259,9 @@ export class ObjectBrowserClass extends Component<ObjectBrowserProps, ObjectBrow
|
|
|
3231
3259
|
this.localStorage.setItem(`${this.props.dialogName || 'App'}.selectedNonObject`, toggleItem);
|
|
3232
3260
|
this.setState({ selected: [], selectedNonObject: toggleItem, focused: toggleItem }, () => {
|
|
3233
3261
|
this.onAfterSelect();
|
|
3234
|
-
|
|
3262
|
+
if (cb) {
|
|
3263
|
+
cb();
|
|
3264
|
+
}
|
|
3235
3265
|
});
|
|
3236
3266
|
}
|
|
3237
3267
|
} else if (
|
|
@@ -3251,7 +3281,9 @@ export class ObjectBrowserClass extends Component<ObjectBrowserProps, ObjectBrow
|
|
|
3251
3281
|
|
|
3252
3282
|
this.setState({ selected, selectedNonObject: '', focused: toggleItem }, () => {
|
|
3253
3283
|
this.onAfterSelect(isDouble);
|
|
3254
|
-
|
|
3284
|
+
if (cb) {
|
|
3285
|
+
cb();
|
|
3286
|
+
}
|
|
3255
3287
|
});
|
|
3256
3288
|
}
|
|
3257
3289
|
}
|
|
@@ -3512,7 +3544,9 @@ export class ObjectBrowserClass extends Component<ObjectBrowserProps, ObjectBrow
|
|
|
3512
3544
|
private checkUnsubscribes() {
|
|
3513
3545
|
// Remove unused subscriptions
|
|
3514
3546
|
for (let i = this.subscribes.length - 1; i >= 0; i--) {
|
|
3515
|
-
!this.recordStates.includes(this.subscribes[i])
|
|
3547
|
+
if (!this.recordStates.includes(this.subscribes[i])) {
|
|
3548
|
+
this.unsubscribe(this.subscribes[i]);
|
|
3549
|
+
}
|
|
3516
3550
|
}
|
|
3517
3551
|
this.recordStates = [];
|
|
3518
3552
|
}
|
|
@@ -3659,7 +3693,9 @@ export class ObjectBrowserClass extends Component<ObjectBrowserProps, ObjectBrow
|
|
|
3659
3693
|
}
|
|
3660
3694
|
});
|
|
3661
3695
|
|
|
3662
|
-
|
|
3696
|
+
if (newState) {
|
|
3697
|
+
this.setState(newState);
|
|
3698
|
+
}
|
|
3663
3699
|
this.afterObjectUpdated();
|
|
3664
3700
|
}
|
|
3665
3701
|
};
|
|
@@ -3670,7 +3706,9 @@ export class ObjectBrowserClass extends Component<ObjectBrowserProps, ObjectBrow
|
|
|
3670
3706
|
return;
|
|
3671
3707
|
}
|
|
3672
3708
|
|
|
3673
|
-
|
|
3709
|
+
if (newInnerState) {
|
|
3710
|
+
this.setState(newInnerState);
|
|
3711
|
+
}
|
|
3674
3712
|
this.afterObjectUpdated();
|
|
3675
3713
|
};
|
|
3676
3714
|
|
|
@@ -3748,7 +3786,9 @@ export class ObjectBrowserClass extends Component<ObjectBrowserProps, ObjectBrow
|
|
|
3748
3786
|
if (!this.subscribes.includes(id)) {
|
|
3749
3787
|
this.subscribes.push(id);
|
|
3750
3788
|
console.log(`+ subscribe ${id}`);
|
|
3751
|
-
!this.pausedSubscribes
|
|
3789
|
+
if (!this.pausedSubscribes) {
|
|
3790
|
+
this.props.socket.subscribeState(id, this.onStateChange);
|
|
3791
|
+
}
|
|
3752
3792
|
}
|
|
3753
3793
|
}
|
|
3754
3794
|
|
|
@@ -3856,7 +3896,9 @@ export class ObjectBrowserClass extends Component<ObjectBrowserProps, ObjectBrow
|
|
|
3856
3896
|
placeholder={this.texts[`filter_${filterName}`]}
|
|
3857
3897
|
defaultValue={(this.state.filter as Record<string, string>)[filterName] || ''}
|
|
3858
3898
|
onChange={() => {
|
|
3859
|
-
|
|
3899
|
+
if (this.filterTimer) {
|
|
3900
|
+
clearTimeout(this.filterTimer);
|
|
3901
|
+
}
|
|
3860
3902
|
this.filterTimer = setTimeout(() => this.onFilter(), 400);
|
|
3861
3903
|
}}
|
|
3862
3904
|
autoComplete="off"
|
|
@@ -3895,7 +3937,9 @@ export class ObjectBrowserClass extends Component<ObjectBrowserProps, ObjectBrow
|
|
|
3895
3937
|
sx={styles.headerCellInput}
|
|
3896
3938
|
className="no-underline"
|
|
3897
3939
|
onChange={() => {
|
|
3898
|
-
|
|
3940
|
+
if (this.filterTimer) {
|
|
3941
|
+
clearTimeout(this.filterTimer);
|
|
3942
|
+
}
|
|
3899
3943
|
this.filterTimer = setTimeout(() => this.onFilter(), 400);
|
|
3900
3944
|
}}
|
|
3901
3945
|
defaultValue={(this.state.filter as Record<string, string>)[name] || ''}
|
|
@@ -4052,7 +4096,9 @@ export class ObjectBrowserClass extends Component<ObjectBrowserProps, ObjectBrow
|
|
|
4052
4096
|
if (this.state.depth < 9) {
|
|
4053
4097
|
const depth = this.state.depth + 1;
|
|
4054
4098
|
const expanded = [...this.state.expanded];
|
|
4055
|
-
|
|
4099
|
+
if (this.root) {
|
|
4100
|
+
this.expandDepth(this.root, depth, expanded);
|
|
4101
|
+
}
|
|
4056
4102
|
this.localStorage.setItem(`${this.props.dialogName || 'App'}.objectExpanded`, JSON.stringify(expanded));
|
|
4057
4103
|
this.setState({ depth, expanded });
|
|
4058
4104
|
}
|
|
@@ -4168,7 +4214,9 @@ export class ObjectBrowserClass extends Component<ObjectBrowserProps, ObjectBrow
|
|
|
4168
4214
|
}
|
|
4169
4215
|
try {
|
|
4170
4216
|
await this.props.socket.setObject(id, obj);
|
|
4171
|
-
|
|
4217
|
+
if (enums) {
|
|
4218
|
+
await this._createAllEnums(enums, obj._id);
|
|
4219
|
+
}
|
|
4172
4220
|
if (obj.type === 'state') {
|
|
4173
4221
|
if (val !== undefined && val !== null) {
|
|
4174
4222
|
try {
|
|
@@ -4972,7 +5020,9 @@ export class ObjectBrowserClass extends Component<ObjectBrowserProps, ObjectBrow
|
|
|
4972
5020
|
}
|
|
4973
5021
|
}
|
|
4974
5022
|
|
|
4975
|
-
|
|
5023
|
+
if (this.props.onObjectDelete) {
|
|
5024
|
+
this.props.onObjectDelete(id, !!item.children?.length, false, count + 1);
|
|
5025
|
+
}
|
|
4976
5026
|
}}
|
|
4977
5027
|
>
|
|
4978
5028
|
<IconDelete style={styles.cellButtonsButtonIcon} />
|
|
@@ -5054,12 +5104,14 @@ export class ObjectBrowserClass extends Component<ObjectBrowserProps, ObjectBrow
|
|
|
5054
5104
|
break;
|
|
5055
5105
|
}
|
|
5056
5106
|
}
|
|
5057
|
-
this.props.onObjectDelete
|
|
5058
|
-
|
|
5059
|
-
|
|
5060
|
-
|
|
5061
|
-
|
|
5062
|
-
|
|
5107
|
+
if (this.props.onObjectDelete) {
|
|
5108
|
+
this.props.onObjectDelete(
|
|
5109
|
+
id,
|
|
5110
|
+
!!item.children?.length,
|
|
5111
|
+
!item.data.obj?.common?.dontDelete,
|
|
5112
|
+
count,
|
|
5113
|
+
);
|
|
5114
|
+
}
|
|
5063
5115
|
}}
|
|
5064
5116
|
title={this.texts.deleteObject}
|
|
5065
5117
|
>
|
|
@@ -5174,7 +5226,9 @@ export class ObjectBrowserClass extends Component<ObjectBrowserProps, ObjectBrow
|
|
|
5174
5226
|
{_item.v}
|
|
5175
5227
|
</div>);
|
|
5176
5228
|
// <div style={styles.cellValueTooltipValue} key={item.t + '_v'}>{item.v}</div>,
|
|
5177
|
-
!_item.nbr
|
|
5229
|
+
if (!_item.nbr) {
|
|
5230
|
+
valFullRx.push(<br key={`${_item.t}_br`} />);
|
|
5231
|
+
}
|
|
5178
5232
|
} else {
|
|
5179
5233
|
valFullRx.push(<div style={styles.cellValueTooltipTitle} key={_item.t}>
|
|
5180
5234
|
{_item.t}
|
|
@@ -5183,7 +5237,9 @@ export class ObjectBrowserClass extends Component<ObjectBrowserProps, ObjectBrow
|
|
|
5183
5237
|
valFullRx.push(<div style={styles.cellValueTooltipValue} key={`${_item.t}_v`}>
|
|
5184
5238
|
{_item.v}
|
|
5185
5239
|
</div>);
|
|
5186
|
-
!_item.nbr
|
|
5240
|
+
if (!_item.nbr) {
|
|
5241
|
+
valFullRx.push(<br key={`${_item.t}_br`} />);
|
|
5242
|
+
}
|
|
5187
5243
|
}
|
|
5188
5244
|
});
|
|
5189
5245
|
|
|
@@ -5228,13 +5284,17 @@ export class ObjectBrowserClass extends Component<ObjectBrowserProps, ObjectBrow
|
|
|
5228
5284
|
if (!this.states[id]) {
|
|
5229
5285
|
if (obj.type === 'state') {
|
|
5230
5286
|
// we are waiting for state
|
|
5231
|
-
!this.recordStates.includes(id)
|
|
5287
|
+
if (!this.recordStates.includes(id)) {
|
|
5288
|
+
this.recordStates.push(id);
|
|
5289
|
+
}
|
|
5232
5290
|
this.states[id] = { val: null } as ioBroker.State;
|
|
5233
5291
|
this.subscribe(id);
|
|
5234
5292
|
}
|
|
5235
5293
|
return null;
|
|
5236
5294
|
}
|
|
5237
|
-
!this.recordStates.includes(id)
|
|
5295
|
+
if (!this.recordStates.includes(id)) {
|
|
5296
|
+
this.recordStates.push(id);
|
|
5297
|
+
}
|
|
5238
5298
|
|
|
5239
5299
|
const state = this.states[id];
|
|
5240
5300
|
|
|
@@ -5251,31 +5311,46 @@ export class ObjectBrowserClass extends Component<ObjectBrowserProps, ObjectBrow
|
|
|
5251
5311
|
item.data.state = { valTextRx };
|
|
5252
5312
|
|
|
5253
5313
|
const copyText = valText.v || '';
|
|
5254
|
-
valTextRx.push(<span
|
|
5255
|
-
{valText.v.toString()}
|
|
5256
|
-
</span>);
|
|
5257
|
-
valText.u && valTextRx.push(<span
|
|
5314
|
+
valTextRx.push(<span
|
|
5258
5315
|
className={`newValueBrowser-${this.props.themeType || 'light'}`}
|
|
5259
|
-
|
|
5260
|
-
|
|
5261
|
-
|
|
5262
|
-
|
|
5263
|
-
|
|
5264
|
-
|
|
5265
|
-
|
|
5266
|
-
className={`newValueBrowser-${this.props.themeType || 'light'}`}
|
|
5267
|
-
key={`${valText.v.toString()}states`}
|
|
5316
|
+
key={`${valText.v.toString()}valText`}
|
|
5317
|
+
style={{
|
|
5318
|
+
whiteSpace: 'nowrap',
|
|
5319
|
+
display: 'inline-block',
|
|
5320
|
+
overflow: 'hidden',
|
|
5321
|
+
textOverflow: 'ellipsis',
|
|
5322
|
+
}}
|
|
5268
5323
|
>
|
|
5269
|
-
(
|
|
5270
|
-
{valText.s}
|
|
5271
|
-
)
|
|
5324
|
+
{valText.v.toString()}
|
|
5272
5325
|
</span>);
|
|
5273
|
-
|
|
5274
|
-
|
|
5275
|
-
|
|
5276
|
-
|
|
5277
|
-
|
|
5278
|
-
|
|
5326
|
+
if (valText.u) {
|
|
5327
|
+
valTextRx.push(<span
|
|
5328
|
+
className={`newValueBrowser-${this.props.themeType || 'light'}`}
|
|
5329
|
+
style={styles.cellValueTextUnit}
|
|
5330
|
+
key={`${valText.v.toString()}unit`}
|
|
5331
|
+
>
|
|
5332
|
+
{valText.u}
|
|
5333
|
+
</span>);
|
|
5334
|
+
}
|
|
5335
|
+
if (valText.s !== undefined) {
|
|
5336
|
+
valTextRx.push(<span
|
|
5337
|
+
style={styles.cellValueTextState}
|
|
5338
|
+
className={`newValueBrowser-${this.props.themeType || 'light'}`}
|
|
5339
|
+
key={`${valText.v.toString()}states`}
|
|
5340
|
+
>
|
|
5341
|
+
(
|
|
5342
|
+
{valText.s}
|
|
5343
|
+
)
|
|
5344
|
+
</span>);
|
|
5345
|
+
}
|
|
5346
|
+
if (!narrowStyleWithDetails) {
|
|
5347
|
+
valTextRx.push(<IconCopy
|
|
5348
|
+
className="copyButton"
|
|
5349
|
+
style={this.styles.iconCopy}
|
|
5350
|
+
onClick={e => this.onCopy(e, copyText)}
|
|
5351
|
+
key="cc"
|
|
5352
|
+
/>);
|
|
5353
|
+
}
|
|
5279
5354
|
// <IconEdit className="copyButton" style={{{ ...styles.cellButtonsValueButton, styles.cellButtonsValueButtonEdit)} key="ce" />
|
|
5280
5355
|
|
|
5281
5356
|
info = item.data.state;
|
|
@@ -5284,8 +5359,20 @@ export class ObjectBrowserClass extends Component<ObjectBrowserProps, ObjectBrow
|
|
|
5284
5359
|
info.style = getValueStyle({ state, isExpertMode: this.state.filter.expertMode, isButton: item.data.button });
|
|
5285
5360
|
|
|
5286
5361
|
let val: React.JSX.Element[] = info.valTextRx as React.JSX.Element[];
|
|
5287
|
-
if (!this.state.filter.expertMode
|
|
5288
|
-
|
|
5362
|
+
if (!this.state.filter.expertMode) {
|
|
5363
|
+
if (item.data.button) {
|
|
5364
|
+
val = [<ButtonIcon key="button" style={{ color: info.style.color, ...styles.cellValueButton }} />];
|
|
5365
|
+
} else if (item.data.switch) {
|
|
5366
|
+
val = [<Switch
|
|
5367
|
+
key="switch"
|
|
5368
|
+
sx={{
|
|
5369
|
+
'& .MuiSwitch-thumb': { color: info.style.color },
|
|
5370
|
+
'& .MuiSwitch-track': !!this.states[id].val && this.state.selected.includes(id) ?
|
|
5371
|
+
{ backgroundColor: this.props.themeType === 'dark' ? '#FFF !important' : '#111 !important' } : undefined,
|
|
5372
|
+
}}
|
|
5373
|
+
checked={!!this.states[id].val}
|
|
5374
|
+
/>];
|
|
5375
|
+
}
|
|
5289
5376
|
}
|
|
5290
5377
|
|
|
5291
5378
|
return <Tooltip
|
|
@@ -5301,7 +5388,13 @@ export class ObjectBrowserClass extends Component<ObjectBrowserProps, ObjectBrow
|
|
|
5301
5388
|
<Box
|
|
5302
5389
|
component="div"
|
|
5303
5390
|
style={info.style}
|
|
5304
|
-
sx={{
|
|
5391
|
+
sx={{
|
|
5392
|
+
...styles.cellValueText,
|
|
5393
|
+
height: narrowStyleWithDetails ? undefined : ROW_HEIGHT,
|
|
5394
|
+
'& .admin-button:active': {
|
|
5395
|
+
transform: 'translate(0, 2px)',
|
|
5396
|
+
},
|
|
5397
|
+
}}
|
|
5305
5398
|
>
|
|
5306
5399
|
{val}
|
|
5307
5400
|
</Box>
|
|
@@ -5315,7 +5408,9 @@ export class ObjectBrowserClass extends Component<ObjectBrowserProps, ObjectBrow
|
|
|
5315
5408
|
cb: () => void,
|
|
5316
5409
|
): void {
|
|
5317
5410
|
if (!enumIds || !enumIds.length) {
|
|
5318
|
-
|
|
5411
|
+
if (cb) {
|
|
5412
|
+
cb();
|
|
5413
|
+
}
|
|
5319
5414
|
return;
|
|
5320
5415
|
}
|
|
5321
5416
|
const enumId = enumIds.pop() || '';
|
|
@@ -5324,7 +5419,7 @@ export class ObjectBrowserClass extends Component<ObjectBrowserProps, ObjectBrow
|
|
|
5324
5419
|
if (this.info.objects[enumId].common.members?.length) {
|
|
5325
5420
|
const pos = this.info.objects[enumId].common.members.indexOf(id);
|
|
5326
5421
|
if (pos !== -1 && !newArray.includes(enumId)) {
|
|
5327
|
-
// delete from members
|
|
5422
|
+
// delete it from members
|
|
5328
5423
|
const obj = JSON.parse(JSON.stringify(this.info.objects[enumId]));
|
|
5329
5424
|
obj.common.members.splice(pos, 1);
|
|
5330
5425
|
promises.push(
|
|
@@ -5886,15 +5981,19 @@ export class ObjectBrowserClass extends Component<ObjectBrowserProps, ObjectBrow
|
|
|
5886
5981
|
}
|
|
5887
5982
|
|
|
5888
5983
|
if (obj) {
|
|
5889
|
-
obj.from
|
|
5984
|
+
if (obj.from) {
|
|
5890
5985
|
newValueTitle.push(
|
|
5891
5986
|
`${this.texts.objectChangedFrom} ${obj.from.replace(/^system\.adapter\.|^system\./, '')}`,
|
|
5892
5987
|
);
|
|
5893
|
-
|
|
5894
|
-
obj.
|
|
5988
|
+
}
|
|
5989
|
+
if (obj.user) {
|
|
5990
|
+
newValueTitle.push(`${this.texts.objectChangedBy} ${obj.user.replace(/^system\.user\./, '')}`);
|
|
5991
|
+
}
|
|
5992
|
+
if (obj.ts) {
|
|
5895
5993
|
newValueTitle.push(
|
|
5896
5994
|
`${this.texts.objectChangedByUser} ${Utils.formatDate(new Date(obj.ts), this.props.dateFormat || this.systemConfig.common.dateFormat)}`,
|
|
5897
5995
|
);
|
|
5996
|
+
}
|
|
5898
5997
|
}
|
|
5899
5998
|
|
|
5900
5999
|
const readWriteAlias = typeof common?.alias?.id === 'object';
|
|
@@ -5995,12 +6094,14 @@ export class ObjectBrowserClass extends Component<ObjectBrowserProps, ObjectBrow
|
|
|
5995
6094
|
|
|
5996
6095
|
if (!this.states[_id]) {
|
|
5997
6096
|
if (this.objects[_id]?.type === 'state') {
|
|
5998
|
-
!this.recordStates.includes(_id)
|
|
6097
|
+
if (!this.recordStates.includes(_id)) {
|
|
6098
|
+
this.recordStates.push(_id);
|
|
6099
|
+
}
|
|
5999
6100
|
this.states[_id] = { val: null } as ioBroker.State;
|
|
6000
6101
|
this.subscribe(_id);
|
|
6001
6102
|
}
|
|
6002
|
-
} else {
|
|
6003
|
-
|
|
6103
|
+
} else if (!this.recordStates.includes(_id)) {
|
|
6104
|
+
this.recordStates.push(_id);
|
|
6004
6105
|
}
|
|
6005
6106
|
});
|
|
6006
6107
|
// calculate color
|
|
@@ -6365,7 +6466,7 @@ export class ObjectBrowserClass extends Component<ObjectBrowserProps, ObjectBrow
|
|
|
6365
6466
|
let colValue = (narrowStyleWithDetails && columnValue) || this.columnsVisibility.val ? <div
|
|
6366
6467
|
style={{
|
|
6367
6468
|
...styles.cellValue,
|
|
6368
|
-
width: this.props.width !== 'xs' ? this.columnsVisibility.val :
|
|
6469
|
+
width: this.props.width !== 'xs' ? this.columnsVisibility.val : 'calc(100% - 100px)',
|
|
6369
6470
|
cursor: valueEditable ? (common?.type === 'file' ? 'zoom-in' : (item.data.button ? 'grab' : 'text')) : 'default',
|
|
6370
6471
|
}}
|
|
6371
6472
|
onClick={valueEditable ? () => {
|
|
@@ -6379,6 +6480,11 @@ export class ObjectBrowserClass extends Component<ObjectBrowserProps, ObjectBrow
|
|
|
6379
6480
|
this.props.socket
|
|
6380
6481
|
.setState(id, true)
|
|
6381
6482
|
.catch(e => window.alert(`Cannot write state "${id}": ${e}`));
|
|
6483
|
+
} else if (!this.state.filter.expertMode && item.data.switch) {
|
|
6484
|
+
// in non-expert mode control switch directly
|
|
6485
|
+
this.props.socket
|
|
6486
|
+
.setState(id, !this.states[id].val)
|
|
6487
|
+
.catch(e => window.alert(`Cannot write state "${id}": ${e}`));
|
|
6382
6488
|
} else {
|
|
6383
6489
|
this.edit = {
|
|
6384
6490
|
val: this.states[id] ? this.states[id].val : '',
|
|
@@ -6579,7 +6685,9 @@ export class ObjectBrowserClass extends Component<ObjectBrowserProps, ObjectBrow
|
|
|
6579
6685
|
} else {
|
|
6580
6686
|
leaf = result.row;
|
|
6581
6687
|
}
|
|
6582
|
-
root.data.id && leaf
|
|
6688
|
+
if (root.data.id && leaf) {
|
|
6689
|
+
items.push(leaf);
|
|
6690
|
+
}
|
|
6583
6691
|
if (result.details) {
|
|
6584
6692
|
items.push(result.details);
|
|
6585
6693
|
}
|
|
@@ -6588,18 +6696,20 @@ export class ObjectBrowserClass extends Component<ObjectBrowserProps, ObjectBrow
|
|
|
6588
6696
|
|
|
6589
6697
|
if (!root.data.id || isExpanded) {
|
|
6590
6698
|
if (!this.state.foldersFirst) {
|
|
6591
|
-
|
|
6592
|
-
|
|
6593
|
-
|
|
6594
|
-
if (
|
|
6595
|
-
|
|
6699
|
+
if (root.children) {
|
|
6700
|
+
items.push(root.children.map(item => {
|
|
6701
|
+
// do not render too many items in column editor mode
|
|
6702
|
+
if (!this.state.columnsSelectorShow || counter.count < 15) {
|
|
6703
|
+
if (item.data.sumVisibility) {
|
|
6704
|
+
return this.renderItem(item, undefined, counter);
|
|
6705
|
+
}
|
|
6596
6706
|
}
|
|
6597
|
-
|
|
6598
|
-
|
|
6599
|
-
}
|
|
6600
|
-
} else {
|
|
6707
|
+
return null;
|
|
6708
|
+
}) as any as React.JSX.Element);
|
|
6709
|
+
}
|
|
6710
|
+
} else if (root.children) {
|
|
6601
6711
|
// first only folder
|
|
6602
|
-
|
|
6712
|
+
items.push(root.children.map(item => {
|
|
6603
6713
|
if (item.children) {
|
|
6604
6714
|
// do not render too many items in column editor mode
|
|
6605
6715
|
if (!this.state.columnsSelectorShow || counter.count < 15) {
|
|
@@ -6613,7 +6723,7 @@ export class ObjectBrowserClass extends Component<ObjectBrowserProps, ObjectBrow
|
|
|
6613
6723
|
}) as any as React.JSX.Element);
|
|
6614
6724
|
|
|
6615
6725
|
// then items
|
|
6616
|
-
|
|
6726
|
+
items.push(root.children.map(item => {
|
|
6617
6727
|
if (!item.children) {
|
|
6618
6728
|
// do not render too many items in column editor mode
|
|
6619
6729
|
if (!this.state.columnsSelectorShow || counter.count < 15) {
|
|
@@ -6839,7 +6949,9 @@ export class ObjectBrowserClass extends Component<ObjectBrowserProps, ObjectBrow
|
|
|
6839
6949
|
this.resizerCurrentWidths.name = width - this.state.scrollBarWidth;
|
|
6840
6950
|
}
|
|
6841
6951
|
this.customWidth = true;
|
|
6842
|
-
|
|
6952
|
+
if (this.resizeTimeout) {
|
|
6953
|
+
clearTimeout(this.resizeTimeout);
|
|
6954
|
+
}
|
|
6843
6955
|
this.resizeTimeout = setTimeout(() => {
|
|
6844
6956
|
this.resizeTimeout = null;
|
|
6845
6957
|
this.forceUpdate();
|
|
@@ -7189,12 +7301,11 @@ export class ObjectBrowserClass extends Component<ObjectBrowserProps, ObjectBrow
|
|
|
7189
7301
|
this.selectFirst = '';
|
|
7190
7302
|
|
|
7191
7303
|
const node = window.document.getElementById(id);
|
|
7192
|
-
node
|
|
7193
|
-
|
|
7194
|
-
|
|
7195
|
-
|
|
7196
|
-
|
|
7197
|
-
});
|
|
7304
|
+
node?.scrollIntoView({
|
|
7305
|
+
behavior: 'auto',
|
|
7306
|
+
block: 'center',
|
|
7307
|
+
inline: 'center',
|
|
7308
|
+
});
|
|
7198
7309
|
}
|
|
7199
7310
|
|
|
7200
7311
|
private renderCustomDialog(): React.JSX.Element | null {
|
|
@@ -7665,7 +7776,9 @@ export class ObjectBrowserClass extends Component<ObjectBrowserProps, ObjectBrow
|
|
|
7665
7776
|
open={!0}
|
|
7666
7777
|
anchorEl={this.state.showContextMenu.subAnchor}
|
|
7667
7778
|
onClose={() => {
|
|
7668
|
-
|
|
7779
|
+
if (this.state.showContextMenu) {
|
|
7780
|
+
this.setState({ showContextMenu: { item: this.state.showContextMenu.item } });
|
|
7781
|
+
}
|
|
7669
7782
|
this.contextMenu = null;
|
|
7670
7783
|
}}
|
|
7671
7784
|
>
|
|
@@ -7715,8 +7828,8 @@ export class ObjectBrowserClass extends Component<ObjectBrowserProps, ObjectBrow
|
|
|
7715
7828
|
e.preventDefault();
|
|
7716
7829
|
if (e.altKey) {
|
|
7717
7830
|
Object.keys(ITEMS).forEach(key => {
|
|
7718
|
-
if (e.key === ITEMS[key].key) {
|
|
7719
|
-
ITEMS[key].onClick
|
|
7831
|
+
if (e.key === ITEMS[key].key && ITEMS[key].onClick) {
|
|
7832
|
+
ITEMS[key].onClick();
|
|
7720
7833
|
}
|
|
7721
7834
|
});
|
|
7722
7835
|
}
|
|
@@ -7771,7 +7884,9 @@ export class ObjectBrowserClass extends Component<ObjectBrowserProps, ObjectBrow
|
|
|
7771
7884
|
isFloatComma={this.props.isFloatComma === undefined ? this.systemConfig.common.isFloatComma : this.props.isFloatComma}
|
|
7772
7885
|
onClose={(res?: { val: ioBroker.StateValue; ack: boolean; q: ioBroker.STATE_QUALITY[keyof ioBroker.STATE_QUALITY]; expire: number | undefined }) => {
|
|
7773
7886
|
this.setState({ updateOpened: false });
|
|
7774
|
-
|
|
7887
|
+
if (res) {
|
|
7888
|
+
this.onUpdate(res);
|
|
7889
|
+
}
|
|
7775
7890
|
}}
|
|
7776
7891
|
width={this.props.width}
|
|
7777
7892
|
/>;
|
|
@@ -7782,7 +7897,9 @@ export class ObjectBrowserClass extends Component<ObjectBrowserProps, ObjectBrow
|
|
|
7782
7897
|
*/
|
|
7783
7898
|
render(): React.JSX.Element {
|
|
7784
7899
|
this.recordStates = [];
|
|
7785
|
-
|
|
7900
|
+
if (this.unsubscribeTimer) {
|
|
7901
|
+
clearTimeout(this.unsubscribeTimer);
|
|
7902
|
+
}
|
|
7786
7903
|
|
|
7787
7904
|
if (this.styleTheme !== this.props.themeType) {
|
|
7788
7905
|
this.styles = {
|