Skip to content

Commit

Permalink
feat: change node url for proposal (#5956)
Browse files Browse the repository at this point in the history
* refactor: refactor menuitem

* feat: change node url

* enhancement: improve error message

* enhancement: add node icon

* enhancement: make selected proposal reactive

* fix: fix tests

* enhancement: add success translations

* fix: allow overflow on edit proposal popup

---------

Co-authored-by: Matthew Maxwell <44885822+maxwellmattryan@users.noreply.github.com>
Co-authored-by: Nicole O'Brien <nicole.obrien@iota.org>
  • Loading branch information
3 people committed Feb 24, 2023
1 parent 63869b9 commit 1c5a03c
Show file tree
Hide file tree
Showing 21 changed files with 251 additions and 118 deletions.
26 changes: 18 additions & 8 deletions packages/desktop/components/popups/AddProposalPopup.svelte
Expand Up @@ -13,16 +13,18 @@
import { selectedAccount } from '@core/account'
import { PopupId } from '@auxiliary/popup'
export let eventId: string
export let nodeUrl: string
export let initialEventId: string
export let initialNodeUrl: string
let inputtedEventId = initialEventId
let nodeUrl = initialNodeUrl
let eventIdError: string
let nodeInput: NodeInput
let nodeInputError: string
let inputtedEventId = eventId
let isBusy = false
let toAllAccounts = false
$: isEditMode = !!initialEventId && !!initialNodeUrl
$: disabled = !eventId || !nodeUrl || isBusy
$: eventId = inputtedEventId?.trim()
Expand All @@ -33,7 +35,7 @@
async function onSubmit(): Promise<void> {
try {
isBusy = true
await Promise.all([validateEventId(!toAllAccounts), nodeInput?.validate()])
await Promise.all([validateEventId(!toAllAccounts && !isEditMode), nodeInput?.validate()])
await registerParticipationWrapper()
isBusy = false
} catch (err) {
Expand Down Expand Up @@ -74,9 +76,12 @@
const accounts = toAllAccounts ? $activeAccounts : [$selectedAccount]
const promises = accounts.map((account) => registerParticipationEvent(eventId, { url: nodeUrl, auth }, account))
await Promise.all(promises)
const successMessage = isEditMode
? localize('views.governance.proposals.successEdit')
: localize('views.governance.proposals.' + (toAllAccounts ? 'successAddAll' : 'successAdd'))
showAppNotification({
type: 'success',
message: localize('views.governance.proposals.' + (toAllAccounts ? 'successAddAll' : 'successAdd')),
message: successMessage,
alert: true,
})
closePopup()
Expand All @@ -103,17 +108,22 @@
</script>

<form id="add-proposal" on:submit|preventDefault={onSubmit}>
<Text type={TextType.h3} classes="mb-6">{localize('popups.addProposal.title')}</Text>
<Text fontSize="15">{localize('popups.addProposal.body')}</Text>
<Text type={TextType.h3} classes="mb-6"
>{localize(`popups.${isEditMode ? 'editProposal' : 'addProposal'}.title`)}</Text
>
<Text fontSize="15">{localize(`popups.${isEditMode ? 'editProposal' : 'addProposal'}.body`)}</Text>
<div class="flex flex-col w-full space-y-4 mt-4">
<TextInput
bind:value={inputtedEventId}
bind:error={eventIdError}
placeholder={localize('views.governance.details.proposalInformation.eventId')}
label={localize('views.governance.details.proposalInformation.eventId')}
disabled={isEditMode}
/>
<NodeInput bind:this={nodeInput} bind:nodeUrl bind:error={nodeInputError} />
<Checkbox label={localize('popups.addProposal.addToAllAccounts')} bind:checked={toAllAccounts} />
{#if !isEditMode}
<Checkbox label={localize('popups.addProposal.addToAllAccounts')} bind:checked={toAllAccounts} />
{/if}
</div>
<div class="flex w-full space-x-4 mt-6">
<Button outline classes="w-full" onClick={onCancelClick}>{localize('actions.cancel')}</Button>
Expand Down
Expand Up @@ -222,7 +222,7 @@
<Pane classes="p-6 flex flex-col h-fit">
<header-container class="flex justify-between items-center mb-4">
<ProposalStatusPill status={$selectedProposal?.status} />
<ProposalDetailsButton />
<ProposalDetailsButton proposal={$selectedProposal} />
</header-container>
<div class="flex flex-1 flex-col justify-between">
<Text type={TextType.h2}>{$selectedProposal?.title}</Text>
Expand Down
24 changes: 24 additions & 0 deletions packages/shared/components/atoms/Icon.svelte
Expand Up @@ -45,6 +45,18 @@
: path.fill ?? ''}
/>
{/each}
{#if selected.circles}
{#each selected.circles as circle}
<circle
cx={circle.cx}
cy={circle.cy}
r={circle.r}
fill={circle.fill}
stroke-width={circle.strokeWidth || ''}
stroke={circle.strokeColor || ''}
/>
{/each}
{/if}
</svg>
</div>
{:else}
Expand Down Expand Up @@ -81,6 +93,18 @@
: path.fill ?? ''}
/>
{/each}
{#if selected.circles}
{#each selected.circles as circle}
<circle
cx={circle.cx}
cy={circle.cy}
r={circle.r}
fill={circle.fill}
stroke-width={circle.strokeWidth || ''}
stroke={circle.strokeColor || ''}
/>
{/each}
{/if}
</svg>
{/if}
{/if}
Expand Down
56 changes: 42 additions & 14 deletions packages/shared/components/atoms/MenuItem.svelte
@@ -1,5 +1,5 @@
<script lang="ts">
import { Icon, Text } from 'shared/components'
import { Icon, Text, Spinner, Position, Tooltip } from 'shared/components'
export let icon: string = ''
export let iconProps: Record<string, unknown> = undefined
Expand All @@ -8,9 +8,18 @@
export let onClick: () => any
export let selected = false
export let disabled = false
export let isLoading = false
export let enableTooltipVisible = false
export let tooltip: string = undefined
export let variant: 'success' | 'error' | 'warning' | 'info' = 'info'
let showTooltip = false
let menuItem: HTMLElement
let color = 'blue'
$: isDisabled = disabled || isLoading
$: variant, setColor()
function setColor(): void {
switch (variant) {
Expand All @@ -34,38 +43,51 @@
return onClick()
}
}
function toggleTooltip(show: boolean): void {
showTooltip = enableTooltipVisible && show
}
</script>

<button
bind:this={menuItem}
on:click|stopPropagation={handleOnClick}
on:mouseenter={() => toggleTooltip(true)}
on:mouseleave={() => toggleTooltip(false)}
class="group w-full flex flex-row justify-between items-center p-3
{disabled
{isDisabled
? 'bg-gray-100 dark:bg-gray-850 cursor-default'
: `hover:bg-${color}-50 dark:hover:bg-gray-800 dark:hover:bg-opacity-20`}
"
>
<div class="flex flex-row space-x-3 items-center">
<Icon
{icon}
height={24}
width={24}
classes={disabled ? 'text-gray-400 dark:text-gray-700' : `text-gray-600 group-hover:text-${color}-500`}
{...iconProps}
/>
{#if isLoading}
<Spinner busy width={24} height={24} />
{:else}
<Icon
{icon}
height={24}
width={24}
classes={isDisabled
? 'text-gray-400 dark:text-gray-700'
: `text-gray-600 group-hover:text-${color}-500`}
{...iconProps}
/>
{/if}
<div class="flex flex-col text-left">
<Text
type="p"
color={disabled ? 'gray-400' : 'gray-800'}
darkColor={disabled ? 'gray-700' : 'white'}
classes={disabled ? '' : `group-hover:text-${color}-500`}
color={isDisabled ? 'gray-400' : 'gray-800'}
darkColor={isDisabled ? 'gray-700' : 'white'}
classes={isDisabled ? '' : `group-hover:text-${color}-500`}
>
{title}
</Text>
{#if subtitle}
<Text
type="p"
color={disabled ? 'gray-400' : 'gray-600'}
darkColor={disabled ? 'gray-700' : 'gray-500'}
color={isDisabled ? 'gray-400' : 'gray-600'}
darkColor={isDisabled ? 'gray-700' : 'gray-500'}
>
{subtitle}
</Text>
Expand All @@ -76,3 +98,9 @@
<Icon icon="checkmark" classes="ml-2 text-blue-500" />
{/if}
</button>

{#if showTooltip}
<Tooltip anchor={menuItem} position={Position.Right}>
<Text smaller>{tooltip}</Text>
</Tooltip>
{/if}
@@ -1,10 +1,83 @@
<script lang="ts">
import { Modal, ProposalDetailsMenu, MeatballMenuButton } from 'shared/components'
import { onMount } from 'svelte'
import { Modal, MenuItem, MeatballMenuButton } from 'shared/components'
import { Icon } from '@auxiliary/icon'
import { openPopup } from '@auxiliary/popup/actions'
import { handleError } from '@core/error/handlers'
import { isVotingForSelectedProposal } from '@contexts/governance/utils'
import { participationOverviewForSelectedAccount } from '@contexts/governance/stores'
import { localize } from '@core/i18n'
import { selectedAccount } from '@core/account/stores'
// TODO: https://github.com/iotaledger/firefly/issues/5801
import features from '../../../../desktop/features/features'
import { PopupId } from '@auxiliary/popup'
import { IProposal } from '@contexts/governance'
let modal: Modal
export let proposal: IProposal
export let modal: Modal = undefined
let isVotingForProposal: boolean
let isBusy = true // starts in a busy state because data needs to be fetched before displaying selectable options
$: isTransferring = $selectedAccount?.isTransferring
$: isTransferring, $participationOverviewForSelectedAccount, void updateIsVoting() // vote/stop vote changes the isTransferring value. Relying on this requires less updates than relying on proposalsState
$: isBusy = isVotingForProposal === undefined
$: buttons = [
{
icon: Icon.Node,
title: localize('actions.changeNode'),
onClick: onChangeNodeClick,
},
{
icon: Icon.Delete,
title: isBusy ? localize('views.governance.details.fetching') : localize('actions.removeProposal'),
onClick: onRemoveProposalClick,
variant: 'error',
isLoading: isBusy,
disabled: !features.governance.removeProposals.enabled || isVotingForProposal,
enableTooltipVisible: isVotingForProposal !== undefined,
tooltip: localize('tooltips.governance.removeProposalWarning'),
},
]
function onChangeNodeClick(): void {
openPopup({
id: PopupId.AddProposal,
props: {
initialEventId: proposal.id,
initialNodeUrl: proposal.nodeUrl,
},
overflow: true,
})
modal.close()
}
function onRemoveProposalClick(): void {
openPopup({
id: PopupId.RemoveProposal,
})
modal.close()
}
function updateIsVoting(): void {
try {
isVotingForProposal = isVotingForSelectedProposal()
} catch (err) {
handleError(err)
}
}
onMount(() => void updateIsVoting())
</script>

<div class="max-h-7 max-w-9 flex-none flex-initial overflow-visible relative">
<MeatballMenuButton onClick={modal?.toggle} />
<ProposalDetailsMenu bind:modal position={{ right: '0' }} classes="mt-1.5" />
<Modal bind:this={modal} position={{ right: '0' }} classes="mt-1.5">
<div class="flex flex-col">
{#each buttons as button}
<MenuItem {...button} />
{/each}
</div>
</Modal>
</div>
78 changes: 0 additions & 78 deletions packages/shared/components/modals/ProposalDetailsMenu.svelte

This file was deleted.

1 change: 0 additions & 1 deletion packages/shared/components/modals/index.js
Expand Up @@ -6,5 +6,4 @@ export { default as Modal } from './Modal.svelte'
export { default as NetworkSummaryModal } from './NetworkSummaryModal.svelte'
export { default as NodeActionsMenu } from './NodeActionsMenu.svelte'
export { default as ProfileActionsModal } from './ProfileActions.svelte'
export { default as ProposalDetailsMenu } from './ProposalDetailsMenu.svelte'
export { default as RecipientAccountSelector } from './RecipientAccountSelector.svelte'
Expand Up @@ -18,7 +18,7 @@
export let activity: Activity
export let networkAddress: string = null
export let activeTab = Tab.Transaction
export let activeTab: Tab = Tab.Transaction
let hasMetadata = false
$: {
Expand Down

0 comments on commit 1c5a03c

Please sign in to comment.