Skip to content

Commit 6bdc3d4

Browse files
committed
Fix for PR comments
1. Made terminology and variable naming consistent (see README changes) 2. Fixed caught bugs in PR review 3. Right aligned inspection tab
1 parent d2626f2 commit 6bdc3d4

File tree

10 files changed

+120
-113
lines changed

10 files changed

+120
-113
lines changed

workflow-trace-viewer/README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,14 @@ It can be run via Gradle using:
1010
./gradlew :workflow-trace-viewer:run
1111
```
1212

13+
### Terminology
14+
15+
**Trace**: A trace is a file — made up of frames — that contains the execution history of a Workflow. It includes information about render passes, how states have changed within workflows, and the specific props being passed through. The data collected to generate these should be in chronological order, and allows developers to step through the process easily.
16+
17+
**Frame**: Essentially a "snapshot" of the current "state" of the whole Workflow tree. It contains relevant information about the changes in workflow states and how props are passed throughout.
18+
19+
- Note that "snapshot" and "state" are different from `snapshotState` and `State`, which are idiomatic to the Workflow library.
20+
1321
### External Libraries
1422

1523
[FileKit](https://github.com/vinceglb/FileKit) is an external library made to apply file operations on Kotlin and KMP projects. It's purpose in this app is to allow developers to upload their own json trace files. The motivation for its use is to quickly implement a file picker.

workflow-trace-viewer/src/jvmMain/kotlin/com/squareup/workflow1/traceviewer/App.kt

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,12 @@ import androidx.compose.runtime.remember
99
import androidx.compose.runtime.setValue
1010
import androidx.compose.ui.Alignment
1111
import androidx.compose.ui.Modifier
12-
import com.squareup.workflow1.traceviewer.model.WorkflowNode
12+
import com.squareup.workflow1.traceviewer.model.Node
1313
import com.squareup.workflow1.traceviewer.ui.InfoPanel
1414
import com.squareup.workflow1.traceviewer.ui.RenderDiagram
1515
import com.squareup.workflow1.traceviewer.ui.StateSelectTab
16-
import com.squareup.workflow1.traceviewer.utils.SandboxBackground
17-
import com.squareup.workflow1.traceviewer.utils.UploadFile
16+
import com.squareup.workflow1.traceviewer.util.SandboxBackground
17+
import com.squareup.workflow1.traceviewer.util.UploadFile
1818
import io.github.vinceglb.filekit.PlatformFile
1919

2020
/**
@@ -24,40 +24,43 @@ import io.github.vinceglb.filekit.PlatformFile
2424
public fun App(
2525
modifier: Modifier = Modifier
2626
) {
27-
var selectedFile by remember { mutableStateOf<PlatformFile?>(null) }
28-
var selectedNode by remember { mutableStateOf<WorkflowNode?>(null) }
29-
var workflowTrace by remember { mutableStateOf<List<WorkflowNode>>(emptyList()) }
30-
var snapshotIndex by remember { mutableIntStateOf(0) }
27+
var selectedTraceFile by remember { mutableStateOf<PlatformFile?>(null) }
28+
var selectedNode by remember { mutableStateOf<Node?>(null) }
29+
var workflowFrames by remember { mutableStateOf<List<Node>>(emptyList()) }
30+
var frameIndex by remember { mutableIntStateOf(0) }
3131

3232
Box {
3333
// Main content
34-
if (selectedFile != null) {
34+
if (selectedTraceFile != null) {
3535
SandboxBackground {
3636
RenderDiagram(
37-
file = selectedFile!!,
38-
traceInd = snapshotIndex,
39-
onFileParse = { workflowTrace = it },
37+
traceFile = selectedTraceFile!!,
38+
traceInd = frameIndex,
39+
onFileParse = { workflowFrames = it },
4040
onNodeSelect = { selectedNode = it }
4141
)
4242
}
4343
}
4444

4545
// Top trace selector row
4646
StateSelectTab(
47-
trace = workflowTrace,
48-
currentIndex = snapshotIndex,
49-
onIndexChange = { snapshotIndex = it },
47+
frames = workflowFrames,
48+
currentIndex = frameIndex,
49+
onIndexChange = { frameIndex = it },
5050
modifier = Modifier.align(Alignment.TopCenter)
5151
)
5252

53-
// Left side information panel
53+
// Right side information panel
5454
InfoPanel(selectedNode)
5555

56-
// Bottom right upload button
56+
// Bottom left upload button
5757
val onReset = {
5858
selectedNode = null
59-
snapshotIndex = 0
59+
frameIndex = 0
6060
}
61-
UploadFile(onReset = onReset, onFileSelect = { selectedFile = it })
61+
UploadFile(
62+
onReset = onReset,
63+
onFileSelect = { selectedTraceFile = it }
64+
)
6265
}
6366
}

workflow-trace-viewer/src/jvmMain/kotlin/com/squareup/workflow1/traceviewer/model/WorkflowNode.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ package com.squareup.workflow1.traceviewer.model
77
*
88
* TBD what more metadata should be involved with each node, e.g. (props, states, # of render passes)
99
*/
10-
public data class WorkflowNode(
10+
public class Node(
1111
val id: String,
1212
val name: String,
13-
val children: List<WorkflowNode>
13+
val children: List<Node>
1414
)

workflow-trace-viewer/src/jvmMain/kotlin/com/squareup/workflow1/traceviewer/ui/StateSelectTab.kt renamed to workflow-trace-viewer/src/jvmMain/kotlin/com/squareup/workflow1/traceviewer/ui/FrameSelectTab.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,14 @@ import androidx.compose.ui.Modifier
1212
import androidx.compose.ui.draw.clip
1313
import androidx.compose.ui.graphics.Color
1414
import androidx.compose.ui.unit.dp
15-
import com.squareup.workflow1.traceviewer.model.WorkflowNode
15+
import com.squareup.workflow1.traceviewer.model.Node
1616

1717
/**
1818
* A trace tab selector that allows devs to switch between different states within the provided trace.
1919
*/
2020
@Composable
2121
public fun StateSelectTab(
22-
trace: List<WorkflowNode>,
22+
frames: List<Node>,
2323
currentIndex: Int,
2424
onIndexChange: (Int) -> Unit,
2525
modifier: Modifier = Modifier
@@ -36,7 +36,7 @@ public fun StateSelectTab(
3636
.padding(8.dp),
3737
state = state
3838
) {
39-
items(trace.size) { index ->
39+
items(frames.size) { index ->
4040
Text(
4141
text = "State ${index + 1}",
4242
color = if (index == currentIndex) Color.Black else Color.LightGray,

workflow-trace-viewer/src/jvmMain/kotlin/com/squareup/workflow1/traceviewer/ui/WorkflowInfoPanel.kt

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package com.squareup.workflow1.traceviewer.ui
33
import androidx.compose.foundation.background
44
import androidx.compose.foundation.layout.Column
55
import androidx.compose.foundation.layout.Row
6+
import androidx.compose.foundation.layout.Spacer
67
import androidx.compose.foundation.layout.fillMaxHeight
78
import androidx.compose.foundation.layout.fillMaxWidth
89
import androidx.compose.foundation.layout.padding
@@ -23,7 +24,7 @@ import androidx.compose.ui.Modifier
2324
import androidx.compose.ui.graphics.Color
2425
import androidx.compose.ui.unit.dp
2526
import androidx.compose.ui.unit.sp
26-
import com.squareup.workflow1.traceviewer.model.WorkflowNode
27+
import com.squareup.workflow1.traceviewer.model.Node
2728

2829
/**
2930
* A panel that displays information about the selected workflow node.
@@ -33,19 +34,14 @@ import com.squareup.workflow1.traceviewer.model.WorkflowNode
3334
*/
3435
@Composable
3536
public fun InfoPanel(
36-
selectedNode: WorkflowNode?,
37+
selectedNode: Node?,
3738
modifier: Modifier = Modifier
3839
) {
40+
// This row is ordered RTL
3941
Row {
40-
var panelOpen by remember { mutableStateOf(false) }
42+
Spacer(modifier = Modifier.weight(1f))
4143

42-
// based on open/close, display the node details (Column)
43-
if (panelOpen) {
44-
PanelDetails(
45-
selectedNode,
46-
Modifier.fillMaxWidth(.35f)
47-
)
48-
}
44+
var panelOpen by remember { mutableStateOf(false) }
4945

5046
IconButton(
5147
onClick = { panelOpen = !panelOpen },
@@ -60,39 +56,43 @@ public fun InfoPanel(
6056
modifier = Modifier
6157
)
6258
}
59+
60+
// based on open/close, display the node details (Column)
61+
if (panelOpen) {
62+
PanelDetails(
63+
selectedNode,
64+
Modifier.fillMaxWidth(.35f)
65+
)
66+
}
6367
}
6468
}
6569

6670
/**
67-
* The text details of the selected node. This should be closely coupled with the [WorkflowNode]
71+
* The text details of the selected node. This should be closely coupled with the [Node]
6872
* data class to see what information should be displayed.
6973
*/
7074
@Composable
7175
private fun PanelDetails(
72-
node: WorkflowNode?,
76+
node: Node?,
7377
modifier: Modifier = Modifier
7478
) {
7579
Column(
76-
modifier
80+
modifier = modifier
7781
.fillMaxHeight()
7882
.background(Color.LightGray)
83+
.padding(8.dp),
84+
horizontalAlignment = Alignment.CenterHorizontally
7985
) {
8086
if (node == null) {
8187
Text("No node selected")
8288
return@Column
8389
}
8490

85-
Column(
86-
modifier = Modifier
87-
.padding(8.dp),
88-
horizontalAlignment = Alignment.CenterHorizontally
89-
) {
90-
Text("only visible with a node selected")
91-
Text(
92-
text = "This is a node panel for ${node.name}",
93-
fontSize = 20.sp,
94-
modifier = Modifier.padding(8.dp)
95-
)
96-
}
91+
Text("only visible with a node selected")
92+
Text(
93+
text = "This is a node panel for ${node.name}",
94+
fontSize = 20.sp,
95+
modifier = Modifier.padding(8.dp)
96+
)
9797
}
9898
}

workflow-trace-viewer/src/jvmMain/kotlin/com/squareup/workflow1/traceviewer/ui/WorkflowTree.kt

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ import androidx.compose.ui.Alignment
1919
import androidx.compose.ui.Modifier
2020
import androidx.compose.ui.graphics.Color
2121
import androidx.compose.ui.unit.dp
22-
import com.squareup.workflow1.traceviewer.model.WorkflowNode
23-
import com.squareup.workflow1.traceviewer.utils.fetchTrace
22+
import com.squareup.workflow1.traceviewer.model.Node
23+
import com.squareup.workflow1.traceviewer.util.fetchTrace
2424
import io.github.vinceglb.filekit.PlatformFile
2525

2626
/**
@@ -29,22 +29,23 @@ import io.github.vinceglb.filekit.PlatformFile
2929
*/
3030
@Composable
3131
public fun RenderDiagram(
32-
file: PlatformFile,
32+
traceFile: PlatformFile,
3333
traceInd: Int,
34-
onFileParse: (List<WorkflowNode>) -> Unit,
35-
onNodeSelect: (WorkflowNode) -> Unit,
34+
onFileParse: (List<Node>) -> Unit,
35+
onNodeSelect: (Node) -> Unit,
3636
) {
37-
var workflowNodes by remember { mutableStateOf<List<WorkflowNode>>(emptyList()) }
37+
var nodes by remember { mutableStateOf<List<Node>>(emptyList()) }
3838
var isLoading by remember { mutableStateOf(true) }
3939

40-
LaunchedEffect(file) {
41-
workflowNodes = fetchTrace(file)
42-
onFileParse(workflowNodes)
40+
LaunchedEffect(traceFile) {
41+
isLoading = true
42+
nodes = fetchTrace(traceFile)
43+
onFileParse(nodes)
4344
isLoading = false
4445
}
4546

4647
if (!isLoading) {
47-
DrawTree(workflowNodes[traceInd], onNodeSelect)
48+
DrawTree(nodes[traceInd], onNodeSelect)
4849
}
4950

5051
// TODO: catch errors and display UI here
@@ -56,8 +57,8 @@ public fun RenderDiagram(
5657
*/
5758
@Composable
5859
private fun DrawTree(
59-
node: WorkflowNode,
60-
onNodeSelect: (WorkflowNode) -> Unit,
60+
node: Node,
61+
onNodeSelect: (Node) -> Unit,
6162
modifier: Modifier = Modifier,
6263
) {
6364
Column(
@@ -87,8 +88,8 @@ private fun DrawTree(
8788
*/
8889
@Composable
8990
private fun DrawNode(
90-
node: WorkflowNode,
91-
onNodeSelect: (WorkflowNode) -> Unit,
91+
node: Node,
92+
onNodeSelect: (Node) -> Unit,
9293
) {
9394
Box(
9495
modifier = Modifier
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package com.squareup.workflow1.traceviewer.util
2+
3+
import androidx.compose.ui.Modifier
4+
import com.squareup.moshi.JsonAdapter
5+
import com.squareup.moshi.JsonDataException
6+
import com.squareup.moshi.Moshi
7+
import com.squareup.moshi.Types
8+
import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory
9+
import com.squareup.workflow1.traceviewer.model.Node
10+
import io.github.vinceglb.filekit.PlatformFile
11+
import io.github.vinceglb.filekit.readString
12+
import java.io.IOException
13+
14+
/**
15+
* Parses the data from the given file and initiates the workflow tree
16+
*/
17+
public suspend fun fetchTrace(
18+
file: PlatformFile?,
19+
modifier: Modifier = Modifier
20+
): List<Node> {
21+
val jsonString = file?.readString()
22+
return jsonString?.let { parseTrace(it) } ?: emptyList()
23+
}
24+
25+
/**
26+
* Parses a JSON string into [Node] with Moshi adapters. Moshi automatically throws JsonDataException
27+
* and IOException
28+
* @throws JsonDataException malformed JSON data or an error reading.
29+
* @throws IOException JSON is correct, but mismatch between class and JSON structure.
30+
*/
31+
public fun parseTrace(
32+
json: String
33+
): List<Node> {
34+
val moshi = Moshi.Builder()
35+
.add(KotlinJsonAdapterFactory())
36+
.build()
37+
38+
val workflowList = Types.newParameterizedType(List::class.java, Node::class.java)
39+
val workflowAdapter: JsonAdapter<List<Node>> = moshi.adapter(workflowList)
40+
val root = workflowAdapter.fromJson(json) ?: emptyList()
41+
return root
42+
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.squareup.workflow1.traceviewer.utils
1+
package com.squareup.workflow1.traceviewer.util
22

33
import androidx.compose.foundation.gestures.awaitEachGesture
44
import androidx.compose.foundation.gestures.detectDragGestures

workflow-trace-viewer/src/jvmMain/kotlin/com/squareup/workflow1/traceviewer/utils/UploadFile.kt renamed to workflow-trace-viewer/src/jvmMain/kotlin/com/squareup/workflow1/traceviewer/util/UploadFile.kt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.squareup.workflow1.traceviewer.utils
1+
package com.squareup.workflow1.traceviewer.util
22

33
import androidx.compose.foundation.layout.Box
44
import androidx.compose.foundation.layout.fillMaxSize
@@ -39,10 +39,11 @@ public fun UploadFile(
3939
onReset()
4040
onFileSelect(it)
4141
}
42+
4243
Button(
4344
onClick = { launcher.launch() },
4445
modifier = Modifier
45-
.align(Alignment.BottomEnd),
46+
.align(Alignment.BottomStart),
4647
shape = CircleShape,
4748
colors = buttonColors(Color.Black)
4849
) {

0 commit comments

Comments
 (0)