Skip to content
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
4 changes: 3 additions & 1 deletion examples/app1/src/app/dashboard/dashboard.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ <h5 class="same-name portal-special">count: {{ counter.count }}</h5>
<section-card class="mt-4" title="Open app1's detail">
<form class="mb-2" thyForm thyLayout="inline">
<thy-form-group thyLabelText="Size:">
<thy-custom-select thyPlaceHolder="选择弹框大小" name="size" [(ngModel)]="size" style="width:500px;">
<thy-custom-select thyPlaceHolder="选择弹框大小" name="size" [(ngModel)]="size" style="width: 500px">
<thy-option thyValue="sm" thyLabelText="小" [thyShowOptionCustom]="true">
<span class="same-name">小 </span>
</thy-option>
Expand Down Expand Up @@ -49,3 +49,5 @@ <h5 class="same-name portal-special">count: {{ counter.count }}</h5>
<section-card class="mt-4" title="Load app1's assets image">
<img width="100" src="/static/app1/assets/github.png" />
</section-card>

<ng-container *planetComponentOutlet="'app-portal-custom'; app: 'portal'"> </ng-container>
2 changes: 2 additions & 0 deletions examples/portal/src/app/about/about.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,5 @@
<section-card class="mt-5 same-name" title="同名样式">
<span class="text-desc">同名样式: </span> <span class="text-danger">color: blue, font-size:12px</span>
</section-card>

<app-portal-custom></app-portal-custom>
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<section-card class="mt-5 portal-special" title="Portal Component">
<span class="text-desc">I am Portal's Component</span>
</section-card>
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { Component, OnInit } from '@angular/core';

@Component({
selector: 'app-portal-custom',
templateUrl: './portal-custom.component.html',
styleUrls: ['./portal-custom.component.scss']
})
export class PortalCustomComponent implements OnInit {
constructor() {}

ngOnInit() {}
}
17 changes: 10 additions & 7 deletions examples/portal/src/app/app.component.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { Component, OnInit, ChangeDetectorRef, ApplicationRef, NgZone, HostBinding } from '@angular/core';
import { Planet, SwitchModes, GlobalEventDispatcher, ApplicationStatus, PlanetApplication } from '@worktile/planet';
import { Router, NavigationEnd, ActivatedRoute } from '@angular/router';
import { Component, OnInit } from '@angular/core';
import { AppRootContext } from '@demo/common';
import { GlobalEventDispatcher, Planet, PlanetComponentLoader, SwitchModes } from '@worktile/planet';
import { debug } from 'debug';
import { ThyDialog } from 'ngx-tethys/dialog';
import { ADetailComponent } from './a-detail/a-detail.component';
import { ThyNotifyService } from 'ngx-tethys/notify';
import { AppRootContext } from '@demo/common';
import { ADetailComponent } from './a-detail/a-detail.component';
import { PortalCustomComponent } from './about/components/portal-custom.component';
import { CustomSettingsService } from './custom-settings.service';
import { debug } from 'debug';

