Skip to content

Commit

Permalink
Merge pull request #38719 from Krishna2323/krishna2323/issue/37782
Browse files Browse the repository at this point in the history
fix: Fix scrollable elements in Policy pages.
  • Loading branch information
chiragsalian authored May 23, 2024
2 parents 6fd7fbb + d343397 commit cb5c597
Show file tree
Hide file tree
Showing 8 changed files with 111 additions and 72 deletions.
73 changes: 43 additions & 30 deletions src/components/SelectionList/BaseSelectionList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ function BaseSelectionList<TItem extends ListItem>(
sectionTitleStyles,
textInputAutoFocus = true,
shouldTextInputInterceptSwipe = false,
listHeaderContent,
onEndReached = () => {},
onEndReachedThreshold,
}: BaseSelectionListProps<TItem>,
Expand Down Expand Up @@ -334,7 +335,7 @@ function BaseSelectionList<TItem extends ListItem>(
return <section.CustomSectionHeader section={section} />;
}

if (!section.title || isEmptyObject(section.data)) {
if (!section.title || isEmptyObject(section.data) || listHeaderContent) {
return null;
}

Expand All @@ -349,6 +350,39 @@ function BaseSelectionList<TItem extends ListItem>(
);
};

const header = () => (
<>
{!headerMessage && canSelectMultiple && shouldShowSelectAll && (
<View style={[styles.userSelectNone, styles.peopleRow, styles.ph5, styles.pb3, listHeaderWrapperStyle, styles.selectionListStickyHeader]}>
<View style={[styles.flexRow, styles.alignItemsCenter]}>
<Checkbox
accessibilityLabel={translate('workspace.people.selectAll')}
isChecked={flattenedSections.allSelected}
onPress={selectAllRow}
disabled={flattenedSections.allOptions.length === flattenedSections.disabledOptionsIndexes.length}
/>
{!customListHeader && (
<PressableWithFeedback
style={[styles.userSelectNone, styles.flexRow, styles.alignItemsCenter]}
onPress={selectAllRow}
accessibilityLabel={translate('workspace.people.selectAll')}
role="button"
accessibilityState={{checked: flattenedSections.allSelected}}
disabled={flattenedSections.allOptions.length === flattenedSections.disabledOptionsIndexes.length}
dataSet={{[CONST.SELECTION_SCRAPER_HIDDEN_ELEMENT]: true}}
onMouseDown={shouldPreventDefaultFocusOnSelectRow ? (e) => e.preventDefault() : undefined}
>
<Text style={[styles.textStrong, styles.ph3]}>{translate('workspace.people.selectAll')}</Text>
</PressableWithFeedback>
)}
</View>
{customListHeader}
</View>
)}
{!headerMessage && !canSelectMultiple && customListHeader}
</>
);

