-
Notifications
You must be signed in to change notification settings - Fork 20
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
287 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,266 @@ | ||
<script setup lang="ts"> | ||
import {ref, watch, onMounted} from 'vue'; | ||
import {csrfToken} from './api.js' | ||
let subject_inbus_selected = ref<number[]|null>(null); | ||
let subject_kelvin_selected = ref(null); | ||
let semester = ref(null); | ||
let busy = ref<boolean>(false); | ||
let semesters = ref(null); | ||
let semesters_loading = ref<boolean>(true); | ||
let inbus_and_kelvin_subjects_loading = ref<boolean>(true); | ||
let inbus_schedule_loaded = ref<boolean>(false); | ||
let subjects_inbus : InbusSubjectVersion[] | null = null; | ||
let subjects_inbus_filtered : InbusSubjectVersion[] | null= null; | ||
let subjects_kelvin : KelvinSubject[] | null = null; | ||
let subject_inbus_schedule = ref<ConcreteActivity[]|null>(null); | ||
let classes_to_import = ref([]); | ||
let result = ref(null); | ||
let canImport = ref(classes_to_import.value.length && !busy.value); | ||
function assembleRequest(url: string) : RequestInfo { | ||
const headers: Headers = new Headers(); | ||
headers.set('Content-Type', 'application/json'); | ||
headers.set('Accept', 'application/json'); | ||
const request: RequestInfo = new Request(url, { | ||
method: 'GET', | ||
headers: headers | ||
}); | ||
return request; | ||
} | ||
function svcc2num(svcc: string) : number { | ||
const [dept_code, version] : [string, string] = svcc.split('/'); | ||
const [dept, code] : [string, string] = dept_code.split('-'); | ||
const svcc_str = dept + code + version; | ||
const svcc_num = Number(svcc_str); | ||
return svcc_num; | ||
} | ||
class InbusGuarantee { | ||
personId: number | ||
login: string | ||
fullName: string | ||
} | ||
class InbusSubject { | ||
subjectId: number | ||
code: string | ||
abbrev: string | ||
title: string | ||
guarantee: InbusGuarantee | ||
} | ||
class InbusSubjectVersion { | ||
subjectVersionId: number | ||
subject: InbusSubject | ||
subjectVersionCompleteCode: string | ||
guarantee: InbusGuarantee | ||
} | ||
class KelvinSubject { | ||
name: string | ||
abbr: string | ||
} | ||
async function loadInbusAndKelvinSubjects() { | ||
const res1 = await fetch('/api/inbus/subject_versions', {}); | ||
const res2 = await fetch('/api/subjects/all', {}); | ||
subjects_inbus = await res1.json(); | ||
const subjects_kelvin_resp = await res2.json(); | ||
subjects_kelvin = subjects_kelvin_resp.subjects; | ||
subjects_kelvin.sort((a, b) => { | ||
const name_a = a.name.toUpperCase(); | ||
const name_b = b.name.toUpperCase(); | ||
if (name_a < name_b) { | ||
return -1; | ||
} | ||
if (name_a > name_b) { | ||
return 1; | ||
} | ||
return 0; | ||
}); | ||
const subject_kelvin_abbrs = subjects_kelvin.map(s => s.abbr); | ||
subjects_inbus_filtered = subjects_inbus.filter(subject_inbus => subject_kelvin_abbrs.includes(subject_inbus.subject.abbrev)); | ||
subjects_inbus_filtered = subjects_inbus_filtered.sort((a, b) => | ||
svcc2num(a.subjectVersionCompleteCode) - svcc2num(b.subjectVersionCompleteCode)); | ||
inbus_and_kelvin_subjects_loading.value = false; | ||
} | ||
class Semester { | ||
pk: number | ||
year: number | ||
winter: boolean | ||
} | ||
function parseSemesters(semesters_data : Semester[]) { | ||
semesters.value = semesters_data.map(sm => ({'pk': sm.pk, 'year': sm.year, 'winter': sm.winter, 'display': String(sm.year) + (sm.winter ? 'W' : 'S')})); | ||
semesters_loading.value = false; | ||
} | ||
async function loadSemesters() { | ||
const request = assembleRequest("/api/semesters") | ||
const res = await fetch(request, {}) | ||
const semesters_data = await res.json(); | ||
parseSemesters(semesters_data["semesters"]); | ||
} | ||
async function loadScheduleForSubjectVersionId(subject_inbus: InbusSubjectVersion) { | ||
const request = assembleRequest("/api/inbus/schedule/subject/version/" + subject_inbus.subjectVersionId) | ||
let res = await fetch(request, {}); | ||
subject_inbus_schedule = await res.json(); | ||
inbus_schedule_loaded.value = true; | ||
} | ||
async function importActivities() { | ||
busy.value = true; | ||
const req = { | ||
'semester_id': semester.value, | ||
'subject': subject_kelvin_selected.value, | ||
'activities': classes_to_import.value, | ||
}; | ||
console.log(req); | ||
const res = await fetch('/api/import/activities', { | ||
method: 'POST', | ||
headers: { | ||
'Accept': 'application/json', | ||
'Content-Type': 'application/json', | ||
'X-CSRFToken': csrfToken(), | ||
}, | ||
body: JSON.stringify(req), | ||
}); | ||
result.value = (await res.json()); | ||
busy.value = false; | ||
} | ||
onMounted(() => { | ||
watch(subject_inbus_selected, (newValue, oldValue) => { | ||
inbus_schedule_loaded.value = false; | ||
loadScheduleForSubjectVersionId(newValue); | ||
}); | ||
watch(classes_to_import, (newValue, oldValue) => { | ||
canImport.value = (classes_to_import.value.length && !busy.value); | ||
}); | ||
loadSemesters(); | ||
loadInbusAndKelvinSubjects(); | ||
}) | ||
</script> | ||
|
||
|
||
<template> | ||
<select v-if="!semesters_loading" v-model="semester"> | ||
<option v-for="item in semesters" :key="item.pk" :value="item.pk">{{item.display}}</option> | ||
</select> | ||
|
||
|
||
|
||
<select v-if="!inbus_and_kelvin_subjects_loading" v-model="subject_kelvin_selected"> | ||
<option v-for="item in subjects_kelvin" :key="item" :value="item">{{item.abbr}} - {{item.name}}</option> | ||
</select> | ||
|
||
|
||
|
||
<select v-if="!inbus_and_kelvin_subjects_loading" v-model="subject_inbus_selected"> | ||
<option v-for="item in subjects_inbus_filtered" :key="item" :value="item">{{item.subjectVersionCompleteCode}} - {{item.subject.abbrev}} - {{item.subject.title}}</option> | ||
</select> | ||
|
||
<table v-if="inbus_schedule_loaded" class="table table-hover table-stripped table-sm"> | ||
<tbody> | ||
<tr v-for="ca in subject_inbus_schedule"> | ||
<td> | ||
<label> | ||
<input type="checkbox" v-model="classes_to_import" :value="ca.concreteActivityId" name="classesToImport"/> | ||
{{ca.educationTypeAbbrev}} | ||
</label> | ||
</td> | ||
|
||
<td> | ||
{{ca.educationTypeAbbrev}}/{{ca.order}}, {{ca.subjectVersionCompleteCode}} | ||
</td> | ||
|
||
<td> | ||
{{ca.teacherFullNames}} | ||
</td> | ||
|
||
<td> | ||
{{ca.weekDayAbbrev}} | ||
</td> | ||
|
||
<td> | ||
{{ca.beginTime}} | ||
</td> | ||
|
||
<td> | ||
{{ca.endTime}} | ||
</td> | ||
</tr> | ||
</tbody> | ||
</table> | ||
|
||
|
||
<button class="btn" :class="{ 'btn-success': canImport, 'btn-danger': !canImport }" @click="importActivities" :disabled="!canImport"> | ||
<span v-if="busy">Importing...</span> | ||
<span v-else>Import</span> | ||
</button> | ||
|
||
|
||
<div> | ||
<div v-if="result"> | ||
<div v-if="result.error" class="alert alert-danger" role="alert"> | ||
{{ result.error }} | ||
</div> | ||
<div v-else> | ||
<table class="table table-sm table-hover table-striped"> | ||
<tbody> | ||
<tr v-for="item in result.users" :key="item.login"> | ||
<td>{{ item.login }}</td> | ||
<td>{{ item.firstname }}</td> | ||
<td>{{ item.lastname }}</td> | ||
<td>{{ item.created }}</td> | ||
</tr> | ||
</tbody> | ||
</table> | ||
</div> | ||
</div> | ||
</div> | ||
</template> | ||
|
||
|
||
<style scoped> | ||
</style> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
{% extends 'web/layout.html' %} | ||
|
||
{% block fullcontent %} | ||
<kelvin-import-inbus></kelvin-import-inbus> | ||
{% endblock %} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters