Skip to content

Commit ca46912

Browse files
committed
refactor(ui): extract child definition tree traversal to a common method
Remove outdated TODOs. Fix formatting.
1 parent d912341 commit ca46912

File tree

7 files changed

+69
-83
lines changed

7 files changed

+69
-83
lines changed

ui/src/components/canvas/EipNode.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,6 @@ const getClassNames = (props: NodeProps<EipNodeData>, role: EipRole) => {
8787

8888
// TODO: Consider separating into Endpoint and Channel custom node types
8989
export const EipNode = (props: NodeProps<EipNodeData>) => {
90-
// TODO: clearSelectedChildNode is used in too many different components. See if that can be reduced (or elimnated).
9190
const layout = useGetLayout()
9291
const children = useGetEnabledChildren(props.id)
9392
const hasChildren = children.length > 0

ui/src/components/config-panel/ChildManagementModal.tsx

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import {
2626
import { useGetEnabledChildren } from "../../singletons/store/getterHooks"
2727
import { getEipId } from "../../singletons/store/storeViews"
2828
import { DraggableList, DraggableListItem } from "./DraggableList"
29+
import { findChildDefinition } from "./childDefinitions"
2930

3031
interface ChildPathBreadcrumbProps {
3132
path: string[]
@@ -51,20 +52,13 @@ interface ChildModalProps {
5152
initPath?: string[]
5253
}
5354

54-
// TODO: Should this be a utility method in the EipComponentDef module?
55-
const getEipDefinition = (rootEipDef: EipComponent, path: string[]) => {
56-
let children = rootEipDef.childGroup?.children
57-
55+
const getChildEipDefinition = (rootEipDef: EipComponent, path: string[]) => {
5856
if (path.length == 1) {
59-
return children
57+
return rootEipDef.childGroup?.children
6058
}
6159

62-
for (const id of path.slice(1)) {
63-
const name = getEipId(id)?.name
64-
const child = children?.find((c) => c.name === name)
65-
children = child?.childGroup?.children
66-
}
67-
return children
60+
const child = findChildDefinition(rootEipDef, path)
61+
return child?.childGroup?.children
6862
}
6963

7064
const ChildPathBreadcrumb = ({
@@ -164,7 +158,7 @@ export const ChildManagementModal = ({
164158
const rootEipId = getEipId(rootId)
165159
const rootEipDef = rootEipId && lookupEipComponent(rootEipId)
166160

167-
const childOptions = rootEipDef && getEipDefinition(rootEipDef, path)
161+
const childOptions = rootEipDef && getChildEipDefinition(rootEipDef, path)
168162

169163
let modalContent: ReactNode
170164
if (childOptions && childOptions.length > 0) {

ui/src/components/config-panel/EipConfigSidePanel.tsx

Lines changed: 2 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,7 @@ import { HeaderPanel } from "@carbon/react"
22
import { useState } from "react"
33
import { Edge, useOnSelectionChange, useStoreApi } from "reactflow"
44
import { DYNAMIC_EDGE_TYPE, DynamicEdge, EipFlowNode } from "../../api/flow"
5-
import {
6-
Attribute,
7-
EipChildElement,
8-
EipComponent,
9-
} from "../../api/generated/eipComponentDef"
5+
import { Attribute } from "../../api/generated/eipComponentDef"
106
import { EipId } from "../../api/generated/eipFlow"
117
import {
128
FLOW_CONTROLLED_ATTRIBUTES,
@@ -18,6 +14,7 @@ import { useGetSelectedChildNode } from "../../singletons/store/getterHooks"
1814
import { getEipId } from "../../singletons/store/storeViews"
1915
import DynamicEdgeConfig from "./DynamicEdgeConfig"
2016
import { ChildNodeConfig, RootNodeConfig } from "./NodeConfigPanel"
17+
import { findChildDefinition } from "./childDefinitions"
2118

2219
const isDynamicRouterAttribute = (attribute: Attribute, eipId?: EipId) => {
2320
if (!eipId) {
@@ -44,25 +41,6 @@ const filterConfigurableAttributes = (attrs?: Attribute[], eipId?: EipId) => {
4441

4542
const isDynamicEdge = (edge: Edge) => edge?.type === DYNAMIC_EDGE_TYPE
4643

47-
// TODO: Should this be a utility method in the EipComponentDef module?
48-
// TODO: Handle invalid path error case
49-
const findChildDefinition = (
50-
rootComponent: EipComponent,
51-
childPath: string[]
52-
) => {
53-
let children = rootComponent.childGroup?.children
54-
let child: EipChildElement | null = null
55-
56-
for (const id of childPath.slice(1)) {
57-
const name = getEipId(id)?.name
58-
child = children?.find((c) => c.name === name) ?? null
59-
children = child?.childGroup?.children
60-
}
61-
62-
return child
63-
}
64-
65-
// TODO: Add breadcrumb menu at the top, showing the path to child.
6644
const EipConfigSidePanel = () => {
6745
const reactFlowStore = useStoreApi()
6846
const [selectedNode, setSelectedNode] = useState<EipFlowNode | null>(null)
@@ -81,7 +59,6 @@ const EipConfigSidePanel = () => {
8159
})
8260

8361
let sidePanelContent
84-
// TODO: Simplify conditionals
8562
if (selectedChildPath) {
8663
// TODO: Handle error case if childElement or rootComponent is undefined
8764
const childId = selectedChildPath[selectedChildPath.length - 1]
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import {
2+
EipChildElement,
3+
EipComponent,
4+
} from "../../api/generated/eipComponentDef"
5+
import { getEipId } from "../../singletons/store/storeViews"
6+
7+
// Searches the root's child tree to find the child definition referenced by 'childPath'
8+
export const findChildDefinition = (
9+
rootEipComponent: EipComponent,
10+
childPath: string[]
11+
) => {
12+
let children = rootEipComponent.childGroup?.children
13+
let child: EipChildElement | null = null
14+
15+
if (childPath.length <= 1) {
16+
return null
17+
}
18+
19+
for (const id of childPath.slice(1)) {
20+
const name = getEipId(id)?.name
21+
child = children?.find((c) => c.name === name) ?? null
22+
children = child?.childGroup?.children
23+
}
24+
25+
return child
26+
}

ui/src/components/toolbar/assistant/AssistantChatPanel.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,6 @@ const ChatHistory = forwardRef<HTMLParagraphElement, ChatHistoryProps>(
128128

129129
ChatHistory.displayName = "ChatHistory"
130130

131-
// TODO: Create a new store action to set nodes/edges directly from object instead of JSON string.
132131
const AssistantChatPanel = () => {
133132
const chatHistoryEndRef = useRef<HTMLParagraphElement | null>(null)
134133
const [chatEntries, setChatEntries] = useState<ChatEntry[]>([])
Lines changed: 35 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,60 +1,52 @@
11
import isDeepEqual from "fast-deep-equal"
22
import { temporal } from "zundo"
33
import { create } from "zustand"
4-
import { createJSONStorage, devtools, persist } from "zustand/middleware"
4+
import { createJSONStorage, persist } from "zustand/middleware"
55
import debounce from "../../utils/debounce"
66

77
import { AppStore } from "./api"
88

99
export const EXPORTED_FLOW_VERSION = "1.0"
1010

1111
// If app becomes too slow, might need to switch to async persistent storage.
12-
// TODO: Remove devtools
1312
export const useAppStore = create<AppStore>()(
14-
devtools(
15-
persist(
16-
temporal(
17-
(_) => ({
18-
nodes: [],
19-
edges: [],
20-
eipConfigs: {},
21-
selectedChildNode: null,
22-
layout: {
23-
orientation: "horizontal",
24-
density: "comfortable",
25-
},
26-
}),
27-
{
28-
limit: 50,
29-
partialize: (state) => {
30-
const newNodes = state.nodes.map((node) => {
31-
const n = { ...node }
32-
const {
33-
selected,
34-
draggable,
35-
dragging,
36-
positionAbsolute,
37-
...rest
38-
} = n
39-
return rest
40-
})
13+
persist(
14+
temporal(
15+
(_) => ({
16+
nodes: [],
17+
edges: [],
18+
eipConfigs: {},
19+
selectedChildNode: null,
20+
layout: {
21+
orientation: "horizontal",
22+
density: "comfortable",
23+
},
24+
}),
25+
{
26+
limit: 50,
27+
partialize: (state) => {
28+
const newNodes = state.nodes.map((node) => {
29+
const n = { ...node }
30+
const { selected, draggable, dragging, positionAbsolute, ...rest } =
31+
n
32+
return rest
33+
})
4134

42-
const { eipConfigs, edges, layout } = state
43-
return { eipConfigs, edges, layout, nodes: newNodes }
44-
},
35+
const { eipConfigs, edges, layout } = state
36+
return { eipConfigs, edges, layout, nodes: newNodes }
37+
},
4538

46-
equality: (pastState, currentState) =>
47-
isDeepEqual(pastState, currentState),
39+
equality: (pastState, currentState) =>
40+
isDeepEqual(pastState, currentState),
4841

49-
handleSet: (handleSet) =>
50-
debounce<typeof handleSet>((state) => handleSet(state), 1000, true),
51-
}
52-
),
53-
{
54-
name: "eipFlow",
55-
version: Number(EXPORTED_FLOW_VERSION.split(".")[0]),
56-
storage: createJSONStorage(() => localStorage),
42+
handleSet: (handleSet) =>
43+
debounce<typeof handleSet>((state) => handleSet(state), 1000, true),
5744
}
58-
)
45+
),
46+
{
47+
name: "eipFlow",
48+
version: Number(EXPORTED_FLOW_VERSION.split(".")[0]),
49+
storage: createJSONStorage(() => localStorage),
50+
}
5951
)
6052
)

ui/src/singletons/store/reactFlowActions.test.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ beforeEach(() => {
1919
})
2020
})
2121

22-
// TODO: test that child node configs are deleted recursively
2322
describe("onNodesChange", () => {
2423
test("top-level config and all child configs are removed when node is deleted", () => {
2524
// assert configs exist before removing node

0 commit comments

Comments
 (0)