Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(154)

Side by Side Diff: chrome/browser/resources/options/manage_profile_overlay.js

Issue 125993002: Add error handling for supervised user import flow. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Address review comments. Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 cr.define('options', function() { 5 cr.define('options', function() {
6 var OptionsPage = options.OptionsPage; 6 var OptionsPage = options.OptionsPage;
7 var ArrayDataModel = cr.ui.ArrayDataModel; 7 var ArrayDataModel = cr.ui.ArrayDataModel;
8 8
9 /** 9 /**
10 * ManageProfileOverlay class 10 * ManageProfileOverlay class
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
51 // Override the create-profile-ok and create-* keydown handlers, to avoid 51 // Override the create-profile-ok and create-* keydown handlers, to avoid
52 // closing the overlay until we finish creating the profile. 52 // closing the overlay until we finish creating the profile.
53 $('create-profile-ok').onclick = function(event) { 53 $('create-profile-ok').onclick = function(event) {
54 self.submitCreateProfile_(); 54 self.submitCreateProfile_();
55 }; 55 };
56 56
57 $('create-profile-cancel').onclick = function(event) { 57 $('create-profile-cancel').onclick = function(event) {
58 CreateProfileOverlay.cancelCreateProfile(); 58 CreateProfileOverlay.cancelCreateProfile();
59 }; 59 };
60 60
61 $('import-existing-managed-user-link').hidden =
62 !loadTimeData.getBoolean('allowCreateExistingManagedUsers');
63
64 $('manage-profile-cancel').onclick = 61 $('manage-profile-cancel').onclick =
65 $('delete-profile-cancel').onclick = function(event) { 62 $('delete-profile-cancel').onclick = function(event) {
66 OptionsPage.closeOverlay(); 63 OptionsPage.closeOverlay();
67 }; 64 };
68 $('delete-profile-ok').onclick = function(event) { 65 $('delete-profile-ok').onclick = function(event) {
69 OptionsPage.closeOverlay(); 66 OptionsPage.closeOverlay();
70 if (BrowserOptions.getCurrentProfile().isManaged) 67 if (BrowserOptions.getCurrentProfile().isManaged)
71 return; 68 return;
72 chrome.send('deleteProfile', [self.profileInfo_.filePath]); 69 chrome.send('deleteProfile', [self.profileInfo_.filePath]);
73 }; 70 };
(...skipping 19 matching lines...) Expand all
93 OptionsPage.closeOverlay(); 90 OptionsPage.closeOverlay();
94 SyncSetupOverlay.startSignIn(); 91 SyncSetupOverlay.startSignIn();
95 }; 92 };
96 93
97 $('create-profile-managed-sign-in-again-link').onclick = function(event) { 94 $('create-profile-managed-sign-in-again-link').onclick = function(event) {
98 OptionsPage.closeOverlay(); 95 OptionsPage.closeOverlay();
99 SyncSetupOverlay.showSetupUI(); 96 SyncSetupOverlay.showSetupUI();
100 }; 97 };
101 98
102 $('import-existing-managed-user-link').onclick = function(event) { 99 $('import-existing-managed-user-link').onclick = function(event) {
103 OptionsPage.closeOverlay();
104 OptionsPage.navigateToPage('managedUserImport'); 100 OptionsPage.navigateToPage('managedUserImport');
105 }; 101 };
106 }, 102 },
107 103
108 /** @override */ 104 /** @override */
109 didShowPage: function() { 105 didShowPage: function() {
110 chrome.send('requestDefaultProfileIcons'); 106 chrome.send('requestDefaultProfileIcons');
111 107
112 // Just ignore the manage profile dialog on Chrome OS, they use /accounts. 108 // Just ignore the manage profile dialog on Chrome OS, they use /accounts.
113 if (!cr.isChromeOS && window.location.pathname == '/manageProfile') 109 if (!cr.isChromeOS && window.location.pathname == '/manageProfile')
(...skipping 13 matching lines...) Expand all
127 var manageNameField = $('manage-profile-name'); 123 var manageNameField = $('manage-profile-name');
128 // Supervised users cannot edit their names. 124 // Supervised users cannot edit their names.
129 if (manageNameField.disabled) 125 if (manageNameField.disabled)
130 $('manage-profile-ok').focus(); 126 $('manage-profile-ok').focus();
131 else 127 else
132 manageNameField.focus(); 128 manageNameField.focus();
133 }, 129 },
134 130
135 /** 131 /**
136 * Registers event handlers that are common between create and manage modes. 132 * Registers event handlers that are common between create and manage modes.
137 * @param {string} mode A label that specifies the type of dialog 133 * @param {string} mode A label that specifies the type of dialog box which
138 * box which is currently being viewed (i.e. 'create' or 134 * is currently being viewed (i.e. 'create' or 'manage').
139 * 'manage').
140 * @param {function()} submitFunction The function that should be called 135 * @param {function()} submitFunction The function that should be called
141 * when the user chooses to submit (e.g. by clicking the OK button). 136 * when the user chooses to submit (e.g. by clicking the OK button).
142 * @private 137 * @private
143 */ 138 */
144 registerCommonEventHandlers_: function(mode, submitFunction) { 139 registerCommonEventHandlers_: function(mode, submitFunction) {
145 var self = this; 140 var self = this;
146 $(mode + '-profile-icon-grid').addEventListener('change', function(e) { 141 $(mode + '-profile-icon-grid').addEventListener('change', function(e) {
147 self.onIconGridSelectionChanged_(mode); 142 self.onIconGridSelectionChanged_(mode);
148 }); 143 });
149 $(mode + '-profile-name').oninput = function(event) { 144 $(mode + '-profile-name').oninput = function(event) {
150 self.onNameChanged_(event, mode); 145 self.onNameChanged_(mode);
151 }; 146 };
152 $(mode + '-profile-ok').onclick = function(event) { 147 $(mode + '-profile-ok').onclick = function(event) {
153 OptionsPage.closeOverlay(); 148 OptionsPage.closeOverlay();
154 submitFunction(); 149 submitFunction();
155 }; 150 };
156 }, 151 },
157 152
158 /** 153 /**
159 * Set the profile info used in the dialog. 154 * Set the profile info used in the dialog.
160 * @param {Object} profileInfo An object of the form: 155 * @param {Object} profileInfo An object of the form:
161 * profileInfo = { 156 * profileInfo = {
162 * name: "Profile Name", 157 * name: "Profile Name",
163 * iconURL: "chrome://path/to/icon/image", 158 * iconURL: "chrome://path/to/icon/image",
164 * filePath: "/path/to/profile/data/on/disk", 159 * filePath: "/path/to/profile/data/on/disk",
165 * isCurrentProfile: false, 160 * isCurrentProfile: false,
166 * isManaged: false 161 * isManaged: false
167 * }; 162 * };
168 * @param {string} mode A label that specifies the type of dialog 163 * @param {string} mode A label that specifies the type of dialog box which
169 * box which is currently being viewed (i.e. 'create' or 164 * is currently being viewed (i.e. 'create' or 'manage').
170 * 'manage').
171 * @private 165 * @private
172 */ 166 */
173 setProfileInfo_: function(profileInfo, mode) { 167 setProfileInfo_: function(profileInfo, mode) {
174 this.iconGridSelectedURL_ = profileInfo.iconURL; 168 this.iconGridSelectedURL_ = profileInfo.iconURL;
175 this.profileInfo_ = profileInfo; 169 this.profileInfo_ = profileInfo;
176 $(mode + '-profile-name').value = profileInfo.name; 170 $(mode + '-profile-name').value = profileInfo.name;
177 $(mode + '-profile-icon-grid').selectedItem = profileInfo.iconURL; 171 $(mode + '-profile-icon-grid').selectedItem = profileInfo.iconURL;
178 }, 172 },
179 173
180 /** 174 /**
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
249 * message. 243 * message.
250 * @param {boolean} hasShortcuts Whether profile has any existing shortcuts. 244 * @param {boolean} hasShortcuts Whether profile has any existing shortcuts.
251 * @private 245 * @private
252 */ 246 */
253 receiveHasProfileShortcuts_: function(hasShortcuts) { 247 receiveHasProfileShortcuts_: function(hasShortcuts) {
254 $('add-shortcut-button').hidden = hasShortcuts; 248 $('add-shortcut-button').hidden = hasShortcuts;
255 $('remove-shortcut-button').hidden = !hasShortcuts; 249 $('remove-shortcut-button').hidden = !hasShortcuts;
256 }, 250 },
257 251
258 /** 252 /**
259 * Display the error bubble, with |errorText| in the bubble. 253 * Display the error bubble, with |errorHtml| in the bubble.
260 * @param {string} errorText The string to display as an error. 254 * @param {string} errorHtml The html string to display as an error.
261 * @param {string} mode A label that specifies the type of dialog 255 * @param {string} mode A label that specifies the type of dialog box which
262 * box which is currently being viewed (i.e. 'create' or 256 * is currently being viewed (i.e. 'create' or 'manage').
263 * 'manage').
264 * @param {boolean} disableOKButton True if the dialog's OK button should be 257 * @param {boolean} disableOKButton True if the dialog's OK button should be
265 * disabled when the error bubble is shown. It will be (re-)enabled when 258 * disabled when the error bubble is shown. It will be (re-)enabled when
266 * the error bubble is hidden. 259 * the error bubble is hidden.
267 * @private 260 * @private
268 */ 261 */
269 showErrorBubble_: function(errorText, mode, disableOKButton) { 262 showErrorBubble_: function(errorHtml, mode, disableOKButton) {
270 var nameErrorEl = $(mode + '-profile-error-bubble'); 263 var nameErrorEl = $(mode + '-profile-error-bubble');
271 nameErrorEl.hidden = false; 264 nameErrorEl.hidden = false;
272 nameErrorEl.textContent = errorText; 265 nameErrorEl.innerHTML = errorHtml;
273 266
274 if (disableOKButton) 267 if (disableOKButton)
275 $(mode + '-profile-ok').disabled = true; 268 $(mode + '-profile-ok').disabled = true;
276 }, 269 },
277 270
278 /** 271 /**
279 * Hide the error bubble. 272 * Hide the error bubble.
280 * @param {string} mode A label that specifies the type of dialog 273 * @param {string} mode A label that specifies the type of dialog box which
281 * box which is currently being viewed (i.e. 'create' or 274 * is currently being viewed (i.e. 'create' or 'manage').
282 * 'manage').
283 * @private 275 * @private
284 */ 276 */
285 hideErrorBubble_: function(mode) { 277 hideErrorBubble_: function(mode) {
286 $(mode + '-profile-error-bubble').hidden = true; 278 $(mode + '-profile-error-bubble').hidden = true;
287 $(mode + '-profile-ok').disabled = false; 279 $(mode + '-profile-ok').disabled = false;
288 }, 280 },
289 281
290 /** 282 /**
291 * oninput callback for <input> field. 283 * oninput callback for <input> field.
292 * @param {Event} event The event object. 284 * @param {string} mode A label that specifies the type of dialog box which
293 * @param {string} mode A label that specifies the type of dialog 285 * is currently being viewed (i.e. 'create' or 'manage').
294 * box which is currently being viewed (i.e. 'create' or
295 * 'manage').
296 * @private 286 * @private
297 */ 287 */
298 onNameChanged_: function(event, mode) { 288 onNameChanged_: function(mode) {
299 var newName = event.target.value; 289 var newName = $(mode + '-profile-name').value;
300 var oldName = this.profileInfo_.name; 290 var oldName = this.profileInfo_.name;
301 291
302 if (newName == oldName) { 292 // In 'create' mode, the initial name can be the name of an already
293 // existing supervised user.
294 if (newName == oldName && mode == 'manage') {
303 this.hideErrorBubble_(mode); 295 this.hideErrorBubble_(mode);
304 } else if (this.profileNames_[newName] != undefined) { 296 } else if (this.profileNames_[newName] != undefined) {
305 var errorText = 297 var errorHtml =
306 loadTimeData.getString('manageProfilesDuplicateNameError'); 298 loadTimeData.getString('manageProfilesDuplicateNameError');
307 this.showErrorBubble_(errorText, mode, true); 299 this.showErrorBubble_(errorHtml, mode, true);
300 } else if (mode == 'create' &&
301 loadTimeData.getBoolean('allowCreateExistingManagedUsers')) {
302 this.checkIfSupervisedUserExists_();
308 } else { 303 } else {
309 this.hideErrorBubble_(mode); 304 this.updateOkButton_(mode);
310
311 var nameIsValid = $(mode + '-profile-name').validity.valid;
312 $(mode + '-profile-ok').disabled = !nameIsValid;
313 } 305 }
314 }, 306 },
315 307
316 /** 308 /**
309 * Checks if a supervised user with the currently entered name already
310 * exists.
311 * @private
312 */
313 checkIfSupervisedUserExists_: function() {
314 if (!$('create-profile-managed').checked) {
315 this.updateOkButton_('create');
316 return;
317 }
318 options.ManagedUserList.requestExistingManagedUsers(
319 this.receiveExistingManagedUsers_.bind(this),
320 this.onSigninError_.bind(this));
321 },
322
323 /**
324 * Callback which receives the list of existing managed users. Checks if the
325 * currently entered name is the name of an already existing managed user.
326 * If yes, the user is prompted to import the existing managed user, and the
327 * create button is disabled.
328 * @param {Array.<Object>} The list of existing managed users.
329 * @private
330 */
331 receiveExistingManagedUsers_: function(managedUsers) {
332 var newName = $('create-profile-name').value;
333 var i;
334 for (i = 0; i < managedUsers.length; ++i) {
335 if (managedUsers[i].name == newName &&
336 !managedUsers[i].onCurrentDevice) {
337 var errorHtml = loadTimeData.getStringF(
338 'manageProfilesExistingSupervisedUser',
339 HTMLEscape(elide(newName, /* maxLength */ 50)));
340 this.showErrorBubble_(errorHtml, 'create', true);
341
342 // Check if another supervised user also exists with that name.
343 var nameIsUnique = true;
344 var j;
345 for (j = i + 1; j < managedUsers.length; ++j) {
346 if (managedUsers[j].name == newName) {
347 nameIsUnique = false;
348 break;
349 }
350 }
351 function getImportHandler(managedUser, nameIsUnique) {
352 return function() {
353 if (managedUser.needAvatar || !nameIsUnique) {
354 OptionsPage.navigateToPage('managedUserImport');
355 } else {
356 chrome.send('createProfile',
357 [managedUser.name, managedUser.iconURL, false, true,
358 managedUser.id]);
359 }
360 }
361 };
362 $('supervised-user-import').onclick =
363 getImportHandler(managedUsers[i], nameIsUnique);
364 $('create-profile-ok').disabled = true;
365 return;
366 }
367 }
368 this.updateOkButton_('create');
369 },
370
371 /**
372 * Called in case the request for the list of managed users fails because of
373 * a signin error.
374 * @private
375 */
376 onSigninError_: function() {
377 this.updateImportExistingManagedUserLink_(false);
378 this.updateManagedUsersAllowed_(false);
379 },
380
381 /**
382 * Called if the name seems to be unused so far.
383 * @param {string} mode A label that specifies the type of dialog box which
384 * is currently being viewed (i.e. 'create' or 'manage').
385 * @private
386 */
387 updateOkButton_: function(mode) {
388 this.hideErrorBubble_(mode);
389
390 var nameIsValid = $(mode + '-profile-name').validity.valid;
391 $(mode + '-profile-ok').disabled = !nameIsValid;
392 },
393
394 /**
317 * Called when the user clicks "OK" or hits enter. Saves the newly changed 395 * Called when the user clicks "OK" or hits enter. Saves the newly changed
318 * profile info. 396 * profile info.
319 * @private 397 * @private
320 */ 398 */
321 submitManageChanges_: function() { 399 submitManageChanges_: function() {
322 var name = $('manage-profile-name').value; 400 var name = $('manage-profile-name').value;
323 var iconURL = $('manage-profile-icon-grid').selectedItem; 401 var iconURL = $('manage-profile-icon-grid').selectedItem;
324 402
325 chrome.send('setProfileIconAndName', 403 chrome.send('setProfileIconAndName',
326 [this.profileInfo_.filePath, iconURL, name]); 404 [this.profileInfo_.filePath, iconURL, name]);
(...skipping 22 matching lines...) Expand all
349 var existingManagedUserId = ''; 427 var existingManagedUserId = '';
350 428
351 // 'createProfile' is handled by the CreateProfileHandler. 429 // 'createProfile' is handled by the CreateProfileHandler.
352 chrome.send('createProfile', 430 chrome.send('createProfile',
353 [name, iconUrl, createShortcut, 431 [name, iconUrl, createShortcut,
354 isManaged, existingManagedUserId]); 432 isManaged, existingManagedUserId]);
355 }, 433 },
356 434
357 /** 435 /**
358 * Called when the selected icon in the icon grid changes. 436 * Called when the selected icon in the icon grid changes.
359 * @param {string} mode A label that specifies the type of dialog 437 * @param {string} mode A label that specifies the type of dialog box which
360 * box which is currently being viewed (i.e. 'create' or 438 * is currently being viewed (i.e. 'create' or 'manage').
361 * 'manage').
362 * @private 439 * @private
363 */ 440 */
364 onIconGridSelectionChanged_: function(mode) { 441 onIconGridSelectionChanged_: function(mode) {
365 var iconURL = $(mode + '-profile-icon-grid').selectedItem; 442 var iconURL = $(mode + '-profile-icon-grid').selectedItem;
366 if (!iconURL || iconURL == this.iconGridSelectedURL_) 443 if (!iconURL || iconURL == this.iconGridSelectedURL_)
367 return; 444 return;
368 this.iconGridSelectedURL_ = iconURL; 445 this.iconGridSelectedURL_ = iconURL;
369 if (this.profileInfo_ && this.profileInfo_.filePath) { 446 if (this.profileInfo_ && this.profileInfo_.filePath) {
370 chrome.send('profileIconSelectionChanged', 447 chrome.send('profileIconSelectionChanged',
371 [this.profileInfo_.filePath, iconURL]); 448 [this.profileInfo_.filePath, iconURL]);
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
487 564
488 var shortcutsEnabled = loadTimeData.getBoolean('profileShortcutsEnabled'); 565 var shortcutsEnabled = loadTimeData.getBoolean('profileShortcutsEnabled');
489 $('create-shortcut-container').hidden = !shortcutsEnabled; 566 $('create-shortcut-container').hidden = !shortcutsEnabled;
490 $('create-shortcut').checked = shortcutsEnabled; 567 $('create-shortcut').checked = shortcutsEnabled;
491 568
492 $('create-profile-name-label').hidden = true; 569 $('create-profile-name-label').hidden = true;
493 $('create-profile-name').hidden = true; 570 $('create-profile-name').hidden = true;
494 $('create-profile-ok').disabled = true; 571 $('create-profile-ok').disabled = true;
495 572
496 $('create-profile-managed').checked = false; 573 $('create-profile-managed').checked = false;
574 if (loadTimeData.getBoolean('allowCreateExistingManagedUsers')) {
575 $('import-existing-managed-user-link').hidden = false;
576 $('create-profile-managed').onchange = function() {
577 ManageProfileOverlay.getInstance().onNameChanged_('create');
578 };
579 }
497 $('create-profile-managed-signed-in').disabled = true; 580 $('create-profile-managed-signed-in').disabled = true;
498 $('create-profile-managed-signed-in').hidden = true; 581 $('create-profile-managed-signed-in').hidden = true;
499 $('create-profile-managed-not-signed-in').hidden = true; 582 $('create-profile-managed-not-signed-in').hidden = true;
500 }, 583 },
501 584
502 /** @override */ 585 /** @override */
503 handleCancel: function() { 586 handleCancel: function() {
504 this.cancelCreateProfile_(); 587 this.cancelCreateProfile_();
505 }, 588 },
506 589
507 /** @override */ 590 /** @override */
508 showErrorBubble_: function(errorText) { 591 showErrorBubble_: function(errorHtml) {
509 ManageProfileOverlay.getInstance().showErrorBubble_(errorText, 592 ManageProfileOverlay.getInstance().showErrorBubble_(errorHtml,
510 'create', 593 'create',
511 false); 594 false);
512 }, 595 },
513 596
514 /** @override */ 597 /** @override */
515 hideErrorBubble_: function() { 598 hideErrorBubble_: function() {
516 ManageProfileOverlay.getInstance().hideErrorBubble_('create'); 599 ManageProfileOverlay.getInstance().hideErrorBubble_('create');
517 }, 600 },
518 601
519 /** 602 /**
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
695 return instance[name + '_'].apply(instance, arguments); 778 return instance[name + '_'].apply(instance, arguments);
696 }; 779 };
697 }); 780 });
698 781
699 // Export 782 // Export
700 return { 783 return {
701 ManageProfileOverlay: ManageProfileOverlay, 784 ManageProfileOverlay: ManageProfileOverlay,
702 CreateProfileOverlay: CreateProfileOverlay, 785 CreateProfileOverlay: CreateProfileOverlay,
703 }; 786 };
704 }); 787 });
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698