diff --git a/.eslintrc.js b/.eslintrc.js index 22b94d79e369..ac4546567833 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -164,7 +164,7 @@ module.exports = { }, }, { - files: ['tests/**/*.{js,jsx,ts,tsx}', '.github/**/*.{js,jsx,ts,tsx}'], + files: ['workflow_tests/**/*.{js,jsx,ts,tsx}', 'tests/**/*.{js,jsx,ts,tsx}', '.github/**/*.{js,jsx,ts,tsx}'], rules: { '@lwc/lwc/no-async-await': 'off', 'no-await-in-loop': 'off', diff --git a/.github/workflows/cherryPick.yml b/.github/workflows/cherryPick.yml index 494326869cca..b6558b049647 100644 --- a/.github/workflows/cherryPick.yml +++ b/.github/workflows/cherryPick.yml @@ -13,7 +13,8 @@ jobs: outputs: IS_DEPLOYER: ${{ fromJSON(steps.isDeployer.outputs.IS_DEPLOYER) || github.actor == 'OSBotify' }} steps: - - id: isDeployer + - name: Check if user is deployer + id: isDeployer run: | if gh api /orgs/Expensify/teams/mobile-deployers/memberships/${{ github.actor }} --silent; then echo "IS_DEPLOYER=true" >> "$GITHUB_OUTPUT" @@ -39,7 +40,8 @@ jobs: ref: staging token: ${{ secrets.OS_BOTIFY_TOKEN }} - - uses: Expensify/App/.github/actions/composite/setupGitForOSBotify@main + - name: Set up git for OSBotify + uses: Expensify/App/.github/actions/composite/setupGitForOSBotify@main with: GPG_PASSPHRASE: ${{ secrets.LARGE_SECRET_PASSPHRASE }} diff --git a/.github/workflows/cla.yml b/.github/workflows/cla.yml index 8943669c2ba8..54ae1048b57b 100644 --- a/.github/workflows/cla.yml +++ b/.github/workflows/cla.yml @@ -13,18 +13,20 @@ jobs: # It does not run for pull requests created by OSBotify if: ${{ github.event.issue.pull_request || (github.event_name == 'pull_request_target' && github.event.pull_request.user.login != 'OSBotify') }} steps: - - uses: actions-ecosystem/action-regex-match@9c35fe9ac1840239939c59e5db8839422eed8a73 + - name: CLA comment check + uses: actions-ecosystem/action-regex-match@9c35fe9ac1840239939c59e5db8839422eed8a73 id: sign with: text: ${{ github.event.comment.body }} regex: '\s*I have read the CLA Document and I hereby sign the CLA\s*' - - uses: actions-ecosystem/action-regex-match@9c35fe9ac1840239939c59e5db8839422eed8a73 + - name: CLA comment re-check + uses: actions-ecosystem/action-regex-match@9c35fe9ac1840239939c59e5db8839422eed8a73 id: recheck with: text: ${{ github.event.comment.body }} regex: '\s*recheck\s*' - name: CLA Assistant - if: ${{ steps.recheck.outputs.match != '' || steps.sign.outputs.match != '' }} || github.event_name == 'pull_request_target' + if: ${{ steps.recheck.outputs.match != '' || steps.sign.outputs.match != '' || github.event_name == 'pull_request_target' }} # Version: 2.1.2-beta uses: cla-assistant/github-action@948230deb0d44dd38957592f08c6bd934d96d0cf env: diff --git a/.github/workflows/createNewVersion.yml b/.github/workflows/createNewVersion.yml index b2703731df79..ba907334c595 100644 --- a/.github/workflows/createNewVersion.yml +++ b/.github/workflows/createNewVersion.yml @@ -54,18 +54,21 @@ jobs: NEW_VERSION: ${{ steps.bumpVersion.outputs.NEW_VERSION }} steps: - - uses: softprops/turnstyle@ca99add00ff0c9cbc697d22631d2992f377e5bd5 + - name: Run turnstyle + uses: softprops/turnstyle@ca99add00ff0c9cbc697d22631d2992f377e5bd5 with: poll-interval-seconds: 10 env: GITHUB_TOKEN: ${{ github.token }} - - uses: actions/checkout@v3 + - name: Check out + uses: actions/checkout@v3 with: ref: main token: ${{ secrets.OS_BOTIFY_TOKEN }} - - uses: Expensify/App/.github/actions/composite/setupGitForOSBotify@main + - name: Setup git for OSBotify + uses: Expensify/App/.github/actions/composite/setupGitForOSBotify@main with: GPG_PASSPHRASE: ${{ secrets.LARGE_SECRET_PASSPHRASE }} @@ -89,7 +92,8 @@ jobs: - name: Update main branch run: git push origin main - - if: ${{ failure() }} + - name: Announce failed workflow in Slack + if: ${{ failure() }} uses: Expensify/App/.github/actions/composite/announceFailedWorkflowInSlack@main with: SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }} diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index b3105ee05c2c..f2ff67680940 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -15,7 +15,8 @@ jobs: ref: staging token: ${{ secrets.OS_BOTIFY_TOKEN }} - - uses: Expensify/App/.github/actions/composite/setupGitForOSBotify@main + - name: Setup git for OSBotify + uses: Expensify/App/.github/actions/composite/setupGitForOSBotify@main with: GPG_PASSPHRASE: ${{ secrets.LARGE_SECRET_PASSPHRASE }} @@ -29,12 +30,14 @@ jobs: runs-on: ubuntu-latest if: github.ref == 'refs/heads/production' steps: - - uses: actions/checkout@v3 + - name: Checkout + uses: actions/checkout@v3 with: ref: production token: ${{ secrets.OS_BOTIFY_TOKEN }} - - uses: Expensify/App/.github/actions/composite/setupGitForOSBotify@main + - name: Setup git for OSBotify + uses: Expensify/App/.github/actions/composite/setupGitForOSBotify@main with: GPG_PASSPHRASE: ${{ secrets.LARGE_SECRET_PASSPHRASE }} diff --git a/.github/workflows/deployBlocker.yml b/.github/workflows/deployBlocker.yml index 8065a5c88cb2..f42d19ca8241 100644 --- a/.github/workflows/deployBlocker.yml +++ b/.github/workflows/deployBlocker.yml @@ -11,7 +11,8 @@ jobs: if: ${{ github.event.label.name == 'DeployBlockerCash' }} steps: - - uses: actions/checkout@v3 + - name: Checkout + uses: actions/checkout@v3 with: token: ${{ secrets.GITHUB_TOKEN }} @@ -63,7 +64,8 @@ jobs: 2. Find someone who can quickly fix the issue. 3. Fix the issue yourself. - - if: ${{ failure() }} + - name: Announce failed workflow in Slack + if: ${{ failure() }} uses: Expensify/App/.github/actions/composite/announceFailedWorkflowInSlack@main with: SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }} diff --git a/.github/workflows/finishReleaseCycle.yml b/.github/workflows/finishReleaseCycle.yml index 7b71f6263c88..e2323af2486e 100644 --- a/.github/workflows/finishReleaseCycle.yml +++ b/.github/workflows/finishReleaseCycle.yml @@ -23,7 +23,7 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.OS_BOTIFY_TOKEN }} - - name: Reopen and comment on issue + - name: Reopen and comment on issue (not a team member) if: ${{ !fromJSON(steps.isDeployer.outputs.IS_DEPLOYER) }} uses: Expensify/App/.github/actions/javascript/reopenIssueWithComment@main with: @@ -41,8 +41,8 @@ jobs: GITHUB_TOKEN: ${{ secrets.OS_BOTIFY_TOKEN }} ISSUE_NUMBER: ${{ github.event.issue.number }} - - name: Reopen and comment on issue - if: ${{ fromJSON(steps.isDeployer.outputs.IS_DEPLOYER) && fromJSON(steps.checkDeployBlockers.outputs.HAS_DEPLOY_BLOCKERS) }} + - name: Reopen and comment on issue (has blockers) + if: ${{ fromJSON(steps.isDeployer.outputs.IS_DEPLOYER) && fromJSON(steps.checkDeployBlockers.outputs.HAS_DEPLOY_BLOCKERS || 'false') }} uses: Expensify/App/.github/actions/javascript/reopenIssueWithComment@main with: GITHUB_TOKEN: ${{ secrets.OS_BOTIFY_TOKEN }} @@ -51,7 +51,8 @@ jobs: This issue either has unchecked items or has not yet been marked with the `:shipit:` emoji of approval. Reopening! - - if: ${{ failure() }} + - name: Announce failed workflow in Slack + if: ${{ failure() }} uses: Expensify/App/.github/actions/composite/announceFailedWorkflowInSlack@main with: SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }} @@ -62,12 +63,14 @@ jobs: needs: validate if: ${{ fromJSON(needs.validate.outputs.isValid) }} steps: - - uses: actions/checkout@v3 + - name: Checkout + uses: actions/checkout@v3 with: ref: staging token: ${{ secrets.OS_BOTIFY_TOKEN }} - - uses: Expensify/App/.github/actions/composite/setupGitForOSBotify@main + - name: Setup Git for OSBotify + uses: Expensify/App/.github/actions/composite/setupGitForOSBotify@main with: GPG_PASSPHRASE: ${{ secrets.LARGE_SECRET_PASSPHRASE }} @@ -79,7 +82,8 @@ jobs: # Force-update the remote production branch. git push --force origin production - - if: ${{ failure() }} + - name: Announce failed workflow in Slack + if: ${{ failure() }} uses: Expensify/App/.github/actions/composite/announceFailedWorkflowInSlack@main with: SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }} @@ -98,12 +102,14 @@ jobs: runs-on: ubuntu-latest needs: [updateProduction, createNewPatchVersion] steps: - - uses: actions/checkout@v3 + - name: Checkout + uses: actions/checkout@v3 with: ref: main token: ${{ secrets.OS_BOTIFY_TOKEN }} - - uses: Expensify/App/.github/actions/composite/setupGitForOSBotify@main + - name: Setup Git for OSBotify + uses: Expensify/App/.github/actions/composite/setupGitForOSBotify@main with: GPG_PASSPHRASE: ${{ secrets.LARGE_SECRET_PASSPHRASE }} @@ -115,7 +121,8 @@ jobs: # Force-update the remote staging branch git push --force origin staging - - if: ${{ failure() }} + - name: Announce failed workflow in Slack + if: ${{ failure() }} uses: Expensify/App/.github/actions/composite/announceFailedWorkflowInSlack@main with: SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }} diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 1983e406c77b..5953a4aa89e2 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -11,9 +11,11 @@ jobs: if: ${{ github.actor != 'OSBotify' || github.event_name == 'workflow_call' }} runs-on: ubuntu-latest steps: - - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 + - name: Checkout + uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 - - uses: Expensify/App/.github/actions/composite/setupNode@main + - name: Setup Node + uses: Expensify/App/.github/actions/composite/setupNode@main - name: Lint JavaScript and Typescript with ESLint run: npm run lint diff --git a/.github/workflows/lockDeploys.yml b/.github/workflows/lockDeploys.yml index a49a5519f690..6ca025bb2a25 100644 --- a/.github/workflows/lockDeploys.yml +++ b/.github/workflows/lockDeploys.yml @@ -9,7 +9,8 @@ jobs: if: ${{ github.event.label.name == '🔐 LockCashDeploys 🔐' && contains(github.event.issue.labels.*.name, 'StagingDeployCash') && github.actor != 'OSBotify' }} runs-on: macos-12 steps: - - uses: actions/checkout@v3 + - name: Checkout + uses: actions/checkout@v3 with: ref: main token: ${{ secrets.OS_BOTIFY_TOKEN }} @@ -27,7 +28,8 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.OS_BOTIFY_TOKEN }} - - if: ${{ failure() }} + - name: Announce failed workflow + if: ${{ failure() }} uses: Expensify/App/.github/actions/composite/announceFailedWorkflowInSlack@main with: SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }} diff --git a/.github/workflows/platformDeploy.yml b/.github/workflows/platformDeploy.yml index cd65b8451636..ad002e164837 100644 --- a/.github/workflows/platformDeploy.yml +++ b/.github/workflows/platformDeploy.yml @@ -18,7 +18,8 @@ jobs: outputs: IS_DEPLOYER: ${{ fromJSON(steps.isUserDeployer.outputs.IS_DEPLOYER) || github.actor == 'OSBotify' }} steps: - - id: isUserDeployer + - name: Check if user is deployer + id: isUserDeployer run: | if gh api /orgs/Expensify/teams/mobile-deployers/memberships/${{ github.actor }} --silent; then echo "IS_DEPLOYER=true" >> "$GITHUB_OUTPUT" @@ -35,8 +36,10 @@ jobs: if: ${{ github.event_name != 'release' }} needs: validateActor steps: - - uses: actions/checkout@v3 - - uses: Expensify/App/.github/actions/composite/setupNode@main + - name: Checkout + uses: actions/checkout@v3 + - name: Setup Node + uses: Expensify/App/.github/actions/composite/setupNode@main - name: Set version id: getVersion @@ -54,14 +57,17 @@ jobs: if: ${{ fromJSON(needs.validateActor.outputs.IS_DEPLOYER) }} runs-on: ubuntu-latest-xl steps: - - uses: actions/checkout@v3 + - name: Checkout + uses: actions/checkout@v3 - name: Configure MapBox SDK run: ./scripts/setup-mapbox-sdk.sh ${{ secrets.MAPBOX_SDK_DOWNLOAD_TOKEN }} - - uses: Expensify/App/.github/actions/composite/setupNode@main + - name: Setup Node + uses: Expensify/App/.github/actions/composite/setupNode@main - - uses: ruby/setup-ruby@eae47962baca661befdfd24e4d6c34ade04858f7 + - name: Setup Ruby + uses: ruby/setup-ruby@eae47962baca661befdfd24e4d6c34ade04858f7 with: ruby-version: '2.7' bundler-cache: true @@ -128,9 +134,11 @@ jobs: if: ${{ fromJSON(needs.validateActor.outputs.IS_DEPLOYER) }} runs-on: macos-12-xl steps: - - uses: actions/checkout@v3 + - name: Checkout + uses: actions/checkout@v3 - - uses: Expensify/App/.github/actions/composite/setupNode@main + - name: Setup Node + uses: Expensify/App/.github/actions/composite/setupNode@main - name: Decrypt Developer ID Certificate run: cd desktop && gpg --quiet --batch --yes --decrypt --passphrase="$DEVELOPER_ID_SECRET_PASSPHRASE" --output developer_id.p12 developer_id.p12.gpg @@ -165,14 +173,17 @@ jobs: if: ${{ fromJSON(needs.validateActor.outputs.IS_DEPLOYER) }} runs-on: macos-12-xl steps: - - uses: actions/checkout@v3 + - name: Checkout + uses: actions/checkout@v3 - name: Configure MapBox SDK run: ./scripts/setup-mapbox-sdk.sh ${{ secrets.MAPBOX_SDK_DOWNLOAD_TOKEN }} - - uses: Expensify/App/.github/actions/composite/setupNode@main + - name: Setup Node + uses: Expensify/App/.github/actions/composite/setupNode@main - - uses: ruby/setup-ruby@eae47962baca661befdfd24e4d6c34ade04858f7 + - name: Setup Ruby + uses: ruby/setup-ruby@eae47962baca661befdfd24e4d6c34ade04858f7 with: ruby-version: '2.7' bundler-cache: true @@ -267,9 +278,11 @@ jobs: if: ${{ fromJSON(needs.validateActor.outputs.IS_DEPLOYER) }} runs-on: ubuntu-latest-xl steps: - - uses: actions/checkout@v3 + - name: Checkout + uses: actions/checkout@v3 - - uses: Expensify/App/.github/actions/composite/setupNode@main + - name: Setup Node + uses: Expensify/App/.github/actions/composite/setupNode@main - name: Setup Cloudflare CLI run: pip3 install cloudflare @@ -324,7 +337,8 @@ jobs: if: ${{ failure() }} needs: [android, desktop, iOS, web] steps: - - uses: Expensify/App/.github/actions/composite/announceFailedWorkflowInSlack@main + - name: Post Slack message on failure + uses: Expensify/App/.github/actions/composite/announceFailedWorkflowInSlack@main with: SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }} @@ -334,7 +348,8 @@ jobs: if: ${{ success() }} needs: [android, desktop, iOS, web] steps: - - uses: actions/checkout@v3 + - name: Checkout + uses: actions/checkout@v3 - name: Set version run: echo "VERSION=$(npm run print-version --silent)" >> "$GITHUB_ENV" @@ -394,9 +409,11 @@ jobs: if: ${{ always() }} needs: [android, desktop, iOS, web] steps: - - uses: actions/checkout@v3 + - name: Checkout + uses: actions/checkout@v3 - - uses: Expensify/App/.github/actions/composite/setupNode@main + - name: Setup Node + uses: Expensify/App/.github/actions/composite/setupNode@main - name: Set version run: echo "VERSION=$(npm run print-version --silent)" >> "$GITHUB_ENV" diff --git a/.github/workflows/preDeploy.yml b/.github/workflows/preDeploy.yml index e3977734fc50..186490c7baaf 100644 --- a/.github/workflows/preDeploy.yml +++ b/.github/workflows/preDeploy.yml @@ -2,7 +2,8 @@ name: Process new code merged to main on: push: - branches: [main] + branches: + - main jobs: typecheck: @@ -20,12 +21,14 @@ jobs: if: ${{ always() }} steps: - - if: ${{ needs.typecheck.result == 'failure' || needs.lint.result == 'failure' || needs.test.result == 'failure' }} + - name: Announce failed workflow in Slack + if: ${{ needs.typecheck.result == 'failure' || needs.lint.result == 'failure' || needs.test.result == 'failure' }} uses: Expensify/App/.github/actions/composite/announceFailedWorkflowInSlack@main with: SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }} - - if: ${{ needs.typecheck.result == 'failure' || needs.lint.result == 'failure' || needs.test.result == 'failure' }} + - name: Exit failed workflow + if: ${{ needs.typecheck.result == 'failure' || needs.lint.result == 'failure' || needs.test.result == 'failure' }} run: exit 1 chooseDeployActions: @@ -33,7 +36,7 @@ jobs: needs: confirmPassingBuild outputs: MERGED_PR: ${{ steps.getMergedPullRequest.outputs.number }} - SHOULD_DEPLOY: ${{ steps.shouldDeploy.outputs.SHOULD_DEPLOY }} + SHOULD_DEPLOY: ${{ fromJSON(steps.shouldDeploy.outputs.SHOULD_DEPLOY) }} steps: - name: Get merged pull request @@ -75,18 +78,21 @@ jobs: needs: [chooseDeployActions, createNewVersion] runs-on: ubuntu-latest steps: - - uses: softprops/turnstyle@ca99add00ff0c9cbc697d22631d2992f377e5bd5 + - name: Run turnstyle + uses: softprops/turnstyle@ca99add00ff0c9cbc697d22631d2992f377e5bd5 with: poll-interval-seconds: 10 env: GITHUB_TOKEN: ${{ github.token }} - - uses: actions/checkout@v3 + - name: Checkout main + uses: actions/checkout@v3 with: ref: main token: ${{ secrets.OS_BOTIFY_TOKEN }} - - uses: Expensify/App/.github/actions/composite/setupGitForOSBotify@main + - name: Setup Git for OSBotify + uses: Expensify/App/.github/actions/composite/setupGitForOSBotify@main with: GPG_PASSPHRASE: ${{ secrets.LARGE_SECRET_PASSPHRASE }} @@ -98,7 +104,8 @@ jobs: # Force-update the remote staging branch git push --force origin staging - - if: ${{ failure() }} + - name: Announce failed workflow in Slack + if: ${{ failure() }} uses: Expensify/App/.github/actions/composite/announceFailedWorkflowInSlack@main with: SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }} @@ -134,7 +141,8 @@ jobs: if: ${{ github.actor != 'OSBotify' && !fromJSON(needs.isExpensifyEmployee.outputs.IS_EXPENSIFY_EMPLOYEE) }} steps: # Version: 2.3.4 - - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 + - name: Checkout + uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 with: token: ${{ secrets.OS_BOTIFY_TOKEN }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index e79a02281ae0..72bdd0468fd2 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -18,9 +18,11 @@ jobs: chunk: [ 1, 2, 3 ] name: test (job ${{ fromJSON(matrix.chunk) }}) steps: - - uses: actions/checkout@v3 + - name: Checkout + uses: actions/checkout@v3 - - uses: Expensify/App/.github/actions/composite/setupNode@main + - name: Setup Node + uses: Expensify/App/.github/actions/composite/setupNode@main - name: Get number of CPU cores id: cpu-cores @@ -53,9 +55,11 @@ jobs: runs-on: ubuntu-latest name: Shell tests steps: - - uses: actions/checkout@v3 + - name: Checkout + uses: actions/checkout@v3 - - uses: Expensify/App/.github/actions/composite/setupNode@main + - name: Setup Node + uses: Expensify/App/.github/actions/composite/setupNode@main - name: Test CI git logic run: tests/unit/CIGitLogicTest.sh diff --git a/.github/workflows/testBuild.yml b/.github/workflows/testBuild.yml index fd8118895679..755ab6dbaa60 100644 --- a/.github/workflows/testBuild.yml +++ b/.github/workflows/testBuild.yml @@ -19,7 +19,8 @@ jobs: outputs: READY_TO_BUILD: ${{ fromJSON(steps.isExpensifyEmployee.outputs.IS_EXPENSIFY_EMPLOYEE) && fromJSON(steps.hasReadyToBuildLabel.outputs.HAS_READY_TO_BUILD_LABEL) }} steps: - - id: isExpensifyEmployee + - name: Is Expensify employee + id: isExpensifyEmployee run: | if gh api /orgs/Expensify/teams/expensify-expensify/memberships/${{ github.actor }} --silent; then echo "IS_EXPENSIFY_EMPLOYEE=true" >> "$GITHUB_OUTPUT" @@ -70,7 +71,8 @@ jobs: PULL_REQUEST_NUMBER: ${{ github.event.number || github.event.inputs.PULL_REQUEST_NUMBER }} steps: # This action checks-out the repository, so the workflow can access it. - - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 + - name: Checkout + uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 with: ref: ${{ github.event.pull_request.head.sha || needs.getBranchRef.outputs.REF }} @@ -80,9 +82,11 @@ jobs: sed -i 's/ENVIRONMENT=staging/ENVIRONMENT=adhoc/' .env.adhoc echo "PULL_REQUEST_NUMBER=$PULL_REQUEST_NUMBER" >> .env.adhoc - - uses: Expensify/App/.github/actions/composite/setupNode@main + - name: Setup Node + uses: Expensify/App/.github/actions/composite/setupNode@main - - uses: ruby/setup-ruby@eae47962baca661befdfd24e4d6c34ade04858f7 + - name: Setup Ruby + uses: ruby/setup-ruby@eae47962baca661befdfd24e4d6c34ade04858f7 with: ruby-version: '2.7' bundler-cache: true @@ -117,7 +121,8 @@ jobs: MYAPP_UPLOAD_STORE_PASSWORD: ${{ secrets.MYAPP_UPLOAD_STORE_PASSWORD }} MYAPP_UPLOAD_KEY_PASSWORD: ${{ secrets.MYAPP_UPLOAD_KEY_PASSWORD }} - - uses: actions/upload-artifact@v3 + - name: Upload Artifact + uses: actions/upload-artifact@v3 with: name: android path: ./android_paths.json @@ -131,7 +136,8 @@ jobs: runs-on: macos-12-xl steps: # This action checks-out the repository, so the workflow can access it. - - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 + - name: Checkout + uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 with: ref: ${{ github.event.pull_request.head.sha || needs.getBranchRef.outputs.REF }} @@ -144,12 +150,14 @@ jobs: sed -i '' 's/ENVIRONMENT=staging/ENVIRONMENT=adhoc/' .env.adhoc echo "PULL_REQUEST_NUMBER=$PULL_REQUEST_NUMBER" >> .env.adhoc - - uses: Expensify/App/.github/actions/composite/setupNode@main + - name: Setup Node + uses: Expensify/App/.github/actions/composite/setupNode@main - - name: Setup Xcode + - name: Setup XCode run: sudo xcode-select -switch /Applications/Xcode_14.2.app - - uses: ruby/setup-ruby@eae47962baca661befdfd24e4d6c34ade04858f7 + - name: Setup Ruby + uses: ruby/setup-ruby@eae47962baca661befdfd24e4d6c34ade04858f7 with: ruby-version: '2.7' bundler-cache: true @@ -198,7 +206,8 @@ jobs: S3_BUCKET: ad-hoc-expensify-cash S3_REGION: us-east-1 - - uses: actions/upload-artifact@v3 + - name: Upload Artifact + uses: actions/upload-artifact@v3 with: name: ios path: ./ios_paths.json @@ -211,7 +220,8 @@ jobs: PULL_REQUEST_NUMBER: ${{ github.event.number || github.event.inputs.PULL_REQUEST_NUMBER }} runs-on: macos-12-xl steps: - - uses: actions/checkout@v3 + - name: Checkout + uses: actions/checkout@v3 with: ref: ${{ github.event.pull_request.head.sha || needs.getBranchRef.outputs.REF }} @@ -221,7 +231,8 @@ jobs: sed -i '' 's/ENVIRONMENT=staging/ENVIRONMENT=adhoc/' .env.adhoc echo "PULL_REQUEST_NUMBER=$PULL_REQUEST_NUMBER" >> .env.adhoc - - uses: Expensify/App/.github/actions/composite/setupNode@main + - name: Setup Node + uses: Expensify/App/.github/actions/composite/setupNode@main - name: Decrypt Developer ID Certificate run: cd desktop && gpg --quiet --batch --yes --decrypt --passphrase="$DEVELOPER_ID_SECRET_PASSPHRASE" --output developer_id.p12 developer_id.p12.gpg @@ -252,7 +263,8 @@ jobs: PULL_REQUEST_NUMBER: ${{ github.event.number || github.event.inputs.PULL_REQUEST_NUMBER }} runs-on: ubuntu-latest-xl steps: - - uses: actions/checkout@v3 + - name: Checkout + uses: actions/checkout@v3 with: ref: ${{ github.event.pull_request.head.sha || needs.getBranchRef.outputs.REF }} @@ -262,7 +274,8 @@ jobs: sed -i 's/ENVIRONMENT=staging/ENVIRONMENT=adhoc/' .env.adhoc echo "PULL_REQUEST_NUMBER=$PULL_REQUEST_NUMBER" >> .env.adhoc - - uses: Expensify/App/.github/actions/composite/setupNode@main + - name: Setup Node + uses: Expensify/App/.github/actions/composite/setupNode@main - name: Configure AWS Credentials uses: Expensify/App/.github/actions/composite/configureAwsCredentials@main @@ -283,7 +296,7 @@ jobs: postGithubComment: runs-on: ubuntu-latest name: Post a GitHub comment with app download links for testing - needs: [validateActor, getBranchRef, android, ios, desktop, web] + needs: [validateActor, getBranchRef, android, iOS, desktop, web] if: ${{ always() }} env: PULL_REQUEST_NUMBER: ${{ github.event.number || github.event.inputs.PULL_REQUEST_NUMBER }} @@ -294,7 +307,8 @@ jobs: with: ref: ${{ github.event.pull_request.head.sha || needs.getBranchRef.outputs.REF }} - - uses: actions/download-artifact@v3 + - name: Download Artifact + uses: actions/download-artifact@v3 if: ${{ fromJSON(needs.validateActor.outputs.READY_TO_BUILD) }} - name: Read JSONs with android paths @@ -310,7 +324,7 @@ jobs: - name: Read JSONs with iOS paths id: get_ios_path - if: ${{ needs.ios.result == 'success' }} + if: ${{ needs.iOS.result == 'success' }} run: | content_ios="$(cat ./ios/ios_paths.json)" content_ios="${content_ios//'%'/'%25'}" @@ -340,6 +354,6 @@ jobs: IOS: ${{ needs.iOS.result }} WEB: ${{ needs.web.result }} ANDROID_LINK: ${{steps.get_android_path.outputs.android_path}} - DESKTOP_LINK: https://ad-hoc-expensify-cash.s3.amazonaws.com/desktop/${{ env.PULL_REQUEST_NUMBER }}/NewExpensify.dmg + DESKTOP_LINK: https://ad-hoc-expensify-cash.s3.amazonaws.com/desktop/${{ env.PULL_REQUEST_NUMBER }}/NewExpensifyAdHoc.dmg IOS_LINK: ${{steps.get_ios_path.outputs.ios_path}} WEB_LINK: https://${{ env.PULL_REQUEST_NUMBER }}.pr-testing.expensify.com diff --git a/.github/workflows/validateGithubActions.yml b/.github/workflows/validateGithubActions.yml index f496c5e4b27e..bcda941e1b05 100644 --- a/.github/workflows/validateGithubActions.yml +++ b/.github/workflows/validateGithubActions.yml @@ -12,9 +12,11 @@ jobs: if: github.actor != 'OSBotify' runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - name: Checkout + uses: actions/checkout@v3 - - uses: Expensify/App/.github/actions/composite/setupNode@main + - name: Setup Node + uses: Expensify/App/.github/actions/composite/setupNode@main # Rebuild all the actions on this branch and check for a diff. Fail if there is one, # because that would be a sign that the PR author did not rebuild the Github Actions diff --git a/.github/workflows/verifyPodfile.yml b/.github/workflows/verifyPodfile.yml index 64188769f0bd..d8d931e476d1 100644 --- a/.github/workflows/verifyPodfile.yml +++ b/.github/workflows/verifyPodfile.yml @@ -14,8 +14,9 @@ jobs: if: github.actor != 'OSBotify' runs-on: macos-latest steps: - - uses: actions/checkout@v3 - - - uses: Expensify/App/.github/actions/composite/setupNode@main - - - run: ./.github/scripts/verifyPodfile.sh + - name: Checkout + uses: actions/checkout@v3 + - name: Setup Node + uses: Expensify/App/.github/actions/composite/setupNode@main + - name: Verify podfile + run: ./.github/scripts/verifyPodfile.sh diff --git a/.github/workflows/verifySignedCommits.yml b/.github/workflows/verifySignedCommits.yml index e1068e71e041..ee1b0c4c78da 100644 --- a/.github/workflows/verifySignedCommits.yml +++ b/.github/workflows/verifySignedCommits.yml @@ -9,6 +9,7 @@ jobs: verifySignedCommits: runs-on: ubuntu-latest steps: - - uses: Expensify/App/.github/actions/javascript/verifySignedCommits@main + - name: Verify signed commits + uses: Expensify/App/.github/actions/javascript/verifySignedCommits@main with: GITHUB_TOKEN: ${{ github.token }} diff --git a/.gitignore b/.gitignore index 4919ddc1fdc9..aae9baad529f 100644 --- a/.gitignore +++ b/.gitignore @@ -101,3 +101,9 @@ tests/e2e/results/ # Typescript tsconfig.tsbuildinfo + +# Mock-github +/repo/ + +# Workflow test logs +/workflow_tests/logs/ diff --git a/.storybook/theme.js b/.storybook/theme.js index 0867f6a830b5..96631764726f 100644 --- a/.storybook/theme.js +++ b/.storybook/theme.js @@ -7,17 +7,17 @@ export default create({ fontBase: 'ExpensifyNeue-Regular', fontCode: 'monospace', base: 'dark', - appBg: colors.greenHighlightBackground, - colorPrimary: colors.greenDefaultButton, + appBg: colors.darkHighlightBackground, + colorPrimary: colors.darkDefaultButton, colorSecondary: colors.green, - appContentBg: colors.greenAppBackground, - textColor: colors.white, - barTextColor: colors.white, + appContentBg: colors.darkAppBackground, + textColor: colors.darkPrimaryText, + barTextColor: colors.darkPrimaryText, barSelectedColor: colors.green, - barBg: colors.greenAppBackground, - appBorderColor: colors.greenBorders, - inputBg: colors.greenHighlightBackground, - inputBorder: colors.greenBorders, + barBg: colors.darkAppBackground, + appBorderColor: colors.darkBorders, + inputBg: colors.darkHighlightBackground, + inputBorder: colors.darkBorders, appBorderRadius: 8, inputBorderRadius: 8, }); diff --git a/.well-known/apple-app-site-association b/.well-known/apple-app-site-association index 9274dd8c1382..c871764117ed 100644 --- a/.well-known/apple-app-site-association +++ b/.well-known/apple-app-site-association @@ -63,6 +63,14 @@ { "/": "/new/*", "comment": "New Chat" + }, + { + "/": "/workspace/*", + "comment": "Workspace Details" + }, + { + "/": "/teachersunite/*", + "comment": "Teachers Unite!" } ] } diff --git a/android/app/build.gradle b/android/app/build.gradle index 98f7cbfa495c..9986b297a437 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -22,7 +22,7 @@ react { // The list of variants to that are debuggable. For those we're going to // skip the bundling of the JS bundle and the assets. By default is just 'debug'. // If you add flavors like lite, prod, etc. you'll have to list your debuggableVariants. - debuggableVariants = ["developmentDebug"] + debuggableVariants = ["developmentDebug", "productionDebug"] /* Bundling */ // A list containing the node command and its flags. Default is just 'node'. @@ -90,8 +90,8 @@ android { minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion multiDexEnabled rootProject.ext.multiDexEnabled - versionCode 1001036812 - versionName "1.3.68-12" + versionCode 1001037003 + versionName "1.3.70-3" } flavorDimensions "default" diff --git a/android/app/src/development/assets/airshipconfig.properties b/android/app/src/development/assets/airshipconfig.properties index 490f74552f11..43907fcbf251 100644 --- a/android/app/src/development/assets/airshipconfig.properties +++ b/android/app/src/development/assets/airshipconfig.properties @@ -5,4 +5,4 @@ developmentLogLevel = VERBOSE # Notification Customization notificationIcon = ic_notification -notificationAccentColor = #2EAAE2 \ No newline at end of file +notificationAccentColor = #03D47C \ No newline at end of file diff --git a/android/app/src/main/assets/airshipconfig.properties b/android/app/src/main/assets/airshipconfig.properties index 194c4577de8b..e15533fdda4d 100644 --- a/android/app/src/main/assets/airshipconfig.properties +++ b/android/app/src/main/assets/airshipconfig.properties @@ -4,4 +4,4 @@ inProduction = true # Notification Customization notificationIcon = ic_notification -notificationAccentColor = #2EAAE2 \ No newline at end of file +notificationAccentColor = #03D47C \ No newline at end of file diff --git a/config/electronBuilder.config.js b/config/electronBuilder.config.js index da87c93ee367..a5478dbd8f78 100644 --- a/config/electronBuilder.config.js +++ b/config/electronBuilder.config.js @@ -21,6 +21,24 @@ const macIcon = { adhoc: './desktop/icon-adhoc.png', }; +const appIds = { + production: 'com.expensifyreactnative.chat', + staging: 'com.expensifyreactnative.dev.chat', + adhoc: 'com.expensifyreactnative.adhoc.chat', +}; + +const productNames = { + production: 'New Expensify', + staging: 'New Expensify Dev', + adhoc: 'New Expensify AdHoc', +}; + +const artifactNames = { + production: 'NewExpensify.dmg', + staging: 'NewExpensifyDev.dmg', + adhoc: 'NewExpensifyAdHoc.dmg', +}; + const isCorrectElectronEnv = ['production', 'staging', 'adhoc'].includes(process.env.ELECTRON_ENV); if (!isCorrectElectronEnv) { @@ -32,8 +50,8 @@ if (!isCorrectElectronEnv) { * It can be used to create local builds of the same, by omitting the `--publish` flag */ module.exports = { - appId: 'com.expensifyreactnative.chat', - productName: 'New Expensify', + appId: appIds[process.env.ELECTRON_ENV], + productName: productNames[process.env.ELECTRON_ENV], extraMetadata: { version, }, @@ -46,8 +64,8 @@ module.exports = { type: 'distribution', }, dmg: { - title: 'New Expensify', - artifactName: 'NewExpensify.dmg', + title: productNames[process.env.ELECTRON_ENV], + artifactName: artifactNames[process.env.ELECTRON_ENV], internetEnabled: true, }, publish: [ @@ -65,7 +83,7 @@ module.exports = { output: 'desktop-build', }, protocols: { - name: 'New Expensify', + name: productNames[process.env.ELECTRON_ENV], schemes: ['new-expensify'], }, }; diff --git a/ios/NewExpensify.xcodeproj/project.pbxproj b/ios/NewExpensify.xcodeproj/project.pbxproj index d87226269a8b..64ed3fda8b02 100644 --- a/ios/NewExpensify.xcodeproj/project.pbxproj +++ b/ios/NewExpensify.xcodeproj/project.pbxproj @@ -52,6 +52,7 @@ 00E356F11AD99517003FC87E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 02BE6CF80ED1BD2445267F92 /* Pods-NewExpensify.release development.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NewExpensify.release development.xcconfig"; path = "Target Support Files/Pods-NewExpensify/Pods-NewExpensify.release development.xcconfig"; sourceTree = ""; }; 0B09CE5BDAF34DD3573AB4E2 /* Pods-NewExpensify.debug adhoc.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NewExpensify.debug adhoc.xcconfig"; path = "Target Support Files/Pods-NewExpensify/Pods-NewExpensify.debug adhoc.xcconfig"; sourceTree = ""; }; + 0B627F2A465153FFA6E3A4E0 /* Pods-NewExpensify.debugdevelopment.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NewExpensify.debugdevelopment.xcconfig"; path = "Target Support Files/Pods-NewExpensify/Pods-NewExpensify.debugdevelopment.xcconfig"; sourceTree = ""; }; 0CDA8E33287DD650004ECBEC /* AppDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = AppDelegate.mm; path = NewExpensify/AppDelegate.mm; sourceTree = ""; }; 0CDA8E36287DD6A0004ECBEC /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = NewExpensify/Images.xcassets; sourceTree = ""; }; 0E27AA27706D894246E7946D /* Pods-NewExpensify.debug production.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NewExpensify.debug production.xcconfig"; path = "Target Support Files/Pods-NewExpensify/Pods-NewExpensify.debug production.xcconfig"; sourceTree = ""; }; @@ -64,38 +65,49 @@ 13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = NewExpensify/main.m; sourceTree = ""; }; 18D050DF262400AF000D658B /* BridgingFile.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BridgingFile.swift; sourceTree = ""; }; 1DDE5449979A136852B939B5 /* Pods-NewExpensify.release adhoc.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NewExpensify.release adhoc.xcconfig"; path = "Target Support Files/Pods-NewExpensify/Pods-NewExpensify.release adhoc.xcconfig"; sourceTree = ""; }; + 25A4587E168FD67CF890B448 /* Pods-NewExpensify-NewExpensifyTests.debugadhoc.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NewExpensify-NewExpensifyTests.debugadhoc.xcconfig"; path = "Target Support Files/Pods-NewExpensify-NewExpensifyTests/Pods-NewExpensify-NewExpensifyTests.debugadhoc.xcconfig"; sourceTree = ""; }; + 30FFBD291B71222A393D9CC9 /* Pods-NewExpensify.releasedevelopment.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NewExpensify.releasedevelopment.xcconfig"; path = "Target Support Files/Pods-NewExpensify/Pods-NewExpensify.releasedevelopment.xcconfig"; sourceTree = ""; }; 34A8FDD1F9AA58B8F15C8380 /* Pods-NewExpensify.release production.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NewExpensify.release production.xcconfig"; path = "Target Support Files/Pods-NewExpensify/Pods-NewExpensify.release production.xcconfig"; sourceTree = ""; }; 374FB8D528A133A7000D84EF /* OriginImageRequestHandler.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = OriginImageRequestHandler.h; path = NewExpensify/OriginImageRequestHandler.h; sourceTree = ""; }; 374FB8D628A133FE000D84EF /* OriginImageRequestHandler.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = OriginImageRequestHandler.mm; path = NewExpensify/OriginImageRequestHandler.mm; sourceTree = ""; }; 3D393D7ABC1092F1DE91397F /* Pods-NewExpensify-NewExpensifyTests.debug staging.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NewExpensify-NewExpensifyTests.debug staging.xcconfig"; path = "Target Support Files/Pods-NewExpensify-NewExpensifyTests/Pods-NewExpensify-NewExpensifyTests.debug staging.xcconfig"; sourceTree = ""; }; 432FF5842B766535509FC547 /* Pods-NewExpensify-NewExpensifyTests.debug adhoc.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NewExpensify-NewExpensifyTests.debug adhoc.xcconfig"; path = "Target Support Files/Pods-NewExpensify-NewExpensifyTests/Pods-NewExpensify-NewExpensifyTests.debug adhoc.xcconfig"; sourceTree = ""; }; 44BF435285B94E5B95F90994 /* ExpensifyNewKansas-Medium.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "ExpensifyNewKansas-Medium.otf"; path = "../assets/fonts/native/ExpensifyNewKansas-Medium.otf"; sourceTree = ""; }; + 47D5DF3C6779D41BE70CD031 /* Pods-NewExpensify.releaseproduction.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NewExpensify.releaseproduction.xcconfig"; path = "Target Support Files/Pods-NewExpensify/Pods-NewExpensify.releaseproduction.xcconfig"; sourceTree = ""; }; + 4E8BF7B08BA3181991BFCF4B /* Pods-NewExpensify-NewExpensifyTests.releasedevelopment.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NewExpensify-NewExpensifyTests.releasedevelopment.xcconfig"; path = "Target Support Files/Pods-NewExpensify-NewExpensifyTests/Pods-NewExpensify-NewExpensifyTests.releasedevelopment.xcconfig"; sourceTree = ""; }; 52796131E6554494B2DDB056 /* ExpensifyNeue-Bold.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "ExpensifyNeue-Bold.otf"; path = "../assets/fonts/native/ExpensifyNeue-Bold.otf"; sourceTree = ""; }; + 57DBBEDB9692E096D4BA0141 /* Pods-NewExpensify-NewExpensifyTests.releaseproduction.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NewExpensify-NewExpensifyTests.releaseproduction.xcconfig"; path = "Target Support Files/Pods-NewExpensify-NewExpensifyTests/Pods-NewExpensify-NewExpensifyTests.releaseproduction.xcconfig"; sourceTree = ""; }; 6B5211DB0EEB46E12DF4AD2D /* Pods-NewExpensify-NewExpensifyTests.release adhoc.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NewExpensify-NewExpensifyTests.release adhoc.xcconfig"; path = "Target Support Files/Pods-NewExpensify-NewExpensifyTests/Pods-NewExpensify-NewExpensifyTests.release adhoc.xcconfig"; sourceTree = ""; }; 6BE16DA6EFF88513DB1CD47B /* Pods-NewExpensify-NewExpensifyTests.release staging.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NewExpensify-NewExpensifyTests.release staging.xcconfig"; path = "Target Support Files/Pods-NewExpensify-NewExpensifyTests/Pods-NewExpensify-NewExpensifyTests.release staging.xcconfig"; sourceTree = ""; }; + 6F6A514B4DF07A60EC8355BA /* Pods-NewExpensify.debugadhoc.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NewExpensify.debugadhoc.xcconfig"; path = "Target Support Files/Pods-NewExpensify/Pods-NewExpensify.debugadhoc.xcconfig"; sourceTree = ""; }; 6FB387B20AE4E6E98858B6AA /* libPods-NewExpensify-NewExpensifyTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-NewExpensify-NewExpensifyTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 7041848326A8E40900E09F4D /* RCTStartupTimer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = RCTStartupTimer.h; path = NewExpensify/RCTStartupTimer.h; sourceTree = ""; }; 7041848426A8E47D00E09F4D /* RCTStartupTimer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = RCTStartupTimer.m; path = NewExpensify/RCTStartupTimer.m; sourceTree = ""; }; 70CF6E81262E297300711ADC /* BootSplash.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = BootSplash.storyboard; path = NewExpensify/BootSplash.storyboard; sourceTree = ""; }; 75CABB0D0ABB0082FE0EB600 /* Pods-NewExpensify.release staging.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NewExpensify.release staging.xcconfig"; path = "Target Support Files/Pods-NewExpensify/Pods-NewExpensify.release staging.xcconfig"; sourceTree = ""; }; + 8709DF3C8D91F0FC1581CDD7 /* Pods-NewExpensify-NewExpensifyTests.debugdevelopment.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NewExpensify-NewExpensifyTests.debugdevelopment.xcconfig"; path = "Target Support Files/Pods-NewExpensify-NewExpensifyTests/Pods-NewExpensify-NewExpensifyTests.debugdevelopment.xcconfig"; sourceTree = ""; }; 8B28D84EF339436DBD42A203 /* ExpensifyNeue-BoldItalic.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "ExpensifyNeue-BoldItalic.otf"; path = "../assets/fonts/native/ExpensifyNeue-BoldItalic.otf"; sourceTree = ""; }; 8D3B36BF88E773E3C1A383FA /* Pods-NewExpensify.debug staging.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NewExpensify.debug staging.xcconfig"; path = "Target Support Files/Pods-NewExpensify/Pods-NewExpensify.debug staging.xcconfig"; sourceTree = ""; }; 96552D489D9F09B6A5ABD81B /* Pods-NewExpensify-NewExpensifyTests.release production.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NewExpensify-NewExpensifyTests.release production.xcconfig"; path = "Target Support Files/Pods-NewExpensify-NewExpensifyTests/Pods-NewExpensify-NewExpensifyTests.release production.xcconfig"; sourceTree = ""; }; AEFE6CD54912D427D19133C7 /* libPods-NewExpensify.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-NewExpensify.a"; sourceTree = BUILT_PRODUCTS_DIR; }; BD6E1BA27D6ABE0AC9D70586 /* Pods-NewExpensify-NewExpensifyTests.release development.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NewExpensify-NewExpensifyTests.release development.xcconfig"; path = "Target Support Files/Pods-NewExpensify-NewExpensifyTests/Pods-NewExpensify-NewExpensifyTests.release development.xcconfig"; sourceTree = ""; }; + BD8828A882E2D6B51362AAC3 /* Pods-NewExpensify.releaseadhoc.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NewExpensify.releaseadhoc.xcconfig"; path = "Target Support Files/Pods-NewExpensify/Pods-NewExpensify.releaseadhoc.xcconfig"; sourceTree = ""; }; BF6A4C5167244B9FB8E4D4E3 /* ExpensifyNeue-Italic.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "ExpensifyNeue-Italic.otf"; path = "../assets/fonts/native/ExpensifyNeue-Italic.otf"; sourceTree = ""; }; + CE2F84BEE9A6DCC228AF7E42 /* Pods-NewExpensify.debugproduction.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NewExpensify.debugproduction.xcconfig"; path = "Target Support Files/Pods-NewExpensify/Pods-NewExpensify.debugproduction.xcconfig"; sourceTree = ""; }; CECC4CBB97A55705A33BEA9E /* Pods-NewExpensify.debug development.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NewExpensify.debug development.xcconfig"; path = "Target Support Files/Pods-NewExpensify/Pods-NewExpensify.debug development.xcconfig"; sourceTree = ""; }; D2AFB39EC1D44BF9B91D3227 /* ExpensifyNewKansas-MediumItalic.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "ExpensifyNewKansas-MediumItalic.otf"; path = "../assets/fonts/native/ExpensifyNewKansas-MediumItalic.otf"; sourceTree = ""; }; DB76E0D5C670190A0997C71E /* Pods-NewExpensify-NewExpensifyTests.debug production.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NewExpensify-NewExpensifyTests.debug production.xcconfig"; path = "Target Support Files/Pods-NewExpensify-NewExpensifyTests/Pods-NewExpensify-NewExpensifyTests.debug production.xcconfig"; sourceTree = ""; }; DCF33E34FFEC48128CDD41D4 /* ExpensifyMono-Bold.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "ExpensifyMono-Bold.otf"; path = "../assets/fonts/native/ExpensifyMono-Bold.otf"; sourceTree = ""; }; DD7904292792E76D004484B4 /* RCTBootSplash.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RCTBootSplash.h; path = NewExpensify/RCTBootSplash.h; sourceTree = ""; }; DD79042A2792E76D004484B4 /* RCTBootSplash.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RCTBootSplash.m; path = NewExpensify/RCTBootSplash.m; sourceTree = ""; }; + E2C8555C607612465A7473F8 /* Pods-NewExpensify-NewExpensifyTests.releaseadhoc.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NewExpensify-NewExpensifyTests.releaseadhoc.xcconfig"; path = "Target Support Files/Pods-NewExpensify-NewExpensifyTests/Pods-NewExpensify-NewExpensifyTests.releaseadhoc.xcconfig"; sourceTree = ""; }; E2F1036F70CBFE39E9352674 /* Pods-NewExpensify-NewExpensifyTests.debug development.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NewExpensify-NewExpensifyTests.debug development.xcconfig"; path = "Target Support Files/Pods-NewExpensify-NewExpensifyTests/Pods-NewExpensify-NewExpensifyTests.debug development.xcconfig"; sourceTree = ""; }; E704648954784DDFBAADF568 /* ExpensifyMono-Regular.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "ExpensifyMono-Regular.otf"; path = "../assets/fonts/native/ExpensifyMono-Regular.otf"; sourceTree = ""; }; E9DF872C2525201700607FDC /* AirshipConfig.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = AirshipConfig.plist; sourceTree = ""; }; ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; }; ED2971642150620600B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS12.0.sdk/System/Library/Frameworks/JavaScriptCore.framework; sourceTree = DEVELOPER_DIR; }; F0C450E92705020500FD2970 /* colors.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; name = colors.json; path = ../colors.json; sourceTree = ""; }; + F15A36A3262EEC3B0CAB8EDF /* Pods-NewExpensify-NewExpensifyTests.debugproduction.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NewExpensify-NewExpensifyTests.debugproduction.xcconfig"; path = "Target Support Files/Pods-NewExpensify-NewExpensifyTests/Pods-NewExpensify-NewExpensifyTests.debugproduction.xcconfig"; sourceTree = ""; }; F4F8A052A22040339996324B /* ExpensifyNeue-Regular.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "ExpensifyNeue-Regular.otf"; path = "../assets/fonts/native/ExpensifyNeue-Regular.otf"; sourceTree = ""; }; /* End PBXFileReference section */ @@ -239,6 +251,18 @@ 6B5211DB0EEB46E12DF4AD2D /* Pods-NewExpensify-NewExpensifyTests.release adhoc.xcconfig */, 6BE16DA6EFF88513DB1CD47B /* Pods-NewExpensify-NewExpensifyTests.release staging.xcconfig */, 96552D489D9F09B6A5ABD81B /* Pods-NewExpensify-NewExpensifyTests.release production.xcconfig */, + 0B627F2A465153FFA6E3A4E0 /* Pods-NewExpensify.debugdevelopment.xcconfig */, + 6F6A514B4DF07A60EC8355BA /* Pods-NewExpensify.debugadhoc.xcconfig */, + CE2F84BEE9A6DCC228AF7E42 /* Pods-NewExpensify.debugproduction.xcconfig */, + 30FFBD291B71222A393D9CC9 /* Pods-NewExpensify.releasedevelopment.xcconfig */, + BD8828A882E2D6B51362AAC3 /* Pods-NewExpensify.releaseadhoc.xcconfig */, + 47D5DF3C6779D41BE70CD031 /* Pods-NewExpensify.releaseproduction.xcconfig */, + 8709DF3C8D91F0FC1581CDD7 /* Pods-NewExpensify-NewExpensifyTests.debugdevelopment.xcconfig */, + 25A4587E168FD67CF890B448 /* Pods-NewExpensify-NewExpensifyTests.debugadhoc.xcconfig */, + F15A36A3262EEC3B0CAB8EDF /* Pods-NewExpensify-NewExpensifyTests.debugproduction.xcconfig */, + 4E8BF7B08BA3181991BFCF4B /* Pods-NewExpensify-NewExpensifyTests.releasedevelopment.xcconfig */, + E2C8555C607612465A7473F8 /* Pods-NewExpensify-NewExpensifyTests.releaseadhoc.xcconfig */, + 57DBBEDB9692E096D4BA0141 /* Pods-NewExpensify-NewExpensifyTests.releaseproduction.xcconfig */, ); path = Pods; sourceTree = ""; @@ -641,9 +665,9 @@ /* End PBXTargetDependency section */ /* Begin XCBuildConfiguration section */ - 00E356F61AD99517003FC87E /* Debug Development */ = { + 00E356F61AD99517003FC87E /* DebugDevelopment */ = { isa = XCBuildConfiguration; - baseConfigurationReference = E2F1036F70CBFE39E9352674 /* Pods-NewExpensify-NewExpensifyTests.debug development.xcconfig */; + baseConfigurationReference = 8709DF3C8D91F0FC1581CDD7 /* Pods-NewExpensify-NewExpensifyTests.debugdevelopment.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; BUNDLE_LOADER = "$(TEST_HOST)"; @@ -664,11 +688,11 @@ PRODUCT_NAME = "$(TARGET_NAME)"; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/NewExpensify.app/NewExpensify"; }; - name = "Debug Development"; + name = DebugDevelopment; }; - 00E356F71AD99517003FC87E /* Release Development */ = { + 00E356F71AD99517003FC87E /* ReleaseDevelopment */ = { isa = XCBuildConfiguration; - baseConfigurationReference = BD6E1BA27D6ABE0AC9D70586 /* Pods-NewExpensify-NewExpensifyTests.release development.xcconfig */; + baseConfigurationReference = 4E8BF7B08BA3181991BFCF4B /* Pods-NewExpensify-NewExpensifyTests.releasedevelopment.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; BUNDLE_LOADER = "$(TEST_HOST)"; @@ -687,11 +711,11 @@ PRODUCT_NAME = "$(TARGET_NAME)"; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/NewExpensify.app/NewExpensify"; }; - name = "Release Development"; + name = ReleaseDevelopment; }; - 13B07F941A680F5B00A75B9A /* Debug Development */ = { + 13B07F941A680F5B00A75B9A /* DebugDevelopment */ = { isa = XCBuildConfiguration; - baseConfigurationReference = CECC4CBB97A55705A33BEA9E /* Pods-NewExpensify.debug development.xcconfig */; + baseConfigurationReference = 0B627F2A465153FFA6E3A4E0 /* Pods-NewExpensify.debugdevelopment.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIconDev; ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO; @@ -719,11 +743,11 @@ TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; }; - name = "Debug Development"; + name = DebugDevelopment; }; - 13B07F951A680F5B00A75B9A /* Release Development */ = { + 13B07F951A680F5B00A75B9A /* ReleaseDevelopment */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 02BE6CF80ED1BD2445267F92 /* Pods-NewExpensify.release development.xcconfig */; + baseConfigurationReference = 30FFBD291B71222A393D9CC9 /* Pods-NewExpensify.releasedevelopment.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIconDev; ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO; @@ -749,9 +773,9 @@ TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; }; - name = "Release Development"; + name = ReleaseDevelopment; }; - 83CBBA201A601CBA00E9B192 /* Debug Development */ = { + 83CBBA201A601CBA00E9B192 /* DebugDevelopment */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; @@ -814,9 +838,9 @@ REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native"; SDKROOT = iphoneos; }; - name = "Debug Development"; + name = DebugDevelopment; }; - 83CBBA211A601CBA00E9B192 /* Release Development */ = { + 83CBBA211A601CBA00E9B192 /* ReleaseDevelopment */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; @@ -873,9 +897,9 @@ SDKROOT = iphoneos; VALIDATE_PRODUCT = YES; }; - name = "Release Development"; + name = ReleaseDevelopment; }; - CF9AF93E29EE9276001FA527 /* Debug Production */ = { + CF9AF93E29EE9276001FA527 /* DebugProduction */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; @@ -938,11 +962,11 @@ REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native"; SDKROOT = iphoneos; }; - name = "Debug Production"; + name = DebugProduction; }; - CF9AF93F29EE9276001FA527 /* Debug Production */ = { + CF9AF93F29EE9276001FA527 /* DebugProduction */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 0E27AA27706D894246E7946D /* Pods-NewExpensify.debug production.xcconfig */; + baseConfigurationReference = CE2F84BEE9A6DCC228AF7E42 /* Pods-NewExpensify.debugproduction.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO; @@ -970,11 +994,11 @@ TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; }; - name = "Debug Production"; + name = DebugProduction; }; - CF9AF94029EE9276001FA527 /* Debug Production */ = { + CF9AF94029EE9276001FA527 /* DebugProduction */ = { isa = XCBuildConfiguration; - baseConfigurationReference = DB76E0D5C670190A0997C71E /* Pods-NewExpensify-NewExpensifyTests.debug production.xcconfig */; + baseConfigurationReference = F15A36A3262EEC3B0CAB8EDF /* Pods-NewExpensify-NewExpensifyTests.debugproduction.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; BUNDLE_LOADER = "$(TEST_HOST)"; @@ -995,9 +1019,9 @@ PRODUCT_NAME = "$(TARGET_NAME)"; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/NewExpensify.app/NewExpensify"; }; - name = "Debug Production"; + name = DebugProduction; }; - CF9AF94429EE927A001FA527 /* Debug AdHoc */ = { + CF9AF94429EE927A001FA527 /* DebugAdHoc */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; @@ -1060,11 +1084,11 @@ REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native"; SDKROOT = iphoneos; }; - name = "Debug AdHoc"; + name = DebugAdHoc; }; - CF9AF94529EE927A001FA527 /* Debug AdHoc */ = { + CF9AF94529EE927A001FA527 /* DebugAdHoc */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 0B09CE5BDAF34DD3573AB4E2 /* Pods-NewExpensify.debug adhoc.xcconfig */; + baseConfigurationReference = 6F6A514B4DF07A60EC8355BA /* Pods-NewExpensify.debugadhoc.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIconAdHoc; ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO; @@ -1092,11 +1116,11 @@ TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; }; - name = "Debug AdHoc"; + name = DebugAdHoc; }; - CF9AF94629EE927A001FA527 /* Debug AdHoc */ = { + CF9AF94629EE927A001FA527 /* DebugAdHoc */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 432FF5842B766535509FC547 /* Pods-NewExpensify-NewExpensifyTests.debug adhoc.xcconfig */; + baseConfigurationReference = 25A4587E168FD67CF890B448 /* Pods-NewExpensify-NewExpensifyTests.debugadhoc.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; BUNDLE_LOADER = "$(TEST_HOST)"; @@ -1117,9 +1141,9 @@ PRODUCT_NAME = "$(TARGET_NAME)"; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/NewExpensify.app/NewExpensify"; }; - name = "Debug AdHoc"; + name = DebugAdHoc; }; - CF9AF94729EE928E001FA527 /* Release Production */ = { + CF9AF94729EE928E001FA527 /* ReleaseProduction */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; @@ -1176,11 +1200,11 @@ SDKROOT = iphoneos; VALIDATE_PRODUCT = YES; }; - name = "Release Production"; + name = ReleaseProduction; }; - CF9AF94829EE928E001FA527 /* Release Production */ = { + CF9AF94829EE928E001FA527 /* ReleaseProduction */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 34A8FDD1F9AA58B8F15C8380 /* Pods-NewExpensify.release production.xcconfig */; + baseConfigurationReference = 47D5DF3C6779D41BE70CD031 /* Pods-NewExpensify.releaseproduction.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO; @@ -1206,11 +1230,11 @@ TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; }; - name = "Release Production"; + name = ReleaseProduction; }; - CF9AF94929EE928E001FA527 /* Release Production */ = { + CF9AF94929EE928E001FA527 /* ReleaseProduction */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 96552D489D9F09B6A5ABD81B /* Pods-NewExpensify-NewExpensifyTests.release production.xcconfig */; + baseConfigurationReference = 57DBBEDB9692E096D4BA0141 /* Pods-NewExpensify-NewExpensifyTests.releaseproduction.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; BUNDLE_LOADER = "$(TEST_HOST)"; @@ -1229,9 +1253,9 @@ PRODUCT_NAME = "$(TARGET_NAME)"; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/NewExpensify.app/NewExpensify"; }; - name = "Release Production"; + name = ReleaseProduction; }; - CF9AF94D29EE9293001FA527 /* Release AdHoc */ = { + CF9AF94D29EE9293001FA527 /* ReleaseAdHoc */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; @@ -1288,11 +1312,11 @@ SDKROOT = iphoneos; VALIDATE_PRODUCT = YES; }; - name = "Release AdHoc"; + name = ReleaseAdHoc; }; - CF9AF94E29EE9293001FA527 /* Release AdHoc */ = { + CF9AF94E29EE9293001FA527 /* ReleaseAdHoc */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 1DDE5449979A136852B939B5 /* Pods-NewExpensify.release adhoc.xcconfig */; + baseConfigurationReference = BD8828A882E2D6B51362AAC3 /* Pods-NewExpensify.releaseadhoc.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIconAdHoc; ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO; @@ -1318,11 +1342,11 @@ TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; }; - name = "Release AdHoc"; + name = ReleaseAdHoc; }; - CF9AF94F29EE9293001FA527 /* Release AdHoc */ = { + CF9AF94F29EE9293001FA527 /* ReleaseAdHoc */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 6B5211DB0EEB46E12DF4AD2D /* Pods-NewExpensify-NewExpensifyTests.release adhoc.xcconfig */; + baseConfigurationReference = E2C8555C607612465A7473F8 /* Pods-NewExpensify-NewExpensifyTests.releaseadhoc.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; BUNDLE_LOADER = "$(TEST_HOST)"; @@ -1341,7 +1365,7 @@ PRODUCT_NAME = "$(TARGET_NAME)"; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/NewExpensify.app/NewExpensify"; }; - name = "Release AdHoc"; + name = ReleaseAdHoc; }; /* End XCBuildConfiguration section */ @@ -1349,41 +1373,41 @@ 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "NewExpensifyTests" */ = { isa = XCConfigurationList; buildConfigurations = ( - 00E356F61AD99517003FC87E /* Debug Development */, - CF9AF94629EE927A001FA527 /* Debug AdHoc */, - CF9AF94029EE9276001FA527 /* Debug Production */, - 00E356F71AD99517003FC87E /* Release Development */, - CF9AF94F29EE9293001FA527 /* Release AdHoc */, - CF9AF94929EE928E001FA527 /* Release Production */, + 00E356F61AD99517003FC87E /* DebugDevelopment */, + CF9AF94629EE927A001FA527 /* DebugAdHoc */, + CF9AF94029EE9276001FA527 /* DebugProduction */, + 00E356F71AD99517003FC87E /* ReleaseDevelopment */, + CF9AF94F29EE9293001FA527 /* ReleaseAdHoc */, + CF9AF94929EE928E001FA527 /* ReleaseProduction */, ); defaultConfigurationIsVisible = 0; - defaultConfigurationName = "Debug Development"; + defaultConfigurationName = DebugDevelopment; }; 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "NewExpensify" */ = { isa = XCConfigurationList; buildConfigurations = ( - 13B07F941A680F5B00A75B9A /* Debug Development */, - CF9AF94529EE927A001FA527 /* Debug AdHoc */, - CF9AF93F29EE9276001FA527 /* Debug Production */, - 13B07F951A680F5B00A75B9A /* Release Development */, - CF9AF94E29EE9293001FA527 /* Release AdHoc */, - CF9AF94829EE928E001FA527 /* Release Production */, + 13B07F941A680F5B00A75B9A /* DebugDevelopment */, + CF9AF94529EE927A001FA527 /* DebugAdHoc */, + CF9AF93F29EE9276001FA527 /* DebugProduction */, + 13B07F951A680F5B00A75B9A /* ReleaseDevelopment */, + CF9AF94E29EE9293001FA527 /* ReleaseAdHoc */, + CF9AF94829EE928E001FA527 /* ReleaseProduction */, ); defaultConfigurationIsVisible = 0; - defaultConfigurationName = "Debug Development"; + defaultConfigurationName = DebugDevelopment; }; 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "NewExpensify" */ = { isa = XCConfigurationList; buildConfigurations = ( - 83CBBA201A601CBA00E9B192 /* Debug Development */, - CF9AF94429EE927A001FA527 /* Debug AdHoc */, - CF9AF93E29EE9276001FA527 /* Debug Production */, - 83CBBA211A601CBA00E9B192 /* Release Development */, - CF9AF94D29EE9293001FA527 /* Release AdHoc */, - CF9AF94729EE928E001FA527 /* Release Production */, + 83CBBA201A601CBA00E9B192 /* DebugDevelopment */, + CF9AF94429EE927A001FA527 /* DebugAdHoc */, + CF9AF93E29EE9276001FA527 /* DebugProduction */, + 83CBBA211A601CBA00E9B192 /* ReleaseDevelopment */, + CF9AF94D29EE9293001FA527 /* ReleaseAdHoc */, + CF9AF94729EE928E001FA527 /* ReleaseProduction */, ); defaultConfigurationIsVisible = 0; - defaultConfigurationName = "Debug Development"; + defaultConfigurationName = DebugDevelopment; }; /* End XCConfigurationList section */ }; diff --git a/ios/NewExpensify.xcodeproj/xcshareddata/xcschemes/New Expensify AdHoc.xcscheme b/ios/NewExpensify.xcodeproj/xcshareddata/xcschemes/New Expensify AdHoc.xcscheme index 0e0fad6399a0..6cd590456eed 100644 --- a/ios/NewExpensify.xcodeproj/xcshareddata/xcschemes/New Expensify AdHoc.xcscheme +++ b/ios/NewExpensify.xcodeproj/xcshareddata/xcschemes/New Expensify AdHoc.xcscheme @@ -57,7 +57,7 @@ @@ -75,7 +75,7 @@ + buildConfiguration = "DebugAdHoc"> diff --git a/ios/NewExpensify.xcodeproj/xcshareddata/xcschemes/New Expensify Dev.xcscheme b/ios/NewExpensify.xcodeproj/xcshareddata/xcschemes/New Expensify Dev.xcscheme index 77f512242f67..93d775217f11 100644 --- a/ios/NewExpensify.xcodeproj/xcshareddata/xcschemes/New Expensify Dev.xcscheme +++ b/ios/NewExpensify.xcodeproj/xcshareddata/xcschemes/New Expensify Dev.xcscheme @@ -23,7 +23,7 @@ @@ -41,7 +41,7 @@ + buildConfiguration = "DebugDevelopment"> diff --git a/ios/NewExpensify.xcodeproj/xcshareddata/xcschemes/New Expensify.xcscheme b/ios/NewExpensify.xcodeproj/xcshareddata/xcschemes/New Expensify.xcscheme index f68be2705527..b6b5874506a8 100644 --- a/ios/NewExpensify.xcodeproj/xcshareddata/xcschemes/New Expensify.xcscheme +++ b/ios/NewExpensify.xcodeproj/xcshareddata/xcschemes/New Expensify.xcscheme @@ -75,7 +75,7 @@ + buildConfiguration = "DebugProduction"> diff --git a/ios/NewExpensify/Info.plist b/ios/NewExpensify/Info.plist index 97875d4a2945..22a72c5d9b0d 100644 --- a/ios/NewExpensify/Info.plist +++ b/ios/NewExpensify/Info.plist @@ -19,7 +19,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 1.3.68 + 1.3.70 CFBundleSignature ???? CFBundleURLTypes @@ -40,7 +40,7 @@ CFBundleVersion - 1.3.68.12 + 1.3.70.3 ITSAppUsesNonExemptEncryption LSApplicationQueriesSchemes diff --git a/ios/NewExpensifyTests/Info.plist b/ios/NewExpensifyTests/Info.plist index 83065d9e9d78..8e76ad5b6c60 100644 --- a/ios/NewExpensifyTests/Info.plist +++ b/ios/NewExpensifyTests/Info.plist @@ -15,10 +15,10 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 1.3.68 + 1.3.70 CFBundleSignature ???? CFBundleVersion - 1.3.68.12 + 1.3.70.3 diff --git a/ios/Podfile b/ios/Podfile index 6445685db014..b30510572448 100644 --- a/ios/Podfile +++ b/ios/Podfile @@ -22,7 +22,7 @@ prepare_react_native_project! # dependencies: { # ...(process.env.NO_FLIPPER ? { 'react-native-flipper': { platforms: { ios: null } } } : {}), # ``` -flipper_config = ENV['NO_FLIPPER'] == "1" ? FlipperConfiguration.disabled : FlipperConfiguration.enabled(['Debug Production', 'Debug Development', 'Debug AdHoc']) +flipper_config = ENV['NO_FLIPPER'] == "1" ? FlipperConfiguration.disabled : FlipperConfiguration.enabled(['DebugProduction', 'DebugDevelopment', 'DebugAdHoc']) linkage = ENV['USE_FRAMEWORKS'] if linkage != nil @@ -54,12 +54,12 @@ target 'NewExpensify' do permissions_path = '../node_modules/react-native-permissions/ios' project 'NewExpensify', - 'Debug Development' => :debug, - 'Debug AdHoc' => :debug, - 'Debug Production' => :debug, - 'Release Development' => :release, - 'Release AdHoc' => :release, - 'Release Production' => :release + 'DebugDevelopment' => :debug, + 'DebugAdHoc' => :debug, + 'DebugProduction' => :debug, + 'ReleaseDevelopment' => :release, + 'ReleaseAdHoc' => :release, + 'ReleaseProduction' => :release pod 'Permission-LocationAccuracy', :path => "#{permissions_path}/LocationAccuracy" pod 'Permission-LocationAlways', :path => "#{permissions_path}/LocationAlways" diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 2bea672171fe..aeb1887223cd 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -1309,6 +1309,6 @@ SPEC CHECKSUMS: Yoga: 8796b55dba14d7004f980b54bcc9833ee45b28ce YogaKit: f782866e155069a2cca2517aafea43200b01fd5a -PODFILE CHECKSUM: 845537d35601574adcd0794e17003ba7dbccdbfd +PODFILE CHECKSUM: 2daf34c870819a933f3fefe426801d54b2ff2a14 COCOAPODS: 1.12.1 diff --git a/package-lock.json b/package-lock.json index 1ae63b31fd0c..c27370ff864a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,16 +1,17 @@ { "name": "new.expensify", - "version": "1.3.68-12", + "version": "1.3.70-3", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "new.expensify", - "version": "1.3.68-12", + "version": "1.3.70-3", "hasInstallScript": true, "license": "MIT", "dependencies": { "@expensify/react-native-web": "0.18.15", + "@formatjs/intl-datetimeformat": "^6.10.0", "@formatjs/intl-getcanonicallocales": "^2.2.0", "@formatjs/intl-listformat": "^7.2.2", "@formatjs/intl-locale": "^3.3.0", @@ -18,6 +19,8 @@ "@formatjs/intl-pluralrules": "^5.2.2", "@gorhom/portal": "^1.0.14", "@invertase/react-native-apple-authentication": "^2.2.2", + "@kie/act-js": "^2.0.1", + "@kie/mock-github": "^1.0.0", "@oguzhnatly/react-native-image-manipulator": "github:Expensify/react-native-image-manipulator#5cdae3d4455b03a04c57f50be3863e2fe6c92c52", "@onfido/react-native-sdk": "7.4.0", "@react-native-async-storage/async-storage": "^1.17.10", @@ -36,6 +39,7 @@ "@react-navigation/stack": "6.3.16", "@react-ng/bounds-observer": "^0.2.1", "@rnmapbox/maps": "^10.0.11", + "@types/node": "^18.14.0", "@ua/react-native-airship": "^15.2.6", "awesome-phonenumber": "^5.4.0", "babel-plugin-transform-remove-console": "^6.9.4", @@ -48,6 +52,7 @@ "domhandler": "^4.3.0", "expensify-common": "git+ssh://git@github.com/Expensify/expensify-common.git#35bff866a8d345b460ea6256f0a0f0a8a7f81086", "fbjs": "^3.0.2", + "focus-trap-react": "^10.2.1", "htmlparser2": "^7.2.0", "idb-keyval": "^6.2.1", "jest-when": "^3.5.2", @@ -60,7 +65,7 @@ "patch-package": "^8.0.0", "process": "^0.11.10", "prop-types": "^15.7.2", - "pusher-js": "7.4.0", + "pusher-js": "8.3.0", "react": "18.2.0", "react-collapse": "^5.1.0", "react-content-loader": "^6.1.0", @@ -85,7 +90,7 @@ "react-native-linear-gradient": "^2.8.1", "react-native-localize": "^2.2.6", "react-native-modal": "^13.0.0", - "react-native-onyx": "1.0.72", + "react-native-onyx": "1.0.76", "react-native-pager-view": "^6.2.0", "react-native-pdf": "^6.7.1", "react-native-performance": "^4.0.0", @@ -128,6 +133,8 @@ "@babel/runtime": "^7.20.0", "@electron/notarize": "^1.2.3", "@jest/globals": "^29.5.0", + "@kie/act-js": "^2.0.1", + "@kie/mock-github": "^1.0.0", "@octokit/core": "4.0.4", "@octokit/plugin-paginate-rest": "3.1.0", "@octokit/plugin-throttling": "4.1.0", @@ -179,7 +186,7 @@ "css-loader": "^6.7.2", "diff-so-fancy": "^1.3.0", "dotenv": "^16.0.3", - "electron": "^25.8.0", + "electron": "^25.8.1", "electron-builder": "24.6.4", "eslint": "^7.6.0", "eslint-config-airbnb-typescript": "^17.1.0", @@ -221,7 +228,8 @@ "webpack-cli": "^4.10.0", "webpack-dev-server": "^4.9.3", "webpack-font-preload-plugin": "^1.5.0", - "webpack-merge": "^5.8.0" + "webpack-merge": "^5.8.0", + "yaml": "^2.2.1" }, "engines": { "node": "16.15.1", @@ -3688,6 +3696,33 @@ "tslib": "^2.4.0" } }, + "node_modules/@formatjs/intl-datetimeformat": { + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/@formatjs/intl-datetimeformat/-/intl-datetimeformat-6.10.0.tgz", + "integrity": "sha512-5tJWZxOyP5D4PDrqv27h0LWAPHhQM9BHR0pDBTZOKWFEZNrS2IgREbyalSGwQLtN1tZaDrt3YeNfNLbZk1wSUw==", + "dependencies": { + "@formatjs/ecma402-abstract": "1.17.0", + "@formatjs/intl-localematcher": "0.4.0", + "tslib": "^2.4.0" + } + }, + "node_modules/@formatjs/intl-datetimeformat/node_modules/@formatjs/ecma402-abstract": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-1.17.0.tgz", + "integrity": "sha512-6ueQTeJZtwKjmh23bdkq/DMqH4l4bmfvtQH98blOSbiXv/OUiyijSW6jU22IT8BNM1ujCaEvJfTtyCYVH38EMQ==", + "dependencies": { + "@formatjs/intl-localematcher": "0.4.0", + "tslib": "^2.4.0" + } + }, + "node_modules/@formatjs/intl-datetimeformat/node_modules/@formatjs/intl-localematcher": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.4.0.tgz", + "integrity": "sha512-bRTd+rKomvfdS4QDlVJ6TA/Jx1F2h/TBVO5LjvhQ7QPPHp19oPNMIum7W2CMEReq/zPxpmCeB31F9+5gl/qtvw==", + "dependencies": { + "tslib": "^2.4.0" + } + }, "node_modules/@formatjs/intl-enumerator": { "version": "1.3.0", "license": "MIT", @@ -5193,6 +5228,110 @@ "integrity": "sha512-dfLbk+PwWvFzSxwk3n5ySL0hfBog779o8h68wK/7/APo/7cgyWp5jcXockbxdk5kFRkbeXWm4Fbi9FrdN381sA==", "dev": true }, + "node_modules/@kie/act-js": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@kie/act-js/-/act-js-2.3.0.tgz", + "integrity": "sha512-Q9k0b05uA46jXKWmVfoGDW+0xsCcE7QPiHi8IH7h41P36DujHKBj4k28RCeIEx3IwUCxYHKwubN8DH4Vzc9XcA==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "@kie/mock-github": "^2.0.0", + "adm-zip": "^0.5.10", + "ajv": "^8.12.0", + "bin-links": "^4.0.1", + "express": "^4.18.1", + "follow-redirects": "^1.15.2", + "tar": "^6.1.13", + "yaml": "^2.1.3" + }, + "bin": { + "act-js": "bin/act" + } + }, + "node_modules/@kie/act-js/node_modules/@kie/mock-github": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@kie/mock-github/-/mock-github-2.0.0.tgz", + "integrity": "sha512-od6UyICJYKMnz9HgEWCQAFT/JsCpKkLp+JQH8fV23tf+ZmmQI1dK3C20k6aO5uJhAHA0yOcFtbKFVF4+8i3DTg==", + "dev": true, + "dependencies": { + "@octokit/openapi-types-ghec": "^18.0.0", + "ajv": "^8.11.0", + "express": "^4.18.1", + "fast-glob": "^3.2.12", + "fs-extra": "^10.1.0", + "nock": "^13.2.7", + "simple-git": "^3.8.0", + "totalist": "^3.0.0" + } + }, + "node_modules/@kie/act-js/node_modules/@octokit/openapi-types-ghec": { + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types-ghec/-/openapi-types-ghec-18.0.0.tgz", + "integrity": "sha512-xY5FTR/DW2gUJdC5GyzkqrfMHhr3u3hg+dUG6bA5FvuuODw6A7+0JTTSS1ndLQEKGmFxP7chf1BKkhvhnqxCew==", + "dev": true + }, + "node_modules/@kie/act-js/node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@kie/act-js/node_modules/totalist": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", + "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/@kie/mock-github": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@kie/mock-github/-/mock-github-1.1.0.tgz", + "integrity": "sha512-fD+utlOiyZSOutOcXL0G9jfjbtvOO44PLUyTfgfkrm1+575R/dbvU6AcJfjc1DtHeRv7FC7f4ebyU+a1wgL6CA==", + "dev": true, + "dependencies": { + "@octokit/openapi-types-ghec": "^14.0.0", + "ajv": "^8.11.0", + "express": "^4.18.1", + "fast-glob": "^3.2.12", + "fs-extra": "^10.1.0", + "nock": "^13.2.7", + "simple-git": "^3.8.0", + "totalist": "^3.0.0" + } + }, + "node_modules/@kie/mock-github/node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@kie/mock-github/node_modules/totalist": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", + "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/@kwsites/file-exists": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@kwsites/file-exists/-/file-exists-1.1.1.tgz", @@ -5699,6 +5838,12 @@ "dev": true, "license": "MIT" }, + "node_modules/@octokit/openapi-types-ghec": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types-ghec/-/openapi-types-ghec-14.0.0.tgz", + "integrity": "sha512-xhd9oEvn2aroGn+sk09Ptx/76Y7aKU0EIgHukHPCU1+rGJreO36baEEk6k8ZPblieHNM39FcykJQmtDrETm0KA==", + "dev": true + }, "node_modules/@octokit/plugin-paginate-rest": { "version": "3.1.0", "dev": true, @@ -6929,14 +7074,6 @@ "node": ">=8" } }, - "node_modules/@react-native-community/cli-doctor/node_modules/yaml": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.1.tgz", - "integrity": "sha512-2eHWfjaoXgTBC2jNM1LRef62VQa0umtvRiDSk6HSzW7RvS5YtkabJrwYLLEKWBc8a5U2PTSCs+dJjUTJdlHsWQ==", - "engines": { - "node": ">= 14" - } - }, "node_modules/@react-native-community/cli-hermes": { "version": "11.3.5", "resolved": "https://registry.npmjs.org/@react-native-community/cli-hermes/-/cli-hermes-11.3.5.tgz", @@ -19380,6 +19517,15 @@ "node": ">= 10.0.0" } }, + "node_modules/adm-zip": { + "version": "0.5.10", + "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.10.tgz", + "integrity": "sha512-x0HvcHqVJNTPk/Bw8JbLWlWoo6Wwnsug0fnYYro1HBrjxZ3G7/AZk7Ahv8JwDe1uIcz8eBqvu86FuF1POiG7vQ==", + "dev": true, + "engines": { + "node": ">=6.0" + } + }, "node_modules/agent-base": { "version": "6.0.2", "dev": true, @@ -21217,6 +21363,46 @@ "node": "*" } }, + "node_modules/bin-links": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/bin-links/-/bin-links-4.0.2.tgz", + "integrity": "sha512-jxJ0PbXR8eQyPlExCvCs3JFnikvs1Yp4gUJt6nmgathdOwvur+q22KWC3h20gvWl4T/14DXKj2IlkJwwZkZPOw==", + "dev": true, + "dependencies": { + "cmd-shim": "^6.0.0", + "npm-normalize-package-bin": "^3.0.0", + "read-cmd-shim": "^4.0.0", + "write-file-atomic": "^5.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/bin-links/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/bin-links/node_modules/write-file-atomic": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz", + "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, "node_modules/binary-extensions": { "version": "2.2.0", "devOptional": true, @@ -22650,6 +22836,15 @@ "node": ">=6" } }, + "node_modules/cmd-shim": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/cmd-shim/-/cmd-shim-6.0.1.tgz", + "integrity": "sha512-S9iI9y0nKR4hwEQsVWpyxld/6kRfGepGfzff83FcaiEBpmvlbA2nnGe7Cylgrx2f/p1P5S5wpRm9oL8z1PbS3Q==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, "node_modules/co": { "version": "4.6.0", "license": "MIT", @@ -23304,6 +23499,15 @@ "node": ">=10" } }, + "node_modules/cosmiconfig/node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, "node_modules/cp-file": { "version": "7.0.0", "dev": true, @@ -24840,9 +25044,9 @@ } }, "node_modules/electron": { - "version": "25.8.0", - "resolved": "https://registry.npmjs.org/electron/-/electron-25.8.0.tgz", - "integrity": "sha512-T3kC1a/3ntSaYMCVVfUUc9v7myPzi6J2GP0Ad/CyfWKDPp054dGyKxb2EEjKnxQQ7wfjsT1JTEdBG04x6ekVBw==", + "version": "25.8.1", + "resolved": "https://registry.npmjs.org/electron/-/electron-25.8.1.tgz", + "integrity": "sha512-GtcP1nMrROZfFg0+mhyj1hamrHvukfF6of2B/pcWxmWkd5FVY1NJib0tlhiorFZRzQN5Z+APLPr7aMolt7i2AQ==", "dev": true, "hasInstallScript": true, "dependencies": { @@ -28091,8 +28295,32 @@ "readable-stream": "^2.3.6" } }, + "node_modules/focus-trap": { + "version": "7.5.2", + "resolved": "https://registry.npmjs.org/focus-trap/-/focus-trap-7.5.2.tgz", + "integrity": "sha512-p6vGNNWLDGwJCiEjkSK6oERj/hEyI9ITsSwIUICBoKLlWiTWXJRfQibCwcoi50rTZdbi87qDtUlMCmQwsGSgPw==", + "dependencies": { + "tabbable": "^6.2.0" + } + }, + "node_modules/focus-trap-react": { + "version": "10.2.1", + "resolved": "https://registry.npmjs.org/focus-trap-react/-/focus-trap-react-10.2.1.tgz", + "integrity": "sha512-UrAKOn52lvfHF6lkUMfFhlQxFgahyNW5i6FpHWkDxAeD4FSk3iwx9n4UEA4Sims0G5WiGIi0fAyoq3/UVeNCYA==", + "dependencies": { + "focus-trap": "^7.5.2", + "tabbable": "^6.2.0" + }, + "peerDependencies": { + "prop-types": "^15.8.1", + "react": ">=16.3.0", + "react-dom": ">=16.3.0" + } + }, "node_modules/follow-redirects": { - "version": "1.15.1", + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", "dev": true, "funding": [ { @@ -28100,7 +28328,6 @@ "url": "https://github.com/sponsors/RubenVerborgh" } ], - "license": "MIT", "engines": { "node": ">=4.0" }, @@ -28299,6 +28526,15 @@ "node": ">=8" } }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, "node_modules/form-data": { "version": "3.0.1", "dev": true, @@ -37534,6 +37770,21 @@ "node": ">=12.0.0" } }, + "node_modules/nock": { + "version": "13.3.3", + "resolved": "https://registry.npmjs.org/nock/-/nock-13.3.3.tgz", + "integrity": "sha512-z+KUlILy9SK/RjpeXDiDUEAq4T94ADPHE3qaRkf66mpEhzc/ytOMm3Bwdrbq6k1tMWkbdujiKim3G2tfQARuJw==", + "dev": true, + "dependencies": { + "debug": "^4.1.0", + "json-stringify-safe": "^5.0.1", + "lodash": "^4.17.21", + "propagate": "^2.0.0" + }, + "engines": { + "node": ">= 10.13" + } + }, "node_modules/node-abort-controller": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/node-abort-controller/-/node-abort-controller-3.1.1.tgz", @@ -37717,6 +37968,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/npm-normalize-package-bin": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-3.0.1.tgz", + "integrity": "sha512-dMxCf+zZ+3zeQZXKxmyuCKlIDPGuv8EF940xbkC4kQVDTtqoh6rJFO+JTKSA6/Rwi0getWmtuy4Itup0AMcaDQ==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, "node_modules/npm-run-path": { "version": "4.0.1", "license": "MIT", @@ -38687,14 +38947,6 @@ "node": ">=0.6.0" } }, - "node_modules/patch-package/node_modules/yaml": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.1.tgz", - "integrity": "sha512-2eHWfjaoXgTBC2jNM1LRef62VQa0umtvRiDSk6HSzW7RvS5YtkabJrwYLLEKWBc8a5U2PTSCs+dJjUTJdlHsWQ==", - "engines": { - "node": ">= 14" - } - }, "node_modules/path-browserify": { "version": "0.0.1", "license": "MIT" @@ -39393,6 +39645,15 @@ "react-is": "^16.13.1" } }, + "node_modules/propagate": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/propagate/-/propagate-2.0.1.tgz", + "integrity": "sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, "node_modules/property-information": { "version": "5.6.0", "dev": true, @@ -39484,10 +39745,10 @@ } }, "node_modules/pusher-js": { - "version": "7.4.0", - "license": "MIT", + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/pusher-js/-/pusher-js-8.3.0.tgz", + "integrity": "sha512-6GohP06WlVeomAQQe9qWh1IDzd3+InluWt+ZUOcecVK1SEQkg6a8uYVsvxSJm7cbccfmHhE0jDkmhKIhue8vmA==", "dependencies": { - "@types/node": "^14.14.31", "tweetnacl": "^1.0.3" } }, @@ -39499,11 +39760,6 @@ "node": ">=4.2.4" } }, - "node_modules/pusher-js/node_modules/@types/node": { - "version": "14.18.56", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.56.tgz", - "integrity": "sha512-+k+57NVS9opgrEn5l9c0gvD1r6C+PtyhVE4BTnMMRwiEA8ZO8uFcs6Yy2sXIy0eC95ZurBtRSvhZiHXBysbl6w==" - }, "node_modules/qrcode": { "version": "1.5.3", "license": "MIT", @@ -40311,9 +40567,9 @@ } }, "node_modules/react-native-onyx": { - "version": "1.0.72", - "resolved": "https://registry.npmjs.org/react-native-onyx/-/react-native-onyx-1.0.72.tgz", - "integrity": "sha512-roJuA92qZH2PLYSqBhSPCse+Ra2EJu4FBpVqguwJRp6oaLNHR1CtPTgU1xMh/kj2nWmdpcqKoOc3nS35asb80g==", + "version": "1.0.76", + "resolved": "https://registry.npmjs.org/react-native-onyx/-/react-native-onyx-1.0.76.tgz", + "integrity": "sha512-mcMlYQCo1B/kom+4hu7CQKKLwvPFjQAJsVIzV2s9aa8XKNlcnYiJbfuM6RSJ1fFmSIeud4Y66rhv4/oWUkSl5A==", "dependencies": { "ascii-table": "0.0.9", "fast-equals": "^4.0.3", @@ -41403,6 +41659,15 @@ "react-dom": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0" } }, + "node_modules/read-cmd-shim": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/read-cmd-shim/-/read-cmd-shim-4.0.0.tgz", + "integrity": "sha512-yILWifhaSEEytfXI76kB9xEEiG1AiozaCJZ83A87ytjRiN+jVibXjedjCRNjoZviinhG+4UkalO3mWTd8u5O0Q==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, "node_modules/read-config-file": { "version": "6.3.2", "resolved": "https://registry.npmjs.org/read-config-file/-/read-config-file-6.3.2.tgz", @@ -44427,6 +44692,11 @@ "dev": true, "license": "BSD-3-Clause" }, + "node_modules/tabbable": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.2.0.tgz", + "integrity": "sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==" + }, "node_modules/table": { "version": "6.8.1", "resolved": "https://registry.npmjs.org/table/-/table-6.8.1.tgz", @@ -47697,11 +47967,11 @@ "license": "ISC" }, "node_modules/yaml": { - "version": "1.10.2", - "dev": true, - "license": "ISC", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.2.tgz", + "integrity": "sha512-N/lyzTPaJasoDmfV7YTrYCI0G/3ivm/9wdG0aHuheKowWQwGTsK0Eoiw6utmzAnI6pkJa0DUVygvp3spqqEKXg==", "engines": { - "node": ">= 6" + "node": ">= 14" } }, "node_modules/yargs": { @@ -50130,6 +50400,35 @@ "tslib": "^2.4.0" } }, + "@formatjs/intl-datetimeformat": { + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/@formatjs/intl-datetimeformat/-/intl-datetimeformat-6.10.0.tgz", + "integrity": "sha512-5tJWZxOyP5D4PDrqv27h0LWAPHhQM9BHR0pDBTZOKWFEZNrS2IgREbyalSGwQLtN1tZaDrt3YeNfNLbZk1wSUw==", + "requires": { + "@formatjs/ecma402-abstract": "1.17.0", + "@formatjs/intl-localematcher": "0.4.0", + "tslib": "^2.4.0" + }, + "dependencies": { + "@formatjs/ecma402-abstract": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-1.17.0.tgz", + "integrity": "sha512-6ueQTeJZtwKjmh23bdkq/DMqH4l4bmfvtQH98blOSbiXv/OUiyijSW6jU22IT8BNM1ujCaEvJfTtyCYVH38EMQ==", + "requires": { + "@formatjs/intl-localematcher": "0.4.0", + "tslib": "^2.4.0" + } + }, + "@formatjs/intl-localematcher": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.4.0.tgz", + "integrity": "sha512-bRTd+rKomvfdS4QDlVJ6TA/Jx1F2h/TBVO5LjvhQ7QPPHp19oPNMIum7W2CMEReq/zPxpmCeB31F9+5gl/qtvw==", + "requires": { + "tslib": "^2.4.0" + } + } + } + }, "@formatjs/intl-enumerator": { "version": "1.3.0", "requires": { @@ -51206,6 +51505,98 @@ "integrity": "sha512-dfLbk+PwWvFzSxwk3n5ySL0hfBog779o8h68wK/7/APo/7cgyWp5jcXockbxdk5kFRkbeXWm4Fbi9FrdN381sA==", "dev": true }, + "@kie/act-js": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@kie/act-js/-/act-js-2.3.0.tgz", + "integrity": "sha512-Q9k0b05uA46jXKWmVfoGDW+0xsCcE7QPiHi8IH7h41P36DujHKBj4k28RCeIEx3IwUCxYHKwubN8DH4Vzc9XcA==", + "dev": true, + "requires": { + "@kie/mock-github": "^2.0.0", + "adm-zip": "^0.5.10", + "ajv": "^8.12.0", + "bin-links": "^4.0.1", + "express": "^4.18.1", + "follow-redirects": "^1.15.2", + "tar": "^6.1.13", + "yaml": "^2.1.3" + }, + "dependencies": { + "@kie/mock-github": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@kie/mock-github/-/mock-github-2.0.0.tgz", + "integrity": "sha512-od6UyICJYKMnz9HgEWCQAFT/JsCpKkLp+JQH8fV23tf+ZmmQI1dK3C20k6aO5uJhAHA0yOcFtbKFVF4+8i3DTg==", + "dev": true, + "requires": { + "@octokit/openapi-types-ghec": "^18.0.0", + "ajv": "^8.11.0", + "express": "^4.18.1", + "fast-glob": "^3.2.12", + "fs-extra": "^10.1.0", + "nock": "^13.2.7", + "simple-git": "^3.8.0", + "totalist": "^3.0.0" + } + }, + "@octokit/openapi-types-ghec": { + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types-ghec/-/openapi-types-ghec-18.0.0.tgz", + "integrity": "sha512-xY5FTR/DW2gUJdC5GyzkqrfMHhr3u3hg+dUG6bA5FvuuODw6A7+0JTTSS1ndLQEKGmFxP7chf1BKkhvhnqxCew==", + "dev": true + }, + "fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + } + }, + "totalist": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", + "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", + "dev": true + } + } + }, + "@kie/mock-github": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@kie/mock-github/-/mock-github-1.1.0.tgz", + "integrity": "sha512-fD+utlOiyZSOutOcXL0G9jfjbtvOO44PLUyTfgfkrm1+575R/dbvU6AcJfjc1DtHeRv7FC7f4ebyU+a1wgL6CA==", + "dev": true, + "requires": { + "@octokit/openapi-types-ghec": "^14.0.0", + "ajv": "^8.11.0", + "express": "^4.18.1", + "fast-glob": "^3.2.12", + "fs-extra": "^10.1.0", + "nock": "^13.2.7", + "simple-git": "^3.8.0", + "totalist": "^3.0.0" + }, + "dependencies": { + "fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + } + }, + "totalist": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", + "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", + "dev": true + } + } + }, "@kwsites/file-exists": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@kwsites/file-exists/-/file-exists-1.1.1.tgz", @@ -51588,6 +51979,12 @@ "version": "12.11.0", "dev": true }, + "@octokit/openapi-types-ghec": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types-ghec/-/openapi-types-ghec-14.0.0.tgz", + "integrity": "sha512-xhd9oEvn2aroGn+sk09Ptx/76Y7aKU0EIgHukHPCU1+rGJreO36baEEk6k8ZPblieHNM39FcykJQmtDrETm0KA==", + "dev": true + }, "@octokit/plugin-paginate-rest": { "version": "3.1.0", "dev": true, @@ -52501,11 +52898,6 @@ "requires": { "has-flag": "^4.0.0" } - }, - "yaml": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.1.tgz", - "integrity": "sha512-2eHWfjaoXgTBC2jNM1LRef62VQa0umtvRiDSk6HSzW7RvS5YtkabJrwYLLEKWBc8a5U2PTSCs+dJjUTJdlHsWQ==" } } }, @@ -61211,6 +61603,12 @@ "version": "1.2.1", "dev": true }, + "adm-zip": { + "version": "0.5.10", + "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.10.tgz", + "integrity": "sha512-x0HvcHqVJNTPk/Bw8JbLWlWoo6Wwnsug0fnYYro1HBrjxZ3G7/AZk7Ahv8JwDe1uIcz8eBqvu86FuF1POiG7vQ==", + "dev": true + }, "agent-base": { "version": "6.0.2", "dev": true, @@ -62510,6 +62908,36 @@ "version": "5.2.2", "devOptional": true }, + "bin-links": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/bin-links/-/bin-links-4.0.2.tgz", + "integrity": "sha512-jxJ0PbXR8eQyPlExCvCs3JFnikvs1Yp4gUJt6nmgathdOwvur+q22KWC3h20gvWl4T/14DXKj2IlkJwwZkZPOw==", + "dev": true, + "requires": { + "cmd-shim": "^6.0.0", + "npm-normalize-package-bin": "^3.0.0", + "read-cmd-shim": "^4.0.0", + "write-file-atomic": "^5.0.0" + }, + "dependencies": { + "signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true + }, + "write-file-atomic": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz", + "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==", + "dev": true, + "requires": { + "imurmurhash": "^0.1.4", + "signal-exit": "^4.0.1" + } + } + } + }, "binary-extensions": { "version": "2.2.0", "devOptional": true @@ -63485,6 +63913,12 @@ "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz", "integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==" }, + "cmd-shim": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/cmd-shim/-/cmd-shim-6.0.1.tgz", + "integrity": "sha512-S9iI9y0nKR4hwEQsVWpyxld/6kRfGepGfzff83FcaiEBpmvlbA2nnGe7Cylgrx2f/p1P5S5wpRm9oL8z1PbS3Q==", + "dev": true + }, "co": { "version": "4.6.0" }, @@ -63919,6 +64353,14 @@ "parse-json": "^5.0.0", "path-type": "^4.0.0", "yaml": "^1.10.0" + }, + "dependencies": { + "yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "dev": true + } } }, "cp-file": { @@ -64991,9 +65433,9 @@ } }, "electron": { - "version": "25.8.0", - "resolved": "https://registry.npmjs.org/electron/-/electron-25.8.0.tgz", - "integrity": "sha512-T3kC1a/3ntSaYMCVVfUUc9v7myPzi6J2GP0Ad/CyfWKDPp054dGyKxb2EEjKnxQQ7wfjsT1JTEdBG04x6ekVBw==", + "version": "25.8.1", + "resolved": "https://registry.npmjs.org/electron/-/electron-25.8.1.tgz", + "integrity": "sha512-GtcP1nMrROZfFg0+mhyj1hamrHvukfF6of2B/pcWxmWkd5FVY1NJib0tlhiorFZRzQN5Z+APLPr7aMolt7i2AQ==", "dev": true, "requires": { "@electron/get": "^2.0.0", @@ -67266,8 +67708,27 @@ "readable-stream": "^2.3.6" } }, + "focus-trap": { + "version": "7.5.2", + "resolved": "https://registry.npmjs.org/focus-trap/-/focus-trap-7.5.2.tgz", + "integrity": "sha512-p6vGNNWLDGwJCiEjkSK6oERj/hEyI9ITsSwIUICBoKLlWiTWXJRfQibCwcoi50rTZdbi87qDtUlMCmQwsGSgPw==", + "requires": { + "tabbable": "^6.2.0" + } + }, + "focus-trap-react": { + "version": "10.2.1", + "resolved": "https://registry.npmjs.org/focus-trap-react/-/focus-trap-react-10.2.1.tgz", + "integrity": "sha512-UrAKOn52lvfHF6lkUMfFhlQxFgahyNW5i6FpHWkDxAeD4FSk3iwx9n4UEA4Sims0G5WiGIi0fAyoq3/UVeNCYA==", + "requires": { + "focus-trap": "^7.5.2", + "tabbable": "^6.2.0" + } + }, "follow-redirects": { - "version": "1.15.1", + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", "dev": true }, "for-each": { @@ -67383,6 +67844,12 @@ "requires": { "has-flag": "^4.0.0" } + }, + "yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "dev": true } } }, @@ -73699,6 +74166,18 @@ "resolved": "https://registry.npmjs.org/nocache/-/nocache-3.0.4.tgz", "integrity": "sha512-WDD0bdg9mbq6F4mRxEYcPWwfA1vxd0mrvKOyxI7Xj/atfRHVeutzuWByG//jfm4uPzp0y4Kj051EORCBSQMycw==" }, + "nock": { + "version": "13.3.3", + "resolved": "https://registry.npmjs.org/nock/-/nock-13.3.3.tgz", + "integrity": "sha512-z+KUlILy9SK/RjpeXDiDUEAq4T94ADPHE3qaRkf66mpEhzc/ytOMm3Bwdrbq6k1tMWkbdujiKim3G2tfQARuJw==", + "dev": true, + "requires": { + "debug": "^4.1.0", + "json-stringify-safe": "^5.0.1", + "lodash": "^4.17.21", + "propagate": "^2.0.0" + } + }, "node-abort-controller": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/node-abort-controller/-/node-abort-controller-3.1.1.tgz", @@ -73832,6 +74311,12 @@ "version": "6.1.0", "dev": true }, + "npm-normalize-package-bin": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-3.0.1.tgz", + "integrity": "sha512-dMxCf+zZ+3zeQZXKxmyuCKlIDPGuv8EF940xbkC4kQVDTtqoh6rJFO+JTKSA6/Rwi0getWmtuy4Itup0AMcaDQ==", + "dev": true + }, "npm-run-path": { "version": "4.0.1", "requires": { @@ -74463,11 +74948,6 @@ "requires": { "os-tmpdir": "~1.0.2" } - }, - "yaml": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.1.tgz", - "integrity": "sha512-2eHWfjaoXgTBC2jNM1LRef62VQa0umtvRiDSk6HSzW7RvS5YtkabJrwYLLEKWBc8a5U2PTSCs+dJjUTJdlHsWQ==" } } }, @@ -74932,6 +75412,12 @@ "react-is": "^16.13.1" } }, + "propagate": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/propagate/-/propagate-2.0.1.tgz", + "integrity": "sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag==", + "dev": true + }, "property-information": { "version": "5.6.0", "dev": true, @@ -75008,17 +75494,11 @@ "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==" }, "pusher-js": { - "version": "7.4.0", + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/pusher-js/-/pusher-js-8.3.0.tgz", + "integrity": "sha512-6GohP06WlVeomAQQe9qWh1IDzd3+InluWt+ZUOcecVK1SEQkg6a8uYVsvxSJm7cbccfmHhE0jDkmhKIhue8vmA==", "requires": { - "@types/node": "^14.14.31", "tweetnacl": "^1.0.3" - }, - "dependencies": { - "@types/node": { - "version": "14.18.56", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.56.tgz", - "integrity": "sha512-+k+57NVS9opgrEn5l9c0gvD1r6C+PtyhVE4BTnMMRwiEA8ZO8uFcs6Yy2sXIy0eC95ZurBtRSvhZiHXBysbl6w==" - } } }, "pusher-js-mock": { @@ -75636,9 +76116,9 @@ } }, "react-native-onyx": { - "version": "1.0.72", - "resolved": "https://registry.npmjs.org/react-native-onyx/-/react-native-onyx-1.0.72.tgz", - "integrity": "sha512-roJuA92qZH2PLYSqBhSPCse+Ra2EJu4FBpVqguwJRp6oaLNHR1CtPTgU1xMh/kj2nWmdpcqKoOc3nS35asb80g==", + "version": "1.0.76", + "resolved": "https://registry.npmjs.org/react-native-onyx/-/react-native-onyx-1.0.76.tgz", + "integrity": "sha512-mcMlYQCo1B/kom+4hu7CQKKLwvPFjQAJsVIzV2s9aa8XKNlcnYiJbfuM6RSJ1fFmSIeud4Y66rhv4/oWUkSl5A==", "requires": { "ascii-table": "0.0.9", "fast-equals": "^4.0.3", @@ -76222,6 +76702,12 @@ "memoize-one": ">=3.1.1 <6" } }, + "read-cmd-shim": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/read-cmd-shim/-/read-cmd-shim-4.0.0.tgz", + "integrity": "sha512-yILWifhaSEEytfXI76kB9xEEiG1AiozaCJZ83A87ytjRiN+jVibXjedjCRNjoZviinhG+4UkalO3mWTd8u5O0Q==", + "dev": true + }, "read-config-file": { "version": "6.3.2", "resolved": "https://registry.npmjs.org/read-config-file/-/read-config-file-6.3.2.tgz", @@ -78362,6 +78848,11 @@ "version": "2.0.15", "dev": true }, + "tabbable": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.2.0.tgz", + "integrity": "sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==" + }, "table": { "version": "6.8.1", "resolved": "https://registry.npmjs.org/table/-/table-6.8.1.tgz", @@ -80552,8 +81043,9 @@ "version": "4.0.0" }, "yaml": { - "version": "1.10.2", - "dev": true + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.2.tgz", + "integrity": "sha512-N/lyzTPaJasoDmfV7YTrYCI0G/3ivm/9wdG0aHuheKowWQwGTsK0Eoiw6utmzAnI6pkJa0DUVygvp3spqqEKXg==" }, "yargs": { "version": "13.3.2", diff --git a/package.json b/package.json index 340a1c8d0880..e16d36f50632 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "new.expensify", - "version": "1.3.68-12", + "version": "1.3.70-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.", @@ -11,10 +11,10 @@ "postinstall": "scripts/postInstall.sh", "clean": "npx react-native clean-project-auto", "android": "scripts/set-pusher-suffix.sh && npx react-native run-android --variant=developmentDebug --appId=com.expensify.chat.dev", - "ios": "scripts/set-pusher-suffix.sh && npx react-native run-ios --list-devices --configuration=\"Debug Development\" --scheme=\"New Expensify Dev\"", + "ios": "scripts/set-pusher-suffix.sh && npx react-native run-ios --list-devices --configuration=\"DebugDevelopment\" --scheme=\"New Expensify Dev\"", "pod-install": "cd ios && bundle exec pod install", - "ipad": "concurrently \"npx react-native run-ios --simulator=\\\"iPad Pro (12.9-inch) (6th generation)\\\" --configuration=\\\"Debug Development\\\" --scheme=\\\"New Expensify Dev\\\"\"", - "ipad-sm": "concurrently \"npx react-native run-ios --simulator=\\\"iPad Pro (11-inch) (4th generation)\\\" --configuration=\\\"Debug Development\\\" --scheme=\\\"New Expensify Dev\\\"\"", + "ipad": "concurrently \"npx react-native run-ios --simulator=\\\"iPad Pro (12.9-inch) (6th generation)\\\" --configuration=\\\"DebugDevelopment\\\" --scheme=\\\"New Expensify Dev\\\"\"", + "ipad-sm": "concurrently \"npx react-native run-ios --simulator=\\\"iPad Pro (11-inch) (4th generation)\\\" --configuration=\\\"DebugDevelopment\\\" --scheme=\\\"New Expensify Dev\\\"\"", "start": "npx react-native start", "web": "scripts/set-pusher-suffix.sh && concurrently npm:web-proxy npm:web-server", "web-proxy": "node web/proxy.js", @@ -47,10 +47,13 @@ "analyze-packages": "ANALYZE_BUNDLE=true webpack --config config/webpack/webpack.common.js --env envFile=.env.production", "symbolicate:android": "npx metro-symbolicate android/app/build/generated/sourcemaps/react/release/index.android.bundle.map", "symbolicate:ios": "npx metro-symbolicate main.jsbundle.map", - "test:e2e": "node tests/e2e/testRunner.js --development" + "test:e2e": "node tests/e2e/testRunner.js --development", + "workflow-test": "./workflow_tests/scripts/runWorkflowTests.sh", + "workflow-test:generate": "node workflow_tests/utils/preGenerateTest.js" }, "dependencies": { "@expensify/react-native-web": "0.18.15", + "@formatjs/intl-datetimeformat": "^6.10.0", "@formatjs/intl-getcanonicallocales": "^2.2.0", "@formatjs/intl-listformat": "^7.2.2", "@formatjs/intl-locale": "^3.3.0", @@ -59,6 +62,8 @@ "@gorhom/portal": "^1.0.14", "@invertase/react-native-apple-authentication": "^2.2.2", "@oguzhnatly/react-native-image-manipulator": "github:Expensify/react-native-image-manipulator#5cdae3d4455b03a04c57f50be3863e2fe6c92c52", + "@kie/act-js": "^2.0.1", + "@kie/mock-github": "^1.0.0", "@onfido/react-native-sdk": "7.4.0", "@react-native-async-storage/async-storage": "^1.17.10", "@react-native-camera-roll/camera-roll": "5.4.0", @@ -78,6 +83,7 @@ "@rnmapbox/maps": "^10.0.11", "@ua/react-native-airship": "^15.2.6", "awesome-phonenumber": "^5.4.0", + "@types/node": "^18.14.0", "babel-plugin-transform-remove-console": "^6.9.4", "babel-polyfill": "^6.26.0", "canvas-size": "^1.2.6", @@ -88,6 +94,7 @@ "domhandler": "^4.3.0", "expensify-common": "git+ssh://git@github.com/Expensify/expensify-common.git#35bff866a8d345b460ea6256f0a0f0a8a7f81086", "fbjs": "^3.0.2", + "focus-trap-react": "^10.2.1", "htmlparser2": "^7.2.0", "idb-keyval": "^6.2.1", "jest-when": "^3.5.2", @@ -100,7 +107,7 @@ "patch-package": "^8.0.0", "process": "^0.11.10", "prop-types": "^15.7.2", - "pusher-js": "7.4.0", + "pusher-js": "8.3.0", "react": "18.2.0", "react-collapse": "^5.1.0", "react-content-loader": "^6.1.0", @@ -125,7 +132,7 @@ "react-native-linear-gradient": "^2.8.1", "react-native-localize": "^2.2.6", "react-native-modal": "^13.0.0", - "react-native-onyx": "1.0.72", + "react-native-onyx": "1.0.76", "react-native-pager-view": "^6.2.0", "react-native-pdf": "^6.7.1", "react-native-performance": "^4.0.0", @@ -168,6 +175,8 @@ "@babel/runtime": "^7.20.0", "@electron/notarize": "^1.2.3", "@jest/globals": "^29.5.0", + "@kie/act-js": "^2.0.1", + "@kie/mock-github": "^1.0.0", "@octokit/core": "4.0.4", "@octokit/plugin-paginate-rest": "3.1.0", "@octokit/plugin-throttling": "4.1.0", @@ -219,7 +228,7 @@ "css-loader": "^6.7.2", "diff-so-fancy": "^1.3.0", "dotenv": "^16.0.3", - "electron": "^25.8.0", + "electron": "^25.8.1", "electron-builder": "24.6.4", "eslint": "^7.6.0", "eslint-config-airbnb-typescript": "^17.1.0", @@ -261,7 +270,8 @@ "webpack-cli": "^4.10.0", "webpack-dev-server": "^4.9.3", "webpack-font-preload-plugin": "^1.5.0", - "webpack-merge": "^5.8.0" + "webpack-merge": "^5.8.0", + "yaml": "^2.2.1" }, "overrides": { "react-native": "$react-native" diff --git a/src/App.js b/src/App.js index 7ec82b9a4f8a..284c6115d7b8 100644 --- a/src/App.js +++ b/src/App.js @@ -22,6 +22,7 @@ import ThemeProvider from './styles/themes/ThemeProvider'; import ThemeStylesProvider from './styles/ThemeStylesProvider'; import {CurrentReportIDContextProvider} from './components/withCurrentReportID'; import {EnvironmentProvider} from './components/withEnvironment'; +import {ReportAttachmentsProvider} from './pages/home/report/ReportAttachmentsContext'; import * as Session from './libs/actions/Session'; import useDefaultDragAndDrop from './hooks/useDefaultDragAndDrop'; import OnyxUpdateManager from './libs/actions/OnyxUpdateManager'; @@ -58,6 +59,7 @@ function App() { KeyboardStateProvider, PopoverContextProvider, CurrentReportIDContextProvider, + ReportAttachmentsProvider, PickerStateProvider, EnvironmentProvider, ThemeProvider, diff --git a/src/CONST.ts b/src/CONST.ts index dc7313d1137a..57b4d81f145a 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -240,6 +240,8 @@ const CONST = { TASKS: 'tasks', THREADS: 'threads', CUSTOM_STATUS: 'customStatus', + NEW_DOT_CATEGORIES: 'newDotCategories', + NEW_DOT_TAGS: 'newDotTags', }, BUTTON_STATES: { DEFAULT: 'default', @@ -1089,6 +1091,29 @@ const CONST = { DEFAULT: 'en', }, + LANGUAGES: ['en', 'es'], + + PRONOUNS_LIST: [ + 'coCos', + 'eEyEmEir', + 'heHimHis', + 'heHimHisTheyThemTheirs', + 'sheHerHers', + 'sheHerHersTheyThemTheirs', + 'merMers', + 'neNirNirs', + 'neeNerNers', + 'perPers', + 'theyThemTheirs', + 'thonThons', + 'veVerVis', + 'viVir', + 'xeXemXyr', + 'zeZieZirHir', + 'zeHirHirs', + 'callMeByMyName', + ], + POLICY: { TYPE: { FREE: 'free', diff --git a/src/ONYXKEYS.ts b/src/ONYXKEYS.ts index a2809c439931..2e0b75910bae 100755 --- a/src/ONYXKEYS.ts +++ b/src/ONYXKEYS.ts @@ -240,6 +240,8 @@ const ONYXKEYS = { POLICY_MEMBERS: 'policyMembers_', POLICY_CATEGORIES: 'policyCategories_', POLICY_RECENTLY_USED_CATEGORIES: 'policyRecentlyUsedCategories_', + POLICY_TAGS: 'policyTags_', + POLICY_RECENTLY_USED_TAGS: 'policyRecentlyUsedTags_', WORKSPACE_INVITE_MEMBERS_DRAFT: 'workspaceInviteMembersDraft_', REPORT: 'report_', REPORT_ACTIONS: 'reportActions_', @@ -375,7 +377,8 @@ type OnyxValues = { // Collections [ONYXKEYS.COLLECTION.DOWNLOAD]: OnyxTypes.Download; [ONYXKEYS.COLLECTION.POLICY]: OnyxTypes.Policy; - [ONYXKEYS.COLLECTION.POLICY_CATEGORIES]: unknown; + [ONYXKEYS.COLLECTION.POLICY_CATEGORIES]: OnyxTypes.PolicyCategory; + [ONYXKEYS.COLLECTION.POLICY_TAGS]: OnyxTypes.PolicyTag; [ONYXKEYS.COLLECTION.POLICY_MEMBERS]: OnyxTypes.PolicyMember; [ONYXKEYS.COLLECTION.POLICY_RECENTLY_USED_CATEGORIES]: OnyxTypes.RecentlyUsedCategories; [ONYXKEYS.COLLECTION.DEPRECATED_POLICY_MEMBER_LIST]: OnyxTypes.PolicyMember; @@ -390,6 +393,7 @@ type OnyxValues = { [ONYXKEYS.COLLECTION.REPORT_USER_IS_TYPING]: boolean; [ONYXKEYS.COLLECTION.SECURITY_GROUP]: OnyxTypes.SecurityGroup; [ONYXKEYS.COLLECTION.TRANSACTION]: OnyxTypes.Transaction; + [ONYXKEYS.COLLECTION.POLICY_RECENTLY_USED_TAGS]: OnyxTypes.RecentlyUsedTags; [ONYXKEYS.COLLECTION.SELECTED_TAB]: string; // Forms diff --git a/src/ROUTES.ts b/src/ROUTES.ts index ed4fbb97a41a..1133dcec8e9a 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -71,7 +71,7 @@ export default { NEW_CHAT: 'new/chat', NEW_TASK, REPORT, - REPORT_WITH_ID: 'r/:reportID/:reportActionID?', + REPORT_WITH_ID: 'r/:reportID?/:reportActionID?', EDIT_REQUEST: 'r/:threadReportID/edit/:field', getEditRequestRoute: (threadReportID: string, field: ValueOf) => `r/${threadReportID}/edit/${field}`, EDIT_CURRENCY_REQUEST: 'r/:threadReportID/edit/currency', @@ -98,11 +98,13 @@ export default { MONEY_REQUEST_CURRENCY: ':iouType/new/currency/:reportID?', MONEY_REQUEST_DESCRIPTION: ':iouType/new/description/:reportID?', MONEY_REQUEST_CATEGORY: ':iouType/new/category/:reportID?', + MONEY_REQUEST_TAG: ':iouType/new/tag/:reportID?', MONEY_REQUEST_MERCHANT: ':iouType/new/merchant/:reportID?', MONEY_REQUEST_MANUAL_TAB: ':iouType/new/:reportID?/manual', MONEY_REQUEST_SCAN_TAB: ':iouType/new/:reportID?/scan', MONEY_REQUEST_DISTANCE_TAB: ':iouType/new/:reportID?/distance', MONEY_REQUEST_WAYPOINT: ':iouType/new/waypoint/:waypointIndex', + MONEY_REQUEST_ADDRESS: ':iouType/new/address/:reportID?', IOU_SEND_ADD_BANK_ACCOUNT: `${IOU_SEND}/add-bank-account`, IOU_SEND_ADD_DEBIT_CARD: `${IOU_SEND}/add-debit-card`, IOU_SEND_ENABLE_PAYMENTS: `${IOU_SEND}/enable-payments`, @@ -117,6 +119,8 @@ export default { getMoneyRequestMerchantRoute: (iouType: string, reportID = '') => `${iouType}/new/merchant/${reportID}`, getMoneyRequestDistanceTabRoute: (iouType: string, reportID = '') => `${iouType}/new/${reportID}/distance`, getMoneyRequestWaypointRoute: (iouType: string, waypointIndex: number) => `${iouType}/new/waypoint/${waypointIndex}`, + getMoneyRequestAddressRoute: (iouType: string, reportID = '') => `${iouType}/new/address/${reportID}`, + getMoneyRequestTagRoute: (iouType: string, reportID = '') => `${iouType}/new/tag/${reportID}`, SPLIT_BILL_DETAILS: `r/:reportID/split/:reportActionID`, getSplitBillDetailsRoute: (reportID: string, reportActionID: string) => `r/${reportID}/split/${reportActionID}`, getNewTaskRoute: (reportID: string) => `${NEW_TASK}/${reportID}`, @@ -135,10 +139,10 @@ export default { FLAG_COMMENT: `flag/:reportID/:reportActionID`, getFlagCommentRoute: (reportID: string, reportActionID: string) => `flag/${reportID}/${reportActionID}`, SEARCH: 'search', - SAVE_THE_WORLD: 'save-the-world', - I_KNOW_A_TEACHER: 'save-the-world/i-know-a-teacher', - INTRO_SCHOOL_PRINCIPAL: 'save-the-world/intro-school-principal', - I_AM_A_TEACHER: 'save-the-world/i-am-a-teacher', + TEACHERS_UNITE: 'teachersunite', + I_KNOW_A_TEACHER: 'teachersunite/i-know-a-teacher', + INTRO_SCHOOL_PRINCIPAL: 'teachersunite/intro-school-principal', + I_AM_A_TEACHER: 'teachersunite/i-am-a-teacher', DETAILS: 'details', getDetailsRoute: (login: string) => `details?login=${encodeURIComponent(login)}`, PROFILE: 'a/:accountID', diff --git a/src/components/AddPlaidBankAccount.js b/src/components/AddPlaidBankAccount.js index dbe7e46ff6aa..e2843ba7fae8 100644 --- a/src/components/AddPlaidBankAccount.js +++ b/src/components/AddPlaidBankAccount.js @@ -1,6 +1,7 @@ import _ from 'underscore'; -import React, {useEffect, useRef, useCallback} from 'react'; +import React, {useEffect, useRef, useCallback, useMemo} from 'react'; import {ActivityIndicator, View} from 'react-native'; +import {useIsFocused} from '@react-navigation/native'; import PropTypes from 'prop-types'; import {withOnyx} from 'react-native-onyx'; import lodashGet from 'lodash/get'; @@ -38,6 +39,9 @@ const propTypes = { /** Fired when the user exits the Plaid flow */ onExitPlaid: PropTypes.func, + /** Fired when the screen is blurred */ + onBlurPlaid: PropTypes.func, + /** Fired when the user selects an account */ onSelect: PropTypes.func, @@ -61,6 +65,7 @@ const defaultProps = { selectedPlaidAccountID: '', plaidLinkToken: '', onExitPlaid: () => {}, + onBlurPlaid: () => {}, onSelect: () => {}, text: '', receivedRedirectURI: null, @@ -75,6 +80,7 @@ function AddPlaidBankAccount({ selectedPlaidAccountID, plaidLinkToken, onExitPlaid, + onBlurPlaid, onSelect, text, receivedRedirectURI, @@ -88,6 +94,7 @@ function AddPlaidBankAccount({ const {translate} = useLocalize(); const {isOffline} = useNetwork(); + const isFocused = useIsFocused(); /** * @returns {String} @@ -102,6 +109,11 @@ function AddPlaidBankAccount({ } }; + /** + * @returns {Array} + */ + const plaidBankAccounts = useMemo(() => lodashGet(plaidData, 'bankAccounts') || [], [plaidData]); + /** * @returns {Boolean} * I'm using useCallback so the useEffect which uses this function doesn't run on every render. @@ -151,6 +163,13 @@ function AddPlaidBankAccount({ // eslint-disable-next-line react-hooks/exhaustive-deps }, []); + useEffect(() => { + if (isFocused || plaidBankAccounts.length) { + return; + } + onBlurPlaid(); + }, [isFocused, onBlurPlaid, plaidBankAccounts.length]); + useEffect(() => { // If we are coming back from offline and we haven't authenticated with Plaid yet, we need to re-run our call to kick off Plaid // previousNetworkState.current also makes sure that this doesn't run on the first render. @@ -160,7 +179,6 @@ function AddPlaidBankAccount({ previousNetworkState.current = isOffline; }, [allowDebit, bankAccountID, isAuthenticatedWithPlaid, isOffline]); - const plaidBankAccounts = lodashGet(plaidData, 'bankAccounts') || []; const token = getPlaidLinkToken(); const options = _.map(plaidBankAccounts, (account) => ({ value: account.plaidAccountID, diff --git a/src/components/AttachmentModal.js b/src/components/AttachmentModal.js index c07a4474a68b..d39906faf3a3 100755 --- a/src/components/AttachmentModal.js +++ b/src/components/AttachmentModal.js @@ -25,7 +25,6 @@ import HeaderGap from './HeaderGap'; import SafeAreaConsumer from './SafeAreaConsumer'; import addEncryptedAuthTokenToURL from '../libs/addEncryptedAuthTokenToURL'; import reportPropTypes from '../pages/reportPropTypes'; -import tryResolveUrlFromApiRoot from '../libs/tryResolveUrlFromApiRoot'; /** * Modal render prop component that exposes modal launching triggers that can be used @@ -351,7 +350,7 @@ function AttachmentModal(props) { onCanceled.current(), {once: true}); + fileInput.current.addEventListener( + 'cancel', + () => { + // For Android Chrome, the cancel event happens before the page is visible on physical devices, + // which makes it unreliable for us to show the keyboard, while on emulators it happens after the page is visible. + // So here we can delay calling the onCanceled.current function based on visibility in order to reliably show the keyboard. + if (Visibility.isVisible()) { + onCanceled.current(); + return; + } + const unsubscribeVisibilityListener = Visibility.onVisibilityChange(() => { + onCanceled.current(); + unsubscribeVisibilityListener(); + }); + }, + {once: true}, + ); }} accept={getAcceptableFileTypes(props.type)} /> diff --git a/src/components/Attachments/AttachmentCarousel/CarouselItem.js b/src/components/Attachments/AttachmentCarousel/CarouselItem.js new file mode 100644 index 000000000000..3aeef8482e2d --- /dev/null +++ b/src/components/Attachments/AttachmentCarousel/CarouselItem.js @@ -0,0 +1,115 @@ +import React, {useContext, useState} from 'react'; +import {View} from 'react-native'; +import PropTypes from 'prop-types'; +import CONST from '../../../CONST'; +import styles from '../../../styles/styles'; +import useLocalize from '../../../hooks/useLocalize'; +import PressableWithoutFeedback from '../../Pressable/PressableWithoutFeedback'; +import Text from '../../Text'; +import Button from '../../Button'; +import AttachmentView from '../AttachmentView'; +import SafeAreaConsumer from '../../SafeAreaConsumer'; +import ReportAttachmentsContext from '../../../pages/home/report/ReportAttachmentsContext'; + +const propTypes = { + /** Attachment required information such as the source and file name */ + item: PropTypes.shape({ + /** Report action ID of the attachment */ + reportActionID: PropTypes.string, + + /** Whether source URL requires authentication */ + isAuthTokenRequired: PropTypes.bool, + + /** The source (URL) of the attachment */ + source: PropTypes.string, + + /** Additional information about the attachment file */ + file: PropTypes.shape({ + /** File name of the attachment */ + name: PropTypes.string, + }), + + /** Whether the attachment has been flagged */ + hasBeenFlagged: PropTypes.bool, + }).isRequired, + + /** Whether the attachment is currently being viewed in the carousel */ + isFocused: PropTypes.bool.isRequired, + + /** onPress callback */ + onPress: PropTypes.func, +}; + +const defaultProps = { + onPress: undefined, +}; + +function CarouselItem({item, isFocused, onPress}) { + const {translate} = useLocalize(); + const {isAttachmentHidden} = useContext(ReportAttachmentsContext); + // eslint-disable-next-line es/no-nullish-coalescing-operators + const [isHidden, setIsHidden] = useState(isAttachmentHidden(item.reportActionID) ?? item.hasBeenFlagged); + + const renderButton = (style) => ( + + ); + + if (isHidden) { + const children = ( + <> + {translate('moderation.flaggedContent')} + {renderButton([styles.mt2])} + + ); + return onPress ? ( + + {children} + + ) : ( + {children} + ); + } + + return ( + + + + + + {item.hasBeenFlagged && ( + + {({safeAreaPaddingBottomStyle}) => {renderButton([styles.m4, styles.alignSelfCenter])}} + + )} + + ); +} + +CarouselItem.propTypes = propTypes; +CarouselItem.defaultProps = defaultProps; + +export default CarouselItem; diff --git a/src/components/Attachments/AttachmentCarousel/extractAttachmentsFromReport.js b/src/components/Attachments/AttachmentCarousel/extractAttachmentsFromReport.js index b967d5ab0066..d5da25c89576 100644 --- a/src/components/Attachments/AttachmentCarousel/extractAttachmentsFromReport.js +++ b/src/components/Attachments/AttachmentCarousel/extractAttachmentsFromReport.js @@ -28,10 +28,12 @@ function extractAttachmentsFromReport(report, reportActions) { // By iterating actions in chronological order and prepending each attachment // we ensure correct order of attachments even across actions with multiple attachments. attachments.unshift({ + reportActionID: attribs['data-id'], source: tryResolveUrlFromApiRoot(expensifySource || attribs.src), isAuthTokenRequired: Boolean(expensifySource), file: {name: attribs[CONST.ATTACHMENT_ORIGINAL_FILENAME_ATTRIBUTE]}, isReceipt: false, + hasBeenFlagged: attribs['data-flagged'] === 'true', }); }, }); @@ -62,7 +64,10 @@ function extractAttachmentsFromReport(report, reportActions) { } } - htmlParser.write(_.get(action, ['message', 0, 'html'])); + const decision = _.get(action, ['message', 0, 'moderationDecision', 'decision'], ''); + const hasBeenFlagged = decision === CONST.MODERATION.MODERATOR_DECISION_PENDING_HIDE || decision === CONST.MODERATION.MODERATOR_DECISION_HIDDEN; + const html = _.get(action, ['message', 0, 'html'], '').replace('/>', `data-flagged="${hasBeenFlagged}" data-id="${action.reportActionID}"/>`); + htmlParser.write(html); }); htmlParser.end(); diff --git a/src/components/Attachments/AttachmentCarousel/index.js b/src/components/Attachments/AttachmentCarousel/index.js index 53c2c840d95d..5c731a0ccfee 100644 --- a/src/components/Attachments/AttachmentCarousel/index.js +++ b/src/components/Attachments/AttachmentCarousel/index.js @@ -2,10 +2,8 @@ import React, {useRef, useCallback, useState, useEffect} from 'react'; import {View, FlatList, PixelRatio, Keyboard} from 'react-native'; import {withOnyx} from 'react-native-onyx'; import _ from 'underscore'; -import * as DeviceCapabilities from '../../../libs/DeviceCapabilities'; import styles from '../../../styles/styles'; import CarouselActions from './CarouselActions'; -import AttachmentView from '../AttachmentView'; import withWindowDimensions from '../../withWindowDimensions'; import CarouselButtons from './CarouselButtons'; import extractAttachmentsFromReport from './extractAttachmentsFromReport'; @@ -15,12 +13,13 @@ import withLocalize from '../../withLocalize'; import compose from '../../../libs/compose'; import useCarouselArrows from './useCarouselArrows'; import useWindowDimensions from '../../../hooks/useWindowDimensions'; +import CarouselItem from './CarouselItem'; import Navigation from '../../../libs/Navigation/Navigation'; import BlockingView from '../../BlockingViews/BlockingView'; import * as Illustrations from '../../Icon/Illustrations'; import variables from '../../../styles/variables'; +import * as DeviceCapabilities from '../../../libs/DeviceCapabilities'; -const canUseTouchScreen = DeviceCapabilities.canUseTouchScreen(); const viewabilityConfig = { // To facilitate paging through the attachments, we want to consider an item "viewable" when it is // more than 95% visible. When that happens we update the page index in the state. @@ -31,6 +30,7 @@ function AttachmentCarousel({report, reportActions, source, onNavigate, setDownl const scrollRef = useRef(null); const {windowWidth, isSmallScreenWidth} = useWindowDimensions(); + const canUseTouchScreen = DeviceCapabilities.canUseTouchScreen(); const [containerWidth, setContainerWidth] = useState(0); const [page, setPage] = useState(0); @@ -99,7 +99,7 @@ function AttachmentCarousel({report, reportActions, source, onNavigate, setDownl scrollRef.current.scrollToIndex({index: nextIndex, animated: canUseTouchScreen}); }, - [attachments, page], + [attachments, canUseTouchScreen, page], ); /** @@ -143,24 +143,23 @@ function AttachmentCarousel({report, reportActions, source, onNavigate, setDownl /** * Defines how a single attachment should be rendered * @param {Object} item + * @param {String} item.reportActionID * @param {Boolean} item.isAuthTokenRequired * @param {String} item.source * @param {Object} item.file * @param {String} item.file.name + * @param {Boolean} item.hasBeenFlagged * @returns {JSX.Element} */ const renderItem = useCallback( ({item}) => ( - setShouldShowArrows(!shouldShowArrows) : undefined} - isUsedInCarousel /> ), - [activeSource, setShouldShowArrows, shouldShowArrows], + [activeSource, canUseTouchScreen, setShouldShowArrows, shouldShowArrows], ); return ( diff --git a/src/components/Attachments/AttachmentCarousel/index.native.js b/src/components/Attachments/AttachmentCarousel/index.native.js index 4162cfae88e9..95cda7c2f5c9 100644 --- a/src/components/Attachments/AttachmentCarousel/index.native.js +++ b/src/components/Attachments/AttachmentCarousel/index.native.js @@ -5,11 +5,11 @@ import _ from 'underscore'; import AttachmentCarouselPager from './Pager'; import styles from '../../../styles/styles'; import CarouselButtons from './CarouselButtons'; -import AttachmentView from '../AttachmentView'; import ONYXKEYS from '../../../ONYXKEYS'; import {propTypes, defaultProps} from './attachmentCarouselPropTypes'; import extractAttachmentsFromReport from './extractAttachmentsFromReport'; import useCarouselArrows from './useCarouselArrows'; +import CarouselItem from './CarouselItem'; import Navigation from '../../../libs/Navigation/Navigation'; import BlockingView from '../../BlockingViews/BlockingView'; import * as Illustrations from '../../Icon/Illustrations'; @@ -85,17 +85,14 @@ function AttachmentCarousel({report, reportActions, source, onNavigate, onClose, /** * Defines how a single attachment should be rendered - * @param {{ isAuthTokenRequired: Boolean, source: String, file: { name: String } }} item + * @param {{ reportActionID: String, isAuthTokenRequired: Boolean, source: String, file: { name: String }, hasBeenFlagged: Boolean }} item * @returns {JSX.Element} */ const renderItem = useCallback( ({item}) => ( - setShouldShowArrows(!shouldShowArrows)} /> ), diff --git a/src/components/Attachments/AttachmentCarousel/useCarouselArrows.js b/src/components/Attachments/AttachmentCarousel/useCarouselArrows.js index f43a26ab94ee..64c97fa99819 100644 --- a/src/components/Attachments/AttachmentCarousel/useCarouselArrows.js +++ b/src/components/Attachments/AttachmentCarousel/useCarouselArrows.js @@ -2,9 +2,8 @@ import {useCallback, useEffect, useRef, useState} from 'react'; import CONST from '../../../CONST'; import * as DeviceCapabilities from '../../../libs/DeviceCapabilities'; -const canUseTouchScreen = DeviceCapabilities.canUseTouchScreen(); - function useCarouselArrows() { + const canUseTouchScreen = DeviceCapabilities.canUseTouchScreen(); const [shouldShowArrows, setShouldShowArrowsInternal] = useState(canUseTouchScreen); const autoHideArrowTimeout = useRef(null); @@ -25,7 +24,7 @@ function useCarouselArrows() { autoHideArrowTimeout.current = setTimeout(() => { setShouldShowArrowsInternal(false); }, CONST.ARROW_HIDE_DELAY); - }, [cancelAutoHideArrows]); + }, [canUseTouchScreen, cancelAutoHideArrows]); const setShouldShowArrows = useCallback( (show = true) => { diff --git a/src/components/CategoryPicker/categoryPickerPropTypes.js b/src/components/CategoryPicker/categoryPickerPropTypes.js index ccc1643021ce..b8e24c199a73 100644 --- a/src/components/CategoryPicker/categoryPickerPropTypes.js +++ b/src/components/CategoryPicker/categoryPickerPropTypes.js @@ -14,11 +14,23 @@ const propTypes = { /* Onyx Props */ /** Collection of categories attached to a policy */ policyCategories: PropTypes.objectOf(categoryPropTypes), + + /* Onyx Props */ + /** Collection of recently used categories attached to a policy */ + policyRecentlyUsedCategories: PropTypes.arrayOf(PropTypes.string), + + /* Onyx Props */ + /** Holds data related to Money Request view state, rather than the underlying Money Request data. */ + iou: PropTypes.shape({ + category: PropTypes.string.isRequired, + }), }; const defaultProps = { policyID: '', - policyCategories: null, + policyCategories: {}, + policyRecentlyUsedCategories: [], + iou: {}, }; export {propTypes, defaultProps}; diff --git a/src/components/CategoryPicker/index.js b/src/components/CategoryPicker/index.js index 163ab6673ca2..91c7e82e7887 100644 --- a/src/components/CategoryPicker/index.js +++ b/src/components/CategoryPicker/index.js @@ -1,47 +1,88 @@ -import React, {useMemo} from 'react'; -import _ from 'underscore'; +import React, {useMemo, useState} from 'react'; import {withOnyx} from 'react-native-onyx'; +import _ from 'underscore'; +import lodashGet from 'lodash/get'; import ONYXKEYS from '../../ONYXKEYS'; import {propTypes, defaultProps} from './categoryPickerPropTypes'; -import OptionsList from '../OptionsList'; import styles from '../../styles/styles'; -import ScreenWrapper from '../ScreenWrapper'; import Navigation from '../../libs/Navigation/Navigation'; import ROUTES from '../../ROUTES'; +import CONST from '../../CONST'; +import * as IOU from '../../libs/actions/IOU'; +import * as OptionsListUtils from '../../libs/OptionsListUtils'; +import OptionsSelector from '../OptionsSelector'; +import useLocalize from '../../hooks/useLocalize'; + +function CategoryPicker({policyCategories, reportID, iouType, iou, policyRecentlyUsedCategories}) { + const {translate} = useLocalize(); + const [searchValue, setSearchValue] = useState(''); + + const policyCategoriesCount = _.size(policyCategories); + const isCategoriesCountBelowThreshold = policyCategoriesCount < CONST.CATEGORY_LIST_THRESHOLD; -function CategoryPicker({policyCategories, reportID, iouType}) { - const sections = useMemo(() => { - const categoryList = _.chain(policyCategories) - .values() - .map((category) => ({ - text: category.name, - keyForList: category.name, - tooltipText: category.name, - })) - .value(); + const selectedOptions = useMemo(() => { + if (!iou.category) { + return []; + } return [ { - data: categoryList, + name: iou.category, + enabled: true, + accountID: null, }, ]; - }, [policyCategories]); + }, [iou.category]); + + const initialFocusedIndex = useMemo(() => { + if (isCategoriesCountBelowThreshold && selectedOptions.length > 0) { + return _.chain(policyCategories) + .values() + .findIndex((category) => category.name === selectedOptions[0].name, true) + .value(); + } + + return 0; + }, [policyCategories, selectedOptions, isCategoriesCountBelowThreshold]); + + const sections = useMemo( + () => OptionsListUtils.getNewChatOptions({}, {}, [], searchValue, selectedOptions, [], false, false, true, policyCategories, policyRecentlyUsedCategories, false).categoryOptions, + [policyCategories, policyRecentlyUsedCategories, searchValue, selectedOptions], + ); + + const headerMessage = OptionsListUtils.getHeaderMessage(lodashGet(sections, '[0].data.length', 0) > 0, false, searchValue); + const shouldShowTextInput = !isCategoriesCountBelowThreshold; const navigateBack = () => { Navigation.goBack(ROUTES.getMoneyRequestConfirmationRoute(iouType, reportID)); }; + const updateCategory = (category) => { + if (category.searchText === iou.category) { + IOU.resetMoneyRequestCategory(); + } else { + IOU.setMoneyRequestCategory(category.searchText); + } + + navigateBack(); + }; + return ( - - {({safeAreaPaddingBottomStyle}) => ( - - )} - + ); } @@ -53,4 +94,10 @@ export default withOnyx({ policyCategories: { key: ({policyID}) => `${ONYXKEYS.COLLECTION.POLICY_CATEGORIES}${policyID}`, }, + policyRecentlyUsedCategories: { + key: ({policyID}) => `${ONYXKEYS.COLLECTION.POLICY_RECENTLY_USED_CATEGORIES}${policyID}`, + }, + iou: { + key: ONYXKEYS.IOU, + }, })(CategoryPicker); diff --git a/src/components/ConfirmedRoute.js b/src/components/ConfirmedRoute.js index 6790e8ae4d65..4bcdc4738a3c 100644 --- a/src/components/ConfirmedRoute.js +++ b/src/components/ConfirmedRoute.js @@ -16,7 +16,7 @@ import transactionPropTypes from './transactionPropTypes'; import BlockingView from './BlockingViews/BlockingView'; import useNetwork from '../hooks/useNetwork'; import useLocalize from '../hooks/useLocalize'; -import MapView from './MapView'; +import DistanceMapView from './DistanceMapView'; const propTypes = { /** Transaction that stores the distance request data */ @@ -90,7 +90,7 @@ function ConfirmedRoute({mapboxAccessToken, transaction}) { return ( <> {!isOffline && Boolean(mapboxAccessToken.token) ? ( - - _.map(translate('allCountries'), (countryName, countryISO) => ({ - value: countryISO, - keyForList: countryISO, - text: countryName, - isSelected: currentCountry === countryISO, - searchValue: StringUtils.sanitizeString(`${countryISO}${countryName}`), - })), + _.map(_.keys(CONST.ALL_COUNTRIES), (countryISO) => { + const countryName = translate(`allCountries.${countryISO}`); + return { + value: countryISO, + keyForList: countryISO, + text: countryName, + isSelected: currentCountry === countryISO, + searchValue: StringUtils.sanitizeString(`${countryISO}${countryName}`), + }; + }), [translate, currentCountry], ); diff --git a/src/components/CountryPicker/index.js b/src/components/CountryPicker/index.js index c6bbae0dd645..c838ed8f4060 100644 --- a/src/components/CountryPicker/index.js +++ b/src/components/CountryPicker/index.js @@ -31,7 +31,6 @@ const defaultProps = { function CountryPicker({value, errorText, onInputChange, forwardedRef}) { const {translate} = useLocalize(); - const allCountries = translate('allCountries'); const [isPickerVisible, setIsPickerVisible] = useState(false); const [searchValue, setSearchValue] = useState(''); @@ -48,7 +47,7 @@ function CountryPicker({value, errorText, onInputChange, forwardedRef}) { hidePickerModal(); }; - const title = allCountries[value] || ''; + const title = value ? translate(`allCountries.${value}`) : ''; const descStyle = title.length === 0 ? styles.textNormal : null; return ( diff --git a/src/components/DeeplinkWrapper/DeeplinkRedirectLoadingIndicator.js b/src/components/DeeplinkWrapper/DeeplinkRedirectLoadingIndicator.js index e31429af61b6..61614c7e49e6 100644 --- a/src/components/DeeplinkWrapper/DeeplinkRedirectLoadingIndicator.js +++ b/src/components/DeeplinkWrapper/DeeplinkRedirectLoadingIndicator.js @@ -7,7 +7,7 @@ import Text from '../Text'; import Icon from '../Icon'; import * as Illustrations from '../Icon/Illustrations'; import * as Expensicons from '../Icon/Expensicons'; -import colors from '../../styles/colors'; +import themeColors from '../../styles/themes/default'; import styles from '../../styles/styles'; import withLocalize, {withLocalizePropTypes} from '../withLocalize'; import Navigation from '../../libs/Navigation/Navigation'; @@ -56,7 +56,7 @@ function DeeplinkRedirectLoadingIndicator({translate, openLinkInBrowser, session diff --git a/src/components/DistanceMapView/distanceMapViewPropTypes.js b/src/components/DistanceMapView/distanceMapViewPropTypes.js new file mode 100644 index 000000000000..05068cbc9b34 --- /dev/null +++ b/src/components/DistanceMapView/distanceMapViewPropTypes.js @@ -0,0 +1,55 @@ +import PropTypes from 'prop-types'; + +const propTypes = { + // Public access token to be used to fetch map data from Mapbox. + accessToken: PropTypes.string.isRequired, + + // Style applied to MapView component. Note some of the View Style props are not available on ViewMap + style: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.object), PropTypes.object]), + + // Link to the style JSON document. + styleURL: PropTypes.string, + + // Whether map can tilt in the vertical direction. + pitchEnabled: PropTypes.bool, + + // Padding to apply when the map is adjusted to fit waypoints and directions + mapPadding: PropTypes.number, + + // Initial coordinate and zoom level + initialState: PropTypes.shape({ + location: PropTypes.arrayOf(PropTypes.number).isRequired, + zoom: PropTypes.number.isRequired, + }), + + // Locations on which to put markers + waypoints: PropTypes.arrayOf( + PropTypes.shape({ + id: PropTypes.string, + coordinate: PropTypes.arrayOf(PropTypes.number), + markerComponent: PropTypes.oneOfType([PropTypes.element, PropTypes.func]), + }), + ), + + // List of coordinates which together forms a direction. + directionCoordinates: PropTypes.arrayOf(PropTypes.arrayOf(PropTypes.number)), + + // Callback to call when the map is idle / ready + onMapReady: PropTypes.func, + + // Optional additional styles to be applied to the overlay + overlayStyle: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.object), PropTypes.object]), +}; + +const defaultProps = { + styleURL: undefined, + pitchEnabled: false, + mapPadding: 0, + initialState: undefined, + waypoints: undefined, + directionCoordinates: undefined, + onMapReady: () => {}, + overlayStyle: undefined, +}; + +export {propTypes, defaultProps}; diff --git a/src/components/DistanceMapView/index.android.js b/src/components/DistanceMapView/index.android.js new file mode 100644 index 000000000000..ea72fb4de299 --- /dev/null +++ b/src/components/DistanceMapView/index.android.js @@ -0,0 +1,48 @@ +import React, {useState} from 'react'; +import {View} from 'react-native'; +import _ from 'underscore'; +import BlockingView from '../BlockingViews/BlockingView'; +import MapView from '../MapView'; +import styles from '../../styles/styles'; +import useNetwork from '../../hooks/useNetwork'; +import useLocalize from '../../hooks/useLocalize'; +import * as Expensicons from '../Icon/Expensicons'; +import * as StyleUtils from '../../styles/StyleUtils'; +import * as distanceMapViewPropTypes from './distanceMapViewPropTypes'; + +function DistanceMapView(props) { + const [isMapReady, setIsMapReady] = useState(false); + const {isOffline} = useNetwork(); + const {translate} = useLocalize(); + + return ( + <> + { + if (isMapReady) { + return; + } + setIsMapReady(true); + }} + /> + {!isMapReady && ( + + + + )} + + ); +} + +DistanceMapView.propTypes = distanceMapViewPropTypes.propTypes; +DistanceMapView.defaultProps = distanceMapViewPropTypes.defaultProps; +DistanceMapView.displayName = 'DistanceMapView'; + +export default DistanceMapView; diff --git a/src/components/DistanceMapView/index.js b/src/components/DistanceMapView/index.js new file mode 100644 index 000000000000..24bdf99382d1 --- /dev/null +++ b/src/components/DistanceMapView/index.js @@ -0,0 +1,15 @@ +import React from 'react'; +import _ from 'underscore'; +import MapView from '../MapView'; +import * as distanceMapViewPropTypes from './distanceMapViewPropTypes'; + +function DistanceMapView(props) { + // eslint-disable-next-line react/jsx-props-no-spreading + return ; +} + +DistanceMapView.propTypes = distanceMapViewPropTypes.propTypes; +DistanceMapView.defaultProps = distanceMapViewPropTypes.defaultProps; +DistanceMapView.displayName = 'DistanceMapView'; + +export default DistanceMapView; diff --git a/src/components/DistanceRequest.js b/src/components/DistanceRequest.js index e0d8e8b642f6..bf5a4cb9548b 100644 --- a/src/components/DistanceRequest.js +++ b/src/components/DistanceRequest.js @@ -26,9 +26,10 @@ import Navigation from '../libs/Navigation/Navigation'; import * as MapboxToken from '../libs/actions/MapboxToken'; import * as Transaction from '../libs/actions/Transaction'; import * as TransactionUtils from '../libs/TransactionUtils'; +import * as IOUUtils from '../libs/IOUUtils'; import Button from './Button'; -import MapView from './MapView'; +import DistanceMapView from './DistanceMapView'; import LinearGradient from './LinearGradient'; import * as Expensicons from './Icon/Expensicons'; import BlockingView from './BlockingViews/BlockingView'; @@ -38,6 +39,9 @@ import {iouPropTypes} from '../pages/iou/propTypes'; import reportPropTypes from '../pages/reportPropTypes'; import * as IOU from '../libs/actions/IOU'; import * as StyleUtils from '../styles/StyleUtils'; +import ScreenWrapper from './ScreenWrapper'; +import FullPageNotFoundView from './BlockingViews/FullPageNotFoundView'; +import HeaderWithBackButton from './HeaderWithBackButton'; const MAX_WAYPOINTS = 25; const MAX_WAYPOINTS_TO_DISPLAY = 4; @@ -63,6 +67,18 @@ const propTypes = { /** Time when the token will expire in ISO 8601 */ expiration: PropTypes.string, }), + + /** React Navigation route */ + route: PropTypes.shape({ + /** Params from the route */ + params: PropTypes.shape({ + /** The type of IOU report, i.e. bill, request, send */ + iouType: PropTypes.string, + + /** The report ID of the IOU */ + reportID: PropTypes.string, + }), + }).isRequired, }; const defaultProps = { @@ -75,13 +91,14 @@ const defaultProps = { }, }; -function DistanceRequest({iou, iouType, report, transaction, mapboxAccessToken}) { +function DistanceRequest({iou, iouType, report, transaction, mapboxAccessToken, route}) { const [shouldShowGradient, setShouldShowGradient] = useState(false); const [scrollContainerHeight, setScrollContainerHeight] = useState(0); const [scrollContentHeight, setScrollContentHeight] = useState(0); const {isOffline} = useNetwork(); const {translate} = useLocalize(); + const isEditing = lodashGet(route, 'path', '').includes('address'); const reportID = lodashGet(report, 'reportID', ''); const waypoints = useMemo(() => lodashGet(transaction, 'comment.waypoints', {}), [transaction]); const previousWaypoints = usePrevious(waypoints); @@ -161,21 +178,36 @@ function DistanceRequest({iou, iouType, report, transaction, mapboxAccessToken}) Transaction.getRoute(iou.transactionID, validatedWaypoints); }, [shouldFetchRoute, iou.transactionID, validatedWaypoints, isOffline]); + useEffect(() => { + if (numberOfWaypoints <= numberOfPreviousWaypoints) { + return; + } + scrollViewRef.current.scrollToEnd({animated: true}); + }, [numberOfPreviousWaypoints, numberOfWaypoints]); + useEffect(updateGradientVisibility, [scrollContainerHeight, scrollContentHeight]); - return ( + const navigateBack = () => { + Navigation.goBack(isEditing ? ROUTES.getMoneyRequestConfirmationRoute(iouType, reportID) : null); + }; + + const navigateToNextPage = () => { + if (isEditing) { + Navigation.goBack(ROUTES.getMoneyRequestConfirmationRoute(iouType, reportID)); + return; + } + + IOU.navigateToNextPage(iou, iouType, reportID, report); + }; + + const content = ( setScrollContainerHeight(lodashGet(event, 'nativeEvent.layout.height', 0))} > { - if (scrollContentHeight < height && numberOfWaypoints > numberOfPreviousWaypoints) { - scrollViewRef.current.scrollToEnd({animated: true}); - } - setScrollContentHeight(height); - }} + onContentSizeChange={(width, height) => setScrollContentHeight(height)} onScroll={updateGradientVisibility} scrollEventThrottle={variables.distanceScrollEventThrottle} ref={scrollViewRef} @@ -236,7 +268,7 @@ function DistanceRequest({iou, iouType, report, transaction, mapboxAccessToken}) {!isOffline && Boolean(mapboxAccessToken.token) ? ( - ) : ( @@ -263,12 +296,35 @@ function DistanceRequest({iou, iouType, report, transaction, mapboxAccessToken})