From a89539c9bbf54d8d91a43aa4c63a715a0444ca38 Mon Sep 17 00:00:00 2001 From: Christian Seyfferth Date: Wed, 16 Jan 2019 10:35:46 +0100 Subject: [PATCH] basic import and export working --- .vscode/launch.json | 22 ++++++++++++ app.js | 82 ++++++++++++++++++++++++++++++++++++--------- index.html | 13 +++---- js/shift.js | 68 ++++++++++++++++++++++++++++++------- js/vcal.js | 41 ++++++++++++++++++----- 5 files changed, 184 insertions(+), 42 deletions(-) create mode 100644 .vscode/launch.json diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..97f0ec7 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,22 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "chrome", + "request": "attach", + "name": "Attach to Chrome", + "port": 9222, + "webRoot": "${workspaceFolder}" + }, + { + "type": "chrome", + "request": "launch", + "name": "Launch Chrome against localhost", + "url": "http://localhost:5500", + "webRoot": "${workspaceFolder}" + }, + ] +} \ No newline at end of file diff --git a/app.js b/app.js index 4b7d598..14dd4e8 100644 --- a/app.js +++ b/app.js @@ -118,38 +118,48 @@ var app = new Vue({ } }, methods: { + makeToast(message) { + M.toast({ + html: message, + displayLength: this.config.toast_length + }); + }, + onFileChange: function (event) { var files = event.target.files || event.dataTransfer.files; this.handleInputFile(files[0]); this.uploadFileName = files[0].name + " [" + Math.round(files[0].size / 1024) + " kB]"; - M.toast({html:this.uploadFileName + " ausgewählt", displayLength:this.config.toast_length}); + this.makeToast(this.uploadFileName + " ausgewählt"); }, handleInputFile: function (file) { var reader = new FileReader(); var vm = this; reader.onload = (e) => { var data = !e ? reader.content : e.target.result; - var workbook = XLSX.read(data, { type: 'binary', cellDates: true, }); - if(workbook.Sheets["Dienstplan"] == null){ - file.status = "error"; + var isErfurterDienstplan = workbook.SheetNames.indexOf("Dienstplan") > -1; + + if(isErfurterDienstplan){ + vm.parseForErfurt(workbook.Sheets["Dienstplan"]); } else { - vm.parseWorksheet(workbook.Sheets["Dienstplan"]); - file.status = "success"; + var sheetName = workbook.SheetNames[0]; + vm.parseForStuttgart(workbook.Sheets[sheetName]); } }; reader.readAsBinaryString(file); - M.toast({html:this.uploadFileName + " wird eingelesen",displayLength: this.config.toast_length}); }, - parseWorksheet: function (dp) { + parseForErfurt: function (dp) { var arr = XLSX.utils.sheet_to_row_object_array(dp, { range: 1 }); var vm = this; var day; + + this.makeToast("Erfurter Dienstplan erkannt."); + arr.forEach(element => { moment.locale(vm.config.moment.parse_language); if (element.hasOwnProperty('Datum')) { @@ -157,11 +167,51 @@ var app = new Vue({ } if (element.hasOwnProperty('Dienst')) { var time = element.Zeit ? moment(element.Zeit) : day; - var date = day.hour(time.hour()).minute(time.minute()); - var bemerkung = !element.Bemerkung ? "" : element.Bemerkung.trim(); - var art = !element.Dienst ? "" : element.Dienst.trim(); - var name = !element.__EMPTY ? "" : element.__EMPTY.trim(); - vm.addShift(new Shift(art, name, date, bemerkung)); + var termin = { + datum: day.clone().hour(time.hour()).minute(time.minute()), + art: element.Dienst ? element.Dienst.trim() : "", + beschreibung: element.Bemerkung ? element.Bemerkung.trim(): "", + name: element.__EMPTY ? element.__EMPTY.trim() : "" + } + vm.addShift(new Shift(termin)); + } + }); + }, + parseForStuttgart: function (dp) { + var arr = XLSX.utils.sheet_to_json(dp, { + header: "A", + blankrows: false, + }); + var vm = this; + var day; + + this.makeToast("Stuttgarter Dienstplan erkannt."); + + arr.forEach(element => { + moment.locale(vm.config.moment.parse_language); + if (element.hasOwnProperty('C')) { + day = moment(element.C); + } + if (element.hasOwnProperty('D') && moment(element.D, "HH:mm").isValid()) { + var time = day.clone(); + var end = null; + if (typeof(element.D) === "object") { + time = moment(element.D); + } else if(element.D.indexOf("-") > -1 ) { + var tArray = element.D.split(" - "); + time = moment(tArray[0],"HH:mm"); + end = moment(tArray[1], "HH:mm"); + } + var termin = { + datum: day.clone().hour(time.hour()).minute(time.minute()), + ende: end ? end.format("HH:mm"): null, + ort: element.H ? element.H.trim() : "", + art: element.E ? element.E.trim() : "", + beschreibung: element.H ? element.H.trim(): "", + name: element.F ? element.F.trim() : "" + } + vm.addShift(new Shift(termin)); + } }); }, @@ -170,11 +220,11 @@ var app = new Vue({ }, removeShift: function (shift) { this.shifts.splice(this.shifts.indexOf(shift), 1); - M.toast({html:shift.VEventTitle + " gelöscht",displayLength: this.config.toast_length}); + this.makeToast(shift.VEventTitle + " gelöscht"); }, cleanStorage: function () { this.shifts = []; - M.toast({html:"Alle Einträge gelöscht",displayLength: this.config.toast_length}); + this.makeToast("Alle Einträge gelöscht"); }, createDownloadFile: function () { var vCal = new VCalendar("Dienstplan Kalender"); @@ -191,7 +241,7 @@ var app = new Vue({ } this.icsFile = window.URL.createObjectURL(this.blob); - M.toast({html:this.saveto + " erstellt.",displayLength: this.config.toast_length}); + this.makeToast(this.saveto + " erstellt."); }, downloadFile: function () { if (window.navigator.msSaveOrOpenBlob) { diff --git a/index.html b/index.html index 6b4b998..8dbe512 100644 --- a/index.html +++ b/index.html @@ -29,7 +29,7 @@ @@ -37,10 +37,10 @@
-
+
-

Dienste

+

Termine

@@ -61,6 +61,7 @@ - +
{{s.VEventTitle}} + {{ s.Ort }} {{s.Beginn}} - {{s.Ende}} @@ -75,7 +76,7 @@
{{shifts.length }} Dienste {{shifts.length }} Dienste
@@ -96,14 +97,14 @@ - Dienste löschen + Termine löschen

- Noch keine Dienste da + Noch keine Termine da

diff --git a/js/shift.js b/js/shift.js index 11ffdd8..d0230a3 100644 --- a/js/shift.js +++ b/js/shift.js @@ -88,15 +88,42 @@ Rule.defaults = function () { } var DURATION_RULES = Rule.defaults(); -function Shift(kind, name, date, info) { - 'use strict'; - this.Datum = date.format(DATE_INPUT_FORMAT); - this.Beginn = date.format(TIME_FORMAT); - this.Art = kind; - this.Beschreibung = info; - this.Name = name; - Shift.setDurationFromRules(this); +function Shift() { + var evt = window.event || arguments[1] || arguments.callee.caller.arguments[0]; + var target = evt.target || evt.srcElement; + + var options = {}; + + if (arguments[0]) options = arguments[0]; + + var default_args = { + 'art' : "", + 'name' : "DUMMY", + 'datum' : moment(), + 'beschreibung' : "", + 'ort' : "", + } + for (var index in default_args) { + if (typeof options[index] == "undefined") options[index] = default_args[index]; + } + + this.Datum = options.datum.format(DATE_INPUT_FORMAT); + this.Beginn = options.datum.format(TIME_FORMAT); + this.Art = options.art; + this.Beschreibung = options.beschreibung; + this.Name = options.name; + this.Ort = options.ort; + + if (typeof options.ende != "undefined") { + this.Ende = options.ende; + } else { + if (!options.dontSetDurationFromRules) { + Shift.setDurationFromRules(this); + } + } + } + Shift.prototype = { get Wochentag() { return this._date.clone().locale(MOMENT_LOCALE).format(WEEKDAY_FORMAT); @@ -153,6 +180,13 @@ Shift.prototype = { this._name = value ? value.trim() : ""; }, + get Ort() { + return this._ort; + }, + set Ort(value) { + this._ort = value ? value.trim() : ""; + }, + get VEventTitle() { return this.Name + " " + this.Art; }, @@ -197,15 +231,25 @@ Shift.setDurationFromRules = function (shift) { shift.Dauer = moment.duration(duration, 'm').locale(MOMENT_LOCALE); } Shift.prototype.toVEvent = function () { - 'use strict'; var end = this._begin.clone().add(this._duration); - return new VEvent(TIMEZONE_NAME, this._begin, end, this.VEventTitle, this.Beschreibung); + return new VEvent({ + startMoment: this._begin, + endMoment: end, + title: this.VEventTitle, + description: this.Beschreibung, + location: this.Ort + }); }; Shift.thaw = function (jsonShift) { - 'use strict'; moment.locale(MOMENT_LOCALE); var begin = moment(jsonShift._begin); - var shift = new Shift(jsonShift._kind, jsonShift._name, begin, jsonShift._description); + var shift = new Shift( + { + art: jsonShift._kind, + name: jsonShift._name, + datum: begin, + beschreibung: jsonShift._description + }); shift.id = jsonShift.id; shift.Dauer = moment.duration(jsonShift._duration); return shift; diff --git a/js/vcal.js b/js/vcal.js index 1fb0b4a..b8e4c78 100644 --- a/js/vcal.js +++ b/js/vcal.js @@ -72,21 +72,46 @@ function VCalendar(calendarName) { VCalendar.prototype = Object.create(VMeta.prototype); VCalendar.prototype.constructor = VCalendar; -function VEvent(timezoneName, startMoment, endMoment, title, description) { +function VEvent() { + var evt = window.event || arguments[1] || arguments.callee.caller.arguments[0]; + var target = evt.target || evt.srcElement; + + var options = {}; + + if (arguments[0]) options = arguments[0]; + + var default_args = { + 'tzName' : "Europe/Berlin", + 'startMoment' : moment(), + 'endMoment' : moment(), + 'uid' : VMeta.generateUID(), + 'dtStamp' : VMeta.formatDate(moment()) + "Z", + 'title' : "", + 'description' : "", + 'location' : "", + 'organizer' : "", + + } + for (var index in default_args) { + if (typeof options[index] == "undefined") options[index] = default_args[index]; + } + VMeta.call(this); this.tag = "VEVENT"; - this.set('DTSTART;TZID=' + timezoneName, VMeta.formatDate(startMoment)); - this.set('DTEND;TZID=' + timezoneName, VMeta.formatDate(endMoment)); - this.set('DTSTAMP', VMeta.formatDate(moment()) + "Z"); - this.set('UID', VMeta.generateUID()); - this.set('SUMMARY', title); - this.set('DESCRIPTION', description); + this.set('DTSTART;TZID=' + options.tzName, VMeta.formatDate(options.startMoment)); + this.set('DTEND;TZID=' + options.tzName, VMeta.formatDate(options.endMoment)); + this.set('DTSTAMP', options.dtStamp); + this.set('UID', options.uid); + this.set('SUMMARY', options.title); + this.set('DESCRIPTION', options.description); + this.set('LOCATION', options.location) this.set('CLASS', "PUBLIC"); this.set('TRANSP', "OPAQUE"); this.set('STATUS', "CONFIRMED"); - this.set('ORGANIZER', ""); + this.set('ORGANIZER', options.organizer); } + VEvent.prototype = Object.create(VMeta.prototype); VEvent.prototype.constructor = VEvent;