MsaRowTitleComponent.tsx 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. /*
  2. * Copyright (c) 2021 RCSB PDB and contributors, licensed under MIT, See LICENSE file for more info.
  3. * @author Joan Segura Mora <joan.segura@rcsb.org>
  4. */
  5. import * as React from "react";
  6. import {RcsbFvRowTitleInterface} from "@rcsb/rcsb-saguaro/build/RcsbFv/RcsbFvRow/RcsbFvRowTitle";
  7. import {RcsbFvRowConfigInterface} from "@rcsb/rcsb-saguaro";
  8. import {
  9. AlignmentRequestContextType
  10. } from "@rcsb/rcsb-saguaro-app/build/dist/RcsbFvWeb/RcsbFvFactories/RcsbFvTrackFactory/TrackFactoryImpl/AlignmentTrackFactory";
  11. import {TargetAlignment} from "@rcsb/rcsb-api-tools/build/RcsbGraphQL/Types/Borrego/GqlTypes";
  12. import {RcsbFvStateManager} from "../../../../../RcsbFvState/RcsbFvStateManager";
  13. import {Subscription} from "rxjs";
  14. import {TagDelimiter} from "@rcsb/rcsb-saguaro-app";
  15. import {MsaRowTitleCheckboxComponent} from "./MsaRowTitleCheckboxComponent";
  16. import {MouseEvent} from "react";
  17. import {Property} from "csstype";
  18. interface MsaRowTitleInterface extends RcsbFvRowTitleInterface {
  19. alignmentContext: AlignmentRequestContextType;
  20. targetAlignment: TargetAlignment;
  21. stateManager:RcsbFvStateManager;
  22. titleClick: ()=>void;
  23. }
  24. interface MsaRowTitleState {
  25. expandTitle: boolean;
  26. disabled: boolean;
  27. titleColor: string;
  28. blocked:boolean;
  29. }
  30. export class MsaRowTitleComponent extends React.Component <MsaRowTitleInterface, MsaRowTitleState> {
  31. private readonly configData : RcsbFvRowConfigInterface;
  32. private subscription: Subscription;
  33. private readonly INACTIVE_COLOR: string = "#ccc";
  34. private readonly ACTIVE_COLOR: string ="rgb(51, 122, 183)";
  35. readonly state = {
  36. expandTitle: false,
  37. disabled: true,
  38. titleColor: this.INACTIVE_COLOR,
  39. blocked:false
  40. };
  41. constructor(props: MsaRowTitleInterface) {
  42. super(props);
  43. this.configData = this.props.data;
  44. }
  45. public render(): JSX.Element{
  46. return (
  47. <div style={{textAlign:"right", display:"flex"}}
  48. onMouseOver={()=>this.hover(true)}
  49. onMouseOut={()=>this.hover(false)}
  50. >
  51. <div>
  52. <div style={{
  53. MozUserSelect:"none",
  54. WebkitUserSelect:"none",
  55. msUserSelect:"none",
  56. color: this.state.titleColor,
  57. cursor: this.state.blocked ? "wait" : "pointer",
  58. maxWidth:100,
  59. overflow: "hidden",
  60. textOverflow: "ellipsis",
  61. whiteSpace: "nowrap"
  62. }}
  63. onClick={(e: MouseEvent)=>this.click(e)}
  64. title={this.props.targetAlignment.target_id ?? undefined}
  65. >
  66. {this.props.targetAlignment.target_id}
  67. </div>
  68. </div>
  69. <div style={{cursor: this.cursor()}} onClick={(e: MouseEvent)=>this.altClick(e)} >
  70. <MsaRowTitleCheckboxComponent disabled={this.state.disabled} {...TagDelimiter.parseEntity(this.props.targetAlignment.target_id!)} tag={"aligned"} stateManager={this.props.stateManager}/>
  71. <MsaRowTitleCheckboxComponent disabled={this.state.disabled} {...TagDelimiter.parseEntity(this.props.targetAlignment.target_id!)} tag={"polymer"} stateManager={this.props.stateManager}/>
  72. <MsaRowTitleCheckboxComponent disabled={this.state.disabled} {...TagDelimiter.parseEntity(this.props.targetAlignment.target_id!)} tag={"non-polymer"} stateManager={this.props.stateManager}/>
  73. </div>
  74. </div>
  75. );
  76. }
  77. public componentDidMount(): void {
  78. this.subscribe();
  79. this.modelChange();
  80. }
  81. public componentWillUnmount() {
  82. this.subscription.unsubscribe();
  83. }
  84. private subscribe(): void{
  85. this.subscription = this.props.stateManager.subscribe<"representation-change",{label:string;isHidden:boolean;}>((o)=>{
  86. if(o.type == "model-change" && o.view == "1d-view")
  87. this.block();
  88. if(o.type == "model-change" && o.view == "3d-view")
  89. this.modelChange();
  90. })
  91. }
  92. private block(): void {
  93. this.setState({blocked:true});
  94. }
  95. private modelChange(): void {
  96. if(this.props.targetAlignment.target_id && this.props.stateManager.assemblyModelSate.getMap()?.has(this.props.targetAlignment.target_id)){
  97. if(this.state.disabled)
  98. this.setState({disabled:false, titleColor:this.ACTIVE_COLOR, blocked:false});
  99. else
  100. this.setState({blocked:false});
  101. }else if(!this.state.disabled){
  102. this.setState({disabled:true, titleColor:this.INACTIVE_COLOR, blocked:false});
  103. }else if(this.state.blocked){
  104. this.setState({blocked:false});
  105. }
  106. }
  107. private hover(flag: boolean): void {
  108. if(this.state.disabled && flag)
  109. this.setState({titleColor:this.ACTIVE_COLOR});
  110. else if(this.state.disabled && !flag)
  111. this.setState({titleColor:this.INACTIVE_COLOR});
  112. }
  113. private click(e: MouseEvent): void{
  114. if(e.shiftKey) {
  115. const newWin: Window|null = window.open(
  116. `/structure/${TagDelimiter.parseEntity(this.props.targetAlignment.target_id!).entryId}#entity-${TagDelimiter.parseEntity(this.props.targetAlignment.target_id!).entityId}`,
  117. "_blank"
  118. );
  119. if(!newWin || newWin.closed || typeof newWin.closed === 'undefined')
  120. document.location.href = `/structure/${TagDelimiter.parseEntity(this.props.targetAlignment.target_id!).entryId}#entity-${TagDelimiter.parseEntity(this.props.targetAlignment.target_id!).entityId}`;
  121. } else {
  122. if(this.state.blocked)
  123. return;
  124. this.setState({blocked:true});
  125. this.props.titleClick();
  126. }
  127. }
  128. private cursor():Property.Cursor|undefined {
  129. if(this.state.blocked)
  130. return "wait"
  131. return this.state.disabled ? "pointer" : undefined
  132. }
  133. private altClick(e: MouseEvent): void{
  134. if(this.state.disabled)
  135. this.props.titleClick();
  136. }
  137. }