PluginProbe
Code Snippets / 3.10.2
Code Snippets v3.10.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
code-snippets / js / components / ManageMenu / CommunityCloud / SearchResult.tsx

SearchResult.tsx in Code Snippets 3.10.2, at js/components/ManageMenu/CommunityCloud/SearchResult.tsx

143 lines 4.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 import { humanTimeDiff } from '@wordpress/date'
2 import { __, sprintf } from '@wordpress/i18n'
3 import React, { useState } from 'react'
4 import { getSnippetType } from '../../../utils/snippets/snippets'
5 import { stripTags, truncateChars } from '../../../utils/text'
6 import { Badge } from '../../common/Badge'
7 import { Button } from '../../common/Button'
8 import { CloudSnippetDownloadButton } from '../../common/cloud/CloudSnippetDownloadButton'
9 import { CloudStatusIndicator } from '../../common/cloud/CloudStatusBadge'
10 import { CloudUpdateIcon } from '../../common/icons/CloudUpdateIcon'
11 import { SnippetCard } from '../../common/snippets/SnippetCard'
12 import { CloudSnippetPreviewModal } from '../../common/snippets/SnippetPreviewModal'
13 import { useCloudSearch } from './WithCloudSearchContext'
14 import type { ReactNode } from 'react'
15 import type { CloudSnippetSchema } from '../../../types/schema/CloudSnippetSchema'
16
17 export interface CloudSnippetAuthorProps {
18 codevaultSlug: string
19 }
20
21 export const CloudSnippetAuthor: React.FC<CloudSnippetAuthorProps> = ({ codevaultSlug }) =>
22 <p className="cloud-snippet-author">
23 <a
24 href={`${window.CODE_SNIPPETS?.urls.cloud}/codevault/${codevaultSlug}`}
25 target="_blank"
26 rel="noopener noreferrer"
27 >
28 {// translators: %s: cloud library author name.
29 sprintf(__('By %s', 'code-snippets'), codevaultSlug)}
30 </a>
31 </p>
32
33 interface CloudSnippetDetailsProps {
34 snippet: CloudSnippetSchema
35 author?: ReactNode
36 setIsPreviewOpen: (isOpen: boolean) => void
37 }
38
39 const CloudSnippetDetails: React.FC<CloudSnippetDetailsProps> = ({
40 snippet,
41 author,
42 setIsPreviewOpen
43 }) =>
44 <div className="cloud-snippet card-inner">
45 <div className="snippet-card-header">
46 <Badge name={getSnippetType(snippet)} />
47
48 <h3>
49 <button
50 type="button"
51 className="cloud-snippet-title-button"
52 title={__('Preview this snippet', 'code-snippets')}
53 onClick={() => {
54 setIsPreviewOpen(true)
55 }}
56 >
57 {snippet.name}
58 </button>
59 </h3>
60 </div>
61
62 {0 < snippet.tags.length || snippet.updated
63 ? <div className="snippet-card-meta">
64 {0 < snippet.tags.length
65 ? <span className="cloud-snippet-tags">
66 <span className="snippet-card-tags-label">
67 {__('Tags:', 'code-snippets')}
68 </span> {snippet.tags.join(', ')}
69 </span>
70 : null}
71
72 {snippet.updated
73 ? <time className="snippet-card-modified" dateTime={snippet.updated} title={snippet.updated}>
74 {sprintf(
75 /* translators: %s: human-readable time difference. */
76 __('Modified %s', 'code-snippets'),
77 humanTimeDiff(snippet.updated, undefined)
78 )}
79 </time>
80 : null}
81 </div>
82 : null}
83
84 {snippet.description
85 ? <p className="snippet-description-content">
86 {truncateChars(stripTags(snippet.description))}
87 </p>
88 : null}
89
90 {author}
91 </div>
92
93 export interface SearchResultProps {
94 snippet: CloudSnippetSchema
95 author?: ReactNode
96 isSelected?: boolean
97 onSelectedChange?: (isSelected: boolean) => void
98 }
99
100 export const SearchResult: React.FC<SearchResultProps> = ({
101 snippet,
102 author,
103 isSelected = false,
104 onSelectedChange
105 }) => {
106 const { doSearch } = useCloudSearch()
107 const [isPreviewOpen, setIsPreviewOpen] = useState(false)
108
109 return (
110 <SnippetCard
111 className="cloud-search-result"
112 isSelected={isSelected}
113 onSelectedChange={onSelectedChange}
114 selectionLabel={sprintf(
115 /* translators: %s: name of the snippet. */
116 __('Select %s', 'code-snippets'),
117 snippet.name
118 )}
119 footerStatus={<>
120 <CloudStatusIndicator status={snippet.status} />
121
122 {snippet.update_available
123 ? <span className="cloud-snippet-update" title={__('Update available', 'code-snippets')}>
124 <CloudUpdateIcon aria-label={__('Update available', 'code-snippets')} />
125 </span>
126 : null}
127 </>}
128 footer={<>
129 <Button secondary onClick={() => setIsPreviewOpen(true)}>
130 {__('Preview', 'code-snippets')}
131 </Button>
132
133 <CloudSnippetDownloadButton snippet={snippet} onDownloaded={doSearch} />
134 </>}
135 >
136 <CloudSnippetDetails snippet={snippet} author={author} setIsPreviewOpen={setIsPreviewOpen} />
137
138 {isPreviewOpen && (
139 <CloudSnippetPreviewModal snippet={snippet} setIsOpen={setIsPreviewOpen} onDownloaded={doSearch} />)}
140 </SnippetCard>
141 )
142 }
143