Skip to content
Merged
28 changes: 3 additions & 25 deletions frontend/src/components/logging/detailed-logs/DetailedLogs.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 }) => {
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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}/`);
Expand Down Expand Up @@ -490,7 +468,7 @@ const DetailedLogs = () => {
<Button
className="copy-btn-outlined"
icon={<CopyOutlined />}
onClick={() => handleCopyToClipboard(id, "Execution ID")}
onClick={() => copyToClipboard(id, "Execution ID")}
/>
</Typography.Title>
<LogsRefreshControls
Expand Down
25 changes: 22 additions & 3 deletions frontend/src/components/logging/log-modal/LogModal.css
Original file line number Diff line number Diff line change
@@ -1,4 +1,23 @@
.clear-button{
margin-left: 50px;
margin-top: 10px;
.clear-button {
margin-left: 50px;
margin-top: 10px;
}

.log-modal-title {
display: inline-flex;
align-items: center;
}

.log-modal-title .copy-btn-outlined {
border: 1px solid #d9d9d9;
background: #fff;
color: rgba(0, 0, 0, 0.65);
margin-left: 8px;
height: auto;
min-width: auto;
}

.log-modal-title .copy-btn-outlined:hover {
border-color: #1677ff;
color: #1677ff;
}
20 changes: 18 additions & 2 deletions frontend/src/components/logging/log-modal/LogModal.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Modal, Table, Tooltip } from "antd";
import { Button, Modal, Table, Tooltip } from "antd";
import { useEffect, useState } from "react";
import PropTypes from "prop-types";
import { CopyOutlined } from "@ant-design/icons";

import "./LogModal.css";
import { useExceptionHandler } from "../../../hooks/useExceptionHandler";
Expand All @@ -12,6 +13,7 @@ import {
} from "../../../helpers/GetStaticData";
import { FilterDropdown, FilterIcon } from "../filter-dropdown/FilterDropdown";
import useRequestUrl from "../../../hooks/useRequestUrl";
import { useCopyToClipboard } from "../../../hooks/useCopyToClipboard";

function LogModal({
executionId,
Expand All @@ -24,6 +26,8 @@ function LogModal({
const { setAlertDetails } = useAlertStore();
const handleException = useExceptionHandler();
const { getUrl } = useRequestUrl();
const copyToClipboard = useCopyToClipboard();
const displayId = fileId || executionId;

const [executionLogs, setExecutionLogs] = useState([]);
const [loading, setLoading] = useState(false);
Expand Down Expand Up @@ -150,7 +154,19 @@ function LogModal({
}, [logDescModalOpen, pagination.current, selectedLogLevel, ordering]);
return (
<Modal
title={`Execution Log Details - ${fileId || executionId}`}
title={
<span className="log-modal-title">
File Execution ID {displayId}
{displayId && (
<Button
className="copy-btn-outlined"
icon={<CopyOutlined />}
aria-label="Copy execution ID"
onClick={() => copyToClipboard(displayId, "File Execution ID")}
/>
)}
</span>
Comment thread
coderabbitai[bot] marked this conversation as resolved.
}
centered
open={logDescModalOpen}
onCancel={handleClose}
Expand Down
33 changes: 33 additions & 0 deletions frontend/src/hooks/useCopyToClipboard.js
Original file line number Diff line number Diff line change
@@ -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 };