Skip to content
This repository has been archived by the owner on Oct 28, 2024. It is now read-only.

Commit

Permalink
Merge pull request #1010 from equilobe/show-channel-status-on-overvie…
Browse files Browse the repository at this point in the history
…w-page

Show channel status on overview page
  • Loading branch information
bacongobbler authored Jul 8, 2022
2 parents 811a044 + 3ce8f0a commit 06ff476
Show file tree
Hide file tree
Showing 14 changed files with 205 additions and 18 deletions.
1 change: 1 addition & 0 deletions src/Application/Common/Interfaces/IJobService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ public interface IJobService
public void DeleteJob(string jobName);
public string[] GetJobLogs(string jobName);
public IEnumerable<Job>? GetJobs();
public Job? GetJob(string jobName);
}
31 changes: 31 additions & 0 deletions src/Application/JobStatuses/Queries/GetJobStatusQuery.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using Hippo.Application.Common.Interfaces;
using Hippo.Application.Jobs;
using MediatR;

namespace Hippo.Application.Channels.Queries;

public class GetJobStatusQuery : IRequest<ChannelJobStatusItem>
{
public Guid ChannelId { get; set; }
}

public class GetJobStatusQueryHandler : IRequestHandler<GetJobStatusQuery, ChannelJobStatusItem>
{
private readonly IJobService _jobService;

public GetJobStatusQueryHandler(IJobService jobService)
{
_jobService = jobService;
}

public Task<ChannelJobStatusItem> Handle(GetJobStatusQuery request, CancellationToken cancellationToken)
{
var job = _jobService.GetJob(request.ChannelId.ToString());

return Task.FromResult(new ChannelJobStatusItem
{
ChannelId = request.ChannelId,
Status = job?.Status ?? JobStatus.Dead,
});
}
}
18 changes: 18 additions & 0 deletions src/Infrastructure/Services/NomadJobService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,24 @@ private Fermyon.Nomad.Model.Task GenerateJobTask(NomadJob nomadJob)
}
}

public Application.Jobs.Job? GetJob(string jobName)
{
try
{
var job = _jobsClient.GetJob(jobName);

return new NomadJob(_configuration,
Guid.Parse(job.ID),
string.Empty,
string.Empty,
Enum.Parse<JobStatus>(FormatNomadJobStatus(job.Status)));
}
catch
{
return null;
}
}

private string FormatNomadJobStatus(string status)
{
return char.ToUpper(status[0]) + status[1..];
Expand Down
9 changes: 9 additions & 0 deletions src/Web/Api/JobStatusController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,13 @@ public async Task<ActionResult<Page<ChannelJobStatusItem>>> Index(
PageSize = pageSize,
});
}

