mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Lens app source code (#119)
Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> Signed-off-by: Cody Belcher <cody.t.belcher@gmail.com>
This commit is contained in:
1 parent
492ea272d1
commit
d057cb17c6
797 files changed
+73714
-215
No files matched your search
@@ -0,0 +1,254 @@
|
||||
import "./release-details.scss";
|
||||
|
||||
import React, { Component } from "react";
|
||||
import groupBy from "lodash/groupBy";
|
||||
import isEqual from "lodash/isEqual";
|
||||
import { observable, reaction } from "mobx";
|
||||
import { Link } from "react-router-dom";
|
||||
import { t, Trans } from "@lingui/macro";
|
||||
import kebabCase from "lodash/kebabCase";
|
||||
import { HelmRelease, helmReleasesApi, IReleaseDetails } from "../../api/endpoints/helm-releases.api";
|
||||
import { HelmReleaseMenu } from "./release-menu";
|
||||
import { Drawer, DrawerItem, DrawerTitle } from "../drawer";
|
||||
import { Badge } from "../badge";
|
||||
import { cssNames, stopPropagation } from "../../utils";
|
||||
import { disposeOnUnmount, observer } from "mobx-react";
|
||||
import { Spinner } from "../spinner";
|
||||
import { Table, TableCell, TableHead, TableRow } from "../table";
|
||||
import { AceEditor } from "../ace-editor";
|
||||
import { Button } from "../button";
|
||||
import { releaseStore } from "./release.store";
|
||||
import { Notifications } from "../notifications";
|
||||
import { Icon } from "../icon";
|
||||
import { createUpgradeChartTab } from "../dock/upgrade-chart.store";
|
||||
import { getDetailsUrl } from "../../navigation";
|
||||
import { _i18n } from "../../i18n";
|
||||
import { themeStore } from "../../theme.store";
|
||||
import { apiManager } from "../../api/api-manager";
|
||||
import { SubTitle } from "../layout/sub-title";
|
||||
import { secretsStore } from "../+config-secrets/secrets.store";
|
||||
import { Secret } from "../../api/endpoints";
|
||||
|
||||
interface Props {
|
||||
release: HelmRelease;
|
||||
hideDetails(): void;
|
||||
}
|
||||
|
||||
@observer
|
||||
export class ReleaseDetails extends Component<Props> {
|
||||
@observable details: IReleaseDetails;
|
||||
@observable values = "";
|
||||
@observable saving = false;
|
||||
@observable releaseSecret: Secret;
|
||||
|
||||
@disposeOnUnmount
|
||||
releaseSelector = reaction(() => this.props.release, release => {
|
||||
if (!release) return;
|
||||
this.loadDetails();
|
||||
this.loadValues();
|
||||
this.releaseSecret = null;
|
||||
}
|
||||
);
|
||||
|
||||
@disposeOnUnmount
|
||||
secretWatcher = reaction(() => secretsStore.items.toJS(), () => {
|
||||
if (!this.props.release) return;
|
||||
const { getReleaseSecret } = releaseStore;
|
||||
const { release } = this.props;
|
||||
const secret = getReleaseSecret(release);
|
||||
if (this.releaseSecret) {
|
||||
if (isEqual(this.releaseSecret.getLabels(), secret.getLabels())) return;
|
||||
this.loadDetails();
|
||||
}
|
||||
this.releaseSecret = secret;
|
||||
});
|
||||
|
||||
async loadDetails() {
|
||||
const { release } = this.props;
|
||||
this.details = null;
|
||||
this.details = await helmReleasesApi.get(release.getName(), release.getNs());
|
||||
}
|
||||
|
||||
async loadValues() {
|
||||
const { release } = this.props;
|
||||
this.values = "";
|
||||
this.values = await helmReleasesApi.getValues(release.getName(), release.getNs());
|
||||
}
|
||||
|
||||
updateValues = async () => {
|
||||
const { release } = this.props;
|
||||
const name = release.getName();
|
||||
const namespace = release.getNs()
|
||||
const data = {
|
||||
chart: release.getChart(),
|
||||
repo: await release.getRepo(),
|
||||
version: release.getVersion(),
|
||||
values: this.values
|
||||
};
|
||||
this.saving = true;
|
||||
try {
|
||||
await releaseStore.update(name, namespace, data);
|
||||
Notifications.ok(
|
||||
<p>Release <b>{name}</b> successfully updated!</p>
|
||||
);
|
||||
} catch (err) {
|
||||
Notifications.error(err);
|
||||
}
|
||||
this.saving = false;
|
||||
}
|
||||
|
||||
upgradeVersion = () => {
|
||||
const { release, hideDetails } = this.props;
|
||||
createUpgradeChartTab(release);
|
||||
hideDetails();
|
||||
}
|
||||
|
||||
renderValues() {
|
||||
const { values, saving } = this;
|
||||
return (
|
||||
<div className="values">
|
||||
<DrawerTitle title={_i18n._(t`Values`)}/>
|
||||
<div className="flex column gaps">
|
||||
<AceEditor
|
||||
mode="yaml"
|
||||
value={values}
|
||||
onChange={values => this.values = values}
|
||||
/>
|
||||
<Button
|
||||
primary
|
||||
label={_i18n._(t`Save`)}
|
||||
waiting={saving}
|
||||
onClick={this.updateValues}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
renderNotes() {
|
||||
if (!this.details.info?.notes) return null;
|
||||
const { notes } = this.details.info;
|
||||
return (
|
||||
<div className="notes">
|
||||
{notes}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderResources() {
|
||||
const { resources } = this.details;
|
||||
if (!resources) return null;
|
||||
const groups = groupBy(resources, item => item.kind);
|
||||
const tables = Object.entries(groups).map(([kind, items]) => {
|
||||
return (
|
||||
<React.Fragment key={kind}>
|
||||
<SubTitle title={kind}/>
|
||||
<Table scrollable={false}>
|
||||
<TableHead sticky={false}>
|
||||
<TableCell className="name">Name</TableCell>
|
||||
{items[0].getNs() && <TableCell className="namespace">Namespace</TableCell>}
|
||||
<TableCell className="age">Age</TableCell>
|
||||
</TableHead>
|
||||
{items.map(item => {
|
||||
const name = item.getName();
|
||||
const namespace = item.getNs();
|
||||
const api = apiManager.getApi(item.metadata.selfLink);
|
||||
const detailsUrl = api ? getDetailsUrl(api.getUrl({
|
||||
name,
|
||||
namespace,
|
||||
})) : "";
|
||||
return (
|
||||
<TableRow key={item.getId()}>
|
||||
<TableCell className="name">
|
||||
{detailsUrl ? <Link to={detailsUrl}>{name}</Link> : name}
|
||||
</TableCell>
|
||||
{namespace && <TableCell className="namespace">{namespace}</TableCell>}
|
||||
<TableCell className="age">{item.getAge()}</TableCell>
|
||||
</TableRow>
|
||||
);
|
||||
})}
|
||||
</Table>
|
||||
</React.Fragment>
|
||||
);
|
||||
});
|
||||
return (
|
||||
<div className="resources">
|
||||
{tables}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderContent() {
|
||||
const { release } = this.props;
|
||||
const { details } = this;
|
||||
if (!release) return null;
|
||||
if (!details) {
|
||||
return <Spinner center/>;
|
||||
}
|
||||
return (
|
||||
<div>
|
||||
<DrawerItem name={<Trans>Chart</Trans>} className="chart">
|
||||
<div className="flex gaps align-center">
|
||||
<span>{release.getChart()}</span>
|
||||
{release.hasNewVersion() && (
|
||||
<Button
|
||||
primary
|
||||
label={_i18n._(t`Upgrade`)}
|
||||
className="box right upgrade"
|
||||
onClick={this.upgradeVersion}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</DrawerItem>
|
||||
<DrawerItem name={<Trans>Updated</Trans>}>
|
||||
{release.getUpdated()} <Trans>ago</Trans> ({release.updated})
|
||||
</DrawerItem>
|
||||
<DrawerItem name={<Trans>Namespace</Trans>}>
|
||||
{release.getNs()}
|
||||
</DrawerItem>
|
||||
<DrawerItem name={<Trans>Version</Trans>} onClick={stopPropagation}>
|
||||
<div className="version flex gaps align-center">
|
||||
<span>
|
||||
{release.getVersion()}
|
||||
</span>
|
||||
{!release.getLastVersion() && (
|
||||
<Icon svg="spinner" small/>
|
||||
)}
|
||||
{release.hasNewVersion() && (
|
||||
<span><Trans>New version available:</Trans> <b>{release.getLastVersion()}</b></span>
|
||||
)}
|
||||
</div>
|
||||
</DrawerItem>
|
||||
<DrawerItem name={<Trans>Status</Trans>} className="status" labelsOnly>
|
||||
<Badge
|
||||
label={release.getStatus()}
|
||||
className={cssNames("status", kebabCase(release.getStatus()))}
|
||||
/>
|
||||
</DrawerItem>
|
||||
{this.renderValues()}
|
||||
<DrawerTitle title={_i18n._(t`Notes`)}/>
|
||||
{this.renderNotes()}
|
||||
<DrawerTitle title={_i18n._(t`Resources`)}/>
|
||||
{this.renderResources()}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
render() {
|
||||
const { release, hideDetails } = this.props
|
||||
const title = release ? <Trans>Release: {release.getName()}</Trans> : ""
|
||||
const toolbar = <HelmReleaseMenu release={release} toolbar hideDetails={hideDetails}/>
|
||||
return (
|
||||
<Drawer
|
||||
className={cssNames("ReleaseDetails", themeStore.activeTheme.type)}
|
||||
usePortal={true}
|
||||
open={!!release}
|
||||
title={title}
|
||||
onClose={hideDetails}
|
||||
toolbar={toolbar}
|
||||
>
|
||||
{this.renderContent()}
|
||||
</Drawer>
|
||||
)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user