Browse Source

ref(tsc): modals to tsx (#52435)

Convert the rest of the modals to tsx. It's kind of sad that we ended up
typing body/footer as styled components type (which is pretty much all
the changes here)
Jonas 1 year ago
parent
commit
0d89fda696

+ 3 - 3
static/app/components/asyncComponent.tsx

@@ -14,16 +14,16 @@ import getRouteStringFromRoutes from 'sentry/utils/getRouteStringFromRoutes';
 import PermissionDenied from 'sentry/views/permissionDenied';
 import RouteError from 'sentry/views/routeError';
 
-export type AsyncComponentProps = Partial<RouteComponentProps<{}, {}>>;
+export interface AsyncComponentProps extends Partial<RouteComponentProps<{}, {}>> {}
 
-type AsyncComponentState = {
+export interface AsyncComponentState {
   [key: string]: any;
   error: boolean;
   errors: Record<string, ResponseMeta>;
   loading: boolean;
   reloading: boolean;
   remainingRequests?: number;
-};
+}
 
 type SearchInputProps = React.ComponentProps<typeof AsyncComponentSearchInput>;
 

+ 8 - 1
static/app/components/modals/diffModal.spec.jsx → static/app/components/modals/diffModal.spec.tsx

@@ -1,3 +1,5 @@
+import styled from '@emotion/styled';
+
 import {render} from 'sentry-test/reactTestingLibrary';
 
 import DiffModal from 'sentry/components/modals/diffModal';
@@ -26,14 +28,19 @@ describe('DiffModal', function () {
       body: [],
     });
 
+    const styledWrapper = styled(c => c.children);
+
     render(
       <DiffModal
         orgId="123"
         baseIssueId="123"
         targetIssueId="234"
         project={project}
-        Body={({children}) => <div>{children}</div>}
+        Footer={styledWrapper()}
+        Body={styledWrapper()}
+        Header={c => <span>{c.children}</span>}
         CloseButton={({children}) => <div>{children}</div>}
+        closeModal={() => {}}
       />
     );
   });

+ 13 - 5
static/app/components/modals/inviteMembersModal/index.spec.jsx → static/app/components/modals/inviteMembersModal/index.spec.tsx

@@ -1,9 +1,13 @@
 import selectEvent from 'react-select-event';
+import styled from '@emotion/styled';
 
 import {render, screen, userEvent} from 'sentry-test/reactTestingLibrary';
 import {textWithMarkupMatcher} from 'sentry-test/utils';
 
