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() { } });