Skip to content

Commit

Permalink
refactor(composer): use RenderComponent API in droppable component
Browse files Browse the repository at this point in the history
  • Loading branch information
gund committed Jan 14, 2022
1 parent 8dba993 commit 78bfe38
Show file tree
Hide file tree
Showing 8 changed files with 111 additions and 71 deletions.
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<orc-orchestrator [config]="initialConfig"></orc-orchestrator>
<orc-render-item [item]="initialConfig"></orc-render-item>
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@ import { ComposerDroppableComponent } from '../composer-droppable';
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ComposerCanvasComponent {
initialConfig: OrchestratorConfigItem = ComposerDroppableComponent.getWrapperConfig();
initialConfig = ComposerDroppableComponent.wrapperConfig;
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
ComponentFactory,
ComponentFactoryResolver,
OnInit,
Type,
} from '@angular/core';
import {
ComponentLocatorService,
Expand All @@ -17,6 +18,8 @@ import {
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ComposerComponentsComponent implements OnInit {
static BLACKLIST_COMPONENTS: Type<any>[] = [];

componentsInfo: ComponentFactory<OrchestratorDynamicComponent>[] = [];

constructor(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,29 +1,11 @@
import { Injectable } from '@angular/core';
import {
Option,
OptionRequired,
OrchestratorConfigItem,
OrchestratorDynamicComponentType,
} from '@orchestrator/core';
import { Option, OrchestratorConfigItem } from '@orchestrator/core';

/**
* @internal
*/
@Injectable({ providedIn: 'root' })
export class ComposerDroppableConfig<C = any>
implements OrchestratorConfigItem<C> {
@OptionRequired()
component: string | OrchestratorDynamicComponentType<C>;

@Option()
config?: C;

@Option()
id?: string;

@Option()
classes?: string | string[] | { [name: string]: boolean };

@Option()
attributes?: { [attr: string]: string };

export class ComposerDroppableConfig<C = any> {
@Option()
handlers?: { [event: string]: string | Function };
item?: OrchestratorConfigItem<C>;
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
.rendered-item {
position: relative;
display: inline-block;
}

.drop-list {
padding: 10px;
background: lightcyan;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,18 @@
<orc-orchestrator *ngIf="config.component" [config]="config"></orc-orchestrator>
<div
*ngIf="!config.component"
class="drop-list"
cdkDropList
(cdkDropListDropped)="drop($event)"
>
<span class="drop-list-hint">Drop component here!</span>
<div class="rendered-item" *ngIf="config?.item?.component; else dropTpl">
<orc-render-item [item]="config.item"></orc-render-item>
</div>
<ng-template #dropTpl>
<div
class="drop-list"
cdkDropList
(cdkDropListDropped)="drop($event, configInput.value)"
>
<span class="drop-list-hint">Drop component here!</span>
</div>
<nz-divider nzText="Set component configuration" nzDashed></nz-divider>
<textarea
#configInput
nz-input
[nzAutosize]="{ minRows: 2, maxRows: 6 }"
></textarea>
</ng-template>
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,18 @@ import {
Component,
EventEmitter,
Input,
OnChanges,
Optional,
Output,
SimpleChanges,
SkipSelf,
} from '@angular/core';
import {
DynamicComponent,
OrchestratorConfigItem,
OrchestratorDynamicComponent,
OrchestratorDynamicComponentType,
RenderComponent,
} from '@orchestrator/core';

import { ComposerDroppableConfig } from './composer-droppable-config';
Expand All @@ -26,51 +31,83 @@ import { ComposerDroppableConfig } from './composer-droppable-config';
})
@DynamicComponent({ config: ComposerDroppableConfig })
export class ComposerDroppableComponent
implements OrchestratorDynamicComponent {
implements OrchestratorDynamicComponent<ComposerDroppableConfig>, OnChanges {

constructor(
private renderComponent: RenderComponent,
@SkipSelf() @Optional() private parentDroppable: ComposerDroppableComponent,
) {}
static wrapperConfig = Object.freeze<OrchestratorConfigItem>({
component: ComposerDroppableComponent,
});

@Input() config: ComposerDroppableConfig;

@Output() componentDrop = new EventEmitter<OrchestratorConfigItem>();
static getWrapperConfig() {
return {
component: ComposerDroppableComponent,
handlers: {
componentDrop(
updateConfig,
getInjector,
injectFlags,
getComponent,
$config: OrchestratorConfigItem,
) {
updateConfig($config);
const getParentDroppableInjector = getInjector().get(
'getInjector',
injectFlags.SkipSelf,
);
const parentUpdateConfig = getParentDroppableInjector().get(
'updateConfig',
);
const parentGetConfig = getParentDroppableInjector().get('getConfig');
const parentConfigItems = parentGetConfig().items || [];
parentUpdateConfig({
items: [
...parentConfigItems,
getComponent().constructor.getWrapperConfig(),
],
});
},
},
};
}
@Input() items: OrchestratorConfigItem[];

@Output() componentDropped = new EventEmitter<
OrchestratorDynamicComponentType
>();

private droppedConfig: OrchestratorConfigItem;

static wrapComponent(comp) {
static wrapComponent<C>(
comp: OrchestratorDynamicComponentType<C>,
config?: C,
): OrchestratorConfigItem<C> {
return {
component: comp,
items: [ComposerDroppableComponent.getWrapperConfig()],
config,
items: [ComposerDroppableComponent.wrapperConfig],
};
}

drop(e: CdkDragDrop<any>) {
ngOnChanges(changes: SimpleChanges) {
if ('config' in changes && this.droppedConfig) {
this.config = {
...this.config,
item: this.droppedConfig,
};
}

if ('items' in changes) {
this.config = {
...this.config,
item: {
...this.config.item,
items: this.items,
},
};
}
}

drop(e: CdkDragDrop<any>, conf?: string) {
const compType = e.item.data as OrchestratorDynamicComponentType;
this.componentDrop.emit(ComposerDroppableComponent.wrapComponent(compType));
const config = ComposerDroppableComponent.wrapComponent(
compType,
JSON.parse(conf || 'null'),
);

this.droppedConfig = config;

if (this.parentDroppable) {
this.parentDroppable.addItem(config);
} else {
this.config = { item: config };
}

this.componentDropped.emit(compType);
}

addItem(item: OrchestratorConfigItem) {
this.renderComponent.removeItem(ComposerDroppableComponent.wrapperConfig);

this.renderComponent.addItem(
ComposerDroppableComponent.wrapComponent(ComposerDroppableComponent, {
item,
}),
);

this.renderComponent.addItem(ComposerDroppableComponent.wrapperConfig);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import { DragDropModule } from '@angular/cdk/drag-drop';
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { OrchestratorCoreModule } from '@orchestrator/core';
import { NzDividerModule } from 'ng-zorro-antd/divider';
import { NzInputModule } from 'ng-zorro-antd/input';

import { ComposerDroppableComponent } from './composer-droppable.component';

Expand All @@ -12,6 +14,8 @@ import { ComposerDroppableComponent } from './composer-droppable.component';
imports: [
CommonModule,
DragDropModule,
NzInputModule,
NzDividerModule,
OrchestratorCoreModule.withComponents([ComposerDroppableComponent]),
],
exports: [ComposerDroppableComponent],
Expand Down

0 comments on commit 78bfe38

Please sign in to comment.