PluginProbe
Code Snippets / trunk
Code Snippets vtrunk
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 / CloudLibraryDemo / cloudLibraryDemoColumns.tsx

cloudLibraryDemoColumns.tsx in Code Snippets trunk, at js/components/ManageMenu/CloudLibraryDemo/cloudLibraryDemoColumns.tsx

142 lines 4.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 import React, { Fragment } from 'react'
2 import { __ } from '@wordpress/i18n'
3 import { humanTimeDiff } from '@wordpress/date'
4 import classnames from 'classnames'
5 import { getSnippetDisplayName, getSnippetType } from '../../../utils/snippets/snippets'
6 import { stripTags, truncateChars } from '../../../utils/text'
7 import { Badge } from '../../common/Badge'
8 import { Button } from '../../common/Button'
9 import { CloudStatusBadge } from '../../common/cloud/CloudStatusBadge'
10 import { Tooltip } from '../../common/Tooltip'
11 import { CloudAvailableIcon } from '../../common/icons/cloud/CloudAvailableIcon'
12 import { CloudSyncedIcon } from '../../common/icons/cloud/CloudSyncedIcon'
13 import { FEATURED_SNIPPET_ID } from './demoCloudSnippets'
14 import { hasReached } from './types'
15 import type { DemoStage } from './types'
16 import type { ListTableColumn } from '../../common/ListTable'
17 import type { CloudSnippetSchema } from '../../../types/schema/CloudSnippetSchema'
18
19 /**
20 * Whether a row should render as already downloaded. Only the featured snippet
21 * changes state, and only once the walkthrough has downloaded it.
22 */
23 const isSynced = (snippet: CloudSnippetSchema, stage: DemoStage): boolean =>
24 FEATURED_SNIPPET_ID === snippet.id && hasReached(stage, 'synced')
25
26 const StateColumn: React.FC<{ snippet: CloudSnippetSchema, stage: DemoStage }> = ({ snippet, stage }) => {
27 const synced = isSynced(snippet, stage)
28 const label = synced
29 ? __('Synced to Cloud', 'code-snippets')
30 : __('Available in Cloud', 'code-snippets')
31
32 const Icon = () =>
33 <span className="cloud-sync-indicator" role="img" aria-label={label}>
34 {synced ? <CloudSyncedIcon /> : <CloudAvailableIcon />}
35 </span>
36
37 return <Tooltip inline label={label} icon={<Icon />}>{label}</Tooltip>
38 }
39
40 const TagsColumn: React.FC<{ snippet: CloudSnippetSchema }> = ({ snippet }) =>
41 snippet.tags.map((tag, index) =>
42 <Fragment key={tag}>{tag}{index < snippet.tags.length - 1 ? ', ' : ''}</Fragment>)
43
44 interface ActionsColumnProps {
45 snippet: CloudSnippetSchema
46 stage: DemoStage
47 onPreview: (snippet: CloudSnippetSchema) => void
48 }
49
50 const ActionsColumn: React.FC<ActionsColumnProps> = ({ snippet, stage, onPreview }) => {
51 const featured = FEATURED_SNIPPET_ID === snippet.id
52
53 return (
54 <div className="cloud-snippet-action-buttons">
55 <Button
56 secondary
57 className={classnames('demo-preview-button', { 'demo-click': featured && 'preview' === stage })}
58 onClick={() => onPreview(snippet)}
59 >
60 {__('Preview', 'code-snippets')}
61 </Button>
62
63 {isSynced(snippet, stage)
64 ? <Button secondary className="demo-action-button" aria-hidden="true" tabIndex={-1}>
65 {__('Edit', 'code-snippets')}
66 </Button>
67 : <Button
68 primary
69 aria-hidden="true"
70 tabIndex={-1}
71 className={classnames('cloud-snippet-download demo-action-button', {
72 'demo-click': featured && 'download' === stage
73 })}
74 >
75 {__('Download', 'code-snippets')}
76 </Button>}
77 </div>
78 )
79 }
80
81 interface ColumnParams {
82 stage: DemoStage
83 onPreview: (snippet: CloudSnippetSchema) => void
84 }
85
86 // eslint-disable-next-line max-lines-per-function -- the column set reads as one table definition.
87 export const cloudLibraryDemoColumns = (
88 { stage, onPreview }: ColumnParams
89 ): ListTableColumn<CloudSnippetSchema>[] => [
90 {
91 id: 'state',
92 title: <CloudAvailableIcon role="img" aria-label={__('Sync Status', 'code-snippets')} />,
93 render: snippet => <StateColumn snippet={snippet} stage={stage} />
94 },
95 {
96 id: 'name',
97 title: __('Snippet Name', 'code-snippets'),
98 isPrimary: true,
99 sortedValue: snippet => getSnippetDisplayName(snippet).toLowerCase(),
100 render: snippet => <strong>{snippet.name}</strong>
101 },
102 {
103 id: 'type',
104 title: __('Type', 'code-snippets'),
105 sortedValue: snippet => getSnippetType(snippet),
106 render: snippet => <Badge name={getSnippetType(snippet)} />
107 },
108 {
109 id: 'status',
110 title: __('Status', 'code-snippets'),
111 sortedValue: snippet => snippet.status,
112 render: snippet => <CloudStatusBadge status={snippet.status} />
113 },
114 {
115 id: 'desc',
116 title: __('Description', 'code-snippets'),
117 render: snippet =>
118 <div className="snippet-description-content">
119 {truncateChars(stripTags(snippet.description))}
120 </div>
121 },
122 {
123 id: 'tags',
124 title: __('Tags', 'code-snippets'),
125 render: snippet => <TagsColumn snippet={snippet} />
126 },
127 {
128 id: 'date',
129 title: __('Updated', 'code-snippets'),
130 sortedValue: snippet => new Date(snippet.updated).toISOString(),
131 render: snippet =>
132 <span className="modified-column-content" title={snippet.updated}>
133 <time dateTime={snippet.updated}>{humanTimeDiff(snippet.updated, undefined)}</time>
134 </span>
135 },
136 {
137 id: 'actions',
138 title: <span className="screen-reader-text">{__('Actions', 'code-snippets')}</span>,
139 render: snippet => <ActionsColumn snippet={snippet} stage={stage} onPreview={onPreview} />
140 }
141 ]
142