Skip to content

Commit

Permalink
Merge pull request #28381 from fvlvte/24908-migrate-welcome-lib
Browse files Browse the repository at this point in the history
[No QA][TS migration] Migrate 'Welcome.js' lib to TypeScript
  • Loading branch information
Hayata Suenaga authored Oct 27, 2023
2 parents b529f96 + e651ba3 commit 22678a5
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 39 deletions.
2 changes: 1 addition & 1 deletion src/libs/actions/Policy.js
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ function deleteWorkspace(policyID, reports, policyName) {
/**
* Is the user an admin of a free policy (aka workspace)?
*
* @param {Array} policies
* @param {Record<string, Policy>} [policies]
* @returns {Boolean}
*/
function isAdminOfFreePolicy(policies) {
Expand Down
86 changes: 48 additions & 38 deletions src/libs/actions/Welcome.js → src/libs/actions/Welcome.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,33 @@
import Onyx from 'react-native-onyx';
import _ from 'underscore';
import lodashGet from 'lodash/get';
import Onyx, {OnyxCollection} from 'react-native-onyx';
import Navigation from '../Navigation/Navigation';
import * as ReportUtils from '../ReportUtils';
import ROUTES from '../../ROUTES';
import * as Policy from './Policy';
import ONYXKEYS from '../../ONYXKEYS';
import SCREENS from '../../SCREENS';
import CONST from '../../CONST';
import Report from '../../types/onyx/Report';
import OnyxPolicy from '../../types/onyx/Policy';

let resolveIsReadyPromise;
let isReadyPromise = new Promise((resolve) => {
let resolveIsReadyPromise: (value?: Promise<void>) => void | undefined;
let isReadyPromise = new Promise<void>((resolve) => {
resolveIsReadyPromise = resolve;
});

let isFirstTimeNewExpensifyUser;
let isFirstTimeNewExpensifyUser: boolean | undefined;
let isLoadingReportData = true;
let currentUserAccountID;
let currentUserAccountID: number | undefined;

type Route = {
name: string;
params?: {path: string; exitTo?: string; openOnAdminRoom?: boolean};
};

type ShowParams = {
routes: Route[];
showCreateMenu?: () => void;
showPopoverMenu?: () => boolean;
};

/**
* Check that a few requests have completed so that the welcome action can proceed:
Expand All @@ -26,36 +37,36 @@ let currentUserAccountID;
* - Whether we have loaded all reports the server knows about
*/
function checkOnReady() {
if (!_.isBoolean(isFirstTimeNewExpensifyUser) || isLoadingReportData) {
if (isFirstTimeNewExpensifyUser === undefined || isLoadingReportData) {
return;
}

resolveIsReadyPromise();
resolveIsReadyPromise?.();
}

Onyx.connect({
key: ONYXKEYS.NVP_IS_FIRST_TIME_NEW_EXPENSIFY_USER,
initWithStoredValues: false,
callback: (val) => {
callback: (value) => {
// If isFirstTimeNewExpensifyUser was true do not update it to false. We update it to false inside the Welcome.show logic
// More context here https://github.com/Expensify/App/pull/16962#discussion_r1167351359
if (!isFirstTimeNewExpensifyUser) {
isFirstTimeNewExpensifyUser = val;
}

isFirstTimeNewExpensifyUser = value ?? undefined;

checkOnReady();
},
});

Onyx.connect({
key: ONYXKEYS.IS_LOADING_REPORT_DATA,
initWithStoredValues: false,
callback: (val) => {
isLoadingReportData = val;
callback: (value) => {
isLoadingReportData = value ?? false;
checkOnReady();
},
});

const allReports = {};
const allReports: OnyxCollection<Report> = {};
Onyx.connect({
key: ONYXKEYS.COLLECTION.REPORT,
initWithStoredValues: false,
Expand All @@ -68,7 +79,7 @@ Onyx.connect({
},
});

const allPolicies = {};
const allPolicies: OnyxCollection<OnyxPolicy> = {};
Onyx.connect({
key: ONYXKEYS.COLLECTION.POLICY,
callback: (val, key) => {
Expand Down Expand Up @@ -98,47 +109,46 @@ Onyx.connect({

/**
* Shows a welcome action on first login
*
* @param {Object} params
* @param {Object} params.routes
* @param {Function} [params.showCreateMenu]
* @param {Function} [params.showPopoverMenu]
*/
function show({routes, showCreateMenu = () => {}, showPopoverMenu = () => {}}) {
function show({routes, showCreateMenu = () => {}, showPopoverMenu = () => false}: ShowParams) {
isReadyPromise.then(() => {
if (!isFirstTimeNewExpensifyUser) {
return;
}

// If we are rendering the SidebarScreen at the same time as a workspace route that means we've already created a workspace via workspace/new and should not open the global
// create menu right now. We should also stay on the workspace page if that is our destination.
const topRoute = _.last(routes);
const isWorkspaceRoute = topRoute.name === 'Settings' && topRoute.params.path.includes('workspace');
const transitionRoute = _.find(routes, (route) => route.name === SCREENS.TRANSITION_BETWEEN_APPS);
const exitingToWorkspaceRoute = lodashGet(transitionRoute, 'params.exitTo', '') === 'workspace/new';
const openOnAdminRoom = lodashGet(topRoute, 'params.openOnAdminRoom', false);
const isDisplayingWorkspaceRoute = isWorkspaceRoute || exitingToWorkspaceRoute;
const topRoute = routes.length > 0 ? routes[routes.length - 1] : undefined;
const isWorkspaceRoute = topRoute !== undefined && topRoute.name === 'Settings' && topRoute.params?.path.includes('workspace');
const transitionRoute = routes.find((route) => route.name === SCREENS.TRANSITION_BETWEEN_APPS);
const exitingToWorkspaceRoute = transitionRoute?.params?.exitTo === 'workspace/new';
const openOnAdminRoom = topRoute?.params?.openOnAdminRoom ?? false;
const isDisplayingWorkspaceRoute = isWorkspaceRoute ?? exitingToWorkspaceRoute;

// If we already opened the workspace settings or want the admin room to stay open, do not
// navigate away to the workspace chat report
const shouldNavigateToWorkspaceChat = !isDisplayingWorkspaceRoute && !openOnAdminRoom;

const workspaceChatReport = _.find(
allReports,
(report) => ReportUtils.isPolicyExpenseChat(report) && report.ownerAccountID === currentUserAccountID && report.statusNum !== CONST.REPORT.STATUS.CLOSED,
);
const workspaceChatReport = Object.values(allReports ?? {}).find((report) => {
if (report) {
return ReportUtils.isPolicyExpenseChat(report) && report.ownerAccountID === currentUserAccountID && report.statusNum !== CONST.REPORT.STATUS.CLOSED;
}
return false;
});

if (workspaceChatReport || openOnAdminRoom) {
if (workspaceChatReport ?? openOnAdminRoom) {
// This key is only updated when we call ReconnectApp, setting it to false now allows the user to navigate normally instead of always redirecting to the workspace chat
Onyx.set(ONYXKEYS.NVP_IS_FIRST_TIME_NEW_EXPENSIFY_USER, false);
}

if (shouldNavigateToWorkspaceChat && workspaceChatReport) {
Navigation.navigate(ROUTES.REPORT_WITH_ID.getRoute(workspaceChatReport.reportID));
if (workspaceChatReport.reportID !== null) {
Navigation.navigate(ROUTES.REPORT_WITH_ID.getRoute(workspaceChatReport.reportID));
}

// If showPopoverMenu exists and returns true then it opened the Popover Menu successfully, and we can update isFirstTimeNewExpensifyUser
// so the Welcome logic doesn't run again
if (showPopoverMenu()) {
if (showPopoverMenu?.()) {
isFirstTimeNewExpensifyUser = false;
}

Expand All @@ -147,7 +157,7 @@ function show({routes, showCreateMenu = () => {}, showPopoverMenu = () => {}}) {

// If user is not already an admin of a free policy and we are not navigating them to their workspace or creating a new workspace via workspace/new then
// we will show the create menu.
if (!Policy.isAdminOfFreePolicy(allPolicies) && !isDisplayingWorkspaceRoute) {
if (!Policy.isAdminOfFreePolicy(allPolicies ?? undefined) && !isDisplayingWorkspaceRoute) {
showCreateMenu();
}

Expand All @@ -164,7 +174,7 @@ function resetReadyCheck() {
isLoadingReportData = true;
}

function serverDataIsReadyPromise() {
function serverDataIsReadyPromise(): Promise<void> {
return isReadyPromise;
}

Expand Down

0 comments on commit 22678a5

Please sign in to comment.