@iobroker/adapter-react-v5 7.2.2 → 7.2.4

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.
@@ -38,7 +38,7 @@ const styles = {
38
38
  periodSelect: {
39
39
  // margin: '0 10px 60px 10px',
40
40
  display: 'block',
41
- width: 200,
41
+ width: 250,
42
42
  },
43
43
  slider: {
44
44
  marginTop: 20,
@@ -400,9 +400,9 @@ class ComplexCron extends react_1.Component {
400
400
  const everyMinute = this.state.minutes === '*' || this.state.minutes === '*/1';
401
401
  const everySecond = this.state.seconds === '*' || this.state.seconds === '*/1';
402
402
  return (react_1.default.createElement("div", { style: styles.mainDiv },
403
- react_1.default.createElement("div", { style: { paddingLeft: 8, width: '100%' } },
403
+ react_1.default.createElement("div", { style: { paddingLeft: 8, width: 'calc(100% - px)' } },
404
404
  react_1.default.createElement(material_1.TextField, { variant: "standard", style: { width: '100%' }, value: this.state.cron, disabled: true })),
405
- react_1.default.createElement("div", { style: { paddingLeft: 8, width: '100%', height: 60 } },
405
+ react_1.default.createElement("div", { style: { paddingLeft: 8, width: 'calc(100% - px)', height: 60 } },
406
406
  ComplexCron.convertCronToText(this.state.cron, this.props.language || 'en'),
407
407
  react_1.default.createElement("span", { style: styles.warning }, everySecond
408
408
  ? i18n_1.default.t('ra_warning_every_second')
@@ -4,7 +4,7 @@
4
4
  * MIT License
5
5
  *
6
6
  */
7
- import React, { Component } from 'react';
7
+ import React, { Component, type JSX } from 'react';
8
8
  import type { Connection } from '@iobroker/socket-client';
9
9
  import type { ThemeName, ThemeType, Translate, IobTheme } from '../types';
10
10
  export interface MetaACL extends ioBroker.ObjectACL {
@@ -69,7 +69,7 @@ export interface FileBrowserProps {
69
69
  /** Padding in pixels for folder levels */
70
70
  levelPadding?: number;
71
71
  restrictToFolder?: string;
72
- modalEditOfAccessControl?: (obj: FileBrowserClass) => React.JSX.Element | null;
72
+ modalEditOfAccessControl?: (obj: FileBrowserClass) => JSX.Element | null;
73
73
  allowNonRestricted?: boolean;
74
74
  showTypeSelector?: boolean;
75
75
  }
@@ -145,38 +145,38 @@ export declare class FileBrowserClass extends Component<FileBrowserProps, FileBr
145
145
  readDirSerial(adapter: string, relPath: string): Promise<ioBroker.ReadDirResult[]>;
146
146
  processBrowseList(level?: number): void;
147
147
  browseFolder(folderId: string, _newFolders?: Folders | null, _checkEmpty?: boolean, force?: boolean): Promise<Folders>;
148
- toggleFolder(item: FolderOrFileItem, e: React.MouseEvent<Element>): void;
148
+ toggleFolder(item: FolderOrFileItem, e: React.MouseEvent): void;
149
149
  onFileChange: (id: string, fileName: string, size: number | null) => void;
150
150
  changeFolder(e: React.MouseEvent<HTMLDivElement>, folder?: string): void;
151
151
  select(id: string, e?: React.MouseEvent<HTMLDivElement> | null, cb?: () => void): void;
152
152
  getText(text?: ioBroker.StringOrTranslated | null): string | undefined;
153
- renderFolder(item: FolderOrFileItem, expanded?: boolean): React.JSX.Element | null;
154
- renderBackFolder(): React.JSX.Element;
155
- formatSize(size: number | null | undefined): React.JSX.Element;
156
- formatAcl(acl: ioBroker.EvaluatedFileACL | MetaACL | undefined): React.JSX.Element;
157
- getFileIcon(ext: string | null): React.JSX.Element;
153
+ renderFolder(item: FolderOrFileItem, expanded?: boolean): JSX.Element | null;
154
+ renderBackFolder(): JSX.Element;
155
+ formatSize(size: number | null | undefined): JSX.Element;
156
+ formatAcl(acl: ioBroker.EvaluatedFileACL | MetaACL | undefined): JSX.Element;
157
+ getFileIcon(ext: string | null): JSX.Element;
158
158
  static getEditFile(ext: string | null): boolean;
159
159
  setStateBackgroundImage: () => void;
160
160
  getStyleBackgroundImage: () => React.CSSProperties | null;
161
- renderFile(item: FolderOrFileItem): React.JSX.Element;
162
- renderItems(folderId: string): React.JSX.Element | (React.JSX.Element | null)[];
163
- renderToolbar(): React.JSX.Element;
161
+ renderFile(item: FolderOrFileItem): JSX.Element;
162
+ renderItems(folderId: string): JSX.Element | (JSX.Element | null)[];
163
+ renderToolbar(): JSX.Element;
164
164
  findItem(id: string, folders?: Folders | null): null | FolderOrFileItem;
165
- renderInputDialog(): React.JSX.Element | null;
165
+ renderInputDialog(): JSX.Element | null;
166
166
  componentDidUpdate(): void;
167
167
  findFirstFolder(id: string): string | null;
168
168
  uploadFile(fileName: string, data: string): Promise<void>;
169
- renderUpload(): React.JSX.Element[] | null;
169
+ renderUpload(): JSX.Element[] | null;
170
170
  deleteRecursive(id: string): Promise<void>;
171
171
  deleteItem(deleteItem: string): void;
172
- renderDeleteDialog(): React.JSX.Element | null;
173
- renderViewDialog(): React.JSX.Element | null;
174
- renderError(): React.JSX.Element | null;
172
+ renderDeleteDialog(): JSX.Element | null;
173
+ renderViewDialog(): JSX.Element | null;
174
+ renderError(): JSX.Element | null;
175
175
  updateItemsAcl(info: FolderOrFileItem[]): void;
176
176
  changeToPath(): void;
177
- renderBreadcrumb(): React.JSX.Element;
178
- renderPath(): React.JSX.Element;
179
- render(): React.JSX.Element;
177
+ renderBreadcrumb(): JSX.Element;
178
+ renderPath(): JSX.Element;
179
+ render(): JSX.Element;
180
180
  }
181
- declare const _default: (props: Record<string, any>) => React.JSX.Element;
181
+ declare const _default: (props: Record<string, any>) => JSX.Element;
182
182
  export default _default;
@@ -63,9 +63,6 @@ const FILE_TYPE_ICONS = {
63
63
  video: icons_material_1.Videocam,
64
64
  };
65
65
  const styles = {
66
- dialog: (theme) => ({
67
- height: `calc(100% - ${theme.mixins.toolbar.minHeight}px)`,
68
- }),
69
66
  root: {
70
67
  width: '100%',
71
68
  overflow: 'hidden',
@@ -107,7 +104,8 @@ const styles = {
107
104
  textAlign: 'center',
108
105
  opacity: 0.1,
109
106
  transition: 'opacity 1s',
110
- margin: 4,
107
+ margin: '4px',
108
+ borderRadius: '4px',
111
109
  '&:hover': {
112
110
  background: theme.palette.secondary.light,
113
111
  color: Utils_1.default.invertColor(theme.palette.secondary.main, true),
@@ -228,8 +226,8 @@ const styles = {
228
226
  opacity: 0.4,
229
227
  },
230
228
  itemFolderIconTable: (theme) => ({
231
- marginTop: 1,
232
- marginLeft: 8,
229
+ marginTop: '1px',
230
+ marginLeft: '8px',
233
231
  display: 'inline-block',
234
232
  width: 30,
235
233
  height: 30,
@@ -362,6 +360,9 @@ const styles = {
362
360
  background: theme.palette.primary.main,
363
361
  },
364
362
  }),
363
+ pathDivBreadcrumbSelected: {
364
+ // todo: add style
365
+ },
365
366
  backgroundImageLight: {
366
367
  background: 'white',
367
368
  },
@@ -838,7 +839,19 @@ class FileBrowserClass extends react_1.Component {
838
839
  const adapter = parts.shift();
839
840
  const relPath = parts.join('/');
840
841
  // make all requests here serial
841
- const files = await this.readDirSerial(adapter || '', relPath);
842
+ let files;
843
+ try {
844
+ files = await this.readDirSerial(adapter || '', relPath);
845
+ }
846
+ catch (error) {
847
+ // work around: 0_userdata.0 is a special folder, that should exist event when other folders and itself do not exit, as the browser shows it anyway.
848
+ if (error === 'Not exists' && adapter === '0_userdata.0') {
849
+ files = [];
850
+ }
851
+ else {
852
+ throw error;
853
+ }
854
+ }
842
855
  try {
843
856
  const _folders = [];
844
857
  files.forEach(file => {
@@ -922,9 +935,7 @@ class FileBrowserClass extends react_1.Component {
922
935
  }
923
936
  }
924
937
  changeFolder(e, folder) {
925
- if (e) {
926
- e.stopPropagation();
927
- }
938
+ e === null || e === void 0 ? void 0 : e.stopPropagation();
928
939
  this.lastSelect = Date.now();
929
940
  let _folder = folder || getParentDir(this.state.currentDir);
930
941
  if (_folder === '/') {
@@ -932,8 +943,10 @@ class FileBrowserClass extends react_1.Component {
932
943
  }
933
944
  this.localStorage.setItem('files.currentDir', _folder);
934
945
  if (folder && e && (e.altKey || e.shiftKey || e.ctrlKey || e.metaKey)) {
935
- return this.setState({ selected: _folder });
946
+ this.setState({ selected: _folder });
947
+ return;
936
948
  }
949
+ // If desired folder is not yet loaded
937
950
  if (_folder && !this.state.folders[_folder]) {
938
951
  this.browseFolder(_folder)
939
952
  .then(folders => this.setState({
@@ -946,7 +959,7 @@ class FileBrowserClass extends react_1.Component {
946
959
  .catch(_e => console.error(`Cannot read folder: ${_e.message}`));
947
960
  return;
948
961
  }
949
- return this.setState({
962
+ this.setState({
950
963
  currentDir: _folder,
951
964
  selected: _folder,
952
965
  path: _folder,
@@ -997,10 +1010,9 @@ class FileBrowserClass extends react_1.Component {
997
1010
  const padding = this.state.viewType === TABLE ? item.level * this.levelPadding : 0;
998
1011
  const isUserData = item.name === USER_DATA;
999
1012
  const isSpecialData = isUserData || item.name === 'vis.0' || item.name === 'vis-2.0';
1013
+ const iconStyle = Utils_1.default.getStyle(this.props.theme, styles[`itemFolderIcon${this.state.viewType}`], isSpecialData && styles.specialFolder);
1000
1014
  return (react_1.default.createElement(material_1.Box, { component: "div", key: item.id, id: item.id, style: this.state.viewType === TABLE ? { marginLeft: padding, width: `calc(100% - ${padding}px` } : {}, onClick: e => (this.state.viewType === TABLE ? this.select(item.id, e) : this.changeFolder(e, item.id)), onDoubleClick: e => this.state.viewType === TABLE && this.toggleFolder(item, e), title: this.getText(item.title), className: "browserItem", sx: Utils_1.default.getStyle(this.props.theme, styles[`item${this.state.viewType}`], styles[`itemFolder${this.state.viewType}`], this.state.selected === item.id ? styles.itemSelected : {}, item.temp ? styles.itemFolderTemp : {}) },
1001
- react_1.default.createElement(IconEl, { style: Utils_1.default.getStyle(this.props.theme, styles[`itemFolderIcon${this.state.viewType}`], isSpecialData && styles.specialFolder), onClick: this.state.viewType === TABLE
1002
- ? (e) => this.toggleFolder(item, e)
1003
- : undefined }),
1015
+ react_1.default.createElement(IconEl, { style: iconStyle, onClick: this.state.viewType === TABLE ? (e) => this.toggleFolder(item, e) : undefined }),
1004
1016
  react_1.default.createElement(material_1.Box, { component: "div", sx: Utils_1.default.getStyle(this.props.theme, styles[`itemName${this.state.viewType}`], styles[`itemNameFolder${this.state.viewType}`]) }, isUserData ? this.props.t('ra_User files') : item.name),
1005
1017
  react_1.default.createElement(material_1.Box, { component: "div", style: styles[`itemSize${this.state.viewType}`], sx: { display: { md: 'inline-block', sm: 'none' } } }, this.state.viewType === TABLE && this.state.folders[item.id]
1006
1018
  ? this.state.folders[item.id].length
@@ -1024,7 +1036,7 @@ class FileBrowserClass extends react_1.Component {
1024
1036
  }
1025
1037
  renderBackFolder() {
1026
1038
  return (react_1.default.createElement(material_1.Box, { component: "div", key: this.state.currentDir, id: this.state.currentDir, onClick: e => this.changeFolder(e), title: this.props.t('ra_Back to %s', getParentDir(this.state.currentDir)), className: "browserItem", sx: Utils_1.default.getStyle(this.props.theme, styles[`item${this.state.viewType}`], styles[`itemFolder${this.state.viewType}`]) },
1027
- react_1.default.createElement(IconClosed_1.default, { style: styles[`itemFolderIcon${this.state.viewType}`] }),
1039
+ react_1.default.createElement(IconClosed_1.default, { style: Utils_1.default.getStyle(this.props.theme, styles[`itemFolderIcon${this.state.viewType}`]) }),
1028
1040
  react_1.default.createElement(icons_material_1.ArrowBack, { sx: styles.itemFolderIconBack }),
1029
1041
  react_1.default.createElement(material_1.Box, { component: "div", sx: Utils_1.default.getStyle(this.props.theme, styles[`itemName${this.state.viewType}`], styles[`itemNameFolder${this.state.viewType}`]) }, "..")));
1030
1042
  }
@@ -1,4 +1,4 @@
1
- import React from 'react';
1
+ import { type JSX } from 'react';
2
2
  export declare const EXTENSIONS: {
3
3
  images: string[];
4
4
  code: string[];
@@ -6,5 +6,5 @@ export declare const EXTENSIONS: {
6
6
  audio: string[];
7
7
  video: string[];
8
8
  };
9
- declare const _default: (props: Record<string, any>) => React.JSX.Element;
9
+ declare const _default: (props: Record<string, any>) => JSX.Element;
10
10
  export default _default;
@@ -571,6 +571,9 @@ export declare class ObjectBrowserClass extends Component<ObjectBrowserProps, Ob
571
571
  navigateKeyPress(event: React.KeyboardEvent): void;
572
572
  /**
573
573
  * Find the id from the root
574
+ *
575
+ * @param root The current root
576
+ * @param id The object id to find
574
577
  */
575
578
  private static getItemFromRoot;
576
579
  resizerReset: () => void;
@@ -871,10 +871,13 @@ function binarySearch(list, find, _start, _end) {
871
871
  return false;
872
872
  }
873
873
  function getName(name, lang) {
874
- if (name && typeof name === 'object') {
874
+ if (typeof name === 'object') {
875
+ if (!name) {
876
+ return '';
877
+ }
875
878
  return (name[lang] || name.en || '').toString();
876
879
  }
877
- return (name || '').toString();
880
+ return name ? name.toString() : '';
878
881
  }
879
882
  function getSelectIdIconFromObjects(objects, id, lang, imagePrefix) {
880
883
  // `admin` has prefix '.' and `web` has '../..'
@@ -3021,13 +3024,17 @@ class ObjectBrowserClass extends react_1.Component {
3021
3024
  }
3022
3025
  parseObjectForAdmins(columnsForAdmin, obj) {
3023
3026
  if (obj.common && obj.common.adminColumns && obj.common.name) {
3024
- let columns = obj.common.adminColumns;
3027
+ const columns = obj.common.adminColumns;
3028
+ let aColumns;
3025
3029
  if (columns && typeof columns !== 'object') {
3026
- columns = [columns];
3030
+ aColumns = [columns];
3031
+ }
3032
+ else if (columns) {
3033
+ aColumns = columns;
3027
3034
  }
3028
3035
  let cColumns;
3029
3036
  if (columns) {
3030
- cColumns = columns
3037
+ cColumns = aColumns
3031
3038
  .map((_item) => {
3032
3039
  if (typeof _item !== 'object') {
3033
3040
  return { path: _item, name: _item.split('.').pop() };
@@ -3063,7 +3070,7 @@ class ObjectBrowserClass extends react_1.Component {
3063
3070
  objTypes: item.objTypes,
3064
3071
  };
3065
3072
  })
3066
- .filter(item => item);
3073
+ .filter((item) => item);
3067
3074
  }
3068
3075
  else {
3069
3076
  cColumns = null;
@@ -5282,21 +5289,29 @@ class ObjectBrowserClass extends react_1.Component {
5282
5289
  }
5283
5290
  /**
5284
5291
  * Find the id from the root
5292
+ *
5293
+ * @param root The current root
5294
+ * @param id The object id to find
5285
5295
  */
5286
- static getItemFromRoot(
5287
- /** The current root */
5288
- root,
5289
- /** the object id to find */
5290
- id) {
5291
- var _b;
5296
+ static getItemFromRoot(root, id) {
5292
5297
  const idArr = id.split('.');
5293
5298
  let currId = '';
5294
5299
  let _root = root;
5295
- for (const idEntry of idArr) {
5300
+ for (let i = 0; i < idArr.length; i++) {
5301
+ const idEntry = idArr[i];
5296
5302
  currId = currId ? `${currId}.${idEntry}` : idEntry;
5297
- _root = (_b = _root.children) === null || _b === void 0 ? void 0 : _b.find(item => item.data.id === currId);
5298
- if (!_root) {
5299
- break;
5303
+ let found = false;
5304
+ if (_root.children) {
5305
+ for (let j = 0; j < _root.children.length; j++) {
5306
+ if (_root.children[j].data.id === currId) {
5307
+ _root = _root.children[j];
5308
+ found = true;
5309
+ break;
5310
+ }
5311
+ }
5312
+ }
5313
+ if (!found) {
5314
+ return null;
5300
5315
  }
5301
5316
  }
5302
5317
  return _root || null;
@@ -5662,7 +5677,6 @@ class ObjectBrowserClass extends react_1.Component {
5662
5677
  visibility: !!(!this.props.notEditable &&
5663
5678
  this.props.objectBrowserAliasEditor &&
5664
5679
  this.props.objectBrowserEditObject &&
5665
- this.state.filter.expertMode &&
5666
5680
  (obj === null || obj === void 0 ? void 0 : obj.type) === 'state' &&
5667
5681
  // @ts-expect-error deprecated from js-controller 6
5668
5682
  ((_e = obj.common) === null || _e === void 0 ? void 0 : _e.type) !== 'file'),
@@ -5765,7 +5779,7 @@ class ObjectBrowserClass extends react_1.Component {
5765
5779
  react_1.default.createElement(material_1.ListItemText, null,
5766
5780
  ITEMS[key].label,
5767
5781
  "..."),
5768
- react_1.default.createElement(material_1.ListItemSecondaryAction, null,
5782
+ react_1.default.createElement("div", { style: Object.assign(Object.assign({}, styles.contextMenuKeys), { opacity: 1 }) },
5769
5783
  react_1.default.createElement(icons_material_1.ArrowRight, null))));
5770
5784
  if (((_b = this.state.showContextMenu) === null || _b === void 0 ? void 0 : _b.subItem) === key) {
5771
5785
  items.push(react_1.default.createElement(material_1.Menu, { key: "subContextMenu", open: !0, anchorEl: this.state.showContextMenu.subAnchor, onClose: () => {
@@ -47,7 +47,7 @@ declare class Schedule extends Component<ScheduleProps, ScheduleState> {
47
47
  getTimeExactElements(): JSX.Element;
48
48
  static getDivider(): JSX.Element;
49
49
  getPeriodModes(): JSX.Element[];
50
- getPeriodSettingsMinutes(): JSX.Element;
50
+ getPeriodSettingsMinutes(fromTo: boolean): JSX.Element;
51
51
  getPeriodSettingsWeekdays(): JSX.Element[];
52
52
  getPeriodSettingsDaily(): JSX.Element[] | null;
53
53
  getPeriodSettingsWeekly(): JSX.Element[] | null;
@@ -526,7 +526,7 @@ class Schedule extends react_1.Component {
526
526
  desc.push(i18n_1.default.t('sch_desc_everyMinute'));
527
527
  }
528
528
  else {
529
- // every N minutes
529
+ // every N minute
530
530
  desc.push(i18n_1.default.t('sch_desc_everyNMinutes', schedule.time.interval.toString()));
531
531
  }
532
532
  }
@@ -535,7 +535,7 @@ class Schedule extends react_1.Component {
535
535
  desc.push(i18n_1.default.t('sch_desc_everyHour'));
536
536
  }
537
537
  else {
538
- // every N minutes
538
+ // every N minute
539
539
  desc.push(i18n_1.default.t('sch_desc_everyNHours', schedule.time.interval.toString()));
540
540
  }
541
541
  const start = ASTRO.indexOf(schedule.time.start) !== -1
@@ -600,7 +600,11 @@ class Schedule extends react_1.Component {
600
600
  this.onChange(_schedule);
601
601
  } }), label: !fromTo ? i18n_1.default.t('sch_fromTo') : '' }),
602
602
  fromTo && [
603
- react_1.default.createElement(material_1.TextField, { variant: "standard", style: Object.assign(Object.assign({}, styles.inputTime), { marginRight: 10 }), key: "exactTimeFrom", type: "time", value: this.state.schedule.time.start,
603
+ react_1.default.createElement(material_1.TextField, { variant: "standard", style: Object.assign(Object.assign({}, styles.inputTime), { marginRight: 10 }), key: "exactTimeFrom", type: "time", sx: (theme) => ({
604
+ '& input[type="time"]::-webkit-calendar-picker-indicator': {
605
+ filter: theme.palette.mode === 'dark' ? 'invert(80%)' : undefined,
606
+ },
607
+ }), value: this.state.schedule.time.start,
604
608
  // InputProps={{inputComponent: TextTime}}
605
609
  onChange: e => {
606
610
  const _schedule = JSON.parse(JSON.stringify(this.state.schedule));
@@ -609,7 +613,11 @@ class Schedule extends react_1.Component {
609
613
  }, slotProps: {
610
614
  inputLabel: { shrink: true },
611
615
  }, label: i18n_1.default.t('sch_from'), margin: "normal" }),
612
- react_1.default.createElement(material_1.TextField, { variant: "standard", style: styles.inputTime, key: "exactTimeTo", type: "time", value: this.state.schedule.time.end,
616
+ react_1.default.createElement(material_1.TextField, { variant: "standard", style: styles.inputTime, key: "exactTimeTo", type: "time", sx: (theme) => ({
617
+ '& input[type="time"]::-webkit-calendar-picker-indicator': {
618
+ filter: theme.palette.mode === 'dark' ? 'invert(80%)' : undefined,
619
+ },
620
+ }), value: this.state.schedule.time.end,
613
621
  // InputProps={{inputComponent: TextTime}}
614
622
  onChange: e => {
615
623
  const _schedule = JSON.parse(JSON.stringify(this.state.schedule));
@@ -640,7 +648,7 @@ class Schedule extends react_1.Component {
640
648
  _schedule.time.end = 'sunrise';
641
649
  this.onChange(_schedule);
642
650
  } }), label: i18n_1.default.t('sch_astroNight') })))),
643
- !schedule.time.exactTime && this.getPeriodSettingsMinutes())));
651
+ !schedule.time.exactTime && this.getPeriodSettingsMinutes(fromTo))));
644
652
  }
645
653
  getTimeExactElements() {
646
654
  const isAstro = ASTRO.includes(this.state.schedule.time.start);
@@ -659,13 +667,17 @@ class Schedule extends react_1.Component {
659
667
  react_1.default.createElement(material_1.MenuItem, { key: "specific", value: "00:00" }, i18n_1.default.t('sch_specificTime')),
660
668
  ASTRO.map(event => (react_1.default.createElement(material_1.MenuItem, { key: event, value: event }, i18n_1.default.t(`sch_astro_${event}`)))))),
661
669
  this.state.schedule.time.exactTime && !isAstro && (react_1.default.createElement("div", { style: styles.settingsDiv },
662
- react_1.default.createElement(material_1.TextField, { variant: "standard", style: styles.inputTime, key: "exactTimeValue", value: this.state.schedule.time.start, type: "time",
663
- // inputComponent={TextTime}
664
- onChange: e => {
670
+ react_1.default.createElement(material_1.TextField, { variant: "standard", style: styles.inputTime, key: "exactTimeValue", value: this.state.schedule.time.start, type: "time", sx: (theme) => ({
671
+ '& input[type="time"]::-webkit-calendar-picker-indicator': {
672
+ filter: theme.palette.mode === 'dark' ? 'invert(80%)' : undefined,
673
+ },
674
+ }), onChange: e => {
665
675
  const _schedule = JSON.parse(JSON.stringify(this.state.schedule));
666
676
  _schedule.time.start = e.target.value;
667
677
  this.onChange(_schedule);
668
- }, InputLabelProps: { shrink: true }, margin: "normal" })))));
678
+ }, slotProps: {
679
+ inputLabel: { shrink: true },
680
+ }, margin: "normal" })))));
669
681
  }
670
682
  static getDivider() {
671
683
  return react_1.default.createElement("hr", { style: styles.hr });
@@ -719,7 +731,9 @@ class Schedule extends react_1.Component {
719
731
  this.onChange(_schedule);
720
732
  }
721
733
  }, 1500, e.target.value);
722
- }, InputLabelProps: { shrink: true }, label: i18n_1.default.t('sch_at'), margin: "normal" })))),
734
+ }, slotProps: {
735
+ inputLabel: { shrink: true },
736
+ }, label: i18n_1.default.t('sch_at'), margin: "normal" })))),
723
737
  // ----- days ---
724
738
  react_1.default.createElement(material_1.Box, { component: "div", key: "days", sx: Utils_1.default.getStyle(this.props.theme, styles.rowDiv, styles.rowDays) },
725
739
  react_1.default.createElement("div", { style: styles.modeDiv },
@@ -854,9 +868,9 @@ class Schedule extends react_1.Component {
854
868
  MONTHS.map((month, i) => (react_1.default.createElement(material_1.MenuItem, { key: month, value: i + 1 }, i18n_1.default.t(month))))))))),
855
869
  ];
856
870
  }
857
- getPeriodSettingsMinutes() {
858
- return (react_1.default.createElement("div", { style: { display: 'inline-block' } },
859
- react_1.default.createElement("label", null, i18n_1.default.t('sch_every')),
871
+ getPeriodSettingsMinutes(fromTo) {
872
+ return (react_1.default.createElement("div", { style: { display: 'inline-block', marginTop: fromTo ? 15 : 'inherit' } },
873
+ react_1.default.createElement("label", { style: { marginLeft: 4, marginRight: 4 } }, i18n_1.default.t('sch_every')),
860
874
  react_1.default.createElement(material_1.Input, { value: this.state.schedule.time.interval, style: Object.assign(Object.assign({}, styles.inputEvery), { verticalAlign: 'bottom' }), type: "number", inputProps: { min: 1 }, onChange: e => {
861
875
  const _schedule = JSON.parse(JSON.stringify(this.state.schedule));
862
876
  _schedule.time.interval = parseInt(e.target.value, 10);
@@ -1218,7 +1232,9 @@ class Schedule extends react_1.Component {
1218
1232
  this.onChange(_schedule);
1219
1233
  }
1220
1234
  }, 1500, e.target.value);
1221
- }, InputLabelProps: { shrink: true }, margin: "normal" }),
1235
+ }, slotProps: {
1236
+ inputLabel: { shrink: true },
1237
+ }, margin: "normal" }),
1222
1238
  react_1.default.createElement(material_1.FormControlLabel, { control: react_1.default.createElement(material_1.Checkbox, { style: styles.inputRadio, checked: !!schedule.valid.to, onClick: () => {
1223
1239
  const _schedule = JSON.parse(JSON.stringify(this.state.schedule));
1224
1240
  _schedule.valid.to = _schedule.valid.to ? '' : Schedule.now2string(true);
@@ -1243,7 +1259,9 @@ class Schedule extends react_1.Component {
1243
1259
  this.onChange(_schedule);
1244
1260
  }
1245
1261
  }, 1500, e.target.value);
1246
- }, InputLabelProps: { shrink: true }, margin: "normal" })))));
1262
+ }, slotProps: {
1263
+ inputLabel: { shrink: true },
1264
+ }, margin: "normal" })))));
1247
1265
  }
1248
1266
  render() {
1249
1267
  return (react_1.default.createElement("div", { style: { height: 'calc(100% - 48px)', width: '100%', overflow: 'hidden' } },
@@ -36,7 +36,16 @@ const PERIODIC_TYPES = {
36
36
  minutes: 'minutes',
37
37
  // hours: 'hours',
38
38
  };
39
- const WEEKDAYS = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'];
39
+ const WEEKDAYS = [
40
+ 'ra_Sunday',
41
+ 'ra_Monday',
42
+ 'ra_Tuesday',
43
+ 'ra_Wednesday',
44
+ 'ra_Thursday',
45
+ 'ra_Friday',
46
+ 'ra_Saturday',
47
+ 'ra_Sunday',
48
+ ];
40
49
  function padding(num) {
41
50
  if (num < 10) {
42
51
  return `0${num}`;
@@ -281,6 +290,9 @@ class SimpleCron extends react_1.default.Component {
281
290
  const text = [];
282
291
  let start = null;
283
292
  let end = null;
293
+ if (!list.length) {
294
+ return '_';
295
+ }
284
296
  for (let i = 0; i < list.length; i++) {
285
297
  if (start === null) {
286
298
  start = list[i];
@@ -459,13 +471,21 @@ class SimpleCron extends react_1.default.Component {
459
471
  }
460
472
  getControlsWeekdaysElements(type) {
461
473
  const settings = type === 'intervalBetween' ? this.state.intervalBetween : this.state.specific;
462
- return (react_1.default.createElement("div", { key: "weekdays", style: { paddingLeft: 8, width: '100%', maxWidth: 600 } },
474
+ return (react_1.default.createElement("div", { key: "weekdays", style: { paddingLeft: 8, width: 'calc(100% - 8px)', maxWidth: 600 } },
463
475
  react_1.default.createElement("h5", null, i18n_1.default.t('ra_On weekdays')),
464
476
  [1, 2, 3, 4, 5, 6, 0].map(day => (react_1.default.createElement(material_1.FormControlLabel, { key: WEEKDAYS[day], control: react_1.default.createElement(material_1.Checkbox, { checked: settings.weekdays.includes(day), onChange: e => {
465
477
  const _settings = JSON.parse(JSON.stringify(this.state[type]));
466
478
  const pos = _settings.weekdays.indexOf(day);
467
- e.target.checked && pos === -1 && _settings.weekdays.push(day);
468
- !e.target.checked && pos !== -1 && _settings.weekdays.splice(pos, 1);
479
+ if (e.target.checked) {
480
+ if (pos === -1) {
481
+ _settings.weekdays.push(day);
482
+ }
483
+ }
484
+ else {
485
+ if (pos !== -1) {
486
+ _settings.weekdays.splice(pos, 1);
487
+ }
488
+ }
469
489
  _settings.weekdays.sort();
470
490
  if (type === 'intervalBetween') {
471
491
  this.setState({ intervalBetween: _settings }, () => this.recalcCron());
@@ -564,7 +584,11 @@ class SimpleCron extends react_1.default.Component {
564
584
  getControlsTime(type) {
565
585
  const settings = type === 'once' ? this.state.once : this.state.specific;
566
586
  return (react_1.default.createElement(material_1.FormControl, { variant: "standard", sx: Object.assign(Object.assign({}, styles.formControl), { '&.MuiFormControl-root': styles.formControlMarginRight }) },
567
- react_1.default.createElement(material_1.TextField, { variant: "standard", key: "at", label: i18n_1.default.t('sc_time'), value: settings.time, type: "time", onChange: e => {
587
+ react_1.default.createElement(material_1.TextField, { variant: "standard", key: "at", label: i18n_1.default.t('sc_time'), value: settings.time, type: "time", sx: (theme) => ({
588
+ '& input[type="time"]::-webkit-calendar-picker-indicator': {
589
+ filter: theme.palette.mode === 'dark' ? 'invert(80%)' : undefined,
590
+ },
591
+ }), onChange: e => {
568
592
  const _settings = JSON.parse(JSON.stringify(this.state[type]));
569
593
  _settings.time = e.target.value;
570
594
  if (type === 'once') {
@@ -655,9 +679,11 @@ class SimpleCron extends react_1.default.Component {
655
679
  }
656
680
  render() {
657
681
  return (react_1.default.createElement("div", { style: styles.mainDiv },
658
- react_1.default.createElement("div", { style: { paddingLeft: 8, width: '100%' } },
659
- react_1.default.createElement(material_1.TextField, { variant: "standard", style: { width: '100%' }, value: this.state.cron, disabled: true })),
660
- react_1.default.createElement("div", { style: { paddingLeft: 8, width: '100%', height: 60 } }, (0, cronText_1.default)(this.state.cron, this.props.language || 'en')),
682
+ react_1.default.createElement("div", { style: { paddingLeft: 8, width: 'calc(100% - 8px)' } },
683
+ react_1.default.createElement(material_1.TextField, { variant: "standard", style: { width: '100%' }, value: this.state.cron, disabled: true, error: this.state.cron.includes('_') })),
684
+ react_1.default.createElement("div", { style: { paddingLeft: 8, width: 'calc(100% - 8px)', height: 60 } }, this.state.cron.includes('_')
685
+ ? i18n_1.default.t('sc_invalid_cron')
686
+ : (0, cronText_1.default)(this.state.cron, this.props.language || 'en')),
661
687
  react_1.default.createElement("div", null,
662
688
  react_1.default.createElement(material_1.FormControl, { variant: "standard", style: Object.assign(Object.assign({}, styles.formControl), { marginLeft: 8, marginTop: 8 }) },
663
689
  react_1.default.createElement(material_1.InputLabel, null, i18n_1.default.t('ra_Repeat')),
@@ -44,7 +44,7 @@ class DialogSimpleCron extends react_1.default.Component {
44
44
  react_1.default.createElement(material_1.DialogContent, { style: { height: '100%', overflow: 'hidden' } },
45
45
  react_1.default.createElement(SimpleCron_1.default, { cronExpression: this.state.cron, onChange: cron => this.setState({ cron }), language: i18n_1.default.getLanguage() })),
46
46
  react_1.default.createElement(material_1.DialogActions, null,
47
- react_1.default.createElement(material_1.Button, { variant: "contained", onClick: () => this.handleOk(), color: "primary", startIcon: react_1.default.createElement(icons_material_1.Check, null) }, this.props.ok || i18n_1.default.t('ra_Ok')),
47
+ react_1.default.createElement(material_1.Button, { variant: "contained", disabled: !this.state.cron || this.state.cron.includes('_'), onClick: () => this.handleOk(), color: "primary", startIcon: react_1.default.createElement(icons_material_1.Check, null) }, this.props.ok || i18n_1.default.t('ra_Ok')),
48
48
  react_1.default.createElement(material_1.Button, { variant: "contained", onClick: () => this.handleCancel(), color: "grey", startIcon: react_1.default.createElement(icons_material_1.Cancel, null) }, this.props.cancel || i18n_1.default.t('ra_Cancel')))));
49
49
  }
50
50
  }
package/README.md CHANGED
@@ -13,7 +13,7 @@ If you want to create the configuration page with ReactJS:
13
13
  - Change `name` from `src` to `ADAPTERNAME-admin` (Of course replace `ADAPTERNAME` with yours)
14
14
  - Add to devDependencies:
15
15
  ```
16
- "@iobroker/adapter-react-v5": "^7.2.2",
16
+ "@iobroker/adapter-react-v5": "^7.2.4",
17
17
  ```
18
18
  Versions can be higher.
19
19
  So your `src/package.json` should look like:
@@ -24,7 +24,7 @@ If you want to create the configuration page with ReactJS:
24
24
  "version": "0.1.0",
25
25
  "private": true,
26
26
  "dependencies": {
27
- "@iobroker/adapter-react-v5": "^7.2.2",
27
+ "@iobroker/adapter-react-v5": "^7.2.4",
28
28
  "@iobroker/build-tools": "^1.0.0",
29
29
  "@iobroker/eslint-config": "^0.1.2",
30
30
  "@mui/material": "^6.0.2",
@@ -697,6 +697,11 @@ You can find the migration instructions:
697
697
  -->
698
698
 
699
699
  ## Changelog
700
+ ### 7.2.4 (2024-10-07)
701
+
702
+ - (@GermanBluefox) Corrected file browser
703
+ - (@GermanBluefox) Changed Open/Close Folder icons
704
+
700
705
  ### 7.2.2 (2024-10-04)
701
706
  - (@GermanBluefox) Small layout change for Icon Picker
702
707
 
package/i18n/de.json CHANGED
@@ -115,8 +115,8 @@
115
115
  "sc_to": "Bis",
116
116
  "sc_wizard": "Wizard",
117
117
  "sch_all": "alle",
118
- "sch_astroDay": "Astronomisch Tag",
119
- "sch_astroNight": "Astronomisch Nacht",
118
+ "sch_astroDay": "Astronomischer Tag",
119
+ "sch_astroNight": "Astronomische Nacht",
120
120
  "sch_astro_dawn": "Morgendämmerung",
121
121
  "sch_astro_dusk": "Abenddämmerung",
122
122
  "sch_astro_goldenHour": "Goldene Stunde",
@@ -435,5 +435,15 @@
435
435
  "ra_warning_every_second": "Achtung: Der CRON-Job wird im angegebenen Zeitraum jede Sekunde ausgeführt!",
436
436
  "ra_warning_every_minute": "Achtung: Der CRON-Job wird im angegebenen Zeitraum jede Minute ausgeführt!",
437
437
  "ra_The schedule will be executed every second. Are you sure?": "Der Zeitplan wird jede Sekunde ausgeführt. Sind Sie sicher?",
438
- "ra_The schedule will be executed every minute. Are you sure?": "Der Zeitplan wird jede Minute ausgeführt. Sind Sie sicher?"
439
- }
438
+ "ra_The schedule will be executed every minute. Are you sure?": "Der Zeitplan wird jede Minute ausgeführt. Sind Sie sicher?",
439
+ "sc_dow": "Tag",
440
+ "ra_Define CRON...": "Definieren Sie CRON ...",
441
+ "ra_Sunday": "Sonntag",
442
+ "ra_Monday": "Montag",
443
+ "ra_Tuesday": "Dienstag",
444
+ "ra_Wednesday": "Mittwoch",
445
+ "ra_Thursday": "Donnerstag",
446
+ "ra_Friday": "Freitag",
447
+ "ra_Saturday": "Samstag",
448
+ "sc_invalid_cron": "Ungültiger CRON"
449
+ }