You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
284 lines
8.5 KiB
284 lines
8.5 KiB
let tab = new Vue({ |
|
el: '#root', |
|
data: { |
|
theme: 'quartz', |
|
themes: null, |
|
dashboardLogo: 'img/logo.png', |
|
ticketSystemUrl: '', |
|
showPT: true, |
|
linkTarget: '_blank', |
|
inputs: { |
|
importJson: '' |
|
}, |
|
trackedTickets: [], |
|
selectedTicket: null |
|
}, |
|
mounted() { |
|
let vue = this; |
|
|
|
this.loadStorage(); |
|
this.fetchThemes(); |
|
moment.locale('de'); |
|
|
|
setInterval(() => { |
|
vue.$forceUpdate(); |
|
}, 1000 * 60) |
|
}, |
|
methods: { |
|
loadStorage() { |
|
let storedTrackedTickets = JSON.parse(localStorage.getItem('trackedTickets')); |
|
this.trackedTickets = storedTrackedTickets == null ? [] : storedTrackedTickets; |
|
|
|
let storedticketSystemUrl = localStorage.getItem('ticketSystemUrl'); |
|
this.ticketSystemUrl = storedticketSystemUrl == null ? '' : storedticketSystemUrl; |
|
|
|
let storedShowPT = localStorage.getItem('showPT'); |
|
this.showPT = storedShowPT == null ? true : storedShowPT; |
|
|
|
let storedTheme = localStorage.getItem('theme'); |
|
this.theme = storedTheme == null ? 'materia' : storedTheme; |
|
}, |
|
updateStorage() { |
|
localStorage.setItem('trackedTickets', JSON.stringify(this.trackedTickets)); |
|
localStorage.setItem('ticketSystemUrl', this.ticketSystemUrl); |
|
localStorage.setItem('showPT', this.showPT); |
|
localStorage.setItem('theme', this.theme); |
|
}, |
|
resetToDefault() { |
|
this.updateStorage(); |
|
}, |
|
addTrackedTicket() { |
|
let newTicket = { |
|
archived: false, |
|
tracking: false, |
|
number: '#', |
|
trackingStarted: null, |
|
trackingStopped: null, |
|
history: [] |
|
}; |
|
|
|
this.trackedTickets.push(newTicket); |
|
this.updateStorage(); |
|
}, |
|
startTracking(ticket) { |
|
this.stopTrackingTicket(); |
|
ticket.trackingStarted = moment(); |
|
ticket.tracking = true; |
|
|
|
this.$forceUpdate(); |
|
this.updateStorage(); |
|
}, |
|
stopTracking(ticket) { |
|
ticket.trackingStopped = moment(); |
|
ticket.tracking = false; |
|
|
|
let minutesSpent = moment.duration( |
|
ticket.trackingStopped.diff(ticket.trackingStarted) |
|
).as('minutes'); |
|
|
|
|
|
ticket.history.push({ |
|
trackingStarted: ticket.trackingStarted, |
|
trackingStopped: ticket.trackingStopped, |
|
manually: false, |
|
minutes: Math.round(minutesSpent) |
|
}); |
|
|
|
ticket.trackingStarted = null; |
|
ticket.trackingStopped = null; |
|
|
|
this.$forceUpdate(); |
|
this.updateStorage(); |
|
}, |
|
formattedDate(date) { |
|
return moment(date).format('llll'); |
|
}, |
|
exactTimestamp(date) { |
|
return moment(date).format('LTS'); |
|
}, |
|
currentTrackingRunningFor(ticket) { |
|
return this.timeWithPostFix(Math.round(moment.duration(moment().diff(ticket.trackingStarted)).as('minutes'))); |
|
}, |
|
getTotalTime(ticket) { |
|
let totalTime = 0; |
|
|
|
if (ticket.history.length > 0) { |
|
ticket.history.forEach(function (historyEntry) { |
|
totalTime += Math.round(historyEntry.minutes); |
|
}); |
|
} |
|
|
|
if (ticket.tracking) { |
|
totalTime += Math.round(moment.duration(moment().diff(ticket.trackingStarted)).as('minutes')); |
|
} |
|
|
|
return this.timeWithPostFix(totalTime); |
|
}, |
|
getTotalTimeToday(ticket) { |
|
let totalTime = 0; |
|
|
|
if (ticket.history.length > 0) { |
|
ticket.history.forEach(function (historyEntry) { |
|
if (moment(historyEntry.trackingStarted).format("MMM Do YY") === moment().format("MMM Do YY")) { |
|
totalTime += Math.round(historyEntry.minutes); |
|
} |
|
}); |
|
} |
|
|
|
if (ticket.tracking) { |
|
totalTime += Math.round(moment.duration(moment().diff(ticket.trackingStarted)).as('minutes')); |
|
} |
|
|
|
return this.timeWithPostFix(totalTime); |
|
}, |
|
timeWithPostFix(time) { |
|
let postFix = ' Minute'; |
|
|
|
if (time >= 480 && this.showPT) { |
|
postFix = ' PT'; |
|
time = (time / 480).toFixed(1); |
|
} else if (time >= 60) { |
|
postFix = ' Stunde'; |
|
time = (time / 60).toFixed(2); |
|
} |
|
|
|
let plural = ''; |
|
|
|
if ((time > 1 || time <= 0) && postFix !== ' PT') { |
|
plural = 'n' |
|
} |
|
|
|
return time + postFix + plural; |
|
}, |
|
stopTrackingTicket() { |
|
let vue = this; |
|
|
|
vue.trackedTickets.forEach(function (ticket) { |
|
if (ticket.tracking === true) { |
|
vue.stopTracking(ticket); |
|
} |
|
}) |
|
}, |
|
getTrackingStartTime(ticket) { |
|
return moment(ticket.trackingStarted).format('LT'); |
|
}, |
|
isTicketNumber(number) { |
|
return number.indexOf('#') >= 0; |
|
}, |
|
deleteTicket(index) { |
|
this.trackedTickets.splice(index, 1); |
|
this.updateStorage(); |
|
}, |
|
archiveTicket(ticket) { |
|
ticket.archived = true; |
|
if (ticket.tracking) { |
|
this.stopTrackingTicket(); |
|
} |
|
this.updateStorage(); |
|
this.$forceUpdate(); |
|
}, |
|
reactivateTicket(ticket) { |
|
ticket.archived = false; |
|
this.updateStorage(); |
|
}, |
|
deleteHistoryEntry(ticketIndex, historyIndex) { |
|
if (ticketIndex) { |
|
this.trackedTickets[ticketIndex].history.splice(historyIndex, 1); |
|
} else { |
|
this.selectedTicket.history.splice(historyIndex, 1); |
|
} |
|
this.updateStorage(); |
|
}, |
|
bookTimeManually(ticket, minutes) { |
|
ticket.history.push({ |
|
trackingStarted: moment(), |
|
trackingStopped: moment(), |
|
manually: true, |
|
minutes: Math.round(minutes) |
|
}); |
|
|
|
this.updateStorage(); |
|
}, |
|
importData() { |
|
let json = JSON.parse(this.inputs.importJson); |
|
|
|
this.trackedTickets = json.trackedTickets; |
|
this.ticketSystemUrl = json.ticketSystemUrl; |
|
this.showPT = json.showPT; |
|
this.theme = json.theme; |
|
this.updateStorage(); |
|
location.reload(); |
|
}, |
|
copy2Clipboard() { |
|
let copyText = document.getElementById("exportJsonInput"); |
|
|
|
copyText.select(); |
|
copyText.setSelectionRange(0, 99999); |
|
|
|
document.execCommand("copy"); |
|
|
|
alert('Text kopiert!'); |
|
}, |
|
fetchThemes() { |
|
let vue = this; |
|
|
|
axios.get( |
|
'https://bootswatch.com/api/5.json' |
|
).then((response) => { |
|
vue.themes = response.data.themes; |
|
}).catch((error) => { |
|
console.log(error); |
|
}); |
|
}, |
|
showHistoryForTicket(ticket) { |
|
this.selectedTicket = ticket; |
|
this.$forceUpdate(); |
|
setTimeout(() => { |
|
let historyModal = new bootstrap.Modal(document.getElementById('historyModal')); |
|
historyModal.toggle(); |
|
}, 50) |
|
} |
|
}, |
|
watch: { |
|
showPT() { |
|
this.updateStorage(); |
|
this.$forceUpdate(); |
|
}, |
|
theme() { |
|
this.updateStorage(); |
|
this.$forceUpdate(); |
|
} |
|
}, |
|
computed: { |
|
exportJson() { |
|
return JSON.stringify({ |
|
trackedTickets: this.trackedTickets, |
|
ticketSystemUrl: this.ticketSystemUrl, |
|
showPT: this.showPT, |
|
theme: this.theme |
|
}); |
|
}, |
|
archivedTrackers() { |
|
let vue = this; |
|
let count = 0; |
|
|
|
this.trackedTickets.forEach((ticket) => { |
|
count += (ticket.archived ? 1 : 0); |
|
}) |
|
|
|
return count; |
|
}, |
|
activeTrackers() { |
|
let vue = this; |
|
let count = 0; |
|
|
|
this.trackedTickets.forEach((ticket) => { |
|
count += (ticket.archived ? 0 : 1); |
|
}) |
|
|
|
return count; |
|
} |
|
}, |
|
created() { |
|
} |
|
});
|
|
|