123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156 |
- import {Fragment, useState} from 'react';
- import {addLoadingMessage, clearIndicators} from 'sentry/actionCreators/indicator';
- import type {ModalRenderProps} from 'sentry/actionCreators/modal';
- import NumberField from 'sentry/components/forms/fields/numberField';
- import SelectField from 'sentry/components/forms/fields/selectField';
- import Form from 'sentry/components/forms/form';
- import LoadingError from 'sentry/components/loadingError';
- import LoadingIndicator from 'sentry/components/loadingIndicator';
- import {tct} from 'sentry/locale';
- import type {IntegrationFeature} from 'sentry/types/integrations';
- import {useApiQuery, useMutation} from 'sentry/utils/queryClient';
- import type RequestError from 'sentry/utils/requestError/requestError';
- import useApi from 'sentry/utils/useApi';
- const fieldProps = {
- stacked: true,
- inline: false,
- flexibleControlStateSize: true,
- } as const;
- type Props = ModalRenderProps & {
- onAction: (data: any) => void;
- sentryAppData: any;
- };
- type SubmitQueryVariables = {
- data: Record<string, any>;
- onSubmitError: (error: any) => void;
- onSubmitSuccess: (response: Record<string, any>) => void;
- };
- type SubmitQueryResponse = Record<string, any>;
- // See Django reference for PositiveSmallIntegerField
- // (https://docs.djangoproject.com/en/3.2/ref/models/fields/#positivesmallintegerfield)
- const POPULARITY_MIN = 0;
- const POPULARITY_MAX = 32767;
- function SentryAppUpdateModal(props: Props) {
- const api = useApi({persistInFlight: true});
- const {sentryAppData, closeModal, Header, Body} = props;
- const [popularityError, setPopularityError] = useState(false);
- const onPopularityChange = (value: any) => {
- const popularity = parseInt(value, 10);
- const hasError =
- isNaN(popularity) || popularity < POPULARITY_MIN || popularity > POPULARITY_MAX;
- if (hasError) {
- setPopularityError(true);
- }
- };
- const onSubmitMutation = useMutation<
- SubmitQueryResponse,
- RequestError,
- SubmitQueryVariables
- >({
- mutationFn: ({data}: SubmitQueryVariables) => {
- return api.requestPromise(`/sentry-apps/${sentryAppData.slug}/`, {
- method: 'PUT',
- data,
- });
- },
- onMutate: () => {
- addLoadingMessage('Saving changes\u2026');
- },
- onSuccess: (data: Record<string, any>, {onSubmitSuccess}) => {
- clearIndicators();
- onSubmitSuccess(data);
- },
- onError: (err: RequestError, {onSubmitError}) => {
- clearIndicators();
- onSubmitError(err);
- },
- });
- const {
- data: featureData,
- isPending,
- isError,
- refetch,
- } = useApiQuery<IntegrationFeature[]>([`/integration-features/`], {
- staleTime: 0,
- });
- if (isPending) {
- return <LoadingIndicator />;
- }
- if (isError) {
- return <LoadingError onRetry={refetch} />;
- }
- const getFeatures = (): Array<[number, string]> => {
- if (!featureData) {
- return [];
- }
- return featureData.map(({featureId, featureGate}) => [
- featureId,
- featureGate.replace(/(^integrations-)/, ''),
- ]);
- };
- const getInitialData = () => {
- return {
- ...sentryAppData,
- features: sentryAppData?.featureData?.map(({featureId}: any) => featureId),
- };
- };
- return (
- <Fragment>
- <Header>Update Sentry App</Header>
- <Body>
- <Form
- submitDisabled={popularityError}
- onSubmit={(data, onSubmitSuccess, onSubmitError) =>
- onSubmitMutation.mutate({data, onSubmitSuccess, onSubmitError})
- }
- onSubmitSuccess={() => {
- closeModal();
- }}
- initialData={getInitialData()}
- >
- <NumberField
- {...fieldProps}
- name="popularity"
- label="New popularity"
- help={tct(
- 'Higher values will be more prominent on the integration directory. Only values between [POPULARITY_MIN] and [POPULARITY_MAX] are permitted.',
- {
- POPULARITY_MIN,
- POPULARITY_MAX,
- }
- )}
- onChange={onPopularityChange}
- defaultValue={sentryAppData.popularity}
- />
- <SelectField
- {...fieldProps}
- multiple
- name="features"
- label="Features"
- help="What features does this integration have?"
- choices={getFeatures()}
- required
- />
- </Form>
- </Body>
- </Fragment>
- );
- }
- export default SentryAppUpdateModal;
|