From cd6801d625f2c43055105969adf85016f3201ec4 Mon Sep 17 00:00:00 2001 From: minie4 Date: Mon, 19 Jun 2023 23:58:17 +0200 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20Implement=20importing=20and=20expor?= =?UTF-8?q?ting=20of=20timetables?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 6 +++ package.json | 1 + src/components/settings/timetable-card.vue | 4 +- src/strings.js | 6 ++- src/views/settings/TimetableSettings.vue | 63 +++++++++++++++++++--- 5 files changed, 71 insertions(+), 9 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9115863..298e1fb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,6 +10,7 @@ "license": "GPL-3.0-or-later", "dependencies": { "dayjs": "^1.11.3", + "downloadjs": "^1.4.7", "lucide-vue-next": "^0.233.0", "swiper": "^9.3.2", "vue": "^3.2.37", @@ -3108,6 +3109,11 @@ "node": ">=6.0.0" } }, + "node_modules/downloadjs": { + "version": "1.4.7", + "resolved": "https://registry.npmjs.org/downloadjs/-/downloadjs-1.4.7.tgz", + "integrity": "sha512-LN1gO7+u9xjU5oEScGFKvXhYf7Y/empUIIEAGBs1LzUq/rg5duiDrkuH5A2lQGd5jfMOb9X9usDa2oVXwJ0U/Q==" + }, "node_modules/ejs": { "version": "3.1.9", "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.9.tgz", diff --git a/package.json b/package.json index 8a8a563..8e3f653 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,7 @@ }, "dependencies": { "dayjs": "^1.11.3", + "downloadjs": "^1.4.7", "lucide-vue-next": "^0.233.0", "swiper": "^9.3.2", "vue": "^3.2.37", diff --git a/src/components/settings/timetable-card.vue b/src/components/settings/timetable-card.vue index 02efa1c..8ccf196 100644 --- a/src/components/settings/timetable-card.vue +++ b/src/components/settings/timetable-card.vue @@ -8,9 +8,10 @@ import { AlertCircleIcon, CopyIcon, } from "lucide-vue-next"; +import { DownloadIcon } from "lucide-vue-next"; defineProps(["timetable", "editable", "selected"]); -defineEmits(["click", "edit", "delete", "copy"]); +defineEmits(["click", "edit", "delete", "copy", "export"]); const deleteConfirm = ref(false); @@ -36,6 +37,7 @@ watch(deleteConfirm, (value) => {
+ import TimetableCard from "@/components/settings/timetable-card.vue"; import { timetables, localTimetables, timetableId } from "@/store"; -import { PlusIcon } from "lucide-vue-next"; -import { toRaw } from "vue"; +import { PlusIcon, PaperclipIcon } from "lucide-vue-next"; +import { toRaw, ref } from "vue"; +import download from "downloadjs"; function copyTimetable(timetable) { const newTimetable = structuredClone(toRaw(timetable)); @@ -18,6 +19,33 @@ function createTimetable() { data: [], }); } + +const fileInput = ref(); +function importTimetable(event) { + const file = event.target.files[0]; + if (!file) return; + + const reader = new FileReader(); + reader.onload = (e) => { + const contents = e.target.result; + try { + const data = JSON.parse(contents); + if (!data.data) throw "Invalid data"; + localTimetables.value.push(data); + } catch (e) { + alert("Import failed! Check your timetable file!"); + } + }; + reader.readAsText(file); +} + +function exportTimetable(timetable) { + download( + JSON.stringify(timetable), + `timetable-${timetable.id}.json`, + "application/json" + ); +}