diff --git a/app.js b/app.js index 2c1bbc4..bbd1210 100644 --- a/app.js +++ b/app.js @@ -1,389 +1,521 @@ -if (!String.prototype.includes) { - String.prototype.includes = function () { - 'use strict'; - return String.prototype.indexOf.apply(this, arguments) !== -1; - }; -} -//extend FileReader -if (!FileReader.prototype.readAsBinaryString) { - FileReader.prototype.readAsBinaryString = function (fileData) { - var binary = ""; - var pt = this; - var reader = new FileReader(); - reader.onload = function (e) { - var bytes = new Uint8Array(reader.result); - var length = bytes.byteLength; - for (var i = 0; i < length; i++) { - binary += String.fromCharCode(bytes[i]); - } - //pt.result - readonly so assign binary - pt.content = binary; - $(pt).trigger('onload'); - } - reader.readAsArrayBuffer(file); - } -} - -var options = { - timepicker: { - twelveHour: false, - } -}; - -document.addEventListener('DOMContentLoaded', function() { - M.AutoInit(); - var elems = document.querySelectorAll('.timepicker'); - var timepickers = M.Timepicker.init(elems, options.timepicker); -}); -//localStorage persistence - -var SHIFT_STORAGE_KEY = "dienstplan_chrosey"; -var RULE_STORAGE_KEY = "regeln_chrosey"; -var shiftStorage = { - fetch: function () { - 'use strict'; - var parsed = JSON.parse(localStorage.getItem(SHIFT_STORAGE_KEY) || '[]'), - shifts = []; - parsed.forEach(function (el, index) { - var shift = Shift.thaw(el); - shift.id = index; - shifts.push(shift); - }); - shiftStorage.uid = shifts.length; - return shifts; - }, - save: function (shifts) { - 'use strict'; - var json = JSON.stringify(shifts) - localStorage.setItem(SHIFT_STORAGE_KEY, json); - }, - count: function () { - return JSON.parse(localStorage.getItem(SHIFT_STORAGE_KEY) || '[]').length; - } -}; -var ruleStorage = { - fetch: function () { - 'use strict'; - var parsed = JSON.parse(localStorage.getItem(RULE_STORAGE_KEY)) | []; - var rules = parsed.length > 0 - ? parsed.map((e,i) => { - var r = Rule.thaw(e); - r.id = i; - return r; - }) - : Rule.defaults(); - ruleStorage.uid = rules.length; - return rules; - }, - save: function (rules) { - 'use strict'; - var json = JSON.stringify(rules); - localStorage.setItem(RULE_STORAGE_KEY, json); - } -}; - -Vue.component('chip-input', { - template: ` -
- `, - data() { - return { - instance: null, - chips: [] - } - }, - - computed: { - chipsData() { - return this.instance.chipsData; - } - }, - - watch:{ - initData:{ - deep: true, - handler(n,o) { - if (n !== o) { - this.initialize(); - this.$emit('init'); - } - } - } - }, - props: { - name: String, - initData: Array - }, - - methods: { - initialize() { - this.chips = this.initData.map(e => e); - var el = $('#'+this.name)[0]; - this.instance = M.Chips.init(el, { - data: this.chips, - onChipAdd: () => { - this.$emit("change",this.chipsData); - }, - onChipDelete: () => { - this.$emit("change",this.chipsData); - } - }); - } - }, - - mounted() { - this.initialize(); - } -}); - -var app = new Vue({ - el: '#app', - data: { - shifts: shiftStorage.fetch(), - rules: ruleStorage.fetch(), - icsFile: null, - blob: null, - dp_sheet: '', - deletedShift: '', - remaining: shiftStorage.count(), - selectedShift: new Shift({}), - selectedShiftIndex: -1, - selectedRule: new Rule({}), - selectedRuleIndex: -1, - saveto: 'dienstplan.ics', - uploadFileName: "", - config: { - moment: { - parse_formats: [ - "ddd, DD/ MMM. 'YY HH:mm", - "ddd, DD/ MMM. YYYY HH:mm" - ], - parse_language: 'en', - display_language: 'de' - }, - toast: { - displayLength: 3000 - } - }, - }, - watch: { - shifts: { - handler: function (shifts) { - 'use strict'; - shiftStorage.save(shifts); - this.remaining = shifts.length; - this.makeToast("Änderungen gespeichert."); - }, - deep: true - }, - rules: { - handler: function (rules) { - 'use strict'; - ruleStorage.save(rules); - this.makeToast("Änderungen gespeichert."); - }, - deep: true - } - }, - - computed: { - groupedTermine() { - return _.groupBy(this.shifts, e => e.Datum); - } - }, - - methods: { - updateArten(value){ - this.selectedRule.Arten = value; - }, - - updateTitel(value){ - this.selectedRule.Titel = value; - }, - - makeToast(message) { - var toastOptions = this.config.toast; - toastOptions.html = message; - M.toast(toastOptions); - }, - - 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]"; - 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, - }); - var isErfurterDienstplan = workbook.SheetNames.indexOf("Dienstplan") > -1; - - if(isErfurterDienstplan){ - vm.parseForErfurt(workbook.Sheets["Dienstplan"]); - } else { - var sheetName = workbook.SheetNames[0]; - vm.parseForStuttgart(workbook.Sheets[sheetName]); - } - }; - reader.readAsBinaryString(file); - }, - - 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')) { - day = moment(element.Datum); - } - if (element.hasOwnProperty('Dienst')) { - var time = element.Zeit ? moment(element.Zeit) : day; - 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 termin = { - ort: element.H ? element.H.trim() : "", - art: element.E ? element.E.trim() : "", - beschreibung: element.H ? element.H.trim(): "", - name: element.F ? element.F.trim() : "" - } - var time = day.clone(); - if (typeof(element.D) === "object") { - time = moment(element.D); - termin.datum = day.clone().hour(time.hour()).minute(time.minute()); - } else if(element.D.indexOf("-") > -1 ) { - var tArray = element.D.split(" - "); - time = moment(tArray[0],"HH:mm"); - termin.datum = day.clone().hour(time.hour()).minute(time.minute()); - termin.ende = moment(tArray[1], "HH:mm").format("HH:mm"); - } - vm.addShift(new Shift(termin)); - - } - }); - }, - - addShift: function (shift) { - this.shifts.push(shift); - }, - - removeShift: function (shift) { - this.shifts.splice(this.shifts.indexOf(shift), 1); - this.makeToast(shift.VEventTitle + " gelöscht"); - }, - - cleanStorage: function () { - this.shifts = []; - this.makeToast("Alle Einträge gelöscht"); - }, - - createDownloadFile: function () { - var vCal = new VCalendar("Dienstplan Kalender"); - this.shifts.forEach(function (shift) { - vCal.add(shift.toVEvent()); - }); - var calString = vCal.toString(); - this.blob = new Blob([calString], { - type: 'text/plain' - }); - - if (this.icsFile !== null) { - window.URL.revokeObjectURL(this.icsFile); - } - - this.icsFile = window.URL.createObjectURL(this.blob); - this.makeToast(this.saveto + " erstellt."); - }, - - downloadFile: function () { - if (window.navigator.msSaveOrOpenBlob) { - window.navigator.msSaveOrOpenBlob(this.blob, this.saveto); - } - }, - - selectShift: function (shift) { - this.selectedShift = Shift.thaw(shift); - this.keepShift = shift; - M.updateTextFields(); - $('#shiftModal').modal('open'); - }, - - saveChanges: function (changedShift) { - this.shifts.splice(this.shifts.indexOf(this.keepShift), 1, changedShift); - - $('#shiftModal').modal('close'); - this.keepShift = ''; - this.selectedShift = ''; - }, - - discardChanges: function (changedShift) { - $('#shiftModal').modal('close'); - this.keepShift = ''; - this.selectedShift = ''; - }, - - editRule: function (rule) { - this.selectedRule = Rule.thaw(rule); - this.selectedRuleIndex = this.rules.indexOf(rule); - $('#ruleModal').modal('open'); - }, - - saveRule: function () { - this.rules[this.selectedRuleIndex] = this.selectedRule; - - $('#ruleModal').modal('close'); - this.selectedRule = new Rule(); - }, - - discardRule: function () { - $('#ruleModal').modal('close'); - - this.selectedRule = new Rule(); - } - - }, - directives: { - 'edit-focus': function (el, value) { - if (value) { - el.focus(); - } - } - } -}) +if (!String.prototype.includes) { + String.prototype.includes = function () { + 'use strict'; + return String.prototype.indexOf.apply(this, arguments) !== -1; + }; +} +//extend FileReader +if (!FileReader.prototype.readAsBinaryString) { + FileReader.prototype.readAsBinaryString = function (fileData) { + var binary = ""; + var pt = this; + var reader = new FileReader(); + reader.onload = function (e) { + var bytes = new Uint8Array(reader.result); + var length = bytes.byteLength; + for (var i = 0; i < length; i++) { + binary += String.fromCharCode(bytes[i]); + } + //pt.result - readonly so assign binary + pt.content = binary; + $(pt).trigger('onload'); + } + reader.readAsArrayBuffer(file); + } +} + +var options = { + timepicker: { + twelveHour: false, + } +}; + +document.addEventListener('DOMContentLoaded', function() { + M.AutoInit(); + var elems = document.querySelectorAll('.timepicker'); + var timepickers = M.Timepicker.init(elems, options.timepicker); +}); +//localStorage persistence + +var SHIFT_STORAGE_KEY = "dienstplan_chrosey"; +var RULE_STORAGE_KEY = "regeln_chrosey"; +var shiftStorage = { + fetch: function () { + 'use strict'; + var parsed = JSON.parse(localStorage.getItem(SHIFT_STORAGE_KEY) || '[]'), + shifts = []; + parsed.forEach(function (el, index) { + var shift = Shift.thaw(el); + shift.id = index; + shifts.push(shift); + }); + shiftStorage.uid = shifts.length; + return shifts; + }, + save: function (shifts) { + 'use strict'; + var json = JSON.stringify(shifts) + localStorage.setItem(SHIFT_STORAGE_KEY, json); + }, + count: function () { + return JSON.parse(localStorage.getItem(SHIFT_STORAGE_KEY) || '[]').length; + } +}; +var ruleStorage = { + fetch: function () { + 'use strict'; + var parsed = JSON.parse(localStorage.getItem(RULE_STORAGE_KEY)) | []; + var rules = parsed.length > 0 + ? parsed.map((e,i) => { + var r = Rule.thaw(e); + r.id = i; + return r; + }) + : Rule.defaults(); + ruleStorage.uid = rules.length; + return rules; + }, + save: function (rules) { + 'use strict'; + var json = JSON.stringify(rules); + localStorage.setItem(RULE_STORAGE_KEY, json); + } +}; + +Vue.component('ask-format-modal',{ + template: ` +