()
| 1169 | } |
| 1170 | |
| 1171 | export async function openUserGroupsModal() { |
| 1172 | const isDark = document.body.classList.contains('dark-mode'); |
| 1173 | const overlayBg = isDark ? 'rgba(0,0,0,0.7)' : 'rgba(0,0,0,0.3)'; |
| 1174 | const contentBg = isDark ? '#2c2c2c' : '#fff'; |
| 1175 | const contentFg = isDark ? '#e0e0e0' : '#000'; |
| 1176 | const borderCol = isDark ? '#555' : '#ccc'; |
| 1177 | |
| 1178 | let modal = document.getElementById('userGroupsModal'); |
| 1179 | if (!modal) { |
| 1180 | modal = document.createElement('div'); |
| 1181 | modal.id = 'userGroupsModal'; |
| 1182 | modal.style.cssText = ` |
| 1183 | position:fixed; inset:0; background:${overlayBg}; |
| 1184 | display:flex; align-items:center; justify-content:center; z-index:3750; |
| 1185 | `; |
| 1186 | modal.innerHTML = ` |
| 1187 | <div class="modal-content" |
| 1188 | style="background:${contentBg}; color:${contentFg}; |
| 1189 | padding:16px; max-width:980px; width:95%; |
| 1190 | position:relative; |
| 1191 | border:1px solid ${borderCol}; max-height:90vh; overflow:auto;"> |
| 1192 | <span id="closeUserGroupsModal" |
| 1193 | class="editor-close-btn" |
| 1194 | style="right:8px; top:8px;">×</span> |
| 1195 | |
| 1196 | <h3>User Groups</h3> |
| 1197 | <p class="muted" style="margin-top:-6px;"> |
| 1198 | Define named groups, assign users to them, and attach folder access |
| 1199 | just like per-user ACL. Group access is additive to user access. |
| 1200 | </p> |
| 1201 | |
| 1202 | <div class="d-flex justify-content-between align-items-center" style="margin:8px 0 10px;"> |
| 1203 | <button type="button" id="addGroupBtn" class="btn btn-sm btn-success"> |
| 1204 | <i class="material-icons" style="font-size:16px;">group_add</i> |
| 1205 | <span style="margin-left:4px;">Add group</span> |
| 1206 | </button> |
| 1207 | <span id="userGroupsStatus" class="small text-muted"></span> |
| 1208 | </div> |
| 1209 | |
| 1210 | <div id="userGroupsBody" style="max-height:60vh; overflow:auto; margin-bottom:12px;"> |
| 1211 | ${t('loading')}… |
| 1212 | </div> |
| 1213 | |
| 1214 | <div style="display:flex; justify-content:flex-end; gap:8px;"> |
| 1215 | <button type="button" id="cancelUserGroups" class="btn btn-secondary">${t('cancel')}</button> |
| 1216 | <button type="button" id="saveUserGroups" class="btn btn-primary">${t('save_settings')}</button> |
| 1217 | </div> |
| 1218 | </div> |
| 1219 | `; |
| 1220 | document.body.appendChild(modal); |
| 1221 | |
| 1222 | document.getElementById('closeUserGroupsModal').onclick = () => (modal.style.display = 'none'); |
| 1223 | document.getElementById('cancelUserGroups').onclick = () => (modal.style.display = 'none'); |
| 1224 | document.getElementById('saveUserGroups').onclick = saveUserGroupsFromUI; |
| 1225 | document.getElementById('addGroupBtn').onclick = addEmptyGroupRow; |
| 1226 | } else { |
| 1227 | modal.style.background = overlayBg; |
| 1228 | const content = modal.querySelector('.modal-content'); |
no test coverage detected