mirror of https://github.com/abpframework/abp
- configure route providerspull/9395/head
parent
50f91f7f56
commit
e915a9132c
@ -0,0 +1,62 @@
|
||||
<nav
|
||||
class="navbar navbar-expand-lg navbar-dark bg-dark shadow-sm flex-column flex-md-row mb-4"
|
||||
id="main-navbar"
|
||||
style="min-height: 4rem"
|
||||
>
|
||||
<div class="container">
|
||||
<abp-logo *abpReplaceableTemplate="{ componentKey: service.logoComponentKey }"></abp-logo>
|
||||
<button
|
||||
class="navbar-toggler"
|
||||
type="button"
|
||||
[attr.aria-expanded]="!service.isCollapsed"
|
||||
(click)="service.isCollapsed = !service.isCollapsed"
|
||||
>
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div
|
||||
class="navbar-collapse"
|
||||
[class.overflow-hidden]="service.smallScreen"
|
||||
id="main-navbar-collapse"
|
||||
>
|
||||
<ng-container *ngTemplateOutlet="!service.smallScreen ? navigations : null"></ng-container>
|
||||
|
||||
<div
|
||||
*ngIf="service.smallScreen"
|
||||
[@collapseWithMargin]="service.isCollapsed ? 'collapsed' : 'expanded'"
|
||||
>
|
||||
<ng-container *ngTemplateOutlet="navigations"></ng-container>
|
||||
</div>
|
||||
|
||||
<ng-template #navigations>
|
||||
<abp-routes
|
||||
*abpReplaceableTemplate="{
|
||||
componentKey: service.routesComponentKey,
|
||||
inputs: {
|
||||
smallScreen: { value: service.smallScreen }
|
||||
}
|
||||
}"
|
||||
class="mx-auto"
|
||||
[smallScreen]="service.smallScreen"
|
||||
></abp-routes>
|
||||
|
||||
<abp-nav-items
|
||||
*abpReplaceableTemplate="{
|
||||
componentKey: service.navItemsComponentKey
|
||||
}"
|
||||
></abp-nav-items>
|
||||
</ng-template>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<!-- [@slideFromBottom]="outlet.isActivated && outlet.activatedRoute?.routeConfig?.path" TODO: throws ExpressionChangedAfterItHasBeenCheck when animation is active. It should be fixed -->
|
||||
<div class="container">
|
||||
<abp-page-alert-container></abp-page-alert-container>
|
||||
<abp-auth-wrapper
|
||||
*abpReplaceableTemplate="{
|
||||
componentKey: authWrapperKey
|
||||
}"
|
||||
>
|
||||
<router-outlet #outlet="outlet"></router-outlet>
|
||||
</abp-auth-wrapper>
|
||||
</div>
|
@ -1,14 +1,22 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { eLayoutType } from '@abp/ng.core';
|
||||
import { AfterViewInit, Component } from '@angular/core';
|
||||
import { eLayoutType, SubscriptionService } from '@abp/ng.core';
|
||||
|
||||
import { LayoutService } from '../../services/layout.service';
|
||||
|
||||
@Component({
|
||||
selector: 'abp-layout-account',
|
||||
template: `
|
||||
<router-outlet></router-outlet>
|
||||
<abp-confirmation></abp-confirmation>
|
||||
`,
|
||||
templateUrl: './account-layout.component.html',
|
||||
providers: [LayoutService, SubscriptionService],
|
||||
})
|
||||
export class AccountLayoutComponent {
|
||||
export class AccountLayoutComponent implements AfterViewInit {
|
||||
// required for dynamic component
|
||||
static type = eLayoutType.account;
|
||||
|
||||
authWrapperKey = 'Account.AuthWrapperComponent';
|
||||
|
||||
constructor(public service: LayoutService) {}
|
||||
|
||||
ngAfterViewInit() {
|
||||
this.service.subscribeWindowSize();
|
||||
}
|
||||
}
|
||||
|
@ -1,16 +1,18 @@
|
||||
<div class="row">
|
||||
<div class="mx-auto col col-md-5">
|
||||
<ng-container *ngIf="(isMultiTenancyEnabled$ | async) && isTenantBoxVisible">
|
||||
<abp-tenant-box *abpReplaceableTemplate="{ componentKey: tenantBoxKey }"></abp-tenant-box>
|
||||
<ng-container *ngIf="(service.isMultiTenancyEnabled$ | async) && service.isTenantBoxVisible">
|
||||
<abp-tenant-box
|
||||
*abpReplaceableTemplate="{ componentKey: service.tenantBoxKey }"
|
||||
></abp-tenant-box>
|
||||
</ng-container>
|
||||
|
||||
<div class="abp-account-container">
|
||||
<div
|
||||
*ngIf="enableLocalLogin$ | async; else disableLocalLoginTemplate"
|
||||
*ngIf="service.enableLocalLogin$ | async; else disableLocalLoginTemplate"
|
||||
class="card mt-3 shadow-sm rounded"
|
||||
>
|
||||
<div class="card-body p-5">
|
||||
<router-outlet></router-outlet>
|
||||
<ng-content></ng-content>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -0,0 +1,25 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { AuthWrapperComponent } from './auth-wrapper.component';
|
||||
|
||||
describe('AuthWrapperComponent', () => {
|
||||
let component: AuthWrapperComponent;
|
||||
let fixture: ComponentFixture<AuthWrapperComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ AuthWrapperComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(AuthWrapperComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
@ -0,0 +1,13 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { AuthWrapperService } from '@abp/ng.account-core';
|
||||
|
||||
@Component({
|
||||
selector: 'abp-auth-wrapper',
|
||||
templateUrl: './auth-wrapper.component.html',
|
||||
providers: [AuthWrapperService],
|
||||
})
|
||||
export class AuthWrapperComponent implements OnInit {
|
||||
constructor(public service: AuthWrapperService) {}
|
||||
|
||||
ngOnInit(): void {}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { TenantBoxComponent } from './tenant-box.component';
|
||||
|
||||
describe('TenantBoxComponent', () => {
|
||||
let component: TenantBoxComponent;
|
||||
let fixture: ComponentFixture<TenantBoxComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ TenantBoxComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(TenantBoxComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
@ -0,0 +1,13 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { TenantBoxService } from '@abp/ng.account-core';
|
||||
|
||||
@Component({
|
||||
selector: 'abp-tenant-box',
|
||||
templateUrl: './tenant-box.component.html',
|
||||
providers: [TenantBoxService],
|
||||
})
|
||||
export class TenantBoxComponent implements OnInit {
|
||||
constructor(public service: TenantBoxService) {}
|
||||
|
||||
ngOnInit(): void {}
|
||||
}
|
@ -1,54 +1,21 @@
|
||||
import { eLayoutType, SubscriptionService } from '@abp/ng.core';
|
||||
import { collapseWithMargin, slideFromBottom } from '@abp/ng.theme.shared';
|
||||
import { AfterViewInit, Component, OnDestroy } from '@angular/core';
|
||||
import { fromEvent } from 'rxjs';
|
||||
import { debounceTime } from 'rxjs/operators';
|
||||
import { eThemeBasicComponents } from '../../enums/components';
|
||||
import { AfterViewInit, Component } from '@angular/core';
|
||||
import { LayoutService } from '../../services/layout.service';
|
||||
|
||||
@Component({
|
||||
selector: 'abp-layout-application',
|
||||
templateUrl: './application-layout.component.html',
|
||||
animations: [slideFromBottom, collapseWithMargin],
|
||||
providers: [SubscriptionService],
|
||||
providers: [LayoutService, SubscriptionService],
|
||||
})
|
||||
export class ApplicationLayoutComponent implements AfterViewInit, OnDestroy {
|
||||
export class ApplicationLayoutComponent implements AfterViewInit {
|
||||
// required for dynamic component
|
||||
static type = eLayoutType.application;
|
||||
|
||||
isCollapsed = true;
|
||||
|
||||
smallScreen: boolean; // do not set true or false
|
||||
|
||||
logoComponentKey = eThemeBasicComponents.Logo;
|
||||
|
||||
routesComponentKey = eThemeBasicComponents.Routes;
|
||||
|
||||
navItemsComponentKey = eThemeBasicComponents.NavItems;
|
||||
|
||||
constructor(private subscription: SubscriptionService) {}
|
||||
|
||||
private checkWindowWidth() {
|
||||
setTimeout(() => {
|
||||
if (window.innerWidth < 992) {
|
||||
if (this.smallScreen === false) {
|
||||
this.isCollapsed = false;
|
||||
setTimeout(() => {
|
||||
this.isCollapsed = true;
|
||||
}, 100);
|
||||
}
|
||||
this.smallScreen = true;
|
||||
} else {
|
||||
this.smallScreen = false;
|
||||
}
|
||||
}, 0);
|
||||
}
|
||||
constructor(public service: LayoutService) {}
|
||||
|
||||
ngAfterViewInit() {
|
||||
this.checkWindowWidth();
|
||||
|
||||
const resize$ = fromEvent(window, 'resize').pipe(debounceTime(150));
|
||||
this.subscription.addOne(resize$, () => this.checkWindowWidth());
|
||||
this.service.subscribeWindowSize();
|
||||
}
|
||||
|
||||
ngOnDestroy() {}
|
||||
}
|
||||
|
@ -0,0 +1,43 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { eThemeBasicComponents } from '../enums';
|
||||
import { SubscriptionService } from '@abp/ng.core';
|
||||
import { fromEvent } from 'rxjs';
|
||||
import { debounceTime } from 'rxjs/operators';
|
||||
|
||||
@Injectable()
|
||||
export class LayoutService {
|
||||
isCollapsed = true;
|
||||
|
||||
smallScreen: boolean; // do not set true or false
|
||||
|
||||
logoComponentKey = eThemeBasicComponents.Logo;
|
||||
|
||||
routesComponentKey = eThemeBasicComponents.Routes;
|
||||
|
||||
navItemsComponentKey = eThemeBasicComponents.NavItems;
|
||||
|
||||
constructor(private subscription: SubscriptionService) {}
|
||||
|
||||
private checkWindowWidth() {
|
||||
setTimeout(() => {
|
||||
if (window.innerWidth < 992) {
|
||||
if (this.smallScreen === false) {
|
||||
this.isCollapsed = false;
|
||||
setTimeout(() => {
|
||||
this.isCollapsed = true;
|
||||
}, 100);
|
||||
}
|
||||
this.smallScreen = true;
|
||||
} else {
|
||||
this.smallScreen = false;
|
||||
}
|
||||
}, 0);
|
||||
}
|
||||
|
||||
subscribeWindowSize() {
|
||||
this.checkWindowWidth();
|
||||
|
||||
const resize$ = fromEvent(window, 'resize').pipe(debounceTime(150));
|
||||
this.subscription.addOne(resize$, () => this.checkWindowWidth());
|
||||
}
|
||||
}
|
Loading…
Reference in new issue