Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhance LogCard.vue with log file selection and clipboard copy functionality #612

Open
wants to merge 12 commits into
base: main
Choose a base branch
from
13 changes: 12 additions & 1 deletion src/components/OpenwbBaseCard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -97,22 +97,33 @@ export default {
collapsible: { type: Boolean, default: false },
collapsed: { type: Boolean, default: false },
},
emits: ["collapsed", "expanded"],
data() {
return {
isCollapsed: this.collapsible && this.collapsed,
};
},
watch: {
collapsed(newVal) {
this.isCollapsed = newVal;
},
},
methods: {
toggleBody() {
if (this.collapsible === true) {
this.isCollapsed = !this.isCollapsed;
}
if (this.isCollapsed) {
this.$emit("collapsed");
} else {
this.$emit("expanded");
}
},
},
};
</script>

<style>
<style scoped>
.card {
margin-bottom: 1rem;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
Expand Down
135 changes: 127 additions & 8 deletions src/components/debug_config/LogCard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,54 @@
class="log-card"
:collapsible="true"
:collapsed="true"
@expanded="onCardExpand"
>
<template #actions>
<openwb-base-avatar
class="bg-success clickable"
@click.stop="loadLog(logFile)"
@click.stop="loadLog(logFile, selectedVariant)"
>
<font-awesome-icon
fixed-width
:class="loading ? 'fa-spin-pulse' : ''"
:icon="loading ? ['fas', 'spinner'] : ['fas', 'file-download']"
title="Log laden/aktualisieren"
/>
</openwb-base-avatar>
</template>
<openwb-base-alert
v-if="foundFiles.length > 0"
subtype="info"
>
Im {{ title }} stehen unterschiedliche Logauszüge zur Verfügung. Standardmässig werden Logs des letzten Durchlaufs
geladen, für viele Fälle sollte dies ausreichen. Optional kann auch das gesamte Log geladen werden.<br />
Wurde eine Warnung oder ein Fehler protokolliert steht zusätzlich der letzte Durchlauf mit Warnungen und Fehlern
zur Verfügung.<br />
<openwb-base-select-input
v-model="selectedVariant"
title="Logfile"
required
:options="foundFiles.map((file) => ({ value: file.suffix, text: file.title }))"
@change="loadLog(logFile, selectedVariant)"
/>
</openwb-base-alert>

<div
v-if="!copyMessage"
class="text-right"
>
<a
href="#"
@click.prevent="copyToClipboard"
>Kopiere Log in die Zwischenablage</a
>
</div>
<div
v-if="copyMessage"
class="copy-message text-right"
>
Logs in die Zwischenablage kopiert.
</div>
<pre class="log-data mb-0">{{ logData }}</pre>
</openwb-base-card>
</template>
Expand Down Expand Up @@ -47,22 +82,34 @@ export default {
return {
logData: "-- noch nicht geladen --",
loading: false,
foundFiles: [], // Array to store found files with title, suffix, and description
selectedVariant: "", // Selected file variant
copyMessage: false, // Flag to show copy message
};
},
methods: {
async getFilePromise(myFile, ignore404 = false) {
return this.axios
.get(location.protocol + "//" + location.host + myFile)
async getFilePromise(myFile, ignore404 = false, handleError = true, useHead = false) {
const requestMethod = useHead ? "head" : "get";
return this.axios[requestMethod](location.protocol + "//" + location.host + myFile)
.then((response) => {
return response.data;
if (useHead) {
// If the request is successful, the file exists
return true;
} else {
const data = response.data;
return data ? data : "log file is empty";
}
})
.catch((error) => {
if (!handleError) {
throw error;
}
if (error.response) {
// The request was made and the server responded with a status code
// The request was made but the server responded with a status code
// that falls out of the range of 2xx
if (error.response.status == 404 && ignore404) {
// ignore a 404 if requested, used for rotated log files which may not exist yet
return "";
return useHead ? false : "";
}
return (
"A 404 is expected if running node.js dev server!\n" +
Expand All @@ -83,10 +130,13 @@ export default {
}
});
},
async loadLog(fileName) {
async loadLog(fileName, fileNameVariant = "") {
this.logData = "wird aktualisiert...";
this.loading = true;
var logContents = "";
if (fileNameVariant) {
fileName = fileName.replace(".log", `.${fileNameVariant}.log`);
}

for (let i = 4; i >= 1; i--) {
const result = await this.getFilePromise(fileName + "." + i, true);
Expand All @@ -99,6 +149,75 @@ export default {
this.logData = logContents;
this.loading = false;
},
async checkLatestLog(fileName) {
// Define file name variations
const fileVariations = [
{ suffix: "latest", title: "Letzter Durchlauf", description: "Logs des Letzten Durchlauf laden" },
{
suffix: "latest-warning",
title: "Letzter Durchlauf mit Warnung oder Fehler",
description: "Fehlerprotokoll laden",
},
// Add more variations as needed
];
// Check for the existence of the .latest log file
this.foundFiles = [];
for (const variation of fileVariations) {
const variantFileName = fileName.replace(".log", `.${variation.suffix}.log`);
try {
await this.getFilePromise(variantFileName, false, false, true);
this.foundFiles.push(variation);
if (variation.suffix === "latest") {
this.selectedVariant = "latest";
console.log("Found latest log file: ", variantFileName);
}
} catch (error) {
console.log(error);
}
}
if (this.foundFiles.length > 0) {
this.foundFiles.push({
suffix: "",
title: "Vollständiges Log",
description: "Vollständiges Log laden",
});
}
},
async onCardExpand() {
await this.checkLatestLog(this.logFile);
this.loadLog(this.logFile, this.selectedVariant);
},
copyToClipboard() {
if (navigator.clipboard && navigator.clipboard.writeText) {
navigator.clipboard
.writeText(this.logData)
.then(() => {
this.showCopyMessage();
})
.catch((err) => {
console.error("Fehler beim Kopieren in die Zwischenablage: ", err);
});
} else {
// Fallback method for older browsers and non-HTTPS contexts
const textArea = document.createElement("textarea");
textArea.value = this.logData;
document.body.appendChild(textArea);
textArea.select();
try {
document.execCommand("copy");
this.showCopyMessage();
} catch (err) {
console.error("Fehler beim Kopieren in die Zwischenablage: ", err);
}
document.body.removeChild(textArea);
}
},
showCopyMessage() {
this.copyMessage = true;
setTimeout(() => {
this.copyMessage = false;
}, 3000); // Message disappears after 3 seconds
},
},
};
</script>
Expand Down
Loading