@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.
@@ -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
- // this style is used for simple div. Do not migrate it to "secondary.main"
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: 'inline-block',
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: 100,
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(object: Record<string, any>, iteratee: (result: Record<string, any>, value: any, key: string) => void): Record<string, any> {
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) && _result.push(data.id);
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 css style for given state value
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 (e) {
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 (e) {
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 (e) {
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 && this.visibleCols.splice(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 (e) {
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 (e) {
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 (error) {
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 (e) {
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
- props.setObjectsReference && props.setObjectsReference(this.objects);
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 && 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
- this.props.onSelect && this.props.onSelect(this.state.selected, name, isDouble);
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 && 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
- this.filterTimer && clearTimeout(this.filterTimer);
3095
- this.filterTimer = null;
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
- this.props.onObjectDelete && this.props.onObjectDelete(id, !!item.children?.length, !obj.common?.dontDelete, count + 1);
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
- cb && cb();
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
- cb && cb();
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
- cb && cb();
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]) && this.unsubscribe(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
- newState && this.setState(newState);
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
- newInnerState && this.setState(newInnerState);
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 && this.props.socket.subscribeState(id, this.onStateChange);
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
- this.filterTimer && clearTimeout(this.filterTimer);
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
- this.filterTimer && clearTimeout(this.filterTimer);
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
- this.root && this.expandDepth(this.root, depth, expanded);
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
- enums && (await this._createAllEnums(enums, obj._id));
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
- this.props.onObjectDelete && this.props.onObjectDelete(id, !!item.children?.length, false, count + 1);
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 && this.props.onObjectDelete(
5058
- id,
5059
- !!item.children?.length,
5060
- !item.data.obj?.common?.dontDelete,
5061
- count,
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 && valFullRx.push(<br key={`${_item.t}_br`} />);
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 && valFullRx.push(<br key={`${_item.t}_br`} />);
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) && this.recordStates.push(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) && this.recordStates.push(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 className={`newValueBrowser-${this.props.themeType || 'light'}`} key={`${valText.v.toString()}valText`}>
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
- style={styles.cellValueTextUnit}
5260
- key={`${valText.v.toString()}unit`}
5261
- >
5262
- {valText.u}
5263
- </span>);
5264
- valText.s !== undefined && valTextRx.push(<span
5265
- style={styles.cellValueTextState}
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
- !narrowStyleWithDetails && valTextRx.push(<IconCopy
5274
- className="copyButton"
5275
- style={this.styles.iconCopy}
5276
- onClick={e => this.onCopy(e, copyText)}
5277
- key="cc"
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 && item.data.button) {
5288
- val = [<PressButtonIcon style={styles.cellValueButton} />];
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={{ ...styles.cellValueText, height: narrowStyleWithDetails ? undefined : ROW_HEIGHT }}
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
- cb && cb();
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
- obj.user && newValueTitle.push(`${this.texts.objectChangedBy} ${obj.user.replace(/^system\.user\./, '')}`);
5894
- obj.ts &&
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) && this.recordStates.push(_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
- !this.recordStates.includes(_id) && this.recordStates.push(_id);
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 : undefined,
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 && items.push(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
- root.children && items.push(root.children.map(item => {
6592
- // do not render too many items in column editor mode
6593
- if (!this.state.columnsSelectorShow || counter.count < 15) {
6594
- if (item.data.sumVisibility) {
6595
- return this.renderItem(item, undefined, counter);
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
- return null;
6599
- }) as any as React.JSX.Element);
6600
- } else {
6707
+ return null;
6708
+ }) as any as React.JSX.Element);
6709
+ }
6710
+ } else if (root.children) {
6601
6711
  // first only folder
6602
- root.children && items.push(root.children.map(item => {
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
- root.children && items.push(root.children.map(item => {
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
- this.resizeTimeout && clearTimeout(this.resizeTimeout);
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
- node.scrollIntoView({
7194
- behavior: 'auto',
7195
- block: 'center',
7196
- inline: 'center',
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
- this.state.showContextMenu && this.setState({ showContextMenu: { item: this.state.showContextMenu.item } });
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 && 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
- res && this.onUpdate(res);
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
- this.unsubscribeTimer && clearTimeout(this.unsubscribeTimer);
7900
+ if (this.unsubscribeTimer) {
7901
+ clearTimeout(this.unsubscribeTimer);
7902
+ }
7786
7903
 
7787
7904
  if (this.styleTheme !== this.props.themeType) {
7788
7905
  this.styles = {