Skip to content

Conversation

@himaniraghav3
Copy link
Collaborator

Related JIRA Ticket:

https://topcoder.atlassian.net/browse/PM-2179

What's in this PR?

image

// const isTablet = useMemo(() => screenWidth <= 1000, [screenWidth])
const { workflowId, workflowRun }: ReviewsContextModel = useReviewsContext()
const { artifacts }: AiWorkflowRunAttachmentsResponse
= useFetchAiWorkflowsRunAttachments(workflowId, workflowRun?.id)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[⚠️ correctness]
Consider adding error handling for the useFetchAiWorkflowsRunAttachments hook to manage cases where the fetch might fail. This will improve the robustness of the component.


const handleDownload = useCallback(
async (artifactId: number): Promise<void> => {
await download(artifactId)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[⚠️ correctness]
The handleDownload function should include error handling to manage potential failures during the download process. This will ensure that the user is informed if something goes wrong.

className,
'enhanced-table',
)}
>

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[💡 design]
Consider adding a loading state or indicator while the attachments are being fetched. This will enhance the user experience by providing feedback that the data is being loaded.

* converts size_in_bytes into KB / MB / GB with correct formatting.
*/
export const formatFileSize = (bytes: number): string => {
if (!bytes || bytes < 0) return '0 B'

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[❗❗ correctness]
The check !bytes will return true for 0, which is not a negative value. Consider changing the condition to bytes <= 0 to handle only negative values and zero correctly.

>(
`${TC_API_BASE_URL}/workflows/${workflowId}/runs/${runId}/attachments`,
{
isPaused: () => !workflowId || !runId,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[⚠️ correctness]
The isPaused option in the useSWR hook is used to conditionally pause the request. However, the current logic will not pause if workflowId or runId is an empty string. Consider using !workflowId?.trim() || !runId?.trim() to ensure that empty strings also pause the request.

const [isDownloading, setIsDownloading] = useState(false)

const download = async (artifactId: number): Promise<void> => {
if (!workflowId || !runId || !artifactId) return

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[❗❗ correctness]
The check if (!workflowId || !runId || !artifactId) return does not handle the case where artifactId is zero, which is a valid number. Consider using artifactId == null to check for null or undefined values.

} catch (err) {
handleError(err as Error)
} finally {
setIsDownloading(false)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[❗❗ correctness]
The setIsDownloading(false) call in the finally block will execute after the asynchronous xhrGetBlobAsync call, potentially setting isDownloading to false before the download completes. Consider moving setIsDownloading(false) inside the .then and .catch blocks to ensure it reflects the actual download state.

@import '@libs/ui/styles/includes';

.container {
min-height: calc($content-height - 250px);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[⚠️ maintainability]
The use of a hardcoded value (250px) in the min-height calculation could lead to maintainability issues. Consider defining this value as a variable or constant to improve flexibility and ease of updates.

Copy link
Collaborator

@kkartunov kkartunov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@himaniraghav3 very good work!
Minor observation shared below.
Please also add attachments count to the tab heading and make sure it behaves on mobile.


const url = `${TC_API_BASE_URL}/workflows/${workflowId}/runs/${runId}/attachments/${artifactId}/zip`

xhrGetBlobAsync<Blob>(url)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@himaniraghav3 please conver to async/await type of code block. In general, we have to avoid mixing .then/.catch with async/await. The function is async so we should await. This will also ensure we do not end up with unhandled promises as noted for line 238.

[styles.expired]: isExpired,
[styles.downloading]: downloading,
})}
onClick={!isExpired ? createDownloadHandler(attachment.id) : undefined}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[💡 design]
The onClick handler for downloading an attachment is conditionally set to undefined if the attachment is expired. This is correct, but consider adding a cursor: not-allowed style to visually indicate that the download action is disabled for expired attachments, improving user experience.

@himaniraghav3
Copy link
Collaborator Author

himaniraghav3 commented Nov 18, 2025

image

Added mobile view
Added number on header
Changed the hook as per feedback

Copy link
Collaborator

@kkartunov kkartunov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. Thanks @himaniraghav3

@himaniraghav3 himaniraghav3 merged commit 94d9f86 into dev Nov 18, 2025
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants