Add constraint group dividers, use wa-select/wa-button for constraint form, persist level/kind on add
This commit is contained in:
@@ -57,10 +57,10 @@
|
|||||||
.input-action:hover { opacity: 1; }
|
.input-action:hover { opacity: 1; }
|
||||||
#trip-settings { display: flex; align-items: center; gap: 0.5rem; margin-bottom: 0.75rem; }
|
#trip-settings { display: flex; align-items: center; gap: 0.5rem; margin-bottom: 0.75rem; }
|
||||||
#room-size { width: 3.5rem; font-size: 0.85rem; padding: 0.2rem; border: 1px solid var(--wa-color-neutral-300, #ccc); border-radius: 0.25rem; }
|
#room-size { width: 3.5rem; font-size: 0.85rem; padding: 0.2rem; border: 1px solid var(--wa-color-neutral-300, #ccc); border-radius: 0.25rem; }
|
||||||
.constraint-group { display: flex; flex-wrap: wrap; align-items: center; gap: 0.25rem; margin-bottom: 0.2rem; }
|
.constraint-group { display: flex; flex-wrap: wrap; align-items: center; gap: 0.25rem; padding-bottom: 0.3rem; margin-bottom: 0.3rem; border-bottom: 1px solid #909090; }
|
||||||
.constraint-level { font-size: 0.65rem; font-weight: bold; background: var(--wa-color-neutral-200, #ddd); color: var(--wa-color-neutral-700, #555); border-radius: 0.25rem; padding: 0.1rem 0.35rem; }
|
.constraint-level { font-size: 0.65rem; font-weight: bold; background: var(--wa-color-neutral-200, #ddd); color: var(--wa-color-neutral-700, #555); border-radius: 0.25rem; padding: 0.1rem 0.35rem; }
|
||||||
.constraint-add { display: flex; gap: 0.5rem; align-items: center; margin-top: 0.3rem; }
|
.constraint-add { display: flex; gap: 0.5rem; align-items: center; margin-top: 0.3rem; }
|
||||||
.constraint-add select { font-size: 0.75rem; padding: 0.15rem; border: 1px solid var(--wa-color-neutral-300, #ccc); border-radius: 0.25rem; }
|
.constraint-add wa-select { flex: 1; }
|
||||||
#conflicts { margin-bottom: 0.5rem; }
|
#conflicts { margin-bottom: 0.5rem; }
|
||||||
#mismatches { margin-bottom: 0.5rem; }
|
#mismatches { margin-bottom: 0.5rem; }
|
||||||
#hard-conflicts { margin-bottom: 0.5rem; }
|
#hard-conflicts { margin-bottom: 0.5rem; }
|
||||||
|
|||||||
@@ -387,50 +387,70 @@ async function loadStudents() {
|
|||||||
parent: ['must_not'],
|
parent: ['must_not'],
|
||||||
admin: ['must', 'prefer', 'prefer_not', 'must_not']
|
admin: ['must', 'prefer', 'prefer_not', 'must_not']
|
||||||
};
|
};
|
||||||
const levelSelect = document.createElement('select');
|
const levelSelect = document.createElement('wa-select');
|
||||||
|
levelSelect.size = 'small';
|
||||||
for (const level of ['student', 'parent', 'admin']) {
|
for (const level of ['student', 'parent', 'admin']) {
|
||||||
const opt = document.createElement('option');
|
const opt = document.createElement('wa-option');
|
||||||
opt.value = level;
|
opt.value = level;
|
||||||
opt.textContent = level.charAt(0).toUpperCase() + level.slice(1);
|
opt.textContent = capitalize(level);
|
||||||
levelSelect.appendChild(opt);
|
levelSelect.appendChild(opt);
|
||||||
}
|
}
|
||||||
const kindSelect = document.createElement('select');
|
levelSelect.value = 'student';
|
||||||
|
const kindSelect = document.createElement('wa-select');
|
||||||
|
kindSelect.size = 'small';
|
||||||
const updateKinds = () => {
|
const updateKinds = () => {
|
||||||
kindSelect.innerHTML = '';
|
kindSelect.querySelectorAll('wa-option').forEach(o => o.remove());
|
||||||
for (const kind of levelKinds[levelSelect.value]) {
|
for (const kind of levelKinds[levelSelect.value]) {
|
||||||
const opt = document.createElement('option');
|
const opt = document.createElement('wa-option');
|
||||||
opt.value = kind;
|
opt.value = kind;
|
||||||
opt.textContent = kindLabels[kind];
|
opt.textContent = kindLabels[kind];
|
||||||
kindSelect.appendChild(opt);
|
kindSelect.appendChild(opt);
|
||||||
}
|
}
|
||||||
|
kindSelect.value = levelKinds[levelSelect.value][0];
|
||||||
};
|
};
|
||||||
updateKinds();
|
updateKinds();
|
||||||
levelSelect.addEventListener('change', updateKinds);
|
levelSelect.addEventListener('wa-change', updateKinds);
|
||||||
const studentSelect = document.createElement('select');
|
const studentSelect = document.createElement('wa-select');
|
||||||
const defaultOpt = document.createElement('option');
|
studentSelect.size = 'small';
|
||||||
defaultOpt.value = '';
|
studentSelect.placeholder = 'Student\u2026';
|
||||||
defaultOpt.textContent = 'Student\u2026';
|
|
||||||
studentSelect.appendChild(defaultOpt);
|
|
||||||
for (const other of students) {
|
for (const other of students) {
|
||||||
if (other.id === student.id) continue;
|
if (other.id === student.id) continue;
|
||||||
const opt = document.createElement('option');
|
const opt = document.createElement('wa-option');
|
||||||
opt.value = other.id;
|
opt.value = other.id;
|
||||||
opt.textContent = other.name;
|
opt.textContent = other.name;
|
||||||
studentSelect.appendChild(opt);
|
studentSelect.appendChild(opt);
|
||||||
}
|
}
|
||||||
const cAddBtn = document.createElement('button');
|
const cAddBtn = document.createElement('wa-button');
|
||||||
cAddBtn.className = 'input-action';
|
cAddBtn.size = 'small';
|
||||||
cAddBtn.textContent = '+';
|
cAddBtn.textContent = '+';
|
||||||
cAddBtn.addEventListener('click', async () => {
|
cAddBtn.addEventListener('click', async () => {
|
||||||
const otherID = parseInt(studentSelect.value);
|
const otherID = parseInt(studentSelect.value);
|
||||||
if (!otherID) return;
|
if (!otherID) return;
|
||||||
|
const savedLevel = levelSelect.value;
|
||||||
|
const savedKind = kindSelect.value;
|
||||||
await api('POST', '/api/trips/' + tripID + '/constraints', {
|
await api('POST', '/api/trips/' + tripID + '/constraints', {
|
||||||
student_a_id: student.id,
|
student_a_id: student.id,
|
||||||
student_b_id: otherID,
|
student_b_id: otherID,
|
||||||
kind: kindSelect.value,
|
kind: savedKind,
|
||||||
level: levelSelect.value
|
level: savedLevel
|
||||||
});
|
});
|
||||||
loadStudents();
|
await loadStudents();
|
||||||
|
const card = document.querySelector('[data-student-id="' + student.id + '"]');
|
||||||
|
if (card) {
|
||||||
|
const selects = card.querySelectorAll('.constraint-add wa-select');
|
||||||
|
if (selects[0]) selects[0].value = savedLevel;
|
||||||
|
if (selects[1]) {
|
||||||
|
const kinds = levelKinds[savedLevel];
|
||||||
|
selects[1].querySelectorAll('wa-option').forEach(o => o.remove());
|
||||||
|
for (const kind of kinds) {
|
||||||
|
const opt = document.createElement('wa-option');
|
||||||
|
opt.value = kind;
|
||||||
|
opt.textContent = kindLabels[kind];
|
||||||
|
selects[1].appendChild(opt);
|
||||||
|
}
|
||||||
|
selects[1].value = savedKind;
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
addRow.appendChild(levelSelect);
|
addRow.appendChild(levelSelect);
|
||||||
addRow.appendChild(kindSelect);
|
addRow.appendChild(kindSelect);
|
||||||
|
|||||||
Reference in New Issue
Block a user