-import InviteMembersModal from 'sentry/components/modals/inviteMembersModal';
+import {makeCloseButton} from 'sentry/components/globalModal/components';
+import InviteMembersModal, {
+  InviteMembersModalProps,
+} from 'sentry/components/modals/inviteMembersModal';
 import TeamStore from 'sentry/stores/teamStore';
 
 describe('InviteMembersModal', function () {
@@ -11,10 +15,14 @@ describe('InviteMembersModal', function () {
   const org = TestStubs.Organization({access: ['member:write'], teams: [team]});
   TeamStore.loadInitialData([team]);
 
-  const modalProps = {
-    Body: p => p.children,
-    Header: p => p.children,
-    Footer: p => p.children,
+  const styledWrapper = styled(c => c.children);
+  const modalProps: InviteMembersModalProps = {
+    Body: styledWrapper(),
+    Header: p => <span>{p.children}</span>,
+    Footer: styledWrapper(),
+    closeModal: () => {},
+    CloseButton: makeCloseButton(() => {}),
+    organization: TestStubs.Organization(),
   };
 
   const noWriteOrg = TestStubs.Organization({

+ 12 - 9
static/app/components/modals/inviteMembersModal/index.tsx

@@ -4,6 +4,10 @@ import styled from '@emotion/styled';
 
 import {ModalRenderProps} from 'sentry/actionCreators/modal';
 import Alert from 'sentry/components/alert';
+import type {
+  AsyncComponentProps,
+  AsyncComponentState,
+} from 'sentry/components/asyncComponent';
 import AsyncComponent from 'sentry/components/asyncComponent';
 import {Button} from 'sentry/components/button';
 import ButtonBar from 'sentry/components/buttonBar';
@@ -21,19 +25,18 @@ import withLatestContext from 'sentry/utils/withLatestContext';
 import InviteRowControl from './inviteRowControl';
 import {InviteRow, InviteStatus, NormalizedInvite} from './types';
 
-type Props = AsyncComponent['props'] &
-  ModalRenderProps & {
-    organization: Organization;
-    initialData?: Partial<InviteRow>[];
-    source?: string;
-  };
+export interface InviteMembersModalProps extends AsyncComponentProps, ModalRenderProps {
+  organization: Organization;
+  initialData?: Partial<InviteRow>[];
+  source?: string;
+}
 
-type State = AsyncComponent['state'] & {
+interface State extends AsyncComponentState {
   complete: boolean;
   inviteStatus: InviteStatus;
   pendingInvites: InviteRow[];
   sendingInvites: boolean;
-};
+}
 
 const DEFAULT_ROLE = 'member';
 
@@ -45,7 +48,7 @@ const InviteModalHook = HookOrDefault({
 
 type InviteModalRenderFunc = React.ComponentProps<typeof InviteModalHook>['children'];
 
-class InviteMembersModal extends AsyncComponent<Props, State> {
+class InviteMembersModal extends AsyncComponent<InviteMembersModalProps, State> {
   get inviteTemplate(): InviteRow {
     return {
       emails: new Set(),

+ 9 - 5
static/app/components/modals/recoveryOptionsModal.spec.jsx → static/app/components/modals/recoveryOptionsModal.spec.tsx

@@ -1,10 +1,12 @@
+import styled from '@emotion/styled';
+
 import {render, screen, userEvent} from 'sentry-test/reactTestingLibrary';
 
+import {makeCloseButton} from 'sentry/components/globalModal/components';
 import RecoveryOptionsModal from 'sentry/components/modals/recoveryOptionsModal';
 
 describe('RecoveryOptionsModal', function () {
   const closeModal = jest.fn();
-  const onClose = jest.fn();
   const mockId = TestStubs.Authenticators().Recovery().authId;
   const routerContext = TestStubs.routerContext();
 
@@ -18,14 +20,16 @@ describe('RecoveryOptionsModal', function () {
   });
 
   function renderComponent() {
+    const styledWrapper = styled(c => c.children);
+
     render(
       <RecoveryOptionsModal
-        Body={p => p.children}
-        Header={p => p.children}
-        Footer={p => p.children}
+        Body={styledWrapper()}
+        Header={p => <span>{p.children}</span>}
+        Footer={styledWrapper()}
         authenticatorName="Authenticator App"
         closeModal={closeModal}
-        onClose={onClose}
+        CloseButton={makeCloseButton(() => {})}
       />,
       {context: routerContext}
     );

+ 17 - 15
static/app/components/modals/teamAccessRequestModal.spec.jsx → static/app/components/modals/teamAccessRequestModal.spec.tsx

@@ -1,33 +1,35 @@
+import styled from '@emotion/styled';
+
 import {render, screen, userEvent} from 'sentry-test/reactTestingLibrary';
 
-import TeamAccessRequestModal from 'sentry/components/modals/teamAccessRequestModal';
+import {makeCloseButton} from 'sentry/components/globalModal/components';
+import TeamAccessRequestModal, {
+  CreateTeamAccessRequestModalProps,
+} from 'sentry/components/modals/teamAccessRequestModal';
 
 describe('TeamAccessRequestModal', function () {
   let createMock;
 
   const closeModal = jest.fn();
-  const onClose = jest.fn();
   const orgId = TestStubs.Organization().slug;
   const memberId = TestStubs.Member().id;
   const teamId = TestStubs.Team().slug;
 
-  const modalRenderProps = {
-    Body: p => p.children,
-    Footer: p => p.children,
-    Header: p => p.children,
+  const styledWrapper = styled(c => c.children);
+  const modalRenderProps: CreateTeamAccessRequestModalProps = {
+    Body: styledWrapper(),
+    Footer: styledWrapper(),
+    Header: p => <span>{p.children}</span>,
     closeModal,
-    onClose,
+    orgId,
+    teamId,
+    memberId,
+    CloseButton: makeCloseButton(() => {}),
+    api: new MockApiClient(),
   };
 
   function renderComponent() {
-    return render(
-      <TeamAccessRequestModal
-        orgId={orgId}
-        teamId={teamId}
-        memberId={memberId}
-        {...modalRenderProps}
-      />
-    );
+    return render(<TeamAccessRequestModal {...modalRenderProps} />);
   }
 
   beforeEach(function () {

+ 13 - 9
static/app/components/modals/teamAccessRequestModal.tsx

@@ -12,19 +12,23 @@ import {t, tct} from 'sentry/locale';
 import {space} from 'sentry/styles/space';
 import withApi from 'sentry/utils/withApi';
 
-type Props = ModalRenderProps &
-  TeamAccessRequestModalOptions & {
-    api: Client;
-    memberId: string;
-    orgId: string;
-    teamId: string;
-  };
+export interface CreateTeamAccessRequestModalProps
+  extends ModalRenderProps,
+    TeamAccessRequestModalOptions {
+  api: Client;
+  memberId: string;
+  orgId: string;
+  teamId: string;
+}
 
 type State = {
   createBusy: boolean;
 };
 
-class CreateTeamAccessRequest extends Component<Props, State> {
+class CreateTeamAccessRequestModal extends Component<
+  CreateTeamAccessRequestModalProps,
+  State
+> {
   state: State = {
     createBusy: false,
   };
@@ -84,4 +88,4 @@ const ButtonGroup = styled('div')`
   gap: ${space(1)};
 `;
 
-export default withApi(CreateTeamAccessRequest);
+export default withApi(CreateTeamAccessRequestModal);