Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add node configuration flow before login #2890

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions packages/desktop/components/NodeListTable.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
export let nodesContainer: HTMLElement | undefined = undefined

$: clientOptions = $activeProfile?.clientOptions
$: nodes =
clientOptions?.nodes?.length ?? 0 > 0 ? clientOptions?.nodes : getDefaultNodes($activeProfile?.network?.id)

function isPrimary(node: INode): boolean {
return node.url === clientOptions?.primaryNode?.url
Expand All @@ -26,9 +28,7 @@
</script>

<node-list-table class="max-h-80 flex flex-col overflow-auto" bind:this={nodesContainer}>
{#if clientOptions?.nodes}
{@const nodes =
clientOptions?.nodes?.length > 0 ? clientOptions?.nodes : getDefaultNodes($activeProfile?.network?.id)}
{#if nodes}
{#each nodes as node}
<div class="flex flex-row items-center justify-between">
<button
Expand All @@ -49,7 +49,7 @@
</Pill>
{/if}
</button>
<NodeActionsMenu {node} {clientOptions} />
<NodeActionsMenu {node} {clientOptions} currentNetwork={$activeProfile?.network} />
</div>
{/each}
{/if}
Expand Down
110 changes: 62 additions & 48 deletions packages/desktop/components/menus/NodeActionsMenu.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -7,91 +7,106 @@
toggleDisabledNodeInClientOptions,
togglePrimaryNodeInClientOptions,
} from '@core/network/actions'
import { IClientOptions } from '@core/network/interfaces'
import { getDefaultNodes } from '@core/network/utils'
import { activeProfile } from '@core/profile/stores'
import { IClientOptions, IStardustNetworkMetadata } from '@core/network/interfaces'
import { PopupId, closePopup, openPopup } from '@desktop/auxiliary/popup'

export let currentNetwork: IStardustNetworkMetadata
export let node: INode
export let clientOptions: IClientOptions

let menu: Menu | undefined = undefined

$: isOfficialNode = getDefaultNodes($activeProfile?.network?.id).some((n) => n.url === node?.url)
$: allowDisableOrRemove = node?.disabled || clientOptions?.nodes?.filter((node) => !node.disabled)?.length > 1
$: isPrimary = clientOptions?.primaryNode?.url === node.url

function onEditNodeDetailsClick(): void {
openPopup({
id: PopupId.AddNode,
props: {
node,
isEditingNode: true,
onSuccess: () => {
closePopup()
openPopup(
{
id: PopupId.AddNode,
props: {
node,
isEditingNode: true,
currentNetwork,
onSuccess: () => {
closePopup()
},
},
},
})
false,
false
)
menu?.close()
}

async function onTogglePrimaryNodeClick(): Promise<void> {
if (isPrimary) {
openPopup({
id: PopupId.Confirmation,
props: {
variant: 'danger',
title: localize('popups.unsetAsPrimaryNode.title'),
description: localize('popups.unsetAsPrimaryNode.body', { values: { url: node.url } }),
confirmText: localize('actions.clear'),
onConfirm: () => {
void togglePrimaryNodeInClientOptions(node)
closePopup()
openPopup(
{
id: PopupId.Confirmation,
props: {
variant: 'danger',
title: localize('popups.unsetAsPrimaryNode.title'),
description: localize('popups.unsetAsPrimaryNode.body', { values: { url: node.url } }),
confirmText: localize('actions.clear'),
onConfirm: () => {
void togglePrimaryNodeInClientOptions(node)
closePopup()
},
},
},
})
false,
false
)
} else {
await togglePrimaryNodeInClientOptions(node)
}
menu?.close()
}

function onRemoveNodeClick(): void {
openPopup({
id: PopupId.Confirmation,
props: {
variant: 'danger',
title: localize('popups.node.titleRemove'),
description: localize('popups.node.removeConfirmation'),
confirmText: localize('actions.removeNode'),
onConfirm: () => {
void removeNodeFromClientOptions(node)
closePopup()
openPopup(
{
id: PopupId.Confirmation,
props: {
variant: 'danger',
title: localize('popups.node.titleRemove'),
description: localize('popups.node.removeConfirmation'),
confirmText: localize('actions.removeNode'),
onConfirm: () => {
void removeNodeFromClientOptions(node)
closePopup()
},
},
},
})
false,
false
)
menu?.close()
}

function onToggleDisabledNodeClick(): void {
if (node.disabled) {
void toggleDisabledNodeInClientOptions(node)
} else {
openPopup({
id: PopupId.Confirmation,
props: {
variant: 'danger',
title: localize('popups.excludeNode.title'),
description: localize('popups.excludeNode.body', { values: { url: node?.url } }),
confirmText: localize(
'views.dashboard.drawers.networkConfig.networkSettings.configureNodeList.excludeNode'
),
onConfirm: () => {
void toggleDisabledNodeInClientOptions(node)
closePopup()
openPopup(
{
id: PopupId.Confirmation,
props: {
variant: 'danger',
title: localize('popups.excludeNode.title'),
description: localize('popups.excludeNode.body', { values: { url: node?.url } }),
confirmText: localize(
'views.dashboard.drawers.networkConfig.networkSettings.configureNodeList.excludeNode'
),
onConfirm: () => {
void toggleDisabledNodeInClientOptions(node)
closePopup()
},
},
},
})
false,
false
)
}
menu?.close()
}
Expand All @@ -104,7 +119,6 @@
{
icon: IconName.Edit,
title: localize('views.dashboard.drawers.networkConfig.networkSettings.configureNodeList.editDetails'),
disabled: isOfficialNode,
onClick: onEditNodeDetailsClick,
},
{
Expand Down
10 changes: 8 additions & 2 deletions packages/desktop/components/popup/popups/AddNodePopup.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,18 @@
import { registerProposalsForAccounts } from '@contexts/governance'
import { Platform } from '@core/app'
import { localize } from '@core/i18n'
import { EMPTY_NODE, addNodeToClientOptions, editNodeInClientOptions } from '@core/network'
import {
EMPTY_NODE,
IStardustNetworkMetadata,
addNodeToClientOptions,
editNodeInClientOptions,
} from '@core/network'
import { activeAccounts } from '@core/profile/stores'
import { closePopup } from '@desktop/auxiliary/popup'
import { NodeConfigurationForm } from '@ui'
import PopupTemplate from '../PopupTemplate.svelte'

export let currentNetwork: IStardustNetworkMetadata
export let node: INode = structuredClone(EMPTY_NODE)
export let isEditingNode: boolean = false
export let onSuccess: (..._: any[]) => void
Expand All @@ -26,7 +32,7 @@
try {
isBusy = true
await nodeConfigurationForm.validate({
checkSameNetwork: true,
checkSameNetwork: currentNetwork,
uniqueCheck: !isEditingNode,
checkNodeInfo: true,
validateClientOptions: true,
Expand Down
1 change: 1 addition & 0 deletions packages/desktop/lib/auxiliary/drawer/actions/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export * from './closeDrawer'
export * from './openDrawer'
export * from './toggleDashboardDrawer'
export * from './toggleLoginDrawer'
export * from './updateDrawerProps'
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { get } from 'svelte/store'
import { closeDrawer, openDrawer } from '.'
import { DrawerDirection, DrawerRoute } from '../enums'
import { drawerState } from '../stores'
import { DrawerState } from '../types'

export function toggleLoginDrawer({
id,
initialSubroute = undefined,
direction = DrawerDirection.Right,
hideClose = false,
preventClose = false,
overflow = false,
props = undefined,
}: Omit<DrawerState, 'route'>): void {
const $drawerState = get(drawerState)
if ($drawerState && $drawerState.route === DrawerRoute.Login && $drawerState.id === id) {
closeDrawer()
} else {
openDrawer({
route: DrawerRoute.Login,
id,
initialSubroute,
hideClose,
preventClose,
direction,
overflow,
props,
})
}
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export enum DrawerRoute {
Dashboard = 'dashboard',
Login = 'login',
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
DashboardDrawerRoute,
NetworkConfigRoute,
} from '../../../../views/dashboard/drawers'
import { LoginDrawerRoute } from '../../../../views/login/drawers'

interface IBaseDrawerState {
hideClose?: boolean
Expand All @@ -27,7 +28,7 @@ export interface IDappConfigDrawerState extends IBaseDrawerState {
}

export interface INetworkConfigDrawerState extends IBaseDrawerState {
route: DrawerRoute.Dashboard
id: DashboardDrawerRoute.NetworkConfig
route: DrawerRoute.Dashboard | DrawerRoute.Login
id: DashboardDrawerRoute.NetworkConfig | LoginDrawerRoute.NetworkConfig
initialSubroute?: NetworkConfigRoute
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import { NodeListTable } from '@components'
import { localize } from '@core/i18n'

export let nodesContainer: HTMLElement
export let nodesContainer: HTMLElement | undefined = undefined
</script>

<div class="flex flex-col space-y-2">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,28 +8,34 @@
import LocalProofOfWork from './LocalProofOfWork.svelte'
import { IStardustNetwork } from '@core/network'
import { NetworkConfigRoute } from '../../network-config-route.enum'
import { activeProfile } from '@core/profile/stores'

export let drawerRouter: Router<NetworkConfigRoute>
export let network: IStardustNetwork

let nodesContainer: HTMLElement

function onAddNodeClick(): void {
openPopup({
id: PopupId.AddNode,
props: {
onSuccess: () => {
closePopup()
setTimeout(() => {
/**
* NOTE: This automatically scrolls the user to the bottom of the
* nodes container to see the newly added node.
*/
nodesContainer.scrollTop = nodesContainer.scrollHeight
}, 100)
openPopup(
{
id: PopupId.AddNode,
props: {
onSuccess: () => {
closePopup()
setTimeout(() => {
/**
* NOTE: This automatically scrolls the user to the bottom of the
* nodes container to see the newly added node.
*/
nodesContainer.scrollTop = nodesContainer.scrollHeight
}, 100)
},
currentNetwork: $activeProfile?.network,
},
},
})
false,
false
)
}
</script>

Expand Down
2 changes: 2 additions & 0 deletions packages/desktop/views/login/LoginRouter.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import { UpdateStrongholdRouterView } from '@views'
import { LoadProfileView, LoginView, SelectProfileView } from './views'
import { PopupId, openPopup } from '@desktop/auxiliary/popup'
import { LoginDrawerRouterView } from './drawers'

$: if (features.analytics.loginRoute.enabled && $loginRoute)
Platform.trackEvent('login-route', { route: $loginRoute })
Expand All @@ -31,3 +32,4 @@
{:else if $loginRoute === LoginRoute.LoadProfile}
<LoadProfileView />
{/if}
<LoginDrawerRouterView />
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,13 @@
import { deleteProfile } from '@contexts/settings/actions'
import { localize } from '@core/i18n'
import { IPersistedProfile } from '@core/profile'
import { toggleLoginDrawer } from '@desktop/auxiliary/drawer'
import { PopupId, closePopup, openPopup } from '@desktop/auxiliary/popup'
import { LoginDrawerRoute } from '../drawers'
import { NetworkConfigRoute } from '@views/dashboard/drawers'
import { setSelectedNetworkForNetworkDrawer } from '@core/network/stores'
import { StardustNetwork } from '@core/network/classes'
import { loadPersistedProfileIntoActiveProfile } from '@core/profile/actions'

export let profile: IPersistedProfile

Expand All @@ -20,6 +26,16 @@
)
}

function onNodeConfigurationClick(): void {
loadPersistedProfileIntoActiveProfile(profile.id)
const profileNetwork = new StardustNetwork(profile.network)
setSelectedNetworkForNetworkDrawer(profileNetwork)
toggleLoginDrawer({
id: LoginDrawerRoute.NetworkConfig,
initialSubroute: NetworkConfigRoute.ChainInformation,
})
}

function onDeleteClick(): void {
openPopup(
{
Expand Down Expand Up @@ -48,6 +64,11 @@
title: localize('popups.profileDiagnostics.title'),
onClick: onDiagnosticsClick,
},
{
icon: IconName.Tool,
title: 'Node configuration',
onClick: onNodeConfigurationClick,
},
{
variant: 'danger',
icon: IconName.Trash,
Expand Down
Loading