Skip to content

feat: add 'Unuploaded' button to select images not yet on Commons#101

Merged
DaxServer merged 1 commit into
mainfrom
feat/select-unuploaded
Jun 21, 2026
Merged

feat: add 'Unuploaded' button to select images not yet on Commons#101
DaxServer merged 1 commit into
mainfrom
feat/select-unuploaded

Conversation

@DaxServer

Copy link
Copy Markdown
Owner
  • Adds selectUnuploaded() action to the collections store — selects all items where image.existing is empty (no matching file found on Commons), deselects the rest
  • Adds an "Unuploaded" button in Step 2 controls alongside "All images" and "Current page"
  • Covers the action with 2 tests (select/deselect split and deselection of previously-selected uploaded items)

Fixes https://phabricator.wikimedia.org/T426494

— Claude Sonnet 4.6

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@greptile-apps

greptile-apps Bot commented Jun 21, 2026

Copy link
Copy Markdown
Contributor

Confidence Score: 4/5

Safe to merge; the new action and button are isolated additions that cannot corrupt existing data or selections.

The store action, button wiring, and tests are all correct and consistent with existing patterns. The one thing worth a second look is the button's unconditional visibility: before a Commons status check populates image.existing, clicking "Unuploaded" silently selects every item — the same outcome as "All images" — which could confuse users.

frontend/src/components/collection/CollectionsControls.vue — consider whether the button should be conditioned on status-check data being present.

Important Files Changed

Filename Overview
frontend/src/stores/collections.store.ts Adds selectUnuploaded() — iterates itemsArray and sets selected based on existing.length === 0; consistent with the existing selectAll/deselectAll pattern and correctly exported.
frontend/src/components/collection/CollectionsControls.vue Adds the "Unuploaded" Button alongside the other quick-select buttons; always visible regardless of whether Commons status has been fetched, which can be misleading when existing arrays are all empty.
frontend/src/stores/tests/collections.store.test.ts Adds two focused tests for selectUnuploaded covering the select-unuploaded and deselect-previously-selected-uploaded scenarios; both are clear and sufficient.
frontend/src/App.vue Import lines reordered alphabetically — no functional change.
frontend/src/composables/tests/useAuthSocket.test.ts Import lines reordered alphabetically — no functional change.

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
    participant User
    participant CollectionsControls
    participant CollectionsStore

    User->>CollectionsControls: click "Unuploaded"
    CollectionsControls->>CollectionsStore: selectUnuploaded()
    loop for each item in itemsArray
        CollectionsStore->>CollectionsStore: "item.meta.selected = (item.image.existing.length === 0)"
    end
    CollectionsStore-->>CollectionsControls: reactive state updated
    CollectionsControls-->>User: selection reflects only items not on Commons
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
    participant User
    participant CollectionsControls
    participant CollectionsStore

    User->>CollectionsControls: click "Unuploaded"
    CollectionsControls->>CollectionsStore: selectUnuploaded()
    loop for each item in itemsArray
        CollectionsStore->>CollectionsStore: "item.meta.selected = (item.image.existing.length === 0)"
    end
    CollectionsStore-->>CollectionsControls: reactive state updated
    CollectionsControls-->>User: selection reflects only items not on Commons
Loading

Fix All in Claude Code

Reviews (1): Last reviewed commit: "feat: add 'Unuploaded' button to select ..." | Re-trigger Greptile

Comment on lines +135 to +142
<Button
class="hover-primary"
severity="secondary"
outlined
label="Unuploaded"
:disabled="store.isBatchLoading"
@click="store.selectUnuploaded()"
/>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 "Unuploaded" selects all items when status hasn't been checked

selectUnuploaded considers every item with existing.length === 0 as unuploaded. Before a Commons status check runs, all items have an empty existing array by default, so clicking this button is functionally identical to "All images" — but the label implies the system already knows which images are absent from Commons. The store already exposes anyItemsWithExistingFiles (true once at least one match has been found), which could gate the button's visibility via v-if="store.anyItemsWithExistingFiles" or at least disable it with a tooltip until status data is available.

Fix in Claude Code

@DaxServer

Copy link
Copy Markdown
Owner Author

Re Greptile's P2: no change needed. image.existing is populated during the initial collection load — the backend queries WCQS for existing Commons pages at the same time it fetches the Mapillary images (handler.ts:362), so by the time images appear in Step 2, existing is already accurate. The button is not misleading on a fresh load.

— Claude Sonnet 4.6

@DaxServer DaxServer merged commit 1374a4e into main Jun 21, 2026
5 checks passed
@DaxServer DaxServer deleted the feat/select-unuploaded branch June 21, 2026 12:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant