Много разных изменений
This commit is contained in:
@@ -1,13 +1,29 @@
|
||||
import { api } from '../api.js';
|
||||
import {
|
||||
academicYearsFromSemesters,
|
||||
resolveAcademicPeriod,
|
||||
semestersForAcademicYear
|
||||
} from '../academic-period.js';
|
||||
import { escapeHtml } from '../utils.js';
|
||||
import { trackUxEvent } from '../../../telemetry.js';
|
||||
|
||||
let qualityState = null;
|
||||
|
||||
export async function initScheduleQuality() {
|
||||
const root = document.querySelector('.quality-lab');
|
||||
if (!root) return;
|
||||
qualityState = { root, analysis: null, versions: [], visibleProblems: [], selectedProblemId: null, applying: false };
|
||||
qualityState = {
|
||||
root,
|
||||
analysis: null,
|
||||
semesters: [],
|
||||
academicYearId: '',
|
||||
versions: [],
|
||||
visibleProblems: [],
|
||||
selectedProblemId: null,
|
||||
applying: false
|
||||
};
|
||||
root.querySelector('#quality-run')?.addEventListener('click', runAnalysis);
|
||||
root.querySelector('#quality-year')?.addEventListener('change', handleYearChange);
|
||||
root.querySelector('#quality-semester')?.addEventListener('change', loadVersions);
|
||||
root.querySelector('#quality-severity-filter')?.addEventListener('change', renderProblems);
|
||||
root.querySelector('#quality-type-filter')?.addEventListener('change', renderProblems);
|
||||
@@ -20,26 +36,18 @@ async function loadSemesters() {
|
||||
const select = qualityState?.root.querySelector('#quality-semester');
|
||||
if (!select) return;
|
||||
try {
|
||||
const semesters = await api.get('/api/schedule/semesters');
|
||||
select.innerHTML = (semesters || []).map(semester => `
|
||||
<option value="${escapeHtml(String(semester.id))}">
|
||||
${escapeHtml(semesterLabel(semester))}
|
||||
</option>
|
||||
`).join('');
|
||||
if (!semesters?.length) {
|
||||
select.innerHTML = '<option value="">Семестры не настроены</option>';
|
||||
qualityState.semesters = await api.get('/api/schedule/semesters');
|
||||
if (!qualityState.semesters?.length) {
|
||||
renderPeriodSelects('', '');
|
||||
qualityStatus('Сначала создайте учебный год и семестр.', 'warning');
|
||||
return;
|
||||
}
|
||||
const today = localIsoDate(new Date());
|
||||
const current = semesters.find(semester =>
|
||||
semester.startDate <= today && semester.endDate >= today
|
||||
);
|
||||
select.value = String(current?.id ?? semesters[0].id);
|
||||
const savedSemesterId = localStorage.getItem('magistr.quality.semesterId');
|
||||
if (semesters.some(semester => String(semester.id) === savedSemesterId)) {
|
||||
select.value = savedSemesterId;
|
||||
}
|
||||
const selected = resolveAcademicPeriod(qualityState.semesters, {
|
||||
academicYearId: localStorage.getItem('magistr.quality.yearId'),
|
||||
semesterId: localStorage.getItem('magistr.quality.semesterId'),
|
||||
date: localIsoDate(new Date())
|
||||
});
|
||||
renderPeriodSelects(selected.academicYearId, selected.semesterId);
|
||||
await loadVersions();
|
||||
} catch (error) {
|
||||
select.innerHTML = '<option value="">Ошибка загрузки</option>';
|
||||
@@ -47,6 +55,39 @@ async function loadSemesters() {
|
||||
}
|
||||
}
|
||||
|
||||
async function handleYearChange() {
|
||||
const yearId = qualityState?.root.querySelector('#quality-year')?.value || '';
|
||||
const selected = resolveAcademicPeriod(qualityState.semesters, {
|
||||
academicYearId: yearId,
|
||||
date: localIsoDate(new Date())
|
||||
});
|
||||
renderPeriodSelects(yearId, selected.semesterId);
|
||||
await loadVersions();
|
||||
}
|
||||
|
||||
function renderPeriodSelects(academicYearId, semesterId) {
|
||||
const yearSelect = qualityState?.root.querySelector('#quality-year');
|
||||
const semesterSelect = qualityState?.root.querySelector('#quality-semester');
|
||||
if (!yearSelect || !semesterSelect) return;
|
||||
const years = academicYearsFromSemesters(qualityState.semesters);
|
||||
qualityState.academicYearId = String(academicYearId || years[0]?.id || '');
|
||||
yearSelect.innerHTML = years.length
|
||||
? years.map(year => `<option value="${escapeHtml(year.id)}">${escapeHtml(year.title)}</option>`).join('')
|
||||
: '<option value="">Учебные годы не настроены</option>';
|
||||
yearSelect.value = qualityState.academicYearId;
|
||||
|
||||
const yearSemesters = semestersForAcademicYear(qualityState.semesters, qualityState.academicYearId);
|
||||
semesterSelect.innerHTML = yearSemesters.length
|
||||
? yearSemesters.map(semester => `
|
||||
<option value="${escapeHtml(String(semester.id))}">${escapeHtml(semesterLabel(semester))}</option>
|
||||
`).join('')
|
||||
: '<option value="">Семестры не настроены</option>';
|
||||
const selectedSemester = yearSemesters.find(semester => String(semester.id) === String(semesterId))
|
||||
|| yearSemesters[0];
|
||||
semesterSelect.value = String(selectedSemester?.id || '');
|
||||
localStorage.setItem('magistr.quality.yearId', qualityState.academicYearId);
|
||||
}
|
||||
|
||||
async function loadVersions() {
|
||||
const semesterId = qualityState?.root.querySelector('#quality-semester')?.value;
|
||||
const select = qualityState?.root.querySelector('#quality-version');
|
||||
@@ -69,6 +110,7 @@ async function loadVersions() {
|
||||
const saved = qualityState.versions.find(version => String(version.id) === savedVersionId);
|
||||
const published = qualityState.versions.find(version => version.status === 'PUBLISHED');
|
||||
select.value = String((saved || published || qualityState.versions[0]).id);
|
||||
localStorage.setItem('magistr.quality.yearId', qualityState.academicYearId);
|
||||
localStorage.setItem('magistr.quality.semesterId', semesterId);
|
||||
} catch (error) {
|
||||
select.innerHTML = '<option value="">Ошибка загрузки</option>';
|
||||
@@ -100,6 +142,11 @@ async function runAnalysis() {
|
||||
);
|
||||
qualityState.selectedProblemId = null;
|
||||
renderAnalysis();
|
||||
trackUxEvent('качество_расписания_проверено', {
|
||||
semesterId,
|
||||
versionId,
|
||||
score: Number(qualityState.analysis.score || 0)
|
||||
});
|
||||
qualityStatus(
|
||||
qualityState.analysis.scheduleVersionStatus === 'DRAFT'
|
||||
? 'Черновик проверен. Проблемные правила можно открыть в конструкторе до публикации.'
|
||||
@@ -261,6 +308,7 @@ function handleRulePanelClick(event) {
|
||||
|
||||
function openRuleInConstructor(problem) {
|
||||
if (!problem?.scheduleRuleId || qualityState?.analysis?.scheduleVersionStatus === 'ARCHIVED') return;
|
||||
localStorage.setItem('magistr.schedule.semesterId', String(qualityState.analysis.semesterId));
|
||||
localStorage.setItem('magistr.schedule.openVersionId', String(qualityState.analysis.scheduleVersionId));
|
||||
localStorage.setItem('magistr.schedule.openRuleId', String(problem.scheduleRuleId));
|
||||
document.querySelector('.nav-item[data-tab="schedule"]')?.click();
|
||||
|
||||
Reference in New Issue
Block a user