@realtek/core-theme 0.0.183 → 0.0.184

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Breadcrumb-C_ybG8rI.js","names":[],"sources":["../src/theme/colors/colors.js","../src/components/typography/Typography.jsx","../src/components/TipTapEditor.jsx","../src/components/DocumentViewer.jsx","../src/utils/modulePath.js","../src/services/moduleDataApi.js","../src/services/addFormApi.js","../src/services/adminApi.js","../src/services/detailedViewApi.js","../src/services/detailDefaults.js","../src/utils/roleFormPermissionGate.js","../src/components/form/inputSecurity.js","../src/components/form/payloadTransformer.js","../src/components/form/linkedAddRowGroups.js","../src/services/aiActionApi.js","../src/components/detail/renderConfig.js","../src/components/form/applyGroupValues.js","../src/components/form/useAiActions.js","../src/components/form/AiActionButtons.jsx","../src/components/form/emailValidator.js","../src/components/form/inputValidator.js","../src/components/form/uploadAccept.js","../src/components/form/QuickCreateEditField.jsx","../src/utils/roleAllowsAction.js","../src/utils/afterSubmitNav.js","../src/utils/submitMessages.js","../src/utils/scrollToFirstFormError.js","../src/components/form/conditionalFieldLabel.js","../src/components/Breadcrumb.jsx"],"sourcesContent":["export const colors = {\n brand: '#0053a5',\n brandDark: '#1d4ed8',\n brandDarker: '#1e40af',\n brandHover: '#004f85',\n brandSoft: '#dfedf7',\n brandSofter: '#e7f2fa',\n brandSubtle: '#edf8fe',\n\n textPrimary: '#111827',\n textSecondary: '#4b5563',\n textMuted: '#6b7280',\n textSubtle: '#010306',\n textHeading: '#142235',\n textDark: '#232a31',\n textPlaceholder: '#a7b0bb',\n textInverse: '#ffffff',\n textLink: '#0053a5',\n\n surfacePage: '#f5f6fa',\n surfaceSoft: '#f8fafc',\n surfaceSofter: '#f3f8fb',\n surfaceCard: '#ffffff',\n surfaceHover: '#eff6ff',\n surfaceHoverLight: '#f8fcff',\n surfaceHoverSoft: '#f5fbff',\n surfaceSelected: '#dbeafe',\n surfaceControl: '#f4f8fb',\n surfaceRowAlt: '#fbfdff',\n\n border: '#e6f0ff',\n borderLight: '#eef3f8',\n borderSofter: '#f0f0f0',\n borderMuted: '#d8e4ef',\n borderInput: '#d5dde5',\n borderFocus: '#7dbce6',\n borderHover: '#99c7e8',\n controlBorder: '#77abd0',\n controlBorderMuted: '#e7edf3',\n controlAccent: '#4f9ac7',\n\n iconMuted: '#d1d5db',\n iconSubtle: '#9aa6b2',\n iconNeutral: '#8c8c8c',\n iconSoft: '#bbbbbb',\n scrollbarThumb: '#c4ccd8',\n scrollbarThumbLight: '#d1d5db',\n danger: '#dc2626',\n dangerSoft: '#ef4444',\n dangerStrong: '#e11d24',\n success: '#15803d',\n successSoft: '#16a34a',\n warning: '#f97316',\n info: '#3b82f6',\n transparent: 'transparent',\n\n statusNeutralBg: '#f1f3ee',\n statusNeutralText: '#717b36',\n statusProcessingBg: '#f6f4f7',\n statusProcessingText: '#273048',\n statusProcessingBorder: '#d4d8dd',\n statusWarningBg: '#fff7ea',\n statusWarningText: '#bf7328',\n\n shadowMenu: 'rgba(15, 35, 55, 0.08)',\n shadowBadge: 'rgba(26, 95, 145, 0.08)',\n shadowTag: 'rgba(39, 51, 70, 0.05)',\n shadowAvatar: 'rgba(57, 77, 103, 0.12)',\n shadowDropdown: '0 6px 16px 0 rgba(0, 0, 0, .08), 0 3px 6px -4px rgba(0, 0, 0, .12), 0 9px 28px 8px rgba(0, 0, 0, .05)',\n avatarBlueBg: '#eaf3ff',\n avatarBlueText: '#142235',\n avatarPurpleBg: '#f2eaff',\n avatarMoreBg: '#eef6ff',\n avatarMoreText: '#0053a5',\n\n avatarNeutralBg: '#d9d9d9',\n avatarNeutralText: '#555555',\n avatarIndigo: '#6366f1',\n avatarPurple: '#8b5cf6',\n avatarBlue: '#3b82f6',\n avatarGreen: '#10b981',\n linkedIn: '#0077b5',\n};\n\nexport const typographyColors = {\n primary: colors.textPrimary,\n secondary: colors.textSecondary,\n muted: colors.textMuted,\n subtle: colors.textSubtle,\n inverse: colors.textInverse,\n link: colors.textLink,\n danger: colors.danger,\n success: colors.success,\n};\n\nexport const onboardingStageToneColors = {\n approved: {\n background: '#f2f2e8',\n text: '#79772d',\n },\n danger: {\n background: '#fde7e9',\n text: colors.danger,\n },\n issued: {\n background: '#e9f2fb',\n text: colors.textLink,\n },\n neutral: {\n background: colors.surfaceSoft,\n text: colors.textSecondary,\n },\n success: {\n background: '#e7f5ee',\n text: colors.success,\n },\n warning: {\n background: '#fbf0e7',\n text: colors.warning,\n },\n};\n\nexport const colorVars = {\n brand: 'var(--color-brand)',\n brandDark: 'var(--color-brand-dark)',\n brandDarker: 'var(--color-brand-darker)',\n brandHover: 'var(--color-brand-hover)',\n brandSoft: 'var(--color-brand-soft)',\n brandSofter: 'var(--color-brand-softer)',\n brandSubtle: 'var(--color-brand-subtle)',\n\n textPrimary: 'var(--color-text-primary)',\n textSecondary: 'var(--color-text-secondary)',\n textMuted: 'var(--color-text-muted)',\n textSubtle: 'var(--color-text-subtle)',\n textHeading: 'var(--color-text-heading)',\n textDark: 'var(--color-text-dark)',\n textPlaceholder: 'var(--color-text-placeholder)',\n textInverse: 'var(--color-text-inverse)',\n textLink: 'var(--color-text-link)',\n\n surfacePage: 'var(--color-surface-page)',\n surfaceSoft: 'var(--color-surface-soft)',\n surfaceSofter: 'var(--color-surface-softer)',\n surfaceCard: 'var(--color-surface-card)',\n surfaceHover: 'var(--color-surface-hover)',\n surfaceHoverLight: 'var(--color-surface-hover-light)',\n surfaceHoverSoft: 'var(--color-surface-hover-soft)',\n surfaceSelected: 'var(--color-surface-selected)',\n surfaceControl: 'var(--color-surface-control)',\n surfaceRowAlt: 'var(--color-surface-row-alt)',\n\n border: 'var(--color-border)',\n borderLight: 'var(--color-border-light)',\n borderSofter: 'var(--color-border-softer)',\n borderMuted: 'var(--color-border-muted)',\n borderInput: 'var(--color-border-input)',\n borderFocus: 'var(--color-border-focus)',\n borderHover: 'var(--color-border-hover)',\n controlBorder: 'var(--color-control-border)',\n controlBorderMuted: 'var(--color-control-border-muted)',\n controlAccent: 'var(--color-control-accent)',\n\n iconMuted: 'var(--color-icon-muted)',\n iconSubtle: 'var(--color-icon-subtle)',\n iconNeutral: 'var(--color-icon-neutral)',\n iconSoft: 'var(--color-icon-soft)',\n scrollbarThumb: 'var(--color-scrollbar-thumb)',\n scrollbarThumbLight: 'var(--color-scrollbar-thumb-light)',\n danger: 'var(--color-danger)',\n dangerSoft: 'var(--color-danger-soft)',\n dangerStrong: 'var(--color-danger-strong)',\n success: 'var(--color-success)',\n successSoft: 'var(--color-success-soft)',\n warning: 'var(--color-warning)',\n info: 'var(--color-info)',\n transparent: 'var(--color-transparent)',\n linkedIn: 'var(--color-linkedin)',\n\n statusNeutralBg: 'var(--color-status-neutral-bg)',\n statusNeutralText: 'var(--color-status-neutral-text)',\n statusProcessingBg: 'var(--color-status-processing-bg)',\n statusProcessingText: 'var(--color-status-processing-text)',\n statusProcessingBorder: 'var(--color-status-processing-border)',\n statusWarningBg: 'var(--color-status-warning-bg)',\n statusWarningText: 'var(--color-status-warning-text)',\n\n shadowMenu: 'var(--color-shadow-menu)',\n shadowBadge: 'var(--color-shadow-badge)',\n shadowTag: 'var(--color-shadow-tag)',\n shadowAvatar: 'var(--color-shadow-avatar)',\n shadowDropdown: 'var(--color-shadow-dropdown)',\n avatarBlueBg: 'var(--color-avatar-blue-bg)',\n avatarBlueText: 'var(--color-avatar-blue-text)',\n avatarPurpleBg: 'var(--color-avatar-purple-bg)',\n avatarMoreBg: 'var(--color-avatar-more-bg)',\n avatarMoreText: 'var(--color-avatar-more-text)',\n};\n","import { Typography } from 'antd';\nimport { colorVars } from '../../theme/colors/colors';\n\nconst { Text, Title, Paragraph, Link } = Typography;\n\nconst defaultElementByVariant = {\n display: 'h1',\n h1: 'h1',\n h2: 'h2',\n h3: 'h3',\n h4: 'h4',\n h5: 'h5',\n 'section-title': 'h3',\n 'card-title': 'h4',\n subtitle: 'span',\n body: 'span',\n 'body-strong': 'span',\n label: 'span',\n caption: 'span',\n meta: 'span',\n metric: 'span',\n helper: 'span',\n link: 'a',\n};\n\nconst namedSizes = {\n xs: 'var(--font-size-xs)',\n sm: 'var(--font-size-sm)',\n md: 'var(--font-size-md)',\n lg: 'var(--font-size-lg)',\n xl: 'var(--font-size-xl)',\n '2xl': 'var(--font-size-2xl)',\n '3xl': 'var(--font-size-3xl)',\n '4xl': 'var(--font-size-4xl)',\n};\n\nconst namedWeights = {\n regular: 'var(--font-weight-regular)',\n medium: 'var(--font-weight-medium)',\n semibold: 'var(--font-weight-semibold)',\n bold: 'var(--font-weight-bold)',\n extrabold: 'var(--font-weight-extrabold)',\n};\n\nconst namedLineHeights = {\n tight: 'var(--line-height-tight)',\n snug: 'var(--line-height-snug)',\n normal: 'var(--line-height-normal)',\n relaxed: 'var(--line-height-relaxed)',\n};\n\nconst namedColors = {\n primary: colorVars.textPrimary,\n secondary: colorVars.textSecondary,\n muted: colorVars.textMuted,\n subtle: colorVars.textSubtle,\n inverse: colorVars.textInverse,\n link: colorVars.textLink,\n danger: colorVars.danger,\n success: colorVars.success,\n};\n\nfunction cx(...classes) {\n return classes.filter(Boolean).join(' ');\n}\n\nfunction tokenValue(value, tokens) {\n if (value === undefined || value === null) return undefined;\n return tokens[value] || value;\n}\n\nfunction getAntTypographyComponent(tag, variant) {\n if (variant === 'link' || tag === 'a') return Link;\n if (tag === 'p') return Paragraph;\n if (['h1', 'h2', 'h3', 'h4', 'h5'].includes(tag)) return Title;\n return Text;\n}\n\nfunction getTitleLevel(tag, variant) {\n const resolvedTag = tag || defaultElementByVariant[variant];\n if (!resolvedTag?.startsWith('h')) return undefined;\n return Number(resolvedTag.slice(1));\n}\n\nexport default function AppTypography({\n as,\n tag,\n variant = 'body',\n color,\n size,\n weight,\n lineHeight,\n align,\n truncate = false,\n display,\n className,\n style,\n children,\n ...props\n}) {\n const resolvedTag = tag || as || defaultElementByVariant[variant] || 'span';\n const Component = getAntTypographyComponent(resolvedTag, variant);\n const titleLevel = getTitleLevel(resolvedTag, variant);\n const dynamicStyle = {\n color: tokenValue(color, namedColors),\n fontSize: tokenValue(size, namedSizes),\n fontWeight: tokenValue(weight, namedWeights),\n lineHeight: tokenValue(lineHeight, namedLineHeights),\n display,\n ...style,\n };\n\n return (\n <Component\n {...(titleLevel ? { level: titleLevel } : {})}\n className={cx(\n 'app-typography',\n `app-typography--${variant}`,\n color && namedColors[color] && `app-typography--${color}`,\n align && `app-typography--${align}`,\n truncate && 'app-typography--truncate',\n className,\n )}\n style={dynamicStyle}\n {...props}\n >\n {children}\n </Component>\n );\n}\n","/**\n * TipTapEditor — Rich text editor component\n * Drop-in replacement for ReactQuill in EditFormV1\n *\n * Props:\n * value string — HTML string (controlled)\n * onChange function — called with HTML string on every change\n * disabled boolean — makes editor read-only\n * placeholder string — placeholder text\n */\n\nimport { useEffect, useRef } from 'react';\nimport { useEditor, EditorContent } from '@tiptap/react';\nimport StarterKit from '@tiptap/starter-kit';\nimport Link from '@tiptap/extension-link';\nimport Underline from '@tiptap/extension-underline';\nimport '../styles/TipTapEditor.css';\n\n// ─── Toolbar button ───────────────────────────────────────────────────────────\n\nfunction ToolbarButton({ onClick, active, disabled, title, children }) {\n return (\n <button\n type=\"button\"\n title={title}\n disabled={disabled}\n className={`tte-btn${active ? ' tte-btn--active' : ''}`}\n onMouseDown={(e) => {\n e.preventDefault(); // prevent editor losing focus\n onClick?.();\n }}\n >\n {children}\n </button>\n );\n}\n\n// ─── Toolbar ─────────────────────────────────────────────────────────────────\n\nfunction Toolbar({ editor, disabled }) {\n if (!editor) return null;\n\n const setLink = () => {\n const url = window.prompt('Enter URL');\n if (!url) {\n editor.chain().focus().unsetLink().run();\n return;\n }\n editor.chain().focus().setLink({ href: url }).run();\n };\n\n return (\n <div className={`tte-toolbar${disabled ? ' tte-toolbar--disabled' : ''}`}>\n <div className=\"tte-toolbar-group\">\n <ToolbarButton\n title=\"Bold\"\n disabled={disabled}\n active={editor.isActive('bold')}\n onClick={() => editor.chain().focus().toggleBold().run()}\n >\n <strong>B</strong>\n </ToolbarButton>\n\n <ToolbarButton\n title=\"Italic\"\n disabled={disabled}\n active={editor.isActive('italic')}\n onClick={() => editor.chain().focus().toggleItalic().run()}\n >\n <em>I</em>\n </ToolbarButton>\n\n <ToolbarButton\n title=\"Underline\"\n disabled={disabled}\n active={editor.isActive('underline')}\n onClick={() => editor.chain().focus().toggleUnderline().run()}\n >\n <span style={{ textDecoration: 'underline' }}>U</span>\n </ToolbarButton>\n\n <ToolbarButton\n title=\"Strikethrough\"\n disabled={disabled}\n active={editor.isActive('strike')}\n onClick={() => editor.chain().focus().toggleStrike().run()}\n >\n <s>S</s>\n </ToolbarButton>\n </div>\n\n <div className=\"tte-toolbar-divider\" />\n\n <div className=\"tte-toolbar-group\">\n <ToolbarButton\n title=\"Bullet List\"\n disabled={disabled}\n active={editor.isActive('bulletList')}\n onClick={() => editor.chain().focus().toggleBulletList().run()}\n >\n ≡\n </ToolbarButton>\n\n <ToolbarButton\n title=\"Ordered List\"\n disabled={disabled}\n active={editor.isActive('orderedList')}\n onClick={() => editor.chain().focus().toggleOrderedList().run()}\n >\n 1.\n </ToolbarButton>\n </div>\n\n <div className=\"tte-toolbar-divider\" />\n\n <div className=\"tte-toolbar-group\">\n <ToolbarButton\n title=\"Link\"\n disabled={disabled}\n active={editor.isActive('link')}\n onClick={setLink}\n >\n 🔗\n </ToolbarButton>\n </div>\n\n <div className=\"tte-toolbar-divider\" />\n\n <div className=\"tte-toolbar-group\">\n <ToolbarButton\n title=\"Clear formatting\"\n disabled={disabled}\n onClick={() => editor.chain().focus().clearNodes().unsetAllMarks().run()}\n >\n ✕\n </ToolbarButton>\n </div>\n </div>\n );\n}\n\n// ─── Main editor ──────────────────────────────────────────────────────────────\n\nexport default function TipTapEditor({\n value = '',\n onChange,\n disabled = false,\n placeholder = '',\n}) {\n // Tracks the last value this editor itself produced (via onUpdate) or was\n // last told to show (via the sync effect below) — NOT the editor's live\n // getHTML(), which can drift from `value` after a round-trip through\n // TipTap's HTML serializer (e.g. plain AI-generated text with no <p> tags\n // never equals its own wrapped-in-<p> serialization, which previously made\n // the old getHTML()-based comparison useless as a \"did this come from us\"\n // check and caused an external update to fight with a stale echo).\n const lastKnownValueRef = useRef(value ?? '');\n\n const editor = useEditor({\n extensions: [\n StarterKit,\n Underline,\n Link.configure({\n openOnClick: false,\n HTMLAttributes: { rel: 'noopener noreferrer' },\n }),\n ],\n content: value, // set initial content correctly on mount\n editable: !disabled,\n editorProps: {\n attributes: {\n class: 'tte-content',\n },\n },\n onUpdate: ({ editor }) => {\n const html = editor.getHTML();\n const next = html === '<p></p>' ? '' : html;\n lastKnownValueRef.current = next;\n onChange?.(next);\n },\n });\n\n // Sync value from outside — handles setFieldsValue from Ant Design form\n // (e.g. an AI Action replacing the content). Skips only when the incoming\n // value is exactly what this editor itself last emitted, so a genuine\n // external update always applies even if it differs from getHTML() purely\n // due to HTML serialization (missing <p> wrapper, entity encoding, etc).\n useEffect(() => {\n if (!editor || editor.isDestroyed) return;\n const nextValue = value || '';\n if (nextValue === (lastKnownValueRef.current || '')) return;\n lastKnownValueRef.current = nextValue;\n editor.commands.setContent(nextValue, false);\n }, [value, editor]);\n\n // Sync disabled state\n useEffect(() => {\n if (!editor) return;\n editor.setEditable(!disabled);\n }, [disabled, editor]);\n\n return (\n <div className={`tte-wrapper${disabled ? ' tte-wrapper--disabled' : ''}`}>\n <Toolbar editor={editor} disabled={disabled} />\n <EditorContent editor={editor} />\n {!value && !editor?.isFocused && placeholder && (\n <div className=\"tte-placeholder\">{placeholder}</div>\n )}\n </div>\n );\n}\n","import { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport PropTypes from 'prop-types';\nimport { Modal, Spin, Tooltip, message } from 'antd';\nimport {\n CloseOutlined,\n DownloadOutlined,\n FileUnknownOutlined,\n LeftOutlined,\n RightOutlined,\n ZoomInOutlined,\n ZoomOutOutlined,\n} from '@ant-design/icons';\nimport { Document, Page, pdfjs } from 'react-pdf';\nimport { renderAsync } from 'docx-preview';\nimport DOMPurify from 'dompurify';\nimport 'react-pdf/dist/Page/AnnotationLayer.css';\nimport 'react-pdf/dist/Page/TextLayer.css';\nimport '../styles/DocumentViewer.css';\n\n// pdf.js needs a web worker; Vite resolves this URL at build time so it works\n// in dev and production without copying files into /public.\npdfjs.GlobalWorkerOptions.workerSrc = new URL(\n 'pdfjs-dist/build/pdf.worker.min.mjs',\n import.meta.url,\n).toString();\n\nconst IMAGE_EXT = ['png', 'jpg', 'jpeg', 'gif', 'webp', 'bmp', 'svg', 'avif', 'ico'];\nconst TEXT_EXT = ['txt', 'csv', 'log', 'json', 'md', 'xml'];\nconst VIDEO_EXT = ['mp4', 'webm', 'ogg', 'ogv', 'mov', 'm4v'];\nconst ZOOM_STEP = 0.2;\nconst ZOOM_MIN = 0.4;\nconst ZOOM_MAX = 3;\n\nfunction fileNameFromUrl(url) {\n if (!url) return 'Document';\n const clean = String(url).split('?')[0].split('#')[0];\n return decodeURIComponent(clean.split('/').pop() || clean) || 'Document';\n}\n\nfunction extOf(nameOrUrl) {\n const clean = String(nameOrUrl || '').split('?')[0].split('#')[0];\n const dot = clean.lastIndexOf('.');\n return dot === -1 ? '' : clean.slice(dot + 1).toLowerCase();\n}\n\nconst KNOWN_BUCKETS = ['pdf', 'docx', 'image', 'text', 'video', 'html'];\n\n// bucketFromExt maps a bare extension (no dot) to a renderer bucket, or null.\nfunction bucketFromExt(ext) {\n if (!ext) return null;\n if (ext === 'pdf') return 'pdf';\n if (ext === 'doc' || ext === 'docx') return 'docx';\n if (IMAGE_EXT.includes(ext)) return 'image';\n if (TEXT_EXT.includes(ext)) return 'text';\n if (VIDEO_EXT.includes(ext)) return 'video';\n return null;\n}\n\n// kindOf maps a document to a renderer bucket: pdf | docx | image | text |\n// video | html | unknown.\n//\n// `doc.type` is normalized rather than trusted verbatim, because it arrives\n// in different shapes depending on the caller: an already-correct bucket\n// name (\"image\", inline html), a bare file extension as the backend upload\n// handler stores it (\"jpg\", \"png\", \"pdf\" — see timesheetController.go's\n// `ext := strings.ToLower(strings.TrimPrefix(filepath.Ext(...), \".\"))`), or a\n// MIME type (\"image/jpeg\"). Returning a bare extension straight through only\n// happened to work for \"pdf\"/\"docx\" because those extensions equal their own\n// bucket name — every image extension (\"jpg\", \"png\", …) doesn't equal\n// \"image\", so it silently fell through to the \"no preview available\"\n// fallback. This maps all three shapes through the same extension table.\nfunction kindOf(doc) {\n const rawType = String(doc.type || '').toLowerCase().trim();\n if (KNOWN_BUCKETS.includes(rawType)) return rawType;\n\n const mimeExt = rawType.includes('/') ? rawType.split('/').pop() : rawType;\n const fromType = bucketFromExt(mimeExt);\n if (fromType) return fromType;\n\n const fromName = bucketFromExt(extOf(doc.name || doc.url));\n if (fromName) return fromName;\n\n return 'unknown';\n}\n\n// normalizeDocs accepts either bare URL strings, file objects, or inline\n// document objects ({ name, type: 'text'|'html', content }).\nfunction normalizeDocs(documents) {\n return (documents || [])\n .map((d, i) => {\n if (typeof d === 'string') {\n return { url: d, name: fileNameFromUrl(d), key: String(i) };\n }\n const url = d.url || d.location || d.path || '';\n return {\n url,\n name: d.name || fileNameFromUrl(url),\n type: d.type,\n content: typeof d.content === 'string' ? d.content : '',\n key: String(d.id ?? d._id ?? i),\n };\n })\n .filter((d) => d.url || d.content);\n}\n\n/* ------------------------------- renderers ------------------------------- */\n\nfunction PdfRenderer({ url, scale, onNativeFallback }) {\n const wrapRef = useRef(null);\n const [numPages, setNumPages] = useState(0);\n const [width, setWidth] = useState(0);\n const [error, setError] = useState(false);\n\n useEffect(() => {\n const el = wrapRef.current;\n if (!el) return undefined;\n const update = () => setWidth(el.clientWidth);\n update();\n const ro = new ResizeObserver(update);\n ro.observe(el);\n return () => ro.disconnect();\n }, []);\n\n // pdf.js streams the file via its own fetch, which commonly fails on\n // presigned storage URLs without matching CORS/range-request support —\n // distinct from a plain navigation (an <iframe> load), which the browser's\n // own built-in PDF viewer can still render. Fall back to that rather than\n // dead-ending the preview; the native viewer brings its own zoom/controls,\n // so the toolbar hides its (now inert) zoom buttons via onNativeFallback.\n if (error) {\n return <iframe title=\"PDF preview\" src={url} className=\"dv-pdf-native\" />;\n }\n\n return (\n <div ref={wrapRef} className=\"dv-pdf-wrap\">\n <Document\n file={url}\n loading={<Spin />}\n error={<FallbackStage label=\"This PDF could not be displayed.\" />}\n onLoadSuccess={({ numPages: n }) => setNumPages(n)}\n onLoadError={() => {\n setError(true);\n onNativeFallback?.();\n }}\n >\n {Array.from({ length: numPages }, (_, i) => (\n <Page\n key={`page-${i + 1}`}\n pageNumber={i + 1}\n width={width ? width * scale : undefined}\n className=\"dv-pdf-page\"\n renderTextLayer\n renderAnnotationLayer\n />\n ))}\n </Document>\n </div>\n );\n}\n\nPdfRenderer.propTypes = {\n url: PropTypes.string.isRequired,\n scale: PropTypes.number.isRequired,\n onNativeFallback: PropTypes.func,\n};\n\nfunction DocxRenderer({ url }) {\n const ref = useRef(null);\n const [status, setStatus] = useState('loading'); // loading | ready | error\n\n useEffect(() => {\n let cancelled = false;\n\n fetch(url)\n .then((r) => {\n if (!r.ok) throw new Error(`HTTP ${r.status}`);\n return r.blob();\n })\n .then((blob) => {\n if (cancelled || !ref.current) return undefined;\n ref.current.innerHTML = '';\n return renderAsync(blob, ref.current, undefined, {\n className: 'dv-docx',\n inWrapper: true,\n ignoreWidth: false,\n ignoreHeight: false,\n });\n })\n .then(() => {\n if (!cancelled) setStatus('ready');\n })\n .catch(() => {\n if (!cancelled) setStatus('error');\n });\n\n return () => {\n cancelled = true;\n };\n }, [url]);\n\n if (status === 'error') {\n return <FallbackStage label=\"This document could not be displayed.\" />;\n }\n\n return (\n <div className=\"dv-docx-scroll\">\n {status === 'loading' && <div className=\"dv-center\"><Spin /></div>}\n <div ref={ref} style={{ visibility: status === 'ready' ? 'visible' : 'hidden' }} />\n </div>\n );\n}\n\nDocxRenderer.propTypes = { url: PropTypes.string.isRequired };\n\nfunction TextRenderer({ url, content = '' }) {\n const [text, setText] = useState(null);\n const [status, setStatus] = useState('loading');\n\n useEffect(() => {\n if (content) return undefined;\n\n let cancelled = false;\n fetch(url)\n .then((r) => {\n if (!r.ok) throw new Error(`HTTP ${r.status}`);\n return r.text();\n })\n .then((t) => {\n if (!cancelled) {\n setText(t);\n setStatus('ready');\n }\n })\n .catch(() => !cancelled && setStatus('error'));\n return () => {\n cancelled = true;\n };\n }, [content, url]);\n\n if (content) return <pre className=\"dv-text\">{content}</pre>;\n if (status === 'loading') return <div className=\"dv-center\"><Spin /></div>;\n if (status === 'error') return <FallbackStage label=\"This file could not be displayed.\" />;\n return <pre className=\"dv-text\">{text}</pre>;\n}\n\nTextRenderer.propTypes = {\n url: PropTypes.string,\n content: PropTypes.string,\n};\n\nfunction HtmlRenderer({ content }) {\n const safeHtml = useMemo(() => DOMPurify.sanitize(content), [content]);\n return <div className=\"dv-html\" dangerouslySetInnerHTML={{ __html: safeHtml }} />;\n}\n\nHtmlRenderer.propTypes = { content: PropTypes.string.isRequired };\n\nfunction ImageRenderer({ url, name, scale }) {\n const [error, setError] = useState(false);\n if (error) return <FallbackStage label=\"This image could not be displayed.\" />;\n return (\n <div className=\"dv-image-wrap\">\n <img\n className=\"dv-image\"\n src={url}\n alt={name}\n style={{ transform: `scale(${scale})` }}\n onError={() => setError(true)}\n />\n </div>\n );\n}\n\nImageRenderer.propTypes = {\n url: PropTypes.string.isRequired,\n name: PropTypes.string.isRequired,\n scale: PropTypes.number.isRequired,\n};\n\nfunction VideoRenderer({ url, name }) {\n const [error, setError] = useState(false);\n if (error) return <FallbackStage label=\"This video could not be played.\" />;\n return (\n <div className=\"dv-video-wrap\">\n <video\n className=\"dv-video\"\n src={url}\n title={name}\n controls\n preload=\"metadata\"\n controlsList=\"nodownload\"\n onError={() => setError(true)}\n />\n </div>\n );\n}\n\nVideoRenderer.propTypes = {\n url: PropTypes.string.isRequired,\n name: PropTypes.string.isRequired,\n};\n\nfunction FallbackStage({ label }) {\n return (\n <div className=\"dv-center dv-fallback\">\n <FileUnknownOutlined className=\"dv-fallback-icon\" />\n <p>{label}</p>\n <span className=\"dv-fallback-hint\">Use the download button to open it.</span>\n </div>\n );\n}\n\nFallbackStage.propTypes = { label: PropTypes.string.isRequired };\n\n/* ----------------------------- main component ---------------------------- */\n\n// ViewerBody holds the per-session state (active index + zoom). It lives inside\n// the Modal body, which is destroyed on close (destroyOnHidden), so it remounts\n// fresh on every open — no manual \"reset on open\" effects required.\nfunction ViewerBody({ docs, initialIndex, onClose }) {\n const total = docs.length;\n const safeInitial = Math.min(Math.max(initialIndex, 0), Math.max(0, total - 1));\n const [index, setIndex] = useState(safeInitial);\n const [scale, setScale] = useState(1);\n // Set when a PDF falls back to the browser's native viewer (see\n // PdfRenderer) — that viewer has its own zoom UI, so ours would sit there\n // doing nothing if left visible.\n const [pdfNativeFallback, setPdfNativeFallback] = useState(false);\n\n const current = docs[index];\n const kind = current ? kindOf(current) : 'unknown';\n const zoomable = (kind === 'pdf' && !pdfNativeFallback) || kind === 'image';\n\n // setActive changes the document and resets zoom/fallback in one event\n // handler, so we never have to reset them from an effect.\n const setActive = useCallback((next) => {\n setIndex(next);\n setScale(1);\n setPdfNativeFallback(false);\n }, []);\n\n const goPrev = useCallback(() => setActive(Math.max(0, index - 1)), [index, setActive]);\n const goNext = useCallback(\n () => setActive(Math.min(total - 1, index + 1)),\n [index, total, setActive],\n );\n\n // Keyboard navigation.\n useEffect(() => {\n const onKey = (e) => {\n // A focused <video> uses arrow keys to seek — don't switch documents.\n if (e.target?.tagName === 'VIDEO') return;\n if (e.key === 'ArrowLeft') goPrev();\n else if (e.key === 'ArrowRight') goNext();\n };\n window.addEventListener('keydown', onKey);\n return () => window.removeEventListener('keydown', onKey);\n }, [goPrev, goNext]);\n\n const download = useCallback(async (doc) => {\n if (!doc) return;\n try {\n let blob;\n if (doc.content) {\n const mimeType = doc.type === 'html' ? 'text/html;charset=utf-8' : 'text/plain;charset=utf-8';\n blob = new Blob([doc.content], { type: mimeType });\n } else {\n const res = await fetch(doc.url);\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n blob = await res.blob();\n }\n const objUrl = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = objUrl;\n a.download = doc.name || 'document';\n document.body.appendChild(a);\n a.click();\n a.remove();\n URL.revokeObjectURL(objUrl);\n } catch {\n // Cross-origin without CORS: fall back to opening in a new tab.\n message.info('Opening file in a new tab…');\n if (doc.url) window.open(doc.url, '_blank', 'noopener,noreferrer');\n }\n }, []);\n\n function renderStage() {\n if (!current) {\n return <FallbackStage label=\"No document to preview.\" />;\n }\n switch (kind) {\n case 'pdf':\n return (\n <PdfRenderer\n key={current.key}\n url={current.url}\n scale={scale}\n onNativeFallback={() => setPdfNativeFallback(true)}\n />\n );\n case 'docx':\n return <DocxRenderer key={current.key} url={current.url} />;\n case 'image':\n return (\n <ImageRenderer key={current.key} url={current.url} name={current.name} scale={scale} />\n );\n case 'text':\n return <TextRenderer key={current.key} url={current.url} content={current.content} />;\n case 'html':\n return <HtmlRenderer key={current.key} content={current.content} />;\n case 'video':\n return <VideoRenderer key={current.key} url={current.url} name={current.name} />;\n default:\n return <FallbackStage label=\"Preview is not available for this file type.\" />;\n }\n }\n\n return (\n <div className=\"dv-root\">\n {/* toolbar */}\n <div className=\"dv-toolbar\">\n <div className=\"dv-title\" title={current?.name}>\n <span className=\"dv-title-text\">{current?.name || 'Document'}</span>\n {total > 1 && <span className=\"dv-counter\">{index + 1} / {total}</span>}\n </div>\n <div className=\"dv-actions\">\n {zoomable && (\n <>\n <Tooltip title=\"Zoom out\">\n <button\n type=\"button\"\n className=\"dv-icon-btn\"\n onClick={() => setScale((s) => Math.max(ZOOM_MIN, +(s - ZOOM_STEP).toFixed(2)))}\n disabled={scale <= ZOOM_MIN}\n >\n <ZoomOutOutlined />\n </button>\n </Tooltip>\n <span className=\"dv-zoom-label\">{Math.round(scale * 100)}%</span>\n <Tooltip title=\"Zoom in\">\n <button\n type=\"button\"\n className=\"dv-icon-btn\"\n onClick={() => setScale((s) => Math.min(ZOOM_MAX, +(s + ZOOM_STEP).toFixed(2)))}\n disabled={scale >= ZOOM_MAX}\n >\n <ZoomInOutlined />\n </button>\n </Tooltip>\n <span className=\"dv-divider\" />\n </>\n )}\n <Tooltip title=\"Download\">\n <button type=\"button\" className=\"dv-icon-btn dv-download\" onClick={() => download(current)}>\n <DownloadOutlined />\n </button>\n </Tooltip>\n <Tooltip title=\"Close\">\n <button type=\"button\" className=\"dv-icon-btn\" onClick={onClose}>\n <CloseOutlined />\n </button>\n </Tooltip>\n </div>\n </div>\n\n {/* stage + slider arrows */}\n <div className=\"dv-stage\">\n {total > 1 && (\n <button\n type=\"button\"\n className=\"dv-nav dv-nav--prev\"\n onClick={goPrev}\n disabled={index === 0}\n aria-label=\"Previous document\"\n >\n <LeftOutlined />\n </button>\n )}\n\n <div className=\"dv-canvas\">{renderStage()}</div>\n\n {total > 1 && (\n <button\n type=\"button\"\n className=\"dv-nav dv-nav--next\"\n onClick={goNext}\n disabled={index === total - 1}\n aria-label=\"Next document\"\n >\n <RightOutlined />\n </button>\n )}\n </div>\n\n {/* dots */}\n {total > 1 && (\n <div className=\"dv-dots\">\n {docs.map((d, i) => (\n <button\n key={d.key}\n type=\"button\"\n className={`dv-dot${i === index ? ' dv-dot--active' : ''}`}\n onClick={() => setActive(i)}\n aria-label={`Go to document ${i + 1}`}\n />\n ))}\n </div>\n )}\n </div>\n );\n}\n\nViewerBody.propTypes = {\n docs: PropTypes.arrayOf(PropTypes.object).isRequired,\n initialIndex: PropTypes.number.isRequired,\n onClose: PropTypes.func.isRequired,\n};\n\n// DocumentViewer is the public component: a Modal shell that mounts ViewerBody\n// only while open. `documents` may be URL strings or document objects.\n//\n// Pass `inline` to render ViewerBody directly with no Modal — used by the timesheet\n// manager review, which shows the uploaded screenshot side-by-side with the calendar\n// rather than in a popup. Everything ViewerBody already does (pdf/image/docx render,\n// zoom, download, multi-document navigation) comes along for free.\nexport default function DocumentViewer({ documents, open, onClose, initialIndex = 0, inline = false }) {\n const docs = useMemo(() => normalizeDocs(documents), [documents]);\n\n if (inline) {\n return (\n <div className=\"dv-root--inline\">\n <ViewerBody docs={docs} initialIndex={initialIndex} onClose={onClose ?? (() => {})} />\n </div>\n );\n }\n\n return (\n <Modal\n open={open}\n onCancel={onClose}\n footer={null}\n title={null}\n closable={false}\n centered\n width=\"min(1100px, 94vw)\"\n className=\"dv-modal\"\n styles={{ content: { padding: 0, overflow: 'hidden', borderRadius: 14 }, body: { padding: 0 } }}\n destroyOnHidden\n >\n <ViewerBody docs={docs} initialIndex={initialIndex} onClose={onClose} />\n </Modal>\n );\n}\n\nDocumentViewer.propTypes = {\n // URL strings, file objects, or inline objects ({ content, type: 'text'|'html' }).\n documents: PropTypes.arrayOf(\n PropTypes.oneOfType([PropTypes.string, PropTypes.object]),\n ).isRequired,\n // Required for the Modal shell; unused (and optional) when `inline` is set.\n open: PropTypes.bool,\n onClose: PropTypes.func,\n initialIndex: PropTypes.number,\n // Render the viewer body directly, with no Modal wrapper.\n inline: PropTypes.bool,\n};\n","// Dot-notation module names: \"job.client.company\" means \"fetch the `job`\n// module, then display the data found at `client.company` inside each record\".\n// Only the segment before the first dot is a real backend module — every API\n// call (module-data-list, field-config, permissions) must use it, while the\n// remaining segments are resolved client-side against each fetched record.\n\nexport function parseModulePath(moduleName) {\n const raw = String(moduleName ?? '').trim();\n if (!raw) return { baseModule: '', nestedPath: '' };\n\n const [baseModule, ...rest] = raw.split('.');\n return {\n baseModule: baseModule.trim(),\n nestedPath: rest.map((part) => part.trim()).filter(Boolean).join('.'),\n };\n}\n\nexport function getBaseModuleName(moduleName) {\n return parseModulePath(moduleName).baseModule;\n}\n\nexport function getValueAtPath(source, path) {\n return String(path ?? '')\n .split('.')\n .filter(Boolean)\n .reduce((value, key) => (value == null ? undefined : value[key]), source);\n}\n","import { fetchJsonWithAuth, apiGetWithAuth } from './authApi';\nimport { AUTH_URL, SUBMISSIONS_URL } from './apiConfig';\nimport { normalizeDiceSkills, resolveDiceProfileId } from './diceCandidateMapper';\nimport { getBaseModuleName } from '../utils/modulePath';\n\nconst TEST_FLOW_MODULE = 'test-flows';\nconst LMS_FLOW_MODULE = 'lms-flows';\n\nconst TEST_FLOW_FIELDS = [\n { value: 'module', label: 'Module', isVisible: true, type: 'text' },\n { value: 'flow', label: 'Flow', isVisible: true, type: 'text' },\n { value: 'step_order', label: 'Step Order', isVisible: true, type: 'number' },\n { value: 'keyword', label: 'Action', isVisible: true, type: 'text' },\n { value: 'description', label: 'Description', isVisible: true, type: 'text' },\n { value: 'target', label: 'Key', isVisible: true, type: 'text' },\n { value: 'tags', label: 'Tags', isVisible: true, type: 'text' },\n { value: 'value', label: 'Value', isVisible: true, type: 'text' },\n { value: 'expected', label: 'Expected', isVisible: true, type: 'text' },\n];\n\nconst LMS_FLOW_FIELDS = [\n { value: 'module', label: 'Module', isVisible: true, type: 'text' },\n { value: 'flow', label: 'Flow', isVisible: true, type: 'text' },\n { value: 'step_order', label: 'Step Order', isVisible: true, type: 'number' },\n { value: 'keyword', label: 'Action', isVisible: true, type: 'text' },\n { value: 'description', label: 'Description', isVisible: true, type: 'text' },\n { value: 'target', label: 'Key', isVisible: true, type: 'text' },\n { value: 'tags', label: 'Tags', isVisible: true, type: 'text' },\n { value: 'value', label: 'Value', isVisible: true, type: 'text' },\n { value: 'expected', label: 'Expected', isVisible: true, type: 'text' },\n];\n\nfunction normalizeCandidateSearchSource(value) {\n const values = (Array.isArray(value) ? value : [value])\n .flat()\n .map((item) => {\n if (item && typeof item === 'object') {\n return item.value ?? item.label ?? item.name ?? '';\n }\n return item;\n })\n .map((item) => String(item ?? '').trim().toLowerCase())\n .filter(Boolean);\n\n if (values.includes('dice')) return 'dice';\n if (values.includes('internal')) return 'internal';\n return values[0] || '';\n}\n\nfunction firstFiniteNumber(...values) {\n for (const value of values) {\n const number = Number(value);\n if (Number.isFinite(number)) return number;\n }\n\n return undefined;\n}\n\nfunction extractResponseTotal(response, payload, rows, scope = '') {\n const responseCount = response?.count;\n const payloadCount = payload?.count;\n const normalizedScope = String(scope ?? '').trim().toLowerCase();\n\n if (responseCount && typeof responseCount === 'object') {\n const total = firstFiniteNumber(\n normalizedScope ? responseCount[normalizedScope] : undefined,\n responseCount.total,\n responseCount.searchCount,\n responseCount.count,\n );\n if (total !== undefined) return total;\n }\n\n if (payloadCount && typeof payloadCount === 'object') {\n const total = firstFiniteNumber(\n normalizedScope ? payloadCount[normalizedScope] : undefined,\n payloadCount.total,\n payloadCount.searchCount,\n payloadCount.count,\n );\n if (total !== undefined) return total;\n }\n\n return firstFiniteNumber(\n response?.total,\n typeof responseCount !== 'object' ? responseCount : undefined,\n response?.totalCount,\n payload?.total,\n typeof payloadCount !== 'object' ? payloadCount : undefined,\n payload?.totalCount,\n rows.length,\n ) ?? 0;\n}\n\nfunction extractResponseCounts(response, payload) {\n const counts = {};\n [response?.count, payload?.count].forEach((count) => {\n if (!count || typeof count !== 'object') return;\n\n Object.entries(count).forEach(([key, value]) => {\n const number = Number(value);\n if (Number.isFinite(number)) counts[String(key).trim().toLowerCase()] = number;\n });\n });\n\n return counts;\n}\n\nexport async function getDropdownFields(module) {\n if (module === TEST_FLOW_MODULE) return TEST_FLOW_FIELDS;\n if (module === LMS_FLOW_MODULE) return LMS_FLOW_FIELDS;\n // Dot-notation names (\"job.client\") target nested data client-side; the\n // backend only knows the base module.\n const baseModule = getBaseModuleName(module);\n return apiGetWithAuth(SUBMISSIONS_URL, `/filter-dropdown-fields?module=${encodeURIComponent(baseModule)}`);\n}\n\nexport async function getFieldConfig(module) {\n if (module === TEST_FLOW_MODULE) return TEST_FLOW_FIELDS;\n if (module === LMS_FLOW_MODULE) return LMS_FLOW_FIELDS;\n return apiGetWithAuth(AUTH_URL, `/admin/field-config?module=${encodeURIComponent(getBaseModuleName(module))}`);\n}\n\nexport async function getDropdownValues(module, field, search = '', limit = 50, offset = 0, meta = {}) {\n const params = new URLSearchParams({\n module: getBaseModuleName(module), field, value: search,\n limit: String(limit), offset: String(offset),\n });\n if (meta.dataSource) params.set('dataSource', meta.dataSource);\n if (meta.masterName) params.set('masterName', meta.masterName);\n if (meta.groupName) params.set('groupName', meta.groupName);\n // The Auth gateway owns the admin form configuration and understands\n // dataSource/masterName. Keeping this generic lets every configured master,\n // module and lookup field work without module-specific UI code.\n return apiGetWithAuth(AUTH_URL, `/filter-dropdown-values?${params}`);\n}\n\nexport async function getModuleDataList(module, limit = 10, offset = 0, options = {}) {\n const { scope = '', sort = '', sortDir = '', filters = [] } = options;\n\n if (module === TEST_FLOW_MODULE) {\n const { getTestFlows } = await import('./testingApi');\n const data = await getTestFlows({ limit, offset });\n const rows = Array.isArray(data?.items) ? data.items : [];\n const total = Number(data?.total) || 0;\n return { items: rows, total, limit, offset, tabs: [{ key: 'all', title: 'Test Cases', count: total }] };\n }\n\n if (module === LMS_FLOW_MODULE) {\n const { getLmsFlows } = await import('./testingApi');\n const data = await getLmsFlows({ limit, offset });\n const rows = Array.isArray(data?.items) ? data.items : [];\n const total = Number(data?.total) || 0;\n return { items: rows, total, limit, offset, tabs: [{ key: 'all', title: 'LMS Cases', count: total }] };\n }\n\n // const params = new URLSearchParams({ module, limit: String(limit), offset: String(offset) });\n // if (scope) params.set('scope', scope);\n const params = new URLSearchParams({\n module: getBaseModuleName(module), limit: String(limit), offset: String(offset),\n });\n const normalizedScope = String(scope ?? '').trim();\n if (normalizedScope) params.set('scope', normalizedScope);\n if (sort) params.set('sort', sort);\n if (sortDir) params.set('sortDir', sortDir);\n if (Array.isArray(filters) && filters.some((item) => item?.field)) {\n params.set('filters', JSON.stringify(filters));\n }\n\n return fetchJsonWithAuth(AUTH_URL, `/module-data-list?${params.toString()}`);\n}\n\nexport async function searchModuleData(moduleName, searchParams = {}, pagination = {}, options = {}) {\n const { limit = 10, offset = 0 } = pagination;\n const { sort = '', sortDir = '', scope = '' } = options;\n const inferredScope = normalizeCandidateSearchSource(scope || searchParams.selectedSource);\n\n const query = new URLSearchParams();\n query.append('module', getBaseModuleName(moduleName));\n query.append('limit', String(limit));\n query.append('offset', String(offset));\n\n if (inferredScope) {\n query.set('scope', inferredScope);\n console.log('[searchModuleData] Adding scope to query:', inferredScope);\n }\n if (sort) query.set('sort', sort);\n if (sortDir) query.set('sortDir', sortDir);\n\n console.log('[searchModuleData] Final query string:', query.toString());\n\n Object.entries(searchParams).forEach(([key, value]) => {\n if (value === undefined || value === null || value === '') return;\n\n let normalizedValue = value;\n if (typeof value === 'object') {\n normalizedValue = value.value ?? value.label ?? value.name ?? String(value);\n } else {\n normalizedValue = String(value);\n }\n\n query.append(key, normalizedValue);\n });\n\n const response = await fetchJsonWithAuth(AUTH_URL, `/module-data-list?${query.toString()}`);\n // const response = await fetchJsonWithAuth(\"http://localhost:9009/v1\", `/module-data-list?${query.toString()}`);\n // response = { status, data: { actionRules, actions, columnActions, data: [...records] } }\n const payload = response?.data ?? response;\n const rows = Array.isArray(payload)\n ? payload\n : payload?.rows ?? payload?.records ?? payload?.items ?? payload?.list ?? payload?.data ?? [];\n\n const total = extractResponseTotal(response, payload, rows, inferredScope);\n const counts = extractResponseCounts(response, payload);\n if (inferredScope && counts[inferredScope] === undefined && Number.isFinite(total)) {\n counts[inferredScope] = total;\n }\n\n // Check if response contains Dice candidates and transform if needed\n const hasDiceCandidates = rows.some((record) => {\n const sourceFields = [\n record?.sourceType,\n record?.profileSource,\n record?.selectedSource,\n record?.customFields?.sourceType,\n record?.customFields?.profileSource,\n ].flat();\n return sourceFields.some(\n (value) => String(value ?? '').trim().toLowerCase() === 'dice',\n ) || Boolean(record?.customFields?.diceProfileData);\n });\n\n let normalizedRows = rows;\n if (hasDiceCandidates) {\n try {\n const { transformDiceResponseToInternalFormat } = await import('./diceCandidateMapper');\n const transformed = transformDiceResponseToInternalFormat(response, response);\n normalizedRows = transformed?.data?.data ?? rows;\n } catch (error) {\n console.error('[searchModuleData] Dice transformation failed:', error);\n normalizedRows = rows.map(normalizeCandidateSearchRow);\n }\n } else {\n normalizedRows = Array.isArray(rows) ? rows.map(normalizeCandidateSearchRow) : [];\n }\n\n return {\n rows: normalizedRows,\n total: Number(total) || 0,\n counts,\n tabs: response?.tabs ?? response?.tabList ?? payload?.tabs ?? payload?.tabList ?? [],\n fields: response?.fields ?? response?.fieldConfig ?? payload?.fields ?? payload?.fieldConfig ?? [],\n tabField: response?.tabField ?? payload?.tabField ?? '',\n actionRules: payload?.actionRules ?? [],\n actions: payload?.actions ?? [],\n columnActions: payload?.columnActions ?? [],\n };\n}\n\nfunction getNestedValue(record, path) {\n return String(path)\n .split('.')\n .reduce((value, key) => value?.[key], record);\n}\n\nfunction setNestedValue(record, path, value) {\n const keys = String(path).split('.').filter(Boolean);\n if (!keys.length) return record;\n\n const nextRecord = { ...record };\n let target = nextRecord;\n let source = record;\n\n keys.slice(0, -1).forEach((key) => {\n const currentValue = source?.[key];\n const nextValue = currentValue && typeof currentValue === 'object' && !Array.isArray(currentValue)\n ? { ...currentValue }\n : {};\n\n target[key] = nextValue;\n target = nextValue;\n source = currentValue;\n });\n\n target[keys[keys.length - 1]] = value;\n return nextRecord;\n}\n\nfunction normalizeCandidateSearchRow(row) {\n if (!row || typeof row !== 'object') return row;\n\n const skillPaths = [\n 'skills',\n 'technicalSkills',\n 'primarySkills',\n 'keySkills',\n 'customFields.diceProfileData.skills',\n ];\n\n let nextRow = row;\n let firstNormalizedSkills = null;\n\n skillPaths.forEach((path) => {\n const rawSkills = getNestedValue(nextRow, path);\n if (rawSkills === undefined || rawSkills === null) return;\n\n const mappedSkills = normalizeDiceSkills(rawSkills);\n if (mappedSkills.length === 0 && Array.isArray(rawSkills) && rawSkills.length > 0) return;\n\n firstNormalizedSkills = firstNormalizedSkills ?? mappedSkills;\n nextRow = setNestedValue(nextRow, path, mappedSkills);\n });\n\n if (firstNormalizedSkills && getNestedValue(nextRow, 'skills') === undefined) {\n nextRow = setNestedValue(nextRow, 'skills', firstNormalizedSkills);\n }\n\n const sourceFields = [\n nextRow?.sourceType,\n nextRow?.profileSource,\n nextRow?.selectedSource,\n nextRow?.customFields?.sourceType,\n nextRow?.customFields?.profileSource,\n ].flat();\n const isDiceCandidate = sourceFields.some(\n (value) => String(value ?? '').trim().toLowerCase() === 'dice',\n ) || Boolean(nextRow?.customFields?.diceProfileData);\n\n if (isDiceCandidate) {\n const diceProfileId = resolveDiceProfileId(nextRow);\n const candidateId = nextRow?.candidateId\n ?? nextRow?.customFields?.diceProfileData?.candidateId\n ?? '';\n\n nextRow = {\n ...nextRow,\n id: nextRow?.id ?? diceProfileId,\n diceId: diceProfileId,\n candidateId,\n };\n }\n\n return nextRow;\n}\n","import { ensureToken, fetchJsonWithAuth } from './authApi';\nimport { AUTH_URL, JOBS_URL } from './apiConfig';\n\n// ── Form Groups ───────────────────────────────────────────────────────────────\n\nfunction extractFormGroups(json) {\n const payload = json?.data ?? json;\n if (Array.isArray(payload)) return payload;\n if (Array.isArray(payload?.groups)) return payload.groups;\n if (Array.isArray(json?.groups)) return json.groups;\n return [];\n}\n\nexport async function getFormGroups({ module, id, action, clientId, region } = {}) {\n if (!module) throw new Error('module is required to fetch form groups');\n const token = await ensureToken();\n const params = new URLSearchParams({ module });\n if (id) params.set('id', id);\n if (action) params.set('action', action);\n if (clientId) params.set('clientId', clientId);\n if (region) params.set('region', region);\n const res = await fetch(`${AUTH_URL}/admin/form-groups?${params.toString()}`, {\n method: 'GET',\n headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${token}` },\n });\n if (!res.ok) throw new Error(`API ${res.status}: ${res.statusText}`);\n const json = await res.json();\n return extractFormGroups(json);\n}\n\nexport async function getCandidateFormGroups(options = {}) {\n return getFormGroups({ module: 'candidates', ...options });\n}\n\nexport async function getMentionUsers(search = '') {\n const { apiGetWithAuth } = await import('./authApi');\n const params = search ? `?search=${encodeURIComponent(search)}` : '';\n return apiGetWithAuth(JOBS_URL, `/users/any${params}`);\n}\n\n// ── Create Records ────────────────────────────────────────────────────────────\n// Routes through the Auth gateway which injects tenant context from JWT\n// and proxies to the correct downstream service based on module name.\n\nexport async function createModuleRecord(moduleName, formData) {\n // ensureToken (not getStoredToken) so a missing/expired session throws a\n // clear \"Authentication required\" error instead of silently sending the\n // request with no Authorization header (which the gateway rejects as 401).\n // NOTE: do NOT set Content-Type here — the browser must add the multipart\n // boundary itself. Only the Authorization header is set manually.\n const token = await ensureToken();\n\n const res = await fetch(\n `${AUTH_URL}/module/create?module=${encodeURIComponent(moduleName)}`,\n { method: 'POST', headers: { Authorization: `Bearer ${token}` }, body: formData },\n );\n\n const { logout } = await import('./authApi');\n if (res.status === 401) logout();\n\n const contentType = res.headers.get('content-type') || '';\n const data = contentType.includes('application/json') ? await res.json() : await res.text();\n\n if (!res.ok) {\n const error = new Error(data?.error || data?.message || `API ${res.status}: ${res.statusText}`);\n error.status = res.status;\n error.data = data;\n throw error;\n }\n\n return data;\n}\n","import { fetchJsonWithAuth } from './authApi';\nimport { AUTH_URL, SUBMISSIONS_URL } from './apiConfig';\n\nconst FIELD_CONFIG_PATH = '/admin/field-config';\n\nconst CUSTOMIZABLE_MODULES = [\n { key: 'clients', apiModule: 'clients' },\n { key: 'job', apiModule: 'jobs' },\n { key: 'candidate', apiModule: 'candidates' },\n { key: 'submissions', apiModule: 'submissions' },\n { key: 'onboarding', apiModule: 'onboarding' },\n { key: 'billing', apiModule: 'billing' },\n { key: 'payroll', apiModule: 'payroll' },\n];\n\n// ── Shared Utilities ──────────────────────────────────────────────────────────\n\nfunction firstArray(...values) {\n return values.find(Array.isArray) ?? [];\n}\n\nfunction firstValue(record, keys, fallback) {\n return keys.map((k) => record?.[k]).find((v) => v !== undefined && v !== null && v !== '') ?? fallback;\n}\n\nfunction normalizeTotal(payload, items) {\n return (\n payload?.total ?? payload?.totalCount ?? payload?.count ??\n payload?.recordsTotal ?? payload?.meta?.total ?? payload?.pagination?.total ?? items.length\n );\n}\n\nfunction normalizeModuleField(field, index) {\n const fieldName = firstValue(field, ['label', 'Label', 'fieldName', 'field_name', 'name', 'fieldLabel', 'value'], `Field ${index + 1}`);\n const fieldKey = firstValue(field, ['field', 'Field', 'fieldKey', 'field_key', 'key', 'value', 'fieldName', 'name'], fieldName);\n const showValue = firstValue(field, ['isVisible', 'is_visible', 'visible', 'show', 'is_show', 'isShow', 'enabled'], true);\n const mandatoryValue = firstValue(field, ['ismandatory', 'isMandatory', 'is_mandatory', 'mandatory', 'required', 'req'], false);\n const orderValue = firstValue(field, ['order', 'Order', 'sortOrder', 'position'], index);\n\n return {\n ...field,\n fieldKey,\n fieldName,\n type: firstValue(field, ['type', 'Type'], 'text'),\n isVisible: typeof showValue === 'string'\n ? !['false', '0', 'hide', 'hidden', 'no'].includes(showValue.toLowerCase())\n : Boolean(showValue),\n ismandatory: typeof mandatoryValue === 'string'\n ? ['true', '1', 'yes', 'required'].includes(mandatoryValue.toLowerCase())\n : Boolean(mandatoryValue),\n order: typeof orderValue === 'number' ? orderValue : index,\n isLink: Boolean(field.isLink),\n linkTemplate: field.linkTemplate ?? '',\n linkType: field.linkType ?? 'internal',\n linkTarget: field.linkTarget ?? '_self',\n action: field.action ?? 'navigate',\n secondaryField: field.secondaryField ?? '',\n secondaryLabel: field.secondaryLabel ?? '',\n secondaryFields: Array.isArray(field.secondaryFields) ? field.secondaryFields : [],\n secondarySeparator: field.secondarySeparator ?? '',\n lookup: field.lookup\n ? { ...field.lookup, projectFields: Array.isArray(field.lookup.projectFields) ? field.lookup.projectFields : [] }\n : null,\n derived: field.derived ?? null,\n computed: field.computed\n ? { ...field.computed, operands: Array.isArray(field.computed.operands) ? field.computed.operands : [] }\n : null,\n actionButtons: Array.isArray(field.actionButtons) ? field.actionButtons : [],\n renderType: field.renderType ?? '',\n renderConfig: field.renderConfig ?? null,\n valueStyles: Array.isArray(field.valueStyles) ? field.valueStyles : [],\n commonStyle: field.commonStyle ?? null,\n displayTemplate: field.displayTemplate ?? '',\n dataSource: field.dataSource ?? 'module',\n groupName: field.groupName ?? '',\n };\n}\n\nfunction normalizeCustomizableModule(module) {\n if (typeof module === 'string') {\n return { key: module, apiModule: module };\n }\n\n const key = firstValue(\n module,\n ['key', 'moduleKey', 'value', 'module', 'apiModule', 'name', 'modulename', 'menuName'],\n ''\n );\n if (!key) return null;\n\n return {\n key,\n apiModule: firstValue(\n module,\n ['apiModule', 'api_module', 'module', 'value', 'key', 'name', 'modulename', 'menuName'],\n key\n ),\n };\n}\n\nfunction normalizeCustomizableModules(modules = CUSTOMIZABLE_MODULES) {\n const source = Array.isArray(modules) && modules.length ? modules : CUSTOMIZABLE_MODULES;\n const seen = new Set();\n return source\n .map(normalizeCustomizableModule)\n .filter(Boolean)\n .filter((module) => {\n if (seen.has(module.key)) return false;\n seen.add(module.key);\n return true;\n });\n}\n\n// ── Modules ───────────────────────────────────────────────────────────────────\n\nconst MODULES_PATH = '/admin/modules';\n\nexport async function getModules() {\n const json = await fetchJsonWithAuth(AUTH_URL, MODULES_PATH);\n const payload = json?.data;\n if (Array.isArray(payload)) return payload;\n if (Array.isArray(json)) return json;\n return [];\n}\n\n// createModule/updateModule let Admin define workflow modules (e.g. \"Source\n// Candidates\") that extend an existing module via baseModule, inheriting its\n// forms/columns/tabs/filters/actions wherever the new module hasn't\n// configured its own — see the backend's ModuleLookupChain.\nexport async function createModule({ key, label, collectionName, baseModule = '', order = 0 }) {\n return fetchJsonWithAuth(AUTH_URL, MODULES_PATH, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ key, label, collectionName, baseModule, order }),\n });\n}\n\nexport async function updateModule(key, { label, collectionName, baseModule = '', order = 0, isActive = true }) {\n return fetchJsonWithAuth(AUTH_URL, `${MODULES_PATH}/${encodeURIComponent(key)}`, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ label, collectionName, baseModule, order, isActive }),\n });\n}\n\n// getModuleAutomations/saveModuleAutomations edit a module's Gateway +\n// Strategies — the Admin \"Automations\" screen. This is the config-driven\n// replacement for logic legacy services used to hardcode in Go (reference-id\n// generation, duplicate checks, cross-module field snapshots, reporting-chain\n// hierarchy expansion, board updates, notifications, cache invalidation).\n// Separate endpoint from updateModule() above, so saving automations can\n// never touch label/forms/columns, and vice versa.\nexport async function getModuleAutomations(key) {\n const json = await fetchJsonWithAuth(AUTH_URL, `${MODULES_PATH}/${encodeURIComponent(key)}/automations`);\n const data = json?.data ?? json ?? {};\n return { gateway: data.gateway ?? null, strategies: data.strategies ?? null };\n}\n\n// Platform metadata (workflows / resolvers / state-machines / applications) —\n// the event-driven behavior layer. kind ∈ 'workflows' | 'resolvers' |\n// 'state-machines' | 'applications'. Docs are keyed by their \"key\" field.\nexport async function listPlatformDocs(kind) {\n const json = await fetchJsonWithAuth(AUTH_URL, `/admin/platform/${kind}`);\n const data = json?.data ?? json;\n return Array.isArray(data) ? data : [];\n}\n\nexport async function savePlatformDoc(kind, doc) {\n return fetchJsonWithAuth(AUTH_URL, `/admin/platform/${kind}`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(doc),\n });\n}\n\nexport async function deletePlatformDoc(kind, key) {\n return fetchJsonWithAuth(AUTH_URL, `/admin/platform/${kind}/${encodeURIComponent(key)}`, {\n method: 'DELETE',\n });\n}\n\nexport async function saveModuleAutomations(key, { gateway, strategies }) {\n return fetchJsonWithAuth(AUTH_URL, `${MODULES_PATH}/${encodeURIComponent(key)}/automations`, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ gateway, strategies }),\n });\n}\n\n// getAvailableModules() is the single source of truth for \"which modules can\n// be picked in an Admin configuration screen\" (Form Groups, Detail Groups,\n// Row Actions, Module Action Rules, Templates, Role Configuration). It's\n// driven by the curated Menus list (an admin explicitly adds/removes/disables\n// entries there) rather than the `modules` collection, which is really the\n// CRUD/gateway registry and accumulates every module ever wired for storage\n// (including disabled/legacy ones no admin actively curates).\n//\n// Falls back to getModules() when Menus has nothing configured yet, so a\n// project that hasn't set up Menus keeps working exactly as before.\nexport async function getAvailableModules() {\n let menus = [];\n try {\n menus = await getMenuModules();\n } catch {\n menus = [];\n }\n const active = (Array.isArray(menus) ? menus : []).filter((m) => (\n m?.isDeleted !== true\n && String(m?.status ?? 'active').toLowerCase() !== 'inactive'\n && String(m?.status ?? 'active').toLowerCase() !== 'disabled'\n ));\n if (active.length > 0) return active;\n return getModules();\n}\n\n// ── Admin Form Groups ─────────────────────────────────────────────────────────\n\nconst FORM_GROUPS_PATH = '/admin/form-groups';\nconst CONFIG_DEFAULTS_PATH = '/admin/config-defaults';\n\nfunction formGroupScopeQuery(scope = {}) {\n const params = new URLSearchParams();\n if (scope.module) params.set('module', scope.module);\n if (scope.clientId) params.set('clientId', scope.clientId);\n if (scope.region) params.set('region', scope.region);\n const qs = params.toString();\n return qs ? `?${qs}` : '';\n}\n\nexport async function getAdminFormGroups(module = '', scope = {}) {\n const query = formGroupScopeQuery({ ...scope, module: module || scope.module || '' });\n const path = `${FORM_GROUPS_PATH}${query}`;\n const json = await fetchJsonWithAuth(AUTH_URL, path);\n const payload = json?.data;\n // Backend returns EITHER a flat array of groups, OR a wrapper object\n // { id, module, ..., groups: [...] }. Support both shapes.\n if (Array.isArray(payload)) return payload;\n if (payload && Array.isArray(payload.groups)) return payload.groups;\n if (Array.isArray(json)) return json;\n if (json && Array.isArray(json.groups)) return json.groups;\n return [];\n}\n\nexport async function getAdminClients({ offset = 0, limit = 100, sortBy = 'new', searchvalue = '' } = {}) {\n const params = new URLSearchParams({\n offset: String(offset),\n limit: String(limit),\n sortBy,\n searchvalue,\n });\n // Scope the list to the active tenant/business/businessUnit captured from the\n // login token (authApi stores these on login). The backend uses them when\n // present, otherwise falls back to the token claims — so the dropdown lists\n // the right clients for the selected project, same as the legacy flow.\n const tenantId = localStorage.getItem('tenantId') || '';\n const businessId = localStorage.getItem('businessId') || '';\n const businessUnitId = localStorage.getItem('businessUnitId') || '';\n if (tenantId) params.set('tenantId', tenantId);\n if (businessId) params.set('businessId', businessId);\n if (businessUnitId) params.set('businessUnitId', businessUnitId);\n const json = await fetchJsonWithAuth(AUTH_URL, `/client/view?${params.toString()}`);\n const data = json?.data ?? json;\n return data?.clients ?? data?.Clients ?? data?.items ?? [];\n}\n\nexport async function getModuleFields(module) {\n const json = await fetchJsonWithAuth(AUTH_URL, `/filter-dropdown-fields?module=${encodeURIComponent(module)}`);\n const fields = json?.data ?? json;\n return Array.isArray(fields) ? fields : [];\n}\n\nexport async function createAdminFormGroup(group, scope = {}) {\n return fetchJsonWithAuth(AUTH_URL, `${FORM_GROUPS_PATH}${formGroupScopeQuery(scope)}`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(group),\n });\n}\n\nexport async function updateAdminFormGroup(id, group, scope = {}) {\n return fetchJsonWithAuth(AUTH_URL, `${FORM_GROUPS_PATH}/${id}${formGroupScopeQuery(scope)}`, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(group),\n });\n}\n\nexport async function deleteAdminFormGroup(id) {\n return fetchJsonWithAuth(AUTH_URL, `${FORM_GROUPS_PATH}/${id}`, { method: 'DELETE' });\n}\n\nexport async function seedAdminFormGroups() {\n return fetchJsonWithAuth(AUTH_URL, `${FORM_GROUPS_PATH}/seed`, { method: 'POST' });\n}\n\nexport async function requestConfigOtp(scope, action) {\n return fetchJsonWithAuth(AUTH_URL, `${CONFIG_DEFAULTS_PATH}/request-otp`, {\n method: 'POST',\n body: JSON.stringify({ scope, action }),\n });\n}\n\nexport async function applyConfigDefault(scope, action, otp) {\n return fetchJsonWithAuth(AUTH_URL, `${CONFIG_DEFAULTS_PATH}/apply`, {\n method: 'POST',\n body: JSON.stringify({ scope, action, otp }),\n });\n}\n\n// ── Admin Detail-View Config ──────────────────────────────────────────────────\n// Per-module customization layered on top of the form groups, applied only by\n// the detail view (?view=detail). Shape: { module, fields:[…], merges:[…] }.\n\nconst DETAIL_CONFIG_PATH = '/admin/detail-config';\n\nexport async function getDetailConfig(module) {\n const json = await fetchJsonWithAuth(AUTH_URL, `${DETAIL_CONFIG_PATH}?module=${encodeURIComponent(module)}`);\n const data = json?.data ?? json ?? {};\n return {\n module: data.module ?? module,\n fields: Array.isArray(data.fields) ? data.fields : [],\n merges: Array.isArray(data.merges) ? data.merges : [],\n };\n}\n\nexport async function saveDetailConfig({ module, fields = [], merges = [] }) {\n return fetchJsonWithAuth(AUTH_URL, DETAIL_CONFIG_PATH, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ module, fields, merges }),\n });\n}\n\n// ── Detail-View Display Defaults ──────────────────────────────────────────────\n// Tenant-wide display settings (S3 base, date format, boolean/empty labels,\n// separator, document name order) — the configurable home of what used to be\n// hard-coded in fileUtils.js / FieldValue.jsx.\n\nconst DETAIL_DEFAULTS_PATH = '/admin/detail-defaults';\n\nexport async function getDetailDefaults() {\n const json = await fetchJsonWithAuth(AUTH_URL, DETAIL_DEFAULTS_PATH);\n return json?.data ?? json ?? {};\n}\n\nexport async function saveDetailDefaults(defaults) {\n return fetchJsonWithAuth(AUTH_URL, DETAIL_DEFAULTS_PATH, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(defaults),\n });\n}\n\n// ── AI Service registry (backends AI Actions can call) ─────────────────────\n\nconst AI_SERVICE_CONFIG_PATH = '/admin/ai-service-config';\n\nexport async function getAiServiceConfigs() {\n const json = await fetchJsonWithAuth(AUTH_URL, AI_SERVICE_CONFIG_PATH);\n return json?.data ?? json ?? [];\n}\n\nexport async function saveAiServiceConfig(config) {\n return fetchJsonWithAuth(AUTH_URL, AI_SERVICE_CONFIG_PATH, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(config),\n });\n}\n\nexport async function deleteAiServiceConfig(serviceKey) {\n return fetchJsonWithAuth(AUTH_URL, `${AI_SERVICE_CONFIG_PATH}?serviceKey=${encodeURIComponent(serviceKey)}`, {\n method: 'DELETE',\n });\n}\n\n// ── Background Check integration ───────────────────────────────────────────\n\nconst BGC_INTEGRATION_CONFIG_PATH = '/admin/bgc-integration-config';\n\nexport async function getBgcIntegrationConfig() {\n const json = await fetchJsonWithAuth(AUTH_URL, BGC_INTEGRATION_CONFIG_PATH);\n return json?.data ?? json ?? { updateMethod: 'MANUAL', enabled: true };\n}\n\nexport async function saveBgcIntegrationConfig(config) {\n return fetchJsonWithAuth(AUTH_URL, BGC_INTEGRATION_CONFIG_PATH, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(config),\n });\n}\n\n// Safe runtime view for consumers such as the onboarding BGC stage. It never\n// contains credential values, only credentialsConfigured/webhookConfigured.\nexport async function getBgcIntegrationSummary() {\n const json = await fetchJsonWithAuth(AUTH_URL, '/integration-config/bgc/summary');\n return json?.data ?? json ?? { updateMethod: 'MANUAL', enabled: true };\n}\n\nconst INTEGRATION_CONFIG_PATH = '/admin/integration-config';\n\nexport async function getIntegrationConfigs() {\n const json = await fetchJsonWithAuth(AUTH_URL, INTEGRATION_CONFIG_PATH);\n return json?.data ?? json ?? [];\n}\n\nexport async function getIntegrationConfig(integrationKey) {\n const json = await fetchJsonWithAuth(\n AUTH_URL,\n `${INTEGRATION_CONFIG_PATH}/${encodeURIComponent(integrationKey)}`,\n );\n return json?.data ?? json;\n}\n\nexport async function saveIntegrationConfig(config) {\n const key = config?.integrationKey;\n const path = key\n ? `${INTEGRATION_CONFIG_PATH}/${encodeURIComponent(key)}`\n : INTEGRATION_CONFIG_PATH;\n return fetchJsonWithAuth(AUTH_URL, path, {\n method: key ? 'PUT' : 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(config),\n });\n}\n\nexport async function deleteIntegrationConfig(integrationKey) {\n return fetchJsonWithAuth(\n AUTH_URL,\n `${INTEGRATION_CONFIG_PATH}/${encodeURIComponent(integrationKey)}`,\n { method: 'DELETE' },\n );\n}\n\nexport async function testIntegrationConnection(config) {\n const json = await fetchJsonWithAuth(AUTH_URL, `${INTEGRATION_CONFIG_PATH}/test`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(config),\n });\n return json?.data ?? json;\n}\n\nexport async function getIntegrationSummary(integrationKey) {\n const json = await fetchJsonWithAuth(\n AUTH_URL,\n `/integration-config/${encodeURIComponent(integrationKey)}/summary`,\n );\n return json?.data ?? json;\n}\n\nexport async function applyIntegrationStatus(integrationKey, recordId, providerResponse) {\n const json = await fetchJsonWithAuth(\n AUTH_URL,\n `/integration-config/${encodeURIComponent(integrationKey)}/apply-status/${encodeURIComponent(recordId)}`,\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(providerResponse),\n },\n );\n return json?.data ?? json;\n}\n\n// getModuleDetailPreview fetches a record's detail-view groups WITH resolved\n// values (references → {id,value}, documents → full object) so the admin page\n// can preview exactly what the detail view will render.\nexport async function getModuleDetailPreview(module, id) {\n const path = `${FORM_GROUPS_PATH}?module=${encodeURIComponent(module)}&id=${encodeURIComponent(id)}&view=detail`;\n const json = await fetchJsonWithAuth(AUTH_URL, path);\n const data = json?.data ?? json;\n return Array.isArray(data) ? data : [];\n}\n\n// ── Roles ─────────────────────────────────────────────────────────────────────\n\nfunction normalizeRole(record) {\n return {\n key: record.role_id ?? record.id,\n roleId: record.role_id ?? record.id,\n roleName: record.role_name ?? 'N/A',\n description: record.role_description ?? 'N/A',\n userCount: record.user_count ?? 0,\n roleType: record.role_type ?? 0,\n raw: record,\n };\n}\n\nexport function getRoleId(role) {\n return role?.raw?.role_id ?? role?.roleId ?? role?.key;\n}\n\nexport async function getAllRoles() {\n const json = await fetchJsonWithAuth(AUTH_URL, '/get-roles');\n const payload = json.data ?? json;\n const defaultRoles = firstArray(payload?.zinnext_default).map(normalizeRole);\n const customRoles = firstArray(payload?.custom_roles).map(normalizeRole);\n const all = [...defaultRoles, ...customRoles];\n return { roles: all, total: all.length };\n}\n\n// ── Teams ─────────────────────────────────────────────────────────────────────\n\nfunction normalizeTeam(record) {\n return {\n key: record.teamId,\n teamId: record.teamId,\n teamName: record.teamName ?? 'N/A',\n manager: record.reportingManager ?? 'N/A',\n managerId: record.reportingManagerId ?? 0,\n memberCount: record.noOfTeamMembers ?? 0,\n members: firstArray(record.teamMembers),\n memberIds: firstArray(record.teamMembersIds),\n raw: record,\n };\n}\n\nexport function getTeamId(team) {\n return team?.raw?.teamId ?? team?.teamId ?? team?.key;\n}\n\nexport async function getAllTeams({ offset = 0, limit = 10, sortBy = 'new', search = '' } = {}) {\n const params = new URLSearchParams({ searchquery: search, sortBy, limit: String(limit), offset: String(offset) });\n const json = await fetchJsonWithAuth(AUTH_URL, `/get-teams?${params}`);\n const payload = json.data ?? json;\n const teams = firstArray(payload?.teams, payload, json?.teams);\n const total = payload?.totalCount ?? payload?.total ?? teams.length;\n return { teams: teams.map(normalizeTeam), total };\n}\n\nexport async function updateTeam(team, { teamName, managerId, memberIds = [] }) {\n const teamId = getTeamId(team);\n return fetchJsonWithAuth(AUTH_URL, `/team/edit?teamId=${teamId}`, {\n method: 'PUT',\n body: JSON.stringify({\n team_name: teamName,\n team_manager: managerId,\n other_team_members: memberIds,\n reporting_team_member: [],\n }),\n });\n}\n\n// ── Role / Team Field Config ──────────────────────────────────────────────────\n\nasync function fetchFieldConfigModule(apiModule, idParam, idValue, configType = 'listView') {\n const params = new URLSearchParams({ module: apiModule, userId: '0', [idParam]: String(idValue), configType });\n const json = await fetchJsonWithAuth(AUTH_URL, `${FIELD_CONFIG_PATH}?${params}`);\n const payload = json.data ?? json;\n return firstArray(payload, payload?.visibleFields, json?.visibleFields);\n}\n\nexport async function getRoleModuleFields(role, configType = 'listView', modules = CUSTOMIZABLE_MODULES) {\n const roleId = getRoleId(role);\n const customizableModules = normalizeCustomizableModules(modules);\n const entries = await Promise.all(\n customizableModules.map(async ({ key, apiModule }) => {\n const fields = await fetchFieldConfigModule(apiModule, 'roleId', roleId, configType);\n return [key, fields.map((f, i) => ({ ...normalizeModuleField(f, i), module: key, apiModule, roleId }))];\n })\n );\n return Object.fromEntries(entries);\n}\n\nexport async function getTeamModuleFields(team, configType = 'listView') {\n const teamId = getTeamId(team);\n const entries = await Promise.all(\n CUSTOMIZABLE_MODULES.map(async ({ key, apiModule }) => {\n const fields = await fetchFieldConfigModule(apiModule, 'teamId', teamId, configType);\n return [key, fields.map((f, i) => ({ ...normalizeModuleField(f, i), module: key, apiModule, teamId }))];\n })\n );\n return Object.fromEntries(entries);\n}\n\nfunction visibleFieldPayload(fields, configType) {\n const isListView = !configType || configType === 'listView';\n return fields.map((field, index) => {\n const base = {\n label: field.fieldName, field: field.fieldKey,\n isVisible: field.isVisible, type: field.type ?? 'text', order: field.order ?? index,\n };\n if (isListView) {\n Object.assign(base, {\n isLink: field.isLink ?? false, linkTemplate: field.linkTemplate ?? '',\n linkType: field.linkType ?? 'internal', linkTarget: field.linkTarget ?? '_self',\n action: field.action ?? 'navigate',\n secondaryField: field.secondaryField ?? '', secondaryLabel: field.secondaryLabel ?? '',\n secondaryFields: Array.isArray(field.secondaryFields) ? field.secondaryFields : [],\n secondarySeparator: field.secondarySeparator ?? '',\n lookup: field.lookup ?? null, actionButtons: field.actionButtons ?? [],\n derived: field.derived ?? null, computed: field.computed ?? null,\n renderType: field.renderType ?? '', renderConfig: field.renderConfig ?? null,\n valueStyles: Array.isArray(field.valueStyles) ? field.valueStyles : [],\n commonStyle: field.commonStyle ?? null, displayTemplate: field.displayTemplate ?? '',\n });\n } else {\n base.isEditable = field.isEditable ?? false;\n base.ismandatory = field.ismandatory ?? field.isMandatory ?? false;\n if (configType === 'filter') {\n base.filterInputType = field.filterInputType ?? 'dropdown';\n base.isDefaultFilter = Boolean(field.isDefaultFilter);\n base.dataSource = field.dataSource ?? 'module';\n if (field.dataSource === 'group') base.groupName = field.groupName ?? '';\n if (field.lookup) base.lookup = field.lookup;\n } else {\n if (['select', 'radio', 'checkbox'].includes(field.type)) {\n base.dataSource = field.dataSource ?? 'module';\n if (field.dataSource === 'group') base.groupName = field.groupName ?? '';\n }\n }\n }\n return base;\n });\n}\n\nexport async function updateRoleModuleFieldConfig(role, module, fields, configType = 'listView', modules = CUSTOMIZABLE_MODULES) {\n const roleId = getRoleId(role);\n const apiModule = normalizeCustomizableModules(modules).find((m) => m.key === module)?.apiModule ?? module;\n return fetchJsonWithAuth(AUTH_URL, `${FIELD_CONFIG_PATH}/role`, {\n method: 'PUT',\n body: JSON.stringify({ module: apiModule, roleId, configType, visibleFields: visibleFieldPayload(fields, configType) }),\n });\n}\n\n// ── Role Configure → Form (derived from Form Groups) ─────────────────────────\n// Unlike getRoleModuleFields/updateRoleModuleFieldConfig above (an\n// independently-seeded flat field list), these back the Form tab's grouped\n// view: the backend derives groups/fields straight from the module's Form\n// Groups config and overlays this role's saved grants (GET\n// /admin/role-form-permissions), so Form Groups stays the single source of\n// truth and new/renamed/removed fields sync automatically. Saving still goes\n// through the existing PUT /admin/field-config/role (configType \"form\") —\n// the backend clamps it against Form Groups' global Show flags either way.\nconst ROLE_FORM_PERMISSIONS_PATH = '/admin/role-form-permissions';\n\n// Must match Be_Auth_DevOps models/roleFormPermissions.go's\n// roleGroupPermissionKey — the synthetic field-config key a group-level\n// ON/OFF toggle is persisted under, alongside real per-field grants, in the\n// same flat visibleFields list (no separate schema/endpoint needed).\nfunction roleGroupPermissionKey(groupName) {\n return `__group__:${groupName}`;\n}\n\n// scope: { clientId, region } — same client/region scope as\n// getAdminFormGroups/AddFormV1's effectiveClientId+effectiveRegion, so a\n// client- or region-scoped Form Groups override (e.g. a per-client Jobs\n// variant) is reflected here too, not just the tenant-wide default. Generic\n// for any module — GetFormGroupConfigScoped falls back to the default when\n// no scoped config exists for the given module, so this is always safe to pass.\nexport async function getRoleFormPermissions(role, module, scope = {}) {\n const roleId = getRoleId(role);\n const params = new URLSearchParams({ module, roleId: String(roleId ?? '') });\n if (scope.clientId) params.set('clientId', scope.clientId);\n if (scope.region) params.set('region', scope.region);\n const json = await fetchJsonWithAuth(AUTH_URL, `${ROLE_FORM_PERMISSIONS_PATH}?${params}`);\n const payload = json?.data ?? json;\n return Array.isArray(payload) ? payload : [];\n}\n\n// groups: [{ name, label, enabled, locked, fields: [{ field, label, enabled, locked, editable }] }]\n// as edited in the UI (see RoleFormPermissionsEditor). Group toggles are sent\n// as synthetic visibleFields rows so the existing role-save + clamp pipeline\n// needs no changes.\n//\n// A role's field-level grants are NOT stored per client/region — they're one\n// shared set overlaid onto whichever scoped Form Groups structure a caller\n// requests (getRoleFormPermissions). So any group/field that's `locked` in\n// the CURRENTLY VIEWED scope (globally disabled there, but possibly enabled\n// under the tenant-wide default or a different client's scope) is left out\n// of the payload entirely — sending its scope-computed `enabled: false`\n// would silently overwrite the role's real, scope-independent stored\n// preference the next time anyone loads a different scope. Locked items\n// aren't editable in this view anyway (their Switch is disabled), so there's\n// nothing this save is meant to change for them.\nexport async function saveRoleFormPermissions(role, module, groups) {\n const roleId = getRoleId(role);\n const visibleFields = [];\n let order = 0;\n for (const group of groups) {\n if (!group.locked) {\n visibleFields.push({\n label: group.label,\n field: roleGroupPermissionKey(group.name),\n // A group carries two independent role toggles: isVisible = shown,\n // isEditable = not-disabled (read-only when false). Default both true.\n isVisible: group.enabled,\n isEditable: group.editable !== false,\n order: order++,\n });\n }\n for (const field of group.fields ?? []) {\n if (field.locked) continue;\n visibleFields.push({\n label: field.label,\n field: field.field,\n isVisible: field.enabled,\n isEditable: field.editable !== false,\n order: order++,\n });\n }\n }\n return fetchJsonWithAuth(AUTH_URL, `${FIELD_CONFIG_PATH}/role`, {\n method: 'PUT',\n body: JSON.stringify({ module, roleId, configType: 'form', visibleFields }),\n });\n}\n\nexport async function updateTeamModuleFieldConfig(team, module, fields, configType = 'listView') {\n const teamId = getTeamId(team);\n const apiModule = CUSTOMIZABLE_MODULES.find((m) => m.key === module)?.apiModule ?? module;\n return fetchJsonWithAuth(AUTH_URL, `${FIELD_CONFIG_PATH}/team`, {\n method: 'PUT',\n body: JSON.stringify({ module: apiModule, teamId, configType, visibleFields: visibleFieldPayload(fields, configType) }),\n });\n}\n\n// ── Users ─────────────────────────────────────────────────────────────────────\n\nexport async function getAllUsers({ offset = 0, limit = 10, sortBy = 'new', searchQuery = '' } = {}) {\n const params = new URLSearchParams({ offset: String(offset), limit: String(limit), sortBy });\n if (searchQuery) params.set('searchquery', searchQuery);\n const json = await fetchJsonWithAuth(AUTH_URL, `/get-all-users?${params}`);\n const payload = json.data ?? json;\n const users = firstArray(\n payload, json.users, json.rows, json.items, json.records,\n payload?.users, payload?.data, payload?.rows, payload?.items,\n payload?.records, payload?.docs, payload?.result, payload?.results,\n );\n return { users, total: normalizeTotal({ ...json, ...payload }, users) };\n}\n\nexport function getUserId(user) {\n const value = firstValue(\n user?.raw ?? user,\n ['USER_ID', 'user_id', 'userId', 'id', '_id', 'uuid'],\n user?.key\n );\n const num = Number(value);\n return Number.isFinite(num) ? num : value;\n}\n\nexport function getUserRoleId(user) {\n const value = firstValue(user?.raw ?? user, ['ROLE_ID', 'role_id', 'roleId', 'ROLEID'], 0);\n const num = Number(value);\n return Number.isFinite(num) && num > 0 ? num : 0;\n}\n\nasync function getFieldConfigModule(apiModule, userId, roleId, configType) {\n const params = new URLSearchParams({ module: apiModule, userId: String(userId ?? ''), roleId: String(roleId ?? ''), configType });\n const json = await fetchJsonWithAuth(AUTH_URL, `${FIELD_CONFIG_PATH}?${params}`);\n const payload = json.data ?? json;\n return firstArray(payload, payload?.visibleFields, json?.visibleFields);\n}\n\nasync function getDropdownModuleFields(apiModule) {\n const json = await fetchJsonWithAuth(SUBMISSIONS_URL, `/filter-dropdown-fields?module=${encodeURIComponent(apiModule)}`);\n const payload = json.data ?? json;\n return firstArray(payload, payload?.fields, payload?.items, payload?.rows, json?.fields);\n}\n\nexport async function getUserModuleFields(user, configType = 'listView', modules = CUSTOMIZABLE_MODULES) {\n const userId = getUserId(user);\n const roleId = getUserRoleId(user);\n const customizableModules = normalizeCustomizableModules(modules);\n const entries = await Promise.all(\n customizableModules.map(async ({ key, apiModule }) => {\n let fields;\n try {\n fields = await getFieldConfigModule(apiModule, userId, roleId, configType);\n } catch {\n try { fields = await getDropdownModuleFields(apiModule); } catch { fields = []; }\n }\n if ((fields?.length ?? 0) === 0) {\n try { fields = await getDropdownModuleFields(apiModule); } catch { fields = []; }\n }\n return [key, fields.map((f, i) => ({ ...normalizeModuleField(f, i), module: key, apiModule, userId, roleId }))];\n })\n );\n return Object.fromEntries(entries);\n}\n\nexport async function hasUserFieldConfigData(user, configType = 'listView', modules = CUSTOMIZABLE_MODULES) {\n const userId = getUserId(user);\n const roleId = getUserRoleId(user);\n const customizableModules = normalizeCustomizableModules(modules);\n const results = await Promise.all(\n customizableModules.map(async ({ apiModule }) => {\n try {\n const fields = await getFieldConfigModule(apiModule, userId, roleId, configType);\n return (fields?.length ?? 0) > 0;\n } catch {\n return false;\n }\n })\n );\n return results.some(Boolean);\n}\n\nexport async function seedFieldConfig(collections = []) {\n return fetchJsonWithAuth(AUTH_URL, `${FIELD_CONFIG_PATH}/seed`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ collections }),\n });\n}\n\nexport async function getFieldConfigSeedStatus() {\n const json = await fetchJsonWithAuth(AUTH_URL, `${FIELD_CONFIG_PATH}/seed-status`);\n const data = json?.data ?? json ?? {};\n return {\n modules: Array.isArray(data.modules) ? data.modules : [],\n seededModules: data.seededModules ?? {},\n };\n}\n\nexport async function updateUserModuleFieldConfig(user, module, fields, configType = 'listView', modules = CUSTOMIZABLE_MODULES) {\n const userId = getUserId(user);\n const roleId = getUserRoleId(user);\n const apiModule = normalizeCustomizableModules(modules).find((m) => m.key === module)?.apiModule ?? module;\n return fetchJsonWithAuth(AUTH_URL, FIELD_CONFIG_PATH, {\n method: 'PUT',\n body: JSON.stringify({ module: apiModule, userId, roleId, configType, visibleFields: visibleFieldPayload(fields, configType) }),\n });\n}\n\nexport async function updateUserModuleFields(user, moduleFields, configType = 'listView') {\n return Promise.all(\n Object.entries(moduleFields).map(([module, fields]) => updateUserModuleFieldConfig(user, module, fields, configType))\n );\n}\n\nexport async function uploadFormGroupIcon(file) {\n const token = localStorage.getItem('authToken');\n const formData = new FormData();\n formData.append('icon', file);\n const res = await fetch(`${AUTH_URL}/admin/form-groups/icon`, {\n method: 'POST',\n headers: { Authorization: `Bearer ${token}` },\n body: formData,\n });\n if (!res.ok) { const e = new Error(`Upload failed: ${res.status}`); e.status = res.status; throw e; }\n const json = await res.json();\n return json.data ?? json;\n}\n\nexport async function uploadListViewActionIcon(file) {\n const token = localStorage.getItem('authToken');\n const formData = new FormData();\n formData.append('icon', file);\n const res = await fetch(`${AUTH_URL}/admin/field-config/action-icon`, {\n method: 'POST',\n headers: { Authorization: `Bearer ${token}` },\n body: formData,\n });\n if (!res.ok) { const e = new Error(`Upload failed: ${res.status}`); e.status = res.status; throw e; }\n const json = await res.json();\n return json.data ?? json;\n}\n\n// Module options for the Actions admin screens: the configured menu/module\n// catalog PLUS every collection in this app's database, so row actions can be\n// configured for ANY module (onboarding, movements, a brand-new collection…)\n// without first registering it as a menu module. Resolves per app DB via\n// X-App-Id, so each project sees its own collections.\nexport async function getActionConfigModules() {\n const [modules, collections] = await Promise.all([\n getAvailableModules().catch(() => []),\n getAvailableCollections().catch(() => []),\n ]);\n const baseModules = Array.isArray(modules) ? modules : [];\n // Detail-view action variants: a module's DETAIL page can carry its own row\n // actions (e.g. an \"Open JD\" primary button on the submission detail view)\n // without those actions also appearing on the LIST view — the detail page\n // fetches actions under \"<module>detail\" (DetailHeaderCard customConfigName).\n // Offer each real module's \"<key>detail\" variant here so those detail-only\n // actions are configurable from the same Actions screen. Purely additive.\n const detailVariants = baseModules\n .map((m) => (typeof m === 'string' ? m : (m?.menuKey ?? m?.module ?? m?.key ?? m?.value ?? m?.name)))\n .filter(Boolean)\n .map((key) => `${String(key).toLowerCase()}detail`);\n return [\n ...baseModules,\n ...(Array.isArray(collections) ? collections : []),\n ...detailVariants,\n ];\n}\n\n// Generic module CRUD — used by the Masters admin screen (locations/taxes),\n// but not specific to either: works for any module via the dynamic gateway.\nexport async function listModuleRecords(module, { page = 1, limit = 100 } = {}) {\n const params = new URLSearchParams({ module, page: String(page), limit: String(limit) });\n const json = await fetchJsonWithAuth(AUTH_URL, `/module/list?${params}`);\n const data = json?.data ?? json ?? {};\n return { items: Array.isArray(data.data) ? data.data : [], total: data.pagination?.total ?? 0 };\n}\n\nexport async function createModuleRecordGeneric(module, payload) {\n return fetchJsonWithAuth(AUTH_URL, `/module/create?module=${encodeURIComponent(module)}`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(payload),\n });\n}\n\nexport async function updateModuleRecordGeneric(module, id, payload) {\n return fetchJsonWithAuth(AUTH_URL, `/module/update/${encodeURIComponent(id)}?module=${encodeURIComponent(module)}`, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(payload),\n });\n}\n\nexport async function deleteModuleRecordGeneric(module, id) {\n return fetchJsonWithAuth(AUTH_URL, `/module/delete/${encodeURIComponent(id)}?module=${encodeURIComponent(module)}`, {\n method: 'DELETE',\n });\n}\n\n// Searchable \"City, State, Country\" options from the locationMasters collection\n// — the same source AddFormV1's `location` field type uses. Used by the Location\n// Tax Master screen to pick a real location instead of free-typing one.\nexport async function getLocationMasterOptions(search = '', limit = 50) {\n const params = new URLSearchParams({ search, limit: String(limit), offset: '0' });\n const json = await fetchJsonWithAuth(AUTH_URL, `/admin/location-dropdown-values?${params}`);\n const raw = json?.data ?? json ?? [];\n return (Array.isArray(raw) ? raw : [])\n .map((item) => {\n const label = typeof item === 'string' ? item : (item.label ?? item.value ?? '');\n return { label, value: label };\n })\n .filter((option) => option.label);\n}\n\n// Generic record options for any lookup-configured field — used by the Form\n// Groups editor's \"Conditional Default\" record picker (e.g. choose the default\n// Employer applied when Contract Type is W2). Returns { label, value } pairs\n// where value is the record's valueField (usually _id).\nexport async function getLookupRecordOptions(collection, displayField, valueField = '_id') {\n const params = new URLSearchParams({\n collection: String(collection),\n displayField: String(displayField),\n valueField: String(valueField),\n });\n const json = await fetchJsonWithAuth(AUTH_URL, `/admin/lookup-dropdown-values?${params}`);\n const raw = json?.data ?? json ?? [];\n return (Array.isArray(raw) ? raw : [])\n .map((item) => ({\n label: item.label ?? item.displayValue ?? item[displayField] ?? String(item.value ?? ''),\n value: String(item.value ?? item._id ?? item.id ?? ''),\n }))\n .filter((option) => option.value && option.label);\n}\n\n// Default Fields — per-module field keys forced always-shown + always-required.\n// getModuleDefaultFields is also called at runtime by AddFormV1/EditFormV1.\n// Saving is OTP-gated: request the code (requestConfigOtp('defaultFields','save'))\n// then pass it here.\nexport async function getModuleDefaultFields(module) {\n const json = await fetchJsonWithAuth(AUTH_URL, `/admin/default-fields?module=${encodeURIComponent(module)}`);\n const data = json?.data ?? json ?? {};\n return Array.isArray(data.fields) ? data.fields : [];\n}\n\nexport async function saveModuleDefaultFields(module, fields, otp) {\n return fetchJsonWithAuth(AUTH_URL, '/admin/default-fields', {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ module, fields, otp }),\n });\n}\n\n// Generic email verification — used by any admin-configured\n// field.verifyAction === \"email\" (AddFormV1/EditFormV1's VerifyFieldButton).\n//\n// The backend runs a layered check (syntax -> MX -> Mailgun -> SMTP mailbox\n// probe -> catch-all detection), so the verdict is richer than a boolean:\n//\n// valid keep/reject the address (unchanged meaning — the form gate)\n// result 'deliverable' | 'undeliverable' | 'risky' | 'unknown'\n// mailboxConfirmed the receiving server confirmed THIS mailbox specifically\n// catchAll the domain accepts every address, so the mailbox is unproven\n//\n// mailboxConfirmed is the one to trust for \"this person will actually get mail\".\n// A catch-all domain (Google Workspace default, many corporates) can never be\n// proven from outside — the UI says so rather than implying certainty.\nexport async function verifyEmail(email) {\n const json = await fetchJsonWithAuth(AUTH_URL, '/email-verify', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ email }),\n });\n const data = json?.data ?? json ?? {};\n return {\n valid: Boolean(data.valid),\n reason: data.reason ?? '',\n result: data.result ?? '',\n mailboxConfirmed: Boolean(data.mailboxConfirmed),\n catchAll: Boolean(data.catchAll),\n disposable: Boolean(data.disposable),\n roleAddress: Boolean(data.roleAddress),\n risk: data.risk ?? '',\n checks: Array.isArray(data.checks) ? data.checks : [],\n };\n}\n\nexport async function getAvailableCollections() {\n const json = await fetchJsonWithAuth(AUTH_URL, '/admin/lookup/collections');\n const data = json.data ?? json;\n return Array.isArray(data) ? data : [];\n}\n\nexport async function getCollectionFields(collection) {\n const json = await fetchJsonWithAuth(AUTH_URL, `/admin/lookup/collection-fields?collection=${encodeURIComponent(collection)}`);\n const data = json.data ?? json;\n return Array.isArray(data) ? data : [];\n}\n\nexport async function getArraySubfields(module, field) {\n const json = await fetchJsonWithAuth(AUTH_URL, `/admin/field-array-subfields?module=${encodeURIComponent(module)}&field=${encodeURIComponent(field)}`);\n const data = json.data ?? json;\n return Array.isArray(data?.fields) ? data.fields : [];\n}\n\n// ── Menu Modules & Actions (master data management) ──────────────────────────\n\nexport async function getMenuModules() {\n const json = await fetchJsonWithAuth(AUTH_URL, '/admin/menu-modules');\n return firstArray(json.data, json);\n}\n\nexport async function createMenuModule({ menuName, apiUrl = '', menuType = 'menu', parentMenuId = 0, displayOrder = 0 }) {\n const json = await fetchJsonWithAuth(AUTH_URL, '/admin/menu-modules', {\n method: 'POST',\n body: JSON.stringify({ menuName, apiUrl, menuType, parentMenuId, displayOrder }),\n });\n return json.data ?? json;\n}\n\nexport async function updateMenuModule(id, { menuName }) {\n const json = await fetchJsonWithAuth(AUTH_URL, `/admin/menu-modules/${id}`, {\n method: 'PUT',\n body: JSON.stringify({ menuName }),\n });\n return json.data ?? json;\n}\n\nexport async function deleteMenuModule(id) {\n const json = await fetchJsonWithAuth(AUTH_URL, `/admin/menu-modules/${id}`, { method: 'DELETE' });\n return json.data ?? json;\n}\n\nexport async function getMenuActions() {\n const json = await fetchJsonWithAuth(AUTH_URL, '/admin/menu-actions');\n return firstArray(json.data, json);\n}\n\nexport async function createMenuAction({ permissionName, permissionKey }) {\n const json = await fetchJsonWithAuth(AUTH_URL, '/admin/menu-actions', {\n method: 'POST',\n body: JSON.stringify({ permissionName, permissionKey }),\n });\n return json.data ?? json;\n}\n\nexport async function updateMenuAction(id, { permissionName }) {\n const json = await fetchJsonWithAuth(AUTH_URL, `/admin/menu-actions/${id}`, {\n method: 'PUT',\n body: JSON.stringify({ permissionName }),\n });\n return json.data ?? json;\n}\n\nexport async function deleteMenuAction(id) {\n const json = await fetchJsonWithAuth(AUTH_URL, `/admin/menu-actions/${id}`, { method: 'DELETE' });\n return json.data ?? json;\n}\n\n// ── Permissions ───────────────────────────────────────────────────────────────\n\nexport async function getRolePermissions(roleId) {\n const json = await fetchJsonWithAuth(AUTH_URL, `/get-role-details?roleid=${roleId}`);\n return (json?.data ?? json) ?? {};\n}\n\nexport async function updateRolePermissions(roleId, menus) {\n return fetchJsonWithAuth(AUTH_URL, '/edit-role-details', {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ roleId, menus }),\n });\n}\n\n// Resolved permissions for the logged-in user's own role — moduleName ->\n// actionKey -> allowed (or the wildcard shape { \"*\": { \"*\": true } } for\n// full-access roles). Fetched once on login by PermissionContext.\nexport async function getMyPermissions() {\n const json = await fetchJsonWithAuth(AUTH_URL, '/me/permissions');\n return (json?.data ?? json) ?? {};\n}\n\n// ── Custom Forms ──────────────────────────────────────────────────────────────\n\nconst CUSTOM_FORMS_PATH = '/admin/custom-forms';\n\nexport async function getCustomForms(module = '', type = '', action = '') {\n const params = new URLSearchParams();\n if (module) params.append('module', module);\n if (type) params.append('formType', type);\n if (action) params.append('action', action);\n const path = `${CUSTOM_FORMS_PATH}?${params.toString()}`;\n const json = await fetchJsonWithAuth(AUTH_URL, path);\n const payload = json?.data;\n if (Array.isArray(payload)) return payload;\n if (Array.isArray(json)) return json;\n return [];\n}\n\nexport async function createCustomForm(form) {\n return fetchJsonWithAuth(AUTH_URL, CUSTOM_FORMS_PATH, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(form),\n });\n}\n\nexport async function updateCustomForm(id, form) {\n return fetchJsonWithAuth(AUTH_URL, `${CUSTOM_FORMS_PATH}/${id}`, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(form),\n });\n}\n\nexport async function deleteCustomForm(id) {\n return fetchJsonWithAuth(AUTH_URL, `${CUSTOM_FORMS_PATH}/${id}`, { method: 'DELETE' });\n}\n\n// ── Row Action Config ─────────────────────────────────────────────────────────\n\nconst ROW_ACTION_CONFIG_PATH = '/admin/row-action-config';\n\n// Keep the module key written by Admin identical to the key used by ListView.\n// Module labels/keys supplied by the module catalog (or typed into the tags\n// selector) may contain casing and surrounding whitespace, while list routes\n// consistently request normalized keys.\nfunction normalizeRowActionModule(module) {\n return String(module ?? '').trim().toLowerCase();\n}\n\nexport async function getRowActionConfigs(module = '') {\n const normalizedModule = normalizeRowActionModule(module);\n const path = normalizedModule\n ? `${ROW_ACTION_CONFIG_PATH}?module=${encodeURIComponent(normalizedModule)}`\n : ROW_ACTION_CONFIG_PATH;\n const json = await fetchJsonWithAuth(AUTH_URL, path);\n const payload = json?.data;\n if (Array.isArray(payload)) return payload;\n if (Array.isArray(json)) return json;\n return [];\n}\n\nexport async function createRowActionConfig({ module, roleId = 0, rowActions = [] }) {\n const normalizedModule = normalizeRowActionModule(module);\n return fetchJsonWithAuth(AUTH_URL, ROW_ACTION_CONFIG_PATH, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ module: normalizedModule, roleId, rowActions }),\n });\n}\n\nexport async function updateRowActionConfig(id, rowActions = []) {\n return fetchJsonWithAuth(AUTH_URL, `${ROW_ACTION_CONFIG_PATH}/${id}`, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ rowActions }),\n });\n}\n\nexport async function deleteRowActionConfig(id) {\n return fetchJsonWithAuth(AUTH_URL, `${ROW_ACTION_CONFIG_PATH}/${id}`, { method: 'DELETE' });\n}\n\nexport async function seedRowActionConfigs() {\n return fetchJsonWithAuth(AUTH_URL, `${ROW_ACTION_CONFIG_PATH}/seed`, { method: 'POST' });\n}\n\n// ── Module Action Rules ───────────────────────────────────────────────────────\n// Per-module configurable rules stored in auth repo, returned by module-data-list.\n// Frontend evaluates these rules per-row to show/hide row action buttons.\n\nconst MODULE_ACTION_RULES_PATH = '/admin/module-action-rules';\n\nexport async function getModuleActionRules(module) {\n const json = await fetchJsonWithAuth(AUTH_URL, `${MODULE_ACTION_RULES_PATH}?module=${encodeURIComponent(module)}`);\n const payload = json?.data;\n if (Array.isArray(payload)) return payload;\n if (Array.isArray(json)) return json;\n return [];\n}\n\nexport async function createModuleActionRule({ module, name, description = '', conditions = [], blockedActions = [], disabledActions = [], isActive = true }) {\n return fetchJsonWithAuth(AUTH_URL, MODULE_ACTION_RULES_PATH, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ module, name, description, conditions, blockedActions, disabledActions, isActive }),\n });\n}\n\nexport async function updateModuleActionRule(id, { name, description = '', conditions = [], blockedActions = [], disabledActions = [], isActive = true }) {\n return fetchJsonWithAuth(AUTH_URL, `${MODULE_ACTION_RULES_PATH}/${id}`, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ name, description, conditions, blockedActions, disabledActions, isActive }),\n });\n}\n\nexport async function deleteModuleActionRule(id) {\n return fetchJsonWithAuth(AUTH_URL, `${MODULE_ACTION_RULES_PATH}/${id}`, { method: 'DELETE' });\n}\n","import { ensureToken, fetchJsonWithAuth } from './authApi';\nimport { AUTH_URL, JOBS_URL, CANDIDATES_URL, SUBMISSIONS_URL } from './apiConfig';\n\n// ── Module Detail & Record Edit ───────────────────────────────────────────────\n\n// fetchUrl — direct downstream (read-only, no tenant injection needed)\n// updateUrl is no longer used; updates go through the Auth gateway.\nconst MODULE_EDIT_CONFIG = {\n job: {\n fetchUrl: (id) => `${JOBS_URL}/edit/detailed-view/${encodeURIComponent(id)}`,\n },\n candidates: {\n fetchUrl: (id) => `${CANDIDATES_URL}/edit/detailed-view?_id=${encodeURIComponent(id)}`,\n },\n submission: {\n fetchUrl: (id) => `${SUBMISSIONS_URL}/edit/detailed-view?_id=${encodeURIComponent(id)}`,\n },\n};\n\nexport async function getModuleDataDetail(module, id) {\n const normalizedModule = String(module ?? '').trim().toLowerCase();\n\n if (normalizedModule === 'job' || normalizedModule === 'jobs') {\n const { getJobDetailView } = await import('./jobsApi');\n return getJobDetailView(id);\n }\n\n const params = new URLSearchParams({ module: String(module ?? ''), id: String(id) });\n return fetchJsonWithAuth(AUTH_URL, `/module-data-detail?${params.toString()}`);\n}\n\nexport async function getModuleActions(module) {\n const json = await fetchJsonWithAuth(\n AUTH_URL,\n `/module-actions?module=${encodeURIComponent(module)}`,\n );\n const data = json?.data ?? json ?? {};\n return {\n actions: Array.isArray(data.actions) ? data.actions : [],\n actionRules: Array.isArray(data.actionRules) ? data.actionRules : [],\n };\n}\n\nexport async function getRecordForEdit(module, id) {\n if (!module) throw new Error('module is required');\n if (!id) throw new Error('id is required');\n\n const config = MODULE_EDIT_CONFIG[module];\n if (!config) throw new Error(`No edit config for module: ${module}`);\n\n const token = await ensureToken();\n const res = await fetch(config.fetchUrl(id), {\n method: 'GET',\n headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${token}` },\n });\n if (!res.ok) throw new Error(`API ${res.status}: ${res.statusText}`);\n const json = await res.json();\n return json.data ?? json;\n}\n\nexport async function updateRecord(module, id, payload, fileParts = []) {\n if (!module) throw new Error('module is required');\n if (!id) throw new Error('id is required');\n\n const token = await ensureToken();\n const formData = new FormData();\n formData.append('json', JSON.stringify(payload));\n // New file uploads ride along in the SAME multipart, under the part name the\n // downstream update handler reads (jobs → \"file\", candidates → resume/passport/\n // documents/…). The gateway forwards them and the downstream stores + returns\n // their name/location. Existing files (no originFileObj) are not re-sent.\n (fileParts ?? []).forEach(({ formKey, file }) => formData.append(formKey, file));\n\n const res = await fetch(\n `${AUTH_URL}/module/update/${encodeURIComponent(id)}?module=${encodeURIComponent(module)}`,\n { method: 'PUT', headers: { Authorization: `Bearer ${token}` }, body: formData },\n );\n\n if (!res.ok) {\n const errorText = await res.text();\n console.error('[updateRecord] Error response:', errorText);\n throw new Error(errorText || `API ${res.status}: ${res.statusText}`);\n }\n\n const json = await res.json();\n return json.data ?? json;\n}\n\n// ── Activity & Notes ──────────────────────────────────────────────────────────\n\nconst unwrap = (json) => json?.data ?? json;\n\nexport async function getActivity(module, id) {\n if (!module || !id) return [];\n const params = new URLSearchParams({ module, id: String(id) });\n const json = await fetchJsonWithAuth(AUTH_URL, `/module-activity?${params.toString()}`);\n const data = unwrap(json);\n return Array.isArray(data) ? data : [];\n}\n\nexport async function getNotes(relatedId) {\n if (!relatedId) return [];\n const json = await fetchJsonWithAuth(AUTH_URL, `/notes?relatedId=${encodeURIComponent(relatedId)}`);\n const data = unwrap(json);\n return Array.isArray(data) ? data : [];\n}\n\nexport async function createNote({ relatedId, notes, title, notesFor }) {\n const json = await fetchJsonWithAuth(AUTH_URL, '/notes', {\n method: 'POST',\n body: JSON.stringify({ relatedId, notes, title, notesFor }),\n });\n return unwrap(json);\n}\n\nexport async function uploadJobAttachment(recordId, file) {\n const { ensureToken } = await import('./authApi');\n const token = await ensureToken();\n\n const formData = new FormData();\n formData.append('file', file);\n formData.append('jobId', recordId);\n\n const res = await fetch(`${JOBS_URL}/jobs/${recordId}/attachment`, {\n method: 'POST',\n headers: { Authorization: `Bearer ${token}` },\n body: formData,\n });\n\n if (!res.ok) {\n const errorText = await res.text();\n throw new Error(errorText || `API ${res.status}: ${res.statusText}`);\n }\n\n const json = await res.json();\n return json.data ?? json;\n}\n","// Central source-of-truth for detail-view DISPLAY defaults.\n//\n// These values used to be hard-coded inside components/detail/fileUtils.js and\n// components/detail/FieldValue.jsx. They now live here, are seeded with the same\n// built-in defaults, and are overridable from the admin page\n// (Admin → Detail Groups → Display Defaults), which persists them via\n// GET/POST /admin/detail-defaults.\n//\n// This is a plain module (not a React component / context) so fileUtils.js — a\n// non-component helper — can read it synchronously. Consumers read getDefaults()\n// at render time; loadDetailDefaults() fetches the saved values once and updates\n// the store (falling back to the built-ins on any failure).\n\nimport { getDetailDefaults as fetchDetailDefaults } from './adminApi';\n\n// Built-in defaults — exactly the previous hard-coded behaviour. S3 base still\n// honours VITE_S3_BASE_URL as the env-level seed; the admin value overrides it.\nexport const BUILT_IN_DEFAULTS = Object.freeze({\n s3BaseUrl: (\n import.meta.env?.VITE_S3_BASE_URL ||\n 'https://zinnext-devlopment-ap-south-1.s3.ap-south-1.amazonaws.com'\n ).replace(/\\/+$/, ''),\n dateFormat: 'DD MMM YYYY',\n booleanTrueLabel: 'Yes',\n booleanFalseLabel: 'No',\n emptyPlaceholder: '-',\n separator: ' - ',\n documentNameOrder: ['name', 'documentName', 'uploadName', 'uploadedFileName', 'uniqueName'],\n // Common phone-number format — one place, applied everywhere (forms + detail),\n // exactly like `dateFormat`. Groups of digit counts separated by a literal\n // separator: \"3-3-4\" → 999-878-3413 (total 10 digits). Change it here (or in\n // Admin → Display Defaults) and every phone field re-formats to match.\n phoneFormat: '3-3-4',\n});\n\nlet current = { ...BUILT_IN_DEFAULTS };\nlet loadPromise = null;\n\n// getDefaults returns the live defaults (built-ins until loadDetailDefaults runs).\nexport function getDefaults() {\n return current;\n}\n\n// sanitize keeps only the keys that carry a real value, so a partial/empty saved\n// config never blanks out a built-in.\nfunction sanitize(d) {\n if (!d || typeof d !== 'object') return {};\n const out = {};\n if (d.s3BaseUrl) out.s3BaseUrl = String(d.s3BaseUrl).replace(/\\/+$/, '');\n if (d.dateFormat) out.dateFormat = d.dateFormat;\n if (d.booleanTrueLabel) out.booleanTrueLabel = d.booleanTrueLabel;\n if (d.booleanFalseLabel) out.booleanFalseLabel = d.booleanFalseLabel;\n if (d.emptyPlaceholder) out.emptyPlaceholder = d.emptyPlaceholder;\n if (typeof d.separator === 'string' && d.separator !== '') out.separator = d.separator;\n if (typeof d.phoneFormat === 'string' && d.phoneFormat.trim() !== '') out.phoneFormat = d.phoneFormat.trim();\n if (Array.isArray(d.documentNameOrder) && d.documentNameOrder.length) out.documentNameOrder = d.documentNameOrder;\n return out;\n}\n\n// ── Phone number formatting (common, config-driven) ──────────────────────────\n// The format string is groups of digit counts joined by a literal separator,\n// e.g. \"3-3-4\" → [3,3,4] joined by \"-\". parsePhoneFormat returns { groups, sep,\n// total } so both the formatter and the length validation share one definition.\nexport function parsePhoneFormat(format = getPhoneFormat()) {\n const groups = (String(format).match(/\\d+/g) ?? ['3', '3', '4']).map(Number).filter((n) => n > 0);\n const sep = (String(format).match(/\\D+/)?.[0]) ?? '-';\n const safeGroups = groups.length ? groups : [3, 3, 4];\n return { groups: safeGroups, sep, total: safeGroups.reduce((a, b) => a + b, 0) };\n}\n\n// Live phone format from the same singleton the detail defaults use.\nexport function getPhoneFormat() {\n return current.phoneFormat || BUILT_IN_DEFAULTS.phoneFormat;\n}\n\n// Strips everything but digits, capped at the configured total (default 10).\nexport function phoneDigits(value, format = getPhoneFormat()) {\n const { total } = parsePhoneFormat(format);\n return String(value ?? '').replace(/\\D/g, '').slice(0, total);\n}\n\n// formatPhone turns any input into the configured mask as the user types:\n// \"9998783413\" → \"999-878-3413\". Partial input formats progressively\n// (\"99987\" → \"999-87\"); non-digits are ignored.\nexport function formatPhone(value, format = getPhoneFormat()) {\n const { groups, sep } = parsePhoneFormat(format);\n const digits = phoneDigits(value, format);\n if (!digits) return '';\n const chunks = [];\n let i = 0;\n for (const size of groups) {\n if (i >= digits.length) break;\n chunks.push(digits.slice(i, i + size));\n i += size;\n }\n return chunks.join(sep);\n}\n\n// applyDefaults merges a (partial) config over the current store immediately —\n// used by the admin page right after a successful save so the change is live\n// without a reload.\nexport function applyDefaults(partial) {\n current = { ...current, ...sanitize(partial) };\n return current;\n}\n\n// loadDetailDefaults fetches the saved defaults once (cached). Safe to call from\n// anywhere — failures silently keep the built-ins. Pass force=true to refetch.\nexport function loadDetailDefaults(force = false) {\n if (loadPromise && !force) return loadPromise;\n loadPromise = fetchDetailDefaults()\n .then((d) => applyDefaults(d))\n .catch(() => current);\n return loadPromise;\n}\n","// Runtime gate consulted by AddFormV1/EditFormV1 so a role's Form\n// Configuration (Role Configure → Form) actually restricts the real add/edit\n// form, not just the admin preview. rolePerms is the array returned by\n// GET /admin/role-form-permissions (see adminApi.js getRoleFormPermissions):\n// [{ name, enabled, locked, fields: [{ field, enabled, locked }] }].\n//\n// Fails OPEN (returns true) whenever rolePerms is null/empty/not-yet-loaded —\n// a module or role with no derived permissions behaves exactly as before\n// (gated only by Form Groups' own show/visiblePermission), so this is purely\n// additive and cannot hide a field that used to render.\nexport function groupAllowedByRole(rolePerms, groupName) {\n if (!rolePerms) return true;\n const group = rolePerms.find((g) => g.name === groupName);\n if (!group) return true;\n return group.enabled !== false;\n}\n\nexport function fieldAllowedByRole(rolePerms, groupName, fieldKey) {\n if (!rolePerms) return true;\n const group = rolePerms.find((g) => g.name === groupName);\n if (!group) return true;\n const field = group.fields?.find((f) => f.field === fieldKey);\n if (!field) return true;\n return field.enabled !== false;\n}\n\n// Editability gate — the \"disable\" side of Role Configure → Form. A group or\n// field marked editable:false is still SHOWN but rendered read-only. Fails\n// OPEN (returns true = editable) when nothing is configured, so a role/module\n// with no derived permissions stays fully editable, exactly as before.\nexport function groupEditableByRole(rolePerms, groupName) {\n if (!rolePerms) return true;\n const group = rolePerms.find((g) => g.name === groupName);\n if (!group) return true;\n return group.editable !== false;\n}\n\nexport function fieldEditableByRole(rolePerms, groupName, fieldKey) {\n if (!rolePerms) return true;\n const group = rolePerms.find((g) => g.name === groupName);\n if (!group) return true;\n if (group.editable === false) return false; // group disabled → every field read-only\n const field = group.fields?.find((f) => f.field === fieldKey);\n if (!field) return true;\n return field.editable !== false;\n}\n","import DOMPurify from 'dompurify';\n\nconst RICH_TEXT_TAGS = [\n 'p', 'br', 'strong', 'b', 'em', 'i', 'u', 's', 'ul', 'ol', 'li',\n 'blockquote', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'a', 'code', 'pre',\n];\nconst RICH_TEXT_ATTRS = ['href', 'title', 'target', 'rel'];\nconst INVISIBLE_RE = /[\\u200B-\\u200D\\u2060\\uFEFF]/g;\n// Security normalization intentionally targets ASCII control characters.\n// eslint-disable-next-line no-control-regex\nconst CONTROL_RE = /[\\u0000-\\u0008\\u000B\\u000C\\u000E-\\u001F\\u007F]/g;\nconst NAME_RE = /^[\\p{L}\\p{M}\\p{N} .'-]+$/u;\nconst PHONE_RE = /^\\+?[0-9 ()-]+$/;\nconst NUMBER_RE = /^-?(?:\\d+|\\d*\\.\\d+)$/;\n\nconst ATTACK_PATTERNS = [\n { re: /<\\s*\\/?\\s*(?:script|iframe|object|embed|svg|img|form|input|style|link|meta)\\b/i, message: 'HTML/script content is not allowed' },\n { re: /\\b(?:javascript|vbscript)\\s*:|\\bdata\\s*:\\s*text\\/html/i, message: 'Unsafe URL protocol is not allowed' },\n { re: /\\bon[a-z]+\\s*=/i, message: 'HTML event handlers are not allowed' },\n { re: /\\bunion\\s+(?:all\\s+)?select\\b|\\b(?:drop\\s+table|delete\\s+from|insert\\s+into|xp_cmdshell)\\b/i, message: 'Database command patterns are not allowed' },\n { re: /(?:['\"]\\s*)?\\b(?:or|and)\\s+\\d+\\s*=\\s*\\d+/i, message: 'Injection patterns are not allowed' },\n { re: /[\"']?\\$(?:where|gt|gte|lt|lte|ne|regex|or|and|expr|function)\\b/i, message: 'MongoDB operators are not allowed in input values' },\n { re: /(?:\\.\\.[/\\\\])|(?:%2e|%2f|%5c)/i, message: 'Path traversal patterns are not allowed' },\n { re: /&&|\\|\\||\\$\\(|\\$\\{|`|\\b(?:rm\\s+-rf|cat\\s+\\/etc\\/|whoami\\b|curl\\s+https?:\\/\\/|wget\\s+https?:\\/\\/)/i, message: 'Command execution patterns are not allowed' },\n];\n\nfunction decodeHtmlEntities(value) {\n if (typeof document === 'undefined') return value;\n const textarea = document.createElement('textarea');\n textarea.innerHTML = value;\n return textarea.value;\n}\n\nexport function canonicalizeForSecurityScan(value) {\n let result = String(value ?? '');\n for (let i = 0; i < 2; i += 1) {\n try {\n const decoded = decodeURIComponent(result);\n if (decoded === result) break;\n result = decoded;\n } catch { break; }\n }\n result = decodeHtmlEntities(result)\n .replace(/\\\\x([0-9a-f]{2})/gi, (_, hex) => String.fromCharCode(Number.parseInt(hex, 16)))\n .replace(/\\\\u([0-9a-f]{4})/gi, (_, hex) => String.fromCharCode(Number.parseInt(hex, 16)));\n return result.normalize('NFC');\n}\n\nexport function sanitizeRichText(value) {\n return DOMPurify.sanitize(String(value ?? ''), {\n ALLOWED_TAGS: RICH_TEXT_TAGS,\n ALLOWED_ATTR: RICH_TEXT_ATTRS,\n ALLOW_DATA_ATTR: false,\n FORBID_TAGS: ['script', 'style', 'iframe', 'object', 'embed', 'svg', 'img', 'form', 'input'],\n FORBID_ATTR: ['style', 'src', 'srcset'],\n });\n}\n\nfunction validationMax(field) {\n const rule = (field.validations ?? []).find((item) => item?.type === 'max');\n const configured = Number(field.validator?.maxLength ?? rule?.value ?? field.maxLength);\n if (Number.isFinite(configured) && configured > 0) return configured;\n if (field.type === 'email' || field.formatter === 'email') return 255;\n if (field.formatter === 'phone' || field.formatter === 'digits') return 32;\n if (field.formatter === 'name') return 100;\n if (field.type === 'text-editor') return 50000;\n if (field.type === 'textarea') return 5000;\n return 5000;\n}\n\nfunction isMultiline(field) {\n return field.type === 'textarea' || field.type === 'text-editor';\n}\n\nexport function normalizeSecureString(value, field = {}) {\n if (typeof value !== 'string') return value;\n if (field.type === 'text-editor') return sanitizeRichText(value.normalize('NFC'));\n\n let normalized = value.normalize('NFC')\n .replace(INVISIBLE_RE, '')\n .replace(/\\u00A0/g, ' ')\n .replace(CONTROL_RE, '');\n if (isMultiline(field)) {\n normalized = normalized.replace(/\\r\\n?/g, '\\n').replace(/[ \\t]{2,}/g, ' ').trim();\n } else {\n normalized = normalized.replace(/\\s+/g, ' ').trim();\n }\n return normalized;\n}\n\nexport function validateSecureString(value, field = {}) {\n if (typeof value !== 'string' || value === '') return null;\n const label = field.label || field.field || 'Field';\n const canonical = canonicalizeForSecurityScan(value);\n\n if (canonical.includes('\\0') || canonical.includes('\\u0000')) return `${label} contains a null byte`;\n if (field.type !== 'text-editor') {\n const attack = ATTACK_PATTERNS.find(({ re }) => re.test(canonical));\n if (attack) return `${label}: ${attack.message}`;\n } else {\n const dangerousRichText = ATTACK_PATTERNS.slice(0, 3).find(({ re }) => re.test(canonical));\n if (dangerousRichText) return `${label}: ${dangerousRichText.message}`;\n }\n\n const normalized = normalizeSecureString(value, field);\n if ([...normalized].length > validationMax(field)) return `${label} is too long`;\n if (field.formatter === 'name' && normalized && !NAME_RE.test(normalized)) {\n return `${label} allows only letters, numbers, spaces, apostrophes, hyphens and periods`;\n }\n if ((field.formatter === 'phone' || field.formatter === 'digits') && normalized && !PHONE_RE.test(normalized)) {\n return `${label} contains invalid phone characters`;\n }\n if (field.type === 'number' && normalized && !NUMBER_RE.test(normalized)) {\n return `${label} must contain only a valid number`;\n }\n if ((field.type === 'url' || field.formatter === 'url') && normalized && !/^https?:\\/\\//i.test(normalized)) {\n return `${label} must use http:// or https://`;\n }\n return null;\n}\n\nexport function securityValidationRule(field) {\n return {\n validator: (_, value) => {\n const values = Array.isArray(value) ? value : [value];\n const error = values.map((item) => validateSecureString(item, field)).find(Boolean);\n return error ? Promise.reject(new Error(error)) : Promise.resolve();\n },\n };\n}\n\nfunction policyMap(groups = []) {\n const policies = new Map();\n groups.forEach((group) => {\n (group.fields ?? []).forEach((field) => {\n if (field.type === 'file') return;\n const destination = field.payloadKey || field.field;\n if (!destination) return;\n const path = group.addRow ? `${group.payloadKey || group.name}[].${destination}` : destination;\n policies.set(path, field);\n });\n });\n return policies;\n}\n\nexport function securePayload(payload, groups = []) {\n const policies = policyMap(groups);\n const walk = (node, path = '') => {\n if (typeof node === 'string') {\n const field = policies.get(path) ?? {};\n const error = validateSecureString(node, field);\n if (error) throw new Error(error);\n return normalizeSecureString(node, field);\n }\n if (Array.isArray(node)) return node.map((item) => walk(item, `${path}[]`));\n if (node && typeof node === 'object') {\n return Object.fromEntries(Object.entries(node).map(([key, value]) => {\n if (key.startsWith('$') || key.includes('.') || key.includes('\\0')) {\n throw new Error(`Unsafe object key: ${key}`);\n }\n const childPath = path ? `${path}.${key}` : key;\n return [key, walk(value, childPath)];\n }));\n }\n return node;\n };\n return walk(payload);\n}\n","/**\n * payloadTransformer — the single, configuration-driven payload engine shared by\n * AddFormV1 and EditFormV1.\n *\n * Goal: the Admin form-group config is the ONLY source of truth for how a form\n * value becomes an API payload value. There is ZERO field-name / module-specific\n * branching here. Every behaviour is driven by these per-field config keys:\n *\n * payloadKey output key (dot-notation allowed). Default: field.field\n * dataType auto | string | number | boolean | array | object | date | custom\n * elementType for dataType \"array\": coerce each element (e.g. \"number\")\n * payloadMode auto | value | label | object | custom | template | skip\n * valueKey which key holds the id/value on an option object (default: value/id/_id…)\n * displayKey which key holds the label on an option object (default: label/name…)\n * payloadTemplate object template for custom/template modes, with {{value}} {{label}} {{raw}} tokens\n * defaultValue value substituted when the form value is empty\n * transformRule { map: {...}, default, name } — value maps / named transforms\n * omitEmpty drop the key entirely when the final value is empty\n *\n * Nothing here knows about \"priority\", \"recruiters\", \"noticePeriod\", etc. Those\n * are expressed purely through the config above.\n *\n * Backward compatibility: when a field carries NONE of the new keys, the engine\n * falls back to the historical generic behaviour — dot-notation nesting, dayjs →\n * ISO string, scalar pass-through — so existing forms keep working unchanged.\n */\n\nimport dayjs from 'dayjs';\nimport { securePayload } from './inputSecurity';\n\n// ── small shared predicates ───────────────────────────────────────────────────\n\nconst isEmpty = (v) =>\n v === undefined ||\n v === null ||\n v === '' ||\n (Array.isArray(v) && v.length === 0);\n\n// truthy tolerates the shapes a boolean config flag can arrive in (true/1/\"1\"),\n// matching how the forms read the same flags elsewhere.\nconst truthy = (v) => v === true || v === 1 || v === '1';\n\nconst isPlainObject = (v) =>\n v !== null && typeof v === 'object' && !Array.isArray(v) && !isDayjs(v);\n\nfunction isDayjs(v) {\n return (\n v &&\n typeof v === 'object' &&\n typeof v.format === 'function' &&\n typeof v.isValid === 'function'\n );\n}\n\nfunction isDateLike(v) {\n return isDayjs(v) || v instanceof Date;\n}\n\nfunction toISO(v) {\n if (v instanceof Date) return v.toISOString();\n if (isDayjs(v)) return v.isValid() ? v.toISOString() : null;\n return v;\n}\n\n// ── dot-notation get / set ────────────────────────────────────────────────────\n\nexport function getDeep(obj, path) {\n if (!path) return undefined;\n const parts = String(path).split('.');\n let cur = obj;\n for (const part of parts) {\n if (cur == null) return undefined;\n cur = cur[part];\n }\n return cur;\n}\n\n// readFormValue reads a field value tolerating BOTH antd conventions used in this\n// codebase: a flat dotted key (\"experience.from\", as EditForm registers fields)\n// and a nested object (\"experience\": { from }, as AddForm registers fields).\nexport function readFormValue(values, path) {\n if (values && Object.prototype.hasOwnProperty.call(values, path)) return values[path];\n return getDeep(values, path);\n}\n\n// hasFormValue reports whether a submit actually carried this field (so EditForm\n// can leave untouched parts of the base record alone).\nexport function hasFormValue(values, path) {\n if (values && Object.prototype.hasOwnProperty.call(values, path)) return true;\n return getDeep(values, path) !== undefined;\n}\n\nexport function setDeep(target, path, value) {\n const parts = String(path).split('.');\n let cur = target;\n for (let i = 0; i < parts.length - 1; i += 1) {\n const key = parts[i];\n if (!isPlainObject(cur[key])) cur[key] = {};\n cur = cur[key];\n }\n cur[parts[parts.length - 1]] = value;\n return target;\n}\n\n/** Merge a plain object's keys into target at root (used by custom/template spread). */\nfunction mergeDeep(target, source) {\n Object.entries(source ?? {}).forEach(([k, v]) => {\n if (isPlainObject(v) && isPlainObject(target[k])) mergeDeep(target[k], v);\n else target[k] = v;\n });\n return target;\n}\n\n// ── option / value-label normalisation ────────────────────────────────────────\n\nfunction optionLabelFor(field, value) {\n const opts = field.options ?? field.values ?? [];\n for (const o of opts) {\n if (typeof o === 'string') {\n if (o === value) return o;\n } else if ((o.value ?? o.id ?? o.name ?? o.label) === value) {\n return o.label ?? o.name ?? o.value;\n }\n }\n return undefined;\n}\n\n/**\n * splitValueLabel — normalises a raw form value into { value, label }.\n * Handles antd labelInValue ({value,label}), {id,name}/{_id,…} option objects,\n * and plain primitives (label recovered from field.options when present).\n */\nfunction splitValueLabel(raw, field) {\n if (isPlainObject(raw)) {\n const value =\n (field.valueKey && raw[field.valueKey]) ??\n raw.value ??\n raw.id ??\n raw._id ??\n raw.key ??\n raw.code;\n const label =\n (field.displayKey && raw[field.displayKey]) ??\n raw.label ??\n raw.name ??\n raw.text ??\n raw.title ??\n value;\n return { value, label };\n }\n return { value: raw, label: optionLabelFor(field, raw) ?? raw };\n}\n\n// effectiveDataType — the dataType to apply. An explicit dataType always wins;\n// otherwise it is inferred from the field's input type / multiplicity so that a\n// plain `type: \"number\"` or a multi-select keeps coercing without the admin\n// having to set dataType on every field (keeps existing configs working).\nexport function effectiveDataType(field = {}) {\n if (field.dataType && field.dataType !== 'auto') return field.dataType;\n if (field.multiSelect || field.mode === 'multiple' || field.addRow) return 'array';\n switch (field.type) {\n case 'number':\n return 'number';\n case 'date':\n case 'time':\n return 'date';\n default:\n return 'auto';\n }\n}\n\n// ── data-type coercion ────────────────────────────────────────────────────────\n\nexport function coerceDataType(value, dataType, field = {}) {\n if (isDateLike(value)) {\n // Dates always serialise to ISO unless explicitly typed otherwise below.\n if (dataType === 'string') return toISO(value);\n if (dataType === 'number') {\n const t = isDayjs(value) ? value.valueOf() : value.getTime();\n return Number.isNaN(t) ? null : t;\n }\n if (dataType === 'date' || dataType === 'auto' || !dataType) return toISO(value);\n }\n\n switch (dataType) {\n case 'string':\n return value == null ? '' : String(value);\n\n case 'number': {\n if (isEmpty(value)) return null;\n const n = Number(value);\n return Number.isNaN(n) ? null : n;\n }\n\n case 'boolean':\n return value === true || value === 1 || value === '1' || value === 'true';\n\n case 'array': {\n let arr;\n if (Array.isArray(value)) arr = value;\n else if (isEmpty(value)) arr = [];\n else if (typeof value === 'string' && value.includes(','))\n arr = value.split(',').map((s) => s.trim()).filter(Boolean);\n else arr = [value];\n if (field.elementType) {\n return arr\n .map((el) => coerceDataType(el, field.elementType, {}))\n .filter((el) => el !== null && el !== undefined && el !== '');\n }\n return arr;\n }\n\n case 'object':\n return isPlainObject(value) ? value : value;\n\n case 'date':\n return toISO(value);\n\n case 'custom':\n case 'auto':\n case undefined:\n case '':\n default:\n return value;\n }\n}\n\n// ── transformRule (value maps + named transforms) ─────────────────────────────\n\nconst NAMED_TRANSFORMS = {\n firstChecked: (v) => (Array.isArray(v) ? v[0] : v),\n csvToArray: (v) =>\n typeof v === 'string' ? v.split(',').map((s) => s.trim()).filter(Boolean) : v,\n arrayToCsv: (v) => (Array.isArray(v) ? v.join(',') : v),\n trim: (v) => (typeof v === 'string' ? v.trim() : v),\n upper: (v) => (typeof v === 'string' ? v.toUpperCase() : v),\n lower: (v) => (typeof v === 'string' ? v.toLowerCase() : v),\n};\n\nfunction applyTransformRule(value, transformRule) {\n if (!transformRule) return value;\n let rule = transformRule;\n if (typeof rule === 'string') {\n // Either a named transform or a JSON blob.\n if (NAMED_TRANSFORMS[rule]) return NAMED_TRANSFORMS[rule](value);\n try {\n rule = JSON.parse(rule);\n } catch {\n return value;\n }\n }\n\n let out = value;\n if (rule.name && NAMED_TRANSFORMS[rule.name]) out = NAMED_TRANSFORMS[rule.name](out);\n\n if (rule.map && typeof rule.map === 'object') {\n const key = Array.isArray(out) ? String(out[0]) : String(out);\n if (Object.prototype.hasOwnProperty.call(rule.map, key)) out = rule.map[key];\n else if (rule.default !== undefined) out = rule.default;\n }\n return out;\n}\n\n// ── template resolution (custom / template payload modes) ─────────────────────\n\nconst TOKEN_RE = /\\{\\{\\s*([\\w.]+)\\s*\\}\\}/g;\n\nfunction resolveToken(token, ctx) {\n const [head, ...rest] = token.split('.');\n let base;\n if (head === 'value') base = ctx.value;\n else if (head === 'label') base = ctx.label;\n else if (head === 'raw') base = ctx.raw;\n else return undefined;\n return rest.length ? getDeep(base, rest.join('.')) : base;\n}\n\nfunction resolveTemplateNode(node, ctx) {\n if (typeof node === 'string') {\n // Whole-string single token → return the typed value (keep numbers numeric).\n const whole = node.match(/^\\{\\{\\s*([\\w.]+)\\s*\\}\\}$/);\n if (whole) return resolveToken(whole[1], ctx);\n return node.replace(TOKEN_RE, (_, tok) => {\n const v = resolveToken(tok, ctx);\n return v == null ? '' : String(v);\n });\n }\n if (Array.isArray(node)) return node.map((n) => resolveTemplateNode(n, ctx));\n if (isPlainObject(node)) {\n const out = {};\n Object.entries(node).forEach(([k, v]) => {\n out[k] = resolveTemplateNode(v, ctx);\n });\n return out;\n }\n return node;\n}\n\nfunction parseTemplate(template) {\n if (!template) return null;\n if (typeof template === 'string') {\n try {\n return JSON.parse(template);\n } catch {\n return null;\n }\n }\n return template;\n}\n\n// ── payloadMode shaping ───────────────────────────────────────────────────────\n\nfunction shapeSingle(field, raw) {\n const mode = field.payloadMode || 'auto';\n const dataType = effectiveDataType(field);\n const { value, label } = splitValueLabel(raw, field);\n\n switch (mode) {\n case 'value':\n return { kind: 'scalar', out: coerceDataType(value, dataType, field) };\n\n case 'label':\n return { kind: 'scalar', out: coerceDataType(label, field.dataType || 'string', field) };\n\n case 'object': {\n const vKey = field.valueKey || 'id';\n const dKey = field.displayKey || 'name';\n return {\n kind: 'scalar',\n out: {\n [vKey]: coerceDataType(value, field.elementType || 'auto', {}),\n [dKey]: label,\n },\n };\n }\n\n case 'custom':\n case 'template': {\n const tpl = parseTemplate(field.payloadTemplate);\n if (!tpl) return { kind: 'scalar', out: coerceDataType(value, dataType, field) };\n const ctx = { value: coerceDataType(value, field.elementType || 'auto', {}), label, raw };\n const resolved = resolveTemplateNode(tpl, ctx);\n // A template that yields a plain object spreads into the parent unless the\n // admin pinned an explicit payloadKey.\n return { kind: field.payloadKey ? 'scalar' : 'spread', out: resolved };\n }\n\n case 'auto':\n default:\n return { kind: 'scalar', out: coerceDataType(value, dataType, field) };\n }\n}\n\n/**\n * shapeFieldValue — turns one field's raw form value into its payload contribution.\n * Returns { kind: 'scalar'|'spread'|'skip', out }.\n * scalar → write `out` at the field's payloadKey\n * spread → merge `out` (a plain object) into the parent payload\n * skip → contribute nothing\n */\nexport function shapeFieldValue(field, rawValue) {\n if (field.payloadMode === 'skip') return { kind: 'skip' };\n\n let raw = rawValue;\n if (isEmpty(raw) && field.defaultValue !== undefined && field.defaultValue !== '') {\n raw = field.defaultValue;\n }\n\n raw = applyTransformRule(raw, field.transformRule);\n\n if (isEmpty(raw) && field.omitEmpty) return { kind: 'skip' };\n\n // Multi-value (multi-select / array source) with a per-element shape.\n const isMultiSource =\n Array.isArray(raw) &&\n (effectiveDataType(field) === 'array' || field.payloadMode === 'object');\n\n if (isMultiSource && field.payloadMode && field.payloadMode !== 'value' && field.payloadMode !== 'auto') {\n const out = raw.map((item) => shapeSingle(field, item).out);\n return { kind: 'scalar', out };\n }\n\n return shapeSingle(field, raw);\n}\n\nexport function usesLabeledSelectValue(field = {}) {\n return Boolean(field.richValue) || ['label', 'object', 'custom', 'template'].includes(field.payloadMode);\n}\n\nexport function toSelectControlValue(field, value, options = []) {\n if (!usesLabeledSelectValue(field) || value == null) return value;\n const toLabeled = (item) => {\n if (isPlainObject(item) && item.value !== undefined) return item;\n const match = options.find((option) =>\n String(option?.value ?? '') === String(item) || String(option?.label ?? '') === String(item));\n return {\n value: match?.value ?? item,\n label: match?.label ?? String(item),\n };\n };\n return Array.isArray(value) ? value.map(toLabeled) : toLabeled(value);\n}\n\n// ── showIf payload gating ─────────────────────────────────────────────────────\n//\n// A field hidden by its showIf condition must not STORE either: antd preserves\n// values of unmounted Form.Items, so \"check VMS Required, type a commission,\n// uncheck it\" would still submit the commission. showIfSatisfied evaluates the\n// same operators the forms render with, against the field's own scope (the row\n// object for an addRow row) falling back to the whole form values (a condition\n// field living in another group, e.g. contractType). writeField consults it and\n// writes null instead of the stale value, so an edit also clears what a\n// now-hidden field previously stored. Config-driven; no field names.\nexport function showIfSatisfied(showIf, scope, root) {\n if (!showIf?.field) return true;\n const val = hasFormValue(scope, showIf.field)\n ? readFormValue(scope, showIf.field)\n : readFormValue(root ?? scope, showIf.field);\n const list = () => String(showIf.value ?? '').split(',').map((v) => v.trim());\n switch (showIf.operator) {\n case 'eq': return String(val ?? '') === String(showIf.value ?? '');\n case 'neq': return String(val ?? '') !== String(showIf.value ?? '');\n case 'truthy': return val !== undefined && val !== null && val !== '' && val !== false;\n case 'falsy': return val === undefined || val === null || val === '' || val === false;\n case 'notEmpty': return Array.isArray(val) ? val.length > 0 : Boolean(val);\n case 'in': return list().includes(String(val ?? ''));\n case 'notIn': return !list().includes(String(val ?? ''));\n default: return true;\n }\n}\n\n// fieldVisibleForPayload — transitive showIf: a field is storable only when its\n// own condition passes AND the field its condition READS is itself storable\n// (e.g. vmsCommission is gated on isVMSRequired, which is gated on\n// contractType — on W2 all of them drop together even if stale values linger).\n// `index` maps field key → field config across every group; `seen` guards\n// against condition cycles.\nfunction fieldVisibleForPayload(field, scope, root, index, seen = new Set()) {\n if (!field?.showIf?.field) return true;\n if (seen.has(field.field)) return true; // cycle — fail open\n seen.add(field.field);\n if (!showIfSatisfied(field.showIf, scope, root)) return false;\n const gate = index?.get?.(field.showIf.field);\n return gate ? fieldVisibleForPayload(gate, scope, root, index, seen) : true;\n}\n\n// payloadFieldIndex — field key → field config across all groups, for the\n// transitive showIf walk above.\nfunction payloadFieldIndex(groups = []) {\n const index = new Map();\n groups.forEach((g) => (g.fields ?? []).forEach((f) => {\n if (f?.field && !index.has(f.field)) index.set(f.field, f);\n }));\n return index;\n}\n\n// rowDefaultsFor — the seed object for a brand-new addRow row: every non-file\n// field's configured defaultValue (e.g. VMS Commission 5.5, Rate Currency USD)\n// keyed by its form key. Used for a group's initial empty rows AND every row\n// the user adds, so admin defaults show inside repeatable groups too (top-level\n// fields already get theirs via Form.Item initialValue).\nexport function rowDefaultsFor(group = {}, { editing = false } = {}) {\n const seed = {};\n (group.fields ?? []).forEach((f) => {\n if (!f.field || f.type === 'file') return;\n if (editing && !f.defaultOnEdit) return;\n if (f.defaultValue === undefined || f.defaultValue === '') return;\n seed[f.field] = f.defaultValue;\n });\n return seed;\n}\n\n// ── field flattening from groups ──────────────────────────────────────────────\n\n/** All leaf fields across groups, with their group context (for addRow arrays). */\nexport function flattenFields(groups = []) {\n const out = [];\n groups.forEach((g) => {\n (g.fields ?? []).forEach((f) => {\n out.push({ field: f, group: g });\n });\n });\n return out;\n}\n\nexport function fileFields(groups = []) {\n return flattenFields(groups)\n .map(({ field }) => field)\n .filter((f) => f.type === 'file');\n}\n\n/**\n * collectFileParts — gather the NEW files the user picked, ready to append to a\n * multipart request, so create AND edit upload through the same gateway endpoint.\n *\n * Returns [{ formKey, file }]. The part name is the field's `fileKey` if set\n * (e.g. jobs reads \"file\"), else the first segment of its path\n * (\"passport.passportUploadName\" → \"passport\"). addRow groups fan out across\n * every row. Only fresh uploads (antd `originFileObj`, or a raw File/Blob) are\n * included — existing/stored files (url only) are left alone. Config-driven; no\n * field-name or module-specific logic.\n *\n * opts.indexed — when true, files inside an addRow group are emitted under an\n * INDEXED part name (\"documents[0]\", \"documents[1]\", …) where the index is the\n * row's position. EditForm uses this because the candidates update handler reads\n * document files by indexed key and aligns each file to its metadata row by\n * index.\n *\n * opts.scope — 'all' (default) | 'flat' | 'addRow'. Lets a caller collect only\n * the non-repeatable (flat) file fields, or only the repeatable (addRow) ones.\n * AddForm uploads flat files in the create request, then attaches addRow files\n * (e.g. candidate documents) in a follow-up update — the create handler for\n * repeatable document files is unreliable, while the indexed update path is the\n * proven one. Config-driven (keyed on the group's addRow flag), no module names.\n */\n// normalizeModuleKey trims + lower-cases a module key so a group's Target\n// Collection can be compared against the form's own module case-insensitively.\n//\n// It deliberately does NOT singularize (strip a trailing \"s\"). The gateway is\n// the source of truth for collection identity: it folds a moduleWrites entry\n// back into the main record only when the target resolves to the SAME physical\n// collection (foldSameCollectionModuleWrites → isSameCollectionTarget in\n// moduleCrudController.go), and its NormalizeFormGroupModule does not blindly\n// singularize either. A naive \"trainers\" → \"trainer\" fold here diverged from\n// that and silently merged a genuinely-distinct collection (e.g. \"trainers\")\n// into the primary record (e.g. module \"trainer\") — the exact multi-collection\n// bug. Exact-match keeps the FE from over-folding; any real same-collection\n// alias/plural case is folded server-side where the collection names are known.\nfunction normalizeModuleKey(module) {\n return String(module ?? '').trim().toLowerCase();\n}\n\n// isSameModuleTarget — the group's Target Collection is the form's own module\n// (exact, case-insensitive), i.e. the group writes to the MAIN record rather\n// than a linked document. Plural/alias targets that still resolve to the main\n// collection are folded by the gateway, not guessed here.\nfunction isSameModuleTarget(group, primaryKey) {\n return Boolean(primaryKey) && normalizeModuleKey(group.moduleName) === primaryKey;\n}\n\nexport function collectFileParts(values, groups = [], opts = {}) {\n const parts = [];\n const scope = opts.scope ?? 'all';\n const primaryKey = normalizeModuleKey(opts.module);\n const push = (formKey, node) => {\n if (node == null) return;\n const list = Array.isArray(node) ? node : [node];\n list.forEach((file) => {\n const raw = file?.originFileObj || file;\n if (typeof File !== 'undefined' && raw instanceof File) parts.push({ formKey, file: raw });\n else if (typeof Blob !== 'undefined' && raw instanceof Blob) parts.push({ formKey, file: raw });\n });\n };\n (groups ?? []).forEach((group) => {\n const files = (group.fields ?? []).filter((f) => f.type === 'file');\n if (!files.length) return;\n // A moduleWrites group's files must be routed to ITS collection, not the\n // primary record — prefixed so the gateway's applyModuleWrites can tell\n // them apart (see splitModuleWriteFiles / filesForModuleWrite server-side).\n // A group targeting the form's own module writes to the main record, so\n // its files stay unprefixed (mirrors buildPayload's targetFor).\n const routed = group.moduleName && !isSameModuleTarget(group, primaryKey);\n const keyFor = (baseKey) => (routed ? `__mw__${group.moduleName}__${baseKey}` : baseKey);\n if (group.addRow) {\n if (scope === 'flat') return;\n const rows = values[group.name];\n if (!Array.isArray(rows)) return;\n files.forEach((field) => {\n const baseKey = field.fileKey ?? String(field.field).split('.')[0];\n rows.forEach((row, rowIdx) => {\n const formKey = keyFor(opts.indexed ? `${baseKey}[${rowIdx}]` : baseKey);\n push(formKey, readFormValue(row, field.field));\n });\n });\n return;\n }\n if (scope === 'addRow') return;\n files.forEach((field) => {\n const formKey = keyFor(field.fileKey ?? String(field.field).split('.')[0]);\n push(formKey, readFormValue(values, field.field));\n });\n });\n return parts;\n}\n\n// ── the two public builders ───────────────────────────────────────────────────\n\n/**\n * buildPayload — config-driven payload object from antd form values.\n *\n * @param values the antd form values object (may contain dot-notation nesting,\n * Form.List arrays for addRow groups, and dayjs date objects)\n * @param groups normalised form groups (with the per-field payload config)\n * @param opts { base } optional base object to merge onto (edit keeps the\n * untouched parts of the original record)\n * @returns a plain payload object ready to JSON.stringify\n *\n * File-typed fields are skipped — the caller handles uploads separately.\n */\nexport function buildPayload(values, groups, opts = {}) {\n const payload = isPlainObject(opts.base) ? structuredClone(opts.base) : {};\n\n // Strip file fields out of any base so stale file arrays never ride along.\n fileFields(groups).forEach((f) => {\n if (f.payloadKey || f.field) {\n // best-effort removal at both the configured key and source key\n deleteDeep(payload, f.payloadKey || f.field);\n deleteDeep(payload, f.field);\n }\n });\n\n // moduleWrites — a group with `moduleName` set (Feature 1: Per-Group Target\n // Collection) is routed to a DIFFERENT collection than the default record,\n // so its fields build their OWN sub-payload instead of merging into\n // `payload`. Groups sharing the same moduleName merge into ONE entry — the\n // backend's applyModuleWrites (moduleCrudController.go) upserts them the\n // same way, into one secondary document per (primary record, moduleName).\n //\n // A target that IS the form's own module (opts.module) means \"the main\n // record\": routing it through moduleWrites would create a parentId-linked\n // TWIN document in the same collection, so it merges into `payload` instead.\n // The backend applies the same guard (foldSameCollectionModuleWrites).\n const primaryKey = normalizeModuleKey(opts.module);\n const fieldIndex = payloadFieldIndex(groups);\n const moduleWrites = new Map();\n const targetFor = (group) => {\n if (!group.moduleName || isSameModuleTarget(group, primaryKey)) return payload;\n if (!moduleWrites.has(group.moduleName)) moduleWrites.set(group.moduleName, {});\n return moduleWrites.get(group.moduleName);\n };\n\n (groups ?? []).forEach((group) => {\n const target = targetFor(group);\n const groupFields = group.fields ?? [];\n const groupToggleOn = group.toggleEnabled && group.toggleField && hasFormValue(values, group.toggleField)\n ? Boolean(readFormValue(values, group.toggleField))\n : false;\n if (group.toggleEnabled && group.toggleField && hasFormValue(values, group.toggleField)) {\n setDeep(target, group.toggleField, groupToggleOn);\n if (groupToggleOn && group.addRow) {\n setDeep(target, group.payloadKey || group.name, []);\n return;\n }\n }\n\n if (group.addRow) {\n // Repeatable group → ROW-oriented array of objects:\n // [{ fieldA: v, fieldB: v }, { ... }]\n // matching a Go []struct (e.g. workExperience, educationDetails, documents).\n // The output key is the group's payloadKey (the struct's array key, e.g.\n // \"workExperience\") falling back to the group name.\n const rows = values[group.name];\n // Not present in this submit (e.g. EditForm doesn't prefill Form.List) →\n // leave whatever the base record already has untouched.\n if (!Array.isArray(rows)) return;\n const outKey = group.payloadKey || group.name;\n const rowObjects = rows\n .map((row) => buildRowObject(groupFields, row, values, fieldIndex))\n .filter((obj) => obj && Object.keys(obj).length > 0);\n setDeep(target, outKey, rowObjects);\n return;\n }\n\n groupFields.forEach((field) => writeField(field, values, target, values, fieldIndex));\n });\n\n if (moduleWrites.size > 0) {\n payload.moduleWrites = Array.from(moduleWrites, ([moduleName, data]) => ({ moduleName, data }));\n }\n\n return securePayload(payload, groups);\n}\n\n// writeField — the single, shared rule for turning ONE field's value (read from\n// `scope`, which is the whole form values for a normal group or a single row\n// object for an addRow row) into its contribution on `target`. Used by both\n// buildPayload (top-level groups) and buildRowObject (addRow rows) so a field\n// behaves identically no matter how deeply it is nested — a repeatable\n// field-GROUP (subFields) or a repeatable scalar field (addRow) serialises to a\n// nested array the same way at any level. Config-driven; no field-name logic.\nfunction writeField(field, scope, target, root, fieldIndex) {\n if (field.type === 'file') return; // uploaded separately\n\n // showIf gating at PAYLOAD time: a field whose visibility condition fails is\n // not stored. antd preserves unmounted Form.Item values, so without this a\n // value typed before the condition flipped (e.g. VMS Commission after VMS\n // Required was unchecked) would silently ride along. Writing null (rather\n // than skipping) also clears the stale stored value on edit; inside an\n // addRow row the whole row array is rewritten anyway, so the key simply\n // drops out of the row object. Visibility is TRANSITIVE: a field whose gate\n // field is itself hidden drops too (fieldVisibleForPayload).\n if (field.showIf?.field && !fieldVisibleForPayload(field, scope, root, fieldIndex)) {\n // Top-level (scope === root): write null so an edit clears the stale\n // stored value. Row scope: the row array is rewritten wholesale, so simply\n // omitting the key removes it from the stored row.\n if ((root === undefined || root === scope) && hasFormValue(scope, field.field)) {\n setDeep(target, field.payloadKey || field.field, null);\n }\n return;\n }\n\n // Repeatable field-GROUP (subFields): each Form.List row is an object of the\n // sub-fields, so this field submits as an array of row objects —\n // [{question, answer}, …] — under its own payloadKey. Recurses so a nested\n // repeat group (e.g. inside an addRow row) is shaped element-by-element.\n if (Array.isArray(field.subFields) && field.subFields.length > 0) {\n if (!hasFormValue(scope, field.field)) return;\n const rows = readFormValue(scope, field.field);\n if (!Array.isArray(rows)) return;\n const rowObjects = rows\n .map((row) => buildRowObject(field.subFields, row, root, fieldIndex))\n .filter((obj) => obj && Object.keys(obj).length > 0);\n setDeep(target, field.payloadKey || field.field, rowObjects);\n return;\n }\n\n if (!hasFormValue(scope, field.field)) return; // not in this submit — leave base untouched\n\n // Repeatable SCALAR field (addRow, no subFields): each Form.List item is one\n // value, so normalise every element through the field's single-value shape\n // (dates → ISO, select → id) instead of relying on a blanket array coercion.\n // This makes a repeat field work INSIDE an addRow row (subjects[] per row) as\n // well as at the top level.\n if (truthy(field.addRow) && (!Array.isArray(field.subFields) || field.subFields.length === 0)) {\n const raw = readFormValue(scope, field.field);\n const arr = Array.isArray(raw) ? raw : isEmpty(raw) ? [] : [raw];\n const single = singleFieldOf(field);\n const out = arr\n .map((el) => shapeFieldValue(single, el))\n .filter((r) => r.kind !== 'skip')\n .map((r) => r.out);\n setDeep(target, field.payloadKey || field.field, out);\n return;\n }\n\n const raw = readFormValue(scope, field.field);\n const result = shapeFieldValue(field, raw);\n if (result.kind === 'skip') return;\n if (result.kind === 'spread' && isPlainObject(result.out)) {\n mergeDeep(target, result.out);\n return;\n }\n setDeep(target, field.payloadKey || field.field, result.out);\n}\n\n// buildRowObject — shape one addRow row into a plain object keyed by each\n// field's payloadKey/field (relative to the row). File fields are skipped (they\n// upload separately and their metadata is merged server-side).\nfunction buildRowObject(groupFields, row, root, fieldIndex) {\n const obj = {};\n groupFields.forEach((field) => writeField(field, row, obj, root ?? row, fieldIndex));\n return obj;\n}\n\nfunction deleteDeep(obj, path) {\n const parts = String(path).split('.');\n let cur = obj;\n for (let i = 0; i < parts.length - 1; i += 1) {\n if (!isPlainObject(cur[parts[i]])) return;\n cur = cur[parts[i]];\n }\n delete cur[parts[parts.length - 1]];\n}\n\n/**\n * buildInitialValue — reverse direction, for EditForm prefill.\n * Given a field config and the stored value (which may be a scalar, an\n * { id, value } reference, an { id, name } object, or an array of those),\n * returns the value the input control expects.\n *\n * - date/time fields → dayjs\n * - select/radio/checkbox → the id/value (single) or array of ids (multi)\n * - everything else → the scalar\n *\n * This replaces convertInitialValue's hardcoded field-name handling.\n */\nexport function buildInitialValue(field, stored) {\n const configuredEmpty = (value) => {\n const emptyValues = Array.isArray(field.emptyValues) ? field.emptyValues : [];\n return emptyValues.some((v) => String(v) === String(value));\n };\n const fallbackEditDefault = () =>\n field.defaultOnEdit && field.defaultValue !== undefined && field.defaultValue !== ''\n ? field.defaultValue\n : undefined;\n\n if (stored === undefined || stored === null) {\n return fallbackEditDefault() ?? stored;\n }\n if (configuredEmpty(stored)) {\n return fallbackEditDefault();\n }\n if (isEmpty(stored) && field.defaultOnEdit && field.defaultValue !== undefined && field.defaultValue !== '') {\n return field.defaultValue;\n }\n\n if (field.type === 'date' || field.type === 'time') {\n if (!stored || stored === '0001-01-01T00:00:00Z') return null;\n const p = dayjs(stored);\n return p.isValid() ? p : null;\n }\n\n const pickId = (item) => {\n if (isPlainObject(item)) {\n return (\n (field.valueKey && item[field.valueKey]) ??\n item.id ??\n item._id ??\n item.value ??\n item.userId ??\n item.recruiterId\n );\n }\n return item;\n };\n\n // Radio groups are ALWAYS single-select in the UI, even when the payload\n // dataType is \"array\" (e.g. jobRemoteStatus → []string). Prefill the scalar\n // so the selected radio shows; the payload engine re-wraps it to an array on\n // save via coerceDataType. Without this, a radio gets an array value and\n // renders with nothing selected.\n const isMulti = field.type === 'radio' ? false : effectiveDataType(field) === 'array';\n\n // A stored value that only differs from a static option by case (e.g. a\n // legacy \"active\" vs the configured option value \"Active\") would otherwise\n // match nothing and render as an unselected/empty control.\n const matchOptionCase = (v) => {\n if (v === undefined || v === null || v === '' || !Array.isArray(field.options)) return v;\n const match = field.options.find((option) => String(option?.value ?? '').toLowerCase() === String(v).toLowerCase());\n return match ? match.value : v;\n };\n\n if (field.type === 'select' || field.type === 'radio' || field.type === 'checkbox') {\n if (isMulti) {\n const arr = Array.isArray(stored) ? stored : [stored];\n return arr.map(pickId).map(matchOptionCase).filter((v) => v !== undefined && v !== null && v !== '' && !configuredEmpty(v));\n }\n const selected = matchOptionCase(Array.isArray(stored) ? pickId(stored[0]) : pickId(stored));\n return configuredEmpty(selected) ? fallbackEditDefault() : selected;\n }\n\n // checkbox group with a transformRule map (e.g. \"high\" → checked) is handled\n // by the caller via the same map; here we just pass the scalar through.\n return stored;\n}\n\n// singleFieldOf strips a repeatable (addRow) field down to its per-item shape:\n// each Form.List item holds ONE value, so multi/array coercion must NOT apply\n// when reading or rendering a single item. Preserves everything else (type,\n// options, datasource, validations) so the item control still behaves like the\n// field otherwise would.\nexport function singleFieldOf(field = {}) {\n return { ...field, addRow: false, multiSelect: false, mode: undefined, dataType: undefined };\n}\n\n// buildRepeatFieldInitial — the Form.List initialValue for a field-level repeat\n// (field.addRow). Unlike a repeatable GROUP (rows are objects), each item here\n// is a single scalar, so a stored array maps element-by-element through\n// buildInitialValue as if the field were single (see singleFieldOf). The result\n// is padded to minRows; when there is no stored value at all, initialRows\n// (falling back to minRows) empty inputs are shown so the user sees a starting\n// control instead of only a \"+\" button. Config keys mirror the group ones:\n// field.minRows / field.initialRows.\nexport function buildRepeatFieldInitial(field, stored) {\n const minRows = Math.max(0, Number(field.minRows ?? 0) || 0);\n const initialRows = field.initialRows !== undefined && field.initialRows !== ''\n ? Math.max(minRows, Math.max(0, Number(field.initialRows) || 0))\n : minRows;\n\n // Repeatable field-GROUP (subFields): each stored element is a row OBJECT, so\n // map every sub-field through buildInitialValue into a per-row object (mirrors\n // getAddRowInitialValue's group-addRow row mapping). Empty rows fall back to {}\n // so the sub-field controls still render.\n if (Array.isArray(field.subFields) && field.subFields.length > 0) {\n let rows = [];\n if (Array.isArray(stored)) {\n rows = stored.map((row) => {\n const out = {};\n field.subFields.forEach((sub) => {\n if (!sub.field || sub.type === 'file') return;\n const v = getDeep(row ?? {}, sub.field) ?? (row ?? {})[sub.field];\n if (v !== undefined && v !== null) out[sub.field] = buildInitialValue(sub, v);\n });\n return out;\n });\n }\n const target = rows.length > 0 ? minRows : Math.max(minRows, initialRows);\n while (rows.length < target) rows.push({});\n return rows;\n }\n\n const singleField = singleFieldOf(field);\n let items = [];\n if (Array.isArray(stored)) {\n items = stored\n .map((v) => buildInitialValue(singleField, v))\n .filter((v) => v !== undefined && v !== null && v !== '');\n } else if (stored !== undefined && stored !== null && stored !== '') {\n const v = buildInitialValue(singleField, stored);\n if (v !== undefined && v !== null && v !== '') items = [v];\n }\n\n const target = items.length > 0 ? minRows : Math.max(minRows, initialRows);\n while (items.length < target) items.push(undefined);\n return items;\n}\n\nexport default {\n buildPayload,\n buildInitialValue,\n showIfSatisfied,\n rowDefaultsFor,\n buildRepeatFieldInitial,\n singleFieldOf,\n shapeFieldValue,\n usesLabeledSelectValue,\n toSelectControlValue,\n coerceDataType,\n getDeep,\n setDeep,\n flattenFields,\n fileFields,\n};\n","// linkedAddRowGroups.js\n//\n// Pure helpers for group.linkGroup — an opt-in mechanism that keeps two or\n// more addRow groups' rows synchronized (same add/remove, same row count)\n// while each group keeps rendering as its own Card and submitting its own\n// independent payload array (buildPayload / buildAddRowInitial are untouched\n// and stay fully per-group — see payloadTransformer.js / applyGroupValues.js).\n//\n// A group only participates when BOTH group.addRow is true AND group.linkGroup\n// is a non-empty string shared by at least one other group. Every group that\n// predates this field (i.e. every group in production today) has no\n// linkGroup, so these helpers are a strict no-op for it.\n\nconst truthy = (value) => value === true || value === 1 || value === '1';\n\n// computeLinkedSets(groups) -> Map<linkGroupKey, { leaderName, memberNames: string[] }>\n//\n// `groups` is expected already order-sorted (normalizeGroups sorts by `order`\n// before render), so the first member encountered per key is the leader —\n// Array.prototype.sort is stable, so this matches the existing order\n// convention with no extra tie-break logic needed. A \"set\" of size 1 (nothing\n// else shares that linkGroup value) is dropped — a lone linkGroup value isn't\n// meaningfully linked to anything, and the group renders as if unlinked.\nexport function computeLinkedSets(groups = []) {\n const byKey = new Map();\n groups.forEach((group) => {\n const key = group?.linkGroup;\n if (!truthy(group?.addRow) || !key) return;\n if (!byKey.has(key)) byKey.set(key, []);\n byKey.get(key).push(group.name);\n });\n\n const sets = new Map();\n byKey.forEach((memberNames, key) => {\n if (memberNames.length < 2) return;\n sets.set(key, { leaderName: memberNames[0], memberNames });\n });\n return sets;\n}\n\n// findLinkedSet(linkedSets, groupName) -> { leaderName, memberNames } | null\n// Cheap membership lookup against an already-computed sets Map (compute once\n// per render via computeLinkedSets, look up per group here — avoids\n// recomputing the whole map on every group).\nexport function findLinkedSet(linkedSets, groupName) {\n for (const set of linkedSets.values()) {\n if (set.memberNames.includes(groupName)) return set;\n }\n return null;\n}\n\n// padLinkedInitialValues(linkedSets, initialValuesByGroupName) -> a new\n// { [groupName]: rows[] } object where every member of a linked set is padded\n// with {} placeholder rows up to the set's max length. Guards against\n// pre-existing data where two linked groups' stored `rows` happen to differ\n// in length (undefined territory otherwise — buildAddRowInitial/\n// getAddRowInitialValue compute each group's rows fully independently). A\n// no-op passthrough for any group not in a real (>=2 member) linked set.\nexport function padLinkedInitialValues(linkedSets, initialValuesByGroupName = {}) {\n const next = { ...initialValuesByGroupName };\n linkedSets.forEach(({ memberNames }) => {\n const maxLen = Math.max(...memberNames.map((name) => (next[name] ?? []).length));\n memberNames.forEach((name) => {\n const rows = next[name] ?? [];\n if (rows.length < maxLen) {\n next[name] = [...rows, ...Array.from({ length: maxLen - rows.length }, () => ({}))];\n }\n });\n });\n return next;\n}\n","import { ensureToken } from './authApi';\nimport { AUTH_URL } from './apiConfig';\n\n// ── AI Actions ──────────────────────────────────────────────────────────────\n// Generic, config-driven \"call an AI/automation service and get a JSON\n// response back\" call. The gateway resolves WHICH service/endpoint to hit\n// entirely from admin config (module/group/field/action) — this file never\n// carries a service URL, module name, or field name as a hardcoded value.\n\n/**\n * @param {Object} args\n * @param {string} args.module\n * @param {string} args.group - FormGroup.name the field lives in\n * @param {string} args.field - FormGroupField.field the action is attached to\n * @param {string} args.actionKey - AiActionConfig.key to run\n * @param {Object} [args.inputs] - { [param]: textValue } for this action's text inputs\n * @param {Object} [args.files] - { [param]: File } for this action's file inputs\n * @returns {Promise<{ raw: any, actionKey: string, responseMappings: any[] }>}\n */\nexport async function runAiAction({ module, group, field, actionKey, inputs = {}, files = {} }) {\n if (!module || !group || !field || !actionKey) {\n throw new Error('module, group, field and actionKey are required to run an AI action');\n }\n const token = await ensureToken();\n\n const formData = new FormData();\n formData.append('json', JSON.stringify({ inputs }));\n Object.entries(files).forEach(([param, file]) => {\n if (file) formData.append(param, file);\n });\n\n const params = new URLSearchParams({ module, group, field, action: actionKey });\n const res = await fetch(`${AUTH_URL}/ai-action?${params.toString()}`, {\n method: 'POST',\n headers: { Authorization: `Bearer ${token}` },\n body: formData,\n });\n\n const { logout } = await import('./authApi');\n if (res.status === 401) logout();\n\n const contentType = res.headers.get('content-type') || '';\n const data = contentType.includes('application/json') ? await res.json() : await res.text();\n\n if (!res.ok) {\n const error = new Error(data?.error || data?.message || `API ${res.status}: ${res.statusText}`);\n error.status = res.status;\n error.data = data;\n throw error;\n }\n\n return data?.data ?? data;\n}\n","// renderConfig — non-component shared module for the detail-view render engine.\n// Holds the Admin-facing option lists and the file/document resolution helpers,\n// kept out of the .jsx engine so React Fast Refresh stays happy and so other\n// modules (DocumentLink, the admin screen) can reuse them.\n\nimport { getDefaults } from '../../services/detailDefaults';\n\n// ── Admin option lists ───────────────────────────────────────────────────────\nexport const RENDER_TYPES = [\n { value: 'auto', label: 'Default (auto)' },\n { value: 'text', label: 'Text' },\n { value: 'tag', label: 'Tag' },\n { value: 'tags', label: 'Multi Tag (Skills)' },\n { value: 'badge', label: 'Badge' },\n { value: 'chip', label: 'Chip' },\n { value: 'document', label: 'Document' },\n { value: 'link', label: 'Link' },\n { value: 'email', label: 'Email' },\n { value: 'phone', label: 'Phone' },\n { value: 'date', label: 'Date' },\n { value: 'currency', label: 'Currency' },\n { value: 'budget', label: 'Budget' },\n { value: 'html', label: 'HTML' },\n];\n\nexport const DOCUMENT_MODES = [\n { value: 'preview', label: 'Preview (viewer)' },\n { value: 'download', label: 'Download button' },\n { value: 'link', label: 'Link (filename)' },\n { value: 'tag', label: 'Tag' },\n { value: 'text', label: 'Text (filename)' },\n];\n\nexport const TEXT_TRANSFORMS = [\n { value: 'none', label: 'None' },\n { value: 'upper', label: 'UPPERCASE' },\n { value: 'lower', label: 'lowercase' },\n { value: 'title', label: 'Title Case' },\n];\n\n// ── file / document resolution ───────────────────────────────────────────────\nconst LOC_EXACT = ['location', 'path', 'url', 'key'];\nconst LOC_SUFFIX = ['location', 'filepath', 'path', 'url', 'key'];\nconst NAME_SUFFIX = ['uploadedfilename', 'uploadname', 'originalname', 'displayname', 'documentname', 'filename'];\nconst NAME_LAST = ['name'];\nconst lc = (s) => String(s).toLowerCase();\nconst isEmpty = (v) => v === undefined || v === null || v === '';\n\nfunction pickExact(obj, keys) {\n for (const key of keys) {\n const v = obj[key];\n if (typeof v === 'string' && v) return v;\n }\n return '';\n}\n\nfunction pickSuffix(obj, suffixes) {\n for (const suffix of suffixes) {\n for (const [key, val] of Object.entries(obj)) {\n if (typeof val === 'string' && val && lc(key).endsWith(suffix)) return val;\n }\n }\n return '';\n}\n\nexport function fileNameFromPath(path) {\n if (!path) return '';\n const clean = String(path).split('?')[0].split('#')[0];\n return decodeURIComponent(clean.split('/').pop() || '');\n}\n\nexport function buildFileUrl(location) {\n if (!location) return '';\n const loc = String(location);\n if (/^https?:\\/\\//i.test(loc)) return loc;\n const base = getDefaults().s3BaseUrl || '';\n return base ? `${base}/${loc.replace(/^\\/+/, '')}` : '';\n}\n\nexport function locationOf(doc) {\n if (typeof doc === 'string') return doc.includes('/') ? doc : '';\n if (!doc || typeof doc !== 'object') return '';\n return pickExact(doc, LOC_EXACT) || pickSuffix(doc, LOC_SUFFIX);\n}\n\nexport function docDisplayName(doc) {\n if (!doc) return 'Document';\n if (typeof doc === 'string') return fileNameFromPath(doc) || doc;\n if (typeof doc !== 'object') return 'Document';\n const order = getDefaults().documentNameOrder ?? [];\n return (\n pickExact(doc, order) ||\n pickSuffix(doc, NAME_SUFFIX) ||\n fileNameFromPath(locationOf(doc)) ||\n pickSuffix(doc, NAME_LAST) ||\n 'Document'\n );\n}\n\n// extractDocuments flattens any file-field value (array | object | string) into\n// a list of { location, name, url }.\nexport function extractDocuments(value) {\n if (isEmpty(value)) return [];\n const items = Array.isArray(value) ? value : [value];\n const out = [];\n for (const item of items) {\n if (isEmpty(item)) continue;\n if (typeof item === 'string') {\n const location = item.includes('/') ? item : '';\n out.push({ location, name: fileNameFromPath(item) || item, url: buildFileUrl(location) });\n } else if (typeof item === 'object') {\n const location = locationOf(item);\n // A doc from the central `documents` collection already carries a 24h\n // presigned download URL (fileUrl) — prefer it over rebuilding from the\n // S3 base, so private-bucket files open correctly.\n const presigned = item.fileUrl || item.downloadUrl || item.signedUrl || '';\n out.push({ location, name: docDisplayName(item), url: presigned || buildFileUrl(location) });\n }\n }\n return out;\n}\n","// applyGroupValues — the SINGLE place that turns a `groups` array (each field\n// carrying `.value`, each addRow group carrying `.rows`) into antd form state.\n//\n// This is the exact mechanism Edit-prefill has always used (getFormGroups with\n// an `id` embeds field.value/group.rows server-side via AttachFieldValues).\n// It's extracted here so any OTHER source of the same shape — notably an AI\n// Action's response, which the gateway resolves through the identical\n// AttachFieldValues engine — can be applied to the form with the same code,\n// instead of maintaining a second, parallel field-mapping implementation.\nimport { buildInitialValue, buildRepeatFieldInitial, getDeep, rowDefaultsFor } from './payloadTransformer';\n\n// truthy tolerates the boolean-ish shapes a config flag can arrive in.\nconst isTruthyFlag = (v) => v === true || v === 1 || v === '1';\nimport { buildFileUrl } from '../detail/renderConfig';\n\nconst empty = (v) => v === undefined || v === null || v === '';\n\nexport function namePathFromString(path) {\n return String(path ?? '').split('.').map((part) => part.trim()).filter(Boolean);\n}\n\nexport function writeFormValue(target, path, value) {\n const parts = Array.isArray(path) ? path : namePathFromString(path);\n if (!parts.length) return target;\n let cursor = target;\n for (let i = 0; i < parts.length - 1; i += 1) {\n const key = parts[i];\n if (!cursor[key] || typeof cursor[key] !== 'object' || Array.isArray(cursor[key])) cursor[key] = {};\n cursor = cursor[key];\n }\n cursor[parts[parts.length - 1]] = value;\n return target;\n}\n\nfunction firstConfiguredValue(source, keys = []) {\n if (!source || typeof source !== 'object') return undefined;\n for (const key of keys) {\n if (!key) continue;\n const val = getDeep(source, key);\n if (!empty(val)) return val;\n }\n return undefined;\n}\n\nfunction firstMatchingValue(source, pattern) {\n if (!source || typeof source !== 'object') return undefined;\n const entries = Object.entries(source);\n const direct = entries.find(([key, val]) => pattern.test(key) && !empty(val));\n if (direct) return direct[1];\n for (const [, val] of entries) {\n if (val && typeof val === 'object' && !Array.isArray(val)) {\n const nested = firstMatchingValue(val, pattern);\n if (!empty(nested)) return nested;\n }\n }\n return undefined;\n}\n\n// fileListFromValue — turn a file field's embedded value (from getFormGroups,\n// or an AI response resolved the same way) into the antd fileList the file\n// control expects. The value may be a full document object ({ location,\n// uploadName/name, uniqueName }), a bare original filename string, or an\n// array of either. Returns undefined when empty.\nexport function fileListFromValue(stored, field) {\n const list = Array.isArray(stored) ? stored : (stored ? [stored] : []);\n if (!list.length) return undefined;\n const mapped = list.map((f, i) => {\n if (typeof f === 'string') {\n return { uid: `${field.field}-${i}`, name: f, status: 'done' };\n }\n if (!f || typeof f !== 'object') return null;\n const rawUrl = firstConfiguredValue(f, [field.fileUrlKey, field.locationKey])\n ?? firstMatchingValue(f, /(location|url|path)$/i)\n ?? '';\n const fileName = firstConfiguredValue(f, [field.fileNameKey])\n ?? firstMatchingValue(f, /(uploadName|uploadedFileName|fileName|name)$/i)\n ?? '';\n // A stored object with no usable url AND no real filename carries no actual\n // file (e.g. an all-null document sub-object from a parsed AI response) —\n // skip it rather than showing a bogus \"file\" chip with nothing behind it.\n if (!rawUrl && !fileName) return null;\n const fullUrl = rawUrl && !String(rawUrl).startsWith('http')\n ? buildFileUrl(rawUrl)\n : rawUrl;\n return {\n uid: String(f.id ?? f._id ?? f.uniqueName ?? f.documentCopyUniqueName ?? `${field.field}-${i}`),\n name: fileName || 'file',\n status: 'done',\n existing: true,\n url: fullUrl || undefined,\n };\n }).filter(Boolean);\n return mapped.length ? mapped : undefined;\n}\n\n// buildRowFileList — turn an addRow row's stored file metadata into the antd\n// fileList. Returns undefined when the row has no file.\nexport function buildRowFileList(row, field) {\n if (!row || typeof row !== 'object') return undefined;\n const name = firstConfiguredValue(row, [field.fileNameKey, field.field])\n ?? firstMatchingValue(row, /(uploadName|uploadedFileName|fileName|name)$/i);\n const rawUrl = firstConfiguredValue(row, [field.fileUrlKey, field.locationKey])\n ?? firstMatchingValue(row, /(location|url|path)$/i)\n ?? '';\n if (!name && !rawUrl) return undefined;\n const fullUrl = rawUrl && !String(rawUrl).startsWith('http')\n ? buildFileUrl(rawUrl)\n : rawUrl;\n const uid = row.documentCopyUniqueName ?? row.uniqueName ?? name ?? `${field.field}-0`;\n return [{\n uid: String(uid),\n name: name ?? 'file',\n status: 'done',\n existing: true,\n url: fullUrl || undefined,\n }];\n}\n\n// buildAddRowInitial — turn a repeatable (addRow) group's backend-embedded\n// stored rows (group.rows) into the Form.List initialValue shape: an array\n// with ONE object per stored row, each mapped through buildInitialValue (file\n// fields via the row's sibling keys). Returns [] when the group has no stored\n// rows, padded to group.minRows.\nexport function buildAddRowInitial(group) {\n const storedRows = Array.isArray(group.rows) ? group.rows : null;\n const minRows = Math.max(0, Number(group.minRows ?? 0) || 0);\n const mapRow = (row, readFile, readScalar) => {\n const rowVals = {};\n (group.fields ?? []).forEach((field) => {\n if (!field.field) return;\n if (field.type === 'file') {\n const fileList = readFile(row, field);\n if (fileList) writeFormValue(rowVals, field.field, fileList);\n return;\n }\n const stored = readScalar(row, field);\n if (stored === undefined || stored === null) {\n // Row has no stored value — an admin defaultOnEdit default still shows\n // (e.g. VMS Commission 5.5 on rows saved before the field existed).\n if (field.defaultOnEdit && field.defaultValue !== undefined && field.defaultValue !== '') {\n writeFormValue(rowVals, field.field, field.defaultValue);\n }\n return;\n }\n // A repeat field inside the row (nested Form.List) hydrates as an array,\n // each element normalised for its control; a plain field as a single value.\n writeFormValue(rowVals, field.field, isTruthyFlag(field.addRow)\n ? buildRepeatFieldInitial(field, stored)\n : buildInitialValue(field, stored));\n });\n return rowVals;\n };\n\n const padSeed = rowDefaultsFor(group, { editing: true });\n if (storedRows && storedRows.length > 0) {\n const rows = storedRows.map((row) => mapRow(\n row,\n (r, field) => buildRowFileList(r, field),\n (r, field) => getDeep(r, field.field),\n ));\n while (rows.length < minRows) rows.push({ ...padSeed });\n return rows;\n }\n\n // Fallback for an older backend that embeds only per-field field.value (row 0).\n const rowVals = mapRow(\n group,\n (_g, field) => fileListFromValue(field.value, field),\n (_g, field) => field.value,\n );\n const rows = Object.keys(rowVals).length > 0 ? [rowVals] : [];\n while (rows.length < minRows) rows.push({ ...padSeed });\n return rows;\n}\n\n// applyScalarFieldValues — walk every NON-addRow group's fields, read each\n// field's embedded `.value`, shape it (buildInitialValue / fileListFromValue /\n// checkbox-transformRule reversal), and set it on the form in one batch.\n// AddRow groups are skipped — their rows only apply correctly as a Form.List\n// `initialValue` at mount (or via an explicit remount for a post-mount\n// update), never via setFieldsValue.\nexport function applyScalarFieldValues(form, groups = []) {\n const values = {};\n\n groups.forEach((group) => {\n if (group.toggleEnabled && group.toggleField) {\n writeFormValue(values, group.toggleField, Boolean(group.toggleValue));\n }\n if (group.addRow) return;\n\n (group.fields ?? []).forEach((field) => {\n if (!field.field) return;\n // A repeatable (addRow) field prefills via its own Form.List initialValue\n // at mount (buildRepeatFieldInitial) — setFieldsValue on a Form.List that\n // mounted empty only keeps the last item, so skip it here.\n if (field.addRow) return;\n const stored = field.value;\n const name = field.field;\n\n if (field.type === 'file') {\n const fileList = fileListFromValue(stored, field);\n if (fileList) writeFormValue(values, name, fileList);\n return;\n }\n\n if (stored === undefined || stored === null) return;\n\n if (field.type === 'checkbox' && Array.isArray(field.options) && field.options.length > 0) {\n const map = field.transformRule?.map;\n if (map) {\n const match = Object.entries(map).find(([, to]) => String(to) === String(stored));\n writeFormValue(values, name, match ? [match[0]] : []);\n } else {\n writeFormValue(values, name, Array.isArray(stored) ? stored : [stored]);\n }\n return;\n }\n\n writeFormValue(values, name, buildInitialValue(field, stored));\n });\n });\n\n if (Object.keys(values).length > 0) form.setFieldsValue(values);\n return values;\n}\n","import { useCallback, useState } from 'react';\nimport { Form, Modal, message } from 'antd';\nimport { runAiAction } from '../../services/aiActionApi';\nimport { applyScalarFieldValues, buildAddRowInitial } from './applyGroupValues';\n\nfunction stripHtml(html) {\n const div = document.createElement('div');\n div.innerHTML = String(html ?? '');\n return div.textContent || div.innerText || '';\n}\n\nfunction applyTransform(value, transform) {\n if (!transform) return value;\n if (transform === 'stripHtml') return stripHtml(value);\n return value;\n}\n\nfunction wordCount(text) {\n return String(text ?? '').trim().split(/\\s+/).filter(Boolean).length;\n}\n\nfunction rowHasData(row) {\n return Object.values(row || {}).some((v) => v !== undefined && v !== null && v !== '');\n}\n\n// isInputSatisfied — an input \"counts\" once it has real content: a file\n// present for kind \"file\", or non-empty (post-transform) text for kind\n// \"text\" that also meets the input's own MinWords, if configured.\nfunction isInputSatisfied(input, rawValue) {\n if (input.kind === 'file') {\n return Array.isArray(rawValue) ? rawValue.length > 0 : Boolean(rawValue);\n }\n const text = applyTransform(rawValue, input.transform);\n const str = String(text ?? '').trim();\n if (!str) return false;\n const minWords = Number(input.minWords) || 0;\n return minWords > 0 ? wordCount(str) >= minWords : true;\n}\n\n// computeActionEnabled — an action is disabled until every GATED input is\n// satisfied. An input gates the button when it's marked Required, or has a\n// MinWords requirement (>0) — a plain optional input never gates. Inputs\n// sharing a Group (e.g. \"either a JD file or JD text\") gate as one unit: the\n// group is satisfied once ANY member of it is satisfied.\nfunction computeActionEnabled(action, getValue) {\n const inputs = action.inputs || [];\n if (inputs.length === 0) return true;\n\n const groupsMap = new Map();\n inputs.forEach((input, i) => {\n const key = input.group || `__solo_${i}`;\n if (!groupsMap.has(key)) groupsMap.set(key, []);\n groupsMap.get(key).push(input);\n });\n\n for (const groupInputs of groupsMap.values()) {\n const gates = groupInputs.some((i) => i.required || Number(i.minWords) > 0);\n if (!gates) continue;\n const satisfied = groupInputs.some((i) => isInputSatisfied(i, getValue(i.sourceField)));\n if (!satisfied) return false;\n }\n return true;\n}\n\nconst AI_ACTION_POSITIONS = ['top-left', 'top-center', 'top-right', 'bottom-left', 'bottom-center', 'bottom-right'];\nconst DEFAULT_AI_ACTION_POSITION = 'bottom-left';\n\n// groupActionsByPosition — buckets a field's click-triggered AI actions by\n// their admin-configured Position (blank/unknown falls back to the original\n// \"bottom-left\" layout), so the caller can render each bucket in its own\n// slot around the field with the right alignment.\nexport function groupActionsByPosition(actions = []) {\n const buckets = {};\n actions.forEach((action) => {\n const pos = AI_ACTION_POSITIONS.includes(action.position) ? action.position : DEFAULT_AI_ACTION_POSITION;\n (buckets[pos] ??= []).push(action);\n });\n return buckets;\n}\n\nexport { AI_ACTION_POSITIONS };\n\n/**\n * useAiActions — shared logic behind config-driven \"AI Action\" buttons\n * (Generate/Parse-style: send some form fields to an admin-configured\n * service, get back the SAME `{groups: [...]}` shape getFormGroups returns\n * for Edit prefill, and apply it to the form via the same shared functions).\n * Used identically by AddFormV1 and EditFormV1 so the apply logic isn't\n * duplicated.\n *\n * @param {Object} args\n * @param {import('antd').FormInstance} args.form\n * @param {Array} args.groups - the module's form groups (for input lookups)\n * @param {string} args.module\n */\nexport default function useAiActions({ form, groups, module }) {\n const [loadingKey, setLoadingKey] = useState(null);\n // Re-renders whenever ANY field changes, so isActionEnabled below reflects\n // live typing/upload without needing to know in advance which field names\n // any given action reads from (fully config-driven, no hardcoded paths).\n const watchedValues = Form.useWatch((values) => values, form);\n\n const isActionEnabled = useCallback(\n (action) => computeActionEnabled(action, (sourceField) => (watchedValues || {})[sourceField]),\n [watchedValues],\n );\n\n // Returns whether anything was actually applied to the form, so the caller\n // can show an accurate success vs. \"nothing found\" message — generic to any\n // action/module, since it only looks at what the response itself contained.\n const applyResponse = useCallback((responseGroups) => {\n if (!Array.isArray(responseGroups) || responseGroups.length === 0) return false;\n\n const scalarValues = applyScalarFieldValues(form, responseGroups.filter((g) => !g.addRow));\n let appliedAny = Object.keys(scalarValues).length > 0;\n\n responseGroups.forEach((group) => {\n if (!group.addRow) return;\n if (!Array.isArray(group.rows) || group.rows.length === 0) return;\n\n const shapedRows = buildAddRowInitial(group);\n if (shapedRows.length === 0) return;\n appliedAny = true;\n\n // A mounted Form.List's field name is already registered in the Form's\n // store (even with an empty array) — setFieldsValue is what antd\n // documents for a post-mount update; it re-renders the List with the\n // new rows directly, no remount trick needed.\n const applyRows = () => form.setFieldsValue({ [group.name]: shapedRows });\n\n const existingRows = form.getFieldValue(group.name) || [];\n if (existingRows.some(rowHasData)) {\n Modal.confirm({\n title: 'Replace existing rows?',\n content: `This will replace ${existingRows.length} existing row(s) in \"${group.label || group.name}\".`,\n okText: 'Replace',\n cancelText: 'Cancel',\n onOk: applyRows,\n });\n } else {\n applyRows();\n }\n });\n\n return appliedAny;\n }, [form]);\n\n const runAction = useCallback(async (groupName, field, action, extraFile) => {\n setLoadingKey(action.key);\n try {\n const inputs = {};\n const files = {};\n\n (action.inputs || []).forEach((input) => {\n if (input.kind === 'file') {\n const fromFileList = form.getFieldValue(input.sourceField);\n const file = extraFile ?? fromFileList?.[fromFileList.length - 1]?.originFileObj;\n if (file) files[input.param] = file;\n } else {\n const raw = form.getFieldValue(input.sourceField);\n if (raw !== undefined && raw !== null && raw !== '') {\n inputs[input.param] = applyTransform(raw, input.transform);\n }\n }\n });\n // Within a shared input Group (e.g. \"either a JD file or JD text\"), a\n // file input wins — drop the sibling text input if both are present.\n (action.inputs || []).forEach((input) => {\n if (!input.group || input.kind !== 'text') return;\n const fileSiblingProvided = (action.inputs || [])\n .some((i) => i.group === input.group && i.kind === 'file' && files[i.param]);\n if (fileSiblingProvided) delete inputs[input.param];\n });\n\n const result = await runAiAction({\n module, group: groupName, field: field.field, actionKey: action.key, inputs, files,\n });\n const appliedAny = applyResponse(result?.groups);\n const label = action.label || 'AI action';\n if (appliedAny) {\n message.success(`${label} completed successfully.`);\n } else {\n message.info(`${label} completed, but no matching details were found.`);\n }\n return result;\n } catch (error) {\n message.error(error?.message || `${action.label || 'AI action'} failed`);\n return undefined;\n } finally {\n setLoadingKey(null);\n }\n }, [form, module, applyResponse]);\n\n return { runAction, loadingKey, busy: loadingKey !== null, isActionEnabled };\n}\n","import { Button, Space } from 'antd';\n\n// AiActionButtonGroup — renders one position bucket (\"top-left\", \"bottom-right\",\n// etc.) of a field's AI action buttons, admin-configured entirely via each\n// action's `position`. Horizontal alignment follows the position's own\n// left/center/right suffix; the caller places top vs. bottom buckets around\n// the field itself.\nexport default function AiActionButtonGroup({ position, actions, aiActions, groupName, field }) {\n if (!actions || actions.length === 0) return null;\n\n const justifyContent = position.endsWith('center')\n ? 'center'\n : position.endsWith('right')\n ? 'flex-end'\n : 'flex-start';\n\n return (\n <Space size={8} className=\"v1-ai-action-buttons\" style={{ width: '100%', justifyContent }}>\n {actions.map((action) => (\n <Button\n key={action.key}\n size=\"small\"\n loading={aiActions.loadingKey === action.key}\n disabled={aiActions.busy || !aiActions.isActionEnabled(action)}\n onClick={() => aiActions.runAction(groupName, field, action)}\n >\n {action.label}\n </Button>\n ))}\n </Space>\n );\n}\n","// Generic email rule used by Add/Edit forms and the real-time input validator.\n// The rule is selected through the DB validation type `email`; it contains no\n// module or field-name assumptions.\nexport function isValidConfiguredEmail(value) {\n const email = String(value ?? '').trim();\n const match = /^([^\\s@]+)@([^\\s@]+)\\.([A-Za-z]{2,})$/.exec(email);\n if (!match) return false;\n\n const [, localPart, domainHost] = match;\n return /[A-Za-z]/.test(localPart) && /[A-Za-z]/.test(domainHost);\n}\n\nexport function configuredEmailRule(label = 'Email', message) {\n return {\n validator: (_, value) => {\n if (value === undefined || value === null || value === '') return Promise.resolve();\n return isValidConfiguredEmail(value)\n ? Promise.resolve()\n : Promise.reject(new Error(message ?? `Enter a valid ${label}; numeric-only email addresses are not allowed`));\n },\n };\n}\n","// inputValidator.js — config-driven real-time input restriction engine.\n// Driven entirely by field.validator in formGroupConfig — no hardcoding.\n// Used by FieldControl in AddFormV1 and EditFormV1.\n\nimport { isValidConfiguredEmail } from './emailValidator';\n\nexport const INPUT_VALIDATOR_TYPES = [\n { label: 'Only Numbers', value: 'onlyNumber' },\n { label: 'Only Letters', value: 'onlyLetter' },\n { label: 'Only Letters & Spaces', value: 'onlyLettersAndSpace' },\n { label: 'Only Alphanumeric', value: 'onlyAlphanumeric' },\n { label: 'Letters, Numbers & Hyphen', value: 'onlyLettersNumberAndHyphen' },\n { label: 'Letters, Numbers, Hyphen & Dot', value: 'onlyLettersNumberHyphenAndDot' },\n { label: 'Contact Number (digits, (), -)', value: 'contactNumber' },\n { label: 'Email (reject numeric-only address)', value: 'email' },\n { label: 'Job Title (letters, nums, symbols)', value: 'jobTitle' },\n { label: 'MSP / Ref ID (alphanumeric only)', value: 'mspRefId' },\n { label: 'Location (letters, nums, , . -)', value: 'locationValidation' },\n { label: 'Decimal / Range (number + dot)', value: 'decimalRange' },\n { label: 'Budget (numbers, must be > 0)', value: 'budgetValidation' },\n { label: 'Experience (numbers only)', value: 'experience' },\n { label: 'Numeric — 2 digits max', value: 'numericTwoDigits' },\n { label: 'Job Description (character count)', value: 'jobDescription' },\n { label: 'Website URL', value: 'websiteUrl' },\n];\n\n// onKeyPress allowlist patterns — used to block invalid chars before they appear.\n// null means no per-key blocking for that type.\nconst KEY_PATTERNS = {\n onlyNumber: /^[0-9]$/,\n experience: /^[0-9]$/,\n numericTwoDigits: /^[0-9]$/,\n budgetValidation: /^[0-9]$/,\n onlyLetter: /^[a-zA-Z\\s]$/,\n onlyLettersAndSpace: /^[a-zA-Z\\s]$/,\n onlyAlphanumeric: /^[a-zA-Z0-9]$/,\n mspRefId: /^[a-zA-Z0-9]$/,\n onlyLettersNumberAndHyphen: /^[a-zA-Z0-9\\s-]$/,\n locationValidation: /^[a-zA-Z0-9\\s\\-.,]$/,\n jobTitle: /^[a-zA-Z0-9\\s\\-.,/&+()*'\"#@]$/,\n decimalRange: /^[0-9.]$/,\n contactNumber: /^[0-9()\\-+\\s]$/,\n};\n\nexport function getKeyPattern(type) {\n return KEY_PATTERNS[type] ?? null;\n}\n\n// applyInputValidator — clean a raw input value according to the validator config.\n// Returns { cleaned: string, error: string|null }.\n// eventType 'blur' triggers trim; 'change' only strips leading whitespace.\nexport function applyInputValidator(rawValue, config = {}, eventType = 'change') {\n if (!config?.type || rawValue === undefined || rawValue === null) {\n return { cleaned: rawValue ?? '', error: null };\n }\n\n const value = String(rawValue);\n const { type, maxLength, maxChars } = config;\n const title = config.title || 'Field';\n let cleaned;\n let error = null;\n\n const trimStart = (s) => (eventType === 'blur' ? s.trim() : s.replace(/^\\s+/, ''));\n\n switch (type) {\n case 'onlyNumber':\n case 'experience':\n case 'numericTwoDigits': {\n const limit = Number(maxLength ?? (type === 'numericTwoDigits' ? 2 : 10));\n cleaned = value.replace(/[^0-9]/g, '');\n if (value !== cleaned) error = `${title} allows only numbers.`;\n if (cleaned.length > limit) {\n error = `${title} cannot exceed ${limit} characters.`;\n cleaned = cleaned.slice(0, limit);\n }\n break;\n }\n\n case 'onlyLetter': {\n const limit = Number(maxLength ?? 50);\n cleaned = value.replace(/[^a-zA-Z]/g, '');\n if (value !== cleaned) error = `${title} allows only letters.`;\n if (cleaned.length > limit) { error = `${title} cannot exceed ${limit} characters.`; cleaned = cleaned.slice(0, limit); }\n break;\n }\n\n case 'onlyLettersAndSpace': {\n const limit = Number(maxLength ?? 55);\n cleaned = trimStart(value.replace(/[^a-zA-Z\\s]/g, ''));\n if (value.replace(/^\\s+/, '') !== cleaned) error = `${title} allows only letters and spaces.`;\n if (cleaned.length > limit) { error = `${title} cannot exceed ${limit} characters.`; cleaned = cleaned.slice(0, limit); }\n break;\n }\n\n case 'onlyAlphanumeric':\n case 'mspRefId': {\n const limit = Number(maxLength ?? 50);\n cleaned = trimStart(value.replace(/[^a-zA-Z0-9]/g, ''));\n if (value.replace(/^\\s+/, '') !== cleaned) error = `${title} allows only letters and numbers.`;\n if (cleaned.length > limit) { error = `${title} cannot exceed ${limit} characters.`; cleaned = cleaned.slice(0, limit); }\n break;\n }\n\n case 'onlyLettersNumberAndHyphen': {\n const limit = Number(maxLength ?? 55);\n cleaned = trimStart(value.replace(/[^a-zA-Z0-9\\s-]/g, ''));\n if (value.replace(/^\\s+/, '') !== cleaned) error = `${title} allows only letters, numbers and hyphens.`;\n if (cleaned.length > limit) { error = `${title} cannot exceed ${limit} characters.`; cleaned = cleaned.slice(0, limit); }\n break;\n }\n\n case 'onlyLettersNumberHyphenAndDot': {\n const limit = Number(maxLength ?? 100);\n cleaned = value.replace(/[^a-zA-Z0-9\\-./#+[\\]{}()\\s]/g, '').slice(0, limit);\n if (value !== cleaned) error = `${title} allows only letters, numbers, hyphens and dots.`;\n break;\n }\n\n case 'contactNumber': {\n const limit = Number(maxLength ?? 15);\n cleaned = value.replace(/[^0-9()\\-+\\s]/g, '').slice(0, limit);\n const re = /^(\\+?[0-9]{1,3}[- ]?)?(\\(?\\d{1,4}\\)?[- ]?)?[\\d\\-\\s]{3,15}$/;\n if (value !== cleaned) error = `${title} allows only digits, parentheses () and hyphens.`;\n else if (cleaned && !re.test(cleaned)) error = `${title} is not a valid phone number format.`;\n break;\n }\n\n case 'locationValidation': {\n const limit = Number(maxLength ?? 100);\n cleaned = trimStart(value.replace(/[^a-zA-Z0-9\\s\\-.,]/g, ''));\n if (value.replace(/^\\s+/, '') !== cleaned) error = `${title} allows only letters, numbers, spaces, commas, dots and hyphens.`;\n if (cleaned.length > limit) { error = `${title} cannot exceed ${limit} characters.`; cleaned = cleaned.slice(0, limit); }\n break;\n }\n\n case 'jobTitle': {\n const limit = Number(maxLength ?? 80);\n cleaned = trimStart(value.replace(/[^a-zA-Z0-9\\s\\-/&.,()+#@'\"*]/g, ''));\n if (value.replace(/^\\s+/, '') !== cleaned) error = `${title} allows only letters, numbers, spaces and common symbols.`;\n if (cleaned.length > limit) { error = `${title} cannot exceed ${limit} characters.`; cleaned = cleaned.slice(0, limit); }\n break;\n }\n\n case 'decimalRange': {\n let c = value.replace(/[^0-9.]/g, '');\n const dotCount = (c.match(/\\./g) || []).length;\n if (dotCount > 1) {\n const di = c.indexOf('.');\n c = c.slice(0, di + 1) + c.slice(di + 1).replace(/\\./g, '');\n error = `${title} can have only one decimal point.`;\n }\n const digits = c.replace(/\\./g, '');\n const limit = Number(maxLength ?? 10);\n if (digits.length > limit) {\n c = c.slice(0, limit + (c.includes('.') ? 1 : 0));\n error = `${title} cannot exceed ${limit} digits.`;\n }\n cleaned = c;\n if (!error && value !== cleaned) error = `${title} allows only numbers and one dot.`;\n break;\n }\n\n case 'budgetValidation': {\n const limit = Number(maxLength ?? 10);\n cleaned = value.replace(/[^0-9]/g, '').slice(0, limit);\n const num = Number(cleaned);\n if (value !== cleaned) error = `${title} allows only numbers.`;\n else if (cleaned && num <= 0) error = `${title} must be greater than 0.`;\n break;\n }\n\n case 'jobDescription': {\n const limit = Number(maxChars ?? maxLength ?? 1500);\n const plain = value\n .replace(/<[^>]+>/g, ' ')\n .replace(/&nbsp;/g, ' ')\n .replace(/\\s+/g, ' ')\n .trim();\n if (plain.length > limit) error = `${title} cannot exceed ${limit} characters.`;\n cleaned = value; // never truncate HTML content\n break;\n }\n\n case 'email': {\n cleaned = eventType === 'blur' ? value.trim() : value;\n if (cleaned && !isValidConfiguredEmail(cleaned)) {\n error = `${title} must be a valid email address; numeric-only email addresses are not allowed.`;\n }\n break;\n }\n\n case 'websiteUrl': {\n cleaned = eventType === 'blur' ? value.trim() : value;\n const urlRe = /^(https?:\\/\\/)?([\\da-z.-]+)\\.([a-z.]{2,6})([/\\w .-]*)*\\/?$/i;\n if (cleaned && !urlRe.test(cleaned)) error = `${title} must be a valid URL.`;\n break;\n }\n\n default:\n cleaned = value;\n }\n\n return { cleaned, error };\n}\n","// Admin-configurable upload content categories. The Form Groups admin stores a\n// category key on a file field (`field.accept`); AddFormV1/EditFormV1 expand it\n// to the browser `accept` attribute and a beforeUpload extension check, so a\n// file outside the category is rejected client-side with a clear message.\n// A field without a category (or 'any') falls back to the fine-grained\n// `fileType` validation rule, preserving existing behaviour.\n\nconst IMAGE_EXTS = ['jpg', 'jpeg', 'png', 'gif', 'webp', 'bmp', 'svg', 'avif'];\n// Mirrors DocumentViewer's VIDEO_EXT so anything uploadable is also previewable.\nconst VIDEO_EXTS = ['mp4', 'webm', 'ogg', 'ogv', 'mov', 'm4v'];\nconst DOC_EXTS = ['pdf', 'doc', 'docx'];\n\nexport const UPLOAD_ACCEPT_OPTIONS = [\n { label: 'Any file', value: 'any' },\n { label: 'Documents & Images (pdf, doc, images)', value: 'documents' },\n { label: 'Images only', value: 'images' },\n { label: 'Videos only', value: 'videos' },\n { label: 'Images & Videos', value: 'imagesAndVideos' },\n];\n\nexport const UPLOAD_ACCEPT_CATEGORIES = {\n documents: {\n exts: [...DOC_EXTS, ...IMAGE_EXTS],\n hint: 'PDF, DOC or image files',\n error: 'Only document (PDF/DOC) or image files are allowed',\n },\n images: {\n exts: IMAGE_EXTS,\n hint: 'Image files',\n error: 'Only image files are allowed',\n },\n videos: {\n exts: VIDEO_EXTS,\n hint: 'Video files',\n error: 'Only video files are allowed',\n },\n imagesAndVideos: {\n exts: [...IMAGE_EXTS, ...VIDEO_EXTS],\n hint: 'Image or video files',\n error: 'Only image or video files are allowed',\n },\n};\n\n// uploadAcceptCategory resolves a field's configured category, or null when the\n// field accepts any file ('any', unset, or an unknown key).\nexport function uploadAcceptCategory(field) {\n return UPLOAD_ACCEPT_CATEGORIES[String(field?.accept ?? '').trim()] ?? null;\n}\n","// QuickCreateEditField — the \"Add More\" / \"Edit\" affordance inside a select\n// dropdown. Fully admin-config driven (FormGroupField.quickCreate / quickEdit,\n// see the Go struct). When a select carries quickCreate, its dropdown grows an\n// \"Add More\" button that opens the target module's Add form in a modal; on a\n// successful create the host field refetches its options and selects the new\n// record. quickEdit adds an \"Edit\" button that opens the target module's Edit\n// form for a resolved record id (this field's own value, or a sibling field via\n// quickEditIdFrom — e.g. \"edit the SELECTED CLIENT to add a contact\" from the\n// job's Contact Person field). No module or field name is hardcoded here.\n//\n// AddFormV1/EditFormV1 are pulled in with React.lazy so this module can be\n// imported by those same files without a static circular dependency.\nimport React, { Suspense, lazy, useMemo, useState } from 'react';\nimport { Button, Modal, Space, Spin } from 'antd';\nimport { PlusOutlined, EditOutlined } from '@ant-design/icons';\n\nconst AddFormV1 = lazy(() => import('../AddFormV1'));\nconst EditFormV1 = lazy(() => import('../EditFormV1'));\n\nconst empty = (v) => v === undefined || v === null || v === '';\nconst pathOf = (key) => (typeof key === 'string' && key.includes('.') ? key.split('.') : [key]);\n\n// Resolve the record id a quick-edit should open. Priority:\n// 1. field.quickEditIdFrom → a sibling field's value (row-scoped inside an\n// addRow row, else top-level; falls back to scopeValues, e.g. clientId).\n// 2. this field's own selected value (labeled selects carry {value}).\nfunction resolveEditId(field, form, name, scopeValues, ownValue) {\n const idFrom = field.quickEditIdFrom;\n if (idFrom) {\n const insideRow = Array.isArray(name) && name.length >= 3 && typeof name[1] === 'number';\n const abs = insideRow ? [...name.slice(0, 2), ...pathOf(idFrom)] : pathOf(idFrom);\n let v = form?.getFieldValue?.(abs);\n if (empty(v)) v = scopeValues?.[idFrom];\n return empty(v) ? null : v;\n }\n if (ownValue && typeof ownValue === 'object') return ownValue.value ?? null;\n return empty(ownValue) ? null : ownValue;\n}\n\n/**\n * useQuickField — returns { footer, modal } for a select FieldControl.\n * footer: JSX to append inside the Select's dropdownRender (the action buttons)\n * modal: JSX to render alongside the Select (the create/edit Modal)\n * onDone(kind, recordId) fires after a successful create/edit so the caller can\n * refetch options (and, for create, select the new record).\n */\nexport function useQuickField({ field, form, name, moduleName, scopeValues, ownValue, onDone }) {\n const [modal, setModal] = useState(null); // { mode: 'create'|'edit', module, recordId }\n\n const quickCreate = Boolean(field?.quickCreate);\n const quickEdit = Boolean(field?.quickEdit);\n const createModule = field?.quickCreateModule || field?.lookupCollection || '';\n const editModule = field?.quickEditModule || field?.lookupCollection || '';\n\n const editId = useMemo(\n () => (quickEdit ? resolveEditId(field, form, name, scopeValues, ownValue) : null),\n // ownValue / sibling changes should re-resolve\n [quickEdit, field, form, name, scopeValues, ownValue],\n );\n\n if (!quickCreate && !quickEdit) return { footer: null, modal: null };\n\n const close = () => setModal(null);\n const openCreate = () => createModule && setModal({ mode: 'create', module: createModule });\n const openEdit = () => editModule && editId && setModal({ mode: 'edit', module: editModule, recordId: String(editId) });\n\n const footer = (\n <div\n className=\"v1-quick-actions\"\n role=\"presentation\"\n onMouseDown={(e) => e.preventDefault()} // keep the select open while clicking\n style={{ display: 'flex', gap: 8, padding: '6px 8px', borderTop: '1px solid rgba(0,0,0,0.06)' }}\n >\n <Space size={8}>\n {quickCreate && (\n <Button type=\"link\" size=\"small\" icon={<PlusOutlined />} onClick={openCreate} style={{ paddingLeft: 0 }}>\n {field.quickCreateLabel || 'Add More'}\n </Button>\n )}\n {quickEdit && (\n <Button\n type=\"link\"\n size=\"small\"\n icon={<EditOutlined />}\n onClick={openEdit}\n disabled={!editId}\n title={!editId ? 'Select a record first' : undefined}\n >\n {field.quickEditLabel || 'Edit'}\n </Button>\n )}\n </Space>\n </div>\n );\n\n const modalNode = modal ? (\n <Modal\n open\n title={modal.mode === 'create' ? (field.quickCreateLabel || 'Add More') : (field.quickEditLabel || 'Edit')}\n width=\"min(1080px, 96vw)\"\n footer={null}\n destroyOnClose\n maskClosable={false}\n onCancel={close}\n styles={{ body: { maxHeight: '78vh', overflowY: 'auto' } }}\n >\n <Suspense fallback={<div style={{ padding: 48, textAlign: 'center' }}><Spin /></div>}>\n {modal.mode === 'create' ? (\n <AddFormV1\n moduleName={modal.module}\n embedded\n breadcrumbItems={[]}\n onCancel={close}\n onSuccess={(newId) => { close(); onDone?.('create', newId); }}\n />\n ) : (\n <EditFormV1\n moduleName={modal.module}\n recordId={modal.recordId}\n embedded\n breadcrumbItems={[]}\n onCancel={close}\n onSuccess={(rid) => { close(); onDone?.('edit', rid); }}\n />\n )}\n </Suspense>\n </Modal>\n ) : null;\n\n return { footer, modal: modalNode };\n}\n","// Shared role/permission gate used by row actions (ListView, DetailHeaderCard)\n// and, via AddFormV1/EditFormV1, by field-level visiblePermission/editablePermission.\n// A permission value looks like \"<module>.<key>\" (e.g. \"submission.viewRate\").\n//\n// checkPermission() is the CURRENT gate — it resolves against the `can`\n// function from src/hooks/usePermissions.js (backed by GET /me/permissions,\n// see src/contexts/PermissionContext.jsx), which every consumer must call\n// usePermissions() to obtain and pass in. roleAllowsAction() below is the\n// OLD, localStorage.menuPermission-based gate — kept only for isActionValueAllowed's\n// row-level (record.actionPermission.<key>) use, which is a separate,\n// per-record mechanism unrelated to role permissions.\n\nexport function isActionValueAllowed(value) {\n if (value === undefined || value === null) return true;\n if (typeof value === 'object') {\n return isActionValueAllowed(value.permission ?? value.allowed ?? value.value);\n }\n return value !== false && value !== 0 && value !== '0';\n}\n\n// permission: \"<module>.<key>\" string from admin config (RowAction.permission,\n// field.visiblePermission/editablePermission). can: the `can` function returned\n// by usePermissions(). Falls back to the field/action's own moduleName when the\n// permission string has no module prefix (a bare key, e.g. \"edit\").\nexport function checkPermission(can, permission, moduleName) {\n if (!permission) return true;\n if (typeof can !== 'function') return true;\n const [configuredModule, configuredKey] = String(permission).split('.');\n const module = configuredKey ? configuredModule : (moduleName || configuredModule);\n const key = configuredKey ?? configuredModule;\n return can(module, key);\n}\n\n// Deprecated — localStorage.menuPermission-based gate, superseded by\n// checkPermission()/usePermissions(). No remaining call sites; kept only so a\n// stray import doesn't break until it's confirmed unused everywhere.\nexport function roleAllowsAction(permission, moduleName) {\n if (!permission) return true;\n try {\n const permissions = JSON.parse(localStorage.getItem('menuPermission') || '{}');\n const [configuredModule, configuredKey] = String(permission).split('.');\n const moduleKey = configuredModule || String(moduleName || '').replace(/s$/i, '');\n const modulePermissions = permissions[moduleKey]\n ?? permissions[String(moduleName || '')]\n ?? permissions[String(moduleName || '').replace(/s$/i, '')]\n ?? {};\n return isActionValueAllowed(modulePermissions[configuredKey]);\n } catch {\n return true;\n }\n}\n","// Shared \"After Submit\" navigation resolver used by AddFormV1/EditFormV1.\n// Admin-configured per FormGroup (group.afterSubmit — see FormGroupsSection.jsx),\n// generic across every module/project: no module name is ever referenced here.\n\n// Picks the configured behavior from the group with the lowest `order` that\n// declares one. Returns null when no group configures it, so callers fall\n// back to their existing (pre-feature) navigation — unchanged behavior.\nexport function resolveAfterSubmit(groups) {\n const withConfig = (groups ?? [])\n .filter((g) => g?.afterSubmit?.mode)\n .sort((a, b) => (a.order ?? 0) - (b.order ?? 0));\n return withConfig[0]?.afterSubmit ?? null;\n}\n\n// Resolves a configured route template (e.g. \"/trainers/:id\") against the\n// created/updated record id and the submitted field values, and rejects\n// anything that isn't a safe in-app path (blocks open-redirect / javascript:\n// / data: payloads an admin could otherwise paste into the target field).\nexport function safeNavTarget(template, recordId, values) {\n const raw = String(template ?? '').trim();\n if (!raw || !raw.startsWith('/') || raw.startsWith('//')) return null;\n if (/^[a-z][a-z0-9+.-]*:/i.test(raw)) return null; // any \"scheme:\" prefix, e.g. javascript:, data:\n return raw.replace(/:([A-Za-z_][\\w]*)/g, (_, key) => {\n const value = key === 'id' ? recordId : values?.[key];\n return encodeURIComponent(value ?? '');\n });\n}\n","// Shared submit-toast resolver used by AddFormV1/EditFormV1.\n// Admin-configured per FormGroup (group.submitMessages — see FormGroupsSection),\n// generic across every module/project: no module name is ever referenced here.\n//\n// Defaults (no configuration anywhere, including brand-new modules):\n// add → \"<Module> has added successfully\"\n// edit → \"<Module> has Updated successfully\"\n// An admin can override any template (with ${module} substitution) or set\n// suppress to skip the success toast entirely.\n\n// Picks the configured messages from the group with the lowest `order` that\n// declares any — the same resolution rule afterSubmitNav uses.\nexport function resolveSubmitMessages(groups) {\n const withConfig = (groups ?? [])\n .filter((g) => g?.submitMessages && typeof g.submitMessages === 'object')\n .sort((a, b) => (a.order ?? 0) - (b.order ?? 0));\n return withConfig[0]?.submitMessages ?? null;\n}\n\n// \"jobs\" → \"Jobs\", \"locationTaxMaster\" → \"LocationTaxMaster\" (first letter only —\n// the module key is the admin-facing name across the platform).\nfunction moduleLabel(moduleName) {\n const raw = String(moduleName ?? '').trim();\n return raw ? raw.charAt(0).toUpperCase() + raw.slice(1) : 'Record';\n}\n\nfunction fillTemplate(template, moduleName) {\n return String(template).replaceAll('${module}', moduleLabel(moduleName))\n .replaceAll('${moduleName}', moduleLabel(moduleName));\n}\n\n// Returns the success toast text for a finished submit, or null when the admin\n// suppressed success toasts for this module. kind: 'add' | 'edit'.\nexport function submitSuccessMessage(groups, moduleName, kind) {\n const config = resolveSubmitMessages(groups);\n if (config?.suppress) return null;\n const template = kind === 'edit' ? config?.editSuccess : config?.addSuccess;\n if (template && String(template).trim()) return fillTemplate(template, moduleName);\n return kind === 'edit'\n ? `${moduleLabel(moduleName)} has Updated successfully`\n : `${moduleLabel(moduleName)} has added successfully`;\n}\n\n// Returns the error toast text: admin override first, then the real server\n// error (most actionable), then a generic fallback. Never null — a failed\n// submit must always surface.\nexport function submitErrorMessage(groups, moduleName, kind, serverText) {\n const config = resolveSubmitMessages(groups);\n const template = kind === 'edit' ? config?.editError : config?.addError;\n if (template && String(template).trim()) return fillTemplate(template, moduleName);\n if (serverText && String(serverText).trim()) return String(serverText);\n return kind === 'edit'\n ? `Failed to update ${moduleLabel(moduleName)}`\n : `Failed to create ${moduleLabel(moduleName)}`;\n}\n","// Shared \"scroll to the first invalid field\" handler for AddFormV1/EditFormV1.\n// Wire it from the antd Form's onFinishFailed: when Create/Save is clicked with\n// validation errors, the screen scrolls to the first errored field, focuses it\n// (cursor placed in the input) and pulses a red halo so the user sees exactly\n// which field failed. Generic — works for every module's add & edit form.\n//\n// Robustness notes:\n// - antd applies the .ant-form-item-has-error classes AFTER onFinishFailed\n// fires, so location runs on a short delay.\n// - The DOM query + scrollIntoView is the PRIMARY mechanism and always runs.\n// form.scrollToField is only a best-effort extra: antd locates fields by\n// DOM id, which custom field controls don't always forward — relying on it\n// alone silently scrolls nothing.\n// - Callers should expand any collapsed sections BEFORE calling this (a field\n// inside a display:none section can be neither scrolled to nor focused) —\n// both form engines do so in their onFinishFailed wrapper.\nexport function scrollToFirstFormError({ errorFields } = {}, form) {\n if (!errorFields?.length) return;\n const firstName = errorFields[0]?.name;\n\n setTimeout(() => {\n if (form?.scrollToField && firstName !== undefined) {\n try {\n form.scrollToField(firstName, { behavior: 'smooth', block: 'center' });\n } catch { /* best-effort only — the DOM scroll below always runs */ }\n }\n\n const errorFormItem = document.querySelector('.ant-form-item-has-error');\n if (!errorFormItem) return;\n const input = errorFormItem.querySelector('input, textarea, select, .ProseMirror');\n const target = input ?? errorFormItem;\n target.scrollIntoView({ behavior: 'smooth', block: 'center' });\n\n setTimeout(() => {\n input?.focus?.({ preventScroll: true });\n target.style.boxShadow = '0 0 0 3px rgba(255, 77, 79, 0.3)';\n setTimeout(() => { target.style.boxShadow = ''; }, 1200);\n }, 350);\n }, 60);\n}\n\nexport default scrollToFirstFormError;\n","function comparisonValues(value) {\n if (Array.isArray(value)) return value.map((item) => String(item ?? '').trim());\n return String(value ?? '').split(',').map((item) => item.trim());\n}\n\n// Matches the same generic operators supported by showIf. Keeping this helper\n// independent of React makes conditional labels usable in Add/Edit forms and\n// straightforward to test without module- or field-specific code.\nexport function conditionMatches(condition, value) {\n if (!condition?.field) return false;\n switch (condition.operator ?? 'eq') {\n case 'eq': return String(value ?? '') === String(condition.value ?? '');\n case 'neq': return String(value ?? '') !== String(condition.value ?? '');\n case 'truthy': return value !== undefined && value !== null && value !== '' && value !== false;\n case 'falsy': return value === undefined || value === null || value === '' || value === false;\n case 'notEmpty': return Array.isArray(value) ? value.length > 0 : Boolean(value);\n case 'in': return comparisonValues(condition.value).includes(String(value ?? ''));\n case 'notIn': return !comparisonValues(condition.value).includes(String(value ?? ''));\n default: return false;\n }\n}\n\nexport function configuredFieldLabel(field, watchedValue, combined = false) {\n const fallback = combined\n ? (field?.combineLabel ?? field?.label)\n : field?.label;\n const rule = field?.labelWhen;\n return conditionMatches(rule, watchedValue) && rule?.label\n ? rule.label\n : fallback;\n}\n\nexport function conditionFieldPath(condition, siblingPrefix) {\n if (!condition?.field) return ['__noop_conditional_label__'];\n return siblingPrefix != null\n ? [...(Array.isArray(siblingPrefix) ? siblingPrefix : [siblingPrefix]), condition.field]\n : [condition.field];\n}\n","import { Breadcrumb } from 'antd';\nimport { DownOutlined } from '@ant-design/icons';\nimport AppTypography from './typography/Typography';\n\nexport default function AppBreadcrumb({ items = [] }) {\n const breadcrumbItems = items.map((item, index) => {\n const isLast = index === items.length - 1;\n return {\n title: isLast ? (\n <AppTypography variant=\"body\" weight=\"medium\" color=\"link\">\n {item.label}\n </AppTypography>\n ) : (\n <a href={item.href}>\n <AppTypography variant=\"body\" color=\"secondary\">\n {item.label}\n </AppTypography>\n {item.dropdown && <DownOutlined />}\n </a>\n ),\n };\n });\n\n return <Breadcrumb items={breadcrumbItems} />;\n}\n"],"mappings":"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"}