Software exists to support humans while they are performing specific tasks.
Yet most software, especially administrative software designed for desktop or the web, is not taking these tasks in mind.
Traditional forms over data (aka CRUD) apps expose all the internal details to the user and expect them to bend their reality to the software.
That doesn't work!
You can't make a dog bark by cutting open its chest and squeezing the lungs.
So why do we try to make users perform tasks by exposing the internals of a system?
We can do better!
A task-oriented user interface adapts itself to the task that the user intends to perform and to the context in which this task is performed.
Such an interface is designed to make the users life easier by bringing the tasks relevant to the situation to the forefront.
Here is a screenshot of an app that I purpose-built to deliver fundraising orders at our club. Sorry that the screenshots are in dutch, this particular app still needs to be translated.
The entire app has been built to support this specific scenario and make my life easier in this specific context.
Show relevant state only
This all starts by showing only the information relevant to the current context.
When I'm going to deliver orders, I only want to see a list of undelivered orders.
If I was going to reconcile orders, I would want to see the invoiced ones... but that is not the case.
So, don't show me irrelevant information, you know, 'just in case'.
It only adds to the mental load and makes the software harder to use.
Show related tasks only
Similar to showing only relevant state, you also do not want to show tasks that are irrelevant in the current context.
When a I am going to deliver orders, I only need a button to deliver the order and nothing else.
If, on a rare occasion, a secondary task needs to be performed in this same context, then add a hidden option to do so (e.g. a dropdown), but make only the primary task very prominent.
A form per task
When the task is started, show a purpose-built form for each task.
Each task really deserves its own form!
Only show as few form fields as required to perform the job.
Prepopulate them if you can.
Make the form as easy and quick to fill out as possible.
In the form above, the green button indicates the payment status of the order. When green I can proceed to deliver the order. When red, I'll ask the orderer to pay cash. A simple push on the button will confirm an exact cash payment in the system.
The form allows me to proceed to the next order regardless.
When the form is submitted, ensure to provide appropriate feedback.
If the task is completed, update the state to reflect this. In the app shown above the order will disappear from the undelivered list after the delivery form is submitted, so that it doesn't bother me in any way anymore.
This app has been designed to work offline though. So as soon as there are changes locally that have not yet been synchronized to the cloud, the synchronization icon in the top right will turn red to warn me about the pending changes.
In some scenarios a task may be initiated after filling out the form, but won't have completed yet. In that case, do present a text to explain what is going to happen and, if possible, show a list of tasks with their respective completion status somewhere (this can be out of sight).
In each case, ensure the feedback is aligned with the nature of the processing pattern chosen to process it behind the scenes.
Multiple apps are recommended
I can only recommend to create multiple small apps, each with a specific context in mind, over a single large app that contains everything and the kitchen sink.
The smaller the app, the easier it is to adjust it to the context in which a task has to be performed.
From bringing the right data and components to the forefront, to adjusting the online/offline behavior, all of these aspects can vary wildly between tasks and operational context.
So the more of these tasks you put together, the harder it becomes to adjust.
It's not only the task itself that decides how the app should behave, but also the device used to interact with the app and the environment the device is used in.
The delivery app shown above has been designed for use on a portable laptop, because we used to deliver our goods indoors before the pandemic hit.
But during the pandemic, we had to move delivery outdoors. In the outdoors, using a phone might have been a better choice (except when it freezes in winter).
On a phone, typing a name to find the order is not convenient. Scanning a QR code would be a better method instead.
Depending on how the pandemic will evolve and whether delivery will continue outside in the future, I might change how the app behaves if used from a phone.
It's not more work
The number one objection against building applications with task orientation in mind is the potential increase in the work required to build UIs.
Creating many purpose-built visualizations, forms and apps may appear to be more work at first sight. But it really isn't.
Instead of heaving a few yet super complex components and apps... you'll have many simple ones that are easier to reason about.
And let's be honest. No matter how you build an app, it will take years before users start to love it...
Reuse is a fallacy
The second most common, follow up, objection is that of reusability.
It is true, purpose-built components often can't be reused.
But remember, before a component becomes re-useable, it must first be useable.
And that can only be achieved when it is built for purpose.