1
0
mirror of https://github.com/bitwarden/browser.git synced 2025-01-04 18:37:45 +01:00

[SM-589][SM-592] Remove router reuse hack (#4913)

* Remove router reuse hack

* Add AuthGuard

* Change to distinctUntilChanged

* Extract show logic
This commit is contained in:
Oscar Hinton 2023-03-03 15:28:59 +01:00 committed by GitHub
parent 2b95c786d8
commit 7736a981e7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 33 additions and 35 deletions

View File

@ -6602,5 +6602,8 @@
"example": "14" "example": "14"
} }
} }
},
"dismiss": {
"message": "Dismiss"
} }
} }

View File

@ -1,10 +1,4 @@
<details <details #details class="tw-rounded-sm tw-bg-background-alt tw-text-main" (toggle)="toggle()" open>
*ngIf="visible"
#details
class="tw-rounded-sm tw-bg-background-alt tw-text-main"
(toggle)="toggle()"
open
>
<summary class="tw-list-none tw-p-2 tw-px-4"> <summary class="tw-list-none tw-p-2 tw-px-4">
<div class="tw-flex tw-select-none tw-items-center tw-gap-4"> <div class="tw-flex tw-select-none tw-items-center tw-gap-4">
<i class="bwi bwi-dashboard tw-text-3xl tw-text-primary-500" aria-hidden="true"></i> <i class="bwi bwi-dashboard tw-text-3xl tw-text-primary-500" aria-hidden="true"></i>
@ -29,9 +23,9 @@
type="button" type="button"
class="tw-ml-auto tw-block" class="tw-ml-auto tw-block"
[ngClass]="{ 'tw-invisible': !isComplete }" [ngClass]="{ 'tw-invisible': !isComplete }"
(click)="dismiss()" (click)="dismiss.emit()"
> >
Dismiss {{ "dismiss" | i18n }}
</button> </button>
</div> </div>
</details> </details>

View File

