Allow json in workflow run's error field (#12762)

We can now inspect errors even if they contain complex data as objects.
Only the first line of the error is put in red.



![CleanShot 2025-06-20 at 18 31
54@2x](https://github.com/user-attachments/assets/a3fd41fb-0063-4fe1-8185-54137c2a0d6e)


![image](https://github.com/user-attachments/assets/833a2851-e7d5-4985-9e42-07a1899cd3de)
This commit is contained in:
Baptiste Devessier
2025-06-20 19:07:24 +02:00
committed by GitHub
parent 1e0ee9421d
commit 22e126869c
6 changed files with 55 additions and 19 deletions

View File

@ -571,6 +571,9 @@ export const RedHighlighting: Story = {
value: {
name: 'John Doe',
age: 30,
address: {
city: 'Paris',
},
},
getNodeHighlighting: () => 'red',
},

View File

@ -25,8 +25,9 @@ const StyledLabelContainer = styled.div`
gap: ${({ theme }) => theme.spacing(2)};
`;
const StyledElementsCount = styled.span`
color: ${({ theme }) => theme.font.color.tertiary};
const StyledElementsCount = styled.span<{ variant?: 'red' }>`
color: ${({ theme, variant }) =>
variant === 'red' ? theme.font.color.danger : theme.font.color.tertiary};
`;
const StyledJsonList = styled(JsonList)``.withComponent(motion.ul);
@ -118,13 +119,25 @@ export const JsonNestedNode = ({
<JsonArrow
isOpen={isOpen}
onClick={handleArrowClick}
variant={highlighting === 'partial-blue' ? 'blue' : undefined}
variant={
highlighting === 'partial-blue'
? 'blue'
: highlighting === 'red'
? highlighting
: undefined
}
/>
<JsonNodeLabel label={label} Icon={Icon} />
<JsonNodeLabel
label={label}
Icon={Icon}
highlighting={highlighting === 'red' ? highlighting : undefined}
/>
{renderElementsCount && (
<StyledElementsCount>
<StyledElementsCount
variant={highlighting === 'red' ? 'red' : undefined}
>
{renderElementsCount(elements.length)}
</StyledElementsCount>
)}

View File

@ -6,16 +6,20 @@ import { useJsonTreeContextOrThrow } from '@ui/json-visualizer/hooks/useJsonTree
import { ANIMATION } from '@ui/theme';
import { motion } from 'framer-motion';
const StyledButton = styled(motion.button)`
const StyledButton = styled(motion.button)<{ variant?: 'blue' | 'red' }>`
align-items: center;
border-color: ${({ theme }) => theme.border.color.medium};
background-color: ${({ theme, variant }) =>
variant === 'red'
? theme.background.danger
: theme.background.transparent.lighter};
border-color: ${({ theme, variant }) =>
variant === 'red' ? theme.border.color.danger : theme.border.color.medium};
border-radius: ${({ theme }) => theme.border.radius.sm};
border-style: solid;
border-width: 1px;
display: flex;
justify-content: center;
padding-inline: ${({ theme }) => theme.spacing(1)};
background-color: ${({ theme }) => theme.background.transparent.lighter};
height: 24px;
width: 24px;
box-sizing: border-box;
@ -31,7 +35,7 @@ export const JsonArrow = ({
}: {
isOpen: boolean;
onClick: () => void;
variant?: 'blue';
variant?: 'blue' | 'red';
}) => {
const theme = useTheme();
@ -39,7 +43,7 @@ export const JsonArrow = ({
useJsonTreeContextOrThrow();
return (
<StyledButton onClick={onClick}>
<StyledButton variant={variant} onClick={onClick}>
<VisibilityHidden>
{isOpen ? arrowButtonExpandedLabel : arrowButtonCollapsedLabel}
</VisibilityHidden>
@ -47,7 +51,11 @@ export const JsonArrow = ({
<MotionIconChevronDown
size={theme.icon.size.md}
color={
variant === 'blue' ? theme.color.blue : theme.font.color.secondary
variant === 'blue'
? theme.color.blue
: variant === 'red'
? theme.font.color.danger
: theme.font.color.secondary
}
initial={false}
animate={{ rotate: isOpen ? 0 : -90 }}