index.tsx 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. import {
  2. addErrorMessage,
  3. addLoadingMessage,
  4. addSuccessMessage,
  5. } from 'sentry/actionCreators/indicator';
  6. import {Button} from 'sentry/components/button';
  7. import EmptyMessage from 'sentry/components/emptyMessage';
  8. import LoadingError from 'sentry/components/loadingError';
  9. import LoadingIndicator from 'sentry/components/loadingIndicator';
  10. import Panel from 'sentry/components/panels/panel';
  11. import PanelBody from 'sentry/components/panels/panelBody';
  12. import PanelHeader from 'sentry/components/panels/panelHeader';
  13. import SentryDocumentTitle from 'sentry/components/sentryDocumentTitle';
  14. import {IconAdd} from 'sentry/icons';
  15. import {t} from 'sentry/locale';
  16. import type {RouteComponentProps} from 'sentry/types/legacyReactRouter';
  17. import type {ApiApplication} from 'sentry/types/user';
  18. import {isDemoModeEnabled} from 'sentry/utils/demoMode';
  19. import {setApiQueryData, useApiQuery, useQueryClient} from 'sentry/utils/queryClient';
  20. import useApi from 'sentry/utils/useApi';
  21. import Row from 'sentry/views/settings/account/apiApplications/row';
  22. import SettingsPageHeader from 'sentry/views/settings/components/settingsPageHeader';
  23. const ROUTE_PREFIX = '/settings/account/api/';
  24. type Props = RouteComponentProps;
  25. function ApiApplications({router}: Props) {
  26. const api = useApi();
  27. const queryClient = useQueryClient();
  28. const ENDPOINT = '/api-applications/';
  29. const {
  30. data: appList = [],
  31. isLoading,
  32. isError,
  33. refetch,
  34. } = useApiQuery<ApiApplication[]>([ENDPOINT], {
  35. staleTime: 0,
  36. enabled: !isDemoModeEnabled(),
  37. });
  38. if (isLoading) {
  39. return <LoadingIndicator />;
  40. }
  41. if (isError) {
  42. return <LoadingError onRetry={refetch} />;
  43. }
  44. const handleCreateApplication = async () => {
  45. addLoadingMessage();
  46. try {
  47. const app = await api.requestPromise(ENDPOINT, {
  48. method: 'POST',
  49. });
  50. addSuccessMessage(t('Created a new API Application'));
  51. router.push(`${ROUTE_PREFIX}applications/${app.id}/`);
  52. } catch {
  53. addErrorMessage(t('Unable to remove application. Please try again.'));
  54. }
  55. };
  56. const handleRemoveApplication = (app: ApiApplication) => {
  57. setApiQueryData<any>(queryClient, [ENDPOINT], (oldAppList: any) =>
  58. oldAppList.filter((a: any) => a.id !== app.id)
  59. );
  60. };
  61. const isEmpty = appList.length === 0;
  62. return (
  63. <SentryDocumentTitle title={t('API Applications')}>
  64. <SettingsPageHeader
  65. title="API Applications"
  66. action={
  67. <Button
  68. priority="primary"
  69. size="sm"
  70. onClick={handleCreateApplication}
  71. icon={<IconAdd isCircled />}
  72. >
  73. {t('Create New Application')}
  74. </Button>
  75. }
  76. />
  77. <Panel>
  78. <PanelHeader>{t('Application Name')}</PanelHeader>
  79. <PanelBody>
  80. {!isEmpty ? (
  81. appList.map(app => (
  82. <Row key={app.id} app={app} onRemove={handleRemoveApplication} />
  83. ))
  84. ) : (
  85. <EmptyMessage>{t("You haven't created any applications yet.")}</EmptyMessage>
  86. )}
  87. </PanelBody>
  88. </Panel>
  89. </SentryDocumentTitle>
  90. );
  91. }
  92. export default ApiApplications;