mirror of
https://github.com/empayre/fleet.git
synced 2024-11-07 09:18:59 +00:00
138 lines
3.7 KiB
TypeScript
138 lines
3.7 KiB
TypeScript
import React, { useState, useCallback } from "react";
|
|
import { filter } from "lodash";
|
|
|
|
import { ILabel } from "interfaces/label";
|
|
import { PLATFORM_LABEL_DISPLAY_ORDER } from "utilities/constants";
|
|
|
|
import Spinner from "components/Spinner";
|
|
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 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
|
|
) => (evt: React.MouseEvent<HTMLButtonElement>) => void;
|
|
selectedFilter: string | undefined;
|
|
canAddNewLabel: boolean;
|
|
isLabelsLoading: boolean;
|
|
}
|
|
|
|
const HostSidePanel = ({
|
|
labels,
|
|
onAddLabelClick,
|
|
onLabelClick,
|
|
selectedFilter,
|
|
canAddNewLabel,
|
|
isLabelsLoading,
|
|
}: IHostSidePanelProps): JSX.Element => {
|
|
const [labelFilter, setLabelFilter] = useState<string>("");
|
|
|
|
const onFilterLabels = useCallback(
|
|
(filterString: string): void => {
|
|
setLabelFilter(filterString.toLowerCase());
|
|
},
|
|
[setLabelFilter]
|
|
);
|
|
|
|
if (isLabelsLoading || !labels) {
|
|
return (
|
|
<SecondarySidePanelContainer className={`${baseClass}`}>
|
|
<Spinner />
|
|
</SecondarySidePanelContainer>
|
|
);
|
|
}
|
|
|
|
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;
|