Skip to content

Commit

Permalink
fix: tags header update action (#5312)
Browse files Browse the repository at this point in the history
  • Loading branch information
petermakowski committed Feb 7, 2024
1 parent 7951e56 commit 5fbd6be
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 111 deletions.
15 changes: 11 additions & 4 deletions src/app/tags/components/TagsHeader/TagsHeader.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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()}
Expand Down Expand Up @@ -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()}
Expand Down Expand Up @@ -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();
});

Expand All @@ -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()}
Expand All @@ -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()}
Expand All @@ -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()}
Expand All @@ -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({
Expand All @@ -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()}
Expand All @@ -200,6 +207,6 @@ it("can go to the tag edit page", async () => {
</Routes>,
{ 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);
});
110 changes: 46 additions & 64 deletions src/app/tags/components/TagsHeader/TagsHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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 {
Expand All @@ -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)
Expand All @@ -62,71 +59,56 @@ export const TagsHeader = ({
</Link>
) : null}
<MainToolbar.Controls>
{tagViewState === TagViewState.Updating ? null : (
{isDetails && tag ? (
<>
{isDetails && tag ? (
<>
{showButtons ? (
<>
<Button
element={Link}
hasIcon
state={{ canGoBack: true }}
to={{
pathname: urls.tags.tag.update({ id: tag.id }),
}}
>
<Icon name="edit" /> <span>{Label.EditButton}</span>
</Button>
<Button
appearance="negative"
hasIcon
onClick={() => onDelete(tag[TagMeta.PK], true)}
>
<Icon className="is-light" name="delete" />{" "}
<span>{Label.DeleteButton}</span>
</Button>
</>
) : null}
</>
) : (
<>
<SearchBox
externallyControlled
onChange={setSearchText}
value={searchText}
/>
<SegmentedControl
aria-label="tag filter"
onSelect={setFilter}
options={[
{
label: Label.All,
value: TagSearchFilter.All,
},
{
label: Label.Manual,
value: TagSearchFilter.Manual,
},
{
label: Label.Auto,
value: TagSearchFilter.Auto,
},
]}
selected={filter}
/>
</>
)}
<Button hasIcon onClick={() => onUpdate(tag[TagMeta.PK])}>
<Icon name="edit" /> <span>{Label.EditButton}</span>
</Button>
<Button
appearance="positive"
onClick={() =>
setSidePanelContent({ view: TagSidePanelViews.AddTag })
}
appearance="negative"
hasIcon
onClick={() => onDelete(tag[TagMeta.PK], true)}
>
{Label.CreateButton}
<Icon className="is-light" name="delete" />{" "}
<span>{Label.DeleteButton}</span>
</Button>
</>
) : (
<>
<SearchBox
externallyControlled
onChange={setSearchText}
value={searchText}
/>
<SegmentedControl
aria-label="tag filter"
onSelect={setFilter}
options={[
{
label: Label.All,
value: TagSearchFilter.All,
},
{
label: Label.Manual,
value: TagSearchFilter.Manual,
},
{
label: Label.Auto,
value: TagSearchFilter.Auto,
},
]}
selected={filter}
/>
</>
)}
<Button
appearance="positive"
onClick={() =>
setSidePanelContent({ view: TagSidePanelViews.AddTag })
}
>
{Label.CreateButton}
</Button>
</MainToolbar.Controls>
</MainToolbar>
);
Expand Down
6 changes: 0 additions & 6 deletions src/app/tags/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,3 @@ export type TagSidePanelContent =
| SidePanelContent<HeaderViews["UpdateTag"], { id: Tag[TagMeta.PK] }>;

export type TagSetSidePanelContent = SetSidePanelContent<TagSidePanelContent>;

export enum TagViewState {
Creating = "creating",
Deleting = "deleting",
Updating = "updating",
}
1 change: 0 additions & 1 deletion src/app/tags/urls.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ const urls = {
tag: {
index: withId("/tag/:id"),
machines: withId("/tag/:id/machines"),
update: withId("/tag/:id/edit"),
},
} as const;

Expand Down
2 changes: 1 addition & 1 deletion src/app/tags/views/Tags.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ describe("Tags", () => {
})
).toBeInTheDocument();
expect(
screen.getByRole("link", { name: TagDetailsLabel.EditButton })
screen.getByRole("button", { name: TagDetailsLabel.EditButton })
).toBeInTheDocument();
});
});
37 changes: 2 additions & 35 deletions src/app/tags/views/Tags.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,18 @@
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";
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";
Expand All @@ -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,
Expand Down Expand Up @@ -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={
Expand Down

0 comments on commit 5fbd6be

Please sign in to comment.