Choose which identifiers are shown and in what order, under Settings → Appearance #672

Closed
opened 2026-10-03 01:58:51 +00:00 by tiagoagueda · 1 comment
Owner

From the list: “Ability to change appearance and order of Identifier from user settings.” Identifiers are drawn in one fixed order for everybody, and the only part of them a person can arrange today is the companies table's columns.

What exists today

  • The order is the database's. CompanyIdentifier.Meta.ordering = ("scheme", "value") (src/postulo/jobs/models.py:505) and the same on PersonIdentifier (src/postulo/accounts/models.py:188), so a company's identifiers on its page come out alphabetically by scheme key, and one the person cares about most is wherever the alphabet puts it. The company page draws company.identifiers.all as a definition list (src/postulo/templates/jobs/company_detail.html:73-83); Your details draws the person's rows as a form (src/postulo/templates/accounts/profile.html:186-215).
  • What is per person today is only the table. The companies table has one optional column per scheme, hidden until asked for (src/postulo/jobs/tables.py:120-133), and which columns show, in what order, is kept on the profile in Profile.table_settings (accounts/models.py:388-390, src/postulo/core/tables.py).
  • The pattern for “show these, in my order” exists and is recent. The main navigation keeps two lists on the profile, hidden_nav_items and nav_order (accounts/models.py:309-320), and stores what was decided, never what was offered: an item added by a later release is in neither list and is drawn after the placed ones (src/postulo/core/navigation.py:19-30, complete() at :153, to_store() at :201). Settings → Appearance edits them with a switch and two arrow buttons per item, all submit buttons of one form, so it works with scripts off (AppearanceForm, src/postulo/accounts/forms.py:761-909). Both lists travel in the archive (PROFILE_FIELDS, src/postulo/core/export.py:111-137). tests/test_navigation.py is the test model: default order, placed keys first, new item after the placed ones, forged input passed over, round trip through the archive.
  • The registry can grow between releases. Identifier schemes come from plugins and are merged in registration order (src/postulo/core/identifiers.py, registry()); an instance can have schemes this person has never seen, which is the same situation as a navigation item added later.
  • What a CV prints is already a choice, per CV, by row (#308; src/postulo/documents/forms.py:205-235). That is which rows print, not in what order the person keeps them.

Checked against main at f09b6010b.

Proposal

  1. Two lists on Profile, mirroring the navigation pair: the scheme keys the person has placed, in order, and the ones they have switched off. Empty means the default, which is today's behaviour, so nothing is migrated. Both are read through one helper that drops keys the registry does not know and appends unplaced schemes after the placed ones.
  2. An Identifiers section in Settings → Appearance: every scheme the registry knows for a person or a company, each with a switch and up/down arrow buttons, and Back to the usual order, built on the same form mechanics as the navigation list. A refused page comes back in the order it was posted in, as the navigation list does.
  3. Apply the order and the switches where identifiers are displayed: the company page's list, the Your details list, the default columns of the companies table (a person who has not arranged the columns), and the order of the rows offered to a CV's print choice. Rows of scheme Other keep the order they have today (by value) inside their place.
  4. What “switched off” means. A switched-off scheme is not drawn in the company page's summary and is not a default table column. It is never deleted, never dropped from the edit forms (a hidden value must stay reachable and removable), never left out of the export, the API or a CV the person chose to print it on.
  5. The archive carries both lists and the importer reads them through the same filter as the navigation, so an archive naming a scheme this instance does not have is passed over.

Decisions

  • What “appearance” covers. The list says “appearance and order”. Options: show or hide only; also how each is written (the scheme's label, its short code, a brand icon); also grouping (people's and organisations' together or apart). Recommended: show or hide and order in this issue, because writing an identifier as an icon needs brand marks Postulo does not have (#654), and the label-versus-icon choice belongs to that issue once it exists. Grouping is not asked for.
  • One setting or two. One order for people and companies (a scheme such as ISNI or Wikidata identifies both, core/identifiers.py), filtered to the subject being drawn; or one per subject. Recommended: one. It is the shorter page and the schemes that are only one subject simply do not appear on the other.
  • Per person only, or an instance default as well. The list says “from user settings”. Recommended: per person only. An instance default would be a second place with the same list; add it only if an operator asks.
  • Two columns or one JSON field. The navigation uses two. Recommended: two, so the code and the tests copy a design that already works.
  • Hide on a company's page or only in tables. Hiding a value the person typed in is surprising; the navigation precedent is justified by “everything is reachable another way”. Recommended: hidden schemes stay in the edit form and in the table's column chooser, and the company page says “n hidden” with a link to the form so nothing disappears without a trace.

Builds on

Issues #307 (a kind already held cannot be chosen again), #308 (what a CV prints), #311 (the registry's schemes defined in JSON; open), #299 (the navigation order that this copies), #109 (one registry, a subject matrix).

Needed by

#654 (the icon or label choice, later). #675 reads the same order when it lists warnings.

Done when

  • A new test file for identifier arrangement, modelled on tests/test_navigation.py: the default order is today's; placed keys come first; a scheme added later is drawn after them; a stored list is believed only as far as the registry goes; a forged move is passed over; the order is applied on the company page, in Your details and in the CV's row choice; a hidden scheme is not drawn on the company page and is still in the edit form and the export.
  • tests/test_export.py or tests/test_navigation.py::test_the_arrangement_travels_with_the_account is extended so both lists round-trip, and the format bump is in place: the archive format goes up by one (src/postulo/core/export.py FORMAT_VERSION: one more than whatever FORMAT_VERSION is when the commit lands (29 at f09b6010b); the format tests follow it, tests/test_export.py:96). The candidate format (4 at f09b6010b) does not change: this is how Postulo behaves for one account, not part of the CV (CANDIDATE_PROFILE_FIELDS).
  • The processing record (src/postulo/core/gdpr.py) is about contacts' data and does not change: these are a person's own display preferences. The Appearance page stays in tests/test_page_coverage.py and the browser suite with axe, both themes.
  • New strings are in the working catalogues (en-GB, fr-FR, pt-PT as drafts) and in Weblate (#349); the wiki's Your career record or Settings page is updated.

From the list of improvements of 2026-10-02.

From the list: “Ability to change appearance and order of Identifier from user settings.” Identifiers are drawn in one fixed order for everybody, and the only part of them a person can arrange today is the companies table's columns. ## What exists today - **The order is the database's.** `CompanyIdentifier.Meta.ordering = ("scheme", "value")` (`src/postulo/jobs/models.py:505`) and the same on `PersonIdentifier` (`src/postulo/accounts/models.py:188`), so a company's identifiers on its page come out alphabetically by scheme key, and one the person cares about most is wherever the alphabet puts it. The company page draws `company.identifiers.all` as a definition list (`src/postulo/templates/jobs/company_detail.html:73-83`); *Your details* draws the person's rows as a form (`src/postulo/templates/accounts/profile.html:186-215`). - **What is per person today is only the table.** The companies table has one optional column per scheme, hidden until asked for (`src/postulo/jobs/tables.py:120-133`), and which columns show, in what order, is kept on the profile in `Profile.table_settings` (`accounts/models.py:388-390`, `src/postulo/core/tables.py`). - **The pattern for “show these, in my order” exists and is recent.** The main navigation keeps two lists on the profile, `hidden_nav_items` and `nav_order` (`accounts/models.py:309-320`), and stores *what was decided, never what was offered*: an item added by a later release is in neither list and is drawn after the placed ones (`src/postulo/core/navigation.py:19-30`, `complete()` at `:153`, `to_store()` at `:201`). Settings → Appearance edits them with a switch and two arrow buttons per item, all submit buttons of one form, so it works with scripts off (`AppearanceForm`, `src/postulo/accounts/forms.py:761-909`). Both lists travel in the archive (`PROFILE_FIELDS`, `src/postulo/core/export.py:111-137`). `tests/test_navigation.py` is the test model: default order, placed keys first, new item after the placed ones, forged input passed over, round trip through the archive. - **The registry can grow between releases.** Identifier schemes come from plugins and are merged in registration order (`src/postulo/core/identifiers.py`, `registry()`); an instance can have schemes this person has never seen, which is the same situation as a navigation item added later. - **What a CV prints is already a choice**, per CV, by row (#308; `src/postulo/documents/forms.py:205-235`). That is which rows print, not in what order the person keeps them. Checked against `main` at `f09b6010b`. ## Proposal 1. **Two lists on `Profile`, mirroring the navigation pair**: the scheme keys the person has placed, in order, and the ones they have switched off. Empty means the default, which is today's behaviour, so nothing is migrated. Both are read through one helper that drops keys the registry does not know and appends unplaced schemes after the placed ones. 2. **An *Identifiers* section in Settings → Appearance**: every scheme the registry knows for a person or a company, each with a switch and up/down arrow buttons, and *Back to the usual order*, built on the same form mechanics as the navigation list. A refused page comes back in the order it was posted in, as the navigation list does. 3. **Apply the order and the switches where identifiers are *displayed***: the company page's list, the *Your details* list, the default columns of the companies table (a person who has not arranged the columns), and the order of the rows offered to a CV's print choice. Rows of scheme *Other* keep the order they have today (by value) inside their place. 4. **What “switched off” means.** A switched-off scheme is not drawn in the company page's summary and is not a default table column. It is never deleted, never dropped from the edit forms (a hidden value must stay reachable and removable), never left out of the export, the API or a CV the person chose to print it on. 5. **The archive carries both lists** and the importer reads them through the same filter as the navigation, so an archive naming a scheme this instance does not have is passed over. ## Decisions - **What “appearance” covers.** The list says “appearance and order”. Options: show or hide only; also how each is written (the scheme's label, its short code, a brand icon); also grouping (people's and organisations' together or apart). **Recommended: show or hide and order in this issue**, because writing an identifier as an icon needs brand marks Postulo does not have (#654), and the label-versus-icon choice belongs to that issue once it exists. Grouping is not asked for. - **One setting or two.** One order for people and companies (a scheme such as ISNI or Wikidata identifies both, `core/identifiers.py`), filtered to the subject being drawn; or one per subject. **Recommended: one.** It is the shorter page and the schemes that are only one subject simply do not appear on the other. - **Per person only, or an instance default as well.** The list says “from user settings”. **Recommended: per person only.** An instance default would be a second place with the same list; add it only if an operator asks. - **Two columns or one JSON field.** The navigation uses two. **Recommended: two**, so the code and the tests copy a design that already works. - **Hide on a company's page or only in tables.** Hiding a value the person typed in is surprising; the navigation precedent is justified by “everything is reachable another way”. **Recommended: hidden schemes stay in the edit form and in the table's column chooser, and the company page says “n hidden” with a link to the form** so nothing disappears without a trace. ## Builds on Issues #307 (a kind already held cannot be chosen again), #308 (what a CV prints), #311 (the registry's schemes defined in JSON; open), #299 (the navigation order that this copies), #109 (one registry, a subject matrix). ## Needed by #654 (the icon or label choice, later). #675 reads the same order when it lists warnings. ## Done when - A new test file for identifier arrangement, modelled on `tests/test_navigation.py`: the default order is today's; placed keys come first; a scheme added later is drawn after them; a stored list is believed only as far as the registry goes; a forged move is passed over; the order is applied on the company page, in *Your details* and in the CV's row choice; a hidden scheme is not drawn on the company page and is still in the edit form and the export. - `tests/test_export.py` or `tests/test_navigation.py::test_the_arrangement_travels_with_the_account` is extended so both lists round-trip, and the format bump is in place: **the archive format goes up by one** (`src/postulo/core/export.py` `FORMAT_VERSION`: one more than whatever `FORMAT_VERSION` is when the commit lands (29 at `f09b6010b`); the format tests follow it, `tests/test_export.py:96`). The candidate format (4 at `f09b6010b`) does not change: this is how Postulo behaves for one account, not part of the CV (`CANDIDATE_PROFILE_FIELDS`). - The processing record (`src/postulo/core/gdpr.py`) is about contacts' data and does not change: these are a person's own display preferences. The Appearance page stays in `tests/test_page_coverage.py` and the browser suite with axe, both themes. - New strings are in the working catalogues (en-GB, fr-FR, pt-PT as drafts) and in Weblate (#349); the wiki's *Your career record* or Settings page is updated. From the list of improvements of 2026-10-02.
tiagoagueda added this to the 0.6.0 milestone 2026-10-03 01:58:51 +00:00
Author
Owner

Done in 343666d06, f01ce2bab and 99fca82a0 (on main; CI green at 15e6d7ee4). Show/hide and order only, one setting for people and companies, per person; hidden identifiers stay in the edit forms, export, API and CVs. Wiki: Your career record.

Done in 343666d06, f01ce2bab and 99fca82a0 (on main; CI green at 15e6d7ee4). Show/hide and order only, one setting for people and companies, per person; hidden identifiers stay in the edit forms, export, API and CVs. Wiki: Your career record.
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#672
No description provided.