diff --git a/frontend/src/druksui/Blocks.tsx b/frontend/src/druksui/Blocks.tsx
index 17311c00..4a55411c 100644
--- a/frontend/src/druksui/Blocks.tsx
+++ b/frontend/src/druksui/Blocks.tsx
@@ -1,13 +1,10 @@
-import { useContext } from 'react'
-import { Link as RouteLink } from 'wouter'
-
import type { Action, Block, Link } from '../api/types'
import { Markdown } from '../components/Markdown'
import { GateControls } from './GateControls'
-import { Chart, Facts, ImageGallery, List, Metrics, Table } from './DataBlocks'
+import { Chart, Facts, ImageGallery, LinkControl, List, Metrics, Table } from './DataBlocks'
import { ActionButton, Form } from './Form'
import { Files, Image, Progress, Timeline } from './RunBlocks'
-import { fillPath, PagesContext, RegionContext } from './pages'
+import { RegionContext } from './pages'
export function Blocks({ blocks }: { blocks: Block[] }) {
return (
@@ -163,38 +160,3 @@ function LinkRow({ links }: { links: (Action | Link)[] }) {
)
}
-function LinkControl({ link }: { link: Link }) {
- const { app, pages } = useContext(PagesContext)
- if (link.url) {
- return (
-
- {link.label}
-
- )
- }
- if (link.subject) {
- // The subject's own platform page — the full story of what druks did.
- return (
-
- {link.label}
-
- )
- }
- const target = pages.find((entry) => entry.name === link.page)
- const href = target ? fillPath(target.path, link.arguments) : ''
- if (href) {
- return (
-
- {link.label}
-
- )
- }
- return (
-
- {link.label}
-
- )
-}
diff --git a/frontend/src/druksui/DataBlocks.test.tsx b/frontend/src/druksui/DataBlocks.test.tsx
index 4cf66345..8513f71a 100644
--- a/frontend/src/druksui/DataBlocks.test.tsx
+++ b/frontend/src/druksui/DataBlocks.test.tsx
@@ -86,6 +86,31 @@ describe('values', () => {
expect(screen.getByText('peer-7').getAttribute('href')).toBe('/field_notes/notes/7')
})
+ it('follows a subject link out of a list item', () => {
+ renderBlocks([
+ {
+ block: 'list',
+ title: '',
+ items: [
+ {
+ value: 'text',
+ text: 'peer-7',
+ link: {
+ block: 'link',
+ label: 'peer-7',
+ page: '',
+ arguments: {},
+ url: '',
+ subject: { subjectType: 'note', subjectId: '7' },
+ },
+ },
+ ],
+ },
+ ])
+
+ expect(screen.getByText('peer-7').getAttribute('href')).toBe('/field_notes/note/7')
+ })
+
it('shows a number the way the app gave it', () => {
renderBlocks([
{
diff --git a/frontend/src/druksui/DataBlocks.tsx b/frontend/src/druksui/DataBlocks.tsx
index 6d04f305..cbf9bc78 100644
--- a/frontend/src/druksui/DataBlocks.tsx
+++ b/frontend/src/druksui/DataBlocks.tsx
@@ -52,27 +52,44 @@ export function Datum({ value }: { value: Value }) {
}
function TextDatum({ text, link }: { text: string; link: Link | null }) {
- const { pages } = useContext(PagesContext)
if (!link) return {text}
+ return
+}
+
+/** A control that navigates. It is a block of its own, or the link on a value,
+ which shows the value's own text. */
+export function LinkControl({ link, label = link.label }: { link: Link; label?: string }) {
+ const { app, pages } = useContext(PagesContext)
if (link.url) {
return (
- {text}
+ {label}
)
}
+ if (link.subject) {
+ // The subject's own platform page — the full story of what druks did.
+ return (
+
+ {label}
+
+ )
+ }
const target = pages.find((entry) => entry.name === link.page)
const href = target ? fillPath(target.path, link.arguments) : ''
if (href) {
return (
- {text}
+ {label}
)
}
return (
- {text}
+ {label}
)
}