import { useState } from 'react'; import { confirmWarn } from '@/portainer/services/modal.service/confirm'; import { Datatable } from '@@/datatables'; import { Button, ButtonGroup } from '@@/buttons'; import { Icon } from '@@/Icon'; import { IngressControllerClassMap } from '../types'; import { useColumns } from './columns'; import { createStore } from './datatable-store'; const useStore = createStore('ingressClasses'); interface Props { onChangeAvailability: ( controllerClassMap: IngressControllerClassMap[] ) => void; // angular function to save the ingress class list description: string; ingressControllers: IngressControllerClassMap[] | undefined; isLoading: boolean; noIngressControllerLabel: string; view: string; } export function IngressClassDatatable({ onChangeAvailability, description, ingressControllers, isLoading, noIngressControllerLabel, view, }: Props) { const [ingControllerFormValues, setIngControllerFormValues] = useState(ingressControllers); const settings = useStore(); const columns = useColumns(); return (
`${row.Name}-${row.ClassName}-${row.Type}`} renderTableActions={(selectedRows) => renderTableActions(selectedRows)} description={renderIngressClassDescription()} />
); function renderTableActions(selectedRows: IngressControllerClassMap[]) { return (
); } function renderIngressClassDescription() { return (
{description}
{ingressControllers && ingControllerFormValues && isUnsavedChanges(ingressControllers, ingControllerFormValues) && ( Unsaved changes. )}
); } function updateIngressControllers( selectedRows: IngressControllerClassMap[], ingControllerFormValues: IngressControllerClassMap[], availability: boolean ) { const updatedIngressControllers = getUpdatedIngressControllers( selectedRows, ingControllerFormValues || [], availability ); if (ingressControllers && ingressControllers.length) { const newAllowed = updatedIngressControllers.map( (ingController) => ingController.Availability ); if (view === 'namespace') { setIngControllerFormValues(updatedIngressControllers); onChangeAvailability(updatedIngressControllers); return; } const usedControllersToDisallow = ingressControllers.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 usedControllerHtmlListItems = usedControllersToDisallow.map( (controller) => `
  • ${controller.ClassName}
  • ` ); const usedControllerHtmlList = ``; confirmWarn({ title: 'Disallow in-use ingress controllers?', message: `

    There are ingress controllers you want to disallow that are in use:

    ${usedControllerHtmlList}

    No new ingress rules can be created for the disallowed controllers.

    `, buttons: { cancel: { label: 'Cancel', className: 'btn-default', }, confirm: { label: 'Disallow', className: 'btn-warning', }, }, callback: (confirmed) => { if (confirmed) { setIngControllerFormValues(updatedIngressControllers); onChangeAvailability(updatedIngressControllers); } }, }); return; } setIngControllerFormValues(updatedIngressControllers); onChangeAvailability(updatedIngressControllers); } } } function isUnsavedChanges( oldIngressControllers: IngressControllerClassMap[], newIngressControllers: IngressControllerClassMap[] ) { for (let i = 0; i < oldIngressControllers.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; }