cleanup Lens repo with tighter linting

Signed-off-by: Sebastian Malton <smalton@mirantis.com>
This commit is contained in:
Sebastian Malton committed 2020-07-09 17:00:23 -04:00
1 parent e468105143
commit b1ff34879a
470 files changed
+8447 -7443

No files matched your search

@@ -7,7 +7,7 @@ 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 { HelmRelease, helmReleasesApi, ReleaseInfo } from "../../api/endpoints/helm-releases.api";
import { HelmReleaseMenu } from "./release-menu";
import { Drawer, DrawerItem, DrawerTitle } from "../drawer";
import { Badge } from "../badge";
@@ -35,14 +35,16 @@ interface Props {
@observer
export class ReleaseDetails extends Component<Props> {
@observable details: IReleaseDetails;
@observable details: ReleaseInfo;
@observable values = "";
@observable saving = false;
@observable releaseSecret: Secret;
@disposeOnUnmount
releaseSelector = reaction(() => this.props.release, release => {
if (!release) return;
if (!release) {
return;
}
this.loadDetails();
this.loadValues();
this.releaseSecret = null;
@@ -51,33 +53,36 @@ export class ReleaseDetails extends Component<Props> {
@disposeOnUnmount
secretWatcher = reaction(() => secretsStore.items.toJS(), () => {
if (!this.props.release) return;
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;
if (isEqual(this.releaseSecret.getLabels(), secret.getLabels())) {
return;
}
this.loadDetails();
}
this.releaseSecret = secret;
});
async loadDetails() {
async loadDetails(): Promise<void> {
const { release } = this.props;
this.details = null;
this.details = await helmReleasesApi.get(release.getName(), release.getNs());
this.details = await helmReleasesApi.get(release.getName(), release.namespace);
}
async loadValues() {
async loadValues(): Promise<void> {
const { release } = this.props;
this.values = "";
this.values = await helmReleasesApi.getValues(release.getName(), release.getNs());
this.values = await helmReleasesApi.getValues(release.getName(), release.namespace);
}
updateValues = async () => {
updateValues = async (): Promise<void> => {
const { release } = this.props;
const name = release.getName();
const namespace = release.getNs()
const { namespace, name} = release;
const data = {
chart: release.getChart(),
repo: await release.getRepo(),
@@ -96,13 +101,13 @@ export class ReleaseDetails extends Component<Props> {
this.saving = false;
}
upgradeVersion = () => {
upgradeVersion = (): void => {
const { release, hideDetails } = this.props;
createUpgradeChartTab(release);
hideDetails();
}
renderValues() {
renderValues(): JSX.Element {
const { values, saving } = this;
return (
<div className="values">
@@ -111,7 +116,7 @@ export class ReleaseDetails extends Component<Props> {
<AceEditor
mode="yaml"
value={values}
onChange={values => this.values = values}
onChange={(values): string => this.values = values}
/>
<Button
primary
@@ -121,11 +126,13 @@ export class ReleaseDetails extends Component<Props> {
/>
</div>
</div>
)
);
}
renderNotes() {
if (!this.details.info?.notes) return null;
renderNotes(): JSX.Element {
if (!this.details.info?.notes) {
return null;
}
const { notes } = this.details.info;
return (
<div className="notes">
@@ -134,9 +141,11 @@ export class ReleaseDetails extends Component<Props> {
);
}
renderResources() {
renderResources(): JSX.Element {
const { resources } = this.details;
if (!resources) return null;
if (!resources) {
return null;
}
const groups = groupBy(resources, item => item.kind);
const tables = Object.entries(groups).map(([kind, items]) => {
return (
@@ -177,10 +186,12 @@ export class ReleaseDetails extends Component<Props> {
);
}
renderContent() {
renderContent(): JSX.Element {
const { release } = this.props;
const { details } = this;
if (!release) return null;
if (!release) {
return null;
}
if (!details) {
return <Spinner center/>;
}
@@ -201,7 +212,7 @@ export class ReleaseDetails extends Component<Props> {
{release.getUpdated()} <Trans>ago</Trans> ({release.updated})
</DrawerItem>
<DrawerItem name={<Trans>Namespace</Trans>}>
{release.getNs()}
{release.namespace}
</DrawerItem>
<DrawerItem name={<Trans>Version</Trans>} onClick={stopPropagation}>
<div className="version flex gaps align-center">
@@ -222,13 +233,13 @@ export class ReleaseDetails extends Component<Props> {
<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}/>
render(): JSX.Element {
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)}
@@ -240,6 +251,6 @@ export class ReleaseDetails extends Component<Props> {
>
{this.renderContent()}
</Drawer>
)
);
}
}
@@ -17,26 +17,28 @@ interface Props extends MenuActionsProps {
export class HelmReleaseMenu extends React.Component<Props> {
@autobind()
remove() {
remove(): Promise<void> {
return releaseStore.remove(this.props.release);
}
@autobind()
upgrade() {
upgrade(): void {
const { release, hideDetails } = this.props;
createUpgradeChartTab(release);
hideDetails && hideDetails();
}
@autobind()
rollback() {
rollback(): void {
ReleaseRollbackDialog.open(this.props.release);
}
renderContent() {
renderContent(): JSX.Element {
const { release, toolbar } = this.props;
if (!release) return;
const hasRollback = release && release.getRevision() > 1;
if (!release) {
return;
}
const hasRollback = release && release.revision > 1;
return (
<>
{hasRollback && (
@@ -46,18 +48,19 @@ export class HelmReleaseMenu extends React.Component<Props> {
</MenuItem>
)}
</>
)
);
}
render() {
const { className, release, ...menuProps } = this.props;
render(): JSX.Element {
const { className, release: _release, ...menuProps } = this.props;
return (
<MenuActions
{...menuProps}
className={cssNames("HelmReleaseMenu", className)}
removeAction={this.remove}
children={this.renderContent()}
/>
>
{this.renderContent()}
</MenuActions>
);
}
}
@@ -6,11 +6,11 @@ import { observer } from "mobx-react";
import { Trans } from "@lingui/macro";
import { Dialog, DialogProps } from "../dialog";
import { Wizard, WizardStep } from "../wizard";
import { HelmRelease, helmReleasesApi, IReleaseRevision } from "../../api/endpoints/helm-releases.api";
import { HelmRelease, helmReleasesApi, ReleaseRevision } from "../../api/endpoints/helm-releases.api";
import { releaseStore } from "./release.store";
import { Select, SelectOption } from "../select";
import { Notifications } from "../notifications";
import orderBy from "lodash/orderBy"
import orderBy from "lodash/orderBy";
interface Props extends DialogProps {
}
@@ -21,15 +21,15 @@ export class ReleaseRollbackDialog extends React.Component<Props> {
@observable.ref static release: HelmRelease = null;
@observable isLoading = false;
@observable revision: IReleaseRevision;
@observable revisions = observable.array<IReleaseRevision>();
@observable revision: ReleaseRevision;
@observable revisions = observable.array<ReleaseRevision>();
static open(release: HelmRelease) {
static open(release: HelmRelease): void {
ReleaseRollbackDialog.isOpen = true;
ReleaseRollbackDialog.release = release;
}
static close() {
static close(): void {
ReleaseRollbackDialog.isOpen = false;
}
@@ -37,10 +37,10 @@ export class ReleaseRollbackDialog extends React.Component<Props> {
return ReleaseRollbackDialog.release;
}
onOpen = async () => {
onOpen = async (): Promise<void> => {
this.isLoading = true;
const currentRevision = this.release.getRevision();
let releases = await helmReleasesApi.getHistory(this.release.getName(), this.release.getNs());
const currentRevision = this.release.revision;
let releases = await helmReleasesApi.getHistory(this.release.getName(), this.release.namespace);
releases = releases.filter(item => item.revision !== currentRevision); // remove current
releases = orderBy(releases, "revision", "desc"); // sort
this.revisions.replace(releases);
@@ -48,24 +48,24 @@ export class ReleaseRollbackDialog extends React.Component<Props> {
this.isLoading = false;
}
rollback = async () => {
rollback = async (): Promise<void> => {
const revisionNumber = this.revision.revision;
try {
await releaseStore.rollback(this.release.getName(), this.release.getNs(), revisionNumber);
await releaseStore.rollback(this.release.getName(), this.release.namespace, revisionNumber);
this.close();
} catch (err) {
Notifications.error(err);
}
};
close = () => {
close = (): void => {
ReleaseRollbackDialog.close();
}
renderContent() {
renderContent(): JSX.Element {
const { revision, revisions } = this;
if (!revision) {
return <p><Trans>No revisions to rollback.</Trans></p>
return <p><Trans>No revisions to rollback.</Trans></p>;
}
return (
<div className="flex gaps align-center">
@@ -74,17 +74,19 @@ export class ReleaseRollbackDialog extends React.Component<Props> {
themeName="light"
value={revision}
options={revisions}
formatOptionLabel={({ value }: SelectOption<IReleaseRevision>) => `${value.revision} - ${value.chart}`}
onChange={({ value }: SelectOption<IReleaseRevision>) => this.revision = value}
formatOptionLabel={({ value }: SelectOption<ReleaseRevision>): string => `${value.revision} - ${value.chart}`}
onChange={({ value }: SelectOption<ReleaseRevision>): void => {
this.revision = value;
}}
/>
</div>
)
);
}
render() {
render(): JSX.Element {
const { ...dialogProps } = this.props;
const releaseName = this.release ? this.release.getName() : "";
const header = <h5><Trans>Rollback <b>{releaseName}</b></Trans></h5>
const header = <h5><Trans>Rollback <b>{releaseName}</b></Trans></h5>;
return (
<Dialog
{...dialogProps}
@@ -104,6 +106,6 @@ export class ReleaseRollbackDialog extends React.Component<Props> {
</WizardStep>
</Wizard>
</Dialog>
)
);
}
}
@@ -1,14 +1,14 @@
import { RouteProps } from "react-router"
import { RouteProps } from "react-router";
import { appsRoute } from "../+apps/apps.route";
import { buildURL } from "../../navigation";
export const releaseRoute: RouteProps = {
path: appsRoute.path + "/releases/:namespace?/:name?"
}
};
export interface IReleaseRouteParams {
export interface ReleaseRouteParams {
name?: string;
namespace?: string;
}
export const releaseURL = buildURL<IReleaseRouteParams>(releaseRoute.path);
export const releaseURL = buildURL<ReleaseRouteParams>(releaseRoute.path);
@@ -1,11 +1,12 @@
import isEqual from "lodash/isEqual";
import { action, observable, when, IReactionDisposer, reaction } from "mobx";
import { autobind } from "../../utils";
import { HelmRelease, helmReleasesApi, IReleaseCreatePayload, IReleaseUpdatePayload } from "../../api/endpoints/helm-releases.api";
import { HelmRelease, helmReleasesApi, ReleaseCreatePayload, ReleaseUpdatePayload, ReleaseUpdateDetails } from "../../api/endpoints/helm-releases.api";
import { ItemStore } from "../../item.store";
import { configStore } from "../../config.store";
import { secretsStore } from "../+config-secrets/secrets.store";
import { Secret } from "../../api/endpoints";
import { KubeJsonApiData } from "client/api/kube-json-api";
@autobind()
export class ReleaseStore extends ItemStore<HelmRelease> {
@@ -19,47 +20,51 @@ export class ReleaseStore extends ItemStore<HelmRelease> {
});
}
watch() {
watch(): void {
this.secretWatcher = reaction(() => secretsStore.items.toJS(), () => {
if (this.isLoading) return;
if (this.isLoading) {
return;
}
const secrets = this.getReleaseSecrets();
const amountChanged = secrets.length !== this.releaseSecrets.length;
const labelsChanged = this.releaseSecrets.some(item => {
const secret = secrets.find(secret => secret.getId() == item.getId());
if (!secret) return;
if (!secret) {
return;
}
return !isEqual(item.getLabels(), secret.getLabels());
});
if (amountChanged || labelsChanged) {
this.loadAll();
}
this.releaseSecrets = [...secrets];
})
});
}
unwatch() {
unwatch(): void {
this.secretWatcher();
}
getReleaseSecrets() {
getReleaseSecrets(): Secret[] {
return secretsStore.getByLabel({ owner: "helm" });
}
getReleaseSecret(release: HelmRelease) {
getReleaseSecret(release: HelmRelease): Secret {
const labels = {
owner: "helm",
name: release.getName()
}
};
return secretsStore.getByLabel(labels)
.filter(secret => secret.getNs() == release.getNs())[0];
.filter(secret => secret.getNs() == release.namespace)[0];
}
@action
async loadAll() {
async loadAll(): Promise<void> {
this.isLoading = true;
let items;
let items: HelmRelease[];
try {
const { isClusterAdmin, allowedNamespaces } = configStore;
items = await this.loadItems(!isClusterAdmin ? allowedNamespaces : null);
items = await this.loadItems(...(!isClusterAdmin ? allowedNamespaces : []));
} finally {
if (items) {
items = this.sortItems(items);
@@ -70,42 +75,49 @@ export class ReleaseStore extends ItemStore<HelmRelease> {
}
}
async loadItems(namespaces?: string[]) {
async loadItems(...namespaces: any[]): Promise<HelmRelease[]> {
if (!namespaces) {
return helmReleasesApi.list();
}
else {
} else {
return Promise
.all(namespaces.map(namespace => helmReleasesApi.list(namespace)))
.then(items => items.flat());
}
}
async create(payload: IReleaseCreatePayload) {
async create(payload: ReleaseCreatePayload): Promise<ReleaseUpdateDetails> {
const response = await helmReleasesApi.create(payload);
if (this.isLoaded) this.loadAll();
if (this.isLoaded) {
this.loadAll();
}
return response;
}
async update(name: string, namespace: string, payload: IReleaseUpdatePayload) {
async update(name: string, namespace: string, payload: ReleaseUpdatePayload): Promise<ReleaseUpdateDetails> {
const response = await helmReleasesApi.update(name, namespace, payload);
if (this.isLoaded) this.loadAll();
if (this.isLoaded) {
this.loadAll();
}
return response;
}
async rollback(name: string, namespace: string, revision: number) {
async rollback(name: string, namespace: string, revision: number): Promise<KubeJsonApiData> {
const response = await helmReleasesApi.rollback(name, namespace, revision);
if (this.isLoaded) this.loadAll();
if (this.isLoaded) {
this.loadAll();
}
return response;
}
async remove(release: HelmRelease) {
return super.removeItem(release, () => helmReleasesApi.delete(release.getName(), release.getNs()));
async remove(release: HelmRelease): Promise<void> {
return super.removeItem(release, () => helmReleasesApi.delete(release.getName(), release.namespace));
}
async removeSelectedItems() {
if (!this.selectedItems.length) return;
return Promise.all(this.selectedItems.map(this.remove));
async removeSelectedItems(): Promise<void> {
if (!this.selectedItems.length) {
return;
}
await Promise.all(this.selectedItems.map(this.remove));
}
}
@@ -6,7 +6,7 @@ import { observer } from "mobx-react";
import { Trans } from "@lingui/macro";
import { RouteComponentProps } from "react-router";
import { releaseStore } from "./release.store";
import { IReleaseRouteParams, releaseURL } from "./release.route";
import { ReleaseRouteParams, releaseURL } from "./release.route";
import { HelmRelease } from "../../api/endpoints/helm-releases.api";
import { ReleaseDetails } from "./release-details";
import { ReleaseRollbackDialog } from "./release-rollback-dialog";
@@ -24,59 +24,58 @@ enum sortBy {
updated = "update"
}
interface Props extends RouteComponentProps<IReleaseRouteParams> {
interface Props extends RouteComponentProps<ReleaseRouteParams> {
}
@observer
export class HelmReleases extends Component<Props> {
componentDidMount() {
componentDidMount(): void {
// Watch for secrets associated with releases and react to their changes
releaseStore.watch();
}
componentWillUnmount() {
componentWillUnmount(): void {
releaseStore.unwatch();
}
get selectedRelease() {
get selectedRelease(): HelmRelease {
const { match: { params: { name, namespace } } } = this.props;
return releaseStore.items.find(release => {
return release.getName() == name && release.getNs() == namespace;
return release.getName() == name && release.namespace == namespace;
});
}
showDetails = (item: HelmRelease) => {
showDetails = (item: HelmRelease): void => {
if (!item) {
navigation.merge(releaseURL())
}
else {
navigation.merge(releaseURL());
} else {
navigation.merge(releaseURL({
params: {
name: item.getName(),
namespace: item.getNs()
namespace: item.namespace
}
}))
}));
}
}
hideDetails = () => {
hideDetails = (): void => {
this.showDetails(null);
}
renderRemoveDialogMessage(selectedItems: HelmRelease[]) {
renderRemoveDialogMessage(selectedItems: HelmRelease[]): JSX.Element {
const releaseNames = selectedItems.map(item => item.getName()).join(", ");
return (
<div>
<Trans>Remove <b>{releaseNames}</b>?</Trans>
<p className="warning">
<Trans>Note: StatefulSet Volumes won't be deleted automatically</Trans>
<Trans>Note: StatefulSet Volumes won&apos;t be deleted automatically</Trans>
</p>
</div>
)
);
}
render() {
render(): JSX.Element {
return (
<>
<ItemListLayout
@@ -84,19 +83,19 @@ export class HelmReleases extends Component<Props> {
store={releaseStore}
dependentStores={[secretsStore]}
sortingCallbacks={{
[sortBy.name]: (release: HelmRelease) => release.getName(),
[sortBy.namespace]: (release: HelmRelease) => release.getNs(),
[sortBy.revision]: (release: HelmRelease) => release.getRevision(),
[sortBy.chart]: (release: HelmRelease) => release.getChart(),
[sortBy.status]: (release: HelmRelease) => release.getStatus(),
[sortBy.updated]: (release: HelmRelease) => release.getUpdated(false, false),
[sortBy.name]: (release: HelmRelease): string => release.getName(),
[sortBy.namespace]: (release: HelmRelease): string => release.namespace,
[sortBy.revision]: (release: HelmRelease): number => release.revision,
[sortBy.chart]: (release: HelmRelease): string => release.getChart(),
[sortBy.status]: (release: HelmRelease): string => release.status,
[sortBy.updated]: (release: HelmRelease): string | number => release.getUpdated(false, false),
}}
searchFilters={[
(release: HelmRelease) => release.getName(),
(release: HelmRelease) => release.getNs(),
(release: HelmRelease) => release.getChart(),
(release: HelmRelease) => release.getStatus(),
(release: HelmRelease) => release.getVersion(),
(release: HelmRelease): string => release.getName(),
(release: HelmRelease): string => release.namespace,
(release: HelmRelease): string => release.getChart(),
(release: HelmRelease): string => release.getStatus(),
(release: HelmRelease): string | number => release.getVersion(),
]}
renderHeaderTitle={<Trans>Releases</Trans>}
renderTableHeader={[
@@ -109,30 +108,30 @@ export class HelmReleases extends Component<Props> {
{ title: <Trans>Status</Trans>, className: "status", sortBy: sortBy.status },
{ title: <Trans>Updated</Trans>, className: "updated", sortBy: sortBy.updated },
]}
renderTableContents={(release: HelmRelease) => {
renderTableContents={(release: HelmRelease): (string | number | React.ReactNode)[] => {
const version = release.getVersion();
return [
release.getName(),
release.getNs(),
release.namespace,
release.getChart(),
release.getRevision(),
release.revision,
<>
{version}
</>,
release.appVersion,
{ title: release.getStatus(), className: kebabCase(release.getStatus()) },
release.getUpdated(),
]
];
}}
renderItemMenu={(release: HelmRelease) => {
renderItemMenu={(release: HelmRelease): JSX.Element => {
return (
<HelmReleaseMenu
release={release}
removeConfirmationMessage={this.renderRemoveDialogMessage([release])}
/>
)
);
}}
customizeRemoveDialog={(selectedItems: HelmRelease[]) => ({
customizeRemoveDialog={(selectedItems: HelmRelease[]): {message: JSX.Element} => ({
message: this.renderRemoveDialogMessage(selectedItems)
})}
detailsItem={this.selectedRelease}