A list page shows one kind of record. A combined view shows several at once, nested: clients, and under each client its projects, its documents and its invoices. You describe the shape once, save it, and it is there the next time.
Your account starts with two views: Clients overview and Project work.
What a view is made of
A view is a stack of up to four levels, from the outside in. The top level is the records the view starts from. Each level below it is reached through a relationship — "the projects of this client", "the tasks of this project".
Eight kinds of record can appear in a view: clients, projects, tasks, documents, invoices, transactions, time entries and subscriptions. Any of them can start a view. Below the top level you pick from the kinds that are actually related to the level above — time entries hang off tasks, for instance, and subscriptions off transactions.
A level can hold more than one set of records — up to four of them. That is what lets a client expand into its projects and its documents side by side, rather than making you choose. Each set is fetched and paged on its own, and gets its own heading row naming its columns — because a project and a document do not have the same fields, and one shared header would have to lie about one of them.
Every set can also be grouped by one of its fields before it is listed. Grouping transactions by type, for example, turns one long list into an Income row and an Expenses row, each opening onto its own records. Groupings stack up to three deep: group by type and then by client, and you get clients inside each of the two.
Grouping by an interval
Some fields have too many distinct values to group by directly — a date is almost never shared by two records, and neither is an exact amount, so grouping by either would give you one group per row. Those fields are grouped by the Interval or Bucket size they fall in instead, chosen beside the field:
- Dates — a day, a week, a month, a quarter or a year. Transactions by month, invoices by the quarter they were issued in, anything by the week it is due.
- Amounts — a range you set the width of. A bucket size of 1,000 puts every invoice between 1,000 and 2,000 in one group, the next thousand in the next, and so on.
Weeks start on Monday, and every interval is worked out from the calendar date on the record rather than from your timezone, so a month holds exactly the days that are in it.
Because the interval is part of the grouping, the same field can be grouped twice at different widths: by year and then by month gives you months inside years. Two groupings at the same width is still refused — the inner one would hold a single group per outer one, which is a level of indentation and nothing else.
Two things a range cannot do. It does not know which currency it is in, because one set of records can hold invoices in three — so an amount range shows bare numbers unless a Currency grouping sits above it, which settles the question. And a grouping that would produce more than 500 groups is refused with a message rather than truncated, so you are never shown a partial answer that looks complete: widen the interval, or narrow the set's filter.
Filtering a layer
Each set of records has its own filter, and a filter is a tree of conditions rather than a flat list. You choose All of or Any of for a group of conditions, and you can nest a group inside another one.
That is the difference from the filters on a list page, where conditions on different columns always combine with and. Here you can ask for "status is Active or deadline is before the end of the month", which a list page cannot express at all.
A condition is a field, how it compares, and a value. There are fourteen comparisons in all, and each field is offered the ones that make sense for it: text can contain or start with something, numbers and dates can be greater, less or between, and a status or a tag can be one of a set. Two comparisons — is empty and is not empty — take no value at all.
A set with no conditions shows everything, which is not the same as a group with no conditions in it. Emptying a group removes it.
One group holds at most nine conditions, a filter at most 64 conditions and groups counted together, and groups nest at most three levels deep. Past any of those bounds the view is refused rather than saved, because a rule tree that size compiles into a query nobody wants to wait for — and one that shape is no longer readable back.
Tabs
Open views are tabs across the top of the page.
- + starts a new view. It is a draft: it lives only in this browser, and it is marked in the tab strip until you save it.
- Save view turns the draft into a saved view. From then on it is stored in your account and reaches every device. It sits on the structure page, which is where a view is written.
- × closes a tab. Closing a saved view does not delete it — the view stays in your account.
- Open view lists every saved view that is not already open — a table you can search and sort, showing each view's description and when it last changed, so you can tell two similarly named views apart before opening either. It is where a closed one comes back from, and where you delete one for good.
Right-click a tab to rename it, close it, or move it left or right. Renaming a saved view renames it everywhere; renaming a draft only changes it here. Moving is also Alt with the left or right arrow key while the tab is focused, and only saved views can move — a draft has no position to keep.
Each tab has its own address, so a view can be bookmarked, and a link to one opens the same view for you on another device. The rows you had open are remembered per tab, so looking at the tab next door and coming back leaves the tree as you left it. Changing a view's structure closes it again, because the rows that were open may not exist in the new shape.
How the rows load
A view fetches one level at a time. Only the top level loads when you open the page; a level below it is fetched when you expand the row above it, and each level pages independently. A branch you never open costs nothing.
The top level pages like every other table in the app: a page picker under the rows, honouring the page size you set for lists. A level below it is a run of rows opened inside a parent, so it grows instead of turning over — Show N more adds the next batch underneath, and what you were already reading stays put.
Two things follow from that, and both are easy to misread:
A row can stay empty. A client whose projects all fail the filter still appears, and expands to show nothing. That is the honest answer — "this client has no projects matching your rules" — rather than dropping the client and leaving you wondering where it went.
A nested level can hold more rows than its parent. A project can be linked to several clients, so it appears under each of them. Adding up a level and comparing it with the level above will not reconcile, and nothing is wrong when it does not.
Working with a row
A row in a view is the record itself, and everything you can do to it on its own list page you can do here.
Its name opens it. Clicking the name in the first column goes to that record's page. Names inside a cell are links too — the projects on a task, the client on an invoice — and where a cell holds more of them than fit, +2 opens the rest.
Cells are drawn the way that record's own page draws them. An amount in the currency it was billed in rather than a bare number, a date in your format, a status as its coloured badge, tags as chips.
You can edit in place. Hover a cell and a pencil appears; Enter or the tick saves, Escape or the cross discards. A field that has no pencil on its own list page has none here either — a total that is the sum of its lines is still calculated rather than typed.
Right-click a row for the same menu that record has on its list page: open, duplicate, flag, delete, and the rest. Whatever you do from there, the view catches up on its own.
Group rows have none of this. A group stands for several records, so there is nothing to open, edit or delete.
Sorting
Click a column heading to sort by it — once for ascending, again for descending, a third time to clear it. The first column, the one holding each record's name, sorts too.
A set you have not sorted rests in the order that entity's own list page uses: invoices by issue date, transactions by date, documents by when they last changed, and most of the rest newest first.
Sorting applies to the whole set of records, not to the one branch you clicked in. The invoices under one client and the invoices under another are the same set, so they move together; ordering them separately would leave two parts of the same page disagreeing.
The order lives in the page address rather than in the view, and it is not alone there: the address also holds which rows you have opened and which page the top level is on. A link therefore opens the view the way you were reading it. None of it is a change to the view — nobody else's copy moves — and how far you have rolled one branch open past its first page is not kept, so opening the link again starts that branch at one page.
What a view does not do
A view holds no records. It is a description of what to read, so deleting one changes nothing about the clients, projects or invoices it was showing — and editing a cell in a view edits the record, not the view.
Exporting a view
Export turns the view on screen into a file — the tab you are looking at, saved or not, so you never have to save a view just to get a file out of it, and in the order you sorted it into.
The file has one sheet per set of records, because a level of clients and a level of documents do not share columns and one table would have to mislabel one of them. Nesting is kept as indentation: a project sits indented under its client, in the order it appears on screen. It carries the columns the view carries, so the file matches what you were reading — which is not true of every export in the app.
A CSV holds only the first sheet, since the format has no notion of a second one. Choose Excel or PDF to keep the whole view. A very large view is refused rather than truncated; narrow its filters and try again.