118 lines
3.9 KiB
JavaScript
118 lines
3.9 KiB
JavaScript
'use strict';
|
|
|
|
function adminApp() {
|
|
return {
|
|
me: null,
|
|
users: [],
|
|
schemes: [],
|
|
error: '',
|
|
tab: 'users',
|
|
|
|
user: { id: null, username: '', email: '', password: '', role: 'user', active: true },
|
|
scheme: { id: null, name: '', seed_color: '#1565c0', mode: 'light', is_default: false },
|
|
|
|
async init() {
|
|
try {
|
|
const me = await API.get('/api/me');
|
|
this.me = me.user;
|
|
if (me.user.role !== 'admin') { window.location.href = '/'; return; }
|
|
} catch (_) {
|
|
window.location.href = '/login.html';
|
|
return;
|
|
}
|
|
await this.loadSchemes();
|
|
await this.loadUsers();
|
|
const scheme = Theme.resolve(this.schemes, this.me.preferred_scheme_id);
|
|
await Theme.apply(scheme);
|
|
},
|
|
|
|
async loadUsers() {
|
|
try { this.users = (await API.get('/api/users')).users; }
|
|
catch (e) { this.toast(e.message); }
|
|
},
|
|
async loadSchemes() {
|
|
try { this.schemes = (await API.get('/api/schemes')).schemes; }
|
|
catch (e) { this.toast(e.message); }
|
|
},
|
|
schemeName(id) {
|
|
const s = this.schemes.find((x) => x.id === id);
|
|
return s ? s.name : '—';
|
|
},
|
|
|
|
// ---- Users ----
|
|
openNewUser() {
|
|
this.user = { id: null, username: '', email: '', password: '', role: 'user', active: true };
|
|
this.$refs.userDialog.showModal();
|
|
},
|
|
openEditUser(u) {
|
|
this.user = { id: u.id, username: u.username, email: u.email || '', password: '', role: u.role, active: !!u.active };
|
|
this.$refs.userDialog.showModal();
|
|
},
|
|
async saveUser() {
|
|
try {
|
|
if (this.user.id) {
|
|
const body = { email: this.user.email, role: this.user.role, active: this.user.active };
|
|
if (this.user.password) body.password = this.user.password;
|
|
await API.patch(`/api/users/${this.user.id}`, body);
|
|
} else {
|
|
await API.post('/api/users', {
|
|
username: this.user.username,
|
|
email: this.user.email,
|
|
password: this.user.password,
|
|
role: this.user.role,
|
|
active: this.user.active,
|
|
});
|
|
}
|
|
this.$refs.userDialog.close();
|
|
await this.loadUsers();
|
|
} catch (e) { this.toast(e.message); }
|
|
},
|
|
async deleteUser(u) {
|
|
if (!confirm(`Delete user "${u.username}"? Their projects and KPIs will also be removed.`)) return;
|
|
try { await API.del(`/api/users/${u.id}`); await this.loadUsers(); }
|
|
catch (e) { this.toast(e.message); }
|
|
},
|
|
|
|
// ---- Schemes ----
|
|
openNewScheme() {
|
|
this.scheme = { id: null, name: '', seed_color: '#1565c0', mode: 'light', is_default: false };
|
|
this.$refs.schemeDialog.showModal();
|
|
},
|
|
openEditScheme(s) {
|
|
this.scheme = { id: s.id, name: s.name, seed_color: s.seed_color, mode: s.mode, is_default: !!s.is_default };
|
|
this.$refs.schemeDialog.showModal();
|
|
},
|
|
previewScheme() {
|
|
Theme.apply({ seed_color: this.scheme.seed_color, mode: this.scheme.mode });
|
|
},
|
|
async saveScheme() {
|
|
try {
|
|
const body = {
|
|
name: this.scheme.name,
|
|
seed_color: this.scheme.seed_color,
|
|
mode: this.scheme.mode,
|
|
is_default: this.scheme.is_default,
|
|
};
|
|
if (this.scheme.id) await API.patch(`/api/schemes/${this.scheme.id}`, body);
|
|
else await API.post('/api/schemes', body);
|
|
this.$refs.schemeDialog.close();
|
|
await this.loadSchemes();
|
|
// Restore the admin's own theme after previewing.
|
|
await Theme.apply(Theme.resolve(this.schemes, this.me.preferred_scheme_id));
|
|
} catch (e) { this.toast(e.message); }
|
|
},
|
|
async deleteScheme(s) {
|
|
if (!confirm(`Delete scheme "${s.name}"?`)) return;
|
|
try { await API.del(`/api/schemes/${s.id}`); await this.loadSchemes(); }
|
|
catch (e) { this.toast(e.message); }
|
|
},
|
|
|
|
toast(msg) {
|
|
this.error = msg;
|
|
if (typeof window.ui === 'function') window.ui('#snackbar');
|
|
},
|
|
};
|
|
}
|
|
|
|
window.adminApp = adminApp;
|