mirror of
https://github.com/bitwarden/browser.git
synced 2024-12-01 13:13:36 +01:00
[CL-269] extension router transitions (#11989)
This commit is contained in:
parent
7d6da0a68d
commit
178ef353d4
1
.github/CODEOWNERS
vendored
1
.github/CODEOWNERS
vendored
@ -102,6 +102,7 @@ apps/desktop/src/services/duckduckgo-message-handler.service.ts @bitwarden/team-
|
||||
.storybook @bitwarden/team-design-system
|
||||
libs/components @bitwarden/team-design-system
|
||||
apps/browser/src/platform/popup/layout @bitwarden/team-design-system
|
||||
apps/browser/src/popup/app-routing.animations.ts @bitwarden/team-design-system
|
||||
apps/web/src/app/layouts @bitwarden/team-design-system
|
||||
|
||||
## Desktop native module ##
|
||||
|
@ -1,4 +1,19 @@
|
||||
import { animate, group, query, style, transition, trigger } from "@angular/animations";
|
||||
import {
|
||||
animate,
|
||||
AnimationMetadata,
|
||||
group,
|
||||
query,
|
||||
style,
|
||||
transition,
|
||||
trigger,
|
||||
} from "@angular/animations";
|
||||
|
||||
/**
|
||||
* Determines the router transition behavior.
|
||||
* Changing between elevations will animate from the right.
|
||||
* Navigating between two pages of the same elevation will not animate.
|
||||
*/
|
||||
export type RouteElevation = 0 | 1 | 2 | 3 | 4;
|
||||
|
||||
const queryShown = query(
|
||||
":enter, :leave",
|
||||
@ -13,11 +28,15 @@ const queryChildRoute = query("router-outlet ~ *", [style({}), animate(1, style(
|
||||
optional: true,
|
||||
});
|
||||
|
||||
const speed = "0.4s";
|
||||
const speedX = "0.225s";
|
||||
const speedY = "0.3s";
|
||||
|
||||
export function queryTranslate(
|
||||
direction: string,
|
||||
axis: string,
|
||||
type TranslateDirection = "enter" | "leave";
|
||||
type TranslationAxis = "X" | "Y";
|
||||
|
||||
function queryTranslate(
|
||||
direction: TranslateDirection,
|
||||
axis: TranslationAxis,
|
||||
from: number,
|
||||
to: number,
|
||||
zIndex = 1000,
|
||||
@ -30,217 +49,67 @@ export function queryTranslate(
|
||||
zIndex: zIndex,
|
||||
boxShadow: "0 3px 2px -2px gray",
|
||||
}),
|
||||
animate(speed + " ease-in-out", style({ transform: "translate" + axis + "(" + to + "%)" })),
|
||||
animate(
|
||||
(axis === "X" ? speedX : speedY) + " ease-in-out",
|
||||
style({
|
||||
transform: "translate" + axis + "(" + to + "%)",
|
||||
}),
|
||||
),
|
||||
],
|
||||
{ optional: true },
|
||||
{
|
||||
optional: true,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
export function queryTranslateX(direction: string, from: number, to: number, zIndex = 1000) {
|
||||
return queryTranslate(direction, "X", from, to, zIndex);
|
||||
}
|
||||
|
||||
export function queryTranslateY(direction: string, from: number, to: number, zIndex = 1000) {
|
||||
return queryTranslate(direction, "Y", from, to, zIndex);
|
||||
}
|
||||
|
||||
const inSlideLeft = [
|
||||
const animations = {
|
||||
slideInFromRight: [
|
||||
queryShown,
|
||||
group([queryTranslateX("enter", 100, 0), queryTranslateX("leave", 0, -100), queryChildRoute]),
|
||||
];
|
||||
|
||||
const outSlideRight = [
|
||||
group([
|
||||
queryTranslate("enter", "X", 100, 0, 1010),
|
||||
queryTranslate("leave", "X", 0, 0),
|
||||
queryChildRoute,
|
||||
]),
|
||||
],
|
||||
slideOutToRight: [
|
||||
queryShown,
|
||||
group([queryTranslateX("enter", -100, 0), queryTranslateX("leave", 0, 100)]),
|
||||
];
|
||||
|
||||
const inSlideUp = [
|
||||
queryShown,
|
||||
group([queryTranslateY("enter", 100, 0, 1010), queryTranslateY("leave", 0, 0), queryChildRoute]),
|
||||
];
|
||||
|
||||
const outSlideDown = [
|
||||
queryShown,
|
||||
group([queryTranslateY("enter", 0, 0), queryTranslateY("leave", 0, 100, 1010)]),
|
||||
];
|
||||
|
||||
const inSlideDown = [
|
||||
queryShown,
|
||||
group([queryTranslateY("enter", -100, 0, 1010), queryTranslateY("leave", 0, 0), queryChildRoute]),
|
||||
];
|
||||
|
||||
// eslint-disable-next-line
|
||||
const outSlideUp = [
|
||||
queryShown,
|
||||
group([queryTranslateY("enter", 0, 0), queryTranslateY("leave", 0, -100, 1010)]),
|
||||
];
|
||||
|
||||
export function tabsToCiphers(fromState: string, toState: string) {
|
||||
if (fromState == null || toState === null || toState.indexOf("ciphers_") === -1) {
|
||||
return false;
|
||||
}
|
||||
return (
|
||||
(fromState.indexOf("ciphers_") === 0 && fromState.indexOf("ciphers_direction=b") === -1) ||
|
||||
fromState === "tabs"
|
||||
);
|
||||
}
|
||||
|
||||
export function ciphersToTabs(fromState: string, toState: string) {
|
||||
if (fromState == null || toState === null || fromState.indexOf("ciphers_") === -1) {
|
||||
return false;
|
||||
}
|
||||
return toState.indexOf("ciphers_direction=b") === 0 || toState === "tabs";
|
||||
}
|
||||
|
||||
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" || toState === "clone-cipher")
|
||||
);
|
||||
}
|
||||
|
||||
export function viewToCiphers(fromState: string, toState: string) {
|
||||
if (fromState == null || toState === null) {
|
||||
return false;
|
||||
}
|
||||
return (
|
||||
(fromState === "view-cipher" || fromState === "add-cipher" || fromState === "clone-cipher") &&
|
||||
toState.indexOf("ciphers_") === 0
|
||||
);
|
||||
}
|
||||
group([queryTranslate("enter", "X", 0, 0), queryTranslate("leave", "X", 0, 100, 1010)]),
|
||||
],
|
||||
/** --- Not used --- */
|
||||
// slideInFromTop: [
|
||||
// queryShown,
|
||||
// group([
|
||||
// queryTranslate("enter", "Y", -100, 0, 1010),
|
||||
// queryTranslate("leave", "Y", 0, 0),
|
||||
// queryChildRoute,
|
||||
// ]),
|
||||
// ],
|
||||
// slideOutToTop: [
|
||||
// queryShown,
|
||||
// group([queryTranslate("enter", "Y", 0, 0), queryTranslate("leave", "Y", 0, -100, 1010)]),
|
||||
// ],
|
||||
} satisfies Record<string, AnimationMetadata[]>;
|
||||
|
||||
export const routerTransition = trigger("routerTransition", [
|
||||
transition("void => home", inSlideLeft),
|
||||
transition("void => tabs", inSlideLeft),
|
||||
transition("0 => 1", animations.slideInFromRight),
|
||||
transition("0 => 2", animations.slideInFromRight),
|
||||
transition("0 => 3", animations.slideInFromRight),
|
||||
transition("0 => 4", animations.slideInFromRight),
|
||||
transition("1 => 2", animations.slideInFromRight),
|
||||
transition("1 => 3", animations.slideInFromRight),
|
||||
transition("1 => 4", animations.slideInFromRight),
|
||||
transition("2 => 3", animations.slideInFromRight),
|
||||
transition("2 => 4", animations.slideInFromRight),
|
||||
transition("3 => 4", animations.slideInFromRight),
|
||||
|
||||
transition("home => environment, home => login, home => register", inSlideUp),
|
||||
|
||||
transition("login => home", outSlideDown),
|
||||
transition("login => hint", inSlideUp),
|
||||
transition("login => tabs, login => 2fa, login => login-with-device", inSlideLeft),
|
||||
|
||||
transition("hint => login, register => home, environment => home", outSlideDown),
|
||||
|
||||
transition("2fa => login", outSlideRight),
|
||||
transition("2fa => 2fa-options", inSlideUp),
|
||||
transition("2fa-options => 2fa", outSlideDown),
|
||||
transition("2fa => tabs", inSlideLeft),
|
||||
|
||||
transition("login-with-device => tabs, login-with-device => 2fa", inSlideLeft),
|
||||
transition("login-with-device => login", outSlideRight),
|
||||
|
||||
transition("admin-approval-requested => tabs, admin-approval-requested => 2fa", inSlideLeft),
|
||||
transition("admin-approval-requested => login", outSlideRight),
|
||||
|
||||
transition(tabsToCiphers, inSlideLeft),
|
||||
transition(ciphersToTabs, outSlideRight),
|
||||
|
||||
transition(ciphersToView, inSlideUp),
|
||||
transition(viewToCiphers, outSlideDown),
|
||||
|
||||
transition("tabs => view-cipher", inSlideUp),
|
||||
transition("view-cipher => tabs", outSlideDown),
|
||||
|
||||
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("view-cipher => share-cipher", inSlideUp),
|
||||
transition("share-cipher => view-cipher", 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, clone-cipher => generator",
|
||||
inSlideUp,
|
||||
),
|
||||
transition(
|
||||
"generator => add-cipher, generator => edit-cipher, generator => clone-cipher",
|
||||
outSlideDown,
|
||||
),
|
||||
|
||||
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 => account-security", inSlideLeft),
|
||||
transition("account-security => tabs", outSlideRight),
|
||||
|
||||
transition("tabs => assign-collections", inSlideLeft),
|
||||
transition("assign-collections => tabs", outSlideRight),
|
||||
|
||||
// Vault settings
|
||||
transition("tabs => vault-settings", inSlideLeft),
|
||||
transition("vault-settings => tabs", outSlideRight),
|
||||
|
||||
transition("vault-settings => import", inSlideLeft),
|
||||
transition("import => vault-settings", outSlideRight),
|
||||
|
||||
transition("vault-settings => export", inSlideLeft),
|
||||
transition("export => vault-settings", outSlideRight),
|
||||
|
||||
transition("vault-settings => folders", inSlideLeft),
|
||||
transition("folders => vault-settings", outSlideRight),
|
||||
|
||||
transition("folders => edit-folder, folders => add-folder", inSlideUp),
|
||||
transition("edit-folder => folders, add-folder => folders", outSlideDown),
|
||||
|
||||
transition("vault-settings => sync", inSlideLeft),
|
||||
transition("sync => vault-settings", outSlideRight),
|
||||
|
||||
transition("vault-settings => trash", inSlideLeft),
|
||||
transition("trash => vault-settings", outSlideRight),
|
||||
|
||||
transition("trash => view-cipher", inSlideLeft),
|
||||
transition("view-cipher => trash", outSlideRight),
|
||||
|
||||
// Appearance settings
|
||||
transition("tabs => appearance", inSlideLeft),
|
||||
transition("appearance => tabs", outSlideRight),
|
||||
|
||||
transition("tabs => premium", inSlideLeft),
|
||||
transition("premium => tabs", outSlideRight),
|
||||
|
||||
transition("tabs => lock", inSlideDown),
|
||||
|
||||
transition("tabs => about", inSlideLeft),
|
||||
transition("about => tabs", outSlideRight),
|
||||
|
||||
transition("tabs => send-type", inSlideLeft),
|
||||
transition("send-type => tabs", outSlideRight),
|
||||
|
||||
transition("tabs => add-send, send-type => add-send", inSlideUp),
|
||||
transition("add-send => tabs, add-send => send-type", outSlideDown),
|
||||
|
||||
transition("tabs => edit-send, send-type => edit-send", inSlideUp),
|
||||
transition("edit-send => tabs, edit-send => send-type", outSlideDown),
|
||||
|
||||
// Notification settings
|
||||
transition("tabs => notifications", inSlideLeft),
|
||||
transition("notifications => tabs", outSlideRight),
|
||||
|
||||
transition("notifications => excluded-domains", inSlideLeft),
|
||||
transition("excluded-domains => notifications", outSlideRight),
|
||||
|
||||
transition("tabs => autofill", inSlideLeft),
|
||||
transition("autofill => tabs", outSlideRight),
|
||||
|
||||
transition("* => account-switcher", inSlideUp),
|
||||
transition("account-switcher => *", outSlideDown),
|
||||
|
||||
transition("lock => *", outSlideDown),
|
||||
transition("1 => 0", animations.slideOutToRight),
|
||||
transition("2 => 0", animations.slideOutToRight),
|
||||
transition("2 => 1", animations.slideOutToRight),
|
||||
transition("3 => 0", animations.slideOutToRight),
|
||||
transition("3 => 1", animations.slideOutToRight),
|
||||
transition("3 => 2", animations.slideOutToRight),
|
||||
transition("4 => 0", animations.slideOutToRight),
|
||||
transition("4 => 1", animations.slideOutToRight),
|
||||
transition("4 => 2", animations.slideOutToRight),
|
||||
transition("4 => 3", animations.slideOutToRight),
|
||||
]);
|
||||
|
@ -123,6 +123,7 @@ import { TrashComponent } from "../vault/popup/settings/trash.component";
|
||||
import { VaultSettingsV2Component } from "../vault/popup/settings/vault-settings-v2.component";
|
||||
import { VaultSettingsComponent } from "../vault/popup/settings/vault-settings.component";
|
||||
|
||||
import { RouteElevation } from "./app-routing.animations";
|
||||
import { debounceNavigationGuard } from "./services/debounce-navigation.service";
|
||||
import { TabsV2Component } from "./tabs-v2.component";
|
||||
import { TabsComponent } from "./tabs.component";
|
||||
@ -131,13 +132,10 @@ import { TabsComponent } from "./tabs.component";
|
||||
* Data properties acceptable for use in extension route objects
|
||||
*/
|
||||
export interface RouteDataProperties {
|
||||
elevation: RouteElevation;
|
||||
|
||||
/**
|
||||
* A state string which identifies the current route for the sake of transition animation logic.
|
||||
* The state string is passed into [@routerTransition] in the app.component.
|
||||
*/
|
||||
state: string;
|
||||
/**
|
||||
* A boolean to indicate that the URL should not be saved in memory in the BrowserRouterSvc.
|
||||
* A boolean to indicate that the URL should not be saved in memory in the BrowserRouterService.
|
||||
*/
|
||||
doNotSaveUrl?: boolean;
|
||||
}
|
||||
@ -167,19 +165,19 @@ const routes: Routes = [
|
||||
path: "home",
|
||||
component: HomeComponent,
|
||||
canActivate: [unauthGuardFn(unauthRouteOverrides), unauthUiRefreshRedirect("/login")],
|
||||
data: { state: "home" } satisfies RouteDataProperties,
|
||||
data: { elevation: 1 } satisfies RouteDataProperties,
|
||||
},
|
||||
...extensionRefreshSwap(Fido2V1Component, Fido2Component, {
|
||||
path: "fido2",
|
||||
canActivate: [fido2AuthGuard],
|
||||
data: { state: "fido2" } satisfies RouteDataProperties,
|
||||
data: { elevation: 1 } satisfies RouteDataProperties,
|
||||
}),
|
||||
{
|
||||
path: "lock",
|
||||
component: LockComponent,
|
||||
canActivate: [lockGuard()],
|
||||
canMatch: [extensionRefreshRedirect("/lockV2")],
|
||||
data: { state: "lock", doNotSaveUrl: true } satisfies RouteDataProperties,
|
||||
data: { elevation: 1, doNotSaveUrl: true } satisfies RouteDataProperties,
|
||||
},
|
||||
...twofactorRefactorSwap(
|
||||
TwoFactorComponent,
|
||||
@ -187,12 +185,12 @@ const routes: Routes = [
|
||||
{
|
||||
path: "2fa",
|
||||
canActivate: [unauthGuardFn(unauthRouteOverrides)],
|
||||
data: { state: "2fa" } satisfies RouteDataProperties,
|
||||
data: { elevation: 1 } satisfies RouteDataProperties,
|
||||
},
|
||||
{
|
||||
path: "2fa",
|
||||
canActivate: [unauthGuardFn(unauthRouteOverrides)],
|
||||
data: { state: "2fa" } satisfies RouteDataProperties,
|
||||
data: { elevation: 1 } satisfies RouteDataProperties,
|
||||
children: [
|
||||
{
|
||||
path: "",
|
||||
@ -205,201 +203,207 @@ const routes: Routes = [
|
||||
path: "2fa-options",
|
||||
component: TwoFactorOptionsComponent,
|
||||
canActivate: [unauthGuardFn(unauthRouteOverrides)],
|
||||
data: { state: "2fa-options" } satisfies RouteDataProperties,
|
||||
data: { elevation: 1 } satisfies RouteDataProperties,
|
||||
},
|
||||
{
|
||||
path: "sso",
|
||||
component: SsoComponent,
|
||||
canActivate: [unauthGuardFn(unauthRouteOverrides)],
|
||||
data: { state: "sso" } satisfies RouteDataProperties,
|
||||
data: { elevation: 1 } satisfies RouteDataProperties,
|
||||
},
|
||||
{
|
||||
path: "set-password",
|
||||
component: SetPasswordComponent,
|
||||
data: { state: "set-password" } satisfies RouteDataProperties,
|
||||
data: { elevation: 1 } satisfies RouteDataProperties,
|
||||
},
|
||||
{
|
||||
path: "remove-password",
|
||||
component: RemovePasswordComponent,
|
||||
canActivate: [authGuard],
|
||||
data: { state: "remove-password" } satisfies RouteDataProperties,
|
||||
data: { elevation: 1 } satisfies RouteDataProperties,
|
||||
},
|
||||
{
|
||||
path: "register",
|
||||
component: RegisterComponent,
|
||||
canActivate: [unauthGuardFn(unauthRouteOverrides)],
|
||||
data: { state: "register" } satisfies RouteDataProperties,
|
||||
data: { elevation: 1 } satisfies RouteDataProperties,
|
||||
},
|
||||
{
|
||||
path: "environment",
|
||||
component: EnvironmentComponent,
|
||||
canActivate: [unauthGuardFn(unauthRouteOverrides)],
|
||||
data: { state: "environment" } satisfies RouteDataProperties,
|
||||
data: { elevation: 1 } satisfies RouteDataProperties,
|
||||
},
|
||||
{
|
||||
path: "ciphers",
|
||||
component: VaultItemsComponent,
|
||||
canActivate: [authGuard],
|
||||
data: { state: "ciphers" } satisfies RouteDataProperties,
|
||||
data: { elevation: 1 } satisfies RouteDataProperties,
|
||||
},
|
||||
...extensionRefreshSwap(ViewComponent, ViewV2Component, {
|
||||
path: "view-cipher",
|
||||
canActivate: [authGuard],
|
||||
data: { state: "view-cipher" } satisfies RouteDataProperties,
|
||||
data: {
|
||||
// Above "trash"
|
||||
elevation: 3,
|
||||
} satisfies RouteDataProperties,
|
||||
}),
|
||||
...extensionRefreshSwap(PasswordHistoryComponent, PasswordHistoryV2Component, {
|
||||
path: "cipher-password-history",
|
||||
canActivate: [authGuard],
|
||||
data: { state: "cipher-password-history" } satisfies RouteDataProperties,
|
||||
data: { elevation: 1 } satisfies RouteDataProperties,
|
||||
}),
|
||||
...extensionRefreshSwap(AddEditComponent, AddEditV2Component, {
|
||||
path: "add-cipher",
|
||||
canActivate: [authGuard, debounceNavigationGuard()],
|
||||
data: { state: "add-cipher" } satisfies RouteDataProperties,
|
||||
data: { elevation: 1 } satisfies RouteDataProperties,
|
||||
runGuardsAndResolvers: "always",
|
||||
}),
|
||||
...extensionRefreshSwap(AddEditComponent, AddEditV2Component, {
|
||||
path: "edit-cipher",
|
||||
canActivate: [authGuard, debounceNavigationGuard()],
|
||||
data: { state: "edit-cipher" } satisfies RouteDataProperties,
|
||||
data: {
|
||||
// Above "trash"
|
||||
elevation: 3,
|
||||
} satisfies RouteDataProperties,
|
||||
runGuardsAndResolvers: "always",
|
||||
}),
|
||||
{
|
||||
path: "share-cipher",
|
||||
component: ShareComponent,
|
||||
canActivate: [authGuard],
|
||||
data: { state: "share-cipher" } satisfies RouteDataProperties,
|
||||
data: { elevation: 1 } satisfies RouteDataProperties,
|
||||
},
|
||||
{
|
||||
path: "collections",
|
||||
component: CollectionsComponent,
|
||||
canActivate: [authGuard],
|
||||
data: { state: "collections" } satisfies RouteDataProperties,
|
||||
data: { elevation: 1 } satisfies RouteDataProperties,
|
||||
},
|
||||
...extensionRefreshSwap(AttachmentsComponent, AttachmentsV2Component, {
|
||||
path: "attachments",
|
||||
canActivate: [authGuard],
|
||||
data: { state: "attachments" } satisfies RouteDataProperties,
|
||||
data: { elevation: 1 } satisfies RouteDataProperties,
|
||||
}),
|
||||
{
|
||||
path: "generator",
|
||||
component: GeneratorComponent,
|
||||
canActivate: [authGuard],
|
||||
data: { state: "generator" } satisfies RouteDataProperties,
|
||||
data: { elevation: 0 } satisfies RouteDataProperties,
|
||||
},
|
||||
...extensionRefreshSwap(PasswordGeneratorHistoryComponent, CredentialGeneratorHistoryComponent, {
|
||||
path: "generator-history",
|
||||
canActivate: [authGuard],
|
||||
data: { state: "generator-history" } satisfies RouteDataProperties,
|
||||
data: { elevation: 1 } satisfies RouteDataProperties,
|
||||
}),
|
||||
...extensionRefreshSwap(ImportBrowserComponent, ImportBrowserV2Component, {
|
||||
path: "import",
|
||||
canActivate: [authGuard],
|
||||
data: { state: "import" } satisfies RouteDataProperties,
|
||||
data: { elevation: 1 } satisfies RouteDataProperties,
|
||||
}),
|
||||
...extensionRefreshSwap(ExportBrowserComponent, ExportBrowserV2Component, {
|
||||
path: "export",
|
||||
canActivate: [authGuard],
|
||||
data: { state: "export" } satisfies RouteDataProperties,
|
||||
data: { elevation: 2 } satisfies RouteDataProperties,
|
||||
}),
|
||||
...extensionRefreshSwap(AutofillV1Component, AutofillComponent, {
|
||||
path: "autofill",
|
||||
canActivate: [authGuard],
|
||||
data: { state: "autofill" } satisfies RouteDataProperties,
|
||||
data: { elevation: 1 } satisfies RouteDataProperties,
|
||||
}),
|
||||
...extensionRefreshSwap(AccountSecurityV1Component, AccountSecurityComponent, {
|
||||
path: "account-security",
|
||||
canActivate: [authGuard],
|
||||
data: { state: "account-security" } satisfies RouteDataProperties,
|
||||
data: { elevation: 1 } satisfies RouteDataProperties,
|
||||
}),
|
||||
...extensionRefreshSwap(NotificationsSettingsV1Component, NotificationsSettingsComponent, {
|
||||
path: "notifications",
|
||||
canActivate: [authGuard],
|
||||
data: { state: "notifications" } satisfies RouteDataProperties,
|
||||
data: { elevation: 1 } satisfies RouteDataProperties,
|
||||
}),
|
||||
...extensionRefreshSwap(VaultSettingsComponent, VaultSettingsV2Component, {
|
||||
path: "vault-settings",
|
||||
canActivate: [authGuard],
|
||||
data: { state: "vault-settings" } satisfies RouteDataProperties,
|
||||
data: { elevation: 1 } satisfies RouteDataProperties,
|
||||
}),
|
||||
...extensionRefreshSwap(FoldersComponent, FoldersV2Component, {
|
||||
path: "folders",
|
||||
canActivate: [authGuard],
|
||||
data: { state: "folders" } satisfies RouteDataProperties,
|
||||
data: { elevation: 2 } satisfies RouteDataProperties,
|
||||
}),
|
||||
{
|
||||
path: "add-folder",
|
||||
component: FolderAddEditComponent,
|
||||
canActivate: [authGuard],
|
||||
data: { state: "add-folder" } satisfies RouteDataProperties,
|
||||
data: { elevation: 1 } satisfies RouteDataProperties,
|
||||
},
|
||||
{
|
||||
path: "edit-folder",
|
||||
component: FolderAddEditComponent,
|
||||
canActivate: [authGuard],
|
||||
data: { state: "edit-folder" } satisfies RouteDataProperties,
|
||||
data: { elevation: 1 } satisfies RouteDataProperties,
|
||||
},
|
||||
{
|
||||
path: "sync",
|
||||
component: SyncComponent,
|
||||
canActivate: [authGuard],
|
||||
data: { state: "sync" } satisfies RouteDataProperties,
|
||||
data: { elevation: 1 } satisfies RouteDataProperties,
|
||||
},
|
||||
...extensionRefreshSwap(ExcludedDomainsV1Component, ExcludedDomainsComponent, {
|
||||
path: "excluded-domains",
|
||||
canActivate: [authGuard],
|
||||
data: { state: "excluded-domains" } satisfies RouteDataProperties,
|
||||
data: { elevation: 2 } satisfies RouteDataProperties,
|
||||
}),
|
||||
...extensionRefreshSwap(PremiumComponent, PremiumV2Component, {
|
||||
path: "premium",
|
||||
component: PremiumComponent,
|
||||
canActivate: [authGuard],
|
||||
data: { state: "premium" } satisfies RouteDataProperties,
|
||||
data: { elevation: 1 } satisfies RouteDataProperties,
|
||||
}),
|
||||
...extensionRefreshSwap(AppearanceComponent, AppearanceV2Component, {
|
||||
path: "appearance",
|
||||
canActivate: [authGuard],
|
||||
data: { state: "appearance" } satisfies RouteDataProperties,
|
||||
data: { elevation: 1 } satisfies RouteDataProperties,
|
||||
}),
|
||||
...extensionRefreshSwap(AddEditComponent, AddEditV2Component, {
|
||||
path: "clone-cipher",
|
||||
canActivate: [authGuard],
|
||||
data: { state: "clone-cipher" } satisfies RouteDataProperties,
|
||||
data: { elevation: 1 } satisfies RouteDataProperties,
|
||||
}),
|
||||
{
|
||||
path: "send-type",
|
||||
component: SendTypeComponent,
|
||||
canActivate: [authGuard],
|
||||
data: { state: "send-type" } satisfies RouteDataProperties,
|
||||
data: { elevation: 1 } satisfies RouteDataProperties,
|
||||
},
|
||||
...extensionRefreshSwap(SendAddEditComponent, SendAddEditV2Component, {
|
||||
path: "add-send",
|
||||
canActivate: [authGuard],
|
||||
data: { state: "add-send" } satisfies RouteDataProperties,
|
||||
data: { elevation: 1 } satisfies RouteDataProperties,
|
||||
}),
|
||||
...extensionRefreshSwap(SendAddEditComponent, SendAddEditV2Component, {
|
||||
path: "edit-send",
|
||||
canActivate: [authGuard],
|
||||
data: { state: "edit-send" } satisfies RouteDataProperties,
|
||||
data: { elevation: 1 } satisfies RouteDataProperties,
|
||||
}),
|
||||
{
|
||||
path: "send-created",
|
||||
component: SendCreatedComponent,
|
||||
canActivate: [authGuard],
|
||||
data: { state: "send" } satisfies RouteDataProperties,
|
||||
data: { elevation: 1 } satisfies RouteDataProperties,
|
||||
},
|
||||
{
|
||||
path: "update-temp-password",
|
||||
component: UpdateTempPasswordComponent,
|
||||
canActivate: [authGuard],
|
||||
data: { state: "update-temp-password" } satisfies RouteDataProperties,
|
||||
data: { elevation: 1 } satisfies RouteDataProperties,
|
||||
},
|
||||
...unauthUiRefreshSwap(
|
||||
LoginViaAuthRequestComponentV1,
|
||||
ExtensionAnonLayoutWrapperComponent,
|
||||
{
|
||||
path: "login-with-device",
|
||||
data: { state: "login-with-device" } satisfies RouteDataProperties,
|
||||
data: { elevation: 1 } satisfies RouteDataProperties,
|
||||
},
|
||||
{
|
||||
path: "login-with-device",
|
||||
@ -413,7 +417,7 @@ const routes: Routes = [
|
||||
},
|
||||
showLogo: false,
|
||||
showBackButton: true,
|
||||
state: "login-with-device",
|
||||
elevation: 1,
|
||||
} satisfies RouteDataProperties & ExtensionAnonLayoutWrapperData,
|
||||
children: [
|
||||
{ path: "", component: LoginViaAuthRequestComponent },
|
||||
@ -430,7 +434,7 @@ const routes: Routes = [
|
||||
ExtensionAnonLayoutWrapperComponent,
|
||||
{
|
||||
path: "admin-approval-requested",
|
||||
data: { state: "admin-approval-requested" } satisfies RouteDataProperties,
|
||||
data: { elevation: 1 } satisfies RouteDataProperties,
|
||||
},
|
||||
{
|
||||
path: "admin-approval-requested",
|
||||
@ -444,7 +448,7 @@ const routes: Routes = [
|
||||
},
|
||||
showLogo: false,
|
||||
showBackButton: true,
|
||||
state: "admin-approval-requested",
|
||||
elevation: 1,
|
||||
} satisfies RouteDataProperties & ExtensionAnonLayoutWrapperData,
|
||||
children: [{ path: "", component: LoginViaAuthRequestComponent }],
|
||||
},
|
||||
@ -456,7 +460,7 @@ const routes: Routes = [
|
||||
path: "hint",
|
||||
canActivate: [unauthGuardFn(unauthRouteOverrides)],
|
||||
data: {
|
||||
state: "hint",
|
||||
elevation: 1,
|
||||
} satisfies RouteDataProperties,
|
||||
},
|
||||
{
|
||||
@ -474,7 +478,7 @@ const routes: Routes = [
|
||||
},
|
||||
pageIcon: UserLockIcon,
|
||||
showBackButton: true,
|
||||
state: "hint",
|
||||
elevation: 1,
|
||||
} satisfies RouteDataProperties & ExtensionAnonLayoutWrapperData,
|
||||
children: [
|
||||
{ path: "", component: PasswordHintComponent },
|
||||
@ -497,7 +501,7 @@ const routes: Routes = [
|
||||
{
|
||||
path: "login",
|
||||
canActivate: [unauthGuardFn(unauthRouteOverrides)],
|
||||
data: { state: "login" },
|
||||
data: { elevation: 1 },
|
||||
},
|
||||
{
|
||||
path: "",
|
||||
@ -510,7 +514,7 @@ const routes: Routes = [
|
||||
pageTitle: {
|
||||
key: "logInToBitwarden",
|
||||
},
|
||||
state: "login",
|
||||
elevation: 1,
|
||||
showAcctSwitcher: true,
|
||||
} satisfies RouteDataProperties & ExtensionAnonLayoutWrapperData,
|
||||
children: [
|
||||
@ -535,7 +539,7 @@ const routes: Routes = [
|
||||
{
|
||||
path: "login-initiated",
|
||||
canActivate: [tdeDecryptionRequiredGuard()],
|
||||
data: { state: "login-initiated" } satisfies RouteDataProperties,
|
||||
data: { elevation: 1 } satisfies RouteDataProperties,
|
||||
},
|
||||
{
|
||||
path: "login-initiated",
|
||||
@ -554,7 +558,7 @@ const routes: Routes = [
|
||||
path: "signup",
|
||||
canActivate: [canAccessFeature(FeatureFlag.EmailVerification), unauthGuardFn()],
|
||||
data: {
|
||||
state: "signup",
|
||||
elevation: 1,
|
||||
pageIcon: RegistrationUserAddIcon,
|
||||
pageTitle: {
|
||||
key: "createAccount",
|
||||
@ -581,7 +585,7 @@ const routes: Routes = [
|
||||
canActivate: [canAccessFeature(FeatureFlag.EmailVerification), unauthGuardFn()],
|
||||
data: {
|
||||
pageIcon: RegistrationLockAltIcon,
|
||||
state: "finish-signup",
|
||||
elevation: 1,
|
||||
showBackButton: true,
|
||||
} satisfies RouteDataProperties & ExtensionAnonLayoutWrapperData,
|
||||
children: [
|
||||
@ -626,7 +630,7 @@ const routes: Routes = [
|
||||
pageSubtitle: {
|
||||
key: "finishJoiningThisOrganizationBySettingAMasterPassword",
|
||||
},
|
||||
state: "set-password-jit",
|
||||
elevation: 1,
|
||||
} satisfies RouteDataProperties & AnonLayoutWrapperData,
|
||||
},
|
||||
],
|
||||
@ -635,21 +639,21 @@ const routes: Routes = [
|
||||
path: "assign-collections",
|
||||
component: AssignCollections,
|
||||
canActivate: [canAccessFeature(FeatureFlag.ExtensionRefresh, true, "/")],
|
||||
data: { state: "assign-collections" } satisfies RouteDataProperties,
|
||||
data: { elevation: 1 } satisfies RouteDataProperties,
|
||||
},
|
||||
...extensionRefreshSwap(AboutPageComponent, AboutPageV2Component, {
|
||||
path: "about",
|
||||
canActivate: [authGuard],
|
||||
data: { state: "about" } satisfies RouteDataProperties,
|
||||
data: { elevation: 1 } satisfies RouteDataProperties,
|
||||
}),
|
||||
...extensionRefreshSwap(MoreFromBitwardenPageComponent, MoreFromBitwardenPageV2Component, {
|
||||
path: "more-from-bitwarden",
|
||||
canActivate: [authGuard],
|
||||
data: { state: "moreFromBitwarden" } satisfies RouteDataProperties,
|
||||
data: { elevation: 2 } satisfies RouteDataProperties,
|
||||
}),
|
||||
...extensionRefreshSwap(TabsComponent, TabsV2Component, {
|
||||
path: "tabs",
|
||||
data: { state: "tabs" } satisfies RouteDataProperties,
|
||||
data: { elevation: 0 } satisfies RouteDataProperties,
|
||||
children: [
|
||||
{
|
||||
path: "",
|
||||
@ -661,42 +665,42 @@ const routes: Routes = [
|
||||
component: CurrentTabComponent,
|
||||
canActivate: [authGuard],
|
||||
canMatch: [extensionRefreshRedirect("/tabs/vault")],
|
||||
data: { state: "tabs_current" } satisfies RouteDataProperties,
|
||||
data: { elevation: 0 } satisfies RouteDataProperties,
|
||||
runGuardsAndResolvers: "always",
|
||||
},
|
||||
...extensionRefreshSwap(VaultFilterComponent, VaultV2Component, {
|
||||
path: "vault",
|
||||
canActivate: [authGuard],
|
||||
canDeactivate: [clearVaultStateGuard],
|
||||
data: { state: "tabs_vault" } satisfies RouteDataProperties,
|
||||
data: { elevation: 0 } satisfies RouteDataProperties,
|
||||
}),
|
||||
...extensionRefreshSwap(GeneratorComponent, CredentialGeneratorComponent, {
|
||||
path: "generator",
|
||||
canActivate: [authGuard],
|
||||
data: { state: "tabs_generator" } satisfies RouteDataProperties,
|
||||
data: { elevation: 0 } satisfies RouteDataProperties,
|
||||
}),
|
||||
...extensionRefreshSwap(SettingsComponent, SettingsV2Component, {
|
||||
path: "settings",
|
||||
canActivate: [authGuard],
|
||||
data: { state: "tabs_settings" } satisfies RouteDataProperties,
|
||||
data: { elevation: 0 } satisfies RouteDataProperties,
|
||||
}),
|
||||
...extensionRefreshSwap(SendGroupingsComponent, SendV2Component, {
|
||||
path: "send",
|
||||
canActivate: [authGuard],
|
||||
data: { state: "tabs_send" } satisfies RouteDataProperties,
|
||||
data: { elevation: 0 } satisfies RouteDataProperties,
|
||||
}),
|
||||
],
|
||||
}),
|
||||
{
|
||||
path: "account-switcher",
|
||||
component: AccountSwitcherComponent,
|
||||
data: { state: "account-switcher", doNotSaveUrl: true } satisfies RouteDataProperties,
|
||||
data: { elevation: 4, doNotSaveUrl: true } satisfies RouteDataProperties,
|
||||
},
|
||||
{
|
||||
path: "trash",
|
||||
component: TrashComponent,
|
||||
canActivate: [authGuard],
|
||||
data: { state: "trash" } satisfies RouteDataProperties,
|
||||
data: { elevation: 2 } satisfies RouteDataProperties,
|
||||
},
|
||||
];
|
||||
|
||||
|
@ -38,8 +38,8 @@ import { DesktopSyncVerificationDialogComponent } from "./components/desktop-syn
|
||||
selector: "app-root",
|
||||
styles: [],
|
||||
animations: [routerTransition],
|
||||
template: ` <div [@routerTransition]="getState(o)">
|
||||
<router-outlet #o="outlet"></router-outlet>
|
||||
template: ` <div [@routerTransition]="getRouteElevation(outlet)">
|
||||
<router-outlet #outlet="outlet"></router-outlet>
|
||||
</div>`,
|
||||
})
|
||||
export class AppComponent implements OnInit, OnDestroy {
|
||||
@ -223,23 +223,12 @@ export class AppComponent implements OnInit, OnDestroy {
|
||||
this.destroy$.complete();
|
||||
}
|
||||
|
||||
getState(outlet: RouterOutlet) {
|
||||
getRouteElevation(outlet: RouterOutlet) {
|
||||
if (!this.routerAnimations) {
|
||||
return;
|
||||
} else if (outlet.activatedRouteData.state === "ciphers") {
|
||||
const routeDirection =
|
||||
(window as any).routeDirection != null ? (window as any).routeDirection : "";
|
||||
return (
|
||||
"ciphers_direction=" +
|
||||
routeDirection +
|
||||
"_" +
|
||||
(outlet.activatedRoute.queryParams as any).value.folderId +
|
||||
"_" +
|
||||
(outlet.activatedRoute.queryParams as any).value.collectionId
|
||||
);
|
||||
} else {
|
||||
return outlet.activatedRouteData.state;
|
||||
}
|
||||
|
||||
return outlet.activatedRouteData.elevation;
|
||||
}
|
||||
|
||||
private async recordActivity() {
|
||||
|
Loading…
Reference in New Issue
Block a user