/react-pluggable-commands-exercise

Упражнение на улучшение кода react-компонента

Primary LanguageTypeScript

Упражнение на улучшение кода react-компонента

В репозитории находится приложение со списком, над строками которого можно поизводить действия (команды): Increase, Decrease и Print Summary.

Команда Increase увеличивает поле amount у выбранных объектов на единицу. Она не доступна для объектов, у которых name === 'Const'.

Команда Decrease уменьшает поле amount у выбранных объектов на единицу. Она не доступна для объектов, у которых name === 'Const' и для объектов у которых amount уже равен нулю.

Обе команды Increase и Decrease доступны как из верхнего тулбара (где они пременяются ко всем выделенным строкам), так и из контекстного меню каждой из строк.

Команда Print Summary не модифицирует выбранные строки, но показывает последовательно 2 диалога. В первом показывается статус, иммитируя затратные вычисления, после чего открывается второй диалог, котрый показывает результат: сумму amount для выбранных строк. Эта команда не имеет смысла для одиночной строки, поэтому не отображается в контекстном меню - только в тулбаре.

Вся эта функциональность находится в компонете Grid: он содержит стейт, необходимый для выполнения некоторых команд, реализует логику выполнения этих команд, отвечает за то, какие именно значки/названия отображаются для этих команд и т.д.

Задание 1: добавить команду Rename

Для начала, мы не будем трогать то, как написан Grid компонент, а просто расширим его функциональность "в лоб".

Эта команда будет выводить на экран диалог с полем для редактирования name объекта и кнопку Rename

Отображение диалога и его внутреннего состояния можно реализовать дополнительными свойствами в стейте Grid коомпонента

Нажатие кнопки Rename внутри диалога скроет диалог и по аналогии с командами Increase/Decrease вызовет метод handleCommandComplete с измененными объектами.

Кстати команда Rename в тулбаре будет доступна, только если выбрана одна строка. Кроме того она будет применима к объектам с name === 'Const' и также доступна в контекстном меню.

Задание 2: избавится от реализации функционала команд внутри Grid компонента

Сейчас, когда Grid содержит в себе всю реализацию всех команд, мы не можем добавть/убрать/поменять команду без изменения самого Grid. Мы не можем экспортировать Grid без команд в отдельный пакет - код слишком монолитен. Всё очень плохо.

Задача заключается в том, чтобы убрать имплементацию и вообще любое знание о конкретных командах из кода Grid и передавать ее в компонент извне.

Чтобы в итоге все команды передавались в Grid через props например таким образом:

<div className="app">
  <Grid
    commands={[
      IncreaseCommand,
      DecreaseCommand,
      RenameCommand,
      PrintSumCommand,
    ]}
  />
</div>

Передаваемые объекты команд могут реализовывать какой-нибудь интерфейс, позволяющий Grid отобразить/не отобразить/задизейблить кнопку в тулбаре, пункт в контекстном меню строки, и как-нибудь запустить саму команду, передав ей выделенные строки и колбэк на измененные строки.

Некоторые команды требуют рендера диалогов (PrintSumCommand и RenameCommand) - надо предусмотреть и это.