Skip to content

Commit

Permalink
Continue moving components to @tektoncd/dashboard-components
Browse files Browse the repository at this point in the history
This also involves restructuring some of the components so they
no longer embed containers. In these cases, the containers are
passed as props by the parent so the components remain purely
presentational and are more easily reused outside the context of
the dashboard application.

- new presentational component for PipelineRuns list (excludes
  create button/dialog, etc.)
  - stories and tests for this too, which we didn't have before
- pass the Rebuild button as a prop to RunHeader (making RunHeader
  a purely presentational component, also fixes a bug where we
  displayed the Rebuild button in some cases where we didn't have
  enough info to rebuild)
- pass the Log container as a prop to StepDetails (making
  StepDetails a purely presentational component)
- the rest of the components just needed a `git mv` and update the
  import references
  • Loading branch information
AlanGreene authored and tekton-robot committed Aug 16, 2019
1 parent 056259c commit bcfe703
Show file tree
Hide file tree
Showing 88 changed files with 649 additions and 327 deletions.
1 change: 1 addition & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions packages/components/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"@carbon/icons-react": "^10.3.0",
"@tektoncd/dashboard-utils": "file:../utils",
"ansi-to-react": "^5.0.0",
"js-yaml": "^3.13.0",
"prop-types": "^15.7.2",
"react-window": "^1.8.5"
},
Expand Down
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@ limitations under the License.

import React from 'react';
import { InlineNotification } from 'carbon-components-react';

import { getErrorMessage } from '../../utils';
import { getErrorMessage } from '@tektoncd/dashboard-utils';

