diff --git a/src/behaviours/helm-charts/__snapshots__/activate-helm-repository-from-list-in-preferences.test.ts.snap b/src/behaviours/helm-charts/__snapshots__/activate-helm-repository-from-list-in-preferences.test.ts.snap
new file mode 100644
index 0000000000..33cb389643
--- /dev/null
+++ b/src/behaviours/helm-charts/__snapshots__/activate-helm-repository-from-list-in-preferences.test.ts.snap
@@ -0,0 +1,5211 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`activate helm repository from list in preferences when navigating to preferences containing helm repositories renders 1`] = `
+
+
+
+
+
+
+
+
+
+ Kubernetes
+
+
+
+ Kubectl binary download
+
+
+
+
+
+
+ Download mirror
+
+
+
+
+
+
+
+
+ Download mirror for kubectl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Directory for binaries
+
+
+
+
+
+
+
+ The directory to download binaries into.
+
+
+
+
+ Path to kubectl binary
+
+
+
+
+
+
+
+
+
+
+
+ Kubeconfig Syncs
+
+
+
+
+
+ Synced Items
+
+
+
+
+ No files and folders have been synced yet
+
+
+
+
+
+
+ Helm Charts
+
+
+
+
+
+
+
+
+
+ Repositories
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Repositories
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ close
+
+
+
+
+ ESC
+
+
+
+
+
+
+
+
+
+`;
+
+exports[`activate helm repository from list in preferences when navigating to preferences containing helm repositories when both active and public repositories resolve renders 1`] = `
+
+
+
+
+
+
+
+
+
+ Kubernetes
+
+
+
+ Kubectl binary download
+
+
+
+
+
+
+ Download mirror
+
+
+
+
+
+
+
+
+ Download mirror for kubectl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Directory for binaries
+
+
+
+
+
+
+
+ The directory to download binaries into.
+
+
+
+
+ Path to kubectl binary
+
+
+
+
+
+
+
+
+
+
+
+ Kubeconfig Syncs
+
+
+
+
+
+ Synced Items
+
+
+
+
+ No files and folders have been synced yet
+
+
+
+
+
+
+ Helm Charts
+
+
+
+
+
+
+
+
+
+ Repositories
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Repositories
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Some already active repository
+
+
+ some-url
+
+
+
+
+
+
+
+
+
+
+
+
+
+ close
+
+
+
+
+ ESC
+
+
+
+
+
+
+
+
+
+`;
+
+exports[`activate helm repository from list in preferences when navigating to preferences containing helm repositories when both active and public repositories resolve when select for selecting active repositories is clicked renders 1`] = `
+
+
+
+
+
+
+
+
+
+ Kubernetes
+
+
+
+ Kubectl binary download
+
+
+
+
+
+
+ Download mirror
+
+
+
+
+
+
+
+
+ Download mirror for kubectl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Directory for binaries
+
+
+
+
+
+
+
+ The directory to download binaries into.
+
+
+
+
+ Path to kubectl binary
+
+
+
+
+
+
+
+
+
+
+
+ Kubeconfig Syncs
+
+
+
+
+
+ Synced Items
+
+
+
+
+ No files and folders have been synced yet
+
+
+
+
+
+
+ Helm Charts
+
+
+
+
+
+
+
+
+
+ Repositories
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Repositories
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Some already active repository
+
+
+ some-url
+
+
+
+
+
+
+
+
+
+
+
+
+
+ close
+
+
+
+
+ ESC
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Some already active repository
+
+
+
+ check
+
+
+
+
+
+
+
+ Some to be activated repository
+
+
+
+
+
+
+
+`;
+
+exports[`activate helm repository from list in preferences when navigating to preferences containing helm repositories when both active and public repositories resolve when select for selecting active repositories is clicked when deactive public repository is selected renders 1`] = `
+
+
+
+
+
+
+
+
+
+ Kubernetes
+
+
+
+ Kubectl binary download
+
+
+
+
+
+
+ Download mirror
+
+
+
+
+
+
+
+
+ Download mirror for kubectl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Directory for binaries
+
+
+
+
+
+
+
+ The directory to download binaries into.
+
+
+
+
+ Path to kubectl binary
+
+
+
+
+
+
+
+
+
+
+
+ Kubeconfig Syncs
+
+
+
+
+
+ Synced Items
+
+
+
+
+ No files and folders have been synced yet
+
+
+
+
+
+
+ Helm Charts
+
+
+
+
+
+
+
+
+
+ Repositories
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Repositories
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Some already active repository
+
+
+ some-url
+
+
+
+
+
+
+
+
+
+
+
+
+
+ close
+
+
+
+
+ ESC
+
+
+
+
+
+
+
+
+
+`;
+
+exports[`activate helm repository from list in preferences when navigating to preferences containing helm repositories when both active and public repositories resolve when select for selecting active repositories is clicked when deactive public repository is selected when activating resolves renders 1`] = `
+
+
+
+
+
+
+
+
+
+ Kubernetes
+
+
+
+ Kubectl binary download
+
+
+
+
+
+
+ Download mirror
+
+
+
+
+
+
+
+
+ Download mirror for kubectl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Directory for binaries
+
+
+
+
+
+
+
+ The directory to download binaries into.
+
+
+
+
+ Path to kubectl binary
+
+
+
+
+
+
+
+
+
+
+
+ Kubeconfig Syncs
+
+
+
+
+
+ Synced Items
+
+
+
+
+ No files and folders have been synced yet
+
+
+
+
+
+
+ Helm Charts
+
+
+
+
+
+
+
+
+
+ Repositories
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Repositories
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ close
+
+
+
+
+ ESC
+
+
+
+
+
+
+
+
+
+`;
+
+exports[`activate helm repository from list in preferences when navigating to preferences containing helm repositories when both active and public repositories resolve when select for selecting active repositories is clicked when deactive public repository is selected when activating resolves when active repositories resolve again renders 1`] = `
+
+
+
+
+
+
+
+
+
+ Kubernetes
+
+
+
+ Kubectl binary download
+
+
+
+
+
+
+ Download mirror
+
+
+
+
+
+
+
+
+ Download mirror for kubectl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Directory for binaries
+
+
+
+
+
+
+
+ The directory to download binaries into.
+
+
+
+
+ Path to kubectl binary
+
+
+
+
+
+
+
+
+
+
+
+ Kubeconfig Syncs
+
+
+
+
+
+ Synced Items
+
+
+
+
+ No files and folders have been synced yet
+
+
+
+
+
+
+ Helm Charts
+
+
+
+
+
+
+
+
+
+ Repositories
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Repositories
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Some already active repository
+
+
+ some-url
+
+
+
+
+ Some to be activated repository
+
+
+ some-other-url
+
+
+
+
+
+
+
+
+
+
+
+
+
+ close
+
+
+
+
+ ESC
+
+
+
+
+
+
+
+
+
+`;
+
+exports[`activate helm repository from list in preferences when navigating to preferences containing helm repositories when both active and public repositories resolve when select for selecting active repositories is clicked when deactive public repository is selected when activating resolves when active repositories resolve again when select for selecting active repositories is clicked renders 1`] = `
+
+
+
+
+
+
+
+
+
+ Kubernetes
+
+
+
+ Kubectl binary download
+
+
+
+
+
+
+ Download mirror
+
+
+
+
+
+
+
+
+ Download mirror for kubectl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Directory for binaries
+
+
+
+
+
+
+
+ The directory to download binaries into.
+
+
+
+
+ Path to kubectl binary
+
+
+
+
+
+
+
+
+
+
+
+ Kubeconfig Syncs
+
+
+
+
+
+ Synced Items
+
+
+
+
+ No files and folders have been synced yet
+
+
+
+
+
+
+ Helm Charts
+
+
+
+
+
+
+
+
+
+ Repositories
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Repositories
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Some already active repository
+
+
+ some-url
+
+
+
+
+ Some to be activated repository
+
+
+ some-other-url
+
+
+
+
+
+
+
+
+
+
+
+
+
+ close
+
+
+
+
+ ESC
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Some already active repository
+
+
+
+ check
+
+
+
+
+
+
+
+ Some to be activated repository
+
+
+
+ check
+
+
+
+
+
+
+
+
+`;
+
+exports[`activate helm repository from list in preferences when navigating to preferences containing helm repositories when both active and public repositories resolve when select for selecting active repositories is clicked when deactive public repository is selected when activating resolves when active repositories resolve again when select for selecting active repositories is clicked when active repository is selected renders 1`] = `
+
+
+
+
+
+
+
+
+
+ Kubernetes
+
+
+
+ Kubectl binary download
+
+
+
+
+
+
+ Download mirror
+
+
+
+
+
+
+
+
+ Download mirror for kubectl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Directory for binaries
+
+
+
+
+
+
+
+ The directory to download binaries into.
+
+
+
+
+ Path to kubectl binary
+
+
+
+
+
+
+
+
+
+
+
+ Kubeconfig Syncs
+
+
+
+
+
+ Synced Items
+
+
+
+
+ No files and folders have been synced yet
+
+
+
+
+
+
+ Helm Charts
+
+
+
+
+
+
+
+
+
+ Repositories
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Repositories
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Some already active repository
+
+
+ some-url
+
+
+
+
+ Some to be activated repository
+
+
+ some-other-url
+
+
+
+
+
+
+
+
+
+
+
+
+
+ close
+
+
+
+
+ ESC
+
+
+
+
+
+
+
+
+
+`;
+
+exports[`activate helm repository from list in preferences when navigating to preferences containing helm repositories when both active and public repositories resolve when select for selecting active repositories is clicked when deactive public repository is selected when activating resolves when active repositories resolve again when select for selecting active repositories is clicked when active repository is selected when deactivating resolves renders 1`] = `
+
+
+
+
+
+
+
+
+
+ Kubernetes
+
+
+
+ Kubectl binary download
+
+
+
+
+
+
+ Download mirror
+
+
+
+
+
+
+
+
+ Download mirror for kubectl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Directory for binaries
+
+
+
+
+
+
+
+ The directory to download binaries into.
+
+
+
+
+ Path to kubectl binary
+
+
+
+
+
+
+
+
+
+
+
+ Kubeconfig Syncs
+
+
+
+
+
+ Synced Items
+
+
+
+
+ No files and folders have been synced yet
+
+
+
+
+
+
+ Helm Charts
+
+
+
+
+
+
+
+
+
+ Repositories
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Repositories
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ close
+
+
+
+
+ ESC
+
+
+
+
+
+
+
+
+
+`;
diff --git a/src/behaviours/helm-charts/activate-helm-repository-from-list-in-preferences.test.ts b/src/behaviours/helm-charts/activate-helm-repository-from-list-in-preferences.test.ts
new file mode 100644
index 0000000000..80029efd78
--- /dev/null
+++ b/src/behaviours/helm-charts/activate-helm-repository-from-list-in-preferences.test.ts
@@ -0,0 +1,218 @@
+/**
+ * Copyright (c) OpenLens Authors. All rights reserved.
+ * Licensed under MIT License. See LICENSE in root directory for more information.
+ */
+import type { RenderResult } from "@testing-library/react";
+import type { ApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder";
+import { getApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder";
+import type { AsyncFnMock } from "@async-fn/jest";
+import asyncFn from "@async-fn/jest";
+import execFileInjectable from "../../common/fs/exec-file.injectable";
+import helmBinaryPathInjectable from "../../main/helm/helm-binary-path.injectable";
+import getActiveHelmRepositoriesInjectable from "../../main/helm/repositories/get-active-helm-repositories/get-active-helm-repositories.injectable";
+import type { HelmRepo } from "../../common/helm-repo";
+import callForPublicHelmRepositoriesInjectable from "../../renderer/components/+preferences/kubernetes/helm-charts/activation-of-public-helm-repository/public-helm-repositories/call-for-public-helm-repositories.injectable";
+
+describe("activate helm repository from list in preferences", () => {
+ let applicationBuilder: ApplicationBuilder;
+ let rendered: RenderResult;
+ let execFileMock: AsyncFnMock<
+ ReturnType
+ >;
+ let getActiveHelmRepositoriesMock: AsyncFnMock<() => Promise>;
+ let callForPublicHelmRepositoriesMock: AsyncFnMock<() => Promise>;
+
+ beforeEach(async () => {
+ applicationBuilder = getApplicationBuilder();
+
+ execFileMock = asyncFn();
+ getActiveHelmRepositoriesMock = asyncFn();
+ callForPublicHelmRepositoriesMock = asyncFn();
+
+ applicationBuilder.beforeApplicationStart(({ mainDi, rendererDi }) => {
+ rendererDi.override(
+ callForPublicHelmRepositoriesInjectable,
+ () => callForPublicHelmRepositoriesMock,
+ );
+
+ mainDi.override(
+ getActiveHelmRepositoriesInjectable,
+ () => getActiveHelmRepositoriesMock,
+ );
+ mainDi.override(execFileInjectable, () => execFileMock);
+ mainDi.override(helmBinaryPathInjectable, () => "some-helm-binary-path");
+ });
+
+ rendered = await applicationBuilder.render();
+ });
+
+ describe("when navigating to preferences containing helm repositories", () => {
+ beforeEach(async () => {
+ applicationBuilder.preferences.navigate();
+ applicationBuilder.preferences.navigation.click("kubernetes");
+ });
+
+ it("renders", () => {
+ expect(rendered.baseElement).toMatchSnapshot();
+ });
+
+ it("calls for public repositories", () => {
+ expect(callForPublicHelmRepositoriesMock).toHaveBeenCalled();
+ });
+
+ it("calls for active repositories", () => {
+ expect(getActiveHelmRepositoriesMock).toHaveBeenCalled();
+ });
+
+ describe("when both active and public repositories resolve", () => {
+ beforeEach(async () => {
+ await Promise.all([
+ callForPublicHelmRepositoriesMock.resolve([
+ { name: "Some already active repository", url: "some-url" },
+ { name: "Some to be activated repository", url: "some-other-url" },
+ ]),
+
+ getActiveHelmRepositoriesMock.resolve([
+ { name: "Some already active repository", url: "some-url" },
+ ]),
+ ]);
+ });
+
+ it("renders", () => {
+ expect(rendered.baseElement).toMatchSnapshot();
+ });
+
+ describe("when select for selecting active repositories is clicked", () => {
+ beforeEach(() => {
+ applicationBuilder.select.openMenu(
+ "selection-of-active-public-helm-repository",
+ );
+ });
+
+ it("renders", () => {
+ expect(rendered.baseElement).toMatchSnapshot();
+ });
+
+ describe("when deactive public repository is selected", () => {
+ beforeEach(async () => {
+ getActiveHelmRepositoriesMock.mockClear();
+
+ applicationBuilder.select.selectOption(
+ "selection-of-active-public-helm-repository",
+ "Some to be activated repository",
+ );
+ });
+
+ it("renders", () => {
+ expect(rendered.baseElement).toMatchSnapshot();
+ });
+
+ it("activates the repository", () => {
+ expect(execFileMock).toHaveBeenCalledWith(
+ "some-helm-binary-path",
+ ["repo", "add", "Some to be activated repository", "some-other-url"],
+ );
+ });
+
+ it("does not reload active repositories yet", () => {
+ expect(getActiveHelmRepositoriesMock).not.toHaveBeenCalled();
+ });
+
+ describe("when activating resolves", () => {
+ beforeEach(async () => {
+ await execFileMock.resolveSpecific(
+ [
+ "some-helm-binary-path",
+ ["repo", "add", "Some to be activated repository", "some-other-url"],
+ ],
+
+ "",
+ );
+ });
+
+ it("renders", () => {
+ expect(rendered.baseElement).toMatchSnapshot();
+ });
+
+ it("reloads active repositories", () => {
+ expect(getActiveHelmRepositoriesMock).toHaveBeenCalled();
+ });
+
+ describe("when active repositories resolve again", () => {
+ beforeEach(async () => {
+ await getActiveHelmRepositoriesMock.resolve([
+ { name: "Some already active repository", url: "some-url" },
+ { name: "Some to be activated repository", url: "some-other-url" },
+ ]);
+ });
+
+ it("renders", () => {
+ expect(rendered.baseElement).toMatchSnapshot();
+ });
+
+ describe("when select for selecting active repositories is clicked", () => {
+ beforeEach(() => {
+ applicationBuilder.select.openMenu(
+ "selection-of-active-public-helm-repository",
+ );
+ });
+
+ it("renders", () => {
+ expect(rendered.baseElement).toMatchSnapshot();
+ });
+
+ describe("when active repository is selected", () => {
+ beforeEach(() => {
+ execFileMock.mockClear();
+ getActiveHelmRepositoriesMock.mockClear();
+
+ applicationBuilder.select.selectOption(
+ "selection-of-active-public-helm-repository",
+ "Some already active repository",
+ );
+ });
+
+ it("renders", () => {
+ expect(rendered.baseElement).toMatchSnapshot();
+ });
+
+ it("deactivates the repository", () => {
+ expect(execFileMock).toHaveBeenCalledWith(
+ "some-helm-binary-path",
+ ["repo", "remove", "Some already active repository"],
+ );
+ });
+
+ it("does not reload active repositories yet", () => {
+ expect(getActiveHelmRepositoriesMock).not.toHaveBeenCalled();
+ });
+
+ describe("when deactivating resolves", () => {
+ beforeEach(async () => {
+ await execFileMock.resolveSpecific(
+ [
+ "some-helm-binary-path",
+ ["repo", "remove", "Some already active repository"],
+ ],
+
+ "",
+ );
+ });
+
+ it("renders", () => {
+ expect(rendered.baseElement).toMatchSnapshot();
+ });
+
+ it("reloads active repositories", () => {
+ expect(getActiveHelmRepositoriesMock).toHaveBeenCalled();
+ });
+ });
+ });
+ });
+ });
+ });
+ });
+ });
+ });
+ });
+});
diff --git a/src/common/helm/activate-helm-repository-channel.injectable.ts b/src/common/helm/activate-helm-repository-channel.injectable.ts
new file mode 100644
index 0000000000..81ed44315a
--- /dev/null
+++ b/src/common/helm/activate-helm-repository-channel.injectable.ts
@@ -0,0 +1,22 @@
+/**
+ * Copyright (c) OpenLens Authors. All rights reserved.
+ * Licensed under MIT License. See LICENSE in root directory for more information.
+ */
+import { getInjectable } from "@ogre-tools/injectable";
+import type { HelmRepo } from "../helm-repo";
+import type { RequestChannel } from "../utils/channel/request-channel-injection-token";
+import { requestChannelInjectionToken } from "../utils/channel/request-channel-injection-token";
+
+export type ActivateHelmRepositoryChannel = RequestChannel;
+
+const activateHelmRepositoryChannelInjectable = getInjectable({
+ id: "activate-helm-repository-channel",
+
+ instantiate: (): ActivateHelmRepositoryChannel => ({
+ id: "activate-helm-repository-channel",
+ }),
+
+ injectionToken: requestChannelInjectionToken,
+});
+
+export default activateHelmRepositoryChannelInjectable;
diff --git a/src/common/helm/deactivate-helm-repository-channel.injectable.ts b/src/common/helm/deactivate-helm-repository-channel.injectable.ts
new file mode 100644
index 0000000000..a841525987
--- /dev/null
+++ b/src/common/helm/deactivate-helm-repository-channel.injectable.ts
@@ -0,0 +1,22 @@
+/**
+ * Copyright (c) OpenLens Authors. All rights reserved.
+ * Licensed under MIT License. See LICENSE in root directory for more information.
+ */
+import { getInjectable } from "@ogre-tools/injectable";
+import type { HelmRepo } from "../helm-repo";
+import type { RequestChannel } from "../utils/channel/request-channel-injection-token";
+import { requestChannelInjectionToken } from "../utils/channel/request-channel-injection-token";
+
+export type DeactivateHelmRepositoryChannel = RequestChannel;
+
+const deactivateHelmRepositoryChannelInjectable = getInjectable({
+ id: "deactivate-helm-repository-channel",
+
+ instantiate: (): DeactivateHelmRepositoryChannel => ({
+ id: "deactivate-helm-repository-channel",
+ }),
+
+ injectionToken: requestChannelInjectionToken,
+});
+
+export default deactivateHelmRepositoryChannelInjectable;
diff --git a/src/main/helm/repositories/activate-helm-repository/activate-helm-repository-channel-listener.injectable.ts b/src/main/helm/repositories/activate-helm-repository/activate-helm-repository-channel-listener.injectable.ts
new file mode 100644
index 0000000000..ae7f12efe9
--- /dev/null
+++ b/src/main/helm/repositories/activate-helm-repository/activate-helm-repository-channel-listener.injectable.ts
@@ -0,0 +1,26 @@
+/**
+ * Copyright (c) OpenLens Authors. All rights reserved.
+ * Licensed under MIT License. See LICENSE in root directory for more information.
+ */
+import { getInjectable } from "@ogre-tools/injectable";
+import activateHelmRepositoryChannelInjectable from "../../../../common/helm/activate-helm-repository-channel.injectable";
+import activateHelmRepositoryInjectable from "./activate-helm-repository.injectable";
+import { requestChannelListenerInjectionToken } from "../../../../common/utils/channel/request-channel-listener-injection-token";
+
+const activateHelmRepositoryChannelListenerInjectable = getInjectable({
+ id: "activate-helm-repository-channel-listener",
+
+ instantiate: (di) => {
+ const activateHelmRepository = di.inject(activateHelmRepositoryInjectable);
+ const channel = di.inject(activateHelmRepositoryChannelInjectable);
+
+ return {
+ channel,
+ handler: activateHelmRepository,
+ };
+ },
+
+ injectionToken: requestChannelListenerInjectionToken,
+});
+
+export default activateHelmRepositoryChannelListenerInjectable;
diff --git a/src/main/helm/repositories/activate-helm-repository/activate-helm-repository.injectable.ts b/src/main/helm/repositories/activate-helm-repository/activate-helm-repository.injectable.ts
new file mode 100644
index 0000000000..2218caf4c2
--- /dev/null
+++ b/src/main/helm/repositories/activate-helm-repository/activate-helm-repository.injectable.ts
@@ -0,0 +1,62 @@
+/**
+ * Copyright (c) OpenLens Authors. All rights reserved.
+ * Licensed under MIT License. See LICENSE in root directory for more information.
+ */
+import { getInjectable } from "@ogre-tools/injectable";
+import execHelmInjectable from "../../exec-helm/exec-helm.injectable";
+import type { HelmRepo } from "../../../../common/helm-repo";
+import loggerInjectable from "../../../../common/logger.injectable";
+
+const activateHelmRepositoryInjectable = getInjectable({
+ id: "activate-helm-repository",
+
+ instantiate: (di) => {
+ const execHelm = di.inject(execHelmInjectable);
+ const logger = di.inject(loggerInjectable);
+
+ return async (repo: HelmRepo) => {
+ const {
+ name,
+ url,
+ insecureSkipTlsVerify,
+ username,
+ password,
+ caFile,
+ keyFile,
+ certFile,
+ } = repo;
+
+ logger.info(`[HELM]: adding repo ${name} from ${url}`);
+
+ const args = ["repo", "add", name, url];
+
+ if (insecureSkipTlsVerify) {
+ args.push("--insecure-skip-tls-verify");
+ }
+
+ if (username) {
+ args.push("--username", username);
+ }
+
+ if (password) {
+ args.push("--password", password);
+ }
+
+ if (caFile) {
+ args.push("--ca-file", caFile);
+ }
+
+ if (keyFile) {
+ args.push("--key-file", keyFile);
+ }
+
+ if (certFile) {
+ args.push("--cert-file", certFile);
+ }
+
+ await execHelm(...args);
+ };
+ },
+});
+
+export default activateHelmRepositoryInjectable;
diff --git a/src/main/helm/repositories/deactivate-helm-repository/deactivate-helm-repository-channel-listener.injectable.ts b/src/main/helm/repositories/deactivate-helm-repository/deactivate-helm-repository-channel-listener.injectable.ts
new file mode 100644
index 0000000000..9eb852aee6
--- /dev/null
+++ b/src/main/helm/repositories/deactivate-helm-repository/deactivate-helm-repository-channel-listener.injectable.ts
@@ -0,0 +1,26 @@
+/**
+ * Copyright (c) OpenLens Authors. All rights reserved.
+ * Licensed under MIT License. See LICENSE in root directory for more information.
+ */
+import { getInjectable } from "@ogre-tools/injectable";
+import { requestChannelListenerInjectionToken } from "../../../../common/utils/channel/request-channel-listener-injection-token";
+import deactivateHelmRepositoryInjectable from "./deactivate-helm-repository.injectable";
+import deactivateHelmRepositoryChannelInjectable from "../../../../common/helm/deactivate-helm-repository-channel.injectable";
+
+const deactivateHelmRepositoryChannelListenerInjectable = getInjectable({
+ id: "deactivate-helm-repository-channel-listener",
+
+ instantiate: (di) => {
+ const deactivateHelmRepository = di.inject(deactivateHelmRepositoryInjectable);
+ const channel = di.inject(deactivateHelmRepositoryChannelInjectable);
+
+ return {
+ channel,
+ handler: deactivateHelmRepository,
+ };
+ },
+
+ injectionToken: requestChannelListenerInjectionToken,
+});
+
+export default deactivateHelmRepositoryChannelListenerInjectable;
diff --git a/src/main/helm/repositories/deactivate-helm-repository/deactivate-helm-repository.injectable.ts b/src/main/helm/repositories/deactivate-helm-repository/deactivate-helm-repository.injectable.ts
new file mode 100644
index 0000000000..d31ca9e883
--- /dev/null
+++ b/src/main/helm/repositories/deactivate-helm-repository/deactivate-helm-repository.injectable.ts
@@ -0,0 +1,29 @@
+/**
+ * Copyright (c) OpenLens Authors. All rights reserved.
+ * Licensed under MIT License. See LICENSE in root directory for more information.
+ */
+import { getInjectable } from "@ogre-tools/injectable";
+import execHelmInjectable from "../../exec-helm/exec-helm.injectable";
+import type { HelmRepo } from "../../../../common/helm-repo";
+import loggerInjectable from "../../../../common/logger.injectable";
+
+const deactivateHelmRepositoryInjectable = getInjectable({
+ id: "deactive-helm-repository",
+
+ instantiate: (di) => {
+ const execHelm = di.inject(execHelmInjectable);
+ const logger = di.inject(loggerInjectable);
+
+ return async (repo: HelmRepo) => {
+ logger.info(`[HELM]: removing repo ${repo.name} (${repo.url})`);
+
+ return execHelm(
+ "repo",
+ "remove",
+ repo.name,
+ );
+ };
+ },
+});
+
+export default deactivateHelmRepositoryInjectable;
diff --git a/src/renderer/components/+preferences/kubernetes/helm-charts/activation-of-public-helm-repository/activation-of-public-helm-repository.tsx b/src/renderer/components/+preferences/kubernetes/helm-charts/activation-of-public-helm-repository/activation-of-public-helm-repository.tsx
new file mode 100644
index 0000000000..05d513bcbd
--- /dev/null
+++ b/src/renderer/components/+preferences/kubernetes/helm-charts/activation-of-public-helm-repository/activation-of-public-helm-repository.tsx
@@ -0,0 +1,82 @@
+/**
+ * Copyright (c) OpenLens Authors. All rights reserved.
+ * Licensed under MIT License. See LICENSE in root directory for more information.
+ */
+import type { IAsyncComputed } from "@ogre-tools/injectable-react";
+import { withInjectables } from "@ogre-tools/injectable-react";
+import React from "react";
+import publicHelmRepositoriesInjectable from "./public-helm-repositories/public-helm-repositories.injectable";
+import type { HelmRepo } from "../../../../../../common/helm-repo";
+import type { SelectOption } from "../../../../select";
+import { Select } from "../../../../select";
+import { Icon } from "../../../../icon";
+import { observer } from "mobx-react";
+import type { SingleValue } from "react-select";
+import selectHelmRepositoryInjectable from "./select-helm-repository/select-helm-repository.injectable";
+import { matches } from "lodash/fp";
+import activeHelmRepositoriesInjectable from "../active-helm-repositories.injectable";
+
+interface Dependencies {
+ publicRepositories: IAsyncComputed;
+ activeRepositories: IAsyncComputed;
+ selectRepository: (value: SingleValue>) => void;
+}
+
+const NonInjectedActivationOfPublicHelmRepository = observer(({
+ publicRepositories,
+ activeRepositories,
+ selectRepository,
+}: Dependencies) => {
+ const dereferencesPublicRepositories = publicRepositories.value.get();
+ const dereferencesActiveRepositories = activeRepositories.value.get();
+
+ const valuesAreLoading = publicRepositories.pending.get() || activeRepositories.pending.get();
+
+ const repositoryOptions = dereferencesPublicRepositories.map(repository => ({
+ value: repository,
+ label: repository.name,
+ isSelected: !!dereferencesActiveRepositories.find(matches({ name: repository.name })),
+ }));
+
+ return (
+