Listings become a table, with everything a table now gets #160

Closed
opened 2026-09-10 03:32:46 +00:00 by tiagoagueda · 1 comment
Owner

Observation

Split out of #136, which asked the question and said it should be decided rather than
assumed:

The listings page is not a table at all. ApplicationsTable and CompaniesTable are
the only two registered; jobs/listing_list.html renders its own rows, so none of the
sorting and filtering the suggestion opens by praising is available there. If the tables
are getting richer, the page most like a channel list — many rows, triaged in bulk, mostly
discarded — is the one that has none of it.

The decision made in #136: not there, here. Making listings a table is a page rewrite
rather than a table feature, and folding it into an issue that was already four features
would have meant doing it badly to finish something else.

What exists

jobs/listing_list.html draws its own rows. core/tables.py holds everything a registered
table gets for free, and two pages already have it:

Listings today A registered table
Sort by a column no yes, three states since #136
Filter per column, as you type no yes, server-side
Choose and order columns no yes, saved on the profile
Column widths no yes, saved on the profile
Select rows, act in bulk no yes, since #134
Edit a value in the cell no yes, since #135
Page size no yes

Why this page in particular

A listing is the shortest-lived thing Postulo holds. Most are discarded; the useful gesture
is look at forty, keep three, and that is exactly the shape bulk actions and per-column
filtering were built for. It is the page in this application closest to the channel list
that started #136, and the only one of the three that has none of what that comparison
produced.

Worth being careful about

The listings page has its own state that a table does not model. A listing is captured,
reviewed, kept or discarded, and DiscardReason records why. That is a workflow rather than
a column, and a choice filter over it is not obviously the same control as the review
screen it has now.

Bulk discard needs a reason. #134's bulk actions apply one action to many rows; discard
takes a reason per listing today. Either the bulk form asks once and applies it to all, or
discard is not one of the bulk actions — worth deciding rather than discovering.

Nothing about the capture flow should change. Capturing, reviewing and converting a
listing into an application are separate screens for good reasons, and this is about the
list, not about them.

The empty state is most of what somebody sees at first. A table with a Columns
control, a filter row and a bulk bar, over no rows at all, is worse than the page there is
now. Whatever is built has to look right at zero listings as well as at four hundred.

Classification

Enhancement. Not breaking: it changes how a list is drawn, not what is stored.

## Observation Split out of #136, which asked the question and said it should be decided rather than assumed: > **The listings page is not a table at all.** `ApplicationsTable` and `CompaniesTable` are > the only two registered; `jobs/listing_list.html` renders its own rows, so none of the > sorting and filtering the suggestion opens by praising is available there. If the tables > are getting richer, the page most like a channel list — many rows, triaged in bulk, mostly > discarded — is the one that has none of it. **The decision made in #136: not there, here.** Making listings a table is a page rewrite rather than a table feature, and folding it into an issue that was already four features would have meant doing it badly to finish something else. ## What exists `jobs/listing_list.html` draws its own rows. `core/tables.py` holds everything a registered table gets for free, and two pages already have it: | | Listings today | A registered table | | --- | --- | --- | | Sort by a column | no | yes, three states since #136 | | Filter per column, as you type | no | yes, server-side | | Choose and order columns | no | yes, saved on the profile | | Column widths | no | yes, saved on the profile | | Select rows, act in bulk | no | yes, since #134 | | Edit a value in the cell | no | yes, since #135 | | Page size | no | yes | ## Why this page in particular A listing is the shortest-lived thing Postulo holds. Most are discarded; the useful gesture is *look at forty, keep three*, and that is exactly the shape bulk actions and per-column filtering were built for. It is the page in this application closest to the channel list that started #136, and the only one of the three that has none of what that comparison produced. ## Worth being careful about **The listings page has its own state that a table does not model.** A listing is captured, reviewed, kept or discarded, and `DiscardReason` records why. That is a workflow rather than a column, and a `choice` filter over it is not obviously the same control as the review screen it has now. **Bulk discard needs a reason.** #134's bulk actions apply one action to many rows; discard takes a reason per listing today. Either the bulk form asks once and applies it to all, or discard is not one of the bulk actions — worth deciding rather than discovering. **Nothing about the capture flow should change.** Capturing, reviewing and converting a listing into an application are separate screens for good reasons, and this is about the list, not about them. **The empty state is most of what somebody sees at first.** A table with a *Columns* control, a filter row and a bulk bar, over no rows at all, is worse than the page there is now. Whatever is built has to look right at zero listings as well as at four hundred. ## Classification Enhancement. Not breaking: it changes how a list is drawn, not what is stored.
tiagoagueda added this to the 0.4.0 milestone 2026-09-10 03:32:46 +00:00
Author
Owner

Landed on main as 19d37134b.

Landed on `main` as 19d37134b.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
Postulo/postulo#160
No description provided.