@navios/commander-tui 1.3.0 → 1.4.0
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/CHANGELOG.md +25 -0
- package/{src/__tests__/mocks/scm-mock.ts → dist/base/src/__tests__/mocks/scm-mock.d.ts} +3 -1
- package/dist/base/src/__tests__/mocks/scm-mock.d.ts.map +1 -0
- package/dist/base/src/__tests__/setup.d.ts +2 -0
- package/dist/base/src/__tests__/setup.d.ts.map +1 -0
- package/dist/base/src/__tests__/utils/factories.d.ts +67 -0
- package/dist/base/src/__tests__/utils/factories.d.ts.map +1 -0
- package/dist/base/src/__tests__/utils/render-utils.d.ts +21 -0
- package/dist/base/src/__tests__/utils/render-utils.d.ts.map +1 -0
- package/dist/base/src/__tests__/utils/test-container.d.ts +20 -0
- package/dist/base/src/__tests__/utils/test-container.d.ts.map +1 -0
- package/dist/base/src/adapters/interface.d.ts +9 -2
- package/dist/base/src/adapters/interface.d.ts.map +1 -1
- package/dist/base/src/overrides/missing-adapter.override.d.ts +10 -0
- package/dist/base/src/overrides/missing-adapter.override.d.ts.map +1 -1
- package/dist/base/src/schemas/logger-options.d.ts +1 -1
- package/dist/base/src/services/index.d.ts +1 -0
- package/dist/base/src/services/index.d.ts.map +1 -1
- package/dist/base/src/services/logger.d.ts.map +1 -1
- package/dist/base/src/services/readline_prompt.d.ts +27 -0
- package/dist/base/src/services/readline_prompt.d.ts.map +1 -0
- package/dist/base/src/services/screen.d.ts +14 -8
- package/dist/base/src/services/screen.d.ts.map +1 -1
- package/dist/base/src/services/screen_manager.d.ts +62 -12
- package/dist/base/src/services/screen_manager.d.ts.map +1 -1
- package/dist/base/src/types/events.types.d.ts +40 -0
- package/dist/base/src/types/events.types.d.ts.map +1 -0
- package/dist/base/src/types/index.d.ts +1 -0
- package/dist/base/src/types/index.d.ts.map +1 -1
- package/dist/base/src/types/screen.types.d.ts +28 -0
- package/dist/base/src/types/screen.types.d.ts.map +1 -1
- package/dist/base/src/utils/colors/helpers.d.ts +0 -16
- package/dist/base/src/utils/colors/helpers.d.ts.map +1 -1
- package/dist/base/src/utils/index.d.ts +2 -0
- package/dist/base/src/utils/index.d.ts.map +1 -1
- package/dist/base/src/utils/prompt.d.ts +7 -0
- package/dist/base/src/utils/prompt.d.ts.map +1 -0
- package/dist/base/src/utils/runtime.d.ts +10 -0
- package/dist/base/src/utils/runtime.d.ts.map +1 -0
- package/dist/base/src/utils/stdout-printer.d.ts +5 -0
- package/dist/base/src/utils/stdout-printer.d.ts.map +1 -1
- package/dist/base/tsconfig.base.tsbuildinfo +1 -1
- package/dist/base/tsconfig.tsbuildinfo +1 -0
- package/dist/ink/src/adapters/ink/components/file/file_log.d.ts +28 -0
- package/dist/ink/src/adapters/ink/components/file/file_log.d.ts.map +1 -0
- package/dist/ink/src/adapters/ink/components/file/index.d.ts +2 -0
- package/dist/ink/src/adapters/ink/components/file/index.d.ts.map +1 -0
- package/dist/ink/src/adapters/ink/components/filter/filter_bar.d.ts +7 -0
- package/dist/ink/src/adapters/ink/components/filter/filter_bar.d.ts.map +1 -0
- package/dist/ink/src/adapters/ink/components/filter/index.d.ts +2 -0
- package/dist/ink/src/adapters/ink/components/filter/index.d.ts.map +1 -0
- package/dist/ink/src/adapters/ink/components/help/help_overlay.d.ts +6 -0
- package/dist/ink/src/adapters/ink/components/help/help_overlay.d.ts.map +1 -0
- package/dist/ink/src/adapters/ink/components/help/index.d.ts +2 -0
- package/dist/ink/src/adapters/ink/components/help/index.d.ts.map +1 -0
- package/dist/ink/src/adapters/ink/components/index.d.ts +9 -0
- package/dist/ink/src/adapters/ink/components/index.d.ts.map +1 -0
- package/dist/ink/src/adapters/ink/components/log/index.d.ts +2 -0
- package/dist/ink/src/adapters/ink/components/log/index.d.ts.map +1 -0
- package/dist/ink/src/adapters/ink/components/log/log_message.d.ts +15 -0
- package/dist/ink/src/adapters/ink/components/log/log_message.d.ts.map +1 -0
- package/dist/ink/src/adapters/ink/components/prompt/index.d.ts +2 -0
- package/dist/ink/src/adapters/ink/components/prompt/index.d.ts.map +1 -0
- package/dist/ink/src/adapters/ink/components/prompt/prompt_renderer.d.ts +6 -0
- package/dist/ink/src/adapters/ink/components/prompt/prompt_renderer.d.ts.map +1 -0
- package/dist/ink/src/adapters/ink/components/screen/group_renderer.d.ts +14 -0
- package/dist/ink/src/adapters/ink/components/screen/group_renderer.d.ts.map +1 -0
- package/dist/ink/src/adapters/ink/components/screen/index.d.ts +7 -0
- package/dist/ink/src/adapters/ink/components/screen/index.d.ts.map +1 -0
- package/dist/ink/src/adapters/ink/components/screen/loading_message.d.ts +6 -0
- package/dist/ink/src/adapters/ink/components/screen/loading_message.d.ts.map +1 -0
- package/dist/ink/src/adapters/ink/components/screen/message_renderer.d.ts +6 -0
- package/dist/ink/src/adapters/ink/components/screen/message_renderer.d.ts.map +1 -0
- package/dist/ink/src/adapters/ink/components/screen/progress_message.d.ts +6 -0
- package/dist/ink/src/adapters/ink/components/screen/progress_message.d.ts.map +1 -0
- package/dist/ink/src/adapters/ink/components/screen/screen_bridge.d.ts +14 -0
- package/dist/ink/src/adapters/ink/components/screen/screen_bridge.d.ts.map +1 -0
- package/dist/ink/src/adapters/ink/components/screen/table_message.d.ts +6 -0
- package/dist/ink/src/adapters/ink/components/screen/table_message.d.ts.map +1 -0
- package/dist/ink/src/adapters/ink/components/screen_manager_bridge.d.ts +8 -0
- package/dist/ink/src/adapters/ink/components/screen_manager_bridge.d.ts.map +1 -0
- package/dist/ink/src/adapters/ink/components/sidebar/index.d.ts +4 -0
- package/dist/ink/src/adapters/ink/components/sidebar/index.d.ts.map +1 -0
- package/dist/ink/src/adapters/ink/components/sidebar/sidebar.d.ts +11 -0
- package/dist/ink/src/adapters/ink/components/sidebar/sidebar.d.ts.map +1 -0
- package/dist/ink/src/adapters/ink/components/sidebar/sidebar_item.d.ts +9 -0
- package/dist/ink/src/adapters/ink/components/sidebar/sidebar_item.d.ts.map +1 -0
- package/dist/ink/src/adapters/ink/components/sidebar/sidebar_separator.d.ts +2 -0
- package/dist/ink/src/adapters/ink/components/sidebar/sidebar_separator.d.ts.map +1 -0
- package/dist/ink/src/adapters/ink/context/index.d.ts +2 -0
- package/dist/ink/src/adapters/ink/context/index.d.ts.map +1 -0
- package/dist/ink/src/adapters/ink/context/logger_context.d.ts +33 -0
- package/dist/ink/src/adapters/ink/context/logger_context.d.ts.map +1 -0
- package/dist/ink/src/adapters/ink/hooks/index.d.ts +2 -0
- package/dist/ink/src/adapters/ink/hooks/index.d.ts.map +1 -0
- package/dist/ink/src/adapters/ink/hooks/use_theme.d.ts +7 -0
- package/dist/ink/src/adapters/ink/hooks/use_theme.d.ts.map +1 -0
- package/dist/ink/src/adapters/ink/index.d.ts +18 -0
- package/dist/ink/src/adapters/ink/index.d.ts.map +1 -0
- package/dist/ink/src/adapters/react-shared/hooks/index.d.ts +4 -0
- package/dist/ink/src/adapters/react-shared/hooks/index.d.ts.map +1 -0
- package/dist/ink/src/adapters/react-shared/hooks/use_filter_state.d.ts +18 -0
- package/dist/ink/src/adapters/react-shared/hooks/use_filter_state.d.ts.map +1 -0
- package/dist/ink/src/adapters/react-shared/hooks/use_keyboard_manager.d.ts +26 -0
- package/dist/ink/src/adapters/react-shared/hooks/use_keyboard_manager.d.ts.map +1 -0
- package/dist/ink/src/adapters/react-shared/hooks/use_manager_subscription.d.ts +7 -0
- package/dist/ink/src/adapters/react-shared/hooks/use_manager_subscription.d.ts.map +1 -0
- package/dist/ink/src/adapters/react-shared/index.d.ts +2 -0
- package/dist/ink/src/adapters/react-shared/index.d.ts.map +1 -0
- package/dist/ink/tsconfig.ink.tsbuildinfo +1 -0
- package/dist/react/src/adapters/react-shared/hooks/index.d.ts +4 -0
- package/dist/react/src/adapters/react-shared/hooks/index.d.ts.map +1 -0
- package/dist/react/src/adapters/react-shared/hooks/use_filter_state.d.ts +18 -0
- package/dist/react/src/adapters/react-shared/hooks/use_filter_state.d.ts.map +1 -0
- package/dist/react/src/adapters/react-shared/hooks/use_keyboard_manager.d.ts +26 -0
- package/dist/react/src/adapters/react-shared/hooks/use_keyboard_manager.d.ts.map +1 -0
- package/dist/react/src/adapters/react-shared/hooks/use_manager_subscription.d.ts +7 -0
- package/dist/react/src/adapters/react-shared/hooks/use_manager_subscription.d.ts.map +1 -0
- package/dist/react/src/adapters/react-shared/index.d.ts +2 -0
- package/dist/react/src/adapters/react-shared/index.d.ts.map +1 -0
- package/dist/react/tsconfig.react.tsbuildinfo +1 -1
- package/dist/solid/tsconfig.solid.tsbuildinfo +1 -1
- package/lib/index.cjs +2177 -178
- package/lib/index.cjs.map +1 -1
- package/lib/index.d.cts +942 -78
- package/lib/index.d.cts.map +1 -0
- package/lib/index.d.mts +902 -38
- package/lib/index.d.mts.map +1 -0
- package/lib/index.mjs +2098 -135
- package/lib/index.mjs.map +1 -1
- package/package.json +1 -31
- package/src/__tests__/services/logger.spec.ts +32 -0
- package/src/__tests__/services/screen.spec.ts +106 -95
- package/src/__tests__/utils/factories.ts +2 -0
- package/src/adapters/interface.ts +10 -2
- package/src/overrides/missing-adapter.override.ts +16 -6
- package/src/services/index.ts +1 -0
- package/src/services/logger.ts +7 -1
- package/src/services/readline_prompt.ts +194 -0
- package/src/services/screen.ts +106 -54
- package/src/services/screen_manager.ts +282 -74
- package/src/types/events.types.ts +84 -0
- package/src/types/index.ts +3 -0
- package/src/types/screen.types.ts +34 -0
- package/src/utils/colors/helpers.ts +0 -25
- package/src/utils/index.ts +6 -0
- package/src/utils/prompt.ts +18 -0
- package/src/utils/runtime.ts +14 -0
- package/src/utils/stdout-printer.ts +16 -5
- package/tsconfig.base.json +1 -17
- package/tsconfig.json +1 -6
- package/tsdown.config.mts +13 -70
- package/lib/adapters/react/index.cjs +0 -1768
- package/lib/adapters/react/index.cjs.map +0 -1
- package/lib/adapters/react/index.d.cts +0 -80
- package/lib/adapters/react/index.d.mts +0 -80
- package/lib/adapters/react/index.mjs +0 -1760
- package/lib/adapters/react/index.mjs.map +0 -1
- package/lib/adapters/solid/index.cjs +0 -3855
- package/lib/adapters/solid/index.cjs.map +0 -1
- package/lib/adapters/solid/index.d.cts +0 -74
- package/lib/adapters/solid/index.d.mts +0 -74
- package/lib/adapters/solid/index.mjs +0 -3847
- package/lib/adapters/solid/index.mjs.map +0 -1
- package/lib/filter_engine-DXqu9Vaq.cjs +0 -1836
- package/lib/filter_engine-DXqu9Vaq.cjs.map +0 -1
- package/lib/filter_engine-DmqhEhpA.mjs +0 -1609
- package/lib/filter_engine-DmqhEhpA.mjs.map +0 -1
- package/lib/interface-CTHQ08aY.d.mts +0 -699
- package/lib/interface-DQEIz9Mb.d.cts +0 -699
- package/src/__tests__/components/__snapshots__/filter_bar.spec.tsx.snap +0 -2293
- package/src/__tests__/components/__snapshots__/loading_message.spec.tsx.snap +0 -1414
- package/src/__tests__/components/__snapshots__/log_message.spec.tsx.snap +0 -3245
- package/src/__tests__/components/__snapshots__/progress_message.spec.tsx.snap +0 -1783
- package/src/__tests__/components/__snapshots__/prompt_renderer.spec.tsx.snap +0 -3203
- package/src/__tests__/components/__snapshots__/sidebar.spec.tsx.snap +0 -2857
- package/src/__tests__/components/filter_bar.spec.tsx +0 -190
- package/src/__tests__/components/loading_message.spec.tsx +0 -110
- package/src/__tests__/components/log_message.spec.tsx +0 -166
- package/src/__tests__/components/progress_message.spec.tsx +0 -147
- package/src/__tests__/components/prompt_renderer.spec.tsx +0 -274
- package/src/__tests__/components/sidebar.spec.tsx +0 -322
- package/src/__tests__/utils/render-utils.tsx +0 -39
- package/src/adapters/react/components/file/file_log.tsx +0 -241
- package/src/adapters/react/components/file/index.ts +0 -1
- package/src/adapters/react/components/filter/filter_bar.tsx +0 -79
- package/src/adapters/react/components/filter/index.ts +0 -1
- package/src/adapters/react/components/help/help_overlay.tsx +0 -100
- package/src/adapters/react/components/help/index.ts +0 -1
- package/src/adapters/react/components/log/index.ts +0 -1
- package/src/adapters/react/components/log/log_message.tsx +0 -102
- package/src/adapters/react/components/prompt/index.ts +0 -2
- package/src/adapters/react/components/prompt/prompt_renderer.tsx +0 -346
- package/src/adapters/react/components/screen/group_renderer.tsx +0 -64
- package/src/adapters/react/components/screen/index.ts +0 -6
- package/src/adapters/react/components/screen/loading_message.tsx +0 -43
- package/src/adapters/react/components/screen/message_renderer.tsx +0 -108
- package/src/adapters/react/components/screen/progress_message.tsx +0 -60
- package/src/adapters/react/components/screen/screen_bridge.tsx +0 -149
- package/src/adapters/react/components/screen/table_message.tsx +0 -57
- package/src/adapters/react/components/screen_manager_bridge.tsx +0 -245
- package/src/adapters/react/components/sidebar/index.ts +0 -3
- package/src/adapters/react/components/sidebar/sidebar.tsx +0 -102
- package/src/adapters/react/components/sidebar/sidebar_item.tsx +0 -50
- package/src/adapters/react/components/sidebar/sidebar_separator.tsx +0 -13
- package/src/adapters/react/context/index.ts +0 -1
- package/src/adapters/react/context/logger_context.tsx +0 -109
- package/src/adapters/react/hooks/index.ts +0 -1
- package/src/adapters/react/hooks/use_theme.ts +0 -12
- package/src/adapters/react/index.ts +0 -39
- package/src/adapters/solid/components/file/file_log.tsx +0 -221
- package/src/adapters/solid/components/file/index.ts +0 -1
- package/src/adapters/solid/components/filter/filter_bar.tsx +0 -84
- package/src/adapters/solid/components/filter/index.ts +0 -1
- package/src/adapters/solid/components/help/help_overlay.tsx +0 -106
- package/src/adapters/solid/components/help/index.ts +0 -1
- package/src/adapters/solid/components/log/index.ts +0 -1
- package/src/adapters/solid/components/log/log_message.tsx +0 -92
- package/src/adapters/solid/components/prompt/index.ts +0 -2
- package/src/adapters/solid/components/prompt/prompt_renderer.tsx +0 -350
- package/src/adapters/solid/components/screen/group_renderer.tsx +0 -61
- package/src/adapters/solid/components/screen/index.ts +0 -6
- package/src/adapters/solid/components/screen/loading_message.tsx +0 -39
- package/src/adapters/solid/components/screen/message_renderer.tsx +0 -122
- package/src/adapters/solid/components/screen/progress_message.tsx +0 -61
- package/src/adapters/solid/components/screen/screen_bridge.tsx +0 -155
- package/src/adapters/solid/components/screen/table_message.tsx +0 -58
- package/src/adapters/solid/components/screen_manager_bridge.tsx +0 -243
- package/src/adapters/solid/components/sidebar/index.ts +0 -3
- package/src/adapters/solid/components/sidebar/sidebar.tsx +0 -108
- package/src/adapters/solid/components/sidebar/sidebar_item.tsx +0 -55
- package/src/adapters/solid/components/sidebar/sidebar_separator.tsx +0 -13
- package/src/adapters/solid/context/index.ts +0 -2
- package/src/adapters/solid/context/logger_context.tsx +0 -95
- package/src/adapters/solid/hooks/index.ts +0 -1
- package/src/adapters/solid/hooks/use_theme.ts +0 -12
- package/src/adapters/solid/index.tsx +0 -43
- package/src/adapters/solid/jsx.d.ts +0 -98
- package/tsconfig.react.json +0 -16
- package/tsconfig.solid.json +0 -16
|
@@ -1,350 +0,0 @@
|
|
|
1
|
-
import { TextAttributes } from '@opentui/core'
|
|
2
|
-
import { Show, For, Switch, Match } from 'solid-js'
|
|
3
|
-
|
|
4
|
-
import { useTheme } from '../../hooks/index.ts'
|
|
5
|
-
|
|
6
|
-
import type {
|
|
7
|
-
PromptData,
|
|
8
|
-
ChoicePromptData,
|
|
9
|
-
ConfirmPromptData,
|
|
10
|
-
InputPromptData,
|
|
11
|
-
MultiChoicePromptData,
|
|
12
|
-
PromptTheme,
|
|
13
|
-
} from '../../../../types/index.ts'
|
|
14
|
-
|
|
15
|
-
export interface PromptRendererProps {
|
|
16
|
-
prompt: PromptData
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export function PromptRenderer(props: PromptRendererProps) {
|
|
20
|
-
const theme = useTheme()
|
|
21
|
-
// Calculate timeout remaining if applicable
|
|
22
|
-
const timeoutRemaining = () => getTimeoutRemaining(props.prompt)
|
|
23
|
-
|
|
24
|
-
return (
|
|
25
|
-
<Switch fallback={null}>
|
|
26
|
-
<Match when={props.prompt.type === 'choice'}>
|
|
27
|
-
<ChoicePromptRenderer
|
|
28
|
-
prompt={props.prompt as ChoicePromptData}
|
|
29
|
-
timeoutRemaining={timeoutRemaining()}
|
|
30
|
-
colors={theme.prompt}
|
|
31
|
-
/>
|
|
32
|
-
</Match>
|
|
33
|
-
<Match when={props.prompt.type === 'confirm'}>
|
|
34
|
-
<ConfirmPromptRenderer
|
|
35
|
-
prompt={props.prompt as ConfirmPromptData}
|
|
36
|
-
timeoutRemaining={timeoutRemaining()}
|
|
37
|
-
colors={theme.prompt}
|
|
38
|
-
/>
|
|
39
|
-
</Match>
|
|
40
|
-
<Match when={props.prompt.type === 'input'}>
|
|
41
|
-
<InputPromptRenderer
|
|
42
|
-
prompt={props.prompt as InputPromptData}
|
|
43
|
-
timeoutRemaining={timeoutRemaining()}
|
|
44
|
-
colors={theme.prompt}
|
|
45
|
-
/>
|
|
46
|
-
</Match>
|
|
47
|
-
<Match when={props.prompt.type === 'multiChoice'}>
|
|
48
|
-
<MultiChoicePromptRenderer
|
|
49
|
-
prompt={props.prompt as MultiChoicePromptData}
|
|
50
|
-
timeoutRemaining={timeoutRemaining()}
|
|
51
|
-
colors={theme.prompt}
|
|
52
|
-
/>
|
|
53
|
-
</Match>
|
|
54
|
-
</Switch>
|
|
55
|
-
)
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
function getTimeoutRemaining(prompt: PromptData): number | null {
|
|
59
|
-
if (!prompt.timeout || !prompt.timeoutStarted) return null
|
|
60
|
-
const elapsed = Date.now() - prompt.timeoutStarted
|
|
61
|
-
const remaining = Math.max(0, prompt.timeout - elapsed)
|
|
62
|
-
return Math.ceil(remaining / 1000)
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
function TimeoutIndicator(props: { seconds: number | null; colors: PromptTheme }) {
|
|
66
|
-
return (
|
|
67
|
-
<Show when={props.seconds !== null}>
|
|
68
|
-
<text fg={props.colors.optionTextDim} attributes={TextAttributes.DIM}>
|
|
69
|
-
{' '}
|
|
70
|
-
(auto-select in {props.seconds}s)
|
|
71
|
-
</text>
|
|
72
|
-
</Show>
|
|
73
|
-
)
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
interface ChoicePromptRendererProps {
|
|
77
|
-
prompt: ChoicePromptData
|
|
78
|
-
timeoutRemaining: number | null
|
|
79
|
-
colors: PromptTheme
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
function ChoicePromptRenderer(props: ChoicePromptRendererProps) {
|
|
83
|
-
return (
|
|
84
|
-
<box
|
|
85
|
-
flexDirection="column"
|
|
86
|
-
borderColor={props.colors.focusBorder}
|
|
87
|
-
border={['left']}
|
|
88
|
-
paddingLeft={1}
|
|
89
|
-
paddingRight={1}
|
|
90
|
-
gap={1}
|
|
91
|
-
>
|
|
92
|
-
{/* Question */}
|
|
93
|
-
<box flexDirection="row">
|
|
94
|
-
<text fg={props.colors.question} attributes={TextAttributes.BOLD}>
|
|
95
|
-
? {props.prompt.question}
|
|
96
|
-
</text>
|
|
97
|
-
<TimeoutIndicator seconds={props.timeoutRemaining} colors={props.colors} />
|
|
98
|
-
</box>
|
|
99
|
-
|
|
100
|
-
{/* Choices */}
|
|
101
|
-
<box flexDirection="column">
|
|
102
|
-
<For each={props.prompt.choices}>
|
|
103
|
-
{(choice, index) => {
|
|
104
|
-
const isSelected = () => index() === props.prompt.selectedIndex
|
|
105
|
-
const showInput = () => isSelected() && choice.input && props.prompt.inputMode
|
|
106
|
-
|
|
107
|
-
return (
|
|
108
|
-
<box flexDirection="row">
|
|
109
|
-
{/* Selection indicator */}
|
|
110
|
-
<text fg={isSelected() ? props.colors.optionSelected : 'transparent'}>{'>'} </text>
|
|
111
|
-
|
|
112
|
-
{/* Choice label */}
|
|
113
|
-
<text
|
|
114
|
-
fg={isSelected() ? props.colors.optionText : props.colors.optionTextDim}
|
|
115
|
-
attributes={isSelected() ? TextAttributes.BOLD : undefined}
|
|
116
|
-
>
|
|
117
|
-
{choice.label}
|
|
118
|
-
</text>
|
|
119
|
-
|
|
120
|
-
{/* Input field (if applicable) */}
|
|
121
|
-
<Show when={showInput()}>
|
|
122
|
-
<box flexDirection="row" marginLeft={1}>
|
|
123
|
-
<text fg={props.colors.inputText}>: </text>
|
|
124
|
-
<text fg={props.colors.inputText}>{props.prompt.inputValue}</text>
|
|
125
|
-
<text fg={props.colors.inputCursor} attributes={TextAttributes.BLINK}>
|
|
126
|
-
_
|
|
127
|
-
</text>
|
|
128
|
-
</box>
|
|
129
|
-
</Show>
|
|
130
|
-
|
|
131
|
-
{/* Show hint for input option when selected but not in input mode */}
|
|
132
|
-
<Show when={isSelected() && choice.input && !props.prompt.inputMode}>
|
|
133
|
-
<text fg={props.colors.optionTextDim}> (press Enter to type)</text>
|
|
134
|
-
</Show>
|
|
135
|
-
</box>
|
|
136
|
-
)
|
|
137
|
-
}}
|
|
138
|
-
</For>
|
|
139
|
-
</box>
|
|
140
|
-
|
|
141
|
-
{/* Instructions */}
|
|
142
|
-
<Show
|
|
143
|
-
when={props.prompt.inputMode}
|
|
144
|
-
fallback={
|
|
145
|
-
<text fg={props.colors.optionTextDim} attributes={TextAttributes.DIM}>
|
|
146
|
-
↑/↓ to navigate, Enter to select
|
|
147
|
-
</text>
|
|
148
|
-
}
|
|
149
|
-
>
|
|
150
|
-
<text fg={props.colors.optionTextDim} attributes={TextAttributes.DIM}>
|
|
151
|
-
Type your answer, Enter to submit, Esc to cancel
|
|
152
|
-
</text>
|
|
153
|
-
</Show>
|
|
154
|
-
</box>
|
|
155
|
-
)
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
interface ConfirmPromptRendererProps {
|
|
159
|
-
prompt: ConfirmPromptData
|
|
160
|
-
timeoutRemaining: number | null
|
|
161
|
-
colors: PromptTheme
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
function ConfirmPromptRenderer(props: ConfirmPromptRendererProps) {
|
|
165
|
-
const confirmSelected = () => props.prompt.selectedValue === true
|
|
166
|
-
const cancelSelected = () => props.prompt.selectedValue === false
|
|
167
|
-
|
|
168
|
-
return (
|
|
169
|
-
<box
|
|
170
|
-
flexDirection="column"
|
|
171
|
-
borderColor={props.colors.focusBorder}
|
|
172
|
-
border={['left']}
|
|
173
|
-
paddingLeft={1}
|
|
174
|
-
paddingRight={1}
|
|
175
|
-
gap={1}
|
|
176
|
-
>
|
|
177
|
-
{/* Question */}
|
|
178
|
-
<box flexDirection="row">
|
|
179
|
-
<text fg={props.colors.question} attributes={TextAttributes.BOLD}>
|
|
180
|
-
? {props.prompt.question}
|
|
181
|
-
</text>
|
|
182
|
-
<TimeoutIndicator seconds={props.timeoutRemaining} colors={props.colors} />
|
|
183
|
-
</box>
|
|
184
|
-
|
|
185
|
-
{/* Buttons */}
|
|
186
|
-
<box flexDirection="row" gap={2}>
|
|
187
|
-
{/* Confirm button */}
|
|
188
|
-
<box
|
|
189
|
-
backgroundColor={confirmSelected() ? props.colors.buttonSelectedBackground : undefined}
|
|
190
|
-
paddingLeft={1}
|
|
191
|
-
paddingRight={1}
|
|
192
|
-
>
|
|
193
|
-
<text
|
|
194
|
-
fg={confirmSelected() ? props.colors.confirmButton : props.colors.optionTextDim}
|
|
195
|
-
attributes={confirmSelected() ? TextAttributes.BOLD : undefined}
|
|
196
|
-
>
|
|
197
|
-
{confirmSelected() ? '>' : ' '} {props.prompt.confirmText}
|
|
198
|
-
</text>
|
|
199
|
-
</box>
|
|
200
|
-
|
|
201
|
-
{/* Cancel button */}
|
|
202
|
-
<box
|
|
203
|
-
backgroundColor={cancelSelected() ? props.colors.buttonSelectedBackground : undefined}
|
|
204
|
-
paddingLeft={1}
|
|
205
|
-
paddingRight={1}
|
|
206
|
-
>
|
|
207
|
-
<text
|
|
208
|
-
fg={cancelSelected() ? props.colors.cancelButton : props.colors.optionTextDim}
|
|
209
|
-
attributes={cancelSelected() ? TextAttributes.BOLD : undefined}
|
|
210
|
-
>
|
|
211
|
-
{cancelSelected() ? '>' : ' '} {props.prompt.cancelText}
|
|
212
|
-
</text>
|
|
213
|
-
</box>
|
|
214
|
-
</box>
|
|
215
|
-
|
|
216
|
-
{/* Instructions */}
|
|
217
|
-
<text fg={props.colors.optionTextDim} attributes={TextAttributes.DIM}>
|
|
218
|
-
←/→ to select, Enter to confirm
|
|
219
|
-
</text>
|
|
220
|
-
</box>
|
|
221
|
-
)
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
interface InputPromptRendererProps {
|
|
225
|
-
prompt: InputPromptData
|
|
226
|
-
timeoutRemaining: number | null
|
|
227
|
-
colors: PromptTheme
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
function InputPromptRenderer(props: InputPromptRendererProps) {
|
|
231
|
-
const hasValue = () => props.prompt.value.length > 0
|
|
232
|
-
|
|
233
|
-
return (
|
|
234
|
-
<box
|
|
235
|
-
flexDirection="column"
|
|
236
|
-
borderColor={props.colors.focusBorder}
|
|
237
|
-
border={['left']}
|
|
238
|
-
paddingLeft={1}
|
|
239
|
-
paddingRight={1}
|
|
240
|
-
gap={1}
|
|
241
|
-
>
|
|
242
|
-
{/* Question */}
|
|
243
|
-
<box flexDirection="row">
|
|
244
|
-
<text fg={props.colors.question} attributes={TextAttributes.BOLD}>
|
|
245
|
-
? {props.prompt.question}
|
|
246
|
-
</text>
|
|
247
|
-
<TimeoutIndicator seconds={props.timeoutRemaining} colors={props.colors} />
|
|
248
|
-
</box>
|
|
249
|
-
|
|
250
|
-
{/* Input field */}
|
|
251
|
-
<box flexDirection="row" borderColor={props.colors.inputBorder} border={['left']} paddingLeft={1}>
|
|
252
|
-
<text fg={hasValue() ? props.colors.inputText : props.colors.inputPlaceholder}>
|
|
253
|
-
{hasValue() ? props.prompt.value : props.prompt.placeholder}
|
|
254
|
-
</text>
|
|
255
|
-
<text fg={props.colors.inputCursor} attributes={TextAttributes.BLINK}>
|
|
256
|
-
_
|
|
257
|
-
</text>
|
|
258
|
-
</box>
|
|
259
|
-
|
|
260
|
-
{/* Instructions */}
|
|
261
|
-
<text fg={props.colors.optionTextDim} attributes={TextAttributes.DIM}>
|
|
262
|
-
Type your answer, Enter to submit
|
|
263
|
-
</text>
|
|
264
|
-
</box>
|
|
265
|
-
)
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
interface MultiChoicePromptRendererProps {
|
|
269
|
-
prompt: MultiChoicePromptData
|
|
270
|
-
timeoutRemaining: number | null
|
|
271
|
-
colors: PromptTheme
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
function MultiChoicePromptRenderer(props: MultiChoicePromptRendererProps) {
|
|
275
|
-
const selectedCount = () => props.prompt.selectedIndices.size
|
|
276
|
-
const canSubmit = () => selectedCount() >= props.prompt.minSelect
|
|
277
|
-
|
|
278
|
-
return (
|
|
279
|
-
<box
|
|
280
|
-
flexDirection="column"
|
|
281
|
-
borderColor={props.colors.focusBorder}
|
|
282
|
-
border={['left']}
|
|
283
|
-
paddingLeft={1}
|
|
284
|
-
paddingRight={1}
|
|
285
|
-
gap={1}
|
|
286
|
-
>
|
|
287
|
-
{/* Question */}
|
|
288
|
-
<box flexDirection="row">
|
|
289
|
-
<text fg={props.colors.question} attributes={TextAttributes.BOLD}>
|
|
290
|
-
? {props.prompt.question}
|
|
291
|
-
</text>
|
|
292
|
-
<text fg={props.colors.optionTextDim}>
|
|
293
|
-
{' '}
|
|
294
|
-
({selectedCount()}/{props.prompt.maxSelect} selected)
|
|
295
|
-
</text>
|
|
296
|
-
<TimeoutIndicator seconds={props.timeoutRemaining} colors={props.colors} />
|
|
297
|
-
</box>
|
|
298
|
-
|
|
299
|
-
{/* Choices */}
|
|
300
|
-
<box flexDirection="column">
|
|
301
|
-
<For each={props.prompt.choices}>
|
|
302
|
-
{(choice, index) => {
|
|
303
|
-
const isFocused = () => index() === props.prompt.focusedIndex
|
|
304
|
-
const isChecked = () => props.prompt.selectedIndices.has(index())
|
|
305
|
-
|
|
306
|
-
return (
|
|
307
|
-
<box flexDirection="row">
|
|
308
|
-
{/* Focus indicator */}
|
|
309
|
-
<text fg={isFocused() ? props.colors.optionSelected : 'transparent'}>{'>'} </text>
|
|
310
|
-
|
|
311
|
-
{/* Checkbox */}
|
|
312
|
-
<text fg={isChecked() ? props.colors.optionSelected : props.colors.optionTextDim}>
|
|
313
|
-
{isChecked() ? '[✓]' : '[ ]'}{' '}
|
|
314
|
-
</text>
|
|
315
|
-
|
|
316
|
-
{/* Choice label */}
|
|
317
|
-
<text
|
|
318
|
-
fg={isFocused() ? props.colors.optionText : props.colors.optionTextDim}
|
|
319
|
-
attributes={isFocused() ? TextAttributes.BOLD : undefined}
|
|
320
|
-
>
|
|
321
|
-
{choice.label}
|
|
322
|
-
</text>
|
|
323
|
-
</box>
|
|
324
|
-
)
|
|
325
|
-
}}
|
|
326
|
-
</For>
|
|
327
|
-
</box>
|
|
328
|
-
|
|
329
|
-
{/* Instructions */}
|
|
330
|
-
<box flexDirection="column">
|
|
331
|
-
<text fg={props.colors.optionTextDim} attributes={TextAttributes.DIM}>
|
|
332
|
-
↑/↓ to navigate, Space to toggle
|
|
333
|
-
</text>
|
|
334
|
-
<Show
|
|
335
|
-
when={canSubmit()}
|
|
336
|
-
fallback={
|
|
337
|
-
<text fg={props.colors.cancelButton} attributes={TextAttributes.DIM}>
|
|
338
|
-
Select at least {props.prompt.minSelect} option
|
|
339
|
-
{props.prompt.minSelect > 1 ? 's' : ''}
|
|
340
|
-
</text>
|
|
341
|
-
}
|
|
342
|
-
>
|
|
343
|
-
<text fg={props.colors.optionTextDim} attributes={TextAttributes.DIM}>
|
|
344
|
-
Enter to confirm
|
|
345
|
-
</text>
|
|
346
|
-
</Show>
|
|
347
|
-
</box>
|
|
348
|
-
</box>
|
|
349
|
-
)
|
|
350
|
-
}
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
import { TextAttributes } from '@opentui/core'
|
|
2
|
-
import { For, Show } from 'solid-js'
|
|
3
|
-
|
|
4
|
-
import { useTheme } from '../../hooks/index.ts'
|
|
5
|
-
|
|
6
|
-
import type { MessageData, GroupMessageData } from '../../../../types/index.ts'
|
|
7
|
-
|
|
8
|
-
import { MessageRenderer } from './message_renderer.tsx'
|
|
9
|
-
|
|
10
|
-
export interface GroupRendererProps {
|
|
11
|
-
label: string
|
|
12
|
-
messages: MessageData[]
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export function GroupRenderer(props: GroupRendererProps) {
|
|
16
|
-
const theme = useTheme()
|
|
17
|
-
|
|
18
|
-
return (
|
|
19
|
-
<box
|
|
20
|
-
flexDirection="column"
|
|
21
|
-
border={['left']}
|
|
22
|
-
borderColor={theme.group.border}
|
|
23
|
-
backgroundColor={theme.group.background}
|
|
24
|
-
paddingLeft={1}
|
|
25
|
-
>
|
|
26
|
-
{/* Group header */}
|
|
27
|
-
<box flexDirection="row" marginBottom={1}>
|
|
28
|
-
<text fg={theme.group.icon}>▼ </text>
|
|
29
|
-
<text fg={theme.group.headerText} attributes={TextAttributes.BOLD}>
|
|
30
|
-
{props.label}
|
|
31
|
-
</text>
|
|
32
|
-
</box>
|
|
33
|
-
|
|
34
|
-
{/* Group content */}
|
|
35
|
-
<box flexDirection="column" gap={1}>
|
|
36
|
-
<For each={props.messages}>{(msg) => <MessageRenderer message={msg} />}</For>
|
|
37
|
-
</box>
|
|
38
|
-
</box>
|
|
39
|
-
)
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
export interface GroupMessageRendererProps {
|
|
43
|
-
message: GroupMessageData
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Fallback renderer for group markers (when not processed at higher level)
|
|
48
|
-
*/
|
|
49
|
-
export function GroupMessageRenderer(props: GroupMessageRendererProps) {
|
|
50
|
-
const theme = useTheme()
|
|
51
|
-
|
|
52
|
-
return (
|
|
53
|
-
<Show when={!props.message.isEnd}>
|
|
54
|
-
<box flexDirection="row" borderColor={theme.group.border} border={['left']} paddingLeft={1}>
|
|
55
|
-
<text fg={theme.group.headerText} attributes={TextAttributes.BOLD}>
|
|
56
|
-
▼ {props.message.label}
|
|
57
|
-
</text>
|
|
58
|
-
</box>
|
|
59
|
-
</Show>
|
|
60
|
-
)
|
|
61
|
-
}
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import { createSignal, createEffect, onCleanup } from 'solid-js'
|
|
2
|
-
|
|
3
|
-
import { LogMessage } from '../log/index.ts'
|
|
4
|
-
|
|
5
|
-
import type { LoadingMessageData, LogMessageVariant } from '../../../../types/index.ts'
|
|
6
|
-
|
|
7
|
-
const SPINNER_FRAMES = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏']
|
|
8
|
-
|
|
9
|
-
export interface LoadingMessageProps {
|
|
10
|
-
message: LoadingMessageData
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export function LoadingMessage(props: LoadingMessageProps) {
|
|
14
|
-
const [frameIndex, setFrameIndex] = createSignal(0)
|
|
15
|
-
|
|
16
|
-
createEffect(() => {
|
|
17
|
-
if (props.message.status === 'loading') {
|
|
18
|
-
const interval = setInterval(() => {
|
|
19
|
-
setFrameIndex((prev) => (prev + 1) % SPINNER_FRAMES.length)
|
|
20
|
-
}, 80)
|
|
21
|
-
|
|
22
|
-
onCleanup(() => clearInterval(interval))
|
|
23
|
-
}
|
|
24
|
-
})
|
|
25
|
-
|
|
26
|
-
// Map loading status to log level and variant for display
|
|
27
|
-
const level = () => (props.message.status === 'fail' ? 'error' : 'log')
|
|
28
|
-
const variant = (): LogMessageVariant | undefined =>
|
|
29
|
-
props.message.status === 'success' ? 'success' : undefined
|
|
30
|
-
|
|
31
|
-
const displayContent = () => props.message.resolvedContent ?? props.message.content
|
|
32
|
-
const spinner = () => (props.message.status === 'loading' ? SPINNER_FRAMES[frameIndex()] + ' ' : '')
|
|
33
|
-
|
|
34
|
-
return (
|
|
35
|
-
<LogMessage level={level()} variant={variant()} timestamp={props.message.timestamp}>
|
|
36
|
-
{spinner() + displayContent()}
|
|
37
|
-
</LogMessage>
|
|
38
|
-
)
|
|
39
|
-
}
|
|
@@ -1,122 +0,0 @@
|
|
|
1
|
-
import { Switch, Match } from 'solid-js'
|
|
2
|
-
|
|
3
|
-
import { useTheme } from '../../hooks/index.ts'
|
|
4
|
-
import { FileLog } from '../file/index.ts'
|
|
5
|
-
import { LogMessage } from '../log/index.ts'
|
|
6
|
-
|
|
7
|
-
import type {
|
|
8
|
-
MessageData,
|
|
9
|
-
LogMessageData,
|
|
10
|
-
FileMessageData,
|
|
11
|
-
DiffMessageData,
|
|
12
|
-
FileErrorMessageData,
|
|
13
|
-
LoadingMessageData,
|
|
14
|
-
ProgressMessageData,
|
|
15
|
-
GroupMessageData,
|
|
16
|
-
TableMessageData,
|
|
17
|
-
} from '../../../../types/index.ts'
|
|
18
|
-
|
|
19
|
-
import { GroupMessageRenderer } from './group_renderer.tsx'
|
|
20
|
-
import { LoadingMessage } from './loading_message.tsx'
|
|
21
|
-
import { ProgressMessage } from './progress_message.tsx'
|
|
22
|
-
import { TableMessage } from './table_message.tsx'
|
|
23
|
-
|
|
24
|
-
export interface MessageRendererProps {
|
|
25
|
-
message: MessageData
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export function MessageRenderer(props: MessageRendererProps) {
|
|
29
|
-
const theme = useTheme()
|
|
30
|
-
const msg = () => props.message
|
|
31
|
-
|
|
32
|
-
return (
|
|
33
|
-
<Switch fallback={null}>
|
|
34
|
-
<Match when={msg().type === 'log' && (msg() as LogMessageData)}>
|
|
35
|
-
{(logMsg) => (
|
|
36
|
-
<LogMessage
|
|
37
|
-
level={logMsg().level}
|
|
38
|
-
timestamp={logMsg().timestamp}
|
|
39
|
-
variant={logMsg().variant}
|
|
40
|
-
label={logMsg().label}
|
|
41
|
-
trace={logMsg().trace}
|
|
42
|
-
>
|
|
43
|
-
{logMsg().content}
|
|
44
|
-
</LogMessage>
|
|
45
|
-
)}
|
|
46
|
-
</Match>
|
|
47
|
-
|
|
48
|
-
<Match when={msg().type === 'file' && (msg() as FileMessageData)}>
|
|
49
|
-
{(fileMsg) => (
|
|
50
|
-
<box
|
|
51
|
-
flexDirection="column"
|
|
52
|
-
border={['left']}
|
|
53
|
-
borderColor={theme.file.border}
|
|
54
|
-
backgroundColor={theme.file.background}
|
|
55
|
-
>
|
|
56
|
-
<FileLog
|
|
57
|
-
mode="full"
|
|
58
|
-
filePath={fileMsg().filePath}
|
|
59
|
-
content={fileMsg().content}
|
|
60
|
-
headerBackgroundColor={theme.file.headerBackground}
|
|
61
|
-
/>
|
|
62
|
-
</box>
|
|
63
|
-
)}
|
|
64
|
-
</Match>
|
|
65
|
-
|
|
66
|
-
<Match when={msg().type === 'diff' && (msg() as DiffMessageData)}>
|
|
67
|
-
{(diffMsg) => (
|
|
68
|
-
<box
|
|
69
|
-
flexDirection="column"
|
|
70
|
-
border={['left']}
|
|
71
|
-
borderColor={theme.file.border}
|
|
72
|
-
backgroundColor={theme.file.background}
|
|
73
|
-
>
|
|
74
|
-
<FileLog
|
|
75
|
-
mode="diff"
|
|
76
|
-
filePath={diffMsg().filePath}
|
|
77
|
-
diff={diffMsg().diff}
|
|
78
|
-
view={diffMsg().view}
|
|
79
|
-
headerBackgroundColor={theme.file.headerBackground}
|
|
80
|
-
/>
|
|
81
|
-
</box>
|
|
82
|
-
)}
|
|
83
|
-
</Match>
|
|
84
|
-
|
|
85
|
-
<Match when={msg().type === 'fileError' && (msg() as FileErrorMessageData)}>
|
|
86
|
-
{(errorMsg) => (
|
|
87
|
-
<box
|
|
88
|
-
flexDirection="column"
|
|
89
|
-
border={['left']}
|
|
90
|
-
borderColor={theme.file.border}
|
|
91
|
-
backgroundColor={theme.file.background}
|
|
92
|
-
>
|
|
93
|
-
<FileLog
|
|
94
|
-
mode="partial"
|
|
95
|
-
filePath={errorMsg().filePath}
|
|
96
|
-
content={errorMsg().content}
|
|
97
|
-
startLine={errorMsg().startLine}
|
|
98
|
-
errorLines={errorMsg().errorLines}
|
|
99
|
-
headerBackgroundColor={theme.file.headerBackground}
|
|
100
|
-
/>
|
|
101
|
-
</box>
|
|
102
|
-
)}
|
|
103
|
-
</Match>
|
|
104
|
-
|
|
105
|
-
<Match when={msg().type === 'loading' && (msg() as LoadingMessageData)}>
|
|
106
|
-
{(loadingMsg) => <LoadingMessage message={loadingMsg()} />}
|
|
107
|
-
</Match>
|
|
108
|
-
|
|
109
|
-
<Match when={msg().type === 'progress' && (msg() as ProgressMessageData)}>
|
|
110
|
-
{(progressMsg) => <ProgressMessage message={progressMsg()} />}
|
|
111
|
-
</Match>
|
|
112
|
-
|
|
113
|
-
<Match when={msg().type === 'group' && (msg() as GroupMessageData)}>
|
|
114
|
-
{(groupMsg) => <GroupMessageRenderer message={groupMsg()} />}
|
|
115
|
-
</Match>
|
|
116
|
-
|
|
117
|
-
<Match when={msg().type === 'table' && (msg() as TableMessageData)}>
|
|
118
|
-
{(tableMsg) => <TableMessage message={tableMsg()} />}
|
|
119
|
-
</Match>
|
|
120
|
-
</Switch>
|
|
121
|
-
)
|
|
122
|
-
}
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
import { useTheme } from '../../hooks/index.ts'
|
|
2
|
-
|
|
3
|
-
import type { ProgressMessageData } from '../../../../types/index.ts'
|
|
4
|
-
|
|
5
|
-
export interface ProgressMessageProps {
|
|
6
|
-
message: ProgressMessageData
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export function ProgressMessage(props: ProgressMessageProps) {
|
|
10
|
-
const theme = useTheme()
|
|
11
|
-
|
|
12
|
-
const percent = () => Math.round((props.message.current / props.message.total) * 100)
|
|
13
|
-
const barWidth = 20
|
|
14
|
-
const filled = () => Math.round((percent() / 100) * barWidth)
|
|
15
|
-
const empty = () => barWidth - filled()
|
|
16
|
-
|
|
17
|
-
const barFilled = () => '█'.repeat(filled())
|
|
18
|
-
const barEmpty = () => '░'.repeat(empty())
|
|
19
|
-
|
|
20
|
-
// Determine colors based on status
|
|
21
|
-
const borderColor = () =>
|
|
22
|
-
props.message.status === 'complete'
|
|
23
|
-
? theme.progress.complete
|
|
24
|
-
: props.message.status === 'failed'
|
|
25
|
-
? theme.progress.failed
|
|
26
|
-
: theme.progress.border
|
|
27
|
-
|
|
28
|
-
const backgroundColor = () =>
|
|
29
|
-
props.message.status === 'complete'
|
|
30
|
-
? theme.progress.completeBackground
|
|
31
|
-
: props.message.status === 'failed'
|
|
32
|
-
? theme.progress.failedBackground
|
|
33
|
-
: theme.progress.background
|
|
34
|
-
|
|
35
|
-
const barColor = () =>
|
|
36
|
-
props.message.status === 'complete'
|
|
37
|
-
? theme.progress.complete
|
|
38
|
-
: props.message.status === 'failed'
|
|
39
|
-
? theme.progress.failed
|
|
40
|
-
: theme.progress.barFilled
|
|
41
|
-
|
|
42
|
-
const displayLabel = () => props.message.resolvedContent ?? props.message.label
|
|
43
|
-
|
|
44
|
-
return (
|
|
45
|
-
<box
|
|
46
|
-
flexDirection="column"
|
|
47
|
-
border={['left']}
|
|
48
|
-
borderColor={borderColor()}
|
|
49
|
-
backgroundColor={backgroundColor()}
|
|
50
|
-
paddingLeft={1}
|
|
51
|
-
paddingRight={1}
|
|
52
|
-
>
|
|
53
|
-
<box flexDirection="row" gap={1}>
|
|
54
|
-
<text fg={barColor()}>[{barFilled()}</text>
|
|
55
|
-
<text fg={theme.progress.barEmpty}>{barEmpty()}]</text>
|
|
56
|
-
<text fg={theme.progress.textDim}>{percent()}%</text>
|
|
57
|
-
<text fg={theme.progress.text}>{displayLabel()}</text>
|
|
58
|
-
</box>
|
|
59
|
-
</box>
|
|
60
|
-
)
|
|
61
|
-
}
|