// 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 (