From 06b816fcb0b52795155da4daf554733a5f7c5146 Mon Sep 17 00:00:00 2001 From: chiragsalian Date: Wed, 12 Oct 2022 12:24:55 -0700 Subject: [PATCH 01/49] Adding workspaces to languages --- src/languages/en.js | 1 + src/languages/es.js | 1 + 2 files changed, 2 insertions(+) diff --git a/src/languages/en.js b/src/languages/en.js index 844f1b090c81..e2c51a5ab39e 100755 --- a/src/languages/en.js +++ b/src/languages/en.js @@ -19,6 +19,7 @@ export default { save: 'Save', saveChanges: 'Save changes', password: 'Password', + workspaces: 'Workspaces', profile: 'Profile', payments: 'Payments', preferences: 'Preferences', diff --git a/src/languages/es.js b/src/languages/es.js index 66d8ceb364c1..1499199fa550 100644 --- a/src/languages/es.js +++ b/src/languages/es.js @@ -19,6 +19,7 @@ export default { save: 'Guardar', saveChanges: 'Guardar cambios', password: 'Contraseña', + workspaces: 'Espacios de trabajo', profile: 'Perfil', payments: 'Pagos', preferences: 'Preferencias', From 65ffc1023920635d2a20e76617b1e06a9c871ce7 Mon Sep 17 00:00:00 2001 From: chiragsalian Date: Wed, 12 Oct 2022 12:25:34 -0700 Subject: [PATCH 02/49] a new route and menu item --- src/ROUTES.js | 1 + src/pages/settings/InitialSettingsPage.js | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/src/ROUTES.js b/src/ROUTES.js index 0cd8b4164a8e..0dd0f61824e2 100644 --- a/src/ROUTES.js +++ b/src/ROUTES.js @@ -23,6 +23,7 @@ export default { SETTINGS: 'settings', SETTINGS_PROFILE: 'settings/profile', SETTINGS_PREFERENCES: 'settings/preferences', + SETTINGS_WORKSPACES: 'settings/workspaces', SETTINGS_SECURITY: 'settings/security', SETTINGS_CLOSE: 'settings/security/closeAccount', SETTINGS_PASSWORD: 'settings/security/password', diff --git a/src/pages/settings/InitialSettingsPage.js b/src/pages/settings/InitialSettingsPage.js index b70beb2a9e33..f73dca7dfe16 100755 --- a/src/pages/settings/InitialSettingsPage.js +++ b/src/pages/settings/InitialSettingsPage.js @@ -143,6 +143,11 @@ class InitialSettingsPage extends React.Component { */ getDefaultMenuItems() { return ([ + { + translationKey: 'common.workspaces', + icon: Expensicons.Profile, + action: () => { Navigation.navigate(ROUTES.SETTINGS_WORKSPACES); }, + }, { translationKey: 'common.profile', icon: Expensicons.Profile, From 77167cf592eb8967a88e49936cbf61b096ac8c65 Mon Sep 17 00:00:00 2001 From: chiragsalian Date: Wed, 12 Oct 2022 12:26:02 -0700 Subject: [PATCH 03/49] a new modal screen --- src/libs/Navigation/linkingConfig.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/libs/Navigation/linkingConfig.js b/src/libs/Navigation/linkingConfig.js index 23cfa9ea349c..6e8951bffbcf 100644 --- a/src/libs/Navigation/linkingConfig.js +++ b/src/libs/Navigation/linkingConfig.js @@ -36,6 +36,10 @@ export default { Settings_Root: { path: ROUTES.SETTINGS, }, + Settings_Workspaces: { + path: ROUTES.SETTINGS_WORKSPACES, + exact: true, + }, Settings_Preferences: { path: ROUTES.SETTINGS_PREFERENCES, exact: true, From 657b6e62feabe058d3b7bee4b34043ffd337f770 Mon Sep 17 00:00:00 2001 From: chiragsalian Date: Wed, 12 Oct 2022 12:26:57 -0700 Subject: [PATCH 04/49] updating modal stack navigator with new workspacesPage --- src/libs/Navigation/AppNavigator/ModalStackNavigators.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/libs/Navigation/AppNavigator/ModalStackNavigators.js b/src/libs/Navigation/AppNavigator/ModalStackNavigators.js index 6702b90769d8..e33ee2b73e58 100644 --- a/src/libs/Navigation/AppNavigator/ModalStackNavigators.js +++ b/src/libs/Navigation/AppNavigator/ModalStackNavigators.js @@ -203,6 +203,13 @@ const SettingsModalStackNavigator = createModalStackNavigator([ }, name: 'Settings_Root', }, + { + getComponent: () => { + const SettingsWorkspacesPage = require('../../../pages/settings/Workspaces/WorkspacesPage').default; + return SettingsWorkspacesPage; + }, + name: 'Settings_Workspaces', + }, { getComponent: () => { const SettingsProfilePage = require('../../../pages/settings/Profile/ProfilePage').default; From 7e2d1f563792ead199d3079c04f131d2cde9beaa Mon Sep 17 00:00:00 2001 From: chiragsalian Date: Wed, 12 Oct 2022 12:27:18 -0700 Subject: [PATCH 05/49] New workspaces page --- .../settings/Workspaces/WorkspacesPage.js | 202 ++++++++++++++++++ 1 file changed, 202 insertions(+) create mode 100755 src/pages/settings/Workspaces/WorkspacesPage.js diff --git a/src/pages/settings/Workspaces/WorkspacesPage.js b/src/pages/settings/Workspaces/WorkspacesPage.js new file mode 100755 index 000000000000..7e7ef4bc3482 --- /dev/null +++ b/src/pages/settings/Workspaces/WorkspacesPage.js @@ -0,0 +1,202 @@ +import React, {Component} from 'react'; +import {withOnyx} from 'react-native-onyx'; +import PropTypes from 'prop-types'; +import _ from 'underscore'; +import HeaderWithCloseButton from '../../../components/HeaderWithCloseButton'; +import Navigation from '../../../libs/Navigation/Navigation'; +import ScreenWrapper from '../../../components/ScreenWrapper'; +import ROUTES from '../../../ROUTES'; +import ONYXKEYS from '../../../ONYXKEYS'; +import CONST from '../../../CONST'; +import styles from '../../../styles/styles'; +import compose from '../../../libs/compose'; +import OfflineWithFeedback from '../../../components/OfflineWithFeedback'; +import withLocalize, {withLocalizePropTypes} from '../../../components/withLocalize'; +import * as Expensicons from '../../../components/Icon/Expensicons'; +import themeColors from '../../../styles/themes/default'; +import * as PolicyUtils from '../../../libs/PolicyUtils'; +import MenuItem from '../../../components/MenuItem'; +import * as Policy from '../../../libs/actions/Policy'; +import policyMemberPropType from '../../policyMemberPropType'; +import Permissions from '../../../libs/Permissions'; + +const propTypes = { + /* Onyx Props */ + + /** The list of this user's policies */ + policies: PropTypes.objectOf(PropTypes.shape({ + /** The ID of the policy */ + ID: PropTypes.string, + + /** The name of the policy */ + name: PropTypes.string, + + /** The type of the policy */ + type: PropTypes.string, + + /** The user's role in the policy */ + role: PropTypes.string, + + /** The current action that is waiting to happen on the policy */ + pendingAction: PropTypes.oneOf(_.values(CONST.RED_BRICK_ROAD_PENDING_ACTION)), + })), + + /** List of policy members */ + policyMembers: PropTypes.objectOf(policyMemberPropType), + + /** The user's wallet account */ + userWallet: PropTypes.shape({ + /** The user's current wallet balance */ + currentBalance: PropTypes.number, + }), + + ...withLocalizePropTypes, +}; + +const defaultProps = { + policies: {}, + policyMembers: {}, + userWallet: { + currentBalance: 0, + }, +}; + +/** + * Dismisses the errors on one item + * + * @param {string} policyID + * @param {string} pendingAction + */ +function dismissWorkspaceError(policyID, pendingAction) { + if (pendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE) { + Policy.clearDeleteWorkspaceError(policyID); + return; + } + throw new Error('Not implemented'); +} + +class WorkspacesPage extends Component { + constructor(props) { + super(props); + + this.getWalletBalance = this.getWalletBalance.bind(this); + this.getMenuItemsList = this.getMenuItemsList.bind(this); + this.getMenuItem = this.getMenuItem.bind(this); + } + + /** + * @param {Boolean} isPaymentItem whether the item being rendered is the payments menu item + * @returns {Number} the user wallet balance + */ + getWalletBalance(isPaymentItem) { + return (isPaymentItem && Permissions.canUseWallet(this.props.betas)) + ? this.props.numberFormat( + this.props.userWallet.currentBalance / 100, // Divide by 100 because balance is in cents + {style: 'currency', currency: 'USD'}, + ) : undefined; + } + + /** + * Add free policies (workspaces) to the list of menu items and returns the list of menu items + * @returns {Array} the menu item list + */ + getMenuItemsList() { + return _.chain(this.props.policies) + .filter(policy => policy && policy.type === CONST.POLICY.TYPE.FREE && policy.role === CONST.POLICY.ROLE.ADMIN) + .map(policy => ({ + title: policy.name, + icon: policy.avatar ? policy.avatar : Expensicons.Building, + iconType: policy.avatar ? CONST.ICON_TYPE_AVATAR : CONST.ICON_TYPE_ICON, + action: () => Navigation.navigate(ROUTES.getWorkspaceInitialRoute(policy.id)), + iconStyles: policy.avatar ? [] : [styles.popoverMenuIconEmphasized], + iconFill: themeColors.iconReversed, + fallbackIcon: Expensicons.FallbackWorkspaceAvatar, + brickRoadIndicator: PolicyUtils.getPolicyBrickRoadIndicatorStatus(policy, this.props.policyMembers), + pendingAction: policy.pendingAction, + isPolicy: true, + errors: policy.errors, + dismissError: () => dismissWorkspaceError(policy.id, policy.pendingAction), + disabled: policy.pendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE, + })) + .value(); + } + + getMenuItem(item, index) { + const keyTitle = item.translationKey ? this.props.translate(item.translationKey) : item.title; + const isPaymentItem = item.translationKey === 'common.payments'; + + if (item.isPolicy) { + return ( + + + + ); + } + + return ( + + ); + } + + render() { + return ( + + Navigation.navigate(ROUTES.SETTINGS)} + onCloseButtonPress={() => Navigation.dismissModal(true)} + /> + {_.map(this.getMenuItemsList(), (item, index) => this.getMenuItem(item, index))} + + ); + } +} + +WorkspacesPage.propTypes = propTypes; +WorkspacesPage.defaultProps = defaultProps; + +export default compose( + withLocalize, + withOnyx({ + policies: { + key: ONYXKEYS.COLLECTION.POLICY, + }, + policyMembers: { + key: ONYXKEYS.COLLECTION.POLICY_MEMBER_LIST, + }, + userWallet: { + key: ONYXKEYS.USER_WALLET, + }, + }), +)(WorkspacesPage); From 1c3078ee3961b9389fa06596cfcb480b6ff3f102 Mon Sep 17 00:00:00 2001 From: chiragsalian Date: Wed, 12 Oct 2022 12:27:26 -0700 Subject: [PATCH 06/49] correcting the back button --- src/pages/workspace/WorkspaceInitialPage.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/workspace/WorkspaceInitialPage.js b/src/pages/workspace/WorkspaceInitialPage.js index fbaf9289979d..32e06ffde79e 100644 --- a/src/pages/workspace/WorkspaceInitialPage.js +++ b/src/pages/workspace/WorkspaceInitialPage.js @@ -138,7 +138,7 @@ class WorkspaceInitialPage extends React.Component { Navigation.navigate(ROUTES.SETTINGS)} + onBackButtonPress={() => Navigation.navigate(ROUTES.SETTINGS_WORKSPACES)} onCloseButtonPress={() => Navigation.dismissModal()} shouldShowThreeDotsButton shouldShowGetAssistanceButton From f245ef2afde05529822258f6adb2c64d10869d7d Mon Sep 17 00:00:00 2001 From: chiragsalian Date: Wed, 12 Oct 2022 12:30:21 -0700 Subject: [PATCH 07/49] Path rename so all workspace files are in the same place --- .../AppNavigator/ModalStackNavigators.js | 2 +- .../WorkspacesListPage.js} | 42 +++++++++---------- 2 files changed, 22 insertions(+), 22 deletions(-) rename src/pages/{settings/Workspaces/WorkspacesPage.js => workspace/WorkspacesListPage.js} (84%) diff --git a/src/libs/Navigation/AppNavigator/ModalStackNavigators.js b/src/libs/Navigation/AppNavigator/ModalStackNavigators.js index e33ee2b73e58..7a22f47572fc 100644 --- a/src/libs/Navigation/AppNavigator/ModalStackNavigators.js +++ b/src/libs/Navigation/AppNavigator/ModalStackNavigators.js @@ -205,7 +205,7 @@ const SettingsModalStackNavigator = createModalStackNavigator([ }, { getComponent: () => { - const SettingsWorkspacesPage = require('../../../pages/settings/Workspaces/WorkspacesPage').default; + const SettingsWorkspacesPage = require('../../../pages/workspace/WorkspacesListPage').default; return SettingsWorkspacesPage; }, name: 'Settings_Workspaces', diff --git a/src/pages/settings/Workspaces/WorkspacesPage.js b/src/pages/workspace/WorkspacesListPage.js similarity index 84% rename from src/pages/settings/Workspaces/WorkspacesPage.js rename to src/pages/workspace/WorkspacesListPage.js index 7e7ef4bc3482..5b69cbf3e6f1 100755 --- a/src/pages/settings/Workspaces/WorkspacesPage.js +++ b/src/pages/workspace/WorkspacesListPage.js @@ -2,23 +2,23 @@ import React, {Component} from 'react'; import {withOnyx} from 'react-native-onyx'; import PropTypes from 'prop-types'; import _ from 'underscore'; -import HeaderWithCloseButton from '../../../components/HeaderWithCloseButton'; -import Navigation from '../../../libs/Navigation/Navigation'; -import ScreenWrapper from '../../../components/ScreenWrapper'; -import ROUTES from '../../../ROUTES'; -import ONYXKEYS from '../../../ONYXKEYS'; -import CONST from '../../../CONST'; -import styles from '../../../styles/styles'; -import compose from '../../../libs/compose'; -import OfflineWithFeedback from '../../../components/OfflineWithFeedback'; -import withLocalize, {withLocalizePropTypes} from '../../../components/withLocalize'; -import * as Expensicons from '../../../components/Icon/Expensicons'; -import themeColors from '../../../styles/themes/default'; -import * as PolicyUtils from '../../../libs/PolicyUtils'; -import MenuItem from '../../../components/MenuItem'; -import * as Policy from '../../../libs/actions/Policy'; -import policyMemberPropType from '../../policyMemberPropType'; -import Permissions from '../../../libs/Permissions'; +import HeaderWithCloseButton from '../../components/HeaderWithCloseButton'; +import Navigation from '../../libs/Navigation/Navigation'; +import ScreenWrapper from '../../components/ScreenWrapper'; +import ROUTES from '../../ROUTES'; +import ONYXKEYS from '../../ONYXKEYS'; +import CONST from '../../CONST'; +import styles from '../../styles/styles'; +import compose from '../../libs/compose'; +import OfflineWithFeedback from '../../components/OfflineWithFeedback'; +import withLocalize, {withLocalizePropTypes} from '../../components/withLocalize'; +import * as Expensicons from '../../components/Icon/Expensicons'; +import themeColors from '../../styles/themes/default'; +import * as PolicyUtils from '../../libs/PolicyUtils'; +import MenuItem from '../../components/MenuItem'; +import * as Policy from '../../libs/actions/Policy'; +import policyMemberPropType from '../policyMemberPropType'; +import Permissions from '../../libs/Permissions'; const propTypes = { /* Onyx Props */ @@ -75,7 +75,7 @@ function dismissWorkspaceError(policyID, pendingAction) { throw new Error('Not implemented'); } -class WorkspacesPage extends Component { +class WorkspacesListPage extends Component { constructor(props) { super(props); @@ -183,8 +183,8 @@ class WorkspacesPage extends Component { } } -WorkspacesPage.propTypes = propTypes; -WorkspacesPage.defaultProps = defaultProps; +WorkspacesListPage.propTypes = propTypes; +WorkspacesListPage.defaultProps = defaultProps; export default compose( withLocalize, @@ -199,4 +199,4 @@ export default compose( key: ONYXKEYS.USER_WALLET, }, }), -)(WorkspacesPage); +)(WorkspacesListPage); From 08e8c9a6c9b7f30f94aeae5c4cba9e9b7733a0c6 Mon Sep 17 00:00:00 2001 From: chiragsalian Date: Wed, 12 Oct 2022 15:30:22 -0700 Subject: [PATCH 08/49] removing unused code and trying some stuff --- src/components/menuItemPropTypes.js | 3 + src/pages/settings/InitialSettingsPage.js | 91 ++--------------------- src/pages/workspace/WorkspacesListPage.js | 58 +++++---------- 3 files changed, 31 insertions(+), 121 deletions(-) diff --git a/src/components/menuItemPropTypes.js b/src/components/menuItemPropTypes.js index 7f38175d564e..5ed0ba21abf7 100644 --- a/src/components/menuItemPropTypes.js +++ b/src/components/menuItemPropTypes.js @@ -76,6 +76,9 @@ const propTypes = { /** A fallback avatar icon to display when there is an error on loading avatar from remote URL. */ fallbackIcon: PropTypes.func, + /** Test */ + floatRightAvatars: PropTypes.arrayOf(PropTypes.string), + /** The type of brick road indicator to show. */ brickRoadIndicator: PropTypes.oneOf([CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR, CONST.BRICK_ROAD_INDICATOR_STATUS.INFO, '']), }; diff --git a/src/pages/settings/InitialSettingsPage.js b/src/pages/settings/InitialSettingsPage.js index f73dca7dfe16..59e32a855e2f 100755 --- a/src/pages/settings/InitialSettingsPage.js +++ b/src/pages/settings/InitialSettingsPage.js @@ -5,10 +5,8 @@ import _ from 'underscore'; import {withOnyx} from 'react-native-onyx'; import Str from 'expensify-common/lib/str'; import styles from '../../styles/styles'; -import themeColors from '../../styles/themes/default'; import Text from '../../components/Text'; import * as Session from '../../libs/actions/Session'; -import * as Policy from '../../libs/actions/Policy'; import ONYXKEYS from '../../ONYXKEYS'; import Tooltip from '../../components/Tooltip'; import Avatar from '../../components/Avatar'; @@ -24,13 +22,10 @@ import CONST from '../../CONST'; import Permissions from '../../libs/Permissions'; import * as App from '../../libs/actions/App'; import withCurrentUserPersonalDetails, {withCurrentUserPersonalDetailsPropTypes, withCurrentUserPersonalDetailsDefaultProps} from '../../components/withCurrentUserPersonalDetails'; -import * as PolicyUtils from '../../libs/PolicyUtils'; -import policyMemberPropType from '../policyMemberPropType'; import * as PaymentMethods from '../../libs/actions/PaymentMethods'; import bankAccountPropTypes from '../../components/bankAccountPropTypes'; import cardPropTypes from '../../components/cardPropTypes'; import * as Wallet from '../../libs/actions/Wallet'; -import OfflineWithFeedback from '../../components/OfflineWithFeedback'; import walletTermsPropTypes from '../EnablePayments/walletTermsPropTypes'; const propTypes = { @@ -60,9 +55,6 @@ const propTypes = { pendingAction: PropTypes.oneOf(_.values(CONST.RED_BRICK_ROAD_PENDING_ACTION)), })), - /** List of policy members */ - policyMembers: PropTypes.objectOf(policyMemberPropType), - /** The user's wallet account */ userWallet: PropTypes.shape({ /** The user's current wallet balance */ @@ -92,32 +84,16 @@ const defaultProps = { currentBalance: 0, }, betas: [], - policyMembers: {}, walletTerms: {}, ...withCurrentUserPersonalDetailsDefaultProps, }; -/** - * Dismisses the errors on one item - * - * @param {string} policyID - * @param {string} pendingAction - */ -function dismissWorkspaceError(policyID, pendingAction) { - if (pendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE) { - Policy.clearDeleteWorkspaceError(policyID); - return; - } - throw new Error('Not implemented'); -} - class InitialSettingsPage extends React.Component { constructor(props) { super(props); this.getWalletBalance = this.getWalletBalance.bind(this); this.getDefaultMenuItems = this.getDefaultMenuItems.bind(this); - this.getMenuItemsList = this.getMenuItemsList.bind(this); this.getMenuItem = this.getMenuItem.bind(this); } @@ -142,10 +118,16 @@ class InitialSettingsPage extends React.Component { * @returns {Array} the default menu items */ getDefaultMenuItems() { + const policiesAvatars = _.chain(this.props.policies) + .filter(policy => policy && policy.type === CONST.POLICY.TYPE.FREE && policy.role === CONST.POLICY.ROLE.ADMIN) + .get(policy => (policy.avatar ? policy.avatar : Expensicons.Building)) + .value(); + debugger; + return ([ { translationKey: 'common.workspaces', - icon: Expensicons.Profile, + icon: Expensicons.Workspace, action: () => { Navigation.navigate(ROUTES.SETTINGS_WORKSPACES); }, }, { @@ -183,64 +165,10 @@ class InitialSettingsPage extends React.Component { ]); } - /** - * Add free policies (workspaces) to the list of menu items and returns the list of menu items - * @returns {Array} the menu item list - */ - getMenuItemsList() { - const menuItems = _.chain(this.props.policies) - .filter(policy => policy && policy.type === CONST.POLICY.TYPE.FREE && policy.role === CONST.POLICY.ROLE.ADMIN) - .map(policy => ({ - title: policy.name, - icon: policy.avatar ? policy.avatar : Expensicons.Building, - iconType: policy.avatar ? CONST.ICON_TYPE_AVATAR : CONST.ICON_TYPE_ICON, - action: () => Navigation.navigate(ROUTES.getWorkspaceInitialRoute(policy.id)), - iconStyles: policy.avatar ? [] : [styles.popoverMenuIconEmphasized], - iconFill: themeColors.iconReversed, - fallbackIcon: Expensicons.FallbackWorkspaceAvatar, - brickRoadIndicator: PolicyUtils.getPolicyBrickRoadIndicatorStatus(policy, this.props.policyMembers), - pendingAction: policy.pendingAction, - isPolicy: true, - errors: policy.errors, - dismissError: () => dismissWorkspaceError(policy.id, policy.pendingAction), - disabled: policy.pendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE, - })) - .value(); - menuItems.push(...this.getDefaultMenuItems()); - - return menuItems; - } - getMenuItem(item, index) { const keyTitle = item.translationKey ? this.props.translate(item.translationKey) : item.title; const isPaymentItem = item.translationKey === 'common.payments'; - if (item.isPolicy) { - return ( - - - - ); - } - return ( )} - {_.map(this.getMenuItemsList(), (item, index) => this.getMenuItem(item, index))} + {_.map(this.getDefaultMenuItems(), (item, index) => this.getMenuItem(item, index))} @@ -326,9 +254,6 @@ export default compose( policies: { key: ONYXKEYS.COLLECTION.POLICY, }, - policyMembers: { - key: ONYXKEYS.COLLECTION.POLICY_MEMBER_LIST, - }, userWallet: { key: ONYXKEYS.USER_WALLET, }, diff --git a/src/pages/workspace/WorkspacesListPage.js b/src/pages/workspace/WorkspacesListPage.js index 5b69cbf3e6f1..c61c59a41c62 100755 --- a/src/pages/workspace/WorkspacesListPage.js +++ b/src/pages/workspace/WorkspacesListPage.js @@ -125,46 +125,28 @@ class WorkspacesListPage extends Component { const keyTitle = item.translationKey ? this.props.translate(item.translationKey) : item.title; const isPaymentItem = item.translationKey === 'common.payments'; - if (item.isPolicy) { - return ( - - - - ); - } - return ( - + pendingAction={item.pendingAction} + errorRowStyles={styles.offlineFeedback.menuItemErrorPadding} + onClose={item.dismissError} + errors={item.errors} + > + + ); } From 163988e6e39a549f7dc41507ec47357fd5bfd0a2 Mon Sep 17 00:00:00 2001 From: chiragsalian Date: Wed, 12 Oct 2022 17:56:28 -0700 Subject: [PATCH 09/49] adding avatars to the end of workspace --- src/components/MenuItem.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/components/MenuItem.js b/src/components/MenuItem.js index 1059cd965fb1..8769b9c904c5 100644 --- a/src/components/MenuItem.js +++ b/src/components/MenuItem.js @@ -16,6 +16,8 @@ import menuItemPropTypes from './menuItemPropTypes'; import SelectCircle from './SelectCircle'; import colors from '../styles/colors'; import variables from '../styles/variables'; +import themeColors from '../styles/themes/default'; +import MultipleAvatars from './MultipleAvatars'; const propTypes = { ...menuItemPropTypes, @@ -46,6 +48,7 @@ const defaultProps = { interactive: true, fallbackIcon: Expensicons.FallbackAvatar, brickRoadIndicator: '', + floatRightAvatars: [], }; const MenuItem = (props) => { @@ -160,6 +163,16 @@ const MenuItem = (props) => { /> )} + {!_.isEmpty(props.floatRightAvatars) && ( + + )} {Boolean(props.shouldShowRightIcon) && ( Date: Wed, 12 Oct 2022 17:56:56 -0700 Subject: [PATCH 10/49] support for fallbackIcons. unsure why avatar component is not used instead of Image --- src/components/MultipleAvatars.js | 42 +++++++++++++++++++++++++------ 1 file changed, 34 insertions(+), 8 deletions(-) diff --git a/src/components/MultipleAvatars.js b/src/components/MultipleAvatars.js index f29abef842e1..46c94df634e3 100644 --- a/src/components/MultipleAvatars.js +++ b/src/components/MultipleAvatars.js @@ -9,6 +9,9 @@ import Text from './Text'; import themeColors from '../styles/themes/default'; import * as StyleUtils from '../styles/StyleUtils'; import CONST from '../CONST'; +import * as Expensicons from './Icon/Expensicons'; +import defaultTheme from '../styles/themes/default'; +import Icon from './Icon'; const propTypes = { /** Array of avatar URLs or icons */ @@ -23,6 +26,8 @@ const propTypes = { /** Tooltip for the Avatar */ avatarTooltips: PropTypes.arrayOf(PropTypes.string), + + fallbackIcon: PropTypes.func, }; const defaultProps = { @@ -30,6 +35,7 @@ const defaultProps = { size: CONST.AVATAR_SIZE.DEFAULT, secondAvatarStyle: [StyleUtils.getBackgroundAndBorderStyle(themeColors.componentBG)], avatarTooltips: [], + fallbackIcon: undefined, }; const MultipleAvatars = (props) => { @@ -64,20 +70,40 @@ const MultipleAvatars = (props) => { style={singleAvatarStyles} > - + {!_.isEmpty(props.icons[0]) && ( + + )} + {_.isEmpty(props.icons[0]) && props.fallbackIcon && ( + + )} {props.icons.length === 2 ? ( - + {!_.isEmpty(props.icons[1]) && ( + + )} + {_.isEmpty(props.icons[1]) && props.fallbackIcon && ( + + )} ) : ( From bd79e90fb5fdff7ae513ba298f7e532235ec5dc5 Mon Sep 17 00:00:00 2001 From: chiragsalian Date: Wed, 12 Oct 2022 17:57:11 -0700 Subject: [PATCH 11/49] passing policy avatars --- src/pages/settings/InitialSettingsPage.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/pages/settings/InitialSettingsPage.js b/src/pages/settings/InitialSettingsPage.js index 59e32a855e2f..0c3b7bafc3b8 100755 --- a/src/pages/settings/InitialSettingsPage.js +++ b/src/pages/settings/InitialSettingsPage.js @@ -27,6 +27,7 @@ import bankAccountPropTypes from '../../components/bankAccountPropTypes'; import cardPropTypes from '../../components/cardPropTypes'; import * as Wallet from '../../libs/actions/Wallet'; import walletTermsPropTypes from '../EnablePayments/walletTermsPropTypes'; +import lodashGet from 'lodash/get'; const propTypes = { /* Onyx Props */ @@ -120,15 +121,15 @@ class InitialSettingsPage extends React.Component { getDefaultMenuItems() { const policiesAvatars = _.chain(this.props.policies) .filter(policy => policy && policy.type === CONST.POLICY.TYPE.FREE && policy.role === CONST.POLICY.ROLE.ADMIN) - .get(policy => (policy.avatar ? policy.avatar : Expensicons.Building)) + .pluck('avatar') .value(); - debugger; return ([ { translationKey: 'common.workspaces', icon: Expensicons.Workspace, action: () => { Navigation.navigate(ROUTES.SETTINGS_WORKSPACES); }, + floatRightAvatars: policiesAvatars, }, { translationKey: 'common.profile', @@ -182,6 +183,7 @@ class InitialSettingsPage extends React.Component { badgeText={this.getWalletBalance(isPaymentItem)} fallbackIcon={item.fallbackIcon} brickRoadIndicator={item.brickRoadIndicator} + floatRightAvatars={item.floatRightAvatars} /> ); } From 36315ce251956ad3845459c11418221df1d58d34 Mon Sep 17 00:00:00 2001 From: chiragsalian Date: Wed, 12 Oct 2022 17:57:32 -0700 Subject: [PATCH 12/49] Removing new workspace button from 3 dots and adding it as footer --- src/pages/workspace/WorkspaceInitialPage.js | 4 ---- src/pages/workspace/WorkspacesListPage.js | 14 +++++++++++++- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/pages/workspace/WorkspaceInitialPage.js b/src/pages/workspace/WorkspaceInitialPage.js index 32e06ffde79e..52f0ae69d830 100644 --- a/src/pages/workspace/WorkspaceInitialPage.js +++ b/src/pages/workspace/WorkspaceInitialPage.js @@ -145,10 +145,6 @@ class WorkspaceInitialPage extends React.Component { guidesCallTaskID={CONST.GUIDES_CALL_TASK_IDS.WORKSPACE_INITIAL} threeDotsMenuItems={[ { - icon: Expensicons.Plus, - text: this.props.translate('workspace.new.newWorkspace'), - onSelected: () => Policy.createWorkspace(), - }, { icon: Expensicons.Trashcan, text: this.props.translate('workspace.common.delete'), onSelected: () => this.setState({isDeleteModalOpen: true}), diff --git a/src/pages/workspace/WorkspacesListPage.js b/src/pages/workspace/WorkspacesListPage.js index c61c59a41c62..5009a869675e 100755 --- a/src/pages/workspace/WorkspacesListPage.js +++ b/src/pages/workspace/WorkspacesListPage.js @@ -1,4 +1,5 @@ import React, {Component} from 'react'; +import {ScrollView} from 'react-native'; import {withOnyx} from 'react-native-onyx'; import PropTypes from 'prop-types'; import _ from 'underscore'; @@ -19,6 +20,8 @@ import MenuItem from '../../components/MenuItem'; import * as Policy from '../../libs/actions/Policy'; import policyMemberPropType from '../policyMemberPropType'; import Permissions from '../../libs/Permissions'; +import Button from '../../components/Button'; +import FixedFooter from '../../components/FixedFooter'; const propTypes = { /* Onyx Props */ @@ -159,7 +162,16 @@ class WorkspacesListPage extends Component { onBackButtonPress={() => Navigation.navigate(ROUTES.SETTINGS)} onCloseButtonPress={() => Navigation.dismissModal(true)} /> - {_.map(this.getMenuItemsList(), (item, index) => this.getMenuItem(item, index))} + + {_.map(this.getMenuItemsList(), (item, index) => this.getMenuItem(item, index))} + + +