Added bulk import.
This commit is contained in:
parent
65e61a9fbf
commit
2b9b207e2d
|
@ -1,13 +1,15 @@
|
|||
import handy_httpd;
|
||||
import handy_httpd.handlers.path_handler;
|
||||
import std.stdio;
|
||||
import d2sqlite3;
|
||||
import std.process;
|
||||
|
||||
import db;
|
||||
import api_modules.auth;
|
||||
static import api_modules.classroom_compliance;
|
||||
|
||||
void main() {
|
||||
string env = environment.get("TEACHER_TOOLS_API_ENV", "DEV");
|
||||
|
||||
// Initialize the database on startup.
|
||||
auto db = getDb();
|
||||
db.close();
|
||||
|
@ -22,6 +24,11 @@ void main() {
|
|||
config.defaultHeaders["Access-Control-Request-Method"] = "*";
|
||||
config.defaultHeaders["Access-Control-Allow-Headers"] = "Authorization, Content-Length, Content-Type";
|
||||
|
||||
if (env == "PROD") {
|
||||
config.port = 8107;
|
||||
config.workerPoolSize = 5;
|
||||
}
|
||||
|
||||
|
||||
PathHandler handler = new PathHandler();
|
||||
handler.addMapping(Method.OPTIONS, "/api/**", &optionsEndpoint);
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
VITE_API_URL=https://teacher-tools.andrewlalis.com/api
|
|
@ -37,6 +37,8 @@ async function deleteThisClass() {
|
|||
<div class="button-bar" style="margin-bottom: 1em;">
|
||||
<button type="button" @click="router.push(`/classroom-compliance/classes/${cls.id}/edit-student`)">Add
|
||||
Student</button>
|
||||
<button type="button" @click="router.push(`/classroom-compliance/classes/${cls.id}/import-students`)">Import
|
||||
Students</button>
|
||||
<button type="button" @click="deleteThisClass">Delete this Class</button>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
<script setup lang="ts">
|
||||
import { showAlert } from '@/alerts';
|
||||
import { ClassroomComplianceAPIClient } from '@/api/classroom_compliance';
|
||||
import { useAuthStore } from '@/stores/auth';
|
||||
import { computed, ref } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
|
||||
const props = defineProps<{
|
||||
classId: string
|
||||
}>()
|
||||
const authStore = useAuthStore()
|
||||
const router = useRouter()
|
||||
const apiClient = new ClassroomComplianceAPIClient(authStore)
|
||||
|
||||
const textContent = ref('')
|
||||
const working = ref(false)
|
||||
const lines = computed(() => textContent.value.trim().split('\n').filter(s => s.trim().length > 0))
|
||||
const studentCount = computed(() => lines.value.length)
|
||||
|
||||
async function doImport() {
|
||||
working.value = true
|
||||
const classIdNumber = parseInt(props.classId, 10)
|
||||
for (let i = 0; i < lines.value.length; i++) {
|
||||
const line = lines.value[i]
|
||||
const student = await apiClient.createStudent(classIdNumber, { name: line, deskNumber: 0, removed: false })
|
||||
.handleErrorsWithAlert()
|
||||
if (!student) break;
|
||||
}
|
||||
working.value = false
|
||||
await showAlert('Created students!')
|
||||
await router.replace(`/classroom-compliance/classes/${classIdNumber}`)
|
||||
}
|
||||
</script>
|
||||
<template>
|
||||
<div>
|
||||
<h1>Import Students</h1>
|
||||
<p>
|
||||
Import a large number of students to a class at once by pasting their names in the text box below, with one
|
||||
student per line.
|
||||
</p>
|
||||
<form @submit.prevent="doImport">
|
||||
<textarea style="min-width: 300px; min-height: 500px;" v-model="textContent"></textarea>
|
||||
<div>
|
||||
<span>Detected <span>{{ studentCount }}</span> students in the above text.</span>
|
||||
</div>
|
||||
<div class="button-bar">
|
||||
<button type="submit" :disabled="working">Submit</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</template>
|
|
@ -54,6 +54,11 @@ const router = createRouter({
|
|||
component: () => import('@/apps/classroom_compliance/EditStudentView.vue'),
|
||||
props: true,
|
||||
},
|
||||
{
|
||||
path: 'classes/:classId/import-students',
|
||||
component: () => import('@/apps/classroom_compliance/ImportStudentsView.vue'),
|
||||
props: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
set -o pipefail
|
||||
|
||||
# Script for deploying the application to teacher-tools.andrewlalis.com.
|
||||
|
||||
echo "Building app"
|
||||
cd app
|
||||
rm -rf dist
|
||||
npm run build
|
||||
cd ..
|
||||
|
||||
echo "Building API"
|
||||
cd api
|
||||
dub clean
|
||||
dub build --build=release --compiler=/opt/ldc2/ldc2-1.36.0-linux-x86_64/bin/ldc2
|
||||
cd ..
|
||||
|
||||
ssh -f root@andrewlalis.com 'systemctl stop teacher-tools-api.service'
|
||||
scp api/teacher-tools-api root@andrewlalis.com:/opt/teacher-tools/
|
||||
rsync -rav -e ssh --delete app/dist/* root@andrewlalis.com:/opt/teacher-tools/app-content
|
||||
ssh -f root@andrewlalis.com 'systemctl start teacher-tools-api.service'
|
|
@ -0,0 +1,14 @@
|
|||
[Unit]
|
||||
Description=teacher-tools-api
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=root
|
||||
WorkingDirectory=/opt/teacher-tools
|
||||
Environment="TEACHER_TOOLS_API_ENV=PROD"
|
||||
ExecStart=/opt/teacher-tools/teacher-tools-api
|
||||
Restart=always
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
Loading…
Reference in New Issue