Skip to content

Commit

Permalink
NNS1-3349 add neuron visibility action (#5516)
Browse files Browse the repository at this point in the history
# Motivation

Displaying visibility of Neuron under NnsNeuronAdvancedSection so
clients can see the visibility of their neruons and eventually adjust
them as needed.

# Changes

1. Add NnsNeuronPublicVisibilityAction to display visibility and button,
currently disabled.
2. Add ENABLE_NEURON_VISIBILITY flag check around
NnsNeuronPublicVisibilityAction
3. Update NnsNeuronAdvancedSection , CommonItemAction and NnsNeuronAge
styling to match with Figma


# Tests

Add tests for NnsNeuronPublicVisibilityAction
Add fullpage screenshot for neuron details modal

# Todos

- [ ] Add entry to changelog (if necessary).

---------

Signed-off-by: David Dal Busco <david.dalbusco@dfinity.org>
Co-authored-by: “Cosku <“cosku.cinkilic@dfinity.org”>
Co-authored-by: sa-github-api <138766536+sa-github-api@users.noreply.github.com>
Co-authored-by: gix-bot <gix-bot@users.noreply.github.com>
Co-authored-by: David de Kloet <122978264+dskloetd@users.noreply.github.com>
Co-authored-by: David Dal Busco <david.dalbusco@dfinity.org>
Co-authored-by: Max Strasinsky <98811342+mstrasinskis@users.noreply.github.com>
  • Loading branch information
7 people authored Oct 1, 2024
1 parent 009d8af commit bf677a9
Show file tree
Hide file tree
Showing 14 changed files with 244 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
} from "@dfinity/gix-components";
import type { NeuronInfo } from "@dfinity/nns";
import { nonNullish } from "@dfinity/utils";
import NnsNeuronPublicVisibilityAction from "./NnsNeuronPublicVisibilityAction.svelte";
import { ENABLE_NEURON_VISIBILITY } from "$lib/stores/feature-flags.store";
export let neuron: NeuronInfo;
Expand All @@ -47,6 +49,11 @@
<Section testId="nns-neuron-advanced-section-component">
<h3 slot="title">{$i18n.neuron_detail.advanced_settings_title}</h3>
<div class="content">
{#if $ENABLE_NEURON_VISIBILITY}
<div class="visibility-action-container">
<NnsNeuronPublicVisibilityAction {neuron} />
</div>
{/if}
<KeyValuePair>
<span slot="key" class="label">{$i18n.neurons.neuron_id}</span>
<span slot="value" class="value" data-tid="neuron-id"
Expand Down Expand Up @@ -107,10 +114,12 @@
</KeyValuePairInfo>
</div>
{/if}

<NnsAutoStakeMaturity {neuron} />
{#if canManageNFParticipation}
<JoinCommunityFundCheckbox {neuron} />
{/if}

{#if isControllable}
<SplitNnsNeuronButton {neuron} />
{/if}
Expand All @@ -133,4 +142,8 @@
--checkbox-padding: 0;
--checkbox-label-order: 1;
}
.visibility-action-container {
padding: var(--padding) 0;
}
</style>
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<script lang="ts">
import { i18n } from "$lib/stores/i18n";
import { isPublicNeuron } from "$lib/utils/neuron.utils";
import CommonItemAction from "../ui/CommonItemAction.svelte";
import { IconPublicBadge } from "@dfinity/gix-components";
import type { NeuronInfo } from "@dfinity/nns";
export let neuron: NeuronInfo;
let isPublic: boolean;
$: isPublic = isPublicNeuron(neuron);
</script>

<CommonItemAction testId="nns-neuron-public-visibility-action-component">
<div slot="icon" class={`public-badge-container ${!isPublic && "private"}`}>
<IconPublicBadge />
</div>

<span slot="title" data-tid="neuron-visibility-title">
{isPublic
? $i18n.neurons.public_neuron
: $i18n.neurons.private_neuron}</span
>
<svelte:fragment slot="subtitle">
<span class="description" data-tid="neuron-visibility-description">
{isPublic
? $i18n.neurons.public_neuron_description
: $i18n.neurons.private_neuron_description}
<a
data-tid="neuron-visibility-learn-more"
href="https://internetcomputer.org/docs/current/developer-docs/daos/nns/concepts/neurons/neuron-management"
target="_blank">{$i18n.neurons.learn_more}</a
>
</span>
</svelte:fragment>

<button class="secondary" data-tid="change-neuron-visibility-button" disabled
>{isPublic
? $i18n.neurons.make_neuron_private
: $i18n.neurons.make_neuron_public}</button
>
</CommonItemAction>

<style lang="scss">
.public-badge-container {
line-height: 0;
color: var(--elements-badges);
}
.private {
color: var(--elements-badges-inactive);
}
a {
color: var(--link-color);
}
button {
text-wrap: nowrap;
}
</style>
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,11 @@
/>
{#if $ENABLE_NEURON_VISIBILITY && rowData.isPublic}
<span class="public-icon-container" data-tid="public-icon-container">
<Tooltip top id="neuron-id-cell-public-icon" text={$i18n.neurons.public}>
<Tooltip
top
id="neuron-id-cell-public-icon"
text={$i18n.neurons.public_neuron_tooltip}
>
<IconPublicBadge />
</Tooltip>
</span>
Expand Down
7 changes: 7 additions & 0 deletions frontend/src/lib/components/neurons/NnsNeuronAge.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,10 @@
</KeyValuePair>
{/if}
</TestIdWrapper>

<style lang="scss">
@use "@dfinity/gix-components/dist/styles/mixins/fonts";
.label {
color: var(--description-color);
}
</style>
6 changes: 3 additions & 3 deletions frontend/src/lib/components/ui/CommonItemAction.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,14 @@
}
.icon {
width: 100%;
height: 100%;
color: var(--elements-icons);
padding: var(--padding-2x);
display: flex;
justify-content: center;
align-items: center;
border-radius: var(--border-radius);
background: var(--content-background);
background-color: var(--card-background-tint);
}
</style>
9 changes: 8 additions & 1 deletion frontend/src/lib/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,14 @@
"merge_neurons_more_info": "Learn more about merging neurons <a href=\"https://medium.com/dfinity/internet-computer-nns-neurons-can-now-be-merged-8b4e44584dc2\" rel=\"noopener noreferrer\" aria-label=\"more info about merging neurons\" target=\"_blank\">here</a>.",
"stake_amount": "Stake Amount",
"state": "State",
"public": "Neuron is public"
"public_neuron_tooltip": "Neuron is public",
"public_neuron": "Public Neuron",
"private_neuron": "Private Neuron",
"public_neuron_description": "This neuron exposes additional information, including its votes.",
"private_neuron_description": "This neuron limits information it exposes publicly.",
"learn_more": "Learn more.",
"make_neuron_private": "Make Neuron Private",
"make_neuron_public": "Make Neuron Public"
},
"new_followee": {
"title": "Enter New Followee",
Expand Down
9 changes: 8 additions & 1 deletion frontend/src/lib/types/i18n.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,14 @@ interface I18nNeurons {
merge_neurons_more_info: string;
stake_amount: string;
state: string;
public: string;
public_neuron_tooltip: string;
public_neuron: string;
private_neuron: string;
public_neuron_description: string;
private_neuron_description: string;
learn_more: string;
make_neuron_private: string;
make_neuron_public: string;
}

interface I18nNew_followee {
Expand Down
9 changes: 8 additions & 1 deletion frontend/src/tests/e2e/neuron-details.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { PlaywrightPageObjectElement } from "$tests/page-objects/playwright.page
import { getNnsNeuronCardsIds } from "$tests/utils/e2e.nns-neuron.test-utils";
import {
replaceContent,
setFeatureFlag,
signInWithNewUser,
step,
} from "$tests/utils/e2e.test-utils";
Expand Down Expand Up @@ -36,12 +37,18 @@ test("Test neuron details", async ({ page, context }) => {

step("Make screenshots");

await setFeatureFlag({
page,
featureFlag: "ENABLE_NEURON_VISIBILITY",
value: true,
});

// Replace neuron details with fixed values
await replaceContent({
page,
selectors: ['[data-tid="identifier"]', '[data-tid="neuron-id"]'],
pattern: /[0-9a-f]{19}/,
replacements: ["7737260276268288098"],
replacements: ["7737260276268288098", "7737260276268288098"],
});
await replaceContent({
page,
Expand Down
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.
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.
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import NnsNeuronPublicVisibilityAction from "$lib/components/neuron-detail/NnsNeuronPublicVisibilityAction.svelte";
import { mockNeuron } from "$tests/mocks/neurons.mock";
import { NnsNeuronPublicVisibilityActionPo } from "$tests/page-objects/NnsNeuronPublicVisibilityAction.page-object";
import { JestPageObjectElement } from "$tests/page-objects/jest.page-object";
import { NeuronVisibility, type NeuronInfo } from "@dfinity/nns";
import { render } from "@testing-library/svelte";

describe("NnsNeuronPublicVisibilityAction", () => {
const renderComponent = async (neuron) => {
const { container } = render(NnsNeuronPublicVisibilityAction, {
props: { neuron },
});
return NnsNeuronPublicVisibilityActionPo.under(
new JestPageObjectElement(container)
);
};

it("should render elements and text for public neuron", async () => {
const mockNeuronPublic: NeuronInfo = {
...mockNeuron,
visibility: NeuronVisibility.Public,
};
const po = await renderComponent(mockNeuronPublic);

expect(await po.getTitleText()).toBe("Public Neuron");
expect(await po.getSubtitleText()).toBe(
"This neuron exposes additional information, including its votes. Learn more."
);
expect(await po.getSubtitleLinkPo().getText()).toBe("Learn more.");
expect(await po.getSubtitleLinkPo().getHref()).toBe(
"https://internetcomputer.org/docs/current/developer-docs/daos/nns/concepts/neurons/neuron-management"
);
expect(await po.getButtonPo().getText()).toBe("Make Neuron Private");
expect(await po.getButtonPo().isDisabled()).toBe(true);
});

it("should render elements and text for private neuron", async () => {
const mockNeuronPrivate: NeuronInfo = {
...mockNeuron,
visibility: NeuronVisibility.Private,
};
const po = await renderComponent(mockNeuronPrivate);

expect(await po.getTitleText()).toBe("Private Neuron");
expect(await po.getSubtitleText()).toBe(
"This neuron limits information it exposes publicly. Learn more."
);
expect(await po.getSubtitleLinkPo().getText()).toBe("Learn more.");
expect(await po.getSubtitleLinkPo().getHref()).toBe(
"https://internetcomputer.org/docs/current/developer-docs/daos/nns/concepts/neurons/neuron-management"
);
expect(await po.getButtonPo().getText()).toBe("Make Neuron Public");
expect(await po.getButtonPo().isDisabled()).toBe(true);
});

it("should render elements and text for unspecified neuron", async () => {
const mockNeuronUnspecified: NeuronInfo = {
...mockNeuron,
visibility: NeuronVisibility.Unspecified,
};
const po = await renderComponent(mockNeuronUnspecified);

expect(await po.getTitleText()).toBe("Private Neuron");
expect(await po.getSubtitleText()).toBe(
"This neuron limits information it exposes publicly. Learn more."
);

expect(await po.getSubtitleLinkPo().getText()).toBe("Learn more.");
expect(await po.getSubtitleLinkPo().getHref()).toBe(
"https://internetcomputer.org/docs/current/developer-docs/daos/nns/concepts/neurons/neuron-management"
);
expect(await po.getButtonPo().getText()).toBe("Make Neuron Public");
expect(await po.getButtonPo().isDisabled()).toBe(true);
});

it("should render elements and text for neuron with no visibility", async () => {
const mockNeuronVisibilityUndefined: NeuronInfo = {
...mockNeuron,
visibility: undefined,
};
const po = await renderComponent(mockNeuronVisibilityUndefined);

expect(await po.getTitleText()).toBe("Private Neuron");
expect(await po.getSubtitleText()).toBe(
"This neuron limits information it exposes publicly. Learn more."
);
expect(await po.getSubtitleLinkPo().getText()).toBe("Learn more.");
expect(await po.getSubtitleLinkPo().getHref()).toBe(
"https://internetcomputer.org/docs/current/developer-docs/daos/nns/concepts/neurons/neuron-management"
);
expect(await po.getButtonPo().getText()).toBe("Make Neuron Public");
expect(await po.getButtonPo().isDisabled()).toBe(true);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { TooltipIconPo } from "$tests/page-objects/TooltipIcon.page-object";
import { BasePageObject } from "$tests/page-objects/base.page-object";
import type { PageObjectElement } from "$tests/types/page-object.types";
import { ButtonPo } from "./Button.page-object";
import { LinkPo } from "./Link.page-object";

export class NnsNeuronPublicVisibilityActionPo extends BasePageObject {
private static readonly TID = "nns-neuron-public-visibility-action-component";

static under(element: PageObjectElement): NnsNeuronPublicVisibilityActionPo {
return new NnsNeuronPublicVisibilityActionPo(
element.byTestId("nns-neuron-public-visibility-action-component")
);
}

getTooltipIconPo(): TooltipIconPo {
return TooltipIconPo.under(this.root);
}

getTitleText(): Promise<string> {
return this.getText("neuron-visibility-title");
}

getSubtitleText(): Promise<string> {
return this.getText("neuron-visibility-description");
}

getSubtitleLinkPo(): LinkPo {
return LinkPo.under({
element: this.root,
testId: "neuron-visibility-learn-more",
});
}

getButtonPo(): ButtonPo {
return this.getButton("change-neuron-visibility-button");
}
}

0 comments on commit bf677a9

Please sign in to comment.