From b6c9ac07823b380301a9d66c40e2a661f2c7ce53 Mon Sep 17 00:00:00 2001 From: Roman Date: Fri, 22 Oct 2021 16:18:42 +0300 Subject: [PATCH] dock: upgrade-chart refactoring & fixes -- part 2 Signed-off-by: Roman --- .../+apps-releases/release.store.ts | 15 +- .../components/dock/upgrade-chart.store.ts | 129 ++++++++++-------- .../components/dock/upgrade-chart.tsx | 30 ++-- src/renderer/utils/storageHelper.ts | 4 +- 4 files changed, 105 insertions(+), 73 deletions(-) diff --git a/src/renderer/components/+apps-releases/release.store.ts b/src/renderer/components/+apps-releases/release.store.ts index 4475953138..f158208911 100644 --- a/src/renderer/components/+apps-releases/release.store.ts +++ b/src/renderer/components/+apps-releases/release.store.ts @@ -42,6 +42,14 @@ export class ReleaseStore extends ItemStore { }); } + getByName(name: string, namespace?: string): HelmRelease | undefined { + return this.items.find(release => { + return release.getName() === name && ( + namespace ? release.getNs() === namespace : true + ); + }); + } + watchAssociatedSecrets(): (() => void) { return reaction(() => secretsStore.getItems(), () => { if (this.isLoading) return; @@ -106,10 +114,7 @@ export class ReleaseStore extends ItemStore { } async loadFromContextNamespaces(): Promise { - const { contextNamespaces } = namespaceStore.context ?? {}; - - if (!contextNamespaces) return; - await this.loadAll(contextNamespaces); + return this.loadAll(namespaceStore.context.contextNamespaces); } async loadItems(namespaces: string[]) { @@ -137,7 +142,7 @@ export class ReleaseStore extends ItemStore { async update(name: string, namespace: string, payload: IReleaseUpdatePayload) { const response = await updateRelease(name, namespace, payload); - if (this.isLoaded) this.loadFromContextNamespaces(); + if (this.isLoaded) await this.loadFromContextNamespaces(); return response; } diff --git a/src/renderer/components/dock/upgrade-chart.store.ts b/src/renderer/components/dock/upgrade-chart.store.ts index 0c2c1f1b14..58b9f93cc0 100644 --- a/src/renderer/components/dock/upgrade-chart.store.ts +++ b/src/renderer/components/dock/upgrade-chart.store.ts @@ -19,22 +19,20 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -import { action, IReactionDisposer, IReactionOptions, makeObservable, observable, reaction } from "mobx"; +import { action, makeObservable, observable } from "mobx"; import { dockStore, DockTab, DockTabCreateSpecific, TabId, TabKind } from "./dock.store"; import { DockTabStore } from "./dock-tab.store"; -import { getReleaseValues, HelmRelease } from "../../../common/k8s-api/endpoints/helm-releases.api"; -import { releaseStore } from "../+apps-releases/release.store"; +import { getReleaseValues, HelmRelease, listReleases } from "../../../common/k8s-api/endpoints/helm-releases.api"; import { helmChartStore, IChartVersion } from "../+apps-helm-charts/helm-chart.store"; +import { releaseStore } from "../+apps-releases/release.store"; export interface IChartUpgradeData { releaseName: string; releaseNamespace: string; } -// FIXME: detach `releaseStore` and load directly from api-calls - export class UpgradeChartStore extends DockTabStore { - private stopWatcher: IReactionDisposer; + releases = observable.map(); versions = observable.map(); values = observable.map(); @@ -43,71 +41,75 @@ export class UpgradeChartStore extends DockTabStore { makeObservable(this); } - async init() { - super.init(); - - this.dispose.push( - dockStore.onTabChange(async ({ tabId }) => { - this.loadVersions(tabId); - this.stopWatcher?.(); // unsubscribe previous active upgrade-chart tab - this.stopWatcher = this.watchRelease(tabId); - }, { - tabKind: TabKind.UPGRADE_CHART, - fireImmediately: true, - }), - ); - } - - private watchRelease(tabId: TabId, opts: IReactionOptions = {}): IReactionDisposer { - const { releaseName, releaseNamespace } = this.getData(tabId); - - return reaction( - () => releaseStore.getByName(releaseName, releaseNamespace)?.getRevision(), - () => this.loadValues(tabId), - { - fireImmediately: true, - ...opts, - }, - ); - } - - // TODO - upgrade(tabId: TabId, version: IChartVersion) { - const release = this.getRelease(tabId); - const chart = release.getChart(); - const values = this.values.get(tabId); - - console.warn("UPGRADE", { release, chart, values, version }); - } - - getRelease(tabId: TabId) { - const { releaseName, releaseNamespace } = this.getData(tabId) ?? {}; - - return releaseStore.getByName(releaseName, releaseNamespace); - } - isReady(tabId: TabId) { return [ - this.dataReady, + this.releases.get(tabId), this.values.get(tabId), this.versions.get(tabId), ].every(Boolean); } + async load(tabId: TabId) { + await this.whenReady; + await this.loadRelease(tabId); + + await Promise.all([ + this.loadVersions(tabId), + this.loadValues(tabId), + ]); + } + + async updateRelease(tabId: TabId, { version, repo }: IChartVersion) { + const release = this.releases.get(tabId); + const values = this.values.get(tabId); + const chart = release.getChart(); + const releaseName = release.getName(); + const namespace = release.getNs(); + + await releaseStore.update(releaseName, namespace, { chart, values, version, repo }); + await this.loadRelease(tabId, true); // refresh local instance + } + + async loadRelease(tabId: TabId, force = false) { + if (this.releases.has(tabId) && !force) { + return; + } + + const { releaseName, releaseNamespace } = this.getData(tabId); + let release = releaseStore.getByName(releaseName, releaseNamespace); + + if (!release) { + const releasesInNamespace = await listReleases(releaseNamespace); + + release = releasesInNamespace.find(item => item.getName() == releaseName && item.getNs() === releaseNamespace); + } + + if (!release) { + throw new Error(`Helm release "${releaseName}" doesn't exist in namespace "${releaseNamespace}"`); + } + + this.releases.set(tabId, release); + } + @action - async loadValues(tabId: TabId) { + async loadValues(tabId: TabId, force = false) { + if (this.values.has(tabId) && !force) { + return; + } + const { releaseName, releaseNamespace } = this.getData(tabId); const values = await getReleaseValues(releaseName, releaseNamespace, true); this.values.set(tabId, values); } - async loadVersions(tabId: TabId) { - const { releaseName, releaseNamespace } = this.getData(tabId); - const release = releaseStore.getByName(releaseName, releaseNamespace); - - if (!release) return; + @action + async loadVersions(tabId: TabId, force = false) { + if (this.versions.has(tabId) && !force) { + return; + } + const release = this.releases.get(tabId); const versions = await helmChartStore.getVersions(release.getChart()); this.versions.set(tabId, versions); @@ -124,9 +126,18 @@ export class UpgradeChartStore extends DockTabStore { return dockStore.getTabById(tabId); } - destroy() { - super.destroy(); - this.stopWatcher?.(); + clearData(tabId: TabId) { + super.clearData(tabId); + this.releases.delete(tabId); + this.versions.delete(tabId); + this.values.delete(tabId); + } + + reset() { + super.reset(); + this.releases.clear(); + this.versions.clear(); + this.values.clear(); } } diff --git a/src/renderer/components/dock/upgrade-chart.tsx b/src/renderer/components/dock/upgrade-chart.tsx index 5f8b34c20f..aea7f0c2da 100644 --- a/src/renderer/components/dock/upgrade-chart.tsx +++ b/src/renderer/components/dock/upgrade-chart.tsx @@ -20,15 +20,14 @@ */ import React from "react"; -import { computed, makeObservable, observable } from "mobx"; -import { observer } from "mobx-react"; -import type { TabId } from "./dock.store"; -import { TabKind } from "./dock.store"; +import { action, computed, makeObservable, observable } from "mobx"; +import { disposeOnUnmount, observer } from "mobx-react"; import { InfoPanel, InfoPanelProps } from "./info-panel"; import { Badge } from "../badge"; +import { Select, SelectOption } from "../select"; +import { dockStore, TabId, TabKind } from "./dock.store"; import type { IChartVersion } from "../+apps-helm-charts/helm-chart.store"; import type { HelmRelease } from "../../../common/k8s-api/endpoints/helm-releases.api"; -import { Select, SelectOption } from "../select"; import { upgradeChartStore } from "./upgrade-chart.store"; import { dockViewsManager } from "./dock.views-manager"; @@ -44,12 +43,27 @@ export class UpgradeChartInfoPanel extends React.Component { makeObservable(this); } + componentDidMount() { + disposeOnUnmount(this, [ + dockStore.onTabChange(({ tabId }) => this.onTabChange(tabId), { + tabKind: TabKind.UPGRADE_CHART, + fireImmediately: true, + }), + ]); + } + + @action + async onTabChange(tabId: TabId) { + await upgradeChartStore.load(tabId); + this.selectedVersion = upgradeChartStore.versions.get(tabId)?.[0]; + } + get tabId(): TabId { return this.props.tabId; } - get release(): HelmRelease { - return upgradeChartStore.getRelease(this.tabId); + get release(): HelmRelease | undefined { + return upgradeChartStore.releases.get(this.tabId); } @computed get chartVersions(): SelectOption[] { @@ -63,7 +77,7 @@ export class UpgradeChartInfoPanel extends React.Component { } upgrade = async () => { - await upgradeChartStore.upgrade(this.tabId, this.selectedVersion); + await upgradeChartStore.updateRelease(this.tabId, this.selectedVersion); return (

diff --git a/src/renderer/utils/storageHelper.ts b/src/renderer/utils/storageHelper.ts index 38e68406e9..3a0440550d 100755 --- a/src/renderer/utils/storageHelper.ts +++ b/src/renderer/utils/storageHelper.ts @@ -87,7 +87,7 @@ export class StorageHelper { const notDefault = !this.isDefaultValue(data); if (notEmpty && notDefault) { - this.merge(data); + this.set(data); } this.initialized = true; @@ -169,6 +169,8 @@ export class StorageHelper { } else if (isPlainObject(value)) { Object.assign(draft, value); } + + return draft; }); this.set(nextValue);