IGNITE-7610 Web Console: Profile page refactored to component.
authorAlexey Kuznetsov <akuznetsov@apache.org>
Fri, 2 Feb 2018 10:07:57 +0000 (17:07 +0700)
committerAlexey Kuznetsov <akuznetsov@apache.org>
Fri, 2 Feb 2018 10:07:57 +0000 (17:07 +0700)
modules/web-console/frontend/app/app.js
modules/web-console/frontend/app/components/page-profile/component.js [moved from modules/web-console/frontend/app/modules/states/profile.state.js with 64% similarity]
modules/web-console/frontend/app/components/page-profile/controller.js [new file with mode: 0644]
modules/web-console/frontend/app/components/page-profile/index.js [new file with mode: 0644]
modules/web-console/frontend/app/components/page-profile/template.pug [moved from modules/web-console/frontend/views/settings/profile.tpl.pug with 60% similarity]
modules/web-console/frontend/app/data/countries.json
modules/web-console/frontend/controllers/profile-controller.js [deleted file]

index dcb369d..c19018c 100644 (file)
@@ -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)
  * limitations under the License.
  */
 
-import angular from 'angular';
+import template from './template.pug';
+import controller from './controller';
 
-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'
-        }
-    });
-}]);
+export default {
+    template,
+    controller
+};
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 (file)
index 0000000..b60340b
--- /dev/null
@@ -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));
+    }
+}
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 (file)
index 0000000..d9921b3
--- /dev/null
@@ -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);
@@ -20,64 +20,64 @@ mixin lbl(txt)
 mixin lbl-not-required(txt)
     label.col-sm-2.labelFormField #{txt}
 
-.row(ng-controller='profileController')
+.row
     .docs-content
         .docs-header
             h1 User profile
             hr
         .docs-body
-            form.form-horizontal(name='profileForm' novalidate)
+            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='user.firstName' placeholder='Input first name' required ignite-auto-focus)
+                            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='user.lastName' placeholder='Input last name' required)
+                            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-phone' type='email' ng-model='user.email' placeholder='Input email' required)
+                            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='user.phone' placeholder='Input phone')
+                            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='user.company' placeholder='Input company name' required)
+                            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 countries' type='text' ng-model='user.country' placeholder='Choose your country' ng-required='true')
-                    .details-row
+                            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='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')
+                            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 {{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')
+                            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
+                    .details-row#change-password-section
                         .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')
+                            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='user.password' placeholder='New password')
+                                    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='user.password' placeholder='Confirm new password')
+                                    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
-                    a.btn.btn-primary(ng-disabled='!profileCouldBeSaved()' ng-click='profileCouldBeSaved() && saveUser()' bs-tooltip='' data-title='{{saveBtnTipText()}}' data-placement='bottom' data-trigger='hover') Save
+                    button.btn.btn-primary(ng-click='$ctrl.saveUser()' ng-disabled='$ctrl.form.$invalid') Save
index f420f48..18dbe64 100644 (file)
     "code": "FRA"
   },
   {
+    "name": "Belgium",
+    "code": "BEL"
+  },
+  {
     "name": "Switzerland",
     "code": "CHE"
   },
diff --git a/modules/web-console/frontend/controllers/profile-controller.js b/modules/web-console/frontend/controllers/profile-controller.js
deleted file mode 100644 (file)
index 87a8805..0000000
+++ /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));
-        };
-    }
-]];