Downstream alert summaries:{' '}
@@ -489,7 +494,7 @@ export default class AlertTable extends React.Component {
{alertSummary.notes && (
(
{statusColor === 'text-success' && (
-
+
)}
{alertStatus}
{alert.related_summary_id && this.getReassignment(alert)})
@@ -427,26 +426,24 @@ export default class AlertTableRow extends React.Component {
data-testid={alert.id}
>
-
- alert {alert.id} title
-
- this.setState(
- { checkboxSelected: !checkboxSelected },
- this.updateCheckbox,
- )
- }
- />
-
+
+ this.setState(
+ { checkboxSelected: !checkboxSelected },
+ this.updateCheckbox,
+ )
+ }
+ />
) : (
-
+
None
)}
diff --git a/ui/perfherder/alerts/AlertTableTagsOptions.jsx b/ui/perfherder/alerts/AlertTableTagsOptions.jsx
index dcd13c115a4..0e425965f0f 100644
--- a/ui/perfherder/alerts/AlertTableTagsOptions.jsx
+++ b/ui/perfherder/alerts/AlertTableTagsOptions.jsx
@@ -1,8 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
-import UncontrolledTooltip from 'reactstrap/lib/UncontrolledTooltip';
-import Button from 'reactstrap/lib/Button';
-import Badge from 'reactstrap/lib/Badge';
+import { Button, Badge, OverlayTrigger, Tooltip } from 'react-bootstrap';
import SimpleTooltip from '../../shared/SimpleTooltip';
@@ -26,8 +24,9 @@ export default class AlertTableTagsOptions extends React.Component {
return items.map((item) => (
@@ -51,7 +50,6 @@ export default class AlertTableTagsOptions extends React.Component {
};
displayItems = (items) => {
- const { alertId } = this.props;
const { displayAllItems } = this.state;
return items.length ? (
@@ -61,29 +59,27 @@ export default class AlertTableTagsOptions extends React.Component {
>
{this.showItems(items.slice(0, this.visibleItems))}
{!displayAllItems && items.length > this.visibleItems && (
-
- this.setState((prevState) => ({
- displayAllItems: !prevState.displayAllItems,
- }))
- }
+ Show more}
>
- ...
-
+ this.setState((prevState) => ({
+ displayAllItems: !prevState.displayAllItems,
+ }))
+ }
>
- Show more
-
-
+ ...
+
+
)}
{displayAllItems && this.showItems(items.slice(this.visibleItems))}
) : (
-
+
No tags or options
);
@@ -109,5 +105,4 @@ AlertTableTagsOptions.propTypes = {
tagAndOption: PropTypes.bool.isRequired,
}),
).isRequired,
- alertId: PropTypes.number.isRequired,
};
diff --git a/ui/perfherder/alerts/AlertsView.jsx b/ui/perfherder/alerts/AlertsView.jsx
index 1d1b92a7c3a..bf25c92ded5 100644
--- a/ui/perfherder/alerts/AlertsView.jsx
+++ b/ui/perfherder/alerts/AlertsView.jsx
@@ -1,6 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
-import { Alert, Container } from 'reactstrap';
+import { Alert, Container } from 'react-bootstrap';
import cloneDeep from 'lodash/cloneDeep';
import withValidation from '../Validation';
@@ -371,14 +371,14 @@ class AlertsView extends React.Component {
)}
{!user.isStaff && (
-
+
You must be logged into perfherder/treeherder and be a sheriff to
make changes
)}
{notSupportedAlertFilters.length > 0 && (
-
+
{notSupportedAlertFiltersMessage(notSupportedAlertFilters)}
)}
diff --git a/ui/perfherder/alerts/AlertsViewControls.jsx b/ui/perfherder/alerts/AlertsViewControls.jsx
index 60b6e740b2c..5eac88a91bb 100644
--- a/ui/perfherder/alerts/AlertsViewControls.jsx
+++ b/ui/perfherder/alerts/AlertsViewControls.jsx
@@ -1,6 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
-import { Row, Button, Container } from 'reactstrap';
+import { Button, Container } from 'react-bootstrap';
import FilterControls from '../../shared/FilterControls';
import { summaryStatusMap, scrollTypes } from '../perf-helpers/constants';
@@ -195,12 +195,11 @@ export default class AlertsViewControls extends React.Component {
return (
{alertSummaries.length > 1 && (
-
+
-
+
this.onScrollAlert(scrollTypes.prev)}
disabled={disableButtons.prev}
data-testid="scroll-prev-alert"
@@ -208,7 +207,7 @@ export default class AlertsViewControls extends React.Component {
Previous alert
this.onScrollAlert(scrollTypes.next)}
disabled={disableButtons.next}
data-testid="scroll-next-alert"
@@ -230,14 +229,14 @@ export default class AlertsViewControls extends React.Component {
/>
{pageNums
? hasMorePages() && (
-
+
)
: null}
{alertSummaries.length > 0 &&
@@ -258,14 +257,14 @@ export default class AlertsViewControls extends React.Component {
))}
{pageNums
? hasMorePages() && (
-
+
)
: null}
diff --git a/ui/perfherder/alerts/Assignee.jsx b/ui/perfherder/alerts/Assignee.jsx
index fdc3e7e3d92..05109100aaf 100644
--- a/ui/perfherder/alerts/Assignee.jsx
+++ b/ui/perfherder/alerts/Assignee.jsx
@@ -1,6 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
-import { Button, Input, InputGroup } from 'reactstrap';
+import { Button, Form, InputGroup } from 'react-bootstrap';
export default class Assignee extends React.Component {
constructor(props) {
@@ -102,10 +102,9 @@ export default class Assignee extends React.Component {
);
return !inEditMode ? (
-
+
{!assigneeUsername && (
)}
-
+
) : (
-
-
-
+ {tooltipText}}
+ >
+
+
{text}
-
-
- {tooltipText}
-
-
+
);
}
}
@@ -46,12 +38,10 @@ BadgeTooltip.propTypes = {
textClass: PropTypes.string,
placement: PropTypes.string,
innerClassName: PropTypes.string,
- autohide: PropTypes.bool,
};
BadgeTooltip.defaultProps = {
textClass: '',
placement: 'top',
innerClassName: '',
- autohide: true,
};
diff --git a/ui/perfherder/alerts/FileBugModal.jsx b/ui/perfherder/alerts/FileBugModal.jsx
index 78dbfa40e2d..b527814d015 100644
--- a/ui/perfherder/alerts/FileBugModal.jsx
+++ b/ui/perfherder/alerts/FileBugModal.jsx
@@ -1,18 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
-import {
- Form,
- FormGroup,
- Input,
- Label,
- Button,
- Modal,
- ModalHeader,
- ModalBody,
- ModalFooter,
- Col,
- Row,
-} from 'reactstrap';
+import { Form, Button, Modal, Col, Row } from 'react-bootstrap';
import debounce from 'lodash/debounce';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faInfoCircle } from '@fortawesome/free-solid-svg-icons';
@@ -76,24 +64,26 @@ export default class FileBugModal extends React.Component {
'regression from the referenced bug.';
return (
-
- {header}
+
+
+ {header}
+
);
diff --git a/ui/perfherder/alerts/NotesModal.jsx b/ui/perfherder/alerts/NotesModal.jsx
index f85008877b9..e55a2b7af34 100644
--- a/ui/perfherder/alerts/NotesModal.jsx
+++ b/ui/perfherder/alerts/NotesModal.jsx
@@ -1,16 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
-import {
- Form,
- FormGroup,
- Input,
- Label,
- Button,
- Modal,
- ModalHeader,
- ModalBody,
- ModalFooter,
-} from 'reactstrap';
+import { Form, Button, Modal } from 'react-bootstrap';
export default class NotesModal extends React.Component {
constructor(props) {
@@ -29,25 +19,27 @@ export default class NotesModal extends React.Component {
const { inputValue } = this.state;
return (
-
- Alert Notes
+
+
+ Alert Notes
+
);
diff --git a/ui/perfherder/alerts/SelectAlertsDropdown.jsx b/ui/perfherder/alerts/SelectAlertsDropdown.jsx
index 05f02088eb1..2f7f14d136b 100644
--- a/ui/perfherder/alerts/SelectAlertsDropdown.jsx
+++ b/ui/perfherder/alerts/SelectAlertsDropdown.jsx
@@ -1,11 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
-import DropdownItem from 'reactstrap/lib/DropdownItem';
-import DropdownMenu from 'reactstrap/lib/DropdownMenu';
-import DropdownToggle from 'reactstrap/lib/DropdownToggle';
-import UncontrolledDropdown from 'reactstrap/lib/UncontrolledDropdown';
-import Input from 'reactstrap/lib/Input';
-import Label from 'reactstrap/lib/Label';
+import { Dropdown, Form } from 'react-bootstrap';
import { alertStatusMap } from '../perf-helpers/constants';
import { getStatus } from '../perf-helpers/helpers';
@@ -54,42 +49,41 @@ class SelectAlertsDropdown extends React.Component {
return (
-
- {
- return allSelected
- ? this.selectAlertsByStatus(none)
- : this.selectAlertsByStatus(all);
- }}
- />
-
-
- {
+ return allSelected
+ ? this.selectAlertsByStatus(none)
+ : this.selectAlertsByStatus(all);
+ }}
+ />
+
+
-
- Check alerts
- this.selectAlertsByStatus(all)}>
+
+ Check alerts
+ this.selectAlertsByStatus(all)}>
All
-
- this.selectAlertsByStatus(none)}>
+
+ this.selectAlertsByStatus(none)}>
None
-
- this.selectAlertsByStatus(triaged)}>
+
+ this.selectAlertsByStatus(triaged)}>
Triaged
-
- this.selectAlertsByStatus(untriaged)}>
+
+ this.selectAlertsByStatus(untriaged)}>
Untriaged
-
-
-
+
+
+
);
}
diff --git a/ui/perfherder/alerts/StatusDropdown.jsx b/ui/perfherder/alerts/StatusDropdown.jsx
index 712a5e2db9c..40f3ac444f2 100644
--- a/ui/perfherder/alerts/StatusDropdown.jsx
+++ b/ui/perfherder/alerts/StatusDropdown.jsx
@@ -1,13 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
-import {
- UncontrolledDropdown,
- DropdownMenu,
- DropdownItem,
- DropdownToggle,
- Col,
- Label,
-} from 'reactstrap';
+import { Dropdown, Col, Form } from 'react-bootstrap';
import template from 'lodash/template';
import templateSettings from 'lodash/templateSettings';
@@ -361,19 +354,23 @@ The following [documentation link](https://firefox-source-docs.mozilla.org/testi
submitButtonText="Assign"
dropdownOption={
- Select Bug Tracker
-
-
+
+ Select Bug Tracker
+
+
+
{selectedValue}
-
-
- this.setState({ selectedValue })
- }
- selectedItem={selectedValue}
- options={issueTrackers.map((item) => item.text)}
- />
-
+
+
+
+ this.setState({ selectedValue })
+ }
+ selectedItem={selectedValue}
+ options={issueTrackers.map((item) => item.text)}
+ />
+
+
}
/>
@@ -433,44 +430,44 @@ The following [documentation link](https://firefox-source-docs.mozilla.org/testi
performanceTags={performanceTags}
updateAndClose={this.updateAndClose}
/>
-
-
+
+
{getStatus(alertSummary.status)}
-
-
-
+
+
+
Copy Summary
-
+
{!alertSummary.bug_number && user.isStaff && (
- this.toggle('showFileBugModal')}
>
File bug
-
+
)}
{!alertSummary.bug_number &&
frameworkName in criticalTestsList &&
user.isStaff && (
- this.toggle('showCriticalFileBugModal')}
>
Request backout
-
+
)}
{user.isStaff && (
{!alertSummary.bug_number ? (
- this.toggle('showBugModal')}
>
Link to bug
-
+
) : (
-
this.changeAlertSummary({
bug_number: null,
@@ -478,17 +475,17 @@ The following [documentation link](https://firefox-source-docs.mozilla.org/testi
}
>
Unlink from bug
-
+
)}
- this.toggle('showNotesModal')}
>
{!alertSummary.notes ? 'Add notes' : 'Edit notes'}
-
+
{this.isResolved(alertStatus) && (
-
this.changeAlertSummary({
status: summaryStatusMap.investigating,
@@ -496,11 +493,11 @@ The following [documentation link](https://firefox-source-docs.mozilla.org/testi
}
>
Re-open
-
+
)}
{this.isValidStatus(alertStatus, 'wontfix') && (
-
this.changeAlertSummary({
status: summaryStatusMap.wontfix,
@@ -508,12 +505,12 @@ The following [documentation link](https://firefox-source-docs.mozilla.org/testi
}
>
Mark as won't fix
-
+
)}
{this.isValidStatus(alertStatus, 'backedout') && (
-
this.changeAlertSummary({
status: summaryStatusMap.backedout,
@@ -521,12 +518,12 @@ The following [documentation link](https://firefox-source-docs.mozilla.org/testi
}
>
Mark as backed out
-
+
)}
{this.isValidStatus(alertStatus, 'fixed') && (
-
this.changeAlertSummary({
status: summaryStatusMap.fixed,
@@ -534,20 +531,20 @@ The following [documentation link](https://firefox-source-docs.mozilla.org/testi
}
>
Mark as fixed
-
+
)}
- this.toggle('showTagsModal')}
>
{!alertSummaryActiveTags.length ? 'Add tags' : 'Edit tags'}
-
+
)}
-
+
{!isWeekend && }
-
+
);
}
diff --git a/ui/perfherder/alerts/TagsList.jsx b/ui/perfherder/alerts/TagsList.jsx
index 32f6cbe7d31..3520ebfd840 100644
--- a/ui/perfherder/alerts/TagsList.jsx
+++ b/ui/perfherder/alerts/TagsList.jsx
@@ -1,20 +1,21 @@
import React from 'react';
import PropTypes from 'prop-types';
-import { Badge, UncontrolledTooltip } from 'reactstrap';
+import { Badge, OverlayTrigger, Tooltip } from 'react-bootstrap';
import { tooltipMessages } from '../perf-helpers/constants';
const TagsList = ({ tags }) => {
if (tags.length > 0) {
return tags.map((tag) => (
-
-
- {tag}
-
-
- {tooltipMessages[tag]}
-
-
+ {tooltipMessages[tag]}}
+ >
+
+ {tag}
+
+
));
}
diff --git a/ui/perfherder/alerts/TagsModal.jsx b/ui/perfherder/alerts/TagsModal.jsx
index 57bff9203b5..511f2597768 100644
--- a/ui/perfherder/alerts/TagsModal.jsx
+++ b/ui/perfherder/alerts/TagsModal.jsx
@@ -1,16 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
-import {
- Modal,
- ModalHeader,
- ModalBody,
- ModalFooter,
- Button,
- Form,
- FormGroup,
- Label,
- CustomInput,
-} from 'reactstrap';
+import { Modal, Button, Form } from 'react-bootstrap';
export default class TagsModal extends React.Component {
constructor(props) {
@@ -44,7 +34,7 @@ export default class TagsModal extends React.Component {
listTags = () => {
return this.state.tags.map((tag, index) => {
return (
-
- Alert Tags
+
+
+ Alert Tags
+
);
diff --git a/ui/perfherder/compare/CompareSelectorView.jsx b/ui/perfherder/compare/CompareSelectorView.jsx
index cd190ae9d99..70cc932cd9b 100644
--- a/ui/perfherder/compare/CompareSelectorView.jsx
+++ b/ui/perfherder/compare/CompareSelectorView.jsx
@@ -5,10 +5,9 @@ import {
Row,
Button,
ButtonGroup,
- ButtonDropdown,
- DropdownToggle,
+ Dropdown,
Alert,
-} from 'reactstrap';
+} from 'react-bootstrap';
import { parseQueryParams, createQueryParams } from '../../helpers/url';
import ErrorMessages from '../../shared/ErrorMessages';
@@ -36,7 +35,6 @@ export default class CompareSelectorView extends React.Component {
missingRevision: false,
framework: 1,
frameworkName: 'talos',
- frameworkDropdownIsOpen: false,
frameworks: [...this.props.frameworks, { id: 0, name: 'infra' }],
};
}
@@ -92,12 +90,6 @@ export default class CompareSelectorView extends React.Component {
}
};
- toggleFrameworkDropdown = () => {
- this.setState((prevState) => ({
- frameworkDropdownIsOpen: !prevState.frameworkDropdownIsOpen,
- }));
- };
-
render() {
const {
originalProject,
@@ -108,7 +100,6 @@ export default class CompareSelectorView extends React.Component {
errorMessages,
disableButton,
missingRevision,
- frameworkDropdownIsOpen,
frameworks,
} = this.state;
@@ -137,15 +128,17 @@ export default class CompareSelectorView extends React.Component {
-
- Compare View will be deprecated soon. Please consider using{' '}
- PerfCompare as an
- alternative.
-
+
+
+ Compare View will be deprecated soon. Please consider using{' '}
+ PerfCompare as an
+ alternative.
+
+
{showWarning && (
-
+
It is not recommended to compare a try build against a{' '}
mozilla-central build, unless it is based on latest
mozilla-central.
@@ -177,21 +170,22 @@ export default class CompareSelectorView extends React.Component {
-
+
-
- {frameworkName}
-
-
+
+
+ {frameworkName}
+
+
+
+
+
{
+ ref={(el) => {
this.header = el;
}}
>
@@ -153,8 +153,8 @@ export default class CompareTable extends React.Component {
)}
{onPermalinkClick && (
onPermalinkClick(
getHashBasedId(testName, hashFunction),
diff --git a/ui/perfherder/compare/CompareTableControls.jsx b/ui/perfherder/compare/CompareTableControls.jsx
index 40c06c42772..8eb49c25d6e 100644
--- a/ui/perfherder/compare/CompareTableControls.jsx
+++ b/ui/perfherder/compare/CompareTableControls.jsx
@@ -1,8 +1,7 @@
import React from 'react';
import PropTypes from 'prop-types';
-import { Container, Row } from 'reactstrap';
+import { Container, Row, Button } from 'react-bootstrap';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import Button from 'reactstrap/lib/Button';
import { faFileDownload } from '@fortawesome/free-solid-svg-icons';
import { filterText } from '../perf-helpers/constants';
@@ -357,8 +356,7 @@ export default class CompareTableControls extends React.Component {
{hasTryProject() && (
-
+
{rowLevelResults.name}
{onPermalinkClick && (
onPermalinkClick(
getHashBasedId(
diff --git a/ui/perfherder/compare/CompareTableView.jsx b/ui/perfherder/compare/CompareTableView.jsx
index 56600206353..d114c822a79 100644
--- a/ui/perfherder/compare/CompareTableView.jsx
+++ b/ui/perfherder/compare/CompareTableView.jsx
@@ -1,6 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
-import { Alert, Col, Row, Container } from 'reactstrap';
+import { Alert, Col, Row, Container } from 'react-bootstrap';
import { Link } from 'react-router-dom';
import ErrorMessages from '../../shared/ErrorMessages';
@@ -325,7 +325,7 @@ export default class CompareTableView extends React.Component {
>
-
+
-
+
{
+const NoiseTable = ({ testsWithNoise, hasSubtests = false }) => {
const valueToString = (value) => {
if (Number.isNaN(value)) {
return value.toString();
@@ -11,7 +11,7 @@ const NoiseTable = ({ testsWithNoise, hasSubtests }) => {
};
return (
-
+
Tests with too much noise to be considered in the noise metric
@@ -43,8 +43,4 @@ NoiseTable.propTypes = {
hasSubtests: PropTypes.bool,
};
-NoiseTable.defaultProps = {
- hasSubtests: false,
-};
-
export default NoiseTable;
diff --git a/ui/perfherder/compare/RetriggerButton.jsx b/ui/perfherder/compare/RetriggerButton.jsx
index dfbe996d496..6cc044ebf43 100644
--- a/ui/perfherder/compare/RetriggerButton.jsx
+++ b/ui/perfherder/compare/RetriggerButton.jsx
@@ -1,5 +1,5 @@
import React from 'react';
-import { Button } from 'reactstrap';
+import { Button } from 'react-bootstrap';
import PropTypes from 'prop-types';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faRedo } from '@fortawesome/free-solid-svg-icons';
@@ -11,7 +11,7 @@ export default function RetriggerButton(props) {
return (
diff --git a/ui/perfherder/compare/RetriggerModal.jsx b/ui/perfherder/compare/RetriggerModal.jsx
index fedbb2f161f..fb7b9084e8d 100644
--- a/ui/perfherder/compare/RetriggerModal.jsx
+++ b/ui/perfherder/compare/RetriggerModal.jsx
@@ -1,18 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
-import {
- Col,
- Form,
- Input,
- InputGroup,
- InputGroupAddon,
- InputGroupText,
- Button,
- Modal,
- ModalHeader,
- ModalBody,
- ModalFooter,
-} from 'reactstrap';
+import { Col, Form, InputGroup, Button, Modal } from 'react-bootstrap';
export default class RetriggerModal extends React.Component {
constructor(props) {
@@ -133,20 +121,21 @@ export default class RetriggerModal extends React.Component {
return (
- Retrigger Jobs
+
+ Retrigger Jobs
+
);
diff --git a/ui/perfherder/compare/SelectorCard.jsx b/ui/perfherder/compare/SelectorCard.jsx
index d5155545a94..413ac64e083 100644
--- a/ui/perfherder/compare/SelectorCard.jsx
+++ b/ui/perfherder/compare/SelectorCard.jsx
@@ -1,20 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
-import {
- Col,
- Card,
- CardHeader,
- CardText,
- CardBody,
- DropdownItem,
- Input,
- CardSubtitle,
- ButtonDropdown,
- DropdownToggle,
- DropdownMenu,
- InputGroup,
- InputGroupButtonDropdown,
-} from 'reactstrap';
+import { Col, Card, InputGroup, Dropdown, Form } from 'react-bootstrap';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faCheck } from '@fortawesome/free-solid-svg-icons';
@@ -186,21 +172,21 @@ export default class SelectorCard extends React.Component {
return (
- {title}
-
- Project
- this.toggle('buttonDropdownOpen')}
+ {title}
+
+ Project
+ this.toggle('buttonDropdownOpen')}
>
-
+
{selectedRepo}
-
- {projects.length > 0 && (
-
- {projects.map((item) => (
-
+
+ {projects.length > 0 &&
+ projects.map((item) => (
+
@@ -209,27 +195,26 @@ export default class SelectorCard extends React.Component {
>
{item.name}
-
+
))}
-
- )}
-
+
+
{invalidProject && (
-
+
{invalidProject}
-
+
)}
- Revision
+ Revision
-
- this.toggle('inputDropdownOpen')}
+ this.toggle('inputDropdownOpen')}
+ as={InputGroup.Append}
>
-
+
Recent
-
- {!!data.results && data.results.length > 0 && (
-
- {data.results.map((item) => (
-
+
+ {!!data.results &&
+ data.results.length > 0 &&
+ data.results.map((item) => (
+
@@ -263,7 +252,7 @@ export default class SelectorCard extends React.Component {
>
{`${item.revision} ${item.author}`}
-
+
))}
-
- )}
-
+
+
{(validating || invalidRevision || missingRevision) && (
-
{validating || invalidRevision || missingRevision}
-
+
)}
-
+
);
diff --git a/ui/perfherder/compare/TableAverage.jsx b/ui/perfherder/compare/TableAverage.jsx
index 98282f8a04e..d4bd456eccf 100644
--- a/ui/perfherder/compare/TableAverage.jsx
+++ b/ui/perfherder/compare/TableAverage.jsx
@@ -1,6 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
-import { Badge } from 'reactstrap';
+import { Badge } from 'react-bootstrap';
import SimpleTooltip from '../../shared/SimpleTooltip';
import { replicatesMaxLength } from '../perf-helpers/constants';
@@ -8,7 +8,13 @@ import { displayNumber, formatNumber } from '../perf-helpers/helpers';
import TooltipGraph from './TooltipGraph';
-const TableAverage = ({ value, stddev, stddevpct, replicates, app }) => {
+const TableAverage = ({
+ value = null,
+ stddev = null,
+ stddevpct = null,
+ replicates = [],
+ app,
+}) => {
let tooltipText;
if (replicates.length > 1) {
const replicatesStr = replicates
@@ -88,7 +94,7 @@ const TableAverage = ({ value, stddev, stddevpct, replicates, app }) => {
)}
{app && (
- {app}
+ {app}
)}
@@ -102,11 +108,4 @@ TableAverage.propTypes = {
replicates: PropTypes.arrayOf(PropTypes.number),
};
-TableAverage.defaultProps = {
- value: PropTypes.null,
- stddev: PropTypes.null,
- stddevpct: PropTypes.null,
- replicates: [],
-};
-
export default TableAverage;
diff --git a/ui/perfherder/compare/TooltipGraph.jsx b/ui/perfherder/compare/TooltipGraph.jsx
index 75cf64dca7c..a22a6f0ca8a 100644
--- a/ui/perfherder/compare/TooltipGraph.jsx
+++ b/ui/perfherder/compare/TooltipGraph.jsx
@@ -1,6 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
-import { Table } from 'reactstrap';
+import { Table } from 'react-bootstrap';
import { abbreviatedNumber } from '../perf-helpers/helpers';
diff --git a/ui/perfherder/graphs/GraphTooltip.jsx b/ui/perfherder/graphs/GraphTooltip.jsx
index 42160191a18..e9f6e12647f 100644
--- a/ui/perfherder/graphs/GraphTooltip.jsx
+++ b/ui/perfherder/graphs/GraphTooltip.jsx
@@ -1,7 +1,7 @@
import React from 'react';
import PropTypes from 'prop-types';
import countBy from 'lodash/countBy';
-import { Button } from 'reactstrap';
+import { Button } from 'react-bootstrap';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import {
faExclamationCircle,
@@ -171,9 +171,8 @@ const GraphTooltip = ({
data-testid="graphTooltip"
>
{dataPointDetails.alertSummary && (
@@ -281,7 +279,6 @@ const GraphTooltip = ({
)}
@@ -302,7 +299,6 @@ const GraphTooltip = ({
Common alert
@@ -311,8 +307,7 @@ const GraphTooltip = ({
{user.isStaff ? (
diff --git a/ui/perfherder/graphs/GraphsContainer.jsx b/ui/perfherder/graphs/GraphsContainer.jsx
index d813a0779db..3685c491532 100644
--- a/ui/perfherder/graphs/GraphsContainer.jsx
+++ b/ui/perfherder/graphs/GraphsContainer.jsx
@@ -1,7 +1,7 @@
// disabling due to a new bug with this rule: https://github.com/eslint/eslint/issues/12117
/* eslint-disable no-unused-vars */
import React from 'react';
-import { Row, Col } from 'reactstrap';
+import { Row, Col } from 'react-bootstrap';
import PropTypes from 'prop-types';
import {
VictoryBar,
diff --git a/ui/perfherder/graphs/GraphsView.jsx b/ui/perfherder/graphs/GraphsView.jsx
index 18b317005ad..c7a3ce806e8 100644
--- a/ui/perfherder/graphs/GraphsView.jsx
+++ b/ui/perfherder/graphs/GraphsView.jsx
@@ -1,6 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
-import { Button, Container, Col, Row } from 'reactstrap';
+import { Button, Container, Col, Row } from 'react-bootstrap';
import unionBy from 'lodash/unionBy';
import queryString from 'query-string';
@@ -425,7 +425,7 @@ class GraphsView extends React.Component {
errorClasses={errorMessageClass}
message={genericErrorMessage}
>
-
+
{loading && }
{errorMessages.length > 0 && (
@@ -448,7 +448,7 @@ class GraphsView extends React.Component {
{testData.length > 0 &&
testData.map((series) => (
@@ -473,7 +473,7 @@ class GraphsView extends React.Component {
)}
diff --git a/ui/perfherder/graphs/GraphsViewControls.jsx b/ui/perfherder/graphs/GraphsViewControls.jsx
index 66af3db3e4a..e89aaebbcb0 100644
--- a/ui/perfherder/graphs/GraphsViewControls.jsx
+++ b/ui/perfherder/graphs/GraphsViewControls.jsx
@@ -1,6 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
-import { Button, Col, Container, Input, Row } from 'reactstrap';
+import { Button, Col, Container, Form, Row } from 'react-bootstrap';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faChartArea, faTable } from '@fortawesome/free-solid-svg-icons';
import moment from 'moment';
@@ -98,29 +98,33 @@ export default class GraphsViewControls extends React.Component {
/>
{!hasNoData && (
-
+
{showTable ? (
-
+
) : (
-
+
)}
{showTable ? 'Graphs View' : 'Table View'}
)}
-
+
-
+
Add test data
@@ -146,8 +150,8 @@ export default class GraphsViewControls extends React.Component {
{highlightedRevisions.length > 0 &&
highlightedRevisions.map((revision, index) => (
// eslint-disable-next-line react/no-array-index-key
-
-
+
))}
{!showTable && (
-
+
updateStateParams({
highlightAlerts: !highlightAlerts,
@@ -176,9 +179,8 @@ export default class GraphsViewControls extends React.Component {
Highlight alerts
updateStateParams({
highlightChangelogData: !highlightChangelogData,
@@ -189,9 +191,8 @@ export default class GraphsViewControls extends React.Component {
Highlight infra changes
updateStateParams({
highlightCommonAlerts: !highlightCommonAlerts,
@@ -202,9 +203,8 @@ export default class GraphsViewControls extends React.Component {
Highlight common alerts
updateStateParams({
replicates: !replicates,
diff --git a/ui/perfherder/graphs/LegendCard.jsx b/ui/perfherder/graphs/LegendCard.jsx
index 748a966984f..eed7446d708 100644
--- a/ui/perfherder/graphs/LegendCard.jsx
+++ b/ui/perfherder/graphs/LegendCard.jsx
@@ -1,8 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
-import { Badge, Button, FormGroup, Input } from 'reactstrap';
-import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { faTimes } from '@fortawesome/free-solid-svg-icons';
+import { Badge, Button, Form, CloseButton } from 'react-bootstrap';
import { getFrameworkName } from '../perf-helpers/helpers';
import { graphColors } from '../perf-helpers/constants';
@@ -129,7 +127,7 @@ const LegendCard = ({
}
};
- const subtitleStyle = 'p-0 mb-0 border-0 text-secondary text-left';
+ const subtitleStyle = 'p-0 mb-0 border-0 text-secondary text-start';
const symbolType = series.symbol || ['circle', 'outline'];
const { suite, platform, framework_id: frameworkId } = series;
@@ -137,26 +135,19 @@ const LegendCard = ({
const perfdocs = new Perfdocs(framework, suite, platform);
const hasDocumentation = perfdocs.hasDocumentation();
return (
-
-
+
-
-
+ aria-label="Remove test"
+ />
addTestData('addRelatedConfigs')}
title="Add related configurations"
>
@@ -179,8 +170,7 @@ const LegendCard = ({
)}
addTestData('addRelatedBranches')}
title="Add related branches"
@@ -188,8 +178,7 @@ const LegendCard = ({
{series.repository_name}
addTestData('addRelatedPlatform')}
title="Add related platforms and branches"
@@ -198,8 +187,7 @@ const LegendCard = ({
{series.application && (
addTestData('addRelatedApplications')}
@@ -217,7 +205,7 @@ const LegendCard = ({
{`alert_threshold: ${series.alertThreshold}`}
{`${series.signatureHash.slice(0, 16)}...`}
-
-
+
);
};
diff --git a/ui/perfherder/graphs/TableView.jsx b/ui/perfherder/graphs/TableView.jsx
index b6f1f7a5b6a..fb641ff41e1 100644
--- a/ui/perfherder/graphs/TableView.jsx
+++ b/ui/perfherder/graphs/TableView.jsx
@@ -1,6 +1,6 @@
import React from 'react';
import ReactTable from 'react-table-6';
-import { Badge } from 'reactstrap';
+import { Badge } from 'react-bootstrap';
import moment from 'moment';
import { groupBy, forIn } from 'lodash';
import numeral from 'numeral';
diff --git a/ui/perfherder/graphs/TestDataModal.jsx b/ui/perfherder/graphs/TestDataModal.jsx
index d12709a7418..d345e30b2e0 100644
--- a/ui/perfherder/graphs/TestDataModal.jsx
+++ b/ui/perfherder/graphs/TestDataModal.jsx
@@ -1,18 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
-import {
- Button,
- Col,
- Form,
- Input,
- Label,
- Modal,
- ModalHeader,
- ModalBody,
- Row,
- FormGroup,
- Badge,
-} from 'reactstrap';
+import { Button, Col, Form, Modal, Row, Badge } from 'react-bootstrap';
import flatMap from 'lodash/flatMap';
import { createDropdowns } from '../../shared/FilterControls';
@@ -513,9 +501,11 @@ export default class TestDataModal extends React.Component {
}
return (
-
- Add Test Data
-
+
+
+ Add Test Data
+
+
-
+
);
}
diff --git a/ui/perfherder/graphs/TimeRangeDropdown.jsx b/ui/perfherder/graphs/TimeRangeDropdown.jsx
index 0b7f5730200..f516bf4db7f 100644
--- a/ui/perfherder/graphs/TimeRangeDropdown.jsx
+++ b/ui/perfherder/graphs/TimeRangeDropdown.jsx
@@ -1,5 +1,5 @@
import React from 'react';
-import { DropdownToggle, UncontrolledDropdown } from 'reactstrap';
+import { Dropdown } from 'react-bootstrap';
import PropTypes from 'prop-types';
import DropdownMenuItems from '../../shared/DropdownMenuItems';
@@ -10,22 +10,24 @@ class TimeRangeDropdown extends React.PureComponent {
const { timeRangeText, updateTimeRange } = this.props;
return (
-
- {timeRangeText}
- item.text)}
- selectedItem={timeRangeText}
- updateData={(newTimeRangeText) =>
- updateTimeRange(
- phTimeRanges.find((item) => item.text === newTimeRangeText),
- )
- }
- />
-
+ {timeRangeText}
+
+ item.text)}
+ selectedItem={timeRangeText}
+ updateData={(newTimeRangeText) =>
+ updateTimeRange(
+ phTimeRanges.find((item) => item.text === newTimeRangeText),
+ )
+ }
+ />
+
+
);
}
}
diff --git a/ui/perfherder/shared/Pagination.jsx b/ui/perfherder/shared/Pagination.jsx
index ad012f5d8a9..baf222eb7bc 100644
--- a/ui/perfherder/shared/Pagination.jsx
+++ b/ui/perfherder/shared/Pagination.jsx
@@ -1,6 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
-import { Pagination, PaginationItem, PaginationLink } from 'reactstrap';
+import { Pagination } from 'react-bootstrap';
class PaginationGroup extends React.Component {
navigatePage = (page) => {
@@ -21,53 +21,58 @@ class PaginationGroup extends React.Component {
const lastButtonAvailable = lastViewablePage < count;
return (
- /* The first and last pagination navigation links
- aren't working correctly (icons aren't visible)
- so they haven't been added */
-
-
- this.navigatePage(1)}
- />
-
-
- this.navigatePage(currentPage - 1)}
- />
-
- {viewablePageNums.map((num) => (
-
-
+ this.navigatePage(1)}
+ linkClassName="d-flex align-items-center justify-content-center"
+ >
+ «
+ First
+
+ this.navigatePage(currentPage - 1)}
+ linkClassName="d-flex align-items-center justify-content-center"
+ >
+ ‹
+ Previous
+
+ {viewablePageNums.map((num) => {
+ const isActive = num === currentPage;
+ return (
+ this.navigatePage(num)}
- aria-label={`pagination-button-${num}`}
+ linkClassName="d-flex align-items-center justify-content-center"
+ aria-label={`Go to page ${num}`}
+ aria-current={isActive ? 'page' : undefined}
>
- {num}
-
-
- ))}
-
- this.navigatePage(currentPage + 1)}
- />
-
-
- this.navigatePage(count)}
- />
-
+ {num}
+ {isActive && Current page }
+
+ );
+ })}
+ this.navigatePage(currentPage + 1)}
+ linkClassName="d-flex align-items-center justify-content-center"
+ >
+ ›
+ Next
+
+ this.navigatePage(count)}
+ linkClassName="d-flex align-items-center justify-content-center"
+ >
+ »
+ Last
+
);
}
diff --git a/ui/perfherder/shared/SortButton.jsx b/ui/perfherder/shared/SortButton.jsx
index 0a1b6a6d9fe..7686bacabd4 100644
--- a/ui/perfherder/shared/SortButton.jsx
+++ b/ui/perfherder/shared/SortButton.jsx
@@ -1,5 +1,5 @@
import React from 'react';
-import { Badge } from 'reactstrap';
+import { Button } from 'react-bootstrap';
import PropTypes from 'prop-types';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import {
@@ -27,14 +27,18 @@ export default class SortButton extends React.Component {
const { column, onChangeSort } = this.props;
const { name, currentSort } = column;
return (
- onChangeSort(column)}
>
-
-
+
+
);
}
}
diff --git a/ui/perfherder/shared/SortButtonDisabled.jsx b/ui/perfherder/shared/SortButtonDisabled.jsx
index 9ed23231c78..0cbf7cb11b4 100644
--- a/ui/perfherder/shared/SortButtonDisabled.jsx
+++ b/ui/perfherder/shared/SortButtonDisabled.jsx
@@ -1,6 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
-import { Badge } from 'reactstrap';
+import { Button } from 'react-bootstrap';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faSort } from '@fortawesome/free-solid-svg-icons';
@@ -10,13 +10,15 @@ export default class SortButtonDisabled extends React.PureComponent {
column: { name },
} = this.props;
return (
-
-
-
+
+
);
}
}
diff --git a/ui/perfherder/shared/TableColumnHeader.jsx b/ui/perfherder/shared/TableColumnHeader.jsx
index 292681efdc2..e12f0c88fa9 100644
--- a/ui/perfherder/shared/TableColumnHeader.jsx
+++ b/ui/perfherder/shared/TableColumnHeader.jsx
@@ -9,7 +9,7 @@ export default class TableColumnHeader extends React.Component {
const { column, onChangeSort } = this.props;
const { name } = column;
return (
-
+
{name === 'Test name' ? '' : `${name}`}
diff --git a/ui/perfherder/tests/ItemList.jsx b/ui/perfherder/tests/ItemList.jsx
index e9b0f5062a6..c9149a18b20 100644
--- a/ui/perfherder/tests/ItemList.jsx
+++ b/ui/perfherder/tests/ItemList.jsx
@@ -7,13 +7,13 @@ export default function ItemList(props) {
return (
{items.slice(0, maxSeen).map((item) => (
-
+
{item}
))}
{items.length > maxSeen && (
...
diff --git a/ui/perfherder/tests/TestsTable.jsx b/ui/perfherder/tests/TestsTable.jsx
index 2cd71fc4044..199bf2751c9 100644
--- a/ui/perfherder/tests/TestsTable.jsx
+++ b/ui/perfherder/tests/TestsTable.jsx
@@ -1,6 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
-import { Container } from 'reactstrap';
+import { Container } from 'react-bootstrap';
import ReactTable from 'react-table-6';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import {
diff --git a/ui/perfherder/tests/TestsTableControls.jsx b/ui/perfherder/tests/TestsTableControls.jsx
index 9840a94a8e3..9230bf4a9a3 100644
--- a/ui/perfherder/tests/TestsTableControls.jsx
+++ b/ui/perfherder/tests/TestsTableControls.jsx
@@ -1,6 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
-import { Container } from 'reactstrap';
+import { Container } from 'react-bootstrap';
import FilterControls from '../../shared/FilterControls';
import { containsText } from '../perf-helpers/helpers';
diff --git a/ui/perfherder/tests/TestsView.jsx b/ui/perfherder/tests/TestsView.jsx
index e109bd86fae..10707df147c 100644
--- a/ui/perfherder/tests/TestsView.jsx
+++ b/ui/perfherder/tests/TestsView.jsx
@@ -1,6 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
-import { Col, Container, Row } from 'reactstrap';
+import { Col, Container, Row } from 'react-bootstrap';
import withValidation from '../Validation';
import { getFrameworkData } from '../perf-helpers/helpers';
diff --git a/ui/push-health/Action.jsx b/ui/push-health/Action.jsx
index 21c80b8e15e..7f15c01b753 100644
--- a/ui/push-health/Action.jsx
+++ b/ui/push-health/Action.jsx
@@ -50,7 +50,7 @@ class Action extends PureComponent {
const groupedTests = this.getTestGroups(tests);
return (
-
+
{name}
{groupedTests.map((test) => (
diff --git a/ui/push-health/ClassificationGroup.jsx b/ui/push-health/ClassificationGroup.jsx
index 340b0629366..4223937c04f 100644
--- a/ui/push-health/ClassificationGroup.jsx
+++ b/ui/push-health/ClassificationGroup.jsx
@@ -10,16 +10,10 @@ import {
Row,
Collapse,
ButtonGroup,
- ButtonDropdown,
+ DropdownButton,
Button,
- DropdownMenu,
- DropdownToggle,
- DropdownItem,
- Navbar,
- Nav,
- NavItem,
- UncontrolledButtonDropdown,
-} from 'reactstrap';
+ Dropdown,
+} from 'react-bootstrap';
import groupBy from 'lodash/groupBy';
import JobModel from '../models/job';
@@ -32,7 +26,6 @@ class ClassificationGroup extends React.PureComponent {
this.state = {
detailsShowing: props.expanded,
- retriggerDropdownOpen: false,
};
}
@@ -47,12 +40,6 @@ class ClassificationGroup extends React.PureComponent {
}));
};
- toggleRetrigger = () => {
- this.setState((prevState) => ({
- retriggerDropdownOpen: !prevState.retriggerDropdownOpen,
- }));
- };
-
retriggerAll = (times) => {
const { tests, notify, currentRepo, jobs } = this.props;
// Reduce down to the unique jobs
@@ -87,7 +74,7 @@ class ClassificationGroup extends React.PureComponent {
};
render() {
- const { detailsShowing, retriggerDropdownOpen } = this.state;
+ const { detailsShowing } = this.state;
const {
jobs,
tests,
@@ -121,164 +108,147 @@ class ClassificationGroup extends React.PureComponent {
return (
-
+
{name} ({groupLength})
{hasRetriggerAll && groupLength > 0 && detailsShowing && (
-
-
-
-
- this.retriggerAll(1)}
- size="sm"
- >
-
- Retrigger all
-
-
-
-
- {[5, 10, 15].map((times) => (
- this.retriggerAll(times)}
- className="pointable"
- tag="a"
- >
- Retrigger all {times} times
-
- ))}
-
-
-
-
-
-
-
- Group By: {groupedBy}
-
-
- setGroupedBy('none')}
- >
- None
-
- {
- setGroupedBy('path');
- }}
- >
- Path
-
- setGroupedBy('platform')}
- >
- Platform
-
-
-
-
-
-
-
- Order By: {orderedBy}
-
-
- {
- setOrderedBy('count');
- }}
- >
- Count
-
-
+
+ this.retriggerAll(1)}
+ size="sm"
+ variant="secondary"
+ >
+
+ Retrigger all
+
+
+
+
+ {[5, 10, 15].map((times) => (
+ this.retriggerAll(times)}
className="pointable"
tag="a"
- onClick={() => {
- setOrderedBy('text');
- }}
>
- Text
-
-
-
-
-
-
+ Retrigger all {times} times
+
+ ))}
+
+
+
+
+ setGroupedBy('none')}
+ >
+ None
+
+ {
+ setGroupedBy('path');
+ }}
+ >
+ Path
+
+ setGroupedBy('platform')}
+ >
+ Platform
+
+
+
+ {
+ setOrderedBy('count');
+ }}
+ >
+ Count
+
+ {
+ setOrderedBy('text');
+ }}
+ >
+ Text
+
+
+
)}
-
- {testsByAction.length > 0 &&
- testsByAction.map(([key, value]) => (
-
- ))}
+
+
+ {testsByAction.length > 0 &&
+ testsByAction.map(([key, value]) => (
+
+ ))}
+
);
diff --git a/ui/push-health/CommitHistory.jsx b/ui/push-health/CommitHistory.jsx
index 1d15ab01d69..6bd451068c9 100644
--- a/ui/push-health/CommitHistory.jsx
+++ b/ui/push-health/CommitHistory.jsx
@@ -1,6 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
-import { Alert, Button } from 'reactstrap';
+import { Alert, Button } from 'react-bootstrap';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faCaretUp, faCaretRight } from '@fortawesome/free-solid-svg-icons';
@@ -84,7 +84,7 @@ class CommitHistory extends React.PureComponent {
Push
-
+
{currentRepo.name}
@@ -113,7 +113,7 @@ class CommitHistory extends React.PureComponent {
{revisions.length > 1 && (
-
+
)}
{showParent && (
-
+
Base commit:
{!exactMatch && (
-
+
Warning: Could not find an exact match parent Push in
Treeherder.
@@ -157,7 +157,7 @@ class CommitHistory extends React.PureComponent {
rel="noopener noreferrer"
title="View this push"
data-testid="parent-commit-sha"
- className="mr-1 ml-1 font-weight-bold text-secondary"
+ className="me-1 ms-1 font-weight-bold text-secondary"
>
{parentPushRevision || parentSha}
@@ -182,9 +182,8 @@ class CommitHistory extends React.PureComponent {
@@ -194,7 +193,7 @@ class CommitHistory extends React.PureComponent {
aria-label={expandTitle}
alt=""
/>
- {expandText}
+ {expandText}
)}
diff --git a/ui/push-health/Health.jsx b/ui/push-health/Health.jsx
index 420162b430c..ab78a83db2b 100644
--- a/ui/push-health/Health.jsx
+++ b/ui/push-health/Health.jsx
@@ -1,6 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
-import { Container, Spinner, Navbar, Nav } from 'reactstrap';
+import { Container, Spinner, Navbar, Nav } from 'react-bootstrap';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import camelCase from 'lodash/camelCase';
import { Helmet } from 'react-helmet';
@@ -179,11 +179,11 @@ export default class Health extends React.PureComponent {
const { notify } = this.props;
return (
-
+
{!!tests && (
-
+
-
+
-
+
{commitHistory.details && (
{linting.result !== 'none' && (
-
+
@@ -241,20 +241,20 @@ export default class Health extends React.PureComponent {
)}
{builds.result !== 'none' && (
-
+
Builds
)}
{tests.result !== 'none' && (
-
+
Tests
@@ -317,7 +317,7 @@ export default class Health extends React.PureComponent {
{!failureMessage && !tests && (
- Gathering health data...
+ Gathering health data...
)}
diff --git a/ui/push-health/MyPushes.jsx b/ui/push-health/MyPushes.jsx
index 36ad5d3eb7a..aede85f2e63 100644
--- a/ui/push-health/MyPushes.jsx
+++ b/ui/push-health/MyPushes.jsx
@@ -3,11 +3,10 @@ import {
Container,
Row,
Col,
- UncontrolledButtonDropdown,
- DropdownToggle,
+ DropdownButton,
Navbar,
Nav,
-} from 'reactstrap';
+} from 'react-bootstrap';
import { Helmet } from 'react-helmet';
import faviconBroken from '../img/push-health-broken.png';
@@ -150,15 +149,16 @@ class MyPushes extends React.Component {
return (
-
-
+
+
-
-
- {`${selectedRepo} pushes`}
+
+
this.setState({ selectedRepo, loading: true }, () =>
@@ -168,7 +168,7 @@ class MyPushes extends React.Component {
selectedItem={selectedRepo}
options={['try', 'all']}
/>
-
+
@@ -195,7 +195,7 @@ class MyPushes extends React.Component {
className="mt-5 flex-nowrap justify-content-center"
key={push.revision}
>
-
+
@@ -220,7 +220,7 @@ class MyPushes extends React.Component {
/>
)}
-
+
{push.metrics.builds.result !== 'none' && (
(
-
-
-
-
-
- My Pushes
-
-
-
-
+
+
+
+
+
+
+ My Pushes
+
+
+
+
+
-
+
);
diff --git a/ui/push-health/NotFound.jsx b/ui/push-health/NotFound.jsx
index fb07ee277d7..16528eb8e95 100644
--- a/ui/push-health/NotFound.jsx
+++ b/ui/push-health/NotFound.jsx
@@ -1,11 +1,11 @@
import React from 'react';
-import { Container, Row, Col, Alert } from 'reactstrap';
+import { Container, Row, Col, Alert } from 'react-bootstrap';
const NotFound = () => (
-
+
Missing required URL parameters of repo
and{' '}
revision
.
diff --git a/ui/push-health/PlatformConfig.jsx b/ui/push-health/PlatformConfig.jsx
index 86cf4315026..c43b7dfc750 100644
--- a/ui/push-health/PlatformConfig.jsx
+++ b/ui/push-health/PlatformConfig.jsx
@@ -1,6 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
-import { Button, Row, Col } from 'reactstrap';
+import { Button, Row, Col } from 'react-bootstrap';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faRedo } from '@fortawesome/free-solid-svg-icons';
import sortBy from 'lodash/sortBy';
@@ -76,26 +76,27 @@ class PlatformConfig extends React.PureComponent {
return (
-
+
{children}
-
+
{taskList.map((task, idx) => {
const { id, result, state, start_time: startTime } = task;
const isSelected = selectedTask && selectedTask.id === id;
return (
-
+
this.setSelectedTask(task)}
>
@@ -121,8 +122,8 @@ class PlatformConfig extends React.PureComponent {
})}
this.retriggerTask(taskList[0])}
- outline
- className="mr-2 border-0"
+ variant="outline"
+ className="me-2 border-0"
title="Retrigger task"
style={{ lineHeight: '10px' }}
>
diff --git a/ui/push-health/TaskSelection.jsx b/ui/push-health/TaskSelection.jsx
index ee96f232299..b5af7576f7a 100644
--- a/ui/push-health/TaskSelection.jsx
+++ b/ui/push-health/TaskSelection.jsx
@@ -1,6 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
-import { Row, Col, Input } from 'reactstrap';
+import { Row, Col, Form } from 'react-bootstrap';
class TaskSelection extends React.PureComponent {
constructor(props) {
@@ -41,11 +41,12 @@ class TaskSelection extends React.PureComponent {
return (
-
@@ -59,7 +60,7 @@ class TaskSelection extends React.PureComponent {
{groupedBy !== 'path' && `${testName} `}
{jobName}
{tier > 1 && (
- [tier-{tier}]
+ [tier-{tier}]
)}
diff --git a/ui/push-health/Test.jsx b/ui/push-health/Test.jsx
index 72a37f62014..de4b448298c 100644
--- a/ui/push-health/Test.jsx
+++ b/ui/push-health/Test.jsx
@@ -5,16 +5,10 @@ import {
Collapse,
Nav,
Navbar,
- NavItem,
- UncontrolledButtonDropdown,
ButtonGroup,
- DropdownMenu,
- DropdownToggle,
- DropdownItem,
- Input,
- FormGroup,
- Label,
-} from 'reactstrap';
+ Dropdown,
+ Form,
+} from 'react-bootstrap';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import {
faCaretDown,
@@ -75,7 +69,7 @@ class Test extends PureComponent {
.reduce(
(acc, test) => ({
...acc,
- ...jobs[test.jobName].reduce((fjAcc, job) => ({ [job.id]: job }), {}),
+ ...jobs[test.jobName].reduce((_, job) => ({ [job.id]: job }), {}),
}),
{},
);
@@ -241,23 +235,23 @@ class Test extends PureComponent {
>
{key === 'none' ? 'All' : this.getGroupHtml(key)}
-
+
({tests.length} failure{tests.length > 1 && 's'})
@@ -268,101 +262,106 @@ class Test extends PureComponent {
/>
-
-
-
-
-
+
+
+
+
+
+
+ this.retriggerSelected(1)}
+ size="sm"
+ variant="secondary"
+ >
+
+ Retrigger Selected
+
+
+
+
+ {[5, 10, 15].map((times) => (
+ this.retriggerSelected(times)}
+ className="pointable"
+ >
+ Retrigger selected {times} times
+
+ ))}
+
+
+
this.retriggerSelected(1)}
size="sm"
+ variant="outline-primary"
+ className="mx-3"
+ title="Mark selected jobs as investigated"
+ onClick={() => this.markAsInvestigated()}
>
-
- Retrigger Selected
+ Mark as investigated
-
-
-
- {[5, 10, 15].map((times) => (
- this.retriggerSelected(times)}
- className="pointable"
- tag="a"
- >
- Retrigger selected {times} times
-
- ))}
-
-
-
- this.markAsInvestigated()}
- >
- Mark as investigated
-
- this.markAsUninvestigated()}
- >
- Mark as Uninvestigated
-
-
-
-
-
diff --git a/ui/push-health/Usage.jsx b/ui/push-health/Usage.jsx
index 72f078585b5..71861e55d1d 100644
--- a/ui/push-health/Usage.jsx
+++ b/ui/push-health/Usage.jsx
@@ -1,5 +1,5 @@
import React, { Component } from 'react';
-import { Alert, Table, Jumbotron, Badge } from 'reactstrap';
+import { Alert, Table, Card, Badge } from 'react-bootstrap';
import { Link } from 'react-router-dom';
import { getData } from '../helpers/http';
@@ -34,13 +34,15 @@ class Usage extends Component {
return (
-
- Push Health Try Usage
-
- This shows the difference in count of need intermittents by push
- over time.
-
-
+
+
+ Push Health Try Usage
+
+ This shows the difference in count of need intermittents by push
+ over time.
+
+
+
@@ -81,7 +83,7 @@ class Usage extends Component {
{latestNI}
{toShortDateStr(latestTime)}
-
+
{peakNI - latestNI > 0 && peakNI - latestNI}
@@ -91,7 +93,7 @@ class Usage extends Component {
})}
- {failureMessage &&
{failureMessage} }
+ {failureMessage &&
{failureMessage} }
);
}
diff --git a/ui/push-health/details/DetailsPanel.jsx b/ui/push-health/details/DetailsPanel.jsx
index 5e93f438475..a4498c2dc88 100644
--- a/ui/push-health/details/DetailsPanel.jsx
+++ b/ui/push-health/details/DetailsPanel.jsx
@@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faTimes } from '@fortawesome/free-solid-svg-icons';
import { Tab, TabList, TabPanel, Tabs } from 'react-tabs';
-import { Col, Button, Spinner } from 'reactstrap';
+import { Col, Button, Spinner } from 'react-bootstrap';
import { getArtifactsUrl, getLogViewerUrl } from '../../helpers/url';
import { formatArtifacts } from '../../helpers/display';
@@ -159,33 +159,33 @@ class DetailsPanel extends React.Component {
{taskDetailLoading &&
}
{!!selectedTaskFull && !taskDetailLoading && (
-
+
-
+
Failure Summary
-
+
Log Viewer
-
+
Artifacts and Debugging Tools
-
+
@@ -211,7 +211,7 @@ class DetailsPanel extends React.Component {
/>
-
+
-
- Intermittent Bug Filer
-
+
+
+ Intermittent Bug Filer
+
+
+
+
+
-
Summary:
+
Summary:
{!!unhelpfulSummaryReason && (
@@ -724,13 +721,13 @@ export class BugFilerClass extends React.Component {
{searchTerms.map((term) => (
-
)}
-
this.toggleTooltip('toggleFailureLines')}
+ show={tooltipOpen.toggleFailureLines}
+ onToggle={() => this.toggleTooltip('toggleFailureLines')}
>
{isFilerSummaryVisible
? 'Hide all failure lines for this job'
@@ -764,13 +761,13 @@ export class BugFilerClass extends React.Component {
: faChevronCircleDown
}
size="lg"
- className="pointable align-bottom pt-2 ml-1"
+ className="pointable align-bottom pt-2 ms-1"
id="toggle-failure-lines"
title={isFilerSummaryVisible ? 'collapse' : 'expand'}
/>
255 ? 'text-danger' : 'text-success'
}`}
>
@@ -779,9 +776,9 @@ export class BugFilerClass extends React.Component {
{isFilerSummaryVisible && (
-
@@ -790,16 +787,16 @@ export class BugFilerClass extends React.Component {
/>
)}
-
-
- Comment:
- Comment:
+
this.setState({ comment: evt.target.value }, () =>
this.checkForSecurityIssue(),
)
}
- type="textarea"
+ as="textarea"
id="summary-input"
className="flex-grow-1"
rows={5}
/>
-
-
+
+ this.setState({ isSecurityIssue: !isSecurityIssue })
+ }
+ label="Report this as a security issue"
+ />
+ {['autoland', 'mozilla-central', 'try'].includes(
+ currentRepo.name,
+ ) && (
+
+
this.setState({
launchConfirmFailure: !launchConfirmFailure,
})
}
+ label="Launch the Confirm Failures task at bug submission"
/>
- Launch the Confirm Failures task at bug submission
-
-
- )}
- {!!crashSignatures.length && (
-
- Signature:
-
- this.setState({ crashSignatures: evt.target.value })
- }
- maxLength="2048"
- readOnly
- value={crashSignatures.join('\n')}
- />
-
- )}
+
+ )}
+ {!!crashSignatures.length && (
+
+
+ Signature:
+
+
+ this.setState({ crashSignatures: evt.target.value })
+ }
+ maxLength="2048"
+ readOnly
+ value={crashSignatures.join('\n')}
+ />
+
+ )}
+
-
-
-
+
+
+
Submit Bug
{' '}
-
+
Cancel
-
+
);
@@ -974,43 +969,48 @@ BugFilerClass.propTypes = {
isOpen: PropTypes.bool.isRequired,
toggle: PropTypes.func.isRequired,
suggestion: PropTypes.shape({}).isRequired,
- suggestions: PropTypes.arrayOf({
- bugs: PropTypes.shape({
- open_recent: PropTypes.arrayOf({
- crash_signature: PropTypes.string.isRequired,
- dupe_of: PropTypes.oneOfType([
- PropTypes.oneOf([null]),
- PropTypes.number,
- ]).isRequired,
- id: PropTypes.number.isRequired,
- keywords: PropTypes.string.isRequired,
- status: PropTypes.string.isRequired,
- resolution: PropTypes.string.isRequired,
- summary: PropTypes.string.isRequired,
- whiteboard: PropTypes.string.isRequired,
- }),
- all_others: PropTypes.arrayOf({
- crash_signature: PropTypes.string.isRequired,
- dupe_of: PropTypes.oneOfType([
- PropTypes.oneOf([null]),
- PropTypes.number,
- ]).isRequired,
- id: PropTypes.number.isRequired,
- keywords: PropTypes.string.isRequired,
- status: PropTypes.string.isRequired,
- resolution: PropTypes.string.isRequired,
- summary: PropTypes.string.isRequired,
- whiteboard: PropTypes.string.isRequired,
+ suggestions: PropTypes.arrayOf(
+ PropTypes.shape({
+ bugs: PropTypes.shape({
+ open_recent: PropTypes.arrayOf(
+ PropTypes.shape({
+ crash_signature: PropTypes.string.isRequired,
+ dupe_of: PropTypes.oneOfType([
+ PropTypes.oneOf([null]),
+ PropTypes.number,
+ ]).isRequired,
+ id: PropTypes.number.isRequired,
+ keywords: PropTypes.string.isRequired,
+ status: PropTypes.string.isRequired,
+ resolution: PropTypes.string.isRequired,
+ summary: PropTypes.string.isRequired,
+ whiteboard: PropTypes.string.isRequired,
+ }),
+ ),
+ all_others: PropTypes.arrayOf(
+ PropTypes.shape({
+ crash_signature: PropTypes.string.isRequired,
+ dupe_of: PropTypes.oneOfType([
+ PropTypes.oneOf([null]),
+ PropTypes.number,
+ ]).isRequired,
+ id: PropTypes.number.isRequired,
+ keywords: PropTypes.string.isRequired,
+ status: PropTypes.string.isRequired,
+ resolution: PropTypes.string.isRequired,
+ summary: PropTypes.string.isRequired,
+ whiteboard: PropTypes.string.isRequired,
+ }),
+ ),
}),
+ counter: PropTypes.number.isRequired,
+ failure_in_new_rev: PropTypes.bool.isRequired,
+ line_number: PropTypes.number.isRequired,
+ path_end: PropTypes.string,
+ search: PropTypes.string.isRequired,
+ search_terms: PropTypes.arrayOf(PropTypes.string),
}),
- counter: PropTypes.number.isRequired,
- failure_in_new_rev: PropTypes.bool.isRequired,
- line_number: PropTypes.number.isRequired,
- path_end: PropTypes.oneOfType([PropTypes.oneOf([null]), PropTypes.string])
- .isRequired,
- search: PropTypes.string.isRequired,
- search_terms: PropTypes.arrayOf(PropTypes.string),
- }).isRequired,
+ ).isRequired,
fullLog: PropTypes.string.isRequired,
parsedLog: PropTypes.string.isRequired,
reftestUrl: PropTypes.string.isRequired,
@@ -1018,7 +1018,7 @@ BugFilerClass.propTypes = {
platform: PropTypes.string.isRequired,
notify: PropTypes.func.isRequired,
selectedJob: PropTypes.shape({}).isRequired,
- currentRepo: PropTypes.string.isRequired,
+ currentRepo: PropTypes.shape({ name: PropTypes.string }).isRequired,
};
const mapStateToProps = ({ pushes: { decisionTaskMap } }) => ({
diff --git a/ui/shared/CallbackMessage.jsx b/ui/shared/CallbackMessage.jsx
index 22b7d0ae1c2..71c270fa2c1 100644
--- a/ui/shared/CallbackMessage.jsx
+++ b/ui/shared/CallbackMessage.jsx
@@ -1,6 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
-import { Row } from 'reactstrap';
+import { Row } from 'react-bootstrap';
import ErrorMessages from './ErrorMessages';
diff --git a/ui/shared/Clipboard.jsx b/ui/shared/Clipboard.jsx
index aa145a6f0a0..a102e882f61 100644
--- a/ui/shared/Clipboard.jsx
+++ b/ui/shared/Clipboard.jsx
@@ -5,7 +5,7 @@ import {
faClipboard,
faCheckCircle,
} from '@fortawesome/free-regular-svg-icons';
-import { Button } from 'reactstrap';
+import { Button } from 'react-bootstrap';
export default class Clipboard extends React.Component {
constructor(props) {
@@ -25,9 +25,28 @@ export default class Clipboard extends React.Component {
};
render() {
- const { description, text, outline, color } = this.props;
+ const { description, text, outline, color, variant } = this.props;
const { copied } = this.state;
+ if (!text) {
+ return null;
+ }
+
+ let buttonVariant;
+ let buttonStyle = {};
+ let iconClassName = '';
+
+ if (variant === 'transparent') {
+ buttonVariant = 'link';
+ buttonStyle = { backgroundColor: 'transparent', border: 'none' };
+ iconClassName = 'text-dark';
+ } else if (variant) {
+ buttonVariant = variant;
+ } else {
+ const baseColor = color || 'light';
+ buttonVariant = outline ? `outline-${baseColor}` : baseColor;
+ }
+
return (
{copied ? (
-
+
) : (
-
+
)}
);
@@ -54,6 +76,8 @@ Clipboard.propTypes = {
description: PropTypes.string.isRequired,
text: PropTypes.string,
outline: PropTypes.bool,
+ color: PropTypes.string,
+ variant: PropTypes.string,
};
Clipboard.defaultProps = {
diff --git a/ui/shared/ComparePageTitle.jsx b/ui/shared/ComparePageTitle.jsx
index 056c44d7488..6d4dfc7cb46 100644
--- a/ui/shared/ComparePageTitle.jsx
+++ b/ui/shared/ComparePageTitle.jsx
@@ -1,7 +1,7 @@
import React from 'react';
import { Helmet } from 'react-helmet';
import PropTypes from 'prop-types';
-import { Button, Input, InputGroup } from 'reactstrap';
+import { Button, Form, InputGroup } from 'react-bootstrap';
import { faEdit } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
@@ -112,7 +112,7 @@ export default class ComparePageTitle extends React.Component {
@@ -126,10 +126,10 @@ export default class ComparePageTitle extends React.Component {
) : (
-
Save
-
+
Cancel
diff --git a/ui/shared/DropdownMenuItems.jsx b/ui/shared/DropdownMenuItems.jsx
index 829dc324ebe..8dfdeb9c53e 100644
--- a/ui/shared/DropdownMenuItems.jsx
+++ b/ui/shared/DropdownMenuItems.jsx
@@ -1,6 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
-import { DropdownMenu, DropdownItem } from 'reactstrap';
+import { Dropdown } from 'react-bootstrap';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faCheck } from '@fortawesome/free-solid-svg-icons';
@@ -12,31 +12,31 @@ const createDropdownItem = (
className,
) => {
return (
-
updateData(item)}
className={`${className || ''}`}
>
{item}
-
+
);
};
const DropdownMenuItems = ({
- selectedItem,
- updateData,
+ selectedItem = null,
+ updateData = null,
options,
- pinned,
- namespace,
- otherPinned,
+ pinned = [],
+ namespace = '',
+ otherPinned = [],
}) => (
-
+ <>
{/* Items pinned to top of dropdown */}
{pinned.length > 0 && (
@@ -49,7 +49,7 @@ const DropdownMenuItems = ({
'top-pinned',
),
)}
-
+
)}
{options.map((item) =>
@@ -58,7 +58,7 @@ const DropdownMenuItems = ({
{/* Items pinned to bottom of dropdown */}
{otherPinned.length > 0 && (
-
+
{otherPinned.map((item) =>
createDropdownItem(
item,
@@ -70,7 +70,7 @@ const DropdownMenuItems = ({
)}
)}
-
+ >
);
DropdownMenuItems.propTypes = {
@@ -83,12 +83,4 @@ DropdownMenuItems.propTypes = {
otherPinned: PropTypes.arrayOf(PropTypes.string),
};
-DropdownMenuItems.defaultProps = {
- updateData: null,
- selectedItem: null,
- pinned: [],
- namespace: '',
- otherPinned: [],
-};
-
export default DropdownMenuItems;
diff --git a/ui/shared/ErrorBoundary.jsx b/ui/shared/ErrorBoundary.jsx
index 989f477b7e2..fa0cc078976 100644
--- a/ui/shared/ErrorBoundary.jsx
+++ b/ui/shared/ErrorBoundary.jsx
@@ -33,7 +33,7 @@ export default class ErrorBoundary extends React.Component {
}
ErrorBoundary.propTypes = {
- children: PropTypes.oneOfType([PropTypes.object, PropTypes.bool]),
+ children: PropTypes.node,
errorClasses: PropTypes.string,
message: PropTypes.string,
};
diff --git a/ui/shared/ErrorMessages.jsx b/ui/shared/ErrorMessages.jsx
index 05197da63b7..b4535f992af 100644
--- a/ui/shared/ErrorMessages.jsx
+++ b/ui/shared/ErrorMessages.jsx
@@ -1,6 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
-import { Alert } from 'reactstrap';
+import { Alert } from 'react-bootstrap';
class ErrorMessages extends React.PureComponent {
constructor(props) {
@@ -33,7 +33,7 @@ class ErrorMessages extends React.PureComponent {
{messages.map((message) => (
this.setState({ visible: !visible })}
key={message}
diff --git a/ui/shared/FilterControls.jsx b/ui/shared/FilterControls.jsx
index 470df3c3b7d..81ed73fe3d8 100644
--- a/ui/shared/FilterControls.jsx
+++ b/ui/shared/FilterControls.jsx
@@ -1,19 +1,12 @@
import React from 'react';
import PropTypes from 'prop-types';
-import {
- Col,
- Row,
- Container,
- Button,
- UncontrolledDropdown,
- DropdownToggle,
-} from 'reactstrap';
+import { Col, Row, Container, Button, Dropdown } from 'react-bootstrap';
import SimpleTooltip from './SimpleTooltip';
import DropdownMenuItems from './DropdownMenuItems';
import InputFilter from './InputFilter';
-export const createDropdowns = (dropdownOptions, colClass, outline = false) => (
+export const createDropdowns = (dropdownOptions, colClass) => (
{dropdownOptions.map((dropdown) => (
(
className={colClass}
key={`dropdown ${dropdown.namespace || ''}${dropdown.selectedItem}`}
>
-
-
+
{dropdown.selectedItem}
-
-
-
+
+
+
+
+
))}
@@ -54,8 +49,7 @@ const FilterControls = ({
}) => {
const createButton = (filter) => (
updateFilter(filter.stateName)}
active={filter.state}
disabled={filter.disable}
@@ -68,15 +62,15 @@ const FilterControls = ({
{!dropdownCol && dropdownOptions.length > 0 && (
- {createDropdowns(dropdownOptions, 'py-0 pl-0 pr-3')}
+ {createDropdowns(dropdownOptions, 'py-0 ps-0 pe-3')}
)}
-
+
{dropdownCol &&
dropdownOptions.length > 0 &&
- createDropdowns(dropdownOptions, 'py-2 pl-0 pr-3')}
+ createDropdowns(dropdownOptions, 'py-2 ps-0 pe-3')}
-
+
(
-
-
+
+
Help
-
-
+
+
{menuItems.map((item) => (
- (
{item.text}
-
+
))}
-
-
+
+
);
export default HelpMenu;
diff --git a/ui/shared/InputFilter.jsx b/ui/shared/InputFilter.jsx
index b811919d8f7..1c028c03e82 100644
--- a/ui/shared/InputFilter.jsx
+++ b/ui/shared/InputFilter.jsx
@@ -1,6 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
-import { InputGroup, Input } from 'reactstrap';
+import { InputGroup, Form } from 'react-bootstrap';
import debounce from 'lodash/debounce';
import { filterText } from '../perfherder/perf-helpers/constants';
@@ -56,7 +56,7 @@ export default class InputFilter extends React.Component {
return (
-
-
-
+
+
Intermittent Internal Issue Filer
-
-
+
+
Summary:
-
255 ? 'text-danger' : 'text-success'
}`}
>
@@ -192,15 +184,15 @@ export class InternalIssueFilerClass extends React.Component {
-
-
-
+
+
+
Submit Internal Issue
{' '}
-
+
Cancel
-
+
);
diff --git a/ui/shared/JobArtifacts.jsx b/ui/shared/JobArtifacts.jsx
index dbb90719e5f..b5d1d6b32bc 100644
--- a/ui/shared/JobArtifacts.jsx
+++ b/ui/shared/JobArtifacts.jsx
@@ -98,11 +98,13 @@ export default class JobArtifacts extends React.PureComponent {
}
JobArtifacts.propTypes = {
- jobDetails: PropTypes.arrayOf({
- url: PropTypes.string.isRequired,
- value: PropTypes.string.isRequired,
- title: PropTypes.string.isRequired,
- }),
+ jobDetails: PropTypes.arrayOf(
+ PropTypes.shape({
+ url: PropTypes.string.isRequired,
+ value: PropTypes.string.isRequired,
+ title: PropTypes.string.isRequired,
+ }),
+ ),
jobArtifactsLoading: PropTypes.bool,
repoName: PropTypes.string.isRequired,
selectedJob: PropTypes.shape({}).isRequired,
diff --git a/ui/shared/JobInfo.jsx b/ui/shared/JobInfo.jsx
index bca2a1d27f4..af30f42d0b8 100644
--- a/ui/shared/JobInfo.jsx
+++ b/ui/shared/JobInfo.jsx
@@ -53,12 +53,13 @@ export default class JobInfo extends React.PureComponent {
const timeFields = getTimeFields(job);
return (
-
+
Job:
{showJobFilters ? (
@@ -74,6 +75,7 @@ export default class JobInfo extends React.PureComponent {
Task:
choice.text !== menuText);
return (
-
-
+
{menuImage ? (
@@ -33,15 +27,15 @@ export default class LogoMenu extends React.PureComponent {
) : (
{menuText}
)}
-
-
+
+
{menuChoices.map((choice) => (
-
+
{choice.text}
-
+
))}
-
-
+
+
);
}
}
diff --git a/ui/shared/NotificationList.jsx b/ui/shared/NotificationList.jsx
index c8d85bc387c..0516d60c438 100644
--- a/ui/shared/NotificationList.jsx
+++ b/ui/shared/NotificationList.jsx
@@ -7,7 +7,7 @@ import {
faCircle,
faExclamationTriangle,
} from '@fortawesome/free-solid-svg-icons';
-import { Alert, Button } from 'reactstrap';
+import { Alert, Button } from 'react-bootstrap';
class NotificationList extends React.Component {
static getIcon(severity) {
@@ -31,12 +31,12 @@ class NotificationList extends React.Component {
{notifications.map((notification, idx) => (
-
+
- {notification.message}
+ {notification.message}
{notification.url && notification.linkText && (
{notification.linkText}
diff --git a/ui/shared/ProgressBar.jsx b/ui/shared/ProgressBar.jsx
index f346cbf0291..64911b317e8 100644
--- a/ui/shared/ProgressBar.jsx
+++ b/ui/shared/ProgressBar.jsx
@@ -1,6 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
-import { Progress } from 'reactstrap';
+import { ProgressBar as BSProgressBar } from 'react-bootstrap';
import SimpleTooltip from './SimpleTooltip';
@@ -8,28 +8,31 @@ const ProgressBar = ({ magnitude, regression, color }) => {
const truncMag = regression
? (Math.floor((100 - magnitude) * 100) / 100).toFixed(2)
: (Math.floor(magnitude * 100) / 100).toFixed(2);
+
+ // For regression, show colored bar on the right
+ // For improvement, show colored bar on the left
+ const leftValue = regression ? 100 - magnitude : magnitude;
+ const rightValue = regression ? magnitude : 100 - magnitude;
+
return (
- {/* the % of the bars that are colored and transparent is based on the newIsBetter metric,
- which determines whether the colored bar for magnitude is displayed on the left or right */}
-
-
+
+
+
}
tooltipText="Relative magnitude of change (scale from 0 - 20%+)"
/>
diff --git a/ui/shared/PushHealthStatus.jsx b/ui/shared/PushHealthStatus.jsx
index 231fb392f7b..6c7a52663cd 100644
--- a/ui/shared/PushHealthStatus.jsx
+++ b/ui/shared/PushHealthStatus.jsx
@@ -1,6 +1,6 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
-import { Badge } from 'reactstrap';
+import { Badge } from 'react-bootstrap';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import {
faCheck,
@@ -64,7 +64,7 @@ class PushHealthStatus extends Component {
} = this.props;
const { needInvestigation } = this.state;
let healthStatus = 'In progress';
- let badgeColor = 'darker-secondary';
+ let badgeColor = 'secondary';
let extraTitle = 'No errors so far';
let icon = faClock;
@@ -95,10 +95,12 @@ class PushHealthStatus extends Component {
rel="noopener noreferrer"
>
-
+
{healthStatus}
diff --git a/ui/shared/PushHealthSummary.jsx b/ui/shared/PushHealthSummary.jsx
index a62e7b9fb92..a0c69b45646 100644
--- a/ui/shared/PushHealthSummary.jsx
+++ b/ui/shared/PushHealthSummary.jsx
@@ -1,6 +1,6 @@
import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
-import { Col, Row } from 'reactstrap';
+import { Col, Row } from 'react-bootstrap';
import { faHeart } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
@@ -35,7 +35,7 @@ class PushHealthSummary extends PureComponent {
if (noResultsFound) return ;
return (
-
+
) : (
@@ -60,7 +60,7 @@ class PushHealthSummary extends PureComponent {
icon={faHeart}
height={heartSize}
width={heartSize}
- color="darker-secondary"
+ variant="darker-secondary"
/>
)}
@@ -69,7 +69,7 @@ class PushHealthSummary extends PureComponent {
{healthStatus && (
-
+
{linting.result !== 'none' && (
-
+
{initials}
@@ -81,11 +81,11 @@ export class Revision extends React.PureComponent {
: 'text-secondary';
return (
-
+
this.showClipboard(true)}
onMouseLeave={() => this.showClipboard(false)}
- className="pr-1 text-nowrap"
+ className="pe-1 text-nowrap"
>
-
-
- {comment}
-
-
-
+ {bugSummaryMap &&
+ !!bugMatches &&
+ bugMatches.map((bug) => {
+ const bugId = bug.split(' ')[1];
+ return (
+
+ Bug {bugId} - {bugSummaryMap[bugId]}
+
+ );
+ })}
+ Commit:
+ {comment}
+
+ }
>
- {bugSummaryMap &&
- !!bugMatches &&
- bugMatches.map((bug) => {
- const bugId = bug.split(' ')[1];
- return (
-
- Bug {bugId} - {bugSummaryMap[bugId]}
-
- );
- })}
- Commit:
- {comment}
-
-
+
+
+ {comment}
+
+
+
+
);
}
}
diff --git a/ui/shared/RevisionInformation.jsx b/ui/shared/RevisionInformation.jsx
index 3c432ae7c70..24958d87015 100644
--- a/ui/shared/RevisionInformation.jsx
+++ b/ui/shared/RevisionInformation.jsx
@@ -1,6 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
-import { ListGroup, ListGroupItem } from 'reactstrap';
+import { ListGroup } from 'react-bootstrap';
import { getJobsUrl } from '../helpers/url';
@@ -61,17 +61,17 @@ export default function RevisionInformation(props) {
return (
{originalRevision && (
-
+
{getRevisionSpecificDetails(
originalRevision,
originalProject,
true,
originalResultSet,
)}
-
+
)}
{selectedTimeRange && (
-
+
{getRevisionSpecificDetails(
originalRevision,
originalProject,
@@ -79,18 +79,18 @@ export default function RevisionInformation(props) {
null,
selectedTimeRange,
)}
-
+
)}
—
{newRevision && (
-
+
{getRevisionSpecificDetails(
newRevision,
newProject,
false,
newResultSet,
)}
-
+
)}
);
diff --git a/ui/shared/RevisionList.jsx b/ui/shared/RevisionList.jsx
index e42d577ab60..06f2423a331 100644
--- a/ui/shared/RevisionList.jsx
+++ b/ui/shared/RevisionList.jsx
@@ -1,6 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
-import { Col, Row } from 'reactstrap';
+import { Row } from 'react-bootstrap';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faExternalLinkSquareAlt } from '@fortawesome/free-solid-svg-icons';
@@ -21,7 +21,7 @@ export class RevisionList extends React.PureComponent {
} = this.props;
return (
-
+
{revisions.map((revision) => (
)}
{children}
-
+
);
}
}
@@ -69,10 +69,10 @@ RevisionList.defaultProps = {
export function MoreRevisionsLink(props) {
return (
-
+
{'\u2026and more'}
-
+
);
diff --git a/ui/shared/SimpleTooltip.jsx b/ui/shared/SimpleTooltip.jsx
index 9c2be9db862..049de3ec871 100644
--- a/ui/shared/SimpleTooltip.jsx
+++ b/ui/shared/SimpleTooltip.jsx
@@ -1,40 +1,29 @@
import React from 'react';
import PropTypes from 'prop-types';
-import { UncontrolledTooltip } from 'reactstrap';
+import { OverlayTrigger, Tooltip } from 'react-bootstrap';
-export default class SimpleTooltip extends React.Component {
- constructor(props) {
- super(props);
- this.tooltipRef = React.createRef();
- }
+const SimpleTooltip = ({
+ text,
+ tooltipText,
+ placement = 'top',
+ textClass = '',
+ innerClassName = '',
+ autohide = true,
+}) => {
+ const tooltip = {tooltipText} ;
- render() {
- const {
- text,
- tooltipText,
- placement,
- textClass,
- innerClassName,
- autohide,
- } = this.props;
+ return (
+
+ {text}
+
+ );
+};
- return (
-
-
- {text}
-
-
- {tooltipText}
-
-
- );
- }
-}
+export default SimpleTooltip;
SimpleTooltip.propTypes = {
text: PropTypes.oneOfType([PropTypes.shape({}), PropTypes.string]).isRequired,
tooltipText: PropTypes.oneOfType([PropTypes.shape({}), PropTypes.string])
@@ -44,10 +33,3 @@ SimpleTooltip.propTypes = {
innerClassName: PropTypes.string,
autohide: PropTypes.bool,
};
-
-SimpleTooltip.defaultProps = {
- textClass: '',
- placement: 'top',
- innerClassName: '',
- autohide: true,
-};
diff --git a/ui/shared/StatusButton.jsx b/ui/shared/StatusButton.jsx
index eab86b20e3e..f18376acb69 100644
--- a/ui/shared/StatusButton.jsx
+++ b/ui/shared/StatusButton.jsx
@@ -42,7 +42,7 @@ const StatusButton = ({
{text}
diff --git a/ui/shared/StatusProgress.jsx b/ui/shared/StatusProgress.jsx
index cb6da6cb788..10201294707 100644
--- a/ui/shared/StatusProgress.jsx
+++ b/ui/shared/StatusProgress.jsx
@@ -4,14 +4,11 @@ import { VictoryPie, VictoryTooltip } from 'victory';
import { getPercentComplete } from '../helpers/display';
-const StatusProgress = (props) => {
+const StatusProgress = ({ counts, customStyle = '' }) => {
// testfailed includes lint, build ("busted") and test failures
// but excludes intermittent failures
- const {
- counts: { success, testfailed, running, pending },
- customStyle,
- } = props;
- const percentComplete = props.counts ? getPercentComplete(props.counts) : 0;
+ const { success, testfailed, running, pending } = counts;
+ const percentComplete = counts ? getPercentComplete(counts) : 0;
let data = [
{ x: 'success', y: success },
{ x: 'in progress', y: running + pending },
@@ -20,7 +17,7 @@ const StatusProgress = (props) => {
if (percentComplete === 100) data = [{ x: 'success', y: percentComplete }];
return (
-
+
@@ -22,11 +25,10 @@ export default class TruncatedText extends React.Component {
{text.length > maxLength && (
this.setState({ showMoreResults: !showMoreResults })}
>
{`show ${showMoreResults ? 'less' : 'more'}`}
diff --git a/ui/shared/auth/Login.jsx b/ui/shared/auth/Login.jsx
index 5fde23fbb78..0332529cf18 100644
--- a/ui/shared/auth/Login.jsx
+++ b/ui/shared/auth/Login.jsx
@@ -1,12 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
-import {
- Button,
- DropdownMenu,
- DropdownItem,
- DropdownToggle,
- UncontrolledDropdown,
-} from 'reactstrap';
+import { Button, Dropdown } from 'react-bootstrap';
import isEqual from 'lodash/isEqual';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faUser } from '@fortawesome/free-solid-svg-icons';
@@ -110,27 +104,27 @@ class Login extends React.Component {
return (
{user && user.isLoggedIn ? (
-
-
+
{user.fullName}
-
-
-
+
+
+
Logout
-
-
-
+
+
+
) : (
Login / Register
diff --git a/ui/shared/tabs/LogviewerTab.jsx b/ui/shared/tabs/LogviewerTab.jsx
index 3559f97d99b..c5ef1bb5c01 100644
--- a/ui/shared/tabs/LogviewerTab.jsx
+++ b/ui/shared/tabs/LogviewerTab.jsx
@@ -52,13 +52,13 @@ class LogviewerTab extends React.PureComponent {
-
+
Full Screen
-
+
Text Log
diff --git a/ui/shared/tabs/failureSummary/BugListItem.jsx b/ui/shared/tabs/failureSummary/BugListItem.jsx
index 55b317029c5..eea1ae2fbc6 100644
--- a/ui/shared/tabs/failureSummary/BugListItem.jsx
+++ b/ui/shared/tabs/failureSummary/BugListItem.jsx
@@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
import Highlighter from 'react-highlight-words';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faBug, faThumbtack } from '@fortawesome/free-solid-svg-icons';
-import { Button } from 'reactstrap';
+import { Button } from 'react-bootstrap';
import { getSearchWords } from '../../../helpers/display';
import { getBugUrl } from '../../../helpers/url';
@@ -24,7 +24,7 @@ function BugListItem(props) {
const internalOccurrenceButton = (
addBug(bug, selectedJob)}
@@ -36,7 +36,7 @@ function BugListItem(props) {
const bugzillaButton = (
toggleBugFiler(suggestion)}
title={
@@ -58,14 +58,14 @@ function BugListItem(props) {
bug.occurrences >= requiredInternalOccurrences &&
bugzillaButton}
{bug.bugzilla_id}
- i{bug.internal_id}
+ i{bug.internal_id}
{!bug.id && (
-
+
({bug.occurrences} occurrences{' '}
)
{' '}
- {bug.summary}
+ {bug.summary}
{!!addBug &&
bug.occurrences >= requiredInternalOccurrences &&
internalOccurrenceButton}
@@ -76,7 +76,7 @@ function BugListItem(props) {
)}
{bug.id && (
- View log
+ View log
));
diff --git a/ui/shared/tabs/failureSummary/FailureSummaryTab.jsx b/ui/shared/tabs/failureSummary/FailureSummaryTab.jsx
index 30e20cf4f9b..a235d892827 100644
--- a/ui/shared/tabs/failureSummary/FailureSummaryTab.jsx
+++ b/ui/shared/tabs/failureSummary/FailureSummaryTab.jsx
@@ -1,6 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
-import { Button } from 'reactstrap';
+import { Button } from 'react-bootstrap';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faSpinner } from '@fortawesome/free-solid-svg-icons';
@@ -216,7 +216,7 @@ class FailureSummaryTab extends React.Component {
{selectedJob.newFailure > 0 && (
{selectedJob.newFailure} new failure line(s). First one is
@@ -352,18 +352,22 @@ class FailureSummaryTab extends React.Component {
FailureSummaryTab.propTypes = {
selectedJob: PropTypes.shape({}).isRequired,
selectedJobId: PropTypes.number.isRequired,
- jobLogUrls: PropTypes.arrayOf({
- id: PropTypes.number.isRequired,
- job_id: PropTypes.number.isRequired,
- name: PropTypes.string.isRequired,
- url: PropTypes.string.isRequired,
- parse_status: PropTypes.string.isRequired,
- }),
- jobDetails: PropTypes.arrayOf({
- url: PropTypes.string.isRequired,
- value: PropTypes.string.isRequired,
- title: PropTypes.string.isRequired,
- }),
+ jobLogUrls: PropTypes.arrayOf(
+ PropTypes.shape({
+ id: PropTypes.number.isRequired,
+ job_id: PropTypes.number.isRequired,
+ name: PropTypes.string.isRequired,
+ url: PropTypes.string.isRequired,
+ parse_status: PropTypes.string.isRequired,
+ }),
+ ),
+ jobDetails: PropTypes.arrayOf(
+ PropTypes.shape({
+ url: PropTypes.string.isRequired,
+ value: PropTypes.string.isRequired,
+ title: PropTypes.string.isRequired,
+ }),
+ ),
logParseStatus: PropTypes.string,
logViewerFullUrl: PropTypes.string,
currentRepo: PropTypes.shape({}).isRequired,
diff --git a/ui/shared/tabs/failureSummary/SuggestionsListItem.jsx b/ui/shared/tabs/failureSummary/SuggestionsListItem.jsx
index e95184a4f86..b67fb1b2c73 100644
--- a/ui/shared/tabs/failureSummary/SuggestionsListItem.jsx
+++ b/ui/shared/tabs/failureSummary/SuggestionsListItem.jsx
@@ -1,6 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
-import { Button } from 'reactstrap';
+import { Button } from 'react-bootstrap';
import { Link } from 'react-router-dom';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import {
@@ -91,7 +91,7 @@ export default class SuggestionsListItem extends React.Component {
suggestions.push(
toggleInternalIssueFiler(suggestion)}
title="File an internal issue for this failure"
@@ -209,7 +209,7 @@ export default class SuggestionsListItem extends React.Component {
{suggestion.showNewButton && (
NEW
@@ -244,12 +244,12 @@ export default class SuggestionsListItem extends React.Component {
toggleBugFiler(suggestion)}
title="File a bug for this failure"
@@ -275,11 +275,13 @@ export default class SuggestionsListItem extends React.Component {
SuggestionsListItem.propTypes = {
selectedJob: PropTypes.shape({}).isRequired,
suggestion: PropTypes.shape({}).isRequired,
- jobDetails: PropTypes.arrayOf({
- url: PropTypes.string.isRequired,
- value: PropTypes.string.isRequired,
- title: PropTypes.string.isRequired,
- }).isRequired,
+ jobDetails: PropTypes.arrayOf(
+ PropTypes.shape({
+ url: PropTypes.string.isRequired,
+ value: PropTypes.string.isRequired,
+ title: PropTypes.string.isRequired,
+ }),
+ ).isRequired,
toggleBugFiler: PropTypes.func.isRequired,
toggleInternalIssueFiler: PropTypes.func.isRequired,
developerMode: PropTypes.bool.isRequired,
diff --git a/webpack.config.js b/webpack.config.js
index cb1163a10f9..df7a66f8e14 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -120,7 +120,7 @@ const developmentConfig = {
devServer: {
host: '0.0.0.0',
- port: 5000,
+ port: process.env.PORT || 5000,
hot: true,
historyApiFallback: true,
open: true,
diff --git a/yarn.lock b/yarn.lock
index 985e66dbbca..1ff06d1fa94 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1015,6 +1015,11 @@
dependencies:
regenerator-runtime "^0.14.0"
+"@babel/runtime@^7.24.7", "@babel/runtime@^7.26.0", "@babel/runtime@^7.6.3":
+ version "7.28.2"
+ resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.28.2.tgz#2ae5a9d51cc583bd1f5673b3bb70d6d819682473"
+ integrity sha512-KHp2IflsnGywDjBWDkR9iEqiWSpc8GIi0lgTT3mOElT0PP1tG26P4tmFI2YvAdzgq9RGyoHZQEIEdZy6Ec5xCA==
+
"@babel/runtime@^7.27.1", "@babel/runtime@^7.5.5":
version "7.27.6"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.27.6.tgz#ec4070a04d76bae8ddbb10770ba55714a417b7c6"
@@ -1279,14 +1284,6 @@
resolved "https://registry.yarnpkg.com/@humanwhocodes/retry/-/retry-0.4.3.tgz#c2b9d2e374ee62c586d3adbea87199b1d7a7a6ba"
integrity sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==
-"@hypnosphi/create-react-context@^0.3.1":
- version "0.3.1"
- resolved "https://registry.yarnpkg.com/@hypnosphi/create-react-context/-/create-react-context-0.3.1.tgz#f8bfebdc7665f5d426cba3753e0e9c7d3154d7c6"
- integrity sha512-V1klUed202XahrWJLLOT3EXNeCpFHCcJntdFGI15ntCwau+jfT386w7OFTMaCqOgXUH1fa0w/I1oZs+i/Rfr0A==
- dependencies:
- gud "^1.0.0"
- warning "^4.0.3"
-
"@isaacs/cliui@^8.0.2":
version "8.0.2"
resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550"
@@ -1823,6 +1820,13 @@
tar-fs "^3.0.8"
yargs "^17.7.2"
+"@react-aria/ssr@^3.5.0":
+ version "3.9.10"
+ resolved "https://registry.yarnpkg.com/@react-aria/ssr/-/ssr-3.9.10.tgz#7fdc09e811944ce0df1d7e713de1449abd7435e6"
+ integrity sha512-hvTm77Pf+pMBhuBm760Li0BVIO38jv1IBws1xFm1NoL26PU+fe+FMW5+VZWyANR6nYL65joaJKZqOdTQMkO9IQ==
+ dependencies:
+ "@swc/helpers" "^0.5.0"
+
"@redocly/ajv@^8.11.2":
version "8.11.2"
resolved "https://registry.yarnpkg.com/@redocly/ajv/-/ajv-8.11.2.tgz#46e1bf321ec0ac1e0fd31dea41a3d1fcbdcda0b5"
@@ -1853,6 +1857,35 @@
pluralize "^8.0.0"
yaml-ast-parser "0.0.43"
+"@restart/hooks@^0.4.9":
+ version "0.4.16"
+ resolved "https://registry.yarnpkg.com/@restart/hooks/-/hooks-0.4.16.tgz#95ae8ac1cc7e2bd4fed5e39800ff85604c6d59fb"
+ integrity sha512-f7aCv7c+nU/3mF7NWLtVVr0Ra80RqsO89hO72r+Y/nvQr5+q0UFGkocElTH6MJApvReVh6JHUFYn2cw1WdHF3w==
+ dependencies:
+ dequal "^2.0.3"
+
+"@restart/hooks@^0.5.0":
+ version "0.5.1"
+ resolved "https://registry.yarnpkg.com/@restart/hooks/-/hooks-0.5.1.tgz#6776b3859e33aea72b23b81fc47021edf17fd247"
+ integrity sha512-EMoH04NHS1pbn07iLTjIjgttuqb7qu4+/EyhAx27MHpoENcB2ZdSsLTNxmKD+WEPnZigo62Qc8zjGnNxoSE/5Q==
+ dependencies:
+ dequal "^2.0.3"
+
+"@restart/ui@^1.9.4":
+ version "1.9.4"
+ resolved "https://registry.yarnpkg.com/@restart/ui/-/ui-1.9.4.tgz#9d61f56f2647f5ab8a33d87b278b9ce183511a26"
+ integrity sha512-N4C7haUc3vn4LTwVUPlkJN8Ach/+yIMvRuTVIhjilNHqegY60SGLrzud6errOMNJwSnmYFnt1J0H/k8FE3A4KA==
+ dependencies:
+ "@babel/runtime" "^7.26.0"
+ "@popperjs/core" "^2.11.8"
+ "@react-aria/ssr" "^3.5.0"
+ "@restart/hooks" "^0.5.0"
+ "@types/warning" "^3.0.3"
+ dequal "^2.0.3"
+ dom-helpers "^5.2.0"
+ uncontrollable "^8.0.4"
+ warning "^4.0.3"
+
"@rtsao/scc@^1.1.0":
version "1.1.0"
resolved "https://registry.yarnpkg.com/@rtsao/scc/-/scc-1.1.0.tgz#927dd2fae9bc3361403ac2c7a00c32ddce9ad7e8"
@@ -1899,6 +1932,13 @@
dependencies:
"@sinonjs/commons" "^3.0.0"
+"@swc/helpers@^0.5.0":
+ version "0.5.17"
+ resolved "https://registry.yarnpkg.com/@swc/helpers/-/helpers-0.5.17.tgz#5a7be95ac0f0bf186e7e6e890e7a6f6cda6ce971"
+ integrity sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A==
+ dependencies:
+ tslib "^2.8.0"
+
"@testing-library/dom@10.4.1":
version "10.4.1"
resolved "https://registry.yarnpkg.com/@testing-library/dom/-/dom-10.4.1.tgz#d444f8a889e9a46e9a3b4f3b88e0fcb3efb6cf95"
@@ -2223,7 +2263,7 @@
dependencies:
undici-types "~6.20.0"
-"@types/prop-types@^15.7.14":
+"@types/prop-types@^15.7.12", "@types/prop-types@^15.7.14":
version "15.7.15"
resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.15.tgz#e6e5a86d602beaca71ce5163fadf5f95d70931c7"
integrity sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==
@@ -2243,7 +2283,7 @@
resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-19.0.4.tgz#bedba97f9346bd4c0fe5d39e689713804ec9ac89"
integrity sha512-4fSQ8vWFkg+TGhePfUzVmat3eC14TXYSsiiDSLI0dVLsrm9gZFABjPy/Qu6TKgl1tq1Bu1yDsuQgY3A3DOjCcg==
-"@types/react-transition-group@^4.4.12":
+"@types/react-transition-group@^4.4.12", "@types/react-transition-group@^4.4.6":
version "4.4.12"
resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.4.12.tgz#b5d76568485b02a307238270bfe96cb51ee2a044"
integrity sha512-8TV6R3h2j7a91c+1DXdJi3Syo69zzIZbz7Lg5tORM5LEJG7X/E6a1V3drRyBRZq7/utz7A+c4OgYLiLcYGHG6w==
@@ -2255,6 +2295,13 @@
dependencies:
csstype "^3.0.2"
+"@types/react@>=16.9.11":
+ version "19.1.9"
+ resolved "https://registry.yarnpkg.com/@types/react/-/react-19.1.9.tgz#f42b24f35474566a39b5c3a98e4d0c425b79a849"
+ integrity sha512-WmdoynAX8Stew/36uTSVMcLJJ1KRh6L3IZRx1PZ7qJtBqT3dYTgyDTx8H1qoRghErydW7xw9mSJ3wS//tCRpFA==
+ dependencies:
+ csstype "^3.0.2"
+
"@types/retry@0.12.2":
version "0.12.2"
resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.12.2.tgz#ed279a64fa438bb69f2480eda44937912bb7480a"
@@ -2323,6 +2370,11 @@
resolved "https://registry.yarnpkg.com/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz#b6725d5f4af24ace33b36fafd295136e75509f43"
integrity sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA==
+"@types/warning@^3.0.3":
+ version "3.0.3"
+ resolved "https://registry.yarnpkg.com/@types/warning/-/warning-3.0.3.tgz#d1884c8cc4a426d1ac117ca2611bf333834c6798"
+ integrity sha512-D1XC7WK8K+zZEveUPY+cf4+kgauk8N4eHr/XIHXGlGYkHLud6hK9lYfZk1ry1TNh798cZUCgb6MqGEG8DkJt6Q==
+
"@types/whatwg-streams@^0.0.7":
version "0.0.7"
resolved "https://registry.yarnpkg.com/@types/whatwg-streams/-/whatwg-streams-0.0.7.tgz#28bfe73dc850562296367249c4b32a50db81e9d3"
@@ -3459,7 +3511,7 @@ cjs-module-lexer@^1.0.0:
resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.4.3.tgz#0f79731eb8cfe1ec72acd4066efac9d61991b00d"
integrity sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==
-classnames@^2.2.3, classnames@^2.2.5, classnames@^2.3.2:
+classnames@^2.2.5, classnames@^2.3.2:
version "2.5.1"
resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.5.1.tgz#ba774c614be0f016da105c858e7159eae8e7687b"
integrity sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==
@@ -4049,18 +4101,6 @@ dedent@^1.0.0:
resolved "https://registry.yarnpkg.com/dedent/-/dedent-1.5.3.tgz#99aee19eb9bae55a67327717b6e848d0bf777e5a"
integrity sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ==
-deep-equal@^1.1.1:
- version "1.1.2"
- resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.1.2.tgz#78a561b7830eef3134c7f6f3a3d6af272a678761"
- integrity sha512-5tdhKF6DbU7iIzrIOa1AOUt39ZRm13cmL1cGEh//aqR8x9+tNfbywRf0n5FD/18OKMdo7DNEtrX2t22ZAkI+eg==
- dependencies:
- is-arguments "^1.1.1"
- is-date-object "^1.0.5"
- is-regex "^1.1.4"
- object-is "^1.1.5"
- object-keys "^1.1.1"
- regexp.prototype.flags "^1.5.1"
-
deep-extend@^0.6.0:
version "0.6.0"
resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac"
@@ -4264,14 +4304,7 @@ dom-converter@^0.2.0:
dependencies:
utila "~0.4"
-dom-helpers@^3.4.0:
- version "3.4.0"
- resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-3.4.0.tgz#e9b369700f959f62ecde5a6babde4bccd9169af8"
- integrity sha512-LnuPJ+dwqKDIyotW1VzmOZ5TONUN7CwkCR5hrgawTUbkBGYdeoNLZo6nNfGkCrjtE1nXXaj7iMMpDa8/d9WoIA==
- dependencies:
- "@babel/runtime" "^7.1.2"
-
-dom-helpers@^5.0.1, dom-helpers@^5.1.3:
+dom-helpers@^5.0.1, dom-helpers@^5.1.3, dom-helpers@^5.2.0, dom-helpers@^5.2.1:
version "5.2.1"
resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-5.2.1.tgz#d9400536b2bf8225ad98fe052e029451ac40e902"
integrity sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==
@@ -5521,11 +5554,6 @@ graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.11,
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3"
integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==
-gud@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/gud/-/gud-1.0.0.tgz#a489581b17e6a70beca9abe3ae57de7a499852c0"
- integrity sha512-zGEOVKFM5sVPPrYs7J5/hYEw2Pof8KCyOwyhG8sAF26mCAeUFAcYPu1mwB7hhpIP29zOIBaDqwuHdLp0jvZXjw==
-
handle-thing@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-2.0.1.tgz#857f79ce359580c340d43081cc648970d0bb234e"
@@ -5991,6 +6019,13 @@ interpret@^3.1.1:
resolved "https://registry.yarnpkg.com/interpret/-/interpret-3.1.1.tgz#5be0ceed67ca79c6c4bc5cf0d7ee843dcea110c4"
integrity sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==
+invariant@^2.2.4:
+ version "2.2.4"
+ resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6"
+ integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==
+ dependencies:
+ loose-envify "^1.0.0"
+
ip-address@^9.0.5:
version "9.0.5"
resolved "https://registry.yarnpkg.com/ip-address/-/ip-address-9.0.5.tgz#117a960819b08780c3bd1f14ef3c1cc1d3f3ea5a"
@@ -6014,7 +6049,7 @@ is-absolute-url@^3.0.3:
resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-3.0.3.tgz#96c6a22b6a23929b11ea0afb1836c36ad4a5d698"
integrity sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q==
-is-arguments@^1.0.4, is-arguments@^1.1.1:
+is-arguments@^1.0.4:
version "1.2.0"
resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.2.0.tgz#ad58c6aecf563b78ef2bf04df540da8f5d7d8e1b"
integrity sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==
@@ -6216,7 +6251,7 @@ is-potential-custom-element-name@^1.0.1:
resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz#171ed6f19e3ac554394edf78caa05784a45bebb5"
integrity sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==
-is-regex@^1.1.0, is-regex@^1.1.4, is-regex@^1.2.1:
+is-regex@^1.1.0, is-regex@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.2.1.tgz#76d70a3ed10ef9be48eb577887d74205bf0cad22"
integrity sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==
@@ -8238,11 +8273,6 @@ polished@^4.2.2:
dependencies:
"@babel/runtime" "^7.17.8"
-popper.js@^1.14.4:
- version "1.16.1"
- resolved "https://registry.yarnpkg.com/popper.js/-/popper.js-1.16.1.tgz#2a223cb3dc7b6213d740e40372be40de43e65b1b"
- integrity sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ==
-
possible-typed-array-names@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz#93e3582bc0e5426586d9d07b79ee40fc841de4ae"
@@ -8390,6 +8420,14 @@ prop-types-exact@^1.2.0:
object.assign "^4.1.7"
own-keys "^1.0.0"
+prop-types-extra@^1.1.0:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/prop-types-extra/-/prop-types-extra-1.1.1.tgz#58c3b74cbfbb95d304625975aa2f0848329a010b"
+ integrity sha512-59+AHNnHYCdiC+vMwY52WmvP5dM3QLeoumYuEyceQDi9aEhtwN9zIQ2ZNo25sMyXnbh32h+P1ezDsUpUH3JAew==
+ dependencies:
+ react-is "^16.3.2"
+ warning "^4.0.0"
+
prop-types@15.8.1, prop-types@^15.5.0, prop-types@^15.5.4, prop-types@^15.5.8, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2, prop-types@^15.8.1:
version "15.8.1"
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5"
@@ -8588,6 +8626,25 @@ raw-body@2.5.2:
iconv-lite "0.4.24"
unpipe "1.0.0"
+react-bootstrap@2.10.10:
+ version "2.10.10"
+ resolved "https://registry.yarnpkg.com/react-bootstrap/-/react-bootstrap-2.10.10.tgz#be0b0d951a69987152d75c0e6986c80425efdf21"
+ integrity sha512-gMckKUqn8aK/vCnfwoBpBVFUGT9SVQxwsYrp9yDHt0arXMamxALerliKBxr1TPbntirK/HGrUAHYbAeQTa9GHQ==
+ dependencies:
+ "@babel/runtime" "^7.24.7"
+ "@restart/hooks" "^0.4.9"
+ "@restart/ui" "^1.9.4"
+ "@types/prop-types" "^15.7.12"
+ "@types/react-transition-group" "^4.4.6"
+ classnames "^2.3.2"
+ dom-helpers "^5.2.1"
+ invariant "^2.2.4"
+ prop-types "^15.8.1"
+ prop-types-extra "^1.1.0"
+ react-transition-group "^4.4.5"
+ uncontrollable "^7.2.1"
+ warning "^4.0.3"
+
react-dates@21.8.0:
version "21.8.0"
resolved "https://registry.yarnpkg.com/react-dates/-/react-dates-21.8.0.tgz#355c3c7a243a7c29568fe00aca96231e171a5e94"
@@ -8663,7 +8720,7 @@ react-hot-loader@4.13.1:
shallowequal "^1.1.0"
source-map "^0.7.3"
-react-is@^16.13.1, react-is@^16.6.0, react-is@^16.7.0:
+react-is@^16.13.1, react-is@^16.3.2, react-is@^16.6.0, react-is@^16.7.0:
version "16.13.1"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
@@ -8730,19 +8787,6 @@ react-outside-click-handler@^1.2.4:
object.values "^1.1.0"
prop-types "^15.7.2"
-react-popper@^1.3.6:
- version "1.3.11"
- resolved "https://registry.yarnpkg.com/react-popper/-/react-popper-1.3.11.tgz#a2cc3f0a67b75b66cfa62d2c409f9dd1fcc71ffd"
- integrity sha512-VSA/bS+pSndSF2fiasHK/PTEEAyOpX60+H5EPAjoArr8JGm+oihu4UbrqcEBpQibJxBVCpYyjAX7abJ+7DoYVg==
- dependencies:
- "@babel/runtime" "^7.1.2"
- "@hypnosphi/create-react-context" "^0.3.1"
- deep-equal "^1.1.1"
- popper.js "^1.14.4"
- prop-types "^15.6.1"
- typed-styles "^0.0.7"
- warning "^4.0.2"
-
react-portal@^4.2.0:
version "4.3.0"
resolved "https://registry.yarnpkg.com/react-portal/-/react-portal-4.3.0.tgz#92ca3492b1309883134f317a6aa88004534c860f"
@@ -8834,16 +8878,6 @@ react-tabs@6.1.0, react-tabs@^6.0.2:
clsx "^2.0.0"
prop-types "^15.5.0"
-react-transition-group@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-3.0.0.tgz#36efa4db970d5eec5e3028e0c458931163fa3b9b"
- integrity sha512-A9ojB/LWECbFj58SNfjK1X9aaAU+1olLS0DFSikvrr2KfMaiBELemHDa5dKNvcTk2t3gUtDL/PJpFrBKDfMpLg==
- dependencies:
- dom-helpers "^3.4.0"
- loose-envify "^1.4.0"
- prop-types "^15.6.2"
- react-lifecycles-compat "^3.0.4"
-
react-transition-group@^4.4.5:
version "4.4.5"
resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-4.4.5.tgz#e53d4e3f3344da8521489fbef8f2581d42becdd1"
@@ -8906,17 +8940,6 @@ react@18.3.1:
dependencies:
loose-envify "^1.1.0"
-reactstrap@8.10.1:
- version "8.10.1"
- resolved "https://registry.yarnpkg.com/reactstrap/-/reactstrap-8.10.1.tgz#43ea596c7f82f88997a9c8aae203417910262d3f"
- integrity sha512-StjLADa/12yMNjafrSs+UD7sZAGtKpLO9fZp++2Dj0IzJinqY7eQhXlM3nFf0q40YsIcLvQdFc9pKF8PF4f0Qg==
- dependencies:
- "@babel/runtime" "^7.12.5"
- classnames "^2.2.3"
- prop-types "^15.5.8"
- react-popper "^1.3.6"
- react-transition-group "^3.0.0"
-
readable-stream@^2.0.1, readable-stream@^2.3.8:
version "2.3.8"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b"
@@ -9064,7 +9087,7 @@ regenerator-transform@^0.15.2:
dependencies:
"@babel/runtime" "^7.8.4"
-regexp.prototype.flags@^1.5.1, regexp.prototype.flags@^1.5.3:
+regexp.prototype.flags@^1.5.3:
version "1.5.4"
resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz#1ad6c62d44a259007e55b3970e00f746efbcaa19"
integrity sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==
@@ -10265,7 +10288,7 @@ tslib@2.6.2:
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae"
integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==
-tslib@^2.0.0, tslib@^2.0.1, tslib@^2.0.3, tslib@^2.1.0:
+tslib@^2.0.0, tslib@^2.0.1, tslib@^2.0.3, tslib@^2.1.0, tslib@^2.8.0:
version "2.8.1"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f"
integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==
@@ -10345,11 +10368,6 @@ typed-query-selector@^2.12.0:
resolved "https://registry.yarnpkg.com/typed-query-selector/-/typed-query-selector-2.12.0.tgz#92b65dbc0a42655fccf4aeb1a08b1dddce8af5f2"
integrity sha512-SbklCd1F0EiZOyPiW192rrHZzZ5sBijB6xM+cpmrwDqObvdtunOHHIk9fCGsoK5JVIYXoyEp4iEdE3upFH3PAg==
-typed-styles@^0.0.7:
- version "0.0.7"
- resolved "https://registry.yarnpkg.com/typed-styles/-/typed-styles-0.0.7.tgz#93392a008794c4595119ff62dde6809dbc40a3d9"
- integrity sha512-pzP0PWoZUhsECYjABgCGQlRGL1n7tOHsgwYv3oIiEpJwGhFTuty/YNeduxQYzXXa3Ge5BdT6sHYIQYpl4uJ+5Q==
-
uc.micro@^1.0.1:
version "1.0.6"
resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-1.0.6.tgz#9c411a802a409a91fc6cf74081baba34b24499ac"
@@ -10370,6 +10388,21 @@ unbox-primitive@^1.1.0:
has-symbols "^1.1.0"
which-boxed-primitive "^1.1.1"
+uncontrollable@^7.2.1:
+ version "7.2.1"
+ resolved "https://registry.yarnpkg.com/uncontrollable/-/uncontrollable-7.2.1.tgz#1fa70ba0c57a14d5f78905d533cf63916dc75738"
+ integrity sha512-svtcfoTADIB0nT9nltgjujTi7BzVmwjZClOmskKu/E8FW9BXzg9os8OLr4f8Dlnk0rYWJIWr4wv9eKUXiQvQwQ==
+ dependencies:
+ "@babel/runtime" "^7.6.3"
+ "@types/react" ">=16.9.11"
+ invariant "^2.2.4"
+ react-lifecycles-compat "^3.0.4"
+
+uncontrollable@^8.0.4:
+ version "8.0.4"
+ resolved "https://registry.yarnpkg.com/uncontrollable/-/uncontrollable-8.0.4.tgz#a0a8307f638795162fafd0550f4a1efa0f8c5eb6"
+ integrity sha512-ulRWYWHvscPFc0QQXvyJjY6LIXU56f0h8pQFvhxiKk5V1fcI8gp9Ht9leVAhrVjzqMw0BgjspBINx9r6oyJUvQ==
+
undici-types@~6.20.0:
version "6.20.0"
resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.20.0.tgz#8171bf22c1f588d1554d55bf204bc624af388433"
@@ -10875,7 +10908,7 @@ walker@^1.0.8:
dependencies:
makeerror "1.0.12"
-warning@^4.0.2, warning@^4.0.3:
+warning@^4.0.0, warning@^4.0.3:
version "4.0.3"
resolved "https://registry.yarnpkg.com/warning/-/warning-4.0.3.tgz#16e9e077eb8a86d6af7d64aa1e05fd85b4678ca3"
integrity sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==