Skip to content

Commit a4a2150

Browse files
nickwesselmanclaude
andcommitted
DRY up shortcut and link rendering in DevSessionUI
Extract devStatusShortcuts array with shortcutLabel, linkLabel, url, condition, and action fields. Both the keyboard shortcut hints and the URL list are now rendered by iterating over the same collection, eliminating duplicated conditions and labels. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 6e6b8d4 commit a4a2150

File tree

2 files changed

+72
-81
lines changed

2 files changed

+72
-81
lines changed

packages/app/src/cli/services/dev/ui/components/DevSessionUI.tsx

Lines changed: 71 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import {Spinner} from './Spinner.js'
2-
import {TabPanel, Tab} from './TabPanel.js'
2+
import {TabPanel, Tab, TabShortcut} from './TabPanel.js'
33
import metadata from '../../../../metadata.js'
44
import {
55
DevSessionStatus,
@@ -22,6 +22,12 @@ import {treeKill} from '@shopify/cli-kit/node/tree-kill'
2222
import {postRunHookHasCompleted} from '@shopify/cli-kit/node/hooks/postrun'
2323
import {Writable} from 'stream'
2424

25+
interface DevStatusShortcut extends TabShortcut {
26+
shortcutLabel: string
27+
linkLabel: string
28+
url?: string
29+
}
30+
2531
interface DevSesionUIProps {
2632
processes: OutputProcess[]
2733
abortController: AbortController
@@ -119,85 +125,78 @@ const DevSessionUI: FunctionComponent<DevSesionUIProps> = ({
119125
}
120126
}
121127

128+
const devStatusShortcuts: DevStatusShortcut[] = [
129+
{
130+
key: 'p',
131+
shortcutLabel: 'Open app preview',
132+
linkLabel: 'Preview',
133+
url: status.previewURL,
134+
condition: () => Boolean(status.isReady && status.previewURL),
135+
action: async () => {
136+
await metadata.addPublicMetadata(() => ({
137+
cmd_dev_preview_url_opened: true,
138+
}))
139+
if (status.previewURL) {
140+
await openURL(status.previewURL)
141+
}
142+
},
143+
},
144+
{
145+
key: 'c',
146+
shortcutLabel: 'Open Dev Console for extension previews',
147+
linkLabel: 'Dev Console',
148+
url: buildDevConsoleURL(shopFqdn),
149+
condition: () => Boolean(status.isReady && status.appEmbedded === false && status.hasExtensions),
150+
action: async () => {
151+
await metadata.addPublicMetadata(() => ({
152+
cmd_dev_preview_url_opened: true,
153+
}))
154+
await openURL(buildDevConsoleURL(shopFqdn))
155+
},
156+
},
157+
{
158+
key: 'g',
159+
shortcutLabel: 'Open GraphiQL (Admin API)',
160+
linkLabel: 'GraphiQL',
161+
url: status.graphiqlURL,
162+
condition: () => Boolean(status.isReady && status.graphiqlURL),
163+
action: async () => {
164+
await metadata.addPublicMetadata(() => ({
165+
cmd_dev_graphiql_opened: true,
166+
}))
167+
if (status.graphiqlURL) {
168+
await openURL(status.graphiqlURL)
169+
}
170+
},
171+
},
172+
]
173+
174+
const activeShortcuts = devStatusShortcuts.filter((shortcut) => shortcut.condition?.() ?? true)
175+
122176
const tabs: {[key: string]: Tab} = {
123177
// eslint-disable-next-line id-length
124178
d: {
125179
label: 'Dev status',
126-
shortcuts: [
127-
{
128-
key: 'p',
129-
condition: () => Boolean(status.isReady && status.previewURL),
130-
action: async () => {
131-
await metadata.addPublicMetadata(() => ({
132-
cmd_dev_preview_url_opened: true,
133-
}))
134-
if (status.previewURL) {
135-
await openURL(status.previewURL)
136-
}
137-
},
138-
},
139-
{
140-
key: 'g',
141-
condition: () => Boolean(status.isReady && status.graphiqlURL),
142-
action: async () => {
143-
await metadata.addPublicMetadata(() => ({
144-
cmd_dev_graphiql_opened: true,
145-
}))
146-
if (status.graphiqlURL) {
147-
await openURL(status.graphiqlURL)
148-
}
149-
},
150-
},
151-
{
152-
key: 'c',
153-
condition: () => Boolean(status.isReady && status.appEmbedded === false && status.hasExtensions),
154-
action: async () => {
155-
await metadata.addPublicMetadata(() => ({
156-
cmd_dev_preview_url_opened: true,
157-
}))
158-
await openURL(buildDevConsoleURL(shopFqdn))
159-
},
160-
},
161-
],
180+
shortcuts: devStatusShortcuts,
162181
content: (
163182
<>
164183
{status.statusMessage && (
165184
<Text>
166185
{getStatusIndicator(status.statusMessage.type)} {status.statusMessage.message}
167186
</Text>
168187
)}
169-
{canUseShortcuts && (
188+
{canUseShortcuts && activeShortcuts.length > 0 && (
170189
<Box marginTop={1} flexDirection="column">
171-
{status.isReady && status.previewURL ? (
172-
<Text>
173-
{figures.pointerSmall} <Text bold>(p)</Text>{' '}
174-
{terminalSupportsHyperlinks() ? (
175-
<Link url={status.previewURL} label="Open app preview" />
176-
) : (
177-
'Open app preview'
178-
)}
179-
</Text>
180-
) : null}
181-
{status.isReady && !status.appEmbedded && status.hasExtensions ? (
182-
<Text>
183-
{figures.pointerSmall} <Text bold>(c)</Text>{' '}
184-
{terminalSupportsHyperlinks() ? (
185-
<Link url={buildDevConsoleURL(shopFqdn)} label="Open Dev Console for extension previews" />
186-
) : (
187-
'Open Dev Console for extension previews'
188-
)}
189-
</Text>
190-
) : null}
191-
{status.isReady && status.graphiqlURL ? (
192-
<Text>
193-
{figures.pointerSmall} <Text bold>(g)</Text>{' '}
194-
{terminalSupportsHyperlinks() ? (
195-
<Link url={status.graphiqlURL} label="Open GraphiQL (Admin API)" />
190+
{activeShortcuts.map((shortcut) => (
191+
<Text key={shortcut.key}>
192+
{figures.pointerSmall} <Text bold>({shortcut.key})</Text>{' '}
193+
{terminalSupportsHyperlinks() && shortcut.url ? (
194+
<Link url={shortcut.url} label={shortcut.shortcutLabel} />
196195
) : (
197-
'Open GraphiQL (Admin API)'
196+
shortcut.shortcutLabel
198197
)}
199198
</Text>
200-
) : null}
199+
))}
201200
</Box>
202201
)}
203202
<Box marginTop={canUseShortcuts ? 1 : 0} flexDirection="column">
@@ -207,21 +206,13 @@ const DevSessionUI: FunctionComponent<DevSesionUIProps> = ({
207206
<>
208207
{status.isReady && !(canUseShortcuts && terminalSupportsHyperlinks()) && (
209208
<>
210-
{status.previewURL ? (
211-
<Text>
212-
Preview URL: <Link url={status.previewURL} />
213-
</Text>
214-
) : null}
215-
{status.appEmbedded === false && status.hasExtensions ? (
216-
<Text>
217-
Dev Console URL: <Link url={buildDevConsoleURL(shopFqdn)} />
218-
</Text>
219-
) : null}
220-
{status.graphiqlURL ? (
221-
<Text>
222-
GraphiQL URL: <Link url={status.graphiqlURL} />
223-
</Text>
224-
) : null}
209+
{activeShortcuts
210+
.filter((shortcut) => shortcut.url)
211+
.map((shortcut) => (
212+
<Text key={shortcut.key}>
213+
{shortcut.linkLabel} URL: <Link url={shortcut.url!} />
214+
</Text>
215+
))}
225216
</>
226217
)}
227218
</>

packages/app/src/cli/services/dev/ui/components/TabPanel.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ export interface Tab {
88
action?: () => Promise<void>
99
}
1010

11-
interface TabShortcut {
11+
export interface TabShortcut {
1212
key: string
1313
condition?: () => boolean
1414
action: () => Promise<void>

0 commit comments

Comments
 (0)