@Component({
selector: 'app-root',
Expand All @@ -29,7 +29,8 @@ export class AppComponent implements OnInit {
private globalEventDispatcher: GlobalEventDispatcher,
private thyDialog: ThyDialog,
private thyNotify: ThyNotifyService,
public appRootContext: AppRootContext
public appRootContext: AppRootContext,
private planetComponentLoader: PlanetComponentLoader
) {}

ngOnInit() {
Expand Down Expand Up @@ -117,5 +118,7 @@ export class AppComponent implements OnInit {
this.activeAppNames = event.shouldLoadApps.map(item => item.name);
console.log(`active app names: ${this.activeAppNames.join(',')}`);
});

this.planetComponentLoader.register([PortalCustomComponent]);
}
}
35 changes: 18 additions & 17 deletions examples/portal/src/app/app.module.ts
Original file line number Diff line number Diff line change
@@ -1,36 +1,37 @@
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { BrowserModule, DomSanitizer } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { NgModule } from '@angular/core';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { AboutComponent } from './about/about.component';
import { Overlay } from '@angular/cdk/overlay';
import { FormsModule } from '@angular/forms';
import { NavigationStart, Router } from '@angular/router';
import { AppRootContext, DemoCommonModule, OVERLAY_PROVIDER } from '@demo/common';
import { NgxPlanetModule } from '@worktile/planet';
import { ThyIconModule, ThyIconRegistry } from 'ngx-tethys/icon';
import { ThyButtonModule } from 'ngx-tethys/button';
import { ThyCheckboxModule } from 'ngx-tethys/checkbox';
import { ThyDialogModule } from 'ngx-tethys/dialog';
import { ThyDropdownModule } from 'ngx-tethys/dropdown';
import { ThyFormModule } from 'ngx-tethys/form';
import { ThyIconModule, ThyIconRegistry } from 'ngx-tethys/icon';
import { ThyLayoutModule } from 'ngx-tethys/layout';
import { ThyTableModule } from 'ngx-tethys/table';
import { ThyNotifyModule } from 'ngx-tethys/notify';
import { ThyLoadingModule } from 'ngx-tethys/loading';
import { ThyNavModule } from 'ngx-tethys/nav';
import { ThyDropdownModule } from 'ngx-tethys/dropdown';
import { ThyTooltipModule } from 'ngx-tethys/tooltip';
import { ThyNotifyModule } from 'ngx-tethys/notify';
import { ThyPopoverModule } from 'ngx-tethys/popover';
import { ThyFormModule } from 'ngx-tethys/form';
import { ThyRadioModule } from 'ngx-tethys/radio';
import { ThyCheckboxModule } from 'ngx-tethys/checkbox';
import { ThyTableModule } from 'ngx-tethys/table';
import { ThyTooltipModule } from 'ngx-tethys/tooltip';
import { ADetailComponent } from './a-detail/a-detail.component';
import { SettingsComponent } from './settings/settings.component';
import { AppRootContext, DemoCommonModule, OVERLAY_PROVIDER } from '@demo/common';
import { FormsModule } from '@angular/forms';
import { Overlay } from '@angular/cdk/overlay';
import { AboutComponent } from './about/about.component';
import { PortalCustomComponent } from './about/components/portal-custom.component';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { AppOverlay } from './overlay';
import { NavigationStart, Router } from '@angular/router';
import { SettingsComponent } from './settings/settings.component';

