Skip to content

Commit

Permalink
chore: new actions table UI (#6435)
Browse files Browse the repository at this point in the history
  • Loading branch information
nunogois committed Mar 5, 2024
1 parent 454f44d commit 86a795e
Show file tree
Hide file tree
Showing 12 changed files with 163 additions and 53 deletions.
Expand Up @@ -3,6 +3,13 @@ import { TextCell } from 'component/common/Table/cells/TextCell/TextCell';
import { IActionSet } from 'interfaces/action';
import { LinkCell } from 'component/common/Table/cells/LinkCell/LinkCell';
import { TooltipLink } from 'component/common/TooltipLink/TooltipLink';
import { ProjectActionsLastEvent } from './ProjectActionsLastEvent';

const StyledCell = styled('div')(({ theme }) => ({
display: 'flex',
alignItems: 'center',
gap: theme.spacing(1),
}));

const StyledActionItems = styled('div')(({ theme }) => ({
display: 'flex',
Expand Down Expand Up @@ -34,7 +41,8 @@ export const ProjectActionsActionsCell = ({
}

return (
<TextCell>
<StyledCell>
<ProjectActionsLastEvent action={action} />
<TooltipLink
tooltip={
<StyledActionItems>
Expand All @@ -60,6 +68,6 @@ export const ProjectActionsActionsCell = ({
? '1 action'
: `${actions.length} actions`}
</TooltipLink>
</TextCell>
</StyledCell>
);
};
@@ -0,0 +1,59 @@
import { IActionSet } from 'interfaces/action';
import { TooltipLink } from 'component/common/TooltipLink/TooltipLink';
import { useActionEvents } from 'hooks/api/getters/useActionEvents/useActionEvents';
import { ProjectActionsEventsDetails } from '../ProjectActionsEventsModal/ProjectActionsEventsDetails/ProjectActionsEventsDetails';
import { CircularProgress, styled } from '@mui/material';
import { CheckCircle, Error as ErrorIcon } from '@mui/icons-material';

const StyledTooltipLink = styled(TooltipLink)(({ theme }) => ({
display: 'flex',
alignItems: 'center',
}));

export const StyledSuccessIcon = styled(CheckCircle)(({ theme }) => ({
color: theme.palette.success.main,
}));

export const StyledFailedIcon = styled(ErrorIcon)(({ theme }) => ({
color: theme.palette.error.main,
}));

interface IProjectActionsLastEventProps {
action: IActionSet;
}

export const ProjectActionsLastEvent = ({
action,
}: IProjectActionsLastEventProps) => {
const { id, project } = action;
const { actionEvents } = useActionEvents(id, project, 1, {
refreshInterval: 5000,
});

if (actionEvents.length === 0) {
return null;
}

const actionSetEvent = actionEvents[0];

const icon =
actionSetEvent.state === 'success' ? (
<StyledSuccessIcon />
) : actionSetEvent.state === 'failed' ? (
<StyledFailedIcon />
) : (
<CircularProgress size={20} />
);

return (
<StyledTooltipLink
tooltipProps={{
maxWidth: 500,
maxHeight: 600,
}}
tooltip={<ProjectActionsEventsDetails {...actionSetEvent} />}
>
{icon}
</StyledTooltipLink>
);
};
Expand Up @@ -19,5 +19,11 @@ export const ProjectActionsActorCell = ({
return <TextCell>No service account</TextCell>;
}

return <LinkCell to='/admin/service-accounts'>{actor.name}</LinkCell>;
return (
<LinkCell
to='/admin/service-accounts'
title={actor.name}
subtitle={actor.username}
/>
);
};
Expand Up @@ -10,6 +10,10 @@ const StyledDetails = styled('div')(({ theme }) => ({
padding: theme.spacing(2),
}));

const StyledAlert = styled(Alert)({
fontSize: 'inherit',
});

export const ProjectActionsEventsDetails = ({
state,
actionSet: { actions },
Expand All @@ -24,9 +28,9 @@ export const ProjectActionsEventsDetails = ({

return (
<StyledDetails>
<Alert severity={state === 'failed' ? 'error' : 'success'}>
<StyledAlert severity={state === 'failed' ? 'error' : 'success'}>
{stateText}
</Alert>
</StyledAlert>
<ProjectActionsEventsDetailsSource signal={signal} />
{actions.map((action, i) => (
<ProjectActionsEventsDetailsAction
Expand Down
Expand Up @@ -44,6 +44,7 @@ export const StyledFailedIcon = styled(ErrorOutline)(({ theme }) => ({

const StyledAlert = styled(Alert)(({ theme }) => ({
marginTop: theme.spacing(2),
fontSize: 'inherit',
}));

const StyledDivider = styled(Divider)(({ theme }) => ({
Expand Down
Expand Up @@ -24,6 +24,10 @@ const StyledAccordion = styled(Accordion)(({ theme }) => ({
},
}));

const StyledAccordionSummary = styled(AccordionSummary)({
lineHeight: '1.5rem',
});

const StyledLink = styled(Link)(({ theme }) => ({
marginLeft: theme.spacing(1),
}));
Expand All @@ -47,7 +51,7 @@ export const ProjectActionsEventsDetailsSourceSignalEndpoint = ({

return (
<StyledAccordion>
<AccordionSummary
<StyledAccordionSummary
expandIcon={
<IconButton>
<ExpandMore titleAccess='Toggle' />
Expand All @@ -58,7 +62,7 @@ export const ProjectActionsEventsDetailsSourceSignalEndpoint = ({
<StyledLink to='/integrations/signals'>
{signalEndpointName}
</StyledLink>
</AccordionSummary>
</StyledAccordionSummary>
<AccordionDetails>
<Suspense fallback={null}>
<LazyReactJSONEditor
Expand Down
Expand Up @@ -2,6 +2,7 @@ import { styled, Typography } from '@mui/material';
import { TextCell } from 'component/common/Table/cells/TextCell/TextCell';
import { IActionSet } from 'interfaces/action';
import { TooltipLink } from 'component/common/TooltipLink/TooltipLink';
import { formatOperatorDescription } from 'component/common/NewConstraintAccordion/ConstraintOperator/formatOperatorDescription';

const StyledItem = styled(Typography)(({ theme }) => ({
fontSize: theme.fontSizes.smallerBody,
Expand All @@ -24,6 +25,9 @@ export const ProjectActionsFiltersCell = ({
return (
<TextCell>
<TooltipLink
tooltipProps={{
maxWidth: 500,
}}
tooltip={
<>
{filters.map(
Expand All @@ -36,18 +40,33 @@ export const ProjectActionsFiltersCell = ({
value,
values,
},
]) => (
<StyledItem key={parameter}>
<strong>{parameter}</strong>{' '}
{inverted ? 'NOT' : ''} {operator}{' '}
{caseInsensitive
? '(case insensitive)'
: ''}{' '}
<strong>
{values ? values.join(', ') : value}
</strong>
</StyledItem>
),
]) => {
const operatorDescription: string =
formatOperatorDescription(operator);

const operatorText = inverted ? (
<>
is <u>not</u>{' '}
{operatorDescription.substring(2)}
</>
) : (
operatorDescription
);

return (
<StyledItem key={parameter}>
<strong>{parameter}</strong>{' '}
{operatorText}
{caseInsensitive
? ' (case insensitive)'
: ''}
{': '}
<strong>
{values ? values.join(', ') : value}
</strong>
</StyledItem>
);
},
)}
</>
}
Expand Down
Expand Up @@ -41,6 +41,7 @@ export const useProjectActionsForm = (action?: IActionSet) => {

const [enabled, setEnabled] = useState(false);
const [name, setName] = useState('');
const [description, setDescription] = useState('');
const [sourceId, setSourceId] = useState<number>(0);
const [filters, setFilters] = useState<ActionsFilterState[]>([]);
const [actorId, setActorId] = useState<number>(0);
Expand All @@ -49,6 +50,7 @@ export const useProjectActionsForm = (action?: IActionSet) => {
const reloadForm = () => {
setEnabled(action?.enabled ?? true);
setName(action?.name || '');
setDescription(action?.description || '');
setSourceId(action?.match?.sourceId ?? 0);
setFilters(
Object.entries(action?.match?.payload ?? {}).map(
Expand Down Expand Up @@ -171,6 +173,8 @@ export const useProjectActionsForm = (action?: IActionSet) => {
setEnabled,
name,
setName,
description,
setDescription,
sourceId,
setSourceId,
filters,
Expand Down
Expand Up @@ -69,6 +69,8 @@ export const ProjectActionsModal = ({
setEnabled,
name,
setName,
description,
setDescription,
sourceId,
setSourceId,
filters,
Expand All @@ -94,6 +96,7 @@ export const ProjectActionsModal = ({
const payload: ActionSetPayload = {
enabled,
name,
description,
match: {
source: 'signal-endpoint',
sourceId,
Expand Down
Expand Up @@ -31,43 +31,43 @@ const StyledLink = styled(Link)<{
},
}));

interface IProjectActionsTriggerCellProps {
interface IProjectActionsSourceCellProps {
action: IActionSet;
signalEndpoints: ISignalEndpoint[];
}

export const ProjectActionsTriggerCell = ({
export const ProjectActionsSourceCell = ({
action,
signalEndpoints,
}: IProjectActionsTriggerCellProps) => {
}: IProjectActionsSourceCellProps) => {
const { sourceId, source } = action.match;
const trigger = signalEndpoints.find(({ id }) => id === sourceId);

if (!trigger) {
return <TextCell>No trigger</TextCell>;
}
if (source === 'signal-endpoint') {
const signalEndpoint = signalEndpoints.find(
({ id }) => id === sourceId,
);

const sourceIcon =
source === 'signal-endpoint' ? (
<HtmlTooltip title='Signal endpoint' arrow>
<StyledIcon alt='Signal endpoint' variant='rounded'>
<SignalsIcon />
</StyledIcon>
</HtmlTooltip>
) : null;
if (signalEndpoint) {
return (
<TextCell>
<StyledCell>
<HtmlTooltip title='Signal endpoint' arrow>
<StyledIcon alt='Signal endpoint' variant='rounded'>
<SignalsIcon />
</StyledIcon>
</HtmlTooltip>
<StyledLink
component={RouterLink}
to='/integrations/signals'
underline='hover'
>
{signalEndpoint.name}
</StyledLink>
</StyledCell>
</TextCell>
);
}
}

return (
<TextCell>
<StyledCell>
{sourceIcon}
<StyledLink
component={RouterLink}
to='/integrations/signals'
underline='hover'
>
{trigger.name}
</StyledLink>
</StyledCell>
</TextCell>
);
return <TextCell>No source</TextCell>;
};
Expand Up @@ -13,10 +13,10 @@ import { useActions } from 'hooks/api/getters/useActions/useActions';
import { useActionsApi } from 'hooks/api/actions/useActionsApi/useActionsApi';
import { IActionSet } from 'interfaces/action';
import { ToggleCell } from 'component/common/Table/cells/ToggleCell/ToggleCell';
import { ProjectActionsTriggerCell } from './ProjectActionsTriggerCell';
import { ProjectActionsSourceCell } from './ProjectActionsSourceCell';
import { ProjectActionsFiltersCell } from './ProjectActionsFiltersCell';
import { ProjectActionsActorCell } from './ProjectActionsActorCell';
import { ProjectActionsActionsCell } from './ProjectActionsActionsCell';
import { ProjectActionsActionsCell } from './ProjectActionsActionsCell/ProjectActionsActionsCell';
import { ProjectActionsTableActionsCell } from './ProjectActionsTableActionsCell';
import { ProjectActionsModal } from './ProjectActionsModal/ProjectActionsModal';
import { ProjectActionsDeleteDialog } from './ProjectActionsDeleteDialog';
Expand Down Expand Up @@ -96,6 +96,7 @@ export const ProjectActionsTable = ({
}: { row: { original: IActionSet } }) => (
<LinkCell
title={action.name}
subtitle={action.description}
onClick={() => {
setSelectedAction(action);
setModalOpen(true);
Expand All @@ -104,12 +105,12 @@ export const ProjectActionsTable = ({
),
},
{
id: 'trigger',
Header: 'Trigger',
id: 'source',
Header: 'Source',
Cell: ({
row: { original: action },
}: { row: { original: IActionSet } }) => (
<ProjectActionsTriggerCell
<ProjectActionsSourceCell
action={action}
signalEndpoints={signalEndpoints}
/>
Expand Down
1 change: 1 addition & 0 deletions frontend/src/interfaces/action.ts
Expand Up @@ -9,6 +9,7 @@ export interface IActionSet {
id: number;
enabled: boolean;
name: string;
description: string;
project: string;
actorId: number;
match: IMatch;
Expand Down

0 comments on commit 86a795e

Please sign in to comment.