From 2c1946e35f3996f87ab91d0e874e6057d075b246 Mon Sep 17 00:00:00 2001 From: Alice Rottersman Date: Tue, 10 Oct 2017 13:10:45 -0400 Subject: [PATCH 1/3] Pass /account browser url to app * We'll be adding a new page: the Account Page * Allow the /account url to feed through to the web app, so that it can handle it accordingly --- src/mmw/apps/home/urls.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mmw/apps/home/urls.py b/src/mmw/apps/home/urls.py index 592b0a0f4..11f1b2f57 100644 --- a/src/mmw/apps/home/urls.py +++ b/src/mmw/apps/home/urls.py @@ -11,6 +11,7 @@ '', url(r'^$', home_page, name='home_page'), url(r'^draw/?$', home_page, name='home_page'), + url(r'^account/?$', home_page, name='account'), url(r'^projects/$', projects, name='projects'), url(r'^project/$', project, name='project'), url(r'^project/new/', project, name='project'), From d9f676e5f2dbfce014845b609ca535a904a05521 Mon Sep 17 00:00:00 2001 From: Alice Rottersman Date: Tue, 10 Oct 2017 13:13:56 -0400 Subject: [PATCH 2/3] Add Account Page Skeleton * Add new browser route /account and wire it to the new `account/AccountController` * AccountController will behave similarly to the "Projects" page - Render its view, AccountContainerView, in the "footer" region of the app - It's styled to be on top the other page elements - Hide LayerPicker and Geocoder regions * Add two placeholder sub-pages to AccountContainerView: Profile, Account - There will be a third sub-page -- Preferences, so keep it easy to add new sub-pages - Placeholder templates display sub-page header * Add link to "My Account" in header's user dropdown --- src/mmw/js/src/account/controllers.js | 33 +++++++++ src/mmw/js/src/account/models.js | 18 +++++ src/mmw/js/src/account/templates/account.html | 1 + .../js/src/account/templates/container.html | 20 ++++++ src/mmw/js/src/account/templates/profile.html | 1 + src/mmw/js/src/account/views.js | 71 +++++++++++++++++++ src/mmw/js/src/core/templates/header.html | 1 + src/mmw/js/src/core/utils.js | 2 + src/mmw/js/src/routes.js | 2 + src/mmw/sass/main.scss | 1 + src/mmw/sass/pages/_account.scss | 43 +++++++++++ 11 files changed, 193 insertions(+) create mode 100644 src/mmw/js/src/account/controllers.js create mode 100644 src/mmw/js/src/account/models.js create mode 100644 src/mmw/js/src/account/templates/account.html create mode 100644 src/mmw/js/src/account/templates/container.html create mode 100644 src/mmw/js/src/account/templates/profile.html create mode 100644 src/mmw/js/src/account/views.js create mode 100644 src/mmw/sass/pages/_account.scss diff --git a/src/mmw/js/src/account/controllers.js b/src/mmw/js/src/account/controllers.js new file mode 100644 index 000000000..1973362d2 --- /dev/null +++ b/src/mmw/js/src/account/controllers.js @@ -0,0 +1,33 @@ +"use strict"; + +var App = require('../app'), + views = require('./views'), + models = require('./models'), + coreUtils= require('../core/utils'); + +var AccountController = { + accountPrepare: function() { + App.rootView.geocodeSearchRegion.empty(); + }, + + account: function() { + App.rootView.footerRegion.show( + new views.AccountContainerView({ + model: new models.AccountContainerModel() + }) + ); + + App.rootView.layerPickerRegion.empty(); + + App.state.set('active_page', coreUtils.accountPageTitle); + }, + + accountCleanUp: function() { + App.rootView.footerRegion.empty(); + App.showLayerPicker(); + } +}; + +module.exports = { + AccountController: AccountController +}; diff --git a/src/mmw/js/src/account/models.js b/src/mmw/js/src/account/models.js new file mode 100644 index 000000000..0a88c96f7 --- /dev/null +++ b/src/mmw/js/src/account/models.js @@ -0,0 +1,18 @@ +"use strict"; + +var Backbone = require('../../shim/backbone'); + +var ACCOUNT = 'account'; +var PROFILE = 'profile'; + +var AccountContainerModel = Backbone.Model.extend({ + defaults: { + active_page: PROFILE + } +}); + +module.exports = { + ACCOUNT: ACCOUNT, + PROFILE: PROFILE, + AccountContainerModel: AccountContainerModel +}; diff --git a/src/mmw/js/src/account/templates/account.html b/src/mmw/js/src/account/templates/account.html new file mode 100644 index 000000000..aa341db86 --- /dev/null +++ b/src/mmw/js/src/account/templates/account.html @@ -0,0 +1 @@ +

