Skip to content

Commit

Permalink
feat: add event card to new ui (#1055)
Browse files Browse the repository at this point in the history
  • Loading branch information
adong authored May 22, 2024
1 parent 65e08cf commit c636204
Show file tree
Hide file tree
Showing 29 changed files with 753 additions and 58 deletions.
150 changes: 150 additions & 0 deletions app/components/newui-event-card/component.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
import Component from '@ember/component';
import { computed } from '@ember/object';
import { inject as service } from '@ember/service';
import { bool } from '@ember/object/computed';
import { statusIcon } from 'screwdriver-ui/utils/build';
import { getTimestamp } from 'screwdriver-ui/utils/timestamp-format';
import MAX_NUM_OF_PARAMETERS_ALLOWED from 'screwdriver-ui/utils/constants';

export default Component.extend({
router: service(),
userSettings: service(),
classNames: ['event-card'],
classNameBindings: ['highlighted'],
highlighted: false,
icon: computed('event.status', {
get() {
return statusIcon(this.get('event.status'), true);
}
}),
startDate: computed('event.createTime', {
get() {
let startDate = 'n/a';

startDate = getTimestamp(this.userSettings, this.get('event.createTime'));

return startDate;
}
}),
externalBuild: computed('event.{causeMessage,startFrom}', {
get() {
// using underscore because router.js doesn't pick up camelcase
/* eslint-disable camelcase */
let pipeline_id = this.get('event.startFrom').match(/^~sd@(\d+):[\w-]+$/);

let build_id = this.get('event.causeMessage').match(/\s(\d+)$/);

if (build_id) {
build_id = build_id[1];
}
if (pipeline_id) {
pipeline_id = pipeline_id[1];
}

return { build_id, pipeline_id };
/* eslint-enable camelcase */
}
}),
isExternalTrigger: computed('event.{pipelineId,startFrom}', {
get() {
const startFrom = this.get('event.startFrom');
const pipelineId = this.get('event.pipelineId');

let isExternal = false;

if (startFrom && startFrom.match(/^~sd@(\d+):([\w-]+)$/)) {
isExternal =
Number(startFrom.match(/^~sd@(\d+):([\w-]+)$/)[1]) !== pipelineId;
}

return isExternal;
}
}),
isCommitterDifferent: computed(
'isExternalTrigger',
'event.{creator.name,commit.author.name}',
{
get() {
const creatorName = this.get('event.creator.name');
const authorName = this.get('event.commit.author.name');

return this.isExternalTrigger || creatorName !== authorName;
}
}
),
isSubscribedEvent: bool('event.meta.subscribedSourceUrl'),

click() {
const eventId = this.event.id;
const { pipelineId } = this;

this.router.transitionTo(`/v2/pipelines/${pipelineId}/events/${eventId}`);
},
init() {
this._super(...arguments);

const pipelineParameters = {};
const jobParameters = {};

// Segregate pipeline level and job level parameters
Object.entries(
this.get('event.meta.parameters') === undefined
? {}
: this.get('event.meta.parameters')
).forEach(([propertyName, propertyVal]) => {
const keys = Object.keys(propertyVal);

if (keys.length === 1 && keys[0] === 'value') {
pipelineParameters[propertyName] = propertyVal;
} else {
jobParameters[propertyName] = propertyVal;
}
});

this.setProperties({
pipelineParameters,
jobParameters
});
},

numberOfParameters: computed(
'pipelineParameters',
'jobParameters',
function numberOfParameters() {
return (
Object.keys(this.pipelineParameters).length +
Object.values(this.jobParameters).reduce((count, parameters) => {
if (count) {
return count + Object.keys(parameters).length;
}

return Object.keys(parameters).length;
}, 0)
);
}
),

isInlineParameters: computed('numberOfParameters', {
get() {
return this.numberOfParameters < MAX_NUM_OF_PARAMETERS_ALLOWED;
}
}),

didReceiveAttrs() {
this._super();
const eventId = this.event.id;
const currentEventId = this.selectedEventId;

if (eventId === currentEventId) {
this.set('highlighted', true);
} else {
this.set('highlighted', false);
}
},

actions: {
toggleParametersPreview() {
this.toggleProperty('isShowingModal');
}
}
});
87 changes: 87 additions & 0 deletions app/components/newui-event-card/styles.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
& {
padding: 12px 24px;
cursor: pointer;

// darkmode
&.highlighted {
background-color: black;
color: white;

.sha {
> a {
color: white;
background-color: #007bff;
border-radius: 3px;
padding: 3px 5px;
}
}

.last-successful {
color: darkblue;
background-color: var(--blue-100, #020f1c);
}
}

.event-card-first-row {
display: flex;
align-items: center;
gap: 16px;

.event-status {
}

.sha {
> a {
border-radius: 3px;
padding: 3px 5px;
}

&:has(> .latest-commit) {
border-color: #007bff;
border-style: dotted;
border-width: 2px;
}
}

.branch {
.branch-name {
}
}

.last-successful {
border-radius: 6px;
padding: 0 8px;
background: var(--blue-100, #e1effe);
}
}

.label {
color: #9a9a9a;
}

.message {
font-size: 14px;
font-style: normal;
font-weight: 700;
// line-height: 21px;
grid-column: 1 / -1;
}

.time,
.duration {
font-size: 12px;
font-style: normal;
font-weight: 400;
line-height: 150%; /* 18px */
}

.by {
}

.parameters-section {
}

.builds > span {
padding-left: 12px;
}
}
125 changes: 125 additions & 0 deletions app/components/newui-event-card/template.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
<div class="event-card-first-row">
<div class="event-status" title={{this.event.status}}>
<div class="status">
<FaIcon
@icon={{this.icon.name}}
@fixedWidth="true"
@prefix={{this.icon.prefix}}
@spin={{this.icon.spin}}
@flip={{this.icon.flip}}
/>
</div>
</div>
<div class="sha" title={{truncate this.event.sha}}>
<a
class={{if (eq this.event.sha this.latestCommit.sha) "latest-commit"}}
href={{this.event.commit.url}}
>#{{this.event.truncatedSha}}
</a>
</div>
<div class="branch" title={{this.event.baseBranch}}>
<FaIcon @icon="code-branch" />
<span class="branch-name">{{truncate this.event.baseBranch 7 true}}</span>
</div>
{{#if (eq this.event.id this.lastSuccessful)}}
<div class="last-successful">Last Successful</div>
{{/if}}
</div>

<div class="message" title={{this.event.commit.message}}>{{this.event.truncatedMessage}} </div>

{{#if this.event.label}}
<div class="label">{{linkify this.event.label target="_blank" rel="nofollow" urlLength=30}}</div>{{/if}}

<div class="time">Started {{this.startDate.content}}</div>
<div class="duration">Duration: {{this.event.durationText}}</div>
<div class="by">
{{#if this.isCommitterDifferent}}
<span>
Committed by:
</span>
<a href={{this.event.commit.author.url}}>
{{this.event.commit.author.name}}
</a>
<br />
<span>
Started by:
</span>
{{#if this.isExternalTrigger}}
{{#if this.externalBuild.build_id}}
<LinkTo
@route="pipeline.build"
@models={{array this.externalBuild.pipeline_id this.externalBuild.build_id}}
>
External Trigger
</LinkTo>
{{else}}
<LinkTo @route="pipeline" @model={{this.externalBuild.pipeline_id}}>
External Trigger
</LinkTo>
{{/if}}
{{else}}
<a href={{this.event.creator.url}}>
{{this.event.creator.name}}
</a>
{{/if}}
{{else}}
{{#if this.isSubscribedEvent}}
<span>
Started by subscribed event:
</span>
<a href={{this.event.meta.subscribedSourceUrl}}>
Subscribed Source
</a>
{{else}}
<span>
Started and committed by:
</span>
<a href={{this.event.creator.url}}>
{{this.event.creator.name}}
</a>
{{/if}}
{{/if}}
</div>

{{#if (get-length this.event.meta.parameters)}}
<div class="parameters-section">
{{#if this.isShowingModal}}
<ModalDialog
@targetAttachment="center"
@translucentOverlay={{true}}
@clickOutsideToClose={{true}}
@onClickOverlay={{action "toggleParametersPreview"}}
@containerClass="detached-confirm-dialog"
>
<h3>
Parameters:
</h3>
<PipelineParameterizedBuild
@pipeline={{this.pipeline}}
@showSubmitButton={{true}}
@buildPipelineParameters={{this.pipelineParameters}}
@buildJobParameters={{this.jobParameters}}
@submitButtonText="Close"
@onSave={{action "toggleParametersPreview"}}
/>
</ModalDialog>
{{/if}}

<div class="parameters">
<span>
<button
class="btn btn-primary btn-xs"
type="button"
onClick={{action "toggleParametersPreview"}}
>
Parameters...
<span class="badge">
{{this.numberOfParameters}}
</span>
</button>
</span>
</div>
</div>
{{/if}}
{{yield}}
2 changes: 1 addition & 1 deletion app/components/pipeline/nav/template.hbs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<div class="pipeline-nav">
<LinkTo @route="v2.pipeline.builds" title="Builds">
<LinkTo @route="v2.pipeline.events" title="Events">
<FaIcon @icon="cubes" @size="16x" />
</LinkTo>
<LinkTo @route="v2.pipeline.secrets" title="Secrets">
Expand Down
6 changes: 5 additions & 1 deletion app/helpers/truncate.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,17 @@ import { helper } from '@ember/component/helper';
* @param {Array} params Array containing the text to truncate as the first element, and the maximum length as the second element.
* @return {String} The truncated text with an ellipsis if the length of the text exceeds the maximum length, or the original text if it does not.
*/
export function truncate([text, maxLength]) {
export function truncate([text, maxLength, hideEllipsis]) {
const ellipsis = '...';

if (!text || text.length <= maxLength) {
return text;
}

if (hideEllipsis) {
return `${text.substring(0, maxLength)}`;
}

return `${text.substring(0, maxLength)}${ellipsis}`;
}

Expand Down
Loading

0 comments on commit c636204

Please sign in to comment.