RcsbView.tsx 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. import * as React from "react";
  2. import {RcsbFvDOMConstants} from "../../../RcsbFvConstants/RcsbFvConstants";
  3. import {unmount} from "@rcsb/rcsb-saguaro-app";
  4. import {AbstractView, AbstractViewInterface} from "../AbstractView";
  5. import {RcsbFvBoardConfigInterface, RcsbFvTrackDataElementInterface} from "@rcsb/rcsb-saguaro";
  6. import {OperatorInfo, SaguaroPluginModelMapType} from "../../../RcsbFvStructure/StructureViewerInterface";
  7. import {RcsbFvAdditionalConfig, RcsbFvModulePublicInterface} from "@rcsb/rcsb-saguaro-app/build/dist/RcsbFvWeb/RcsbFvModule/RcsbFvModuleInterface";
  8. import {AssemblyModelSate} from "../../../RcsbFvState/AssemblyModelSate";
  9. import {DataContainer} from "../../../Utils/DataContainer";
  10. import {
  11. PfvManagerInterface,
  12. PfvManagerFactoryInterface
  13. } from "./PfvManagerFactoryInterface";
  14. import {
  15. CallbackManagerFactoryInterface,
  16. CallbackManagerInterface
  17. } from "./CallbackManagerFactoryInterface";
  18. export interface RcsbViewInterface<T,R,U> {
  19. rcsbId: string;
  20. additionalConfig?: RcsbFvAdditionalConfig & {operatorChangeCallback?:(operatorInfo: OperatorInfo)=>void};
  21. useOperatorsFlag?:boolean;
  22. pfvParams:T;
  23. pfvManagerFactory: PfvManagerFactoryInterface<T,R,U>;
  24. callbackManagerFactory: CallbackManagerFactoryInterface<R,U>;
  25. buildPfvOnMount?: boolean;
  26. }
  27. export class RcsbView<T,R,U> extends AbstractView<RcsbViewInterface<T,R,U>, {}, R>{
  28. private boardConfigContainer: DataContainer<Partial<RcsbFvBoardConfigInterface>> = new DataContainer();
  29. private rcsbFvContainer: DataContainer<RcsbFvModulePublicInterface> = new DataContainer<RcsbFvModulePublicInterface>();
  30. private readonly callbackManager: CallbackManagerInterface<U>;
  31. private readonly pfvFactory: PfvManagerInterface;
  32. constructor(props:RcsbViewInterface<T,R,U> & AbstractViewInterface<R>) {
  33. super(props);
  34. this.pfvFactory = this.props.pfvManagerFactory.getPfvManager({
  35. ...this.props.pfvParams,
  36. rcsbFvContainer: this.rcsbFvContainer,
  37. stateManager: this.props.stateManager,
  38. plugin: this.props.structureViewer,
  39. boardConfigContainer: this.boardConfigContainer,
  40. rcsbFvDivId: this.rcsbFvDivId,
  41. pfvChangeCallback: this.pfvChangeCallback.bind(this),
  42. additionalConfig: this.props.additionalConfig,
  43. useOperatorsFlag: this.props.useOperatorsFlag
  44. });
  45. this.callbackManager = this.props.callbackManagerFactory.getCallbackManager({
  46. rcsbFvContainer: this.rcsbFvContainer,
  47. stateManager: this.props.stateManager,
  48. plugin: this.props.structureViewer,
  49. pfvFactory: this.pfvFactory
  50. });
  51. }
  52. additionalContent(): JSX.Element {
  53. return (
  54. <div style={{marginTop:10}}>
  55. <div>
  56. <div id={RcsbFvDOMConstants.SELECT_BUTTON_PFV_ID} style={{display:"inline-block"}}/>
  57. <div style={{display:"inline-block", marginLeft:25}}>
  58. <a href={"/docs/sequence-viewers/protein-feature-view"} target={"_blank"}>Help</a>
  59. </div>
  60. </div>
  61. <div style={{position:"absolute", top:5, right:5}} >
  62. <a style={{textDecoration:"none", color:"#337ab7", cursor:"pointer", marginRight:15}} target={"_blank"} href={"/docs/sequence-viewers/3d-protein-feature-view"}>
  63. Help
  64. </a>
  65. <a style={{textDecoration:"none", color: "#337ab7", cursor:"pointer"}} onClick={()=>{this.props.unmount(true, ()=>{
  66. window.history.back();
  67. })}}>
  68. Back
  69. </a>
  70. </div>
  71. </div>
  72. );
  73. }
  74. async componentDidMount (): Promise<void> {
  75. super.componentDidMount();
  76. const width: number | undefined = document.getElementById(this.componentDivId)?.getBoundingClientRect().width;
  77. if(width == null)
  78. return;
  79. const trackWidth: number = width - 190 - 55;
  80. this.boardConfigContainer.set({
  81. ...this.props.additionalConfig?.boardConfig,
  82. trackWidth: trackWidth,
  83. highlightHoverPosition:true,
  84. highlightHoverElement:true,
  85. elementClickCallBack:(e:RcsbFvTrackDataElementInterface)=>{
  86. this.elementClickCallback(e);
  87. if(typeof this.props.additionalConfig?.boardConfig?.elementClickCallBack === "function")
  88. this.props.additionalConfig?.boardConfig.elementClickCallBack(e);
  89. },
  90. selectionChangeCallBack:(selection: Array<RcsbFvTrackDataElementInterface>)=>{
  91. this.selectionChangeCallback(selection);
  92. if(typeof this.props.additionalConfig?.boardConfig?.selectionChangeCallBack === "function")
  93. this.props.additionalConfig?.boardConfig.selectionChangeCallBack(selection);
  94. },
  95. highlightHoverCallback:(selection: RcsbFvTrackDataElementInterface[])=>{
  96. this.highlightHoverCallback(selection);
  97. if(typeof this.props.additionalConfig?.boardConfig?.highlightHoverCallback === "function")
  98. this.props.additionalConfig?.boardConfig.highlightHoverCallback(selection);
  99. },
  100. });
  101. if(this.props.buildPfvOnMount)
  102. this.rcsbFvContainer.set(await this.pfvFactory.create());
  103. }
  104. componentWillUnmount() {
  105. super.componentWillUnmount();
  106. unmount(this.rcsbFvDivId);
  107. }
  108. async structureSelectionCallback(): Promise<void> {
  109. await this.pluginSelectCallback('select');
  110. }
  111. async structureHoverCallback(): Promise<void> {
  112. await this.pluginSelectCallback('hover');
  113. }
  114. representationChangeCallback(): void{
  115. //TODO
  116. }
  117. async updateDimensions(): Promise<void> {
  118. const width: number = window.document.getElementById(this.componentDivId)?.getBoundingClientRect().width ?? 0;
  119. const trackWidth: number = width - 190 - 55;
  120. this.boardConfigContainer.set({...this.boardConfigContainer.get(), trackWidth});
  121. await this.rcsbFvContainer.get()?.getFv().updateBoardConfig({boardConfigData:{trackWidth:trackWidth}})
  122. await this.structureSelectionCallback();
  123. return void 0;
  124. }
  125. async modelChangeCallback(defaultAuthId?: string, defaultOperatorName?:string): Promise<void> {
  126. await this.callbackManager.modelChangeCallback(defaultAuthId, defaultOperatorName);
  127. }
  128. private async pluginSelectCallback(mode:'select'|'hover'): Promise<void> {
  129. await this.callbackManager.pluginSelectCallback(mode);
  130. }
  131. private async pfvChangeCallback(context: U): Promise<void>{
  132. await this.callbackManager.pfvChangeCallback(context);
  133. }
  134. private highlightHoverCallback(selection: RcsbFvTrackDataElementInterface[]): void {
  135. this.callbackManager.highlightHoverCallback(selection);
  136. }
  137. private selectionChangeCallback(selection: Array<RcsbFvTrackDataElementInterface>): void {
  138. this.callbackManager.selectionChangeCallback(selection);
  139. }
  140. private elementClickCallback(e:RcsbFvTrackDataElementInterface): void {
  141. this.callbackManager.elementClickCallback(e);
  142. }
  143. }