diff --git a/.github/workflows/platformDeploy.yml b/.github/workflows/platformDeploy.yml
index dd169a25c63d..640d1eaa1172 100644
--- a/.github/workflows/platformDeploy.yml
+++ b/.github/workflows/platformDeploy.yml
@@ -372,11 +372,11 @@ jobs:
needs: validateActor
if: ${{ fromJSON(needs.validateActor.outputs.IS_DEPLOYER) && github.event_name == 'push' }}
steps:
- - name: Get version
- run: echo "VERSION=$(npm run print-version --silent)" >> "$GITHUB_ENV"
+ - name: Checkout
+ uses: actions/checkout@v4
- name: 'Deploy HybridApp'
- run: gh workflow run --repo Expensify/Mobile-Deploy deploy.yml -f force_build=true -f build_version=${{ env.VERSION }}
+ run: gh workflow run --repo Expensify/Mobile-Deploy deploy.yml -f force_build=true -f build_version="$(npm run print-version --silent)"
env:
GITHUB_TOKEN: ${{ secrets.OS_BOTIFY_TOKEN }}
diff --git a/android/app/build.gradle b/android/app/build.gradle
index fd3e0eb64d58..32dc2a6cc4af 100644
--- a/android/app/build.gradle
+++ b/android/app/build.gradle
@@ -107,8 +107,8 @@ android {
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
multiDexEnabled rootProject.ext.multiDexEnabled
- versionCode 1009000002
- versionName "9.0.0-2"
+ versionCode 1009000003
+ versionName "9.0.0-3"
// Supported language variants must be declared here to avoid from being removed during the compilation.
// This also helps us to not include unnecessary language variants in the APK.
resConfigs "en", "es"
diff --git a/docs/articles/new-expensify/expenses/Manually-submit-reports-for-approval.md b/docs/Hidden/Manually-submit-reports-for-approval.md
similarity index 100%
rename from docs/articles/new-expensify/expenses/Manually-submit-reports-for-approval.md
rename to docs/Hidden/Manually-submit-reports-for-approval.md
diff --git a/docs/redirects.csv b/docs/redirects.csv
index 13463327d06d..b4912a629918 100644
--- a/docs/redirects.csv
+++ b/docs/redirects.csv
@@ -201,3 +201,4 @@ https://help.expensify.com/articles/expensify-classic/workspaces/reports/Report-
https://help.expensify.com/articles/expensify-classic/workspaces/reports/Scheduled-Submit,https://help.expensify.com/articles/expensify-classic/reports/Automatically-submit-employee-reports
https://help.expensify.com/articles/new-expensify/chat/Expensify-Chat-For-Admins,https://help.expensify.com/new-expensify/hubs/chat/
https://help.expensify.com/articles/new-expensify/bank-accounts-and-payments/Connect-a-Bank-Account.html,https://help.expensify.com/articles/new-expensify/expenses/Connect-a-Business-Bank-Account
+https://help.expensify.com/articles/new-expensify/expenses/Manually-submit-reports-for-approval,https://help.expensify.com/new-expensify/hubs/expenses/
diff --git a/ios/NewExpensify/Info.plist b/ios/NewExpensify/Info.plist
index 94b35ee850b9..38eac98100b2 100644
--- a/ios/NewExpensify/Info.plist
+++ b/ios/NewExpensify/Info.plist
@@ -40,7 +40,7 @@
CFBundleVersion
- 9.0.0.2
+ 9.0.0.3
FullStory
OrgId
diff --git a/ios/NewExpensifyTests/Info.plist b/ios/NewExpensifyTests/Info.plist
index 4770a8c3cff2..9f14bfdf9b2f 100644
--- a/ios/NewExpensifyTests/Info.plist
+++ b/ios/NewExpensifyTests/Info.plist
@@ -19,6 +19,6 @@
CFBundleSignature
????
CFBundleVersion
- 9.0.0.2
+ 9.0.0.3
diff --git a/ios/NotificationServiceExtension/Info.plist b/ios/NotificationServiceExtension/Info.plist
index fbda3047916a..f285614ce618 100644
--- a/ios/NotificationServiceExtension/Info.plist
+++ b/ios/NotificationServiceExtension/Info.plist
@@ -13,7 +13,7 @@
CFBundleShortVersionString
9.0.0
CFBundleVersion
- 9.0.0.2
+ 9.0.0.3
NSExtension
NSExtensionPointIdentifier
diff --git a/package-lock.json b/package-lock.json
index d6bdfed26b63..167dec05497f 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "new.expensify",
- "version": "9.0.0-2",
+ "version": "9.0.0-3",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "new.expensify",
- "version": "9.0.0-2",
+ "version": "9.0.0-3",
"hasInstallScript": true,
"license": "MIT",
"dependencies": {
diff --git a/package.json b/package.json
index 88bbbcd12436..e520f430541e 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "new.expensify",
- "version": "9.0.0-2",
+ "version": "9.0.0-3",
"author": "Expensify, Inc.",
"homepage": "https://new.expensify.com",
"description": "New Expensify is the next generation of Expensify: a reimagination of payments based atop a foundation of chat.",
diff --git a/src/CONST.ts b/src/CONST.ts
index bff8ced87b5c..71ef5e26f7ae 100755
--- a/src/CONST.ts
+++ b/src/CONST.ts
@@ -363,6 +363,7 @@ const CONST = {
SPOTNANA_TRAVEL: 'spotnanaTravel',
ACCOUNTING_ON_NEW_EXPENSIFY: 'accountingOnNewExpensify',
XERO_ON_NEW_EXPENSIFY: 'xeroOnNewExpensify',
+ NETSUITE_ON_NEW_EXPENSIFY: 'netsuiteOnNewExpensify',
REPORT_FIELDS_FEATURE: 'reportFieldsFeature',
},
BUTTON_STATES: {
@@ -1799,6 +1800,7 @@ const CONST = {
// Here we will add other connections names when we add support for them
QBO: 'quickbooksOnline',
XERO: 'xero',
+ NETSUITE: 'netsuite',
},
SYNC_STAGE_NAME: {
STARTING_IMPORT_QBO: 'startingImportQBO',
diff --git a/src/components/MapView/MapView.tsx b/src/components/MapView/MapView.tsx
index cf3f1ec4eda4..c6be99297182 100644
--- a/src/components/MapView/MapView.tsx
+++ b/src/components/MapView/MapView.tsx
@@ -166,8 +166,41 @@ const MapView = forwardRef(
});
}, [directionCoordinates, currentPosition, mapPadding, waypoints]);
- const centerCoordinate = currentPosition ? [currentPosition.longitude, currentPosition.latitude] : initialState?.location;
- return !isOffline && !!accessToken && !!currentPosition ? (
+ const centerCoordinate = useMemo(() => (currentPosition ? [currentPosition.longitude, currentPosition.latitude] : initialState?.location), [currentPosition, initialState?.location]);
+
+ const waypointsBounds = useMemo(() => {
+ if (!waypoints) {
+ return undefined;
+ }
+ const {northEast, southWest} = utils.getBounds(
+ waypoints.map((waypoint) => waypoint.coordinate),
+ directionCoordinates,
+ );
+ return {ne: northEast, sw: southWest};
+ }, [waypoints, directionCoordinates]);
+
+ const defaultSettings: Mapbox.CameraStop | undefined = useMemo(() => {
+ if (interactive) {
+ if (!centerCoordinate) {
+ return undefined;
+ }
+ return {
+ zoomLevel: initialState?.zoom,
+ centerCoordinate,
+ };
+ }
+ if (!waypointsBounds) {
+ return undefined;
+ }
+ return {
+ bounds: waypointsBounds,
+ };
+ }, [interactive, centerCoordinate, waypointsBounds, initialState?.zoom]);
+
+ const initCenterCoordinate = useMemo(() => (interactive ? centerCoordinate : undefined), [interactive, centerCoordinate]);
+ const initBounds = useMemo(() => (interactive ? undefined : waypointsBounds), [interactive, waypointsBounds]);
+
+ return !isOffline && !!accessToken && !!defaultSettings ? (
(
>
-
-
-
+ >
+
+
+ )}
{waypoints?.map(({coordinate, markerComponent, id}) => {
const MarkerComponent = markerComponent;
- if (utils.areSameCoordinate([coordinate[0], coordinate[1]], [currentPosition?.longitude ?? 0, currentPosition?.latitude ?? 0])) {
+ if (utils.areSameCoordinate([coordinate[0], coordinate[1]], [currentPosition?.longitude ?? 0, currentPosition?.latitude ?? 0]) && interactive) {
return null;
}
return (
@@ -235,16 +268,18 @@ const MapView = forwardRef(
{directionCoordinates && }
-
-
-
+ {interactive && (
+
+
+
+ )}
) : (
(
});
}, [directionCoordinates, currentPosition, mapRef, waypoints, mapPadding]);
- return !isOffline && !!accessToken && !!currentPosition ? (
+ const initialViewState: Partial | undefined = useMemo(() => {
+ if (!interactive) {
+ if (!waypoints) {
+ return undefined;
+ }
+ const {northEast, southWest} = utils.getBounds(
+ waypoints.map((waypoint) => waypoint.coordinate),
+ directionCoordinates,
+ );
+ return {
+ zoom: initialState.zoom,
+ bounds: [northEast, southWest],
+ };
+ }
+ return {
+ longitude: currentPosition?.longitude,
+ latitude: currentPosition?.latitude,
+ zoom: initialState.zoom,
+ };
+ }, [waypoints, directionCoordinates, interactive, currentPosition, initialState.zoom]);
+
+ return !isOffline && !!accessToken && !!initialViewState ? (
(
ref={setRef}
mapLib={mapboxgl}
mapboxAccessToken={accessToken}
- initialViewState={{
- longitude: currentPosition?.longitude,
- latitude: currentPosition?.latitude,
- zoom: initialState.zoom,
- }}
+ initialViewState={initialViewState}
style={StyleUtils.getTextColorStyle(theme.mapAttributionText)}
mapStyle={styleURL}
interactive={interactive}
>
-
-
-
+ {interactive && (
+
+
+
+ )}
{waypoints?.map(({coordinate, markerComponent, id}) => {
const MarkerComponent = markerComponent;
- if (utils.areSameCoordinate([coordinate[0], coordinate[1]], [currentPosition?.longitude ?? 0, currentPosition?.latitude ?? 0])) {
+ if (utils.areSameCoordinate([coordinate[0], coordinate[1]], [currentPosition?.longitude ?? 0, currentPosition?.latitude ?? 0]) && interactive) {
return null;
}
return (
@@ -250,15 +269,17 @@ const MapView = forwardRef(
})}
{directionCoordinates && }
-
-
-
+ {interactive && (
+
+
+
+ )}
) : (
route?.name === SCREENS.RIGHT_MODAL.SEARCH_REPORT);
+
// If action type is different than NAVIGATE we can't change it to the PUSH safely
if (action?.type === CONST.NAVIGATION.ACTION_TYPE.NAVIGATE) {
- const topRouteName = rootState?.routes?.at(-1)?.name;
+ const topRouteName = lastRoute?.name;
const isTargetNavigatorOnTop = topRouteName === action.payload.name;
const isTargetScreenDifferentThanCurrent = !!(!topmostCentralPaneRoute || topmostCentralPaneRoute.name !== action.payload.params?.screen);
@@ -201,6 +204,11 @@ export default function linkTo(navigation: NavigationContainerRef): boolean {
return !!betas?.includes(CONST.BETAS.XERO_ON_NEW_EXPENSIFY) || canUseAllBetas(betas);
}
+function canUseNetSuiteIntegration(betas: OnyxEntry): boolean {
+ return !!betas?.includes(CONST.BETAS.NETSUITE_ON_NEW_EXPENSIFY) || canUseAllBetas(betas);
+}
+
function canUseReportFieldsFeature(betas: OnyxEntry): boolean {
return !!betas?.includes(CONST.BETAS.REPORT_FIELDS_FEATURE) || canUseAllBetas(betas);
}
@@ -71,5 +75,6 @@ export default {
canUseSpotnanaTravel,
canUseAccountingIntegrations,
canUseXeroIntegration,
+ canUseNetSuiteIntegration,
canUseReportFieldsFeature,
};
diff --git a/src/libs/SidebarUtils.ts b/src/libs/SidebarUtils.ts
index 4e5185c56cc3..eef98b213dec 100644
--- a/src/libs/SidebarUtils.ts
+++ b/src/libs/SidebarUtils.ts
@@ -117,8 +117,9 @@ function getOrderedReportIDs(
}
const participantAccountIDs = Object.keys(report?.participants ?? {}).map(Number);
+ const isOnboardedByPersona = currentUserAccountID && AccountUtils.isAccountIDOddNumber(currentUserAccountID) && participantAccountIDs.includes(CONST.ACCOUNT_ID.NOTIFICATIONS);
- if (currentUserAccountID && AccountUtils.isAccountIDOddNumber(currentUserAccountID) && participantAccountIDs.includes(CONST.ACCOUNT_ID.NOTIFICATIONS)) {
+ if (isOnboardedByPersona && isSystemChat && !isInFocusMode) {
return true;
}
diff --git a/src/libs/actions/connections/index.ts b/src/libs/actions/connections/index.ts
index 4770722aca21..d0c9fb762a4c 100644
--- a/src/libs/actions/connections/index.ts
+++ b/src/libs/actions/connections/index.ts
@@ -236,6 +236,11 @@ function updateManyPolicyConnectionConfigs, connectionName: PolicyConnectionName, isSyncInProgress: boolean): boolean {
+ // NetSuite does not use the conventional lastSync object, so we need to check for lastErrorSyncDate
+ if (connectionName === CONST.POLICY.CONNECTIONS.NAME.NETSUITE) {
+ return !isSyncInProgress && !!policy?.connections?.[CONST.POLICY.CONNECTIONS.NAME.NETSUITE].lastErrorSyncDate;
+ }
+
return !isSyncInProgress && policy?.connections?.[connectionName]?.lastSync?.isSuccessful === false;
}
diff --git a/src/pages/workspace/accounting/PolicyAccountingPage.tsx b/src/pages/workspace/accounting/PolicyAccountingPage.tsx
index 78dc434b3d2c..f2e3744f92e4 100644
--- a/src/pages/workspace/accounting/PolicyAccountingPage.tsx
+++ b/src/pages/workspace/accounting/PolicyAccountingPage.tsx
@@ -110,7 +110,7 @@ function PolicyAccountingPage({policy, connectionSyncProgress}: PolicyAccounting
const styles = useThemeStyles();
const {translate} = useLocalize();
const {isOffline} = useNetwork();
- const {canUseXeroIntegration} = usePermissions();
+ const {canUseXeroIntegration, canUseNetSuiteIntegration} = usePermissions();
const {isSmallScreenWidth, windowWidth} = useWindowDimensions();
const [threeDotsMenuPosition, setThreeDotsMenuPosition] = useState({horizontal: 0, vertical: 0});
const [isDisconnectModalOpen, setIsDisconnectModalOpen] = useState(false);
@@ -124,7 +124,9 @@ function PolicyAccountingPage({policy, connectionSyncProgress}: PolicyAccounting
isValid(lastSyncProgressDate) &&
differenceInMinutes(new Date(), lastSyncProgressDate) < CONST.POLICY.CONNECTIONS.SYNC_STAGE_TIMEOUT_MINUTES;
- const accountingIntegrations = Object.values(CONST.POLICY.CONNECTIONS.NAME).filter((name) => !(name === CONST.POLICY.CONNECTIONS.NAME.XERO && !canUseXeroIntegration));
+ const accountingIntegrations = Object.values(CONST.POLICY.CONNECTIONS.NAME).filter(
+ (name) => !(name === CONST.POLICY.CONNECTIONS.NAME.XERO && !canUseXeroIntegration) && !(name === CONST.POLICY.CONNECTIONS.NAME.NETSUITE && !canUseNetSuiteIntegration),
+ );
const connectedIntegration = accountingIntegrations.find((integration) => !!policy?.connections?.[integration]) ?? connectionSyncProgress?.connectionName;
const policyID = policy?.id ?? '-1';
const successfulDate = policy?.connections?.quickbooksOnline?.lastSync?.successfulDate;
diff --git a/src/styles/index.ts b/src/styles/index.ts
index b031e665594f..93419580ae2c 100644
--- a/src/styles/index.ts
+++ b/src/styles/index.ts
@@ -1702,7 +1702,7 @@ const styles = (theme: ThemeColors) =>
createMenuContainer: {
width: variables.sideBarWidth - 40,
- paddingVertical: 12,
+ paddingVertical: variables.componentBorderRadiusLarge,
},
createMenuHeaderText: {
diff --git a/src/styles/utils/generators/ModalStyleUtils.ts b/src/styles/utils/generators/ModalStyleUtils.ts
index bc668ba45670..7f51b7727d6a 100644
--- a/src/styles/utils/generators/ModalStyleUtils.ts
+++ b/src/styles/utils/generators/ModalStyleUtils.ts
@@ -75,7 +75,7 @@ const createModalStyleUtils: StyleUtilGenerator = ({the
};
modalContainerStyle = {
boxShadow: '0px 0px 5px 5px rgba(0, 0, 0, 0.1)',
- borderRadius: 12,
+ borderRadius: variables.componentBorderRadiusLarge,
overflow: 'hidden',
width: variables.sideBarWidth,
};
@@ -102,7 +102,7 @@ const createModalStyleUtils: StyleUtilGenerator = ({the
flex: 1,
marginTop: isSmallScreenWidth ? 0 : 20,
marginBottom: isSmallScreenWidth ? 0 : 20,
- borderRadius: isSmallScreenWidth ? 0 : 12,
+ borderRadius: isSmallScreenWidth ? 0 : variables.componentBorderRadiusLarge,
overflow: 'hidden',
...getCenteredModalStyles(styles, windowWidth, isSmallScreenWidth),
};
@@ -129,7 +129,7 @@ const createModalStyleUtils: StyleUtilGenerator = ({the
flex: 1,
marginTop: isSmallScreenWidth ? 0 : 20,
marginBottom: isSmallScreenWidth ? 0 : 20,
- borderRadius: isSmallScreenWidth ? 0 : 12,
+ borderRadius: isSmallScreenWidth ? 0 : variables.componentBorderRadiusLarge,
overflow: 'hidden',
...getCenteredModalStyles(styles, windowWidth, isSmallScreenWidth, true),
};
@@ -151,7 +151,7 @@ const createModalStyleUtils: StyleUtilGenerator = ({the
};
modalContainerStyle = {
boxShadow: '0px 0px 5px 5px rgba(0, 0, 0, 0.1)',
- borderRadius: 12,
+ borderRadius: variables.componentBorderRadiusLarge,
borderWidth: 0,
};
@@ -174,9 +174,9 @@ const createModalStyleUtils: StyleUtilGenerator = ({the
};
modalContainerStyle = {
width: '100%',
- borderTopLeftRadius: 20,
- borderTopRightRadius: 20,
- paddingTop: 12,
+ borderTopLeftRadius: variables.componentBorderRadiusLarge,
+ borderTopRightRadius: variables.componentBorderRadiusLarge,
+ paddingTop: variables.componentBorderRadiusLarge,
justifyContent: 'center',
overflow: 'hidden',
};
@@ -197,7 +197,7 @@ const createModalStyleUtils: StyleUtilGenerator = ({the
},
};
modalContainerStyle = {
- borderRadius: 12,
+ borderRadius: variables.componentBorderRadiusLarge,
borderWidth: 1,
borderColor: theme.border,
justifyContent: 'center',
diff --git a/src/styles/utils/generators/ReportActionContextMenuStyleUtils.ts b/src/styles/utils/generators/ReportActionContextMenuStyleUtils.ts
index e8761468f640..b3f3a816d09a 100644
--- a/src/styles/utils/generators/ReportActionContextMenuStyleUtils.ts
+++ b/src/styles/utils/generators/ReportActionContextMenuStyleUtils.ts
@@ -45,7 +45,7 @@ const createReportActionContextMenuStyleUtils: StyleUtilGenerator