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


import { Button, Divider } from 'exchange-elements/v2';
import { useEffect, useState } from 'react';

import { type Observable, of } from 'rxjs';

import { IndicatorsSelect } from '@components/IndicatorsSelect';

import { Tooltip } from '@src/components/Tooltip';
import { IndicatorsIds } from '@src/constants';
import { FullscreenController } from '@src/core/Fullscreen';
import { UndoRedo, type UndoRedoState } from '@src/core/UndoRedo';
import { t } from '@src/translations';
import { ChartSeriesType } from '@src/types';
import { Timeframes } from '@src/types/timeframes';
import { useObservable } from '@src/utils';

import { Dropdown } from '../Dropdown';
import {
  BarIcon,
  BurgerMenuIcon,
  CameraIcon,
  CandleStickIcon,
  FullscreenIcon,
  LineIcon,
  PlusCircleIcon,
  RedoIcon,
  SearchIcon,
  UndoIcon,
} from '../Icon';
import { SeriesMenu, SnapshotMenu, TimeframesMenu } from '../Menu';

import styles from './index.module.scss';

const defaultUndoRedoState: UndoRedoState = {
  canUndo: false,
  canRedo: false,
};

const defaultUndoRedoState$ = of(defaultUndoRedoState);

interface HeaderProps {
  timeframes: Timeframes[];
  selectedTimeframeObs: Observable<Timeframes>;
  setTimeframe: (value: Timeframes) => void;
  seriesTypes: ChartSeriesType[];
  setSelectedSeries: (next: ChartSeriesType) => void;
  selectedSeriesObs: Observable<ChartSeriesType>;
  showSettingsModal: (() => void) | undefined;
  addIndicatorToChart: (id: IndicatorsIds) => void;
  toggleToolbarVisible: () => boolean;
  showCompareButton: boolean;
  showSymbolSearchButton: boolean;
  undoRedo: UndoRedo | undefined;
  showMenuButton?: boolean;
  showFullscreenButton?: boolean;
  fullscreen: FullscreenController;
  openCompareModal?: () => void;
  openSymbolSearchModal?: () => void;
  copyImage?: () => Promise<void>;
  isMXT: boolean;
}

