
* test(user-interface): add tests with playwright * test: refactor UI configuration tests --------- Co-authored-by: Ali BARIN <ali.barin53@gmail.com>
141 lines
3.9 KiB
TypeScript
141 lines
3.9 KiB
TypeScript
import * as React from 'react';
|
|
import { Link } from 'react-router-dom';
|
|
import Card from '@mui/material/Card';
|
|
import IconButton from '@mui/material/IconButton';
|
|
import CardActionArea from '@mui/material/CardActionArea';
|
|
import Chip from '@mui/material/Chip';
|
|
import MoreHorizIcon from '@mui/icons-material/MoreHoriz';
|
|
import { DateTime } from 'luxon';
|
|
|
|
import type { IFlow } from '@automatisch/types';
|
|
import FlowAppIcons from 'components/FlowAppIcons';
|
|
import FlowContextMenu from 'components/FlowContextMenu';
|
|
import useFormatMessage from 'hooks/useFormatMessage';
|
|
import * as URLS from 'config/urls';
|
|
import { Apps, CardContent, ContextMenu, Title, Typography } from './style';
|
|
|
|
type FlowRowProps = {
|
|
flow: IFlow;
|
|
};
|
|
|
|
function getFlowStatusTranslationKey(status: IFlow['status']): string {
|
|
if (status === 'published') {
|
|
return 'flow.published';
|
|
} else if (status === 'paused') {
|
|
return 'flow.paused';
|
|
}
|
|
|
|
return 'flow.draft';
|
|
}
|
|
|
|
function getFlowStatusColor(
|
|
status: IFlow['status']
|
|
):
|
|
| 'default'
|
|
| 'primary'
|
|
| 'secondary'
|
|
| 'error'
|
|
| 'info'
|
|
| 'success'
|
|
| 'warning' {
|
|
if (status === 'published') {
|
|
return 'success';
|
|
} else if (status === 'paused') {
|
|
return 'error';
|
|
}
|
|
|
|
return 'info';
|
|
}
|
|
|
|
export default function FlowRow(props: FlowRowProps): React.ReactElement {
|
|
const formatMessage = useFormatMessage();
|
|
const contextButtonRef = React.useRef<HTMLButtonElement | null>(null);
|
|
const [anchorEl, setAnchorEl] = React.useState<HTMLButtonElement | null>(
|
|
null
|
|
);
|
|
const { flow } = props;
|
|
|
|
const handleClose = () => {
|
|
setAnchorEl(null);
|
|
};
|
|
const onContextMenuClick = (event: React.MouseEvent) => {
|
|
event.preventDefault();
|
|
event.stopPropagation();
|
|
event.nativeEvent.stopImmediatePropagation();
|
|
setAnchorEl(contextButtonRef.current);
|
|
};
|
|
|
|
const createdAt = DateTime.fromMillis(parseInt(flow.createdAt, 10));
|
|
const updatedAt = DateTime.fromMillis(parseInt(flow.updatedAt, 10));
|
|
const isUpdated = updatedAt > createdAt;
|
|
const relativeCreatedAt = createdAt.toRelative();
|
|
const relativeUpdatedAt = updatedAt.toRelative();
|
|
|
|
return (
|
|
<>
|
|
<Card sx={{ mb: 1 }} data-test="flow-row">
|
|
<CardActionArea
|
|
component={Link}
|
|
to={URLS.FLOW(flow.id)}
|
|
data-test="card-action-area"
|
|
>
|
|
<CardContent>
|
|
<Apps direction="row" gap={1} sx={{ gridArea: 'apps' }}>
|
|
<FlowAppIcons steps={flow.steps} />
|
|
</Apps>
|
|
|
|
<Title
|
|
justifyContent="center"
|
|
alignItems="flex-start"
|
|
spacing={1}
|
|
sx={{ gridArea: 'title' }}
|
|
>
|
|
<Typography variant="h6" noWrap>
|
|
{flow?.name}
|
|
</Typography>
|
|
|
|
<Typography variant="caption">
|
|
{isUpdated &&
|
|
formatMessage('flow.updatedAt', {
|
|
datetime: relativeUpdatedAt,
|
|
})}
|
|
{!isUpdated &&
|
|
formatMessage('flow.createdAt', {
|
|
datetime: relativeCreatedAt,
|
|
})}
|
|
</Typography>
|
|
</Title>
|
|
|
|
<ContextMenu>
|
|
<Chip
|
|
size="small"
|
|
color={getFlowStatusColor(flow?.status)}
|
|
variant={flow?.active ? 'filled' : 'outlined'}
|
|
label={formatMessage(getFlowStatusTranslationKey(flow?.status))}
|
|
/>
|
|
|
|
<IconButton
|
|
size="large"
|
|
color="inherit"
|
|
aria-label="open context menu"
|
|
ref={contextButtonRef}
|
|
onClick={onContextMenuClick}
|
|
>
|
|
<MoreHorizIcon />
|
|
</IconButton>
|
|
</ContextMenu>
|
|
</CardContent>
|
|
</CardActionArea>
|
|
</Card>
|
|
|
|
{anchorEl && (
|
|
<FlowContextMenu
|
|
flowId={flow.id}
|
|
onClose={handleClose}
|
|
anchorEl={anchorEl}
|
|
/>
|
|
)}
|
|
</>
|
|
);
|
|
}
|