Skip to content

Commit

Permalink
Support Triggers 0.2 features in the Dashboard
Browse files Browse the repository at this point in the history
Fixes #944

Updates the EventListener details page with the following:
- Multiple Interceptors
- Multiple TriggerBindings
- No more params
- Display all 4 built-in types of Interceptors (Webhook, GitHub, GitLab,
and CEL)
  • Loading branch information
Brandon Walker committed Feb 4, 2020
1 parent a0866ee commit 550c3f1
Show file tree
Hide file tree
Showing 5 changed files with 433 additions and 124 deletions.
272 changes: 174 additions & 98 deletions packages/components/src/components/Trigger/Trigger.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,15 @@ See the License for the specific language governing permissions and
limitations under the License.
*/

import LinkIcon from '@carbon/icons-react/lib/launch/16';
import { injectIntl } from 'react-intl';
import React from 'react';
import { urls } from '@tektoncd/dashboard-utils';
import { Link } from 'react-router-dom';
import './Trigger.scss';
import { Accordion, AccordionItem } from 'carbon-components-react';
import { Table } from '@tektoncd/dashboard-components';

import './Trigger.scss';

const Trigger = ({ intl, eventListenerNamespace, trigger }) => {
const tableHeaders = [
{
Expand All @@ -37,119 +38,194 @@ const Trigger = ({ intl, eventListenerNamespace, trigger }) => {
}
];

let triggerParams = [];

if (trigger.params) {
triggerParams = trigger.params.map(param => ({
id: param.name,
name: param.name,
value: param.value
}));
}

let interceptorValues = [];

if (trigger.interceptor) {
if (trigger.interceptor.header) {
interceptorValues = trigger.interceptor.header.map(header => ({
id: header.name,
name: header.name,
value: header.value
}));
}
}

return (
<>
<div className="triggermain">
<h3>Trigger: {trigger.name}</h3>
<div className="triggerresourcelinks">
<span className="resourcekind">TriggerBinding</span>
<Link
to={urls.triggerBindings.byName({
namespace: eventListenerNamespace,
triggerBindingName: trigger.binding.name
})}
>
<span className="linkicon">
<LinkIcon />
</span>
<span className="truncate-text-end" title={trigger.binding.name}>
{trigger.binding.name}
</span>
</Link>
<div className="triggerdetails">
<div className="triggerresourcelinks">
<span className="resourcekind">TriggerBindings:</span>
<div>
{trigger.bindings &&
trigger.bindings.map((binding, index) => (
<span>
<Link
className="triggerresourcelink"
to={urls.triggerBindings.byName({
namespace: eventListenerNamespace,
triggerBindingName: binding.name
})}
>
<span title={binding.name}>{binding.name}</span>
</Link>
{index !== trigger.bindings.length - 1 && <span>, </span>}
</span>
))}
</div>
</div>
</div>
<div className="triggerresourcelinks">
<span className="resourcekind">TriggerTemplate</span>
<span className="resourcekind">TriggerTemplate:</span>

<Link
className="triggerresourcelink"
to={urls.triggerTemplates.byName({
namespace: eventListenerNamespace,
triggerTemplateName: trigger.template.name
})}
>
<span className="linkicon">
<LinkIcon />
</span>
<span className="truncate-text-end" title={trigger.template.name}>
{trigger.template.name}
</span>
<span title={trigger.template.name}>{trigger.template.name}</span>
</Link>
</div>

<div className="triggerinfo">
<h3>
{intl.formatMessage({
id: 'dashboard.triggerDetails.triggerParameters',
defaultMessage: 'Parameters'
})}
</h3>

<Table
className="parameterstable"
headers={tableHeaders}
rows={triggerParams}
emptyTextAllNamespaces={intl.formatMessage({
id: 'dashboard.trigger.noParams',
defaultMessage: 'No parameters found for this Trigger.'
})}
emptyTextSelectedNamespace={intl.formatMessage({
id: 'dashboard.trigger.noParams',
defaultMessage: 'No parameters found for this Trigger.'
})}
/>
{trigger.interceptor && (
<>
<div className="interceptor">
<h3>
{intl.formatMessage({
id: 'dashboard.triggerDetails.interceptorName',
defaultMessage: 'Interceptor: '
})}
{trigger.interceptor.objectRef.name}
</h3>
<h3>
{intl.formatMessage({
id: 'dashboard.triggerDetails.interceptorHeaders',
defaultMessage: 'Headers'
})}
</h3>
</div>
<Table
headers={tableHeaders}
rows={interceptorValues}
emptyTextAllNamespaces={intl.formatMessage({
id: 'dashboard.trigger.noHeaders',
defaultMessage: 'No headers found for this interceptor.'
})}
emptyTextSelectedNamespace={intl.formatMessage({
id: 'dashboard.trigger.noHeaders',
defaultMessage: 'No headers found for this interceptor.'
})}
isSortable={false}
/>
</>
)}
<span className="resourcekind">Interceptors:</span>
<Accordion className="interceptorsaccordian" title="Interceptors">
{trigger.interceptors &&
trigger.interceptors.map((interceptor, index) => {
let title;
let content;
const namespaceText = intl.formatMessage({
id: 'dashboard.triggerDetails.webhookInterceptorNamespace',
defaultMessage: 'Namespace:'
});
const nameText = intl.formatMessage({
id: 'dashboard.triggerDetails.webhookInterceptorName',
defaultMessage: 'Name:'
});
if (interceptor.webhook) {
// Webhook Interceptor
if (!interceptor.webhook.objectRef) {
return null;
}
title = `${intl.formatMessage({
id: 'dashboard.triggerDetails.webhookInterceptorName',
defaultMessage: '(Webhook)'
})} ${interceptor.webhook.objectRef.name}`;
let headerValues = [];
if (interceptor.webhook.header) {
headerValues = interceptor.webhook.header.map(header => {
const headerValue = {
id: header.name,
name: header.name,
value: header.value
};
// Concatenate values with a comma if value is an array
if (Array.isArray(header.value)) {
headerValue.value = header.value.join(', ');
}
return headerValue;
});
}
const serviceText = intl.formatMessage({
id: 'dashboard.triggerDetails.webhookInterceptorService',
defaultMessage: 'Service:'
});
content = (
<>
<p>{serviceText}</p>
<div className="interceptor--service-details">
<p>
{nameText} {interceptor.webhook.objectRef.name}
</p>
{interceptor.webhook.objectRef.namespace && (
<p>
{namespaceText}{' '}
{interceptor.webhook.objectRef.namespace}
</p>
)}
</div>
<p>
{intl.formatMessage({
id: 'dashboard.triggerDetails.interceptorHeaders',
defaultMessage: 'Headers:'
})}
</p>
<Table
headers={tableHeaders}
rows={headerValues}
emptyTextAllNamespaces={intl.formatMessage({
id: 'dashboard.trigger.noHeaders',
defaultMessage:
'No headers found for this interceptor.'
})}
emptyTextSelectedNamespace={intl.formatMessage({
id: 'dashboard.trigger.noHeaders',
defaultMessage:
'No headers found for this interceptor.'
})}
isSortable={false}
/>
</>
);
} else if (interceptor.github || interceptor.gitlab) {
let data;
let titlePrefix;
if (interceptor.github) {
// GitHub Interceptor
data = interceptor.github;
titlePrefix = intl.formatMessage({
id: 'dashboard.triggerDetails.githubInterceptorName',
defaultMessage: '(GitHub)'
});
} else {
// GitLab Interceptor
data = interceptor.gitlab;
titlePrefix = intl.formatMessage({
id: 'dashboard.triggerDetails.gitlabInterceptorName',
defaultMessage: '(GitLab)'
});
}
const eventTypes = data.eventTypes.join(', ');
title = `${titlePrefix} ${eventTypes}`;
const secretText = intl.formatMessage({
id: 'dashboard.triggerDetails.webhookInterceptorSecret',
defaultMessage: 'Secret:'
});
content = (
<>
<p>{secretText}</p>
<div className="interceptor--secret-details">
<p>
{nameText} {data.secretRef.secretName}
</p>
{data.secretRef.namespace && (
<p>
{namespaceText} {data.secretRef.namespace}
</p>
)}
</div>
<p>Event Types: {eventTypes}</p>
</>
);
} else if (interceptor.cel) {
// CEL Interceptor
title = `${intl.formatMessage({
id: 'dashboard.triggerDetails.celInterceptorName',
defaultMessage: '(CEL)'
})} ${interceptor.cel.filter}`;
const filter = intl.formatMessage({
id: 'dashboard.triggerDetails.celInterceptorName',
defaultMessage: 'Filter: '
});
content = (
<>
<p>{filter}</p>
<code className="bx--snippet--multi interceptor--cel-filter">
{interceptor.cel.filter}
</code>
</>
);
} else {
return null;
}
return (
<AccordionItem title={`${index + 1}. ${title}`}>
{content}
</AccordionItem>
);
})}
</Accordion>
</div>
</div>
</>
Expand Down
55 changes: 32 additions & 23 deletions packages/components/src/components/Trigger/Trigger.scss
Original file line number Diff line number Diff line change
Expand Up @@ -20,41 +20,50 @@ limitations under the License.
border-bottom: 0.5px dotted grey;
}

.interceptor h3 {
margin: 5px;
padding: 10px;
.triggerinfo {
margin-top: $spacing-05;

.interceptorsaccordian {
margin-top: $spacing-03;
}
}

.triggerinfo h3 {
margin: 5px;
padding: 10px;
.triggerdetails {
margin-top: $spacing-05;
}

.triggerresourcelinks {
margin: 10px;
padding: 10px;
display: grid;
grid-template-columns: 100px 500px 100px;
margin-top: $spacing-03;
grid-template-columns: 100px 500px;
grid-gap: 30px;

.linkicon {
margin-right: 1rem;
}
line-height: 1.5rem;

.resourcekind {
font-weight: bold;
font-weight: auto;
}

a {
display: flex;
overflow: hidden;
white-space: nowrap;

.triggerresourcelink {
display: inline-block;
overflow: visible;
}
}

.truncate-text-end {
.interceptor--cel-filter {
display: inline-block;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}

.interceptor--secret-details {
margin-left: $spacing-04;
}

.interceptor--service-details {
margin-left: $spacing-04;
}

// .truncate-text-end {
// display: inline-block;
// overflow: hidden;
// text-overflow: ellipsis;
// white-space: nowrap;
// }
Loading

0 comments on commit 550c3f1

Please sign in to comment.