node-tasks-app icon indicating copy to clipboard operation
node-tasks-app copied to clipboard

[FEATURE] Using partials and conditionals for UI

Open raycharius opened this issue 4 years ago • 0 comments

Is there an existing request for this?

  • [X] I have searched for any related issues and avoided creating a duplicate issue.

Have you read our code of conduct?

  • [X] I have read and agree to the code of conduct

Feature as a user story

I recently released an update to the slack-block-builder library that includes helper functions for inline conditionals, which can be helpful in a few places here, for example:

const { Modal, Blocks, Elements } = require('slack-block-builder');

module.exports = (prefilledTitle, currentUser) => {
  const textInput = (taskTitle) => {
    if (taskTitle) {
      return Elements.TextInput({
        placeholder: 'Do this thing',
        actionId: 'taskTitle',
        initialValue: taskTitle,
      });
    }
    return Elements.TextInput({
      placeholder: 'Do this thing',
      actionId: 'taskTitle',
    });
  };

  return Modal({ title: 'Create new task', submit: 'Create', callbackId: 'new-task-modal' })
    .blocks(
      Blocks.Input({ label: 'New task', blockId: 'taskTitle' }).element(
        textInput(prefilledTitle),
      ),
      Blocks.Input({ label: 'Assign user', blockId: 'taskAssignUser' }).element(
        Elements.UserSelect({
          actionId: 'taskAssignUser',
        }).initialUser(currentUser),
      ),
      Blocks.Input({ label: 'Due date', blockId: 'taskDueDate', optional: true }).element(
        Elements.DatePicker({
          actionId: 'taskDueDate',
        }),
      ),
      Blocks.Input({ label: 'Time', blockId: 'taskDueTime', optional: true }).element(
        Elements.TimePicker({
          actionId: 'taskDueTime',
        }),
      ),
    ).buildToJSON();
};

This can easily become the following:

const { Modal, Blocks, Elements, setIfTruthy } = require('slack-block-builder');

module.exports = (prefilledTitle, currentUser) => Modal({
  title: 'Create new task',
  submit: 'Create',
  callbackId: 'new-task-modal',
})
  .blocks(
    Blocks.Input({ label: 'New task', blockId: 'taskTitle' }).element(
      Elements.TextInput({
        placeholder: 'Do this thing',
        actionId: 'taskTitle',
        initialValue: setIfTruthy(prefilledTitle, prefilledTitle),
      })
    ),
    Blocks.Input({ label: 'Assign user', blockId: 'taskAssignUser' }).element(
      Elements.UserSelect({
        actionId: 'taskAssignUser',
      }).initialUser(currentUser),
    ),
    Blocks.Input({ label: 'Due date', blockId: 'taskDueDate', optional: true }).element(
      Elements.DatePicker({
        actionId: 'taskDueDate',
      }),
    ),
    Blocks.Input({ label: 'Time', blockId: 'taskDueTime', optional: true }).element(
      Elements.TimePicker({
        actionId: 'taskDueTime',
      }),
    ),
  ).buildToJSON();

It gets rid of the if, the duplicated copy, and keeps the view's code similar to the view itself. There are a few other similar places.

Another idea was to include partials, which was something we touched on during the talk around Tasks App at Frontiers:

  • Currently the navigation for the App Home is duplicated, they only differ in which button is primary. Could move those to a function that accepts a isOpenTasks: boolean parameter and returns the navigation with the correct button highlighted.
  • There is a general UI for empty task lists, that could be moved to a function that accepts a title and message.
  • I wonder if the open tasks checklist generation may also be moved to a partial to reduce the cognitive complexity of the view, where it could essentially be:
module.exports = (openTasks) => HomeTab({
  callbackId: 'tasks-home',
  privateMetaData: 'open',
}).blocks(
  partials.homeTabNavigation({ isOpenTasks: true }),
  openTasks.length === 0
    ? partials.emptyTaskListContent({
      title: 'No open tasks',
      message: 'Looks like you\'ve got nothing to do.',
    })
    : partials.openTaskListContent(openTasks),
).buildToJSON();

Let me know what you think – happy to send over a PR!

raycharius avatar Dec 13 '21 10:12 raycharius