Skip to content
Snippets Groups Projects
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
BioEntityDrawer.component.tsx 4.99 KiB
import { ZERO } from '@/constants/common';
import {
  currentDrawerBioEntityRelatedSubmapSelector,
  currentDrawerBioEntitySelector,
  currentDrawerElementCommentsSelector,
} from '@/redux/bioEntity/bioEntity.selectors';
import {
  getChemicalsForBioEntityDrawerTarget,
  getDrugsForBioEntityDrawerTarget,
} from '@/redux/drawer/drawer.thunks';
import { useAppDispatch } from '@/redux/hooks/useAppDispatch';
import { useAppSelector } from '@/redux/hooks/useAppSelector';
import { DrawerHeading } from '@/shared/DrawerHeading';
import { ElementSearchResultType } from '@/types/models';
import { CommentItem } from '@/components/Map/Drawer/BioEntityDrawer/Comments/CommentItem.component';
import { ModificationResidueItem } from '@/components/Map/Drawer/BioEntityDrawer/ModificationResidueItem';
import React from 'react';
import { CollapsibleSection } from '../ExportDrawer/CollapsibleSection';
import { AnnotationItem } from './AnnotationItem';
import { AssociatedSubmap } from './AssociatedSubmap';
import { ChemicalsList } from './ChemicalsList';
import { DrugsList } from './DrugsList';
import { OverlayData } from './OverlayData';

const TARGET_PREFIX: ElementSearchResultType = `ALIAS`;

export const BioEntityDrawer = (): React.ReactNode => {
  const dispatch = useAppDispatch();
  const bioEntityData = useAppSelector(currentDrawerBioEntitySelector);
  const commentsData = useAppSelector(currentDrawerElementCommentsSelector);
  const relatedSubmap = useAppSelector(currentDrawerBioEntityRelatedSubmapSelector);
  const currentTargetId = bioEntityData?.id ? `${TARGET_PREFIX}:${bioEntityData.id}` : '';

  const fetchChemicalsForTarget = (): void => {
    dispatch(getChemicalsForBioEntityDrawerTarget(currentTargetId));
  };
  const fetchDrugsForTarget = (): void => {
    dispatch(getDrugsForBioEntityDrawerTarget(currentTargetId));
  };

  if (!bioEntityData) {
    return null;
  }

  const isReferenceAvailable = bioEntityData.references.length > ZERO;
  const isCommentAvailable = commentsData.length > ZERO;
  const modificationResidues = (
    bioEntityData.modificationResidues ? bioEntityData.modificationResidues : []
  ).filter(modificationResidue => modificationResidue.state && modificationResidue.state !== '');
  const isModificationAvailable = modificationResidues.length > ZERO;

  return (
    <div className="h-calc-drawer" data-testid="bioentity-drawer">
      <DrawerHeading
        title={
          <>
            <span className="font-normal">{bioEntityData.stringType}:</span>&nbsp;
            {bioEntityData.name}
          </>
        }
      />
      <div className="flex max-h-full flex-col gap-6 overflow-y-auto p-6">
        <div className="text-sm font-normal">
          Compartment:{' '}
          <b className="font-semibold">
            {bioEntityData.compartmentName ? bioEntityData.compartmentName : 'default'}
          </b>
        </div>
        {bioEntityData.fullName && (
          <div className="text-sm font-normal">
            Full name: <b className="font-semibold">{bioEntityData.fullName}</b>
          </div>
        )}
        {bioEntityData.notes && (
          <span className="visited:text-purple-600 text-blue-600 underline hover:text-blue-800">
            <hr className="border-b border-b-divide" />
            <div
              className="mt-2 text-sm font-normal"
              dangerouslySetInnerHTML={{ __html: bioEntityData.notes }}
            />
          </span>
        )}
        {isModificationAvailable && (
          <h3 className="font-semibold">Post-translational modifications:</h3>
        )}
        {isModificationAvailable && (
          <ul className="ml-5 list-disc">
            {modificationResidues.map(residue => (
              <ModificationResidueItem key={residue.id} state={residue.state} name={residue.name} />
            ))}
          </ul>
        )}
        <h3 className="font-semibold">
          Annotations:{' '}
          {!isReferenceAvailable && <span className="font-normal">No annotations</span>}
        </h3>
        {isReferenceAvailable &&
          bioEntityData.references.map(reference => (
            <AnnotationItem
              key={reference.id}
              type={reference.type}
              link={reference.link}
              resource={reference.resource}
            />
          ))}
        <AssociatedSubmap />
        {!relatedSubmap && (
          <>
            <CollapsibleSection title="Drugs for target" onOpened={fetchDrugsForTarget}>
              <DrugsList />
            </CollapsibleSection>
            <CollapsibleSection title="Chemicals for target" onOpened={fetchChemicalsForTarget}>
              <ChemicalsList />
            </CollapsibleSection>
          </>
        )}
        <OverlayData
          isShowGroupedOverlays={Boolean(relatedSubmap)}
          isShowOverlayBioEntityName={Boolean(relatedSubmap)}
        />
        {isCommentAvailable && <div className="font-bold"> Comments</div>}
        {isCommentAvailable &&
          commentsData.map(comment => <CommentItem key={comment.id} comment={comment} />)}
      </div>
    </div>
  );
};