// Copyright 2018 Red Hat, Inc // // 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 * as React from 'react' import PropTypes from 'prop-types' import { connect } from 'react-redux' import { Link } from 'react-router-dom' import { Checkbox, Badge, Form, FormGroup, FormControl, Icon, TreeView } from 'patternfly-react' class JobsList extends React.Component { static propTypes = { tenant: PropTypes.object, jobs: PropTypes.array, } state = { filter: null, flatten: false, } handleKeyPress = (e) => { if (e.charCode === 13) { this.setState({filter: e.target.value}) e.preventDefault() e.target.blur() } } render () { const { jobs } = this.props const { filter, flatten } = this.state const linkPrefix = this.props.tenant.linkPrefix + '/job/' // job index map const jobMap = {} // nodes contains the tree data const nodes = [] // visited contains individual node const visited = {} // createNode returns the actual node needed by the tree view component const createNode = (job, extra) => ({ text: ( {job.name} {extra && ( ({extra}))} {job.description && ( {job.description} )} {job.tags && job.tags.map((tag, idx) => ( {tag} ))} ), icon: 'fa fa-cube', state: { expanded: true, }, }) // getNode returns the tree node and visit each parents const getNode = function (job, filtered) { if (!visited[job.name]) { // Collect parents let parents = [] if (job.variants) { for (let jobVariant of job.variants) { if (jobVariant.parent && parents.indexOf(jobVariant.parent) === -1) { parents.push(jobVariant.parent) } } } visited[job.name] = createNode(job, null) visited[job.name].parents = parents visited[job.name].filtered = filtered // Visit parent recursively if (!flatten) { for (let parent of parents) { if (jobMap[parent]) { getNode(jobMap[parent], filtered) } } } } return visited[job.name] } // index job list for (let job of jobs) { jobMap[job.name] = job } // filter job let filtered = false if (filter) { filtered = true let filters = filter.replace(/ +/g, ',').split(',') for (let job of jobs) { filters.forEach(jobFilter => { if (jobFilter && ( (job.name.indexOf(jobFilter) !== -1) || (job.description && job.description.indexOf(jobFilter) !== -1))) { getNode(job, !filtered) } }) } } // process job list for (let job of jobs) { const jobNode = getNode(job, filtered) if (!jobNode.filtered) { let attached = false if (!flatten) { // add tree node to each parent and expand the parent for (let parent of jobNode.parents) { const parentNode = visited[parent] if (!parentNode) { console.log( 'Job ', job.name, ' parent ', parent, ' does not exist!') continue } if (!parentNode.nodes) { parentNode.nodes = [] } if (attached) { // We need to create a duplicate node to satisfy TreeView constrains for multi parent parentNode.nodes.push(createNode(job, 'branched')) } else { parentNode.nodes.push(jobNode) } attached = true } } // else add node at the tree root if (!attached || jobNode.parents.length === 0) { nodes.push(jobNode) } } } return (
this.filter = i} onKeyPress={this.handleKeyPress} /> {filter && ( {this.setState({filter: ''}) this.filter.value = ''}} style={{cursor: 'pointer', zIndex: 10, pointerEvents: 'auto'}} >   )}   Flatten list   this.setState({flatten: e.target.checked})} />
) } } export default connect(state => ({ tenant: state.tenant, }))(JobsList)