@ -1,4 +1,4 @@
import { AfterContentInit, Component, ContentChildren, Input, QueryList } from "@angular/core"; import { Component, ContentChildren, EventEmitter, Input, Output, QueryList } from "@angular/core";
import { OnboardingTaskComponent } from "./onboarding-task.component"; import { OnboardingTaskComponent } from "./onboarding-task.component";
@ -6,17 +6,15 @@ import { OnboardingTaskComponent } from "./onboarding-task.component";
selector: "sm-onboarding", selector: "sm-onboarding",
templateUrl: "./onboarding.component.html", templateUrl: "./onboarding.component.html",
}) })
export class OnboardingComponent implements AfterContentInit { export class OnboardingComponent {
@ContentChildren(OnboardingTaskComponent) tasks: QueryList<OnboardingTaskComponent>; @ContentChildren(OnboardingTaskComponent) tasks: QueryList<OnboardingTaskComponent>;
@Input() title: string; @Input() title: string;
@Output() dismiss = new EventEmitter<void>();
protected open = true; protected open = true;
protected visible = false; protected visible = false;
ngAfterContentInit() {
this.visible = !this.isComplete;
}
protected get amountCompleted(): number { protected get amountCompleted(): number {
return this.tasks.filter((task) => task.completed).length; return this.tasks.filter((task) => task.completed).length;
} }
@ -32,8 +30,4 @@ export class OnboardingComponent implements AfterContentInit {
protected toggle() { protected toggle() {
this.open = !this.open; this.open = !this.open;
} }
protected dismiss() {
this.visible = false;
}
} }

View File

@ -3,7 +3,7 @@
</sm-header> </sm-header>
<div *ngIf="view$ | async as view; else spinner"> <div *ngIf="view$ | async as view; else spinner">
<sm-onboarding [title]="'getStarted' | i18n"> <sm-onboarding [title]="'getStarted' | i18n" *ngIf="showOnboarding" (dismiss)="hideOnboarding()">
<sm-onboarding-task <sm-onboarding-task
[title]="'createServiceAccount' | i18n" [title]="'createServiceAccount' | i18n"
(click)="openServiceAccountDialog()" (click)="openServiceAccountDialog()"

View File

@ -1,5 +1,5 @@
import { Component, OnDestroy, OnInit } from "@angular/core"; import { Component, OnDestroy, OnInit } from "@angular/core";
import { ActivatedRoute, Router } from "@angular/router"; import { ActivatedRoute } from "@angular/router";
import { import {
map, map,
Observable, Observable,
@ -8,7 +8,8 @@ import {
takeUntil, takeUntil,
combineLatest, combineLatest,
startWith, startWith,
distinct, distinctUntilChanged,
take,
} from "rxjs"; } from "rxjs";
import { I18nService } from "@bitwarden/common/abstractions/i18n.service"; import { I18nService } from "@bitwarden/common/abstractions/i18n.service";
@ -56,11 +57,11 @@ type Tasks = {
}) })
export class OverviewComponent implements OnInit, OnDestroy { export class OverviewComponent implements OnInit, OnDestroy {
private destroy$: Subject<void> = new Subject<void>(); private destroy$: Subject<void> = new Subject<void>();
private prevShouldReuseRoute: any;
private tableSize = 10; private tableSize = 10;
private organizationId: string; private organizationId: string;
protected organizationName: string; protected organizationName: string;
protected userIsAdmin: boolean; protected userIsAdmin: boolean;
protected showOnboarding = false;
protected view$: Observable<{ protected view$: Observable<{
allProjects: ProjectListView[]; allProjects: ProjectListView[];
@ -72,7 +73,6 @@ export class OverviewComponent implements OnInit, OnDestroy {
constructor( constructor(
private route: ActivatedRoute, private route: ActivatedRoute,
private router: Router,
private projectService: ProjectService, private projectService: ProjectService,
private secretService: SecretService, private secretService: SecretService,
private serviceAccountService: ServiceAccountService, private serviceAccountService: ServiceAccountService,
@ -80,19 +80,12 @@ export class OverviewComponent implements OnInit, OnDestroy {
private organizationService: OrganizationService, private organizationService: OrganizationService,
private platformUtilsService: PlatformUtilsService, private platformUtilsService: PlatformUtilsService,
private i18nService: I18nService private i18nService: I18nService
) { ) {}
/**
* We want to remount the `sm-onboarding` component on route change.
* The component only toggles its visibility on init and on user dismissal.
*/
this.prevShouldReuseRoute = this.router.routeReuseStrategy.shouldReuseRoute;
this.router.routeReuseStrategy.shouldReuseRoute = () => false;
}
ngOnInit() { ngOnInit() {
const orgId$ = this.route.params.pipe( const orgId$ = this.route.params.pipe(
map((p) => p.organizationId), map((p) => p.organizationId),
distinct() distinctUntilChanged()
); );
orgId$ orgId$
@ -136,10 +129,19 @@ export class OverviewComponent implements OnInit, OnDestroy {
}; };
}) })
); );
// Refresh onboarding status when orgId changes by fetching the first value from view$.
orgId$
.pipe(
switchMap(() => this.view$.pipe(take(1))),
takeUntil(this.destroy$)
)
.subscribe((view) => {
this.showOnboarding = Object.values(view.tasks).includes(false);
});
} }
ngOnDestroy(): void { ngOnDestroy(): void {
this.router.routeReuseStrategy.shouldReuseRoute = this.prevShouldReuseRoute;
this.destroy$.next(); this.destroy$.next();
this.destroy$.complete(); this.destroy$.complete();
} }
@ -245,4 +247,8 @@ export class OverviewComponent implements OnInit, OnDestroy {
this.i18nService.t("valueCopied", this.i18nService.t("value")) this.i18nService.t("valueCopied", this.i18nService.t("value"))
); );
} }
protected hideOnboarding() {
this.showOnboarding = false;
}
} }

View File

@ -1,6 +1,7 @@
import { NgModule } from "@angular/core"; import { NgModule } from "@angular/core";
import { RouterModule, Routes } from "@angular/router"; import { RouterModule, Routes } from "@angular/router";
import { AuthGuard } from "@bitwarden/angular/auth/guards/auth.guard";
import { Organization } from "@bitwarden/common/models/domain/organization"; import { Organization } from "@bitwarden/common/models/domain/organization";
import { OrganizationPermissionsGuard } from "@bitwarden/web-vault/app/organizations/guards/org-permissions.guard"; import { OrganizationPermissionsGuard } from "@bitwarden/web-vault/app/organizations/guards/org-permissions.guard";
import { buildFlaggedRoute } from "@bitwarden/web-vault/app/oss-routing.module"; import { buildFlaggedRoute } from "@bitwarden/web-vault/app/oss-routing.module";
@ -19,7 +20,7 @@ const routes: Routes = [
buildFlaggedRoute("secretsManager", { buildFlaggedRoute("secretsManager", {
path: ":organizationId", path: ":organizationId",
component: LayoutComponent, component: LayoutComponent,
canActivate: [OrganizationPermissionsGuard, SMGuard], canActivate: [AuthGuard, OrganizationPermissionsGuard, SMGuard],
data: { data: {
organizationPermissions: (org: Organization) => org.canAccessSecretsManager, organizationPermissions: (org: Organization) => org.canAccessSecretsManager,
}, },