From 046c648c8d98520011a0c472daecceba123341fc Mon Sep 17 00:00:00 2001 From: Jim Ehrismann Date: Fri, 3 Jul 2020 17:10:14 -0400 Subject: [PATCH] Separate the port forward links in the UI (so they don't all spin when one link is clicked) Signed-off-by: Jim Ehrismann --- .../+network-services/service-details.tsx | 12 +++- .../service-port-component.scss | 22 +++++++ ...e-ports.tsx => service-port-component.tsx} | 34 +++++------ .../+network-services/service-ports.scss | 24 -------- .../+workloads-pods/pod-container-port.scss | 23 ++++++++ .../+workloads-pods/pod-container-port.tsx | 56 ++++++++++++++++++ .../+workloads-pods/pod-container-ports.scss | 24 -------- .../+workloads-pods/pod-container-ports.tsx | 57 ------------------- .../+workloads-pods/pod-details-container.tsx | 15 ++++- 9 files changed, 137 insertions(+), 130 deletions(-) create mode 100644 src/renderer/components/+network-services/service-port-component.scss rename src/renderer/components/+network-services/{service-ports.tsx => service-port-component.tsx} (52%) delete mode 100644 src/renderer/components/+network-services/service-ports.scss create mode 100644 src/renderer/components/+workloads-pods/pod-container-port.scss create mode 100644 src/renderer/components/+workloads-pods/pod-container-port.tsx delete mode 100644 src/renderer/components/+workloads-pods/pod-container-ports.scss delete mode 100644 src/renderer/components/+workloads-pods/pod-container-ports.tsx diff --git a/src/renderer/components/+network-services/service-details.tsx b/src/renderer/components/+network-services/service-details.tsx index 0c158c9e6b..935c74c96c 100644 --- a/src/renderer/components/+network-services/service-details.tsx +++ b/src/renderer/components/+network-services/service-details.tsx @@ -11,7 +11,7 @@ import { Service, serviceApi, endpointApi } from "../../api/endpoints"; import { _i18n } from "../../i18n"; import { apiManager } from "../../api/api-manager"; import { KubeObjectMeta } from "../kube-object/kube-object-meta"; -import { ServicePorts } from "./service-ports"; +import { ServicePortComponent } from "./service-port-component"; import { endpointStore } from "../+network-endpoints/endpoints.store"; import { ServiceDetailsEndpoint } from "./service-details-endpoint"; @@ -61,7 +61,15 @@ export class ServiceDetails extends React.Component { )} Ports}> - +
+ { + service.getPorts().map((port) => { + return( + + ); + }) + } +
{spec.type === "LoadBalancer" && spec.loadBalancerIP && ( diff --git a/src/renderer/components/+network-services/service-port-component.scss b/src/renderer/components/+network-services/service-port-component.scss new file mode 100644 index 0000000000..0e9945631d --- /dev/null +++ b/src/renderer/components/+network-services/service-port-component.scss @@ -0,0 +1,22 @@ +.ServicePortComponent { + &.waiting { + opacity: 0.5; + pointer-events: none; + } + + &:not(:last-child) { + margin-bottom: $margin; + } + + span { + cursor: pointer; + color: $primary; + text-decoration: underline; + } + + .Spinner { + --spinner-size: #{$unit * 2}; + margin-left: $margin; + position: absolute; + } +} diff --git a/src/renderer/components/+network-services/service-ports.tsx b/src/renderer/components/+network-services/service-port-component.tsx similarity index 52% rename from src/renderer/components/+network-services/service-ports.tsx rename to src/renderer/components/+network-services/service-port-component.tsx index 1c9128892d..d2b932bce6 100644 --- a/src/renderer/components/+network-services/service-ports.tsx +++ b/src/renderer/components/+network-services/service-port-component.tsx @@ -1,4 +1,4 @@ -import "./service-ports.scss" +import "./service-port-component.scss" import React from "react"; import { observer } from "mobx-react"; @@ -13,14 +13,15 @@ import { Spinner } from "../spinner" interface Props { service: Service; + port: ServicePort; } @observer -export class ServicePorts extends React.Component { +export class ServicePortComponent extends React.Component { @observable waiting = false; - async portForward(port: ServicePort) { - const { service } = this.props; + async portForward() { + const { service, port } = this.props; this.waiting = true; try { await apiBase.post(`/pods/${service.getNs()}/service/${service.getName()}/port-forward/${port.port}`, {}) @@ -32,23 +33,16 @@ export class ServicePorts extends React.Component { } render() { - const { service } = this.props; + const { port } = this.props; return ( -
- { - service.getPorts().map((port) => { - return( -

- this.portForward(port) }> - {port.toString()} - {this.waiting && ( - - )} - -

- ); - })} -
+

+ this.portForward() }> + {port.toString()} + {this.waiting && ( + + )} + +

); } } diff --git a/src/renderer/components/+network-services/service-ports.scss b/src/renderer/components/+network-services/service-ports.scss deleted file mode 100644 index 5a683af86c..0000000000 --- a/src/renderer/components/+network-services/service-ports.scss +++ /dev/null @@ -1,24 +0,0 @@ -.ServicePorts { - &.waiting { - opacity: 0.5; - pointer-events: none; - } - - p { - &:not(:last-child) { - margin-bottom: $margin; - } - - span { - cursor: pointer; - color: $primary; - text-decoration: underline; - } - } - - .Spinner { - --spinner-size: #{$unit * 2}; - margin-left: $margin; - position: absolute; - } -} diff --git a/src/renderer/components/+workloads-pods/pod-container-port.scss b/src/renderer/components/+workloads-pods/pod-container-port.scss new file mode 100644 index 0000000000..081f0b1090 --- /dev/null +++ b/src/renderer/components/+workloads-pods/pod-container-port.scss @@ -0,0 +1,23 @@ +.PodContainerPort { + &.waiting { + opacity: 0.5; + pointer-events: none; + } + + &:not(:last-child) { + margin-bottom: $margin; + } + + span { + cursor: pointer; + color: $primary; + text-decoration: underline; + position: relative; + } + + .Spinner { + --spinner-size: #{$unit * 2}; + margin-left: $margin; + position: absolute; + } +} \ No newline at end of file diff --git a/src/renderer/components/+workloads-pods/pod-container-port.tsx b/src/renderer/components/+workloads-pods/pod-container-port.tsx new file mode 100644 index 0000000000..d62630c115 --- /dev/null +++ b/src/renderer/components/+workloads-pods/pod-container-port.tsx @@ -0,0 +1,56 @@ +import "./pod-container-port.scss" + +import React from "react"; +import { observer } from "mobx-react"; +import { t } from "@lingui/macro"; +import { Pod, IPodContainer } from "../../api/endpoints"; +import { _i18n } from "../../i18n"; +import { apiBase } from "../../api" +import { observable } from "mobx"; +import { cssNames } from "../../utils"; +import { Notifications } from "../notifications"; +import { Spinner } from "../spinner" + +interface Props { + pod: Pod; + containerName: string; + port: { + name?: string; + containerPort: number; + protocol: string; + } +} + +@observer +export class PodContainerPort extends React.Component { + @observable waiting = false; + + async portForward() { + const { pod, port } = this.props; + this.waiting = true; + try { + await apiBase.post(`/pods/${pod.getNs()}/pod/${pod.getName()}/port-forward/${port.containerPort}`, {}) + } catch(error) { + Notifications.error(error); + } finally { + this.waiting = false; + } + } + + render() { + const { containerName, port } = this.props; + const { name, containerPort, protocol } = port; + const key = `${containerName}-port-${containerPort}-${protocol}` + const text = (name ? name + ': ' : '')+`${containerPort}/${protocol}` + return ( +

+ this.portForward() }> + {text} + {this.waiting && ( + + )} + +

+ ) + } +} diff --git a/src/renderer/components/+workloads-pods/pod-container-ports.scss b/src/renderer/components/+workloads-pods/pod-container-ports.scss deleted file mode 100644 index 0424c82125..0000000000 --- a/src/renderer/components/+workloads-pods/pod-container-ports.scss +++ /dev/null @@ -1,24 +0,0 @@ -.PodContainerPorts { - &.waiting { - opacity: 0.5; - pointer-events: none; - } - - p { - &:not(:last-child) { - margin-bottom: $margin; - } - - span { - cursor: pointer; - color: $primary; - text-decoration: underline; - } - } - - .Spinner { - --spinner-size: #{$unit * 2}; - margin-left: $margin; - position: static; - } -} diff --git a/src/renderer/components/+workloads-pods/pod-container-ports.tsx b/src/renderer/components/+workloads-pods/pod-container-ports.tsx deleted file mode 100644 index 0209a99dd5..0000000000 --- a/src/renderer/components/+workloads-pods/pod-container-ports.tsx +++ /dev/null @@ -1,57 +0,0 @@ -import "./pod-container-ports.scss" - -import React from "react"; -import { observer } from "mobx-react"; -import { t } from "@lingui/macro"; -import { Pod, IPodContainer } from "../../api/endpoints"; -import { _i18n } from "../../i18n"; -import { apiBase } from "../../api" -import { observable } from "mobx"; -import { cssNames } from "../../utils"; -import { Notifications } from "../notifications"; -import { Spinner } from "../spinner" - -interface Props { - pod: Pod; - container: IPodContainer; -} - -@observer -export class PodContainerPorts extends React.Component { - @observable waiting = false; - - async portForward(port: number) { - const { pod } = this.props; - this.waiting = true; - try { - await apiBase.post(`/pods/${pod.getNs()}/pod/${pod.getName()}/port-forward/${port}`, {}) - } catch(error) { - Notifications.error(error); - } finally { - this.waiting = false; - } - } - - render() { - const { container } = this.props; - return ( -
- { - container.ports.map((port) => { - const key = `${container.name}-port-${port.containerPort}-${port.protocol}` - const text = (port.name ? port.name + ': ' : '')+`${port.containerPort}/${port.protocol}` - return( -

- this.portForward(port.containerPort) }> - {text} - {this.waiting && ( - - )} - -

- ); - })} -
- ); - } -} diff --git a/src/renderer/components/+workloads-pods/pod-details-container.tsx b/src/renderer/components/+workloads-pods/pod-details-container.tsx index 576b98581e..1139bd8ffe 100644 --- a/src/renderer/components/+workloads-pods/pod-details-container.tsx +++ b/src/renderer/components/+workloads-pods/pod-details-container.tsx @@ -8,7 +8,7 @@ import { cssNames } from "../../utils"; import { StatusBrick } from "../status-brick"; import { Badge } from "../badge"; import { ContainerEnvironment } from "./pod-container-env"; -import { PodContainerPorts } from "./pod-container-ports"; +import { PodContainerPort } from "./pod-container-port"; import { ResourceMetrics } from "../resource-metrics"; import { IMetrics } from "../../api/endpoints/metrics.api"; import { ContainerCharts } from "./container-charts"; @@ -62,9 +62,18 @@ export class PodDetailsContainer extends React.Component { {imagePullPolicy} } - {ports && ports.length > 0 && + {ports && ports.length > 0 && Ports}> - +
+ { + ports.map((port) => { + return( + + ) + }) + } +
+
} {}