Merge pull request #127 from SaraVieira/logs-improvements
UX improvements for the log page
This commit is contained in:
		| @@ -1,5 +1,6 @@ | ||||
| <script lang="ts"> | ||||
| 	export let buildId; | ||||
| 	export let followingBuild; | ||||
|  | ||||
| 	import { createEventDispatcher, onDestroy, onMount } from 'svelte'; | ||||
| 	const dispatch = createEventDispatcher(); | ||||
| @@ -18,13 +19,15 @@ | ||||
|  | ||||
| 	const { id } = $page.params; | ||||
|  | ||||
| 	const cleanAnsiCodes = (str: string) => str.replace(/\x1B\[(\d+)m/g, ''); | ||||
|  | ||||
| 	async function streamLogs(sequence = 0) { | ||||
| 		try { | ||||
| 			let { logs: responseLogs, status } = await get( | ||||
| 				`/applications/${id}/logs/build/build.json?buildId=${buildId}&sequence=${sequence}` | ||||
| 			); | ||||
| 			currentStatus = status; | ||||
| 			logs = logs.concat(responseLogs); | ||||
| 			logs = logs.concat(responseLogs.map((log) => ({ ...log, line: cleanAnsiCodes(log.line) }))); | ||||
| 			loading = false; | ||||
| 			streamInterval = setInterval(async () => { | ||||
| 				if (status !== 'running') { | ||||
| @@ -38,8 +41,13 @@ | ||||
| 					); | ||||
| 					status = data.status; | ||||
| 					currentStatus = status; | ||||
| 					logs = logs.concat(data.logs); | ||||
|  | ||||
| 					logs = logs.concat(data.logs.map((log) => ({ ...log, line: cleanAnsiCodes(log.line) }))); | ||||
| 					dispatch('updateBuildStatus', { status }); | ||||
| 					if (followingBuild) { | ||||
| 						const logEl = document.getElementById('logs'); | ||||
| 						logEl.scrollTop = logEl.scrollHeight; | ||||
| 					} | ||||
| 				} catch ({ error }) { | ||||
| 					return errorNotification(error); | ||||
| 				} | ||||
| @@ -60,12 +68,13 @@ | ||||
| {#if loading} | ||||
| 	<Loading /> | ||||
| {:else} | ||||
| 	<div class="relative"> | ||||
| 	<div class="relative "> | ||||
| 		{#if currentStatus === 'running'} | ||||
| 			<LoadingLogs /> | ||||
| 		{/if} | ||||
| 		<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" | ||||
| 			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]" | ||||
| 			id="logs" | ||||
| 		> | ||||
| 			{#each logs as log} | ||||
| 				<div>{log.line + '\n'}</div> | ||||
|   | ||||
| @@ -33,6 +33,7 @@ | ||||
| 	export let buildCount; | ||||
|  | ||||
| 	let buildId; | ||||
| 	let followingBuild; | ||||
| 	$: buildId; | ||||
|  | ||||
| 	let skip = 0; | ||||
| @@ -85,6 +86,15 @@ | ||||
| 		buildId = build; | ||||
| 		goto(`/applications/${id}/logs/build?buildId=${buildId}`); | ||||
| 	} | ||||
|  | ||||
| 	function followBuild() { | ||||
| 		followingBuild = !followingBuild; | ||||
| 		if (followingBuild) { | ||||
| 			const logEl = document.getElementById('logs'); | ||||
| 			logEl.scrollTop = logEl.scrollHeight; | ||||
| 			window.scrollTo(0, document.body.scrollHeight); | ||||
| 		} | ||||
| 	} | ||||
| </script> | ||||
|  | ||||
| <div class="flex space-x-1 p-6 font-bold"> | ||||
| @@ -92,48 +102,75 @@ | ||||
| 		Build logs of <a href={application.fqdn} target="_blank">{getDomain(application.fqdn)}</a> | ||||
| 	</div> | ||||
| </div> | ||||
| <div class="flex flex-row justify-start space-x-2 px-10 pt-6 "> | ||||
| 	<div class="min-w-[16rem] space-y-2"> | ||||
| 		{#each builds as build (build.id)} | ||||
| 			<div | ||||
| 				data-tooltip={new Intl.DateTimeFormat('default', dateOptions).format( | ||||
| 					new Date(build.createdAt) | ||||
| 				) + `\n${build.status}`} | ||||
| 				on:click={() => loadBuild(build.id)} | ||||
| 				class="tooltip-top flex cursor-pointer items-center justify-center rounded-r border-l-2 border-transparent 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-green-500={build.status === 'success'} | ||||
| 				class:border-yellow-500={build.status === 'inprogress'} | ||||
| 			> | ||||
| 				<div class="flex-col px-2"> | ||||
| 					<div class="text-sm font-bold"> | ||||
| 						{application.branch} | ||||
| <div class="block flex-row justify-start space-x-2 px-5 pt-6 sm:px-10 md:flex"> | ||||
| 	<div class="mb-4 min-w-[16rem] space-y-2 md:mb-0 "> | ||||
| 		<div class="top-4 md:sticky"> | ||||
| 			{#each builds as build (build.id)} | ||||
| 				<div | ||||
| 					data-tooltip={new Intl.DateTimeFormat('default', dateOptions).format( | ||||
| 						new Date(build.createdAt) | ||||
| 					) + `\n${build.status}`} | ||||
| 					on:click={() => loadBuild(build.id)} | ||||
| 					class="tooltip-top flex cursor-pointer items-center justify-center rounded-r border-l-2 border-transparent 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-green-500={build.status === 'success'} | ||||
| 					class:border-yellow-500={build.status === 'inprogress'} | ||||
| 				> | ||||
| 					<div class="flex-col px-2"> | ||||
| 						<div class="text-sm font-bold"> | ||||
| 							{application.branch} | ||||
| 						</div> | ||||
| 						<div class="text-xs"> | ||||
| 							{build.type} | ||||
| 						</div> | ||||
| 					</div> | ||||
| 					<div class="text-xs"> | ||||
| 						{build.type} | ||||
| 					</div> | ||||
| 				</div> | ||||
| 				<div class="flex-1" /> | ||||
| 					<div class="flex-1" /> | ||||
|  | ||||
| 				<div class="w-48 text-center text-xs"> | ||||
| 					{#if build.status === 'running'} | ||||
| 						<div class="font-bold">Running</div> | ||||
| 					{:else} | ||||
| 						<div>{build.since}</div> | ||||
| 						<div>Finished in <span class="font-bold">{build.took}s</span></div> | ||||
| 					{/if} | ||||
| 					<div class="w-48 text-center text-xs"> | ||||
| 						{#if build.status === 'running'} | ||||
| 							<div class="font-bold">Running</div> | ||||
| 						{:else} | ||||
| 							<div>{build.since}</div> | ||||
| 							<div>Finished in <span class="font-bold">{build.took}s</span></div> | ||||
| 						{/if} | ||||
| 					</div> | ||||
| 				</div> | ||||
| 			</div> | ||||
| 		{/each} | ||||
| 			{/each} | ||||
| 		</div> | ||||
| 		<button | ||||
| 			on:click={followBuild} | ||||
| 			data-tooltip="Follow logs" | ||||
| 			class={followingBuild && 'text-green-500'} | ||||
| 		> | ||||
| 			<svg | ||||
| 				xmlns="http://www.w3.org/2000/svg" | ||||
| 				class="h-6 w-6" | ||||
| 				fill="none" | ||||
| 				viewBox="0 0 24 24" | ||||
| 				stroke="currentColor" | ||||
| 			> | ||||
| 				<path | ||||
| 					stroke-linecap="round" | ||||
| 					stroke-linejoin="round" | ||||
| 					stroke-width="2" | ||||
| 					d="M15 13l-3 3m0 0l-3-3m3 3V8m0 13a9 9 0 110-18 9 9 0 010 18z" | ||||
| 				/> | ||||
| 			</svg> | ||||
| 		</button> | ||||
| 		{#if buildCount > 0 && !noMoreBuilds} | ||||
| 			<button class="w-full" on:click={loadMoreBuilds}>Load More</button> | ||||
| 		{/if} | ||||
| 	</div> | ||||
| 	<div class="w-96 flex-1"> | ||||
| 	<div class="flex-1 md:w-96"> | ||||
| 		{#if buildId} | ||||
| 			{#key buildId} | ||||
| 				<svelte:component this={BuildLog} {buildId} on:updateBuildStatus={updateBuildStatus} /> | ||||
| 				<svelte:component | ||||
| 					this={BuildLog} | ||||
| 					{buildId} | ||||
| 					{followingBuild} | ||||
| 					on:updateBuildStatus={updateBuildStatus} | ||||
| 				/> | ||||
| 			{/key} | ||||
| 		{/if} | ||||
| 	</div> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Andras Bacsai
					Andras Bacsai