Merge branch 'feature/ui-test' into 'develop'

Removed the "confirm alert" in the delete costume document function. It made...

See merge request proj-wise2526-video2document/video2document!102
This commit is contained in:
Spanier, Pit
2026-01-21 10:55:15 +01:00
9 changed files with 194 additions and 288 deletions
+76 -1
View File
@@ -4,7 +4,8 @@
1. [How to run the Software](#how-to-run-the-software) 1. [How to run the Software](#how-to-run-the-software)
2. [How it works](#how-it-works) 2. [How it works](#how-it-works)
3. [Modules](#modules) 3. [Modules](#modules)
3. [IPC](#ipc) 4. [IPC](#ipc)
5. [UI](#ui)
## How to run the Software ## How to run the Software
If you read the readme file, you will see the basic setup command in order to run the program. If you read the readme file, you will see the basic setup command in order to run the program.
@@ -114,3 +115,77 @@ The module names are each the name field specified in the module itself.
As for the rest of the fields, they are pretty self explanatory except `document.type`, that is a predefined report type. As for the rest of the fields, they are pretty self explanatory except `document.type`, that is a predefined report type.
This is the minimum required setup for the currently implemented pipeline to work. This is the minimum required setup for the currently implemented pipeline to work.
You can always add fields to it, but dont remove the ones from above. You can always add fields to it, but dont remove the ones from above.
## UI
The UI has a simple, self-explanatory design, in white and blue.
For easy handling and understanding, the UI is using 6 steps to guide the user through the process and offers a help page
with more defined explanations regarding the steps of the GUI. All parts used in the GUI are stored in the directory `./electron/main`.
Files used for the UI:
- index.html
- help_page.html
- style.css
- script.js
- renderer.js
- preload.js
- languages.js
- package-lock.json
- package.json
Folders used for the UI:
- /flags
- /icons
- /node_modules
**index.html:**
This file is the basic framework of our software. Comments in the code define the different UI sections.
The comments are the headlines of the code below them.
**help_page.html:**
This is the html to the help page that is accessible though the burger menu in the software.
Currently only available in german. It describes the different parts of the program in more depth.
**style.css:**
Contains all the css code of the software used in the UI.
**script.js:**
Stores all functions used in the UI.
The code is separated by comments in their matching UI section.
**renderer.js:**
Mainly contains every listener function used in the UI, which listens to any events occuring in the UI,
to handle these events as intended.
The code is separated by comments in their matching UI section.
**preload.js:**
Contains IPC functions to allow communication between the UI and the main process.
**languages.js:**
Holds one JSON, which is used to store the different language variables. These are used
in the script.js for the change of the displayed language of the UI. Add languages here, if
you want to add more options in the language selection.
How to add more languages:
1. Add another language block, like an existing one in the file. (Note: Use every key, which is also used in the other sections,
beside the first key like "eng". This first key should be always unique from the others)
2. Assign the desired values to the keys in the new language section.
How to add more text which changes languages:
1. Create the element in the html file with an unique id.
2. Add this id to every language section and assign them a matching value.
3. Add inside the `script.js` file, inside the `changeLanguage()` function a document call like the others. Except with our id.
**package-log.json:**
It's an electron module file. No changes needed.
**package.json:**
This is an electron base file. No changes needed.
**/flags:**
This directory contains the flags used for the language selection dropdown menu.
**/icons:**
Pictures for the document preview are stored here.
**/node_modules:**
Contains nodes used by electron.
-154
View File
@@ -1,154 +0,0 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Custom Document</title>
<style>
</style>
</head>
<body>
<div class="container">
<h1>Manage document types</h1>
<label for="existingDocs">Vorhandene Dokumententypen auswählen (optional):</label>
<!--Drop Down-->
<select name="existingDocs" id="existingDocs">
<option value="newDoc">-- Neuen Dokumententyp erstellen --</option>
</select>
<div id="docNameWrapper">
<label for="docName">Name des Dokumententyps:</label>
<input type="text" id="docName" placeholder="Gib hier den Namen für den Dokumententyp ein">
</div>
<label for="prompt">Dein Prompt:</label>
<textarea id="prompt" placeholder="Schreibe hier den Prompt für dein Dokumententyp..."></textarea>
<div class="buttons">
<a href="index.html">
<button id="goBackBtn">Abbrechen</button>
</a>
<button id="deleteBtn">Dokumententyp löschen</button>
<button id="generateBtn">Dokumententyp speichern</button>
</div>
<div id="result"></div>
</div>
<script src="languages.js"></script>
<script>
const goBackBtn = document.getElementById("goBackBtn");
const generateBtn = document.getElementById("generateBtn");
const deleteBtn = document.getElementById("deleteBtn");
const existingDocs = document.getElementById("existingDocs");
const docNameInput = document.getElementById("docName");
const promptInput = document.getElementById("prompt");
const resultDiv = document.getElementById("result");
const exampleText = "";
// dokumente speichern
generateBtn.addEventListener("click", () => {
const name = docNameInput.value.trim();
const content = promptInput.value.trim();
if (!name || !content) {
resultDiv.textContent = "Bitte Name des Dokumententyps und Prompt ausfüllen.";
setTimeout(() => {
resultDiv.textContent = "";
}, 3000);
return;
}
window.api.saveTxtFile(name, content).then();
resultDiv.textContent = "Dokumententyp erfolgreich gespeichert!";
setTimeout(() => {
resultDiv.textContent = "";
}, 3000);
reloadDocuments();
});
// dokumente löschen
deleteBtn.addEventListener("click", () => {
const name = docNameInput.value.trim();
if (!name) {
resultDiv.textContent = "Bitte Name des Dokumententyps angeben.";
setTimeout(() => {
resultDiv.textContent = "";
}, 3000);
return;
}
const confirmDelete = confirm(
`Möchtest du den Dokumententyp "${name}" wirklich löschen?`
);
if (!confirmDelete) return;
window.api.deleteTxtFile(name).then((success) => {
if (success) {
resultDiv.textContent = "Dokumententyp erfolgreich gelöscht!";
reloadDocuments();
existingDocs.value = "newDoc";
existingDocs.dispatchEvent(new Event("change"));
} else {
resultDiv.textContent = "Dokumententyp konnte nicht gelöscht werden.";
}
setTimeout(() => {
resultDiv.textContent = "";
}, 3000);
});
});
//function to load existingDoc options to the drop down list
const select = document.getElementById('existingDocs');
window.api.getTxtFiles().then(files => {
reloadDocuments();
});
//content anzeigen
const docNameWrapper = document.getElementById("docNameWrapper");
existingDocs.addEventListener("change", async () => {
const selected = existingDocs.value;
if (selected === "newDoc") {
docNameWrapper.classList.remove("hidden");
docNameInput.value = "";
promptInput.value = exampleText;
return;
}
docNameWrapper.classList.add("hidden");
const content = await window.api.readTxtFile(selected);
promptInput.value = content;
docNameInput.value = selected.replace(".txt", "");
});
//reload drop down
function reloadDocuments() {
[...existingDocs.querySelectorAll('option:not([value="newDoc"])')]
.forEach(o => o.remove());
window.api.getTxtFiles().then(files => {
files.forEach(file => {
const option = document.createElement('option');
option.value = file;
option.textContent = file
.replace('.txt', '') // Endung entfernen
.replace(/_/g, ' ') // Leerzeichen ersetzen
.replace(/\b\w/g, c => c.toUpperCase()) // ersten Buchstaben groß
existingDocs.appendChild(option);
});
});
}
</script>
</body>
</html>
+6 -6
View File
@@ -92,7 +92,7 @@
<!-- Here starts code from step 1--> <!-- Here starts code from step 1-->
<div class="step" id="step1"> <div class="step" id="step1">
<h2 class="h2">Upload your video here:</h2> <h2 class="h2" id="step1_h2">Upload your video here:</h2>
<div class="upload-container" id="uploadContainer"> <div class="upload-container" id="uploadContainer">
<p id="p1">Drag and drop video file</p> <p id="p1">Drag and drop video file</p>
<video id="previewThumbnail" autoplay="false"></video> <video id="previewThumbnail" autoplay="false"></video>
@@ -109,7 +109,7 @@
<!-- Here starts code from step 2--> <!-- Here starts code from step 2-->
<div class="step" id="step2" style="display: none"> <div class="step" id="step2" style="display: none">
<h2 class="h2">Choose your preferences:</h2> <h2 class="h2" id="step2_h2">Choose your preferences:</h2>
<div class="step2-form"> <div class="step2-form">
<div class="KI-wrapper"> <div class="KI-wrapper">
<label id="labelKI">Select ki:</label> <label id="labelKI">Select ki:</label>
@@ -146,7 +146,7 @@
<!-- Hover Effekt für Dokumentenvorschau, Fragezeichen hinter Text, drüber hoven zeigt Beispieldokument --> <!-- Hover Effekt für Dokumentenvorschau, Fragezeichen hinter Text, drüber hoven zeigt Beispieldokument -->
<div class="step" id="step3" style="display: none"> <div class="step" id="step3" style="display: none">
<div class="checkbox-group"> <div class="checkbox-group">
<h2 class="h2">Choose prefered document style:</h2> <h2 class="h2" id="step3_h2">Choose prefered document style:</h2>
<div class="checkbox-container"> <div class="checkbox-container">
<input <input
type="checkbox" type="checkbox"
@@ -241,7 +241,7 @@
<!-- Here starts code from step 4--> <!-- Here starts code from step 4-->
<div class="step" id="step4" style="display: none"> <div class="step" id="step4" style="display: none">
<h2 class="h2">Click to submit:</h2> <h2 class="h2" id="step4_h2">Click to submit:</h2>
<button <button
class="submit-btn" class="submit-btn"
id="submitButton" id="submitButton"
@@ -264,7 +264,7 @@
<!-- Here starts code from step 5--> <!-- Here starts code from step 5-->
<div class="step" id="step5" style="display: none"> <div class="step" id="step5" style="display: none">
<h2 class="h2">Change names of the speakers:</h2> <h2 class="h2" id="step5_h2">Change names of the speakers:</h2>
<div class="speaker-container"> <div class="speaker-container">
<table class="speaker-table"> <table class="speaker-table">
@@ -319,7 +319,7 @@
<!-- Here starts code from step 6--> <!-- Here starts code from step 6-->
<div class="step" id="step6" style="display: none"> <div class="step" id="step6" style="display: none">
<h2 class="h2">Click to download your document:</h2> <h2 class="h2" id="step6_h2">Click to download your document:</h2>
<button <button
class="download-btn" class="download-btn"
id="downloadButton" id="downloadButton"
+24 -3
View File
@@ -41,7 +41,14 @@ var languageOptions = {
"goBackBtn": "Return", "goBackBtn": "Return",
"deleteBtn": "Delete document", "deleteBtn": "Delete document",
"generateBtn": "Save document", "generateBtn": "Save document",
"newDoc": "-- Create new document --" "newDoc": "-- Create new document --",
"step1_h2" : "Upload your video here:",
"step2_h2" : "Choose your preferences:",
"step3_h2" : "Choose prefered document style:",
"step4_h2" : "Click to submit:",
"step5_h2" : "Change names of the speakers:",
"step6_h2" : "Click to download your document:"
}, },
"de":{ "de":{
@@ -86,7 +93,14 @@ var languageOptions = {
"goBackBtn": "Zurück", "goBackBtn": "Zurück",
"deleteBtn": "Lösche Dokument", "deleteBtn": "Lösche Dokument",
"generateBtn": "Speichere Dokument", "generateBtn": "Speichere Dokument",
"newDoc": "-- Neues Dokument erstellen --" "newDoc": "-- Neues Dokument erstellen --",
"step1_h2" : "Laden Sie Ihr Video hier hoch:",
"step2_h2" : "Wählen Sie Ihre Präferenzen:",
"step3_h2" : "Wählen Sie den gewünschten Dokumentstil:",
"step4_h2" : "Zum Absenden klicken:",
"step5_h2" : "Ändern Sie die Namen der Sprecher:",
"step6_h2" : "Klicken Sie hier, um Ihr Dokument herunterzuladen:"
}, },
"in":{ "in":{
"flagPath": "flags/india-flag-png-large.png", "flagPath": "flags/india-flag-png-large.png",
@@ -130,7 +144,14 @@ var languageOptions = {
"goBackBtn": "वापस जाएं", "goBackBtn": "वापस जाएं",
"deleteBtn": "दस्तावेज़ हटाएं", "deleteBtn": "दस्तावेज़ हटाएं",
"generateBtn": "दस्तावेज़ सहेजें", "generateBtn": "दस्तावेज़ सहेजें",
"newDoc": "-- नया दस्तावेज़ बनाएं --" "newDoc": "-- नया दस्तावेज़ बनाएं --",
"step1_h2" : "अपना वीडियो यहां अपलोड करें:",
"step2_h2" : "अपनी प्राथमिकताएँ चुनें:",
"step3_h2" : "पसंदीदा दस्तावेज़ शैली चुनें:",
"step4_h2" : "सबमिट करने के लिए क्लिक करें:",
"step5_h2" : "वक्ताओं के नाम बदलें:",
"step6_h2" : "अपना दस्तावेज़ डाउनलोड करने के लिए यहां क्लिक करें:"
} }
-44
View File
@@ -1,44 +0,0 @@
import { app, BrowserWindow, ipcMain, dialog } from 'electron';
import { exec } from 'child_process';
import path from 'path';
import { fileURLToPath } from 'url';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
let mainWindow;
function createWindow() {
mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: false,
contextIsolation: true,
preload: path.join(__dirname, 'preload.js')
}
});
mainWindow.loadFile('main/index.html');
}
app.whenReady().then(createWindow);
// Kommunikation vom Renderer (Frontend)
ipcMain.handle('convert-video', async (event, filePath) => {
const output = path.join(path.dirname(filePath), 'converted.mp4');
return new Promise((resolve, reject) => {
exec(`ffmpeg -i "${filePath}" -vcodec libx264 "${output}"`, (error, stdout, stderr) => {
if (error) {
console.error('Fehler beim Konvertieren:', error);
reject(error);
} else {
console.log('Konvertierung abgeschlossen:', output);
resolve(output);
}
});
});
});
+21 -33
View File
@@ -133,22 +133,7 @@ Listeners for Step 3
*/ */
window.api.getTxtFiles().then(files => {
var menu = document.getElementById('customDocumentTypes');
var l = document.getElementById('customDocumentTypes').options.length - 1;
for (i = l; i >= 0; i--) {
menu.remove(i);
}
files.forEach(file => {
const option = document.createElement('option');
option.value = file;
option.textContent = file
.replace('.txt', '') // Endung entfernen
.replace(/_/g, ' ') // Leerzeichen ersetzen
.replace(/\b\w/g, c => c.toUpperCase()) // ersten Buchstaben groß
menu.appendChild(option);
});
});
//Checkboxlistener so that only one can be selected at a time //Checkboxlistener so that only one can be selected at a time
docFormat.addEventListener("change", (e) => { docFormat.addEventListener("change", (e) => {
@@ -315,7 +300,6 @@ generateBtn.addEventListener("click", () => {
const content = document.getElementById("prompt").value.trim(); const content = document.getElementById("prompt").value.trim();
if (!name || !content) { if (!name || !content) {
result.textContent = "Bitte Dokumentname und Prompt ausfüllen."; result.textContent = "Bitte Dokumentname und Prompt ausfüllen.";
console.log(name + " " + content);
setTimeout(() => { setTimeout(() => {
result.textContent = ""; result.textContent = "";
}, 3000); }, 3000);
@@ -332,6 +316,7 @@ generateBtn.addEventListener("click", () => {
// dokumente löschen // dokumente löschen
deleteBtn.addEventListener("click", () => { deleteBtn.addEventListener("click", () => {
try {
const name = docName.value.trim(); const name = docName.value.trim();
if (!name) { if (!name) {
@@ -341,51 +326,54 @@ deleteBtn.addEventListener("click", () => {
}, 3000); }, 3000);
return; return;
} }
var success = true;
const confirmDelete = confirm(
`Möchtest du das Dokument "${name}" wirklich löschen?`
);
if (!confirmDelete) return;
window.api.deleteTxtFile(name).then((success) => { window.api.deleteTxtFile(name).then((success) => {
if (success) { if (success) {
result.textContent = "Dokument erfolgreich gelöscht!"; result.textContent = "Dokument erfolgreich gelöscht!";
reloadDocuments(); reloadDocuments();
existingDocs.value = "newDoc";
existingDocs.dispatchEvent(new Event("change")); existingDocs.dispatchEvent(new Event("change"));
} else { } else {
result.textContent = "Dokument konnte nicht gelöscht werden."; result.textContent = "Dokument konnte nicht gelöscht werden.";
} }
setTimeout(() => {
result.textContent = "";
}, 3000);
}); });
} catch (error) {
console.log(error)
}
}); });
//function to load existingDoc options to the drop down list //function to load existingDoc options to the drop down list
window.api.getTxtFiles().then(files => { window.api.getTxtFiles().then(files => {
try {
reloadDocuments(); reloadDocuments();
} catch (error) {
console.log(error)
}
}); });
//content anzeigen //content anzeigen
existingDocs.addEventListener("change", async () => { existingDocs.addEventListener("change", async () => {
try {
const existingDocsed = existingDocs.value; const existingDocsed = existingDocs.value;
const exampleText = ""; const exampleText = "";
if (existingDocsed === "newDoc") { if (existingDocsed === "newDoc") {
docNameWrapper.classList.remove("hidden"); docNameWrapper.classList.remove("hidden");
docName.value = ""; docName.value = "";
prompt.value = exampleText; document.getElementById("prompt").value = exampleText;
document.getElementById("prompt").textContent = exampleText;
return; return;
} }
docNameWrapper.classList.add("hidden"); docNameWrapper.classList.add("hidden");
document.getElementById("prompt").textContent = "";
document.getElementById("prompt").value = "";
const content = await window.api.readTxtFile(existingDocsed); const content = await window.api.readTxtFile(existingDocsed);
prompt.value = content; document.getElementById("prompt").value = content;
document.getElementById("prompt").textContent = content;
docName.value = existingDocsed.replace(".txt", ""); docName.value = existingDocsed.replace(".txt", "");
} catch (error) {
console.log(error)
}
}); });
+30 -9
View File
@@ -27,12 +27,11 @@ function showCD() {
//language changing feature => changes the language of every displayed text //language changing feature => changes the language of every displayed text
function changeLanguage(language) { function changeLanguage(language) {
try { try {
//document.getElementById('labelLanguageFlag').src = languageOptions[language].flagPath;
document.getElementById('labelKI').textContent = languageOptions[language].labelKI; document.getElementById('labelKI').textContent = languageOptions[language].labelKI;
document.getElementById('labelTranscription').textContent = languageOptions[language].labelTranscription; document.getElementById('labelTranscription').textContent = languageOptions[language].labelTranscription;
document.getElementById('labelLanguage').textContent = languageOptions[language].labelLanguage; document.getElementById('labelLanguage').textContent = languageOptions[language].labelLanguage;
document.getElementById('title').textContent = languageOptions[language].title; document.getElementById('title').textContent = languageOptions[language].title;
//document.getElementById('h1').textContent = languageOptions[language].h1; document.getElementById('h1').textContent = languageOptions[language].h1;
document.getElementById('p1').textContent = languageOptions[language].p1; document.getElementById('p1').textContent = languageOptions[language].p1;
document.getElementById('fileName').textContent = languageOptions[language].fileName; document.getElementById('fileName').textContent = languageOptions[language].fileName;
document.getElementById('manualUploadBtn').textContent = languageOptions[language].manualUploadBtn; document.getElementById('manualUploadBtn').textContent = languageOptions[language].manualUploadBtn;
@@ -45,7 +44,6 @@ function changeLanguage(language) {
document.getElementById('step_nav4').textContent = languageOptions[language].step_nav4; document.getElementById('step_nav4').textContent = languageOptions[language].step_nav4;
document.getElementById('step_nav5').textContent = languageOptions[language].step_nav5; document.getElementById('step_nav5').textContent = languageOptions[language].step_nav5;
document.getElementById('step_nav6').textContent = languageOptions[language].step_nav6; document.getElementById('step_nav6').textContent = languageOptions[language].step_nav6;
//document.getElementById('h2').textContent = languageOptions[language].h2;
document.getElementById('labelSpeaker').textContent = languageOptions[language].labelSpeaker; document.getElementById('labelSpeaker').textContent = languageOptions[language].labelSpeaker;
document.getElementById('labelSpeakerAudio').textContent = languageOptions[language].labelSpeakerAudio; document.getElementById('labelSpeakerAudio').textContent = languageOptions[language].labelSpeakerAudio;
document.getElementById('labelSpeakerWriter').textContent = languageOptions[language].labelSpeakerWriter; document.getElementById('labelSpeakerWriter').textContent = languageOptions[language].labelSpeakerWriter;
@@ -69,6 +67,13 @@ function changeLanguage(language) {
document.getElementById('generateBtn').textContent = languageOptions[language].generateBtn; document.getElementById('generateBtn').textContent = languageOptions[language].generateBtn;
document.getElementById('newDoc').textContent = languageOptions[language].newDoc; document.getElementById('newDoc').textContent = languageOptions[language].newDoc;
document.getElementById("step1_h2").textContent = languageOptions[language].step1_h2;
document.getElementById("step2_h2").textContent = languageOptions[language].step2_h2;
document.getElementById("step3_h2").textContent = languageOptions[language].step3_h2;
document.getElementById("step4_h2").textContent = languageOptions[language].step4_h2;
document.getElementById("step5_h2").textContent = languageOptions[language].step5_h2;
document.getElementById("step6_h2").textContent = languageOptions[language].step6_h2;
} catch (error) { } catch (error) {
console.log("Error in script.js changeLanguage function"); console.log("Error in script.js changeLanguage function");
console.log(error); console.log(error);
@@ -89,6 +94,10 @@ let currentStep = 1;
const totalSteps = steps.length; const totalSteps = steps.length;
function showStep(stepNumber) { function showStep(stepNumber) {
if(showCDValue == 1){
showCDValue = 0;
document.getElementById('cdContainer').style.display = "none";
}
if (stepNumber < 1 || stepNumber > totalSteps) { if (stepNumber < 1 || stepNumber > totalSteps) {
console.error("StepNumber out of Bounds", stepNumber); console.error("StepNumber out of Bounds", stepNumber);
return; return;
@@ -473,10 +482,6 @@ function fileDownload() {
} }
} }
/* /*
Functions for the custom document section Functions for the custom document section
@@ -485,21 +490,37 @@ Functions for the custom document section
//reload drop down //reload drop down
function reloadDocuments() { function reloadDocuments() {
try{
[...existingDocs.querySelectorAll('option:not([value="newDoc"])')] [...existingDocs.querySelectorAll('option:not([value="newDoc"])')]
.forEach(o => o.remove()); .forEach(o => o.remove());
[...customDocumentTypes.querySelectorAll('option:not([value="newDoc"])')]
.forEach(o => o.remove());
window.api.getTxtFiles().then(files => { window.api.getTxtFiles().then(files => {
files.forEach(file => { files.forEach(file => {
const option = document.createElement('option'); var option = document.createElement('option');
option.value = file; option.value = file;
option.textContent = file option.textContent = file
.replace('.txt', '') // Endung entfernen .replace('.txt', '') // Endung entfernen
.replace(/_/g, ' ') // Leerzeichen ersetzen .replace(/_/g, ' ') // Leerzeichen ersetzen
.replace(/\b\w/g, c => c.toUpperCase()) // ersten Buchstaben groß .replace(/\b\w/g, c => c.toUpperCase()); // ersten Buchstaben groß
existingDocs.appendChild(option); existingDocs.appendChild(option);
var option2 = document.createElement('option');
option2.value = file;
option2.name = file;
option2.textContent = file
.replace('.txt', '') // Endung entfernen
.replace(/_/g, ' ') // Leerzeichen ersetzen
.replace(/\b\w/g, c => c.toUpperCase()); // ersten Buchstaben groß
customDocumentTypes.appendChild(option2);
}); });
}); });
} }
catch(error){
console.log(error)
}
}
function sendSpeakerPackages() { function sendSpeakerPackages() {
try { try {
-1
View File
@@ -495,7 +495,6 @@ li {
} }
.p-menu1 { .p-menu1 {
margin-left: 20px;
z-index: 10; z-index: 10;
} }
View File