Skip to content

Commit

Permalink
Proposal neurons redesign (#4120)
Browse files Browse the repository at this point in the history
# Motivation

Redesign proposal detail neurons block (split in 3 groups and render in
collapsibles).
[design](https://www.figma.com/file/29OdZHbNaOk9RkrfESucjb/NNS-1.03-WIP?node-id=5091%3A8121&mode=dev)

# Changes

- update MyVotes container and it's children to render in collapsibles.
- labels updated.
- render user votes with color.
- refactor: VotingCard to be shared between nns and sns versions.

# Tests

- Updated current tests to the new DOM changes.
- groups visibility tests when no (votable, voted, ineligible)neurons.
- voted neurons in color.
- refactor to cleanup a bit the structure:
```
  NnsVotingCard|NnsVotingCard
    VotingCard
      VotableNeuronList
      VotedNeuronList
      IneligibleNeuronList
```
# Todos

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

# Screenshots

<img width="1038" alt="Screenshot 2024-01-03 at 09 43 01"
src="https://github.com/dfinity/nns-dapp/assets/98811342/26fd04b3-452f-403e-9fad-15b9ed0b0954">

<img width="381" alt="image"
src="https://github.com/dfinity/nns-dapp/assets/98811342/e434c885-9df3-466f-b094-89970abf6a05">

<img width="494" alt="image"
src="https://github.com/dfinity/nns-dapp/assets/98811342/5f5ad3c0-d101-4e6a-81da-02cdf9a22d6c">
  • Loading branch information
mstrasinskis authored Jan 5, 2024
1 parent 2b526ef commit db449b9
Show file tree
Hide file tree
Showing 28 changed files with 838 additions and 569 deletions.
1 change: 1 addition & 0 deletions CHANGELOG-Nns-Dapp-unreleased.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ proposal is successful, the changes it released will be moved from this file to
- Migration functions.
- Render pending and failed BTC withdrawal transaction as such.
- Add `ENABLE_SNS_TYPES_FILTER` feature flag.
- Redesign proposal detail neurons block (collapsible).

#### Changed

Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
<script lang="ts">
import { i18n } from "$lib/stores/i18n";
import ProposalContentCell from "./ProposalContentCell.svelte";
import type { IneligibleNeuronData } from "$lib/utils/neuron.utils";
import { shortenWithMiddleEllipsis } from "$lib/utils/format.utils";
import { SNS_NEURON_ID_DISPLAY_LENGTH } from "$lib/constants/sns-neurons.constants";
import { replacePlaceholders } from "$lib/utils/i18n.utils";
import { secondsToDissolveDelayDuration } from "$lib/utils/date.utils";
import type { NeuronIneligibilityReason } from "$lib/utils/neuron.utils";
import { nonNullish } from "@dfinity/utils";
import VotingCardNeuronList from "$lib/components/proposal-detail/VotingCard/VotingCardNeuronList.svelte";
export let ineligibleNeurons: IneligibleNeuronData[] = [];
export let minSnsDissolveDelaySeconds: bigint;
Expand Down Expand Up @@ -38,41 +38,43 @@
</script>

{#if visible}
<ProposalContentCell>
<h4 slot="start">{$i18n.proposal_detail__ineligible.headline}</h4>
<p class="description">
{replacePlaceholders($i18n.proposal_detail__ineligible.text, {
$minDissolveDelay: secondsToDissolveDelayDuration(
minSnsDissolveDelaySeconds
),
})}
</p>
<ul>
{#each ineligibleNeurons as neuron}
<li class="value" title={neuron.neuronIdString}>
<p class="description" data-tid="ineligible-neurons-description">
{replacePlaceholders($i18n.proposal_detail__ineligible.text, {
$minDissolveDelay: secondsToDissolveDelayDuration(
minSnsDissolveDelaySeconds
),
})}
</p>
<VotingCardNeuronList>
{#each ineligibleNeurons as neuron}
<li class="value" title={neuron.neuronIdString}>
<span class="label">
{shortenWithMiddleEllipsis(
neuron.neuronIdString,
SNS_NEURON_ID_DISPLAY_LENGTH
)}<small>{reasonText(neuron)}</small>
</li>
{/each}
</ul>
</ProposalContentCell>
)}
</span>
<small class="value">{reasonText(neuron)}</small>
</li>
{/each}
</VotingCardNeuronList>
{/if}

<style lang="scss">
@use "@dfinity/gix-components/dist/styles/mixins/media";
ul {
list-style: none;
padding: 0;
p {
margin: var(--padding-2x) 0;
// fix unexpected scrollbars in voted and ineligible list
line-height: normal;
}
li {
margin: var(--padding-2x) 0;
display: flex;
flex-direction: column;
justify-content: space-between;
gap: var(--padding);
@include media.min-width(small) {
flex-direction: row;
Expand Down
76 changes: 40 additions & 36 deletions frontend/src/lib/components/proposal-detail/MyVotes.svelte
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
<script lang="ts">
import { Vote } from "@dfinity/nns";
import { i18n } from "$lib/stores/i18n";
import { IconThumbDown, IconThumbUp, Value } from "@dfinity/gix-components";
import {
IconThumbDown,
IconThumbUp,
KeyValuePair,
} from "@dfinity/gix-components";
import { replacePlaceholders } from "$lib/utils/i18n.utils";
import {
formatVotingPower,
type CompactNeuronInfo,
} from "$lib/utils/neuron.utils";
import ProposalContentCell from "./ProposalContentCell.svelte";
import { shortenWithMiddleEllipsis } from "$lib/utils/format.utils";
import { SNS_NEURON_ID_DISPLAY_LENGTH } from "$lib/constants/sns-neurons.constants";
import VotingCardNeuronList from "$lib/components/proposal-detail/VotingCard/VotingCardNeuronList.svelte";
import { fade } from "svelte/transition";
export let neuronsVotedForProposal: CompactNeuronInfo[] = [];
Expand All @@ -34,52 +39,51 @@
</script>

{#if neuronsVotedForProposal.length}
<ProposalContentCell>
<h4 slot="start">{$i18n.proposal_detail.my_votes}</h4>
<ul>
{#each neuronsVotedForProposal as neuron}
<li
data-tid="neuron-data"
aria-label={voteMapper({
neuron: neuron.idString,
vote: neuron.vote,
})}
title={voteMapper({ neuron: neuron.idString, vote: neuron.vote })}
>
<p class="value" title={neuron.idString}>
<VotingCardNeuronList>
{#each neuronsVotedForProposal as neuron}
<li
data-tid="neuron-data"
aria-label={voteMapper({
neuron: neuron.idString,
vote: neuron.vote,
})}
title={voteMapper({ neuron: neuron.idString, vote: neuron.vote })}
in:fade
>
<KeyValuePair>
<span slot="key" class="value" title={neuron.idString}>
{shortenWithMiddleEllipsis(
neuron.idString,
SNS_NEURON_ID_DISPLAY_LENGTH
)}
</p>
<p class="vote-details" data-tid="my-votes-voting-power">
<Value>{formatVotingPower(neuron.votingPower)}</Value>
</span>
<span
slot="value"
class="vote-details"
class:rejected={neuron.vote === Vote.No}
data-tid="my-votes-voting-power"
>
<span>{formatVotingPower(neuron.votingPower)}</span>
{#if voteIconMapper[neuron.vote]}
<svelte:component this={voteIconMapper[neuron.vote]} />
{/if}
</p>
</li>
{/each}
</ul>
</ProposalContentCell>
</span>
</KeyValuePair>
</li>
{/each}
</VotingCardNeuronList>
{/if}

<style lang="scss">
@use "@dfinity/gix-components/dist/styles/mixins/media";
ul {
list-style-type: none;
padding: 0;
}
li {
.vote-details {
display: flex;
justify-content: space-between;
align-items: center;
gap: var(--padding);
color: var(--positive-emphasis);
.vote-details {
display: flex;
align-items: center;
gap: var(--padding);
&.rejected {
color: var(--negative-emphasis);
}
}
</style>
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
<script lang="ts">
import type { ProposalInfo } from "@dfinity/nns";
import VotesResults from "./VotesResults.svelte";
import VotingCard from "./VotingCard/VotingCard.svelte";
import { ProposalRewardStatus } from "@dfinity/nns";
import { E8S_PER_ICP } from "$lib/constants/icp.constants";
import { basisPointsToPercent } from "$lib/utils/utils";
import {
MINIMUM_YES_PROPORTION_OF_EXERCISED_VOTING_POWER,
MINIMUM_YES_PROPORTION_OF_TOTAL_VOTING_POWER,
} from "$lib/constants/proposals.constants";
import NnsVotingCard from "$lib/components/proposal-detail/VotingCard/NnsVotingCard.svelte";
export let proposalInfo: ProposalInfo;
Expand Down Expand Up @@ -45,5 +45,5 @@
/>

{#if !settled}
<VotingCard {proposalInfo} />
<NnsVotingCard {proposalInfo} />
{/if}
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
<script lang="ts">
import { IconExpandCircleDown, Collapsible } from "@dfinity/gix-components";
import { fade } from "svelte/transition";
export let testId: string;
let toggleContent: () => void;
let expanded: boolean;
</script>

<div class="container" in:fade>
<Collapsible
{testId}
expandButton={false}
externalToggle={true}
bind:toggleContent
bind:expanded
wrapHeight
>
<div slot="header" class="header" class:expanded>
<div class="header-entry">
<span class="value">
<slot name="start" />
</span>
<button
class="icon"
class:expanded
on:click|stopPropagation={toggleContent}
>
<IconExpandCircleDown />
</button>
</div>

<div class="header-entry">
<slot name="end" />
</div>
</div>

<slot />
</Collapsible>
</div>

<style lang="scss">
@use "@dfinity/gix-components/dist/styles/mixins/media";
.container {
padding-bottom: var(--padding-2x);
border-bottom: 1px solid var(--tertiary);
}
.header {
display: flex;
justify-content: space-between;
gap: var(--padding);
width: 100%;
@include media.min-width(large) {
padding: 0 var(--padding) 0 0;
}
}
.header-entry {
display: flex;
align-items: center;
gap: var(--padding);
}
.icon {
color: var(--tertiary);
display: flex;
align-items: center;
justify-content: center;
padding: 0;
transition: transform ease-in var(--animation-time-normal);
&.expanded {
transform: rotate(-180deg);
}
}
</style>
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<script lang="ts">
import { i18n } from "$lib/stores/i18n";
import { replacePlaceholders } from "$lib/utils/i18n.utils";
import ExpandableProposalNeurons from "$lib/components/proposal-detail/VotingCard/ExpandableProposalNeurons.svelte";
import IneligibleNeuronsCard from "$lib/components/proposal-detail/IneligibleNeuronsCard.svelte";
import type { IneligibleNeuronData } from "$lib/utils/neuron.utils";
export let ineligibleNeurons: IneligibleNeuronData[] = [];
export let minSnsDissolveDelaySeconds: bigint;
let ineligibleNeuronCount: number;
$: ineligibleNeuronCount = ineligibleNeurons.length;
</script>

{#if ineligibleNeuronCount > 0}
<ExpandableProposalNeurons testId="ineligible-neurons">
<svelte:fragment slot="start">
{replacePlaceholders($i18n.proposal_detail__ineligible.headline, {
$count: `${ineligibleNeuronCount}`,
})}
</svelte:fragment>
<IneligibleNeuronsCard {ineligibleNeurons} {minSnsDissolveDelaySeconds} />
</ExpandableProposalNeurons>
{/if}
Loading

0 comments on commit db449b9

Please sign in to comment.