mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Mobx-6 migration (#2718)
* mobx-6 migration -- part 1 Signed-off-by: Roman <ixrock@gmail.com> * mobx-6 migration -- part 2 (npx mobx-undecorate --keepDecorators) Signed-off-by: Roman <ixrock@gmail.com> * mobx-6 migration -- part 3 (more fixes) Signed-off-by: Roman <ixrock@gmail.com> * unwrap possible observables from IPC-messaging Signed-off-by: Roman <ixrock@gmail.com> * mobx-6 migration -- remove @autobind as class-decorator Signed-off-by: Roman <ixrock@gmail.com> * mobx-6: replacing @autobind() as method-decorator to @boundMethod Signed-off-by: Roman <ixrock@gmail.com> * mobx-6: use toJS()-wrapper since monkey-patching require(mobx).toJS doesn't work Signed-off-by: Roman <ixrock@gmail.com> * removed `@observable static` Signed-off-by: Roman <ixrock@gmail.com> * use {useDefineForClassFields: true} in tsconfig.json Signed-off-by: Roman <ixrock@gmail.com> * remove ExtendedObservableMap Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * fix: removed makeObservable(this) from "terminal-tab.tsx" Signed-off-by: Roman <ixrock@gmail.com> * storage-helper refactoring Signed-off-by: Roman <ixrock@gmail.com> * normalize usages of #observable-value.toJSON() / attempt to catch the wind Signed-off-by: Roman <ixrock@gmail.com> * refactoring, more possible branch fixes + lint Signed-off-by: Roman <ixrock@gmail.com> * debugging cluster-view error -- part 1 Signed-off-by: Roman <ixrock@gmail.com> * fix: refreshing cluster-view on ready Signed-off-by: Roman <ixrock@gmail.com> * fix: various app-crashes related to KubeObject.spec.* access from "undefined" fix: config-map-details crash Signed-off-by: Roman <ixrock@gmail.com> * fix: namespace-store refactoring / saving selected-namespaces to external json-file Signed-off-by: Roman <ixrock@gmail.com> * fix: don't cache mobx.when(() => this.someObservable) cause might not work as expected due later call of makeObservable(this) in constructor Signed-off-by: Roman <ixrock@gmail.com> * fix: app-crash on editing k8s resource Signed-off-by: Roman <ixrock@gmail.com> * fix: restore "all namespaces" on page reload Signed-off-by: Roman <ixrock@gmail.com> * - fix: persist table-sort params and cluster-view's sidebar state to lens-local-storage - new-feature: auto-open main-window's devtools in development-mode (yes/no/ugly?) Signed-off-by: Roman <ixrock@gmail.com> * fix: crd definition details -> crashing with <AceEditor mode="json"> (added missing mode-file in ace-editor.tsx) Signed-off-by: Roman <ixrock@gmail.com> * fix: crd definitions -> groups selector couldn't deselect last selected option Signed-off-by: Roman <ixrock@gmail.com> * refactoring: extensions-api exports clarification for "@k8slens/extensions" Signed-off-by: Roman <ixrock@gmail.com> * fix: various app-crashes related to kube-events (events page, some details page, overview, etc.) Signed-off-by: Roman <ixrock@gmail.com> * Reverted "use {useDefineForClassFields: true} in tsconfig.json" (various app-crash fixes) This flag seems to be not possible to use with class-inheritance in some cases. Example / demo: `KubeObject` class has initial type definitions for the fields like: "metadata", "kind", etc. and constructor() has Object.assign(this, data); Meanwhile child class, e.g. KubeEvent inherited from KubeObject and has it's own extra type definitions for underlying resource, e.g. "involvedObject", "source", etc. So calling super(data) doesn't work as expected for child class as it's own type definitions overwrites data from parent's constructor with `undefined` at later point. Signed-off-by: Roman <ixrock@gmail.com> * master-merge lint-fixes Signed-off-by: Roman <ixrock@gmail.com> * catalog.tsx / catalog-entities.store.ts refactoring & fixes Signed-off-by: Roman <ixrock@gmail.com> * fix: Catalog -> Browse all tab Signed-off-by: Roman <ixrock@gmail.com> * fix: CommandPalette doesn't appear from global menu by click/hotkey Signed-off-by: Roman <ixrock@gmail.com> * - Merging interfaces & classses to avoid overwriting fields from parent's super(data)-call with Object.assign(this, data). Otherwise use "declare" keyword at class field definition. - Revamping {useDefineForClassFields: true} to avoid issues with non-observable class fields in some cases (from previous commit): ``` @observer export class CommandContainer extends React.Component<CommandContainerProps> { // without some defined initial value "commandComponent" is non-observable for some reasons // when tsconfig.ts has {useDefineForClassFields:false} @observable.ref commandComponent: React.ReactNode = null; constructor(props: CommandContainerProps) { super(props); makeObservable(this); } ``` Signed-off-by: Roman <ixrock@gmail.com> * update KubeObject class type definition Signed-off-by: Roman <ixrock@gmail.com> * clean up / responding to comments Signed-off-by: Roman <ixrock@gmail.com> * fix: app-crash when navigating to catalog from active cluster-view, refactoring `catalog-entity-store` Signed-off-by: Roman <ixrock@gmail.com> * catalog-pusher clean up, replaced .observe_() to external observe() helper from "mobx" Signed-off-by: Roman <ixrock@gmail.com> * fix: catalog's items stale/non-observable (after connection to the cluster status still "disconnected"), lint-fixes Signed-off-by: Roman <ixrock@gmail.com> * fix: Catalog is empty after closing main-window and re-opening app from Tray Signed-off-by: Roman <ixrock@gmail.com> * fix: HotBar's icon context menu items non-observable (no "disconnect cluster", etc.) Signed-off-by: Roman <ixrock@gmail.com> * lint-fix/license check Signed-off-by: Roman <ixrock@gmail.com> * fix: redirect to catalog when disconnecting active cluster Signed-off-by: Roman <ixrock@gmail.com> * fix: refresh visibility of active cluster-view on switching from hotbar/catalog Signed-off-by: Roman <ixrock@gmail.com> * updated package.json for built-in extensions to use "*" version for packages served from main app Signed-off-by: Roman <ixrock@gmail.com> * - added missing makeObservable(this) to metrics-settings.tsx - updated package-lock.json for built-in extensions - lint fixes Signed-off-by: Roman <ixrock@gmail.com> * master-merge clean up fix, updated package-lock.json for built-in extensions after `make clean-extensions && make build-extensions` Signed-off-by: Roman <ixrock@gmail.com> * fix unit-tests Signed-off-by: Roman <ixrock@gmail.com> * master-merge fixes Signed-off-by: Roman <ixrock@gmail.com> * make lint happy Signed-off-by: Roman <ixrock@gmail.com> * reverted some changes, removed auto-opening devtools in dev-mode Signed-off-by: Roman <ixrock@gmail.com> * merge fixes Signed-off-by: Roman <ixrock@gmail.com> * master-merge conflict fixes: - proper handling and navigating into catalog's active category via URL-builder Signed-off-by: Roman <ixrock@gmail.com> * reverting splitted params for catalog's page route to "/catalog/:group?/:kind?" Signed-off-by: Roman <ixrock@gmail.com> * clean-up: remove app's injecting dependencies from `extensions/kube-object-event-status/package.json` Signed-off-by: Roman <ixrock@gmail.com> * master-merge fix: added missing makeObservable(this) for extensions.tsx Signed-off-by: Roman <ixrock@gmail.com> * fix: catalog entity context menu stale/unobservable Signed-off-by: Roman <ixrock@gmail.com> Co-authored-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>
This commit is contained in:
1 parent
0c45dd807e
commit
2c3b510997
256 files changed
+2359
-1473
No files matched your search
@@ -22,7 +22,7 @@
|
||||
import "./add-cluster.scss";
|
||||
import React from "react";
|
||||
import { observer } from "mobx-react";
|
||||
import { action, observable, runInAction } from "mobx";
|
||||
import { action, observable, runInAction, makeObservable } from "mobx";
|
||||
import { KubeConfig } from "@kubernetes/client-node";
|
||||
import { AceEditor } from "../ace-editor";
|
||||
import { Button } from "../button";
|
||||
@@ -50,6 +50,11 @@ export class AddCluster extends React.Component {
|
||||
|
||||
kubeContexts = observable.map<string, KubeConfig>();
|
||||
|
||||
constructor(props: {}) {
|
||||
super(props);
|
||||
makeObservable(this);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
appEventBus.emit({ name: "cluster-add", action: "start" });
|
||||
}
|
||||
|
||||
@@ -23,10 +23,10 @@ import "./helm-chart-details.scss";
|
||||
|
||||
import React, { Component } from "react";
|
||||
import { getChartDetails, HelmChart } from "../../api/endpoints/helm-charts.api";
|
||||
import { observable, autorun } from "mobx";
|
||||
import { observable, autorun, makeObservable } from "mobx";
|
||||
import { observer } from "mobx-react";
|
||||
import { Drawer, DrawerItem } from "../drawer";
|
||||
import { autobind, stopPropagation } from "../../utils";
|
||||
import { boundMethod, stopPropagation } from "../../utils";
|
||||
import { MarkdownViewer } from "../markdown-viewer";
|
||||
import { Spinner } from "../spinner";
|
||||
import { Button } from "../button";
|
||||
@@ -48,6 +48,11 @@ export class HelmChartDetails extends Component<Props> {
|
||||
|
||||
private abortController?: AbortController;
|
||||
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
makeObservable(this);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this.abortController?.abort();
|
||||
}
|
||||
@@ -67,7 +72,7 @@ export class HelmChartDetails extends Component<Props> {
|
||||
});
|
||||
});
|
||||
|
||||
@autobind()
|
||||
@boundMethod
|
||||
async onVersionChange({ value: version }: SelectOption<string>) {
|
||||
this.selectedChart = this.chartVersions.find(chart => chart.version === version);
|
||||
this.readme = null;
|
||||
@@ -84,7 +89,7 @@ export class HelmChartDetails extends Component<Props> {
|
||||
}
|
||||
}
|
||||
|
||||
@autobind()
|
||||
@boundMethod
|
||||
install() {
|
||||
createInstallChartTab(this.selectedChart);
|
||||
this.props.hideDetails();
|
||||
|
||||
@@ -20,8 +20,8 @@
|
||||
*/
|
||||
|
||||
import semver from "semver";
|
||||
import { observable } from "mobx";
|
||||
import { autobind } from "../../utils";
|
||||
import { observable, makeObservable } from "mobx";
|
||||
import { autoBind } from "../../utils";
|
||||
import { getChartDetails, HelmChart, listCharts } from "../../api/endpoints/helm-charts.api";
|
||||
import { ItemStore } from "../../item.store";
|
||||
import flatten from "lodash/flatten";
|
||||
@@ -31,10 +31,16 @@ export interface IChartVersion {
|
||||
version: string;
|
||||
}
|
||||
|
||||
@autobind()
|
||||
export class HelmChartStore extends ItemStore<HelmChart> {
|
||||
@observable versions = observable.map<string, IChartVersion[]>();
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
makeObservable(this);
|
||||
autoBind(this);
|
||||
}
|
||||
|
||||
async loadAll() {
|
||||
try {
|
||||
const res = await this.loadItems(() => listCharts());
|
||||
|
||||
@@ -57,10 +57,10 @@ export class HelmCharts extends Component<Props> {
|
||||
|
||||
showDetails = (chart: HelmChart) => {
|
||||
if (!chart) {
|
||||
navigation.merge(helmChartsURL());
|
||||
navigation.push(helmChartsURL());
|
||||
}
|
||||
else {
|
||||
navigation.merge(helmChartsURL({
|
||||
navigation.push(helmChartsURL({
|
||||
params: {
|
||||
chartName: chart.getName(),
|
||||
repo: chart.getRepository(),
|
||||
|
||||
@@ -24,7 +24,7 @@ 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 { observable, reaction, makeObservable } from "mobx";
|
||||
import { Link } from "react-router-dom";
|
||||
import kebabCase from "lodash/kebabCase";
|
||||
import { getRelease, getReleaseValues, HelmRelease, IReleaseDetails } from "../../api/endpoints/helm-releases.api";
|
||||
@@ -72,7 +72,7 @@ export class ReleaseDetails extends Component<Props> {
|
||||
);
|
||||
|
||||
@disposeOnUnmount
|
||||
secretWatcher = reaction(() => secretsStore.items.toJS(), () => {
|
||||
secretWatcher = reaction(() => secretsStore.getItems(), () => {
|
||||
if (!this.props.release) return;
|
||||
const { getReleaseSecret } = releaseStore;
|
||||
const { release } = this.props;
|
||||
@@ -85,6 +85,11 @@ export class ReleaseDetails extends Component<Props> {
|
||||
this.releaseSecret = secret;
|
||||
});
|
||||
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
makeObservable(this);
|
||||
}
|
||||
|
||||
async loadDetails() {
|
||||
const { release } = this.props;
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
import React from "react";
|
||||
import type { HelmRelease } from "../../api/endpoints/helm-releases.api";
|
||||
import { autobind, cssNames } from "../../utils";
|
||||
import { boundMethod, cssNames } from "../../utils";
|
||||
import { releaseStore } from "./release.store";
|
||||
import { MenuActions, MenuActionsProps } from "../menu/menu-actions";
|
||||
import { MenuItem } from "../menu";
|
||||
@@ -35,12 +35,12 @@ interface Props extends MenuActionsProps {
|
||||
}
|
||||
|
||||
export class HelmReleaseMenu extends React.Component<Props> {
|
||||
@autobind()
|
||||
@boundMethod
|
||||
remove() {
|
||||
return releaseStore.remove(this.props.release);
|
||||
}
|
||||
|
||||
@autobind()
|
||||
@boundMethod
|
||||
upgrade() {
|
||||
const { release, hideDetails } = this.props;
|
||||
|
||||
@@ -48,7 +48,7 @@ export class HelmReleaseMenu extends React.Component<Props> {
|
||||
hideDetails && hideDetails();
|
||||
}
|
||||
|
||||
@autobind()
|
||||
@boundMethod
|
||||
rollback() {
|
||||
ReleaseRollbackDialog.open(this.props.release);
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
import "./release-rollback-dialog.scss";
|
||||
|
||||
import React from "react";
|
||||
import { observable } from "mobx";
|
||||
import { observable, makeObservable } from "mobx";
|
||||
import { observer } from "mobx-react";
|
||||
import { Dialog, DialogProps } from "../dialog";
|
||||
import { Wizard, WizardStep } from "../wizard";
|
||||
@@ -35,26 +35,33 @@ import orderBy from "lodash/orderBy";
|
||||
interface Props extends DialogProps {
|
||||
}
|
||||
|
||||
const dialogState = observable.object({
|
||||
isOpen: false,
|
||||
release: null as HelmRelease,
|
||||
});
|
||||
|
||||
@observer
|
||||
export class ReleaseRollbackDialog extends React.Component<Props> {
|
||||
@observable static isOpen = false;
|
||||
@observable.ref static release: HelmRelease = null;
|
||||
|
||||
@observable isLoading = false;
|
||||
@observable revision: IReleaseRevision;
|
||||
@observable revisions = observable.array<IReleaseRevision>();
|
||||
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
makeObservable(this);
|
||||
}
|
||||
|
||||
static open(release: HelmRelease) {
|
||||
ReleaseRollbackDialog.isOpen = true;
|
||||
ReleaseRollbackDialog.release = release;
|
||||
dialogState.isOpen = true;
|
||||
dialogState.release = release;
|
||||
}
|
||||
|
||||
static close() {
|
||||
ReleaseRollbackDialog.isOpen = false;
|
||||
dialogState.isOpen = false;
|
||||
}
|
||||
|
||||
get release(): HelmRelease {
|
||||
return ReleaseRollbackDialog.release;
|
||||
return dialogState.release;
|
||||
}
|
||||
|
||||
onOpen = async () => {
|
||||
@@ -115,7 +122,7 @@ export class ReleaseRollbackDialog extends React.Component<Props> {
|
||||
<Dialog
|
||||
{...dialogProps}
|
||||
className="ReleaseRollbackDialog"
|
||||
isOpen={ReleaseRollbackDialog.isOpen}
|
||||
isOpen={dialogState.isOpen}
|
||||
onOpen={this.onOpen}
|
||||
close={this.close}
|
||||
>
|
||||
|
||||
@@ -20,8 +20,8 @@
|
||||
*/
|
||||
|
||||
import isEqual from "lodash/isEqual";
|
||||
import { action, observable, reaction, when } from "mobx";
|
||||
import { autobind } from "../../utils";
|
||||
import { action, observable, reaction, when, makeObservable } from "mobx";
|
||||
import { autoBind } from "../../utils";
|
||||
import { createRelease, deleteRelease, HelmRelease, IReleaseCreatePayload, IReleaseUpdatePayload, listReleases, rollbackRelease, updateRelease } from "../../api/endpoints/helm-releases.api";
|
||||
import { ItemStore } from "../../item.store";
|
||||
import type { Secret } from "../../api/endpoints";
|
||||
@@ -29,19 +29,21 @@ import { secretsStore } from "../+config-secrets/secrets.store";
|
||||
import { namespaceStore } from "../+namespaces/namespace.store";
|
||||
import { Notifications } from "../notifications";
|
||||
|
||||
@autobind()
|
||||
export class ReleaseStore extends ItemStore<HelmRelease> {
|
||||
releaseSecrets = observable.map<string, Secret>();
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
makeObservable(this);
|
||||
autoBind(this);
|
||||
|
||||
when(() => secretsStore.isLoaded, () => {
|
||||
this.releaseSecrets.replace(this.getReleaseSecrets());
|
||||
});
|
||||
}
|
||||
|
||||
watchAssociatedSecrets(): (() => void) {
|
||||
return reaction(() => secretsStore.items.toJS(), () => {
|
||||
return reaction(() => secretsStore.getItems(), () => {
|
||||
if (this.isLoading) return;
|
||||
const newSecrets = this.getReleaseSecrets();
|
||||
const amountChanged = newSecrets.length !== this.releaseSecrets.size;
|
||||
|
||||
@@ -67,7 +67,7 @@ export class HelmReleases extends Component<Props> {
|
||||
}
|
||||
|
||||
showDetails = (item: HelmRelease) => {
|
||||
navigation.merge(releaseURL({
|
||||
navigation.push(releaseURL({
|
||||
params: {
|
||||
name: item.getName(),
|
||||
namespace: item.getNs()
|
||||
@@ -76,7 +76,7 @@ export class HelmReleases extends Component<Props> {
|
||||
};
|
||||
|
||||
hideDetails = () => {
|
||||
navigation.merge(releaseURL());
|
||||
navigation.push(releaseURL());
|
||||
};
|
||||
|
||||
renderRemoveDialogMessage(selectedItems: HelmRelease[]) {
|
||||
|
||||
@@ -24,12 +24,10 @@ import { observer } from "mobx-react";
|
||||
import { TabLayout, TabLayoutRoute } from "../layout/tab-layout";
|
||||
import { HelmCharts, helmChartsRoute, helmChartsURL } from "../+apps-helm-charts";
|
||||
import { HelmReleases, releaseRoute, releaseURL } from "../+apps-releases";
|
||||
import { namespaceUrlParam } from "../+namespaces/namespace.store";
|
||||
|
||||
@observer
|
||||
export class Apps extends React.Component {
|
||||
static get tabRoutes(): TabLayoutRoute[] {
|
||||
const query = namespaceUrlParam.toObjectParam();
|
||||
|
||||
return [
|
||||
{
|
||||
@@ -41,7 +39,7 @@ export class Apps extends React.Component {
|
||||
{
|
||||
title: "Releases",
|
||||
component: HelmReleases,
|
||||
url: releaseURL({ query }),
|
||||
url: releaseURL(),
|
||||
routePath: releaseRoute.path.toString(),
|
||||
},
|
||||
];
|
||||
|
||||
@@ -24,8 +24,8 @@ import React from "react";
|
||||
import { SpeedDial, SpeedDialAction } from "@material-ui/lab";
|
||||
import { Icon } from "../icon";
|
||||
import { disposeOnUnmount, observer } from "mobx-react";
|
||||
import { observable, reaction } from "mobx";
|
||||
import { autobind } from "../../../common/utils";
|
||||
import { observable, reaction, makeObservable } from "mobx";
|
||||
import { boundMethod } from "../../../common/utils";
|
||||
import type { CatalogCategory, CatalogEntityAddMenuContext, CatalogEntityAddMenu } from "../../api/catalog-entity";
|
||||
import { EventEmitter } from "events";
|
||||
import { navigate } from "../../navigation";
|
||||
@@ -39,6 +39,11 @@ export class CatalogAddButton extends React.Component<CatalogAddButtonProps> {
|
||||
@observable protected isOpen = false;
|
||||
protected menuItems = observable.array<CatalogEntityAddMenu>([]);
|
||||
|
||||
constructor(props: CatalogAddButtonProps) {
|
||||
super(props);
|
||||
makeObservable(this);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
disposeOnUnmount(this, [
|
||||
reaction(() => this.props.category, (category) => {
|
||||
@@ -56,17 +61,17 @@ export class CatalogAddButton extends React.Component<CatalogAddButtonProps> {
|
||||
]);
|
||||
}
|
||||
|
||||
@autobind()
|
||||
@boundMethod
|
||||
onOpen() {
|
||||
this.isOpen = true;
|
||||
}
|
||||
|
||||
@autobind()
|
||||
@boundMethod
|
||||
onClose() {
|
||||
this.isOpen = false;
|
||||
}
|
||||
|
||||
@autobind()
|
||||
@boundMethod
|
||||
onButtonClick() {
|
||||
if (this.menuItems.length == 1) {
|
||||
this.menuItems[0].onClick();
|
||||
|
||||
@@ -19,12 +19,12 @@
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
import { action, computed, IReactionDisposer, observable, reaction } from "mobx";
|
||||
import { action, computed, IReactionDisposer, makeObservable, observable, reaction } from "mobx";
|
||||
import { catalogEntityRegistry } from "../../api/catalog-entity-registry";
|
||||
import type { CatalogEntity, CatalogEntityActionContext } from "../../api/catalog-entity";
|
||||
import { ItemObject, ItemStore } from "../../item.store";
|
||||
import { autobind } from "../../utils";
|
||||
import { CatalogCategory } from "../../../common/catalog";
|
||||
import { autoBind } from "../../../common/utils";
|
||||
|
||||
export class CatalogEntityItem implements ItemObject {
|
||||
constructor(public entity: CatalogEntity) {}
|
||||
@@ -84,8 +84,13 @@ export class CatalogEntityItem implements ItemObject {
|
||||
}
|
||||
}
|
||||
|
||||
@autobind()
|
||||
export class CatalogEntityStore extends ItemStore<CatalogEntityItem> {
|
||||
constructor() {
|
||||
super();
|
||||
makeObservable(this);
|
||||
autoBind(this);
|
||||
}
|
||||
|
||||
@observable activeCategory?: CatalogCategory;
|
||||
|
||||
@computed get entities() {
|
||||
|
||||
@@ -23,7 +23,7 @@ import "./catalog.scss";
|
||||
import React from "react";
|
||||
import { disposeOnUnmount, observer } from "mobx-react";
|
||||
import { ItemListLayout } from "../item-object-list";
|
||||
import { action, observable, reaction, when } from "mobx";
|
||||
import { action, makeObservable, observable, reaction, when } from "mobx";
|
||||
import { CatalogEntityItem, CatalogEntityStore } from "./catalog-entity.store";
|
||||
import { navigate } from "../../navigation";
|
||||
import { kebabCase } from "lodash";
|
||||
@@ -32,7 +32,6 @@ import { MenuItem, MenuActions } from "../menu";
|
||||
import { CatalogEntityContextMenu, CatalogEntityContextMenuContext, catalogEntityRunContext } from "../../api/catalog-entity";
|
||||
import { Badge } from "../badge";
|
||||
import { HotbarStore } from "../../../common/hotbar-store";
|
||||
import { autobind } from "../../utils";
|
||||
import { ConfirmDialog } from "../confirm-dialog";
|
||||
import { Tab, Tabs } from "../tabs";
|
||||
import { catalogCategoryRegistry } from "../../../common/catalog";
|
||||
@@ -49,12 +48,18 @@ enum sortBy {
|
||||
}
|
||||
|
||||
interface Props extends RouteComponentProps<ICatalogViewRouteParam> {}
|
||||
|
||||
@observer
|
||||
export class Catalog extends React.Component<Props> {
|
||||
@observable private catalogEntityStore?: CatalogEntityStore;
|
||||
@observable.deep private contextMenu: CatalogEntityContextMenuContext;
|
||||
@observable private contextMenu: CatalogEntityContextMenuContext;
|
||||
@observable activeTab?: string;
|
||||
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
makeObservable(this);
|
||||
}
|
||||
|
||||
get routeActiveTab(): string | undefined {
|
||||
const { group, kind } = this.props.match.params ?? {};
|
||||
|
||||
@@ -155,8 +160,7 @@ export class Catalog extends React.Component<Props> {
|
||||
);
|
||||
}
|
||||
|
||||
@autobind()
|
||||
renderItemMenu(item: CatalogEntityItem) {
|
||||
renderItemMenu = (item: CatalogEntityItem) => {
|
||||
const menuItems = this.contextMenu.menuItems.filter((menuItem) => !menuItem.onlyVisibleForSource || menuItem.onlyVisibleForSource === item.entity.metadata.source);
|
||||
|
||||
return (
|
||||
@@ -173,7 +177,7 @@ export class Catalog extends React.Component<Props> {
|
||||
</MenuItem>
|
||||
</MenuActions>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
renderIcon(item: CatalogEntityItem) {
|
||||
const category = catalogCategoryRegistry.getCategoryForEntity(item.entity);
|
||||
|
||||
@@ -23,13 +23,13 @@ import "./cluster-issues.scss";
|
||||
|
||||
import React from "react";
|
||||
import { observer } from "mobx-react";
|
||||
import { computed } from "mobx";
|
||||
import { computed, makeObservable } from "mobx";
|
||||
import { Icon } from "../icon";
|
||||
import { SubHeader } from "../layout/sub-header";
|
||||
import { Table, TableCell, TableHead, TableRow } from "../table";
|
||||
import { nodesStore } from "../+nodes/nodes.store";
|
||||
import { eventStore } from "../+events/event.store";
|
||||
import { autobind, cssNames, prevDefault } from "../../utils";
|
||||
import { boundMethod, cssNames, prevDefault } from "../../utils";
|
||||
import type { ItemObject } from "../../item.store";
|
||||
import { Spinner } from "../spinner";
|
||||
import { ThemeStore } from "../../theme.store";
|
||||
@@ -62,6 +62,11 @@ export class ClusterIssues extends React.Component<Props> {
|
||||
[sortBy.age]: (warning: IWarning) => warning.timeDiffFromNow,
|
||||
};
|
||||
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
makeObservable(this);
|
||||
}
|
||||
|
||||
@computed get warnings() {
|
||||
const warnings: IWarning[] = [];
|
||||
|
||||
@@ -103,7 +108,7 @@ export class ClusterIssues extends React.Component<Props> {
|
||||
return warnings;
|
||||
}
|
||||
|
||||
@autobind()
|
||||
@boundMethod
|
||||
getTableRow(uid: string) {
|
||||
const { warnings } = this;
|
||||
const warning = warnings.find(warn => warn.getId() == uid);
|
||||
|
||||
@@ -19,10 +19,10 @@
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
import { action, observable, reaction, when } from "mobx";
|
||||
import { action, observable, reaction, when, makeObservable } from "mobx";
|
||||
import { KubeObjectStore } from "../../kube-object.store";
|
||||
import { Cluster, clusterApi, IClusterMetrics } from "../../api/endpoints";
|
||||
import { autobind, createStorage } from "../../utils";
|
||||
import { autoBind, createStorage } from "../../utils";
|
||||
import { IMetricsReqParams, normalizeMetrics } from "../../api/endpoints/metrics.api";
|
||||
import { nodesStore } from "../+nodes/nodes.store";
|
||||
import { apiManager } from "../../api/api-manager";
|
||||
@@ -42,7 +42,6 @@ export interface ClusterOverviewStorageState {
|
||||
metricNodeRole: MetricNodeRole,
|
||||
}
|
||||
|
||||
@autobind()
|
||||
export class ClusterOverviewStore extends KubeObjectStore<Cluster> implements ClusterOverviewStorageState {
|
||||
api = clusterApi;
|
||||
|
||||
@@ -72,6 +71,9 @@ export class ClusterOverviewStore extends KubeObjectStore<Cluster> implements Cl
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
makeObservable(this);
|
||||
autoBind(this);
|
||||
|
||||
this.init();
|
||||
}
|
||||
|
||||
|
||||
@@ -19,12 +19,10 @@
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
import { autobind } from "../../utils";
|
||||
import { KubeObjectStore } from "../../kube-object.store";
|
||||
import { HorizontalPodAutoscaler, hpaApi } from "../../api/endpoints/hpa.api";
|
||||
import { apiManager } from "../../api/api-manager";
|
||||
|
||||
@autobind()
|
||||
export class HPAStore extends KubeObjectStore<HorizontalPodAutoscaler> {
|
||||
api = hpaApi;
|
||||
}
|
||||
|
||||
@@ -19,12 +19,10 @@
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
import { autobind } from "../../../common/utils/autobind";
|
||||
import { KubeObjectStore } from "../../kube-object.store";
|
||||
import { apiManager } from "../../api/api-manager";
|
||||
import { LimitRange, limitRangeApi } from "../../api/endpoints/limit-range.api";
|
||||
|
||||
@autobind()
|
||||
export class LimitRangesStore extends KubeObjectStore<LimitRange> {
|
||||
api = limitRangeApi;
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
import "./config-map-details.scss";
|
||||
|
||||
import React from "react";
|
||||
import { autorun, observable } from "mobx";
|
||||
import { autorun, makeObservable, observable } from "mobx";
|
||||
import { disposeOnUnmount, observer } from "mobx-react";
|
||||
import { DrawerTitle } from "../drawer";
|
||||
import { Notifications } from "../notifications";
|
||||
@@ -41,7 +41,12 @@ interface Props extends KubeObjectDetailsProps<ConfigMap> {
|
||||
@observer
|
||||
export class ConfigMapDetails extends React.Component<Props> {
|
||||
@observable isSaving = false;
|
||||
@observable data = observable.map();
|
||||
@observable data = observable.map<string, string>();
|
||||
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
makeObservable(this);
|
||||
}
|
||||
|
||||
async componentDidMount() {
|
||||
disposeOnUnmount(this, [
|
||||
@@ -60,7 +65,10 @@ export class ConfigMapDetails extends React.Component<Props> {
|
||||
|
||||
try {
|
||||
this.isSaving = true;
|
||||
await configMapsStore.update(configMap, { ...configMap, data: this.data.toJSON() });
|
||||
await configMapsStore.update(configMap, {
|
||||
...configMap,
|
||||
data: Object.fromEntries(this.data),
|
||||
});
|
||||
Notifications.ok(
|
||||
<p>
|
||||
<>ConfigMap <b>{configMap.getName()}</b> successfully updated.</>
|
||||
@@ -75,7 +83,7 @@ export class ConfigMapDetails extends React.Component<Props> {
|
||||
const { object: configMap } = this.props;
|
||||
|
||||
if (!configMap) return null;
|
||||
const data = Object.entries(this.data.toJSON());
|
||||
const data = Array.from(this.data.entries());
|
||||
|
||||
return (
|
||||
<div className="ConfigMapDetails">
|
||||
|
||||
@@ -20,11 +20,9 @@
|
||||
*/
|
||||
|
||||
import { KubeObjectStore } from "../../kube-object.store";
|
||||
import { autobind } from "../../utils";
|
||||
import { ConfigMap, configMapApi } from "../../api/endpoints/configmap.api";
|
||||
import { apiManager } from "../../api/api-manager";
|
||||
|
||||
@autobind()
|
||||
export class ConfigMapsStore extends KubeObjectStore<ConfigMap> {
|
||||
api = configMapApi;
|
||||
}
|
||||
|
||||
+1
-3
@@ -20,11 +20,9 @@
|
||||
*/
|
||||
|
||||
import { KubeObjectStore } from "../../kube-object.store";
|
||||
import { autobind } from "../../utils";
|
||||
import { PodDisruptionBudget, pdbApi } from "../../api/endpoints/poddisruptionbudget.api";
|
||||
import { pdbApi, PodDisruptionBudget } from "../../api/endpoints/poddisruptionbudget.api";
|
||||
import { apiManager } from "../../api/api-manager";
|
||||
|
||||
@autobind()
|
||||
export class PodDisruptionBudgetsStore extends KubeObjectStore<PodDisruptionBudget> {
|
||||
api = pdbApi;
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
import "./add-quota-dialog.scss";
|
||||
|
||||
import React from "react";
|
||||
import { computed, observable } from "mobx";
|
||||
import { computed, observable, makeObservable } from "mobx";
|
||||
import { observer } from "mobx-react";
|
||||
import { Dialog, DialogProps } from "../dialog";
|
||||
import { Wizard, WizardStep } from "../wizard";
|
||||
@@ -39,10 +39,12 @@ import { SubTitle } from "../layout/sub-title";
|
||||
interface Props extends DialogProps {
|
||||
}
|
||||
|
||||
const dialogState = observable.object({
|
||||
isOpen: false,
|
||||
});
|
||||
|
||||
@observer
|
||||
export class AddQuotaDialog extends React.Component<Props> {
|
||||
@observable static isOpen = false;
|
||||
|
||||
static defaultQuotas: IResourceQuotaValues = {
|
||||
"limits.cpu": "",
|
||||
"limits.memory": "",
|
||||
@@ -72,12 +74,17 @@ export class AddQuotaDialog extends React.Component<Props> {
|
||||
@observable namespace = this.defaultNamespace;
|
||||
@observable quotas = AddQuotaDialog.defaultQuotas;
|
||||
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
makeObservable(this);
|
||||
}
|
||||
|
||||
static open() {
|
||||
AddQuotaDialog.isOpen = true;
|
||||
dialogState.isOpen = true;
|
||||
}
|
||||
|
||||
static close() {
|
||||
AddQuotaDialog.isOpen = false;
|
||||
dialogState.isOpen = false;
|
||||
}
|
||||
|
||||
@computed get quotaEntries() {
|
||||
@@ -154,7 +161,7 @@ export class AddQuotaDialog extends React.Component<Props> {
|
||||
<Dialog
|
||||
{...dialogProps}
|
||||
className="AddQuotaDialog"
|
||||
isOpen={AddQuotaDialog.isOpen}
|
||||
isOpen={dialogState.isOpen}
|
||||
close={this.close}
|
||||
>
|
||||
<Wizard header={header} done={this.close}>
|
||||
|
||||
@@ -20,11 +20,9 @@
|
||||
*/
|
||||
|
||||
import { KubeObjectStore } from "../../kube-object.store";
|
||||
import { autobind } from "../../utils";
|
||||
import { ResourceQuota, resourceQuotaApi } from "../../api/endpoints/resource-quota.api";
|
||||
import { apiManager } from "../../api/api-manager";
|
||||
|
||||
@autobind()
|
||||
export class ResourceQuotasStore extends KubeObjectStore<ResourceQuota> {
|
||||
api = resourceQuotaApi;
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
import "./add-secret-dialog.scss";
|
||||
|
||||
import React from "react";
|
||||
import { observable } from "mobx";
|
||||
import { observable, makeObservable } from "mobx";
|
||||
import { observer } from "mobx-react";
|
||||
import { Dialog, DialogProps } from "../dialog";
|
||||
import { Wizard, WizardStep } from "../wizard";
|
||||
@@ -57,16 +57,23 @@ interface ISecretTemplate {
|
||||
|
||||
type ISecretField = keyof ISecretTemplate;
|
||||
|
||||
const dialogState = observable.object({
|
||||
isOpen: false,
|
||||
});
|
||||
|
||||
@observer
|
||||
export class AddSecretDialog extends React.Component<Props> {
|
||||
@observable static isOpen = false;
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
makeObservable(this);
|
||||
}
|
||||
|
||||
static open() {
|
||||
AddSecretDialog.isOpen = true;
|
||||
dialogState.isOpen = true;
|
||||
}
|
||||
|
||||
static close() {
|
||||
AddSecretDialog.isOpen = false;
|
||||
dialogState.isOpen = false;
|
||||
}
|
||||
|
||||
private secretTemplate: { [p: string]: ISecretTemplate } = {
|
||||
@@ -205,7 +212,7 @@ export class AddSecretDialog extends React.Component<Props> {
|
||||
<Dialog
|
||||
{...dialogProps}
|
||||
className="AddSecretDialog"
|
||||
isOpen={AddSecretDialog.isOpen}
|
||||
isOpen={dialogState.isOpen}
|
||||
onOpen={this.reset}
|
||||
close={this.close}
|
||||
>
|
||||
|
||||
@@ -23,7 +23,7 @@ import "./secret-details.scss";
|
||||
|
||||
import React from "react";
|
||||
import isEmpty from "lodash/isEmpty";
|
||||
import { autorun, observable } from "mobx";
|
||||
import { autorun, observable, makeObservable } from "mobx";
|
||||
import { disposeOnUnmount, observer } from "mobx-react";
|
||||
import { DrawerItem, DrawerTitle } from "../drawer";
|
||||
import { Input } from "../input";
|
||||
@@ -46,6 +46,11 @@ export class SecretDetails extends React.Component<Props> {
|
||||
@observable data: { [name: string]: string } = {};
|
||||
@observable revealSecret: { [name: string]: boolean } = {};
|
||||
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
makeObservable(this);
|
||||
}
|
||||
|
||||
async componentDidMount() {
|
||||
disposeOnUnmount(this, [
|
||||
autorun(() => {
|
||||
|
||||
@@ -20,11 +20,9 @@
|
||||
*/
|
||||
|
||||
import { KubeObjectStore } from "../../kube-object.store";
|
||||
import { autobind } from "../../utils";
|
||||
import { Secret, secretsApi } from "../../api/endpoints";
|
||||
import { apiManager } from "../../api/api-manager";
|
||||
|
||||
@autobind()
|
||||
export class SecretsStore extends KubeObjectStore<Secret> {
|
||||
api = secretsApi;
|
||||
}
|
||||
|
||||
@@ -24,7 +24,6 @@ import { observer } from "mobx-react";
|
||||
import { TabLayout, TabLayoutRoute } from "../layout/tab-layout";
|
||||
import { ConfigMaps, configMapsRoute, configMapsURL } from "../+config-maps";
|
||||
import { Secrets, secretsRoute, secretsURL } from "../+config-secrets";
|
||||
import { namespaceUrlParam } from "../+namespaces/namespace.store";
|
||||
import { resourceQuotaRoute, ResourceQuotas, resourceQuotaURL } from "../+config-resource-quotas";
|
||||
import { pdbRoute, pdbURL, PodDisruptionBudgets } from "../+config-pod-disruption-budgets";
|
||||
import { HorizontalPodAutoscalers, hpaRoute, hpaURL } from "../+config-autoscalers";
|
||||
@@ -34,14 +33,13 @@ import { LimitRanges, limitRangesRoute, limitRangeURL } from "../+config-limit-r
|
||||
@observer
|
||||
export class Config extends React.Component {
|
||||
static get tabRoutes(): TabLayoutRoute[] {
|
||||
const query = namespaceUrlParam.toObjectParam();
|
||||
const routes: TabLayoutRoute[] = [];
|
||||
|
||||
if (isAllowedResource("configmaps")) {
|
||||
routes.push({
|
||||
title: "ConfigMaps",
|
||||
component: ConfigMaps,
|
||||
url: configMapsURL({ query }),
|
||||
url: configMapsURL(),
|
||||
routePath: configMapsRoute.path.toString(),
|
||||
});
|
||||
}
|
||||
@@ -50,7 +48,7 @@ export class Config extends React.Component {
|
||||
routes.push({
|
||||
title: "Secrets",
|
||||
component: Secrets,
|
||||
url: secretsURL({ query }),
|
||||
url: secretsURL(),
|
||||
routePath: secretsRoute.path.toString(),
|
||||
});
|
||||
}
|
||||
@@ -59,7 +57,7 @@ export class Config extends React.Component {
|
||||
routes.push({
|
||||
title: "Resource Quotas",
|
||||
component: ResourceQuotas,
|
||||
url: resourceQuotaURL({ query }),
|
||||
url: resourceQuotaURL(),
|
||||
routePath: resourceQuotaRoute.path.toString(),
|
||||
});
|
||||
}
|
||||
@@ -68,7 +66,7 @@ export class Config extends React.Component {
|
||||
routes.push({
|
||||
title: "Limit Ranges",
|
||||
component: LimitRanges,
|
||||
url: limitRangeURL({ query }),
|
||||
url: limitRangeURL(),
|
||||
routePath: limitRangesRoute.path.toString(),
|
||||
});
|
||||
}
|
||||
@@ -77,7 +75,7 @@ export class Config extends React.Component {
|
||||
routes.push({
|
||||
title: "HPA",
|
||||
component: HorizontalPodAutoscalers,
|
||||
url: hpaURL({ query }),
|
||||
url: hpaURL(),
|
||||
routePath: hpaRoute.path.toString(),
|
||||
});
|
||||
}
|
||||
@@ -86,7 +84,7 @@ export class Config extends React.Component {
|
||||
routes.push({
|
||||
title: "Pod Disruption Budgets",
|
||||
component: PodDisruptionBudgets,
|
||||
url: pdbURL({ query }),
|
||||
url: pdbURL(),
|
||||
routePath: pdbRoute.path.toString(),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
import "./crd-list.scss";
|
||||
|
||||
import React from "react";
|
||||
import { computed } from "mobx";
|
||||
import { computed, makeObservable } from "mobx";
|
||||
import { observer } from "mobx-react";
|
||||
import { Link } from "react-router-dom";
|
||||
import { stopPropagation } from "../../utils";
|
||||
@@ -35,8 +35,6 @@ import { Icon } from "../icon";
|
||||
|
||||
export const crdGroupsUrlParam = createPageParam<string[]>({
|
||||
name: "groups",
|
||||
multiValues: true,
|
||||
isSystem: true,
|
||||
defaultValue: [],
|
||||
});
|
||||
|
||||
@@ -50,6 +48,11 @@ enum columnId {
|
||||
|
||||
@observer
|
||||
export class CrdList extends React.Component {
|
||||
constructor(props: {}) {
|
||||
super(props);
|
||||
makeObservable(this);
|
||||
}
|
||||
|
||||
get selectedGroups(): string[] {
|
||||
return crdGroupsUrlParam.get();
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ import "./crd-resource-details.scss";
|
||||
import React from "react";
|
||||
import jsonPath from "jsonpath";
|
||||
import { observer } from "mobx-react";
|
||||
import { computed } from "mobx";
|
||||
import { computed, makeObservable } from "mobx";
|
||||
import { cssNames } from "../../utils";
|
||||
import { Badge } from "../badge";
|
||||
import { DrawerItem } from "../drawer";
|
||||
@@ -60,6 +60,11 @@ function convertSpecValue(value: any): any {
|
||||
|
||||
@observer
|
||||
export class CrdResourceDetails extends React.Component<Props> {
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
makeObservable(this);
|
||||
}
|
||||
|
||||
@computed get crd() {
|
||||
return crdStore.getByObject(this.props.object);
|
||||
}
|
||||
|
||||
@@ -19,12 +19,10 @@
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
import { autobind } from "../../utils";
|
||||
import { KubeApi } from "../../api/kube-api";
|
||||
import type { KubeApi } from "../../api/kube-api";
|
||||
import { KubeObjectStore } from "../../kube-object.store";
|
||||
import type { KubeObject } from "../../api/kube-object";
|
||||
|
||||
@autobind()
|
||||
export class CRDResourceStore<T extends KubeObject = any> extends KubeObjectStore<T> {
|
||||
api: KubeApi;
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ import type { RouteComponentProps } from "react-router";
|
||||
import { KubeObjectListLayout } from "../kube-object";
|
||||
import type { KubeObject } from "../../api/kube-object";
|
||||
import type { ICRDRouteParams } from "./crd.route";
|
||||
import { autorun, computed } from "mobx";
|
||||
import { autorun, computed, makeObservable } from "mobx";
|
||||
import { crdStore } from "./crd.store";
|
||||
import type { TableSortCallback } from "../table";
|
||||
import { apiManager } from "../../api/api-manager";
|
||||
@@ -45,6 +45,11 @@ enum columnId {
|
||||
|
||||
@observer
|
||||
export class CrdResources extends React.Component<Props> {
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
makeObservable(this);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
disposeOnUnmount(this, [
|
||||
autorun(() => {
|
||||
|
||||
@@ -19,9 +19,9 @@
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
import { computed, reaction } from "mobx";
|
||||
import { computed, reaction, makeObservable } from "mobx";
|
||||
import { KubeObjectStore } from "../../kube-object.store";
|
||||
import { autobind } from "../../utils";
|
||||
import { autoBind } from "../../utils";
|
||||
import { crdApi, CustomResourceDefinition } from "../../api/endpoints/crd.api";
|
||||
import { apiManager } from "../../api/api-manager";
|
||||
import { KubeApi } from "../../api/kube-api";
|
||||
@@ -39,15 +39,17 @@ function initStore(crd: CustomResourceDefinition) {
|
||||
}
|
||||
}
|
||||
|
||||
@autobind()
|
||||
export class CRDStore extends KubeObjectStore<CustomResourceDefinition> {
|
||||
api = crdApi;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
makeObservable(this);
|
||||
autoBind(this);
|
||||
|
||||
// auto-init stores for crd-s
|
||||
reaction(() => this.items.toJS(), items => items.forEach(initStore));
|
||||
reaction(() => this.getItems(), items => items.forEach(initStore));
|
||||
}
|
||||
|
||||
protected sortItems(items: CustomResourceDefinition[]) {
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
import "./entity-settings.scss";
|
||||
|
||||
import React from "react";
|
||||
import { observable } from "mobx";
|
||||
import { observable, makeObservable } from "mobx";
|
||||
import type { RouteComponentProps } from "react-router";
|
||||
import { observer } from "mobx-react";
|
||||
import { PageLayout } from "../layout/page-layout";
|
||||
@@ -41,6 +41,11 @@ interface Props extends RouteComponentProps<EntitySettingsRouteParams> {
|
||||
export class EntitySettings extends React.Component<Props> {
|
||||
@observable activeTab: string;
|
||||
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
makeObservable(this);
|
||||
}
|
||||
|
||||
get entityId() {
|
||||
return this.props.match.params.entityId;
|
||||
}
|
||||
|
||||
@@ -22,19 +22,23 @@
|
||||
import groupBy from "lodash/groupBy";
|
||||
import compact from "lodash/compact";
|
||||
import { KubeObjectStore } from "../../kube-object.store";
|
||||
import { autobind } from "../../utils";
|
||||
import { autoBind } from "../../utils";
|
||||
import { eventApi, KubeEvent } from "../../api/endpoints/events.api";
|
||||
import type { KubeObject } from "../../api/kube-object";
|
||||
import { Pod } from "../../api/endpoints/pods.api";
|
||||
import { podsStore } from "../+workloads-pods/pods.store";
|
||||
import { apiManager } from "../../api/api-manager";
|
||||
|
||||
@autobind()
|
||||
export class EventStore extends KubeObjectStore<KubeEvent> {
|
||||
api = eventApi;
|
||||
limit = 1000;
|
||||
saveLimit = 50000;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
autoBind(this);
|
||||
}
|
||||
|
||||
protected bindWatchEventsUpdater() {
|
||||
return super.bindWatchEventsUpdater(5000);
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
import "./events.scss";
|
||||
|
||||
import React, { Fragment } from "react";
|
||||
import { computed, observable } from "mobx";
|
||||
import { computed, observable, makeObservable } from "mobx";
|
||||
import { observer } from "mobx-react";
|
||||
import { orderBy } from "lodash";
|
||||
import { TabLayout } from "../layout/tab-layout";
|
||||
@@ -81,6 +81,11 @@ export class Events extends React.Component<Props> {
|
||||
onSort: params => this.sorting = params,
|
||||
};
|
||||
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
makeObservable(this);
|
||||
}
|
||||
|
||||
get store(): EventStore {
|
||||
return eventStore;
|
||||
}
|
||||
|
||||
@@ -24,33 +24,17 @@ import "./extensions.scss";
|
||||
import { remote, shell } from "electron";
|
||||
import fse from "fs-extra";
|
||||
import _ from "lodash";
|
||||
import { observable, reaction, when } from "mobx";
|
||||
import { makeObservable, observable, reaction, when } from "mobx";
|
||||
import { disposeOnUnmount, observer } from "mobx-react";
|
||||
import os from "os";
|
||||
import path from "path";
|
||||
import React from "react";
|
||||
import { SemVer } from "semver";
|
||||
import URLParse from "url-parse";
|
||||
|
||||
import {
|
||||
Disposer,
|
||||
disposer,
|
||||
downloadFile,
|
||||
downloadJson,
|
||||
ExtendableDisposer,
|
||||
extractTar,
|
||||
listTarEntries,
|
||||
noop,
|
||||
readFileFromTar,
|
||||
} from "../../../common/utils";
|
||||
import { Disposer, disposer, downloadFile, downloadJson, ExtendableDisposer, extractTar, listTarEntries, noop, readFileFromTar, } from "../../../common/utils";
|
||||
import { ExtensionDiscovery, InstalledExtension, manifestFilename } from "../../../extensions/extension-discovery";
|
||||
import { ExtensionLoader } from "../../../extensions/extension-loader";
|
||||
import {
|
||||
extensionDisplayName,
|
||||
LensExtensionId,
|
||||
LensExtensionManifest,
|
||||
sanitizeExtensionName,
|
||||
} from "../../../extensions/lens-extension";
|
||||
import { extensionDisplayName, LensExtensionId, LensExtensionManifest, sanitizeExtensionName, } from "../../../extensions/lens-extension";
|
||||
import logger from "../../../main/logger";
|
||||
import { Button } from "../button";
|
||||
import { ConfirmDialog } from "../confirm-dialog";
|
||||
@@ -193,7 +177,7 @@ async function validatePackage(filePath: string): Promise<LensExtensionManifest>
|
||||
// tarball from npm contains single root folder "package/*"
|
||||
const firstFile = tarFiles[0];
|
||||
|
||||
if(!firstFile) {
|
||||
if (!firstFile) {
|
||||
throw new Error(`invalid extension bundle, ${manifestFilename} not found`);
|
||||
}
|
||||
|
||||
@@ -201,7 +185,7 @@ async function validatePackage(filePath: string): Promise<LensExtensionManifest>
|
||||
const packedInRootFolder = tarFiles.every(entry => entry.startsWith(rootFolder));
|
||||
const manifestLocation = packedInRootFolder ? path.join(rootFolder, manifestFilename) : manifestFilename;
|
||||
|
||||
if(!tarFiles.includes(manifestLocation)) {
|
||||
if (!tarFiles.includes(manifestLocation)) {
|
||||
throw new Error(`invalid extension bundle, ${manifestFilename} not found`);
|
||||
}
|
||||
|
||||
@@ -415,7 +399,7 @@ async function attemptInstall(request: InstallRequest, d?: ExtendableDisposer):
|
||||
} else {
|
||||
dispose();
|
||||
}
|
||||
}} />
|
||||
}}/>
|
||||
</div>,
|
||||
{
|
||||
onClose: dispose,
|
||||
@@ -460,7 +444,7 @@ async function installFromInput(input: string) {
|
||||
|
||||
await attemptInstall({ fileName, dataP: readFileNotify(input) });
|
||||
} else if (InputValidators.isExtensionNameInstall.validate(input)) {
|
||||
const [{ groups: { name, version }}] = [...input.matchAll(InputValidators.isExtensionNameInstallRegex)];
|
||||
const [{ groups: { name, version } }] = [...input.matchAll(InputValidators.isExtensionNameInstallRegex)];
|
||||
|
||||
await attemptInstallByInfo({ name, version });
|
||||
}
|
||||
@@ -493,10 +477,18 @@ async function installFromSelectFileDialog() {
|
||||
}
|
||||
}
|
||||
|
||||
interface Props {
|
||||
}
|
||||
|
||||
@observer
|
||||
export class Extensions extends React.Component {
|
||||
export class Extensions extends React.Component<Props> {
|
||||
@observable installPath = "";
|
||||
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
makeObservable(this);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
// TODO: change this after upgrading to mobx6 as that versions' reactions have this functionality
|
||||
let prevSize = ExtensionLoader.getInstance().userExtensions.size;
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
import "./add-namespace-dialog.scss";
|
||||
|
||||
import React from "react";
|
||||
import { observable } from "mobx";
|
||||
import { observable, makeObservable } from "mobx";
|
||||
import { observer } from "mobx-react";
|
||||
import { Dialog, DialogProps } from "../dialog";
|
||||
import { Wizard, WizardStep } from "../wizard";
|
||||
@@ -37,17 +37,25 @@ interface Props extends DialogProps {
|
||||
onError?(error: any): void;
|
||||
}
|
||||
|
||||
const dialogState = observable.object({
|
||||
isOpen: false,
|
||||
});
|
||||
|
||||
@observer
|
||||
export class AddNamespaceDialog extends React.Component<Props> {
|
||||
@observable static isOpen = false;
|
||||
@observable namespace = "";
|
||||
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
makeObservable(this);
|
||||
}
|
||||
|
||||
static open() {
|
||||
AddNamespaceDialog.isOpen = true;
|
||||
dialogState.isOpen = true;
|
||||
}
|
||||
|
||||
static close() {
|
||||
AddNamespaceDialog.isOpen = false;
|
||||
dialogState.isOpen = false;
|
||||
}
|
||||
|
||||
reset = () => {
|
||||
@@ -78,7 +86,7 @@ export class AddNamespaceDialog extends React.Component<Props> {
|
||||
<Dialog
|
||||
{...dialogProps}
|
||||
className="AddNamespaceDialog"
|
||||
isOpen={AddNamespaceDialog.isOpen}
|
||||
isOpen={dialogState.isOpen}
|
||||
onOpen={this.reset}
|
||||
close={AddNamespaceDialog.close}
|
||||
>
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
import "./namespace-details.scss";
|
||||
|
||||
import React from "react";
|
||||
import { computed } from "mobx";
|
||||
import { computed, makeObservable } from "mobx";
|
||||
import { observer } from "mobx-react";
|
||||
import { DrawerItem } from "../drawer";
|
||||
import { cssNames } from "../../utils";
|
||||
@@ -40,6 +40,11 @@ interface Props extends KubeObjectDetailsProps<Namespace> {
|
||||
|
||||
@observer
|
||||
export class NamespaceDetails extends React.Component<Props> {
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
makeObservable(this);
|
||||
}
|
||||
|
||||
@computed get quotas() {
|
||||
const namespace = this.props.object.getName();
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
import "./namespace-select.scss";
|
||||
|
||||
import React from "react";
|
||||
import { computed } from "mobx";
|
||||
import { computed, makeObservable } from "mobx";
|
||||
import { disposeOnUnmount, observer } from "mobx-react";
|
||||
import { Select, SelectOption, SelectProps } from "../select";
|
||||
import { cssNames } from "../../utils";
|
||||
@@ -46,6 +46,11 @@ const defaultProps: Partial<Props> = {
|
||||
export class NamespaceSelect extends React.Component<Props> {
|
||||
static defaultProps = defaultProps as object;
|
||||
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
makeObservable(this);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
disposeOnUnmount(this, [
|
||||
kubeWatchApi.subscribeStores([namespaceStore], {
|
||||
|
||||
@@ -19,71 +19,39 @@
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
import { action, comparer, computed, IReactionDisposer, IReactionOptions, observable, reaction } from "mobx";
|
||||
import { autobind, createStorage } from "../../utils";
|
||||
import { action, comparer, computed, IReactionDisposer, IReactionOptions, makeObservable, reaction, } from "mobx";
|
||||
import { autoBind, createStorage } from "../../utils";
|
||||
import { KubeObjectStore, KubeObjectStoreLoadingParams } from "../../kube-object.store";
|
||||
import { Namespace, namespacesApi } from "../../api/endpoints/namespaces.api";
|
||||
import { createPageParam } from "../../navigation";
|
||||
import { apiManager } from "../../api/api-manager";
|
||||
|
||||
const selectedNamespaces = createStorage<string[] | undefined>("selected_namespaces", undefined);
|
||||
|
||||
export const namespaceUrlParam = createPageParam<string[]>({
|
||||
name: "namespaces",
|
||||
isSystem: true,
|
||||
multiValues: true,
|
||||
defaultValue: [],
|
||||
});
|
||||
|
||||
export function getDummyNamespace(name: string) {
|
||||
return new Namespace({
|
||||
kind: Namespace.kind,
|
||||
apiVersion: "v1",
|
||||
metadata: {
|
||||
name,
|
||||
uid: "",
|
||||
resourceVersion: "",
|
||||
selfLink: `/api/v1/namespaces/${name}`
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@autobind()
|
||||
export class NamespaceStore extends KubeObjectStore<Namespace> {
|
||||
api = namespacesApi;
|
||||
|
||||
@observable private contextNs = observable.set<string>();
|
||||
private storage = createStorage<string[] | undefined>("selected_namespaces", undefined);
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
makeObservable(this);
|
||||
autoBind(this);
|
||||
|
||||
this.init();
|
||||
}
|
||||
|
||||
private async init() {
|
||||
await this.contextReady;
|
||||
await selectedNamespaces.whenReady;
|
||||
await this.storage.whenReady;
|
||||
|
||||
this.setContext(this.initialNamespaces);
|
||||
this.selectNamespaces(this.initialNamespaces);
|
||||
this.autoLoadAllowedNamespaces();
|
||||
this.autoUpdateUrlAndLocalStorage();
|
||||
}
|
||||
|
||||
public onContextChange(callback: (contextNamespaces: string[]) => void, opts: IReactionOptions = {}): IReactionDisposer {
|
||||
return reaction(() => Array.from(this.contextNs), callback, {
|
||||
public onContextChange(callback: (namespaces: string[]) => void, opts: IReactionOptions = {}): IReactionDisposer {
|
||||
return reaction(() => Array.from(this.contextNamespaces), callback, {
|
||||
equals: comparer.shallow,
|
||||
...opts,
|
||||
});
|
||||
}
|
||||
|
||||
private autoUpdateUrlAndLocalStorage(): IReactionDisposer {
|
||||
return this.onContextChange(namespaces => {
|
||||
selectedNamespaces.set(namespaces); // save to local-storage
|
||||
namespaceUrlParam.set(namespaces, { replaceHistory: true }); // update url
|
||||
}, {
|
||||
fireImmediately: true,
|
||||
});
|
||||
}
|
||||
|
||||
private autoLoadAllowedNamespaces(): IReactionDisposer {
|
||||
return reaction(() => this.allowedNamespaces, namespaces => this.loadAll({ namespaces }), {
|
||||
fireImmediately: true,
|
||||
@@ -92,24 +60,28 @@ export class NamespaceStore extends KubeObjectStore<Namespace> {
|
||||
}
|
||||
|
||||
private get initialNamespaces(): string[] {
|
||||
const namespaces = new Set(this.allowedNamespaces);
|
||||
const prevSelectedNamespaces = selectedNamespaces.get();
|
||||
const { allowedNamespaces } = this;
|
||||
const selectedNamespaces = this.storage.get(); // raw namespaces, undefined on first load
|
||||
|
||||
// return previously saved namespaces from local-storage (if any)
|
||||
if (prevSelectedNamespaces) {
|
||||
return prevSelectedNamespaces.filter(namespace => namespaces.has(namespace));
|
||||
if (Array.isArray(selectedNamespaces)) {
|
||||
return selectedNamespaces.filter(namespace => allowedNamespaces.includes(namespace));
|
||||
}
|
||||
|
||||
// otherwise select "default" or first allowed namespace
|
||||
if (namespaces.has("default")) {
|
||||
if (allowedNamespaces.includes("default")) {
|
||||
return ["default"];
|
||||
} else if (namespaces.size) {
|
||||
return [Array.from(namespaces)[0]];
|
||||
} else if (allowedNamespaces.length) {
|
||||
return [allowedNamespaces[0]];
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
@computed get selectedNamespaces(): string[] {
|
||||
return this.storage.get() ?? [];
|
||||
}
|
||||
|
||||
@computed get allowedNamespaces(): string[] {
|
||||
return Array.from(new Set([
|
||||
...(this.context?.allNamespaces ?? []), // allowed namespaces from cluster (main), updating every 30s
|
||||
@@ -118,13 +90,11 @@ export class NamespaceStore extends KubeObjectStore<Namespace> {
|
||||
}
|
||||
|
||||
@computed get contextNamespaces(): string[] {
|
||||
const namespaces = Array.from(this.contextNs);
|
||||
|
||||
if (!namespaces.length) {
|
||||
if (!this.selectedNamespaces.length) {
|
||||
return this.allowedNamespaces; // show all namespaces when nothing selected
|
||||
}
|
||||
|
||||
return namespaces;
|
||||
return this.selectedNamespaces;
|
||||
}
|
||||
|
||||
getSubscribeApis() {
|
||||
@@ -151,31 +121,40 @@ export class NamespaceStore extends KubeObjectStore<Namespace> {
|
||||
}
|
||||
|
||||
@action
|
||||
setContext(namespace: string | string[]) {
|
||||
const namespaces = [namespace].flat();
|
||||
selectNamespaces(namespace: string | string[]) {
|
||||
const namespaces = Array.from(new Set([namespace].flat()));
|
||||
|
||||
this.contextNs.replace(namespaces);
|
||||
this.storage.set(namespaces);
|
||||
}
|
||||
|
||||
@action
|
||||
resetContext() {
|
||||
this.contextNs.clear();
|
||||
clearSelected(namespaces?: string | string[]) {
|
||||
if (namespaces) {
|
||||
const resettingNamespaces = [namespaces].flat();
|
||||
const newNamespaces = this.storage.get().filter(ns => !resettingNamespaces.includes(ns));
|
||||
|
||||
this.storage.set(newNamespaces);
|
||||
} else {
|
||||
this.storage.reset();
|
||||
}
|
||||
}
|
||||
|
||||
hasContext(namespaces: string | string[]) {
|
||||
return [namespaces].flat().every(namespace => this.contextNs.has(namespace));
|
||||
hasContext(namespaces: string | string[]): boolean {
|
||||
return [namespaces]
|
||||
.flat()
|
||||
.every(namespace => this.selectedNamespaces.includes(namespace));
|
||||
}
|
||||
|
||||
@computed get hasAllContexts(): boolean {
|
||||
return this.contextNs.size === this.allowedNamespaces.length;
|
||||
return this.selectedNamespaces.length === this.allowedNamespaces.length;
|
||||
}
|
||||
|
||||
@action
|
||||
toggleContext(namespace: string) {
|
||||
if (this.hasContext(namespace)) {
|
||||
this.contextNs.delete(namespace);
|
||||
toggleContext(namespaces: string | string[]) {
|
||||
if (this.hasContext(namespaces)) {
|
||||
this.clearSelected(namespaces);
|
||||
} else {
|
||||
this.contextNs.add(namespace);
|
||||
this.selectNamespaces([this.selectedNamespaces, namespaces].flat());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -183,9 +162,9 @@ export class NamespaceStore extends KubeObjectStore<Namespace> {
|
||||
toggleAll(showAll?: boolean) {
|
||||
if (typeof showAll === "boolean") {
|
||||
if (showAll) {
|
||||
this.setContext(this.allowedNamespaces);
|
||||
this.selectNamespaces(this.allowedNamespaces);
|
||||
} else {
|
||||
this.resetContext(); // empty context considered as "All namespaces"
|
||||
this.selectNamespaces([]); // empty context considered as "All namespaces"
|
||||
}
|
||||
} else {
|
||||
this.toggleAll(!this.hasAllContexts);
|
||||
@@ -195,9 +174,22 @@ export class NamespaceStore extends KubeObjectStore<Namespace> {
|
||||
@action
|
||||
async remove(item: Namespace) {
|
||||
await super.remove(item);
|
||||
this.contextNs.delete(item.getName());
|
||||
this.clearSelected(item.getName());
|
||||
}
|
||||
}
|
||||
|
||||
export const namespaceStore = new NamespaceStore();
|
||||
apiManager.registerStore(namespaceStore);
|
||||
|
||||
export function getDummyNamespace(name: string) {
|
||||
return new Namespace({
|
||||
kind: Namespace.kind,
|
||||
apiVersion: "v1",
|
||||
metadata: {
|
||||
name,
|
||||
uid: "",
|
||||
resourceVersion: "",
|
||||
selfLink: `/api/v1/namespaces/${name}`
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -25,7 +25,7 @@ import React from "react";
|
||||
import { observer } from "mobx-react";
|
||||
import { EndpointSubset, Endpoint, EndpointAddress} from "../../api/endpoints";
|
||||
import { Table, TableCell, TableHead, TableRow } from "../table";
|
||||
import { autobind } from "../../utils";
|
||||
import { boundMethod } from "../../utils";
|
||||
import { lookupApiLink } from "../../api/kube-api";
|
||||
import { Link } from "react-router-dom";
|
||||
import { getDetailsUrl } from "../kube-object";
|
||||
@@ -45,7 +45,7 @@ export class EndpointSubsetList extends React.Component<Props> {
|
||||
return this.renderAddressTableRow(address);
|
||||
}
|
||||
|
||||
@autobind()
|
||||
@boundMethod
|
||||
getNotReadyAddressTableRow(ip: string) {
|
||||
const { subset} = this.props;
|
||||
const address = subset.getNotReadyAddresses().find(address => address.getId() == ip);
|
||||
@@ -53,7 +53,7 @@ export class EndpointSubsetList extends React.Component<Props> {
|
||||
return this.renderAddressTableRow(address);
|
||||
}
|
||||
|
||||
@autobind()
|
||||
@boundMethod
|
||||
renderAddressTable(addresses: EndpointAddress[], virtual: boolean) {
|
||||
return (
|
||||
<div>
|
||||
@@ -79,7 +79,7 @@ export class EndpointSubsetList extends React.Component<Props> {
|
||||
);
|
||||
}
|
||||
|
||||
@autobind()
|
||||
@boundMethod
|
||||
renderAddressTableRow(address: EndpointAddress) {
|
||||
const { endpoint } = this.props;
|
||||
|
||||
|
||||
@@ -20,11 +20,9 @@
|
||||
*/
|
||||
|
||||
import { KubeObjectStore } from "../../kube-object.store";
|
||||
import { autobind } from "../../utils";
|
||||
import { Endpoint, endpointApi } from "../../api/endpoints/endpoint.api";
|
||||
import { apiManager } from "../../api/api-manager";
|
||||
|
||||
@autobind()
|
||||
export class EndpointStore extends KubeObjectStore<Endpoint> {
|
||||
api = endpointApi;
|
||||
}
|
||||
|
||||
@@ -19,17 +19,23 @@
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
import { observable } from "mobx";
|
||||
import { observable, makeObservable } from "mobx";
|
||||
import { KubeObjectStore } from "../../kube-object.store";
|
||||
import { autobind } from "../../utils";
|
||||
import { autoBind } from "../../utils";
|
||||
import { IIngressMetrics, Ingress, ingressApi } from "../../api/endpoints";
|
||||
import { apiManager } from "../../api/api-manager";
|
||||
|
||||
@autobind()
|
||||
export class IngressStore extends KubeObjectStore<Ingress> {
|
||||
api = ingressApi;
|
||||
@observable metrics: IIngressMetrics = null;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
makeObservable(this);
|
||||
autoBind(this);
|
||||
}
|
||||
|
||||
async loadMetrics(ingress: Ingress) {
|
||||
this.metrics = await this.api.getMetrics(ingress.getName(), ingress.getNs());
|
||||
}
|
||||
|
||||
@@ -20,11 +20,9 @@
|
||||
*/
|
||||
|
||||
import { KubeObjectStore } from "../../kube-object.store";
|
||||
import { autobind } from "../../utils";
|
||||
import { NetworkPolicy, networkPolicyApi } from "../../api/endpoints/network-policy.api";
|
||||
import { apiManager } from "../../api/api-manager";
|
||||
|
||||
@autobind()
|
||||
export class NetworkPolicyStore extends KubeObjectStore<NetworkPolicy> {
|
||||
api = networkPolicyApi;
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ import React from "react";
|
||||
import { observer } from "mobx-react";
|
||||
import type { Service, ServicePort } from "../../api/endpoints";
|
||||
import { apiBase } from "../../api";
|
||||
import { observable } from "mobx";
|
||||
import { observable, makeObservable } from "mobx";
|
||||
import { cssNames } from "../../utils";
|
||||
import { Notifications } from "../notifications";
|
||||
import { Spinner } from "../spinner";
|
||||
@@ -39,6 +39,11 @@ interface Props {
|
||||
export class ServicePortComponent extends React.Component<Props> {
|
||||
@observable waiting = false;
|
||||
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
makeObservable(this);
|
||||
}
|
||||
|
||||
async portForward() {
|
||||
const { service, port } = this.props;
|
||||
|
||||
|
||||
@@ -20,11 +20,9 @@
|
||||
*/
|
||||
|
||||
import { KubeObjectStore } from "../../kube-object.store";
|
||||
import { autobind } from "../../utils";
|
||||
import { Service, serviceApi } from "../../api/endpoints/service.api";
|
||||
import { apiManager } from "../../api/api-manager";
|
||||
|
||||
@autobind()
|
||||
export class ServiceStore extends KubeObjectStore<Service> {
|
||||
api = serviceApi;
|
||||
}
|
||||
|
||||
@@ -28,20 +28,18 @@ import { Services, servicesRoute, servicesURL } from "../+network-services";
|
||||
import { endpointRoute, Endpoints, endpointURL } from "../+network-endpoints";
|
||||
import { Ingresses, ingressRoute, ingressURL } from "../+network-ingresses";
|
||||
import { NetworkPolicies, networkPoliciesRoute, networkPoliciesURL } from "../+network-policies";
|
||||
import { namespaceUrlParam } from "../+namespaces/namespace.store";
|
||||
import { isAllowedResource } from "../../../common/rbac";
|
||||
|
||||
@observer
|
||||
export class Network extends React.Component {
|
||||
static get tabRoutes(): TabLayoutRoute[] {
|
||||
const query = namespaceUrlParam.toObjectParam();
|
||||
const routes: TabLayoutRoute[] = [];
|
||||
|
||||
if (isAllowedResource("services")) {
|
||||
routes.push({
|
||||
title: "Services",
|
||||
component: Services,
|
||||
url: servicesURL({ query }),
|
||||
url: servicesURL(),
|
||||
routePath: servicesRoute.path.toString(),
|
||||
});
|
||||
}
|
||||
@@ -50,7 +48,7 @@ export class Network extends React.Component {
|
||||
routes.push({
|
||||
title: "Endpoints",
|
||||
component: Endpoints,
|
||||
url: endpointURL({ query }),
|
||||
url: endpointURL(),
|
||||
routePath: endpointRoute.path.toString(),
|
||||
});
|
||||
}
|
||||
@@ -59,7 +57,7 @@ export class Network extends React.Component {
|
||||
routes.push({
|
||||
title: "Ingresses",
|
||||
component: Ingresses,
|
||||
url: ingressURL({ query }),
|
||||
url: ingressURL(),
|
||||
routePath: ingressRoute.path.toString(),
|
||||
});
|
||||
}
|
||||
@@ -68,7 +66,7 @@ export class Network extends React.Component {
|
||||
routes.push({
|
||||
title: "Network Policies",
|
||||
component: NetworkPolicies,
|
||||
url: networkPoliciesURL({ query }),
|
||||
url: networkPoliciesURL(),
|
||||
routePath: networkPoliciesRoute.path.toString(),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -20,13 +20,12 @@
|
||||
*/
|
||||
|
||||
import { sum } from "lodash";
|
||||
import { action, computed, observable } from "mobx";
|
||||
import { action, computed, observable, makeObservable } from "mobx";
|
||||
import { clusterApi, IClusterMetrics, INodeMetrics, Node, nodesApi } from "../../api/endpoints";
|
||||
import { autobind } from "../../utils";
|
||||
import { autoBind } from "../../utils";
|
||||
import { KubeObjectStore } from "../../kube-object.store";
|
||||
import { apiManager } from "../../api/api-manager";
|
||||
|
||||
@autobind()
|
||||
export class NodesStore extends KubeObjectStore<Node> {
|
||||
api = nodesApi;
|
||||
|
||||
@@ -35,6 +34,13 @@ export class NodesStore extends KubeObjectStore<Node> {
|
||||
@observable metricsLoading = false;
|
||||
@observable metricsLoaded = false;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
makeObservable(this);
|
||||
autoBind(this);
|
||||
}
|
||||
|
||||
@action
|
||||
async loadUsageMetrics() {
|
||||
this.metricsLoading = true;
|
||||
|
||||
@@ -20,11 +20,9 @@
|
||||
*/
|
||||
|
||||
import { PodSecurityPolicy, pspApi } from "../../api/endpoints";
|
||||
import { autobind } from "../../utils";
|
||||
import { KubeObjectStore } from "../../kube-object.store";
|
||||
import { apiManager } from "../../api/api-manager";
|
||||
|
||||
@autobind()
|
||||
export class PodSecurityPoliciesStore extends KubeObjectStore<PodSecurityPolicy> {
|
||||
api = pspApi;
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ import "./add-helm-repo-dialog.scss";
|
||||
|
||||
import React from "react";
|
||||
import { remote, FileFilter } from "electron";
|
||||
import { observable } from "mobx";
|
||||
import { observable, makeObservable } from "mobx";
|
||||
import { observer } from "mobx-react";
|
||||
import { Dialog, DialogProps } from "../dialog";
|
||||
import { Wizard, WizardStep } from "../wizard";
|
||||
@@ -46,6 +46,10 @@ enum FileType {
|
||||
CertFile = "certFile",
|
||||
}
|
||||
|
||||
const dialogState = observable.object({
|
||||
isOpen: false,
|
||||
});
|
||||
|
||||
@observer
|
||||
export class AddHelmRepoDialog extends React.Component<Props> {
|
||||
private emptyRepo = {name: "", url: "", username: "", password: "", insecureSkipTlsVerify: false, caFile:"", keyFile: "", certFile: ""};
|
||||
@@ -53,14 +57,17 @@ export class AddHelmRepoDialog extends React.Component<Props> {
|
||||
private static keyExtensions = ["key", "keystore", "jks", "p12", "pfx", "pem"];
|
||||
private static certExtensions = ["crt", "cer", "ca-bundle", "p7b", "p7c" , "p7s", "p12", "pfx", "pem"];
|
||||
|
||||
@observable static isOpen = false;
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
makeObservable(this);
|
||||
}
|
||||
|
||||
static open() {
|
||||
AddHelmRepoDialog.isOpen = true;
|
||||
dialogState.isOpen = true;
|
||||
}
|
||||
|
||||
static close() {
|
||||
AddHelmRepoDialog.isOpen = false;
|
||||
dialogState.isOpen = false;
|
||||
}
|
||||
|
||||
@observable helmRepo : HelmRepo = this.emptyRepo;
|
||||
@@ -161,7 +168,7 @@ export class AddHelmRepoDialog extends React.Component<Props> {
|
||||
<Dialog
|
||||
{...dialogProps}
|
||||
className="AddHelmRepoDialog"
|
||||
isOpen={AddHelmRepoDialog.isOpen}
|
||||
isOpen={dialogState.isOpen}
|
||||
close={this.close}
|
||||
>
|
||||
<Wizard header={header} done={this.close}>
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
import "./helm-charts.scss";
|
||||
|
||||
import React from "react";
|
||||
import { action, computed, observable } from "mobx";
|
||||
import { action, computed, observable, makeObservable } from "mobx";
|
||||
|
||||
import { HelmRepo, HelmRepoManager } from "../../../main/helm/helm-repo-manager";
|
||||
import { Button } from "../button";
|
||||
@@ -38,6 +38,11 @@ export class HelmCharts extends React.Component {
|
||||
@observable repos: HelmRepo[] = [];
|
||||
@observable addedRepos = observable.map<string, HelmRepo>();
|
||||
|
||||
constructor(props: {}) {
|
||||
super(props);
|
||||
makeObservable(this);
|
||||
}
|
||||
|
||||
@computed get options(): SelectOption<HelmRepo>[] {
|
||||
return this.repos.map(repo => ({
|
||||
label: repo.name,
|
||||
|
||||
@@ -23,7 +23,7 @@ import React from "react";
|
||||
import { remote } from "electron";
|
||||
import { Avatar, IconButton, List, ListItem, ListItemAvatar, ListItemSecondaryAction, ListItemText, Paper } from "@material-ui/core";
|
||||
import { Description, Folder, Delete, HelpOutline } from "@material-ui/icons";
|
||||
import { action, computed, observable, reaction } from "mobx";
|
||||
import { action, computed, observable, reaction, makeObservable } from "mobx";
|
||||
import { disposeOnUnmount, observer } from "mobx-react";
|
||||
import fse from "fs-extra";
|
||||
import { KubeconfigSyncEntry, KubeconfigSyncValue, UserStore } from "../../../common/user-store";
|
||||
@@ -74,6 +74,11 @@ export class KubeconfigSyncs extends React.Component {
|
||||
syncs = observable.map<string, Value>();
|
||||
@observable loaded = false;
|
||||
|
||||
constructor(props: {}) {
|
||||
super(props);
|
||||
makeObservable(this);
|
||||
}
|
||||
|
||||
async componentDidMount() {
|
||||
const mapEntries = await Promise.all(
|
||||
iter.map(
|
||||
|
||||
@@ -23,7 +23,7 @@ import "./preferences.scss";
|
||||
|
||||
import React from "react";
|
||||
import moment from "moment-timezone";
|
||||
import { computed, observable, reaction } from "mobx";
|
||||
import { computed, observable, reaction, makeObservable } from "mobx";
|
||||
import { disposeOnUnmount, observer } from "mobx-react";
|
||||
|
||||
import { isWindows } from "../../../common/vars";
|
||||
@@ -56,6 +56,11 @@ export class Preferences extends React.Component {
|
||||
@observable shell = UserStore.getInstance().shell || "";
|
||||
@observable activeTab = Pages.Application;
|
||||
|
||||
constructor(props: {}) {
|
||||
super(props);
|
||||
makeObservable(this);
|
||||
}
|
||||
|
||||
@computed get themeOptions(): SelectOption<string>[] {
|
||||
return ThemeStore.getInstance().themes.map(theme => ({
|
||||
label: theme.name,
|
||||
|
||||
@@ -20,15 +20,19 @@
|
||||
*/
|
||||
|
||||
import { KubeObjectStore } from "../../kube-object.store";
|
||||
import { autobind } from "../../utils";
|
||||
import { autoBind } from "../../utils";
|
||||
import { StorageClass, storageClassApi } from "../../api/endpoints/storage-class.api";
|
||||
import { apiManager } from "../../api/api-manager";
|
||||
import { volumesStore } from "../+storage-volumes/volumes.store";
|
||||
|
||||
@autobind()
|
||||
export class StorageClassStore extends KubeObjectStore<StorageClass> {
|
||||
api = storageClassApi;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
autoBind(this);
|
||||
}
|
||||
|
||||
getPersistentVolumes(storageClass: StorageClass) {
|
||||
return volumesStore.getByStorageClass(storageClass);
|
||||
}
|
||||
|
||||
@@ -19,17 +19,23 @@
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
import { action, observable } from "mobx";
|
||||
import { action, observable, makeObservable } from "mobx";
|
||||
import { KubeObjectStore } from "../../kube-object.store";
|
||||
import { autobind } from "../../utils";
|
||||
import { autoBind } from "../../utils";
|
||||
import { IPvcMetrics, PersistentVolumeClaim, pvcApi } from "../../api/endpoints";
|
||||
import { apiManager } from "../../api/api-manager";
|
||||
|
||||
@autobind()
|
||||
export class VolumeClaimStore extends KubeObjectStore<PersistentVolumeClaim> {
|
||||
api = pvcApi;
|
||||
@observable metrics: IPvcMetrics = null;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
makeObservable(this);
|
||||
autoBind(this);
|
||||
}
|
||||
|
||||
@action
|
||||
async loadMetrics(pvc: PersistentVolumeClaim) {
|
||||
this.metrics = await pvcApi.getMetrics(pvc.getName(), pvc.getNs());
|
||||
|
||||
@@ -24,7 +24,7 @@ import "./volume-details-list.scss";
|
||||
import React from "react";
|
||||
import { observer } from "mobx-react";
|
||||
import type { PersistentVolume } from "../../api/endpoints/persistent-volume.api";
|
||||
import { autobind } from "../../../common/utils/autobind";
|
||||
import { boundMethod } from "../../../common/utils/autobind";
|
||||
import { TableRow } from "../table/table-row";
|
||||
import { cssNames, prevDefault } from "../../utils";
|
||||
import { showDetails } from "../kube-object/kube-object-details";
|
||||
@@ -54,7 +54,7 @@ export class VolumeDetailsList extends React.Component<Props> {
|
||||
[sortBy.status]: (volume: PersistentVolume) => volume.getStatus(),
|
||||
};
|
||||
|
||||
@autobind()
|
||||
@boundMethod
|
||||
getTableRow(uid: string) {
|
||||
const { persistentVolumes } = this.props;
|
||||
const volume = persistentVolumes.find(volume => volume.getId() === uid);
|
||||
|
||||
@@ -20,15 +20,19 @@
|
||||
*/
|
||||
|
||||
import { KubeObjectStore } from "../../kube-object.store";
|
||||
import { autobind } from "../../utils";
|
||||
import { autoBind } from "../../utils";
|
||||
import { PersistentVolume, persistentVolumeApi } from "../../api/endpoints/persistent-volume.api";
|
||||
import { apiManager } from "../../api/api-manager";
|
||||
import type { StorageClass } from "../../api/endpoints/storage-class.api";
|
||||
|
||||
@autobind()
|
||||
export class PersistentVolumesStore extends KubeObjectStore<PersistentVolume> {
|
||||
api = persistentVolumeApi;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
autoBind(this);
|
||||
}
|
||||
|
||||
getByStorageClass(storageClass: StorageClass): PersistentVolume[] {
|
||||
return this.items.filter(volume =>
|
||||
volume.getStorageClassName() === storageClass.getName()
|
||||
|
||||
@@ -27,20 +27,18 @@ import { TabLayout, TabLayoutRoute } from "../layout/tab-layout";
|
||||
import { PersistentVolumes, volumesRoute, volumesURL } from "../+storage-volumes";
|
||||
import { StorageClasses, storageClassesRoute, storageClassesURL } from "../+storage-classes";
|
||||
import { PersistentVolumeClaims, volumeClaimsRoute, volumeClaimsURL } from "../+storage-volume-claims";
|
||||
import { namespaceUrlParam } from "../+namespaces/namespace.store";
|
||||
import { isAllowedResource } from "../../../common/rbac";
|
||||
|
||||
@observer
|
||||
export class Storage extends React.Component {
|
||||
static get tabRoutes() {
|
||||
const tabRoutes: TabLayoutRoute[] = [];
|
||||
const query = namespaceUrlParam.toObjectParam();
|
||||
|
||||
if (isAllowedResource("persistentvolumeclaims")) {
|
||||
tabRoutes.push({
|
||||
title: "Persistent Volume Claims",
|
||||
component: PersistentVolumeClaims,
|
||||
url: volumeClaimsURL({ query }),
|
||||
url: volumeClaimsURL(),
|
||||
routePath: volumeClaimsRoute.path.toString(),
|
||||
});
|
||||
}
|
||||
|
||||
+16
-9
@@ -22,13 +22,13 @@
|
||||
import "./add-role-binding-dialog.scss";
|
||||
|
||||
import React from "react";
|
||||
import { computed, observable } from "mobx";
|
||||
import { computed, observable, makeObservable } from "mobx";
|
||||
import { observer } from "mobx-react";
|
||||
import { Dialog, DialogProps } from "../dialog";
|
||||
import { Wizard, WizardStep } from "../wizard";
|
||||
import { Select, SelectOption } from "../select";
|
||||
import { SubTitle } from "../layout/sub-title";
|
||||
import { IRoleBindingSubject, Role, RoleBinding, ServiceAccount } from "../../api/endpoints";
|
||||
import type { IRoleBindingSubject, Role, RoleBinding, ServiceAccount } from "../../api/endpoints";
|
||||
import { Icon } from "../icon";
|
||||
import { Input } from "../input";
|
||||
import { NamespaceSelect } from "../+namespaces/namespace-select";
|
||||
@@ -51,22 +51,29 @@ interface BindingSelectOption extends SelectOption {
|
||||
interface Props extends Partial<DialogProps> {
|
||||
}
|
||||
|
||||
const dialogState = observable.object({
|
||||
isOpen: false,
|
||||
data: null as RoleBinding,
|
||||
});
|
||||
|
||||
@observer
|
||||
export class AddRoleBindingDialog extends React.Component<Props> {
|
||||
@observable static isOpen = false;
|
||||
@observable static data: RoleBinding = null;
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
makeObservable(this);
|
||||
}
|
||||
|
||||
static open(roleBinding?: RoleBinding) {
|
||||
AddRoleBindingDialog.isOpen = true;
|
||||
AddRoleBindingDialog.data = roleBinding;
|
||||
dialogState.isOpen = true;
|
||||
dialogState.data = roleBinding;
|
||||
}
|
||||
|
||||
static close() {
|
||||
AddRoleBindingDialog.isOpen = false;
|
||||
dialogState.isOpen = false;
|
||||
}
|
||||
|
||||
get roleBinding(): RoleBinding {
|
||||
return AddRoleBindingDialog.data;
|
||||
return dialogState.data;
|
||||
}
|
||||
|
||||
@observable isLoading = false;
|
||||
@@ -292,7 +299,7 @@ export class AddRoleBindingDialog extends React.Component<Props> {
|
||||
<Dialog
|
||||
{...dialogProps}
|
||||
className="AddRoleBindingDialog"
|
||||
isOpen={AddRoleBindingDialog.isOpen}
|
||||
isOpen={dialogState.isOpen}
|
||||
onOpen={this.onOpen}
|
||||
close={this.close}
|
||||
>
|
||||
|
||||
@@ -24,13 +24,13 @@ import "./role-binding-details.scss";
|
||||
import React from "react";
|
||||
import { AddRemoveButtons } from "../add-remove-buttons";
|
||||
import type { IRoleBindingSubject, RoleBinding } from "../../api/endpoints";
|
||||
import { autobind, prevDefault } from "../../utils";
|
||||
import { boundMethod, prevDefault } from "../../utils";
|
||||
import { Table, TableCell, TableHead, TableRow } from "../table";
|
||||
import { ConfirmDialog } from "../confirm-dialog";
|
||||
import { DrawerTitle } from "../drawer";
|
||||
import { KubeEventDetails } from "../+events/kube-event-details";
|
||||
import { disposeOnUnmount, observer } from "mobx-react";
|
||||
import { observable, reaction } from "mobx";
|
||||
import { observable, reaction, makeObservable } from "mobx";
|
||||
import { roleBindingsStore } from "./role-bindings.store";
|
||||
import { AddRoleBindingDialog } from "./add-role-binding-dialog";
|
||||
import type { KubeObjectDetailsProps } from "../kube-object";
|
||||
@@ -44,6 +44,11 @@ interface Props extends KubeObjectDetailsProps<RoleBinding> {
|
||||
export class RoleBindingDetails extends React.Component<Props> {
|
||||
@observable selectedSubjects = observable.array<IRoleBindingSubject>([], { deep: false });
|
||||
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
makeObservable(this);
|
||||
}
|
||||
|
||||
async componentDidMount() {
|
||||
disposeOnUnmount(this, [
|
||||
reaction(() => this.props.object, () => {
|
||||
@@ -63,7 +68,7 @@ export class RoleBindingDetails extends React.Component<Props> {
|
||||
);
|
||||
}
|
||||
|
||||
@autobind()
|
||||
@boundMethod
|
||||
removeSelectedSubjects() {
|
||||
const { object: roleBinding } = this.props;
|
||||
const { selectedSubjects } = this;
|
||||
|
||||
@@ -23,13 +23,17 @@ import difference from "lodash/difference";
|
||||
import uniqBy from "lodash/uniqBy";
|
||||
import { clusterRoleBindingApi, IRoleBindingSubject, RoleBinding, roleBindingApi } from "../../api/endpoints";
|
||||
import { KubeObjectStore, KubeObjectStoreLoadingParams } from "../../kube-object.store";
|
||||
import { autobind } from "../../utils";
|
||||
import { autoBind } from "../../utils";
|
||||
import { apiManager } from "../../api/api-manager";
|
||||
|
||||
@autobind()
|
||||
export class RoleBindingsStore extends KubeObjectStore<RoleBinding> {
|
||||
api = clusterRoleBindingApi;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
autoBind(this);
|
||||
}
|
||||
|
||||
getSubscribeApis() {
|
||||
return [clusterRoleBindingApi, roleBindingApi];
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
import "./add-role-dialog.scss";
|
||||
|
||||
import React from "react";
|
||||
import { observable } from "mobx";
|
||||
import { observable, makeObservable } from "mobx";
|
||||
import { observer } from "mobx-react";
|
||||
import { Dialog, DialogProps } from "../dialog";
|
||||
import { Wizard, WizardStep } from "../wizard";
|
||||
@@ -36,19 +36,26 @@ import { showDetails } from "../kube-object";
|
||||
interface Props extends Partial<DialogProps> {
|
||||
}
|
||||
|
||||
const dialogState = observable.object({
|
||||
isOpen: false,
|
||||
});
|
||||
|
||||
@observer
|
||||
export class AddRoleDialog extends React.Component<Props> {
|
||||
@observable static isOpen = false;
|
||||
|
||||
@observable roleName = "";
|
||||
@observable namespace = "";
|
||||
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
makeObservable(this);
|
||||
}
|
||||
|
||||
static open() {
|
||||
AddRoleDialog.isOpen = true;
|
||||
dialogState.isOpen = true;
|
||||
}
|
||||
|
||||
static close() {
|
||||
AddRoleDialog.isOpen = false;
|
||||
dialogState.isOpen = false;
|
||||
}
|
||||
|
||||
close = () => {
|
||||
@@ -80,7 +87,7 @@ export class AddRoleDialog extends React.Component<Props> {
|
||||
<Dialog
|
||||
{...dialogProps}
|
||||
className="AddRoleDialog"
|
||||
isOpen={AddRoleDialog.isOpen}
|
||||
isOpen={dialogState.isOpen}
|
||||
close={this.close}
|
||||
>
|
||||
<Wizard header={header} done={this.close}>
|
||||
|
||||
@@ -20,14 +20,18 @@
|
||||
*/
|
||||
|
||||
import { clusterRoleApi, Role, roleApi } from "../../api/endpoints";
|
||||
import { autobind } from "../../utils";
|
||||
import { autoBind } from "../../utils";
|
||||
import { KubeObjectStore, KubeObjectStoreLoadingParams } from "../../kube-object.store";
|
||||
import { apiManager } from "../../api/api-manager";
|
||||
|
||||
@autobind()
|
||||
export class RolesStore extends KubeObjectStore<Role> {
|
||||
api = clusterRoleApi;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
autoBind(this);
|
||||
}
|
||||
|
||||
getSubscribeApis() {
|
||||
return [roleApi, clusterRoleApi];
|
||||
}
|
||||
|
||||
+13
-6
@@ -22,7 +22,7 @@
|
||||
import "./create-service-account-dialog.scss";
|
||||
|
||||
import React from "react";
|
||||
import { observable } from "mobx";
|
||||
import { makeObservable, observable } from "mobx";
|
||||
import { observer } from "mobx-react";
|
||||
import { Dialog, DialogProps } from "../dialog";
|
||||
import { Wizard, WizardStep } from "../wizard";
|
||||
@@ -37,19 +37,26 @@ import { showDetails } from "../kube-object";
|
||||
interface Props extends Partial<DialogProps> {
|
||||
}
|
||||
|
||||
const dialogState = observable.object({
|
||||
isOpen: false,
|
||||
});
|
||||
|
||||
@observer
|
||||
export class CreateServiceAccountDialog extends React.Component<Props> {
|
||||
@observable static isOpen = false;
|
||||
|
||||
@observable name = "";
|
||||
@observable namespace = "default";
|
||||
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
makeObservable(this);
|
||||
}
|
||||
|
||||
static open() {
|
||||
CreateServiceAccountDialog.isOpen = true;
|
||||
dialogState.isOpen = true;
|
||||
}
|
||||
|
||||
static close() {
|
||||
CreateServiceAccountDialog.isOpen = false;
|
||||
dialogState.isOpen = false;
|
||||
}
|
||||
|
||||
close = () => {
|
||||
@@ -79,7 +86,7 @@ export class CreateServiceAccountDialog extends React.Component<Props> {
|
||||
<Dialog
|
||||
{...dialogProps}
|
||||
className="CreateServiceAccountDialog"
|
||||
isOpen={CreateServiceAccountDialog.isOpen}
|
||||
isOpen={dialogState.isOpen}
|
||||
close={this.close}
|
||||
>
|
||||
<Wizard header={header} done={this.close}>
|
||||
|
||||
+6
-1
@@ -22,7 +22,7 @@
|
||||
import "./service-accounts-details.scss";
|
||||
|
||||
import React from "react";
|
||||
import { autorun, observable } from "mobx";
|
||||
import { autorun, observable, makeObservable } from "mobx";
|
||||
import { Spinner } from "../spinner";
|
||||
import { ServiceAccountsSecret } from "./service-accounts-secret";
|
||||
import { DrawerItem, DrawerTitle } from "../drawer";
|
||||
@@ -66,6 +66,11 @@ export class ServiceAccountsDetails extends React.Component<Props> {
|
||||
this.imagePullSecrets = await Promise.all(imagePullSecrets);
|
||||
});
|
||||
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
makeObservable(this);
|
||||
}
|
||||
|
||||
renderSecrets() {
|
||||
const { secrets } = this;
|
||||
|
||||
|
||||
@@ -19,15 +19,19 @@
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
import { autobind } from "../../utils";
|
||||
import { autoBind } from "../../utils";
|
||||
import { ServiceAccount, serviceAccountsApi } from "../../api/endpoints";
|
||||
import { KubeObjectStore } from "../../kube-object.store";
|
||||
import { apiManager } from "../../api/api-manager";
|
||||
|
||||
@autobind()
|
||||
export class ServiceAccountsStore extends KubeObjectStore<ServiceAccount> {
|
||||
api = serviceAccountsApi;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
autoBind(this);
|
||||
}
|
||||
|
||||
protected async createItem(params: { name: string; namespace?: string }) {
|
||||
await super.createItem(params);
|
||||
|
||||
|
||||
@@ -27,21 +27,19 @@ import { Roles } from "../+user-management-roles";
|
||||
import { RoleBindings } from "../+user-management-roles-bindings";
|
||||
import { ServiceAccounts } from "../+user-management-service-accounts";
|
||||
import { podSecurityPoliciesRoute, podSecurityPoliciesURL, roleBindingsRoute, roleBindingsURL, rolesRoute, rolesURL, serviceAccountsRoute, serviceAccountsURL } from "./user-management.route";
|
||||
import { namespaceUrlParam } from "../+namespaces/namespace.store";
|
||||
import { PodSecurityPolicies } from "../+pod-security-policies";
|
||||
import { isAllowedResource } from "../../../common/rbac";
|
||||
|
||||
@observer
|
||||
export class UserManagement extends React.Component {
|
||||
static get tabRoutes() {
|
||||
const query = namespaceUrlParam.toObjectParam();
|
||||
const tabRoutes: TabLayoutRoute[] = [];
|
||||
|
||||
if (isAllowedResource("serviceaccounts")) {
|
||||
tabRoutes.push({
|
||||
title: "Service Accounts",
|
||||
component: ServiceAccounts,
|
||||
url: serviceAccountsURL({ query }),
|
||||
url: serviceAccountsURL(),
|
||||
routePath: serviceAccountsRoute.path.toString(),
|
||||
});
|
||||
}
|
||||
@@ -51,7 +49,7 @@ export class UserManagement extends React.Component {
|
||||
tabRoutes.push({
|
||||
title: "Role Bindings",
|
||||
component: RoleBindings,
|
||||
url: roleBindingsURL({ query }),
|
||||
url: roleBindingsURL(),
|
||||
routePath: roleBindingsRoute.path.toString(),
|
||||
});
|
||||
}
|
||||
@@ -61,7 +59,7 @@ export class UserManagement extends React.Component {
|
||||
tabRoutes.push({
|
||||
title: "Roles",
|
||||
component: Roles,
|
||||
url: rolesURL({ query }),
|
||||
url: rolesURL(),
|
||||
routePath: rolesRoute.path.toString(),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
import "./cronjob-trigger-dialog.scss";
|
||||
|
||||
import React, { Component } from "react";
|
||||
import { observable } from "mobx";
|
||||
import { observable, makeObservable } from "mobx";
|
||||
import { observer } from "mobx-react";
|
||||
import { Dialog, DialogProps } from "../dialog";
|
||||
import { Wizard, WizardStep } from "../wizard";
|
||||
@@ -35,26 +35,32 @@ import { systemName, maxLength } from "../input/input_validators";
|
||||
interface Props extends Partial<DialogProps> {
|
||||
}
|
||||
|
||||
const dialogState = observable.object({
|
||||
isOpen: false,
|
||||
data: null as CronJob,
|
||||
});
|
||||
|
||||
@observer
|
||||
export class CronJobTriggerDialog extends Component<Props> {
|
||||
@observable static isOpen = false;
|
||||
@observable static data: CronJob = null;
|
||||
|
||||
@observable jobName = "";
|
||||
|
||||
@observable ready = false;
|
||||
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
makeObservable(this);
|
||||
}
|
||||
|
||||
static open(cronjob: CronJob) {
|
||||
CronJobTriggerDialog.isOpen = true;
|
||||
CronJobTriggerDialog.data = cronjob;
|
||||
dialogState.isOpen = true;
|
||||
dialogState.data = cronjob;
|
||||
}
|
||||
|
||||
static close() {
|
||||
CronJobTriggerDialog.isOpen = false;
|
||||
dialogState.isOpen = false;
|
||||
}
|
||||
|
||||
get cronjob() {
|
||||
return CronJobTriggerDialog.data;
|
||||
return dialogState.data;
|
||||
}
|
||||
|
||||
close = () => {
|
||||
@@ -128,7 +134,7 @@ export class CronJobTriggerDialog extends Component<Props> {
|
||||
return (
|
||||
<Dialog
|
||||
{...dialogProps}
|
||||
isOpen={CronJobTriggerDialog.isOpen}
|
||||
isOpen={dialogState.isOpen}
|
||||
className={cssNames("CronJobTriggerDialog", className)}
|
||||
onOpen={this.onOpen}
|
||||
onClose={this.onClose}
|
||||
|
||||
@@ -20,15 +20,19 @@
|
||||
*/
|
||||
|
||||
import { KubeObjectStore } from "../../kube-object.store";
|
||||
import { autobind } from "../../utils";
|
||||
import { autoBind } from "../../utils";
|
||||
import { CronJob, cronJobApi } from "../../api/endpoints/cron-job.api";
|
||||
import { jobStore } from "../+workloads-jobs/job.store";
|
||||
import { apiManager } from "../../api/api-manager";
|
||||
|
||||
@autobind()
|
||||
export class CronJobStore extends KubeObjectStore<CronJob> {
|
||||
api = cronJobApi;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
autoBind(this);
|
||||
}
|
||||
|
||||
getStatuses(cronJobs?: CronJob[]) {
|
||||
const status = { suspended: 0, scheduled: 0 };
|
||||
|
||||
|
||||
@@ -19,19 +19,25 @@
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
import { observable } from "mobx";
|
||||
import { observable, makeObservable } from "mobx";
|
||||
import { KubeObjectStore } from "../../kube-object.store";
|
||||
import { autobind } from "../../utils";
|
||||
import { autoBind } from "../../utils";
|
||||
import { DaemonSet, daemonSetApi, IPodMetrics, Pod, podsApi, PodStatus } from "../../api/endpoints";
|
||||
import { podsStore } from "../+workloads-pods/pods.store";
|
||||
import { apiManager } from "../../api/api-manager";
|
||||
|
||||
@autobind()
|
||||
export class DaemonSetStore extends KubeObjectStore<DaemonSet> {
|
||||
api = daemonSetApi;
|
||||
|
||||
@observable metrics: IPodMetrics = null;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
makeObservable(this);
|
||||
autoBind(this);
|
||||
}
|
||||
|
||||
async loadMetrics(daemonSet: DaemonSet) {
|
||||
const pods = this.getChildPods(daemonSet);
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
import "./deployment-scale-dialog.scss";
|
||||
|
||||
import React, { Component } from "react";
|
||||
import { computed, observable } from "mobx";
|
||||
import { computed, observable, makeObservable } from "mobx";
|
||||
import { observer } from "mobx-react";
|
||||
import { Dialog, DialogProps } from "../dialog";
|
||||
import { Wizard, WizardStep } from "../wizard";
|
||||
@@ -35,26 +35,33 @@ import { cssNames } from "../../utils";
|
||||
interface Props extends Partial<DialogProps> {
|
||||
}
|
||||
|
||||
const dialogState = observable.object({
|
||||
isOpen: false,
|
||||
data: null as Deployment,
|
||||
});
|
||||
|
||||
@observer
|
||||
export class DeploymentScaleDialog extends Component<Props> {
|
||||
@observable static isOpen = false;
|
||||
@observable static data: Deployment = null;
|
||||
|
||||
@observable ready = false;
|
||||
@observable currentReplicas = 0;
|
||||
@observable desiredReplicas = 0;
|
||||
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
makeObservable(this);
|
||||
}
|
||||
|
||||
static open(deployment: Deployment) {
|
||||
DeploymentScaleDialog.isOpen = true;
|
||||
DeploymentScaleDialog.data = deployment;
|
||||
dialogState.isOpen = true;
|
||||
dialogState.data = deployment;
|
||||
}
|
||||
|
||||
static close() {
|
||||
DeploymentScaleDialog.isOpen = false;
|
||||
dialogState.isOpen = false;
|
||||
}
|
||||
|
||||
get deployment() {
|
||||
return DeploymentScaleDialog.data;
|
||||
return dialogState.data;
|
||||
}
|
||||
|
||||
close = () => {
|
||||
@@ -165,7 +172,7 @@ export class DeploymentScaleDialog extends Component<Props> {
|
||||
return (
|
||||
<Dialog
|
||||
{...dialogProps}
|
||||
isOpen={DeploymentScaleDialog.isOpen}
|
||||
isOpen={dialogState.isOpen}
|
||||
className={cssNames("DeploymentScaleDialog", className)}
|
||||
onOpen={this.onOpen}
|
||||
onClose={this.onClose}
|
||||
|
||||
@@ -19,18 +19,24 @@
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
import { observable } from "mobx";
|
||||
import { observable, makeObservable } from "mobx";
|
||||
import { Deployment, deploymentApi, IPodMetrics, podsApi, PodStatus } from "../../api/endpoints";
|
||||
import { KubeObjectStore } from "../../kube-object.store";
|
||||
import { autobind } from "../../utils";
|
||||
import { autoBind } from "../../utils";
|
||||
import { podsStore } from "../+workloads-pods/pods.store";
|
||||
import { apiManager } from "../../api/api-manager";
|
||||
|
||||
@autobind()
|
||||
export class DeploymentStore extends KubeObjectStore<Deployment> {
|
||||
api = deploymentApi;
|
||||
@observable metrics: IPodMetrics = null;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
makeObservable(this);
|
||||
autoBind(this);
|
||||
}
|
||||
|
||||
protected sortItems(items: Deployment[]) {
|
||||
return super.sortItems(items, [
|
||||
item => item.getReplicas(),
|
||||
|
||||
@@ -20,16 +20,20 @@
|
||||
*/
|
||||
|
||||
import { KubeObjectStore } from "../../kube-object.store";
|
||||
import { autobind } from "../../utils";
|
||||
import { autoBind } from "../../utils";
|
||||
import { Job, jobApi } from "../../api/endpoints/job.api";
|
||||
import { CronJob, Pod, PodStatus } from "../../api/endpoints";
|
||||
import { podsStore } from "../+workloads-pods/pods.store";
|
||||
import { apiManager } from "../../api/api-manager";
|
||||
|
||||
@autobind()
|
||||
export class JobStore extends KubeObjectStore<Job> {
|
||||
api = jobApi;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
autoBind(this);
|
||||
}
|
||||
|
||||
getChildPods(job: Job): Pod[] {
|
||||
return podsStore.getPodsByOwnerId(job.getId());
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ import { namespaceStore } from "../+namespaces/namespace.store";
|
||||
import { NamespaceSelectFilter } from "../+namespaces/namespace-select-filter";
|
||||
import { isAllowedResource, KubeResource } from "../../../common/rbac";
|
||||
import { ResourceNames } from "../../utils/rbac";
|
||||
import { autobind } from "../../utils";
|
||||
import { boundMethod } from "../../utils";
|
||||
|
||||
const resources: KubeResource[] = [
|
||||
"pods",
|
||||
@@ -44,7 +44,7 @@ const resources: KubeResource[] = [
|
||||
|
||||
@observer
|
||||
export class OverviewStatuses extends React.Component {
|
||||
@autobind()
|
||||
@boundMethod
|
||||
renderWorkload(resource: KubeResource): React.ReactElement {
|
||||
const store = workloadStores[resource];
|
||||
const items = store.getAllByNs(namespaceStore.contextNamespaces);
|
||||
|
||||
@@ -24,7 +24,7 @@ import "./overview-workload-status.scss";
|
||||
import React from "react";
|
||||
import capitalize from "lodash/capitalize";
|
||||
import { findDOMNode } from "react-dom";
|
||||
import { observable } from "mobx";
|
||||
import { observable, makeObservable } from "mobx";
|
||||
import { observer } from "mobx-react";
|
||||
import { PieChart } from "../chart";
|
||||
import { cssVar } from "../../utils";
|
||||
@@ -45,6 +45,11 @@ interface Props {
|
||||
export class OverviewWorkloadStatus extends React.Component<Props> {
|
||||
@observable elem: HTMLElement;
|
||||
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
makeObservable(this);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
// eslint-disable-next-line react/no-find-dom-node
|
||||
this.elem = findDOMNode(this) as HTMLElement;
|
||||
|
||||
@@ -25,7 +25,7 @@ import React from "react";
|
||||
import { observer } from "mobx-react";
|
||||
import type { Pod } from "../../api/endpoints";
|
||||
import { apiBase } from "../../api";
|
||||
import { observable } from "mobx";
|
||||
import { observable, makeObservable } from "mobx";
|
||||
import { cssNames } from "../../utils";
|
||||
import { Notifications } from "../notifications";
|
||||
import { Spinner } from "../spinner";
|
||||
@@ -43,6 +43,11 @@ interface Props {
|
||||
export class PodContainerPort extends React.Component<Props> {
|
||||
@observable waiting = false;
|
||||
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
makeObservable(this);
|
||||
}
|
||||
|
||||
async portForward() {
|
||||
const { pod, port } = this.props;
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ import { reaction } from "mobx";
|
||||
import { disposeOnUnmount, observer } from "mobx-react";
|
||||
import { podsStore } from "./pods.store";
|
||||
import type { Pod } from "../../api/endpoints";
|
||||
import { autobind, bytesToUnits, cssNames, interval, prevDefault } from "../../utils";
|
||||
import { boundMethod, bytesToUnits, cssNames, interval, prevDefault } from "../../utils";
|
||||
import { LineProgress } from "../line-progress";
|
||||
import type { KubeObject } from "../../api/kube-object";
|
||||
import { Table, TableCell, TableHead, TableRow } from "../table";
|
||||
@@ -119,7 +119,7 @@ export class PodDetailsList extends React.Component<Props> {
|
||||
);
|
||||
}
|
||||
|
||||
@autobind()
|
||||
@boundMethod
|
||||
getTableRow(uid: string) {
|
||||
const { pods } = this.props;
|
||||
const pod = pods.find(pod => pod.getId() == uid);
|
||||
|
||||
@@ -23,7 +23,7 @@ import "./pod-details-secrets.scss";
|
||||
|
||||
import React, { Component } from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
import { autorun, observable } from "mobx";
|
||||
import { autorun, observable, makeObservable } from "mobx";
|
||||
import { disposeOnUnmount, observer } from "mobx-react";
|
||||
import { Pod, Secret, secretsApi } from "../../api/endpoints";
|
||||
import { getDetailsUrl } from "../kube-object";
|
||||
@@ -50,6 +50,11 @@ export class PodDetailsSecrets extends Component<Props> {
|
||||
secrets.forEach(secret => secret && this.secrets.set(secret.getName(), secret));
|
||||
});
|
||||
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
makeObservable(this);
|
||||
}
|
||||
|
||||
render() {
|
||||
const { pod } = this.props;
|
||||
|
||||
|
||||
@@ -25,11 +25,11 @@ import React from "react";
|
||||
import kebabCase from "lodash/kebabCase";
|
||||
import { disposeOnUnmount, observer } from "mobx-react";
|
||||
import { Link } from "react-router-dom";
|
||||
import { autorun, observable, reaction, toJS } from "mobx";
|
||||
import { autorun, observable, reaction, makeObservable } from "mobx";
|
||||
import { IPodMetrics, nodesApi, Pod, pvcApi, configMapApi } from "../../api/endpoints";
|
||||
import { DrawerItem, DrawerTitle } from "../drawer";
|
||||
import { Badge } from "../badge";
|
||||
import { autobind, cssNames, interval } from "../../utils";
|
||||
import { boundMethod, cssNames, interval, toJS } from "../../utils";
|
||||
import { PodDetailsContainer } from "./pod-details-container";
|
||||
import { PodDetailsAffinities } from "./pod-details-affinities";
|
||||
import { PodDetailsTolerations } from "./pod-details-tolerations";
|
||||
@@ -55,6 +55,11 @@ export class PodDetails extends React.Component<Props> {
|
||||
|
||||
private watcher = interval(60, () => this.loadMetrics());
|
||||
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
makeObservable(this);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
disposeOnUnmount(this, [
|
||||
autorun(() => {
|
||||
@@ -72,7 +77,7 @@ export class PodDetails extends React.Component<Props> {
|
||||
podsStore.reset();
|
||||
}
|
||||
|
||||
@autobind()
|
||||
@boundMethod
|
||||
async loadMetrics() {
|
||||
const { object: pod } = this.props;
|
||||
|
||||
|
||||
@@ -20,20 +20,26 @@
|
||||
*/
|
||||
|
||||
import countBy from "lodash/countBy";
|
||||
import { action, observable } from "mobx";
|
||||
import { action, observable, makeObservable } from "mobx";
|
||||
import { KubeObjectStore } from "../../kube-object.store";
|
||||
import { autobind, cpuUnitsToNumber, unitsToBytes } from "../../utils";
|
||||
import { autoBind, cpuUnitsToNumber, unitsToBytes } from "../../utils";
|
||||
import { IPodMetrics, Pod, PodMetrics, podMetricsApi, podsApi } from "../../api/endpoints";
|
||||
import { apiManager } from "../../api/api-manager";
|
||||
import type { WorkloadKubeObject } from "../../api/workload-kube-object";
|
||||
|
||||
@autobind()
|
||||
export class PodsStore extends KubeObjectStore<Pod> {
|
||||
api = podsApi;
|
||||
|
||||
@observable metrics: IPodMetrics = null;
|
||||
@observable kubeMetrics = observable.array<PodMetrics>([]);
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
makeObservable(this);
|
||||
autoBind(this);
|
||||
}
|
||||
|
||||
@action
|
||||
async loadMetrics(pod: Pod) {
|
||||
this.metrics = await podsApi.getMetrics([pod], pod.getNs());
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
import "./replicaset-scale-dialog.scss";
|
||||
|
||||
import React, { Component } from "react";
|
||||
import { computed, observable } from "mobx";
|
||||
import { computed, observable, makeObservable } from "mobx";
|
||||
import { observer } from "mobx-react";
|
||||
import { Dialog, DialogProps } from "../dialog";
|
||||
import { Wizard, WizardStep } from "../wizard";
|
||||
@@ -35,26 +35,33 @@ import { ReplicaSet, replicaSetApi } from "../../api/endpoints/replica-set.api";
|
||||
interface Props extends Partial<DialogProps> {
|
||||
}
|
||||
|
||||
const dialogState = observable.object({
|
||||
isOpen: false,
|
||||
data: null as ReplicaSet,
|
||||
});
|
||||
|
||||
@observer
|
||||
export class ReplicaSetScaleDialog extends Component<Props> {
|
||||
@observable static isOpen = false;
|
||||
@observable static data: ReplicaSet = null;
|
||||
|
||||
@observable ready = false;
|
||||
@observable currentReplicas = 0;
|
||||
@observable desiredReplicas = 0;
|
||||
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
makeObservable(this);
|
||||
}
|
||||
|
||||
static open(replicaSet: ReplicaSet) {
|
||||
ReplicaSetScaleDialog.isOpen = true;
|
||||
ReplicaSetScaleDialog.data = replicaSet;
|
||||
dialogState.isOpen = true;
|
||||
dialogState.data = replicaSet;
|
||||
}
|
||||
|
||||
static close() {
|
||||
ReplicaSetScaleDialog.isOpen = false;
|
||||
dialogState.isOpen = false;
|
||||
}
|
||||
|
||||
get replicaSet() {
|
||||
return ReplicaSetScaleDialog.data;
|
||||
return dialogState.data;
|
||||
}
|
||||
|
||||
close = () => {
|
||||
@@ -167,7 +174,7 @@ export class ReplicaSetScaleDialog extends Component<Props> {
|
||||
return (
|
||||
<Dialog
|
||||
{...dialogProps}
|
||||
isOpen={ReplicaSetScaleDialog.isOpen}
|
||||
isOpen={dialogState.isOpen}
|
||||
className={cssNames("ReplicaSetScaleDialog", className)}
|
||||
onOpen={this.onOpen}
|
||||
onClose={this.onClose}
|
||||
|
||||
@@ -19,19 +19,25 @@
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
import { observable } from "mobx";
|
||||
import { autobind } from "../../utils";
|
||||
import { observable, makeObservable } from "mobx";
|
||||
import { autoBind } from "../../utils";
|
||||
import { KubeObjectStore } from "../../kube-object.store";
|
||||
import { Deployment, IPodMetrics, podsApi, ReplicaSet, replicaSetApi } from "../../api/endpoints";
|
||||
import { podsStore } from "../+workloads-pods/pods.store";
|
||||
import { apiManager } from "../../api/api-manager";
|
||||
import { PodStatus } from "../../api/endpoints/pods.api";
|
||||
|
||||
@autobind()
|
||||
export class ReplicaSetStore extends KubeObjectStore<ReplicaSet> {
|
||||
api = replicaSetApi;
|
||||
@observable metrics: IPodMetrics = null;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
makeObservable(this);
|
||||
autoBind(this);
|
||||
}
|
||||
|
||||
async loadMetrics(replicaSet: ReplicaSet) {
|
||||
const pods = this.getChildPods(replicaSet);
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ import "./statefulset-scale-dialog.scss";
|
||||
|
||||
import { StatefulSet, statefulSetApi } from "../../api/endpoints";
|
||||
import React, { Component } from "react";
|
||||
import { computed, observable } from "mobx";
|
||||
import { computed, makeObservable, observable } from "mobx";
|
||||
import { observer } from "mobx-react";
|
||||
import { Dialog, DialogProps } from "../dialog";
|
||||
import { Wizard, WizardStep } from "../wizard";
|
||||
@@ -35,26 +35,33 @@ import { cssNames } from "../../utils";
|
||||
interface Props extends Partial<DialogProps> {
|
||||
}
|
||||
|
||||
const dialogState = observable.object({
|
||||
isOpen: false,
|
||||
data: null as StatefulSet,
|
||||
});
|
||||
|
||||
@observer
|
||||
export class StatefulSetScaleDialog extends Component<Props> {
|
||||
@observable static isOpen = false;
|
||||
@observable static data: StatefulSet = null;
|
||||
|
||||
@observable ready = false;
|
||||
@observable currentReplicas = 0;
|
||||
@observable desiredReplicas = 0;
|
||||
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
makeObservable(this);
|
||||
}
|
||||
|
||||
static open(statefulSet: StatefulSet) {
|
||||
StatefulSetScaleDialog.isOpen = true;
|
||||
StatefulSetScaleDialog.data = statefulSet;
|
||||
dialogState.isOpen = true;
|
||||
dialogState.data = statefulSet;
|
||||
}
|
||||
|
||||
static close() {
|
||||
StatefulSetScaleDialog.isOpen = false;
|
||||
dialogState.isOpen = false;
|
||||
}
|
||||
|
||||
get statefulSet() {
|
||||
return StatefulSetScaleDialog.data;
|
||||
return dialogState.data;
|
||||
}
|
||||
|
||||
close = () => {
|
||||
@@ -167,7 +174,7 @@ export class StatefulSetScaleDialog extends Component<Props> {
|
||||
return (
|
||||
<Dialog
|
||||
{...dialogProps}
|
||||
isOpen={StatefulSetScaleDialog.isOpen}
|
||||
isOpen={dialogState.isOpen}
|
||||
className={cssNames("StatefulSetScaleDialog", className)}
|
||||
onOpen={this.onOpen}
|
||||
onClose={this.onClose}
|
||||
|
||||
@@ -19,18 +19,25 @@
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
import { observable } from "mobx";
|
||||
import { autobind } from "../../utils";
|
||||
import { observable, makeObservable } from "mobx";
|
||||
import { autoBind } from "../../utils";
|
||||
import { KubeObjectStore } from "../../kube-object.store";
|
||||
import { IPodMetrics, podsApi, PodStatus, StatefulSet, statefulSetApi } from "../../api/endpoints";
|
||||
import { podsStore } from "../+workloads-pods/pods.store";
|
||||
import { apiManager } from "../../api/api-manager";
|
||||
|
||||
@autobind()
|
||||
export class StatefulSetStore extends KubeObjectStore<StatefulSet> {
|
||||
api = statefulSetApi;
|
||||
@observable metrics: IPodMetrics = null;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
makeObservable(this);
|
||||
autoBind(this);
|
||||
}
|
||||
|
||||
|
||||
async loadMetrics(statefulSet: StatefulSet) {
|
||||
const pods = this.getChildPods(statefulSet);
|
||||
|
||||
|
||||
@@ -26,7 +26,6 @@ import { observer } from "mobx-react";
|
||||
import { TabLayout, TabLayoutRoute } from "../layout/tab-layout";
|
||||
import { WorkloadsOverview } from "../+workloads-overview/overview";
|
||||
import { cronJobsRoute, cronJobsURL, daemonSetsRoute, daemonSetsURL, deploymentsRoute, deploymentsURL, jobsRoute, jobsURL, overviewRoute, overviewURL, podsRoute, podsURL, replicaSetsRoute, replicaSetsURL, statefulSetsRoute, statefulSetsURL } from "./workloads.route";
|
||||
import { namespaceUrlParam } from "../+namespaces/namespace.store";
|
||||
import { Pods } from "../+workloads-pods";
|
||||
import { Deployments } from "../+workloads-deployments";
|
||||
import { DaemonSets } from "../+workloads-daemonsets";
|
||||
@@ -39,12 +38,11 @@ import { ReplicaSets } from "../+workloads-replicasets";
|
||||
@observer
|
||||
export class Workloads extends React.Component {
|
||||
static get tabRoutes(): TabLayoutRoute[] {
|
||||
const query = namespaceUrlParam.toObjectParam();
|
||||
const routes: TabLayoutRoute[] = [
|
||||
{
|
||||
title: "Overview",
|
||||
component: WorkloadsOverview,
|
||||
url: overviewURL({ query }),
|
||||
url: overviewURL(),
|
||||
routePath: overviewRoute.path.toString()
|
||||
}
|
||||
];
|
||||
@@ -53,7 +51,7 @@ export class Workloads extends React.Component {
|
||||
routes.push({
|
||||
title: "Pods",
|
||||
component: Pods,
|
||||
url: podsURL({ query }),
|
||||
url: podsURL(),
|
||||
routePath: podsRoute.path.toString()
|
||||
});
|
||||
}
|
||||
@@ -62,7 +60,7 @@ export class Workloads extends React.Component {
|
||||
routes.push({
|
||||
title: "Deployments",
|
||||
component: Deployments,
|
||||
url: deploymentsURL({ query }),
|
||||
url: deploymentsURL(),
|
||||
routePath: deploymentsRoute.path.toString(),
|
||||
});
|
||||
}
|
||||
@@ -71,7 +69,7 @@ export class Workloads extends React.Component {
|
||||
routes.push({
|
||||
title: "DaemonSets",
|
||||
component: DaemonSets,
|
||||
url: daemonSetsURL({ query }),
|
||||
url: daemonSetsURL(),
|
||||
routePath: daemonSetsRoute.path.toString(),
|
||||
});
|
||||
}
|
||||
@@ -80,7 +78,7 @@ export class Workloads extends React.Component {
|
||||
routes.push({
|
||||
title: "StatefulSets",
|
||||
component: StatefulSets,
|
||||
url: statefulSetsURL({ query }),
|
||||
url: statefulSetsURL(),
|
||||
routePath: statefulSetsRoute.path.toString(),
|
||||
});
|
||||
}
|
||||
@@ -89,7 +87,7 @@ export class Workloads extends React.Component {
|
||||
routes.push({
|
||||
title: "ReplicaSets",
|
||||
component: ReplicaSets,
|
||||
url: replicaSetsURL({ query }),
|
||||
url: replicaSetsURL(),
|
||||
routePath: replicaSetsRoute.path.toString(),
|
||||
});
|
||||
}
|
||||
@@ -98,7 +96,7 @@ export class Workloads extends React.Component {
|
||||
routes.push({
|
||||
title: "Jobs",
|
||||
component: Jobs,
|
||||
url: jobsURL({ query }),
|
||||
url: jobsURL(),
|
||||
routePath: jobsRoute.path.toString(),
|
||||
});
|
||||
}
|
||||
@@ -107,7 +105,7 @@ export class Workloads extends React.Component {
|
||||
routes.push({
|
||||
title: "CronJobs",
|
||||
component: CronJobs,
|
||||
url: cronJobsURL({ query }),
|
||||
url: cronJobsURL(),
|
||||
routePath: cronJobsRoute.path.toString(),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ import "./ace-editor.scss";
|
||||
import React from "react";
|
||||
import { observer } from "mobx-react";
|
||||
import AceBuild, { Ace } from "ace-builds";
|
||||
import { autobind, cssNames, noop } from "../../utils";
|
||||
import { boundMethod, cssNames, noop } from "../../utils";
|
||||
|
||||
interface Props extends Partial<Ace.EditorOptions> {
|
||||
className?: string;
|
||||
@@ -66,6 +66,7 @@ export class AceEditor extends React.Component<Props, State> {
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
require("ace-builds/src-noconflict/mode-yaml");
|
||||
require("ace-builds/src-noconflict/mode-json");
|
||||
require("ace-builds/src-noconflict/theme-terminal");
|
||||
require("ace-builds/src-noconflict/ext-searchbox");
|
||||
}
|
||||
@@ -149,7 +150,7 @@ export class AceEditor extends React.Component<Props, State> {
|
||||
});
|
||||
}
|
||||
|
||||
@autobind()
|
||||
@boundMethod
|
||||
onCursorPosChange() {
|
||||
const { onCursorPosChange } = this.props;
|
||||
|
||||
@@ -158,7 +159,7 @@ export class AceEditor extends React.Component<Props, State> {
|
||||
}
|
||||
}
|
||||
|
||||
@autobind()
|
||||
@boundMethod
|
||||
onChange(delta: Ace.Delta) {
|
||||
const { onChange } = this.props;
|
||||
|
||||
|
||||
@@ -21,9 +21,9 @@
|
||||
|
||||
import "./animate.scss";
|
||||
import React from "react";
|
||||
import { observable, reaction } from "mobx";
|
||||
import { observable, reaction, makeObservable } from "mobx";
|
||||
import { disposeOnUnmount, observer } from "mobx-react";
|
||||
import { autobind, cssNames, noop } from "../../utils";
|
||||
import { boundMethod, cssNames, noop } from "../../utils";
|
||||
|
||||
export type AnimateName = "opacity" | "slide-right" | "opacity-scale" | string;
|
||||
|
||||
@@ -51,6 +51,11 @@ export class Animate extends React.Component<AnimateProps> {
|
||||
leave: false
|
||||
};
|
||||
|
||||
constructor(props: AnimateProps) {
|
||||
super(props);
|
||||
makeObservable(this);
|
||||
}
|
||||
|
||||
get contentElem() {
|
||||
return React.Children.only(this.props.children) as React.ReactElement<React.HTMLAttributes<any>>;
|
||||
}
|
||||
@@ -87,7 +92,7 @@ export class Animate extends React.Component<AnimateProps> {
|
||||
this.statusClassName.leave = false;
|
||||
}
|
||||
|
||||
@autobind()
|
||||
@boundMethod
|
||||
onTransitionEnd(evt: React.TransitionEvent) {
|
||||
const { enter, leave } = this.statusClassName;
|
||||
const { onTransitionEnd } = this.contentElem.props;
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
import React from "react";
|
||||
import { observable } from "mobx";
|
||||
import { observable, makeObservable } from "mobx";
|
||||
import { disposeOnUnmount, observer } from "mobx-react";
|
||||
import { Redirect, Route, Router, Switch } from "react-router";
|
||||
import { history } from "../navigation";
|
||||
@@ -74,6 +74,11 @@ import { namespaceStore } from "./+namespaces/namespace.store";
|
||||
|
||||
@observer
|
||||
export class App extends React.Component {
|
||||
constructor(props: {}) {
|
||||
super(props);
|
||||
makeObservable(this);
|
||||
}
|
||||
|
||||
static async init() {
|
||||
const frameId = webFrame.routingId;
|
||||
const clusterId = getHostedClusterId();
|
||||
@@ -99,7 +104,7 @@ export class App extends React.Component {
|
||||
whatInput.ask(); // Start to monitor user input device
|
||||
|
||||
// Setup hosted cluster context
|
||||
KubeObjectStore.defaultContext = clusterContext;
|
||||
KubeObjectStore.defaultContext.set(clusterContext);
|
||||
kubeWatchApi.context = clusterContext;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
import "./checkbox.scss";
|
||||
import React from "react";
|
||||
import { autobind, cssNames } from "../../utils";
|
||||
import { boundMethod, cssNames } from "../../utils";
|
||||
|
||||
export interface CheckboxProps<T = boolean> {
|
||||
theme?: "dark" | "light";
|
||||
@@ -36,7 +36,7 @@ export interface CheckboxProps<T = boolean> {
|
||||
export class Checkbox extends React.PureComponent<CheckboxProps> {
|
||||
private input: HTMLInputElement;
|
||||
|
||||
@autobind()
|
||||
@boundMethod
|
||||
onChange(evt: React.ChangeEvent<HTMLInputElement>) {
|
||||
if (this.props.onChange) {
|
||||
this.props.onChange(this.input.checked, evt);
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
import "./clipboard.scss";
|
||||
import React from "react";
|
||||
import { findDOMNode } from "react-dom";
|
||||
import { autobind } from "../../../common/utils";
|
||||
import { boundMethod } from "../../../common/utils";
|
||||
import { Notifications } from "../notifications";
|
||||
import { copyToClipboard } from "../../utils/copyToClipboard";
|
||||
import logger from "../../../main/logger";
|
||||
@@ -54,7 +54,7 @@ export class Clipboard extends React.Component<CopyToClipboardProps> {
|
||||
return React.Children.only(this.props.children) as React.ReactElement;
|
||||
}
|
||||
|
||||
@autobind()
|
||||
@boundMethod
|
||||
onClick(evt: React.MouseEvent) {
|
||||
if (this.rootReactElem.props.onClick) {
|
||||
this.rootReactElem.props.onClick(evt); // pass event to children-root-element if any
|
||||
|
||||
@@ -25,7 +25,7 @@ import "./cluster-status.scss";
|
||||
import React from "react";
|
||||
import { observer } from "mobx-react";
|
||||
import { ipcRenderer } from "electron";
|
||||
import { computed, observable } from "mobx";
|
||||
import { computed, observable, makeObservable } from "mobx";
|
||||
import { requestMain, subscribeToBroadcast } from "../../../common/ipc";
|
||||
import { Icon } from "../icon";
|
||||
import { Button } from "../button";
|
||||
@@ -45,6 +45,11 @@ export class ClusterStatus extends React.Component<Props> {
|
||||
@observable authOutput: KubeAuthProxyLog[] = [];
|
||||
@observable isReconnecting = false;
|
||||
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
makeObservable(this);
|
||||
}
|
||||
|
||||
get cluster(): Cluster {
|
||||
return ClusterStore.getInstance().getById(this.props.clusterId);
|
||||
}
|
||||
|
||||
@@ -21,83 +21,80 @@
|
||||
|
||||
import "./cluster-view.scss";
|
||||
import React from "react";
|
||||
import { reaction } from "mobx";
|
||||
import { computed, makeObservable, reaction } from "mobx";
|
||||
import { disposeOnUnmount, observer } from "mobx-react";
|
||||
import type { RouteComponentProps } from "react-router";
|
||||
import type { IClusterViewRouteParams } from "./cluster-view.route";
|
||||
import { ClusterStatus } from "./cluster-status";
|
||||
import { hasLoadedView, initView, lensViews, refreshViews } from "./lens-views";
|
||||
import { hasLoadedView, initView, refreshViews } from "./lens-views";
|
||||
import type { Cluster } from "../../../main/cluster";
|
||||
import { ClusterStore } from "../../../common/cluster-store";
|
||||
import { requestMain } from "../../../common/ipc";
|
||||
import { clusterActivateHandler } from "../../../common/cluster-ipc";
|
||||
import { catalogEntityRegistry } from "../../api/catalog-entity-registry";
|
||||
import { catalogURL } from "../+catalog";
|
||||
import { navigate } from "../../navigation";
|
||||
|
||||
interface Props extends RouteComponentProps<IClusterViewRouteParams> {
|
||||
}
|
||||
import { getMatchedClusterId, navigate } from "../../navigation";
|
||||
import { catalogURL } from "../+catalog/catalog.route";
|
||||
|
||||
@observer
|
||||
export class ClusterView extends React.Component<Props> {
|
||||
get clusterId() {
|
||||
return this.props.match.params.clusterId;
|
||||
export class ClusterView extends React.Component {
|
||||
constructor(props: {}) {
|
||||
super(props);
|
||||
makeObservable(this);
|
||||
}
|
||||
|
||||
get cluster(): Cluster {
|
||||
get clusterId() {
|
||||
return getMatchedClusterId();
|
||||
}
|
||||
|
||||
@computed get cluster(): Cluster | undefined {
|
||||
return ClusterStore.getInstance().getById(this.clusterId);
|
||||
}
|
||||
|
||||
async componentDidMount() {
|
||||
disposeOnUnmount(this, [
|
||||
reaction(() => this.clusterId, (clusterId) => {
|
||||
this.showCluster(clusterId);
|
||||
}, { fireImmediately: true}
|
||||
),
|
||||
reaction(() => this.cluster?.ready, (ready) => {
|
||||
const clusterView = lensViews.get(this.clusterId);
|
||||
@computed get isReady(): boolean {
|
||||
const { cluster, clusterId } = this;
|
||||
|
||||
if (clusterView && clusterView.isLoaded && !ready) {
|
||||
navigate(catalogURL());
|
||||
return cluster?.ready && cluster?.available && hasLoadedView(clusterId);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.bindEvents();
|
||||
}
|
||||
|
||||
bindEvents() {
|
||||
disposeOnUnmount(this, [
|
||||
reaction(() => this.clusterId, async (clusterId) => {
|
||||
refreshViews(clusterId); // refresh visibility of active cluster
|
||||
initView(clusterId); // init cluster-view (iframe), requires parent container #lens-views to be in DOM
|
||||
requestMain(clusterActivateHandler, clusterId, false); // activate and fetch cluster's state from main
|
||||
catalogEntityRegistry.activeEntity = catalogEntityRegistry.getById(clusterId);
|
||||
}, {
|
||||
fireImmediately: true,
|
||||
}),
|
||||
|
||||
reaction(() => this.isReady, (ready) => {
|
||||
if (ready) {
|
||||
refreshViews(this.clusterId); // show cluster's view (iframe)
|
||||
} else if (hasLoadedView(this.clusterId)) {
|
||||
navigate(catalogURL()); // redirect to catalog when active cluster get disconnected/not available
|
||||
}
|
||||
})
|
||||
}, {
|
||||
fireImmediately: true,
|
||||
}),
|
||||
]);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this.hideCluster();
|
||||
}
|
||||
renderStatus(): React.ReactNode {
|
||||
const { clusterId, cluster, isReady } = this;
|
||||
|
||||
showCluster(clusterId: string) {
|
||||
initView(clusterId);
|
||||
requestMain(clusterActivateHandler, this.clusterId, false);
|
||||
|
||||
const entity = catalogEntityRegistry.getById(this.clusterId);
|
||||
|
||||
if (entity) {
|
||||
catalogEntityRegistry.activeEntity = entity;
|
||||
if (cluster && !isReady) {
|
||||
return <ClusterStatus clusterId={clusterId} className="box center"/>;
|
||||
}
|
||||
}
|
||||
|
||||
hideCluster() {
|
||||
refreshViews();
|
||||
|
||||
if (catalogEntityRegistry.activeEntity?.metadata?.uid === this.clusterId) {
|
||||
catalogEntityRegistry.activeEntity = null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
render() {
|
||||
const { cluster } = this;
|
||||
const showStatus = cluster && (!cluster.available || !hasLoadedView(cluster.id) || !cluster.ready);
|
||||
|
||||
refreshViews(cluster.id);
|
||||
|
||||
return (
|
||||
<div className="ClusterView flex align-center">
|
||||
{showStatus && (
|
||||
<ClusterStatus key={cluster.id} clusterId={cluster.id} className="box center"/>
|
||||
)}
|
||||
{this.renderStatus()}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -36,15 +36,9 @@ export function hasLoadedView(clusterId: ClusterId): boolean {
|
||||
}
|
||||
|
||||
export async function initView(clusterId: ClusterId) {
|
||||
refreshViews(clusterId);
|
||||
|
||||
if (!clusterId || lensViews.has(clusterId)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const cluster = ClusterStore.getInstance().getById(clusterId);
|
||||
|
||||
if (!cluster) {
|
||||
if (!cluster || lensViews.has(clusterId)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -60,6 +54,7 @@ export async function initView(clusterId: ClusterId) {
|
||||
}, { once: true });
|
||||
lensViews.set(clusterId, { clusterId, view: iframe });
|
||||
parentElem.appendChild(iframe);
|
||||
|
||||
logger.info(`[LENS-VIEW]: waiting cluster to be ready, clusterId=${clusterId}`);
|
||||
await cluster.whenReady;
|
||||
await autoCleanOnRemove(clusterId, iframe);
|
||||
@@ -84,7 +79,8 @@ export async function autoCleanOnRemove(clusterId: ClusterId, iframe: HTMLIFrame
|
||||
}
|
||||
|
||||
export function refreshViews(visibleClusterId?: string) {
|
||||
const cluster = !visibleClusterId ? null : ClusterStore.getInstance().getById(visibleClusterId);
|
||||
logger.info(`[LENS-VIEW]: refreshing iframe views, visible cluster id=${visibleClusterId}`);
|
||||
const cluster = ClusterStore.getInstance().getById(visibleClusterId);
|
||||
|
||||
lensViews.forEach(({ clusterId, view, isLoaded }) => {
|
||||
const isCurrent = clusterId === cluster?.id;
|
||||
|
||||
+6
-1
@@ -24,7 +24,7 @@ import { observer } from "mobx-react";
|
||||
import type { Cluster } from "../../../../main/cluster";
|
||||
import { SubTitle } from "../../layout/sub-title";
|
||||
import { EditableList } from "../../editable-list";
|
||||
import { observable } from "mobx";
|
||||
import { observable, makeObservable } from "mobx";
|
||||
|
||||
interface Props {
|
||||
cluster: Cluster;
|
||||
@@ -34,6 +34,11 @@ interface Props {
|
||||
export class ClusterAccessibleNamespaces extends React.Component<Props> {
|
||||
@observable namespaces = new Set(this.props.cluster.accessibleNamespaces);
|
||||
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
makeObservable(this);
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<>
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
*/
|
||||
|
||||
import React from "react";
|
||||
import { observable, autorun } from "mobx";
|
||||
import { observable, autorun, makeObservable } from "mobx";
|
||||
import { observer, disposeOnUnmount } from "mobx-react";
|
||||
import type { Cluster } from "../../../../main/cluster";
|
||||
import { Input } from "../../input";
|
||||
@@ -34,6 +34,11 @@ interface Props {
|
||||
export class ClusterHomeDirSetting extends React.Component<Props> {
|
||||
@observable directory = "";
|
||||
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
makeObservable(this);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
disposeOnUnmount(this,
|
||||
autorun(() => {
|
||||
|
||||
@@ -23,7 +23,7 @@ import React from "react";
|
||||
import type { Cluster } from "../../../../main/cluster";
|
||||
import { observer } from "mobx-react";
|
||||
import { SubTitle } from "../../layout/sub-title";
|
||||
import { autobind } from "../../../../common/utils";
|
||||
import { boundMethod } from "../../../../common/utils";
|
||||
import { shell } from "electron";
|
||||
|
||||
interface Props {
|
||||
@@ -33,7 +33,7 @@ interface Props {
|
||||
@observer
|
||||
export class ClusterKubeconfig extends React.Component<Props> {
|
||||
|
||||
@autobind()
|
||||
@boundMethod
|
||||
openKubeconfig() {
|
||||
const { cluster } = this.props;
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ import { Icon } from "../../icon/icon";
|
||||
import { Button } from "../../button/button";
|
||||
import { SubTitle } from "../../layout/sub-title";
|
||||
import type { Cluster } from "../../../../main/cluster";
|
||||
import { observable, reaction } from "mobx";
|
||||
import { observable, reaction, makeObservable } from "mobx";
|
||||
|
||||
interface Props {
|
||||
cluster: Cluster;
|
||||
@@ -49,6 +49,11 @@ export enum ResourceType {
|
||||
export class ClusterMetricsSetting extends React.Component<Props> {
|
||||
@observable hiddenMetrics = observable.set<string>();
|
||||
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
makeObservable(this);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.hiddenMetrics = observable.set<string>(this.props.cluster.preferences.hiddenMetrics ?? []);
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
import React from "react";
|
||||
import type { Cluster } from "../../../../main/cluster";
|
||||
import { Input } from "../../input";
|
||||
import { observable, autorun } from "mobx";
|
||||
import { observable, autorun, makeObservable } from "mobx";
|
||||
import { observer, disposeOnUnmount } from "mobx-react";
|
||||
import { SubTitle } from "../../layout/sub-title";
|
||||
import { isRequired } from "../../input/input_validators";
|
||||
@@ -35,6 +35,11 @@ interface Props {
|
||||
export class ClusterNameSetting extends React.Component<Props> {
|
||||
@observable name = "";
|
||||
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
makeObservable(this);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
disposeOnUnmount(this,
|
||||
autorun(() => {
|
||||
|
||||
@@ -26,7 +26,7 @@ import type { Cluster } from "../../../../main/cluster";
|
||||
import { SubTitle } from "../../layout/sub-title";
|
||||
import { Select, SelectOption } from "../../select";
|
||||
import { Input } from "../../input";
|
||||
import { observable, computed, autorun } from "mobx";
|
||||
import { observable, computed, autorun, makeObservable } from "mobx";
|
||||
import { productName } from "../../../../common/vars";
|
||||
|
||||
const options: SelectOption<string>[] = [
|
||||
@@ -43,6 +43,11 @@ export class ClusterPrometheusSetting extends React.Component<Props> {
|
||||
@observable path = "";
|
||||
@observable provider = "";
|
||||
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
makeObservable(this);
|
||||
}
|
||||
|
||||
@computed get canEditPrometheusPath() {
|
||||
if (this.provider === "" || this.provider === "lens") return false;
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
*/
|
||||
|
||||
import React from "react";
|
||||
import { observable, autorun } from "mobx";
|
||||
import { observable, autorun, makeObservable } from "mobx";
|
||||
import { observer, disposeOnUnmount } from "mobx-react";
|
||||
import type { Cluster } from "../../../../main/cluster";
|
||||
import { Input, InputValidators } from "../../input";
|
||||
@@ -34,6 +34,11 @@ interface Props {
|
||||
export class ClusterProxySetting extends React.Component<Props> {
|
||||
@observable proxy = "";
|
||||
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
makeObservable(this);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
disposeOnUnmount(this,
|
||||
autorun(() => {
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
import React from "react";
|
||||
import { disposeOnUnmount, observer } from "mobx-react";
|
||||
import type { Cluster } from "../../../../main/cluster";
|
||||
import { observable, reaction } from "mobx";
|
||||
import { observable, reaction, makeObservable } from "mobx";
|
||||
import { Badge } from "../../badge/badge";
|
||||
import { Icon } from "../../icon/icon";
|
||||
|
||||
@@ -34,6 +34,11 @@ interface Props {
|
||||
export class ShowMetricsSetting extends React.Component<Props> {
|
||||
@observable hiddenMetrics = observable.set<string>();
|
||||
|
||||
constructor(props: Props) {
|
||||
super(props);
|
||||
makeObservable(this);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.hiddenMetrics = observable.set<string>(this.props.cluster.preferences.hiddenMetrics ?? []);
|
||||
|
||||
|
||||
Loaded 100 of 256 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user