diff --git a/src/app/features/add-network/add-network.tsx b/src/app/features/add-network/add-network.tsx
index 1e2665f5ce7..2bca208f2ff 100644
--- a/src/app/features/add-network/add-network.tsx
+++ b/src/app/features/add-network/add-network.tsx
@@ -1,77 +1,12 @@
-import { NetworkSelectors } from '@tests/selectors/network.selectors';
-import { Form, Formik } from 'formik';
-import { Stack, styled } from 'leather-styles/jsx';
+import { NetworkForm } from './network-form';
+import { NetworkFormLayout } from './network-form.layout';
-import { Button, Link } from '@leather.io/ui';
-
-import { ErrorLabel } from '@app/components/error-label';
-import { Card, Content, Page } from '@app/components/layout';
-import { PageHeader } from '@app/features/container/headers/page.header';
-
-import { AddNetworkForm } from './add-network-form';
-import { useAddNetwork } from './use-add-network';
+const title = 'Add network';
export function AddNetwork() {
- const { error, initialFormValues, loading, onSubmit } = useAddNetwork();
-
return (
- <>
-
-
-
-
- {({ handleSubmit }) => (
- handleSubmit()}
- >
- Add network
-
- }
- >
-
-
- )}
-
-
-
- >
+
+
+
);
}
diff --git a/src/app/features/add-network/edit-network.tsx b/src/app/features/add-network/edit-network.tsx
new file mode 100644
index 00000000000..2cab972aeba
--- /dev/null
+++ b/src/app/features/add-network/edit-network.tsx
@@ -0,0 +1,12 @@
+import { NetworkForm } from './network-form';
+import { NetworkFormLayout } from './network-form.layout';
+
+const title = 'Edit network';
+
+export function EditNetwork() {
+ return (
+
+
+
+ );
+}
diff --git a/src/app/features/add-network/add-network-form.tsx b/src/app/features/add-network/network-form-fields.tsx
similarity index 89%
rename from src/app/features/add-network/add-network-form.tsx
rename to src/app/features/add-network/network-form-fields.tsx
index 0634a758452..b69ee6c0147 100644
--- a/src/app/features/add-network/add-network-form.tsx
+++ b/src/app/features/add-network/network-form-fields.tsx
@@ -1,4 +1,4 @@
-import { useCallback, useEffect } from 'react';
+import { useCallback } from 'react';
import { NetworkSelectors } from '@tests/selectors/network.selectors';
import { useFormikContext } from 'formik';
@@ -18,6 +18,8 @@ import {
Title,
} from '@leather.io/ui';
+import { useOnMount } from '@app/common/hooks/use-on-mount';
+
import { type AddNetworkFormValues } from './use-add-network';
const networks: {
@@ -42,7 +44,11 @@ const networks: {
},
];
-export function AddNetworkForm() {
+interface NetworkFormFieldsProps {
+ isEditNetworkMode?: boolean;
+}
+
+export function NetworkFormFields({ isEditNetworkMode }: NetworkFormFieldsProps) {
const { handleChange, setFieldValue, values, initialValues } =
useFormikContext();
@@ -60,8 +66,8 @@ export function AddNetworkForm() {
[setFieldValue]
);
- useEffect(() => {
- switch (values.bitcoinNetwork) {
+ function setNetworkUrls(value: BitcoinNetworkModes) {
+ switch (value) {
case 'mainnet':
setStacksUrl('https://api.hiro.so');
setBitcoinUrl(BITCOIN_API_BASE_URL_MAINNET);
@@ -79,7 +85,15 @@ export function AddNetworkForm() {
setBitcoinUrl('https://mempool.space/testnet/api');
break;
}
- }, [setStacksUrl, setBitcoinUrl, values.bitcoinNetwork]);
+ }
+
+ useOnMount(() => {
+ if (isEditNetworkMode) {
+ return;
+ }
+
+ setNetworkUrls(values.bitcoinNetwork);
+ });
return (
<>
@@ -98,7 +112,8 @@ export function AddNetworkForm() {
{
+ onValueChange={(value: BitcoinNetworkModes) => {
+ setNetworkUrls(value);
void setFieldValue('bitcoinNetwork', value);
}}
>
diff --git a/src/app/features/add-network/network-form.layout.tsx b/src/app/features/add-network/network-form.layout.tsx
new file mode 100644
index 00000000000..85e7963addc
--- /dev/null
+++ b/src/app/features/add-network/network-form.layout.tsx
@@ -0,0 +1,20 @@
+import { ReactNode } from 'react';
+
+import { Content, Page } from '@app/components/layout';
+import { PageHeader } from '@app/features/container/headers/page.header';
+
+interface NetworkFormLayoutProps {
+ title: string;
+ children: ReactNode;
+}
+
+export function NetworkFormLayout({ title, children }: NetworkFormLayoutProps) {
+ return (
+ <>
+
+
+ {children}
+
+ >
+ );
+}
diff --git a/src/app/features/add-network/network-form.tsx b/src/app/features/add-network/network-form.tsx
new file mode 100644
index 00000000000..abca63432a4
--- /dev/null
+++ b/src/app/features/add-network/network-form.tsx
@@ -0,0 +1,70 @@
+import { NetworkSelectors } from '@tests/selectors/network.selectors';
+import { Form, Formik } from 'formik';
+import { Stack, styled } from 'leather-styles/jsx';
+
+import { Button, Link } from '@leather.io/ui';
+
+import { ErrorLabel } from '@app/components/error-label';
+import { Card } from '@app/components/layout';
+
+import { NetworkFormFields } from './network-form-fields';
+import { useAddNetwork } from './use-add-network';
+
+interface NetworkFormProps {
+ title: string;
+ isEditNetworkMode?: boolean;
+}
+
+export function NetworkForm({ isEditNetworkMode, title }: NetworkFormProps) {
+ const { error, initialFormValues, loading, onSubmit } = useAddNetwork();
+
+ return (
+
+ {({ handleSubmit }) => (
+ handleSubmit()}
+ >
+ {title}
+
+ }
+ >
+
+
+ )}
+
+ );
+}
diff --git a/src/app/features/add-network/use-add-network.tsx b/src/app/features/add-network/use-add-network.tsx
index 0d20529ab81..1745d6e9437 100644
--- a/src/app/features/add-network/use-add-network.tsx
+++ b/src/app/features/add-network/use-add-network.tsx
@@ -44,14 +44,17 @@ const initialFormValues: AddNetworkFormValues = {
bitcoinNetwork: 'mainnet',
};
-function useInitialValues() {
+function useAddNetworkState() {
const { state } = useLocation();
- if (!state) {
- return initialFormValues;
- }
+ return {
+ isEditNetworkMode: state?.isEditNetworkMode,
+ network: state?.network as NetworkConfiguration | undefined,
+ };
+}
- const network = state.network as NetworkConfiguration | undefined;
+function useInitialValues() {
+ const { network } = useAddNetworkState();
if (!network) {
return initialFormValues;
@@ -79,11 +82,13 @@ export function useAddNetwork() {
const network = useCurrentStacksNetworkState();
const networksActions = useNetworksActions();
const initialValues = useInitialValues();
+ const { isEditNetworkMode } = useAddNetworkState();
return {
error,
initialFormValues: initialValues,
loading,
+ isEditNetworkMode,
onSubmit: async (values: AddNetworkFormValues) => {
const { name, stacksUrl, bitcoinUrl, key, bitcoinNetwork } = values;
diff --git a/src/app/features/settings/network/components/network-list-item-menu.tsx b/src/app/features/settings/network/components/network-list-item-menu.tsx
index a429d7d3950..63c0ae36ff2 100644
--- a/src/app/features/settings/network/components/network-list-item-menu.tsx
+++ b/src/app/features/settings/network/components/network-list-item-menu.tsx
@@ -1,4 +1,4 @@
-import { SettingsSelectors } from '@tests/selectors/settings.selectors';
+import { NetworkSelectors } from '@tests/selectors/network.selectors';
import { css } from 'leather-styles/css';
import { HStack, styled } from 'leather-styles/jsx';
@@ -12,8 +12,8 @@ interface Props {
export function NetworkItemMenu({ onClickDeleteNetwork, onEditNetwork }: Props) {
return (
-
-
+
+
{
e.stopPropagation();
onEditNetwork();
@@ -37,13 +38,14 @@ export function NetworkItemMenu({ onClickDeleteNetwork, onEditNetwork }: Props)
{
e.stopPropagation();
onClickDeleteNetwork();
}}
>
-
+
Delete
diff --git a/src/app/features/settings/network/network.tsx b/src/app/features/settings/network/network.tsx
index a22f8f11e03..51885baf3be 100644
--- a/src/app/features/settings/network/network.tsx
+++ b/src/app/features/settings/network/network.tsx
@@ -72,7 +72,7 @@ export function NetworkSheet({ onClose }: NetworkSheetProps) {
}}
onEditNetwork={() => {
onClose();
- navigate(RouteUrls.AddNetwork, {
+ navigate(RouteUrls.EditNetwork, {
state: {
network: networks[id],
},
diff --git a/src/app/routes/app-routes.tsx b/src/app/routes/app-routes.tsx
index 44bce46d898..1cf14be6412 100644
--- a/src/app/routes/app-routes.tsx
+++ b/src/app/routes/app-routes.tsx
@@ -14,6 +14,7 @@ import { Content } from '@app/components/layout/layouts/content.layout';
import { SwitchAccountLayout } from '@app/components/layout/layouts/switch-account.layout';
import { LoadingSpinner } from '@app/components/loading-spinner';
import { AddNetwork } from '@app/features/add-network/add-network';
+import { EditNetwork } from '@app/features/add-network/edit-network';
import { Container } from '@app/features/container/container';
import { HomeHeader } from '@app/features/container/headers/home.header';
import { IncreaseBtcFeeSheet } from '@app/features/dialogs/increase-fee-dialog/increase-btc-fee-dialog';
@@ -145,6 +146,15 @@ function useAppRoutes() {
}
/>
+
+
+
+ }
+ />
+
{
const errorMessage = await errorMsgElement.innerText();
test.expect(errorMessage).toEqual(NetworkSelectors.NoBitcoinNodeFetch);
});
+
+ test('proper initial values on edit network', async ({ homePage, page, networkPage }) => {
+ await networkPage.inputNetworkNameField('Test network');
+ await networkPage.inputNetworkKeyField('test-network');
+ await networkPage.inputNetworkStacksAddressField('https://leather.granite.world');
+
+ await networkPage.clickAddNetwork();
+ await homePage.waitForHomePageReady();
+
+ await homePage.clickSettingsButton();
+
+ await page.getByTestId(SettingsSelectors.ChangeNetworkAction).click();
+
+ await networkPage.page.getByTestId(NetworkSelectors.NetworkMenuBtn).click({ force: true });
+ await networkPage.page.getByTestId(NetworkSelectors.EditNetworkMenuBtn).click();
+
+ const stacksInputText = await networkPage.page
+ .getByTestId(NetworkSelectors.NetworkStacksAddress)
+ .inputValue();
+
+ test.expect(stacksInputText).toEqual('https://leather.granite.world');
+ });
+
+ test('delete network', async ({ homePage, page, networkPage }) => {
+ const id = 'test-network';
+
+ await networkPage.inputNetworkNameField('Test network');
+ await networkPage.inputNetworkKeyField(id);
+ await networkPage.inputNetworkStacksAddressField('https://leather.granite.world');
+
+ await networkPage.clickAddNetwork();
+ await homePage.waitForHomePageReady();
+
+ await homePage.clickSettingsButton();
+
+ await page.getByTestId(SettingsSelectors.ChangeNetworkAction).click();
+ let networkEl = networkPage.page.getByTestId(id);
+
+ await test.expect(networkEl).toHaveCount(1);
+
+ await networkPage.page.getByTestId(NetworkSelectors.NetworkMenuBtn).click({ force: true });
+ await networkPage.page.getByTestId(NetworkSelectors.DeleteNetworkMenuBtn).click();
+
+ networkEl = networkPage.page.getByTestId(id);
+
+ await test.expect(networkEl).toHaveCount(0);
+ });
});