Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 /** | 5 /** |
| 6 * @fileoverview 'create-profile' is a page that contains controls for creating | 6 * @fileoverview 'create-profile' is a page that contains controls for creating |
| 7 * a (optionally supervised) profile, including choosing a name, and an avatar. | 7 * a (optionally supervised) profile, including choosing a name, and an avatar. |
| 8 */ | 8 */ |
| 9 (function() { | 9 (function() { |
| 10 /** | 10 /** |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 91 */ | 91 */ |
| 92 signedInUserIndex_: { | 92 signedInUserIndex_: { |
| 93 type: Number, | 93 type: Number, |
| 94 value: NO_USER_SELECTED | 94 value: NO_USER_SELECTED |
| 95 }, | 95 }, |
| 96 | 96 |
| 97 /** @private {!signin.ProfileBrowserProxy} */ | 97 /** @private {!signin.ProfileBrowserProxy} */ |
| 98 browserProxy_: Object | 98 browserProxy_: Object |
| 99 }, | 99 }, |
| 100 | 100 |
| 101 listeners: { | |
| 102 'tap': 'onTap_', | |
| 103 'importUserPopup.import': 'onImportUserPopupImport_' | |
| 104 }, | |
| 105 | |
| 101 /** @override */ | 106 /** @override */ |
| 102 created: function() { | 107 created: function() { |
| 103 this.browserProxy_ = signin.ProfileBrowserProxyImpl.getInstance(); | 108 this.browserProxy_ = signin.ProfileBrowserProxyImpl.getInstance(); |
| 104 }, | 109 }, |
| 105 | 110 |
| 106 /** @override */ | 111 /** @override */ |
| 107 ready: function() { | 112 ready: function() { |
| 108 this.addWebUIListener( | 113 this.addWebUIListener( |
| 109 'create-profile-success', this.handleSuccess_.bind(this)); | 114 'create-profile-success', this.handleSuccess_.bind(this)); |
| 110 this.addWebUIListener( | 115 this.addWebUIListener( |
| 111 'create-profile-warning', this.handleMessage_.bind(this)); | 116 'create-profile-warning', this.handleMessage_.bind(this)); |
| 112 this.addWebUIListener( | 117 this.addWebUIListener( |
| 113 'create-profile-error', this.handleMessage_.bind(this)); | 118 'create-profile-error', this.handleMessage_.bind(this)); |
| 114 this.addWebUIListener( | 119 this.addWebUIListener( |
| 115 'profile-icons-received', this.handleProfileIcons_.bind(this)); | 120 'profile-icons-received', this.handleProfileIcons_.bind(this)); |
| 116 this.addWebUIListener( | 121 this.addWebUIListener( |
| 117 'profile-defaults-received', this.handleProfileDefaults_.bind(this)); | 122 'profile-defaults-received', this.handleProfileDefaults_.bind(this)); |
| 118 this.addWebUIListener( | 123 this.addWebUIListener( |
| 119 'signedin-users-received', this.handleSignedInUsers_.bind(this)); | 124 'signedin-users-received', this.handleSignedInUsers_.bind(this)); |
| 120 | 125 |
| 121 this.browserProxy_.getAvailableIcons(); | 126 this.browserProxy_.getAvailableIcons(); |
| 122 this.browserProxy_.getSignedInUsers(); | 127 this.browserProxy_.getSignedInUsers(); |
| 123 | 128 |
| 124 // Alias on 'this' to use in html. | 129 // Alias on 'this' to use in html. |
| 125 this.NO_USER_SELECTED = NO_USER_SELECTED; | 130 this.NO_USER_SELECTED = NO_USER_SELECTED; |
| 126 }, | 131 }, |
| 127 | 132 |
| 128 /** | 133 /** |
| 134 * Handles tap events from dynamically created links in warning/error messages | |
| 135 * pushed by the browser. | |
| 136 * @param {!Event} event | |
| 137 * @private | |
| 138 */ | |
| 139 onTap_: function(event) { | |
| 140 var element = Polymer.dom(event).rootTarget; | |
| 141 | |
| 142 if (element.id == 'supervised-user-import-existing') { | |
| 143 this.onImportUserTap_(event); | |
| 144 event.preventDefault(); | |
| 145 } | |
| 146 // TODO(mahmadi): handle tap event on '#reauth' to re-auth the custodian. | |
| 147 }, | |
| 148 | |
| 149 /** | |
| 129 * Handler for when the profile icons are pushed from the browser. | 150 * Handler for when the profile icons are pushed from the browser. |
| 130 * @param {!Array<string>} iconUrls | 151 * @param {!Array<string>} iconUrls |
| 131 * @private | 152 * @private |
| 132 */ | 153 */ |
| 133 handleProfileIcons_: function(iconUrls) { | 154 handleProfileIcons_: function(iconUrls) { |
| 134 this.availableIconUrls_ = iconUrls; | 155 this.availableIconUrls_ = iconUrls; |
| 135 this.profileIconUrl_ = iconUrls[0]; | 156 this.profileIconUrl_ = iconUrls[0]; |
| 136 }, | 157 }, |
| 137 | 158 |
| 138 /** | 159 /** |
| 139 * Handler for when the profile defaults are pushed from the browser. | 160 * Handler for when the profile defaults are pushed from the browser. |
| 140 * @param {ProfileInfo} profileInfo Default Info for the new profile. | 161 * @param {!ProfileInfo} profileInfo Default Info for the new profile. |
| 141 * @private | 162 * @private |
| 142 */ | 163 */ |
| 143 handleProfileDefaults_: function(profileInfo) { | 164 handleProfileDefaults_: function(profileInfo) { |
| 144 this.profileName_ = profileInfo.name; | 165 this.profileName_ = profileInfo.name; |
| 145 }, | 166 }, |
| 146 | 167 |
| 147 /** | 168 /** |
| 148 * Handler for when signed-in users are pushed from the browser. | 169 * Handler for when signed-in users are pushed from the browser. |
| 149 * @param {!Array<!SignedInUser>} signedInUsers | 170 * @param {!Array<!SignedInUser>} signedInUsers |
| 150 * @private | 171 * @private |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 165 /** | 186 /** |
| 166 * Handler for the 'Learn More' link tap event. | 187 * Handler for the 'Learn More' link tap event. |
| 167 * @param {!Event} event | 188 * @param {!Event} event |
| 168 * @private | 189 * @private |
| 169 */ | 190 */ |
| 170 onLearnMoreTap_: function(event) { | 191 onLearnMoreTap_: function(event) { |
| 171 this.fire('change-page', {page: 'supervised-learn-more-page'}); | 192 this.fire('change-page', {page: 'supervised-learn-more-page'}); |
| 172 }, | 193 }, |
| 173 | 194 |
| 174 /** | 195 /** |
| 196 * Handler for the 'Import Supervised User' link tap event. | |
| 197 * @param {!Event} event | |
| 198 * @private | |
| 199 */ | |
| 200 onImportUserTap_: function(event) { | |
| 201 if (this.signedInUserIndex_ == NO_USER_SELECTED) { | |
| 202 // A custodian must be selected. | |
| 203 this.handleMessage_(this.i18n('custodianAccountNotSelectedError')); | |
| 204 } else { | |
| 205 var signedInUser = this.signedInUser_(this.signedInUserIndex_); | |
| 206 this.createInProgress_ = true; | |
| 207 this.browserProxy_.getExistingSupervisedUsers(signedInUser.profilePath) | |
| 208 .then(this.showImportSupervisedUserPopup_.bind(this), | |
| 209 this.handleMessage_.bind(this)); | |
| 210 } | |
| 211 }, | |
| 212 | |
| 213 /** | |
| 175 * Handler for the 'Save' button tap event. | 214 * Handler for the 'Save' button tap event. |
| 176 * @param {!Event} event | 215 * @param {!Event} event |
| 177 * @private | 216 * @private |
| 178 */ | 217 */ |
| 179 onSaveTap_: function(event) { | 218 onSaveTap_: function(event) { |
| 180 this.createInProgress_ = true; | |
| 181 | |
| 182 if (!this.isSupervised_) { | 219 if (!this.isSupervised_) { |
| 183 // The new profile is not supervised. Go ahead and create it. | 220 // The new profile is not supervised. Go ahead and create it. |
| 184 this.createProfile_(); | 221 this.createProfile_(); |
| 185 } else if (this.signedInUserIndex_ == NO_USER_SELECTED) { | 222 } else if (this.signedInUserIndex_ == NO_USER_SELECTED) { |
| 186 // If the new profile is supervised, a custodian must be selected. | 223 // If the new profile is supervised, a custodian must be selected. |
| 187 this.handleMessage_(this.i18n('custodianAccountNotSelectedError')); | 224 this.handleMessage_(this.i18n('custodianAccountNotSelectedError')); |
| 188 this.createInProgress_ = false; | |
| 189 } else { | 225 } else { |
| 190 var signedInUser = this.signedInUser_(this.signedInUserIndex_); | 226 var signedInUser = this.signedInUser_(this.signedInUserIndex_); |
| 191 this.browserProxy_.getExistingSupervisedUsers( | 227 this.createInProgress_ = true; |
| 192 signedInUser.profilePath).then( | 228 this.browserProxy_.getExistingSupervisedUsers(signedInUser.profilePath) |
| 193 this.createProfileIfValidSupervisedUser_.bind(this), | 229 .then(this.createProfileIfValidSupervisedUser_.bind(this), |
| 194 /** @param {*} error */ | 230 this.handleMessage_.bind(this)); |
| 195 function(error) { this.handleMessage_(error); }.bind(this)); | |
| 196 } | 231 } |
| 197 }, | 232 }, |
| 198 | 233 |
| 199 /** | 234 /** |
| 235 * Displays the import supervised user popup. | |
| 236 * @param {!Array<!SupervisedUser>} supervisedUsers The list of existing | |
| 237 * supervised users. | |
| 238 * @private | |
| 239 */ | |
| 240 showImportSupervisedUserPopup_: function(supervisedUsers) { | |
| 241 this.createInProgress_ = false; | |
| 242 this.$.importUserPopup.show(this.signedInUser_(this.signedInUserIndex_), | |
| 243 supervisedUsers); | |
| 244 }, | |
| 245 | |
| 246 /** | |
| 200 * Checks if the entered name matches name of an existing supervised user. | 247 * Checks if the entered name matches name of an existing supervised user. |
| 201 * If yes, the user is prompted to import the existing supervised user. | 248 * If yes, the user is prompted to import the existing supervised user. |
| 202 * If no, the new supervised profile gets created. | 249 * If no, the new supervised profile gets created. |
| 203 * @param {Array<SupervisedUser>} supervisedUsers The list of existing | 250 * @param {!Array<!SupervisedUser>} supervisedUsers The list of existing |
| 204 * supervised users. | 251 * supervised users. |
| 205 * @private | 252 * @private |
| 206 */ | 253 */ |
| 207 createProfileIfValidSupervisedUser_: function(supervisedUsers) { | 254 createProfileIfValidSupervisedUser_: function(supervisedUsers) { |
| 208 for (var i = 0; i < supervisedUsers.length; ++i) { | 255 for (var i = 0; i < supervisedUsers.length; ++i) { |
| 209 if (supervisedUsers[i].name != this.profileName_) | 256 if (supervisedUsers[i].name != this.profileName_) |
| 210 continue; | 257 continue; |
| 211 // Check if another supervised user also exists with that name. | 258 // Check if another supervised user also exists with that name. |
| 212 var nameIsUnique = true; | 259 var nameIsUnique = true; |
| 213 // Handling the case when multiple supervised users with the same | 260 // Handling the case when multiple supervised users with the same |
| 214 // name exist, but not all of them are on the device. | 261 // name exist, but not all of them are on the device. |
| 215 // If at least one is not imported, we want to offer that | 262 // If at least one is not imported, we want to offer that |
| 216 // option to the user. This could happen due to a bug that allowed | 263 // option to the user. This could happen due to a bug that allowed |
| 217 // creating SUs with the same name (https://crbug.com/557445). | 264 // creating SUs with the same name (https://crbug.com/557445). |
| 218 var allOnCurrentDevice = supervisedUsers[i].onCurrentDevice; | 265 var allOnCurrentDevice = supervisedUsers[i].onCurrentDevice; |
| 219 for (var j = i + 1; j < supervisedUsers.length; ++j) { | 266 for (var j = i + 1; j < supervisedUsers.length; ++j) { |
| 220 if (supervisedUsers[j].name == this.profileName_) { | 267 if (supervisedUsers[j].name == this.profileName_) { |
| 221 nameIsUnique = false; | 268 nameIsUnique = false; |
| 222 allOnCurrentDevice = allOnCurrentDevice && | 269 allOnCurrentDevice = allOnCurrentDevice && |
| 223 supervisedUsers[j].onCurrentDevice; | 270 supervisedUsers[j].onCurrentDevice; |
| 224 } | 271 } |
| 225 } | 272 } |
| 226 | 273 |
| 227 this.handleMessage_(allOnCurrentDevice ? | 274 this.handleMessage_(allOnCurrentDevice ? |
| 228 this.i18n('managedProfilesExistingLocalSupervisedUser') : | 275 this.i18n('managedProfilesExistingLocalSupervisedUser') : |
| 229 this.i18n('manageProfilesExistingSupervisedUser', | 276 this.i18n('manageProfilesExistingSupervisedUser', |
| 230 HTMLEscape(elide(this.profileName_, /* maxLength */ 50)))); | 277 HTMLEscape(elide(this.profileName_, /* maxLength */ 50)))); |
| 231 | |
| 232 this.createInProgress_ = false; | |
| 233 return; | 278 return; |
| 234 } | 279 } |
| 235 // No existing supervised user's name matches the entered profile name. | 280 // No existing supervised user's name matches the entered profile name. |
| 236 // Continue with creating the new supervised profile. | 281 // Continue with creating the new supervised profile. |
| 237 this.createProfile_(); | 282 this.createProfile_(); |
| 238 }, | 283 }, |
| 239 | 284 |
| 240 /** | 285 /** |
| 241 * Creates the new profile. | 286 * Creates the new profile. |
| 242 * @private | 287 * @private |
| 243 */ | 288 */ |
| 244 createProfile_: function() { | 289 createProfile_: function() { |
| 245 var custodianProfilePath = ''; | 290 var custodianProfilePath = ''; |
| 246 if (this.signedInUserIndex_ != NO_USER_SELECTED) { | 291 if (this.signedInUserIndex_ != NO_USER_SELECTED) { |
| 247 custodianProfilePath = | 292 custodianProfilePath = |
| 248 this.signedInUser_(this.signedInUserIndex_).profilePath; | 293 this.signedInUser_(this.signedInUserIndex_).profilePath; |
| 249 } | 294 } |
| 295 this.createInProgress_ = true; | |
| 296 this.browserProxy_.createProfile( | |
| 297 this.profileName_, this.profileIconUrl_, this.isSupervised_, '', | |
| 298 custodianProfilePath); | |
| 299 }, | |
| 250 | 300 |
| 301 /** | |
| 302 * Handler for the 'import' event fired by #importUserPopup once a supervised | |
| 303 * user is selected to be imported and the popup closes. | |
| 304 * @param {!{detail: {supervisedUser: !SupervisedUser, | |
| 305 * signedInUser: !SignedInUser}}} event | |
| 306 * @private | |
| 307 */ | |
| 308 onImportUserPopupImport_: function(event) { | |
| 309 var supervisedUser = event.detail.supervisedUser; | |
| 310 var signedInUser = event.detail.signedInUser; | |
| 311 this.createInProgress_ = true; | |
| 251 this.browserProxy_.createProfile( | 312 this.browserProxy_.createProfile( |
| 252 this.profileName_, this.profileIconUrl_, this.isSupervised_, | 313 supervisedUser.name, supervisedUser.iconURL, true, supervisedUser.id, |
| 253 custodianProfilePath); | 314 signedInUser.profilePath); |
| 254 }, | 315 }, |
| 255 | 316 |
| 256 /** | 317 /** |
| 257 * Handler for the 'Cancel' button tap event. | 318 * Handler for the 'Cancel' button tap event. |
| 258 * @param {!Event} event | 319 * @param {!Event} event |
| 259 * @private | 320 * @private |
| 260 */ | 321 */ |
| 261 onCancelTap_: function(event) { | 322 onCancelTap_: function(event) { |
| 262 if (this.createInProgress_) { | 323 if (this.createInProgress_) { |
| 263 this.createInProgress_ = false; | 324 this.createInProgress_ = false; |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 295 if (profileInfo.showConfirmation) { | 356 if (profileInfo.showConfirmation) { |
| 296 this.fire('change-page', {page: 'supervised-create-confirm-page', | 357 this.fire('change-page', {page: 'supervised-create-confirm-page', |
| 297 data: profileInfo}); | 358 data: profileInfo}); |
| 298 } else { | 359 } else { |
| 299 this.fire('change-page', {page: 'user-pods-page'}); | 360 this.fire('change-page', {page: 'user-pods-page'}); |
| 300 } | 361 } |
| 301 }, | 362 }, |
| 302 | 363 |
| 303 /** | 364 /** |
| 304 * Handles profile create/import warning/error message pushed by the browser. | 365 * Handles profile create/import warning/error message pushed by the browser. |
| 305 * @param {string} message An HTML warning/error message. | 366 * @param {*} message An HTML warning/error message. |
| 306 * @private | 367 * @private |
| 307 */ | 368 */ |
| 308 handleMessage_: function(message) { | 369 handleMessage_: function(message) { |
| 309 this.createInProgress_ = false; | 370 this.createInProgress_ = false; |
| 310 this.message_ = message; | 371 this.message_ = /** @type {string} */ (message); |
|
Dan Beam
2016/04/22 01:25:31
this.message_ = '' + message;
Moe
2016/04/22 18:46:04
Done.
| |
| 311 | |
| 312 // TODO(mahmadi): attach handler to '#supervised-user-import-existing' | |
| 313 // in order to import supervised user with the given name. | |
| 314 | |
| 315 // TODO(mahmadi): attach handler to '#reauth' in order to re-authenticate | |
| 316 // custodian. | |
| 317 }, | 372 }, |
| 318 | 373 |
| 319 /** | 374 /** |
| 320 * Computed binding determining which profile icon button is toggled on. | 375 * Computed binding determining which profile icon button is toggled on. |
| 321 * @param {string} iconUrl icon URL of a given icon button. | 376 * @param {string} iconUrl icon URL of a given icon button. |
| 322 * @param {string} profileIconUrl Currently selected icon URL. | 377 * @param {string} profileIconUrl Currently selected icon URL. |
| 323 * @return {boolean} | 378 * @return {boolean} |
| 324 * @private | 379 * @private |
| 325 */ | 380 */ |
| 326 isActiveIcon_: function(iconUrl, profileIconUrl) { | 381 isActiveIcon_: function(iconUrl, profileIconUrl) { |
| 327 return iconUrl == profileIconUrl; | 382 return iconUrl == profileIconUrl; |
| 328 }, | 383 }, |
| 329 | 384 |
| 330 /** | 385 /** |
| 331 * Computed binding determining whether 'Save' button is disabled. | 386 * Computed binding determining whether 'Save' button is disabled. |
| 332 * @param {boolean} createInProgress Is create in progress? | 387 * @param {boolean} createInProgress Is create in progress? |
| 333 * @param {string} profileName Profile Name. | 388 * @param {string} profileName Profile Name. |
| 334 * @return {boolean} | 389 * @return {boolean} |
| 335 * @private | 390 * @private |
| 336 */ | 391 */ |
| 337 isSaveDisabled_: function(createInProgress, profileName) { | 392 isSaveDisabled_: function(createInProgress, profileName) { |
| 338 // TODO(mahmadi): Figure out a way to add 'paper-input-extracted' as a | 393 // TODO(mahmadi): Figure out a way to add 'paper-input-extracted' as a |
| 339 // dependency and cast to PaperInputElement instead. | 394 // dependency and cast to PaperInputElement instead. |
| 340 /** @type {{validate: function():boolean}} */ | 395 /** @type {{validate: function():boolean}} */ |
| 341 var nameInput = this.$.nameInput; | 396 var nameInput = this.$.nameInput; |
| 342 return createInProgress || !profileName || !nameInput.validate(); | 397 return createInProgress || !profileName || !nameInput.validate(); |
| 343 }, | 398 }, |
| 344 | 399 |
| 345 /** | 400 /** |
| 401 * Returns True if the import supervised user link should be hidden. | |
| 402 * @param {boolean} createInProgress True if create/import is in progress | |
| 403 * @param {number} signedInUserIndex Index of the selected signed-in user. | |
| 404 * @return {boolean} | |
| 405 * @private | |
| 406 */ | |
| 407 isImportUserLinkHidden_: function(createInProgress, signedInUserIndex) { | |
| 408 return createInProgress || !this.signedInUser_(signedInUserIndex); | |
| 409 }, | |
| 410 | |
| 411 /** | |
| 346 * Computed binding that returns True if there are any signed-in users. | 412 * Computed binding that returns True if there are any signed-in users. |
| 347 * @param {!Array<!SignedInUser>} signedInUsers signed-in users. | 413 * @param {!Array<!SignedInUser>} signedInUsers signed-in users. |
| 348 * @return {boolean} | 414 * @return {boolean} |
| 349 * @private | 415 * @private |
| 350 */ | 416 */ |
| 351 isSignedIn_: function(signedInUsers) { | 417 isSignedIn_: function(signedInUsers) { |
| 352 return signedInUsers.length > 0; | 418 return signedInUsers.length > 0; |
| 353 } | 419 } |
| 354 }); | 420 }); |
| 355 }()); | 421 }()); |
| OLD | NEW |