Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FEATURE] Using partials and conditionals for UI #88

Open
2 tasks done
raycharius opened this issue Dec 13, 2021 · 0 comments
Open
2 tasks done

[FEATURE] Using partials and conditionals for UI #88

raycharius opened this issue Dec 13, 2021 · 0 comments
Labels
enhancement New feature or request

Comments

@raycharius
Copy link

raycharius commented Dec 13, 2021

Is there an existing request for this?

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

Have you read our code of conduct?

  • 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 raycharius added the enhancement New feature or request label Dec 13, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant