PluginProbe
Code Snippets / 3.10.0-beta.1
Code Snippets v3.10.0-beta.1
4.0.0-beta.2 3.10.2 3.10.1 3.10.0 3.10.0-beta.2 3.10.0-beta.1 4.0.0-beta.1 3.9.6 trunk 2.10.0 2.10.1 2.12.0 2.12.1 2.13.0 2.13.1 2.13.2 2.13.3 2.14.0 2.14.1 2.14.2 2.14.3 2.14.4 2.14.5 2.14.6 3.0.0 All 65 releases
code-snippets / js / components / ManageMenu / SnippetsTable / SnippetsTableControls.tsx

SnippetsTableControls.tsx in Code Snippets 3.10.0-beta.1, at js/components/ManageMenu/SnippetsTable/SnippetsTableControls.tsx

137 lines 4.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 import { __, sprintf } from '@wordpress/i18n'
2 import React, { Fragment, useMemo } from 'react'
3 import { useRestAPI } from '../../../hooks/useRestAPI'
4 import { useSnippetsList } from '../../../hooks/useSnippetsList'
5 import { handleUnknownError } from '../../../utils/errors'
6 import { REST_BASES } from '../../../utils/restAPI'
7 import { buildUrl } from '../../../utils/urls'
8 import { SubmitButton } from '../../common/SubmitButton'
9 import { SearchArea } from './SnippetsTableSearch'
10 import { useFilteredSnippets } from './WithFilteredSnippetsContext'
11 import { INDEX_STATUS, useSnippetsFilters } from './WithSnippetsTableFilters'
12 import type { Snippet } from '../../../types/Snippet'
13 import type { SnippetStatus } from './WithSnippetsTableFilters'
14
15 const STATUS_LABELS: [SnippetStatus, string][] = [
16 ['all', __('All', 'code-snippets')],
17 ['active', __('Active', 'code-snippets')],
18 ['inactive', __('Inactive', 'code-snippets')],
19 ['recently_active', __('Recently Active', 'code-snippets')],
20 ['locked', __('Locked', 'code-snippets')],
21 ['unlocked', __('Unlocked', 'code-snippets')],
22 ['trashed', __('Trashed', 'code-snippets')]
23 ]
24
25 const SnippetStatusCounts = () => {
26 const { currentStatus, setCurrentStatus } = useSnippetsFilters()
27 const { snippetsByStatus } = useFilteredSnippets()
28
29 const visibleStatuses = STATUS_LABELS.filter(([status]) =>
30 snippetsByStatus.has(status) && ('unlocked' !== status || snippetsByStatus.has('locked')))
31
32 return (
33 <ul className="subsubsub">
34 {visibleStatuses.map(([status, label]) =>
35 <Fragment key={status}>
36 <li className={status}>
37 <a
38 href={buildUrl(window.location.href, {
39 status: INDEX_STATUS === status ? undefined : status
40 })}
41 className={currentStatus === status ? 'current' : undefined}
42 aria-current={currentStatus === status ? 'page' : undefined}
43 onClick={event => {
44 event.preventDefault()
45 setCurrentStatus(status)
46 }}
47 >
48 {`${label} `}
49 <span className="count">{
50 sprintf(
51 // translators: %d: number of snippets in the current view.
52 __('(%d)', 'code-snippets'),
53 snippetsByStatus.get(status)?.length ?? 0
54 )
55 }</span>
56 </a>
57 </li>
58 </Fragment>)}
59 </ul>
60 )
61 }
62
63 const ClearRecentlyActiveButton: React.FC = () => {
64 const { api } = useRestAPI()
65 const { refreshSnippetsList } = useSnippetsList()
66 const { currentStatus } = useSnippetsFilters()
67
68 return 'recently_active' === currentStatus
69 ? <div className="alignleft actions">
70 <SubmitButton
71 secondary
72 name="clear-recent-list"
73 text={__('Clear List', 'code-snippets')}
74 onClick={event => {
75 event.preventDefault()
76 api.del(REST_BASES.recentlyActive)
77 .then(refreshSnippetsList)
78 .catch(handleUnknownError)
79 }}
80 />
81 </div>
82 : null
83 }
84
85 interface FilterByTagControlProps {
86 visibleSnippets: Snippet[]
87 }
88
89 const FilterByTagControl: React.FC<FilterByTagControlProps> = ({ visibleSnippets }) => {
90 const { currentTag, setCurrentTag } = useSnippetsFilters()
91
92 const tagsList: Set<string> = useMemo(
93 () => visibleSnippets.reduce((tags, snippet) => {
94 snippet.tags.forEach(tag => tags.add(tag))
95 return tags
96 }, new Set<string>()),
97 [visibleSnippets])
98
99 return 0 < tagsList.size
100 ? <div className="alignleft actions">
101 <label htmlFor="snippets-tag-filter" className="screen-reader-text">
102 {__('Filter snippets by tag', 'code-snippets')}
103 </label>
104 <select
105 id="snippets-tag-filter"
106 name="tag"
107 value={currentTag}
108 onChange={event => setCurrentTag(event.target.value)}
109 >
110 <option value="">{__('All Tags', 'code-snippets')}</option>
111 {[...tagsList].map(tag =>
112 <option key={tag} value={tag}>{tag}</option>)}
113 </select>
114 </div>
115 : null
116 }
117
118 export interface SnippetsTableNavigationProps {
119 which: 'top' | 'bottom'
120 visibleSnippets: Snippet[]
121 }
122
123 export const SnippetsTableNavigation: React.FC<SnippetsTableNavigationProps> = ({
124 which,
125 visibleSnippets
126 }) =>
127 <>
128 {'top' === which && <FilterByTagControl visibleSnippets={visibleSnippets} />}
129 <ClearRecentlyActiveButton />
130 {'top' === which && <SearchArea />}
131 </>
132
133 export const SnippetsTableToolbar = () =>
134 <div className="snippets-table-toolbar">
135 <SnippetStatusCounts />
136 </div>
137