http://git-wip-us.apache.org/repos/asf/ambari/blob/e83bf1bd/ambari-admin/src/main/resources/ui/admin-web/app/views/stackVersions/stackVersionPage.html ---------------------------------------------------------------------- diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/stackVersions/stackVersionPage.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/stackVersions/stackVersionPage.html index 85d659d..da1ab3f 100644 --- a/ambari-admin/src/main/resources/ui/admin-web/app/views/stackVersions/stackVersionPage.html +++ b/ambari-admin/src/main/resources/ui/admin-web/app/views/stackVersions/stackVersionPage.html @@ -119,14 +119,14 @@ </div> <div id="upload-definition-file-panel" ng-if="createController"> - <div class="col-sm-12 big-radio clearfix hide-soft" ng-class="{'disabled' : networkLost || useRedhatSatellite,'visible':stackRepoUpdateLinkExists}"> - <input type="radio" ng-model="selectedOption.index" value="1" ng-change="togglePublicLocalOptionSelect()" ng-disabled="networkLost || useRedhatSatellite"> - <span>{{'versions.usePublic' | translate}}</span> + <div class="checkbox col-sm-12 big-radio clearfix hide-soft" ng-class="{'disabled' : networkLost || useRedhatSatellite,'visible':stackRepoUpdateLinkExists}"> + <input id="use-public" type="radio" ng-model="selectedOption.index" value="1" ng-change="togglePublicLocalOptionSelect()" ng-disabled="networkLost || useRedhatSatellite"> + <label for="use-public">{{'versions.usePublic' | translate}}</label> <a id="public-disabled-link" href="javascript:void(0);" ng-if="networkLost" ng-click="showPublicRepoDisabledDialog()">{{'versions.networkIssues.networkLost'| translate}}</a> </div> - <div class="col-sm-12 big-radio clearfix"> - <input type="radio" ng-model="selectedOption.index" value="2" ng-change="togglePublicLocalOptionSelect()"> - {{'versions.useLocal' | translate}} + <div class="checkbox col-sm-12 big-radio clearfix"> + <input id="use-local" type="radio" ng-model="selectedOption.index" value="2" ng-change="togglePublicLocalOptionSelect()"> + <label for="use-local">{{'versions.useLocal' | translate}}</label> </div> </div> @@ -181,20 +181,22 @@ <div class="col-sm-9"> <div class="form-group repo-name-url {{repository.Repositories.repo_name}}" ng-class="{'has-error': repository.hasError }" ng-repeat="repository in os.repositories"> - <span class="repo-name-label control-label col-sm-3">{{repository.Repositories.repo_id}}</span> - <div class="col-sm-7 repo-url"> - <input type="text" class="form-control" - placeholder="{{(repository.Repositories.repo_name.indexOf('UTILS') < 0 )?('versions.repository.placeholder' | translate) : ''}}" - ng-model="repository.Repositories.base_url" - ng-change="onRepoUrlChange(repository)" ng-disabled="useRedhatSatellite"> + <div ng-if="showRepo(repository)"> + <span class="repo-name-label control-label col-sm-3">{{repository.Repositories.repo_id}}</span> + <div class="col-sm-7 repo-url"> + <input type="text" class="form-control" + placeholder="{{(repository.Repositories.repo_name.indexOf('UTILS') < 0 )?('versions.repository.placeholder' | translate) : ''}}" + ng-model="repository.Repositories.base_url" + ng-change="onRepoUrlChange(repository)" ng-disabled="useRedhatSatellite"> + </div> + <i class="fa fa-undo orange-icon cursor-pointer" + ng-if="selectedOption.index == 1 && repository.Repositories.base_url != repository.Repositories.initial_base_url + || selectedOption.index == 2 && repository.Repositories.base_url != '' + || editController && repository.Repositories.base_url != repository.Repositories.initial_base_url" + ng-click="undoChange(repository)" + tooltip-html-unsafe="{{'common.undo' | translate}}" + aria-hidden="true"></i> </div> - <i class="fa fa-undo orange-icon cursor-pointer" - ng-if="selectedOption.index == 1 && repository.Repositories.base_url != repository.Repositories.initial_base_url - || selectedOption.index == 2 && repository.Repositories.base_url != '' - || editController && repository.Repositories.base_url != repository.Repositories.initial_base_url" - ng-click="undoChange(repository)" - tooltip-html-unsafe="{{'common.undo' | translate}}" - aria-hidden="true"></i> </div> </div> <div class="col-sm-1 remove-icon" ng-click="removeOS()" ng-class="{'disabled' : useRedhatSatellite}"><i @@ -204,22 +206,21 @@ </div> </div> <div class="clearfix advanced-radio-buttons"> - <div class="col-sm-9" id="skip-validation"> + <div class="col-sm-9"> <div class="checkbox"> - <label> - <input type="checkbox" ng-model="skipValidation" ng-change="clearErrors()" - ng-disabled="useRedhatSatellite"> + <input type="checkbox" id="skip-validation" ng-model="skipValidation" ng-change="clearErrors()" ng-disabled="useRedhatSatellite"> + <label for="skip-validation"> <span ng-class="{'disabled' : useRedhatSatellite}">{{'versions.skipValidation' | translate}}</span> <i class="fa fa-question-circle" tooltip-html-unsafe="{{'versions.alerts.skipValidationWarning' | translate}}" aria-hidden="true"></i> </label> </div> </div> - <div class="col-sm-9" id="use-redhat"> + <div class="col-sm-9"> <div class="checkbox"> - <label> - <input type="checkbox" ng-model="useRedhatSatellite" ng-change="clearErrors()" - ng-disabled="isPublicRepoSelected()"> + <input type="checkbox" id="use-redhat" ng-model="useRedhatSatellite" ng-change="clearErrors()" + ng-disabled="isPublicRepoSelected()"> + <label for="use-redhat"> <span ng-class="{'disabled' : isPublicRepoSelected()}" tooltip="{{(isPublicRepoSelected())? ('versions.useRedhatSatellite.disabledMsg' | translate) : ''}}">{{'versions.useRedhatSatellite.title' | translate}}</span> <i class="fa fa-question-circle"
http://git-wip-us.apache.org/repos/asf/ambari/blob/e83bf1bd/ambari-admin/src/main/resources/ui/admin-web/app/views/urls/create.html ---------------------------------------------------------------------- diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/urls/create.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/urls/create.html index 0c9e1b9..dbd1021 100644 --- a/ambari-admin/src/main/resources/ui/admin-web/app/views/urls/create.html +++ b/ambari-admin/src/main/resources/ui/admin-web/app/views/urls/create.html @@ -16,7 +16,6 @@ * limitations under the License. --> <ol class="breadcrumb"> - <li> <link-to route="views.listViewUrls">{{'urls.viewUrls' | translate}}</link-to></li> <li class="active">{{'urls.createNewUrl' | translate}}</li> </ol> <hr> @@ -25,9 +24,9 @@ <form class="form-horizontal create-user-form" role="form" novalidate name="formHolder.form" autocomplete="off"> <div class="form-group" ng-class="{'has-error' : formHolder.form.url_name.$error.required && formHolder.form.submitted}"> - <label for="urlname" class="col-sm-2 control-label">{{'urls.name' | translate}}</label> + <label for="urlname" class="col-sm-2 control-label">{{'common.name' | translate}}</label> <div class="col-sm-10"> - <input ng-minlength="2" ng-maxlength="25" type="text" id="urlname" class="form-control urlname-input" name="url_name" placeholder="{{'urls.name' | translate}}" ng-model="url.urlName" required autocomplete="off"> + <input ng-minlength="2" ng-maxlength="25" type="text" id="urlname" class="form-control urlname-input" name="url_name" placeholder="{{'common.name' | translate}}" ng-model="url.urlName" required autocomplete="off"> <div class="alert alert-danger top-margin" ng-show="formHolder.form.url_name.$error.required && formHolder.form.submitted">{{'common.alerts.fieldIsRequired' | translate}}</div> <div class="alert alert-danger top-margin" ng-show="formHolder.form.url_name.$error.minlength && formHolder.form.submitted">{{'common.alerts.minimumTwoChars' | translate}}</div> <div class="alert alert-danger top-margin" ng-show="formHolder.form.url_name.$error.maxlength && formHolder.form.submitted">{{'common.alerts.maxTwentyFiveChars' | translate}}</div> @@ -68,7 +67,6 @@ <div class="form-group"> <div class="col-sm-offset-2 col-sm-10"> <button ng-disabled="stepTwoNotCompleted" class="btn btn-primary pull-right left-margin saveuser" ng-click="saveUrl()">{{'common.controls.save' | translate}}</button> - <link-to route="views.listViewUrls" class="btn btn-default pull-right cancel">{{'common.controls.cancel' | translate}}</link-to> </div> </div> http://git-wip-us.apache.org/repos/asf/ambari/blob/e83bf1bd/ambari-admin/src/main/resources/ui/admin-web/app/views/urls/edit.html ---------------------------------------------------------------------- diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/urls/edit.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/urls/edit.html index 9198818..61366db 100644 --- a/ambari-admin/src/main/resources/ui/admin-web/app/views/urls/edit.html +++ b/ambari-admin/src/main/resources/ui/admin-web/app/views/urls/edit.html @@ -16,7 +16,6 @@ * limitations under the License. --> <ol class="breadcrumb"> - <li> <link-to route="views.listViewUrls">{{'urls.viewUrls' | translate}}</link-to></li> <li class="active">{{'urls.edit' | translate}} {{url.url_name}}</li> <div class="pull-right top-margin-4"> <button class="btn deleteuser-btn btn-danger" ng-click="deleteUrl()">{{'views.urlDelete' | translate}}</button> @@ -27,9 +26,9 @@ <form class="form-horizontal create-user-form" role="form" novalidate name="url_form" autocomplete="off"> <div class="form-group" ng-class="{'has-error' : url_form.url_name.$error.required && url_form.submitted}"> - <label for="urlname" class="col-sm-2 control-label">{{'urls.name' | translate}}</label> + <label for="urlname" class="col-sm-2 control-label">{{'common.name' | translate}}</label> <div class="col-sm-10"> - <input disabled type="text" id="urlname" class="form-control urlname-input" name="url_name" placeholder="{{'urls.name' | translate}}" ng-model="url.url_name" required autocomplete="off"> + <input disabled type="text" id="urlname" class="form-control urlname-input" name="url_name" placeholder="{{'common.name' | translate}}" ng-model="url.url_name" required autocomplete="off"> <div class="alert alert-danger top-margin" ng-show="url_form.url_name.$error.required && url_form.submitted">{{'common.alerts.fieldIsRequired' | translate}}</div> </div> </div> @@ -70,7 +69,6 @@ <div class="form-group"> <div class="col-sm-offset-2 col-sm-10"> <button ng-disabled="stepTwoNotCompleted" class="btn btn-primary pull-right left-margin saveuser" ng-click="updateUrl()">{{'common.controls.save' | translate}}</button> - <link-to route="views.listViewUrls" class="btn btn-default pull-right cancel">{{'common.controls.cancel' | translate}}</link-to> </div> </div> http://git-wip-us.apache.org/repos/asf/ambari/blob/e83bf1bd/ambari-admin/src/main/resources/ui/admin-web/app/views/userManagement/groupEdit.html ---------------------------------------------------------------------- diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/userManagement/groupEdit.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/userManagement/groupEdit.html new file mode 100644 index 0000000..5656417 --- /dev/null +++ b/ambari-admin/src/main/resources/ui/admin-web/app/views/userManagement/groupEdit.html @@ -0,0 +1,122 @@ +<!-- +* 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. +--> + +<div id="group-edit"> + <div class="clearfix"> + <ol class="breadcrumb pull-left"> + <li><a href="#/userManagement?tab=groups">{{'common.groups' | translate}}</a></li> + <li class="active">{{group.group_name}}</li> + </ol> + <div class="pull-right"> + <div ng-switch="group.group_type != 'LOCAL'"> + <button + ng-switch-when="true" + class="btn disabled deletegroup-btn" + tooltip="{{'common.cannotDelete' | translate: '{term: constants.group}'}}"> + {{'common.delete' | translate: '{term: constants.group}'}} + </button> + <button ng-switch-when="false" class="btn btn-danger deletegroup-btn" ng-click="deleteGroup(group)"> + {{'common.delete' | translate: '{term: constants.group}'}} + </button> + </div> + </div> + </div> + + <form class="form-horizontal" role="form" novalidate name="form" > + <div class="form-group"> + <label class="col-sm-2 control-label">{{'common.type' | translate}}</label> + <div class="col-sm-10"> + <label class="control-label">{{group.groupTypeName | translate}}</label> + </div> + </div> + <div class="form-group"> + <label class="col-sm-2 control-label">{{group.groupTypeName | translate}} {{'groups.members' | translate}}</label> + <div class="col-sm-10"> + <editable-list items-source="group.editingUsers" resource-type="User" editable="group.group_type == 'LOCAL'"></editable-list> + </div> + </div> + <div class="form-group"> + <label for="role" class="col-sm-2 roles-label"> + {{'groups.role' | translate}} + <i class="fa fa-question-circle" aria-hidden="true" ng-click="showHelpPage()"></i> + </label> + <div class="col-sm-3"> + <select class="form-control" + id="role" + name="role" + ng-change="updateRole()" + ng-options="item as item.permission_label for item in roleOptions track by item.permission_name" + ng-model="currentRole"> + </select> + </div> + </div> + <div class="form-group"> + <label class="col-sm-2 control-label">{{'common.privileges' | translate}}</label> + <div class="col-sm-10"> + <table class="table" ng-hide="hidePrivileges"> + <thead> + <tr> + <th>{{'common.cluster' | translate}}</th> + <th>{{'common.clusterRole' | translate}}</th> + </tr> + </thead> + <tbody> + <tr ng-repeat="(name, privilege) in privileges.clusters"> + <td> + <span class="glyphicon glyphicon-cloud"></span> + <a href="#/clusters/{{name}}/manageAccess">{{name}}</a> + </td> + <td> + <span tooltip="{{item}}" ng-repeat="item in privilege">{{item | translate}}{{$last ? '' : ', '}}</span> + </td> + </tr> + <tr> + <td ng-show="noClusterPriv">{{'common.alerts.noPrivileges' | translate: '{term: constants.cluster}'}}</td> + </tr> + </tbody> + <thead class="view-permission-header"> + <tr> + <th>{{'common.view' | translate}}</th> + <th>{{'common.viewPermissions' | translate}}</th> + </tr> + </thead> + <tbody> + <tr ng-repeat="(name, privilege) in privileges.views"> + <td> + <span class="glyphicon glyphicon-th"></span> + <a href="#/views/{{privilege.view_name}}/versions/{{privilege.version}}/instances/{{name}}/edit">{{name}}</a> + </td> + <td> + <span tooltip="{{item}}" ng-repeat="item in privilege.privileges">{{item | translate}}{{$last ? '' : ', '}}</span> + </td> + <td> + <i class="fa fa-trash-o" aria-hidden="true" ng-click="removeViewPrivilege(name, privilege);"></i> + </td> + </tr> + <tr> + <td ng-show="noViewPriv">{{'common.alerts.noPrivileges' | translate: '{term: constants.view}'}}</td> + </tr> + </tbody> + </table> + <div class="alert alert-info" ng-show="hidePrivileges"> + {{'common.alerts.noPrivilegesDescription' | translate: '{term: constants.group.toLowerCase()}'}} + </div> + </div> + </div> + </form> +</div> http://git-wip-us.apache.org/repos/asf/ambari/blob/e83bf1bd/ambari-admin/src/main/resources/ui/admin-web/app/views/userManagement/groupsList.html ---------------------------------------------------------------------- diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/userManagement/groupsList.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/userManagement/groupsList.html new file mode 100644 index 0000000..d79d14e --- /dev/null +++ b/ambari-admin/src/main/resources/ui/admin-web/app/views/userManagement/groupsList.html @@ -0,0 +1,94 @@ +<!-- +* 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. +--> +<div class="groups-pane"> + <div class="clearfix panel"> + <button class="btn btn-default creategroup-btn pull-right" ng-click="createGroup()"> + {{'groups.createLocal' | translate}} + </button> + </div> + <table class="table table-striped table-hover col-sm-12"> + <thead> + <tr> + <th class="col-sm-6"> + <span>{{'groups.name' | translate}}</span> + </th> + <th class="col-sm-2"> + <span>{{'common.type' | translate}}</span> + </th> + <th class="col-sm-2"> + <span>{{'groups.members' | translate}}</span> + </th> + <th class="col-sm-2"> + <span>{{'common.actions' | translate}}</span> + </th> + </tr> + <tr> + <th class="col-sm-6"> + <div class="search-container"> + <input type="text" class="form-control namefilter" placeholder="{{'common.any' | translate}}" ng-model="filter.name" ng-change="resetPagination()"> + <button type="button" class="close" ng-show="filter.name" ng-click="filter.name=''; resetPagination()"><span aria-hidden="true">×</span><span class="sr-only">{{'common.controls.close' | translate}}</span></button> + </div> + </th> + <th class="col-sm-2"> + <select class="form-control typefilter" + ng-model="filter.type" + ng-options="item.label for item in typeFilterOptions" + ng-change="resetPagination();"> + </select> + </th> + <th class="col-sm-2"></th> + <th class="col-sm-2"></th> + </tr> + </thead> + <tbody> + <tr ng-repeat="group in groups"> + <td class="col-sm-8"> + <span>{{group.group_name}}</span> + </td> + <td class="col-sm-2">{{group.groupTypeName | translate}}</td> + <td class="col-sm-2">{{'groups.membersPlural' | translate: '{n: group.members && group.members.length || 0}'}}</td> + <td class="entity-actions"> + <link-to route="userManagement.editGroup" class="link-to-group" id="{{group.group_name}}"> + <i class="fa fa-pencil"></i> + </link-to> + <a href ng-click="deleteGroup(group)"> + <i class="fa fa-trash-o"></i> + </a> + </td> + </tr> + </tbody> + </table> + <div ng-if="isLoading" class="spinner-container"> + <i class="fa fa-2x fa-spinner fa-spin" aria-hidden="true"></i> + </div> + <div class="alert empty-table-alert col-sm-12" ng-show="!groups.length && !isLoading"> + {{'common.alerts.nothingToDisplay' | translate: '{term: constants.groups}'}} + </div> + <div class="col-sm-12 table-bar" ng-show="totalGroups > minRowsToShowPagination"> + <div class="pull-left filtered-info"> + <span>{{'common.filterInfo' | translate: '{showed: tableInfo.showed, total: tableInfo.total, term: constants.groups}'}}</span> + <span ng-show="isNotEmptyFilter">- <a href ng-click="clearFilters()">{{'common.controls.clearFilters' | translate}}</a></span> + </div> + <div class="pull-right left-margin"> + <pagination class="paginator" total-items="totalGroups" max-size="maxVisiblePages" items-per-page="groupsPerPage" ng-model="currentPage" ng-change="pageChanged()"></pagination> + </div> + <div class="pull-right"> + <select class="form-control" ng-model="groupsPerPage" ng-change="groupsPerPageChanges()" ng-options="currOption for currOption in [10, 25, 50, 100]"></select> + </div> + </div> +</div> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/e83bf1bd/ambari-admin/src/main/resources/ui/admin-web/app/views/userManagement/main.html ---------------------------------------------------------------------- diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/userManagement/main.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/userManagement/main.html new file mode 100644 index 0000000..8520fc2 --- /dev/null +++ b/ambari-admin/src/main/resources/ui/admin-web/app/views/userManagement/main.html @@ -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. +--> + +<div id="user-management"> + <ul class="nav nav-tabs"> + <li ng-class="{active: activeTab === 'USERS'}"> + <a href="#/userManagement?tab=users" >{{'common.users' | translate}}</a> + </li> + <li ng-class="{active: activeTab === 'GROUPS'}"> + <a href="#/userManagement?tab=groups" >{{'common.groups' | translate}}</a> + </li> + </ul> + <div> + <div class="users" ng-if="activeTab === 'USERS'"> + <div ng-include="'views/userManagement/usersList.html'" ng-controller="UsersListCtrl"></div> + </div> + <div class="groups" ng-if="activeTab === 'GROUPS'"> + <div ng-include="'views/userManagement/groupsList.html'" ng-controller="GroupsListCtrl"></div> + </div> + </div> +</div> http://git-wip-us.apache.org/repos/asf/ambari/blob/e83bf1bd/ambari-admin/src/main/resources/ui/admin-web/app/views/userManagement/modals/changePassword.html ---------------------------------------------------------------------- diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/userManagement/modals/changePassword.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/userManagement/modals/changePassword.html new file mode 100644 index 0000000..f29d315 --- /dev/null +++ b/ambari-admin/src/main/resources/ui/admin-web/app/views/userManagement/modals/changePassword.html @@ -0,0 +1,46 @@ +<!-- +* 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. +--> +<div class="modal-header"> + <h3 class="modal-title">{{'users.changePasswordFor' | translate: '{userName: userName}'}}</h3> +</div> +<div class="modal-body"> + <form class="form-horizontal" novalidate name="form.passwordChangeForm" role="form" > + <div class="form-group" ng-class="{'has-error' : (form.passwordChangeForm.currentPassword.$error.required && form.passwordChangeForm.submitted)}"> + <label for="" class="col-sm-4 control-label" >{{'users.yourPassword' | translate}}</label> + <div class="col-sm-8"> + <input type="password" name="currentPassword" class="form-control bottom-margin" placeholder="{{'users.yourPassword' | translate}}" required ng-model="passwordData.currentUserPassword" autocomplete="off"> + <div class="alert alert-danger no-margin-bottom" ng-show='form.passwordChangeForm.password.$error.required && form.passwordChangeForm.submitted'>{{'users.alerts.passwordRequired' | translate}}</div> + </div> + </div> + <div class="form-group no-margin-bottom" ng-class="{'has-error' : (form.passwordChangeForm.password.$error.required && form.passwordChangeForm.submitted) || form.passwordChangeForm.confirmPassword.$error.passwordVerify}"> + <label for="" class="col-sm-4 control-label">{{'users.newPassword' | translate}}:</label> + <div class="col-sm-8"> + <input type="password" class="form-control bottom-margin" name="password" placeholder="{{'users.newPassword' | translate}}" required ng-model="passwordData.password" autocomplete="off"> + <input type="password" class="form-control bottom-margin" name="confirmPassword" placeholder="{{'users.newPasswordConfirmation' | translate}}" required ng-model="passwordData.passwordConfirmation" + password-verify="passwordData.password" autocomplete="off"> + <div class="alert alert-danger no-margin-bottom" ng-show='form.passwordChangeForm.confirmPassword.$error.passwordVerify'>{{'users.alerts.wrongPassword' | translate}}</div> + <div class="alert alert-danger no-margin-bottom" ng-show='form.passwordChangeForm.password.$error.required && form.passwordChangeForm.submitted'>{{'users.alerts.passwordRequired' | translate}}</div> + </div> + + </div> + </form> +</div> +<div class="modal-footer"> + <button class="btn btn-default" ng-click="cancel()">{{'common.controls.cancel' | translate}}</button> + <button class="btn btn-primary" ng-click="ok()">{{'common.controls.ok' | translate}}</button> +</div> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/e83bf1bd/ambari-admin/src/main/resources/ui/admin-web/app/views/userManagement/modals/groupCreate.html ---------------------------------------------------------------------- diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/userManagement/modals/groupCreate.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/userManagement/modals/groupCreate.html new file mode 100644 index 0000000..e11b478 --- /dev/null +++ b/ambari-admin/src/main/resources/ui/admin-web/app/views/userManagement/modals/groupCreate.html @@ -0,0 +1,86 @@ +<!-- +* 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. +--> + +<form id="create-group-form" role="form" novalidate name="form.groupCreateForm"> + <div class="modal-header"> + <h1 class="modal-title"> + {{'groups.createLocal' | translate}} + </h1> + </div> + <div class="modal-body"> + <div class="form-group" + ng-class="{ 'has-error': (form.groupCreateForm.groupName.$error.required || form.groupCreateForm.groupName.$error.pattern) && form.groupCreateForm.submitted }"> + <label for="groupName"> + {{'groups.name' | translate}}<span> *</span> + </label> + <input type="text" + placeholder="{{'groups.name' | translate}}" + ng-pattern="/^([a-zA-Z0-9._\s]+)$/" + autofocus + ng-maxlength="80" + autocomplete="off" + class="form-control" + ng-model="formData.groupName" + name="groupName" + id="groupName" + ng-change="checkIfInstanceExist()" + required> + <span class="help-block validation-block" + ng-show='form.groupCreateForm.groupName.$error.required && form.groupCreateForm.submitted'> + {{'common.alerts.fieldRequired' | translate}} + </span> + <span class="help-block validation-block" + ng-show='form.groupCreateForm.groupName.$error.pattern && form.groupCreateForm.submitted'> + {{'common.alerts.noSpecialChars' | translate}} + </span> + </div> + + <div class="form-group"> + <label>{{'groups.addUsers' | translate}}</label> + <div> + <editable-list items-source="formData.members" resource-type="User" editable="true"></editable-list> + </div> + </div> + + <div class="row"> + <div class="form-group col-sm-6" + ng-class="{ 'has-error': form.groupCreateForm.role.$error.required && form.groupCreateForm.submitted }"> + <label for="role" class="nowrap roles-label"> + {{'groups.role' | translate}} + <i class="fa fa-question-circle" aria-hidden="true" ng-click="showHelpPage()"></i> + </label> + <select + class="form-control" + id="role" + name="role" + ng-model="formData.role"> + <option value="" class="hide">{{'common.select' | translate}}</option> + <option ng-repeat="role in roleOptions" value="{{role.permission_name}}">{{role.permission_label}}</option> + </select> + <span class="help-block validation-block" ng-show='form.groupCreateForm.role.$error.required && form.groupCreateForm.submitted'> + {{'common.alerts.fieldRequired' | translate}} + </span> + </div> + </div> + + </div> + <div class="modal-footer"> + <button class="btn btn-default" ng-click="cancel()">{{'common.controls.cancel' | translate}}</button> + <button class="btn btn-primary" ng-click="save()" type="submit">{{'common.controls.save' | translate}}</button> + </div> +</form> http://git-wip-us.apache.org/repos/asf/ambari/blob/e83bf1bd/ambari-admin/src/main/resources/ui/admin-web/app/views/userManagement/modals/userCreate.html ---------------------------------------------------------------------- diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/userManagement/modals/userCreate.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/userManagement/modals/userCreate.html new file mode 100644 index 0000000..2a71102 --- /dev/null +++ b/ambari-admin/src/main/resources/ui/admin-web/app/views/userManagement/modals/userCreate.html @@ -0,0 +1,147 @@ +<!-- +* 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. +--> + +<form id="create-user-form" role="form" novalidate name="form.userCreateForm"> + <div class="modal-header"> + <h1 class="modal-title"> + {{'users.create' | translate}} + </h1> + </div> + <div class="modal-body"> + <div class="form-group" + ng-class="{ 'has-error': (form.userCreateForm.userName.$error.required || form.userCreateForm.userName.$error.pattern) && form.userCreateForm.submitted }"> + <label for="userName"> + {{'users.username' | translate}}<span> *</span> + <i class="fa fa-question-circle" aria-hidden="true"></i> + </label> + <input type="text" + autofocus + placeholder="{{'users.user.name' | translate}}" + ng-pattern="/^[^<>&`|\\]+$/" + ng-maxlength="80" + tooltip="{{'users.userNameTip' | translate}}" + autocomplete="off" + tooltip-trigger="focus" + class="form-control" + ng-model="formData.userName" + name="userName" + id="userName" + ng-change="checkIfInstanceExist()" + required> + <span class="help-block validation-block" + ng-show='form.userCreateForm.userName.$error.required && form.userCreateForm.submitted'> + {{'common.alerts.fieldRequired' | translate}} + </span> + <span class="help-block validation-block" + ng-show='form.userCreateForm.userName.$error.pattern && form.userCreateForm.submitted'> + {{'common.alerts.noSpecialChars' | translate}} + </span> + </div> + + <div class="row"> + <div class="form-group col-sm-6" + ng-class="{ 'has-error': form.userCreateForm.password.$error.required && form.userCreateForm.submitted }"> + <label for="password"> + {{'users.password' | translate}}<span> *</span> + </label> + <input type="password" + id="password" + class="form-control" + name="password" + placeholder="{{'users.password' | translate}}" + required + ng-model="formData.password" + autocomplete="off"> + <span class="help-block validation-block" + ng-show='form.userCreateForm.password.$error.required && form.userCreateForm.submitted'> + {{'common.alerts.fieldRequired' | translate}} + </span> + </div> + <div class="form-group col-sm-6" + ng-class="{ 'has-error': form.userCreateForm.confirmPassword.$error.passwordVerify || (form.userCreateForm.confirmPassword.$error.required && form.userCreateForm.submitted) }"> + <label for="confirmPassword"> + {{'users.confirmPassword' | translate}}<span> *</span> + </label> + <input type="password" + id="confirmPassword" + class="form-control" + name="confirmPassword" + placeholder="{{'users.confirmPassword' | translate}}" + required + password-verify="formData.password" + ng-model="formData.confirmPassword" + autocomplete="off"> + <span class="help-block validation-block" + ng-show='form.userCreateForm.confirmPassword.$error.required && form.userCreateForm.submitted'> + {{'common.alerts.fieldRequired' | translate}} + </span> + <span class="help-block validation-block" + ng-show='form.userCreateForm.confirmPassword.$error.passwordVerify'> + {{'users.alerts.wrongPassword' | translate}} + </span> + </div> + </div> + + <div class="row"> + <div class="form-group col-sm-6" + ng-class="{ 'has-error': form.userCreateForm.role.$error.required && form.userCreateForm.submitted }"> + <label for="role" class="nowrap roles-label"> + {{'users.role' | translate}}<span> *</span> + <i class="fa fa-question-circle" aria-hidden="true" ng-click="showHelpPage()"></i> + </label> + <select + class="form-control" + id="role" + name="role" + ng-model="formData.role" + required> + <option value="" class="hide">{{'common.select' | translate}}</option> + <option ng-repeat="role in roleOptions" value="{{role.permission_name}}">{{role.permission_label}}</option> + </select> + <span class="help-block validation-block" ng-show='form.userCreateForm.role.$error.required && form.userCreateForm.submitted'> + {{'common.alerts.fieldRequired' | translate}} + </span> + </div> + </div> + + <div class="form-group"> + <label> + {{'users.isAmbariAdmin' | translate}}<span> *</span> + <i class="fa fa-question-circle" aria-hidden="true"></i> + </label> + <div> + <toggle-switch model="formData.isAdmin" on-label="{{'common.yes' | translate}}" off-label="{{'common.no' | translate}}" class="switch-primary" data-off-color="danger"></toggle-switch> + </div> + </div> + + <div class="form-group"> + <label> + {{'users.isActive' | translate}}<span> *</span> + <i class="fa fa-question-circle" aria-hidden="true"></i> + </label> + <div> + <toggle-switch model="formData.isActive" on-label="{{'users.active' | translate}}" off-label="{{'users.inactive' | translate}}" class="switch-primary" data-off-color="danger"></toggle-switch> + </div> + </div> + + </div> + <div class="modal-footer"> + <button class="btn btn-default" ng-click="cancel()">{{'common.controls.cancel' | translate}}</button> + <button class="btn btn-primary" ng-click="save()" type="submit">{{'common.controls.save' | translate}}</button> + </div> +</form> http://git-wip-us.apache.org/repos/asf/ambari/blob/e83bf1bd/ambari-admin/src/main/resources/ui/admin-web/app/views/userManagement/userEdit.html ---------------------------------------------------------------------- diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/userManagement/userEdit.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/userManagement/userEdit.html new file mode 100644 index 0000000..cc46173 --- /dev/null +++ b/ambari-admin/src/main/resources/ui/admin-web/app/views/userManagement/userEdit.html @@ -0,0 +1,140 @@ +<!-- +* 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. +--> + +<div ng-show="user" id="user-edit"> + <div class="clearfix"> + <ol class="breadcrumb pull-left"> + <li><a href="#/userManagement?tab=users">{{'common.users' | translate}}</a></li> + <li class="active"><span class="glyphicon glyphicon-flash" ng-show="user.admin"></span>{{user.user_name}}</li> + </ol> + <div class="pull-right"> + <div ng-switch="isCurrentUser || user.user_type != 'LOCAL'"> + <button class="btn deleteuser-btn disabled btn-default" ng-switch-when="true" tooltip="{{'common.cannotDelete' | translate: '{term: constants.user}'}}">{{'common.delete' | translate: '{term: constants.user}'}}</button> + <button class="btn deleteuser-btn btn-danger" ng-switch-when="false" ng-click="deleteUser()">{{'common.delete' | translate: '{term: constants.user}'}}</button> + </div> + </div> + </div> + <hr> + <form class="form-horizontal" role="form" > + <div class="form-group"> + <label class="col-sm-2 ">{{'common.type' | translate}}</label> + <div class="col-sm-10"> + <label>{{user.userTypeName}}</label> + </div> + </div> + <div class="form-group"> + <label class="col-sm-2 ">{{'users.status' | translate}}</label> + <div class="col-sm-10"> + <toggle-switch on-change="toggleUserActive()" disabled-tooltip="{{'users.alerts.cannotChange' | translate: '{term: constants.status}'}}" ng-disabled="isCurrentUser" model="user.active" on-label="{{'users.active' | translate}}" off-label="{{'users.inactive' | translate}}" class="switch-primary userstatus {{user ? '' : 'no-animation'}}" data-off-color="danger"></toggle-switch> + </div> + </div> + <div class="form-group"> + <label class="col-sm-2 "><span class="glyphicon glyphicon-flash"></span> {{'users.ambariAdmin' | translate}}</label> + <div class="col-sm-10"> + <toggle-switch on-change="toggleUserAdmin()" disabled-tooltip="{{'users.alerts.cannotChange' | translate: '{term: constants.admin}'}}" ng-disabled="isCurrentUser" model="user.admin" on-label="{{'common.yes' | translate}}" off-label="{{'common.no' | translate}}" class="switch-primary userstatus {{user ? '' : 'no-animation'}}" data-off-color="danger"></toggle-switch> + </div> + </div> + <div class="form-group"> + <label class="col-sm-2 ">{{'users.password' | translate}}</label> + <div class="col-sm-10"> + <div ng-switch="user.user_type != 'LOCAL'"> + <button class="btn deleteuser-btn disabled btn-default" ng-switch-when="true" tooltip="{{'users.alerts.cannotChange' | translate: '{term: constants.password}'}}">{{'users.changePassword' | translate}}</button> + <a href ng-click="openChangePwdDialog()" ng-switch-when="false" class="btn btn-default changepassword">{{'users.changePassword' | translate}}</a> + </div> + + </div> + </div> + <div class="form-group"> + <label class="col-sm-2 ">{{getUserMembership(user.user_type)}}</label> + <div class="col-sm-10"> + <editable-list items-source="editingGroupsList" resource-type="Group" editable="user.user_type == 'LOCAL'"></editable-list> + </div> + </div> + + <div class="form-group"> + <label for="role" class="col-sm-2 roles-label"> + {{'users.role' | translate}} + <i class="fa fa-question-circle" aria-hidden="true" ng-click="showHelpPage()"></i> + </label> + <div class="col-sm-3"> + <select ng-hide="user.admin" + class="form-control" + id="role" + name="role" + ng-options="item as item.permission_label for item in roleOptions track by item.permission_name" + ng-change="updateRole()" + ng-model="currentRole"> + </select> + <span ng-show="user.admin" class="roles-label">{{user.roles[0].permission_label}}</span> + </div> + </div> + + <div class="form-group" > + <label class="col-sm-2 ">{{'common.privileges' | translate}}</label> + <div class="col-sm-10"> + <table class="table" ng-hide="hidePrivileges || user.admin"> + <thead> + <tr> + <th>{{'common.cluster' | translate}}</th> + <th>{{'common.clusterRole' | translate}}</th> + </tr> + </thead> + <tbody> + <tr ng-repeat="(name, privilege) in privilegesView.clusters"> + <td> + <span class="glyphicon glyphicon-cloud"></span> + <a href="#/clusters/{{name}}/manageAccess">{{name}}</a> + </td> + <td> + <span tooltip="{{privilege.permission_label}}">{{privilege.permission_label}}</span> + </td> + </tr> + <tr> + <td ng-show="noClusterPriv">{{'common.alerts.noPrivileges' | translate: '{term: constants.cluster}'}}</td> + </tr> + </tbody> + <thead class="view-permission-header"> + <tr> + <th>{{'common.view' | translate}}</th> + <th>{{'common.viewPermissions' | translate}}</th> + </tr> + </thead> + <tbody> + <tr ng-repeat="(name, privilege) in privilegesView.views"> + <td> + <span class="glyphicon glyphicon-th"></span> + <a href="#/views/{{privilege.view_name}}/versions/{{privilege.version}}/instances/{{name}}/edit">{{name}}</a> + </td> + <td> + <span tooltip="{{item}}" ng-repeat="item in privilege.privileges track by $index">{{item | translate}}{{$last ? '' : ', '}}</span> + </td> + <td> + <i class="fa fa-trash-o" aria-hidden="true" ng-click="removeViewPrivilege(name, privilege);"></i> + </td> + </tr> + <tr> + <td ng-show="noViewPriv">{{'common.alerts.noPrivileges' | translate: '{term: constants.view}'}}</td> + </tr> + </tbody> + </table> + <div class="alert alert-info" ng-show="hidePrivileges && !user.admin">{{'common.alerts.noPrivilegesDescription' | translate: '{term: constants.user}'}}</div> + <div class="alert alert-info" ng-show="user.admin">{{'users.userIsAdmin' | translate}}</div> + </div> + </div> + </form> +</div> http://git-wip-us.apache.org/repos/asf/ambari/blob/e83bf1bd/ambari-admin/src/main/resources/ui/admin-web/app/views/userManagement/usersList.html ---------------------------------------------------------------------- diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/userManagement/usersList.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/userManagement/usersList.html new file mode 100644 index 0000000..4a33a31 --- /dev/null +++ b/ambari-admin/src/main/resources/ui/admin-web/app/views/userManagement/usersList.html @@ -0,0 +1,119 @@ +<!-- +* 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. +--> + +<div class="users-pane"> + <div class="clearfix panel"> + <button class="btn btn-default createuser-btn pull-right" ng-click="createUser();"> + {{'users.create' | translate}} + </button> + </div> + <table class="table table-striped table-hover"> + <thead> + <tr class="fix-bottom"> + <th> + <span>{{'users.username' | translate}}</span> + </th> + <th> + <span>{{'clusters.role' | translate}}</span> + </th> + <th> + <span>{{'users.status' | translate}}</span> + </th> + <th> + <span>{{'common.type' | translate}}</span> + </th> + <th> + <span>{{'common.group' | translate}}</span> + </th> + <th class="entity-actions"> + <span>{{'common.actions' | translate}}</span> + </th> + </tr> + <tr class="fix-top"> + <th> + <div class="search-container"> + <input type="text" class="form-control namefilter" placeholder="{{'common.any' | translate}}" ng-model="filters.name" ng-change="resetPagination()"> + <button type="button" class="close clearfilter" ng-show="filters.name" ng-click="filters.name=''; resetPagination()"> + <span aria-hidden="true">×</span><span class="sr-only">{{'common.controls.close' | translate}}</span> + </button> + </div> + </th> + <th></th> + <th> + <select class="form-control statusfilter" + ng-model="filters.status" + ng-options="item.label for item in activeFilterOptions" + ng-change="resetPagination()"> + </select> + </th> + <th> + <select class="form-control typefilter" + ng-model="filters.type" + ng-options="item.label for item in typeFilterOptions" + ng-change="resetPagination()"> + </select> + </th> + <th></th> + <th></th> + </tr> + </thead> + <tbody> + <tr ng-repeat="user in users"> + <td> + <span>{{user.Users.user_name}}</span> + </td> + <td> + <span>{{user.Users.roles[0].permission_label}}</span> + </td> + <td> + <span> + {{(user.Users.active ? 'users.active' : 'users.inactive') | translate}} + </span> + </td> + <td><span>{{user.Users.userTypeName}}</span></td> + <td><span>{{user.Users.groups.length ? user.Users.groups.join(' ') : '-'}}</span></td> + <td class="entity-actions"> + <a href="#/users/{{user.Users.encodedName}}/edit"> + <i class="fa fa-pencil"></i> + </a> + <a href ng-click="deleteUser(user.Users)"> + <i class="fa fa-trash-o"></i> + </a> + </td> + </tr> + </tbody> + </table> + <div ng-if="isLoading" class="spinner-container"> + <i class="fa fa-2x fa-spinner fa-spin" aria-hidden="true"></i> + </div> + <div class="alert empty-table-alert col-sm-12" ng-show="!users.length && !isLoading"> + {{'common.alerts.nothingToDisplay' | translate: '{term: constants.users}'}} + </div> + <div class="col-sm-12 table-bar" ng-show="totalUsers > minRowsToShowPagination"> + <div class="pull-left filtered-info"> + <span>{{'common.filterInfo' | translate: '{showed: tableInfo.showed, total: tableInfo.total, term: constants.users}'}}</span> + <span ng-show="isNotEmptyFilter">- <a href ng-click="clearFilters()">{{'common.controls.clearFilters' | translate}}</a></span> + </div> + <div class="pull-right left-margin"> + <pagination class="paginator" total-items="totalUsers" max-size="maxVisiblePages" items-per-page="usersPerPage" ng-model="currentPage" ng-change="pageChanged()"></pagination> + </div> + <div class="pull-right"> + <select class="form-control" ng-model="usersPerPage" ng-change="usersPerPageChanges()" ng-options="currOption for currOption in [10, 25, 50, 100]"></select> + </div> + </div> +</div> http://git-wip-us.apache.org/repos/asf/ambari/blob/e83bf1bd/ambari-admin/src/main/resources/ui/admin-web/app/views/users/create.html ---------------------------------------------------------------------- diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/users/create.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/users/create.html deleted file mode 100644 index 80a3b04..0000000 --- a/ambari-admin/src/main/resources/ui/admin-web/app/views/users/create.html +++ /dev/null @@ -1,82 +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. ---> -<ol class="breadcrumb"> - <li><a href="#/users">{{'common.users' | translate}}</a></li> - <li class="active">{{'users.create' | translate}}</li> -</ol> -<hr> -<form class="form-horizontal create-user-form" role="form" novalidate name="form" autocomplete="off"> - <div class="form-group" ng-class="{'has-error' : form.user_name.$error.required && form.submitted}"> - <label for="username" class="col-sm-2 control-label">{{'users.username' | translate}}</label> - <div class="col-sm-10" - ng-class="{'has-error': form.user_name.$error.pattern}"> - <input - autofocus - type="text" - id="username" - class="form-control username-input" - name="user_name" - placeholder="{{'users.userName' | translate}}" - ng-model="user.user_name" - ng-required="true" - ng-pattern="/^[^<>&`|\\]+$/" - ng-maxlength="80" - tooltip="{{'users.userNameTip' | translate}}" - autocomplete="off" - tooltip-trigger="focus"> - <div class="alert alert-danger top-margin" ng-show="form.user_name.$error.required && form.submitted">{{'common.alerts.fieldIsRequired' | translate}}</div> - </div> - </div> - <div class="form-group"> - <label for="" class="col-sm-2 control-label">{{'common.type' | translate}}</label> - <div class="col-sm-10"> - <label for="" class="control-label">{{'common.local' | translate}}</label> - </div> - </div> - <div class="form-group"> - <label for="" class="col-sm-2 control-label">{{'users.status' | translate}}</label> - <div class="col-sm-10"> - <toggle-switch model="user.active" on-label="{{'users.active' | translate}}" off-label="{{'users.inactive' | translate}}" class="switch-primary userstatus" data-off-color="danger"></toggle-switch> - </div> - </div> - <div class="form-group"> - <label for="" class="col-sm-2 control-label"><span class="glyphicon glyphicon-flash"></span>{{'users.ambariAdmin' | translate}}</label> - <div class="col-sm-10"> - <toggle-switch ng-disabled="isCurrentUser" model="user.admin" on-label="{{'common.yes' | translate}}" off-label="{{'common.no' | translate}}" class="switch-primary userstatus" data-off-color="danger"></toggle-switch> - </div> - </div> - <div class="form-group" ng-class="{'has-error' : (form.password.$error.required && form.submitted) || form.confirmPassword.$error.passwordVerify}"> - <label for="password" class="col-sm-2 control-label">{{'users.password' | translate}}</label> - <div class="col-sm-10"> - <input type="password" class="form-control bottom-margin userpassword" name="password" placeholder="{{'users.password' | translate}}" required ng-model="user.password" autocomplete="off"> - <input type="password" class="form-control bottom-margin userpasswordconfirm" name="confirmPassword" placeholder="{{'users.passwordConfirmation' | translate}}" required ng-model="user.passwordConfirmation" - password-verify="user.password" autocomplete="off"> - - <div class="alert alert-danger" ng-show='form.confirmPassword.$error.passwordVerify'>{{'users.alerts.wrongPassword' | translate}}</div> - <div class="alert alert-danger" ng-show='form.password.$error.required && form.submitted'>{{'users.alerts.passwordRequired' | translate}}</div> - - </div> - </div> - <div class="form-group"> - <div class="col-sm-offset-2 col-sm-10"> - <button class="btn btn-primary pull-right left-margin saveuser" ng-click="createUser()">{{'common.controls.save' | translate}}</button> - <a class="btn btn-default pull-right cancel" href ng-click="cancel()">{{'common.controls.cancel' | translate}}</a> - </div> - </div> - -</form> http://git-wip-us.apache.org/repos/asf/ambari/blob/e83bf1bd/ambari-admin/src/main/resources/ui/admin-web/app/views/users/list.html ---------------------------------------------------------------------- diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/users/list.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/users/list.html deleted file mode 100644 index 09024a5..0000000 --- a/ambari-admin/src/main/resources/ui/admin-web/app/views/users/list.html +++ /dev/null @@ -1,96 +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. ---> - -<div class="users-pane"> - <div class="clearfix"> - <ol class="breadcrumb pull-left"> - <li class="active">{{'common.users' | translate}}</li> - </ol> - <div class="pull-right top-margin-4"> - <link-to route="users.create" class="btn btn-primary createuser-btn"><span class="glyphicon glyphicon-plus"></span> {{'users.create' | translate}}</link-to> - </div> - </div> - <hr> - <table class="table table-striped table-hover"> - <thead> - <tr> - <th width="30"> - <span class="bottom-margin admin-filter glyphicon glyphicon-flash" - ng-class="{'no-filter' : !adminFilter}" - ng-click="toggleAdminFilter()" - tooltip="{{(adminFilter ? 'users.showAll' : 'users.showAdmin') | translate}}" - ></span> - </th> - <th> - <div class="search-container"> - <label for="">{{'users.username' | translate}}</label> - <input type="text" class="form-control namefilter" placeholder="{{'common.any' | translate}}" ng-model="currentNameFilter" ng-change="resetPagination()"> - <button type="button" class="close clearfilter" ng-show="currentNameFilter" ng-click="currentNameFilter=''; resetPagination()"><span aria-hidden="true">×</span><span class="sr-only">{{'common.controls.close' | translate}}</span></button> - </div> - </th> - <th> - <label for="">{{'common.type' | translate}}</label> - <select class="form-control typefilter" - ng-model="currentTypeFilter" - ng-options="item.label for item in typeFilterOptions" - ng-change="resetPagination()"> - </select> - - </th> - <th> - <label for="">{{'users.status' | translate}}</label> - <select class="form-control statusfilter" - ng-model="currentActiveFilter" - ng-options="item.label for item in activeFilterOptions" - ng-change="resetPagination()"> - </select> - </th> - </tr> - </thead> - <tbody> - <tr ng-repeat="user in users"> - <td> - <span class="glyphicon" tooltip="{{user.Users.admin ? constants.admin : ''}}" ng-class="{'glyphicon-flash' : user.Users.admin}"></span> - </td> - <td> - <a href="#/users/{{user.Users.encoded_name}}">{{user.Users.user_name}}</a> - </td> - <td>{{user.Users.userTypeName}}</td> - <td><span ng-class="user.Users.active ? 'text-success' : 'text-danger'">{{(user.Users.active ? 'users.active' : 'users.inactive') | translate}}</span></td> - </tr> - </tbody> - </table> - <div ng-if="isLoading" class="spinner-container"> - <i class="fa fa-2x fa-spinner fa-spin" aria-hidden="true"></i> - </div> - <div class="alert alert-info col-sm-12" ng-show="!users.length && !isLoading"> - {{'common.alerts.nothingToDisplay' | translate: '{term: constants.users}'}} - </div> - <div class="col-sm-12 table-bar"> - <div class="pull-left filtered-info"> - <span>{{'common.filterInfo' | translate: '{showed: tableInfo.showed, total: tableInfo.total, term: constants.users}'}}</span> - <span ng-show="isNotEmptyFilter">- <a href ng-click="clearFilters()">{{'common.controls.clearFilters' | translate}}</a></span> - </div> - <div class="pull-right left-margin"> - <pagination class="paginator" total-items="totalUsers" max-size="maxVisiblePages" items-per-page="usersPerPage" ng-model="currentPage" ng-change="pageChanged()"></pagination> - </div> - <div class="pull-right"> - <select class="form-control" ng-model="usersPerPage" ng-change="usersPerPageChanges()" ng-options="currOption for currOption in [10, 25, 50, 100]"></select> - </div> - </div> -</div> http://git-wip-us.apache.org/repos/asf/ambari/blob/e83bf1bd/ambari-admin/src/main/resources/ui/admin-web/app/views/users/modals/changePassword.html ---------------------------------------------------------------------- diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/users/modals/changePassword.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/users/modals/changePassword.html deleted file mode 100644 index f29d315..0000000 --- a/ambari-admin/src/main/resources/ui/admin-web/app/views/users/modals/changePassword.html +++ /dev/null @@ -1,46 +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. ---> -<div class="modal-header"> - <h3 class="modal-title">{{'users.changePasswordFor' | translate: '{userName: userName}'}}</h3> -</div> -<div class="modal-body"> - <form class="form-horizontal" novalidate name="form.passwordChangeForm" role="form" > - <div class="form-group" ng-class="{'has-error' : (form.passwordChangeForm.currentPassword.$error.required && form.passwordChangeForm.submitted)}"> - <label for="" class="col-sm-4 control-label" >{{'users.yourPassword' | translate}}</label> - <div class="col-sm-8"> - <input type="password" name="currentPassword" class="form-control bottom-margin" placeholder="{{'users.yourPassword' | translate}}" required ng-model="passwordData.currentUserPassword" autocomplete="off"> - <div class="alert alert-danger no-margin-bottom" ng-show='form.passwordChangeForm.password.$error.required && form.passwordChangeForm.submitted'>{{'users.alerts.passwordRequired' | translate}}</div> - </div> - </div> - <div class="form-group no-margin-bottom" ng-class="{'has-error' : (form.passwordChangeForm.password.$error.required && form.passwordChangeForm.submitted) || form.passwordChangeForm.confirmPassword.$error.passwordVerify}"> - <label for="" class="col-sm-4 control-label">{{'users.newPassword' | translate}}:</label> - <div class="col-sm-8"> - <input type="password" class="form-control bottom-margin" name="password" placeholder="{{'users.newPassword' | translate}}" required ng-model="passwordData.password" autocomplete="off"> - <input type="password" class="form-control bottom-margin" name="confirmPassword" placeholder="{{'users.newPasswordConfirmation' | translate}}" required ng-model="passwordData.passwordConfirmation" - password-verify="passwordData.password" autocomplete="off"> - <div class="alert alert-danger no-margin-bottom" ng-show='form.passwordChangeForm.confirmPassword.$error.passwordVerify'>{{'users.alerts.wrongPassword' | translate}}</div> - <div class="alert alert-danger no-margin-bottom" ng-show='form.passwordChangeForm.password.$error.required && form.passwordChangeForm.submitted'>{{'users.alerts.passwordRequired' | translate}}</div> - </div> - - </div> - </form> -</div> -<div class="modal-footer"> - <button class="btn btn-default" ng-click="cancel()">{{'common.controls.cancel' | translate}}</button> - <button class="btn btn-primary" ng-click="ok()">{{'common.controls.ok' | translate}}</button> -</div> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/e83bf1bd/ambari-admin/src/main/resources/ui/admin-web/app/views/users/show.html ---------------------------------------------------------------------- diff --git a/ambari-admin/src/main/resources/ui/admin-web/app/views/users/show.html b/ambari-admin/src/main/resources/ui/admin-web/app/views/users/show.html deleted file mode 100644 index f965c5d..0000000 --- a/ambari-admin/src/main/resources/ui/admin-web/app/views/users/show.html +++ /dev/null @@ -1,122 +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. ---> - -<div ng-show="user" class="user-edit-panel"> - <div class="clearfix"> - <ol class="breadcrumb pull-left"> - <li><a href="#/users">{{'common.users' | translate}}</a></li> - <li class="active"><span class="glyphicon glyphicon-flash" ng-show="user.admin"></span>{{user.user_name}}</li> - </ol> - <div class="pull-right top-margin-4"> - <div ng-switch="isCurrentUser || user.user_type != 'LOCAL'"> - <button class="btn deleteuser-btn disabled btn-default" ng-switch-when="true" tooltip="{{'common.cannotDelete' | translate: '{term: constants.user}'}}">{{'common.delete' | translate: '{term: constants.user}'}}</button> - <button class="btn deleteuser-btn btn-danger" ng-switch-when="false" ng-click="deleteUser()">{{'common.delete' | translate: '{term: constants.user}'}}</button> - </div> - </div> - </div> - <hr> - <form class="form-horizontal" role="form" > - <div class="form-group"> - <label for="" class="col-sm-2 control-label">{{'common.type' | translate}}</label> - <div class="col-sm-10"> - <label for="" class="control-label">{{user.userTypeName}}</label> - </div> - </div> - <div class="form-group"> - <label for="" class="col-sm-2 control-label">{{'users.status' | translate}}</label> - <div class="col-sm-10"> - <toggle-switch on-change="toggleUserActive()" disabled-tooltip="{{'users.alerts.cannotChange' | translate: '{term: constants.status}'}}" ng-disabled="isCurrentUser" model="user.active" on-label="{{'users.active' | translate}}" off-label="{{'users.inactive' | translate}}" class="switch-primary userstatus {{user ? '' : 'no-animation'}}" data-off-color="danger"></toggle-switch> - </div> - </div> - <div class="form-group"> - <label for="" class="col-sm-2 control-label"><span class="glyphicon glyphicon-flash"></span> {{'users.ambariAdmin' | translate}}</label> - <div class="col-sm-10"> - <toggle-switch on-change="toggleUserAdmin()" disabled-tooltip="{{'users.alerts.cannotChange' | translate: '{term: constants.admin}'}}" ng-disabled="isCurrentUser" model="user.admin" on-label="{{'common.yes' | translate}}" off-label="{{'common.no' | translate}}" class="switch-primary userstatus {{user ? '' : 'no-animation'}}" data-off-color="danger"></toggle-switch> - </div> - </div> - <div class="form-group"> - <label for="password" class="col-sm-2 control-label">{{'users.password' | translate}}</label> - <div class="col-sm-10"> - <div ng-switch="user.user_type != 'LOCAL'"> - <button class="btn deleteuser-btn disabled btn-default" ng-switch-when="true" tooltip="{{'users.alerts.cannotChange' | translate: '{term: constants.password}'}}">{{'users.changePassword' | translate}}</button> - <a href ng-click="openChangePwdDialog()" ng-switch-when="false" class="btn btn-default changepassword">{{'users.changePassword' | translate}}</a> - </div> - - </div> - </div> - <div class="form-group"> - <label for="groups" class="col-sm-2 control-label">{{getUserMembership(user.user_type)}}</label> - <div class="col-sm-10"> - <editable-list items-source="editingGroupsList" resource-type="Group" editable="user.user_type == 'LOCAL'"></editable-list> - </div> - - </div> - <div class="form-group" > - <label for="" class="col-sm-2 control-label">{{'common.privileges' | translate}}</label> - <div class="col-sm-10"> - <table class="table" ng-hide="hidePrivileges || user.admin"> - <thead> - <tr> - <th>{{'common.cluster' | translate}}</th> - <th>{{'common.clusterRole' | translate}}</th> - </tr> - </thead> - <tbody> - <tr ng-repeat="(name, privilege) in privileges.clusters"> - <td> - <span class="glyphicon glyphicon-cloud"></span> - <a href="#/clusters/{{name}}/manageAccess">{{name}}</a> - </td> - <td> - <span tooltip="{{privilege.permission_label}}">{{privilege.permission_label}}</span> - </td> - </tr> - <tr> - <td ng-show="noClusterPriv">{{'common.alerts.noPrivileges' | translate: '{term: constants.cluster}'}}</td> - </tr> - </tbody> - <thead class="view-permission-header"> - <tr> - <th>{{'common.view' | translate}}</th> - <th>{{'common.viewPermissions' | translate}}</th> - </tr> - </thead> - <tbody> - <tr ng-repeat="(name, privilege) in privileges.views"> - <td> - <span class="glyphicon glyphicon-th"></span> - <a href="#/views/{{privilege.view_name}}/versions/{{privilege.version}}/instances/{{name}}/edit">{{name}}</a> - </td> - <td> - <span tooltip="{{item}}" ng-repeat="item in privilege.privileges track by $index">{{item | translate}}{{$last ? '' : ', '}}</span> - </td> - <td> - <i class="fa fa-trash-o" aria-hidden="true" ng-click="removePrivilege(name, privilege);"></i> - </td> - </tr> - <tr> - <td ng-show="noViewPriv">{{'common.alerts.noPrivileges' | translate: '{term: constants.view}'}}</td> - </tr> - </tbody> - </table> - <div class="alert alert-info" ng-show="!privileges && !user.admin">{{'common.alerts.noPrivilegesDescription' | translate: '{term: constants.user}'}}</div> - <div class="alert alert-info" ng-show="user.admin">{{'users.userIsAdmin' | translate}}</div> - </div> - </div> - </form> -</div> http://git-wip-us.apache.org/repos/asf/ambari/blob/e83bf1bd/ambari-admin/src/main/resources/ui/admin-web/bower.json ---------------------------------------------------------------------- diff --git a/ambari-admin/src/main/resources/ui/admin-web/bower.json b/ambari-admin/src/main/resources/ui/admin-web/bower.json index dbdf005..c38f464 100644 --- a/ambari-admin/src/main/resources/ui/admin-web/bower.json +++ b/ambari-admin/src/main/resources/ui/admin-web/bower.json @@ -2,7 +2,7 @@ "name": "adminconsole", "private": true, "dependencies": { - "bootstrap": "3.1.1", + "bootstrap": "3.3.7", "angular": "1.2.26", "angular-route": "1.2.26", "angular-bootstrap": "0.11.0", http://git-wip-us.apache.org/repos/asf/ambari/blob/e83bf1bd/ambari-admin/src/main/resources/ui/admin-web/gulpfile.js ---------------------------------------------------------------------- diff --git a/ambari-admin/src/main/resources/ui/admin-web/gulpfile.js b/ambari-admin/src/main/resources/ui/admin-web/gulpfile.js index 2f47b85..9b377d1 100644 --- a/ambari-admin/src/main/resources/ui/admin-web/gulpfile.js +++ b/ambari-admin/src/main/resources/ui/admin-web/gulpfile.js @@ -24,10 +24,10 @@ var gulp = require('gulp'); var $ = require('gulp-load-plugins')(); gulp.task('styles', function () { - return gulp.src('app/styles/*.css') + return gulp.src('app/styles/**/*.css') .pipe($.order([ - 'app/styles/main.css', - 'app/styles/custom-admin-ui.css' // This should always be the last stylesheet. So it can be dropped and be effective on build time + 'app/styles/theme/bootstrap-ambari.css', + 'app/styles/main.css' ], { base: './' })) .pipe($.concat('main.css')) .pipe($.autoprefixer('last 1 version')) @@ -64,8 +64,8 @@ gulp.task('images', function () { }); gulp.task('fonts', function () { - return $.bowerFiles() - .pipe($.filter('**/*.{eot,svg,ttf,woff}')) + return gulp.src('app/bower_components/**/fonts/*.{eot,svg,ttf,woff}') + .pipe($.addSrc('app/assets/fonts/*')) .pipe($.flatten()) .pipe(gulp.dest('dist/fonts')) .pipe($.size()); http://git-wip-us.apache.org/repos/asf/ambari/blob/e83bf1bd/ambari-admin/src/main/resources/ui/admin-web/package.json ---------------------------------------------------------------------- diff --git a/ambari-admin/src/main/resources/ui/admin-web/package.json b/ambari-admin/src/main/resources/ui/admin-web/package.json index efcd9d4..b7c514c 100644 --- a/ambari-admin/src/main/resources/ui/admin-web/package.json +++ b/ambari-admin/src/main/resources/ui/admin-web/package.json @@ -5,19 +5,19 @@ "devDependencies": { "bower": "1.3.8", "gulp": "^3.8.8", + "gulp-add-src": "^0.2.0", "gulp-autoprefixer": "0.0.7", - "gulp-bower-files": "0.2.1", "gulp-cache": "0.1.1", "gulp-clean": "0.2.4", + "gulp-concat": "2.6.0", "gulp-filter": "0.4.1", "gulp-flatten": "0.0.2", "gulp-load-plugins": "0.5.0", + "gulp-order": "1.1.1", "gulp-plumber": "0.6.6", "gulp-size": "0.3.0", "gulp-uglify": "0.2.1", "gulp-useref": "0.4.2", - "gulp-concat": "2.6.0", - "gulp-order": "1.1.1", "http-server": "0.6.1", "karma": "0.12.16", "karma-chrome-launcher": "0.1.4", http://git-wip-us.apache.org/repos/asf/ambari/blob/e83bf1bd/ambari-admin/src/main/resources/ui/admin-web/test/unit/controllers/AppCtrl_test.js ---------------------------------------------------------------------- diff --git a/ambari-admin/src/main/resources/ui/admin-web/test/unit/controllers/AppCtrl_test.js b/ambari-admin/src/main/resources/ui/admin-web/test/unit/controllers/AppCtrl_test.js new file mode 100644 index 0000000..1bbe47a --- /dev/null +++ b/ambari-admin/src/main/resources/ui/admin-web/test/unit/controllers/AppCtrl_test.js @@ -0,0 +1,211 @@ +/** + * 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. + */ + +describe('#AppCtrl', function () { + + var scope, ctrl, $httpBackend, $window, clusterService, deferred; + + beforeEach(function () { + module('ambariAdminConsole', function ($provide) { + $provide.value('$route', { + current: null + }); + $provide.value('$window', { + location: { + pathname: 'http://c6401.ambari.apache.org:8080/views/ADMIN_VIEW/2.0.0/INSTANCE/#/' + }, + localStorage: { + getItem: function () { + return null; + }, + setItem: angular.noop + } + }); + localStorage.ambari = JSON.stringify({ + app: { + authenticated: true, + loginName: 'admin', + user: 'user' + } + }); + }); + inject(function (_$httpBackend_, $rootScope, $controller, _$window_, _Cluster_, _$q_) { + clusterService = _Cluster_; + deferred = _$q_.defer(); + spyOn(clusterService, 'getStatus').andReturn(deferred.promise); + deferred.resolve({ + Clusters: { + provisioning_state: 'INIT' + } + }); + $window = _$window_; + $httpBackend = _$httpBackend_; + $httpBackend.whenGET(/api\/v1\/services\/AMBARI\/components\/AMBARI_SERVER.+/).respond(200, { + RootServiceComponents: { + component_version: 2.2, + properties: { + 'user.inactivity.timeout.default': 20 + } + } + }); + $httpBackend.whenGET(/\/api\/v1\/views.+/).respond(200, { + "href": "http://c6401.ambari.apache.org:8080/api/v1/views?fields=versions/instances/ViewInstanceInfo&versions/ViewVersionInfo/system=false&versions/instances/ViewInstanceInfo/visible=true", + "items": [ + { + "ViewInfo": { + "view_name": "SLIDER" + }, + "href": "http://c6401.ambari.apache.org:8080/api/v1/views/SLIDER", + "versions": [ + { + "ViewVersionInfo": { + "system": false, + "version": "1.0.0", + "view_name": "SLIDER" + }, + "href": "http://c6401.ambari.apache.org:8080/api/v1/views/SLIDER/versions/1.0.0", + "instances": [ + { + "ViewInstanceInfo": { + "context_path": "/views/SLIDER/1.0.0/VisibleInstance", + "description": "VisibleInstance", + "icon64_path": null, + "icon_path": null, + "instance_data": {}, + "instance_name": "VisibleInstance", + "label": "VisibleInstance", + "properties": { + "ambari.server.password": "123", + "ambari.server.url": "123", + "ambari.server.username": "123", + "slider.user": null, + "view.kerberos.principal": null, + "view.kerberos.principal.keytab": null + }, + "static": false, + "version": "1.0.0", + "view_name": "SLIDER", + "visible": true + }, + "href": "http://c6401.ambari.apache.org:8080/api/v1/views/SLIDER/versions/1.0.0/instances/VisibleInstance" + } + ] + } + ] + } + ] + }); + $httpBackend.whenGET(/\/persist\/user-pref-.*/).respond(200, { + data: { + data: { + addingNewRepository: true + } + } + }); + scope = $rootScope.$new(); + scope.$apply(); + ctrl = $controller('AppCtrl', { + $scope: scope + }); + }); + }); + + afterEach(function() { + $httpBackend.verifyNoOutstandingExpectation(); + $httpBackend.verifyNoOutstandingRequest(); + }); + + describe('signout', function () { + + beforeEach(function () { + $httpBackend.whenGET(/\/api\/v1\/logout\?_=\d+/).respond(200,{ + message: "successfully logged out" + }); + $httpBackend.whenGET(/\/api\/v1\/users\/admin\/authorizations.*/).respond(200, { + items: [ + { + AuthorizationInfo: { + authorization_id: "AMBARI.RENAME_CLUSTER" + } + } + ] + }); + }); + + it('should reset window.location and ambari localstorage', function () { + scope.signOut(); + + runs(function() { + chai.expect($window.location.pathname).to.equal('/'); + }); + + var data = JSON.parse(localStorage.ambari); + chai.expect(data.app.authenticated).to.equal(undefined); + chai.expect(data.app.loginName).to.equal(undefined); + chai.expect(data.app.user).to.equal(undefined); + $httpBackend.flush(); + }); + }); + + describe('roles loading', function () { + + var mock = { + callback: angular.noop + }, + cases = [ + { + canPersistData: true, + items: [ + { + AuthorizationInfo: { + authorization_id: 'CLUSTER.MANAGE_USER_PERSISTED_DATA' + } + } + ], + title: 'user can persist data' + }, + { + canPersistData: false, + items: [], + title: 'user can\'t persist data' + } + ]; + + angular.forEach(cases, function (item) { + + describe(item.title, function () { + + beforeEach(function () { + $httpBackend.whenGET(/\/api\/v1\/users\/admin\/authorizations.*/).respond(200, { + items: item.items + }); + spyOn(mock, 'callback'); + scope.authDataLoad.promise.then(mock.callback); + $httpBackend.flush(); + }); + + it('authDataLoad should be resolved with the correct argument', function () { + expect(mock.callback).toHaveBeenCalledWith(item.canPersistData); + }); + + }); + + }); + + }); +}); http://git-wip-us.apache.org/repos/asf/ambari/blob/e83bf1bd/ambari-admin/src/main/resources/ui/admin-web/test/unit/controllers/ClusterInformationCtrl_test.js ---------------------------------------------------------------------- diff --git a/ambari-admin/src/main/resources/ui/admin-web/test/unit/controllers/ClusterInformationCtrl_test.js b/ambari-admin/src/main/resources/ui/admin-web/test/unit/controllers/ClusterInformationCtrl_test.js new file mode 100644 index 0000000..2972e7f --- /dev/null +++ b/ambari-admin/src/main/resources/ui/admin-web/test/unit/controllers/ClusterInformationCtrl_test.js @@ -0,0 +1,102 @@ +/** + * 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. + */ + +describe('ClusterInformationCtrl', function() { + beforeEach(module('ambariAdminConsole')); + + var ctrl, $scope, Cluster, deferred, ConfirmationModal; + + beforeEach(inject(function($controller, $rootScope, _Cluster_, _$q_, _ConfirmationModal_){ + // The injector unwraps the underscores (_) from around the parameter names when matching + Cluster = _Cluster_; + ConfirmationModal = _ConfirmationModal_; + deferred = _$q_.defer(); + $scope = $rootScope.$new(); + $scope.$apply(); + ctrl = $controller('ClusterInformationCtrl', { + $scope: $scope + }); + + spyOn(Cluster, 'getBlueprint').andReturn(deferred.promise); + spyOn(Cluster, 'editName').andReturn(deferred.promise); + spyOn(ConfirmationModal, 'show').andReturn(deferred.promise); + })); + + describe('#getBlueprint', function() { + it('Cluster.getBlueprint should be called', function() { + $scope.cluster = { + Clusters: { + cluster_name: 'c1' + } + }; + $scope.getBlueprint(); + expect(Cluster.getBlueprint).toHaveBeenCalled(); + }); + }); + + describe('#toggleSaveButton', function() { + beforeEach(function() { + $scope.cluster = { + Clusters: { + cluster_name: 'c1' + } + }; + }); + + it('isClusterNameEdited should be true', function() { + $scope.edit = { + clusterName: 'c2' + }; + $scope.toggleSaveButton(); + expect($scope.isClusterNameEdited).toBeTruthy(); + }); + + it('isClusterNameEdited should be false', function() { + $scope.edit = { + clusterName: 'c1' + }; + $scope.toggleSaveButton(); + expect($scope.isClusterNameEdited).toBeFalsy(); + }); + }); + + describe('#confirmClusterNameChange', function() { + it('ConfirmationModal.show should be called', function() { + $scope.edit = { + clusterName: 'c1' + }; + $scope.confirmClusterNameChange(); + expect(ConfirmationModal.show).toHaveBeenCalled(); + }); + }); + + describe('#saveClusterName', function() { + it('Cluster.editName should be called', function() { + $scope.edit = { + clusterName: 'c1' + }; + $scope.cluster = { + Clusters: { + cluster_name: 'c2' + } + }; + $scope.saveClusterName(); + expect(Cluster.editName).toHaveBeenCalledWith('c2', 'c1'); + }); + }); +});