class ErrorBoundary extends React.Component {
state = { error: null };
Expand Down
File renamed without changes.
148 changes: 148 additions & 0 deletions packages/components/src/components/PipelineRuns/PipelineRuns.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
/*
Copyright 2019 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
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

import React from 'react';
import { injectIntl } from 'react-intl';
import { Link } from 'react-router-dom';
import {
StructuredListBody,
StructuredListCell,
StructuredListHead,
StructuredListRow,
StructuredListWrapper
} from 'carbon-components-react';
import {
ALL_NAMESPACES,
getStatus,
getStatusIcon,
isRunning,
urls
} from '@tektoncd/dashboard-utils';

import { CancelButton } from '..';

import './PipelineRuns.scss';

const PipelineRuns = ({
cancelPipelineRun,
intl,
pipelineName,
pipelineRuns,
selectedNamespace
}) => (
<StructuredListWrapper border selection>
<StructuredListHead>
<StructuredListRow head>
<StructuredListCell head>PipelineRun</StructuredListCell>
{!pipelineName && (
<StructuredListCell head>Pipeline</StructuredListCell>
)}
{selectedNamespace === ALL_NAMESPACES && (
<StructuredListCell head>Namespace</StructuredListCell>
)}
<StructuredListCell head>
{intl.formatMessage({
id: 'dashboard.pipelineRuns.status',
defaultMessage: 'Status'
})}
</StructuredListCell>
<StructuredListCell head>
{intl.formatMessage({
id: 'dashboard.pipelineRuns.transitionTime',
defaultMessage: 'Last Transition Time'
})}
</StructuredListCell>
<StructuredListCell head />
</StructuredListRow>
</StructuredListHead>
<StructuredListBody>
{!pipelineRuns.length && (
<StructuredListRow>
<StructuredListCell>
{pipelineName ? (
<span>No PipelineRuns for {pipelineName}</span>
) : (
<span>No PipelineRuns</span>
)}
</StructuredListCell>
</StructuredListRow>
)}
{pipelineRuns.map(pipelineRun => {
const { name: pipelineRunName, namespace } = pipelineRun.metadata;
const pipelineRefName = pipelineRun.spec.pipelineRef.name;
const { lastTransitionTime, reason, status } = getStatus(pipelineRun);

return (
<StructuredListRow
className="definition"
key={pipelineRun.metadata.uid}
>
<StructuredListCell>
<Link
to={urls.pipelineRuns.byName({
namespace,
pipelineName: pipelineRefName,
pipelineRunName
})}
>
{pipelineRunName}
</Link>
</StructuredListCell>
{!pipelineName && (
<StructuredListCell>
<Link
to={urls.pipelineRuns.byPipeline({
namespace,
pipelineName: pipelineRefName
})}
>
{pipelineRefName}
</Link>
</StructuredListCell>
)}
{selectedNamespace === ALL_NAMESPACES && (
<StructuredListCell>{namespace}</StructuredListCell>
)}
<StructuredListCell
className="status"
data-reason={reason}
data-status={status}
>
{getStatusIcon({ reason, status })}
{pipelineRun.status.conditions
? pipelineRun.status.conditions[0].message
: ''}
</StructuredListCell>
<StructuredListCell>{lastTransitionTime}</StructuredListCell>
<StructuredListCell>
{isRunning(reason, status) && (
<CancelButton
type="PipelineRun"
name={pipelineRunName}
onCancel={() =>
cancelPipelineRun({
name: pipelineRunName,
namespace
})
}
/>
)}
</StructuredListCell>
</StructuredListRow>
);
})}
</StructuredListBody>
</StructuredListWrapper>
);

export default injectIntl(PipelineRuns);
45 changes: 45 additions & 0 deletions packages/components/src/components/PipelineRuns/PipelineRuns.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
Copyright 2019 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
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

@import '../../scss/vars';

.definition .status {
.status-icon {
margin-right: 0.5em;
vertical-align: sub;
}

&:not([data-status]) {
.status-icon {
fill: $unknown;
}
}

&[data-status='True'] {
.status-icon {
fill: $success;
}
}

&[data-status='False'] {
.status-icon {
fill: $failed;
}
}

&[data-status='Unknown'][data-reason='Running'] {
.status-icon {
fill: $running;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/*
Copyright 2019 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
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

import React from 'react';
import { storiesOf } from '@storybook/react';
import StoryRouter from 'storybook-react-router';

import PipelineRuns from '.';

storiesOf('PipelineRuns', module)
.addDecorator(StoryRouter())
.add('default', () => (
<PipelineRuns
pipelineName="Pipeline Name"
selectedNamespace="default"
pipelineRuns={[
{
metadata: {
name: 'pipeline-run-20190816124708',
namespace: 'cb4552a6-b2d7-45e2-9773-3d4ca33909ff',
uid: '7c266264-4d4d-45e3-ace0-041be8f7d06e'
},
spec: {
pipelineRef: {
name: 'pipeline'
}
},
status: {
conditions: [
{
lastTransitionTime: '2019-08-16T12:49:28Z',
message: 'All Tasks have completed executing',
reason: 'Succeeded',
status: 'True',
type: 'Succeeded'
}
]
}
},
{
metadata: {
name: 'pipeline-run-20190816170431',
namespace: '21cf1eac-7392-4e67-a4d0-f654506fe04d',
uid: 'a7812005-f766-4877-abd4-b3d418b04f66'
},
spec: {
pipelineRef: {
name: 'pipeline'
}
},
status: {
conditions: [
{
lastTransitionTime: '2019-08-16T17:10:49Z',
message: 'Not all Tasks have completed executing',
reason: 'Running',
status: 'Unknown',
type: 'Succeeded'
}
]
}
}
]}
cancelPipelineRun={() => {}}
/>
))
.add('empty', () => (
<PipelineRuns
pipelineName="Pipeline Name"
selectedNamespace="default"
pipelineRuns={[]}
cancelPipelineRun={() => {}}
/>
));
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/*
Copyright 2019 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
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

import React from 'react';
import { ALL_NAMESPACES } from '@tektoncd/dashboard-utils';

import { renderWithIntl, renderWithRouter } from '../../utils/test';
import PipelineRuns from './PipelineRuns';

it('PipelineRuns renders empty state', () => {
const { queryByText } = renderWithIntl(<PipelineRuns pipelineRuns={[]} />);
expect(queryByText(/no pipelineruns/i)).toBeTruthy();
expect(queryByText(/namespace/i)).toBeFalsy();
});

it('PipelineRuns renders optional columns', () => {
const { queryByText } = renderWithIntl(
<PipelineRuns
pipelineName="some-pipeline"
pipelineRuns={[]}
selectedNamespace={ALL_NAMESPACES}
/>
);
expect(queryByText(/namespace/i)).toBeTruthy();
expect(queryByText(/pipeline/i)).toBeTruthy();
expect(queryByText(/no pipelineruns for some-pipeline/i)).toBeTruthy();
});

it('PipelineRuns renders data', () => {
const pipelineRunName = 'pipeline-run-20190816124708';
const { queryByText } = renderWithRouter(
<PipelineRuns
pipelineRuns={[
{
metadata: {
name: pipelineRunName,
namespace: 'cb4552a6-b2d7-45e2-9773-3d4ca33909ff',
uid: '7c266264-4d4d-45e3-ace0-041be8f7d06e'
},
spec: {
pipelineRef: {
name: 'pipeline'
}
},
status: {
conditions: [
{
lastTransitionTime: '2019-08-16T12:49:28Z',
message: 'All Tasks have completed executing',
reason: 'Succeeded',
status: 'True',
type: 'Succeeded'
}
]
}
}
]}
/>
);
expect(queryByText(pipelineRunName)).toBeTruthy();
expect(queryByText(/all tasks have completed executing/i)).toBeTruthy();
});
14 changes: 14 additions & 0 deletions packages/components/src/components/PipelineRuns/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/*
Copyright 2019 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
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

export default from './PipelineRuns';
Loading

0 comments on commit bcfe703

Please sign in to comment.