Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/whole-colts-thank.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"landscape-ui": minor

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd tag is a patch because it's rather a UX fix, not a new feature - minor inconsistency with how #644 (a similar "show a message when empty" change) was tagged patch.

---

Add a message for when scripts search returns no results.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,4 @@ src/**/*.module.scss.d.ts
/playwright-report/
/playwright/
.cert
.prettierrc.json

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why are we doing this?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I noticed we didn't have a default prettier configuration, so I didn't want to accidentally commit mine to git.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't have it because we're using its defaults, but it doesn't mean we should add this config to gitignore, because we have a prettier job in the pipeline. You can just not commit yours in this PR, but I wouldn't add it to gitignore.

15 changes: 15 additions & 0 deletions src/features/scripts/components/ScriptList/ScriptList.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ const authContextValuesWithoutFeatureFlag: AuthContextProps = {

describe("ScriptList", () => {
const user = userEvent.setup();

beforeEach(() => {
vi.mocked(useAuth).mockReturnValue(authContextValues);
});

assert(activeScript);
assert(inactiveScript);

Expand Down Expand Up @@ -109,4 +114,14 @@ describe("ScriptList", () => {
expect(inactiveStatusCell).toBeInTheDocument();
expect(inactiveStatusCell).toHaveIcon("status-queued-small");
});

it("should show the search-specific empty message for an empty list", () => {
vi.mocked(useAuth).mockReturnValue(authContextValues);

renderWithProviders(<ScriptList scripts={[]} />);

expect(
screen.getByText("No scripts found according to your search parameters."),
).toBeInTheDocument();
});
});
30 changes: 20 additions & 10 deletions src/features/scripts/components/ScriptList/ScriptList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import type { SelectOption } from "@/types/SelectOption";
import { Button } from "@canonical/react-components";
import moment from "moment";
import type { FC, ReactElement } from "react";
import { lazy, Suspense, useMemo } from "react";
import { lazy, Suspense, useCallback, useMemo } from "react";
import type { CellProps, Column } from "react-table";
import { formatTitleCase } from "../../helpers";
import { useOpenScriptDetails } from "../../hooks";
Expand All @@ -37,14 +37,17 @@ const ScriptList: FC<ScriptListProps> = ({ scripts }) => {
const { expandedRowIndex, getTableRowsRef, handleExpand } =
useExpandableRow();

const openViewPanel = (script: Script) => {
setSidePanelContent(
script.title,
<Suspense fallback={<LoadingState />}>
<ScriptDetails scriptId={script.id} />
</Suspense>,
);
};
const openViewPanel = useCallback(
(script: Script) => {
setSidePanelContent(
script.title,
<Suspense fallback={<LoadingState />}>
<ScriptDetails scriptId={script.id} />
</Suspense>,
);
},
[setSidePanelContent],
);

useOpenScriptDetails((profile) => {
openViewPanel(profile);
Expand Down Expand Up @@ -177,10 +180,17 @@ const ScriptList: FC<ScriptListProps> = ({ scripts }) => {
return isFeatureEnabled("script-profiles")
? result
: result.filter((column) => column.id !== "associated_profiles");
}, [scripts, accessGroupOptions, expandedRowIndex]);
}, [
accessGroupOptions,
expandedRowIndex,
handleExpand,
isFeatureEnabled,
openViewPanel,
]);

return (
<ResponsiveTable
emptyMsg="No scripts found according to your search parameters."
ref={getTableRowsRef}
columns={columns}
Comment thread
gesquivelgaghi marked this conversation as resolved.
data={scripts}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,14 @@ import { expectLoadingState } from "@/tests/helpers";
import { scripts } from "@/tests/mocks/script";
import { renderWithProviders } from "@/tests/render";
import { screen } from "@testing-library/react";
import { describe, expect, it } from "vitest";
import { beforeEach, describe, expect, it } from "vitest";
import ScriptsContainer from "./ScriptsContainer";

describe("Scripts Empty State", () => {
beforeEach(() => {
setEndpointStatus("default");
});

it("should empty state when there are no scripts", async () => {
setEndpointStatus("empty");

Expand All @@ -19,8 +23,6 @@ describe("Scripts Empty State", () => {
});

it("should show scripts when there are scripts", async () => {
setEndpointStatus("default");

renderWithProviders(<ScriptsContainer />);

await expectLoadingState();
Expand All @@ -31,17 +33,39 @@ describe("Scripts Empty State", () => {

it("should show scripts when there are scripts with search", async () => {
const searchText = scripts[0].title;
const encodedSearchText = encodeURIComponent(searchText);

renderWithProviders(
<ScriptsContainer />,
undefined,
`/scripts?search=${searchText}`,
`/scripts?search=${encodedSearchText}`,
);
Comment thread
RyanLoi98 marked this conversation as resolved.

await expectLoadingState();

expect(screen.getByText(searchText)).toBeInTheDocument();

scripts
.filter(({ title }) => !title.includes(searchText))
.forEach((script) => {
expect(screen.queryByText(script.title)).not.toBeInTheDocument();
});
});

it("should show search-specific empty message when there are no search results", async () => {
setEndpointStatus("empty");

renderWithProviders(
<ScriptsContainer />,
undefined,
"/scripts?search=non-existent-script",
);

await expectLoadingState();

const emptyStateTitle = screen.getByText(
"No scripts found according to your search parameters.",
);
expect(emptyStateTitle).toBeInTheDocument();
});
});
Loading