function initializeNewTopic() { actualTopic = {"name": "", "id": randomId()} reset() document.getElementById("topicInput").value = actualTopic.name } function reset() { actualTopic.watches = [{"actions": []}, {"actions": []}, {"actions": []}] saveActualTopic() } function resetButton() { if(confirm("Soll die Zähler zurückgesetzt werden?")){ reset() } } function buttonDeleteAllClosedTopics() { if(confirm("Sollen alle abgeschlossenen Themen gelöscht werden?")) { closedTopics = [] saveClosedTopics() refreshClosedTopics() } } function buttonDeleteClosedTopic(topicIndex) { if(confirm('Soll das Thema "' + closedTopics[topicIndex]["name"] + '" gelöscht werden?')) { deleteTopic(topicIndex) } } function closeTopic() { stop() let defaultname = "Thema" let name = actualTopic.name let nameLessCounter = 1 while(!name){ let foundName = false closedTopics.forEach(topic => { if(topic.name === defaultname + nameLessCounter){ foundName = true } }); if(foundName) { nameLessCounter++ } else { name = defaultname + nameLessCounter } } actualTopic.name = name closedTopics.push(actualTopic) saveClosedTopics() refreshClosedTopics() initializeNewTopic() } function deleteTopic(topicIndex) { closedTopics = closedTopics.slice(0, topicIndex).concat(closedTopics.slice(topicIndex+1)) saveClosedTopics() refreshClosedTopics() } function reopenTopic(topicIndex) { if(actualTopic.watches[0]["actions"]["length"] > 0 || actualTopic.watches[1]["actions"]["length"] > 0 ||actualTopic.watches[2]["actions"]["length"] > 0 || actualTopic.name !== "") { closeTopic() } actualTopic = closedTopics[topicIndex] document.getElementById("topicInput").value = actualTopic.name deleteTopic(topicIndex) saveClosedTopics() saveActualTopic() } function start(watchIndex) { stop() actualTopic.watches[watchIndex].actions.push({"type": "start", "time": new Date().getTime()}) saveActualTopic() } function stop() { actualTopic.watches.forEach(watch => { if(watch["actions"]["length"] > 0) { if(watch["actions"]["length"] % 2 === 1){ watch["actions"].push({"type": "stop", "time": new Date().getTime()}) } } }); saveActualTopic() } function calcPercForWatch(watchIndex, topic) { let sumAll = sumAllwatches(topic) if(sumAll === 0) { return 0 } return Math.round(sumForWatch(topic.watches[watchIndex]) / sumAllwatches(topic) * 100) } function sumForWatch(watch) { let summe = 0 let i = 0 while( i < watch["actions"]["length"]){ let start = watch.actions[i].time let stop = new Date().getTime() if(i+1 < watch["actions"]["length"]) { stop = watch["actions"][i+1].time } summe += (stop - start) i += 2 } return summe } function countForWatch(watch) { return watch["actions"].length / 2 } function calcPercCountForWatch(watchindex, topic) { let sumAll = sumCountAllWatches(topic) if(sumAll === 0) { return 0 } return Math.round(countForWatch(topic.watches[watchindex]) / sumAll * 100) } function sumCountAllWatches(topic){ return countForWatch(topic.watches[0]) + countForWatch(topic.watches[1]) + countForWatch(topic.watches[2]) } function sumAllwatches(topic) { return sumForWatch(topic.watches[0]) + sumForWatch(topic.watches[1]) + sumForWatch(topic.watches[2]) } function timeToISO(time){ return new Date(time).toISOString().slice(11, 19) } function refreshWatch(watchIndex) { let timeCell = document.getElementById("time-" + watchIndex) timeCell.textContent = timeToISO(sumForWatch(actualTopic.watches[watchIndex])) if(actualTopic.watches[watchIndex]["actions"].length !== 0 && actualTopic.watches[watchIndex]["actions"].slice(-1)[0]["type"] === "start"){ timeCell.classList.add("active") } else { timeCell.classList.remove("active") } let countCell = document.getElementById("count-" + watchIndex) countCell.textContent = countForWatch(actualTopic.watches[watchIndex]) + " Wortmeldungen" } function refreshClosedTopics() { let table = document.getElementById("closedTopicsTable") table.innerHTML = "" for(let i = closedTopics.length - 1; i >= 0; i--) { let topic = closedTopics[i] let topicColumn = elt("td") topicColumn.textContent = topic.name let time0 = elt("div") time0.textContent = timeToISO(sumForWatch(topic.watches[0])) + " (" + calcPercForWatch(0, topic) + "%)" let count0 = elt("div") count0.textContent = countForWatch(topic.watches[0]) + " Wortmeldungen (" + calcPercCountForWatch(0, topic) + "%)" let time0Column = elt("td", {}, time0, count0) let time1 = elt("div") time1.textContent = timeToISO(sumForWatch(topic.watches[1])) + " (" + calcPercForWatch(1, topic) + "%)" let count1 = elt("div") count1.textContent = ((topic.watches[1]["actions"].length) / 2) + " Wortmeldungen (" + calcPercCountForWatch(1, topic) + "%)" let time1Column = elt("td", {}, time1, count1) let time2 = elt("div") time2.textContent = timeToISO(sumForWatch(topic.watches[2])) + " (" + calcPercForWatch(2, topic) + "%)" let count2 = elt("div") count2.textContent = ((topic.watches[2]["actions"].length) / 2) + " Wortmeldungen (" + calcPercCountForWatch(2, topic) + "%)" let time2Column = elt("td", {}, time2, count2) let reopenButton = elt("button", {"onclick": "reopenTopic(" + i + ")"}) reopenButton.textContent = "wieder öffnen" let reopenButtonColumn = elt("td", {}, reopenButton) let deleteButton = elt("button", {"onclick": "buttonDeleteClosedTopic(" + i + ")"}) deleteButton.textContent = "löschen" let deleteButtonColumn = elt("td", {}, deleteButton) table.appendChild(elt("tr", {}, topicColumn, time0Column, time1Column, time2Column, reopenButtonColumn, deleteButtonColumn)) } } function saveActualTopicName() { actualTopic.name = document.getElementById("topicInput").value saveActualTopic() } function saveActualTopic() { //save it to LocalStorage localStorage.setItem("actualTopic", JSON.stringify(actualTopic)) //save it to Server fetch(document.URL + "dataCollector/dataCollector.php", { method: 'POST', headers: { 'Content-type': 'application/json' }, body: JSON.stringify({ "lastSave": new Date().getTime(), "timeWatchM": sumForWatch(actualTopic.watches[0]), "timeWatchW": sumForWatch(actualTopic.watches[1]), "timeWatchD": sumForWatch(actualTopic.watches[2]), "countWatchM": countForWatch(actualTopic.watches[0]), "countWatchW": countForWatch(actualTopic.watches[1]), "countWatchD": countForWatch(actualTopic.watches[2]), "id": actualTopic.id, "watches": actualTopic.watches }) }); } function saveClosedTopics() { localStorage.setItem("closedTopics", JSON.stringify(closedTopics)) } // Helper function for DOM manipulation // function elt (type, attrs, ...children) { let node = document.createElement(type) for (a in attrs) { node.setAttribute(a, attrs[a]) } for (let child of children) { if (typeof child != "string") node.appendChild(child) else node.appendChild(document.createTextNode(child)) } return node } // random.ts function randomId() { const uint32 = window.crypto.getRandomValues(new Uint32Array(1))[0]; return uint32.toString(16); }