Files
asuinventory/frontend/app.js
2025-11-10 11:28:49 +03:00

222 lines
6.8 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

const { createApp } = Vue;
const api = {
auds: "/auditories/",
oboruds: (audId) => `/oboruds/?aud_id=${encodeURIComponent(audId)}`,
owners: "/owners/",
};
async function fetchJSON(url) {
const res = await fetch(url);
if (!res.ok) throw new Error(`HTTP ${res.status}`);
return res.json();
}
createApp({
data() {
return {
view: 'byAud',
auditories: [],
selectedAudId: '',
oboruds: [],
status: '',
error: '',
// auth/user management
token: '',
role: '',
users: [],
newAdminUsername: '',
newAdminPassword: '',
newAudName: '',
owners: [],
newOwnerName: '',
};
},
computed: {
isAuth() { return !!this.token; },
isAdmin() { return this.role === 'admin'; },
isEditor() { return this.role === 'editor'; },
canEdit() { return this.isAdmin || this.isEditor; },
},
methods: {
logout() {
try {
localStorage.removeItem('access_token');
localStorage.removeItem('role');
} catch {}
this.token = '';
this.role = '';
this.users = [];
this.status = '';
this.error = '';
this.view = 'byAud';
// опционально: редирект на страницу логина
// window.location.href = '/login';
},
authHeaders() {
const h = {};
if (this.token) h['Authorization'] = `Bearer ${this.token}`;
return h;
},
async fetchAuth(url, options = {}) {
const opt = { ...options, headers: { ...(options.headers||{}), ...this.authHeaders() } };
const res = await fetch(url, opt);
if (!res.ok) {
const text = await res.text();
throw new Error(`HTTP ${res.status}: ${text}`);
}
return res.json();
},
async loadAuditories() {
this.status = 'Загрузка аудиторий…';
this.error = '';
try {
this.auditories = await fetchJSON(api.auds);
this.status = '';
} catch (e) {
console.error(e);
this.error = 'Не удалось загрузить аудитории';
this.status = '';
}
},
async loadOboruds() {
if (!this.selectedAudId) {
this.error = '';
this.status = 'Выберите аудиторию';
return;
}
this.status = 'Загрузка оборудования…';
this.error = '';
try {
this.oboruds = await fetchJSON(api.oboruds(this.selectedAudId));
// init selected owner helper field
this.oboruds.forEach(o => { o.selectedOwnerId = o.owner?.id || ''; });
this.status = '';
} catch (e) {
console.error(e);
this.error = 'Не удалось загрузить оборудование';
this.status = '';
}
},
async saveOwner(item) {
try {
this.status = 'Сохранение владельца…';
await this.fetchAuth(`/oboruds/${item.id}`, {
method: 'PATCH',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ owner_id: item.selectedOwnerId || null }),
});
this.status = 'Сохранено';
} catch (e) {
console.error(e);
this.error = 'Не удалось сохранить владельца';
this.status = '';
}
},
async loadOwners() {
try {
this.status = this.status || 'Загрузка владельцев…';
const data = await fetchJSON(api.owners);
this.owners = data;
this.status = '';
} catch (e) {
console.error(e);
this.error = 'Не удалось загрузить владельцев';
this.status = '';
}
},
async createOwner() {
if (!this.newOwnerName) {
this.status = 'Укажите имя владельца';
return;
}
try {
this.status = 'Добавление владельца…';
await this.fetchAuth(api.owners, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name: this.newOwnerName }),
});
this.newOwnerName = '';
await this.loadOwners();
// refresh table owner names if visible
if (this.selectedAudId) await this.loadOboruds();
this.status = 'Владелец добавлен';
} catch (e) {
console.error(e);
this.error = 'Не удалось добавить владельца';
this.status = '';
}
},
async loadUsers() {
try {
this.status = 'Загрузка пользователей…';
this.error = '';
this.users = await this.fetchAuth('/auth/users');
this.status = '';
} catch (e) {
console.error(e);
this.error = 'Не удалось загрузить пользователей';
this.status = '';
}
},
async createAdmin() {
if (!this.newAdminUsername || !this.newAdminPassword) {
this.status = 'Укажите логин и пароль';
return;
}
try {
this.status = 'Создание администратора…';
this.error = '';
await this.fetchAuth('/auth/users/admin', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ username: this.newAdminUsername, password: this.newAdminPassword }),
});
this.newAdminUsername = '';
this.newAdminPassword = '';
await this.loadUsers();
this.status = 'Администратор создан';
} catch (e) {
console.error(e);
this.error = 'Не удалось создать администратора';
this.status = '';
}
},
async createAuditory() {
if (!this.newAudName) {
this.status = 'Укажите название аудитории';
return;
}
try {
this.status = 'Добавление аудитории…';
this.error = '';
await this.fetchAuth('/auditories/', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ audnazvanie: this.newAudName }),
});
this.newAudName = '';
await this.loadAuditories();
this.status = 'Аудитория добавлена';
} catch (e) {
console.error(e);
this.error = 'Не удалось добавить аудиторию';
this.status = '';
}
}
},
mounted() {
// read auth from localStorage
try {
this.token = localStorage.getItem('access_token') || '';
this.role = localStorage.getItem('role') || '';
} catch {}
this.loadAuditories();
this.loadOwners();
if (this.isAdmin) {
this.loadUsers();
}
}
}).mount('#app');