Skip to content

Commit

Permalink
ref(tsc): convert projectServiceHooks to FC (#83884)
Browse files Browse the repository at this point in the history
  • Loading branch information
michellewzhang authored Jan 24, 2025
1 parent 01a8514 commit 9a8694a
Showing 1 changed file with 97 additions and 87 deletions.
184 changes: 97 additions & 87 deletions static/app/views/settings/project/projectServiceHooks.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@ import {
clearIndicators,
} from 'sentry/actionCreators/indicator';
import {LinkButton} from 'sentry/components/button';
import DeprecatedAsyncComponent from 'sentry/components/deprecatedAsyncComponent';
import EmptyMessage from 'sentry/components/emptyMessage';
import FieldGroup from 'sentry/components/forms/fieldGroup';
import Link from 'sentry/components/links/link';
import LoadingError from 'sentry/components/loadingError';
import LoadingIndicator from 'sentry/components/loadingIndicator';
import Panel from 'sentry/components/panels/panel';
import PanelAlert from 'sentry/components/panels/panelAlert';
import PanelBody from 'sentry/components/panels/panelBody';
Expand All @@ -19,8 +20,15 @@ import Truncate from 'sentry/components/truncate';
import {IconAdd} from 'sentry/icons';
import {t} from 'sentry/locale';
import type {ServiceHook} from 'sentry/types/integrations';
import type {RouteComponentProps} from 'sentry/types/legacyReactRouter';
import type {Organization} from 'sentry/types/organization';
import {
setApiQueryData,
useApiQuery,
useMutation,
useQueryClient,
} from 'sentry/utils/queryClient';
import useApi from 'sentry/utils/useApi';
import useOrganization from 'sentry/utils/useOrganization';
import {useParams} from 'sentry/utils/useParams';
import withOrganization from 'sentry/utils/withOrganization';
import SettingsPageHeader from 'sentry/views/settings/components/settingsPageHeader';

Expand Down Expand Up @@ -57,69 +65,76 @@ function ServiceHookRow({orgId, projectId, hook, onToggleActive}: RowProps) {
);
}

type Props = RouteComponentProps<{projectId: string}, {}> & {
organization: Organization;
};

type State = {
hookList: null | ServiceHook[];
} & DeprecatedAsyncComponent['state'];
function ProjectServiceHooks() {
const organization = useOrganization();
const {projectId} = useParams<{projectId: string}>();
const api = useApi({persistInFlight: true});
const queryClient = useQueryClient();

class ProjectServiceHooks extends DeprecatedAsyncComponent<Props, State> {
getEndpoints(): ReturnType<DeprecatedAsyncComponent['getEndpoints']> {
const {organization, params} = this.props;
const projectId = params.projectId;
return [['hookList', `/projects/${organization.slug}/${projectId}/hooks/`]];
}
const {
data: hookList,
isPending,
isError,
refetch,
} = useApiQuery<ServiceHook[]>([`/projects/${organization.slug}/${projectId}/hooks/`], {
staleTime: 0,
});

onToggleActive = (hook: ServiceHook) => {
const {organization, params} = this.props;
const {hookList} = this.state;
if (!hookList) {
return;
}
const onToggleActiveMutation = useMutation({
mutationFn: ({hook}: {hook: ServiceHook}) => {
return api.requestPromise(
`/projects/${organization.slug}/${projectId}/hooks/${hook.id}/`,
{
method: 'PUT',
data: {
isActive: hook.status !== 'active',
},
}
);
},
onMutate: () => {
addLoadingMessage(t('Saving changes\u2026'));
},
onSuccess: data => {
clearIndicators();
setApiQueryData<ServiceHook[]>(
queryClient,
[`/projects/${organization.slug}/${projectId}/hooks/`],
oldHookList => {
return oldHookList.map(h => {
if (h.id === data.id) {
return {
...h,
...data,
};
}
return h;
});
}
);
},
onError: () => {
addErrorMessage(t('Unable to remove application. Please try again.'));
},
});

addLoadingMessage(t('Saving changes\u2026'));
if (isPending) {
return <LoadingIndicator />;
}

this.api.request(
`/projects/${organization.slug}/${params.projectId}/hooks/${hook.id}/`,
{
method: 'PUT',
data: {
isActive: hook.status !== 'active',
},
success: data => {
clearIndicators();
this.setState({
hookList: hookList.map(h => {
if (h.id === data.id) {
return {
...h,
...data,
};
}
return h;
}),
});
},
error: () => {
addErrorMessage(t('Unable to remove application. Please try again.'));
},
}
);
};
if (isError) {
return <LoadingError onRetry={refetch} />;
}

renderEmpty() {
const renderEmpty = () => {
return (
<EmptyMessage>
{t('There are no service hooks associated with this project.')}
</EmptyMessage>
);
}

renderResults() {
const {organization, params} = this.props;
};

const renderResults = () => {
return (
<Fragment>
<PanelHeader key="header">{t('Service Hook')}</PanelHeader>
Expand All @@ -129,48 +144,43 @@ class ProjectServiceHooks extends DeprecatedAsyncComponent<Props, State> {
'Service Hooks are an early adopter preview feature and will change in the future.'
)}
</PanelAlert>
{this.state.hookList?.map(hook => (
{hookList?.map(hook => (
<ServiceHookRow
key={hook.id}
orgId={organization.slug}
projectId={params.projectId}
projectId={projectId}
hook={hook}
onToggleActive={this.onToggleActive.bind(this, hook)}
onToggleActive={() => onToggleActiveMutation.mutate({hook})}
/>
))}
</PanelBody>
</Fragment>
);
}

renderBody() {
const {hookList} = this.state;
const body =
hookList && hookList.length > 0 ? this.renderResults() : this.renderEmpty();
};

const {organization, params} = this.props;
const body = hookList && hookList.length > 0 ? renderResults() : renderEmpty();

return (
<Fragment>
<SettingsPageHeader
title={t('Service Hooks')}
action={
organization.access.includes('project:write') ? (
<LinkButton
data-test-id="new-service-hook"
to={`/settings/${organization.slug}/projects/${params.projectId}/hooks/new/`}
size="sm"
priority="primary"
icon={<IconAdd isCircled />}
>
{t('Create New Hook')}
</LinkButton>
) : null
}
/>
<Panel>{body}</Panel>
</Fragment>
);
}
return (
<Fragment>
<SettingsPageHeader
title={t('Service Hooks')}
action={
organization.access.includes('project:write') ? (
<LinkButton
data-test-id="new-service-hook"
to={`/settings/${organization.slug}/projects/${projectId}/hooks/new/`}
size="sm"
priority="primary"
icon={<IconAdd isCircled />}
>
{t('Create New Hook')}
</LinkButton>
) : null
}
/>
<Panel>{body}</Panel>
</Fragment>
);
}

export default withOrganization(ProjectServiceHooks);

0 comments on commit 9a8694a

Please sign in to comment.