import { __, sprintf } from '@wordpress/i18n' import React, { useState } from 'react' import { getSnippetType, isCloudSnippetDownloadable } from '../../../utils/snippets/snippets' import { stripTags, truncateChars } from '../../../utils/text' import { Badge } from '../../common/Badge' import { Button } from '../../common/Button' import { CloudSnippetDownloadButton } from '../../common/cloud/CloudSnippetDownloadButton' import { CloudStatusBadge } from '../../common/cloud/CloudStatusBadge' import { CloudSnippetPreviewModal } from '../../common/snippets/SnippetPreviewModal' import { useCloudSearch } from './WithCloudSearchContext' import type { CloudSnippetSchema } from '../../../types/schema/CloudSnippetSchema' import type { Dispatch, SetStateAction } from 'react' interface CloudSnippetRowProps { snippet: CloudSnippetSchema } const CloudSnippetRow: React.FC = ({ snippet }) => { const { doSearch } = useCloudSearch() const [isPreviewOpen, setIsPreviewOpen] = useState(false) return ( <>
{truncateChars(stripTags(snippet.description))}
{isPreviewOpen && ( )} ) } interface TableHeadingCheckboxProps { availableIds: CloudSnippetSchema['id'][] selectedIds: Set setSelectedIds: Dispatch>> } /** * 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 = ({ availableIds, selectedIds, setSelectedIds }) => 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 downloadable snippets', 'code-snippets')} /> /** 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 setSelected: Dispatch>> } /** * 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 = ({ snippet, selected, setSelected }) => { const reason = unavailableReason(snippet) return ( setSelected(previous => new Set(event.target.checked ? [...previous, snippet.id] : [...previous].filter(snippetId => snippetId !== snippet.id)) )} /> ) } export interface CloudSnippetsTableProps { snippets: CloudSnippetSchema[] selected?: Set setSelected?: Dispatch>> } /** * Table view for lists of cloud snippets (community search results and * bundle contents), mirroring the card actions. Descriptions are clamped * so all rows stay the same height. Selection is only offered when the * containing view provides selection state, as bundle contents have no * bulk actions. */ export const CloudSnippetsTable: React.FC = ({ snippets, selected, setSelected }) => {selected && setSelected && ( isCloudSnippetDownloadable(snippet)) .map(snippet => snippet.id)} />)} {snippets.map(snippet => {selected && setSelected && } )}
{__('Name', 'code-snippets')} {__('Type', 'code-snippets')} {__('Status', 'code-snippets')} {__('Description', 'code-snippets')} {__('Actions', 'code-snippets')}