diff --git a/frontend/src/components/index.js b/frontend/src/components/index.js index b266a34d..bcbb0cde 100644 --- a/frontend/src/components/index.js +++ b/frontend/src/components/index.js @@ -5,7 +5,6 @@ export { EmptyObject } from './empty-object'; export { FilterTable, MetaFilter } from './filtertable'; export { IbutsuPage } from './ibutsu-page'; export { MultiValueInput } from './multivalueinput'; -export { ParamDropdown } from './widget-components'; export { ResultView } from './result'; export { RunSummary } from './runsummary'; export { TableEmptyState, TableErrorState } from './tablestates'; diff --git a/frontend/src/components/param-dropdown.js b/frontend/src/components/param-dropdown.js new file mode 100644 index 00000000..799f1155 --- /dev/null +++ b/frontend/src/components/param-dropdown.js @@ -0,0 +1,79 @@ +import React, { useEffect, useState } from 'react'; +import PropTypes from 'prop-types'; +import { + Dropdown, + DropdownItem, + DropdownList, + MenuToggle, + Text, + Tooltip +} from '@patternfly/react-core'; + + +const ParamDropdown = (props) => { + const { + defaultValue, + handleSelect, + tooltip, + dropdownItems + } = props; + + const [isOpen, setIsOpen] = useState(false); + const [value, setValue] = useState(defaultValue || 'Group data by?'); + + const dropOnSelect = (event) => { + setIsOpen(!isOpen); + handleSelect(event.target.innerText); + setValue(event.target.innerText); + } + + useEffect(()=>{ + setValue(defaultValue) + }, [defaultValue, setValue]) + + return ( + // TODO this formatting of the dropdown labels is ugly as hell + +
+ {tooltip} + + setIsOpen(false)} + toggle={toggleRef => ( + setIsOpen(!isOpen)} + isExpanded={isOpen} + > + {value} + + )} + ouiaId="BasicDropdown" + shouldFocusToggleOnSelect + > + + {dropdownItems && dropdownItems.map((item) => ( + + {item} + + ))} + <> + + + +
+
+ ); +}; + +ParamDropdown.propTypes = { + defaultValue: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), + dropdownItems: PropTypes.array, + handleSelect: PropTypes.func, + tooltip: PropTypes.string +}; + +export default ParamDropdown; diff --git a/frontend/src/components/widget-components.js b/frontend/src/components/widget-components.js deleted file mode 100644 index 72f440c0..00000000 --- a/frontend/src/components/widget-components.js +++ /dev/null @@ -1,143 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import { - Button, - CardHeader, - Dropdown, - DropdownItem, - DropdownList, - MenuToggle, - Text, - Tooltip -} from '@patternfly/react-core'; -import { PficonHistoryIcon, TimesIcon, PencilAltIcon } from '@patternfly/react-icons'; - - -export class WidgetHeader extends React.Component { - static propTypes = { - id: PropTypes.string, - getDataFunc: PropTypes.func, - onDeleteClick: PropTypes.func, - title: PropTypes.string, - actions: PropTypes.object, - onEditClick: PropTypes.func - } - - - render () { - const { title, getDataFunc, actions, onDeleteClick, onEditClick } = this.props; - const headerActions = ( - <> - {actions} - {getDataFunc && - - } - {onEditClick && - - } - {onDeleteClick && - - } - - ); - - return ( - - {title} - - ); - } -} - - -export class ParamDropdown extends React.Component { - // parameter dropdown for changing widget params in the FE - static propTypes = { - defaultValue: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), - description: PropTypes.string, - dropdownItems: PropTypes.array, - handleSelect: PropTypes.func, - showDescription: PropTypes.bool, - tooltip: PropTypes.string - } - - constructor(props) { - super(props); - this.onSelect = this.onSelect.bind(this); - this.onToggle = this.onToggle.bind(this); - this.state = { - isOpen: false, - value: props.defaultValue || 'Group data by?', - showDescription: props.showDescription || true - }; - } - - onToggle = () => { - this.setState({isOpen: !this.state.isOpen}); - } - - - onSelect = (event) => { - this.setState({ - isOpen: !this.state.isOpen, - }); - this.props.handleSelect(event.target.innerText); - this.setState({ - value: event.target.innerText - }); - } - - componentDidUpdate(prevProps) { - if (prevProps !== this.props) { - this.setState({ - value: this.props.defaultValue - }); - } - } - - render() { - const { isOpen } = this.state; - const { showDescription } = this.state; - - return ( -
- {showDescription && - {this.props.description || this.props.tooltip || ''} - } - - this.setState({isOpen: false})} - toggle={toggleRef => ( - - {this.state.value} - - )} - ouiaId="BasicDropdown" - shouldFocusToggleOnSelect - > - - {this.props.dropdownItems.map((item) => ( - - {item} - - ))} - - - -
- ); - } -} diff --git a/frontend/src/components/widget-header.js b/frontend/src/components/widget-header.js new file mode 100644 index 00000000..0fa8578d --- /dev/null +++ b/frontend/src/components/widget-header.js @@ -0,0 +1,57 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { + Button, + CardHeader, + Title, +} from '@patternfly/react-core'; +import { PficonHistoryIcon, TimesIcon, PencilAltIcon } from '@patternfly/react-icons'; + +const WidgetHeader = (props) => { + const { + id, + getDataFunc, + onDeleteClick, + title, + actions, + onEditClick + } = props; + + const headerActions = ( + + {actions ? actions : []} + {getDataFunc && + + } + {onEditClick && + + } + {onDeleteClick && + + } + + ); + + return ( + + {title} + + ); +} + +WidgetHeader.propTypes = { + id: PropTypes.string, + getDataFunc: PropTypes.func, + onDeleteClick: PropTypes.func, + title: PropTypes.string, + actions: PropTypes.array, + onEditClick: PropTypes.func +} + +export default WidgetHeader; diff --git a/frontend/src/views/jenkinsjobanalysis.js b/frontend/src/views/jenkinsjobanalysis.js index e350f603..ed1d75c7 100644 --- a/frontend/src/views/jenkinsjobanalysis.js +++ b/frontend/src/views/jenkinsjobanalysis.js @@ -12,9 +12,9 @@ import { parseFilter, } from '../utilities'; import { FilterHeatmapWidget, GenericAreaWidget, GenericBarWidget } from '../widgets'; -import { ParamDropdown } from '../components'; import { HEATMAP_MAX_BUILDS } from '../constants' import { IbutsuContext } from '../services/context'; +import ParamDropdown from '../components/param-dropdown'; export class JenkinsJobAnalysisView extends React.Component { @@ -114,11 +114,12 @@ export class JenkinsJobAnalysisView extends React.Component { if (activeTab === 'heatmap') { defaultValue = Math.min(defaultValue, HEATMAP_MAX_BUILDS); } - return (); } diff --git a/frontend/src/widgets/filterheatmap.js b/frontend/src/widgets/filterheatmap.js index 054950aa..5ce5df07 100644 --- a/frontend/src/widgets/filterheatmap.js +++ b/frontend/src/widgets/filterheatmap.js @@ -22,7 +22,8 @@ import HeatMap from 'react-heatmap-grid'; import { HttpClient } from '../services/http'; import { Settings } from '../settings'; -import { ParamDropdown, WidgetHeader } from '../components/widget-components'; +import WidgetHeader from '../components/widget-header'; +import ParamDropdown from '../components/param-dropdown'; export class FilterHeatmapWidget extends React.Component { @@ -230,11 +231,17 @@ export class FilterHeatmapWidget extends React.Component { } } labels.forEach((item) => xLabels.push(item)); - const actions = this.getJenkinsAnalysisLink() || null; + const jenkins_analysis_link = this.getJenkinsAnalysisLink(); return ( - + a !== null)} + getDataFunc={this.getHeatmap} + onEditClick={this.props.onEditClick} + onDeleteClick={this.props.onDeleteClick} + /> {(!this.state.heatmapError && this.state.isLoading) && Loading ... @@ -270,7 +277,7 @@ export class FilterHeatmapWidget extends React.Component { dropdownItems={this.props.dropdownItems || [3, 5, 6, 7]} handleSelect={this.onBuildSelect} defaultValue={this.params.builds} - tooltip="Set no. of builds to:" + tooltip="Number of builds:" /> {this.props.type === 'jenkins' &&