mirror of
https://github.com/Unleash/unleash.git
synced 2025-03-14 00:15:52 +01:00
chore: use new signal meta properties in event timeline (#8421)
https://linear.app/unleash/issue/2-2796/better-signals-integration Adds support to the following signal payload meta properties: - `unleash_title` - `unleash_description` - `unleash_icon` - `unleash_variant` Follows a logic similar to what we currently have for banners. E.g. [custom icon](https://docs.getunleash.io/reference/banners#custom-icon). ## Call signal endpoints   ## View signals in event timeline  
This commit is contained in:
parent
24b9e4987b
commit
7c5fab518f
@ -14,12 +14,14 @@ export type TimelineEventType = 'signal' | EventSchemaType;
|
|||||||
|
|
||||||
type RawTimelineEvent = EventSchema | ISignalQuerySignal;
|
type RawTimelineEvent = EventSchema | ISignalQuerySignal;
|
||||||
|
|
||||||
type TimelineEvent = {
|
export type TimelineEvent = {
|
||||||
id: number;
|
id: number;
|
||||||
timestamp: number;
|
timestamp: number;
|
||||||
type: TimelineEventType;
|
type: TimelineEventType;
|
||||||
label: string;
|
label: string;
|
||||||
summary: string;
|
summary: string;
|
||||||
|
icon?: string;
|
||||||
|
variant?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TimelineEventGroup = TimelineEvent[];
|
export type TimelineEventGroup = TimelineEvent[];
|
||||||
@ -111,6 +113,9 @@ const getTimestamp = (event: RawTimelineEvent) => {
|
|||||||
const isInRange = (timestamp: number, startTime: number, endTime: number) =>
|
const isInRange = (timestamp: number, startTime: number, endTime: number) =>
|
||||||
timestamp >= startTime && timestamp <= endTime;
|
timestamp >= startTime && timestamp <= endTime;
|
||||||
|
|
||||||
|
const isValidString = (str: unknown): str is string =>
|
||||||
|
typeof str === 'string' && str.trim().length > 0;
|
||||||
|
|
||||||
const getTimelineEvent = (
|
const getTimelineEvent = (
|
||||||
event: RawTimelineEvent,
|
event: RawTimelineEvent,
|
||||||
timestamp: number,
|
timestamp: number,
|
||||||
@ -122,10 +127,19 @@ const getTimelineEvent = (
|
|||||||
sourceName = 'unknown source',
|
sourceName = 'unknown source',
|
||||||
sourceDescription,
|
sourceDescription,
|
||||||
tokenName,
|
tokenName,
|
||||||
|
payload: {
|
||||||
|
experimental_unleash_title,
|
||||||
|
experimental_unleash_description,
|
||||||
|
experimental_unleash_icon,
|
||||||
|
experimental_unleash_variant,
|
||||||
|
},
|
||||||
} = event;
|
} = event;
|
||||||
|
|
||||||
const label = `Signal: ${sourceName}`;
|
const title = experimental_unleash_title || sourceName;
|
||||||
const summary = `Signal originated from **[${sourceName} (${tokenName})](/integrations/signals)** endpoint${sourceDescription ? `: ${sourceDescription}` : ''}`;
|
const label = `Signal: ${title}`;
|
||||||
|
const summary = experimental_unleash_description
|
||||||
|
? `Signal: **[${title}](/integrations/signals)** ${experimental_unleash_description}`
|
||||||
|
: `Signal originated from **[${sourceName} (${tokenName})](/integrations/signals)** endpoint${sourceDescription ? `: ${sourceDescription}` : ''}`;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id,
|
id,
|
||||||
@ -133,6 +147,12 @@ const getTimelineEvent = (
|
|||||||
type: 'signal',
|
type: 'signal',
|
||||||
label,
|
label,
|
||||||
summary,
|
summary,
|
||||||
|
...(isValidString(experimental_unleash_icon)
|
||||||
|
? { icon: experimental_unleash_icon }
|
||||||
|
: {}),
|
||||||
|
...(isValidString(experimental_unleash_variant)
|
||||||
|
? { variant: experimental_unleash_variant }
|
||||||
|
: {}),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,14 +4,18 @@ import FlagOutlinedIcon from '@mui/icons-material/FlagOutlined';
|
|||||||
import ExtensionOutlinedIcon from '@mui/icons-material/ExtensionOutlined';
|
import ExtensionOutlinedIcon from '@mui/icons-material/ExtensionOutlined';
|
||||||
import SegmentsIcon from '@mui/icons-material/DonutLargeOutlined';
|
import SegmentsIcon from '@mui/icons-material/DonutLargeOutlined';
|
||||||
import QuestionMarkIcon from '@mui/icons-material/QuestionMark';
|
import QuestionMarkIcon from '@mui/icons-material/QuestionMark';
|
||||||
import { styled } from '@mui/material';
|
import { Icon, styled } from '@mui/material';
|
||||||
import type { TimelineEventGroup, TimelineEventType } from '../EventTimeline';
|
import type {
|
||||||
|
TimelineEvent,
|
||||||
|
TimelineEventGroup,
|
||||||
|
TimelineEventType,
|
||||||
|
} from '../EventTimeline';
|
||||||
import MoreHorizIcon from '@mui/icons-material/MoreHoriz';
|
import MoreHorizIcon from '@mui/icons-material/MoreHoriz';
|
||||||
import type { HTMLAttributes } from 'react';
|
import type { HTMLAttributes } from 'react';
|
||||||
import SensorsIcon from '@mui/icons-material/Sensors';
|
import SensorsIcon from '@mui/icons-material/Sensors';
|
||||||
|
|
||||||
type DefaultEventVariant = 'secondary';
|
type DefaultEventVariant = 'secondary';
|
||||||
type CustomEventVariant = 'success' | 'neutral' | 'warning';
|
type CustomEventVariant = 'success' | 'neutral' | 'warning' | 'error';
|
||||||
type EventVariant = DefaultEventVariant | CustomEventVariant;
|
type EventVariant = DefaultEventVariant | CustomEventVariant;
|
||||||
|
|
||||||
const StyledEventCircle = styled('div', {
|
const StyledEventCircle = styled('div', {
|
||||||
@ -26,17 +30,26 @@ const StyledEventCircle = styled('div', {
|
|||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
transition: 'transform 0.2s',
|
transition: 'transform 0.2s',
|
||||||
'& svg': {
|
'& svg, span': {
|
||||||
color: theme.palette[variant].main,
|
color: theme.palette[variant].main,
|
||||||
|
},
|
||||||
|
'& svg': {
|
||||||
height: theme.spacing(2.5),
|
height: theme.spacing(2.5),
|
||||||
width: theme.spacing(2.5),
|
width: theme.spacing(2.5),
|
||||||
},
|
},
|
||||||
|
'& span': {
|
||||||
|
fontSize: theme.fontSizes.bodySize,
|
||||||
|
},
|
||||||
'&:hover': {
|
'&:hover': {
|
||||||
transform: 'scale(1.5)',
|
transform: 'scale(1.5)',
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const getEventIcon = (type: TimelineEventType) => {
|
const getEventIcon = ({ icon, type }: Pick<TimelineEvent, 'icon' | 'type'>) => {
|
||||||
|
if (icon) {
|
||||||
|
return <Icon>{icon}</Icon>;
|
||||||
|
}
|
||||||
|
|
||||||
if (type === 'signal') {
|
if (type === 'signal') {
|
||||||
return <SensorsIcon />;
|
return <SensorsIcon />;
|
||||||
}
|
}
|
||||||
@ -72,6 +85,10 @@ const customEventVariants: Partial<
|
|||||||
'feature-archived': 'neutral',
|
'feature-archived': 'neutral',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const isValidVariant = (variant?: string): variant is EventVariant =>
|
||||||
|
variant !== undefined &&
|
||||||
|
['secondary', 'success', 'neutral', 'warning', 'error'].includes(variant);
|
||||||
|
|
||||||
interface IEventTimelineEventCircleProps
|
interface IEventTimelineEventCircleProps
|
||||||
extends HTMLAttributes<HTMLDivElement> {
|
extends HTMLAttributes<HTMLDivElement> {
|
||||||
group: TimelineEventGroup;
|
group: TimelineEventGroup;
|
||||||
@ -83,16 +100,23 @@ export const EventTimelineEventCircle = ({
|
|||||||
}: IEventTimelineEventCircleProps) => {
|
}: IEventTimelineEventCircleProps) => {
|
||||||
if (
|
if (
|
||||||
group.length === 1 ||
|
group.length === 1 ||
|
||||||
!group.some(({ type }) => type !== group[0].type)
|
!group.some(
|
||||||
|
({ type, icon }) =>
|
||||||
|
type !== group[0].type || icon !== group[0].icon,
|
||||||
|
)
|
||||||
) {
|
) {
|
||||||
const event = group[0];
|
const event = group[0];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StyledEventCircle
|
<StyledEventCircle
|
||||||
variant={customEventVariants[event.type]}
|
variant={
|
||||||
|
isValidVariant(event.variant)
|
||||||
|
? event.variant
|
||||||
|
: customEventVariants[event.type]
|
||||||
|
}
|
||||||
{...props}
|
{...props}
|
||||||
>
|
>
|
||||||
{getEventIcon(event.type)}
|
{getEventIcon(event)}
|
||||||
</StyledEventCircle>
|
</StyledEventCircle>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -50,6 +50,7 @@ const StyledTooltipItem = styled('div')(({ theme }) => ({
|
|||||||
|
|
||||||
const StyledEventTimelineEventCircle = styled(EventTimelineEventCircle)(
|
const StyledEventTimelineEventCircle = styled(EventTimelineEventCircle)(
|
||||||
({ theme }) => ({
|
({ theme }) => ({
|
||||||
|
flexShrink: 0,
|
||||||
marginTop: theme.spacing(0.125),
|
marginTop: theme.spacing(0.125),
|
||||||
height: theme.spacing(2.5),
|
height: theme.spacing(2.5),
|
||||||
width: theme.spacing(2.5),
|
width: theme.spacing(2.5),
|
||||||
@ -57,6 +58,9 @@ const StyledEventTimelineEventCircle = styled(EventTimelineEventCircle)(
|
|||||||
'& > svg': {
|
'& > svg': {
|
||||||
height: theme.spacing(1.75),
|
height: theme.spacing(1.75),
|
||||||
},
|
},
|
||||||
|
'& > span': {
|
||||||
|
fontSize: theme.fontSizes.smallBody,
|
||||||
|
},
|
||||||
'&:hover': {
|
'&:hover': {
|
||||||
transform: 'none',
|
transform: 'none',
|
||||||
},
|
},
|
||||||
|
Loading…
Reference in New Issue
Block a user