import { useCallback, useEffect, useMemo, useState } from 'react'; import { Link, useSearchParams } from 'react-router'; import { Background, Controls, MiniMap, Panel, ReactFlow, addEdge, useEdgesState, useNodesState, } from '@xyflow/react'; import '@xyflow/react/dist/style.css'; import { Button, Card, Col, Container, Form, Modal, Row, Spinner } from 'react-bootstrap'; import Select from 'react-select'; import PageBreadcrumb from '@/components/PageBreadcrumb'; import { isSuccess, signedGet, signedPost } from '@/api/client'; import { dropdownMap } from '@/api/dropdowns'; import { defaultConfig, fromFlow, labelFor, toFlow, NODE_TYPES, edgeLabel, contactMappings } from '@/views/workflow/graph'; function newId() { return crypto.randomUUID(); } const MANAGER_LEVELS = [ { value: 'l1manager', label: 'L1 Manager' }, { value: 'l2manager', label: 'L2 Manager' }, { value: 'l3manager', label: 'L3 Manager' }, { value: 'l4manager', label: 'L4 Manager' }, ]; function approverGroups(roles, users) { return [ { label: 'Manager', options: MANAGER_LEVELS }, { label: 'Roles', options: Object.entries(roles).map(([value, label]) => ({ value, label })) }, { label: 'Users', options: Object.entries(users).map(([value, label]) => ({ value, label })) }, ]; } function ApproverSelect({ values, groups, onChange }) { const known = groups.flatMap((group) => group.options || []); const saved = (values || []).filter((value) => !known.some((option) => option.value === value)).map((value) => ({ value, label: value })); const options = saved.length ? groups.concat({ label: 'Saved', options: saved }) : groups; const byValue = new Map(known.concat(saved).map((option) => [option.value, option])); return (