Skip to content

Instantly share code, notes, and snippets.

@gaspard
Created May 23, 2016 11:27
Show Gist options
  • Save gaspard/d903b219da185d36f45732637534db43 to your computer and use it in GitHub Desktop.
Save gaspard/d903b219da185d36f45732637534db43 to your computer and use it in GitHub Desktop.
// A way to express the full workflow of an edit in a single file
// inspired by Christian Alfoni's thoughts on rxjs-app.
// In Cerebral.js, an Operation could be a signal with a single action filtering on input.operation.
// The emit function would be a wrapper around this signal, passing required context.
// The only new element is the 'emit' function passed through the actions and "binding" them together.
export const editSingleProp = Operation
( { start: ( { input, services: { auth }, emit } ) => {
if ( auth.editAllowed ( input.path ) ) {
emit ( 'editAllowed' )
}
else {
emit ( 'editNotAllowed' )
}
}
, editAllowed:
[ ( { state, input } ) => {
// changes state to adapt UI for edit (show an <input/> field)
// and saves hooks and context so that the UI only fires the
// messages by doing something like:
// emit = editSingleProp.emitter ( { path: [ 'project', 'title' ] } )
// <input hook-create={ ( _, { elm } ) => emit ( 'focus', elm ) }
// on-blur={ ( e ) => emit ( 'blur', e ) }
// on-keyup={ ( e ) => emit ( 'keyup', e ) }
// etc />
//
state.set
( [ '$editing', ...input.path ]
, { focus: 'focusField'
, keyup: detectKey
, blur: 'commitField'
, change: 'commitField'
}
)
}
]
, editNotAllowed: [] // ignore user interaction
, error: [ logError ] // Any error
, focusField: ( context, elm ) => { elm.focus (); elm.select () }
// 'input' here corresponds to the original input in the complete operation
, commitField: ( { services: { db }, input, emit }, e ) => {
db.saveProp ( input.path, e.target.value () )
.then ( () => emit ( 'saved' ) )
.catch ( ( err ) => emit ( 'error', err ) )
}
, abortEdit: 'endEdit'
, saved: 'endEdit'
, endEdit: ( { state, input } ) => { state.unset ( [ '$editing', ...input.path ] ) }
, keyup: detectKey ( { ESC: 'abortEdit' , Enter: 'commitField' } )
}
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment