277 lines
16 KiB
HTML
277 lines
16 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="de">
|
|
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<title>Dienstplan Converter</title>
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<meta http-equiv="x-ua-compatible" content="ie=edge">
|
|
<link rel="apple-touch-icon" sizes="180x180" href="/favicons/apple-touch-icon.png">
|
|
<link rel="icon" type="image/png" href="/favicons/favicon-32x32.png" sizes="32x32">
|
|
<link rel="icon" type="image/png" href="/favicons/favicon-16x16.png" sizes="16x16">
|
|
<link rel="mask-icon" href="/favicons/safari-pinned-tab.svg" color="#e6b300">
|
|
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
|
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">
|
|
|
|
<link rel="stylesheet" href="https://unpkg.com/materialize-stepper@3.1.0/dist/css/mstepper.min.css">
|
|
<link rel="stylesheet" href="css/page.css">
|
|
|
|
</head>
|
|
|
|
<body>
|
|
<div id="app">
|
|
<nav class="nav blue">
|
|
<div class="container">
|
|
<span class="brand-logo">
|
|
<img src="/img/logo.svg" height="30">
|
|
Dienstplan Converter
|
|
<link rel="apple-touch-icon" sizes="180x180" href="/favicons/apple-touch-icon.png">
|
|
<link rel="icon" type="image/png" href="/favicons/favicon-32x32.png" sizes="32x32">
|
|
<link rel="icon" type="image/png" href="/favicons/favicon-16x16.png" sizes="16x16">
|
|
<link rel="mask-icon" href="/favicons/safari-pinned-tab.svg" color="#e6b300">
|
|
</span>
|
|
</div>
|
|
</nav>
|
|
<div id="body">
|
|
<main class="container">
|
|
<ul class="stepper">
|
|
<li class="step active">
|
|
<div class="step-title waves-effect">Dienstplan-Datei auswählen</div>
|
|
<div class="step-content">
|
|
<label class="btn waves-effect waves-green" data-position="left"
|
|
data-tooltip="Dienstplan einlesen" for="fileInput">
|
|
Datei auswählen
|
|
</label>
|
|
<div class="card-panel" v-if="format">Erkanntes Format: {{format}}</div>
|
|
<div class="step-actions">
|
|
<button class="waves-effect waves-dark btn next-step">Weiter</button>
|
|
|
|
<a class="btn-flat red-text waves-effect" @click="cleanStorage"
|
|
:disabled=" (remaining > 0) ? null : 'disabled'">
|
|
{{ remaining }} Termine löschen
|
|
</a>
|
|
</div>
|
|
</div>
|
|
|
|
</li>
|
|
<li class="step">
|
|
<div class="step-title waves-effect">Dateiformat erkennen</div>
|
|
<div class="step-content">
|
|
|
|
<div v-if="format">Erkanntes Format: {{format}}</div>
|
|
<div v-else>keine neue Datei eingelesen</div>
|
|
<div class="step-actions">
|
|
<button class="waves-effect waves-dark btn next-step">Weiter</button>
|
|
</div>
|
|
</div>
|
|
</li>
|
|
<li class="step">
|
|
<div class="step-title waves-effect" data-step-label="Termin-Dauer-Bestimmung">
|
|
Regeln prüfen
|
|
</div>
|
|
<div class="step-content">
|
|
<div>
|
|
<span class="chip orange">Titel der Veranstaltung</span>
|
|
<span class="chip indigo">Art des Dienstes</span>
|
|
</div>
|
|
<div class="collection">
|
|
<a class="collection-item avatar" v-for="(r,i) in rules" :key="'rule-'+i"
|
|
@click="editRule(r)">
|
|
<i class="circle">#{{ i+1 }}</i>
|
|
<span class="title">{{ r.Name}} </span>
|
|
<div class="secondary-content">
|
|
<span class="badge new" data-badge-caption="Minuten">{{ r.Dauer }}</span>
|
|
</div>
|
|
<div>
|
|
<span class="chip indigo" :class="'lighten-'+(r.Arten.length > 1 ? '3' : '1')"
|
|
v-for="a in r.Arten">
|
|
{{a.tag}}
|
|
</span>
|
|
|
|
<span class="chip orange" :class="'lighten-'+(r.Titel.length > 1 ? '3' : '1')"
|
|
v-for="t in r.Titel">
|
|
{{t.tag}}
|
|
</span>
|
|
|
|
</div>
|
|
</a>
|
|
</div>
|
|
<div class="step-actions">
|
|
<button class="waves-effect waves-dark btn-flat" @click.prevent="applyRules">Regeln
|
|
anwenden</button>
|
|
<button class="waves-effect waves-dark btn next-step">Weiter</button>
|
|
</div>
|
|
</div>
|
|
</li>
|
|
<li class="step">
|
|
<div class="step-title waves-effect">Termine prüfen</div>
|
|
<div class="step-content">
|
|
<table class="highlight">
|
|
<thead>
|
|
<tr>
|
|
<th>Datum</th>
|
|
<th>Dauer</th>
|
|
<th>Info</th>
|
|
<th></th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<template v-for="g in groupedTermine">
|
|
<tr v-for="(s,i) in g">
|
|
<th v-if="i == 0" :rowspan="g.length">
|
|
{{s.FormattedDatum}}
|
|
</th>
|
|
<td>{{ s.Beginn }} - {{ s.Ende }} Uhr</td>
|
|
<td>
|
|
<h6>{{ s.VEventTitle }}</h6>
|
|
{{ s.Dauer }}
|
|
<p v-if="s.Ort!=''">
|
|
<i class="material-icons red-text">location_on</i>
|
|
{{ s.Ort }}
|
|
</p>
|
|
<blockquote v-if="s.Ort != s.Beschreibung">
|
|
{{ s.Beschreibung }}
|
|
</blockquote>
|
|
</td>
|
|
<td>
|
|
<button class="btn-flat"
|
|
@click.prevent="removeShift(s)">löschen</button>
|
|
<button class="btn-flat"
|
|
@click.prevent="selectShift(s)">bearbeiten</button>
|
|
<button class="waves-effect waves-dark btn blue" @click.prevent="updateBeginn(s, -1)">1 h früher</button>
|
|
<button class="waves-effect waves-dark btn blue" @click.prevent="updateBeginn(s, 1)">1 h später</button>
|
|
</td>
|
|
</tr>
|
|
</template>
|
|
</tbody>
|
|
</table>
|
|
|
|
<div class="step-actions">
|
|
<button class="btn-flat waves-effect" @click.prevent="createDownloadFile"
|
|
:disabled=" (remaining > 0) ? null : 'disabled'">
|
|
Kalenderdatei erstellen
|
|
</button>
|
|
<button class="waves-effect waves-dark btn blue" @click.prevent="changeTime(-1)">alle 1 h früher</button>
|
|
<button class="waves-effect waves-dark btn blue" @click.prevent="changeTime(1)">alle 1 h später</button>
|
|
<button class="waves-effect waves-dark btn next-step">Weiter</button>
|
|
</div>
|
|
</div>
|
|
</li>
|
|
<li class="step">
|
|
<div class="step-title waves-effect">Kalenderdatei speichern</div>
|
|
<div class="step-content">
|
|
<div class="step-actions">
|
|
<a class="btn-flat waves-effect" :href="icsFile" :class="[ icsFile ? '' : 'disabled']"
|
|
download="dienstplan.ics" @click.stop="downloadFile">
|
|
Kalenderdatei speichern
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</li>
|
|
</ul>
|
|
</main>
|
|
<div id="confirmModal" class="modal active">
|
|
<div class="modal-content">
|
|
<h4>Aktion bestätigen</h4>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button class="btn-flat" @click="true">Bestätigen</button>
|
|
<button class="btn-flat" @click="false">Abbrechen</button>
|
|
</div>
|
|
</div>
|
|
<div id="ruleModal" class="modal bottom-sheet active">
|
|
<div class="modal-content">
|
|
<h4>Regel anpassen</h4>
|
|
<div class="row">
|
|
<div class="range-field col s12 m6 l4">
|
|
<label class="active" for="rule_duration">Dauer in Minuten: {{selectedRule.Dauer}}</label>
|
|
<input id="rule_duration" type="range" v-model="selectedRule.Dauer" min="30" max="300"
|
|
step="10">
|
|
</div>
|
|
<div class="range-field col s12 m6 l8">
|
|
<label class="active" for="rule_name">Name</label>
|
|
<input id="rule_name" type="text" v-model="selectedRule.Name">
|
|
</div>
|
|
<div class="input-field col s12">
|
|
<label class="active" for="shift_kind">Arten</label>
|
|
<chip-input name="regel_arten" :init-data="selectedRule.Arten" @change="updateArten">
|
|
</div>
|
|
<div class="input-field col s12">
|
|
<label class="active" for="rule_titel">Titel</label>
|
|
<chip-input name="regel_titel" :init-data="selectedRule.Titel" @change="updateTitel">>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button class="waves-effect btn-flat waves-green" @click="saveRule(selectedRule)">Speichern</button>
|
|
<button class="waves-effect btn-flat waves-red"
|
|
@click="discardRule(selectedRule)">Verwerfen</button>
|
|
</div>
|
|
</div>
|
|
<div id="shiftModal" class="modal bottom-sheet">
|
|
<div class="modal-content">
|
|
<h4>{{ selectedShift.VEventTitle || 'kein Titel'}}</h4>
|
|
<div class="row">
|
|
<div class="input-field col s6 ">
|
|
<input id="shift_name" type="text" v-model="selectedShift.Name" placeholder="kein Titel">
|
|
<label class="active" for="shift_name">Titel</label>
|
|
</div>
|
|
<div class="input-field col s6 ">
|
|
<input id="shift_kind" type="text" v-model="selectedShift.Art" placeholder="keine Art">
|
|
<label class="active" for="shift_kind">Art</label>
|
|
</div>
|
|
<div class="input-field col s6 ">
|
|
<input id="shift_date" type="date" class="datepicker" v-model.lazy="selectedShift.Datum"
|
|
placeholder="Datum">
|
|
<label class="active" for="shift_date">Datum</label>
|
|
</div>
|
|
<div class="input-field col s6">
|
|
<input id="shift_begin" type="time" v-model.lazy="selectedShift.Beginn"
|
|
placeholder="Uhrzeit" class="timepicker no-autoinit"
|
|
:data-default="selectedShift.Beginn">
|
|
<label class="active" for="shift_begin">Anfang</label>
|
|
</div>
|
|
<div class="input-field col s6 ">
|
|
<input id="shift_end" type="time" v-model.lazy="selectedShift.Ende" placeholder="Ende"
|
|
class="timepicker no-autoinit">
|
|
<label class="active" for="shift_end">Ende</label>
|
|
</div>
|
|
<div class="input-field col s6 ">
|
|
<input id="shift_desc" type="text" v-model="selectedShift.Beschreibung"
|
|
placeholder="keine Beschreibung">
|
|
<label class="active" for="shift_desc">Beschreibung</label>
|
|
</div>
|
|
<div class="input-field col s6 ">
|
|
<input id="shift_location" type="text" v-model="selectedShift.Ort" placeholder="kein Ort">
|
|
<label class="active" for="shift_location">Ort</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button class="waves-effect btn-flat waves-green"
|
|
@click="saveChanges(selectedShift)">Speichern</button>
|
|
<button class="waves-effect btn-flat waves-red"
|
|
@click="discardChanges(selectedShift)">Verwerfen</button>
|
|
</div>
|
|
</div>
|
|
<ask-format-modal :options="availableFormats" @picked-format="parsePickedFormat"></ask-format-modal>
|
|
</div>
|
|
<input type="file" name="fileInput" id="fileInput" @change="onFileChange"
|
|
accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.ms-excel"
|
|
style="display:none;">
|
|
</div>
|
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
|
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
|
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
|
|
|
|
<script src="https://unpkg.com/materialize-stepper@3.1.0/dist/js/mstepper.min.js"></script>
|
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.14.1/xlsx.full.min.js"></script>
|
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.23.0/moment-with-locales.min.js"></script>
|
|
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.22/dist/vue.js"></script>
|
|
<script src="js/shift.js"></script>
|
|
<script src="js/vcal.js"></script>
|
|
<script src="app.js"></script>
|
|
</body>
|
|
|
|
</html>
|