Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
70b6f38
Start creating new demo page route
Beamanator Aug 14, 2023
69da9ad
Add new saastr email
Beamanator Aug 14, 2023
e805fdc
Set up a new workspace, note todos
Beamanator Aug 14, 2023
49fb4c1
A few fixes to connect the new API command
Beamanator Aug 14, 2023
0507a0f
Add ability to run specific demo by initial URL
Beamanator Aug 14, 2023
766f5eb
Merge branch 'main' of github.com:Expensify/App into beaman-createSaa…
Beamanator Aug 14, 2023
a3f7564
Fix customizing the header
Beamanator Aug 15, 2023
24843e6
New util to get workspace chat report from policy owner
Beamanator Aug 15, 2023
247a58a
Lookup workspace chat first & add workspace name prefix
Beamanator Aug 15, 2023
cdb31cb
Merge branch 'main' of github.com:Expensify/App into beaman-createSaa…
Beamanator Aug 15, 2023
0b32e91
Add optimistic welcome message when creating workspace chat
Beamanator Aug 15, 2023
24f4e36
A few fixes & remove a few TODOs
Beamanator Aug 15, 2023
2556d2f
Make sure welcome message comes from SaaStr
Beamanator Aug 15, 2023
e812d10
Add saastr acct num
Beamanator Aug 15, 2023
2d3d3a3
prettify
Beamanator Aug 15, 2023
4cf5705
Update spanish translation
Beamanator Aug 15, 2023
9be4aee
Small tweaks
cristipaval Aug 16, 2023
d6f0c1c
Merge branch 'main' of github.com:Expensify/App into beaman-createSaa…
Beamanator Aug 16, 2023
5451be6
Fixing up lint errors
Beamanator Aug 16, 2023
ea4c983
Merge branch 'main' of github.com:Expensify/App into beaman-createSaa…
Beamanator Aug 17, 2023
1b56731
Remove admin rooms, send welcome report action id
Beamanator Aug 17, 2023
5a8c607
Merge branch 'main' of github.com:Expensify/App into beaman-createSaa…
Beamanator Aug 21, 2023
453ff52
Remove duplicate demo page setup
Beamanator Aug 21, 2023
1f97101
Add similar SBE demo workflow
Beamanator Aug 21, 2023
db90ed0
Refactor for new SBE flow
Beamanator Aug 21, 2023
75651e3
Merge branch 'main' of github.com:Expensify/App into beaman-createSaa…
Beamanator Aug 22, 2023
bc97f1a
Clean up url-cleaning logic
Beamanator Aug 22, 2023
f4d1ff4
Add sbe account number
Beamanator Aug 22, 2023
a2bda8c
Move fn to DemoActions, remove optimistic data
Beamanator Aug 22, 2023
511f438
Cleanup and correctly navigate
Beamanator Aug 22, 2023
3eb1707
Lint cleanup
Beamanator Aug 22, 2023
e8f719c
Update src/pages/DemoSetupPage.js
cristipaval Aug 22, 2023
ac14e22
Address feedback after review.
cristipaval Aug 22, 2023
7a71444
Merge remote-tracking branch 'origin/main' into beaman-createSaastrDe…
cristipaval Aug 22, 2023
a32515a
Fix conflicts after merge.
cristipaval Aug 22, 2023
a694759
Update src/libs/ReportUtils.js
cristipaval Aug 22, 2023
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 .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,7 @@ EXPENSIFY_ACCOUNT_ID_QA=-1
EXPENSIFY_ACCOUNT_ID_QA_TRAVIS=-1
EXPENSIFY_ACCOUNT_ID_RECEIPTS=-1
EXPENSIFY_ACCOUNT_ID_REWARDS=-1
EXPENSIFY_ACCOUNT_ID_SAASTR=-1
EXPENSIFY_ACCOUNT_ID_SBE=-1
EXPENSIFY_ACCOUNT_ID_STUDENT_AMBASSADOR=-1
EXPENSIFY_ACCOUNT_ID_SVFG=-1
12 changes: 12 additions & 0 deletions src/CONST.js
Original file line number Diff line number Diff line change
Expand Up @@ -867,6 +867,8 @@ const CONST = {
QA: 'qa@expensify.com',
QA_TRAVIS: 'qa+travisreceipts@expensify.com',
RECEIPTS: 'receipts@expensify.com',
SAASTR: 'saastr@expensify.com',
SBE: 'sbe@expensify.com',
STUDENT_AMBASSADOR: 'studentambassadors@expensify.com',
SVFG: 'svfg@expensify.com',
},
Expand All @@ -886,6 +888,8 @@ const CONST = {
QA_TRAVIS: Number(lodashGet(Config, 'EXPENSIFY_ACCOUNT_ID_QA_TRAVIS', 8595733)),
RECEIPTS: Number(lodashGet(Config, 'EXPENSIFY_ACCOUNT_ID_RECEIPTS', -1)),
REWARDS: Number(lodashGet(Config, 'EXPENSIFY_ACCOUNT_ID_REWARDS', 11023767)), // rewards@expensify.com
SAASTR: Number(lodashGet(Config, 'EXPENSIFY_ACCOUNT_ID_SAASTR', 15252830)),
SBE: Number(lodashGet(Config, 'EXPENSIFY_ACCOUNT_ID_SBE', 15305309)),
STUDENT_AMBASSADOR: Number(lodashGet(Config, 'EXPENSIFY_ACCOUNT_ID_STUDENT_AMBASSADOR', 10476956)),
SVFG: Number(lodashGet(Config, 'EXPENSIFY_ACCOUNT_ID_SVFG', 2012843)),
},
Expand Down Expand Up @@ -1221,6 +1225,8 @@ const CONST = {
this.EMAIL.QA,
this.EMAIL.QA_TRAVIS,
this.EMAIL.RECEIPTS,
this.EMAIL.SAASTR,
this.EMAIL.SBE,
this.EMAIL.STUDENT_AMBASSADOR,
this.EMAIL.SVFG,
];
Expand All @@ -1241,6 +1247,8 @@ const CONST = {
this.ACCOUNT_ID.QA_TRAVIS,
this.ACCOUNT_ID.RECEIPTS,
this.ACCOUNT_ID.REWARDS,
this.ACCOUNT_ID.SAASTR,
this.ACCOUNT_ID.SBE,
this.ACCOUNT_ID.STUDENT_AMBASSADOR,
this.ACCOUNT_ID.SVFG,
];
Expand Down Expand Up @@ -2584,6 +2592,10 @@ const CONST = {
NAVIGATE: 'NAVIGATE',
},
},
DEMO_PAGES: {
SAASTR: 'SaaStrDemoSetup',
SBE: 'SbeDemoSetup',
},
Comment on lines +2595 to +2598

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

