Skip to content

Conversation

@sbakhtiarov
Copy link
Contributor

@sbakhtiarov sbakhtiarov commented Dec 8, 2025

https://wearezeta.atlassian.net/browse/WPB-22984

What's new in this PR?

Fixed issues:

  • Top bar elevation removed
  • Tag chip view and text input aligned
  • Invalid tag input field cursor color in dark mode

Other:

  • Refactoring viewmodel state management

@sbakhtiarov sbakhtiarov force-pushed the chore/tags-ui-refactor branch 2 times, most recently from 1201ec6 to cbcedab Compare December 9, 2025 13:17
@pull-request-size pull-request-size bot added size/M and removed size/S labels Dec 9, 2025
@sbakhtiarov sbakhtiarov force-pushed the chore/tags-ui-refactor branch from cbcedab to 83b8ff6 Compare December 12, 2025 09:51
@codecov
Copy link

codecov bot commented Dec 18, 2025

Codecov Report

❌ Patch coverage is 94.87179% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 48.48%. Comparing base (20153ef) to head (f4f548a).

Files with missing lines Patch % Lines
...id/feature/cells/ui/tags/AddRemoveTagsViewModel.kt 94.87% 1 Missing and 1 partial ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##           develop    #4467      +/-   ##
===========================================
+ Coverage    48.46%   48.48%   +0.01%     
===========================================
  Files          575      575              
  Lines        19803    19804       +1     
  Branches      3313     3311       -2     
===========================================
+ Hits          9598     9601       +3     
+ Misses        9190     9189       -1     
+ Partials      1015     1014       -1     
Files with missing lines Coverage Δ
...id/feature/cells/ui/tags/AddRemoveTagsViewModel.kt 96.22% <94.87%> (+3.91%) ⬆️

Continue to review full report in Codecov by Sentry.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 20153ef...f4f548a. Read the comment docs.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@sbakhtiarov sbakhtiarov requested a review from Garzas January 12, 2026 08:22
@sbakhtiarov sbakhtiarov changed the title chore: tags ui refactor (WPB-17811) chore: tags ui refactor (WPB-22984) Jan 21, 2026
@sonarqubecloud
Copy link

Comment on lines +224 to +231
addedTags.forEach { item ->
WireFilterChip(
modifier = Modifier.align(Alignment.CenterVertically),
label = item,
isSelected = true,
onSelectChip = onRemoveTag
)
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we wrap each chip with key(tag) to avoid state and animation issues when the list changes?

  addedTags.forEach { item ->
                    key(item) {
                        WireFilterChip(
                            modifier = Modifier.align(Alignment.CenterVertically),
                            label = item,
                            isSelected = true,
                            onSelectChip = onRemoveTag
                        )
                    }
                }

Comment on lines +106 to +110
fun updateViewState() {
updateViewState(state.value.addedTags)
}

result
.onSuccess { sendAction(AddRemoveTagsViewModelAction.Success) }
.onFailure { sendAction(AddRemoveTagsViewModelAction.Failure) }
.also { isLoading.value = false }
fun updateViewState(addedTags: Set<String>) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could remove redundant function overload by making it like this

fun updateViewState(addedTags: Set<String> = state.value.addedTags) 

And can we cover it with unit test


private val navArgs: AddRemoveTagsNavArgs = savedStateHandle.navArgs()
private val initialTags: Set<String> = navArgs.tags.toSet()
private val disallowedChars = listOf(",", ";", "/", "\\", "\"", "\'", "<", ">")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
private val disallowedChars = listOf(",", ";", "/", "\\", "\"", "\'", "<", ">")
private val disallowedChars = setOf(",", ";", "/", "\\", "\"", "\'", "<", ">")

Comment on lines 76 to 82
tag.trim().let { newTag ->
if (newTag.isNotBlank() && newTag !in addedTags.value) {
addedTags.update { it + newTag }
updateSuggestions("")
val addedTags = state.value.addedTags
if (newTag.isNotBlank() && newTag !in addedTags) {
updateViewState(addedTags + tag)
tagsTextState.clearText()
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we could avoid unnecessary let here

val newTag = tag.trim()
    if (newTag.isNotBlank() && newTag !in state.value.addedTags) {
        updateViewState(state.value.addedTags + newTag)
        tagsTextState.clearText()
    }

Comment on lines +63 to +67
launch {
snapshotFlow { tagsTextState.text.toString() }
.debounce(TYPING_DEBOUNCE_TIME)
.collectLatest { updateViewState() }
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The inner launch is unnecessary.
The flow collection can run directly in the outer coroutine, since we always need to wait for getAllTagsUseCase() to complete before collecting the flow.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants