Skip to content

feat(aci): add monitor config form #90501

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 38 commits into from
May 16, 2025
Merged
Show file tree
Hide file tree
Changes from 32 commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
79163fc
giant demo mess
natemoo-re Apr 18, 2025
72af9dd
chore: data
natemoo-re Apr 21, 2025
4e10a79
chore: data
natemoo-re Apr 21, 2025
906f004
ref(aci): create mock chart component
natemoo-re Apr 28, 2025
99210a9
:hammer_and_wrench: apply pre-commit fixes
getsantry[bot] Apr 28, 2025
912e83d
chore: remove mocks
natemoo-re May 6, 2025
05c87b6
fix(aci): form display
natemoo-re May 6, 2025
e9347ed
feat(aci): fix detector query util
natemoo-re May 6, 2025
2371be4
fix(aci): cleanup detectors lost
natemoo-re May 6, 2025
58e1d67
fix(aci): use detector query
natemoo-re May 6, 2025
87f018a
:hammer_and_wrench: apply pre-commit fixes
getsantry[bot] May 12, 2025
636349c
fix(lint): appease eslint
natemoo-re May 13, 2025
9128d7c
chore(types): add readonly DataCondition type
natemoo-re May 13, 2025
f8dccda
chore(types): add readonly DataCondition type
natemoo-re May 13, 2025
f96d00f
chore(fixtures): allow all DataCondition properties
natemoo-re May 13, 2025
e3c221d
fix(hooks): unify hooks files
natemoo-re May 13, 2025
0c25cfb
:hammer_and_wrench: apply pre-commit fixes
getsantry[bot] May 13, 2025
8d27241
Revert ":hammer_and_wrench: apply pre-commit fixes"
natemoo-re May 14, 2025
e40b590
fix(aci): container sizing
natemoo-re May 15, 2025
a572e9a
chore(aci): refactor detector hooks
natemoo-re May 15, 2025
1d2a997
chore(aci): refactor automation hooks
natemoo-re May 15, 2025
f2aced1
fix(aci): header layout
natemoo-re May 15, 2025
8509c4d
fix(aci): anomaly detection fields
natemoo-re May 15, 2025
0ba6e16
fix(aci): update monitor form logic
natemoo-re May 15, 2025
31e69bc
chore(aci): creator -> owner
natemoo-re May 16, 2025
a660080
chore(aci): remove comments
natemoo-re May 16, 2025
054fca5
chore(aci): add comment
natemoo-re May 16, 2025
0f23ff9
chore(aci): add projectIds from hook
natemoo-re May 16, 2025
87a4c62
chore(aci): adjust types date -> string
natemoo-re May 16, 2025
39c623c
fix(aci): use relaxed date type
natemoo-re May 16, 2025
0420a82
fix(aci): replace chart mock with spinner
natemoo-re May 16, 2025
8a5b4f4
chore(aci): add data source mock
natemoo-re May 16, 2025
92ed66c
fix(aci): use translated strings
natemoo-re May 16, 2025
82efb48
ref(aci): simplify styles
natemoo-re May 16, 2025
b687c70
ref(aci): use details pathname helper
natemoo-re May 16, 2025
e13ba68
Update static/app/views/detectors/edit.tsx
natemoo-re May 16, 2025
22a010d
ref(aci): use project slugs
natemoo-re May 16, 2025
7946e35
Merge branch 'master' into aci/nm/monitor-settings
natemoo-re May 16, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ export default function PriorityControl({
flexibleControlStateSize
size="sm"
suffix="s"
placeholder="0"
// empty string required to keep this as a controlled input
value={thresholds[PriorityLevel.MEDIUM] ?? ''}
onChange={threshold => setMediumThreshold(Number(threshold))}
Expand All @@ -96,6 +97,7 @@ export default function PriorityControl({
flexibleControlStateSize
size="sm"
suffix="s"
placeholder="0"
// empty string required to keep this as a controlled input
value={thresholds[PriorityLevel.HIGH] ?? ''}
onChange={threshold => setHighThreshold(Number(threshold))}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,10 @@ export function ActionCell({actions, disabled}: ActionCellProps) {
</Flex>
);
}

const actionsList = actions
.map(action => ActionMetadata[action]?.name)
.filter(x => x)
.join(', ');

return (
<ActionContainer align="center" gap={space(0.75)}>
<IconContainer>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ const links: Record<
};

export function ConnectionCell({
ids: items,
ids: items = [],
type,
disabled = false,
className,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export default storyBook('Grid Cell Components', story => {
},
openIssues: 3,
creator: '1',
type: 'trace',
type: 'uptime',
},
{
title: {
Expand Down Expand Up @@ -95,7 +95,7 @@ export default storyBook('Grid Cell Components', story => {
},
actions: [ActionType.SLACK, ActionType.DISCORD, ActionType.EMAIL],
creator: 'sentry',
type: 'errors',
type: 'uptime',
timeAgo: null,
linkedItems: {
ids: [],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import TimeSince from 'sentry/components/timeSince';
import {EmptyCell} from 'sentry/components/workflowEngine/gridCell/emptyCell';

type TimeAgoCellProps = {
date?: Date;
date?: string | Date;
};

export function TimeAgoCell({date}: TimeAgoCellProps) {
Expand Down
7 changes: 3 additions & 4 deletions static/app/components/workflowEngine/layout/actions.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import {createContext, useContext} from 'react';

import {ButtonBar} from 'sentry/components/core/button/buttonBar';
import {Flex} from 'sentry/components/container/flex';
import {HeaderActions} from 'sentry/components/layouts/thirds';
import {space} from 'sentry/styles/space';

const ActionContext = createContext<React.ReactNode | undefined>(undefined);

Expand All @@ -26,9 +27,7 @@ export function ActionsFromContext() {
}
return (
<HeaderActions>
<ButtonBar merged={false} gap={1}>
{actions}
</ButtonBar>
<Flex gap={space(1)}>{actions}</Flex>
</HeaderActions>
);
}
2 changes: 1 addition & 1 deletion static/app/components/workflowEngine/layout/detail.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ function DetailLayout({children, project}: WorkflowEngineDetailLayoutProps) {
const title = useDocumentTitle();
return (
<StyledPage>
<Layout.Header>
<Layout.Header unified>
<Layout.HeaderContent>
<BreadcrumbsFromContext />
<Layout.Title>{title}</Layout.Title>
Expand Down
8 changes: 2 additions & 6 deletions static/app/components/workflowEngine/layout/edit.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ function EditLayout({children, onTitleChange}: WorkflowEngineEditLayoutProps) {
const title = useDocumentTitle();
return (
<Layout.Page>
<StyledHeader>
<Layout.Header unified>
<Layout.HeaderContent>
<BreadcrumbsFromContext />
<Layout.Title>
Expand All @@ -37,16 +37,12 @@ function EditLayout({children, onTitleChange}: WorkflowEngineEditLayoutProps) {
</Layout.Title>
</Layout.HeaderContent>
<ActionsFromContext />
</StyledHeader>
</Layout.Header>
<Body>{children}</Body>
</Layout.Page>
);
}

const StyledHeader = styled(Layout.Header)`
background: ${p => p.theme.background};
`;

const Body = styled('div')`
display: flex;
flex-direction: column;
Expand Down
2 changes: 1 addition & 1 deletion static/app/components/workflowEngine/layout/list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ function WorkflowEngineListLayout({children}: WorkflowEngineListLayoutProps) {
const title = useDocumentTitle();
return (
<Layout.Page>
<Layout.Header>
<Layout.Header unified>
<Layout.HeaderContent>
<Layout.Title>{title}</Layout.Title>
</Layout.HeaderContent>
Expand Down
5 changes: 3 additions & 2 deletions static/app/components/workflowEngine/ui/container.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,13 @@ export const Container = styled('div')`
flex-direction: column;
gap: ${space(2)};
justify-content: flex-start;
background-color: ${p => p.theme.backgroundSecondary};
background-color: ${p => p.theme.background};
border: 1px solid ${p => p.theme.translucentBorder};
border-radius: ${p => p.theme.borderRadius};
padding: ${space(1.5)};

@media (max-width: ${p => p.theme.breakpoints.large}) {
width: fit-content;
min-width: fit-content;
flex: 1;
}
`;
1 change: 1 addition & 0 deletions static/app/components/workflowEngine/ui/footer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {space} from 'sentry/styles/space';
export const StickyFooter = styled('div')`
position: sticky;
margin-top: auto;
margin-bottom: -56px;
bottom: 0;
right: 0;
width: 100%;
Expand Down
14 changes: 12 additions & 2 deletions static/app/components/workflowEngine/ui/section.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,28 @@ import {space} from 'sentry/styles/space';
type SectionProps = {
children: React.ReactNode;
title: string;
description?: string;
};

export default function Section({children, title}: SectionProps) {
export default function Section({children, title, description}: SectionProps) {
return (
<Flex column gap={space(1)}>
<SectionHeading>{title}</SectionHeading>
{description && <SectionDescription>{description}</SectionDescription>}
{children}
</Flex>
);
}

const SectionHeading = styled('h4')`
export const SectionHeading = styled('h4')`
font-size: ${p => p.theme.fontSizeLarge};
font-weight: ${p => p.theme.fontWeightBold};
margin: 0;
`;

export const SectionDescription = styled('p')`
font-size: ${p => p.theme.fontSizeMedium};
font-weight: ${p => p.theme.fontWeightNormal};
color: ${p => p.theme.subText};
margin: 0;
`;
2 changes: 1 addition & 1 deletion static/app/plugins/components/pluginIcon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ const PLUGIN_ICONS = {
} satisfies Record<string, string>;

export interface PluginIconProps extends React.RefAttributes<HTMLDivElement> {
pluginId: string | keyof typeof PLUGIN_ICONS;
pluginId: keyof typeof PLUGIN_ICONS | (string & {});
/**
* @default 20
*/
Expand Down
4 changes: 2 additions & 2 deletions static/app/types/workflowEngine/automations.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type {DataConditionGroup} from 'sentry/types/workflowEngine/dataConditions';

interface NewAutomation {
export interface NewAutomation {
actionFilters: DataConditionGroup[];
detectorIds: string[];
name: string;
Expand All @@ -10,5 +10,5 @@ interface NewAutomation {

export interface Automation extends Readonly<NewAutomation> {
readonly id: string;
readonly lastTriggered: Date;
readonly lastTriggered: string;
}
4 changes: 4 additions & 0 deletions static/app/types/workflowEngine/dataConditions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,10 @@ export interface NewDataCondition {
condition_result?: any;
}

export interface DataCondition extends Readonly<NewDataCondition> {
readonly id: string;
}

export interface DataConditionGroup {
conditions: NewDataCondition[];
id: string;
Expand Down
11 changes: 6 additions & 5 deletions static/app/types/workflowEngine/detectors.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@ import type {
} from 'sentry/types/workflowEngine/dataConditions';

export type DetectorType =
| 'metric'
| 'crons'
| 'errors'
| 'metric'
| 'performance'
| 'trace'
| 'replay'
| 'trace'
| 'uptime';

interface NewDetector {
Expand All @@ -24,8 +25,8 @@ interface NewDetector {

export interface Detector extends Readonly<NewDetector> {
readonly createdBy: string;
readonly dateCreated: Date;
readonly dateUpdated: Date;
readonly dateCreated: string;
readonly dateUpdated: string;
readonly id: string;
readonly lastTriggered: Date;
readonly lastTriggered: string;
}
1 change: 1 addition & 0 deletions static/app/utils/useParams.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ type ParamKeys =
| 'groupId'
| 'id'
| 'installationId'
| 'detectorId'
| 'integrationSlug'
| 'issueId'
| 'memberId'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,18 @@ import styled from '@emotion/styled';
import {Flex} from 'sentry/components/container/flex';
import {Checkbox} from 'sentry/components/core/checkbox';
import InteractionStateLayer from 'sentry/components/interactionStateLayer';
import {ProjectList} from 'sentry/components/projectList';
import {ActionCell} from 'sentry/components/workflowEngine/gridCell/actionCell';
import AutomationTitleCell from 'sentry/components/workflowEngine/gridCell/automationTitleCell';
import {ConnectionCell} from 'sentry/components/workflowEngine/gridCell/connectionCell';
import {TimeAgoCell} from 'sentry/components/workflowEngine/gridCell/timeAgoCell';
import {space} from 'sentry/styles/space';
import type {Automation} from 'sentry/types/workflowEngine/automations';
import useOrganization from 'sentry/utils/useOrganization';
import {useAutomationActions} from 'sentry/views/automations/hooks/utils';
import {
useAutomationActions,
useAutomationProjectIds,
} from 'sentry/views/automations/hooks/utils';
import {makeAutomationDetailsPathname} from 'sentry/views/automations/pathnames';

type AutomationListRowProps = {
Expand All @@ -28,6 +32,7 @@ export function AutomationListRow({
const organization = useOrganization();
const actions = useAutomationActions(automation);
const {id, name, disabled, lastTriggered, detectorIds = []} = automation;
const projectIds = useAutomationProjectIds(automation);
return (
<RowWrapper disabled={disabled}>
<InteractionStateLayer />
Expand All @@ -51,6 +56,9 @@ export function AutomationListRow({
<CellWrapper className="action">
<ActionCell actions={actions} disabled={disabled} />
</CellWrapper>
<CellWrapper className="projects">
<ProjectList projectSlugs={projectIds} />
</CellWrapper>
<CellWrapper className="connected-monitors">
<ConnectionCell ids={detectorIds} type="detector" disabled={disabled} />
</CellWrapper>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,17 @@ function AutomationListTable() {
<HeaderDivider />
<Heading>{t('Actions')}</Heading>
</Flex>
<Flex className="projects">
<HeaderDivider />
<Heading>{t('Projects')}</Heading>
</Flex>
<Flex className="connected-monitors">
<HeaderDivider />
<Heading>{t('Monitors')}</Heading>
</Flex>
</StyledPanelHeader>
<PanelBody>
{isLoading ? <LoadingIndicator /> : null}

{automations.map(automation => (
<AutomationListRow
key={automation.id}
Expand Down
4 changes: 2 additions & 2 deletions static/app/views/automations/detail.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ function HistoryAndConnectedMonitors() {

function Details() {
return (
<div>
<Flex column gap={space(3)}>
<Flex column gap={space(1)}>
<SectionHeading>{t('Last Triggered')}</SectionHeading>
<span>
Expand Down Expand Up @@ -78,7 +78,7 @@ function Details() {
<KeyValueTableRow keyName={t('Team')} value="Platform" />
</KeyValueTable>
</Flex>
</div>
</Flex>
);
}

Expand Down
5 changes: 5 additions & 0 deletions static/app/views/automations/hooks/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,8 @@ export function useAutomationsQuery(_options: UseAutomationsQueryOptions = {}) {
retry: false,
});
}

export const makeAutomationQueryKey = (
orgSlug: string,
automationId = ''
): [url: string] => [`/organizations/${orgSlug}/workflows/${automationId}/`];
7 changes: 7 additions & 0 deletions static/app/views/automations/hooks/utils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {useState} from 'react';

import type {ActionType} from 'sentry/types/workflowEngine/actions';
import type {Automation} from 'sentry/types/workflowEngine/automations';
import {useDetectorQueriesByIds} from 'sentry/views/detectors/hooks';

export function useAutomationActions(automation: Automation): ActionType[] {
return [
Expand Down Expand Up @@ -47,3 +48,9 @@ export function useConnectedIds({storageKey, initialIds = []}: UseConnectedIdsPr
}

export const NEW_AUTOMATION_CONNECTED_IDS_KEY = 'new-automation-connected-ids';
export function useAutomationProjectIds(automation: Automation): string[] {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

making x requests to get project ids seems kinda weird. Are we using this anywhere?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to get connected projects for the automation list view

Screenshot 2025-05-15 at 3 27 50 PM

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't the project ids exist in the list returned from that api

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah we've had a lot of back-and-forth discussion on this data model... it is weird! automations aren't associated directly with projects but only to detectors which are then associated with projects. so there's a lot of hoop jumping just to display these project badges, which would also be surfaced in the connected monitors tooltip.

const queries = useDetectorQueriesByIds(automation.detectorIds);
return [
...new Set(queries.map(query => query.data?.projectId).filter(x => x)),
] as string[];
}
2 changes: 1 addition & 1 deletion static/app/views/automations/list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export default function AutomationsList() {
function TableHeader() {
return (
<Flex gap={space(2)}>
<ProjectPageFilter />
<ProjectPageFilter size="md" />
<div style={{flexGrow: 1}}>
<SearchBar placeholder={t('Search for events, users, tags, and more')} />
</div>
Expand Down
8 changes: 4 additions & 4 deletions static/app/views/detectors/components/detectorListRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ interface DetectorListRowProps {
}

export function DetectorListRow({
detector: {workflowIds, id, name, disabled, projectId},
detector: {workflowIds, createdBy, id, projectId, name, disabled, type},
handleSelect,
selected,
}: DetectorListRowProps) {
Expand Down Expand Up @@ -51,16 +51,16 @@ export function DetectorListRow({
<StyledGraphCell />
</Flex>
<CellWrapper className="type">
<TypeCell type="errors" />
<TypeCell type={type} />
</CellWrapper>
<CellWrapper className="last-issue">
<StyledIssueCell
group={issues.length > 0 ? issues[0] : undefined}
disabled={disabled}
/>
</CellWrapper>
<CellWrapper className="owner">
<UserCell user="sentry" />
<CellWrapper className="creator">
<UserCell user={createdBy ?? 'sentry'} />
</CellWrapper>
<CellWrapper className="connected-automations">
<ConnectionCell ids={workflowIds} type="workflow" disabled={disabled} />
Expand Down
Loading
Loading