Skip to content

Instantly share code, notes, and snippets.

@bloodyKnuckles
Last active April 4, 2018 23:20
Show Gist options
  • Save bloodyKnuckles/bf43a4cecd408d41c312b6f8be5da5a8 to your computer and use it in GitHub Desktop.
Save bloodyKnuckles/bf43a4cecd408d41c312b6f8be5da5a8 to your computer and use it in GitHub Desktop.
const xs = xstream.default;
const { div, input, a, p, form, table, tbody, tr, td, makeDOMDriver } = CycleDOM;
function main (sources) {
const db$ = sources.DB
.filter(db => db.requests).map(db => db.requests)
.map(requests => {
return requests.filter(request => 'submitted' === request.status)
}).startWith([])
const form$ = sources.DOM
.select('form#actions').events('submit')
.map(evt => {evt.preventDefault(); return evt.target.elements})
const showinfo$ = sources.DOM
.select('a.show').events('click').map(evt => [
evt.target.id, evt.target.parentNode.parentNode.nextSibling.className
]).startWith([])
const radioclick$ = sources.DOM
.select('input[type=radio]').events('click')
.map(evt => evt.target).map(reset => [reset.name, reset.value])
.fold((prev, next) => {
if ( 'noa' === next[1] ) { delete prev[next[0]] }
else { prev[next[0]] = next[0] }
return prev
}, {})
.startWith({})
const vdom$ = xs.combine(db$, showinfo$, radioclick$)
.map(([requests, showinfo, radioclick]) => div({class: {container: true}}, [form({attrs: {id: 'actions'}}, [
'VEHICLE REQUEST:',
table((requests.length && requests.map(request =>
tbody([tr([
td({class: {app: true}},[
input({
attrs: {type: 'radio', name: 'action_' + request.id, value: 'approved', title: 'Approve'},
hook: {update: (o,n) => {
if ( o.data.attrs.name === n.data.attrs.name ) { n.elm.checked = o.elm.checked }
else { n.elm.checked = false }
}}
})
]),
td('.leadcol',[a('#request_'+request.id+'.show',{attrs:{href:'#', title: 'Toggle extra info'}},request.user)]),
td(request.dest), td(request.date),
td({class: {ret: true}},[
input({
attrs: {type: 'radio', name: 'action_' + request.id, value: 'rejected', title: 'Reject, with cause'},
hook: {update: (o,n) => {
if ( o.data.attrs.name === n.data.attrs.name ) { n.elm.checked = o.elm.checked }
else { n.elm.checked = false }
}}
}),
input({
attrs: {type: 'text', name: 'cause_' + request.id, value: '', title: 'Type cause for rejection here'},
hook: {update: (o,n) => {
if ( o.data.attrs.name === n.data.attrs.name ) { n.elm.value = o.elm.value }
else { n.elm.value = '' }
}}
})
]),
td([
input({
attrs: Object.assign(
{type: 'radio', name: 'action_' + request.id, value: 'noa', title: 'Reset selection'},
'undefined' === typeof radioclick['action_' + request.id]? {disabled: 'disabled'}: {}
),
hook: {update: (o,n) => n.elm.checked = false}
})
]),
]),
tr({class: {hideinfo: 'request_' + request.id === showinfo[0] ? 'hideinfo' !== showinfo[1]: true}},[
td(),
td(), td(request.dest), td(request.date),
td(),td()
])])
)) || [tbody([tr([td(),td('.alert','no requests')])])] ),
requests.length && input({attrs: {id: 'save', type: 'submit', name: 'submit', value: 'Save'}})
])]))
const ls$ = form$.map(
elements => Array.from(elements)
.reduce((values, element) => {
if (
('radio' === element.type && true === element.checked)
|| ('text' === element.type && '' !== element.value)
) {
return [...values, [element.name, element.value]]
}
else return [...values]
}, [])
).map(actions => {return {requests: actions}})
const log$ = xs.empty()
return {
DOM: vdom$,
DB: ls$,
log: log$
}
}
const LS = db$ => {
const dbb$ = db$.mapTo('saved').startWith('saved')
db$.addListener({
next: data => {
Object.keys(data).map(key => {
let lsdata = JSON.parse(window.localStorage.getItem(key))
data[key].map(action => {
const actioninfo = action[0].split('_')
lsdata = lsdata.map(record => {
if ( 'action' === actioninfo[0] && record.id + '' === actioninfo[1] + '' && 'noa' !== action[1] ) {
record.status = action[1]
return record
}
else { return record }
})
})
window.localStorage.setItem(key, JSON.stringify(lsdata))
})
},
error: ()=>{}, complete: ()=>{}
})
const windowstorage$ = xs.create({
start: listener => window.addEventListener('storage', evt => listener.next(evt)),
stop: ()=>{}
})
windowstorage$.addListener({next: evt => 1, error: ()=>{}, complete: ()=>{}})
const win$ = windowstorage$.startWith(1)
const lskeys$ = xs.fromArray(Object.keys(window.localStorage))
const ret$ = xs.combine(lskeys$, dbb$, win$)
.map(([key, dbb, win]) => {
let records = JSON.parse(localStorage.getItem(key))
records = Array.isArray(records)? records: [records]
return {[key]: records}
})
return ret$
}
Cycle.run(main, {
DOM: makeDOMDriver('#app'),
DB: LS,
log: msg$ => { msg$.addListener({next: msg => console.log(msg), error: ()=>{}, complete: ()=>{}}) }
})
//localStorage.setItem('requests', JSON.stringify([{id: 1, user: 'George', dest: 'game', date: '03/21/2018', status: 'submitted'},{id: 2, user: 'Sally', dest: 'field trip', date: '03/21/2018', status: 'approved'},{id: 3, user: 'Jill', dest: 'workshop', date: '03/22/2018', status: 'submitted'},{id: 4, user: 'John', dest: 'field trip', date: '03/22/2018', status: 'submitted'}]))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment