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 | 9 |
10 /** @typedef {{url: string, label:string}} */ | 10 /** @typedef {{url: string, label:string}} */ |
11 var AvatarIcon; | 11 var AvatarIcon; |
12 | 12 |
13 (function() { | 13 (function() { |
14 /** | 14 /** |
15 * Sentinel signed-in user's index value. | 15 * Sentinel signed-in user's index value. |
16 * @const {number} | 16 * @const {number} |
17 */ | 17 */ |
18 var NO_USER_SELECTED = -1; | 18 var NO_USER_SELECTED = -1; |
19 | 19 |
20 Polymer({ | 20 Polymer({ |
21 is: 'create-profile', | 21 is: 'create-profile', |
22 | 22 |
23 behaviors: [ | 23 behaviors: [I18nBehavior, WebUIListenerBehavior], |
24 I18nBehavior, | 24 |
25 WebUIListenerBehavior | 25 properties: { |
26 ], | 26 /** |
27 | 27 * The current profile name. |
28 properties: { | 28 * @private {string} |
29 /** | 29 */ |
30 * The current profile name. | 30 profileName_: {type: String, value: ''}, |
31 * @private {string} | 31 |
32 */ | 32 /** |
33 profileName_: { | 33 * The list of available profile icon Urls and labels. |
34 type: String, | 34 * @private {!Array<!AvatarIcon>} |
35 value: '' | 35 */ |
36 }, | 36 availableIcons_: { |
37 | 37 type: Array, |
38 /** | 38 value: function() { |
39 * The list of available profile icon Urls and labels. | 39 return []; |
40 * @private {!Array<!AvatarIcon>} | 40 } |
41 */ | |
42 availableIcons_: { | |
43 type: Array, | |
44 value: function() { return []; } | |
45 }, | |
46 | |
47 /** | |
48 * The currently selected profile icon URL. May be a data URL. | |
49 * @private {string} | |
50 */ | |
51 profileIconUrl_: { | |
52 type: String, | |
53 value: '' | |
54 }, | |
55 | |
56 /** | |
57 * True if the existing supervised users are being loaded. | |
58 * @private {boolean} | |
59 */ | |
60 loadingSupervisedUsers_: { | |
61 type: Boolean, | |
62 value: false | |
63 }, | |
64 | |
65 /** | |
66 * True if a profile is being created or imported. | |
67 * @private {boolean} | |
68 */ | |
69 createInProgress_: { | |
70 type: Boolean, | |
71 value: false | |
72 }, | |
73 | |
74 /** | |
75 * True if the error/warning message is displaying. | |
76 * @private {boolean} | |
77 */ | |
78 isMessageVisble_: { | |
79 type: Boolean, | |
80 value: false | |
81 }, | |
82 | |
83 /** | |
84 * The current error/warning message. | |
85 * @private {string} | |
86 */ | |
87 message_: { | |
88 type: String, | |
89 value: '' | |
90 }, | |
91 | |
92 /** | |
93 * if true, a desktop shortcut will be created for the new profile. | |
94 * @private {boolean} | |
95 */ | |
96 createShortcut_: { | |
97 type: Boolean, | |
98 value: true | |
99 }, | |
100 | |
101 /** | |
102 * True if the new profile is a supervised profile. | |
103 * @private {boolean} | |
104 */ | |
105 isSupervised_: { | |
106 type: Boolean, | |
107 value: false | |
108 }, | |
109 | |
110 /** | |
111 * The list of usernames and profile paths for currently signed-in users. | |
112 * @private {!Array<!SignedInUser>} | |
113 */ | |
114 signedInUsers_: { | |
115 type: Array, | |
116 value: function() { return []; } | |
117 }, | |
118 | |
119 /** | |
120 * Index of the selected signed-in user. | |
121 * @private {number} | |
122 */ | |
123 signedInUserIndex_: { | |
124 type: Number, | |
125 value: NO_USER_SELECTED | |
126 }, | |
127 | |
128 /** @private {!signin.ProfileBrowserProxy} */ | |
129 browserProxy_: Object, | |
130 | |
131 /** | |
132 * True if the profile shortcuts feature is enabled. | |
133 * @private | |
134 */ | |
135 isProfileShortcutsEnabled_: { | |
136 type: Boolean, | |
137 value: function() { | |
138 return loadTimeData.getBoolean('profileShortcutsEnabled'); | |
139 }, | 41 }, |
140 readOnly: true | 42 |
141 }, | 43 /** |
142 | 44 * The currently selected profile icon URL. May be a data URL. |
143 /** | 45 * @private {string} |
144 * True if the force sign in policy is enabled. | 46 */ |
145 * @private {boolean} | 47 profileIconUrl_: {type: String, value: ''}, |
146 */ | 48 |
147 isForceSigninEnabled_: { | 49 /** |
148 type: Boolean, | 50 * True if the existing supervised users are being loaded. |
149 value: function() { | 51 * @private {boolean} |
150 return loadTimeData.getBoolean('isForceSigninEnabled'); | 52 */ |
| 53 loadingSupervisedUsers_: {type: Boolean, value: false}, |
| 54 |
| 55 /** |
| 56 * True if a profile is being created or imported. |
| 57 * @private {boolean} |
| 58 */ |
| 59 createInProgress_: {type: Boolean, value: false}, |
| 60 |
| 61 /** |
| 62 * True if the error/warning message is displaying. |
| 63 * @private {boolean} |
| 64 */ |
| 65 isMessageVisble_: {type: Boolean, value: false}, |
| 66 |
| 67 /** |
| 68 * The current error/warning message. |
| 69 * @private {string} |
| 70 */ |
| 71 message_: {type: String, value: ''}, |
| 72 |
| 73 /** |
| 74 * if true, a desktop shortcut will be created for the new profile. |
| 75 * @private {boolean} |
| 76 */ |
| 77 createShortcut_: {type: Boolean, value: true}, |
| 78 |
| 79 /** |
| 80 * True if the new profile is a supervised profile. |
| 81 * @private {boolean} |
| 82 */ |
| 83 isSupervised_: {type: Boolean, value: false}, |
| 84 |
| 85 /** |
| 86 * The list of usernames and profile paths for currently signed-in users. |
| 87 * @private {!Array<!SignedInUser>} |
| 88 */ |
| 89 signedInUsers_: { |
| 90 type: Array, |
| 91 value: function() { |
| 92 return []; |
| 93 } |
151 }, | 94 }, |
152 } | 95 |
153 }, | 96 /** |
154 | 97 * Index of the selected signed-in user. |
155 listeners: { | 98 * @private {number} |
156 'tap': 'onTap_', | 99 */ |
157 'importUserPopup.import': 'onImportUserPopupImport_' | 100 signedInUserIndex_: {type: Number, value: NO_USER_SELECTED}, |
158 }, | 101 |
159 | 102 /** @private {!signin.ProfileBrowserProxy} */ |
160 /** @override */ | 103 browserProxy_: Object, |
161 created: function() { | 104 |
162 this.browserProxy_ = signin.ProfileBrowserProxyImpl.getInstance(); | 105 /** |
163 }, | 106 * True if the profile shortcuts feature is enabled. |
164 | 107 * @private |
165 /** @override */ | 108 */ |
166 ready: function() { | 109 isProfileShortcutsEnabled_: { |
167 this.addWebUIListener( | 110 type: Boolean, |
168 'create-profile-success', this.handleSuccess_.bind(this)); | 111 value: function() { |
169 this.addWebUIListener( | 112 return loadTimeData.getBoolean('profileShortcutsEnabled'); |
170 'create-profile-warning', this.handleMessage_.bind(this)); | 113 }, |
171 this.addWebUIListener( | 114 readOnly: true |
172 'create-profile-error', this.handleMessage_.bind(this)); | 115 }, |
173 this.addWebUIListener( | 116 |
174 'profile-icons-received', this.handleProfileIcons_.bind(this)); | 117 /** |
175 this.addWebUIListener( | 118 * True if the force sign in policy is enabled. |
176 'profile-defaults-received', this.handleProfileDefaults_.bind(this)); | 119 * @private {boolean} |
177 this.addWebUIListener( | 120 */ |
178 'signedin-users-received', this.handleSignedInUsers_.bind(this)); | 121 isForceSigninEnabled_: { |
179 | 122 type: Boolean, |
180 this.browserProxy_.getAvailableIcons(); | 123 value: function() { |
181 this.browserProxy_.getSignedInUsers(); | 124 return loadTimeData.getBoolean('isForceSigninEnabled'); |
182 }, | 125 }, |
183 | 126 } |
184 /** @override */ | 127 }, |
185 attached: function() { | 128 |
186 this.$.nameInput.focus(); | 129 listeners: |
187 }, | 130 {'tap': 'onTap_', 'importUserPopup.import': 'onImportUserPopupImport_'}, |
188 | 131 |
189 /** | 132 /** @override */ |
190 * Handles tap events from: | 133 created: function() { |
191 * - links within dynamic warning/error messages pushed from the browser. | 134 this.browserProxy_ = signin.ProfileBrowserProxyImpl.getInstance(); |
192 * - the 'noSignedInUserMessage' i18n string. | 135 }, |
193 * @param {!Event} event | 136 |
194 * @private | 137 /** @override */ |
195 */ | 138 ready: function() { |
196 onTap_: function(event) { | 139 this.addWebUIListener( |
197 var element = Polymer.dom(event).rootTarget; | 140 'create-profile-success', this.handleSuccess_.bind(this)); |
198 | 141 this.addWebUIListener( |
199 if (element.id == 'supervised-user-import-existing') { | 142 'create-profile-warning', this.handleMessage_.bind(this)); |
200 this.onImportUserTap_(event); | 143 this.addWebUIListener( |
201 event.preventDefault(); | 144 'create-profile-error', this.handleMessage_.bind(this)); |
202 } else if (element.id == 'sign-in-to-chrome') { | 145 this.addWebUIListener( |
203 this.browserProxy_.openUrlInLastActiveProfileBrowser(element.href); | 146 'profile-icons-received', this.handleProfileIcons_.bind(this)); |
204 event.preventDefault(); | 147 this.addWebUIListener( |
205 } else if (element.id == 'reauth') { | 148 'profile-defaults-received', this.handleProfileDefaults_.bind(this)); |
206 var elementData = /** @type {{userEmail: string}} */ (element.dataset); | 149 this.addWebUIListener( |
207 this.browserProxy_.authenticateCustodian(elementData.userEmail); | 150 'signedin-users-received', this.handleSignedInUsers_.bind(this)); |
208 this.hideMessage_(); | 151 |
209 event.preventDefault(); | 152 this.browserProxy_.getAvailableIcons(); |
210 } | 153 this.browserProxy_.getSignedInUsers(); |
211 }, | 154 }, |
212 | 155 |
213 /** | 156 /** @override */ |
214 * Handler for when the profile icons are pushed from the browser. | 157 attached: function() { |
215 * @param {!Array<!AvatarIcon>} icons | 158 this.$.nameInput.focus(); |
216 * @private | 159 }, |
217 */ | 160 |
218 handleProfileIcons_: function(icons) { | 161 /** |
219 this.availableIcons_ = icons; | 162 * Handles tap events from: |
220 this.profileIconUrl_ = icons[0].url; | 163 * - links within dynamic warning/error messages pushed from the browser. |
221 }, | 164 * - the 'noSignedInUserMessage' i18n string. |
222 | 165 * @param {!Event} event |
223 /** | 166 * @private |
224 * Handler for when the profile defaults are pushed from the browser. | 167 */ |
225 * @param {!ProfileInfo} profileInfo Default Info for the new profile. | 168 onTap_: function(event) { |
226 * @private | 169 var element = Polymer.dom(event).rootTarget; |
227 */ | 170 |
228 handleProfileDefaults_: function(profileInfo) { | 171 if (element.id == 'supervised-user-import-existing') { |
229 this.profileName_ = profileInfo.name; | 172 this.onImportUserTap_(event); |
230 }, | 173 event.preventDefault(); |
231 | 174 } else if (element.id == 'sign-in-to-chrome') { |
232 /** | 175 this.browserProxy_.openUrlInLastActiveProfileBrowser(element.href); |
233 * Handler for when signed-in users are pushed from the browser. | 176 event.preventDefault(); |
234 * @param {!Array<!SignedInUser>} signedInUsers | 177 } else if (element.id == 'reauth') { |
235 * @private | 178 var elementData = /** @type {{userEmail: string}} */ (element.dataset); |
236 */ | 179 this.browserProxy_.authenticateCustodian(elementData.userEmail); |
237 handleSignedInUsers_: function(signedInUsers) { | 180 this.hideMessage_(); |
238 this.signedInUsers_ = signedInUsers; | 181 event.preventDefault(); |
239 }, | 182 } |
240 | 183 }, |
241 /** | 184 |
| 185 /** |
| 186 * Handler for when the profile icons are pushed from the browser. |
| 187 * @param {!Array<!AvatarIcon>} icons |
| 188 * @private |
| 189 */ |
| 190 handleProfileIcons_: function(icons) { |
| 191 this.availableIcons_ = icons; |
| 192 this.profileIconUrl_ = icons[0].url; |
| 193 }, |
| 194 |
| 195 /** |
| 196 * Handler for when the profile defaults are pushed from the browser. |
| 197 * @param {!ProfileInfo} profileInfo Default Info for the new profile. |
| 198 * @private |
| 199 */ |
| 200 handleProfileDefaults_: function(profileInfo) { |
| 201 this.profileName_ = profileInfo.name; |
| 202 }, |
| 203 |
| 204 /** |
| 205 * Handler for when signed-in users are pushed from the browser. |
| 206 * @param {!Array<!SignedInUser>} signedInUsers |
| 207 * @private |
| 208 */ |
| 209 handleSignedInUsers_: function(signedInUsers) { |
| 210 this.signedInUsers_ = signedInUsers; |
| 211 }, |
| 212 |
| 213 /** |
242 * Returns the currently selected signed-in user. | 214 * Returns the currently selected signed-in user. |
243 * @return {(!SignedInUser|undefined)} | 215 * @return {(!SignedInUser|undefined)} |
244 * @private | 216 * @private |
245 */ | 217 */ |
246 signedInUser_: function(signedInUserIndex) { | 218 signedInUser_: function(signedInUserIndex) { |
247 return this.signedInUsers_[signedInUserIndex]; | 219 return this.signedInUsers_[signedInUserIndex]; |
248 }, | 220 }, |
249 | 221 |
250 /** | 222 /** |
251 * Handler for the 'Learn More' link tap event. | 223 * Handler for the 'Learn More' link tap event. |
252 * @param {!Event} event | 224 * @param {!Event} event |
253 * @private | 225 * @private |
254 */ | 226 */ |
255 onLearnMoreTap_: function(event) { | 227 onLearnMoreTap_: function(event) { |
256 this.fire('change-page', {page: 'supervised-learn-more-page'}); | 228 this.fire('change-page', {page: 'supervised-learn-more-page'}); |
257 }, | 229 }, |
258 | 230 |
259 /** | 231 /** |
260 * Handler for the 'Import Supervised User' link tap event. | 232 * Handler for the 'Import Supervised User' link tap event. |
261 * @param {!Event} event | 233 * @param {!Event} event |
262 * @private | 234 * @private |
263 */ | 235 */ |
264 onImportUserTap_: function(event) { | 236 onImportUserTap_: function(event) { |
265 if (this.signedInUserIndex_ == NO_USER_SELECTED) { | 237 if (this.signedInUserIndex_ == NO_USER_SELECTED) { |
266 // A custodian must be selected. | 238 // A custodian must be selected. |
267 this.handleMessage_(this.i18n('custodianAccountNotSelectedError')); | 239 this.handleMessage_(this.i18n('custodianAccountNotSelectedError')); |
268 } else { | 240 } else { |
269 var signedInUser = this.signedInUser_(this.signedInUserIndex_); | 241 var signedInUser = this.signedInUser_(this.signedInUserIndex_); |
| 242 this.hideMessage_(); |
| 243 this.loadingSupervisedUsers_ = true; |
| 244 this.browserProxy_.getExistingSupervisedUsers(signedInUser.profilePath) |
| 245 .then( |
| 246 this.showImportSupervisedUserPopup_.bind(this), |
| 247 this.handleMessage_.bind(this)); |
| 248 } |
| 249 }, |
| 250 |
| 251 /** |
| 252 * Handler for the 'Save' button tap event. |
| 253 * @param {!Event} event |
| 254 * @private |
| 255 */ |
| 256 onSaveTap_: function(event) { |
| 257 if (!this.isSupervised_) { |
| 258 // The new profile is not supervised. Go ahead and create it. |
| 259 this.createProfile_(); |
| 260 } else if (this.signedInUserIndex_ == NO_USER_SELECTED) { |
| 261 // If the new profile is supervised, a custodian must be selected. |
| 262 this.handleMessage_(this.i18n('custodianAccountNotSelectedError')); |
| 263 } else { |
| 264 var signedInUser = this.signedInUser_(this.signedInUserIndex_); |
| 265 this.hideMessage_(); |
| 266 this.loadingSupervisedUsers_ = true; |
| 267 this.browserProxy_.getExistingSupervisedUsers(signedInUser.profilePath) |
| 268 .then( |
| 269 this.createProfileIfValidSupervisedUser_.bind(this), |
| 270 this.handleMessage_.bind(this)); |
| 271 } |
| 272 }, |
| 273 |
| 274 /** |
| 275 * Displays the import supervised user popup or an error message if there |
| 276 * are |
| 277 * no existing supervised users. |
| 278 * @param {!Array<!SupervisedUser>} supervisedUsers The list of existing |
| 279 * supervised users. |
| 280 * @private |
| 281 */ |
| 282 showImportSupervisedUserPopup_: function(supervisedUsers) { |
| 283 this.loadingSupervisedUsers_ = false; |
| 284 if (supervisedUsers.length > 0) { |
| 285 this.$.importUserPopup.show( |
| 286 this.signedInUser_(this.signedInUserIndex_), supervisedUsers); |
| 287 } else { |
| 288 this.handleMessage_(this.i18n('noSupervisedUserImportText')); |
| 289 } |
| 290 }, |
| 291 |
| 292 /** |
| 293 * Checks if the entered name matches name of an existing supervised user. |
| 294 * If yes, the user is prompted to import the existing supervised user. |
| 295 * If no, the new supervised profile gets created. |
| 296 * @param {!Array<!SupervisedUser>} supervisedUsers The list of existing |
| 297 * supervised users. |
| 298 * @private |
| 299 */ |
| 300 createProfileIfValidSupervisedUser_: function(supervisedUsers) { |
| 301 for (var i = 0; i < supervisedUsers.length; ++i) { |
| 302 if (supervisedUsers[i].name != this.profileName_) |
| 303 continue; |
| 304 // Check if another supervised user also exists with that name. |
| 305 var nameIsUnique = true; |
| 306 // Handling the case when multiple supervised users with the same |
| 307 // name exist, but not all of them are on the device. |
| 308 // If at least one is not imported, we want to offer that |
| 309 // option to the user. This could happen due to a bug that allowed |
| 310 // creating SUs with the same name (https://crbug.com/557445). |
| 311 var allOnCurrentDevice = supervisedUsers[i].onCurrentDevice; |
| 312 for (var j = i + 1; j < supervisedUsers.length; ++j) { |
| 313 if (supervisedUsers[j].name == this.profileName_) { |
| 314 nameIsUnique = false; |
| 315 allOnCurrentDevice = |
| 316 allOnCurrentDevice && supervisedUsers[j].onCurrentDevice; |
| 317 } |
| 318 } |
| 319 |
| 320 var opts = { |
| 321 'substitutions': |
| 322 [HTMLEscape(elide(this.profileName_, /* maxLength */ 50))], |
| 323 'attrs': { |
| 324 'id': function(node, value) { |
| 325 return node.tagName == 'A'; |
| 326 }, |
| 327 'is': function(node, value) { |
| 328 return node.tagName == 'A' && value == 'action-link'; |
| 329 }, |
| 330 'role': function(node, value) { |
| 331 return node.tagName == 'A' && value == 'link'; |
| 332 }, |
| 333 'tabindex': function(node, value) { |
| 334 return node.tagName == 'A'; |
| 335 } |
| 336 } |
| 337 }; |
| 338 |
| 339 this.handleMessage_( |
| 340 allOnCurrentDevice ? |
| 341 this.i18n('managedProfilesExistingLocalSupervisedUser') : |
| 342 this.i18nAdvanced( |
| 343 'manageProfilesExistingSupervisedUser', opts)); |
| 344 return; |
| 345 } |
| 346 // No existing supervised user's name matches the entered profile name. |
| 347 // Continue with creating the new supervised profile. |
| 348 this.createProfile_(); |
| 349 // Set this to false after createInProgress_ has been set to true in |
| 350 // order for the 'Save' button to remain disabled. |
| 351 this.loadingSupervisedUsers_ = false; |
| 352 }, |
| 353 |
| 354 /** |
| 355 * Creates the new profile. |
| 356 * @private |
| 357 */ |
| 358 createProfile_: function() { |
| 359 var custodianProfilePath = ''; |
| 360 if (this.signedInUserIndex_ != NO_USER_SELECTED) { |
| 361 custodianProfilePath = |
| 362 this.signedInUser_(this.signedInUserIndex_).profilePath; |
| 363 } |
270 this.hideMessage_(); | 364 this.hideMessage_(); |
271 this.loadingSupervisedUsers_ = true; | 365 this.createInProgress_ = true; |
272 this.browserProxy_.getExistingSupervisedUsers(signedInUser.profilePath) | 366 var createShortcut = |
273 .then(this.showImportSupervisedUserPopup_.bind(this), | 367 this.isProfileShortcutsEnabled_ && this.createShortcut_; |
274 this.handleMessage_.bind(this)); | 368 this.browserProxy_.createProfile( |
275 } | 369 this.profileName_, this.profileIconUrl_, createShortcut, |
276 }, | 370 this.isSupervised_, '', custodianProfilePath); |
277 | 371 }, |
278 /** | 372 |
279 * Handler for the 'Save' button tap event. | 373 /** |
280 * @param {!Event} event | 374 * Handler for the 'import' event fired by #importUserPopup once a |
281 * @private | 375 * supervised |
282 */ | 376 * user is selected to be imported and the popup closes. |
283 onSaveTap_: function(event) { | 377 * @param {!{detail: {supervisedUser: !SupervisedUser, |
284 if (!this.isSupervised_) { | 378 * signedInUser: !SignedInUser}}} event |
285 // The new profile is not supervised. Go ahead and create it. | 379 * @private |
286 this.createProfile_(); | 380 */ |
287 } else if (this.signedInUserIndex_ == NO_USER_SELECTED) { | 381 onImportUserPopupImport_: function(event) { |
288 // If the new profile is supervised, a custodian must be selected. | 382 var supervisedUser = event.detail.supervisedUser; |
289 this.handleMessage_(this.i18n('custodianAccountNotSelectedError')); | 383 var signedInUser = event.detail.signedInUser; |
290 } else { | |
291 var signedInUser = this.signedInUser_(this.signedInUserIndex_); | |
292 this.hideMessage_(); | 384 this.hideMessage_(); |
293 this.loadingSupervisedUsers_ = true; | 385 this.createInProgress_ = true; |
294 this.browserProxy_.getExistingSupervisedUsers(signedInUser.profilePath) | 386 var createShortcut = this.isProfileShortcutsEnabled_; |
295 .then(this.createProfileIfValidSupervisedUser_.bind(this), | 387 this.browserProxy_.createProfile( |
296 this.handleMessage_.bind(this)); | 388 supervisedUser.name, supervisedUser.iconURL, createShortcut, |
297 } | 389 true /* isSupervised */, supervisedUser.id, signedInUser.profilePath); |
298 }, | 390 }, |
299 | 391 |
300 /** | 392 /** |
301 * Displays the import supervised user popup or an error message if there are | 393 * Handler for the 'Cancel' button tap event. |
302 * no existing supervised users. | 394 * @param {!Event} event |
303 * @param {!Array<!SupervisedUser>} supervisedUsers The list of existing | 395 * @private |
304 * supervised users. | 396 */ |
305 * @private | 397 onCancelTap_: function(event) { |
306 */ | 398 if (this.createInProgress_) { |
307 showImportSupervisedUserPopup_: function(supervisedUsers) { | 399 this.createInProgress_ = false; |
308 this.loadingSupervisedUsers_ = false; | 400 this.browserProxy_.cancelCreateProfile(); |
309 if (supervisedUsers.length > 0) { | 401 } else if (this.loadingSupervisedUsers_) { |
310 this.$.importUserPopup.show(this.signedInUser_(this.signedInUserIndex_), | 402 this.loadingSupervisedUsers_ = false; |
311 supervisedUsers); | 403 this.browserProxy_.cancelLoadingSupervisedUsers(); |
312 } else { | 404 } else { |
313 this.handleMessage_(this.i18n('noSupervisedUserImportText')); | 405 this.fire('change-page', {page: 'user-pods-page'}); |
314 } | 406 } |
315 }, | 407 }, |
316 | 408 |
317 /** | 409 /** |
318 * Checks if the entered name matches name of an existing supervised user. | 410 * Handles profile create/import success message pushed by the browser. |
319 * If yes, the user is prompted to import the existing supervised user. | 411 * @param {!ProfileInfo} profileInfo Details of the created/imported |
320 * If no, the new supervised profile gets created. | 412 * profile. |
321 * @param {!Array<!SupervisedUser>} supervisedUsers The list of existing | 413 * @private |
322 * supervised users. | 414 */ |
323 * @private | 415 handleSuccess_: function(profileInfo) { |
324 */ | 416 this.createInProgress_ = false; |
325 createProfileIfValidSupervisedUser_: function(supervisedUsers) { | 417 if (profileInfo.showConfirmation) { |
326 for (var i = 0; i < supervisedUsers.length; ++i) { | 418 this.fire( |
327 if (supervisedUsers[i].name != this.profileName_) | 419 'change-page', |
328 continue; | 420 {page: 'supervised-create-confirm-page', data: profileInfo}); |
329 // Check if another supervised user also exists with that name. | 421 } else { |
330 var nameIsUnique = true; | 422 this.fire('change-page', {page: 'user-pods-page'}); |
331 // Handling the case when multiple supervised users with the same | 423 } |
332 // name exist, but not all of them are on the device. | 424 }, |
333 // If at least one is not imported, we want to offer that | 425 |
334 // option to the user. This could happen due to a bug that allowed | 426 /** |
335 // creating SUs with the same name (https://crbug.com/557445). | 427 * Hides the warning/error message. |
336 var allOnCurrentDevice = supervisedUsers[i].onCurrentDevice; | 428 * @private |
337 for (var j = i + 1; j < supervisedUsers.length; ++j) { | 429 */ |
338 if (supervisedUsers[j].name == this.profileName_) { | 430 hideMessage_: function() { |
339 nameIsUnique = false; | 431 this.isMessageVisble_ = false; |
340 allOnCurrentDevice = allOnCurrentDevice && | 432 }, |
341 supervisedUsers[j].onCurrentDevice; | 433 |
342 } | 434 /** |
343 } | 435 * Handles warning/error messages when a profile is being created/imported |
344 | 436 * or the existing supervised users are being loaded. |
| 437 * @param {*} message An HTML warning/error message. |
| 438 * @private |
| 439 */ |
| 440 handleMessage_: function(message) { |
| 441 this.createInProgress_ = false; |
| 442 this.loadingSupervisedUsers_ = false; |
| 443 this.message_ = '' + message; |
| 444 this.isMessageVisble_ = true; |
| 445 }, |
| 446 |
| 447 /** |
| 448 * Returns a translated message that contains link elements with the 'id' |
| 449 * attribute. |
| 450 * @param {string} id The ID of the string to translate. |
| 451 * @private |
| 452 */ |
| 453 i18nAllowIDAttr_: function(id) { |
345 var opts = { | 454 var opts = { |
346 'substitutions': | |
347 [HTMLEscape(elide(this.profileName_, /* maxLength */ 50))], | |
348 'attrs': { | 455 'attrs': { |
349 'id': function(node, value) { | 456 'id': function(node, value) { |
350 return node.tagName == 'A'; | 457 return node.tagName == 'A'; |
351 }, | |
352 'is': function(node, value) { | |
353 return node.tagName == 'A' && value == 'action-link'; | |
354 }, | |
355 'role': function(node, value) { | |
356 return node.tagName == 'A' && value == 'link'; | |
357 }, | |
358 'tabindex': function(node, value) { | |
359 return node.tagName == 'A'; | |
360 } | 458 } |
361 } | 459 } |
362 }; | 460 }; |
363 | 461 |
364 this.handleMessage_(allOnCurrentDevice ? | 462 return this.i18nAdvanced(id, opts); |
365 this.i18n('managedProfilesExistingLocalSupervisedUser') : | 463 }, |
366 this.i18nAdvanced('manageProfilesExistingSupervisedUser', opts)); | 464 |
367 return; | 465 /** |
368 } | |
369 // No existing supervised user's name matches the entered profile name. | |
370 // Continue with creating the new supervised profile. | |
371 this.createProfile_(); | |
372 // Set this to false after createInProgress_ has been set to true in | |
373 // order for the 'Save' button to remain disabled. | |
374 this.loadingSupervisedUsers_ = false; | |
375 }, | |
376 | |
377 /** | |
378 * Creates the new profile. | |
379 * @private | |
380 */ | |
381 createProfile_: function() { | |
382 var custodianProfilePath = ''; | |
383 if (this.signedInUserIndex_ != NO_USER_SELECTED) { | |
384 custodianProfilePath = | |
385 this.signedInUser_(this.signedInUserIndex_).profilePath; | |
386 } | |
387 this.hideMessage_(); | |
388 this.createInProgress_ = true; | |
389 var createShortcut = this.isProfileShortcutsEnabled_ && | |
390 this.createShortcut_; | |
391 this.browserProxy_.createProfile( | |
392 this.profileName_, this.profileIconUrl_, createShortcut, | |
393 this.isSupervised_, '', custodianProfilePath); | |
394 }, | |
395 | |
396 /** | |
397 * Handler for the 'import' event fired by #importUserPopup once a supervised | |
398 * user is selected to be imported and the popup closes. | |
399 * @param {!{detail: {supervisedUser: !SupervisedUser, | |
400 * signedInUser: !SignedInUser}}} event | |
401 * @private | |
402 */ | |
403 onImportUserPopupImport_: function(event) { | |
404 var supervisedUser = event.detail.supervisedUser; | |
405 var signedInUser = event.detail.signedInUser; | |
406 this.hideMessage_(); | |
407 this.createInProgress_ = true; | |
408 var createShortcut = this.isProfileShortcutsEnabled_; | |
409 this.browserProxy_.createProfile( | |
410 supervisedUser.name, supervisedUser.iconURL, createShortcut, | |
411 true /* isSupervised */, supervisedUser.id, signedInUser.profilePath); | |
412 }, | |
413 | |
414 /** | |
415 * Handler for the 'Cancel' button tap event. | |
416 * @param {!Event} event | |
417 * @private | |
418 */ | |
419 onCancelTap_: function(event) { | |
420 if (this.createInProgress_) { | |
421 this.createInProgress_ = false; | |
422 this.browserProxy_.cancelCreateProfile(); | |
423 } else if (this.loadingSupervisedUsers_) { | |
424 this.loadingSupervisedUsers_ = false; | |
425 this.browserProxy_.cancelLoadingSupervisedUsers(); | |
426 } else { | |
427 this.fire('change-page', {page: 'user-pods-page'}); | |
428 } | |
429 }, | |
430 | |
431 /** | |
432 * Handles profile create/import success message pushed by the browser. | |
433 * @param {!ProfileInfo} profileInfo Details of the created/imported profile. | |
434 * @private | |
435 */ | |
436 handleSuccess_: function(profileInfo) { | |
437 this.createInProgress_ = false; | |
438 if (profileInfo.showConfirmation) { | |
439 this.fire('change-page', {page: 'supervised-create-confirm-page', | |
440 data: profileInfo}); | |
441 } else { | |
442 this.fire('change-page', {page: 'user-pods-page'}); | |
443 } | |
444 }, | |
445 | |
446 /** | |
447 * Hides the warning/error message. | |
448 * @private | |
449 */ | |
450 hideMessage_: function() { | |
451 this.isMessageVisble_ = false; | |
452 }, | |
453 | |
454 /** | |
455 * Handles warning/error messages when a profile is being created/imported | |
456 * or the existing supervised users are being loaded. | |
457 * @param {*} message An HTML warning/error message. | |
458 * @private | |
459 */ | |
460 handleMessage_: function(message) { | |
461 this.createInProgress_ = false; | |
462 this.loadingSupervisedUsers_ = false; | |
463 this.message_ = '' + message; | |
464 this.isMessageVisble_ = true; | |
465 }, | |
466 | |
467 /** | |
468 * Returns a translated message that contains link elements with the 'id' | |
469 * attribute. | |
470 * @param {string} id The ID of the string to translate. | |
471 * @private | |
472 */ | |
473 i18nAllowIDAttr_: function(id) { | |
474 var opts = { | |
475 'attrs': { | |
476 'id' : function(node, value) { | |
477 return node.tagName == 'A'; | |
478 } | |
479 } | |
480 }; | |
481 | |
482 return this.i18nAdvanced(id, opts); | |
483 }, | |
484 | |
485 /** | |
486 * Computed binding determining which profile icon button is toggled on. | 466 * Computed binding determining which profile icon button is toggled on. |
487 * @param {string} iconUrl icon URL of a given icon button. | 467 * @param {string} iconUrl icon URL of a given icon button. |
488 * @param {string} profileIconUrl Currently selected icon URL. | 468 * @param {string} profileIconUrl Currently selected icon URL. |
489 * @return {boolean} | 469 * @return {boolean} |
490 * @private | 470 * @private |
491 */ | 471 */ |
492 isActiveIcon_: function(iconUrl, profileIconUrl) { | 472 isActiveIcon_: function(iconUrl, profileIconUrl) { |
493 return iconUrl == profileIconUrl; | 473 return iconUrl == profileIconUrl; |
494 }, | 474 }, |
495 | 475 |
496 /** | 476 /** |
497 * Computed binding determining whether the paper-spinner is active. | 477 * Computed binding determining whether the paper-spinner is active. |
498 * @param {boolean} createInProgress Is create in progress? | 478 * @param {boolean} createInProgress Is create in progress? |
499 * @param {boolean} loadingSupervisedUsers Are supervised users being loaded? | 479 * @param {boolean} loadingSupervisedUsers Are supervised users being loaded? |
500 * @return {boolean} | 480 * @return {boolean} |
501 * @private | 481 * @private |
502 */ | 482 */ |
503 isSpinnerActive_: function(createInProgress, loadingSupervisedUsers) { | 483 isSpinnerActive_: function(createInProgress, loadingSupervisedUsers) { |
504 return createInProgress || loadingSupervisedUsers; | 484 return createInProgress || loadingSupervisedUsers; |
505 }, | 485 }, |
506 | 486 |
507 /** | 487 /** |
508 * Computed binding determining whether 'Save' button is disabled. | 488 * Computed binding determining whether 'Save' button is disabled. |
509 * @param {boolean} createInProgress Is create in progress? | 489 * @param {boolean} createInProgress Is create in progress? |
510 * @param {boolean} loadingSupervisedUsers Are supervised users being loaded? | 490 * @param {boolean} loadingSupervisedUsers Are supervised users being loaded? |
511 * @param {string} profileName Profile Name. | 491 * @param {string} profileName Profile Name. |
512 * @return {boolean} | 492 * @return {boolean} |
513 * @private | 493 * @private |
514 */ | 494 */ |
515 isSaveDisabled_: function(createInProgress, | 495 isSaveDisabled_: function( |
516 loadingSupervisedUsers, | 496 createInProgress, loadingSupervisedUsers, profileName) { |
517 profileName) { | 497 // TODO(mahmadi): Figure out a way to add 'paper-input-extracted' as a |
518 // TODO(mahmadi): Figure out a way to add 'paper-input-extracted' as a | 498 // dependency and cast to PaperInputElement instead. |
519 // dependency and cast to PaperInputElement instead. | 499 /** @type {{validate: function():boolean}} */ |
520 /** @type {{validate: function():boolean}} */ | 500 var nameInput = this.$.nameInput; |
521 var nameInput = this.$.nameInput; | 501 return createInProgress || loadingSupervisedUsers || !profileName || |
522 return createInProgress || loadingSupervisedUsers || !profileName || | 502 !nameInput.validate(); |
523 !nameInput.validate(); | 503 }, |
524 }, | |
525 | 504 |
526 /** | 505 /** |
527 * Returns True if the import existing supervised user link should be hidden. | 506 * Returns True if the import existing supervised user link should be hidden. |
528 * @param {boolean} createInProgress True if create/import is in progress. | 507 * @param {boolean} createInProgress True if create/import is in progress. |
529 * @param {boolean} loadingSupervisedUsers True if supervised users are being | 508 * @param {boolean} loadingSupervisedUsers True if supervised users are being |
530 * loaded. | 509 * loaded. |
531 * @param {number} signedInUserIndex Index of the selected signed-in user. | 510 * @param {number} signedInUserIndex Index of the selected signed-in user. |
532 * @return {boolean} | 511 * @return {boolean} |
533 * @private | 512 * @private |
534 */ | 513 */ |
535 isImportUserLinkHidden_: function(createInProgress, | 514 isImportUserLinkHidden_: function( |
536 loadingSupervisedUsers, | 515 createInProgress, loadingSupervisedUsers, signedInUserIndex) { |
537 signedInUserIndex) { | 516 return createInProgress || loadingSupervisedUsers || |
538 return createInProgress || loadingSupervisedUsers || | 517 !this.signedInUser_(signedInUserIndex); |
539 !this.signedInUser_(signedInUserIndex); | 518 }, |
540 }, | |
541 | 519 |
542 /** | 520 /** |
543 * Computed binding that returns True if there are any signed-in users. | 521 * Computed binding that returns True if there are any signed-in users. |
544 * @param {!Array<!SignedInUser>} signedInUsers signed-in users. | 522 * @param {!Array<!SignedInUser>} signedInUsers signed-in users. |
545 * @return {boolean} | 523 * @return {boolean} |
546 * @private | 524 * @private |
547 */ | 525 */ |
548 isSignedIn_: function(signedInUsers) { | 526 isSignedIn_: function(signedInUsers) { |
549 return signedInUsers.length > 0; | 527 return signedInUsers.length > 0; |
550 } | 528 } |
551 }); | 529 }); |
552 }()); | 530 }()); |
OLD | NEW |