From f9b5ba69809d3677ba18b8fb0c41b27d7e730a82 Mon Sep 17 00:00:00 2001 From: Lauri Nevala Date: Wed, 30 Sep 2020 21:54:12 +0300 Subject: [PATCH 1/7] Release v3.6.5 (#1004) * Release v3.6.5 Signed-off-by: Lauri Nevala --- package.json | 2 +- static/RELEASE_NOTES.md | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 53488e932d..059ffc63ef 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "kontena-lens", "productName": "Lens", "description": "Lens - The Kubernetes IDE", - "version": "3.6.5-rc.1", + "version": "3.6.5", "main": "static/build/main.js", "copyright": "© 2020, Mirantis, Inc.", "license": "MIT", diff --git a/static/RELEASE_NOTES.md b/static/RELEASE_NOTES.md index e3f2af3cfb..11e3ef4aa7 100644 --- a/static/RELEASE_NOTES.md +++ b/static/RELEASE_NOTES.md @@ -2,7 +2,13 @@ Here you can find description of changes we've built into each release. While we try our best to make each upgrade automatic and as smooth as possible, there may be some cases where you might need to do something to ensure the application works smoothly. So please read through the release highlights! -## 3.6.5-rc.1 (current version) +## 3.6.5 (current version) +- Prevent drawer close when revealing secret value +- Fix app crash when CRD conditions were not present +- Add support for Stacklight prometheus metrics +- Terminal: set NO_PROXY env for localhost communication +- Fix CPU/Memory usage metrics when using prometheus operator +- Display last-applied-configuration annotation - Fix Notifications not to block items not visually under them from being interacted with - Fix side bar not to scroll after clicking on lower menu item - Auto-select context if only one context is present in pasted Kubeconfig From 135282da91ce52a56011f10aeec6efa0a2af57d1 Mon Sep 17 00:00:00 2001 From: Lauri Nevala Date: Thu, 1 Oct 2020 11:16:20 +0300 Subject: [PATCH 2/7] Fix cluster dashboard opening and state refreshing (#1006) * Fix cluster dashboard opening and state refreshing Signed-off-by: Lauri Nevala --- src/common/cluster-ipc.ts | 11 +++++++++++ src/main/cluster.ts | 3 ++- src/renderer/bootstrap.tsx | 2 +- src/renderer/components/+cluster/cluster.tsx | 5 +++-- src/renderer/components/app.tsx | 4 ++-- 5 files changed, 19 insertions(+), 6 deletions(-) diff --git a/src/common/cluster-ipc.ts b/src/common/cluster-ipc.ts index e11a232ea3..6ab46c1489 100644 --- a/src/common/cluster-ipc.ts +++ b/src/common/cluster-ipc.ts @@ -14,6 +14,17 @@ export const clusterIpc = { }, }), + setFrameId: createIpcChannel({ + channel: "cluster:set-frame-id", + handle: (clusterId: ClusterId, frameId?: number) => { + const cluster = clusterStore.getById(clusterId); + if (cluster) { + if (frameId) cluster.frameId = frameId; // save cluster's webFrame.routingId to be able to send push-updates + return cluster.pushState(); + } + }, + }), + refresh: createIpcChannel({ channel: "cluster:refresh", handle: (clusterId: ClusterId) => { diff --git a/src/main/cluster.ts b/src/main/cluster.ts index 12acb793ab..3e3ba3f6b5 100644 --- a/src/main/cluster.ts +++ b/src/main/cluster.ts @@ -59,6 +59,7 @@ export class Cluster implements ClusterModel { @observable online = false; @observable accessible = false; @observable ready = false; + @observable reconnecting = false; @observable disconnected = true; @observable failureReason: string; @observable nodes = 0; @@ -110,7 +111,7 @@ export class Cluster implements ClusterModel { protected bindEvents() { logger.info(`[CLUSTER]: bind events`, this.getMeta()); - const refreshTimer = setInterval(() => this.online && this.refresh(), 30000); // every 30s + const refreshTimer = setInterval(() => !this.disconnected && this.refresh(), 30000); // every 30s this.eventDisposers.push( reaction(this.getState, this.pushState), diff --git a/src/renderer/bootstrap.tsx b/src/renderer/bootstrap.tsx index 37fdc35e03..f03df719b6 100644 --- a/src/renderer/bootstrap.tsx +++ b/src/renderer/bootstrap.tsx @@ -11,7 +11,7 @@ import { App } from "./components/app"; import { LensApp } from "./lens-app"; type AppComponent = React.ComponentType & { - init?(): void; + init?(): Promise; } export async function bootstrap(App: AppComponent) { diff --git a/src/renderer/components/+cluster/cluster.tsx b/src/renderer/components/+cluster/cluster.tsx index 9ef032335b..9a1ce47123 100644 --- a/src/renderer/components/+cluster/cluster.tsx +++ b/src/renderer/components/+cluster/cluster.tsx @@ -14,14 +14,15 @@ import { podsStore } from "../+workloads-pods/pods.store"; import { clusterStore } from "./cluster.store"; import { eventStore } from "../+events/event.store"; import { isAllowedResource } from "../../../common/rbac"; +import { getHostedCluster } from "../../../common/cluster-store"; @observer export class Cluster extends React.Component { private dependentStores = [nodesStore, podsStore]; private watchers = [ - interval(60, () => clusterStore.getMetrics()), - interval(20, () => eventStore.loadAll()) + interval(60, () => { getHostedCluster().available && clusterStore.getMetrics()}), + interval(20, () => { getHostedCluster().available && eventStore.loadAll()}) ]; @computed get isLoaded() { diff --git a/src/renderer/components/app.tsx b/src/renderer/components/app.tsx index 053d8fa3d6..aee156ff31 100755 --- a/src/renderer/components/app.tsx +++ b/src/renderer/components/app.tsx @@ -44,8 +44,8 @@ export class App extends React.Component { const clusterId = getHostedClusterId(); logger.info(`[APP]: Init dashboard, clusterId=${clusterId}, frameId=${frameId}`) await Terminal.preloadFonts() - await clusterIpc.activate.invokeFromRenderer(clusterId, frameId); - await getHostedCluster().whenReady; // cluster.refresh() is done at this point + await clusterIpc.setFrameId.invokeFromRenderer(clusterId, frameId); + await getHostedCluster().whenReady; // cluster.activate() is done at this point } get startURL() { From 9ecfeb316c4ea59681eaea5549e84fc64a886a5a Mon Sep 17 00:00:00 2001 From: Sebastian Malton Date: Thu, 1 Oct 2020 11:37:27 -0400 Subject: [PATCH 3/7] cleanup Draggable into ResizingAnchor (#989) * Rename `Draggable` as `ResizingAnchor` since that is what it is used for and shouldn't be mistaken as a general draggable item * Refactor `ResizingAnchor` to be much more smart about how it handles mouse movements. Allow it to know which direction the resizing should be in allowing it to produce exact resized values. * Add event handlers for the min and max extents so that actions can be triggered when those extents are passed (in either direction) * Add double click support Signed-off-by: Sebastian Malton --- src/renderer/components/dock/dock.scss | 23 +- src/renderer/components/dock/dock.store.ts | 25 +- src/renderer/components/dock/dock.tsx | 61 ++-- src/renderer/components/dock/terminal.ts | 7 +- .../components/draggable/draggable.scss | 5 - .../components/draggable/draggable.tsx | 119 -------- src/renderer/components/draggable/index.ts | 1 - .../components/resizing-anchor/index.ts | 1 + .../resizing-anchor/resizing-anchor.scss | 46 +++ .../resizing-anchor/resizing-anchor.tsx | 281 ++++++++++++++++++ yarn.lock | 16 +- 11 files changed, 376 insertions(+), 209 deletions(-) delete mode 100644 src/renderer/components/draggable/draggable.scss delete mode 100644 src/renderer/components/draggable/draggable.tsx delete mode 100644 src/renderer/components/draggable/index.ts create mode 100644 src/renderer/components/resizing-anchor/index.ts create mode 100644 src/renderer/components/resizing-anchor/resizing-anchor.scss create mode 100644 src/renderer/components/resizing-anchor/resizing-anchor.tsx diff --git a/src/renderer/components/dock/dock.scss b/src/renderer/components/dock/dock.scss index 6b2d90925d..8c7ab7e07d 100644 --- a/src/renderer/components/dock/dock.scss +++ b/src/renderer/components/dock/dock.scss @@ -14,10 +14,6 @@ left: 0; bottom: 0; z-index: 100; - - > .resizer { - display: none; - } } } @@ -65,24 +61,7 @@ } } - .resizer { - $height: 12px; - - position: absolute; - top: -$height / 2; - left: 0; - right: 0; - bottom: 100%; - height: $height; - cursor: row-resize; - z-index: 10; - - &.disabled { - pointer-events: none; - } - } - .AceEditor { border: none; } -} \ No newline at end of file +} diff --git a/src/renderer/components/dock/dock.store.ts b/src/renderer/components/dock/dock.store.ts index c1b70cc925..2fed511e75 100644 --- a/src/renderer/components/dock/dock.store.ts +++ b/src/renderer/components/dock/dock.store.ts @@ -27,8 +27,8 @@ export class DockStore { ]; protected storage = createStorage("dock", {}); // keep settings in localStorage - public defaultTabId = this.initialTabs[0].id; - public minHeight = 100; + public readonly defaultTabId = this.initialTabs[0].id; + public readonly minHeight = 100; @observable isOpen = false; @observable fullSize = false; @@ -45,11 +45,12 @@ export class DockStore { } get maxHeight() { - const mainLayoutHeader = 40; - const mainLayoutTabs = 33; - const mainLayoutMargin = 16; - const dockTabs = 33; - return window.innerHeight - mainLayoutHeader - mainLayoutTabs - mainLayoutMargin - dockTabs; + const mainLayoutHeader = 40 + const mainLayoutTabs = 33 + const mainLayoutMargin = 16 + const dockTabs = 33 + const preferedMax = window.innerHeight - mainLayoutHeader - mainLayoutTabs - mainLayoutMargin - dockTabs + return Math.max(preferedMax, this.minHeight) // don't let max < min } constructor() { @@ -65,7 +66,6 @@ export class DockStore { }); // adjust terminal height if window size changes - this.checkMaxHeight(); window.addEventListener("resize", throttle(this.checkMaxHeight, 250)); } @@ -171,20 +171,19 @@ export class DockStore { @action selectTab(tabId: TabId) { - const tab = this.getTabById(tabId); - this.selectedTabId = tab ? tab.id : null; + this.selectedTabId = this.getTabById(tabId)?.id ?? null; } @action - setHeight(height: number) { - this.height = Math.max(0, Math.min(height, this.maxHeight)); + setHeight(height?: number) { + this.height = Math.max(this.minHeight, Math.min(height || this.minHeight, this.maxHeight)); } @action reset() { this.selectedTabId = this.defaultTabId; this.tabs.replace(this.initialTabs); - this.height = this.defaultHeight; + this.setHeight(this.defaultHeight); this.close(); } } diff --git a/src/renderer/components/dock/dock.tsx b/src/renderer/components/dock/dock.tsx index d384c36608..c020d20672 100644 --- a/src/renderer/components/dock/dock.tsx +++ b/src/renderer/components/dock/dock.tsx @@ -4,7 +4,7 @@ import React, { Fragment } from "react"; import { observer } from "mobx-react"; import { Trans } from "@lingui/macro"; import { autobind, cssNames, prevDefault } from "../../utils"; -import { Draggable, DraggableState } from "../draggable"; +import { ResizingAnchor, ResizeDirection } from "../resizing-anchor"; import { Icon } from "../icon"; import { Tabs } from "../tabs/tabs"; import { MenuItem } from "../menu"; @@ -29,28 +29,8 @@ interface Props { @observer export class Dock extends React.Component { - onResizeStart = () => { - const { isOpen, open, setHeight, minHeight } = dockStore; - if (!isOpen) { - open(); - setHeight(minHeight); - } - } - - onResize = ({ offsetY }: DraggableState) => { - const { isOpen, close, height, setHeight, minHeight, defaultHeight } = dockStore; - const newHeight = height + offsetY; - if (height > newHeight && newHeight < minHeight) { - setHeight(defaultHeight); - close(); - } - else if (isOpen) { - setHeight(newHeight); - } - } - onKeydown = (evt: React.KeyboardEvent) => { - const { close, closeTab, selectedTab, fullSize, toggleFillSize } = dockStore; + const { close, closeTab, selectedTab } = dockStore; if (!selectedTab) return; const { code, ctrlKey, shiftKey } = evt.nativeEvent; if (shiftKey && code === "Escape") { @@ -71,13 +51,13 @@ export class Dock extends React.Component { @autobind() renderTab(tab: IDockTab) { if (isTerminalTab(tab)) { - return + return } if (isCreateResourceTab(tab) || isEditResourceTab(tab)) { - return + return } if (isInstallChartTab(tab) || isUpgradeChartTab(tab)) { - return }/> + return } /> } } @@ -86,11 +66,11 @@ export class Dock extends React.Component { if (!isOpen || !tab) return; return (
- {isCreateResourceTab(tab) && } - {isEditResourceTab(tab) && } - {isInstallChartTab(tab) && } - {isUpgradeChartTab(tab) && } - {isTerminalTab(tab) && } + {isCreateResourceTab(tab) && } + {isEditResourceTab(tab) && } + {isInstallChartTab(tab) && } + {isUpgradeChartTab(tab) && } + {isTerminalTab(tab) && }
) } @@ -104,11 +84,16 @@ export class Dock extends React.Component { onKeyDown={this.onKeydown} tabIndex={-1} > - dockStore.height} + minExtent={dockStore.minHeight} + maxExtent={dockStore.maxHeight} + direction={ResizeDirection.VERTICAL} + onStart={dockStore.open} + onMinExtentSubceed={dockStore.close} + onMinExtentExceed={dockStore.open} + onDrag={dockStore.setHeight} />
{
New tab }} closeOnScroll={false}> createTerminalTab()}> - + Terminal session createResourceTab()}> - + Create resource @@ -133,7 +118,7 @@ export class Dock extends React.Component { {hasTabs() && ( <> Exit full size mode : Fit to window} onClick={toggleFillSize} /> diff --git a/src/renderer/components/dock/terminal.ts b/src/renderer/components/dock/terminal.ts index f02fd478f2..cea1e91292 100644 --- a/src/renderer/components/dock/terminal.ts +++ b/src/renderer/components/dock/terminal.ts @@ -121,6 +121,8 @@ export class Terminal { } fit = () => { + // Since this function is debounced we need to read this value as late as possible + if (!this.isActive) return; this.fitAddon.fit(); const { cols, rows } = this.xterm; this.api.sendTerminalSize(cols, rows); @@ -150,7 +152,6 @@ export class Terminal { } onResize = () => { - if (!this.isActive) return; this.fitLazy(); this.focus(); } @@ -176,8 +177,8 @@ export class Terminal { if (this.xterm.hasSelection()) return false; break; - // Ctrl+W: prevent unexpected terminal tab closing, e.g. editing file in vim - // https://github.com/kontena/lens-app/issues/156#issuecomment-534906480 + // Ctrl+W: prevent unexpected terminal tab closing, e.g. editing file in vim + // https://github.com/kontena/lens-app/issues/156#issuecomment-534906480 case "KeyW": evt.preventDefault(); break; diff --git a/src/renderer/components/draggable/draggable.scss b/src/renderer/components/draggable/draggable.scss deleted file mode 100644 index e99e306ce2..0000000000 --- a/src/renderer/components/draggable/draggable.scss +++ /dev/null @@ -1,5 +0,0 @@ -body.dragging { - user-select: none; - -moz-user-select: none; - -webkit-user-select: none; -} \ No newline at end of file diff --git a/src/renderer/components/draggable/draggable.tsx b/src/renderer/components/draggable/draggable.tsx deleted file mode 100644 index 12fd020929..0000000000 --- a/src/renderer/components/draggable/draggable.tsx +++ /dev/null @@ -1,119 +0,0 @@ -import "./draggable.scss"; -import React from "react"; -import { cssNames, IClassName, noop } from "../../utils"; -import throttle from "lodash/throttle"; - -export interface DraggableEventHandler { - (state: DraggableState): void; -} - -interface Props { - className?: IClassName; - vertical?: boolean; - horizontal?: boolean; - onStart?: DraggableEventHandler; - onEnter?: DraggableEventHandler; - onEnd?: DraggableEventHandler; -} - -export interface DraggableState { - inited?: boolean; - changed?: boolean; - initX?: number; - initY?: number; - pageX?: number; - pageY?: number; - offsetX?: number; - offsetY?: number; -} - -const initState: DraggableState = { - inited: false, - changed: false, - offsetX: 0, - offsetY: 0, -}; - -export class Draggable extends React.PureComponent { - public state = initState; - - static IS_DRAGGING = "dragging" - - static defaultProps: Props = { - vertical: true, - horizontal: true, - onStart: noop, - onEnter: noop, - onEnd: noop, - }; - - constructor(props: Props) { - super(props); - document.addEventListener("mousemove", this.onDrag); - document.addEventListener("mouseup", this.onDragEnd); - } - - componentWillUnmount() { - document.removeEventListener("mousemove", this.onDrag); - document.removeEventListener("mouseup", this.onDragEnd); - } - - onDragInit = (evt: React.MouseEvent) => { - document.body.classList.add(Draggable.IS_DRAGGING); - const { pageX, pageY } = evt; - this.setState({ - inited: true, - initX: pageX, - initY: pageY, - pageX: pageX, - pageY: pageY, - }) - } - - onDrag = throttle((evt: MouseEvent) => { - const { vertical, horizontal, onEnter, onStart } = this.props; - const { inited, pageX, pageY } = this.state; - const offsetX = pageX - evt.pageX; - const offsetY = pageY - evt.pageY; - let changed = false; - if (horizontal && offsetX !== 0) changed = true; - if (vertical && offsetY !== 0) changed = true; - if (inited && changed) { - const start = !this.state.changed; - const state = Object.assign({}, this.state, { - changed: true, - pageX: evt.pageX, - pageY: evt.pageY, - offsetX: offsetX, - offsetY: offsetY, - }); - if (start) onStart(state); - this.setState(state, () => onEnter(state)); - } - }, 100) - - onDragEnd = (evt: MouseEvent) => { - const { pageX, pageY } = evt; - const { inited, changed, initX, initY } = this.state; - if (inited) { - document.body.classList.remove(Draggable.IS_DRAGGING); - this.setState(initState, () => { - if (!changed) return; - const state = Object.assign({}, this.state, { - offsetX: initX - pageX, - offsetY: initY - pageY, - }); - this.props.onEnd(state); - }); - } - } - - render() { - const { className, children } = this.props; - return ( -
- {children} -
- ); - } -} \ No newline at end of file diff --git a/src/renderer/components/draggable/index.ts b/src/renderer/components/draggable/index.ts deleted file mode 100644 index 0a3b92d235..0000000000 --- a/src/renderer/components/draggable/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './draggable' \ No newline at end of file diff --git a/src/renderer/components/resizing-anchor/index.ts b/src/renderer/components/resizing-anchor/index.ts new file mode 100644 index 0000000000..6197be8d84 --- /dev/null +++ b/src/renderer/components/resizing-anchor/index.ts @@ -0,0 +1 @@ +export * from './resizing-anchor' diff --git a/src/renderer/components/resizing-anchor/resizing-anchor.scss b/src/renderer/components/resizing-anchor/resizing-anchor.scss new file mode 100644 index 0000000000..310727af2c --- /dev/null +++ b/src/renderer/components/resizing-anchor/resizing-anchor.scss @@ -0,0 +1,46 @@ +body.resizing { + user-select: none; + -moz-user-select: none; + -webkit-user-select: none; +} + +.ResizingAnchor { + $dimension: 12px; + + position: absolute; + z-index: 10; + + &.disabled { + display: none; + } + + &.vertical { + left: 0; + right: 0; + cursor: row-resize; + height: $dimension; + + &.leading { + top: -$dimension / 2; + } + + &.trailing { + bottom: -$dimension / 2; + } + } + + &.horizontal { + top: 0; + bottom: 0; + cursor: col-resize; + width: $dimension; + + &.leading { + left: -$dimension / 2; + } + + &.trailing { + right: -$dimension / 2; + } + } +} diff --git a/src/renderer/components/resizing-anchor/resizing-anchor.tsx b/src/renderer/components/resizing-anchor/resizing-anchor.tsx new file mode 100644 index 0000000000..a5a8ba2086 --- /dev/null +++ b/src/renderer/components/resizing-anchor/resizing-anchor.tsx @@ -0,0 +1,281 @@ +import "./resizing-anchor.scss"; +import React from "react"; +import { action, observable } from "mobx"; +import _ from "lodash" +import { findDOMNode } from "react-dom"; +import { cssNames, noop } from "../../utils"; + +export enum ResizeDirection { + HORIZONTAL = "horizontal", + VERTICAL = "vertical", +} + +/** + * ResizeSide is for customizing where the area should be rendered. + * That location is determined in conjunction with the `ResizeDirection` using the following table: + * + * +----------+------------+----------+ + * | | HORIZONTAL | VERTICAL | + * +----------+------------+----------+ + * | LEADING | left | top | + * +----------+------------+----------+ + * | TRAILING | right | bottom | + * +----------+------------+----------+ + */ +export enum ResizeSide { + LEADING = "leading", + TRAILING = "trailing", +} + +/** + * ResizeGrowthDirection determines how the anchor interprets the drag. + * + * Because the origin of the screen is top left a drag from bottom to top + * results in a negative directional delta. However, if the component being + * dragged grows in the opposite direction, this needs to be compensated for. + */ +export enum ResizeGrowthDirection { + TOP_TO_BOTTOM = 1, + BOTTOM_TO_TOP = -1, + LEFT_TO_RIGHT = 1, + RIGHT_TO_LEFT = -1, +} + +interface Props { + direction: ResizeDirection; + + /** + * getCurrentExtent should return the current prominent dimension in the + * given resizing direction. Width for HORIZONTAL and height for VERTICAL + */ + getCurrentExtent: () => number; + + disabled?: boolean; + placement?: ResizeSide; + growthDirection?: ResizeGrowthDirection; + + // Ability to restrict which mouse buttons are allowed to resize this component + // Reference: https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/buttons + onlyButtons?: number; + + // onStart is called when the ResizeAnchor is first clicked (mouse down) + onStart?: () => void; + + // onEnd is called when the ResizeAnchor is released (mouse up) + onEnd?: () => void; + + /** + * onDrag is called whenever there is a mousemove event. All calls will be + * bounded by matching `onStart` and `onEnd` calls. + */ + onDrag?: (newExtent: number) => void; + + // onDoubleClick is called when the the ResizeAnchor is double clicked + onDoubleClick?: () => void; + + /** + * The following two extents represent the max and min values set to `onDrag` + */ + maxExtent?: number; + minExtent?: number; + + /** + * The following events are triggerred with respect to the above values. + * - The "__Exceed" call will be made when the unbounded extent goes from + * < the above to >= the above + * - The "__Subceed" call is similar but is triggered when the unbounded + * extent goes from >= the above to < the above. + */ + onMaxExtentExceed?: () => void; + onMaxExtentSubceed?: () => void; + onMinExtentSubceed?: () => void; + onMinExtentExceed?: () => void; +} + +interface Position { + readonly pageX: number; + readonly pageY: number; +} + +/** + * Return the direction delta, but ignore drags leading up to a moved item + * 1. `->|` => return `false` + * 2. `<-|` => return `directed length (M, P2)` (negative) + * 3. `-|>` => return `directed length (M, P2)` (positive) + * 4. `<|-` => return `directed length (M, P2)` (negative) + * 5. `|->` => return `directed length (M, P2)` (positive) + * 6. `|<-` => return `false` + * @param P1 the starting position on the number line + * @param P2 the ending position on the number line + * @param M a third point that determines if the delta is meaningful + * @returns the directional difference between including appropriate sign. + */ +function directionDelta(P1: number, P2: number, M: number): number | false { + const delta = Math.abs(M - P2) + + if (P1 < M) { + if (P2 >= M) { + // case 3 + return delta + } + + if (P2 < P1) { + // case 2 + return -delta + } + + // case 1 + return false + } + + if (P2 < M) { + // case 4 + return -delta + } + + if (P1 < P2) { + // case 5 + return delta + } + + // case 6 + return false +} + +export class ResizingAnchor extends React.PureComponent { + @observable lastMouseEvent?: MouseEvent + @observable.ref ref?: React.RefObject; + + static defaultProps = { + onStart: noop, + onDrag: noop, + onEnd: noop, + onMaxExtentExceed: noop, + onMinExtentExceed: noop, + onMinExtentSubceed: noop, + onMaxExtentSubceed: noop, + onDoubleClick: noop, + disabled: false, + growthDirection: ResizeGrowthDirection.BOTTOM_TO_TOP, + maxExtent: Number.POSITIVE_INFINITY, + minExtent: 0, + placement: ResizeSide.LEADING, + } + static IS_RESIZING = "resizing" + + constructor(props: Props) { + super(props) + if (props.maxExtent < props.minExtent) { + throw new Error("maxExtent must be >= minExtent") + } + + this.ref = React.createRef() + } + + componentWillUnmount() { + document.removeEventListener("mousemove", this.onDrag) + document.removeEventListener("mouseup", this.onDragEnd) + } + + @action + onDragInit = (event: React.MouseEvent) => { + const { onStart, onlyButtons } = this.props + + if (typeof onlyButtons === "number" && onlyButtons !== event.buttons) { + return + } + + document.addEventListener("mousemove", this.onDrag) + document.addEventListener("mouseup", this.onDragEnd) + document.body.classList.add(ResizingAnchor.IS_RESIZING) + + this.lastMouseEvent = undefined + onStart() + } + + calculateDelta(from: Position, to: Position): number | false { + const node = this.ref.current + if (!node) { + return false + } + + const boundingBox = node.getBoundingClientRect() + + if (this.props.direction === ResizeDirection.HORIZONTAL) { + const barX = Math.round(boundingBox.x + (boundingBox.width / 2)) + return directionDelta(from.pageX, to.pageX, barX) + } else { // direction === ResizeDirection.VERTICAL + const barY = Math.round(boundingBox.y + (boundingBox.height / 2)) + return directionDelta(from.pageY, to.pageY, barY) + } + } + + onDrag = _.throttle((event: MouseEvent) => { + /** + * Some notes to help understand the following: + * - A browser's origin point is in the top left of the screen + * - X increases going from left to right + * - Y increases going from top to bottom + * - Since the resize bar should always be a rectangle, use its centre + * line (in the resizing direction) as the line for determining if + * the bar has "jumped around" + * + * Desire: + * - Always ignore movement in the non-resizing direction + * - Figure out how much the user has "dragged" the resize bar + * - If the resize bar has jumped around, compensate by ignoring movement + * in the resizing direction if it is moving "towards" the resize bar's + * new location. + */ + + if (!this.lastMouseEvent) { + this.lastMouseEvent = event + return + } + + const { maxExtent, minExtent, getCurrentExtent, growthDirection } = this.props + const { onDrag, onMaxExtentExceed, onMinExtentSubceed, onMaxExtentSubceed, onMinExtentExceed } = this.props + const delta = this.calculateDelta(this.lastMouseEvent, event) + + // always update the last mouse event + this.lastMouseEvent = event + + if (delta === false) { + return + } + + const previousExtent = getCurrentExtent() + const unboundedExtent = previousExtent + (delta * growthDirection) + const boundedExtent = Math.round(Math.max(minExtent, Math.min(maxExtent, unboundedExtent))) + onDrag(boundedExtent) + + if (previousExtent <= minExtent && minExtent <= unboundedExtent) { + onMinExtentExceed() + } else if (previousExtent >= minExtent && minExtent >= unboundedExtent) { + onMinExtentSubceed() + } + if (previousExtent <= maxExtent && maxExtent <= unboundedExtent) { + onMaxExtentExceed() + } else if (previousExtent >= maxExtent && maxExtent >= unboundedExtent) { + onMaxExtentSubceed() + } + }, 100) + + @action + onDragEnd = (_event: MouseEvent) => { + this.props.onEnd() + document.removeEventListener("mousemove", this.onDrag) + document.removeEventListener("mouseup", this.onDragEnd) + document.body.classList.remove(ResizingAnchor.IS_RESIZING) + } + + render() { + const { disabled, direction, placement, onDoubleClick } = this.props + return
+ } +} diff --git a/yarn.lock b/yarn.lock index 300efc58ce..f64e36b703 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8181,17 +8181,17 @@ mobx-observable-history@^1.0.3: history "^4.10.1" mobx "^5.15.4" -mobx-react-lite@2: - version "2.0.7" - resolved "https://registry.yarnpkg.com/mobx-react-lite/-/mobx-react-lite-2.0.7.tgz#1bfb3b4272668e288047cf0c7940b14e91cba284" - integrity sha512-YKAh2gThC6WooPnVZCoC+rV1bODAKFwkhxikzgH18wpBjkgTkkR9Sb0IesQAH5QrAEH/JQVmy47jcpQkf2Au3Q== +mobx-react-lite@>=2.2.0: + version "2.2.2" + resolved "https://registry.yarnpkg.com/mobx-react-lite/-/mobx-react-lite-2.2.2.tgz#87c217dc72b4e47b22493daf155daf3759f868a6" + integrity sha512-2SlXALHIkyUPDsV4VTKVR9DW7K3Ksh1aaIv3NrNJygTbhXe2A9GrcKHZ2ovIiOp/BXilOcTYemfHHZubP431dg== mobx-react@^6.2.2: - version "6.2.2" - resolved "https://registry.yarnpkg.com/mobx-react/-/mobx-react-6.2.2.tgz#45e8e7c4894cac8399bba0a91060d7cfb8ea084b" - integrity sha512-Us6V4ng/iKIRJ8pWxdbdysC6bnS53ZKLKlVGBqzHx6J+gYPYbOotWvhHZnzh/W5mhpYXxlXif4kL2cxoWJOplQ== + version "6.3.0" + resolved "https://registry.yarnpkg.com/mobx-react/-/mobx-react-6.3.0.tgz#7d11799f988bbdadc49e725081993b18baa20329" + integrity sha512-C14yya2nqEBRSEiJjPkhoWJLlV8pcCX3m2JRV7w1KivwANJqipoiPx9UMH4pm6QNMbqDdvJqoyl+LqNu9AhvEQ== dependencies: - mobx-react-lite "2" + mobx-react-lite ">=2.2.0" mobx@^5.15.4: version "5.15.4" From af71834676842ee807096afa3769d2fe27ebe436 Mon Sep 17 00:00:00 2001 From: Alex Andreev Date: Fri, 2 Oct 2020 09:32:20 +0300 Subject: [PATCH 4/7] Moving dock info panel to the top (#1007) * Moving EditorPanel to the top Signed-off-by: Alex Andreev * Preventing save with empty yaml Signed-off-by: Alex Andreev * Make tooltips in @withTooltip narrower Signed-off-by: Alex Andreev * Not showing api errors in icon Signed-off-by: Alex Andreev * Success notification for create resource operation Signed-off-by: Alex Andreev * Button outlined style Signed-off-by: Alex Andreev * Making second button to stay outlined Signed-off-by: Alex Andreev * Fine-tuning dock info panel colors Signed-off-by: Alex Andreev * Removing border-radius from ace-editor Signed-off-by: Alex Andreev --- .../components/ace-editor/ace-editor.scss | 2 - src/renderer/components/button/button.scss | 11 +++++ src/renderer/components/button/button.tsx | 5 ++- .../components/dock/create-resource.tsx | 15 ++++--- .../components/dock/edit-resource.tsx | 10 ++--- src/renderer/components/dock/info-panel.scss | 29 +----------- src/renderer/components/dock/info-panel.tsx | 44 ++++++------------- .../components/dock/install-chart.tsx | 10 ++--- .../components/dock/upgrade-chart.tsx | 12 ++--- .../components/tooltip/withTooltip.tsx | 1 + src/renderer/themes/kontena-dark.json | 4 +- 11 files changed, 58 insertions(+), 85 deletions(-) diff --git a/src/renderer/components/ace-editor/ace-editor.scss b/src/renderer/components/ace-editor/ace-editor.scss index 26b74d1b64..7aabbf01d5 100644 --- a/src/renderer/components/ace-editor/ace-editor.scss +++ b/src/renderer/components/ace-editor/ace-editor.scss @@ -7,7 +7,6 @@ .theme-light & { border: 1px solid gainsboro; - border-radius: $radius; .ace_scrollbar { @include custom-scrollbar(dark); @@ -19,7 +18,6 @@ width: inherit; height: inherit; font-size: 90%; - border-radius: $radius; } // --Theme customization diff --git a/src/renderer/components/button/button.scss b/src/renderer/components/button/button.scss index e85647ca9f..f586a03c5a 100644 --- a/src/renderer/components/button/button.scss +++ b/src/renderer/components/button/button.scss @@ -41,6 +41,17 @@ } } + &.outlined { + color: inherit; + background: transparent; + + &.active, + &:focus { + color: inherit; + box-shadow: 0 0 0 1px inset; + } + } + &.big { font-size: 2.2 * $unit; border-radius: 50px; diff --git a/src/renderer/components/button/button.tsx b/src/renderer/components/button/button.tsx index c0cb8dcc49..65aa3a979e 100644 --- a/src/renderer/components/button/button.tsx +++ b/src/renderer/components/button/button.tsx @@ -9,6 +9,7 @@ export interface ButtonProps extends ButtonHTMLAttributes, TooltipDecorator primary?: boolean; accent?: boolean; plain?: boolean; + outlined?: boolean; hidden?: boolean; active?: boolean; big?: boolean; @@ -23,12 +24,12 @@ export class Button extends React.PureComponent { private button: HTMLButtonElement; render() { - const { className, waiting, label, primary, accent, plain, hidden, active, big, round, tooltip, children, ...props } = this.props; + const { className, waiting, label, primary, accent, plain, hidden, active, big, round, outlined, tooltip, children, ...props } = this.props; const btnProps = props as Partial; if (hidden) return null; btnProps.className = cssNames('Button', className, { - waiting, primary, accent, plain, active, big, round, + waiting, primary, accent, plain, active, big, round, outlined }); const btnContent: ReactNode = ( diff --git a/src/renderer/components/dock/create-resource.tsx b/src/renderer/components/dock/create-resource.tsx index 6d89455b3b..e665c831a0 100644 --- a/src/renderer/components/dock/create-resource.tsx +++ b/src/renderer/components/dock/create-resource.tsx @@ -39,6 +39,7 @@ export class CreateResource extends React.Component { create = async () => { if (this.error) return; + if (!this.data.trim()) return; // do not save when field is empty const resources = jsYaml.safeLoadAll(this.data) .filter(v => !!v) // skip empty documents if "---" pasted at the beginning or end const createdResources: string[] = []; @@ -54,12 +55,14 @@ export class CreateResource extends React.Component { errors.forEach(Notifications.error); if (!createdResources.length) throw errors[0]; } - return ( + const successMessage = (

{" "} {createdResources.join(", ")} successfully created

) + Notifications.ok(successMessage) + return successMessage } render() { @@ -67,11 +70,6 @@ export class CreateResource extends React.Component { const { className } = this.props; return (
- { submitLabel={_i18n._(t`Create`)} showNotifications={false} /> +
) } diff --git a/src/renderer/components/dock/edit-resource.tsx b/src/renderer/components/dock/edit-resource.tsx index 8168af28bc..6d9aa961c2 100644 --- a/src/renderer/components/dock/edit-resource.tsx +++ b/src/renderer/components/dock/edit-resource.tsx @@ -90,11 +90,6 @@ export class EditResource extends React.Component { const { kind, getNs, getName } = resource; return (
- {
)} /> +
) } diff --git a/src/renderer/components/dock/info-panel.scss b/src/renderer/components/dock/info-panel.scss index 3bc3f94f82..23dcc52243 100644 --- a/src/renderer/components/dock/info-panel.scss +++ b/src/renderer/components/dock/info-panel.scss @@ -2,7 +2,7 @@ @include hidden-scrollbar; background: $dockInfoBackground; - border-top: 1px solid $dockInfoBorderColor; + border-bottom: 1px solid $dockInfoBorderColor; padding: $padding $padding * 2; flex-shrink: 0; @@ -12,37 +12,12 @@ > .controls { white-space: nowrap; - - &:empty { - display: none; - } + flex: 1 1; &:not(:empty) + .info { - border: 1px solid $borderColor; - border-top: 0; - border-bottom: 0; min-height: 25px; padding-left: $padding; padding-right: $padding; } } - - > .info { - @include hidden-scrollbar; - - min-width: 40px; // min-space for icon - flex: 1 1; - white-space: nowrap; - text-overflow: ellipsis; - - > div { - padding-right: $padding; - flex-shrink: 0; - } - - .Icon { - margin: 0; - margin-right: $padding; - } - } } \ No newline at end of file diff --git a/src/renderer/components/dock/info-panel.tsx b/src/renderer/components/dock/info-panel.tsx index 39d998d9d4..122fea6d9f 100644 --- a/src/renderer/components/dock/info-panel.tsx +++ b/src/renderer/components/dock/info-panel.tsx @@ -38,35 +38,29 @@ export class InfoPanel extends Component { showNotifications: true, } - @observable.ref result: ReactNode; @observable error = ""; @observable waiting = false; componentDidMount() { disposeOnUnmount(this, [ reaction(() => this.props.tabId, () => { - this.result = "" - this.error = "" this.waiting = false }) ]) } @computed get errorInfo() { - return this.error || this.props.error; + return this.props.error; } submit = async () => { const { showNotifications } = this.props; - this.result = ""; - this.error = ""; this.waiting = true; try { - this.result = await this.props.submit() - if (showNotifications) Notifications.ok(this.result); + const result = await this.props.submit(); + if (showNotifications) Notifications.ok(result); } catch (error) { - this.error = error.toString(); - if (showNotifications) Notifications.error(this.error); + if (showNotifications) Notifications.error(error.toString()); } finally { this.waiting = false } @@ -81,27 +75,15 @@ export class InfoPanel extends Component { dockStore.closeTab(this.props.tabId); } - renderInfo() { - if (!this.props.showInlineInfo) { + renderErrorIcon() { + if (!this.props.showInlineInfo || !this.errorInfo) { return; } - const { result, errorInfo } = this; return ( - <> - {result && ( -
- - {result} -
- )} - {errorInfo && ( -
- - {errorInfo} -
- )} - - ) +
+ +
+ ); } render() { @@ -114,11 +96,13 @@ export class InfoPanel extends Component { {controls}
- {waiting ? <> {submittingMessage} : this.renderInfo()} + {waiting ? <> {submittingMessage} : this.renderErrorIcon()}
) return (
- { submittingMessage={_i18n._(t`Updating..`)} controls={controlsAndInfo} /> +
) } diff --git a/src/renderer/components/tooltip/withTooltip.tsx b/src/renderer/components/tooltip/withTooltip.tsx index f8c3e3ea93..5861e5af82 100644 --- a/src/renderer/components/tooltip/withTooltip.tsx +++ b/src/renderer/components/tooltip/withTooltip.tsx @@ -28,6 +28,7 @@ export function withTooltip>(Target: T): T { const tooltipProps: TooltipProps = { targetId: tooltipId, tooltipOnParentHover: tooltipOverrideDisabled, + formatters: { narrow: true }, ...(isReactNode(tooltip) ? { children: tooltip } : tooltip), }; targetProps.id = tooltipId; diff --git a/src/renderer/themes/kontena-dark.json b/src/renderer/themes/kontena-dark.json index a0d0eb9869..1071024841 100644 --- a/src/renderer/themes/kontena-dark.json +++ b/src/renderer/themes/kontena-dark.json @@ -58,8 +58,8 @@ "colorVague": "#36393e", "colorTerminated": "#4c5053", "dockHeadBackground": "#2e3136", - "dockInfoBackground": "#111111", - "dockInfoBorderColor": "#4c5053", + "dockInfoBackground": "#1e2125", + "dockInfoBorderColor": "#303136", "terminalBackground": "#000000", "terminalForeground": "#ffffff", "terminalCursor": "#ffffff", From 68317453c1f3e45bc8db507251a67a38288f9533 Mon Sep 17 00:00:00 2001 From: Alex Andreev Date: Fri, 2 Oct 2020 12:49:03 +0300 Subject: [PATCH 5/7] Adding space after drawer badges (#1014) Signed-off-by: Alex Andreev --- src/renderer/components/badge/badge.tsx | 7 ------- src/renderer/components/drawer/drawer-item.scss | 5 +++++ 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/renderer/components/badge/badge.tsx b/src/renderer/components/badge/badge.tsx index eca3c94063..3a70c98286 100644 --- a/src/renderer/components/badge/badge.tsx +++ b/src/renderer/components/badge/badge.tsx @@ -18,13 +18,6 @@ export class Badge extends React.Component { {label} {children} - { /** - * This is a zero-width-space. It makes there be a word seperation - * between adjacent Badge's because 's are ignored for browers' - * word detection algorithmns use for determining the extent of the - * text to highlight on multi-click sequences. - */} - ​ } } diff --git a/src/renderer/components/drawer/drawer-item.scss b/src/renderer/components/drawer/drawer-item.scss index b7e69fc1ae..f7727414a3 100644 --- a/src/renderer/components/drawer/drawer-item.scss +++ b/src/renderer/components/drawer/drawer-item.scss @@ -48,6 +48,11 @@ float: left; margin: $spacing; + &:after { + content: " "; + display: block; + } + &.disabled { opacity: 0.5; } From 14d3d88278c6c328d9579c133d5642e4d44b6b79 Mon Sep 17 00:00:00 2001 From: Alex Andreev Date: Fri, 2 Oct 2020 14:33:29 +0300 Subject: [PATCH 6/7] Fix: check for location bevore navigate (#1016) * Check for location before navigate Signed-off-by: Alex Andreev * Handling every location type Signed-off-by: Alex Andreev --- src/renderer/navigation.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/renderer/navigation.ts b/src/renderer/navigation.ts index ce831feac4..f7d5b6e435 100644 --- a/src/renderer/navigation.ts +++ b/src/renderer/navigation.ts @@ -18,7 +18,11 @@ if (ipcRenderer) { } export function navigate(location: LocationDescriptor) { + const currentLocation = navigation.getPath(); navigation.push(location); + if (currentLocation === navigation.getPath()) { + navigation.goBack(); // prevent sequences of same url in history + } } export interface IURLParams

{ From 87061cee9e067744a7bf78e1cf4c9deb4d610a04 Mon Sep 17 00:00:00 2001 From: Sebastian Malton Date: Fri, 2 Oct 2020 10:05:59 -0400 Subject: [PATCH 7/7] Refactor testing harness to use defaults (#808) * Refactor testing harness to use defaults - Move tests into defaultly named test folders - Use default test suffix of ".test" instead of "_test" - Make cluster-store tests unit tests by adding more nesting, so that order of tests doesn't matter Signed-off-by: Sebastian Malton Co-authored-by: Sebastian Malton --- .../app_spec.ts => __tests__/app.tests.ts} | 0 integration/helpers/utils.ts | 19 +- locales/en/messages.po | 116 +++++----- locales/fi/messages.po | 114 +++++----- locales/ru/messages.po | 114 +++++----- package.json | 1 - .../cluster-store.test.ts} | 201 +++++++++--------- .../user-store.test.ts} | 2 +- .../workspace-store.test.ts} | 2 +- .../splitArray.test.ts} | 4 +- .../kube-api-parse.test.ts} | 15 +- .../components/cluster-name-setting.tsx | 4 +- .../components/cluster-proxy-setting.tsx | 4 +- .../add-quota-dialog.tsx | 10 +- .../+config-secrets/add-secret-dialog.tsx | 8 +- .../+namespaces/add-namespace-dialog.tsx | 2 +- .../+preferences/kubectl-binaries.tsx | 2 +- .../create-service-account-dialog.tsx | 6 +- .../cronjob-trigger-dialog.tsx | 2 +- .../components/+workspaces/workspaces.tsx | 2 +- .../input_validators.test.ts} | 2 +- src/renderer/components/input/input.tsx | 8 +- ...nput.validators.ts => input_validators.ts} | 0 .../formatDuration.test.ts} | 12 +- .../metricUnitsToNumber.test.ts} | 2 +- 25 files changed, 345 insertions(+), 307 deletions(-) rename integration/{specs/app_spec.ts => __tests__/app.tests.ts} (100%) rename src/common/{cluster-store_test.ts => __tests__/cluster-store.test.ts} (66%) rename src/common/{user-store_test.ts => __tests__/user-store.test.ts} (98%) rename src/common/{workspace-store_test.ts => __tests__/workspace-store.test.ts} (98%) rename src/common/utils/{splitArray_test.ts => __tests__/splitArray.test.ts} (95%) rename src/renderer/api/{kube-api-parse_test.ts => __tests__/kube-api-parse.test.ts} (89%) rename src/renderer/components/input/{input.validators_test.ts => __tests__/input_validators.test.ts} (97%) rename src/renderer/components/input/{input.validators.ts => input_validators.ts} (100%) rename src/renderer/utils/{formatDuration_spec.ts => __tests__/formatDuration.test.ts} (95%) rename src/renderer/utils/{metricUnitsToNumber_test.ts => __tests__/metricUnitsToNumber.test.ts} (85%) diff --git a/integration/specs/app_spec.ts b/integration/__tests__/app.tests.ts similarity index 100% rename from integration/specs/app_spec.ts rename to integration/__tests__/app.tests.ts diff --git a/integration/helpers/utils.ts b/integration/helpers/utils.ts index 72d6e3d732..a50b13e023 100644 --- a/integration/helpers/utils.ts +++ b/integration/helpers/utils.ts @@ -1,23 +1,16 @@ import { Application } from "spectron"; -let appPath = "" -switch(process.platform) { -case "win32": - appPath = "./dist/win-unpacked/Lens.exe" - break -case "linux": - appPath = "./dist/linux-unpacked/kontena-lens" - break -case "darwin": - appPath = "./dist/mac/Lens.app/Contents/MacOS/Lens" - break +const AppPaths: Partial> = { + "win32": "./dist/win-unpacked/Lens.exe", + "linux": "./dist/linux-unpacked/kontena-lens", + "darwin": "./dist/mac/Lens.app/Contents/MacOS/Lens", } export function setup(): Application { return new Application({ // path to electron app args: [], - path: appPath, + path: AppPaths[process.platform], startTimeout: 30000, waitTimeout: 30000, chromeDriverArgs: ['remote-debugging-port=9222'], @@ -32,7 +25,7 @@ export async function tearDown(app: Application) { await app.stop() try { process.kill(pid, 0); - } catch(e) { + } catch (e) { return } } diff --git a/locales/en/messages.po b/locales/en/messages.po index 092161d0cf..86f99a841f 100644 --- a/locales/en/messages.po +++ b/locales/en/messages.po @@ -49,7 +49,7 @@ msgstr "<0>Filtered: {itemsCount} / {allItemsCount}" #~ msgid "<0>Your browser does not support all Lens features. Please consider using another browser." #~ msgstr "<0>Your browser does not support all Lens features. Please consider using another browser." -#: src/renderer/components/dock/create-resource.tsx:56 +#: src/renderer/components/dock/create-resource.tsx:58 msgid "<0>{0} successfully created" msgstr "<0>{0} successfully created" @@ -57,7 +57,7 @@ msgstr "<0>{0} successfully created" #~ msgid "A HTTP proxy server URL (format: http://

:)" #~ msgstr "A HTTP proxy server URL (format: http://
:)" -#: src/renderer/components/input/input.validators.ts:46 +#: src/renderer/components/input/input_validators.ts:46 msgid "A System Name must be lowercase DNS labels separated by dots. DNS labels are alphanumerics and dashes enclosed by alphanumerics." msgstr "A System Name must be lowercase DNS labels separated by dots. DNS labels are alphanumerics and dashes enclosed by alphanumerics." @@ -87,7 +87,7 @@ msgstr "Account Name" msgid "Active" msgstr "Active" -#: src/renderer/components/+add-cluster/add-cluster.tsx:288 +#: src/renderer/components/+add-cluster/add-cluster.tsx:289 #: src/renderer/components/cluster-manager/clusters-menu.tsx:130 msgid "Add Cluster" msgstr "Add Cluster" @@ -112,7 +112,7 @@ msgstr "Add bindings to {name}" #~ msgid "Add cluster" #~ msgstr "Add cluster" -#: src/renderer/components/+add-cluster/add-cluster.tsx:305 +#: src/renderer/components/+add-cluster/add-cluster.tsx:306 msgid "Add cluster(s)" msgstr "Add cluster(s)" @@ -273,7 +273,7 @@ msgstr "App Version" msgid "App crash at <0>{pageUrl}" msgstr "App crash at <0>{pageUrl}" -#: src/renderer/components/dock/edit-resource.tsx:88 +#: src/renderer/components/dock/edit-resource.tsx:87 msgid "Applying.." msgstr "Applying.." @@ -404,7 +404,7 @@ msgstr "CPU:" #: src/renderer/components/+workspaces/workspaces.tsx:133 #: src/renderer/components/confirm-dialog/confirm-dialog.tsx:44 -#: src/renderer/components/dock/info-panel.tsx:97 +#: src/renderer/components/dock/info-panel.tsx:85 #: src/renderer/components/wizard/wizard.tsx:130 msgid "Cancel" msgstr "Cancel" @@ -440,7 +440,7 @@ msgstr "Chart" msgid "Chart Release <0>{0} successfully created." msgstr "Chart Release <0>{0} successfully created." -#: src/renderer/components/+apps-helm-charts/helm-chart-details.tsx:105 +#: src/renderer/components/+apps-helm-charts/helm-chart-details.tsx:124 msgid "Chart: {0}" msgstr "Chart: {0}" @@ -647,7 +647,7 @@ msgstr "Count" #: src/renderer/components/+user-management-roles/add-role-dialog.tsx:73 #: src/renderer/components/+user-management-roles-bindings/add-role-binding-dialog.tsx:212 #: src/renderer/components/+user-management-service-accounts/create-service-account-dialog.tsx:76 -#: src/renderer/components/dock/create-resource.tsx:71 +#: src/renderer/components/dock/create-resource.tsx:74 msgid "Create" msgstr "Create" @@ -691,7 +691,7 @@ msgstr "Create new Secret" msgid "Create new Service Account" msgstr "Create new Service Account" -#: src/renderer/components/dock/dock.tsx:111 +#: src/renderer/components/dock/dock.tsx:93 msgid "Create resource" msgstr "Create resource" @@ -783,8 +783,8 @@ msgid "Default Runtime Class Name" msgstr "Default Runtime Class Name" #: src/renderer/components/+preferences/kubectl-binaries.tsx:30 -msgid "Default:" -msgstr "Default:" +#~ msgid "Default:" +#~ msgstr "Default:" #: src/renderer/components/+custom-resources/custom-resources.tsx:22 msgid "Definitions" @@ -848,15 +848,19 @@ msgstr "Domains" msgid "Download file" msgstr "Download file" -#: src/renderer/components/+preferences/kubectl-binaries.tsx:39 +#: src/renderer/components/+preferences/kubectl-binaries.tsx:24 msgid "Download kubectl binaries" msgstr "Download kubectl binaries" #: src/renderer/components/+preferences/kubectl-binaries.tsx:37 -msgid "Download kubectl binaries matching to Kubernetes cluster verison." -msgstr "Download kubectl binaries matching to Kubernetes cluster verison." +#~ msgid "Download kubectl binaries matching to Kubernetes cluster verison." +#~ msgstr "Download kubectl binaries matching to Kubernetes cluster verison." -#: src/renderer/components/+preferences/kubectl-binaries.tsx:41 +#: src/renderer/components/+preferences/kubectl-binaries.tsx:26 +msgid "Download kubectl binaries matching to Kubernetes cluster version." +msgstr "Download kubectl binaries matching to Kubernetes cluster version." + +#: src/renderer/components/+preferences/kubectl-binaries.tsx:29 msgid "Download mirror for kubectl" msgstr "Download mirror for kubectl" @@ -944,7 +948,7 @@ msgstr "Everything is fine in the Cluster" #~ msgid "Excluded items with \"system:\" prefix" #~ msgstr "Excluded items with \"system:\" prefix" -#: src/renderer/components/dock/dock.tsx:116 +#: src/renderer/components/dock/dock.tsx:98 msgid "Exit full size mode" msgstr "Exit full size mode" @@ -985,7 +989,7 @@ msgstr "Finalizers" msgid "First seen" msgstr "First seen" -#: src/renderer/components/dock/dock.tsx:116 +#: src/renderer/components/dock/dock.tsx:98 msgid "Fit to window" msgstr "Fit to window" @@ -1073,7 +1077,7 @@ msgstr "Hide" msgid "High number of replicas may cause cluster performance issues" msgstr "High number of replicas may cause cluster performance issues" -#: src/renderer/components/+apps-helm-charts/helm-chart-details.tsx:81 +#: src/renderer/components/+apps-helm-charts/helm-chart-details.tsx:88 msgid "Home" msgstr "Home" @@ -1128,7 +1132,7 @@ msgstr "Image" msgid "ImagePullPolicy" msgstr "ImagePullPolicy" -#: src/renderer/components/+user-management-service-accounts/service-accounts-details.tsx:80 +#: src/renderer/components/+user-management-service-accounts/service-accounts-details.tsx:108 msgid "ImagePullSecrets" msgstr "ImagePullSecrets" @@ -1153,8 +1157,8 @@ msgstr "Ingresses" msgid "Init Containers" msgstr "Init Containers" -#: src/renderer/components/+apps-helm-charts/helm-chart-details.tsx:76 -#: src/renderer/components/dock/install-chart.tsx:128 +#: src/renderer/components/+apps-helm-charts/helm-chart-details.tsx:83 +#: src/renderer/components/dock/install-chart.tsx:127 msgid "Install" msgstr "Install" @@ -1162,15 +1166,15 @@ msgstr "Install" msgid "Installation complete!" msgstr "Installation complete!" -#: src/renderer/components/dock/install-chart.tsx:128 +#: src/renderer/components/dock/install-chart.tsx:127 msgid "Installing..." msgstr "Installing..." -#: src/renderer/components/input/input.validators.ts:50 +#: src/renderer/components/input/input_validators.ts:50 msgid "Invalid account ID" msgstr "Invalid account ID" -#: src/renderer/components/input/input.validators.ts:16 +#: src/renderer/components/input/input_validators.ts:16 msgid "Invalid number" msgstr "Invalid number" @@ -1231,13 +1235,13 @@ msgstr "Key Size" msgid "Keys" msgstr "Keys" -#: src/renderer/components/+apps-helm-charts/helm-chart-details.tsx:87 +#: src/renderer/components/+apps-helm-charts/helm-chart-details.tsx:94 msgid "Keywords" msgstr "Keywords" #: src/renderer/components/+events/event-details.tsx:57 #: src/renderer/components/+user-management-roles-bindings/role-binding-details.tsx:79 -#: src/renderer/components/dock/edit-resource.tsx:89 +#: src/renderer/components/dock/edit-resource.tsx:88 msgid "Kind" msgstr "Kind" @@ -1249,7 +1253,7 @@ msgstr "Kubeconfig" msgid "Kubeconfig File" msgstr "Kubeconfig File" -#: src/renderer/components/+preferences/kubectl-binaries.tsx:35 +#: src/renderer/components/+preferences/kubectl-binaries.tsx:23 msgid "Kubectl Binary" msgstr "Kubectl Binary" @@ -1343,7 +1347,7 @@ msgstr "Logs" msgid "Logs copied to clipboard." msgstr "Logs copied to clipboard." -#: src/renderer/components/+apps-helm-charts/helm-chart-details.tsx:84 +#: src/renderer/components/+apps-helm-charts/helm-chart-details.tsx:91 msgid "Maintainers" msgstr "Maintainers" @@ -1369,7 +1373,7 @@ msgstr "Max Pods" msgid "Max Unavailable" msgstr "Max Unavailable" -#: src/renderer/components/input/input.validators.ts:41 +#: src/renderer/components/input/input_validators.ts:41 msgid "Maximum length is {maxLength}" msgstr "Maximum length is {maxLength}" @@ -1441,11 +1445,11 @@ msgstr "Min Available" msgid "Min Pods" msgstr "Min Pods" -#: src/renderer/components/dock/dock.tsx:117 +#: src/renderer/components/dock/dock.tsx:99 msgid "Minimize" msgstr "Minimize" -#: src/renderer/components/input/input.validators.ts:36 +#: src/renderer/components/input/input_validators.ts:36 msgid "Minimum length is {minLength}" msgstr "Minimum length is {minLength}" @@ -1454,7 +1458,7 @@ msgstr "Minimum length is {minLength}" msgid "Mount Options" msgstr "Mount Options" -#: src/renderer/components/+user-management-service-accounts/service-accounts-details.tsx:84 +#: src/renderer/components/+user-management-service-accounts/service-accounts-details.tsx:112 msgid "Mountable secrets" msgstr "Mountable secrets" @@ -1510,7 +1514,7 @@ msgstr "Mounts" #: src/renderer/components/+workloads-replicasets/replicasets.tsx:50 #: src/renderer/components/+workloads-statefulsets/statefulsets.tsx:40 #: src/renderer/components/+workspaces/workspaces.tsx:130 -#: src/renderer/components/dock/edit-resource.tsx:90 +#: src/renderer/components/dock/edit-resource.tsx:89 #: src/renderer/components/kube-object/kube-object-meta.tsx:20 msgid "Name" msgstr "Name" @@ -1556,7 +1560,7 @@ msgstr "Names" #: src/renderer/components/+workloads-jobs/jobs.tsx:38 #: src/renderer/components/+workloads-pods/pods.tsx:76 #: src/renderer/components/+workloads-statefulsets/statefulsets.tsx:41 -#: src/renderer/components/dock/edit-resource.tsx:91 +#: src/renderer/components/dock/edit-resource.tsx:90 #: src/renderer/components/dock/install-chart.tsx:122 #: src/renderer/components/dock/upgrade-chart.tsx:98 #: src/renderer/components/item-object-list/page-filters-select.tsx:57 @@ -1600,7 +1604,7 @@ msgstr "Network Policies" msgid "New logs since opening the dialog" msgstr "New logs since opening the dialog" -#: src/renderer/components/dock/dock.tsx:104 +#: src/renderer/components/dock/dock.tsx:86 msgid "New tab" msgstr "New tab" @@ -1734,7 +1738,7 @@ msgstr "Ok" msgid "Ok, got it!" msgstr "Ok, got it!" -#: src/renderer/components/dock/dock.tsx:117 +#: src/renderer/components/dock/dock.tsx:99 msgid "Open" msgstr "Open" @@ -1939,7 +1943,7 @@ msgstr "Provisioner" msgid "Proxy is used only for non-cluster communication." msgstr "Proxy is used only for non-cluster communication." -#: src/renderer/components/+add-cluster/add-cluster.tsx:293 +#: src/renderer/components/+add-cluster/add-cluster.tsx:294 msgid "Proxy settings" msgstr "Proxy settings" @@ -2264,7 +2268,7 @@ msgstr "Runtime Class" #: src/renderer/components/+config-secrets/secret-details.tsx:97 #: src/renderer/components/+workloads-pods/pod-logs-dialog.tsx:216 #: src/renderer/components/+workspaces/workspaces.tsx:132 -#: src/renderer/components/dock/edit-resource.tsx:88 +#: src/renderer/components/dock/edit-resource.tsx:87 msgid "Save" msgstr "Save" @@ -2318,6 +2322,10 @@ msgstr "Secret" msgid "Secret Name" msgstr "Secret Name" +#: src/renderer/components/+user-management-service-accounts/service-accounts-details.tsx:72 +msgid "Secret is not found" +msgstr "Secret is not found" + #: src/renderer/components/+config-secrets/add-secret-dialog.tsx:147 msgid "Secret name" msgstr "Secret name" @@ -2472,7 +2480,7 @@ msgid "Shell" msgstr "Shell" #: src/renderer/components/+config-secrets/secret-details.tsx:93 -#: src/renderer/components/+workloads-pods/pod-container-env.tsx:100 +#: src/renderer/components/+workloads-pods/pod-container-env.tsx:101 #: src/renderer/components/+workloads-pods/pod-logs-dialog.tsx:215 #: src/renderer/components/drawer/drawer-param-toggler.tsx:19 msgid "Show" @@ -2580,12 +2588,12 @@ msgstr "Strategy Type" msgid "Sub-object" msgstr "Sub-object" -#: src/renderer/components/dock/info-panel.tsx:104 +#: src/renderer/components/dock/info-panel.tsx:93 #: src/renderer/components/wizard/wizard.tsx:131 msgid "Submit" msgstr "Submit" -#: src/renderer/components/dock/info-panel.tsx:105 +#: src/renderer/components/dock/info-panel.tsx:94 msgid "Submitting.." msgstr "Submitting.." @@ -2627,10 +2635,14 @@ msgstr "Telemetry & usage data is collected to continuously improve the Lens exp msgid "Terminal" msgstr "Terminal" -#: src/renderer/components/dock/dock.tsx:107 +#: src/renderer/components/dock/dock.tsx:89 msgid "Terminal session" msgstr "Terminal session" +#: src/renderer/components/+preferences/kubectl-binaries.tsx:38 +msgid "The path to the kubectl binary on the system." +msgstr "The path to the kubectl binary on the system." + #: src/renderer/components/+workloads-pods/pod-logs-dialog.tsx:226 msgid "There are no logs available for container." msgstr "There are no logs available for container." @@ -2639,11 +2651,11 @@ msgstr "There are no logs available for container." msgid "There are no logs available." msgstr "There are no logs available." -#: src/renderer/components/input/input.validators.ts:6 +#: src/renderer/components/input/input_validators.ts:6 msgid "This field is required" msgstr "This field is required" -#: src/renderer/components/input/input.validators.ts:31 +#: src/renderer/components/input/input_validators.ts:31 msgid "This field must be a valid path" msgstr "This field must be a valid path" @@ -2663,7 +2675,7 @@ msgstr "To" msgid "To help us improve the product please report bugs to {slackLink} community or {githubLink} issues tracker." msgstr "To help us improve the product please report bugs to {slackLink} community or {githubLink} issues tracker." -#: src/renderer/components/+user-management-service-accounts/service-accounts-details.tsx:76 +#: src/renderer/components/+user-management-service-accounts/service-accounts-details.tsx:104 msgid "Tokens" msgstr "Tokens" @@ -2730,12 +2742,12 @@ msgstr "Update" msgid "Updated" msgstr "Updated" -#: src/renderer/components/dock/upgrade-chart.tsx:105 +#: src/renderer/components/dock/upgrade-chart.tsx:104 msgid "Updating.." msgstr "Updating.." #: src/renderer/components/+apps-releases/release-details.tsx:176 -#: src/renderer/components/dock/upgrade-chart.tsx:105 +#: src/renderer/components/dock/upgrade-chart.tsx:104 msgid "Upgrade" msgstr "Upgrade" @@ -2799,7 +2811,7 @@ msgstr "Values" msgid "Verbs" msgstr "Verbs" -#: src/renderer/components/+apps-helm-charts/helm-chart-details.tsx:78 +#: src/renderer/components/+apps-helm-charts/helm-chart-details.tsx:85 #: src/renderer/components/+apps-helm-charts/helm-charts.tsx:66 #: src/renderer/components/+apps-releases/release-details.tsx:185 #: src/renderer/components/+apps-releases/releases.tsx:91 @@ -2866,11 +2878,11 @@ msgstr "Workspaces" msgid "Workspaces are used to organize number of clusters into logical groups." msgstr "Workspaces are used to organize number of clusters into logical groups." -#: src/renderer/components/input/input.validators.ts:11 +#: src/renderer/components/input/input_validators.ts:11 msgid "Wrong email format" msgstr "Wrong email format" -#: src/renderer/components/input/input.validators.ts:26 +#: src/renderer/components/input/input_validators.ts:26 msgid "Wrong url format" msgstr "Wrong url format" @@ -2953,7 +2965,7 @@ msgstr "singular" msgid "timestamps" msgstr "timestamps" -#: src/renderer/components/dock/create-resource.tsx:55 +#: src/renderer/components/dock/create-resource.tsx:57 msgid "{0, plural, one {Resource} other {Resources}}" msgstr "{0, plural, one {Resource} other {Resources}}" @@ -3005,6 +3017,6 @@ msgstr "{resourceType} <0>{resourceName} updated." msgid "{selectedCount, plural, one {<0>Remove item <1>{selectedNames}?} other {<2>Remove <3>{selectedCount} items <4>{selectedNames} {tail}?}}" msgstr "{selectedCount, plural, one {<0>Remove item <1>{selectedNames}?} other {<2>Remove <3>{selectedCount} items <4>{selectedNames} {tail}?}}" -#: src/renderer/components/dock/info-panel.tsx:99 +#: src/renderer/components/dock/info-panel.tsx:88 msgid "{submitLabel} & Close" msgstr "{submitLabel} & Close" diff --git a/locales/fi/messages.po b/locales/fi/messages.po index 363b9a49cc..1b53f1bffa 100644 --- a/locales/fi/messages.po +++ b/locales/fi/messages.po @@ -49,7 +49,7 @@ msgstr "" #~ msgid "<0>Your browser does not support all Lens features. Please consider using another browser." #~ msgstr "" -#: src/renderer/components/dock/create-resource.tsx:56 +#: src/renderer/components/dock/create-resource.tsx:58 msgid "<0>{0} successfully created" msgstr "" @@ -57,7 +57,7 @@ msgstr "" #~ msgid "A HTTP proxy server URL (format: http://
:)" #~ msgstr "" -#: src/renderer/components/input/input.validators.ts:46 +#: src/renderer/components/input/input_validators.ts:46 msgid "A System Name must be lowercase DNS labels separated by dots. DNS labels are alphanumerics and dashes enclosed by alphanumerics." msgstr "" @@ -87,7 +87,7 @@ msgstr "" msgid "Active" msgstr "" -#: src/renderer/components/+add-cluster/add-cluster.tsx:288 +#: src/renderer/components/+add-cluster/add-cluster.tsx:289 #: src/renderer/components/cluster-manager/clusters-menu.tsx:130 msgid "Add Cluster" msgstr "" @@ -112,7 +112,7 @@ msgstr "" #~ msgid "Add cluster" #~ msgstr "" -#: src/renderer/components/+add-cluster/add-cluster.tsx:305 +#: src/renderer/components/+add-cluster/add-cluster.tsx:306 msgid "Add cluster(s)" msgstr "" @@ -273,7 +273,7 @@ msgstr "" msgid "App crash at <0>{pageUrl}" msgstr "" -#: src/renderer/components/dock/edit-resource.tsx:88 +#: src/renderer/components/dock/edit-resource.tsx:87 msgid "Applying.." msgstr "" @@ -404,7 +404,7 @@ msgstr "" #: src/renderer/components/+workspaces/workspaces.tsx:133 #: src/renderer/components/confirm-dialog/confirm-dialog.tsx:44 -#: src/renderer/components/dock/info-panel.tsx:97 +#: src/renderer/components/dock/info-panel.tsx:85 #: src/renderer/components/wizard/wizard.tsx:130 msgid "Cancel" msgstr "" @@ -440,7 +440,7 @@ msgstr "" msgid "Chart Release <0>{0} successfully created." msgstr "" -#: src/renderer/components/+apps-helm-charts/helm-chart-details.tsx:105 +#: src/renderer/components/+apps-helm-charts/helm-chart-details.tsx:124 msgid "Chart: {0}" msgstr "" @@ -643,7 +643,7 @@ msgstr "" #: src/renderer/components/+user-management-roles/add-role-dialog.tsx:73 #: src/renderer/components/+user-management-roles-bindings/add-role-binding-dialog.tsx:212 #: src/renderer/components/+user-management-service-accounts/create-service-account-dialog.tsx:76 -#: src/renderer/components/dock/create-resource.tsx:71 +#: src/renderer/components/dock/create-resource.tsx:74 msgid "Create" msgstr "" @@ -687,7 +687,7 @@ msgstr "" msgid "Create new Service Account" msgstr "" -#: src/renderer/components/dock/dock.tsx:111 +#: src/renderer/components/dock/dock.tsx:93 msgid "Create resource" msgstr "" @@ -779,8 +779,8 @@ msgid "Default Runtime Class Name" msgstr "" #: src/renderer/components/+preferences/kubectl-binaries.tsx:30 -msgid "Default:" -msgstr "" +#~ msgid "Default:" +#~ msgstr "" #: src/renderer/components/+custom-resources/custom-resources.tsx:22 msgid "Definitions" @@ -844,15 +844,19 @@ msgstr "" msgid "Download file" msgstr "" -#: src/renderer/components/+preferences/kubectl-binaries.tsx:39 +#: src/renderer/components/+preferences/kubectl-binaries.tsx:24 msgid "Download kubectl binaries" msgstr "" #: src/renderer/components/+preferences/kubectl-binaries.tsx:37 -msgid "Download kubectl binaries matching to Kubernetes cluster verison." +#~ msgid "Download kubectl binaries matching to Kubernetes cluster verison." +#~ msgstr "" + +#: src/renderer/components/+preferences/kubectl-binaries.tsx:26 +msgid "Download kubectl binaries matching to Kubernetes cluster version." msgstr "" -#: src/renderer/components/+preferences/kubectl-binaries.tsx:41 +#: src/renderer/components/+preferences/kubectl-binaries.tsx:29 msgid "Download mirror for kubectl" msgstr "" @@ -935,7 +939,7 @@ msgstr "" msgid "Everything is fine in the Cluster" msgstr "" -#: src/renderer/components/dock/dock.tsx:116 +#: src/renderer/components/dock/dock.tsx:98 msgid "Exit full size mode" msgstr "" @@ -976,7 +980,7 @@ msgstr "" msgid "First seen" msgstr "" -#: src/renderer/components/dock/dock.tsx:116 +#: src/renderer/components/dock/dock.tsx:98 msgid "Fit to window" msgstr "" @@ -1064,7 +1068,7 @@ msgstr "" msgid "High number of replicas may cause cluster performance issues" msgstr "" -#: src/renderer/components/+apps-helm-charts/helm-chart-details.tsx:81 +#: src/renderer/components/+apps-helm-charts/helm-chart-details.tsx:88 msgid "Home" msgstr "" @@ -1119,7 +1123,7 @@ msgstr "" msgid "ImagePullPolicy" msgstr "" -#: src/renderer/components/+user-management-service-accounts/service-accounts-details.tsx:80 +#: src/renderer/components/+user-management-service-accounts/service-accounts-details.tsx:108 msgid "ImagePullSecrets" msgstr "" @@ -1144,8 +1148,8 @@ msgstr "" msgid "Init Containers" msgstr "" -#: src/renderer/components/+apps-helm-charts/helm-chart-details.tsx:76 -#: src/renderer/components/dock/install-chart.tsx:128 +#: src/renderer/components/+apps-helm-charts/helm-chart-details.tsx:83 +#: src/renderer/components/dock/install-chart.tsx:127 msgid "Install" msgstr "" @@ -1153,15 +1157,15 @@ msgstr "" msgid "Installation complete!" msgstr "" -#: src/renderer/components/dock/install-chart.tsx:128 +#: src/renderer/components/dock/install-chart.tsx:127 msgid "Installing..." msgstr "" -#: src/renderer/components/input/input.validators.ts:50 +#: src/renderer/components/input/input_validators.ts:50 msgid "Invalid account ID" msgstr "" -#: src/renderer/components/input/input.validators.ts:16 +#: src/renderer/components/input/input_validators.ts:16 msgid "Invalid number" msgstr "" @@ -1222,13 +1226,13 @@ msgstr "" msgid "Keys" msgstr "" -#: src/renderer/components/+apps-helm-charts/helm-chart-details.tsx:87 +#: src/renderer/components/+apps-helm-charts/helm-chart-details.tsx:94 msgid "Keywords" msgstr "" #: src/renderer/components/+events/event-details.tsx:57 #: src/renderer/components/+user-management-roles-bindings/role-binding-details.tsx:79 -#: src/renderer/components/dock/edit-resource.tsx:89 +#: src/renderer/components/dock/edit-resource.tsx:88 msgid "Kind" msgstr "" @@ -1240,7 +1244,7 @@ msgstr "" msgid "Kubeconfig File" msgstr "" -#: src/renderer/components/+preferences/kubectl-binaries.tsx:35 +#: src/renderer/components/+preferences/kubectl-binaries.tsx:23 msgid "Kubectl Binary" msgstr "" @@ -1334,7 +1338,7 @@ msgstr "" msgid "Logs copied to clipboard." msgstr "" -#: src/renderer/components/+apps-helm-charts/helm-chart-details.tsx:84 +#: src/renderer/components/+apps-helm-charts/helm-chart-details.tsx:91 msgid "Maintainers" msgstr "" @@ -1360,7 +1364,7 @@ msgstr "" msgid "Max Unavailable" msgstr "" -#: src/renderer/components/input/input.validators.ts:41 +#: src/renderer/components/input/input_validators.ts:41 msgid "Maximum length is {maxLength}" msgstr "" @@ -1432,11 +1436,11 @@ msgstr "" msgid "Min Pods" msgstr "" -#: src/renderer/components/dock/dock.tsx:117 +#: src/renderer/components/dock/dock.tsx:99 msgid "Minimize" msgstr "" -#: src/renderer/components/input/input.validators.ts:36 +#: src/renderer/components/input/input_validators.ts:36 msgid "Minimum length is {minLength}" msgstr "" @@ -1445,7 +1449,7 @@ msgstr "" msgid "Mount Options" msgstr "" -#: src/renderer/components/+user-management-service-accounts/service-accounts-details.tsx:84 +#: src/renderer/components/+user-management-service-accounts/service-accounts-details.tsx:112 msgid "Mountable secrets" msgstr "" @@ -1501,7 +1505,7 @@ msgstr "" #: src/renderer/components/+workloads-replicasets/replicasets.tsx:50 #: src/renderer/components/+workloads-statefulsets/statefulsets.tsx:40 #: src/renderer/components/+workspaces/workspaces.tsx:130 -#: src/renderer/components/dock/edit-resource.tsx:90 +#: src/renderer/components/dock/edit-resource.tsx:89 #: src/renderer/components/kube-object/kube-object-meta.tsx:20 msgid "Name" msgstr "" @@ -1547,7 +1551,7 @@ msgstr "" #: src/renderer/components/+workloads-jobs/jobs.tsx:38 #: src/renderer/components/+workloads-pods/pods.tsx:76 #: src/renderer/components/+workloads-statefulsets/statefulsets.tsx:41 -#: src/renderer/components/dock/edit-resource.tsx:91 +#: src/renderer/components/dock/edit-resource.tsx:90 #: src/renderer/components/dock/install-chart.tsx:122 #: src/renderer/components/dock/upgrade-chart.tsx:98 #: src/renderer/components/item-object-list/page-filters-select.tsx:57 @@ -1591,7 +1595,7 @@ msgstr "" msgid "New logs since opening the dialog" msgstr "" -#: src/renderer/components/dock/dock.tsx:104 +#: src/renderer/components/dock/dock.tsx:86 msgid "New tab" msgstr "" @@ -1717,7 +1721,7 @@ msgstr "" msgid "Ok, got it!" msgstr "" -#: src/renderer/components/dock/dock.tsx:117 +#: src/renderer/components/dock/dock.tsx:99 msgid "Open" msgstr "" @@ -1922,7 +1926,7 @@ msgstr "" msgid "Proxy is used only for non-cluster communication." msgstr "" -#: src/renderer/components/+add-cluster/add-cluster.tsx:293 +#: src/renderer/components/+add-cluster/add-cluster.tsx:294 msgid "Proxy settings" msgstr "" @@ -2247,7 +2251,7 @@ msgstr "" #: src/renderer/components/+config-secrets/secret-details.tsx:97 #: src/renderer/components/+workloads-pods/pod-logs-dialog.tsx:216 #: src/renderer/components/+workspaces/workspaces.tsx:132 -#: src/renderer/components/dock/edit-resource.tsx:88 +#: src/renderer/components/dock/edit-resource.tsx:87 msgid "Save" msgstr "" @@ -2301,6 +2305,10 @@ msgstr "" msgid "Secret Name" msgstr "" +#: src/renderer/components/+user-management-service-accounts/service-accounts-details.tsx:72 +msgid "Secret is not found" +msgstr "" + #: src/renderer/components/+config-secrets/add-secret-dialog.tsx:147 msgid "Secret name" msgstr "" @@ -2455,7 +2463,7 @@ msgid "Shell" msgstr "" #: src/renderer/components/+config-secrets/secret-details.tsx:93 -#: src/renderer/components/+workloads-pods/pod-container-env.tsx:100 +#: src/renderer/components/+workloads-pods/pod-container-env.tsx:101 #: src/renderer/components/+workloads-pods/pod-logs-dialog.tsx:215 #: src/renderer/components/drawer/drawer-param-toggler.tsx:19 msgid "Show" @@ -2563,12 +2571,12 @@ msgstr "" msgid "Sub-object" msgstr "" -#: src/renderer/components/dock/info-panel.tsx:104 +#: src/renderer/components/dock/info-panel.tsx:93 #: src/renderer/components/wizard/wizard.tsx:131 msgid "Submit" msgstr "" -#: src/renderer/components/dock/info-panel.tsx:105 +#: src/renderer/components/dock/info-panel.tsx:94 msgid "Submitting.." msgstr "" @@ -2610,10 +2618,14 @@ msgstr "" msgid "Terminal" msgstr "" -#: src/renderer/components/dock/dock.tsx:107 +#: src/renderer/components/dock/dock.tsx:89 msgid "Terminal session" msgstr "" +#: src/renderer/components/+preferences/kubectl-binaries.tsx:38 +msgid "The path to the kubectl binary on the system." +msgstr "" + #: src/renderer/components/+workloads-pods/pod-logs-dialog.tsx:226 msgid "There are no logs available for container." msgstr "" @@ -2622,11 +2634,11 @@ msgstr "" msgid "There are no logs available." msgstr "" -#: src/renderer/components/input/input.validators.ts:6 +#: src/renderer/components/input/input_validators.ts:6 msgid "This field is required" msgstr "" -#: src/renderer/components/input/input.validators.ts:31 +#: src/renderer/components/input/input_validators.ts:31 msgid "This field must be a valid path" msgstr "" @@ -2646,7 +2658,7 @@ msgstr "" msgid "To help us improve the product please report bugs to {slackLink} community or {githubLink} issues tracker." msgstr "" -#: src/renderer/components/+user-management-service-accounts/service-accounts-details.tsx:76 +#: src/renderer/components/+user-management-service-accounts/service-accounts-details.tsx:104 msgid "Tokens" msgstr "" @@ -2713,12 +2725,12 @@ msgstr "" msgid "Updated" msgstr "" -#: src/renderer/components/dock/upgrade-chart.tsx:105 +#: src/renderer/components/dock/upgrade-chart.tsx:104 msgid "Updating.." msgstr "" #: src/renderer/components/+apps-releases/release-details.tsx:176 -#: src/renderer/components/dock/upgrade-chart.tsx:105 +#: src/renderer/components/dock/upgrade-chart.tsx:104 msgid "Upgrade" msgstr "" @@ -2782,7 +2794,7 @@ msgstr "" msgid "Verbs" msgstr "" -#: src/renderer/components/+apps-helm-charts/helm-chart-details.tsx:78 +#: src/renderer/components/+apps-helm-charts/helm-chart-details.tsx:85 #: src/renderer/components/+apps-helm-charts/helm-charts.tsx:66 #: src/renderer/components/+apps-releases/release-details.tsx:185 #: src/renderer/components/+apps-releases/releases.tsx:91 @@ -2849,11 +2861,11 @@ msgstr "" msgid "Workspaces are used to organize number of clusters into logical groups." msgstr "" -#: src/renderer/components/input/input.validators.ts:11 +#: src/renderer/components/input/input_validators.ts:11 msgid "Wrong email format" msgstr "" -#: src/renderer/components/input/input.validators.ts:26 +#: src/renderer/components/input/input_validators.ts:26 msgid "Wrong url format" msgstr "" @@ -2936,7 +2948,7 @@ msgstr "" msgid "timestamps" msgstr "" -#: src/renderer/components/dock/create-resource.tsx:55 +#: src/renderer/components/dock/create-resource.tsx:57 msgid "{0, plural, one {Resource} other {Resources}}" msgstr "" @@ -2988,6 +3000,6 @@ msgstr "" msgid "{selectedCount, plural, one {<0>Remove item <1>{selectedNames}?} other {<2>Remove <3>{selectedCount} items <4>{selectedNames} {tail}?}}" msgstr "" -#: src/renderer/components/dock/info-panel.tsx:99 +#: src/renderer/components/dock/info-panel.tsx:88 msgid "{submitLabel} & Close" msgstr "" diff --git a/locales/ru/messages.po b/locales/ru/messages.po index ea3d5a9731..5cbf7f603e 100644 --- a/locales/ru/messages.po +++ b/locales/ru/messages.po @@ -50,7 +50,7 @@ msgstr "<0>Отфильтровано: {itemsCount} / {allItemsCount}" #~ msgid "<0>Your browser does not support all Lens features. Please consider using another browser." #~ msgstr "<0>Ваш браузер не поддерживает все возможности Lens. Пожалуйста рассмотрите использование другого современного браузера." -#: src/renderer/components/dock/create-resource.tsx:56 +#: src/renderer/components/dock/create-resource.tsx:58 msgid "<0>{0} successfully created" msgstr "" @@ -58,7 +58,7 @@ msgstr "" #~ msgid "A HTTP proxy server URL (format: http://
:)" #~ msgstr "" -#: src/renderer/components/input/input.validators.ts:46 +#: src/renderer/components/input/input_validators.ts:46 msgid "A System Name must be lowercase DNS labels separated by dots. DNS labels are alphanumerics and dashes enclosed by alphanumerics." msgstr "Это поле может содержать только латинские буквы в нижнем регистре, номера и дефис." @@ -88,7 +88,7 @@ msgstr "Название аккаунта" msgid "Active" msgstr "Активный" -#: src/renderer/components/+add-cluster/add-cluster.tsx:288 +#: src/renderer/components/+add-cluster/add-cluster.tsx:289 #: src/renderer/components/cluster-manager/clusters-menu.tsx:130 msgid "Add Cluster" msgstr "" @@ -113,7 +113,7 @@ msgstr "Добавить привязки к {name}" #~ msgid "Add cluster" #~ msgstr "" -#: src/renderer/components/+add-cluster/add-cluster.tsx:305 +#: src/renderer/components/+add-cluster/add-cluster.tsx:306 msgid "Add cluster(s)" msgstr "" @@ -274,7 +274,7 @@ msgstr "Версия приложения" msgid "App crash at <0>{pageUrl}" msgstr "Сбой работы приложения на <0>{pageUrl}" -#: src/renderer/components/dock/edit-resource.tsx:88 +#: src/renderer/components/dock/edit-resource.tsx:87 msgid "Applying.." msgstr "Применение.." @@ -405,7 +405,7 @@ msgstr "CPU:" #: src/renderer/components/+workspaces/workspaces.tsx:133 #: src/renderer/components/confirm-dialog/confirm-dialog.tsx:44 -#: src/renderer/components/dock/info-panel.tsx:97 +#: src/renderer/components/dock/info-panel.tsx:85 #: src/renderer/components/wizard/wizard.tsx:130 msgid "Cancel" msgstr "Отмена" @@ -441,7 +441,7 @@ msgstr "Чарт" msgid "Chart Release <0>{0} successfully created." msgstr "Релиз чарта <0>{0} успешно создан." -#: src/renderer/components/+apps-helm-charts/helm-chart-details.tsx:105 +#: src/renderer/components/+apps-helm-charts/helm-chart-details.tsx:124 msgid "Chart: {0}" msgstr "Чарт: {0}" @@ -648,7 +648,7 @@ msgstr "Кол-во" #: src/renderer/components/+user-management-roles/add-role-dialog.tsx:73 #: src/renderer/components/+user-management-roles-bindings/add-role-binding-dialog.tsx:212 #: src/renderer/components/+user-management-service-accounts/create-service-account-dialog.tsx:76 -#: src/renderer/components/dock/create-resource.tsx:71 +#: src/renderer/components/dock/create-resource.tsx:74 msgid "Create" msgstr "Создать" @@ -692,7 +692,7 @@ msgstr "Создать новый секрет" msgid "Create new Service Account" msgstr "Создать новый Service Account" -#: src/renderer/components/dock/dock.tsx:111 +#: src/renderer/components/dock/dock.tsx:93 msgid "Create resource" msgstr "Создать ресурс" @@ -784,8 +784,8 @@ msgid "Default Runtime Class Name" msgstr "" #: src/renderer/components/+preferences/kubectl-binaries.tsx:30 -msgid "Default:" -msgstr "" +#~ msgid "Default:" +#~ msgstr "" #: src/renderer/components/+custom-resources/custom-resources.tsx:22 msgid "Definitions" @@ -849,15 +849,19 @@ msgstr "Домены" msgid "Download file" msgstr "Скачать файл" -#: src/renderer/components/+preferences/kubectl-binaries.tsx:39 +#: src/renderer/components/+preferences/kubectl-binaries.tsx:24 msgid "Download kubectl binaries" msgstr "" #: src/renderer/components/+preferences/kubectl-binaries.tsx:37 -msgid "Download kubectl binaries matching to Kubernetes cluster verison." +#~ msgid "Download kubectl binaries matching to Kubernetes cluster verison." +#~ msgstr "" + +#: src/renderer/components/+preferences/kubectl-binaries.tsx:26 +msgid "Download kubectl binaries matching to Kubernetes cluster version." msgstr "" -#: src/renderer/components/+preferences/kubectl-binaries.tsx:41 +#: src/renderer/components/+preferences/kubectl-binaries.tsx:29 msgid "Download mirror for kubectl" msgstr "" @@ -945,7 +949,7 @@ msgstr "В кластере все в порядке" #~ msgid "Excluded items with \"system:\" prefix" #~ msgstr "За исключением объектов с префиксом “system:”" -#: src/renderer/components/dock/dock.tsx:116 +#: src/renderer/components/dock/dock.tsx:98 msgid "Exit full size mode" msgstr "Выйти из полного размера" @@ -986,7 +990,7 @@ msgstr "Финализаторы" msgid "First seen" msgstr "Увиденно впервые" -#: src/renderer/components/dock/dock.tsx:116 +#: src/renderer/components/dock/dock.tsx:98 msgid "Fit to window" msgstr "По размеру окна" @@ -1074,7 +1078,7 @@ msgstr "Скрыть" msgid "High number of replicas may cause cluster performance issues" msgstr "Большое количество реплик может вызвать проблемы с производительностью кластера" -#: src/renderer/components/+apps-helm-charts/helm-chart-details.tsx:81 +#: src/renderer/components/+apps-helm-charts/helm-chart-details.tsx:88 msgid "Home" msgstr "Ссылка" @@ -1129,7 +1133,7 @@ msgstr "Изображение" msgid "ImagePullPolicy" msgstr "ImagePullPolicy" -#: src/renderer/components/+user-management-service-accounts/service-accounts-details.tsx:80 +#: src/renderer/components/+user-management-service-accounts/service-accounts-details.tsx:108 msgid "ImagePullSecrets" msgstr "ImagePullSecrets" @@ -1154,8 +1158,8 @@ msgstr "Ingresses" msgid "Init Containers" msgstr "Контейнеры инициализации" -#: src/renderer/components/+apps-helm-charts/helm-chart-details.tsx:76 -#: src/renderer/components/dock/install-chart.tsx:128 +#: src/renderer/components/+apps-helm-charts/helm-chart-details.tsx:83 +#: src/renderer/components/dock/install-chart.tsx:127 msgid "Install" msgstr "Установить" @@ -1163,15 +1167,15 @@ msgstr "Установить" msgid "Installation complete!" msgstr "Установка завершена!" -#: src/renderer/components/dock/install-chart.tsx:128 +#: src/renderer/components/dock/install-chart.tsx:127 msgid "Installing..." msgstr "Установка.." -#: src/renderer/components/input/input.validators.ts:50 +#: src/renderer/components/input/input_validators.ts:50 msgid "Invalid account ID" msgstr "Неверный ID аккаунта" -#: src/renderer/components/input/input.validators.ts:16 +#: src/renderer/components/input/input_validators.ts:16 msgid "Invalid number" msgstr "Неверный номер" @@ -1232,13 +1236,13 @@ msgstr "Размер ключа" msgid "Keys" msgstr "Ключи" -#: src/renderer/components/+apps-helm-charts/helm-chart-details.tsx:87 +#: src/renderer/components/+apps-helm-charts/helm-chart-details.tsx:94 msgid "Keywords" msgstr "Ключевые слова" #: src/renderer/components/+events/event-details.tsx:57 #: src/renderer/components/+user-management-roles-bindings/role-binding-details.tsx:79 -#: src/renderer/components/dock/edit-resource.tsx:89 +#: src/renderer/components/dock/edit-resource.tsx:88 msgid "Kind" msgstr "Тип" @@ -1250,7 +1254,7 @@ msgstr "Файл конфигурации" msgid "Kubeconfig File" msgstr "Файл конфигурации" -#: src/renderer/components/+preferences/kubectl-binaries.tsx:35 +#: src/renderer/components/+preferences/kubectl-binaries.tsx:23 msgid "Kubectl Binary" msgstr "" @@ -1344,7 +1348,7 @@ msgstr "Логи" msgid "Logs copied to clipboard." msgstr "Скопировано." -#: src/renderer/components/+apps-helm-charts/helm-chart-details.tsx:84 +#: src/renderer/components/+apps-helm-charts/helm-chart-details.tsx:91 msgid "Maintainers" msgstr "Создатели" @@ -1370,7 +1374,7 @@ msgstr "Макс. подов" msgid "Max Unavailable" msgstr "" -#: src/renderer/components/input/input.validators.ts:41 +#: src/renderer/components/input/input_validators.ts:41 msgid "Maximum length is {maxLength}" msgstr "Максимальная длина {maxLength}" @@ -1442,11 +1446,11 @@ msgstr "" msgid "Min Pods" msgstr "Мин. подов" -#: src/renderer/components/dock/dock.tsx:117 +#: src/renderer/components/dock/dock.tsx:99 msgid "Minimize" msgstr "Минимизировать" -#: src/renderer/components/input/input.validators.ts:36 +#: src/renderer/components/input/input_validators.ts:36 msgid "Minimum length is {minLength}" msgstr "Минимальная длина {minLength}" @@ -1455,7 +1459,7 @@ msgstr "Минимальная длина {minLength}" msgid "Mount Options" msgstr "Опции монтирования" -#: src/renderer/components/+user-management-service-accounts/service-accounts-details.tsx:84 +#: src/renderer/components/+user-management-service-accounts/service-accounts-details.tsx:112 msgid "Mountable secrets" msgstr "Монтируемые секреты" @@ -1511,7 +1515,7 @@ msgstr "Установки" #: src/renderer/components/+workloads-replicasets/replicasets.tsx:50 #: src/renderer/components/+workloads-statefulsets/statefulsets.tsx:40 #: src/renderer/components/+workspaces/workspaces.tsx:130 -#: src/renderer/components/dock/edit-resource.tsx:90 +#: src/renderer/components/dock/edit-resource.tsx:89 #: src/renderer/components/kube-object/kube-object-meta.tsx:20 msgid "Name" msgstr "Имя" @@ -1557,7 +1561,7 @@ msgstr "" #: src/renderer/components/+workloads-jobs/jobs.tsx:38 #: src/renderer/components/+workloads-pods/pods.tsx:76 #: src/renderer/components/+workloads-statefulsets/statefulsets.tsx:41 -#: src/renderer/components/dock/edit-resource.tsx:91 +#: src/renderer/components/dock/edit-resource.tsx:90 #: src/renderer/components/dock/install-chart.tsx:122 #: src/renderer/components/dock/upgrade-chart.tsx:98 #: src/renderer/components/item-object-list/page-filters-select.tsx:57 @@ -1601,7 +1605,7 @@ msgstr "Network Policies" msgid "New logs since opening the dialog" msgstr "Новые логи с момента открытия диалога" -#: src/renderer/components/dock/dock.tsx:104 +#: src/renderer/components/dock/dock.tsx:86 msgid "New tab" msgstr "Новая вкладка" @@ -1735,7 +1739,7 @@ msgstr "Ок" msgid "Ok, got it!" msgstr "" -#: src/renderer/components/dock/dock.tsx:117 +#: src/renderer/components/dock/dock.tsx:99 msgid "Open" msgstr "Открыть" @@ -1940,7 +1944,7 @@ msgstr "Комиссия" msgid "Proxy is used only for non-cluster communication." msgstr "" -#: src/renderer/components/+add-cluster/add-cluster.tsx:293 +#: src/renderer/components/+add-cluster/add-cluster.tsx:294 msgid "Proxy settings" msgstr "" @@ -2265,7 +2269,7 @@ msgstr "" #: src/renderer/components/+config-secrets/secret-details.tsx:97 #: src/renderer/components/+workloads-pods/pod-logs-dialog.tsx:216 #: src/renderer/components/+workspaces/workspaces.tsx:132 -#: src/renderer/components/dock/edit-resource.tsx:88 +#: src/renderer/components/dock/edit-resource.tsx:87 msgid "Save" msgstr "Сохранить" @@ -2319,6 +2323,10 @@ msgstr "Секрет" msgid "Secret Name" msgstr "Название секрета" +#: src/renderer/components/+user-management-service-accounts/service-accounts-details.tsx:72 +msgid "Secret is not found" +msgstr "" + #: src/renderer/components/+config-secrets/add-secret-dialog.tsx:147 msgid "Secret name" msgstr "Имя секрета" @@ -2473,7 +2481,7 @@ msgid "Shell" msgstr "Командная строка" #: src/renderer/components/+config-secrets/secret-details.tsx:93 -#: src/renderer/components/+workloads-pods/pod-container-env.tsx:100 +#: src/renderer/components/+workloads-pods/pod-container-env.tsx:101 #: src/renderer/components/+workloads-pods/pod-logs-dialog.tsx:215 #: src/renderer/components/drawer/drawer-param-toggler.tsx:19 msgid "Show" @@ -2581,12 +2589,12 @@ msgstr "Тип стратегии" msgid "Sub-object" msgstr "Суб-объект" -#: src/renderer/components/dock/info-panel.tsx:104 +#: src/renderer/components/dock/info-panel.tsx:93 #: src/renderer/components/wizard/wizard.tsx:131 msgid "Submit" msgstr "Отправить" -#: src/renderer/components/dock/info-panel.tsx:105 +#: src/renderer/components/dock/info-panel.tsx:94 msgid "Submitting.." msgstr "Применение.." @@ -2628,10 +2636,14 @@ msgstr "" msgid "Terminal" msgstr "Терминал" -#: src/renderer/components/dock/dock.tsx:107 +#: src/renderer/components/dock/dock.tsx:89 msgid "Terminal session" msgstr "Сессия терминала" +#: src/renderer/components/+preferences/kubectl-binaries.tsx:38 +msgid "The path to the kubectl binary on the system." +msgstr "" + #: src/renderer/components/+workloads-pods/pod-logs-dialog.tsx:226 msgid "There are no logs available for container." msgstr "Для контейнера нет логов." @@ -2640,11 +2652,11 @@ msgstr "Для контейнера нет логов." msgid "There are no logs available." msgstr "Логи отсутствуют." -#: src/renderer/components/input/input.validators.ts:6 +#: src/renderer/components/input/input_validators.ts:6 msgid "This field is required" msgstr "Это обязательное поле" -#: src/renderer/components/input/input.validators.ts:31 +#: src/renderer/components/input/input_validators.ts:31 msgid "This field must be a valid path" msgstr "" @@ -2664,7 +2676,7 @@ msgstr "Из" msgid "To help us improve the product please report bugs to {slackLink} community or {githubLink} issues tracker." msgstr "Чтобы помочь нам улучшить продукт пожалуйста отправляйте ошибки на {slackLink} сообщество или {githubLink} трекер ошибок." -#: src/renderer/components/+user-management-service-accounts/service-accounts-details.tsx:76 +#: src/renderer/components/+user-management-service-accounts/service-accounts-details.tsx:104 msgid "Tokens" msgstr "Токены" @@ -2731,12 +2743,12 @@ msgstr "Обновить" msgid "Updated" msgstr "Обновлено" -#: src/renderer/components/dock/upgrade-chart.tsx:105 +#: src/renderer/components/dock/upgrade-chart.tsx:104 msgid "Updating.." msgstr "Обновление.." #: src/renderer/components/+apps-releases/release-details.tsx:176 -#: src/renderer/components/dock/upgrade-chart.tsx:105 +#: src/renderer/components/dock/upgrade-chart.tsx:104 msgid "Upgrade" msgstr "Обновить" @@ -2800,7 +2812,7 @@ msgstr "Конфигурация" msgid "Verbs" msgstr "Определения" -#: src/renderer/components/+apps-helm-charts/helm-chart-details.tsx:78 +#: src/renderer/components/+apps-helm-charts/helm-chart-details.tsx:85 #: src/renderer/components/+apps-helm-charts/helm-charts.tsx:66 #: src/renderer/components/+apps-releases/release-details.tsx:185 #: src/renderer/components/+apps-releases/releases.tsx:91 @@ -2867,11 +2879,11 @@ msgstr "" msgid "Workspaces are used to organize number of clusters into logical groups." msgstr "" -#: src/renderer/components/input/input.validators.ts:11 +#: src/renderer/components/input/input_validators.ts:11 msgid "Wrong email format" msgstr "Неверный формат электронной почты" -#: src/renderer/components/input/input.validators.ts:26 +#: src/renderer/components/input/input_validators.ts:26 msgid "Wrong url format" msgstr "Неверный url формат" @@ -2954,7 +2966,7 @@ msgstr "" msgid "timestamps" msgstr "временные метки" -#: src/renderer/components/dock/create-resource.tsx:55 +#: src/renderer/components/dock/create-resource.tsx:57 msgid "{0, plural, one {Resource} other {Resources}}" msgstr "{0, plural, one {Ресурс} few {Ресурсы} many {Ресурсы} other {Ресурсы}}" @@ -3013,6 +3025,6 @@ msgstr "" "other {<2>Удалить <3>{selectedCount} элементов <4>{selectedNames} {tail}?}\n" "}" -#: src/renderer/components/dock/info-panel.tsx:99 +#: src/renderer/components/dock/info-panel.tsx:88 msgid "{submitLabel} & Close" msgstr "{submitLabel} и закрыть" diff --git a/package.json b/package.json index 059ffc63ef..0d1589db30 100644 --- a/package.json +++ b/package.json @@ -60,7 +60,6 @@ ] }, "jest": { - "testRegex": ".*_(spec|test)\\.[jt]sx?$", "collectCoverage": false, "verbose": true, "testEnvironment": "node", diff --git a/src/common/cluster-store_test.ts b/src/common/__tests__/cluster-store.test.ts similarity index 66% rename from src/common/cluster-store_test.ts rename to src/common/__tests__/cluster-store.test.ts index 3c0369def3..724a83f0d7 100644 --- a/src/common/cluster-store_test.ts +++ b/src/common/__tests__/cluster-store.test.ts @@ -1,9 +1,9 @@ import fs from "fs"; import mockFs from "mock-fs"; import yaml from "js-yaml"; -import { Cluster } from "../main/cluster"; -import { ClusterStore } from "./cluster-store"; -import { workspaceStore } from "./workspace-store"; +import { Cluster } from "../../main/cluster"; +import { ClusterStore } from "../cluster-store"; +import { workspaceStore } from "../workspace-store"; const testDataIcon = fs.readFileSync("test-data/cluster-store-migration-icon.png") @@ -12,7 +12,7 @@ console.log("") // fix bug let clusterStore: ClusterStore; describe("empty config", () => { - beforeAll(() => { + beforeEach(() => { ClusterStore.resetInstance(); const mockOpts = { 'tmp': { @@ -24,109 +24,120 @@ describe("empty config", () => { return clusterStore.load(); }) - afterAll(() => { + afterEach(() => { mockFs.restore(); }) - it("adds new cluster to store", async () => { - const cluster = new Cluster({ - id: "foo", - contextName: "minikube", - preferences: { - terminalCWD: "/tmp", - icon: "data:;base64,iVBORw0KGgoAAAANSUhEUgAAA1wAAAKoCAYAAABjkf5", - clusterName: "minikube" - }, - kubeConfigPath: ClusterStore.embedCustomKubeConfig("foo", "fancy foo config"), - workspace: workspaceStore.currentWorkspaceId + describe("with foo cluster added", () => { + beforeEach(() => { + clusterStore.addCluster( + new Cluster({ + id: "foo", + contextName: "minikube", + preferences: { + terminalCWD: "/tmp", + icon: "data:image/jpeg;base64, iVBORw0KGgoAAAANSUhEUgAAA1wAAAKoCAYAAABjkf5", + clusterName: "minikube" + }, + kubeConfigPath: ClusterStore.embedCustomKubeConfig("foo", "fancy foo config"), + workspace: workspaceStore.currentWorkspaceId + }) + ); + }) + + it("adds new cluster to store", async () => { + const storedCluster = clusterStore.getById("foo"); + expect(storedCluster.id).toBe("foo"); + expect(storedCluster.preferences.terminalCWD).toBe("/tmp"); + expect(storedCluster.preferences.icon).toBe("data:image/jpeg;base64, iVBORw0KGgoAAAANSUhEUgAAA1wAAAKoCAYAAABjkf5"); + }) + + it("adds cluster to default workspace", () => { + const storedCluster = clusterStore.getById("foo"); + expect(storedCluster.workspace).toBe("default"); + }) + + it("removes cluster from store", async () => { + await clusterStore.removeById("foo"); + expect(clusterStore.getById("foo")).toBeUndefined(); + }) + + it("sets active cluster", () => { + clusterStore.setActive("foo"); + expect(clusterStore.activeCluster.id).toBe("foo"); + }) + }) + + describe("with prod and dev clusters added", () => { + beforeEach(() => { + clusterStore.addCluster( + new Cluster({ + id: "prod", + contextName: "prod", + preferences: { + clusterName: "prod" + }, + kubeConfigPath: ClusterStore.embedCustomKubeConfig("prod", "fancy config"), + workspace: "workstation" + }), + new Cluster({ + id: "dev", + contextName: "dev", + preferences: { + clusterName: "dev" + }, + kubeConfigPath: ClusterStore.embedCustomKubeConfig("dev", "fancy config"), + workspace: "workstation" + }) + ) + }) + + it("check if store can contain multiple clusters", () => { + expect(clusterStore.hasClusters()).toBeTruthy(); + expect(clusterStore.clusters.size).toBe(2); }); - clusterStore.addCluster(cluster); - const storedCluster = clusterStore.getById(cluster.id); - expect(storedCluster.id).toBe(cluster.id); - expect(storedCluster.preferences.terminalCWD).toBe(cluster.preferences.terminalCWD); - expect(storedCluster.preferences.icon).toBe(cluster.preferences.icon); - }) - it("adds cluster to default workspace", () => { - const storedCluster = clusterStore.getById("foo"); - expect(storedCluster.workspace).toBe("default"); - }) + it("gets clusters by workspaces", () => { + const wsClusters = clusterStore.getByWorkspaceId("workstation"); + const defaultClusters = clusterStore.getByWorkspaceId("default"); + expect(defaultClusters.length).toBe(0); + expect(wsClusters.length).toBe(2); + expect(wsClusters[0].id).toBe("prod"); + expect(wsClusters[1].id).toBe("dev"); + }) - it("check if store can contain multiple clusters", () => { - const prodCluster = new Cluster({ - id: "prod", - contextName: "prod", - preferences: { - clusterName: "prod" - }, - kubeConfigPath: ClusterStore.embedCustomKubeConfig("prod", "fancy config"), - workspace: "workstation" - }); - const devCluster = new Cluster({ - id: "dev", - contextName: "dev", - preferences: { - clusterName: "dev" - }, - kubeConfigPath: ClusterStore.embedCustomKubeConfig("dev", "fancy config"), - workspace: "workstation" - }); - clusterStore.addCluster(prodCluster); - clusterStore.addCluster(devCluster); - expect(clusterStore.hasClusters()).toBeTruthy(); - expect(clusterStore.clusters.size).toBe(3); - }); + it("check if cluster's kubeconfig file saved", () => { + const file = ClusterStore.embedCustomKubeConfig("boo", "kubeconfig"); + expect(fs.readFileSync(file, "utf8")).toBe("kubeconfig"); + }) - it("gets clusters by workspaces", () => { - const wsClusters = clusterStore.getByWorkspaceId("workstation"); - const defaultClusters = clusterStore.getByWorkspaceId("default"); - expect(defaultClusters.length).toBe(1); - expect(wsClusters.length).toBe(2); - expect(wsClusters[0].id).toBe("prod"); - expect(wsClusters[1].id).toBe("dev"); - }) + it("check if reorderring works for same from and to", () => { + clusterStore.swapIconOrders("workstation", 1, 1) - it("sets active cluster", () => { - clusterStore.setActive("foo"); - expect(clusterStore.activeCluster.id).toBe("foo"); - }) + const clusters = clusterStore.getByWorkspaceId("workstation"); + expect(clusters[0].id).toBe("prod") + expect(clusters[0].preferences.iconOrder).toBe(0) + expect(clusters[1].id).toBe("dev") + expect(clusters[1].preferences.iconOrder).toBe(1) + }) - it("check if cluster's kubeconfig file saved", () => { - const file = ClusterStore.embedCustomKubeConfig("boo", "kubeconfig"); - expect(fs.readFileSync(file, "utf8")).toBe("kubeconfig"); - }) + it("check if reorderring works for different from and to", () => { + clusterStore.swapIconOrders("workstation", 0, 1) - it("check if reorderring works for same from and to", () => { - clusterStore.swapIconOrders("workstation", 1, 1) + const clusters = clusterStore.getByWorkspaceId("workstation"); + expect(clusters[0].id).toBe("dev") + expect(clusters[0].preferences.iconOrder).toBe(0) + expect(clusters[1].id).toBe("prod") + expect(clusters[1].preferences.iconOrder).toBe(1) + }) - const clusters = clusterStore.getByWorkspaceId("workstation"); - expect(clusters[0].id).toBe("prod") - expect(clusters[0].preferences.iconOrder).toBe(0) - expect(clusters[1].id).toBe("dev") - expect(clusters[1].preferences.iconOrder).toBe(1) - }); + it("check if after icon reordering, changing workspaces still works", () => { + clusterStore.swapIconOrders("workstation", 1, 1) + clusterStore.getById("prod").workspace = "default" - it("check if reorderring works for different from and to", () => { - clusterStore.swapIconOrders("workstation", 0, 1) - - const clusters = clusterStore.getByWorkspaceId("workstation"); - expect(clusters[0].id).toBe("dev") - expect(clusters[0].preferences.iconOrder).toBe(0) - expect(clusters[1].id).toBe("prod") - expect(clusters[1].preferences.iconOrder).toBe(1) - }); - - it("check if after icon reordering, changing workspaces still works", () => { - clusterStore.swapIconOrders("workstation", 1, 1) - clusterStore.getById("prod").workspace = "default" - - expect(clusterStore.getByWorkspaceId("workstation").length).toBe(1); - expect(clusterStore.getByWorkspaceId("default").length).toBe(2); - }); - - it("removes cluster from store", async () => { - await clusterStore.removeById("foo"); - expect(clusterStore.getById("foo")).toBeUndefined(); + expect(clusterStore.getByWorkspaceId("workstation").length).toBe(1); + expect(clusterStore.getByWorkspaceId("default").length).toBe(1); + }) }) }) diff --git a/src/common/user-store_test.ts b/src/common/__tests__/user-store.test.ts similarity index 98% rename from src/common/user-store_test.ts rename to src/common/__tests__/user-store.test.ts index 4e9efe97d8..e361397565 100644 --- a/src/common/user-store_test.ts +++ b/src/common/__tests__/user-store.test.ts @@ -10,7 +10,7 @@ jest.mock("electron", () => { } }) -import { UserStore } from "./user-store" +import { UserStore } from "../user-store" import { SemVer } from "semver" import electron from "electron" diff --git a/src/common/workspace-store_test.ts b/src/common/__tests__/workspace-store.test.ts similarity index 98% rename from src/common/workspace-store_test.ts rename to src/common/__tests__/workspace-store.test.ts index 232f0b013a..8ac3ac599d 100644 --- a/src/common/workspace-store_test.ts +++ b/src/common/__tests__/workspace-store.test.ts @@ -10,7 +10,7 @@ jest.mock("electron", () => { } }) -import { WorkspaceStore } from "./workspace-store" +import { WorkspaceStore } from "../workspace-store" describe("workspace store tests", () => { describe("for an empty config", () => { diff --git a/src/common/utils/splitArray_test.ts b/src/common/utils/__tests__/splitArray.test.ts similarity index 95% rename from src/common/utils/splitArray_test.ts rename to src/common/utils/__tests__/splitArray.test.ts index ede542d605..a401e07701 100644 --- a/src/common/utils/splitArray_test.ts +++ b/src/common/utils/__tests__/splitArray.test.ts @@ -1,4 +1,4 @@ -import { splitArray } from "./splitArray"; +import { splitArray } from "../splitArray"; describe("split array on element tests", () => { test("empty array", () => { @@ -16,7 +16,7 @@ describe("split array on element tests", () => { test("one elements, in array", () => { expect(splitArray([1], 1)).toStrictEqual([[], [], true]); }); - + test("ten elements, in front array", () => { expect(splitArray([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], 0)).toStrictEqual([[], [1, 2, 3, 4, 5, 6, 7, 8, 9], true]); }); diff --git a/src/renderer/api/kube-api-parse_test.ts b/src/renderer/api/__tests__/kube-api-parse.test.ts similarity index 89% rename from src/renderer/api/kube-api-parse_test.ts rename to src/renderer/api/__tests__/kube-api-parse.test.ts index dee3bf031d..c2aec7fd58 100644 --- a/src/renderer/api/kube-api-parse_test.ts +++ b/src/renderer/api/__tests__/kube-api-parse.test.ts @@ -1,11 +1,11 @@ -import { IKubeApiParsed, parseKubeApi } from "./kube-api-parse"; +import { IKubeApiParsed, parseKubeApi } from "../kube-api-parse"; -interface KubeApi_Parse_Test { +interface KubeApiParseTestData { url: string; expected: Required; } -const tests: KubeApi_Parse_Test[] = [ +const tests: KubeApiParseTestData[] = [ { url: "/apis/apiextensions.k8s.io/v1beta1/customresourcedefinitions/prometheuses.monitoring.coreos.com", expected: { @@ -125,11 +125,10 @@ const tests: KubeApi_Parse_Test[] = [ }, ]; -describe.only("parseApi unit tests", () => { - for (const i in tests) { - const { url: tUrl, expected:tExpect} = tests[i]; - test(`test #${parseInt(i)+1}`, () => { - expect(parseKubeApi(tUrl)).toStrictEqual(tExpect); +describe("parseApi unit tests", () => { + for (const { url, expected } of tests) { + test(`testing "${url}"`, () => { + expect(parseKubeApi(url)).toStrictEqual(expected); }); } }); diff --git a/src/renderer/components/+cluster-settings/components/cluster-name-setting.tsx b/src/renderer/components/+cluster-settings/components/cluster-name-setting.tsx index a11f8aed6e..54d76c08eb 100644 --- a/src/renderer/components/+cluster-settings/components/cluster-name-setting.tsx +++ b/src/renderer/components/+cluster-settings/components/cluster-name-setting.tsx @@ -4,7 +4,7 @@ import { Input } from "../../input"; import { observable, autorun } from "mobx"; import { observer, disposeOnUnmount } from "mobx-react"; import { SubTitle } from "../../layout/sub-title"; -import { isRequired } from "../../input/input.validators"; +import { isRequired } from "../../input/input_validators"; interface Props { cluster: Cluster; @@ -33,7 +33,7 @@ export class ClusterNameSetting extends React.Component { render() { return ( <> - +

Define cluster name.

{ render() { return ( <> - +

HTTP Proxy server. Used for communicating with Kubernetes API.

{ const isCount = quota.startsWith("count/"); const icon = isCompute ? "memory" : isStorage ? "storage" : isCount ? "looks_one" : ""; return { - label: icon ? {quota} : quota, + label: icon ? {quota} : quota, value: quota, }; }); @@ -151,7 +151,7 @@ export class AddQuotaDialog extends React.Component { /> - Namespace}/> + Namespace} /> { onChange={({ value }) => this.namespace = value} /> - Values}/> + Values} />
{
- Namespace}/> + Namespace} /> { />
- Secret type}/> + Secret type} /> this.name = v.toLowerCase()} /> - Namespace}/> + Namespace} /> { } diff --git a/src/renderer/components/+workspaces/workspaces.tsx b/src/renderer/components/+workspaces/workspaces.tsx index a2e7dbf74f..3cd5e71f82 100644 --- a/src/renderer/components/+workspaces/workspaces.tsx +++ b/src/renderer/components/+workspaces/workspaces.tsx @@ -12,7 +12,7 @@ import { Icon } from "../icon"; import { Input } from "../input"; import { cssNames, prevDefault } from "../../utils"; import { Button } from "../button"; -import { isRequired, Validator } from "../input/input.validators"; +import { isRequired, Validator } from "../input/input_validators"; @observer export class Workspaces extends React.Component { diff --git a/src/renderer/components/input/input.validators_test.ts b/src/renderer/components/input/__tests__/input_validators.test.ts similarity index 97% rename from src/renderer/components/input/input.validators_test.ts rename to src/renderer/components/input/__tests__/input_validators.test.ts index 4477d63e93..7bf08ffbdb 100644 --- a/src/renderer/components/input/input.validators_test.ts +++ b/src/renderer/components/input/__tests__/input_validators.test.ts @@ -1,4 +1,4 @@ -import { isEmail, systemName } from "./input.validators"; +import { isEmail, systemName } from "../input_validators"; describe("input validation tests", () => { describe("isEmail tests", () => { diff --git a/src/renderer/components/input/input.tsx b/src/renderer/components/input/input.tsx index c109735927..224f7f953e 100644 --- a/src/renderer/components/input/input.tsx +++ b/src/renderer/components/input/input.tsx @@ -3,7 +3,7 @@ import "./input.scss"; import React, { DOMAttributes, InputHTMLAttributes, TextareaHTMLAttributes } from "react"; import { autobind, cssNames, debouncePromise } from "../../utils"; import { Icon } from "../icon"; -import { conditionalValidators, Validator } from "./input.validators"; +import { conditionalValidators, Validator } from "./input_validators"; import isString from "lodash/isString" import isFunction from "lodash/isFunction" import isBoolean from "lodash/isBoolean" @@ -288,9 +288,9 @@ export class Input extends React.Component { return (