mirror of
https://github.com/bitwarden/browser.git
synced 2025-03-12 13:39:14 +01:00
Implement Clone item functionality (personal/org) (#457)
* Clone personal/org items * Removed ability to delete during clone process
This commit is contained in:
parent
7e95e44f1d
commit
ccf3d49fc4
@ -70,7 +70,7 @@ export class AddEditComponent extends BaseAddEditComponent {
|
|||||||
if (!this.organization.isAdmin) {
|
if (!this.organization.isAdmin) {
|
||||||
return super.saveCipher(cipher);
|
return super.saveCipher(cipher);
|
||||||
}
|
}
|
||||||
if (this.editMode) {
|
if (this.editMode && !this.cloneMode) {
|
||||||
const request = new CipherRequest(cipher);
|
const request = new CipherRequest(cipher);
|
||||||
return this.apiService.putCipherAdmin(this.cipherId, request);
|
return this.apiService.putCipherAdmin(this.cipherId, request);
|
||||||
} else {
|
} else {
|
||||||
|
@ -24,7 +24,8 @@
|
|||||||
</div>
|
</div>
|
||||||
<app-org-vault-ciphers (onCipherClicked)="editCipher($event)"
|
<app-org-vault-ciphers (onCipherClicked)="editCipher($event)"
|
||||||
(onAttachmentsClicked)="editCipherAttachments($event)" (onAddCipher)="addCipher()"
|
(onAttachmentsClicked)="editCipherAttachments($event)" (onAddCipher)="addCipher()"
|
||||||
(onCollectionsClicked)="editCipherCollections($event)" (onEventsClicked)="viewEvents($event)">
|
(onCollectionsClicked)="editCipherCollections($event)" (onEventsClicked)="viewEvents($event)"
|
||||||
|
(onCloneClicked)="cloneCipher($event)">
|
||||||
</app-org-vault-ciphers>
|
</app-org-vault-ciphers>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -263,6 +263,18 @@ export class VaultComponent implements OnInit, OnDestroy {
|
|||||||
return childComponent;
|
return childComponent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cloneCipher(cipher: CipherView) {
|
||||||
|
const component = this.editCipher(cipher);
|
||||||
|
component.cloneMode = true;
|
||||||
|
component.organizationId = this.organization.id;
|
||||||
|
if (this.organization.isAdmin) {
|
||||||
|
component.collections = this.groupingsComponent.collections.filter((c) => !c.readOnly);
|
||||||
|
}
|
||||||
|
// Regardless of Admin state, the collection Ids need to passed manually as they are not assigned value
|
||||||
|
// in the add-edit componenet
|
||||||
|
component.collectionIds = cipher.collectionIds;
|
||||||
|
}
|
||||||
|
|
||||||
async viewEvents(cipher: CipherView) {
|
async viewEvents(cipher: CipherView) {
|
||||||
if (this.modal != null) {
|
if (this.modal != null) {
|
||||||
this.modal.close();
|
this.modal.close();
|
||||||
|
@ -439,7 +439,8 @@
|
|||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<ng-container *ngIf="!editMode && !organization && ownershipOptions && ownershipOptions.length > 1">
|
<ng-container
|
||||||
|
*ngIf="(!editMode || cloneMode) && !organization && ownershipOptions && ownershipOptions.length > 1">
|
||||||
<h3 class="mt-4">{{'ownership' | i18n}}</h3>
|
<h3 class="mt-4">{{'ownership' | i18n}}</h3>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-5">
|
<div class="col-5">
|
||||||
@ -451,7 +452,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
<ng-container *ngIf="!editMode && cipher.organizationId">
|
<ng-container *ngIf="(!editMode || cloneMode) && cipher.organizationId">
|
||||||
<h3 class="mt-4">{{'collections' | i18n}}</h3>
|
<h3 class="mt-4">{{'collections' | i18n}}</h3>
|
||||||
<div *ngIf="!collections || !collections.length">
|
<div *ngIf="!collections || !collections.length">
|
||||||
{{'noCollectionsInList' | i18n}}
|
{{'noCollectionsInList' | i18n}}
|
||||||
@ -504,7 +505,7 @@
|
|||||||
aria-hidden="true"></i>
|
aria-hidden="true"></i>
|
||||||
</button>
|
</button>
|
||||||
<button #deleteBtn type="button" (click)="delete()" class="btn btn-outline-danger"
|
<button #deleteBtn type="button" (click)="delete()" class="btn btn-outline-danger"
|
||||||
appA11yTitle="{{'delete' | i18n}}" *ngIf="editMode" [disabled]="deleteBtn.loading"
|
appA11yTitle="{{'delete' | i18n}}" *ngIf="editMode && !cloneMode" [disabled]="deleteBtn.loading"
|
||||||
[appApiAction]="deletePromise">
|
[appApiAction]="deletePromise">
|
||||||
<i class="fa fa-trash-o fa-lg fa-fw" [hidden]="deleteBtn.loading" aria-hidden="true"></i>
|
<i class="fa fa-trash-o fa-lg fa-fw" [hidden]="deleteBtn.loading" aria-hidden="true"></i>
|
||||||
<i class="fa fa-spinner fa-spin fa-lg fa-fw" [hidden]="!deleteBtn.loading"
|
<i class="fa fa-spinner fa-spin fa-lg fa-fw" [hidden]="!deleteBtn.loading"
|
||||||
|
@ -52,6 +52,11 @@
|
|||||||
<i class="fa fa-fw fa-paperclip" aria-hidden="true"></i>
|
<i class="fa fa-fw fa-paperclip" aria-hidden="true"></i>
|
||||||
{{'attachments' | i18n}}
|
{{'attachments' | i18n}}
|
||||||
</a>
|
</a>
|
||||||
|
<a class="dropdown-item" href="#" appStopClick
|
||||||
|
*ngIf="(!organization && !c.organizationId) || organization" (click)="clone(c)">
|
||||||
|
<i class="fa fa-fw fa-clone" aria-hidden="true"></i>
|
||||||
|
{{'clone' | i18n}}
|
||||||
|
</a>
|
||||||
<a class="dropdown-item" href="#" appStopClick *ngIf="!organization && !c.organizationId"
|
<a class="dropdown-item" href="#" appStopClick *ngIf="!organization && !c.organizationId"
|
||||||
(click)="share(c)">
|
(click)="share(c)">
|
||||||
<i class="fa fa-fw fa-share-alt" aria-hidden="true"></i>
|
<i class="fa fa-fw fa-share-alt" aria-hidden="true"></i>
|
||||||
|
@ -33,6 +33,7 @@ export class CiphersComponent extends BaseCiphersComponent implements OnDestroy
|
|||||||
@Output() onAttachmentsClicked = new EventEmitter<CipherView>();
|
@Output() onAttachmentsClicked = new EventEmitter<CipherView>();
|
||||||
@Output() onShareClicked = new EventEmitter<CipherView>();
|
@Output() onShareClicked = new EventEmitter<CipherView>();
|
||||||
@Output() onCollectionsClicked = new EventEmitter<CipherView>();
|
@Output() onCollectionsClicked = new EventEmitter<CipherView>();
|
||||||
|
@Output() onCloneClicked = new EventEmitter<CipherView>();
|
||||||
|
|
||||||
cipherType = CipherType;
|
cipherType = CipherType;
|
||||||
actionPromise: Promise<any>;
|
actionPromise: Promise<any>;
|
||||||
@ -91,6 +92,10 @@ export class CiphersComponent extends BaseCiphersComponent implements OnDestroy
|
|||||||
this.onCollectionsClicked.emit(c);
|
this.onCollectionsClicked.emit(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
clone(c: CipherView) {
|
||||||
|
this.onCloneClicked.emit(c);
|
||||||
|
}
|
||||||
|
|
||||||
async delete(c: CipherView): Promise<boolean> {
|
async delete(c: CipherView): Promise<boolean> {
|
||||||
if (this.actionPromise != null) {
|
if (this.actionPromise != null) {
|
||||||
return;
|
return;
|
||||||
|
@ -57,7 +57,8 @@
|
|||||||
</div>
|
</div>
|
||||||
<app-vault-ciphers (onCipherClicked)="editCipher($event)"
|
<app-vault-ciphers (onCipherClicked)="editCipher($event)"
|
||||||
(onAttachmentsClicked)="editCipherAttachments($event)" (onAddCipher)="addCipher()"
|
(onAttachmentsClicked)="editCipherAttachments($event)" (onAddCipher)="addCipher()"
|
||||||
(onShareClicked)="shareCipher($event)" (onCollectionsClicked)="editCipherCollections($event)">
|
(onShareClicked)="shareCipher($event)" (onCollectionsClicked)="editCipherCollections($event)"
|
||||||
|
(onCloneClicked)="cloneCipher($event)">
|
||||||
</app-vault-ciphers>
|
</app-vault-ciphers>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-3">
|
<div class="col-3">
|
||||||
|
@ -366,6 +366,11 @@ export class VaultComponent implements OnInit, OnDestroy {
|
|||||||
return childComponent;
|
return childComponent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cloneCipher(cipher: CipherView) {
|
||||||
|
const component = this.editCipher(cipher);
|
||||||
|
component.cloneMode = true;
|
||||||
|
}
|
||||||
|
|
||||||
bulkDelete() {
|
bulkDelete() {
|
||||||
const selectedIds = this.ciphersComponent.getSelectedIds();
|
const selectedIds = this.ciphersComponent.getSelectedIds();
|
||||||
if (selectedIds.length === 0) {
|
if (selectedIds.length === 0) {
|
||||||
|
@ -2956,5 +2956,8 @@
|
|||||||
},
|
},
|
||||||
"minLength": {
|
"minLength": {
|
||||||
"message": "Minimum Length"
|
"message": "Minimum Length"
|
||||||
|
},
|
||||||
|
"clone": {
|
||||||
|
"message": "Clone"
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user