Account

diff --git a/src/mmw/js/src/account/templates/container.html b/src/mmw/js/src/account/templates/container.html new file mode 100644 index 000000000..6fc640316 --- /dev/null +++ b/src/mmw/js/src/account/templates/container.html @@ -0,0 +1,20 @@ +
+
+ + +
+ +
+ diff --git a/src/mmw/js/src/account/templates/profile.html b/src/mmw/js/src/account/templates/profile.html new file mode 100644 index 000000000..3f4631a3a --- /dev/null +++ b/src/mmw/js/src/account/templates/profile.html @@ -0,0 +1 @@ +

Profile

diff --git a/src/mmw/js/src/account/views.js b/src/mmw/js/src/account/views.js new file mode 100644 index 000000000..63b9182aa --- /dev/null +++ b/src/mmw/js/src/account/views.js @@ -0,0 +1,71 @@ +"use strict"; + +var Marionette = require('../../shim/backbone.marionette'), + models = require('./models'), + containerTmpl = require('./templates/container.html'), + profileTmpl = require('./templates/profile.html'), + accountTmpl = require('./templates/account.html'); + +var ProfileView = Marionette.ItemView.extend({ + template: profileTmpl +}); + +var AccountView = Marionette.ItemView.extend({ + template: accountTmpl +}); + +var AccountContainerView = Marionette.LayoutView.extend({ + // model AccountContainerModel + + template: containerTmpl, + + ui: { + profile: '[data-action="viewprofile"]', + account: '[data-action="viewaccount"]' + }, + + events: { + 'click @ui.profile': 'viewProfile', + 'click @ui.account': 'viewAccount' + }, + + modelEvents: { + 'change:active_page': 'render' + }, + + regions: { + infoContainer: '.account-page-container' + }, + + showActivePage: function() { + var activePage = this.model.get('active_page'); + + switch(activePage) { + case models.PROFILE: + this.infoContainer.show(new ProfileView()); + break; + case models.ACCOUNT: + this.infoContainer.show(new AccountView()); + break; + default: + console.error("Account page, ", activePage, + ", is not supported."); + } + }, + + onRender: function() { + this.showActivePage(); + }, + + viewProfile: function() { + this.model.set('active_page', models.PROFILE); + }, + + viewAccount: function() { + this.model.set('active_page', models.ACCOUNT); + } +}); + +module.exports = { + AccountContainerView: AccountContainerView +}; diff --git a/src/mmw/js/src/core/templates/header.html b/src/mmw/js/src/core/templates/header.html index 8a796c4cd..38e77d0c9 100644 --- a/src/mmw/js/src/core/templates/header.html +++ b/src/mmw/js/src/core/templates/header.html @@ -20,6 +20,7 @@ {% if not itsi_embed %}
  • My Projects
  • {% endif %} +
  • My Account
  • Logout
  • diff --git a/src/mmw/js/src/core/utils.js b/src/mmw/js/src/core/utils.js index 3ced9e395..84a56d6e5 100644 --- a/src/mmw/js/src/core/utils.js +++ b/src/mmw/js/src/core/utils.js @@ -33,6 +33,8 @@ var utils = { projectsPageTitle: 'Projects', + accountPageTitle: 'Account', + filterNoData: function(data) { if (data && !isNaN(data) && isFinite(data)) { return data.toFixed(3); diff --git a/src/mmw/js/src/routes.js b/src/mmw/js/src/routes.js index 9ee14a5d8..6ed6ea7a2 100644 --- a/src/mmw/js/src/routes.js +++ b/src/mmw/js/src/routes.js @@ -4,6 +4,7 @@ var router = require('./router').router, settings = require('./core/settings'), DrawController = require('./draw/controllers').DrawController, AnalyzeController = require('./analyze/controllers').AnalyzeController, + AccountController = require('./account/controllers').AccountController, DataCatalogController = require('./data_catalog/controllers').DataCatalogController, ModelingController = require('./modeling/controllers').ModelingController, CompareController = require('./compare/controllers').CompareController, @@ -14,6 +15,7 @@ var router = require('./router').router, router.addRoute(/^/, DrawController, 'splash'); router.addRoute(/^draw/, DrawController, 'draw'); router.addRoute(/^analyze/, AnalyzeController, 'analyze'); +router.addRoute(/^account/, AccountController, 'account'); router.addRoute('project/new/:modelPackage(/)', ModelingController, 'makeNewProject'); router.addRoute('project(/:projectId)(/scenario/:scenarioId)(/)', ModelingController, 'project'); router.addRoute('project/:projectId/clone(/)', ModelingController, 'projectClone'); diff --git a/src/mmw/sass/main.scss b/src/mmw/sass/main.scss index 3d7e9fe15..c975ed9e1 100644 --- a/src/mmw/sass/main.scss +++ b/src/mmw/sass/main.scss @@ -77,6 +77,7 @@ "pages/model", "pages/compare", "pages/projects", + "pages/account", "pages/water-balance", "pages/registration", "pages/data-catalog"; diff --git a/src/mmw/sass/pages/_account.scss b/src/mmw/sass/pages/_account.scss new file mode 100644 index 000000000..f79c94daa --- /dev/null +++ b/src/mmw/sass/pages/_account.scss @@ -0,0 +1,43 @@ +#account-container { + padding: 2em; + display: flex; + flex-direction: row; + position: absolute; + top: 44px; + left: 0; + right: 0; + bottom: 0; + z-index: 100; + background-color: #eceff1; + transition: 0.3s ease left, 0.3s ease right; + + > .page-toggle-column { + width: 100px; + } + + > .account-page-column { + flex-grow: 1; + } +} + +#account-container .page-toggle-button { + background: none; + border: none; + display: block; + font-size: $font-size-h4; + font-weight: lighter; + + &.active { + font-weight: bolder; + color: $brand-primary; + } +} + +#account-container .account-page-container { + background: $paper; + padding: 2rem; + box-sizing: content-box; + box-shadow: 1px 1px 1px 0px rgba(0, 0, 0, 0.5); + margin-left: 8em; + max-width: 700px; +} From cec61103e99f47f83c69558d5af92bf6fce7aa45 Mon Sep 17 00:00:00 2001 From: Alice Rottersman Date: Wed, 11 Oct 2017 17:42:32 -0400 Subject: [PATCH 3/3] Show guest user login modal if they try to access account page * If a not-logged in user goes to the account page view the browser route, show them the login modal. Display their account page on success --- src/mmw/js/src/account/controllers.js | 37 ++++++++++++++++++++------- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/src/mmw/js/src/account/controllers.js b/src/mmw/js/src/account/controllers.js index 1973362d2..8e3044e27 100644 --- a/src/mmw/js/src/account/controllers.js +++ b/src/mmw/js/src/account/controllers.js @@ -3,6 +3,7 @@ var App = require('../app'), views = require('./views'), models = require('./models'), + router = require('../router').router, coreUtils= require('../core/utils'); var AccountController = { @@ -11,15 +12,7 @@ var AccountController = { }, account: function() { - App.rootView.footerRegion.show( - new views.AccountContainerView({ - model: new models.AccountContainerModel() - }) - ); - - App.rootView.layerPickerRegion.empty(); - - App.state.set('active_page', coreUtils.accountPageTitle); + showLoginOrAccountView(); }, accountCleanUp: function() { @@ -28,6 +21,32 @@ var AccountController = { } }; +function showAccountView() { + App.rootView.footerRegion.show( + new views.AccountContainerView({ + model: new models.AccountContainerModel() + }) + ); + App.rootView.layerPickerRegion.empty(); + + App.state.set('active_page', coreUtils.accountPageTitle); +} + +function showLoginOrAccountView() { + App.user.fetch().always(function() { + if (App.user.get('guest')) { + var loginSuccess = function() { + router.navigate("/account", { trigger: true }); + }; + App.showLoginModal(loginSuccess); + // Until the user has logged in, show the main page + router.navigate("/", { trigger: true }); + } else { + showAccountView(); + } + }); +} + module.exports = { AccountController: AccountController };