Last active
April 4, 2018 23:20
-
-
Save bloodyKnuckles/bf43a4cecd408d41c312b6f8be5da5a8 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
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