Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Angular - Account Pages Sidebar Flicker on Reload #19413

Merged
merged 6 commits into from
Mar 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions npm/ng-packs/apps/dev-app/src/app/home/home.component.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
import { AuthService } from '@abp/ng.core';
import { Component } from '@angular/core';
import { Component, inject } from '@angular/core';

@Component({
selector: 'app-home',
templateUrl: './home.component.html',
})
export class HomeComponent {
protected readonly authService = inject(AuthService);

loading = false;
get hasLoggedIn(): boolean {
return this.authService.isAuthenticated;
}

constructor(private authService: AuthService) {}
login() {
this.loading = true;
this.authService.navigateToLogin();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { AuthService, ConfigStateService } from '@abp/ng.core';
import { ToasterService } from '@abp/ng.theme.shared';
import { Component, Injector, OnInit } from '@angular/core';
import { Component, Injector, OnInit, inject } from '@angular/core';
import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms';
import { throwError } from 'rxjs';
import { catchError, finalize } from 'rxjs/operators';
Expand All @@ -14,6 +14,12 @@ const { maxLength, required } = Validators;
templateUrl: './login.component.html',
})
export class LoginComponent implements OnInit {
protected injector = inject(Injector);
protected fb = inject(UntypedFormBuilder);
protected toasterService = inject(ToasterService);
protected authService = inject(AuthService);
protected configState = inject(ConfigStateService);

form!: UntypedFormGroup;

inProgress?: boolean;
Expand All @@ -22,14 +28,6 @@ export class LoginComponent implements OnInit {

authWrapperKey = eAccountComponents.AuthWrapper;

constructor(
protected injector: Injector,
protected fb: UntypedFormBuilder,
protected toasterService: ToasterService,
protected authService: AuthService,
protected configState: ConfigStateService,
) {}

ngOnInit() {
this.init();
this.buildForm();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,74 +1,66 @@
import {
Component,
inject,
isDevMode,
OnInit,
Optional,
SkipSelf,
Type
} from '@angular/core';
import {ActivatedRoute, Router} from '@angular/router';
import {eLayoutType} from '../enums/common';
import {ABP} from '../models';
import {ReplaceableComponents} from '../models/replaceable-components';
import {LocalizationService} from '../services/localization.service';
import {ReplaceableComponentsService} from '../services/replaceable-components.service';
import {RouterEvents} from '../services/router-events.service';
import {RoutesService} from '../services/routes.service';
import {SubscriptionService} from '../services/subscription.service';
import {findRoute, getRoutePath} from '../utils/route-utils';
import {TreeNode} from '../utils/tree-utils';
import {DYNAMIC_LAYOUTS_TOKEN} from "../tokens/dynamic-layout.token";
import { Component, inject, isDevMode, OnInit, Optional, SkipSelf, Type } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { eLayoutType } from '../enums/common';
import { ABP } from '../models';
import { ReplaceableComponents } from '../models/replaceable-components';
import { LocalizationService } from '../services/localization.service';
import { ReplaceableComponentsService } from '../services/replaceable-components.service';
import { RouterEvents } from '../services/router-events.service';
import { RoutesService } from '../services/routes.service';
import { SubscriptionService } from '../services/subscription.service';
import { findRoute, getRoutePath } from '../utils/route-utils';
import { TreeNode } from '../utils/tree-utils';
import { DYNAMIC_LAYOUTS_TOKEN } from '../tokens/dynamic-layout.token';
import { EnvironmentService } from '../services';

@Component({
selector: 'abp-dynamic-layout',
template: `
<ng-container *ngIf="isLayoutVisible" [ngComponentOutlet]="layout"></ng-container> `,
template: ` <ng-container *ngIf="isLayoutVisible" [ngComponentOutlet]="layout"></ng-container> `,
providers: [SubscriptionService],
})
export class DynamicLayoutComponent implements OnInit {
layout?: Type<any>;
layoutKey?: eLayoutType;
readonly layouts = inject(DYNAMIC_LAYOUTS_TOKEN)
readonly layouts = inject(DYNAMIC_LAYOUTS_TOKEN);
isLayoutVisible = true;

private readonly router = inject(Router);
private readonly route = inject(ActivatedRoute);
private readonly routes = inject(RoutesService);
private localizationService = inject(LocalizationService)
private replaceableComponents = inject(ReplaceableComponentsService)
private subscription = inject(SubscriptionService)
private routerEvents = inject(RouterEvents)
protected readonly router = inject(Router);
protected readonly route = inject(ActivatedRoute);
protected readonly routes = inject(RoutesService);
protected readonly localizationService = inject(LocalizationService);
protected readonly replaceableComponents = inject(ReplaceableComponentsService);
protected readonly subscription = inject(SubscriptionService);
protected readonly routerEvents = inject(RouterEvents);
protected readonly environment = inject(EnvironmentService);


constructor(
@Optional() @SkipSelf() dynamicLayoutComponent: DynamicLayoutComponent,
) {
constructor(@Optional() @SkipSelf() dynamicLayoutComponent: DynamicLayoutComponent) {
if (dynamicLayoutComponent) {
if (isDevMode()) console.warn('DynamicLayoutComponent must be used only in AppComponent.');
return;
}
this.checkLayoutOnNavigationEnd();
this.listenToLanguageChange();
}

ngOnInit(): void {
if (this.layout) {
return;
}
this.getLayout()

const { oAuthConfig } = this.environment.getEnvironment();
if (oAuthConfig.responseType === 'code') {
this.getLayout();
}
}

private checkLayoutOnNavigationEnd() {
const navigationEnd$ = this.routerEvents.getNavigationEvents('End');
this.subscription.addOne(navigationEnd$, () => this.getLayout());
}


private getLayout() {
let expectedLayout = this.getExtractedLayout();


if (!expectedLayout) expectedLayout = eLayoutType.empty;

if (this.layoutKey === expectedLayout) return;
Expand All @@ -84,15 +76,11 @@ export class DynamicLayoutComponent implements OnInit {
}

private getExtractedLayout() {
const routeData = (this.route.snapshot.data || {});
const routeData = this.route.snapshot.data || {};
let expectedLayout = routeData['layout'] as eLayoutType;

if (expectedLayout) {
return expectedLayout;
}

let node = findRoute(this.routes, getRoutePath(this.router));
node = {parent: node} as TreeNode<ABP.Route>;
node = { parent: node } as TreeNode<ABP.Route>;

while (node.parent) {
node = node.parent;
Expand All @@ -108,12 +96,12 @@ export class DynamicLayoutComponent implements OnInit {
showLayoutNotFoundError(layoutName: string) {
let message = `Layout ${layoutName} not found.`;
if (layoutName === 'account') {
message = 'Account layout not found. Please check your configuration. If you are using LeptonX, please make sure you have added "AccountLayoutModule.forRoot()" to your app.module configuration.';
message =
'Account layout not found. Please check your configuration. If you are using LeptonX, please make sure you have added "AccountLayoutModule.forRoot()" to your app.module configuration.';
}
console.warn(message);
}


private listenToLanguageChange() {
this.subscription.addOne(this.localizationService.languageChange$, () => {
this.isLayoutVisible = false;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,19 @@
import {eLayoutType, SubscriptionService} from '@abp/ng.core';
import { eLayoutType, SubscriptionService } from '@abp/ng.core';
import { collapseWithMargin, slideFromBottom } from '@abp/ng.theme.shared';
import {AfterViewInit, Component} from '@angular/core';
import { AfterViewInit, Component, inject } from '@angular/core';
import { LayoutService } from '../../services/layout.service';


@Component({
selector: 'abp-layout-application',
templateUrl: './application-layout.component.html',
animations: [slideFromBottom, collapseWithMargin],
providers: [LayoutService, SubscriptionService],
})
export class ApplicationLayoutComponent implements AfterViewInit {
public readonly service = inject(LayoutService);
// required for dynamic component
static type = eLayoutType.application;

constructor(public service: LayoutService) {}

ngAfterViewInit() {
this.service.subscribeWindowSize();
}
Expand Down
Loading