Compare commits

..

26 Commits

Author SHA1 Message Date
stingl d8ed85792a repair stupidity; 3 years ago
stingl b9d82dbf93 update version; 3 years ago
stingl 0f08919318 automatically create multiple tasks if seperated by semicolons; 3 years ago
stingl 21bf3a7035 save on delete; 3 years ago
stingl 3824776c7e responsiveness adjustments; 3 years ago
stingl 075e3a37e1 responsiveness adjustments; 3 years ago
stingl 4a5f06cc4a make notes own page; grid for notes; show version on app; 3 years ago
1nicerOli d6053fb205 Remove classes for responsiveness due to canvas-card; 3 years ago
Nero Ignis b8860afe93 Fix Icons for Task-Components; 3 years ago
Nero Ignis cc91919da1 Show message if no notes match the filter; 3 years ago
Nero Ignis 1be7efaff7 Change notes to canvas instead of own page; 3 years ago
Nero Ignis 9ab4122bd6 Fix box-model; 3 years ago
Nero Ignis 6fb5ba4220 Move filter and only show it if notes are present; 3 years ago
Nero Ignis c636bb6f82 Add filter for colors; 3 years ago
Nero Ignis 287a335f21 Fix saving colors for notes; 3 years ago
Nero Ignis 0c2cb6c44a Add notes-module; 3 years ago
stingl 5e25410897 make page scrollable; 3 years ago
stingl e1ecf56258 change heading; 3 years ago
stingl c5671f0fc7 Fix text-color; 3 years ago
stingl f7605e8084 fix typo; 3 years ago
stingl ed32f4ba13 add general tasks; 3 years ago
stingl d97dce6905 save settings in store; 4 years ago
stingl d3c13a37b2 fix with method; 4 years ago
stingl b449678ace Fix; 4 years ago
stingl fd3a7b6911 show day for history; 4 years ago
stingl 35b605a8f8 don't show today if empty; shot start time in tracking-info; 4 years ago
  1. 16869
      package-lock.json
  2. 1
      package.json
  3. BIN
      public/fonts/NotePaper-regular.otf
  4. 19
      src/App.vue
  5. 10
      src/css/app.scss
  6. 6
      src/router/index.js
  7. 37
      src/store/index.js
  8. 6
      src/views/History.vue
  9. 25
      src/views/Menu.vue
  10. 190
      src/views/Notes.vue
  11. 7
      src/views/Settings.vue
  12. 120
      src/views/Tasks.vue
  13. 26
      src/views/TasksForTracker.vue
  14. 261
      src/views/Trackers.vue

16869
package-lock.json generated

File diff suppressed because it is too large Load Diff

1
package.json

