Repository: ignite Updated Branches: refs/heads/master 8f2045e36 -> 71db70793
IGNITE-7610 Web Console: Profile page refactored to component. Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/958975e8 Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/958975e8 Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/958975e8 Branch: refs/heads/master Commit: 958975e868de174b6c5e09f284cee2c0c427e508 Parents: 8f2045e Author: Alexey Kuznetsov <[email protected]> Authored: Fri Feb 2 17:07:57 2018 +0700 Committer: Alexey Kuznetsov <[email protected]> Committed: Fri Feb 2 17:07:57 2018 +0700 ---------------------------------------------------------------------- modules/web-console/frontend/app/app.js | 7 +- .../app/components/page-profile/component.js | 24 +++++ .../app/components/page-profile/controller.js | 79 ++++++++++++++++ .../app/components/page-profile/index.js | 36 ++++++++ .../app/components/page-profile/template.pug | 83 +++++++++++++++++ .../frontend/app/data/countries.json | 4 + .../app/modules/states/profile.state.js | 36 -------- .../frontend/controllers/profile-controller.js | 94 -------------------- .../frontend/views/settings/profile.tpl.pug | 83 ----------------- 9 files changed, 229 insertions(+), 217 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/958975e8/modules/web-console/frontend/app/app.js ---------------------------------------------------------------------- diff --git a/modules/web-console/frontend/app/app.js b/modules/web-console/frontend/app/app.js index dcb369d..c19018c 100644 --- a/modules/web-console/frontend/app/app.js +++ b/modules/web-console/frontend/app/app.js @@ -29,7 +29,6 @@ import './modules/states/signin.state'; import './modules/states/logout.state'; import './modules/states/password.state'; import './modules/states/configuration.state'; -import './modules/states/profile.state'; import './modules/states/admin.state'; import './modules/states/errors.state'; @@ -108,7 +107,6 @@ import uiGridSubcategories from './filters/uiGridSubcategories.filter'; import id8 from './filters/id8.filter'; // Controllers -import profile from 'Controllers/profile-controller'; import resetPassword from './controllers/reset-password.controller'; // Components @@ -136,6 +134,8 @@ import listEditable from './components/list-editable'; import clusterSelector from './components/cluster-selector'; import connectedClusters from './components/connected-clusters'; +import pageProfile from './components/page-profile'; + import igniteServices from './services'; // Inject external modules. @@ -182,7 +182,6 @@ angular.module('ignite-console', [ 'ignite-console.states.logout', 'ignite-console.states.password', 'ignite-console.states.configuration', - 'ignite-console.states.profile', 'ignite-console.states.admin', 'ignite-console.states.errors', // Common modules. @@ -218,6 +217,7 @@ angular.module('ignite-console', [ clusterSelector.name, connectedClusters.name, igniteListOfRegisteredUsers.name, + pageProfile.name, // Ignite modules. IgniteModules.name ]) @@ -269,7 +269,6 @@ angular.module('ignite-console', [ .service(CSV.name, CSV) // Controllers. .controller(...resetPassword) -.controller(...profile) // Filters. .filter('byName', byName) .filter('defaultName', defaultName) http://git-wip-us.apache.org/repos/asf/ignite/blob/958975e8/modules/web-console/frontend/app/components/page-profile/component.js ---------------------------------------------------------------------- diff --git a/modules/web-console/frontend/app/components/page-profile/component.js b/modules/web-console/frontend/app/components/page-profile/component.js new file mode 100644 index 0000000..9578339 --- /dev/null +++ b/modules/web-console/frontend/app/components/page-profile/component.js @@ -0,0 +1,24 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import template from './template.pug'; +import controller from './controller'; + +export default { + template, + controller +}; http://git-wip-us.apache.org/repos/asf/ignite/blob/958975e8/modules/web-console/frontend/app/components/page-profile/controller.js ---------------------------------------------------------------------- diff --git a/modules/web-console/frontend/app/components/page-profile/controller.js b/modules/web-console/frontend/app/components/page-profile/controller.js new file mode 100644 index 0000000..b60340b --- /dev/null +++ b/modules/web-console/frontend/app/components/page-profile/controller.js @@ -0,0 +1,79 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export default class PageProfileController { + static $inject = [ + '$rootScope', '$scope', '$http', 'IgniteLegacyUtils', 'IgniteMessages', 'IgniteFocus', 'IgniteConfirm', 'IgniteCountries', 'User' + ]; + + constructor($root, $scope, $http, LegacyUtils, Messages, Focus, Confirm, Countries, User) { + Object.assign(this, {$root, $scope, $http, LegacyUtils, Messages, Focus, Confirm, Countries, User}); + } + + $onInit() { + const self = this; + + self.ui = {}; + + this.User.read() + .then((user) => self.ui.user = angular.copy(user)); + + self.ui.countries = this.Countries.getAll(); + } + + toggleToken() { + this.ui.expandedToken = !this.ui.expandedToken; + + if (!this.ui.expandedToken) + this.ui.user.token = this.$root.user.token; + } + + generateToken() { + this.Confirm.confirm('Are you sure you want to change security token?') + .then(() => this.ui.user.token = this.LegacyUtils.randomString(20)); + } + + togglePassword() { + this.ui.expandedPassword = !this.ui.expandedPassword; + + if (this.ui.expandedPassword) + this.Focus.move('profile_password'); + else { + delete this.ui.user.password; + delete this.ui.user.confirm; + } + } + + saveUser() { + return this.$http.post('/api/v1/profile/save', this.ui.user) + .then(this.User.load) + .then(() => { + if (this.ui.expandedPassword) + this.togglePassword(); + + if (this.ui.expandedToken) + this.toggleToken(); + + this.Messages.showInfo('Profile saved.'); + + this.Focus.move('profile-username'); + + this.$root.$broadcast('user', this.ui.user); + }) + .catch((res) => this.Messages.showError('Failed to save profile: ', res)); + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/958975e8/modules/web-console/frontend/app/components/page-profile/index.js ---------------------------------------------------------------------- diff --git a/modules/web-console/frontend/app/components/page-profile/index.js b/modules/web-console/frontend/app/components/page-profile/index.js new file mode 100644 index 0000000..d9921b3 --- /dev/null +++ b/modules/web-console/frontend/app/components/page-profile/index.js @@ -0,0 +1,36 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import angular from 'angular'; +import component from './component'; + +export default angular + .module('ignite-console.page-profile', [ + 'ignite-console.user' + ]) + .config(['$stateProvider', ($stateProvider) => { + // set up the states + $stateProvider.state('base.settings.profile', { + url: '/profile', + component: 'pageProfile', + permission: 'profile', + tfMetaTags: { + title: 'User profile' + } + }); + }]) + .component('pageProfile', component); http://git-wip-us.apache.org/repos/asf/ignite/blob/958975e8/modules/web-console/frontend/app/components/page-profile/template.pug ---------------------------------------------------------------------- diff --git a/modules/web-console/frontend/app/components/page-profile/template.pug b/modules/web-console/frontend/app/components/page-profile/template.pug new file mode 100644 index 0000000..5331670 --- /dev/null +++ b/modules/web-console/frontend/app/components/page-profile/template.pug @@ -0,0 +1,83 @@ +//- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +mixin lbl(txt) + label.col-sm-2.required.labelFormField #{txt} + +mixin lbl-not-required(txt) + label.col-sm-2.labelFormField #{txt} + +.row + .docs-content + .docs-header + h1 User profile + hr + .docs-body + form.form-horizontal(name='$ctrl.form' novalidate) + .col-sm-10(style='padding: 0') + .details-row + +lbl('First name:') + .col-xs-5.col-sm-4 + input#profile-firstname.form-control(ignite-on-enter-focus-move='profile-lastname' type='text' ng-model='$ctrl.ui.user.firstName' placeholder='Input first name' required ignite-auto-focus) + .details-row + +lbl('Last name:') + .col-xs-5.col-sm-4 + input#profile-lastname.form-control(ignite-on-enter-focus-move='profile-email' type='text' ng-model='$ctrl.ui.user.lastName' placeholder='Input last name' required) + .details-row + +lbl('Email:') + .col-xs-5.col-sm-4 + input#profile-email.form-control(ignite-on-enter-focus-move='profile-company' type='email' ng-model='$ctrl.ui.user.email' placeholder='Input email' required) + .details-row + +lbl-not-required('Phone:') + .col-xs-5.col-sm-4 + input#profile-phone.form-control(ignite-on-enter-focus-move='profile-company' type='tel' ng-model='$ctrl.ui.user.phone' placeholder='Input phone') + .details-row + +lbl('Company:') + .col-xs-5.col-sm-4 + input#profile-company.form-control(ignite-on-enter-focus-move='profile-country' type='text' ng-model='$ctrl.ui.user.company' placeholder='Input company name' required) + .details-row + +lbl('Country:') + .col-xs-5.col-sm-4 + button#profile-country.select-toggle.form-control(bs-select bs-options='item.name as item.name for item in $ctrl.ui.countries' type='text' ng-model='$ctrl.ui.user.country' placeholder='Choose your country' ng-required='true') + .details-row#security-token-section + .advanced-options + i.fa( + ng-click='$ctrl.toggleToken()' + ng-class='$ctrl.ui.expandedToken ? "fa-chevron-circle-down" : "fa-chevron-circle-right"') + a(ng-click='$ctrl.toggleToken()') {{$ctrl.ui.expandedToken ? 'Cancel security token changing...' : 'Show security token...'}} + div(ng-if='$ctrl.ui.expandedToken') + +lbl('Security token:') + label#current-security-token {{$ctrl.ui.user.token || 'No security token. Regenerate please.'}} + i.tipLabel.fa.fa-refresh(ng-click='$ctrl.generateToken()' bs-tooltip='' data-title='Generate random security token') + i.tipLabel.fa.fa-clipboard(ignite-copy-to-clipboard='{{$ctrl.ui.user.token}}' bs-tooltip='' data-title='Copy security token to clipboard') + i.tipLabel.icon-help(ng-if=lines bs-tooltip='' data-title='The security token is used for authorization of web agent') + .details-row#change-password-section + .advanced-options + i.fa( + ng-click='$ctrl.togglePassword()' + ng-class='$ctrl.ui.expandedPassword ? "fa-chevron-circle-down" : "fa-chevron-circle-right"') + a(ng-click='$ctrl.togglePassword()') {{$ctrl.ui.expandedPassword ? 'Cancel password changing...' : 'Change password...'}} + div(ng-if='$ctrl.ui.expandedPassword') + .details-row + +lbl('New password:') + .col-xs-5.col-sm-4 + input#profile_password.form-control(ignite-on-enter-focus-move='profile_confirm' type='password' ng-model='$ctrl.ui.user.password' placeholder='New password' required) + .details-row + +lbl('Confirm:') + .col-xs-5.col-sm-4 + input#profile_confirm.form-control(type='password' ng-model='user.confirm' ignite-match='$ctrl.ui.user.password' placeholder='Confirm new password' required) + .col-xs-12.col-sm-12.details-row + button.btn.btn-primary(ng-click='$ctrl.saveUser()' ng-disabled='$ctrl.form.$invalid') Save http://git-wip-us.apache.org/repos/asf/ignite/blob/958975e8/modules/web-console/frontend/app/data/countries.json ---------------------------------------------------------------------- diff --git a/modules/web-console/frontend/app/data/countries.json b/modules/web-console/frontend/app/data/countries.json index f420f48..18dbe64 100644 --- a/modules/web-console/frontend/app/data/countries.json +++ b/modules/web-console/frontend/app/data/countries.json @@ -20,6 +20,10 @@ "code": "FRA" }, { + "name": "Belgium", + "code": "BEL" + }, + { "name": "Switzerland", "code": "CHE" }, http://git-wip-us.apache.org/repos/asf/ignite/blob/958975e8/modules/web-console/frontend/app/modules/states/profile.state.js ---------------------------------------------------------------------- diff --git a/modules/web-console/frontend/app/modules/states/profile.state.js b/modules/web-console/frontend/app/modules/states/profile.state.js deleted file mode 100644 index 35e0ae6..0000000 --- a/modules/web-console/frontend/app/modules/states/profile.state.js +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import angular from 'angular'; - -import templateUrl from 'views/settings/profile.tpl.pug'; - -angular -.module('ignite-console.states.profile', [ - 'ui.router' -]) -.config(['$stateProvider', function($stateProvider) { - // set up the states - $stateProvider.state('base.settings.profile', { - url: '/profile', - templateUrl, - permission: 'profile', - tfMetaTags: { - title: 'User profile' - } - }); -}]); http://git-wip-us.apache.org/repos/asf/ignite/blob/958975e8/modules/web-console/frontend/controllers/profile-controller.js ---------------------------------------------------------------------- diff --git a/modules/web-console/frontend/controllers/profile-controller.js b/modules/web-console/frontend/controllers/profile-controller.js deleted file mode 100644 index 87a8805..0000000 --- a/modules/web-console/frontend/controllers/profile-controller.js +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -// Controller for Profile screen. -export default ['profileController', [ - '$rootScope', '$scope', '$http', 'IgniteLegacyUtils', 'IgniteMessages', 'IgniteFocus', 'IgniteConfirm', 'IgniteCountries', 'User', - function($root, $scope, $http, LegacyUtils, Messages, Focus, Confirm, Countries, User) { - User.read() - .then((user) => $scope.user = angular.copy(user)); - - $scope.countries = Countries.getAll(); - - $scope.generateToken = () => { - Confirm.confirm('Are you sure you want to change security token?') - .then(() => $scope.user.token = LegacyUtils.randomString(20)); - }; - - const _passwordValid = () => { - const cur = $scope.user; - - return !$scope.expandedPassword || (cur.password && cur.confirm && cur.password === cur.confirm); - }; - - const _profileChanged = () => { - const old = $root.user; - const cur = $scope.user; - - return !_.isEqual(old, cur); - }; - - $scope.toggleToken = () => { - $scope.expandedToken = !$scope.expandedToken; - - if (!$scope.expandedToken) - $scope.user.token = $root.user.token; - }; - - $scope.togglePassword = () => { - $scope.expandedPassword = !$scope.expandedPassword; - - if ($scope.expandedPassword) - Focus.move('profile_password'); - else { - delete $scope.user.password; - delete $scope.user.confirm; - } - }; - - $scope.profileCouldBeSaved = () => _profileChanged() && $scope.profileForm && $scope.profileForm.$valid && _passwordValid(); - - $scope.saveBtnTipText = () => { - if (!_profileChanged()) - return 'Nothing to save'; - - if (!_passwordValid()) - return 'Invalid password'; - - return $scope.profileForm && $scope.profileForm.$valid ? 'Save profile' : 'Invalid profile settings'; - }; - - $scope.saveUser = () => { - $http.post('/api/v1/profile/save', $scope.user) - .then(User.load) - .then(() => { - if ($scope.expandedPassword) - $scope.togglePassword(); - - if ($scope.expandedToken) - $scope.toggleToken(); - - Messages.showInfo('Profile saved.'); - - Focus.move('profile-username'); - - $root.$broadcast('user', $scope.user); - }) - .catch((res) => Messages.showError('Failed to save profile: ', res)); - }; - } -]]; http://git-wip-us.apache.org/repos/asf/ignite/blob/958975e8/modules/web-console/frontend/views/settings/profile.tpl.pug ---------------------------------------------------------------------- diff --git a/modules/web-console/frontend/views/settings/profile.tpl.pug b/modules/web-console/frontend/views/settings/profile.tpl.pug deleted file mode 100644 index 8f19b16..0000000 --- a/modules/web-console/frontend/views/settings/profile.tpl.pug +++ /dev/null @@ -1,83 +0,0 @@ -//- - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - -mixin lbl(txt) - label.col-sm-2.required.labelFormField #{txt} - -mixin lbl-not-required(txt) - label.col-sm-2.labelFormField #{txt} - -.row(ng-controller='profileController') - .docs-content - .docs-header - h1 User profile - hr - .docs-body - form.form-horizontal(name='profileForm' novalidate) - .col-sm-10(style='padding: 0') - .details-row - +lbl('First name:') - .col-xs-5.col-sm-4 - input#profile-firstname.form-control(ignite-on-enter-focus-move='profile-lastname' type='text' ng-model='user.firstName' placeholder='Input first name' required ignite-auto-focus) - .details-row - +lbl('Last name:') - .col-xs-5.col-sm-4 - input#profile-lastname.form-control(ignite-on-enter-focus-move='profile-email' type='text' ng-model='user.lastName' placeholder='Input last name' required) - .details-row - +lbl('Email:') - .col-xs-5.col-sm-4 - input#profile-email.form-control(ignite-on-enter-focus-move='profile-phone' type='email' ng-model='user.email' placeholder='Input email' required) - .details-row - +lbl-not-required('Phone:') - .col-xs-5.col-sm-4 - input#profile-phone.form-control(ignite-on-enter-focus-move='profile-company' type='tel' ng-model='user.phone' placeholder='Input phone') - .details-row - +lbl('Company:') - .col-xs-5.col-sm-4 - input#profile-company.form-control(ignite-on-enter-focus-move='profile-country' type='text' ng-model='user.company' placeholder='Input company name' required) - .details-row - +lbl('Country:') - .col-xs-5.col-sm-4 - button#profile-country.select-toggle.form-control(bs-select bs-options='item.name as item.name for item in countries' type='text' ng-model='user.country' placeholder='Choose your country' ng-required='true') - .details-row - .advanced-options - i.fa( - ng-click='toggleToken()' - ng-class='expandedToken ? "fa-chevron-circle-down" : "fa-chevron-circle-right"') - a(ng-click='toggleToken()') {{expandedToken ? 'Cancel security token changing...' : 'Show security token...'}} - div(ng-if='expandedToken') - +lbl('Security token:') - label#current-security-token {{user.token || 'No security token. Regenerate please.'}} - i.tipLabel.fa.fa-refresh(ng-click='generateToken()' bs-tooltip='' data-title='Generate random security token') - i.tipLabel.fa.fa-clipboard(ignite-copy-to-clipboard='{{user.token}}' bs-tooltip='' data-title='Copy security token to clipboard') - i.tipLabel.icon-help(ng-if=lines bs-tooltip='' data-title='The security token is used for authorization of web agent') - .details-row - .advanced-options - i.fa( - ng-click='togglePassword()' - ng-class='expandedPassword ? "fa-chevron-circle-down" : "fa-chevron-circle-right"') - a(ng-click='togglePassword()') {{expandedPassword ? 'Cancel password changing...' : 'Change password...'}} - div(ng-if='expandedPassword') - .details-row - +lbl('New password:') - .col-xs-5.col-sm-4 - input#profile_password.form-control(ignite-on-enter-focus-move='profile_confirm' type='password' ng-model='user.password' placeholder='New password') - .details-row - +lbl('Confirm:') - .col-xs-5.col-sm-4 - input#profile_confirm.form-control(type='password' ng-model='user.confirm' ignite-match='user.password' placeholder='Confirm new password') - .col-xs-12.col-sm-12.details-row - a.btn.btn-primary(ng-disabled='!profileCouldBeSaved()' ng-click='profileCouldBeSaved() && saveUser()' bs-tooltip='' data-title='{{saveBtnTipText()}}' data-placement='bottom' data-trigger='hover') Save
