From 0ecf00ed0394887063c85f36ea5ccc9db012c0a9 Mon Sep 17 00:00:00 2001 From: Alex Andreev Date: Wed, 1 Feb 2023 13:29:22 +0300 Subject: [PATCH] Expand and collapse tree nodes Signed-off-by: Alex Andreev --- .../namespace-tree-view.test.tsx.snap | 210 ++++++++++++++++++ .../+namespaces/namespace-tree-view.test.tsx | 13 +- .../+namespaces/namespace-tree-view.tsx | 28 ++- 3 files changed, 247 insertions(+), 4 deletions(-) diff --git a/packages/core/src/renderer/components/+namespaces/__snapshots__/namespace-tree-view.test.tsx.snap b/packages/core/src/renderer/components/+namespaces/__snapshots__/namespace-tree-view.test.tsx.snap index 67a8d75393..67d45e7b34 100644 --- a/packages/core/src/renderer/components/+namespaces/__snapshots__/namespace-tree-view.test.tsx.snap +++ b/packages/core/src/renderer/components/+namespaces/__snapshots__/namespace-tree-view.test.tsx.snap @@ -1,5 +1,211 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[` once the subscribe resolves collapses item by clicking minus button 1`] = ` + +
+
+
+ Tree View +
+
    +
  • +
    +
    + +
    +
    + levels-deep +
    +
    +
      +
      +
      +
    • +
      +
      + +
      +
      + level-deep-child-a + +
      +
      +
        +
        +
        +
        +
      +
    • + +
      +
      +
    +
  • +
+
+
+ +`; + exports[` once the subscribe resolves renders 2 levels deep 1`] = `
@@ -32,6 +238,7 @@ exports[` once the subscribe resolves renders 2 levels deep once the subscribe resolves renders 2 levels deep once the subscribe resolves renders namespace wit once the subscribe resolves renders namespace wit ", () => { expect(result.baseElement).toMatchSnapshot(); }); - it("expands children items", () => { + it("expands children items by default", () => { const result = render(); const deepest = result.getByTestId("namespace-level-deep-child-b-1"); expect(deepest).toHaveAttribute("aria-expanded", "true"); }); + + it("collapses item by clicking minus button", () => { + const result = render(); + const levelB = result.getByTestId("namespace-level-deep-child-b-1"); + const minusButton = levelB.querySelector("[data-testid='minus-square']"); + + fireEvent.click(minusButton!); + + expect(result.baseElement).toMatchSnapshot(); + }); }); }); \ No newline at end of file diff --git a/packages/core/src/renderer/components/+namespaces/namespace-tree-view.tsx b/packages/core/src/renderer/components/+namespaces/namespace-tree-view.tsx index a7ceb3c933..1cbd52ecef 100644 --- a/packages/core/src/renderer/components/+namespaces/namespace-tree-view.tsx +++ b/packages/core/src/renderer/components/+namespaces/namespace-tree-view.tsx @@ -20,9 +20,15 @@ interface Dependencies { getDetailsUrl: GetDetailsUrl; } +function isNamespaceControlledByHNC(namespace: Namespace) { + const hierarchicalNamesaceControllerLabel = "hnc.x-k8s.io/included-namespace=true"; + + return namespace.getLabels().find(label => label === hierarchicalNamesaceControllerLabel); +} + function NonInjectableNamespaceTreeView({ root, namespaceStore, getDetailsUrl }: Dependencies & NamespaceTreeViewProps) { const hierarchicalNamespaces = namespaceStore.getByLabel(["hnc.x-k8s.io/included-namespace=true"]); - const expandedItems = hierarchicalNamespaces.map(ns => `namespace-${ns.getId()}`); + const [expandedItems, setExpandedItems] = React.useState(hierarchicalNamespaces.map(ns => `namespace-${ns.getId()}`)); function renderChildren(parent: Namespace) { const children = hierarchicalNamespaces.filter(ns => @@ -34,6 +40,10 @@ function NonInjectableNamespaceTreeView({ root, namespaceStore, getDetailsUrl }: key={`namespace-${child.getId()}`} nodeId={`namespace-${child.getId()}`} data-testid={`namespace-${child.getId()}`} + onIconClick={(evt) =>{ + toggleNode(`namespace-${child.getId()}`) + evt.stopPropagation(); + }} label={( <> @@ -49,7 +59,15 @@ function NonInjectableNamespaceTreeView({ root, namespaceStore, getDetailsUrl }: )); } - if (!root.getLabels().find(label => label === "hnc.x-k8s.io/included-namespace=true")) { + function toggleNode(id: string) { + if (expandedItems.includes(id)) { + setExpandedItems(expandedItems.filter(item => item !== id)); + } else { + setExpandedItems([...expandedItems, id]); + } + } + + if (!isNamespaceControlledByHNC(root)) { return null; } @@ -67,6 +85,10 @@ function NonInjectableNamespaceTreeView({ root, namespaceStore, getDetailsUrl }: nodeId={`namespace-${root.getId()}`} label={root.getName()} data-testid={`namespace-${root.getId()}`} + onIconClick={(evt) => { + toggleNode(`namespace-${root.getId()}`); + evt.stopPropagation(); + }} > {renderChildren(root)} @@ -77,7 +99,7 @@ function NonInjectableNamespaceTreeView({ root, namespaceStore, getDetailsUrl }: function MinusSquare() { return ( - + );