strapi-plugin-bulk-updater 1.3.8 → 1.3.10

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.
Files changed (29) hide show
  1. package/dist/_chunks/{BulkUpdater-BosdSbGF.js → BulkUpdater-DRHQBZZV.js} +20 -4
  2. package/dist/_chunks/BulkUpdater-DRHQBZZV.js.map +1 -0
  3. package/dist/_chunks/{BulkUpdater-DUrmamj-.mjs → BulkUpdater-J21ZgJWx.mjs} +20 -4
  4. package/dist/_chunks/BulkUpdater-J21ZgJWx.mjs.map +1 -0
  5. package/dist/_chunks/{ScopedQuotaSelectInput-CyGlYa9x.js → ScopedQuotaSelectInput-BsBpmwun.js} +79 -11
  6. package/dist/_chunks/ScopedQuotaSelectInput-BsBpmwun.js.map +1 -0
  7. package/dist/_chunks/{ScopedQuotaSelectInput-Cy3eEj9-.mjs → ScopedQuotaSelectInput-YKdQgrPt.mjs} +79 -11
  8. package/dist/_chunks/ScopedQuotaSelectInput-YKdQgrPt.mjs.map +1 -0
  9. package/dist/_chunks/{SettingsPage-Bdse5MP4.mjs → SettingsPage-BDObdCIY.mjs} +2 -2
  10. package/dist/_chunks/{SettingsPage-Bdse5MP4.mjs.map → SettingsPage-BDObdCIY.mjs.map} +1 -1
  11. package/dist/_chunks/{SettingsPage-B6Ia7SVS.js → SettingsPage-M-HQ8Jtr.js} +2 -2
  12. package/dist/_chunks/{SettingsPage-B6Ia7SVS.js.map → SettingsPage-M-HQ8Jtr.js.map} +1 -1
  13. package/dist/_chunks/{ValidationRulesTab-BqGz1VLo.js → ValidationRulesTab-DuvL-K4F.js} +21 -8
  14. package/dist/_chunks/ValidationRulesTab-DuvL-K4F.js.map +1 -0
  15. package/dist/_chunks/{ValidationRulesTab-Dqkson67.mjs → ValidationRulesTab-VeRr-vxa.mjs} +21 -8
  16. package/dist/_chunks/ValidationRulesTab-VeRr-vxa.mjs.map +1 -0
  17. package/dist/admin/index.js +3 -3
  18. package/dist/admin/index.mjs +3 -3
  19. package/dist/server/index.js +223 -42
  20. package/dist/server/index.js.map +1 -1
  21. package/dist/server/index.mjs +223 -42
  22. package/dist/server/index.mjs.map +1 -1
  23. package/package.json +1 -1
  24. package/dist/_chunks/BulkUpdater-BosdSbGF.js.map +0 -1
  25. package/dist/_chunks/BulkUpdater-DUrmamj-.mjs.map +0 -1
  26. package/dist/_chunks/ScopedQuotaSelectInput-Cy3eEj9-.mjs.map +0 -1
  27. package/dist/_chunks/ScopedQuotaSelectInput-CyGlYa9x.js.map +0 -1
  28. package/dist/_chunks/ValidationRulesTab-BqGz1VLo.js.map +0 -1
  29. package/dist/_chunks/ValidationRulesTab-Dqkson67.mjs.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ValidationRulesTab-DuvL-K4F.js","sources":["../../admin/src/pages/ValidationRulesTab.tsx"],"sourcesContent":["import React, { useState, useEffect } from 'react';\nimport { useFetchClient, useNotification } from '@strapi/strapi/admin';\nimport {\n Box,\n Flex,\n Typography,\n Button,\n TextInput,\n Textarea,\n SingleSelect,\n SingleSelectOption,\n Badge,\n Table,\n Thead,\n Tbody,\n Tr,\n Th,\n Td,\n Alert,\n Checkbox,\n} from '@strapi/design-system';\nimport { Plus, Trash, Check, ArrowClockwise, Search, Download } from '@strapi/icons';\n\nexport interface ValidationRule {\n id: string;\n name: string;\n description?: string;\n collectionUid?: string;\n targetField: string;\n quotas: Record<string, number>;\n exceededAction: 'disable' | 'hide';\n enabled: boolean;\n scope: 'entry' | 'document';\n includeRichTextHtml?: boolean;\n richTextFields?: string[];\n createdAt?: string;\n updatedAt?: string;\n}\n\nexport default function ValidationRulesTab() {\n const { get, post, del } = useFetchClient();\n const { toggleNotification } = useNotification();\n\n const [rules, setRules] = useState<ValidationRule[]>([]);\n const [loading, setLoading] = useState<boolean>(true);\n const [modalOpen, setModalOpen] = useState<boolean>(false);\n const [editingRule, setEditingRule] = useState<ValidationRule | null>(null);\n\n // Available collections from backend models\n const [availableCollections, setAvailableCollections] = useState<Array<{ uid: string; displayName: string }>>([]);\n\n // Form state for creating/editing a rule\n const [formName, setFormName] = useState<string>('');\n const [formDesc, setFormDesc] = useState<string>('');\n const [formCollectionUid, setFormCollectionUid] = useState<string>('*');\n const [formField, setFormField] = useState<string>('');\n const [formAction, setFormAction] = useState<'disable' | 'hide'>('disable');\n const [formIncludeRichText, setFormIncludeRichText] = useState<boolean>(true);\n const [formQuotas, setFormQuotas] = useState<Array<{ key: string; maxAllowed: number }>>([\n { key: 'h1', maxAllowed: 1 },\n { key: 'h2', maxAllowed: 3 },\n ]);\n const [saving, setSaving] = useState<boolean>(false);\n\n // Scan modal state\n const [scanModalOpen, setScanModalOpen] = useState<boolean>(false);\n const [scanningRuleId, setScanningRuleId] = useState<string | null>(null);\n const [scanReport, setScanReport] = useState<any>(null);\n\n const fetchCollections = async () => {\n try {\n const res = await get('/bulk-updater/models');\n let list: Array<{ uid: string; displayName: string }> = [];\n if (Array.isArray(res.data?.collections)) {\n list = res.data.collections.map((c: any) => ({\n uid: c.uid,\n displayName: c.displayName || c.singularName || c.uid,\n }));\n } else if (res.data?.targetUids && res.data?.metaByUid) {\n list = res.data.targetUids.map((uid: string) => ({\n uid,\n displayName: res.data.metaByUid[uid]?.displayName || uid,\n }));\n }\n setAvailableCollections(list);\n } catch {\n // Fallback silently if models not loaded\n }\n };\n\n const handleScanRule = async (rule: ValidationRule) => {\n try {\n setScanningRuleId(rule.id);\n const res = await get(`/bulk-updater/validation-rules/${rule.id}/scan`);\n if (res.data && res.data.success) {\n setScanReport(res.data);\n setScanModalOpen(true);\n }\n } catch (err: any) {\n toggleNotification({\n type: 'danger',\n message: `Scan failed: ${err.message}`,\n });\n } finally {\n setScanningRuleId(null);\n }\n };\n\n const fetchRules = async () => {\n try {\n setLoading(true);\n const res = await get('/bulk-updater/validation-rules');\n if (res.data && res.data.success) {\n setRules(res.data.rules || []);\n }\n } catch (err: any) {\n toggleNotification({\n type: 'danger',\n message: `Failed to load rules: ${err.message}`,\n });\n } finally {\n setLoading(false);\n }\n };\n\n useEffect(() => {\n fetchRules();\n fetchCollections();\n }, []);\n\n const openCreateModal = () => {\n fetchCollections();\n setEditingRule(null);\n setFormName('');\n setFormDesc('');\n setFormCollectionUid('*');\n setFormField('headingLevel');\n setFormAction('disable');\n setFormIncludeRichText(true);\n setFormQuotas([\n { key: 'h1', maxAllowed: 1 },\n { key: 'h2', maxAllowed: 3 },\n ]);\n setModalOpen(true);\n };\n\n const openEditModal = (rule: ValidationRule) => {\n fetchCollections();\n setEditingRule(rule);\n setFormName(rule.name);\n setFormDesc(rule.description || '');\n setFormCollectionUid(rule.collectionUid || '*');\n setFormField(rule.targetField);\n setFormAction(rule.exceededAction || 'disable');\n setFormIncludeRichText(rule.includeRichTextHtml ?? true);\n const quotaPairs = Object.entries(rule.quotas || {}).map(([k, v]) => ({\n key: k,\n maxAllowed: v,\n }));\n setFormQuotas(quotaPairs.length > 0 ? quotaPairs : [{ key: 'h1', maxAllowed: 1 }]);\n setModalOpen(true);\n };\n\n const handleAddQuotaRow = () => {\n setFormQuotas((prev) => [...prev, { key: '', maxAllowed: 1 }]);\n };\n\n const handleRemoveQuotaRow = (idx: number) => {\n setFormQuotas((prev) => prev.filter((_, i) => i !== idx));\n };\n\n const handleQuotaChange = (idx: number, field: 'key' | 'maxAllowed', value: any) => {\n setFormQuotas((prev) =>\n prev.map((row, i) => {\n if (i === idx) {\n return {\n ...row,\n [field]: field === 'maxAllowed' ? Math.max(1, parseInt(value, 10) || 1) : String(value).trim(),\n };\n }\n return row;\n })\n );\n };\n\n const handleSave = async () => {\n if (!formName.trim() || !formField.trim()) {\n toggleNotification({\n type: 'warning',\n message: 'Rule Name and Target Field are required.',\n });\n return;\n }\n\n const quotasRecord: Record<string, number> = {};\n for (const q of formQuotas) {\n if (q.key.trim()) {\n quotasRecord[q.key.trim().toLowerCase()] = q.maxAllowed;\n }\n }\n\n if (Object.keys(quotasRecord).length === 0) {\n toggleNotification({\n type: 'warning',\n message: 'At least one quota option with a limit is required.',\n });\n return;\n }\n\n try {\n setSaving(true);\n const payload: Partial<ValidationRule> = {\n id: editingRule ? editingRule.id : undefined,\n name: formName.trim(),\n description: formDesc.trim(),\n collectionUid: formCollectionUid,\n targetField: formField.trim(),\n quotas: quotasRecord,\n exceededAction: formAction,\n enabled: editingRule ? editingRule.enabled : true,\n scope: 'entry',\n includeRichTextHtml: formIncludeRichText,\n };\n\n const res = await post('/bulk-updater/validation-rules', { rule: payload });\n if (res.data && res.data.success) {\n toggleNotification({\n type: 'success',\n message: `Rule \"${payload.name}\" saved successfully!`,\n });\n setModalOpen(false);\n fetchRules();\n }\n } catch (err: any) {\n toggleNotification({\n type: 'danger',\n message: `Failed to save rule: ${err.message}`,\n });\n } finally {\n setSaving(false);\n }\n };\n\n const handleToggle = async (rule: ValidationRule) => {\n try {\n const res = await post(`/bulk-updater/validation-rules/${rule.id}/toggle`, {\n enabled: !rule.enabled,\n });\n if (res.data && res.data.success) {\n setRules((prev) =>\n prev.map((r) => (r.id === rule.id ? { ...r, enabled: !rule.enabled } : r))\n );\n toggleNotification({\n type: 'info',\n message: `Rule \"${rule.name}\" is now ${!rule.enabled ? 'ACTIVE' : 'DISABLED'}.`,\n });\n }\n } catch (err: any) {\n toggleNotification({\n type: 'danger',\n message: `Failed to update rule status: ${err.message}`,\n });\n }\n };\n\n const handleDelete = async (ruleId: string, ruleName: string) => {\n if (!window.confirm(`Are you sure you want to delete the rule \"${ruleName}\"?`)) return;\n\n try {\n const res = await del(`/bulk-updater/validation-rules/${ruleId}`);\n if (res.data && res.data.success) {\n setRules((prev) => prev.filter((r) => r.id !== ruleId));\n toggleNotification({\n type: 'success',\n message: `Rule \"${ruleName}\" deleted.`,\n });\n }\n } catch (err: any) {\n toggleNotification({\n type: 'danger',\n message: `Failed to delete rule: ${err.message}`,\n });\n }\n };\n\n return (\n <Box>\n <style>{`\n [data-radix-popper-content-wrapper] {\n z-index: 10005 !important;\n }\n `}</style>\n {/* Header Panel */}\n <Box padding={6} background=\"neutral0\" shadow=\"filterShadow\" hasRadius marginBottom={6}>\n <Flex justifyContent=\"space-between\" alignItems=\"center\" wrap=\"wrap\" gap={3}>\n <Box>\n <Typography variant=\"delta\" tag=\"h2\" fontWeight=\"bold\">\n Scoped & Cross-Component Validation Rules\n </Typography>\n <Typography variant=\"pi\" textColor=\"neutral600\" style={{ marginTop: 4 }}>\n Define collection-scoped rules and combined heading limits across structured components and free-form Rich Text / CKEditor HTML / Markdown content.\n </Typography>\n </Box>\n <Flex gap={2}>\n <Button\n variant=\"tertiary\"\n startIcon={<ArrowClockwise />}\n onClick={fetchRules}\n loading={loading}\n >\n Refresh\n </Button>\n <Button\n variant=\"default\"\n startIcon={<Plus />}\n onClick={openCreateModal}\n >\n Create New Rule\n </Button>\n </Flex>\n </Flex>\n </Box>\n\n {/* Rules Table */}\n <Box padding={6} background=\"neutral0\" shadow=\"filterShadow\" hasRadius>\n <Typography variant=\"sigma\" textColor=\"neutral600\" marginBottom={3} style={{ display: 'block' }}>\n CONFIGURED RULES ({rules.length})\n </Typography>\n\n {loading ? (\n <Typography variant=\"omega\" textColor=\"neutral500\">Loading validation rules...</Typography>\n ) : rules.length === 0 ? (\n <Alert variant=\"info\" title=\"No Rules Defined\">\n Click \"Create New Rule\" above to add your first cross-component quota rule.\n </Alert>\n ) : (\n <Table colCount={7} rowCount={rules.length + 1}>\n <Thead>\n <Tr>\n <Th><Typography variant=\"sigma\">RULE NAME & TARGET FIELD</Typography></Th>\n <Th><Typography variant=\"sigma\">COLLECTION SCOPE</Typography></Th>\n <Th><Typography variant=\"sigma\">QUOTA CONSTRAINTS</Typography></Th>\n <Th><Typography variant=\"sigma\">RICH TEXT / HTML</Typography></Th>\n <Th><Typography variant=\"sigma\">EXCEEDED ACTION</Typography></Th>\n <Th><Typography variant=\"sigma\">STATUS</Typography></Th>\n <Th style={{ textAlign: 'right' }}><Typography variant=\"sigma\">ACTIONS</Typography></Th>\n </Tr>\n </Thead>\n <Tbody>\n {rules.map((rule) => {\n const quotaKeys = Object.entries(rule.quotas || {});\n const isGlobal = !rule.collectionUid || rule.collectionUid === '*';\n const collectionName = !isGlobal\n ? (availableCollections.find((c) => c.uid === rule.collectionUid)?.displayName || rule.collectionUid)\n : 'All Collections (Global)';\n\n return (\n <Tr key={rule.id}>\n <Td style={{ minWidth: 200 }}>\n <Typography variant=\"omega\" fontWeight=\"bold\" textColor=\"neutral800\" display=\"block\">\n {rule.name}\n </Typography>\n <Typography variant=\"pi\" textColor=\"neutral500\">\n Target: <code>{rule.targetField}</code>\n </Typography>\n </Td>\n <Td style={{ minWidth: 160 }}>\n <Badge\n backgroundColor={isGlobal ? 'neutral150' : 'primary100'}\n textColor={isGlobal ? 'neutral700' : 'primary700'}\n >\n {collectionName}\n </Badge>\n </Td>\n <Td style={{ minWidth: 180 }}>\n <Flex gap={1} wrap=\"wrap\">\n {quotaKeys.map(([optVal, maxVal]) => (\n <Badge key={optVal} backgroundColor=\"neutral100\" textColor=\"primary700\">\n <strong>{optVal.toUpperCase()}</strong>: max {maxVal}\n </Badge>\n ))}\n </Flex>\n </Td>\n <Td style={{ minWidth: 140 }}>\n {rule.includeRichTextHtml ? (\n <Badge backgroundColor=\"success100\" textColor=\"success700\">\n HTML & Rich Text Active\n </Badge>\n ) : (\n <Badge backgroundColor=\"neutral150\" textColor=\"neutral600\">\n Structured Only\n </Badge>\n )}\n </Td>\n <Td style={{ minWidth: 110 }}>\n <Badge\n backgroundColor={rule.exceededAction === 'hide' ? 'secondary100' : 'warning100'}\n textColor={rule.exceededAction === 'hide' ? 'secondary700' : 'warning700'}\n >\n {rule.exceededAction.toUpperCase()}\n </Badge>\n </Td>\n <Td style={{ minWidth: 100 }}>\n <Button\n variant={rule.enabled ? 'success-light' : 'tertiary'}\n size=\"S\"\n onClick={() => handleToggle(rule)}\n >\n {rule.enabled ? '● ACTIVE' : '○ DISABLED'}\n </Button>\n </Td>\n <Td style={{ textAlign: 'right', minWidth: 260 }}>\n <Flex gap={2} justifyContent=\"flex-end\">\n <Button\n variant=\"secondary\"\n size=\"S\"\n startIcon={<Search />}\n onClick={() => handleScanRule(rule)}\n loading={scanningRuleId === rule.id}\n >\n Scan Violations\n </Button>\n <Button\n variant=\"tertiary\"\n size=\"S\"\n onClick={() => openEditModal(rule)}\n >\n Edit\n </Button>\n <Button\n variant=\"danger-light\"\n size=\"S\"\n startIcon={<Trash />}\n onClick={() => handleDelete(rule.id, rule.name)}\n >\n Delete\n </Button>\n </Flex>\n </Td>\n </Tr>\n );\n })}\n </Tbody>\n </Table>\n )}\n </Box>\n\n {/* Create / Edit Rule Modal */}\n {modalOpen && (\n <Box\n style={{\n position: 'fixed',\n inset: 0,\n backgroundColor: 'rgba(33, 33, 52, 0.65)',\n zIndex: 1000,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n }}\n >\n <Box\n background=\"neutral0\"\n hasRadius\n shadow=\"popupShadow\"\n padding={6}\n style={{ width: '90%', maxWidth: 640, maxHeight: '90vh', overflowY: 'auto' }}\n >\n <Typography variant=\"delta\" tag=\"h2\" fontWeight=\"bold\" marginBottom={1}>\n {editingRule ? 'Edit Validation Rule' : 'Create New Validation Rule'}\n </Typography>\n <Typography variant=\"pi\" textColor=\"neutral600\" marginBottom={4} style={{ display: 'block' }}>\n Configure collection-scoped quotas. Rules apply consistently to target properties and optionally scan rich text HTML content.\n </Typography>\n\n <Flex direction=\"column\" gap={4} alignItems=\"stretch\">\n <TextInput\n label=\"Rule Name\"\n placeholder=\"e.g. SEO Single H1 Page Rule\"\n value={formName}\n onChange={(e: any) => setFormName(e.target.value)}\n required\n />\n\n <SingleSelect\n label=\"Target Collection Type\"\n value={formCollectionUid}\n onChange={(val: any) => setFormCollectionUid(val)}\n hint=\"Scope this rule to a specific collection type, or select All Collections.\"\n >\n <SingleSelectOption value=\"*\">* (All Collections / Global)</SingleSelectOption>\n {availableCollections.map((c) => (\n <SingleSelectOption key={c.uid} value={c.uid}>\n {c.displayName} ({c.uid})\n </SingleSelectOption>\n ))}\n </SingleSelect>\n\n <TextInput\n label=\"Target Field / Component Property Path\"\n placeholder=\"e.g. titleStyle, titleHeadingStyle.titleStyle, or content.titleHeadingStyle.titleStyle\"\n value={formField}\n onChange={(e: any) => setFormField(e.target.value)}\n hint=\"Matches leaf key ('titleStyle'), component path ('titleHeadingStyle.titleStyle'), dynamic zone path ('content.titleHeadingStyle.titleStyle'), or collection-prefixed path ('st-featured.titleHeadingStyle.titleStyle').\"\n required\n />\n\n <Box padding={3} background=\"neutral100\" hasRadius style={{ border: '1px solid #e0e0e0' }}>\n <Checkbox\n checked={formIncludeRichText}\n onCheckedChange={(checked: boolean) => setFormIncludeRichText(checked)}\n >\n <Box marginLeft={2}>\n <Typography variant=\"omega\" fontWeight=\"bold\">\n Scan & Combine Rich Text / CKEditor HTML Headings\n </Typography>\n <Typography variant=\"pi\" textColor=\"neutral600\" display=\"block\">\n When enabled, any &lt;h1&gt;..&lt;h6&gt; tags, Markdown headings (#), or Strapi Blocks inside rich text fields are counted together with structured component choices towards the quota.\n </Typography>\n </Box>\n </Checkbox>\n </Box>\n\n <Textarea\n label=\"Rule Description\"\n placeholder=\"Briefly explain what this constraint accomplishes...\"\n value={formDesc}\n onChange={(e: any) => setFormDesc(e.target.value)}\n />\n\n <SingleSelect\n label=\"When Quota Is Exceeded in Another Component\"\n value={formAction}\n onChange={(val: any) => setFormAction(val as 'disable' | 'hide')}\n >\n <SingleSelectOption value=\"disable\">\n Disable Option with Usage Badge [(1/1 used)]\n </SingleSelectOption>\n <SingleSelectOption value=\"hide\">\n Hide Option completely from dropdown menu\n </SingleSelectOption>\n </SingleSelect>\n\n {/* Quotas Editor */}\n <Box\n padding={4}\n background=\"neutral100\"\n hasRadius\n style={{ border: '1px solid #e0e0e0' }}\n >\n <Flex justifyContent=\"space-between\" alignItems=\"center\" marginBottom={3}>\n <Box>\n <Typography variant=\"pi\" fontWeight=\"bold\" textColor=\"neutral800\">\n Option Quotas (Max Allowed per Entry)\n </Typography>\n <Typography variant=\"pi\" textColor=\"neutral600\" style={{ display: 'block' }}>\n Options left unlisted will have unlimited usage.\n </Typography>\n </Box>\n <Button\n variant=\"secondary\"\n size=\"S\"\n startIcon={<Plus />}\n onClick={handleAddQuotaRow}\n >\n Add Option\n </Button>\n </Flex>\n\n <Flex direction=\"column\" gap={2}>\n {formQuotas.map((q, idx) => (\n <Flex key={idx} gap={2} alignItems=\"center\">\n <Box style={{ flex: 2 }}>\n <TextInput\n placeholder=\"Option key (e.g. h1)\"\n value={q.key}\n onChange={(e: any) => handleQuotaChange(idx, 'key', e.target.value)}\n />\n </Box>\n <Box style={{ flex: 1 }}>\n <TextInput\n type=\"number\"\n placeholder=\"Max\"\n value={String(q.maxAllowed)}\n onChange={(e: any) => handleQuotaChange(idx, 'maxAllowed', e.target.value)}\n />\n </Box>\n <Button\n variant=\"ghost\"\n size=\"S\"\n onClick={() => handleRemoveQuotaRow(idx)}\n disabled={formQuotas.length <= 1}\n >\n ✕\n </Button>\n </Flex>\n ))}\n </Flex>\n </Box>\n </Flex>\n\n {/* Modal Actions */}\n <Flex justifyContent=\"flex-end\" gap={2} marginTop={6}>\n <Button\n variant=\"tertiary\"\n onClick={() => setModalOpen(false)}\n disabled={saving}\n >\n Cancel\n </Button>\n <Button\n variant=\"default\"\n startIcon={<Check />}\n onClick={handleSave}\n loading={saving}\n >\n Save Rule\n </Button>\n </Flex>\n </Box>\n </Box>\n )}\n\n {/* Scan Results Modal */}\n {scanModalOpen && scanReport && (\n <Box\n style={{\n position: 'fixed',\n inset: 0,\n backgroundColor: 'rgba(33, 33, 52, 0.65)',\n zIndex: 1000,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n }}\n >\n <Box\n background=\"neutral0\"\n hasRadius\n shadow=\"popupShadow\"\n padding={6}\n style={{ width: '90%', maxWidth: 780, maxHeight: '85vh', overflowY: 'auto' }}\n >\n <Flex justifyContent=\"space-between\" alignItems=\"center\" marginBottom={4}>\n <Box>\n <Typography variant=\"beta\" tag=\"h2\" fontWeight=\"bold\">\n Rule Violation Audit: {scanReport.rule?.name}\n </Typography>\n <Typography variant=\"pi\" textColor=\"neutral600\">\n Target Field: <code>{scanReport.rule?.targetField}</code> • Total Entries Scanned: {scanReport.totalScanned}\n </Typography>\n </Box>\n <Badge\n backgroundColor={scanReport.totalViolations > 0 ? 'danger100' : 'success100'}\n textColor={scanReport.totalViolations > 0 ? 'danger700' : 'success700'}\n size=\"M\"\n >\n {scanReport.totalViolations > 0\n ? `${scanReport.totalViolations} VIOLATION(S) FOUND`\n : '100% COMPLIANT'}\n </Badge>\n </Flex>\n\n {scanReport.totalViolations === 0 ? (\n <Alert variant=\"success\" title=\"No Pre-Existing Violations Detected\" marginBottom={4}>\n All existing documents across your collections adhere strictly to the configured quota limits.\n </Alert>\n ) : (\n <Box>\n <Alert variant=\"danger\" title=\"Legacy Records Found Exceeding Quota\" marginBottom={4}>\n The following {scanReport.totalViolations} record(s) contain more instances of restricted options than currently permitted by this rule.\n </Alert>\n\n <Table colCount={4} rowCount={scanReport.violations.length + 1}>\n <Thead>\n <Tr>\n <Th><Typography variant=\"sigma\">CONTENT TYPE & ENTRY</Typography></Th>\n <Th><Typography variant=\"sigma\">RESTRICTED OPTION</Typography></Th>\n <Th><Typography variant=\"sigma\">COUNT VS LIMIT</Typography></Th>\n <Th style={{ textAlign: 'right' }}><Typography variant=\"sigma\">ACTION</Typography></Th>\n </Tr>\n </Thead>\n <Tbody>\n {scanReport.violations.map((v: any, idx: number) => (\n <Tr key={idx}>\n <Td>\n <Typography variant=\"omega\" fontWeight=\"bold\">\n {v.entryLabel}\n </Typography>\n <Typography variant=\"pi\" textColor=\"neutral500\" display=\"block\">\n Collection: {v.collectionDisplayName}\n </Typography>\n {v.detail && (\n <Typography variant=\"pi\" textColor=\"neutral600\" display=\"block\" style={{ fontSize: 11 }}>\n Breakdown: {v.detail}\n </Typography>\n )}\n </Td>\n <Td>\n <Badge backgroundColor=\"warning100\" textColor=\"warning700\">\n {v.violatingOption}\n </Badge>\n </Td>\n <Td>\n <Typography variant=\"omega\" textColor=\"danger600\" fontWeight=\"bold\">\n {v.foundCount} used\n </Typography>\n <Typography variant=\"pi\" textColor=\"neutral500\">\n {' '}(Allowed max: {v.maxAllowed})\n </Typography>\n </Td>\n <Td style={{ textAlign: 'right' }}>\n <Button\n variant=\"secondary\"\n size=\"S\"\n onClick={() => window.open(v.editUrl, '_blank')}\n >\n Open in Editor ↗\n </Button>\n </Td>\n </Tr>\n ))}\n </Tbody>\n </Table>\n </Box>\n )}\n\n <Flex justifyContent=\"space-between\" alignItems=\"center\" marginTop={6}>\n {scanReport.totalViolations > 0 ? (\n <Button\n variant=\"secondary\"\n startIcon={<Download />}\n onClick={async () => {\n try {\n const res = await get(`/bulk-updater/csv/export-violations/${scanReport.rule.id}`);\n const csvStr = res.data?.csvContent || (typeof res.data === 'string' ? res.data : '');\n if (!csvStr) {\n toggleNotification({\n type: 'warning',\n message: 'No violation data to export',\n });\n return;\n }\n const safeContent = csvStr.startsWith('\\uFEFF') ? csvStr : '\\uFEFF' + csvStr;\n const blob = new Blob([safeContent], { type: 'text/csv;charset=utf-8;' });\n const url = URL.createObjectURL(blob);\n const link = document.createElement('a');\n link.href = url;\n link.setAttribute('download', `violations_${scanReport.rule.id}.csv`);\n document.body.appendChild(link);\n link.click();\n document.body.removeChild(link);\n URL.revokeObjectURL(url);\n toggleNotification({\n type: 'success',\n message: 'Violations exported to CSV successfully',\n });\n } catch (e: any) {\n toggleNotification({\n type: 'danger',\n message: e.message || 'Failed exporting violations CSV',\n });\n }\n }}\n >\n Export Violations CSV\n </Button>\n ) : (\n <Box />\n )}\n <Button variant=\"default\" onClick={() => setScanModalOpen(false)}>\n Close Report\n </Button>\n </Flex>\n </Box>\n </Box>\n )}\n </Box>\n );\n}\n"],"names":["useFetchClient","useNotification","useState","useEffect","Box","jsx","jsxs","Flex","Typography","Button","ArrowClockwise","Plus","Alert","Table","Thead","Tr","Th","Tbody","Td","Badge","Search","Trash","TextInput","SingleSelect","SingleSelectOption","Checkbox","Textarea","Check","Download"],"mappings":"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"}
@@ -28,13 +28,19 @@ function ValidationRulesTab() {
28
28
  const fetchCollections = async () => {
29
29
  try {
30
30
  const res = await get("/bulk-updater/models");
31
- if (res.data?.targetUids && res.data?.metaByUid) {
32
- const list = res.data.targetUids.map((uid) => ({
31
+ let list = [];
32
+ if (Array.isArray(res.data?.collections)) {
33
+ list = res.data.collections.map((c) => ({
34
+ uid: c.uid,
35
+ displayName: c.displayName || c.singularName || c.uid
36
+ }));
37
+ } else if (res.data?.targetUids && res.data?.metaByUid) {
38
+ list = res.data.targetUids.map((uid) => ({
33
39
  uid,
34
40
  displayName: res.data.metaByUid[uid]?.displayName || uid
35
41
  }));
36
- setAvailableCollections(list);
37
42
  }
43
+ setAvailableCollections(list);
38
44
  } catch {
39
45
  }
40
46
  };
@@ -76,6 +82,7 @@ function ValidationRulesTab() {
76
82
  fetchCollections();
77
83
  }, []);
78
84
  const openCreateModal = () => {
85
+ fetchCollections();
79
86
  setEditingRule(null);
80
87
  setFormName("");
81
88
  setFormDesc("");
@@ -90,6 +97,7 @@ function ValidationRulesTab() {
90
97
  setModalOpen(true);
91
98
  };
92
99
  const openEditModal = (rule) => {
100
+ fetchCollections();
93
101
  setEditingRule(rule);
94
102
  setFormName(rule.name);
95
103
  setFormDesc(rule.description || "");
@@ -216,6 +224,11 @@ function ValidationRulesTab() {
216
224
  }
217
225
  };
218
226
  return /* @__PURE__ */ jsxs(Box, { children: [
227
+ /* @__PURE__ */ jsx("style", { children: `
228
+ [data-radix-popper-content-wrapper] {
229
+ z-index: 10005 !important;
230
+ }
231
+ ` }),
219
232
  /* @__PURE__ */ jsx(Box, { padding: 6, background: "neutral0", shadow: "filterShadow", hasRadius: true, marginBottom: 6, children: /* @__PURE__ */ jsxs(Flex, { justifyContent: "space-between", alignItems: "center", wrap: "wrap", gap: 3, children: [
220
233
  /* @__PURE__ */ jsxs(Box, { children: [
221
234
  /* @__PURE__ */ jsx(Typography, { variant: "delta", tag: "h2", fontWeight: "bold", children: "Scoped & Cross-Component Validation Rules" }),
@@ -345,7 +358,7 @@ function ValidationRulesTab() {
345
358
  position: "fixed",
346
359
  inset: 0,
347
360
  backgroundColor: "rgba(33, 33, 52, 0.65)",
348
- zIndex: 9999,
361
+ zIndex: 1e3,
349
362
  display: "flex",
350
363
  alignItems: "center",
351
364
  justifyContent: "center"
@@ -394,10 +407,10 @@ function ValidationRulesTab() {
394
407
  TextInput,
395
408
  {
396
409
  label: "Target Field / Component Property Path",
397
- placeholder: "e.g. headingLevel, titleStyle, or st-featured.titleHeadingStyle.titleStyle",
410
+ placeholder: "e.g. titleStyle, titleHeadingStyle.titleStyle, or content.titleHeadingStyle.titleStyle",
398
411
  value: formField,
399
412
  onChange: (e) => setFormField(e.target.value),
400
- hint: "Attribute name or dot-notated hierarchy (e.g. 'titleStyle' or 'st-featured.titleHeadingStyle.titleStyle').",
413
+ hint: "Matches leaf key ('titleStyle'), component path ('titleHeadingStyle.titleStyle'), dynamic zone path ('content.titleHeadingStyle.titleStyle'), or collection-prefixed path ('st-featured.titleHeadingStyle.titleStyle').",
401
414
  required: true
402
415
  }
403
416
  ),
@@ -523,7 +536,7 @@ function ValidationRulesTab() {
523
536
  position: "fixed",
524
537
  inset: 0,
525
538
  backgroundColor: "rgba(33, 33, 52, 0.65)",
526
- zIndex: 9999,
539
+ zIndex: 1e3,
527
540
  display: "flex",
528
541
  alignItems: "center",
529
542
  justifyContent: "center"
@@ -663,4 +676,4 @@ function ValidationRulesTab() {
663
676
  export {
664
677
  ValidationRulesTab as V
665
678
  };
666
- //# sourceMappingURL=ValidationRulesTab-Dqkson67.mjs.map
679
+ //# sourceMappingURL=ValidationRulesTab-VeRr-vxa.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ValidationRulesTab-VeRr-vxa.mjs","sources":["../../admin/src/pages/ValidationRulesTab.tsx"],"sourcesContent":["import React, { useState, useEffect } from 'react';\nimport { useFetchClient, useNotification } from '@strapi/strapi/admin';\nimport {\n Box,\n Flex,\n Typography,\n Button,\n TextInput,\n Textarea,\n SingleSelect,\n SingleSelectOption,\n Badge,\n Table,\n Thead,\n Tbody,\n Tr,\n Th,\n Td,\n Alert,\n Checkbox,\n} from '@strapi/design-system';\nimport { Plus, Trash, Check, ArrowClockwise, Search, Download } from '@strapi/icons';\n\nexport interface ValidationRule {\n id: string;\n name: string;\n description?: string;\n collectionUid?: string;\n targetField: string;\n quotas: Record<string, number>;\n exceededAction: 'disable' | 'hide';\n enabled: boolean;\n scope: 'entry' | 'document';\n includeRichTextHtml?: boolean;\n richTextFields?: string[];\n createdAt?: string;\n updatedAt?: string;\n}\n\nexport default function ValidationRulesTab() {\n const { get, post, del } = useFetchClient();\n const { toggleNotification } = useNotification();\n\n const [rules, setRules] = useState<ValidationRule[]>([]);\n const [loading, setLoading] = useState<boolean>(true);\n const [modalOpen, setModalOpen] = useState<boolean>(false);\n const [editingRule, setEditingRule] = useState<ValidationRule | null>(null);\n\n // Available collections from backend models\n const [availableCollections, setAvailableCollections] = useState<Array<{ uid: string; displayName: string }>>([]);\n\n // Form state for creating/editing a rule\n const [formName, setFormName] = useState<string>('');\n const [formDesc, setFormDesc] = useState<string>('');\n const [formCollectionUid, setFormCollectionUid] = useState<string>('*');\n const [formField, setFormField] = useState<string>('');\n const [formAction, setFormAction] = useState<'disable' | 'hide'>('disable');\n const [formIncludeRichText, setFormIncludeRichText] = useState<boolean>(true);\n const [formQuotas, setFormQuotas] = useState<Array<{ key: string; maxAllowed: number }>>([\n { key: 'h1', maxAllowed: 1 },\n { key: 'h2', maxAllowed: 3 },\n ]);\n const [saving, setSaving] = useState<boolean>(false);\n\n // Scan modal state\n const [scanModalOpen, setScanModalOpen] = useState<boolean>(false);\n const [scanningRuleId, setScanningRuleId] = useState<string | null>(null);\n const [scanReport, setScanReport] = useState<any>(null);\n\n const fetchCollections = async () => {\n try {\n const res = await get('/bulk-updater/models');\n let list: Array<{ uid: string; displayName: string }> = [];\n if (Array.isArray(res.data?.collections)) {\n list = res.data.collections.map((c: any) => ({\n uid: c.uid,\n displayName: c.displayName || c.singularName || c.uid,\n }));\n } else if (res.data?.targetUids && res.data?.metaByUid) {\n list = res.data.targetUids.map((uid: string) => ({\n uid,\n displayName: res.data.metaByUid[uid]?.displayName || uid,\n }));\n }\n setAvailableCollections(list);\n } catch {\n // Fallback silently if models not loaded\n }\n };\n\n const handleScanRule = async (rule: ValidationRule) => {\n try {\n setScanningRuleId(rule.id);\n const res = await get(`/bulk-updater/validation-rules/${rule.id}/scan`);\n if (res.data && res.data.success) {\n setScanReport(res.data);\n setScanModalOpen(true);\n }\n } catch (err: any) {\n toggleNotification({\n type: 'danger',\n message: `Scan failed: ${err.message}`,\n });\n } finally {\n setScanningRuleId(null);\n }\n };\n\n const fetchRules = async () => {\n try {\n setLoading(true);\n const res = await get('/bulk-updater/validation-rules');\n if (res.data && res.data.success) {\n setRules(res.data.rules || []);\n }\n } catch (err: any) {\n toggleNotification({\n type: 'danger',\n message: `Failed to load rules: ${err.message}`,\n });\n } finally {\n setLoading(false);\n }\n };\n\n useEffect(() => {\n fetchRules();\n fetchCollections();\n }, []);\n\n const openCreateModal = () => {\n fetchCollections();\n setEditingRule(null);\n setFormName('');\n setFormDesc('');\n setFormCollectionUid('*');\n setFormField('headingLevel');\n setFormAction('disable');\n setFormIncludeRichText(true);\n setFormQuotas([\n { key: 'h1', maxAllowed: 1 },\n { key: 'h2', maxAllowed: 3 },\n ]);\n setModalOpen(true);\n };\n\n const openEditModal = (rule: ValidationRule) => {\n fetchCollections();\n setEditingRule(rule);\n setFormName(rule.name);\n setFormDesc(rule.description || '');\n setFormCollectionUid(rule.collectionUid || '*');\n setFormField(rule.targetField);\n setFormAction(rule.exceededAction || 'disable');\n setFormIncludeRichText(rule.includeRichTextHtml ?? true);\n const quotaPairs = Object.entries(rule.quotas || {}).map(([k, v]) => ({\n key: k,\n maxAllowed: v,\n }));\n setFormQuotas(quotaPairs.length > 0 ? quotaPairs : [{ key: 'h1', maxAllowed: 1 }]);\n setModalOpen(true);\n };\n\n const handleAddQuotaRow = () => {\n setFormQuotas((prev) => [...prev, { key: '', maxAllowed: 1 }]);\n };\n\n const handleRemoveQuotaRow = (idx: number) => {\n setFormQuotas((prev) => prev.filter((_, i) => i !== idx));\n };\n\n const handleQuotaChange = (idx: number, field: 'key' | 'maxAllowed', value: any) => {\n setFormQuotas((prev) =>\n prev.map((row, i) => {\n if (i === idx) {\n return {\n ...row,\n [field]: field === 'maxAllowed' ? Math.max(1, parseInt(value, 10) || 1) : String(value).trim(),\n };\n }\n return row;\n })\n );\n };\n\n const handleSave = async () => {\n if (!formName.trim() || !formField.trim()) {\n toggleNotification({\n type: 'warning',\n message: 'Rule Name and Target Field are required.',\n });\n return;\n }\n\n const quotasRecord: Record<string, number> = {};\n for (const q of formQuotas) {\n if (q.key.trim()) {\n quotasRecord[q.key.trim().toLowerCase()] = q.maxAllowed;\n }\n }\n\n if (Object.keys(quotasRecord).length === 0) {\n toggleNotification({\n type: 'warning',\n message: 'At least one quota option with a limit is required.',\n });\n return;\n }\n\n try {\n setSaving(true);\n const payload: Partial<ValidationRule> = {\n id: editingRule ? editingRule.id : undefined,\n name: formName.trim(),\n description: formDesc.trim(),\n collectionUid: formCollectionUid,\n targetField: formField.trim(),\n quotas: quotasRecord,\n exceededAction: formAction,\n enabled: editingRule ? editingRule.enabled : true,\n scope: 'entry',\n includeRichTextHtml: formIncludeRichText,\n };\n\n const res = await post('/bulk-updater/validation-rules', { rule: payload });\n if (res.data && res.data.success) {\n toggleNotification({\n type: 'success',\n message: `Rule \"${payload.name}\" saved successfully!`,\n });\n setModalOpen(false);\n fetchRules();\n }\n } catch (err: any) {\n toggleNotification({\n type: 'danger',\n message: `Failed to save rule: ${err.message}`,\n });\n } finally {\n setSaving(false);\n }\n };\n\n const handleToggle = async (rule: ValidationRule) => {\n try {\n const res = await post(`/bulk-updater/validation-rules/${rule.id}/toggle`, {\n enabled: !rule.enabled,\n });\n if (res.data && res.data.success) {\n setRules((prev) =>\n prev.map((r) => (r.id === rule.id ? { ...r, enabled: !rule.enabled } : r))\n );\n toggleNotification({\n type: 'info',\n message: `Rule \"${rule.name}\" is now ${!rule.enabled ? 'ACTIVE' : 'DISABLED'}.`,\n });\n }\n } catch (err: any) {\n toggleNotification({\n type: 'danger',\n message: `Failed to update rule status: ${err.message}`,\n });\n }\n };\n\n const handleDelete = async (ruleId: string, ruleName: string) => {\n if (!window.confirm(`Are you sure you want to delete the rule \"${ruleName}\"?`)) return;\n\n try {\n const res = await del(`/bulk-updater/validation-rules/${ruleId}`);\n if (res.data && res.data.success) {\n setRules((prev) => prev.filter((r) => r.id !== ruleId));\n toggleNotification({\n type: 'success',\n message: `Rule \"${ruleName}\" deleted.`,\n });\n }\n } catch (err: any) {\n toggleNotification({\n type: 'danger',\n message: `Failed to delete rule: ${err.message}`,\n });\n }\n };\n\n return (\n <Box>\n <style>{`\n [data-radix-popper-content-wrapper] {\n z-index: 10005 !important;\n }\n `}</style>\n {/* Header Panel */}\n <Box padding={6} background=\"neutral0\" shadow=\"filterShadow\" hasRadius marginBottom={6}>\n <Flex justifyContent=\"space-between\" alignItems=\"center\" wrap=\"wrap\" gap={3}>\n <Box>\n <Typography variant=\"delta\" tag=\"h2\" fontWeight=\"bold\">\n Scoped & Cross-Component Validation Rules\n </Typography>\n <Typography variant=\"pi\" textColor=\"neutral600\" style={{ marginTop: 4 }}>\n Define collection-scoped rules and combined heading limits across structured components and free-form Rich Text / CKEditor HTML / Markdown content.\n </Typography>\n </Box>\n <Flex gap={2}>\n <Button\n variant=\"tertiary\"\n startIcon={<ArrowClockwise />}\n onClick={fetchRules}\n loading={loading}\n >\n Refresh\n </Button>\n <Button\n variant=\"default\"\n startIcon={<Plus />}\n onClick={openCreateModal}\n >\n Create New Rule\n </Button>\n </Flex>\n </Flex>\n </Box>\n\n {/* Rules Table */}\n <Box padding={6} background=\"neutral0\" shadow=\"filterShadow\" hasRadius>\n <Typography variant=\"sigma\" textColor=\"neutral600\" marginBottom={3} style={{ display: 'block' }}>\n CONFIGURED RULES ({rules.length})\n </Typography>\n\n {loading ? (\n <Typography variant=\"omega\" textColor=\"neutral500\">Loading validation rules...</Typography>\n ) : rules.length === 0 ? (\n <Alert variant=\"info\" title=\"No Rules Defined\">\n Click \"Create New Rule\" above to add your first cross-component quota rule.\n </Alert>\n ) : (\n <Table colCount={7} rowCount={rules.length + 1}>\n <Thead>\n <Tr>\n <Th><Typography variant=\"sigma\">RULE NAME & TARGET FIELD</Typography></Th>\n <Th><Typography variant=\"sigma\">COLLECTION SCOPE</Typography></Th>\n <Th><Typography variant=\"sigma\">QUOTA CONSTRAINTS</Typography></Th>\n <Th><Typography variant=\"sigma\">RICH TEXT / HTML</Typography></Th>\n <Th><Typography variant=\"sigma\">EXCEEDED ACTION</Typography></Th>\n <Th><Typography variant=\"sigma\">STATUS</Typography></Th>\n <Th style={{ textAlign: 'right' }}><Typography variant=\"sigma\">ACTIONS</Typography></Th>\n </Tr>\n </Thead>\n <Tbody>\n {rules.map((rule) => {\n const quotaKeys = Object.entries(rule.quotas || {});\n const isGlobal = !rule.collectionUid || rule.collectionUid === '*';\n const collectionName = !isGlobal\n ? (availableCollections.find((c) => c.uid === rule.collectionUid)?.displayName || rule.collectionUid)\n : 'All Collections (Global)';\n\n return (\n <Tr key={rule.id}>\n <Td style={{ minWidth: 200 }}>\n <Typography variant=\"omega\" fontWeight=\"bold\" textColor=\"neutral800\" display=\"block\">\n {rule.name}\n </Typography>\n <Typography variant=\"pi\" textColor=\"neutral500\">\n Target: <code>{rule.targetField}</code>\n </Typography>\n </Td>\n <Td style={{ minWidth: 160 }}>\n <Badge\n backgroundColor={isGlobal ? 'neutral150' : 'primary100'}\n textColor={isGlobal ? 'neutral700' : 'primary700'}\n >\n {collectionName}\n </Badge>\n </Td>\n <Td style={{ minWidth: 180 }}>\n <Flex gap={1} wrap=\"wrap\">\n {quotaKeys.map(([optVal, maxVal]) => (\n <Badge key={optVal} backgroundColor=\"neutral100\" textColor=\"primary700\">\n <strong>{optVal.toUpperCase()}</strong>: max {maxVal}\n </Badge>\n ))}\n </Flex>\n </Td>\n <Td style={{ minWidth: 140 }}>\n {rule.includeRichTextHtml ? (\n <Badge backgroundColor=\"success100\" textColor=\"success700\">\n HTML & Rich Text Active\n </Badge>\n ) : (\n <Badge backgroundColor=\"neutral150\" textColor=\"neutral600\">\n Structured Only\n </Badge>\n )}\n </Td>\n <Td style={{ minWidth: 110 }}>\n <Badge\n backgroundColor={rule.exceededAction === 'hide' ? 'secondary100' : 'warning100'}\n textColor={rule.exceededAction === 'hide' ? 'secondary700' : 'warning700'}\n >\n {rule.exceededAction.toUpperCase()}\n </Badge>\n </Td>\n <Td style={{ minWidth: 100 }}>\n <Button\n variant={rule.enabled ? 'success-light' : 'tertiary'}\n size=\"S\"\n onClick={() => handleToggle(rule)}\n >\n {rule.enabled ? '● ACTIVE' : '○ DISABLED'}\n </Button>\n </Td>\n <Td style={{ textAlign: 'right', minWidth: 260 }}>\n <Flex gap={2} justifyContent=\"flex-end\">\n <Button\n variant=\"secondary\"\n size=\"S\"\n startIcon={<Search />}\n onClick={() => handleScanRule(rule)}\n loading={scanningRuleId === rule.id}\n >\n Scan Violations\n </Button>\n <Button\n variant=\"tertiary\"\n size=\"S\"\n onClick={() => openEditModal(rule)}\n >\n Edit\n </Button>\n <Button\n variant=\"danger-light\"\n size=\"S\"\n startIcon={<Trash />}\n onClick={() => handleDelete(rule.id, rule.name)}\n >\n Delete\n </Button>\n </Flex>\n </Td>\n </Tr>\n );\n })}\n </Tbody>\n </Table>\n )}\n </Box>\n\n {/* Create / Edit Rule Modal */}\n {modalOpen && (\n <Box\n style={{\n position: 'fixed',\n inset: 0,\n backgroundColor: 'rgba(33, 33, 52, 0.65)',\n zIndex: 1000,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n }}\n >\n <Box\n background=\"neutral0\"\n hasRadius\n shadow=\"popupShadow\"\n padding={6}\n style={{ width: '90%', maxWidth: 640, maxHeight: '90vh', overflowY: 'auto' }}\n >\n <Typography variant=\"delta\" tag=\"h2\" fontWeight=\"bold\" marginBottom={1}>\n {editingRule ? 'Edit Validation Rule' : 'Create New Validation Rule'}\n </Typography>\n <Typography variant=\"pi\" textColor=\"neutral600\" marginBottom={4} style={{ display: 'block' }}>\n Configure collection-scoped quotas. Rules apply consistently to target properties and optionally scan rich text HTML content.\n </Typography>\n\n <Flex direction=\"column\" gap={4} alignItems=\"stretch\">\n <TextInput\n label=\"Rule Name\"\n placeholder=\"e.g. SEO Single H1 Page Rule\"\n value={formName}\n onChange={(e: any) => setFormName(e.target.value)}\n required\n />\n\n <SingleSelect\n label=\"Target Collection Type\"\n value={formCollectionUid}\n onChange={(val: any) => setFormCollectionUid(val)}\n hint=\"Scope this rule to a specific collection type, or select All Collections.\"\n >\n <SingleSelectOption value=\"*\">* (All Collections / Global)</SingleSelectOption>\n {availableCollections.map((c) => (\n <SingleSelectOption key={c.uid} value={c.uid}>\n {c.displayName} ({c.uid})\n </SingleSelectOption>\n ))}\n </SingleSelect>\n\n <TextInput\n label=\"Target Field / Component Property Path\"\n placeholder=\"e.g. titleStyle, titleHeadingStyle.titleStyle, or content.titleHeadingStyle.titleStyle\"\n value={formField}\n onChange={(e: any) => setFormField(e.target.value)}\n hint=\"Matches leaf key ('titleStyle'), component path ('titleHeadingStyle.titleStyle'), dynamic zone path ('content.titleHeadingStyle.titleStyle'), or collection-prefixed path ('st-featured.titleHeadingStyle.titleStyle').\"\n required\n />\n\n <Box padding={3} background=\"neutral100\" hasRadius style={{ border: '1px solid #e0e0e0' }}>\n <Checkbox\n checked={formIncludeRichText}\n onCheckedChange={(checked: boolean) => setFormIncludeRichText(checked)}\n >\n <Box marginLeft={2}>\n <Typography variant=\"omega\" fontWeight=\"bold\">\n Scan & Combine Rich Text / CKEditor HTML Headings\n </Typography>\n <Typography variant=\"pi\" textColor=\"neutral600\" display=\"block\">\n When enabled, any &lt;h1&gt;..&lt;h6&gt; tags, Markdown headings (#), or Strapi Blocks inside rich text fields are counted together with structured component choices towards the quota.\n </Typography>\n </Box>\n </Checkbox>\n </Box>\n\n <Textarea\n label=\"Rule Description\"\n placeholder=\"Briefly explain what this constraint accomplishes...\"\n value={formDesc}\n onChange={(e: any) => setFormDesc(e.target.value)}\n />\n\n <SingleSelect\n label=\"When Quota Is Exceeded in Another Component\"\n value={formAction}\n onChange={(val: any) => setFormAction(val as 'disable' | 'hide')}\n >\n <SingleSelectOption value=\"disable\">\n Disable Option with Usage Badge [(1/1 used)]\n </SingleSelectOption>\n <SingleSelectOption value=\"hide\">\n Hide Option completely from dropdown menu\n </SingleSelectOption>\n </SingleSelect>\n\n {/* Quotas Editor */}\n <Box\n padding={4}\n background=\"neutral100\"\n hasRadius\n style={{ border: '1px solid #e0e0e0' }}\n >\n <Flex justifyContent=\"space-between\" alignItems=\"center\" marginBottom={3}>\n <Box>\n <Typography variant=\"pi\" fontWeight=\"bold\" textColor=\"neutral800\">\n Option Quotas (Max Allowed per Entry)\n </Typography>\n <Typography variant=\"pi\" textColor=\"neutral600\" style={{ display: 'block' }}>\n Options left unlisted will have unlimited usage.\n </Typography>\n </Box>\n <Button\n variant=\"secondary\"\n size=\"S\"\n startIcon={<Plus />}\n onClick={handleAddQuotaRow}\n >\n Add Option\n </Button>\n </Flex>\n\n <Flex direction=\"column\" gap={2}>\n {formQuotas.map((q, idx) => (\n <Flex key={idx} gap={2} alignItems=\"center\">\n <Box style={{ flex: 2 }}>\n <TextInput\n placeholder=\"Option key (e.g. h1)\"\n value={q.key}\n onChange={(e: any) => handleQuotaChange(idx, 'key', e.target.value)}\n />\n </Box>\n <Box style={{ flex: 1 }}>\n <TextInput\n type=\"number\"\n placeholder=\"Max\"\n value={String(q.maxAllowed)}\n onChange={(e: any) => handleQuotaChange(idx, 'maxAllowed', e.target.value)}\n />\n </Box>\n <Button\n variant=\"ghost\"\n size=\"S\"\n onClick={() => handleRemoveQuotaRow(idx)}\n disabled={formQuotas.length <= 1}\n >\n ✕\n </Button>\n </Flex>\n ))}\n </Flex>\n </Box>\n </Flex>\n\n {/* Modal Actions */}\n <Flex justifyContent=\"flex-end\" gap={2} marginTop={6}>\n <Button\n variant=\"tertiary\"\n onClick={() => setModalOpen(false)}\n disabled={saving}\n >\n Cancel\n </Button>\n <Button\n variant=\"default\"\n startIcon={<Check />}\n onClick={handleSave}\n loading={saving}\n >\n Save Rule\n </Button>\n </Flex>\n </Box>\n </Box>\n )}\n\n {/* Scan Results Modal */}\n {scanModalOpen && scanReport && (\n <Box\n style={{\n position: 'fixed',\n inset: 0,\n backgroundColor: 'rgba(33, 33, 52, 0.65)',\n zIndex: 1000,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n }}\n >\n <Box\n background=\"neutral0\"\n hasRadius\n shadow=\"popupShadow\"\n padding={6}\n style={{ width: '90%', maxWidth: 780, maxHeight: '85vh', overflowY: 'auto' }}\n >\n <Flex justifyContent=\"space-between\" alignItems=\"center\" marginBottom={4}>\n <Box>\n <Typography variant=\"beta\" tag=\"h2\" fontWeight=\"bold\">\n Rule Violation Audit: {scanReport.rule?.name}\n </Typography>\n <Typography variant=\"pi\" textColor=\"neutral600\">\n Target Field: <code>{scanReport.rule?.targetField}</code> • Total Entries Scanned: {scanReport.totalScanned}\n </Typography>\n </Box>\n <Badge\n backgroundColor={scanReport.totalViolations > 0 ? 'danger100' : 'success100'}\n textColor={scanReport.totalViolations > 0 ? 'danger700' : 'success700'}\n size=\"M\"\n >\n {scanReport.totalViolations > 0\n ? `${scanReport.totalViolations} VIOLATION(S) FOUND`\n : '100% COMPLIANT'}\n </Badge>\n </Flex>\n\n {scanReport.totalViolations === 0 ? (\n <Alert variant=\"success\" title=\"No Pre-Existing Violations Detected\" marginBottom={4}>\n All existing documents across your collections adhere strictly to the configured quota limits.\n </Alert>\n ) : (\n <Box>\n <Alert variant=\"danger\" title=\"Legacy Records Found Exceeding Quota\" marginBottom={4}>\n The following {scanReport.totalViolations} record(s) contain more instances of restricted options than currently permitted by this rule.\n </Alert>\n\n <Table colCount={4} rowCount={scanReport.violations.length + 1}>\n <Thead>\n <Tr>\n <Th><Typography variant=\"sigma\">CONTENT TYPE & ENTRY</Typography></Th>\n <Th><Typography variant=\"sigma\">RESTRICTED OPTION</Typography></Th>\n <Th><Typography variant=\"sigma\">COUNT VS LIMIT</Typography></Th>\n <Th style={{ textAlign: 'right' }}><Typography variant=\"sigma\">ACTION</Typography></Th>\n </Tr>\n </Thead>\n <Tbody>\n {scanReport.violations.map((v: any, idx: number) => (\n <Tr key={idx}>\n <Td>\n <Typography variant=\"omega\" fontWeight=\"bold\">\n {v.entryLabel}\n </Typography>\n <Typography variant=\"pi\" textColor=\"neutral500\" display=\"block\">\n Collection: {v.collectionDisplayName}\n </Typography>\n {v.detail && (\n <Typography variant=\"pi\" textColor=\"neutral600\" display=\"block\" style={{ fontSize: 11 }}>\n Breakdown: {v.detail}\n </Typography>\n )}\n </Td>\n <Td>\n <Badge backgroundColor=\"warning100\" textColor=\"warning700\">\n {v.violatingOption}\n </Badge>\n </Td>\n <Td>\n <Typography variant=\"omega\" textColor=\"danger600\" fontWeight=\"bold\">\n {v.foundCount} used\n </Typography>\n <Typography variant=\"pi\" textColor=\"neutral500\">\n {' '}(Allowed max: {v.maxAllowed})\n </Typography>\n </Td>\n <Td style={{ textAlign: 'right' }}>\n <Button\n variant=\"secondary\"\n size=\"S\"\n onClick={() => window.open(v.editUrl, '_blank')}\n >\n Open in Editor ↗\n </Button>\n </Td>\n </Tr>\n ))}\n </Tbody>\n </Table>\n </Box>\n )}\n\n <Flex justifyContent=\"space-between\" alignItems=\"center\" marginTop={6}>\n {scanReport.totalViolations > 0 ? (\n <Button\n variant=\"secondary\"\n startIcon={<Download />}\n onClick={async () => {\n try {\n const res = await get(`/bulk-updater/csv/export-violations/${scanReport.rule.id}`);\n const csvStr = res.data?.csvContent || (typeof res.data === 'string' ? res.data : '');\n if (!csvStr) {\n toggleNotification({\n type: 'warning',\n message: 'No violation data to export',\n });\n return;\n }\n const safeContent = csvStr.startsWith('\\uFEFF') ? csvStr : '\\uFEFF' + csvStr;\n const blob = new Blob([safeContent], { type: 'text/csv;charset=utf-8;' });\n const url = URL.createObjectURL(blob);\n const link = document.createElement('a');\n link.href = url;\n link.setAttribute('download', `violations_${scanReport.rule.id}.csv`);\n document.body.appendChild(link);\n link.click();\n document.body.removeChild(link);\n URL.revokeObjectURL(url);\n toggleNotification({\n type: 'success',\n message: 'Violations exported to CSV successfully',\n });\n } catch (e: any) {\n toggleNotification({\n type: 'danger',\n message: e.message || 'Failed exporting violations CSV',\n });\n }\n }}\n >\n Export Violations CSV\n </Button>\n ) : (\n <Box />\n )}\n <Button variant=\"default\" onClick={() => setScanModalOpen(false)}>\n Close Report\n </Button>\n </Flex>\n </Box>\n </Box>\n )}\n </Box>\n );\n}\n"],"names":[],"mappings":"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"}
@@ -13,7 +13,7 @@ const index = {
13
13
  id: `${PLUGIN_ID}.plugin.name`,
14
14
  defaultMessage: "Bulk Attribute Updater"
15
15
  },
16
- Component: () => Promise.resolve().then(() => require("../_chunks/BulkUpdater-BosdSbGF.js")),
16
+ Component: () => Promise.resolve().then(() => require("../_chunks/BulkUpdater-DRHQBZZV.js")),
17
17
  permissions: [],
18
18
  position: 3
19
19
  });
@@ -24,7 +24,7 @@ const index = {
24
24
  defaultMessage: "Bulk Updater Settings"
25
25
  },
26
26
  to: `${PLUGIN_ID}`,
27
- Component: () => Promise.resolve().then(() => require("../_chunks/SettingsPage-B6Ia7SVS.js")),
27
+ Component: () => Promise.resolve().then(() => require("../_chunks/SettingsPage-M-HQ8Jtr.js")),
28
28
  permissions: []
29
29
  });
30
30
  app.registerPlugin({
@@ -44,7 +44,7 @@ const index = {
44
44
  defaultMessage: "Dropdown with dynamic cross-component usage quota enforcement"
45
45
  },
46
46
  components: {
47
- Input: async () => Promise.resolve().then(() => require("../_chunks/ScopedQuotaSelectInput-CyGlYa9x.js"))
47
+ Input: async () => Promise.resolve().then(() => require("../_chunks/ScopedQuotaSelectInput-BsBpmwun.js"))
48
48
  }
49
49
  });
50
50
  },
@@ -10,7 +10,7 @@ const index = {
10
10
  id: `${PLUGIN_ID}.plugin.name`,
11
11
  defaultMessage: "Bulk Attribute Updater"
12
12
  },
13
- Component: () => import("../_chunks/BulkUpdater-DUrmamj-.mjs"),
13
+ Component: () => import("../_chunks/BulkUpdater-J21ZgJWx.mjs"),
14
14
  permissions: [],
15
15
  position: 3
16
16
  });
@@ -21,7 +21,7 @@ const index = {
21
21
  defaultMessage: "Bulk Updater Settings"
22
22
  },
23
23
  to: `${PLUGIN_ID}`,
24
- Component: () => import("../_chunks/SettingsPage-Bdse5MP4.mjs"),
24
+ Component: () => import("../_chunks/SettingsPage-BDObdCIY.mjs"),
25
25
  permissions: []
26
26
  });
27
27
  app.registerPlugin({
@@ -41,7 +41,7 @@ const index = {
41
41
  defaultMessage: "Dropdown with dynamic cross-component usage quota enforcement"
42
42
  },
43
43
  components: {
44
- Input: async () => import("../_chunks/ScopedQuotaSelectInput-Cy3eEj9-.mjs")
44
+ Input: async () => import("../_chunks/ScopedQuotaSelectInput-YKdQgrPt.mjs")
45
45
  }
46
46
  });
47
47
  },