Загрузка данных


import React, { FC, lazy, useContext, useState } from 'react';

import { DNDWrapper } from '@components/DNDWrapper';
import { InstrumentSearch } from '@components/InstrumentSearch';
import WidgetContentWrapper from '@components/WidgetContentWrapper';
import WidgetHeader from '@components/WidgetHeader';
import { useDropInstrument } from '@hooks/dnd';

import { WidgetEnvContext } from '@terminal/desktop/workspaces/default/components/Widget/context';
import { useWidgetHeaderName } from '@utils/useWidgetName';

import useChartComponentFacade from './hooks/useChartComponentFacade';

import type { ChartContainerProps } from './types';

const MoexChart = lazy(() => import('./components/MoexChart/MoexChart'));

export const Chart: FC<ChartContainerProps> = function (props): JSX.Element {
  const indicativeData = props.widgetContentProps?.indicativeData;

  const {
    dropDownOpen,
    setDropdownOpen,
    currentSymbolInfo,
    setIsWidgetHeaderContextMenuOpen,
    isWidgetHeaderContextMenuOpen,
    onDropInstrument,
    addInstrumentFromModal,
    isOver,
  } = useChartComponentFacade(props);

  /* на дроп обновляем название бумаги в сторе
    и делаем апдейт на бэк, чтобы сохранить изменения
    при обновлении страницы */
  const { dropRef } = useDropInstrument((dragData) => {
    onDropInstrument(dragData.properties.issKey, true);
  });

  const [isOpenEmptyAction, setIsOpenEmptyAction] = useState<boolean>(false);

  const openInstrumentModal = () => {
    setIsOpenEmptyAction(true);
    setIsWidgetHeaderContextMenuOpen(false);
  };

  // TODO: Зависит от сеток
  const { isDraggedOver } = useContext(WidgetEnvContext);
  const contractsInstrumentName = useWidgetHeaderName(currentSymbolInfo.symbolId);

  const symbolInfo = indicativeData
    ? {
        symbolId: indicativeData.key,
        symbol: indicativeData.secId,
        symbolName: `${indicativeData.instrumentName} ${indicativeData.settlement} - ${indicativeData.firmName}`,
      }
    : currentSymbolInfo;

  const instrumentName =
    symbolInfo.symbolName ||
    contractsInstrumentName ||
    symbolInfo.symbol ||
    symbolInfo.symbolId;

  return (
    <DNDWrapper
      ref={dropRef}
      isOver={isOver}
      canDrop
    >
      <WidgetHeader
        {...props}
        dropdownOpen={dropDownOpen}
        setDropdownOpen={setDropdownOpen}
        itemsSearchIcon={[true]}
        handlerSaveAsExcel={null}
        addToWidgetNamePrefix={instrumentName}
        setIsOpenContextMenuFromWidget={setIsWidgetHeaderContextMenuOpen}
        isOpenContextMenuFromWidget={isWidgetHeaderContextMenuOpen}
        openInstrumentsModal={openInstrumentModal}
      />

      <WidgetContentWrapper {...props}>
        <div
          style={{
            display: 'flex',
            flexDirection: 'column',
            height: '100%',
            pointerEvents: isDraggedOver ? 'none' : 'inherit',
          }}
        >
          <MoexChart
            symbolInfo={symbolInfo}
            indicativeData={indicativeData}
            widgetId={props.widgetId}
            addInstrumentFromModal={addInstrumentFromModal}
          />

          {isOpenEmptyAction && (
            <InstrumentSearch
              setOpen={setIsOpenEmptyAction}
              isOpen={isOpenEmptyAction}
              variant="single"
              widgetId={props.widgetId}
              // withNRD={false}
              addInstruments={addInstrumentFromModal}
            />
          )}
        </div>
      </WidgetContentWrapper>
    </DNDWrapper>
  );
};




import React from 'react';

import { SymbolSearchModal } from '@widgets/Chart/components/MoexChart/components/SymbolSearchModal';

import { CompareModal } from './components/CompareModal';
import { useMoexChart } from './hooks';

import 'moex-chart/dist/styles.css';

import type { ChartIndicativeData, SelectedInstrument } from '../../types';
import type { SymbolInfoInput } from 'moex-chart';

interface TRProps {
  symbolInfo: SymbolInfoInput;
  indicativeData?: ChartIndicativeData;
  widgetId: number;
  addInstrumentFromModal: (instruments: SelectedInstrument[]) => void;
}

function MoexChartComponent({
  symbolInfo,
  indicativeData,
  widgetId,
  addInstrumentFromModal,
}: TRProps): React.ReactElement {
  const {
    containerRef,
    isCompareOpen,
    isSymbolSearchOpen,
    compareManagerRef,
    setIsCompareOpen,
    setIsSymbolSearchOpen,
  } = useMoexChart({
    symbolInfo,
    indicativeData,
  });

  const handleSymbolChange = (instrument: SelectedInstrument): void => {
    addInstrumentFromModal([instrument]);
  };

  return (
    <div
      style={{
        flex: '1 1 0',
        minHeight: 0,
        minWidth: 0,
      }}
    >
      <div ref={containerRef} />

      {isCompareOpen && (
        <CompareModal
          compareManager={compareManagerRef}
          widgetId={widgetId}
          isOpen={isCompareOpen}
          setOpen={setIsCompareOpen}
        />
      )}

      {isSymbolSearchOpen && (
        <SymbolSearchModal
          widgetId={widgetId}
          isOpen={isSymbolSearchOpen}
          setOpen={setIsSymbolSearchOpen}
          onSymbolChange={handleSymbolChange}
        />
      )}
    </div>
  );
}

export default React.memo(MoexChartComponent);