diff --git a/.github/actions/composite/setupNode/action.yml b/.github/actions/composite/setupNode/action.yml index c6a6029e06e0..b3bbf7a537ff 100644 --- a/.github/actions/composite/setupNode/action.yml +++ b/.github/actions/composite/setupNode/action.yml @@ -31,7 +31,7 @@ runs: - name: Install root project node packages if: steps.cache-node-modules.outputs.cache-hit != 'true' - uses: nick-fields/retry@v2 + uses: nick-fields/retry@3f757583fb1b1f940bc8ef4bf4734c8dc02a5847 with: timeout_minutes: 30 max_attempts: 3 @@ -39,7 +39,7 @@ runs: - name: Install node packages for desktop submodule if: steps.cache-desktop-node-modules.outputs.cache-hit != 'true' - uses: nick-fields/retry@v2 + uses: nick-fields/retry@3f757583fb1b1f940bc8ef4bf4734c8dc02a5847 with: timeout_minutes: 30 max_attempts: 3 diff --git a/.github/actions/javascript/proposalPoliceComment/index.js b/.github/actions/javascript/proposalPoliceComment/index.js index e000c99bc4ca..49dbe3b52cf7 100644 --- a/.github/actions/javascript/proposalPoliceComment/index.js +++ b/.github/actions/javascript/proposalPoliceComment/index.js @@ -18487,12 +18487,6 @@ class GithubUtils { }) .then((response) => response.data.workflow_runs[0]?.id); } - /** - * Generate the well-formatted body of a production release. - */ - static getReleaseBody(pullRequests) { - return pullRequests.map((number) => `- ${this.getPullRequestURLFromNumber(number)}`).join('\r\n'); - } /** * Generate the URL of an New Expensify pull request given the PR number. */ diff --git a/.github/scripts/verifyPodfile.sh b/.github/scripts/verifyPodfile.sh index f4b1c5521733..2c9a7dee672a 100755 --- a/.github/scripts/verifyPodfile.sh +++ b/.github/scripts/verifyPodfile.sh @@ -1,5 +1,7 @@ #!/bin/bash +set -e + START_DIR=$(pwd) ROOT_DIR=$(dirname "$(dirname "$(dirname "${BASH_SOURCE[0]}")")") cd "$ROOT_DIR" || exit 1 diff --git a/.github/workflows/platformDeploy.yml b/.github/workflows/platformDeploy.yml index f2fda2bc56ff..1eb86cb981b4 100644 --- a/.github/workflows/platformDeploy.yml +++ b/.github/workflows/platformDeploy.yml @@ -209,14 +209,13 @@ jobs: with: path: ios/Pods key: ${{ runner.os }}-pods-cache-${{ hashFiles('ios/Podfile.lock', 'firebase.json') }} - restore-keys: ${{ runner.os }}-pods-cache- - name: Compare Podfile.lock and Manifest.lock id: compare-podfile-and-manifest run: echo "IS_PODFILE_SAME_AS_MANIFEST=${{ hashFiles('ios/Podfile.lock') == hashFiles('ios/Pods/Manifest.lock') }}" >> "$GITHUB_OUTPUT" - name: Install cocoapods - uses: nick-invision/retry@0711ba3d7808574133d713a0d92d2941be03a350 + uses: nick-fields/retry@3f757583fb1b1f940bc8ef4bf4734c8dc02a5847 if: steps.pods-cache.outputs.cache-hit != 'true' || steps.compare-podfile-and-manifest.outputs.IS_PODFILE_SAME_AS_MANIFEST != 'true' || steps.setup-node.outputs.cache-hit != 'true' with: timeout_minutes: 10 @@ -379,7 +378,7 @@ jobs: - name: Upload web build to GitHub Release if: ${{ fromJSON(env.SHOULD_DEPLOY_PRODUCTION) }} - run: + run: | tar -czvf webBuild.tar.gz dist zip -r webBuild.zip dist gh release upload ${{ github.event.release.tag_name }} webBuild.tar.gz webBuild.zip diff --git a/.github/workflows/testBuild.yml b/.github/workflows/testBuild.yml index 1abe22dc395d..024f5b712a3f 100644 --- a/.github/workflows/testBuild.yml +++ b/.github/workflows/testBuild.yml @@ -173,14 +173,13 @@ jobs: with: path: ios/Pods key: ${{ runner.os }}-pods-cache-${{ hashFiles('ios/Podfile.lock', 'firebase.json') }} - restore-keys: ${{ runner.os }}-pods-cache- - name: Compare Podfile.lock and Manifest.lock id: compare-podfile-and-manifest run: echo "IS_PODFILE_SAME_AS_MANIFEST=${{ hashFiles('ios/Podfile.lock') == hashFiles('ios/Pods/Manifest.lock') }}" >> "$GITHUB_OUTPUT" - name: Install cocoapods - uses: nick-invision/retry@0711ba3d7808574133d713a0d92d2941be03a350 + uses: nick-fields/retry@3f757583fb1b1f940bc8ef4bf4734c8dc02a5847 if: steps.pods-cache.outputs.cache-hit != 'true' || steps.compare-podfile-and-manifest.outputs.IS_PODFILE_SAME_AS_MANIFEST != 'true' || steps.setup-node.outputs.cache-hit != 'true' with: timeout_minutes: 10 diff --git a/.well-known/apple-app-site-association b/.well-known/apple-app-site-association index 394e45f8d9ae..dce724440adf 100644 --- a/.well-known/apple-app-site-association +++ b/.well-known/apple-app-site-association @@ -91,6 +91,14 @@ { "/": "/money2020/*", "comment": "Money 2020" + }, + { + "/": "/track-expense/*", + "comment": "Track Expense" + }, + { + "/": "/submit-expense/*", + "comment": "Submit Expense" } ] } diff --git a/android/app/build.gradle b/android/app/build.gradle index 66a2ba20102d..2f83c52a1713 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -108,8 +108,8 @@ android { minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion multiDexEnabled rootProject.ext.multiDexEnabled - versionCode 1009001303 - versionName "9.0.13-3" + versionCode 1009001402 + versionName "9.0.14-2" // Supported language variants must be declared here to avoid from being removed during the compilation. // This also helps us to not include unnecessary language variants in the APK. resConfigs "en", "es" diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 520602a28a02..142d919a7a18 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -73,6 +73,8 @@ + + @@ -94,6 +96,8 @@ + + diff --git a/assets/emojis/common.ts b/assets/emojis/common.ts index c19d958812d1..5162a71367b2 100644 --- a/assets/emojis/common.ts +++ b/assets/emojis/common.ts @@ -162,10 +162,26 @@ const emojis: PickerEmojis = [ name: 'hand_over_mouth', code: '🤭', }, + { + name: 'face_with_open_eyes_and_hand_over_mouth', + code: '🫢', + }, + { + name: 'saluting_face', + code: '🫡', + }, { name: 'shushing_face', code: '🤫', }, + { + name: 'face_with_peeking_eye', + code: '🫣', + }, + { + name: 'melting_face', + code: '🫠', + }, { name: 'thinking', code: '🤔', @@ -174,6 +190,10 @@ const emojis: PickerEmojis = [ name: 'zipper_mouth_face', code: '🤐', }, + { + name: 'dotted_line_face', + code: '🫥', + }, { name: 'raised_eyebrow', code: '🤨', @@ -182,10 +202,18 @@ const emojis: PickerEmojis = [ name: 'neutral_face', code: '😐', }, + { + name: 'face_with_diagonal_mouth', + code: '🫤', + }, { name: 'expressionless', code: '😑', }, + { + name: 'shaking_face', + code: '🫨', + }, { name: 'no_mouth', code: '😶', @@ -362,6 +390,10 @@ const emojis: PickerEmojis = [ name: 'cold_sweat', code: '😰', }, + { + name: 'face_holding_back_tears', + code: '🥹', + }, { name: 'disappointed_relieved', code: '😥', @@ -578,6 +610,18 @@ const emojis: PickerEmojis = [ name: 'heart', code: '❤️', }, + { + name: 'pink_heart', + code: '🩷', + }, + { + name: 'light_blue_heart', + code: '🩵', + }, + { + name: 'grey_heart', + code: '🩶', + }, { name: 'orange_heart', code: '🧡', @@ -630,6 +674,10 @@ const emojis: PickerEmojis = [ name: 'sweat_drops', code: '💦', }, + { + name: 'bubbles', + code: '🫧', + }, { name: 'dash', code: '💨', @@ -706,6 +754,16 @@ const emojis: PickerEmojis = [ code: '🤏', types: ['🤏🏿', '🤏🏾', '🤏🏽', '🤏🏼', '🤏🏻'], }, + { + name: 'palm_down_hand', + code: '🫳', + types: ['🫳🏿', '🫳🏾', '🫳🏽', '🫳🏼', '🫳🏻'], + }, + { + name: 'palm_up_hand', + code: '🫴', + types: ['🫴🏿', '🫴🏾', '🫴🏽', '🫴🏼', '🫴🏻'], + }, { name: 'v', code: '✌️', @@ -716,6 +774,11 @@ const emojis: PickerEmojis = [ code: '🤞', types: ['🤞🏿', '🤞🏾', '🤞🏽', '🤞🏼', '🤞🏻'], }, + { + name: 'hand_with_index_finger_and_thumb_crossed', + code: '🫰', + types: ['🫰🏿', '🫰🏾', '🫰🏽', '🫰🏼', '🫰🏻'], + }, { name: 'love_you_gesture', code: '🤟', @@ -731,6 +794,16 @@ const emojis: PickerEmojis = [ code: '🤙', types: ['🤙🏿', '🤙🏾', '🤙🏽', '🤙🏼', '🤙🏻'], }, + { + name: 'rightwards_hand', + code: '🫱', + types: ['🫱🏿', '🫱🏾', '🫱🏽', '🫱🏼', '🫱🏻'], + }, + { + name: 'leftwards_hand', + code: '🫲', + types: ['🫲🏿', '🫲🏾', '🫲🏽', '🫲🏼', '🫲🏻'], + }, { name: 'point_left', code: '👈', @@ -791,6 +864,16 @@ const emojis: PickerEmojis = [ code: '🤜', types: ['🤜🏿', '🤜🏾', '🤜🏽', '🤜🏼', '🤜🏻'], }, + { + name: 'leftwards_pushing_hand', + code: '🫷', + types: ['🫷🏿', '🫷🏾', '🫷🏽', '🫷🏼', '🫷🏻'], + }, + { + name: 'rightwards_pushing_hand', + code: '🫸', + types: ['🫸🏿', '🫸🏾', '🫸🏽', '🫸🏼', '🫸🏻'], + }, { name: 'clap', code: '👏', @@ -801,6 +884,11 @@ const emojis: PickerEmojis = [ code: '🙌', types: ['🙌🏿', '🙌🏾', '🙌🏽', '🙌🏼', '🙌🏻'], }, + { + name: 'heart_hands', + code: '🫶', + types: ['🫶🏿', '🫶🏾', '🫶🏽', '🫶🏼', '🫶🏻'], + }, { name: 'open_hands', code: '👐', @@ -821,6 +909,11 @@ const emojis: PickerEmojis = [ code: '🙏', types: ['🙏🏿', '🙏🏾', '🙏🏽', '🙏🏼', '🙏🏻'], }, + { + name: 'index_pointing_at_the_viewer', + code: '🫵', + types: ['🫵🏿', '🫵🏾', '🫵🏽', '🫵🏼', '🫵🏻'], + }, { name: 'writing_hand', code: '✍️', @@ -910,6 +1003,10 @@ const emojis: PickerEmojis = [ name: 'lips', code: '👄', }, + { + name: 'biting_lip', + code: '🫦', + }, { name: 'baby', code: '👶', @@ -1510,6 +1607,11 @@ const emojis: PickerEmojis = [ code: '🤴', types: ['🤴🏿', '🤴🏾', '🤴🏽', '🤴🏼', '🤴🏻'], }, + { + name: 'person_with_crown', + code: '🫅', + types: ['🫅🏿', '🫅🏾', '🫅🏽', '🫅🏼', '🫅🏻'], + }, { name: 'princess', code: '👸', @@ -1575,6 +1677,16 @@ const emojis: PickerEmojis = [ code: '🤰', types: ['🤰🏿', '🤰🏾', '🤰🏽', '🤰🏼', '🤰🏻'], }, + { + name: 'pregnant_person', + code: '🫄', + types: ['🫄🏿', '🫄🏾', '🫄🏽', '🫄🏼', '🫄🏻'], + }, + { + name: 'pregnant_man', + code: '🫃', + types: ['🫃🏿', '🫃🏾', '🫃🏽', '🫃🏼', '🫃🏻'], + }, { name: 'breast_feeding', code: '🤱', @@ -1720,6 +1832,10 @@ const emojis: PickerEmojis = [ code: '🧝‍♀️', types: ['🧝🏿‍♀️', '🧝🏾‍♀️', '🧝🏽‍♀️', '🧝🏼‍♀️', '🧝🏻‍♀️'], }, + { + name: 'troll', + code: '🧌', + }, { name: 'genie', code: '🧞', @@ -2448,6 +2564,30 @@ const emojis: PickerEmojis = [ name: 'unicorn', code: '🦄', }, + { + name: 'moose', + code: '🫎', + }, + { + name: 'donkey', + code: '🫏', + }, + { + name: 'wing', + code: '🪽', + }, + { + name: 'black_bird', + code: '🐦‍⬛', + }, + { + name: 'goose', + code: '🪿', + }, + { + name: 'jellyfish', + code: '🪼', + }, { name: 'zebra', code: '🦓', @@ -2764,6 +2904,10 @@ const emojis: PickerEmojis = [ name: 'shell', code: '🐚', }, + { + name: 'coral', + code: '🪸', + }, { name: 'snail', code: '🐌', @@ -2852,6 +2996,14 @@ const emojis: PickerEmojis = [ name: 'wilted_flower', code: '🥀', }, + { + name: 'hyacinth', + code: '🪻', + }, + { + name: 'lotus', + code: '🪷', + }, { name: 'hibiscus', code: '🌺', @@ -2920,6 +3072,14 @@ const emojis: PickerEmojis = [ name: 'leaves', code: '🍃', }, + { + name: 'nest_with_eggs', + code: '🪺', + }, + { + name: 'empty_nest', + code: '🪹', + }, { header: true, icon: FoodAndDrink, @@ -3057,6 +3217,10 @@ const emojis: PickerEmojis = [ name: 'peanuts', code: '🥜', }, + { + name: 'beans', + code: '🫘', + }, { name: 'chestnut', code: '🌰', @@ -3197,6 +3361,10 @@ const emojis: PickerEmojis = [ name: 'canned_food', code: '🥫', }, + { + name: 'jar', + code: '🫙', + }, { name: 'bento', code: '🍱', @@ -3229,6 +3397,14 @@ const emojis: PickerEmojis = [ name: 'sweet_potato', code: '🍠', }, + { + name: 'ginger', + code: '🫚', + }, + { + name: 'pea_pod', + code: '🫛', + }, { name: 'oden', code: '🍢', @@ -3349,6 +3525,10 @@ const emojis: PickerEmojis = [ name: 'milk_glass', code: '🥛', }, + { + name: 'pouring_liquid', + code: '🫗', + }, { name: 'coffee', code: '☕', @@ -3842,6 +4022,10 @@ const emojis: PickerEmojis = [ name: 'motorized_wheelchair', code: '🦼', }, + { + name: 'crutch', + code: '🩼', + }, { name: 'auto_rickshaw', code: '🛺', @@ -3862,6 +4046,10 @@ const emojis: PickerEmojis = [ name: 'roller_skate', code: '🛼', }, + { + name: 'wheel', + code: '🛞', + }, { name: 'busstop', code: '🚏', @@ -3934,6 +4122,10 @@ const emojis: PickerEmojis = [ name: 'ship', code: '🚢', }, + { + name: 'ring_buoy', + code: '🛟', + }, { name: 'airplane', code: '✈️', @@ -4359,6 +4551,10 @@ const emojis: PickerEmojis = [ name: 'dolls', code: '🎎', }, + { + name: 'folding_hand_fan', + code: '🪭', + }, { name: 'flags', code: '🎏', @@ -4367,6 +4563,10 @@ const emojis: PickerEmojis = [ name: 'wind_chime', code: '🎐', }, + { + name: 'mirror_ball', + code: '🪩', + }, { name: 'rice_scene', code: '🎑', @@ -4539,6 +4739,10 @@ const emojis: PickerEmojis = [ name: 'kite', code: '🪁', }, + { + name: 'playground_slide', + code: '🛝', + }, { name: '8ball', code: '🎱', @@ -4555,6 +4759,10 @@ const emojis: PickerEmojis = [ name: 'nazar_amulet', code: '🧿', }, + { + name: 'hamsa', + code: '🪬', + }, { name: 'video_game', code: '🎮', @@ -4920,6 +5128,10 @@ const emojis: PickerEmojis = [ name: 'musical_keyboard', code: '🎹', }, + { + name: 'maracas', + code: '🪇', + }, { name: 'trumpet', code: '🎺', @@ -4928,6 +5140,10 @@ const emojis: PickerEmojis = [ name: 'violin', code: '🎻', }, + { + name: 'flute', + code: '🪈', + }, { name: 'banjo', code: '🪕', @@ -4968,6 +5184,10 @@ const emojis: PickerEmojis = [ name: 'battery', code: '🔋', }, + { + name: 'low_battery', + code: '🪫', + }, { name: 'electric_plug', code: '🔌', @@ -5180,6 +5400,10 @@ const emojis: PickerEmojis = [ name: 'credit_card', code: '💳', }, + { + name: 'identification_card', + code: '🪪', + }, { name: 'receipt', code: '🧾', @@ -5508,6 +5732,10 @@ const emojis: PickerEmojis = [ name: 'telescope', code: '🔭', }, + { + name: 'x_ray', + code: '🩻', + }, { name: 'satellite', code: '📡', @@ -5584,6 +5812,10 @@ const emojis: PickerEmojis = [ name: 'razor', code: '🪒', }, + { + name: 'hair_pick', + code: '🪮', + }, { name: 'lotion_bottle', code: '🧴', @@ -5709,6 +5941,10 @@ const emojis: PickerEmojis = [ name: 'left_luggage', code: '🛅', }, + { + name: 'wireless', + code: '🛜', + }, { name: 'warning', code: '⚠️', @@ -5865,6 +6101,10 @@ const emojis: PickerEmojis = [ name: 'wheel_of_dharma', code: '☸️', }, + { + name: 'khanda', + code: '🪯', + }, { name: 'yin_yang', code: '☯️', @@ -6069,6 +6309,10 @@ const emojis: PickerEmojis = [ name: 'heavy_division_sign', code: '➗', }, + { + name: 'heavy_equals_sign', + code: '🟰', + }, { name: 'infinity', code: '♾️', diff --git a/assets/emojis/en.ts b/assets/emojis/en.ts index 28051e5ecd99..adac235f56ce 100644 --- a/assets/emojis/en.ts +++ b/assets/emojis/en.ts @@ -92,9 +92,21 @@ const enEmojis: EmojisList = { '🤭': { keywords: ['quiet', 'whoops'], }, + '🫡': { + keywords: ['face', 'salute', 'respect', 'military', 'honor'], + }, + '🫣': { + keywords: ['face', 'peek', 'eye', 'curious', 'shy'], + }, + '🫢': { + keywords: ['face', 'open eyes', 'hand over mouth', 'surprised', 'shock'], + }, '🤫': { keywords: ['silence', 'quiet'], }, + '🫠': { + keywords: ['face', 'disappear', 'dissolve', 'liquid', 'melt', 'melting face'], + }, '🤔': { keywords: ['face'], }, @@ -104,12 +116,21 @@ const enEmojis: EmojisList = { '🤨': { keywords: ['suspicious'], }, + '🫥': { + keywords: ['face', 'invisible', 'hidden', 'dotted line', 'disappear'], + }, '😐': { keywords: ['meh', 'deadpan', 'face', 'neutral'], }, + '🫤': { + keywords: ['face', 'diagonal mouth', 'meh', 'neutral', 'uncertain'], + }, '😑': { keywords: ['face', 'inexpressive', 'unexpressive'], }, + '🫨': { + keywords: ['shaking', 'face', 'shock', 'vibration', 'tremble', 'emotion'], + }, '😶': { keywords: ['mute', 'silence', 'face', 'mouth', 'quiet', 'silent'], }, @@ -242,6 +263,9 @@ const enEmojis: EmojisList = { '😰': { keywords: ['nervous', 'blue', 'cold', 'face', 'mouth', 'open', 'rushed', 'sweat'], }, + '🥹': { + keywords: ['face', 'tears', 'emotional', 'holding back', 'crying'], + }, '😥': { keywords: ['phew', 'sweat', 'nervous', 'disappointed', 'face', 'relieved', 'whew'], }, @@ -404,6 +428,15 @@ const enEmojis: EmojisList = { '❤️': { keywords: ['love'], }, + '🩷': { + keywords: ['pink', 'heart', 'love', 'affection', 'romance', 'valentine'], + }, + '🩵': { + keywords: ['light blue', 'heart', 'love', 'affection', 'calm', 'tranquility'], + }, + '🩶': { + keywords: ['grey', 'heart', 'love', 'affection', 'neutral', 'balance'], + }, '🧡': { keywords: [], }, @@ -443,6 +476,9 @@ const enEmojis: EmojisList = { '💦': { keywords: ['water', 'workout', 'comic', 'splashing', 'sweat'], }, + '🫧': { + keywords: ['bubbles', 'soap', 'water', 'float'], + }, '💨': { keywords: ['wind', 'blow', 'fast', 'comic', 'running'], }, @@ -494,12 +530,21 @@ const enEmojis: EmojisList = { '🤏': { keywords: [], }, + '🫳': { + keywords: ['hand', 'palm down', 'gesture'], + }, + '🫴': { + keywords: ['hand', 'palm up', 'gesture'], + }, '✌️': { keywords: ['victory', 'peace'], }, '🤞': { keywords: ['luck', 'hopeful', 'cross', 'finger', 'hand'], }, + '🫰': { + keywords: ['hand', 'finger', 'thumb', 'crossed', 'gesture'], + }, '🤟': { keywords: [], }, @@ -509,6 +554,12 @@ const enEmojis: EmojisList = { '🤙': { keywords: ['call', 'hand', 'shaka'], }, + '🫱': { + keywords: ['hand', 'right', 'pointing', 'gesture'], + }, + '🫲': { + keywords: ['hand', 'left', 'pointing', 'gesture'], + }, '👈': { keywords: ['backhand', 'body', 'finger', 'hand', 'index', 'point'], }, @@ -545,12 +596,21 @@ const enEmojis: EmojisList = { '🤜': { keywords: ['fist', 'rightwards'], }, + '🫷': { + keywords: ['leftwards', 'pushing', 'hand', 'gesture', 'stop', 'block'], + }, + '🫸': { + keywords: ['rightwards', 'pushing', 'hand', 'gesture', 'stop', 'block'], + }, '👏': { keywords: ['praise', 'applause', 'body', 'hand'], }, '🙌': { keywords: ['hooray', 'body', 'celebration', 'gesture', 'hand', 'raised'], }, + '🫶': { + keywords: ['hand', 'heart', 'gesture', 'love'], + }, '👐': { keywords: ['body', 'hand', 'open'], }, @@ -563,6 +623,9 @@ const enEmojis: EmojisList = { '🙏': { keywords: ['please', 'hope', 'wish', 'ask', 'body', 'bow', 'folded', 'gesture', 'hand', 'thanks'], }, + '🫵': { + keywords: ['hand', 'pointing', 'viewer', 'gesture'], + }, '✍️': { keywords: [], }, @@ -623,6 +686,9 @@ const enEmojis: EmojisList = { '👄': { keywords: ['kiss', 'body', 'mouth'], }, + '🫦': { + keywords: ['biting', 'lip', 'nervous', 'flirt'], + }, '👶': { keywords: ['child', 'newborn'], }, @@ -983,6 +1049,9 @@ const enEmojis: EmojisList = { '🤴': { keywords: ['crown', 'royal'], }, + '🫅': { + keywords: ['person', 'crown', 'royalty', 'king', 'queen'], + }, '👸': { keywords: ['crown', 'royal', 'fairy tale', 'fantasy'], }, @@ -1022,6 +1091,12 @@ const enEmojis: EmojisList = { '🤰': { keywords: ['pregnant', 'woman'], }, + '🫄': { + keywords: ['pregnant', 'person', 'expecting', 'parent'], + }, + '🫃': { + keywords: ['pregnant', 'man', 'expecting', 'parent'], + }, '🤱': { keywords: ['nursing'], }, @@ -1109,6 +1184,9 @@ const enEmojis: EmojisList = { '🧝‍♀️': { keywords: [], }, + '🧌': { + keywords: ['troll', 'mythical', 'creature', 'fantasy'], + }, '🧞': { keywords: [], }, @@ -1583,6 +1661,25 @@ const enEmojis: EmojisList = { '🦄': { keywords: ['face'], }, + '🫎': { + keywords: ['moose', 'animal', 'wildlife', 'antlers', 'forest', 'nature'], + }, + '🫏': { + keywords: ['donkey', 'animal', 'mule', 'farm', 'stubborn', 'nature'], + }, + '🪽': { + keywords: ['wing', 'bird', 'fly', 'angel', 'freedom', 'flight'], + }, + '🐦‍⬛': { + keywords: ['black', 'bird', 'animal', 'crow', 'raven', 'flight'], + }, + '🪿': { + keywords: ['goose', 'animal', 'bird', 'waterfowl', 'nature', 'pond'], + }, + '🪼': { + keywords: ['jellyfish', 'animal', 'sea', 'ocean', 'tentacles', 'marine'], + }, + '🦓': { keywords: [], }, @@ -1820,6 +1917,9 @@ const enEmojis: EmojisList = { '🐚': { keywords: ['sea', 'beach', 'spiral'], }, + '🪸': { + keywords: ['coral', 'reef', 'sea', 'ocean', 'marine'], + }, '🐌': { keywords: ['slow'], }, @@ -1886,6 +1986,12 @@ const enEmojis: EmojisList = { '🥀': { keywords: ['flower', 'wilted'], }, + '🪻': { + keywords: ['hyacinth', 'flower', 'plant', 'blossom', 'garden', 'nature'], + }, + '🪷': { + keywords: ['lotus', 'flower', 'bloom', 'plant'], + }, '🌺': { keywords: ['flower', 'plant'], }, @@ -1937,6 +2043,12 @@ const enEmojis: EmojisList = { '🍃': { keywords: ['leaf', 'blow', 'flutter', 'plant', 'wind'], }, + '🪺': { + keywords: ['nest', 'eggs', 'bird', 'home'], + }, + '🪹': { + keywords: ['nest', 'empty', 'bird', 'home'], + }, '🍇': { keywords: ['fruit', 'grape', 'plant'], }, @@ -2036,6 +2148,9 @@ const enEmojis: EmojisList = { '🥜': { keywords: ['nut', 'peanut', 'vegetable'], }, + '🫘': { + keywords: ['beans', 'food', 'legume'], + }, '🌰': { keywords: ['plant'], }, @@ -2141,6 +2256,9 @@ const enEmojis: EmojisList = { '🥫': { keywords: [], }, + '🫙': { + keywords: ['jar', 'container', 'storage'], + }, '🍱': { keywords: ['box'], }, @@ -2165,6 +2283,12 @@ const enEmojis: EmojisList = { '🍠': { keywords: ['potato', 'roasted', 'sweet'], }, + '🫚': { + keywords: ['ginger', 'root', 'spice', 'food', 'cooking', 'health'], + }, + '🫛': { + keywords: ['pea', 'pod', 'vegetable', 'food', 'plant', 'garden'], + }, '🍢': { keywords: ['kebab', 'seafood', 'skewer', 'stick'], }, @@ -2255,6 +2379,9 @@ const enEmojis: EmojisList = { '🥛': { keywords: ['drink', 'glass', 'milk'], }, + '🫗': { + keywords: ['pouring', 'liquid', 'drink', 'water'], + }, '☕': { keywords: ['cafe', 'espresso', 'beverage', 'drink', 'hot', 'steaming', 'tea'], }, @@ -2621,6 +2748,9 @@ const enEmojis: EmojisList = { '🦼': { keywords: [], }, + '🩼': { + keywords: ['crutch', 'support', 'injury', 'aid'], + }, '🛺': { keywords: [], }, @@ -2636,6 +2766,9 @@ const enEmojis: EmojisList = { '🛼': { keywords: [], }, + '🛞': { + keywords: ['wheel', 'vehicle', 'transportation'], + }, '🚏': { keywords: ['bus', 'stop'], }, @@ -2690,6 +2823,9 @@ const enEmojis: EmojisList = { '🚢': { keywords: ['vehicle'], }, + '🛟': { + keywords: ['ring', 'buoy', 'lifesaver', 'safety'], + }, '✈️': { keywords: ['flight', 'vehicle'], }, @@ -3005,12 +3141,18 @@ const enEmojis: EmojisList = { '🎎': { keywords: ['activity', 'celebration', 'doll', 'entertainment', 'festival', 'japanese'], }, + '🪭': { + keywords: ['folding', 'hand', 'fan', 'cool', 'breeze', 'accessory'], + }, '🎏': { keywords: ['activity', 'carp', 'celebration', 'entertainment', 'flag', 'streamer'], }, '🎐': { keywords: ['activity', 'bell', 'celebration', 'chime', 'entertainment', 'wind'], }, + '🪩': { + keywords: ['mirror', 'ball', 'disco', 'party'], + }, '🎑': { keywords: ['activity', 'celebration', 'ceremony', 'entertainment', 'moon'], }, @@ -3140,6 +3282,9 @@ const enEmojis: EmojisList = { '🪁': { keywords: [], }, + '🛝': { + keywords: ['playground', 'slide', 'play', 'park'], + }, '🎱': { keywords: ['pool', 'billiards', '8', '8 ball', 'ball', 'billiard', 'eight', 'game'], }, @@ -3152,6 +3297,9 @@ const enEmojis: EmojisList = { '🧿': { keywords: [], }, + '🪬': { + keywords: ['hamsa', 'hand', 'protection', 'luck'], + }, '🎮': { keywords: ['play', 'controller', 'console', 'entertainment', 'game', 'video game'], }, @@ -3422,12 +3570,18 @@ const enEmojis: EmojisList = { '🎹': { keywords: ['piano', 'activity', 'entertainment', 'instrument', 'keyboard', 'music'], }, + '🪇': { + keywords: ['maracas', 'instrument', 'music', 'percussion', 'rhythm', 'shake'], + }, '🎺': { keywords: ['activity', 'entertainment', 'instrument', 'music'], }, '🎻': { keywords: ['activity', 'entertainment', 'instrument', 'music'], }, + '🪈': { + keywords: ['flute', 'instrument', 'music', 'wind', 'melody', 'play'], + }, '🪕': { keywords: [], }, @@ -3458,6 +3612,9 @@ const enEmojis: EmojisList = { '🔋': { keywords: ['power'], }, + '🪫': { + keywords: ['low', 'battery', 'power', 'charge'], + }, '🔌': { keywords: ['electric', 'electricity', 'plug'], }, @@ -3617,6 +3774,9 @@ const enEmojis: EmojisList = { '💳': { keywords: ['subscription', 'bank', 'card', 'credit', 'money'], }, + '🪪': { + keywords: ['identification', 'card', 'ID', 'document'], + }, '🧾': { keywords: [], }, @@ -3863,6 +4023,9 @@ const enEmojis: EmojisList = { '🔭': { keywords: ['tool'], }, + '🩻': { + keywords: ['x-ray', 'medical', 'scan', 'radiology'], + }, '📡': { keywords: ['signal', 'antenna', 'communication', 'dish'], }, @@ -3920,6 +4083,9 @@ const enEmojis: EmojisList = { '🪒': { keywords: [], }, + '🪮': { + keywords: ['hair', 'pick', 'comb', 'grooming', 'accessory', 'style'], + }, '🧴': { keywords: [], }, @@ -4010,6 +4176,9 @@ const enEmojis: EmojisList = { '🛅': { keywords: ['baggage', 'left luggage', 'locker', 'luggage'], }, + '🛜': { + keywords: ['wireless', 'network', 'signal', 'connection', 'internet', 'wifi'], + }, '⚠️': { keywords: ['wip'], }, @@ -4127,6 +4296,9 @@ const enEmojis: EmojisList = { '☸️': { keywords: ['buddhist', 'dharma', 'religion', 'wheel'], }, + '🪯': { + keywords: ['khanda', 'sikh', 'symbol', 'religion', 'faith', 'sikhism'], + }, '☯️': { keywords: [], }, @@ -4280,6 +4452,9 @@ const enEmojis: EmojisList = { '➗': { keywords: ['division', 'math'], }, + '🟰': { + keywords: ['equals', 'sign', 'math', 'symbol'], + }, '♾️': { keywords: [], }, diff --git a/assets/emojis/es.ts b/assets/emojis/es.ts index 0d23f887f556..67e97caf2121 100644 --- a/assets/emojis/es.ts +++ b/assets/emojis/es.ts @@ -122,10 +122,26 @@ const esEmojis: EmojisList = { name: 'cara_con_mano_sobre_boca', keywords: ['ostras', 'uy', 'vaya', 'cara con mano sobre la boca'], }, + '🫣': { + name: 'cara_espiando', + keywords: ['cara', 'espiar', 'ojo', 'curioso', 'tímido'], + }, + '🫢': { + name: 'cara_con_ojos_abiertos_y_mano_sobre_boca', + keywords: ['cara', 'ojos abiertos', 'mano sobre boca', 'sorprendido', 'choque'], + }, + '🫡': { + name: 'cara_saludando', + keywords: ['cara', 'saludo', 'respeto', 'militar', 'honor'], + }, '🤫': { name: 'calla', keywords: ['callado', 'silencio', 'cara pidiendo silencio'], }, + '🫠': { + name: 'cara_derritiéndose', + keywords: ['calor', 'cara', 'derritiéndose', 'derretido', 'derretirse', 'desaparecer', 'fundirse', 'líquido'], + }, '🤔': { name: 'cara_pensativa', keywords: ['cara', 'duda', 'pensando', 'cara pensativa'], @@ -138,14 +154,26 @@ const esEmojis: EmojisList = { name: 'cara_con_ceja_levantada', keywords: ['desconfiado', 'escéptico', 'cara con ceja alzada'], }, + '🫥': { + name: 'cara_invisible', + keywords: ['cara', 'invisible', 'oculto', 'línea discontinua', 'desaparecer'], + }, '😐': { name: 'cara_neutra', keywords: ['cara', 'inexpresivo', 'neutral'], }, + '🫤': { + name: 'cara_con_boca_diagonal', + keywords: ['cara', 'boca diagonal', 'meh', 'neutral', 'incierto'], + }, '😑': { name: 'inexpresivo', keywords: ['cara', 'inexpresión', 'inexpresiva', 'inexpresivo', 'cara sin expresión'], }, + '🫨': { + name: 'cara_temblorosa', + keywords: ['cara', 'temblorosa', 'sacudida', 'temblor'], + }, '😶': { name: 'prohibido_hablar', keywords: ['boca', 'callado', 'cara', 'silencio', 'cara sin boca'], @@ -322,6 +350,10 @@ const esEmojis: EmojisList = { name: 'sudor_frío', keywords: ['ansiedad', 'cara', 'frío', 'sudor', 'cara con ansiedad y sudor'], }, + '🥹': { + name: 'cara_con_lágrimas', + keywords: ['cara', 'lágrimas', 'emocional', 'contener', 'llorando'], + }, '😥': { name: 'decepcionado_aliviado', keywords: ['aliviado', 'cara', 'decepcionado', 'menos mal', 'cara triste pero aliviada'], @@ -538,6 +570,18 @@ const esEmojis: EmojisList = { name: 'corazón', keywords: ['corazón', 'emoción', 'rojo'], }, + '🩷': { + name: 'corazón_rosa', + keywords: ['corazón', 'rosa', 'amor', 'afecto'], + }, + '🩵': { + name: 'corazón_azul_claro', + keywords: ['corazón', 'azul', 'claro', 'amor', 'afecto'], + }, + '🩶': { + name: 'corazón_gris', + keywords: ['corazón', 'gris', 'amor', 'afecto'], + }, '🧡': { name: 'corazón_naranja', keywords: ['corazón', 'emoción', 'naranja'], @@ -590,6 +634,10 @@ const esEmojis: EmojisList = { name: 'gotas_de_sudor', keywords: ['cómic', 'emoción', 'sudor', 'gotas de sudor'], }, + '🫧': { + name: 'burbujas', + keywords: ['burbujas', 'jabón', 'agua', 'flotar'], + }, '💨': { name: 'guión', keywords: ['carrera', 'cómic', 'correr', 'humo', 'salir corriendo'], @@ -658,6 +706,14 @@ const esEmojis: EmojisList = { name: 'mano_pellizcando', keywords: ['pellizco', 'poco', 'poquito', 'mano pellizcando'], }, + '🫳': { + name: 'mano_con_palma_hacia_abajo', + keywords: ['mano', 'palma abajo', 'gesto'], + }, + '🫴': { + name: 'mano_con_palma_hacia_arriba', + keywords: ['mano', 'palma arriba', 'gesto'], + }, '✌️': { name: 'v', keywords: ['mano', 'señal de victoria', 'victoria', 'mano con señal de victoria'], @@ -666,6 +722,10 @@ const esEmojis: EmojisList = { name: 'dedos_cruzados', keywords: ['cruzar', 'dedos', 'mano', 'suerte', 'dedos cruzados'], }, + '🫰': { + name: 'mano_con_dedos_cruzados', + keywords: ['mano', 'dedo', 'pulgar', 'cruzado', 'gesto'], + }, '🤟': { name: 'te_amo_en_lenguaje_de_señas', keywords: ['mano', 'quiero', 'gesto de te quiero'], @@ -678,6 +738,14 @@ const esEmojis: EmojisList = { name: 'mano_llámame', keywords: ['llamar', 'mano', 'meñique', 'pulgar', 'mano haciendo el gesto de llamar'], }, + '🫱': { + name: 'mano_derecha', + keywords: ['mano', 'derecha', 'apuntar', 'gesto'], + }, + '🫲': { + name: 'mano_izquierda', + keywords: ['mano', 'izquierda', 'apuntar', 'gesto'], + }, '👈': { name: 'apuntando_hacia_la_izquierda', keywords: ['dedo', 'índice', 'izquierda', 'mano', 'dorso de mano con índice a la izquierda'], @@ -726,6 +794,14 @@ const esEmojis: EmojisList = { name: 'puño_hacia_la_derecha', keywords: ['derecha', 'puño', 'puño hacia la derecha'], }, + '🫷': { + name: 'mano_empujando_hacia_la_izquierda', + keywords: ['mano', 'empujando', 'izquierda', 'gesto'], + }, + '🫸': { + name: 'mano_empujando_hacia_la_derecha', + keywords: ['mano', 'empujando', 'derecha', 'gesto'], + }, '👏': { name: 'aplauso', keywords: ['aplaudir', 'manos', 'palmas', 'señal', 'manos aplaudiendo'], @@ -734,6 +810,10 @@ const esEmojis: EmojisList = { name: 'manos_levantadas', keywords: ['celebración', 'gesto', 'hurra', 'mano', 'manos levantadas celebrando'], }, + '🫶': { + name: 'manos_haciendo_corazón', + keywords: ['mano', 'corazón', 'gesto', 'amor'], + }, '👐': { name: 'manos_abiertas', keywords: ['abiertas', 'manos'], @@ -750,6 +830,10 @@ const esEmojis: EmojisList = { name: 'rezo', keywords: ['gracias', 'mano', 'oración', 'orar', 'por favor', 'rezar', 'manos en oración'], }, + '🫵': { + name: 'mano_apuntando', + keywords: ['mano', 'apuntar', 'espectador', 'gesto'], + }, '✍️': { name: 'mano_escribiendo', keywords: ['escribir', 'lápiz', 'mano', 'mano escribiendo'], @@ -830,6 +914,10 @@ const esEmojis: EmojisList = { name: 'labios', keywords: ['labios', 'boca'], }, + '🫦': { + name: 'labios_mordiendo', + keywords: ['mordiendo', 'labio', 'nervioso', 'coqueteo'], + }, '👶': { name: 'bebé', keywords: ['joven', 'niño', 'bebé'], @@ -1290,6 +1378,7 @@ const esEmojis: EmojisList = { name: 'guardia_mujer', keywords: ['guardia', 'mujer', 'vigilante'], }, + '🥷': { name: 'ninja', keywords: ['furtivo', 'guerrero', 'luchador', 'oculto', 'sigilo', 'ninja'], @@ -1310,6 +1399,10 @@ const esEmojis: EmojisList = { name: 'príncipe', keywords: ['corona', 'príncipe'], }, + '🫅': { + name: 'persona_con_corona', + keywords: ['persona', 'corona', 'realeza', 'rey', 'reina'], + }, '👸': { name: 'princesa', keywords: ['cuento', 'fantasía', 'hadas', 'princesa'], @@ -1362,6 +1455,14 @@ const esEmojis: EmojisList = { name: 'embarazada', keywords: ['embarazada', 'mujer'], }, + '🫄': { + name: 'persona_embarazada', + keywords: ['embarazado', 'persona', 'esperando', 'padre'], + }, + '🫃': { + name: 'hombre_embarazado', + keywords: ['embarazado', 'hombre', 'esperando', 'padre'], + }, '🤱': { name: 'amamantar', keywords: ['amamantar', 'bebé', 'dar pecho', 'pecho', 'lactancia materna'], @@ -1478,6 +1579,10 @@ const esEmojis: EmojisList = { name: 'elfa', keywords: ['mágico', 'mujer', 'elfa'], }, + '🧌': { + name: 'trol', + keywords: ['trol', 'mítico', 'criatura', 'fantasía'], + }, '🧞': { name: 'genio', keywords: ['lámpara', 'genio'], @@ -2110,6 +2215,30 @@ const esEmojis: EmojisList = { name: 'cara_de_unicornio', keywords: ['cara', 'unicornio'], }, + '🫎': { + name: 'alce', + keywords: ['alce', 'animal', 'cuernos', 'naturaleza'], + }, + '🫏': { + name: 'burro', + keywords: ['burro', 'animal', 'granja', 'naturaleza'], + }, + '🪽': { + name: 'ala', + keywords: ['ala', 'volar', 'pájaro', 'ángel'], + }, + '🐦‍⬛': { + name: 'pájaro_negro', + keywords: ['pájaro', 'negro', 'animal', 'naturaleza'], + }, + '🪿': { + name: 'ganso', + keywords: ['ganso', 'animal', 'ave', 'naturaleza'], + }, + '🪼': { + name: 'medusa', + keywords: ['medusa', 'animal', 'mar', 'naturaleza'], + }, '🦓': { name: 'cara_zebra', keywords: ['raya', 'cebra'], @@ -2426,6 +2555,10 @@ const esEmojis: EmojisList = { name: 'caracola', keywords: ['concha', 'mar', 'concha de mar'], }, + '🪸': { + name: 'coral', + keywords: ['coral', 'arrecife', 'mar', 'océano', 'marino'], + }, '🐌': { name: 'caracol', keywords: ['caracola', 'molusco', 'caracol'], @@ -2514,6 +2647,14 @@ const esEmojis: EmojisList = { name: 'flor_marchita', keywords: ['flor', 'marchita', 'marchitada', 'marchitarse'], }, + '🪻': { + name: 'jacinto', + keywords: ['jacinto', 'flor', 'planta', 'naturaleza'], + }, + '🪷': { + name: 'flor_de_loto', + keywords: ['loto', 'flor', 'florecer', 'planta'], + }, '🌺': { name: 'hibisco', keywords: ['flor', 'hibisco', 'flor de hibisco'], @@ -2582,6 +2723,14 @@ const esEmojis: EmojisList = { name: 'hojas', keywords: ['hoja', 'revolotear', 'soplar', 'viento', 'hojas revoloteando al viento'], }, + '🪺': { + name: 'nido_con_huevos', + keywords: ['nido', 'huevos', 'pájaro', 'hogar'], + }, + '🪹': { + name: 'nido_vacío', + keywords: ['nido', 'vacío', 'pájaro', 'hogar'], + }, '🍇': { name: 'uvas', keywords: ['agracejo', 'fruta', 'racimo', 'uva', 'uvas'], @@ -2714,6 +2863,10 @@ const esEmojis: EmojisList = { name: 'cacahuetes', keywords: ['cacahuete', 'comida', 'fruto seco', 'verdura', 'cacahuetes'], }, + '🫘': { + name: 'frijoles', + keywords: ['frijoles', 'comida', 'legumbre'], + }, '🌰': { name: 'castaña', keywords: ['castaño', 'fruto seco', 'castaña'], @@ -2854,6 +3007,10 @@ const esEmojis: EmojisList = { name: 'comida_enlatada', keywords: ['conserva', 'lata', 'comida enlatada'], }, + '🫙': { + name: 'jarra', + keywords: ['jarra', 'contenedor', 'almacenamiento'], + }, '🍱': { name: 'bento', keywords: ['bento', 'caja', 'comida', 'restaurante', 'caja de bento'], @@ -2886,6 +3043,14 @@ const esEmojis: EmojisList = { name: 'batata', keywords: ['asada', 'papa asada', 'patata', 'restaurante'], }, + '🫚': { + name: 'jengibre', + keywords: ['jengibre', 'especia', 'planta', 'cocina'], + }, + '🫛': { + name: 'vaina_de_guisante', + keywords: ['vaina', 'guisante', 'vegetal', 'planta'], + }, '🍢': { name: 'oden', keywords: ['japonés', 'marisco', 'oden', 'pincho', 'brocheta'], @@ -3006,6 +3171,10 @@ const esEmojis: EmojisList = { name: 'vaso_de_leche', keywords: ['bebida', 'leche', 'vaso', 'vaso de leche'], }, + '🫗': { + name: 'vertiendo_líquido', + keywords: ['vertiendo', 'líquido', 'bebida', 'agua'], + }, '☕': { name: 'café', keywords: ['bebida', 'café', 'caliente', 'té'], @@ -3494,6 +3663,10 @@ const esEmojis: EmojisList = { name: 'silla_de_ruedas_eléctrica', keywords: ['accesibilidad', 'silla de ruedas eléctrica'], }, + '🩼': { + name: 'muleta', + keywords: ['muleta', 'soporte', 'lesión', 'ayuda'], + }, '🛺': { name: 'mototaxi', keywords: ['rickshaw', 'tuk tuk', 'mototaxi'], @@ -3514,6 +3687,10 @@ const esEmojis: EmojisList = { name: 'patines', keywords: ['patín', 'patín de 4 ruedas', 'patín de cuatro ruedas', 'patines'], }, + '🛞': { + name: 'rueda', + keywords: ['rueda', 'vehículo', 'transporte'], + }, '🚏': { name: 'parada_de_autobús', keywords: ['autobús', 'parada', 'parada de autobús'], @@ -3586,6 +3763,10 @@ const esEmojis: EmojisList = { name: 'barco', keywords: ['vehículo', 'barco'], }, + '🛟': { + name: 'aro_salvavidas', + keywords: ['aro', 'salvavidas', 'seguridad'], + }, '✈️': { name: 'avión', keywords: ['aeroplano', 'avión'], @@ -4006,6 +4187,10 @@ const esEmojis: EmojisList = { name: 'muñecas', keywords: ['celebración', 'festival', 'hinamatsuri', 'muñecas', 'muñecas japonesas'], }, + '🪭': { + name: 'abanico_plegable', + keywords: ['abanico', 'plegable', 'viento', 'accesorio'], + }, '🎏': { name: 'banderas', keywords: ['banderín', 'carpa', 'celebración', 'koinobori', 'banderín de carpas'], @@ -4014,6 +4199,10 @@ const esEmojis: EmojisList = { name: 'campanilla_de_viento', keywords: ['campanilla', 'furin', 'viento', 'campanilla de viento'], }, + '🪩': { + name: 'bola_de_disco', + keywords: ['bola', 'espejo', 'disco', 'fiesta'], + }, '🎑': { name: 'espiga_de_arroz', keywords: ['celebración', 'contemplación', 'luna', 'tsukimi', 'ceremonia de contemplación de la luna'], @@ -4186,6 +4375,10 @@ const esEmojis: EmojisList = { name: 'cometa', keywords: ['juguete', 'planear', 'viento', 'volar', 'cometa'], }, + '🛝': { + name: 'resbaladilla', + keywords: ['parque', 'resbaladilla', 'jugar', 'parque'], + }, '🎱': { name: 'bola_ocho', keywords: ['8', 'billar', 'bola ocho', 'juego', 'bola negra de billar'], @@ -4202,6 +4395,10 @@ const esEmojis: EmojisList = { name: 'ojo_turco', keywords: ['amuleto', 'mal de ojo', 'nazar', 'talismán', 'ojo turco'], }, + '🪬': { + name: 'hamsa', + keywords: ['hamsa', 'mano', 'protección', 'suerte'], + }, '🎮': { name: 'videojuego', keywords: ['juego', 'mando', 'videojuego', 'mando de videoconsola'], @@ -4562,6 +4759,10 @@ const esEmojis: EmojisList = { name: 'teclado_musical', keywords: ['instrumento', 'instrumento musical', 'música', 'teclado', 'piano', 'teclado musical'], }, + '🪇': { + name: 'maracas', + keywords: ['maracas', 'música', 'instrumento', 'ritmo'], + }, '🎺': { name: 'trompeta', keywords: ['instrumento', 'instrumento musical', 'música', 'trompeta'], @@ -4570,6 +4771,10 @@ const esEmojis: EmojisList = { name: 'violín', keywords: ['instrumento', 'instrumento musical', 'música', 'violín'], }, + '🪈': { + name: 'flauta', + keywords: ['flauta', 'música', 'instrumento', 'viento'], + }, '🪕': { name: 'banjo', keywords: ['banyo', 'cuerda', 'instrumento', 'música', 'banjo'], @@ -4610,6 +4815,10 @@ const esEmojis: EmojisList = { name: 'batería', keywords: ['batería', 'pila'], }, + '🪫': { + name: 'batería_baja', + keywords: ['bajo', 'batería', 'poder', 'carga'], + }, '🔌': { name: 'enchufe_eléctrico', keywords: ['corriente', 'electricidad', 'eléctrico', 'enchufe'], @@ -4822,6 +5031,10 @@ const esEmojis: EmojisList = { name: 'tarjeta_de_crédito', keywords: ['crédito', 'tarjeta', 'tarjeta de crédito'], }, + '🪪': { + name: 'tarjeta_de_identificación', + keywords: ['identificación', 'tarjeta', 'ID', 'documento'], + }, '🧾': { name: 'recibo', keywords: ['contabilidad', 'prueba', 'teneduría de libros', 'testimonio', 'recibo'], @@ -5150,6 +5363,10 @@ const esEmojis: EmojisList = { name: 'telescopio', keywords: ['astronomía', 'instrumento', 'telescopio'], }, + '🩻': { + name: 'rayos_x', + keywords: ['rayos x', 'médico', 'escáner', 'radiología'], + }, '📡': { name: 'antena_de_satélite', keywords: ['antena', 'comunicación', 'satélite', 'antena de satélite'], @@ -5226,6 +5443,10 @@ const esEmojis: EmojisList = { name: 'cuchilla_de_afeitar', keywords: ['afeitado', 'afeitar', 'afilado', 'barbero', 'navaja', 'cuchilla de afeitar'], }, + '🪮': { + name: 'peine_para_cabello', + keywords: ['peine', 'cabello', 'herramienta', 'accesorio'], + }, '🧴': { name: 'bote_de_crema', keywords: ['champú', 'crema', 'hidratante', 'protector solar', 'bote de crema'], @@ -5346,6 +5567,10 @@ const esEmojis: EmojisList = { name: 'consigna', keywords: ['depósito', 'equipaje', 'servicio de equipaje en depósito', 'consigna'], }, + '🛜': { + name: 'inalámbrico', + keywords: ['inalámbrico', 'conexión', 'wifi', 'red'], + }, '⚠️': { name: 'advertencia', keywords: ['cuidado', 'señal', 'advertencia'], @@ -5502,6 +5727,10 @@ const esEmojis: EmojisList = { name: 'rueda_del_dharma', keywords: ['budismo', 'dharma', 'religión', 'rueda', 'rueda del dharma'], }, + '🪯': { + name: 'khanda', + keywords: ['khanda', 'símbolo', 'sijismo', 'religión'], + }, '☯️': { name: 'yin_yang', keywords: ['religión', 'taoísmo', 'yang', 'yin'], @@ -5706,6 +5935,10 @@ const esEmojis: EmojisList = { name: 'signo_de_división_grueso', keywords: ['÷', 'signo', 'signo de división', 'división'], }, + '🟰': { + name: 'signo_igual', + keywords: ['igual', 'signo', 'matemáticas', 'símbolo'], + }, '♾️': { name: 'infinito', keywords: ['ilimitado', 'siempre', 'universal', 'infinito'], diff --git a/docs/_includes/hub.html b/docs/_includes/hub.html index cac0eaeec382..32d81d88e981 100644 --- a/docs/_includes/hub.html +++ b/docs/_includes/hub.html @@ -4,20 +4,19 @@ {% assign activeHub = page.url | remove: activePlatform | remove: "/hubs/" | remove: "/" | remove: ".html" %} {% assign hub = platform.hubs | where: "href", activeHub | first %} -

