bulk actions with move and delete
This commit is contained in:
parent
c094a26cbf
commit
f170157817
|
@ -38,7 +38,9 @@
|
|||
putCollections: { url: _apiUri + '/ciphers/:id/collections', method: 'POST', params: { id: '@id' } },
|
||||
putCollectionsAdmin: { url: _apiUri + '/ciphers/:id/collections-admin', method: 'POST', params: { id: '@id' } },
|
||||
del: { url: _apiUri + '/ciphers/:id/delete', method: 'POST', params: { id: '@id' } },
|
||||
delAdmin: { url: _apiUri + '/ciphers/:id/delete-admin', method: 'POST', params: { id: '@id' } }
|
||||
delAdmin: { url: _apiUri + '/ciphers/:id/delete-admin', method: 'POST', params: { id: '@id' } },
|
||||
delMany: { url: _apiUri + '/ciphers/delete', method: 'POST' },
|
||||
moveMany: { url: _apiUri + '/ciphers/move', method: 'POST' }
|
||||
});
|
||||
|
||||
_service.organizations = $resource(_apiUri + '/organizations/:id', {}, {
|
||||
|
|
|
@ -312,6 +312,59 @@
|
|||
return $scope.folderIdFilter === undefined || folder.id === $scope.folderIdFilter;
|
||||
};
|
||||
|
||||
function distinct(value, index, self) {
|
||||
return self.indexOf(value) === index;
|
||||
}
|
||||
|
||||
function getSelectedLogins() {
|
||||
return $('input[name="loginSelection"]:checked').map(function () {
|
||||
return $(this).val();
|
||||
}).get().filter(distinct);
|
||||
}
|
||||
|
||||
function clearLoginSelections() {
|
||||
$('input[name="loginSelection"]').attr('checked', false);
|
||||
}
|
||||
|
||||
$scope.bulkMove = function () {
|
||||
var ids = getSelectedLogins();
|
||||
if (ids.length === 0) {
|
||||
alert('You have not selected anything.');
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO
|
||||
};
|
||||
|
||||
$scope.bulkDelete = function () {
|
||||
var ids = getSelectedLogins();
|
||||
if (ids.length === 0) {
|
||||
alert('You have not selected anything.');
|
||||
return;
|
||||
}
|
||||
|
||||
if (!confirm('Are you sure you want to delete the selected logins (total: ' + ids.length + ')?')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$scope.bulkActionLoading = true;
|
||||
apiService.ciphers.delMany({ ids: ids }, function () {
|
||||
$analytics.eventTrack('Bulk Deleted Logins');
|
||||
|
||||
for (var i = 0; i < ids.length; i++) {
|
||||
var login = $filter('filter')($rootScope.vaultLogins, { id: ids[i] });
|
||||
if (login.length && login[0].edit) {
|
||||
removeLoginFromScopes(login[0]);
|
||||
}
|
||||
}
|
||||
|
||||
clearLoginSelections();
|
||||
$scope.bulkActionLoading = false;
|
||||
}, function () {
|
||||
$scope.bulkActionLoading = false;
|
||||
});
|
||||
};
|
||||
|
||||
function removeLoginFromScopes(login) {
|
||||
var index = $rootScope.vaultLogins.indexOf(login);
|
||||
if (index > -1) {
|
||||
|
|
|
@ -1,4 +1,23 @@
|
|||
<section class="content-header">
|
||||
<div class="btn-group pull-right">
|
||||
<button type="button" class="btn btn-link dropdown-toggle" data-toggle="dropdown"
|
||||
ng-disabled="bulkActionLoading">
|
||||
<i class="fa fa-refresh fa-spin" ng-show="bulkActionLoading"></i>
|
||||
Bulk Actions <span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu">
|
||||
<li>
|
||||
<a href="#" stop-click ng-click="bulkMove()">
|
||||
<i class="fa fa-fw fa-share"></i> Move Selected
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#" stop-click ng-click="bulkDelete()">
|
||||
<i class="fa fa-fw fa-trash"></i> Delete Selected
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<h1>
|
||||
My Vault
|
||||
<small>
|
||||
|
@ -85,6 +104,9 @@
|
|||
</ul>
|
||||
</div>
|
||||
</td>
|
||||
<td class="action-select">
|
||||
<input type="checkbox" value="{{::login.id}}" name="loginSelection" />
|
||||
</td>
|
||||
<td>
|
||||
<a href="#" stop-click ng-click="editLogin(login)">{{login.name}}</a>
|
||||
<i class="fa fa-share-alt text-muted" title="Shared" ng-show="login.organizationId"></i>
|
||||
|
@ -179,6 +201,9 @@
|
|||
</ul>
|
||||
</div>
|
||||
</td>
|
||||
<td class="action-select">
|
||||
<input type="checkbox" value="{{::login.id}}" name="loginSelection" />
|
||||
</td>
|
||||
<td>
|
||||
<a href="#" stop-click ng-click="editLogin(login)">{{login.name}}</a>
|
||||
<i class="fa fa-star text-muted" title="Favorite" ng-show="login.favorite"></i>
|
||||
|
|
|
@ -228,8 +228,17 @@ form .btn .loading-icon {
|
|||
}
|
||||
}
|
||||
|
||||
/* Forms */
|
||||
.btn-link:active {
|
||||
.box-shadow(none);
|
||||
}
|
||||
|
||||
@media (max-width: @screen-sm-max) {
|
||||
.content-header .btn-group {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* Forms */
|
||||
.form-control {
|
||||
border-radius: 0 !important;
|
||||
}
|
||||
|
@ -331,8 +340,15 @@ form .btn .loading-icon {
|
|||
border-top: 0;
|
||||
}
|
||||
|
||||
/* Callouts */
|
||||
.table td.action-select {
|
||||
text-align: center;
|
||||
width: 30px;
|
||||
|
||||
@media (max-width: @screen-sm-max) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
/* Callouts */
|
||||
.callout.callout-default {
|
||||
background-color: #fff;
|
||||
border-color: darken(@gray, 10%);
|
||||
|
@ -364,9 +380,7 @@ form .btn .loading-icon {
|
|||
color: @btn-default-color;
|
||||
}
|
||||
}
|
||||
|
||||
/* Boxes */
|
||||
|
||||
.box > .list-group {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
@ -423,9 +437,7 @@ form .btn .loading-icon {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Toastr */
|
||||
|
||||
#toast-container {
|
||||
position: absolute;
|
||||
|
||||
|
@ -497,15 +509,11 @@ form .btn .loading-icon {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Typography */
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
/* Misc */
|
||||
|
||||
.strike {
|
||||
text-decoration: line-through;
|
||||
color: @text-muted;
|
||||
|
|
Loading…
Reference in New Issue