From 2b9fd97109fab66be92adef9e6e3e1bac9b8c85c Mon Sep 17 00:00:00 2001 From: Roman Date: Thu, 21 Oct 2021 18:34:13 +0300 Subject: [PATCH] dock: upgrade-chart tab refactoring & fixes -- part 1 Signed-off-by: Roman --- .../components/dock/upgrade-chart.store.ts | 118 ++++++++++-------- .../components/dock/upgrade-chart.tsx | 87 +++++-------- 2 files changed, 93 insertions(+), 112 deletions(-) diff --git a/src/renderer/components/dock/upgrade-chart.store.ts b/src/renderer/components/dock/upgrade-chart.store.ts index e499f431fa..0c2c1f1b14 100644 --- a/src/renderer/components/dock/upgrade-chart.store.ts +++ b/src/renderer/components/dock/upgrade-chart.store.ts @@ -19,22 +19,24 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -import { action, makeObservable, observable } from "mobx"; +import { action, IReactionDisposer, IReactionOptions, makeObservable, observable, reaction } 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 type { IChartVersion } from "../+apps-helm-charts/helm-chart.store"; -import { helmChartStore } from "../+apps-helm-charts/helm-chart.store"; +import { helmChartStore, IChartVersion } from "../+apps-helm-charts/helm-chart.store"; export interface IChartUpgradeData { releaseName: string; releaseNamespace: string; } +// FIXME: detach `releaseStore` and load directly from api-calls + export class UpgradeChartStore extends DockTabStore { - public values = observable.map(); - public versions = observable.array(); + private stopWatcher: IReactionDisposer; + versions = observable.map(); + values = observable.map(); constructor() { super({ storageKey: "chart_releases" }); @@ -45,83 +47,93 @@ export class UpgradeChartStore extends DockTabStore { super.init(); this.dispose.push( - dockStore.onTabChange(({ tabId }) => this.loadData(tabId), { + 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, }), ); } - async loadData(tabId: TabId) { - await this.whenReady; + private watchRelease(tabId: TabId, opts: IReactionOptions = {}): IReactionDisposer { + const { releaseName, releaseNamespace } = this.getData(tabId); - return Promise.all([ - !releaseStore.isLoaded && releaseStore.loadFromContextNamespaces(), - this.loadValues(tabId), - this.loadVersions(tabId), - ]); + return reaction( + () => releaseStore.getByName(releaseName, releaseNamespace)?.getRevision(), + () => this.loadValues(tabId), + { + fireImmediately: true, + ...opts, + }, + ); } - getRelease(tabId: TabId): HelmRelease | null { - const releaseName = this.getData(tabId)?.releaseName; + // TODO + upgrade(tabId: TabId, version: IChartVersion) { + const release = this.getRelease(tabId); + const chart = release.getChart(); + const values = this.values.get(tabId); - if (!releaseName) return null; + console.warn("UPGRADE", { release, chart, values, version }); + } - return releaseStore.getByName(releaseName); + getRelease(tabId: TabId) { + const { releaseName, releaseNamespace } = this.getData(tabId) ?? {}; + + return releaseStore.getByName(releaseName, releaseNamespace); + } + + isReady(tabId: TabId) { + return [ + this.dataReady, + this.values.get(tabId), + this.versions.get(tabId), + ].every(Boolean); } @action - private async loadVersions(tabId: TabId): Promise { - try { - const { releaseName } = this.getData(tabId); + async loadValues(tabId: TabId) { + const { releaseName, releaseNamespace } = this.getData(tabId); + const values = await getReleaseValues(releaseName, releaseNamespace, true); - console.info(`[UPGRADE-CHART]: loading versions for release "${releaseName}"`); - const versions = await helmChartStore.getVersions(releaseName); - - this.versions.replace(versions); - - return versions; - } catch (error) { - console.error(`[UPGRADE-CHART]: loading versions has failed: ${error}`); - } - - return []; + this.values.set(tabId, values); } - @action - private async loadValues(tabId: TabId): Promise { - if (this.values.has(tabId)) { - return this.values.get(tabId); // use cached values - } + async loadVersions(tabId: TabId) { + const { releaseName, releaseNamespace } = this.getData(tabId); + const release = releaseStore.getByName(releaseName, releaseNamespace); - try { - const { releaseName, releaseNamespace } = this.getData(tabId); + if (!release) return; - console.info(`[UPGRADE-CHART]: loading values for release "${releaseName}"`); + const versions = await helmChartStore.getVersions(release.getChart()); - const values = await getReleaseValues(releaseName, releaseNamespace, true); - - this.values.set(tabId, values); - - return values; - } catch (error) { - console.error(`[UPGRADE-CHART]: loading values has failed: ${error}`); - } - - return ""; + this.versions.set(tabId, versions); } - getTabByRelease(releaseName: string): DockTab | null { - const entry = Object.entries(this.data).find(([, data]) => data.releaseName === releaseName); + getTabId(releaseName: string, namespace: string): TabId { + return Object.entries(this.data) + .find(([/*tabId*/, data]) => data.releaseName === releaseName && data.releaseNamespace === namespace)?.[0]; + } - return entry ? dockStore.getTabById(entry[0]) : null; + getTabByRelease(releaseName: string, namespace: string): DockTab { + const tabId = this.getTabId(releaseName, namespace); + + return dockStore.getTabById(tabId); + } + + destroy() { + super.destroy(); + this.stopWatcher?.(); } } export const upgradeChartStore = new UpgradeChartStore(); export function createUpgradeChartTab(release: HelmRelease, tabParams: DockTabCreateSpecific = {}) { - let tab = upgradeChartStore.getTabByRelease(release.getName()); + let tab = upgradeChartStore.getTabByRelease(release.getName(), release.getNs()); if (tab) { dockStore.open(); diff --git a/src/renderer/components/dock/upgrade-chart.tsx b/src/renderer/components/dock/upgrade-chart.tsx index 397c835084..5f8b34c20f 100644 --- a/src/renderer/components/dock/upgrade-chart.tsx +++ b/src/renderer/components/dock/upgrade-chart.tsx @@ -22,92 +22,62 @@ 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 { InfoPanel, InfoPanelProps } from "./info-panel"; -import { upgradeChartStore } from "./upgrade-chart.store"; -import { releaseStore } from "../+apps-releases/release.store"; import { Badge } from "../badge"; -import { Select, SelectOption } from "../select"; import type { IChartVersion } from "../+apps-helm-charts/helm-chart.store"; import type { HelmRelease } from "../../../common/k8s-api/endpoints/helm-releases.api"; -import { TabKind } from "./dock.store"; +import { Select, SelectOption } from "../select"; +import { upgradeChartStore } from "./upgrade-chart.store"; import { dockViewsManager } from "./dock.views-manager"; interface Props extends InfoPanelProps { } @observer -export class UpgradeChart extends React.Component { +export class UpgradeChartInfoPanel extends React.Component { + @observable selectedVersion: IChartVersion; + constructor(props: Props) { super(props); makeObservable(this); } - get tabId() { + get tabId(): TabId { return this.props.tabId; } - get release(): HelmRelease | null { + get release(): HelmRelease { return upgradeChartStore.getRelease(this.tabId); } - @observable selectedVersion: IChartVersion | undefined; + @computed get chartVersions(): SelectOption[] { + const chartName = this.release.getChart(); + const versions = upgradeChartStore.versions.get(this.tabId) ?? []; - @computed get releaseVersion(): IChartVersion { - return this.getChartVersionByRelease(this.release); - } - - @computed get chartVersionOptions(): SelectOption[] { - return upgradeChartStore.versions.map(version => ({ - value: version, - disabled: this.selectedVersion == this.releaseVersion, + return versions.map(value => ({ + label: `${value.repo}/${chartName}-${value.version}`, + value, })); } - @computed get chartValues(): string { - return upgradeChartStore.values.get(this.tabId); - } - - getChartVersionByRelease(release: HelmRelease): IChartVersion | undefined { - return upgradeChartStore.versions.find(({ version, repo }) => ( - release?.getChart() == repo && - release?.getVersion() === version - )); - } - upgrade = async () => { - const { releaseVersion, selectedVersion, release, chartValues } = this; - const newVersionNotSelected = !selectedVersion || selectedVersion == releaseVersion; - - if (!release || newVersionNotSelected) { - throw new Error(`You have not selected new version for "${releaseVersion}"`); // skip: nothing to upgrade - } - - const { version, repo } = selectedVersion; - const releaseName = release.getName(); - const releaseNs = release.getNs(); - - await releaseStore.update(releaseName, releaseNs, { - chart: release.getChart(), - values: chartValues, - repo, version, - }); + await upgradeChartStore.upgrade(this.tabId, this.selectedVersion); return (

- Release {releaseName} successfully upgraded to version {version} + Release {this.release.getName()} successfully upgraded to version {this.selectedVersion.version}

); }; - formatVersionLabel = ({ value }: SelectOption) => { - const chartName = this.release.getChart(); - const { repo, version } = value; - - return `${repo}/${chartName}-${version}`; - }; - render() { - const { release, chartVersionOptions } = this; + if (!upgradeChartStore.isReady(this.tabId)) { + return null; + } + + const { release, selectedVersion, chartVersions } = this; return ( { submittingMessage="Updating.." controls={
- Release - Namespace - Version + Release + Namespace + Version Upgrade version