Redo user admin page to match the style of the org admin page
This commit is contained in:
parent
dba806fd97
commit
10db2884ac
7 changed files with 91 additions and 176 deletions
|
@ -1369,22 +1369,30 @@ p.editable:hover i {
|
||||||
font-size: 22px;
|
font-size: 22px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#repository-usage-chart path.warning-0 {
|
#repository-usage-chart.limit-at path.arc-0 {
|
||||||
fill: #c09853;
|
fill: #c09853;
|
||||||
}
|
}
|
||||||
|
|
||||||
#repository-usage-chart path.error-0 {
|
#repository-usage-chart.limit-over path.arc-0 {
|
||||||
fill: #b94a48;
|
fill: #b94a48;
|
||||||
}
|
}
|
||||||
|
|
||||||
#repository-usage-chart path.warning-1 {
|
#repository-usage-chart.limit-near path.arc-0 {
|
||||||
|
fill: #468847;
|
||||||
|
}
|
||||||
|
|
||||||
|
#repository-usage-chart.limit-over path.arc-1 {
|
||||||
fill: #fcf8e3;
|
fill: #fcf8e3;
|
||||||
}
|
}
|
||||||
|
|
||||||
#repository-usage-chart path.error-1 {
|
#repository-usage-chart.limit-at path.arc-1 {
|
||||||
fill: #f2dede;
|
fill: #f2dede;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#repository-usage-chart.limit-near path.arc-1 {
|
||||||
|
fill: #dff0d8;
|
||||||
|
}
|
||||||
|
|
||||||
.plan-manager-element .usage-caption {
|
.plan-manager-element .usage-caption {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
color: #aaa;
|
color: #aaa;
|
||||||
|
@ -1525,22 +1533,22 @@ p.editable:hover i {
|
||||||
padding: 6px;
|
padding: 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.org-admin .plans-table thead td {
|
.plan-manager-element .plans-table thead td {
|
||||||
color: #aaa;
|
color: #aaa;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
.org-admin .plans-table td {
|
.plan-manager-element .plans-table td {
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
}
|
}
|
||||||
|
|
||||||
.org-admin .plans-table td.controls {
|
.plan-manager-element .plans-table td.controls {
|
||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
.org-admin .plans-table .plan-price {
|
.plan-manager-element .plans-table .plan-price {
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
margin-bottom: 0px;
|
margin-bottom: 0px;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,19 +3,23 @@
|
||||||
<i class="fa fa-spinner fa-spin fa-3x" ng-show="planLoading"></i>
|
<i class="fa fa-spinner fa-spin fa-3x" ng-show="planLoading"></i>
|
||||||
|
|
||||||
<!-- Alerts -->
|
<!-- Alerts -->
|
||||||
<div class="alert alert-danger" ng-show="overLimit && !planLoading">
|
<div class="alert alert-danger" ng-show="limit == 'over' && !planLoading">
|
||||||
You are using more private repositories than your plan allows, please
|
You are using more private repositories than your plan allows. Please
|
||||||
upgrade your subscription to avoid disruptions in your organization's service.
|
upgrade your subscription to avoid disruptions in your <span ng-show="organization">organization's</span> service.
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="alert alert-warning" ng-show="nearLimit && !planLoading">
|
<div class="alert alert-warning" ng-show="limit == 'at' && !planLoading">
|
||||||
|
You are at your current plan's number of allowed private repositories. Please upgrade your subscription to avoid future disruptions in your <span ng-show="organization">organization's</span> service.
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="alert alert-success" ng-show="limit == 'near' && !planLoading">
|
||||||
You are nearing the number of allowed private repositories. It might be time to think about
|
You are nearing the number of allowed private repositories. It might be time to think about
|
||||||
upgrading your subscription to avoid future disruptions in your organization's service.
|
upgrading your subscription to avoid future disruptions in your <span ng-show="organization">organization's</span> service.
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Chart -->
|
<!-- Chart -->
|
||||||
<div>
|
<div>
|
||||||
<div id="repository-usage-chart"></div>
|
<div id="repository-usage-chart" class="limit-{{limit}}"></div>
|
||||||
<span class="usage-caption" ng-show="chart">Repository Usage</span>
|
<span class="usage-caption" ng-show="chart">Repository Usage</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -557,12 +557,13 @@ quayApp.directive('planManager', function () {
|
||||||
$scope.planUsagePercent = sub.usedPrivateRepos * 100 / $scope.subscribedPlan.privateRepos;
|
$scope.planUsagePercent = sub.usedPrivateRepos * 100 / $scope.subscribedPlan.privateRepos;
|
||||||
|
|
||||||
if (sub.usedPrivateRepos > $scope.subscribedPlan.privateRepos) {
|
if (sub.usedPrivateRepos > $scope.subscribedPlan.privateRepos) {
|
||||||
$scope.overLimit = true;
|
$scope.limit = 'over';
|
||||||
|
} else if (sub.usedPrivateRepos == $scope.subscribedPlan.privateRepos) {
|
||||||
|
$scope.limit = 'at';
|
||||||
} else if (sub.usedPrivateRepos >= $scope.subscribedPlan.privateRepos * 0.7) {
|
} else if (sub.usedPrivateRepos >= $scope.subscribedPlan.privateRepos * 0.7) {
|
||||||
$scope.nearLimit = true;
|
$scope.limit = 'near';
|
||||||
} else {
|
} else {
|
||||||
$scope.overLimit = false;
|
$scope.limit = 'none';
|
||||||
$scope.nearLimit = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$scope.chart) {
|
if (!$scope.chart) {
|
||||||
|
@ -588,9 +589,7 @@ quayApp.directive('planManager', function () {
|
||||||
|
|
||||||
var update = function() {
|
var update = function() {
|
||||||
$scope.planLoading = true;
|
$scope.planLoading = true;
|
||||||
|
|
||||||
if (!$scope.plans) { return; }
|
if (!$scope.plans) { return; }
|
||||||
if (!$scope.user && !$scope.organization) { return; }
|
|
||||||
|
|
||||||
PlanService.getSubscription($scope.organization, subscribedToPlan, function() {
|
PlanService.getSubscription($scope.organization, subscribedToPlan, function() {
|
||||||
// User/Organization has no subscription.
|
// User/Organization has no subscription.
|
||||||
|
@ -599,6 +598,7 @@ quayApp.directive('planManager', function () {
|
||||||
};
|
};
|
||||||
|
|
||||||
var loadPlans = function() {
|
var loadPlans = function() {
|
||||||
|
if (!$scope.user && !$scope.organization) { return; }
|
||||||
PlanService.getPlans(function(plans) {
|
PlanService.getPlans(function(plans) {
|
||||||
$scope.plans = plans[$scope.organization ? 'business' : 'user'];
|
$scope.plans = plans[$scope.organization ? 'business' : 'user'];
|
||||||
update();
|
update();
|
||||||
|
@ -606,15 +606,15 @@ quayApp.directive('planManager', function () {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Start the initial download.
|
// Start the initial download.
|
||||||
|
$scope.planLoading = true;
|
||||||
loadPlans();
|
loadPlans();
|
||||||
update();
|
|
||||||
|
|
||||||
$scope.$watch('organization', function() {
|
$scope.$watch('organization', function() {
|
||||||
update();
|
loadPlans();
|
||||||
});
|
});
|
||||||
|
|
||||||
$scope.$watch('user', function() {
|
$scope.$watch('user', function() {
|
||||||
update();
|
loadPlans();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -667,91 +667,24 @@ function RepoAdminCtrl($scope, Restangular, $routeParams, $rootScope) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function UserAdminCtrl($scope, $timeout, Restangular, PlanService, UserService, KeyService, $routeParams) {
|
function UserAdminCtrl($scope, $timeout, Restangular, PlanService, UserService, KeyService, $routeParams) {
|
||||||
// Load the list of plans.
|
|
||||||
PlanService.getPlans(function(plans) {
|
|
||||||
$scope.plans = plans.user;
|
|
||||||
});
|
|
||||||
|
|
||||||
$scope.$watch(function () { return UserService.currentUser(); }, function (currentUser) {
|
$scope.$watch(function () { return UserService.currentUser(); }, function (currentUser) {
|
||||||
$scope.askForPassword = currentUser.askForPassword;
|
$scope.askForPassword = currentUser.askForPassword;
|
||||||
}, true);
|
if (!currentUser.anonymous) {
|
||||||
|
$scope.user = currentUser;
|
||||||
var subscribedToPlan = function(sub) {
|
|
||||||
$scope.subscription = sub;
|
|
||||||
PlanService.getPlan(sub.plan, function(subscribedPlan) {
|
|
||||||
$scope.subscribedPlan = subscribedPlan;
|
|
||||||
$scope.planUsagePercent = sub.usedPrivateRepos * 100 / $scope.subscribedPlan.privateRepos;
|
|
||||||
|
|
||||||
if (sub.usedPrivateRepos > $scope.subscribedPlan.privateRepos) {
|
|
||||||
$scope.errorMessage = 'You are using more private repositories than your plan allows, please upgrade your subscription to avoid disruptions in your service.';
|
|
||||||
} else {
|
|
||||||
$scope.errorMessage = null;
|
|
||||||
}
|
}
|
||||||
|
$scope.loading = false;
|
||||||
$scope.planLoading = false;
|
}, true);
|
||||||
$scope.planChanging = false;
|
|
||||||
|
|
||||||
mixpanel.people.set({
|
|
||||||
'plan': sub.plan
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
$scope.planLoading = true;
|
|
||||||
UserService.getCurrentSubscription(subscribedToPlan, function() {
|
|
||||||
// User has no subscription
|
|
||||||
$scope.planChanging = false;
|
|
||||||
});
|
|
||||||
|
|
||||||
$scope.planChanging = false;
|
|
||||||
$scope.subscribe = function(planId) {
|
|
||||||
PlanService.showSubscribeDialog($scope, planId, null, function() {
|
|
||||||
// Subscribing.
|
|
||||||
$scope.planChanging = true;
|
|
||||||
}, function(plan) {
|
|
||||||
// Subscribed.
|
|
||||||
UserService.resetCurrentSubscription();
|
|
||||||
subscribedToPlan(plan);
|
|
||||||
}, function() {
|
|
||||||
// Failure.
|
|
||||||
$scope.errorMessage = 'Unable to subscribe.';
|
|
||||||
$scope.planChanging = false;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
$scope.changeSubscription = function(planId) {
|
|
||||||
$scope.planChanging = true;
|
|
||||||
$scope.errorMessage = undefined;
|
|
||||||
|
|
||||||
var subscriptionDetails = {
|
|
||||||
plan: planId,
|
|
||||||
};
|
|
||||||
|
|
||||||
UserService.resetCurrentSubscription();
|
|
||||||
var changeSubscriptionRequest = Restangular.one('user/plan');
|
|
||||||
changeSubscriptionRequest.customPUT(subscriptionDetails).then(subscribedToPlan, function() {
|
|
||||||
// Failure
|
|
||||||
$scope.errorMessage = 'Unable to change subscription.';
|
|
||||||
$scope.planChanging = false;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
$scope.cancelSubscription = function() {
|
|
||||||
$scope.changeSubscription('free');
|
|
||||||
};
|
|
||||||
|
|
||||||
// Show the subscribe dialog if a plan was requested.
|
// Show the subscribe dialog if a plan was requested.
|
||||||
var requested = $routeParams['plan']
|
var requested = $routeParams['plan']
|
||||||
if (requested !== undefined && requested !== 'free') {
|
if (requested !== undefined && requested !== 'free') {
|
||||||
PlanService.getPlan(requested, function(found) {
|
// TODO: this.
|
||||||
if (found) {
|
|
||||||
$scope.subscribe(requested);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$scope.loading = true;
|
||||||
$scope.updatingUser = false;
|
$scope.updatingUser = false;
|
||||||
$scope.changePasswordSuccess = false;
|
$scope.changePasswordSuccess = false;
|
||||||
|
|
||||||
$('.form-change-pw').popover();
|
$('.form-change-pw').popover();
|
||||||
|
|
||||||
$scope.changePassword = function() {
|
$scope.changePassword = function() {
|
||||||
|
@ -768,6 +701,7 @@ function UserAdminCtrl($scope, $timeout, Restangular, PlanService, UserService,
|
||||||
$scope.user.repeatPassword = '';
|
$scope.user.repeatPassword = '';
|
||||||
$scope.changePasswordForm.$setPristine();
|
$scope.changePasswordForm.$setPristine();
|
||||||
|
|
||||||
|
// Reload the user.
|
||||||
UserService.load();
|
UserService.load();
|
||||||
}, function(result) {
|
}, function(result) {
|
||||||
$scope.updatingUser = false;
|
$scope.updatingUser = false;
|
||||||
|
@ -1176,6 +1110,7 @@ function OrgAdminCtrl($rootScope, $scope, Restangular, $routeParams, UserService
|
||||||
});
|
});
|
||||||
|
|
||||||
var orgname = $routeParams.orgname;
|
var orgname = $routeParams.orgname;
|
||||||
|
$scope.orgname = orgname;
|
||||||
|
|
||||||
var loadOrganization = function() {
|
var loadOrganization = function() {
|
||||||
var getOrganization = Restangular.one(getRestUrl('organization', orgname));
|
var getOrganization = Restangular.one(getRestUrl('organization', orgname));
|
||||||
|
|
|
@ -1175,18 +1175,6 @@ RepositoryUsageChart.prototype.drawInternal_ = function() {
|
||||||
|
|
||||||
var data = [count, Math.max(0, total - count)];
|
var data = [count, Math.max(0, total - count)];
|
||||||
|
|
||||||
var getClass = function(i) {
|
|
||||||
if (total > 0 && (count / total) >= 0.7) {
|
|
||||||
return 'warning-' + i;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (count >= total) {
|
|
||||||
return 'error-' + i;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 'normal';
|
|
||||||
};
|
|
||||||
|
|
||||||
var arcTween = function(a) {
|
var arcTween = function(a) {
|
||||||
var i = d3.interpolate(this._current, a);
|
var i = d3.interpolate(this._current, a);
|
||||||
this._current = i(0);
|
this._current = i(0);
|
||||||
|
@ -1208,7 +1196,7 @@ RepositoryUsageChart.prototype.drawInternal_ = function() {
|
||||||
.data(pie)
|
.data(pie)
|
||||||
.enter().append("path")
|
.enter().append("path")
|
||||||
.attr("fill", function(d, i) { return color(i); })
|
.attr("fill", function(d, i) { return color(i); })
|
||||||
.attr("class", function(d, i) { return getClass(i); })
|
.attr("class", function(d, i) { return 'arc-' + i; })
|
||||||
.attr("d", arc)
|
.attr("d", arc)
|
||||||
.each(function(d) { this._current = d; }); // store the initial angles
|
.each(function(d) { this._current = d; }); // store the initial angles
|
||||||
|
|
||||||
|
@ -1217,9 +1205,7 @@ RepositoryUsageChart.prototype.drawInternal_ = function() {
|
||||||
} else {
|
} else {
|
||||||
pie.value(function(d, i) { return data[i]; }); // change the value function
|
pie.value(function(d, i) { return data[i]; }); // change the value function
|
||||||
this.path_ = this.path_.data(pie); // compute the new angles
|
this.path_ = this.path_.data(pie); // compute the new angles
|
||||||
|
|
||||||
this.path_.transition().duration(duration).attrTween("d", arcTween); // redraw the arcs
|
this.path_.transition().duration(duration).attrTween("d", arcTween); // redraw the arcs
|
||||||
this.path_.attr("class", function(d, i) { return getClass(i); });
|
|
||||||
|
|
||||||
// Update the text.
|
// Update the text.
|
||||||
this.text_.text(this.count_ + ' / ' + this.total_);
|
this.text_.text(this.count_ + ' / ' + this.total_);
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
<div class="tab-content">
|
<div class="tab-content">
|
||||||
<!-- Plans tab -->
|
<!-- Plans tab -->
|
||||||
<div id="plan" class="tab-pane active">
|
<div id="plan" class="tab-pane active">
|
||||||
<div class="plan-manager" organization="organization.name"></div>
|
<div class="plan-manager" organization="orgname"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Members tab -->
|
<!-- Members tab -->
|
||||||
|
|
|
@ -1,80 +1,62 @@
|
||||||
<div class="container user-admin">
|
<div class="loading" ng-show="loading">
|
||||||
<div class="loading" ng-show="planLoading || planChanging">
|
|
||||||
<i class="fa fa-spinner fa-spin fa-3x"></i>
|
<i class="fa fa-spinner fa-spin fa-3x"></i>
|
||||||
</div>
|
</div>
|
||||||
<div class="row" ng-show="errorMessage">
|
|
||||||
<div class="col-md-12">
|
<div class="loading" ng-show="!loading && !user">
|
||||||
<div class="alert alert-danger">{{ errorMessage }}</div>
|
No matching user found
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="user-admin container" ng-show="!loading && user">
|
||||||
|
<div class="row">
|
||||||
|
<div class="organization-header-element">
|
||||||
|
<img src="//www.gravatar.com/avatar/{{ user.gravatar }}?s=24&d=identicon">
|
||||||
|
<span class="organization-name">
|
||||||
|
{{ user.username }}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row" ng-show="askForPassword">
|
<div class="row" ng-show="askForPassword">
|
||||||
<div class="col-md-12">
|
<div class="col-md-12">
|
||||||
<div class="alert alert-warning">Your account does not currently have a password. You will need to create a password before you will be able to <strong>push</strong> or <strong>pull</strong> repositories.</div>
|
<div class="alert alert-warning">Your account does not currently have a password. You will need to create a password before you will be able to <strong>push</strong> or <strong>pull</strong> repositories.</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row" ng-hide="planLoading">
|
|
||||||
<div class="col-md-3" ng-repeat='plan in plans'>
|
|
||||||
<div class="panel" ng-class="{'panel-success': subscription.plan == plan.stripeId, 'panel-default': subscription.plan != plan.stripeId}">
|
|
||||||
<div class="panel-heading">
|
|
||||||
{{ plan.title }}
|
|
||||||
<span class="pull-right" ng-show="subscription.plan == plan.stripeId">
|
|
||||||
<i class="fa fa-ok"></i>
|
|
||||||
Subscribed
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div class="panel-body panel-plan">
|
|
||||||
<div class="plan-price">${{ plan.price / 100 }}</div>
|
|
||||||
<div class="plan-description"><b>{{ plan.privateRepos }}</b> Private Repositories</div>
|
|
||||||
<div ng-switch='plan.stripeId'>
|
|
||||||
<div ng-switch-when='free'>
|
|
||||||
<button class="btn button-hidden">Hidden!</button>
|
|
||||||
</div>
|
|
||||||
<div ng-switch-default>
|
|
||||||
<button class="btn btn-primary" ng-show="subscription.plan === 'free'" ng-click="subscribe(plan.stripeId)">Subscribe</button>
|
|
||||||
<button class="btn btn-default" ng-hide="subscription.plan === 'free' || subscription.plan === plan.stripeId" ng-click="changeSubscription(plan.stripeId)">Change</button>
|
|
||||||
<button class="btn btn-danger" ng-show="subscription.plan === plan.stripeId" ng-click="cancelSubscription()">Cancel</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row" ng-show="subscription">
|
|
||||||
<div class="col-md-6">
|
|
||||||
<div class="panel panel-default">
|
|
||||||
<div class="panel-heading">
|
|
||||||
Plan Usage
|
|
||||||
</div>
|
|
||||||
<div class="panel-body">
|
|
||||||
<div class="used-description">
|
|
||||||
<b>{{ subscription.usedPrivateRepos }}</b> of <b>{{ subscribedPlan.privateRepos }}</b> private repositories used
|
|
||||||
</div>
|
|
||||||
<div class="progress">
|
|
||||||
<div ng-class="'progress-bar ' + (planUsagePercent > 90 ? 'progress-bar-danger' : '')" role="progressbar" aria-valuenow="{{ subscription.usedPrivateRepos }}" aria-valuemin="0" aria-valuemax="{{ subscribedPlan.privateRepos }}" style="width: {{ planUsagePercent }}%;">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
<!-- Side tabs -->
|
||||||
|
<div class="col-md-2">
|
||||||
|
<ul class="nav nav-pills nav-stacked">
|
||||||
|
<li class="active"><a href="javascript:void(0)" data-toggle="tab" data-target="#plan">Plan and Usage</a></li>
|
||||||
|
<li><a href="javascript:void(0)" data-toggle="tab" data-target="#password">Set Password</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Content -->
|
||||||
|
<div class="col-md-10">
|
||||||
|
<div class="tab-content">
|
||||||
|
<!-- Plans tab -->
|
||||||
|
<div id="plan" class="tab-pane active">
|
||||||
|
<div class="plan-manager" user="user.username"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Change password tab -->
|
||||||
|
<div id="password" class="tab-pane">
|
||||||
<div class="loading" ng-show="updatingUser">
|
<div class="loading" ng-show="updatingUser">
|
||||||
<i class="fa fa-spinner fa-spin fa-3x"></i>
|
<i class="fa fa-spinner fa-spin fa-3x"></i>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-3">
|
|
||||||
<div class="panel panel-default">
|
<form class="form-change-pw" name="changePasswordForm" ng-submit="changePassword()" data-trigger="manual"
|
||||||
<div class="panel-heading">
|
data-content="{{ changePasswordError }}" data-placement="right" ng-show="!awaitingConfirmation && !registering">
|
||||||
Change Password
|
|
||||||
</div>
|
|
||||||
<div class="panel-body">
|
|
||||||
<form class="form-change-pw" name="changePasswordForm" ng-submit="changePassword()" data-trigger="manual" data-content="{{ changePasswordError }}" data-placement="right" ng-show="!awaitingConfirmation && !registering">
|
|
||||||
<input type="password" class="form-control" placeholder="Your new password" ng-model="user.password" required>
|
<input type="password" class="form-control" placeholder="Your new password" ng-model="user.password" required>
|
||||||
<input type="password" class="form-control" placeholder="Verify your new password" ng-model="user.repeatPassword" match="user.password" required>
|
<input type="password" class="form-control" placeholder="Verify your new password" ng-model="user.repeatPassword"
|
||||||
<button class="btn btn-danger" ng-disabled="changePasswordForm.$invalid" type="submit" analytics-on analytics-event="register">Change Password</button>
|
match="user.password" required>
|
||||||
|
<button class="btn btn-danger" ng-disabled="changePasswordForm.$invalid" type="submit"
|
||||||
|
analytics-on analytics-event="register">Change Password</button>
|
||||||
<span class="help-block" ng-show="changePasswordSuccess">Password changed successfully</span>
|
<span class="help-block" ng-show="changePasswordSuccess">Password changed successfully</span>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
Reference in a new issue