PluginProbe
Code Snippets / 4.0.0-beta.2
Code Snippets v4.0.0-beta.2
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
← All changes | js/components/ManageMenu/SnippetsTable/TableColumns.tsx +66 -9 3.10.2 → 4.0.0-beta.2 View file →
@@ -1,7 +1,7 @@
1 1 import { humanTimeDiff } from '@wordpress/date'
2 2 import { RawHTML } from '@wordpress/element'
3 -import { __ } from '@wordpress/i18n'
3 +import { __, sprintf } from '@wordpress/i18n'
4 4 import React, { Fragment } from 'react'
5 5 import { useSnippetsAPI } from '../../../hooks/useSnippetsAPI'
6 6 import { useSnippetsList } from '../../../hooks/useSnippetsList'
7 7 import { handleUnknownError } from '../../../utils/errors'
@@ -6,8 +6,9 @@
6 6 import { useSnippetsList } from '../../../hooks/useSnippetsList'
7 7 import { handleUnknownError } from '../../../utils/errors'
8 8 import { isNetworkAdmin } from '../../../utils/screen'
9 9 import { getSnippetDisplayName, getSnippetEditUrl, getSnippetType } from '../../../utils/snippets/snippets'
10 +import { getRunOnceNonce } from '../../../utils/restAPI'
10 11 import { buildUrl } from '../../../utils/urls'
11 12 import { Badge } from '../../common/Badge'
12 13 import { SnippetPriorityInput } from '../../common/snippets/SnippetPriorityInput'
13 14 import { Tooltip } from '../../common/Tooltip'
@@ -21,18 +22,32 @@
21 22 interface ColumnProps {
22 23 snippet: Snippet
23 24 }
24 25
26 +const runOnceUrl = (snippet: Snippet, nonce: string): string =>
27 + buildUrl(window.location.href, {
28 + action: 'run-once',
29 + snippet: snippet.id,
30 + network: snippet.network ? 'true' : 'false',
31 + _wpnonce: nonce
32 + })
33 +
34 +// The rendered link carries the nonce from page load. Before any navigation
35 +// starts, whether a click, a middle-click or "open in new tab", the href is
36 +// rebuilt from the nonce the Heartbeat has refreshed since, so a page left open
37 +// still works.
25 38 const RunOnceButton: React.FC<ColumnProps> = ({ snippet }) =>
26 39 <a
27 40 className="snippet-execution-button"
28 41 title={__('Run Once', 'code-snippets')}
29 - href={buildUrl(window.location.href, {
30 - action: 'run-once',
31 - snippet: snippet.id,
32 - network: snippet.network ? 'true' : 'false',
33 - _wpnonce: window.CODE_SNIPPETS_MANAGE?.runOnceNonce ?? ''
34 - })}
42 + href={runOnceUrl(snippet, window.CODE_SNIPPETS_MANAGE?.runOnceNonce ?? '')}
43 + onMouseDown={event => {
44 + event.currentTarget.href = runOnceUrl(snippet, getRunOnceNonce())
45 + }}
46 + onClick={event => {
47 + event.preventDefault()
48 + window.location.assign(runOnceUrl(snippet, getRunOnceNonce()))
49 + }}
35 50 >
36 51 <span className="screen-reader-text">{__('Run Once', 'code-snippets')}</span>
37 52 <span aria-hidden="true">&nbsp;</span>
38 53 </a>
@@ -100,9 +115,9 @@
100 115 </Tooltip>)}
101 116 </div>
102 117
103 118 export const SnippetName: React.FC<ColumnProps> = ({ snippet }) =>
104 - <>
119 + <span className="snippet-name-group">
105 120 {!snippet.trashed && (isNetworkAdmin() || !snippet.network || window.CODE_SNIPPETS_MANAGE?.hasNetworkCap)
106 121 ? <a
107 122 href={getSnippetEditUrl(snippet)}
108 123 className="snippet-name"
@@ -114,9 +129,9 @@
114 129 {getSnippetDisplayName(snippet)}
115 130 </span>}
116 131
117 132 {snippet.shared_network && <span className="badge">{__('Shared on Network', 'code-snippets')}</span>}
118 - </>
133 + </span>
119 134
120 135 const NameColumn: React.FC<ColumnProps> = ({ snippet }) =>
121 136 <>
122 137 <SnippetExtraIcons snippet={snippet} />
@@ -158,8 +173,38 @@
158 173 </time>
159 174 </span>
160 175 : <>&#8212;</>
161 176
177 +export const PriorityColumn: React.FC<ColumnProps> = ({ snippet }) =>
178 + <SnippetPriorityInput snippet={snippet} />
179 +
180 +export const getAuthorDisplayName = (snippet: Snippet): string =>
181 + (snippet.updatedBy ?? snippet.createdBy)?.displayName ?? ''
182 +
183 +const AuthorColumn: React.FC<ColumnProps> = ({ snippet }) => {
184 + const creator = snippet.createdBy
185 + const updater = snippet.updatedBy
186 + const primary = updater ?? creator
187 +
188 + if (!primary) {
189 + return <span className="snippet-author is-unknown">&#8212;</span>
190 + }
191 +
192 + const tooltip = creator && updater && creator.id !== updater.id
193 + ? sprintf(__('Created by %1$s ยท Last edited by %2$s', 'code-snippets'), creator.displayName, updater.displayName)
194 + : creator
195 + ? sprintf(__('Created by %s', 'code-snippets'), creator.displayName)
196 + : sprintf(__('Last edited by %s', 'code-snippets'), primary.displayName)
197 +
198 + return (
199 + <span className="snippet-author" title={tooltip}>
200 + {primary.avatarUrl &&
201 + <img className="snippet-author__avatar" src={primary.avatarUrl} alt="" width={20} height={20} />}
202 + <span className="snippet-author__name">{primary.displayName}</span>
203 + </span>
204 + )
205 +}
206 +
162 207 const baseTableColumns: ListTableColumn<Snippet>[] = [
163 208 {
164 209 id: 'activate',
165 210 title: <span className="screen-reader-text">{__('Activate', 'code-snippets')}</span>,
@@ -165,8 +210,14 @@
165 210 title: <span className="screen-reader-text">{__('Activate', 'code-snippets')}</span>,
166 211 render: snippet => <ActivateColumn snippet={snippet} />
167 212 },
168 213 {
214 + id: 'id',
215 + title: __('ID', 'code-snippets'),
216 + sortedValue: snippet => snippet.id,
217 + render: snippet => snippet.id
218 + },
219 + {
169 220 id: 'name',
170 221 title: __('Name', 'code-snippets'),
171 222 isPrimary: true,
172 223 sortedValue: snippet => getSnippetDisplayName(snippet).toLowerCase(),
@@ -198,8 +249,14 @@
198 249 id: 'priority',
199 250 title: __('Priority', 'code-snippets'),
200 251 sortedValue: snippet => snippet.priority,
201 252 render: snippet => <SnippetPriorityInput snippet={snippet} />
253 + },
254 + {
255 + id: 'author',
256 + title: __('Author', 'code-snippets'),
257 + sortedValue: snippet => getAuthorDisplayName(snippet).toLowerCase(),
258 + render: snippet => <AuthorColumn snippet={snippet} />
202 259 }
203 260 ]
204 261
205 262 export const getTableColumns = (hiddenColumns: Set<Key>): ListTableColumn<Snippet>[] =>