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


import classNames from 'classnames';
import { Button, Divider, Tooltip } from 'exchange-elements/v2';

import { Dispatch, SetStateAction, useRef, useState } from 'react';

import { Observable } from 'rxjs';

import { MenuList } from '@src/components/Menu';
import SplitDropdown from '@src/components/SplitDropdown';

import { geometricShapes, measurementTools, trendLines } from '@src/components/Toolbar/constants';

import { DrawingsNames } from '@src/constants';
import { ActiveDrawingTool } from '@src/types';
import { ensureDefined, useObservable } from '@src/utils';

import {
  CrossIcon,
  EyeBrushIcon,
  HeartIcon,
  LayersIcon,
  MagnetIcon,
  PencilLockerIcon,
  RulerIcon,
  SlidersCircleIcon,
  SplineCurveIcon,
  TrashIcon,
  TypeIcon,
  UnlockIcon,
  ZoomInIcon,
} from '../Icon';

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

interface ToolbarProps {
  toggleDOM: () => void;
  addDrawing: (name: DrawingsNames) => void;
  setEndlessDrawingsMode: (value: boolean) => void;
  isEndlessDrawingsMode$: Observable<boolean>;
  activateCrosshair: () => void;
  activeTool$: Observable<ActiveDrawingTool>;
}

const implemented = {
  crosshair: true,
  lines: true,
  fib: false,
  rectangle: true,
  text: true,
  XABCD: false,
  position: true,
  icons: false,
};

const TOOLTIP_CLASSNAME = 'moex-chart-drawing-tooltip';

