From 88bf456cea2a381c8a53691957c7a824940fe5e0 Mon Sep 17 00:00:00 2001
From: Iku-turso
Date: Fri, 14 Apr 2023 15:50:04 +0300
Subject: [PATCH] Feat: Implement rendering of dock tab content
Signed-off-by: Iku-turso
Co-authored-by: Janne Savolainen
Signed-off-by: Iku-turso
---
.../dock/src/__snapshots__/dock.test.tsx.snap | 59 ++++++++++++++++--
.../business-features/dock/src/dock.test.tsx | 62 ++++++++++++++++---
.../src/dock/activate-dock-tab.injectable.ts | 19 ++++++
.../src/dock/active-dock-tab-id.injectable.ts | 9 +++
.../src/dock/active-dock-tab.injectable.ts | 30 ++++++---
.../dock/src/dock/dock-host.tsx | 8 +--
.../src/dock/dock-tabs-types.injectable.ts | 15 +++++
.../dock/src/dock/dock-tabs.injectable.ts | 21 +++++--
.../business-features/dock/src/dock/tabs.tsx | 9 ++-
9 files changed, 194 insertions(+), 38 deletions(-)
create mode 100644 packages/business-features/dock/src/dock/activate-dock-tab.injectable.ts
create mode 100644 packages/business-features/dock/src/dock/active-dock-tab-id.injectable.ts
create mode 100644 packages/business-features/dock/src/dock/dock-tabs-types.injectable.ts
diff --git a/packages/business-features/dock/src/__snapshots__/dock.test.tsx.snap b/packages/business-features/dock/src/__snapshots__/dock.test.tsx.snap
index 856251be46..bbf89358a7 100644
--- a/packages/business-features/dock/src/__snapshots__/dock.test.tsx.snap
+++ b/packages/business-features/dock/src/__snapshots__/dock.test.tsx.snap
@@ -7,19 +7,68 @@ exports[`DockHost, given rendered given implementations of dock tabs emerge rend
-
+
- Some title
+ Some title 1
+
+
+
- Some content
+ Some content 1
+
+
+
+
+
+
+
diff --git a/packages/business-features/dock/src/dock.test.tsx b/packages/business-features/dock/src/dock.test.tsx
index 01e81f138d..d54c85663b 100644
--- a/packages/business-features/dock/src/dock.test.tsx
+++ b/packages/business-features/dock/src/dock.test.tsx
@@ -4,6 +4,7 @@ import { renderFor } from "@k8slens/test-utils";
import { DockHost } from "./dock/dock-host";
import React from "react";
import type { RenderResult } from "@testing-library/react";
+import { act } from "@testing-library/react";
import { dockTabInjectionToken } from "./dock-tab";
import { Discover, discoverFor } from "@k8slens/react-testing-library-discovery";
import { registerFeature } from "@k8slens/feature-core";
@@ -31,20 +32,38 @@ describe("DockHost, given rendered", () => {
describe("given implementations of dock tabs emerge", () => {
beforeEach(() => {
- const dockTabInjectable = getInjectable({
- id: "some-dock-tab",
+ const dockTabInjectable1 = getInjectable({
+ id: "some-dock-tab-1",
instantiate: () => ({
- id: "some-dock-tab",
- TitleComponent: () =>
Some title
,
- ContentComponent: () =>
Some content
,
+ id: "some-dock-tab-1",
+ TitleComponent: () =>
Some title 1
,
+
+ ContentComponent: () => (
+
Some content 1
+ ),
+ }),
+
+ injectionToken: dockTabInjectionToken,
+ });
+
+ const dockTabInjectable2 = getInjectable({
+ id: "some-dock-tab-2",
+
+ instantiate: () => ({
+ id: "some-dock-tab-2",
+ TitleComponent: () =>
Some title 2
,
+
+ ContentComponent: () => (
+
Some content 2
+ ),
}),
injectionToken: dockTabInjectionToken,
});
runInAction(() => {
- di.register(dockTabInjectable);
+ di.register(dockTabInjectable1, dockTabInjectable2);
});
});
@@ -52,12 +71,35 @@ describe("DockHost, given rendered", () => {
expect(rendered.baseElement).toMatchSnapshot();
});
- it("renders the title of dock tab", () => {
- discover.getSingleElement("some-dock-tab-title");
+ it("renders the titles of all the dock tabs in order", () => {
+ expect(discover.queryAllElements("dock-tab-title").attributeValues).toEqual([
+ "some-title-1",
+ "some-title-2",
+ ]);
});
- it("renders the content of the dock tab", () => {
- discover.getSingleElement("some-dock-tab-content");
+ it("renders only the content of the first dock tab", () => {
+ expect(discover.queryAllElements("dock-tab-content").attributeValues).toEqual([
+ "some-content-1",
+ ]);
+ });
+
+ describe("when the second dock tab is clicked", () => {
+ beforeEach(() => {
+ act(() => {
+ discover.getSingleElement("dock-tab", "some-dock-tab-2").click();
+ });
+ });
+
+ it("renders", () => {
+ expect(rendered.baseElement).toMatchSnapshot();
+ });
+
+ it("renders only the content of the second dock tab", () => {
+ expect(discover.queryAllElements("dock-tab-content").attributeValues).toEqual([
+ "some-content-2",
+ ]);
+ });
});
});
});
diff --git a/packages/business-features/dock/src/dock/activate-dock-tab.injectable.ts b/packages/business-features/dock/src/dock/activate-dock-tab.injectable.ts
new file mode 100644
index 0000000000..80d68e103a
--- /dev/null
+++ b/packages/business-features/dock/src/dock/activate-dock-tab.injectable.ts
@@ -0,0 +1,19 @@
+import { getInjectable, lifecycleEnum } from "@ogre-tools/injectable";
+import { action } from "mobx";
+import activeDockTabIdInjectable from "./active-dock-tab-id.injectable";
+
+const activateDockTabInjectable = getInjectable({
+ id: "activate-dock-tab",
+
+ instantiate: (di, tabId) => {
+ const activeDockTabId = di.inject(activeDockTabIdInjectable);
+
+ return action(() => activeDockTabId.set(tabId));
+ },
+
+ lifecycle: lifecycleEnum.keyedSingleton({
+ getInstanceKey: (di, tabId: string) => tabId,
+ }),
+});
+
+export default activateDockTabInjectable;
diff --git a/packages/business-features/dock/src/dock/active-dock-tab-id.injectable.ts b/packages/business-features/dock/src/dock/active-dock-tab-id.injectable.ts
new file mode 100644
index 0000000000..e689fae9b1
--- /dev/null
+++ b/packages/business-features/dock/src/dock/active-dock-tab-id.injectable.ts
@@ -0,0 +1,9 @@
+import { getInjectable } from "@ogre-tools/injectable";
+import { observable } from "mobx";
+
+const activeDockTabIdInjectable = getInjectable({
+ id: "active-dock-tab-id",
+ instantiate: () => observable.box
(),
+});
+
+export default activeDockTabIdInjectable;
diff --git a/packages/business-features/dock/src/dock/active-dock-tab.injectable.ts b/packages/business-features/dock/src/dock/active-dock-tab.injectable.ts
index fd1fc5f517..02d634eabf 100644
--- a/packages/business-features/dock/src/dock/active-dock-tab.injectable.ts
+++ b/packages/business-features/dock/src/dock/active-dock-tab.injectable.ts
@@ -1,23 +1,33 @@
import { getInjectable } from "@ogre-tools/injectable";
import { computed } from "mobx";
-import dockTabsInjectable from "./dock-tabs.injectable";
+import activeDockTabIdInjectable from "./active-dock-tab-id.injectable";
+import { pipeline } from "@ogre-tools/fp";
+import { defaults, find, first } from "lodash/fp";
+import type { DockTab } from "../dock-tab";
+import dockTabTypesInjectable from "./dock-tabs-types.injectable";
+
+const nullTab: DockTab = {
+ id: "no-active-dock-tab",
+ TitleComponent: () => null,
+ ContentComponent: () => null,
+};
const activeDockTabInjectable = getInjectable({
id: "active-dock-tab",
instantiate: (di) => {
- const dockTabs = di.inject(dockTabsInjectable);
+ const dockTabTypes = di.inject(dockTabTypesInjectable);
+ const activeDockTabId = di.inject(activeDockTabIdInjectable);
return computed(() => {
- const [
- activeDockTab = {
- id: "no-active-dock-tab",
- TitleComponent: () => null,
- ContentComponent: () => null,
- },
- ] = dockTabs.get();
+ const tabs = dockTabTypes.get();
- return activeDockTab;
+ return pipeline(
+ tabs,
+ find((tab) => tab.id === activeDockTabId.get()),
+ defaults(first(tabs)),
+ defaults(nullTab),
+ );
});
},
});
diff --git a/packages/business-features/dock/src/dock/dock-host.tsx b/packages/business-features/dock/src/dock/dock-host.tsx
index f2250c2c9d..47709e5800 100644
--- a/packages/business-features/dock/src/dock/dock-host.tsx
+++ b/packages/business-features/dock/src/dock/dock-host.tsx
@@ -4,7 +4,7 @@ import { withInjectables } from "@ogre-tools/injectable-react";
import React from "react";
import { Tabs } from "./tabs";
import { Div, Map } from "@k8slens/ui-components";
-import dockTabsInjectable from "./dock-tabs.injectable";
+import dockTabsInjectable, { ActivatableDockTab } from "./dock-tabs.injectable";
import type { DockTab } from "../dock-tab";
import activeDockTabInjectable from "./active-dock-tab.injectable";
@@ -15,8 +15,8 @@ const NonInjectedDockHost = observer(({ dockTabs, activeDockTab }: Dependencies)