@iobroker/adapter-react-v5 6.1.9 → 7.0.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.
- package/Components/404.js +13 -13
- package/Components/FileBrowser.js +24 -19
- package/Components/FileViewer.js +14 -5
- package/Components/Loader.js +223 -223
- package/Components/Loaders/PT.css +108 -108
- package/Components/Loaders/PT.js +103 -103
- package/Components/Loaders/Vendor.css +13 -13
- package/Components/Loaders/Vendor.js +7 -7
- package/Components/ObjectBrowser.d.ts +2 -0
- package/Components/ObjectBrowser.js +214 -115
- package/Components/UploadImage.js +305 -305
- package/Components/loader.css +221 -221
- package/Components/types.d.ts +82 -82
- package/GenericApp.js +49 -49
- package/LICENSE +22 -22
- package/Prompt.js +7 -7
- package/README.md +1004 -1008
- package/Theme.js +8 -7
- package/assets/devices/Alarm Systems.svg +18 -18
- package/assets/devices/Amplifier.svg +21 -21
- package/assets/devices/Awnings.svg +4 -4
- package/assets/devices/Battery Status.svg +4 -4
- package/assets/devices/Ceiling Spotlights.svg +15 -15
- package/assets/devices/Chandelier.svg +6 -6
- package/assets/devices/Climate.svg +11 -11
- package/assets/devices/Coffee Makers.svg +5 -5
- package/assets/devices/Cold Water.svg +31 -31
- package/assets/devices/Computer.svg +21 -21
- package/assets/devices/Consumption.svg +7 -7
- package/assets/devices/Curtains.svg +43 -43
- package/assets/devices/Dishwashers.svg +11 -11
- package/assets/devices/Doors.svg +5 -5
- package/assets/devices/Doorstep.svg +35 -35
- package/assets/devices/Dryer.svg +13 -13
- package/assets/devices/Fan.svg +20 -20
- package/assets/devices/Floor Lamps.svg +4 -4
- package/assets/devices/Garage Doors.svg +9 -9
- package/assets/devices/Gates.svg +32 -32
- package/assets/devices/Hairdryer.svg +23 -23
- package/assets/devices/Handle.svg +6 -6
- package/assets/devices/Hanging Lamps.svg +8 -8
- package/assets/devices/Heater.svg +44 -44
- package/assets/devices/Hoods.svg +11 -11
- package/assets/devices/Hot Water.svg +9 -9
- package/assets/devices/Humidity.svg +41 -41
- package/assets/devices/Iron.svg +4 -4
- package/assets/devices/Irrigation.svg +22 -22
- package/assets/devices/Led Strip.svg +30 -30
- package/assets/devices/Light.svg +29 -29
- package/assets/devices/Lightings.svg +46 -46
- package/assets/devices/Lock.svg +19 -19
- package/assets/devices/Louvre.svg +6 -6
- package/assets/devices/Mowing Machine.svg +8 -8
- package/assets/devices/Music.svg +12 -12
- package/assets/devices/Outdoor Blinds.svg +6 -6
- package/assets/devices/People.svg +19 -19
- package/assets/devices/Pool.svg +7 -7
- package/assets/devices/Power Consumption.svg +12 -12
- package/assets/devices/Printer.svg +9 -9
- package/assets/devices/Pump.svg +9 -9
- package/assets/devices/Receiver.svg +18 -18
- package/assets/devices/Sconces.svg +9 -9
- package/assets/devices/Security.svg +34 -34
- package/assets/devices/Shading.svg +4 -4
- package/assets/devices/Shutters.svg +10 -10
- package/assets/devices/SmokeDetector.svg +12 -12
- package/assets/devices/Sockets.svg +13 -13
- package/assets/devices/Speaker.svg +35 -35
- package/assets/devices/Stove.svg +11 -11
- package/assets/devices/Table Lamps.svg +11 -11
- package/assets/devices/Temperature Sensors.svg +28 -28
- package/assets/devices/Tv.svg +7 -7
- package/assets/devices/Vacuum Cleaner.svg +15 -15
- package/assets/devices/Ventilation.svg +12 -12
- package/assets/devices/Washing Machines.svg +15 -15
- package/assets/devices/Water Consumption.svg +5 -5
- package/assets/devices/Water Heater.svg +8 -8
- package/assets/devices/Water.svg +40 -40
- package/assets/devices/Weather.svg +28 -28
- package/assets/devices/Window.svg +7 -7
- package/assets/lamp_ceiling.svg +8 -8
- package/assets/lamp_table.svg +7 -7
- package/assets/no_icon.svg +9 -9
- package/assets/rooms/Anteroom.svg +52 -52
- package/assets/rooms/Attic.svg +21 -21
- package/assets/rooms/Balcony.svg +12 -12
- package/assets/rooms/Barn.svg +5 -5
- package/assets/rooms/Basement.svg +4 -4
- package/assets/rooms/Bathroom.svg +38 -38
- package/assets/rooms/Bedroom.svg +5 -5
- package/assets/rooms/Boiler Room.svg +12 -12
- package/assets/rooms/Carport.svg +17 -17
- package/assets/rooms/Cellar.svg +89 -89
- package/assets/rooms/Chamber.svg +9 -9
- package/assets/rooms/Corridor.svg +52 -52
- package/assets/rooms/Dining Area.svg +37 -37
- package/assets/rooms/Dining Room.svg +37 -37
- package/assets/rooms/Dining.svg +37 -37
- package/assets/rooms/Dressing Room.svg +4 -4
- package/assets/rooms/Driveway.svg +14 -14
- package/assets/rooms/Entrance.svg +44 -44
- package/assets/rooms/Equipment Room.svg +14 -14
- package/assets/rooms/Front Yard.svg +64 -64
- package/assets/rooms/Gallery.svg +13 -13
- package/assets/rooms/Garage.svg +20 -20
- package/assets/rooms/Garden.svg +12 -12
- package/assets/rooms/Ground Floor.svg +95 -95
- package/assets/rooms/Guest Bathroom.svg +32 -32
- package/assets/rooms/Guest Room.svg +5 -5
- package/assets/rooms/Gym.svg +4 -4
- package/assets/rooms/Hall.svg +19 -19
- package/assets/rooms/Home Theater.svg +7 -7
- package/assets/rooms/Kitchen.svg +17 -17
- package/assets/rooms/Laundry Room.svg +11 -11
- package/assets/rooms/Living Area.svg +10 -10
- package/assets/rooms/Living Room.svg +10 -10
- package/assets/rooms/Locker Room.svg +16 -16
- package/assets/rooms/Nursery.svg +4 -4
- package/assets/rooms/Office.svg +8 -8
- package/assets/rooms/Outdoors.svg +7 -7
- package/assets/rooms/Playroom.svg +5 -5
- package/assets/rooms/Pool.svg +7 -7
- package/assets/rooms/Rear Wall.svg +30 -30
- package/assets/rooms/Second Floor.svg +95 -95
- package/assets/rooms/Shed.svg +16 -16
- package/assets/rooms/Sleeping Area.svg +22 -22
- package/assets/rooms/Stairway.svg +4 -4
- package/assets/rooms/Stairwell.svg +15 -15
- package/assets/rooms/Storeroom.svg +4 -4
- package/assets/rooms/Summer House.svg +27 -27
- package/assets/rooms/Swimming Pool.svg +21 -21
- package/assets/rooms/Terrace.svg +6 -6
- package/assets/rooms/Toilet.svg +10 -10
- package/assets/rooms/Upstairs.svg +5 -5
- package/assets/rooms/Wardrobe.svg +60 -60
- package/assets/rooms/Washroom.svg +19 -19
- package/assets/rooms/Wc.svg +10 -10
- package/assets/rooms/Windscreen.svg +60 -60
- package/assets/rooms/Workshop.svg +22 -22
- package/assets/rooms/Workspace.svg +8 -8
- package/craco-module-federation.js +71 -71
- package/icons/IconFx.js +1 -1
- package/icons/IconLogout.js +1 -1
- package/index.css +54 -54
- package/modulefederation.admin.config.js +31 -31
- package/package.json +9 -9
- package/src/AdminConnection.tsx +3 -3
- package/src/Components/404.tsx +121 -121
- package/src/Components/ColorPicker.tsx +315 -315
- package/src/Components/ComplexCron.tsx +507 -507
- package/src/Components/CopyToClipboard.tsx +165 -165
- package/src/Components/CustomModal.tsx +163 -163
- package/src/Components/FileBrowser.tsx +2414 -2394
- package/src/Components/FileViewer.tsx +393 -384
- package/src/Components/Icon.tsx +210 -210
- package/src/Components/IconPicker.tsx +149 -149
- package/src/Components/IconSelector.tsx +2202 -2202
- package/src/Components/Image.tsx +176 -176
- package/src/Components/Loader.tsx +304 -304
- package/src/Components/Logo.tsx +166 -166
- package/src/Components/MDUtils.tsx +100 -100
- package/src/Components/ObjectBrowser.tsx +8032 -7915
- package/src/Components/Router.tsx +90 -90
- package/src/Components/SaveCloseButtons.tsx +113 -113
- package/src/Components/Schedule.tsx +1724 -1724
- package/src/Components/SelectWithIcon.tsx +197 -197
- package/src/Components/TabContainer.tsx +55 -55
- package/src/Components/TabContent.tsx +37 -37
- package/src/Components/TabHeader.tsx +19 -19
- package/src/Components/TableResize.tsx +259 -259
- package/src/Components/TextWithIcon.tsx +148 -148
- package/src/Components/ToggleThemeMenu.tsx +34 -34
- package/src/Components/TreeTable.tsx +919 -919
- package/src/Components/UploadImage.tsx +599 -599
- package/src/Components/Utils.tsx +1794 -1794
- package/src/Components/loader.css +221 -221
- package/src/Components/withWidth.tsx +21 -21
- package/src/Connection.tsx +7 -7
- package/src/Dialogs/ComplexCron.tsx +129 -129
- package/src/Dialogs/Confirm.tsx +162 -162
- package/src/Dialogs/Cron.tsx +182 -182
- package/src/Dialogs/Error.tsx +72 -72
- package/src/Dialogs/Message.tsx +71 -71
- package/src/Dialogs/SelectFile.tsx +270 -270
- package/src/Dialogs/SelectID.tsx +298 -298
- package/src/Dialogs/SimpleCron.tsx +100 -100
- package/src/Dialogs/TextInput.tsx +107 -107
- package/src/GenericApp.tsx +976 -976
- package/src/LegacyConnection.tsx +3589 -3589
- package/src/Prompt.tsx +20 -20
- package/src/Theme.tsx +479 -479
- package/src/icons/IconAdapter.tsx +20 -20
- package/src/icons/IconAlias.tsx +20 -20
- package/src/icons/IconChannel.tsx +21 -21
- package/src/icons/IconClearFilter.tsx +22 -22
- package/src/icons/IconClosed.tsx +17 -17
- package/src/icons/IconCopy.tsx +16 -16
- package/src/icons/IconDevice.tsx +27 -27
- package/src/icons/IconDocument.tsx +17 -17
- package/src/icons/IconDocumentReadOnly.tsx +18 -18
- package/src/icons/IconExpert.tsx +18 -18
- package/src/icons/IconFx.tsx +36 -36
- package/src/icons/IconInstance.tsx +20 -20
- package/src/icons/IconLogout.tsx +30 -30
- package/src/icons/IconNoIcon.tsx +19 -19
- package/src/icons/IconOpen.tsx +17 -17
- package/src/icons/IconProps.tsx +15 -15
- package/src/icons/IconState.tsx +17 -17
- package/src/index.css +54 -54
- package/types.d.ts +134 -134
package/README.md
CHANGED
|
@@ -1,1334 +1,1330 @@
|
|
|
1
|
-
# Help ReactJS classes for adapter config
|
|
2
|
-
You can find demo on https://github.com/ioBroker/adapter-react-demo
|
|
3
|
-
|
|
4
|
-
## Getting started
|
|
5
|
-
If you want to create the configuration page with ReactJS:
|
|
6
|
-
1. Create github repo for adapter.
|
|
7
|
-
2. execute `npx create-react-app src` . It will take a while.
|
|
8
|
-
3. `cd src`
|
|
9
|
-
4. Modify package.json file in src directory:
|
|
10
|
-
- Change `name` from `src` to `ADAPTERNAME-admin` (Of course replace `ADAPTERNAME` with yours)
|
|
11
|
-
- Add to devDependencies:
|
|
12
|
-
```
|
|
13
|
-
"@iobroker/adapter-react": "^4.0.10",
|
|
14
|
-
```
|
|
15
|
-
Versions can be higher.
|
|
16
|
-
So your src/package.json should look like:
|
|
17
|
-
```
|
|
18
|
-
{
|
|
19
|
-
"name": "ADAPTERNAME-admin",
|
|
20
|
-
"version": "0.1.0",
|
|
21
|
-
"private": true,
|
|
22
|
-
"dependencies": {
|
|
23
|
-
"react": "^18.2.0",
|
|
24
|
-
"react-dom": "^18.2.0",
|
|
25
|
-
"react-icons": "^4.6.0",
|
|
26
|
-
"react-scripts": "^5.0.1",
|
|
27
|
-
"@iobroker/adapter-react-v5": "^3.2.7",
|
|
28
|
-
"del": "^6.1.1",
|
|
29
|
-
"gulp": "^4.0.2"
|
|
30
|
-
},
|
|
31
|
-
"scripts": {
|
|
32
|
-
"start": "react-scripts start",
|
|
33
|
-
"build": "react-scripts build",
|
|
34
|
-
"test": "react-scripts test",
|
|
35
|
-
"eject": "react-scripts eject"
|
|
36
|
-
},
|
|
37
|
-
"eslintConfig": {
|
|
38
|
-
"extends": "react-app"
|
|
39
|
-
},
|
|
40
|
-
"homepage": ".",
|
|
41
|
-
"browserslist": [
|
|
42
|
-
">0.2%",
|
|
43
|
-
"not dead",
|
|
44
|
-
"not ie <= 11",
|
|
45
|
-
"not op_mini all"
|
|
46
|
-
]
|
|
47
|
-
}
|
|
48
|
-
```
|
|
49
|
-
5. Call in `src`: `npm install`
|
|
50
|
-
6. Copy gulpfile.js into `src`: `cp node_modules/@iobroker/adapter-react/gulpfile.js gulpfile.js`
|
|
51
|
-
7. Start your dummy application `npm run start` for developing or build with `npm run build` and
|
|
52
|
-
copy files in `build` directory to `www` or to `admin`. In the admin you must rename `index.html` to `index_m.html`.
|
|
53
|
-
8. You can do that with `gulp` tasks: `gulp build`, `gulp copy`, `gulp renameIndex` or `gulp renameTab`
|
|
54
|
-
|
|
55
|
-
## Development
|
|
56
|
-
1. Add `socket.io` to `public/index.html`.
|
|
57
|
-
After
|
|
58
|
-
|
|
59
|
-
```
|
|
60
|
-
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
insert
|
|
64
|
-
|
|
65
|
-
```
|
|
66
|
-
<script>
|
|
67
|
-
var script = document.createElement('script');
|
|
68
|
-
window.registerSocketOnLoad = function (cb) {
|
|
69
|
-
window.socketLoadedHandler = cb;
|
|
70
|
-
};
|
|
71
|
-
const parts = (window.location.search || '').replace(/^\?/, '').split('&');
|
|
72
|
-
const query = {};
|
|
73
|
-
parts.forEach(item => {
|
|
74
|
-
const [name, val] = item.split('=');
|
|
75
|
-
query[decodeURIComponent(name)] = val !== undefined ? decodeURIComponent(val) : true;
|
|
76
|
-
});
|
|
77
|
-
script.onload = function () { typeof window.socketLoadedHandler === 'function' && window.socketLoadedHandler(); };
|
|
78
|
-
script.src = window.location.port === '3000' ? window.location.protocol + '//' + (query.host || window.location.hostname) + ':' + (query.port || 8081) + '/lib/js/socket.io.js' : '%PUBLIC_URL%/../../lib/js/socket.io.js';
|
|
79
|
-
|
|
80
|
-
document.head.appendChild(script);
|
|
81
|
-
</script>
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
3. Add to App.js constructor initialization for I18n:
|
|
85
|
-
```
|
|
86
|
-
class App extends GenericApp {
|
|
87
|
-
constructor(props) {
|
|
88
|
-
const extendedProps = {...props};
|
|
89
|
-
extendedProps.encryptedFields = ['pass']; // this parameter will be encrypted and decrypted automatically
|
|
90
|
-
extendedProps.translations = {
|
|
91
|
-
'en': require('./i18n/en'),
|
|
92
|
-
'de': require('./i18n/de'),
|
|
93
|
-
'ru': require('./i18n/ru'),
|
|
94
|
-
'pt': require('./i18n/pt'),
|
|
95
|
-
'nl': require('./i18n/nl'),
|
|
96
|
-
'fr': require('./i18n/fr'),
|
|
97
|
-
'it': require('./i18n/it'),
|
|
98
|
-
'es': require('./i18n/es'),
|
|
99
|
-
'pl': require('./i18n/pl'),
|
|
100
|
-
'uk': require('./i18n/uk'),
|
|
101
|
-
'zh-cn': require('./i18n/zh-cn'),
|
|
102
|
-
};
|
|
103
|
-
// get actual admin port
|
|
104
|
-
extendedProps.socket = {port: parseInt(window.location.port, 10)};
|
|
105
|
-
|
|
106
|
-
// Only if close, save buttons are not required at the bottom (e.g. if admin tab)
|
|
107
|
-
// extendedProps.bottomButtons = false;
|
|
108
|
-
|
|
109
|
-
// only for debug purposes
|
|
110
|
-
if (extendedProps.socket.port === 3000) {
|
|
111
|
-
extendedProps.socket.port = 8081;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
// allow to manage GenericApp the sentry initialisation or do not set the sentryDSN if no sentry available
|
|
115
|
-
extendedProps.sentryDSN = 'https://yyy@sentry.iobroker.net/xx';
|
|
116
|
-
|
|
117
|
-
super(extendedProps);
|
|
118
|
-
}
|
|
119
|
-
...
|
|
120
|
-
}
|
|
121
|
-
```
|
|
122
|
-
|
|
123
|
-
4. Replace `index.js` with the following code to support themes:
|
|
124
|
-
```
|
|
125
|
-
import React from 'react';
|
|
126
|
-
import ReactDOM from 'react-dom';
|
|
127
|
-
import { MuiThemeProvider} from '@material-ui/core/styles';
|
|
128
|
-
import * as serviceWorker from './serviceWorker';
|
|
129
|
-
|
|
130
|
-
import './index.css';
|
|
131
|
-
import App from './App';
|
|
132
|
-
import { version } from '../package.json';
|
|
133
|
-
|
|
134
|
-
import theme from '@iobroker/adapter-react/Theme';
|
|
135
|
-
|
|
136
|
-
console.log('iobroker.scenes@' + version);
|
|
137
|
-
let themeName = window.localStorage ? window.localStorage.getItem('App.theme') || 'light' : 'light';
|
|
138
|
-
|
|
139
|
-
function build() {
|
|
140
|
-
return ReactDOM.render(<MuiThemeProvider theme={ theme(themeName) }>
|
|
141
|
-
<App onThemeChange={_theme => {
|
|
142
|
-
themeName = _theme;
|
|
143
|
-
build();
|
|
144
|
-
}}/>
|
|
145
|
-
</MuiThemeProvider>, document.getElementById('root'));
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
build();
|
|
149
|
-
|
|
150
|
-
// If you want your app to work offline and load faster, you can change
|
|
151
|
-
// unregister() to register() below. Note this comes with some pitfalls.
|
|
152
|
-
// Learn more about service workers: http://bit.ly/CRA-PWA
|
|
153
|
-
serviceWorker.unregister();
|
|
154
|
-
```
|
|
155
|
-
|
|
156
|
-
5. Add to App.js encoding and decoding of values:
|
|
157
|
-
```
|
|
158
|
-
class App extend GenericApp {
|
|
159
|
-
...
|
|
160
|
-
onPrepareLoad(settings) {
|
|
161
|
-
settings.pass = this.decode(settings.pass);
|
|
162
|
-
}
|
|
163
|
-
onPrepareSave(settings) {
|
|
164
|
-
settings.pass = this.encode(settings.pass);
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
```
|
|
168
|
-
|
|
169
|
-
6. The optional step is to validate the data to be saved:
|
|
170
|
-
```
|
|
171
|
-
onPrepareSave(settings) {
|
|
172
|
-
super.onPrepareSave(settings);
|
|
173
|
-
if (DATA_INVALID) {
|
|
174
|
-
return false; // configuration will not be saved
|
|
175
|
-
} else {
|
|
176
|
-
return true;
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
```
|
|
180
|
-
|
|
181
|
-
## Components
|
|
182
|
-
|
|
183
|
-
### Connection.tsx
|
|
184
|
-
This is a non-react class to provide the communication for socket connection with the server.
|
|
185
|
-
|
|
186
|
-
### GenericApp.tsx
|
|
187
|
-
|
|
188
|
-
### i18n.ts
|
|
189
|
-
|
|
190
|
-
### Theme.tsx
|
|
191
|
-
|
|
192
|
-
### Dialogs
|
|
193
|
-
Some dialogs are predefined and could be used out of the box.
|
|
194
|
-
|
|
195
|
-
#### Confirm.tsx
|
|
196
|
-
<!-- TODO: Provide screenshot here -->
|
|
197
|
-
|
|
198
|
-
Usage:
|
|
199
|
-
```
|
|
200
|
-
import React from 'react';
|
|
201
|
-
import ConfirmDialog from '@iobroker/adapter-react/Dialogs/Confirm'
|
|
202
|
-
import I18n from '@iobroker/adapter-react/i18n';
|
|
203
|
-
|
|
204
|
-
class ExportImportDialog extends React.Component {
|
|
205
|
-
constructor(props) {
|
|
206
|
-
super(props);
|
|
207
|
-
|
|
208
|
-
this.state = {
|
|
209
|
-
confirmDialog: false,
|
|
210
|
-
};
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
renderConfirmDialog() {
|
|
214
|
-
if (!this.state.confirmDialog) {
|
|
215
|
-
return null;
|
|
216
|
-
}
|
|
217
|
-
return <ConfirmDialog
|
|
218
|
-
title={ I18n.t('Scene will be overwritten.') }
|
|
219
|
-
text={ I18n.t('All data will be lost. Confirm?') }
|
|
220
|
-
ok={ I18n.t('Yes') }
|
|
221
|
-
cancel={ I18n.t('Cancel') }
|
|
222
|
-
suppressQuestionMinutes={5}
|
|
223
|
-
dialogName="myConfirmDialogThatCouldBeSuppressed"
|
|
224
|
-
suppressText={I18n.t('Suppress question for next %s minutes', 5)}
|
|
225
|
-
onClose={isYes => {
|
|
226
|
-
this.setState({ confirmDialog: false} );
|
|
227
|
-
}}
|
|
228
|
-
/>;
|
|
229
|
-
}
|
|
230
|
-
render() {
|
|
231
|
-
return <div>
|
|
232
|
-
<Button onClick={ () => this.setState({confirmDialog: true}) }>Click</Button>
|
|
233
|
-
{ this.renderConfirmDialog() }
|
|
234
|
-
</div>
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
export default ExportImportDialog;
|
|
239
|
-
```
|
|
240
|
-
|
|
241
|
-
#### Error.tsx
|
|
242
|
-
<!-- TODO: Provide screenshot here -->
|
|
243
|
-
|
|
244
|
-
#### Message.tsx
|
|
245
|
-
<!-- TODO: Provide screenshot here -->
|
|
246
|
-
```
|
|
247
|
-
renderMessage() {
|
|
248
|
-
if (this.state.showMessage) {
|
|
249
|
-
return <Message
|
|
250
|
-
text={this.state.showMessage}
|
|
251
|
-
onClose={() => this.setState({showMessage: false})}
|
|
252
|
-
/>;
|
|
253
|
-
} else {
|
|
254
|
-
return null;
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
```
|
|
258
|
-
|
|
259
|
-
#### SelectID.tsx
|
|
260
|
-