NAB. This belongs to SCREENS.

@cristipaval cristipaval Aug 22, 2023

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Agree, I think we could do a follow-up to clean this up. But let's keep moving for now.

};

export default CONST;
11 changes: 9 additions & 2 deletions src/Expensify.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import KeyboardShortcutsModal from './components/KeyboardShortcutsModal';
import AppleAuthWrapper from './components/SignInButtons/AppleAuthWrapper';
import EmojiPicker from './components/EmojiPicker/EmojiPicker';
import * as EmojiPickerAction from './libs/actions/EmojiPickerAction';
import * as DemoActions from './libs/actions/DemoActions';
import DeeplinkWrapper from './components/DeeplinkWrapper';

// This lib needs to be imported, but it has nothing to export since all it contains is an Onyx connection
Expand Down Expand Up @@ -163,10 +164,16 @@ function Expensify(props) {
appStateChangeListener.current = AppState.addEventListener('change', initializeClient);

// If the app is opened from a deep link, get the reportID (if exists) from the deep link and navigate to the chat report
Linking.getInitialURL().then((url) => Report.openReportFromDeepLink(url, isAuthenticated));
Linking.getInitialURL().then((url) => {
DemoActions.runDemoByURL(url);
Report.openReportFromDeepLink(url, isAuthenticated);
});

// Open chat report from a deep link (only mobile native)
Linking.addEventListener('url', (state) => Report.openReportFromDeepLink(state.url, isAuthenticated));
Linking.addEventListener('url', (state) => {
DemoActions.runDemoByURL(state.url);
Report.openReportFromDeepLink(state.url, isAuthenticated);
});

return () => {
if (!appStateChangeListener.current) {
Expand Down
3 changes: 3 additions & 0 deletions src/ONYXKEYS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,9 @@ const ONYXKEYS = {
// The access token to be used with the Mapbox library
MAPBOX_ACCESS_TOKEN: 'mapboxAccessToken',

// Information on any active demos being run
DEMO_INFO: 'demoInfo',

/** Collection Keys */
COLLECTION: {
DOWNLOAD: 'download_',
Expand Down
5 changes: 4 additions & 1 deletion src/ROUTES.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ export default {
return `bank-account/${stepToOpen}?policyID=${policyID}${backToParam}`;
},
HOME: '',
SAASTR_HOME: 'saastr',
SETTINGS: 'settings',
SETTINGS_PROFILE: 'settings/profile',
SETTINGS_SHARE_CODE: 'settings/shareCode',
Expand Down Expand Up @@ -186,6 +185,10 @@ export default {
getWorkspaceTravelRoute: (policyID) => `workspace/${policyID}/travel`,
getWorkspaceMembersRoute: (policyID) => `workspace/${policyID}/members`,

// These are some on-off routes that will be removed once they're no longer needed (see GH issues for details)
SAASTR: 'saastr',
SBE: 'sbe',

/**
* @param {String} route
* @returns {Object}
Expand Down
9 changes: 8 additions & 1 deletion src/languages/en.js
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,6 @@ export default {
hero: {
header: 'Split bills, request payments, and chat with friends.',
body: 'Welcome to the future of Expensify, your new go-to place for financial collaboration with friends and teammates alike.',
demoHeadline: 'Welcome to SaaStr! Hop in to start networking now.',
},
},
thirdPartySignIn: {
Expand Down Expand Up @@ -1629,4 +1628,12 @@ export default {
stateSelectorModal: {
placeholderText: 'Search to see options',
},
demos: {
saastr: {
signInWelcome: 'Welcome to SaaStr! Hop in to start networking now.',
},
sbe: {
signInWelcome: 'Welcome to Small Business Expo! Get paid back for your ride.',
},
},
};
9 changes: 8 additions & 1 deletion src/languages/es.js
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,6 @@ export default {
hero: {
header: 'Divida las facturas, solicite pagos y chatee con sus amigos.',
body: 'Bienvenido al futuro de Expensify, tu nuevo lugar de referencia para la colaboración financiera con amigos y compañeros de equipo por igual.',
demoHeadline: '¡Bienvenido a SaaStr! Entra y empieza a establecer contactos.',
},
},
thirdPartySignIn: {
Expand Down Expand Up @@ -2116,4 +2115,12 @@ export default {
stateSelectorModal: {
placeholderText: 'Buscar para ver opciones',
},
demos: {
saastr: {
signInWelcome: '¡Bienvenido a SaaStr! Entra y empieza a establecer contactos.',
},
sbe: {
signInWelcome: '¡Bienvenido a Small Business Expo! Recupera el dinero de tu viaje.',
},
},
};
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ import React from 'react';
import {createStackNavigator} from '@react-navigation/stack';
import SCREENS from '../../../../SCREENS';
import ReportScreenWrapper from '../ReportScreenWrapper';
import DemoSetupPage from '../../../../pages/DemoSetupPage';
import getCurrentUrl from '../../currentUrl';
import styles from '../../../../styles/styles';
import FreezeWrapper from '../../FreezeWrapper';
import CONST from '../../../../CONST';

const Stack = createStackNavigator();

Expand All @@ -28,6 +30,22 @@ function CentralPaneNavigator() {
}}
component={ReportScreenWrapper}
/>
<Stack.Screen
name={CONST.DEMO_PAGES.SAASTR}
options={{
headerShown: false,
title: 'New Expensify',
}}
component={DemoSetupPage}
/>
<Stack.Screen
name={CONST.DEMO_PAGES.SBE}
options={{
headerShown: false,
title: 'New Expensify',
}}
component={DemoSetupPage}
/>
</Stack.Navigator>
</FreezeWrapper>
);
Expand Down
6 changes: 0 additions & 6 deletions src/libs/Navigation/AppNavigator/PublicScreens.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import React from 'react';
import {createStackNavigator} from '@react-navigation/stack';
import SignInPage from '../../../pages/signin/SignInPage';
import DemoSetupPage from '../../../pages/signin/DemoSetupPage';
import ValidateLoginPage from '../../../pages/ValidateLoginPage';
import LogInWithShortLivedAuthTokenPage from '../../../pages/LogInWithShortLivedAuthTokenPage';
import SCREENS from '../../../SCREENS';
Expand All @@ -20,11 +19,6 @@ function PublicScreens() {
options={defaultScreenOptions}
component={SignInPage}
/>
<RootStack.Screen
name="SaaStrHome"
options={defaultScreenOptions}
component={DemoSetupPage}
/>
<RootStack.Screen
name={SCREENS.TRANSITION_BETWEEN_APPS}
options={defaultScreenOptions}
Expand Down
3 changes: 2 additions & 1 deletion src/libs/Navigation/linkingConfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ export default {
GoogleSignInDesktop: ROUTES.GOOGLE_SIGN_IN,
DesktopSignInRedirect: ROUTES.DESKTOP_SIGN_IN_REDIRECT,
[SCREENS.REPORT_ATTACHMENTS]: ROUTES.REPORT_ATTACHMENTS,
SaaStrHome: ROUTES.SAASTR_HOME,

// Sidebar
[SCREENS.HOME]: {
Expand All @@ -27,6 +26,8 @@ export default {
[NAVIGATORS.CENTRAL_PANE_NAVIGATOR]: {
screens: {
[SCREENS.REPORT]: ROUTES.REPORT_WITH_ID,
[CONST.DEMO_PAGES.SAASTR]: ROUTES.SAASTR,
[CONST.DEMO_PAGES.SBE]: ROUTES.SBE,
},
},
[NAVIGATORS.FULL_SCREEN_NAVIGATOR]: {
Expand Down
18 changes: 18 additions & 0 deletions src/libs/ReportUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -3104,6 +3104,23 @@ function getPolicy(policyID) {
return policy;
}

/**
* @param {String} policyOwner
* @returns {String|null}
*/
function getPolicyExpenseChatReportIDByOwner(policyOwner) {
const policyWithOwner = _.find(allPolicies, (policy) => policy.owner === policyOwner);
if (!policyWithOwner) {
return null;
}

const expenseChat = _.find(allReports, (report) => isPolicyExpenseChat(report) && report.policyID === policyWithOwner.id);
if (!expenseChat) {
return null;
}
return expenseChat.reportID;
}

/*
* @param {Object|null} report
* @returns {Boolean}
Expand Down Expand Up @@ -3394,6 +3411,7 @@ export {
getReportOfflinePendingActionAndErrors,
isDM,
getPolicy,
getPolicyExpenseChatReportIDByOwner,
shouldDisableSettings,
shouldDisableRename,
hasSingleParticipant,
Expand Down
92 changes: 92 additions & 0 deletions src/libs/actions/DemoActions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import Onyx from 'react-native-onyx';
import _ from 'underscore';
import lodashGet from 'lodash/get';
import CONST from '../../CONST';
import * as API from '../API';
import * as ReportUtils from '../ReportUtils';
import Navigation from '../Navigation/Navigation';
import ROUTES from '../../ROUTES';
import ONYXKEYS from '../../ONYXKEYS';
import * as Localize from '../Localize';

/**
* @param {String} workspaceOwnerEmail email of the workspace owner
* @param {String} apiCommand
*/
function createDemoWorkspaceAndNavigate(workspaceOwnerEmail, apiCommand) {
// Try to navigate to existing demo workspace expense chat if it exists in Onyx
const demoWorkspaceChatReportID = ReportUtils.getPolicyExpenseChatReportIDByOwner(workspaceOwnerEmail);
if (demoWorkspaceChatReportID) {
// We must call goBack() to remove the demo route from nav history
Navigation.goBack();
Navigation.navigate(ROUTES.getReportRoute(demoWorkspaceChatReportID));
return;
}

// We use makeRequestWithSideEffects here because we need to get the workspace chat report ID to navigate to it after it's created
// eslint-disable-next-line rulesdir/no-api-side-effects-method
API.makeRequestWithSideEffects(apiCommand).then((response) => {
// Get report updates from Onyx response data
const reportUpdate = _.find(response.onyxData, ({key}) => key === ONYXKEYS.COLLECTION.REPORT);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Did you mean to check if the key starts with ONYXKEYS.COLLECTION.REPORT? And are we guaranteed to always have one report update?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We're receiving an onyx update here which has the mergecollection onyx method. So the key check is correct here.

if (!reportUpdate) {
return;
}
Comment on lines +31 to +33

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Shouldn't we call goBack here? Otherwise we may get stuck at the loader indicator

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The thing is that most of the Saastr attendees will land on this page after signup, so I'm not sure goBack would help. But we have a follow-up issue to add proper error handling with a new page related to Saastr.


// Get the policy expense chat update
const policyExpenseChatReport = _.find(reportUpdate.value, ({chatType}) => chatType === CONST.REPORT.CHAT_TYPE.POLICY_EXPENSE_CHAT);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

For a report we only have one object in value. We don't need _.find. reportUpdate.value.chatType should be enough.

If that's the case we can merge this with the above _.find

_.find(response.onyxData, ({key, value}) => key.startsWith(ONYXKEYS.COLLECTION.REPORT) && value?.chatType === CONST.REPORT.CHAT_TYPE.POLICY_EXPENSE_CHAT);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

again, here we are handling an onyx update of method mergecollection, where the value is an array

if (!policyExpenseChatReport) {
return;
}

// Navigate to the new policy expense chat report
// Note: We must call goBack() to remove the demo route from history
Navigation.goBack();
Navigation.navigate(ROUTES.getReportRoute(policyExpenseChatReport.reportID));
});
}

function runSbeDemo() {
createDemoWorkspaceAndNavigate(CONST.EMAIL.SBE, 'CreateSbeDemoWorkspace');
}

function runSaastrDemo() {
createDemoWorkspaceAndNavigate(CONST.EMAIL.SAASTR, 'CreateSaastrDemoWorkspace');
}

/**
* Runs code for specific demos, based on the provided URL
*
* @param {String} url - URL user is navigating to via deep link (or regular link in web)
*/
function runDemoByURL(url = '') {
const cleanUrl = (url || '').toLowerCase();

if (cleanUrl.endsWith(ROUTES.SAASTR)) {
Onyx.set(ONYXKEYS.DEMO_INFO, {
saastr: {
isBeginningDemo: true,
},
});
} else if (cleanUrl.endsWith(ROUTES.SBE)) {
Onyx.set(ONYXKEYS.DEMO_INFO, {
sbe: {
isBeginningDemo: true,
},
});
} else {
// No demo is being run, so clear out demo info
Onyx.set(ONYXKEYS.DEMO_INFO, null);
}
}

function getHeadlineKeyByDemoInfo(demoInfo = {}) {
if (lodashGet(demoInfo, 'saastr.isBeginningDemo')) {
return Localize.translateLocal('demos.saastr.signInWelcome');
}
if (lodashGet(demoInfo, 'sbe.isBeginningDemo')) {
return Localize.translateLocal('demos.sbe.signInWelcome');
}
return '';
}

export {runSaastrDemo, runSbeDemo, runDemoByURL, getHeadlineKeyByDemoInfo};
41 changes: 41 additions & 0 deletions src/pages/DemoSetupPage.js
Comment thread
cristipaval marked this conversation as resolved.
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import React from 'react';
import PropTypes from 'prop-types';
import {useFocusEffect} from '@react-navigation/native';
import FullScreenLoadingIndicator from '../components/FullscreenLoadingIndicator';
import CONST from '../CONST';
import * as DemoActions from '../libs/actions/DemoActions';
import Navigation from '../libs/Navigation/Navigation';

const propTypes = {
/** Navigation route context info provided by react navigation */
route: PropTypes.shape({
/** The exact route name used to get to this screen */
name: PropTypes.string.isRequired,
}).isRequired,
};

/*
* This is a "utility page", that does this:
* - Looks at the current route
* - Determines if there's a demo command we need to call
* - If not, routes back to home
*/
function DemoSetupPage(props) {
useFocusEffect(() => {
// Depending on the route that the user hit to get here, run a specific demo flow
if (props.route.name === CONST.DEMO_PAGES.SAASTR) {
DemoActions.runSaastrDemo();
} else if (props.route.name === CONST.DEMO_PAGES.SBE) {
DemoActions.runSbeDemo();
} else {
Navigation.goBack();
}
});

return <FullScreenLoadingIndicator />;
}

DemoSetupPage.propTypes = propTypes;
DemoSetupPage.displayName = 'DemoSetupPage';

export default DemoSetupPage;
Loading