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:

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; }