12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273 |
- import * as _ from 'lodash';
- import { OptionsProcessor } from './OptionsProcessor';
- import { LayoutType } from './LayoutType';
-
- export interface Data {
- name?: string;
- options?: any;
- passProps?: any;
- }
- export interface LayoutNode {
- id?: string;
- type: LayoutType;
- data: Data;
- children: LayoutNode[];
- }
-
- export class LayoutTreeCrawler {
- private optionsProcessor: OptionsProcessor;
- constructor(
- private readonly uniqueIdProvider: any,
- public readonly store: any) {
- this.crawl = this.crawl.bind(this);
- this.processOptions = this.processOptions.bind(this);
- this.optionsProcessor = new OptionsProcessor(store, uniqueIdProvider);
- }
-
- crawl(node: LayoutNode): void {
- this._assertKnownLayoutType(node.type);
- node.id = node.id || this.uniqueIdProvider.generate(node.type);
- node.data = node.data || {};
- node.children = node.children || [];
- if (node.type === LayoutType.Component) {
- this._handleComponent(node);
- }
- this.processOptions(node.data.options);
- _.forEach(node.children, this.crawl);
- }
-
- processOptions(options) {
- this.optionsProcessor.processOptions(options);
- }
-
- _handleComponent(node) {
- this._assertComponentDataName(node);
- this._savePropsToStore(node);
- this._applyStaticOptions(node);
- node.data.passProps = undefined;
- }
-
- _savePropsToStore(node) {
- this.store.setPropsForId(node.id, node.data.passProps);
- }
-
- _applyStaticOptions(node) {
- const clazz = this.store.getComponentClassForName(node.data.name) ? this.store.getComponentClassForName(node.data.name)() : {};
- const staticOptions = _.isFunction(clazz.options) ? clazz.options(node.data.passProps || {}) : (_.cloneDeep(clazz.options) || {});
- const passedOptions = node.data.options || {};
- node.data.options = _.merge({}, staticOptions, passedOptions);
- }
-
- _assertKnownLayoutType(type) {
- if (!LayoutType[type]) {
- throw new Error(`Unknown layout type ${type}`);
- }
- }
-
- _assertComponentDataName(component) {
- if (!component.data.name) {
- throw new Error('Missing component data.name');
- }
- }
- }
|