Big changes and fixes. Uses action history. Improve role selection. Remove unused logs
This commit is contained in:
120
src/tui/screens/action-wizard/steps/RoleSelectStep.tsx
Normal file
120
src/tui/screens/action-wizard/steps/RoleSelectStep.tsx
Normal file
@@ -0,0 +1,120 @@
|
||||
/**
|
||||
* Role Selection Step - Allows the user to choose which role they want
|
||||
* to take for the selected action.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { Box, Text } from 'ink';
|
||||
import { colors } from '../../../theme.js';
|
||||
import type { XOTemplate } from '@xo-cash/types';
|
||||
import type { FocusArea } from '../types.js';
|
||||
|
||||
interface RoleSelectStepProps {
|
||||
/** The loaded template definition. */
|
||||
template: XOTemplate;
|
||||
/** The selected action identifier. */
|
||||
actionIdentifier: string;
|
||||
/** Role identifiers available for this action. */
|
||||
availableRoles: string[];
|
||||
/** The currently focused role index. */
|
||||
selectedRoleIndex: number;
|
||||
/** Whether the content area or button bar is focused. */
|
||||
focusArea: FocusArea;
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays the available roles for the selected action and
|
||||
* lets the user navigate between them with arrow keys.
|
||||
*/
|
||||
export function RoleSelectStep({
|
||||
template,
|
||||
actionIdentifier,
|
||||
availableRoles,
|
||||
selectedRoleIndex,
|
||||
focusArea,
|
||||
}: RoleSelectStepProps): React.ReactElement {
|
||||
const action = template.actions?.[actionIdentifier];
|
||||
|
||||
return (
|
||||
<Box flexDirection="column">
|
||||
<Text color={colors.text} bold>
|
||||
Select your role for this action:
|
||||
</Text>
|
||||
|
||||
{/* Action info */}
|
||||
{action && (
|
||||
<Box marginTop={1} flexDirection="column">
|
||||
<Text color={colors.textMuted}>
|
||||
{action.description || 'No description available'}
|
||||
</Text>
|
||||
</Box>
|
||||
)}
|
||||
|
||||
{/* Role list */}
|
||||
<Box
|
||||
marginTop={1}
|
||||
flexDirection="column"
|
||||
borderStyle="single"
|
||||
borderColor={colors.border}
|
||||
paddingX={1}
|
||||
>
|
||||
{availableRoles.length === 0 ? (
|
||||
<Text color={colors.textMuted}>No roles available</Text>
|
||||
) : (
|
||||
availableRoles.map((roleId, index) => {
|
||||
const isCursor =
|
||||
selectedRoleIndex === index && focusArea === 'content';
|
||||
const roleDef = template.roles?.[roleId];
|
||||
const actionRole = action?.roles?.[roleId];
|
||||
const requirements = actionRole?.requirements;
|
||||
|
||||
return (
|
||||
<Box key={roleId} flexDirection="column" marginY={0}>
|
||||
<Text
|
||||
color={isCursor ? colors.focus : colors.text}
|
||||
bold={isCursor}
|
||||
>
|
||||
{isCursor ? '▸ ' : ' '}
|
||||
{roleDef?.name || roleId}
|
||||
</Text>
|
||||
|
||||
{/* Show role description indented below the name */}
|
||||
{roleDef?.description && (
|
||||
<Text color={colors.textMuted}>
|
||||
{' '}
|
||||
{roleDef.description}
|
||||
</Text>
|
||||
)}
|
||||
|
||||
{/* Show a brief summary of requirements */}
|
||||
{requirements && (
|
||||
<Box flexDirection="row" paddingLeft={4}>
|
||||
{requirements.variables && requirements.variables.length > 0 && (
|
||||
<Text color={colors.textMuted} dimColor>
|
||||
{requirements.variables.length} variable
|
||||
{requirements.variables.length !== 1 ? 's' : ''}
|
||||
{' '}
|
||||
</Text>
|
||||
)}
|
||||
{requirements.slots && requirements.slots.min > 0 && (
|
||||
<Text color={colors.textMuted} dimColor>
|
||||
{requirements.slots.min} input slot
|
||||
{requirements.slots.min !== 1 ? 's' : ''}
|
||||
</Text>
|
||||
)}
|
||||
</Box>
|
||||
)}
|
||||
</Box>
|
||||
);
|
||||
})
|
||||
)}
|
||||
</Box>
|
||||
|
||||
<Box marginTop={1}>
|
||||
<Text color={colors.textMuted} dimColor>
|
||||
↑↓: Navigate • Next: Confirm selection
|
||||
</Text>
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user