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

feat(LogSheet): Update UI of log download links #670

Merged
merged 1 commit into from
Dec 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions dashboard/src/lib/string.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,27 @@ export const truncateBigText = (
text && text.length > maxTextLength
? text.slice(0, maxTextLength) + '...'
: valueOrEmpty(text);

export const truncateUrl = (
url: string | undefined,
domainLength = 50,
endPathLength = 20,
): string => {
if (url) {
if (url.length <= domainLength + endPathLength) {
return url;
}
const protocolRegex = /^\w+:\/\//;
const searchParamsRegex = /\?.*$/;
const replacedUrl = url
.replace(protocolRegex, '')
.replace(searchParamsRegex, '');
const splittedUrl = replacedUrl.split('/');
const hostname = splittedUrl[0];
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
const hostname = splittedUrl[0];
const hostname = splittedUrl[0] ?? '';

typescript strict mode doesn't check array index

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm checking for undefined below

const pathname = splittedUrl?.pop();
const domain = hostname ? hostname.slice(0, domainLength) : '';
const lastPath = pathname ? pathname.slice(-endPathLength) : '';
return `${domain}...${lastPath}`;
}
return valueOrEmpty(url);
};
6 changes: 5 additions & 1 deletion dashboard/src/locales/messages/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ export const messages = {
'global.failedCount': 'Failed: {count}',
'global.fails': 'Fails',
'global.filters': 'Filters',
'global.fullLogs': 'Full logs',
'global.github': 'GitHub',
'global.hardware': 'Hardware',
'global.hardwares': 'Hardwares',
Expand Down Expand Up @@ -173,9 +174,12 @@ export const messages = {
'hardware.searchPlaceholder': 'Search by hardware name',
'hardwareDetails.treeBranch': 'Tree / Branch',
'issue.noIssueFound': 'No issue found.',
'logSheet.downloadLog': 'You can download the full log here: {link}',
'logSheet.fileName': 'File Name',
'logSheet.fileSize': 'File Size',
'logSheet.indexOf': 'Index of {link}',
'logSheet.logQueryCustomError':
'This log url is not supported in the log viewer yet, but you can still download the log in the link above',
'logSheet.noLogFound': 'No logs available',
'logSheet.title': 'Logs Viewer',
'routes.buildDetails': 'Build',
'routes.hardwareMonitor': 'Hardware',
Expand Down
83 changes: 47 additions & 36 deletions dashboard/src/pages/TreeDetails/Tabs/LogSheet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {
import { DumbTableHeader, TableHead } from '@/components/Table/BaseTable';
import { Button } from '@/components/ui/button';
import { Table, TableBody, TableCell, TableRow } from '@/components/ui/table';
import { truncateBigText } from '@/lib/string';
import { truncateUrl } from '@/lib/string';
import { useLogFiles } from '@/api/treeDetails';
import QuerySwitcher from '@/components/QuerySwitcher/QuerySwitcher';
import type { LogFile } from '@/types/tree/TreeDetails';
Expand Down Expand Up @@ -179,42 +179,53 @@ export const LogSheet = ({
<FormattedMessage id="logSheet.title" />
</SheetTitle>
</SheetHeader>
<BaseCard className="gap-0" title={<FormattedMessage id="global.logs" />}>
<div className="px-2 py-3 font-mono text-sm text-[#454545]">
<FormattedMessage
id="logSheet.indexOf"
values={{
link: (
<a
href={logUrl}
className="flex gap-2 transition-all hover:text-blue"
>
<span>{truncateBigText(logUrl)}</span>
<GrDocumentDownload className="text-blue" />
</a>
),
}}
/>
<BaseCard
className="gap-0"
title={<FormattedMessage id="global.fullLogs" />}
>
<div className="px-2 py-3 font-mono text-[#454545]">
{navigationLogsActions?.isLoading ? (
<FormattedMessage id="global.loading" />
) : (
<FormattedMessage
id={logUrl ? 'logSheet.downloadLog' : 'logSheet.noLogFound'}
values={{
link: (
<a
href={logUrl}
className="flex gap-2 text-blue transition-all hover:underline"
>
<span>{truncateUrl(logUrl)}</span>
<GrDocumentDownload className="text-blue" />
</a>
),
}}
/>
)}
</div>
<QuerySwitcher
data={logFilesData}
status={status}
skeletonClassname="h-[3rem]"
customError={
<div className="p-4 text-center">
This log url is not supported in the log viewer yet
</div>
}
>
<Table containerClassName="rounded-none border-none">
{logFilesData?.log_files && !!logUrl && (
<MemoizedLogFilesTable
logFiles={logFilesData?.log_files}
logUrl={logUrl}
/>
)}
</Table>
</QuerySwitcher>
{logUrl ? (
<QuerySwitcher
data={logFilesData}
status={status}
skeletonClassname="h-[3rem]"
customError={
<div className="p-4 text-center">
<FormattedMessage id="logSheet.logQueryCustomError" />
</div>
}
>
<Table containerClassName="rounded-none border-none">
{logFilesData?.log_files && !!logUrl && (
<MemoizedLogFilesTable
logFiles={logFilesData?.log_files}
logUrl={logUrl}
/>
)}
</Table>
</QuerySwitcher>
) : (
<div className="p-9"></div>
)}
</BaseCard>

{navigationLogsActions?.isLoading ? (
Expand Down
Loading