import QtQuick 2.15 import QtQuick.Controls 2.15 import QtQuick.Layouts 1.15 import org.kde.kirigami 2.5 as Kirigami Kirigami.FormLayout { property alias cfg_canvasUrl: canvasUrl.text property alias cfg_oauth2Token: oauth2Token.text property alias cfg_courses: courses.text TextField { id: canvasUrl Kirigami.FormData.label: i18n("Canvas URL:") placeholderText: i18n("https://your.canvas.url") } TextField { id: oauth2Token Kirigami.FormData.label: i18n("OAuth2 Token:") placeholderText: i18n("Generate in Canvas web interface") } function fetchCourses() { fetchCoursesStatus.text = i18n("Fetching…") let xhr = new XMLHttpRequest() xhr.open("GET", `${canvasUrl.text.replace(/\/$/, "")}/api/v1/courses?per_page=100`) xhr.setRequestHeader("Authorization", `Bearer ${oauth2Token.text}`) xhr.onload = () => { if (xhr.status == 200) { try { courses.clear() let json = JSON.parse(xhr.responseText) for (let c of json) { courses.append(`${c.id} ${c.course_code}`) } fetchCoursesStatus.text = i18n( "Done! To remove a course, just delete the line.\n" + "You can also rename a course, but do not change the numeric ID." ) } catch (e) { if (e instanceof SyntaxError) { console.error(`Cannot parse response for ${path} as JSON:\n${xhr.responseText}`) fetchCoursesStatus.text = i18n("Cannot parse API response") } else { throw e } } } else { console.error(`XHR failed when retrieving /courses (status ${xhr.status}):\n${xhr.responseText}`) fetchCoursesStatus.text = i18n("API call failed (HTTP status %1)", xhr.status) } } xhr.send() } ScrollView { Layout.fillWidth: true Kirigami.FormData.label: i18n("Courses:") TextArea { Layout.fillWidth: true id: courses placeholderText: i18n("Click Fetch courses for a full list") } } Button { icon.name: "download" text: "Fetch courses" onClicked: fetchCourses() } Label { id: fetchCoursesStatus text: "Fetching courses from Canvas will overwrite your current config." } }