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

Commit

Permalink
Merge pull request #1840 from hashicorp/ui/pushed-artifacts
Browse files Browse the repository at this point in the history
ui: Incorporate pushed artifacts into build display
  • Loading branch information
jgwhite authored Jul 20, 2021
2 parents 27b8279 + f36048c commit f95e34b
Show file tree
Hide file tree
Showing 23 changed files with 416 additions and 101 deletions.
3 changes: 3 additions & 0 deletions .changelog/1840.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:improvement
ui: Incorporate pushed artifacts into build display
```
37 changes: 17 additions & 20 deletions ui/app/components/app-card/build.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -9,28 +9,25 @@
>
<b class="badge badge--version">v{{@model.sequence}}</b>
</LinkTo>
<OperationStatusIndicator @status={{@model.status}} />
<OperationStatusIndicator @status={{or @model.pushedArtifact.status @model.status}} />
</:meta-primary>

<:meta-secondary>
<Pds::Icon
@type={{icon-for-component @model.component.name}}
class="icon app-card__component-icon"
/>

<span>
{{#if (eq @model.status.state 2)}}
Built with
<b>{{component-name @model.component.name}}</b>
in
{{date-format-distance @model.status.startTime.seconds @model.status.completeTime.seconds }}
{{else if (eq @model.status.state 3)}}
Failed to build with
<b>{{component-name @model.component.name}}</b>
{{else}}
Building with
<b>{{component-name @model.component.name}}</b>
{{/if}}
</span>
{{#let (or @model.pushedArtifact @model) as |operation|}}
<Pds::Icon
@type={{icon-for-component operation.component.name}}
class="icon app-card__component-icon"
/>
<span>
{{t
(concat
"build_status"
".type-" operation.component.type
".state-" operation.status.state
)
}}
<b>{{component-name operation.component.name}}</b>
</span>
{{/let}}
</:meta-secondary>
</AppCard>
57 changes: 31 additions & 26 deletions ui/app/components/app-item/build.hbs
Original file line number Diff line number Diff line change
@@ -1,34 +1,39 @@
<li class="app-item">
<li class="app-item" data-test-app-item-build>
<LinkTo @route="workspace.projects.project.app.build" @models={{array @build.sequence}}>
<p>
<b class="badge badge--version">v{{@build.sequence}}</b>
</p>
<b class="badge badge--version">v{{@build.sequence}}</b>
<small class="app-item__meta__secondary">
<Pds::Icon @type={{icon-for-component @build.component.name}} class="icon" />
<span>{{if (eq @model.status.state 1) 'Building' 'Built'}} with
<b>{{titleize @build.component.name}}</b>
{{#if (eq @build.status.state 1)}}
(Started {{date-format-distance-to-now @build.status.startTime.seconds }})
{{else}}
{{date-format-distance-to-now @build.status.completeTime.seconds }}
{{/if}}
</span>
{{#let (or @build.pushedArtifact @build) as |operation|}}
<Pds::Icon
@type={{icon-for-component operation.component.name}}
class="icon"
/>

<span>
{{t
(concat
"build_status"
".type-" operation.component.type
".state-" operation.status.state
)
}}
<b>{{component-name operation.component.name}}</b>
<OperationStatusIndicator @status={{operation.status}} @matchTypography={{true}} />
</span>
{{/let}}
</small>
</LinkTo>
{{#if (eq @build.status.state 1)}}
<b class="badge">

{{#if (and (eq @build.status.state 2) (eq @build.pushedArtifact.status.state 2))}}
<b class="badge badge--info">
<Pds::Icon @type="clock-outline" class="icon" />
<span>Building...</span>
</b>
{{else if (eq @build.status.state 2)}}
<b class="badge badge--success">
<Pds::Icon @type="check-plain" class="icon" />
<span>Built in {{date-format-distance @build.status.startTime.seconds @build.status.completeTime.seconds }}</span>
</b>
{{else if (eq @build.status.state 3)}}
<b class="badge badge--error">
<Pds::Icon @type="alert-triangle" class="icon" />
<span>Build failed</span>
<span>
{{t "app_item_build.built_in"
duration=(date-format-distance
@build.status.startTime.seconds
@build.status.completeTime.seconds
)
}}
</span>
</b>
{{/if}}
</li>
21 changes: 20 additions & 1 deletion ui/app/components/operation-status-indicator.hbs
Original file line number Diff line number Diff line change
@@ -1,3 +1,21 @@
{{!--
## Usage
<OperationStatusIndicator
@status={{build.status}}
/>
If you would like the indicator to match the surrounding typography,
pass `@matchTypography={{true}}`:
<OperationStatusIndicator
@status={{build.status}}
@matchTypography={{true}}
/>
--}}

{{#let
(hash
state=(or
Expand All @@ -14,10 +32,11 @@
as |vars|
}}
<span
data-test-operation-status-indicator
data-test-operation-status-indicator={{vars.state}}
class="
operation-status-indicator
operation-status-indicator--{{vars.state}}
{{if @matchTypography "operation-status-indicator--match-typography"}}
focus-ring
"
tabindex="0"
Expand Down
8 changes: 7 additions & 1 deletion ui/app/helpers/component-name.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,13 @@ export function componentName([component]: [string]): string {
});

// Replace any separators that are not human readable
return result.replace(replace, ' ');
result = result.replace(replace, ' ');

// Replace brand initialisms
result = result.replace('Aws', 'AWS');
result = result.replace('Ecr', 'ECR');

return result;
}

export default helper(componentName);
2 changes: 1 addition & 1 deletion ui/app/helpers/icon-for-component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import { helper } from '@ember/component/helper';
export function iconForComponent([component]: [string]): string {
switch (component) {
case 'aws-ec2':
return 'logo-aws-color';
case 'aws-ecs':
case 'aws-ecr':
return 'logo-aws-color';
case 'azure-container-instances':
return 'logo-azure-color';
Expand Down
24 changes: 22 additions & 2 deletions ui/app/routes/workspace/projects/project/app.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Route from '@ember/routing/route';
import { inject as service } from '@ember/service';
import ApiService from 'waypoint/services/api';
import { Ref, Deployment, Build, Release, Project, StatusReport } from 'waypoint-pb';
import { Ref, Deployment, Build, Release, Project, StatusReport, PushedArtifact } from 'waypoint-pb';
import PollModelService from 'waypoint/services/poll-model';
import { hash } from 'rsvp';

Expand All @@ -13,14 +13,19 @@ export interface Model {
application: Ref.Application.AsObject;
deployments: (Deployment.AsObject & WithStatusReport)[];
releases: (Release.AsObject & WithStatusReport)[];
builds: Build.AsObject[];
builds: (Build.AsObject & WithPushedArtifact)[];
pushedArtifacts: PushedArtifact.AsObject[];
statusReports: StatusReport.AsObject[];
}

interface WithStatusReport {
statusReport?: StatusReport.AsObject;
}

interface WithPushedArtifact {
pushedArtifact?: PushedArtifact.AsObject;
}

interface Breadcrumb {
label: string;
icon: string;
Expand Down Expand Up @@ -60,12 +65,14 @@ export default class App extends Route {
deployments: this.api.listDeployments(wsRef, appRef),
releases: this.api.listReleases(wsRef, appRef),
builds: this.api.listBuilds(wsRef, appRef),
pushedArtifacts: this.api.listPushedArtifacts(wsRef, appRef),
statusReports: this.api.listStatusReports(wsRef, appRef),
});
}

afterModel(model: Model): void {
injectStatusReports(model);
injectPushedArtifacts(model);
this.pollModel.setup(this);
}
}
Expand All @@ -87,3 +94,16 @@ function injectStatusReports(model: Model): void {
}
}
}

function injectPushedArtifacts(model: Model): void {
let { builds, pushedArtifacts } = model;

for (let pushedArtifact of pushedArtifacts) {
if (pushedArtifact.buildId) {
let build = builds.find((b) => b.id === pushedArtifact.buildId);
if (build) {
build.pushedArtifact = pushedArtifact;
}
}
}
}
25 changes: 20 additions & 5 deletions ui/app/routes/workspace/projects/project/app/build.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
import Route from '@ember/routing/route';
import { inject as service } from '@ember/service';
import ApiService from 'waypoint/services/api';
import { Ref, GetBuildRequest } from 'waypoint-pb';
import { Ref, GetBuildRequest, Build, PushedArtifact } from 'waypoint-pb';
import { Model as AppRouteModel } from '../app';

interface BuildModelParams {
sequence: number;
}

interface WithPushedArtifact {
pushedArtifact?: PushedArtifact.AsObject;
}

type BuildWithArtifact = Build.AsObject & WithPushedArtifact;

export default class BuildDetail extends Route {
@service api!: ApiService;

Expand All @@ -28,15 +35,23 @@ export default class BuildDetail extends Route {

async model(params: BuildModelParams) {
// Setup the build request
let { builds } = this.modelFor('workspace.projects.project.app');
let { id: build_id } = builds.find((obj) => obj.sequence === Number(params.sequence));
let { builds } = this.modelFor('workspace.projects.project.app') as AppRouteModel;
let buildFromAppRoute = builds.find((obj) => obj.sequence === Number(params.sequence));

if (!buildFromAppRoute) {
throw new Error('Build not found');
}

let ref = new Ref.Operation();
ref.setId(build_id);
ref.setId(buildFromAppRoute.id);
let req = new GetBuildRequest();
req.setRef(ref);

let build = await this.api.client.getBuild(req, this.api.WithMeta());
return build.toObject();
let result: BuildWithArtifact = build.toObject();

result.pushedArtifact = buildFromAppRoute.pushedArtifact;

return result;
}
}
21 changes: 21 additions & 0 deletions ui/app/services/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import {
ListStatusReportsRequest,
ListStatusReportsResponse,
GetLatestStatusReportRequest,
ListPushedArtifactsRequest,
PushedArtifact,
} from 'waypoint-pb';
import config from 'waypoint/config/environment';

Expand Down Expand Up @@ -84,6 +86,25 @@ export default class ApiService extends Service {
return resp.getBuildsList().map((d) => d.toObject());
}

async listPushedArtifacts(
wsRef: Ref.Workspace,
appRef: Ref.Application
): Promise<PushedArtifact.AsObject[]> {
let request = new ListPushedArtifactsRequest();

request.setApplication(appRef);
request.setWorkspace(wsRef);

// TODO(jgwhite): request.setIncludeBuild
// TODO(jgwhite): request.setOrder
// TODO(jgwhite): request.setStatusList

let response = await this.client.listPushedArtifacts(request, this.WithMeta());
let result = response.getArtifactsList().map((pa) => pa.toObject());

return result;
}

async listReleases(wsRef: Ref.Workspace, appRef: Ref.Application): Promise<Release.AsObject[]> {
let req = new ListReleasesRequest();
req.setWorkspace(wsRef);
Expand Down
7 changes: 7 additions & 0 deletions ui/app/styles/components/badge.scss
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,13 @@
background: rgb(var(--warning));
}

&--info {
@media (prefers-color-scheme: light) {
color: color.$ui-cool-gray-700;
background: color.$ui-cool-gray-100;
}
}

.icon {
width: scale.$base;
height: scale.$base;
Expand Down
5 changes: 5 additions & 0 deletions ui/app/styles/components/operation-status-indicator.scss
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,9 @@
&--error {
color: rgb(var(--error-text));
}

&--match-typography {
font-size: inherit;
font-weight: inherit;
}
}
Loading

0 comments on commit f95e34b

Please sign in to comment.