Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(628)

Unified Diff: app/app.js

Issue 9119044: Converted service and unit views to use promises
Patch Set: Converted service and unit views to use promises Created 11 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: app/app.js
=== modified file 'app/app.js'
--- app/app.js 2013-04-30 15:49:27 +0000
+++ app/app.js 2013-05-02 19:57:17 +0000
@@ -252,6 +252,8 @@
}
}
+ this.renderEnvironment = true;
+
// This attribute is used by the namespaced URL tracker.
// _routeSeen is part of a mechanism to prevent non-namespaced routes
// from being processed multiple times when multiple namespaces are
@@ -501,24 +503,61 @@
*/
show_unit: function(req) {
// This replacement honors service names that have a hyphen in them.
- var unit_id = req.params.id.replace(/^(\S+)-(\d+)$/, '$1/$2');
- var unit = this.db.units.getById(unit_id);
- if (unit) {
- // Once the unit is loaded we need to get the full details of the
- // service. Otherwise the relations data will not be available.
- var service = this.db.services.getById(unit.service);
- }
- this.showView(
- 'unit',
- // The querystring is used to handle highlighting relation rows in
- // links from notifications about errors.
- { getModelURL: Y.bind(this.getModelURL, this),
- unit: unit,
+ var unitId = req.params.id.replace(/^(\S+)-(\d+)$/, '$1/$2');
+ var serviceId = unitId.split('/')[0];
+ var self = this,
+ options = {
+ getModelURL: Y.bind(this.getModelURL, this),
db: this.db,
env: this.env,
querystring: req.query,
landscape: this.landscape,
- nsRouter: this.nsRouter });
+ nsRouter: this.nsRouter
+ };
+ // Give the page 100 milliseconds to try and load the model
+ // before we show a loading screen.
+ var handle = setTimeout(function() {
bcsaller 2013/05/02 21:25:46 I can envision a way that we can declare requireme
+ self.showView('unit', options);
+ }, 100);
+
+ var promise = this.modelController.getService(serviceId);
+ promise.then(
+ // If there is a service available then we need to check if the unit
+ // is available.
+ function(models) {
+ clearTimeout(handle);
+ var unit = self.db.units.getById(unitId);
+ if (unit) {
+ options.unit = unit;
+ self.showView('unit', options);
+ } else {
+ // If there is no unit available in this service then we show
+ // a notification and then redirect to the service.
+ self.db.notifications.add(
+ new Y.juju.models.Notification({
+ title: 'Unit is not available',
+ message: 'The unit you are trying to view does not exist',
+ level: 'error'
+ })
+ );
+ self.fire('navigateTo', {url: self.nsRouter.url(
+ {gui: '/service/' + serviceId})});
+ }
+ },
+ // If there is no service available then there definitely is no unit
+ // available so we create a notification and redirect the user to the
+ // environment view.
+ function() {
+ clearTimeout(handle);
+ self.db.notifications.add(
+ new Y.juju.models.Notification({
+ title: 'Service is not available',
+ message: 'The service you are trying to view does not exist',
+ level: 'error'
+ })
+ );
+ self.fire('navigateTo', {url: self.nsRouter.url({gui: '/'})});
+ });
},
/**
@@ -526,22 +565,43 @@
* @private
*/
_buildServiceView: function(req, viewName) {
- var service = this.db.services.getById(req.params.id);
- this.showView(viewName, {
- model: service,
- db: this.db,
- env: this.env,
- landscape: this.landscape,
- getModelURL: Y.bind(this.getModelURL, this),
- nsRouter: this.nsRouter,
- querystring: req.query
- }, {}, function(view) {
- // If the view contains a method call fitToWindow,
- // we will execute it after getting the view rendered.
- if (view.fitToWindow) {
- view.fitToWindow();
- }
- });
+ var self = this,
+ options = {
+ db: this.db,
+ env: this.env,
+ landscape: this.landscape,
+ getModelURL: Y.bind(self.getModelURL, this),
+ nsRouter: this.nsRouter,
+ querystring: req.query
+ };
+ // Give the page 100 milliseconds to try and load the model
+ // before we show a loading screen.
+ var handle = setTimeout(function() {
+ self.showView(viewName, options);
+ }, 100);
+
+ var promise = this.modelController.getServiceWithCharm(req.params.id);
+ promise.then(
+ function(models) {
+ clearTimeout(handle);
+ options.model = models.service;
+ // Calling update allows showView to be called multiple times but
+ // only have its config updated not re-rendered.
+ self.showView(viewName, options, { update: true });
+ },
+ function() {
+ clearTimeout(handle);
+ self.showView(viewName, options, { update: true },
+ function(view) {
+ // At this point the service view could be in loading state
+ // or showing details but the service has become unavailable
gary.poster 2013/05/02 21:01:02 Thanks for the clarification. It can only be in a
+ // or was never available. This calls a method on the view
+ // to redirect to the environment and to create a notification
+ if (typeof view.noServiceAvailable === 'function') {
+ view.noServiceAvailable();
+ }
+ });
+ });
},
/**
@@ -785,18 +845,21 @@
},
/**
- Determine if the browser should be visible or not.
+ Determine if the browser or environment should be rendered or not.
When hitting internal :gui: views, the browser needs to disappear
entirely from the UX for users. However, when we pop back it needs to
appear back in the previous state.
- @method checkShowBrowser
+ The environment only needs to render when another full page view isn't
+ visible.
+
+ @method toggleStaticViews
@param {Request} req current request object.
@param {Response} res current response object.
@param {function} next callable for the next route in the chain.
*/
- checkShowBrowser: function(req, res, next) {
+ toggleStaticViews: function(req, res, next) {
var url = req.url,
match = /(logout|:gui:\/(charms|service|unit))/;
bcsaller 2013/05/02 21:25:46 I'd almost rather the routes contained metadata, l
var subapps = this.get('subApps');
@@ -805,8 +868,13 @@
var charmstore = subapps.charmstore;
if (url.match(match)) {
charmstore.hidden = true;
+ // XXX At some point in the near future we will add the ability to
+ // route on root namespaced paths and this check will no longer
+ // be needed
+ this.renderEnvironment = false;
} else {
charmstore.hidden = false;
+ this.renderEnvironment = true;
}
charmstore.updateVisible();
}
@@ -827,6 +895,9 @@
* @method show_environment
*/
show_environment: function(req, res, next) {
+ if (!this.renderEnvironment) {
+ next(); return;
bcsaller 2013/05/02 21:25:46 newline
+ }
var self = this,
view = this.getViewInfo('environment'),
options = {
@@ -962,9 +1033,8 @@
// Called on each request.
{ path: '*', callbacks: 'check_user_credentials'},
{ path: '*', callbacks: 'show_notifications_view'},
- // Root.
+ { path: '*', callbacks: 'toggleStaticViews'},
{ path: '*', callbacks: 'show_environment'},
- { path: '*', callbacks: 'checkShowBrowser'},
// Charms.
{ path: '/charms/',
callbacks: 'show_charm_collection',
« no previous file with comments | « [revision details] ('k') | app/views/service.js » ('j') | app/views/service.js » ('J')

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b