mirror of
				https://github.com/ClusterCockpit/cc-backend
				synced 2025-11-04 09:35:07 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			134 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			Svelte
		
	
	
	
	
	
			
		
		
	
	
			134 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			Svelte
		
	
	
	
	
	
<!--
 | 
						|
    @component Displays job metaData, serves links to detail pages
 | 
						|
 | 
						|
    Properties:
 | 
						|
    - `job Object`: The Job Object (GraphQL.Job)
 | 
						|
    - `jobTags [Number]?`: The jobs tags as IDs, default useful for dynamically updating the tags [Default: job.tags]
 | 
						|
 -->
 | 
						|
 | 
						|
<script>
 | 
						|
  import Tag from "../Tag.svelte";
 | 
						|
  import { Badge, Icon } from "@sveltestrap/sveltestrap";
 | 
						|
  import { scrambleNames, scramble } from "../utils.js";
 | 
						|
 | 
						|
  export let job;
 | 
						|
  export let jobTags = job.tags;
 | 
						|
 | 
						|
  function formatDuration(duration) {
 | 
						|
    const hours = Math.floor(duration / 3600);
 | 
						|
    duration -= hours * 3600;
 | 
						|
    const minutes = Math.floor(duration / 60);
 | 
						|
    duration -= minutes * 60;
 | 
						|
    const seconds = duration;
 | 
						|
    return `${hours}:${("0" + minutes).slice(-2)}:${("0" + seconds).slice(-2)}`;
 | 
						|
  }
 | 
						|
 | 
						|
  function getStateColor(state) {
 | 
						|
    switch (state) {
 | 
						|
      case "running":
 | 
						|
        return "success";
 | 
						|
      case "completed":
 | 
						|
        return "primary";
 | 
						|
      default:
 | 
						|
        return "danger";
 | 
						|
    }
 | 
						|
  }
 | 
						|
</script>
 | 
						|
 | 
						|
<div>
 | 
						|
  <p>
 | 
						|
    <span class="fw-bold"
 | 
						|
      ><a href="/monitoring/job/{job.id}" target="_blank">{job.jobId}</a>
 | 
						|
      ({job.cluster})</span
 | 
						|
    >
 | 
						|
    {#if job.metaData?.jobName}
 | 
						|
      <br />
 | 
						|
      {#if job.metaData?.jobName.length <= 25}
 | 
						|
        <div>{job.metaData.jobName}</div>
 | 
						|
      {:else}
 | 
						|
        <div
 | 
						|
          class="truncate"
 | 
						|
          style="cursor:help; width:230px;"
 | 
						|
          title={job.metaData.jobName}
 | 
						|
        >
 | 
						|
          {job.metaData.jobName}
 | 
						|
        </div>
 | 
						|
      {/if}
 | 
						|
    {/if}
 | 
						|
    {#if job.arrayJobId}
 | 
						|
      Array Job: <a
 | 
						|
        href="/monitoring/jobs/?arrayJobId={job.arrayJobId}&cluster={job.cluster}"
 | 
						|
        target="_blank">#{job.arrayJobId}</a
 | 
						|
      >
 | 
						|
    {/if}
 | 
						|
  </p>
 | 
						|
 | 
						|
  <p>
 | 
						|
    <Icon name="person-fill" />
 | 
						|
    <a class="fst-italic" href="/monitoring/user/{job.user}" target="_blank">
 | 
						|
      {scrambleNames ? scramble(job.user) : job.user}
 | 
						|
    </a>
 | 
						|
    {#if job.userData && job.userData.name}
 | 
						|
      ({scrambleNames ? scramble(job.userData.name) : job.userData.name})
 | 
						|
    {/if}
 | 
						|
    {#if job.project && job.project != "no project"}
 | 
						|
      <br />
 | 
						|
      <Icon name="people-fill" />
 | 
						|
      <a
 | 
						|
        class="fst-italic"
 | 
						|
        href="/monitoring/jobs/?project={job.project}&projectMatch=eq"
 | 
						|
        target="_blank"
 | 
						|
      >
 | 
						|
        {scrambleNames ? scramble(job.project) : job.project}
 | 
						|
      </a>
 | 
						|
    {/if}
 | 
						|
  </p>
 | 
						|
 | 
						|
  <p>
 | 
						|
    {#if job.numNodes == 1}
 | 
						|
      {job.resources[0].hostname}
 | 
						|
    {:else}
 | 
						|
      {job.numNodes}
 | 
						|
    {/if}
 | 
						|
    <Icon name="pc-horizontal" />
 | 
						|
    {#if job.exclusive != 1}
 | 
						|
      (shared)
 | 
						|
    {/if}
 | 
						|
    {#if job.numAcc > 0}
 | 
						|
      , {job.numAcc} <Icon name="gpu-card" />
 | 
						|
    {/if}
 | 
						|
    {#if job.numHWThreads > 0}
 | 
						|
      , {job.numHWThreads} <Icon name="cpu" />
 | 
						|
    {/if}
 | 
						|
    <br />
 | 
						|
    {job.subCluster}
 | 
						|
  </p>
 | 
						|
 | 
						|
  <p>
 | 
						|
    Start: <span class="fw-bold"
 | 
						|
      >{new Date(job.startTime).toLocaleString()}</span
 | 
						|
    >
 | 
						|
    <br />
 | 
						|
    Duration: <span class="fw-bold">{formatDuration(job.duration)}</span>
 | 
						|
    <Badge color={getStateColor(job.state)}>{job.state}</Badge>
 | 
						|
    {#if job.walltime}
 | 
						|
      <br />
 | 
						|
      Walltime: <span class="fw-bold">{formatDuration(job.walltime)}</span>
 | 
						|
    {/if}
 | 
						|
  </p>
 | 
						|
 | 
						|
  <p>
 | 
						|
    {#each jobTags as tag}
 | 
						|
      <Tag {tag} />
 | 
						|
    {/each}
 | 
						|
  </p>
 | 
						|
</div>
 | 
						|
 | 
						|
<style>
 | 
						|
  .truncate {
 | 
						|
    overflow: hidden;
 | 
						|
    text-overflow: ellipsis;
 | 
						|
    white-space: nowrap;
 | 
						|
  }
 | 
						|
</style>
 |