PluginProbe
Code Snippets / 3.10.0
Code Snippets v3.10.0
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 / SnippetsListTable.tsx

SnippetsListTable.tsx in Code Snippets 3.10.0, at js/components/ManageMenu/SnippetsTable/SnippetsListTable.tsx

205 lines 6.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 import { __ } from '@wordpress/i18n'
2 import React, { useEffect, useMemo, useState } from 'react'
3 import classnames from 'classnames'
4 import { getSnippetType, isSnippetActive } from '../../../utils/snippets/snippets'
5 import { buildUrl } from '../../../utils/urls'
6 import { ListTable } from '../../common/ListTable'
7 import { SnippetViewToggle } from '../../common/SnippetViewToggle'
8 import { SnippetsCardGrid } from './SnippetsCardGrid'
9 import { SnippetsTableNavigation, SnippetsTableToolbar } from './SnippetsTableControls'
10 import { SearchResultsIndicator } from './SnippetsTableSearch'
11 import { getTableColumns } from './TableColumns'
12 import { useFilteredSnippets } from './WithFilteredSnippetsContext'
13 import { INDEX_STATUS, useSnippetsFilters } from './WithSnippetsTableFilters'
14 import { BULK_ACTIONS, TRASHED_BULK_ACTIONS, useApplyBulkAction } from './useApplyBulkAction'
15 import type { ListTableAction } from '../../common/ListTable'
16 import type { SnippetsTableAction } from './useApplyBulkAction'
17 import type { Snippet } from '../../../types/Snippet'
18 import type { SnippetView } from '../../../types/SnippetView'
19 import type { ReactNode } from 'react'
20
21 interface ManageTableSettings {
22 hiddenColumns: Set<string>
23 truncateRowValues: boolean
24 }
25
26 const useManageTableSettings = (): ManageTableSettings => {
27 const [hiddenColumns, setHiddenColumns] = useState(
28 () => new Set(window.CODE_SNIPPETS_MANAGE?.hiddenColumns ?? [])
29 )
30 const [truncateRowValues, setTruncateRowValues] = useState(
31 () => 0 !== Number(window.CODE_SNIPPETS_MANAGE?.truncateRowValues ?? 1)
32 )
33
34 useEffect(() => {
35 const screenOptions = document.getElementById('adv-settings')
36
37 if (!screenOptions) {
38 return
39 }
40
41 const updateHiddenColumns = () => {
42 setHiddenColumns(
43 new Set(Array.from(screenOptions.querySelectorAll<HTMLInputElement>(
44 '.hide-column-tog:not(:checked)'
45 ))
46 .map(toggle => toggle.value))
47 )
48
49 setTruncateRowValues(
50 screenOptions.querySelector<HTMLInputElement>(
51 '#snippets-table-truncate-row-values'
52 )?.checked ?? true
53 )
54 }
55
56 updateHiddenColumns()
57 screenOptions.addEventListener('change', updateHiddenColumns)
58
59 return () => {
60 screenOptions.removeEventListener('change', updateHiddenColumns)
61 }
62 }, [])
63
64 return { hiddenColumns, truncateRowValues }
65 }
66
67 const NoItemsMessage = () => {
68 const { currentType, currentTag, searchQuery } = useSnippetsFilters()
69 const emptyMessage = currentType
70 ? __("You don't have snippets of this type yet.", 'code-snippets')
71 : __("You don't have any snippets yet.", 'code-snippets')
72
73 return searchQuery || currentTag
74 ? <>
75 {__('No snippets were found matching the current search query.', 'code-snippets')}
76 {__(' Please enter a new query or use the "Clear Filters" button above.', 'code-snippets')}
77 </>
78 : <>
79 {emptyMessage}{' '}
80 <a href={buildUrl(window.CODE_SNIPPETS?.urls.addNew, { type: currentType })}>
81 {__('Add a new snippet.', 'code-snippets')}
82 </a>
83 </>
84 }
85
86 const getRowClassName = (
87 snippet: Snippet,
88 activeByCondition: Map<Snippet['id'], Snippet[]>
89 ): string =>
90 classnames(
91 'snippet',
92 `snippet ${isSnippetActive(snippet, activeByCondition) ? 'active' : 'inactive'}-snippet`,
93 `${getSnippetType(snippet)}-snippet`,
94 `${snippet.scope}-snippet`,
95 {
96 'trashed-snippet': snippet.trashed
97 }
98 )
99
100 interface SnippetsViewProps {
101 snippetView: SnippetView
102 setSnippetView: (view: SnippetView) => void
103 snippets: Snippet[]
104 actions: ListTableAction<SnippetsTableAction>[]
105 doAction: (action: SnippetsTableAction | undefined, selected: Set<Snippet['id']>) => Promise<void>
106 extraTableNav: (which: 'top' | 'bottom') => ReactNode
107 hiddenColumns: Set<string>
108 truncateRowValues: boolean
109 }
110
111 const SnippetsView: React.FC<SnippetsViewProps> = ({
112 snippetView,
113 setSnippetView,
114 snippets,
115 actions,
116 doAction,
117 extraTableNav,
118 hiddenColumns,
119 truncateRowValues
120 }) => {
121 const { activeByCondition } = useFilteredSnippets()
122 const columns = useMemo(() => getTableColumns(hiddenColumns), [hiddenColumns])
123 const itemsPerPage = window.CODE_SNIPPETS_MANAGE?.snippetsPerPage
124 const pageCount = itemsPerPage && Math.ceil(snippets.length / itemsPerPage)
125 const endTableNav = (which: 'top' | 'bottom') =>
126 'top' === which
127 ? <SnippetViewToggle snippetView={snippetView} setSnippetView={setSnippetView} />
128 : null
129
130 return 'card' === snippetView
131 ? <SnippetsCardGrid
132 snippets={snippets}
133 actions={actions}
134 doAction={doAction}
135 itemsPerPage={itemsPerPage}
136 extraTableNav={extraTableNav}
137 endTableNav={endTableNav}
138 noItems={<NoItemsMessage />}
139 beforeGrid={<SearchResultsIndicator />}
140 />
141 : <ListTable
142 items={snippets}
143 getKey={snippet => snippet.id}
144 className={classnames({ 'truncate-row-values': truncateRowValues })}
145 columns={columns}
146 actions={actions}
147 doAction={doAction}
148 totalPages={pageCount}
149 extraTableNav={extraTableNav}
150 selectAllControl
151 endTableNav={endTableNav}
152 rowClassName={snippet => getRowClassName(snippet, activeByCondition)}
153 noItems={<NoItemsMessage />}
154 beforeTable={<SearchResultsIndicator />}
155 />
156 }
157
158 export interface SnippetsListTableProps {
159 snippetView: SnippetView
160 setSnippetView: (view: SnippetView) => void
161 }
162
163 export const SnippetsListTable: React.FC<SnippetsListTableProps> = ({
164 snippetView,
165 setSnippetView
166 }) => {
167 const { snippetsByStatus } = useFilteredSnippets()
168 const { currentStatus, setCurrentStatus } = useSnippetsFilters()
169 const { hiddenColumns, truncateRowValues } = useManageTableSettings()
170
171 const currentSnippets = useMemo(
172 () => snippetsByStatus.get(currentStatus) ?? [],
173 [snippetsByStatus, currentStatus]
174 )
175 const applyBulkAction = useApplyBulkAction(currentSnippets)
176
177 useEffect(() => {
178 if (INDEX_STATUS !== currentStatus && !snippetsByStatus.has(currentStatus)) {
179 setCurrentStatus(INDEX_STATUS)
180 }
181 }, [currentStatus, setCurrentStatus, snippetsByStatus])
182
183 const extraTableNav = (which: 'top' | 'bottom') =>
184 <SnippetsTableNavigation which={which} visibleSnippets={snippetsByStatus.get('all') ?? []} />
185
186 return (
187 <>
188 <SnippetsTableToolbar />
189
190 <div className="snippets-list-view">
191 <SnippetsView
192 snippetView={snippetView}
193 setSnippetView={setSnippetView}
194 snippets={currentSnippets}
195 actions={'trashed' === currentStatus ? TRASHED_BULK_ACTIONS : BULK_ACTIONS}
196 doAction={applyBulkAction}
197 extraTableNav={extraTableNav}
198 hiddenColumns={hiddenColumns}
199 truncateRowValues={truncateRowValues}
200 />
201 </div>
202 </>
203 )
204 }
205