mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
dock: upgrade-chart tab refactoring & fixes -- part 1
Signed-off-by: Roman <ixrock@gmail.com>
This commit is contained in:
parent
05552fefab
commit
2b9fd97109
@ -19,22 +19,24 @@
|
|||||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
* 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 { dockStore, DockTab, DockTabCreateSpecific, TabId, TabKind } from "./dock.store";
|
||||||
import { DockTabStore } from "./dock-tab.store";
|
import { DockTabStore } from "./dock-tab.store";
|
||||||
import { getReleaseValues, HelmRelease } from "../../../common/k8s-api/endpoints/helm-releases.api";
|
import { getReleaseValues, HelmRelease } from "../../../common/k8s-api/endpoints/helm-releases.api";
|
||||||
import { releaseStore } from "../+apps-releases/release.store";
|
import { releaseStore } from "../+apps-releases/release.store";
|
||||||
import type { IChartVersion } from "../+apps-helm-charts/helm-chart.store";
|
import { helmChartStore, IChartVersion } from "../+apps-helm-charts/helm-chart.store";
|
||||||
import { helmChartStore } from "../+apps-helm-charts/helm-chart.store";
|
|
||||||
|
|
||||||
export interface IChartUpgradeData {
|
export interface IChartUpgradeData {
|
||||||
releaseName: string;
|
releaseName: string;
|
||||||
releaseNamespace: string;
|
releaseNamespace: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME: detach `releaseStore` and load directly from api-calls
|
||||||
|
|
||||||
export class UpgradeChartStore extends DockTabStore<IChartUpgradeData> {
|
export class UpgradeChartStore extends DockTabStore<IChartUpgradeData> {
|
||||||
public values = observable.map<TabId, string>();
|
private stopWatcher: IReactionDisposer;
|
||||||
public versions = observable.array<IChartVersion>();
|
versions = observable.map<TabId, IChartVersion[]>();
|
||||||
|
values = observable.map<TabId, string>();
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super({ storageKey: "chart_releases" });
|
super({ storageKey: "chart_releases" });
|
||||||
@ -45,83 +47,93 @@ export class UpgradeChartStore extends DockTabStore<IChartUpgradeData> {
|
|||||||
super.init();
|
super.init();
|
||||||
|
|
||||||
this.dispose.push(
|
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,
|
tabKind: TabKind.UPGRADE_CHART,
|
||||||
fireImmediately: true,
|
fireImmediately: true,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
async loadData(tabId: TabId) {
|
private watchRelease(tabId: TabId, opts: IReactionOptions = {}): IReactionDisposer {
|
||||||
await this.whenReady;
|
const { releaseName, releaseNamespace } = this.getData(tabId);
|
||||||
|
|
||||||
return Promise.all([
|
return reaction(
|
||||||
!releaseStore.isLoaded && releaseStore.loadFromContextNamespaces(),
|
() => releaseStore.getByName(releaseName, releaseNamespace)?.getRevision(),
|
||||||
this.loadValues(tabId),
|
() => this.loadValues(tabId),
|
||||||
this.loadVersions(tabId),
|
{
|
||||||
]);
|
fireImmediately: true,
|
||||||
|
...opts,
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
getRelease(tabId: TabId): HelmRelease | null {
|
// TODO
|
||||||
const releaseName = this.getData(tabId)?.releaseName;
|
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
|
@action
|
||||||
private async loadVersions(tabId: TabId): Promise<IChartVersion[]> {
|
async loadValues(tabId: TabId) {
|
||||||
try {
|
const { releaseName, releaseNamespace } = this.getData(tabId);
|
||||||
const { releaseName } = this.getData(tabId);
|
const values = await getReleaseValues(releaseName, releaseNamespace, true);
|
||||||
|
|
||||||
console.info(`[UPGRADE-CHART]: loading versions for release "${releaseName}"`);
|
this.values.set(tabId, values);
|
||||||
const versions = await helmChartStore.getVersions(releaseName);
|
|
||||||
|
|
||||||
this.versions.replace(versions);
|
|
||||||
|
|
||||||
return versions;
|
|
||||||
} catch (error) {
|
|
||||||
console.error(`[UPGRADE-CHART]: loading versions has failed: ${error}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
return [];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
async loadVersions(tabId: TabId) {
|
||||||
private async loadValues(tabId: TabId): Promise<string> {
|
const { releaseName, releaseNamespace } = this.getData(tabId);
|
||||||
if (this.values.has(tabId)) {
|
const release = releaseStore.getByName(releaseName, releaseNamespace);
|
||||||
return this.values.get(tabId); // use cached values
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
if (!release) return;
|
||||||
const { releaseName, releaseNamespace } = this.getData(tabId);
|
|
||||||
|
|
||||||
console.info(`[UPGRADE-CHART]: loading values for release "${releaseName}"`);
|
const versions = await helmChartStore.getVersions(release.getChart());
|
||||||
|
|
||||||
const values = await getReleaseValues(releaseName, releaseNamespace, true);
|
this.versions.set(tabId, versions);
|
||||||
|
|
||||||
this.values.set(tabId, values);
|
|
||||||
|
|
||||||
return values;
|
|
||||||
} catch (error) {
|
|
||||||
console.error(`[UPGRADE-CHART]: loading values has failed: ${error}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
return "";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getTabByRelease(releaseName: string): DockTab | null {
|
getTabId(releaseName: string, namespace: string): TabId {
|
||||||
const entry = Object.entries(this.data).find(([, data]) => data.releaseName === releaseName);
|
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 const upgradeChartStore = new UpgradeChartStore();
|
||||||
|
|
||||||
export function createUpgradeChartTab(release: HelmRelease, tabParams: DockTabCreateSpecific = {}) {
|
export function createUpgradeChartTab(release: HelmRelease, tabParams: DockTabCreateSpecific = {}) {
|
||||||
let tab = upgradeChartStore.getTabByRelease(release.getName());
|
let tab = upgradeChartStore.getTabByRelease(release.getName(), release.getNs());
|
||||||
|
|
||||||
if (tab) {
|
if (tab) {
|
||||||
dockStore.open();
|
dockStore.open();
|
||||||
|
|||||||
@ -22,92 +22,62 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { computed, makeObservable, observable } from "mobx";
|
import { computed, makeObservable, observable } from "mobx";
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
|
import type { TabId } from "./dock.store";
|
||||||
|
import { TabKind } from "./dock.store";
|
||||||
import { InfoPanel, InfoPanelProps } from "./info-panel";
|
import { InfoPanel, InfoPanelProps } from "./info-panel";
|
||||||
import { upgradeChartStore } from "./upgrade-chart.store";
|
|
||||||
import { releaseStore } from "../+apps-releases/release.store";
|
|
||||||
import { Badge } from "../badge";
|
import { Badge } from "../badge";
|
||||||
import { Select, SelectOption } from "../select";
|
|
||||||
import type { IChartVersion } from "../+apps-helm-charts/helm-chart.store";
|
import type { IChartVersion } from "../+apps-helm-charts/helm-chart.store";
|
||||||
import type { HelmRelease } from "../../../common/k8s-api/endpoints/helm-releases.api";
|
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";
|
import { dockViewsManager } from "./dock.views-manager";
|
||||||
|
|
||||||
interface Props extends InfoPanelProps {
|
interface Props extends InfoPanelProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
@observer
|
@observer
|
||||||
export class UpgradeChart extends React.Component<Props> {
|
export class UpgradeChartInfoPanel extends React.Component<Props> {
|
||||||
|
@observable selectedVersion: IChartVersion;
|
||||||
|
|
||||||
constructor(props: Props) {
|
constructor(props: Props) {
|
||||||
super(props);
|
super(props);
|
||||||
makeObservable(this);
|
makeObservable(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
get tabId() {
|
get tabId(): TabId {
|
||||||
return this.props.tabId;
|
return this.props.tabId;
|
||||||
}
|
}
|
||||||
|
|
||||||
get release(): HelmRelease | null {
|
get release(): HelmRelease {
|
||||||
return upgradeChartStore.getRelease(this.tabId);
|
return upgradeChartStore.getRelease(this.tabId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@observable selectedVersion: IChartVersion | undefined;
|
@computed get chartVersions(): SelectOption<IChartVersion>[] {
|
||||||
|
const chartName = this.release.getChart();
|
||||||
|
const versions = upgradeChartStore.versions.get(this.tabId) ?? [];
|
||||||
|
|
||||||
@computed get releaseVersion(): IChartVersion {
|
return versions.map(value => ({
|
||||||
return this.getChartVersionByRelease(this.release);
|
label: `${value.repo}/${chartName}-${value.version}`,
|
||||||
}
|
value,
|
||||||
|
|
||||||
@computed get chartVersionOptions(): SelectOption<IChartVersion>[] {
|
|
||||||
return upgradeChartStore.versions.map(version => ({
|
|
||||||
value: version,
|
|
||||||
disabled: this.selectedVersion == this.releaseVersion,
|
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
@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 () => {
|
upgrade = async () => {
|
||||||
const { releaseVersion, selectedVersion, release, chartValues } = this;
|
await upgradeChartStore.upgrade(this.tabId, this.selectedVersion);
|
||||||
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,
|
|
||||||
});
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<p>
|
<p>
|
||||||
Release <b>{releaseName}</b> successfully upgraded to version <b>{version}</b>
|
Release <b>{this.release.getName()}</b> successfully upgraded to version <b>{this.selectedVersion.version}</b>
|
||||||
</p>
|
</p>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
formatVersionLabel = ({ value }: SelectOption<IChartVersion>) => {
|
|
||||||
const chartName = this.release.getChart();
|
|
||||||
const { repo, version } = value;
|
|
||||||
|
|
||||||
return `${repo}/${chartName}-${version}`;
|
|
||||||
};
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { release, chartVersionOptions } = this;
|
if (!upgradeChartStore.isReady(this.tabId)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { release, selectedVersion, chartVersions } = this;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<InfoPanel
|
<InfoPanel
|
||||||
@ -117,17 +87,16 @@ export class UpgradeChart extends React.Component<Props> {
|
|||||||
submittingMessage="Updating.."
|
submittingMessage="Updating.."
|
||||||
controls={
|
controls={
|
||||||
<div className="upgrade flex gaps align-center">
|
<div className="upgrade flex gaps align-center">
|
||||||
<span>Release</span> <Badge label={release?.getName()}/>
|
<span>Release</span> <Badge label={release.getName()}/>
|
||||||
<span>Namespace</span> <Badge label={release?.getNs()}/>
|
<span>Namespace</span> <Badge label={release.getNs()}/>
|
||||||
<span>Version</span> <Badge label={release?.getVersion()}/>
|
<span>Version</span> <Badge label={release.getVersion()}/>
|
||||||
<span>Upgrade version</span>
|
<span>Upgrade version</span>
|
||||||
<Select
|
<Select
|
||||||
className="chart-version"
|
className="chart-version"
|
||||||
menuPlacement="top"
|
menuPlacement="top"
|
||||||
themeName="outlined"
|
themeName="outlined"
|
||||||
value={this.selectedVersion ?? this.releaseVersion}
|
value={selectedVersion}
|
||||||
options={chartVersionOptions}
|
options={chartVersions}
|
||||||
formatOptionLabel={this.formatVersionLabel}
|
|
||||||
onChange={({ value }: SelectOption<IChartVersion>) => this.selectedVersion = value}
|
onChange={({ value }: SelectOption<IChartVersion>) => this.selectedVersion = value}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@ -138,7 +107,7 @@ export class UpgradeChart extends React.Component<Props> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dockViewsManager.register(TabKind.UPGRADE_CHART, {
|
dockViewsManager.register(TabKind.UPGRADE_CHART, {
|
||||||
InfoPanel: UpgradeChart,
|
InfoPanel: UpgradeChartInfoPanel,
|
||||||
editor: {
|
editor: {
|
||||||
getValue(tabId): string {
|
getValue(tabId): string {
|
||||||
return upgradeChartStore.values.get(tabId);
|
return upgradeChartStore.values.get(tabId);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user