content-viewer.component.ts 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. import { Component, ComponentRef, Input, OnDestroy, ViewChild, ViewContainerRef } from '@angular/core';
  2. import { AttributesMap } from 'ng-dynamic-component';
  3. import { BehaviorSubject, combineLatest, Observable } from 'rxjs';
  4. import { filter, map, shareReplay } from 'rxjs/operators';
  5. import { EditionLevelType, TextFlow } from '../../app.config';
  6. import { GenericElement } from '../../models/evt-models';
  7. import { ComponentRegisterService } from '../../services/component-register.service';
  8. import { EntitiesSelectService } from '../../services/entities-select.service';
  9. import { EntitiesSelectItem } from '../entities-select/entities-select.component';
  10. import { LemsSelectService } from '../../services/lems-select.service';
  11. import { LemsSelectItem } from '../lems-select/lems-select.component';
  12. @Component({
  13. selector: 'evt-content-viewer',
  14. templateUrl: './content-viewer.component.html',
  15. })
  16. export class ContentViewerComponent implements OnDestroy {
  17. private v: GenericElement;
  18. @Input() set content(v: GenericElement) {
  19. this.v = v;
  20. this.contentChange.next(v);
  21. }
  22. get content() { return this.v; }
  23. private ith: EntitiesSelectItem[];
  24. @Input() set itemsToHighlight(i: EntitiesSelectItem[]) {
  25. this.ith = i;
  26. this.itemsToHighlightChange.next(i);
  27. }
  28. get itemsToHighlight() { return this.ith; }
  29. private ithlems: LemsSelectItem[];
  30. @Input() set itemsLemsToHighlight(i: LemsSelectItem[]) {
  31. this.ithlems = i;
  32. this.itemsLemsToHighlightChange.next(i);
  33. }
  34. get itemsLemsToHighlight() { return this.ithlems; }
  35. contentChange = new BehaviorSubject<GenericElement>(undefined);
  36. @ViewChild('container', { read: ViewContainerRef }) container: ViewContainerRef;
  37. itemsToHighlightChange = new BehaviorSubject<EntitiesSelectItem[]>([]);
  38. itemsLemsToHighlightChange = new BehaviorSubject<LemsSelectItem[]>([]);
  39. private edLevel: EditionLevelType;
  40. @Input() set editionLevel(el: EditionLevelType) {
  41. this.edLevel = el;
  42. this.editionLevelChange.next(el);
  43. }
  44. get editionLevel() { return this.edLevel; }
  45. editionLevelChange = new BehaviorSubject<EditionLevelType | ''>('');
  46. private txtFlow: TextFlow;
  47. @Input() set textFlow(t: TextFlow) {
  48. this.txtFlow = t;
  49. this.textFlowChange.next(t);
  50. }
  51. get textFlow() { return this.txtFlow; }
  52. textFlowChange = new BehaviorSubject<TextFlow>(undefined);
  53. constructor(
  54. private componentRegister: ComponentRegisterService,
  55. private entitiesSelectService: EntitiesSelectService,
  56. private lemsSelectService: LemsSelectService,
  57. ) {
  58. }
  59. // tslint:disable-next-line: no-any
  60. public parsedContent: Observable<{ [keyName: string]: any }> = this.contentChange.pipe(
  61. map((data) => ({
  62. ...data,
  63. type: this.componentRegister.getComponent(data?.type ?? GenericElement) || this.componentRegister.getComponent(GenericElement),
  64. })),
  65. shareReplay(1),
  66. );
  67. // tslint:disable-next-line: no-any
  68. public inputs: Observable<{ [keyName: string]: any }> = combineLatest([
  69. this.contentChange,
  70. this.itemsToHighlightChange,
  71. this.itemsLemsToHighlightChange,
  72. this.editionLevelChange,
  73. this.textFlowChange,
  74. ]).pipe(
  75. map(([data, itemsToHighlight, itemsLemsToHighlight, editionLevel, textFlow]) => {
  76. if (this.toBeHighlighted()) {
  77. return {
  78. data,
  79. highlightData: this.getHighlightData(data, itemsToHighlight),
  80. highlightDataLem: this.getHighlightDataLem(data, itemsLemsToHighlight),
  81. itemsToHighlight,
  82. itemsLemsToHighlight,
  83. editionLevel,
  84. textFlow,
  85. };
  86. }
  87. return {
  88. data,
  89. editionLevel,
  90. textFlow,
  91. };
  92. }),
  93. shareReplay(1),
  94. );
  95. // tslint:disable-next-line: ban-types
  96. public outputs: Observable<{ [keyName: string]: Function }> = this.contentChange.pipe(
  97. map(() => ({})),
  98. shareReplay(1),
  99. );
  100. public attributes: Observable<AttributesMap> = this.contentChange.pipe(
  101. filter(parsedContent => !!parsedContent),
  102. map((parsedContent) => ({ ...parsedContent.attributes || {}, ...{ class: `edition-font ${parsedContent.class || ''}` } })),
  103. shareReplay(1),
  104. );
  105. public context$ = combineLatest([
  106. this.parsedContent,
  107. this.inputs,
  108. this.outputs,
  109. this.attributes,
  110. ]).pipe(
  111. map(([parsedContent, inputs, outputs, attributes]) => (
  112. { parsedContent, inputs, outputs, attributes }
  113. )),
  114. );
  115. private componentRef: ComponentRef<{}>;
  116. private toBeHighlighted() {
  117. return true; // TODO: Decide when an item should be highlighted
  118. }
  119. private getHighlightData(data, ith: EntitiesSelectItem[]) {
  120. return {
  121. highlight: ith?.some(i => this.entitiesSelectService.matchClassAndAttributes(i.value, data?.attributes ?? {}, data?.class)) ?? false,
  122. highlightColor: this.entitiesSelectService.getHighlightColor(data?.attributes ?? {}, data?.class, ith),
  123. };
  124. }
  125. private getHighlightDataLem(data, ithlems: LemsSelectItem[]) {
  126. return {
  127. highlight: ithlems?.some(i => this.lemsSelectService.matchClassAndAttributes(i.value, data?.attributes ?? {}, data?.class)) ?? false,
  128. highlightColor: this.lemsSelectService.getHighlightColor(data?.attributes ?? {}, data?.class, ithlems),
  129. };
  130. }
  131. ngOnDestroy() {
  132. if (this.componentRef) {
  133. this.componentRef.destroy();
  134. this.componentRef = undefined;
  135. }
  136. }
  137. }