mirror of
https://github.com/fleetdm/fleet
synced 2026-05-23 17:08:53 +00:00
Frontend Tech Debt: Remove unused schedule query side panel (#7668)
This commit is contained in:
parent
9f79b13eb0
commit
fa52b7b107
10 changed files with 0 additions and 479 deletions
|
|
@ -1,162 +0,0 @@
|
|||
import React, { Component } from "react";
|
||||
import PropTypes from "prop-types";
|
||||
import { pull } from "lodash";
|
||||
|
||||
import Button from "components/buttons/Button";
|
||||
import Dropdown from "components/forms/fields/Dropdown";
|
||||
import Form from "components/forms/Form";
|
||||
import formFieldInterface from "interfaces/form_field";
|
||||
import InputField from "components/forms/fields/InputField";
|
||||
import validate from "components/forms/ConfigurePackQueryForm/validate";
|
||||
import {
|
||||
PLATFORM_DROPDOWN_OPTIONS,
|
||||
LOGGING_TYPE_OPTIONS,
|
||||
MIN_OSQUERY_VERSION_OPTIONS,
|
||||
} from "utilities/constants";
|
||||
|
||||
const baseClass = "configure-pack-query-form";
|
||||
const fieldNames = [
|
||||
"query_id",
|
||||
"interval",
|
||||
"logging_type",
|
||||
"platform",
|
||||
"shard",
|
||||
"version",
|
||||
];
|
||||
|
||||
export class ConfigurePackQueryForm extends Component {
|
||||
static propTypes = {
|
||||
fields: PropTypes.shape({
|
||||
interval: formFieldInterface.isRequired,
|
||||
logging_type: formFieldInterface.isRequired,
|
||||
platform: formFieldInterface.isRequired,
|
||||
version: formFieldInterface.isRequired,
|
||||
shard: formFieldInterface.isRequired,
|
||||
}).isRequired,
|
||||
formData: PropTypes.shape({
|
||||
id: PropTypes.number,
|
||||
}),
|
||||
handleSubmit: PropTypes.func,
|
||||
onCancel: PropTypes.func,
|
||||
};
|
||||
|
||||
componentWillMount() {
|
||||
const { fields } = this.props;
|
||||
|
||||
if (fields && fields.shard && !fields.shard.value) {
|
||||
fields.shard.value = "";
|
||||
}
|
||||
}
|
||||
|
||||
onCancel = (evt) => {
|
||||
evt.preventDefault();
|
||||
|
||||
const { formData, onCancel: handleCancel } = this.props;
|
||||
|
||||
return handleCancel(formData);
|
||||
};
|
||||
|
||||
handlePlatformChoice = (value) => {
|
||||
const {
|
||||
fields: { platform },
|
||||
} = this.props;
|
||||
const valArray = value.split(",");
|
||||
|
||||
// Remove All if another OS is chosen
|
||||
if (valArray.indexOf("") === 0 && valArray.length > 1) {
|
||||
return platform.onChange(pull(valArray, "").join(","));
|
||||
}
|
||||
|
||||
// Remove OS if All is chosen
|
||||
if (valArray.length > 1 && valArray.indexOf("") > -1) {
|
||||
return platform.onChange("");
|
||||
}
|
||||
|
||||
return platform.onChange(value);
|
||||
};
|
||||
|
||||
renderCancelButton = () => {
|
||||
const { formData } = this.props;
|
||||
const { onCancel } = this;
|
||||
|
||||
if (!formData.id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (
|
||||
<Button
|
||||
className={`${baseClass}__cancel-btn`}
|
||||
onClick={onCancel}
|
||||
variant="inverse"
|
||||
>
|
||||
Cancel
|
||||
</Button>
|
||||
);
|
||||
};
|
||||
|
||||
render() {
|
||||
const { fields, handleSubmit } = this.props;
|
||||
const { handlePlatformChoice, renderCancelButton } = this;
|
||||
|
||||
// Uncontrolled form field defaults to snapshot if !fields.logging_type
|
||||
const loggingType = fields.logging_type.value || "snapshot";
|
||||
|
||||
return (
|
||||
<form className={baseClass} onSubmit={handleSubmit} autoComplete="off">
|
||||
<h2 className={`${baseClass}__title`}>Configuration</h2>
|
||||
<div className={`${baseClass}__fields`}>
|
||||
<Dropdown
|
||||
{...fields.logging_type}
|
||||
options={LOGGING_TYPE_OPTIONS}
|
||||
placeholder="- - -"
|
||||
label="Logging"
|
||||
value={loggingType}
|
||||
wrapperClassName={`${baseClass}__form-field ${baseClass}__form-field--logging`}
|
||||
/>
|
||||
<InputField
|
||||
{...fields.interval}
|
||||
inputWrapperClass={`${baseClass}__form-field ${baseClass}__form-field--frequency`}
|
||||
placeholder="- - -"
|
||||
label="Frequency (seconds)"
|
||||
// hint="Seconds"
|
||||
type="number"
|
||||
/>
|
||||
<Dropdown
|
||||
{...fields.platform}
|
||||
options={PLATFORM_DROPDOWN_OPTIONS}
|
||||
placeholder="- - -"
|
||||
label="Platform"
|
||||
onChange={handlePlatformChoice}
|
||||
multi
|
||||
wrapperClassName={`${baseClass}__form-field ${baseClass}__form-field--platform`}
|
||||
/>
|
||||
<Dropdown
|
||||
{...fields.version}
|
||||
options={MIN_OSQUERY_VERSION_OPTIONS}
|
||||
placeholder="- - -"
|
||||
label="Minimum osquery version"
|
||||
wrapperClassName={`${baseClass}__form-field ${baseClass}__form-field--osquer-vers`}
|
||||
/>
|
||||
<InputField
|
||||
{...fields.shard}
|
||||
inputWrapperClass={`${baseClass}__form-field ${baseClass}__form-field--shard`}
|
||||
placeholder="- - -"
|
||||
label="Shard"
|
||||
type="number"
|
||||
/>
|
||||
<div className="modal-cta-wrap">
|
||||
{renderCancelButton()}
|
||||
<Button type="submit" variant="brand">
|
||||
Save
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default Form(ConfigurePackQueryForm, {
|
||||
fields: fieldNames,
|
||||
validate,
|
||||
});
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
.configure-pack-query-form {
|
||||
&__form-field {
|
||||
&--frequency {
|
||||
position: relative;
|
||||
|
||||
.input-field {
|
||||
width: 100%;
|
||||
padding-right: 70px;
|
||||
}
|
||||
|
||||
.form-field__hint {
|
||||
position: absolute;
|
||||
bottom: 10px;
|
||||
right: 10px;
|
||||
text-transform: lowercase;
|
||||
font-size: $x-small;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&__title {
|
||||
font-size: $x-small;
|
||||
font-weight: $bold;
|
||||
letter-spacing: -0.5px;
|
||||
color: $core-fleet-black;
|
||||
padding: 0 0 9px;
|
||||
margin: 0 0 9px;
|
||||
}
|
||||
|
||||
&__fields {
|
||||
.fleeticon {
|
||||
margin-right: 6px;
|
||||
margin-left: 6px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
export { default } from "./ConfigurePackQueryForm";
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
import { size } from "lodash";
|
||||
|
||||
import validateNumericality from "components/forms/validators/validate_numericality";
|
||||
|
||||
const validate = (formData) => {
|
||||
const errors = {};
|
||||
|
||||
if (!formData.query_id) {
|
||||
errors.query_id = "A query must be selected";
|
||||
}
|
||||
|
||||
if (!formData.interval) {
|
||||
errors.interval = "Frequency (seconds) must be present";
|
||||
}
|
||||
|
||||
if (formData.interval && !validateNumericality(formData.interval)) {
|
||||
errors.interval = "Frequency must be a number";
|
||||
}
|
||||
|
||||
// logging_type does not need to be validated because it is defaulted "snapshot" if unspecified.
|
||||
|
||||
if (formData.shard) {
|
||||
if (formData.shard < 0 || formData.shard > 100) {
|
||||
errors.shard = "Shard must be between 0 and 100";
|
||||
}
|
||||
}
|
||||
|
||||
const valid = !size(errors);
|
||||
|
||||
return { valid, errors };
|
||||
};
|
||||
|
||||
export default validate;
|
||||
|
|
@ -1,65 +0,0 @@
|
|||
import React from "react";
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
import ConfigurePackQueryForm from "components/forms/ConfigurePackQueryForm";
|
||||
import queryInterface from "interfaces/query";
|
||||
import scheduledQueryInterface from "interfaces/scheduled_query";
|
||||
import SearchPackQuery from "./SearchPackQuery";
|
||||
import SecondarySidePanelContainer from "../SecondarySidePanelContainer";
|
||||
|
||||
const baseClass = "schedule-query-side-panel";
|
||||
|
||||
const ScheduleQuerySidePanel = ({
|
||||
allQueries,
|
||||
onConfigurePackQuerySubmit,
|
||||
onFormCancel,
|
||||
onUpdateScheduledQuery,
|
||||
onSelectQuery,
|
||||
selectedQuery,
|
||||
selectedScheduledQuery,
|
||||
}) => {
|
||||
const renderForm = () => {
|
||||
if (!selectedQuery) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const formData = selectedScheduledQuery || { logging_type: "snapshot" };
|
||||
|
||||
formData.query_id = selectedQuery.id;
|
||||
|
||||
const handleSubmit = selectedScheduledQuery
|
||||
? onUpdateScheduledQuery
|
||||
: onConfigurePackQuerySubmit;
|
||||
|
||||
return (
|
||||
<ConfigurePackQueryForm
|
||||
formData={formData}
|
||||
handleSubmit={handleSubmit}
|
||||
onCancel={onFormCancel}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<SecondarySidePanelContainer className={baseClass}>
|
||||
<SearchPackQuery
|
||||
allQueries={allQueries}
|
||||
onSelectQuery={onSelectQuery}
|
||||
selectedQuery={selectedQuery}
|
||||
/>
|
||||
{renderForm()}
|
||||
</SecondarySidePanelContainer>
|
||||
);
|
||||
};
|
||||
|
||||
ScheduleQuerySidePanel.propTypes = {
|
||||
allQueries: PropTypes.arrayOf(queryInterface),
|
||||
onConfigurePackQuerySubmit: PropTypes.func,
|
||||
onFormCancel: PropTypes.func,
|
||||
onSelectQuery: PropTypes.func,
|
||||
onUpdateScheduledQuery: PropTypes.func,
|
||||
selectedQuery: queryInterface,
|
||||
selectedScheduledQuery: scheduledQueryInterface,
|
||||
};
|
||||
|
||||
export default ScheduleQuerySidePanel;
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
import React from "react";
|
||||
import { render } from "@testing-library/react";
|
||||
|
||||
import ScheduleQuerySidePanel from "./ScheduleQuerySidePanel";
|
||||
|
||||
describe("ScheduleQuerySidePanel - component", () => {
|
||||
it("renders SearchPackQuery", () => {
|
||||
const { container } = render(<ScheduleQuerySidePanel />);
|
||||
|
||||
expect(container.querySelectorAll(".search-pack-query").length).toEqual(1);
|
||||
});
|
||||
});
|
||||
|
|
@ -1,129 +0,0 @@
|
|||
import React, { Component } from "react";
|
||||
import PropTypes from "prop-types";
|
||||
import AceEditor from "react-ace";
|
||||
import { isEqual, sortBy } from "lodash";
|
||||
|
||||
import FleetIcon from "components/icons/FleetIcon";
|
||||
import queryInterface from "interfaces/query";
|
||||
import Dropdown from "components/forms/fields/Dropdown";
|
||||
|
||||
const baseClass = "search-pack-query";
|
||||
|
||||
class SearchPackQuery extends Component {
|
||||
static propTypes = {
|
||||
allQueries: PropTypes.arrayOf(queryInterface),
|
||||
onSelectQuery: PropTypes.func,
|
||||
selectedQuery: queryInterface,
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
allQueries: [],
|
||||
};
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
queryDropdownOptions: [],
|
||||
};
|
||||
}
|
||||
|
||||
componentWillMount() {
|
||||
const { allQueries } = this.props;
|
||||
|
||||
const queryDropdownOptions = allQueries.map((query) => {
|
||||
return { label: query.name, value: String(query.id) };
|
||||
});
|
||||
|
||||
this.setState({
|
||||
queryDropdownOptions: sortBy(queryDropdownOptions, ["label"]),
|
||||
});
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
const { allQueries } = nextProps;
|
||||
|
||||
if (!isEqual(allQueries, this.props.allQueries)) {
|
||||
const queryDropdownOptions = allQueries.map((query) => {
|
||||
return { label: query.name, value: String(query.id) };
|
||||
});
|
||||
|
||||
this.setState({
|
||||
queryDropdownOptions: sortBy(queryDropdownOptions, ["label"]),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
renderHeader = () => {
|
||||
const { selectedQuery } = this.props;
|
||||
if (selectedQuery) {
|
||||
return (
|
||||
<h1 className={`${baseClass}__title`}>
|
||||
<FleetIcon name="query" /> {selectedQuery.name}
|
||||
</h1>
|
||||
);
|
||||
}
|
||||
|
||||
return <h1 className={`${baseClass}__title`}>Choose Query</h1>;
|
||||
};
|
||||
|
||||
renderQuery = () => {
|
||||
const { selectedQuery } = this.props;
|
||||
if (selectedQuery) {
|
||||
return (
|
||||
<AceEditor
|
||||
editorProps={{ $blockScrolling: Infinity }}
|
||||
mode="fleet"
|
||||
minLines={1}
|
||||
maxLines={3}
|
||||
name="pack-query"
|
||||
readOnly
|
||||
setOptions={{ wrap: true }}
|
||||
showGutter={false}
|
||||
showPrintMargin={false}
|
||||
theme="fleet"
|
||||
value={selectedQuery.query}
|
||||
width="100%"
|
||||
fontSize={14}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
renderDescription = () => {
|
||||
const { selectedQuery } = this.props;
|
||||
if (selectedQuery) {
|
||||
return (
|
||||
<div className={`${baseClass}__description`}>
|
||||
<h2>Description</h2>
|
||||
<p>{selectedQuery.description || <>No description available.</>}</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
render() {
|
||||
const { renderHeader, renderQuery, renderDescription } = this;
|
||||
const { onSelectQuery } = this.props;
|
||||
const { queryDropdownOptions } = this.state;
|
||||
|
||||
return (
|
||||
<div className={baseClass}>
|
||||
{renderHeader()}
|
||||
<Dropdown
|
||||
options={queryDropdownOptions}
|
||||
onChange={onSelectQuery}
|
||||
placeholder={"Select query"}
|
||||
/>
|
||||
{renderQuery()}
|
||||
{renderDescription()}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default SearchPackQuery;
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
.search-pack-query {
|
||||
&__title {
|
||||
@include ellipsis(250px);
|
||||
font-size: $x-small;
|
||||
font-weight: $bold;
|
||||
letter-spacing: -0.5px;
|
||||
color: $core-fleet-black;
|
||||
margin: 0 0 10px;
|
||||
}
|
||||
|
||||
.form-field--dropdown {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.ace-fleet {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
&__description {
|
||||
margin: 0 0 $pad-xlarge;
|
||||
word-wrap: break-word;
|
||||
|
||||
h2 {
|
||||
font-size: $x-small;
|
||||
font-weight: $bold;
|
||||
letter-spacing: -0.5px;
|
||||
color: $core-fleet-black;
|
||||
margin: 0 0 $pad-small;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0 0 10px;
|
||||
font-size: $x-small;
|
||||
font-weight: $regular;
|
||||
line-height: 1.71;
|
||||
color: $core-fleet-black;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
export { default } from "./SearchPackQuery";
|
||||
|
|
@ -1 +0,0 @@
|
|||
export { default } from "./ScheduleQuerySidePanel";
|
||||
Loading…
Reference in a new issue