@ -18,7 +18,6 @@
"moment": "^2.29.1", "moment": "^2.29.1",
"vue": "^3.0.0", "vue": "^3.0.0",
"vue-router": "^4.0.0-0", "vue-router": "^4.0.0-0",
"vuetify": "^3.0.0-alpha.0",
"vuex": "^4.0.0-0" "vuex": "^4.0.0-0"
}, },
"devDependencies": { "devDependencies": {

BIN
public/fonts/NotePaper-regular.otf

Binary file not shown.

19
src/App.vue

@ -4,6 +4,9 @@
<Menu/> <Menu/>
<div class="col" id="page-wrapper"> <div class="col" id="page-wrapper">
<router-view/> <router-view/>
<span id="version">
v{{ version }}
</span>
</div> </div>
</div> </div>
</div> </div>
@ -11,6 +14,7 @@
<HistoryForTracker/> <HistoryForTracker/>
<CustomBookForTracker/> <CustomBookForTracker/>
<TasksForTracker/> <TasksForTracker/>
<Tasks/>
<History/> <History/>
<Settings/> <Settings/>
</template> </template>
@ -25,19 +29,22 @@ import TasksForTracker from "./views/TasksForTracker";
import HistoryForTracker from "./views/HistoryForTracker"; import HistoryForTracker from "./views/HistoryForTracker";
import CustomBookForTracker from "./views/CustomBookForTracker"; import CustomBookForTracker from "./views/CustomBookForTracker";
import Settings from "./views/Settings"; import Settings from "./views/Settings";
import Tasks from "./views/Tasks";
export default { export default {
el: '#root', el: '#root',
components: { components: {
Tasks,
Settings, Settings,
CustomBookForTracker, CustomBookForTracker,
HistoryForTracker, HistoryForTracker,
TasksForTracker, TasksForTracker,
History, History,
Menu Menu,
}, },
data() { data() {
return { return {
version: '0.8.24.1',
sounds: { sounds: {
bad: [ bad: [
'alert', 'alert',
@ -50,7 +57,7 @@ export default {
theme: 'materia', theme: 'materia',
customBookingValue: '', customBookingValue: '',
customDateForPastDays: '', customDateForPastDays: '',
newTaskInput: '' newTaskInput: '',
} }
}, },
mounted() { mounted() {
@ -225,4 +232,12 @@ export default {
#page-wrapper { #page-wrapper {
padding-top: 15px; padding-top: 15px;
} }
#version {
position: fixed;
bottom: 1em;
right: 2em;
z-index: -1;
color: lightgrey;
}
</style> </style>

10
src/css/app.scss

@ -1,10 +1,20 @@
@import '~izitoast/dist/css/iziToast.min.css'; @import '~izitoast/dist/css/iziToast.min.css';
@import "~bootswatch/dist/materia/bootstrap.min.css"; @import "~bootswatch/dist/materia/bootstrap.min.css";
@font-face {
font-family: 'NotePaper';
src: url('/fonts/NotePaper-regular.otf');
}
body { body {
background-color: #e7e7e7; background-color: #e7e7e7;
} }
#page-wrapper {
max-height: 100vh;
overflow-y: scroll;
}
.tracker-action-button { .tracker-action-button {
margin-top: 10px; margin-top: 10px;
padding: 1px 5px 1px 5px; padding: 1px 5px 1px 5px;

6
src/router/index.js

@ -3,6 +3,7 @@ import Trackers from "../views/Trackers";
import Settings from "../views/Settings"; import Settings from "../views/Settings";
import TrackersDetail from "../views/TrackersDetail"; import TrackersDetail from "../views/TrackersDetail";
import Archive from "../views/Archive"; import Archive from "../views/Archive";
import Notes from "../views/Notes";
Array.prototype.pushToBeginning = function (toPush) { Array.prototype.pushToBeginning = function (toPush) {
return this.unshift.apply(this, [toPush]); return this.unshift.apply(this, [toPush]);
@ -24,6 +25,11 @@ const routes = [
name: 'Archive', name: 'Archive',
component: Archive component: Archive
}, },
{
path: '/notes',
name: 'Notes',
component: Notes
},
{ {
path: '/settings', path: '/settings',
name: 'Settings', name: 'Settings',

37
src/store/index.js

@ -1,4 +1,5 @@
import {createStore} from 'vuex' import {createStore} from 'vuex'
import moment from "moment";
export default createStore({ export default createStore({
state: { state: {
@ -8,7 +9,9 @@ export default createStore({
theme: 'materia' theme: 'materia'
}, },
trashed: {}, trashed: {},
selectedTracker: {} selectedTracker: {},
tasks: [],
notes: []
}, },
mutations: { mutations: {
loadSavedData(state) { loadSavedData(state) {
@ -22,6 +25,16 @@ export default createStore({
state.archive = JSON.parse(storedArchive); state.archive = JSON.parse(storedArchive);
} }
let storedTasks = localStorage.getItem('tasks');
if (storedTasks !== null && storedTasks !== undefined) {
state.tasks = JSON.parse(storedTasks);
}
let storedNotes = localStorage.getItem('notes');
if (storedNotes !== null && storedNotes !== undefined) {
state.notes = JSON.parse(storedNotes);
}
let storedSettings = localStorage.getItem('settings'); let storedSettings = localStorage.getItem('settings');
state.settings = storedSettings == null ? { state.settings = storedSettings == null ? {
theme: '', theme: '',
@ -55,6 +68,12 @@ export default createStore({
localStorage.setItem('trackers', JSON.stringify(state.trackers)); localStorage.setItem('trackers', JSON.stringify(state.trackers));
localStorage.setItem('archive', JSON.stringify(state.archive)); localStorage.setItem('archive', JSON.stringify(state.archive));
}, },
saveTasks(state) {
localStorage.setItem('tasks', JSON.stringify(state.tasks));
},
saveSettings(state) {
localStorage.setItem('settings', JSON.stringify(state.settings));
},
deleteTracker(state, index, archive) { deleteTracker(state, index, archive) {
let message = ''; let message = '';
@ -85,6 +104,20 @@ export default createStore({
}, },
selectTracker(state, tracker) { selectTracker(state, tracker) {
state.selectedTracker = tracker; state.selectedTracker = tracker;
},
saveNotes(state) {
localStorage.setItem('notes', JSON.stringify(state.notes));
},
createNote(state, content = '') {
state.notes.pushToBeginning({
body: content,
color: '#ffea77',
created: moment()
});
},
deleteNote(state, index) {
state.notes.splice(index, 1);
localStorage.setItem('notes', JSON.stringify(state.notes));
} }
} }
}) })

6
src/views/History.vue

@ -13,6 +13,9 @@
<h6>Datum</h6> <h6>Datum</h6>
<input id="date" type="date" class="form-control" v-model="customDateForPastDays"> <input id="date" type="date" class="form-control" v-model="customDateForPastDays">
</div> </div>
<div>
{{ showWeekday(customDateForPastDays) }}
</div>
<ul class="list-group"> <ul class="list-group">
<li class="list-group-item" <li class="list-group-item"
:style="entry.archive ? 'background-color: lightgrey;' : ''" :style="entry.archive ? 'background-color: lightgrey;' : ''"
@ -119,6 +122,9 @@ export default {
return time + postFix + plural; return time + postFix + plural;
}, },
showWeekday(date) {
return moment(date).format('dddd');
}
} }
} }
</script> </script>

25
src/views/Menu.vue

@ -45,6 +45,16 @@
<i class="fas fa-archive"></i> <i class="fas fa-archive"></i>
</router-link> </router-link>
</div> </div>
<div class="left-menu-item">
<router-link to="/notes"
type="button"
class="btn btn-info text-light bottom-menu-item"
style="background-color: #ffea77;"
data-bs-placement="left"
title="Notizen">
<i class="fas fa-pen"></i>
</router-link>
</div>
<div class="left-menu-item" v-if="($store.state.trackers.length + $store.state.archive.length) > 0"> <div class="left-menu-item" v-if="($store.state.trackers.length + $store.state.archive.length) > 0">
<a type="button" <a type="button"
class="btn btn-info text-light bottom-menu-item" class="btn btn-info text-light bottom-menu-item"
@ -55,6 +65,17 @@
<i class="fas fa-history"></i> <i class="fas fa-history"></i>
</a> </a>
</div> </div>
<div class="left-menu-item">
<a type="button"
class="btn text-dark bottom-menu-item"
data-bs-toggle="offcanvas"
data-bs-target="#tasksCanvas"
data-bs-placement="top"
style="background-color: beige;"
title="Tasks">
<i class="fas fa-tasks"></i>
</a>
</div>
<div class="left-menu-item"> <div class="left-menu-item">
<a type="button" <a type="button"
class="btn btn-dark text-light bottom-menu-item" class="btn btn-dark text-light bottom-menu-item"
@ -101,4 +122,8 @@ export default {
margin-bottom: 1em; margin-bottom: 1em;
} }
.fas {
text-shadow: 1px 1px grey;
}
</style> </style>

190
src/views/Notes.vue

@ -0,0 +1,190 @@
<template>
<div class="row">
<div class="col-md-12">
<div class="float-end">
<div v-if="$store.state.notes.length > 0" class="filter-wrapper">
<a href="javascript:"
v-if="colorToFilter !== ''"
v-on:click="colorToFilter = ''"
class="color-change-button disable-filter-button"
:style="'background-color: '+colorToFilter">
Filter aus
</a>
<span v-for="color in noteColors"
v-bind:key="color">
<a href="javascript:"
v-if="colorToFilter !== color"
v-on:click="colorToFilter = color"
class="color-change-button"
:style="'background-color: ' + color">
<i class="fas fa-filter filter-icon"></i>
</a>
</span>
</div>
<a href="javascript:" v-on:click="createNote()" class="btn btn-sm btn-success">Neue Notiz</a>
</div>
<h5><i class="fa fa-pen"></i> Notizen</h5>
</div>
<template v-for="(note, noteIndex) in $store.state.notes" v-bind:key="noteIndex">
<div v-if="colorToFilter === '' || note.color === colorToFilter" class="col-sm-6 col-md-4 col-lg-3 card-box">
<div class="card">
<div class="card-body note"
:style="'background-color:' + note.color ?? '#ffea77'">
<textarea v-model="note.body" spellcheck="false"
@keydown="this.$store.commit('saveNotes')"></textarea>
<div class="color-changer">
<span v-for="color in noteColors" v-bind:key="color">
<span href="javascript:"
@click="changeColor(note, color);"
class="color-change-button"
v-if="color !== note.color"
:style="'background-color: ' + color">
</span>
</span>
</div>
<div class="float-end">
<a href="javascript:" class="delete-button"
@click="$store.commit('deleteNote', noteIndex)"><i
class="fas fa-trash"></i></a>
</div>
</div>
</div>
</div>
</template>
<span v-if="colorToFilter !== '' && !notesExistInFilteredColor">
Keine Notizen mit gewählter Farbe vorhanden<br>
<a href="javascript:"
class="color-change-button disable-filter-button"
:style="'background-color: '+colorToFilter"
v-on:click="colorToFilter = ''">
Filter ausschalten
</a>
</span>
</div>
</template>
<script>
import axios from "axios";
export default {
name: "Notes",
data() {
return {
noteColors: ['#ffea77', '#ee6352', '#59cd90', '#3fa7d6', '#fac05e', '#f79d84'],
colorToFilter: ''
}
},
methods: {
createNote() {
let component = this;
axios.get(
'https://api.quotable.io/random'
).then((response) => {
component.$store.commit('createNote', response.data.content + '\n - ' + response.data.author);
component.$store.commit('saveNotes');
}).catch(() => {
component.$store.commit('createNote', '');
component.$store.commit('saveNotes');
})
},
changeColor(note, color) {
note.color = color;
this.$store.commit('saveNotes');
}
},
computed: {
notesExistInFilteredColor() {
let component = this;
return this.$store.state.notes.filter((note) => {
return note.color === component.colorToFilter;
}).length;
}
}
}
</script>
<style scoped>
.card-body {
font-family: NotePaper, sans-serif;
}
#note-container {
margin-top: 1em;
}
textarea {
width: 100%;
height: 100%;
padding: 0;
margin: 0;
background-color: transparent;
border: 0 solid transparent;
min-height: 10em;
}
textarea:focus {
outline: none;
}
.color-changer {
position: absolute;
bottom: -0.8em;
z-index: 1000;
}
.color-change-button {
margin-right: 0.2em;
background-color: red;
border-radius: 25px;
padding: 0.2em 0.7em;
text-decoration: none;
}
.color-change-button:hover {
opacity: 0.9;
cursor: pointer;
}
.delete-button {
position: absolute;
bottom: -1.5em;
right: 0.5em;
text-align: right;
background-color: red;
border-radius: 25px;
z-index: 1000;
}
.delete-button i {
margin: 1em;
color: black;
}
.delete-button:hover * {
color: white;
}
.filter-icon {
color: white;
font-size: 0.7em;
}
.disable-filter-button {
color: white;
background-color: grey;
}
.filter-wrapper {
display: inline-block;
margin: 0.3em 1em;
}
.card-box {
margin-top: 0.5em;
margin-bottom: 0.5em;
}
</style>

7
src/views/Settings.vue

@ -3,7 +3,6 @@
aria-hidden="true"> aria-hidden="true">
<div class="offcanvas-header"> <div class="offcanvas-header">
<h5><i class="fas fa-sliders-h"></i> Einstellungen</h5> <h5><i class="fas fa-sliders-h"></i> Einstellungen</h5>
<button type="button" v-on:click="updateStorage()" class="btn-close" data-bs-dismiss="offcanvas" aria-label="Close"></button>
</div> </div>
<div class="offcanvas-body"> <div class="offcanvas-body">
<div class="row"> <div class="row">
@ -11,19 +10,19 @@
<h5>Allgemeine Einstellungen</h5> <h5>Allgemeine Einstellungen</h5>
<div class="form-group"> <div class="form-group">
<label>Ticket-Link <small>Link zu einem Ticket ohne Ticketnummer</small></label> <label>Ticket-Link <small>Link zu einem Ticket ohne Ticketnummer</small></label>
<input type="text" v-model="trackerSystemUrl" class="form-control"> <input type="text" v-model="$store.state.settings.trackerSystemUrl" v-on:input="$store.commit('saveSettings')" class="form-control">
</div> </div>
<br/> <br/>
<div class="form-group"> <div class="form-group">
<label> <label>
<input type="checkbox" class="form-control-checkbox" v-model="$store.state.settings.showPT"> <input type="checkbox" v-on:input="$store.commit('saveSettings')" class="form-control-checkbox" v-model="$store.state.settings.showPT">
Ab 8 Stunden nurmehr PT anzeigen Ab 8 Stunden nurmehr PT anzeigen
</label> </label>
</div> </div>
<br/> <br/>
<div class="form-group"> <div class="form-group">
<label> <label>
<input type="checkbox" class="form-control-checkbox" <input type="checkbox" v-on:input="$store.commit('saveSettings')" class="form-control-checkbox"
v-model="$store.state.settings.dontShowMinutes"> v-model="$store.state.settings.dontShowMinutes">
Zeit immer in Stunden anzeigen Zeit immer in Stunden anzeigen
</label> </label>

120
src/views/Tasks.vue

@ -0,0 +1,120 @@
<template>
<div class="offcanvas offcanvas-end"
id="tasksCanvas"
tabindex="-1"
role="dialog"
aria-labelledby="showTasksCanvas"
aria-hidden="true">
<div class="offcanvas-header">
<h5><i class="fas fa-clipboard"></i> Tasks</h5>
</div>
<div class="offcanvas-body">
<div class="form-group">
<input type="text" id="newTaskInput" class="form-control"
v-model="newTaskInput" placeholder="Neuer Task" v-on:keyup.enter="addTask()"/>
</div>
<ul class="list-group" v-if="$store.state.tasks && $store.state.tasks.length > 0">
<template v-for="(task, taskIndex) in $store.state.tasks" v-bind:key="taskIndex">
<li class="list-group-item" v-if="!task.done">
<span class="float-end">
<a href="javascript:">
<i class="fas fa-trash" @click="deleteTask(taskIndex)"></i>
</a>
</span>
<a href="javascript:" @click="toggleTask(task)">
<i class="far fa-square"></i>
</a> {{ task.name }}
<div class="form-group">
<div class="float-end">
{{ task.percentDone }}% erledigt
</div>
<input type="range"
class="range range-success range-tasks"
min="0"
max="100"
step="5"
v-model="task.percentDone"
@change="checkForCompletionOfTask(task)">
</div>
</li>
</template>
</ul>
<br/>
<ul class="list-group" v-if="$store.state.tasks && $store.state.tasks.length > 0">
<template v-for="(task, taskIndex) in $store.state.tasks" v-bind:key="taskIndex">
<li class="list-group-item" v-if="task.done">
<span class="float-end">
<a href="javascript:">
<i class="fas fa-trash" @click="deleteTask(taskIndex)"></i>
</a>
</span>
<a href="javascript:" @click="toggleTask(task)">
<i class="far fa-check-square"></i>
</a> <span class="finished-task">{{ task.name }}</span>
</li>
</template>
</ul>
</div>
</div>
</template>
<script>
import moment from "moment";
export default {
name: "Tasks",
data() {
return {
newTaskInput: ''
}
},
methods: {
deleteTask(taskIndex) {
this.$store.state.tasks.splice(taskIndex, 1)
this.$store.commit('saveTasks');
},
addTask() {
if (this.newTaskInput.length <= 0 || this.newTaskInput.trim() === '') {
return false;
}
if (!this.$store.state.tasks) {
this.$store.state.tasks = [];
}
this.$store.state.tasks.pushToBeginning({
name: this.newTaskInput,
done: false,
created: moment(),
percentDone: 0,
finished: null
});
this.newTaskInput = '';
this.$store.commit('saveTasks');
},
toggleTask(task) {
task.done = !task.done;
if (task.done) {
task.finished = moment();
task.percentDone = 100;
} else {
task.finished = null;
task.percentDone = 0;
}
this.$store.commit('saveTasks');
},
checkForCompletionOfTask(task) {
task.done = task.percentDone === 100;
this.$forceUpdate();
this.$store.commit('saveTasks');
},
}
}
</script>
<style scoped>
</style>

26
src/views/TasksForTracker.vue

@ -7,7 +7,7 @@
aria-labelledby="showTrackerCanvasCanvas" aria-labelledby="showTrackerCanvasCanvas"
aria-hidden="true"> aria-hidden="true">
<div class="offcanvas-header"> <div class="offcanvas-header">
<h5><i class="fas fa-clock"></i> Tasks für {{ $store.state.selectedTracker.number }}</h5> <h5><i class="fas fa-clipboard"></i> Tasks für {{ $store.state.selectedTracker.number }}</h5>
</div> </div>
<div class="offcanvas-body"> <div class="offcanvas-body">
<div class="form-group"> <div class="form-group">
@ -83,13 +83,23 @@ export default {
this.$store.state.selectedTracker.tasks = []; this.$store.state.selectedTracker.tasks = [];
} }
this.$store.state.selectedTracker.tasks.pushToBeginning({ let newTasks = [];
name: this.newTaskInput,
done: false, if (this.newTaskInput.split(';').length > 3) {
created: moment(), newTasks = this.newTaskInput.split(';').reverse().map((task) => task.trim());
percentDone: 0, } else {
finished: null newTasks.push(this.newTaskInput);
}); }
newTasks.forEach((task) => {
this.$store.state.selectedTracker.tasks.pushToBeginning({
name: task,
done: false,
created: moment(),
percentDone: 0,
finished: null
});
})
this.newTaskInput = ''; this.newTaskInput = '';
this.$store.commit('saveTrackers'); this.$store.commit('saveTrackers');

261
src/views/Trackers.vue

@ -8,147 +8,146 @@
:style="tracker.isTimeBox ? 'background: linear-gradient(90deg, grey ' + ((timeBoxTimeLeft(tracker) * 100) / tracker.timeBoxMinutes)+'% , black 100%':''"> :style="tracker.isTimeBox ? 'background: linear-gradient(90deg, grey ' + ((timeBoxTimeLeft(tracker) * 100) / tracker.timeBoxMinutes)+'% , black 100%':''">
<div class="card-body"> <div class="card-body">
<div class="card-text"> <div class="card-text">
<a class="position-absolute"
data-bs-toggle="dropdown"
aria-expanded="false"
title="Neu">
<i class="fas fa-ellipsis-v"></i>
</a>
<div class="dropdown-menu" aria-labelledby="create-dropdown-menu">
<span @click="archiveTracker(trackerIndex)" title="Archivieren">
<i class="fas fa-archive"></i> <small>Archivieren</small>
</span><br/>
<span @click="openTasksForTracker(tracker)" title="Tasks">
<i class="fas fa-clipboard -check"></i> <small>Tasks
{{ showOpenTasksForTracker(tracker.tasks) }}</small>
</span><br/>
<span @click="deleteTracker(trackerIndex)" title="Löschen">
<i class="fas fa-trash"></i> <small>Löschen</small>
</span>
</div>
<input type="text" <input type="text"
v-model="tracker.number" v-model="tracker.number"
class="form-control trackingNameField" class="form-control trackingNameField"
@keydown="this.$store.commit('saveTrackers')"/> @keydown="this.$store.commit('saveTrackers')"/>
<div class="row time-data-container"> <div class="row">
<div v-if="!tracker.tracking"> <div v-if="tracker.tracking === true">
<button type="button" <div class="text-danger font-weight-bolder float-end tracker-time-info">
class="btn btn-success rounded-circle position-absolute btn-tracker-state" <div class="spinner-grow spinner-grow-sm" role="status">
@click="startTracking(tracker)"> <span class="sr-only">Tracking...</span>
<i class="fas fa-play"></i> </div>
</button> Tracking (<i class="fas fa-play"></i> {{ getTrackingStartTime(tracker) }})
</div>
</div> </div>
</div>
<div v-else> <template v-if="!tracker.isTimeBox">
<button type="button" <div v-if="tracker.tracking === true">
class="btn btn-danger rounded-circle position-absolute btn-tracker-state" <!-- <span class="float-end">{{ getTrackingStartTime(tracker) }}</span>-->
@click="stopTracking(tracker)"> <!-- <span v-if="tracker.tracking === true">Gestartet: </span>-->
<i class="fas fa-stop"></i> <!-- <br/>-->
</button> <span class="float-end">{{ currentTrackingRunningFor(tracker) }}</span>
<span v-if="tracker.tracking === true">Läuft seit: </span>
</div> </div>
<template v-if="!tracker.isTimeBox"> <div>
<template v-if="tracker.tracking === true"> <span class="float-end">{{ getTotalTime(tracker) }}</span>
<div class="col-6 col-sm-3"> <span class="current-tracker-info">Gesamt: </span>
<small class="text-muted">Gestartet </small><br/> </div>
<span>{{ getTrackingStartTime(tracker) }}</span>
</div>
<div class="col-6 col-sm-3"> <div v-if="getTotalTimeToday(tracker, true) > 1">
<small class="text-muted">Läuft seit </small><br/> <span class="float-end">{{ getTotalTimeToday(tracker) }}</span>
<span>{{ currentTrackingRunningFor(tracker) }}</span> <span class="">Heute: </span>
</div> </div>
</template>
<div class="col-6 col-sm-3"> <div class="row">
<small class="text-muted">Gesamt </small><br/> <div class="col-md-6" v-if="!tracker.tracking">
<span>{{ getTotalTime(tracker) }}</span> <button type="button" class="btn btn-primary tracker-action-button"
@click="startTracking(tracker)">
<i class="far fa-play-circle"></i> <small>Starten</small>
</button>
</div> </div>
<div class="col-6 col-sm-3"> <div class="col-md-6" v-else>
<small class="text-muted">Heute </small><br/> <button type="button" class="btn btn-danger tracker-action-button"
<span>{{ getTotalTimeToday(tracker) }}</span> @click="stopTracking(tracker)">
<i class="far fa-stop-circle"></i> <small>Stoppen</small>
</button>
</div> </div>
</template>
<template v-else>
<div class="row">
<div v-if="tracker.tracking === true">
<span class="float-end">{{ getTrackingStartTime(tracker) }}</span>
<span v-if="tracker.tracking === true">Gestartet: </span>
<br/>
<span class="float-end">{{
currentTrackingRunningFor(tracker)
}}</span>
<span v-if="tracker.tracking === true">Läuft seit: </span>
</div>
<template v-if="!tracker.timeBoxMinutes"> <div class="col-md-6">
<div class="col-12"> <button class="btn btn-warning tracker-action-button"
Minuten: @click="archiveTracker(trackerIndex)" title="Archivieren">
</div> <i class="fas fa-archive"></i> <small>Archivieren</small>
<div class="col"> </button>
<button type="button" </div>
class="btn btn-secondary tracker-action-button"
@click="startTimeBox(tracker, 15)">
<i class="far fa-play-circle"></i> 15
</button>
</div>
<div class="col">
<button type="button"
class="btn btn-secondary tracker-action-button"
@click="startTimeBox(tracker, 30)">
<i class="far fa-play-circle"></i> 30
</button>
</div>
<div class="col">
<button type="button"
class="btn btn-secondary tracker-action-button"
@click="startTimeBox(tracker, 60)">
<i class="far fa-play-circle"></i> 60
</button>
</div>
</template>
<div class="col-12"
v-if="tracker.timeBoxMinutes && timeBoxTimeLeft(tracker) > 0">
<span class="float-end">{{
timeBoxTimeLeft(tracker)
}} Minuten</span>
<span>Zeit übrig: </span>
</div>
<div class="col-12 text-center" v-if="timeBoxTimeLeft(tracker) <= 0">
<h5 class="text-danger text-bold">Abgeschlossen</h5>
</div>
<div class="col-md-12" v-if="tracker.tracking"> <div class="col-md-6">
<button type="button" class="btn btn-danger tracker-action-button" <button type="button" class="btn btn-info tracker-action-button"
@click="stopTracking(tracker)"> @click="openTasksForTracker(tracker)" title="Tasks">
<i class="far fa-stop-circle"></i> <small>Stoppen</small> <i class="fas fa-clipboard -check"></i> <small>Tasks
{{ showOpenTasksForTracker(tracker.tasks) }}</small>
</button>
</div>
<div class="col-md-6">
<button class="btn btn-danger tracker-action-button"
@click="deleteTracker(trackerIndex)" title="Löschen">
<i class="fas fa-trash"></i> <small>Löschen</small>
</button>
</div>
</div>
</template>
<template v-else>
<div class="row">
<div v-if="tracker.tracking === true">
<span class="float-end">{{ getTrackingStartTime(tracker) }}</span>
<span v-if="tracker.tracking === true">Gestartet: </span>
<br/>
<span class="float-end">{{ currentTrackingRunningFor(tracker) }}</span>
<span v-if="tracker.tracking === true">Läuft seit: </span>
</div>
<template v-if="!tracker.timeBoxMinutes">
<div class="col-12">
Minuten:
</div>
<div class="col">
<button type="button" class="btn btn-secondary tracker-action-button"
@click="startTimeBox(tracker, 15)">
<i class="far fa-play-circle"></i> 15
</button> </button>
</div> </div>
<div class="col-md-12"
v-if="!tracker.tracking && tracker.timeBoxMinutes && timeBoxTimeLeft(tracker) > 0"> <div class="col">
<button type="button" class="btn btn-primary tracker-action-button" <button type="button" class="btn btn-secondary tracker-action-button"
@click="startTracking(tracker)"> @click="startTimeBox(tracker, 30)">
<i class="far fa-play-circle"></i> <small>Starten</small> <i class="far fa-play-circle"></i> 30
</button> </button>
</div> </div>
<div class="col-md-12"> <div class="col">
<button class="btn btn-danger tracker-action-button" <button type="button" class="btn btn-secondary tracker-action-button"
@click="deleteTracker(trackerIndex)" title="Löschen"> @click="startTimeBox(tracker, 60)">
<i class="fas fa-trash"></i> <small>Löschen</small> <i class="far fa-play-circle"></i> 60
</button> </button>
</div> </div>
</template>
<div class="col-12"
v-if="tracker.timeBoxMinutes && timeBoxTimeLeft(tracker) > 0">
<span class="float-end">{{ timeBoxTimeLeft(tracker) }} Minuten</span>
<span>Zeit übrig: </span>
</div> </div>
</template> <div class="col-12 text-center" v-if="timeBoxTimeLeft(tracker) <= 0">
</div> <h5 class="text-danger text-bold">Abgeschlossen</h5>
</div>
<div class="col-md-12" v-if="tracker.tracking">
<button type="button" class="btn btn-danger tracker-action-button"
@click="stopTracking(tracker)">
<i class="far fa-stop-circle"></i> <small>Stoppen</small>
</button>
</div>
<div class="col-md-12"
v-if="!tracker.tracking && tracker.timeBoxMinutes && timeBoxTimeLeft(tracker) > 0">
<button type="button" class="btn btn-primary tracker-action-button"
@click="startTracking(tracker)">
<i class="far fa-play-circle"></i> <small>Starten</small>
</button>
</div>
<div class="col-md-12">
<button class="btn btn-danger tracker-action-button"
@click="deleteTracker(trackerIndex)" title="Löschen">
<i class="fas fa-trash"></i> <small>Löschen</small>
</button>
</div>
</div>
</template>
</div> </div>
</div> </div>
</div> </div>
@ -167,7 +166,8 @@ import {Offcanvas} from "bootstrap";
export default { export default {
name: "Trackers", name: "Trackers",
data() { data() {
return {} return {
}
}, },
computed: { computed: {
trackers() { trackers() {
@ -243,7 +243,7 @@ export default {
return this.timeWithPostFix(totalTime); return this.timeWithPostFix(totalTime);
} }
}, },
getTotalTimeToday(tracker) { getTotalTimeToday(tracker, raw = false) {
let totalTime = 0; let totalTime = 0;
if (tracker.history.length > 0) { if (tracker.history.length > 0) {
@ -258,6 +258,10 @@ export default {
totalTime += Math.round(moment.duration(moment().diff(tracker.trackingStarted)).as('minutes')); totalTime += Math.round(moment.duration(moment().diff(tracker.trackingStarted)).as('minutes'));
} }
if (raw) {
return totalTime;
}
return this.timeWithPostFix(totalTime); return this.timeWithPostFix(totalTime);
}, },
timeWithPostFix(time) { timeWithPostFix(time) {
@ -306,7 +310,7 @@ export default {
['<button><i class="fas fa-undo"></i></button>', function (instance, toast) { ['<button><i class="fas fa-undo"></i></button>', function (instance, toast) {
instance.hide({ instance.hide({
transitionOut: 'fadeOutUp', transitionOut: 'fadeOutUp',
onClosing: function () { onClosing: function(){
component.$store.commit('restoreTrashed'); component.$store.commit('restoreTrashed');
component.$store.commit('saveTrackers'); component.$store.commit('saveTrackers');
} }
@ -318,7 +322,7 @@ export default {
}, },
showOpenTasksForTracker(tasks) { showOpenTasksForTracker(tasks) {
let count = this.getOpenTasksForTracker(tasks); let count = this.getOpenTasksForTracker(tasks);
return count > 0 ? ' (' + count + ' offen)' : ''; return count > 0 ? ' ('+count+' offen)' : '';
}, },
getOpenTasksForTracker(tasks) { getOpenTasksForTracker(tasks) {
if (!tasks) { if (!tasks) {
@ -356,10 +360,14 @@ export default {
</script> </script>
<style scoped> <style scoped>
.tracker-time-info {
margin-top: 1em;
clear: both;
}
.trackingNameField { .trackingNameField {
max-height: 1em; max-height: 1em;
margin-bottom: 1px; margin-bottom: 1px;
width: 80%;
} }
.bg-timebox input { .bg-timebox input {
@ -370,13 +378,4 @@ export default {
color: lightgray; color: lightgray;
} }
.btn-tracker-state {
margin-top: -2em;
right: 1em;
}
.time-data-container {
padding-top: 2.5em;
}
</style> </style>
Loading…
Cancel
Save