mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Remove lingui (#1874)
* remove lingui Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * babelless Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * tweak ts-loader options Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com> * tweak renderer webpack config Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>
This commit is contained in:
parent
050603a7b3
commit
a03da3c572
12
.babelrc
12
.babelrc
@ -1,12 +0,0 @@
|
|||||||
{
|
|
||||||
"presets": [
|
|
||||||
"@babel/preset-env",
|
|
||||||
"@babel/preset-react",
|
|
||||||
"@lingui/babel-preset-react"
|
|
||||||
],
|
|
||||||
"plugins": [
|
|
||||||
"macros",
|
|
||||||
"@babel/plugin-syntax-dynamic-import",
|
|
||||||
"@babel/plugin-transform-runtime"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
34
package.json
34
package.json
@ -20,7 +20,6 @@
|
|||||||
"compile": "env NODE_ENV=production concurrently yarn:compile:*",
|
"compile": "env NODE_ENV=production concurrently yarn:compile:*",
|
||||||
"compile:main": "yarn run webpack --config webpack.main.ts",
|
"compile:main": "yarn run webpack --config webpack.main.ts",
|
||||||
"compile:renderer": "yarn run webpack --config webpack.renderer.ts",
|
"compile:renderer": "yarn run webpack --config webpack.renderer.ts",
|
||||||
"compile:i18n": "yarn run lingui compile",
|
|
||||||
"compile:extension-types": "yarn run webpack --config webpack.extensions.ts",
|
"compile:extension-types": "yarn run webpack --config webpack.extensions.ts",
|
||||||
"npm:fix-package-version": "yarn run ts-node build/set_npm_version.ts",
|
"npm:fix-package-version": "yarn run ts-node build/set_npm_version.ts",
|
||||||
"build:linux": "yarn run compile && electron-builder --linux --dir -c.productName=Lens",
|
"build:linux": "yarn run compile && electron-builder --linux --dir -c.productName=Lens",
|
||||||
@ -32,7 +31,6 @@
|
|||||||
"dist:win": "yarn run compile && electron-builder --publish onTag --x64 --ia32",
|
"dist:win": "yarn run compile && electron-builder --publish onTag --x64 --ia32",
|
||||||
"dist:dir": "yarn run dist --dir -c.compression=store -c.mac.identity=null",
|
"dist:dir": "yarn run dist --dir -c.compression=store -c.mac.identity=null",
|
||||||
"postinstall": "patch-package",
|
"postinstall": "patch-package",
|
||||||
"i18n:extract": "yarn run lingui extract",
|
|
||||||
"download-bins": "concurrently yarn:download:*",
|
"download-bins": "concurrently yarn:download:*",
|
||||||
"download:kubectl": "yarn run ts-node build/download_kubectl.ts",
|
"download:kubectl": "yarn run ts-node build/download_kubectl.ts",
|
||||||
"download:helm": "yarn run ts-node build/download_helm.ts",
|
"download:helm": "yarn run ts-node build/download_helm.ts",
|
||||||
@ -50,23 +48,6 @@
|
|||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=12 <13"
|
"node": ">=12 <13"
|
||||||
},
|
},
|
||||||
"lingui": {
|
|
||||||
"locales": [
|
|
||||||
"en",
|
|
||||||
"ru",
|
|
||||||
"fi"
|
|
||||||
],
|
|
||||||
"format": "po",
|
|
||||||
"sourceLocale": "en",
|
|
||||||
"fallbackLocale": "en",
|
|
||||||
"compileNamespace": "cjs",
|
|
||||||
"catalogs": [
|
|
||||||
{
|
|
||||||
"path": "./locales/{locale}/messages",
|
|
||||||
"include": "./src/renderer"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"jest": {
|
"jest": {
|
||||||
"collectCoverage": false,
|
"collectCoverage": false,
|
||||||
"verbose": true,
|
"verbose": true,
|
||||||
@ -250,18 +231,7 @@
|
|||||||
"ws": "^7.3.0"
|
"ws": "^7.3.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.10.2",
|
|
||||||
"@babel/plugin-syntax-dynamic-import": "^7.2.0",
|
|
||||||
"@babel/plugin-transform-runtime": "^7.6.2",
|
|
||||||
"@babel/preset-env": "^7.10.2",
|
|
||||||
"@babel/preset-react": "^7.10.1",
|
|
||||||
"@babel/preset-typescript": "^7.10.1",
|
|
||||||
"@emeraldpay/hashicon-react": "^0.4.0",
|
"@emeraldpay/hashicon-react": "^0.4.0",
|
||||||
"@lingui/babel-preset-react": "^2.9.1",
|
|
||||||
"@lingui/cli": "^3.0.0-13",
|
|
||||||
"@lingui/loader": "^3.0.0-13",
|
|
||||||
"@lingui/macro": "^3.0.0-13",
|
|
||||||
"@lingui/react": "^3.0.0-13",
|
|
||||||
"@material-ui/core": "^4.10.1",
|
"@material-ui/core": "^4.10.1",
|
||||||
"@pmmmwh/react-refresh-webpack-plugin": "^0.4.3",
|
"@pmmmwh/react-refresh-webpack-plugin": "^0.4.3",
|
||||||
"@testing-library/jest-dom": "^5.11.5",
|
"@testing-library/jest-dom": "^5.11.5",
|
||||||
@ -319,10 +289,6 @@
|
|||||||
"@typescript-eslint/parser": "^4.0.0",
|
"@typescript-eslint/parser": "^4.0.0",
|
||||||
"ace-builds": "^1.4.11",
|
"ace-builds": "^1.4.11",
|
||||||
"ansi_up": "^4.0.4",
|
"ansi_up": "^4.0.4",
|
||||||
"babel-core": "^7.0.0-beta.3",
|
|
||||||
"babel-loader": "^8.1.0",
|
|
||||||
"babel-plugin-macros": "^2.8.0",
|
|
||||||
"babel-runtime": "^6.26.0",
|
|
||||||
"chart.js": "^2.9.3",
|
"chart.js": "^2.9.3",
|
||||||
"circular-dependency-plugin": "^5.2.0",
|
"circular-dependency-plugin": "^5.2.0",
|
||||||
"color": "^3.1.2",
|
"color": "^3.1.2",
|
||||||
|
|||||||
@ -14,7 +14,6 @@ import { extensionLoader } from "../extensions/extension-loader";
|
|||||||
import { extensionsStore } from "../extensions/extensions-store";
|
import { extensionsStore } from "../extensions/extensions-store";
|
||||||
import { filesystemProvisionerStore } from "../main/extension-filesystem";
|
import { filesystemProvisionerStore } from "../main/extension-filesystem";
|
||||||
import { App } from "./components/app";
|
import { App } from "./components/app";
|
||||||
import { i18nStore } from "./i18n";
|
|
||||||
import { LensApp } from "./lens-app";
|
import { LensApp } from "./lens-app";
|
||||||
import { themeStore } from "./theme.store";
|
import { themeStore } from "./theme.store";
|
||||||
|
|
||||||
@ -44,7 +43,6 @@ export async function bootstrap(App: AppComponent) {
|
|||||||
clusterStore.load(),
|
clusterStore.load(),
|
||||||
extensionsStore.load(),
|
extensionsStore.load(),
|
||||||
filesystemProvisionerStore.load(),
|
filesystemProvisionerStore.load(),
|
||||||
i18nStore.init(),
|
|
||||||
themeStore.init(),
|
themeStore.init(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { Trans } from "@lingui/macro";
|
|
||||||
import { TabLayout } from "../layout/tab-layout";
|
import { TabLayout } from "../layout/tab-layout";
|
||||||
|
|
||||||
export class NotFound extends React.Component {
|
export class NotFound extends React.Component {
|
||||||
@ -7,7 +6,7 @@ export class NotFound extends React.Component {
|
|||||||
return (
|
return (
|
||||||
<TabLayout className="NotFound" contentClass="flex">
|
<TabLayout className="NotFound" contentClass="flex">
|
||||||
<p className="box center">
|
<p className="box center">
|
||||||
<Trans>Page not found</Trans>
|
Page not found
|
||||||
</p>
|
</p>
|
||||||
</TabLayout>
|
</TabLayout>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -5,8 +5,6 @@ import { observer } from "mobx-react";
|
|||||||
import { action, observable, runInAction } from "mobx";
|
import { action, observable, runInAction } from "mobx";
|
||||||
import { remote } from "electron";
|
import { remote } from "electron";
|
||||||
import { KubeConfig } from "@kubernetes/client-node";
|
import { KubeConfig } from "@kubernetes/client-node";
|
||||||
import { _i18n } from "../../i18n";
|
|
||||||
import { t, Trans } from "@lingui/macro";
|
|
||||||
import { Select, SelectOption } from "../select";
|
import { Select, SelectOption } from "../select";
|
||||||
import { DropFileInput, Input } from "../input";
|
import { DropFileInput, Input } from "../input";
|
||||||
import { AceEditor } from "../ace-editor";
|
import { AceEditor } from "../ace-editor";
|
||||||
@ -118,8 +116,8 @@ export class AddCluster extends React.Component {
|
|||||||
const { canceled, filePaths } = await dialog.showOpenDialog(BrowserWindow.getFocusedWindow(), {
|
const { canceled, filePaths } = await dialog.showOpenDialog(BrowserWindow.getFocusedWindow(), {
|
||||||
defaultPath: this.kubeConfigPath,
|
defaultPath: this.kubeConfigPath,
|
||||||
properties: ["openFile", "showHiddenFiles"],
|
properties: ["openFile", "showHiddenFiles"],
|
||||||
message: _i18n._(t`Select custom kubeconfig file`),
|
message: `Select custom kubeconfig file`,
|
||||||
buttonLabel: _i18n._(t`Use configuration`),
|
buttonLabel: `Use configuration`,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!canceled && filePaths.length) {
|
if (!canceled && filePaths.length) {
|
||||||
@ -138,7 +136,7 @@ export class AddCluster extends React.Component {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
if (!this.selectedContexts.length) {
|
if (!this.selectedContexts.length) {
|
||||||
this.error = <Trans>Please select at least one cluster context</Trans>;
|
this.error = "Please select at least one cluster context";
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -156,7 +154,7 @@ export class AddCluster extends React.Component {
|
|||||||
this.error = String(err.message);
|
this.error = String(err.message);
|
||||||
|
|
||||||
if (err instanceof ExecValidationNotFoundError) {
|
if (err instanceof ExecValidationNotFoundError) {
|
||||||
Notifications.error(<Trans>Error while adding cluster(s): {this.error}</Trans>);
|
Notifications.error(<>Error while adding cluster(s): {this.error}</>);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
@ -193,7 +191,7 @@ export class AddCluster extends React.Component {
|
|||||||
} else {
|
} else {
|
||||||
if (newClusters.length > 1) {
|
if (newClusters.length > 1) {
|
||||||
Notifications.ok(
|
Notifications.ok(
|
||||||
<Trans>Successfully imported <b>{newClusters.length}</b> cluster(s)</Trans>
|
<>Successfully imported <b>{newClusters.length}</b> cluster(s)</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -201,7 +199,7 @@ export class AddCluster extends React.Component {
|
|||||||
this.refreshContexts();
|
this.refreshContexts();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this.error = String(err);
|
this.error = String(err);
|
||||||
Notifications.error(<Trans>Error while adding cluster(s): {this.error}</Trans>);
|
Notifications.error(<>Error while adding cluster(s): {this.error}</>);
|
||||||
} finally {
|
} finally {
|
||||||
this.isWaiting = false;
|
this.isWaiting = false;
|
||||||
}
|
}
|
||||||
@ -224,11 +222,11 @@ export class AddCluster extends React.Component {
|
|||||||
<Tabs onChange={this.onKubeConfigTabChange}>
|
<Tabs onChange={this.onKubeConfigTabChange}>
|
||||||
<Tab
|
<Tab
|
||||||
value={KubeConfigSourceTab.FILE}
|
value={KubeConfigSourceTab.FILE}
|
||||||
label={<Trans>Select kubeconfig file</Trans>}
|
label="Select kubeconfig file"
|
||||||
active={this.sourceTab == KubeConfigSourceTab.FILE}/>
|
active={this.sourceTab == KubeConfigSourceTab.FILE}/>
|
||||||
<Tab
|
<Tab
|
||||||
value={KubeConfigSourceTab.TEXT}
|
value={KubeConfigSourceTab.TEXT}
|
||||||
label={<Trans>Paste as text</Trans>}
|
label="Paste as text"
|
||||||
active={this.sourceTab == KubeConfigSourceTab.TEXT}
|
active={this.sourceTab == KubeConfigSourceTab.TEXT}
|
||||||
/>
|
/>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
@ -246,17 +244,17 @@ export class AddCluster extends React.Component {
|
|||||||
<Icon
|
<Icon
|
||||||
material="settings_backup_restore"
|
material="settings_backup_restore"
|
||||||
onClick={() => this.setKubeConfig(kubeConfigDefaultPath)}
|
onClick={() => this.setKubeConfig(kubeConfigDefaultPath)}
|
||||||
tooltip={<Trans>Reset</Trans>}
|
tooltip="Reset"
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<Icon
|
<Icon
|
||||||
material="folder"
|
material="folder"
|
||||||
onClick={this.selectKubeConfigDialog}
|
onClick={this.selectKubeConfigDialog}
|
||||||
tooltip={<Trans>Browse</Trans>}
|
tooltip="Browse"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<small className="hint">
|
<small className="hint">
|
||||||
<Trans>Pro-Tip: you can also drag-n-drop kubeconfig file to this area</Trans>
|
Pro-Tip: you can also drag-n-drop kubeconfig file to this area
|
||||||
</small>
|
</small>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
@ -273,7 +271,7 @@ export class AddCluster extends React.Component {
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<small className="hint">
|
<small className="hint">
|
||||||
<Trans>Pro-Tip: paste kubeconfig to get available contexts</Trans>
|
Pro-Tip: paste kubeconfig to get available contexts
|
||||||
</small>
|
</small>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
@ -284,8 +282,8 @@ export class AddCluster extends React.Component {
|
|||||||
renderContextSelector() {
|
renderContextSelector() {
|
||||||
const allContexts = Array.from(this.kubeContexts.keys());
|
const allContexts = Array.from(this.kubeContexts.keys());
|
||||||
const placeholder = this.selectedContexts.length > 0
|
const placeholder = this.selectedContexts.length > 0
|
||||||
? <Trans>Selected contexts: <b>{this.selectedContexts.length}</b></Trans>
|
? <>Selected contexts: <b>{this.selectedContexts.length}</b></>
|
||||||
: <Trans>Select contexts</Trans>;
|
: "Select contexts";
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
@ -297,7 +295,7 @@ export class AddCluster extends React.Component {
|
|||||||
isOptionSelected={() => false}
|
isOptionSelected={() => false}
|
||||||
options={allContexts}
|
options={allContexts}
|
||||||
formatOptionLabel={this.formatContextLabel}
|
formatOptionLabel={this.formatContextLabel}
|
||||||
noOptionsMessage={() => _i18n._(t`No contexts available or they have been added already`)}
|
noOptionsMessage={() => `No contexts available or they have been added already`}
|
||||||
onChange={({ value: ctx }: SelectOption<string>) => {
|
onChange={({ value: ctx }: SelectOption<string>) => {
|
||||||
if (this.selectedContexts.includes(ctx)) {
|
if (this.selectedContexts.includes(ctx)) {
|
||||||
this.selectedContexts.remove(ctx);
|
this.selectedContexts.remove(ctx);
|
||||||
@ -361,7 +359,7 @@ export class AddCluster extends React.Component {
|
|||||||
{this.renderContextSelector()}
|
{this.renderContextSelector()}
|
||||||
<div className="cluster-settings">
|
<div className="cluster-settings">
|
||||||
<a href="#" onClick={() => this.showSettings = !this.showSettings}>
|
<a href="#" onClick={() => this.showSettings = !this.showSettings}>
|
||||||
<Trans>Proxy settings</Trans>
|
Proxy settings
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
{this.showSettings && (
|
{this.showSettings && (
|
||||||
@ -386,10 +384,10 @@ export class AddCluster extends React.Component {
|
|||||||
<Button
|
<Button
|
||||||
primary
|
primary
|
||||||
disabled={submitDisabled}
|
disabled={submitDisabled}
|
||||||
label={this.selectedContexts.length < 2 ? <Trans>Add cluster</Trans> : <Trans>Add clusters</Trans>}
|
label={this.selectedContexts.length < 2 ? "Add cluster" : "Add clusters"}
|
||||||
onClick={this.addClusters}
|
onClick={this.addClusters}
|
||||||
waiting={this.isWaiting}
|
waiting={this.isWaiting}
|
||||||
tooltip={submitDisabled ? _i18n._("Select at least one cluster to add.") : undefined}
|
tooltip={submitDisabled ? "Select at least one cluster to add." : undefined}
|
||||||
tooltipOverrideDisabled
|
tooltipOverrideDisabled
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -2,7 +2,6 @@ import "./helm-chart-details.scss";
|
|||||||
|
|
||||||
import React, { Component } from "react";
|
import React, { Component } from "react";
|
||||||
import { HelmChart, helmChartsApi } from "../../api/endpoints/helm-charts.api";
|
import { HelmChart, helmChartsApi } from "../../api/endpoints/helm-charts.api";
|
||||||
import { t, Trans } from "@lingui/macro";
|
|
||||||
import { observable, autorun } from "mobx";
|
import { observable, autorun } from "mobx";
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { Drawer, DrawerItem } from "../drawer";
|
import { Drawer, DrawerItem } from "../drawer";
|
||||||
@ -14,7 +13,6 @@ import { Button } from "../button";
|
|||||||
import { Select, SelectOption } from "../select";
|
import { Select, SelectOption } from "../select";
|
||||||
import { createInstallChartTab } from "../dock/install-chart.store";
|
import { createInstallChartTab } from "../dock/install-chart.store";
|
||||||
import { Badge } from "../badge";
|
import { Badge } from "../badge";
|
||||||
import { _i18n } from "../../i18n";
|
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
chart: HelmChart;
|
chart: HelmChart;
|
||||||
@ -84,9 +82,9 @@ export class HelmChartDetails extends Component<Props> {
|
|||||||
<div className="intro-contents box grow">
|
<div className="intro-contents box grow">
|
||||||
<div className="description flex align-center justify-space-between">
|
<div className="description flex align-center justify-space-between">
|
||||||
{selectedChart.getDescription()}
|
{selectedChart.getDescription()}
|
||||||
<Button primary label={_i18n._(t`Install`)} onClick={this.install} />
|
<Button primary label={`Install`} onClick={this.install} />
|
||||||
</div>
|
</div>
|
||||||
<DrawerItem name={_i18n._(t`Version`)} className="version" onClick={stopPropagation}>
|
<DrawerItem name={`Version`} className="version" onClick={stopPropagation}>
|
||||||
<Select
|
<Select
|
||||||
themeName="outlined"
|
themeName="outlined"
|
||||||
menuPortalTarget={null}
|
menuPortalTarget={null}
|
||||||
@ -95,16 +93,16 @@ export class HelmChartDetails extends Component<Props> {
|
|||||||
onChange={onVersionChange}
|
onChange={onVersionChange}
|
||||||
/>
|
/>
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
<DrawerItem name={_i18n._(t`Home`)}>
|
<DrawerItem name={`Home`}>
|
||||||
<a href={selectedChart.getHome()} target="_blank" rel="noreferrer">{selectedChart.getHome()}</a>
|
<a href={selectedChart.getHome()} target="_blank" rel="noreferrer">{selectedChart.getHome()}</a>
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
<DrawerItem name={_i18n._(t`Maintainers`)} className="maintainers">
|
<DrawerItem name={`Maintainers`} className="maintainers">
|
||||||
{selectedChart.getMaintainers().map(({ name, email, url }) =>
|
{selectedChart.getMaintainers().map(({ name, email, url }) =>
|
||||||
<a key={name} href={url || `mailto:${email}`} target="_blank" rel="noreferrer">{name}</a>
|
<a key={name} href={url || `mailto:${email}`} target="_blank" rel="noreferrer">{name}</a>
|
||||||
)}
|
)}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
{selectedChart.getKeywords().length > 0 && (
|
{selectedChart.getKeywords().length > 0 && (
|
||||||
<DrawerItem name={_i18n._(t`Keywords`)} labelsOnly>
|
<DrawerItem name={`Keywords`} labelsOnly>
|
||||||
{selectedChart.getKeywords().map(key => <Badge key={key} label={key} />)}
|
{selectedChart.getKeywords().map(key => <Badge key={key} label={key} />)}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
)}
|
)}
|
||||||
@ -148,7 +146,7 @@ export class HelmChartDetails extends Component<Props> {
|
|||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { chart, hideDetails } = this.props;
|
const { chart, hideDetails } = this.props;
|
||||||
const title = chart ? <Trans>Chart: {chart.getFullName()}</Trans> : "";
|
const title = chart ? <>Chart: {chart.getFullName()}</> : "";
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Drawer
|
<Drawer
|
||||||
|
|||||||
@ -9,8 +9,6 @@ import { HelmChart } from "../../api/endpoints/helm-charts.api";
|
|||||||
import { HelmChartDetails } from "./helm-chart-details";
|
import { HelmChartDetails } from "./helm-chart-details";
|
||||||
import { navigation } from "../../navigation";
|
import { navigation } from "../../navigation";
|
||||||
import { ItemListLayout } from "../item-object-list/item-list-layout";
|
import { ItemListLayout } from "../item-object-list/item-list-layout";
|
||||||
import { t, Trans } from "@lingui/macro";
|
|
||||||
import { _i18n } from "../../i18n";
|
|
||||||
import { SearchInputUrl } from "../input";
|
import { SearchInputUrl } from "../input";
|
||||||
|
|
||||||
enum sortBy {
|
enum sortBy {
|
||||||
@ -73,15 +71,15 @@ export class HelmCharts extends Component<Props> {
|
|||||||
(items: HelmChart[]) => items.filter(item => !item.deprecated)
|
(items: HelmChart[]) => items.filter(item => !item.deprecated)
|
||||||
]}
|
]}
|
||||||
customizeHeader={() => (
|
customizeHeader={() => (
|
||||||
<SearchInputUrl placeholder={_i18n._(t`Search Helm Charts`)} />
|
<SearchInputUrl placeholder={`Search Helm Charts`} />
|
||||||
)}
|
)}
|
||||||
renderTableHeader={[
|
renderTableHeader={[
|
||||||
{ className: "icon" },
|
{ className: "icon" },
|
||||||
{ title: <Trans>Name</Trans>, className: "name", sortBy: sortBy.name },
|
{ title: "Name", className: "name", sortBy: sortBy.name },
|
||||||
{ title: <Trans>Description</Trans>, className: "description" },
|
{ title: "Description", className: "description" },
|
||||||
{ title: <Trans>Version</Trans>, className: "version" },
|
{ title: "Version", className: "version" },
|
||||||
{ title: <Trans>App Version</Trans>, className: "app-version" },
|
{ title: "App Version", className: "app-version" },
|
||||||
{ title: <Trans>Repository</Trans>, className: "repository", sortBy: sortBy.repo },
|
{ title: "Repository", className: "repository", sortBy: sortBy.repo },
|
||||||
|
|
||||||
]}
|
]}
|
||||||
renderTableContents={(chart: HelmChart) => [
|
renderTableContents={(chart: HelmChart) => [
|
||||||
|
|||||||
@ -5,7 +5,6 @@ import groupBy from "lodash/groupBy";
|
|||||||
import isEqual from "lodash/isEqual";
|
import isEqual from "lodash/isEqual";
|
||||||
import { observable, reaction } from "mobx";
|
import { observable, reaction } from "mobx";
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
import { t, Trans } from "@lingui/macro";
|
|
||||||
import kebabCase from "lodash/kebabCase";
|
import kebabCase from "lodash/kebabCase";
|
||||||
import { HelmRelease, helmReleasesApi, IReleaseDetails } from "../../api/endpoints/helm-releases.api";
|
import { HelmRelease, helmReleasesApi, IReleaseDetails } from "../../api/endpoints/helm-releases.api";
|
||||||
import { HelmReleaseMenu } from "./release-menu";
|
import { HelmReleaseMenu } from "./release-menu";
|
||||||
@ -20,7 +19,6 @@ import { Button } from "../button";
|
|||||||
import { releaseStore } from "./release.store";
|
import { releaseStore } from "./release.store";
|
||||||
import { Notifications } from "../notifications";
|
import { Notifications } from "../notifications";
|
||||||
import { createUpgradeChartTab } from "../dock/upgrade-chart.store";
|
import { createUpgradeChartTab } from "../dock/upgrade-chart.store";
|
||||||
import { _i18n } from "../../i18n";
|
|
||||||
import { themeStore } from "../../theme.store";
|
import { themeStore } from "../../theme.store";
|
||||||
import { apiManager } from "../../api/api-manager";
|
import { apiManager } from "../../api/api-manager";
|
||||||
import { SubTitle } from "../layout/sub-title";
|
import { SubTitle } from "../layout/sub-title";
|
||||||
@ -113,7 +111,7 @@ export class ReleaseDetails extends Component<Props> {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="values">
|
<div className="values">
|
||||||
<DrawerTitle title={_i18n._(t`Values`)}/>
|
<DrawerTitle title={`Values`}/>
|
||||||
<div className="flex column gaps">
|
<div className="flex column gaps">
|
||||||
<AceEditor
|
<AceEditor
|
||||||
mode="yaml"
|
mode="yaml"
|
||||||
@ -122,7 +120,7 @@ export class ReleaseDetails extends Component<Props> {
|
|||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
primary
|
primary
|
||||||
label={_i18n._(t`Save`)}
|
label={`Save`}
|
||||||
waiting={saving}
|
waiting={saving}
|
||||||
onClick={this.updateValues}
|
onClick={this.updateValues}
|
||||||
/>
|
/>
|
||||||
@ -197,40 +195,40 @@ export class ReleaseDetails extends Component<Props> {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<DrawerItem name={<Trans>Chart</Trans>} className="chart">
|
<DrawerItem name="Chart" className="chart">
|
||||||
<div className="flex gaps align-center">
|
<div className="flex gaps align-center">
|
||||||
<span>{release.getChart()}</span>
|
<span>{release.getChart()}</span>
|
||||||
<Button
|
<Button
|
||||||
primary
|
primary
|
||||||
label={_i18n._(t`Upgrade`)}
|
label={`Upgrade`}
|
||||||
className="box right upgrade"
|
className="box right upgrade"
|
||||||
onClick={this.upgradeVersion}
|
onClick={this.upgradeVersion}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
<DrawerItem name={<Trans>Updated</Trans>}>
|
<DrawerItem name="Updated">
|
||||||
{release.getUpdated()} <Trans>ago</Trans> ({release.updated})
|
{release.getUpdated()} ago ({release.updated})
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
<DrawerItem name={<Trans>Namespace</Trans>}>
|
<DrawerItem name="Namespace">
|
||||||
{release.getNs()}
|
{release.getNs()}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
<DrawerItem name={<Trans>Version</Trans>} onClick={stopPropagation}>
|
<DrawerItem name="Version" onClick={stopPropagation}>
|
||||||
<div className="version flex gaps align-center">
|
<div className="version flex gaps align-center">
|
||||||
<span>
|
<span>
|
||||||
{release.getVersion()}
|
{release.getVersion()}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
<DrawerItem name={<Trans>Status</Trans>} className="status" labelsOnly>
|
<DrawerItem name="Status" className="status" labelsOnly>
|
||||||
<Badge
|
<Badge
|
||||||
label={release.getStatus()}
|
label={release.getStatus()}
|
||||||
className={cssNames("status", kebabCase(release.getStatus()))}
|
className={cssNames("status", kebabCase(release.getStatus()))}
|
||||||
/>
|
/>
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
{this.renderValues()}
|
{this.renderValues()}
|
||||||
<DrawerTitle title={_i18n._(t`Notes`)}/>
|
<DrawerTitle title={`Notes`}/>
|
||||||
{this.renderNotes()}
|
{this.renderNotes()}
|
||||||
<DrawerTitle title={_i18n._(t`Resources`)}/>
|
<DrawerTitle title={`Resources`}/>
|
||||||
{this.renderResources()}
|
{this.renderResources()}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
@ -238,7 +236,7 @@ export class ReleaseDetails extends Component<Props> {
|
|||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { release, hideDetails } = this.props;
|
const { release, hideDetails } = this.props;
|
||||||
const title = release ? <Trans>Release: {release.getName()}</Trans> : "";
|
const title = release ? <>Release: {release.getName()}</> : "";
|
||||||
const toolbar = <HelmReleaseMenu release={release} toolbar hideDetails={hideDetails}/>;
|
const toolbar = <HelmReleaseMenu release={release} toolbar hideDetails={hideDetails}/>;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { t, Trans } from "@lingui/macro";
|
|
||||||
import { HelmRelease } from "../../api/endpoints/helm-releases.api";
|
import { HelmRelease } from "../../api/endpoints/helm-releases.api";
|
||||||
import { autobind, cssNames } from "../../utils";
|
import { autobind, cssNames } from "../../utils";
|
||||||
import { releaseStore } from "./release.store";
|
import { releaseStore } from "./release.store";
|
||||||
@ -8,7 +7,6 @@ import { MenuItem } from "../menu";
|
|||||||
import { Icon } from "../icon";
|
import { Icon } from "../icon";
|
||||||
import { ReleaseRollbackDialog } from "./release-rollback-dialog";
|
import { ReleaseRollbackDialog } from "./release-rollback-dialog";
|
||||||
import { createUpgradeChartTab } from "../dock/upgrade-chart.store";
|
import { createUpgradeChartTab } from "../dock/upgrade-chart.store";
|
||||||
import { _i18n } from "../../i18n";
|
|
||||||
|
|
||||||
interface Props extends MenuActionsProps {
|
interface Props extends MenuActionsProps {
|
||||||
release: HelmRelease;
|
release: HelmRelease;
|
||||||
@ -44,8 +42,8 @@ export class HelmReleaseMenu extends React.Component<Props> {
|
|||||||
<>
|
<>
|
||||||
{hasRollback && (
|
{hasRollback && (
|
||||||
<MenuItem onClick={this.rollback}>
|
<MenuItem onClick={this.rollback}>
|
||||||
<Icon material="history" interactive={toolbar} title={_i18n._(t`Rollback`)}/>
|
<Icon material="history" interactive={toolbar} title={`Rollback`}/>
|
||||||
<span className="title"><Trans>Rollback</Trans></span>
|
<span className="title">Rollback</span>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
|
|||||||
@ -3,7 +3,6 @@ import "./release-rollback-dialog.scss";
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { observable } from "mobx";
|
import { observable } from "mobx";
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { Trans } from "@lingui/macro";
|
|
||||||
import { Dialog, DialogProps } from "../dialog";
|
import { Dialog, DialogProps } from "../dialog";
|
||||||
import { Wizard, WizardStep } from "../wizard";
|
import { Wizard, WizardStep } from "../wizard";
|
||||||
import { HelmRelease, helmReleasesApi, IReleaseRevision } from "../../api/endpoints/helm-releases.api";
|
import { HelmRelease, helmReleasesApi, IReleaseRevision } from "../../api/endpoints/helm-releases.api";
|
||||||
@ -68,12 +67,12 @@ export class ReleaseRollbackDialog extends React.Component<Props> {
|
|||||||
const { revision, revisions } = this;
|
const { revision, revisions } = this;
|
||||||
|
|
||||||
if (!revision) {
|
if (!revision) {
|
||||||
return <p><Trans>No revisions to rollback.</Trans></p>;
|
return <p>No revisions to rollback.</p>;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex gaps align-center">
|
<div className="flex gaps align-center">
|
||||||
<b><Trans>Revision</Trans></b>
|
<b>Revision</b>
|
||||||
<Select
|
<Select
|
||||||
themeName="light"
|
themeName="light"
|
||||||
value={revision}
|
value={revision}
|
||||||
@ -88,7 +87,7 @@ export class ReleaseRollbackDialog extends React.Component<Props> {
|
|||||||
render() {
|
render() {
|
||||||
const { ...dialogProps } = this.props;
|
const { ...dialogProps } = this.props;
|
||||||
const releaseName = this.release ? this.release.getName() : "";
|
const releaseName = this.release ? this.release.getName() : "";
|
||||||
const header = <h5><Trans>Rollback <b>{releaseName}</b></Trans></h5>;
|
const header = <h5>Rollback <b>{releaseName}</b></h5>;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog
|
<Dialog
|
||||||
@ -101,7 +100,7 @@ export class ReleaseRollbackDialog extends React.Component<Props> {
|
|||||||
<Wizard header={header} done={this.close}>
|
<Wizard header={header} done={this.close}>
|
||||||
<WizardStep
|
<WizardStep
|
||||||
scrollable={false}
|
scrollable={false}
|
||||||
nextLabel={<Trans>Rollback</Trans>}
|
nextLabel="Rollback"
|
||||||
next={this.rollback}
|
next={this.rollback}
|
||||||
loading={this.isLoading}
|
loading={this.isLoading}
|
||||||
>
|
>
|
||||||
|
|||||||
@ -3,7 +3,6 @@ import "./releases.scss";
|
|||||||
import React, { Component } from "react";
|
import React, { Component } from "react";
|
||||||
import kebabCase from "lodash/kebabCase";
|
import kebabCase from "lodash/kebabCase";
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { Trans } from "@lingui/macro";
|
|
||||||
import { RouteComponentProps } from "react-router";
|
import { RouteComponentProps } from "react-router";
|
||||||
import { releaseStore } from "./release.store";
|
import { releaseStore } from "./release.store";
|
||||||
import { IReleaseRouteParams, releaseURL } from "./release.route";
|
import { IReleaseRouteParams, releaseURL } from "./release.route";
|
||||||
@ -70,9 +69,9 @@ export class HelmReleases extends Component<Props> {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Trans>Remove <b>{releaseNames}</b>?</Trans>
|
<>Remove <b>{releaseNames}</b>?</>
|
||||||
<p className="warning">
|
<p className="warning">
|
||||||
<Trans>Note: StatefulSet Volumes won't be deleted automatically</Trans>
|
Note: StatefulSet Volumes won't be deleted automatically
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
@ -100,16 +99,16 @@ export class HelmReleases extends Component<Props> {
|
|||||||
(release: HelmRelease) => release.getStatus(),
|
(release: HelmRelease) => release.getStatus(),
|
||||||
(release: HelmRelease) => release.getVersion(),
|
(release: HelmRelease) => release.getVersion(),
|
||||||
]}
|
]}
|
||||||
renderHeaderTitle={<Trans>Releases</Trans>}
|
renderHeaderTitle="Releases"
|
||||||
renderTableHeader={[
|
renderTableHeader={[
|
||||||
{ title: <Trans>Name</Trans>, className: "name", sortBy: sortBy.name },
|
{ title: "Name", className: "name", sortBy: sortBy.name },
|
||||||
{ title: <Trans>Namespace</Trans>, className: "namespace", sortBy: sortBy.namespace },
|
{ title: "Namespace", className: "namespace", sortBy: sortBy.namespace },
|
||||||
{ title: <Trans>Chart</Trans>, className: "chart", sortBy: sortBy.chart },
|
{ title: "Chart", className: "chart", sortBy: sortBy.chart },
|
||||||
{ title: <Trans>Revision</Trans>, className: "revision", sortBy: sortBy.revision },
|
{ title: "Revision", className: "revision", sortBy: sortBy.revision },
|
||||||
{ title: <Trans>Version</Trans>, className: "version" },
|
{ title: "Version", className: "version" },
|
||||||
{ title: <Trans>App Version</Trans>, className: "app-version" },
|
{ title: "App Version", className: "app-version" },
|
||||||
{ title: <Trans>Status</Trans>, className: "status", sortBy: sortBy.status },
|
{ title: "Status", className: "status", sortBy: sortBy.status },
|
||||||
{ title: <Trans>Updated</Trans>, className: "updated", sortBy: sortBy.updated },
|
{ title: "Updated", className: "updated", sortBy: sortBy.updated },
|
||||||
]}
|
]}
|
||||||
renderTableContents={(release: HelmRelease) => {
|
renderTableContents={(release: HelmRelease) => {
|
||||||
const version = release.getVersion();
|
const version = release.getVersion();
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { Trans } from "@lingui/macro";
|
|
||||||
import { TabLayout, TabLayoutRoute } from "../layout/tab-layout";
|
import { TabLayout, TabLayoutRoute } from "../layout/tab-layout";
|
||||||
import { HelmCharts, helmChartsRoute, helmChartsURL } from "../+apps-helm-charts";
|
import { HelmCharts, helmChartsRoute, helmChartsURL } from "../+apps-helm-charts";
|
||||||
import { HelmReleases, releaseRoute, releaseURL } from "../+apps-releases";
|
import { HelmReleases, releaseRoute, releaseURL } from "../+apps-releases";
|
||||||
@ -13,13 +12,13 @@ export class Apps extends React.Component {
|
|||||||
|
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
title: <Trans>Charts</Trans>,
|
title: "Charts",
|
||||||
component: HelmCharts,
|
component: HelmCharts,
|
||||||
url: helmChartsURL(),
|
url: helmChartsURL(),
|
||||||
routePath: helmChartsRoute.path.toString(),
|
routePath: helmChartsRoute.path.toString(),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: <Trans>Releases</Trans>,
|
title: "Releases",
|
||||||
component: HelmReleases,
|
component: HelmReleases,
|
||||||
url: releaseURL({ query }),
|
url: releaseURL({ query }),
|
||||||
routePath: releaseRoute.path.toString(),
|
routePath: releaseRoute.path.toString(),
|
||||||
|
|||||||
@ -4,8 +4,6 @@ import { Cluster } from "../../../../main/cluster";
|
|||||||
import { SubTitle } from "../../layout/sub-title";
|
import { SubTitle } from "../../layout/sub-title";
|
||||||
import { EditableList } from "../../editable-list";
|
import { EditableList } from "../../editable-list";
|
||||||
import { observable } from "mobx";
|
import { observable } from "mobx";
|
||||||
import { _i18n } from "../../../i18n";
|
|
||||||
import { Trans } from "@lingui/macro";
|
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
cluster: Cluster;
|
cluster: Cluster;
|
||||||
@ -19,9 +17,9 @@ export class ClusterAccessibleNamespaces extends React.Component<Props> {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<SubTitle title="Accessible Namespaces" />
|
<SubTitle title="Accessible Namespaces" />
|
||||||
<p><Trans>This setting is useful for manually specifying which namespaces you have access to. This is useful when you don't have permissions to list namespaces.</Trans></p>
|
<p>This setting is useful for manually specifying which namespaces you have access to. This is useful when you don't have permissions to list namespaces.</p>
|
||||||
<EditableList
|
<EditableList
|
||||||
placeholder={_i18n._("Add new namespace...")}
|
placeholder="Add new namespace..."
|
||||||
add={(newNamespace) => {
|
add={(newNamespace) => {
|
||||||
this.namespaces.add(newNamespace);
|
this.namespaces.add(newNamespace);
|
||||||
this.props.cluster.accessibleNamespaces = Array.from(this.namespaces);
|
this.props.cluster.accessibleNamespaces = Array.from(this.namespaces);
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { Trans } from "@lingui/macro";
|
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { clusterStore } from "../../../../common/cluster-store";
|
import { clusterStore } from "../../../../common/cluster-store";
|
||||||
import { Cluster } from "../../../../main/cluster";
|
import { Cluster } from "../../../../main/cluster";
|
||||||
@ -19,8 +18,8 @@ export class RemoveClusterButton extends React.Component<Props> {
|
|||||||
|
|
||||||
ConfirmDialog.open({
|
ConfirmDialog.open({
|
||||||
message: <p>Are you sure you want to remove <b>{cluster.preferences.clusterName}</b> from Lens?</p>,
|
message: <p>Are you sure you want to remove <b>{cluster.preferences.clusterName}</b> from Lens?</p>,
|
||||||
labelOk: <Trans>Yes</Trans>,
|
labelOk: "Yes",
|
||||||
labelCancel: <Trans>No</Trans>,
|
labelCancel: "No",
|
||||||
ok: async () => {
|
ok: async () => {
|
||||||
await clusterStore.removeById(cluster.id);
|
await clusterStore.removeById(cluster.id);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,7 +3,6 @@ import "./cluster-issues.scss";
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { computed } from "mobx";
|
import { computed } from "mobx";
|
||||||
import { Trans } from "@lingui/macro";
|
|
||||||
import { Icon } from "../icon";
|
import { Icon } from "../icon";
|
||||||
import { SubHeader } from "../layout/sub-header";
|
import { SubHeader } from "../layout/sub-header";
|
||||||
import { Table, TableCell, TableHead, TableRow } from "../table";
|
import { Table, TableCell, TableHead, TableRow } from "../table";
|
||||||
@ -114,8 +113,8 @@ export class ClusterIssues extends React.Component<Props> {
|
|||||||
return (
|
return (
|
||||||
<div className="no-issues flex column box grow gaps align-center justify-center">
|
<div className="no-issues flex column box grow gaps align-center justify-center">
|
||||||
<div><Icon material="check" big sticker/></div>
|
<div><Icon material="check" big sticker/></div>
|
||||||
<div className="ok-title"><Trans>No issues found</Trans></div>
|
<div className="ok-title">No issues found</div>
|
||||||
<span><Trans>Everything is fine in the Cluster</Trans></span>
|
<span>Everything is fine in the Cluster</span>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -124,7 +123,7 @@ export class ClusterIssues extends React.Component<Props> {
|
|||||||
<>
|
<>
|
||||||
<SubHeader>
|
<SubHeader>
|
||||||
<Icon material="error_outline"/>{" "}
|
<Icon material="error_outline"/>{" "}
|
||||||
<Trans>Warnings: {warnings.length}</Trans>
|
<>Warnings: {warnings.length}</>
|
||||||
</SubHeader>
|
</SubHeader>
|
||||||
<Table
|
<Table
|
||||||
items={warnings}
|
items={warnings}
|
||||||
@ -137,9 +136,9 @@ export class ClusterIssues extends React.Component<Props> {
|
|||||||
className={cssNames("box grow", themeStore.activeTheme.type)}
|
className={cssNames("box grow", themeStore.activeTheme.type)}
|
||||||
>
|
>
|
||||||
<TableHead nowrap>
|
<TableHead nowrap>
|
||||||
<TableCell className="message"><Trans>Message</Trans></TableCell>
|
<TableCell className="message">Message</TableCell>
|
||||||
<TableCell className="object" sortBy={sortBy.object}><Trans>Object</Trans></TableCell>
|
<TableCell className="object" sortBy={sortBy.object}>Object</TableCell>
|
||||||
<TableCell className="kind" sortBy={sortBy.type}><Trans>Type</Trans></TableCell>
|
<TableCell className="kind" sortBy={sortBy.type}>Type</TableCell>
|
||||||
</TableHead>
|
</TableHead>
|
||||||
</Table>
|
</Table>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
import "./cluster-metric-switchers.scss";
|
import "./cluster-metric-switchers.scss";
|
||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { Trans } from "@lingui/macro";
|
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { nodesStore } from "../+nodes/nodes.store";
|
import { nodesStore } from "../+nodes/nodes.store";
|
||||||
import { cssNames } from "../../utils";
|
import { cssNames } from "../../utils";
|
||||||
@ -24,8 +23,8 @@ export const ClusterMetricSwitchers = observer(() => {
|
|||||||
value={metricNodeRole}
|
value={metricNodeRole}
|
||||||
onChange={(metric: MetricNodeRole) => clusterOverviewStore.metricNodeRole = metric}
|
onChange={(metric: MetricNodeRole) => clusterOverviewStore.metricNodeRole = metric}
|
||||||
>
|
>
|
||||||
<Radio label={<Trans>Master</Trans>} value={MetricNodeRole.MASTER}/>
|
<Radio label="Master" value={MetricNodeRole.MASTER}/>
|
||||||
<Radio label={<Trans>Worker</Trans>} value={MetricNodeRole.WORKER}/>
|
<Radio label="Worker" value={MetricNodeRole.WORKER}/>
|
||||||
</RadioGroup>
|
</RadioGroup>
|
||||||
</div>
|
</div>
|
||||||
<div className="box grow metric-switch">
|
<div className="box grow metric-switch">
|
||||||
@ -35,8 +34,8 @@ export const ClusterMetricSwitchers = observer(() => {
|
|||||||
value={metricType}
|
value={metricType}
|
||||||
onChange={(value: MetricType) => clusterOverviewStore.metricType = value}
|
onChange={(value: MetricType) => clusterOverviewStore.metricType = value}
|
||||||
>
|
>
|
||||||
<Radio label={<Trans>CPU</Trans>} value={MetricType.CPU}/>
|
<Radio label="CPU" value={MetricType.CPU}/>
|
||||||
<Radio label={<Trans>Memory</Trans>} value={MetricType.MEMORY}/>
|
<Radio label="Memory" value={MetricType.MEMORY}/>
|
||||||
</RadioGroup>
|
</RadioGroup>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { Icon } from "../icon";
|
import { Icon } from "../icon";
|
||||||
import { Trans } from "@lingui/macro";
|
|
||||||
import { cssNames } from "../../utils";
|
import { cssNames } from "../../utils";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
@ -11,8 +10,8 @@ export function ClusterNoMetrics({ className }: Props) {
|
|||||||
return (
|
return (
|
||||||
<div className={cssNames("ClusterNoMetrics flex column box grow justify-center align-center", className)}>
|
<div className={cssNames("ClusterNoMetrics flex column box grow justify-center align-center", className)}>
|
||||||
<Icon material="info"/>
|
<Icon material="info"/>
|
||||||
<p><Trans>Metrics are not available due to missing or invalid Prometheus configuration.</Trans></p>
|
<p>Metrics are not available due to missing or invalid Prometheus configuration.</p>
|
||||||
<p><Trans>Right click cluster icon to open cluster settings.</Trans></p>
|
<p>Right click cluster icon to open cluster settings.</p>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,8 +2,6 @@ import "./cluster-pie-charts.scss";
|
|||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { t, Trans } from "@lingui/macro";
|
|
||||||
import { useLingui } from "@lingui/react";
|
|
||||||
import { clusterOverviewStore, MetricNodeRole } from "./cluster-overview.store";
|
import { clusterOverviewStore, MetricNodeRole } from "./cluster-overview.store";
|
||||||
import { Spinner } from "../spinner";
|
import { Spinner } from "../spinner";
|
||||||
import { Icon } from "../icon";
|
import { Icon } from "../icon";
|
||||||
@ -15,13 +13,11 @@ import { themeStore } from "../../theme.store";
|
|||||||
import { getMetricLastPoints } from "../../api/endpoints/metrics.api";
|
import { getMetricLastPoints } from "../../api/endpoints/metrics.api";
|
||||||
|
|
||||||
export const ClusterPieCharts = observer(() => {
|
export const ClusterPieCharts = observer(() => {
|
||||||
const { i18n } = useLingui();
|
|
||||||
|
|
||||||
const renderLimitWarning = () => {
|
const renderLimitWarning = () => {
|
||||||
return (
|
return (
|
||||||
<div className="node-warning flex gaps align-center">
|
<div className="node-warning flex gaps align-center">
|
||||||
<Icon material="info"/>
|
<Icon material="info"/>
|
||||||
<p><Trans>Specified limits are higher than node capacity!</Trans></p>
|
<p>Specified limits are higher than node capacity!</p>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@ -73,10 +69,10 @@ export const ClusterPieCharts = observer(() => {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
labels: [
|
labels: [
|
||||||
`${i18n._(t`Usage`)}: ${cpuUsage ? cpuUsage.toFixed(2) : "N/A"}`,
|
`Usage: ${cpuUsage ? cpuUsage.toFixed(2) : "N/A"}`,
|
||||||
`${i18n._(t`Requests`)}: ${cpuRequests ? cpuRequests.toFixed(2) : "N/A"}`,
|
`Requests: ${cpuRequests ? cpuRequests.toFixed(2) : "N/A"}`,
|
||||||
`${i18n._(t`Limits`)}: ${cpuLimits ? cpuLimits.toFixed(2) : "N/A"}`,
|
`Limits: ${cpuLimits ? cpuLimits.toFixed(2) : "N/A"}`,
|
||||||
`${i18n._(t`Capacity`)}: ${cpuCapacity || "N/A"}`
|
`Capacity: ${cpuCapacity || "N/A"}`
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
const memoryData: ChartData = {
|
const memoryData: ChartData = {
|
||||||
@ -116,10 +112,10 @@ export const ClusterPieCharts = observer(() => {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
labels: [
|
labels: [
|
||||||
`${i18n._(t`Usage`)}: ${bytesToUnits(memoryUsage)}`,
|
`Usage: ${bytesToUnits(memoryUsage)}`,
|
||||||
`${i18n._(t`Requests`)}: ${bytesToUnits(memoryRequests)}`,
|
`Requests: ${bytesToUnits(memoryRequests)}`,
|
||||||
`${i18n._(t`Limits`)}: ${bytesToUnits(memoryLimits)}`,
|
`Limits: ${bytesToUnits(memoryLimits)}`,
|
||||||
`${i18n._(t`Capacity`)}: ${bytesToUnits(memoryCapacity)}`,
|
`Capacity: ${bytesToUnits(memoryCapacity)}`,
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
const podsData: ChartData = {
|
const podsData: ChartData = {
|
||||||
@ -137,8 +133,8 @@ export const ClusterPieCharts = observer(() => {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
labels: [
|
labels: [
|
||||||
`${i18n._(t`Usage`)}: ${podUsage || 0}`,
|
`Usage: ${podUsage || 0}`,
|
||||||
`${i18n._(t`Capacity`)}: ${podCapacity}`,
|
`Capacity: ${podCapacity}`,
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -147,7 +143,7 @@ export const ClusterPieCharts = observer(() => {
|
|||||||
<div className="chart flex column align-center box grow">
|
<div className="chart flex column align-center box grow">
|
||||||
<PieChart
|
<PieChart
|
||||||
data={cpuData}
|
data={cpuData}
|
||||||
title={i18n._(t`CPU`)}
|
title={`CPU`}
|
||||||
legendColors={["#c93dce", "#4caf50", "#3d90ce", defaultColor]}
|
legendColors={["#c93dce", "#4caf50", "#3d90ce", defaultColor]}
|
||||||
/>
|
/>
|
||||||
{cpuLimitsOverload && renderLimitWarning()}
|
{cpuLimitsOverload && renderLimitWarning()}
|
||||||
@ -155,7 +151,7 @@ export const ClusterPieCharts = observer(() => {
|
|||||||
<div className="chart flex column align-center box grow">
|
<div className="chart flex column align-center box grow">
|
||||||
<PieChart
|
<PieChart
|
||||||
data={memoryData}
|
data={memoryData}
|
||||||
title={i18n._(t`Memory`)}
|
title={`Memory`}
|
||||||
legendColors={["#c93dce", "#4caf50", "#3d90ce", defaultColor]}
|
legendColors={["#c93dce", "#4caf50", "#3d90ce", defaultColor]}
|
||||||
/>
|
/>
|
||||||
{memoryLimitsOverload && renderLimitWarning()}
|
{memoryLimitsOverload && renderLimitWarning()}
|
||||||
@ -163,7 +159,7 @@ export const ClusterPieCharts = observer(() => {
|
|||||||
<div className="chart flex column align-center box grow">
|
<div className="chart flex column align-center box grow">
|
||||||
<PieChart
|
<PieChart
|
||||||
data={podsData}
|
data={podsData}
|
||||||
title={i18n._(t`Pods`)}
|
title={`Pods`}
|
||||||
legendColors={["#4caf50", defaultColor]}
|
legendColors={["#4caf50", defaultColor]}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@ -180,7 +176,7 @@ export const ClusterPieCharts = observer(() => {
|
|||||||
return (
|
return (
|
||||||
<div className="empty flex column box grow align-center justify-center">
|
<div className="empty flex column box grow align-center justify-center">
|
||||||
<Icon material="info"/>
|
<Icon material="info"/>
|
||||||
<Trans>No Nodes Available.</Trans>
|
No Nodes Available.
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,7 +9,6 @@ import { KubeObjectDetailsProps, getDetailsUrl } from "../kube-object";
|
|||||||
import { cssNames } from "../../utils";
|
import { cssNames } from "../../utils";
|
||||||
import { HorizontalPodAutoscaler, HpaMetricType, IHpaMetric } from "../../api/endpoints/hpa.api";
|
import { HorizontalPodAutoscaler, HpaMetricType, IHpaMetric } from "../../api/endpoints/hpa.api";
|
||||||
import { KubeEventDetails } from "../+events/kube-event-details";
|
import { KubeEventDetails } from "../+events/kube-event-details";
|
||||||
import { Trans } from "@lingui/macro";
|
|
||||||
import { Table, TableCell, TableHead, TableRow } from "../table";
|
import { Table, TableCell, TableHead, TableRow } from "../table";
|
||||||
import { lookupApiLink } from "../../api/kube-api";
|
import { lookupApiLink } from "../../api/kube-api";
|
||||||
import { KubeObjectMeta } from "../kube-object/kube-object-meta";
|
import { KubeObjectMeta } from "../kube-object/kube-object-meta";
|
||||||
@ -26,12 +25,12 @@ export class HpaDetails extends React.Component<Props> {
|
|||||||
const renderName = (metric: IHpaMetric) => {
|
const renderName = (metric: IHpaMetric) => {
|
||||||
switch (metric.type) {
|
switch (metric.type) {
|
||||||
case HpaMetricType.Resource:
|
case HpaMetricType.Resource:
|
||||||
const addition = metric.resource.targetAverageUtilization ? <Trans>(as a percentage of request)</Trans> : "";
|
const addition = metric.resource.targetAverageUtilization ? <>(as a percentage of request)</> : "";
|
||||||
|
|
||||||
return <Trans>Resource {metric.resource.name} on Pods {addition}</Trans>;
|
return <>Resource {metric.resource.name} on Pods {addition}</>;
|
||||||
|
|
||||||
case HpaMetricType.Pods:
|
case HpaMetricType.Pods:
|
||||||
return <Trans>{metric.pods.metricName} on Pods</Trans>;
|
return <>{metric.pods.metricName} on Pods</>;
|
||||||
|
|
||||||
case HpaMetricType.Object:
|
case HpaMetricType.Object:
|
||||||
const { target } = metric.object;
|
const { target } = metric.object;
|
||||||
@ -39,17 +38,17 @@ export class HpaDetails extends React.Component<Props> {
|
|||||||
const objectUrl = getDetailsUrl(lookupApiLink(target, hpa));
|
const objectUrl = getDetailsUrl(lookupApiLink(target, hpa));
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Trans>
|
<>
|
||||||
{metric.object.metricName} on{" "}
|
{metric.object.metricName} on{" "}
|
||||||
<Link to={objectUrl}>{kind}/{name}</Link>
|
<Link to={objectUrl}>{kind}/{name}</Link>
|
||||||
</Trans>
|
</>
|
||||||
);
|
);
|
||||||
case HpaMetricType.External:
|
case HpaMetricType.External:
|
||||||
return (
|
return (
|
||||||
<Trans>
|
<>
|
||||||
{metric.external.metricName} on{" "}
|
{metric.external.metricName} on{" "}
|
||||||
{JSON.stringify(metric.external.selector)}
|
{JSON.stringify(metric.external.selector)}
|
||||||
</Trans>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -57,8 +56,8 @@ export class HpaDetails extends React.Component<Props> {
|
|||||||
return (
|
return (
|
||||||
<Table>
|
<Table>
|
||||||
<TableHead>
|
<TableHead>
|
||||||
<TableCell className="name"><Trans>Name</Trans></TableCell>
|
<TableCell className="name">Name</TableCell>
|
||||||
<TableCell className="metrics"><Trans>Current / Target</Trans></TableCell>
|
<TableCell className="metrics">Current / Target</TableCell>
|
||||||
</TableHead>
|
</TableHead>
|
||||||
{
|
{
|
||||||
hpa.getMetrics().map((metric, index) => {
|
hpa.getMetrics().map((metric, index) => {
|
||||||
@ -87,7 +86,7 @@ export class HpaDetails extends React.Component<Props> {
|
|||||||
<div className="HpaDetails">
|
<div className="HpaDetails">
|
||||||
<KubeObjectMeta object={hpa}/>
|
<KubeObjectMeta object={hpa}/>
|
||||||
|
|
||||||
<DrawerItem name={<Trans>Reference</Trans>}>
|
<DrawerItem name="Reference">
|
||||||
{scaleTargetRef && (
|
{scaleTargetRef && (
|
||||||
<Link to={getDetailsUrl(lookupApiLink(scaleTargetRef, hpa))}>
|
<Link to={getDetailsUrl(lookupApiLink(scaleTargetRef, hpa))}>
|
||||||
{scaleTargetRef.kind}/{scaleTargetRef.name}
|
{scaleTargetRef.kind}/{scaleTargetRef.name}
|
||||||
@ -95,19 +94,19 @@ export class HpaDetails extends React.Component<Props> {
|
|||||||
)}
|
)}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
|
|
||||||
<DrawerItem name={<Trans>Min Pods</Trans>}>
|
<DrawerItem name="Min Pods">
|
||||||
{hpa.getMinPods()}
|
{hpa.getMinPods()}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
|
|
||||||
<DrawerItem name={<Trans>Max Pods</Trans>}>
|
<DrawerItem name="Max Pods">
|
||||||
{hpa.getMaxPods()}
|
{hpa.getMaxPods()}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
|
|
||||||
<DrawerItem name={<Trans>Replicas</Trans>}>
|
<DrawerItem name="Replicas">
|
||||||
{hpa.getReplicas()}
|
{hpa.getReplicas()}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
|
|
||||||
<DrawerItem name={<Trans>Status</Trans>} labelsOnly>
|
<DrawerItem name="Status" labelsOnly>
|
||||||
{hpa.getConditions().map(({ type, tooltip, isReady }) => {
|
{hpa.getConditions().map(({ type, tooltip, isReady }) => {
|
||||||
if (!isReady) return null;
|
if (!isReady) return null;
|
||||||
|
|
||||||
|
|||||||
@ -3,7 +3,6 @@ import "./hpa.scss";
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { RouteComponentProps } from "react-router";
|
import { RouteComponentProps } from "react-router";
|
||||||
import { Trans } from "@lingui/macro";
|
|
||||||
import { KubeObjectListLayout } from "../kube-object";
|
import { KubeObjectListLayout } from "../kube-object";
|
||||||
import { IHpaRouteParams } from "./hpa.route";
|
import { IHpaRouteParams } from "./hpa.route";
|
||||||
import { HorizontalPodAutoscaler } from "../../api/endpoints/hpa.api";
|
import { HorizontalPodAutoscaler } from "../../api/endpoints/hpa.api";
|
||||||
@ -29,7 +28,7 @@ export class HorizontalPodAutoscalers extends React.Component<Props> {
|
|||||||
getTargets(hpa: HorizontalPodAutoscaler) {
|
getTargets(hpa: HorizontalPodAutoscaler) {
|
||||||
const metrics = hpa.getMetrics();
|
const metrics = hpa.getMetrics();
|
||||||
const metricsRemainCount = metrics.length - 1;
|
const metricsRemainCount = metrics.length - 1;
|
||||||
const metricsRemain = metrics.length > 1 ? <Trans>{metricsRemainCount} more...</Trans> : null;
|
const metricsRemain = metrics.length > 1 ? <>{metricsRemainCount} more...</> : null;
|
||||||
const metricValues = hpa.getMetricValues(metrics[0]);
|
const metricValues = hpa.getMetricValues(metrics[0]);
|
||||||
|
|
||||||
return <p>{metricValues} {metricsRemain && "+"}{metricsRemain}</p>;
|
return <p>{metricValues} {metricsRemain && "+"}{metricsRemain}</p>;
|
||||||
@ -49,17 +48,17 @@ export class HorizontalPodAutoscalers extends React.Component<Props> {
|
|||||||
searchFilters={[
|
searchFilters={[
|
||||||
(item: HorizontalPodAutoscaler) => item.getSearchFields()
|
(item: HorizontalPodAutoscaler) => item.getSearchFields()
|
||||||
]}
|
]}
|
||||||
renderHeaderTitle={<Trans>Horizontal Pod Autoscalers</Trans>}
|
renderHeaderTitle="Horizontal Pod Autoscalers"
|
||||||
renderTableHeader={[
|
renderTableHeader={[
|
||||||
{ title: <Trans>Name</Trans>, className: "name", sortBy: sortBy.name },
|
{ title: "Name", className: "name", sortBy: sortBy.name },
|
||||||
{ className: "warning" },
|
{ className: "warning" },
|
||||||
{ title: <Trans>Namespace</Trans>, className: "namespace", sortBy: sortBy.namespace },
|
{ title: "Namespace", className: "namespace", sortBy: sortBy.namespace },
|
||||||
{ title: <Trans>Metrics</Trans>, className: "metrics" },
|
{ title: "Metrics", className: "metrics" },
|
||||||
{ title: <Trans>Min Pods</Trans>, className: "min-pods", sortBy: sortBy.minPods },
|
{ title: "Min Pods", className: "min-pods", sortBy: sortBy.minPods },
|
||||||
{ title: <Trans>Max Pods</Trans>, className: "max-pods", sortBy: sortBy.maxPods },
|
{ title: "Max Pods", className: "max-pods", sortBy: sortBy.maxPods },
|
||||||
{ title: <Trans>Replicas</Trans>, className: "replicas", sortBy: sortBy.replicas },
|
{ title: "Replicas", className: "replicas", sortBy: sortBy.replicas },
|
||||||
{ title: <Trans>Age</Trans>, className: "age", sortBy: sortBy.age },
|
{ title: "Age", className: "age", sortBy: sortBy.age },
|
||||||
{ title: <Trans>Status</Trans>, className: "status" },
|
{ title: "Status", className: "status" },
|
||||||
]}
|
]}
|
||||||
renderTableContents={(hpa: HorizontalPodAutoscaler) => [
|
renderTableContents={(hpa: HorizontalPodAutoscaler) => [
|
||||||
hpa.getName(),
|
hpa.getName(),
|
||||||
|
|||||||
@ -3,7 +3,6 @@ import "./config-map-details.scss";
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { autorun, observable } from "mobx";
|
import { autorun, observable } from "mobx";
|
||||||
import { disposeOnUnmount, observer } from "mobx-react";
|
import { disposeOnUnmount, observer } from "mobx-react";
|
||||||
import { Trans } from "@lingui/macro";
|
|
||||||
import { DrawerTitle } from "../drawer";
|
import { DrawerTitle } from "../drawer";
|
||||||
import { Notifications } from "../notifications";
|
import { Notifications } from "../notifications";
|
||||||
import { Input } from "../input";
|
import { Input } from "../input";
|
||||||
@ -43,7 +42,7 @@ export class ConfigMapDetails extends React.Component<Props> {
|
|||||||
await configMapsStore.update(configMap, { ...configMap, data: this.data.toJSON() });
|
await configMapsStore.update(configMap, { ...configMap, data: this.data.toJSON() });
|
||||||
Notifications.ok(
|
Notifications.ok(
|
||||||
<p>
|
<p>
|
||||||
<Trans>ConfigMap <b>{configMap.getName()}</b> successfully updated.</Trans>
|
<>ConfigMap <b>{configMap.getName()}</b> successfully updated.</>
|
||||||
</p>
|
</p>
|
||||||
);
|
);
|
||||||
} finally {
|
} finally {
|
||||||
@ -63,7 +62,7 @@ export class ConfigMapDetails extends React.Component<Props> {
|
|||||||
{
|
{
|
||||||
data.length > 0 && (
|
data.length > 0 && (
|
||||||
<>
|
<>
|
||||||
<DrawerTitle title={<Trans>Data</Trans>}/>
|
<DrawerTitle title="Data"/>
|
||||||
{
|
{
|
||||||
data.map(([name, value]) => {
|
data.map(([name, value]) => {
|
||||||
return (
|
return (
|
||||||
@ -84,7 +83,7 @@ export class ConfigMapDetails extends React.Component<Props> {
|
|||||||
}
|
}
|
||||||
<Button
|
<Button
|
||||||
primary
|
primary
|
||||||
label={<Trans>Save</Trans>} waiting={this.isSaving}
|
label="Save" waiting={this.isSaving}
|
||||||
className="save-btn"
|
className="save-btn"
|
||||||
onClick={this.save}
|
onClick={this.save}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@ -2,7 +2,6 @@ import "./config-maps.scss";
|
|||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { Trans } from "@lingui/macro";
|
|
||||||
import { RouteComponentProps } from "react-router";
|
import { RouteComponentProps } from "react-router";
|
||||||
import { configMapsStore } from "./config-maps.store";
|
import { configMapsStore } from "./config-maps.store";
|
||||||
import { ConfigMap } from "../../api/endpoints/configmap.api";
|
import { ConfigMap } from "../../api/endpoints/configmap.api";
|
||||||
@ -36,13 +35,13 @@ export class ConfigMaps extends React.Component<Props> {
|
|||||||
(item: ConfigMap) => item.getSearchFields(),
|
(item: ConfigMap) => item.getSearchFields(),
|
||||||
(item: ConfigMap) => item.getKeys()
|
(item: ConfigMap) => item.getKeys()
|
||||||
]}
|
]}
|
||||||
renderHeaderTitle={<Trans>Config Maps</Trans>}
|
renderHeaderTitle="Config Maps"
|
||||||
renderTableHeader={[
|
renderTableHeader={[
|
||||||
{ title: <Trans>Name</Trans>, className: "name", sortBy: sortBy.name },
|
{ title: "Name", className: "name", sortBy: sortBy.name },
|
||||||
{ className: "warning" },
|
{ className: "warning" },
|
||||||
{ title: <Trans>Namespace</Trans>, className: "namespace", sortBy: sortBy.namespace },
|
{ title: "Namespace", className: "namespace", sortBy: sortBy.namespace },
|
||||||
{ title: <Trans>Keys</Trans>, className: "keys", sortBy: sortBy.keys },
|
{ title: "Keys", className: "keys", sortBy: sortBy.keys },
|
||||||
{ title: <Trans>Age</Trans>, className: "age", sortBy: sortBy.age },
|
{ title: "Age", className: "age", sortBy: sortBy.age },
|
||||||
]}
|
]}
|
||||||
renderTableContents={(configMap: ConfigMap) => [
|
renderTableContents={(configMap: ConfigMap) => [
|
||||||
configMap.getName(),
|
configMap.getName(),
|
||||||
|
|||||||
@ -2,7 +2,6 @@ import "./pod-disruption-budgets-details.scss";
|
|||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { Trans } from "@lingui/macro";
|
|
||||||
import { DrawerItem } from "../drawer";
|
import { DrawerItem } from "../drawer";
|
||||||
import { Badge } from "../badge";
|
import { Badge } from "../badge";
|
||||||
import { KubeObjectDetailsProps } from "../kube-object";
|
import { KubeObjectDetailsProps } from "../kube-object";
|
||||||
@ -27,26 +26,26 @@ export class PodDisruptionBudgetDetails extends React.Component<Props> {
|
|||||||
<KubeObjectMeta object={pdb}/>
|
<KubeObjectMeta object={pdb}/>
|
||||||
|
|
||||||
{selectors.length > 0 &&
|
{selectors.length > 0 &&
|
||||||
<DrawerItem name={<Trans>Selector</Trans>} labelsOnly>
|
<DrawerItem name="Selector" labelsOnly>
|
||||||
{
|
{
|
||||||
selectors.map(label => <Badge key={label} label={label}/>)
|
selectors.map(label => <Badge key={label} label={label}/>)
|
||||||
}
|
}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
}
|
}
|
||||||
|
|
||||||
<DrawerItem name={<Trans>Min Available</Trans>}>
|
<DrawerItem name="Min Available">
|
||||||
{pdb.getMinAvailable()}
|
{pdb.getMinAvailable()}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
|
|
||||||
<DrawerItem name={<Trans>Max Unavailable</Trans>}>
|
<DrawerItem name="Max Unavailable">
|
||||||
{pdb.getMaxUnavailable()}
|
{pdb.getMaxUnavailable()}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
|
|
||||||
<DrawerItem name={<Trans>Current Healthy</Trans>}>
|
<DrawerItem name="Current Healthy">
|
||||||
{pdb.getCurrentHealthy()}
|
{pdb.getCurrentHealthy()}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
|
|
||||||
<DrawerItem name={<Trans>Desired Healthy</Trans>}>
|
<DrawerItem name="Desired Healthy">
|
||||||
{pdb.getDesiredHealthy()}
|
{pdb.getDesiredHealthy()}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
|
|
||||||
|
|||||||
@ -2,7 +2,6 @@ import "./pod-disruption-budgets.scss";
|
|||||||
|
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { Trans } from "@lingui/macro";
|
|
||||||
import { podDisruptionBudgetsStore } from "./pod-disruption-budgets.store";
|
import { podDisruptionBudgetsStore } from "./pod-disruption-budgets.store";
|
||||||
import { PodDisruptionBudget } from "../../api/endpoints/poddisruptionbudget.api";
|
import { PodDisruptionBudget } from "../../api/endpoints/poddisruptionbudget.api";
|
||||||
import { KubeObjectDetailsProps, KubeObjectListLayout } from "../kube-object";
|
import { KubeObjectDetailsProps, KubeObjectListLayout } from "../kube-object";
|
||||||
@ -40,16 +39,16 @@ export class PodDisruptionBudgets extends React.Component<Props> {
|
|||||||
searchFilters={[
|
searchFilters={[
|
||||||
(pdb: PodDisruptionBudget) => pdb.getSearchFields(),
|
(pdb: PodDisruptionBudget) => pdb.getSearchFields(),
|
||||||
]}
|
]}
|
||||||
renderHeaderTitle={<Trans>Pod Disruption Budgets</Trans>}
|
renderHeaderTitle="Pod Disruption Budgets"
|
||||||
renderTableHeader={[
|
renderTableHeader={[
|
||||||
{ title: <Trans>Name</Trans>, className: "name", sortBy: sortBy.name },
|
{ title: "Name", className: "name", sortBy: sortBy.name },
|
||||||
{ className: "warning" },
|
{ className: "warning" },
|
||||||
{ title: <Trans>Namespace</Trans>, className: "namespace", sortBy: sortBy.namespace },
|
{ title: "Namespace", className: "namespace", sortBy: sortBy.namespace },
|
||||||
{ title: <Trans>Min Available</Trans>, className: "min-available", sortBy: sortBy.minAvailable },
|
{ title: "Min Available", className: "min-available", sortBy: sortBy.minAvailable },
|
||||||
{ title: <Trans>Max Unavailable</Trans>, className: "max-unavailable", sortBy: sortBy.maxUnavailable },
|
{ title: "Max Unavailable", className: "max-unavailable", sortBy: sortBy.maxUnavailable },
|
||||||
{ title: <Trans>Current Healthy</Trans>, className: "current-healthy", sortBy: sortBy.currentHealthy },
|
{ title: "Current Healthy", className: "current-healthy", sortBy: sortBy.currentHealthy },
|
||||||
{ title: <Trans>Desired Healthy</Trans>, className: "desired-healthy", sortBy: sortBy.desiredHealthy },
|
{ title: "Desired Healthy", className: "desired-healthy", sortBy: sortBy.desiredHealthy },
|
||||||
{ title: <Trans>Age</Trans>, className: "age", sortBy: sortBy.age },
|
{ title: "Age", className: "age", sortBy: sortBy.age },
|
||||||
]}
|
]}
|
||||||
renderTableContents={(pdb: PodDisruptionBudget) => {
|
renderTableContents={(pdb: PodDisruptionBudget) => {
|
||||||
return [
|
return [
|
||||||
|
|||||||
@ -3,8 +3,6 @@ import "./add-quota-dialog.scss";
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { computed, observable } from "mobx";
|
import { computed, observable } from "mobx";
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { t, Trans } from "@lingui/macro";
|
|
||||||
import { _i18n } from "../../i18n";
|
|
||||||
import { Dialog, DialogProps } from "../dialog";
|
import { Dialog, DialogProps } from "../dialog";
|
||||||
import { Wizard, WizardStep } from "../wizard";
|
import { Wizard, WizardStep } from "../wizard";
|
||||||
import { Input } from "../input";
|
import { Input } from "../input";
|
||||||
@ -129,7 +127,7 @@ export class AddQuotaDialog extends React.Component<Props> {
|
|||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { ...dialogProps } = this.props;
|
const { ...dialogProps } = this.props;
|
||||||
const header = <h5><Trans>Create ResourceQuota</Trans></h5>;
|
const header = <h5>Create ResourceQuota</h5>;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog
|
<Dialog
|
||||||
@ -142,41 +140,41 @@ export class AddQuotaDialog extends React.Component<Props> {
|
|||||||
<WizardStep
|
<WizardStep
|
||||||
contentClass="flex gaps column"
|
contentClass="flex gaps column"
|
||||||
disabledNext={!this.namespace}
|
disabledNext={!this.namespace}
|
||||||
nextLabel={<Trans>Create</Trans>}
|
nextLabel="Create"
|
||||||
next={this.addQuota}
|
next={this.addQuota}
|
||||||
>
|
>
|
||||||
<div className="flex gaps">
|
<div className="flex gaps">
|
||||||
<Input
|
<Input
|
||||||
required autoFocus
|
required autoFocus
|
||||||
placeholder={_i18n._(t`ResourceQuota name`)}
|
placeholder={`ResourceQuota name`}
|
||||||
validators={systemName}
|
validators={systemName}
|
||||||
value={this.quotaName} onChange={v => this.quotaName = v.toLowerCase()}
|
value={this.quotaName} onChange={v => this.quotaName = v.toLowerCase()}
|
||||||
className="box grow"
|
className="box grow"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<SubTitle title={<Trans>Namespace</Trans>} />
|
<SubTitle title="Namespace" />
|
||||||
<NamespaceSelect
|
<NamespaceSelect
|
||||||
value={this.namespace}
|
value={this.namespace}
|
||||||
placeholder={_i18n._(t`Namespace`)}
|
placeholder={`Namespace`}
|
||||||
themeName="light"
|
themeName="light"
|
||||||
className="box grow"
|
className="box grow"
|
||||||
onChange={({ value }) => this.namespace = value}
|
onChange={({ value }) => this.namespace = value}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<SubTitle title={<Trans>Values</Trans>} />
|
<SubTitle title="Values" />
|
||||||
<div className="flex gaps align-center">
|
<div className="flex gaps align-center">
|
||||||
<Select
|
<Select
|
||||||
className="quota-select"
|
className="quota-select"
|
||||||
themeName="light"
|
themeName="light"
|
||||||
placeholder={_i18n._(t`Select a quota..`)}
|
placeholder={`Select a quota..`}
|
||||||
options={this.quotaOptions}
|
options={this.quotaOptions}
|
||||||
value={this.quotaSelectValue}
|
value={this.quotaSelectValue}
|
||||||
onChange={({ value }) => this.quotaSelectValue = value}
|
onChange={({ value }) => this.quotaSelectValue = value}
|
||||||
/>
|
/>
|
||||||
<Input
|
<Input
|
||||||
maxLength={10}
|
maxLength={10}
|
||||||
placeholder={_i18n._(t`Value`)}
|
placeholder={`Value`}
|
||||||
value={this.quotaInputValue}
|
value={this.quotaInputValue}
|
||||||
onChange={v => this.quotaInputValue = v}
|
onChange={v => this.quotaInputValue = v}
|
||||||
onKeyDown={this.onInputQuota}
|
onKeyDown={this.onInputQuota}
|
||||||
@ -185,7 +183,7 @@ export class AddQuotaDialog extends React.Component<Props> {
|
|||||||
<Button round primary onClick={this.setQuota}>
|
<Button round primary onClick={this.setQuota}>
|
||||||
<Icon
|
<Icon
|
||||||
material={this.quotas[this.quotaSelectValue] ? "edit" : "add"}
|
material={this.quotas[this.quotaSelectValue] ? "edit" : "add"}
|
||||||
tooltip={_i18n._(t`Set quota`)}
|
tooltip={`Set quota`}
|
||||||
/>
|
/>
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -2,7 +2,6 @@ import "./resource-quota-details.scss";
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import kebabCase from "lodash/kebabCase";
|
import kebabCase from "lodash/kebabCase";
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { Trans } from "@lingui/macro";
|
|
||||||
import { DrawerItem, DrawerTitle } from "../drawer";
|
import { DrawerItem, DrawerTitle } from "../drawer";
|
||||||
import { cpuUnitsToNumber, cssNames, unitsToBytes, metricUnitsToNumber } from "../../utils";
|
import { cpuUnitsToNumber, cssNames, unitsToBytes, metricUnitsToNumber } from "../../utils";
|
||||||
import { KubeObjectDetailsProps } from "../kube-object";
|
import { KubeObjectDetailsProps } from "../kube-object";
|
||||||
@ -45,7 +44,7 @@ function renderQuotas(quota: ResourceQuota): JSX.Element[] {
|
|||||||
max={max}
|
max={max}
|
||||||
value={current}
|
value={current}
|
||||||
tooltip={
|
tooltip={
|
||||||
<p><Trans>Set</Trans>: {value}. <Trans>Usage</Trans>: {`${usage}%`}</p>
|
<p>Set: {value}. Usage: {`${usage}%`}</p>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@ -64,18 +63,18 @@ export class ResourceQuotaDetails extends React.Component<Props> {
|
|||||||
<div className="ResourceQuotaDetails">
|
<div className="ResourceQuotaDetails">
|
||||||
<KubeObjectMeta object={quota}/>
|
<KubeObjectMeta object={quota}/>
|
||||||
|
|
||||||
<DrawerItem name={<Trans>Quotas</Trans>} className="quota-list">
|
<DrawerItem name="Quotas" className="quota-list">
|
||||||
{renderQuotas(quota)}
|
{renderQuotas(quota)}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
|
|
||||||
{quota.getScopeSelector().length > 0 && (
|
{quota.getScopeSelector().length > 0 && (
|
||||||
<>
|
<>
|
||||||
<DrawerTitle title={<Trans>Scope Selector</Trans>}/>
|
<DrawerTitle title="Scope Selector"/>
|
||||||
<Table className="paths">
|
<Table className="paths">
|
||||||
<TableHead>
|
<TableHead>
|
||||||
<TableCell><Trans>Operator</Trans></TableCell>
|
<TableCell>Operator</TableCell>
|
||||||
<TableCell><Trans>Scope name</Trans></TableCell>
|
<TableCell>Scope name</TableCell>
|
||||||
<TableCell><Trans>Values</Trans></TableCell>
|
<TableCell>Values</TableCell>
|
||||||
</TableHead>
|
</TableHead>
|
||||||
{
|
{
|
||||||
quota.getScopeSelector().map((selector, index) => {
|
quota.getScopeSelector().map((selector, index) => {
|
||||||
|
|||||||
@ -2,7 +2,6 @@ import "./resource-quotas.scss";
|
|||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { Trans } from "@lingui/macro";
|
|
||||||
import { RouteComponentProps } from "react-router";
|
import { RouteComponentProps } from "react-router";
|
||||||
import { KubeObjectListLayout } from "../kube-object";
|
import { KubeObjectListLayout } from "../kube-object";
|
||||||
import { ResourceQuota } from "../../api/endpoints/resource-quota.api";
|
import { ResourceQuota } from "../../api/endpoints/resource-quota.api";
|
||||||
@ -36,12 +35,12 @@ export class ResourceQuotas extends React.Component<Props> {
|
|||||||
(item: ResourceQuota) => item.getSearchFields(),
|
(item: ResourceQuota) => item.getSearchFields(),
|
||||||
(item: ResourceQuota) => item.getName(),
|
(item: ResourceQuota) => item.getName(),
|
||||||
]}
|
]}
|
||||||
renderHeaderTitle={<Trans>Resource Quotas</Trans>}
|
renderHeaderTitle="Resource Quotas"
|
||||||
renderTableHeader={[
|
renderTableHeader={[
|
||||||
{ title: <Trans>Name</Trans>, className: "name", sortBy: sortBy.name },
|
{ title: "Name", className: "name", sortBy: sortBy.name },
|
||||||
{ className: "warning" },
|
{ className: "warning" },
|
||||||
{ title: <Trans>Namespace</Trans>, className: "namespace", sortBy: sortBy.namespace },
|
{ title: "Namespace", className: "namespace", sortBy: sortBy.namespace },
|
||||||
{ title: <Trans>Age</Trans>, className: "age", sortBy: sortBy.age },
|
{ title: "Age", className: "age", sortBy: sortBy.age },
|
||||||
]}
|
]}
|
||||||
renderTableContents={(resourceQuota: ResourceQuota) => [
|
renderTableContents={(resourceQuota: ResourceQuota) => [
|
||||||
resourceQuota.getName(),
|
resourceQuota.getName(),
|
||||||
@ -51,7 +50,7 @@ export class ResourceQuotas extends React.Component<Props> {
|
|||||||
]}
|
]}
|
||||||
addRemoveButtons={{
|
addRemoveButtons={{
|
||||||
onAdd: () => AddQuotaDialog.open(),
|
onAdd: () => AddQuotaDialog.open(),
|
||||||
addTooltip: <Trans>Create new ResourceQuota</Trans>
|
addTooltip: "Create new ResourceQuota"
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<AddQuotaDialog/>
|
<AddQuotaDialog/>
|
||||||
|
|||||||
@ -3,8 +3,6 @@ import "./add-secret-dialog.scss";
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { observable } from "mobx";
|
import { observable } from "mobx";
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { t, Trans } from "@lingui/macro";
|
|
||||||
import { _i18n } from "../../i18n";
|
|
||||||
import { Dialog, DialogProps } from "../dialog";
|
import { Dialog, DialogProps } from "../dialog";
|
||||||
import { Wizard, WizardStep } from "../wizard";
|
import { Wizard, WizardStep } from "../wizard";
|
||||||
import { Input } from "../input";
|
import { Input } from "../input";
|
||||||
@ -135,7 +133,7 @@ export class AddSecretDialog extends React.Component<Props> {
|
|||||||
<SubTitle compact className="fields-title" title={upperFirst(field.toString())}>
|
<SubTitle compact className="fields-title" title={upperFirst(field.toString())}>
|
||||||
<Icon
|
<Icon
|
||||||
small
|
small
|
||||||
tooltip={_i18n._(t`Add field`)}
|
tooltip={`Add field`}
|
||||||
material="add_circle_outline"
|
material="add_circle_outline"
|
||||||
onClick={() => this.addField(field)}
|
onClick={() => this.addField(field)}
|
||||||
/>
|
/>
|
||||||
@ -148,7 +146,7 @@ export class AddSecretDialog extends React.Component<Props> {
|
|||||||
<div key={index} className="secret-field flex gaps auto align-center">
|
<div key={index} className="secret-field flex gaps auto align-center">
|
||||||
<Input
|
<Input
|
||||||
className="key"
|
className="key"
|
||||||
placeholder={_i18n._(t`Name`)}
|
placeholder={`Name`}
|
||||||
title={key}
|
title={key}
|
||||||
tabIndex={required ? -1 : 0}
|
tabIndex={required ? -1 : 0}
|
||||||
readOnly={required}
|
readOnly={required}
|
||||||
@ -158,13 +156,13 @@ export class AddSecretDialog extends React.Component<Props> {
|
|||||||
multiLine maxRows={5}
|
multiLine maxRows={5}
|
||||||
required={required}
|
required={required}
|
||||||
className="value"
|
className="value"
|
||||||
placeholder={_i18n._(t`Value`)}
|
placeholder={`Value`}
|
||||||
value={value} onChange={v => item.value = v}
|
value={value} onChange={v => item.value = v}
|
||||||
/>
|
/>
|
||||||
<Icon
|
<Icon
|
||||||
small
|
small
|
||||||
disabled={required}
|
disabled={required}
|
||||||
tooltip={required ? <Trans>Required field</Trans> : <Trans>Remove field</Trans>}
|
tooltip={required ? "Required field" : "Remove field"}
|
||||||
className="remove-icon"
|
className="remove-icon"
|
||||||
material="remove_circle_outline"
|
material="remove_circle_outline"
|
||||||
onClick={() => this.removeField(field, index)}
|
onClick={() => this.removeField(field, index)}
|
||||||
@ -180,7 +178,7 @@ export class AddSecretDialog extends React.Component<Props> {
|
|||||||
render() {
|
render() {
|
||||||
const { ...dialogProps } = this.props;
|
const { ...dialogProps } = this.props;
|
||||||
const { namespace, name, type } = this;
|
const { namespace, name, type } = this;
|
||||||
const header = <h5><Trans>Create Secret</Trans></h5>;
|
const header = <h5>Create Secret</h5>;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog
|
<Dialog
|
||||||
@ -191,19 +189,19 @@ export class AddSecretDialog extends React.Component<Props> {
|
|||||||
close={this.close}
|
close={this.close}
|
||||||
>
|
>
|
||||||
<Wizard header={header} done={this.close}>
|
<Wizard header={header} done={this.close}>
|
||||||
<WizardStep contentClass="flow column" nextLabel={<Trans>Create</Trans>} next={this.createSecret}>
|
<WizardStep contentClass="flow column" nextLabel="Create" next={this.createSecret}>
|
||||||
<div className="secret-name">
|
<div className="secret-name">
|
||||||
<SubTitle title={<Trans>Secret name</Trans>} />
|
<SubTitle title="Secret name" />
|
||||||
<Input
|
<Input
|
||||||
autoFocus required
|
autoFocus required
|
||||||
placeholder={_i18n._(t`Name`)}
|
placeholder={`Name`}
|
||||||
validators={systemName}
|
validators={systemName}
|
||||||
value={name} onChange={v => this.name = v}
|
value={name} onChange={v => this.name = v}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex auto gaps">
|
<div className="flex auto gaps">
|
||||||
<div className="secret-namespace">
|
<div className="secret-namespace">
|
||||||
<SubTitle title={<Trans>Namespace</Trans>} />
|
<SubTitle title="Namespace" />
|
||||||
<NamespaceSelect
|
<NamespaceSelect
|
||||||
themeName="light"
|
themeName="light"
|
||||||
value={namespace}
|
value={namespace}
|
||||||
@ -211,7 +209,7 @@ export class AddSecretDialog extends React.Component<Props> {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="secret-type">
|
<div className="secret-type">
|
||||||
<SubTitle title={<Trans>Secret type</Trans>} />
|
<SubTitle title="Secret type" />
|
||||||
<Select
|
<Select
|
||||||
themeName="light"
|
themeName="light"
|
||||||
options={this.types}
|
options={this.types}
|
||||||
|
|||||||
@ -4,7 +4,6 @@ import React from "react";
|
|||||||
import isEmpty from "lodash/isEmpty";
|
import isEmpty from "lodash/isEmpty";
|
||||||
import { autorun, observable } from "mobx";
|
import { autorun, observable } from "mobx";
|
||||||
import { disposeOnUnmount, observer } from "mobx-react";
|
import { disposeOnUnmount, observer } from "mobx-react";
|
||||||
import { t, Trans } from "@lingui/macro";
|
|
||||||
import { DrawerItem, DrawerTitle } from "../drawer";
|
import { DrawerItem, DrawerTitle } from "../drawer";
|
||||||
import { Input } from "../input";
|
import { Input } from "../input";
|
||||||
import { Button } from "../button";
|
import { Button } from "../button";
|
||||||
@ -14,7 +13,6 @@ import { Icon } from "../icon";
|
|||||||
import { secretsStore } from "./secrets.store";
|
import { secretsStore } from "./secrets.store";
|
||||||
import { KubeObjectDetailsProps } from "../kube-object";
|
import { KubeObjectDetailsProps } from "../kube-object";
|
||||||
import { Secret } from "../../api/endpoints";
|
import { Secret } from "../../api/endpoints";
|
||||||
import { _i18n } from "../../i18n";
|
|
||||||
import { KubeObjectMeta } from "../kube-object/kube-object-meta";
|
import { KubeObjectMeta } from "../kube-object/kube-object-meta";
|
||||||
import { kubeObjectDetailRegistry } from "../../api/kube-object-detail-registry";
|
import { kubeObjectDetailRegistry } from "../../api/kube-object-detail-registry";
|
||||||
|
|
||||||
@ -47,7 +45,7 @@ export class SecretDetails extends React.Component<Props> {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
await secretsStore.update(secret, { ...secret, data: this.data });
|
await secretsStore.update(secret, { ...secret, data: this.data });
|
||||||
Notifications.ok(<Trans>Secret successfully updated.</Trans>);
|
Notifications.ok("Secret successfully updated.");
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
Notifications.error(err);
|
Notifications.error(err);
|
||||||
}
|
}
|
||||||
@ -66,12 +64,12 @@ export class SecretDetails extends React.Component<Props> {
|
|||||||
return (
|
return (
|
||||||
<div className="SecretDetails">
|
<div className="SecretDetails">
|
||||||
<KubeObjectMeta object={secret}/>
|
<KubeObjectMeta object={secret}/>
|
||||||
<DrawerItem name={<Trans>Type</Trans>}>
|
<DrawerItem name="Type">
|
||||||
{secret.type}
|
{secret.type}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
{!isEmpty(this.data) && (
|
{!isEmpty(this.data) && (
|
||||||
<>
|
<>
|
||||||
<DrawerTitle title={_i18n._(t`Data`)}/>
|
<DrawerTitle title={`Data`}/>
|
||||||
{
|
{
|
||||||
Object.entries(this.data).map(([name, value]) => {
|
Object.entries(this.data).map(([name, value]) => {
|
||||||
const revealSecret = this.revealSecret[name];
|
const revealSecret = this.revealSecret[name];
|
||||||
@ -98,7 +96,7 @@ export class SecretDetails extends React.Component<Props> {
|
|||||||
{decodedVal && (
|
{decodedVal && (
|
||||||
<Icon
|
<Icon
|
||||||
material={`visibility${revealSecret ? "" : "_off"}`}
|
material={`visibility${revealSecret ? "" : "_off"}`}
|
||||||
tooltip={revealSecret ? <Trans>Hide</Trans> : <Trans>Show</Trans>}
|
tooltip={revealSecret ? "Hide" : "Show"}
|
||||||
onClick={() => this.revealSecret[name] = !revealSecret}
|
onClick={() => this.revealSecret[name] = !revealSecret}
|
||||||
/>)
|
/>)
|
||||||
}
|
}
|
||||||
@ -109,7 +107,7 @@ export class SecretDetails extends React.Component<Props> {
|
|||||||
}
|
}
|
||||||
<Button
|
<Button
|
||||||
primary
|
primary
|
||||||
label={_i18n._(t`Save`)} waiting={this.isSaving}
|
label={`Save`} waiting={this.isSaving}
|
||||||
className="save-btn"
|
className="save-btn"
|
||||||
onClick={this.saveSecret}
|
onClick={this.saveSecret}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@ -2,7 +2,6 @@ import "./secrets.scss";
|
|||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { Trans } from "@lingui/macro";
|
|
||||||
import { RouteComponentProps } from "react-router";
|
import { RouteComponentProps } from "react-router";
|
||||||
import { Secret } from "../../api/endpoints";
|
import { Secret } from "../../api/endpoints";
|
||||||
import { AddSecretDialog } from "./add-secret-dialog";
|
import { AddSecretDialog } from "./add-secret-dialog";
|
||||||
@ -43,15 +42,15 @@ export class Secrets extends React.Component<Props> {
|
|||||||
(item: Secret) => item.getSearchFields(),
|
(item: Secret) => item.getSearchFields(),
|
||||||
(item: Secret) => item.getKeys(),
|
(item: Secret) => item.getKeys(),
|
||||||
]}
|
]}
|
||||||
renderHeaderTitle={<Trans>Secrets</Trans>}
|
renderHeaderTitle="Secrets"
|
||||||
renderTableHeader={[
|
renderTableHeader={[
|
||||||
{ title: <Trans>Name</Trans>, className: "name", sortBy: sortBy.name },
|
{ title: "Name", className: "name", sortBy: sortBy.name },
|
||||||
{ className: "warning" },
|
{ className: "warning" },
|
||||||
{ title: <Trans>Namespace</Trans>, className: "namespace", sortBy: sortBy.namespace },
|
{ title: "Namespace", className: "namespace", sortBy: sortBy.namespace },
|
||||||
{ title: <Trans>Labels</Trans>, className: "labels", sortBy: sortBy.labels },
|
{ title: "Labels", className: "labels", sortBy: sortBy.labels },
|
||||||
{ title: <Trans>Keys</Trans>, className: "keys", sortBy: sortBy.keys },
|
{ title: "Keys", className: "keys", sortBy: sortBy.keys },
|
||||||
{ title: <Trans>Type</Trans>, className: "type", sortBy: sortBy.type },
|
{ title: "Type", className: "type", sortBy: sortBy.type },
|
||||||
{ title: <Trans>Age</Trans>, className: "age", sortBy: sortBy.age },
|
{ title: "Age", className: "age", sortBy: sortBy.age },
|
||||||
]}
|
]}
|
||||||
renderTableContents={(secret: Secret) => [
|
renderTableContents={(secret: Secret) => [
|
||||||
secret.getName(),
|
secret.getName(),
|
||||||
@ -64,7 +63,7 @@ export class Secrets extends React.Component<Props> {
|
|||||||
]}
|
]}
|
||||||
addRemoveButtons={{
|
addRemoveButtons={{
|
||||||
onAdd: () => AddSecretDialog.open(),
|
onAdd: () => AddSecretDialog.open(),
|
||||||
addTooltip: <Trans>Create new Secret</Trans>
|
addTooltip: "Create new Secret"
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<AddSecretDialog/>
|
<AddSecretDialog/>
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { Trans } from "@lingui/macro";
|
|
||||||
import { TabLayout, TabLayoutRoute } from "../layout/tab-layout";
|
import { TabLayout, TabLayoutRoute } from "../layout/tab-layout";
|
||||||
import { ConfigMaps, configMapsRoute, configMapsURL } from "../+config-maps";
|
import { ConfigMaps, configMapsRoute, configMapsURL } from "../+config-maps";
|
||||||
import { Secrets, secretsRoute, secretsURL } from "../+config-secrets";
|
import { Secrets, secretsRoute, secretsURL } from "../+config-secrets";
|
||||||
@ -18,7 +17,7 @@ export class Config extends React.Component {
|
|||||||
|
|
||||||
if (isAllowedResource("configmaps")) {
|
if (isAllowedResource("configmaps")) {
|
||||||
routes.push({
|
routes.push({
|
||||||
title: <Trans>ConfigMaps</Trans>,
|
title: "ConfigMaps",
|
||||||
component: ConfigMaps,
|
component: ConfigMaps,
|
||||||
url: configMapsURL({ query }),
|
url: configMapsURL({ query }),
|
||||||
routePath: configMapsRoute.path.toString(),
|
routePath: configMapsRoute.path.toString(),
|
||||||
@ -27,7 +26,7 @@ export class Config extends React.Component {
|
|||||||
|
|
||||||
if (isAllowedResource("secrets")) {
|
if (isAllowedResource("secrets")) {
|
||||||
routes.push({
|
routes.push({
|
||||||
title: <Trans>Secrets</Trans>,
|
title: "Secrets",
|
||||||
component: Secrets,
|
component: Secrets,
|
||||||
url: secretsURL({ query }),
|
url: secretsURL({ query }),
|
||||||
routePath: secretsRoute.path.toString(),
|
routePath: secretsRoute.path.toString(),
|
||||||
@ -36,7 +35,7 @@ export class Config extends React.Component {
|
|||||||
|
|
||||||
if (isAllowedResource("resourcequotas")) {
|
if (isAllowedResource("resourcequotas")) {
|
||||||
routes.push({
|
routes.push({
|
||||||
title: <Trans>Resource Quotas</Trans>,
|
title: "Resource Quotas",
|
||||||
component: ResourceQuotas,
|
component: ResourceQuotas,
|
||||||
url: resourceQuotaURL({ query }),
|
url: resourceQuotaURL({ query }),
|
||||||
routePath: resourceQuotaRoute.path.toString(),
|
routePath: resourceQuotaRoute.path.toString(),
|
||||||
@ -45,7 +44,7 @@ export class Config extends React.Component {
|
|||||||
|
|
||||||
if (isAllowedResource("horizontalpodautoscalers")) {
|
if (isAllowedResource("horizontalpodautoscalers")) {
|
||||||
routes.push({
|
routes.push({
|
||||||
title: <Trans>HPA</Trans>,
|
title: "HPA",
|
||||||
component: HorizontalPodAutoscalers,
|
component: HorizontalPodAutoscalers,
|
||||||
url: hpaURL({ query }),
|
url: hpaURL({ query }),
|
||||||
routePath: hpaRoute.path.toString(),
|
routePath: hpaRoute.path.toString(),
|
||||||
@ -54,7 +53,7 @@ export class Config extends React.Component {
|
|||||||
|
|
||||||
if (isAllowedResource("poddisruptionbudgets")) {
|
if (isAllowedResource("poddisruptionbudgets")) {
|
||||||
routes.push({
|
routes.push({
|
||||||
title: <Trans>Pod Disruption Budgets</Trans>,
|
title: "Pod Disruption Budgets",
|
||||||
component: PodDisruptionBudgets,
|
component: PodDisruptionBudgets,
|
||||||
url: pdbURL({ query }),
|
url: pdbURL({ query }),
|
||||||
routePath: pdbRoute.path.toString(),
|
routePath: pdbRoute.path.toString(),
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
import "./crd-details.scss";
|
import "./crd-details.scss";
|
||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { Trans } from "@lingui/macro";
|
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { CustomResourceDefinition } from "../../api/endpoints/crd.api";
|
import { CustomResourceDefinition } from "../../api/endpoints/crd.api";
|
||||||
@ -32,24 +31,24 @@ export class CRDDetails extends React.Component<Props> {
|
|||||||
<div className="CRDDetails">
|
<div className="CRDDetails">
|
||||||
<KubeObjectMeta object={crd}/>
|
<KubeObjectMeta object={crd}/>
|
||||||
|
|
||||||
<DrawerItem name={<Trans>Group</Trans>}>
|
<DrawerItem name="Group">
|
||||||
{crd.getGroup()}
|
{crd.getGroup()}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
<DrawerItem name={<Trans>Version</Trans>}>
|
<DrawerItem name="Version">
|
||||||
{crd.getVersion()}
|
{crd.getVersion()}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
<DrawerItem name={<Trans>Stored versions</Trans>}>
|
<DrawerItem name="Stored versions">
|
||||||
{crd.getStoredVersions()}
|
{crd.getStoredVersions()}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
<DrawerItem name={<Trans>Scope</Trans>}>
|
<DrawerItem name="Scope">
|
||||||
{crd.getScope()}
|
{crd.getScope()}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
<DrawerItem name={<Trans>Resource</Trans>}>
|
<DrawerItem name="Resource">
|
||||||
<Link to={crd.getResourceUrl()}>
|
<Link to={crd.getResourceUrl()}>
|
||||||
{crd.getResourceTitle()}
|
{crd.getResourceTitle()}
|
||||||
</Link>
|
</Link>
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
<DrawerItem name={<Trans>Conversion</Trans>} className="flex gaps align-flex-start">
|
<DrawerItem name="Conversion" className="flex gaps align-flex-start">
|
||||||
<Input
|
<Input
|
||||||
multiLine
|
multiLine
|
||||||
theme="round-black"
|
theme="round-black"
|
||||||
@ -58,7 +57,7 @@ export class CRDDetails extends React.Component<Props> {
|
|||||||
readOnly
|
readOnly
|
||||||
/>
|
/>
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
<DrawerItem name={<Trans>Conditions</Trans>} className="conditions" labelsOnly>
|
<DrawerItem name="Conditions" className="conditions" labelsOnly>
|
||||||
{
|
{
|
||||||
crd.getConditions().map(condition => {
|
crd.getConditions().map(condition => {
|
||||||
const { type, message, lastTransitionTime, status } = condition;
|
const { type, message, lastTransitionTime, status } = condition;
|
||||||
@ -71,7 +70,7 @@ export class CRDDetails extends React.Component<Props> {
|
|||||||
tooltip={(
|
tooltip={(
|
||||||
<>
|
<>
|
||||||
<p>{message}</p>
|
<p>{message}</p>
|
||||||
<p><Trans>Last transition time: {lastTransitionTime}</Trans></p>
|
<p>Last transition time: {lastTransitionTime}</p>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
@ -79,13 +78,13 @@ export class CRDDetails extends React.Component<Props> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
<DrawerTitle title={<Trans>Names</Trans>}/>
|
<DrawerTitle title="Names"/>
|
||||||
<Table selectable className="names box grow">
|
<Table selectable className="names box grow">
|
||||||
<TableHead>
|
<TableHead>
|
||||||
<TableCell><Trans>plural</Trans></TableCell>
|
<TableCell>plural</TableCell>
|
||||||
<TableCell><Trans>singular</Trans></TableCell>
|
<TableCell>singular</TableCell>
|
||||||
<TableCell><Trans>kind</Trans></TableCell>
|
<TableCell>kind</TableCell>
|
||||||
<TableCell><Trans>listKind</Trans></TableCell>
|
<TableCell>listKind</TableCell>
|
||||||
</TableHead>
|
</TableHead>
|
||||||
<TableRow>
|
<TableRow>
|
||||||
<TableCell>{plural}</TableCell>
|
<TableCell>{plural}</TableCell>
|
||||||
@ -96,12 +95,12 @@ export class CRDDetails extends React.Component<Props> {
|
|||||||
</Table>
|
</Table>
|
||||||
{printerColumns.length > 0 &&
|
{printerColumns.length > 0 &&
|
||||||
<>
|
<>
|
||||||
<DrawerTitle title={<Trans>Additional Printer Columns</Trans>}/>
|
<DrawerTitle title="Additional Printer Columns"/>
|
||||||
<Table selectable className="printer-columns box grow">
|
<Table selectable className="printer-columns box grow">
|
||||||
<TableHead>
|
<TableHead>
|
||||||
<TableCell className="name"><Trans>Name</Trans></TableCell>
|
<TableCell className="name">Name</TableCell>
|
||||||
<TableCell className="type"><Trans>Type</Trans></TableCell>
|
<TableCell className="type">Type</TableCell>
|
||||||
<TableCell className="json-path"><Trans>JSON Path</Trans></TableCell>
|
<TableCell className="json-path">JSON Path</TableCell>
|
||||||
</TableHead>
|
</TableHead>
|
||||||
{
|
{
|
||||||
printerColumns.map((column, index) => {
|
printerColumns.map((column, index) => {
|
||||||
@ -123,7 +122,7 @@ export class CRDDetails extends React.Component<Props> {
|
|||||||
}
|
}
|
||||||
{validation &&
|
{validation &&
|
||||||
<>
|
<>
|
||||||
<DrawerTitle title={<Trans>Validation</Trans>}/>
|
<DrawerTitle title="Validation"/>
|
||||||
<AceEditor
|
<AceEditor
|
||||||
mode="json"
|
mode="json"
|
||||||
className="validation"
|
className="validation"
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
import "./crd-list.scss";
|
import "./crd-list.scss";
|
||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { Trans } from "@lingui/macro";
|
|
||||||
import { computed } from "mobx";
|
import { computed } from "mobx";
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
@ -66,12 +65,12 @@ export class CrdList extends React.Component {
|
|||||||
return selectedGroups.length ? items.filter(item => selectedGroups.includes(item.getGroup())) : items;
|
return selectedGroups.length ? items.filter(item => selectedGroups.includes(item.getGroup())) : items;
|
||||||
}
|
}
|
||||||
]}
|
]}
|
||||||
renderHeaderTitle={<Trans>Custom Resources</Trans>}
|
renderHeaderTitle="Custom Resources"
|
||||||
customizeHeader={() => {
|
customizeHeader={() => {
|
||||||
let placeholder = <Trans>All groups</Trans>;
|
let placeholder = <>All groups</>;
|
||||||
|
|
||||||
if (selectedGroups.length == 1) placeholder = <><Trans>Group</Trans>: {selectedGroups[0]}</>;
|
if (selectedGroups.length == 1) placeholder = <>Group: {selectedGroups[0]}</>;
|
||||||
if (selectedGroups.length >= 2) placeholder = <><Trans>Groups</Trans>: {selectedGroups.join(", ")}</>;
|
if (selectedGroups.length >= 2) placeholder = <>Groups: {selectedGroups.join(", ")}</>;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
// todo: move to global filters
|
// todo: move to global filters
|
||||||
@ -98,11 +97,11 @@ export class CrdList extends React.Component {
|
|||||||
};
|
};
|
||||||
}}
|
}}
|
||||||
renderTableHeader={[
|
renderTableHeader={[
|
||||||
{ title: <Trans>Resource</Trans>, className: "kind", sortBy: sortBy.kind },
|
{ title: "Resource", className: "kind", sortBy: sortBy.kind },
|
||||||
{ title: <Trans>Group</Trans>, className: "group", sortBy: sortBy.group },
|
{ title: "Group", className: "group", sortBy: sortBy.group },
|
||||||
{ title: <Trans>Version</Trans>, className: "version", sortBy: sortBy.group },
|
{ title: "Version", className: "version", sortBy: sortBy.group },
|
||||||
{ title: <Trans>Scope</Trans>, className: "scope", sortBy: sortBy.scope },
|
{ title: "Scope", className: "scope", sortBy: sortBy.scope },
|
||||||
{ title: <Trans>Age</Trans>, className: "age", sortBy: sortBy.age },
|
{ title: "Age", className: "age", sortBy: sortBy.age },
|
||||||
]}
|
]}
|
||||||
renderTableContents={(crd: CustomResourceDefinition) => [
|
renderTableContents={(crd: CustomResourceDefinition) => [
|
||||||
<Link key="link" to={crd.getResourceUrl()} onClick={stopPropagation}>
|
<Link key="link" to={crd.getResourceUrl()} onClick={stopPropagation}>
|
||||||
|
|||||||
@ -2,7 +2,6 @@ import "./crd-resource-details.scss";
|
|||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import jsonPath from "jsonpath";
|
import jsonPath from "jsonpath";
|
||||||
import { Trans } from "@lingui/macro";
|
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { computed } from "mobx";
|
import { computed } from "mobx";
|
||||||
import { cssNames } from "../../utils";
|
import { cssNames } from "../../utils";
|
||||||
@ -71,7 +70,7 @@ export class CrdResourceDetails extends React.Component<Props> {
|
|||||||
));
|
));
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DrawerItem name={<Trans>Status</Trans>} className="status" labelsOnly>
|
<DrawerItem name="Status" className="status" labelsOnly>
|
||||||
{conditions}
|
{conditions}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -3,7 +3,6 @@ import "./crd-resources.scss";
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import jsonPath from "jsonpath";
|
import jsonPath from "jsonpath";
|
||||||
import { disposeOnUnmount, observer } from "mobx-react";
|
import { disposeOnUnmount, observer } from "mobx-react";
|
||||||
import { Trans } from "@lingui/macro";
|
|
||||||
import { RouteComponentProps } from "react-router";
|
import { RouteComponentProps } from "react-router";
|
||||||
import { KubeObjectListLayout } from "../kube-object";
|
import { KubeObjectListLayout } from "../kube-object";
|
||||||
import { KubeObject } from "../../api/kube-object";
|
import { KubeObject } from "../../api/kube-object";
|
||||||
@ -76,8 +75,8 @@ export class CrdResources extends React.Component<Props> {
|
|||||||
]}
|
]}
|
||||||
renderHeaderTitle={crd.getResourceTitle()}
|
renderHeaderTitle={crd.getResourceTitle()}
|
||||||
renderTableHeader={[
|
renderTableHeader={[
|
||||||
{ title: <Trans>Name</Trans>, className: "name", sortBy: sortBy.name },
|
{ title: "Name", className: "name", sortBy: sortBy.name },
|
||||||
isNamespaced && { title: <Trans>Namespace</Trans>, className: "namespace", sortBy: sortBy.namespace },
|
isNamespaced && { title: "Namespace", className: "namespace", sortBy: sortBy.namespace },
|
||||||
...extraColumns.map(column => {
|
...extraColumns.map(column => {
|
||||||
const { name } = column;
|
const { name } = column;
|
||||||
|
|
||||||
@ -87,7 +86,7 @@ export class CrdResources extends React.Component<Props> {
|
|||||||
sortBy: name
|
sortBy: name
|
||||||
};
|
};
|
||||||
}),
|
}),
|
||||||
{ title: <Trans>Age</Trans>, className: "age", sortBy: sortBy.age },
|
{ title: "Age", className: "age", sortBy: sortBy.age },
|
||||||
]}
|
]}
|
||||||
renderTableContents={(crdInstance: KubeObject) => [
|
renderTableContents={(crdInstance: KubeObject) => [
|
||||||
crdInstance.getName(),
|
crdInstance.getName(),
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { Redirect, Route, Switch } from "react-router";
|
import { Redirect, Route, Switch } from "react-router";
|
||||||
import { Trans } from "@lingui/macro";
|
|
||||||
import { TabLayout, TabLayoutRoute } from "../layout/tab-layout";
|
import { TabLayout, TabLayoutRoute } from "../layout/tab-layout";
|
||||||
import { crdResourcesRoute, crdRoute, crdURL, crdDefinitionsRoute } from "./crd.route";
|
import { crdResourcesRoute, crdRoute, crdURL, crdDefinitionsRoute } from "./crd.route";
|
||||||
import { CrdList } from "./crd-list";
|
import { CrdList } from "./crd-list";
|
||||||
@ -12,7 +11,7 @@ export class CustomResources extends React.Component {
|
|||||||
static get tabRoutes(): TabLayoutRoute[] {
|
static get tabRoutes(): TabLayoutRoute[] {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
title: <Trans>Definitions</Trans>,
|
title: "Definitions",
|
||||||
component: CustomResources,
|
component: CustomResources,
|
||||||
url: crdURL(),
|
url: crdURL(),
|
||||||
routePath: crdRoute.path.toString(),
|
routePath: crdRoute.path.toString(),
|
||||||
|
|||||||
@ -2,7 +2,6 @@ import "./event-details.scss";
|
|||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import kebabCase from "lodash/kebabCase";
|
import kebabCase from "lodash/kebabCase";
|
||||||
import { Trans } from "@lingui/macro";
|
|
||||||
import { DrawerItem, DrawerTitle } from "../drawer";
|
import { DrawerItem, DrawerTitle } from "../drawer";
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
@ -29,35 +28,35 @@ export class EventDetails extends React.Component<Props> {
|
|||||||
<div className="EventDetails">
|
<div className="EventDetails">
|
||||||
<KubeObjectMeta object={event}/>
|
<KubeObjectMeta object={event}/>
|
||||||
|
|
||||||
<DrawerItem name={<Trans>Message</Trans>}>
|
<DrawerItem name="Message">
|
||||||
{message}
|
{message}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
<DrawerItem name={<Trans>Reason</Trans>}>
|
<DrawerItem name="Reason">
|
||||||
{reason}
|
{reason}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
<DrawerItem name={<Trans>Source</Trans>}>
|
<DrawerItem name="Source">
|
||||||
{event.getSource()}
|
{event.getSource()}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
<DrawerItem name={<Trans>First seen</Trans>}>
|
<DrawerItem name="First seen">
|
||||||
{event.getFirstSeenTime()} <Trans>ago</Trans> {event.firstTimestamp}
|
{event.getFirstSeenTime()} ago {event.firstTimestamp}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
<DrawerItem name={<Trans>Last seen</Trans>}>
|
<DrawerItem name="Last seen">
|
||||||
{event.getLastSeenTime()} <Trans>ago</Trans> {event.lastTimestamp}
|
{event.getLastSeenTime()} ago {event.lastTimestamp}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
<DrawerItem name={<Trans>Count</Trans>}>
|
<DrawerItem name="Count">
|
||||||
{count}
|
{count}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
<DrawerItem name={<Trans>Type</Trans>} className="type">
|
<DrawerItem name="Type" className="type">
|
||||||
<span className={kebabCase(type)}>{type}</span>
|
<span className={kebabCase(type)}>{type}</span>
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
|
|
||||||
<DrawerTitle title={<Trans>Involved object</Trans>}/>
|
<DrawerTitle title="Involved object"/>
|
||||||
<Table>
|
<Table>
|
||||||
<TableHead>
|
<TableHead>
|
||||||
<TableCell><Trans>Name</Trans></TableCell>
|
<TableCell>Name</TableCell>
|
||||||
<TableCell><Trans>Namespace</Trans></TableCell>
|
<TableCell>Namespace</TableCell>
|
||||||
<TableCell><Trans>Kind</Trans></TableCell>
|
<TableCell>Kind</TableCell>
|
||||||
<TableCell><Trans>Field Path</Trans></TableCell>
|
<TableCell>Field Path</TableCell>
|
||||||
</TableHead>
|
</TableHead>
|
||||||
<TableRow>
|
<TableRow>
|
||||||
<TableCell>
|
<TableCell>
|
||||||
|
|||||||
@ -5,7 +5,6 @@ import { observer } from "mobx-react";
|
|||||||
import { TabLayout } from "../layout/tab-layout";
|
import { TabLayout } from "../layout/tab-layout";
|
||||||
import { eventStore } from "./event.store";
|
import { eventStore } from "./event.store";
|
||||||
import { KubeObjectListLayout, KubeObjectListLayoutProps, getDetailsUrl } from "../kube-object";
|
import { KubeObjectListLayout, KubeObjectListLayoutProps, getDetailsUrl } from "../kube-object";
|
||||||
import { Trans } from "@lingui/macro";
|
|
||||||
import { KubeEvent } from "../../api/endpoints/events.api";
|
import { KubeEvent } from "../../api/endpoints/events.api";
|
||||||
import { Tooltip } from "../tooltip";
|
import { Tooltip } from "../tooltip";
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
@ -56,7 +55,7 @@ export class Events extends React.Component<Props> {
|
|||||||
(event: KubeEvent) => event.getSource(),
|
(event: KubeEvent) => event.getSource(),
|
||||||
(event: KubeEvent) => event.involvedObject.name,
|
(event: KubeEvent) => event.involvedObject.name,
|
||||||
]}
|
]}
|
||||||
renderHeaderTitle={<Trans>Events</Trans>}
|
renderHeaderTitle="Events"
|
||||||
customizeHeader={({ title, info }) => (
|
customizeHeader={({ title, info }) => (
|
||||||
compact ? title : ({
|
compact ? title : ({
|
||||||
info: (
|
info: (
|
||||||
@ -66,20 +65,20 @@ export class Events extends React.Component<Props> {
|
|||||||
small
|
small
|
||||||
material="help_outline"
|
material="help_outline"
|
||||||
className="help-icon"
|
className="help-icon"
|
||||||
tooltip={<Trans>Limited to {eventStore.limit}</Trans>}
|
tooltip="Limited to {eventStore.limit}"
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
)}
|
)}
|
||||||
renderTableHeader={[
|
renderTableHeader={[
|
||||||
{ title: <Trans>Message</Trans>, className: "message" },
|
{ title: "Message", className: "message" },
|
||||||
{ title: <Trans>Namespace</Trans>, className: "namespace", sortBy: sortBy.namespace },
|
{ title: "Namespace", className: "namespace", sortBy: sortBy.namespace },
|
||||||
{ title: <Trans>Type</Trans>, className: "type", sortBy: sortBy.type },
|
{ title: "Type", className: "type", sortBy: sortBy.type },
|
||||||
{ title: <Trans>Involved Object</Trans>, className: "object", sortBy: sortBy.object },
|
{ title: "Involved Object", className: "object", sortBy: sortBy.object },
|
||||||
{ title: <Trans>Source</Trans>, className: "source" },
|
{ title: "Source", className: "source" },
|
||||||
{ title: <Trans>Count</Trans>, className: "count", sortBy: sortBy.count },
|
{ title: "Count", className: "count", sortBy: sortBy.count },
|
||||||
{ title: <Trans>Age</Trans>, className: "age", sortBy: sortBy.age },
|
{ title: "Age", className: "age", sortBy: sortBy.age },
|
||||||
]}
|
]}
|
||||||
renderTableContents={(event: KubeEvent) => {
|
renderTableContents={(event: KubeEvent) => {
|
||||||
const { involvedObject, type, message } = event;
|
const { involvedObject, type, message } = event;
|
||||||
|
|||||||
@ -2,7 +2,6 @@ import "./kube-event-details.scss";
|
|||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { Trans } from "@lingui/macro";
|
|
||||||
import { KubeObject } from "../../api/kube-object";
|
import { KubeObject } from "../../api/kube-object";
|
||||||
import { DrawerItem, DrawerTitle } from "../drawer";
|
import { DrawerItem, DrawerTitle } from "../drawer";
|
||||||
import { cssNames } from "../../utils";
|
import { cssNames } from "../../utils";
|
||||||
@ -25,7 +24,7 @@ export class KubeEventDetails extends React.Component<KubeEventDetailsProps> {
|
|||||||
if (!events.length) {
|
if (!events.length) {
|
||||||
return (
|
return (
|
||||||
<DrawerTitle className="flex gaps align-center">
|
<DrawerTitle className="flex gaps align-center">
|
||||||
<span><Trans>Events</Trans></span>
|
<span>Events</span>
|
||||||
</DrawerTitle>
|
</DrawerTitle>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -33,7 +32,7 @@ export class KubeEventDetails extends React.Component<KubeEventDetailsProps> {
|
|||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<DrawerTitle className="flex gaps align-center">
|
<DrawerTitle className="flex gaps align-center">
|
||||||
<span><Trans>Events</Trans></span>
|
<span>Events</span>
|
||||||
</DrawerTitle>
|
</DrawerTitle>
|
||||||
<div className="KubeEventDetails">
|
<div className="KubeEventDetails">
|
||||||
{events.map(evt => {
|
{events.map(evt => {
|
||||||
@ -44,16 +43,16 @@ export class KubeEventDetails extends React.Component<KubeEventDetailsProps> {
|
|||||||
<div className={cssNames("title", { warning: evt.isWarning() })}>
|
<div className={cssNames("title", { warning: evt.isWarning() })}>
|
||||||
{message}
|
{message}
|
||||||
</div>
|
</div>
|
||||||
<DrawerItem name={<Trans>Source</Trans>}>
|
<DrawerItem name="Source">
|
||||||
{evt.getSource()}
|
{evt.getSource()}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
<DrawerItem name={<Trans>Count</Trans>}>
|
<DrawerItem name="Count">
|
||||||
{count}
|
{count}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
<DrawerItem name={<Trans>Sub-object</Trans>}>
|
<DrawerItem name="Sub-object">
|
||||||
{involvedObject.fieldPath}
|
{involvedObject.fieldPath}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
<DrawerItem name={<Trans>Last seen</Trans>}>
|
<DrawerItem name="Last seen">
|
||||||
{lastTimestamp}
|
{lastTimestamp}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
import { t, Trans } from "@lingui/macro";
|
|
||||||
import { remote, shell } from "electron";
|
import { remote, shell } from "electron";
|
||||||
import fse from "fs-extra";
|
import fse from "fs-extra";
|
||||||
import { computed, observable, reaction } from "mobx";
|
import { computed, observable, reaction } from "mobx";
|
||||||
@ -12,7 +11,6 @@ import { extensionDiscovery, InstalledExtension, manifestFilename } from "../../
|
|||||||
import { extensionLoader } from "../../../extensions/extension-loader";
|
import { extensionLoader } from "../../../extensions/extension-loader";
|
||||||
import { extensionDisplayName, LensExtensionManifest, sanitizeExtensionName } from "../../../extensions/lens-extension";
|
import { extensionDisplayName, LensExtensionManifest, sanitizeExtensionName } from "../../../extensions/lens-extension";
|
||||||
import logger from "../../../main/logger";
|
import logger from "../../../main/logger";
|
||||||
import { _i18n } from "../../i18n";
|
|
||||||
import { prevDefault } from "../../utils";
|
import { prevDefault } from "../../utils";
|
||||||
import { Button } from "../button";
|
import { Button } from "../button";
|
||||||
import { ConfirmDialog } from "../confirm-dialog";
|
import { ConfirmDialog } from "../confirm-dialog";
|
||||||
@ -46,7 +44,7 @@ export class Extensions extends React.Component {
|
|||||||
private static supportedFormats = ["tar", "tgz"];
|
private static supportedFormats = ["tar", "tgz"];
|
||||||
|
|
||||||
private static installPathValidator: InputValidator = {
|
private static installPathValidator: InputValidator = {
|
||||||
message: <Trans>Invalid URL or absolute path</Trans>,
|
message: "Invalid URL or absolute path",
|
||||||
validate(value: string) {
|
validate(value: string) {
|
||||||
return InputValidators.isUrl.validate(value) || InputValidators.isPath.validate(value);
|
return InputValidators.isUrl.validate(value) || InputValidators.isPath.validate(value);
|
||||||
}
|
}
|
||||||
@ -143,8 +141,8 @@ export class Extensions extends React.Component {
|
|||||||
const { canceled, filePaths } = await dialog.showOpenDialog(BrowserWindow.getFocusedWindow(), {
|
const { canceled, filePaths } = await dialog.showOpenDialog(BrowserWindow.getFocusedWindow(), {
|
||||||
defaultPath: app.getPath("downloads"),
|
defaultPath: app.getPath("downloads"),
|
||||||
properties: ["openFile", "multiSelections"],
|
properties: ["openFile", "multiSelections"],
|
||||||
message: _i18n._(t`Select extensions to install (formats: ${Extensions.supportedFormats.join(", ")}), `),
|
message: `Select extensions to install (formats: ${Extensions.supportedFormats.join(", ")}), `,
|
||||||
buttonLabel: _i18n._(t`Use configuration`),
|
buttonLabel: `Use configuration`,
|
||||||
filters: [
|
filters: [
|
||||||
{ name: "tarball", extensions: Extensions.supportedFormats }
|
{ name: "tarball", extensions: Extensions.supportedFormats }
|
||||||
]
|
]
|
||||||
@ -398,8 +396,8 @@ export class Extensions extends React.Component {
|
|||||||
|
|
||||||
ConfirmDialog.open({
|
ConfirmDialog.open({
|
||||||
message: <p>Are you sure you want to uninstall extension <b>{displayName}</b>?</p>,
|
message: <p>Are you sure you want to uninstall extension <b>{displayName}</b>?</p>,
|
||||||
labelOk: <Trans>Yes</Trans>,
|
labelOk: "Yes",
|
||||||
labelCancel: <Trans>No</Trans>,
|
labelCancel: "No",
|
||||||
ok: () => this.uninstallExtension(extension)
|
ok: () => this.uninstallExtension(extension)
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@ -500,7 +498,7 @@ export class Extensions extends React.Component {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="install-extension flex column gaps">
|
<div className="install-extension flex column gaps">
|
||||||
<SubTitle title={<Trans>Install Extension:</Trans>}/>
|
<SubTitle title="Install Extension:"/>
|
||||||
<div className="extension-input flex box gaps align-center">
|
<div className="extension-input flex box gaps align-center">
|
||||||
<Input
|
<Input
|
||||||
className="box grow"
|
className="box grow"
|
||||||
@ -518,7 +516,7 @@ export class Extensions extends React.Component {
|
|||||||
interactive
|
interactive
|
||||||
material="folder"
|
material="folder"
|
||||||
onClick={prevDefault(this.installFromSelectFileDialog)}
|
onClick={prevDefault(this.installFromSelectFileDialog)}
|
||||||
tooltip={<Trans>Browse</Trans>}
|
tooltip="Browse"
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
@ -531,7 +529,7 @@ export class Extensions extends React.Component {
|
|||||||
onClick={this.installFromUrlOrPath}
|
onClick={this.installFromUrlOrPath}
|
||||||
/>
|
/>
|
||||||
<small className="hint">
|
<small className="hint">
|
||||||
<Trans><b>Pro-Tip</b>: you can also drag-n-drop tarball-file to this area</Trans>
|
<b>Pro-Tip</b>: you can also drag-n-drop tarball-file to this area
|
||||||
</small>
|
</small>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@ -2,7 +2,6 @@ import "./landing-page.scss";
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { observable } from "mobx";
|
import { observable } from "mobx";
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { Trans } from "@lingui/macro";
|
|
||||||
import { clusterStore } from "../../../common/cluster-store";
|
import { clusterStore } from "../../../common/cluster-store";
|
||||||
import { workspaceStore } from "../../../common/workspace-store";
|
import { workspaceStore } from "../../../common/workspace-store";
|
||||||
|
|
||||||
@ -19,21 +18,19 @@ export class LandingPage extends React.Component {
|
|||||||
<div className="LandingPage flex">
|
<div className="LandingPage flex">
|
||||||
{showStartupHint && (
|
{showStartupHint && (
|
||||||
<div className="startup-hint flex column gaps" onMouseEnter={() => this.showHint = false}>
|
<div className="startup-hint flex column gaps" onMouseEnter={() => this.showHint = false}>
|
||||||
<p><Trans>This is the quick launch menu.</Trans></p>
|
<p>This is the quick launch menu.</p>
|
||||||
<p>
|
<p>
|
||||||
<Trans>
|
|
||||||
Associate clusters and choose the ones you want to access via quick launch menu by clicking the + button.
|
Associate clusters and choose the ones you want to access via quick launch menu by clicking the + button.
|
||||||
</Trans>
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{noClustersInScope && (
|
{noClustersInScope && (
|
||||||
<div className="no-clusters flex column gaps box center">
|
<div className="no-clusters flex column gaps box center">
|
||||||
<h1>
|
<h1>
|
||||||
<Trans>Welcome!</Trans>
|
Welcome!
|
||||||
</h1>
|
</h1>
|
||||||
<p>
|
<p>
|
||||||
<Trans>Get started by associating one or more clusters to Lens.</Trans>
|
Get started by associating one or more clusters to Lens.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@ -3,8 +3,6 @@ import "./add-namespace-dialog.scss";
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { observable } from "mobx";
|
import { observable } from "mobx";
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { t, Trans } from "@lingui/macro";
|
|
||||||
import { _i18n } from "../../i18n";
|
|
||||||
import { Dialog, DialogProps } from "../dialog";
|
import { Dialog, DialogProps } from "../dialog";
|
||||||
import { Wizard, WizardStep } from "../wizard";
|
import { Wizard, WizardStep } from "../wizard";
|
||||||
import { namespaceStore } from "./namespace.store";
|
import { namespaceStore } from "./namespace.store";
|
||||||
@ -55,7 +53,7 @@ export class AddNamespaceDialog extends React.Component<Props> {
|
|||||||
render() {
|
render() {
|
||||||
const { ...dialogProps } = this.props;
|
const { ...dialogProps } = this.props;
|
||||||
const { namespace } = this;
|
const { namespace } = this;
|
||||||
const header = <h5><Trans>Create Namespace</Trans></h5>;
|
const header = <h5>Create Namespace</h5>;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog
|
<Dialog
|
||||||
@ -68,13 +66,13 @@ export class AddNamespaceDialog extends React.Component<Props> {
|
|||||||
<Wizard header={header} done={this.close}>
|
<Wizard header={header} done={this.close}>
|
||||||
<WizardStep
|
<WizardStep
|
||||||
contentClass="flex gaps column"
|
contentClass="flex gaps column"
|
||||||
nextLabel={<Trans>Create</Trans>}
|
nextLabel="Create"
|
||||||
next={this.addNamespace}
|
next={this.addNamespace}
|
||||||
>
|
>
|
||||||
<Input
|
<Input
|
||||||
required autoFocus
|
required autoFocus
|
||||||
iconLeft="layers"
|
iconLeft="layers"
|
||||||
placeholder={_i18n._(t`Namespace`)}
|
placeholder={`Namespace`}
|
||||||
validators={systemName}
|
validators={systemName}
|
||||||
value={namespace} onChange={v => this.namespace = v.toLowerCase()}
|
value={namespace} onChange={v => this.namespace = v.toLowerCase()}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@ -3,7 +3,6 @@ import "./namespace-details.scss";
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { computed } from "mobx";
|
import { computed } from "mobx";
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { Trans } from "@lingui/macro";
|
|
||||||
import { DrawerItem } from "../drawer";
|
import { DrawerItem } from "../drawer";
|
||||||
import { cssNames } from "../../utils";
|
import { cssNames } from "../../utils";
|
||||||
import { Namespace } from "../../api/endpoints";
|
import { Namespace } from "../../api/endpoints";
|
||||||
@ -39,11 +38,11 @@ export class NamespaceDetails extends React.Component<Props> {
|
|||||||
<div className="NamespaceDetails">
|
<div className="NamespaceDetails">
|
||||||
<KubeObjectMeta object={namespace}/>
|
<KubeObjectMeta object={namespace}/>
|
||||||
|
|
||||||
<DrawerItem name={<Trans>Status</Trans>}>
|
<DrawerItem name="Status">
|
||||||
<span className={cssNames("status", status.toLowerCase())}>{status}</span>
|
<span className={cssNames("status", status.toLowerCase())}>{status}</span>
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
|
|
||||||
<DrawerItem name={<Trans>Resource Quotas</Trans>} className="quotas flex align-center">
|
<DrawerItem name="Resource Quotas" className="quotas flex align-center">
|
||||||
{!this.quotas && resourceQuotaStore.isLoading && <Spinner/>}
|
{!this.quotas && resourceQuotaStore.isLoading && <Spinner/>}
|
||||||
{this.quotas.map(quota => {
|
{this.quotas.map(quota => {
|
||||||
return (
|
return (
|
||||||
|
|||||||
@ -3,12 +3,10 @@ import "./namespace-select.scss";
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { computed } from "mobx";
|
import { computed } from "mobx";
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { t, Trans } from "@lingui/macro";
|
|
||||||
import { Select, SelectOption, SelectProps } from "../select";
|
import { Select, SelectOption, SelectProps } from "../select";
|
||||||
import { cssNames, noop } from "../../utils";
|
import { cssNames, noop } from "../../utils";
|
||||||
import { Icon } from "../icon";
|
import { Icon } from "../icon";
|
||||||
import { namespaceStore } from "./namespace.store";
|
import { namespaceStore } from "./namespace.store";
|
||||||
import { _i18n } from "../../i18n";
|
|
||||||
import { FilterIcon } from "../item-object-list/filter-icon";
|
import { FilterIcon } from "../item-object-list/filter-icon";
|
||||||
import { FilterType } from "../item-object-list/page-filters.store";
|
import { FilterType } from "../item-object-list/page-filters.store";
|
||||||
|
|
||||||
@ -23,7 +21,7 @@ const defaultProps: Partial<Props> = {
|
|||||||
showIcons: true,
|
showIcons: true,
|
||||||
showClusterOption: false,
|
showClusterOption: false,
|
||||||
get clusterOptionLabel() {
|
get clusterOptionLabel() {
|
||||||
return _i18n._(t`Cluster`);
|
return `Cluster`;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -87,10 +85,10 @@ export class NamespaceSelect extends React.Component<Props> {
|
|||||||
export class NamespaceSelectFilter extends React.Component {
|
export class NamespaceSelectFilter extends React.Component {
|
||||||
render() {
|
render() {
|
||||||
const { contextNs, hasContext, toggleContext } = namespaceStore;
|
const { contextNs, hasContext, toggleContext } = namespaceStore;
|
||||||
let placeholder = <Trans>All namespaces</Trans>;
|
let placeholder = <>All namespaces</>;
|
||||||
|
|
||||||
if (contextNs.length == 1) placeholder = <Trans>Namespace: {contextNs[0]}</Trans>;
|
if (contextNs.length == 1) placeholder = <>Namespace: {contextNs[0]}</>;
|
||||||
if (contextNs.length >= 2) placeholder = <Trans>Namespaces: {contextNs.join(", ")}</Trans>;
|
if (contextNs.length >= 2) placeholder = <>Namespaces: {contextNs.join(", ")}</>;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<NamespaceSelect
|
<NamespaceSelect
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
import "./namespaces.scss";
|
import "./namespaces.scss";
|
||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { Trans } from "@lingui/macro";
|
|
||||||
import { Namespace, NamespaceStatus } from "../../api/endpoints";
|
import { Namespace, NamespaceStatus } from "../../api/endpoints";
|
||||||
import { AddNamespaceDialog } from "./add-namespace-dialog";
|
import { AddNamespaceDialog } from "./add-namespace-dialog";
|
||||||
import { TabLayout } from "../layout/tab-layout";
|
import { TabLayout } from "../layout/tab-layout";
|
||||||
@ -39,13 +38,13 @@ export class Namespaces extends React.Component<Props> {
|
|||||||
(item: Namespace) => item.getSearchFields(),
|
(item: Namespace) => item.getSearchFields(),
|
||||||
(item: Namespace) => item.getStatus()
|
(item: Namespace) => item.getStatus()
|
||||||
]}
|
]}
|
||||||
renderHeaderTitle={<Trans>Namespaces</Trans>}
|
renderHeaderTitle="Namespaces"
|
||||||
renderTableHeader={[
|
renderTableHeader={[
|
||||||
{ title: <Trans>Name</Trans>, className: "name", sortBy: sortBy.name },
|
{ title: "Name", className: "name", sortBy: sortBy.name },
|
||||||
{ className: "warning" },
|
{ className: "warning" },
|
||||||
{ title: <Trans>Labels</Trans>, className: "labels", sortBy: sortBy.labels },
|
{ title: "Labels", className: "labels", sortBy: sortBy.labels },
|
||||||
{ title: <Trans>Age</Trans>, className: "age", sortBy: sortBy.age },
|
{ title: "Age", className: "age", sortBy: sortBy.age },
|
||||||
{ title: <Trans>Status</Trans>, className: "status", sortBy: sortBy.status },
|
{ title: "Status", className: "status", sortBy: sortBy.status },
|
||||||
]}
|
]}
|
||||||
renderTableContents={(item: Namespace) => [
|
renderTableContents={(item: Namespace) => [
|
||||||
item.getName(),
|
item.getName(),
|
||||||
@ -55,7 +54,7 @@ export class Namespaces extends React.Component<Props> {
|
|||||||
{ title: item.getStatus(), className: item.getStatus().toLowerCase() },
|
{ title: item.getStatus(), className: item.getStatus().toLowerCase() },
|
||||||
]}
|
]}
|
||||||
addRemoveButtons={{
|
addRemoveButtons={{
|
||||||
addTooltip: <Trans>Add Namespace</Trans>,
|
addTooltip: "Add Namespace",
|
||||||
onAdd: () => AddNamespaceDialog.open(),
|
onAdd: () => AddNamespaceDialog.open(),
|
||||||
}}
|
}}
|
||||||
customizeTableRowProps={(item: Namespace) => ({
|
customizeTableRowProps={(item: Namespace) => ({
|
||||||
|
|||||||
@ -2,7 +2,6 @@ import "./endpoint-details.scss";
|
|||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { Trans } from "@lingui/macro";
|
|
||||||
import { DrawerTitle } from "../drawer";
|
import { DrawerTitle } from "../drawer";
|
||||||
import { KubeEventDetails } from "../+events/kube-event-details";
|
import { KubeEventDetails } from "../+events/kube-event-details";
|
||||||
import { KubeObjectDetailsProps } from "../kube-object";
|
import { KubeObjectDetailsProps } from "../kube-object";
|
||||||
@ -24,7 +23,7 @@ export class EndpointDetails extends React.Component<Props> {
|
|||||||
return (
|
return (
|
||||||
<div className="EndpointDetails">
|
<div className="EndpointDetails">
|
||||||
<KubeObjectMeta object={endpoint}/>
|
<KubeObjectMeta object={endpoint}/>
|
||||||
<DrawerTitle title={<Trans>Subsets</Trans>}/>
|
<DrawerTitle title="Subsets"/>
|
||||||
{
|
{
|
||||||
endpoint.getEndpointSubsets().map((subset) => (
|
endpoint.getEndpointSubsets().map((subset) => (
|
||||||
<EndpointSubsetList key={subset.toString()} subset={subset} endpoint={endpoint} />
|
<EndpointSubsetList key={subset.toString()} subset={subset} endpoint={endpoint} />
|
||||||
|
|||||||
@ -3,7 +3,6 @@ import "./endpoint-subset-list.scss";
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { EndpointSubset, Endpoint, EndpointAddress} from "../../api/endpoints";
|
import { EndpointSubset, Endpoint, EndpointAddress} from "../../api/endpoints";
|
||||||
import { Trans } from "@lingui/macro";
|
|
||||||
import { Table, TableCell, TableHead, TableRow } from "../table";
|
import { Table, TableCell, TableHead, TableRow } from "../table";
|
||||||
import { autobind } from "../../utils";
|
import { autobind } from "../../utils";
|
||||||
import { lookupApiLink } from "../../api/kube-api";
|
import { lookupApiLink } from "../../api/kube-api";
|
||||||
@ -37,7 +36,7 @@ export class EndpointSubsetList extends React.Component<Props> {
|
|||||||
renderAddressTable(addresses: EndpointAddress[], virtual: boolean) {
|
renderAddressTable(addresses: EndpointAddress[], virtual: boolean) {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div className="title flex gaps"><Trans>Addresses</Trans></div>
|
<div className="title flex gaps">Addresses</div>
|
||||||
<Table
|
<Table
|
||||||
items={addresses}
|
items={addresses}
|
||||||
selectable={false}
|
selectable={false}
|
||||||
@ -48,7 +47,7 @@ export class EndpointSubsetList extends React.Component<Props> {
|
|||||||
>
|
>
|
||||||
<TableHead>
|
<TableHead>
|
||||||
<TableCell className="ip">IP</TableCell>
|
<TableCell className="ip">IP</TableCell>
|
||||||
<TableCell className="name"><Trans>Hostname</Trans></TableCell>
|
<TableCell className="name">Hostname</TableCell>
|
||||||
<TableCell className="target">Target</TableCell>
|
<TableCell className="target">Target</TableCell>
|
||||||
</TableHead>
|
</TableHead>
|
||||||
{
|
{
|
||||||
@ -92,7 +91,7 @@ export class EndpointSubsetList extends React.Component<Props> {
|
|||||||
<div className="EndpointSubsetList flex column">
|
<div className="EndpointSubsetList flex column">
|
||||||
{addresses.length > 0 && (
|
{addresses.length > 0 && (
|
||||||
<div>
|
<div>
|
||||||
<div className="title flex gaps"><Trans>Addresses</Trans></div>
|
<div className="title flex gaps">Addresses</div>
|
||||||
<Table
|
<Table
|
||||||
items={addresses}
|
items={addresses}
|
||||||
selectable={false}
|
selectable={false}
|
||||||
@ -103,7 +102,7 @@ export class EndpointSubsetList extends React.Component<Props> {
|
|||||||
>
|
>
|
||||||
<TableHead>
|
<TableHead>
|
||||||
<TableCell className="ip">IP</TableCell>
|
<TableCell className="ip">IP</TableCell>
|
||||||
<TableCell className="host"><Trans>Hostname</Trans></TableCell>
|
<TableCell className="host">Hostname</TableCell>
|
||||||
<TableCell className="target">Target</TableCell>
|
<TableCell className="target">Target</TableCell>
|
||||||
</TableHead>
|
</TableHead>
|
||||||
{ !addressesVirtual && addresses.map(address => this.getAddressTableRow(address.getId())) }
|
{ !addressesVirtual && addresses.map(address => this.getAddressTableRow(address.getId())) }
|
||||||
@ -113,7 +112,7 @@ export class EndpointSubsetList extends React.Component<Props> {
|
|||||||
|
|
||||||
{notReadyAddresses.length > 0 && (
|
{notReadyAddresses.length > 0 && (
|
||||||
<div>
|
<div>
|
||||||
<div className="title flex gaps"><Trans>Not Ready Addresses</Trans></div>
|
<div className="title flex gaps">Not Ready Addresses</div>
|
||||||
<Table
|
<Table
|
||||||
items={notReadyAddresses}
|
items={notReadyAddresses}
|
||||||
selectable
|
selectable
|
||||||
@ -124,7 +123,7 @@ export class EndpointSubsetList extends React.Component<Props> {
|
|||||||
>
|
>
|
||||||
<TableHead>
|
<TableHead>
|
||||||
<TableCell className="ip">IP</TableCell>
|
<TableCell className="ip">IP</TableCell>
|
||||||
<TableCell className="host"><Trans>Hostname</Trans></TableCell>
|
<TableCell className="host">Hostname</TableCell>
|
||||||
<TableCell className="target">Target</TableCell>
|
<TableCell className="target">Target</TableCell>
|
||||||
</TableHead>
|
</TableHead>
|
||||||
{ !notReadyAddressesVirtual && notReadyAddresses.map(address => this.getNotReadyAddressTableRow(address.getId())) }
|
{ !notReadyAddressesVirtual && notReadyAddresses.map(address => this.getNotReadyAddressTableRow(address.getId())) }
|
||||||
@ -132,7 +131,7 @@ export class EndpointSubsetList extends React.Component<Props> {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<div className="title flex gaps"><Trans>Ports</Trans></div>
|
<div className="title flex gaps">Ports</div>
|
||||||
<Table
|
<Table
|
||||||
selectable={false}
|
selectable={false}
|
||||||
virtual={false}
|
virtual={false}
|
||||||
@ -140,8 +139,8 @@ export class EndpointSubsetList extends React.Component<Props> {
|
|||||||
className="box grow"
|
className="box grow"
|
||||||
>
|
>
|
||||||
<TableHead>
|
<TableHead>
|
||||||
<TableCell className="port"><Trans>Port</Trans></TableCell>
|
<TableCell className="port">Port</TableCell>
|
||||||
<TableCell className="name"><Trans>Name</Trans></TableCell>
|
<TableCell className="name">Name</TableCell>
|
||||||
<TableCell className="protocol">Protocol</TableCell>
|
<TableCell className="protocol">Protocol</TableCell>
|
||||||
</TableHead>
|
</TableHead>
|
||||||
{
|
{
|
||||||
|
|||||||
@ -7,7 +7,6 @@ import { EndpointRouteParams } from "./endpoints.route";
|
|||||||
import { Endpoint } from "../../api/endpoints/endpoint.api";
|
import { Endpoint } from "../../api/endpoints/endpoint.api";
|
||||||
import { endpointStore } from "./endpoints.store";
|
import { endpointStore } from "./endpoints.store";
|
||||||
import { KubeObjectListLayout } from "../kube-object";
|
import { KubeObjectListLayout } from "../kube-object";
|
||||||
import { Trans } from "@lingui/macro";
|
|
||||||
import { KubeObjectStatusIcon } from "../kube-object-status-icon";
|
import { KubeObjectStatusIcon } from "../kube-object-status-icon";
|
||||||
|
|
||||||
enum sortBy {
|
enum sortBy {
|
||||||
@ -33,13 +32,13 @@ export class Endpoints extends React.Component<Props> {
|
|||||||
searchFilters={[
|
searchFilters={[
|
||||||
(endpoint: Endpoint) => endpoint.getSearchFields()
|
(endpoint: Endpoint) => endpoint.getSearchFields()
|
||||||
]}
|
]}
|
||||||
renderHeaderTitle={<Trans>Endpoints</Trans>}
|
renderHeaderTitle="Endpoints"
|
||||||
renderTableHeader={[
|
renderTableHeader={[
|
||||||
{ title: <Trans>Name</Trans>, className: "name", sortBy: sortBy.name },
|
{ title: "Name", className: "name", sortBy: sortBy.name },
|
||||||
{ className: "warning" },
|
{ className: "warning" },
|
||||||
{ title: <Trans>Namespace</Trans>, className: "namespace", sortBy: sortBy.namespace },
|
{ title: "Namespace", className: "namespace", sortBy: sortBy.namespace },
|
||||||
{ title: <Trans>Endpoints</Trans>, className: "endpoints" },
|
{ title: "Endpoints", className: "endpoints" },
|
||||||
{ title: <Trans>Age</Trans>, className: "age", sortBy: sortBy.age },
|
{ title: "Age", className: "age", sortBy: sortBy.age },
|
||||||
]}
|
]}
|
||||||
renderTableContents={(endpoint: Endpoint) => [
|
renderTableContents={(endpoint: Endpoint) => [
|
||||||
endpoint.getName(),
|
endpoint.getName(),
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
import React, { useContext } from "react";
|
import React, { useContext } from "react";
|
||||||
import { t } from "@lingui/macro";
|
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { ChartOptions, ChartPoint } from "chart.js";
|
import { ChartOptions, ChartPoint } from "chart.js";
|
||||||
import { IIngressMetrics, Ingress } from "../../api/endpoints";
|
import { IIngressMetrics, Ingress } from "../../api/endpoints";
|
||||||
@ -7,7 +6,6 @@ import { BarChart, memoryOptions } from "../chart";
|
|||||||
import { normalizeMetrics, isMetricsEmpty } from "../../api/endpoints/metrics.api";
|
import { normalizeMetrics, isMetricsEmpty } from "../../api/endpoints/metrics.api";
|
||||||
import { NoMetrics } from "../resource-metrics/no-metrics";
|
import { NoMetrics } from "../resource-metrics/no-metrics";
|
||||||
import { ResourceMetricsContext, IResourceMetricsValue } from "../resource-metrics";
|
import { ResourceMetricsContext, IResourceMetricsValue } from "../resource-metrics";
|
||||||
import { _i18n } from "../../i18n";
|
|
||||||
|
|
||||||
type IContext = IResourceMetricsValue<Ingress, { metrics: IIngressMetrics }>;
|
type IContext = IResourceMetricsValue<Ingress, { metrics: IIngressMetrics }>;
|
||||||
|
|
||||||
@ -33,15 +31,15 @@ export const IngressCharts = observer(() => {
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
id: `${id}-bytesSentSuccess`,
|
id: `${id}-bytesSentSuccess`,
|
||||||
label: _i18n._(t`Bytes sent, status 2xx`),
|
label: `Bytes sent, status 2xx`,
|
||||||
tooltip: _i18n._(t`Bytes sent by Ingress controller with successful status`),
|
tooltip: `Bytes sent by Ingress controller with successful status`,
|
||||||
borderColor: "#46cd9e",
|
borderColor: "#46cd9e",
|
||||||
data: bytesSentSuccess.map(([x, y]) => ({ x, y }))
|
data: bytesSentSuccess.map(([x, y]) => ({ x, y }))
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: `${id}-bytesSentFailure`,
|
id: `${id}-bytesSentFailure`,
|
||||||
label: _i18n._(t`Bytes sent, status 5xx`),
|
label: `Bytes sent, status 5xx`,
|
||||||
tooltip: _i18n._(t`Bytes sent by Ingress controller with error status`),
|
tooltip: `Bytes sent by Ingress controller with error status`,
|
||||||
borderColor: "#cd465a",
|
borderColor: "#cd465a",
|
||||||
data: bytesSentFailure.map(([x, y]) => ({ x, y }))
|
data: bytesSentFailure.map(([x, y]) => ({ x, y }))
|
||||||
},
|
},
|
||||||
@ -50,15 +48,15 @@ export const IngressCharts = observer(() => {
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
id: `${id}-requestDurationSeconds`,
|
id: `${id}-requestDurationSeconds`,
|
||||||
label: _i18n._(t`Request`),
|
label: `Request`,
|
||||||
tooltip: _i18n._(t`Request duration in seconds`),
|
tooltip: `Request duration in seconds`,
|
||||||
borderColor: "#48b18d",
|
borderColor: "#48b18d",
|
||||||
data: requestDurationSeconds.map(([x, y]) => ({ x, y }))
|
data: requestDurationSeconds.map(([x, y]) => ({ x, y }))
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: `${id}-responseDurationSeconds`,
|
id: `${id}-responseDurationSeconds`,
|
||||||
label: _i18n._(t`Response`),
|
label: `Response`,
|
||||||
tooltip: _i18n._(t`Response duration in seconds`),
|
tooltip: `Response duration in seconds`,
|
||||||
borderColor: "#73ba3c",
|
borderColor: "#73ba3c",
|
||||||
data: responseDurationSeconds.map(([x, y]) => ({ x, y }))
|
data: responseDurationSeconds.map(([x, y]) => ({ x, y }))
|
||||||
},
|
},
|
||||||
@ -78,7 +76,7 @@ export const IngressCharts = observer(() => {
|
|||||||
label: ({ datasetIndex, index }, { datasets }) => {
|
label: ({ datasetIndex, index }, { datasets }) => {
|
||||||
const { label, data } = datasets[datasetIndex];
|
const { label, data } = datasets[datasetIndex];
|
||||||
const value = data[index] as ChartPoint;
|
const value = data[index] as ChartPoint;
|
||||||
const chartTooltipSec = _i18n._(t`sec`);
|
const chartTooltipSec = `sec`;
|
||||||
|
|
||||||
return `${label}: ${parseFloat(value.y as string).toFixed(3)} ${chartTooltipSec}`;
|
return `${label}: ${parseFloat(value.y as string).toFixed(3)} ${chartTooltipSec}`;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,7 +3,6 @@ import "./ingress-details.scss";
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { disposeOnUnmount, observer } from "mobx-react";
|
import { disposeOnUnmount, observer } from "mobx-react";
|
||||||
import { reaction } from "mobx";
|
import { reaction } from "mobx";
|
||||||
import { Trans } from "@lingui/macro";
|
|
||||||
import { DrawerItem, DrawerTitle } from "../drawer";
|
import { DrawerItem, DrawerTitle } from "../drawer";
|
||||||
import { Ingress, ILoadBalancerIngress } from "../../api/endpoints";
|
import { Ingress, ILoadBalancerIngress } from "../../api/endpoints";
|
||||||
import { Table, TableCell, TableHead, TableRow } from "../table";
|
import { Table, TableCell, TableHead, TableRow } from "../table";
|
||||||
@ -40,14 +39,14 @@ export class IngressDetails extends React.Component<Props> {
|
|||||||
<div className="rules" key={index}>
|
<div className="rules" key={index}>
|
||||||
{rule.host && (
|
{rule.host && (
|
||||||
<div className="host-title">
|
<div className="host-title">
|
||||||
<Trans>Host: {rule.host}</Trans>
|
<>Host: {rule.host}</>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{rule.http && (
|
{rule.http && (
|
||||||
<Table className="paths">
|
<Table className="paths">
|
||||||
<TableHead>
|
<TableHead>
|
||||||
<TableCell className="path"><Trans>Path</Trans></TableCell>
|
<TableCell className="path">Path</TableCell>
|
||||||
<TableCell className="backends"><Trans>Backends</Trans></TableCell>
|
<TableCell className="backends">Backends</TableCell>
|
||||||
</TableHead>
|
</TableHead>
|
||||||
{
|
{
|
||||||
rule.http.paths.map((path, index) => {
|
rule.http.paths.map((path, index) => {
|
||||||
@ -78,8 +77,8 @@ export class IngressDetails extends React.Component<Props> {
|
|||||||
<div>
|
<div>
|
||||||
<Table className="ingress-points">
|
<Table className="ingress-points">
|
||||||
<TableHead>
|
<TableHead>
|
||||||
<TableCell className="name" ><Trans>Hostname</Trans></TableCell>
|
<TableCell className="name" >Hostname</TableCell>
|
||||||
<TableCell className="ingresspoints"><Trans>IP</Trans></TableCell>
|
<TableCell className="ingresspoints">IP</TableCell>
|
||||||
</TableHead>
|
</TableHead>
|
||||||
{ingressPoints.map(({hostname, ip}, index) => {
|
{ingressPoints.map(({hostname, ip}, index) => {
|
||||||
return (
|
return (
|
||||||
@ -104,8 +103,8 @@ export class IngressDetails extends React.Component<Props> {
|
|||||||
const ingressPoints = status?.loadBalancer?.ingress;
|
const ingressPoints = status?.loadBalancer?.ingress;
|
||||||
const { metrics } = ingressStore;
|
const { metrics } = ingressStore;
|
||||||
const metricTabs = [
|
const metricTabs = [
|
||||||
<Trans key="network">Network</Trans>,
|
"Network",
|
||||||
<Trans key="network">Duration</Trans>,
|
"Duration",
|
||||||
];
|
];
|
||||||
|
|
||||||
const { serviceName, servicePort } = ingress.getServiceNamePort();
|
const { serviceName, servicePort } = ingress.getServiceNamePort();
|
||||||
@ -119,23 +118,23 @@ export class IngressDetails extends React.Component<Props> {
|
|||||||
<IngressCharts/>
|
<IngressCharts/>
|
||||||
</ResourceMetrics>
|
</ResourceMetrics>
|
||||||
<KubeObjectMeta object={ingress}/>
|
<KubeObjectMeta object={ingress}/>
|
||||||
<DrawerItem name={<Trans>Ports</Trans>}>
|
<DrawerItem name="Ports">
|
||||||
{ingress.getPorts()}
|
{ingress.getPorts()}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
{spec.tls &&
|
{spec.tls &&
|
||||||
<DrawerItem name={<Trans>TLS</Trans>}>
|
<DrawerItem name="TLS">
|
||||||
{spec.tls.map((tls, index) => <p key={index}>{tls.secretName}</p>)}
|
{spec.tls.map((tls, index) => <p key={index}>{tls.secretName}</p>)}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
}
|
}
|
||||||
{serviceName && servicePort &&
|
{serviceName && servicePort &&
|
||||||
<DrawerItem name={<Trans>Service</Trans>}>
|
<DrawerItem name="Service">
|
||||||
{serviceName}:{servicePort}
|
{serviceName}:{servicePort}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
}
|
}
|
||||||
<DrawerTitle title={<Trans>Rules</Trans>}/>
|
<DrawerTitle title="Rules"/>
|
||||||
{this.renderPaths(ingress)}
|
{this.renderPaths(ingress)}
|
||||||
|
|
||||||
<DrawerTitle title={<Trans>Load-Balancer Ingress Points</Trans>}/>
|
<DrawerTitle title="Load-Balancer Ingress Points"/>
|
||||||
{this.renderIngressPoints(ingressPoints)}
|
{this.renderIngressPoints(ingressPoints)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -7,7 +7,6 @@ import { IngressRouteParams } from "./ingresses.route";
|
|||||||
import { Ingress } from "../../api/endpoints/ingress.api";
|
import { Ingress } from "../../api/endpoints/ingress.api";
|
||||||
import { ingressStore } from "./ingress.store";
|
import { ingressStore } from "./ingress.store";
|
||||||
import { KubeObjectListLayout } from "../kube-object";
|
import { KubeObjectListLayout } from "../kube-object";
|
||||||
import { Trans } from "@lingui/macro";
|
|
||||||
import { KubeObjectStatusIcon } from "../kube-object-status-icon";
|
import { KubeObjectStatusIcon } from "../kube-object-status-icon";
|
||||||
|
|
||||||
enum sortBy {
|
enum sortBy {
|
||||||
@ -34,14 +33,14 @@ export class Ingresses extends React.Component<Props> {
|
|||||||
(ingress: Ingress) => ingress.getSearchFields(),
|
(ingress: Ingress) => ingress.getSearchFields(),
|
||||||
(ingress: Ingress) => ingress.getPorts(),
|
(ingress: Ingress) => ingress.getPorts(),
|
||||||
]}
|
]}
|
||||||
renderHeaderTitle={<Trans>Ingresses</Trans>}
|
renderHeaderTitle="Ingresses"
|
||||||
renderTableHeader={[
|
renderTableHeader={[
|
||||||
{ title: <Trans>Name</Trans>, className: "name", sortBy: sortBy.name },
|
{ title: "Name", className: "name", sortBy: sortBy.name },
|
||||||
{ className: "warning" },
|
{ className: "warning" },
|
||||||
{ title: <Trans>Namespace</Trans>, className: "namespace", sortBy: sortBy.namespace },
|
{ title: "Namespace", className: "namespace", sortBy: sortBy.namespace },
|
||||||
{ title: <Trans>LoadBalancers</Trans>, className: "loadbalancers" },
|
{ title: "LoadBalancers", className: "loadbalancers" },
|
||||||
{ title: <Trans>Rules</Trans>, className: "rules" },
|
{ title: "Rules", className: "rules" },
|
||||||
{ title: <Trans>Age</Trans>, className: "age", sortBy: sortBy.age },
|
{ title: "Age", className: "age", sortBy: sortBy.age },
|
||||||
]}
|
]}
|
||||||
renderTableContents={(ingress: Ingress) => [
|
renderTableContents={(ingress: Ingress) => [
|
||||||
ingress.getName(),
|
ingress.getName(),
|
||||||
|
|||||||
@ -2,7 +2,6 @@ import "./network-policies.scss";
|
|||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { Trans } from "@lingui/macro";
|
|
||||||
import { RouteComponentProps } from "react-router-dom";
|
import { RouteComponentProps } from "react-router-dom";
|
||||||
import { NetworkPolicy } from "../../api/endpoints/network-policy.api";
|
import { NetworkPolicy } from "../../api/endpoints/network-policy.api";
|
||||||
import { KubeObjectListLayout } from "../kube-object";
|
import { KubeObjectListLayout } from "../kube-object";
|
||||||
@ -33,13 +32,13 @@ export class NetworkPolicies extends React.Component<Props> {
|
|||||||
searchFilters={[
|
searchFilters={[
|
||||||
(item: NetworkPolicy) => item.getSearchFields(),
|
(item: NetworkPolicy) => item.getSearchFields(),
|
||||||
]}
|
]}
|
||||||
renderHeaderTitle={<Trans>Network Policies</Trans>}
|
renderHeaderTitle="Network Policies"
|
||||||
renderTableHeader={[
|
renderTableHeader={[
|
||||||
{ title: <Trans>Name</Trans>, className: "name", sortBy: sortBy.name },
|
{ title: "Name", className: "name", sortBy: sortBy.name },
|
||||||
{ className: "warning" },
|
{ className: "warning" },
|
||||||
{ title: <Trans>Namespace</Trans>, className: "namespace", sortBy: sortBy.namespace },
|
{ title: "Namespace", className: "namespace", sortBy: sortBy.namespace },
|
||||||
{ title: <Trans>Policy Types</Trans>, className: "type" },
|
{ title: "Policy Types", className: "type" },
|
||||||
{ title: <Trans>Age</Trans>, className: "age", sortBy: sortBy.age },
|
{ title: "Age", className: "age", sortBy: sortBy.age },
|
||||||
]}
|
]}
|
||||||
renderTableContents={(item: NetworkPolicy) => [
|
renderTableContents={(item: NetworkPolicy) => [
|
||||||
item.getName(),
|
item.getName(),
|
||||||
|
|||||||
@ -2,7 +2,6 @@ import "./network-policy-details.scss";
|
|||||||
|
|
||||||
import get from "lodash/get";
|
import get from "lodash/get";
|
||||||
import React, { Fragment } from "react";
|
import React, { Fragment } from "react";
|
||||||
import { t, Trans } from "@lingui/macro";
|
|
||||||
import { DrawerItem, DrawerTitle } from "../drawer";
|
import { DrawerItem, DrawerTitle } from "../drawer";
|
||||||
import { IPolicyEgress, IPolicyIngress, IPolicyIpBlock, IPolicySelector, NetworkPolicy } from "../../api/endpoints/network-policy.api";
|
import { IPolicyEgress, IPolicyIngress, IPolicyIpBlock, IPolicySelector, NetworkPolicy } from "../../api/endpoints/network-policy.api";
|
||||||
import { Badge } from "../badge";
|
import { Badge } from "../badge";
|
||||||
@ -10,7 +9,6 @@ import { SubTitle } from "../layout/sub-title";
|
|||||||
import { KubeEventDetails } from "../+events/kube-event-details";
|
import { KubeEventDetails } from "../+events/kube-event-details";
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { KubeObjectDetailsProps } from "../kube-object";
|
import { KubeObjectDetailsProps } from "../kube-object";
|
||||||
import { _i18n } from "../../i18n";
|
|
||||||
import { KubeObjectMeta } from "../kube-object/kube-object-meta";
|
import { KubeObjectMeta } from "../kube-object/kube-object-meta";
|
||||||
import { kubeObjectDetailRegistry } from "../../api/kube-object-detail-registry";
|
import { kubeObjectDetailRegistry } from "../../api/kube-object-detail-registry";
|
||||||
|
|
||||||
@ -26,7 +24,7 @@ export class NetworkPolicyDetails extends React.Component<Props> {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<SubTitle title={<Trans>From</Trans>}/>
|
<SubTitle title="From"/>
|
||||||
{from.map(item =>
|
{from.map(item =>
|
||||||
Object.keys(item).map(key => {
|
Object.keys(item).map(key => {
|
||||||
const data = get(item, key);
|
const data = get(item, key);
|
||||||
@ -75,7 +73,7 @@ export class NetworkPolicyDetails extends React.Component<Props> {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<SubTitle title={<Trans>To</Trans>}/>
|
<SubTitle title="To"/>
|
||||||
{to.map(item => {
|
{to.map(item => {
|
||||||
const { ipBlock } = item;
|
const { ipBlock } = item;
|
||||||
|
|
||||||
@ -110,22 +108,22 @@ export class NetworkPolicyDetails extends React.Component<Props> {
|
|||||||
<div className="NetworkPolicyDetails">
|
<div className="NetworkPolicyDetails">
|
||||||
<KubeObjectMeta object={policy}/>
|
<KubeObjectMeta object={policy}/>
|
||||||
|
|
||||||
<DrawerItem name={<Trans>Pod Selector</Trans>} labelsOnly={selector.length > 0}>
|
<DrawerItem name="Pod Selector" labelsOnly={selector.length > 0}>
|
||||||
{selector.length > 0 ?
|
{selector.length > 0 ?
|
||||||
policy.getMatchLabels().map(label => <Badge key={label} label={label}/>) :
|
policy.getMatchLabels().map(label => <Badge key={label} label={label}/>) :
|
||||||
_i18n._(t`(empty) (Allowing the specific traffic to all pods in this namespace)`)
|
`(empty) (Allowing the specific traffic to all pods in this namespace)`
|
||||||
}
|
}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
|
|
||||||
{ingress && (
|
{ingress && (
|
||||||
<>
|
<>
|
||||||
<DrawerTitle title={_i18n._(t`Ingress`)}/>
|
<DrawerTitle title={`Ingress`}/>
|
||||||
{ingress.map((ingress, i) => {
|
{ingress.map((ingress, i) => {
|
||||||
const { ports } = ingress;
|
const { ports } = ingress;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Fragment key={i}>
|
<Fragment key={i}>
|
||||||
<DrawerItem name={<Trans>Ports</Trans>}>
|
<DrawerItem name="Ports">
|
||||||
{ports && ports.map(({ port, protocol }) => `${protocol || ""}:${port || ""}`).join(", ")}
|
{ports && ports.map(({ port, protocol }) => `${protocol || ""}:${port || ""}`).join(", ")}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
{this.renderIngressFrom(ingress)}
|
{this.renderIngressFrom(ingress)}
|
||||||
@ -137,13 +135,13 @@ export class NetworkPolicyDetails extends React.Component<Props> {
|
|||||||
|
|
||||||
{egress && (
|
{egress && (
|
||||||
<>
|
<>
|
||||||
<DrawerTitle title={<Trans>Egress</Trans>}/>
|
<DrawerTitle title="Egress"/>
|
||||||
{egress.map((egress, i) => {
|
{egress.map((egress, i) => {
|
||||||
const { ports } = egress;
|
const { ports } = egress;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Fragment key={i}>
|
<Fragment key={i}>
|
||||||
<DrawerItem name={<Trans>Ports</Trans>}>
|
<DrawerItem name="Ports">
|
||||||
{ports && ports.map(({ port, protocol }) => `${protocol || ""}:${port || ""}`).join(", ")}
|
{ports && ports.map(({ port, protocol }) => `${protocol || ""}:${port || ""}`).join(", ")}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
{this.renderEgressTo(egress)}
|
{this.renderEgressTo(egress)}
|
||||||
|
|||||||
@ -3,7 +3,6 @@ import { observer } from "mobx-react";
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { Table, TableHead, TableCell, TableRow } from "../table";
|
import { Table, TableHead, TableCell, TableRow } from "../table";
|
||||||
import { prevDefault } from "../../utils";
|
import { prevDefault } from "../../utils";
|
||||||
import { Trans } from "@lingui/macro";
|
|
||||||
import { endpointStore } from "../+network-endpoints/endpoints.store";
|
import { endpointStore } from "../+network-endpoints/endpoints.store";
|
||||||
import { Spinner } from "../spinner";
|
import { Spinner } from "../spinner";
|
||||||
import { showDetails } from "../kube-object";
|
import { showDetails } from "../kube-object";
|
||||||
@ -34,8 +33,8 @@ export class ServiceDetailsEndpoint extends React.Component<Props> {
|
|||||||
className="box grow"
|
className="box grow"
|
||||||
>
|
>
|
||||||
<TableHead>
|
<TableHead>
|
||||||
<TableCell className="name" ><Trans>Name</Trans></TableCell>
|
<TableCell className="name" >Name</TableCell>
|
||||||
<TableCell className="endpoints"><Trans>Endpoints</Trans></TableCell>
|
<TableCell className="endpoints">Endpoints</TableCell>
|
||||||
</TableHead>
|
</TableHead>
|
||||||
<TableRow
|
<TableRow
|
||||||
key={endpoint.getId()}
|
key={endpoint.getId()}
|
||||||
|
|||||||
@ -2,13 +2,11 @@ import "./service-details.scss";
|
|||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { t, Trans } from "@lingui/macro";
|
|
||||||
import { DrawerItem, DrawerTitle } from "../drawer";
|
import { DrawerItem, DrawerTitle } from "../drawer";
|
||||||
import { Badge } from "../badge";
|
import { Badge } from "../badge";
|
||||||
import { KubeEventDetails } from "../+events/kube-event-details";
|
import { KubeEventDetails } from "../+events/kube-event-details";
|
||||||
import { KubeObjectDetailsProps } from "../kube-object";
|
import { KubeObjectDetailsProps } from "../kube-object";
|
||||||
import { Service, endpointApi } from "../../api/endpoints";
|
import { Service, endpointApi } from "../../api/endpoints";
|
||||||
import { _i18n } from "../../i18n";
|
|
||||||
import { KubeObjectMeta } from "../kube-object/kube-object-meta";
|
import { KubeObjectMeta } from "../kube-object/kube-object-meta";
|
||||||
import { ServicePortComponent } from "./service-port-component";
|
import { ServicePortComponent } from "./service-port-component";
|
||||||
import { endpointStore } from "../+network-endpoints/endpoints.store";
|
import { endpointStore } from "../+network-endpoints/endpoints.store";
|
||||||
@ -38,31 +36,31 @@ export class ServiceDetails extends React.Component<Props> {
|
|||||||
<div className="ServicesDetails">
|
<div className="ServicesDetails">
|
||||||
<KubeObjectMeta object={service}/>
|
<KubeObjectMeta object={service}/>
|
||||||
|
|
||||||
<DrawerItem name={<Trans>Selector</Trans>} labelsOnly>
|
<DrawerItem name="Selector" labelsOnly>
|
||||||
{service.getSelector().map(selector => <Badge key={selector} label={selector}/>)}
|
{service.getSelector().map(selector => <Badge key={selector} label={selector}/>)}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
|
|
||||||
<DrawerItem name={<Trans>Type</Trans>}>
|
<DrawerItem name="Type">
|
||||||
{spec.type}
|
{spec.type}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
|
|
||||||
<DrawerItem name={<Trans>Session Affinity</Trans>}>
|
<DrawerItem name="Session Affinity">
|
||||||
{spec.sessionAffinity}
|
{spec.sessionAffinity}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
|
|
||||||
<DrawerTitle title={_i18n._(t`Connection`)}/>
|
<DrawerTitle title={`Connection`}/>
|
||||||
|
|
||||||
<DrawerItem name={<Trans>Cluster IP</Trans>}>
|
<DrawerItem name="Cluster IP">
|
||||||
{spec.clusterIP}
|
{spec.clusterIP}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
|
|
||||||
{service.getExternalIps().length > 0 && (
|
{service.getExternalIps().length > 0 && (
|
||||||
<DrawerItem name={<Trans>External IPs</Trans>}>
|
<DrawerItem name="External IPs">
|
||||||
{service.getExternalIps().map(ip => <div key={ip}>{ip}</div>)}
|
{service.getExternalIps().map(ip => <div key={ip}>{ip}</div>)}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<DrawerItem name={<Trans>Ports</Trans>}>
|
<DrawerItem name="Ports">
|
||||||
<div>
|
<div>
|
||||||
{
|
{
|
||||||
service.getPorts().map((port) => (
|
service.getPorts().map((port) => (
|
||||||
@ -73,11 +71,11 @@ export class ServiceDetails extends React.Component<Props> {
|
|||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
|
|
||||||
{spec.type === "LoadBalancer" && spec.loadBalancerIP && (
|
{spec.type === "LoadBalancer" && spec.loadBalancerIP && (
|
||||||
<DrawerItem name={<Trans>Load Balancer IP</Trans>}>
|
<DrawerItem name="Load Balancer IP">
|
||||||
{spec.loadBalancerIP}
|
{spec.loadBalancerIP}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
)}
|
)}
|
||||||
<DrawerTitle title={_i18n._(t`Endpoint`)}/>
|
<DrawerTitle title={`Endpoint`}/>
|
||||||
|
|
||||||
<ServiceDetailsEndpoint endpoint={endpoint} />
|
<ServiceDetailsEndpoint endpoint={endpoint} />
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -2,9 +2,7 @@ import "./service-port-component.scss";
|
|||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { t } from "@lingui/macro";
|
|
||||||
import { Service, ServicePort } from "../../api/endpoints";
|
import { Service, ServicePort } from "../../api/endpoints";
|
||||||
import { _i18n } from "../../i18n";
|
|
||||||
import { apiBase } from "../../api";
|
import { apiBase } from "../../api";
|
||||||
import { observable } from "mobx";
|
import { observable } from "mobx";
|
||||||
import { cssNames } from "../../utils";
|
import { cssNames } from "../../utils";
|
||||||
@ -39,7 +37,7 @@ export class ServicePortComponent extends React.Component<Props> {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={cssNames("ServicePortComponent", { waiting: this.waiting })}>
|
<div className={cssNames("ServicePortComponent", { waiting: this.waiting })}>
|
||||||
<span title={_i18n._(t`Open in a browser`)} onClick={() => this.portForward() }>
|
<span title={`Open in a browser`} onClick={() => this.portForward() }>
|
||||||
{port.toString()}
|
{port.toString()}
|
||||||
{this.waiting && (
|
{this.waiting && (
|
||||||
<Spinner />
|
<Spinner />
|
||||||
|
|||||||
@ -2,7 +2,6 @@ import "./services.scss";
|
|||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { Trans } from "@lingui/macro";
|
|
||||||
import { RouteComponentProps } from "react-router";
|
import { RouteComponentProps } from "react-router";
|
||||||
import { IServicesRouteParams } from "./services.route";
|
import { IServicesRouteParams } from "./services.route";
|
||||||
import { Service } from "../../api/endpoints/service.api";
|
import { Service } from "../../api/endpoints/service.api";
|
||||||
@ -46,18 +45,18 @@ export class Services extends React.Component<Props> {
|
|||||||
(service: Service) => service.getSelector().join(" "),
|
(service: Service) => service.getSelector().join(" "),
|
||||||
(service: Service) => service.getPorts().join(" "),
|
(service: Service) => service.getPorts().join(" "),
|
||||||
]}
|
]}
|
||||||
renderHeaderTitle={<Trans>Services</Trans>}
|
renderHeaderTitle="Services"
|
||||||
renderTableHeader={[
|
renderTableHeader={[
|
||||||
{ title: <Trans>Name</Trans>, className: "name", sortBy: sortBy.name },
|
{ title: "Name", className: "name", sortBy: sortBy.name },
|
||||||
{ className: "warning" },
|
{ className: "warning" },
|
||||||
{ title: <Trans>Namespace</Trans>, className: "namespace", sortBy: sortBy.namespace },
|
{ title: "Namespace", className: "namespace", sortBy: sortBy.namespace },
|
||||||
{ title: <Trans>Type</Trans>, className: "type", sortBy: sortBy.type },
|
{ title: "Type", className: "type", sortBy: sortBy.type },
|
||||||
{ title: <Trans>Cluster IP</Trans>, className: "clusterIp", sortBy: sortBy.clusterIp, },
|
{ title: "Cluster IP", className: "clusterIp", sortBy: sortBy.clusterIp, },
|
||||||
{ title: <Trans>Ports</Trans>, className: "ports", sortBy: sortBy.ports },
|
{ title: "Ports", className: "ports", sortBy: sortBy.ports },
|
||||||
{ title: <Trans>External IP</Trans>, className: "externalIp" },
|
{ title: "External IP", className: "externalIp" },
|
||||||
{ title: <Trans>Selector</Trans>, className: "selector", sortBy: sortBy.selector },
|
{ title: "Selector", className: "selector", sortBy: sortBy.selector },
|
||||||
{ title: <Trans>Age</Trans>, className: "age", sortBy: sortBy.age },
|
{ title: "Age", className: "age", sortBy: sortBy.age },
|
||||||
{ title: <Trans>Status</Trans>, className: "status", sortBy: sortBy.status },
|
{ title: "Status", className: "status", sortBy: sortBy.status },
|
||||||
]}
|
]}
|
||||||
renderTableContents={(service: Service) => [
|
renderTableContents={(service: Service) => [
|
||||||
service.getName(),
|
service.getName(),
|
||||||
|
|||||||
@ -2,7 +2,6 @@ import "./network.scss";
|
|||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { Trans } from "@lingui/macro";
|
|
||||||
import { TabLayout, TabLayoutRoute } from "../layout/tab-layout";
|
import { TabLayout, TabLayoutRoute } from "../layout/tab-layout";
|
||||||
import { Services, servicesRoute, servicesURL } from "../+network-services";
|
import { Services, servicesRoute, servicesURL } from "../+network-services";
|
||||||
import { endpointRoute, Endpoints, endpointURL } from "../+network-endpoints";
|
import { endpointRoute, Endpoints, endpointURL } from "../+network-endpoints";
|
||||||
@ -19,7 +18,7 @@ export class Network extends React.Component {
|
|||||||
|
|
||||||
if (isAllowedResource("services")) {
|
if (isAllowedResource("services")) {
|
||||||
routes.push({
|
routes.push({
|
||||||
title: <Trans>Services</Trans>,
|
title: "Services",
|
||||||
component: Services,
|
component: Services,
|
||||||
url: servicesURL({ query }),
|
url: servicesURL({ query }),
|
||||||
routePath: servicesRoute.path.toString(),
|
routePath: servicesRoute.path.toString(),
|
||||||
@ -28,7 +27,7 @@ export class Network extends React.Component {
|
|||||||
|
|
||||||
if (isAllowedResource("endpoints")) {
|
if (isAllowedResource("endpoints")) {
|
||||||
routes.push({
|
routes.push({
|
||||||
title: <Trans>Endpoints</Trans>,
|
title: "Endpoints",
|
||||||
component: Endpoints,
|
component: Endpoints,
|
||||||
url: endpointURL({ query }),
|
url: endpointURL({ query }),
|
||||||
routePath: endpointRoute.path.toString(),
|
routePath: endpointRoute.path.toString(),
|
||||||
@ -37,7 +36,7 @@ export class Network extends React.Component {
|
|||||||
|
|
||||||
if (isAllowedResource("ingresses")) {
|
if (isAllowedResource("ingresses")) {
|
||||||
routes.push({
|
routes.push({
|
||||||
title: <Trans>Ingresses</Trans>,
|
title: "Ingresses",
|
||||||
component: Ingresses,
|
component: Ingresses,
|
||||||
url: ingressURL({ query }),
|
url: ingressURL({ query }),
|
||||||
routePath: ingressRoute.path.toString(),
|
routePath: ingressRoute.path.toString(),
|
||||||
@ -46,7 +45,7 @@ export class Network extends React.Component {
|
|||||||
|
|
||||||
if (isAllowedResource("networkpolicies")) {
|
if (isAllowedResource("networkpolicies")) {
|
||||||
routes.push({
|
routes.push({
|
||||||
title: <Trans>Network Policies</Trans>,
|
title: "Network Policies",
|
||||||
component: NetworkPolicies,
|
component: NetworkPolicies,
|
||||||
url: networkPoliciesURL({ query }),
|
url: networkPoliciesURL({ query }),
|
||||||
routePath: networkPoliciesRoute.path.toString(),
|
routePath: networkPoliciesRoute.path.toString(),
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
import React, { useContext } from "react";
|
import React, { useContext } from "react";
|
||||||
import { t } from "@lingui/macro";
|
|
||||||
import { IClusterMetrics, Node } from "../../api/endpoints";
|
import { IClusterMetrics, Node } from "../../api/endpoints";
|
||||||
import { BarChart, cpuOptions, memoryOptions } from "../chart";
|
import { BarChart, cpuOptions, memoryOptions } from "../chart";
|
||||||
import { isMetricsEmpty, normalizeMetrics } from "../../api/endpoints/metrics.api";
|
import { isMetricsEmpty, normalizeMetrics } from "../../api/endpoints/metrics.api";
|
||||||
@ -8,7 +7,6 @@ import { IResourceMetricsValue, ResourceMetricsContext } from "../resource-metri
|
|||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { ChartOptions, ChartPoint } from "chart.js";
|
import { ChartOptions, ChartPoint } from "chart.js";
|
||||||
import { themeStore } from "../../theme.store";
|
import { themeStore } from "../../theme.store";
|
||||||
import { _i18n } from "../../i18n";
|
|
||||||
|
|
||||||
type IContext = IResourceMetricsValue<Node, { metrics: IClusterMetrics }>;
|
type IContext = IResourceMetricsValue<Node, { metrics: IClusterMetrics }>;
|
||||||
|
|
||||||
@ -43,22 +41,22 @@ export const NodeCharts = observer(() => {
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
id: `${id}-cpuUsage`,
|
id: `${id}-cpuUsage`,
|
||||||
label: _i18n._(t`Usage`),
|
label: `Usage`,
|
||||||
tooltip: _i18n._(t`CPU cores usage`),
|
tooltip: `CPU cores usage`,
|
||||||
borderColor: "#3D90CE",
|
borderColor: "#3D90CE",
|
||||||
data: cpuUsage.map(([x, y]) => ({ x, y }))
|
data: cpuUsage.map(([x, y]) => ({ x, y }))
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: `${id}-cpuRequests`,
|
id: `${id}-cpuRequests`,
|
||||||
label: _i18n._(t`Requests`),
|
label: `Requests`,
|
||||||
tooltip: _i18n._(t`CPU requests`),
|
tooltip: `CPU requests`,
|
||||||
borderColor: "#30b24d",
|
borderColor: "#30b24d",
|
||||||
data: cpuRequests.map(([x, y]) => ({ x, y }))
|
data: cpuRequests.map(([x, y]) => ({ x, y }))
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: `${id}-cpuCapacity`,
|
id: `${id}-cpuCapacity`,
|
||||||
label: _i18n._(t`Capacity`),
|
label: `Capacity`,
|
||||||
tooltip: _i18n._(t`CPU capacity`),
|
tooltip: `CPU capacity`,
|
||||||
borderColor: chartCapacityColor,
|
borderColor: chartCapacityColor,
|
||||||
data: cpuCapacity.map(([x, y]) => ({ x, y }))
|
data: cpuCapacity.map(([x, y]) => ({ x, y }))
|
||||||
}
|
}
|
||||||
@ -67,22 +65,22 @@ export const NodeCharts = observer(() => {
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
id: `${id}-memoryUsage`,
|
id: `${id}-memoryUsage`,
|
||||||
label: _i18n._(t`Usage`),
|
label: `Usage`,
|
||||||
tooltip: _i18n._(t`Memory usage`),
|
tooltip: `Memory usage`,
|
||||||
borderColor: "#c93dce",
|
borderColor: "#c93dce",
|
||||||
data: memoryUsage.map(([x, y]) => ({ x, y }))
|
data: memoryUsage.map(([x, y]) => ({ x, y }))
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "memoryRequests",
|
id: "memoryRequests",
|
||||||
label: _i18n._(t`Requests`),
|
label: `Requests`,
|
||||||
tooltip: _i18n._(t`Memory requests`),
|
tooltip: `Memory requests`,
|
||||||
borderColor: "#30b24d",
|
borderColor: "#30b24d",
|
||||||
data: memoryRequests.map(([x, y]) => ({ x, y }))
|
data: memoryRequests.map(([x, y]) => ({ x, y }))
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: `${id}-memoryCapacity`,
|
id: `${id}-memoryCapacity`,
|
||||||
label: _i18n._(t`Capacity`),
|
label: `Capacity`,
|
||||||
tooltip: _i18n._(t`Memory capacity`),
|
tooltip: `Memory capacity`,
|
||||||
borderColor: chartCapacityColor,
|
borderColor: chartCapacityColor,
|
||||||
data: memoryCapacity.map(([x, y]) => ({ x, y }))
|
data: memoryCapacity.map(([x, y]) => ({ x, y }))
|
||||||
}
|
}
|
||||||
@ -91,15 +89,15 @@ export const NodeCharts = observer(() => {
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
id: `${id}-fsUsage`,
|
id: `${id}-fsUsage`,
|
||||||
label: _i18n._(t`Usage`),
|
label: `Usage`,
|
||||||
tooltip: _i18n._(t`Node filesystem usage in bytes`),
|
tooltip: `Node filesystem usage in bytes`,
|
||||||
borderColor: "#ffc63d",
|
borderColor: "#ffc63d",
|
||||||
data: fsUsage.map(([x, y]) => ({ x, y }))
|
data: fsUsage.map(([x, y]) => ({ x, y }))
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: `${id}-fsSize`,
|
id: `${id}-fsSize`,
|
||||||
label: _i18n._(t`Size`),
|
label: `Size`,
|
||||||
tooltip: _i18n._(t`Node filesystem size in bytes`),
|
tooltip: `Node filesystem size in bytes`,
|
||||||
borderColor: chartCapacityColor,
|
borderColor: chartCapacityColor,
|
||||||
data: fsSize.map(([x, y]) => ({ x, y }))
|
data: fsSize.map(([x, y]) => ({ x, y }))
|
||||||
}
|
}
|
||||||
@ -108,15 +106,15 @@ export const NodeCharts = observer(() => {
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
id: `${id}-podUsage`,
|
id: `${id}-podUsage`,
|
||||||
label: _i18n._(t`Usage`),
|
label: `Usage`,
|
||||||
tooltip: _i18n._(t`Number of running Pods`),
|
tooltip: `Number of running Pods`,
|
||||||
borderColor: "#30b24d",
|
borderColor: "#30b24d",
|
||||||
data: podUsage.map(([x, y]) => ({ x, y }))
|
data: podUsage.map(([x, y]) => ({ x, y }))
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: `${id}-podCapacity`,
|
id: `${id}-podCapacity`,
|
||||||
label: _i18n._(t`Capacity`),
|
label: `Capacity`,
|
||||||
tooltip: _i18n._(t`Node Pods capacity`),
|
tooltip: `Node Pods capacity`,
|
||||||
borderColor: chartCapacityColor,
|
borderColor: chartCapacityColor,
|
||||||
data: podCapacity.map(([x, y]) => ({ x, y }))
|
data: podCapacity.map(([x, y]) => ({ x, y }))
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,7 +4,6 @@ import React from "react";
|
|||||||
import upperFirst from "lodash/upperFirst";
|
import upperFirst from "lodash/upperFirst";
|
||||||
import kebabCase from "lodash/kebabCase";
|
import kebabCase from "lodash/kebabCase";
|
||||||
import { disposeOnUnmount, observer } from "mobx-react";
|
import { disposeOnUnmount, observer } from "mobx-react";
|
||||||
import { Trans } from "@lingui/macro";
|
|
||||||
import { DrawerItem, DrawerItemLabels } from "../drawer";
|
import { DrawerItem, DrawerItemLabels } from "../drawer";
|
||||||
import { Badge } from "../badge";
|
import { Badge } from "../badge";
|
||||||
import { nodesStore } from "./nodes.store";
|
import { nodesStore } from "./nodes.store";
|
||||||
@ -50,10 +49,10 @@ export class NodeDetails extends React.Component<Props> {
|
|||||||
const childPods = podsStore.getPodsByNode(node.getName());
|
const childPods = podsStore.getPodsByNode(node.getName());
|
||||||
const metrics = nodesStore.nodeMetrics;
|
const metrics = nodesStore.nodeMetrics;
|
||||||
const metricTabs = [
|
const metricTabs = [
|
||||||
<Trans key="cpu">CPU</Trans>,
|
"CPU",
|
||||||
<Trans key="memory">Memory</Trans>,
|
"Memory",
|
||||||
<Trans key="disk">Disk</Trans>,
|
"Disk",
|
||||||
<Trans key="pods">Pods</Trans>,
|
"Pods",
|
||||||
];
|
];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -67,18 +66,18 @@ export class NodeDetails extends React.Component<Props> {
|
|||||||
</ResourceMetrics>
|
</ResourceMetrics>
|
||||||
)}
|
)}
|
||||||
<KubeObjectMeta object={node} hideFields={["labels", "annotations", "uid", "resourceVersion", "selfLink"]}/>
|
<KubeObjectMeta object={node} hideFields={["labels", "annotations", "uid", "resourceVersion", "selfLink"]}/>
|
||||||
<DrawerItem name={<Trans>Capacity</Trans>}>
|
<DrawerItem name="Capacity">
|
||||||
<Trans>CPU</Trans>: {capacity.cpu},{" "}
|
CPU: {capacity.cpu},{" "}
|
||||||
<Trans>Memory</Trans>: {Math.floor(parseInt(capacity.memory) / 1024)}Mi,{" "}
|
Memory: {Math.floor(parseInt(capacity.memory) / 1024)}Mi,{" "}
|
||||||
<Trans>Pods</Trans>: {capacity.pods}
|
Pods: {capacity.pods}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
<DrawerItem name={<Trans>Allocatable</Trans>}>
|
<DrawerItem name="Allocatable">
|
||||||
<Trans>CPU</Trans>: {allocatable.cpu},{" "}
|
CPU: {allocatable.cpu},{" "}
|
||||||
<Trans>Memory</Trans>: {Math.floor(parseInt(allocatable.memory) / 1024)}Mi,{" "}
|
Memory: {Math.floor(parseInt(allocatable.memory) / 1024)}Mi,{" "}
|
||||||
<Trans>Pods</Trans>: {allocatable.pods}
|
Pods: {allocatable.pods}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
{addresses &&
|
{addresses &&
|
||||||
<DrawerItem name={<Trans>Addresses</Trans>}>
|
<DrawerItem name="Addresses">
|
||||||
{
|
{
|
||||||
addresses.map(({ type, address }) => (
|
addresses.map(({ type, address }) => (
|
||||||
<p key={type}>{type}: {address}</p>
|
<p key={type}>{type}: {address}</p>
|
||||||
@ -86,31 +85,31 @@ export class NodeDetails extends React.Component<Props> {
|
|||||||
}
|
}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
}
|
}
|
||||||
<DrawerItem name={<Trans>OS</Trans>}>
|
<DrawerItem name="OS">
|
||||||
{nodeInfo.operatingSystem} ({nodeInfo.architecture})
|
{nodeInfo.operatingSystem} ({nodeInfo.architecture})
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
<DrawerItem name={<Trans>OS Image</Trans>}>
|
<DrawerItem name="OS Image">
|
||||||
{nodeInfo.osImage}
|
{nodeInfo.osImage}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
<DrawerItem name={<Trans>Kernel version</Trans>}>
|
<DrawerItem name="Kernel version">
|
||||||
{nodeInfo.kernelVersion}
|
{nodeInfo.kernelVersion}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
<DrawerItem name={<Trans>Container runtime</Trans>}>
|
<DrawerItem name="Container runtime">
|
||||||
{nodeInfo.containerRuntimeVersion}
|
{nodeInfo.containerRuntimeVersion}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
<DrawerItem name={<Trans>Kubelet version</Trans>}>
|
<DrawerItem name="Kubelet version">
|
||||||
{nodeInfo.kubeletVersion}
|
{nodeInfo.kubeletVersion}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
<DrawerItemLabels
|
<DrawerItemLabels
|
||||||
name={<Trans>Labels</Trans>}
|
name="Labels"
|
||||||
labels={node.getLabels()}
|
labels={node.getLabels()}
|
||||||
/>
|
/>
|
||||||
<DrawerItemLabels
|
<DrawerItemLabels
|
||||||
name={<Trans>Annotations</Trans>}
|
name="Annotations"
|
||||||
labels={node.getAnnotations()}
|
labels={node.getAnnotations()}
|
||||||
/>
|
/>
|
||||||
{taints.length > 0 && (
|
{taints.length > 0 && (
|
||||||
<DrawerItem name={<Trans>Taints</Trans>} labelsOnly>
|
<DrawerItem name="Taints" labelsOnly>
|
||||||
{
|
{
|
||||||
taints.map(({ key, effect, value }) => (
|
taints.map(({ key, effect, value }) => (
|
||||||
<Badge key={key} label={`${key}: ${effect}`} tooltip={value}/>
|
<Badge key={key} label={`${key}: ${effect}`} tooltip={value}/>
|
||||||
@ -119,7 +118,7 @@ export class NodeDetails extends React.Component<Props> {
|
|||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
)}
|
)}
|
||||||
{conditions &&
|
{conditions &&
|
||||||
<DrawerItem name={<Trans>Conditions</Trans>} className="conditions" labelsOnly>
|
<DrawerItem name="Conditions" className="conditions" labelsOnly>
|
||||||
{
|
{
|
||||||
conditions.map(condition => {
|
conditions.map(condition => {
|
||||||
const { type } = condition;
|
const { type } = condition;
|
||||||
|
|||||||
@ -2,7 +2,6 @@ import "./nodes.scss";
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { RouteComponentProps } from "react-router";
|
import { RouteComponentProps } from "react-router";
|
||||||
import { t, Trans } from "@lingui/macro";
|
|
||||||
import { cssNames, interval } from "../../utils";
|
import { cssNames, interval } from "../../utils";
|
||||||
import { TabLayout } from "../layout/tab-layout";
|
import { TabLayout } from "../layout/tab-layout";
|
||||||
import { nodesStore } from "./nodes.store";
|
import { nodesStore } from "./nodes.store";
|
||||||
@ -11,7 +10,6 @@ import { KubeObjectListLayout } from "../kube-object";
|
|||||||
import { INodesRouteParams } from "./nodes.route";
|
import { INodesRouteParams } from "./nodes.route";
|
||||||
import { Node } from "../../api/endpoints/nodes.api";
|
import { Node } from "../../api/endpoints/nodes.api";
|
||||||
import { LineProgress } from "../line-progress";
|
import { LineProgress } from "../line-progress";
|
||||||
import { _i18n } from "../../i18n";
|
|
||||||
import { bytesToUnits } from "../../utils/convertMemory";
|
import { bytesToUnits } from "../../utils/convertMemory";
|
||||||
import { Tooltip, TooltipPosition } from "../tooltip";
|
import { Tooltip, TooltipPosition } from "../tooltip";
|
||||||
import kebabCase from "lodash/kebabCase";
|
import kebabCase from "lodash/kebabCase";
|
||||||
@ -60,7 +58,7 @@ export class Nodes extends React.Component<Props> {
|
|||||||
value={usage}
|
value={usage}
|
||||||
tooltip={{
|
tooltip={{
|
||||||
preferredPositions: TooltipPosition.BOTTOM,
|
preferredPositions: TooltipPosition.BOTTOM,
|
||||||
children: `${_i18n._(t`CPU:`)} ${Math.ceil(usage * 100) / cores}\%, ${_i18n._(t`cores:`)} ${cores}`
|
children: `CPU: ${Math.ceil(usage * 100) / cores}\%, cores: ${cores}`
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
@ -79,7 +77,7 @@ export class Nodes extends React.Component<Props> {
|
|||||||
value={usage}
|
value={usage}
|
||||||
tooltip={{
|
tooltip={{
|
||||||
preferredPositions: TooltipPosition.BOTTOM,
|
preferredPositions: TooltipPosition.BOTTOM,
|
||||||
children: `${_i18n._(t`Memory:`)} ${Math.ceil(usage * 100 / capacity)}%, ${bytesToUnits(usage, 3)}`
|
children: `Memory: ${Math.ceil(usage * 100 / capacity)}%, ${bytesToUnits(usage, 3)}`
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
@ -98,7 +96,7 @@ export class Nodes extends React.Component<Props> {
|
|||||||
value={usage}
|
value={usage}
|
||||||
tooltip={{
|
tooltip={{
|
||||||
preferredPositions: TooltipPosition.BOTTOM,
|
preferredPositions: TooltipPosition.BOTTOM,
|
||||||
children: `${_i18n._(t`Disk:`)} ${Math.ceil(usage * 100 / capacity)}%, ${bytesToUnits(usage, 3)}`
|
children: `Disk: ${Math.ceil(usage * 100 / capacity)}%, ${bytesToUnits(usage, 3)}`
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
@ -155,18 +153,18 @@ export class Nodes extends React.Component<Props> {
|
|||||||
(node: Node) => node.getKubeletVersion(),
|
(node: Node) => node.getKubeletVersion(),
|
||||||
(node: Node) => node.getNodeConditionText(),
|
(node: Node) => node.getNodeConditionText(),
|
||||||
]}
|
]}
|
||||||
renderHeaderTitle={<Trans>Nodes</Trans>}
|
renderHeaderTitle="Nodes"
|
||||||
renderTableHeader={[
|
renderTableHeader={[
|
||||||
{ title: <Trans>Name</Trans>, className: "name", sortBy: sortBy.name },
|
{ title: "Name", className: "name", sortBy: sortBy.name },
|
||||||
{ className: "warning" },
|
{ className: "warning" },
|
||||||
{ title: <Trans>CPU</Trans>, className: "cpu", sortBy: sortBy.cpu },
|
{ title: "CPU", className: "cpu", sortBy: sortBy.cpu },
|
||||||
{ title: <Trans>Memory</Trans>, className: "memory", sortBy: sortBy.memory },
|
{ title: "Memory", className: "memory", sortBy: sortBy.memory },
|
||||||
{ title: <Trans>Disk</Trans>, className: "disk", sortBy: sortBy.disk },
|
{ title: "Disk", className: "disk", sortBy: sortBy.disk },
|
||||||
{ title: <Trans>Taints</Trans>, className: "taints", sortBy: sortBy.taints },
|
{ title: "Taints", className: "taints", sortBy: sortBy.taints },
|
||||||
{ title: <Trans>Roles</Trans>, className: "roles", sortBy: sortBy.roles },
|
{ title: "Roles", className: "roles", sortBy: sortBy.roles },
|
||||||
{ title: <Trans>Version</Trans>, className: "version", sortBy: sortBy.version },
|
{ title: "Version", className: "version", sortBy: sortBy.version },
|
||||||
{ title: <Trans>Age</Trans>, className: "age", sortBy: sortBy.age },
|
{ title: "Age", className: "age", sortBy: sortBy.age },
|
||||||
{ title: <Trans>Conditions</Trans>, className: "conditions", sortBy: sortBy.conditions },
|
{ title: "Conditions", className: "conditions", sortBy: sortBy.conditions },
|
||||||
]}
|
]}
|
||||||
renderTableContents={(node: Node) => {
|
renderTableContents={(node: Node) => {
|
||||||
const tooltipId = `node-taints-${node.getId()}`;
|
const tooltipId = `node-taints-${node.getId()}`;
|
||||||
|
|||||||
@ -2,7 +2,6 @@ import "./pod-security-policies.scss";
|
|||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { Trans } from "@lingui/macro";
|
|
||||||
import { KubeObjectListLayout } from "../kube-object";
|
import { KubeObjectListLayout } from "../kube-object";
|
||||||
import { podSecurityPoliciesStore } from "./pod-security-policies.store";
|
import { podSecurityPoliciesStore } from "./pod-security-policies.store";
|
||||||
import { PodSecurityPolicy } from "../../api/endpoints";
|
import { PodSecurityPolicy } from "../../api/endpoints";
|
||||||
@ -34,19 +33,19 @@ export class PodSecurityPolicies extends React.Component {
|
|||||||
(item: PodSecurityPolicy) => item.getVolumes(),
|
(item: PodSecurityPolicy) => item.getVolumes(),
|
||||||
(item: PodSecurityPolicy) => Object.values(item.getRules()),
|
(item: PodSecurityPolicy) => Object.values(item.getRules()),
|
||||||
]}
|
]}
|
||||||
renderHeaderTitle={<Trans>Pod Security Policies</Trans>}
|
renderHeaderTitle="Pod Security Policies"
|
||||||
renderTableHeader={[
|
renderTableHeader={[
|
||||||
{ title: <Trans>Name</Trans>, className: "name", sortBy: sortBy.name },
|
{ title: "Name", className: "name", sortBy: sortBy.name },
|
||||||
{ className: "warning" },
|
{ className: "warning" },
|
||||||
{ title: <Trans>Privileged</Trans>, className: "privileged", sortBy: sortBy.privileged },
|
{ title: "Privileged", className: "privileged", sortBy: sortBy.privileged },
|
||||||
{ title: <Trans>Volumes</Trans>, className: "volumes", sortBy: sortBy.volumes },
|
{ title: "Volumes", className: "volumes", sortBy: sortBy.volumes },
|
||||||
{ title: <Trans>Age</Trans>, className: "age", sortBy: sortBy.age },
|
{ title: "Age", className: "age", sortBy: sortBy.age },
|
||||||
]}
|
]}
|
||||||
renderTableContents={(item: PodSecurityPolicy) => {
|
renderTableContents={(item: PodSecurityPolicy) => {
|
||||||
return [
|
return [
|
||||||
item.getName(),
|
item.getName(),
|
||||||
<KubeObjectStatusIcon key="icon" object={item} />,
|
<KubeObjectStatusIcon key="icon" object={item} />,
|
||||||
item.isPrivileged() ? <Trans>Yes</Trans> : <Trans>No</Trans>,
|
item.isPrivileged() ? "Yes" : "No",
|
||||||
item.getVolumes().join(", "),
|
item.getVolumes().join(", "),
|
||||||
item.getAge(),
|
item.getAge(),
|
||||||
];
|
];
|
||||||
|
|||||||
@ -2,7 +2,6 @@ import "./pod-security-policy-details.scss";
|
|||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { Trans } from "@lingui/macro";
|
|
||||||
import { DrawerItem, DrawerTitle } from "../drawer";
|
import { DrawerItem, DrawerTitle } from "../drawer";
|
||||||
import { KubeObjectDetailsProps } from "../kube-object";
|
import { KubeObjectDetailsProps } from "../kube-object";
|
||||||
import { PodSecurityPolicy } from "../../api/endpoints";
|
import { PodSecurityPolicy } from "../../api/endpoints";
|
||||||
@ -28,11 +27,11 @@ export class PodSecurityPolicyDetails extends React.Component<Props> {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<DrawerTitle title={title}/>
|
<DrawerTitle title={title}/>
|
||||||
<DrawerItem name={<Trans>Rule</Trans>}>
|
<DrawerItem name="Rule">
|
||||||
{rule}
|
{rule}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
{ranges && (
|
{ranges && (
|
||||||
<DrawerItem name={<Trans>Ranges (Min-Max)</Trans>} labelsOnly>
|
<DrawerItem name="Ranges (Min-Max)" labelsOnly>
|
||||||
{ranges.map(({ min, max }, index) => {
|
{ranges.map(({ min, max }, index) => {
|
||||||
return <Badge key={index} label={`${min} - ${max}`}/>;
|
return <Badge key={index} label={`${min} - ${max}`}/>;
|
||||||
})}
|
})}
|
||||||
@ -60,85 +59,85 @@ export class PodSecurityPolicyDetails extends React.Component<Props> {
|
|||||||
<KubeObjectMeta object={psp}/>
|
<KubeObjectMeta object={psp}/>
|
||||||
|
|
||||||
{allowedCapabilities && (
|
{allowedCapabilities && (
|
||||||
<DrawerItem name={<Trans>Allowed Capabilities</Trans>}>
|
<DrawerItem name="Allowed Capabilities">
|
||||||
{allowedCapabilities.join(", ")}
|
{allowedCapabilities.join(", ")}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{volumes && (
|
{volumes && (
|
||||||
<DrawerItem name={<Trans>Volumes</Trans>}>
|
<DrawerItem name="Volumes">
|
||||||
{volumes.join(", ")}
|
{volumes.join(", ")}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{allowedCSIDrivers && (
|
{allowedCSIDrivers && (
|
||||||
<DrawerItem name={<Trans>Allowed CSI Drivers</Trans>}>
|
<DrawerItem name="Allowed CSI Drivers">
|
||||||
{allowedCSIDrivers.map(({ name }) => name).join(", ")}
|
{allowedCSIDrivers.map(({ name }) => name).join(", ")}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{allowedFlexVolumes && (
|
{allowedFlexVolumes && (
|
||||||
<DrawerItem name={<Trans>Allowed Flex Volumes</Trans>}>
|
<DrawerItem name="Allowed Flex Volumes">
|
||||||
{allowedFlexVolumes.map(({ driver }) => driver).join(", ")}
|
{allowedFlexVolumes.map(({ driver }) => driver).join(", ")}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{allowedProcMountTypes && (
|
{allowedProcMountTypes && (
|
||||||
<DrawerItem name={<Trans>Allowed Proc Mount Types</Trans>}>
|
<DrawerItem name="Allowed Proc Mount Types">
|
||||||
{allowedProcMountTypes.join(", ")}
|
{allowedProcMountTypes.join(", ")}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{allowedUnsafeSysctls && (
|
{allowedUnsafeSysctls && (
|
||||||
<DrawerItem name={<Trans>Allowed Unsafe Sysctls</Trans>}>
|
<DrawerItem name="Allowed Unsafe Sysctls">
|
||||||
{allowedUnsafeSysctls.join(", ")}
|
{allowedUnsafeSysctls.join(", ")}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{forbiddenSysctls && (
|
{forbiddenSysctls && (
|
||||||
<DrawerItem name={<Trans>Forbidden Sysctls</Trans>}>
|
<DrawerItem name="Forbidden Sysctls">
|
||||||
{forbiddenSysctls.join(", ")}
|
{forbiddenSysctls.join(", ")}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<DrawerItem name={<Trans>Allow Privilege Escalation</Trans>}>
|
<DrawerItem name="Allow Privilege Escalation">
|
||||||
{allowPrivilegeEscalation ? <Trans>Yes</Trans> : <Trans>No</Trans>}
|
{allowPrivilegeEscalation ? "Yes" : "No"}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
|
|
||||||
<DrawerItem name={<Trans>Privileged</Trans>}>
|
<DrawerItem name="Privileged">
|
||||||
{privileged ? <Trans>Yes</Trans> : <Trans>No</Trans>}
|
{privileged ? "Yes" : "No"}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
|
|
||||||
<DrawerItem name={<Trans>Read-only Root Filesystem</Trans>}>
|
<DrawerItem name="Read-only Root Filesystem">
|
||||||
{readOnlyRootFilesystem ? <Trans>Yes</Trans> : <Trans>No</Trans>}
|
{readOnlyRootFilesystem ? "Yes" : "No"}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
|
|
||||||
{defaultAddCapabilities && (
|
{defaultAddCapabilities && (
|
||||||
<DrawerItem name={<Trans>Default Add Capabilities</Trans>}>
|
<DrawerItem name="Default Add Capabilities">
|
||||||
{defaultAddCapabilities.join(", ")}
|
{defaultAddCapabilities.join(", ")}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{requiredDropCapabilities && (
|
{requiredDropCapabilities && (
|
||||||
<DrawerItem name={<Trans>Required Drop Capabilities</Trans>}>
|
<DrawerItem name="Required Drop Capabilities">
|
||||||
{requiredDropCapabilities.join(", ")}
|
{requiredDropCapabilities.join(", ")}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<DrawerItem name={<Trans>Host IPC</Trans>}>
|
<DrawerItem name="Host IPC">
|
||||||
{hostIPC ? <Trans>Yes</Trans> : <Trans>No</Trans>}
|
{hostIPC ? "Yes" : "No"}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
|
|
||||||
<DrawerItem name={<Trans>Host Network</Trans>}>
|
<DrawerItem name="Host Network">
|
||||||
{hostNetwork ? <Trans>Yes</Trans> : <Trans>No</Trans>}
|
{hostNetwork ? "Yes" : "No"}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
|
|
||||||
<DrawerItem name={<Trans>Host PID</Trans>}>
|
<DrawerItem name="Host PID">
|
||||||
{hostPID ? <Trans>Yes</Trans> : <Trans>No</Trans>}
|
{hostPID ? "Yes" : "No"}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
|
|
||||||
{hostPorts && (
|
{hostPorts && (
|
||||||
<DrawerItem name={<Trans>Host Ports (Min-Max)</Trans>} labelsOnly>
|
<DrawerItem name="Host Ports (Min-Max)" labelsOnly>
|
||||||
{hostPorts.map(({ min, max }, index) => {
|
{hostPorts.map(({ min, max }, index) => {
|
||||||
return <Badge key={index} label={`${min} - ${max}`}/>;
|
return <Badge key={index} label={`${min} - ${max}`}/>;
|
||||||
})}
|
})}
|
||||||
@ -147,17 +146,17 @@ export class PodSecurityPolicyDetails extends React.Component<Props> {
|
|||||||
|
|
||||||
{allowedHostPaths && (
|
{allowedHostPaths && (
|
||||||
<>
|
<>
|
||||||
<DrawerTitle title={<Trans>Allowed Host Paths</Trans>}/>
|
<DrawerTitle title="Allowed Host Paths"/>
|
||||||
<Table>
|
<Table>
|
||||||
<TableHead>
|
<TableHead>
|
||||||
<TableCell><Trans>Path Prefix</Trans></TableCell>
|
<TableCell>Path Prefix</TableCell>
|
||||||
<TableCell><Trans>Read-only</Trans></TableCell>
|
<TableCell>Read-only</TableCell>
|
||||||
</TableHead>
|
</TableHead>
|
||||||
{allowedHostPaths.map(({ pathPrefix, readOnly }, index) => {
|
{allowedHostPaths.map(({ pathPrefix, readOnly }, index) => {
|
||||||
return (
|
return (
|
||||||
<TableRow key={index}>
|
<TableRow key={index}>
|
||||||
<TableCell>{pathPrefix}</TableCell>
|
<TableCell>{pathPrefix}</TableCell>
|
||||||
<TableCell>{readOnly ? <Trans>Yes</Trans> : <Trans>No</Trans>}</TableCell>
|
<TableCell>{readOnly ? "Yes" : "No"}</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
@ -165,18 +164,18 @@ export class PodSecurityPolicyDetails extends React.Component<Props> {
|
|||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{this.renderRuleGroup(<Trans>Fs Group</Trans>, fsGroup)}
|
{this.renderRuleGroup("Fs Group", fsGroup)}
|
||||||
{this.renderRuleGroup(<Trans>Run As Group</Trans>, runAsGroup)}
|
{this.renderRuleGroup("Run As Group", runAsGroup)}
|
||||||
{this.renderRuleGroup(<Trans>Run As User</Trans>, runAsUser)}
|
{this.renderRuleGroup("Run As User", runAsUser)}
|
||||||
{this.renderRuleGroup(<Trans>Supplemental Groups</Trans>, supplementalGroups)}
|
{this.renderRuleGroup("Supplemental Groups", supplementalGroups)}
|
||||||
|
|
||||||
{runtimeClass && (
|
{runtimeClass && (
|
||||||
<>
|
<>
|
||||||
<DrawerTitle title={<Trans>Runtime Class</Trans>}/>
|
<DrawerTitle title="Runtime Class"/>
|
||||||
<DrawerItem name={<Trans>Allowed Runtime Class Names</Trans>}>
|
<DrawerItem name="Allowed Runtime Class Names">
|
||||||
{(runtimeClass.allowedRuntimeClassNames || []).join(", ") || "-"}
|
{(runtimeClass.allowedRuntimeClassNames || []).join(", ") || "-"}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
<DrawerItem name={<Trans>Default Runtime Class Name</Trans>}>
|
<DrawerItem name="Default Runtime Class Name">
|
||||||
{runtimeClass.defaultRuntimeClassName || "-"}
|
{runtimeClass.defaultRuntimeClassName || "-"}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
</>
|
</>
|
||||||
@ -184,22 +183,22 @@ export class PodSecurityPolicyDetails extends React.Component<Props> {
|
|||||||
|
|
||||||
{seLinux && (
|
{seLinux && (
|
||||||
<>
|
<>
|
||||||
<DrawerTitle title={<Trans>Se Linux</Trans>}/>
|
<DrawerTitle title="Se Linux"/>
|
||||||
<DrawerItem name={<Trans>Rule</Trans>}>
|
<DrawerItem name="Rule">
|
||||||
{seLinux.rule}
|
{seLinux.rule}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
{seLinux.seLinuxOptions && (
|
{seLinux.seLinuxOptions && (
|
||||||
<>
|
<>
|
||||||
<DrawerItem name={<Trans>Level</Trans>}>
|
<DrawerItem name="Level">
|
||||||
{seLinux.seLinuxOptions.level}
|
{seLinux.seLinuxOptions.level}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
<DrawerItem name={<Trans>Role</Trans>}>
|
<DrawerItem name="Role">
|
||||||
{seLinux.seLinuxOptions.role}
|
{seLinux.seLinuxOptions.role}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
<DrawerItem name={<Trans>Type</Trans>}>
|
<DrawerItem name="Type">
|
||||||
{seLinux.seLinuxOptions.type}
|
{seLinux.seLinuxOptions.type}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
<DrawerItem name={<Trans>User</Trans>}>
|
<DrawerItem name="User">
|
||||||
{seLinux.seLinuxOptions.user}
|
{seLinux.seLinuxOptions.user}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@ -4,8 +4,6 @@ import React from "react";
|
|||||||
import { remote, FileFilter } from "electron";
|
import { remote, FileFilter } from "electron";
|
||||||
import { observable } from "mobx";
|
import { observable } from "mobx";
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { t, Trans } from "@lingui/macro";
|
|
||||||
import { _i18n } from "../../i18n";
|
|
||||||
import { Dialog, DialogProps } from "../dialog";
|
import { Dialog, DialogProps } from "../dialog";
|
||||||
import { Wizard, WizardStep } from "../wizard";
|
import { Wizard, WizardStep } from "../wizard";
|
||||||
import { Input } from "../input";
|
import { Input } from "../input";
|
||||||
@ -66,8 +64,8 @@ export class AddHelmRepoDialog extends React.Component<Props> {
|
|||||||
const { canceled, filePaths } = await dialog.showOpenDialog(BrowserWindow.getFocusedWindow(), {
|
const { canceled, filePaths } = await dialog.showOpenDialog(BrowserWindow.getFocusedWindow(), {
|
||||||
defaultPath: this.getFilePath(type),
|
defaultPath: this.getFilePath(type),
|
||||||
properties: ["openFile", "showHiddenFiles"],
|
properties: ["openFile", "showHiddenFiles"],
|
||||||
message: _i18n._(t`Select file`),
|
message: `Select file`,
|
||||||
buttonLabel: _i18n._(t`Use file`),
|
buttonLabel: `Use file`,
|
||||||
filters: [
|
filters: [
|
||||||
fileFilter,
|
fileFilter,
|
||||||
{ name: "Any", extensions: ["*"]}
|
{ name: "Any", extensions: ["*"]}
|
||||||
@ -82,11 +80,11 @@ export class AddHelmRepoDialog extends React.Component<Props> {
|
|||||||
async addCustomRepo() {
|
async addCustomRepo() {
|
||||||
try {
|
try {
|
||||||
await repoManager.addСustomRepo(this.helmRepo);
|
await repoManager.addСustomRepo(this.helmRepo);
|
||||||
Notifications.ok(<Trans>Helm repository <b>{this.helmRepo.name}</b> has added</Trans>);
|
Notifications.ok(<>Helm repository <b>{this.helmRepo.name}</b> has added</>);
|
||||||
this.props.onAddRepo();
|
this.props.onAddRepo();
|
||||||
this.close();
|
this.close();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
Notifications.error(<Trans>Adding helm branch <b>{this.helmRepo.name}</b> has failed: {String(err)}</Trans>);
|
Notifications.error(<>Adding helm branch <b>{this.helmRepo.name}</b> has failed: {String(err)}</>);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -103,7 +101,7 @@ export class AddHelmRepoDialog extends React.Component<Props> {
|
|||||||
<Icon
|
<Icon
|
||||||
material="folder"
|
material="folder"
|
||||||
onClick={() => this.selectFileDialog(fileType, {name: placeholder, extensions: fileExtensions})}
|
onClick={() => this.selectFileDialog(fileType, {name: placeholder, extensions: fileExtensions})}
|
||||||
tooltip={<Trans>Browse</Trans>}
|
tooltip="Browse"
|
||||||
/>
|
/>
|
||||||
</div>);
|
</div>);
|
||||||
}
|
}
|
||||||
@ -111,23 +109,23 @@ export class AddHelmRepoDialog extends React.Component<Props> {
|
|||||||
renderOptions() {
|
renderOptions() {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<SubTitle title={<Trans>Security settings</Trans>} />
|
<SubTitle title="Security settings" />
|
||||||
<Checkbox
|
<Checkbox
|
||||||
label={_i18n._(t`Skip TLS certificate checks for the repository`)}
|
label={`Skip TLS certificate checks for the repository`}
|
||||||
value={this.helmRepo.insecureSkipTlsVerify}
|
value={this.helmRepo.insecureSkipTlsVerify}
|
||||||
onChange={v => this.helmRepo.insecureSkipTlsVerify = v}
|
onChange={v => this.helmRepo.insecureSkipTlsVerify = v}
|
||||||
/>
|
/>
|
||||||
{this.renderFileInput(_i18n._(t`Key file`), FileType.KeyFile, AddHelmRepoDialog.keyExtensions)}
|
{this.renderFileInput(`Key file`, FileType.KeyFile, AddHelmRepoDialog.keyExtensions)}
|
||||||
{this.renderFileInput(_i18n._(t`Ca file`), FileType.CaFile, AddHelmRepoDialog.certExtensions)}
|
{this.renderFileInput(`Ca file`, FileType.CaFile, AddHelmRepoDialog.certExtensions)}
|
||||||
{this.renderFileInput(_i18n._(t`Cerificate file`), FileType.CertFile, AddHelmRepoDialog.certExtensions)}
|
{this.renderFileInput(`Cerificate file`, FileType.CertFile, AddHelmRepoDialog.certExtensions)}
|
||||||
<SubTitle title={<Trans>Chart Repository Credentials</Trans>} />
|
<SubTitle title="Chart Repository Credentials" />
|
||||||
<Input
|
<Input
|
||||||
placeholder={_i18n._(t`Username`)}
|
placeholder={`Username`}
|
||||||
value={this.helmRepo.username} onChange= {v => this.helmRepo.username = v}
|
value={this.helmRepo.username} onChange= {v => this.helmRepo.username = v}
|
||||||
/>
|
/>
|
||||||
<Input
|
<Input
|
||||||
type="password"
|
type="password"
|
||||||
placeholder={_i18n._(t`Password`)}
|
placeholder={`Password`}
|
||||||
value={this.helmRepo.password} onChange={v => this.helmRepo.password = v}
|
value={this.helmRepo.password} onChange={v => this.helmRepo.password = v}
|
||||||
/>
|
/>
|
||||||
</>);
|
</>);
|
||||||
@ -136,7 +134,7 @@ export class AddHelmRepoDialog extends React.Component<Props> {
|
|||||||
render() {
|
render() {
|
||||||
const { ...dialogProps } = this.props;
|
const { ...dialogProps } = this.props;
|
||||||
|
|
||||||
const header = <h5><Trans>Add custom Helm Repo</Trans></h5>;
|
const header = <h5>Add custom Helm Repo</h5>;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog
|
<Dialog
|
||||||
@ -146,25 +144,25 @@ export class AddHelmRepoDialog extends React.Component<Props> {
|
|||||||
close={this.close}
|
close={this.close}
|
||||||
>
|
>
|
||||||
<Wizard header={header} done={this.close}>
|
<Wizard header={header} done={this.close}>
|
||||||
<WizardStep contentClass="flow column" nextLabel={<Trans>Add</Trans>} next={()=>{this.addCustomRepo();}}>
|
<WizardStep contentClass="flow column" nextLabel="Add" next={()=>{this.addCustomRepo();}}>
|
||||||
<div className="flex column gaps">
|
<div className="flex column gaps">
|
||||||
<Input
|
<Input
|
||||||
autoFocus required
|
autoFocus required
|
||||||
placeholder={_i18n._(t`Helm repo name`)}
|
placeholder={`Helm repo name`}
|
||||||
validators={systemName}
|
validators={systemName}
|
||||||
value={this.helmRepo.name} onChange={v => this.helmRepo.name = v}
|
value={this.helmRepo.name} onChange={v => this.helmRepo.name = v}
|
||||||
/>
|
/>
|
||||||
<Input
|
<Input
|
||||||
required
|
required
|
||||||
placeholder={_i18n._(t`URL`)}
|
placeholder={`URL`}
|
||||||
validators={isUrl}
|
validators={isUrl}
|
||||||
value={this.helmRepo.url} onChange={v => this.helmRepo.url = v}
|
value={this.helmRepo.url} onChange={v => this.helmRepo.url = v}
|
||||||
/>
|
/>
|
||||||
<Button plain className="accordion" onClick={() => this.showOptions = !this.showOptions} >
|
<Button plain className="accordion" onClick={() => this.showOptions = !this.showOptions} >
|
||||||
<Trans>More</Trans>
|
More
|
||||||
<Icon
|
<Icon
|
||||||
small
|
small
|
||||||
tooltip={_i18n._(t`More`)}
|
tooltip={`More`}
|
||||||
material={this.showOptions ? "remove" : "add"}
|
material={this.showOptions ? "remove" : "add"}
|
||||||
/>
|
/>
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import { Trans } from "@lingui/macro";
|
|
||||||
import { Checkbox } from "../checkbox";
|
import { Checkbox } from "../checkbox";
|
||||||
import { Input, InputValidators } from "../input";
|
import { Input, InputValidators } from "../input";
|
||||||
import { SubTitle } from "../layout/sub-title";
|
import { SubTitle } from "../layout/sub-title";
|
||||||
@ -25,18 +24,18 @@ export const KubectlBinaries = observer(({ preferences }: { preferences: UserPre
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<h2><Trans>Kubectl Binary</Trans></h2>
|
<h2>Kubectl Binary</h2>
|
||||||
<Checkbox
|
<Checkbox
|
||||||
label={<Trans>Download kubectl binaries</Trans>}
|
label="Download kubectl binaries"
|
||||||
value={preferences.downloadKubectlBinaries}
|
value={preferences.downloadKubectlBinaries}
|
||||||
onChange={downloadKubectlBinaries => preferences.downloadKubectlBinaries = downloadKubectlBinaries}
|
onChange={downloadKubectlBinaries => preferences.downloadKubectlBinaries = downloadKubectlBinaries}
|
||||||
/>
|
/>
|
||||||
<small className="hint">
|
<small className="hint">
|
||||||
<Trans>Download kubectl binaries matching to Kubernetes cluster version.</Trans>
|
Download kubectl binaries matching to Kubernetes cluster version.
|
||||||
</small>
|
</small>
|
||||||
<SubTitle title="Download mirror" />
|
<SubTitle title="Download mirror" />
|
||||||
<Select
|
<Select
|
||||||
placeholder={<Trans>Download mirror for kubectl</Trans>}
|
placeholder="Download mirror for kubectl"
|
||||||
options={downloadMirrorOptions}
|
options={downloadMirrorOptions}
|
||||||
value={preferences.downloadMirror}
|
value={preferences.downloadMirror}
|
||||||
onChange={({ value }: SelectOption) => preferences.downloadMirror = value}
|
onChange={({ value }: SelectOption) => preferences.downloadMirror = value}
|
||||||
@ -66,7 +65,7 @@ export const KubectlBinaries = observer(({ preferences }: { preferences: UserPre
|
|||||||
disabled={preferences.downloadKubectlBinaries}
|
disabled={preferences.downloadKubectlBinaries}
|
||||||
/>
|
/>
|
||||||
<small className="hint">
|
<small className="hint">
|
||||||
<Trans>The path to the kubectl binary on the system.</Trans>
|
The path to the kubectl binary on the system.
|
||||||
</small>
|
</small>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -3,8 +3,6 @@ import "./preferences.scss";
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { action, computed, observable } from "mobx";
|
import { action, computed, observable } from "mobx";
|
||||||
import { t, Trans } from "@lingui/macro";
|
|
||||||
import { _i18n } from "../../i18n";
|
|
||||||
import { Icon } from "../icon";
|
import { Icon } from "../icon";
|
||||||
import { Select, SelectOption } from "../select";
|
import { Select, SelectOption } from "../select";
|
||||||
import { userStore } from "../../../common/user-store";
|
import { userStore } from "../../../common/user-store";
|
||||||
@ -69,7 +67,7 @@ export class Preferences extends React.Component {
|
|||||||
await repoManager.addRepo(repo);
|
await repoManager.addRepo(repo);
|
||||||
this.helmAddedRepos.set(repo.name, repo);
|
this.helmAddedRepos.set(repo.name, repo);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
Notifications.error(<Trans>Adding helm branch <b>{repo.name}</b> has failed: {String(err)}</Trans>);
|
Notifications.error(<>Adding helm branch <b>{repo.name}</b> has failed: {String(err)}</>);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,7 +77,7 @@ export class Preferences extends React.Component {
|
|||||||
this.helmAddedRepos.delete(repo.name);
|
this.helmAddedRepos.delete(repo.name);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
Notifications.error(
|
Notifications.error(
|
||||||
<Trans>Removing helm branch <b>{repo.name}</b> has failed: {String(err)}</Trans>
|
<>Removing helm branch <b>{repo.name}</b> has failed: {String(err)}</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -88,7 +86,7 @@ export class Preferences extends React.Component {
|
|||||||
const isAdded = this.helmAddedRepos.has(repo.name);
|
const isAdded = this.helmAddedRepos.has(repo.name);
|
||||||
|
|
||||||
if (isAdded) {
|
if (isAdded) {
|
||||||
Notifications.ok(<Trans>Helm branch <b>{repo.name}</b> already in use</Trans>);
|
Notifications.ok(<>Helm branch <b>{repo.name}</b> already in use</>);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -110,35 +108,35 @@ export class Preferences extends React.Component {
|
|||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { preferences } = userStore;
|
const { preferences } = userStore;
|
||||||
const header = <h2><Trans>Preferences</Trans></h2>;
|
const header = <h2>Preferences</h2>;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PageLayout showOnTop className="Preferences" header={header}>
|
<PageLayout showOnTop className="Preferences" header={header}>
|
||||||
<h2><Trans>Color Theme</Trans></h2>
|
<h2>Color Theme</h2>
|
||||||
<Select
|
<Select
|
||||||
options={this.themeOptions}
|
options={this.themeOptions}
|
||||||
value={preferences.colorTheme}
|
value={preferences.colorTheme}
|
||||||
onChange={({ value }: SelectOption) => preferences.colorTheme = value}
|
onChange={({ value }: SelectOption) => preferences.colorTheme = value}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<h2><Trans>HTTP Proxy</Trans></h2>
|
<h2>HTTP Proxy</h2>
|
||||||
<Input
|
<Input
|
||||||
theme="round-black"
|
theme="round-black"
|
||||||
placeholder={_i18n._(t`Type HTTP proxy url (example: http://proxy.acme.org:8080)`)}
|
placeholder={`Type HTTP proxy url (example: http://proxy.acme.org:8080)`}
|
||||||
value={this.httpProxy}
|
value={this.httpProxy}
|
||||||
onChange={v => this.httpProxy = v}
|
onChange={v => this.httpProxy = v}
|
||||||
onBlur={() => preferences.httpsProxy = this.httpProxy}
|
onBlur={() => preferences.httpsProxy = this.httpProxy}
|
||||||
/>
|
/>
|
||||||
<small className="hint">
|
<small className="hint">
|
||||||
<Trans>Proxy is used only for non-cluster communication.</Trans>
|
Proxy is used only for non-cluster communication.
|
||||||
</small>
|
</small>
|
||||||
|
|
||||||
<KubectlBinaries preferences={preferences}/>
|
<KubectlBinaries preferences={preferences}/>
|
||||||
|
|
||||||
<h2><Trans>Helm</Trans></h2>
|
<h2>Helm</h2>
|
||||||
<div className="flex gaps">
|
<div className="flex gaps">
|
||||||
<Select id="HelmRepoSelect"
|
<Select id="HelmRepoSelect"
|
||||||
placeholder={<Trans>Repositories</Trans>}
|
placeholder="Repositories"
|
||||||
isLoading={this.helmLoading}
|
isLoading={this.helmLoading}
|
||||||
isDisabled={this.helmLoading}
|
isDisabled={this.helmLoading}
|
||||||
options={this.helmOptions}
|
options={this.helmOptions}
|
||||||
@ -149,7 +147,7 @@ export class Preferences extends React.Component {
|
|||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
primary
|
primary
|
||||||
label={<Trans>Add Custom Helm Repo</Trans>}
|
label="Add Custom Helm Repo"
|
||||||
onClick={AddHelmRepoDialog.open}
|
onClick={AddHelmRepoDialog.open}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@ -164,7 +162,7 @@ export class Preferences extends React.Component {
|
|||||||
<Icon
|
<Icon
|
||||||
material="delete"
|
material="delete"
|
||||||
onClick={() => this.removeRepo(repo)}
|
onClick={() => this.removeRepo(repo)}
|
||||||
tooltip={<Trans>Remove</Trans>}
|
tooltip="Remove"
|
||||||
/>
|
/>
|
||||||
<Tooltip targetId={tooltipId} formatters={{ narrow: true }}>
|
<Tooltip targetId={tooltipId} formatters={{ narrow: true }}>
|
||||||
{repo.url}
|
{repo.url}
|
||||||
@ -174,23 +172,23 @@ export class Preferences extends React.Component {
|
|||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h2><Trans>Auto start-up</Trans></h2>
|
<h2>Auto start-up</h2>
|
||||||
<Checkbox
|
<Checkbox
|
||||||
label={<Trans>Automatically start Lens on login</Trans>}
|
label="Automatically start Lens on login"
|
||||||
value={preferences.openAtLogin}
|
value={preferences.openAtLogin}
|
||||||
onChange={v => preferences.openAtLogin = v}
|
onChange={v => preferences.openAtLogin = v}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<h2><Trans>Certificate Trust</Trans></h2>
|
<h2>Certificate Trust</h2>
|
||||||
<Checkbox
|
<Checkbox
|
||||||
label={<Trans>Allow untrusted Certificate Authorities</Trans>}
|
label="Allow untrusted Certificate Authorities"
|
||||||
value={preferences.allowUntrustedCAs}
|
value={preferences.allowUntrustedCAs}
|
||||||
onChange={v => preferences.allowUntrustedCAs = v}
|
onChange={v => preferences.allowUntrustedCAs = v}
|
||||||
/>
|
/>
|
||||||
<small className="hint">
|
<small className="hint">
|
||||||
<Trans>This will make Lens to trust ANY certificate authority without any validations.</Trans>{" "}
|
This will make Lens to trust ANY certificate authority without any validations.{" "}
|
||||||
<Trans>Needed with some corporate proxies that do certificate re-writing.</Trans>{" "}
|
Needed with some corporate proxies that do certificate re-writing.{" "}
|
||||||
<Trans>Does not affect cluster communications!</Trans>
|
Does not affect cluster communications!
|
||||||
</small>
|
</small>
|
||||||
|
|
||||||
<div className="extensions flex column gaps">
|
<div className="extensions flex column gaps">
|
||||||
|
|||||||
@ -2,14 +2,12 @@ import "./storage-class-details.scss";
|
|||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import startCase from "lodash/startCase";
|
import startCase from "lodash/startCase";
|
||||||
import { t, Trans } from "@lingui/macro";
|
|
||||||
import { DrawerItem, DrawerTitle } from "../drawer";
|
import { DrawerItem, DrawerTitle } from "../drawer";
|
||||||
import { Badge } from "../badge";
|
import { Badge } from "../badge";
|
||||||
import { KubeEventDetails } from "../+events/kube-event-details";
|
import { KubeEventDetails } from "../+events/kube-event-details";
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { KubeObjectDetailsProps } from "../kube-object";
|
import { KubeObjectDetailsProps } from "../kube-object";
|
||||||
import { StorageClass } from "../../api/endpoints";
|
import { StorageClass } from "../../api/endpoints";
|
||||||
import { _i18n } from "../../i18n";
|
|
||||||
import { KubeObjectMeta } from "../kube-object/kube-object-meta";
|
import { KubeObjectMeta } from "../kube-object/kube-object-meta";
|
||||||
import { kubeObjectDetailRegistry } from "../../api/kube-object-detail-registry";
|
import { kubeObjectDetailRegistry } from "../../api/kube-object-detail-registry";
|
||||||
|
|
||||||
@ -29,25 +27,25 @@ export class StorageClassDetails extends React.Component<Props> {
|
|||||||
<KubeObjectMeta object={storageClass}/>
|
<KubeObjectMeta object={storageClass}/>
|
||||||
|
|
||||||
{provisioner && (
|
{provisioner && (
|
||||||
<DrawerItem name={<Trans>Provisioner</Trans>} labelsOnly>
|
<DrawerItem name="Provisioner" labelsOnly>
|
||||||
<Badge label={provisioner}/>
|
<Badge label={provisioner}/>
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
)}
|
)}
|
||||||
<DrawerItem name={<Trans>Volume Binding Mode</Trans>}>
|
<DrawerItem name="Volume Binding Mode">
|
||||||
{storageClass.getVolumeBindingMode()}
|
{storageClass.getVolumeBindingMode()}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
<DrawerItem name={<Trans>Reclaim Policy</Trans>}>
|
<DrawerItem name="Reclaim Policy">
|
||||||
{storageClass.getReclaimPolicy()}
|
{storageClass.getReclaimPolicy()}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
|
|
||||||
{mountOptions && (
|
{mountOptions && (
|
||||||
<DrawerItem name={<Trans>Mount Options</Trans>}>
|
<DrawerItem name="Mount Options">
|
||||||
{mountOptions.join(", ")}
|
{mountOptions.join(", ")}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
)}
|
)}
|
||||||
{parameters && (
|
{parameters && (
|
||||||
<>
|
<>
|
||||||
<DrawerTitle title={_i18n._(t`Parameters`)}/>
|
<DrawerTitle title={`Parameters`}/>
|
||||||
{
|
{
|
||||||
Object.entries(parameters).map(([name, value]) => (
|
Object.entries(parameters).map(([name, value]) => (
|
||||||
<DrawerItem key={name + value} name={startCase(name)}>
|
<DrawerItem key={name + value} name={startCase(name)}>
|
||||||
|
|||||||
@ -3,7 +3,6 @@ import "./storage-classes.scss";
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { RouteComponentProps } from "react-router-dom";
|
import { RouteComponentProps } from "react-router-dom";
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { Trans } from "@lingui/macro";
|
|
||||||
import { StorageClass } from "../../api/endpoints/storage-class.api";
|
import { StorageClass } from "../../api/endpoints/storage-class.api";
|
||||||
import { KubeObjectListLayout } from "../kube-object";
|
import { KubeObjectListLayout } from "../kube-object";
|
||||||
import { IStorageClassesRouteParams } from "./storage-classes.route";
|
import { IStorageClassesRouteParams } from "./storage-classes.route";
|
||||||
@ -37,21 +36,21 @@ export class StorageClasses extends React.Component<Props> {
|
|||||||
(item: StorageClass) => item.getSearchFields(),
|
(item: StorageClass) => item.getSearchFields(),
|
||||||
(item: StorageClass) => item.provisioner,
|
(item: StorageClass) => item.provisioner,
|
||||||
]}
|
]}
|
||||||
renderHeaderTitle={<Trans>Storage Classes</Trans>}
|
renderHeaderTitle="Storage Classes"
|
||||||
renderTableHeader={[
|
renderTableHeader={[
|
||||||
{ title: <Trans>Name</Trans>, className: "name", sortBy: sortBy.name },
|
{ title: "Name", className: "name", sortBy: sortBy.name },
|
||||||
{ className: "warning" },
|
{ className: "warning" },
|
||||||
{ title: <Trans>Provisioner</Trans>, className: "provisioner", sortBy: sortBy.provisioner },
|
{ title: "Provisioner", className: "provisioner", sortBy: sortBy.provisioner },
|
||||||
{ title: <Trans>Reclaim Policy</Trans>, className: "reclaim-policy", sortBy: sortBy.reclaimPolicy },
|
{ title: "Reclaim Policy", className: "reclaim-policy", sortBy: sortBy.reclaimPolicy },
|
||||||
{ title: <Trans>Default</Trans>, className: "is-default" },
|
{ title: "Default", className: "is-default" },
|
||||||
{ title: <Trans>Age</Trans>, className: "age", sortBy: sortBy.age },
|
{ title: "Age", className: "age", sortBy: sortBy.age },
|
||||||
]}
|
]}
|
||||||
renderTableContents={(storageClass: StorageClass) => [
|
renderTableContents={(storageClass: StorageClass) => [
|
||||||
storageClass.getName(),
|
storageClass.getName(),
|
||||||
<KubeObjectStatusIcon key="icon" object={storageClass} />,
|
<KubeObjectStatusIcon key="icon" object={storageClass} />,
|
||||||
storageClass.provisioner,
|
storageClass.provisioner,
|
||||||
storageClass.getReclaimPolicy(),
|
storageClass.getReclaimPolicy(),
|
||||||
storageClass.isDefault() ? <Trans>Yes</Trans> : null,
|
storageClass.isDefault() ? "Yes" : null,
|
||||||
storageClass.getAge(),
|
storageClass.getAge(),
|
||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@ -3,7 +3,6 @@ import "./volume-claim-details.scss";
|
|||||||
import React, { Fragment } from "react";
|
import React, { Fragment } from "react";
|
||||||
import { reaction } from "mobx";
|
import { reaction } from "mobx";
|
||||||
import { disposeOnUnmount, observer } from "mobx-react";
|
import { disposeOnUnmount, observer } from "mobx-react";
|
||||||
import { t, Trans } from "@lingui/macro";
|
|
||||||
import { DrawerItem, DrawerTitle } from "../drawer";
|
import { DrawerItem, DrawerTitle } from "../drawer";
|
||||||
import { Badge } from "../badge";
|
import { Badge } from "../badge";
|
||||||
import { podsStore } from "../+workloads-pods/pods.store";
|
import { podsStore } from "../+workloads-pods/pods.store";
|
||||||
@ -14,7 +13,6 @@ import { ResourceMetrics } from "../resource-metrics";
|
|||||||
import { VolumeClaimDiskChart } from "./volume-claim-disk-chart";
|
import { VolumeClaimDiskChart } from "./volume-claim-disk-chart";
|
||||||
import { getDetailsUrl, KubeObjectDetailsProps, KubeObjectMeta } from "../kube-object";
|
import { getDetailsUrl, KubeObjectDetailsProps, KubeObjectMeta } from "../kube-object";
|
||||||
import { PersistentVolumeClaim } from "../../api/endpoints";
|
import { PersistentVolumeClaim } from "../../api/endpoints";
|
||||||
import { _i18n } from "../../i18n";
|
|
||||||
import { kubeObjectDetailRegistry } from "../../api/kube-object-detail-registry";
|
import { kubeObjectDetailRegistry } from "../../api/kube-object-detail-registry";
|
||||||
|
|
||||||
interface Props extends KubeObjectDetailsProps<PersistentVolumeClaim> {
|
interface Props extends KubeObjectDetailsProps<PersistentVolumeClaim> {
|
||||||
@ -41,7 +39,7 @@ export class PersistentVolumeClaimDetails extends React.Component<Props> {
|
|||||||
const { metrics } = volumeClaimStore;
|
const { metrics } = volumeClaimStore;
|
||||||
const pods = volumeClaim.getPods(podsStore.items);
|
const pods = volumeClaim.getPods(podsStore.items);
|
||||||
const metricTabs = [
|
const metricTabs = [
|
||||||
<Trans key="disk">Disk</Trans>
|
"Disk"
|
||||||
];
|
];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -53,38 +51,38 @@ export class PersistentVolumeClaimDetails extends React.Component<Props> {
|
|||||||
<VolumeClaimDiskChart/>
|
<VolumeClaimDiskChart/>
|
||||||
</ResourceMetrics>
|
</ResourceMetrics>
|
||||||
<KubeObjectMeta object={volumeClaim}/>
|
<KubeObjectMeta object={volumeClaim}/>
|
||||||
<DrawerItem name={<Trans>Access Modes</Trans>}>
|
<DrawerItem name="Access Modes">
|
||||||
{accessModes.join(", ")}
|
{accessModes.join(", ")}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
<DrawerItem name={<Trans>Storage Class Name</Trans>}>
|
<DrawerItem name="Storage Class Name">
|
||||||
{storageClassName}
|
{storageClassName}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
<DrawerItem name={<Trans>Storage</Trans>}>
|
<DrawerItem name="Storage">
|
||||||
{volumeClaim.getStorage()}
|
{volumeClaim.getStorage()}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
<DrawerItem name={<Trans>Pods</Trans>} className="pods">
|
<DrawerItem name="Pods" className="pods">
|
||||||
{pods.map(pod => (
|
{pods.map(pod => (
|
||||||
<Link key={pod.getId()} to={getDetailsUrl(pod.selfLink)}>
|
<Link key={pod.getId()} to={getDetailsUrl(pod.selfLink)}>
|
||||||
{pod.getName()}
|
{pod.getName()}
|
||||||
</Link>
|
</Link>
|
||||||
))}
|
))}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
<DrawerItem name={<Trans>Status</Trans>}>
|
<DrawerItem name="Status">
|
||||||
{volumeClaim.getStatus()}
|
{volumeClaim.getStatus()}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
|
|
||||||
<DrawerTitle title={_i18n._(t`Selector`)}/>
|
<DrawerTitle title={`Selector`}/>
|
||||||
|
|
||||||
<DrawerItem name={<Trans>Match Labels</Trans>} labelsOnly>
|
<DrawerItem name="Match Labels" labelsOnly>
|
||||||
{volumeClaim.getMatchLabels().map(label => <Badge key={label} label={label}/>)}
|
{volumeClaim.getMatchLabels().map(label => <Badge key={label} label={label}/>)}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
|
|
||||||
<DrawerItem name={<Trans>Match Expressions</Trans>}>
|
<DrawerItem name="Match Expressions">
|
||||||
{volumeClaim.getMatchExpressions().map(({ key, operator, values }, i) => (
|
{volumeClaim.getMatchExpressions().map(({ key, operator, values }, i) => (
|
||||||
<Fragment key={i}>
|
<Fragment key={i}>
|
||||||
<DrawerItem name={<Trans>Key</Trans>}>{key}</DrawerItem>
|
<DrawerItem name="Key">{key}</DrawerItem>
|
||||||
<DrawerItem name={<Trans>Operator</Trans>}>{operator}</DrawerItem>
|
<DrawerItem name="Operator">{operator}</DrawerItem>
|
||||||
<DrawerItem name={<Trans>Values</Trans>}>{values.join(", ")}</DrawerItem>
|
<DrawerItem name="Values">{values.join(", ")}</DrawerItem>
|
||||||
</Fragment>
|
</Fragment>
|
||||||
))}
|
))}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
|
|||||||
@ -1,12 +1,10 @@
|
|||||||
import React, { useContext } from "react";
|
import React, { useContext } from "react";
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { t } from "@lingui/macro";
|
|
||||||
import { IPvcMetrics, PersistentVolumeClaim } from "../../api/endpoints";
|
import { IPvcMetrics, PersistentVolumeClaim } from "../../api/endpoints";
|
||||||
import { BarChart, ChartDataSets, memoryOptions } from "../chart";
|
import { BarChart, ChartDataSets, memoryOptions } from "../chart";
|
||||||
import { isMetricsEmpty, normalizeMetrics } from "../../api/endpoints/metrics.api";
|
import { isMetricsEmpty, normalizeMetrics } from "../../api/endpoints/metrics.api";
|
||||||
import { NoMetrics } from "../resource-metrics/no-metrics";
|
import { NoMetrics } from "../resource-metrics/no-metrics";
|
||||||
import { IResourceMetricsValue, ResourceMetricsContext } from "../resource-metrics";
|
import { IResourceMetricsValue, ResourceMetricsContext } from "../resource-metrics";
|
||||||
import { _i18n } from "../../i18n";
|
|
||||||
import { themeStore } from "../../theme.store";
|
import { themeStore } from "../../theme.store";
|
||||||
|
|
||||||
type IContext = IResourceMetricsValue<PersistentVolumeClaim, { metrics: IPvcMetrics }>;
|
type IContext = IResourceMetricsValue<PersistentVolumeClaim, { metrics: IPvcMetrics }>;
|
||||||
@ -26,15 +24,15 @@ export const VolumeClaimDiskChart = observer(() => {
|
|||||||
const datasets: ChartDataSets[] = [
|
const datasets: ChartDataSets[] = [
|
||||||
{
|
{
|
||||||
id: `${id}-diskUsage`,
|
id: `${id}-diskUsage`,
|
||||||
label: _i18n._(t`Usage`),
|
label: `Usage`,
|
||||||
tooltip: _i18n._(t`Volume disk usage`),
|
tooltip: `Volume disk usage`,
|
||||||
borderColor: "#ffc63d",
|
borderColor: "#ffc63d",
|
||||||
data: usage.map(([x, y]) => ({ x, y }))
|
data: usage.map(([x, y]) => ({ x, y }))
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: `${id}-diskCapacity`,
|
id: `${id}-diskCapacity`,
|
||||||
label: _i18n._(t`Capacity`),
|
label: `Capacity`,
|
||||||
tooltip: _i18n._(t`Volume disk capacity`),
|
tooltip: `Volume disk capacity`,
|
||||||
borderColor: chartCapacityColor,
|
borderColor: chartCapacityColor,
|
||||||
data: capacity.map(([x, y]) => ({ x, y }))
|
data: capacity.map(([x, y]) => ({ x, y }))
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,7 +3,6 @@ import "./volume-claims.scss";
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { Link, RouteComponentProps } from "react-router-dom";
|
import { Link, RouteComponentProps } from "react-router-dom";
|
||||||
import { Trans } from "@lingui/macro";
|
|
||||||
import { volumeClaimStore } from "./volume-claim.store";
|
import { volumeClaimStore } from "./volume-claim.store";
|
||||||
import { PersistentVolumeClaim } from "../../api/endpoints/persistent-volume-claims.api";
|
import { PersistentVolumeClaim } from "../../api/endpoints/persistent-volume-claims.api";
|
||||||
import { podsStore } from "../+workloads-pods/pods.store";
|
import { podsStore } from "../+workloads-pods/pods.store";
|
||||||
@ -48,16 +47,16 @@ export class PersistentVolumeClaims extends React.Component<Props> {
|
|||||||
(item: PersistentVolumeClaim) => item.getSearchFields(),
|
(item: PersistentVolumeClaim) => item.getSearchFields(),
|
||||||
(item: PersistentVolumeClaim) => item.getPods(podsStore.items).map(pod => pod.getName()),
|
(item: PersistentVolumeClaim) => item.getPods(podsStore.items).map(pod => pod.getName()),
|
||||||
]}
|
]}
|
||||||
renderHeaderTitle={<Trans>Persistent Volume Claims</Trans>}
|
renderHeaderTitle="Persistent Volume Claims"
|
||||||
renderTableHeader={[
|
renderTableHeader={[
|
||||||
{ title: <Trans>Name</Trans>, className: "name", sortBy: sortBy.name },
|
{ title: "Name", className: "name", sortBy: sortBy.name },
|
||||||
{ className: "warning" },
|
{ className: "warning" },
|
||||||
{ title: <Trans>Namespace</Trans>, className: "namespace", sortBy: sortBy.namespace },
|
{ title: "Namespace", className: "namespace", sortBy: sortBy.namespace },
|
||||||
{ title: <Trans>Storage class</Trans>, className: "storageClass", sortBy: sortBy.storageClass },
|
{ title: "Storage class", className: "storageClass", sortBy: sortBy.storageClass },
|
||||||
{ title: <Trans>Size</Trans>, className: "size", sortBy: sortBy.size },
|
{ title: "Size", className: "size", sortBy: sortBy.size },
|
||||||
{ title: <Trans>Pods</Trans>, className: "pods", sortBy: sortBy.pods },
|
{ title: "Pods", className: "pods", sortBy: sortBy.pods },
|
||||||
{ title: <Trans>Age</Trans>, className: "age", sortBy: sortBy.age },
|
{ title: "Age", className: "age", sortBy: sortBy.age },
|
||||||
{ title: <Trans>Status</Trans>, className: "status", sortBy: sortBy.status },
|
{ title: "Status", className: "status", sortBy: sortBy.status },
|
||||||
]}
|
]}
|
||||||
renderTableContents={(pvc: PersistentVolumeClaim) => {
|
renderTableContents={(pvc: PersistentVolumeClaim) => {
|
||||||
const pods = pvc.getPods(podsStore.items);
|
const pods = pvc.getPods(podsStore.items);
|
||||||
|
|||||||
@ -2,7 +2,6 @@ import startCase from "lodash/startCase";
|
|||||||
import "./volume-details.scss";
|
import "./volume-details.scss";
|
||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { Trans } from "@lingui/macro";
|
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { DrawerItem, DrawerTitle } from "../drawer";
|
import { DrawerItem, DrawerTitle } from "../drawer";
|
||||||
@ -29,32 +28,32 @@ export class PersistentVolumeDetails extends React.Component<Props> {
|
|||||||
return (
|
return (
|
||||||
<div className="PersistentVolumeDetails">
|
<div className="PersistentVolumeDetails">
|
||||||
<KubeObjectMeta object={volume}/>
|
<KubeObjectMeta object={volume}/>
|
||||||
<DrawerItem name={<Trans>Capacity</Trans>}>
|
<DrawerItem name="Capacity">
|
||||||
{capacity.storage}
|
{capacity.storage}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
|
|
||||||
{mountOptions && (
|
{mountOptions && (
|
||||||
<DrawerItem name={<Trans>Mount Options</Trans>}>
|
<DrawerItem name="Mount Options">
|
||||||
{mountOptions.join(", ")}
|
{mountOptions.join(", ")}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<DrawerItem name={<Trans>Access Modes</Trans>}>
|
<DrawerItem name="Access Modes">
|
||||||
{accessModes.join(", ")}
|
{accessModes.join(", ")}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
<DrawerItem name={<Trans>Reclaim Policy</Trans>}>
|
<DrawerItem name="Reclaim Policy">
|
||||||
{persistentVolumeReclaimPolicy}
|
{persistentVolumeReclaimPolicy}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
<DrawerItem name={<Trans>Storage Class Name</Trans>}>
|
<DrawerItem name="Storage Class Name">
|
||||||
{storageClassName}
|
{storageClassName}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
<DrawerItem name={<Trans>Status</Trans>} labelsOnly>
|
<DrawerItem name="Status" labelsOnly>
|
||||||
<Badge label={volume.getStatus()}/>
|
<Badge label={volume.getStatus()}/>
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
|
|
||||||
{nfs && (
|
{nfs && (
|
||||||
<>
|
<>
|
||||||
<DrawerTitle title={<Trans>Network File System</Trans>}/>
|
<DrawerTitle title="Network File System"/>
|
||||||
{
|
{
|
||||||
Object.entries(nfs).map(([name, value]) => (
|
Object.entries(nfs).map(([name, value]) => (
|
||||||
<DrawerItem key={name} name={startCase(name)}>
|
<DrawerItem key={name} name={startCase(name)}>
|
||||||
@ -67,8 +66,8 @@ export class PersistentVolumeDetails extends React.Component<Props> {
|
|||||||
|
|
||||||
{flexVolume && (
|
{flexVolume && (
|
||||||
<>
|
<>
|
||||||
<DrawerTitle title={<Trans>FlexVolume</Trans>}/>
|
<DrawerTitle title="FlexVolume"/>
|
||||||
<DrawerItem name={<Trans>Driver</Trans>}>
|
<DrawerItem name="Driver">
|
||||||
{flexVolume.driver}
|
{flexVolume.driver}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
{
|
{
|
||||||
@ -83,16 +82,16 @@ export class PersistentVolumeDetails extends React.Component<Props> {
|
|||||||
|
|
||||||
{claimRef && (
|
{claimRef && (
|
||||||
<>
|
<>
|
||||||
<DrawerTitle title={<Trans>Claim</Trans>}/>
|
<DrawerTitle title="Claim"/>
|
||||||
<DrawerItem name={<Trans>Type</Trans>}>
|
<DrawerItem name="Type">
|
||||||
{claimRef.kind}
|
{claimRef.kind}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
<DrawerItem name={<Trans>Name</Trans>}>
|
<DrawerItem name="Name">
|
||||||
<Link to={getDetailsUrl(pvcApi.getUrl(claimRef))}>
|
<Link to={getDetailsUrl(pvcApi.getUrl(claimRef))}>
|
||||||
{claimRef.name}
|
{claimRef.name}
|
||||||
</Link>
|
</Link>
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
<DrawerItem name={<Trans>Namespace</Trans>}>
|
<DrawerItem name="Namespace">
|
||||||
{claimRef.namespace}
|
{claimRef.namespace}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@ -2,7 +2,6 @@ import "./volumes.scss";
|
|||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { Trans } from "@lingui/macro";
|
|
||||||
import { Link, RouteComponentProps } from "react-router-dom";
|
import { Link, RouteComponentProps } from "react-router-dom";
|
||||||
import { PersistentVolume } from "../../api/endpoints/persistent-volume.api";
|
import { PersistentVolume } from "../../api/endpoints/persistent-volume.api";
|
||||||
import { getDetailsUrl, KubeObjectListLayout } from "../kube-object";
|
import { getDetailsUrl, KubeObjectListLayout } from "../kube-object";
|
||||||
@ -41,15 +40,15 @@ export class PersistentVolumes extends React.Component<Props> {
|
|||||||
(item: PersistentVolume) => item.getSearchFields(),
|
(item: PersistentVolume) => item.getSearchFields(),
|
||||||
(item: PersistentVolume) => item.getClaimRefName(),
|
(item: PersistentVolume) => item.getClaimRefName(),
|
||||||
]}
|
]}
|
||||||
renderHeaderTitle={<Trans>Persistent Volumes</Trans>}
|
renderHeaderTitle="Persistent Volumes"
|
||||||
renderTableHeader={[
|
renderTableHeader={[
|
||||||
{ title: <Trans>Name</Trans>, className: "name", sortBy: sortBy.name },
|
{ title: "Name", className: "name", sortBy: sortBy.name },
|
||||||
{ className: "warning" },
|
{ className: "warning" },
|
||||||
{ title: <Trans>Storage Class</Trans>, className: "storageClass", sortBy: sortBy.storageClass },
|
{ title: "Storage Class", className: "storageClass", sortBy: sortBy.storageClass },
|
||||||
{ title: <Trans>Capacity</Trans>, className: "capacity", sortBy: sortBy.capacity },
|
{ title: "Capacity", className: "capacity", sortBy: sortBy.capacity },
|
||||||
{ title: <Trans>Claim</Trans>, className: "claim" },
|
{ title: "Claim", className: "claim" },
|
||||||
{ title: <Trans>Age</Trans>, className: "age", sortBy: sortBy.age },
|
{ title: "Age", className: "age", sortBy: sortBy.age },
|
||||||
{ title: <Trans>Status</Trans>, className: "status", sortBy: sortBy.status },
|
{ title: "Status", className: "status", sortBy: sortBy.status },
|
||||||
]}
|
]}
|
||||||
renderTableContents={(volume: PersistentVolume) => {
|
renderTableContents={(volume: PersistentVolume) => {
|
||||||
const { claimRef, storageClassName } = volume.spec;
|
const { claimRef, storageClassName } = volume.spec;
|
||||||
|
|||||||
@ -2,7 +2,6 @@ import "./storage.scss";
|
|||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { Trans } from "@lingui/macro";
|
|
||||||
import { TabLayout, TabLayoutRoute } from "../layout/tab-layout";
|
import { TabLayout, TabLayoutRoute } from "../layout/tab-layout";
|
||||||
import { PersistentVolumes, volumesRoute, volumesURL } from "../+storage-volumes";
|
import { PersistentVolumes, volumesRoute, volumesURL } from "../+storage-volumes";
|
||||||
import { StorageClasses, storageClassesRoute, storageClassesURL } from "../+storage-classes";
|
import { StorageClasses, storageClassesRoute, storageClassesURL } from "../+storage-classes";
|
||||||
@ -18,7 +17,7 @@ export class Storage extends React.Component {
|
|||||||
|
|
||||||
if (isAllowedResource("persistentvolumeclaims")) {
|
if (isAllowedResource("persistentvolumeclaims")) {
|
||||||
tabRoutes.push({
|
tabRoutes.push({
|
||||||
title: <Trans>Persistent Volume Claims</Trans>,
|
title: "Persistent Volume Claims",
|
||||||
component: PersistentVolumeClaims,
|
component: PersistentVolumeClaims,
|
||||||
url: volumeClaimsURL({ query }),
|
url: volumeClaimsURL({ query }),
|
||||||
routePath: volumeClaimsRoute.path.toString(),
|
routePath: volumeClaimsRoute.path.toString(),
|
||||||
@ -27,7 +26,7 @@ export class Storage extends React.Component {
|
|||||||
|
|
||||||
if (isAllowedResource("persistentvolumes")) {
|
if (isAllowedResource("persistentvolumes")) {
|
||||||
tabRoutes.push({
|
tabRoutes.push({
|
||||||
title: <Trans>Persistent Volumes</Trans>,
|
title: "Persistent Volumes",
|
||||||
component: PersistentVolumes,
|
component: PersistentVolumes,
|
||||||
url: volumesURL(),
|
url: volumesURL(),
|
||||||
routePath: volumesRoute.path.toString(),
|
routePath: volumesRoute.path.toString(),
|
||||||
@ -36,7 +35,7 @@ export class Storage extends React.Component {
|
|||||||
|
|
||||||
if (isAllowedResource("storageclasses")) {
|
if (isAllowedResource("storageclasses")) {
|
||||||
tabRoutes.push({
|
tabRoutes.push({
|
||||||
title: <Trans>Storage Classes</Trans>,
|
title: "Storage Classes",
|
||||||
component: StorageClasses,
|
component: StorageClasses,
|
||||||
url: storageClassesURL(),
|
url: storageClassesURL(),
|
||||||
routePath: storageClassesRoute.path.toString(),
|
routePath: storageClassesRoute.path.toString(),
|
||||||
|
|||||||
@ -3,8 +3,6 @@ import "./add-role-binding-dialog.scss";
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { computed, observable } from "mobx";
|
import { computed, observable } from "mobx";
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { t, Trans } from "@lingui/macro";
|
|
||||||
import { _i18n } from "../../i18n";
|
|
||||||
import { Dialog, DialogProps } from "../dialog";
|
import { Dialog, DialogProps } from "../dialog";
|
||||||
import { Wizard, WizardStep } from "../wizard";
|
import { Wizard, WizardStep } from "../wizard";
|
||||||
import { Select, SelectOption } from "../select";
|
import { Select, SelectOption } from "../select";
|
||||||
@ -194,7 +192,7 @@ export class AddRoleBindingDialog extends React.Component<Props> {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<SubTitle title={<Trans>Context</Trans>}/>
|
<SubTitle title="Context"/>
|
||||||
<NamespaceSelect
|
<NamespaceSelect
|
||||||
showClusterOption
|
showClusterOption
|
||||||
themeName="light"
|
themeName="light"
|
||||||
@ -203,11 +201,11 @@ export class AddRoleBindingDialog extends React.Component<Props> {
|
|||||||
onChange={({ value }) => this.onBindContextChange(value)}
|
onChange={({ value }) => this.onBindContextChange(value)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<SubTitle title={<Trans>Role</Trans>}/>
|
<SubTitle title="Role"/>
|
||||||
<Select
|
<Select
|
||||||
key={this.selectedRoleId}
|
key={this.selectedRoleId}
|
||||||
themeName="light"
|
themeName="light"
|
||||||
placeholder={_i18n._(t`Select role..`)}
|
placeholder={`Select role..`}
|
||||||
isDisabled={this.isEditing}
|
isDisabled={this.isEditing}
|
||||||
options={this.roleOptions}
|
options={this.roleOptions}
|
||||||
value={this.selectedRoleId}
|
value={this.selectedRoleId}
|
||||||
@ -218,7 +216,7 @@ export class AddRoleBindingDialog extends React.Component<Props> {
|
|||||||
<>
|
<>
|
||||||
<Checkbox
|
<Checkbox
|
||||||
theme="light"
|
theme="light"
|
||||||
label={<Trans>Use same name for RoleBinding</Trans>}
|
label="Use same name for RoleBinding"
|
||||||
value={this.useRoleForBindingName}
|
value={this.useRoleForBindingName}
|
||||||
onChange={v => this.useRoleForBindingName = v}
|
onChange={v => this.useRoleForBindingName = v}
|
||||||
/>
|
/>
|
||||||
@ -226,7 +224,7 @@ export class AddRoleBindingDialog extends React.Component<Props> {
|
|||||||
!this.useRoleForBindingName && (
|
!this.useRoleForBindingName && (
|
||||||
<Input
|
<Input
|
||||||
autoFocus
|
autoFocus
|
||||||
placeholder={_i18n._(t`Name`)}
|
placeholder={`Name`}
|
||||||
disabled={this.isEditing}
|
disabled={this.isEditing}
|
||||||
value={this.bindingName}
|
value={this.bindingName}
|
||||||
onChange={v => this.bindingName = v}
|
onChange={v => this.bindingName = v}
|
||||||
@ -237,11 +235,11 @@ export class AddRoleBindingDialog extends React.Component<Props> {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
<SubTitle title={<Trans>Binding targets</Trans>}/>
|
<SubTitle title="Binding targets"/>
|
||||||
<Select
|
<Select
|
||||||
isMulti
|
isMulti
|
||||||
themeName="light"
|
themeName="light"
|
||||||
placeholder={_i18n._(t`Select service accounts`)}
|
placeholder={`Select service accounts`}
|
||||||
autoConvertOptions={false}
|
autoConvertOptions={false}
|
||||||
options={this.serviceAccountOptions}
|
options={this.serviceAccountOptions}
|
||||||
onChange={(opts: BindingSelectOption[]) => {
|
onChange={(opts: BindingSelectOption[]) => {
|
||||||
@ -261,13 +259,13 @@ export class AddRoleBindingDialog extends React.Component<Props> {
|
|||||||
const header = (
|
const header = (
|
||||||
<h5>
|
<h5>
|
||||||
{roleBindingName
|
{roleBindingName
|
||||||
? <Trans>Edit RoleBinding <span className="name">{roleBindingName}</span></Trans>
|
? <>Edit RoleBinding <span className="name">{roleBindingName}</span></>
|
||||||
: <Trans>Add RoleBinding</Trans>
|
: "Add RoleBinding"
|
||||||
}
|
}
|
||||||
</h5>
|
</h5>
|
||||||
);
|
);
|
||||||
const disableNext = this.isLoading || !selectedRole || !selectedBindings.length;
|
const disableNext = this.isLoading || !selectedRole || !selectedBindings.length;
|
||||||
const nextLabel = isEditing ? <Trans>Update</Trans> : <Trans>Create</Trans>;
|
const nextLabel = isEditing ? "Update" : "Create";
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog
|
<Dialog
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
import "./role-binding-details.scss";
|
import "./role-binding-details.scss";
|
||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { t, Trans } from "@lingui/macro";
|
|
||||||
import { AddRemoveButtons } from "../add-remove-buttons";
|
import { AddRemoveButtons } from "../add-remove-buttons";
|
||||||
import { IRoleBindingSubject, RoleBinding } from "../../api/endpoints";
|
import { IRoleBindingSubject, RoleBinding } from "../../api/endpoints";
|
||||||
import { autobind, prevDefault } from "../../utils";
|
import { autobind, prevDefault } from "../../utils";
|
||||||
@ -14,7 +13,6 @@ import { observable, reaction } from "mobx";
|
|||||||
import { roleBindingsStore } from "./role-bindings.store";
|
import { roleBindingsStore } from "./role-bindings.store";
|
||||||
import { AddRoleBindingDialog } from "./add-role-binding-dialog";
|
import { AddRoleBindingDialog } from "./add-role-binding-dialog";
|
||||||
import { KubeObjectDetailsProps } from "../kube-object";
|
import { KubeObjectDetailsProps } from "../kube-object";
|
||||||
import { _i18n } from "../../i18n";
|
|
||||||
import { KubeObjectMeta } from "../kube-object/kube-object-meta";
|
import { KubeObjectMeta } from "../kube-object/kube-object-meta";
|
||||||
import { kubeObjectDetailRegistry } from "../../api/kube-object-detail-registry";
|
import { kubeObjectDetailRegistry } from "../../api/kube-object-detail-registry";
|
||||||
|
|
||||||
@ -51,9 +49,9 @@ export class RoleBindingDetails extends React.Component<Props> {
|
|||||||
|
|
||||||
ConfirmDialog.open({
|
ConfirmDialog.open({
|
||||||
ok: () => roleBindingsStore.updateSubjects({ roleBinding, removeSubjects: selectedSubjects }),
|
ok: () => roleBindingsStore.updateSubjects({ roleBinding, removeSubjects: selectedSubjects }),
|
||||||
labelOk: _i18n._(t`Remove`),
|
labelOk: `Remove`,
|
||||||
message: (
|
message: (
|
||||||
<p><Trans>Remove selected bindings for <b>{roleBinding.getName()}</b>?</Trans></p>
|
<p>Remove selected bindings for <b>{roleBinding.getName()}</b>?</p>
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -65,7 +63,6 @@ export class RoleBindingDetails extends React.Component<Props> {
|
|||||||
if (!roleBinding) {
|
if (!roleBinding) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
const name = roleBinding.getName();
|
|
||||||
const { roleRef } = roleBinding;
|
const { roleRef } = roleBinding;
|
||||||
const subjects = roleBinding.getSubjects();
|
const subjects = roleBinding.getSubjects();
|
||||||
|
|
||||||
@ -73,12 +70,12 @@ export class RoleBindingDetails extends React.Component<Props> {
|
|||||||
<div className="RoleBindingDetails">
|
<div className="RoleBindingDetails">
|
||||||
<KubeObjectMeta object={roleBinding}/>
|
<KubeObjectMeta object={roleBinding}/>
|
||||||
|
|
||||||
<DrawerTitle title={<Trans>Reference</Trans>}/>
|
<DrawerTitle title="Reference"/>
|
||||||
<Table>
|
<Table>
|
||||||
<TableHead>
|
<TableHead>
|
||||||
<TableCell><Trans>Kind</Trans></TableCell>
|
<TableCell>Kind</TableCell>
|
||||||
<TableCell><Trans>Name</Trans></TableCell>
|
<TableCell>Name</TableCell>
|
||||||
<TableCell><Trans>API Group</Trans></TableCell>
|
<TableCell>API Group</TableCell>
|
||||||
</TableHead>
|
</TableHead>
|
||||||
<TableRow>
|
<TableRow>
|
||||||
<TableCell>{roleRef.kind}</TableCell>
|
<TableCell>{roleRef.kind}</TableCell>
|
||||||
@ -87,14 +84,14 @@ export class RoleBindingDetails extends React.Component<Props> {
|
|||||||
</TableRow>
|
</TableRow>
|
||||||
</Table>
|
</Table>
|
||||||
|
|
||||||
<DrawerTitle title={<Trans>Bindings</Trans>}/>
|
<DrawerTitle title="Bindings"/>
|
||||||
{subjects.length > 0 && (
|
{subjects.length > 0 && (
|
||||||
<Table selectable className="bindings box grow">
|
<Table selectable className="bindings box grow">
|
||||||
<TableHead>
|
<TableHead>
|
||||||
<TableCell checkbox/>
|
<TableCell checkbox/>
|
||||||
<TableCell className="binding"><Trans>Binding</Trans></TableCell>
|
<TableCell className="binding">Binding</TableCell>
|
||||||
<TableCell className="type"><Trans>Type</Trans></TableCell>
|
<TableCell className="type">Type</TableCell>
|
||||||
<TableCell className="type"><Trans>Namespace</Trans></TableCell>
|
<TableCell className="type">Namespace</TableCell>
|
||||||
</TableHead>
|
</TableHead>
|
||||||
{
|
{
|
||||||
subjects.map((subject, i) => {
|
subjects.map((subject, i) => {
|
||||||
@ -120,8 +117,8 @@ export class RoleBindingDetails extends React.Component<Props> {
|
|||||||
<AddRemoveButtons
|
<AddRemoveButtons
|
||||||
onAdd={() => AddRoleBindingDialog.open(roleBinding)}
|
onAdd={() => AddRoleBindingDialog.open(roleBinding)}
|
||||||
onRemove={selectedSubjects.length ? this.removeSelectedSubjects : null}
|
onRemove={selectedSubjects.length ? this.removeSelectedSubjects : null}
|
||||||
addTooltip={<Trans>Add bindings to {name}</Trans>}
|
addTooltip="Add bindings to {name}"
|
||||||
removeTooltip={<Trans>Remove selected bindings from ${name}</Trans>}
|
removeTooltip="Remove selected bindings from ${name}"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -2,7 +2,6 @@ import "./role-bindings.scss";
|
|||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { Trans } from "@lingui/macro";
|
|
||||||
import { RouteComponentProps } from "react-router";
|
import { RouteComponentProps } from "react-router";
|
||||||
import { IRoleBindingsRouteParams } from "../+user-management/user-management.route";
|
import { IRoleBindingsRouteParams } from "../+user-management/user-management.route";
|
||||||
import { RoleBinding } from "../../api/endpoints";
|
import { RoleBinding } from "../../api/endpoints";
|
||||||
@ -38,13 +37,13 @@ export class RoleBindings extends React.Component<Props> {
|
|||||||
(binding: RoleBinding) => binding.getSearchFields(),
|
(binding: RoleBinding) => binding.getSearchFields(),
|
||||||
(binding: RoleBinding) => binding.getSubjectNames(),
|
(binding: RoleBinding) => binding.getSubjectNames(),
|
||||||
]}
|
]}
|
||||||
renderHeaderTitle={<Trans>Role Bindings</Trans>}
|
renderHeaderTitle="Role Bindings"
|
||||||
renderTableHeader={[
|
renderTableHeader={[
|
||||||
{ title: <Trans>Name</Trans>, className: "name", sortBy: sortBy.name },
|
{ title: "Name", className: "name", sortBy: sortBy.name },
|
||||||
{ className: "warning" },
|
{ className: "warning" },
|
||||||
{ title: <Trans>Bindings</Trans>, className: "bindings", sortBy: sortBy.bindings },
|
{ title: "Bindings", className: "bindings", sortBy: sortBy.bindings },
|
||||||
{ title: <Trans>Namespace</Trans>, className: "namespace", sortBy: sortBy.namespace },
|
{ title: "Namespace", className: "namespace", sortBy: sortBy.namespace },
|
||||||
{ title: <Trans>Age</Trans>, className: "age", sortBy: sortBy.age },
|
{ title: "Age", className: "age", sortBy: sortBy.age },
|
||||||
]}
|
]}
|
||||||
renderTableContents={(binding: RoleBinding) => [
|
renderTableContents={(binding: RoleBinding) => [
|
||||||
binding.getName(),
|
binding.getName(),
|
||||||
@ -55,7 +54,7 @@ export class RoleBindings extends React.Component<Props> {
|
|||||||
]}
|
]}
|
||||||
addRemoveButtons={{
|
addRemoveButtons={{
|
||||||
onAdd: () => AddRoleBindingDialog.open(),
|
onAdd: () => AddRoleBindingDialog.open(),
|
||||||
addTooltip: <Trans>Create new RoleBinding</Trans>,
|
addTooltip: "Create new RoleBinding",
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -3,8 +3,6 @@ import "./add-role-dialog.scss";
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { observable } from "mobx";
|
import { observable } from "mobx";
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { t, Trans } from "@lingui/macro";
|
|
||||||
import { _i18n } from "../../i18n";
|
|
||||||
import { Dialog, DialogProps } from "../dialog";
|
import { Dialog, DialogProps } from "../dialog";
|
||||||
import { Wizard, WizardStep } from "../wizard";
|
import { Wizard, WizardStep } from "../wizard";
|
||||||
import { Notifications } from "../notifications";
|
import { Notifications } from "../notifications";
|
||||||
@ -51,7 +49,7 @@ export class AddRoleDialog extends React.Component<Props> {
|
|||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { ...dialogProps } = this.props;
|
const { ...dialogProps } = this.props;
|
||||||
const header = <h5><Trans>Create Role</Trans></h5>;
|
const header = <h5>Create Role</h5>;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog
|
<Dialog
|
||||||
@ -63,12 +61,12 @@ export class AddRoleDialog extends React.Component<Props> {
|
|||||||
<Wizard header={header} done={this.close}>
|
<Wizard header={header} done={this.close}>
|
||||||
<WizardStep
|
<WizardStep
|
||||||
contentClass="flex gaps column"
|
contentClass="flex gaps column"
|
||||||
nextLabel={<Trans>Create</Trans>}
|
nextLabel="Create"
|
||||||
next={this.createRole}
|
next={this.createRole}
|
||||||
>
|
>
|
||||||
<Input
|
<Input
|
||||||
required autoFocus
|
required autoFocus
|
||||||
placeholder={_i18n._(t`Role name`)}
|
placeholder={`Role name`}
|
||||||
iconLeft="supervisor_account"
|
iconLeft="supervisor_account"
|
||||||
value={this.roleName}
|
value={this.roleName}
|
||||||
onChange={v => this.roleName = v}
|
onChange={v => this.roleName = v}
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
import "./role-details.scss";
|
import "./role-details.scss";
|
||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { Trans } from "@lingui/macro";
|
|
||||||
import { DrawerTitle } from "../drawer";
|
import { DrawerTitle } from "../drawer";
|
||||||
import { KubeEventDetails } from "../+events/kube-event-details";
|
import { KubeEventDetails } from "../+events/kube-event-details";
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
@ -25,25 +24,25 @@ export class RoleDetails extends React.Component<Props> {
|
|||||||
<div className="RoleDetails">
|
<div className="RoleDetails">
|
||||||
<KubeObjectMeta object={role}/>
|
<KubeObjectMeta object={role}/>
|
||||||
|
|
||||||
<DrawerTitle title={<Trans>Rules</Trans>}/>
|
<DrawerTitle title="Rules"/>
|
||||||
{rules.map(({ resourceNames, apiGroups, resources, verbs }, index) => {
|
{rules.map(({ resourceNames, apiGroups, resources, verbs }, index) => {
|
||||||
return (
|
return (
|
||||||
<div className="rule" key={index}>
|
<div className="rule" key={index}>
|
||||||
{resources && (
|
{resources && (
|
||||||
<>
|
<>
|
||||||
<div className="name"><Trans>Resources</Trans></div>
|
<div className="name">Resources</div>
|
||||||
<div className="value">{resources.join(", ")}</div>
|
<div className="value">{resources.join(", ")}</div>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
{verbs && (
|
{verbs && (
|
||||||
<>
|
<>
|
||||||
<div className="name"><Trans>Verbs</Trans></div>
|
<div className="name">Verbs</div>
|
||||||
<div className="value">{verbs.join(", ")}</div>
|
<div className="value">{verbs.join(", ")}</div>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
{apiGroups && (
|
{apiGroups && (
|
||||||
<>
|
<>
|
||||||
<div className="name"><Trans>Api Groups</Trans></div>
|
<div className="name">Api Groups</div>
|
||||||
<div className="value">
|
<div className="value">
|
||||||
{apiGroups
|
{apiGroups
|
||||||
.map(apiGroup => apiGroup === "" ? `'${apiGroup}'` : apiGroup)
|
.map(apiGroup => apiGroup === "" ? `'${apiGroup}'` : apiGroup)
|
||||||
@ -54,7 +53,7 @@ export class RoleDetails extends React.Component<Props> {
|
|||||||
)}
|
)}
|
||||||
{resourceNames && (
|
{resourceNames && (
|
||||||
<>
|
<>
|
||||||
<div className="name"><Trans>Resource Names</Trans></div>
|
<div className="name">Resource Names</div>
|
||||||
<div className="value">{resourceNames.join(", ")}</div>
|
<div className="value">{resourceNames.join(", ")}</div>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@ -2,7 +2,6 @@ import "./roles.scss";
|
|||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { Trans } from "@lingui/macro";
|
|
||||||
import { RouteComponentProps } from "react-router";
|
import { RouteComponentProps } from "react-router";
|
||||||
import { IRolesRouteParams } from "../+user-management/user-management.route";
|
import { IRolesRouteParams } from "../+user-management/user-management.route";
|
||||||
import { rolesStore } from "./roles.store";
|
import { rolesStore } from "./roles.store";
|
||||||
@ -36,12 +35,12 @@ export class Roles extends React.Component<Props> {
|
|||||||
searchFilters={[
|
searchFilters={[
|
||||||
(role: Role) => role.getSearchFields(),
|
(role: Role) => role.getSearchFields(),
|
||||||
]}
|
]}
|
||||||
renderHeaderTitle={<Trans>Roles</Trans>}
|
renderHeaderTitle="Roles"
|
||||||
renderTableHeader={[
|
renderTableHeader={[
|
||||||
{ title: <Trans>Name</Trans>, className: "name", sortBy: sortBy.name },
|
{ title: "Name", className: "name", sortBy: sortBy.name },
|
||||||
{ className: "warning" },
|
{ className: "warning" },
|
||||||
{ title: <Trans>Namespace</Trans>, className: "namespace", sortBy: sortBy.namespace },
|
{ title: "Namespace", className: "namespace", sortBy: sortBy.namespace },
|
||||||
{ title: <Trans>Age</Trans>, className: "age", sortBy: sortBy.age },
|
{ title: "Age", className: "age", sortBy: sortBy.age },
|
||||||
]}
|
]}
|
||||||
renderTableContents={(role: Role) => [
|
renderTableContents={(role: Role) => [
|
||||||
role.getName(),
|
role.getName(),
|
||||||
@ -51,7 +50,7 @@ export class Roles extends React.Component<Props> {
|
|||||||
]}
|
]}
|
||||||
addRemoveButtons={{
|
addRemoveButtons={{
|
||||||
onAdd: () => AddRoleDialog.open(),
|
onAdd: () => AddRoleDialog.open(),
|
||||||
addTooltip: <Trans>Create new Role</Trans>,
|
addTooltip: "Create new Role",
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<AddRoleDialog/>
|
<AddRoleDialog/>
|
||||||
|
|||||||
@ -3,8 +3,6 @@ import "./create-service-account-dialog.scss";
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { observable } from "mobx";
|
import { observable } from "mobx";
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { t, Trans } from "@lingui/macro";
|
|
||||||
import { _i18n } from "../../i18n";
|
|
||||||
import { Dialog, DialogProps } from "../dialog";
|
import { Dialog, DialogProps } from "../dialog";
|
||||||
import { Wizard, WizardStep } from "../wizard";
|
import { Wizard, WizardStep } from "../wizard";
|
||||||
import { SubTitle } from "../layout/sub-title";
|
import { SubTitle } from "../layout/sub-title";
|
||||||
@ -54,7 +52,7 @@ export class CreateServiceAccountDialog extends React.Component<Props> {
|
|||||||
render() {
|
render() {
|
||||||
const { ...dialogProps } = this.props;
|
const { ...dialogProps } = this.props;
|
||||||
const { name, namespace } = this;
|
const { name, namespace } = this;
|
||||||
const header = <h5><Trans>Create Service Account</Trans></h5>;
|
const header = <h5>Create Service Account</h5>;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog
|
<Dialog
|
||||||
@ -64,15 +62,15 @@ export class CreateServiceAccountDialog extends React.Component<Props> {
|
|||||||
close={this.close}
|
close={this.close}
|
||||||
>
|
>
|
||||||
<Wizard header={header} done={this.close}>
|
<Wizard header={header} done={this.close}>
|
||||||
<WizardStep nextLabel={<Trans>Create</Trans>} next={this.createAccount}>
|
<WizardStep nextLabel="Create" next={this.createAccount}>
|
||||||
<SubTitle title={<Trans>Account Name</Trans>} />
|
<SubTitle title="Account Name" />
|
||||||
<Input
|
<Input
|
||||||
autoFocus required
|
autoFocus required
|
||||||
placeholder={_i18n._(t`Enter a name`)}
|
placeholder={`Enter a name`}
|
||||||
validators={systemName}
|
validators={systemName}
|
||||||
value={name} onChange={v => this.name = v.toLowerCase()}
|
value={name} onChange={v => this.name = v.toLowerCase()}
|
||||||
/>
|
/>
|
||||||
<SubTitle title={<Trans>Namespace</Trans>} />
|
<SubTitle title="Namespace" />
|
||||||
<NamespaceSelect
|
<NamespaceSelect
|
||||||
themeName="light"
|
themeName="light"
|
||||||
value={namespace}
|
value={namespace}
|
||||||
|
|||||||
@ -2,7 +2,6 @@ import "./service-accounts-details.scss";
|
|||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { autorun, observable } from "mobx";
|
import { autorun, observable } from "mobx";
|
||||||
import { Trans } from "@lingui/macro";
|
|
||||||
import { Spinner } from "../spinner";
|
import { Spinner } from "../spinner";
|
||||||
import { ServiceAccountsSecret } from "./service-accounts-secret";
|
import { ServiceAccountsSecret } from "./service-accounts-secret";
|
||||||
import { DrawerItem, DrawerTitle } from "../drawer";
|
import { DrawerItem, DrawerTitle } from "../drawer";
|
||||||
@ -76,7 +75,7 @@ export class ServiceAccountsDetails extends React.Component<Props> {
|
|||||||
{secret.getName()}
|
{secret.getName()}
|
||||||
<Icon
|
<Icon
|
||||||
small material="warning"
|
small material="warning"
|
||||||
tooltip={<Trans>Secret is not found</Trans>}
|
tooltip="Secret is not found"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
@ -120,17 +119,17 @@ export class ServiceAccountsDetails extends React.Component<Props> {
|
|||||||
<KubeObjectMeta object={serviceAccount}/>
|
<KubeObjectMeta object={serviceAccount}/>
|
||||||
|
|
||||||
{tokens.length > 0 &&
|
{tokens.length > 0 &&
|
||||||
<DrawerItem name={<Trans>Tokens</Trans>} className="links">
|
<DrawerItem name="Tokens" className="links">
|
||||||
{this.renderSecretLinks(tokens)}
|
{this.renderSecretLinks(tokens)}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
}
|
}
|
||||||
{imagePullSecrets.length > 0 &&
|
{imagePullSecrets.length > 0 &&
|
||||||
<DrawerItem name={<Trans>ImagePullSecrets</Trans>} className="links">
|
<DrawerItem name="ImagePullSecrets" className="links">
|
||||||
{this.renderImagePullSecrets()}
|
{this.renderImagePullSecrets()}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
}
|
}
|
||||||
|
|
||||||
<DrawerTitle title={<Trans>Mountable secrets</Trans>}/>
|
<DrawerTitle title="Mountable secrets"/>
|
||||||
<div className="secrets">
|
<div className="secrets">
|
||||||
{this.renderSecrets()}
|
{this.renderSecrets()}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -2,7 +2,6 @@ import "./service-accounts-secret.scss";
|
|||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
import { Trans } from "@lingui/macro";
|
|
||||||
import { Icon } from "../icon";
|
import { Icon } from "../icon";
|
||||||
import { Secret } from "../../api/endpoints/secret.api";
|
import { Secret } from "../../api/endpoints/secret.api";
|
||||||
import { prevDefault } from "../../utils";
|
import { prevDefault } from "../../utils";
|
||||||
@ -31,7 +30,7 @@ export class ServiceAccountsSecret extends React.Component<Props, State> {
|
|||||||
<span className="asterisks">{Array(16).fill("•").join("")}</span>
|
<span className="asterisks">{Array(16).fill("•").join("")}</span>
|
||||||
<Icon
|
<Icon
|
||||||
small material="lock_open"
|
small material="lock_open"
|
||||||
tooltip={<Trans>Show value</Trans>}
|
tooltip="Show value"
|
||||||
onClick={prevDefault(() => this.setState({ showToken: true }))}
|
onClick={prevDefault(() => this.setState({ showToken: true }))}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
@ -49,21 +48,21 @@ export class ServiceAccountsSecret extends React.Component<Props, State> {
|
|||||||
return (
|
return (
|
||||||
<div className="ServiceAccountsSecret box grow-fixed">
|
<div className="ServiceAccountsSecret box grow-fixed">
|
||||||
<div className="secret-row">
|
<div className="secret-row">
|
||||||
<span className="name"><Trans>Name</Trans>: </span>
|
<span className="name">Name: </span>
|
||||||
<span className="value">{name}</span>
|
<span className="value">{name}</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="secret-row">
|
<div className="secret-row">
|
||||||
<span className="name"><Trans>Value</Trans>: </span>
|
<span className="name">Value: </span>
|
||||||
<span className="value flex align-center">{this.renderSecretValue()}</span>
|
<span className="value flex align-center">{this.renderSecretValue()}</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="secret-row">
|
<div className="secret-row">
|
||||||
<span className="name"><Trans>Created at</Trans>: </span>
|
<span className="name">Created at: </span>
|
||||||
<span className="value" title={creationTimestamp}>
|
<span className="value" title={creationTimestamp}>
|
||||||
{moment(creationTimestamp).format("LLL")}
|
{moment(creationTimestamp).format("LLL")}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="secret-row">
|
<div className="secret-row">
|
||||||
<span className="name"><Trans>Type</Trans>: </span>
|
<span className="name">Type: </span>
|
||||||
<span className="value">{type}</span>
|
<span className="value">{type}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -2,7 +2,6 @@ import "./service-accounts.scss";
|
|||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { Trans } from "@lingui/macro";
|
|
||||||
import { ServiceAccount } from "../../api/endpoints/service-accounts.api";
|
import { ServiceAccount } from "../../api/endpoints/service-accounts.api";
|
||||||
import { RouteComponentProps } from "react-router";
|
import { RouteComponentProps } from "react-router";
|
||||||
import { KubeObjectMenuProps } from "../kube-object/kube-object-menu";
|
import { KubeObjectMenuProps } from "../kube-object/kube-object-menu";
|
||||||
@ -40,12 +39,12 @@ export class ServiceAccounts extends React.Component<Props> {
|
|||||||
searchFilters={[
|
searchFilters={[
|
||||||
(account: ServiceAccount) => account.getSearchFields(),
|
(account: ServiceAccount) => account.getSearchFields(),
|
||||||
]}
|
]}
|
||||||
renderHeaderTitle={<Trans>Service Accounts</Trans>}
|
renderHeaderTitle="Service Accounts"
|
||||||
renderTableHeader={[
|
renderTableHeader={[
|
||||||
{ title: <Trans>Name</Trans>, className: "name", sortBy: sortBy.name },
|
{ title: "Name", className: "name", sortBy: sortBy.name },
|
||||||
{ className: "warning" },
|
{ className: "warning" },
|
||||||
{ title: <Trans>Namespace</Trans>, className: "namespace", sortBy: sortBy.namespace },
|
{ title: "Namespace", className: "namespace", sortBy: sortBy.namespace },
|
||||||
{ title: <Trans>Age</Trans>, className: "age", sortBy: sortBy.age },
|
{ title: "Age", className: "age", sortBy: sortBy.age },
|
||||||
]}
|
]}
|
||||||
renderTableContents={(account: ServiceAccount) => [
|
renderTableContents={(account: ServiceAccount) => [
|
||||||
account.getName(),
|
account.getName(),
|
||||||
@ -58,7 +57,7 @@ export class ServiceAccounts extends React.Component<Props> {
|
|||||||
}}
|
}}
|
||||||
addRemoveButtons={{
|
addRemoveButtons={{
|
||||||
onAdd: () => CreateServiceAccountDialog.open(),
|
onAdd: () => CreateServiceAccountDialog.open(),
|
||||||
addTooltip: <Trans>Create new Service Account</Trans>,
|
addTooltip: "Create new Service Account",
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<CreateServiceAccountDialog/>
|
<CreateServiceAccountDialog/>
|
||||||
@ -73,7 +72,7 @@ function ServiceAccountMenu(props: KubeObjectMenuProps<ServiceAccount>) {
|
|||||||
return (
|
return (
|
||||||
<MenuItem onClick={() => openServiceAccountKubeConfig(object)}>
|
<MenuItem onClick={() => openServiceAccountKubeConfig(object)}>
|
||||||
<Icon material="insert_drive_file" title="Kubeconfig File" interactive={toolbar}/>
|
<Icon material="insert_drive_file" title="Kubeconfig File" interactive={toolbar}/>
|
||||||
<span className="title"><Trans>Kubeconfig</Trans></span>
|
<span className="title">Kubeconfig</span>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
import "./user-management.scss";
|
import "./user-management.scss";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { Trans } from "@lingui/macro";
|
|
||||||
import { TabLayout, TabLayoutRoute } from "../layout/tab-layout";
|
import { TabLayout, TabLayoutRoute } from "../layout/tab-layout";
|
||||||
import { Roles } from "../+user-management-roles";
|
import { Roles } from "../+user-management-roles";
|
||||||
import { RoleBindings } from "../+user-management-roles-bindings";
|
import { RoleBindings } from "../+user-management-roles-bindings";
|
||||||
@ -19,19 +18,19 @@ export class UserManagement extends React.Component {
|
|||||||
|
|
||||||
tabRoutes.push(
|
tabRoutes.push(
|
||||||
{
|
{
|
||||||
title: <Trans>Service Accounts</Trans>,
|
title: "Service Accounts",
|
||||||
component: ServiceAccounts,
|
component: ServiceAccounts,
|
||||||
url: serviceAccountsURL({ query }),
|
url: serviceAccountsURL({ query }),
|
||||||
routePath: serviceAccountsRoute.path.toString(),
|
routePath: serviceAccountsRoute.path.toString(),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: <Trans>Role Bindings</Trans>,
|
title: "Role Bindings",
|
||||||
component: RoleBindings,
|
component: RoleBindings,
|
||||||
url: roleBindingsURL({ query }),
|
url: roleBindingsURL({ query }),
|
||||||
routePath: roleBindingsRoute.path.toString(),
|
routePath: roleBindingsRoute.path.toString(),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: <Trans>Roles</Trans>,
|
title: "Roles",
|
||||||
component: Roles,
|
component: Roles,
|
||||||
url: rolesURL({ query }),
|
url: rolesURL({ query }),
|
||||||
routePath: rolesRoute.path.toString(),
|
routePath: rolesRoute.path.toString(),
|
||||||
@ -40,7 +39,7 @@ export class UserManagement extends React.Component {
|
|||||||
|
|
||||||
if (isAllowedResource("podsecuritypolicies")) {
|
if (isAllowedResource("podsecuritypolicies")) {
|
||||||
tabRoutes.push({
|
tabRoutes.push({
|
||||||
title: <Trans>Pod Security Policies</Trans>,
|
title: "Pod Security Policies",
|
||||||
component: PodSecurityPolicies,
|
component: PodSecurityPolicies,
|
||||||
url: podSecurityPoliciesURL(),
|
url: podSecurityPoliciesURL(),
|
||||||
routePath: podSecurityPoliciesRoute.path.toString(),
|
routePath: podSecurityPoliciesRoute.path.toString(),
|
||||||
|
|||||||
@ -6,7 +6,6 @@ import { observer } from "mobx-react";
|
|||||||
import { userStore } from "../../../common/user-store";
|
import { userStore } from "../../../common/user-store";
|
||||||
import { navigate } from "../../navigation";
|
import { navigate } from "../../navigation";
|
||||||
import { Button } from "../button";
|
import { Button } from "../button";
|
||||||
import { Trans } from "@lingui/macro";
|
|
||||||
import marked from "marked";
|
import marked from "marked";
|
||||||
|
|
||||||
@observer
|
@observer
|
||||||
@ -34,7 +33,7 @@ export class WhatsNew extends React.Component {
|
|||||||
<div className="bottom">
|
<div className="bottom">
|
||||||
<Button
|
<Button
|
||||||
primary autoFocus
|
primary autoFocus
|
||||||
label={<Trans>Ok, got it!</Trans>}
|
label="Ok, got it!"
|
||||||
onClick={this.ok}
|
onClick={this.ok}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -3,7 +3,6 @@ import "./cronjob-details.scss";
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import kebabCase from "lodash/kebabCase";
|
import kebabCase from "lodash/kebabCase";
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { Trans } from "@lingui/macro";
|
|
||||||
import { DrawerItem, DrawerTitle } from "../drawer";
|
import { DrawerItem, DrawerTitle } from "../drawer";
|
||||||
import { Badge } from "../badge/badge";
|
import { Badge } from "../badge/badge";
|
||||||
import { jobStore } from "../+workloads-jobs/job.store";
|
import { jobStore } from "../+workloads-jobs/job.store";
|
||||||
@ -35,25 +34,25 @@ export class CronJobDetails extends React.Component<Props> {
|
|||||||
return (
|
return (
|
||||||
<div className="CronJobDetails">
|
<div className="CronJobDetails">
|
||||||
<KubeObjectMeta object={cronJob}/>
|
<KubeObjectMeta object={cronJob}/>
|
||||||
<DrawerItem name={<Trans>Schedule</Trans>}>
|
<DrawerItem name="Schedule">
|
||||||
{cronJob.isNeverRun() ? (
|
{cronJob.isNeverRun() ? (
|
||||||
<>
|
<>
|
||||||
<Trans>never</Trans> ({cronJob.getSchedule()})
|
never ({cronJob.getSchedule()})
|
||||||
</>
|
</>
|
||||||
) : cronJob.getSchedule()}
|
) : cronJob.getSchedule()}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
<DrawerItem name={<Trans>Active</Trans>}>
|
<DrawerItem name="Active">
|
||||||
{cronJobStore.getActiveJobsNum(cronJob)}
|
{cronJobStore.getActiveJobsNum(cronJob)}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
<DrawerItem name={<Trans>Suspend</Trans>}>
|
<DrawerItem name="Suspend">
|
||||||
{cronJob.getSuspendFlag()}
|
{cronJob.getSuspendFlag()}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
<DrawerItem name={<Trans>Last schedule</Trans>}>
|
<DrawerItem name="Last schedule">
|
||||||
{cronJob.getLastScheduleTime()}
|
{cronJob.getLastScheduleTime()}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
{childJobs.length > 0 &&
|
{childJobs.length > 0 &&
|
||||||
<>
|
<>
|
||||||
<DrawerTitle title={<Trans>Jobs</Trans>}/>
|
<DrawerTitle title="Jobs"/>
|
||||||
{childJobs.map((job: Job) => {
|
{childJobs.map((job: Job) => {
|
||||||
const selectors = job.getSelectors();
|
const selectors = job.getSelectors();
|
||||||
const condition = job.getCondition();
|
const condition = job.getCondition();
|
||||||
@ -65,7 +64,7 @@ export class CronJobDetails extends React.Component<Props> {
|
|||||||
{job.getName()}
|
{job.getName()}
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
<DrawerItem name={<Trans>Condition</Trans>} className="conditions" labelsOnly>
|
<DrawerItem name="Condition" className="conditions" labelsOnly>
|
||||||
{condition && (
|
{condition && (
|
||||||
<Badge
|
<Badge
|
||||||
label={condition.type}
|
label={condition.type}
|
||||||
@ -73,7 +72,7 @@ export class CronJobDetails extends React.Component<Props> {
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
<DrawerItem name={<Trans>Selector</Trans>} labelsOnly>
|
<DrawerItem name="Selector" labelsOnly>
|
||||||
{
|
{
|
||||||
selectors.map(label => <Badge key={label} label={label}/>)
|
selectors.map(label => <Badge key={label} label={label}/>)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,7 +3,6 @@ import "./cronjob-trigger-dialog.scss";
|
|||||||
import React, { Component } from "react";
|
import React, { Component } from "react";
|
||||||
import { observable } from "mobx";
|
import { observable } from "mobx";
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { Trans } from "@lingui/macro";
|
|
||||||
import { Dialog, DialogProps } from "../dialog";
|
import { Dialog, DialogProps } from "../dialog";
|
||||||
import { Wizard, WizardStep } from "../wizard";
|
import { Wizard, WizardStep } from "../wizard";
|
||||||
import { CronJob, cronJobApi, jobApi } from "../../api/endpoints";
|
import { CronJob, cronJobApi, jobApi } from "../../api/endpoints";
|
||||||
@ -80,7 +79,7 @@ export class CronJobTriggerDialog extends Component<Props> {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="flex gaps">
|
<div className="flex gaps">
|
||||||
<Trans>Job name</Trans>:
|
Job name:
|
||||||
</div>
|
</div>
|
||||||
<div className="flex gaps">
|
<div className="flex gaps">
|
||||||
<Input
|
<Input
|
||||||
@ -101,7 +100,7 @@ export class CronJobTriggerDialog extends Component<Props> {
|
|||||||
const cronjobName = this.cronjob ? this.cronjob.getName() : "";
|
const cronjobName = this.cronjob ? this.cronjob.getName() : "";
|
||||||
const header = (
|
const header = (
|
||||||
<h5>
|
<h5>
|
||||||
<Trans>Trigger CronJob <span>{cronjobName}</span></Trans>
|
Trigger CronJob <span>{cronjobName}</span>
|
||||||
</h5>
|
</h5>
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -118,7 +117,7 @@ export class CronJobTriggerDialog extends Component<Props> {
|
|||||||
<WizardStep
|
<WizardStep
|
||||||
contentClass="flex gaps column"
|
contentClass="flex gaps column"
|
||||||
next={this.trigger}
|
next={this.trigger}
|
||||||
nextLabel={<Trans>Trigger</Trans>}
|
nextLabel="Trigger"
|
||||||
disabledNext={!this.ready}
|
disabledNext={!this.ready}
|
||||||
>
|
>
|
||||||
{this.renderContents()}
|
{this.renderContents()}
|
||||||
|
|||||||
@ -3,7 +3,6 @@ import "./cronjobs.scss";
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { RouteComponentProps } from "react-router";
|
import { RouteComponentProps } from "react-router";
|
||||||
import { t, Trans } from "@lingui/macro";
|
|
||||||
import { CronJob } from "../../api/endpoints/cron-job.api";
|
import { CronJob } from "../../api/endpoints/cron-job.api";
|
||||||
import { MenuItem } from "../menu";
|
import { MenuItem } from "../menu";
|
||||||
import { Icon } from "../icon";
|
import { Icon } from "../icon";
|
||||||
@ -13,7 +12,6 @@ import { eventStore } from "../+events/event.store";
|
|||||||
import { KubeObjectMenuProps } from "../kube-object/kube-object-menu";
|
import { KubeObjectMenuProps } from "../kube-object/kube-object-menu";
|
||||||
import { ICronJobsRouteParams } from "../+workloads";
|
import { ICronJobsRouteParams } from "../+workloads";
|
||||||
import { KubeObjectListLayout } from "../kube-object";
|
import { KubeObjectListLayout } from "../kube-object";
|
||||||
import { _i18n } from "../../i18n";
|
|
||||||
import { CronJobTriggerDialog } from "./cronjob-trigger-dialog";
|
import { CronJobTriggerDialog } from "./cronjob-trigger-dialog";
|
||||||
import { kubeObjectMenuRegistry } from "../../../extensions/registries/kube-object-menu-registry";
|
import { kubeObjectMenuRegistry } from "../../../extensions/registries/kube-object-menu-registry";
|
||||||
import { KubeObjectStatusIcon } from "../kube-object-status-icon";
|
import { KubeObjectStatusIcon } from "../kube-object-status-icon";
|
||||||
@ -49,22 +47,22 @@ export class CronJobs extends React.Component<Props> {
|
|||||||
(cronJob: CronJob) => cronJob.getSearchFields(),
|
(cronJob: CronJob) => cronJob.getSearchFields(),
|
||||||
(cronJob: CronJob) => cronJob.getSchedule(),
|
(cronJob: CronJob) => cronJob.getSchedule(),
|
||||||
]}
|
]}
|
||||||
renderHeaderTitle={<Trans>Cron Jobs</Trans>}
|
renderHeaderTitle="Cron Jobs"
|
||||||
renderTableHeader={[
|
renderTableHeader={[
|
||||||
{ title: <Trans>Name</Trans>, className: "name", sortBy: sortBy.name },
|
{ title: "Name", className: "name", sortBy: sortBy.name },
|
||||||
{ className: "warning" },
|
{ className: "warning" },
|
||||||
{ title: <Trans>Namespace</Trans>, className: "namespace", sortBy: sortBy.namespace },
|
{ title: "Namespace", className: "namespace", sortBy: sortBy.namespace },
|
||||||
{ title: <Trans>Schedule</Trans>, className: "schedule" },
|
{ title: "Schedule", className: "schedule" },
|
||||||
{ title: <Trans>Suspend</Trans>, className: "suspend", sortBy: sortBy.suspend },
|
{ title: "Suspend", className: "suspend", sortBy: sortBy.suspend },
|
||||||
{ title: <Trans>Active</Trans>, className: "active", sortBy: sortBy.active },
|
{ title: "Active", className: "active", sortBy: sortBy.active },
|
||||||
{ title: <Trans>Last schedule</Trans>, className: "last-schedule", sortBy: sortBy.lastSchedule },
|
{ title: "Last schedule", className: "last-schedule", sortBy: sortBy.lastSchedule },
|
||||||
{ title: <Trans>Age</Trans>, className: "age", sortBy: sortBy.age },
|
{ title: "Age", className: "age", sortBy: sortBy.age },
|
||||||
]}
|
]}
|
||||||
renderTableContents={(cronJob: CronJob) => [
|
renderTableContents={(cronJob: CronJob) => [
|
||||||
cronJob.getName(),
|
cronJob.getName(),
|
||||||
<KubeObjectStatusIcon key="icon" object={cronJob} />,
|
<KubeObjectStatusIcon key="icon" object={cronJob} />,
|
||||||
cronJob.getNs(),
|
cronJob.getNs(),
|
||||||
cronJob.isNeverRun() ? <Trans>never</Trans> : cronJob.getSchedule(),
|
cronJob.isNeverRun() ? "never" : cronJob.getSchedule(),
|
||||||
cronJob.getSuspendFlag(),
|
cronJob.getSuspendFlag(),
|
||||||
cronJobStore.getActiveJobsNum(cronJob),
|
cronJobStore.getActiveJobsNum(cronJob),
|
||||||
cronJob.getLastScheduleTime(),
|
cronJob.getLastScheduleTime(),
|
||||||
@ -83,8 +81,8 @@ export function CronJobMenu(props: KubeObjectMenuProps<CronJob>) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<MenuItem onClick={() => CronJobTriggerDialog.open(object)}>
|
<MenuItem onClick={() => CronJobTriggerDialog.open(object)}>
|
||||||
<Icon material="play_circle_filled" title={_i18n._(t`Trigger`)} interactive={toolbar}/>
|
<Icon material="play_circle_filled" title={`Trigger`} interactive={toolbar}/>
|
||||||
<span className="title"><Trans>Trigger</Trans></span>
|
<span className="title">Trigger</span>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,7 +2,6 @@ import "./daemonset-details.scss";
|
|||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { disposeOnUnmount, observer } from "mobx-react";
|
import { disposeOnUnmount, observer } from "mobx-react";
|
||||||
import { Trans } from "@lingui/macro";
|
|
||||||
import { DrawerItem } from "../drawer";
|
import { DrawerItem } from "../drawer";
|
||||||
import { Badge } from "../badge";
|
import { Badge } from "../badge";
|
||||||
import { PodDetailsStatuses } from "../+workloads-pods/pod-details-statuses";
|
import { PodDetailsStatuses } from "../+workloads-pods/pod-details-statuses";
|
||||||
@ -63,32 +62,32 @@ export class DaemonSetDetails extends React.Component<Props> {
|
|||||||
)}
|
)}
|
||||||
<KubeObjectMeta object={daemonSet}/>
|
<KubeObjectMeta object={daemonSet}/>
|
||||||
{selectors.length > 0 &&
|
{selectors.length > 0 &&
|
||||||
<DrawerItem name={<Trans>Selector</Trans>} labelsOnly>
|
<DrawerItem name="Selector" labelsOnly>
|
||||||
{
|
{
|
||||||
selectors.map(label => <Badge key={label} label={label}/>)
|
selectors.map(label => <Badge key={label} label={label}/>)
|
||||||
}
|
}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
}
|
}
|
||||||
{nodeSelector.length > 0 &&
|
{nodeSelector.length > 0 &&
|
||||||
<DrawerItem name={<Trans>Node Selector</Trans>} labelsOnly>
|
<DrawerItem name="Node Selector" labelsOnly>
|
||||||
{
|
{
|
||||||
nodeSelector.map(label => (<Badge key={label} label={label}/>))
|
nodeSelector.map(label => (<Badge key={label} label={label}/>))
|
||||||
}
|
}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
}
|
}
|
||||||
{images.length > 0 &&
|
{images.length > 0 &&
|
||||||
<DrawerItem name={<Trans>Images</Trans>}>
|
<DrawerItem name="Images">
|
||||||
{
|
{
|
||||||
images.map(image => <p key={image}>{image}</p>)
|
images.map(image => <p key={image}>{image}</p>)
|
||||||
}
|
}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
}
|
}
|
||||||
<DrawerItem name={<Trans>Strategy Type</Trans>}>
|
<DrawerItem name="Strategy Type">
|
||||||
{spec.updateStrategy.type}
|
{spec.updateStrategy.type}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
<PodDetailsTolerations workload={daemonSet}/>
|
<PodDetailsTolerations workload={daemonSet}/>
|
||||||
<PodDetailsAffinities workload={daemonSet}/>
|
<PodDetailsAffinities workload={daemonSet}/>
|
||||||
<DrawerItem name={<Trans>Pod Status</Trans>} className="pod-status">
|
<DrawerItem name="Pod Status" className="pod-status">
|
||||||
<PodDetailsStatuses pods={childPods}/>
|
<PodDetailsStatuses pods={childPods}/>
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
<ResourceMetricsText metrics={metrics}/>
|
<ResourceMetricsText metrics={metrics}/>
|
||||||
|
|||||||
@ -10,7 +10,6 @@ import { podsStore } from "../+workloads-pods/pods.store";
|
|||||||
import { nodesStore } from "../+nodes/nodes.store";
|
import { nodesStore } from "../+nodes/nodes.store";
|
||||||
import { KubeObjectListLayout } from "../kube-object";
|
import { KubeObjectListLayout } from "../kube-object";
|
||||||
import { IDaemonSetsRouteParams } from "../+workloads";
|
import { IDaemonSetsRouteParams } from "../+workloads";
|
||||||
import { Trans } from "@lingui/macro";
|
|
||||||
import { Badge } from "../badge";
|
import { Badge } from "../badge";
|
||||||
import { KubeObjectStatusIcon } from "../kube-object-status-icon";
|
import { KubeObjectStatusIcon } from "../kube-object-status-icon";
|
||||||
|
|
||||||
@ -51,14 +50,14 @@ export class DaemonSets extends React.Component<Props> {
|
|||||||
(daemonSet: DaemonSet) => daemonSet.getSearchFields(),
|
(daemonSet: DaemonSet) => daemonSet.getSearchFields(),
|
||||||
(daemonSet: DaemonSet) => daemonSet.getLabels(),
|
(daemonSet: DaemonSet) => daemonSet.getLabels(),
|
||||||
]}
|
]}
|
||||||
renderHeaderTitle={<Trans>Daemon Sets</Trans>}
|
renderHeaderTitle="Daemon Sets"
|
||||||
renderTableHeader={[
|
renderTableHeader={[
|
||||||
{ title: <Trans>Name</Trans>, className: "name", sortBy: sortBy.name },
|
{ title: "Name", className: "name", sortBy: sortBy.name },
|
||||||
{ title: <Trans>Namespace</Trans>, className: "namespace", sortBy: sortBy.namespace },
|
{ title: "Namespace", className: "namespace", sortBy: sortBy.namespace },
|
||||||
{ title: <Trans>Pods</Trans>, className: "pods", sortBy: sortBy.pods },
|
{ title: "Pods", className: "pods", sortBy: sortBy.pods },
|
||||||
{ className: "warning" },
|
{ className: "warning" },
|
||||||
{ title: <Trans>Node Selector</Trans>, className: "labels" },
|
{ title: "Node Selector", className: "labels" },
|
||||||
{ title: <Trans>Age</Trans>, className: "age", sortBy: sortBy.age },
|
{ title: "Age", className: "age", sortBy: sortBy.age },
|
||||||
]}
|
]}
|
||||||
renderTableContents={(daemonSet: DaemonSet) => [
|
renderTableContents={(daemonSet: DaemonSet) => [
|
||||||
daemonSet.getName(),
|
daemonSet.getName(),
|
||||||
|
|||||||
@ -3,7 +3,6 @@ import "./deployment-details.scss";
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import kebabCase from "lodash/kebabCase";
|
import kebabCase from "lodash/kebabCase";
|
||||||
import { disposeOnUnmount, observer } from "mobx-react";
|
import { disposeOnUnmount, observer } from "mobx-react";
|
||||||
import { t, Trans } from "@lingui/macro";
|
|
||||||
import { DrawerItem } from "../drawer";
|
import { DrawerItem } from "../drawer";
|
||||||
import { Badge } from "../badge";
|
import { Badge } from "../badge";
|
||||||
import { Deployment } from "../../api/endpoints";
|
import { Deployment } from "../../api/endpoints";
|
||||||
@ -13,7 +12,6 @@ import { PodDetailsAffinities } from "../+workloads-pods/pod-details-affinities"
|
|||||||
import { KubeEventDetails } from "../+events/kube-event-details";
|
import { KubeEventDetails } from "../+events/kube-event-details";
|
||||||
import { podsStore } from "../+workloads-pods/pods.store";
|
import { podsStore } from "../+workloads-pods/pods.store";
|
||||||
import { KubeObjectDetailsProps } from "../kube-object";
|
import { KubeObjectDetailsProps } from "../kube-object";
|
||||||
import { _i18n } from "../../i18n";
|
|
||||||
import { ResourceMetrics, ResourceMetricsText } from "../resource-metrics";
|
import { ResourceMetrics, ResourceMetricsText } from "../resource-metrics";
|
||||||
import { deploymentStore } from "./deployments.store";
|
import { deploymentStore } from "./deployments.store";
|
||||||
import { PodCharts, podMetricTabs } from "../+workloads-pods/pod-charts";
|
import { PodCharts, podMetricTabs } from "../+workloads-pods/pod-charts";
|
||||||
@ -63,20 +61,20 @@ export class DeploymentDetails extends React.Component<Props> {
|
|||||||
</ResourceMetrics>
|
</ResourceMetrics>
|
||||||
)}
|
)}
|
||||||
<KubeObjectMeta object={deployment}/>
|
<KubeObjectMeta object={deployment}/>
|
||||||
<DrawerItem name={<Trans>Replicas</Trans>}>
|
<DrawerItem name="Replicas">
|
||||||
{_i18n._(t`${spec.replicas} desired, ${status.updatedReplicas || 0} updated`)},{" "}
|
{`${spec.replicas} desired, ${status.updatedReplicas || 0} updated`},{" "}
|
||||||
{_i18n._(t`${status.replicas || 0} total, ${status.availableReplicas || 0} available`)},{" "}
|
{`${status.replicas || 0} total, ${status.availableReplicas || 0} available`},{" "}
|
||||||
{_i18n._(t`${status.unavailableReplicas || 0} unavailable`)}
|
{`${status.unavailableReplicas || 0} unavailable`}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
{selectors.length > 0 &&
|
{selectors.length > 0 &&
|
||||||
<DrawerItem name={<Trans>Selector</Trans>} labelsOnly>
|
<DrawerItem name="Selector" labelsOnly>
|
||||||
{
|
{
|
||||||
selectors.map(label => <Badge key={label} label={label}/>)
|
selectors.map(label => <Badge key={label} label={label}/>)
|
||||||
}
|
}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
}
|
}
|
||||||
{nodeSelector.length > 0 &&
|
{nodeSelector.length > 0 &&
|
||||||
<DrawerItem name={<Trans>Node Selector</Trans>}>
|
<DrawerItem name="Node Selector">
|
||||||
{
|
{
|
||||||
nodeSelector.map(label => (
|
nodeSelector.map(label => (
|
||||||
<Badge key={label} label={label}/>
|
<Badge key={label} label={label}/>
|
||||||
@ -84,10 +82,10 @@ export class DeploymentDetails extends React.Component<Props> {
|
|||||||
}
|
}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
}
|
}
|
||||||
<DrawerItem name={<Trans>Strategy Type</Trans>}>
|
<DrawerItem name="Strategy Type">
|
||||||
{spec.strategy.type}
|
{spec.strategy.type}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
<DrawerItem name={<Trans>Conditions</Trans>} className="conditions" labelsOnly>
|
<DrawerItem name="Conditions" className="conditions" labelsOnly>
|
||||||
{
|
{
|
||||||
deployment.getConditions().map(condition => {
|
deployment.getConditions().map(condition => {
|
||||||
const { type, message, lastTransitionTime, status } = condition;
|
const { type, message, lastTransitionTime, status } = condition;
|
||||||
@ -100,7 +98,7 @@ export class DeploymentDetails extends React.Component<Props> {
|
|||||||
tooltip={(
|
tooltip={(
|
||||||
<>
|
<>
|
||||||
<p>{message}</p>
|
<p>{message}</p>
|
||||||
<p><Trans>Last transition time: {lastTransitionTime}</Trans></p>
|
<p>Last transition time: {lastTransitionTime}</p>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@ -3,7 +3,6 @@ import "./deployment-scale-dialog.scss";
|
|||||||
import React, { Component } from "react";
|
import React, { Component } from "react";
|
||||||
import { computed, observable } from "mobx";
|
import { computed, observable } from "mobx";
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { Trans } from "@lingui/macro";
|
|
||||||
import { Dialog, DialogProps } from "../dialog";
|
import { Dialog, DialogProps } from "../dialog";
|
||||||
import { Wizard, WizardStep } from "../wizard";
|
import { Wizard, WizardStep } from "../wizard";
|
||||||
import { Deployment, deploymentApi } from "../../api/endpoints";
|
import { Deployment, deploymentApi } from "../../api/endpoints";
|
||||||
@ -101,11 +100,11 @@ export class DeploymentScaleDialog extends Component<Props> {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="current-scale" data-testid="current-scale">
|
<div className="current-scale" data-testid="current-scale">
|
||||||
<Trans>Current replica scale: {currentReplicas}</Trans>
|
Current replica scale: {currentReplicas}
|
||||||
</div>
|
</div>
|
||||||
<div className="flex gaps align-center">
|
<div className="flex gaps align-center">
|
||||||
<div className="desired-scale" data-testid="desired-scale">
|
<div className="desired-scale" data-testid="desired-scale">
|
||||||
<Trans>Desired number of replicas</Trans>: {desiredReplicas}
|
Desired number of replicas: {desiredReplicas}
|
||||||
</div>
|
</div>
|
||||||
<div className="slider-container flex align-center">
|
<div className="slider-container flex align-center">
|
||||||
<Slider value={desiredReplicas} max={scaleMax} onChange={onChange as any /** see: https://github.com/mui-org/material-ui/issues/20191 */}/>
|
<Slider value={desiredReplicas} max={scaleMax} onChange={onChange as any /** see: https://github.com/mui-org/material-ui/issues/20191 */}/>
|
||||||
@ -126,7 +125,7 @@ export class DeploymentScaleDialog extends Component<Props> {
|
|||||||
{warning &&
|
{warning &&
|
||||||
<div className="warning" data-testid="warning">
|
<div className="warning" data-testid="warning">
|
||||||
<Icon material="warning"/>
|
<Icon material="warning"/>
|
||||||
<Trans>High number of replicas may cause cluster performance issues</Trans>
|
High number of replicas may cause cluster performance issues
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
</>
|
</>
|
||||||
@ -138,7 +137,7 @@ export class DeploymentScaleDialog extends Component<Props> {
|
|||||||
const deploymentName = this.deployment ? this.deployment.getName() : "";
|
const deploymentName = this.deployment ? this.deployment.getName() : "";
|
||||||
const header = (
|
const header = (
|
||||||
<h5>
|
<h5>
|
||||||
<Trans>Scale Deployment <span>{deploymentName}</span></Trans>
|
Scale Deployment <span>{deploymentName}</span>
|
||||||
</h5>
|
</h5>
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -155,7 +154,7 @@ export class DeploymentScaleDialog extends Component<Props> {
|
|||||||
<WizardStep
|
<WizardStep
|
||||||
contentClass="flex gaps column"
|
contentClass="flex gaps column"
|
||||||
next={this.scale}
|
next={this.scale}
|
||||||
nextLabel={<Trans>Scale</Trans>}
|
nextLabel="Scale"
|
||||||
disabledNext={!this.ready}
|
disabledNext={!this.ready}
|
||||||
>
|
>
|
||||||
{this.renderContents()}
|
{this.renderContents()}
|
||||||
|
|||||||
@ -3,7 +3,6 @@ import "./deployments.scss";
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { RouteComponentProps } from "react-router";
|
import { RouteComponentProps } from "react-router";
|
||||||
import { t, Trans } from "@lingui/macro";
|
|
||||||
import { Deployment, deploymentApi } from "../../api/endpoints";
|
import { Deployment, deploymentApi } from "../../api/endpoints";
|
||||||
import { KubeObjectMenuProps } from "../kube-object/kube-object-menu";
|
import { KubeObjectMenuProps } from "../kube-object/kube-object-menu";
|
||||||
import { MenuItem } from "../menu";
|
import { MenuItem } from "../menu";
|
||||||
@ -17,7 +16,6 @@ import { nodesStore } from "../+nodes/nodes.store";
|
|||||||
import { eventStore } from "../+events/event.store";
|
import { eventStore } from "../+events/event.store";
|
||||||
import { KubeObjectListLayout } from "../kube-object";
|
import { KubeObjectListLayout } from "../kube-object";
|
||||||
import { IDeploymentsRouteParams } from "../+workloads";
|
import { IDeploymentsRouteParams } from "../+workloads";
|
||||||
import { _i18n } from "../../i18n";
|
|
||||||
import { cssNames } from "../../utils";
|
import { cssNames } from "../../utils";
|
||||||
import kebabCase from "lodash/kebabCase";
|
import kebabCase from "lodash/kebabCase";
|
||||||
import orderBy from "lodash/orderBy";
|
import orderBy from "lodash/orderBy";
|
||||||
@ -70,15 +68,15 @@ export class Deployments extends React.Component<Props> {
|
|||||||
(deployment: Deployment) => deployment.getSearchFields(),
|
(deployment: Deployment) => deployment.getSearchFields(),
|
||||||
(deployment: Deployment) => deployment.getConditionsText(),
|
(deployment: Deployment) => deployment.getConditionsText(),
|
||||||
]}
|
]}
|
||||||
renderHeaderTitle={<Trans>Deployments</Trans>}
|
renderHeaderTitle="Deployments"
|
||||||
renderTableHeader={[
|
renderTableHeader={[
|
||||||
{ title: <Trans>Name</Trans>, className: "name", sortBy: sortBy.name },
|
{ title: "Name", className: "name", sortBy: sortBy.name },
|
||||||
{ className: "warning" },
|
{ className: "warning" },
|
||||||
{ title: <Trans>Namespace</Trans>, className: "namespace", sortBy: sortBy.namespace },
|
{ title: "Namespace", className: "namespace", sortBy: sortBy.namespace },
|
||||||
{ title: <Trans>Pods</Trans>, className: "pods" },
|
{ title: "Pods", className: "pods" },
|
||||||
{ title: <Trans>Replicas</Trans>, className: "replicas", sortBy: sortBy.replicas },
|
{ title: "Replicas", className: "replicas", sortBy: sortBy.replicas },
|
||||||
{ title: <Trans>Age</Trans>, className: "age", sortBy: sortBy.age },
|
{ title: "Age", className: "age", sortBy: sortBy.age },
|
||||||
{ title: <Trans>Conditions</Trans>, className: "conditions", sortBy: sortBy.condition },
|
{ title: "Conditions", className: "conditions", sortBy: sortBy.condition },
|
||||||
]}
|
]}
|
||||||
renderTableContents={(deployment: Deployment) => [
|
renderTableContents={(deployment: Deployment) => [
|
||||||
deployment.getName(),
|
deployment.getName(),
|
||||||
@ -103,8 +101,8 @@ export function DeploymentMenu(props: KubeObjectMenuProps<Deployment>) {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<MenuItem onClick={() => DeploymentScaleDialog.open(object)}>
|
<MenuItem onClick={() => DeploymentScaleDialog.open(object)}>
|
||||||
<Icon material="open_with" title={_i18n._(t`Scale`)} interactive={toolbar}/>
|
<Icon material="open_with" title={`Scale`} interactive={toolbar}/>
|
||||||
<span className="title"><Trans>Scale</Trans></span>
|
<span className="title">Scale</span>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem onClick={() => ConfirmDialog.open({
|
<MenuItem onClick={() => ConfirmDialog.open({
|
||||||
ok: async () =>
|
ok: async () =>
|
||||||
@ -118,15 +116,15 @@ export function DeploymentMenu(props: KubeObjectMenuProps<Deployment>) {
|
|||||||
Notifications.error(err);
|
Notifications.error(err);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
labelOk: _i18n._(t`Restart`),
|
labelOk: `Restart`,
|
||||||
message: (
|
message: (
|
||||||
<p>
|
<p>
|
||||||
<Trans>Are you sure you want to restart deployment <b>{object.getName()}</b>?</Trans>
|
Are you sure you want to restart deployment <b>{object.getName()}</b>?
|
||||||
</p>
|
</p>
|
||||||
),
|
),
|
||||||
})}>
|
})}>
|
||||||
<Icon material="autorenew" title={_i18n._(t`Restart`)} interactive={toolbar}/>
|
<Icon material="autorenew" title={`Restart`} interactive={toolbar}/>
|
||||||
<span className="title"><Trans>Restart</Trans></span>
|
<span className="title">Restart</span>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -3,7 +3,6 @@ import "./job-details.scss";
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import kebabCase from "lodash/kebabCase";
|
import kebabCase from "lodash/kebabCase";
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { Trans } from "@lingui/macro";
|
|
||||||
import { DrawerItem } from "../drawer";
|
import { DrawerItem } from "../drawer";
|
||||||
import { Badge } from "../badge";
|
import { Badge } from "../badge";
|
||||||
import { PodDetailsStatuses } from "../+workloads-pods/pod-details-statuses";
|
import { PodDetailsStatuses } from "../+workloads-pods/pod-details-statuses";
|
||||||
@ -45,13 +44,13 @@ export class JobDetails extends React.Component<Props> {
|
|||||||
return (
|
return (
|
||||||
<div className="JobDetails">
|
<div className="JobDetails">
|
||||||
<KubeObjectMeta object={job}/>
|
<KubeObjectMeta object={job}/>
|
||||||
<DrawerItem name={<Trans>Selector</Trans>} labelsOnly>
|
<DrawerItem name="Selector" labelsOnly>
|
||||||
{
|
{
|
||||||
Object.keys(selectors).map(label => <Badge key={label} label={label}/>)
|
Object.keys(selectors).map(label => <Badge key={label} label={label}/>)
|
||||||
}
|
}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
{nodeSelector.length > 0 &&
|
{nodeSelector.length > 0 &&
|
||||||
<DrawerItem name={<Trans>Node Selector</Trans>} labelsOnly>
|
<DrawerItem name="Node Selector" labelsOnly>
|
||||||
{
|
{
|
||||||
nodeSelector.map(label => (
|
nodeSelector.map(label => (
|
||||||
<Badge key={label} label={label}/>
|
<Badge key={label} label={label}/>
|
||||||
@ -60,14 +59,14 @@ export class JobDetails extends React.Component<Props> {
|
|||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
}
|
}
|
||||||
{images.length > 0 &&
|
{images.length > 0 &&
|
||||||
<DrawerItem name={<Trans>Images</Trans>}>
|
<DrawerItem name="Images">
|
||||||
{
|
{
|
||||||
images.map(image => <p key={image}>{image}</p>)
|
images.map(image => <p key={image}>{image}</p>)
|
||||||
}
|
}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
}
|
}
|
||||||
{ownerRefs.length > 0 &&
|
{ownerRefs.length > 0 &&
|
||||||
<DrawerItem name={<Trans>Controlled by</Trans>}>
|
<DrawerItem name="Controlled by">
|
||||||
{
|
{
|
||||||
ownerRefs.map(ref => {
|
ownerRefs.map(ref => {
|
||||||
const { name, kind } = ref;
|
const { name, kind } = ref;
|
||||||
@ -82,7 +81,7 @@ export class JobDetails extends React.Component<Props> {
|
|||||||
}
|
}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
}
|
}
|
||||||
<DrawerItem name={<Trans>Conditions</Trans>} className="conditions" labelsOnly>
|
<DrawerItem name="Conditions" className="conditions" labelsOnly>
|
||||||
{condition && (
|
{condition && (
|
||||||
<Badge
|
<Badge
|
||||||
className={kebabCase(condition.type)}
|
className={kebabCase(condition.type)}
|
||||||
@ -91,15 +90,15 @@ export class JobDetails extends React.Component<Props> {
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
<DrawerItem name={<Trans>Completions</Trans>}>
|
<DrawerItem name="Completions">
|
||||||
{job.getDesiredCompletions()}
|
{job.getDesiredCompletions()}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
<DrawerItem name={<Trans>Parallelism</Trans>}>
|
<DrawerItem name="Parallelism">
|
||||||
{job.getParallelism()}
|
{job.getParallelism()}
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
<PodDetailsTolerations workload={job}/>
|
<PodDetailsTolerations workload={job}/>
|
||||||
<PodDetailsAffinities workload={job}/>
|
<PodDetailsAffinities workload={job}/>
|
||||||
<DrawerItem name={<Trans>Pod Status</Trans>} className="pod-status">
|
<DrawerItem name="Pod Status" className="pod-status">
|
||||||
<PodDetailsStatuses pods={childPods}/>
|
<PodDetailsStatuses pods={childPods}/>
|
||||||
</DrawerItem>
|
</DrawerItem>
|
||||||
<PodDetailsList pods={childPods} owner={job}/>
|
<PodDetailsList pods={childPods} owner={job}/>
|
||||||
|
|||||||
@ -3,7 +3,6 @@ import "./jobs.scss";
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { RouteComponentProps } from "react-router";
|
import { RouteComponentProps } from "react-router";
|
||||||
import { Trans } from "@lingui/macro";
|
|
||||||
import { podsStore } from "../+workloads-pods/pods.store";
|
import { podsStore } from "../+workloads-pods/pods.store";
|
||||||
import { jobStore } from "./job.store";
|
import { jobStore } from "./job.store";
|
||||||
import { eventStore } from "../+events/event.store";
|
import { eventStore } from "../+events/event.store";
|
||||||
@ -39,14 +38,14 @@ export class Jobs extends React.Component<Props> {
|
|||||||
searchFilters={[
|
searchFilters={[
|
||||||
(job: Job) => job.getSearchFields(),
|
(job: Job) => job.getSearchFields(),
|
||||||
]}
|
]}
|
||||||
renderHeaderTitle={<Trans>Jobs</Trans>}
|
renderHeaderTitle="Jobs"
|
||||||
renderTableHeader={[
|
renderTableHeader={[
|
||||||
{ title: <Trans>Name</Trans>, className: "name", sortBy: sortBy.name },
|
{ title: "Name", className: "name", sortBy: sortBy.name },
|
||||||
{ title: <Trans>Namespace</Trans>, className: "namespace", sortBy: sortBy.namespace },
|
{ title: "Namespace", className: "namespace", sortBy: sortBy.namespace },
|
||||||
{ title: <Trans>Completions</Trans>, className: "completions" },
|
{ title: "Completions", className: "completions" },
|
||||||
{ className: "warning" },
|
{ className: "warning" },
|
||||||
{ title: <Trans>Age</Trans>, className: "age", sortBy: sortBy.age },
|
{ title: "Age", className: "age", sortBy: sortBy.age },
|
||||||
{ title: <Trans>Conditions</Trans>, className: "conditions", sortBy: sortBy.conditions },
|
{ title: "Conditions", className: "conditions", sortBy: sortBy.conditions },
|
||||||
]}
|
]}
|
||||||
renderTableContents={(job: Job) => {
|
renderTableContents={(job: Job) => {
|
||||||
const condition = job.getCondition();
|
const condition = job.getCondition();
|
||||||
|
|||||||
@ -2,7 +2,6 @@ import "./overview-statuses.scss";
|
|||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { Trans } from "@lingui/macro";
|
|
||||||
import { OverviewWorkloadStatus } from "./overview-workload-status";
|
import { OverviewWorkloadStatus } from "./overview-workload-status";
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
import { workloadURL, workloadStores } from "../+workloads";
|
import { workloadURL, workloadStores } from "../+workloads";
|
||||||
@ -48,7 +47,7 @@ export class OverviewStatuses extends React.Component {
|
|||||||
return (
|
return (
|
||||||
<div className="OverviewStatuses">
|
<div className="OverviewStatuses">
|
||||||
<div className="header flex gaps align-center">
|
<div className="header flex gaps align-center">
|
||||||
<h5 className="box grow"><Trans>Overview</Trans></h5>
|
<h5 className="box grow">Overview</h5>
|
||||||
<NamespaceSelectFilter />
|
<NamespaceSelectFilter />
|
||||||
</div>
|
</div>
|
||||||
<PageFiltersList />
|
<PageFiltersList />
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user