export function Header({
  setTimeframe,
  selectedTimeframeObs,
  setSelectedSeries,
  selectedSeriesObs,
  timeframes,
  seriesTypes,
  showSettingsModal,
  addIndicatorToChart,
  toggleToolbarVisible,
  showCompareButton,
  showSymbolSearchButton,
  fullscreen,
  undoRedo,
  showFullscreenButton,
  showMenuButton,
  openCompareModal,
  openSymbolSearchModal,
  copyImage,
  isMXT,
}: HeaderProps) {
  const [isToolbarOpen, setIsToolbarOpen] = useState(showMenuButton ?? false);
  const [isFullscreen, setIsFullscreen] = useState(fullscreen.isFullscreen);

  const undoRedoState = useObservable(undoRedo?.getState() ?? defaultUndoRedoState$, defaultUndoRedoState);

  useEffect(() => {
    const unsubscribe = fullscreen.onChange(() => {
      setIsFullscreen(fullscreen.isFullscreen);
    });

    return unsubscribe;
  }, [fullscreen]);

  const selectedTimeframe = useObservable(selectedTimeframeObs);
  const selectedSeries = useObservable(selectedSeriesObs);

  const seriesDropdownValue =
    selectedSeries === 'Line' ? <LineIcon /> : selectedSeries === 'Bar' ? <BarIcon /> : <CandleStickIcon />;

  const handleOpenToolbar = (): void => {
    setIsToolbarOpen(toggleToolbarVisible());
  };

  return (
    <header className={styles.header}>
      <div className={styles.group}>
        {showMenuButton && (
          <Tooltip
            location="bottom"
            label={t(isToolbarOpen ? 'Hide drawing toolbar' : 'Show drawing toolbar')}
          >
            <Button
              size="sm"
              className={`${styles.button} ${isToolbarOpen ? styles.pressed : ''}`}
              onClick={handleOpenToolbar}
              label={<BurgerMenuIcon />}
            />
          </Tooltip>
        )}

        {showSymbolSearchButton && (
          <Tooltip
            location="bottom"
            label={t('Symbol search')}
          >
            <Button
              size="sm"
              className={styles.button}
              onClick={openSymbolSearchModal}
              label={<SearchIcon />}
            />
          </Tooltip>
        )}

        {showCompareButton && (
          <Tooltip
            location="bottom"
            label={t('Compare symbols')}
          >
            <Button
              size="sm"
              className={styles.button}
              onClick={openCompareModal}
              label={<PlusCircleIcon />}
            />
          </Tooltip>
        )}
      </div>

      {(showMenuButton || showCompareButton || showSymbolSearchButton) && (
        <Divider
          direction="vertical"
          pt={{ divider: { className: styles.divider } }}
        />
      )}

      <Tooltip
        location="bottom"
        label={t('Timeframe')}
      >
        <Dropdown
          menuClassName={styles.menu}
          selectedValue={selectedTimeframe ? t(selectedTimeframe) : selectedTimeframe}
        >
          <TimeframesMenu
            onClick={setTimeframe}
            {...{ selectedTimeframe, timeframes }}
          />
        </Dropdown>
      </Tooltip>

      <Divider
        direction="vertical"
        pt={{ divider: { className: styles.divider } }}
      />

      <div className={styles.group}>
        <IndicatorsSelect
          addIndicatorToChart={addIndicatorToChart}
          isMXT={isMXT}
        />

        {showSettingsModal && (
          <Button
            size="sm"
            className={styles.button}
            onClick={showSettingsModal}
            label={t('Settings')}
          />
        )}

        <Tooltip
          location="bottom"
          label={t('Chart type')}
        >
          <Dropdown
            menuClassName={styles.menu}
            selectedValue={seriesDropdownValue}
          >
            <SeriesMenu
              selectedType={selectedSeries}
              seriesTypes={seriesTypes}
              onClick={setSelectedSeries}
            />
          </Dropdown>
        </Tooltip>
      </div>

      {undoRedo && (
        <Divider
          direction="vertical"
          pt={{ divider: { className: styles.divider } }}
        />
      )}

      <div className={styles.group}>
        {undoRedo && (
          <>
            <Tooltip
              location="bottom"
              label={t('Undo')}
            >
              <Button
                size="sm"
                className={styles.button}
                onClick={undoRedo.undo}
                disabled={!undoRedoState?.canUndo}
                label={<UndoIcon />}
              />
            </Tooltip>

            <Tooltip
              location="bottom"
              label={t('Redo')}
            >
              <Button
                size="sm"
                className={styles.button}
                onClick={undoRedo.redo}
                disabled={!undoRedoState?.canRedo}
                label={<RedoIcon />}
              />
            </Tooltip>
          </>
        )}

        {(copyImage || showFullscreenButton) && (
          <Divider
            direction="vertical"
            pt={{ divider: { className: styles.divider } }}
          />
        )}

        <div className={styles.group}>
          {copyImage && (
            <Tooltip
              location="bottom"
              label={t('Snapshot')}
            >
              <Dropdown
                menuClassName={styles.menu}
                selectedValue={<CameraIcon />}
              >
                <SnapshotMenu onCopyImage={copyImage} />
              </Dropdown>
            </Tooltip>
          )}

          {showFullscreenButton && (
            <Tooltip
              location="bottom"
              label={t(isFullscreen ? 'Exit fullscreen' : 'Fullscreen')}
            >
              <Button
                size="sm"
                className={`${styles.button} ${isFullscreen ? styles.pressed : ''}`}
                onClick={() => fullscreen.toggle()}
                label={<FullscreenIcon />}
              />
            </Tooltip>
          )}
        </div>
      </div>
    </header>
  );
}