mirror of https://github.com/abpframework/abp.git
10 changed files with 219 additions and 0 deletions
@ -0,0 +1,7 @@ |
|||
{ |
|||
"$schema": "../../../node_modules/ng-packagr/ng-package.schema.json", |
|||
"dest": "../../dist/components/page", |
|||
"lib": { |
|||
"entryFile": "src/public-api.ts" |
|||
} |
|||
} |
|||
@ -0,0 +1,77 @@ |
|||
import { |
|||
Directive, |
|||
TemplateRef, |
|||
ViewContainerRef, |
|||
Input, |
|||
InjectionToken, |
|||
Optional, |
|||
Inject, |
|||
OnInit, |
|||
OnDestroy, |
|||
Injector, |
|||
OnChanges, |
|||
SimpleChanges, |
|||
SimpleChange, |
|||
} from '@angular/core'; |
|||
|
|||
export interface PageRenderStrategy { |
|||
shouldRender(type: string); |
|||
onInit?(type: string, injector: Injector, context?: any); |
|||
onDestroy?(type: string, injector?: Injector, context?: any); |
|||
onContextUpdate?(change: SimpleChange); |
|||
} |
|||
|
|||
export const PAGE_RENDER_STRATEGY = new InjectionToken<PageRenderStrategy>('PAGE_RENDER_STRATEGY'); |
|||
|
|||
@Directive({ selector: '[abpPagePart]' }) |
|||
export class PagePartDirective implements OnInit, OnDestroy, OnChanges { |
|||
hasRendered = false; |
|||
type: string; |
|||
|
|||
@Input() set abpPagePart(type: string) { |
|||
this.type = type; |
|||
const shouldRender = this.shouldRender(type); |
|||
|
|||
if (shouldRender && !this.hasRendered) { |
|||
this.viewContainer.createEmbeddedView(this.templateRef); |
|||
this.hasRendered = true; |
|||
} else if (!shouldRender && this.hasRendered) { |
|||
this.viewContainer.clear(); |
|||
this.hasRendered = false; |
|||
} |
|||
} |
|||
|
|||
@Input('abpPagePartContext') context: any; |
|||
|
|||
constructor( |
|||
private templateRef: TemplateRef<any>, |
|||
private viewContainer: ViewContainerRef, |
|||
@Optional() @Inject(PAGE_RENDER_STRATEGY) private renderLogic: PageRenderStrategy, |
|||
private injector: Injector, |
|||
) {} |
|||
|
|||
ngOnChanges({ context }: SimpleChanges): void { |
|||
if (this.renderLogic?.onContextUpdate) { |
|||
this.renderLogic.onContextUpdate(context); |
|||
} |
|||
} |
|||
|
|||
ngOnInit() { |
|||
if (this.renderLogic?.onInit) { |
|||
this.renderLogic.onInit(this.type, this.injector, this.context); |
|||
} |
|||
} |
|||
|
|||
ngOnDestroy() { |
|||
if (this.renderLogic?.onDestroy) { |
|||
this.renderLogic.onDestroy(this.type, this.injector, this.context); |
|||
} |
|||
} |
|||
|
|||
shouldRender(type: string) { |
|||
if (this.renderLogic) { |
|||
return this.renderLogic.shouldRender(type); |
|||
} |
|||
return true; |
|||
} |
|||
} |
|||
@ -0,0 +1,28 @@ |
|||
import { Component, ViewEncapsulation } from '@angular/core'; |
|||
|
|||
export enum PageParts { |
|||
title = 'PageTitleContainerComponent', |
|||
breadcrumb = 'PageBreadcrumbContainerComponent', |
|||
toolbar = 'PageToolbarContainerComponent', |
|||
} |
|||
|
|||
@Component({ |
|||
selector: 'abp-page-title-container', |
|||
template: ` <ng-content></ng-content> `, |
|||
encapsulation: ViewEncapsulation.None, |
|||
}) |
|||
export class PageTitleContainerComponent {} |
|||
|
|||
@Component({ |
|||
selector: 'abp-page-breadcrumb-container', |
|||
template: ` <ng-content></ng-content> `, |
|||
encapsulation: ViewEncapsulation.None, |
|||
}) |
|||
export class PageBreadcrumbContainerComponent {} |
|||
|
|||
@Component({ |
|||
selector: 'abp-page-toolbar-container', |
|||
template: ` <ng-content></ng-content> `, |
|||
encapsulation: ViewEncapsulation.None, |
|||
}) |
|||
export class PageToolbarContainerComponent {} |
|||
@ -0,0 +1,41 @@ |
|||
<div class="row entry-row"> |
|||
<ng-container *ngIf="titleVisible"> |
|||
<ng-container *ngIf="customTitle; else defaultTitleTemplate"> |
|||
<ng-content select="abp-page-title-container"></ng-content> |
|||
</ng-container> |
|||
</ng-container> |
|||
|
|||
<ng-container *ngIf="breadcrumbVisible"> |
|||
<ng-container *ngIf="customBreadcrumb; else defaultBreadcrumbTemplate"> |
|||
<ng-content select="abp-page-breadcrumb-container"></ng-content> |
|||
</ng-container> |
|||
</ng-container> |
|||
|
|||
<ng-container *ngIf="toolbarVisible"> |
|||
<ng-container *ngIf="customToolbar; else defaultPageToolbarTemplate"> |
|||
<ng-content select="abp-page-toolbar-container"></ng-content> |
|||
</ng-container> |
|||
</ng-container> |
|||
</div> |
|||
|
|||
<ng-content></ng-content> |
|||
|
|||
<ng-template #defaultTitleTemplate> |
|||
<div class="col-auto" *abpPagePart="pageParts.title"> |
|||
<h1 class="content-header-title"> |
|||
{{ title }} |
|||
</h1> |
|||
</div> |
|||
</ng-template> |
|||
|
|||
<ng-template #defaultBreadcrumbTemplate> |
|||
<div class="col-lg-auto pl-lg-0" *abpPagePart="pageParts.breadcrumb"> |
|||
<abp-breadcrumb></abp-breadcrumb> |
|||
</div> |
|||
</ng-template> |
|||
|
|||
<ng-template #defaultPageToolbarTemplate> |
|||
<div class="col" *abpPagePart="pageParts.toolbar; context: record"> |
|||
<abp-page-toolbar [record]="record"></abp-page-toolbar> |
|||
</div> |
|||
</ng-template> |
|||
@ -0,0 +1,32 @@ |
|||
import { Component, Input, ViewEncapsulation, ContentChild } from '@angular/core'; |
|||
import { |
|||
PageTitleContainerComponent, |
|||
PageBreadcrumbContainerComponent, |
|||
PageToolbarContainerComponent, |
|||
PageParts, |
|||
} from './page-parts.component'; |
|||
|
|||
@Component({ |
|||
selector: 'abp-page', |
|||
templateUrl: './page.component.html', |
|||
encapsulation: ViewEncapsulation.None, |
|||
}) |
|||
export class PageComponent { |
|||
@Input() title: string; |
|||
@Input() record: any; |
|||
|
|||
@Input() titleVisible = true; |
|||
@Input() breadcrumbVisible = true; |
|||
@Input() toolbarVisible = true; |
|||
|
|||
pageParts = { |
|||
title: PageParts.title, |
|||
breadcrumb: PageParts.breadcrumb, |
|||
toolbar: PageParts.toolbar, |
|||
}; |
|||
|
|||
@ContentChild(PageTitleContainerComponent) customTitle: PageTitleContainerComponent; |
|||
@ContentChild(PageBreadcrumbContainerComponent) |
|||
customBreadcrumb: PageBreadcrumbContainerComponent; |
|||
@ContentChild(PageToolbarContainerComponent) customToolbar: PageToolbarContainerComponent; |
|||
} |
|||
@ -0,0 +1,27 @@ |
|||
import { NgModule } from '@angular/core'; |
|||
import { CommonModule } from '@angular/common'; |
|||
import { UiExtensionsModule } from '@abp/ng.theme.shared/extensions'; |
|||
import { ThemeSharedModule } from '@abp/ng.theme.shared'; |
|||
import { CoreModule } from '@abp/ng.core'; |
|||
import { PageComponent } from './page.component'; |
|||
import { |
|||
PageTitleContainerComponent, |
|||
PageBreadcrumbContainerComponent, |
|||
PageToolbarContainerComponent, |
|||
} from './page-parts.component'; |
|||
import { PagePartDirective } from './page-part.directive'; |
|||
|
|||
const exportedDeclarations = [ |
|||
PageComponent, |
|||
PageTitleContainerComponent, |
|||
PageBreadcrumbContainerComponent, |
|||
PageToolbarContainerComponent, |
|||
PagePartDirective, |
|||
]; |
|||
|
|||
@NgModule({ |
|||
declarations: [...exportedDeclarations], |
|||
imports: [CommonModule, UiExtensionsModule, CoreModule, ThemeSharedModule], |
|||
exports: [...exportedDeclarations], |
|||
}) |
|||
export class PageModule {} |
|||
@ -0,0 +1,4 @@ |
|||
export * from './page.module'; |
|||
export * from './page-part.directive'; |
|||
export * from './page-parts.component'; |
|||
export * from './page.component'; |
|||
Loading…
Reference in new issue