Skip to content

Commit

Permalink
Merge branch 'main' of github.com:Expensify/App into e2e/increase-rel…
Browse files Browse the repository at this point in the history
…iability
  • Loading branch information
hannojg committed Oct 30, 2023
2 parents c469811 + a094cbb commit 551bb87
Show file tree
Hide file tree
Showing 1,121 changed files with 10,157 additions and 8,968 deletions.
25 changes: 24 additions & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ const restrictedImportPatterns = [
];

module.exports = {
extends: ['expensify', 'plugin:storybook/recommended', 'plugin:react-hooks/recommended', 'plugin:react-native-a11y/basic', 'prettier'],
extends: ['expensify', 'plugin:storybook/recommended', 'plugin:react-hooks/recommended', 'plugin:react-native-a11y/basic', 'plugin:@dword-design/import-alias/recommended', 'prettier'],
plugins: ['react-hooks', 'react-native-a11y'],
parser: 'babel-eslint',
ignorePatterns: ['!.*', 'src/vendor', '.github/actions/**/index.js', 'desktop/dist/*.js', 'dist/*.js', 'node_modules/.bin/**', 'node_modules/.cache/**', '.git/**'],
Expand All @@ -49,8 +49,31 @@ module.exports = {
touchables: ['PressableWithoutFeedback', 'PressableWithFeedback'],
},
],
'@dword-design/import-alias/prefer-alias': [
'warn',
{
alias: {
'@assets': './assets',
'@components': './src/components',
'@hooks': './src/hooks',
// This is needed up here, if not @libs/actions would take the priority
'@userActions': './src/libs/actions',
'@libs': './src/libs',
'@navigation': './src/libs/Navigation',
'@pages': './src/pages',
'@styles': './src/styles',
// This path is provide alias for files like `ONYXKEYS` and `CONST`.
'@src': './src',
},
},
],
},
},
// This helps disable the `prefer-alias` rule to be enabled for specific directories
{
files: ['tests/**/*.js', 'tests/**/*.ts', 'tests/**/*.jsx', 'assets/**/*.js', '.storybook/**/*.js'],
rules: {'@dword-design/import-alias/prefer-alias': ['off']},
},
{
files: ['*.js', '*.jsx'],
settings: {
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ on:
pull_request:
types: [opened, synchronize]
branches-ignore: [staging, production]
paths: ['**.js', '**.ts', '**.tsx']
paths: ['**.js', '**.ts', '**.tsx', '**.json', '**.mjs', '**.cjs', 'config/.editorconfig', '.watchmanconfig', '.imgbotconfig']

jobs:
lint:
Expand Down
6 changes: 6 additions & 0 deletions .imgbotconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"ignoredFiles": [
"assets/images/empty-state_background-fade.png" // Caused an issue with colour gradients, https://github.com/Expensify/App/issues/30499
],
"aggressiveCompression": "false"
}
3 changes: 3 additions & 0 deletions .prettierrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,7 @@ module.exports = {
arrowParens: 'always',
printWidth: 190,
singleAttributePerLine: true,
importOrder: ['@assets/(.*)$', '@components/(.*)$', '@hooks/(.*)$', '@libs/(.*)$', '@navigation/(.*)$', '@pages/(.*)$', '@styles/(.*)$', '@userActions/(.*)$', '@src/(.*)$', '^[./]'],
importOrderSortSpecifiers: true,
importOrderCaseInsensitive: true,
};
8 changes: 4 additions & 4 deletions .storybook/preview.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import {PortalProvider} from '@gorhom/portal';
import React from 'react';
import Onyx from 'react-native-onyx';
import {SafeAreaProvider} from 'react-native-safe-area-context';
import {PortalProvider} from '@gorhom/portal';
import './fonts.css';
import ComposeProviders from '../src/components/ComposeProviders';
import HTMLEngineProvider from '../src/components/HTMLEngineProvider';
import OnyxProvider from '../src/components/OnyxProvider';
import {LocaleContextProvider} from '../src/components/LocaleContextProvider';
import {KeyboardStateProvider} from '../src/components/withKeyboardState';
import OnyxProvider from '../src/components/OnyxProvider';
import {EnvironmentProvider} from '../src/components/withEnvironment';
import {KeyboardStateProvider} from '../src/components/withKeyboardState';
import {WindowDimensionsProvider} from '../src/components/withWindowDimensions';
import ONYXKEYS from '../src/ONYXKEYS';
import './fonts.css';

Onyx.init({
keys: ONYXKEYS,
Expand Down
3 changes: 3 additions & 0 deletions .storybook/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ module.exports = ({config}) => {
'react-native-web': '@expensify/react-native-web',
'@react-native-community/netinfo': path.resolve(__dirname, '../__mocks__/@react-native-community/netinfo.js'),
'@react-navigation/native': path.resolve(__dirname, '../__mocks__/@react-navigation/native'),

// Module alias support for storybook files, coping from `webpack.common.js`
...custom.resolve.alias,
};

// Necessary to overwrite the values in the existing DefinePlugin hardcoded to the Config staging values
Expand Down
4 changes: 2 additions & 2 deletions android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,8 @@ android {
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
multiDexEnabled rootProject.ext.multiDexEnabled
versionCode 1001039200
versionName "1.3.92-0"
versionCode 1001039300
versionName "1.3.93-0"
}

flavorDimensions "default"
Expand Down
8 changes: 4 additions & 4 deletions assets/emojis/common.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import Smiley from '../images/emoji.svg';
import AnimalsAndNature from '../images/emojiCategoryIcons/plant.svg';
import Flags from '../images/emojiCategoryIcons/flag.svg';
import FoodAndDrink from '../images/emojiCategoryIcons/hamburger.svg';
import TravelAndPlaces from '../images/emojiCategoryIcons/plane.svg';
import Activities from '../images/emojiCategoryIcons/soccer-ball.svg';
import Objects from '../images/emojiCategoryIcons/light-bulb.svg';
import Symbols from '../images/emojiCategoryIcons/peace-sign.svg';
import Flags from '../images/emojiCategoryIcons/flag.svg';
import TravelAndPlaces from '../images/emojiCategoryIcons/plane.svg';
import AnimalsAndNature from '../images/emojiCategoryIcons/plant.svg';
import Activities from '../images/emojiCategoryIcons/soccer-ball.svg';
import FrequentlyUsed from '../images/history.svg';

const skinTones = [
Expand Down
6 changes: 6 additions & 0 deletions assets/images/bell.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions assets/images/bellSlash.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified assets/images/empty-state_background-fade.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
36 changes: 36 additions & 0 deletions babel.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,42 @@ const metro = {
['@babel/plugin-proposal-private-property-in-object', {loose: true}],
// The reanimated babel plugin needs to be last, as stated here: https://docs.swmansion.com/react-native-reanimated/docs/fundamentals/installation
'react-native-reanimated/plugin',
// Import alias for native devices
[
'module-resolver',
{
extensions: [
'.native.js',
'.native.jsx',
'.native.ts',
'.native.tsx',
'.js',
'.jsx',
'.ts',
'.tsx',
'.ios.js',
'.ios.jsx',
'.ios.ts',
'.ios.tsx',
'.android.js',
'.android.jsx',
'.android.ts',
'.android.tx',
],
alias: {
'@assets': './assets',
'@components': './src/components',
'@hooks': './src/hooks',
'@libs': './src/libs',
'@navigation': './src/libs/Navigation',
'@pages': './src/pages',
'@styles': './src/styles',
// This path is provide alias for files like `ONYXKEYS` and `CONST`.
'@src': './src',
'@userActions': './src/libs/actions',
},
},
],
],
};

Expand Down
13 changes: 13 additions & 0 deletions config/webpack/webpack.common.js
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,19 @@ const webpackConfig = ({envFile = '.env', platform = 'web'}) => ({
'react-native-web': '@expensify/react-native-web',
'react-content-loader/native': 'react-content-loader',
'lottie-react-native': 'react-native-web-lottie',

// Module alias for web & desktop
// https://webpack.js.org/configuration/resolve/#resolvealias
'@assets': path.resolve(__dirname, '../../assets'),
'@components': path.resolve(__dirname, '../../src/components/'),
'@hooks': path.resolve(__dirname, '../../src/hooks/'),
'@libs': path.resolve(__dirname, '../../src/libs/'),
'@navigation': path.resolve(__dirname, '../../src/libs/Navigation/'),
'@pages': path.resolve(__dirname, '../../src/pages/'),
'@styles': path.resolve(__dirname, '../../src/styles/'),
// This path is provide alias for files like `ONYXKEYS` and `CONST`.
'@src': path.resolve(__dirname, '../../src/'),
'@userActions': path.resolve(__dirname, '../../src/libs/actions/'),
},

// React Native libraries may have web-specific module implementations that appear with the extension `.web.js`
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,94 @@
---
title: Coming Soon
description: Coming Soon
title: Workspace Tags
---
## Resource Coming Soon!
# Overview
You can use tags to assign expenses to a specific department, project, location, cost center, and more.

Note that tags function differently depending on whether or not you connect Expensify to a direct account integration (i.e., QuickBooks Online, NetSuite, etc.). With that said, this article covers tags that work for all account setups.
# How to use Tags
Tags are a workspace-level feature. They’re generally used to code expenses to things like customers, projects, locations, or departments. at the expense level. You can have different sets of tags for different workspaces, allowing you to customize coding for cohorts of employees.

With that said, tags come in two forms: single tags and multi-level tags.

## Single Tags
Single tags refer to the simplest version of tags, allowing users to code expenses on a single level. With a single tag setup, users will pick from the list of tags you created and make a single selection on each expense.
## Multi-Level Tags
On the other hand, Multi-Level Tags refer to a more advanced tagging system that allows you to code expenses in a hierarchical or nested manner. Unlike single tags, which are standalone labels, multi-level tags enable you to create a structured hierarchy of tags, with sub-tags nested within parent tags. This feature is particularly useful for organizations that require a more detailed and organized approach to expense tracking.
# How to import single tags (no accounting integration connected)
## Add single tags via spreadsheet
To set up Tags, follow these steps:
- Go to **Settings > Workspace > Group / Individual > [Workspace name] > Tags**.
- You can choose to add tags one by one, or upload them in bulk via a spreadsheet.

After downloading the CSV and creating the tags you want to import, go to the Tags section in the policy editor: Settings > Workspaces > Group > [Workspace name] > Tags
Enable multi-level tags by toggling the button.
Click "Import from Spreadsheet" to bring in your CSV.
Indicate whether the first line contains the tag header.
Choose if the tag list is independent or dependent (matching your CSV).
Decide if your tags list includes GL codes.
Upload your CSV or TSV file.
Confirm your file and update your tags list.
## Manually add single tags

If you need to add Tags to your workspace manually, you can follow the steps below.

On web:

1. Navigate to Settings > Workspace > Group / Individual > [Workspace name] > Tags.
2. Add new tags under Add a Category.

On mobile:

1. Tap the three-bar menu icon at the top left corner of the app
2. Tap on Settings in the menu on the left side
3. Scroll to the Workspace subhead and click on tags listed underneath the default policy
4. Add new categories by tapping the + button in the upper right corner. To delete a category, on iOS swipe left, on Android press and hold. Tap a category name to edit it.

# How to import multi-level tags (no accounting integration connected)
To use multi-level tags, go to the Tags section in your workspace settings.
Toggle on "Do you want to use multiple levels of tags?"

This feature is available for companies with group workspaces and helps accountants track more details in expenses.

If you need to make changes to your multi-level tags, follow these steps:
1. Start by editing them in a CSV file.
2. Import the revised tags into Expensify.
3. Remember to back up your tags! Uploading a CSV will replace your existing settings.
4. Safest Option: Download the old CSV from the Tags page using 'Export to CSV,' make edits, then import it.

## Manage multi-level tags
Once multi-level tagging has been set up, employees will be able to choose more than one tag per expense. Based on the choice made for the first tag, the second subset of tag options will appear. After the second tag is chosen, more tag lists can appear, customizable up to 5 tag levels.

### Best Practices
- Multi-level tagging is available for companies on group workspaces and is intended to help accountants track additional information at the expense line-item level.
- If you need to make any changes to the Tags, you need to first make them on the CSV and import the revised Tags into Expensify.
- Make sure to have a backup of your tags! Every time you upload a CSV it will override your previous settings.
- The easiest way to keep the old CSV is to download it from the Tags page by clicking Export to CSV, editing the list, and then importing it to apply the changes.


# How to import tags with an accounting integration connected
If you have connected Expensify to a direct integration such as QuickBooks Online, QuickBooks Desktop, Sage Intacct, Xero, or NetSuite, then Expensify automatically imports XYZ from your accounting system as tags.

When you first connect your accounting integration you’ll configure classes, customers, projects, departments locations, etc. to import as tags in Expensify.

If you need to update your tags in Expensify, you will first need to update them in your accounting system, then sync the connection in Expensify by navigating to Settings > Workspace > Group > [Workspace Name] > Connection > Sync Now.

Alternatively, if you update the tag details in your accounting integration, be sure to sync the policy connection so that the updated information is available on the workspace.

# Deep Dive
## Make tags required
You can require tags for any workspace expenses by enabling People must tag expenses on the Tags page by navigating to Settings > Workspace > Group > [Workspace Name] > Tags.
# FAQ

## What are the different tag options?
If you want your second tag to depend on the first one, use dependent tags. Include GL codes if needed, especially when using accounting integrations.
For other scenarios, like not using accounting integrations, use independent tags, which can still include GL codes if necessary.


## Are the multi-level tags only available with a certain subscription (pricing plan)?
Multi-level tagging is only available with the Control type policy.

## I can’t see "Do you want to use multiple level tags" feature on my company's expense workspace. Why is that?
If you are connected to an accounting integration, you will not see this feature. You will need to add those tags in your integration first, then sync the connection.


Loading

0 comments on commit 551bb87

Please sign in to comment.