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

Delta Between Two Patch Sets: app/views/inspector.js

Issue 13516044: Update conflict ux per updated design.
Left Patch Set: Created 11 years, 7 months ago
Right Patch Set: Update conflict ux per updated design. Created 11 years, 7 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « app/views/ghost-inspector.js ('k') | app/views/viewlet-manager.js » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 /* 1 /*
2 This file is part of the Juju GUI, which lets users view and manage Juju 2 This file is part of the Juju GUI, which lets users view and manage Juju
3 environments within a graphical interface (https://launchpad.net/juju-gui). 3 environments within a graphical interface (https://launchpad.net/juju-gui).
4 Copyright (C) 2012-2013 Canonical Ltd. 4 Copyright (C) 2012-2013 Canonical Ltd.
5 5
6 This program is free software: you can redistribute it and/or modify it under 6 This program is free software: you can redistribute it and/or modify it under
7 the terms of the GNU Affero General Public License version 3, as published by 7 the terms of the GNU Affero General Public License version 3, as published by
8 the Free Software Foundation. 8 the Free Software Foundation.
9 9
10 This program is distributed in the hope that it will be useful, but WITHOUT 10 This program is distributed in the hope that it will be useful, but WITHOUT
(...skipping 561 matching lines...) Expand 10 before | Expand all | Expand 10 after
572 572
573 @method _onInitiateDestroy 573 @method _onInitiateDestroy
574 @param {Object} evt The event data. 574 @param {Object} evt The event data.
575 @return {undefined} Nothing. 575 @return {undefined} Nothing.
576 */ 576 */
577 _onInitiateDestroy: function(evt) { 577 _onInitiateDestroy: function(evt) {
578 evt.halt(); 578 evt.halt();
579 this.closeInspector(); 579 this.closeInspector();
580 this.initiateServiceDestroy(); 580 this.initiateServiceDestroy();
581 this.options.environment.topo.fire('clearState'); 581 this.options.environment.topo.fire('clearState');
582 },
583
584 /**
585 Keep checkboxes in sync with their textual representation.
586
587 @method onCheckboxUpdate
588 @param {Y.Event} ev the event from the change triggered.
589
590 */
591 onCheckboxUpdate: function(ev) {
592 var checked = ev.currentTarget.get('checked');
593 ev.currentTarget.ancestor('.toggle').one('.textvalue').set('text',
594 checked);
582 }, 595 },
583 596
584 /** 597 /**
585 Handles exposing the service. 598 Handles exposing the service.
586 599
587 @method toggleExpose 600 @method toggleExpose
588 @param {Y.EventFacade} e An event object. 601 @param {Y.EventFacade} e An event object.
589 @return {undefined} Nothing. 602 @return {undefined} Nothing.
590 */ 603 */
591 toggleExpose: function(e) { 604 toggleExpose: function(e) {
(...skipping 590 matching lines...) Expand 10 before | Expand all | Expand 10 after
1182 * @method _makeConflict 1195 * @method _makeConflict
1183 * @param {Y.Node} node of the input to mark. 1196 * @param {Y.Node} node of the input to mark.
1184 * 1197 *
1185 */ 1198 */
1186 '_makeConflict': function(node) { 1199 '_makeConflict': function(node) {
1187 node.addClass('conflict'); 1200 node.addClass('conflict');
1188 }, 1201 },
1189 1202
1190 'changed': function(node, key, field) { 1203 'changed': function(node, key, field) {
1191 // Not all nodes need to show the conflict ux. This is true when 1204 // Not all nodes need to show the conflict ux. This is true when
1192 // multiple binds to a single model field are set, such as in pretty 1205 // multiple binds to a single model field are set, such as in the
1193 // toggle checkbox UI. 1206 // checkbox widgets used in the inspector.
1194 if (node.getData('skipconflictux')) { 1207 if (node.getData('skipconflictux')) {
1195 return; 1208 return;
1196 } 1209 }
1197 var modelValue = this.model.get(key); 1210 var controls = this.container.one('.controls');
1198 var fieldValue = field.get(node); 1211 if (this.changedValues[key]) {
1199 if (modelValue !== fieldValue) {
1200 this._makeModified(node); 1212 this._makeModified(node);
1213 controls.removeClass('closed');
1201 } else { 1214 } else {
1202 this._clearModified(node); 1215 this._clearModified(node);
1216 // Databinding calls syncedFields if there are no more changed
1217 // values, and that method is responsible for closing the controls.
1203 } 1218 }
1204 }, 1219 },
1205 1220
1206 'conflict': function(node, model, viewletName, resolve, binding) { 1221 'conflict': function(node, model, viewletName, resolve, binding) {
1207 // Not all nodes need to show the conflict ux. This is true when 1222 // Not all nodes need to show the conflict ux. This is true when
1208 // multiple binds to a single model field are set, such as in pretty 1223 // multiple binds to a single model field are set, such as in the
1209 // toggle checkbox UI. 1224 // checkbox widgets used in the inspector.
1210 if (node.getData('skipconflictux')) { 1225 if (node.getData('skipconflictux')) {
1211 return; 1226 return;
1212 } 1227 }
1213 /** 1228 /**
1214 Calls the databinding resolve method 1229 Calls the databinding resolve method
1215 @method sendResolve 1230 @method sendResolve
1216 */ 1231 */
1217 var option; 1232 var option;
1233 var viewlet = this;
1218 var key = node.getData('bind'); 1234 var key = node.getData('bind');
1219 var modelValue = model.get(key); 1235 var modelValue = model.get(key);
1220 var field = binding.field; 1236 var field = binding.field;
1221 var wrapper = node.ancestor('.settings-wrapper'); 1237 var wrapper = node.ancestor('.settings-wrapper');
1222 var resolver = wrapper.one('.resolver'); 1238 var resolver = wrapper.one('.resolver');
1223 if (resolver) { 1239 if (resolver) {
1224 option = resolver.one('.config-field'); 1240 option = resolver.one('.config-field');
1225 } 1241 }
1226 var handlers = []; 1242 var handlers = [];
1227 1243
1244 if (binding.annotations.conflict) {
1245 binding.annotations.conflict.cancel();
1246 }
1247
1248 binding.annotations.conflict = {
1249 /**
1250 Cancel this conflict handling UX.
1251
1252 @method cancel
1253 */
1254 cancel: function() {
1255 handlers.forEach(function(h) { h.detach();});
1256 viewlet._clearModified(node);
1257 viewlet._clearConflictPending(node);
1258 viewlet._clearConflict(node);
1259 resolver.addClass('hidden');
1260 delete binding.annotations.conflict;
1261 }
1262 };
1228 /** 1263 /**
1229 User selects one of the two conflicting values. 1264 User selects one of the two conflicting values.
1230 @method sendResolve 1265
1266 @method sendResolve
1231 */ 1267 */
1232 function sendResolve(e) { 1268 function sendResolve(e) {
1233 e.halt(true); 1269 e.halt(true);
1234 var formValue = field.get(node); 1270 binding.annotations.conflict.cancel();
1235 handlers.forEach(function(h) { h.detach();}); 1271 if (e.currentTarget.hasClass('conflicted-env')) {
1236 1272 resolve(modelValue);
1237 /* jshint -W040 */ 1273 } else {
1238 // Ignore 'possible strict violation' 1274 var formValue = field.get(node);
1239 this._clearModified(node); 1275 resolve(formValue);
1240 this._clearConflict(node);
1241
1242 if (resolver) {
1243 resolver.addClass('hidden');
1244 } 1276 }
1245
1246 if (e.currentTarget.hasClass('conflicted-env')) {
1247 resolve(node, viewletName, modelValue);
1248 } else {
1249 resolve(node, viewletName, formValue);
1250 }
1251 } 1277 }
1252 1278
1253 /** 1279 /**
1254 User selects a conflicting field, show the resolution UI 1280 User selects a conflicting field, show the resolution UI
1255 1281
1256 @method setupResolver 1282 @method setupResolver
1257 */ 1283 */
1258 function setupResolver(e) { 1284 function setupResolver(e) {
1259 e.halt(true); 1285 e.halt(true);
1260 /* jshint -W040 */ 1286 viewlet._clearConflictPending(node);
1261 // Ignore 'possible strict violation' 1287 viewlet._makeConflict(node);
1262 this._clearConflictPending(node); 1288 viewlet._makeConflict(option);
1263 this._makeConflict(node); 1289 option.setStyle('width', node.get('offsetWidth'));
1264 // Checkboxes don't have the option node to select a value. 1290 option.setHTML(modelValue);
1265 if (option) { 1291 resolver.removeClass('hidden');
1266 this._makeConflict(option);
1267 option.setStyle('width', node.get('offsetWidth'));
1268 option.setHTML(modelValue);
1269 }
1270 if (resolver) {
1271 resolver.removeClass('hidden');
1272 }
1273 } 1292 }
1274 1293
1275 // On conflict just indicate. 1294 // On conflict just indicate.
1276 this._clearModified(node); 1295 this._clearModified(node);
1277 this._makeConflictPending(node); 1296 this._makeConflictPending(node);
1278 1297
1279 handlers.push(wrapper.delegate( 1298 handlers.push(wrapper.delegate(
1280 'click', 1299 'click', setupResolver, '.conflict-pending'));
1281 setupResolver, 1300 handlers.push(wrapper.delegate('click', sendResolve, '.conflict'));
1282 '.conflict-pending', 1301 },
1283 this)); 1302
1284 1303 'unsyncedFields': function() {
1285 handlers.push(wrapper.delegate('click', sendResolve,
1286 '.conflict', this));
1287 },
1288 'unsyncedFields': function(dirtyFields) {
1289 var node = this.container.one('.controls .confirm'); 1304 var node = this.container.one('.controls .confirm');
1290 if (!node.getData('originalText')) { 1305 if (!node.getData('originalText')) {
1291 node.setData('originalText', node.getHTML()); 1306 node.setData('originalText', node.getHTML());
1292 } 1307 }
1293 node.setHTML('Overwrite'); 1308 node.setHTML('Overwrite');
1294 }, 1309 },
1310
1295 'syncedFields': function() { 1311 'syncedFields': function() {
1296 var node = this.container.one('.controls .confirm'); 1312 var controls = this.container.one('.controls');
1313 var node = controls.one('.confirm');
1297 var title = node.getData('originalText'); 1314 var title = node.getData('originalText');
1315 // For checkboxes remove their modified nodes.
1316 this.container.all('.modified.boolean').remove();
1317 // All else remove their modified class
1298 this.container.all('.modified').removeClass('modified'); 1318 this.container.all('.modified').removeClass('modified');
1299 if (title) { 1319 if (title) {
1300 node.setHTML(title); 1320 node.setHTML(title);
1301 } 1321 }
1322 controls.addClass('closed');
1302 } 1323 }
1303 }; 1324 };
1304 1325
1305 // Mixin Conflict Handling. 1326 // Mixin Conflict Handling.
1306 viewletNS.config = Y.merge(viewletNS.config, ConflictMixin); 1327 viewletNS.config = Y.merge(viewletNS.config, ConflictMixin);
1307 viewletNS.constraints = Y.merge(viewletNS.constraints, ConflictMixin); 1328 viewletNS.constraints = Y.merge(viewletNS.constraints, ConflictMixin);
1308 1329
1309 1330
1310 /** 1331 /**
1311 Service Inspector Viewlet Manager Controller 1332 Service Inspector Viewlet Manager Controller
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
1403 'panel', 1424 'panel',
1404 'transition', 1425 'transition',
1405 'view', 1426 'view',
1406 // Imported viewlets 1427 // Imported viewlets
1407 'viewlet-charm-details', 1428 'viewlet-charm-details',
1408 'viewlet-inspector-header', 1429 'viewlet-inspector-header',
1409 'viewlet-inspector-overview', 1430 'viewlet-inspector-overview',
1410 'viewlet-service-config', 1431 'viewlet-service-config',
1411 'viewlet-service-constraints', 1432 'viewlet-service-constraints',
1412 'viewlet-service-ghost', 1433 'viewlet-service-ghost',
1413 'viewlet-unit-details' 1434 'viewlet-unit-details',
1435 'viewlet-service-relations'
1414 ] 1436 ]
1415 }); 1437 });
1416 1438
LEFTRIGHT

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