UNPKG

bixi

Version:

企业级中后台前端解决方案

249 lines (241 loc) 7.15 kB
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, EventEmitter, Input, OnDestroy, OnInit, Output, TemplateRef, ViewChild, ViewContainerRef, ViewEncapsulation } from '@angular/core'; import { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser'; import { Subscription } from 'rxjs'; import { delayWhen, filter } from 'rxjs/operators'; import { EVENTS } from './label.event'; import { LabelHub } from './label.hub'; import { IClickLabelsEvent, IDeleteLabelsEvent, IHoverInLabelsEvent, ILabelingEvent, ISafeAny, ITableMatrix } from './label.type'; import { functionProxy } from './label.util'; @Component({ selector: 'bixi-label-core', template: ` <div class="bixi-label-core"> <iframe #iframe [src]="url" (load)="onLoad()" [attr.id]="hub.id" [title]="hub.id"> </iframe> <bixi-label-tooltip *ngIf="hoverInLabelsEvent && !labelTooltipDisabled" [tooltip]="hoverInLabelsEvent" [content]="labelTooltipContent"> </bixi-label-tooltip> <bixi-label-modal *ngIf="labelModalContent && labelingEvent && !labelModalDisabled" [dragBoundary]="dragBoundary" (close)="onCloseLabelModal()" [labeling]="labelingEvent" [title]="labelModalTitle" [content]="labelModalContent"> </bixi-label-modal> </div> `, exportAs: 'bixiLabelText', encapsulation: ViewEncapsulation.None, preserveWhitespaces: true, changeDetection: ChangeDetectionStrategy.OnPush, // TODO 做主题切换 styleUrls: ['./style/index.less'] }) export class BixiLabelCoreComponent implements OnInit, OnDestroy { subscription = new Subscription(); _engine: string; url: SafeResourceUrl; hoverInLabelsEvent: IHoverInLabelsEvent | null = null; labelingEvent: ILabelingEvent | null = null; @Input() dragBoundary: string; @ViewChild('iframe', { read: ViewContainerRef }) iframe: ViewContainerRef; @Input() hub: LabelHub; @Input() set engine(val: string) { this.url = this.sanitizer.bypassSecurityTrustResourceUrl(`${val || './bixi-label/index.html'}`); this._engine = val; } get engine() { return this._engine; } @Input() labelTooltipContent: TemplateRef<ISafeAny> | undefined; @Input() labelTooltipDisabled: boolean = false; @Input() labelModalTitle: string; @Input() labelModalDisabled: boolean = false; @Input() labelModalContent: TemplateRef<ISafeAny> | undefined; @Output() startLabeling: EventEmitter<ILabelingEvent> = new EventEmitter<ILabelingEvent>(); @Output() deleteLabels: EventEmitter<IDeleteLabelsEvent> = new EventEmitter<IDeleteLabelsEvent>(); @Output() clickLabels: EventEmitter<IClickLabelsEvent> = new EventEmitter<IClickLabelsEvent>(); @Output() pdfLoadFailed = new EventEmitter(); @Output() pdfScrolling = new EventEmitter(); @Output() mergeTables: EventEmitter<ITableMatrix[]> = new EventEmitter(); @Output() splitTable: EventEmitter<ITableMatrix[]> = new EventEmitter(); constructor( public sanitizer: DomSanitizer, private cdr: ChangeDetectorRef ) { } onLoad() { if (!this.hub) return; const api = this.api; this.hub.setApi(api); this.hub.setLoaded(!!api); } get api() { if (!this.iframe) return; const service = this.iframe.element.nativeElement.contentWindow.ProxyApiService2; if (this.hub.dev) { return functionProxy(service); } return service; } ngOnInit() { this.subscription.add(this.hub.init$ .pipe( filter(i => !!i), delayWhen(() => this.hub.loaded$.pipe(filter(r => r === true))) ) .subscribe(options => { if (!this.api) return; this.api.init(options); })); this.subscription.add(this.hub.labels$ .pipe( filter(i => !!i), delayWhen(() => this.hub.ready$.pipe(filter(r => r === true))) ) .subscribe((labels) => { if (!this.api) return; this.api.setLabels(labels); })); this.subscription.add(this.hub.tables$ .pipe( filter(i => !!i), delayWhen(() => this.hub.ready$.pipe(filter(r => r === true))) ) .subscribe((tables) => { if (!this.api) return; this.api.setTables(tables); })); this.subscription.add(this.hub.hoverInLabelsEvent$ .subscribe(event => { this.hoverInLabelsEvent = event; this.cdr.detectChanges(); })); this.subscription.add(this.hub.labelingEvent$ .subscribe(event => { this.labelingEvent = event; this.cdr.detectChanges(); })); window.addEventListener('message', this.messageHandler); } onCloseLabelModal() { this.hub.stopLabeling(); this.hub.restore(); } messageHandler = (e: MessageEvent) => { const { id, event, data } = e.data; if (this.hub.id !== id) return; if (this.hub.logAllEvents) { if (!this.hub.logIgnoreEvents.includes(event)) { console.log(`[@bixi/label] Event(${this.hub.id})`, e.data); } } switch (event) { case EVENTS.ready: { // 初始化标注器 this.hub.setReady(true); this.hub.innerSetPagination({ pageCount: data.pageCount }); break; } case EVENTS.zoomChange: { this.hub.setZoom(data.zoom); break; } case EVENTS.startLabeling: { this.hub.startLabeling(data); this.startLabeling.emit(data); break; } case EVENTS.deleteLabels: { this.hub.deleteLabels(data); this.deleteLabels.emit(data); break; } case EVENTS.paginationChange: { this.hub.innerSetPagination({ pageNumber: data.pageNumber }); break; } case EVENTS.searchResult: { this.hub.setSearchResult(data); break; } case EVENTS.clickLabels: { this.clickLabels.emit(data); break; } case EVENTS.hoverInLabel: { this.hub.hoverInLabels(data); break; } case EVENTS.hoverOutLabel: { this.hub.hoverInLabels(null); break; } case EVENTS.pdfScrolling: { if (this.hub.hoverInLabelsEvent) { this.hub.hoverInLabels(null); } this.pdfScrolling.emit(true); break; } case EVENTS.pdfLoadFailed: { this.pdfLoadFailed.emit(); break; } case EVENTS.log: { this.hub.setLog(data); break; } case EVENTS.resize: { this.hub.resize$.next(); break; } case EVENTS.mergeTables: { this.mergeTables.emit(data); break; } case EVENTS.splitTable: { this.splitTable.emit(data); break; } default: { if (this.hub.logUnhandledEvents) { if (!this.hub.logIgnoreEvents.includes(event)) { console.warn(`[@bixi/label] Unhandled Event(${this.hub.id}) `, event, data); } } break; } } } ngOnDestroy() { this.subscription.unsubscribe(); this.hub.destory(); window.removeEventListener('message', this.messageHandler); } }