1
0
mirror of https://github.com/lensapp/lens.git synced 2025-05-20 05:10:56 +00:00
lens/src/renderer/components/dock/create-resource/view.tsx
Sebastian Malton 24e8861a1a
Release/v6.0.2 alpha.0 (#6116)
* Fix create release PR to cherry-pick commits

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Fix create release PR to cherry-pick commits

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* release v6.0.2-alpha.0

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Fix Badges being too small when scrollable and not expandable (#5987)

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Remove Tabs hover line width transition (#6020)

Signed-off-by: Alex Andreev <alex.andreev.email@gmail.com>

Signed-off-by: Alex Andreev <alex.andreev.email@gmail.com>

* Fix distribution detector erroneously depending on previous metadata (#6023)

Signed-off-by: Sebastian Malton <sebastian@malton.name>

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Override @astronautlabs/jsonpath's underscore version (#6044)

* Override @astronautlabs/jsonpath's underscore version

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Remove use of buggy 'yarn check'

Signed-off-by: Sebastian Malton <sebastian@malton.name>

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Don't error out if we can't find resources from helm in our cluster, and handle "blank" output from kubectl gracefully. (#6039)

* Use official node-fetch 2.x (#6049)

* Fix UI for scaling ReplicaSets (#6052)

* Use color-scheme: auto on all iframes (#6074)

Signed-off-by: Alex Andreev <alex.andreev.email@gmail.com>

Signed-off-by: Alex Andreev <alex.andreev.email@gmail.com>

* Use abort-controller package to fix typing issues (#6077)

* Use default export to fix issue with package lying with types (#6081)

Signed-off-by: Sebastian Malton <sebastian@malton.name>

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Switch ubuntu CI to ubuntu-20.04 (#6078)

Signed-off-by: Sebastian Malton <sebastian@malton.name>

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Fix <Select/> text overflow below baseline (#6085)

* Fix: do not crop <Select/> single value

Signed-off-by: Alex Andreev <alex.andreev.email@gmail.com>

* Fix: do not crop namespace selector placeholder

Signed-off-by: Alex Andreev <alex.andreev.email@gmail.com>

* Align working dir input height with others

Signed-off-by: Alex Andreev <alex.andreev.email@gmail.com>

* Linter fix

Signed-off-by: Alex Andreev <alex.andreev.email@gmail.com>

Signed-off-by: Alex Andreev <alex.andreev.email@gmail.com>

* Prevent massed remounting of dock tabs when dock height changes (#6104)

* Update injectable to make withInjectables have authentic React reconciliation

Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com>

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Make some dock tabs have primitive props to have them React reconcile properly

Currently tab objects that are stored in a storage change reference on every change of dock height, making them less usable as React prop for causing involuntary remounting.

Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com>

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>

* Fix node conditions column text-align (#6092)

Signed-off-by: Alex Andreev <alex.andreev.email@gmail.com>

Signed-off-by: Alex Andreev <alex.andreev.email@gmail.com>

* Make cluster #app component transparent (#6076)

until theme ready

Signed-off-by: Alex Andreev <alex.andreev.email@gmail.com>

Signed-off-by: Alex Andreev <alex.andreev.email@gmail.com>

* Fix badge not expanding on click when appropriate (#6029)

* Fix badge not expanding on click when appropriate

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Fix snapshots

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Fix snapshots

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Update other snapshots

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Remove unneccessary code

Signed-off-by: Sebastian Malton <sebastian@malton.name>

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* Disable fail-fast on the testing CI jobs (#6080)

- There are several reasons why these might fail that are irrelavent to
  the other pipelines. So we should just let them continue

Signed-off-by: Sebastian Malton <sebastian@malton.name>

Signed-off-by: Sebastian Malton <sebastian@malton.name>

Signed-off-by: Sebastian Malton <sebastian@malton.name>
Signed-off-by: Alex Andreev <alex.andreev.email@gmail.com>
Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>
Co-authored-by: Alex Andreev <alex.andreev.email@gmail.com>
Co-authored-by: Michael Pearson <mipearson@gmail.com>
Co-authored-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>
Co-authored-by: Carlos René Mederos Arias <krlosmederos@gmail.com>
Co-authored-by: Janne Savolainen <janne.savolainen@live.fi>
2022-08-26 15:13:13 -04:00

173 lines
5.5 KiB
TypeScript

/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import React from "react";
import type { SelectOption } from "../../select";
import { Select } from "../../select";
import yaml from "js-yaml";
import type { IComputedValue } from "mobx";
import { makeObservable, observable } from "mobx";
import { observer } from "mobx-react";
import type { CreateResourceTabStore } from "./store";
import { EditorPanel } from "../editor-panel";
import { InfoPanel } from "../info-panel";
import * as resourceApplierApi from "../../../../common/k8s-api/endpoints/resource-applier.api";
import { Notifications } from "../../notifications";
import logger from "../../../../common/logger";
import type { ApiManager } from "../../../../common/k8s-api/api-manager";
import { isObject, prevDefault } from "../../../utils";
import { withInjectables } from "@ogre-tools/injectable-react";
import createResourceTabStoreInjectable from "./store.injectable";
import createResourceTemplatesInjectable from "./create-resource-templates.injectable";
import { Spinner } from "../../spinner";
import type { GroupBase } from "react-select";
import type { Navigate } from "../../../navigation/navigate.injectable";
import type { GetDetailsUrl } from "../../kube-detail-params/get-details-url.injectable";
import apiManagerInjectable from "../../../../common/k8s-api/api-manager/manager.injectable";
import getDetailsUrlInjectable from "../../kube-detail-params/get-details-url.injectable";
import navigateInjectable from "../../../navigation/navigate.injectable";
export interface CreateResourceProps {
tabId: string;
}
interface Dependencies {
createResourceTemplates: IComputedValue<GroupBase<{ label: string; value: string }>[]>;
createResourceTabStore: CreateResourceTabStore;
apiManager: ApiManager;
navigate: Navigate;
getDetailsUrl: GetDetailsUrl;
}
@observer
class NonInjectedCreateResource extends React.Component<CreateResourceProps & Dependencies> {
@observable error = "";
constructor(props: CreateResourceProps & Dependencies) {
super(props);
makeObservable(this);
}
get tabId() {
return this.props.tabId;
}
get data() {
return this.props.createResourceTabStore.getData(this.tabId) ?? "";
}
onChange = (value: string) => {
this.error = ""; // reset first, validation goes later
this.props.createResourceTabStore.setData(this.tabId, value);
};
onError = (error: Error | string) => {
this.error = error.toString();
};
create = async (): Promise<void> => {
const { apiManager, getDetailsUrl, navigate } = this.props;
if (this.error || !this.data?.trim()) {
// do not save when field is empty or there is an error
return;
}
// skip empty documents
const resources = yaml.loadAll(this.data).filter(isObject);
if (resources.length === 0) {
return void logger.info("Nothing to create");
}
const creatingResources = resources.map(async (resource) => {
try {
const data = await resourceApplierApi.update(resource);
const { kind, apiVersion, metadata: { name, namespace }} = data;
const showDetails = () => {
const resourceLink = apiManager.lookupApiLink({ kind, apiVersion, name, namespace });
navigate(getDetailsUrl(resourceLink));
close();
};
const close = Notifications.ok(
<p>
{kind}
{" "}
<a onClick={prevDefault(showDetails)}>
{name}
</a>
{" successfully created."}
</p>,
);
} catch (error) {
Notifications.checkedError(error, "Unknown error occured while creating resources");
}
});
await Promise.allSettled(creatingResources);
};
renderControls() {
return (
<div className="flex gaps align-center">
<Select<string, SelectOption<string>, false>
id="create-resource-resource-templates-input"
controlShouldRenderValue={false} // always keep initial placeholder
className="TemplateSelect"
placeholder="Select Template ..."
options={this.props.createResourceTemplates.get()}
formatGroupLabel={group => group.label}
menuPlacement="top"
themeName="outlined"
onChange={(option) => {
if (option) {
this.props.createResourceTabStore.setData(this.tabId, option.value);
}
}}
/>
</div>
);
}
render() {
const { tabId, data, error } = this;
return (
<div className="CreateResource flex column">
<InfoPanel
tabId={tabId}
error={error}
controls={this.renderControls()}
submit={this.create}
submitLabel="Create"
showNotifications={false}
/>
<EditorPanel
tabId={tabId}
value={data}
onChange={this.onChange}
onError={this.onError}
/>
</div>
);
}
}
export const CreateResource = withInjectables<Dependencies, CreateResourceProps>(NonInjectedCreateResource, {
getPlaceholder: () => <Spinner center />,
getProps: async (di, props) => ({
...props,
createResourceTabStore: di.inject(createResourceTabStoreInjectable),
createResourceTemplates: await di.inject(createResourceTemplatesInjectable),
apiManager: di.inject(apiManagerInjectable),
getDetailsUrl: di.inject(getDetailsUrlInjectable),
navigate: di.inject(navigateInjectable),
}),
});