[HttpGet("{channelId}")]
public async Task<ActionResult<ChannelJobStatusItem>> GetJobStatus(Guid channelId)
{
return await Mediator.Send(new GetJobStatusQuery
{
ChannelId = channelId,
});
}
}
2 changes: 1 addition & 1 deletion src/Web/ClientApp/.eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ e2e/**
karma.conf.js
commitlint.config.js
*.spec.ts
src/app/core/api/*
src/app/core/api/**
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,13 @@
<div *ngIf="!loading">
<div class="box">
<div *ngIf="activeRevision">
<!-- TODO: add status -->
<span class="icon has-text-success">
<fa-icon [icon]="icons.faCheckCircle"></fa-icon>
<span class="icon">
<fa-icon
[icon]="icons.faCircle"
[ngStyle]="{'color': getStatusColor(channelStatus)}"
[attr.data-tooltip]=channelStatus
>
</fa-icon>
</span>
Version {{activeRevision.revisionNumber}} was published {{publishedAt}}.
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
import { ChannelItem, ChannelService, RevisionItem } from 'src/app/core/api/v1';
import { Component, Input, OnChanges } from '@angular/core';
import {
faCheckCircle,
ChannelItem,
ChannelService,
JobStatus,
JobStatusService,
RevisionItem,
} from 'src/app/core/api/v1';
import { Component, Input, OnChanges, OnDestroy, OnInit } from '@angular/core';
import {
faCircle,
faNetworkWired,
faTimesCircle,
} from '@fortawesome/free-solid-svg-icons';
Expand All @@ -16,29 +22,67 @@ import en from 'javascript-time-ago/locale/en';
templateUrl: './overview.component.html',
styleUrls: ['./overview.component.css'],
})
export class OverviewComponent implements OnChanges {
export class OverviewComponent implements OnChanges, OnInit, OnDestroy {
@Input() channelId = '';
channel!: ChannelItem;
channelStatus!: JobStatus;
activeRevision!: RevisionItem | undefined;
publishedAt: string | null | undefined;
icons = { faCheckCircle, faTimesCircle, faNetworkWired };
icons = { faCircle, faTimesCircle, faNetworkWired };
types = ComponentTypes;
protocol = window.location.protocol;
loading = false;
timeAgo: any;

interval: any = null;
timeInterval = 5000;

constructor(
private readonly channelService: ChannelService,
private readonly jobStatusService: JobStatusService,
private router: Router
) {
TimeAgo.addDefaultLocale(en);
this.timeAgo = new TimeAgo('en-US');
}

ngOnInit(): void {
this.getJobStatus();

this.interval = setInterval(() => {
this.getJobStatus();
}, this.timeInterval);
}

ngOnChanges(): void {
this.refreshData();
}

ngOnDestroy(): void {
clearInterval(this.interval);
}

getJobStatus(): void {
this.jobStatusService
.apiJobstatusChannelIdGet(this.channelId)
.subscribe((res) => (this.channelStatus = res.status));
}

getStatusColor(status: JobStatus | undefined) {
switch (status) {
case JobStatus.Unknown:
return 'gray';
case JobStatus.Pending:
return 'yellow';
case JobStatus.Running:
return 'green';
case JobStatus.Dead:
return 'red';
default:
return 'gray';
}
}

refreshData() {
this.loading = true;
this.channelService.apiChannelIdGet(this.channelId).subscribe({
Expand Down
67 changes: 67 additions & 0 deletions src/Web/ClientApp/src/app/core/api/v1/api/jobStatus.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import { HttpClient, HttpHeaders, HttpParams,
import { CustomHttpParameterCodec } from '../encoder';
import { Observable } from 'rxjs';

// @ts-ignore
import { ChannelJobStatusItem } from '../model/channelJobStatusItem';
// @ts-ignore
import { ChannelJobStatusItemPage } from '../model/channelJobStatusItemPage';

Expand Down Expand Up @@ -86,6 +88,71 @@ export class JobStatusService {
return httpParams;
}

/**
* @param channelId
* @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
* @param reportProgress flag to report request and response progress.
*/
public apiJobstatusChannelIdGet(channelId: string, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'text/plain' | 'application/json' | 'text/json', context?: HttpContext}): Observable<ChannelJobStatusItem>;
public apiJobstatusChannelIdGet(channelId: string, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'text/plain' | 'application/json' | 'text/json', context?: HttpContext}): Observable<HttpResponse<ChannelJobStatusItem>>;
public apiJobstatusChannelIdGet(channelId: string, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'text/plain' | 'application/json' | 'text/json', context?: HttpContext}): Observable<HttpEvent<ChannelJobStatusItem>>;
public apiJobstatusChannelIdGet(channelId: string, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'text/plain' | 'application/json' | 'text/json', context?: HttpContext}): Observable<any> {
if (channelId === null || channelId === undefined) {
throw new Error('Required parameter channelId was null or undefined when calling apiJobstatusChannelIdGet.');
}

let localVarHeaders = this.defaultHeaders;

let localVarCredential: string | undefined;
// authentication (Bearer) required
localVarCredential = this.configuration.lookupCredential('Bearer');
if (localVarCredential) {
localVarHeaders = localVarHeaders.set('Authorization', localVarCredential);
}

let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept;
if (localVarHttpHeaderAcceptSelected === undefined) {
// to determine the Accept header
const httpHeaderAccepts: string[] = [
'text/plain',
'application/json',
'text/json'
];
localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts);
}
if (localVarHttpHeaderAcceptSelected !== undefined) {
localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected);
}

let localVarHttpContext: HttpContext | undefined = options && options.context;
if (localVarHttpContext === undefined) {
localVarHttpContext = new HttpContext();
}


let responseType_: 'text' | 'json' | 'blob' = 'json';
if (localVarHttpHeaderAcceptSelected) {
if (localVarHttpHeaderAcceptSelected.startsWith('text')) {
responseType_ = 'text';
} else if (this.configuration.isJsonMime(localVarHttpHeaderAcceptSelected)) {
responseType_ = 'json';
} else {
responseType_ = 'blob';
}
}

return this.httpClient.get<ChannelJobStatusItem>(`${this.configuration.basePath}/api/jobstatus/${encodeURIComponent(String(channelId))}`,
{
context: localVarHttpContext,
responseType: <any>responseType_,
withCredentials: this.configuration.withCredentials,
headers: localVarHeaders,
observe: observe,
reportProgress: reportProgress
}
);
}

/**
* @param pageIndex
* @param pageSize
Expand Down
2 changes: 1 addition & 1 deletion src/Web/ClientApp/src/app/core/api/v1/model/appItem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ import { AppChannelListItem } from './appChannelListItem';


export interface AppItem {
name: string;
id: string;
name: string;
storageId: string;
description?: string | null;
channels: Array<AppChannelListItem>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,17 @@
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
*
* The version of the OpenAPI document: 1.0
*
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/

export interface CreateEnvironmentVariableCommand {

export interface CreateEnvironmentVariableCommand {
key: string;
value: string;
channelId: string;
}

Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,18 @@
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
*
* The version of the OpenAPI document: 1.0
*
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/

export interface EnvironmentVariableDto {

export interface EnvironmentVariableDto {
id: string;
channelId: string;
key: string;
value: string;
}

Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,16 @@
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
*
* The version of the OpenAPI document: 1.0
*
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
import { EnvironmentVariableDto } from './environmentVariableDto';

export interface EnvironmentVariablesVm {

export interface EnvironmentVariablesVm {
environmentVariables: Array<EnvironmentVariableDto>;
}

Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,17 @@
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
*
* The version of the OpenAPI document: 1.0
*
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/

export interface UpdateEnvironmentVariableCommand {

export interface UpdateEnvironmentVariableCommand {
id: string;
key: string;
value: string;
}

5 changes: 5 additions & 0 deletions tests/Hippo.FunctionalTests/TestBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,11 @@ public string[] GetJobLogs(string jobName)
return null;
}

public Job? GetJob(string jobName)
{
return null;
}

private class NullJob : Job
{
public void Reload() { }
Expand Down

0 comments on commit 06ff476

Please sign in to comment.