Help ReactJS classes for adapter config
Getting started
If you want to create the configuration page with react:
- Create github repo for adapter.
- execute
npx create-react-app src
. It will take a while. cd src
- Modify package.json file in src directory:
- Change
name
fromsrc
toADAPTERNAME-admin
(Of course replaceADAPTERNAME
with yours) - Add to dependencies:
Versions can be higher. So your src/package.json should look like:
"@material-ui/core": "^4.2.0", "react-icons": "^3.7.0", "@iobroker/adapter-react": "^0.1.0", "gulp": "^4.0.2", "del": "^5.0.0"
- Change
{
"name": "ADAPTERNAME-admin",
"version": "0.1.0",
"private": true,
"dependencies": {
"clsx": "^1.1.0",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"react-icons": "^3.10.0",
"react-scripts": "^3.4.1",
"@material-ui/core": "^4.10.2",
"@material-ui/lab": "^4.0.0-alpha.56",
"@iobroker/adapter-react": "^actual-version",
"del": "^5.1.0",
"gulp": "^4.0.2"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": "react-app"
},
"homepage": ".",
"browserslist": [
">0.2%",
"not dead",
"not ie <= 11",
"not op_mini all"
]
}
- Call in
src
:npm install
- Copy gulpfile.js into
src
:cp node_modules/@iobroker/adapter-react/gulpfile.js gulpfile.js
- Start your dummy application
npm run start
for developing or build withnpm run build
and copy files inbuild
directory towww
or toadmin
. In admin you must renameindex.html
toindex_m.html
. - You can do that with
gulp
tasks:gulp build
,gulp copy
,gulp renameIndex
orgulp renameTab
Development
- Add socket.io to public/index.html After
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
insert
<script>
var script = document.createElement('script');
window.registerSocketOnLoad = function (cb) {
window.socketLoadedHandler = cb;
};
const parts = (window.location.search || '').replace(/^\?/, '').split('&');
const query = {};
parts.forEach(item => {
const [name, val] = item.split('=');
query[decodeURIComponent(name)] = val !== undefined ? decodeURIComponent(val) : true;
});
script.onload = function () { typeof window.socketLoadedHandler === 'function' && window.socketLoadedHandler(); };
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';
document.head.appendChild(script);
</script>
- Add to App.js constructor initialization for I18n:
class App extends GenericApp {
constructor(props) {
const extendedProps = {...props};
extendedProps.encryptedFields = ['pass']; // this parameter will be encrypted and decrypted automatically
extendedProps.translations = {
'en': require('./i18n/en'),
'de': require('./i18n/de'),
'ru': require('./i18n/ru'),
'pt': require('./i18n/pt'),
'nl': require('./i18n/nl'),
'fr': require('./i18n/fr'),
'it': require('./i18n/it'),
'es': require('./i18n/es'),
'pl': require('./i18n/pl'),
'zh-cn': require('./i18n/zh-cn'),
};
// get actual admin port
extendedProps.socket = {port: parseInt(window.location.port, 10)};
// Only if close, save buttons are not required at the bottom (e.g. if admin tab)
// extendedProps.bottomButtons = false;
// only for debug purposes
if (extendedProps.socket.port === 3000) {
extendedProps.socket.port = 8081;
}
super(extendedProps);
}
...
}
- Replace index.js with following code to support themes:
import React from 'react';
import ReactDOM from 'react-dom';
import { MuiThemeProvider} from '@material-ui/core/styles';
import * as serviceWorker from './serviceWorker';
import './index.css';
import App from './App';
import { version } from '../package.json';
import theme from '@iobroker/adapter-react/Theme';
console.log('iobroker.scenes@' + version);
let themeName = window.localStorage ? window.localStorage.getItem('App.theme') || 'light' : 'light';
function build() {
return ReactDOM.render(<MuiThemeProvider theme={ theme(themeName) }>
<App onThemeChange={_theme => {
themeName = _theme;
build();
}}/>
</MuiThemeProvider>, document.getElementById('root'));
}
build();
// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: http://bit.ly/CRA-PWA
serviceWorker.unregister();
- Add to App.js encoding and decoding of values:
class App extend GenericApp {
...
onPrepareLoad(settings) {
settings.pass = this.decode(settings.pass);
}
onPrepareSave(settings) {
settings.pass = this.encode(settings.pass);
}
}
Components
Connection.js
GenericApp.js
i18n.js
Theme.js
Dialogs
Confirm.js
Usage:
import React from 'react';
import ConfirmDialog from '@iobroker/adapter-react/Dialogs/Confirm'
import I18n from '@iobroker/adapter-react/i18n';
class ExportImportDialog extends React.Component {
constructor(props) {
super(props);
this.state = {
confirmDialog: false,
};
}
renderConfirmDialog() {
if (!this.state.confirmDialog) {
return null;
}
return <ConfirmDialog
title={ I18n.t('Scene will be overwritten.') }
text={ I18n.t('All data will be lost. Confirm?') }
ok={ I18n.t('Yes') }
cancel={ I18n.t('Cancel') }
onClose={isYes => {
this.setState({ confirmDialog: false} );
}}
/>;
}
render() {
return <div>
<Button onClick={ () => this.setState({confirmDialog: true}) }>Click</Button>
{ this.renderConfirmDialog() }
</div>
}
}
export default ExportImportDialog;
Error.js
Message.js
SelectID.js
Components
Utils.js
getObjectNameFromObj
getObjectNameFromObj(obj, settings, options, isDesc)
Get object name from single object.
Usage: Utils.getObjectNameFromObj(this.objects[id], null, {language: I18n.getLanguage()})
getObjectIcon
getObjectIcon(id, obj)
Get icon from object.
Usage:
const icon = Utils.getObjectIcon(id, this.objects[id]);
return (<img src={icon}/>);
isUseBright
isUseBright(color, defaultValue)
Usage: `
Loader.js
Logo.js
Router.js
ObjectBrowser.js
Changelog
1.4.6 (2020-11-07)
- (bluefox) Better icon processing
- (bluefox) Added getParentId function
1.4.4 (2020-11-02)
- (bluefox) Fix React warning
1.4.3 (2020-10-30)
- (bluefox) Optimize loading
1.4.2 (2020-10-29)
- (UncleSamSwiss) More JSDoc issues fixed
1.4.1 (2020-10-20)
- (UncleSamSwiss) Made Router generic
- (UncleSamSwiss) Fixed getThemeName(), it will always return a string (never null).
- (UncleSamSwiss) Fixed issue with Router DTS not properly extending React.Component<>
1.4.0 (2020-10-04)
- (UncleSamSwiss) added a lot of JSDoc comments and fixed some errors
License
The MIT License (MIT)
Copyright (c) 2019-2020 bluefox dogafox@gmail.com
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.