Add HF model auto-download with configurable AI env, and share link visibility toggles
This commit is contained in:
+29
-7
@@ -2,15 +2,27 @@ let links = [];
|
||||
let groups = [];
|
||||
let editingId = null;
|
||||
let studentsLoaded = false;
|
||||
let linkSettings = null;
|
||||
|
||||
async function loadLinkSettings() {
|
||||
if (!linkSettings) {
|
||||
const res = await fetch(`${API}/api/settings`, { headers: hdr() });
|
||||
linkSettings = await res.json().catch(() => ({}));
|
||||
}
|
||||
return linkSettings;
|
||||
}
|
||||
|
||||
function linkUrl(token) { return `${location.origin}/s/${token}`; }
|
||||
|
||||
async function loadLinks() {
|
||||
await loadLinkSettings();
|
||||
const res = await fetch(`${API}/api/links`, { headers: hdr() });
|
||||
links = await res.json();
|
||||
const el = document.getElementById('linksList');
|
||||
if (!links.length) { el.innerHTML = '<div class="empty">Ссылок пока нет. Создайте её в Журнале кнопкой «Ссылка».</div>'; return; }
|
||||
el.innerHTML = links.map(l => `
|
||||
el.innerHTML = links.map(l => {
|
||||
const namesHidden = l.show_student_names != null ? !l.show_student_names : linkSettings.share_show_student_names === 'false';
|
||||
return `
|
||||
<div class="item">
|
||||
<div style="min-width:0">
|
||||
<div class="name">${esc(l.name)}</div>
|
||||
@@ -19,7 +31,7 @@ async function loadLinks() {
|
||||
${l.student_name ? `${l.group_name ? ' · ' : ''}Ученик: <b>${esc(l.student_name)}</b>` : ''}
|
||||
${l.date_from || l.date_to ? ` · период: <b>${l.date_from ? l.date_from.split('-').reverse().join('.') : '…'}</b> — <b>${l.date_to ? l.date_to.split('-').reverse().join('.') : '…'}</b>` : ' · весь период'}
|
||||
${l.expires_at ? ` · истекает ${new Date(l.expires_at).toLocaleDateString('ru')}` : ''}
|
||||
${l.anonymize_names ? ` · <span style="color:#f59e0b">анонимизировано</span>` : ''}
|
||||
${namesHidden ? ` · <span style="color:#f59e0b">имена скрыты</span>` : ''}
|
||||
${l.access_password_hash ? ` · <span style="color:#2563eb">🔒 пароль</span>` : ''}
|
||||
· создана ${new Date(l.created_at).toLocaleString('ru')}
|
||||
</div>
|
||||
@@ -31,7 +43,7 @@ async function loadLinks() {
|
||||
<button class="btn-link" style="color:var(--muted)" data-del-link="${l.id}" title="Удалить">×</button>
|
||||
</div>
|
||||
</div>
|
||||
`).join('');
|
||||
`;}).join('');
|
||||
}
|
||||
|
||||
function fmtDate(d) { const [y, m, day] = (d || '').split('-'); return d ? `${day}.${m}.${y}` : ''; }
|
||||
@@ -43,10 +55,15 @@ async function openLinkModal() {
|
||||
document.getElementById('linkDateFrom').value = '';
|
||||
document.getElementById('linkDateTo').value = '';
|
||||
document.getElementById('linkExpiresDays').value = '7';
|
||||
document.getElementById('linkAnonymizeNames').checked = false;
|
||||
document.getElementById('linkShowNames').checked = false;
|
||||
document.getElementById('linkPassword').value = '';
|
||||
document.getElementById('linkMessage').value = '';
|
||||
document.getElementById('linkUrl').value = '';
|
||||
const s = await loadLinkSettings();
|
||||
document.getElementById('linkShowNames').checked = s.share_show_student_names !== 'false';
|
||||
document.getElementById('linkShowMessage').checked = s.share_show_student_message === 'true';
|
||||
document.getElementById('linkShowDate').checked = s.share_show_entry_date === 'true';
|
||||
document.getElementById('linkShowPhotos').checked = s.share_show_group_photos !== 'false';
|
||||
if (!groups.length) {
|
||||
const res = await fetch(`${API}/api/groups`, { headers: hdr() });
|
||||
groups = await res.json();
|
||||
@@ -72,10 +89,15 @@ async function openLinkEdit(id) {
|
||||
document.getElementById('linkDateFrom').value = l.date_from || '';
|
||||
document.getElementById('linkDateTo').value = l.date_to || '';
|
||||
document.getElementById('linkExpiresDays').value = l.expires_at ? Math.ceil((new Date(l.expires_at) - new Date()) / (1000 * 60 * 60 * 24)) : '7';
|
||||
document.getElementById('linkAnonymizeNames').checked = l.anonymize_names || false;
|
||||
document.getElementById('linkShowNames').checked = l.show_student_names != null ? !!l.show_student_names : true;
|
||||
document.getElementById('linkPassword').value = '';
|
||||
document.getElementById('linkMessage').value = l.message || '';
|
||||
document.getElementById('linkUrl').value = l.link_url || '';
|
||||
const s = await loadLinkSettings();
|
||||
document.getElementById('linkShowNames').checked = l.show_student_names != null ? !!l.show_student_names : s.share_show_student_names !== 'false';
|
||||
document.getElementById('linkShowMessage').checked = l.show_student_message != null ? !!l.show_student_message : s.share_show_student_message === 'true';
|
||||
document.getElementById('linkShowDate').checked = l.show_entry_date != null ? !!l.show_entry_date : s.share_show_entry_date === 'true';
|
||||
document.getElementById('linkShowPhotos').checked = l.show_group_photos != null ? !!l.show_group_photos : s.share_show_group_photos !== 'false';
|
||||
if (!groups.length) {
|
||||
const res = await fetch(`${API}/api/groups`, { headers: hdr() });
|
||||
groups = await res.json();
|
||||
@@ -106,14 +128,14 @@ async function saveLink() {
|
||||
const date_from = document.getElementById('linkDateFrom').value;
|
||||
const date_to = document.getElementById('linkDateTo').value;
|
||||
const expires_days = parseInt(document.getElementById('linkExpiresDays').value, 10);
|
||||
const anonymize_names = document.getElementById('linkAnonymizeNames').checked;
|
||||
const show_student_names = document.getElementById('linkShowNames').checked;
|
||||
const access_password = document.getElementById('linkPassword').value;
|
||||
const message = document.getElementById('linkMessage').value.trim();
|
||||
const link_url = document.getElementById('linkUrl').value.trim();
|
||||
if (!name) { alert('Введите название'); return; }
|
||||
if (expires_days < 1 || expires_days > 365) { alert('Дней истечения: 1-365'); return; }
|
||||
const expires_at = new Date(Date.now() + expires_days * 24 * 60 * 60 * 1000).toISOString();
|
||||
const body = JSON.stringify({ name, group_id: group_id || null, student_name: student_name || null, date_from: date_from || null, date_to: date_to || null, anonymize_names, expires_at, access_password: access_password || null, message: message || null, link_url: link_url || null });
|
||||
const body = JSON.stringify({ name, group_id: group_id || null, student_name: student_name || null, date_from: date_from || null, date_to: date_to || null, show_student_names, expires_at, access_password: access_password || null, message: message || null, link_url: link_url || null, show_student_message: document.getElementById('linkShowMessage').checked, show_entry_date: document.getElementById('linkShowDate').checked, show_group_photos: document.getElementById('linkShowPhotos').checked });
|
||||
const res = await fetch(editingId ? `${API}/api/links/${editingId}` : `${API}/api/links`, {
|
||||
method: editingId ? 'PUT' : 'POST',
|
||||
headers: hdrJson(),
|
||||
|
||||
Reference in New Issue
Block a user