RcsbView.tsx 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. import {RcsbFvTrackDataElementInterface} from "@rcsb/rcsb-saguaro/lib/RcsbDataManager/RcsbDataManager";
  2. import {RcsbFvBoardConfigInterface} from "@rcsb/rcsb-saguaro/lib/RcsbFv/RcsbFvConfig/RcsbFvConfigInterface";
  3. import {
  4. RcsbFvAdditionalConfig,
  5. RcsbFvModulePublicInterface
  6. } from "@rcsb/rcsb-saguaro-app/lib/RcsbFvWeb/RcsbFvModule/RcsbFvModuleInterface"
  7. import {unmount} from "@rcsb/rcsb-saguaro-app/lib/RcsbFvWeb/RcsbFvBuilder";
  8. import {AbstractView, AbstractViewInterface} from "../AbstractView";
  9. import {OperatorInfo} from "../../../RcsbFvStructure/StructureViewerInterface";
  10. import {DataContainer} from "../../../Utils/DataContainer";
  11. import {
  12. PfvManagerInterface,
  13. PfvManagerFactoryInterface
  14. } from "./PfvManagerFactoryInterface";
  15. import {
  16. CallbackManagerFactoryInterface,
  17. CallbackManagerInterface
  18. } from "./CallbackManagerFactoryInterface";
  19. import {RcsbViewBehaviourInterface} from "./RcsbViewBehaviourInterface";
  20. export interface RcsbViewInterface<T,U> {
  21. rcsbId: string;
  22. additionalConfig?: RcsbFvAdditionalConfig & {operatorChangeCallback?:(operatorInfo: OperatorInfo)=>void};
  23. useOperatorsFlag?:boolean;
  24. pfvParams:T;
  25. pfvManagerFactory: PfvManagerFactoryInterface<T,U>;
  26. callbackManagerFactory: CallbackManagerFactoryInterface<U>;
  27. additionalContent?(props:RcsbViewInterface<T,U> & AbstractViewInterface): JSX.Element;
  28. buildPfvOnMount?: boolean;
  29. rcsbViewBehaviour?: RcsbViewBehaviourInterface;
  30. }
  31. export class RcsbView<T,U> extends AbstractView<RcsbViewInterface<T,U>, {}>{
  32. private boardConfigContainer: DataContainer<Partial<RcsbFvBoardConfigInterface>> = new DataContainer();
  33. private rcsbFvContainer: DataContainer<RcsbFvModulePublicInterface> = new DataContainer<RcsbFvModulePublicInterface>();
  34. private readonly callbackManager: CallbackManagerInterface<U>;
  35. private readonly pfvFactory: PfvManagerInterface;
  36. constructor(props:RcsbViewInterface<T,U> & AbstractViewInterface) {
  37. super(props);
  38. this.pfvFactory = this.props.pfvManagerFactory.getPfvManager({
  39. ...this.props.pfvParams,
  40. rcsbFvContainer: this.rcsbFvContainer,
  41. stateManager: this.props.stateManager,
  42. boardConfigContainer: this.boardConfigContainer,
  43. rcsbFvDivId: this.rcsbFvDivId,
  44. pfvChangeCallback: this.pfvChangeCallback.bind(this),
  45. additionalConfig: this.props.additionalConfig,
  46. useOperatorsFlag: this.props.useOperatorsFlag
  47. });
  48. this.callbackManager = this.props.callbackManagerFactory.getCallbackManager({
  49. rcsbFvContainer: this.rcsbFvContainer,
  50. stateManager: this.props.stateManager,
  51. pfvFactory: this.pfvFactory
  52. });
  53. this.props.rcsbViewBehaviour?.observe(this.rcsbFvContainer, this.props.stateManager);
  54. }
  55. additionalContent(): JSX.Element {
  56. return this.props.additionalContent ? this.props.additionalContent(this.props) : <></>;
  57. }
  58. async componentDidMount (): Promise<void> {
  59. super.componentDidMount();
  60. const trackWidth: number = this.getwidth();
  61. this.boardConfigContainer.set({
  62. trackWidth: trackWidth,
  63. highlightHoverPosition:true,
  64. highlightHoverElement:true,
  65. ...this.props.additionalConfig?.boardConfig,
  66. elementClickCallBack:(e?:RcsbFvTrackDataElementInterface)=>{
  67. this.elementClickCallback(e);
  68. if(typeof this.props.additionalConfig?.boardConfig?.elementClickCallBack === "function")
  69. this.props.additionalConfig?.boardConfig.elementClickCallBack(e);
  70. },
  71. selectionChangeCallBack:(selection: Array<RcsbFvTrackDataElementInterface>)=>{
  72. this.selectionChangeCallback(selection);
  73. if(typeof this.props.additionalConfig?.boardConfig?.selectionChangeCallBack === "function")
  74. this.props.additionalConfig?.boardConfig.selectionChangeCallBack(selection);
  75. },
  76. highlightHoverCallback:(selection: RcsbFvTrackDataElementInterface[])=>{
  77. this.highlightHoverCallback(selection);
  78. if(typeof this.props.additionalConfig?.boardConfig?.highlightHoverCallback === "function")
  79. this.props.additionalConfig?.boardConfig.highlightHoverCallback(selection);
  80. },
  81. });
  82. if(this.props.buildPfvOnMount)
  83. this.rcsbFvContainer.set(await this.pfvFactory.create());
  84. }
  85. componentWillUnmount() {
  86. super.componentWillUnmount();
  87. unmount(this.rcsbFvDivId);
  88. this.props.rcsbViewBehaviour?.unsubscribe();
  89. }
  90. async structureSelectionCallback(): Promise<void> {
  91. await this.pluginSelectCallback('select');
  92. }
  93. async structureHoverCallback(): Promise<void> {
  94. await this.pluginSelectCallback('hover');
  95. }
  96. representationChangeCallback(): void{
  97. //TODO
  98. }
  99. async updateDimensions(): Promise<void> {
  100. const trackWidth: number = this.getwidth();
  101. this.boardConfigContainer.set({...this.boardConfigContainer.get(), trackWidth});
  102. const select = this.rcsbFvContainer.get()?.getFv().getSelection("select");
  103. const dom = this.rcsbFvContainer.get()?.getFv().getDomain();
  104. await this.rcsbFvContainer.get()?.getFv().updateBoardConfig({boardConfigData:{trackWidth:trackWidth}})
  105. if(select)
  106. this.rcsbFvContainer.get()?.getFv().setSelection({
  107. elements: select.map(s=>({begin:s.rcsbFvTrackDataElement.begin, end:s.rcsbFvTrackDataElement.end })),
  108. mode:"select"
  109. });
  110. if(dom) this.rcsbFvContainer.get()?.getFv().setDomain(dom);
  111. return void 0;
  112. }
  113. async modelChangeCallback(defaultAuthId?: string, defaultOperatorName?:string): Promise<void> {
  114. await this.callbackManager.modelChangeCallback(defaultAuthId, defaultOperatorName);
  115. }
  116. private async pluginSelectCallback(mode:'select'|'hover'): Promise<void> {
  117. await this.callbackManager.structureViewerSelectionCallback(mode);
  118. }
  119. private async pfvChangeCallback(context: U): Promise<void>{
  120. await this.callbackManager.pfvChangeCallback(context);
  121. }
  122. private highlightHoverCallback(selection: RcsbFvTrackDataElementInterface[]): void {
  123. this.callbackManager.highlightHoverCallback(selection);
  124. }
  125. private selectionChangeCallback(selection: Array<RcsbFvTrackDataElementInterface>): void {
  126. this.callbackManager.pfvSelectionChangeCallback(selection);
  127. }
  128. private elementClickCallback(e?:RcsbFvTrackDataElementInterface): void {
  129. this.callbackManager.featureClickCallback(e);
  130. }
  131. private getwidth(): number {
  132. const width: number = window.document.getElementById(this.componentDivId)?.getBoundingClientRect().width ?? 0;
  133. return width - (this.props.additionalConfig?.boardConfig?.rowTitleWidth ?? 190) - (this.props.additionalConfig?.boardConfig?.disableMenu ? 10 : 55);
  134. }
  135. }