export default function Toolbar({
  toggleDOM,
  addDrawing,
  setEndlessDrawingsMode,
  isEndlessDrawingsMode$,
  activateCrosshair,
  activeTool$,
}: ToolbarProps) {
  const [selectedLineType, setSelectedLineType] = useState<DrawingsNames>(DrawingsNames.trendLine);
  const [selectedMeasurementTool, setSelectedMeasurementTool] = useState(DrawingsNames.fixedRangeProfile);
  const [selectedGeometricShape, setSelectedGeometricShape] = useState(DrawingsNames.rectangle);

  const isEndlessDrawingsMode = useObservable(isEndlessDrawingsMode$);

  const activeTool = useObservable(activeTool$, 'crosshair');

  const toolbarRef = useRef<HTMLDivElement | null>(null);

  const createDrawingHandler = (setter: Dispatch<SetStateAction<DrawingsNames>>) => (value: DrawingsNames) => {
    setter(value);
    addDrawing(value);
  };

  const findOptionByValue = <T extends { value: string }>(options: T[], selectedValue: T['value']): T | undefined =>
    options.find((item) => item.value === selectedValue);

  const selectedTrendLineOption = findOptionByValue(trendLines, selectedLineType);
  const selectedMeasurementToolOption = findOptionByValue(measurementTools, selectedMeasurementTool);
  const selectedGeometricShapeOption = findOptionByValue(geometricShapes, selectedGeometricShape);

  const getButtonClassName = (tool: ActiveDrawingTool) =>
    classNames(styles.button, {
      [styles.pressed]: activeTool === tool,
    });

  return (
    <div
      ref={toolbarRef}
      className={styles.toolbar}
    >
      <div className={classNames(styles.group)}>
        {implemented.crosshair && (
          <Tooltip
            tooltipClassName={classNames(styles.tooltipHint, TOOLTIP_CLASSNAME)}
            showMessageOnFocus
            label="Перекрестие"
            location="right"
          >
            <Button
              size="sm"
              onClick={activateCrosshair}
              className={getButtonClassName('crosshair')}
              label={<CrossIcon />}
            />
          </Tooltip>
        )}
        {implemented.lines && (
          <SplitDropdown
            anchorRef={toolbarRef}
            mainContent={ensureDefined(selectedTrendLineOption?.icon)}
            mainTooltip={ensureDefined(selectedTrendLineOption).label}
            onMainClick={() => addDrawing(selectedLineType)}
            menuTooltip="Линии тренда"
            mainButtonClassName={getButtonClassName(selectedLineType)}
          >
            <MenuList
              mode="single"
              value={selectedLineType}
              options={trendLines}
              onClick={createDrawingHandler(setSelectedLineType)}
            />
          </SplitDropdown>
        )}
        {implemented.fib && (
          <Tooltip
            tooltipClassName={classNames(styles.tooltipHint, TOOLTIP_CLASSNAME)}
            showMessageOnFocus
            label="Коррекция по Фибоначчи"
            location="right"
          >
            <Button
              size="sm"
              className={styles.button}
              onClick={() => {}}
              label={<SlidersCircleIcon />}
            />
          </Tooltip>
        )}
        {implemented.rectangle && (
          <SplitDropdown
            anchorRef={toolbarRef}
            mainContent={ensureDefined(selectedGeometricShapeOption?.icon)}
            mainTooltip={ensureDefined(selectedGeometricShapeOption).label}
            onMainClick={() => addDrawing(selectedGeometricShape)}
            menuTooltip="Геометрические фигуры"
            mainButtonClassName={getButtonClassName(selectedGeometricShape)}
          >
            <MenuList
              mode="single"
              value={selectedGeometricShape}
              options={geometricShapes}
              onClick={createDrawingHandler(setSelectedGeometricShape)}
            />
          </SplitDropdown>
        )}
        {implemented.text && (
          <Tooltip
            tooltipClassName={classNames(styles.tooltipHint, TOOLTIP_CLASSNAME)}
            showMessageOnFocus
            label="Текст"
            location="right"
          >
            <Button
              size="sm"
              className={getButtonClassName(DrawingsNames.text)}
              onClick={() => addDrawing(DrawingsNames.text)}
              label={<TypeIcon />}
            />
          </Tooltip>
        )}
        {implemented.XABCD && (
          <Tooltip
            tooltipClassName={classNames(styles.tooltipHint, TOOLTIP_CLASSNAME)}
            showMessageOnFocus
            label="Шаблон XABCD"
            location="right"
          >
            <Button
              size="sm"
              className={styles.button}
              onClick={() => {}}
              label={<SplineCurveIcon />}
            />
          </Tooltip>
        )}
        {implemented.position && (
          <SplitDropdown
            anchorRef={toolbarRef}
            mainContent={ensureDefined(selectedMeasurementToolOption?.icon)}
            mainTooltip={ensureDefined(selectedMeasurementToolOption).label}
            menuTooltip="Инструменты для измерения и прогнозирования"
            onMainClick={() => addDrawing(selectedMeasurementTool)}
            mainButtonClassName={getButtonClassName(selectedMeasurementTool)}
          >
            <MenuList
              mode="single"
              value={selectedMeasurementTool}
              options={measurementTools}
              onClick={createDrawingHandler(setSelectedMeasurementTool)}
            />
          </SplitDropdown>
        )}
        {implemented.icons && (
          <Tooltip
            label="Значок"
            location="right"
            tooltipClassName={classNames(styles.tooltipHint, TOOLTIP_CLASSNAME)}
            showMessageOnFocus
          >
            <Button
              size="sm"
              className={styles.button}
              onClick={() => {}}
              label={<HeartIcon />}
            />
          </Tooltip>
        )}
      </div>
      <Divider
        direction="horizontal"
        pt={{ divider: { className: styles.divider } }}
      />
      <div className={classNames(styles.group)}>
        <Tooltip
          tooltipClassName={classNames(styles.tooltipHint, TOOLTIP_CLASSNAME)}
          showMessageOnFocus
          label="Линейка"
          location="right"
        >
          <Button
            size="sm"
            className={getButtonClassName(DrawingsNames.ruler)}
            onClick={() => addDrawing(DrawingsNames.ruler)}
            label={<RulerIcon />}
          />
        </Tooltip>

        <Tooltip
          tooltipClassName={classNames(styles.tooltipHint, TOOLTIP_CLASSNAME)}
          showMessageOnFocus
          label="Увеличить масштаб"
          location="right"
          className={styles.notImplemented}
        >
          <Button
            size="sm"
            className={styles.button}
            onClick={() => {}}
            label={<ZoomInIcon />}
          />
        </Tooltip>
      </div>
      <Divider
        direction="horizontal"
        pt={{ divider: { className: classNames(styles.divider) } }}
      />
      <div className={classNames(styles.group)}>
        <Tooltip
          tooltipClassName={classNames(styles.tooltipHint, TOOLTIP_CLASSNAME)}
          showMessageOnFocus
          label="Магнит позволяет притягивать точки объектов к ближайшим ценам (откр., макс., мин., закр.) баров"
          location="right"
          className={styles.notImplemented}
        >
          <Button
            size="sm"
            className={styles.button}
            onClick={() => {}}
            label={<MagnetIcon />}
          />
        </Tooltip>

        <Tooltip
          tooltipClassName={classNames(styles.tooltipHint, TOOLTIP_CLASSNAME)}
          showMessageOnFocus
          label="Продолжить в режиме рисования"
          location="right"
        >
          <Button
            size="sm"
            className={`${styles.button} ${isEndlessDrawingsMode ? styles.pressed : ''}`}
            onClick={() => setEndlessDrawingsMode(!isEndlessDrawingsMode)}
            label={<PencilLockerIcon />}
          />
        </Tooltip>

        <Tooltip
          tooltipClassName={classNames(styles.tooltipHint, TOOLTIP_CLASSNAME)}
          showMessageOnFocus
          label="Зафиксировать все объекты"
          location="right"
          className={styles.notImplemented}
        >
          <Button
            size="sm"
            className={styles.button}
            onClick={() => {}}
            label={<UnlockIcon />}
          />
        </Tooltip>

        <Tooltip
          tooltipClassName={classNames(styles.tooltipHint, TOOLTIP_CLASSNAME)}
          showMessageOnFocus
          label="Скрыть все объекты рисования"
          location="right"
          className={styles.notImplemented}
        >
          <Button
            size="sm"
            className={styles.button}
            onClick={() => {}}
            label={<EyeBrushIcon />}
          />
        </Tooltip>
      </div>
      <Divider
        direction="horizontal"
        pt={{ divider: { className: classNames(styles.divider) } }}
      />
      <div className={classNames(styles.group)}>
        <Tooltip
          tooltipClassName={classNames(styles.tooltipHint, TOOLTIP_CLASSNAME)}
          showMessageOnFocus
          label="Удалить объекты"
          location="right"
          className={styles.notImplemented}
        >
          <Button
            size="sm"
            className={styles.button}
            onClick={() => {}}
            label={<TrashIcon />}
          />
        </Tooltip>

        <Tooltip
          tooltipClassName={classNames(styles.tooltipHint, TOOLTIP_CLASSNAME)}
          showMessageOnFocus
          label="Дерево объектов"
          location="right"
        >
          <Button
            size="sm"
            className={styles.button}
            onClick={() => toggleDOM()}
            label={<LayersIcon />}
          />
        </Tooltip>
      </div>
    </div>
  );
}