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
Ali 2023-05-11 12:55:15 +12:00 committed by GitHub
parent 22f4c5d650
commit 42fce1ec57
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 148 additions and 108 deletions

View File

@ -21,6 +21,7 @@ import { useTableState } from '@@/datatables/useTableState';
import { useMutationDeleteServices, useServices } from '../service'; import { useMutationDeleteServices, useServices } from '../service';
import { Service } from '../types'; import { Service } from '../types';
import { DefaultDatatableSettings } from '../../datatables/DefaultDatatableSettings'; import { DefaultDatatableSettings } from '../../datatables/DefaultDatatableSettings';
import { isSystemNamespace } from '../../namespaces/utils';
import { columns } from './columns'; import { columns } from './columns';
import { createStore } from './datatable-store'; import { createStore } from './datatable-store';
@ -40,7 +41,7 @@ export function ServicesDatatable() {
const filteredServices = servicesQuery.data?.filter( const filteredServices = servicesQuery.data?.filter(
(service) => (service) =>
(isAdmin && tableState.showSystemResources) || (isAdmin && tableState.showSystemResources) ||
!KubernetesNamespaceHelper.isSystemNamespace(service.Namespace) !isSystemNamespace(service.Namespace)
); );
return ( return (

View File

@ -1,38 +1,41 @@
import { columnHelper } from './helper'; import { columnHelper } from './helper';
export const clusterIP = columnHelper.accessor('ClusterIPs', { export const clusterIP = columnHelper.accessor(
header: 'Cluster IP', (row) => row.ClusterIPs?.join(','),
id: 'clusterIP', {
cell: ({ getValue }) => { header: 'Cluster IP',
const clusterIPs = getValue(); id: 'clusterIP',
cell: ({ row }) => {
const clusterIPs = row.original.ClusterIPs;
if (!clusterIPs?.length) { if (!clusterIPs?.length) {
return '-'; 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,
} }
); 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,
}
);
},
}
);

View File

@ -2,19 +2,22 @@ import { formatDate } from '@/portainer/filters/filters';
import { columnHelper } from './helper'; import { columnHelper } from './helper';
export const created = columnHelper.accessor('CreationTimestamp', { export const created = columnHelper.accessor(
header: 'Created', (row) => {
id: 'created', const owner = row.Labels?.['io.portainer.kubernetes.application.owner'];
cell: ({ row, getValue }) => { const date = formatDate(row.CreationTimestamp);
const date = formatDate(getValue()); return owner ? `${date} by ${owner}` : date;
const owner =
row.original.Labels?.['io.portainer.kubernetes.application.owner'];
if (owner) {
return `${date} by ${owner}`;
}
return 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;
},
}
);

View File

@ -8,14 +8,14 @@ import { columnHelper } from './helper';
export const externalIP = columnHelper.accessor( export const externalIP = columnHelper.accessor(
(row) => { (row) => {
if (row.Type === 'ExternalName') { if (row.Type === 'ExternalName') {
return row.ExternalName; return row.ExternalName || '';
} }
if (row.ExternalIPs?.length) { 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', header: 'External IP',

View File

@ -1,37 +1,53 @@
import { Authorized } from '@/react/hooks/useUser'; import { Authorized } from '@/react/hooks/useUser';
import KubernetesNamespaceHelper from '@/kubernetes/helpers/namespaceHelper'; import { isSystemNamespace } from '@/react/kubernetes/namespaces/utils';
import { columnHelper } from './helper'; import { columnHelper } from './helper';
export const name = columnHelper.accessor('Name', { export const name = columnHelper.accessor(
header: 'Name', (row) => {
id: 'name', let name = row.Name;
cell: ({ row, getValue }) => {
const name = getValue();
const isSystem = KubernetesNamespaceHelper.isSystemNamespace(
row.original.Namespace
);
const isExternal = const isExternal =
!row.original.Labels || !row.Labels || !row.Labels['io.portainer.kubernetes.application.owner'];
!row.original.Labels['io.portainer.kubernetes.application.owner']; const isSystem = isSystemNamespace(row.Namespace);
return ( if (isExternal && !isSystem) {
<Authorized authorizations="K8sServiceW" childrenUnauthorized={name}> name = `${name} external`;
{name} }
{isSystem && ( if (isSystem) {
<span className="label label-info image-tag label-margins"> name = `${name} system`;
system }
</span> return name;
)}
{isExternal && !isSystem && (
<span className="label label-primary image-tag label-margins">
external
</span>
)}
</Authorized>
);
}, },
}); {
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>
);
},
}
);

View File

@ -4,7 +4,12 @@ import { columnHelper } from './helper';
export const ports = columnHelper.accessor( export const ports = columnHelper.accessor(
(row) => (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: () => ( header: () => (
<> <>

View File

@ -1,13 +1,12 @@
import { columnHelper } from './helper'; import { columnHelper } from './helper';
export const targetPorts = columnHelper.accessor( export const targetPorts = columnHelper.accessor(
(row) => row.Ports.map((port) => `${port.TargetPort}`), (row) => row.Ports.map((port) => port.TargetPort).join(','),
{ {
header: 'Target Ports', header: 'Target Ports',
id: 'targetPorts', id: 'targetPorts',
cell: ({ getValue }) => { cell: ({ row }) => {
const ports = getValue(); const ports = row.original.Ports.map((port) => port.TargetPort);
if (!ports.length) { if (!ports.length) {
return '-'; return '-';
} }

View File

@ -2,18 +2,21 @@ import { formatDate } from '@/portainer/filters/filters';
import { columnHelper } from './helper'; import { columnHelper } from './helper';
export const created = columnHelper.accessor('CreationDate', { export const created = columnHelper.accessor(
header: 'Created', (row) => {
cell: ({ row, getValue }) => { const owner = row.Labels?.['io.portainer.kubernetes.ingress.owner'];
const date = formatDate(getValue()); const date = formatDate(row.CreationDate);
const owner = return owner ? `${date} by ${owner}` : date;
row.original.Labels?.['io.portainer.kubernetes.ingress.owner'];
if (owner) {
return `${date} by ${owner}`;
}
return 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',
}
);

View File

@ -4,18 +4,28 @@ import { AlertTriangle, ArrowRight } from 'lucide-react';
import { Icon } from '@@/Icon'; import { Icon } from '@@/Icon';
import { Badge } from '@@/Badge'; import { Badge } from '@@/Badge';
import { Ingress, TLS, Path } from '../../types'; import { Ingress, TLS } from '../../types';
import { columnHelper } from './helper'; import { columnHelper } from './helper';
export const ingressRules = columnHelper.accessor('Paths', { export const ingressRules = columnHelper.accessor(
header: 'Rules and Paths', ({ Paths, TLS }) =>
id: 'ingressRules', // return an accessor function with all the useful text to search for
cell: Cell, 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>) { function Cell({ row }: CellContext<Ingress, string>) {
const paths = getValue(); const paths = row.original.Paths;
if (!paths) { if (!paths) {
return <div />; return <div />;