Created
February 13, 2019 19:05
-
-
Save andersevenrud/bf1b611e9c0291b0ba0e6d701ba5f7b0 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import './index.scss'; | |
import osjs from 'osjs'; | |
import {name as applicationName} from './metadata.json'; | |
import {h, app} from 'hyperapp'; | |
import {Box, BoxContainer, Button, Toolbar, TextField, SelectField} from '@osjs/gui'; | |
/////////////////////////////////////////////////////// | |
// Custom GUI Elements | |
/////////////////////////////////////////////////////// | |
/* | |
* A container that holds a label and input | |
*/ | |
const FieldContainer = (props, children) => | |
h(Box, {margin: false}, [ | |
h(BoxContainer, {}, props.label), | |
...children | |
]); | |
/* | |
* A container that holds a text field | |
*/ | |
const TextFieldContainer = props => (state, actions) => | |
h(FieldContainer, props, h(TextField, { | |
value: state.form[props.name], | |
name: props.name, | |
oninput: ev => actions.onInput(ev) | |
})); | |
/** | |
* A container that holds a select field | |
*/ | |
const SelectFieldContainer = props => (state, actions) => | |
h(FieldContainer, props, h(SelectField, { | |
choices: props.choices, | |
value: state.form[props.name], | |
name: props.name, | |
onchange: ev => actions.onInput(ev) | |
})); | |
/////////////////////////////////////////////////////// | |
// Windows | |
/////////////////////////////////////////////////////// | |
/* | |
* Our main window | |
*/ | |
const renderMainWindow = (core, proc) => ($content, win) => { | |
$content.appendChild( | |
document.createTextNode('This is just some window') | |
); | |
}; | |
/* | |
* Our form window | |
*/ | |
const renderFormWindow = (core, proc) => ($content, win) => { | |
const defaultValues = { | |
first_name: '', | |
last_name: '', | |
gender: '' | |
}; | |
// This is our GUI view with the form | |
const view = (state, actions) => | |
h(Box, { | |
grow: 1, | |
shrink: 1 | |
}, [ | |
h(Box, { | |
grow: 1, | |
shrink: 1, | |
margin: false | |
}, [ | |
h(TextFieldContainer, { | |
name: 'first_name', | |
label: 'First Name' | |
}), | |
h(TextFieldContainer, { | |
name: 'last_name', | |
label: 'Last Name' | |
}), | |
h(SelectFieldContainer, { | |
name: 'gender', | |
label: 'Gender', | |
choices: ['', 'Male', 'Female'] | |
}) | |
]), | |
h(Toolbar, {justify: 'flex-end'}, [ | |
h(Button, {onclick: () => actions.save()}, 'Save'), | |
h(Button, {onclick: () => actions.reset()}, 'Clear') | |
]) | |
]); | |
// This is our GUI state and event handler | |
const happ = app({ | |
form: defaultValues | |
}, { | |
// Reset form to default values | |
reset: () => { | |
return {form: defaultValues}; | |
}, | |
// Sends the save signal and resets values | |
save: () => (state, actions) => { | |
proc.emit('save-form', state.form); | |
actions.reset(); | |
}, | |
// Sets the form values | |
load: form => ({form}), | |
// Sets a form value based on input | |
onInput: ev => state => { | |
const {name, value} = ev.target; | |
return {form: Object.assign({}, state.form, {[name]: value})}; | |
} | |
}, view, $content); | |
// This will signal the hyperapp to reset the form with given data | |
proc.on('load-form', form => { | |
happ.load(form); | |
}); | |
}; | |
/* | |
* Our list window | |
*/ | |
const renderListWindow = (core, proc) => ($content, win) => { | |
// This is our GUI view with the form | |
const view = (state, actions) => | |
h(Box, {}, [ | |
h(BoxContainer, {}, 'When you save a form it appears below. Click it to set the form data into another window'), | |
...state.forms.map((form, index) => { | |
return h(Box, {}, [ | |
h('div', {}, `First Name: ${form.first_name}`), | |
h('div', {}, `Last Name: ${form.last_name}`), | |
h('div', {}, `Gender: ${form.gender}`), | |
h(Button, {onclick: () => actions.select(form)}, 'Load'), | |
h(Button, {onclick: () => actions.delete(index)}, 'Delete') | |
]) | |
}) | |
]); | |
// This is our GUI state and event handler | |
const happ = app({ | |
forms: [] | |
}, { | |
// Send the load signal with the saved form values | |
select: form => { | |
proc.emit('load-form', form) | |
}, | |
// Removes a saved form by index | |
delete: index => state => { | |
const newFormList = state.forms; | |
newFormList.splice(index, 1); | |
return {forms: newFormList}; | |
}, | |
// Adds a form to our list | |
addFormData: form => state => { | |
return {forms: [...state.forms, form]}; | |
} | |
}, view, $content); | |
// This will signal the hyperapp to add a form to our list | |
proc.on('save-form', form => { | |
happ.addFormData(form); | |
}); | |
}; | |
/////////////////////////////////////////////////////// | |
// Application | |
/////////////////////////////////////////////////////// | |
// Our launcher | |
const register = (core, args, options, metadata) => { | |
// Create a new Application instance | |
const proc = core.make('osjs/application', {args, options, metadata}); | |
// Create our windows | |
proc | |
.createWindow({ | |
title: 'Main Window', | |
position: {top: 100, left: 10}, | |
dimension: {width: 400, height: 400}, | |
}) | |
.render(renderMainWindow(core, proc)) | |
.on('destroy', () => proc.destroy()); | |
proc | |
.createWindow({ | |
title: 'Form Window', | |
position: {top: 100, left: 420}, | |
dimension: {width: 400, height: 400}, | |
attributes: {closeable: false} | |
}) | |
.render(renderFormWindow(core, proc)); | |
proc | |
.createWindow({ | |
title: 'List Window', | |
position: {top: 520, left: 10}, | |
dimension: {width: 400, height: 400}, | |
attributes: {closeable: false} | |
}) | |
.render(renderListWindow(core, proc)); | |
return proc; | |
}; | |
osjs.register(applicationName, register); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment