@@ -12,6 +12,7 @@ import androidx.compose.foundation.layout.RowScope
1212import androidx.compose.foundation.layout.Spacer
1313import androidx.compose.foundation.layout.fillMaxSize
1414import androidx.compose.foundation.layout.fillMaxWidth
15+ import androidx.compose.foundation.layout.height
1516import androidx.compose.foundation.layout.padding
1617import androidx.compose.foundation.layout.size
1718import androidx.compose.foundation.rememberScrollState
@@ -38,6 +39,7 @@ import androidx.compose.ui.text.style.TextAlign
3839import androidx.compose.ui.unit.DpSize
3940import androidx.compose.ui.unit.dp
4041import androidx.compose.ui.util.fastForEach
42+ import com.sebastianneubauer.jsontree.TreeState
4143import io.github.openflocon.flocondesktop.common.ui.window.FloconWindow
4244import io.github.openflocon.flocondesktop.common.ui.window.FloconWindowState
4345import io.github.openflocon.flocondesktop.common.ui.window.createFloconWindowState
@@ -49,11 +51,15 @@ import io.github.openflocon.flocondesktop.features.network.mock.edition.model.He
4951import io.github.openflocon.flocondesktop.features.network.mock.edition.model.MockNetworkUiModel
5052import io.github.openflocon.flocondesktop.features.network.mock.edition.model.SelectedMockUiModel
5153import io.github.openflocon.library.designsystem.FloconTheme
54+ import io.github.openflocon.library.designsystem.components.DefaultLabel
5255import io.github.openflocon.library.designsystem.components.FloconCheckbox
5356import io.github.openflocon.library.designsystem.components.FloconDialogButtons
5457import io.github.openflocon.library.designsystem.components.FloconDialogHeader
58+ import io.github.openflocon.library.designsystem.components.FloconJsonTree
5559import io.github.openflocon.library.designsystem.components.FloconSurface
60+ import io.github.openflocon.library.designsystem.components.FloconTab
5661import io.github.openflocon.library.designsystem.components.FloconTextField
62+ import io.github.openflocon.library.designsystem.components.TabType
5763import io.github.openflocon.library.designsystem.components.defaultLabel
5864import io.github.openflocon.library.designsystem.components.defaultPlaceHolder
5965
@@ -67,7 +73,7 @@ fun NetworkEditionWindow(
6773) {
6874 val windowState: FloconWindowState = remember(instanceId) {
6975 createFloconWindowState(
70- size = DpSize (900 .dp, 700 .dp)
76+ size = DpSize (900 .dp, 800 .dp)
7177 )
7278 }
7379 key(windowState, instanceId) {
@@ -202,17 +208,21 @@ fun MockEditorScreen(
202208 )
203209
204210 Row (modifier = Modifier .fillMaxWidth()) {
205- Tab (
211+ FloconTab (
212+ modifier = Modifier .weight(1F ),
206213 text = " HttpCode + Body" ,
207214 isSelected = mock.responseType == EditableMockNetworkUiModel .ResponseType .BODY ,
215+ tabType = TabType .Start ,
208216 onSelected = {
209217 mock =
210218 mock.copy(responseType = EditableMockNetworkUiModel .ResponseType .BODY )
211219 }
212220 )
213- Tab (
221+ FloconTab (
222+ modifier = Modifier .weight(1F ),
214223 text = " Exception" ,
215224 isSelected = mock.responseType == EditableMockNetworkUiModel .ResponseType .EXCEPTION ,
225+ tabType = TabType .End ,
216226 onSelected = {
217227 mock =
218228 mock.copy(responseType = EditableMockNetworkUiModel .ResponseType .EXCEPTION )
@@ -365,16 +375,66 @@ fun MockEditorScreen(
365375 }
366376 }
367377
368- FloconTextField (
369- label = defaultLabel(" Body" ),
370- value = bodyResponse.body,
371- minLines = 4 ,
372- onValueChange = { newValue ->
373- mock = mock.copy(bodyResponse = bodyResponse.copy(body = newValue))
374- },
375- modifier = Modifier .fillMaxWidth(),
376- containerColor = FloconTheme .colorPalette.primary
377- )
378+ DefaultLabel (" Body" )
379+
380+ var isEditSelected by remember { mutableStateOf(true ) }
381+
382+ Row (modifier = Modifier .fillMaxWidth()) {
383+ FloconTab (
384+ modifier = Modifier .weight(1F ),
385+ text = " Edit" ,
386+ isSelected = isEditSelected,
387+ onSelected = { isEditSelected = true },
388+ tabType = TabType .Start
389+ )
390+ FloconTab (
391+ modifier = Modifier .weight(1F ),
392+ text = " Validate" ,
393+ isSelected = ! isEditSelected,
394+ onSelected = { isEditSelected = false },
395+ tabType = TabType .End
396+ )
397+ }
398+
399+ if (isEditSelected) {
400+ FloconTextField (
401+ value = bodyResponse.body,
402+ minLines = 10 ,
403+ onValueChange = { newValue ->
404+ mock = mock.copy(bodyResponse = bodyResponse.copy(body = newValue))
405+ },
406+ modifier = Modifier .fillMaxWidth(),
407+ containerColor = FloconTheme .colorPalette.primary
408+ )
409+ } else {
410+ var jsonError by remember(bodyResponse.body) { mutableStateOf<Throwable ?>(null ) }
411+
412+ Box (
413+ modifier = Modifier
414+ .fillMaxWidth()
415+ .height(400 .dp)
416+ .background(
417+ color = FloconTheme .colorPalette.primary,
418+ shape = FloconTheme .shapes.medium,
419+ )
420+ .padding(vertical = 4 .dp, horizontal = 8 .dp),
421+ ) {
422+ val throwable = jsonError
423+ if (throwable == null ) {
424+ FloconJsonTree (
425+ json = bodyResponse.body,
426+ initialState = TreeState .EXPANDED ,
427+ onError = { jsonError = it },
428+ modifier = Modifier .fillMaxSize()
429+ )
430+ } else {
431+ Text (
432+ text = throwable.localizedMessage,
433+ style = FloconTheme .typography.bodySmall
434+ )
435+ }
436+ }
437+ }
378438 }
379439 }
380440 }
@@ -471,32 +531,3 @@ private fun HeaderInputField(
471531 }
472532 }
473533}
474-
475- @Composable
476- fun RowScope.Tab (
477- text : String ,
478- isSelected : Boolean ,
479- onSelected : () -> Unit
480- ) {
481- Text (
482- modifier = Modifier .weight(1f )
483- .clip(RoundedCornerShape (4 .dp))
484- .background(
485- color = if (isSelected) {
486- Color .White .copy(alpha = 0.8f )
487- } else {
488- Color .White .copy(alpha = 0.1f )
489- },
490- ).clickable {
491- onSelected()
492- }.padding(vertical = 8 .dp),
493- text = text,
494- textAlign = TextAlign .Center ,
495- style = FloconTheme .typography.bodyMedium,
496- color = if (isSelected) {
497- FloconTheme .colorPalette.primary
498- } else {
499- FloconTheme .colorPalette.onSurface.copy(alpha = 0.45f )
500- },
501- )
502- }
0 commit comments