mirror of https://github.com/portainer/portainer
fix(kube-tables): update table accessor fns [EE-5464] (#8920)
* fix(services): update accessor fns [EE-5464] * small fixes --------- Co-authored-by: testa113 <testa113>pull/8720/head
parent
22f4c5d650
commit
42fce1ec57
|
@ -21,6 +21,7 @@ import { useTableState } from '@@/datatables/useTableState';
|
|||
import { useMutationDeleteServices, useServices } from '../service';
|
||||
import { Service } from '../types';
|
||||
import { DefaultDatatableSettings } from '../../datatables/DefaultDatatableSettings';
|
||||
import { isSystemNamespace } from '../../namespaces/utils';
|
||||
|
||||
import { columns } from './columns';
|
||||
import { createStore } from './datatable-store';
|
||||
|
@ -40,7 +41,7 @@ export function ServicesDatatable() {
|
|||
const filteredServices = servicesQuery.data?.filter(
|
||||
(service) =>
|
||||
(isAdmin && tableState.showSystemResources) ||
|
||||
!KubernetesNamespaceHelper.isSystemNamespace(service.Namespace)
|
||||
!isSystemNamespace(service.Namespace)
|
||||
);
|
||||
|
||||
return (
|
||||
|
|
|
@ -1,38 +1,41 @@
|
|||
import { columnHelper } from './helper';
|
||||
|
||||
export const clusterIP = columnHelper.accessor('ClusterIPs', {
|
||||
header: 'Cluster IP',
|
||||
id: 'clusterIP',
|
||||
cell: ({ getValue }) => {
|
||||
const clusterIPs = getValue();
|
||||
export const clusterIP = columnHelper.accessor(
|
||||
(row) => row.ClusterIPs?.join(','),
|
||||
{
|
||||
header: 'Cluster IP',
|
||||
id: 'clusterIP',
|
||||
cell: ({ row }) => {
|
||||
const clusterIPs = row.original.ClusterIPs;
|
||||
|
||||
if (!clusterIPs?.length) {
|
||||
return '-';
|
||||
}
|
||||
return clusterIPs.map((ip) => <div key={ip}>{ip}</div>);
|
||||
},
|
||||
sortingFn: (rowA, rowB) => {
|
||||
const a = rowA.original.ClusterIPs;
|
||||
const b = rowB.original.ClusterIPs;
|
||||
|
||||
const ipA = a?.[0];
|
||||
const ipB = b?.[0];
|
||||
|
||||
// no ip's at top, followed by 'None', then ordered by ip
|
||||
if (!ipA) return 1;
|
||||
if (!ipB) return -1;
|
||||
if (ipA === ipB) return 0;
|
||||
if (ipA === 'None') return 1;
|
||||
if (ipB === 'None') return -1;
|
||||
|
||||
// natural sort of the ip
|
||||
return ipA.localeCompare(
|
||||
ipB,
|
||||
navigator.languages[0] || navigator.language,
|
||||
{
|
||||
numeric: true,
|
||||
ignorePunctuation: true,
|
||||
if (!clusterIPs?.length) {
|
||||
return '-';
|
||||
}
|
||||
);
|
||||
},
|
||||
});
|
||||
return clusterIPs.map((ip) => <div key={ip}>{ip}</div>);
|
||||
},
|
||||
sortingFn: (rowA, rowB) => {
|
||||
const a = rowA.original.ClusterIPs;
|
||||
const b = rowB.original.ClusterIPs;
|
||||
|
||||
const ipA = a?.[0];
|
||||
const ipB = b?.[0];
|
||||
|
||||
// no ip's at top, followed by 'None', then ordered by ip
|
||||
if (!ipA) return 1;
|
||||
if (!ipB) return -1;
|
||||
if (ipA === ipB) return 0;
|
||||
if (ipA === 'None') return 1;
|
||||
if (ipB === 'None') return -1;
|
||||
|
||||
// natural sort of the ip
|
||||
return ipA.localeCompare(
|
||||
ipB,
|
||||
navigator.languages[0] || navigator.language,
|
||||
{
|
||||
numeric: true,
|
||||
ignorePunctuation: true,
|
||||
}
|
||||
);
|
||||
},
|
||||
}
|
||||
);
|
||||
|
|
|
@ -2,19 +2,22 @@ import { formatDate } from '@/portainer/filters/filters';
|
|||
|
||||
import { columnHelper } from './helper';
|
||||
|
||||
export const created = columnHelper.accessor('CreationTimestamp', {
|
||||
header: 'Created',
|
||||
id: 'created',
|
||||
cell: ({ row, getValue }) => {
|
||||
const date = formatDate(getValue());
|
||||
|
||||
const owner =
|
||||
row.original.Labels?.['io.portainer.kubernetes.application.owner'];
|
||||
|
||||
if (owner) {
|
||||
return `${date} by ${owner}`;
|
||||
}
|
||||
|
||||
return date;
|
||||
export const created = columnHelper.accessor(
|
||||
(row) => {
|
||||
const owner = row.Labels?.['io.portainer.kubernetes.application.owner'];
|
||||
const date = formatDate(row.CreationTimestamp);
|
||||
return owner ? `${date} by ${owner}` : date;
|
||||
},
|
||||
});
|
||||
{
|
||||
header: 'Created',
|
||||
id: 'created',
|
||||
cell: ({ row }) => {
|
||||
const date = formatDate(row.original.CreationTimestamp);
|
||||
|
||||
const owner =
|
||||
row.original.Labels?.['io.portainer.kubernetes.application.owner'];
|
||||
|
||||
return owner ? `${date} by ${owner}` : date;
|
||||
},
|
||||
}
|
||||
);
|
||||
|
|
|
@ -8,14 +8,14 @@ import { columnHelper } from './helper';
|
|||
export const externalIP = columnHelper.accessor(
|
||||
(row) => {
|
||||
if (row.Type === 'ExternalName') {
|
||||
return row.ExternalName;
|
||||
return row.ExternalName || '';
|
||||
}
|
||||
|
||||
if (row.ExternalIPs?.length) {
|
||||
return row.ExternalIPs?.slice(0);
|
||||
return row.ExternalIPs?.join(',') || '';
|
||||
}
|
||||
|
||||
return row.IngressStatus?.slice(0);
|
||||
return row.IngressStatus?.map((status) => status.IP).join(',') || '';
|
||||
},
|
||||
{
|
||||
header: 'External IP',
|
||||
|
|
|
@ -1,37 +1,53 @@
|
|||
import { Authorized } from '@/react/hooks/useUser';
|
||||
import KubernetesNamespaceHelper from '@/kubernetes/helpers/namespaceHelper';
|
||||
import { isSystemNamespace } from '@/react/kubernetes/namespaces/utils';
|
||||
|
||||
import { columnHelper } from './helper';
|
||||
|
||||
export const name = columnHelper.accessor('Name', {
|
||||
header: 'Name',
|
||||
id: 'name',
|
||||
cell: ({ row, getValue }) => {
|
||||
const name = getValue();
|
||||
const isSystem = KubernetesNamespaceHelper.isSystemNamespace(
|
||||
row.original.Namespace
|
||||
);
|
||||
export const name = columnHelper.accessor(
|
||||
(row) => {
|
||||
let name = row.Name;
|
||||
|
||||
const isExternal =
|
||||
!row.original.Labels ||
|
||||
!row.original.Labels['io.portainer.kubernetes.application.owner'];
|
||||
!row.Labels || !row.Labels['io.portainer.kubernetes.application.owner'];
|
||||
const isSystem = isSystemNamespace(row.Namespace);
|
||||
|
||||
return (
|
||||
<Authorized authorizations="K8sServiceW" childrenUnauthorized={name}>
|
||||
{name}
|
||||
if (isExternal && !isSystem) {
|
||||
name = `${name} external`;
|
||||
}
|
||||
|
||||
{isSystem && (
|
||||
<span className="label label-info image-tag label-margins">
|
||||
system
|
||||
</span>
|
||||
)}
|
||||
|
||||
{isExternal && !isSystem && (
|
||||
<span className="label label-primary image-tag label-margins">
|
||||
external
|
||||
</span>
|
||||
)}
|
||||
</Authorized>
|
||||
);
|
||||
if (isSystem) {
|
||||
name = `${name} system`;
|
||||
}
|
||||
return name;
|
||||
},
|
||||
});
|
||||
{
|
||||
header: 'Name',
|
||||
id: 'Name',
|
||||
cell: ({ row }) => {
|
||||
const name = row.original.Name;
|
||||
const isSystem = isSystemNamespace(row.original.Namespace);
|
||||
|
||||
const isExternal =
|
||||
!row.original.Labels ||
|
||||
!row.original.Labels['io.portainer.kubernetes.application.owner'];
|
||||
|
||||
return (
|
||||
<Authorized authorizations="K8sServiceW" childrenUnauthorized={name}>
|
||||
{name}
|
||||
|
||||
{isSystem && (
|
||||
<span className="label label-info image-tag label-margins">
|
||||
system
|
||||
</span>
|
||||
)}
|
||||
|
||||
{isExternal && !isSystem && (
|
||||
<span className="label label-primary image-tag label-margins">
|
||||
external
|
||||
</span>
|
||||
)}
|
||||
</Authorized>
|
||||
);
|
||||
},
|
||||
}
|
||||
);
|
||||
|
|
|
@ -4,7 +4,12 @@ import { columnHelper } from './helper';
|
|||
|
||||
export const ports = columnHelper.accessor(
|
||||
(row) =>
|
||||
row.Ports.map((port) => `${port.Port}:${port.NodePort}/${port.Protocol}`),
|
||||
row.Ports.map(
|
||||
(port) =>
|
||||
`${port.Port}${port.NodePort !== 0 ? `:${port.NodePort}` : ''}/${
|
||||
port.Protocol
|
||||
}`
|
||||
).join(',') || '-',
|
||||
{
|
||||
header: () => (
|
||||
<>
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
import { columnHelper } from './helper';
|
||||
|
||||
export const targetPorts = columnHelper.accessor(
|
||||
(row) => row.Ports.map((port) => `${port.TargetPort}`),
|
||||
(row) => row.Ports.map((port) => port.TargetPort).join(','),
|
||||
{
|
||||
header: 'Target Ports',
|
||||
id: 'targetPorts',
|
||||
cell: ({ getValue }) => {
|
||||
const ports = getValue();
|
||||
|
||||
cell: ({ row }) => {
|
||||
const ports = row.original.Ports.map((port) => port.TargetPort);
|
||||
if (!ports.length) {
|
||||
return '-';
|
||||
}
|
||||
|
|
|
@ -2,18 +2,21 @@ import { formatDate } from '@/portainer/filters/filters';
|
|||
|
||||
import { columnHelper } from './helper';
|
||||
|
||||
export const created = columnHelper.accessor('CreationDate', {
|
||||
header: 'Created',
|
||||
cell: ({ row, getValue }) => {
|
||||
const date = formatDate(getValue());
|
||||
const owner =
|
||||
row.original.Labels?.['io.portainer.kubernetes.ingress.owner'];
|
||||
|
||||
if (owner) {
|
||||
return `${date} by ${owner}`;
|
||||
}
|
||||
|
||||
return date;
|
||||
export const created = columnHelper.accessor(
|
||||
(row) => {
|
||||
const owner = row.Labels?.['io.portainer.kubernetes.ingress.owner'];
|
||||
const date = formatDate(row.CreationDate);
|
||||
return owner ? `${date} by ${owner}` : date;
|
||||
},
|
||||
id: 'created',
|
||||
});
|
||||
{
|
||||
header: 'Created',
|
||||
cell: ({ row, getValue }) => {
|
||||
const date = formatDate(getValue());
|
||||
const owner =
|
||||
row.original.Labels?.['io.portainer.kubernetes.ingress.owner'];
|
||||
|
||||
return owner ? `${date} by ${owner}` : date;
|
||||
},
|
||||
id: 'created',
|
||||
}
|
||||
);
|
||||
|
|
|
@ -4,18 +4,28 @@ import { AlertTriangle, ArrowRight } from 'lucide-react';
|
|||
import { Icon } from '@@/Icon';
|
||||
import { Badge } from '@@/Badge';
|
||||
|
||||
import { Ingress, TLS, Path } from '../../types';
|
||||
import { Ingress, TLS } from '../../types';
|
||||
|
||||
import { columnHelper } from './helper';
|
||||
|
||||
export const ingressRules = columnHelper.accessor('Paths', {
|
||||
header: 'Rules and Paths',
|
||||
id: 'ingressRules',
|
||||
cell: Cell,
|
||||
});
|
||||
export const ingressRules = columnHelper.accessor(
|
||||
({ Paths, TLS }) =>
|
||||
// return an accessor function with all the useful text to search for
|
||||
Paths.map((path) => {
|
||||
const isHttp = isHTTP(TLS || [], path.Host);
|
||||
return `${isHttp ? 'http' : 'https'}://${path.Host}${path.Path}${
|
||||
path.ServiceName
|
||||
}:${path.Port} ${!path.HasService && "Service doesn't exist"}`;
|
||||
}).join(','),
|
||||
{
|
||||
header: 'Rules and Paths',
|
||||
id: 'ingressRules',
|
||||
cell: Cell,
|
||||
}
|
||||
);
|
||||
|
||||
function Cell({ row, getValue }: CellContext<Ingress, Path[] | undefined>) {
|
||||
const paths = getValue();
|
||||
function Cell({ row }: CellContext<Ingress, string>) {
|
||||
const paths = row.original.Paths;
|
||||
|
||||
if (!paths) {
|
||||
return <div />;
|
||||
|
|
Loading…
Reference in New Issue