Skip to content

Commit

Permalink
Merge branch 'main' into new-product-training-tooltips
Browse files Browse the repository at this point in the history
  • Loading branch information
ishpaul777 authored Dec 13, 2024
2 parents db57944 + 63636e5 commit b63ecf1
Show file tree
Hide file tree
Showing 88 changed files with 806 additions and 564 deletions.
2 changes: 1 addition & 1 deletion Mobile-Expensify
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -456,7 +456,7 @@ You can only build HybridApp if you have been granted access to [`Mobile-Expensi
## Getting started with HybridApp
1. If you haven't, please follow [these instructions](https://github.com/Expensify/App?tab=readme-ov-file#getting-started) to setup the NewDot local environment.
2. Run `git submodule update --init` to download the `Mobile-Expensify` sourcecode.
2. Run `git submodule update --init --progress` to download the `Mobile-Expensify` sourcecode.
- If you have access to `Mobile-Expensify` and the command fails with a https-related error add this to your `~/.gitconfig` file:

```
Expand Down
4 changes: 2 additions & 2 deletions android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,8 @@ android {
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
multiDexEnabled rootProject.ext.multiDexEnabled
versionCode 1009007502
versionName "9.0.75-2"
versionCode 1009007506
versionName "9.0.75-6"
// 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"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,42 @@
---
title: Accelo Troubleshooting
description: Accelo Troubleshooting
order: 3
description: Resources to help you solve issues with your Accelo integration.
---

# Coming soon
# Overview
Most of the Accelo integration with Expensify is managed on the Accelo side. You will find their [help site](https://help.accelo.com/guides/integrations-guide/expensify/) helpful, especially the [FAQs](https://help.accelo.com/guides/integrations-guide/expensify/#faq).

## Information sync between Expensify and Accelo
The Accelo integration does a one-way sync, bringing expenses from Expensify into Accelo. When this happens, it transfers specific information from Expensify expenses to Accelo:

| Expensify | Accelo |
|---------------------|-----------------------|
| Description | Title |
| Date | Date Incurred |
| Category | Type |
| Tags | Against (relevant Project, Ticket or Retainer) |
| Distance (mileage) | Quantity |
| Hours (time expenses) | Quantity |
| Amount | Purchase Price and Sale Price |
| Reimbursable? | Reimbursable? |
| Billable? | Billable? |
| Receipt | Attachment |
| Tax Rate | Tax Code |
| Attendees | Submitted By |

## Expense Status
The status of your expense report in Expensify is also synced in Accelo.

| Expensify Report Status | Accelo Expense Status |
|-------------------------|-----------------------|
| Open | Submitted |
| Submitted | Submitted |
| Approved | Approved |
| Reimbursed | Approved |
| Rejected | Declined |
| Archived | Approved |
| Closed | Approved |


## Can I use an Accelo and an accounting integration in Expensify at the same time?
Yes, you can use Accelo and an accounting system simultaneously. In order to update your Expensify tags with your Accelo Projects, Tickets, or Retainers, you will need to have a special switch enabled that allows you to have non-accounting tags alongside your accounting connection. Please contact Concierge to request that our support team enable the “Indirect Tag Uploads” switch for you.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion ios/NewExpensify/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
</dict>
</array>
<key>CFBundleVersion</key>
<string>9.0.75.2</string>
<string>9.0.75.6</string>
<key>FullStory</key>
<dict>
<key>OrgId</key>
Expand Down
2 changes: 1 addition & 1 deletion ios/NewExpensifyTests/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,6 @@
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>9.0.75.2</string>
<string>9.0.75.6</string>
</dict>
</plist>
2 changes: 1 addition & 1 deletion ios/NotificationServiceExtension/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
<key>CFBundleShortVersionString</key>
<string>9.0.75</string>
<key>CFBundleVersion</key>
<string>9.0.75.2</string>
<string>9.0.75.6</string>
<key>NSExtension</key>
<dict>
<key>NSExtensionPointIdentifier</key>
Expand Down
23 changes: 21 additions & 2 deletions ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1981,8 +1981,27 @@ PODS:
- ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core
- Yoga
- react-native-view-shot (3.8.0):
- react-native-view-shot (4.0.0):
- DoubleConversion
- glog
- hermes-engine
- RCT-Folly (= 2024.01.01.00)
- RCTRequired
- RCTTypeSafety
- React-Core
- React-debug
- React-Fabric
- React-featureflags
- React-graphics
- React-ImageManager
- React-NativeModulesApple
- React-RCTFabric
- React-rendererdebug
- React-utils
- ReactCodegen
- ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core
- Yoga
- react-native-webview (13.8.6):
- DoubleConversion
- glog
Expand Down Expand Up @@ -3231,7 +3250,7 @@ SPEC CHECKSUMS:
react-native-quick-sqlite: 7c793c9f5834e756b336257a8d8b8239b7ceb451
react-native-release-profiler: 131ec5e4145d900b2be2a8d6641e2ce0dd784259
react-native-safe-area-context: 38fdd9b3c5561de7cabae64bd0cd2ce05d2768a1
react-native-view-shot: 6b7ed61d77d88580fed10954d45fad0eb2d47688
react-native-view-shot: 6bafd491eb295b5834e05c469a37ecbd796d5b22
react-native-webview: ad29375839c9aa0409ce8e8693291b42bdc067a4
React-nativeconfig: 57781b79e11d5af7573e6f77cbf1143b71802a6d
React-NativeModulesApple: 7ff2e2cfb2e5fa5bdedcecf28ce37e696c6ef1e1
Expand Down
10 changes: 6 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "new.expensify",
"version": "9.0.75-2",
"version": "9.0.75-6",
"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.",
Expand Down Expand Up @@ -177,7 +177,7 @@
"react-native-svg": "15.9.0",
"react-native-tab-view": "^3.5.2",
"react-native-url-polyfill": "^2.0.0",
"react-native-view-shot": "3.8.0",
"react-native-view-shot": "4.0.0",
"react-native-vision-camera": "^4.6.1",
"react-native-web": "0.19.13",
"react-native-webview": "13.8.6",
Expand Down
2 changes: 2 additions & 0 deletions src/CONST.ts
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,8 @@ const CONST = {
ANIMATION_GYROSCOPE_VALUE: 0.4,
ANIMATION_PAID_DURATION: 200,
ANIMATION_PAID_CHECKMARK_DELAY: 300,
ANIMATION_THUMBSUP_DURATION: 250,
ANIMATION_THUMBSUP_DELAY: 200,
ANIMATION_PAID_BUTTON_HIDE_DELAY: 1000,
BACKGROUND_IMAGE_TRANSITION_DURATION: 1000,
SCREEN_TRANSITION_END_TIMEOUT: 1000,
Expand Down
4 changes: 4 additions & 0 deletions src/ONYXKEYS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,9 @@ const ONYXKEYS = {
/** The user's Concierge reportID */
CONCIERGE_REPORT_ID: 'conciergeReportID',

/** The user's session that will be preserved when using imported state */
PRESERVED_USER_SESSION: 'preservedUserSession',

/** Collection Keys */
COLLECTION: {
DOWNLOAD: 'download_',
Expand Down Expand Up @@ -1014,6 +1017,7 @@ type OnyxValuesMapping = {
[ONYXKEYS.IS_USING_IMPORTED_STATE]: boolean;
[ONYXKEYS.NVP_EXPENSIFY_COMPANY_CARDS_CUSTOM_NAMES]: Record<string, string>;
[ONYXKEYS.CONCIERGE_REPORT_ID]: string;
[ONYXKEYS.PRESERVED_USER_SESSION]: OnyxTypes.Session;
[ONYXKEYS.NVP_DISMISSED_PRODUCT_TRAINING]: OnyxTypes.DismissedProductTraining;
};
type OnyxValues = OnyxValuesMapping & OnyxCollectionValuesMapping & OnyxFormValuesMapping & OnyxFormDraftValuesMapping;
Expand Down
2 changes: 1 addition & 1 deletion src/components/AmountTextInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ type AmountTextInputProps = {

/** Hide the focus styles on TextInput */
hideFocusedState?: boolean;
} & Pick<BaseTextInputProps, 'autoFocus' | 'autoGrowExtraSpace'>;
} & Pick<BaseTextInputProps, 'autoFocus'>;

function AmountTextInput(
{
Expand Down
30 changes: 7 additions & 23 deletions src/components/ArchivedReportFooter.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import lodashEscape from 'lodash/escape';
import React from 'react';
import type {OnyxEntry} from 'react-native-onyx';
import {withOnyx} from 'react-native-onyx';
import {useOnyx} from 'react-native-onyx';
import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';
import {getCurrentUserAccountID} from '@libs/actions/Report';
Expand All @@ -10,26 +9,20 @@ import * as ReportActionsUtils from '@libs/ReportActionsUtils';
import * as ReportUtils from '@libs/ReportUtils';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import type {PersonalDetailsList, Report, ReportAction} from '@src/types/onyx';
import type {Report} from '@src/types/onyx';
import Banner from './Banner';

type ArchivedReportFooterOnyxProps = {
/** The reason this report was archived */
reportClosedAction: OnyxEntry<ReportAction>;

/** Personal details of all users */
personalDetails: OnyxEntry<PersonalDetailsList>;
};

type ArchivedReportFooterProps = ArchivedReportFooterOnyxProps & {
type ArchivedReportFooterProps = {
/** The archived report */
report: Report;
};

function ArchivedReportFooter({report, reportClosedAction, personalDetails = {}}: ArchivedReportFooterProps) {
function ArchivedReportFooter({report}: ArchivedReportFooterProps) {
const styles = useThemeStyles();
const {translate} = useLocalize();

const [personalDetails] = useOnyx(ONYXKEYS.PERSONAL_DETAILS_LIST, {initialValue: {}});
const [reportClosedAction] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report.reportID}`, {canEvict: false, selector: ReportActionsUtils.getLastClosedReportAction});
const originalMessage = ReportActionsUtils.isClosedAction(reportClosedAction) ? ReportActionsUtils.getOriginalMessage(reportClosedAction) : null;
const archiveReason = originalMessage?.reason ?? CONST.REPORT.ARCHIVE_REASON.DEFAULT;
const actorPersonalDetails = personalDetails?.[reportClosedAction?.actorAccountID ?? -1];
Expand Down Expand Up @@ -78,13 +71,4 @@ function ArchivedReportFooter({report, reportClosedAction, personalDetails = {}}

ArchivedReportFooter.displayName = 'ArchivedReportFooter';

export default withOnyx<ArchivedReportFooterProps, ArchivedReportFooterOnyxProps>({
personalDetails: {
key: ONYXKEYS.PERSONAL_DETAILS_LIST,
},
reportClosedAction: {
key: ({report}) => `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report.reportID}`,
canEvict: false,
selector: ReportActionsUtils.getLastClosedReportAction,
},
})(ArchivedReportFooter);
export default ArchivedReportFooter;
17 changes: 7 additions & 10 deletions src/components/ImportOnyxState/index.native.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import React, {useState} from 'react';
import ReactNativeBlobUtil from 'react-native-blob-util';
import Onyx from 'react-native-onyx';
import Onyx, {useOnyx} from 'react-native-onyx';
import type {FileObject} from '@components/AttachmentModal';
import {KEYS_TO_PRESERVE, setIsUsingImportedState} from '@libs/actions/App';
import {KEYS_TO_PRESERVE, setIsUsingImportedState, setPreservedUserSession} from '@libs/actions/App';
import {setShouldForceOffline} from '@libs/actions/Network';
import Navigation from '@libs/Navigation/Navigation';
import type {OnyxValues} from '@src/ONYXKEYS';
import ONYXKEYS from '@src/ONYXKEYS';
import ROUTES from '@src/ROUTES';
import BaseImportOnyxState from './BaseImportOnyxState';
import type ImportOnyxStateProps from './types';
Expand Down Expand Up @@ -45,8 +46,9 @@ function applyStateInChunks(state: OnyxValues) {
return promise;
}

export default function ImportOnyxState({setIsLoading, isLoading}: ImportOnyxStateProps) {
export default function ImportOnyxState({setIsLoading}: ImportOnyxStateProps) {
const [isErrorModalVisible, setIsErrorModalVisible] = useState(false);
const [session] = useOnyx(ONYXKEYS.SESSION);

const handleFileRead = (file: FileObject) => {
if (!file.uri) {
Expand All @@ -57,6 +59,8 @@ export default function ImportOnyxState({setIsLoading, isLoading}: ImportOnyxSta
readOnyxFile(file.uri)
.then((fileContent: string) => {
const transformedState = cleanAndTransformState<OnyxValues>(fileContent);
const currentUserSessionCopy = {...session};
setPreservedUserSession(currentUserSessionCopy);
setShouldForceOffline(true);
Onyx.clear(KEYS_TO_PRESERVE).then(() => {
applyStateInChunks(transformedState).then(() => {
Expand All @@ -67,14 +71,7 @@ export default function ImportOnyxState({setIsLoading, isLoading}: ImportOnyxSta
})
.catch(() => {
setIsErrorModalVisible(true);
})
.finally(() => {
setIsLoading(false);
});

if (isLoading) {
setIsLoading(false);
}
};

return (
Expand Down
26 changes: 11 additions & 15 deletions src/components/ImportOnyxState/index.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
import React, {useState} from 'react';
import Onyx from 'react-native-onyx';
import Onyx, {useOnyx} from 'react-native-onyx';
import type {FileObject} from '@components/AttachmentModal';
import {KEYS_TO_PRESERVE, setIsUsingImportedState} from '@libs/actions/App';
import {KEYS_TO_PRESERVE, setIsUsingImportedState, setPreservedUserSession} from '@libs/actions/App';
import {setShouldForceOffline} from '@libs/actions/Network';
import Navigation from '@libs/Navigation/Navigation';
import type {OnyxValues} from '@src/ONYXKEYS';
import ONYXKEYS from '@src/ONYXKEYS';
import ROUTES from '@src/ROUTES';
import BaseImportOnyxState from './BaseImportOnyxState';
import type ImportOnyxStateProps from './types';
import {cleanAndTransformState} from './utils';

export default function ImportOnyxState({setIsLoading, isLoading}: ImportOnyxStateProps) {
export default function ImportOnyxState({setIsLoading}: ImportOnyxStateProps) {
const [isErrorModalVisible, setIsErrorModalVisible] = useState(false);
const [session] = useOnyx(ONYXKEYS.SESSION);

const handleFileRead = (file: FileObject) => {
if (!file.uri) {
Expand All @@ -27,26 +29,20 @@ export default function ImportOnyxState({setIsLoading, isLoading}: ImportOnyxSta
.then((text) => {
const fileContent = text;
const transformedState = cleanAndTransformState<OnyxValues>(fileContent);
const currentUserSessionCopy = {...session};
setPreservedUserSession(currentUserSessionCopy);
setShouldForceOffline(true);
Onyx.clear(KEYS_TO_PRESERVE).then(() => {
Onyx.multiSet(transformedState)
.then(() => {
setIsUsingImportedState(true);
Navigation.navigate(ROUTES.HOME);
})
.finally(() => {
setIsLoading(false);
});
Onyx.multiSet(transformedState).then(() => {
setIsUsingImportedState(true);
Navigation.navigate(ROUTES.HOME);
});
});
})
.catch(() => {
setIsErrorModalVisible(true);
setIsLoading(false);
});

if (isLoading) {
setIsLoading(false);
}
};

return (
Expand Down
1 change: 0 additions & 1 deletion src/components/ImportOnyxState/types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
type ImportOnyxStateProps = {
isLoading: boolean;
setIsLoading: (isLoading: boolean) => void;
};

Expand Down
2 changes: 1 addition & 1 deletion src/components/ImportOnyxState/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import type {UnknownRecord} from 'type-fest';
import ONYXKEYS from '@src/ONYXKEYS';

// List of Onyx keys from the .txt file we want to keep for the local override
const keysToOmit = [ONYXKEYS.ACTIVE_CLIENTS, ONYXKEYS.FREQUENTLY_USED_EMOJIS, ONYXKEYS.NETWORK, ONYXKEYS.CREDENTIALS, ONYXKEYS.SESSION, ONYXKEYS.PREFERRED_THEME];
const keysToOmit = [ONYXKEYS.ACTIVE_CLIENTS, ONYXKEYS.FREQUENTLY_USED_EMOJIS, ONYXKEYS.NETWORK, ONYXKEYS.CREDENTIALS, ONYXKEYS.PREFERRED_THEME];

function isRecord(value: unknown): value is Record<string, unknown> {
return typeof value === 'object' && !Array.isArray(value) && value !== null;
Expand Down
Loading

0 comments on commit b63ecf1

Please sign in to comment.