Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Settings button appears after delay after enabling Tags #42623

Merged
merged 13 commits into from
Jul 23, 2024
16 changes: 7 additions & 9 deletions src/pages/workspace/tags/WorkspaceTagsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -201,15 +201,13 @@ function WorkspaceTagsPage({route}: WorkspaceTagsPageProps) {
style={[isSmallScreenWidth && styles.flex1]}
/>
)}
{policyTags && (
<Button
medium
onPress={navigateToTagsSettings}
icon={Expensicons.Gear}
text={translate('common.settings')}
style={[isSmallScreenWidth && styles.flex1]}
/>
)}
<Button
medium
onPress={navigateToTagsSettings}
icon={Expensicons.Gear}
text={translate('common.settings')}
style={[isSmallScreenWidth && styles.flex1]}
/>
</View>
);
}
Expand Down
75 changes: 41 additions & 34 deletions src/pages/workspace/tags/WorkspaceTagsSettingsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@ import React, {useCallback, useMemo} from 'react';
import {View} from 'react-native';
import type {OnyxEntry} from 'react-native-onyx';
import {withOnyx} from 'react-native-onyx';
import FullPageOfflineBlockingView from '@components/BlockingViews/FullPageOfflineBlockingView';
import HeaderWithBackButton from '@components/HeaderWithBackButton';
import MenuItemWithTopDescription from '@components/MenuItemWithTopDescription';
import OfflineWithFeedback from '@components/OfflineWithFeedback';
import ScreenWrapper from '@components/ScreenWrapper';
import Switch from '@components/Switch';
import Text from '@components/Text';
import useLocalize from '@hooks/useLocalize';
import useNetwork from '@hooks/useNetwork';
import useThemeStyles from '@hooks/useThemeStyles';
import * as Tag from '@libs/actions/Policy/Tag';
import Navigation from '@libs/Navigation/Navigation';
Expand All @@ -34,6 +36,8 @@ function WorkspaceTagsSettingsPage({route, policyTags}: WorkspaceTagsSettingsPag
const styles = useThemeStyles();
const {translate} = useLocalize();
const [policyTagLists, isMultiLevelTags] = useMemo(() => [PolicyUtils.getTagLists(policyTags), PolicyUtils.isMultiLevelTags(policyTags)], [policyTags]);
const isLoading = !PolicyUtils.getTagLists(policyTags)?.[0] || Object.keys(policyTags ?? {})[0] === 'undefined';
const {isOffline} = useNetwork();
const hasEnabledOptions = OptionsListUtils.hasEnabledOptions(Object.values(policyTags ?? {}).flatMap(({tags}) => Object.values(tags)));
const updateWorkspaceRequiresTag = useCallback(
(value: boolean) => {
Expand All @@ -42,6 +46,42 @@ function WorkspaceTagsSettingsPage({route, policyTags}: WorkspaceTagsSettingsPag
[policyID],
);

const getTagsSettings = (policy: OnyxEntry<OnyxTypes.Policy>) => (
<View style={styles.flexGrow1}>
<OfflineWithFeedback
errors={policy?.errorFields?.requiresTag}
pendingAction={policy?.pendingFields?.requiresTag}
errorRowStyles={styles.mh5}
>
<View style={[styles.mt2, styles.mh4]}>
<View style={[styles.flexRow, styles.mb5, styles.mr2, styles.alignItemsCenter, styles.justifyContentBetween]}>
<Text style={[styles.textNormal]}>{translate('workspace.tags.requiresTag')}</Text>
<Switch
isOn={policy?.requiresTag ?? false}
accessibilityLabel={translate('workspace.tags.requiresTag')}
onToggle={updateWorkspaceRequiresTag}
disabled={!policy?.areTagsEnabled || !hasEnabledOptions}
/>
</View>
</View>
</OfflineWithFeedback>
{!isMultiLevelTags && (
<OfflineWithFeedback
errors={policyTags?.[policyTagLists[0]?.name]?.errors}
onClose={() => Tag.clearPolicyTagListErrors(policyID, policyTagLists[0].orderWeight)}
pendingAction={policyTags?.[policyTagLists[0]?.name]?.pendingAction}
errorRowStyles={styles.mh5}
>
<MenuItemWithTopDescription
title={policyTagLists[0]?.name}
description={translate(`workspace.tags.customTagName`)}
onPress={() => Navigation.navigate(ROUTES.WORKSPACE_EDIT_TAGS.getRoute(policyID, policyTagLists[0].orderWeight))}
shouldShowRightIcon
/>
</OfflineWithFeedback>
)}
</View>
);
return (
<AccessOrNotFoundWrapper
accessVariants={[CONST.POLICY.ACCESS_VARIANTS.ADMIN, CONST.POLICY.ACCESS_VARIANTS.PAID]}
Expand All @@ -55,40 +95,7 @@ function WorkspaceTagsSettingsPage({route, policyTags}: WorkspaceTagsSettingsPag
testID={WorkspaceTagsSettingsPage.displayName}
>
<HeaderWithBackButton title={translate('common.settings')} />
<View style={styles.flexGrow1}>
<OfflineWithFeedback
errors={policy?.errorFields?.requiresTag}
pendingAction={policy?.pendingFields?.requiresTag}
errorRowStyles={styles.mh5}
>
<View style={[styles.mt2, styles.mh4]}>
<View style={[styles.flexRow, styles.mb5, styles.mr2, styles.alignItemsCenter, styles.justifyContentBetween]}>
<Text style={[styles.textNormal]}>{translate('workspace.tags.requiresTag')}</Text>
<Switch
isOn={policy?.requiresTag ?? false}
accessibilityLabel={translate('workspace.tags.requiresTag')}
onToggle={updateWorkspaceRequiresTag}
disabled={!policy?.areTagsEnabled || !hasEnabledOptions}
/>
</View>
</View>
</OfflineWithFeedback>
{!isMultiLevelTags && (
<OfflineWithFeedback
errors={policyTags?.[policyTagLists[0].name]?.errors}
onClose={() => Tag.clearPolicyTagListErrors(policyID, policyTagLists[0].orderWeight)}
pendingAction={policyTags?.[policyTagLists[0].name]?.pendingAction}
errorRowStyles={styles.mh5}
>
<MenuItemWithTopDescription
title={policyTagLists[0].name}
description={translate(`workspace.tags.customTagName`)}
onPress={() => Navigation.navigate(ROUTES.WORKSPACE_EDIT_TAGS.getRoute(policyID, policyTagLists[0].orderWeight))}
shouldShowRightIcon
/>
</OfflineWithFeedback>
)}
</View>
{isOffline && isLoading ? <FullPageOfflineBlockingView>{getTagsSettings(policy)}</FullPageOfflineBlockingView> : getTagsSettings(policy)}
</ScreenWrapper>
)}
</AccessOrNotFoundWrapper>
Expand Down
Loading