Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[TS migration] Migrate Signin to TypeScript #35294

Merged
merged 75 commits into from
Feb 14, 2024
Merged
Show file tree
Hide file tree
Changes from 69 commits
Commits
Show all changes
75 commits
Select commit Hold shift + click to select a range
f8da976
[Refactor] Convert Socials.js to TypeScript
fedirjh Jan 26, 2024
8cde601
[Refactor] Convert Terms.js to TypeScript
fedirjh Jan 26, 2024
eaeebb9
[Refactor] Convert Licenses.js to TypeScript
fedirjh Jan 26, 2024
20ba59f
[Refactor] Convert SignInPageHero.js to TypeScript
fedirjh Jan 26, 2024
7a5c68a
[Refactor] Convert SignInModal.js to TypeScript
fedirjh Jan 26, 2024
10c37a0
[Refactor] Convert DesktopRedirectPage.js to TypeScript
fedirjh Jan 26, 2024
c39f6ae
[Refactor] Convert DesktopSignInRedirectPage to TypeScript
fedirjh Jan 26, 2024
9cea571
[Refactor] Convert SAMLSignInPage to TypeScript
fedirjh Jan 26, 2024
76212e5
Adjust semicolon usage and import organization
fedirjh Jan 26, 2024
41721fd
[Refactor] Convert SignIn page styles to TypeScript.
fedirjh Jan 28, 2024
93ed872
[Refactor] Convert ChangeExpensifyLoginLink to TypeScript.
fedirjh Jan 28, 2024
ffe42c9
[Refactor] Convert ChangeExpensifyLoginLink to TypeScript.
fedirjh Jan 28, 2024
f538d2c
[Refactor] Convert SignInHeroImage to TypeScript.
fedirjh Jan 28, 2024
75f96a9
[Refactor] Convert SignInHeroCopy to TypeScript.
fedirjh Jan 28, 2024
684e329
[Refactor] Convert EmailDeliveryFailurePage to TypeScript.
fedirjh Jan 28, 2024
eaf21dd
[Refactor] Convert UnlinkLoginForm to TypeScript.
fedirjh Jan 28, 2024
dd2ae56
[Chore] Add comments
fedirjh Jan 28, 2024
f922225
[Refactor] Convert ChooseSSOOrMagicCode to TypeScript.
fedirjh Jan 28, 2024
c483550
[Refactor] Convert ThirdPartySignInPage to TypeScript.
fedirjh Jan 28, 2024
4d1b5bf
[Refactor] Convert BackgroundImage to TypeScript.
fedirjh Jan 28, 2024
d284a85
[Chore] The TextLink component props definition was simplified by rem…
fedirjh Jan 28, 2024
bbf409c
[Refactor] convert to TypeScript
fedirjh Jan 28, 2024
a1168ee
[Refactor] convert ValidateCodeForm to TypeScript
fedirjh Jan 29, 2024
ee57088
[Refactor] convert LoginForm to TypeScript
fedirjh Jan 29, 2024
46247f5
[Refactor] convert SignInPageContent to TypeScript
fedirjh Jan 29, 2024
fdc97b3
[Refactor] convert SignInPageLayout to TypeScript
fedirjh Jan 29, 2024
a40388f
[Refactor] convert SignInPageLayout to TypeScript
fedirjh Jan 29, 2024
3d736a4
Revert "[Refactor] Convert ChangeExpensifyLoginLink to TypeScript."
fedirjh Feb 4, 2024
167a9e4
Revert "[Refactor] Convert ChangeExpensifyLoginLink to TypeScript."
fedirjh Feb 4, 2024
2537f6b
Revert "[Refactor] convert ValidateCodeForm to TypeScript"
fedirjh Feb 4, 2024
be857c4
Revert "[Refactor] Convert DesktopRedirectPage.js to TypeScript"
fedirjh Feb 4, 2024
c1570fd
Revert "[Refactor] Convert DesktopSignInRedirectPage to TypeScript"
fedirjh Feb 4, 2024
dd4cf14
Revert "[Refactor] convert to TypeScript"
fedirjh Feb 4, 2024
68d3efb
[Chore] Fix types
fedirjh Feb 4, 2024
9c28e14
[Chore] Fix typeScript checks + Rename BaseLoginForm
fedirjh Feb 4, 2024
18258bb
[Refactor] Migrate SignInPage to typeScript
fedirjh Feb 4, 2024
c715670
[Chore] Fix code style
fedirjh Feb 4, 2024
5971307
[Chore] Fix TS errors
fedirjh Feb 4, 2024
f01dd1c
[Chore] Fix Lint & TS
fedirjh Feb 5, 2024
28d79f3
[Chore] Fix Types
fedirjh Feb 8, 2024
f666615
[Chore] Fix nullish coalescing
fedirjh Feb 9, 2024
04218f2
[Chore] Rename File
fedirjh Feb 9, 2024
9c51d5e
[Chore] Rename TS File
fedirjh Feb 9, 2024
188fb50
[Refactor] Convert SignInPageHero.js to TypeScript
fedirjh Jan 26, 2024
ab306f4
[Refactor] Convert DesktopRedirectPage.js to TypeScript
fedirjh Jan 26, 2024
3376742
[Refactor] Convert DesktopSignInRedirectPage to TypeScript
fedirjh Jan 26, 2024
46478df
Adjust semicolon usage and import organization
fedirjh Jan 26, 2024
b305ae2
[Refactor] Convert ChangeExpensifyLoginLink to TypeScript.
fedirjh Jan 28, 2024
e58cffd
[Refactor] Convert ChangeExpensifyLoginLink to TypeScript.
fedirjh Jan 28, 2024
7f6b3bc
[Chore] The TextLink component props definition was simplified by rem…
fedirjh Jan 28, 2024
7137455
[Refactor] convert to TypeScript
fedirjh Jan 28, 2024
fcbe681
[Refactor] convert ValidateCodeForm to TypeScript
fedirjh Jan 29, 2024
14b157a
Revert "[Refactor] Convert ChangeExpensifyLoginLink to TypeScript."
fedirjh Feb 4, 2024
a8f4b16
Revert "[Refactor] Convert ChangeExpensifyLoginLink to TypeScript."
fedirjh Feb 4, 2024
43af805
Revert "[Refactor] convert ValidateCodeForm to TypeScript"
fedirjh Feb 4, 2024
a76c3c6
Revert "[Refactor] Convert DesktopRedirectPage.js to TypeScript"
fedirjh Feb 4, 2024
a133fcc
Revert "[Refactor] Convert DesktopSignInRedirectPage to TypeScript"
fedirjh Feb 4, 2024
8a70498
Revert "[Refactor] convert to TypeScript"
fedirjh Feb 4, 2024
59f5d3f
[Chore] Fix code style
fedirjh Feb 4, 2024
96be73c
[Chore] Fix Types
fedirjh Feb 8, 2024
3c6871f
[Chore] Fix nullish coalescing
fedirjh Feb 9, 2024
2a228bb
[Chore] Rename File
fedirjh Feb 9, 2024
a0d6ad3
[Chore] Rename TS File
fedirjh Feb 9, 2024
8c7ee8e
[Chore] Fix TS
fedirjh Feb 9, 2024
6c02db1
Apply suggestions from code review
fedirjh Feb 10, 2024
a3d6104
[Chore] Fix TS types: use TextLink types
fedirjh Feb 10, 2024
a95b2b3
[Chore] Fix SAMLSignIn Props
fedirjh Feb 10, 2024
dfac1a4
[Chore] Fix Lint & Address code review
fedirjh Feb 10, 2024
8550b07
[Refactor] SignInPageLayout to use shared types
fedirjh Feb 10, 2024
d051374
[Chore] Fix TS Types & address code review
fedirjh Feb 11, 2024
8ba10de
[Chore] Fix TS Types & address code review
fedirjh Feb 12, 2024
a97b3cc
Merge branch 'main' into ts-migration-signin
fedirjh Feb 13, 2024
c2a718c
[Chore] Fix merge conflicts
fedirjh Feb 14, 2024
b7f9979
[Chore] Remove extra file
fedirjh Feb 14, 2024
f914990
[Chore] Remove outdated TS directives
fedirjh Feb 14, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/components/TextLink.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -79,4 +79,6 @@ function TextLink({href, onPress, children, style, onMouseDown = (event) => even

TextLink.displayName = 'TextLink';

export type {LinkProps, PressProps};

export default forwardRef(TextLink);
8 changes: 5 additions & 3 deletions src/components/withToggleVisibilityView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ import type {SetOptional} from 'type-fest';
import useThemeStyles from '@hooks/useThemeStyles';
import getComponentDisplayName from '@libs/getComponentDisplayName';

type ToggleVisibilityViewProps = {
type WithToggleVisibilityViewProps = {
/** Whether the content is visible. */
isVisible: boolean;
isVisible?: boolean;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be kept as required. There is another PR dealing with this rn #35404 (comment). Writing a comment so I don't forgot to check again

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I actually used the same props as that PR for this component.

};

export default function withToggleVisibilityView<TProps extends ToggleVisibilityViewProps, TRef>(
export default function withToggleVisibilityView<TProps extends WithToggleVisibilityViewProps, TRef>(
WrappedComponent: ComponentType<TProps & RefAttributes<TRef>>,
): (props: TProps & RefAttributes<TRef>) => ReactElement | null {
function WithToggleVisibilityView({isVisible = false, ...rest}: SetOptional<TProps, 'isVisible'>, ref: ForwardedRef<TRef>) {
Expand All @@ -30,3 +30,5 @@ export default function withToggleVisibilityView<TProps extends ToggleVisibility
WithToggleVisibilityView.displayName = `WithToggleVisibilityViewWithRef(${getComponentDisplayName(WrappedComponent)})`;
return React.forwardRef(WithToggleVisibilityView);
}

export type {WithToggleVisibilityViewProps};
4 changes: 2 additions & 2 deletions src/libs/Performance.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ type PrintPerformanceMetrics = () => void;
type MarkStart = (name: string, detail?: Record<string, unknown>) => PerformanceMark | void;
type MarkEnd = (name: string, detail?: Record<string, unknown>) => PerformanceMark | void;
type MeasureFailSafe = (measureName: string, startOrMeasureOptions: string, endMark?: string) => void;
type MeasureTTI = (endMark: string) => void;
type MeasureTTI = (endMark?: string) => void;
type TraceRender = (id: string, phase: Phase, actualDuration: number, baseDuration: number, startTime: number, commitTime: number, interactions: Set<unknown>) => PerformanceMeasure | void;
type WithRenderTrace = ({id}: WrappedComponentConfig) => WithRenderTraceHOC | BlankHOC;
type SubscribeToMeasurements = (callback: PerformanceEntriesCallback) => void;
Expand Down Expand Up @@ -104,7 +104,7 @@ if (Metrics.canCapturePerformanceMetrics()) {
/**
* Measures the TTI time. To be called when the app is considered to be interactive.
*/
Performance.measureTTI = (endMark: string) => {
Performance.measureTTI = (endMark?: string) => {
// Make sure TTI is captured when the app is really usable
InteractionManager.runAfterInteractions(() => {
requestAnimationFrame(() => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import PropTypes from 'prop-types';
import React, {useEffect} from 'react';
import {Keyboard, View} from 'react-native';
import {withOnyx} from 'react-native-onyx';
import _ from 'underscore';
import type {OnyxEntry} from 'react-native-onyx';
import Button from '@components/Button';
import FormHelpMessage from '@components/FormHelpMessage';
import Text from '@components/Text';
Expand All @@ -17,43 +16,27 @@ import * as Session from '@userActions/Session';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import ROUTES from '@src/ROUTES';
import type {Account, Credentials} from '@src/types/onyx';
import {isEmptyObject} from '@src/types/utils/EmptyObject';
import ChangeExpensifyLoginLink from './ChangeExpensifyLoginLink';
import Terms from './Terms';

const propTypes = {
type ChooseSSOOrMagicCodeOnyxProps = {
/* Onyx Props */

/** The credentials of the logged in person */
credentials: PropTypes.shape({
/** The email/phone the user logged in with */
login: PropTypes.string,
}),
credentials: OnyxEntry<Credentials>;

/** The details about the account that the user is signing in with */
account: PropTypes.shape({
/** Whether or not a sign on form is loading (being submitted) */
isLoading: PropTypes.bool,

/** Form that is being loaded */
loadingForm: PropTypes.oneOf(_.values(CONST.FORMS)),

/** Whether this account has 2FA enabled or not */
requiresTwoFactorAuth: PropTypes.bool,

/** Server-side errors in the submitted authentication code */
errors: PropTypes.objectOf(PropTypes.string),
}),

/** Function that returns whether the user is using SAML or magic codes to log in */
setIsUsingMagicCode: PropTypes.func.isRequired,
account: OnyxEntry<Account>;
};

const defaultProps = {
credentials: {},
account: {},
type ChooseSSOOrMagicCodeProps = ChooseSSOOrMagicCodeOnyxProps & {
/** Function that returns whether the user is using SAML or magic codes to log in */
setIsUsingMagicCode: (value: boolean) => void;
};

function ChooseSSOOrMagicCode({credentials, account, setIsUsingMagicCode}) {
function ChooseSSOOrMagicCode({credentials, account, setIsUsingMagicCode}: ChooseSSOOrMagicCodeProps) {
const styles = useThemeStyles();
const {isKeyboardShown} = useKeyboardState();
const {translate} = useLocalize();
Expand All @@ -77,7 +60,7 @@ function ChooseSSOOrMagicCode({credentials, account, setIsUsingMagicCode}) {
success
style={[styles.mv3]}
text={translate('samlSignIn.useSingleSignOn')}
isLoading={account.isLoading}
isLoading={account?.isLoading}
onPress={() => {
Navigation.navigate(ROUTES.SAML_SIGN_IN);
}}
Expand All @@ -93,14 +76,17 @@ function ChooseSSOOrMagicCode({credentials, account, setIsUsingMagicCode}) {
isDisabled={isOffline}
style={[styles.mv3]}
text={translate('samlSignIn.useMagicCode')}
isLoading={account.isLoading && account.loadingForm === (account.requiresTwoFactorAuth ? CONST.FORMS.VALIDATE_TFA_CODE_FORM : CONST.FORMS.VALIDATE_CODE_FORM)}
isLoading={account?.isLoading && account?.loadingForm === (account?.requiresTwoFactorAuth ? CONST.FORMS.VALIDATE_TFA_CODE_FORM : CONST.FORMS.VALIDATE_CODE_FORM)}
onPress={() => {
Session.resendValidateCode(credentials.login);
Session.resendValidateCode(credentials?.login);
setIsUsingMagicCode(true);
}}
/>
{Boolean(account) && !_.isEmpty(account.errors) && <FormHelpMessage message={ErrorUtils.getLatestErrorMessage(account)} />}
<ChangeExpensifyLoginLink onPress={() => Session.clearSignInData()} />
{!!account && !isEmptyObject(account.errors) && <FormHelpMessage message={ErrorUtils.getLatestErrorMessage(account)} />}
<ChangeExpensifyLoginLink
// @ts-expect-error TODO: Remove this once https://github.com/Expensify/App/pull/35404 is merged
onPress={() => Session.clearSignInData()}
/>
</View>
<View style={[styles.mt5, styles.signInPageWelcomeTextContainer]}>
<Terms />
Expand All @@ -109,11 +95,9 @@ function ChooseSSOOrMagicCode({credentials, account, setIsUsingMagicCode}) {
);
}

ChooseSSOOrMagicCode.propTypes = propTypes;
ChooseSSOOrMagicCode.defaultProps = defaultProps;
ChooseSSOOrMagicCode.displayName = 'ChooseSSOOrMagicCode';

export default withOnyx({
export default withOnyx<ChooseSSOOrMagicCodeProps, ChooseSSOOrMagicCodeOnyxProps>({
credentials: {key: ONYXKEYS.CREDENTIALS},
account: {key: ONYXKEYS.ACCOUNT},
})(ChooseSSOOrMagicCode);
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import Str from 'expensify-common/lib/str';
import PropTypes from 'prop-types';
import React, {useEffect} from 'react';
import React, {useEffect, useMemo} from 'react';
import {Keyboard, View} from 'react-native';
import {withOnyx} from 'react-native-onyx';
import type {OnyxEntry} from 'react-native-onyx';
import PressableWithFeedback from '@components/Pressable/PressableWithFeedback';
import Text from '@components/Text';
import TextLink from '@components/TextLink';
Expand All @@ -12,26 +12,25 @@ import useThemeStyles from '@hooks/useThemeStyles';
import redirectToSignIn from '@userActions/SignInRedirect';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import type {Credentials} from '@src/types/onyx';

const propTypes = {
/* Onyx Props */

type EmailDeliveryFailurePageOnyxProps = {
/** The credentials of the logged in person */
credentials: PropTypes.shape({
/** The email/phone the user logged in with */
login: PropTypes.string,
}),
credentials: OnyxEntry<Credentials>;
};

const defaultProps = {
credentials: {},
};
type EmailDeliveryFailurePageProps = EmailDeliveryFailurePageOnyxProps;

function EmailDeliveryFailurePage(props) {
function EmailDeliveryFailurePage({credentials}: EmailDeliveryFailurePageProps) {
const styles = useThemeStyles();
const {isKeyboardShown} = useKeyboardState();
const {translate} = useLocalize();
const login = Str.isSMSLogin(props.credentials.login) ? Str.removeSMSDomain(props.credentials.login) : props.credentials.login;
const login = useMemo(() => {
if (!credentials?.login) {
return '';
}
return Str.isSMSLogin(credentials.login) ? Str.removeSMSDomain(credentials.login) : credentials.login;
}, [credentials?.login]);

// This view doesn't have a field for user input, so dismiss the device keyboard if shown
useEffect(() => {
Expand All @@ -43,7 +42,7 @@ function EmailDeliveryFailurePage(props) {

return (
<>
<View style={[styles.mv3, styles.flexRow, styles.justifyContentetween]}>
<View style={[styles.mv3, styles.flexRow]}>
<View style={[styles.flex1]}>
<Text>{translate('emailDeliveryFailurePage.ourEmailProvider', {login})}</Text>
<Text style={[styles.mt5]}>
Expand Down Expand Up @@ -89,10 +88,8 @@ function EmailDeliveryFailurePage(props) {
);
}

EmailDeliveryFailurePage.propTypes = propTypes;
EmailDeliveryFailurePage.defaultProps = defaultProps;
EmailDeliveryFailurePage.displayName = 'EmailDeliveryFailurePage';

export default withOnyx({
export default withOnyx<EmailDeliveryFailurePageProps, EmailDeliveryFailurePageOnyxProps>({
credentials: {key: ONYXKEYS.CREDENTIALS},
})(EmailDeliveryFailurePage);
12 changes: 6 additions & 6 deletions src/pages/signin/Licenses.js → src/pages/signin/Licenses.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,26 @@ import {View} from 'react-native';
import LocalePicker from '@components/LocalePicker';
import Text from '@components/Text';
import TextLink from '@components/TextLink';
import withLocalize, {withLocalizePropTypes} from '@components/withLocalize';
import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';
import CONST from '@src/CONST';

const currentYear = new Date().getFullYear();

function Licenses(props) {
function Licenses() {
const styles = useThemeStyles();
const {translate} = useLocalize();
return (
<>
<Text style={[styles.textExtraSmallSupporting, styles.mb4]}>{`© ${currentYear} Expensify`}</Text>
<Text style={[styles.textExtraSmallSupporting]}>
{props.translate('termsOfUse.phrase5')}
{translate('termsOfUse.phrase5')}
<TextLink
style={[styles.textExtraSmallSupporting, styles.link]}
href={CONST.LICENSES_URL}
>
{' '}
{props.translate('termsOfUse.phrase6')}
{translate('termsOfUse.phrase6')}
</TextLink>
.
</Text>
Expand All @@ -32,7 +33,6 @@ function Licenses(props) {
);
}

Licenses.propTypes = {...withLocalizePropTypes};
Licenses.displayName = 'Licenses';

export default withLocalize(Licenses);
export default Licenses;
Loading
Loading