1
0
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:
Jari Kolehmainen 2020-12-29 14:53:34 +02:00 committed by GitHub
parent 050603a7b3
commit a03da3c572
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
163 changed files with 1140 additions and 12003 deletions

View File

@ -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

View File

@ -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",

View File

@ -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(),
]); ]);

View File

@ -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>
); );

View File

@ -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>

View File

@ -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

View File

@ -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) => [

View File

@ -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 (

View File

@ -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>
)} )}
</> </>

View File

@ -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}
> >

View File

@ -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&apos;t be deleted automatically</Trans> Note: StatefulSet Volumes won&apos;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();

View File

@ -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(),

View File

@ -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&apos;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&apos;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);

View File

@ -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);
} }

View File

@ -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>
</> </>

View File

@ -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>

View File

@ -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>
); );
} }

View File

@ -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>
); );
} }

View File

@ -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;

View File

@ -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(),

View File

@ -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}
/> />

View File

@ -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(),

View File

@ -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>

View File

@ -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 [

View File

@ -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>

View File

@ -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) => {

View File

@ -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/>

View File

@ -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}

View File

@ -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}
/> />

View File

@ -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/>

View File

@ -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(),

View File

@ -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"

View File

@ -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}>

View File

@ -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>
); );

View File

@ -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(),

View File

@ -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(),

View File

@ -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>

View File

@ -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;

View File

@ -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>

View File

@ -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>

View File

@ -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>
)} )}

View File

@ -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()}
/> />

View File

@ -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 (

View File

@ -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

View File

@ -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) => ({

View File

@ -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} />

View File

@ -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>
{ {

View File

@ -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(),

View File

@ -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}`;
} }

View File

@ -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>
); );

View File

@ -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(),

View File

@ -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(),

View File

@ -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)}

View File

@ -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()}

View File

@ -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>

View File

@ -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 />

View File

@ -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(),

View File

@ -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(),

View File

@ -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 }))
} }

View File

@ -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;

View File

@ -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()}`;

View File

@ -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(),
]; ];

View File

@ -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>
</> </>

View File

@ -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>

View File

@ -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>
</> </>
); );

View File

@ -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">

View File

@ -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)}>

View File

@ -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(),
]} ]}
/> />

View File

@ -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>

View File

@ -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 }))
} }

View File

@ -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);

View File

@ -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>
</> </>

View File

@ -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;

View File

@ -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(),

View File

@ -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

View File

@ -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>
); );

View File

@ -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",
}} }}
/> />
); );

View File

@ -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}

View File

@ -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>
</> </>
)} )}

View File

@ -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/>

View File

@ -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}

View File

@ -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>

View File

@ -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>

View File

@ -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>
); );
} }

View File

@ -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(),

View File

@ -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>

View File

@ -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}/>)
} }

View File

@ -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()}

View File

@ -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>
); );
} }

View File

@ -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}/>

View File

@ -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(),

View File

@ -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>
</> </>
)} )}
/> />

View File

@ -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()}

View File

@ -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>
</> </>
); );

View File

@ -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}/>

View File

@ -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();

View File

@ -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