Skip to content

Commit

Permalink
Move canister button from sidebar to profile popover (#5435)
Browse files Browse the repository at this point in the history
# Motivation
 move canister to less accessible and visible location.

# Changes

- [X] Canisters button is removed from the sidebar
- [X] Canisters button added to profile popover
- [X] clickCanisters function is moved AccountMenu

<img width="1727" alt="Screenshot 2024-09-11 at 15 23 17"
src="https://github.com/user-attachments/assets/81ec8932-c81e-4743-9ca2-3d46d653000c">


# Tests
Tests are updated to use the clickCanisters from AccountMenuPo


# Todos
- [x]  Add entry to changelog (if necessary).
Need opinions to learn what we add to changlog and what we don't

---------

Co-authored-by: “Cosku <“[email protected]”>
  • Loading branch information
coskucinkilic and “Cosku authored Sep 12, 2024
1 parent 40dff2f commit 016b7d9
Show file tree
Hide file tree
Showing 12 changed files with 91 additions and 28 deletions.
1 change: 1 addition & 0 deletions CHANGELOG-Nns-Dapp-unreleased.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ proposal is successful, the changes it released will be moved from this file to
#### Changed

* Changes for cleaning up the stable structure migration.
* Move Canisters button from sidebar to account menu.

#### Deprecated

Expand Down
15 changes: 1 addition & 14 deletions frontend/src/lib/components/common/MenuItems.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import { authSignedInStore } from "$lib/derived/auth.derived";
import { pageStore } from "$lib/derived/page.derived";
import {
canistersPathStore,
neuronsPathStore,
proposalsPathStore,
} from "$lib/derived/paths.derived";
Expand All @@ -19,7 +18,6 @@
isSelectedPath,
} from "$lib/utils/navigation.utils";
import {
IconExplore,
IconNeurons,
IconRocketLaunch,
IconVote,
Expand All @@ -37,8 +35,7 @@
| typeof IconWallet
| typeof IconNeurons
| typeof IconVote
| typeof IconRocketLaunch
| typeof IconExplore;
| typeof IconRocketLaunch;
statusIcon?: ComponentType;
}[];
$: routes = [
Expand Down Expand Up @@ -86,16 +83,6 @@
title: $i18n.navigation.launchpad,
icon: IconRocketLaunch,
},
{
context: "canisters",
href: $canistersPathStore,
selected: isSelectedPath({
currentPath: $pageStore.path,
paths: [AppPath.Canisters, AppPath.Canister],
}),
title: $i18n.navigation.canisters,
icon: IconExplore,
},
];
</script>

Expand Down
3 changes: 3 additions & 0 deletions frontend/src/lib/components/header/AccountMenu.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import { authSignedInStore } from "$lib/derived/auth.derived";
import { i18n } from "$lib/stores/i18n";
import AccountDetails from "./AccountDetails.svelte";
import LinkToCanisters from "./LinkToCanisters.svelte";
import LoginIconOnly from "./LoginIconOnly.svelte";
import Logout from "./Logout.svelte";
import { IconUser, ThemeToggle, Popover } from "@dfinity/gix-components";
Expand Down Expand Up @@ -40,6 +41,8 @@

<SettingsButton on:nnsLink={() => (visible = false)} />

<LinkToCanisters />

<Logout on:nnsLogoutTriggered={toggle} />
</div>
</Popover>
Expand Down
23 changes: 23 additions & 0 deletions frontend/src/lib/components/header/LinkToCanisters.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<script lang="ts">
import { i18n } from "$lib/stores/i18n";
import { IconExplore } from "@dfinity/gix-components";
import { canistersPathStore } from "$lib/derived/paths.derived";
</script>

<a data-tid="canisters-button" href={$canistersPathStore} class="text">
<IconExplore />
{$i18n.navigation.canisters}
</a>

