feat: show elapsed time on running builds
This commit is contained in:
parent
d002ec72ad
commit
4e2dad7720
@ -6,7 +6,6 @@
|
|||||||
|
|
||||||
import { page } from '$app/stores';
|
import { page } from '$app/stores';
|
||||||
|
|
||||||
import Loading from '$lib/components/Loading.svelte';
|
|
||||||
import { get, post } from '$lib/api';
|
import { get, post } from '$lib/api';
|
||||||
import { t } from '$lib/translations';
|
import { t } from '$lib/translations';
|
||||||
import LoadingLogs from '$lib/components/LoadingLogs.svelte';
|
import LoadingLogs from '$lib/components/LoadingLogs.svelte';
|
||||||
@ -14,7 +13,6 @@
|
|||||||
import Tooltip from '$lib/components/Tooltip.svelte';
|
import Tooltip from '$lib/components/Tooltip.svelte';
|
||||||
|
|
||||||
let logs: any = [];
|
let logs: any = [];
|
||||||
let loading = true;
|
|
||||||
let currentStatus: any;
|
let currentStatus: any;
|
||||||
let streamInterval: any;
|
let streamInterval: any;
|
||||||
let followingBuild: any;
|
let followingBuild: any;
|
||||||
@ -47,7 +45,6 @@
|
|||||||
logs = logs.concat(
|
logs = logs.concat(
|
||||||
responseLogs.map((log: any) => ({ ...log, line: cleanAnsiCodes(log.line) }))
|
responseLogs.map((log: any) => ({ ...log, line: cleanAnsiCodes(log.line) }))
|
||||||
);
|
);
|
||||||
loading = false;
|
|
||||||
streamInterval = setInterval(async () => {
|
streamInterval = setInterval(async () => {
|
||||||
if (status !== 'running' && status !== 'queued') {
|
if (status !== 'running' && status !== 'queued') {
|
||||||
clearInterval(streamInterval);
|
clearInterval(streamInterval);
|
||||||
@ -64,7 +61,7 @@
|
|||||||
logs = logs.concat(
|
logs = logs.concat(
|
||||||
data.logs.map((log: any) => ({ ...log, line: cleanAnsiCodes(log.line) }))
|
data.logs.map((log: any) => ({ ...log, line: cleanAnsiCodes(log.line) }))
|
||||||
);
|
);
|
||||||
dispatch('updateBuildStatus', { status });
|
dispatch('updateBuildStatus', { status, took: data.took });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return errorNotification(error);
|
return errorNotification(error);
|
||||||
}
|
}
|
||||||
@ -97,86 +94,82 @@
|
|||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if loading}
|
<div class="relative ">
|
||||||
<Loading />
|
{#if currentStatus === 'running'}
|
||||||
{:else}
|
<LoadingLogs />
|
||||||
<div class="relative ">
|
{/if}
|
||||||
{#if currentStatus === 'running'}
|
{#if currentStatus === 'queued'}
|
||||||
<LoadingLogs />
|
<div class="text-center font-bold text-xl">{$t('application.build.queued_waiting_exec')}</div>
|
||||||
{/if}
|
{:else}
|
||||||
{#if currentStatus === 'queued'}
|
<div class="flex justify-end sticky top-0 p-2 mx-1">
|
||||||
<div class="text-center font-bold text-xl">{$t('application.build.queued_waiting_exec')}</div>
|
<button
|
||||||
{:else}
|
id="follow"
|
||||||
<div class="flex justify-end sticky top-0 p-2 mx-1">
|
on:click={followBuild}
|
||||||
|
class="bg-transparent btn btn-sm btn-linkhover:text-green-500 hover:bg-coolgray-500"
|
||||||
|
class:text-green-500={followingBuild}
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
class="w-6 h-6"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
stroke-width="1.5"
|
||||||
|
stroke="currentColor"
|
||||||
|
fill="none"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
>
|
||||||
|
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||||
|
<circle cx="12" cy="12" r="9" />
|
||||||
|
<line x1="8" y1="12" x2="12" y2="16" />
|
||||||
|
<line x1="12" y1="8" x2="12" y2="16" />
|
||||||
|
<line x1="16" y1="12" x2="12" y2="16" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
<Tooltip triggeredBy="#follow">Follow Logs</Tooltip>
|
||||||
|
{#if currentStatus === 'running'}
|
||||||
<button
|
<button
|
||||||
id="follow"
|
id="cancel"
|
||||||
on:click={followBuild}
|
on:click={cancelBuild}
|
||||||
class="bg-transparent btn btn-sm btn-linkhover:text-green-500 hover:bg-coolgray-500"
|
class:animation-spin={cancelInprogress}
|
||||||
class:text-green-500={followingBuild}
|
class="bg-transparent btn btn-sm btn-link hover:text-red-500 hover:bg-coolgray-500"
|
||||||
>
|
>
|
||||||
<svg
|
{#if cancelInprogress}
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
Cancelling...
|
||||||
class="w-6 h-6"
|
{:else}
|
||||||
viewBox="0 0 24 24"
|
<svg
|
||||||
stroke-width="1.5"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
stroke="currentColor"
|
class="w-6 h-6"
|
||||||
fill="none"
|
viewBox="0 0 24 24"
|
||||||
stroke-linecap="round"
|
stroke-width="1.5"
|
||||||
stroke-linejoin="round"
|
stroke="currentColor"
|
||||||
>
|
fill="none"
|
||||||
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
stroke-linecap="round"
|
||||||
<circle cx="12" cy="12" r="9" />
|
stroke-linejoin="round"
|
||||||
<line x1="8" y1="12" x2="12" y2="16" />
|
>
|
||||||
<line x1="12" y1="8" x2="12" y2="16" />
|
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||||
<line x1="16" y1="12" x2="12" y2="16" />
|
<circle cx="12" cy="12" r="9" />
|
||||||
</svg>
|
<path d="M10 10l4 4m0 -4l-4 4" />
|
||||||
|
</svg>
|
||||||
|
{/if}
|
||||||
</button>
|
</button>
|
||||||
<Tooltip triggeredBy="#follow">Follow Logs</Tooltip>
|
<Tooltip triggeredBy="#cancel">Cancel build</Tooltip>
|
||||||
{#if currentStatus === 'running'}
|
|
||||||
<button
|
|
||||||
id="cancel"
|
|
||||||
on:click={cancelBuild}
|
|
||||||
class:animation-spin={cancelInprogress}
|
|
||||||
class="bg-transparent btn btn-sm btn-link hover:text-red-500 hover:bg-coolgray-500"
|
|
||||||
>
|
|
||||||
{#if cancelInprogress}
|
|
||||||
Cancelling...
|
|
||||||
{:else}
|
|
||||||
<svg
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
class="w-6 h-6"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
stroke-width="1.5"
|
|
||||||
stroke="currentColor"
|
|
||||||
fill="none"
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round"
|
|
||||||
>
|
|
||||||
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
|
||||||
<circle cx="12" cy="12" r="9" />
|
|
||||||
<path d="M10 10l4 4m0 -4l-4 4" />
|
|
||||||
</svg>
|
|
||||||
{/if}
|
|
||||||
</button>
|
|
||||||
<Tooltip triggeredBy="#cancel">Cancel build</Tooltip>
|
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
{#if logs.length > 0}
|
|
||||||
<div
|
|
||||||
class="font-mono leading-6 text-left text-md tracking-tighter rounded bg-coolgray-200 py-5 px-6 whitespace-pre-wrap break-words overflow-auto max-h-[80vh] -mt-12 overflow-y-scroll scrollbar-w-1 scrollbar-thumb-coollabs scrollbar-track-coolgray-200"
|
|
||||||
bind:this={logsEl}
|
|
||||||
>
|
|
||||||
{#each logs as log}
|
|
||||||
<div>{log.line + '\n'}</div>
|
|
||||||
{/each}
|
|
||||||
</div>
|
|
||||||
{:else}
|
|
||||||
<div
|
|
||||||
class="font-mono leading-6 text-left text-md tracking-tighter rounded bg-coolgray-200 py-5 px-6 whitespace-pre-wrap break-words overflow-auto max-h-[80vh] -mt-12 overflow-y-scroll scrollbar-w-1 scrollbar-thumb-coollabs scrollbar-track-coolgray-200"
|
|
||||||
>
|
|
||||||
No logs found.
|
|
||||||
</div>
|
|
||||||
{/if}
|
{/if}
|
||||||
|
</div>
|
||||||
|
{#if logs.length > 0}
|
||||||
|
<div
|
||||||
|
class="font-mono leading-6 text-left text-md tracking-tighter rounded bg-coolgray-200 py-5 px-6 whitespace-pre-wrap break-words overflow-auto max-h-[80vh] -mt-12 overflow-y-scroll scrollbar-w-1 scrollbar-thumb-coollabs scrollbar-track-coolgray-200"
|
||||||
|
bind:this={logsEl}
|
||||||
|
>
|
||||||
|
{#each logs as log}
|
||||||
|
<div>{log.line + '\n'}</div>
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
{:else}
|
||||||
|
<div
|
||||||
|
class="font-mono leading-6 text-left text-md tracking-tighter rounded bg-coolgray-200 py-5 px-6 whitespace-pre-wrap break-words overflow-auto max-h-[80vh] -mt-12 overflow-y-scroll scrollbar-w-1 scrollbar-thumb-coollabs scrollbar-track-coolgray-200"
|
||||||
|
>
|
||||||
|
No logs found.
|
||||||
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
{/if}
|
||||||
{/if}
|
</div>
|
||||||
|
@ -28,17 +28,20 @@
|
|||||||
import { get } from '$lib/api';
|
import { get } from '$lib/api';
|
||||||
import { t } from '$lib/translations';
|
import { t } from '$lib/translations';
|
||||||
import { changeQueryParams, dateOptions, errorNotification } from '$lib/common';
|
import { changeQueryParams, dateOptions, errorNotification } from '$lib/common';
|
||||||
|
import Tooltip from '$lib/components/Tooltip.svelte';
|
||||||
|
|
||||||
let buildId: any;
|
let buildId: any;
|
||||||
|
|
||||||
let skip = 0;
|
let skip = 0;
|
||||||
let noMoreBuilds = buildCount < 5 || buildCount <= skip;
|
let noMoreBuilds = buildCount < 5 || buildCount <= skip;
|
||||||
|
|
||||||
|
let buildTook = 0;
|
||||||
const { id } = $page.params;
|
const { id } = $page.params;
|
||||||
let preselectedBuildId = $page.url.searchParams.get('buildId');
|
let preselectedBuildId = $page.url.searchParams.get('buildId');
|
||||||
if (preselectedBuildId) buildId = preselectedBuildId;
|
if (preselectedBuildId) buildId = preselectedBuildId;
|
||||||
|
|
||||||
async function updateBuildStatus({ detail }: { detail: any }) {
|
async function updateBuildStatus({ detail }: { detail: any }) {
|
||||||
const { status } = detail;
|
const { status, took } = detail;
|
||||||
if (status !== 'running') {
|
if (status !== 'running') {
|
||||||
try {
|
try {
|
||||||
const data = await get(`/applications/${id}/logs/build?buildId=${buildId}`);
|
const data = await get(`/applications/${id}/logs/build?buildId=${buildId}`);
|
||||||
@ -58,6 +61,7 @@
|
|||||||
if (build.id === buildId) build.status = status;
|
if (build.id === buildId) build.status = status;
|
||||||
return build;
|
return build;
|
||||||
});
|
});
|
||||||
|
buildTook = took;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
async function loadMoreBuilds() {
|
async function loadMoreBuilds() {
|
||||||
@ -137,20 +141,18 @@
|
|||||||
<div class="top-4 md:sticky">
|
<div class="top-4 md:sticky">
|
||||||
{#each builds as build, index (build.id)}
|
{#each builds as build, index (build.id)}
|
||||||
<div
|
<div
|
||||||
data-tip={new Intl.DateTimeFormat('default', dateOptions).format(
|
id={`building-${build.id}`}
|
||||||
new Date(build.createdAt)
|
|
||||||
) + `\n${build.status}`}
|
|
||||||
on:click={() => loadBuild(build.id)}
|
on:click={() => loadBuild(build.id)}
|
||||||
class:rounded-tr={index === 0}
|
class:rounded-tr={index === 0}
|
||||||
class:rounded-br={index === builds.length - 1}
|
class:rounded-br={index === builds.length - 1}
|
||||||
class="tooltip tooltip-primary tooltip-top flex cursor-pointer items-center justify-center border-l-2 py-4 no-underline transition-all duration-100 hover:bg-coolgray-400 hover:shadow-xl"
|
class="flex cursor-pointer items-center justify-center border-l-2 py-4 no-underline transition-all duration-100 hover:bg-coolgray-400 hover:shadow-xl"
|
||||||
class:bg-coolgray-400={buildId === build.id}
|
class:bg-coolgray-400={buildId === build.id}
|
||||||
class:border-red-500={build.status === 'failed'}
|
class:border-red-500={build.status === 'failed'}
|
||||||
class:border-orange-500={build.status === 'canceled'}
|
class:border-orange-500={build.status === 'canceled'}
|
||||||
class:border-green-500={build.status === 'success'}
|
class:border-green-500={build.status === 'success'}
|
||||||
class:border-yellow-500={build.status === 'running'}
|
class:border-yellow-500={build.status === 'running'}
|
||||||
>
|
>
|
||||||
<div class="flex-col px-2">
|
<div class="flex-col px-2 text-center min-w-[10rem]">
|
||||||
<div class="text-sm font-bold">
|
<div class="text-sm font-bold">
|
||||||
{build.branch || application.branch}
|
{build.branch || application.branch}
|
||||||
</div>
|
</div>
|
||||||
@ -162,6 +164,10 @@
|
|||||||
<div class="w-48 text-center text-xs">
|
<div class="w-48 text-center text-xs">
|
||||||
{#if build.status === 'running'}
|
{#if build.status === 'running'}
|
||||||
<div class="font-bold">{$t('application.build.running')}</div>
|
<div class="font-bold">{$t('application.build.running')}</div>
|
||||||
|
<div>
|
||||||
|
Elapsed
|
||||||
|
<span class="font-bold">{buildTook}s</span>
|
||||||
|
</div>
|
||||||
{:else if build.status === 'queued'}
|
{:else if build.status === 'queued'}
|
||||||
<div class="font-bold">{$t('application.build.queued')}</div>
|
<div class="font-bold">{$t('application.build.queued')}</div>
|
||||||
{:else}
|
{:else}
|
||||||
@ -172,6 +178,10 @@
|
|||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<Tooltip triggeredBy={`#building-${build.id}`}
|
||||||
|
>{new Intl.DateTimeFormat('default', dateOptions).format(new Date(build.createdAt)) +
|
||||||
|
`\n${build.status}`}</Tooltip
|
||||||
|
>
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
{#if !noMoreBuilds}
|
{#if !noMoreBuilds}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user