mirror of
https://github.com/fleetdm/fleet
synced 2026-05-23 08:58:41 +00:00
Fix display of platform labels (#1866)
* Add policies UI components * Add policy filter to hosts page
This commit is contained in:
parent
abd4584742
commit
84615afbb3
16 changed files with 272 additions and 297 deletions
1
changes/1792-all-linux-label
Normal file
1
changes/1792-all-linux-label
Normal file
|
|
@ -0,0 +1 @@
|
|||
Fix display of platform labels on manage hosts page
|
||||
|
|
@ -1,112 +0,0 @@
|
|||
import React, { Component } from "react";
|
||||
import PropTypes from "prop-types";
|
||||
import { filter } from "lodash";
|
||||
|
||||
import Button from "components/buttons/Button";
|
||||
import InputField from "components/forms/fields/InputField";
|
||||
import labelInterface from "interfaces/label";
|
||||
import PanelGroup from "components/side_panels/HostSidePanel/PanelGroup";
|
||||
import SecondarySidePanelContainer from "components/side_panels/SecondarySidePanelContainer";
|
||||
import statusLabelsInterface from "interfaces/status_labels";
|
||||
import PlusIcon from "../../../../assets/images/icon-plus-16x16@2x.png";
|
||||
|
||||
const baseClass = "host-side-panel";
|
||||
|
||||
class HostSidePanel extends Component {
|
||||
static propTypes = {
|
||||
labels: PropTypes.arrayOf(labelInterface),
|
||||
onAddLabelClick: PropTypes.func,
|
||||
onLabelClick: PropTypes.func,
|
||||
selectedFilter: PropTypes.string,
|
||||
statusLabels: statusLabelsInterface,
|
||||
canAddNewLabel: PropTypes.bool,
|
||||
};
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = { labelFilter: "" };
|
||||
}
|
||||
|
||||
onFilterLabels = (labelFilter) => {
|
||||
const lowerLabelFilter = labelFilter.toLowerCase();
|
||||
this.setState({ labelFilter: lowerLabelFilter });
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
render() {
|
||||
const {
|
||||
labels,
|
||||
onAddLabelClick,
|
||||
onLabelClick,
|
||||
selectedFilter,
|
||||
canAddNewLabel,
|
||||
} = this.props;
|
||||
const { labelFilter } = this.state;
|
||||
const { onFilterLabels } = this;
|
||||
const allHostLabels = filter(labels, { type: "all" });
|
||||
const hostPlatformLabels = filter(labels, (label) => {
|
||||
return label.type === "platform" && label.count > 0;
|
||||
});
|
||||
const customLabels = filter(labels, (label) => {
|
||||
const lowerDisplayText = label.display_text.toLowerCase();
|
||||
|
||||
return label.type === "custom" && lowerDisplayText.match(labelFilter);
|
||||
});
|
||||
|
||||
return (
|
||||
<SecondarySidePanelContainer className={`${baseClass}`}>
|
||||
<PanelGroup
|
||||
groupItems={allHostLabels}
|
||||
onLabelClick={onLabelClick}
|
||||
selectedFilter={selectedFilter}
|
||||
type="all-hosts"
|
||||
/>
|
||||
|
||||
<h3>Operating systems</h3>
|
||||
<PanelGroup
|
||||
groupItems={hostPlatformLabels}
|
||||
onLabelClick={onLabelClick}
|
||||
selectedFilter={selectedFilter}
|
||||
type="platform"
|
||||
/>
|
||||
<div className="title">
|
||||
<div>
|
||||
<h3>Labels</h3>
|
||||
</div>
|
||||
<div>
|
||||
{canAddNewLabel && (
|
||||
<Button
|
||||
variant="text-icon"
|
||||
onClick={onAddLabelClick}
|
||||
className={`${baseClass}__add-label-btn`}
|
||||
>
|
||||
Add label <img src={PlusIcon} alt="Add label icon" />
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className={`${baseClass}__panel-group-item ${baseClass}__panel-group-item--filter`}
|
||||
>
|
||||
<InputField
|
||||
name="tags-filter"
|
||||
onChange={onFilterLabels}
|
||||
placeholder="Filter labels by name..."
|
||||
value={labelFilter}
|
||||
inputWrapperClass={`${baseClass}__filter-labels`}
|
||||
/>
|
||||
</div>
|
||||
<PanelGroup
|
||||
groupItems={customLabels}
|
||||
onLabelClick={onLabelClick}
|
||||
selectedFilter={selectedFilter}
|
||||
type="label"
|
||||
/>
|
||||
</SecondarySidePanelContainer>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default HostSidePanel;
|
||||
125
frontend/components/side_panels/HostSidePanel/HostSidePanel.tsx
Normal file
125
frontend/components/side_panels/HostSidePanel/HostSidePanel.tsx
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
import React, { useState, useCallback } from "react";
|
||||
import { filter } from "lodash";
|
||||
|
||||
import Button from "components/buttons/Button";
|
||||
// @ts-ignore
|
||||
import InputField from "components/forms/fields/InputField";
|
||||
// @ts-ignore
|
||||
import PanelGroup from "components/side_panels/HostSidePanel/PanelGroup";
|
||||
// @ts-ignore
|
||||
import SecondarySidePanelContainer from "components/side_panels/SecondarySidePanelContainer";
|
||||
import { ILabel } from "interfaces/label";
|
||||
import { PLATFORM_LABEL_DISPLAY_ORDER } from "utilities/constants";
|
||||
|
||||
import PlusIcon from "../../../../assets/images/icon-plus-16x16@2x.png";
|
||||
|
||||
const baseClass = "host-side-panel";
|
||||
|
||||
interface IHostSidePanelProps {
|
||||
labels: ILabel[];
|
||||
onAddLabelClick: (evt: React.MouseEvent<HTMLButtonElement>) => void;
|
||||
onLabelClick: (selectedLabel: ILabel) => boolean;
|
||||
selectedFilter: string;
|
||||
canAddNewLabel: boolean;
|
||||
}
|
||||
|
||||
const HostSidePanel = (props: IHostSidePanelProps): JSX.Element => {
|
||||
const {
|
||||
labels,
|
||||
onAddLabelClick,
|
||||
onLabelClick,
|
||||
selectedFilter,
|
||||
canAddNewLabel,
|
||||
} = props;
|
||||
|
||||
const [labelFilter, setLabelFilter] = useState<string>("");
|
||||
|
||||
const onFilterLabels = useCallback(
|
||||
(filterString: string): void => {
|
||||
setLabelFilter(filterString.toLowerCase());
|
||||
},
|
||||
[setLabelFilter]
|
||||
);
|
||||
|
||||
const allHostLabels = filter(labels, { type: "all" });
|
||||
|
||||
const hostPlatformLabels = (() => {
|
||||
const unorderedList: ILabel[] = labels.filter(
|
||||
(label) => label.type === "platform"
|
||||
);
|
||||
|
||||
const orderedList: ILabel[] = [];
|
||||
PLATFORM_LABEL_DISPLAY_ORDER.forEach((name) => {
|
||||
const label = unorderedList.find((el) => el.name === name);
|
||||
label && orderedList.push(label);
|
||||
});
|
||||
|
||||
return orderedList.filter(
|
||||
(label) =>
|
||||
["macOS", "MS Windows", "All Linux"].includes(label.name) ||
|
||||
label.count !== 0
|
||||
);
|
||||
})();
|
||||
|
||||
const customLabels = filter(labels, (label) => {
|
||||
const lowerDisplayText = label.display_text.toLowerCase();
|
||||
|
||||
return label.type === "custom" && lowerDisplayText.match(labelFilter);
|
||||
});
|
||||
|
||||
return (
|
||||
<SecondarySidePanelContainer className={`${baseClass}`}>
|
||||
<PanelGroup
|
||||
groupItems={allHostLabels}
|
||||
onLabelClick={onLabelClick}
|
||||
selectedFilter={selectedFilter}
|
||||
type="all-hosts"
|
||||
/>
|
||||
|
||||
<h3>Operating systems</h3>
|
||||
<PanelGroup
|
||||
groupItems={hostPlatformLabels}
|
||||
onLabelClick={onLabelClick}
|
||||
selectedFilter={selectedFilter}
|
||||
type="platform"
|
||||
/>
|
||||
<div className="title">
|
||||
<div>
|
||||
<h3>Labels</h3>
|
||||
</div>
|
||||
<div>
|
||||
{canAddNewLabel && (
|
||||
<Button
|
||||
variant="text-icon"
|
||||
onClick={onAddLabelClick}
|
||||
className={`${baseClass}__add-label-btn`}
|
||||
>
|
||||
<span>
|
||||
Add label <img src={PlusIcon} alt="Add label icon" />
|
||||
</span>
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className={`${baseClass}__panel-group-item ${baseClass}__panel-group-item--filter`}
|
||||
>
|
||||
<InputField
|
||||
name="tags-filter"
|
||||
onChange={onFilterLabels}
|
||||
placeholder="Filter labels by name..."
|
||||
value={labelFilter}
|
||||
inputWrapperClass={`${baseClass}__filter-labels`}
|
||||
/>
|
||||
</div>
|
||||
<PanelGroup
|
||||
groupItems={customLabels}
|
||||
onLabelClick={onLabelClick}
|
||||
selectedFilter={selectedFilter}
|
||||
type="label"
|
||||
/>
|
||||
</SecondarySidePanelContainer>
|
||||
);
|
||||
};
|
||||
|
||||
export default HostSidePanel;
|
||||
|
|
@ -21,7 +21,8 @@ class PanelGroup extends Component {
|
|||
|
||||
renderGroupItem = (item) => {
|
||||
const { onLabelClick, selectedFilter, statusLabels, type } = this.props;
|
||||
const selected = item.slug === selectedFilter || type === selectedFilter;
|
||||
const selected =
|
||||
(item && item.slug === selectedFilter) || type === selectedFilter;
|
||||
|
||||
return (
|
||||
<PanelGroupItem
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ describe("PanelGroup - component", () => {
|
|||
const validPanelGroupItems = [
|
||||
{ type: "all", display_text: "All Hosts", hosts_count: 20 },
|
||||
{ type: "platform", display_text: "MAC OS", hosts_count: 10 },
|
||||
{ type: "status", display_text: "ONLINE", hosts_count: 10 },
|
||||
];
|
||||
|
||||
const component = mount(<PanelGroup groupItems={validPanelGroupItems} />);
|
||||
|
|
@ -15,6 +14,6 @@ describe("PanelGroup - component", () => {
|
|||
it("renders a PanelGroupItem for each group item", () => {
|
||||
const panelGroupItems = component.find("PanelGroupItem");
|
||||
|
||||
expect(panelGroupItems.length).toEqual(3);
|
||||
expect(panelGroupItems.length).toEqual(2);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,93 +0,0 @@
|
|||
import React, { Component } from "react";
|
||||
import PropTypes from "prop-types";
|
||||
import classnames from "classnames";
|
||||
|
||||
import statusLabelsInterface from "interfaces/status_labels";
|
||||
import darwinIcon from "../../../../../assets/images/icon-darwin-fleet-black-16x16@2x.png";
|
||||
import linuxIcon from "../../../../../assets/images/icon-linux-fleet-black-16x16@2x.png";
|
||||
import ubuntuIcon from "../../../../../assets/images/icon-ubuntu-fleet-black-16x16@2x.png";
|
||||
import centosIcon from "../../../../../assets/images/icon-centos-fleet-black-16x16@2x.png";
|
||||
import windowsIcon from "../../../../../assets/images/icon-windows-fleet-black-16x16@2x.png";
|
||||
|
||||
const baseClass = "panel-group-item";
|
||||
|
||||
const displayIcon = (name) => {
|
||||
switch (name) {
|
||||
case "macOS":
|
||||
return <img src={darwinIcon} alt="Apple icon" />;
|
||||
case "Linux":
|
||||
return <img src={linuxIcon} alt="Linux icon" />;
|
||||
case "Ubuntu Linux":
|
||||
return <img src={ubuntuIcon} alt="Ubuntu icon" />;
|
||||
case "CentOS Linux":
|
||||
return <img src={centosIcon} alt="Centos icon" />;
|
||||
case "Windows":
|
||||
return <img src={windowsIcon} alt="Windows icon" />;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
};
|
||||
class PanelGroupItem extends Component {
|
||||
static propTypes = {
|
||||
item: PropTypes.shape({
|
||||
count: PropTypes.number.isRequired,
|
||||
title_description: PropTypes.string,
|
||||
display_text: PropTypes.string.isRequired,
|
||||
type: PropTypes.string.isRequired,
|
||||
id: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
|
||||
name: PropTypes.string,
|
||||
label_type: PropTypes.string,
|
||||
}).isRequired,
|
||||
onLabelClick: PropTypes.func,
|
||||
isSelected: PropTypes.bool,
|
||||
statusLabels: statusLabelsInterface,
|
||||
type: PropTypes.string,
|
||||
};
|
||||
|
||||
displayCount = () => {
|
||||
const { item, statusLabels, type } = this.props;
|
||||
|
||||
if (type !== "status") {
|
||||
return item.count;
|
||||
}
|
||||
|
||||
if (statusLabels.loading_counts) {
|
||||
return "";
|
||||
}
|
||||
|
||||
return statusLabels[`${item.id}_count`];
|
||||
};
|
||||
|
||||
render() {
|
||||
const { displayCount } = this;
|
||||
const { item, onLabelClick, isSelected } = this.props;
|
||||
const { display_text: displayText, type, label_type, name } = item;
|
||||
|
||||
const wrapperClassName = classnames(
|
||||
baseClass,
|
||||
"button",
|
||||
"button--contextual-nav-item",
|
||||
`${baseClass}__${type.toLowerCase()}`,
|
||||
`${baseClass}__${type.toLowerCase()}--${displayText
|
||||
.toLowerCase()
|
||||
.replace(" ", "-")}`,
|
||||
{
|
||||
[`${baseClass}--selected`]: isSelected,
|
||||
}
|
||||
);
|
||||
|
||||
return (
|
||||
<button className={wrapperClassName} onClick={onLabelClick}>
|
||||
<div className={`${baseClass}__flexy`}>
|
||||
<span className={`${baseClass}__name`}>
|
||||
{label_type === "builtin" && displayIcon(name)}
|
||||
{displayText}
|
||||
</span>
|
||||
<span className={`${baseClass}__count`}>{displayCount()}</span>
|
||||
</div>
|
||||
</button>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default PanelGroupItem;
|
||||
|
|
@ -1,66 +0,0 @@
|
|||
import React from "react";
|
||||
import { mount } from "enzyme";
|
||||
|
||||
import PanelGroupItem from "./PanelGroupItem";
|
||||
|
||||
describe("PanelGroupItem - component", () => {
|
||||
const id = 0;
|
||||
const validPanelGroupItem = {
|
||||
count: 20,
|
||||
display_text: "All Hosts",
|
||||
type: "all",
|
||||
id,
|
||||
};
|
||||
const validStatusGroupItem = {
|
||||
count: 111,
|
||||
display_text: "Online Hosts",
|
||||
id: "online",
|
||||
type: "status",
|
||||
};
|
||||
const statusLabels = {
|
||||
online_count: 20,
|
||||
loading_counts: false,
|
||||
};
|
||||
const loadingStatusLabels = {
|
||||
online_count: 20,
|
||||
loading_counts: true,
|
||||
};
|
||||
|
||||
const labelComponent = mount(
|
||||
<PanelGroupItem item={validPanelGroupItem} statusLabels={statusLabels} />
|
||||
);
|
||||
|
||||
const statusLabelComponent = mount(
|
||||
<PanelGroupItem
|
||||
item={validStatusGroupItem}
|
||||
statusLabels={statusLabels}
|
||||
type="status"
|
||||
/>
|
||||
);
|
||||
|
||||
const loadingStatusLabelComponent = mount(
|
||||
<PanelGroupItem
|
||||
item={validStatusGroupItem}
|
||||
statusLabels={loadingStatusLabels}
|
||||
type="status"
|
||||
/>
|
||||
);
|
||||
|
||||
it("renders the item text", () => {
|
||||
expect(labelComponent.text()).toContain(validPanelGroupItem.display_text);
|
||||
});
|
||||
|
||||
it("renders the item count", () => {
|
||||
expect(labelComponent.text()).toContain(validPanelGroupItem.count);
|
||||
expect(statusLabelComponent.text()).not.toContain(
|
||||
validStatusGroupItem.count
|
||||
);
|
||||
expect(statusLabelComponent.text()).toContain(statusLabels.online_count);
|
||||
expect(loadingStatusLabelComponent.text()).not.toContain(
|
||||
statusLabels.online_count
|
||||
);
|
||||
expect(loadingStatusLabelComponent.text()).not.toContain(
|
||||
validPanelGroupItem.count
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
import React from "react";
|
||||
import classnames from "classnames";
|
||||
|
||||
import { ILabel } from "interfaces/label";
|
||||
import { PLATFORM_LABEL_DISPLAY_NAMES } from "utilities/constants";
|
||||
import darwinIcon from "../../../../../assets/images/icon-darwin-fleet-black-16x16@2x.png";
|
||||
import linuxIcon from "../../../../../assets/images/icon-linux-fleet-black-16x16@2x.png";
|
||||
import ubuntuIcon from "../../../../../assets/images/icon-ubuntu-fleet-black-16x16@2x.png";
|
||||
import centosIcon from "../../../../../assets/images/icon-centos-fleet-black-16x16@2x.png";
|
||||
import windowsIcon from "../../../../../assets/images/icon-windows-fleet-black-16x16@2x.png";
|
||||
|
||||
const baseClass = "panel-group-item";
|
||||
|
||||
const displayName = (name: string) => {
|
||||
return PLATFORM_LABEL_DISPLAY_NAMES[name] || name;
|
||||
};
|
||||
|
||||
const displayIcon = (name: string) => {
|
||||
switch (name) {
|
||||
case "macOS":
|
||||
return <img src={darwinIcon} alt="Apple icon" />;
|
||||
case "Linux":
|
||||
return <img src={linuxIcon} alt="Linux icon" />;
|
||||
case "Ubuntu Linux":
|
||||
return <img src={ubuntuIcon} alt="Ubuntu icon" />;
|
||||
case "CentOS Linux":
|
||||
return <img src={centosIcon} alt="Centos icon" />;
|
||||
case "Windows":
|
||||
return <img src={windowsIcon} alt="Windows icon" />;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
interface IPanelGroupItemProps {
|
||||
item: ILabel;
|
||||
onLabelClick: () => void;
|
||||
isSelected: boolean;
|
||||
}
|
||||
|
||||
const PanelGroupItem = (props: IPanelGroupItemProps): JSX.Element => {
|
||||
const { item, onLabelClick, isSelected } = props;
|
||||
const {
|
||||
count,
|
||||
display_text: displayText,
|
||||
label_type: labelType,
|
||||
name,
|
||||
} = item;
|
||||
|
||||
const wrapperClassName = classnames(
|
||||
baseClass,
|
||||
"button",
|
||||
"button--contextual-nav-item",
|
||||
`${baseClass}__${displayText.toLowerCase().replace(" ", "-")}`,
|
||||
{
|
||||
[`${baseClass}--selected`]: isSelected,
|
||||
}
|
||||
);
|
||||
|
||||
return (
|
||||
<button className={wrapperClassName} onClick={onLabelClick}>
|
||||
<div className={`${baseClass}__flexy`}>
|
||||
<span className={`${baseClass}__name`}>
|
||||
{labelType === "builtin" && displayIcon(displayName(name))}
|
||||
|
||||
{displayName(name)}
|
||||
</span>
|
||||
<span className={`${baseClass}__count`}>{count}</span>
|
||||
</div>
|
||||
</button>
|
||||
);
|
||||
};
|
||||
|
||||
export default PanelGroupItem;
|
||||
|
|
@ -24,6 +24,11 @@
|
|||
color: $core-vibrant-blue !important;
|
||||
align-self: right;
|
||||
|
||||
span {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
img {
|
||||
margin-left: $pad-xsmall;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import moment from "moment";
|
|||
import yaml from "js-yaml";
|
||||
import stringUtils from "utilities/strings";
|
||||
import { ITeam } from "interfaces/team";
|
||||
import { PLATFORM_LABEL_DISPLAY_TYPES } from "utilities/constants";
|
||||
|
||||
const ORG_INFO_ATTRS = ["org_name", "org_logo_url"];
|
||||
const ADMIN_ATTRS = ["email", "name", "password", "password_confirmation"];
|
||||
|
|
@ -176,20 +177,11 @@ export const frontendFormattedConfig = (config: any) => {
|
|||
};
|
||||
|
||||
const formatLabelResponse = (response: any): { [index: string]: any } => {
|
||||
const labelTypeForDisplayText: { [index: string]: any } = {
|
||||
"All Hosts": "all",
|
||||
"MS Windows": "platform",
|
||||
"CentOS Linux": "platform",
|
||||
macOS: "platform",
|
||||
"Ubuntu Linux": "platform",
|
||||
"Red Hat Linux": "platform",
|
||||
};
|
||||
|
||||
const labels = response.labels.map((label: any) => {
|
||||
return {
|
||||
...label,
|
||||
slug: labelSlug(label),
|
||||
type: labelTypeForDisplayText[label.display_text] || "custom",
|
||||
type: PLATFORM_LABEL_DISPLAY_TYPES[label.display_text] || "custom",
|
||||
};
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -19,11 +19,15 @@ export interface ILabel {
|
|||
updated_at: string;
|
||||
id: number | string;
|
||||
name: string;
|
||||
// description: string;
|
||||
query: string;
|
||||
label_type: string;
|
||||
label_type: "regular" | "builtin";
|
||||
label_membership_type: string;
|
||||
hosts_count: number;
|
||||
display_text: string;
|
||||
count: number; // seems to be a repeat of hosts_count issue #1618
|
||||
host_ids: number[] | null;
|
||||
type: "custom" | "platform" | "status";
|
||||
// slug: string; // e.g., "labels/13" | "online"
|
||||
// target_type: string; // e.g., "labels"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,12 @@
|
|||
import PropTypes from "prop-types";
|
||||
|
||||
export interface IStatusLabels {
|
||||
loading_counts: boolean;
|
||||
new_count: number;
|
||||
online_count: number;
|
||||
offline_count: number;
|
||||
mia_count: number;
|
||||
}
|
||||
export default PropTypes.shape({
|
||||
loading_counts: PropTypes.bool,
|
||||
new_count: PropTypes.number,
|
||||
|
|
@ -33,7 +33,10 @@ import policiesClient from "services/entities/policies";
|
|||
import permissionUtils from "utilities/permissions";
|
||||
import sortUtils from "utilities/sort";
|
||||
|
||||
import { PolicyResponse } from "utilities/constants";
|
||||
import {
|
||||
PLATFORM_LABEL_DISPLAY_NAMES,
|
||||
PolicyResponse,
|
||||
} from "utilities/constants";
|
||||
import { getNextLocationPath } from "./helpers";
|
||||
import {
|
||||
defaultHiddenColumns,
|
||||
|
|
@ -126,8 +129,11 @@ export class ManageHostsPage extends PureComponent {
|
|||
isOnGlobalTeam: PropTypes.bool,
|
||||
isBasicTier: PropTypes.bool,
|
||||
currentUser: userInterface,
|
||||
policyId: PropTypes.number,
|
||||
policyResponse: PolicyResponse,
|
||||
policyId: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
|
||||
policyResponse: PropTypes.oneOf([
|
||||
PolicyResponse.PASSING,
|
||||
PolicyResponse.FAILING,
|
||||
]),
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
|
|
@ -1036,15 +1042,17 @@ export class ManageHostsPage extends PureComponent {
|
|||
renderHeaderLabelBlock = ({
|
||||
description,
|
||||
display_text: displayText,
|
||||
type,
|
||||
label_type: labelType,
|
||||
}) => {
|
||||
const { onEditLabelClick, toggleDeleteLabelModal } = this;
|
||||
|
||||
displayText = PLATFORM_LABEL_DISPLAY_NAMES[displayText] || displayText;
|
||||
|
||||
return (
|
||||
<div className={`${baseClass}__label-block`}>
|
||||
<div className="title">
|
||||
<span>{displayText}</span>
|
||||
{type !== "platform" && (
|
||||
{labelType !== "builtin" && (
|
||||
<>
|
||||
<Button onClick={onEditLabelClick} variant={"text-icon"}>
|
||||
<img src={PencilIcon} alt="Edit label" />
|
||||
|
|
@ -1091,6 +1099,7 @@ export class ManageHostsPage extends PureComponent {
|
|||
</div>
|
||||
);
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
renderForm = () => {
|
||||
|
|
|
|||
|
|
@ -11,13 +11,6 @@ export const FREQUENCY_DROPDOWN_OPTIONS = [
|
|||
{ value: 604800, label: "Every week" },
|
||||
];
|
||||
|
||||
export const PLATFORM_OPTIONS = [
|
||||
{ label: "All", value: "" },
|
||||
{ label: "Windows", value: "windows" },
|
||||
{ label: "Linux", value: "linux" },
|
||||
{ label: "macOS", value: "darwin" },
|
||||
];
|
||||
|
||||
export const LOGGING_TYPE_OPTIONS = [
|
||||
{ label: "Snapshot", value: "snapshot" },
|
||||
{ label: "Differential", value: "differential" },
|
||||
|
|
@ -54,3 +47,39 @@ export const MIN_OSQUERY_VERSION_OPTIONS = [
|
|||
{ label: "1.8.2 +", value: "1.8.2" },
|
||||
{ label: "1.8.1 +", value: "1.8.1" },
|
||||
];
|
||||
|
||||
export const PLATFORM_LABEL_DISPLAY_NAMES: Record<string, string> = {
|
||||
"All Hosts": "All Hosts",
|
||||
"All Linux": "Linux",
|
||||
"CentOS Linux": "CentOS Linux",
|
||||
macOS: "macOS",
|
||||
"MS Windows": "Windows",
|
||||
"Red Hat Linux": "Red Hat Linux",
|
||||
"Ubuntu Linux": "Ubuntu Linux",
|
||||
};
|
||||
|
||||
export const PLATFORM_LABEL_DISPLAY_ORDER = [
|
||||
"macOS",
|
||||
"All Linux",
|
||||
"CentOS Linux",
|
||||
"Red Hat Linux",
|
||||
"Ubuntu Linux",
|
||||
"MS Windows",
|
||||
];
|
||||
|
||||
export const PLATFORM_LABEL_DISPLAY_TYPES: Record<string, string> = {
|
||||
"All Hosts": "all",
|
||||
"All Linux": "platform",
|
||||
"CentOS Linux": "platform",
|
||||
macOS: "platform",
|
||||
"MS Windows": "platform",
|
||||
"Red Hat Linux": "platform",
|
||||
"Ubuntu Linux": "platform",
|
||||
};
|
||||
|
||||
export const PLATFORM_OPTIONS = [
|
||||
{ label: "All", value: "" },
|
||||
{ label: "Windows", value: "windows" },
|
||||
{ label: "Linux", value: "linux" },
|
||||
{ label: "macOS", value: "darwin" },
|
||||
];
|
||||
|
|
|
|||
Loading…
Reference in a new issue