import { obx, computed } from '@ali/lowcode-editor-core'; import { isPanel } from './panel'; import { hasOwnProperty } from '@ali/lowcode-utils'; export interface WidgetItem { name: string; } export interface Activeable { setActive(flag: boolean): void; } function isActiveable(obj: any): obj is Activeable { return obj && obj.setActive; } export default class WidgetContainer { @obx.val items: T[] = []; private maps: { [name: string]: T } = {}; @obx.ref private _current: T & Activeable | null = null; get current() { return this._current; } // eslint-disable-next-line no-useless-constructor constructor( readonly name: string, private handle: (item: T | G) => T, private exclusive: boolean = false, private checkVisible: () => boolean = () => true, private defaultSetCurrent: boolean = false, // eslint-disable-next-line no-empty-function ) {} @computed get visible() { return this.checkVisible(); } active(nameOrItem?: T | string | null) { let item: any = nameOrItem; if (nameOrItem && typeof nameOrItem === 'string') { item = this.get(nameOrItem); } if (!isActiveable(item)) { item = null; } if (this.exclusive) { if (this._current === item) { return; } if (this._current) { this._current.setActive(false); } this._current = item; } if (item) { item.setActive(true); } } unactive(nameOrItem?: T | string | null) { let item: any = nameOrItem; if (nameOrItem && typeof nameOrItem === 'string') { item = this.get(nameOrItem); } if (!isActiveable(item)) { item = null; } if (this._current === item) { this._current = null; } if (item) { item.setActive(false); } } unactiveAll() { Object.keys(this.maps).forEach(name => this.unactive(name)); } add(item: T | G): T { item = this.handle(item); const origin = this.get(item.name); if (origin === item) { return origin; } const i = origin ? this.items.indexOf(origin) : -1; if (i > -1) { this.items[i] = item; } else { this.items.push(item); } this.maps[item.name] = item; if (isPanel(item)) { item.setParent(this); } if (this.defaultSetCurrent) { if (!this._current) { this.active(item); } } return item; } get(name: string): T | null { return this.maps[name] || null; } getAt(index: number): T | null { return this.items[index] || null; } has(name: string): boolean { return hasOwnProperty(this.maps, name); } indexOf(item: T): number { return this.items.indexOf(item); } /** * return indexOf the deletion */ remove(item: string | T): number { const thing = typeof item === 'string' ? this.get(item) : item; if (!thing) { return -1; } const i = this.items.indexOf(thing); if (i > -1) { this.items.splice(i, 1); } delete this.maps[thing.name]; if (thing === this.current) { this._current = null; } return i; } }