From c8d7fbdba318ee30c9dc4b24d2976ea6a9534cbe Mon Sep 17 00:00:00 2001 From: Julien Pinsonneau Date: Tue, 3 Nov 2026 14:18:19 +0100 Subject: [PATCH 1/4] OCPNETUI-117: Add additional views to topology --- dev/topology-fake-resources.yaml | 345 +++++++++++++++++ dev/topology-fake-virtualmachine-crd.yaml | 26 ++ .../en/plugin__networking-console-plugin.json | 24 ++ .../es/plugin__networking-console-plugin.json | 24 ++ .../fr/plugin__networking-console-plugin.json | 24 ++ .../ja/plugin__networking-console-plugin.json | 24 ++ .../ko/plugin__networking-console-plugin.json | 24 ++ .../zh/plugin__networking-console-plugin.json | 24 ++ package-lock.json | 10 + package.json | 1 + src/views/topology/TopologyPage.scss | 14 + .../components/CustomGroup/CustomGroup.tsx | 49 ++- .../components/CustomNode/CustomNode.scss | 4 + .../components/CustomNode/CustomNode.tsx | 18 +- .../components/DisplayOptionsDropdown.scss | 19 + .../components/DisplayOptionsDropdown.tsx | 147 ++++++- .../topology/components/ScopeSlider.scss | 16 + src/views/topology/components/ScopeSlider.tsx | 85 ++++ src/views/topology/components/Topology.tsx | 163 ++++++-- .../components/TopologyControlBar.tsx | 72 ++-- .../topology/components/TopologyIcons.tsx | 180 +++++++++ .../topology/components/TopologyLegend.scss | 46 +++ .../topology/components/TopologyLegend.tsx | 105 +++++ .../topology/components/TopologyToolbar.scss | 7 + .../topology/components/TopologyToolbar.tsx | 25 +- .../topology/hooks/useTopologyK8sModels.ts | 60 +++ src/views/topology/types.ts | 7 + src/views/topology/utils/LevelsLayout.ts | 12 +- src/views/topology/utils/constants.ts | 20 +- .../dataTransformation/dataTransformation.ts | 365 +++++++++++++++++- .../utils/dataTransformation/resourceUtils.ts | 14 +- src/views/topology/utils/filterModel.ts | 10 +- 32 files changed, 1873 insertions(+), 91 deletions(-) create mode 100644 dev/topology-fake-resources.yaml create mode 100644 dev/topology-fake-virtualmachine-crd.yaml create mode 100644 src/views/topology/components/DisplayOptionsDropdown.scss create mode 100644 src/views/topology/components/ScopeSlider.scss create mode 100644 src/views/topology/components/ScopeSlider.tsx create mode 100644 src/views/topology/components/TopologyIcons.tsx create mode 100644 src/views/topology/components/TopologyLegend.scss create mode 100644 src/views/topology/components/TopologyLegend.tsx create mode 100644 src/views/topology/components/TopologyToolbar.scss create mode 100644 src/views/topology/hooks/useTopologyK8sModels.ts diff --git a/dev/topology-fake-resources.yaml b/dev/topology-fake-resources.yaml new file mode 100644 index 000000000..594c6e53a --- /dev/null +++ b/dev/topology-fake-resources.yaml @@ -0,0 +1,345 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: topology-fake-owner + labels: + topology-fake-cudn: member +--- +apiVersion: v1 +kind: Namespace +metadata: + name: topology-fake-namespace + labels: + topology-fake-cudn: member +--- +apiVersion: v1 +kind: Namespace +metadata: + name: topology-fake-network + labels: + topology-fake-cudn: member +--- +apiVersion: v1 +kind: Namespace +metadata: + name: topology-fake-resource + labels: + topology-fake-cudn: member +--- +apiVersion: k8s.cni.cncf.io/v1 +kind: NetworkAttachmentDefinition +metadata: + name: owner-network + namespace: topology-fake-owner +spec: + config: '{"cniVersion":"0.3.1","name":"owner-network","type":"bridge","bridge":"br-owner","ipam":{}}' +--- +apiVersion: k8s.cni.cncf.io/v1 +kind: NetworkAttachmentDefinition +metadata: + name: namespace-network + namespace: topology-fake-namespace +spec: + config: '{"cniVersion":"0.3.1","name":"namespace-network","type":"bridge","bridge":"br-namespace","ipam":{}}' +--- +apiVersion: k8s.cni.cncf.io/v1 +kind: NetworkAttachmentDefinition +metadata: + name: network-a + namespace: topology-fake-network +spec: + config: '{"cniVersion":"0.3.1","name":"network-a","type":"bridge","bridge":"br-a","ipam":{}}' +--- +apiVersion: k8s.cni.cncf.io/v1 +kind: NetworkAttachmentDefinition +metadata: + name: network-b + namespace: topology-fake-network +spec: + config: '{"cniVersion":"0.3.1","name":"network-b","type":"bridge","bridge":"br-b","ipam":{}}' +--- +apiVersion: k8s.cni.cncf.io/v1 +kind: NetworkAttachmentDefinition +metadata: + name: resource-network + namespace: topology-fake-resource +spec: + config: '{"cniVersion":"0.3.1","name":"resource-network","type":"bridge","bridge":"br-resource","ipam":{}}' +--- +apiVersion: k8s.cni.cncf.io/v1 +kind: NetworkAttachmentDefinition +metadata: + name: shared-network + namespace: topology-fake-network +spec: + config: '{"cniVersion":"0.3.1","name":"shared-network","type":"bridge","bridge":"br-shared-network","ipam":{}}' +--- +apiVersion: k8s.cni.cncf.io/v1 +kind: NetworkAttachmentDefinition +metadata: + name: shared-network + namespace: topology-fake-resource +spec: + config: '{"cniVersion":"0.3.1","name":"shared-network","type":"bridge","bridge":"br-shared-resource","ipam":{}}' +--- +apiVersion: k8s.ovn.org/v1 +kind: UserDefinedNetwork +metadata: + name: owner-udn + namespace: topology-fake-owner +spec: + topology: Layer2 + layer2: + role: Secondary + subnets: + - 10.241.0.0/24 +--- +apiVersion: k8s.ovn.org/v1 +kind: UserDefinedNetwork +metadata: + name: namespace-udn + namespace: topology-fake-namespace +spec: + topology: Layer2 + layer2: + role: Secondary + subnets: + - 10.242.0.0/24 +--- +apiVersion: k8s.ovn.org/v1 +kind: UserDefinedNetwork +metadata: + name: resource-udn + namespace: topology-fake-resource +spec: + topology: Layer2 + layer2: + role: Secondary + subnets: + - 10.244.0.0/24 +--- +apiVersion: k8s.ovn.org/v1 +kind: ClusterUserDefinedNetwork +metadata: + name: fake-cluster-network +spec: + namespaceSelector: + matchLabels: + topology-fake-cudn: member + network: + topology: Layer2 + layer2: + role: Secondary + subnets: + - 10.243.0.0/24 +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: fake-owner-deployment + namespace: topology-fake-owner +spec: + replicas: 3 + selector: + matchLabels: + app: fake-owner-deployment + template: + metadata: + labels: + app: fake-owner-deployment + annotations: + k8s.v1.cni.cncf.io/networks: topology-fake-owner/owner-network + spec: + containers: + - name: pause + image: registry.k8s.io/pause:3.9 +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: fake-owner-second + namespace: topology-fake-owner +spec: + replicas: 1 + selector: + matchLabels: + app: fake-owner-second + template: + metadata: + labels: + app: fake-owner-second + annotations: + k8s.v1.cni.cncf.io/networks: topology-fake-owner/owner-network + spec: + containers: + - name: pause + image: registry.k8s.io/pause:3.9 +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: fake-multi-network + namespace: topology-fake-network +spec: + replicas: 1 + selector: + matchLabels: + app: fake-multi-network + template: + metadata: + labels: + app: fake-multi-network + annotations: + # The first entry is used for Network grouping; both entries create edges. + k8s.v1.cni.cncf.io/networks: network-a, topology-fake-resource/resource-network + spec: + containers: + - name: pause + image: registry.k8s.io/pause:3.9 +--- +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: fake-owner-statefulset + namespace: topology-fake-owner +spec: + serviceName: fake-owner-statefulset + replicas: 1 + selector: + matchLabels: + app: fake-owner-statefulset + template: + metadata: + labels: + app: fake-owner-statefulset + annotations: + k8s.v1.cni.cncf.io/networks: topology-fake-owner/owner-network + spec: + containers: + - name: pause + image: registry.k8s.io/pause:3.9 +--- +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: fake-owner-daemonset + namespace: topology-fake-owner +spec: + selector: + matchLabels: + app: fake-owner-daemonset + template: + metadata: + labels: + app: fake-owner-daemonset + annotations: + k8s.v1.cni.cncf.io/networks: topology-fake-owner/owner-network + spec: + containers: + - name: pause + image: registry.k8s.io/pause:3.9 +--- +apiVersion: batch/v1 +kind: Job +metadata: + name: fake-owner-job + namespace: topology-fake-owner +spec: + completions: 1 + parallelism: 1 + template: + metadata: + labels: + app: fake-owner-job + annotations: + k8s.v1.cni.cncf.io/networks: topology-fake-owner/owner-network + spec: + restartPolicy: Never + containers: + - name: pause + image: registry.k8s.io/pause:3.9 +--- +apiVersion: v1 +kind: Pod +metadata: + name: namespace-pod + namespace: topology-fake-namespace + annotations: + k8s.v1.cni.cncf.io/networks: topology-fake-namespace/namespace-network +spec: + containers: + - name: pause + image: registry.k8s.io/pause:3.9 +--- +apiVersion: v1 +kind: Pod +metadata: + name: multi-network-pod + namespace: topology-fake-resource + annotations: + # The Pod belongs to resource-network for grouping but is connected to three NADs. + k8s.v1.cni.cncf.io/networks: resource-network, topology-fake-network/network-a, topology-fake-network/shared-network +spec: + containers: + - name: pause + image: registry.k8s.io/pause:3.9 +--- +apiVersion: v1 +kind: Pod +metadata: + name: same-name-network-pod + namespace: topology-fake-resource + annotations: + # The unqualified reference resolves locally; the qualified reference crosses namespaces. + k8s.v1.cni.cncf.io/networks: shared-network, topology-fake-network/shared-network +spec: + containers: + - name: pause + image: registry.k8s.io/pause:3.9 +--- +apiVersion: v1 +kind: Pod +metadata: + name: network-pod-a + namespace: topology-fake-network + annotations: + k8s.v1.cni.cncf.io/networks: topology-fake-network/network-a +spec: + containers: + - name: pause + image: registry.k8s.io/pause:3.9 +--- +apiVersion: v1 +kind: Pod +metadata: + name: network-pod-b + namespace: topology-fake-network + annotations: + k8s.v1.cni.cncf.io/networks: topology-fake-network/network-b +spec: + containers: + - name: pause + image: registry.k8s.io/pause:3.9 +--- +apiVersion: kubevirt.io/v1 +kind: VirtualMachine +metadata: + name: resource-vm + namespace: topology-fake-resource +spec: + runStrategy: Halted + template: + spec: + domain: + devices: + interfaces: + - name: default + bridge: {} + - name: resource-network + bridge: {} + networks: + - name: default + pod: {} + - name: resource-network + multus: + networkName: topology-fake-resource/resource-network diff --git a/dev/topology-fake-virtualmachine-crd.yaml b/dev/topology-fake-virtualmachine-crd.yaml new file mode 100644 index 000000000..a75a028c9 --- /dev/null +++ b/dev/topology-fake-virtualmachine-crd.yaml @@ -0,0 +1,26 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: virtualmachines.kubevirt.io +spec: + group: kubevirt.io + names: + kind: VirtualMachine + listKind: VirtualMachineList + plural: virtualmachines + singular: virtualmachine + scope: Namespaced + versions: + - name: v1 + served: true + storage: true + schema: + openAPIV3Schema: + type: object + properties: + spec: + type: object + x-kubernetes-preserve-unknown-fields: true + status: + type: object + x-kubernetes-preserve-unknown-fields: true diff --git a/locales/en/plugin__networking-console-plugin.json b/locales/en/plugin__networking-console-plugin.json index c3feeb637..aa353010c 100644 --- a/locales/en/plugin__networking-console-plugin.json +++ b/locales/en/plugin__networking-console-plugin.json @@ -47,6 +47,7 @@ "Add virtual machines": "Add virtual machines", "Advanced": "Advanced", "Advanced filter": "Advanced filter", + "Aggregated connection": "Aggregated connection", "Aggregation mode": "Aggregation mode", "All incoming traffic is denied to Pods in {{namespace}}": "All incoming traffic is denied to Pods in {{namespace}}", "All outgoing traffic is allowed by default. Egress rules can be used to restrict outgoing traffic if the cluster network provider allows it. When using the OpenShift SDN cluster network provider, egress network policy is not supported.": "All outgoing traffic is allowed by default. Egress rules can be used to restrict outgoing traffic if the cluster network provider allows it. When using the OpenShift SDN cluster network provider, egress network policy is not supported.", @@ -104,6 +105,9 @@ "Cluster administrator permissions are required to enable this feature.": "Cluster administrator permissions are required to enable this feature.", "Cluster IP": "Cluster IP", "Cluster map": "Cluster map", + "Cluster user-defined network to network attachment definition": "Cluster user-defined network to network attachment definition", + "Cluster user-defined network to pod": "Cluster user-defined network to pod", + "Cluster user-defined network to virtual machine": "Cluster user-defined network to virtual machine", "Cluster-wide UserDefinedNetworks": "Cluster-wide UserDefinedNetworks", "Cluster's default network": "Cluster's default network", "ClusterUserDefinedNetwork": "ClusterUserDefinedNetwork", @@ -194,6 +198,7 @@ "Duplicate keys found in peer pod selector": "Duplicate keys found in peer pod selector", "e.g. \"openshift-storage\"": "e.g. \"openshift-storage\"", "Edge": "Edge", + "Edges": "Edges", "Edit": "Edit", "Edit {{kind}}": "Edit {{kind}}", "Edit {{label}}": "Edit {{label}}", @@ -250,6 +255,7 @@ "Given subnet is split into smaller subnets for every node.": "Given subnet is split into smaller subnets for every node.", "Graph view": "Graph view", "Grid": "Grid", + "Groups": "Groups", "Health": "Health", "Healthy: {{ready}} of {{total}} endpoints ready": "Healthy: {{ready}} of {{total}} endpoints ready", "Hide": "Hide", @@ -275,6 +281,7 @@ "Ingress points of load balancer": "Ingress points of load balancer", "Ingress rule": "Ingress rule", "Ingress rules": "Ingress rules", + "Ingress to service": "Ingress to service", "Ingresses": "Ingresses", "Input error: selectors must start and end by a letter or number, and can only contain -, _, / or . Offending value: {{offendingSelector}}": "Input error: selectors must start and end by a letter or number, and can only contain -, _, / or . Offending value: {{offendingSelector}}", "Insecure traffic": "Insecure traffic", @@ -306,6 +313,7 @@ "Learn how to use NetworkAttachmentDefinitions": "Learn how to use NetworkAttachmentDefinitions", "Learn more about {{ kind }}": "Learn more about {{ kind }}", "Learn more about working with projects": "Learn more about working with projects", + "Legend": "Legend", "Links": "Links", "linux-bridge": "linux-bridge", "List of {{resourceName}} matching": "List of {{resourceName}} matching", @@ -334,6 +342,7 @@ "MTU": "MTU", "MTU is optional. If not provided, the globally configured value in OVN-Kubernetes (defaults to 1400) is used for the network.": "MTU is optional. If not provided, the globally configured value in OVN-Kubernetes (defaults to 1400) is used for the network.", "MTU is the maximum transmission unit for a network.": "MTU is the maximum transmission unit for a network.", + "Multi-network policy to network attachment definition": "Multi-network policy to network attachment definition", "multi-networkpolicies": "multi-networkpolicies", "multi-networkpolicy": "multi-networkpolicy", "MultiNetworkPolicies": "MultiNetworkPolicies", @@ -341,6 +350,7 @@ "Name": "Name", "Name is required": "Name is required", "Namespace": "Namespace", + "Namespace + Owner": "Namespace + Owner", "Namespace is required": "Namespace is required", "Namespace selector": "Namespace selector", "Namespace Selector": "Namespace Selector", @@ -440,6 +450,7 @@ "Pod port or name": "Pod port or name", "Pod selector": "Pod selector", "Pod selector for": "Pod selector for", + "Pod to network attachment definition": "Pod to network attachment definition", "Pod unschedulable": "Pod unschedulable", "pods": "pods", "Pods": "Pods", @@ -482,7 +493,10 @@ "Remove port": "Remove port", "Remove subnets?": "Remove subnets?", "Remove virtual machine from network?": "Remove virtual machine from network?", + "Replace namespaced resources with their namespace; cluster-scoped resources remain unchanged.": "Replace namespaced resources with their namespace; cluster-scoped resources remain unchanged.", + "Replace resources with their controller owner when one is available; ownerless resources remain unchanged.": "Replace resources with their controller owner when one is available; ownerless resources remain unchanged.", "Reset to default": "Reset to default", + "Resource": "Resource", "Resource name": "Resource name", "Resources in a grid inside each group; groups packed in rows.": "Resources in a grid inside each group; groups packed in rows.", "Restarts": "Restarts", @@ -494,6 +508,7 @@ "Role describes the network role in the pod.": "Role describes the network role in the pod.", "Route": "Route", "Route details": "Route details", + "Route to service": "Route to service", "Router canonical hostname": "Router canonical hostname", "Router: {{routerName}}": "Router: {{routerName}}", "Routes": "Routes", @@ -503,6 +518,7 @@ "Rules": "Rules", "Running": "Running", "Save": "Save", + "Scope": "Scope", "Search by name": "Search by name", "Search by name...": "Search by name...", "Search topology...": "Search topology...", @@ -542,8 +558,11 @@ "Show a preview of the <2>affected pods that this ingress rule will apply to.": "Show a preview of the <2>affected pods that this ingress rule will apply to.", "Show a preview of the <2>affected pods that this policy will apply to": "Show a preview of the <2>affected pods that this policy will apply to", "Show a preview of the <2>matching pods that this selector will apply to": "Show a preview of the <2>matching pods that this selector will apply to", + "Show individual resources using their Kubernetes kind and name.": "Show individual resources using their Kubernetes kind and name.", "Show labels": "Show labels", "Show less": "Show less", + "Show NetworkAttachmentDefinitions, UserDefinedNetworks, and ClusterUserDefinedNetworks as logical network nodes.": "Show NetworkAttachmentDefinitions, UserDefinedNetworks, and ClusterUserDefinedNetworks as logical network nodes.", + "Show topology legend": "Show topology legend", "Showing {{shown}} from {{total}} results": "Showing {{shown}} from {{total}} results", "Showing network definitions and consumers in project {{project}}. NMState configuration is cluster-wide.": "Showing network definitions and consumers in project {{project}}. NMState configuration is cluster-wide.", "Some consumer information is unavailable.": "Some consumer information is unavailable.", @@ -591,6 +610,7 @@ "To use a custom route, you must update your DNS provider by creating a canonical name (CNAME) record. Your CNAME record should point to your custom domain <2>{{host}}, to the OpenShift canonical router hostname, <5>{{routerCanonicalHostname}}, as the alias.": "To use a custom route, you must update your DNS provider by creating a canonical name (CNAME) record. Your CNAME record should point to your custom domain <2>{{host}}, to the OpenShift canonical router hostname, <5>{{routerCanonicalHostname}}, as the alias.", "Topology": "Topology", "Topology describes network configuration.": "Topology describes network configuration.", + "Topology scope": "Topology scope", "total limit": "total limit", "total requested": "total requested", "Traffic": "Traffic", @@ -611,6 +631,9 @@ "Uplink connection": "Uplink connection", "Use \"{{inputValue}}\"": "Use \"{{inputValue}}\"", "Use the default Pod network": "Use the default Pod network", + "User-defined network to network attachment definition": "User-defined network to network attachment definition", + "User-defined network to pod": "User-defined network to pod", + "User-defined network to virtual machine": "User-defined network to virtual machine", "UserDefinedNetwork": "UserDefinedNetwork", "UserDefinedNetworks": "UserDefinedNetworks", "Value": "Value", @@ -624,6 +647,7 @@ "View logs": "View logs", "View naming information": "View naming information", "Virtual machine information is unavailable; consumer information is incomplete.": "Virtual machine information is unavailable; consumer information is incomplete.", + "Virtual machine to network attachment definition": "Virtual machine to network attachment definition", "Virtual Machines": "Virtual Machines", "VirtualMachine": "VirtualMachine", "Visibility": "Visibility", diff --git a/locales/es/plugin__networking-console-plugin.json b/locales/es/plugin__networking-console-plugin.json index 463229f0f..e652057af 100644 --- a/locales/es/plugin__networking-console-plugin.json +++ b/locales/es/plugin__networking-console-plugin.json @@ -50,6 +50,7 @@ "Add virtual machines": "Agregar máquinas virtuales", "Advanced": "Advanced", "Advanced filter": "Advanced filter", + "Aggregated connection": "Aggregated connection", "Aggregation mode": "Aggregation mode", "All incoming traffic is denied to Pods in {{namespace}}": "Se rechaza todo el tráfico entrante a los Pods en {{namespace}}", "All outgoing traffic is allowed by default. Egress rules can be used to restrict outgoing traffic if the cluster network provider allows it. When using the OpenShift SDN cluster network provider, egress network policy is not supported.": "Todo el tráfico saliente está permitido de forma predeterminada. Se pueden utilizar reglas de salida para restringir el tráfico saliente si el proveedor de red del clúster lo permite. Cuando se utiliza el proveedor de red del clúster OpenShift SDN, no se admite la política de red de salida.", @@ -108,6 +109,9 @@ "Cluster administrator permissions are required to enable this feature.": "Se requieren permisos de administrador de clúster para habilitar esta función.", "Cluster IP": "IP del clúster", "Cluster map": "Cluster map", + "Cluster user-defined network to network attachment definition": "Cluster user-defined network to network attachment definition", + "Cluster user-defined network to pod": "Cluster user-defined network to pod", + "Cluster user-defined network to virtual machine": "Cluster user-defined network to virtual machine", "Cluster-wide UserDefinedNetworks": "UserDefinedNetworks en todo el clúster", "Cluster's default network": "Cluster's default network", "ClusterUserDefinedNetwork": "ClusterUserDefinedNetwork", @@ -198,6 +202,7 @@ "Duplicate keys found in peer pod selector": "Claves duplicadas encontradas en el selector de pods de pares", "e.g. \"openshift-storage\"": "e.g. \"openshift-storage\"", "Edge": "Edge", + "Edges": "Edges", "Edit": "Editar", "Edit {{kind}}": "Editar {{kind}}", "Edit {{label}}": "Editar {{label}}", @@ -254,6 +259,7 @@ "Given subnet is split into smaller subnets for every node.": "La subred dada se divide en subredes más pequeñas para cada nodo.", "Graph view": "Graph view", "Grid": "Grid", + "Groups": "Groups", "Health": "Estado", "Healthy: {{ready}} of {{total}} endpoints ready": "En buen estado: {{ready}} de {{total}} puntos de acceso listos", "Hide": "Ocultar", @@ -279,6 +285,7 @@ "Ingress points of load balancer": "Puntos de entrada del balanceador de carga", "Ingress rule": "Regla de ingreso", "Ingress rules": "Reglas de ingreso", + "Ingress to service": "Ingress to service", "Ingresses": "Ingresos", "Input error: selectors must start and end by a letter or number, and can only contain -, _, / or . Offending value: {{offendingSelector}}": "Error de entrada: los selectores deben comenzar y terminar con una letra o número, y solo pueden contener -, _, / o . Valor ofensivo: {{offendingSelector}}", "Insecure traffic": "Tráfico inseguro", @@ -310,6 +317,7 @@ "Learn how to use NetworkAttachmentDefinitions": "Aprenda a utilizar NetworkAttachmentDefinitions", "Learn more about {{ kind }}": "Más información acerca de {{ kind }}", "Learn more about working with projects": "Obtenga más información sobre cómo trabajar con proyectos", + "Legend": "Legend", "Links": "Links", "linux-bridge": "linux-bridge", "List of {{resourceName}} matching": "Lista de {{resourceName}} coincidentes", @@ -338,6 +346,7 @@ "MTU": "MTU", "MTU is optional. If not provided, the globally configured value in OVN-Kubernetes (defaults to 1400) is used for the network.": "MTU es opcional. Si no se proporciona, se utiliza el valor configurado globalmente en OVN-Kubernetes (el valor predeterminado es 1400) para la red.", "MTU is the maximum transmission unit for a network.": "MTU es la unidad máxima de transmisión de una red.", + "Multi-network policy to network attachment definition": "Multi-network policy to network attachment definition", "multi-networkpolicies": "multi-networkpolicies", "multi-networkpolicy": "multi-networkpolicy", "MultiNetworkPolicies": "MultiNetworkPolicies", @@ -345,6 +354,7 @@ "Name": "Nombre", "Name is required": "Se requiere un nombre", "Namespace": "Espacio de nombre", + "Namespace + Owner": "Namespace + Owner", "Namespace is required": "Se requiere un espacio de nombres", "Namespace selector": "Selector de espacio de nombres", "Namespace Selector": "Selector de espacio de nombre", @@ -445,6 +455,7 @@ "Pod port or name": "Puerto o nombre del pod", "Pod selector": "Selector de pods", "Pod selector for": "Selector de pods para", + "Pod to network attachment definition": "Pod to network attachment definition", "Pod unschedulable": "Pod no programable", "pods": "pods", "Pods": "Pods", @@ -487,7 +498,10 @@ "Remove port": "Quitar puerto", "Remove subnets?": "¿Desea eliminar subredes?", "Remove virtual machine from network?": "¿Desea eliminar la máquina virtual de la red?", + "Replace namespaced resources with their namespace; cluster-scoped resources remain unchanged.": "Replace namespaced resources with their namespace; cluster-scoped resources remain unchanged.", + "Replace resources with their controller owner when one is available; ownerless resources remain unchanged.": "Replace resources with their controller owner when one is available; ownerless resources remain unchanged.", "Reset to default": "Restablecer a valores predeterminados", + "Resource": "Resource", "Resource name": "Nombre del recurso", "Resources in a grid inside each group; groups packed in rows.": "Resources in a grid inside each group; groups packed in rows.", "Restarts": "Reinicios", @@ -499,6 +513,7 @@ "Role describes the network role in the pod.": "El rol describe el rol de la red en el pod.", "Route": "Route", "Route details": "Detalles de la ruta", + "Route to service": "Route to service", "Router canonical hostname": "Nombre de host canónico del enrutador", "Router: {{routerName}}": "Enrutador: {{routerName}}", "Routes": "Rutas", @@ -508,6 +523,7 @@ "Rules": "Normas", "Running": "En ejecución", "Save": "Guardar", + "Scope": "Scope", "Search by name": "Search by name", "Search by name...": "Buscar por nombre...", "Search topology...": "Search topology...", @@ -547,8 +563,11 @@ "Show a preview of the <2>affected pods that this ingress rule will apply to.": "Mostrar una vista previa de los <2>pods afectados a los que se aplicará esta regla de ingreso.", "Show a preview of the <2>affected pods that this policy will apply to": "Mostrar una vista previa de los <2>pods afectados a los que se aplicará esta política", "Show a preview of the <2>matching pods that this selector will apply to": "Mostrar una vista previa de los <2>pods coincidentes a los que se aplicará este selector", + "Show individual resources using their Kubernetes kind and name.": "Show individual resources using their Kubernetes kind and name.", "Show labels": "Show labels", "Show less": "Mostrar menos", + "Show NetworkAttachmentDefinitions, UserDefinedNetworks, and ClusterUserDefinedNetworks as logical network nodes.": "Show NetworkAttachmentDefinitions, UserDefinedNetworks, and ClusterUserDefinedNetworks as logical network nodes.", + "Show topology legend": "Show topology legend", "Showing {{shown}} from {{total}} results": "Mostrando {{shown}} de {{total}} resultados", "Showing network definitions and consumers in project {{project}}. NMState configuration is cluster-wide.": "Showing network definitions and consumers in project {{project}}. NMState configuration is cluster-wide.", "Some consumer information is unavailable.": "Some consumer information is unavailable.", @@ -596,6 +615,7 @@ "To use a custom route, you must update your DNS provider by creating a canonical name (CNAME) record. Your CNAME record should point to your custom domain <2>{{host}}, to the OpenShift canonical router hostname, <5>{{routerCanonicalHostname}}, as the alias.": "Para utilizar una ruta personalizada, debe actualizar su proveedor de DNS creando un registro de nombre canónico (CNAME). Su registro CNAME debe apuntar a su dominio personalizado <2>{{host}}, al nombre de host del enrutador canónico de OpenShift, <5>{{routerCanonicalHostname}}, como alias.", "Topology": "Topología", "Topology describes network configuration.": "La topología describe la configuración de la red.", + "Topology scope": "Topology scope", "total limit": "límite total", "total requested": "total solicitado", "Traffic": "Tráfico", @@ -616,6 +636,9 @@ "Uplink connection": "Uplink connection", "Use \"{{inputValue}}\"": "Utilizar \"{{inputValue}}\"", "Use the default Pod network": "Utilice la red pod predeterminada", + "User-defined network to network attachment definition": "User-defined network to network attachment definition", + "User-defined network to pod": "User-defined network to pod", + "User-defined network to virtual machine": "User-defined network to virtual machine", "UserDefinedNetwork": "UserDefinedNetwork", "UserDefinedNetworks": "UserDefinedNetworks", "Value": "Valor", @@ -629,6 +652,7 @@ "View logs": "Ver registros", "View naming information": "Ver información de nombres", "Virtual machine information is unavailable; consumer information is incomplete.": "Virtual machine information is unavailable; consumer information is incomplete.", + "Virtual machine to network attachment definition": "Virtual machine to network attachment definition", "Virtual Machines": "Máquinas virtuales", "VirtualMachine": "VirtualMachine", "Visibility": "Visibility", diff --git a/locales/fr/plugin__networking-console-plugin.json b/locales/fr/plugin__networking-console-plugin.json index e5d157689..1ca7ea752 100644 --- a/locales/fr/plugin__networking-console-plugin.json +++ b/locales/fr/plugin__networking-console-plugin.json @@ -50,6 +50,7 @@ "Add virtual machines": "Ajouter des machines virtuelles", "Advanced": "Advanced", "Advanced filter": "Advanced filter", + "Aggregated connection": "Aggregated connection", "Aggregation mode": "Aggregation mode", "All incoming traffic is denied to Pods in {{namespace}}": "Tout le trafic entrant est refusé aux pods dans {{namespace}}", "All outgoing traffic is allowed by default. Egress rules can be used to restrict outgoing traffic if the cluster network provider allows it. When using the OpenShift SDN cluster network provider, egress network policy is not supported.": "Tout le trafic sortant est autorisé par défaut. Les règles de sortie peuvent être utilisées pour restreindre le trafic sortant si le fournisseur de réseau du cluster le permet. Lors de l’utilisation du fournisseur de réseau de cluster OpenShift SDN, la stratégie réseau de sortie n’est pas prise en charge.", @@ -108,6 +109,9 @@ "Cluster administrator permissions are required to enable this feature.": "Des autorisations d’administrateur de cluster sont requises pour activer cette fonctionnalité.", "Cluster IP": "IP du cluster", "Cluster map": "Cluster map", + "Cluster user-defined network to network attachment definition": "Cluster user-defined network to network attachment definition", + "Cluster user-defined network to pod": "Cluster user-defined network to pod", + "Cluster user-defined network to virtual machine": "Cluster user-defined network to virtual machine", "Cluster-wide UserDefinedNetworks": "Réseaux définis par l'utilisateur à l'échelle du cluster", "Cluster's default network": "Cluster's default network", "ClusterUserDefinedNetwork": "ClusterUserDefinedNetwork", @@ -198,6 +202,7 @@ "Duplicate keys found in peer pod selector": "Clés en double trouvées dans le sélecteur de pod homologue", "e.g. \"openshift-storage\"": "e.g. \"openshift-storage\"", "Edge": "Périphérie", + "Edges": "Edges", "Edit": "Modifier", "Edit {{kind}}": "Modifier {{kind}}", "Edit {{label}}": "Modifier {{label}}", @@ -254,6 +259,7 @@ "Given subnet is split into smaller subnets for every node.": "Le sous-réseau donné est divisé en sous-réseaux plus petits pour chaque nœud.", "Graph view": "Graph view", "Grid": "Grid", + "Groups": "Groups", "Health": "État de fonctionnement", "Healthy: {{ready}} of {{total}} endpoints ready": "En bon état de fonctionnement : {{ready}} de {{total}} points de terminaison prêts", "Hide": "Masquer", @@ -279,6 +285,7 @@ "Ingress points of load balancer": "Points d’entrée de l’équilibreur de charge", "Ingress rule": "Règle d’entrée", "Ingress rules": "Règles d’entrée", + "Ingress to service": "Ingress to service", "Ingresses": "Entrées", "Input error: selectors must start and end by a letter or number, and can only contain -, _, / or . Offending value: {{offendingSelector}}": "Erreur de saisie\u00a0: les sélecteurs doivent commencer et se terminer par une lettre ou un chiffre, et ne peuvent contenir que les caractères -, _, / ou . Valeur erronée\u00a0: {{offendingSelector}}", "Insecure traffic": "Trafic non sécurisé", @@ -310,6 +317,7 @@ "Learn how to use NetworkAttachmentDefinitions": "Découvrez comment utiliser les définitions de rattachement de réseau", "Learn more about {{ kind }}": "En savoir plus sur {{ kind }}", "Learn more about working with projects": "En savoir plus sur l’utilisation de projets", + "Legend": "Legend", "Links": "Links", "linux-bridge": "linux-bridge", "List of {{resourceName}} matching": "Liste de {{resourceName}} correspondants", @@ -338,6 +346,7 @@ "MTU": "MTU", "MTU is optional. If not provided, the globally configured value in OVN-Kubernetes (defaults to 1400) is used for the network.": "La MTU est facultative ; si elle n'est pas fournie, la valeur configurée globalement dans OVN-Kubernetes (1400 par défaut) est utilisée pour le réseau.", "MTU is the maximum transmission unit for a network.": "L'unité de transmission maximale (MTU) d'un réseau.", + "Multi-network policy to network attachment definition": "Multi-network policy to network attachment definition", "multi-networkpolicies": "multi-networkpolicies", "multi-networkpolicy": "multi-networkpolicy", "MultiNetworkPolicies": "Politiques multi-réseaux", @@ -345,6 +354,7 @@ "Name": "Nom", "Name is required": " Le nom est obligatoire.", "Namespace": "Espace de noms", + "Namespace + Owner": "Namespace + Owner", "Namespace is required": "L'espace de noms est requis.", "Namespace selector": "Sélecteur d’espace de noms", "Namespace Selector": "Sélecteur d'espace de noms", @@ -445,6 +455,7 @@ "Pod port or name": "Port ou nom du pod", "Pod selector": "Sélecteur de pod", "Pod selector for": "Sélecteur de pod pour", + "Pod to network attachment definition": "Pod to network attachment definition", "Pod unschedulable": "Pod non planifiable", "pods": " pods", "Pods": "Pods", @@ -487,7 +498,10 @@ "Remove port": "Supprimer le port", "Remove subnets?": "Supprimer les sous-réseaux\u00a0?", "Remove virtual machine from network?": "Supprimer la machine virtuelle du réseau\u00a0?", + "Replace namespaced resources with their namespace; cluster-scoped resources remain unchanged.": "Replace namespaced resources with their namespace; cluster-scoped resources remain unchanged.", + "Replace resources with their controller owner when one is available; ownerless resources remain unchanged.": "Replace resources with their controller owner when one is available; ownerless resources remain unchanged.", "Reset to default": "Réinitialiser par défaut", + "Resource": "Resource", "Resource name": "Nom de la ressource", "Resources in a grid inside each group; groups packed in rows.": "Resources in a grid inside each group; groups packed in rows.", "Restarts": "Redémarre", @@ -499,6 +513,7 @@ "Role describes the network role in the pod.": "Le rôle décrit le rôle du réseau dans le pod.", "Route": "Route", "Route details": "Détails de l’itinéraire", + "Route to service": "Route to service", "Router canonical hostname": "Nom d’hôte canonique du routeur", "Router: {{routerName}}": "Routeur\u00a0: {{routerName}}", "Routes": "Itinéraires", @@ -508,6 +523,7 @@ "Rules": "Règles", "Running": "En cours d’exécution", "Save": "Enregistrer", + "Scope": "Scope", "Search by name": "Search by name", "Search by name...": "Rechercher par nom...", "Search topology...": "Search topology...", @@ -547,8 +563,11 @@ "Show a preview of the <2>affected pods that this ingress rule will apply to.": "Affichez un aperçu des <2>pods affectés auxquels cette règle de trafic entrant s’appliquera.", "Show a preview of the <2>affected pods that this policy will apply to": "Afficher un aperçu des <2>pods affectés auxquels cette stratégie s’appliquera", "Show a preview of the <2>matching pods that this selector will apply to": "Afficher un aperçu des <2>pods correspondants auxquels ce sélecteur s'appliquera", + "Show individual resources using their Kubernetes kind and name.": "Show individual resources using their Kubernetes kind and name.", "Show labels": "Show labels", "Show less": "Montrer moins", + "Show NetworkAttachmentDefinitions, UserDefinedNetworks, and ClusterUserDefinedNetworks as logical network nodes.": "Show NetworkAttachmentDefinitions, UserDefinedNetworks, and ClusterUserDefinedNetworks as logical network nodes.", + "Show topology legend": "Show topology legend", "Showing {{shown}} from {{total}} results": "Affichage de {{shown}} sur {{total}} résultats", "Showing network definitions and consumers in project {{project}}. NMState configuration is cluster-wide.": "Showing network definitions and consumers in project {{project}}. NMState configuration is cluster-wide.", "Some consumer information is unavailable.": "Some consumer information is unavailable.", @@ -596,6 +615,7 @@ "To use a custom route, you must update your DNS provider by creating a canonical name (CNAME) record. Your CNAME record should point to your custom domain <2>{{host}}, to the OpenShift canonical router hostname, <5>{{routerCanonicalHostname}}, as the alias.": "Pour utiliser un itinéraire personnalisé, vous devez mettre à jour votre fournisseur\u00a0DNS en créant un enregistrement de nom canonique (CNAME). Votre enregistrement\u00a0CNAME doit pointer vers votre domaine personnalisé <2>{{host}}, vers le nom d’hôte canonique du routeur OpenShift, <5>{{routerCanonicalHostname}} , comme alias.", "Topology": "Topologie", "Topology describes network configuration.": "La topologie décrit la configuration du réseau.", + "Topology scope": "Topology scope", "total limit": "limite totale", "total requested": "total demandé", "Traffic": "Trafic", @@ -616,6 +636,9 @@ "Uplink connection": "Uplink connection", "Use \"{{inputValue}}\"": "Utiliser \"{{inputValue}} \"", "Use the default Pod network": "Utiliser le réseau Pod par défaut", + "User-defined network to network attachment definition": "User-defined network to network attachment definition", + "User-defined network to pod": "User-defined network to pod", + "User-defined network to virtual machine": "User-defined network to virtual machine", "UserDefinedNetwork": "Réseau défini par l'utilisateur", "UserDefinedNetworks": "Réseaux définis par l'utilisateur", "Value": "Valeur", @@ -629,6 +652,7 @@ "View logs": "Afficher les journaux", "View naming information": "Afficher les informations sur l’attribution de nom", "Virtual machine information is unavailable; consumer information is incomplete.": "Virtual machine information is unavailable; consumer information is incomplete.", + "Virtual machine to network attachment definition": "Virtual machine to network attachment definition", "Virtual Machines": "Machines virtuelles", "VirtualMachine": "VirtualMachine", "Visibility": "Visibility", diff --git a/locales/ja/plugin__networking-console-plugin.json b/locales/ja/plugin__networking-console-plugin.json index d3391a297..296f8f785 100644 --- a/locales/ja/plugin__networking-console-plugin.json +++ b/locales/ja/plugin__networking-console-plugin.json @@ -46,6 +46,7 @@ "Add virtual machines": "仮想マシンの追加", "Advanced": "Advanced", "Advanced filter": "Advanced filter", + "Aggregated connection": "Aggregated connection", "Aggregation mode": "Aggregation mode", "All incoming traffic is denied to Pods in {{namespace}}": "すべての受信トラフィックが {{namespace}} の Pod に対して拒否されます", "All outgoing traffic is allowed by default. Egress rules can be used to restrict outgoing traffic if the cluster network provider allows it. When using the OpenShift SDN cluster network provider, egress network policy is not supported.": "すべての送信トラフィックはデフォルトで許可されます。Egress ルールは、クラスターネットワークプロバイダーが許可する場合に、送信トラフィックを制限するために使用できます。OpenShift SDN クラスターネットワークプロバイダーを使用する場合、Egress ネットワークポリシーはサポートされません。", @@ -103,6 +104,9 @@ "Cluster administrator permissions are required to enable this feature.": "この機能を有効にするには、クラスター管理者権限が必要です。", "Cluster IP": "クラスター IP", "Cluster map": "Cluster map", + "Cluster user-defined network to network attachment definition": "Cluster user-defined network to network attachment definition", + "Cluster user-defined network to pod": "Cluster user-defined network to pod", + "Cluster user-defined network to virtual machine": "Cluster user-defined network to virtual machine", "Cluster-wide UserDefinedNetworks": "クラスター全体の UserDefinedNetworks", "Cluster's default network": "Cluster's default network", "ClusterUserDefinedNetwork": "ClusterUserDefinedNetwork", @@ -193,6 +197,7 @@ "Duplicate keys found in peer pod selector": "ピア Pod セレクターで鍵の重複が見つかりました", "e.g. \"openshift-storage\"": "e.g. \"openshift-storage\"", "Edge": "Edge", + "Edges": "Edges", "Edit": "編集", "Edit {{kind}}": "{{kind}} の編集", "Edit {{label}}": "{{label}} の編集", @@ -249,6 +254,7 @@ "Given subnet is split into smaller subnets for every node.": "指定されたサブネットは、各ノード用に、より小さなサブネットに分割されます。", "Graph view": "Graph view", "Grid": "Grid", + "Groups": "Groups", "Health": "健全性", "Healthy: {{ready}} of {{total}} endpoints ready": "正常: {{total}} 個のエンドポイントのうち {{ready}} 個が準備完了", "Hide": "非表示", @@ -274,6 +280,7 @@ "Ingress points of load balancer": "ロードバランサーの Ingress ポイント", "Ingress rule": "Ingress ルール", "Ingress rules": "Ingress ルール", + "Ingress to service": "Ingress to service", "Ingresses": "Ingresses", "Input error: selectors must start and end by a letter or number, and can only contain -, _, / or . Offending value: {{offendingSelector}}": "入力エラー: セレクターは文字または数字で開始および終了する必要があり、-、_、/、または . しか含めることができません。無効な値: {{offendingSelector}}", "Insecure traffic": "非セキュアなトラフィック", @@ -305,6 +312,7 @@ "Learn how to use NetworkAttachmentDefinitions": "NetworkAttachmentDefinitions の使用方法の詳細", "Learn more about {{ kind }}": "{{ kind }} の詳細", "Learn more about working with projects": "プロジェクトの使用方法は、こちらを参照してください", + "Legend": "Legend", "Links": "Links", "linux-bridge": "linux-bridge", "List of {{resourceName}} matching": "一致する {{resourceName}} のリスト", @@ -333,6 +341,7 @@ "MTU": "MTU", "MTU is optional. If not provided, the globally configured value in OVN-Kubernetes (defaults to 1400) is used for the network.": "MTU の指定は任意です。指定しない場合、OVN-Kubernetes でグローバルに設定された値 (デフォルトは 1400) がネットワークに使用されます。", "MTU is the maximum transmission unit for a network.": "MTU はネットワークの最大転送単位です。", + "Multi-network policy to network attachment definition": "Multi-network policy to network attachment definition", "multi-networkpolicies": "multi-networkpolicies", "multi-networkpolicy": "multi-networkpolicy", "MultiNetworkPolicies": "MultiNetworkPolicies", @@ -340,6 +349,7 @@ "Name": "名前", "Name is required": "名前は必須です", "Namespace": "Namespace", + "Namespace + Owner": "Namespace + Owner", "Namespace is required": "Namespace は必須です", "Namespace selector": "Namespace セレクター", "Namespace Selector": "Namespace セレクター", @@ -438,6 +448,7 @@ "Pod port or name": "Pod ポートまたは名前", "Pod selector": "Pod セレクター", "Pod selector for": "以下の Pod セレクター", + "Pod to network attachment definition": "Pod to network attachment definition", "Pod unschedulable": "Pod がスケジュール対象外である", "pods": "Pod", "Pods": "Pod", @@ -480,7 +491,10 @@ "Remove port": "ポートの削除", "Remove subnets?": "サブネットを削除しますか?", "Remove virtual machine from network?": "仮想マシンをネットワークから削除しますか?", + "Replace namespaced resources with their namespace; cluster-scoped resources remain unchanged.": "Replace namespaced resources with their namespace; cluster-scoped resources remain unchanged.", + "Replace resources with their controller owner when one is available; ownerless resources remain unchanged.": "Replace resources with their controller owner when one is available; ownerless resources remain unchanged.", "Reset to default": "デフォルトにリセット", + "Resource": "Resource", "Resource name": "リソース名", "Resources in a grid inside each group; groups packed in rows.": "Resources in a grid inside each group; groups packed in rows.", "Restarts": "再起動回数", @@ -492,6 +506,7 @@ "Role describes the network role in the pod.": "Role は Pod におけるネットワークの役割を表します。", "Route": "Route", "Route details": "Route の詳細", + "Route to service": "Route to service", "Router canonical hostname": "ルーターの正規ホスト名", "Router: {{routerName}}": "ルーター: {{routerName}}", "Routes": "Routes", @@ -501,6 +516,7 @@ "Rules": "ルール", "Running": "実行中", "Save": "保存", + "Scope": "Scope", "Search by name": "Search by name", "Search by name...": "名前で検索...", "Search topology...": "Search topology...", @@ -540,8 +556,11 @@ "Show a preview of the <2>affected pods that this ingress rule will apply to.": "この Ingress ルールが適用される <2>影響を受ける Pod のプレビューを表示します。", "Show a preview of the <2>affected pods that this policy will apply to": "このポリシーが適用される <2>影響を受ける Pod のプレビューを表示します", "Show a preview of the <2>matching pods that this selector will apply to": "このセレクターが適用される <2>一致する Pod のプレビューを表示します", + "Show individual resources using their Kubernetes kind and name.": "Show individual resources using their Kubernetes kind and name.", "Show labels": "Show labels", "Show less": "簡易表示", + "Show NetworkAttachmentDefinitions, UserDefinedNetworks, and ClusterUserDefinedNetworks as logical network nodes.": "Show NetworkAttachmentDefinitions, UserDefinedNetworks, and ClusterUserDefinedNetworks as logical network nodes.", + "Show topology legend": "Show topology legend", "Showing {{shown}} from {{total}} results": "{{total}} 件中 {{shown}} 件の結果を表示中", "Showing network definitions and consumers in project {{project}}. NMState configuration is cluster-wide.": "Showing network definitions and consumers in project {{project}}. NMState configuration is cluster-wide.", "Some consumer information is unavailable.": "Some consumer information is unavailable.", @@ -589,6 +608,7 @@ "To use a custom route, you must update your DNS provider by creating a canonical name (CNAME) record. Your CNAME record should point to your custom domain <2>{{host}}, to the OpenShift canonical router hostname, <5>{{routerCanonicalHostname}}, as the alias.": "カスタムルートを使用するには、正規名 (CNAME) レコードを作成して DNS プロバイダーを更新する必要があります。カスタムドメイン <2>{{host}} が、エイリアスとなる OpenShift の正規ルーターホスト名 <5>{{routerCanonicalHostname}} を指すように CNAME レコードを設定してください。", "Topology": "トポロジー", "Topology describes network configuration.": "トポロジーはネットワーク構成を表します。", + "Topology scope": "Topology scope", "total limit": "制限の合計", "total requested": "要求の合計", "Traffic": "トラフィック", @@ -609,6 +629,9 @@ "Uplink connection": "Uplink connection", "Use \"{{inputValue}}\"": "\"{{inputValue}}\" の使用", "Use the default Pod network": "デフォルトの Pod ネットワークを使用する", + "User-defined network to network attachment definition": "User-defined network to network attachment definition", + "User-defined network to pod": "User-defined network to pod", + "User-defined network to virtual machine": "User-defined network to virtual machine", "UserDefinedNetwork": "UserDefinedNetwork", "UserDefinedNetworks": "UserDefinedNetworks", "Value": "値", @@ -622,6 +645,7 @@ "View logs": "ログの表示", "View naming information": "命名情報の表示", "Virtual machine information is unavailable; consumer information is incomplete.": "Virtual machine information is unavailable; consumer information is incomplete.", + "Virtual machine to network attachment definition": "Virtual machine to network attachment definition", "Virtual Machines": "仮想マシン", "VirtualMachine": "VirtualMachine", "Visibility": "Visibility", diff --git a/locales/ko/plugin__networking-console-plugin.json b/locales/ko/plugin__networking-console-plugin.json index 905de69ab..6d07344ef 100644 --- a/locales/ko/plugin__networking-console-plugin.json +++ b/locales/ko/plugin__networking-console-plugin.json @@ -46,6 +46,7 @@ "Add virtual machines": "가상 머신 추가", "Advanced": "Advanced", "Advanced filter": "Advanced filter", + "Aggregated connection": "Aggregated connection", "Aggregation mode": "Aggregation mode", "All incoming traffic is denied to Pods in {{namespace}}": "수신되는 모든 트래픽은 {{namespace}}의 Pod에 거부됩니다.", "All outgoing traffic is allowed by default. Egress rules can be used to restrict outgoing traffic if the cluster network provider allows it. When using the OpenShift SDN cluster network provider, egress network policy is not supported.": "모든 나가는 트래픽은 기본적으로 허용됩니다. 클러스터 네트워크 공급자가 송신 트래픽을 허용하는 경우 송신 규칙을 사용하여 나가는 트래픽을 제한할 수 있습니다. OpenShift SDN 클러스터 네트워크 공급자를 사용하는 경우 송신 네트워크 정책이 지원되지 않습니다.", @@ -103,6 +104,9 @@ "Cluster administrator permissions are required to enable this feature.": "이 기능을 활성화하려면 클러스터 관리자 권한이 필요합니다.", "Cluster IP": "클러스터 IP", "Cluster map": "Cluster map", + "Cluster user-defined network to network attachment definition": "Cluster user-defined network to network attachment definition", + "Cluster user-defined network to pod": "Cluster user-defined network to pod", + "Cluster user-defined network to virtual machine": "Cluster user-defined network to virtual machine", "Cluster-wide UserDefinedNetworks": "클러스터 전체 UserDefinedNetworks", "Cluster's default network": "Cluster's default network", "ClusterUserDefinedNetwork": "ClusterUserDefinedNetwork", @@ -193,6 +197,7 @@ "Duplicate keys found in peer pod selector": "피어 pod 선택기에서 중복 키가 발견됨", "e.g. \"openshift-storage\"": "e.g. \"openshift-storage\"", "Edge": "Edge", + "Edges": "Edges", "Edit": "편집", "Edit {{kind}}": "{{kind}} 편집", "Edit {{label}}": "{{label}} 편집", @@ -249,6 +254,7 @@ "Given subnet is split into smaller subnets for every node.": "지정된 서브넷은 각 노드별로 더 작은 서브넷으로 분할됩니다.", "Graph view": "Graph view", "Grid": "Grid", + "Groups": "Groups", "Health": "상태", "Healthy: {{ready}} of {{total}} endpoints ready": "정상: {{total}}개 엔드포인트 중 {{ready}}개 준비됨", "Hide": "숨기기", @@ -274,6 +280,7 @@ "Ingress points of load balancer": "로드 밸런서의 Ingress 포인트", "Ingress rule": "Ingress 규칙", "Ingress rules": "Ingress 규칙", + "Ingress to service": "Ingress to service", "Ingresses": "Ingress", "Input error: selectors must start and end by a letter or number, and can only contain -, _, / or . Offending value: {{offendingSelector}}": "입력 오류: 선택기는 문자나 숫자로 시작하고 끝나야 하며 -, _, / 또는 . 만 포함할 수 있습니다. 잘못된 값: {{offendingSelector}}", "Insecure traffic": "안전하지 않은 트래픽", @@ -305,6 +312,7 @@ "Learn how to use NetworkAttachmentDefinitions": "NetworkAttachmentDefinitions 사용 방법 알아보기", "Learn more about {{ kind }}": "{{ kind }}에 대해 자세히 알아보기", "Learn more about working with projects": "프로젝트 작업에 대해 자세히 알아보기", + "Legend": "Legend", "Links": "Links", "linux-bridge": "linux-bridge", "List of {{resourceName}} matching": "일치하는 {{resourceName}} 목록", @@ -333,6 +341,7 @@ "MTU": "MTU", "MTU is optional. If not provided, the globally configured value in OVN-Kubernetes (defaults to 1400) is used for the network.": "MTU는 선택 사항이며 제공되지 않는 경우 네트워크에 전역적으로 구성된 OVN-Kubernetes 값(기본값: 1400)이 사용됩니다.", "MTU is the maximum transmission unit for a network.": "MTU는 네트워크의 최대 전송 단위입니다.", + "Multi-network policy to network attachment definition": "Multi-network policy to network attachment definition", "multi-networkpolicies": "multi-networkpolicies", "multi-networkpolicy": "multi-networkpolicy", "MultiNetworkPolicies": "MultiNetworkPolicies", @@ -340,6 +349,7 @@ "Name": "이름", "Name is required": "이름은 필수 입력사항입니다.", "Namespace": "네임 스페이스", + "Namespace + Owner": "Namespace + Owner", "Namespace is required": "네임스페이스가 필요합니다.", "Namespace selector": "네임스페이스 선택기", "Namespace Selector": "네임스페이스 선택기", @@ -438,6 +448,7 @@ "Pod port or name": "Pod 포트 또는 이름", "Pod selector": "Pod 선택기", "Pod selector for": "다음의 Pod 선택기", + "Pod to network attachment definition": "Pod to network attachment definition", "Pod unschedulable": "Pod 예약 불가", "pods": "pods", "Pods": "Pod", @@ -480,7 +491,10 @@ "Remove port": "포트 제거", "Remove subnets?": "서브넷을 제거하시겠습니까?", "Remove virtual machine from network?": "네트워크에서 가상 머신을 제거하시겠습니까?", + "Replace namespaced resources with their namespace; cluster-scoped resources remain unchanged.": "Replace namespaced resources with their namespace; cluster-scoped resources remain unchanged.", + "Replace resources with their controller owner when one is available; ownerless resources remain unchanged.": "Replace resources with their controller owner when one is available; ownerless resources remain unchanged.", "Reset to default": "기본값으로 재설정", + "Resource": "Resource", "Resource name": "리소스 이름", "Resources in a grid inside each group; groups packed in rows.": "Resources in a grid inside each group; groups packed in rows.", "Restarts": "재시작", @@ -492,6 +506,7 @@ "Role describes the network role in the pod.": "역할은 Pod의 네트워크 역할을 설명합니다.", "Route": "Route", "Route details": "경로 세부 정보", + "Route to service": "Route to service", "Router canonical hostname": "라우터의 표준 호스트 이름", "Router: {{routerName}}": "라우터: {{routerName}}", "Routes": "경로", @@ -501,6 +516,7 @@ "Rules": "규칙", "Running": "실행 중", "Save": "저장", + "Scope": "Scope", "Search by name": "Search by name", "Search by name...": "이름으로 검색 ...", "Search topology...": "Search topology...", @@ -540,8 +556,11 @@ "Show a preview of the <2>affected pods that this ingress rule will apply to.": "이 ingress 규칙이 적용되는 <2>영향을 받는 pod의 미리보기를 표시합니다.", "Show a preview of the <2>affected pods that this policy will apply to": "이 정책이 적용되는 <2>영향을 받는 pod의 미리보기를 표시합니다.", "Show a preview of the <2>matching pods that this selector will apply to": "이 선택기가 적용될 <2>일치하는 pod의 미리 보기를 표시합니다.", + "Show individual resources using their Kubernetes kind and name.": "Show individual resources using their Kubernetes kind and name.", "Show labels": "Show labels", "Show less": "적게 표시", + "Show NetworkAttachmentDefinitions, UserDefinedNetworks, and ClusterUserDefinedNetworks as logical network nodes.": "Show NetworkAttachmentDefinitions, UserDefinedNetworks, and ClusterUserDefinedNetworks as logical network nodes.", + "Show topology legend": "Show topology legend", "Showing {{shown}} from {{total}} results": "{{total}} 결과에서 {{shown}} 표시", "Showing network definitions and consumers in project {{project}}. NMState configuration is cluster-wide.": "Showing network definitions and consumers in project {{project}}. NMState configuration is cluster-wide.", "Some consumer information is unavailable.": "Some consumer information is unavailable.", @@ -589,6 +608,7 @@ "To use a custom route, you must update your DNS provider by creating a canonical name (CNAME) record. Your CNAME record should point to your custom domain <2>{{host}}, to the OpenShift canonical router hostname, <5>{{routerCanonicalHostname}}, as the alias.": "사용자 지정 경로를 사용하려면 정식 이름 (CNAME) 레코드를 만들어 DNS 공급자를 업데이트해야 합니다. CNAME 레코드는 사용자 지정 도메인 <2>{{host}}, OpenShift 정규 라우터 호스트 이름 <5>{{routerCanonicalHostname}}을 별칭으로 포인트해야 합니다.", "Topology": "토폴로지", "Topology describes network configuration.": "토폴로지는 네트워크 구성을 설명합니다.", + "Topology scope": "Topology scope", "total limit": "총 한도", "total requested": "총 요청", "Traffic": "트래픽", @@ -609,6 +629,9 @@ "Uplink connection": "Uplink connection", "Use \"{{inputValue}}\"": "\"{{inputValue}}\" 사용", "Use the default Pod network": "기본 Pod 네트워크 사용", + "User-defined network to network attachment definition": "User-defined network to network attachment definition", + "User-defined network to pod": "User-defined network to pod", + "User-defined network to virtual machine": "User-defined network to virtual machine", "UserDefinedNetwork": "UserDefinedNetwork", "UserDefinedNetworks": "UserDefinedNetworks", "Value": "값", @@ -622,6 +645,7 @@ "View logs": "로그보기", "View naming information": "이름 지정 정보 보기", "Virtual machine information is unavailable; consumer information is incomplete.": "Virtual machine information is unavailable; consumer information is incomplete.", + "Virtual machine to network attachment definition": "Virtual machine to network attachment definition", "Virtual Machines": "가상 머신", "VirtualMachine": "VirtualMachine", "Visibility": "Visibility", diff --git a/locales/zh/plugin__networking-console-plugin.json b/locales/zh/plugin__networking-console-plugin.json index 4ffffb2b7..0b7c7f9a9 100644 --- a/locales/zh/plugin__networking-console-plugin.json +++ b/locales/zh/plugin__networking-console-plugin.json @@ -46,6 +46,7 @@ "Add virtual machines": "添加虚拟机", "Advanced": "Advanced", "Advanced filter": "Advanced filter", + "Aggregated connection": "Aggregated connection", "Aggregation mode": "Aggregation mode", "All incoming traffic is denied to Pods in {{namespace}}": "所有传入的流量都被 {{namespace}} 中的 Pod 拒绝", "All outgoing traffic is allowed by default. Egress rules can be used to restrict outgoing traffic if the cluster network provider allows it. When using the OpenShift SDN cluster network provider, egress network policy is not supported.": "所有外向流量都是默认允许的。如果集群网络供应商允许,可以使用 egress 规则来限制外向流量。在使用 OpenShift SDN 集群网络供应商时,不支持 egress 网络策略。", @@ -103,6 +104,9 @@ "Cluster administrator permissions are required to enable this feature.": "启用此功能需要具有集群管理员权限。", "Cluster IP": "集群 IP", "Cluster map": "Cluster map", + "Cluster user-defined network to network attachment definition": "Cluster user-defined network to network attachment definition", + "Cluster user-defined network to pod": "Cluster user-defined network to pod", + "Cluster user-defined network to virtual machine": "Cluster user-defined network to virtual machine", "Cluster-wide UserDefinedNetworks": "集群范围的 UserDefinedNetworks", "Cluster's default network": "Cluster's default network", "ClusterUserDefinedNetwork": "ClusterUserDefinedNetwork", @@ -193,6 +197,7 @@ "Duplicate keys found in peer pod selector": "在 peer pod 选择器中找到重复的密钥", "e.g. \"openshift-storage\"": "e.g. \"openshift-storage\"", "Edge": "Edge", + "Edges": "Edges", "Edit": "编辑", "Edit {{kind}}": "编辑 {{kind}}", "Edit {{label}}": "编辑 {{label}}", @@ -249,6 +254,7 @@ "Given subnet is split into smaller subnets for every node.": "给定子网为每个节点分成较小的子网。", "Graph view": "Graph view", "Grid": "Grid", + "Groups": "Groups", "Health": "健康", "Healthy: {{ready}} of {{total}} endpoints ready": "健康: {{ready}}/{{total}} 个端点已就绪", "Hide": "隐藏", @@ -274,6 +280,7 @@ "Ingress points of load balancer": "负载均衡器的 Ingress 点", "Ingress rule": "Ingress 规则", "Ingress rules": "Ingress 规则", + "Ingress to service": "Ingress to service", "Ingresses": "Ingresses", "Input error: selectors must start and end by a letter or number, and can only contain -, _, / or . Offending value: {{offendingSelector}}": "输入错误:选择器必须以字母或数字开头和结尾,并且只能包含 -、_、/ 或 . 输出值:{{offendingSelector}}", "Insecure traffic": "不安全的流量", @@ -305,6 +312,7 @@ "Learn how to use NetworkAttachmentDefinitions": "了解如何使用 NetworkAttachmentDefinitions", "Learn more about {{ kind }}": "了解更多与 {{ kind }} 相关的信息", "Learn more about working with projects": "了解更多有关使用项目的信息", + "Legend": "Legend", "Links": "Links", "linux-bridge": "linux-bridge", "List of {{resourceName}} matching": "{{resourceName}} 匹配列表", @@ -333,6 +341,7 @@ "MTU": "MTU", "MTU is optional. If not provided, the globally configured value in OVN-Kubernetes (defaults to 1400) is used for the network.": "MTU 是可选的,如果没有提供,网络会使用 OVN-Kubernetes 中全局配置的值(默认为 1400)。", "MTU is the maximum transmission unit for a network.": "MTU 是网络的最大传输单元。", + "Multi-network policy to network attachment definition": "Multi-network policy to network attachment definition", "multi-networkpolicies": "multi-networkpolicies", "multi-networkpolicy": "multi-networkpolicy", "MultiNetworkPolicies": "MultiNetworkPolicies", @@ -340,6 +349,7 @@ "Name": "名称", "Name is required": "名称是必需的", "Namespace": "命名空间", + "Namespace + Owner": "Namespace + Owner", "Namespace is required": "命名空间是必需的", "Namespace selector": "命名空间选择器", "Namespace Selector": "命名空间选择器", @@ -438,6 +448,7 @@ "Pod port or name": "Pod 端口或名称", "Pod selector": "Pod 选择器", "Pod selector for": "Pod 选择器", + "Pod to network attachment definition": "Pod to network attachment definition", "Pod unschedulable": "Pod 不可调度", "pods": "pods", "Pods": "Pod", @@ -480,7 +491,10 @@ "Remove port": "删除端口", "Remove subnets?": "删除子网?", "Remove virtual machine from network?": "从网络中删除虚拟机?", + "Replace namespaced resources with their namespace; cluster-scoped resources remain unchanged.": "Replace namespaced resources with their namespace; cluster-scoped resources remain unchanged.", + "Replace resources with their controller owner when one is available; ownerless resources remain unchanged.": "Replace resources with their controller owner when one is available; ownerless resources remain unchanged.", "Reset to default": "重置为默认", + "Resource": "Resource", "Resource name": "资源名称", "Resources in a grid inside each group; groups packed in rows.": "Resources in a grid inside each group; groups packed in rows.", "Restarts": "重启", @@ -492,6 +506,7 @@ "Role describes the network role in the pod.": "Role 用于描述 pod 中的 network 角色。", "Route": "Route", "Route details": "路由详情", + "Route to service": "Route to service", "Router canonical hostname": "路由器真实主机名", "Router: {{routerName}}": "路由器:{{routerName}}", "Routes": "路由", @@ -501,6 +516,7 @@ "Rules": "规则", "Running": "运行", "Save": "保存", + "Scope": "Scope", "Search by name": "Search by name", "Search by name...": "按名称搜索...", "Search topology...": "Search topology...", @@ -540,8 +556,11 @@ "Show a preview of the <2>affected pods that this ingress rule will apply to.": "显示此 ingress 规则要应用到的<2>受影响 pod 的预览。", "Show a preview of the <2>affected pods that this policy will apply to": "显示此策略要应用到的<2>受影响 pod 的预览", "Show a preview of the <2>matching pods that this selector will apply to": "显示此选择器将应用到的<2>匹配 pod的预览", + "Show individual resources using their Kubernetes kind and name.": "Show individual resources using their Kubernetes kind and name.", "Show labels": "Show labels", "Show less": "显示更少", + "Show NetworkAttachmentDefinitions, UserDefinedNetworks, and ClusterUserDefinedNetworks as logical network nodes.": "Show NetworkAttachmentDefinitions, UserDefinedNetworks, and ClusterUserDefinedNetworks as logical network nodes.", + "Show topology legend": "Show topology legend", "Showing {{shown}} from {{total}} results": "显示来自 {{total}} 结果的 {{shown}}", "Showing network definitions and consumers in project {{project}}. NMState configuration is cluster-wide.": "Showing network definitions and consumers in project {{project}}. NMState configuration is cluster-wide.", "Some consumer information is unavailable.": "Some consumer information is unavailable.", @@ -589,6 +608,7 @@ "To use a custom route, you must update your DNS provider by creating a canonical name (CNAME) record. Your CNAME record should point to your custom domain <2>{{host}}, to the OpenShift canonical router hostname, <5>{{routerCanonicalHostname}}, as the alias.": "要使用自定义路由,您必须创建真实名称(CNAME)记录来更新 DNS。您的 CNAME 记录应指向您的自定义域<2>{{host}},到 OpenShift 真实路由器的主机名,<5>{{routerCanonicalHostname}} ,作为别名。", "Topology": "拓扑", "Topology describes network configuration.": "拓扑用于描述网络配置。", + "Topology scope": "Topology scope", "total limit": "总限制", "total requested": "请求的总量", "Traffic": "网络流量", @@ -609,6 +629,9 @@ "Uplink connection": "Uplink connection", "Use \"{{inputValue}}\"": "使用 \"{{inputValue}}\"", "Use the default Pod network": "使用默认 Pod 网络", + "User-defined network to network attachment definition": "User-defined network to network attachment definition", + "User-defined network to pod": "User-defined network to pod", + "User-defined network to virtual machine": "User-defined network to virtual machine", "UserDefinedNetwork": "UserDefinedNetwork", "UserDefinedNetworks": "UserDefinedNetworks", "Value": "值", @@ -622,6 +645,7 @@ "View logs": "查看日志", "View naming information": "查看命名信息", "Virtual machine information is unavailable; consumer information is incomplete.": "Virtual machine information is unavailable; consumer information is incomplete.", + "Virtual machine to network attachment definition": "Virtual machine to network attachment definition", "Virtual Machines": "虚拟机", "VirtualMachine": "VirtualMachine", "Visibility": "Visibility", diff --git a/package-lock.json b/package-lock.json index 4cd52be26..e91d8e62f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -33,6 +33,7 @@ "react-dom": "18.3.1", "react-hook-form": "^7.91.0", "react-i18next": "16.5.8", + "react-icons": "5.5.0", "react-router": "7.18.1", "react-tagsinput": "^3.20.3", "tlds": "1.261.0", @@ -20868,6 +20869,15 @@ } } }, + "node_modules/react-icons": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.5.0.tgz", + "integrity": "sha512-MEFcXdkP3dLo8uumGI5xN3lDFNsRtrjbOEKDLD7yv76v4wpnEq2Lt2qeHaQOr34I/wPN3s3+N08WkQ+CW37Xiw==", + "license": "MIT", + "peerDependencies": { + "react": "*" + } + }, "node_modules/react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", diff --git a/package.json b/package.json index 9efb5488e..76474830f 100644 --- a/package.json +++ b/package.json @@ -57,6 +57,7 @@ "react-dom": "18.3.1", "react-hook-form": "^7.91.0", "react-i18next": "16.5.8", + "react-icons": "5.5.0", "react-router": "7.18.1", "react-tagsinput": "^3.20.3", "tlds": "1.261.0", diff --git a/src/views/topology/TopologyPage.scss b/src/views/topology/TopologyPage.scss index 82e1f6b49..e74050b25 100644 --- a/src/views/topology/TopologyPage.scss +++ b/src/views/topology/TopologyPage.scss @@ -18,4 +18,18 @@ display: flex; flex-direction: column; } + + &__visualization { + display: flex; + height: 100%; + min-height: 0; + position: relative; + } + + &__canvas { + flex: 1; + min-width: 0; + min-height: 0; + width: 100%; + } } diff --git a/src/views/topology/components/CustomGroup/CustomGroup.tsx b/src/views/topology/components/CustomGroup/CustomGroup.tsx index 815aecc51..4ad326472 100644 --- a/src/views/topology/components/CustomGroup/CustomGroup.tsx +++ b/src/views/topology/components/CustomGroup/CustomGroup.tsx @@ -2,11 +2,14 @@ import React, { FC } from 'react'; import { DefaultGroup, + Ellipse, Node, + ShapeProps, WithDndDropProps, WithDragNodeProps, WithSelectionProps, } from '@patternfly/react-topology'; +import { NODE_DIAMETER } from '@views/topology/utils/constants'; import './CustomGroup.scss'; @@ -16,10 +19,54 @@ type CustomGroupProps = { WithDragNodeProps & WithSelectionProps; +const CollapsedGroupShape: FC = ({ + className, + dndDropRef, + element, + filter, + height, + width, +}) => { + const Icon = element.getData()?.icon; + const iconSize = Math.min(width, height) * 0.45; + + return ( + + + {Icon && ( + + + + )} + + ); +}; + const CustomGroup: FC = ({ element, ...rest }) => { const data = element.getData(); - return ; + return ( + CollapsedGroupShape} + {...rest} + /> + ); }; export default CustomGroup; diff --git a/src/views/topology/components/CustomNode/CustomNode.scss b/src/views/topology/components/CustomNode/CustomNode.scss index b0862027b..9ffaac0fa 100644 --- a/src/views/topology/components/CustomNode/CustomNode.scss +++ b/src/views/topology/components/CustomNode/CustomNode.scss @@ -12,6 +12,10 @@ .pf-topology__node__label__background { stroke-width: 2px; } + + .topology-icon > text { + fill: white; + } } .custom-node.pf-topology__node.pf-m-selected .pf-topology__node__background { diff --git a/src/views/topology/components/CustomNode/CustomNode.tsx b/src/views/topology/components/CustomNode/CustomNode.tsx index ed6d276f7..46f1d2348 100644 --- a/src/views/topology/components/CustomNode/CustomNode.tsx +++ b/src/views/topology/components/CustomNode/CustomNode.tsx @@ -2,6 +2,7 @@ import React, { FC } from 'react'; import { useSearchParams } from 'react-router'; import classNames from 'classnames'; +import { NetworkIcon } from '@patternfly/react-icons'; import { DefaultNode, Node, @@ -34,9 +35,13 @@ const CustomNode: FC = ({ element, ...rest }) => { // TODO: Read compactView from controllerState.viewOptions.compactView and adjust NODE_DIAMETER when implemented. // const _compactView = controllerState?.viewOptions?.compactView ?? true; - const data = element.getData(); - const Icon = data.icon; - const { height, width } = element.getBounds(); + const data = element.getData() ?? {}; + const Icon = data.icon ?? NetworkIcon; + const bounds = element.getBounds(); + if (!bounds || typeof bounds.width !== 'number' || typeof bounds.height !== 'number') { + return null; + } + const { height, width } = bounds; const xCenter = (width - ICON_SIZE) / 2; const yCenter = (height - ICON_SIZE) / 2; @@ -46,11 +51,16 @@ const CustomNode: FC = ({ element, ...rest }) => { return ( event.stopPropagation()} showLabel={showLabels} showStatusDecorator - truncateLength={8} + truncateLength={24} {...rest} > diff --git a/src/views/topology/components/DisplayOptionsDropdown.scss b/src/views/topology/components/DisplayOptionsDropdown.scss new file mode 100644 index 000000000..1aa7febe7 --- /dev/null +++ b/src/views/topology/components/DisplayOptionsDropdown.scss @@ -0,0 +1,19 @@ +.networking-topology__scope-group-row { + display: flex; + flex-wrap: wrap; + gap: var(--pf-t--global--spacer--xs); + margin-inline: var(--pf-t--global--spacer--sm); +} + +.networking-topology__scope-group-item { + flex: 1 1 9rem; + min-width: 0; +} + +.networking-topology__display-option-dropdown { + min-width: 0; +} + +.networking-topology__scope-group-toggle { + width: 100%; +} diff --git a/src/views/topology/components/DisplayOptionsDropdown.tsx b/src/views/topology/components/DisplayOptionsDropdown.tsx index a9ebf6e1c..36f5c507f 100644 --- a/src/views/topology/components/DisplayOptionsDropdown.tsx +++ b/src/views/topology/components/DisplayOptionsDropdown.tsx @@ -4,6 +4,8 @@ import { Content, ContentVariants, Divider, + Dropdown, + DropdownItem, Flex, FlexItem, MenuToggle, @@ -17,14 +19,25 @@ import { } from '@patternfly/react-core'; import { SlidersHIcon } from '@patternfly/react-icons'; import { useNetworkingTranslation } from '@utils/hooks/useNetworkingTranslation'; -import { DisplayOptionsState } from '@views/topology/types'; -import { TopologyLayoutType } from '@views/topology/utils/constants'; +import { DisplayOptionsState, TopologyGroupType } from '@views/topology/types'; +import { + TOPOLOGY_GROUP_ORDER, + TOPOLOGY_SCOPE_ORDER, + TopologyLayoutType, + TopologyViewTypes, +} from '@views/topology/utils/constants'; + +import './DisplayOptionsDropdown.scss'; type DisplayOptionsDropdownProps = { displayOptions: DisplayOptionsState; + group: TopologyGroupType; layout: TopologyLayoutType; onDisplayOptionsChange: (options: DisplayOptionsState) => void; + onGroupChange: (group: TopologyGroupType) => void; onLayoutChange: (layout: TopologyLayoutType) => void; + onScopeChange: (scope: TopologyViewTypes) => void; + scope: TopologyViewTypes; }; interface LayoutOption { @@ -35,12 +48,17 @@ interface LayoutOption { const DisplayOptionsDropdown: FC = ({ displayOptions, + group, layout, onDisplayOptionsChange, + onGroupChange, onLayoutChange, + onScopeChange, + scope, }) => { const { t } = useNetworkingTranslation(); const [isOpen, setIsOpen] = useState(false); + const [openDropdown, setOpenDropdown] = useState<'group' | 'scope' | undefined>(); const layoutOptions: LayoutOption[] = [ { @@ -85,17 +103,50 @@ const DisplayOptionsDropdown: FC = ({ }; const onToggle = () => setIsOpen((prev) => !prev); + const scopeLabel = (value: TopologyGroupType | TopologyViewTypes) => { + switch (value) { + case TopologyViewTypes.network: + return t('Network'); + case TopologyViewTypes.owner: + return t('Owner'); + case TopologyViewTypes.namespace: + return t('Namespace'); + case TopologyViewTypes.resource: + return t('Resource'); + case TopologyGroupType.namespaceOwner: + return t('Namespace + Owner'); + case TopologyGroupType.none: + return t('None'); + } + }; + + const groupOptions = TOPOLOGY_GROUP_ORDER.filter((value) => { + if (value === TopologyGroupType.none) return true; + if ( + (scope === TopologyViewTypes.namespace || scope === TopologyViewTypes.network) && + value === TopologyGroupType.owner + ) { + return false; + } + if (scope !== TopologyViewTypes.resource && value === TopologyGroupType.namespaceOwner) { + return false; + } + return value !== scope; + }); return (