@iobroker/adapter-react-v5 6.1.10 → 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/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.js +29 -29
- 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 -1005
- 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 +4 -4
- 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 -2414
- package/src/Components/FileViewer.tsx +393 -393
- 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 -8032
- 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,1331 +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
|
-
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
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
After: `<
|
|
760
|
-
|
|
761
|
-
Before: `<
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
Before. `<
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
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
|
+
|
|
782
787
|
## Changelog
|
|
783
|
-
### 6.1.
|
|
784
|
-
* (bluefox) Updated the object browser
|
|
785
|
-
|
|
786
|
-
### 6.1.9 (2024-08-14)
|
|
787
|
-
* (bluefox) Updated JSON schema
|
|
788
|
-
|
|
789
|
-
### 6.1.8 (2024-08-03)
|
|
788
|
+
### 6.1.7 (2024-08-03)
|
|
790
789
|
* (bluefox) Added translations
|
|
791
790
|
|
|
792
|
-
### 6.1.6 (2024-07-23)
|
|
791
|
+
### 6.1.6 (2024-07-23)
|
|
793
792
|
* (bluefox) Optimize package
|
|
794
793
|
|
|
795
|
-
### 6.1.5 (2024-07-20)
|
|
794
|
+
### 6.1.5 (2024-07-20)
|
|
796
795
|
* (bluefox) Added sources to package
|
|
797
796
|
|
|
798
|
-
### 6.1.3 (2024-07-20)
|
|
797
|
+
### 6.1.3 (2024-07-20)
|
|
799
798
|
* (bluefox) Better typing of legacy connection
|
|
800
799
|
|
|
801
|
-
### 6.1.1 (2024-07-16)
|
|
800
|
+
### 6.1.1 (2024-07-16)
|
|
802
801
|
* (bluefox) Added translations
|
|
803
802
|
|
|
804
|
-
### 6.1.0 (2024-07-15)
|
|
803
|
+
### 6.1.0 (2024-07-15)
|
|
805
804
|
* (bluefox) Replace by CRON to text the package to `cronstrue`
|
|
806
805
|
|
|
807
|
-
### 6.0.19 (2024-07-14)
|
|
806
|
+
### 6.0.19 (2024-07-14)
|
|
808
807
|
* (bluefox) added some packages for federation
|
|
809
808
|
|
|
810
|
-
### 6.0.17 (2024-07-14)
|
|
811
|
-
* (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
|
|
812
811
|
* (bluefox) Corrected jump by object selection
|
|
813
812
|
|
|
814
|
-
### 6.0.14 (2024-07-07)
|
|
813
|
+
### 6.0.14 (2024-07-07)
|
|
815
814
|
* (bluefox) Corrected theme type selection
|
|
816
815
|
|
|
817
|
-
### 6.0.13 (2024-06-30)
|
|
816
|
+
### 6.0.13 (2024-06-30)
|
|
818
817
|
* (bluefox) Corrected color picker
|
|
819
818
|
|
|
820
|
-
### 6.0.12 (2024-06-29)
|
|
819
|
+
### 6.0.12 (2024-06-29)
|
|
821
820
|
* (bluefox) Added support for the overrides in the theme
|
|
822
821
|
|
|
823
|
-
### 6.0.10 (2024-06-27)
|
|
824
|
-
* (bluefox) Added translation
|
|
822
|
+
### 6.0.10 (2024-06-27)
|
|
823
|
+
* (bluefox) Added translation
|
|
825
824
|
* (bluefox) Mobile object browser improved
|
|
826
825
|
|
|
827
|
-
### 6.0.9 (2024-06-26)
|
|
826
|
+
### 6.0.9 (2024-06-26)
|
|
828
827
|
* (bluefox) Corrected Icons
|
|
829
828
|
|
|
830
|
-
### 6.0.8 (2024-06-26)
|
|
831
|
-
* (bluefox) Corrected types of the select ID dialog
|
|
829
|
+
### 6.0.8 (2024-06-26)
|
|
830
|
+
* (bluefox) Corrected types of the select ID dialog
|
|
832
831
|
* (bluefox) Made the tooltips neutral to the pointer events
|
|
833
832
|
|
|
834
|
-
### 6.0.6 (2024-06-24)
|
|
835
|
-
* (bluefox) Synchronised with admin
|
|
833
|
+
### 6.0.6 (2024-06-24)
|
|
834
|
+
* (bluefox) Synchronised with admin
|
|
836
835
|
* (bluefox) Added translations for time scheduler
|
|
837
836
|
|
|
838
|
-
### 6.0.4 (2024-06-21)
|
|
839
|
-
* (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)
|
|
840
839
|
* (bluefox) (BREAKING) Higher version of `@mui/material` (5.15.20) is used
|
|
841
840
|
|
|
842
|
-
### 5.0.8 (2024-06-15)
|
|
841
|
+
### 5.0.8 (2024-06-15)
|
|
843
842
|
* (bluefox) Added `modulefederation.admin.config.js` for module federation
|
|
844
843
|
|
|
845
|
-
### 5.0.5 (2024-06-10)
|
|
844
|
+
### 5.0.5 (2024-06-10)
|
|
846
845
|
* (bluefox) Sources were synchronized with admin
|
|
847
846
|
|
|
848
|
-
### 5.0.4 (2024-06-07)
|
|
847
|
+
### 5.0.4 (2024-06-07)
|
|
849
848
|
* (bluefox) Added better typing
|
|
850
849
|
|
|
851
|
-
### 5.0.2 (2024-05-30)
|
|
852
|
-
* (bluefox) Added better typing
|
|
850
|
+
### 5.0.2 (2024-05-30)
|
|
851
|
+
* (bluefox) Added better typing
|
|
853
852
|
* (bluefox) Json-Config is now a separate package and must be installed additionally
|
|
854
853
|
|
|
855
|
-
### 5.0.0 (2024-05-29)
|
|
856
|
-
* (bluefox) Types are now exported
|
|
857
|
-
* (bluefox) Translator renamed to Translate
|
|
854
|
+
### 5.0.0 (2024-05-29)
|
|
855
|
+
* (bluefox) Types are now exported
|
|
856
|
+
* (bluefox) Translator renamed to Translate
|
|
858
857
|
* (bluefox) Breaking: Theme renamed to IobTheme because of the naming conflict
|
|
859
858
|
|
|
860
|
-
### 4.13.24 (2024-05-25)
|
|
861
|
-
* (bluefox) Updated packages
|
|
862
|
-
|
|
863
|
-
* ### 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)
|
|
864
863
|
* (bluefox) Updated packages
|
|
865
864
|
|
|
866
|
-
### 4.13.20 (2024-05-22)
|
|
867
|
-
* (bluefox) Better types added
|
|
868
|
-
* (bluefox) updated theme definitions
|
|
865
|
+
### 4.13.20 (2024-05-22)
|
|
866
|
+
* (bluefox) Better types added
|
|
867
|
+
* (bluefox) updated theme definitions
|
|
869
868
|
* (bluefox) corrected dates in cron dialog
|
|
870
869
|
|
|
871
|
-
### 4.13.14 (2024-05-19)
|
|
870
|
+
### 4.13.14 (2024-05-19)
|
|
872
871
|
* (bluefox) Updated packages
|
|
873
872
|
|
|
874
|
-
### 4.13.13 (2024-05-09)
|
|
873
|
+
### 4.13.13 (2024-05-09)
|
|
875
874
|
* (bluefox) Updated ioBroker types
|
|
876
875
|
|
|
877
|
-
### 4.13.12 (2024-05-06)
|
|
876
|
+
### 4.13.12 (2024-05-06)
|
|
878
877
|
* (bluefox) All files are migrated to Typescript
|
|
879
878
|
|
|
880
|
-
### 4.13.11 (2024-04-23)
|
|
879
|
+
### 4.13.11 (2024-04-23)
|
|
881
880
|
* (bluefox) Corrected the size of icons
|
|
882
881
|
|
|
883
|
-
### 4.13.10 (2024-04-22)
|
|
882
|
+
### 4.13.10 (2024-04-22)
|
|
884
883
|
* (bluefox) Migrated all icons to Typescript
|
|
885
884
|
|
|
886
|
-
### 4.13.9 (2024-04-20)
|
|
885
|
+
### 4.13.9 (2024-04-20)
|
|
887
886
|
* (bluefox) Updated socket-client package
|
|
888
887
|
|
|
889
|
-
### 4.13.8 (2024-04-19)
|
|
888
|
+
### 4.13.8 (2024-04-19)
|
|
890
889
|
* (bluefox) Corrected CRON selector
|
|
891
890
|
|
|
892
|
-
### 4.13.7 (2024-04-19)
|
|
891
|
+
### 4.13.7 (2024-04-19)
|
|
893
892
|
* (bluefox) Migrated ColorPicker to typescript
|
|
894
893
|
|
|
895
|
-
### 4.13.6 (2024-04-11)
|
|
896
|
-
* (bluefox) Migrated TreeTable to typescript
|
|
894
|
+
### 4.13.6 (2024-04-11)
|
|
895
|
+
* (bluefox) Migrated TreeTable to typescript
|
|
897
896
|
* (bluefox) corrected the object subscription
|
|
898
897
|
|
|
899
|
-
### 4.13.5 (2024-04-02)
|
|
900
|
-
* (bluefox) used new connection classes
|
|
898
|
+
### 4.13.5 (2024-04-02)
|
|
899
|
+
* (bluefox) used new connection classes
|
|
901
900
|
* (bluefox) Improved the `SelectID` dialog
|
|
902
901
|
|
|
903
|
-
### 4.13.3 (2024-04-01)
|
|
902
|
+
### 4.13.3 (2024-04-01)
|
|
904
903
|
* (bluefox) used new connection classes
|
|
905
904
|
|
|
906
|
-
### 4.12.3 (2024-03-30)
|
|
905
|
+
### 4.12.3 (2024-03-30)
|
|
907
906
|
* (bluefox) Migrated legacy connection to typescript
|
|
908
907
|
|
|
909
|
-
### 4.12.2 (2024-03-25)
|
|
908
|
+
### 4.12.2 (2024-03-25)
|
|
910
909
|
* (bluefox) Added support for remote cloud
|
|
911
910
|
|
|
912
|
-
### 4.11.6 (2024-03-19)
|
|
911
|
+
### 4.11.6 (2024-03-19)
|
|
913
912
|
* (bluefox) Corrected rendering of LoaderMV
|
|
914
913
|
|
|
915
|
-
### 4.11.4 (2024-03-18)
|
|
914
|
+
### 4.11.4 (2024-03-18)
|
|
916
915
|
* (bluefox) Corrected types of IconPicker
|
|
917
916
|
|
|
918
|
-
### 4.11.3 (2024-03-17)
|
|
917
|
+
### 4.11.3 (2024-03-17)
|
|
919
918
|
* (bluefox) Made filters for the file selector dialog optional
|
|
920
919
|
|
|
921
|
-
### 4.11.2 (2024-03-16)
|
|
920
|
+
### 4.11.2 (2024-03-16)
|
|
922
921
|
* (bluefox) Migrated GenericApp to typescript
|
|
923
922
|
|
|
924
|
-
### 4.10.4 (2024-03-16)
|
|
923
|
+
### 4.10.4 (2024-03-16)
|
|
925
924
|
* (bluefox) Migrated some components to typescript
|
|
926
925
|
|
|
927
|
-
### 4.10.1 (2024-03-11)
|
|
926
|
+
### 4.10.1 (2024-03-11)
|
|
928
927
|
* (bluefox) Migrated some components to typescript
|
|
929
928
|
|
|
930
|
-
### 4.9.11 (2024-03-08)
|
|
929
|
+
### 4.9.11 (2024-03-08)
|
|
931
930
|
* (foxriver76) type GenericApp socket correctly
|
|
932
931
|
|
|
933
|
-
### 4.9.10 (2024-02-21)
|
|
934
|
-
* (bluefox) translations
|
|
932
|
+
### 4.9.10 (2024-02-21)
|
|
933
|
+
* (bluefox) translations
|
|
935
934
|
* (bluefox) updated json config
|
|
936
935
|
|
|
937
|
-
### 4.9.9 (2024-02-16)
|
|
936
|
+
### 4.9.9 (2024-02-16)
|
|
938
937
|
* (foxriver76) also check plugin state of instance to see if Sentry is explicitly disabled
|
|
939
938
|
|
|
940
|
-
### 4.9.8 (2024-02-13)
|
|
939
|
+
### 4.9.8 (2024-02-13)
|
|
941
940
|
* (bluefox) allowed hiding wizard in cron dialog
|
|
942
941
|
|
|
943
|
-
### 4.9.7 (2024-02-03)
|
|
942
|
+
### 4.9.7 (2024-02-03)
|
|
944
943
|
* (foxriver76) allow passing down the instance number do avoid determining from url
|
|
945
944
|
|
|
946
|
-
### 4.9.5 (2024-01-01)
|
|
945
|
+
### 4.9.5 (2024-01-01)
|
|
947
946
|
* (foxriver76) make `copyToClipboard` event parameter optional
|
|
948
947
|
|
|
949
|
-
### 4.9.4 (2024-01-01)
|
|
948
|
+
### 4.9.4 (2024-01-01)
|
|
950
949
|
* (foxriver76) try to fix `SelectID` scrolling
|
|
951
950
|
|
|
952
|
-
### 4.9.2 (2023-12-30)
|
|
951
|
+
### 4.9.2 (2023-12-30)
|
|
953
952
|
* (foxriver76) bump version of `@iobroker/json-config`
|
|
954
953
|
|
|
955
|
-
### 4.9.1 (2023-12-22)
|
|
954
|
+
### 4.9.1 (2023-12-22)
|
|
956
955
|
* (foxriver76) `@iobroker/json-config` moved to real dependencies
|
|
957
956
|
|
|
958
|
-
### 4.9.0 (2023-12-22)
|
|
959
|
-
* (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
|
|
960
959
|
* (bluefox) Allowed using of `filterFunc` as string
|
|
961
960
|
|
|
962
|
-
### 4.8.1 (2023-12-14)
|
|
961
|
+
### 4.8.1 (2023-12-14)
|
|
963
962
|
* (bluefox) Added Device manager to JSON Config
|
|
964
963
|
|
|
965
|
-
### 4.7.15 (2023-12-12)
|
|
964
|
+
### 4.7.15 (2023-12-12)
|
|
966
965
|
* (bluefox) Corrected parsing of a text
|
|
967
966
|
|
|
968
|
-
### 4.7.13 (2023-12-10)
|
|
967
|
+
### 4.7.13 (2023-12-10)
|
|
969
968
|
* (bluefox) Added possibility to define the root style and embedded property
|
|
970
969
|
|
|
971
|
-
### 4.7.11 (2023-12-06)
|
|
970
|
+
### 4.7.11 (2023-12-06)
|
|
972
971
|
* (bluefox) Extended color picker with "noInputField" option
|
|
973
972
|
|
|
974
|
-
### 4.7.9 (2023-12-04)
|
|
973
|
+
### 4.7.9 (2023-12-04)
|
|
975
974
|
* (bluefox) Corrected the icon picker
|
|
976
975
|
|
|
977
|
-
### 4.7.8 (2023-12-04)
|
|
976
|
+
### 4.7.8 (2023-12-04)
|
|
978
977
|
* (foxriver76) port to `@iobroker/types`
|
|
979
978
|
|
|
980
|
-
### 4.7.6 (2023-11-29)
|
|
979
|
+
### 4.7.6 (2023-11-29)
|
|
981
980
|
* (bluefox) Added translations
|
|
982
981
|
|
|
983
|
-
### 4.7.5 (2023-11-28)
|
|
982
|
+
### 4.7.5 (2023-11-28)
|
|
984
983
|
* (bluefox) Corrected subscribe on objects in the legacy connection
|
|
985
984
|
|
|
986
|
-
### 4.7.4 (2023-11-23)
|
|
987
|
-
* (bluefox) Updated packages
|
|
985
|
+
### 4.7.4 (2023-11-23)
|
|
986
|
+
* (bluefox) Updated packages
|
|
988
987
|
* (bluefox) Made getStates method in legacy connection compatible with new one
|
|
989
988
|
|
|
990
|
-
### 4.7.3 (2023-11-08)
|
|
989
|
+
### 4.7.3 (2023-11-08)
|
|
991
990
|
* (bluefox) Updated packages
|
|
992
991
|
|
|
993
|
-
### 4.7.2 (2023-11-03)
|
|
994
|
-
* (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
|
|
995
994
|
* (foxriver76) fixed light mode color of a path in FileBrowser
|
|
996
995
|
|
|
997
|
-
### 4.7.0 (2023-10-31)
|
|
998
|
-
* (bluefox) Synced with admin
|
|
996
|
+
### 4.7.0 (2023-10-31)
|
|
997
|
+
* (bluefox) Synced with admin
|
|
999
998
|
* (bluefox) Added GIF to image files
|
|
1000
999
|
|
|
1001
|
-
### 4.6.7 (2023-10-19)
|
|
1000
|
+
### 4.6.7 (2023-10-19)
|
|
1002
1001
|
* (bluefox) Added return value for `subscribeOnInstance` for Connection class
|
|
1003
1002
|
|
|
1004
|
-
### 4.6.6 (2023-10-13)
|
|
1003
|
+
### 4.6.6 (2023-10-13)
|
|
1005
1004
|
* (bluefox) Fixed the legacy connection
|
|
1006
1005
|
|
|
1007
|
-
### 4.6.5 (2023-10-12)
|
|
1006
|
+
### 4.6.5 (2023-10-12)
|
|
1008
1007
|
* (foxriver76) fixed object browser with date
|
|
1009
1008
|
|
|
1010
|
-
### 4.6.4 (2023-10-11)
|
|
1009
|
+
### 4.6.4 (2023-10-11)
|
|
1011
1010
|
* (bluefox) Updated the packages
|
|
1012
1011
|
|
|
1013
|
-
### 4.6.3 (2023-10-09)
|
|
1014
|
-
* (bluefox) Just updated the packages
|
|
1012
|
+
### 4.6.3 (2023-10-09)
|
|
1013
|
+
* (bluefox) Just updated the packages
|
|
1015
1014
|
* (bluefox) Synced with admin
|
|
1016
1015
|
|
|
1017
|
-
### 4.6.2 (2023-09-29)
|
|
1016
|
+
### 4.6.2 (2023-09-29)
|
|
1018
1017
|
* (bluefox) Experimental feature added: update states on re-subscribe
|
|
1019
1018
|
|
|
1020
|
-
### 4.5.5 (2023-09-27)
|
|
1019
|
+
### 4.5.5 (2023-09-27)
|
|
1021
1020
|
* (bluefox) Added export for IconNoIcon
|
|
1022
1021
|
|
|
1023
|
-
### 4.5.4 (2023-09-17)
|
|
1022
|
+
### 4.5.4 (2023-09-17)
|
|
1024
1023
|
* (bluefox) Added the restricting to folder property for select file dialog
|
|
1025
1024
|
|
|
1026
|
-
### 4.5.3 (2023-08-20)
|
|
1025
|
+
### 4.5.3 (2023-08-20)
|
|
1027
1026
|
* (foxriver76) fixed css classes of TableResize, see https://github.com/ioBroker/ioBroker.admin/issues/1860
|
|
1028
1027
|
|
|
1029
|
-
### 4.5.2 (2023-08-20)
|
|
1028
|
+
### 4.5.2 (2023-08-20)
|
|
1030
1029
|
* (foxriver76) added missing export of TableResize
|
|
1031
1030
|
|
|
1032
|
-
### 4.5.1 (2023-08-19)
|
|
1031
|
+
### 4.5.1 (2023-08-19)
|
|
1033
1032
|
* (foxriver76) fix dialog TextInput
|
|
1034
1033
|
|
|
1035
|
-
### 4.5.0 (2023-08-18)
|
|
1034
|
+
### 4.5.0 (2023-08-18)
|
|
1036
1035
|
* (bluefox) Synchronize components with admin
|
|
1037
1036
|
|
|
1038
|
-
### 4.4.8 (2023-08-17)
|
|
1037
|
+
### 4.4.8 (2023-08-17)
|
|
1039
1038
|
* (bluefox) Added translations
|
|
1040
1039
|
|
|
1041
|
-
### 4.4.7 (2023-08-10)
|
|
1042
|
-
* (bluefox) Added `subscribeStateAsync` method to wait for answer
|
|
1040
|
+
### 4.4.7 (2023-08-10)
|
|
1041
|
+
* (bluefox) Added `subscribeStateAsync` method to wait for answer
|
|
1043
1042
|
* (bluefox) Added support for arrays for un/subscriptions
|
|
1044
1043
|
|
|
1045
|
-
### 4.4.5 (2023-08-01)
|
|
1044
|
+
### 4.4.5 (2023-08-01)
|
|
1046
1045
|
* (bluefox) Updated packages
|
|
1047
1046
|
|
|
1048
|
-
### 4.3.3 (2023-07-28)
|
|
1047
|
+
### 4.3.3 (2023-07-28)
|
|
1049
1048
|
* (bluefox) Added translations
|
|
1050
1049
|
|
|
1051
|
-
### 4.3.0 (2023-07-19)
|
|
1052
|
-
* (bluefox) Updated packages
|
|
1053
|
-
* (bluefox) Added translations
|
|
1054
|
-
* (bluefox) Synced object browser
|
|
1050
|
+
### 4.3.0 (2023-07-19)
|
|
1051
|
+
* (bluefox) Updated packages
|
|
1052
|
+
* (bluefox) Added translations
|
|
1053
|
+
* (bluefox) Synced object browser
|
|
1055
1054
|
* (bluefox) formatting
|
|
1056
1055
|
|
|
1057
|
-
### 4.2.1 (2023-07-17)
|
|
1058
|
-
* (bluefox) Updated packages
|
|
1056
|
+
### 4.2.1 (2023-07-17)
|
|
1057
|
+
* (bluefox) Updated packages
|
|
1059
1058
|
* (bluefox) Added translations
|
|
1060
1059
|
|
|
1061
|
-
### 4.2.0 (2023-07-07)
|
|
1062
|
-
* (bluefox) Updated packages
|
|
1060
|
+
### 4.2.0 (2023-07-07)
|
|
1061
|
+
* (bluefox) Updated packages
|
|
1063
1062
|
* (bluefox) Added new method `getObjectsById` to the socket communication
|
|
1064
1063
|
|
|
1065
|
-
### 4.1.2 (2023-06-20)
|
|
1064
|
+
### 4.1.2 (2023-06-20)
|
|
1066
1065
|
* (bluefox) Allowed setting theme name directly by theme toggle
|
|
1067
1066
|
|
|
1068
|
-
### 4.1.0 (2023-05-10)
|
|
1067
|
+
### 4.1.0 (2023-05-10)
|
|
1069
1068
|
* (bluefox) `craco-module-federation.js` was added. For node 16
|
|
1070
1069
|
|
|
1071
|
-
### 4.0.27 (2023-05-09)
|
|
1070
|
+
### 4.0.27 (2023-05-09)
|
|
1072
1071
|
* (bluefox) Allowed showing only specific root in SelectIDDialog
|
|
1073
1072
|
|
|
1074
|
-
### 4.0.26 (2023-05-08)
|
|
1073
|
+
### 4.0.26 (2023-05-08)
|
|
1075
1074
|
* (bluefox) Added IDs to the buttons in the dialog for GUI tests
|
|
1076
1075
|
|
|
1077
|
-
### 4.0.25 (2023-04-23)
|
|
1076
|
+
### 4.0.25 (2023-04-23)
|
|
1078
1077
|
* (bluefox) Extended `TextWithIcon` with defined color and icon
|
|
1079
1078
|
|
|
1080
|
-
### 4.0.24 (2023-04-03)
|
|
1079
|
+
### 4.0.24 (2023-04-03)
|
|
1081
1080
|
* (bluefox) Updated the file selector in tile mode
|
|
1082
1081
|
|
|
1083
|
-
### 4.0.23 (2023-03-27)
|
|
1082
|
+
### 4.0.23 (2023-03-27)
|
|
1084
1083
|
* (bluefox) Added translations
|
|
1085
1084
|
|
|
1086
|
-
### 4.0.22 (2023-03-22)
|
|
1085
|
+
### 4.0.22 (2023-03-22)
|
|
1087
1086
|
* (bluefox) Re-Activate legacy connection
|
|
1088
1087
|
|
|
1089
|
-
### 4.0.21 (2023-03-22)
|
|
1088
|
+
### 4.0.21 (2023-03-22)
|
|
1090
1089
|
* (bluefox) Added translations
|
|
1091
1090
|
|
|
1092
|
-
### 4.0.20 (2023-03-21)
|
|
1091
|
+
### 4.0.20 (2023-03-21)
|
|
1093
1092
|
* (bluefox) Color picker was improved
|
|
1094
1093
|
|
|
1095
|
-
### 4.0.19 (2023-03-20)
|
|
1096
|
-
* (bluefox) Packages were updated
|
|
1094
|
+
### 4.0.19 (2023-03-20)
|
|
1095
|
+
* (bluefox) Packages were updated
|
|
1097
1096
|
* (bluefox) Added new translations
|
|
1098
1097
|
|
|
1099
|
-
### 4.0.18 (2023-03-16)
|
|
1098
|
+
### 4.0.18 (2023-03-16)
|
|
1100
1099
|
* (bluefox) Packages were updated
|
|
1101
1100
|
|
|
1102
|
-
### 4.0.17 (2023-03-15)
|
|
1103
|
-
* (bluefox) Added translations
|
|
1101
|
+
### 4.0.17 (2023-03-15)
|
|
1102
|
+
* (bluefox) Added translations
|
|
1104
1103
|
* (bluefox) Added port controller to JSON config
|
|
1105
1104
|
|
|
1106
|
-
### 4.0.15 (2023-03-12)
|
|
1105
|
+
### 4.0.15 (2023-03-12)
|
|
1107
1106
|
* (bluefox) Updated the object browser and file browser
|
|
1108
1107
|
|
|
1109
|
-
### 4.0.14 (2023-03-03)
|
|
1108
|
+
### 4.0.14 (2023-03-03)
|
|
1110
1109
|
* (bluefox) added handler of alert messages
|
|
1111
1110
|
|
|
1112
|
-
### 4.0.13 (2023-02-15)
|
|
1111
|
+
### 4.0.13 (2023-02-15)
|
|
1113
1112
|
* (bluefox) Corrected the theme button
|
|
1114
1113
|
|
|
1115
|
-
### 4.0.12 (2023-02-15)
|
|
1114
|
+
### 4.0.12 (2023-02-15)
|
|
1116
1115
|
* (bluefox) made the fix for `echarts`
|
|
1117
1116
|
|
|
1118
|
-
### 4.0.11 (2023-02-14)
|
|
1119
|
-
* (bluefox) Updated packages
|
|
1117
|
+
### 4.0.11 (2023-02-14)
|
|
1118
|
+
* (bluefox) Updated packages
|
|
1120
1119
|
* (bluefox) The `chartReady` event was omitted
|
|
1121
1120
|
|
|
1122
|
-
### 4.0.10 (2023-02-10)
|
|
1123
|
-
* (bluefox) Updated packages
|
|
1121
|
+
### 4.0.10 (2023-02-10)
|
|
1122
|
+
* (bluefox) Updated packages
|
|
1124
1123
|
* (bluefox) made the fix for `material`
|
|
1125
1124
|
|
|
1126
|
-
### 4.0.9 (2023-02-02)
|
|
1125
|
+
### 4.0.9 (2023-02-02)
|
|
1127
1126
|
* (bluefox) Updated packages
|
|
1128
1127
|
|
|
1129
|
-
### 4.0.8 (2022-12-19)
|
|
1128
|
+
### 4.0.8 (2022-12-19)
|
|
1130
1129
|
* (bluefox) Extended socket with `log` command
|
|
1131
1130
|
|
|
1132
|
-
### 4.0.6 (2022-12-19)
|
|
1131
|
+
### 4.0.6 (2022-12-19)
|
|
1133
1132
|
* (bluefox) Corrected URL for the connection
|
|
1134
1133
|
|
|
1135
|
-
### 4.0.5 (2022-12-14)
|
|
1134
|
+
### 4.0.5 (2022-12-14)
|
|
1136
1135
|
* (bluefox) Added support of custom palette for color picker
|
|
1137
1136
|
|
|
1138
|
-
### 4.0.2 (2022-12-01)
|
|
1137
|
+
### 4.0.2 (2022-12-01)
|
|
1139
1138
|
* (bluefox) use `@iobroker/socket-client` instead of `Connection.tsx`
|
|
1140
1139
|
|
|
1141
|
-
### 3.5.3 (2022-11-30)
|
|
1140
|
+
### 3.5.3 (2022-11-30)
|
|
1142
1141
|
* (bluefox) Improved `renderTextWithA` function to support `<b>` and `<i>` tags
|
|
1143
1142
|
|
|
1144
|
-
### 3.5.2 (2022-11-30)
|
|
1143
|
+
### 3.5.2 (2022-11-30)
|
|
1145
1144
|
* (bluefox) updated json config component
|
|
1146
1145
|
|
|
1147
|
-
### 3.4.1 (2022-11-29)
|
|
1146
|
+
### 3.4.1 (2022-11-29)
|
|
1148
1147
|
* (bluefox) Added button text for message dialog
|
|
1149
1148
|
|
|
1150
|
-
### 3.4.0 (2022-11-29)
|
|
1149
|
+
### 3.4.0 (2022-11-29)
|
|
1151
1150
|
* (bluefox) Added file selector
|
|
1152
1151
|
|
|
1153
|
-
### 3.3.0 (2022-11-26)
|
|
1152
|
+
### 3.3.0 (2022-11-26)
|
|
1154
1153
|
* (bluefox) Added subscribe on files
|
|
1155
1154
|
|
|
1156
|
-
### 3.2.7 (2022-11-13)
|
|
1155
|
+
### 3.2.7 (2022-11-13)
|
|
1157
1156
|
* (bluefox) Added `fullWidth` property to `Dialog`
|
|
1158
1157
|
|
|
1159
|
-
### 3.2.6 (2022-11-08)
|
|
1158
|
+
### 3.2.6 (2022-11-08)
|
|
1160
1159
|
* (xXBJXx) Improved TreeTable component
|
|
1161
1160
|
|
|
1162
|
-
### 3.2.5 (2022-11-08)
|
|
1161
|
+
### 3.2.5 (2022-11-08)
|
|
1163
1162
|
* (bluefox) Added the role filter for the object browser
|
|
1164
1163
|
|
|
1165
|
-
### 3.2.4 (2022-11-03)
|
|
1164
|
+
### 3.2.4 (2022-11-03)
|
|
1166
1165
|
* (bluefox) Added support for alfa channel for `invertColor`
|
|
1167
1166
|
|
|
1168
|
-
### 3.2.3 (2022-10-26)
|
|
1167
|
+
### 3.2.3 (2022-10-26)
|
|
1169
1168
|
* (bluefox) Corrected expert mode for object browser
|
|
1170
1169
|
|
|
1171
|
-
### 3.2.2 (2022-10-25)
|
|
1170
|
+
### 3.2.2 (2022-10-25)
|
|
1172
1171
|
* (bluefox) Added support for prefixes for translations
|
|
1173
1172
|
|
|
1174
|
-
### 3.2.1 (2022-10-24)
|
|
1173
|
+
### 3.2.1 (2022-10-24)
|
|
1175
1174
|
* (bluefox) Corrected color inversion
|
|
1176
1175
|
|
|
1177
|
-
### 3.2.0 (2022-10-19)
|
|
1176
|
+
### 3.2.0 (2022-10-19)
|
|
1178
1177
|
* (bluefox) Added ukrainian translation
|
|
1179
1178
|
|
|
1180
|
-
### 3.1.35 (2022-10-17)
|
|
1179
|
+
### 3.1.35 (2022-10-17)
|
|
1181
1180
|
* (bluefox) small changes for material
|
|
1182
1181
|
|
|
1183
|
-
### 3.1.34 (2022-08-24)
|
|
1182
|
+
### 3.1.34 (2022-08-24)
|
|
1184
1183
|
* (bluefox) Implemented fallback to english by translations
|
|
1185
1184
|
|
|
1186
|
-
### 3.1.33 (2022-08-24)
|
|
1185
|
+
### 3.1.33 (2022-08-24)
|
|
1187
1186
|
* (bluefox) Added support for onchange flag
|
|
1188
1187
|
|
|
1189
|
-
### 3.1.30 (2022-08-23)
|
|
1190
|
-
* (bluefox) Added method `getCompactSystemRepositories`
|
|
1188
|
+
### 3.1.30 (2022-08-23)
|
|
1189
|
+
* (bluefox) Added method `getCompactSystemRepositories`
|
|
1191
1190
|
* (bluefox) corrected error in `ObjectBrowser`
|
|
1192
1191
|
|
|
1193
|
-
### 3.1.27 (2022-08-01)
|
|
1192
|
+
### 3.1.27 (2022-08-01)
|
|
1194
1193
|
* (bluefox) Disable file editing in FileViewer
|
|
1195
1194
|
|
|
1196
|
-
### 3.1.26 (2022-08-01)
|
|
1197
|
-
* (bluefox) Added translations
|
|
1195
|
+
### 3.1.26 (2022-08-01)
|
|
1196
|
+
* (bluefox) Added translations
|
|
1198
1197
|
* (bluefox) JSON schema was extended with missing definitions
|
|
1199
1198
|
|
|
1200
|
-
### 3.1.24 (2022-07-28)
|
|
1199
|
+
### 3.1.24 (2022-07-28)
|
|
1201
1200
|
* (bluefox) Updated file browser and object browser
|
|
1202
1201
|
|
|
1203
|
-
### 3.1.23 (2022-07-25)
|
|
1202
|
+
### 3.1.23 (2022-07-25)
|
|
1204
1203
|
* (bluefox) Extend custom filter for object selector
|
|
1205
1204
|
|
|
1206
|
-
### 3.1.22 (2022-07-22)
|
|
1205
|
+
### 3.1.22 (2022-07-22)
|
|
1207
1206
|
* (bluefox) Added i18n tools for development
|
|
1208
1207
|
|
|
1209
|
-
### 3.1.20 (2022-07-14)
|
|
1208
|
+
### 3.1.20 (2022-07-14)
|
|
1210
1209
|
* (bluefox) Allowed to show select dialog with the expert mode enabled
|
|
1211
1210
|
|
|
1212
|
-
### 3.1.19 (2022-07-08)
|
|
1211
|
+
### 3.1.19 (2022-07-08)
|
|
1213
1212
|
* (bluefox) Allowed extending translations for all languages together
|
|
1214
1213
|
|
|
1215
|
-
### 3.1.18 (2022-07-06)
|
|
1214
|
+
### 3.1.18 (2022-07-06)
|
|
1216
1215
|
* (bluefox) Added translation
|
|
1217
1216
|
|
|
1218
|
-
### 3.1.17 (2022-07-05)
|
|
1217
|
+
### 3.1.17 (2022-07-05)
|
|
1219
1218
|
* (bluefox) Deactivate JSON editor for JSONConfig because of space
|
|
1220
1219
|
|
|
1221
|
-
### 3.1.16 (2022-06-27)
|
|
1220
|
+
### 3.1.16 (2022-06-27)
|
|
1222
1221
|
* (bluefox) Update object browser
|
|
1223
1222
|
|
|
1224
|
-
### 3.1.15 (2022-06-27)
|
|
1223
|
+
### 3.1.15 (2022-06-27)
|
|
1225
1224
|
* (bluefox) Allowed using of spaces in name
|
|
1226
1225
|
|
|
1227
|
-
### 3.1.14 (2022-06-23)
|
|
1226
|
+
### 3.1.14 (2022-06-23)
|
|
1228
1227
|
* (bluefox) Added translations
|
|
1229
1228
|
|
|
1230
|
-
### 3.1.11 (2022-06-22)
|
|
1229
|
+
### 3.1.11 (2022-06-22)
|
|
1231
1230
|
* (bluefox) Added preparations for iobroker cloud
|
|
1232
1231
|
|
|
1233
|
-
### 3.1.10 (2022-06-22)
|
|
1232
|
+
### 3.1.10 (2022-06-22)
|
|
1234
1233
|
* (bluefox) Added translations
|
|
1235
1234
|
|
|
1236
|
-
### 3.1.9 (2022-06-20)
|
|
1235
|
+
### 3.1.9 (2022-06-20)
|
|
1237
1236
|
* (bluefox) Allowed working behind reverse proxy
|
|
1238
1237
|
|
|
1239
|
-
### 3.1.7 (2022-06-19)
|
|
1238
|
+
### 3.1.7 (2022-06-19)
|
|
1240
1239
|
* (bluefox) Added file select dialog
|
|
1241
1240
|
|
|
1242
|
-
### 3.1.3 (2022-06-13)
|
|
1241
|
+
### 3.1.3 (2022-06-13)
|
|
1243
1242
|
* (bluefox) Added table with resized headers
|
|
1244
1243
|
|
|
1245
|
-
### 3.1.2 (2022-06-09)
|
|
1244
|
+
### 3.1.2 (2022-06-09)
|
|
1246
1245
|
* (bluefox) Added new document icon (read only)
|
|
1247
1246
|
|
|
1248
|
-
### 3.1.1 (2022-06-09)
|
|
1247
|
+
### 3.1.1 (2022-06-09)
|
|
1249
1248
|
* (bluefox) Allowed working behind reverse proxy
|
|
1250
1249
|
|
|
1251
|
-
### 3.1.0 (2022-06-07)
|
|
1250
|
+
### 3.1.0 (2022-06-07)
|
|
1252
1251
|
* (bluefox) Some german texts were corrected
|
|
1253
1252
|
|
|
1254
|
-
### 3.0.17 (2022-06-03)
|
|
1253
|
+
### 3.0.17 (2022-06-03)
|
|
1255
1254
|
* (bluefox) Allowed calling getAdapterInstances not for admin too
|
|
1256
1255
|
|
|
1257
|
-
### 3.0.15 (2022-06-01)
|
|
1256
|
+
### 3.0.15 (2022-06-01)
|
|
1258
1257
|
* (bluefox) Updated JsonConfigComponent: password, table
|
|
1259
1258
|
|
|
1260
|
-
### 3.0.14 (2022-05-25)
|
|
1259
|
+
### 3.0.14 (2022-05-25)
|
|
1261
1260
|
* (bluefox) Added ConfigGeneric to import
|
|
1262
1261
|
|
|
1263
|
-
### 3.0.7 (2022-05-25)
|
|
1262
|
+
### 3.0.7 (2022-05-25)
|
|
1264
1263
|
* (bluefox) Made the module definitions
|
|
1265
1264
|
|
|
1266
|
-
### 3.0.6 (2022-05-25)
|
|
1265
|
+
### 3.0.6 (2022-05-25)
|
|
1267
1266
|
* (bluefox) Added JsonConfigComponent
|
|
1268
1267
|
|
|
1269
|
-
### 2.1.11 (2022-05-24)
|
|
1268
|
+
### 2.1.11 (2022-05-24)
|
|
1270
1269
|
* (bluefox) Update file browser. It supports now the file changed events.
|
|
1271
1270
|
|
|
1272
|
-
### 2.1.10 (2022-05-24)
|
|
1271
|
+
### 2.1.10 (2022-05-24)
|
|
1273
1272
|
* (bluefox) Corrected object browser
|
|
1274
1273
|
|
|
1275
|
-
### 2.1.9 (2022-05-16)
|
|
1274
|
+
### 2.1.9 (2022-05-16)
|
|
1276
1275
|
* (bluefox) Corrected expert mode in object browser
|
|
1277
1276
|
|
|
1278
|
-
### 2.1.7 (2022-05-09)
|
|
1279
|
-
* (bluefox) Changes were synchronized with adapter-react-v5
|
|
1277
|
+
### 2.1.7 (2022-05-09)
|
|
1278
|
+
* (bluefox) Changes were synchronized with adapter-react-v5
|
|
1280
1279
|
* (bluefox) Added `I18n.disableWarning` method
|
|
1281
1280
|
|
|
1282
|
-
### 2.1.6 (2022-03-28)
|
|
1283
|
-
* (bluefox) Added `log` method to connection
|
|
1281
|
+
### 2.1.6 (2022-03-28)
|
|
1282
|
+
* (bluefox) Added `log` method to connection
|
|
1284
1283
|
* (bluefox) Corrected translations
|
|
1285
1284
|
|
|
1286
|
-
### 2.1.1 (2022-03-27)
|
|
1285
|
+
### 2.1.1 (2022-03-27)
|
|
1287
1286
|
* (bluefox) Corrected error in TreeTable
|
|
1288
1287
|
|
|
1289
|
-
### 2.1.0 (2022-03-26)
|
|
1288
|
+
### 2.1.0 (2022-03-26)
|
|
1290
1289
|
* (bluefox) BREAKING_CHANGE: Corrected error with readFile(base64=false)
|
|
1291
1290
|
|
|
1292
|
-
### 2.0.0 (2022-03-26)
|
|
1291
|
+
### 2.0.0 (2022-03-26)
|
|
1293
1292
|
* (bluefox) Initial version
|
|
1294
1293
|
|
|
1295
|
-
### 0.1.0 (2022-03-23)
|
|
1294
|
+
### 0.1.0 (2022-03-23)
|
|
1296
1295
|
* (bluefox) Fixed theme errors
|
|
1297
1296
|
|
|
1298
|
-
### 0.0.4 (2022-03-22)
|
|
1297
|
+
### 0.0.4 (2022-03-22)
|
|
1299
1298
|
* (bluefox) Fixed eslint warnings
|
|
1300
1299
|
|
|
1301
|
-
### 0.0.3 (2022-03-19)
|
|
1300
|
+
### 0.0.3 (2022-03-19)
|
|
1302
1301
|
* (bluefox) beta version
|
|
1303
1302
|
|
|
1304
|
-
### 0.0.2 (2022-02-24)
|
|
1303
|
+
### 0.0.2 (2022-02-24)
|
|
1305
1304
|
* (bluefox) try to publish a first version
|
|
1306
1305
|
|
|
1307
|
-
### 0.0.1 (2022-02-24)
|
|
1306
|
+
### 0.0.1 (2022-02-24)
|
|
1308
1307
|
* initial commit
|
|
1309
1308
|
|
|
1310
|
-
## License
|
|
1311
|
-
The MIT License (MIT)
|
|
1312
|
-
|
|
1313
|
-
Copyright (c) 2019-2024 bluefox <dogafox@gmail.com>
|
|
1314
|
-
|
|
1315
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
1316
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
1317
|
-
in the Software without restriction, including without limitation the rights
|
|
1318
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
1319
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
1320
|
-
furnished to do so, subject to the following conditions:
|
|
1321
|
-
|
|
1322
|
-
The above copyright notice and this permission notice shall be included in all
|
|
1323
|
-
copies or substantial portions of the Software.
|
|
1324
|
-
|
|
1325
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
1326
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
1327
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
1328
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
1329
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
1330
|
-
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
|
|
1331
1330
|
SOFTWARE.
|