From 5b8da33360a96848d0054a60abe12e27b88c189e Mon Sep 17 00:00:00 2001 From: Giulio Cesare Solaroli Date: Fri, 5 Sep 2014 18:17:41 +0200 Subject: [PATCH] Improved feedback when cancelling/saving changes --- frontend/delta/html/index_template.html | 1 + .../Clipperz/PM/UI/Components/Cards/Detail.js | 3 +- .../Clipperz/PM/UI/Components/Cards/Edit.js | 31 ++----------------- .../js/Clipperz/PM/UI/Components/Overlay.js | 21 ++++++++++++- .../PM/UI/Components/Pages/MainPage.js | 2 +- .../PM/UI/Components/Panels/MainPanel.js | 26 +--------------- .../delta/js/Clipperz/PM/UI/MainController.js | 22 ++++++------- frontend/delta/scss/core/overlay.scss | 10 ++++++ 8 files changed, 48 insertions(+), 68 deletions(-) diff --git a/frontend/delta/html/index_template.html b/frontend/delta/html/index_template.html index e36a201..8ba2715 100644 --- a/frontend/delta/html/index_template.html +++ b/frontend/delta/html/index_template.html @@ -96,6 +96,7 @@ Clipperz_normalizedNewLine = '\x0d\x0a'; loading + @js_LINKED@ diff --git a/frontend/delta/js/Clipperz/PM/UI/Components/Cards/Detail.js b/frontend/delta/js/Clipperz/PM/UI/Components/Cards/Detail.js index 0e8d760..ec7ff37 100644 --- a/frontend/delta/js/Clipperz/PM/UI/Components/Cards/Detail.js +++ b/frontend/delta/js/Clipperz/PM/UI/Components/Cards/Detail.js @@ -31,7 +31,8 @@ Clipperz.PM.UI.Components.Cards.Detail = React.createClass({ result = this.props['selectedCard']; if (result) { result['style'] = this.props['style']; - result['ask'] = this.props['ask']; + result['ask'] = (this.props['style'] == 'narrow') ? this.props['ask'] : null; + result['showGlobalMask'] = this.props['showGlobalMask']; } return result; diff --git a/frontend/delta/js/Clipperz/PM/UI/Components/Cards/Edit.js b/frontend/delta/js/Clipperz/PM/UI/Components/Cards/Edit.js index ee7898e..9d73b24 100644 --- a/frontend/delta/js/Clipperz/PM/UI/Components/Cards/Edit.js +++ b/frontend/delta/js/Clipperz/PM/UI/Components/Cards/Edit.js @@ -51,23 +51,7 @@ Clipperz.PM.UI.Components.Cards.Edit = React.createClass({ fields: function () { return this.props['fields']; }, -/* - sortedFields: function () { - var result; - var from = this.state['fromFieldPosition']; - var to = this.state['toFieldPosition']; -// console.log("FIELDS", this.fields()); - if ((from != -1) && (to != -1) && (from != to)) { - result = MochiKit.Base.clone(this.fields()); - result.splice(to, 0, result.splice(from, 1)[0]); - } else { - result = this.fields(); - } - - return result; - }, -*/ //============================================================================ positionOfField: function (aFieldReference) { @@ -90,16 +74,6 @@ Clipperz.PM.UI.Components.Cards.Edit = React.createClass({ 'toFieldPosition': -1, 'dropPosition': -1 })); - -// this.setState({ -// 'draggedFieldReference': fieldReference, -// 'fromFieldPosition': fieldPosition -/// 'toFieldPosition': 0 -// }); - -// anEvent.dataTransfer.effectAllowed = 'move'; -// anEvent.dataTransfer.setData('text/html', this.innerHTML); -// anEvent.dropEffect }, /* drag: function (anEvent) { @@ -237,7 +211,6 @@ console.log("DROP"); //, anEvent); return function (anEvent) { method(anEvent.target.value); MochiKit.Signal.signal(Clipperz.Signal.NotificationCenter, 'refreshCardEditDetail', reference); -// MochiKit.Signal.signal(Clipperz.Signal.NotificationCenter, 'refreshCardEditToolbar', reference); }; }, @@ -383,9 +356,9 @@ console.log("DROP"); //, anEvent); 'edit': true } -//console.log("RENDER CARD EDIT"); +//console.log("RENDER CARD EDIT", this.props['showGlobalMask']); return React.DOM.div({'className':'editWrapper'}, [ - React.DOM.div({'className':'mask'}), + this.props['showGlobalMask'] ? null : React.DOM.div({'className':'mask'}), React.DOM.div({'className':React.addons.classSet(classes)},[ Clipperz.PM.UI.Components.Cards.EditToolbar(this.props), React.DOM.div({'className':'content'}, [ diff --git a/frontend/delta/js/Clipperz/PM/UI/Components/Overlay.js b/frontend/delta/js/Clipperz/PM/UI/Components/Overlay.js index cb5f81a..c34b418 100644 --- a/frontend/delta/js/Clipperz/PM/UI/Components/Overlay.js +++ b/frontend/delta/js/Clipperz/PM/UI/Components/Overlay.js @@ -53,7 +53,11 @@ Clipperz.Base.extend(Clipperz.PM.UI.Components.Overlay, Object, { //------------------------------------------------------------------------- - 'show': function (aMessage) { + 'show': function (aMessage, showMask) { + if (showMask === true) { + this.showMask(); + } + this.resetStatus(); this.setMessage(aMessage); MochiKit.DOM.removeElementClass(this.element(), 'ios-overlay-hide'); @@ -61,6 +65,7 @@ Clipperz.Base.extend(Clipperz.PM.UI.Components.Overlay, Object, { }, 'done': function (aMessage, aDelayBeforeHiding) { + this.hideMask(); this.completed(this.showDoneIcon, aMessage, aDelayBeforeHiding); }, @@ -70,6 +75,20 @@ Clipperz.Base.extend(Clipperz.PM.UI.Components.Overlay, Object, { //------------------------------------------------------------------------- + 'maskElement': function () { + return this.getElement('mask'); + }, + + 'showMask': function () { + MochiKit.DOM.removeElementClass(this.maskElement(), 'hidden'); + }, + + 'hideMask': function () { + MochiKit.DOM.addElementClass(this.maskElement(), 'hidden'); + }, + + //------------------------------------------------------------------------- + 'resetStatus': function () { MochiKit.Style.showElement(this.element()); MochiKit.Style.showElement(this.getElement('spinner')); diff --git a/frontend/delta/js/Clipperz/PM/UI/Components/Pages/MainPage.js b/frontend/delta/js/Clipperz/PM/UI/Components/Pages/MainPage.js index 1effa5f..4eef72b 100644 --- a/frontend/delta/js/Clipperz/PM/UI/Components/Pages/MainPage.js +++ b/frontend/delta/js/Clipperz/PM/UI/Components/Pages/MainPage.js @@ -54,7 +54,7 @@ Clipperz.PM.UI.Components.Pages.MainPage = React.createClass({ }; classes[this.props['style']] = true; -//console.log("MAIN PAGE", this.props['ask']); +//console.log("MAIN PAGE", this.props['showGlobalMask']); return React.DOM.div({'className':React.addons.classSet(classes)}, [ this.props['style'] != 'extra-wide' ? Clipperz.PM.UI.Components.Panels.SelectionPanel(this.props) : null, Clipperz.PM.UI.Components.Panels.MainPanel(this.props), diff --git a/frontend/delta/js/Clipperz/PM/UI/Components/Panels/MainPanel.js b/frontend/delta/js/Clipperz/PM/UI/Components/Panels/MainPanel.js index 4962092..80e880a 100644 --- a/frontend/delta/js/Clipperz/PM/UI/Components/Panels/MainPanel.js +++ b/frontend/delta/js/Clipperz/PM/UI/Components/Panels/MainPanel.js @@ -93,30 +93,6 @@ Clipperz.PM.UI.Components.Panels.MainPanel = React.createClass({ }, //---------------------------------------------------------------------------- -/* - viewComponentProps: function () { - var result; - - result = this.props['selectedCard']; - if (result) { - result['style'] = this.props['style']; - } - - return result; - }, - - renderCardDetail: function () { - var result; -//console.log("PROPS", this.props); - if (this.props['mode'] == 'edit') { - result = Clipperz.PM.UI.Components.Cards.Edit(this.viewComponentProps()); - } else { - result = Clipperz.PM.UI.Components.Cards.View(this.viewComponentProps()); - } - - return result; - }, -*/ renderCardDetail: function () { return Clipperz.PM.UI.Components.Cards.Detail(this.props); @@ -190,7 +166,7 @@ Clipperz.PM.UI.Components.Panels.MainPanel = React.createClass({ }, render: function () { -//console.log("MainPanel.cards", this.props['ask']); +//console.log("MainPanel.render", this.props['showGlobalMask']); var classes = { 'panel': true, 'left': this.props['selectionPanelStatus'] == 'OPEN', diff --git a/frontend/delta/js/Clipperz/PM/UI/MainController.js b/frontend/delta/js/Clipperz/PM/UI/MainController.js index 96f196c..5fb6395 100644 --- a/frontend/delta/js/Clipperz/PM/UI/MainController.js +++ b/frontend/delta/js/Clipperz/PM/UI/MainController.js @@ -437,7 +437,8 @@ console.log("SET USER", aUser); deferredResult.setValue('_reference'); deferredResult.addMethod(aRecord, 'isArchived'); deferredResult.setValue('_isArchived'); - deferredResult.addMethod(aRecord, 'hasPendingChanges'); +// deferredResult.addMethod(aRecord, 'hasPendingChanges'); + deferredResult.addMethod(this.user(), 'hasPendingChanges'); deferredResult.setValue('hasPendingChanges'); deferredResult.addMethod(aRecord, 'label'); deferredResult.setValue('label'); @@ -965,11 +966,12 @@ console.log("SET USER", aUser); var self = this; return Clipperz.Async.callbacks("MainController.saveCardEdits_handler", [ + MochiKit.Base.method(currentPage, 'setProps', {'showGlobalMask':true}), + MochiKit.Base.method(this.overlay(), 'show', "saving …", true), MochiKit.Base.method(this.user(), 'saveChanges'), - MochiKit.Base.method(currentPage, 'setProps', {'mode':'view'}), -// MochiKit.Base.method(self, 'updateSelectedCard', {'reference':aRecordReference}, false), -// MochiKit.Base.method(self, 'refreshUI'), - MochiKit.Base.method(this, 'refreshUI', aRecordReference) + MochiKit.Base.method(currentPage, 'setProps', {'mode':'view', 'showGlobalMask':false}), + MochiKit.Base.method(this, 'refreshUI', aRecordReference), + MochiKit.Base.method(this.overlay(), 'done', "saved", 1), ], {trace:false}); }, @@ -992,12 +994,12 @@ console.log("SET USER", aUser); 'cancel': {'label':"No", 'isDefault':true, 'answer':MochiKit.Base.methodcaller('cancel', new MochiKit.Async.CancelledError())}, 'revert': {'label':"Yes", 'isDefault':false, 'answer':MochiKit.Base.methodcaller('callback')} } - }) + }), ], [ // MochiKit.Async.succeed ]), - MochiKit.Base.method(currentPage, 'setProps', {'mode':'view'}), MochiKit.Base.method(this.user(), 'revertChanges'), + MochiKit.Base.method(currentPage, 'setProps', {'mode':'view'}), MochiKit.Base.bind(function () { var info; @@ -1030,11 +1032,9 @@ console.log("SET USER", aUser); var currentPage = this.pages()[this.currentPage()]; deferredResult = new Clipperz.Async.Deferred('MainController.ask', {trace:false}); - currentPage.setProps({'ask': {'info': someInfo, 'deferred':deferredResult}}); + currentPage.setProps({'ask': {'info': someInfo, 'deferred':deferredResult}, 'showGlobalMask':true }); -// deferredResult.addCallback(function (aResult) { console.log("ASK - OK", aResult); return aResult; }); -// deferredResult.addErrback(function (aResult) { console.log("ASK - FAIL", aResult); return aResult; }); - deferredResult.addBothPass(MochiKit.Base.method(currentPage, 'setProps', {'ask': null})); + deferredResult.addBothPass(MochiKit.Base.method(currentPage, 'setProps', {'ask': null, 'showGlobalMask':false })); return deferredResult; }, diff --git a/frontend/delta/scss/core/overlay.scss b/frontend/delta/scss/core/overlay.scss index 81dafd5..3b74be4 100644 --- a/frontend/delta/scss/core/overlay.scss +++ b/frontend/delta/scss/core/overlay.scss @@ -1,6 +1,16 @@ @import "mixin"; div.overlay { + @include mask; + + .mask { + position: fixed; + z-index: -2; + + &.hidden { + display: none; + } + } z-index: 99999; position: fixed; top: 50%;