basic import and export working
This commit is contained in:
parent
921bc18061
commit
a89539c9bb
22
.vscode/launch.json
vendored
Normal file
22
.vscode/launch.json
vendored
Normal 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
82
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) {
|
||||
|
||||
13
index.html
13
index.html
@ -29,7 +29,7 @@
|
||||
<ul class="side-nav" id="mobile-demo">
|
||||
</ul>
|
||||
<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>
|
||||
</ul>
|
||||
</div>
|
||||
@ -37,10 +37,10 @@
|
||||
</div>
|
||||
<div id="body">
|
||||
<main class="container">
|
||||
<div id="Dienste">
|
||||
<div id="termine">
|
||||
<div class="card" v-if="shifts.length > 0">
|
||||
<div class="card-content">
|
||||
<h3 class="card-title">Dienste</h3>
|
||||
<h3 class="card-title">Termine</h3>
|
||||
<table class="highlight" >
|
||||
<thead class="">
|
||||
<tr>
|
||||
@ -61,6 +61,7 @@
|
||||
</td>
|
||||
<td class="">
|
||||
{{s.VEventTitle}}
|
||||
<small>{{ s.Ort }}</small>
|
||||
</td>
|
||||
<td class="" v-if="s.Beginn !== '00:00'">
|
||||
{{s.Beginn}} - {{s.Ende}}
|
||||
@ -75,7 +76,7 @@
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<th colspan="5" class="text-right"> {{shifts.length }} Dienste</th>
|
||||
<th colspan="5" class="right-align"> {{shifts.length }} Dienste</th>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
@ -96,14 +97,14 @@
|
||||
<a class="btn-flat red-text waves-effect"
|
||||
@click="cleanStorage"
|
||||
:disabled=" (remaining > 0) ? null : 'disabled'">
|
||||
Dienste löschen
|
||||
Termine löschen
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card" v-else>
|
||||
<div class="card-content center-align" style="height:100px;">
|
||||
<h3 class="card-title">
|
||||
Noch keine Dienste da
|
||||
Noch keine Termine da
|
||||
</h3>
|
||||
|
||||
</div>
|
||||
|
||||
68
js/shift.js
68
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;
|
||||
|
||||
41
js/vcal.js
41
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;
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user