diff --git a/static/app/views/settings/seer/overview/autofixOverviewSection.tsx b/static/app/views/settings/seer/overview/autofixOverviewSection.tsx index e198fdd13938b1..a3599266ca6b28 100644 --- a/static/app/views/settings/seer/overview/autofixOverviewSection.tsx +++ b/static/app/views/settings/seer/overview/autofixOverviewSection.tsx @@ -161,9 +161,7 @@ function AgentNameForm({ const preferredAgent = useFetchPreferredAgent({organization}); const codingAgentSelectOptions = useFetchAgentOptions({organization}); const codingAgentMutationOptions = getPreferredAgentMutationOptions({organization}); - const bulkMutateSelectedAgent = useBulkMutateSelectedAgent({ - projects: projects.filter(p => !projectsIdsWithPreferredAgent.has(p.id)), - }); + const bulkMutateSelectedAgent = useBulkMutateSelectedAgent(); const preferredAgentLabel = codingAgentSelectOptions.data?.find( o => o.value === preferredAgent.data @@ -225,7 +223,10 @@ function AgentNameForm({ onClick={async () => { if (preferredAgent.data) { setIsBulkMutatingAgent(true); - await bulkMutateSelectedAgent(preferredAgent.data); + await bulkMutateSelectedAgent( + projects.filter(p => !projectsIdsWithPreferredAgent.has(p.id)), + preferredAgent.data + ); setIsBulkMutatingAgent(false); } else { addErrorMessage(t('No coding agent integration found')); diff --git a/static/app/views/settings/seer/overview/utils/seerPreferredAgent.spec.ts b/static/app/views/settings/seer/overview/utils/seerPreferredAgent.spec.ts index 3097deb833d92b..c89d2958b08e19 100644 --- a/static/app/views/settings/seer/overview/utils/seerPreferredAgent.spec.ts +++ b/static/app/views/settings/seer/overview/utils/seerPreferredAgent.spec.ts @@ -295,11 +295,10 @@ describe('seerPreferredAgent', () => { const {result} = renderHookWithProviders(useBulkMutateSelectedAgent, { organization, - initialProps: {projects: [project]}, }); await act(async () => { - await result.current('seer'); + await result.current([project], 'seer'); }); expect(projectPutRequest).toHaveBeenCalledWith( @@ -328,11 +327,10 @@ describe('seerPreferredAgent', () => { const {result} = renderHookWithProviders(useBulkMutateSelectedAgent, { organization, - initialProps: {projects: [project]}, }); await act(async () => { - await result.current(integration); + await result.current([project], integration); }); expect(projectPutRequest).toHaveBeenCalledWith( @@ -368,10 +366,9 @@ describe('seerPreferredAgent', () => { const {result} = renderHookWithProviders(useBulkMutateSelectedAgent, { organization, - initialProps: {projects: [project]}, }); await act(async () => { - await result.current(integration); + await result.current([project], integration); }); expect(seerPreferencesPostRequest).toHaveBeenCalledWith( @@ -392,11 +389,10 @@ describe('seerPreferredAgent', () => { const {result} = renderHookWithProviders(useBulkMutateSelectedAgent, { organization, - initialProps: {projects: [project]}, }); await act(async () => { - await result.current('seer'); + await result.current([project], 'seer'); }); expect(updateSuccessSpy).toHaveBeenCalledWith({ @@ -427,11 +423,10 @@ describe('seerPreferredAgent', () => { const {result} = renderHookWithProviders(useBulkMutateSelectedAgent, { organization, - initialProps: {projects: [project]}, }); await act(async () => { - await result.current('seer'); + await result.current([project], 'seer'); }); expect(addErrorMessageSpy).toHaveBeenCalledWith( @@ -461,11 +456,10 @@ describe('seerPreferredAgent', () => { const {result} = renderHookWithProviders(useBulkMutateSelectedAgent, { organization, - initialProps: {projects: [project]}, }); await act(async () => { - await result.current('seer'); + await result.current([project], 'seer'); }); expect(addErrorMessageSpy).toHaveBeenCalledWith( diff --git a/static/app/views/settings/seer/overview/utils/seerPreferredAgent.ts b/static/app/views/settings/seer/overview/utils/seerPreferredAgent.ts index ce7bd5f611e09c..28b05d7b9ec485 100644 --- a/static/app/views/settings/seer/overview/utils/seerPreferredAgent.ts +++ b/static/app/views/settings/seer/overview/utils/seerPreferredAgent.ts @@ -101,7 +101,7 @@ export function getPreferredAgentMutationOptions({ }); } -export function useBulkMutateSelectedAgent({projects}: {projects: Project[]}) { +export function useBulkMutateSelectedAgent() { const organization = useOrganization(); const queryClient = useQueryClient(); const autofixSettingsQueryOptions = bulkAutofixAutomationSettingsInfiniteOptions({ @@ -109,7 +109,7 @@ export function useBulkMutateSelectedAgent({projects}: {projects: Project[]}) { }); return useCallback( - async (integration: PreferredAgent) => { + async (projects: Project[], integration: PreferredAgent) => { const results = await processInChunks({ items: projects, chunkSize: 15, @@ -184,6 +184,6 @@ export function useBulkMutateSelectedAgent({projects}: {projects: Project[]}) { } } }, - [projects, organization, queryClient, autofixSettingsQueryOptions.queryKey] + [organization, queryClient, autofixSettingsQueryOptions.queryKey] ); } diff --git a/static/gsApp/views/seerAutomation/components/projectTable/seerProjectTable.tsx b/static/gsApp/views/seerAutomation/components/projectTable/seerProjectTable.tsx index 3b40eb076883e7..d89259ee7cf182 100644 --- a/static/gsApp/views/seerAutomation/components/projectTable/seerProjectTable.tsx +++ b/static/gsApp/views/seerAutomation/components/projectTable/seerProjectTable.tsx @@ -280,6 +280,6 @@ const FiltersContainer = styled('div')` `; const SimpleTableWithColumns = styled(SimpleTable)` - grid-template-columns: 3fr minmax(300px, 1fr) repeat(2, max-content); + grid-template-columns: max-content 3fr minmax(300px, 1fr) repeat(2, max-content); overflow: visible; `; diff --git a/static/gsApp/views/seerAutomation/components/projectTable/seerProjectTableHeader.tsx b/static/gsApp/views/seerAutomation/components/projectTable/seerProjectTableHeader.tsx index ec4deaf2c2f872..b6db2925f8f820 100644 --- a/static/gsApp/views/seerAutomation/components/projectTable/seerProjectTableHeader.tsx +++ b/static/gsApp/views/seerAutomation/components/projectTable/seerProjectTableHeader.tsx @@ -16,6 +16,10 @@ import {parseQueryKey} from 'sentry/utils/api/apiQueryKey'; import type {Sort} from 'sentry/utils/discover/fields'; import {useListItemCheckboxContext} from 'sentry/utils/list/useListItemCheckboxState'; import {useOrganization} from 'sentry/utils/useOrganization'; +import { + useBulkMutateSelectedAgent, + useFetchAgentOptions, +} from 'sentry/views/settings/seer/overview/utils/seerPreferredAgent'; import {useCanWriteSettings} from 'getsentry/views/seerAutomation/components/useCanWriteSettings'; @@ -91,15 +95,18 @@ export function ProjectTableHeader({ [projects, selectedIds] ); + const agentOptions = useFetchAgentOptions({organization}); + const bulkMutateSelectedAgent = useBulkMutateSelectedAgent(); + return ( - {/* + - */} + {COLUMNS.map(({title, key, sortKey}) => ( + ({ + key: typeof value === 'object' ? value.provider : value, + label, + onAction: () => { + const selectedProjects = projects.filter(p => + projectIds.includes(p.id) + ); + bulkMutateSelectedAgent(selectedProjects, value); + }, + })) ?? [] + } + triggerLabel={t('Agent')} + /> diff --git a/static/gsApp/views/seerAutomation/components/projectTable/seerProjectTableRow.tsx b/static/gsApp/views/seerAutomation/components/projectTable/seerProjectTableRow.tsx index a2f6aaccb71dac..73c0b6404fd40c 100644 --- a/static/gsApp/views/seerAutomation/components/projectTable/seerProjectTableRow.tsx +++ b/static/gsApp/views/seerAutomation/components/projectTable/seerProjectTableRow.tsx @@ -1,3 +1,6 @@ +import styled from '@emotion/styled'; + +import {Checkbox} from '@sentry/scraps/checkbox'; import {InfoTip} from '@sentry/scraps/info'; import {Flex, Stack} from '@sentry/scraps/layout'; import {Link} from '@sentry/scraps/link'; @@ -15,6 +18,7 @@ import {SimpleTable} from 'sentry/components/tables/simpleTable'; import {IconWarning} from 'sentry/icons/iconWarning'; import {t, tct} from 'sentry/locale'; import type {Project} from 'sentry/types/project'; +import {useListItemCheckboxContext} from 'sentry/utils/list/useListItemCheckboxState'; import {useOrganization} from 'sentry/utils/useOrganization'; import { useAgentOptions, @@ -40,7 +44,7 @@ export function SeerProjectTableRow({ }: Props) { const organization = useOrganization(); const canWrite = useCanWriteSettings(); - // const {isSelected, toggleSelected} = useListItemCheckboxContext(); + const {isSelected, toggleSelected} = useListItemCheckboxContext(); const options = useAgentOptions({integrations: integrations ?? []}); const autofixAgent = useSelectedAgentFromBulkSettings({ @@ -66,7 +70,7 @@ export function SeerProjectTableRow({ return ( - {/* + toggleSelected(project.id)} /> - */} + @@ -194,11 +198,11 @@ export function SeerProjectTableRow({ ); } -// const CheckboxClickTarget = styled('label')` -// cursor: pointer; -// display: block; -// margin: -${p => p.theme.space.md}; -// padding: ${p => p.theme.space.md}; -// max-width: unset; -// line-height: 0; -// `; +const CheckboxClickTarget = styled('label')` + cursor: pointer; + display: block; + margin: -${p => p.theme.space.md}; + padding: ${p => p.theme.space.md}; + max-width: unset; + line-height: 0; +`;