-
Notifications
You must be signed in to change notification settings - Fork 110
fix: keep the cloud table's select-all honest when nothing can be downloaded #532
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -64,46 +64,77 @@ interface TableHeadingCheckboxProps { | |
| setSelectedIds: Dispatch<SetStateAction<Set<CloudSnippetSchema['id']>>> | ||
| } | ||
|
|
||
| /** | ||
| * Selects every snippet on the page that can be downloaded. With nothing | ||
| * downloadable the box is disabled and unticked: "all of nothing" must not | ||
| * read as a selection. | ||
| */ | ||
| const TableHeadingCheckbox: React.FC<TableHeadingCheckboxProps> = ({ availableIds, selectedIds, setSelectedIds }) => | ||
| <td className="column-cb check-column"> | ||
| <input | ||
| id="cb-select-all-cloud-snippets" | ||
| type="checkbox" | ||
| checked={availableIds.every(snippetId => selectedIds.has(snippetId))} | ||
| checked={0 < availableIds.length && availableIds.every(snippetId => selectedIds.has(snippetId))} | ||
| disabled={0 === availableIds.length} | ||
| title={0 === availableIds.length ? __('Nothing on this page can be downloaded.', 'code-snippets') : undefined} | ||
| onChange={event => | ||
| setSelectedIds(previous => | ||
| new Set(event.target.checked | ||
| ? [...previous, ...availableIds] | ||
| : [...previous].filter(snippetId => !availableIds.includes(snippetId))) | ||
| )} | ||
| aria-label={__('Select all snippets', 'code-snippets')} | ||
| aria-label={__('Select all downloadable snippets', 'code-snippets')} | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win Include the disabled reason in Line 86 gives the header checkbox a fixed accessible name. The As per path instructions, disabled controls must accurately communicate why selection is unavailable. 🤖 Prompt for AI AgentsSource: Path instructions |
||
| /> | ||
| </td> | ||
|
|
||
| /** Why a snippet cannot be selected for download, or undefined when it can. */ | ||
| const unavailableReason = (snippet: CloudSnippetSchema): string | undefined => { | ||
| if (snippet.local_id) { | ||
| return __('Already in your library.', 'code-snippets') | ||
| } | ||
|
|
||
| return isCloudSnippetDownloadable(snippet) | ||
| ? undefined | ||
| : __('Requires Code Snippets Pro.', 'code-snippets') | ||
| } | ||
|
|
||
| interface TableRowCheckboxProps { | ||
| snippet: CloudSnippetSchema | ||
| selected: Set<CloudSnippetSchema['id']> | ||
| setSelected: Dispatch<SetStateAction<Set<CloudSnippetSchema['id']>>> | ||
| } | ||
|
|
||
| const TableRowCheckbox: React.FC<TableRowCheckboxProps> = ({ snippet, selected, setSelected }) => | ||
| <th scope="row" className="check-column"> | ||
| {isCloudSnippetDownloadable(snippet) && ( | ||
| /** | ||
| * Every row shows a box, so the column reads as one control: a snippet that | ||
| * cannot be downloaded gets a disabled box that says why. | ||
| */ | ||
| const TableRowCheckbox: React.FC<TableRowCheckboxProps> = ({ snippet, selected, setSelected }) => { | ||
| const reason = unavailableReason(snippet) | ||
|
|
||
| return ( | ||
| <th scope="row" className="check-column"> | ||
| <input | ||
| id={`cb-select-${snippet.id}`} | ||
| type="checkbox" | ||
| name="checked[]" | ||
| checked={selected.has(snippet.id)} | ||
| // translators: %s: snippet name. | ||
| aria-label={sprintf(__('Select %s', 'code-snippets'), snippet.name)} | ||
| checked={!reason && selected.has(snippet.id)} | ||
| disabled={!!reason} | ||
|
Comment on lines
+120
to
+121
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win 🔎 Supported by static analysis🏁 Script executed: #!/bin/bash
set -euo pipefail
rg -n -C 8 '\bCloudSnippetsTable\b|\bsetSelected\b|\bselected\b' src/jsRepository: codesnippetspro/code-snippets Length of output: 50385 🏁 Script executed: #!/bin/bash
set -euo pipefail
printf '%s\n' '--- CloudSearch selection and download flow ---'
sed -n '150,210p' src/js/components/ManageMenu/CommunityCloud/CloudSearch.tsx
printf '%s\n' '--- CloudSnippetsTable ---'
sed -n '1,190p' src/js/components/ManageMenu/CommunityCloud/CloudSnippetsTable.tsx
printf '%s\n' '--- download consumers ---'
rg -n -C 6 'doAction|selectedIds|REST_BASES|download' src/js/components/ManageMenu/CommunityCloud/CloudSearch.tsxRepository: codesnippetspro/code-snippets Length of output: 10895 🤖 get_repo_knowledge executed:
Length of output: 2658 🏁 Script executed: #!/bin/bash
set -euo pipefail
sed -n '150,210p' src/js/components/ManageMenu/CommunityCloud/CloudSearch.tsx
sed -n '1,190p' src/js/components/ManageMenu/CommunityCloud/CloudSnippetsTable.tsx
rg -n -C 6 'doAction|selectedIds|REST_BASES|download' src/js/components/ManageMenu/CommunityCloud/CloudSearch.tsxRepository: codesnippetspro/code-snippets Length of output: 10793 🏁 Script executed: printf '%s\n' '--- CloudSearch ---'
nl -ba src/js/components/ManageMenu/CommunityCloud/CloudSearch.tsx | sed -n '157,180p'
printf '%s\n' '--- CloudSnippetsTable ---'
nl -ba src/js/components/ManageMenu/CommunityCloud/CloudSnippetsTable.tsx | sed -n '65,170p'Repository: codesnippetspro/code-snippets Length of output: 286 🏁 Script executed: #!/bin/bash
set -euo pipefail
printf '%s\n' '--- downloadability contract ---'
rg -n -C 8 'isCloudSnippetDownloadable' src/js/utils src/js/components/ManageMenu/CommunityCloud src/php
printf '%s\n' '--- cloud snippet schema and local_id handling ---'
rg -n -C 8 'local_id|CloudSnippetSchema|/download' src/js/types src/js src/php | head -n 240Repository: codesnippetspro/code-snippets Length of output: 31003 🏁 Script executed: #!/bin/bash
set -euo pipefail
rg -n -C 12 'isCloudSnippetDownloadable' src/js/utils src/js/components/ManageMenu/CommunityCloud
rg -n -C 8 'local_id' src/js/types src/js/components/ManageMenu/CommunityCloudRepository: codesnippetspro/code-snippets Length of output: 19829 🏁 Script executed: #!/bin/bash
set -euo pipefail
rg -n -C 10 'interface .*TableNav|const TableNav|doAction|selected\.size|selected\.has' src/js/components/common/ListTable/TableNavigation.tsx src/js/components/ManageMenu/CommunityCloud/CloudSearch.tsxRepository: codesnippetspro/code-snippets Length of output: 20510 🏁 Script executed: #!/bin/bash
set -euo pipefail
sed -n '97,141p' src/js/components/common/ListTable/TableNavigation.tsxRepository: codesnippetspro/code-snippets Length of output: 1356 Remove unavailable IDs from At 🤖 Prompt for AI Agents |
||
| title={reason} | ||
| aria-label={reason | ||
| // translators: 1: snippet name, 2: why it cannot be selected. | ||
| ? sprintf(__('%1$s cannot be selected: %2$s', 'code-snippets'), snippet.name, reason) | ||
| // translators: %s: snippet name. | ||
| : sprintf(__('Select %s', 'code-snippets'), snippet.name)} | ||
| onChange={event => | ||
| setSelected(previous => | ||
| new Set(event.target.checked | ||
| ? [...previous, snippet.id] | ||
| : [...previous].filter(snippetId => snippetId !== snippet.id)) | ||
| )} | ||
| />)} | ||
| </th> | ||
| /> | ||
| </th> | ||
| ) | ||
| } | ||
|
|
||
| export interface CloudSnippetsTableProps { | ||
| snippets: CloudSnippetSchema[] | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Add tests for each availability state.
Cover no downloadable snippets, partial selection, and complete selection. Cover rows that are already in the library or require Code Snippets Pro. Cover a selected row that becomes unavailable.
As per coding guidelines and path instructions, include unit tests for logic changes and cover edge cases and error paths.
Also applies to: 91-99, 120-133
🤖 Prompt for AI Agents
Sources: Coding guidelines, Path instructions