diff --git a/frontend/src/components/logging/detailed-logs/DetailedLogs.jsx b/frontend/src/components/logging/detailed-logs/DetailedLogs.jsx
index 0c89b2afeb..3a59f84558 100644
--- a/frontend/src/components/logging/detailed-logs/DetailedLogs.jsx
+++ b/frontend/src/components/logging/detailed-logs/DetailedLogs.jsx
@@ -39,6 +39,7 @@ import { LogModal } from "../log-modal/LogModal";
import { FilterIcon } from "../filter-dropdown/FilterDropdown";
import { LogsRefreshControls } from "../logs-refresh-controls/LogsRefreshControls";
import useRequestUrl from "../../../hooks/useRequestUrl";
+import { useCopyToClipboard } from "../../../hooks/useCopyToClipboard";
// Component for status message with conditional tooltip (only when truncated)
const StatusMessageCell = ({ text }) => {
@@ -95,6 +96,7 @@ const DetailedLogs = () => {
const handleException = useExceptionHandler();
const navigate = useNavigate();
const { getUrl } = useRequestUrl();
+ const copyToClipboard = useCopyToClipboard();
const [executionDetails, setExecutionDetails] = useState();
const [executionFiles, setExecutionFiles] = useState();
@@ -122,30 +124,6 @@ const DetailedLogs = () => {
executionDetails?.status &&
TERMINAL_STATES.includes(executionDetails.status.toUpperCase());
- const handleCopyToClipboard = (text, label = "Text") => {
- if (!navigator.clipboard) {
- setAlertDetails({
- type: "error",
- content: "Clipboard not available in this browser",
- });
- return;
- }
- navigator.clipboard.writeText(text).then(
- () => {
- setAlertDetails({
- type: "success",
- content: `${label} copied to clipboard`,
- });
- },
- (err) => {
- setAlertDetails({
- type: "error",
- content: `Failed to copy: ${err.message || "Unknown error"}`,
- });
- }
- );
- };
-
const fetchExecutionDetails = async (id) => {
try {
const url = getUrl(`/execution/${id}/`);
@@ -490,7 +468,7 @@ const DetailedLogs = () => {
}
- onClick={() => handleCopyToClipboard(id, "Execution ID")}
+ onClick={() => copyToClipboard(id, "Execution ID")}
/>
+ File Execution ID {displayId}
+ {displayId && (
+ }
+ aria-label="Copy execution ID"
+ onClick={() => copyToClipboard(displayId, "File Execution ID")}
+ />
+ )}
+
+ }
centered
open={logDescModalOpen}
onCancel={handleClose}
diff --git a/frontend/src/hooks/useCopyToClipboard.js b/frontend/src/hooks/useCopyToClipboard.js
new file mode 100644
index 0000000000..8c68e3954d
--- /dev/null
+++ b/frontend/src/hooks/useCopyToClipboard.js
@@ -0,0 +1,33 @@
+import { useAlertStore } from "../store/alert-store";
+
+function useCopyToClipboard() {
+ const { setAlertDetails } = useAlertStore();
+
+ const copyToClipboard = (text, label = "Text") => {
+ if (!navigator.clipboard) {
+ setAlertDetails({
+ type: "error",
+ content: "Clipboard not available in this browser",
+ });
+ return;
+ }
+ navigator.clipboard.writeText(text).then(
+ () => {
+ setAlertDetails({
+ type: "success",
+ content: `${label} copied to clipboard`,
+ });
+ },
+ (err) => {
+ setAlertDetails({
+ type: "error",
+ content: `Failed to copy: ${err.message || "Unknown error"}`,
+ });
+ }
+ );
+ };
+
+ return copyToClipboard;
+}
+
+export { useCopyToClipboard };