index.tsx 3.0 KB

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