Skip to content

Commit

Permalink
handling changes
Browse files Browse the repository at this point in the history
  • Loading branch information
ppisljar committed Feb 12, 2019
1 parent df1006f commit 31e01aa
Show file tree
Hide file tree
Showing 16 changed files with 364 additions and 153 deletions.
296 changes: 201 additions & 95 deletions build/app.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion build/app.js.map

Large diffs are not rendered by default.

16 changes: 11 additions & 5 deletions src/app.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { h, render, Component } from 'preact';
import { Menu } from './components/menu';
import { Page } from './components/page';
import { ConfigPage, DevicesPage, DevicesEditPage, ControllersPage, ControllerEditPage, ConfigAdvancedPage, ConfigHardwarePage, RebootPage, LoadPage, RulesPage, UpdatePage, ToolsPage, FSPage, FactoryResetPage, DiscoverPage } from './pages';

import { ConfigPage, DevicesPage, DevicesEditPage, ControllersPage, ControllerEditPage, ConfigAdvancedPage, ConfigHardwarePage, RebootPage, LoadPage, RulesPage, UpdatePage, ToolsPage, FSPage, FactoryResetPage, DiscoverPage, DiffPage } from './pages';
import { loadConfig, saveConfig } from './conf/config.dat';
import { settings } from './lib/settings';