|
|
261
|
-
```
|
|
262
|
-
import DialogSelectID from '@iobroker/adapter-react/Dialogs/SelectID';
|
|
263
|
-
|
|
264
|
-
class MyComponent extends Component {
|
|
265
|
-
constructor(props) {
|
|
266
|
-
super(props);
|
|
267
|
-
this.state = {
|
|
268
|
-
showSelectId: false,
|
|
269
|
-
};
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
renderSelectIdDialog() {
|
|
273
|
-
if (this.state.showSelectId) {
|
|
274
|
-
return <DialogSelectID
|
|
275
|
-
key="tableSelect"
|
|
276
|
-
imagePrefix="../.."
|
|
277
|
-
dialogName={this.props.adapterName}
|
|
278
|
-
themeType={this.props.themeType}
|
|
279
|
-
socket={this.props.socket}
|
|
280
|
-
statesOnly={true}
|
|
281
|
-
selected={this.state.selectIdValue}
|
|
282
|
-
onClose={() => this.setState({showSelectId: false})}
|
|
283
|
-
onOk={(selected, name) => {
|
|
284
|
-
this.setState({showSelectId: false, selectIdValue: selected});
|
|
285
|
-
}}
|
|
286
|
-
/>;
|
|
287
|
-
} else {
|
|
288
|
-
return null;
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
render() {
|
|
292
|
-
return renderSelectIdDialog();
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
```
|
|
296
|
-
|
|
297
|
-
#### Cron
|
|
298
|
-
Include `"react-text-mask": "^5.4.3",` in package.json.
|
|
299
|
-
|
|
300
|
-
<!-- TODO: Provide screenshot here -->
|
|
301
|
-
|
|
302
|
-
```
|
|
303
|
-
function renderCron() {
|
|
304
|
-
if (!showCron) {
|
|
305
|
-
return null;
|
|
306
|
-
} else {
|
|
307
|
-
return <DialogCron
|
|
308
|
-
key="dialogCron1"
|
|
309
|
-
cron={this.state.cronValue || '* * * * *'}
|
|
310
|
-
onClose={() => this.setState({ showCron: false })}
|
|
311
|
-
onOk={cronValue => {
|
|
312
|
-
this.setState({ cronValue })
|
|
313
|
-
}}
|
|
314
|
-
/>;
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
```
|
|
318
|
-
|
|
319
|
-
### Components
|
|
320
|
-
|
|
321
|
-
#### Utils.tsx
|
|
322
|
-
##### getObjectNameFromObj
|
|
323
|
-
`getObjectNameFromObj(obj, settings, options, isDesc)`
|
|
324
|
-
|
|
325
|
-
Get object name from a single object.
|
|
326
|
-
|
|
327
|
-
Usage: `Utils.getObjectNameFromObj(this.objects[id], null, {language: I18n.getLanguage()})`
|
|
328
|
-
|
|
329
|
-
##### getObjectIcon
|
|
330
|
-
`getObjectIcon(id, obj)`
|
|
331
|
-
|
|
332
|
-
Get icon from the object.
|
|
333
|
-
|
|
334
|
-
Usage:
|
|
335
|
-
```
|
|
336
|
-
const icon = Utils.getObjectIcon(id, this.objects[id]);
|
|
337
|
-
return (<img src={icon}/>);
|
|
338
|
-
```
|
|
339
|
-
|
|
340
|
-
##### isUseBright
|
|
341
|
-
`isUseBright(color, defaultValue)`
|
|
342
|
-
|
|
343
|
-
Usage: `
|
|
344
|
-
|
|
345
|
-
#### Loader.tsx
|
|
346
|
-

|
|
347
|
-
|
|
348
|
-
```
|
|
349
|
-
render() {
|
|
350
|
-
if (!this.state.loaded) {
|
|
351
|
-
return <MuiThemeProvider theme={this.state.theme}>
|
|
352
|
-
<Loader theme={this.state.themeType}/>
|
|
353
|
-
</MuiThemeProvider>;
|
|
354
|
-
}
|
|
355
|
-
// render loaded data
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
```
|
|
359
|
-
|
|
360
|
-
#### Logo.tsx
|
|
361
|
-

|
|
362
|
-
|
|
363
|
-
```
|
|
364
|
-
render() {
|
|
365
|
-
return <form className={this.props.classes.tab}>
|
|
366
|
-
<Logo
|
|
367
|
-
instance={this.props.instance}
|
|
368
|
-
common={this.props.common}
|
|
369
|
-
native={this.props.native}
|
|
370
|
-
onError={text => this.setState({errorText: text})}
|
|
371
|
-
onLoad={this.props.onLoad}
|
|
372
|
-
/>
|
|
373
|
-
...
|
|
374
|
-
</form>;
|
|
375
|
-
}
|
|
376
|
-
```
|
|
377
|
-
|
|
378
|
-
#### Router.tsx
|
|
379
|
-
|
|
380
|
-
#### ObjectBrowser.js
|
|
381
|
-
It is better to use `Dialog/SelectID`, but if you want:
|
|
382
|
-
|
|
383
|
-

|
|
384
|
-
|
|
385
|
-
```
|
|
386
|
-
<ObjectBrowser
|
|
387
|
-
foldersFirst={this.props.foldersFirst}
|
|
388
|
-
imagePrefix={this.props.imagePrefix || this.props.prefix} // prefix is for back compatibility
|
|
389
|
-
defaultFilters={this.filters}
|
|
390
|
-
dialogName={this.dialogName}
|
|
391
|
-
showExpertButton={this.props.showExpertButton !== undefined ? this.props.showExpertButton : true}
|
|
392
|
-
style={{ width: '100%', height: '100%' }}
|
|
393
|
-
columns={this.props.columns || ['name', 'type', 'role', 'room', 'func', 'val']}
|
|
394
|
-
types={this.props.types || ['state']}
|
|
395
|
-
t={I18n.t}
|
|
396
|
-
lang={this.props.lang || I18n.getLanguage()}
|
|
397
|
-
socket={this.props.socket}
|
|
398
|
-
selected={this.state.selected}
|
|
399
|
-
multiSelect={this.props.multiSelect}
|
|
400
|
-
notEditable={this.props.notEditable === undefined ? true : this.props.notEditable}
|
|
401
|
-
name={this.state.name}
|
|
402
|
-
themeName={this.props.themeName}
|
|
403
|
-
themeType={this.props.themeType}
|
|
404
|
-
customFilter={this.props.customFilter}
|
|
405
|
-
onFilterChanged={filterConfig => {
|
|
406
|
-
this.filters = filterConfig;
|
|
407
|
-
window.localStorage.setItem(this.dialogName, JSON.stringify(filterConfig));
|
|
408
|
-
}}
|
|
409
|
-
onSelect={(selected, name, isDouble) => {
|
|
410
|
-
if (JSON.stringify(selected) !== JSON.stringify(this.state.selected)) {
|
|
411
|
-
this.setState({selected, name}, () =>
|
|
412
|
-
isDouble && this.handleOk());
|
|
413
|
-
} else if (isDouble) {
|
|
414
|
-
this.handleOk();
|
|
415
|
-
}
|
|
416
|
-
}}
|
|
417
|
-
/>
|
|
418
|
-
```
|
|
419
|
-
|
|
420
|
-
#### TreeTable.ts
|
|
421
|
-

|
|
422
|
-
|
|
423
|
-
```
|
|
424
|
-
// STYLES
|
|
425
|
-
const styles = theme => ({
|
|
426
|
-
tableDiv: {
|
|
427
|
-
width: '100%',
|
|
428
|
-
overflow: 'hidden',
|
|
429
|
-
height: 'calc(100% - 48px)',
|
|
430
|
-
},
|
|
431
|
-
});
|
|
432
|
-
class MyComponent extends Component {
|
|
433
|
-
constructor(props) {
|
|
434
|
-
super(props);
|
|
435
|
-
|
|
436
|
-
this.state = {
|
|
437
|
-
data: [
|
|
438
|
-
{
|
|
439
|
-
id: 'UniqueID1' // required
|
|
440
|
-
fieldIdInData: 'Name1',
|
|
441
|
-
myType: 'number',
|
|
442
|
-
},
|
|
443
|
-
{
|
|
444
|
-
id: 'UniqueID2' // required
|
|
445
|
-
fieldIdInData: 'Name12',
|
|
446
|
-
myType: 'string',
|
|
447
|
-
},
|
|
448
|
-
],
|
|
449
|
-
};
|
|
450
|
-
|
|
451
|
-
this.columns = [
|
|
452
|
-
{
|
|
453
|
-
title: 'Name of field', // required, else it will be "field"
|
|
454
|
-
field: 'fieldIdInData', // required
|
|
455
|
-
editable: false, // or true [default - true]
|
|
456
|
-
cellStyle: { // CSS style - // optional
|
|
457
|
-
maxWidth: '12rem',
|
|
458
|
-
overflow: 'hidden',
|
|
459
|
-
wordBreak: 'break-word',
|
|
460
|
-
},
|
|
461
|
-
lookup: { // optional => edit will be automatically "SELECT"
|
|
462
|
-
'value1': 'text1',
|
|
463
|
-
'value2': 'text2',
|
|
464
|
-
}
|
|
465
|
-
},
|
|
466
|
-
{
|
|
467
|
-
title: 'Type', // required, else it will be "field"
|
|
468
|
-
field: 'myType', // required
|
|
469
|
-
editable: true, // or true [default - true]
|
|
470
|
-
lookup: { // optional => edit will be automatically "SELECT"
|
|
471
|
-
'number': 'Number',
|
|
472
|
-
'string': 'String',
|
|
473
|
-
'boolean': 'Boolean',
|
|
474
|
-
},
|
|
475
|
-
type: 'number/string/color/oid/icon/boolean', // oid=ObjectID,icon=base64-icon
|
|
476
|
-
editComponent: props =>
|
|
477
|
-
<div>Prefix{ <br/>
|
|
478
|
-
<textarea
|
|
479
|
-
rows={4}
|
|
480
|
-
style={{width: '100%', resize: 'vertical'}}
|
|
481
|
-
value={props.value}
|
|
482
|
-
onChange={e => props.onChange(e.target.value)}
|
|
483
|
-
/>
|
|
484
|
-
Suffix
|
|
485
|
-
</div>,
|
|
486
|
-
},
|
|
487
|
-
];
|
|
488
|
-
}
|
|
489
|
-
// renderTable
|
|
490
|
-
render() {
|
|
491
|
-
return <div className={this.props.classes.tableDiv}>
|
|
492
|
-
<TreeTable
|
|
493
|
-
columns={this.columns}
|
|
494
|
-
data={this.state.data}
|
|
495
|
-
onUpdate={(newData, oldData) => {
|
|
496
|
-
const data = JSON.parse(JSON.stringify(this.state.data));
|
|
497
|
-
|
|
498
|
-
// Added new line
|
|
499
|
-
if (newData === true) {
|
|
500
|
-
// find unique ID
|
|
501
|
-
let i = 1;
|
|
502
|
-
let id = 'line_' + i;
|
|
503
|
-
|
|
504
|
-
// eslint-disable-next-line
|
|
505
|
-
while(this.state.data.find(item => item.id === id)) {
|
|
506
|
-
i++;
|
|
507
|
-
id = 'line_' + i;
|
|
508
|
-
}
|
|
509
|
-
|
|
510
|
-
data.push({
|
|
511
|
-
id,
|
|
512
|
-
name: I18n.t('New resource') + '_' + i,
|
|
513
|
-
color: '',
|
|
514
|
-
icon: '',
|
|
515
|
-
unit: '',
|
|
516
|
-
price: 0,
|
|
517
|
-
});
|
|
518
|
-
} else {
|
|
519
|
-
// existing line was modifed
|
|
520
|
-
const pos = this.state.data.indexOf(oldData);
|
|
521
|
-
if (pos !== -1) {
|
|
522
|
-
Object.keys(newData).forEach(attr => data[pos][attr] = newData[attr]);
|
|
523
|
-
}
|
|
524
|
-
}
|
|
525
|
-
|
|
526
|
-
this.setState({data});
|
|
527
|
-
}}
|
|
528
|
-
onDelete={oldData => {
|
|
529
|
-
console.log('Delete: ' + JSON.stringify(oldData));
|
|
530
|
-
const pos = this.state.data.indexOf(oldData);
|
|
531
|
-
if (pos !== -1) {
|
|
532
|
-
const data = JSON.parse(JSON.stringify(this.state.data));
|
|
533
|
-
data.splice(pos, 1);
|
|
534
|
-
this.setState({data});
|
|
535
|
-
}
|
|
536
|
-
}}
|
|
537
|
-
/>
|
|
538
|
-
</div>;
|
|
539
|
-
}
|
|
540
|
-
}
|
|
541
|
-
```
|
|
542
|
-
|
|
543
|
-
#### Toast
|
|
544
|
-
<!-- TODO: Provide screenshot here -->
|
|
545
|
-
|
|
546
|
-
Toast is not a part of `adapter-react` but it is an example how to use toast in application:
|
|
547
|
-
|
|
548
|
-
```
|
|
549
|
-
import Snackbar from '@material-ui/core/Snackbar';
|
|
550
|
-
|
|
551
|
-
class MyComponent {
|
|
552
|
-
constructor(props) {
|
|
553
|
-
super(props);
|
|
554
|
-
this.state = {
|
|
555
|
-
// ....
|
|
556
|
-
toast: '',
|
|
557
|
-
};
|
|
558
|
-
}
|
|
559
|
-
// ...
|
|
560
|
-
renderToast() {
|
|
561
|
-
if (!this.state.toast) {
|
|
562
|
-
return null;
|
|
563
|
-
}
|
|
564
|
-
return <Snackbar
|
|
565
|
-
anchorOrigin={{
|
|
566
|
-
vertical: 'bottom',
|
|
567
|
-
horizontal: 'left',
|
|
568
|
-
}}
|
|
569
|
-
open={true}
|
|
570
|
-
autoHideDuration={6000}
|
|
571
|
-
onClose={() => this.setState({toast: ''})}
|
|
572
|
-
ContentProps={{'aria-describedby': 'message-id'}}
|
|
573
|
-
message={<span id="message-id">{this.state.toast}</span>}
|
|
574
|
-
action={[
|
|
575
|
-
<IconButton
|
|
576
|
-
key="close"
|
|
577
|
-
aria-label="Close"
|
|
578
|
-
color="inherit"
|
|
579
|
-
className={this.props.classes.close}
|
|
580
|
-
onClick={() => this.setState({toast: ''})}
|
|
581
|
-
>
|
|
582
|
-
<IconClose />
|
|
583
|
-
</IconButton>,
|
|
584
|
-
]}
|
|
585
|
-
/>;
|
|
586
|
-
}
|
|
587
|
-
render() {
|
|
588
|
-
return <div>
|
|
589
|
-
{this.renderToast()}
|
|
590
|
-
</div>;
|
|
591
|
-
}
|
|
592
|
-
}
|
|
593
|
-
```
|
|
594
|
-
|
|
595
|
-
## List of adapters that use adapter-react
|
|
596
|
-
- Admin
|
|
597
|
-
-
|
|
598
|
-
-
|
|
599
|
-
-
|
|
600
|
-
-
|
|
601
|
-
-
|
|
602
|
-
-
|
|
603
|
-
-
|
|
604
|
-
-
|
|
605
|
-
-
|
|
606
|
-
-
|
|
607
|
-
- vis-2
|
|
608
|
-
-
|
|
609
|
-
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
- `"@
|
|
624
|
-
- `"@material-ui/
|
|
625
|
-
-
|
|
626
|
-
- Add `"
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
- All `@
|
|
631
|
-
-
|
|
632
|
-
- Change `import {
|
|
633
|
-
- Change `import
|
|
634
|
-
-
|
|
635
|
-
-
|
|
636
|
-
- Change
|
|
637
|
-
-
|
|
638
|
-
-
|
|
639
|
-
- Add to all `
|
|
640
|
-
-
|
|
641
|
-
-
|
|
642
|
-
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
- Look for
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
-
|
|
668
|
-
-
|
|
669
|
-
-
|
|
670
|
-
-
|
|
671
|
-
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
import {
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
-
|
|
695
|
-
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
1
|
+
# Help ReactJS classes for adapter config
|
|
2
|
+
You can find demo on https://github.com/ioBroker/adapter-react-demo
|
|
3
|
+
|
|
4
|
+
## Getting started
|
|
5
|
+
If you want to create the configuration page with ReactJS:
|
|
6
|
+
1. Create github repo for adapter.
|
|
7
|
+
2. execute `npx create-react-app src` . It will take a while.
|
|
8
|
+
3. `cd src`
|
|
9
|
+
4. Modify package.json file in src directory:
|
|
10
|
+
- Change `name` from `src` to `ADAPTERNAME-admin` (Of course replace `ADAPTERNAME` with yours)
|
|
11
|
+
- Add to devDependencies:
|
|
12
|
+
```
|
|
13
|
+
"@iobroker/adapter-react": "^4.0.10",
|
|
14
|
+
```
|
|
15
|
+
Versions can be higher.
|
|
16
|
+
So your src/package.json should look like:
|
|
17
|
+
```
|
|
18
|
+
{
|
|
19
|
+
"name": "ADAPTERNAME-admin",
|
|
20
|
+
"version": "0.1.0",
|
|
21
|
+
"private": true,
|
|
22
|
+
"dependencies": {
|
|
23
|
+
"react": "^18.2.0",
|
|
24
|
+
"react-dom": "^18.2.0",
|
|
25
|
+
"react-icons": "^4.6.0",
|
|
26
|
+
"react-scripts": "^5.0.1",
|
|
27
|
+
"@iobroker/adapter-react-v5": "^3.2.7",
|
|
28
|
+
"del": "^6.1.1",
|
|
29
|
+
"gulp": "^4.0.2"
|
|
30
|
+
},
|
|
31
|
+
"scripts": {
|
|
32
|
+
"start": "react-scripts start",
|
|
33
|
+
"build": "react-scripts build",
|
|
34
|
+
"test": "react-scripts test",
|
|
35
|
+
"eject": "react-scripts eject"
|
|
36
|
+
},
|
|
37
|
+
"eslintConfig": {
|
|
38
|
+
"extends": "react-app"
|
|
39
|
+
},
|
|
40
|
+
"homepage": ".",
|
|
41
|
+
"browserslist": [
|
|
42
|
+
">0.2%",
|
|
43
|
+
"not dead",
|
|
44
|
+
"not ie <= 11",
|
|
45
|
+
"not op_mini all"
|
|
46
|
+
]
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
5. Call in `src`: `npm install`
|
|
50
|
+
6. Copy gulpfile.js into `src`: `cp node_modules/@iobroker/adapter-react/gulpfile.js gulpfile.js`
|
|
51
|
+
7. Start your dummy application `npm run start` for developing or build with `npm run build` and
|
|
52
|
+
copy files in `build` directory to `www` or to `admin`. In the admin you must rename `index.html` to `index_m.html`.
|
|
53
|
+
8. You can do that with `gulp` tasks: `gulp build`, `gulp copy`, `gulp renameIndex` or `gulp renameTab`
|
|
54
|
+
|
|
55
|
+
## Development
|
|
56
|
+
1. Add `socket.io` to `public/index.html`.
|
|
57
|
+
After
|
|
58
|
+
|
|
59
|
+
```
|
|
60
|
+
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
insert
|
|
64
|
+
|
|
65
|
+
```
|
|
66
|
+
<script>
|
|
67
|
+
var script = document.createElement('script');
|
|
68
|
+
window.registerSocketOnLoad = function (cb) {
|
|
69
|
+
window.socketLoadedHandler = cb;
|
|
70
|
+
};
|
|
71
|
+
const parts = (window.location.search || '').replace(/^\?/, '').split('&');
|
|
72
|
+
const query = {};
|
|
73
|
+
parts.forEach(item => {
|
|
74
|
+
const [name, val] = item.split('=');
|
|
75
|
+
query[decodeURIComponent(name)] = val !== undefined ? decodeURIComponent(val) : true;
|
|
76
|
+
});
|
|
77
|
+
script.onload = function () { typeof window.socketLoadedHandler === 'function' && window.socketLoadedHandler(); };
|
|
78
|
+
script.src = window.location.port === '3000' ? window.location.protocol + '//' + (query.host || window.location.hostname) + ':' + (query.port || 8081) + '/lib/js/socket.io.js' : '%PUBLIC_URL%/../../lib/js/socket.io.js';
|
|
79
|
+
|
|
80
|
+
document.head.appendChild(script);
|
|
81
|
+
</script>
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
3. Add to App.js constructor initialization for I18n:
|
|
85
|
+
```
|
|
86
|
+
class App extends GenericApp {
|
|
87
|
+
constructor(props) {
|
|
88
|
+
const extendedProps = {...props};
|
|
89
|
+
extendedProps.encryptedFields = ['pass']; // this parameter will be encrypted and decrypted automatically
|
|
90
|
+
extendedProps.translations = {
|
|
91
|
+
'en': require('./i18n/en'),
|
|
92
|
+
'de': require('./i18n/de'),
|
|
93
|
+
'ru': require('./i18n/ru'),
|
|
94
|
+
'pt': require('./i18n/pt'),
|
|
95
|
+
'nl': require('./i18n/nl'),
|
|
96
|
+
'fr': require('./i18n/fr'),
|
|
97
|
+
'it': require('./i18n/it'),
|
|
98
|
+
'es': require('./i18n/es'),
|
|
99
|
+
'pl': require('./i18n/pl'),
|
|
100
|
+
'uk': require('./i18n/uk'),
|
|
101
|
+
'zh-cn': require('./i18n/zh-cn'),
|
|
102
|
+
};
|
|
103
|
+
// get actual admin port
|
|
104
|
+
extendedProps.socket = {port: parseInt(window.location.port, 10)};
|
|
105
|
+
|
|
106
|
+
// Only if close, save buttons are not required at the bottom (e.g. if admin tab)
|
|
107
|
+
// extendedProps.bottomButtons = false;
|
|
108
|
+
|
|
109
|
+
// only for debug purposes
|
|
110
|
+
if (extendedProps.socket.port === 3000) {
|
|
111
|
+
extendedProps.socket.port = 8081;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// allow to manage GenericApp the sentry initialisation or do not set the sentryDSN if no sentry available
|
|
115
|
+
extendedProps.sentryDSN = 'https://yyy@sentry.iobroker.net/xx';
|
|
116
|
+
|
|
117
|
+
super(extendedProps);
|
|
118
|
+
}
|
|
119
|
+
...
|
|
120
|
+
}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
4. Replace `index.js` with the following code to support themes:
|
|
124
|
+
```
|
|
125
|
+
import React from 'react';
|
|
126
|
+
import ReactDOM from 'react-dom';
|
|
127
|
+
import { MuiThemeProvider} from '@material-ui/core/styles';
|
|
128
|
+
import * as serviceWorker from './serviceWorker';
|
|
129
|
+
|
|
130
|
+
import './index.css';
|
|
131
|
+
import App from './App';
|
|
132
|
+
import { version } from '../package.json';
|
|
133
|
+
|
|
134
|
+
import theme from '@iobroker/adapter-react/Theme';
|
|
135
|
+
|
|
136
|
+
console.log('iobroker.scenes@' + version);
|
|
137
|
+
let themeName = window.localStorage ? window.localStorage.getItem('App.theme') || 'light' : 'light';
|
|
138
|
+
|
|
139
|
+
function build() {
|
|
140
|
+
return ReactDOM.render(<MuiThemeProvider theme={ theme(themeName) }>
|
|
141
|
+
<App onThemeChange={_theme => {
|
|
142
|
+
themeName = _theme;
|
|
143
|
+
build();
|
|
144
|
+
}}/>
|
|
145
|
+
</MuiThemeProvider>, document.getElementById('root'));
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
build();
|
|
149
|
+
|
|
150
|
+
// If you want your app to work offline and load faster, you can change
|
|
151
|
+
// unregister() to register() below. Note this comes with some pitfalls.
|
|
152
|
+
// Learn more about service workers: http://bit.ly/CRA-PWA
|
|
153
|
+
serviceWorker.unregister();
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
5. Add to App.js encoding and decoding of values:
|
|
157
|
+
```
|
|
158
|
+
class App extend GenericApp {
|
|
159
|
+
...
|
|
160
|
+
onPrepareLoad(settings) {
|
|
161
|
+
settings.pass = this.decode(settings.pass);
|
|
162
|
+
}
|
|
163
|
+
onPrepareSave(settings) {
|
|
164
|
+
settings.pass = this.encode(settings.pass);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
6. The optional step is to validate the data to be saved:
|
|
170
|
+
```
|
|
171
|
+
onPrepareSave(settings) {
|
|
172
|
+
super.onPrepareSave(settings);
|
|
173
|
+
if (DATA_INVALID) {
|
|
174
|
+
return false; // configuration will not be saved
|
|
175
|
+
} else {
|
|
176
|
+
return true;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
## Components
|
|
182
|
+
|
|
183
|
+
### Connection.tsx
|
|
184
|
+
This is a non-react class to provide the communication for socket connection with the server.
|
|
185
|
+
|
|
186
|
+
### GenericApp.tsx
|
|
187
|
+
|
|
188
|
+
### i18n.ts
|
|
189
|
+
|
|
190
|
+
### Theme.tsx
|
|
191
|
+
|
|
192
|
+
### Dialogs
|
|
193
|
+
Some dialogs are predefined and could be used out of the box.
|
|
194
|
+
|
|
195
|
+
#### Confirm.tsx
|
|
196
|
+
<!-- TODO: Provide screenshot here -->
|
|
197
|
+
|
|
198
|
+
Usage:
|
|
199
|
+
```
|
|
200
|
+
import React from 'react';
|
|
201
|
+
import ConfirmDialog from '@iobroker/adapter-react/Dialogs/Confirm'
|
|
202
|
+
import I18n from '@iobroker/adapter-react/i18n';
|
|
203
|
+
|
|
204
|
+
class ExportImportDialog extends React.Component {
|
|
205
|
+
constructor(props) {
|
|
206
|
+
super(props);
|
|
207
|
+
|
|
208
|
+
this.state = {
|
|
209
|
+
confirmDialog: false,
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
renderConfirmDialog() {
|
|
214
|
+
if (!this.state.confirmDialog) {
|
|
215
|
+
return null;
|
|
216
|
+
}
|
|
217
|
+
return <ConfirmDialog
|
|
218
|
+
title={ I18n.t('Scene will be overwritten.') }
|
|
219
|
+
text={ I18n.t('All data will be lost. Confirm?') }
|
|
220
|
+
ok={ I18n.t('Yes') }
|
|
221
|
+
cancel={ I18n.t('Cancel') }
|
|
222
|
+
suppressQuestionMinutes={5}
|
|
223
|
+
dialogName="myConfirmDialogThatCouldBeSuppressed"
|
|
224
|
+
suppressText={I18n.t('Suppress question for next %s minutes', 5)}
|
|
225
|
+
onClose={isYes => {
|
|
226
|
+
this.setState({ confirmDialog: false} );
|
|
227
|
+
}}
|
|
228
|
+
/>;
|
|
229
|
+
}
|
|
230
|
+
render() {
|
|
231
|
+
return <div>
|
|
232
|
+
<Button onClick={ () => this.setState({confirmDialog: true}) }>Click</Button>
|
|
233
|
+
{ this.renderConfirmDialog() }
|
|
234
|
+
</div>
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
export default ExportImportDialog;
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
#### Error.tsx
|
|
242
|
+
<!-- TODO: Provide screenshot here -->
|
|
243
|
+
|
|
244
|
+
#### Message.tsx
|
|
245
|
+
<!-- TODO: Provide screenshot here -->
|
|
246
|
+
```
|
|
247
|
+
renderMessage() {
|
|
248
|
+
if (this.state.showMessage) {
|
|
249
|
+
return <Message
|
|
250
|
+
text={this.state.showMessage}
|
|
251
|
+
onClose={() => this.setState({showMessage: false})}
|
|
252
|
+
/>;
|
|
253
|
+
} else {
|
|
254
|
+
return null;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
#### SelectID.tsx
|
|
260
|
+

|
|
261
|
+
```
|
|
262
|
+
import DialogSelectID from '@iobroker/adapter-react/Dialogs/SelectID';
|
|
263
|
+
|
|
264
|
+
class MyComponent extends Component {
|
|
265
|
+
constructor(props) {
|
|
266
|
+
super(props);
|
|
267
|
+
this.state = {
|
|
268
|
+
showSelectId: false,
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
renderSelectIdDialog() {
|
|
273
|
+
if (this.state.showSelectId) {
|
|
274
|
+
return <DialogSelectID
|
|
275
|
+
key="tableSelect"
|
|
276
|
+
imagePrefix="../.."
|
|
277
|
+
dialogName={this.props.adapterName}
|
|
278
|
+
themeType={this.props.themeType}
|
|
279
|
+
socket={this.props.socket}
|
|
280
|
+
statesOnly={true}
|
|
281
|
+
selected={this.state.selectIdValue}
|
|
282
|
+
onClose={() => this.setState({showSelectId: false})}
|
|
283
|
+
onOk={(selected, name) => {
|
|
284
|
+
this.setState({showSelectId: false, selectIdValue: selected});
|
|
285
|
+
}}
|
|
286
|
+
/>;
|
|
287
|
+
} else {
|
|
288
|
+
return null;
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
render() {
|
|
292
|
+
return renderSelectIdDialog();
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
#### Cron
|
|
298
|
+
Include `"react-text-mask": "^5.4.3",` in package.json.
|
|
299
|
+
|
|
300
|
+
<!-- TODO: Provide screenshot here -->
|
|
301
|
+
|
|
302
|
+
```
|
|
303
|
+
function renderCron() {
|
|
304
|
+
if (!showCron) {
|
|
305
|
+
return null;
|
|
306
|
+
} else {
|
|
307
|
+
return <DialogCron
|
|
308
|
+
key="dialogCron1"
|
|
309
|
+
cron={this.state.cronValue || '* * * * *'}
|
|
310
|
+
onClose={() => this.setState({ showCron: false })}
|
|
311
|
+
onOk={cronValue => {
|
|
312
|
+
this.setState({ cronValue })
|
|
313
|
+
}}
|
|
314
|
+
/>;
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
### Components
|
|
320
|
+
|
|
321
|
+
#### Utils.tsx
|
|
322
|
+
##### getObjectNameFromObj
|
|
323
|
+
`getObjectNameFromObj(obj, settings, options, isDesc)`
|
|
324
|
+
|
|
325
|
+
Get object name from a single object.
|
|
326
|
+
|
|
327
|
+
Usage: `Utils.getObjectNameFromObj(this.objects[id], null, {language: I18n.getLanguage()})`
|
|
328
|
+
|
|
329
|
+
##### getObjectIcon
|
|
330
|
+
`getObjectIcon(id, obj)`
|
|
331
|
+
|
|
332
|
+
Get icon from the object.
|
|
333
|
+
|
|
334
|
+
Usage:
|
|
335
|
+
```
|
|
336
|
+
const icon = Utils.getObjectIcon(id, this.objects[id]);
|
|
337
|
+
return (<img src={icon}/>);
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
##### isUseBright
|
|
341
|
+
`isUseBright(color, defaultValue)`
|
|
342
|
+
|
|
343
|
+
Usage: `
|
|
344
|
+
|
|
345
|
+
#### Loader.tsx
|
|
346
|
+

|
|
347
|
+
|
|
348
|
+
```
|
|
349
|
+
render() {
|
|
350
|
+
if (!this.state.loaded) {
|
|
351
|
+
return <MuiThemeProvider theme={this.state.theme}>
|
|
352
|
+
<Loader theme={this.state.themeType}/>
|
|
353
|
+
</MuiThemeProvider>;
|
|
354
|
+
}
|
|
355
|
+
// render loaded data
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
#### Logo.tsx
|
|
361
|
+

|
|
362
|
+
|
|
363
|
+
```
|
|
364
|
+
render() {
|
|
365
|
+
return <form className={this.props.classes.tab}>
|
|
366
|
+
<Logo
|
|
367
|
+
instance={this.props.instance}
|
|
368
|
+
common={this.props.common}
|
|
369
|
+
native={this.props.native}
|
|
370
|
+
onError={text => this.setState({errorText: text})}
|
|
371
|
+
onLoad={this.props.onLoad}
|
|
372
|
+
/>
|
|
373
|
+
...
|
|
374
|
+
</form>;
|
|
375
|
+
}
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
#### Router.tsx
|
|
379
|
+
|
|
380
|
+
#### ObjectBrowser.js
|
|
381
|
+
It is better to use `Dialog/SelectID`, but if you want:
|
|
382
|
+
|
|
383
|
+

|
|
384
|
+
|
|
385
|
+
```
|
|
386
|
+
<ObjectBrowser
|
|
387
|
+
foldersFirst={this.props.foldersFirst}
|
|
388
|
+
imagePrefix={this.props.imagePrefix || this.props.prefix} // prefix is for back compatibility
|
|
389
|
+
defaultFilters={this.filters}
|
|
390
|
+
dialogName={this.dialogName}
|
|
391
|
+
showExpertButton={this.props.showExpertButton !== undefined ? this.props.showExpertButton : true}
|
|
392
|
+
style={{ width: '100%', height: '100%' }}
|
|
393
|
+
columns={this.props.columns || ['name', 'type', 'role', 'room', 'func', 'val']}
|
|
394
|
+
types={this.props.types || ['state']}
|
|
395
|
+
t={I18n.t}
|
|
396
|
+
lang={this.props.lang || I18n.getLanguage()}
|
|
397
|
+
socket={this.props.socket}
|
|
398
|
+
selected={this.state.selected}
|
|
399
|
+
multiSelect={this.props.multiSelect}
|
|
400
|
+
notEditable={this.props.notEditable === undefined ? true : this.props.notEditable}
|
|
401
|
+
name={this.state.name}
|
|
402
|
+
themeName={this.props.themeName}
|
|
403
|
+
themeType={this.props.themeType}
|
|
404
|
+
customFilter={this.props.customFilter}
|
|
405
|
+
onFilterChanged={filterConfig => {
|
|
406
|
+
this.filters = filterConfig;
|
|
407
|
+
window.localStorage.setItem(this.dialogName, JSON.stringify(filterConfig));
|
|
408
|
+
}}
|
|
409
|
+
onSelect={(selected, name, isDouble) => {
|
|
410
|
+
if (JSON.stringify(selected) !== JSON.stringify(this.state.selected)) {
|
|
411
|
+
this.setState({selected, name}, () =>
|
|
412
|
+
isDouble && this.handleOk());
|
|
413
|
+
} else if (isDouble) {
|
|
414
|
+
this.handleOk();
|
|
415
|
+
}
|
|
416
|
+
}}
|
|
417
|
+
/>
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
#### TreeTable.ts
|
|
421
|
+

|
|
422
|
+
|
|
423
|
+
```
|
|
424
|
+
// STYLES
|
|
425
|
+
const styles = theme => ({
|
|
426
|
+
tableDiv: {
|
|
427
|
+
width: '100%',
|
|
428
|
+
overflow: 'hidden',
|
|
429
|
+
height: 'calc(100% - 48px)',
|
|
430
|
+
},
|
|
431
|
+
});
|
|
432
|
+
class MyComponent extends Component {
|
|
433
|
+
constructor(props) {
|
|
434
|
+
super(props);
|
|
435
|
+
|
|
436
|
+
this.state = {
|
|
437
|
+
data: [
|
|
438
|
+
{
|
|
439
|
+
id: 'UniqueID1' // required
|
|
440
|
+
fieldIdInData: 'Name1',
|
|
441
|
+
myType: 'number',
|
|
442
|
+
},
|
|
443
|
+
{
|
|
444
|
+
id: 'UniqueID2' // required
|
|
445
|
+
fieldIdInData: 'Name12',
|
|
446
|
+
myType: 'string',
|
|
447
|
+
},
|
|
448
|
+
],
|
|
449
|
+
};
|
|
450
|
+
|
|
451
|
+
this.columns = [
|
|
452
|
+
{
|
|
453
|
+
title: 'Name of field', // required, else it will be "field"
|
|
454
|
+
field: 'fieldIdInData', // required
|
|
455
|
+
editable: false, // or true [default - true]
|
|
456
|
+
cellStyle: { // CSS style - // optional
|
|
457
|
+
maxWidth: '12rem',
|
|
458
|
+
overflow: 'hidden',
|
|
459
|
+
wordBreak: 'break-word',
|
|
460
|
+
},
|
|
461
|
+
lookup: { // optional => edit will be automatically "SELECT"
|
|
462
|
+
'value1': 'text1',
|
|
463
|
+
'value2': 'text2',
|
|
464
|
+
}
|
|
465
|
+
},
|
|
466
|
+
{
|
|
467
|
+
title: 'Type', // required, else it will be "field"
|
|
468
|
+
field: 'myType', // required
|
|
469
|
+
editable: true, // or true [default - true]
|
|
470
|
+
lookup: { // optional => edit will be automatically "SELECT"
|
|
471
|
+
'number': 'Number',
|
|
472
|
+
'string': 'String',
|
|
473
|
+
'boolean': 'Boolean',
|
|
474
|
+
},
|
|
475
|
+
type: 'number/string/color/oid/icon/boolean', // oid=ObjectID,icon=base64-icon
|
|
476
|
+
editComponent: props =>
|
|
477
|
+
<div>Prefix{ <br/>
|
|
478
|
+
<textarea
|
|
479
|
+
rows={4}
|
|
480
|
+
style={{width: '100%', resize: 'vertical'}}
|
|
481
|
+
value={props.value}
|
|
482
|
+
onChange={e => props.onChange(e.target.value)}
|
|
483
|
+
/>
|
|
484
|
+
Suffix
|
|
485
|
+
</div>,
|
|
486
|
+
},
|
|
487
|
+
];
|
|
488
|
+
}
|
|
489
|
+
// renderTable
|
|
490
|
+
render() {
|
|
491
|
+
return <div className={this.props.classes.tableDiv}>
|
|
492
|
+
<TreeTable
|
|
493
|
+
columns={this.columns}
|
|
494
|
+
data={this.state.data}
|
|
495
|
+
onUpdate={(newData, oldData) => {
|
|
496
|
+
const data = JSON.parse(JSON.stringify(this.state.data));
|
|
497
|
+
|
|
498
|
+
// Added new line
|
|
499
|
+
if (newData === true) {
|
|
500
|
+
// find unique ID
|
|
501
|
+
let i = 1;
|
|
502
|
+
let id = 'line_' + i;
|
|
503
|
+
|
|
504
|
+
// eslint-disable-next-line
|
|
505
|
+
while(this.state.data.find(item => item.id === id)) {
|
|
506
|
+
i++;
|
|
507
|
+
id = 'line_' + i;
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
data.push({
|
|
511
|
+
id,
|
|
512
|
+
name: I18n.t('New resource') + '_' + i,
|
|
513
|
+
color: '',
|
|
514
|
+
icon: '',
|
|
515
|
+
unit: '',
|
|
516
|
+
price: 0,
|
|
517
|
+
});
|
|
518
|
+
} else {
|
|
519
|
+
// existing line was modifed
|
|
520
|
+
const pos = this.state.data.indexOf(oldData);
|
|
521
|
+
if (pos !== -1) {
|
|
522
|
+
Object.keys(newData).forEach(attr => data[pos][attr] = newData[attr]);
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
this.setState({data});
|
|
527
|
+
}}
|
|
528
|
+
onDelete={oldData => {
|
|
529
|
+
console.log('Delete: ' + JSON.stringify(oldData));
|
|
530
|
+
const pos = this.state.data.indexOf(oldData);
|
|
531
|
+
if (pos !== -1) {
|
|
532
|
+
const data = JSON.parse(JSON.stringify(this.state.data));
|
|
533
|
+
data.splice(pos, 1);
|
|
534
|
+
this.setState({data});
|
|
535
|
+
}
|
|
536
|
+
}}
|
|
537
|
+
/>
|
|
538
|
+
</div>;
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
```
|
|
542
|
+
|
|
543
|
+
#### Toast
|
|
544
|
+
<!-- TODO: Provide screenshot here -->
|
|
545
|
+
|
|
546
|
+
Toast is not a part of `adapter-react` but it is an example how to use toast in application:
|
|
547
|
+
|
|
548
|
+
```
|
|
549
|
+
import Snackbar from '@material-ui/core/Snackbar';
|
|
550
|
+
|
|
551
|
+
class MyComponent {
|
|
552
|
+
constructor(props) {
|
|
553
|
+
super(props);
|
|
554
|
+
this.state = {
|
|
555
|
+
// ....
|
|
556
|
+
toast: '',
|
|
557
|
+
};
|
|
558
|
+
}
|
|
559
|
+
// ...
|
|
560
|
+
renderToast() {
|
|
561
|
+
if (!this.state.toast) {
|
|
562
|
+
return null;
|
|
563
|
+
}
|
|
564
|
+
return <Snackbar
|
|
565
|
+
anchorOrigin={{
|
|
566
|
+
vertical: 'bottom',
|
|
567
|
+
horizontal: 'left',
|
|
568
|
+
}}
|
|
569
|
+
open={true}
|
|
570
|
+
autoHideDuration={6000}
|
|
571
|
+
onClose={() => this.setState({toast: ''})}
|
|
572
|
+
ContentProps={{'aria-describedby': 'message-id'}}
|
|
573
|
+
message={<span id="message-id">{this.state.toast}</span>}
|
|
574
|
+
action={[
|
|
575
|
+
<IconButton
|
|
576
|
+
key="close"
|
|
577
|
+
aria-label="Close"
|
|
578
|
+
color="inherit"
|
|
579
|
+
className={this.props.classes.close}
|
|
580
|
+
onClick={() => this.setState({toast: ''})}
|
|
581
|
+
>
|
|
582
|
+
<IconClose />
|
|
583
|
+
</IconButton>,
|
|
584
|
+
]}
|
|
585
|
+
/>;
|
|
586
|
+
}
|
|
587
|
+
render() {
|
|
588
|
+
return <div>
|
|
589
|
+
{this.renderToast()}
|
|
590
|
+
</div>;
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
```
|
|
594
|
+
|
|
595
|
+
## List of adapters that use adapter-react
|
|
596
|
+
- Admin
|
|
597
|
+
- iot
|
|
598
|
+
- echarts
|
|
599
|
+
- text2command
|
|
600
|
+
- scenes
|
|
601
|
+
- javascript
|
|
602
|
+
- devices
|
|
603
|
+
- eventlist
|
|
604
|
+
- cameras
|
|
605
|
+
- web
|
|
606
|
+
- vis-2
|
|
607
|
+
- vis-2-widgets-xxx
|
|
608
|
+
- fullcalendar
|
|
609
|
+
- openweathermap
|
|
610
|
+
|
|
611
|
+
## Usability
|
|
612
|
+
In dialogs, the OK button is first (on the left) and the cancel button is last (on the right)
|
|
613
|
+
|
|
614
|
+
## Used icons
|
|
615
|
+
This project uses icons from [Flaticon](https://www.flaticon.com/).
|
|
616
|
+
|
|
617
|
+
ioBroker GmbH has a valid license for all the used icons.
|
|
618
|
+
The icons may not be reused in other projects without the proper flaticon license or flaticon subscription.
|
|
619
|
+
|
|
620
|
+
## Migration from adapter-react to adapter-react-v5
|
|
621
|
+
### In src/package.json => dependencies
|
|
622
|
+
- `"@iobroker/adapter-react": "^2.0.22",` => `"@iobroker/adapter-react-v5": "^3.1.34",`
|
|
623
|
+
- `"@material-ui/core": "^4.12.3",` => `"@mui/material": "^5.10.9",`
|
|
624
|
+
- `"@material-ui/icons": "^4.11.2",` => `"@mui/icons-material": "^5.10.9",`
|
|
625
|
+
- Add `"@mui/styles": "^5.10.9",`
|
|
626
|
+
- Add `"babel-eslint": "^10.1.0",`
|
|
627
|
+
|
|
628
|
+
### In Source files
|
|
629
|
+
- All `@iobroker/adapter-react/...` => `@iobroker/adapter-react-v5/...`
|
|
630
|
+
- All `@material-ui/icons/...` => `@mui/icons-material/...`
|
|
631
|
+
- Change `import { withStyles } from '@material-ui/core/styles';` => `import { withStyles } from '@mui/styles';`
|
|
632
|
+
- Change `import { makeStyles } from '@mui/material/styles';` => `import { makeStyles } from '@mui/styles';`
|
|
633
|
+
- Change `import withWidth from '@material-ui/core/withWidth';` => `import { withWidth } from '@iobroker/adapter-react-v5';`
|
|
634
|
+
- All `@material-ui/core...` => `@mui/material...`
|
|
635
|
+
- Change `import { MuiThemeProvider } from '@material-ui/core/styles';` => `import { ThemeProvider, StyledEngineProvider } from '@mui/material/styles';`
|
|
636
|
+
- Change all `<MuiThemeProvider theme={this.state.theme}>` to `<StyledEngineProvider injectFirst><ThemeProvider theme={this.state.theme}>`
|
|
637
|
+
- Rename in styles `theme.palette.type` => `theme.palette.mode`
|
|
638
|
+
- Add to all `TextField`, `Select`, `FormControl` the property `variant="standard"`
|
|
639
|
+
- Add to all `Button` that do not have `color` property: `color="grey"`
|
|
640
|
+
- Replace by `TextField` the `readOnly` attribute (if exists) with `InputProps={{readOnly: true}}`
|
|
641
|
+
- Remove px by all `theme.spacing`: `calc(100% - ${theme.spacing(4)}px)` => `calc(100% - ${theme.spacing(4)})`
|
|
642
|
+
- Replace `this.selectTab(e.target.parentNode.dataset.name, index)` => `this.selectTab(e.target.dataset.name, index)`
|
|
643
|
+
|
|
644
|
+
If you still have questions, try to find an answer [here](https://mui.com/guides/migration-v4/).
|
|
645
|
+
|
|
646
|
+
## Migration from adapter-react-v5@3.x to adapter-react-v5@4.x
|
|
647
|
+
- Look for getObjectView socket requests and replace `socket.getObjectView('startKey', 'endKey', 'instance')` to `socket.getObjectViewSystem('instance', 'startKey', 'endKey')`
|
|
648
|
+
- Look for calls of custom like
|
|
649
|
+
```
|
|
650
|
+
this.props.socket._socket.emit('getObjectView', 'system', 'custom', {startKey: '', endKey:'\u9999'}, (err, objs) => {
|
|
651
|
+
(objs?.rows || [])
|
|
652
|
+
.forEach(item => console.log(item.id, item.value));
|
|
653
|
+
});
|
|
654
|
+
```
|
|
655
|
+
to
|
|
656
|
+
```
|
|
657
|
+
socket.getObjectViewCustom('custom', 'state', 'startKey', 'endKey')
|
|
658
|
+
.then(objects => {
|
|
659
|
+
Object.keys(objects).forEach(obj => console.log(obj._id));
|
|
660
|
+
});
|
|
661
|
+
```
|
|
662
|
+
- Replace all `socket.log.error('text')` to `socket.log('text', 'error')`
|
|
663
|
+
- Add to App.js `import { AdminConnection } from '@iobroker/adapter-react-v5';` and `super(props, { Connection: AdminConnection });` if run in admin
|
|
664
|
+
|
|
665
|
+
## Migration from adapter-react-v5@4.x to adapter-react-v5@5.x
|
|
666
|
+
- `Theme` is renamed to IobTheme. It is an object with classes inside. `Theme` is still inside and it same as mui `createTheme`.
|
|
667
|
+
- adapter-react-v5 has all types exported. So you can use `import { type IobTheme, Theme } from '@iobroker/adapter-react-v5';` and `const theme: IobTheme = Theme('light');`
|
|
668
|
+
- Json-Config is now an external package and must be included as dependency separately.
|
|
669
|
+
- Use type `Translate` for `t(word: string, ...args: any[]) => string`
|
|
670
|
+
- All components for admin JsonConfig must be changed:
|
|
671
|
+
Before `adapter-react-v5@5.x`:
|
|
672
|
+
|
|
673
|
+
```
|
|
674
|
+
import { ConfigGeneric, I18n } from '@iobroker/adapter-react-v5';
|
|
675
|
+
class JsonComponent extends ConfigGeneric {
|
|
676
|
+
...
|
|
677
|
+
}
|
|
678
|
+
```
|
|
679
|
+
|
|
680
|
+
With `adapter-react-v5@5.x`:
|
|
681
|
+
|
|
682
|
+
```
|
|
683
|
+
import { I18n } from '@iobroker/adapter-react-v5';
|
|
684
|
+
import { ConfigGeneric } from '@iobroker/json-config';
|
|
685
|
+
class JsonComponent extends ConfigGeneric {
|
|
686
|
+
...
|
|
687
|
+
}
|
|
688
|
+
```
|
|
689
|
+
## Migration from v5 to v6
|
|
690
|
+
The main change is that the `withStyles` was removed. So you have to replace all `withStyles` with `sx` or `style` properties.
|
|
691
|
+
|
|
692
|
+
You can read more about sx [here](https://mui.com/system/getting-started/the-sx-prop/).
|
|
693
|
+
- Remove at start of the file `import { withStyles } from '@mui/styles';`
|
|
694
|
+
- Replace at the very end of the file `export default withStyles(styles)(MyComponent);` with `export default MyComponent;`
|
|
695
|
+
- Modify `const styles`:
|
|
696
|
+
Before:
|
|
697
|
+
```
|
|
698
|
+
const styles: Record<string, any> = (theme: IobTheme) => ({
|
|
699
|
+
dialog: {
|
|
700
|
+
height: `calc(100% - ${theme.mixins.toolbar.minHeight}px)`,
|
|
701
|
+
padding: theme.spacing(1),
|
|
702
|
+
margin: theme.spacing(2),
|
|
703
|
+
gap: 5,
|
|
704
|
+
borderRadius: 5,
|
|
705
|
+
marginLeft: 10, // marginTop, marginRight, marginBottom
|
|
706
|
+
paddingLeft: 10, // paddingTop, paddingRight, paddingBottom
|
|
707
|
+
},
|
|
708
|
+
...
|
|
709
|
+
});
|
|
710
|
+
```
|
|
711
|
+
|
|
712
|
+
After:
|
|
713
|
+
```
|
|
714
|
+
const styles: Record<string, any> = {
|
|
715
|
+
dialog: (theme: IobTheme) => ({
|
|
716
|
+
height: `calc(100% - ${theme => theme.mixins.toolbar.minHeight}px)`,
|
|
717
|
+
p: 1, // or 8px, padding is OK too
|
|
718
|
+
m: '16px', // or 2, margin is OK too
|
|
719
|
+
gap: '5px',
|
|
720
|
+
borderRadius: '5px',
|
|
721
|
+
ml: '10px', // mt, mr, mb, but marginLeft, marginRight, marginBottom is OK too
|
|
722
|
+
pl: '10px', // pt, pr, pb, but paddingTop, paddingRight, paddingBottom is OK too
|
|
723
|
+
}),
|
|
724
|
+
};
|
|
725
|
+
```
|
|
726
|
+
|
|
727
|
+
- Modify `className`:
|
|
728
|
+
Before: `<div className={this.props.classes.box}>`
|
|
729
|
+
|
|
730
|
+
After: `<Box sx={styles.box}>`
|
|
731
|
+
|
|
732
|
+
Before: `<span className={Utils.clsx(this.props.classes.box1, condition && this.props.classes.box2)}>`
|
|
733
|
+
|
|
734
|
+
After: `<Box component="span" sx={Utils.getStyle(this.props.theme, this.props.classes.box1, condition && this.props.classes.box2)}>`
|
|
735
|
+
Or if no one style is a function: `<Box component="div" sx={{ ...this.props.classes.box1, ...(condition ? this.props.classes.box2 : undefined) }}>`
|
|
736
|
+
|
|
737
|
+
Do not use `sx` if the style is not dynamic (not a function). Use `style` instead.
|
|
738
|
+
|
|
739
|
+
Be aware, that all paddings and margins are now in `theme.spacing(1)` format.
|
|
740
|
+
So you have to replace all `padding: 8` with `padding: 1` or with `padding: '8px'`.
|
|
741
|
+
|
|
742
|
+
The best practice is to replace `padding` with `p` and `margin` with `m`, so you will see immediately that it is a padding or margin for `sx` property.
|
|
743
|
+
|
|
744
|
+
- Modify `classes`:
|
|
745
|
+
Before: `<Dialog classes={{ scrollPaper: this.props.classes.dialog, paper: this.props.classes.paper }}>`
|
|
746
|
+
|
|
747
|
+
After: `<Dialog sx={{ '&.MuiDialog-scrollPaper': styles.dialog, '& .MuiDialog-paper': styles.paper }}>`
|
|
748
|
+
|
|
749
|
+
Before: `<Dialog classes={{ scrollPaper: this.props.classes.dialog, paper: this.props.classes.paper }}>`
|
|
750
|
+
|
|
751
|
+
After: `<Dialog sx={{ '&.MuiDialog-scrollPaper': styles.dialog, '& .MuiDialog-paper': styles.paper }}>`
|
|
752
|
+
|
|
753
|
+
Before: `<ListItem classes={{ root: styles.listItem }} >`
|
|
754
|
+
|
|
755
|
+
After: `<ListItem sx={{ '&.MuiListItem-root': styles.listItem }} >`
|
|
756
|
+
|
|
757
|
+
Before: `<Typography component="h2" variant="h6" classes={{ root: styles.typography }}>`
|
|
758
|
+
|
|
759
|
+
After: `<Typography component="h2" variant="h6" sx={{ '&.MuiTypography-root': styles.typography }}>`
|
|
760
|
+
|
|
761
|
+
Before: `<Badge classes={{ 'badge': styles.expertBadge }}>`
|
|
762
|
+
|
|
763
|
+
After: `<Badge sx={{ '& .MuiBadge-badge': styles.expertBadge }}>`
|
|
764
|
+
|
|
765
|
+
Before: `<Tab classes={{ selected: styles.selected }} />`
|
|
766
|
+
|
|
767
|
+
After: `<Tab sx={{ '&.Mui-selected': styles.selected }} />`
|
|
768
|
+
|
|
769
|
+
Before: `<Tooltip title={this.props.t('ra_Refresh tree')} classes={{ popper: styles.tooltip }}>`
|
|
770
|
+
|
|
771
|
+
After: `<Tooltip title={this.props.t('ra_Refresh tree')} componentsProps={{ popper: { sx: { pointerEvents: 'none' } } }}>`
|
|
772
|
+
Or: `<Tooltip title={this.props.t('ra_Refresh tree')} componentsProps={{ popper: { sx: styles.tooltip } }}>`
|
|
773
|
+
|
|
774
|
+
Before. `<AccordionSummary classes={{ root: styles.rootStyle, content: styles.content }}>`
|
|
775
|
+
|
|
776
|
+
After. `<AccordionSummary sx={{ '&.MuiAccordionSummary-root': styles.rootStyle, '& .MuiAccordionSummary-content': styles.content }}>`
|
|
777
|
+
|
|
778
|
+
Before. `<Drawer classes={{ paper: styles.paperStyle }}>`
|
|
779
|
+
|
|
780
|
+
After. `<Drawer sx={{ '& .MuiDrawer-paper': styles.paperStyle }}>`
|
|
781
|
+
|
|
782
|
+
<!--
|
|
783
|
+
Placeholder for the next version (at the beginning of the line):
|
|
784
|
+
### **WORK IN PROGRESS**
|
|
785
|
+
-->
|
|
786
|
+
|
|
788
787
|
## Changelog
|
|
789
|
-
### 6.1.
|
|
790
|
-
* (bluefox) Updated JSON schema
|
|
791
|
-
|
|
792
|
-
### 6.1.8 (2024-08-03)
|
|
788
|
+
### 6.1.7 (2024-08-03)
|
|
793
789
|
* (bluefox) Added translations
|
|
794
790
|
|
|
795
|
-
### 6.1.6 (2024-07-23)
|
|
791
|
+
### 6.1.6 (2024-07-23)
|
|
796
792
|
* (bluefox) Optimize package
|
|
797
793
|
|
|
798
|
-
### 6.1.5 (2024-07-20)
|
|
794
|
+
### 6.1.5 (2024-07-20)
|
|
799
795
|
* (bluefox) Added sources to package
|
|
800
796
|
|
|
801
|
-
### 6.1.3 (2024-07-20)
|
|
797
|
+
### 6.1.3 (2024-07-20)
|
|
802
798
|
* (bluefox) Better typing of legacy connection
|
|
803
799
|
|
|
804
|
-
### 6.1.1 (2024-07-16)
|
|
800
|
+
### 6.1.1 (2024-07-16)
|
|
805
801
|
* (bluefox) Added translations
|
|
806
802
|
|
|
807
|
-
### 6.1.0 (2024-07-15)
|
|
803
|
+
### 6.1.0 (2024-07-15)
|
|
808
804
|
* (bluefox) Replace by CRON to text the package to `cronstrue`
|
|
809
805
|
|
|
810
|
-
### 6.0.19 (2024-07-14)
|
|
806
|
+
### 6.0.19 (2024-07-14)
|
|
811
807
|
* (bluefox) added some packages for federation
|
|
812
808
|
|
|
813
|
-
### 6.0.17 (2024-07-14)
|
|
814
|
-
* (bluefox) Allowed playing mp3 files in the file browser
|
|
809
|
+
### 6.0.17 (2024-07-14)
|
|
810
|
+
* (bluefox) Allowed playing mp3 files in the file browser
|
|
815
811
|
* (bluefox) Corrected jump by object selection
|
|
816
812
|
|
|
817
|
-
### 6.0.14 (2024-07-07)
|
|
813
|
+
### 6.0.14 (2024-07-07)
|
|
818
814
|
* (bluefox) Corrected theme type selection
|
|
819
815
|
|
|
820
|
-
### 6.0.13 (2024-06-30)
|
|
816
|
+
### 6.0.13 (2024-06-30)
|
|
821
817
|
* (bluefox) Corrected color picker
|
|
822
818
|
|
|
823
|
-
### 6.0.12 (2024-06-29)
|
|
819
|
+
### 6.0.12 (2024-06-29)
|
|
824
820
|
* (bluefox) Added support for the overrides in the theme
|
|
825
821
|
|
|
826
|
-
### 6.0.10 (2024-06-27)
|
|
827
|
-
* (bluefox) Added translation
|
|
822
|
+
### 6.0.10 (2024-06-27)
|
|
823
|
+
* (bluefox) Added translation
|
|
828
824
|
* (bluefox) Mobile object browser improved
|
|
829
825
|
|
|
830
|
-
### 6.0.9 (2024-06-26)
|
|
826
|
+
### 6.0.9 (2024-06-26)
|
|
831
827
|
* (bluefox) Corrected Icons
|
|
832
828
|
|
|
833
|
-
### 6.0.8 (2024-06-26)
|
|
834
|
-
* (bluefox) Corrected types of the select ID dialog
|
|
829
|
+
### 6.0.8 (2024-06-26)
|
|
830
|
+
* (bluefox) Corrected types of the select ID dialog
|
|
835
831
|
* (bluefox) Made the tooltips neutral to the pointer events
|
|
836
832
|
|
|
837
|
-
### 6.0.6 (2024-06-24)
|
|
838
|
-
* (bluefox) Synchronised with admin
|
|
833
|
+
### 6.0.6 (2024-06-24)
|
|
834
|
+
* (bluefox) Synchronised with admin
|
|
839
835
|
* (bluefox) Added translations for time scheduler
|
|
840
836
|
|
|
841
|
-
### 6.0.4 (2024-06-21)
|
|
842
|
-
* (bluefox) Removed the usage of `withStyles` in favor of `sx` and `style` properties (see [Migration from v5 to v6](#migration-from-v5-to-v6)
|
|
837
|
+
### 6.0.4 (2024-06-21)
|
|
838
|
+
* (bluefox) Removed the usage of `withStyles` in favor of `sx` and `style` properties (see [Migration from v5 to v6](#migration-from-v5-to-v6)
|
|
843
839
|
* (bluefox) (BREAKING) Higher version of `@mui/material` (5.15.20) is used
|
|
844
840
|
|
|
845
|
-
### 5.0.8 (2024-06-15)
|
|
841
|
+
### 5.0.8 (2024-06-15)
|
|
846
842
|
* (bluefox) Added `modulefederation.admin.config.js` for module federation
|
|
847
843
|
|
|
848
|
-
### 5.0.5 (2024-06-10)
|
|
844
|
+
### 5.0.5 (2024-06-10)
|
|
849
845
|
* (bluefox) Sources were synchronized with admin
|
|
850
846
|
|
|
851
|
-
### 5.0.4 (2024-06-07)
|
|
847
|
+
### 5.0.4 (2024-06-07)
|
|
852
848
|
* (bluefox) Added better typing
|
|
853
849
|
|
|
854
|
-
### 5.0.2 (2024-05-30)
|
|
855
|
-
* (bluefox) Added better typing
|
|
850
|
+
### 5.0.2 (2024-05-30)
|
|
851
|
+
* (bluefox) Added better typing
|
|
856
852
|
* (bluefox) Json-Config is now a separate package and must be installed additionally
|
|
857
853
|
|
|
858
|
-
### 5.0.0 (2024-05-29)
|
|
859
|
-
* (bluefox) Types are now exported
|
|
860
|
-
* (bluefox) Translator renamed to Translate
|
|
854
|
+
### 5.0.0 (2024-05-29)
|
|
855
|
+
* (bluefox) Types are now exported
|
|
856
|
+
* (bluefox) Translator renamed to Translate
|
|
861
857
|
* (bluefox) Breaking: Theme renamed to IobTheme because of the naming conflict
|
|
862
858
|
|
|
863
|
-
### 4.13.24 (2024-05-25)
|
|
864
|
-
* (bluefox) Updated packages
|
|
865
|
-
|
|
866
|
-
* ### 4.13.22 (2024-05-23)
|
|
859
|
+
### 4.13.24 (2024-05-25)
|
|
860
|
+
* (bluefox) Updated packages
|
|
861
|
+
|
|
862
|
+
* ### 4.13.22 (2024-05-23)
|
|
867
863
|
* (bluefox) Updated packages
|
|
868
864
|
|
|
869
|
-
### 4.13.20 (2024-05-22)
|
|
870
|
-
* (bluefox) Better types added
|
|
871
|
-
* (bluefox) updated theme definitions
|
|
865
|
+
### 4.13.20 (2024-05-22)
|
|
866
|
+
* (bluefox) Better types added
|
|
867
|
+
* (bluefox) updated theme definitions
|
|
872
868
|
* (bluefox) corrected dates in cron dialog
|
|
873
869
|
|
|
874
|
-
### 4.13.14 (2024-05-19)
|
|
870
|
+
### 4.13.14 (2024-05-19)
|
|
875
871
|
* (bluefox) Updated packages
|
|
876
872
|
|
|
877
|
-
### 4.13.13 (2024-05-09)
|
|
873
|
+
### 4.13.13 (2024-05-09)
|
|
878
874
|
* (bluefox) Updated ioBroker types
|
|
879
875
|
|
|
880
|
-
### 4.13.12 (2024-05-06)
|
|
876
|
+
### 4.13.12 (2024-05-06)
|
|
881
877
|
* (bluefox) All files are migrated to Typescript
|
|
882
878
|
|
|
883
|
-
### 4.13.11 (2024-04-23)
|
|
879
|
+
### 4.13.11 (2024-04-23)
|
|
884
880
|
* (bluefox) Corrected the size of icons
|
|
885
881
|
|
|
886
|
-
### 4.13.10 (2024-04-22)
|
|
882
|
+
### 4.13.10 (2024-04-22)
|
|
887
883
|
* (bluefox) Migrated all icons to Typescript
|
|
888
884
|
|
|
889
|
-
### 4.13.9 (2024-04-20)
|
|
885
|
+
### 4.13.9 (2024-04-20)
|
|
890
886
|
* (bluefox) Updated socket-client package
|
|
891
887
|
|
|
892
|
-
### 4.13.8 (2024-04-19)
|
|
888
|
+
### 4.13.8 (2024-04-19)
|
|
893
889
|
* (bluefox) Corrected CRON selector
|
|
894
890
|
|
|
895
|
-
### 4.13.7 (2024-04-19)
|
|
891
|
+
### 4.13.7 (2024-04-19)
|
|
896
892
|
* (bluefox) Migrated ColorPicker to typescript
|
|
897
893
|
|
|
898
|
-
### 4.13.6 (2024-04-11)
|
|
899
|
-
* (bluefox) Migrated TreeTable to typescript
|
|
894
|
+
### 4.13.6 (2024-04-11)
|
|
895
|
+
* (bluefox) Migrated TreeTable to typescript
|
|
900
896
|
* (bluefox) corrected the object subscription
|
|
901
897
|
|
|
902
|
-
### 4.13.5 (2024-04-02)
|
|
903
|
-
* (bluefox) used new connection classes
|
|
898
|
+
### 4.13.5 (2024-04-02)
|
|
899
|
+
* (bluefox) used new connection classes
|
|
904
900
|
* (bluefox) Improved the `SelectID` dialog
|
|
905
901
|
|
|
906
|
-
### 4.13.3 (2024-04-01)
|
|
902
|
+
### 4.13.3 (2024-04-01)
|
|
907
903
|
* (bluefox) used new connection classes
|
|
908
904
|
|
|
909
|
-
### 4.12.3 (2024-03-30)
|
|
905
|
+
### 4.12.3 (2024-03-30)
|
|
910
906
|
* (bluefox) Migrated legacy connection to typescript
|
|
911
907
|
|
|
912
|
-
### 4.12.2 (2024-03-25)
|
|
908
|
+
### 4.12.2 (2024-03-25)
|
|
913
909
|
* (bluefox) Added support for remote cloud
|
|
914
910
|
|
|
915
|
-
### 4.11.6 (2024-03-19)
|
|
911
|
+
### 4.11.6 (2024-03-19)
|
|
916
912
|
* (bluefox) Corrected rendering of LoaderMV
|
|
917
913
|
|
|
918
|
-
### 4.11.4 (2024-03-18)
|
|
914
|
+
### 4.11.4 (2024-03-18)
|
|
919
915
|
* (bluefox) Corrected types of IconPicker
|
|
920
916
|
|
|
921
|
-
### 4.11.3 (2024-03-17)
|
|
917
|
+
### 4.11.3 (2024-03-17)
|
|
922
918
|
* (bluefox) Made filters for the file selector dialog optional
|
|
923
919
|
|
|
924
|
-
### 4.11.2 (2024-03-16)
|
|
920
|
+
### 4.11.2 (2024-03-16)
|
|
925
921
|
* (bluefox) Migrated GenericApp to typescript
|
|
926
922
|
|
|
927
|
-
### 4.10.4 (2024-03-16)
|
|
923
|
+
### 4.10.4 (2024-03-16)
|
|
928
924
|
* (bluefox) Migrated some components to typescript
|
|
929
925
|
|
|
930
|
-
### 4.10.1 (2024-03-11)
|
|
926
|
+
### 4.10.1 (2024-03-11)
|
|
931
927
|
* (bluefox) Migrated some components to typescript
|
|
932
928
|
|
|
933
|
-
### 4.9.11 (2024-03-08)
|
|
929
|
+
### 4.9.11 (2024-03-08)
|
|
934
930
|
* (foxriver76) type GenericApp socket correctly
|
|
935
931
|
|
|
936
|
-
### 4.9.10 (2024-02-21)
|
|
937
|
-
* (bluefox) translations
|
|
932
|
+
### 4.9.10 (2024-02-21)
|
|
933
|
+
* (bluefox) translations
|
|
938
934
|
* (bluefox) updated json config
|
|
939
935
|
|
|
940
|
-
### 4.9.9 (2024-02-16)
|
|
936
|
+
### 4.9.9 (2024-02-16)
|
|
941
937
|
* (foxriver76) also check plugin state of instance to see if Sentry is explicitly disabled
|
|
942
938
|
|
|
943
|
-
### 4.9.8 (2024-02-13)
|
|
939
|
+
### 4.9.8 (2024-02-13)
|
|
944
940
|
* (bluefox) allowed hiding wizard in cron dialog
|
|
945
941
|
|
|
946
|
-
### 4.9.7 (2024-02-03)
|
|
942
|
+
### 4.9.7 (2024-02-03)
|
|
947
943
|
* (foxriver76) allow passing down the instance number do avoid determining from url
|
|
948
944
|
|
|
949
|
-
### 4.9.5 (2024-01-01)
|
|
945
|
+
### 4.9.5 (2024-01-01)
|
|
950
946
|
* (foxriver76) make `copyToClipboard` event parameter optional
|
|
951
947
|
|
|
952
|
-
### 4.9.4 (2024-01-01)
|
|
948
|
+
### 4.9.4 (2024-01-01)
|
|
953
949
|
* (foxriver76) try to fix `SelectID` scrolling
|
|
954
950
|
|
|
955
|
-
### 4.9.2 (2023-12-30)
|
|
951
|
+
### 4.9.2 (2023-12-30)
|
|
956
952
|
* (foxriver76) bump version of `@iobroker/json-config`
|
|
957
953
|
|
|
958
|
-
### 4.9.1 (2023-12-22)
|
|
954
|
+
### 4.9.1 (2023-12-22)
|
|
959
955
|
* (foxriver76) `@iobroker/json-config` moved to real dependencies
|
|
960
956
|
|
|
961
|
-
### 4.9.0 (2023-12-22)
|
|
962
|
-
* (foxriver76) migrate to `@iobroker/json-config` module to have a single point of truth
|
|
957
|
+
### 4.9.0 (2023-12-22)
|
|
958
|
+
* (foxriver76) migrate to `@iobroker/json-config` module to have a single point of truth
|
|
963
959
|
* (bluefox) Allowed using of `filterFunc` as string
|
|
964
960
|
|
|
965
|
-
### 4.8.1 (2023-12-14)
|
|
961
|
+
### 4.8.1 (2023-12-14)
|
|
966
962
|
* (bluefox) Added Device manager to JSON Config
|
|
967
963
|
|
|
968
|
-
### 4.7.15 (2023-12-12)
|
|
964
|
+
### 4.7.15 (2023-12-12)
|
|
969
965
|
* (bluefox) Corrected parsing of a text
|
|
970
966
|
|
|
971
|
-
### 4.7.13 (2023-12-10)
|
|
967
|
+
### 4.7.13 (2023-12-10)
|
|
972
968
|
* (bluefox) Added possibility to define the root style and embedded property
|
|
973
969
|
|
|
974
|
-
### 4.7.11 (2023-12-06)
|
|
970
|
+
### 4.7.11 (2023-12-06)
|
|
975
971
|
* (bluefox) Extended color picker with "noInputField" option
|
|
976
972
|
|
|
977
|
-
### 4.7.9 (2023-12-04)
|
|
973
|
+
### 4.7.9 (2023-12-04)
|
|
978
974
|
* (bluefox) Corrected the icon picker
|
|
979
975
|
|
|
980
|
-
### 4.7.8 (2023-12-04)
|
|
976
|
+
### 4.7.8 (2023-12-04)
|
|
981
977
|
* (foxriver76) port to `@iobroker/types`
|
|
982
978
|
|
|
983
|
-
### 4.7.6 (2023-11-29)
|
|
979
|
+
### 4.7.6 (2023-11-29)
|
|
984
980
|
* (bluefox) Added translations
|
|
985
981
|
|
|
986
|
-
### 4.7.5 (2023-11-28)
|
|
982
|
+
### 4.7.5 (2023-11-28)
|
|
987
983
|
* (bluefox) Corrected subscribe on objects in the legacy connection
|
|
988
984
|
|
|
989
|
-
### 4.7.4 (2023-11-23)
|
|
990
|
-
* (bluefox) Updated packages
|
|
985
|
+
### 4.7.4 (2023-11-23)
|
|
986
|
+
* (bluefox) Updated packages
|
|
991
987
|
* (bluefox) Made getStates method in legacy connection compatible with new one
|
|
992
988
|
|
|
993
|
-
### 4.7.3 (2023-11-08)
|
|
989
|
+
### 4.7.3 (2023-11-08)
|
|
994
990
|
* (bluefox) Updated packages
|
|
995
991
|
|
|
996
|
-
### 4.7.2 (2023-11-03)
|
|
997
|
-
* (foxriver76) fixed problem with color picker, where editing TextField was buggy
|
|
992
|
+
### 4.7.2 (2023-11-03)
|
|
993
|
+
* (foxriver76) fixed problem with color picker, where editing TextField was buggy
|
|
998
994
|
* (foxriver76) fixed light mode color of a path in FileBrowser
|
|
999
995
|
|
|
1000
|
-
### 4.7.0 (2023-10-31)
|
|
1001
|
-
* (bluefox) Synced with admin
|
|
996
|
+
### 4.7.0 (2023-10-31)
|
|
997
|
+
* (bluefox) Synced with admin
|
|
1002
998
|
* (bluefox) Added GIF to image files
|
|
1003
999
|
|
|
1004
|
-
### 4.6.7 (2023-10-19)
|
|
1000
|
+
### 4.6.7 (2023-10-19)
|
|
1005
1001
|
* (bluefox) Added return value for `subscribeOnInstance` for Connection class
|
|
1006
1002
|
|
|
1007
|
-
### 4.6.6 (2023-10-13)
|
|
1003
|
+
### 4.6.6 (2023-10-13)
|
|
1008
1004
|
* (bluefox) Fixed the legacy connection
|
|
1009
1005
|
|
|
1010
|
-
### 4.6.5 (2023-10-12)
|
|
1006
|
+
### 4.6.5 (2023-10-12)
|
|
1011
1007
|
* (foxriver76) fixed object browser with date
|
|
1012
1008
|
|
|
1013
|
-
### 4.6.4 (2023-10-11)
|
|
1009
|
+
### 4.6.4 (2023-10-11)
|
|
1014
1010
|
* (bluefox) Updated the packages
|
|
1015
1011
|
|
|
1016
|
-
### 4.6.3 (2023-10-09)
|
|
1017
|
-
* (bluefox) Just updated the packages
|
|
1012
|
+
### 4.6.3 (2023-10-09)
|
|
1013
|
+
* (bluefox) Just updated the packages
|
|
1018
1014
|
* (bluefox) Synced with admin
|
|
1019
1015
|
|
|
1020
|
-
### 4.6.2 (2023-09-29)
|
|
1016
|
+
### 4.6.2 (2023-09-29)
|
|
1021
1017
|
* (bluefox) Experimental feature added: update states on re-subscribe
|
|
1022
1018
|
|
|
1023
|
-
### 4.5.5 (2023-09-27)
|
|
1019
|
+
### 4.5.5 (2023-09-27)
|
|
1024
1020
|
* (bluefox) Added export for IconNoIcon
|
|
1025
1021
|
|
|
1026
|
-
### 4.5.4 (2023-09-17)
|
|
1022
|
+
### 4.5.4 (2023-09-17)
|
|
1027
1023
|
* (bluefox) Added the restricting to folder property for select file dialog
|
|
1028
1024
|
|
|
1029
|
-
### 4.5.3 (2023-08-20)
|
|
1025
|
+
### 4.5.3 (2023-08-20)
|
|
1030
1026
|
* (foxriver76) fixed css classes of TableResize, see https://github.com/ioBroker/ioBroker.admin/issues/1860
|
|
1031
1027
|
|
|
1032
|
-
### 4.5.2 (2023-08-20)
|
|
1028
|
+
### 4.5.2 (2023-08-20)
|
|
1033
1029
|
* (foxriver76) added missing export of TableResize
|
|
1034
1030
|
|
|
1035
|
-
### 4.5.1 (2023-08-19)
|
|
1031
|
+
### 4.5.1 (2023-08-19)
|
|
1036
1032
|
* (foxriver76) fix dialog TextInput
|
|
1037
1033
|
|
|
1038
|
-
### 4.5.0 (2023-08-18)
|
|
1034
|
+
### 4.5.0 (2023-08-18)
|
|
1039
1035
|
* (bluefox) Synchronize components with admin
|
|
1040
1036
|
|
|
1041
|
-
### 4.4.8 (2023-08-17)
|
|
1037
|
+
### 4.4.8 (2023-08-17)
|
|
1042
1038
|
* (bluefox) Added translations
|
|
1043
1039
|
|
|
1044
|
-
### 4.4.7 (2023-08-10)
|
|
1045
|
-
* (bluefox) Added `subscribeStateAsync` method to wait for answer
|
|
1040
|
+
### 4.4.7 (2023-08-10)
|
|
1041
|
+
* (bluefox) Added `subscribeStateAsync` method to wait for answer
|
|
1046
1042
|
* (bluefox) Added support for arrays for un/subscriptions
|
|
1047
1043
|
|
|
1048
|
-
### 4.4.5 (2023-08-01)
|
|
1044
|
+
### 4.4.5 (2023-08-01)
|
|
1049
1045
|
* (bluefox) Updated packages
|
|
1050
1046
|
|
|
1051
|
-
### 4.3.3 (2023-07-28)
|
|
1047
|
+
### 4.3.3 (2023-07-28)
|
|
1052
1048
|
* (bluefox) Added translations
|
|
1053
1049
|
|
|
1054
|
-
### 4.3.0 (2023-07-19)
|
|
1055
|
-
* (bluefox) Updated packages
|
|
1056
|
-
* (bluefox) Added translations
|
|
1057
|
-
* (bluefox) Synced object browser
|
|
1050
|
+
### 4.3.0 (2023-07-19)
|
|
1051
|
+
* (bluefox) Updated packages
|
|
1052
|
+
* (bluefox) Added translations
|
|
1053
|
+
* (bluefox) Synced object browser
|
|
1058
1054
|
* (bluefox) formatting
|
|
1059
1055
|
|
|
1060
|
-
### 4.2.1 (2023-07-17)
|
|
1061
|
-
* (bluefox) Updated packages
|
|
1056
|
+
### 4.2.1 (2023-07-17)
|
|
1057
|
+
* (bluefox) Updated packages
|
|
1062
1058
|
* (bluefox) Added translations
|
|
1063
1059
|
|
|
1064
|
-
### 4.2.0 (2023-07-07)
|
|
1065
|
-
* (bluefox) Updated packages
|
|
1060
|
+
### 4.2.0 (2023-07-07)
|
|
1061
|
+
* (bluefox) Updated packages
|
|
1066
1062
|
* (bluefox) Added new method `getObjectsById` to the socket communication
|
|
1067
1063
|
|
|
1068
|
-
### 4.1.2 (2023-06-20)
|
|
1064
|
+
### 4.1.2 (2023-06-20)
|
|
1069
1065
|
* (bluefox) Allowed setting theme name directly by theme toggle
|
|
1070
1066
|
|
|
1071
|
-
### 4.1.0 (2023-05-10)
|
|
1067
|
+
### 4.1.0 (2023-05-10)
|
|
1072
1068
|
* (bluefox) `craco-module-federation.js` was added. For node 16
|
|
1073
1069
|
|
|
1074
|
-
### 4.0.27 (2023-05-09)
|
|
1070
|
+
### 4.0.27 (2023-05-09)
|
|
1075
1071
|
* (bluefox) Allowed showing only specific root in SelectIDDialog
|
|
1076
1072
|
|
|
1077
|
-
### 4.0.26 (2023-05-08)
|
|
1073
|
+
### 4.0.26 (2023-05-08)
|
|
1078
1074
|
* (bluefox) Added IDs to the buttons in the dialog for GUI tests
|
|
1079
1075
|
|
|
1080
|
-
### 4.0.25 (2023-04-23)
|
|
1076
|
+
### 4.0.25 (2023-04-23)
|
|
1081
1077
|
* (bluefox) Extended `TextWithIcon` with defined color and icon
|
|
1082
1078
|
|
|
1083
|
-
### 4.0.24 (2023-04-03)
|
|
1079
|
+
### 4.0.24 (2023-04-03)
|
|
1084
1080
|
* (bluefox) Updated the file selector in tile mode
|
|
1085
1081
|
|
|
1086
|
-
### 4.0.23 (2023-03-27)
|
|
1082
|
+
### 4.0.23 (2023-03-27)
|
|
1087
1083
|
* (bluefox) Added translations
|
|
1088
1084
|
|
|
1089
|
-
### 4.0.22 (2023-03-22)
|
|
1085
|
+
### 4.0.22 (2023-03-22)
|
|
1090
1086
|
* (bluefox) Re-Activate legacy connection
|
|
1091
1087
|
|
|
1092
|
-
### 4.0.21 (2023-03-22)
|
|
1088
|
+
### 4.0.21 (2023-03-22)
|
|
1093
1089
|
* (bluefox) Added translations
|
|
1094
1090
|
|
|
1095
|
-
### 4.0.20 (2023-03-21)
|
|
1091
|
+
### 4.0.20 (2023-03-21)
|
|
1096
1092
|
* (bluefox) Color picker was improved
|
|
1097
1093
|
|
|
1098
|
-
### 4.0.19 (2023-03-20)
|
|
1099
|
-
* (bluefox) Packages were updated
|
|
1094
|
+
### 4.0.19 (2023-03-20)
|
|
1095
|
+
* (bluefox) Packages were updated
|
|
1100
1096
|
* (bluefox) Added new translations
|
|
1101
1097
|
|
|
1102
|
-
### 4.0.18 (2023-03-16)
|
|
1098
|
+
### 4.0.18 (2023-03-16)
|
|
1103
1099
|
* (bluefox) Packages were updated
|
|
1104
1100
|
|
|
1105
|
-
### 4.0.17 (2023-03-15)
|
|
1106
|
-
* (bluefox) Added translations
|
|
1101
|
+
### 4.0.17 (2023-03-15)
|
|
1102
|
+
* (bluefox) Added translations
|
|
1107
1103
|
* (bluefox) Added port controller to JSON config
|
|
1108
1104
|
|
|
1109
|
-
### 4.0.15 (2023-03-12)
|
|
1105
|
+
### 4.0.15 (2023-03-12)
|
|
1110
1106
|
* (bluefox) Updated the object browser and file browser
|
|
1111
1107
|
|
|
1112
|
-
### 4.0.14 (2023-03-03)
|
|
1108
|
+
### 4.0.14 (2023-03-03)
|
|
1113
1109
|
* (bluefox) added handler of alert messages
|
|
1114
1110
|
|
|
1115
|
-
### 4.0.13 (2023-02-15)
|
|
1111
|
+
### 4.0.13 (2023-02-15)
|
|
1116
1112
|
* (bluefox) Corrected the theme button
|
|
1117
1113
|
|
|
1118
|
-
### 4.0.12 (2023-02-15)
|
|
1114
|
+
### 4.0.12 (2023-02-15)
|
|
1119
1115
|
* (bluefox) made the fix for `echarts`
|
|
1120
1116
|
|
|
1121
|
-
### 4.0.11 (2023-02-14)
|
|
1122
|
-
* (bluefox) Updated packages
|
|
1117
|
+
### 4.0.11 (2023-02-14)
|
|
1118
|
+
* (bluefox) Updated packages
|
|
1123
1119
|
* (bluefox) The `chartReady` event was omitted
|
|
1124
1120
|
|
|
1125
|
-
### 4.0.10 (2023-02-10)
|
|
1126
|
-
* (bluefox) Updated packages
|
|
1121
|
+
### 4.0.10 (2023-02-10)
|
|
1122
|
+
* (bluefox) Updated packages
|
|
1127
1123
|
* (bluefox) made the fix for `material`
|
|
1128
1124
|
|
|
1129
|
-
### 4.0.9 (2023-02-02)
|
|
1125
|
+
### 4.0.9 (2023-02-02)
|
|
1130
1126
|
* (bluefox) Updated packages
|
|
1131
1127
|
|
|
1132
|
-
### 4.0.8 (2022-12-19)
|
|
1128
|
+
### 4.0.8 (2022-12-19)
|
|
1133
1129
|
* (bluefox) Extended socket with `log` command
|
|
1134
1130
|
|
|
1135
|
-
### 4.0.6 (2022-12-19)
|
|
1131
|
+
### 4.0.6 (2022-12-19)
|
|
1136
1132
|
* (bluefox) Corrected URL for the connection
|
|
1137
1133
|
|
|
1138
|
-
### 4.0.5 (2022-12-14)
|
|
1134
|
+
### 4.0.5 (2022-12-14)
|
|
1139
1135
|
* (bluefox) Added support of custom palette for color picker
|
|
1140
1136
|
|
|
1141
|
-
### 4.0.2 (2022-12-01)
|
|
1137
|
+
### 4.0.2 (2022-12-01)
|
|
1142
1138
|
* (bluefox) use `@iobroker/socket-client` instead of `Connection.tsx`
|
|
1143
1139
|
|
|
1144
|
-
### 3.5.3 (2022-11-30)
|
|
1140
|
+
### 3.5.3 (2022-11-30)
|
|
1145
1141
|
* (bluefox) Improved `renderTextWithA` function to support `<b>` and `<i>` tags
|
|
1146
1142
|
|
|
1147
|
-
### 3.5.2 (2022-11-30)
|
|
1143
|
+
### 3.5.2 (2022-11-30)
|
|
1148
1144
|
* (bluefox) updated json config component
|
|
1149
1145
|
|
|
1150
|
-
### 3.4.1 (2022-11-29)
|
|
1146
|
+
### 3.4.1 (2022-11-29)
|
|
1151
1147
|
* (bluefox) Added button text for message dialog
|
|
1152
1148
|
|
|
1153
|
-
### 3.4.0 (2022-11-29)
|
|
1149
|
+
### 3.4.0 (2022-11-29)
|
|
1154
1150
|
* (bluefox) Added file selector
|
|
1155
1151
|
|
|
1156
|
-
### 3.3.0 (2022-11-26)
|
|
1152
|
+
### 3.3.0 (2022-11-26)
|
|
1157
1153
|
* (bluefox) Added subscribe on files
|
|
1158
1154
|
|
|
1159
|
-
### 3.2.7 (2022-11-13)
|
|
1155
|
+
### 3.2.7 (2022-11-13)
|
|
1160
1156
|
* (bluefox) Added `fullWidth` property to `Dialog`
|
|
1161
1157
|
|
|
1162
|
-
### 3.2.6 (2022-11-08)
|
|
1158
|
+
### 3.2.6 (2022-11-08)
|
|
1163
1159
|
* (xXBJXx) Improved TreeTable component
|
|
1164
1160
|
|
|
1165
|
-
### 3.2.5 (2022-11-08)
|
|
1161
|
+
### 3.2.5 (2022-11-08)
|
|
1166
1162
|
* (bluefox) Added the role filter for the object browser
|
|
1167
1163
|
|
|
1168
|
-
### 3.2.4 (2022-11-03)
|
|
1164
|
+
### 3.2.4 (2022-11-03)
|
|
1169
1165
|
* (bluefox) Added support for alfa channel for `invertColor`
|
|
1170
1166
|
|
|
1171
|
-
### 3.2.3 (2022-10-26)
|
|
1167
|
+
### 3.2.3 (2022-10-26)
|
|
1172
1168
|
* (bluefox) Corrected expert mode for object browser
|
|
1173
1169
|
|
|
1174
|
-
### 3.2.2 (2022-10-25)
|
|
1170
|
+
### 3.2.2 (2022-10-25)
|
|
1175
1171
|
* (bluefox) Added support for prefixes for translations
|
|
1176
1172
|
|
|
1177
|
-
### 3.2.1 (2022-10-24)
|
|
1173
|
+
### 3.2.1 (2022-10-24)
|
|
1178
1174
|
* (bluefox) Corrected color inversion
|
|
1179
1175
|
|
|
1180
|
-
### 3.2.0 (2022-10-19)
|
|
1176
|
+
### 3.2.0 (2022-10-19)
|
|
1181
1177
|
* (bluefox) Added ukrainian translation
|
|
1182
1178
|
|
|
1183
|
-
### 3.1.35 (2022-10-17)
|
|
1179
|
+
### 3.1.35 (2022-10-17)
|
|
1184
1180
|
* (bluefox) small changes for material
|
|
1185
1181
|
|
|
1186
|
-
### 3.1.34 (2022-08-24)
|
|
1182
|
+
### 3.1.34 (2022-08-24)
|
|
1187
1183
|
* (bluefox) Implemented fallback to english by translations
|
|
1188
1184
|
|
|
1189
|
-
### 3.1.33 (2022-08-24)
|
|
1185
|
+
### 3.1.33 (2022-08-24)
|
|
1190
1186
|
* (bluefox) Added support for onchange flag
|
|
1191
1187
|
|
|
1192
|
-
### 3.1.30 (2022-08-23)
|
|
1193
|
-
* (bluefox) Added method `getCompactSystemRepositories`
|
|
1188
|
+
### 3.1.30 (2022-08-23)
|
|
1189
|
+
* (bluefox) Added method `getCompactSystemRepositories`
|
|
1194
1190
|
* (bluefox) corrected error in `ObjectBrowser`
|
|
1195
1191
|
|
|
1196
|
-
### 3.1.27 (2022-08-01)
|
|
1192
|
+
### 3.1.27 (2022-08-01)
|
|
1197
1193
|
* (bluefox) Disable file editing in FileViewer
|
|
1198
1194
|
|
|
1199
|
-
### 3.1.26 (2022-08-01)
|
|
1200
|
-
* (bluefox) Added translations
|
|
1195
|
+
### 3.1.26 (2022-08-01)
|
|
1196
|
+
* (bluefox) Added translations
|
|
1201
1197
|
* (bluefox) JSON schema was extended with missing definitions
|
|
1202
1198
|
|
|
1203
|
-
### 3.1.24 (2022-07-28)
|
|
1199
|
+
### 3.1.24 (2022-07-28)
|
|
1204
1200
|
* (bluefox) Updated file browser and object browser
|
|
1205
1201
|
|
|
1206
|
-
### 3.1.23 (2022-07-25)
|
|
1202
|
+
### 3.1.23 (2022-07-25)
|
|
1207
1203
|
* (bluefox) Extend custom filter for object selector
|
|
1208
1204
|
|
|
1209
|
-
### 3.1.22 (2022-07-22)
|
|
1205
|
+
### 3.1.22 (2022-07-22)
|
|
1210
1206
|
* (bluefox) Added i18n tools for development
|
|
1211
1207
|
|
|
1212
|
-
### 3.1.20 (2022-07-14)
|
|
1208
|
+
### 3.1.20 (2022-07-14)
|
|
1213
1209
|
* (bluefox) Allowed to show select dialog with the expert mode enabled
|
|
1214
1210
|
|
|
1215
|
-
### 3.1.19 (2022-07-08)
|
|
1211
|
+
### 3.1.19 (2022-07-08)
|
|
1216
1212
|
* (bluefox) Allowed extending translations for all languages together
|
|
1217
1213
|
|
|
1218
|
-
### 3.1.18 (2022-07-06)
|
|
1214
|
+
### 3.1.18 (2022-07-06)
|
|
1219
1215
|
* (bluefox) Added translation
|
|
1220
1216
|
|
|
1221
|
-
### 3.1.17 (2022-07-05)
|
|
1217
|
+
### 3.1.17 (2022-07-05)
|
|
1222
1218
|
* (bluefox) Deactivate JSON editor for JSONConfig because of space
|
|
1223
1219
|
|
|
1224
|
-
### 3.1.16 (2022-06-27)
|
|
1220
|
+
### 3.1.16 (2022-06-27)
|
|
1225
1221
|
* (bluefox) Update object browser
|
|
1226
1222
|
|
|
1227
|
-
### 3.1.15 (2022-06-27)
|
|
1223
|
+
### 3.1.15 (2022-06-27)
|
|
1228
1224
|
* (bluefox) Allowed using of spaces in name
|
|
1229
1225
|
|
|
1230
|
-
### 3.1.14 (2022-06-23)
|
|
1226
|
+
### 3.1.14 (2022-06-23)
|
|
1231
1227
|
* (bluefox) Added translations
|
|
1232
1228
|
|
|
1233
|
-
### 3.1.11 (2022-06-22)
|
|
1229
|
+
### 3.1.11 (2022-06-22)
|
|
1234
1230
|
* (bluefox) Added preparations for iobroker cloud
|
|
1235
1231
|
|
|
1236
|
-
### 3.1.10 (2022-06-22)
|
|
1232
|
+
### 3.1.10 (2022-06-22)
|
|
1237
1233
|
* (bluefox) Added translations
|
|
1238
1234
|
|
|
1239
|
-
### 3.1.9 (2022-06-20)
|
|
1235
|
+
### 3.1.9 (2022-06-20)
|
|
1240
1236
|
* (bluefox) Allowed working behind reverse proxy
|
|
1241
1237
|
|
|
1242
|
-
### 3.1.7 (2022-06-19)
|
|
1238
|
+
### 3.1.7 (2022-06-19)
|
|
1243
1239
|
* (bluefox) Added file select dialog
|
|
1244
1240
|
|
|
1245
|
-
### 3.1.3 (2022-06-13)
|
|
1241
|
+
### 3.1.3 (2022-06-13)
|
|
1246
1242
|
* (bluefox) Added table with resized headers
|
|
1247
1243
|
|
|
1248
|
-
### 3.1.2 (2022-06-09)
|
|
1244
|
+
### 3.1.2 (2022-06-09)
|
|
1249
1245
|
* (bluefox) Added new document icon (read only)
|
|
1250
1246
|
|
|
1251
|
-
### 3.1.1 (2022-06-09)
|
|
1247
|
+
### 3.1.1 (2022-06-09)
|
|
1252
1248
|
* (bluefox) Allowed working behind reverse proxy
|
|
1253
1249
|
|
|
1254
|
-
### 3.1.0 (2022-06-07)
|
|
1250
|
+
### 3.1.0 (2022-06-07)
|
|
1255
1251
|
* (bluefox) Some german texts were corrected
|
|
1256
1252
|
|
|
1257
|
-
### 3.0.17 (2022-06-03)
|
|
1253
|
+
### 3.0.17 (2022-06-03)
|
|
1258
1254
|
* (bluefox) Allowed calling getAdapterInstances not for admin too
|
|
1259
1255
|
|
|
1260
|
-
### 3.0.15 (2022-06-01)
|
|
1256
|
+
### 3.0.15 (2022-06-01)
|
|
1261
1257
|
* (bluefox) Updated JsonConfigComponent: password, table
|
|
1262
1258
|
|
|
1263
|
-
### 3.0.14 (2022-05-25)
|
|
1259
|
+
### 3.0.14 (2022-05-25)
|
|
1264
1260
|
* (bluefox) Added ConfigGeneric to import
|
|
1265
1261
|
|
|
1266
|
-
### 3.0.7 (2022-05-25)
|
|
1262
|
+
### 3.0.7 (2022-05-25)
|
|
1267
1263
|
* (bluefox) Made the module definitions
|
|
1268
1264
|
|
|
1269
|
-
### 3.0.6 (2022-05-25)
|
|
1265
|
+
### 3.0.6 (2022-05-25)
|
|
1270
1266
|
* (bluefox) Added JsonConfigComponent
|
|
1271
1267
|
|
|
1272
|
-
### 2.1.11 (2022-05-24)
|
|
1268
|
+
### 2.1.11 (2022-05-24)
|
|
1273
1269
|
* (bluefox) Update file browser. It supports now the file changed events.
|
|
1274
1270
|
|
|
1275
|
-
### 2.1.10 (2022-05-24)
|
|
1271
|
+
### 2.1.10 (2022-05-24)
|
|
1276
1272
|
* (bluefox) Corrected object browser
|
|
1277
1273
|
|
|
1278
|
-
### 2.1.9 (2022-05-16)
|
|
1274
|
+
### 2.1.9 (2022-05-16)
|
|
1279
1275
|
* (bluefox) Corrected expert mode in object browser
|
|
1280
1276
|
|
|
1281
|
-
### 2.1.7 (2022-05-09)
|
|
1282
|
-
* (bluefox) Changes were synchronized with adapter-react-v5
|
|
1277
|
+
### 2.1.7 (2022-05-09)
|
|
1278
|
+
* (bluefox) Changes were synchronized with adapter-react-v5
|
|
1283
1279
|
* (bluefox) Added `I18n.disableWarning` method
|
|
1284
1280
|
|
|
1285
|
-
### 2.1.6 (2022-03-28)
|
|
1286
|
-
* (bluefox) Added `log` method to connection
|
|
1281
|
+
### 2.1.6 (2022-03-28)
|
|
1282
|
+
* (bluefox) Added `log` method to connection
|
|
1287
1283
|
* (bluefox) Corrected translations
|
|
1288
1284
|
|
|
1289
|
-
### 2.1.1 (2022-03-27)
|
|
1285
|
+
### 2.1.1 (2022-03-27)
|
|
1290
1286
|
* (bluefox) Corrected error in TreeTable
|
|
1291
1287
|
|
|
1292
|
-
### 2.1.0 (2022-03-26)
|
|
1288
|
+
### 2.1.0 (2022-03-26)
|
|
1293
1289
|
* (bluefox) BREAKING_CHANGE: Corrected error with readFile(base64=false)
|
|
1294
1290
|
|
|
1295
|
-
### 2.0.0 (2022-03-26)
|
|
1291
|
+
### 2.0.0 (2022-03-26)
|
|
1296
1292
|
* (bluefox) Initial version
|
|
1297
1293
|
|
|
1298
|
-
### 0.1.0 (2022-03-23)
|
|
1294
|
+
### 0.1.0 (2022-03-23)
|
|
1299
1295
|
* (bluefox) Fixed theme errors
|
|
1300
1296
|
|
|
1301
|
-
### 0.0.4 (2022-03-22)
|
|
1297
|
+
### 0.0.4 (2022-03-22)
|
|
1302
1298
|
* (bluefox) Fixed eslint warnings
|
|
1303
1299
|
|
|
1304
|
-
### 0.0.3 (2022-03-19)
|
|
1300
|
+
### 0.0.3 (2022-03-19)
|
|
1305
1301
|
* (bluefox) beta version
|
|
1306
1302
|
|
|
1307
|
-
### 0.0.2 (2022-02-24)
|
|
1303
|
+
### 0.0.2 (2022-02-24)
|
|
1308
1304
|
* (bluefox) try to publish a first version
|
|
1309
1305
|
|
|
1310
|
-
### 0.0.1 (2022-02-24)
|
|
1306
|
+
### 0.0.1 (2022-02-24)
|
|
1311
1307
|
* initial commit
|
|
1312
1308
|
|
|
1313
|
-
## License
|
|
1314
|
-
The MIT License (MIT)
|
|
1315
|
-
|
|
1316
|
-
Copyright (c) 2019-2024 bluefox <dogafox@gmail.com>
|
|
1317
|
-
|
|
1318
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
1319
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
1320
|
-
in the Software without restriction, including without limitation the rights
|
|
1321
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
1322
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
1323
|
-
furnished to do so, subject to the following conditions:
|
|
1324
|
-
|
|
1325
|
-
The above copyright notice and this permission notice shall be included in all
|
|
1326
|
-
copies or substantial portions of the Software.
|
|
1327
|
-
|
|
1328
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
1329
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
1330
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
1331
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
1332
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
1333
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
1309
|
+
## License
|
|
1310
|
+
The MIT License (MIT)
|
|
1311
|
+
|
|
1312
|
+
Copyright (c) 2019-2024 bluefox <dogafox@gmail.com>
|
|
1313
|
+
|
|
1314
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
1315
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
1316
|
+
in the Software without restriction, including without limitation the rights
|
|
1317
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
1318
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
1319
|
+
furnished to do so, subject to the following conditions:
|
|
1320
|
+
|
|
1321
|
+
The above copyright notice and this permission notice shall be included in all
|
|
1322
|
+
copies or substantial portions of the Software.
|
|
1323
|
+
|
|
1324
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
1325
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
1326
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
1327
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
1328
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
1329
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
1334
1330
|
SOFTWARE.
|