|
@@ -4,7 +4,9 @@ import {css} from '@emotion/react';
|
|
|
import styled from '@emotion/styled';
|
|
|
|
|
|
import {Button} from 'sentry/components/button';
|
|
|
-import {tct} from 'sentry/locale';
|
|
|
+import {DropdownMenu} from 'sentry/components/dropdownMenu';
|
|
|
+import {IconEllipsis} from 'sentry/icons';
|
|
|
+import {t, tct} from 'sentry/locale';
|
|
|
import {fadeIn} from 'sentry/styles/animations';
|
|
|
import {space} from 'sentry/styles/space';
|
|
|
import useOrganization from 'sentry/utils/useOrganization';
|
|
@@ -19,6 +21,7 @@ import {MonitorBucket} from './types';
|
|
|
interface Props extends Omit<CheckInTimelineProps, 'bucketedData' | 'environment'> {
|
|
|
monitor: Monitor;
|
|
|
bucketedData?: MonitorBucket[];
|
|
|
+ onDeleteEnvironment?: (env: string) => void;
|
|
|
/**
|
|
|
* Whether only one monitor is being rendered in a larger view with this component
|
|
|
* turns off things like zebra striping, hover effect, and showing monitor name
|
|
@@ -32,6 +35,7 @@ export function TimelineTableRow({
|
|
|
monitor,
|
|
|
bucketedData,
|
|
|
singleMonitorView,
|
|
|
+ onDeleteEnvironment,
|
|
|
...timelineProps
|
|
|
}: Props) {
|
|
|
const [isExpanded, setExpanded] = useState(
|
|
@@ -51,6 +55,28 @@ export function TimelineTableRow({
|
|
|
monitor.status === MonitorStatus.DISABLED ? MonitorStatus.DISABLED : status;
|
|
|
return (
|
|
|
<EnvWithStatus key={name}>
|
|
|
+ {onDeleteEnvironment && (
|
|
|
+ <DropdownMenu
|
|
|
+ size="sm"
|
|
|
+ trigger={triggerProps => (
|
|
|
+ <EnvActionButton
|
|
|
+ {...triggerProps}
|
|
|
+ aria-label={t('Monitor environment actions')}
|
|
|
+ size="zero"
|
|
|
+ icon={<IconEllipsis size="sm" />}
|
|
|
+ />
|
|
|
+ )}
|
|
|
+ items={[
|
|
|
+ {
|
|
|
+ label: t('Delete Environment'),
|
|
|
+ key: 'delete',
|
|
|
+ onAction: () => {
|
|
|
+ onDeleteEnvironment(name);
|
|
|
+ },
|
|
|
+ },
|
|
|
+ ]}
|
|
|
+ />
|
|
|
+ )}
|
|
|
<MonitorEnvLabel status={envStatus}>{name}</MonitorEnvLabel>
|
|
|
{statusIconColorMap[envStatus].icon}
|
|
|
</EnvWithStatus>
|
|
@@ -140,17 +166,25 @@ const Schedule = styled('small')`
|
|
|
|
|
|
const MonitorEnvContainer = styled('div')`
|
|
|
display: flex;
|
|
|
- padding: ${space(3)} ${space(2)};
|
|
|
+ padding: 0 ${space(2)};
|
|
|
flex-direction: column;
|
|
|
- gap: ${space(4)};
|
|
|
border-right: 1px solid ${p => p.theme.innerBorder};
|
|
|
text-align: right;
|
|
|
`;
|
|
|
|
|
|
+const EnvActionButton = styled(Button)`
|
|
|
+ padding: ${space(0.5)} ${space(1)};
|
|
|
+ display: none;
|
|
|
+`;
|
|
|
+
|
|
|
const EnvWithStatus = styled('div')`
|
|
|
display: flex;
|
|
|
- gap: ${space(1)};
|
|
|
+ gap: ${space(0.5)};
|
|
|
align-items: center;
|
|
|
+
|
|
|
+ &:hover ${EnvActionButton} {
|
|
|
+ display: block;
|
|
|
+ }
|
|
|
`;
|
|
|
|
|
|
const MonitorEnvLabel = styled('div')<{status: MonitorStatus}>`
|
|
@@ -158,6 +192,8 @@ const MonitorEnvLabel = styled('div')<{status: MonitorStatus}>`
|
|
|
overflow: hidden;
|
|
|
white-space: nowrap;
|
|
|
flex: 1;
|
|
|
+
|
|
|
+ padding: ${space(2)} 0;
|
|
|
color: ${p => p.theme[statusIconColorMap[p.status].color]};
|
|
|
`;
|
|
|
|