mirror of
https://github.com/Unleash/unleash.git
synced 2025-01-25 00:07:47 +01:00
chore: event timeline signals tip (#8342)
https://linear.app/unleash/issue/2-2723/add-signals-tip Adds a tip to the event timeline regarding the usage of signals. The conditions for it to show up are the following: - `!signalsSuggestionSeen` - The current user has not closed the tip yet - `isEnterprise()` - The Unleash instance is an Enterprise instance (signals are currently Enterprise-only) - `isAdmin` - The current user is an admin (signals are currently admin-only) - `signalsEnabled` - The signals feature flag is currently enabled - `!loading` - Signal endpoints have not finished loading (prevents flickering) - `signalEndpoints.length === 0` - The Unleash instance currently has zero configured signal endpoints (signals feature is not being used) ![image](https://github.com/user-attachments/assets/8dd73e62-a341-4d12-97b1-4e011f7891c3)
This commit is contained in:
parent
9a64dfbfbe
commit
836adf52a1
@ -33,7 +33,7 @@ const StyledRow = styled('div')({
|
|||||||
const StyledTimelineBody = styled('div')(({ theme }) => ({
|
const StyledTimelineBody = styled('div')(({ theme }) => ({
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
flexDirection: 'column',
|
flexDirection: 'column',
|
||||||
padding: theme.spacing(1, 0),
|
padding: theme.spacing(1.5, 0),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const StyledTimelineContainer = styled('div')(({ theme }) => ({
|
const StyledTimelineContainer = styled('div')(({ theme }) => ({
|
||||||
|
@ -11,6 +11,7 @@ import { useEffect, useMemo } from 'react';
|
|||||||
import { timeSpanOptions } from '../EventTimelineProvider';
|
import { timeSpanOptions } from '../EventTimelineProvider';
|
||||||
import CloseIcon from '@mui/icons-material/Close';
|
import CloseIcon from '@mui/icons-material/Close';
|
||||||
import { useEventTimelineContext } from '../EventTimelineContext';
|
import { useEventTimelineContext } from '../EventTimelineContext';
|
||||||
|
import { EventTimelineHeaderTip } from './EventTimelineHeaderTip';
|
||||||
|
|
||||||
const StyledCol = styled('div')(({ theme }) => ({
|
const StyledCol = styled('div')(({ theme }) => ({
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
@ -86,6 +87,7 @@ export const EventTimelineHeader = ({
|
|||||||
))}
|
))}
|
||||||
</StyledFilter>
|
</StyledFilter>
|
||||||
</StyledCol>
|
</StyledCol>
|
||||||
|
<EventTimelineHeaderTip />
|
||||||
<StyledCol>
|
<StyledCol>
|
||||||
<ConditionallyRender
|
<ConditionallyRender
|
||||||
condition={Boolean(environment)}
|
condition={Boolean(environment)}
|
||||||
|
@ -0,0 +1,61 @@
|
|||||||
|
import { Chip, styled } from '@mui/material';
|
||||||
|
import AccessContext from 'contexts/AccessContext';
|
||||||
|
import { useSignalEndpoints } from 'hooks/api/getters/useSignalEndpoints/useSignalEndpoints';
|
||||||
|
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
|
||||||
|
import { useUiFlag } from 'hooks/useUiFlag';
|
||||||
|
import { useContext } from 'react';
|
||||||
|
import { useEventTimelineContext } from '../EventTimelineContext';
|
||||||
|
import { Link, useNavigate } from 'react-router-dom';
|
||||||
|
import SensorsIcon from '@mui/icons-material/Sensors';
|
||||||
|
|
||||||
|
const StyledTip = styled('div')({
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
});
|
||||||
|
|
||||||
|
const StyledSignalIcon = styled(SensorsIcon)(({ theme }) => ({
|
||||||
|
'&&&': {
|
||||||
|
color: theme.palette.primary.main,
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
|
const signalsLink = '/integrations/signals';
|
||||||
|
|
||||||
|
export const EventTimelineHeaderTip = () => {
|
||||||
|
const navigate = useNavigate();
|
||||||
|
const { signalsSuggestionSeen, setSignalsSuggestionSeen } =
|
||||||
|
useEventTimelineContext();
|
||||||
|
|
||||||
|
const { isEnterprise } = useUiConfig();
|
||||||
|
const { isAdmin } = useContext(AccessContext);
|
||||||
|
const signalsEnabled = useUiFlag('signals');
|
||||||
|
const { signalEndpoints, loading } = useSignalEndpoints();
|
||||||
|
|
||||||
|
if (
|
||||||
|
!signalsSuggestionSeen &&
|
||||||
|
isEnterprise() &&
|
||||||
|
isAdmin &&
|
||||||
|
signalsEnabled &&
|
||||||
|
!loading &&
|
||||||
|
signalEndpoints.length === 0
|
||||||
|
) {
|
||||||
|
return (
|
||||||
|
<StyledTip>
|
||||||
|
<Chip
|
||||||
|
size='small'
|
||||||
|
icon={<StyledSignalIcon />}
|
||||||
|
label={
|
||||||
|
<>
|
||||||
|
See <Link to={signalsLink}>signals</Link> from
|
||||||
|
external sources in real-time within Unleash
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
onClick={() => navigate(signalsLink)}
|
||||||
|
onDelete={() => setSignalsSuggestionSeen(true)}
|
||||||
|
/>
|
||||||
|
</StyledTip>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
};
|
@ -14,14 +14,14 @@ type EventTimelineState = {
|
|||||||
open: boolean;
|
open: boolean;
|
||||||
timeSpan: TimeSpanOption;
|
timeSpan: TimeSpanOption;
|
||||||
environment?: IEnvironment;
|
environment?: IEnvironment;
|
||||||
signalsAlertSeen?: boolean;
|
signalsSuggestionSeen?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
type EventTimelineStateSetters = {
|
type EventTimelineStateSetters = {
|
||||||
setOpen: (open: boolean) => void;
|
setOpen: (open: boolean) => void;
|
||||||
setTimeSpan: (timeSpan: TimeSpanOption) => void;
|
setTimeSpan: (timeSpan: TimeSpanOption) => void;
|
||||||
setEnvironment: (environment: IEnvironment) => void;
|
setEnvironment: (environment: IEnvironment) => void;
|
||||||
setSignalsAlertSeen: (seen: boolean) => void;
|
setSignalsSuggestionSeen: (seen: boolean) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
export interface IEventTimelineContext
|
export interface IEventTimelineContext
|
||||||
@ -108,8 +108,8 @@ export const EventTimelineProvider = ({
|
|||||||
setField('timeSpan', timeSpan),
|
setField('timeSpan', timeSpan),
|
||||||
setEnvironment: (environment: IEnvironment) =>
|
setEnvironment: (environment: IEnvironment) =>
|
||||||
setField('environment', environment),
|
setField('environment', environment),
|
||||||
setSignalsAlertSeen: (seen: boolean) =>
|
setSignalsSuggestionSeen: (seen: boolean) =>
|
||||||
setField('signalsAlertSeen', seen),
|
setField('signalsSuggestionSeen', seen),
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -8,10 +8,10 @@ import { useEffect, useState } from 'react';
|
|||||||
|
|
||||||
const StyledEventTimelineSlider = styled(Box)(({ theme }) => ({
|
const StyledEventTimelineSlider = styled(Box)(({ theme }) => ({
|
||||||
backgroundColor: theme.palette.background.paper,
|
backgroundColor: theme.palette.background.paper,
|
||||||
height: '105px',
|
height: '120px',
|
||||||
overflow: 'hidden',
|
overflow: 'hidden',
|
||||||
boxShadow: theme.boxShadows.popup,
|
boxShadow: theme.boxShadows.popup,
|
||||||
borderLeft: `1px solid ${theme.palette.divider}`,
|
borderLeft: `1px solid ${theme.palette.background.application}`,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const StyledEventTimelineWrapper = styled(Box)(({ theme }) => ({
|
const StyledEventTimelineWrapper = styled(Box)(({ theme }) => ({
|
||||||
@ -36,7 +36,7 @@ export const MainLayoutEventTimeline = () => {
|
|||||||
transition: isInitialLoad
|
transition: isInitialLoad
|
||||||
? 'none'
|
? 'none'
|
||||||
: 'max-height 0.3s ease-in-out',
|
: 'max-height 0.3s ease-in-out',
|
||||||
maxHeight: open ? '105px' : '0',
|
maxHeight: open ? '120px' : '0',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<StyledEventTimelineWrapper>
|
<StyledEventTimelineWrapper>
|
||||||
|
Loading…
Reference in New Issue
Block a user