import Route from '@/assets/ico/route.svg?c';
import { confirm } from '@@/modals/confirm';
import { ModalType } from '@@/modals';
import { Datatable } from '@@/datatables';
import { Button, ButtonGroup } from '@@/buttons';
import { createPersistedStore } from '@@/datatables/types';
import { buildConfirmButton } from '@@/modals/utils';
import { useTableState } from '@@/datatables/useTableState';
import { TextTip } from '@@/Tip/TextTip';
import { IngressControllerClassMap } from '../types';
import { columns } from './columns';
const storageKey = 'ingressClasses';
const settingsStore = createPersistedStore(storageKey, 'name');
interface Props {
onChange: (controllerClassMap: IngressControllerClassMap[]) => void; // angular function to save the ingress class list
description: string;
values: IngressControllerClassMap[] | undefined;
initialValues: IngressControllerClassMap[] | undefined;
isLoading: boolean;
noIngressControllerLabel: string;
view: 'namespace' | 'cluster';
}
export function IngressClassDatatable({
onChange,
description,
initialValues,
values,
isLoading,
noIngressControllerLabel,
view,
}: Props) {
const tableState = useTableState(settingsStore, storageKey);
return (
`${row.Name}-${row.ClassName}-${row.Type}`}
renderTableActions={(selectedRows) => renderTableActions(selectedRows)}
description={renderIngressClassDescription()}
data-cy="ingress-class-datatable"
/>
);
function renderTableActions(selectedRows: IngressControllerClassMap[]) {
return (
);
}
function renderIngressClassDescription() {
return (
{!isLoading && values && values.length === 0 && (
{noIngressControllerLabel}
)}
{description}
{initialValues &&
values &&
isUnsavedChanges(initialValues, values) && (
Unsaved changes.
)}
);
}
async function updateIngressControllers(
selectedRows: IngressControllerClassMap[],
values: IngressControllerClassMap[],
availability: boolean
) {
const updatedIngressControllers = getUpdatedIngressControllers(
selectedRows,
values || [],
availability
);
if (values && values.length) {
const newAllowed = updatedIngressControllers.map(
(ingController) => ingController.Availability
);
if (view === 'namespace') {
onChange(updatedIngressControllers);
return;
}
const usedControllersToDisallow = values.filter(
(ingController, index) => {
// if any of the current controllers are allowed, and are used, then become disallowed, then add the controller to a new list
if (
ingController.Availability &&
ingController.Used &&
!newAllowed[index]
) {
return true;
}
return false;
}
);
if (usedControllersToDisallow.length > 0) {
const confirmed = await confirm({
title: 'Disallow in-use ingress controllers?',
modalType: ModalType.Warn,
message: (
There are ingress controllers you want to disallow that are in
use:
{usedControllersToDisallow.map((controller) => (
- {controller.ClassName}
))}
No new ingress rules can be created for the disallowed
controllers.
),
confirmButton: buildConfirmButton('Disallow', 'warning'),
});
if (!confirmed) {
return;
}
}
onChange(updatedIngressControllers);
}
}
}
function isUnsavedChanges(
oldIngressControllers: IngressControllerClassMap[],
newIngressControllers: IngressControllerClassMap[]
) {
if (oldIngressControllers.length !== newIngressControllers.length) {
return true;
}
for (let i = 0; i < newIngressControllers.length; i += 1) {
if (
oldIngressControllers[i]?.Availability !==
newIngressControllers[i]?.Availability
) {
return true;
}
}
return false;
}
function getUpdatedIngressControllers(
selectedRows: IngressControllerClassMap[],
allRows: IngressControllerClassMap[],
allow: boolean
) {
const selectedRowClassNames = selectedRows.map((row) => row.ClassName);
const updatedIngressControllers = allRows?.map((row) => {
if (selectedRowClassNames.includes(row.ClassName)) {
return { ...row, Availability: allow };
}
return row;
});
return updatedIngressControllers;
}