List → Detail → Edit

Most of an internal tool: find a record in a list, open it, change it, save. Here with invoices, made only of Canon's components. Open an invoice, edit it, save; or change something and try to leave.

The pattern

An App Shell with the three steps as views of one page. In an app, each is its own address: /invoices, /invoices/2041, /invoices/2041/edit.

Invoices

10 invoices · €72,580.00 outstanding

Invoices
InvoiceCustomerDueAmountStatus
INV-2041Globex Corporation€12,400.00Overdue
INV-2040Initech€6,900.00Due soon
INV-2039Umbrella€3,150.00Paid
INV-2038Soylent€980.00Sent
INV-2037Hooli—€15,000.00Draft
INV-2036Vandelay Industries€2,200.00Paid
INV-2035Stark Industries€45,000.00Overdue
INV-2034Wayne Enterprises€7,300.00Sent
INV-2033Acme Corp€640.00Paid
INV-2032Cyberdyne€12,000.00Draft

Discard your changes?

Your changes to this invoice haven't been saved.

The list

A Page Header names the collection and holds what you can do to it: one primary action (New invoice), the rest neutral.

A Data Table finds the record: its own search and filters (a column, a condition, a value), sorting, pages. Its status column is a Status Indicator per row: quiet, so the eye can run down the column.

Each record opens from its name, a link in the row's header cell (th scope="row"), not from a click anywhere on the row: links can be opened in a new tab, copied and read as links, and the row's other cells stay selectable.

The record

A back link up to the list, the record's name as the title and its status beside it, as a Tag: the one status on the page, so it can be louder than the list's.

Its actions: what the page is for is the primary one (Send reminder); Edit is neutral, and also beside the part it edits.

Its parts in Tabs, each a Card: facts in a Description List, rows in a Table running edge to edge, events as Status Indicators.

Editing

A page of its own when there's more than a field or two to change (a Drawer for a quick change beside the list; a field in place for one value). Its back link goes to the record, not the list.

The form ends with a Save Bar: it counts the changes, Discard brings the record back, Save (or ⌘S) saves. Saving goes back to the record, which shows the new values, and a Toast says it's done.

Leaving with changes asks first: closing the page through the browser's own question; leaving inside the app through an alert Dialog, which the app opens when the bar's data-state is changed.