mirror of
https://github.com/Unleash/unleash.git
synced 2025-05-22 01:16:07 +02:00
chore: add integration events modal (#7648)
https://linear.app/unleash/issue/2-2441/create-integration-events-modal Adds the integration events modal to the UI, allowing us to visualize them. This is the core of the UI work for this feature. <img width="587" alt="image" src="https://github.com/user-attachments/assets/f64cbb8c-1c01-4638-a661-5943ad7a890c"> ### Example: Success <img width="1277" alt="image" src="https://github.com/user-attachments/assets/578bc7dc-d37d-4c0a-b74a-4bd33e859b51"> ### Example: Success with errors <img width="1255" alt="image" src="https://github.com/user-attachments/assets/f784104d-7f11-4146-829d-6b3a3808815b"> ### Example: Failed <img width="1254" alt="image" src="https://github.com/user-attachments/assets/543f857d-3877-4c17-92eb-58e6f038b8ac">
This commit is contained in:
parent
9c2b906d79
commit
e63503e832
@ -0,0 +1,75 @@
|
|||||||
|
import { Alert, styled } from '@mui/material';
|
||||||
|
import type { IntegrationEvent } from 'interfaces/integrationEvent';
|
||||||
|
import { IntegrationEventsDetailsAccordion } from './IntegrationEventsDetailsAccordion';
|
||||||
|
import CheckCircleOutline from '@mui/icons-material/CheckCircleOutline';
|
||||||
|
import { Link } from 'react-router-dom';
|
||||||
|
import { lazy, Suspense } from 'react';
|
||||||
|
|
||||||
|
const LazyReactJSONEditor = lazy(
|
||||||
|
() => import('component/common/ReactJSONEditor/ReactJSONEditor'),
|
||||||
|
);
|
||||||
|
|
||||||
|
const StyledDetails = styled('div')(({ theme }) => ({
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
gap: theme.spacing(2),
|
||||||
|
padding: theme.spacing(2),
|
||||||
|
}));
|
||||||
|
|
||||||
|
const StyledAlert = styled(Alert)({
|
||||||
|
fontSize: 'inherit',
|
||||||
|
lineBreak: 'anywhere',
|
||||||
|
});
|
||||||
|
|
||||||
|
const StyledLink = styled(Link)(({ theme }) => ({
|
||||||
|
marginLeft: theme.spacing(1),
|
||||||
|
}));
|
||||||
|
|
||||||
|
export const IntegrationEventsDetails = ({
|
||||||
|
state,
|
||||||
|
stateDetails,
|
||||||
|
event,
|
||||||
|
details,
|
||||||
|
}: IntegrationEvent) => {
|
||||||
|
const severity =
|
||||||
|
state === 'failed'
|
||||||
|
? 'error'
|
||||||
|
: state === 'success'
|
||||||
|
? 'success'
|
||||||
|
: 'warning';
|
||||||
|
|
||||||
|
const icon = state === 'success' ? <CheckCircleOutline /> : undefined;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<StyledDetails>
|
||||||
|
<StyledAlert severity={severity} icon={icon}>
|
||||||
|
{stateDetails}
|
||||||
|
</StyledAlert>
|
||||||
|
<IntegrationEventsDetailsAccordion
|
||||||
|
header={
|
||||||
|
<>
|
||||||
|
Event:
|
||||||
|
<StyledLink to='/history'>{event.type}</StyledLink>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Suspense fallback={null}>
|
||||||
|
<LazyReactJSONEditor
|
||||||
|
content={{ json: event }}
|
||||||
|
readOnly
|
||||||
|
statusBar={false}
|
||||||
|
editorStyle='sidePanel'
|
||||||
|
/>
|
||||||
|
</Suspense>
|
||||||
|
</IntegrationEventsDetailsAccordion>
|
||||||
|
<Suspense fallback={null}>
|
||||||
|
<LazyReactJSONEditor
|
||||||
|
content={{ json: details }}
|
||||||
|
readOnly
|
||||||
|
statusBar={false}
|
||||||
|
editorStyle='sidePanel'
|
||||||
|
/>
|
||||||
|
</Suspense>
|
||||||
|
</StyledDetails>
|
||||||
|
);
|
||||||
|
};
|
@ -0,0 +1,45 @@
|
|||||||
|
import ExpandMore from '@mui/icons-material/ExpandMore';
|
||||||
|
import {
|
||||||
|
Accordion,
|
||||||
|
AccordionDetails,
|
||||||
|
AccordionSummary,
|
||||||
|
IconButton,
|
||||||
|
styled,
|
||||||
|
} from '@mui/material';
|
||||||
|
import type { ReactNode } from 'react';
|
||||||
|
|
||||||
|
const StyledAccordion = styled(Accordion)(({ theme }) => ({
|
||||||
|
boxShadow: 'none',
|
||||||
|
border: `1px solid ${theme.palette.divider}`,
|
||||||
|
borderRadius: theme.shape.borderRadiusMedium,
|
||||||
|
'&:before': {
|
||||||
|
display: 'none',
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
|
const StyledAccordionSummary = styled(AccordionSummary)({
|
||||||
|
lineHeight: '1.5rem',
|
||||||
|
});
|
||||||
|
|
||||||
|
interface IIntegrationEventsDetailsEventProps {
|
||||||
|
header: ReactNode;
|
||||||
|
children: ReactNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const IntegrationEventsDetailsAccordion = ({
|
||||||
|
header,
|
||||||
|
children,
|
||||||
|
}: IIntegrationEventsDetailsEventProps) => (
|
||||||
|
<StyledAccordion>
|
||||||
|
<StyledAccordionSummary
|
||||||
|
expandIcon={
|
||||||
|
<IconButton>
|
||||||
|
<ExpandMore titleAccess='Toggle' />
|
||||||
|
</IconButton>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{header}
|
||||||
|
</StyledAccordionSummary>
|
||||||
|
<AccordionDetails>{children}</AccordionDetails>
|
||||||
|
</StyledAccordion>
|
||||||
|
);
|
@ -0,0 +1,174 @@
|
|||||||
|
import { Button, Link, styled } from '@mui/material';
|
||||||
|
import { SidebarModal } from 'component/common/SidebarModal/SidebarModal';
|
||||||
|
import type { AddonSchema } from 'openapi';
|
||||||
|
import { useIntegrationEvents } from 'hooks/api/getters/useIntegrationEvents/useIntegrationEvents';
|
||||||
|
import FormTemplate from 'component/common/FormTemplate/FormTemplate';
|
||||||
|
import { SidePanelList } from 'component/common/SidePanelList/SidePanelList';
|
||||||
|
import { formatDateYMDHMS } from 'utils/formatDate';
|
||||||
|
import { useLocationSettings } from 'hooks/useLocationSettings';
|
||||||
|
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
||||||
|
import { IntegrationEventsStateIcon } from './IntegrationEventsStateIcon';
|
||||||
|
import { IntegrationEventsDetails } from './IntegrationEventsDetails/IntegrationEventsDetails';
|
||||||
|
import { useNavigate } from 'react-router-dom';
|
||||||
|
|
||||||
|
const StyledHeader = styled('div')(({ theme }) => ({
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
marginBottom: theme.fontSizes.mainHeader,
|
||||||
|
}));
|
||||||
|
|
||||||
|
const StyledHeaderRow = styled('div')({
|
||||||
|
display: 'flex',
|
||||||
|
justifyContent: 'space-between',
|
||||||
|
alignItems: 'center',
|
||||||
|
width: '100%',
|
||||||
|
});
|
||||||
|
|
||||||
|
const StyledTitle = styled('h1')({
|
||||||
|
fontWeight: 'normal',
|
||||||
|
});
|
||||||
|
|
||||||
|
const StyledSubtitle = styled('h2')(({ theme }) => ({
|
||||||
|
marginTop: theme.spacing(1.5),
|
||||||
|
fontSize: theme.fontSizes.smallBody,
|
||||||
|
fontWeight: 'normal',
|
||||||
|
}));
|
||||||
|
|
||||||
|
const StyledForm = styled('form')({
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
height: '100%',
|
||||||
|
});
|
||||||
|
|
||||||
|
const StyledFailedItemWrapper = styled('div')(({ theme }) => ({
|
||||||
|
backgroundColor: theme.palette.error.light,
|
||||||
|
}));
|
||||||
|
|
||||||
|
const StyledButtonContainer = styled('div')(({ theme }) => ({
|
||||||
|
marginTop: 'auto',
|
||||||
|
display: 'flex',
|
||||||
|
justifyContent: 'flex-end',
|
||||||
|
paddingTop: theme.spacing(4),
|
||||||
|
}));
|
||||||
|
|
||||||
|
interface IIntegrationEventsModalProps {
|
||||||
|
addon?: AddonSchema;
|
||||||
|
open: boolean;
|
||||||
|
setOpen: React.Dispatch<React.SetStateAction<boolean>>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const IntegrationEventsModal = ({
|
||||||
|
addon,
|
||||||
|
open,
|
||||||
|
setOpen,
|
||||||
|
}: IIntegrationEventsModalProps) => {
|
||||||
|
const navigate = useNavigate();
|
||||||
|
const { locationSettings } = useLocationSettings();
|
||||||
|
const { integrationEvents, hasMore, loadMore, loading } =
|
||||||
|
useIntegrationEvents(addon?.id, 20, {
|
||||||
|
refreshInterval: 5000,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!addon) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const title = `Events: ${addon.provider}${addon.description ? ` - ${addon.description}` : ''} (id: ${addon.id})`;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<SidebarModal
|
||||||
|
open={open}
|
||||||
|
onClose={() => {
|
||||||
|
setOpen(false);
|
||||||
|
}}
|
||||||
|
label={title}
|
||||||
|
>
|
||||||
|
<FormTemplate
|
||||||
|
loading={loading && integrationEvents.length === 0}
|
||||||
|
modal
|
||||||
|
description=''
|
||||||
|
documentationLink=''
|
||||||
|
documentationLinkLabel=''
|
||||||
|
showGuidance={false}
|
||||||
|
>
|
||||||
|
<StyledHeader>
|
||||||
|
<StyledHeaderRow>
|
||||||
|
<StyledTitle>{title}</StyledTitle>
|
||||||
|
<Link
|
||||||
|
onClick={() => {
|
||||||
|
setOpen(false);
|
||||||
|
navigate(`/integrations/edit/${addon.id}`);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
View configuration
|
||||||
|
</Link>
|
||||||
|
</StyledHeaderRow>
|
||||||
|
<StyledHeaderRow>
|
||||||
|
<StyledSubtitle>
|
||||||
|
All events older than the last 100 or older than the
|
||||||
|
past 2 hours will be automatically deleted.
|
||||||
|
</StyledSubtitle>
|
||||||
|
</StyledHeaderRow>
|
||||||
|
</StyledHeader>
|
||||||
|
<StyledForm>
|
||||||
|
<SidePanelList
|
||||||
|
height={960}
|
||||||
|
items={integrationEvents}
|
||||||
|
columns={[
|
||||||
|
{
|
||||||
|
header: 'Status',
|
||||||
|
align: 'center',
|
||||||
|
maxWidth: 100,
|
||||||
|
cell: IntegrationEventsStateIcon,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
header: 'Date',
|
||||||
|
maxWidth: 240,
|
||||||
|
cell: ({ createdAt }) =>
|
||||||
|
formatDateYMDHMS(
|
||||||
|
createdAt,
|
||||||
|
locationSettings?.locale,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
sidePanelHeader='Details'
|
||||||
|
renderContent={IntegrationEventsDetails}
|
||||||
|
renderItem={({ id, state }, children) => {
|
||||||
|
if (state === 'failed') {
|
||||||
|
return (
|
||||||
|
<StyledFailedItemWrapper key={id}>
|
||||||
|
{children}
|
||||||
|
</StyledFailedItemWrapper>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return children;
|
||||||
|
}}
|
||||||
|
listEnd={
|
||||||
|
<ConditionallyRender
|
||||||
|
condition={hasMore}
|
||||||
|
show={
|
||||||
|
<Button onClick={loadMore}>
|
||||||
|
Load more
|
||||||
|
</Button>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<ConditionallyRender
|
||||||
|
condition={integrationEvents.length === 0}
|
||||||
|
show={
|
||||||
|
<p>
|
||||||
|
No events have been registered for this
|
||||||
|
integration configuration.
|
||||||
|
</p>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<StyledButtonContainer>
|
||||||
|
<Button onClick={() => setOpen(false)}>Close</Button>
|
||||||
|
</StyledButtonContainer>
|
||||||
|
</StyledForm>
|
||||||
|
</FormTemplate>
|
||||||
|
</SidebarModal>
|
||||||
|
);
|
||||||
|
};
|
@ -0,0 +1,31 @@
|
|||||||
|
import { styled } from '@mui/material';
|
||||||
|
import CheckCircleOutline from '@mui/icons-material/CheckCircleOutline';
|
||||||
|
import ErrorOutline from '@mui/icons-material/ErrorOutline';
|
||||||
|
import WarningAmber from '@mui/icons-material/WarningAmber';
|
||||||
|
import type { IntegrationEvent } from 'interfaces/integrationEvent';
|
||||||
|
|
||||||
|
export const StyledSuccessIcon = styled(CheckCircleOutline)(({ theme }) => ({
|
||||||
|
color: theme.palette.success.main,
|
||||||
|
}));
|
||||||
|
|
||||||
|
export const StyledFailedIcon = styled(ErrorOutline)(({ theme }) => ({
|
||||||
|
color: theme.palette.error.main,
|
||||||
|
}));
|
||||||
|
|
||||||
|
export const StyledSuccessWithErrorsIcon = styled(WarningAmber)(
|
||||||
|
({ theme }) => ({
|
||||||
|
color: theme.palette.warning.main,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
export const IntegrationEventsStateIcon = ({ state }: IntegrationEvent) => {
|
||||||
|
if (state === 'success') {
|
||||||
|
return <StyledSuccessIcon />;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state === 'failed') {
|
||||||
|
return <StyledFailedIcon />;
|
||||||
|
}
|
||||||
|
|
||||||
|
return <StyledSuccessWithErrorsIcon />;
|
||||||
|
};
|
@ -2,11 +2,19 @@ import {
|
|||||||
type ChangeEventHandler,
|
type ChangeEventHandler,
|
||||||
type FormEventHandler,
|
type FormEventHandler,
|
||||||
type MouseEventHandler,
|
type MouseEventHandler,
|
||||||
|
useContext,
|
||||||
useEffect,
|
useEffect,
|
||||||
useState,
|
useState,
|
||||||
type VFC,
|
type VFC,
|
||||||
} from 'react';
|
} from 'react';
|
||||||
import { Alert, Button, Divider, Typography } from '@mui/material';
|
import {
|
||||||
|
Alert,
|
||||||
|
Button,
|
||||||
|
Divider,
|
||||||
|
Link,
|
||||||
|
styled,
|
||||||
|
Typography,
|
||||||
|
} from '@mui/material';
|
||||||
import produce from 'immer';
|
import produce from 'immer';
|
||||||
import { trim } from 'component/common/util';
|
import { trim } from 'component/common/util';
|
||||||
import type { AddonSchema, AddonTypeSchema } from 'openapi';
|
import type { AddonSchema, AddonTypeSchema } from 'openapi';
|
||||||
@ -44,6 +52,21 @@ import { IntegrationDelete } from './IntegrationDelete/IntegrationDelete';
|
|||||||
import { IntegrationStateSwitch } from './IntegrationStateSwitch/IntegrationStateSwitch';
|
import { IntegrationStateSwitch } from './IntegrationStateSwitch/IntegrationStateSwitch';
|
||||||
import { capitalizeFirst } from 'utils/capitalizeFirst';
|
import { capitalizeFirst } from 'utils/capitalizeFirst';
|
||||||
import { IntegrationHowToSection } from '../IntegrationHowToSection/IntegrationHowToSection';
|
import { IntegrationHowToSection } from '../IntegrationHowToSection/IntegrationHowToSection';
|
||||||
|
import { useUiFlag } from 'hooks/useUiFlag';
|
||||||
|
import { IntegrationEventsModal } from '../IntegrationEventsModal/IntegrationEventsModal';
|
||||||
|
import AccessContext from 'contexts/AccessContext';
|
||||||
|
|
||||||
|
const StyledHeader = styled('div')(({ theme }) => ({
|
||||||
|
display: 'flex',
|
||||||
|
justifyContent: 'space-between',
|
||||||
|
alignItems: 'center',
|
||||||
|
width: '100%',
|
||||||
|
marginBottom: theme.fontSizes.mainHeader,
|
||||||
|
}));
|
||||||
|
|
||||||
|
const StyledHeaderTitle = styled('h1')({
|
||||||
|
fontWeight: 'normal',
|
||||||
|
});
|
||||||
|
|
||||||
type IntegrationFormProps = {
|
type IntegrationFormProps = {
|
||||||
provider?: AddonTypeSchema;
|
provider?: AddonTypeSchema;
|
||||||
@ -91,6 +114,10 @@ export const IntegrationForm: VFC<IntegrationFormProps> = ({
|
|||||||
containsErrors: false,
|
containsErrors: false,
|
||||||
parameters: {},
|
parameters: {},
|
||||||
});
|
});
|
||||||
|
const [eventsModalOpen, setEventsModalOpen] = useState(false);
|
||||||
|
const { isAdmin } = useContext(AccessContext);
|
||||||
|
const integrationEventsEnabled = useUiFlag('integrationEvents');
|
||||||
|
|
||||||
const submitText = editMode ? 'Update' : 'Create';
|
const submitText = editMode ? 'Update' : 'Create';
|
||||||
const url = `${uiConfig.unleashUrl}/api/admin/addons${
|
const url = `${uiConfig.unleashUrl}/api/admin/addons${
|
||||||
editMode ? `/${(formValues as AddonSchema).id}` : ``
|
editMode ? `/${(formValues as AddonSchema).id}` : ``
|
||||||
@ -259,13 +286,6 @@ export const IntegrationForm: VFC<IntegrationFormProps> = ({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<FormTemplate
|
<FormTemplate
|
||||||
title={
|
|
||||||
<>
|
|
||||||
{submitText}{' '}
|
|
||||||
{displayName || (name ? capitalizeFirst(name) : '')}{' '}
|
|
||||||
integration
|
|
||||||
</>
|
|
||||||
}
|
|
||||||
description={description || ''}
|
description={description || ''}
|
||||||
documentationLink={documentationUrl}
|
documentationLink={documentationUrl}
|
||||||
documentationLinkLabel={`${
|
documentationLinkLabel={`${
|
||||||
@ -291,6 +311,21 @@ export const IntegrationForm: VFC<IntegrationFormProps> = ({
|
|||||||
</StyledButtonContainer>
|
</StyledButtonContainer>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
|
<StyledHeader>
|
||||||
|
<StyledHeaderTitle>
|
||||||
|
{submitText}{' '}
|
||||||
|
{displayName || (name ? capitalizeFirst(name) : '')}{' '}
|
||||||
|
integration
|
||||||
|
</StyledHeaderTitle>
|
||||||
|
<ConditionallyRender
|
||||||
|
condition={editMode && isAdmin && integrationEventsEnabled}
|
||||||
|
show={
|
||||||
|
<Link onClick={() => setEventsModalOpen(true)}>
|
||||||
|
View events
|
||||||
|
</Link>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</StyledHeader>
|
||||||
<StyledForm onSubmit={onSubmit}>
|
<StyledForm onSubmit={onSubmit}>
|
||||||
<StyledContainer>
|
<StyledContainer>
|
||||||
<ConditionallyRender
|
<ConditionallyRender
|
||||||
@ -403,6 +438,11 @@ export const IntegrationForm: VFC<IntegrationFormProps> = ({
|
|||||||
</section>
|
</section>
|
||||||
</StyledContainer>
|
</StyledContainer>
|
||||||
</StyledForm>
|
</StyledForm>
|
||||||
|
<IntegrationEventsModal
|
||||||
|
addon={initialValues as AddonSchema}
|
||||||
|
open={eventsModalOpen}
|
||||||
|
setOpen={setEventsModalOpen}
|
||||||
|
/>
|
||||||
</FormTemplate>
|
</FormTemplate>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -14,6 +14,7 @@ import MoreVertIcon from '@mui/icons-material/MoreVert';
|
|||||||
import Delete from '@mui/icons-material/Delete';
|
import Delete from '@mui/icons-material/Delete';
|
||||||
import PowerSettingsNew from '@mui/icons-material/PowerSettingsNew';
|
import PowerSettingsNew from '@mui/icons-material/PowerSettingsNew';
|
||||||
import {
|
import {
|
||||||
|
ADMIN,
|
||||||
DELETE_ADDON,
|
DELETE_ADDON,
|
||||||
UPDATE_ADDON,
|
UPDATE_ADDON,
|
||||||
} from 'component/providers/AccessProvider/permissions';
|
} from 'component/providers/AccessProvider/permissions';
|
||||||
@ -24,6 +25,11 @@ import useAddons from 'hooks/api/getters/useAddons/useAddons';
|
|||||||
import useToast from 'hooks/useToast';
|
import useToast from 'hooks/useToast';
|
||||||
import { formatUnknownError } from 'utils/formatUnknownError';
|
import { formatUnknownError } from 'utils/formatUnknownError';
|
||||||
import { Dialogue } from 'component/common/Dialogue/Dialogue';
|
import { Dialogue } from 'component/common/Dialogue/Dialogue';
|
||||||
|
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
||||||
|
import { useUiFlag } from 'hooks/useUiFlag';
|
||||||
|
import Visibility from '@mui/icons-material/Visibility';
|
||||||
|
import { PermissionHOC } from 'component/common/PermissionHOC/PermissionHOC';
|
||||||
|
import { IntegrationEventsModal } from 'component/integrations/IntegrationEventsModal/IntegrationEventsModal';
|
||||||
|
|
||||||
interface IIntegrationCardMenuProps {
|
interface IIntegrationCardMenuProps {
|
||||||
addon: AddonSchema;
|
addon: AddonSchema;
|
||||||
@ -48,6 +54,8 @@ export const IntegrationCardMenu: VFC<IIntegrationCardMenuProps> = ({
|
|||||||
const { updateAddon, removeAddon } = useAddonsApi();
|
const { updateAddon, removeAddon } = useAddonsApi();
|
||||||
const { refetchAddons } = useAddons();
|
const { refetchAddons } = useAddons();
|
||||||
const { setToastData, setToastApiError } = useToast();
|
const { setToastData, setToastApiError } = useToast();
|
||||||
|
const [eventsModalOpen, setEventsModalOpen] = useState(false);
|
||||||
|
const integrationEventsEnabled = useUiFlag('integrationEvents');
|
||||||
|
|
||||||
const closeMenu = () => {
|
const closeMenu = () => {
|
||||||
setIsMenuOpen(false);
|
setIsMenuOpen(false);
|
||||||
@ -123,6 +131,24 @@ export const IntegrationCardMenu: VFC<IIntegrationCardMenuProps> = ({
|
|||||||
}}
|
}}
|
||||||
onClose={handleMenuClick}
|
onClose={handleMenuClick}
|
||||||
>
|
>
|
||||||
|
<ConditionallyRender
|
||||||
|
condition={integrationEventsEnabled}
|
||||||
|
show={
|
||||||
|
<PermissionHOC permission={ADMIN}>
|
||||||
|
{({ hasAccess }) => (
|
||||||
|
<MenuItem
|
||||||
|
onClick={() => setEventsModalOpen(true)}
|
||||||
|
disabled={!hasAccess}
|
||||||
|
>
|
||||||
|
<ListItemIcon>
|
||||||
|
<Visibility />
|
||||||
|
</ListItemIcon>
|
||||||
|
<ListItemText>View events</ListItemText>
|
||||||
|
</MenuItem>
|
||||||
|
)}
|
||||||
|
</PermissionHOC>
|
||||||
|
}
|
||||||
|
/>
|
||||||
<MenuItem
|
<MenuItem
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setIsToggleOpen(true);
|
setIsToggleOpen(true);
|
||||||
@ -151,6 +177,11 @@ export const IntegrationCardMenu: VFC<IIntegrationCardMenuProps> = ({
|
|||||||
</MenuItem>
|
</MenuItem>
|
||||||
</Menu>
|
</Menu>
|
||||||
|
|
||||||
|
<IntegrationEventsModal
|
||||||
|
addon={addon}
|
||||||
|
open={eventsModalOpen}
|
||||||
|
setOpen={setEventsModalOpen}
|
||||||
|
/>
|
||||||
<Dialogue
|
<Dialogue
|
||||||
open={isToggleOpen}
|
open={isToggleOpen}
|
||||||
onClick={toggleIntegration}
|
onClick={toggleIntegration}
|
||||||
|
Loading…
Reference in New Issue
Block a user