feat: show elapsed time on running builds
This commit is contained in:
		@@ -6,7 +6,6 @@
 | 
			
		||||
 | 
			
		||||
	import { page } from '$app/stores';
 | 
			
		||||
 | 
			
		||||
	import Loading from '$lib/components/Loading.svelte';
 | 
			
		||||
	import { get, post } from '$lib/api';
 | 
			
		||||
	import { t } from '$lib/translations';
 | 
			
		||||
	import LoadingLogs from '$lib/components/LoadingLogs.svelte';
 | 
			
		||||
@@ -14,7 +13,6 @@
 | 
			
		||||
	import Tooltip from '$lib/components/Tooltip.svelte';
 | 
			
		||||
 | 
			
		||||
	let logs: any = [];
 | 
			
		||||
	let loading = true;
 | 
			
		||||
	let currentStatus: any;
 | 
			
		||||
	let streamInterval: any;
 | 
			
		||||
	let followingBuild: any;
 | 
			
		||||
@@ -47,7 +45,6 @@
 | 
			
		||||
			logs = logs.concat(
 | 
			
		||||
				responseLogs.map((log: any) => ({ ...log, line: cleanAnsiCodes(log.line) }))
 | 
			
		||||
			);
 | 
			
		||||
			loading = false;
 | 
			
		||||
			streamInterval = setInterval(async () => {
 | 
			
		||||
				if (status !== 'running' && status !== 'queued') {
 | 
			
		||||
					clearInterval(streamInterval);
 | 
			
		||||
@@ -64,7 +61,7 @@
 | 
			
		||||
					logs = logs.concat(
 | 
			
		||||
						data.logs.map((log: any) => ({ ...log, line: cleanAnsiCodes(log.line) }))
 | 
			
		||||
					);
 | 
			
		||||
					dispatch('updateBuildStatus', { status });
 | 
			
		||||
					dispatch('updateBuildStatus', { status, took: data.took });
 | 
			
		||||
				} catch (error) {
 | 
			
		||||
					return errorNotification(error);
 | 
			
		||||
				}
 | 
			
		||||
@@ -97,86 +94,82 @@
 | 
			
		||||
	});
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
{#if loading}
 | 
			
		||||
	<Loading />
 | 
			
		||||
{:else}
 | 
			
		||||
	<div class="relative ">
 | 
			
		||||
		{#if currentStatus === 'running'}
 | 
			
		||||
			<LoadingLogs />
 | 
			
		||||
		{/if}
 | 
			
		||||
		{#if currentStatus === 'queued'}
 | 
			
		||||
			<div class="text-center font-bold text-xl">{$t('application.build.queued_waiting_exec')}</div>
 | 
			
		||||
		{:else}
 | 
			
		||||
			<div class="flex justify-end sticky top-0 p-2 mx-1">
 | 
			
		||||
<div class="relative ">
 | 
			
		||||
	{#if currentStatus === 'running'}
 | 
			
		||||
		<LoadingLogs />
 | 
			
		||||
	{/if}
 | 
			
		||||
	{#if currentStatus === 'queued'}
 | 
			
		||||
		<div class="text-center font-bold text-xl">{$t('application.build.queued_waiting_exec')}</div>
 | 
			
		||||
	{:else}
 | 
			
		||||
		<div class="flex justify-end sticky top-0 p-2 mx-1">
 | 
			
		||||
			<button
 | 
			
		||||
				id="follow"
 | 
			
		||||
				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
 | 
			
		||||
					id="follow"
 | 
			
		||||
					on:click={followBuild}
 | 
			
		||||
					class="bg-transparent btn btn-sm btn-linkhover:text-green-500 hover:bg-coolgray-500"
 | 
			
		||||
					class:text-green-500={followingBuild}
 | 
			
		||||
					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"
 | 
			
		||||
				>
 | 
			
		||||
					<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>
 | 
			
		||||
					{#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="#follow">Follow Logs</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>
 | 
			
		||||
				<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}
 | 
			
		||||
	</div>
 | 
			
		||||
{/if}
 | 
			
		||||
	{/if}
 | 
			
		||||
</div>
 | 
			
		||||
 
 | 
			
		||||
@@ -28,17 +28,20 @@
 | 
			
		||||
	import { get } from '$lib/api';
 | 
			
		||||
	import { t } from '$lib/translations';
 | 
			
		||||
	import { changeQueryParams, dateOptions, errorNotification } from '$lib/common';
 | 
			
		||||
	import Tooltip from '$lib/components/Tooltip.svelte';
 | 
			
		||||
 | 
			
		||||
	let buildId: any;
 | 
			
		||||
 | 
			
		||||
	let skip = 0;
 | 
			
		||||
	let noMoreBuilds = buildCount < 5 || buildCount <= skip;
 | 
			
		||||
 | 
			
		||||
	let buildTook = 0;
 | 
			
		||||
	const { id } = $page.params;
 | 
			
		||||
	let preselectedBuildId = $page.url.searchParams.get('buildId');
 | 
			
		||||
	if (preselectedBuildId) buildId = preselectedBuildId;
 | 
			
		||||
 | 
			
		||||
	async function updateBuildStatus({ detail }: { detail: any }) {
 | 
			
		||||
		const { status } = detail;
 | 
			
		||||
		const { status, took } = detail;
 | 
			
		||||
		if (status !== 'running') {
 | 
			
		||||
			try {
 | 
			
		||||
				const data = await get(`/applications/${id}/logs/build?buildId=${buildId}`);
 | 
			
		||||
@@ -58,6 +61,7 @@
 | 
			
		||||
				if (build.id === buildId) build.status = status;
 | 
			
		||||
				return build;
 | 
			
		||||
			});
 | 
			
		||||
			buildTook = took;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	async function loadMoreBuilds() {
 | 
			
		||||
@@ -137,20 +141,18 @@
 | 
			
		||||
		<div class="top-4 md:sticky">
 | 
			
		||||
			{#each builds as build, index (build.id)}
 | 
			
		||||
				<div
 | 
			
		||||
					data-tip={new Intl.DateTimeFormat('default', dateOptions).format(
 | 
			
		||||
						new Date(build.createdAt)
 | 
			
		||||
					) + `\n${build.status}`}
 | 
			
		||||
					id={`building-${build.id}`}
 | 
			
		||||
					on:click={() => loadBuild(build.id)}
 | 
			
		||||
					class:rounded-tr={index === 0}
 | 
			
		||||
					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:border-red-500={build.status === 'failed'}
 | 
			
		||||
					class:border-orange-500={build.status === 'canceled'}
 | 
			
		||||
					class:border-green-500={build.status === 'success'}
 | 
			
		||||
					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">
 | 
			
		||||
							{build.branch || application.branch}
 | 
			
		||||
						</div>
 | 
			
		||||
@@ -162,6 +164,10 @@
 | 
			
		||||
					<div class="w-48 text-center text-xs">
 | 
			
		||||
						{#if build.status === 'running'}
 | 
			
		||||
							<div class="font-bold">{$t('application.build.running')}</div>
 | 
			
		||||
							<div>
 | 
			
		||||
								Elapsed
 | 
			
		||||
								<span class="font-bold">{buildTook}s</span>
 | 
			
		||||
							</div>
 | 
			
		||||
						{:else if build.status === 'queued'}
 | 
			
		||||
							<div class="font-bold">{$t('application.build.queued')}</div>
 | 
			
		||||
						{:else}
 | 
			
		||||
@@ -172,6 +178,10 @@
 | 
			
		||||
						{/if}
 | 
			
		||||
					</div>
 | 
			
		||||
				</div>
 | 
			
		||||
				<Tooltip triggeredBy={`#building-${build.id}`}
 | 
			
		||||
					>{new Intl.DateTimeFormat('default', dateOptions).format(new Date(build.createdAt)) +
 | 
			
		||||
						`\n${build.status}`}</Tooltip
 | 
			
		||||
				>
 | 
			
		||||
			{/each}
 | 
			
		||||
		</div>
 | 
			
		||||
		{#if !noMoreBuilds}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user