From b7755949c846a86a34d61d1c29f4e21cc2dfe489 Mon Sep 17 00:00:00 2001 From: Samuel Zielke Date: Thu, 12 Sep 2024 02:30:27 +0200 Subject: [PATCH] =?UTF-8?q?Create=20IndexDB=20and=20add=20NewEntryWindow?= =?UTF-8?q?=20with=20func=20&&=20Show=20Data=20of=20month=20in=20Aktivit?= =?UTF-8?q?=C3=A4ten?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/static/app/js/dbcontrol.js | 204 +++++++++++++++++++++ app/static/app/js/serviceworker.js | 1 + app/templates/app/base.html | 5 +- app/templates/app/home.html | 280 +++++++++++++++++++++++++---- 4 files changed, 454 insertions(+), 36 deletions(-) create mode 100644 app/static/app/js/dbcontrol.js diff --git a/app/static/app/js/dbcontrol.js b/app/static/app/js/dbcontrol.js new file mode 100644 index 0000000..7bf886d --- /dev/null +++ b/app/static/app/js/dbcontrol.js @@ -0,0 +1,204 @@ +// IndexedDB Funktionen +const dbName = 'myDB'; +const dbVersion = 1; +let db; + +// IndexedDB initialisieren +function initDB() { + return new Promise((resolve, reject) => { + const request = indexedDB.open(dbName, dbVersion); + + request.onupgradeneeded = function (event) { + db = event.target.result; + const store = db.createObjectStore('hours', { + keyPath: 'id', + autoIncrement: true, + }); + + // Spalten definieren + store.createIndex('createdate', 'createdate', { unique: false }); + store.createIndex('date', 'date', { unique: false }); + store.createIndex('duration', 'duration', { unique: false }); + store.createIndex('type', 'type', { unique: false }); + store.createIndex('status', 'status', { unique: false }); + store.createIndex('sondertext', 'sondertext', { unique: false }); + }; + + request.onsuccess = function (event) { + db = event.target.result; + resolve(db); + }; + + request.onerror = function (event) { + console.error('IndexedDB Fehler:', event.target.errorCode); + reject(event.target.errorCode); + }; + }); +} + +// Neuer Eintrag in die IndexedDB +function addEntry(data) { + return new Promise((resolve, reject) => { + const transaction = db.transaction(['hours'], 'readwrite'); + const store = transaction.objectStore('hours'); + + data.createdate = new Date(); + const request = store.add(data); + + request.onsuccess = function () { + resolve(request.result); + }; + + request.onerror = function (event) { + reject('Fehler beim Hinzufügen des Eintrags:', event.target.error); + }; + }); +} + +// Eintrag aktualisieren +function updateEntry(id, updatedData) { + return new Promise((resolve, reject) => { + const transaction = db.transaction(['hours'], 'readwrite'); + const store = transaction.objectStore('hours'); + + const getRequest = store.get(id); + + getRequest.onsuccess = function (event) { + const data = event.target.result; + Object.assign(data, updatedData); + data.createdate = new Date(); // Aktualisiere das Änderungsdatum + + const updateRequest = store.put(data); + + updateRequest.onsuccess = function () { + resolve(data); + }; + + updateRequest.onerror = function (event) { + reject('Fehler beim Aktualisieren des Eintrags:', event.target.error); + }; + }; + + getRequest.onerror = function (event) { + reject('Fehler beim Abrufen des Eintrags:', event.target.error); + }; + }); +} + +// Eintrag löschen +function deleteEntry(id) { + return new Promise((resolve, reject) => { + const transaction = db.transaction(['hours'], 'readwrite'); + const store = transaction.objectStore('hours'); + + const request = store.delete(id); + + request.onsuccess = function () { + resolve(`Eintrag mit ID ${id} gelöscht.`); + }; + + request.onerror = function (event) { + reject('Fehler beim Löschen des Eintrags:', event.target.error); + }; + }); +} + +// Einträge abrufen +function getAllEntries() { + return new Promise((resolve, reject) => { + const transaction = db.transaction(['hours'], 'readonly'); + const store = transaction.objectStore('hours'); + + const request = store.getAll(); + + request.onsuccess = function () { + resolve(request.result); + }; + + request.onerror = function (event) { + reject('Fehler beim Abrufen der Einträge:', event.target.error); + }; + }); +} + +// Einträge nach Monat und/oder Jahr filtern +function filterEntriesByMonthYear(month, year) { + return new Promise((resolve, reject) => { + const transaction = db.transaction(['hours'], 'readonly'); + const store = transaction.objectStore('hours'); + + const request = store.getAll(); + + request.onsuccess = function () { + const allEntries = request.result; + + // Filter nach Monat und Jahr + const filteredEntries = allEntries.filter(entry => { + const entryDate = new Date(entry.date); // Konvertiere das date-Feld in ein Date-Objekt + + const matchesMonth = month ? entryDate.getMonth() + 1 === month : true; // +1 da getMonth() 0-basiert ist + const matchesYear = year ? entryDate.getFullYear() === year : true; + + return matchesMonth && matchesYear; + }); + + resolve(filteredEntries); + }; + + request.onerror = function (event) { + reject('Fehler beim Abrufen der Einträge:', event.target.error); + }; + }); +} + +// Neuen Eintrag verschlüsselt speichern +async function addEncryptedEntry(data) { + const key = await generateKey(); + const { iv, encryptedData } = await encryptData(key, JSON.stringify(data)); + + return new Promise((resolve, reject) => { + const transaction = db.transaction(['hours'], 'readwrite'); + const store = transaction.objectStore('hours'); + + const request = store.add({ + iv: Array.from(iv), // IV muss auch gespeichert werden + encryptedData: Array.from(new Uint8Array(encryptedData)), // Encrypted data als Uint8Array speichern + }); + + request.onsuccess = function () { + resolve(request.result); + }; + + request.onerror = function (event) { + reject('Fehler beim Hinzufügen des verschlüsselten Eintrags:', event.target.error); + }; + }); +} + +// Verschlüsselten Eintrag entschlüsseln +async function getDecryptedEntry(id) { + const key = await generateKey(); + + return new Promise((resolve, reject) => { + const transaction = db.transaction(['hours'], 'readonly'); + const store = transaction.objectStore('hours'); + + const request = store.get(id); + + request.onsuccess = async function () { + const entry = request.result; + if (entry) { + const iv = new Uint8Array(entry.iv); + const encryptedData = new Uint8Array(entry.encryptedData); + const decryptedData = await decryptData(key, iv, encryptedData); + resolve(JSON.parse(decryptedData)); + } else { + reject('Eintrag nicht gefunden'); + } + }; + + request.onerror = function (event) { + reject('Fehler beim Abrufen des verschlüsselten Eintrags:', event.target.error); + }; +}); +} \ No newline at end of file diff --git a/app/static/app/js/serviceworker.js b/app/static/app/js/serviceworker.js index 59f8a35..7731fb1 100644 --- a/app/static/app/js/serviceworker.js +++ b/app/static/app/js/serviceworker.js @@ -13,6 +13,7 @@ var filesToCache = [ // ) // }); + // Clear cache on activate self.addEventListener('activate', event => { event.waitUntil( diff --git a/app/templates/app/base.html b/app/templates/app/base.html index b386503..f04938b 100644 --- a/app/templates/app/base.html +++ b/app/templates/app/base.html @@ -8,6 +8,7 @@ + {% progressive_web_app_meta %} @@ -39,10 +40,6 @@ Dauer-Hippi -
  • - Stunden-Schnitt berechnung - -
  • Account