node-tasks-app
node-tasks-app copied to clipboard
[FEATURE] Using partials and conditionals for UI
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: booleanparameter 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
titleandmessage. - 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!