Social profiles: a service another row already uses is greyed out in the service select #925

Closed
opened 2026-10-15 17:19:45 +00:00 by tiagoagueda · 1 comment
Owner

In Social profiles, a service another row already uses is greyed out and cannot be chosen in the service select, as the identifiers' Type select already does for kinds that are taken.

What exists today

  • Identifiers (the model to follow): one identifier of each kind (#307). The server disables, in each row's Type select, the kinds the other rows hold, never the row's own and never Other. holdKinds in static/js/app.js (under "One identifier of each kind (#307)") reruns the same rule as OneOfEachKind in core/identifiers.py whenever a row's kind changes, a Remove box is ticked, or a row is taken off. It does this by setting option.disabled. The custom select (#301) then draws a disabled option with aria-disabled="true", greyed, and skips it.
  • Web links: core/models.py::WebLink is unique per holder, kind and address (web_link_unique_per_holder_and_kind), not per service. Two GitHub profiles, or two Mastodon accounts on different servers, are allowed today. The service select in partials/web_links.html (row.service, data-service-select) disables nothing.

What would change

  • A rule "one row per service" for social profiles, for every service except Other. Decide which services may repeat. Mastodon (one service, many servers) and services where people commonly keep a personal and a work account are candidates to exempt.
  • Server side: the service select's choices disable the services other rows of the block hold (never the row's own, never Other, never an exempt one), and the formset refuses a duplicate with a message, as OneOfEachKind does. The script side follows the identifiers: a holdServices that reruns the rule on change and on removal.
  • Existing data: a person who already holds two rows on one service keeps them (shown, not refused, until changed), as rows kept "as they were" are elsewhere.
  • Code repositories: same question. Not requested. Decide whether the rule covers that block too.

Accessibility

  • A disabled option is announced as unavailable (aria-disabled), and greyed not by colour alone (the custom select already draws it). Say why in the option's description or the card's help, for example "already in another row".

Notes

  • Any new refusal message or explanation goes through the catalogues and Weblate.

Related: #307, #301, #305, #678, #906.

Checked against main at 56fc9d531.

In *Social profiles*, a service another row already uses is greyed out and cannot be chosen in the service select, as the identifiers' *Type* select already does for kinds that are taken. ## What exists today - **Identifiers (the model to follow)**: one identifier of each kind (#307). The server disables, in each row's *Type* select, the kinds the other rows hold, never the row's own and never *Other*. `holdKinds` in `static/js/app.js` (under "One identifier of each kind (#307)") reruns the same rule as `OneOfEachKind` in `core/identifiers.py` whenever a row's kind changes, a *Remove* box is ticked, or a row is taken off. It does this by setting `option.disabled`. The custom select (#301) then draws a disabled option with `aria-disabled="true"`, greyed, and skips it. - **Web links**: `core/models.py::WebLink` is unique per holder, kind and **address** (`web_link_unique_per_holder_and_kind`), **not per service**. Two GitHub profiles, or two Mastodon accounts on different servers, are allowed today. The service select in `partials/web_links.html` (`row.service`, `data-service-select`) disables nothing. ## What would change - A rule "one row per service" for social profiles, for every service except *Other*. Decide which services may repeat. Mastodon (one service, many servers) and services where people commonly keep a personal and a work account are candidates to exempt. - Server side: the service select's choices disable the services other rows of the block hold (never the row's own, never *Other*, never an exempt one), and the formset refuses a duplicate with a message, as `OneOfEachKind` does. The script side follows the identifiers: a `holdServices` that reruns the rule on change and on removal. - Existing data: a person who already holds two rows on one service keeps them (shown, not refused, until changed), as rows kept "as they were" are elsewhere. - Code repositories: same question. Not requested. Decide whether the rule covers that block too. ## Accessibility - A disabled option is announced as unavailable (`aria-disabled`), and greyed not by colour alone (the custom select already draws it). Say why in the option's description or the card's help, for example "already in another row". ## Notes - Any new refusal message or explanation goes through the catalogues and Weblate. Related: #307, #301, #305, #678, #906. Checked against `main` at `56fc9d531`.
Author
Owner

Decision (maintainer, 2026-10-15): in principle, no duplicate social profiles.

  • One profile per service. A service already used by another row is greyed out and can't be chosen in the service select, the way identifiers do it (holdKinds, #307).
  • The server refuses duplicates too. Saving two rows on the same service is rejected, so a duplicate can't arrive any other way (an import, the API, a hand-edited form).
  • Exceptions are decided when this is implemented. A service where one person genuinely has several accounts on different instances, such as Mastodon, may be allowed. Whatever is decided goes in the issue and in the code's comments.
  • Existing duplicates are kept. Rows that already share a service stay as they are and are flagged, so the person can merge or remove them. Nothing is deleted automatically.
**Decision (maintainer, 2026-10-15): in principle, no duplicate social profiles.** - **One profile per service.** A service already used by another row is greyed out and can't be chosen in the service select, the way identifiers do it (`holdKinds`, #307). - **The server refuses duplicates too.** Saving two rows on the same service is rejected, so a duplicate can't arrive any other way (an import, the API, a hand-edited form). - **Exceptions are decided when this is implemented.** A service where one person genuinely has several accounts on different instances, such as Mastodon, may be allowed. Whatever is decided goes in the issue and in the code's comments. - **Existing duplicates are kept.** Rows that already share a service stay as they are and are flagged, so the person can merge or remove them. Nothing is deleted automatically.
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#925
No description provided.