()
| 1709 | } |
| 1710 | |
| 1711 | async function saveUserGroupsFromUI() { |
| 1712 | const body = document.getElementById('userGroupsBody'); |
| 1713 | const status = document.getElementById('userGroupsStatus'); |
| 1714 | if (!body) return; |
| 1715 | |
| 1716 | const cards = body.querySelectorAll('[data-group-name]'); |
| 1717 | const groups = {}; |
| 1718 | |
| 1719 | cards.forEach(card => { |
| 1720 | const oldName = card.getAttribute('data-group-name') || ''; |
| 1721 | const nameEl = card.querySelector('input[data-group-field="name"]'); |
| 1722 | const labelEl = card.querySelector('input[data-group-field="label"]'); |
| 1723 | const membersSel = card.querySelector('select[data-group-field="members"]'); |
| 1724 | |
| 1725 | const name = (nameEl && nameEl.value || '').trim(); |
| 1726 | if (!name) return; |
| 1727 | |
| 1728 | const label = (labelEl && labelEl.value || '').trim() || name; |
| 1729 | const members = Array.from(membersSel && membersSel.selectedOptions || []).map(o => o.value); |
| 1730 | |
| 1731 | const existing = __groupsCache[oldName] || __groupsCache[name] || { grants: {}, grantsBySource: {} }; |
| 1732 | groups[name] = { |
| 1733 | name, |
| 1734 | label, |
| 1735 | members, |
| 1736 | grants: existing.grants || {} |
| 1737 | }; |
| 1738 | if (existing.grantsBySource && typeof existing.grantsBySource === 'object' && !Array.isArray(existing.grantsBySource)) { |
| 1739 | groups[name].grantsBySource = existing.grantsBySource; |
| 1740 | } |
| 1741 | }); |
| 1742 | |
| 1743 | if (status) { |
| 1744 | status.textContent = 'Saving groups…'; |
| 1745 | status.className = 'small text-muted'; |
| 1746 | } |
| 1747 | |
| 1748 | try { |
| 1749 | const res = await saveAllGroups(groups); |
| 1750 | if (!res.success) { |
| 1751 | showToast(res.error || t('admin_groups_save_error')); |
| 1752 | if (status) { |
| 1753 | status.textContent = 'Error saving groups.'; |
| 1754 | status.className = 'small text-danger'; |
| 1755 | } |
| 1756 | return; |
| 1757 | } |
| 1758 | |
| 1759 | __groupsCache = groups; |
| 1760 | if (status) { |
| 1761 | status.textContent = 'Groups saved.'; |
| 1762 | status.className = 'small text-success'; |
| 1763 | } |
| 1764 | showToast(t('admin_groups_saved')); |
| 1765 | } catch (e) { |
| 1766 | console.error(e); |
| 1767 | if (status) { |
| 1768 | status.textContent = 'Error saving groups.'; |
nothing calls this directly
no test coverage detected