basic import and export working

This commit is contained in:
Christian Seyfferth 2019-01-16 10:35:46 +01:00
parent 921bc18061
commit a89539c9bb
5 changed files with 184 additions and 42 deletions

22
.vscode/launch.json vendored Normal file
View File

@ -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}"
},
]
}

82
app.js
View File

@ -118,38 +118,48 @@ var app = new Vue({
} }
}, },
methods: { methods: {
makeToast(message) {
M.toast({
html: message,
displayLength: this.config.toast_length
});
},
onFileChange: function (event) { onFileChange: function (event) {
var files = event.target.files || event.dataTransfer.files; var files = event.target.files || event.dataTransfer.files;
this.handleInputFile(files[0]); this.handleInputFile(files[0]);
this.uploadFileName = files[0].name + " [" + Math.round(files[0].size / 1024) + " kB]"; 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) { handleInputFile: function (file) {
var reader = new FileReader(); var reader = new FileReader();
var vm = this; var vm = this;
reader.onload = (e) => { reader.onload = (e) => {
var data = !e ? reader.content : e.target.result; var data = !e ? reader.content : e.target.result;
var workbook = XLSX.read(data, { var workbook = XLSX.read(data, {
type: 'binary', type: 'binary',
cellDates: true, cellDates: true,
}); });
if(workbook.Sheets["Dienstplan"] == null){ var isErfurterDienstplan = workbook.SheetNames.indexOf("Dienstplan") > -1;
file.status = "error";
if(isErfurterDienstplan){
vm.parseForErfurt(workbook.Sheets["Dienstplan"]);
} else { } else {
vm.parseWorksheet(workbook.Sheets["Dienstplan"]); var sheetName = workbook.SheetNames[0];
file.status = "success"; vm.parseForStuttgart(workbook.Sheets[sheetName]);
} }
}; };
reader.readAsBinaryString(file); 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, { var arr = XLSX.utils.sheet_to_row_object_array(dp, {
range: 1 range: 1
}); });
var vm = this; var vm = this;
var day; var day;
this.makeToast("Erfurter Dienstplan erkannt.");
arr.forEach(element => { arr.forEach(element => {
moment.locale(vm.config.moment.parse_language); moment.locale(vm.config.moment.parse_language);
if (element.hasOwnProperty('Datum')) { if (element.hasOwnProperty('Datum')) {
@ -157,11 +167,51 @@ var app = new Vue({
} }
if (element.hasOwnProperty('Dienst')) { if (element.hasOwnProperty('Dienst')) {
var time = element.Zeit ? moment(element.Zeit) : day; var time = element.Zeit ? moment(element.Zeit) : day;
var date = day.hour(time.hour()).minute(time.minute()); var termin = {
var bemerkung = !element.Bemerkung ? "" : element.Bemerkung.trim(); datum: day.clone().hour(time.hour()).minute(time.minute()),
var art = !element.Dienst ? "" : element.Dienst.trim(); art: element.Dienst ? element.Dienst.trim() : "",
var name = !element.__EMPTY ? "" : element.__EMPTY.trim(); beschreibung: element.Bemerkung ? element.Bemerkung.trim(): "",
vm.addShift(new Shift(art, name, date, bemerkung)); 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) { removeShift: function (shift) {
this.shifts.splice(this.shifts.indexOf(shift), 1); 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 () { cleanStorage: function () {
this.shifts = []; this.shifts = [];
M.toast({html:"Alle Einträge gelöscht",displayLength: this.config.toast_length}); this.makeToast("Alle Einträge gelöscht");
}, },
createDownloadFile: function () { createDownloadFile: function () {
var vCal = new VCalendar("Dienstplan Kalender"); var vCal = new VCalendar("Dienstplan Kalender");
@ -191,7 +241,7 @@ var app = new Vue({
} }
this.icsFile = window.URL.createObjectURL(this.blob); 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 () { downloadFile: function () {
if (window.navigator.msSaveOrOpenBlob) { if (window.navigator.msSaveOrOpenBlob) {

View File

@ -29,7 +29,7 @@
<ul class="side-nav" id="mobile-demo"> <ul class="side-nav" id="mobile-demo">
</ul> </ul>
<ul class="tabs tabs-transparent"> <ul class="tabs tabs-transparent">
<li class="tab"><a class="active" href="#Dienste">Dienste</a></li> <li class="tab"><a class="active" href="#termine">Termine</a></li>
<li class="tab"><a href="#Einstellungen">Regeln</a></li> <li class="tab"><a href="#Einstellungen">Regeln</a></li>
</ul> </ul>
</div> </div>
@ -37,10 +37,10 @@
</div> </div>
<div id="body"> <div id="body">
<main class="container"> <main class="container">
<div id="Dienste"> <div id="termine">
<div class="card" v-if="shifts.length > 0"> <div class="card" v-if="shifts.length > 0">
<div class="card-content"> <div class="card-content">
<h3 class="card-title">Dienste</h3> <h3 class="card-title">Termine</h3>
<table class="highlight" > <table class="highlight" >
<thead class=""> <thead class="">
<tr> <tr>
@ -61,6 +61,7 @@
</td> </td>
<td class=""> <td class="">
{{s.VEventTitle}} {{s.VEventTitle}}
<small>{{ s.Ort }}</small>
</td> </td>
<td class="" v-if="s.Beginn !== '00:00'"> <td class="" v-if="s.Beginn !== '00:00'">
{{s.Beginn}} - {{s.Ende}} {{s.Beginn}} - {{s.Ende}}
@ -75,7 +76,7 @@
</tbody> </tbody>
<tfoot> <tfoot>
<tr> <tr>
<th colspan="5" class="text-right"> {{shifts.length }} Dienste</th> <th colspan="5" class="right-align"> {{shifts.length }} Dienste</th>
</tr> </tr>
</tfoot> </tfoot>
</table> </table>
@ -96,14 +97,14 @@
<a class="btn-flat red-text waves-effect" <a class="btn-flat red-text waves-effect"
@click="cleanStorage" @click="cleanStorage"
:disabled=" (remaining > 0) ? null : 'disabled'"> :disabled=" (remaining > 0) ? null : 'disabled'">
Dienste löschen Termine löschen
</a> </a>
</div> </div>
</div> </div>
<div class="card" v-else> <div class="card" v-else>
<div class="card-content center-align" style="height:100px;"> <div class="card-content center-align" style="height:100px;">
<h3 class="card-title"> <h3 class="card-title">
Noch keine Dienste da Noch keine Termine da
</h3> </h3>
</div> </div>

View File

@ -88,15 +88,42 @@ Rule.defaults = function () {
} }
var DURATION_RULES = Rule.defaults(); var DURATION_RULES = Rule.defaults();
function Shift(kind, name, date, info) { function Shift() {
'use strict'; var evt = window.event || arguments[1] || arguments.callee.caller.arguments[0];
this.Datum = date.format(DATE_INPUT_FORMAT); var target = evt.target || evt.srcElement;
this.Beginn = date.format(TIME_FORMAT);
this.Art = kind; var options = {};
this.Beschreibung = info;
this.Name = name; if (arguments[0]) options = arguments[0];
Shift.setDurationFromRules(this);
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 = { Shift.prototype = {
get Wochentag() { get Wochentag() {
return this._date.clone().locale(MOMENT_LOCALE).format(WEEKDAY_FORMAT); return this._date.clone().locale(MOMENT_LOCALE).format(WEEKDAY_FORMAT);
@ -153,6 +180,13 @@ Shift.prototype = {
this._name = value ? value.trim() : ""; this._name = value ? value.trim() : "";
}, },
get Ort() {
return this._ort;
},
set Ort(value) {
this._ort = value ? value.trim() : "";
},
get VEventTitle() { get VEventTitle() {
return this.Name + " " + this.Art; return this.Name + " " + this.Art;
}, },
@ -197,15 +231,25 @@ Shift.setDurationFromRules = function (shift) {
shift.Dauer = moment.duration(duration, 'm').locale(MOMENT_LOCALE); shift.Dauer = moment.duration(duration, 'm').locale(MOMENT_LOCALE);
} }
Shift.prototype.toVEvent = function () { Shift.prototype.toVEvent = function () {
'use strict';
var end = this._begin.clone().add(this._duration); 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) { Shift.thaw = function (jsonShift) {
'use strict';
moment.locale(MOMENT_LOCALE); moment.locale(MOMENT_LOCALE);
var begin = moment(jsonShift._begin); 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.id = jsonShift.id;
shift.Dauer = moment.duration(jsonShift._duration); shift.Dauer = moment.duration(jsonShift._duration);
return shift; return shift;

View File

@ -72,21 +72,46 @@ function VCalendar(calendarName) {
VCalendar.prototype = Object.create(VMeta.prototype); VCalendar.prototype = Object.create(VMeta.prototype);
VCalendar.prototype.constructor = VCalendar; 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); VMeta.call(this);
this.tag = "VEVENT"; this.tag = "VEVENT";
this.set('DTSTART;TZID=' + timezoneName, VMeta.formatDate(startMoment)); this.set('DTSTART;TZID=' + options.tzName, VMeta.formatDate(options.startMoment));
this.set('DTEND;TZID=' + timezoneName, VMeta.formatDate(endMoment)); this.set('DTEND;TZID=' + options.tzName, VMeta.formatDate(options.endMoment));
this.set('DTSTAMP', VMeta.formatDate(moment()) + "Z"); this.set('DTSTAMP', options.dtStamp);
this.set('UID', VMeta.generateUID()); this.set('UID', options.uid);
this.set('SUMMARY', title); this.set('SUMMARY', options.title);
this.set('DESCRIPTION', description); this.set('DESCRIPTION', options.description);
this.set('LOCATION', options.location)
this.set('CLASS', "PUBLIC"); this.set('CLASS', "PUBLIC");
this.set('TRANSP', "OPAQUE"); this.set('TRANSP', "OPAQUE");
this.set('STATUS', "CONFIRMED"); this.set('STATUS', "CONFIRMED");
this.set('ORGANIZER', ""); this.set('ORGANIZER', options.organizer);
} }
VEvent.prototype = Object.create(VMeta.prototype); VEvent.prototype = Object.create(VMeta.prototype);
VEvent.prototype.constructor = VEvent; VEvent.prototype.constructor = VEvent;