diff --git a/src/app/tags/components/TagsHeader/TagsHeader.test.tsx b/src/app/tags/components/TagsHeader/TagsHeader.test.tsx index be622a2ba7..2646bca9c5 100644 --- a/src/app/tags/components/TagsHeader/TagsHeader.test.tsx +++ b/src/app/tags/components/TagsHeader/TagsHeader.test.tsx @@ -31,6 +31,7 @@ it("displays the searchbox and group select when isDetails is false", () => { filter={TagSearchFilter.All} isDetails={false} onDelete={vi.fn()} + onUpdate={vi.fn()} searchText="" setFilter={vi.fn()} setSearchText={vi.fn()} @@ -73,6 +74,7 @@ it("displays edit and delete buttons, and a return link when isDetails is true", filter={TagSearchFilter.All} isDetails={true} onDelete={vi.fn()} + onUpdate={vi.fn()} searchText="" setFilter={vi.fn()} setSearchText={vi.fn()} @@ -100,7 +102,7 @@ it("displays edit and delete buttons, and a return link when isDetails is true", screen.getByRole("button", { name: Label.DeleteButton }) ).toBeInTheDocument(); expect( - screen.getByRole("link", { name: Label.EditButton }) + screen.getByRole("button", { name: Label.EditButton }) ).toBeInTheDocument(); }); @@ -111,6 +113,7 @@ it("can call a function to display the add tag form", async () => { filter={TagSearchFilter.All} isDetails={false} onDelete={vi.fn()} + onUpdate={vi.fn()} searchText="" setFilter={vi.fn()} setSearchText={vi.fn()} @@ -134,6 +137,7 @@ it("displays the default title", () => { filter={TagSearchFilter.All} isDetails={false} onDelete={vi.fn()} + onUpdate={vi.fn()} searchText="" setFilter={vi.fn()} setSearchText={vi.fn()} @@ -157,6 +161,7 @@ it("can update the filter", async () => { filter={TagSearchFilter.All} isDetails={false} onDelete={vi.fn()} + onUpdate={vi.fn()} searchText="" setFilter={setFilter} setSearchText={vi.fn()} @@ -172,7 +177,8 @@ it("can update the filter", async () => { expect(setFilter).toHaveBeenCalledWith(TagSearchFilter.Manual); }); -it("can go to the tag edit page", async () => { +it("triggers onUpdate with the correct tag ID", async () => { + const onUpdate = vi.fn(); const tag = tagFactory({ id: 1 }); const state = rootStateFactory({ tag: tagStateFactory({ @@ -189,6 +195,7 @@ it("can go to the tag edit page", async () => { filter={TagSearchFilter.All} isDetails={true} onDelete={vi.fn()} + onUpdate={onUpdate} searchText="" setFilter={vi.fn()} setSearchText={vi.fn()} @@ -200,6 +207,6 @@ it("can go to the tag edit page", async () => { , { route: urls.tags.tag.index({ id: 1 }), state } ); - await userEvent.click(screen.getByRole("link", { name: "Edit" })); - expect(window.location.pathname).toBe(urls.tags.tag.update({ id: 1 })); + await userEvent.click(screen.getByRole("button", { name: "Edit" })); + expect(onUpdate).toBeCalledWith(1); }); diff --git a/src/app/tags/components/TagsHeader/TagsHeader.tsx b/src/app/tags/components/TagsHeader/TagsHeader.tsx index 58ffa7dfe4..3ea322d991 100644 --- a/src/app/tags/components/TagsHeader/TagsHeader.tsx +++ b/src/app/tags/components/TagsHeader/TagsHeader.tsx @@ -13,7 +13,6 @@ import tagSelectors, { TagSearchFilter } from "@/app/store/tag/selectors"; import type { Tag } from "@/app/store/tag/types"; import { TagMeta } from "@/app/store/tag/types"; import { TagSidePanelViews } from "@/app/tags/constants"; -import { TagViewState } from "@/app/tags/types"; export type Props = { filter: TagSearchFilter; @@ -22,8 +21,8 @@ export type Props = { setSearchText: (searchText: string) => void; isDetails: boolean; setSidePanelContent: SetSidePanelContent; - tagViewState?: TagViewState | null; onDelete: (id: Tag[TagMeta.PK], fromDetails?: boolean) => void; + onUpdate: (id: Tag[TagMeta.PK]) => void; }; export enum Label { @@ -43,11 +42,9 @@ export const TagsHeader = ({ setSearchText, isDetails, setSidePanelContent, - tagViewState, onDelete, + onUpdate, }: Props): JSX.Element => { - // Don't show the buttons when any of the forms are visible. - const showButtons = !tagViewState; const id = useGetURLId(TagMeta.PK); const tag = useSelector((state: RootState) => tagSelectors.getById(state, id) @@ -62,71 +59,56 @@ export const TagsHeader = ({ ) : null} - {tagViewState === TagViewState.Updating ? null : ( + {isDetails && tag ? ( <> - {isDetails && tag ? ( - <> - {showButtons ? ( - <> - - - - ) : null} - - ) : ( - <> - - - - )} + + ) : ( + <> + + + )} + ); diff --git a/src/app/tags/types.ts b/src/app/tags/types.ts index 1b8668d5ec..c834cbc5e7 100644 --- a/src/app/tags/types.ts +++ b/src/app/tags/types.ts @@ -14,9 +14,3 @@ export type TagSidePanelContent = | SidePanelContent; export type TagSetSidePanelContent = SetSidePanelContent; - -export enum TagViewState { - Creating = "creating", - Deleting = "deleting", - Updating = "updating", -} diff --git a/src/app/tags/urls.ts b/src/app/tags/urls.ts index f14039c09f..4df3c615f7 100644 --- a/src/app/tags/urls.ts +++ b/src/app/tags/urls.ts @@ -8,7 +8,6 @@ const urls = { tag: { index: withId("/tag/:id"), machines: withId("/tag/:id/machines"), - update: withId("/tag/:id/edit"), }, } as const; diff --git a/src/app/tags/views/Tags.test.tsx b/src/app/tags/views/Tags.test.tsx index d972aee70d..27f399c9ca 100644 --- a/src/app/tags/views/Tags.test.tsx +++ b/src/app/tags/views/Tags.test.tsx @@ -78,7 +78,7 @@ describe("Tags", () => { }) ).toBeInTheDocument(); expect( - screen.getByRole("link", { name: TagDetailsLabel.EditButton }) + screen.getByRole("button", { name: TagDetailsLabel.EditButton }) ).toBeInTheDocument(); }); }); diff --git a/src/app/tags/views/Tags.tsx b/src/app/tags/views/Tags.tsx index dd689e0c66..2acae25098 100644 --- a/src/app/tags/views/Tags.tsx +++ b/src/app/tags/views/Tags.tsx @@ -1,18 +1,11 @@ import { useState } from "react"; import { useSelector } from "react-redux"; -import { - matchPath, - Route, - Routes, - useLocation, - useMatch, -} from "react-router-dom-v5-compat"; +import { Route, Routes, useMatch } from "react-router-dom-v5-compat"; import TagsHeader from "../components/TagsHeader"; import TagForms from "../components/TagsHeader/TagForms"; import { TagSidePanelViews } from "../constants"; -import { TagViewState } from "../types"; import TagDetails from "./TagDetails"; import TagList from "./TagList"; @@ -20,7 +13,6 @@ import TagMachines from "./TagMachines"; import PageContent from "@/app/base/components/PageContent"; import { useId } from "@/app/base/hooks/base"; -import type { SidePanelContent } from "@/app/base/side-panel-context"; import { useSidePanel } from "@/app/base/side-panel-context"; import urls from "@/app/base/urls"; import NotFound from "@/app/base/views/NotFound"; @@ -30,35 +22,10 @@ import type { Tag, TagMeta } from "@/app/store/tag/types"; import { getSidePanelTitle } from "@/app/store/utils/node/base"; import { getRelativeRoute } from "@/app/utils"; -const getViewState = ( - sidePanelContent: SidePanelContent | null, - pathname: string -) => { - if (sidePanelContent?.view === TagSidePanelViews.DeleteTag) { - return TagViewState.Deleting; - } - if (sidePanelContent?.view === TagSidePanelViews.AddTag) { - return TagViewState.Creating; - } - const isUpdating = matchPath( - { - path: urls.tags.tag.update(null), - end: true, - }, - pathname - ); - if (isUpdating) { - return TagViewState.Updating; - } - return null; -}; - const Tags = (): JSX.Element => { - const { pathname } = useLocation(); const detailsMatch = useMatch(urls.tags.tag.index(null)); const isDetails = !!detailsMatch; const { sidePanelContent, setSidePanelContent } = useSidePanel(); - const tagViewState = getViewState(sidePanelContent, pathname); const onDelete = (id: Tag[TagMeta.PK], fromDetails?: boolean) => setSidePanelContent({ view: TagSidePanelViews.DeleteTag, @@ -87,11 +54,11 @@ const Tags = (): JSX.Element => { filter={filter} isDetails={isDetails} onDelete={onDelete} + onUpdate={onUpdate} searchText={searchText} setFilter={setFilter} setSearchText={setSearchText} setSidePanelContent={setSidePanelContent} - tagViewState={tagViewState} /> } sidePanelContent={