const menus = [
Expand All @@ -28,7 +28,8 @@ const menus = [

let routes = [
{ title: 'Edit Controller', href:'controllers/edit', component: ControllerEditPage },
{ title: 'Edit Device', href:'devices/edit', component: DevicesEditPage }
{ title: 'Edit Device', href:'devices/edit', component: DevicesEditPage },
{ title: 'Save to Flash', href:'tools/diff', component: DiffPage }
];
menus.map(menu => {
routes = [...routes, menu, ...menu.children];
Expand All @@ -50,6 +51,7 @@ class App extends Component {
this.state = {
menu: menus[0],
page: menus[0],
changed: false,
}
}

Expand All @@ -58,7 +60,7 @@ class App extends Component {
return (
<div id="layout">
<Menu menus={menus} open={true} selected={state.menu} />
<Page page={state.page} params={params} />
<Page page={state.page} params={params} changed={this.state.changed} />
</div>
);
}
Expand All @@ -67,6 +69,10 @@ class App extends Component {
let current = '';
const fn = () => {
const newFragment = getFragment();
const diff = settings.diff();
if(this.state.changed !== !!diff.length) {
this.setState({changed: !this.state.changed})
}
if(current !== newFragment) {
current = newFragment;
const parts = current.split('/');
Expand All @@ -77,7 +83,7 @@ class App extends Component {
}
}
}
this.interval = setInterval(fn, 50);
this.interval = setInterval(fn, 100);
}

componentWillUnmount() {}
Expand Down
73 changes: 41 additions & 32 deletions src/components/form/index.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,11 @@
import { h, Component } from 'preact';
import { get } from 'lodash';

const getKeys = object => {
const keys = [];
for (let key in object) {
if (object.hasOwnProperty(key)) {
keys.push(key);
}
}
return keys;
}
import { get, set } from 'lodash';
import { getKeys } from '../../lib/helpers';
import { settings } from '../../lib/settings';

export class Form extends Component {
constructor() {
super();
constructor(props) {
super(props);

this.saveForm = () => {
const values = {};
Expand All @@ -36,37 +28,54 @@ export class Form extends Component {
this.resetForm = () => {
this.form.reset();
}

this.onChange = (id, prop, config = {}) => {
return (e) => {
let val = this.form.elements[id].value;
if (config.type === 'checkbox') {
val = val === 'on' ? 1 : 0;
} else if (config.type === 'number') {
val = parseFloat(val);
} else if (config.type === 'select') {
val = isNaN(val) ? val : parseInt(val);
}
set(this.props.selected, prop, val);
if (config.onChange) {
config.onChange(e);
}
}
}
}

renderConfig(id, config, value) {
renderConfig(id, config, value, varName) {
switch (config.type) {
case 'string':
return (
<input id={id} type="text" value={value} />
<input id={id} type="text" value={value} onChange={this.onChange(id, varName, config)} />
);
case 'number':
return (
<input id={id} type="number" value={value} />
<input id={id} type="number" value={value} onChange={this.onChange(id, varName, config)}/>
) ;
case 'ip':
return [
(<input id={id} type="number" min="0" max="255" style="width: 80px" value={value[0]} />),
(<input id={id} type="number" min="0" max="255" style="width: 80px" value={value[1]} />),
(<input id={id} type="number" min="0" max="255" style="width: 80px" value={value[2]} />),
(<input id={id} type="number" min="0" max="255" style="width: 80px" value={value[3]} />)
(<input id={`${id}.0`} type="number" min="0" max="255" onChange={this.onChange(id, `${varName}.0`, config)} style="width: 80px" value={value ? value[0] : null} />),
(<input id={`${id}.1`} type="number" min="0" max="255" onChange={this.onChange(id, `${varName}.1`, config)} style="width: 80px" value={value ? value[1] : null} />),
(<input id={`${id}.2`} type="number" min="0" max="255" onChange={this.onChange(id, `${varName}.2`, config)} style="width: 80px" value={value ? value[2] : null} />),
(<input id={`${id}.3`} type="number" min="0" max="255" onChange={this.onChange(id, `${varName}.3`, config)} style="width: 80px" value={value ? value[3] : null} />)
]
case 'password':
return (
<input id={id} type="password" />
<input id={id} type="password" onChange={this.onChange(id, varName, config)} />
) ;
case 'checkbox':
return (
<input id={id} type="checkbox" defaultChecked={value} />
<input id={id} type="checkbox" defaultChecked={value} onChange={this.onChange(id, varName, config)} />
) ;
case 'select':
const options = (typeof config.options === 'function') ? config.options() : config.options;
return (
<select id={id} type="password" onChange={config.onChange}>
<select id={id} type="password" onChange={this.onChange(id, varName, config)}>
{options.map(option => {
const name = option instanceof Object ? option.name : option;
const val = option instanceof Object ? option.value : option;
Expand All @@ -90,15 +99,14 @@ export class Form extends Component {

return (
<div class="pure-control-group">
{configArray.map(conf => {
let val;
if (values) {
val = conf.var ? get(values, conf.var) : (values[id] ? values[id][key] : null);
}
{configArray.map((conf, i) => {

const varName = conf.var ? conf.var : (configArray.length > 1 ? `${id}.${i}` : id);
const val = get(values, varName, null);

return [
(<label for={id}>{conf.name}</label>),
this.renderConfig(id, conf, val)
this.renderConfig(id, conf, val, varName)
];
})}
</div>
Expand All @@ -122,9 +130,10 @@ export class Form extends Component {
const keys = getKeys(props.config.groups);
return (<form class="pure-form pure-form-aligned" ref={ref => this.form = ref}>
{keys.map(key => this.renderGroup(key, props.config.groups[key], props.selected))}
<div>
<button type="button" onClick={this.saveForm}>save</button><button onClick={this.resetForm}>cancel</button>
</div>
{/* <div>
<button type="button" onClick={this.saveForm}>save</button>
<button onClick={this.resetForm}>cancel</button>
</div> */}
</form>)
}
}
3 changes: 3 additions & 0 deletions src/components/page/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ export class Page extends Component {
<div id="main">
<div class="header">
> {props.page.title}
{ props.changed ? (
<a style="float: right" href="#tools/diff">CHANGED! Click here to SAVE</a>
) : (null) }
</div>

<div class="content">
Expand Down
10 changes: 3 additions & 7 deletions src/conf/config.dat.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ export const configDatParseConfig = [
[...Array(CONTROLLER_MAX)].map((x, i) => ({ prop: `controllers[${i}].protocol`, type:'byte' })),
[...Array(NOTIFICATION_MAX)].map((x, i) => ({ prop: `notifications[${i}].type`, type:'byte' })),
[...Array(TASKS_MAX)].map((x, i) => ({ prop: `tasks[${i}].device`, type:'byte' })),
{ prop: 'OLD_TaskDeviceID', type: 'longs', length: TASKS_MAX },
[...Array(TASKS_MAX)].map((x, i) => ({ prop: `tasks[${i}].OLD_TaskDeviceID`, type:'int32' })),
[...Array(TASKS_MAX)].map((x, i) => ({ prop: `tasks[${i}].gpio1`, type:'byte' })),
[...Array(TASKS_MAX)].map((x, i) => ({ prop: `tasks[${i}].gpio2`, type:'byte' })),
[...Array(TASKS_MAX)].map((x, i) => ({ prop: `tasks[${i}].gpio3`, type:'byte' })),
Expand All @@ -71,12 +71,8 @@ export const configDatParseConfig = [
[...Array(TASKS_MAX)].map((x, i) => ({ prop: `tasks[${i}].enabled`, type:'byte' })),
[...Array(CONTROLLER_MAX)].map((x, i) => ({ prop: `controllers[${i}].enabled`, type:'byte' })),
[...Array(NOTIFICATION_MAX)].map((x, i) => ({ prop: `notifications[${i}].enabled`, type:'byte' })),
{ prop: 'TaskDeviceID.1', type: 'longs', length: TASKS_MAX },// TODO
{ prop: 'TaskDeviceID.2', type: 'longs', length: TASKS_MAX },// TODO
{ prop: 'TaskDeviceID.3', type: 'longs', length: TASKS_MAX },// TODO
{ prop: 'TaskDeviceSendData.1', type: 'bytes', length: TASKS_MAX }, // TODO
{ prop: 'TaskDeviceSendData.2', type: 'bytes', length: TASKS_MAX },// TODO
{ prop: 'TaskDeviceSendData.3', type: 'bytes', length: TASKS_MAX },// TODO
[...Array(TASKS_MAX)].map((x, i) => ({ prop: `task[${i}].TaskDeviceID`, type:'longs', length: CONTROLLER_MAX })),
[...Array(TASKS_MAX)].map((x, i) => ({ prop: `task[${i}].TaskDeviceSendData`, type:'longs', length: CONTROLLER_MAX })),
{ prop: 'hardware.led.inverse', type: 'byte' },
{ prop: 'config.sleep.sleeponfailiure', type: 'byte' },
{ prop: 'UseValueLogger', type: 'byte' },// TODO
Expand Down
9 changes: 9 additions & 0 deletions src/lib/helpers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export const getKeys = object => {
const keys = [];
for (let key in object) {
if (object.hasOwnProperty(key)) {
keys.push(key);
}
}
return keys;
}
42 changes: 39 additions & 3 deletions src/lib/settings.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,53 @@
import { get, set } from 'lodash';
import { get, set, merge } from 'lodash';
import { getKeys } from './helpers';

const diff = (obj1, obj2, path = '') => {
return getKeys(obj1).map(key => {
const val1 = obj1[key];
const val2 = obj2[key];
if (val1 instanceof Object) return diff(val1, val2, `${path}.${key}`);
else if (val1 !== val2) {
return [{ path: `${path}.${key}`, val1, val2 }];
} else return [];
}).flat();
}

class Settings {
init(settings) {
this.settings = settings;
this.apply();
}

get(prop) {
return get(this.settings, prop);
}

/**
* sets changes to the current version and sets changed flag
* @param {*} prop
* @param {*} value
*/
set(prop, value) {
return set(this.settings, prop, value);
const obj = get(this.settings, prop);
const res = merge(obj, value);
set(this.settings, prop, res);
if (this.diff().length) this.changed = true;
}

/**
* returns diff between applied and current version
*/
diff() {
return diff(this.stored, this.settings);
}

/***
* applys changes and creates new version in localStorage
*/
apply() {
this.stored = JSON.parse(JSON.stringify(this.settings));
this.changed = false;
}
}

export const settings = new Settings();
export const settings = window.settings1 = new Settings();
4 changes: 4 additions & 0 deletions src/pages/config.advanced.js
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,10 @@ const formConfig = {

export class ConfigAdvancedPage extends Component {
render(props) {
formConfig.onSave = (values) => {
settings.set('config', values);
window.location.href='#devices';
}
return (
<Form config={formConfig} selected={settings.get('config')} />
);
Expand Down
7 changes: 4 additions & 3 deletions src/pages/config.hardware.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,10 @@ const formConfig = {
export class ConfigHardwarePage extends Component {
render(props) {
const config = settings.get('hardware');
formConfig.onSave = (vals) => {
settings.set('hardware', vals);
};
formConfig.onSave = (values) => {
settings.set('hardware', values);
window.location.href='#devices';
}

return (
<Form config={formConfig} selected={config} />
Expand Down
6 changes: 4 additions & 2 deletions src/pages/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { Form } from '../components/form';
import { settings } from '../lib/settings';

const formConfig = {
onSave: (vals) => { console.log(vals); },
groups: {
general: {
name: 'General',
Expand Down Expand Up @@ -54,7 +53,10 @@ const formConfig = {

export class ConfigPage extends Component {
render(props) {

formConfig.onSave = (values) => {
settings.set(`config`, values);
window.location.href='#devices';
}
const config = settings.get('config');
return (
<Form config={formConfig} selected={config} />
Expand Down
6 changes: 5 additions & 1 deletion src/pages/controllers.edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export const protocols = [
const baseFields = {

dns: { name: 'Locate Controller', type: 'select', options: [{ value: 0, name: 'Use IP Address'}, { value: 1, name: 'Use Hostname' }] },
IP: { name: 'IP', type: 'string' },
IP: { name: 'IP', type: 'ip' },
hostname: { name: 'Hostname', type: 'string' },
port: { name: 'Port', type: 'number' },
minimal_time_between: { name: 'Minimum Send Interval', type: 'number' },
Expand Down Expand Up @@ -101,6 +101,10 @@ export class ControllerEditPage extends Component {
formConfig.groups.settings.configs.protocol.onChange = (e) => {
this.setState({ protocol: e.currentTarget.value });
};
formConfig.onSave = (values) => {
settings.set(`controllers[${props.params[0]}]`, values);
window.location.href='#controllers';
}

return (
<Form config={formConfig} selected={this.config} />
Expand Down
6 changes: 5 additions & 1 deletion src/pages/devices.edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ export class DevicesEditPage extends Component {
super(props);

this.config = settings.get(`tasks[${props.params[0]}]`);
debugger;
this.state = {
device: this.config.device,
}
Expand All @@ -52,7 +53,10 @@ export class DevicesEditPage extends Component {
formConfig.groups.settings.configs.device.onChange = (e) => {
this.setState({ device: e.currentTarget.value });
};

formConfig.onSave = (values) => {
settings.set(`tasks[${props.params[0]}]`, values);
window.location.href='#devices';
}
return (
<Form config={formConfig} selected={this.config} />
);
Expand Down
Loading

0 comments on commit 31e01aa

Please sign in to comment.