@@ -14,6 +14,7 @@ import TableListItem from '@components/SelectionList/TableListItem';
1414import SelectionListWithModal from '@components/SelectionListWithModal' ;
1515import CustomListHeader from '@components/SelectionListWithModal/CustomListHeader' ;
1616import Switch from '@components/Switch' ;
17+ import useFilteredSelection from '@hooks/useFilteredSelection' ;
1718import useLocalize from '@hooks/useLocalize' ;
1819import useMobileSelectionMode from '@hooks/useMobileSelectionMode' ;
1920import useNetwork from '@hooks/useNetwork' ;
@@ -45,6 +46,7 @@ import CONST from '@src/CONST';
4546import ONYXKEYS from '@src/ONYXKEYS' ;
4647import ROUTES from '@src/ROUTES' ;
4748import type SCREENS from '@src/SCREENS' ;
49+ import type { PolicyTag } from '@src/types/onyx' ;
4850import type DeepValueOf from '@src/types/utils/DeepValueOf' ;
4951import type { TagListItem } from './types' ;
5052
@@ -57,7 +59,6 @@ function WorkspaceViewTagsPage({route}: WorkspaceViewTagsProps) {
5759 const styles = useThemeStyles ( ) ;
5860 const theme = useTheme ( ) ;
5961 const { translate} = useLocalize ( ) ;
60- const [ selectedTags , setSelectedTags ] = useState < Record < string , boolean > > ( { } ) ;
6162 const dropdownButtonRef = useRef ( null ) ;
6263 const [ isDeleteTagsConfirmModalVisible , setIsDeleteTagsConfirmModalVisible ] = useState ( false ) ;
6364 const isFocused = useIsFocused ( ) ;
@@ -74,6 +75,10 @@ function WorkspaceViewTagsPage({route}: WorkspaceViewTagsProps) {
7475 openPolicyTagsPage ( policyID ) ;
7576 } , [ policyID ] ) ;
7677
78+ const filterFunction = useCallback ( ( tag : PolicyTag | undefined ) => ! ! tag && tag . pendingAction !== CONST . RED_BRICK_ROAD_PENDING_ACTION . DELETE , [ ] ) ;
79+
80+ const [ selectedTags , setSelectedTags ] = useFilteredSelection ( currentPolicyTag ?. tags , filterFunction ) ;
81+
7782 const { isOffline} = useNetwork ( { onReconnect : fetchTags } ) ;
7883 const canSelectMultiple = isSmallScreenWidth ? selectionMode ?. isEnabled : true ;
7984
@@ -89,7 +94,7 @@ function WorkspaceViewTagsPage({route}: WorkspaceViewTagsProps) {
8994
9095 useSearchBackPress ( {
9196 onClearSelection : ( ) => {
92- setSelectedTags ( { } ) ;
97+ setSelectedTags ( [ ] ) ;
9398 } ,
9499 onNavigationCallBack : ( ) => Navigation . goBack ( isQuickSettingsFlow ? ROUTES . SETTINGS_TAGS_ROOT . getRoute ( policyID ) : undefined ) ,
95100 } ) ;
@@ -109,7 +114,7 @@ function WorkspaceViewTagsPage({route}: WorkspaceViewTagsProps) {
109114 value : tag . name ,
110115 text : getCleanedTagName ( tag . name ) ,
111116 keyForList : tag . name ,
112- isSelected : selectedTags [ tag . name ] && canSelectMultiple ,
117+ isSelected : selectedTags . includes ( tag . name ) && canSelectMultiple ,
113118 pendingAction : tag . pendingAction ,
114119 errors : tag . errors ?? undefined ,
115120 enabled : tag . enabled ,
@@ -142,17 +147,19 @@ function WorkspaceViewTagsPage({route}: WorkspaceViewTagsProps) {
142147 }
143148
144149 const toggleTag = ( tag : TagListItem ) => {
145- setSelectedTags ( ( prev ) => ( {
146- ...prev ,
147- [ tag . value ] : ! prev [ tag . value ] ,
148- } ) ) ;
150+ setSelectedTags ( ( prev ) => {
151+ if ( prev . includes ( tag . value ) ) {
152+ return prev . filter ( ( selectedTag ) => selectedTag !== tag . value ) ;
153+ }
154+ return [ ...prev , tag . value ] ;
155+ } ) ;
149156 } ;
150157
151158 const toggleAllTags = ( ) => {
152159 const availableTags = tagList . filter ( ( tag ) => tag . pendingAction !== CONST . RED_BRICK_ROAD_PENDING_ACTION . DELETE ) ;
153- const anySelected = availableTags . some ( ( tag ) => ! ! selectedTags [ tag . value ] ) ;
160+ const anySelected = availableTags . some ( ( tag ) => selectedTags . includes ( tag . value ) ) ;
154161
155- setSelectedTags ( anySelected ? { } : Object . fromEntries ( availableTags . map ( ( t ) => [ t . value , true ] ) ) ) ;
162+ setSelectedTags ( anySelected ? [ ] : availableTags . map ( ( tag ) => tag . value ) ) ;
156163 } ;
157164
158165 const getCustomListHeader = ( ) => {
@@ -173,29 +180,27 @@ function WorkspaceViewTagsPage({route}: WorkspaceViewTagsProps) {
173180 ) ;
174181 } ;
175182
176- const selectedTagsArray = Object . keys ( selectedTags ) . filter ( ( key ) => selectedTags [ key ] ) ;
177-
178183 const deleteTags = ( ) => {
179- setSelectedTags ( { } ) ;
180- deletePolicyTags ( policyID , selectedTagsArray ) ;
184+ setSelectedTags ( [ ] ) ;
185+ deletePolicyTags ( policyID , selectedTags ) ;
181186 setIsDeleteTagsConfirmModalVisible ( false ) ;
182187 } ;
183188
184189 const isLoading = ! isOffline && policyTags === undefined ;
185190
186191 const getHeaderButtons = ( ) => {
187- if ( ( ! isSmallScreenWidth && selectedTagsArray . length === 0 ) || ( isSmallScreenWidth && ! selectionMode ?. isEnabled ) ) {
192+ if ( ( ! isSmallScreenWidth && selectedTags . length === 0 ) || ( isSmallScreenWidth && ! selectionMode ?. isEnabled ) ) {
188193 return null ;
189194 }
190195
191196 const options : Array < DropdownOption < DeepValueOf < typeof CONST . POLICY . BULK_ACTION_TYPES > > > = [ ] ;
192197 const isThereAnyAccountingConnection = Object . keys ( policy ?. connections ?? { } ) . length !== 0 ;
193198 const isMultiLevelTags = isMultiLevelTagsPolicyUtils ( policyTags ) ;
194199
195- if ( ! isThereAnyAccountingConnection && ! isMultiLevelTags && selectedTagsArray . length > 0 ) {
200+ if ( ! isThereAnyAccountingConnection && ! isMultiLevelTags && selectedTags . length > 0 ) {
196201 options . push ( {
197202 icon : Expensicons . Trashcan ,
198- text : translate ( selectedTagsArray . length === 1 ? 'workspace.tags.deleteTag' : 'workspace.tags.deleteTags' ) ,
203+ text : translate ( selectedTags . length === 1 ? 'workspace.tags.deleteTag' : 'workspace.tags.deleteTags' ) ,
199204 value : CONST . POLICY . BULK_ACTION_TYPES . DELETE ,
200205 onSelected : ( ) => setIsDeleteTagsConfirmModalVisible ( true ) ,
201206 } ) ;
@@ -205,7 +210,7 @@ function WorkspaceViewTagsPage({route}: WorkspaceViewTagsProps) {
205210 const tagsToDisable : Record < string , { name : string ; enabled : boolean } > = { } ;
206211 let disabledTagCount = 0 ;
207212 const tagsToEnable : Record < string , { name : string ; enabled : boolean } > = { } ;
208- for ( const tagName of selectedTagsArray ) {
213+ for ( const tagName of selectedTags ) {
209214 if ( tagListKeyedByName [ tagName ] ?. enabled ) {
210215 enabledTagCount ++ ;
211216 tagsToDisable [ tagName ] = {
@@ -227,7 +232,7 @@ function WorkspaceViewTagsPage({route}: WorkspaceViewTagsProps) {
227232 text : translate ( enabledTagCount === 1 ? 'workspace.tags.disableTag' : 'workspace.tags.disableTags' ) ,
228233 value : CONST . POLICY . BULK_ACTION_TYPES . DISABLE ,
229234 onSelected : ( ) => {
230- setSelectedTags ( { } ) ;
235+ setSelectedTags ( [ ] ) ;
231236 setWorkspaceTagEnabled ( policyID , tagsToDisable , route . params . orderWeight ) ;
232237 } ,
233238 } ) ;
@@ -239,7 +244,7 @@ function WorkspaceViewTagsPage({route}: WorkspaceViewTagsProps) {
239244 text : translate ( disabledTagCount === 1 ? 'workspace.tags.enableTag' : 'workspace.tags.enableTags' ) ,
240245 value : CONST . POLICY . BULK_ACTION_TYPES . ENABLE ,
241246 onSelected : ( ) => {
242- setSelectedTags ( { } ) ;
247+ setSelectedTags ( [ ] ) ;
243248 setWorkspaceTagEnabled ( policyID , tagsToEnable , route . params . orderWeight ) ;
244249 } ,
245250 } ) ;
@@ -253,10 +258,10 @@ function WorkspaceViewTagsPage({route}: WorkspaceViewTagsProps) {
253258 pressOnEnter
254259 isSplitButton = { false }
255260 buttonSize = { CONST . DROPDOWN_BUTTON_SIZE . MEDIUM }
256- customText = { translate ( 'workspace.common.selected' , { count : selectedTagsArray . length } ) }
261+ customText = { translate ( 'workspace.common.selected' , { count : selectedTags . length } ) }
257262 options = { options }
258263 style = { [ shouldUseNarrowLayout && styles . flexGrow1 , shouldUseNarrowLayout && styles . mb3 ] }
259- isDisabled = { ! selectedTagsArray . length }
264+ isDisabled = { ! selectedTags . length }
260265 />
261266 ) ;
262267 } ;
@@ -290,7 +295,7 @@ function WorkspaceViewTagsPage({route}: WorkspaceViewTagsProps) {
290295 title = { selectionModeHeader ? translate ( 'common.selectMultiple' ) : currentTagListName }
291296 onBackButtonPress = { ( ) => {
292297 if ( selectionMode ?. isEnabled ) {
293- setSelectedTags ( { } ) ;
298+ setSelectedTags ( [ ] ) ;
294299 turnOffMobileSelectionMode ( ) ;
295300 return ;
296301 }
@@ -304,8 +309,8 @@ function WorkspaceViewTagsPage({route}: WorkspaceViewTagsProps) {
304309 isVisible = { isDeleteTagsConfirmModalVisible }
305310 onConfirm = { deleteTags }
306311 onCancel = { ( ) => setIsDeleteTagsConfirmModalVisible ( false ) }
307- title = { translate ( selectedTagsArray . length === 1 ? 'workspace.tags.deleteTag' : 'workspace.tags.deleteTags' ) }
308- prompt = { translate ( selectedTagsArray . length === 1 ? 'workspace.tags.deleteTagConfirmation' : 'workspace.tags.deleteTagsConfirmation' ) }
312+ title = { translate ( selectedTags . length === 1 ? 'workspace.tags.deleteTag' : 'workspace.tags.deleteTags' ) }
313+ prompt = { translate ( selectedTags . length === 1 ? 'workspace.tags.deleteTagConfirmation' : 'workspace.tags.deleteTagsConfirmation' ) }
309314 confirmText = { translate ( 'common.delete' ) }
310315 cancelText = { translate ( 'common.cancel' ) }
311316 danger
0 commit comments