Browse Source

ref: convert projectKeys details index to FC (#59761)

Michelle Zhang 1 year ago
parent
commit
20c96efc11

+ 8 - 10
static/app/views/settings/project/projectKeys/details/index.spec.tsx

@@ -105,14 +105,14 @@ describe('ProjectKeyDetails', function () {
     );
   });
 
-  it('has stats box', function () {
-    expect(screen.getByText('Key Details')).toBeInTheDocument();
+  it('has stats box', async function () {
+    expect(await screen.findByText('Key Details')).toBeInTheDocument();
     expect(statsMock).toHaveBeenCalled();
   });
 
   it('changes name', async function () {
-    await userEvent.clear(screen.getByRole('textbox', {name: 'Name'}));
-    await userEvent.type(screen.getByRole('textbox', {name: 'Name'}), 'New Name');
+    await userEvent.clear(await screen.findByRole('textbox', {name: 'Name'}));
+    await userEvent.type(await screen.findByRole('textbox', {name: 'Name'}), 'New Name');
     await userEvent.tab();
 
     expect(putMock).toHaveBeenCalledWith(
@@ -126,7 +126,7 @@ describe('ProjectKeyDetails', function () {
   });
 
   it('disable and enables key', async function () {
-    await userEvent.click(screen.getByRole('checkbox', {name: 'Enabled'}));
+    await userEvent.click(await screen.findByRole('checkbox', {name: 'Enabled'}));
 
     expect(putMock).toHaveBeenCalledWith(
       `/projects/${org.slug}/${project.slug}/keys/${projectKeys[0].id}/`,
@@ -135,7 +135,7 @@ describe('ProjectKeyDetails', function () {
       })
     );
 
-    await userEvent.click(screen.getByRole('checkbox', {name: 'Enabled'}));
+    await userEvent.click(await screen.findByRole('checkbox', {name: 'Enabled'}));
 
     expect(putMock).toHaveBeenCalledWith(
       `/projects/${org.slug}/${project.slug}/keys/${projectKeys[0].id}/`,
@@ -146,11 +146,9 @@ describe('ProjectKeyDetails', function () {
   });
 
   it('revokes a key', async function () {
-    await userEvent.click(screen.getByRole('button', {name: 'Revoke Key'}));
-
+    await userEvent.click(await screen.findByRole('button', {name: 'Revoke Key'}));
     renderGlobalModal();
-    await userEvent.click(screen.getByTestId('confirm-button'));
-
+    await userEvent.click(await screen.findByTestId('confirm-button'));
     expect(deleteMock).toHaveBeenCalled();
   });
 });

+ 47 - 41
static/app/views/settings/project/projectKeys/details/index.tsx

@@ -1,9 +1,13 @@
 import {browserHistory, RouteComponentProps} from 'react-router';
 
+import LoadingIndicator from 'sentry/components/loadingIndicator';
+import SentryDocumentTitle from 'sentry/components/sentryDocumentTitle';
 import {t} from 'sentry/locale';
 import {Organization, Project} from 'sentry/types';
+import {setApiQueryData, useApiQuery, useQueryClient} from 'sentry/utils/queryClient';
+import useApi from 'sentry/utils/useApi';
 import {normalizeUrl} from 'sentry/utils/withDomainRequired';
-import DeprecatedAsyncView from 'sentry/views/deprecatedAsyncView';
+import RouteError from 'sentry/views/routeError';
 import SettingsPageHeader from 'sentry/views/settings/components/settingsPageHeader';
 import PermissionAlert from 'sentry/views/settings/project/permissionAlert';
 import {KeySettings} from 'sentry/views/settings/project/projectKeys/details/keySettings';
@@ -21,55 +25,57 @@ type Props = {
   {}
 >;
 
-type State = {
-  data: ProjectKey;
-} & DeprecatedAsyncView['state'];
+export default function ProjectKeyDetails({organization, params, project}: Props) {
+  const {keyId, projectId} = params;
+  const api = useApi();
+  const queryClient = useQueryClient();
 
-export default class ProjectKeyDetails extends DeprecatedAsyncView<Props, State> {
-  getTitle() {
-    return t('Key Details');
-  }
+  const {
+    data: projKeyData,
+    isError,
+    isLoading,
+  } = useApiQuery<ProjectKey>(
+    [`/projects/${organization.slug}/${projectId}/keys/${keyId}/`],
+    {staleTime: 0}
+  );
 
-  getEndpoints(): ReturnType<DeprecatedAsyncView['getEndpoints']> {
-    const {organization} = this.props;
-    const {keyId, projectId} = this.props.params;
-    return [['data', `/projects/${organization.slug}/${projectId}/keys/${keyId}/`]];
+  function onDataChange(data: ProjectKey) {
+    setApiQueryData<ProjectKey>(
+      queryClient,
+      [`/projects/${organization.slug}/${projectId}/keys/${keyId}/`],
+      oldData => {
+        return {...oldData, data};
+      }
+    );
   }
 
-  handleRemove = () => {
-    const {organization} = this.props;
-    const {projectId} = this.props.params;
+  const handleRemove = () => {
     browserHistory.push(
       normalizeUrl(`/settings/${organization.slug}/projects/${projectId}/keys/`)
     );
   };
 
-  updateData = (data: ProjectKey) => {
-    this.setState(state => {
-      return {...state, data};
-    });
-  };
-
-  renderBody() {
-    const {organization, project, params} = this.props;
-    const {data} = this.state;
-
-    return (
-      <div data-test-id="key-details">
-        <SettingsPageHeader title={t('Key Details')} />
-        <PermissionAlert project={project} />
-
-        <KeyStats api={this.api} organization={organization} params={params} />
+  if (isError) {
+    return <RouteError />;
+  }
 
-        <KeySettings
-          data={data}
-          updateData={this.updateData}
-          onRemove={this.handleRemove}
-          organization={organization}
-          project={project}
-          params={params}
-        />
-      </div>
-    );
+  if (isLoading) {
+    return <LoadingIndicator />;
   }
+
+  return (
+    <SentryDocumentTitle title={t('Key Details')}>
+      <SettingsPageHeader title={t('Key Details')} data-test-id="key-details" />
+      <PermissionAlert project={project} />
+      <KeyStats api={api} organization={organization} params={params} />
+      <KeySettings
+        data={projKeyData}
+        updateData={onDataChange}
+        onRemove={handleRemove}
+        organization={organization}
+        project={project}
+        params={params}
+      />
+    </SentryDocumentTitle>
+  );
 }