From 3e310ba15054e7e2000be90d5dc343a1c704c98e Mon Sep 17 00:00:00 2001 From: RachelElysia <71795832+RachelElysia@users.noreply.github.com> Date: Thu, 1 Sep 2022 14:42:25 -0700 Subject: [PATCH] Fleet UI: Fix bug with label sidebar not collapsing (#7402) --- .../issue-7364-fix-label-collapsing-sidebar | 1 + frontend/hooks/useToggleSidePanel.ts | 32 +++ .../LabelForm/LabelForm.tsx | 29 +- .../LabelForm/_styles.scss | 0 .../LabelForm/index.ts | 0 frontend/pages/LabelPage/LabelPage.tsx | 218 +++++++++++++++ frontend/pages/LabelPage/_styles.scss | 14 + frontend/pages/LabelPage/index.ts | 1 + .../hosts/ManageHostsPage/ManageHostsPage.tsx | 264 +++--------------- .../pages/hosts/ManageHostsPage/constants.ts | 2 - frontend/router/index.tsx | 6 + frontend/router/paths.ts | 7 + frontend/utilities/constants.ts | 4 - frontend/utilities/helpers.ts | 33 +-- 14 files changed, 351 insertions(+), 260 deletions(-) create mode 100644 changes/issue-7364-fix-label-collapsing-sidebar create mode 100644 frontend/hooks/useToggleSidePanel.ts rename frontend/pages/{hosts/ManageHostsPage/components => LabelPage}/LabelForm/LabelForm.tsx (91%) rename frontend/pages/{hosts/ManageHostsPage/components => LabelPage}/LabelForm/_styles.scss (100%) rename frontend/pages/{hosts/ManageHostsPage/components => LabelPage}/LabelForm/index.ts (100%) create mode 100644 frontend/pages/LabelPage/LabelPage.tsx create mode 100644 frontend/pages/LabelPage/_styles.scss create mode 100644 frontend/pages/LabelPage/index.ts diff --git a/changes/issue-7364-fix-label-collapsing-sidebar b/changes/issue-7364-fix-label-collapsing-sidebar new file mode 100644 index 000000000..d8dea2453 --- /dev/null +++ b/changes/issue-7364-fix-label-collapsing-sidebar @@ -0,0 +1 @@ +* Bug fix to collapse label sidebar \ No newline at end of file diff --git a/frontend/hooks/useToggleSidePanel.ts b/frontend/hooks/useToggleSidePanel.ts new file mode 100644 index 000000000..8e455c3f2 --- /dev/null +++ b/frontend/hooks/useToggleSidePanel.ts @@ -0,0 +1,32 @@ +import { useCallback, useState } from "react"; + +interface IUseToggleSidePanelHook { + isSidePanelOpen: boolean; + toggleSidePanel: () => void; + setSidePanelOpen: (isOpen: boolean) => void; +} + +const useToggleSidePanel = ( + initialIsOpened: boolean +): IUseToggleSidePanelHook => { + const [isSidePanelOpen, setIsOpen] = useState(initialIsOpened); + + const toggleSidePanel = useCallback(() => { + setIsOpen(!isSidePanelOpen); + }, [setIsOpen, isSidePanelOpen]); + + const setSidePanelOpen = useCallback( + (isOpen: boolean) => { + setIsOpen(isOpen); + }, + [setIsOpen] + ); + + return { + isSidePanelOpen, + toggleSidePanel, + setSidePanelOpen, + }; +}; + +export default useToggleSidePanel; diff --git a/frontend/pages/hosts/ManageHostsPage/components/LabelForm/LabelForm.tsx b/frontend/pages/LabelPage/LabelForm/LabelForm.tsx similarity index 91% rename from frontend/pages/hosts/ManageHostsPage/components/LabelForm/LabelForm.tsx rename to frontend/pages/LabelPage/LabelForm/LabelForm.tsx index 39ba5e0aa..bf1c66b69 100644 --- a/frontend/pages/hosts/ManageHostsPage/components/LabelForm/LabelForm.tsx +++ b/frontend/pages/LabelPage/LabelForm/LabelForm.tsx @@ -1,4 +1,4 @@ -import React, { useState, useEffect } from "react"; +import React, { useState, useContext, useEffect } from "react"; import { IAceEditor } from "react-ace/lib/types"; import { noop, size } from "lodash"; import { useDebouncedCallback } from "use-debounce"; @@ -12,16 +12,19 @@ import InputField from "components/forms/fields/InputField"; import FleetAce from "components/FleetAce"; // @ts-ignore import validateQuery from "components/forms/validators/validate_query"; +import InfoIcon from "../../../../assets/images/icon-info-purple-14x14@2x.png"; interface ILabelFormProps { baseError: string; selectedLabel?: ILabel; isEdit?: boolean; + isUpdatingLabel?: boolean; onCancel: () => void; handleSubmit: (formData: ILabelFormData) => void; - onOsqueryTableSelect?: (tableName: string) => void; + onOpenSchemaSidebar: () => void; + onOsqueryTableSelect: (tableName: string) => void; + showOpenSchemaActionText: boolean; backendValidators: { [key: string]: string }; - isUpdatingLabel?: boolean; } const baseClass = "label-form"; @@ -57,11 +60,13 @@ const LabelForm = ({ baseError, selectedLabel, isEdit, + isUpdatingLabel, onCancel, handleSubmit, + onOpenSchemaSidebar, onOsqueryTableSelect, + showOpenSchemaActionText, backendValidators, - isUpdatingLabel, }: ILabelFormProps): JSX.Element => { const [name, setName] = useState(selectedLabel?.name || ""); const [nameError, setNameError] = useState(""); @@ -156,6 +161,21 @@ const LabelForm = ({ }); }; + const renderLabelComponent = (): JSX.Element | null => { + if (!showOpenSchemaActionText) { + return null; + } + + return ( + + ); + }; + const isBuiltin = selectedLabel && (selectedLabel.label_type === "builtin" || selectedLabel.type === "status"); @@ -190,6 +210,7 @@ const LabelForm = ({ onChange={onQueryChange} value={query} label="SQL" + labelActionComponent={renderLabelComponent()} onLoad={onLoad} readOnly={isEdit} wrapperClassName={`${baseClass}__text-editor-wrapper`} diff --git a/frontend/pages/hosts/ManageHostsPage/components/LabelForm/_styles.scss b/frontend/pages/LabelPage/LabelForm/_styles.scss similarity index 100% rename from frontend/pages/hosts/ManageHostsPage/components/LabelForm/_styles.scss rename to frontend/pages/LabelPage/LabelForm/_styles.scss diff --git a/frontend/pages/hosts/ManageHostsPage/components/LabelForm/index.ts b/frontend/pages/LabelPage/LabelForm/index.ts similarity index 100% rename from frontend/pages/hosts/ManageHostsPage/components/LabelForm/index.ts rename to frontend/pages/LabelPage/LabelForm/index.ts diff --git a/frontend/pages/LabelPage/LabelPage.tsx b/frontend/pages/LabelPage/LabelPage.tsx new file mode 100644 index 000000000..76564de4e --- /dev/null +++ b/frontend/pages/LabelPage/LabelPage.tsx @@ -0,0 +1,218 @@ +import React, { useState, useContext, useEffect } from "react"; +import { useQuery } from "react-query"; +import { InjectedRouter, Params } from "react-router/lib/Router"; + +import PATHS from "router/paths"; +import MainContent from "components/MainContent"; +import SidePanelContent from "components/SidePanelContent"; +import QuerySidePanel from "components/side_panels/QuerySidePanel"; +import Spinner from "components/Spinner"; +import { QueryContext } from "context/query"; +import { NotificationContext } from "context/notification"; +import { IApiError } from "interfaces/errors"; +import { ILabel, ILabelFormData } from "interfaces/label"; +import labelsAPI, { ILabelsResponse } from "services/entities/labels"; +import deepDifference from "utilities/deep_difference"; +import useToggleSidePanel from "hooks/useToggleSidePanel"; + +import LabelForm from "./LabelForm"; + +const baseClass = "label-page"; + +interface ILabelPageProps { + router: InjectedRouter; + params: Params; + location: { + pathname: string; + }; +} + +const DEFAULT_CREATE_LABEL_ERRORS = { + name: "", +}; + +const LabelPage = ({ + router, + params, + location, +}: ILabelPageProps): JSX.Element | null => { + const isEditLabel = !location.pathname.includes("new"); + + const [selectedLabel, setSelectedLabel] = useState(); + const { isSidePanelOpen, setSidePanelOpen } = useToggleSidePanel(true); + const [showOpenSchemaActionText, setShowOpenSchemaActionText] = useState( + false + ); + const [labelValidator, setLabelValidator] = useState<{ + [key: string]: string; + }>(DEFAULT_CREATE_LABEL_ERRORS); + const [isUpdatingLabel, setIsUpdatingLabel] = useState(false); + const [isLoading, setIsLoading] = useState(true); + + const { selectedOsqueryTable, setSelectedOsqueryTable } = useContext( + QueryContext + ); + const { renderFlash } = useContext(NotificationContext); + + const { data: labels, error: labelsError } = useQuery< + ILabelsResponse, + Error, + ILabel[] + >(["labels"], () => labelsAPI.loadAll(), { + select: (data: ILabelsResponse) => data.labels, + onSuccess: (responseLabels: ILabel[]) => { + if (params.label_id) { + const selectLabel = responseLabels.find( + (label) => label.id === parseInt(params.label_id, 10) + ); + setSelectedLabel(selectLabel); + setIsLoading(false); + } + }, + }); + + const onCloseSchemaSidebar = () => { + setSidePanelOpen(false); + setShowOpenSchemaActionText(true); + }; + + const onOpenSchemaSidebar = () => { + setSidePanelOpen(true); + setShowOpenSchemaActionText(false); + }; + + const onOsqueryTableSelect = (tableName: string) => { + setSelectedOsqueryTable(tableName); + }; + + const onEditLabel = (formData: ILabelFormData) => { + if (!selectedLabel) { + console.error("Label isn't available. This should not happen."); + return; + } + + setIsUpdatingLabel(true); + const updateAttrs = deepDifference(formData, selectedLabel); + + labelsAPI + .update(selectedLabel, updateAttrs) + .then(() => { + router.push(PATHS.MANAGE_HOSTS_LABEL(selectedLabel.id)); + renderFlash( + "success", + "Label updated. Try refreshing this page in just a moment to see the updated host count for your label." + ); + }) + .catch((updateError: { data: IApiError }) => { + if (updateError.data.errors[0].reason.includes("Duplicate")) { + setLabelValidator({ + name: "A label with this name already exists", + }); + } else if ( + updateError.data.errors[0].reason.includes( + "Data too long for column 'name'" + ) + ) { + setLabelValidator({ + name: "Label name is too long", + }); + } else if ( + updateError.data.errors[0].reason.includes( + "Data too long for column 'description'" + ) + ) { + setLabelValidator({ + description: "Label description is too long", + }); + } else { + renderFlash("error", "Could not create label. Please try again."); + } + }) + .finally(() => { + setIsUpdatingLabel(false); + }); + }; + + const onAddLabel = (formData: ILabelFormData) => { + setIsUpdatingLabel(true); + + labelsAPI + .create(formData) + .then((label: ILabel) => { + router.push(PATHS.MANAGE_HOSTS_LABEL(label.id)); + renderFlash( + "success", + "Label created. Try refreshing this page in just a moment to see the updated host count for your label." + ); + }) + .catch((updateError: any) => { + if (updateError.data.errors[0].reason.includes("Duplicate")) { + setLabelValidator({ + name: "A label with this name already exists", + }); + } else if ( + updateError.data.errors[0].reason.includes( + "Data too long for column 'name'" + ) + ) { + setLabelValidator({ + name: "Label name is too long", + }); + } else if ( + updateError.data.errors[0].reason.includes( + "Data too long for column 'description'" + ) + ) { + setLabelValidator({ + description: "Label description is too long", + }); + } else { + renderFlash("error", "Could not create label. Please try again."); + } + }) + .finally(() => { + setIsUpdatingLabel(false); + }); + }; + + const onCancelLabel = () => { + router.goBack(); + }; + + return ( + <> + +
+ {isLoading ? ( + + ) : ( + + )} +
+
+ {isSidePanelOpen && !isEditLabel && ( + + + + )} + + ); +}; + +export default LabelPage; diff --git a/frontend/pages/LabelPage/_styles.scss b/frontend/pages/LabelPage/_styles.scss new file mode 100644 index 000000000..e9a394a6f --- /dev/null +++ b/frontend/pages/LabelPage/_styles.scss @@ -0,0 +1,14 @@ +.label-page { + &__sandboxMode { + margin-top: 70px; + } + + h1 { + margin: 0 0 $pad-xlarge; + } + + h2 { + font-size: $x-small; + font-weight: $bold; + } +} diff --git a/frontend/pages/LabelPage/index.ts b/frontend/pages/LabelPage/index.ts new file mode 100644 index 000000000..45649039f --- /dev/null +++ b/frontend/pages/LabelPage/index.ts @@ -0,0 +1 @@ +export { default } from "./LabelPage"; diff --git a/frontend/pages/hosts/ManageHostsPage/ManageHostsPage.tsx b/frontend/pages/hosts/ManageHostsPage/ManageHostsPage.tsx index 239c2a0d7..88a5f23b5 100644 --- a/frontend/pages/hosts/ManageHostsPage/ManageHostsPage.tsx +++ b/frontend/pages/hosts/ManageHostsPage/ManageHostsPage.tsx @@ -26,25 +26,21 @@ import { import PATHS from "router/paths"; import { AppContext } from "context/app"; -import { QueryContext } from "context/query"; import { TableContext } from "context/table"; import { NotificationContext } from "context/notification"; import { IEnrollSecret, IEnrollSecretsResponse, } from "interfaces/enroll_secret"; -import { IApiError } from "interfaces/errors"; import { IHost } from "interfaces/host"; -import { ILabel, ILabelFormData } from "interfaces/label"; +import { ILabel } from "interfaces/label"; import { IMDMSolution } from "interfaces/macadmins"; import { IOperatingSystemVersion } from "interfaces/operating_system"; import { IPolicy } from "interfaces/policy"; import { ISoftware } from "interfaces/software"; import { ITeam } from "interfaces/team"; -import deepDifference from "utilities/deep_difference"; import sortUtils from "utilities/sort"; import { - DEFAULT_CREATE_LABEL_ERRORS, HOSTS_SEARCH_BOX_PLACEHOLDER, HOSTS_SEARCH_BOX_TOOLTIP, PLATFORM_LABEL_DISPLAY_NAMES, @@ -54,14 +50,12 @@ import { import Button from "components/buttons/Button"; // @ts-ignore import Dropdown from "components/forms/fields/Dropdown"; -import QuerySidePanel from "components/side_panels/QuerySidePanel"; import TableContainer from "components/TableContainer"; import TableDataError from "components/DataError"; import { IActionButtonProps } from "components/TableContainer/DataTable/ActionButton"; import TeamsDropdown from "components/TeamsDropdown"; import Spinner from "components/Spinner"; import MainContent from "components/MainContent"; -import SidePanelContent from "components/SidePanelContent"; import { getValidatedTeamId } from "utilities/helpers"; import { @@ -70,8 +64,6 @@ import { generateAvailableTableHeaders, } from "./HostTableConfig"; import { - NEW_LABEL_HASH, - EDIT_LABEL_HASH, ALL_HOSTS_LABEL, LABEL_SLUG_PREFIX, DEFAULT_SORT_HEADER, @@ -80,8 +72,6 @@ import { HOST_SELECT_STATUSES, } from "./constants"; import { isAcceptableStatus, getNextLocationPath } from "./helpers"; - -import LabelForm from "./components/LabelForm"; import DeleteSecretModal from "../../../components/DeleteSecretModal"; import SecretEditorModal from "../../../components/SecretEditorModal"; import AddHostsModal from "../../../components/AddHostsModal"; @@ -166,10 +156,6 @@ const ManageHostsPage = ({ }); } } - - const { selectedOsqueryTable, setSelectedOsqueryTable } = useContext( - QueryContext - ); const { setResetSelectedRows } = useContext(TableContext); const hostHiddenColumns = localStorage.getItem("hostHiddenColumns"); @@ -242,18 +228,13 @@ const ManageHostsPage = ({ currentQueryOptions, setCurrentQueryOptions, ] = useState(); - const [labelValidator, setLabelValidator] = useState<{ - [key: string]: string; - }>(DEFAULT_CREATE_LABEL_ERRORS); - const [resetPageIndex, setResetPageIndex] = useState(false); - const [isUpdatingLabel, setIsUpdatingLabel] = useState(false); - const [isUpdatingSecret, setIsUpdatingSecret] = useState(false); - const [isUpdatingHosts, setIsUpdatingHosts] = useState(false); + const [resetPageIndex, setResetPageIndex] = useState(false); + const [isUpdatingLabel, setIsUpdatingLabel] = useState(false); + const [isUpdatingSecret, setIsUpdatingSecret] = useState(false); + const [isUpdatingHosts, setIsUpdatingHosts] = useState(false); // ======== end states - const isAddLabel = location.hash === NEW_LABEL_HASH; - const isEditLabel = location.hash === EDIT_LABEL_HASH; const routeTemplate = route?.path ?? ""; const policyId = queryParams?.policy_id; const policyResponse: PolicyResponse = queryParams?.policy_response; @@ -747,17 +728,12 @@ const ManageHostsPage = ({ }; const onAddLabelClick = () => { - setLabelValidator(DEFAULT_CREATE_LABEL_ERRORS); - router.push(`${PATHS.MANAGE_HOSTS}${NEW_LABEL_HASH}`); + router.push(`${PATHS.NEW_LABEL}`); }; const onEditLabelClick = (evt: React.MouseEvent) => { evt.preventDefault(); - - setLabelValidator(DEFAULT_CREATE_LABEL_ERRORS); - router.push( - `${PATHS.MANAGE_HOSTS}/${getLabelSelected()}${EDIT_LABEL_HASH}` - ); + router.push(`${PATHS.EDIT_LABEL(parseInt(labelID, 10))}`); }; const onSaveColumns = (newHiddenColumns: string[]) => { @@ -766,10 +742,6 @@ const ManageHostsPage = ({ setShowEditColumnsModal(false); }; - const onCancelLabel = () => { - router.goBack(); - }; - // NOTE: used to reset page number to 0 when modifying filters useEffect(() => { setResetPageIndex(false); @@ -985,102 +957,6 @@ const ManageHostsPage = ({ } }; - const onEditLabel = (formData: ILabelFormData) => { - if (!selectedLabel) { - console.error("Label isn't available. This should not happen."); - return; - } - - const updateAttrs = deepDifference(formData, selectedLabel); - setIsUpdatingLabel(true); - - labelsAPI - .update(selectedLabel, updateAttrs) - .then(() => { - refetchLabels(); - renderFlash( - "success", - "Label updated. Try refreshing this page in just a moment to see the updated host count for your label." - ); - setLabelValidator({}); - }) - .catch((updateError: { data: IApiError }) => { - if (updateError.data.errors[0].reason.includes("Duplicate")) { - setLabelValidator({ - name: "A label with this name already exists", - }); - } else if ( - updateError.data.errors[0].reason.includes( - "Data too long for column 'name'" - ) - ) { - setLabelValidator({ - name: "Label name is too long", - }); - } else if ( - updateError.data.errors[0].reason.includes( - "Data too long for column 'description'" - ) - ) { - setLabelValidator({ - description: "Label description is too long", - }); - } else { - renderFlash("error", "Could not create label. Please try again."); - } - }) - .finally(() => { - setIsUpdatingLabel(false); - }); - }; - - const onOsqueryTableSelect = (tableName: string) => { - setSelectedOsqueryTable(tableName); - }; - - const onSaveAddLabel = (formData: ILabelFormData) => { - setIsUpdatingLabel(true); - labelsAPI - .create(formData) - .then(() => { - router.push(PATHS.MANAGE_HOSTS); - renderFlash( - "success", - "Label created. Try refreshing this page in just a moment to see the updated host count for your label." - ); - setLabelValidator({}); - refetchLabels(); - }) - .catch((updateError: any) => { - if (updateError.data.errors[0].reason.includes("Duplicate")) { - setLabelValidator({ - name: "A label with this name already exists", - }); - } else if ( - updateError.data.errors[0].reason.includes( - "Data too long for column 'name'" - ) - ) { - setLabelValidator({ - name: "Label name is too long", - }); - } else if ( - updateError.data.errors[0].reason.includes( - "Data too long for column 'description'" - ) - ) { - setLabelValidator({ - description: "Label description is too long", - }); - } else { - renderFlash("error", "Could not create label. Please try again."); - } - }) - .finally(() => { - setIsUpdatingLabel(false); - }); - }; - const onClearLabelFilter = () => { const allHostsLabel = labels?.find((label) => label.name === "All Hosts"); if (allHostsLabel !== undefined) { @@ -1724,38 +1600,6 @@ const ManageHostsPage = ({ return null; }; - const renderForm = () => { - if (isAddLabel) { - return ( - - ); - } - - if (isEditLabel) { - return ( - - ); - } - - return false; - }; - const renderCustomControls = () => { // we filter out the status labels as we dont want to display them in the label // filter select dropdown. @@ -1932,63 +1776,47 @@ const ManageHostsPage = ({ return ( <> - <> - {renderForm()} - {!isAddLabel && !isEditLabel && ( -
-
- {renderHeader()} -
- {!isSandboxMode && - canEnrollHosts && - !hasHostErrors && - !hasHostCountErrors && ( - - )} - {canEnrollHosts && - !hasHostErrors && - !hasHostCountErrors && - !( - getStatusSelected() === ALL_HOSTS_LABEL && - selectedLabel?.count === 0 - ) && - !( - getStatusSelected() === ALL_HOSTS_LABEL && - filteredHostCount === 0 - ) && ( - - )} -
-
- {renderActiveFilterBlock()} - {renderNoEnrollSecretBanner()} - {renderTable()} +
+
+ {renderHeader()} +
+ {!isSandboxMode && + canEnrollHosts && + !hasHostErrors && + !hasHostCountErrors && ( + + )} + {canEnrollHosts && + !hasHostErrors && + !hasHostCountErrors && + !( + getStatusSelected() === ALL_HOSTS_LABEL && + selectedLabel?.count === 0 + ) && + !( + getStatusSelected() === ALL_HOSTS_LABEL && + filteredHostCount === 0 + ) && ( + + )}
- )} - +
+ {renderActiveFilterBlock()} + {renderNoEnrollSecretBanner()} + {renderTable()} +
- {isAddLabel && ( - - - - )} - {canEnrollHosts && showDeleteSecretModal && renderDeleteSecretModal()} {canEnrollHosts && showSecretEditorModal && renderSecretEditorModal()} {canEnrollHosts && showEnrollSecretModal && renderEnrollSecretModal()} diff --git a/frontend/pages/hosts/ManageHostsPage/constants.ts b/frontend/pages/hosts/ManageHostsPage/constants.ts index d1354fce4..49fb6e378 100644 --- a/frontend/pages/hosts/ManageHostsPage/constants.ts +++ b/frontend/pages/hosts/ManageHostsPage/constants.ts @@ -1,5 +1,3 @@ -export const NEW_LABEL_HASH = "#new_label"; -export const EDIT_LABEL_HASH = "#edit_label"; export const ALL_HOSTS_LABEL = "all-hosts"; export const LABEL_SLUG_PREFIX = "labels/"; diff --git a/frontend/router/index.tsx b/frontend/router/index.tsx index 58495f128..67a68b594 100644 --- a/frontend/router/index.tsx +++ b/frontend/router/index.tsx @@ -24,6 +24,7 @@ import EmailTokenRedirect from "components/EmailTokenRedirect"; import ForgotPasswordPage from "pages/ForgotPasswordPage"; import HostDetailsPage from "pages/hosts/details/HostDetailsPage"; import Homepage from "pages/Homepage"; +import LabelPage from "pages/LabelPage"; import LoginPage, { LoginPreviewPage } from "pages/LoginPage"; import LogoutPage from "pages/LogoutPage"; import ManageHostsPage from "pages/hosts/ManageHostsPage"; @@ -120,6 +121,11 @@ const routes = ( + + + + + diff --git a/frontend/router/paths.ts b/frontend/router/paths.ts index c339b8bd3..ab27a3429 100644 --- a/frontend/router/paths.ts +++ b/frontend/router/paths.ts @@ -25,6 +25,9 @@ export default { PACK: (packId: number): string => { return `${URL_PREFIX}/packs/${packId}`; }, + EDIT_LABEL: (labelId: number): string => { + return `${URL_PREFIX}/labels/${labelId}`; + }, EDIT_QUERY: (query: IQuery): string => { return `${URL_PREFIX}/queries/${query.id}`; }, @@ -39,6 +42,9 @@ export default { LOGIN: `${URL_PREFIX}/login`, LOGOUT: `${URL_PREFIX}/logout`, MANAGE_HOSTS: `${URL_PREFIX}/hosts/manage`, + MANAGE_HOSTS_LABEL: (labelId: number | string): string => { + return `${URL_PREFIX}/hosts/manage/labels/${labelId}`; + }, HOST_DETAILS: (host: IHost): string => { return `${URL_PREFIX}/hosts/${host.id}`; }, @@ -63,6 +69,7 @@ export default { return `${URL_PREFIX}/schedule/manage/teams/${teamId}`; }, MANAGE_POLICIES: `${URL_PREFIX}/policies/manage`, + NEW_LABEL: `${URL_PREFIX}/labels/new`, NEW_POLICY: `${URL_PREFIX}/policies/new`, NEW_QUERY: `${URL_PREFIX}/queries/new`, RESET_PASSWORD: `${URL_PREFIX}/login/reset`, diff --git a/frontend/utilities/constants.ts b/frontend/utilities/constants.ts index 0fc1c2b87..cd47c3f1d 100644 --- a/frontend/utilities/constants.ts +++ b/frontend/utilities/constants.ts @@ -566,7 +566,3 @@ export const DEFAULT_CREATE_USER_ERRORS = { password: "", sso_enabled: null, }; - -export const DEFAULT_CREATE_LABEL_ERRORS = { - name: "", -}; diff --git a/frontend/utilities/helpers.ts b/frontend/utilities/helpers.ts index d3df030d4..c6ccd3059 100644 --- a/frontend/utilities/helpers.ts +++ b/frontend/utilities/helpers.ts @@ -59,37 +59,6 @@ const labelSlug = (label: ILabel): string => { return `labels/${id}`; }; -const labelStubs = [ - { - id: "new", - count: 0, - description: "Hosts that have been enrolled to Fleet in the last 24 hours.", - display_text: "New", - slug: "new", - statusLabelKey: "new_count", - title_description: "(added in last 24hrs)", - type: "status", - }, - { - id: "online", - count: 0, - description: "Hosts that have recently checked-in to Fleet.", - display_text: "Online", - slug: "online", - statusLabelKey: "online_count", - type: "status", - }, - { - id: "offline", - count: 0, - description: "Hosts that have not checked-in to Fleet recently.", - display_text: "Offline", - slug: "offline", - statusLabelKey: "offline_count", - type: "status", - }, -]; - const isLabel = (target: ISelectTargetsEntity) => { return "label_type" in target; }; @@ -250,7 +219,7 @@ const formatLabelResponse = (response: any): ILabel[] => { }; }); - return labels.concat(labelStubs); + return labels; }; export const formatSelectedTargetsForApi = (