diff --git a/packages/core/src/common/vars/store-migration-version.injectable.ts b/packages/core/src/common/vars/store-migration-version.injectable.ts index 37169463ae..18ffb08af1 100644 --- a/packages/core/src/common/vars/store-migration-version.injectable.ts +++ b/packages/core/src/common/vars/store-migration-version.injectable.ts @@ -6,7 +6,7 @@ import { getInjectable } from "@ogre-tools/injectable"; const storeMigrationVersionInjectable = getInjectable({ id: "store-migration-version", - instantiate: () => "6.4.0", + instantiate: () => "6.5.0", }); export default storeMigrationVersionInjectable; diff --git a/packages/core/src/features/__snapshots__/extension-special-characters-in-page-registrations.test.tsx.snap b/packages/core/src/features/__snapshots__/extension-special-characters-in-page-registrations.test.tsx.snap index c8d7297e7a..f6a4f60fee 100644 --- a/packages/core/src/features/__snapshots__/extension-special-characters-in-page-registrations.test.tsx.snap +++ b/packages/core/src/features/__snapshots__/extension-special-characters-in-page-registrations.test.tsx.snap @@ -168,6 +168,26 @@ exports[`extension special characters in page registrations renders 1`] = ` >
+
+
+ WP +
+
+
+ +
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
({ + 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 >
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
+
+
+ WP +
+
+
+
+
+
-
when StatusBar's status is set to "error" renders 1`] = ` >
+
+
+ WP +
+
+
+
+
+
when StatusBar's status is set to "error" renders 1`] = `
-
when StatusBar's status is set to "warning" renders 1`] = >
+
+
+ WP +
+
+
+
+
+
when StatusBar's status is set to "warning" renders 1`] =
-
when an extension is enabled specifying the side the elem >
+
+
+ WP +
+
+
+
+
+
when an extension is enabled specifying the side the elem
-
when an extension is enabled with an invalid data type, ( >
+
+
+ WP +
+
+
+
+
+
when an extension is enabled with an invalid data type, (
-
when an extension is enabled with an invalid data type, ( >
+
+
+ WP +
+
+
+
+
+
when an extension is enabled with an invalid data type, (
-
when an extension is enabled with an invalid data type, ( >
+
+
+ WP +
+
+
+
+
+
when an extension is enabled with an invalid data type, (
-
when an extension is enabled with an invalid data type, ( >
+
+
+ WP +
+
+
+
+
+
when an extension is enabled with an invalid data type, (
-
when an extension is enabled with an invalid data type, ( >
+
+
+ WP +
+
+
+
+
+
when an extension is enabled with an invalid data type, (
-
when an extension is enabled with an invalid data type, ( >
+
+
+ WP +
+
+
+
+
+
when an extension is enabled with an invalid data type, (
-
when an extension is enabled with an invalid data type, ( >
+
+
+ WP +
+
+
+
+
+
when an extension is enabled with an invalid data type, (
-
when an extension is enabled with no status items renders >
+
+
+ WP +
+
+
+
+
+
when an extension is enabled with no status items renders
-