I have been wondering what functionalities are usually undoable and which not. For example, in Excel writing content into cells can be reverted, freezing panes or adding comments not. Is there a reasoning on what to include in undo?
The general usability principle is that any action the user can do can be reverted with no more effort than it took to execute in the first place. I call it the “reversion effort principle.” Jordi Jove gives some reasons that it may be technically, legally, or logically infeasible to uphold this principle (e.g., If a user deletes their account, how can they have the authority to undelete it? They don’t have an account). However, if it takes two clicks to change X to Y, then it ideally it should take no more than two clicks to change Y to X. If it takes three or four clicks, well, that’s not ideal, but it’s better than five clicks and typing 130 characters. When considering the effort to revert an action, include any mental or other off-application actions, such as remembering or reconstructing or referencing those 130 characters the user needs to type.
In Excel, freezing the panes takes two or three clicks. Unfreezing the panes likewise take two or three clicks using the same menu item. Adding a comment takes a click or two, plus however long it takes to type the comment. Removing the comment (with the Delete Comment menu item) takes as little as one click. Many commands that can be reverted (undone) using the same UI element that did them in the first place. That’s consistent with the reversion effort principle and pretty intuitive too.
The Undo feature should cover actions that otherwise cannot be reverted as easily as they are executed. Deleting a bunch of cells in Excel takes a mere drag and a keypress. Retyping all those cell contents would take a lot more effort and may even be impossible. Even deleting part of the contents of a single cell can be much harder to revert, if the user deleted a part of a complicated formula. I guess you could argue that if the user deletes a single character, then that does not need to be in Undo, but at that point, you probably want to include it for consistency sake, even though you don’t have to under the reversion effort principle. When in doubt, include it under Undo.
In practice, Undo tends to cover “edit” commands, that is, commands that transform the underlying data values (e.g., the actual content in a spreadsheet, such as with delete, cut, format, insert). Undo tends to not cover “View” commands, that is, inputs that merely change the presentation of the underlying data, such as with Freeze Pane and View Headings. Perhaps users and programmers think of it that way, and put anything transformational in Undo and leave out anything presentational. However, that’s more a collateral effect of the reversion effort principle. If a grid in your web app has a “Default View” button that changes the sort order, filtering, column width and order, and word-wrap to a standard setting, then there should be a way in a click or two to undo that, rather than making the user reconstruct the presentation all over again.
But why not put everything in Undo? There may be another way to easily revert, say, freeze panes, but wouldn’t it benefit the user if they knew there was one place they can go to unhose things if they accidentally hose something up? A case can be made to put everything in Undo. Sometimes, the user doesn’t know what they did so doesn’t know how to revert it. I once saw a user almost panic when, while editing a document on her laptop, the whole document suddenly appeared blank. The user had unknowingly typed Ctrl-N and now a new blank document appeared over her old one. Under the reversion effort principle, this wasn’t a problem: one click of the X button would return the user to her document. But the user didn’t know to do that. Maybe the New command should be under Undo.
However, you may want to reserve Undo only for commands that really need it. Some apps (older, simpler apps mostly), only stack a small number of commands in Undo. Some only cover the most recent command. You don’t want a command that can be reverted easily elsewhere to kick off of the stack a command that can’t be reverted easily. Even if your app stacks many commands to Undo, all those easy-to-revert commands can bury the command the user needs to revert, making it harder to find and, with “historic” Undo, and a pain to get –lots of Ctrl-Z-ing. In another case I witnessed, a user thought she had accidentally cleared her entire spreadsheet. Actually, she unknowingly clicked the horizontal scrollbar. Should every scroll command be in Undo? Often the users need to undo one command but not others that occurred afterward. For example, a user may only realize they deleted the wrong datapoint after zooming and rotating a data visualization. If zooming and rotating were in Undo, then un-deleting the datapoint would also mean re-doing the zooming and rotating, assuming traditional historic Undo. A lot of these issues can be mitigated if you implement Selective Undo. If you’re going to blaze a trail with Selective Undo, you should consider saving more commands in Undo.
Interesting question. The first thing that comes to my mind is a system connected with another system that it's not under your control. For example: If I send an email or transfer money to a bank account once the action is completed and the email/money has arrived to the other system it is not possible to undo the action.
Another scenario would be persistent delete operations. I've seen warning messages about non reversible operations when you try to delete your account in some apps and I guess that companies are obliged per law to allow users to delete their accounts, so probably legal requirements don't allow the software to perform an undo operation, even if the company still keeps the data for other legal reasons (police requirements,...)