@NgModule({
declarations: [AppComponent, AboutComponent, SettingsComponent, ADetailComponent],
declarations: [AppComponent, AboutComponent, PortalCustomComponent, SettingsComponent, ADetailComponent],
imports: [
BrowserModule,
BrowserAnimationsModule,
Expand Down
5 changes: 1 addition & 4 deletions packages/planet/src/application/ng-planet-application-ref.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ import { Router, NavigationEnd } from '@angular/router';
import { take } from 'rxjs/operators';
import { Observable, from } from 'rxjs';
import { PlanetPortalApplication } from './portal-application';
import { PlantComponentConfig } from '../component/plant-component.config';
import { PlanetComponentRef } from '../component/planet-component-ref';
import { PlantComponentFactory } from '../component/planet-component-types';
import { getTagNameByTemplate } from '../helpers';
import { getSandboxInstance, Sandbox } from '../sandbox/';
import { PlanetApplicationRef } from './planet-application-ref';
Expand All @@ -27,8 +26,6 @@ export type BootstrapAppModule = NgBootstrapAppModule;
*/
export interface BootstrapOptions extends NgBootstrapOptions {}

export type PlantComponentFactory = <TData, TComp>(componentName: string, config: PlantComponentConfig<TData>) => PlanetComponentRef<TComp>;

export class NgPlanetApplicationRef implements PlanetApplicationRef {
private injector?: EnvironmentInjector;
private appRef?: ApplicationRef;
Expand Down
9 changes: 9 additions & 0 deletions packages/planet/src/application/portal-application.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,13 @@ describe('PlanetPortalApplication', () => {
expect(navigateByUrlSpy).toHaveBeenCalled();
expect(navigateByUrlSpy).toHaveBeenCalledWith('/app1/dashboard', { skipLocationChange: true });
});

it(`should run registerComponentFactory & getComponentFactory`, () => {
const spy = jasmine.createSpy('spy');
expect(spy).not.toHaveBeenCalled();
planetPortalApplication.registerComponentFactory(spy);
const componentFactory = planetPortalApplication.getComponentFactory();
componentFactory('', {} as any);
expect(spy).toHaveBeenCalled();
});
});
11 changes: 11 additions & 0 deletions packages/planet/src/application/portal-application.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Router, UrlTree, NavigationExtras } from '@angular/router';
import { NgZone, Injector, ApplicationRef } from '@angular/core';
import { PlantComponentFactory } from '../component/planet-component-types';
import { GlobalEventDispatcher } from '../global-event-dispatcher';

export class PlanetPortalApplication<TData = any> {
Expand All @@ -9,6 +10,8 @@ export class PlanetPortalApplication<TData = any> {
ngZone?: NgZone;
globalEventDispatcher?: GlobalEventDispatcher;
data?: TData;
name?: string = 'portal';
private componentFactory?: PlantComponentFactory;

navigateByUrl(url: string | UrlTree, extras?: NavigationExtras): Promise<boolean> {
return this.ngZone!.run(() => {
Expand All @@ -25,4 +28,12 @@ export class PlanetPortalApplication<TData = any> {
tick() {
this.applicationRef!.tick();
}

getComponentFactory() {
return this.componentFactory;
}

registerComponentFactory(componentFactory: PlantComponentFactory) {
this.componentFactory = componentFactory;
}
}
6 changes: 4 additions & 2 deletions packages/planet/src/component/planet-component-loader.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { TestBed, tick, fakeAsync } from '@angular/core/testing';
import { Compiler, Injector, Type, NgModuleRef, ApplicationRef } from '@angular/core';
import { Compiler, Injector, Type, NgModuleRef } from '@angular/core';
import { app1Name, App1Module, App1ProjectsComponent } from '../testing/app1.module';
import { app2Name, App2Module } from '../testing/app2.module';
import { PlanetPortalApplication } from '../application/portal-application';
Expand All @@ -17,7 +17,7 @@ import {
} from '../global-planet';
import { Planet } from 'ngx-planet/planet';
import { RouterTestingModule } from '@angular/router/testing';
import { PlanetComponentRef } from './planet-component-ref';
import { PlanetComponentRef } from './planet-component-types';
import { NgPlanetApplicationRef } from '../application/ng-planet-application-ref';

describe('PlanetComponentLoader', () => {
Expand Down Expand Up @@ -226,6 +226,8 @@ describe('PlanetComponentLoader', () => {
expect(App1ProjectsComponent.state).toEqual('destroyed');
});
}));

it('should child app load portal component success', () => {});
});

function registerAppComponents(appModuleRef: NgModuleRef<any>) {
Expand Down
83 changes: 52 additions & 31 deletions packages/planet/src/component/planet-component-loader.ts
Original file line number Diff line number Diff line change
@@ -1,33 +1,35 @@
import { DOCUMENT } from '@angular/common';
import {
Injectable,
ApplicationRef,
NgModuleRef,
NgZone,
ComponentRef,
ElementRef,
EmbeddedViewRef,
EnvironmentInjector,
Inject,
Injectable,
Injector,
createComponent,
NgModuleRef,
NgZone,
TemplateRef,
Type,
ComponentRef,
EmbeddedViewRef,
reflectComponentType,
EnvironmentInjector,
TemplateRef
createComponent,
reflectComponentType
} from '@angular/core';
import { PlanetPortalApplication } from 'ngx-planet';
import { Observable, of, timer } from 'rxjs';
import { delayWhen, map, shareReplay } from 'rxjs/operators';
import { NgPlanetApplicationRef } from '../application/ng-planet-application-ref';
import { PlanetApplicationRef } from '../application/planet-application-ref';
import { PlanetComponentRef } from './planet-component-ref';
import { PlantComponentConfig } from './plant-component.config';
import { coerceArray } from '../helpers';
import { map, shareReplay, delayWhen } from 'rxjs/operators';
import { of, Observable, timer } from 'rxjs';
import { DOCUMENT } from '@angular/common';
import {
getApplicationLoader,
getApplicationService,
getBootstrappedPlanetApplicationRef,
getPlanetApplicationRef,
getBootstrappedPlanetApplicationRef
globalPlanet
} from '../global-planet';
import { NgPlanetApplicationRef } from '../application/ng-planet-application-ref';
import { coerceArray } from '../helpers';
import { PlanetComponentRef } from './planet-component-types';
import { PlantComponentConfig } from './plant-component.config';

const componentWrapperClass = 'planet-component-wrapper';

Expand Down Expand Up @@ -158,7 +160,15 @@ export class PlanetComponentLoader {

private registerComponentFactory(componentOrComponents: PlanetComponent | PlanetComponent[]) {
const app = this.ngModuleRef.instance.appName;
this.getPlantAppRef(app).subscribe((appRef: NgPlanetApplicationRef) => {
let appRef$: Observable<NgPlanetApplicationRef | PlanetPortalApplication>;

if (app) {
appRef$ = this.getPlantAppRef(app) as Observable<NgPlanetApplicationRef>;
} else {
appRef$ = of(globalPlanet.portalApplication);
}

appRef$.subscribe(appRef => {
appRef.registerComponentFactory((componentName: string, config: PlantComponentConfig<any>) => {
const components = coerceArray(componentOrComponents);
const planetComponent = components.find(item => {
Expand All @@ -170,7 +180,7 @@ export class PlanetComponentLoader {
return this.ngZone.run(() => {
const componentRef = this.attachComponent<any>(
isComponentType(planetComponent) ? planetComponent : planetComponent.component,
appRef.appModuleRef.injector,
appRef instanceof NgPlanetApplicationRef ? appRef.appModuleRef.injector : this.ngModuleRef.injector,
config
);
return componentRef;
Expand All @@ -182,26 +192,37 @@ export class PlanetComponentLoader {
});
}

register(components: PlanetComponent | PlanetComponent[]) {
setTimeout(() => {
register(components: PlanetComponent | PlanetComponent[], immediate?: boolean) {
if (immediate) {
this.registerComponentFactory(components);
});
} else {
setTimeout(() => {
this.registerComponentFactory(components);
});
}
}

load<TComp = unknown, TData = unknown>(
app: string,
componentName: string,
config: PlantComponentConfig<TData>
): Observable<PlanetComponentRef<TComp>> {
const result = this.getPlantAppRef(app).pipe(
delayWhen((appRef: NgPlanetApplicationRef) => {
if (appRef.getComponentFactory()) {
return of('');
} else {
// Because register use 'setTimeout',so timer 20
return timer(20);
}
}),
let appRef$: Observable<NgPlanetApplicationRef | PlanetPortalApplication>;
if (app === globalPlanet.portalApplication.name) {
appRef$ = of(globalPlanet.portalApplication);
} else {
appRef$ = this.getPlantAppRef(app).pipe(
delayWhen((appRef: NgPlanetApplicationRef) => {
if (appRef.getComponentFactory()) {
return of('');
} else {
// Because register use 'setTimeout',so timer 20
return timer(20);
}
})
);
}
const result = appRef$.pipe(
map(appRef => {
const componentFactory = appRef.getComponentFactory();
if (componentFactory) {
Expand Down
11 changes: 3 additions & 8 deletions packages/planet/src/component/planet-component-outlet.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,12 @@ import { Component, DebugElement, OnInit } from '@angular/core';
import { PlanetComponentLoader } from './planet-component-loader';
import { PlantComponentConfig } from './plant-component.config';
import { Observable, Subject } from 'rxjs';
import { PlanetComponentRef } from './planet-component-ref';
import { PlanetComponentRef } from './planet-component-types';
import { tap } from 'rxjs/operators';

@Component({
selector: 'planet-component-outlet-basic-test',
template: `
<ng-container
*planetComponentOutlet="componentName; app: 'app2'; initialState: { term: 'From Test' }"
></ng-container>
`
template: ` <ng-container *planetComponentOutlet="componentName; app: 'app2'; initialState: { term: 'From Test' }"></ng-container> `
})
export class PlanetComponentOutletBasicTestComponent implements OnInit {
componentName = 'project1';
Expand All @@ -32,8 +28,7 @@ export class PlanetComponentOutletBasicTestComponent implements OnInit {
planetComponentOutlet="project1"
planetComponentOutletApp="app2"
planetComponentOutletInitialState="{ term: 'From Test' }"
(planetComponentLoaded)="componentLoaded($event)"
></ng-container>
(planetComponentLoaded)="componentLoaded($event)"></ng-container>
`
})
export class PlanetComponentOutletGeneralTestComponent {
Expand Down
2 changes: 1 addition & 1 deletion packages/planet/src/component/planet-component-outlet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { PlanetComponentLoader } from './planet-component-loader';
import { PlanetComponentRef } from './planet-component-ref';
import { PlanetComponentRef } from './planet-component-types';
import { PlantComponentProjectableNode } from './plant-component.config';

@Directive({
Expand Down
9 changes: 0 additions & 9 deletions packages/planet/src/component/planet-component-ref.ts

This file was deleted.

Loading