const renderItem = ({item, index, section}: SectionListRenderItemInfo<TItem, SectionWithIndexOffset<TItem>>) => {
const normalizedIndex = index + (section?.indexOffset ?? 0);
const isDisabled = !!section.isDisabled || item.isDisabled;
Expand Down Expand Up @@ -580,39 +614,17 @@ function BaseSelectionList<TItem extends ListItem>(
<OptionsListSkeletonView shouldAnimate />
) : (
<>
{!headerMessage && canSelectMultiple && shouldShowSelectAll && (
<View style={[styles.userSelectNone, styles.peopleRow, styles.ph5, styles.pb3, listHeaderWrapperStyle]}>
<View style={[styles.flexRow, styles.alignItemsCenter]}>
<Checkbox
accessibilityLabel={translate('workspace.people.selectAll')}
isChecked={flattenedSections.allSelected}
onPress={selectAllRow}
disabled={flattenedSections.allOptions.length === flattenedSections.disabledOptionsIndexes.length}
/>
{!customListHeader && (
<PressableWithFeedback
style={[styles.userSelectNone, styles.flexRow, styles.alignItemsCenter]}
onPress={selectAllRow}
accessibilityLabel={translate('workspace.people.selectAll')}
role="button"
accessibilityState={{checked: flattenedSections.allSelected}}
disabled={flattenedSections.allOptions.length === flattenedSections.disabledOptionsIndexes.length}
dataSet={{[CONST.SELECTION_SCRAPER_HIDDEN_ELEMENT]: true}}
onMouseDown={shouldPreventDefaultFocusOnSelectRow ? (e) => e.preventDefault() : undefined}
>
<Text style={[styles.textStrong, styles.ph3]}>{translate('workspace.people.selectAll')}</Text>
</PressableWithFeedback>
)}
</View>
{customListHeader}
</View>
)}
{!headerMessage && !canSelectMultiple && customListHeader}
{!listHeaderContent && header()}
<SectionList
ref={listRef}
sections={slicedSections}
stickySectionHeadersEnabled={false}
renderSectionHeader={renderSectionHeader}
renderSectionHeader={(arg) => (
<>
{renderSectionHeader(arg)}
{listHeaderContent && header()}
</>
)}
renderItem={renderItem}
getItemLayout={getItemLayout}
onScroll={onScroll}
Expand All @@ -631,6 +643,7 @@ function BaseSelectionList<TItem extends ListItem>(
onLayout={onSectionListLayout}
style={(!maxToRenderPerBatch || (shouldHideListOnInitialRender && isInitialSectionListRender)) && styles.opacity0}
ListFooterComponent={listFooterContent ?? ShowMoreButtonInstance}
ListHeaderComponent={listHeaderContent && listHeaderContent}
onEndReached={onEndReached}
onEndReachedThreshold={onEndReachedThreshold}
/>
Expand Down
3 changes: 3 additions & 0 deletions src/components/SelectionList/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,9 @@ type BaseSelectionListProps<TItem extends ListItem> = Partial<ChildrenProps> & {
/** Custom content to display in the header */
headerContent?: ReactNode;

/** Custom content to display in the header of list component. */
listHeaderContent?: React.JSX.Element | null;

/** Custom content to display in the footer */
footerContent?: ReactNode;

Expand Down
7 changes: 4 additions & 3 deletions src/pages/workspace/WorkspaceMembersPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -504,7 +504,7 @@ function WorkspaceMembersPage({personalDetails, invitedEmailsToAccountIDsDraft,
onPress={() => null}
options={getBulkActionsButtonOptions()}
isSplitButton={false}
style={[isSmallScreenWidth && styles.flexGrow1]}
style={[isSmallScreenWidth && styles.flexGrow1, isSmallScreenWidth && styles.mb3]}
/>
) : (
<Button
Expand All @@ -514,7 +514,7 @@ function WorkspaceMembersPage({personalDetails, invitedEmailsToAccountIDsDraft,
text={translate('workspace.invite.member')}
icon={Expensicons.Plus}
innerStyles={[isSmallScreenWidth && styles.alignItemsCenter]}
style={[isSmallScreenWidth && styles.flexGrow1]}
style={[isSmallScreenWidth && styles.flexGrow1, isSmallScreenWidth && styles.mb3]}
/>
)}
</View>
Expand Down Expand Up @@ -572,7 +572,7 @@ function WorkspaceMembersPage({personalDetails, invitedEmailsToAccountIDsDraft,
ListItem={TableListItem}
disableKeyboardShortcuts={removeMembersConfirmModalVisible}
headerMessage={getHeaderMessage()}
headerContent={getHeaderContent()}
headerContent={!isSmallScreenWidth && getHeaderContent()}
onSelectRow={openMemberDetails}
onCheckboxPress={(item) => toggleUser(item.accountID)}
onSelectAll={() => toggleAllUsers(data)}
Expand All @@ -582,6 +582,7 @@ function WorkspaceMembersPage({personalDetails, invitedEmailsToAccountIDsDraft,
textInputRef={textInputRef}
customListHeader={getCustomListHeader()}
listHeaderWrapperStyle={[styles.ph9, styles.pv3, styles.pb5]}
listHeaderContent={isSmallScreenWidth ? <View style={[styles.pl5, styles.pr5]}>{getHeaderContent()}</View> : null}
showScrollIndicator={false}
/>
</View>
Expand Down
35 changes: 20 additions & 15 deletions src/pages/workspace/categories/WorkspaceCategoriesPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,24 @@ function WorkspaceCategoriesPage({route}: WorkspaceCategoriesPageProps) {

const shouldShowEmptyState = !categoryList.some((category) => category.pendingAction !== CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE) && !isLoading;

const getHeaderText = () => (
<View style={[styles.ph5, styles.pb5, styles.pt3]}>
{Object.keys(policy?.connections ?? {}).length > 0 ? (
<Text>
<Text style={[styles.textNormal, styles.colorMuted]}>{`${translate('workspace.categories.importedFromAccountingSoftware')} `}</Text>
<TextLink
style={[styles.textNormal, styles.link]}
href={`${environmentURL}/${ROUTES.POLICY_ACCOUNTING.getRoute(policyId)}`}
>
{`${translate('workspace.accounting.qbo')} ${translate('workspace.accounting.settings')}`}
</TextLink>
</Text>
) : (
<Text style={[styles.textNormal, styles.colorMuted]}>{translate('workspace.categories.subtitle')}</Text>
)}
</View>
);

return (
<AccessOrNotFoundWrapper
accessVariants={[CONST.POLICY.ACCESS_VARIANTS.ADMIN, CONST.POLICY.ACCESS_VARIANTS.PAID]}
Expand Down Expand Up @@ -274,21 +292,7 @@ function WorkspaceCategoriesPage({route}: WorkspaceCategoriesPageProps) {
danger
/>
{isSmallScreenWidth && <View style={[styles.pl5, styles.pr5]}>{getHeaderButtons()}</View>}
<View style={[styles.ph5, styles.pb5, styles.pt3]}>
{Object.keys(policy?.connections ?? {}).length > 0 ? (
<Text>
<Text style={[styles.textNormal, styles.colorMuted]}>{`${translate('workspace.categories.importedFromAccountingSoftware')} `}</Text>
<TextLink
style={[styles.textNormal, styles.link]}
href={`${environmentURL}/${ROUTES.POLICY_ACCOUNTING.getRoute(policyId)}`}
>
{`${translate('workspace.accounting.qbo')} ${translate('workspace.accounting.settings')}`}
</TextLink>
</Text>
) : (
<Text style={[styles.textNormal, styles.colorMuted]}>{translate('workspace.categories.subtitle')}</Text>
)}
</View>
{!isSmallScreenWidth && getHeaderText()}
{isLoading && (
<ActivityIndicator
size={CONST.ACTIVITY_INDICATOR_SIZE.LARGE}
Expand All @@ -315,6 +319,7 @@ function WorkspaceCategoriesPage({route}: WorkspaceCategoriesPageProps) {
onDismissError={dismissError}
customListHeader={getCustomListHeader()}
listHeaderWrapperStyle={[styles.ph9, styles.pv3, styles.pb5]}
listHeaderContent={isSmallScreenWidth ? getHeaderText() : null}
showScrollIndicator={false}
/>
)}
Expand Down
11 changes: 8 additions & 3 deletions src/pages/workspace/distanceRates/PolicyDistanceRatesPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,12 @@ function PolicyDistanceRatesPage({policy, route}: PolicyDistanceRatesPageProps)
</View>
);

const getHeaderText = () => (
<View style={[styles.ph5, styles.pb5, styles.pt3]}>
<Text style={[styles.textNormal, styles.colorMuted]}>{translate('workspace.distanceRates.centrallyManage')}</Text>
</View>
);

return (
<AccessOrNotFoundWrapper
accessVariants={[CONST.POLICY.ACCESS_VARIANTS.ADMIN, CONST.POLICY.ACCESS_VARIANTS.PAID]}
Expand All @@ -282,9 +288,7 @@ function PolicyDistanceRatesPage({policy, route}: PolicyDistanceRatesPageProps)
{!isSmallScreenWidth && headerButtons}
</HeaderWithBackButton>
{isSmallScreenWidth && <View style={[styles.ph5]}>{headerButtons}</View>}
<View style={[styles.ph5, styles.pb5, styles.pt3]}>
<Text style={[styles.textNormal, styles.colorMuted]}>{translate('workspace.distanceRates.centrallyManage')}</Text>
</View>
{!isSmallScreenWidth && getHeaderText()}
{isLoading && (
<ActivityIndicator
size={CONST.ACTIVITY_INDICATOR_SIZE.LARGE}
Expand All @@ -304,6 +308,7 @@ function PolicyDistanceRatesPage({policy, route}: PolicyDistanceRatesPageProps)
shouldPreventDefaultFocusOnSelectRow={!DeviceCapabilities.canUseTouchScreen()}
customListHeader={getCustomListHeader()}
listHeaderWrapperStyle={[styles.ph9, styles.pv3, styles.pb5]}
listHeaderContent={isSmallScreenWidth ? getHeaderText() : null}
showScrollIndicator={false}
/>
)}
Expand Down
37 changes: 21 additions & 16 deletions src/pages/workspace/tags/WorkspaceTagsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,24 @@ function WorkspaceTagsPage({route}: WorkspaceTagsPageProps) {
);
};

const getHeaderText = () => (
<View style={[styles.ph5, styles.pb5, styles.pt3]}>
{isConnectedToAccounting ? (
<Text>
<Text style={[styles.textNormal, styles.colorMuted]}>{`${translate('workspace.tags.importedFromAccountingSoftware')} `}</Text>
<TextLink
style={[styles.textNormal, styles.link]}
href={`${environmentURL}/${ROUTES.POLICY_ACCOUNTING.getRoute(policyID)}`}
>
{`${translate('workspace.accounting.qbo')} ${translate('workspace.accounting.settings')}`}
</TextLink>
</Text>
) : (
<Text style={[styles.textNormal, styles.colorMuted]}>{translate('workspace.tags.subtitle')}</Text>
)}
</View>
);

return (
<AccessOrNotFoundWrapper
policyID={policyID}
Expand All @@ -289,6 +307,7 @@ function WorkspaceTagsPage({route}: WorkspaceTagsPageProps) {
>
{!isSmallScreenWidth && getHeaderButtons()}
</HeaderWithBackButton>
{isSmallScreenWidth && <View style={[styles.pl5, styles.pr5]}>{getHeaderButtons()}</View>}
<ConfirmModal
isVisible={isDeleteTagsConfirmModalVisible}
onConfirm={deleteTags}
Expand All @@ -299,22 +318,7 @@ function WorkspaceTagsPage({route}: WorkspaceTagsPageProps) {
cancelText={translate('common.cancel')}
danger
/>
{isSmallScreenWidth && <View style={[styles.pl5, styles.pr5]}>{getHeaderButtons()}</View>}
<View style={[styles.ph5, styles.pb5, styles.pt3]}>
{isConnectedToAccounting ? (
<Text>
<Text style={[styles.textNormal, styles.colorMuted]}>{`${translate('workspace.tags.importedFromAccountingSoftware')} `}</Text>
<TextLink
style={[styles.textNormal, styles.link]}
href={`${environmentURL}/${ROUTES.POLICY_ACCOUNTING.getRoute(policyID)}`}
>
{`${translate('workspace.accounting.qbo')} ${translate('workspace.accounting.settings')}`}
</TextLink>
</Text>
) : (
<Text style={[styles.textNormal, styles.colorMuted]}>{translate('workspace.tags.subtitle')}</Text>
)}
</View>
{!isSmallScreenWidth && getHeaderText()}
{isLoading && (
<ActivityIndicator
size={CONST.ACTIVITY_INDICATOR_SIZE.LARGE}
Expand All @@ -341,6 +345,7 @@ function WorkspaceTagsPage({route}: WorkspaceTagsPageProps) {
shouldPreventDefaultFocusOnSelectRow={!DeviceCapabilities.canUseTouchScreen()}
listHeaderWrapperStyle={[styles.ph9, styles.pv3, styles.pb5]}
onDismissError={(item) => Policy.clearPolicyTagErrors(policyID, item.value)}
listHeaderContent={isSmallScreenWidth ? getHeaderText() : null}
showScrollIndicator={false}
/>
)}
Expand Down
13 changes: 8 additions & 5 deletions src/pages/workspace/taxes/WorkspaceTaxesPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,12 @@ function WorkspaceTaxesPage({
/>
);

const getHeaderText = () => (
<View style={[styles.ph5, styles.pb5, styles.pt3]}>
<Text style={[styles.textNormal, styles.colorMuted]}>{translate('workspace.taxes.subtitle')}</Text>
</View>
);

return (
<AccessOrNotFoundWrapper
accessVariants={[CONST.POLICY.ACCESS_VARIANTS.ADMIN, CONST.POLICY.ACCESS_VARIANTS.PAID]}
Expand All @@ -253,12 +259,8 @@ function WorkspaceTaxesPage({
>
{!isSmallScreenWidth && headerButtons}
</HeaderWithBackButton>

{isSmallScreenWidth && <View style={[styles.pl5, styles.pr5]}>{headerButtons}</View>}

<View style={[styles.ph5, styles.pb5, styles.pt3]}>
<Text style={[styles.textNormal, styles.colorMuted]}>{translate('workspace.taxes.subtitle')}</Text>
</View>
{!isSmallScreenWidth && getHeaderText()}
{isLoading && (
<ActivityIndicator
size={CONST.ACTIVITY_INDICATOR_SIZE.LARGE}
Expand All @@ -274,6 +276,7 @@ function WorkspaceTaxesPage({
onSelectAll={toggleAllTaxes}
ListItem={TableListItem}
customListHeader={getCustomListHeader()}
listHeaderContent={isSmallScreenWidth ? getHeaderText() : null}
shouldPreventDefaultFocusOnSelectRow={!DeviceCapabilities.canUseTouchScreen()}
listHeaderWrapperStyle={[styles.ph9, styles.pv3, styles.pb5]}
onDismissError={(item) => (item.keyForList ? clearTaxRateError(policyID, item.keyForList, item.pendingAction) : undefined)}
Expand Down
4 changes: 4 additions & 0 deletions src/styles/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4481,6 +4481,10 @@ const styles = (theme: ThemeColors) =>
borderRadius: 8,
},

selectionListStickyHeader: {
backgroundColor: theme.appBG,
},

draggableTopBar: {
height: 30,
width: '100%',
Expand Down

0 comments on commit cb5c597

Please sign in to comment.