поправил добавление дисциплин и расписание занятий
This commit is contained in:
@@ -289,6 +289,25 @@
|
||||
grid-template-columns: repeat(8, minmax(125px, 1fr)) auto;
|
||||
}
|
||||
|
||||
.subject-import-rows-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.75rem;
|
||||
margin-top: 0.75rem;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.subject-import-row {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(120px, 1fr) minmax(200px, 3fr) auto;
|
||||
gap: 0.75rem;
|
||||
align-items: end;
|
||||
padding: 0.75rem;
|
||||
background: var(--bg-input);
|
||||
border: 1px solid var(--bg-card-border);
|
||||
border-radius: var(--radius-sm);
|
||||
}
|
||||
|
||||
.schedule-rule-actions {
|
||||
margin-top: 0.25rem;
|
||||
clear: both;
|
||||
@@ -1259,6 +1278,10 @@
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.subject-import-row {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.calendar-fill-panel {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
@@ -12,6 +12,8 @@ export async function initDepartmentWorkspace() {
|
||||
const endInput = document.getElementById('department-workspace-end');
|
||||
const refreshButton = document.getElementById('department-workspace-refresh');
|
||||
const importForm = document.getElementById('department-subject-import-form');
|
||||
const importRowsContainer = document.getElementById('subject-import-rows');
|
||||
const importAddButton = document.getElementById('subject-import-add');
|
||||
const subjectsTbody = document.getElementById('department-subjects-tbody');
|
||||
const subjectCount = document.getElementById('department-subject-count');
|
||||
const commentsCard = document.getElementById('department-comments-card');
|
||||
@@ -32,6 +34,15 @@ export async function initDepartmentWorkspace() {
|
||||
startInput?.addEventListener('change', handleStartDateChange);
|
||||
endInput?.addEventListener('change', loadWorkload);
|
||||
importForm?.addEventListener('submit', importSubjects);
|
||||
importAddButton?.addEventListener('click', () => renderImportRows([...readImportRows(), { code: '', name: '' }]));
|
||||
importRowsContainer?.addEventListener('click', (event) => {
|
||||
const removeBtn = event.target.closest('.subject-import-remove');
|
||||
if (removeBtn) {
|
||||
const rows = readImportRows();
|
||||
rows.splice(Number(removeBtn.dataset.index), 1);
|
||||
renderImportRows(rows.length ? rows : [{ code: '', name: '' }]);
|
||||
}
|
||||
});
|
||||
commentsForm?.addEventListener('submit', saveComment);
|
||||
commentsCloseButton?.addEventListener('click', () => {
|
||||
commentsCard.hidden = true;
|
||||
@@ -50,6 +61,7 @@ export async function initDepartmentWorkspace() {
|
||||
departmentField.hidden = true;
|
||||
departmentSelect.value = userDepartmentId || '';
|
||||
}
|
||||
renderImportRows([{ code: '', name: '' }]);
|
||||
await loadWorkspace();
|
||||
} catch (error) {
|
||||
showAlert('department-workspace-alert', error.message || 'Ошибка загрузки кабинета кафедры', 'error');
|
||||
@@ -96,38 +108,57 @@ export async function initDepartmentWorkspace() {
|
||||
}
|
||||
}
|
||||
|
||||
function renderImportRows(rows) {
|
||||
if (!importRowsContainer) return;
|
||||
importRowsContainer.innerHTML = (rows || [{ code: '', name: '' }]).map((row, index) => `
|
||||
<div class="subject-import-row" data-index="${index}">
|
||||
<div class="form-group">
|
||||
<label>Код</label>
|
||||
<input type="text" class="subject-import-code" value="${escapeHtml(row.code || '')}" placeholder="DB201">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Название</label>
|
||||
<input type="text" class="subject-import-name" value="${escapeHtml(row.name || '')}" placeholder="Базы данных">
|
||||
</div>
|
||||
<button type="button" class="btn-delete subject-import-remove" data-index="${index}">Удалить</button>
|
||||
</div>
|
||||
`).join('');
|
||||
}
|
||||
|
||||
function readImportRows() {
|
||||
if (!importRowsContainer) return [];
|
||||
return Array.from(importRowsContainer.querySelectorAll('.subject-import-row')).map(row => ({
|
||||
code: (row.querySelector('.subject-import-code')?.value || '').trim(),
|
||||
name: (row.querySelector('.subject-import-name')?.value || '').trim()
|
||||
}));
|
||||
}
|
||||
|
||||
async function importSubjects(event) {
|
||||
event.preventDefault();
|
||||
const alertId = 'department-subject-import-alert';
|
||||
hideAlert(alertId);
|
||||
const departmentId = selectedDepartmentId();
|
||||
const rows = document.getElementById('department-subject-import-text').value
|
||||
.split('\n')
|
||||
.map(row => row.trim())
|
||||
.filter(Boolean)
|
||||
.map(row => {
|
||||
const [code, ...nameParts] = row.split(';');
|
||||
return {
|
||||
code: (code || '').trim(),
|
||||
name: nameParts.join(';').trim(),
|
||||
departmentId: Number(departmentId)
|
||||
};
|
||||
})
|
||||
.filter(item => item.name);
|
||||
const rows = readImportRows()
|
||||
.filter(item => item.name)
|
||||
.map(item => ({
|
||||
code: item.code,
|
||||
name: item.name,
|
||||
departmentId: Number(departmentId)
|
||||
}));
|
||||
|
||||
if (!departmentId) {
|
||||
showAlert(alertId, 'Выберите кафедру', 'error');
|
||||
return;
|
||||
}
|
||||
if (!rows.length) {
|
||||
showAlert(alertId, 'Добавьте хотя бы одну строку в формате «код; название»', 'error');
|
||||
showAlert(alertId, 'Заполните название хотя бы одной дисциплины', 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const result = await api.post('/api/department/subjects/import', rows);
|
||||
showAlert(alertId, result.message || 'Дисциплины загружены', 'success');
|
||||
document.getElementById('department-subject-import-text').value = '';
|
||||
renderImportRows([{ code: '', name: '' }]);
|
||||
await loadSubjects();
|
||||
} catch (error) {
|
||||
showAlert(alertId, error.message || 'Ошибка загрузки дисциплин', 'error');
|
||||
|
||||
@@ -416,9 +416,7 @@ export async function initSchedule() {
|
||||
if (!lessons.length) return '';
|
||||
const oddLessons = lessons.filter(lesson => lesson.parity === 'BOTH' || lesson.parity === 'ODD');
|
||||
const evenLessons = lessons.filter(lesson => lesson.parity === 'BOTH' || lesson.parity === 'EVEN');
|
||||
const shouldSplit = oddLessons.length > 0
|
||||
&& evenLessons.length > 0
|
||||
&& visualLessonSignature(oddLessons) !== visualLessonSignature(evenLessons);
|
||||
const shouldSplit = lessons.some(l => l.parity !== 'BOTH');
|
||||
|
||||
if (!shouldSplit) {
|
||||
return `<div class="schedule-visual-unified">${uniqueVisualLessons(lessons).map(renderVisualLesson).join('')}</div>`;
|
||||
@@ -1111,21 +1109,7 @@ export async function initSchedule() {
|
||||
function compactWeekRanges(weeks) {
|
||||
const uniqueWeeks = [...new Set((weeks || []).map(Number).filter(Boolean))].sort((a, b) => a - b);
|
||||
if (!uniqueWeeks.length) return '';
|
||||
const ranges = [];
|
||||
let start = uniqueWeeks[0];
|
||||
let previous = uniqueWeeks[0];
|
||||
for (let index = 1; index < uniqueWeeks.length; index += 1) {
|
||||
const week = uniqueWeeks[index];
|
||||
if (week === previous + 1) {
|
||||
previous = week;
|
||||
continue;
|
||||
}
|
||||
ranges.push(weekRangeText(start, previous));
|
||||
start = week;
|
||||
previous = week;
|
||||
}
|
||||
ranges.push(weekRangeText(start, previous));
|
||||
return `(${ranges.join(', ')})`;
|
||||
return `(${weekRangeText(uniqueWeeks[0], uniqueWeeks[uniqueWeeks.length - 1])})`;
|
||||
}
|
||||
|
||||
function weekRangeText(start, end) {
|
||||
|
||||
@@ -30,9 +30,12 @@
|
||||
<h2>Загрузка дисциплин</h2>
|
||||
</div>
|
||||
<form id="department-subject-import-form" class="stack-form">
|
||||
<div class="form-group">
|
||||
<label for="department-subject-import-text">Строки в формате «код; название»</label>
|
||||
<textarea id="department-subject-import-text" rows="8" placeholder="DB201; Базы данных AI101; Искусственный интеллект"></textarea>
|
||||
<div class="subject-import-slots-panel">
|
||||
<div class="card-header-row">
|
||||
<label class="schedule-section-label" style="margin:0">Дисциплины для загрузки</label>
|
||||
<button type="button" class="btn-edit-classroom" id="subject-import-add">Добавить строку</button>
|
||||
</div>
|
||||
<div id="subject-import-rows" class="subject-import-rows-list"></div>
|
||||
</div>
|
||||
<button type="submit" class="btn-primary">Загрузить</button>
|
||||
<div class="form-alert" id="department-subject-import-alert" role="alert"></div>
|
||||
|
||||
Reference in New Issue
Block a user