@@ -20,6 +20,8 @@ import dev.fritz2.core.storeOf
20
20
import dev.fritz2.core.title
21
21
import files.FluentFilesStore
22
22
import icons.SvgIconSource
23
+ import kotlinx.coroutines.flow.Flow
24
+ import kotlinx.coroutines.flow.combine
23
25
import kotlinx.coroutines.flow.distinctUntilChanged
24
26
import kotlinx.coroutines.flow.filterNotNull
25
27
import kotlinx.coroutines.flow.map
@@ -48,27 +50,44 @@ fun RenderContext.idsListComponent(selectedIdStore: Store<String>) {
48
50
val fluentFilesStore = get<FluentFilesStore >()
49
51
val settingsStore = get<SettingsStore >()
50
52
51
- val keysData = fluentFilesStore.data.filterNotNull().map { files ->
53
+ val keysData = fluentFilesStore.data.distinctUntilChanged(). filterNotNull().map { files ->
52
54
files.flatMap { it.keys() }.distinct().sorted()
53
55
}
54
- val filesSizeData = fluentFilesStore.data.filterNotNull().map { it.size }
56
+ val filesSizeData =
57
+ fluentFilesStore.data.distinctUntilChanged().filterNotNull().map { it.size }
55
58
settingsStore.data.render { settings ->
56
59
val missingTranslationsData = fluentFilesStore.data.filterNotNull().map { files ->
57
60
files.firstOrNull { it.matches(settings.preferredTranslationLanguage) }
58
61
?.let { preferred ->
59
62
files.missingTranslations(preferred)
60
63
}.orEmpty()
61
64
}
65
+ val searchStore = storeOf(" " )
66
+
67
+ val groups: Flow <List <Pair <String , List <String >>>> =
68
+ searchStore.data.combine(keysData) { query, keys ->
69
+ keys.filter { translationId ->
70
+ if (query.isBlank()) true
71
+ else {
72
+ translationId.lowercase().contains(query.lowercase())
73
+ }
74
+ }
75
+ }.map {
76
+ it.groupIdsByLargestPrefix().toList()
77
+ }
62
78
63
79
keysData.distinctUntilChanged().render { keys ->
64
80
65
81
div(" w-96 flex flex-col gap-2 p-5 bg-white shadow-lg m-2" ) {
66
82
67
- filesSizeData.render {numberOfFiles ->
68
- if (numberOfFiles == 0 ) {
83
+ filesSizeData.render { numberOfFiles ->
84
+ if (numberOfFiles == 0 ) {
69
85
markdownDiv(TL .FluentEditor .NoFilesCta )
70
86
} else {
71
- secondaryButton(text = TL .FluentEditor .AddTranslationId , iconSource = SvgIconSource .Plus ) {
87
+ secondaryButton(
88
+ text = TL .FluentEditor .AddTranslationId ,
89
+ iconSource = SvgIconSource .Plus ,
90
+ ) {
72
91
selectedIdStore.data.render {
73
92
disabled(it.isBlank())
74
93
}
@@ -78,7 +97,6 @@ fun RenderContext.idsListComponent(selectedIdStore: Store<String>) {
78
97
}
79
98
}
80
99
}
81
- val searchStore = storeOf(" " )
82
100
83
101
twInputField(
84
102
searchStore,
@@ -89,70 +107,70 @@ fun RenderContext.idsListComponent(selectedIdStore: Store<String>) {
89
107
div(" grow overflow-y-auto" ) {
90
108
91
109
div(" max-h-0" ) {
92
- searchStore.data.render { query ->
93
- keys.filter { translationId ->
94
- if (query.isBlank()) true
95
- else {
96
- translationId.lowercase().contains(query.lowercase())
97
- }
98
- }.also {
99
- p {
100
- translate(TL .FluentEditor .NumberOfKeys , mapOf (
101
- " amount" to it.size
102
- ))
103
- }
104
- }.groupIdsByLargestPrefix().forEach { (prefix, ids) ->
105
- val showIdsStore = storeOf(true )
106
- showIdsStore.data.render { show ->
107
- div {
108
- a {
109
- + " ${prefix.takeIf { it.isNotBlank() } ? : " -terms" } (${ids.size} )"
110
-
111
- clicks handledBy {
112
- showIdsStore.update(! showIdsStore.current)
113
- }
114
- }
115
- }
116
- if (show) {
117
- ids.forEach { translationId ->
118
- div(" ml-5" ) {
119
- a {
120
- + translationId.replace(
121
- " $prefix -" .takeIf { it != " -" } ? : " " ,
122
- " " ,
123
- )
124
- selectedIdStore.data.render {
125
- if (selectedIdStore.current == translationId) {
126
- + " *"
127
- }
128
- }
110
+ groups.render {
129
111
130
- clicks handledBy {
131
- if (selectedIdStore.current == translationId) {
132
- selectedIdStore.update(" " )
133
- } else {
134
- selectedIdStore.update(
135
- translationId,
136
- )
112
+ }
113
+ missingTranslationsData.distinctUntilChanged()
114
+ .render { missingTranslations ->
115
+ missingTranslationsData.distinctUntilChanged()
116
+ .render { missingTranslations ->
117
+
118
+ groups.renderEach { (prefix, ids) ->
119
+ div {
120
+ val showIdsStore = storeOf(true )
121
+ showIdsStore.data.render { show ->
122
+ div {
123
+ a {
124
+ + " ${prefix.takeIf { it.isNotBlank() } ? : " -terms" } (${ids.size} )"
125
+
126
+ clicks handledBy {
127
+ showIdsStore.update(! showIdsStore.current)
128
+ }
137
129
}
138
130
}
139
- }
140
- missingTranslationsData.distinctUntilChanged()
141
- .render { missingTranslations ->
142
- missingTranslations[translationId]?.let { missing ->
143
- if (missing > 0 ) {
144
- span {
145
- + " missing $missing "
131
+ if (show) {
132
+ ids.forEach { translationId ->
133
+ div(" ml-5" ) {
134
+ a {
135
+ + translationId.replace(
136
+ " $prefix -" .takeIf { it != " -" }
137
+ ? : " " ,
138
+ " " ,
139
+ )
140
+ selectedIdStore.data.render {
141
+ if (selectedIdStore.current == translationId) {
142
+ + " *"
143
+ }
144
+ }
145
+
146
+ clicks handledBy {
147
+ if (selectedIdStore.current == translationId) {
148
+ selectedIdStore.update(
149
+ " " ,
150
+ )
151
+ } else {
152
+ selectedIdStore.update(
153
+ translationId,
154
+ )
155
+ }
156
+ }
157
+ }
158
+ missingTranslations[translationId]?.let { missing ->
159
+ if (missing > 0 ) {
160
+ span {
161
+ + " missing $missing "
162
+ }
163
+ }
146
164
}
147
165
}
148
166
}
149
167
}
168
+ }
150
169
}
170
+
151
171
}
152
172
}
153
- }
154
173
}
155
- }
156
174
}
157
175
}
158
176
}
@@ -234,7 +252,7 @@ fun RenderContext.selectedTranslationEditor(
234
252
it.matches(
235
253
settingsStore.current.preferredTranslationLanguage,
236
254
)
237
- }? : files.first())[translationId]?.definition.orEmpty()
255
+ } ? : files.first())[translationId]?.definition.orEmpty()
238
256
val isDisabled = ! translationService.enabled()
239
257
disabled(originalText.isBlank() || isDisabled)
240
258
if (isDisabled) {
@@ -264,9 +282,9 @@ fun RenderContext.selectedTranslationEditor(
264
282
clicks handledBy {
265
283
val newFile =
266
284
file.put(
267
- translationId,
268
- translationEditor.current,
269
- chunk?.comment,
285
+ translationId,
286
+ translationEditor.current,
287
+ chunk?.comment,
270
288
)
271
289
fluentFilesStore.addOrReplace(newFile)
272
290
translationEditor.update(newFile[translationId]?.definition.orEmpty())
0 commit comments