@igstack/app-catalog-frontend-core 6.12.0 → 6.12.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/api/infra/trpc.d.ts +27 -0
- package/dist/esm/modules/appCatalog/ui/catalog/AppDetailPanel.js +0 -1
- package/dist/esm/modules/appCatalog/ui/catalog/AppDetailPanel.js.map +1 -1
- package/dist/esm/modules/appCatalog/ui/detail/AppDetails.js +0 -1
- package/dist/esm/modules/appCatalog/ui/detail/AppDetails.js.map +1 -1
- package/dist/esm/modules/communityTools/siteOpen.d.ts +10 -0
- package/dist/esm/modules/communityTools/siteOpen.js +18 -0
- package/dist/esm/modules/communityTools/siteOpen.js.map +1 -0
- package/dist/esm/modules/communityTools/timeAgo.d.ts +2 -0
- package/dist/esm/modules/communityTools/timeAgo.js +11 -0
- package/dist/esm/modules/communityTools/timeAgo.js.map +1 -1
- package/dist/esm/modules/communityTools/ui/CardScreenshot.js +10 -12
- package/dist/esm/modules/communityTools/ui/CardScreenshot.js.map +1 -1
- package/dist/esm/modules/communityTools/ui/CardTitleBlock.d.ts +1 -1
- package/dist/esm/modules/communityTools/ui/CardTitleBlock.js +5 -13
- package/dist/esm/modules/communityTools/ui/CardTitleBlock.js.map +1 -1
- package/dist/esm/modules/communityTools/ui/CommunityPage.js +2 -4
- package/dist/esm/modules/communityTools/ui/CommunityPage.js.map +1 -1
- package/dist/esm/modules/communityTools/ui/FeedRow.d.ts +6 -3
- package/dist/esm/modules/communityTools/ui/FeedRow.js +14 -8
- package/dist/esm/modules/communityTools/ui/FeedRow.js.map +1 -1
- package/dist/esm/modules/communityTools/ui/ShelfTile.js +4 -7
- package/dist/esm/modules/communityTools/ui/ShelfTile.js.map +1 -1
- package/dist/esm/modules/communityTools/ui/ToolCard.js +15 -3
- package/dist/esm/modules/communityTools/ui/ToolCard.js.map +1 -1
- package/dist/esm/modules/communityTools/ui/ToolFormDialog.js +0 -1
- package/dist/esm/modules/communityTools/ui/ToolFormDialog.js.map +1 -1
- package/dist/esm/modules/communityTools/useCommunityTools.d.ts +2 -0
- package/dist/esm/modules/communityTools/useCommunityTools.js +0 -1
- package/dist/esm/modules/communityTools/useCommunityTools.js.map +1 -1
- package/package.json +4 -4
- package/src/modules/communityTools/siteOpen.ts +20 -0
- package/src/modules/communityTools/timeAgo.ts +12 -0
- package/src/modules/communityTools/ui/CardScreenshot.tsx +21 -9
- package/src/modules/communityTools/ui/CardTitleBlock.tsx +4 -9
- package/src/modules/communityTools/ui/CommunityPage.tsx +2 -5
- package/src/modules/communityTools/ui/FeedRow.tsx +19 -15
- package/src/modules/communityTools/ui/ShelfTile.tsx +4 -5
- package/src/modules/communityTools/ui/ToolCard.tsx +11 -1
|
@@ -13,7 +13,8 @@ import {
|
|
|
13
13
|
} from 'lucide-react'
|
|
14
14
|
import { cn } from '~/lib/utils'
|
|
15
15
|
import { highlightTokens } from '~/util/highlightMatches'
|
|
16
|
-
import {
|
|
16
|
+
import { recordSiteOpen } from '../siteOpen'
|
|
17
|
+
import { exactDate, timeAgo } from '../timeAgo'
|
|
17
18
|
import { LifecycleBadge, UnreviewedBadge } from './LifecycleBadge'
|
|
18
19
|
import { LikeButton } from './LikeButton'
|
|
19
20
|
import { PinButton } from './PinButton'
|
|
@@ -96,7 +97,10 @@ export interface FeedRowProps {
|
|
|
96
97
|
tool: CommunityTool
|
|
97
98
|
/** Shown in the ranked feed; search results have no rank. */
|
|
98
99
|
rank?: number
|
|
99
|
-
/**
|
|
100
|
+
/**
|
|
101
|
+
* Newest shows when it was added, Recently updated when the site changed;
|
|
102
|
+
* every other sort the site's date, or when it was added if that is unknown.
|
|
103
|
+
*/
|
|
100
104
|
sort: FeedSort
|
|
101
105
|
tokens: string[]
|
|
102
106
|
/** Set while searching: which fields the query hit. */
|
|
@@ -122,8 +126,8 @@ const PANEL = 'w-[120px]'
|
|
|
122
126
|
|
|
123
127
|
/**
|
|
124
128
|
* One tool in the feed or the search results. Everything left of the end
|
|
125
|
-
* panel (rank, picture, name, summary, meta) is one link that opens the
|
|
126
|
-
*
|
|
129
|
+
* panel (rank, picture, name, summary, meta) is one link that opens the
|
|
130
|
+
* site; the 120 px panel opens the card. The star sits in the meta
|
|
127
131
|
* line as its own target, above that link.
|
|
128
132
|
*/
|
|
129
133
|
export function FeedRow({
|
|
@@ -142,12 +146,12 @@ export function FeedRow({
|
|
|
142
146
|
const archived = tool.lifecycle.state === 'archived'
|
|
143
147
|
const cell = optionId ? 'gridcell' : undefined
|
|
144
148
|
const owners = tool.owners.map((o) => o.name).join(', ')
|
|
145
|
-
const
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
149
|
+
const siteUpdatedAt = sort !== 'newest' ? tool.siteUpdatedAt : null
|
|
150
|
+
const dated = siteUpdatedAt
|
|
151
|
+
? { label: 'Updated', at: siteUpdatedAt }
|
|
152
|
+
: sort !== 'updated'
|
|
153
|
+
? { label: 'Added', at: tool.createdAt }
|
|
154
|
+
: null
|
|
151
155
|
|
|
152
156
|
return (
|
|
153
157
|
<div
|
|
@@ -182,11 +186,10 @@ export function FeedRow({
|
|
|
182
186
|
<div className="flex items-center gap-2.5 text-[15.5px] font-extrabold">
|
|
183
187
|
<a
|
|
184
188
|
href={tool.url}
|
|
185
|
-
|
|
186
|
-
rel="noopener noreferrer"
|
|
189
|
+
onClick={() => recordSiteOpen(tool.slug)}
|
|
187
190
|
data-site
|
|
188
191
|
data-testid="feed-row-name"
|
|
189
|
-
aria-label={`${tool.name}, opens ${tool.host}
|
|
192
|
+
aria-label={`${tool.name}, opens ${tool.host}`}
|
|
190
193
|
className={cn(
|
|
191
194
|
'truncate decoration-1 underline-offset-[3px] after:absolute after:inset-y-0 after:left-0 after:right-[120px] after:z-[1] after:rounded-l-[13px] focus-visible:outline-none focus-visible:after:outline-2 focus-visible:after:-outline-offset-[3px] focus-visible:after:outline-ring',
|
|
192
195
|
'group-hover/row:underline group-has-[[data-details]:hover]/row:no-underline',
|
|
@@ -269,9 +272,10 @@ export function FeedRow({
|
|
|
269
272
|
{dated && (
|
|
270
273
|
<span
|
|
271
274
|
data-testid="feed-row-date"
|
|
272
|
-
|
|
275
|
+
title={exactDate(dated.at)}
|
|
276
|
+
className="pointer-events-auto ml-auto shrink-0 pr-4 text-[13px] font-semibold whitespace-nowrap text-muted-foreground"
|
|
273
277
|
>
|
|
274
|
-
{dated}
|
|
278
|
+
{dated.label} {timeAgo(dated.at)}
|
|
275
279
|
</span>
|
|
276
280
|
)}
|
|
277
281
|
</div>
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import type { CommunityTool } from '@igstack/app-catalog-shared-core'
|
|
2
|
-
import {
|
|
2
|
+
import { GripVertical } from 'lucide-react'
|
|
3
3
|
import { cn } from '~/lib/utils'
|
|
4
4
|
import { PersonAvatar, ToolThumb } from './FeedRow'
|
|
5
|
+
import { recordSiteOpen } from '../siteOpen'
|
|
5
6
|
import { PinButton } from './PinButton'
|
|
6
7
|
|
|
7
8
|
/**
|
|
@@ -35,8 +36,7 @@ export function ShelfTile({
|
|
|
35
36
|
>
|
|
36
37
|
<a
|
|
37
38
|
href={tool.url}
|
|
38
|
-
|
|
39
|
-
rel="noopener noreferrer"
|
|
39
|
+
onClick={() => recordSiteOpen(tool.slug)}
|
|
40
40
|
aria-keyshortcuts="Alt+ArrowUp Alt+ArrowDown"
|
|
41
41
|
onKeyDown={(e) => {
|
|
42
42
|
if (!e.altKey) return
|
|
@@ -49,8 +49,7 @@ export function ShelfTile({
|
|
|
49
49
|
>
|
|
50
50
|
<span className="relative block aspect-[16/9.5] border-b border-border">
|
|
51
51
|
<ToolThumb tool={tool} size={512} className="size-full border-0" />
|
|
52
|
-
<span className="absolute right-2.5 bottom-2.5
|
|
53
|
-
<ExternalLink aria-hidden="true" className="size-4" />
|
|
52
|
+
<span className="absolute right-2.5 bottom-2.5 rounded-lg bg-primary px-3 py-1.5 text-sm font-extrabold text-primary-foreground opacity-0 shadow-sm transition-opacity group-hover:opacity-100 group-focus-within:opacity-100">
|
|
54
53
|
Open site
|
|
55
54
|
</span>
|
|
56
55
|
</span>
|
|
@@ -26,6 +26,8 @@ import { Skeleton } from '~/ui/skeleton'
|
|
|
26
26
|
import { CardScreenshot, formatCardDate } from './CardScreenshot'
|
|
27
27
|
import { CardTitleBlock } from './CardTitleBlock'
|
|
28
28
|
import { PersonAvatar } from './FeedRow'
|
|
29
|
+
import { openSite } from '../siteOpen'
|
|
30
|
+
import { exactDate, timeAgo } from '../timeAgo'
|
|
29
31
|
import { useTimeUp } from '../useTimeUp'
|
|
30
32
|
import { PinButton } from './PinButton'
|
|
31
33
|
import { TagChip, tagKey, tagLabel } from './TagRow'
|
|
@@ -184,7 +186,7 @@ export function ToolCard({
|
|
|
184
186
|
// that opens the site.
|
|
185
187
|
if (target.closest('a, button')) return
|
|
186
188
|
e.preventDefault()
|
|
187
|
-
|
|
189
|
+
openSite(tool)
|
|
188
190
|
}
|
|
189
191
|
}
|
|
190
192
|
|
|
@@ -296,6 +298,14 @@ export function ToolCard({
|
|
|
296
298
|
</b>{' '}
|
|
297
299
|
all time
|
|
298
300
|
</span>
|
|
301
|
+
{tool.siteUpdatedAt && (
|
|
302
|
+
<span
|
|
303
|
+
data-testid="card-site-updated"
|
|
304
|
+
title={exactDate(tool.siteUpdatedAt)}
|
|
305
|
+
>
|
|
306
|
+
Site updated {timeAgo(tool.siteUpdatedAt)}
|
|
307
|
+
</span>
|
|
308
|
+
)}
|
|
299
309
|
</p>
|
|
300
310
|
)}
|
|
301
311
|
{/* Who to ask, up here with the facts: below the screenshot
|