<style lang="scss">
@use "../../themes/mixins/account-menu";
a {
@include account-menu.button;
text-decoration: none;
&:hover {
text-decoration: underline;
}
}
</style>
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 0 additions & 3 deletions frontend/src/tests/lib/components/common/MenuItems.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,6 @@ describe("MenuItems", () => {
it("should render voting menu item", () =>
shouldRenderMenuItem({ context: "proposals", labelKey: "voting" }));

it("should render canisters menu item", () =>
shouldRenderMenuItem({ context: "canisters", labelKey: "canisters" }));

it("should not render a get icps feature", async () => {
const renderResult = render(MenuItems);

Expand Down
21 changes: 17 additions & 4 deletions frontend/src/tests/lib/components/header/AccountMenu.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ describe("AccountMenu", () => {
await waitFor(() => expect(getByRole("menu")).not.toBeNull());
};

const renderComponent = () => {
const { container } = render(AccountMenu);
return AccountMenuPo.under(new JestPageObjectElement(container));
};

it("should be closed by default", () => {
const { getByRole } = render(AccountMenu);
expect(() => getByRole("menu")).toThrow();
Expand Down Expand Up @@ -41,38 +46,46 @@ describe("AccountMenu", () => {
expect(renderResult.getByTestId("theme-toggle")).not.toBeNull();
});

it("should display logout button if signed in", async () => {
it("should display logout button", async () => {
const renderResult = render(AccountMenu);

await show(renderResult);

expect(renderResult.getByTestId("logout")).not.toBeNull();
});

it("should display settings button if signed in", async () => {
it("should display settings button", async () => {
const renderResult = render(AccountMenu);

await show(renderResult);

expect(renderResult.getByTestId("settings")).not.toBeNull();
});

it('should display "Manage ii" button if signed in', async () => {
it('should display "Manage ii" button', async () => {
const renderResult = render(AccountMenu);

await show(renderResult);

expect(renderResult.getByTestId("manage-ii-link")).not.toBeNull();
});

it('should display "Source code" button if signed in', async () => {
it('should display "Source code" button', async () => {
const renderResult = render(AccountMenu);

await show(renderResult);

expect(renderResult.getByTestId("source-code-link")).not.toBeNull();
});

it('should display "Canisters" button', async () => {
const AccountMenuPo = renderComponent();

await AccountMenuPo.openMenu();

expect(await AccountMenuPo.getCanistersLinkPo().isPresent()).toBe(true);
});

it("should close popover on click on settings", async () => {
const renderResult = render(AccountMenu);

Expand Down
12 changes: 12 additions & 0 deletions frontend/src/tests/page-objects/AccountMenu.page-object.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { BasePageObject } from "$tests/page-objects/base.page-object";
import type { PageObjectElement } from "$tests/types/page-object.types";
import { AccountDetailsPo } from "./AccountDetails.page-object";
import { LinkPo } from "./Link.page-object";

export class AccountMenuPo extends BasePageObject {
private static readonly TID = "account-menu-component";
Expand All @@ -17,6 +18,17 @@ export class AccountMenuPo extends BasePageObject {
return this.click("logout");
}

getCanistersLinkPo(): LinkPo {
return LinkPo.under({
element: this.root,
testId: "canisters-button",
});
}

clickCanisters(): Promise<void> {
return this.getCanistersLinkPo().click();
}

getAccountDetailsPo(): AccountDetailsPo {
return AccountDetailsPo.under(this.root);
}
Expand Down
5 changes: 2 additions & 3 deletions frontend/src/tests/page-objects/App.page-object.ts
Original file line number Diff line number Diff line change
Expand Up @@ -196,9 +196,8 @@ export class AppPo extends BasePageObject {
}

async goToCanisters(): Promise<void> {
await this.goBackAllTheWay();
await this.openMenu();
await this.getMenuItemsPo().clickCanisters();
await this.getAccountMenuPo().openMenu();
await this.getAccountMenuPo().clickCanisters();
// Menu closes automatically.
await this.getBackdropPo().waitForAbsent();
}
Expand Down
32 changes: 32 additions & 0 deletions frontend/src/tests/page-objects/Link.page-object.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { BasePageObject } from "$tests/page-objects/base.page-object";
import type { PageObjectElement } from "$tests/types/page-object.types";
import { isNullish } from "@dfinity/utils";

export class LinkPo extends BasePageObject {
private static readonly DEFAULT_TID = "link-component";

static under({
element,
testId,
}: {
element: PageObjectElement;
testId?: string;
}): LinkPo {
if (isNullish(testId)) {
return new LinkPo(element.byTestId(LinkPo.DEFAULT_TID));
}
return new LinkPo(element.byTestId(testId));
}

getHref(): Promise<string> {
return this.root.getAttribute("href");
}

async click(): Promise<void> {
return this.root.click();
}

async getAttribute(attributeName: string): Promise<string> {
return this.root.getAttribute(attributeName);
}
}
4 changes: 0 additions & 4 deletions frontend/src/tests/page-objects/MenuItems.page-object.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,6 @@ export class MenuItemsPo extends BasePageObject {
return this.click("menuitem-launchpad");
}

clickCanisters(): Promise<void> {
return this.click("menuitem-canisters");
}

getGetTokensPo(): GetTokensPo {
return GetTokensPo.under(this.root);
}
Expand Down

0 comments on commit 016b7d9

Please sign in to comment.