Web polish from testing feedback + admin role toggle
- style the settings-table dropdowns for the dark theme (were white)
- share-icon picker on one even row (no lopsided wrap)
- more breathing room between colour hex and swatch
- user management: promote/demote admin (new PUT /users/{id}/admin,
guarded against self-change and removing the last admin)
- calendar management table: clip/ellipsis cells so narrow columns no
longer overlap (full-width detail rows still wrap)
- centralise default colours: utils.applyTheme now derives every fallback
from settings-sync.DEFAULT_COLORS (single place for coders to edit)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -4248,20 +4248,32 @@ async function loadUsers() {
|
||||
try {
|
||||
const users = await api.get('/users/');
|
||||
const list = document.getElementById('users-list');
|
||||
list.innerHTML = users.map(u =>
|
||||
`<div class="users-list-item">
|
||||
const selfId = JSON.parse(localStorage.getItem('user') || '{}').id;
|
||||
list.innerHTML = users.map(u => {
|
||||
const isSelf = u.id === selfId;
|
||||
return `<div class="users-list-item">
|
||||
<div>
|
||||
<div class="uname">${escHtml(u.username)}</div>
|
||||
${u.email ? `<div class="uemail">${escHtml(u.email)}</div>` : ''}
|
||||
</div>
|
||||
<div style="display:flex;gap:8px;align-items:center">
|
||||
${u.is_admin ? '<span class="ubadge">Admin</span>' : ''}
|
||||
${u.id !== JSON.parse(localStorage.getItem('user')||'{}').id
|
||||
? `<button class="btn btn-ghost" style="padding:4px 10px;font-size:12px" data-del-user="${u.id}">Löschen</button>`
|
||||
: ''}
|
||||
${isSelf ? '' :
|
||||
`<button class="btn btn-ghost" style="padding:4px 10px;font-size:12px" data-admin-user="${u.id}" data-admin-next="${u.is_admin ? '0' : '1'}">${u.is_admin ? t('users_revoke_admin') : t('users_make_admin')}</button>`}
|
||||
${isSelf ? '' :
|
||||
`<button class="btn btn-ghost" style="padding:4px 10px;font-size:12px" data-del-user="${u.id}">${t('delete')}</button>`}
|
||||
</div>
|
||||
</div>`
|
||||
).join('');
|
||||
</div>`;
|
||||
}).join('');
|
||||
|
||||
list.querySelectorAll('[data-admin-user]').forEach(btn => {
|
||||
btn.addEventListener('click', async () => {
|
||||
try {
|
||||
await api.put(`/users/${btn.dataset.adminUser}/admin`, { is_admin: btn.dataset.adminNext === '1' });
|
||||
loadUsers();
|
||||
} catch (e) { showToast(e.message, true); }
|
||||
});
|
||||
});
|
||||
|
||||
list.querySelectorAll('[data-del-user]').forEach(btn => {
|
||||
btn.addEventListener('click', async () => {
|
||||
|
||||
Reference in New Issue
Block a user