- {{ hub.title }} -

+

{{ hub.title }}

-

- {{ hub.description }} -

+

{{ hub.description }}

-{% assign sortedSectionsAndArticles = hub.sections | concat: hub.articles | sort: 'title' %} +{% if hub.articles %} + {% assign sortedSectionsAndArticles = hub.sections | concat: hub.articles | sort: 'title' %} +{% else %} + {% assign sortedSectionsAndArticles = hub.sections | sort: 'title' %} +{% endif%}
{% for item in sortedSectionsAndArticles %} - {% if item.articles %} {% include section-card.html platform=activePlatform hub=hub.href section=item.href title=item.title %} {% else %} diff --git a/docs/_includes/lhn-template.html b/docs/_includes/lhn-template.html index d8298aa22aa7..294094214c8e 100644 --- a/docs/_includes/lhn-template.html +++ b/docs/_includes/lhn-template.html @@ -33,7 +33,11 @@ {{ hub.title }}
    - {% assign sortedSectionsAndArticles = hub.sections | concat: hub.articles | sort: 'title' %} + {% if hub.articles %} + {% assign sortedSectionsAndArticles = hub.sections | concat: hub.articles | sort: 'title' %} + {% else %} + {% assign sortedSectionsAndArticles = hub.sections | sort: 'title' %} + {% endif%} {% for item in sortedSectionsAndArticles %} {% if item.articles %}
  • diff --git a/docs/_includes/section.html b/docs/_includes/section.html index b6def157e954..cd48a40585be 100644 --- a/docs/_includes/section.html +++ b/docs/_includes/section.html @@ -15,10 +15,12 @@

    - {% assign sortedArticles = section.articles | sort: 'order', 'last' | default: 999 %} - {% for article in sortedArticles %} - {% assign article_href = section.href | append: '/' | append: article.href %} - {% include article-card.html hub=hub.href href=article_href title=article.title platform=activePlatform %} - {% endfor %} + {% if section.articles %} + {% assign sortedArticles = section.articles | sort: 'order', 'last' | default: 999 %} + {% for article in sortedArticles %} + {% assign article_href = section.href | append: '/' | append: article.href %} + {% include article-card.html hub=hub.href href=article_href title=article.title platform=activePlatform %} + {% endfor %} + {% endif %}
    diff --git a/docs/articles/expensify-classic/expenses/Merge-expenses.md b/docs/articles/expensify-classic/expenses/Merge-expenses.md index 8b1f573a64b4..e1430ee67543 100644 --- a/docs/articles/expensify-classic/expenses/Merge-expenses.md +++ b/docs/articles/expensify-classic/expenses/Merge-expenses.md @@ -38,20 +38,46 @@ If the expenses exist on two different reports, you will be asked which report y # FAQs -**Why can’t I merge expenses that are on my submitted report?** -You cannot merge expenses that are on reports that have already been submitted. +**Helpful terminology** -**Can I merge expenses that are under different accounts?** -No, you cannot merge expenses across two separate accounts. +- SmartScanned: Any receipt where the data is automatically entered by Expensify. Expenses are SmartScanned by default unless a user stops the SmartScan and enters the details manually. +- Credit card expense: Any transaction imported from a personal card, company card feed, or CSV. +- “Cash” expense: Any expense that wasn't imported from a personal card, company card feed, or CSV. -**Can you merge expenses with different currencies?** -Yes, you can merge expenses with different currencies. The conversion amount will be based on the daily exchange rate for the date of the transaction, as long as the converted rates are within +/- 5%. If the currencies are the same, then the amounts must be an exact match to merge. +**How can the icons and receipt images help me diagnose my issue?** + +Look carefully at your expenses. Each expense has an icon that denotes where the expense came from: +- Cash (bill & coins) icon: Added manually or by SmartScanning an expense +- Credit Card icon: Imported from a connected personal credit card +- Spreadsheet icon: Imported from a personal CSV import +- Locked Credit Card icon: Imported from a company card feed or CSV upload + +Ideally, your credit card expenses will all also have a SmartScanned receipt attached. If you are in the US and your admin has allowed eReceipts for low-value expenses, your expense may include the locked credit card icon and a QR code for the receipt image. + +![Image of different expenses]({{site.url}}/assets/images/Expenses.png){:width="100%"} + +If you see any other combination of icon and image, there is likely a duplicate expense and you will need to manually merge the expenses using the steps above. **Can Expensify automatically merge a cash expense with a credit card expense?** -Yes, Expensify merges a cash expense with a credit card expense if the receipt is SmartScanned or forwarded to receipts@expensify.com. However, these expenses will not merge if: -- The card expense added to your Expensify account is older than the receipt you’re trying to merge it with -- The receipt is dated older than 7 days of the card expense date -- Either expense date (the date the Expense was incurred, not the date it was added into Expensify) is older than 90 days -- The transaction was imported with the Expensify API -However, if a receipt does not automatically merge with the card entry, you can complete this process manually. +Yes, when a card expense is imported that matches the date and amount for a SmartScanned expense, Expensify automatically merges the new expense into the existing SmartScanned expense, and the expense will now show a credit card icon. The same is true if a receipt is SmartScanned and the transaction has already been imported—it will merge as soon as the SmartScan is complete. + +When expenses merge automatically, Expensify uses the SmartScanned merchant name over the merchant data from the bank statement. If the SmartScan is stopped, Expensify can no longer guarantee that the data entry is accurate, so the expenses will not merge. + +{% include info.html %} +Expenses created via the Expensify [Expense Importer API](https://integrations.expensify.com/Integration-Server/doc/#expense-creator) will not automatically merge with card feed transactions. +{% include end-info.html %} + +**Why didn’t my expenses merge automatically?** + +Here are some possible reasons for receipt merge failures: +- The cash receipt was not SmartScanned (manual override by the user) +- The card expense has a different date than the cash expense +- The expenses have different amounts (same currency) +- The expense amounts are outside the FX 5% threshold (different currencies) +- The expense date is older than 90 days (cash or card) +- It’s a duplicate - the same receipt was added twice (and the other one merged) +- The cash receipt was submitted as a reimbursable expense, and reimbursed/exported before the credit card transaction was imported +- The credit card transaction and the receipt are not in the same Expensify user accounts + +Using the above instructions, you can manually merge any Unreported/Open cash receipt and card transaction in the same account. diff --git a/docs/articles/expensify-classic/reports/Assign-report-approvers-to-specific-employees.md b/docs/articles/expensify-classic/reports/Assign-report-approvers-to-specific-employees.md index 38279781cec9..dbeca5a49f04 100644 --- a/docs/articles/expensify-classic/reports/Assign-report-approvers-to-specific-employees.md +++ b/docs/articles/expensify-classic/reports/Assign-report-approvers-to-specific-employees.md @@ -26,7 +26,7 @@ To assign a report approver to a specific member of your workspace, - Approves To: Determines who must approve a report after this user has approved it. This creates an approval chain. When added, a note is visible in the Details column of the Workspace Members table. If blank, the user is a “final approver.” - If Report Total is Over $X then Approves To: These two fields add an extra approver if the report total exceeds the set amount. When added, a note is visible in the Details column of the Workspace Members table. -[Image coming soon] +![Image of user approval settings]({{site.url}}/assets/images/Approves_To.png){:width="100%"} ## Example diff --git a/docs/articles/expensify-classic/reports/How-Complex-Approval-Workflows-Work.md b/docs/articles/expensify-classic/reports/How-Complex-Approval-Workflows-Work.md new file mode 100644 index 000000000000..372a4783378f --- /dev/null +++ b/docs/articles/expensify-classic/reports/How-Complex-Approval-Workflows-Work.md @@ -0,0 +1,64 @@ +--- +title: How Complex Approval Workflows Work +description: Examples of how Advanced Approval Workflows apply in real life +--- +Approval workflows can get complex. Let’s look at the lifecycle of an expense report from submission to final approval. + +## 1.Submission +The approval workflow for all reports starts as soon as the report is submitted. Reports can be submitted manually or set to [submit automatically](https://help.expensify.com/articles/expensify-classic/reports/Automatically-submit-employee-reports) by Concierge. + +If you change part of your workflow after a report has been submitted, the workflow for that report will not change unless it is retracted and resubmitted. + +## 2.Category & tag approvers +If you have [special approvers for categories or tags](https://help.expensify.com/articles/expensify-classic/reports/Assign-tag-and-category-approvers) that are added to a report, the report will go to these people for approval first. They will be notified about the report via email or an in-app notification. + +## 3.Approval mode +The report will now travel through the approval workflow for the workspace: +- Submit & Close: If you use a [Submit & Close](https://help.expensify.com/articles/expensify-classic/reports/Create-a-report-approval-workflow) workflow, the report will now close and notify the set person. +- Submit & Approve: If you use a [Submit & Approve](https://help.expensify.com/articles/expensify-classic/reports/Create-a-report-approval-workflow) workflow, the report will now go to the set person for their approval. +- Advanced Approval: If you use an [Advanced Approval](https://help.expensify.com/articles/expensify-classic/reports/Create-a-report-approval-workflow) workflow, the report will now go to the person in the submitter’s “Submits to” column of the Workspace Members table. Once that person approves the report, + a. The report then goes to the person in the approver’s Approves To column. + b. If the approver has an [approval value limit](https://help.expensify.com/articles/expensify-classic/reports/Require-review-for-over-limit-expenses) (i.e. they have approval restrictions based on the total amount of the report), the report will go to the set person. + c. The report continues through the approval workflow until it reaches someone who does not have anyone in their Approves To column. This person is the final approver. + +Once the report receives final approval, it may be exported to a [connected accounting software](https://help.expensify.com/expensify-classic/hubs/connections/) and/or reimbursed. + +## 4.Concierge approval +If you’ve chosen to [require manual approval for expenses that exceed a set limit](https://help.expensify.com/articles/expensify-classic/reports/Require-review-for-over-limit-expenses), any report that doesn’t contain a single expense over this amount will be approved by Concierge. + +## Workflow examples +Here are some scenarios to demonstrate the different approval workflows. + +### Submit & Close +Two business partners named Terry and Dana run a small business together. They don’t need approvals for their expenses, so they use the Submit & Close workflow and have Terry set as the person to submit to. Once submitted, their reports are closed. + +*Outcome: All submitted reports go to the main approver and are then closed automatically. No action is required for approval.* + +### Submit & Approve with category approvers +Pat does the accounting for a small engineering firm. Everyone submits their reports to Pat for approval. However, all plant and equipment purchases must be seen by Dale. They created a category called “3005 Plant and Equipment” and assigned Dale as the category approver. This way, when a report is coded with this category, it will go to Dale once it is submitted. Then Pat will receive the report for final approval, reimbursement, and to export it to their accounting software connection. + +*Outcome: All submitted reports go to the main approver unless they contain expenses coded with a category that requires review by another approver first.* + +### Submit & Approve with Scheduled Submit and Concierge approval +Sandra’s company has a manual approval threshold of $100 and has Scheduled Submit set to weekly. That means that as long as each expense is under $100, reports will be automatically submitted once a week. + +Her sales rep David regularly hosts client meetings, which results in a report filled with coffee, lunch, and parking expenses paid for on his company card. David has dutifully SmartScanned his receipts and coding them after each purchase. None of the individual expenses are over $100, so his report submits itself on Sunday evening. The report is instantly final approved within moments of submission, and the report history notes that Concierge both submitted and final approved the report. + +*Outcome: Report submission and approval are automated unless there are large expenses.* + +### Advanced Approval - Example 1 +Amal is a photojournalist for a major magazine, and they have been traveling for a week. The last report they submitted contains meals, accommodations, and emergency camera equipment. +1. Their report first goes to Tony, head of photography, who is the category approver for the “6050 Cameras and AV” category that was added to Amal’s report. +2. The report then goes to Jamie, who is Amal’s manager and “submits to.” +3. Jamie approves and forwards the report to her “approves to” person, which is her manager Ali. +4. Ali approves and forwards the report to his “approves to” person, which is the finance team. +5. The finance team is the final approver for the report. They check the coding, approve the report, export it to the accounting system, and reimburse Amal. + +*Outcome: Reports go through category-specific approvers first, then through the multiple levels of approval.* + +### Advanced Approval - Example 2 +Amal had another travel week, but this time to Hong Kong. Their report total includes a $1,200 flight as well as $950 for accommodations and food. + +The report goes to Jamie for approval, but Jamie has an “If Report Total is Over $2000 then Approves To” rule that requires large expenses to be approved by Lee. That means once Jamie approves the report, Lee must approve the expense next. Once Lee approves, the report goes to the finance team who completes the final approval. + +*Outcome: Reports with multiple levels of approval go through each approver whose approval limit is not great enough until it reaches the approver with the required approval limit.* diff --git a/docs/articles/new-expensify/connections/Netsuite/Configure-Netsuite.md b/docs/articles/new-expensify/connections/Netsuite/Configure-Netsuite.md new file mode 100644 index 000000000000..7ae0aa577468 --- /dev/null +++ b/docs/articles/new-expensify/connections/Netsuite/Configure-Netsuite.md @@ -0,0 +1,6 @@ +--- +title: Configure Netsuite +description: Coming soon +--- + +# Coming soon diff --git a/docs/articles/new-expensify/connections/Set-Up-NetSuite-Connection.md b/docs/articles/new-expensify/connections/Netsuite/Connect-to-NetSuite.md similarity index 99% rename from docs/articles/new-expensify/connections/Set-Up-NetSuite-Connection.md rename to docs/articles/new-expensify/connections/Netsuite/Connect-to-NetSuite.md index 5c6678e068be..7cf70cca5abc 100644 --- a/docs/articles/new-expensify/connections/Set-Up-NetSuite-Connection.md +++ b/docs/articles/new-expensify/connections/Netsuite/Connect-to-NetSuite.md @@ -1,8 +1,8 @@ --- -title: Set up NetSuite connection +title: Connect to NetSuite description: Integrate NetSuite with Expensify +order: 1 --- -
    # Connect to NetSuite diff --git a/docs/articles/new-expensify/connections/Netsuite/Netsuite-Troubleshooting.md b/docs/articles/new-expensify/connections/Netsuite/Netsuite-Troubleshooting.md new file mode 100644 index 000000000000..2ac1aaadbef4 --- /dev/null +++ b/docs/articles/new-expensify/connections/Netsuite/Netsuite-Troubleshooting.md @@ -0,0 +1,6 @@ +--- +title: Netsuite Troubleshooting +description: Coming soon +--- + +# Coming soon diff --git a/docs/articles/new-expensify/connections/Quickbooks-Online/Configure-Quickbooks-Online.md b/docs/articles/new-expensify/connections/Quickbooks-Online/Configure-Quickbooks-Online.md new file mode 100644 index 000000000000..db050e5be312 --- /dev/null +++ b/docs/articles/new-expensify/connections/Quickbooks-Online/Configure-Quickbooks-Online.md @@ -0,0 +1,6 @@ +--- +title: Configure Quickbooks Online +description: Coming soon +--- + +# Coming soon diff --git a/docs/articles/new-expensify/connections/Set-up-QuickBooks-Online-connection.md b/docs/articles/new-expensify/connections/Quickbooks-Online/Connect-to-QuickBooks-Online.md similarity index 99% rename from docs/articles/new-expensify/connections/Set-up-QuickBooks-Online-connection.md rename to docs/articles/new-expensify/connections/Quickbooks-Online/Connect-to-QuickBooks-Online.md index 79d5b17055f7..60fdbe94b33b 100644 --- a/docs/articles/new-expensify/connections/Set-up-QuickBooks-Online-connection.md +++ b/docs/articles/new-expensify/connections/Quickbooks-Online/Connect-to-QuickBooks-Online.md @@ -1,8 +1,8 @@ --- -title: Set up QuickBooks Online connection +title: Connect to QuickBooks Online description: Integrate QuickBooks Online with Expensify +order: 1 --- -
    {% include info.html %} To use the QuickBooks Online connection, you must have a QuickBooks Online account and an Expensify Collect plan. The QuickBooks Self-employed subscription is not supported. @@ -134,5 +134,3 @@ This may occur if you incorrectly enter your QuickBooks Online login information 3. Enter your Intuit login details (the login information you use for QuickBooks Online) to establish the connection. {% include faq-end.md %} - -
    diff --git a/docs/articles/new-expensify/connections/Quickbooks-Online/Quickbooks-Online-Troubleshooting.md b/docs/articles/new-expensify/connections/Quickbooks-Online/Quickbooks-Online-Troubleshooting.md new file mode 100644 index 000000000000..5256459d6f9a --- /dev/null +++ b/docs/articles/new-expensify/connections/Quickbooks-Online/Quickbooks-Online-Troubleshooting.md @@ -0,0 +1,6 @@ +--- +title: Quickbooks Online Troubleshooting +description: Coming soon +--- + +# Coming soon diff --git a/docs/articles/new-expensify/connections/Sage-Intacct/Configure-Sage-Intacct.md b/docs/articles/new-expensify/connections/Sage-Intacct/Configure-Sage-Intacct.md new file mode 100644 index 000000000000..c5e549ff74d1 --- /dev/null +++ b/docs/articles/new-expensify/connections/Sage-Intacct/Configure-Sage-Intacct.md @@ -0,0 +1,6 @@ +--- +title: Configure Sage Intacct +description: Coming soon +--- + +# Coming soon diff --git a/docs/articles/new-expensify/connections/Set-Up-Sage-Intacct-connection.md b/docs/articles/new-expensify/connections/Sage-Intacct/Connect-to-Sage-Intacct.md similarity index 99% rename from docs/articles/new-expensify/connections/Set-Up-Sage-Intacct-connection.md rename to docs/articles/new-expensify/connections/Sage-Intacct/Connect-to-Sage-Intacct.md index 1f5d9662bb4f..35a009ae8d4a 100644 --- a/docs/articles/new-expensify/connections/Set-Up-Sage-Intacct-connection.md +++ b/docs/articles/new-expensify/connections/Sage-Intacct/Connect-to-Sage-Intacct.md @@ -1,8 +1,8 @@ --- -title: Set up Sage Intacct connection +title: Connect to Sage Intacct description: Integrate Sage Intacct with Expensify +order: 1 --- -
    # Connect to Sage Intacct diff --git a/docs/articles/new-expensify/connections/Sage-Intacct/Sage-Intacct-Troubleshooting.md b/docs/articles/new-expensify/connections/Sage-Intacct/Sage-Intacct-Troubleshooting.md new file mode 100644 index 000000000000..ae8a0f16d9b9 --- /dev/null +++ b/docs/articles/new-expensify/connections/Sage-Intacct/Sage-Intacct-Troubleshooting.md @@ -0,0 +1,6 @@ +--- +title: Sage Intacct Troubleshooting +description: Coming soon +--- + +# Coming soon diff --git a/docs/articles/new-expensify/connections/Xero/Configure-Xero.md b/docs/articles/new-expensify/connections/Xero/Configure-Xero.md new file mode 100644 index 000000000000..0c65db1b4fd9 --- /dev/null +++ b/docs/articles/new-expensify/connections/Xero/Configure-Xero.md @@ -0,0 +1,6 @@ +--- +title: Configure Xero +description: Coming soon +--- + +# Coming soon diff --git a/docs/articles/new-expensify/connections/Set-up-Xero-connection.md b/docs/articles/new-expensify/connections/Xero/Connect-to-Xero.md similarity index 98% rename from docs/articles/new-expensify/connections/Set-up-Xero-connection.md rename to docs/articles/new-expensify/connections/Xero/Connect-to-Xero.md index 47917f2dffc3..eb35b1589db4 100644 --- a/docs/articles/new-expensify/connections/Set-up-Xero-connection.md +++ b/docs/articles/new-expensify/connections/Xero/Connect-to-Xero.md @@ -1,8 +1,8 @@ --- -title: Set up Xero connection +title: Connect to Xero description: Integrate Xero with Expensify +order: 1 --- -
    {% include info.html %} To use the Xero connection, you must have a Xero account and an Expensify Collect plan. @@ -104,5 +104,3 @@ The following steps help you determine the advanced settings for your connection You will no longer see the imported options from Xero. {% include faq-end.md %} - -
    diff --git a/docs/articles/new-expensify/connections/Xero/Xero-Troubleshooting.md b/docs/articles/new-expensify/connections/Xero/Xero-Troubleshooting.md new file mode 100644 index 000000000000..9c211efbaf24 --- /dev/null +++ b/docs/articles/new-expensify/connections/Xero/Xero-Troubleshooting.md @@ -0,0 +1,6 @@ +--- +title: Xero Troubleshooting +description: Coming soon +--- + +# Coming soon diff --git a/docs/new-expensify/hubs/connections/netsuite.html b/docs/new-expensify/hubs/connections/netsuite.html new file mode 100644 index 000000000000..86641ee60b7d --- /dev/null +++ b/docs/new-expensify/hubs/connections/netsuite.html @@ -0,0 +1,5 @@ +--- +layout: default +--- + +{% include section.html %} diff --git a/docs/new-expensify/hubs/connections/quickbooks-online.html b/docs/new-expensify/hubs/connections/quickbooks-online.html new file mode 100644 index 000000000000..86641ee60b7d --- /dev/null +++ b/docs/new-expensify/hubs/connections/quickbooks-online.html @@ -0,0 +1,5 @@ +--- +layout: default +--- + +{% include section.html %} diff --git a/docs/new-expensify/hubs/connections/sage-intacct.html b/docs/new-expensify/hubs/connections/sage-intacct.html new file mode 100644 index 000000000000..86641ee60b7d --- /dev/null +++ b/docs/new-expensify/hubs/connections/sage-intacct.html @@ -0,0 +1,5 @@ +--- +layout: default +--- + +{% include section.html %} diff --git a/docs/new-expensify/hubs/connections/xero.html b/docs/new-expensify/hubs/connections/xero.html new file mode 100644 index 000000000000..86641ee60b7d --- /dev/null +++ b/docs/new-expensify/hubs/connections/xero.html @@ -0,0 +1,5 @@ +--- +layout: default +--- + +{% include section.html %} diff --git a/docs/redirects.csv b/docs/redirects.csv index 897cd4e95775..4b7cc43bd072 100644 --- a/docs/redirects.csv +++ b/docs/redirects.csv @@ -275,3 +275,11 @@ https://help.expensify.com/articles/expensify-classic/integrations/HR-integratio https://help.expensify.com/articles/expensify-classic/integrations/accounting-integrations/Xero.html,https://help.expensify.com/expensify-classic/hubs/connections/xero https://help.expensify.com/articles/expensify-classic/integrations/HR-integrations/Zenefits.html,https://help.expensify.com/articles/expensify-classic/connections/Zenefits https://help.expensify.com/articles/expensify-classic/settings/Close-or-reopen-account,https://help.expensify.com/articles/expensify-classic/settings/account-settings/Close-or-reopen-account +https://help.expensify.com/articles/new-expensify/connections/Set-Up-NetSuite-Connection,https://help.expensify.com/articles/new-expensify/connections/netsuite/Connect-to-NetSuite +https://help.expensify.com/articles/new-expensify/connections/Set-Up-NetSuite-Connection.html,https://help.expensify.com/articles/new-expensify/connections/netsuite/Connect-to-NetSuite +https://help.expensify.com/articles/new-expensify/connections/Set-up-QuickBooks-Online-connection,https://help.expensify.com/articles/new-expensify/connections/quickbooks-online/Connect-to-QuickBooks-Online +https://help.expensify.com/articles/new-expensify/connections/Set-up-QuickBooks-Online-connection.html,https://help.expensify.com/articles/new-expensify/connections/quickbooks-online/Connect-to-QuickBooks-Online +https://help.expensify.com/articles/new-expensify/connections/Set-Up-Sage-Intacct-connection,https://help.expensify.com/articles/new-expensify/connections/sage-intacct/Connect-to-Sage-Intacct +https://help.expensify.com/articles/new-expensify/connections/Set-Up-Sage-Intacct-connection.html,https://help.expensify.com/articles/new-expensify/connections/sage-intacct/Connect-to-Sage-Intacct +https://help.expensify.com/articles/new-expensify/connections/Set-up-Xero-connection,https://help.expensify.com/articles/new-expensify/connections/xero/Connect-to-Xero +https://help.expensify.com/articles/new-expensify/connections/Set-up-Xero-connection.html,https://help.expensify.com/articles/new-expensify/connections/xero/Connect-to-Xero \ No newline at end of file diff --git a/ios/NewExpensify/Info.plist b/ios/NewExpensify/Info.plist index ef1647dd148a..f224dcb9db92 100644 --- a/ios/NewExpensify/Info.plist +++ b/ios/NewExpensify/Info.plist @@ -19,7 +19,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 9.0.13 + 9.0.14 CFBundleSignature ???? CFBundleURLTypes @@ -40,7 +40,7 @@ CFBundleVersion - 9.0.13.3 + 9.0.14.2 FullStory OrgId diff --git a/ios/NewExpensifyTests/Info.plist b/ios/NewExpensifyTests/Info.plist index 892b4b6304b6..520c82a45f77 100644 --- a/ios/NewExpensifyTests/Info.plist +++ b/ios/NewExpensifyTests/Info.plist @@ -15,10 +15,10 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 9.0.13 + 9.0.14 CFBundleSignature ???? CFBundleVersion - 9.0.13.3 + 9.0.14.2 diff --git a/ios/NotificationServiceExtension/Info.plist b/ios/NotificationServiceExtension/Info.plist index 7afb5537890e..77a3afc2e271 100644 --- a/ios/NotificationServiceExtension/Info.plist +++ b/ios/NotificationServiceExtension/Info.plist @@ -11,9 +11,9 @@ CFBundleName $(PRODUCT_NAME) CFBundleShortVersionString - 9.0.13 + 9.0.14 CFBundleVersion - 9.0.13.3 + 9.0.14.2 NSExtension NSExtensionPointIdentifier diff --git a/package-lock.json b/package-lock.json index 4dea9d28cd9b..9082f9183c23 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "new.expensify", - "version": "9.0.13-3", + "version": "9.0.14-2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "new.expensify", - "version": "9.0.13-3", + "version": "9.0.14-2", "hasInstallScript": true, "license": "MIT", "dependencies": { diff --git a/package.json b/package.json index 34db4f413eb0..89d2a89aeb42 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "new.expensify", - "version": "9.0.13-3", + "version": "9.0.14-2", "author": "Expensify, Inc.", "homepage": "https://new.expensify.com", "description": "New Expensify is the next generation of Expensify: a reimagination of payments based atop a foundation of chat.", diff --git a/src/CONST.ts b/src/CONST.ts index d929a01e030a..55096bb279b2 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -363,7 +363,6 @@ const CONST = { }, BETAS: { ALL: 'all', - CHRONOS_IN_CASH: 'chronosInCash', DEFAULT_ROOMS: 'defaultRooms', VIOLATIONS: 'violations', DUPE_DETECTION: 'dupeDetection', @@ -682,6 +681,9 @@ const CONST = { ACTIONABLE_TRACK_EXPENSE_WHISPER: 'ACTIONABLETRACKEXPENSEWHISPER', ADD_COMMENT: 'ADDCOMMENT', APPROVED: 'APPROVED', + CARD_MISSING_ADDRESS: 'CARDMISSINGADDRESS', + CARD_ISSUED: 'CARDISSUED', + CARD_ISSUED_VIRTUAL: 'CARDISSUEDVIRTUAL', CHANGE_FIELD: 'CHANGEFIELD', // OldDot Action CHANGE_POLICY: 'CHANGEPOLICY', // OldDot Action CHANGE_TYPE: 'CHANGETYPE', // OldDot Action @@ -5251,6 +5253,9 @@ const CONST = { DRAFTS: 'drafts', FINISHED: 'finished', }, + TYPE: { + EXPENSE: 'expense', + }, TAB: { EXPENSE: { ALL: 'type:expense status:all', diff --git a/src/ROUTES.ts b/src/ROUTES.ts index af29a7fdbbb4..0811ea02e9d6 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -33,8 +33,6 @@ const ROUTES = { // This route renders the list of reports. HOME: 'home', - ALL_SETTINGS: 'all-settings', - SEARCH_CENTRAL_PANE: { route: 'search', getRoute: ({query, isCustomQuery = false, policyIDs}: {query: SearchQueryString; isCustomQuery?: boolean; policyIDs?: string}) => @@ -47,6 +45,8 @@ const ROUTES = { SEARCH_ADVANCED_FILTERS_TYPE: 'search/filters/type', + SEARCH_ADVANCED_FILTERS_STATUS: 'search/filters/status', + SEARCH_REPORT: { route: 'search/view/:reportID', getRoute: (reportID: string) => `search/view/${reportID}` as const, @@ -56,6 +56,8 @@ const ROUTES = { // This is a utility route used to go to the user's concierge chat, or the sign-in page if the user's not authenticated CONCIERGE: 'concierge', + TRACK_EXPENSE: 'track-expense', + SUBMIT_EXPENSE: 'submit-expense', FLAG_COMMENT: { route: 'flag/:reportID/:reportActionID', getRoute: (reportID: string, reportActionID: string) => `flag/${reportID}/${reportActionID}` as const, diff --git a/src/SCREENS.ts b/src/SCREENS.ts index 74d4a628e696..4047b0a851bc 100644 --- a/src/SCREENS.ts +++ b/src/SCREENS.ts @@ -8,11 +8,12 @@ const PROTECTED_SCREENS = { HOME: 'Home', CONCIERGE: 'Concierge', ATTACHMENTS: 'Attachments', + TRACK_EXPENSE: 'TrackExpense', + SUBMIT_EXPENSE: 'SubmitExpense', } as const; const SCREENS = { ...PROTECTED_SCREENS, - ALL_SETTINGS: 'AllSettings', REPORT: 'Report', PROFILE_AVATAR: 'ProfileAvatar', WORKSPACE_AVATAR: 'WorkspaceAvatar', @@ -33,6 +34,7 @@ const SCREENS = { ADVANCED_FILTERS_RHP: 'Search_Advanced_Filters_RHP', ADVANCED_FILTERS_DATE_RHP: 'Search_Advanced_Filters_Date_RHP', ADVANCED_FILTERS_TYPE_RHP: 'Search_Advanced_Filters_Type_RHP', + ADVANCED_FILTERS_STATUS_RHP: 'Search_Advanced_Filters_Status_RHP', TRANSACTION_HOLD_REASON_RHP: 'Search_Transaction_Hold_Reason_RHP', BOTTOM_TAB: 'Search_Bottom_Tab', }, diff --git a/src/components/ButtonWithDropdownMenu/index.tsx b/src/components/ButtonWithDropdownMenu/index.tsx index 9d41f7823e6e..12802476ed0d 100644 --- a/src/components/ButtonWithDropdownMenu/index.tsx +++ b/src/components/ButtonWithDropdownMenu/index.tsx @@ -31,6 +31,8 @@ function ButtonWithDropdownMenu({ onPress, options, onOptionSelected, + onOptionsMenuShow, + onOptionsMenuHide, enterKeyEventListenerPriority = 0, wrapperStyle, }: ButtonWithDropdownMenuProps) { @@ -136,7 +138,11 @@ function ButtonWithDropdownMenu({ {(shouldAlwaysShowDropdownMenu || options.length > 1) && popoverAnchorPosition && ( setIsMenuVisible(false)} + onClose={() => { + setIsMenuVisible(false); + onOptionsMenuHide?.(); + }} + onModalShow={onOptionsMenuShow} onItemSelected={() => setIsMenuVisible(false)} anchorPosition={popoverAnchorPosition} anchorRef={caretButton} diff --git a/src/components/ButtonWithDropdownMenu/types.ts b/src/components/ButtonWithDropdownMenu/types.ts index baac60190ce5..f20729380b60 100644 --- a/src/components/ButtonWithDropdownMenu/types.ts +++ b/src/components/ButtonWithDropdownMenu/types.ts @@ -45,6 +45,12 @@ type ButtonWithDropdownMenuProps = { /** Callback to execute when a dropdown option is selected */ onOptionSelected?: (option: DropdownOption) => void; + /** Callback when the options popover is shown */ + onOptionsMenuShow?: () => void; + + /** Callback when the options popover is shown */ + onOptionsMenuHide?: () => void; + /** Call the onPress function on main button when Enter key is pressed */ pressOnEnter?: boolean; diff --git a/src/components/ConnectToNetSuiteButton/index.tsx b/src/components/ConnectToNetSuiteButton/index.tsx index bd6dabf09097..928bc01f12c1 100644 --- a/src/components/ConnectToNetSuiteButton/index.tsx +++ b/src/components/ConnectToNetSuiteButton/index.tsx @@ -56,9 +56,7 @@ function ConnectToNetSuiteButton({policyID, shouldDisconnectIntegrationBeforeCon