mirror of
https://github.com/bitwarden/browser.git
synced 2024-12-22 16:29:09 +01:00
Implement personal item cloning capability (#1129)
* Initial pass of clone item * Updated npm sub:pull script to include target branches * Made requested changes * Formatting changes * Fixed lint warnings
This commit is contained in:
parent
a00fa10214
commit
c57340c4f3
@ -4,7 +4,7 @@
|
||||
"scripts": {
|
||||
"sub:init": "git submodule update --init --recursive",
|
||||
"sub:update": "git submodule update --remote",
|
||||
"sub:pull": "git submodule foreach git pull",
|
||||
"sub:pull": "git submodule foreach git pull origin master",
|
||||
"postinstall": "npm run sub:init && gulp postinstall",
|
||||
"symlink:win": "rm -rf ./jslib && cmd /c mklink /J .\\jslib ..\\jslib",
|
||||
"symlink:mac": "npm run symlink:lin",
|
||||
|
@ -1238,5 +1238,11 @@
|
||||
},
|
||||
"selectOneCollection": {
|
||||
"message": "You must select at least one collection."
|
||||
},
|
||||
"cloneItem": {
|
||||
"message": "Clone Item"
|
||||
},
|
||||
"clone": {
|
||||
"message": "Clone"
|
||||
}
|
||||
}
|
||||
|
@ -106,14 +106,16 @@ export function ciphersToView(fromState: string, toState: string) {
|
||||
if (fromState == null || toState === null) {
|
||||
return false;
|
||||
}
|
||||
return fromState.indexOf('ciphers_') === 0 && (toState === 'view-cipher' || toState === 'add-cipher');
|
||||
return fromState.indexOf('ciphers_') === 0 &&
|
||||
(toState === 'view-cipher' || toState === 'add-cipher' || toState === 'clone-cipher');
|
||||
}
|
||||
|
||||
export function viewToCiphers(fromState: string, toState: string) {
|
||||
if (fromState == null || toState === null) {
|
||||
return false;
|
||||
}
|
||||
return (fromState === 'view-cipher' || fromState === 'add-cipher') && toState.indexOf('ciphers_') === 0;
|
||||
return (fromState === 'view-cipher' || fromState === 'add-cipher' || fromState === 'clone-cipher') &&
|
||||
toState.indexOf('ciphers_') === 0;
|
||||
}
|
||||
|
||||
export const routerTransition = trigger('routerTransition', [
|
||||
@ -145,14 +147,17 @@ export const routerTransition = trigger('routerTransition', [
|
||||
transition('view-cipher => edit-cipher, view-cipher => cipher-password-history', inSlideUp),
|
||||
transition('edit-cipher => view-cipher, cipher-password-history => view-cipher, edit-cipher => tabs', outSlideDown),
|
||||
|
||||
transition('view-cipher => clone-cipher', inSlideUp),
|
||||
transition('clone-cipher => view-cipher, clone-cipher => tabs', outSlideDown),
|
||||
|
||||
transition('tabs => add-cipher', inSlideUp),
|
||||
transition('add-cipher => tabs', outSlideDown),
|
||||
|
||||
transition('generator => generator-history, tabs => generator-history', inSlideLeft),
|
||||
transition('generator-history => generator, generator-history => tabs', outSlideRight),
|
||||
|
||||
transition('add-cipher => generator, edit-cipher => generator', inSlideUp),
|
||||
transition('generator => add-cipher, generator => edit-cipher', outSlideDown),
|
||||
transition('add-cipher => generator, edit-cipher => generator, clone-cipher => generator', inSlideUp),
|
||||
transition('generator => add-cipher, generator => edit-cipher, generator => clone-cipher', outSlideDown),
|
||||
|
||||
transition('edit-cipher => share-cipher', inSlideUp),
|
||||
transition('share-cipher => edit-cipher, share-cipher => view-cipher', outSlideDown),
|
||||
@ -160,6 +165,9 @@ export const routerTransition = trigger('routerTransition', [
|
||||
transition('edit-cipher => attachments, edit-cipher => collections', inSlideLeft),
|
||||
transition('attachments => edit-cipher, collections => edit-cipher', outSlideRight),
|
||||
|
||||
transition('clone-cipher => attachments, clone-cipher => collections', inSlideLeft),
|
||||
transition('attachments => clone-cipher, collections => clone-cipher', outSlideRight),
|
||||
|
||||
transition('tabs => export', inSlideLeft),
|
||||
transition('export => tabs', outSlideRight),
|
||||
|
||||
|
@ -204,6 +204,12 @@ const routes: Routes = [
|
||||
component: PrivateModeComponent,
|
||||
data: { state: 'private-mode' },
|
||||
},
|
||||
{
|
||||
path: 'clone-cipher',
|
||||
component: AddEditComponent,
|
||||
canActivate: [AuthGuardService],
|
||||
data: { state: 'clone-cipher' },
|
||||
},
|
||||
{
|
||||
path: 'tabs',
|
||||
component: TabsComponent,
|
||||
|
@ -256,7 +256,7 @@
|
||||
<i class="fa fa-chevron-right row-sub-icon" aria-hidden="true"></i>
|
||||
</a>
|
||||
<a class="box-content-row box-content-row-flex text-default" href="#" appStopClick appBlurClick
|
||||
(click)="editCollections()" *ngIf="editMode && cipher.organizationId">
|
||||
(click)="editCollections()" *ngIf="editMode && cipher.organizationId && !cloneMode">
|
||||
<div class="row-main">{{'collections' | i18n}}</div>
|
||||
<i class="fa fa-chevron-right row-sub-icon" aria-hidden="true"></i>
|
||||
</a>
|
||||
@ -320,7 +320,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box" *ngIf="!editMode && ownershipOptions && ownershipOptions.length > 1">
|
||||
<div class="box" *ngIf="(!editMode || cloneMode) && ownershipOptions && ownershipOptions.length > 1">
|
||||
<div class="box-header">
|
||||
{{'ownership' | i18n}}
|
||||
</div>
|
||||
@ -334,7 +334,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box" *ngIf="!editMode && cipher.organizationId">
|
||||
<div class="box" *ngIf="(!editMode || cloneMode )&& cipher.organizationId">
|
||||
<div class="box-header">
|
||||
{{'collections' | i18n}}
|
||||
</div>
|
||||
@ -352,7 +352,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box list" *ngIf="editMode">
|
||||
<div class="box list" *ngIf="editMode && !cloneMode">
|
||||
<div class="box-content single-line">
|
||||
<a class="box-content-row" href="#" appStopClick appBlurClick (click)="share()"
|
||||
*ngIf="!cipher.organizationId">
|
||||
|
@ -58,6 +58,10 @@ export class AddEditComponent extends BaseAddEditComponent {
|
||||
this.type = type;
|
||||
}
|
||||
this.editMode = !params.cipherId;
|
||||
|
||||
if (params.cloneMode != null) {
|
||||
this.cloneMode = params.cloneMode === true;
|
||||
}
|
||||
await this.load();
|
||||
|
||||
if (!this.editMode) {
|
||||
@ -86,7 +90,11 @@ export class AddEditComponent extends BaseAddEditComponent {
|
||||
|
||||
async submit(): Promise<boolean> {
|
||||
if (await super.submit()) {
|
||||
this.location.back();
|
||||
if (this.cloneMode) {
|
||||
this.router.navigate(['/tabs/vault']);
|
||||
} else {
|
||||
this.location.back();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -259,6 +259,18 @@
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box list" *ngIf="!cipher.organizationId">
|
||||
<div class="box-content single-line">
|
||||
<a class="box-content-row" href="#" appStopClick appBlurClick (click)="clone()">
|
||||
<div class="row-main text-primary">
|
||||
<div class="icon text-primary" aria-hidden="true">
|
||||
<i class="fa fa-clone fa-lg fa-fw"></i>
|
||||
</div>
|
||||
<span>{{'cloneItem' | i18n}}</span>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box">
|
||||
<div class="box-footer">
|
||||
<div>
|
||||
@ -278,4 +290,4 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</content>
|
||||
</content>
|
@ -64,6 +64,16 @@ export class ViewComponent extends BaseViewComponent {
|
||||
this.router.navigate(['/edit-cipher'], { queryParams: { cipherId: this.cipher.id } });
|
||||
}
|
||||
|
||||
clone() {
|
||||
super.clone();
|
||||
this.router.navigate(['/clone-cipher'], {
|
||||
queryParams: {
|
||||
cloneMode: true,
|
||||
cipherId: this.cipher.id,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
close() {
|
||||
this.location.back();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user