(card, message)
| 2395 | }); |
| 2396 | |
| 2397 | const markCardMissingRequired = (card, message) => { |
| 2398 | // Mark visually |
| 2399 | card.classList.add('portal-card-has-error'); |
| 2400 | card.style.borderColor = '#dc3545'; |
| 2401 | card.style.boxShadow = '0 0 0 2px rgba(220,53,69,0.6)'; |
| 2402 | |
| 2403 | // Expand the card so the error is visible even if it was collapsed |
| 2404 | const header = card.querySelector('.portal-card-header'); |
| 2405 | const bodyEl = card.querySelector('.portal-card-body') || card; |
| 2406 | const caret = card.querySelector('.portal-card-caret'); |
| 2407 | |
| 2408 | if (header && bodyEl) { |
| 2409 | header.setAttribute('aria-expanded', 'true'); |
| 2410 | bodyEl.style.display = 'block'; |
| 2411 | if (caret) caret.textContent = '▾'; |
| 2412 | } |
| 2413 | |
| 2414 | // Small inline hint at top of the card body |
| 2415 | let hint = bodyEl.querySelector('.portal-card-error-hint'); |
| 2416 | if (!hint) { |
| 2417 | hint = document.createElement('div'); |
| 2418 | hint.className = 'portal-card-error-hint text-danger small'; |
| 2419 | hint.style.marginBottom = '6px'; |
| 2420 | hint.textContent = message || 'Slug and folder are required. This portal will not be saved until both are filled.'; |
| 2421 | bodyEl.insertBefore(hint, bodyEl.firstChild); |
| 2422 | } else { |
| 2423 | hint.textContent = message || hint.textContent; |
| 2424 | } |
| 2425 | }; |
| 2426 | |
| 2427 | cards.forEach(card => { |
| 2428 | const origSlug = card.getAttribute('data-portal-slug') || ''; |
no outgoing calls
no test coverage detected