@iobroker/adapter-react-v5 7.1.3 → 7.2.1

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.
@@ -1,57 +1,57 @@
1
- import React from 'react';
2
-
3
- import { Grid2, Paper } from '@mui/material';
4
-
5
- const styles: Record<string, React.CSSProperties> = {
6
- root: {
7
- width: '100%',
8
- height: '100%',
9
- },
10
- overflowHidden: {
11
- overflow: 'hidden',
12
- },
13
- container: {
14
- height: '100%',
15
- },
16
- };
17
-
18
- interface TabContainerProps {
19
- /* The elevation of the tab container. */
20
- elevation?: number;
21
- /* Set to 'visible' show the overflow. */
22
- overflow?: string;
23
- styles?: {
24
- root?: React.CSSProperties;
25
- container?: React.CSSProperties;
26
- };
27
- onKeyDown?: (event: React.KeyboardEvent<HTMLDivElement>) => void;
28
- tabIndex?: number;
29
- /** The content of the component. */
30
- children: React.ReactNode;
31
- }
32
-
33
- function TabContainer(props: TabContainerProps): React.JSX.Element {
34
- return (
35
- <Paper
36
- elevation={!Number.isNaN(props.elevation) ? props.elevation : 1}
37
- style={{
38
- ...styles.root,
39
- ...(props.styles?.root || undefined),
40
- ...(props.overflow !== 'visible' ? styles.overflowHidden : undefined),
41
- }}
42
- onKeyDown={props.onKeyDown}
43
- tabIndex={props.tabIndex}
44
- >
45
- <Grid2
46
- container
47
- direction="column"
48
- wrap="nowrap"
49
- sx={styles.container}
50
- >
51
- {props.children}
52
- </Grid2>
53
- </Paper>
54
- );
55
- }
56
-
57
- export default TabContainer;
1
+ import React from 'react';
2
+
3
+ import { Grid2, Paper } from '@mui/material';
4
+
5
+ const styles: Record<string, React.CSSProperties> = {
6
+ root: {
7
+ width: '100%',
8
+ height: '100%',
9
+ },
10
+ overflowHidden: {
11
+ overflow: 'hidden',
12
+ },
13
+ container: {
14
+ height: '100%',
15
+ },
16
+ };
17
+
18
+ interface TabContainerProps {
19
+ /* The elevation of the tab container. */
20
+ elevation?: number;
21
+ /* Set to 'visible' show the overflow. */
22
+ overflow?: string;
23
+ styles?: {
24
+ root?: React.CSSProperties;
25
+ container?: React.CSSProperties;
26
+ };
27
+ onKeyDown?: (event: React.KeyboardEvent<HTMLDivElement>) => void;
28
+ tabIndex?: number;
29
+ /** The content of the component. */
30
+ children: React.ReactNode;
31
+ }
32
+
33
+ function TabContainer(props: TabContainerProps): React.JSX.Element {
34
+ return (
35
+ <Paper
36
+ elevation={!Number.isNaN(props.elevation) ? props.elevation : 1}
37
+ style={{
38
+ ...styles.root,
39
+ ...(props.styles?.root || undefined),
40
+ ...(props.overflow !== 'visible' ? styles.overflowHidden : undefined),
41
+ }}
42
+ onKeyDown={props.onKeyDown}
43
+ tabIndex={props.tabIndex}
44
+ >
45
+ <Grid2
46
+ container
47
+ direction="column"
48
+ wrap="nowrap"
49
+ sx={styles.container}
50
+ >
51
+ {props.children}
52
+ </Grid2>
53
+ </Paper>
54
+ );
55
+ }
56
+
57
+ export default TabContainer;
@@ -478,8 +478,20 @@ class UploadImage extends Component<UploadImageProps, UploadImageState> {
478
478
  render(): JSX.Element {
479
479
  const { disabled, icon, removeIconFunc, error, crop, onChange } = this.props;
480
480
  const maxSize = this.props.maxSize || 10 * 1024;
481
- const accept = this.props.accept || { 'image/*': [] };
481
+ let accept = this.props.accept || { 'image/*': [] };
482
482
  const { uploadFile, anchorEl, cropHandler } = this.state;
483
+
484
+ // covert '"image/png"' to { 'image/*': [] }
485
+ if (typeof accept === 'string') {
486
+ accept = { [accept]: [] };
487
+ } else if (Array.isArray(accept)) {
488
+ const result: Record<string, string[]> = {};
489
+ accept.forEach(item => {
490
+ result[item] = [];
491
+ });
492
+ accept = result;
493
+ }
494
+
483
495
  return (
484
496
  <Dropzone
485
497
  disabled={!!disabled || cropHandler}
@@ -535,7 +547,7 @@ class UploadImage extends Component<UploadImageProps, UploadImageState> {
535
547
  <div style={styles.buttonRemoveWrapper}>
536
548
  <Tooltip
537
549
  title={I18n.t('ra_Clear')}
538
- componentsProps={{ popper: { sx: { pointerEvents: 'none' } } }}
550
+ slotProps={{ popper: { sx: { pointerEvents: 'none' } } }}
539
551
  >
540
552
  <IconButton
541
553
  size="large"
@@ -554,7 +566,7 @@ class UploadImage extends Component<UploadImageProps, UploadImageState> {
554
566
  <div style={styles.buttonCropWrapper}>
555
567
  <Tooltip
556
568
  title={I18n.t('ra_Crop')}
557
- componentsProps={{ popper: { sx: { pointerEvents: 'none' } } }}
569
+ slotProps={{ popper: { sx: { pointerEvents: 'none' } } }}
558
570
  >
559
571
  <IconButton
560
572
  size="large"
@@ -1,163 +1,163 @@
1
- import React, { type JSX } from 'react';
2
-
3
- import { Button, DialogTitle, DialogContent, DialogActions, Dialog } from '@mui/material';
4
-
5
- import { Check as IconOk, Cancel as IconCancel, Delete as IconClear } from '@mui/icons-material';
6
-
7
- import ComplexCron from '../Components/ComplexCron';
8
- import ConfirmDialog from '../Dialogs/Confirm';
9
-
10
- import I18n from '../i18n';
11
-
12
- // Generate cron expression
13
- const styles: Record<string, React.CSSProperties> = {
14
- headerID: {
15
- fontWeight: 'bold',
16
- fontStyle: 'italic',
17
- },
18
- radio: {
19
- display: 'inline-block',
20
- },
21
- dialogPaper: {
22
- height: 'calc(100% - 96px)',
23
- },
24
- };
25
-
26
- interface DialogCronProps {
27
- onClose: () => void;
28
- onOk: (cron: string | false) => void;
29
- title?: string;
30
- cron?: string;
31
- cancel?: string;
32
- ok?: string;
33
- clear?: string;
34
- clearButton?: boolean;
35
- }
36
-
37
- interface DialogCronState {
38
- cron: string;
39
- showWarning: '' | 'everySecond' | 'everyMinute';
40
- }
41
-
42
- class DialogComplexCron extends React.Component<DialogCronProps, DialogCronState> {
43
- constructor(props: DialogCronProps) {
44
- super(props);
45
- let cron;
46
- if (this.props.cron && typeof this.props.cron === 'string' && this.props.cron.replace(/^["']/, '')[0] !== '{') {
47
- cron = this.props.cron.replace(/['"]/g, '').trim();
48
- } else {
49
- cron = this.props.cron || '{}';
50
- if (typeof cron === 'string') {
51
- cron = cron.replace(/^["']/, '').replace(/["']\n?$/, '');
52
- }
53
- }
54
-
55
- this.state = {
56
- showWarning: '',
57
- cron,
58
- };
59
- }
60
-
61
- handleCancel(): void {
62
- this.props.onClose();
63
- }
64
-
65
- handleOk(ignoreCheck?: boolean): void {
66
- if (!ignoreCheck) {
67
- // Check if the CRON will be executed every second or every minute and warn about it
68
- const cron = ComplexCron.cron2state(this.state.cron);
69
- if (cron.seconds === '*' || cron.seconds === '*/1') {
70
- this.setState({ showWarning: 'everySecond' });
71
- return;
72
- }
73
- if (cron.minutes === '*' || cron.minutes === '*/1') {
74
- this.setState({ showWarning: 'everyMinute' });
75
- return;
76
- }
77
- }
78
-
79
- this.props.onOk(this.state.cron);
80
- this.props.onClose();
81
- }
82
-
83
- renderWarningDialog(): JSX.Element | null {
84
- if (!this.state.showWarning) {
85
- return null;
86
- }
87
- return (
88
- <ConfirmDialog
89
- title={I18n.t('ra_Please confirm')}
90
- text={I18n.t(
91
- this.state.showWarning === 'everySecond'
92
- ? 'ra_The schedule will be executed every second. Are you sure?'
93
- : 'ra_The schedule will be executed every minute. Are you sure?',
94
- )}
95
- onClose={(ok: boolean) =>
96
- this.setState({ showWarning: '' }, () => {
97
- if (ok) {
98
- this.handleOk(true);
99
- }
100
- })
101
- }
102
- />
103
- );
104
- }
105
-
106
- handleClear(): void {
107
- this.props.onOk(false);
108
- this.props.onClose();
109
- }
110
-
111
- render(): JSX.Element {
112
- return (
113
- <Dialog
114
- onClose={() => {}}
115
- maxWidth="md"
116
- fullWidth
117
- sx={{ '& .MuiDialog-paper': styles.dialogPaper }}
118
- open={!0}
119
- aria-labelledby="cron-dialog-title"
120
- >
121
- {this.renderWarningDialog()}
122
- <DialogTitle id="cron-dialog-title">{this.props.title || I18n.t('ra_Define schedule...')}</DialogTitle>
123
- <DialogContent style={{ height: '100%', overflow: 'hidden' }}>
124
- <ComplexCron
125
- cronExpression={this.state.cron}
126
- onChange={cron => this.setState({ cron })}
127
- language={I18n.getLanguage()}
128
- />
129
- </DialogContent>
130
- <DialogActions>
131
- {!!this.props.clearButton && (
132
- <Button
133
- color="grey"
134
- variant="contained"
135
- onClick={() => this.handleClear()}
136
- startIcon={<IconClear />}
137
- >
138
- {this.props.clear || I18n.t('ra_Clear')}
139
- </Button>
140
- )}
141
- <Button
142
- variant="contained"
143
- onClick={() => this.handleOk()}
144
- color="primary"
145
- startIcon={<IconOk />}
146
- >
147
- {this.props.ok || I18n.t('ra_Ok')}
148
- </Button>
149
- <Button
150
- color="grey"
151
- variant="contained"
152
- onClick={() => this.handleCancel()}
153
- startIcon={<IconCancel />}
154
- >
155
- {this.props.cancel || I18n.t('ra_Cancel')}
156
- </Button>
157
- </DialogActions>
158
- </Dialog>
159
- );
160
- }
161
- }
162
-
163
- export default DialogComplexCron;
1
+ import React, { type JSX } from 'react';
2
+
3
+ import { Button, DialogTitle, DialogContent, DialogActions, Dialog } from '@mui/material';
4
+
5
+ import { Check as IconOk, Cancel as IconCancel, Delete as IconClear } from '@mui/icons-material';
6
+
7
+ import ComplexCron from '../Components/ComplexCron';
8
+ import ConfirmDialog from '../Dialogs/Confirm';
9
+
10
+ import I18n from '../i18n';
11
+
12
+ // Generate cron expression
13
+ const styles: Record<string, React.CSSProperties> = {
14
+ headerID: {
15
+ fontWeight: 'bold',
16
+ fontStyle: 'italic',
17
+ },
18
+ radio: {
19
+ display: 'inline-block',
20
+ },
21
+ dialogPaper: {
22
+ height: 'calc(100% - 96px)',
23
+ },
24
+ };
25
+
26
+ interface DialogCronProps {
27
+ onClose: () => void;
28
+ onOk: (cron: string | false) => void;
29
+ title?: string;
30
+ cron?: string;
31
+ cancel?: string;
32
+ ok?: string;
33
+ clear?: string;
34
+ clearButton?: boolean;
35
+ }
36
+
37
+ interface DialogCronState {
38
+ cron: string;
39
+ showWarning: '' | 'everySecond' | 'everyMinute';
40
+ }
41
+
42
+ class DialogComplexCron extends React.Component<DialogCronProps, DialogCronState> {
43
+ constructor(props: DialogCronProps) {
44
+ super(props);
45
+ let cron;
46
+ if (this.props.cron && typeof this.props.cron === 'string' && this.props.cron.replace(/^["']/, '')[0] !== '{') {
47
+ cron = this.props.cron.replace(/['"]/g, '').trim();
48
+ } else {
49
+ cron = this.props.cron || '{}';
50
+ if (typeof cron === 'string') {
51
+ cron = cron.replace(/^["']/, '').replace(/["']\n?$/, '');
52
+ }
53
+ }
54
+
55
+ this.state = {
56
+ showWarning: '',
57
+ cron,
58
+ };
59
+ }
60
+
61
+ handleCancel(): void {
62
+ this.props.onClose();
63
+ }
64
+
65
+ handleOk(ignoreCheck?: boolean): void {
66
+ if (!ignoreCheck) {
67
+ // Check if the CRON will be executed every second or every minute and warn about it
68
+ const cron = ComplexCron.cron2state(this.state.cron);
69
+ if (cron.seconds === '*' || cron.seconds === '*/1') {
70
+ this.setState({ showWarning: 'everySecond' });
71
+ return;
72
+ }
73
+ if (cron.minutes === '*' || cron.minutes === '*/1') {
74
+ this.setState({ showWarning: 'everyMinute' });
75
+ return;
76
+ }
77
+ }
78
+
79
+ this.props.onOk(this.state.cron);
80
+ this.props.onClose();
81
+ }
82
+
83
+ renderWarningDialog(): JSX.Element | null {
84
+ if (!this.state.showWarning) {
85
+ return null;
86
+ }
87
+ return (
88
+ <ConfirmDialog
89
+ title={I18n.t('ra_Please confirm')}
90
+ text={I18n.t(
91
+ this.state.showWarning === 'everySecond'
92
+ ? 'ra_The schedule will be executed every second. Are you sure?'
93
+ : 'ra_The schedule will be executed every minute. Are you sure?',
94
+ )}
95
+ onClose={(ok: boolean) =>
96
+ this.setState({ showWarning: '' }, () => {
97
+ if (ok) {
98
+ this.handleOk(true);
99
+ }
100
+ })
101
+ }
102
+ />
103
+ );
104
+ }
105
+
106
+ handleClear(): void {
107
+ this.props.onOk(false);
108
+ this.props.onClose();
109
+ }
110
+
111
+ render(): JSX.Element {
112
+ return (
113
+ <Dialog
114
+ onClose={() => {}}
115
+ maxWidth="md"
116
+ fullWidth
117
+ sx={{ '& .MuiDialog-paper': styles.dialogPaper }}
118
+ open={!0}
119
+ aria-labelledby="cron-dialog-title"
120
+ >
121
+ {this.renderWarningDialog()}
122
+ <DialogTitle id="cron-dialog-title">{this.props.title || I18n.t('ra_Define schedule...')}</DialogTitle>
123
+ <DialogContent style={{ height: '100%', overflow: 'hidden' }}>
124
+ <ComplexCron
125
+ cronExpression={this.state.cron}
126
+ onChange={cron => this.setState({ cron })}
127
+ language={I18n.getLanguage()}
128
+ />
129
+ </DialogContent>
130
+ <DialogActions>
131
+ {!!this.props.clearButton && (
132
+ <Button
133
+ color="grey"
134
+ variant="contained"
135
+ onClick={() => this.handleClear()}
136
+ startIcon={<IconClear />}
137
+ >
138
+ {this.props.clear || I18n.t('ra_Clear')}
139
+ </Button>
140
+ )}
141
+ <Button
142
+ variant="contained"
143
+ onClick={() => this.handleOk()}
144
+ color="primary"
145
+ startIcon={<IconOk />}
146
+ >
147
+ {this.props.ok || I18n.t('ra_Ok')}
148
+ </Button>
149
+ <Button
150
+ color="grey"
151
+ variant="contained"
152
+ onClick={() => this.handleCancel()}
153
+ startIcon={<IconCancel />}
154
+ >
155
+ {this.props.cancel || I18n.t('ra_Cancel')}
156
+ </Button>
157
+ </DialogActions>
158
+ </Dialog>
159
+ );
160
+ }
161
+ }
162
+
163
+ export default DialogComplexCron;
@@ -37,7 +37,7 @@ interface DialogConfirmProps {
37
37
  /** The dialog title; default: Are you sure? (translated) */
38
38
  title?: string;
39
39
  /** The dialog text */
40
- text?: string | React.JSX.Element;
40
+ text?: string | React.JSX.Element | React.JSX.Element[];
41
41
  /** Close handler. */
42
42
  onClose?: (ok: boolean) => void;
43
43
  /** if the dialog must be fill sized */
@@ -17,7 +17,7 @@ interface DialogErrorProps {
17
17
  /* The dialog title; default: Error (translated) */
18
18
  title?: string;
19
19
  /* The dialog text */
20
- text: string | React.JSX.Element;
20
+ text: string | React.JSX.Element | React.JSX.Element[];
21
21
  /* Close handler. */
22
22
  onClose?: () => void;
23
23
  /* if the dialog must be fill sized */
@@ -18,7 +18,7 @@ interface DialogMessageProps {
18
18
  /* The dialog title; default: Message (translated) */
19
19
  title?: string;
20
20
  /* The dialog text */
21
- text: string | React.JSX.Element;
21
+ text: string | React.JSX.Element | React.JSX.Element[];
22
22
  /* Close handler. */
23
23
  onClose?: () => void;
24
24
  /* if the dialog must be fill sized */
@@ -16,6 +16,7 @@ declare global {
16
16
  registerSocketOnLoad: (func: () => void) => void;
17
17
  vendorPrefix: undefined | string;
18
18
  io: any;
19
+ iob: any;
19
20
  }
20
21
  }
21
22
 
@@ -410,7 +411,7 @@ class Connection {
410
411
  */
411
412
  startSocket(): void {
412
413
  // if socket io is not yet loaded
413
- if (typeof window.io === 'undefined') {
414
+ if (typeof window.io === 'undefined' && typeof window.iob === 'undefined') {
414
415
  // if in index.html the onLoad function not defined
415
416
  if (typeof window.registerSocketOnLoad !== 'function') {
416
417
  // poll if loaded
@@ -475,7 +476,7 @@ class Connection {
475
476
 
476
477
  const url = port ? `${protocol}://${host}:${port}${path}` : `${protocol}://${host}${path}`;
477
478
 
478
- this._socket = window.io.connect(url, {
479
+ this._socket = (window.io || window.iob).connect(url, {
479
480
  path: path.endsWith('/') ? `${path}socket.io` : `${path}/socket.io`,
480
481
  query: 'ws=true',
481
482
  name: this.props.name,