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

Side by Side Diff: app/views/inspector.js

Issue 13516044: Update conflict ux per updated design.
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:
View unified diff | Download patch
OLDNEW
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 1070 matching lines...) Expand 10 before | Expand all | Expand 10 after
1081 * 1081 *
1082 * Marking checkboxes in the UI is done a little differently and requires 1082 * Marking checkboxes in the UI is done a little differently and requires
1083 * condition checking in these helpers. 1083 * condition checking in these helpers.
1084 * 1084 *
1085 * @method _clearModified 1085 * @method _clearModified
1086 * @param {Y.Node} node of the input to clear. 1086 * @param {Y.Node} node of the input to clear.
1087 * 1087 *
1088 */ 1088 */
1089 '_clearModified': function(node) { 1089 '_clearModified': function(node) {
1090 if (node.getAttribute('type') === 'checkbox') { 1090 if (node.getAttribute('type') === 'checkbox') {
1091 var n = node.get('parentNode').one('.modified'); 1091 var n = node.ancestor('.toggle').one('.modified');
1092 if (n) { 1092 if (n) {
1093 n.remove(); 1093 n.remove();
1094 } 1094 }
1095 1095
1096 // If the value isn't modified it can't be in conflict. 1096 // If the value isn't modified it can't be in conflict.
1097 this._clearConflictPending(node); 1097 this._clearConflictPending(node);
1098 } else { 1098 } else {
1099 node.removeClass('modified'); 1099 node.removeClass('modified');
1100 } 1100 }
1101 }, 1101 },
1102 1102
1103 /** 1103 /**
1104 * Mark the given node to not be marked as 'modified' in the UX. 1104 * Mark the given node to not be marked as 'modified' in the UX.
1105 * 1105 *
1106 * @method _markModified 1106 * @method _markModified
1107 * @param {Y.Node} node of the input to mark. 1107 * @param {Y.Node} node of the input to mark.
1108 * 1108 *
1109 */ 1109 */
1110 '_makeModified': function(node) { 1110 '_makeModified': function(node) {
1111 if (node.getAttribute('type') === 'checkbox') { 1111 if (node.getAttribute('type') === 'checkbox') {
1112 node.get('parentNode').append( 1112 node.ancestor('.toggle').one('label').append(
1113 Y.Node.create('<span class="modified boolean"/>')); 1113 Y.Node.create('<span class="modified boolean"/>'));
1114 this._clearConflictPending(node); 1114 this._clearConflictPending(node);
1115 } else { 1115 } else {
1116 node.addClass('modified'); 1116 node.addClass('modified');
1117 } 1117 }
1118 }, 1118 },
1119 1119
1120 /** 1120 /**
1121 * Reset the given node to not be marked as 'conflict-pending' in the UX. 1121 * Reset the given node to not be marked as 'conflict-pending' in the UX.
1122 * 1122 *
1123 * Marking checkboxes in the UI is done a little differently and requires 1123 * Marking checkboxes in the UI is done a little differently and requires
1124 * condition checking in these helpers. 1124 * condition checking in these helpers.
1125 * 1125 *
1126 * @method _clearConflictPending 1126 * @method _clearConflictPending
1127 * @param {Y.Node} node of the input to clear. 1127 * @param {Y.Node} node of the input to clear.
1128 * 1128 *
1129 */ 1129 */
1130 '_clearConflictPending': function(node) { 1130 '_clearConflictPending': function(node) {
1131 if (node.getAttribute('type') === 'checkbox') { 1131 if (node.getAttribute('type') === 'checkbox') {
1132 var n = node.get('parentNode').one('.conflict-pending'); 1132 var n = node.ancestor('.toggle').one('.conflict-pending');
1133 if (n) { 1133 if (n) {
1134 n.remove(); 1134 n.remove();
1135 } 1135 }
1136 } else { 1136 } else {
1137 node.removeClass('conflict-pending'); 1137 node.removeClass('conflict-pending');
1138 } 1138 }
1139 }, 1139 },
1140 1140
1141 /** 1141 /**
1142 * Mark the given node to not be marked as 'conflict-pending' in the UX. 1142 * Mark the given node to not be marked as 'conflict-pending' in the UX.
1143 * 1143 *
1144 * Marking checkboxes in the UI is done a little differently and requires 1144 * Marking checkboxes in the UI is done a little differently and requires
1145 * condition checking in these helpers. 1145 * condition checking in these helpers.
1146 * 1146 *
1147 * @method _makeConflictPending 1147 * @method _makeConflictPending
1148 * @param {Y.Node} node of the input to mark. 1148 * @param {Y.Node} node of the input to mark.
1149 * 1149 *
1150 */ 1150 */
1151 '_makeConflictPending': function(node) { 1151 '_makeConflictPending': function(node) {
1152 if (node.getAttribute('type') === 'checkbox') { 1152 if (node.getAttribute('type') === 'checkbox') {
1153 node.get('parentNode').append( 1153 node.get('parentNode').prepend(
1154 Y.Node.create('<span class="conflict-pending boolean"/>')); 1154 Y.Node.create('<span class="conflict-pending boolean"/>'));
1155 } else { 1155 } else {
1156 node.addClass('conflict-pending'); 1156 node.addClass('conflict-pending');
1157 } 1157 }
1158 }, 1158 },
1159 1159
1160 /** 1160 /**
1161 * Reset the given node to not be marked as 'conflict' in the UX. 1161 * Reset the given node to not be marked as 'conflict' in the UX.
1162 * 1162 *
1163 * Marking checkboxes in the UI is done a little differently and requires 1163 * Marking checkboxes in the UI is done a little differently and requires
(...skipping 17 matching lines...) Expand all
1181 * 1181 *
1182 * @method _makeConflict 1182 * @method _makeConflict
1183 * @param {Y.Node} node of the input to mark. 1183 * @param {Y.Node} node of the input to mark.
1184 * 1184 *
1185 */ 1185 */
1186 '_makeConflict': function(node) { 1186 '_makeConflict': function(node) {
1187 node.addClass('conflict'); 1187 node.addClass('conflict');
1188 }, 1188 },
1189 1189
1190 'changed': function(node, key, field) { 1190 'changed': function(node, key, field) {
1191 // 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
1193 // toggle checkbox UI.
bac 2013/09/11 18:14:59 That last phrase doesn't make sense to me.
1194 if (node.getData('skipconflictux')) {
jeff.pihach 2013/09/11 15:32:53 This feels like it should be a feature of the data
rharding 2013/09/12 13:11:54 I'll disagree here. The conflict UX is handled via
1195 return;
1196 }
1191 var controls = this.container.one('.controls'); 1197 var controls = this.container.one('.controls');
1192 if (this.changedValues[key]) { 1198 if (this.changedValues[key]) {
1193 this._makeModified(node); 1199 this._makeModified(node);
1194 controls.removeClass('closed'); 1200 controls.removeClass('closed');
1195 } else { 1201 } else {
1196 this._clearModified(node); 1202 this._clearModified(node);
1197 // Databinding calls syncedFields if there are no more changed 1203 // Databinding calls syncedFields if there are no more changed
1198 // values, and that method is responsible for closing the controls. 1204 // values, and that method is responsible for closing the controls.
1199 } 1205 }
1200 }, 1206 },
1201 1207
1202 'conflict': function(node, model, viewletName, resolve, binding) { 1208 'conflict': function(node, model, viewletName, resolve, binding) {
1209 // Not all nodes need to show the conflict ux. This is true when
1210 // multiple binds to a single model field are set, such as in pretty
1211 // toggle checkbox UI.
1212 if (node.getData('skipconflictux')) {
jeff.pihach 2013/09/11 15:32:53 Same goes for here.
1213 return;
1214 }
1203 /** 1215 /**
1204 Calls the databinding resolve method 1216 Calls the databinding resolve method
1205 @method sendResolve 1217 @method sendResolve
1206 */ 1218 */
1219 var option;
1207 var key = node.getData('bind'); 1220 var key = node.getData('bind');
1208 var modelValue = model.get(key); 1221 var modelValue = model.get(key);
1209 var field = binding.field; 1222 var field = binding.field;
1210 var wrapper = node.ancestor('.settings-wrapper'); 1223 var wrapper = node.ancestor('.settings-wrapper');
1211 var resolver = wrapper.one('.resolver'); 1224 var resolver = wrapper.one('.resolver');
1212 var option = resolver.one('.config-field'); 1225 if (resolver) {
1226 option = resolver.one('.config-field');
1227 }
1213 var handlers = []; 1228 var handlers = [];
1214 1229
1215 /** 1230 /**
1216 User selects one of the two conflicting values. 1231 User selects one of the two conflicting values.
1217 @method sendResolve 1232 @method sendResolve
1218 */ 1233 */
1219 function sendResolve(e) { 1234 function sendResolve(e) {
1220 e.halt(true); 1235 e.halt(true);
1221 var formValue = field.get(node); 1236 var formValue = field.get(node);
1222 handlers.forEach(function(h) { h.detach();}); 1237 handlers.forEach(function(h) { h.detach();});
1223 1238
1224 /* jshint -W040 */ 1239 /* jshint -W040 */
1225 // Ignore 'possible strict violation' 1240 // Ignore 'possible strict violation'
1226 this._clearModified(node); 1241 this._clearModified(node);
1227 this._clearConflict(node); 1242 this._clearConflict(node);
1228 1243
1229 resolver.addClass('hidden'); 1244 if (resolver) {
1245 resolver.addClass('hidden');
1246 }
1230 1247
1231 if (e.currentTarget.hasClass('conflicted-env')) { 1248 if (e.currentTarget.hasClass('conflicted-env')) {
1232 resolve(modelValue); 1249 resolve(modelValue);
1233 } else { 1250 } else {
1234 resolve(formValue); 1251 resolve(formValue);
1235 } 1252 }
1236 } 1253 }
1237 1254
1238 /** 1255 /**
1239 User selects a conflicting field, show the resolution UI 1256 User selects a conflicting field, show the resolution UI
1240 1257
1241 @method setupResolver 1258 @method setupResolver
1242 */ 1259 */
1243 function setupResolver(e) { 1260 function setupResolver(e) {
1244 e.halt(true); 1261 e.halt(true);
1245 /* jshint -W040 */ 1262 /* jshint -W040 */
1246 // Ignore 'possible strict violation' 1263 // Ignore 'possible strict violation'
1247 this._clearConflictPending(node); 1264 this._clearConflictPending(node);
1248 this._makeConflict(node); 1265 this._makeConflict(node);
1249 this._makeConflict(option); 1266 // Checkboxes don't have the option node to select a value.
1250 option.setStyle('width', node.get('offsetWidth')); 1267 if (option) {
1251 option.setHTML(modelValue); 1268 this._makeConflict(option);
1252 resolver.removeClass('hidden'); 1269 option.setStyle('width', node.get('offsetWidth'));
1270 option.setHTML(modelValue);
1271 }
1272 if (resolver) {
1273 resolver.removeClass('hidden');
1274 }
1253 } 1275 }
1254 1276
1255 // On conflict just indicate. 1277 // On conflict just indicate.
1256 this._clearModified(node); 1278 this._clearModified(node);
1257 this._makeConflictPending(node); 1279 this._makeConflictPending(node);
1258 1280
1259 handlers.push(wrapper.delegate( 1281 handlers.push(wrapper.delegate(
1260 'click', 1282 'click',
1261 setupResolver, 1283 setupResolver,
1262 '.conflict-pending', 1284 '.conflict-pending',
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
1389 'viewlet-charm-details', 1411 'viewlet-charm-details',
1390 'viewlet-inspector-header', 1412 'viewlet-inspector-header',
1391 'viewlet-inspector-overview', 1413 'viewlet-inspector-overview',
1392 'viewlet-service-config', 1414 'viewlet-service-config',
1393 'viewlet-service-constraints', 1415 'viewlet-service-constraints',
1394 'viewlet-service-ghost', 1416 'viewlet-service-ghost',
1395 'viewlet-unit-details' 1417 'viewlet-unit-details'
1396 ] 1418 ]
1397 }); 1419 });
1398 1420
OLDNEW

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