({
+ version: "6.4.1",
+ run: (store) => {
+ const welcomeBarEntity = di.inject(welcomeCatalogEntityInjectable);
+
+ const hotbars = (store.get("hotbars") ?? []) as HotbarData[];
+ const firstHotbar = hotbars[0];
+
+ if (!firstHotbar) {
+ return;
+ }
+
+ const hasWelcomePage = Boolean(firstHotbar.items.find((hotbarItem) => hotbarItem?.entity.uid === welcomeBarEntity.metadata.uid));
+ const hasSpaceForWelcomePage = firstHotbar.items.filter(Boolean).length < defaultHotbarCells;
+
+ if (!hasWelcomePage && hasSpaceForWelcomePage) {
+ const welcomePageHotbarItem: HotbarItem = {
+ entity: {
+ uid: welcomeBarEntity.metadata.uid,
+ name: welcomeBarEntity.metadata.name,
+ source: welcomeBarEntity.metadata.source,
+ },
+ };
+
+ const newFirstHotbar: HotbarData = {
+ ...firstHotbar,
+ items: [welcomePageHotbarItem, ...firstHotbar.items.slice(0, -1)],
+ };
+
+ store.set("hotbars", [newFirstHotbar, ...hotbars.slice(1)]);
+ }
+ },
+ }),
+ injectionToken: hotbarStoreMigrationInjectionToken,
+});
+
+export default welcomePageMigration;
diff --git a/packages/core/src/features/hotbar/storage/main/welcome-page-migration.test.ts b/packages/core/src/features/hotbar/storage/main/welcome-page-migration.test.ts
new file mode 100644
index 0000000000..91541f43e3
--- /dev/null
+++ b/packages/core/src/features/hotbar/storage/main/welcome-page-migration.test.ts
@@ -0,0 +1,104 @@
+/**
+ * Copyright (c) OpenLens Authors. All rights reserved.
+ * Licensed under MIT License. See LICENSE in root directory for more information.
+ */
+import welcomeCatalogEntityInjectable from "../../../../common/catalog-entities/general-catalog-entities/implementations/welcome-catalog-entity.injectable";
+import type { MigrationDeclaration, MigrationStore } from "../../../../common/persistent-storage/migrations.injectable";
+import { getDiForUnitTesting } from "../../../../main/getDiForUnitTesting";
+import type { HotbarData } from "../common/hotbar";
+import type { HotbarItem } from "../common/types";
+import v640HotbarStoreMigrationInjectable from "./welcome-page-migration.injectable";
+import { defaultHotbarCells } from "../common/types";
+
+function fillWithEmpties(items: HotbarItem[]) {
+ const emptyHotBarItems = new Array(defaultHotbarCells).fill(null);
+
+ return [...items, ...emptyHotBarItems.slice(items.length)];
+}
+
+function setFirstHotbarItems(store: MigrationStore, items: HotbarItem[]) {
+ const oldHotbars = store.get("hotbars") as HotbarData[];
+ // empty hotbar items are nulls
+ const itemsWithEmptyCells = fillWithEmpties(items);
+
+ store.set("hotbars", [{ ...oldHotbars[0], items: itemsWithEmptyCells }, ...oldHotbars.slice(1)]);
+}
+
+const someItem: HotbarItem = {
+ entity: {
+ uid: "some-item",
+ name: "some-name",
+ source: "some-source",
+ },
+};
+
+describe("hotbar-welcome-page-migration", () => {
+ const di = getDiForUnitTesting();
+ const welcomePageEntity = di.inject(welcomeCatalogEntityInjectable);
+
+ const welcomeHotbarItem: HotbarItem = {
+ entity: {
+ uid: welcomePageEntity.metadata.uid,
+ name: welcomePageEntity.metadata.name,
+ source: welcomePageEntity.metadata.source,
+ },
+ };
+
+ let migration: MigrationDeclaration;
+ let store: MigrationStore;
+ const storeModel = new Map();
+
+ beforeEach(() => {
+ migration = di.inject(v640HotbarStoreMigrationInjectable);
+
+ storeModel.clear();
+
+ const emptyHotbar: HotbarData = {
+ id: "some-id",
+ name: "some-name",
+ items: [],
+ };
+
+ storeModel.set("hotbars", [emptyHotbar]);
+ store = {
+ path: "some-path",
+ get: (key: string) => storeModel.get(key),
+ set: (key: string, value: any) => storeModel.set(key, value),
+ delete: (key: string) => storeModel.delete(key),
+ has: (key: string) => storeModel.has(key),
+ clear: () => storeModel.clear(),
+ };
+ });
+
+ it("given first hotbar is empty, adds welcome page to first place", () => {
+ migration.run(store);
+ expect(storeModel.get("hotbars")[0].items[0]).toEqual(welcomeHotbarItem);
+ });
+
+ it("given first hotbar has items but is not full, adds welcome page to first place", () => {
+ setFirstHotbarItems(store, [someItem]);
+
+ migration.run(store);
+
+ expect(storeModel.get("hotbars")[0].items.slice(0, 2)).toEqual([welcomeHotbarItem, someItem]);
+ });
+
+ it("given first hotbar is full, does not add welcome page", () => {
+ const fullHotbarItems: HotbarItem[] = Array(defaultHotbarCells).fill(someItem);
+
+ setFirstHotbarItems(store, fullHotbarItems);
+
+ migration.run(store);
+
+ expect(storeModel.get("hotbars")[0].items).toEqual(fullHotbarItems);
+ expect(storeModel.get("hotbars")[0].items).not.toContain(welcomeHotbarItem);
+ });
+
+ it("given first hotbar has already welcome page, does not add welcome page", () => {
+ const hotBarItemsWithWelcomePage = fillWithEmpties([someItem, welcomeHotbarItem, someItem]);
+
+ setFirstHotbarItems(store, hotBarItemsWithWelcomePage);
+ migration.run(store);
+ expect(storeModel.get("hotbars")[0].items).toEqual(hotBarItemsWithWelcomePage);
+ });
+});
diff --git a/packages/core/src/features/hotbar/storage/storage-technical.test.ts b/packages/core/src/features/hotbar/storage/storage-technical.test.ts
index 59119147bc..e7a74d362a 100644
--- a/packages/core/src/features/hotbar/storage/storage-technical.test.ts
+++ b/packages/core/src/features/hotbar/storage/storage-technical.test.ts
@@ -154,21 +154,26 @@ describe("Hotbars technical tests", () => {
expect(activeHotbar.get()?.items?.length).toEqual(defaultHotbarCells);
});
- it("initially adds catalog entity as first item", () => {
- expect(activeHotbar.get()?.items[0]?.entity.name).toEqual("Catalog");
+ it("initially adds welcome page entity as first item", () => {
+ expect(activeHotbar.get()?.items[0]?.entity.name).toEqual("Welcome Page");
+ });
+
+ it("initially adds catalog entity as second item", () => {
+ expect(activeHotbar.get()?.items[1]?.entity.name).toEqual("Catalog");
});
it("adds items", () => {
activeHotbar.get()?.addEntity(testCluster);
const items = activeHotbar.get()?.items.filter(Boolean);
- expect(items?.length).toEqual(2);
+ expect(items?.length).toEqual(3);
});
it("removes items", () => {
activeHotbar.get()?.addEntity(testCluster);
activeHotbar.get()?.removeEntity("some-test-id");
activeHotbar.get()?.removeEntity("catalog-entity");
+ activeHotbar.get()?.removeEntity("welcome-page-entity");
const items = activeHotbar.get()?.items.filter(Boolean);
expect(items).toStrictEqual([]);
@@ -179,7 +184,7 @@ describe("Hotbars technical tests", () => {
activeHotbar.get()?.removeEntity("invalid uid");
const items = activeHotbar.get()?.items.filter(Boolean);
- expect(items?.length).toEqual(2);
+ expect(items?.length).toEqual(3);
});
it("moves item to empty cell", () => {
@@ -189,7 +194,7 @@ describe("Hotbars technical tests", () => {
expect(activeHotbar.get()?.items[6]).toBeNull();
- activeHotbar.get()?.restack(1, 5);
+ activeHotbar.get()?.restack(2, 5);
expect(activeHotbar.get()?.items[5]).toBeTruthy();
expect(activeHotbar.get()?.items[5]?.entity.uid).toEqual("some-test-id");
@@ -201,11 +206,11 @@ describe("Hotbars technical tests", () => {
activeHotbar.get()?.addEntity(awsCluster);
// aws -> catalog
- activeHotbar.get()?.restack(3, 0);
+ activeHotbar.get()?.restack(4, 0);
const items = activeHotbar.get()?.items.map(item => item?.entity.uid || null);
- expect(items?.slice(0, 4)).toEqual(["some-aws-id", "catalog-entity", "some-test-id", "some-minikube-id"]);
+ expect(items?.slice(0, 5)).toEqual(["some-aws-id", "welcome-page-entity", "catalog-entity", "some-test-id", "some-minikube-id"]);
});
it("moves items up", () => {
@@ -214,11 +219,11 @@ describe("Hotbars technical tests", () => {
activeHotbar.get()?.addEntity(awsCluster);
// test -> aws
- activeHotbar.get()?.restack(1, 3);
+ activeHotbar.get()?.restack(2, 4);
const items = activeHotbar.get()?.items.map(item => item?.entity.uid || null);
- expect(items?.slice(0, 4)).toEqual(["catalog-entity", "some-minikube-id", "some-aws-id", "some-test-id"]);
+ expect(items?.slice(0, 5)).toEqual(["welcome-page-entity", "catalog-entity", "some-minikube-id", "some-aws-id", "some-test-id"]);
});
it("logs an error if cellIndex is out of bounds", () => {
@@ -247,15 +252,15 @@ describe("Hotbars technical tests", () => {
it("does nothing when item moved to same cell", () => {
activeHotbar.get()?.addEntity(testCluster);
- activeHotbar.get()?.restack(1, 1);
+ activeHotbar.get()?.restack(2, 2);
- expect(activeHotbar.get()?.items[1]?.entity.uid).toEqual("some-test-id");
+ expect(activeHotbar.get()?.items[2]?.entity.uid).toEqual("some-test-id");
});
it("new items takes first empty cell", () => {
activeHotbar.get()?.addEntity(testCluster);
activeHotbar.get()?.addEntity(awsCluster);
- activeHotbar.get()?.restack(0, 3);
+ activeHotbar.get()?.restack(0, 4);
activeHotbar.get()?.addEntity(minikubeCluster);
expect(activeHotbar.get()?.items[0]?.entity.uid).toEqual("some-minikube-id");
diff --git a/packages/core/src/features/preferences/__snapshots__/closing-preferences.test.tsx.snap b/packages/core/src/features/preferences/__snapshots__/closing-preferences.test.tsx.snap
index 1efecc48af..36d8787bb7 100644
--- a/packages/core/src/features/preferences/__snapshots__/closing-preferences.test.tsx.snap
+++ b/packages/core/src/features/preferences/__snapshots__/closing-preferences.test.tsx.snap
@@ -557,6 +557,26 @@ exports[`preferences - closing-preferences given accessing preferences directly
>
+
+
+