Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/CONST.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1664,6 +1664,9 @@ const CONST = {

// Often referred to as "collect" workspaces
TEAM: 'team',
TAG: {
required: 'required',
},
},
ROLE: {
ADMIN: 'admin',
Expand Down
2 changes: 1 addition & 1 deletion src/languages/es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2246,7 +2246,7 @@ export default {
},
tags: {
tagName: 'Nombre de etiqueta',
requiresTag: 'Los miembros deben etiquetar todos los gastos',
requiresTag: 'Los diputados deben etiquetar todos los gastos',
customTagName: 'Nombre de etiqueta personalizada',
enableTag: 'Habilitar etiqueta',
enableTags: 'Habilitar etiquetas',
Expand Down
7 changes: 7 additions & 0 deletions src/libs/API/parameters/SetPolicyTagsRequired.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
type SetPolicyTagsRequired = {
policyID: string;
tagListIndex: number;
requireTagList: boolean;
};

export default SetPolicyTagsRequired;
1 change: 1 addition & 0 deletions src/libs/API/parameters/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ export type {default as EnablePolicyConnectionsParams} from './EnablePolicyConne
export type {default as EnablePolicyDistanceRatesParams} from './EnablePolicyDistanceRatesParams';
export type {default as EnablePolicyTagsParams} from './EnablePolicyTagsParams';
export type {default as SetPolicyTagsEnabled} from './SetPolicyTagsEnabled';
export type {default as SetPolicyTagsRequired} from './SetPolicyTagsRequired';
export type {default as EnablePolicyWorkflowsParams} from './EnablePolicyWorkflowsParams';
export type {default as EnablePolicyReportFieldsParams} from './EnablePolicyReportFieldsParams';
export type {default as AcceptJoinRequestParams} from './AcceptJoinRequest';
Expand Down
2 changes: 2 additions & 0 deletions src/libs/API/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ const WRITE_COMMANDS = {
CREATE_WORKSPACE_FROM_IOU_PAYMENT: 'CreateWorkspaceFromIOUPayment',
SET_WORKSPACE_CATEGORIES_ENABLED: 'SetWorkspaceCategoriesEnabled',
SET_POLICY_TAGS_ENABLED: 'SetPolicyTagsEnabled',
SET_POLICY_TAGS_REQUIRED: 'SetPolicyTagsRequired',
CREATE_WORKSPACE_CATEGORIES: 'CreateWorkspaceCategories',
RENAME_WORKSPACE_CATEGORY: 'RenameWorkspaceCategory',
CREATE_POLICY_TAG: 'CreatePolicyTag',
Expand Down Expand Up @@ -344,6 +345,7 @@ type WriteCommandParameters = {
[WRITE_COMMANDS.RENAME_POLICY_TAG]: Parameters.RenamePolicyTagsParams;
[WRITE_COMMANDS.SET_POLICY_TAGS_ENABLED]: Parameters.SetPolicyTagsEnabled;
[WRITE_COMMANDS.DELETE_POLICY_TAGS]: Parameters.DeletePolicyTagsParams;
[WRITE_COMMANDS.SET_POLICY_TAGS_REQUIRED]: Parameters.SetPolicyTagsRequired;
[WRITE_COMMANDS.CREATE_TASK]: Parameters.CreateTaskParams;
[WRITE_COMMANDS.CANCEL_TASK]: Parameters.CancelTaskParams;
[WRITE_COMMANDS.EDIT_TASK_ASSIGNEE]: Parameters.EditTaskAssigneeParams;
Expand Down
53 changes: 53 additions & 0 deletions src/libs/actions/Policy/Policy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import type {
RequestWorkspaceOwnerChangeParams,
SetPolicyDistanceRatesEnabledParams,
SetPolicyDistanceRatesUnitParams,
SetPolicyTagsRequired,
SetWorkspaceApprovalModeParams,
SetWorkspaceAutoReportingFrequencyParams,
SetWorkspaceAutoReportingMonthlyOffsetParams,
Expand Down Expand Up @@ -3378,6 +3379,57 @@ function enablePolicyReportFields(policyID: string, enabled: boolean) {
API.write(WRITE_COMMANDS.ENABLE_POLICY_REPORT_FIELDS, parameters, onyxData);
}

function setWorkspaceTagListRequired(policyID: string, tagListIndex: number, required: boolean) {
const policyTag = PolicyUtils.getTagLists(allPolicyTags?.[`${ONYXKEYS.COLLECTION.POLICY_TAGS}${policyID}`] ?? {})?.[tagListIndex] ?? {};

const onyxData: OnyxData = {
optimisticData: [
{
onyxMethod: Onyx.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.POLICY_TAGS}${policyID}`,
value: {
[policyTag.name]: {
required,
errors: null,
pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD,
},
},
},
],
successData: [
{
onyxMethod: Onyx.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.POLICY_TAGS}${policyID}`,
value: {
[policyTag.name]: {
errors: null,
pendingAction: null,
},
},
},
],
failureData: [
{
onyxMethod: Onyx.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.POLICY_TAGS}${policyID}`,
value: {
[policyTag.name]: {
required: policyTag.required,
},
},
},
],
};

const parameters: SetPolicyTagsRequired = {
policyID,
tagListIndex,
requireTagList: required,
};

API.write(WRITE_COMMANDS.SET_POLICY_TAGS_REQUIRED, parameters, onyxData);
}

function enablePolicyTaxes(policyID: string, enabled: boolean) {
const defaultTaxRates: TaxRatesWithDefault = CONST.DEFAULT_TAX;
const taxRatesData: OnyxData = {
Expand Down Expand Up @@ -4242,6 +4294,7 @@ export {
buildPolicyData,
navigateWhenEnableFeature,
removePendingFieldsFromCustomUnit,
setWorkspaceTagListRequired,
};

export type {NewCustomUnit};
14 changes: 14 additions & 0 deletions src/pages/workspace/tags/WorkspaceViewTagsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import type {StackScreenProps} from '@react-navigation/stack';
import React, {useCallback, useEffect, useMemo, useRef, useState} from 'react';
import {ActivityIndicator, View} from 'react-native';
import {useOnyx} from 'react-native-onyx';
import * as Policy from 'src/libs/actions/Policy/Policy';
import ButtonWithDropdownMenu from '@components/ButtonWithDropdownMenu';
import type {DropdownOption} from '@components/ButtonWithDropdownMenu/types';
import ConfirmModal from '@components/ConfirmModal';
Expand All @@ -21,12 +22,14 @@ import useTheme from '@hooks/useTheme';
import useThemeStyles from '@hooks/useThemeStyles';
import useWindowDimensions from '@hooks/useWindowDimensions';
import * as DeviceCapabilities from '@libs/DeviceCapabilities';
import * as ErrorUtils from '@libs/ErrorUtils';
import localeCompare from '@libs/LocaleCompare';
import Navigation from '@libs/Navigation/Navigation';
import * as PolicyUtils from '@libs/PolicyUtils';
import type {SettingsNavigatorParamList} from '@navigation/types';
import NotFoundPage from '@pages/ErrorPage/NotFoundPage';
import AccessOrNotFoundWrapper from '@pages/workspace/AccessOrNotFoundWrapper';
import ToggleSettingOptionRow from '@pages/workspace/workflows/ToggleSettingsOptionRow';
import * as Tag from '@userActions/Policy/Tag';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
Expand Down Expand Up @@ -245,6 +248,17 @@ function WorkspaceViewTagsPage({route}: WorkspaceViewTagsProps) {
shouldShowRightIcon
/>
</OfflineWithFeedback>
<View style={[styles.pv4, styles.ph5]}>
<ToggleSettingOptionRow
title={translate('workspace.tags.requiresTag')}
switchAccessibilityLabel={translate('workspace.tags.requiresTag')}
isActive={Boolean(policyTagList?.required)}
onToggle={(on) => Policy.setWorkspaceTagListRequired(policyID, route.params.orderWeight ?? 0, on)}
pendingAction={currentPolicyTag.pendingFields?.required}
errors={ErrorUtils.getLatestErrorField(policyTags, CONST.POLICY.TAG.required)}
disabled={tagList.length === 0}
/>
</View>
{isLoading && (
<ActivityIndicator
size={CONST.ACTIVITY_INDICATOR_SIZE.LARGE}
Expand Down