Skip to content

Commit

Permalink
Update design of runs pages
Browse files Browse the repository at this point in the history
Update the table layout used for the PipelineRuns and TaskRuns pages
to include more useful information such as trigger info, status details,
and combine fields where this makes sense (e.g. created time + duration).
  • Loading branch information
AlanGreene committed May 10, 2022
1 parent ee5a38e commit 7f96ee0
Show file tree
Hide file tree
Showing 25 changed files with 547 additions and 234 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,37 @@ describe('Actions with modal', () => {
await waitFor(() => getByText('Action'));
fireEvent.click(getByText(`Action`));
await waitFor(() => getByText('primary'));
getByText('secondary');
fireEvent.click(getByText(`primary`));
expect(mockCallBack).toHaveBeenCalled();
});

it('Actions with modal default button text', async () => {
const mockCallBack = jest.fn();
const items = [
{
actionText: 'Action',
action: () => mockCallBack(),
disable: () => false,
modalProperties: {
heading: 'Modal Heading',
primaryButtonText: 'primary',
body: () => 'modal body'
}
},
{
actionText: 'Other',
action: () => {}
}
];
const { getByText, getAllByTitle } = render(
<Actions items={items} resource={resource} />
);
fireEvent.click(getAllByTitle('Actions')[0]);
await waitFor(() => getByText('Action'));
fireEvent.click(getByText(`Action`));
await waitFor(() => getByText('primary'));
getByText('Cancel');
fireEvent.click(getByText(`primary`));
expect(mockCallBack).toHaveBeenCalled();
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright 2019-2021 The Tekton Authors
Copyright 2019-2022 The Tekton Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
Expand Down Expand Up @@ -132,7 +132,7 @@ describe('DetailsHeader', () => {
<DetailsHeader {...props} stepStatus={stepStatus} />
);
expect(queryByText(/duration/i)).toBeTruthy();
expect(queryByText(/0 seconds/i)).toBeTruthy();
expect(queryByText(/0s/i)).toBeTruthy();
});

it('renders no duration for a waiting step', () => {
Expand Down
39 changes: 22 additions & 17 deletions packages/components/src/components/FormattedDate/FormattedDate.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright 2019 The Tekton Authors
Copyright 2019-2022 The Tekton Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
Expand All @@ -14,7 +14,12 @@ limitations under the License.
import React from 'react';
import { FormattedDate, FormattedRelativeTime, injectIntl } from 'react-intl';

const FormattedDateWrapper = ({ date, intl, relative }) => {
const FormattedDateWrapper = ({
date,
formatTooltip = formattedDate => formattedDate,
intl,
relative
}) => {
if (!date) {
return null;
}
Expand All @@ -30,31 +35,31 @@ const FormattedDateWrapper = ({ date, intl, relative }) => {
/>
);
} else {
const yearFormat =
new Date().getFullYear() !== new Date(date).getFullYear()
? 'numeric'
: undefined;
content = (
<FormattedDate
value={date}
day="numeric"
month="long"
year="numeric"
month="short"
year={yearFormat}
hour="numeric"
minute="numeric"
/>
);
}

return (
<span
title={intl.formatDate(date, {
day: 'numeric',
month: 'long',
year: 'numeric',
hour: 'numeric',
minute: 'numeric'
})}
>
{content}
</span>
);
const formattedDate = intl.formatDate(date, {
day: 'numeric',
month: 'long',
year: 'numeric',
hour: 'numeric',
minute: 'numeric'
});

return <span title={formatTooltip(formattedDate)}>{content}</span>;
};

export default injectIntl(FormattedDateWrapper);
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright 2019-2021 The Tekton Authors
Copyright 2019-2022 The Tekton Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
Expand All @@ -23,7 +23,16 @@ describe('FormattedDate', () => {

it('handles absolute date formatting', () => {
const { queryByText } = render(<FormattedDate date="2019/12/01" />);
expect(queryByText(/December 1, 2019/i)).toBeTruthy();
expect(queryByText(/Dec 1, 2019/i)).toBeTruthy();
});

it('handles absolute date formatting for current year', () => {
const currentYear = new Date().getFullYear();
const { queryByText } = render(
<FormattedDate date={`${currentYear}/12/01`} />
);
expect(queryByText(currentYear)).toBeFalsy();
expect(queryByText(/Dec 1/i)).toBeTruthy();
});

it('handles relative date formatting', () => {
Expand All @@ -34,6 +43,6 @@ describe('FormattedDate', () => {
<FormattedDate date="2019/12/01" relative />
);
expect(container.firstChild).not.toBeNull();
expect(queryByText(/December 1, 2019/i)).toBeFalsy();
expect(queryByText(/Dec 1, 2019/i)).toBeFalsy();
});
});
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright 2019-2020 The Tekton Authors
Copyright 2019-2022 The Tekton Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
Expand All @@ -12,7 +12,7 @@ limitations under the License.
*/

import React, { Component } from 'react';
import { defineMessages } from 'react-intl';
import { defineMessages, injectIntl } from 'react-intl';
import FormattedDuration from 'react-intl-formatted-duration';

defineMessages({
Expand All @@ -38,20 +38,40 @@ defineMessages({
}
});

export default class FormattedDurationWrapper extends Component {
class FormattedDurationWrapper extends Component {
state = { tooltip: '' };

componentDidMount() {
const { intl } = this.props;
const tooltip = intl.formatMessage(
{
id: 'dashboard.run.duration',
defaultMessage: 'Duration: {duration}'
},
{
duration: this.durationNode?.textContent
}
);
this.setState({
tooltip: this.durationNode && this.durationNode.textContent
tooltip
});
}

componentDidUpdate() {
const { intl } = this.props;
const duration = this.durationNode.textContent;
if (this.state.tooltip !== duration) {
const tooltip = intl.formatMessage(
{
id: 'dashboard.run.duration',
defaultMessage: 'Duration: {duration}'
},
{
duration
}
);
if (this.state.tooltip !== tooltip) {
this.setState({ // eslint-disable-line
tooltip: duration
tooltip
});
}
}
Expand All @@ -66,10 +86,13 @@ export default class FormattedDurationWrapper extends Component {
title={this.state.tooltip}
>
<FormattedDuration
seconds={milliseconds / 1000}
format="{days} {hours} {minutes} {seconds}"
seconds={milliseconds / 1000}
unitDisplay="narrow"
/>
</span>
);
}
}

export default injectIntl(FormattedDurationWrapper);
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright 2020-2021 The Tekton Authors
Copyright 2020-2022 The Tekton Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
Expand All @@ -20,11 +20,11 @@ describe('FormattedDuration', () => {
const { getByText, getByTitle, rerender } = render(
<FormattedDuration milliseconds={1000} />
);
expect(getByText(/1 second/i)).toBeTruthy();
expect(getByTitle(/1 second/i)).toBeTruthy();
expect(getByText(/1s/i)).toBeTruthy();
expect(getByTitle(/1s/i)).toBeTruthy();

render(<FormattedDuration milliseconds={2000} />, { rerender });
expect(getByText(/2 seconds/i)).toBeTruthy();
expect(getByTitle(/2 seconds/i)).toBeTruthy();
expect(getByText(/2s/i)).toBeTruthy();
expect(getByTitle(/2s/i)).toBeTruthy();
});
});
Loading

0 comments on commit 7f96ee0

Please sign in to comment.