Skip to content

Commit

Permalink
feat: initial governance ui (#5327)
Browse files Browse the repository at this point in the history
* feat: adds governance view, tab and route

* feat: adds initial voting power ui

* feat: adds proposals details initial ui

* feat: adds initial proposals ui

* feat: adds part of the initial proposal details ui

* feat: adds governance and voted icons

* fix: changes openedQuestionIndex inactive value

* fix: remove removeShadow logic

* fix: changes arrow function to function
  • Loading branch information
jeeanribeiro committed Dec 2, 2022
1 parent b7e5df0 commit caf0d75
Show file tree
Hide file tree
Showing 45 changed files with 774 additions and 25 deletions.
3 changes: 3 additions & 0 deletions packages/desktop/lib/routers/actions/initialiseRouters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import {
CollectiblesRouter,
DashboardRouter,
dashboardRouter,
GovernanceRouter,
governanceRouter,
OnboardingRouter,
onboardingRouter,
SettingsRouter,
Expand Down Expand Up @@ -53,6 +55,7 @@ function initialiseBaseRouters(): void {
dashboardRouter.set(new DashboardRouter())
settingsRouter.set(new SettingsRouter())
collectiblesRouter.set(new CollectiblesRouter())
governanceRouter.set(new GovernanceRouter())
initialiseBaseOnboardingRouters()
}

Expand Down
2 changes: 2 additions & 0 deletions packages/desktop/lib/routers/actions/resetRouters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
appSetupRouter,
collectiblesRouter,
dashboardRouter,
governanceRouter,
ledgerSetupRouter,
loginRouter,
networkSetupRouter,
Expand Down Expand Up @@ -41,4 +42,5 @@ function resetBaseRouters(): void {
get(onboardingRouter).reset()
get(settingsRouter).reset()
get(collectiblesRouter).reset()
get(governanceRouter).reset()
}
2 changes: 2 additions & 0 deletions packages/desktop/views/dashboard/Dashboard.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import { Wallet } from './wallet'
import { onDestroy, onMount } from 'svelte'
import Collectibles from './collectibles/Collectibles.svelte'
import { Governance } from './governance'
import Sidebar from './Sidebar.svelte'
import TopNavigation from './TopNavigation.svelte'
Expand All @@ -29,6 +30,7 @@
wallet: Wallet,
settings: Settings,
collectibles: Collectibles,
governance: Governance,
developer: Developer,
}
Expand Down
10 changes: 10 additions & 0 deletions packages/desktop/views/dashboard/Sidebar.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,12 @@
},
]
: []),
{
icon: 'governance',
label: localize('tabs.governance'),
route: DashboardRoute.Governance,
onClick: openGovernance,
},
...(features?.developerTools?.enabled && $activeProfile?.isDeveloperProfile
? [
{
Expand All @@ -72,6 +78,10 @@
$collectiblesRouter.reset()
}
function openGovernance(): void {
$dashboardRouter.goTo(DashboardRoute.Governance)
}
function openDeveloper(): void {
$dashboardRouter.goTo(DashboardRoute.Developer)
}
Expand Down
10 changes: 9 additions & 1 deletion packages/desktop/views/dashboard/TopNavigation.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
collectiblesRouter,
DashboardRoute,
dashboardRoute,
GovernanceRoute,
governanceRoute,
governanceRouter,
SettingsRoute,
settingsRoute,
settingsRouter,
Expand All @@ -18,7 +21,7 @@
let showBackButton = false
$: {
if ($settingsRoute || $collectiblesRoute) {
if ($settingsRoute || $collectiblesRoute || $governanceRoute) {
showBackButton = isCorrectRoute()
}
}
Expand All @@ -30,6 +33,8 @@
return $settingsRoute !== SettingsRoute.Init
case DashboardRoute.Collectibles:
return $collectiblesRoute !== CollectiblesRoute.Gallery
case DashboardRoute.Governance:
return $governanceRoute !== GovernanceRoute.Proposals
default:
break
}
Expand All @@ -43,6 +48,9 @@
case DashboardRoute.Collectibles:
$collectiblesRouter.previous()
break
case DashboardRoute.Governance:
$governanceRouter.previous()
break
default:
break
}
Expand Down
15 changes: 15 additions & 0 deletions packages/desktop/views/dashboard/governance/Governance.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<script lang="typescript">
import { DetailsView, ProposalsView } from './views'
import { selectedAccount } from '@core/account'
import { GovernanceRoute, governanceRoute } from '@core/router'
</script>

{#if $selectedAccount}
{#key $selectedAccount?.index}
{#if $governanceRoute === GovernanceRoute.Proposals}
<ProposalsView />
{:else if $governanceRoute === GovernanceRoute.Details}
<DetailsView />
{/if}
{/key}
{/if}
1 change: 1 addition & 0 deletions packages/desktop/views/dashboard/governance/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default as Governance } from './Governance.svelte'
143 changes: 143 additions & 0 deletions packages/desktop/views/dashboard/governance/views/DetailsView.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
<script lang="typescript">
import { selectedProposal } from '@core/governance'
import { formatDate, localize } from '@core/i18n'
import { networkStatus } from '@core/network'
import { milestoneToDate } from '@core/utils'
import { Button, Text, MeatballMenuButton, Pane, ProposalStatusPill, TextType, FontWeight, Icon } from '@ui'
import { Icon as IconEnum } from '@auxiliary/icon'
const dateFormat = {
year: 'numeric',
month: 'short',
day: 'numeric',
hour: 'numeric',
minute: 'numeric',
timeZoneName: 'short',
} as Intl.DateTimeFormatOptions
const votesCounter = {
total: 0, // mocked data
power: '4821 SMR', // mocked data
}
const proposalInformation = {
countingEnds: formatDate(
milestoneToDate($networkStatus.currentMilestone, $selectedProposal?.milestones?.closed),
dateFormat
),
eventId: 'SGO-0001', // mocked data
nodeUrl: 'jfjk821391290jha.url', // mocked data
}
// just used for mocking
const questions = Array(4).fill('Should we burn the unclaimed tokens')
const options = ['This is option 1', 'This is option 2', 'This is option 3', 'Abstain']
let openedQuestionIndex = null
function handleMeatballMenu(): void {
return
}
function handleQuestionClick(index: number): void {
openedQuestionIndex = openedQuestionIndex === index ? null : index
}
</script>

<div class="w-full h-full flex flex-nowrap p-8 relative flex-1 space-x-4 bg-gray-50 dark:bg-gray-900">
<div class="w-2/5 flex flex-col space-y-4">
<Pane classes="p-6 flex flex-col flex-1">
<header-container class="flex justify-between items-center mb-4">
<ProposalStatusPill status={$selectedProposal?.status} />
<MeatballMenuButton onClick={handleMeatballMenu} />
</header-container>
<div class="flex flex-1 flex-col justify-between">
<Text type={TextType.h2}>{$selectedProposal?.title}</Text>
<div class="flex items-center cursor-pointer">
<Text fontSize="14" fontWeight={FontWeight.semibold} overrideColor classes="text-blue-500"
>{localize('views.governance.details.fullProposal')}</Text
>
<Icon icon={IconEnum.Link} height={16} classes="ml-0.5 text-blue-500" />
</div>
</div>
</Pane>
<Pane classes="p-6 h-fit">
<Text smaller classes="mb-5">
{localize('views.governance.details.yourVote.title')}
</Text>
<ul class="space-y-2">
{#each Object.keys(votesCounter) as counterKey}
<li class="flex justify-between bg-gray-50 px-4 py-3 rounded-lg">
<Text fontWeight={FontWeight.medium} overrideColor classes="text-gray-600">
{localize(`views.governance.details.yourVote.${counterKey}`)}
</Text>
<Text overrideColor classes="text-gray-600">
{votesCounter[counterKey]}
</Text>
</li>
{/each}
</ul>
</Pane>
<Pane classes="p-6 h-fit">
<Text smaller classes="mb-5">
{localize('views.governance.details.proposalInformation.title')}
</Text>
<ul class="space-y-2">
{#each Object.keys(proposalInformation) as counterKey}
<li class="flex justify-between bg-gray-50 px-4 py-3 rounded-lg">
<Text fontWeight={FontWeight.medium} overrideColor classes="text-gray-600">
{localize(`views.governance.details.proposalInformation.${counterKey}`)}
</Text>
<Text overrideColor classes="text-gray-600">
{proposalInformation[counterKey]}
</Text>
</li>
{/each}
</ul>
</Pane>
</div>
<Pane classes="w-3/5 h-full p-6 flex flex-col justify-between ">
<ul class="flex flex-1 flex-col space-y-5 overflow-y-scroll">
{#each questions as question, questionIndex}
<li
on:click={() => handleQuestionClick(questionIndex)}
class="flex flex-col px-5 py-4 rounded-xl border border-solid border-gray-200 cursor-pointer"
>
<div class="flex justify-between items-center">
<div class="flex flex-col">
<Text smaller fontWeight={FontWeight.bold} overrideColor classes="mb-1 text-blue-500"
>Question {questionIndex + 1}</Text
>
<Text fontWeight={FontWeight.bold} overrideColor classes="text-gray-900">{question}</Text>
</div>
<div class="transform {openedQuestionIndex === questionIndex ? 'rotate-180' : 'rotate-0'}">
<Icon icon={IconEnum.ChevronDown} classes="text-gray-500" />
</div>
</div>
<ul class:mt-4={openedQuestionIndex === questionIndex} class="space-y-2">
{#each options as option, optionIndex}
<li
class:hidden={openedQuestionIndex !== questionIndex}
class="flex justify-between items-center p-3 rounded-md border border-solid border-gray-200"
>
<div class="flex space-x-3">
<span
class="flex items-center justify-center h-5 w-5 text-12 text-700 text-gray-500 border border-solid border-gray-200"
>
{optionIndex + 1}
</span>
<Text fontWeight={FontWeight.medium}>{option}</Text>
</div>
<Icon icon={IconEnum.Info} width={10} height={10} classes="text-gray-600" />
</li>
{/each}
</ul>
</li>
{/each}
</ul>
<buttons-container class="flex w-full space-x-4 mt-6">
<Button outline classes="w-full">{localize('actions.cancel')}</Button>
<Button classes="w-full">{localize('actions.vote')}</Button>
</buttons-container>
</Pane>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<script lang="typescript">
import { Pane, Proposals, ProposalsDetails, VotingPower } from '@ui'
</script>

<div class="w-full h-full flex flex-nowrap p-8 relative flex-1 space-x-6 bg-gray-50 dark:bg-gray-900">
<div class="w-1/3 flex flex-col space-y-4">
<Pane classes="p-6 h-fit">
<VotingPower />
</Pane>
<Pane classes="p-6 h-fit">
<ProposalsDetails />
</Pane>
</div>
<span class="block w-0.5 h-full bg-gray-200" />
<div class="w-2/3">
<Proposals />
</div>
</div>
2 changes: 2 additions & 0 deletions packages/desktop/views/dashboard/governance/views/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { default as DetailsView } from './DetailsView.svelte'
export { default as ProposalsView } from './ProposalsView.svelte'
1 change: 1 addition & 0 deletions packages/desktop/views/dashboard/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@ export * from './collectibles'
export * from './developer'
export * from './settings'
export * from './wallet'
export * from './governance'

export { default as Dashboard } from './Dashboard.svelte'
2 changes: 1 addition & 1 deletion packages/mobile/components/AsyncActivityTileFooter.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
} from 'shared/components'
import { time } from '@core/app'
import { Icon as IconEnum } from '@lib/auxiliary/icon'
import { Position } from 'shared/components/Tooltip.svelte'
import { Position } from 'shared/components/enums'
import { localize } from '@core/i18n'
export let onClaim: () => unknown = () => {}
Expand Down
22 changes: 22 additions & 0 deletions packages/shared/components/ProposalStatusInfo.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<script lang="typescript">
import { ProposalStatusTimelineTooltip, ProposalStatusPill } from 'shared/components'
import { ProposalStatus, Position } from 'shared/components/enums'
export let milestones: Record<ProposalStatus, number>
export let status: ProposalStatus
export let position: Position = Position.Right
let anchor: HTMLElement
let isTooltipVisible = false
function showTooltip(show: boolean): void {
isTooltipVisible = show
}
</script>

<div bind:this={anchor} on:mouseenter={() => showTooltip(true)} on:mouseleave={() => showTooltip(false)}>
<ProposalStatusPill {status} />
</div>
{#if isTooltipVisible}
<ProposalStatusTimelineTooltip bind:anchor {milestones} {status} {position} />
{/if}

0 comments on commit caf0d75

Please sign in to comment.