From d22f431ce3a986c5efb660df1f3fd9bdad64a4b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9rard=20Dethier?= Date: Fri, 2 Feb 2024 14:37:43 +0100 Subject: [PATCH] feat: review-less protection. logion-network/logion-internal#1123 --- src/legal-officer/ContextualizedWallet.tsx | 17 --- src/legal-officer/LegalOfficerPaths.tsx | 3 - src/legal-officer/LegalOfficerRouter.tsx | 3 - .../PendingProtectionRequests.test.tsx | 129 ----------------- src/legal-officer/ProtectionRequests.css | 3 - src/legal-officer/ProtectionRequests.test.tsx | 10 -- src/legal-officer/ProtectionRequests.tsx | 53 ------- .../ProtectionRequestsHistory.test.tsx | 19 --- .../ProtectionRequestsHistory.tsx | 66 --------- src/legal-officer/RecoveryDetails.tsx | 12 +- .../ContextualizedWallet.test.tsx.snap | 16 --- .../LegalOfficerRouter.test.tsx.snap | 4 - .../PendingProtectionRequests.test.tsx.snap | 80 ----------- .../ProtectionRequests.test.tsx.snap | 41 ------ .../ProtectionRequestsHistory.test.tsx.snap | 83 ----------- src/loc/issuer/IssuerSelectionFrame.tsx | 1 - src/vault/VaultOutRequest.tsx | 2 +- src/wallet-user/UserContext.tsx | 47 ++----- .../CreateProtectionRequestForm.test.tsx | 6 +- .../CreateProtectionRequestForm.tsx | 51 ++++--- .../ProtectionRecoveryRequest.tsx | 51 ++----- .../trust-protection/ProtectionRefusal.css | 19 --- .../trust-protection/ProtectionRefusal.tsx | 131 ------------------ .../trust-protection/TrustProtection.tsx | 9 -- .../ProtectionRecoveryRequest.test.tsx.snap | 2 + .../TrustProtection.test.tsx.snap | 12 +- yarn.lock | 6 +- 27 files changed, 72 insertions(+), 804 deletions(-) delete mode 100644 src/legal-officer/PendingProtectionRequests.test.tsx delete mode 100644 src/legal-officer/ProtectionRequests.css delete mode 100644 src/legal-officer/ProtectionRequests.test.tsx delete mode 100644 src/legal-officer/ProtectionRequests.tsx delete mode 100644 src/legal-officer/ProtectionRequestsHistory.test.tsx delete mode 100644 src/legal-officer/ProtectionRequestsHistory.tsx delete mode 100644 src/legal-officer/__snapshots__/PendingProtectionRequests.test.tsx.snap delete mode 100644 src/legal-officer/__snapshots__/ProtectionRequests.test.tsx.snap delete mode 100644 src/legal-officer/__snapshots__/ProtectionRequestsHistory.test.tsx.snap delete mode 100644 src/wallet-user/trust-protection/ProtectionRefusal.css delete mode 100644 src/wallet-user/trust-protection/ProtectionRefusal.tsx diff --git a/src/legal-officer/ContextualizedWallet.tsx b/src/legal-officer/ContextualizedWallet.tsx index 9409b057..2bae29ff 100644 --- a/src/legal-officer/ContextualizedWallet.tsx +++ b/src/legal-officer/ContextualizedWallet.tsx @@ -7,7 +7,6 @@ import { useCommonContext } from '../common/CommonContext'; import { HOME_PATH, - PROTECTION_REQUESTS_PATH, RECOVERY_REQUESTS_PATH, SETTINGS_PATH, WALLET_PATH, @@ -145,22 +144,6 @@ export default function ContextualizedWallet() { - } /> } /> } /> } /> diff --git a/src/legal-officer/PendingProtectionRequests.test.tsx b/src/legal-officer/PendingProtectionRequests.test.tsx deleted file mode 100644 index a90b4c4f..00000000 --- a/src/legal-officer/PendingProtectionRequests.test.tsx +++ /dev/null @@ -1,129 +0,0 @@ -jest.mock('../logion-chain/Signature'); -jest.mock('./LegalOfficerContext'); -jest.mock('../logion-chain'); -jest.mock('../loc/Model'); -jest.mock('../common/CommonContext'); - -import { render, screen, waitFor } from '@testing-library/react'; -import userEvent from '@testing-library/user-event'; - -import { shallowRender } from '../tests'; -import PendingProtectionRequests from './PendingProtectionRequests'; -import { setPendingProtectionRequests, setPendingRecoveryRequests } from './__mocks__/LegalOfficerContextMock'; -import { setAcceptProtectionRequest, setRejectProtectionRequest } from '../loc/__mocks__/ModelMock'; -import { PENDING_PROTECTION_REQUESTS } from './TestData'; -import { setCurrentAddress, DEFAULT_LEGAL_OFFICER_ACCOUNT, axiosMock } from '../logion-chain/__mocks__/LogionChainMock'; -import { setupQueriesGetLegalOfficerCase } from 'src/test/Util'; -import { UUID } from '@logion/node-api'; -import { setupApiMock, CLOSED_IDENTITY_LOC, CLOSED_IDENTITY_LOC_ID } from 'src/__mocks__/LogionMock'; - -describe("PendingProtectionRequests", () => { - - beforeEach(() => { - setCurrentAddress(DEFAULT_LEGAL_OFFICER_ACCOUNT); - }); - - it("Renders null with no data", () => { - const tree = shallowRender(); - expect(tree).toMatchSnapshot(); - }); - - it("Renders pending requests", () => { - setPendingProtectionRequests(PENDING_PROTECTION_REQUESTS); - setPendingRecoveryRequests([]); - const tree = shallowRender(); - expect(tree).toMatchSnapshot(); - }); - - it("Click on later closes dialog", async () => { - setPendingProtectionRequests(PENDING_PROTECTION_REQUESTS); - setPendingRecoveryRequests([]); - const rejectCallback = jest.fn(); - setRejectProtectionRequest(rejectCallback); - const acceptCallback = jest.fn(); - setAcceptProtectionRequest(acceptCallback); - - render(); - const reviewButton = screen.getByRole("button", {name: "Review and proceed"}); - await userEvent.click(reviewButton); - - let laterButton: HTMLElement; - await waitFor(() => laterButton = screen.getByRole("button", {name: "Later"})); - const reviewModal = screen.getByRole("dialog"); - await userEvent.click(laterButton!); - - await waitFor(() => expect(reviewModal).not.toBeInTheDocument()); - expect(rejectCallback).not.toBeCalled(); - expect(acceptCallback).not.toBeCalled(); - }); - - it("Review and reject request", async () => { - setPendingProtectionRequests(PENDING_PROTECTION_REQUESTS); - setPendingRecoveryRequests([]); - const rejectCallback = jest.fn(); - setRejectProtectionRequest(rejectCallback); - const acceptCallback = jest.fn(); - setAcceptProtectionRequest(acceptCallback); - - render(); - const reviewButton = screen.getByRole("button", {name: "Review and proceed"}); - await userEvent.click(reviewButton); - - let rejectButton: HTMLElement; - await waitFor(() => rejectButton = screen.getByRole('button', {name: "No"})); - const reviewModal = screen.getByRole("dialog"); - await userEvent.click(rejectButton!); - - await waitFor(() => expect(reviewModal).not.toBeInTheDocument()); - - let confirmModal: HTMLElement; - await waitFor(() => confirmModal = screen.getByRole("dialog")); - let reasonTextArea = screen.getByRole("textbox", {name: "Reason"}); - const rejectReason = "Reason"; - await userEvent.type(reasonTextArea!, rejectReason); - let confirmButton = screen.getByRole('button', {name: "Confirm"}); - await userEvent.click(confirmButton!); - await waitFor(() => expect(confirmModal).not.toBeInTheDocument()); - - await waitFor(() => expect(rejectCallback).toBeCalledWith( - axiosMock.object(), - expect.objectContaining({ - requestId: "1", - rejectReason, - }) - )); - expect(acceptCallback).not.toBeCalled(); - }); - - it("Review and accept request", async () => { - setPendingProtectionRequests(PENDING_PROTECTION_REQUESTS); - setPendingRecoveryRequests([]); - setupApiMock(api => { - setupQueriesGetLegalOfficerCase(api, UUID.fromDecimalStringOrThrow(CLOSED_IDENTITY_LOC_ID), CLOSED_IDENTITY_LOC); - }); - - const rejectCallback = jest.fn(); - setRejectProtectionRequest(rejectCallback); - const acceptCallback = jest.fn(); - setAcceptProtectionRequest(acceptCallback); - - render(); - const reviewButton = screen.getByRole("button", {name: "Review and proceed"}); - await userEvent.click(reviewButton); - - let acceptButton: HTMLElement; - await waitFor(() => acceptButton = screen.getByRole("button", {name: "Yes"})); - const reviewModal = screen.getByRole("dialog"); - await userEvent.click(acceptButton!); - - await waitFor(() => expect(reviewModal).not.toBeInTheDocument()); - - await waitFor(() => expect(acceptCallback).toBeCalledWith( - axiosMock.object(), - expect.objectContaining({ - requestId: "1", - }) - )); - expect(rejectCallback).not.toBeCalled(); - }); -}); diff --git a/src/legal-officer/ProtectionRequests.css b/src/legal-officer/ProtectionRequests.css deleted file mode 100644 index 4de5fcdd..00000000 --- a/src/legal-officer/ProtectionRequests.css +++ /dev/null @@ -1,3 +0,0 @@ -.ProtectionRequests .Tabs { - margin-bottom: 50px; -} diff --git a/src/legal-officer/ProtectionRequests.test.tsx b/src/legal-officer/ProtectionRequests.test.tsx deleted file mode 100644 index f1578116..00000000 --- a/src/legal-officer/ProtectionRequests.test.tsx +++ /dev/null @@ -1,10 +0,0 @@ -jest.mock("../common/CommonContext"); - -import React from 'react'; -import ProtectionRequests from './ProtectionRequests'; -import { shallowRender } from '../tests'; - -test('renders', () => { - const tree = shallowRender(); - expect(tree).toMatchSnapshot(); -}); diff --git a/src/legal-officer/ProtectionRequests.tsx b/src/legal-officer/ProtectionRequests.tsx deleted file mode 100644 index d7c0a55e..00000000 --- a/src/legal-officer/ProtectionRequests.tsx +++ /dev/null @@ -1,53 +0,0 @@ -import { useState } from 'react'; -import { useLocation } from 'react-router-dom'; - -import Tabs from '../common/Tabs'; -import { FullWidthPane } from '../common/Dashboard'; -import Frame from '../common/Frame'; - -import PendingProtectionRequests from './PendingProtectionRequests'; -import ProtectionRequestsHistory from './ProtectionRequestsHistory'; -import ProtectedUsers from "./ProtectedUsers"; - -import './ProtectionRequests.css'; -import { getQueryParam } from '../common/QueryString'; - -export default function ProtectionRequests() { - const location = useLocation(); - const [ tabKey, setTabKey ] = useState(getQueryParam(location, "tab") || "pending"); - - return ( - - setTabKey(key || 'pending') } - tabs={[ - { - key: "pending", - title: "Pending", - render: () => - }, - { - key: "history", - title: "History", - render: () => - } - ]} - /> - -

Activated User Account Protection under my watch

- - - -
- ); -} diff --git a/src/legal-officer/ProtectionRequestsHistory.test.tsx b/src/legal-officer/ProtectionRequestsHistory.test.tsx deleted file mode 100644 index 35df1ba3..00000000 --- a/src/legal-officer/ProtectionRequestsHistory.test.tsx +++ /dev/null @@ -1,19 +0,0 @@ -jest.mock('./LegalOfficerContext'); -jest.mock('../logion-chain'); -jest.mock('./Model'); - -import { shallowRender } from '../tests'; -import ProtectionRequestsHistory from './ProtectionRequestsHistory'; -import { setProtectionRequestsHistory } from './__mocks__/LegalOfficerContextMock'; -import { PROTECTION_REQUESTS_HISTORY } from './TestData'; - -test("Renders null with no data", () => { - const tree = shallowRender(); - expect(tree).toMatchSnapshot(); -}); - -test("Renders requests history", () => { - setProtectionRequestsHistory(PROTECTION_REQUESTS_HISTORY); - const tree = shallowRender(); - expect(tree).toMatchSnapshot(); -}); diff --git a/src/legal-officer/ProtectionRequestsHistory.tsx b/src/legal-officer/ProtectionRequestsHistory.tsx deleted file mode 100644 index 2b6e0481..00000000 --- a/src/legal-officer/ProtectionRequestsHistory.tsx +++ /dev/null @@ -1,66 +0,0 @@ -import React from 'react'; - -import Table, { Cell, EmptyTableMessage, DateTimeCell, CopyPasteCell } from '../common/Table'; - -import { useLegalOfficerContext } from './LegalOfficerContext'; -import ProtectionRequestStatus from './ProtectionRequestStatus'; -import ProtectionRequestDetails from './ProtectionRequestDetails'; -import Button from "../common/Button"; -import { identityLocDetailsPath } from "./LegalOfficerPaths"; -import { useNavigate } from "react-router-dom"; - -export default function ProtectionRequestsHistory() { - const { protectionRequestsHistory } = useLegalOfficerContext(); - const navigate = useNavigate(); - - if (protectionRequestsHistory === null) { - return null; - } - - return ( - <> - , - width: "200px", - align: 'left', - }, - { - header: "Last name", - render: request => , - width: "200px", - renderDetails: request => , - align: 'left', - }, - { - header: "Status", - render: request => , - width: "170px", - splitAfter: true, - }, - { - header: "Submission date", - render: request => , - width: "120px", - smallerText: true, - }, - { - header: "Account number", - render: request => , - align: 'left', - }, - { - header: "Action", - render: request => , - width: "180px", - align: 'center', - }, - ]} - data={ protectionRequestsHistory } - renderEmpty={ () => No processed request} - /> - - ); -} diff --git a/src/legal-officer/RecoveryDetails.tsx b/src/legal-officer/RecoveryDetails.tsx index 6ef72ab8..5fe716d1 100644 --- a/src/legal-officer/RecoveryDetails.tsx +++ b/src/legal-officer/RecoveryDetails.tsx @@ -61,10 +61,11 @@ export default function RecoveryDetails() { const currentAddress = accounts!.current!.accountId.address; const lost = recoveryInfo!.accountToRecover!.requesterAddress; const rescuer = recoveryInfo!.recoveryAccount.requesterAddress; - await acceptProtectionRequest(axiosFactory!(currentAddress)!, { - requestId: requestId!, - }); + if (await alreadyVouched(lost, rescuer, currentAddress)) { + await acceptProtectionRequest(axiosFactory!(currentAddress)!, { + requestId: requestId!, + }); refreshRequests!(false); navigate(RECOVERY_REQUESTS_PATH); } else { @@ -77,7 +78,10 @@ export default function RecoveryDetails() { signerId: currentAddress, submittable, callback, - }) + }); + await acceptProtectionRequest(axiosFactory!(currentAddress)!, { + requestId: requestId!, + }); }; try { await submitCall(call); diff --git a/src/legal-officer/__snapshots__/ContextualizedWallet.test.tsx.snap b/src/legal-officer/__snapshots__/ContextualizedWallet.test.tsx.snap index 8106d0c8..e2d8df37 100644 --- a/src/legal-officer/__snapshots__/ContextualizedWallet.test.tsx.snap +++ b/src/legal-officer/__snapshots__/ContextualizedWallet.test.tsx.snap @@ -24,22 +24,6 @@ exports[`renders 1`] = ` } menuMiddle={ Array [ - Object { - "disabled": false, - "exact": true, - "icon": Object { - "height": "auto", - "icon": Object { - "hasVariants": true, - "id": "shield", - }, - "width": "60px", - }, - "id": "protection", - "onClick": [Function], - "text": "Protection Management", - "to": "/legal-officer/protection", - }, Object { "disabled": false, "exact": true, diff --git a/src/legal-officer/__snapshots__/LegalOfficerRouter.test.tsx.snap b/src/legal-officer/__snapshots__/LegalOfficerRouter.test.tsx.snap index 3ea5dfb5..01ee0d40 100644 --- a/src/legal-officer/__snapshots__/LegalOfficerRouter.test.tsx.snap +++ b/src/legal-officer/__snapshots__/LegalOfficerRouter.test.tsx.snap @@ -2,10 +2,6 @@ exports[`renders 1`] = ` - } - path="/protection" - /> } path="/vault" diff --git a/src/legal-officer/__snapshots__/PendingProtectionRequests.test.tsx.snap b/src/legal-officer/__snapshots__/PendingProtectionRequests.test.tsx.snap deleted file mode 100644 index dbc466d4..00000000 --- a/src/legal-officer/__snapshots__/PendingProtectionRequests.test.tsx.snap +++ /dev/null @@ -1,80 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`PendingProtectionRequests Renders null with no data 1`] = `null`; - -exports[`PendingProtectionRequests Renders pending requests 1`] = ` - -
- -`; diff --git a/src/legal-officer/__snapshots__/ProtectionRequests.test.tsx.snap b/src/legal-officer/__snapshots__/ProtectionRequests.test.tsx.snap deleted file mode 100644 index 4fd40486..00000000 --- a/src/legal-officer/__snapshots__/ProtectionRequests.test.tsx.snap +++ /dev/null @@ -1,41 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`renders 1`] = ` - - -

- Activated User Account Protection under my watch -

- - - -
-`; diff --git a/src/legal-officer/__snapshots__/ProtectionRequestsHistory.test.tsx.snap b/src/legal-officer/__snapshots__/ProtectionRequestsHistory.test.tsx.snap deleted file mode 100644 index 2f9ef931..00000000 --- a/src/legal-officer/__snapshots__/ProtectionRequestsHistory.test.tsx.snap +++ /dev/null @@ -1,83 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Renders null with no data 1`] = `null`; - -exports[`Renders requests history 1`] = ` - -
- -`; diff --git a/src/loc/issuer/IssuerSelectionFrame.tsx b/src/loc/issuer/IssuerSelectionFrame.tsx index 040aaa62..e4a0dfee 100644 --- a/src/loc/issuer/IssuerSelectionFrame.tsx +++ b/src/loc/issuer/IssuerSelectionFrame.tsx @@ -20,7 +20,6 @@ export default function IssuerSelectionFrame() { if (locState !== null && (locState instanceof OpenLoc || locState instanceof ClosedCollectionLoc)) { (async function() { const issuers = await locState.legalOfficer.getVerifiedIssuers(); - console.log(issuers) setIssuerSelections(issuers); })(); } diff --git a/src/vault/VaultOutRequest.tsx b/src/vault/VaultOutRequest.tsx index 272d7a5e..5b1d5878 100644 --- a/src/vault/VaultOutRequest.tsx +++ b/src/vault/VaultOutRequest.tsx @@ -33,7 +33,7 @@ export default function VaultOutRequest() { useEffect(() => { if(availableLegalOfficers && protectionState) { - const protectingLegalOfficers = protectionState.protectionParameters.states.map(state => state.legalOfficer.address); + const protectingLegalOfficers = protectionState.protectionParameters.legalOfficers.map(legalOfficer => legalOfficer.address); setCandidates(availableLegalOfficers.filter(legalOfficer => protectingLegalOfficers.includes(legalOfficer.address))); } }, [ accounts, api, availableLegalOfficers, setCandidates, protectionState ]); diff --git a/src/wallet-user/UserContext.tsx b/src/wallet-user/UserContext.tsx index 10407158..e3469100 100644 --- a/src/wallet-user/UserContext.tsx +++ b/src/wallet-user/UserContext.tsx @@ -11,7 +11,7 @@ import { SignCallback, AcceptedProtection, PendingRecovery, - RejectedProtection, + RejectedRecovery, } from "@logion/client"; import { VaultState } from "@logion/client"; @@ -27,7 +27,7 @@ import { UUID } from "@logion/node-api"; export interface CreateProtectionRequestParams { legalOfficers: LegalOfficerClass[], addressToRecover?: string, - callback?: SignCallback, + callback: SignCallback, requesterIdentityLoc1: UUID, requesterIdentityLoc2: UUID, } @@ -41,7 +41,6 @@ export interface UserContext { claimRecovery: ((callback: SignCallback) => Promise) | null, cancelProtection: () => Promise, resubmitProtection: (legalOfficer: LegalOfficer) => Promise, - changeProtectionLegalOfficer: (legalOfficer: LegalOfficer, newLegalOfficer: LegalOfficer, newIdentityLoc: UUID) => Promise protectionState?: ProtectionState, vaultState?: VaultState, mutateVaultState: (mutator: (current: VaultState) => Promise) => Promise, @@ -67,7 +66,6 @@ function initialContextValue(): FullUserContext { claimRecovery: null, cancelProtection: () => Promise.reject(), resubmitProtection: () => Promise.reject(), - changeProtectionLegalOfficer: () => Promise.reject(), mutateVaultState: () => Promise.reject(), mutateRecoveredVaultState: () => Promise.reject(), mutateRecoveredBalanceState: () => Promise.reject(), @@ -243,11 +241,6 @@ const reducer: Reducer = (state: FullUserContext, actio ...state, resubmitProtection: action.resubmitProtection!, } - case "SET_PROTECTION_CHANGE_LO": - return { - ...state, - changeProtectionLegalOfficer: action.changeProtectionLegalOfficer! - } default: /* istanbul ignore next */ throw new Error(`Unknown type: ${action.type}`); @@ -362,11 +355,15 @@ export function UserContextProvider(props: Props) { signer: signer!, }); } else { - pending = await protectionState.requestProtection({ - legalOfficer1: params.legalOfficers[0], - legalOfficer2: params.legalOfficers[1], - requesterIdentityLoc1: params.requesterIdentityLoc1, - requesterIdentityLoc2: params.requesterIdentityLoc2, + pending = await protectionState.activateProtection({ + payload: { + legalOfficer1: params.legalOfficers[0], + legalOfficer2: params.legalOfficers[1], + requesterIdentityLoc1: params.requesterIdentityLoc1, + requesterIdentityLoc2: params.requesterIdentityLoc2, + }, + callback: params.callback, + signer: signer!, }); } dispatch({ @@ -508,7 +505,7 @@ export function UserContextProvider(props: Props) { }, [ mutateLocsStateCallback, contextValue.mutateLocsState ]); const cancelProtectionCallback = useCallback(async () => { - const rejectedProtection = contextValue.protectionState as RejectedProtection; + const rejectedProtection = contextValue.protectionState as RejectedRecovery; const noProtection = await rejectedProtection.cancel(); dispatch({ type: "REFRESH_PROTECTION_STATE", @@ -517,7 +514,7 @@ export function UserContextProvider(props: Props) { }, [ contextValue.protectionState ]) const resubmitProtectionCallback = useCallback(async (legalOfficer: LegalOfficer) => { - const rejectedProtection = contextValue.protectionState as RejectedProtection; + const rejectedProtection = contextValue.protectionState as RejectedRecovery; const pendingProtection = await rejectedProtection.resubmit(legalOfficer); dispatch({ type: "REFRESH_PROTECTION_STATE", @@ -525,15 +522,6 @@ export function UserContextProvider(props: Props) { }) }, [ contextValue.protectionState ]) - const changeProtectionLegalOfficerCallback = useCallback(async (legalOfficer: LegalOfficer, newLegalOfficer: LegalOfficer, newIdentityLoc: UUID) => { - const rejectedProtection = contextValue.protectionState as RejectedProtection; - const pendingProtection = await rejectedProtection.changeLegalOfficer(legalOfficer, newLegalOfficer, newIdentityLoc); - dispatch({ - type: "REFRESH_PROTECTION_STATE", - protectionState: pendingProtection - }) - }, [ contextValue.protectionState ]) - useEffect(() => { if (contextValue.cancelProtection !== cancelProtectionCallback) { dispatch({ @@ -552,15 +540,6 @@ export function UserContextProvider(props: Props) { } }, [ contextValue.resubmitProtection, resubmitProtectionCallback ]); - useEffect(() => { - if (contextValue.changeProtectionLegalOfficer !== changeProtectionLegalOfficerCallback) { - dispatch({ - type: "SET_PROTECTION_CHANGE_LO", - changeProtectionLegalOfficer: changeProtectionLegalOfficerCallback - }); - } - }, [ contextValue.changeProtectionLegalOfficer, changeProtectionLegalOfficerCallback ]); - return ( { props.children } diff --git a/src/wallet-user/trust-protection/CreateProtectionRequestForm.test.tsx b/src/wallet-user/trust-protection/CreateProtectionRequestForm.test.tsx index 0db9f92e..a13f03ed 100644 --- a/src/wallet-user/trust-protection/CreateProtectionRequestForm.test.tsx +++ b/src/wallet-user/trust-protection/CreateProtectionRequestForm.test.tsx @@ -35,7 +35,7 @@ describe("CreateProtectionRequestForm", () => { await selectLegalOfficers(); - await clickByName("Submit request"); + await clickByName("Proceed"); await waitFor(() => expect(createProtectionRequest).toBeCalledWith( expect.objectContaining({ @@ -52,7 +52,7 @@ describe("CreateProtectionRequestForm", () => { await selectLegalOfficers(); - await clickByName("Submit request"); + await clickByName("Proceed"); await waitFor(() => expect(createProtectionRequest).toBeCalledWith( expect.objectContaining({ @@ -71,7 +71,7 @@ describe("CreateProtectionRequestForm", () => { await selectLegalOfficers(); - await clickByName("Submit request"); + await clickByName("Proceed"); await waitFor(() => expect(createProtectionRequest).toBeCalledWith( expect.objectContaining({ diff --git a/src/wallet-user/trust-protection/CreateProtectionRequestForm.tsx b/src/wallet-user/trust-protection/CreateProtectionRequestForm.tsx index 941c1ea2..391b584c 100644 --- a/src/wallet-user/trust-protection/CreateProtectionRequestForm.tsx +++ b/src/wallet-user/trust-protection/CreateProtectionRequestForm.tsx @@ -1,3 +1,4 @@ +import { LocsState, LogionClient } from "@logion/client"; import { useState, useEffect, useMemo, useCallback } from 'react'; import { Row, Col } from "react-bootstrap"; import Form from "react-bootstrap/Form"; @@ -18,9 +19,24 @@ import LegalOfficers from './LegalOfficers'; import './CreateProtectionRequestForm.css'; import { LegalOfficerAndLoc } from './SelectLegalOfficerAndLoc'; -import { getLegalOfficerAndLocs } from './ProtectionRefusal'; import ExtrinsicSubmissionStateView from 'src/ExtrinsicSubmissionStateView'; +export function getLegalOfficerAndLocs(locsState: LocsState | undefined, client: LogionClient | null) { + if(locsState && client) { + const closedIdentityLocs = locsState.closedLocs["Identity"]; + const list: LegalOfficerAndLoc[] = []; + for(const loc of closedIdentityLocs) { + list.push({ + loc: loc.locId, + legalOfficer: client.getLegalOfficer(loc.data().ownerAddress), + }); + } + return list; + } else { + return []; + } +} + export interface Props { isRecovery: boolean, } @@ -47,34 +63,23 @@ export default function CreateProtectionRequestForm(props: Props) { return; } - if(props.isRecovery) { - const call = async (callback: CallCallback) => { - await createProtectionRequest!({ - legalOfficers: [ - legalOfficer1!.legalOfficer, - legalOfficer2!.legalOfficer, - ], - addressToRecover, - callback, - requesterIdentityLoc1: legalOfficer1!.loc, - requesterIdentityLoc2: legalOfficer2!.loc, - }); - }; - try { - await submitCall(call); - } finally { - clearSubmissionState(); - } - } else { + const call = async (callback: CallCallback) => { await createProtectionRequest!({ legalOfficers: [ legalOfficer1!.legalOfficer, legalOfficer2!.legalOfficer, ], - addressToRecover: undefined, + addressToRecover: props.isRecovery ? addressToRecover : undefined, + callback, requesterIdentityLoc1: legalOfficer1!.loc, requesterIdentityLoc2: legalOfficer2!.loc, }); + }; + + try { + await submitCall(call); + } finally { + clearSubmissionState(); } }, [ legalOfficer1, legalOfficer2, addressToRecover, props.isRecovery, createProtectionRequest, submitCall, clearSubmissionState, canSubmit ]); @@ -205,9 +210,9 @@ export default function CreateProtectionRequestForm(props: Props) { extrinsicSubmissionState.canSubmit() && canSubmit && } diff --git a/src/wallet-user/trust-protection/ProtectionRecoveryRequest.tsx b/src/wallet-user/trust-protection/ProtectionRecoveryRequest.tsx index 2bd9b919..c7e6f465 100644 --- a/src/wallet-user/trust-protection/ProtectionRecoveryRequest.tsx +++ b/src/wallet-user/trust-protection/ProtectionRecoveryRequest.tsx @@ -4,8 +4,7 @@ import { LegalOfficer, PendingProtection, UnavailableProtection, - RejectedProtection, - RejectedRecovery, ProtectionState + RejectedRecovery, } from "@logion/client"; import { useLogionChain } from '../../logion-chain'; @@ -25,7 +24,6 @@ import SelectLegalOfficer from './SelectLegalOfficer'; import './ProtectionRecoveryRequest.css'; import { ProtectionRequestStatus } from '@logion/client/dist/RecoveryClient.js'; -import ProtectionRefusal from "./ProtectionRefusal"; import RecoveryRefusal from "./RecoveryRefusal"; import ButtonGroup from "../../common/ButtonGroup"; import ExtrinsicSubmissionStateView from 'src/ExtrinsicSubmissionStateView'; @@ -65,11 +63,11 @@ export default function ProtectionRecoveryRequest(props: Props) { if(props.type !== 'unavailable') { const protectionParameters = protectionState.protectionParameters; - const legalOfficer1: LegalOfficer = protectionParameters.states[0].legalOfficer; - const legalOfficer2: LegalOfficer = protectionParameters.states[1].legalOfficer; + const legalOfficer1: LegalOfficer = protectionParameters.legalOfficers[0]; + const legalOfficer2: LegalOfficer = protectionParameters.legalOfficers[1]; let legalOfficer1Status: ProtectionRequestStatus; let legalOfficer2Status: ProtectionRequestStatus; - if(protectionState instanceof PendingProtection || protectionState instanceof RejectedProtection || protectionState instanceof RejectedRecovery) { + if(protectionState instanceof PendingProtection || protectionState instanceof RejectedRecovery) { legalOfficer1Status = protectionParameters.states[0].status; legalOfficer2Status = protectionParameters.states[1].status; } else if(props.type === 'accepted') { @@ -205,6 +203,7 @@ export default function ProtectionRecoveryRequest(props: Props) { @@ -216,6 +215,7 @@ export default function ProtectionRecoveryRequest(props: Props) { @@ -226,11 +226,10 @@ export default function ProtectionRecoveryRequest(props: Props) { { refusal === 'double' && - + } @@ -248,9 +247,8 @@ export default function ProtectionRecoveryRequest(props: Props) { { refusal === 'single' && - } @@ -327,31 +325,6 @@ export default function ProtectionRecoveryRequest(props: Props) { } } -interface RefusalProps { - isRecovery: boolean - protectionState: ProtectionState - refusal: Refusal -} - -function RefusalBox(props: RefusalProps) { - const { isRecovery, protectionState, refusal } = props - if (!isRecovery) { - return ( - - ) - } else { - return ( - - ) - } -} - interface HeaderProps { color: string; icon: string; diff --git a/src/wallet-user/trust-protection/ProtectionRefusal.css b/src/wallet-user/trust-protection/ProtectionRefusal.css deleted file mode 100644 index eac6cb35..00000000 --- a/src/wallet-user/trust-protection/ProtectionRefusal.css +++ /dev/null @@ -1,19 +0,0 @@ -.ProtectionRefusal .Title { - text-align: center; - margin: 20px; -} - -.ProtectionRefusal .Button { - margin: 15px; -} - -.ProtectionRefusal .select, -.ProtectionRefusal .restart { - display: flex; - width: 100%; - flex-wrap: wrap; -} - -.ProtectionRefusal .ButtonGroup { - width: auto; -} diff --git a/src/wallet-user/trust-protection/ProtectionRefusal.tsx b/src/wallet-user/trust-protection/ProtectionRefusal.tsx deleted file mode 100644 index faebd71e..00000000 --- a/src/wallet-user/trust-protection/ProtectionRefusal.tsx +++ /dev/null @@ -1,131 +0,0 @@ -import { RejectedProtection, LocsState, LogionClient } from "@logion/client"; -import Button from "../../common/Button"; -import { useUserContext } from "../UserContext"; -import { useMemo, useState } from "react"; -import SelectLegalOfficerAndLoc, { LegalOfficerAndLoc } from "./SelectLegalOfficerAndLoc"; -import { useCommonContext } from "../../common/CommonContext"; -import './ProtectionRefusal.css'; -import { RED } from "../../common/ColorTheme"; -import ButtonGroup from "../../common/ButtonGroup"; -import { LegalOfficerProtectionState } from "@logion/client/dist/Recovery.js"; -import { Refusal } from "./ProtectionRecoveryRequest"; -import { useLogionChain } from "src/logion-chain"; - -export function getLegalOfficerAndLocs(locsState: LocsState | undefined, client: LogionClient | null) { - if(locsState && client) { - const closedIdentityLocs = locsState.closedLocs["Identity"]; - const list: LegalOfficerAndLoc[] = []; - for(const loc of closedIdentityLocs) { - list.push({ - loc: loc.locId, - legalOfficer: client.getLegalOfficer(loc.data().ownerAddress), - }); - } - return list; - } else { - return []; - } -} - -export interface Props { - protection: RejectedProtection - refusal: Refusal -} - -export default function ProtectionRefusal(props: Props) { - const { protection, refusal } = props; - const { cancelProtection, resubmitProtection, changeProtectionLegalOfficer } = useUserContext() - const rejectedState = protection.protectionParameters.states[0]; - const currentLegalOfficer = rejectedState.legalOfficer; - const [ legalOfficerAndLoc, setLegalOfficerAndLoc ] = useState(null) - const otherState = protection.protectionParameters.states[1]; - const otherLegalOfficerAndLoc = { - legalOfficer: otherState.legalOfficer, - loc: otherState.identityLoc, - } - const { availableLegalOfficers } = useCommonContext(); - const { locsState } = useUserContext(); - const { client } = useLogionChain(); - - const legalOfficersAndLocs = useMemo(() => getLegalOfficerAndLocs(locsState, client), [ locsState, client ]); - - if (!availableLegalOfficers || !locsState) { - return null - } - - function reasonBox(state: LegalOfficerProtectionState) { - const legalOfficer = state.legalOfficer; - const reason = state.decision.rejectReason; - return ( -

- { legalOfficer.name }:
- «{ reason }» -

- ) - } - - return ( -
-

Protection Refusal

- { refusal === 'single' && - <> -

The Legal Officer { currentLegalOfficer.name } did not accept your protection request due to - the - following reason:

-

«{ rejectedState.decision.rejectReason }»

-

Please contact { currentLegalOfficer.name } for more details and select one of the following next - steps:

- - } - { refusal === 'double' && - <> -

Two Legal Officers - { currentLegalOfficer.name } and { otherLegalOfficerAndLoc.legalOfficer.name } - did not accept - your protection request due to the following reasons:

- { reasonBox(rejectedState) } - { reasonBox(otherState) } -

Please contact { currentLegalOfficer.name } and { otherLegalOfficerAndLoc.legalOfficer.name } for more details and select the following next - step:

- - } -
- - - - { refusal === 'single' && - - - - } -
- { refusal === 'single' && - <> -
Or select another Legal Officer for your protection:
-
- - - - -
- - } -
- ) -} diff --git a/src/wallet-user/trust-protection/TrustProtection.tsx b/src/wallet-user/trust-protection/TrustProtection.tsx index ce02c317..961e71ce 100644 --- a/src/wallet-user/trust-protection/TrustProtection.tsx +++ b/src/wallet-user/trust-protection/TrustProtection.tsx @@ -1,9 +1,6 @@ import { - AcceptedProtection, NoProtection, - PendingProtection, UnavailableProtection, - RejectedProtection } from "@logion/client"; import { useUserContext } from "../UserContext"; @@ -43,12 +40,6 @@ export default function TrustProtection() { return ; } else if(protectionState.protectionParameters.isActive) { return ; - } else if(protectionState instanceof PendingProtection) { - return ; - } else if(protectionState instanceof AcceptedProtection) { - return ; - } else if (protectionState instanceof RejectedProtection) { - return ; } else { return null; } diff --git a/src/wallet-user/trust-protection/__snapshots__/ProtectionRecoveryRequest.test.tsx.snap b/src/wallet-user/trust-protection/__snapshots__/ProtectionRecoveryRequest.test.tsx.snap index 4a851d8a..35410b88 100644 --- a/src/wallet-user/trust-protection/__snapshots__/ProtectionRecoveryRequest.test.tsx.snap +++ b/src/wallet-user/trust-protection/__snapshots__/ProtectionRecoveryRequest.test.tsx.snap @@ -407,6 +407,7 @@ exports[`ProtectionRecoveryRequest activated recovery request 1`] = ` @@ -1174,6 +1175,7 @@ exports[`ProtectionRecoveryRequest pending recovery request 1`] = ` diff --git a/src/wallet-user/trust-protection/__snapshots__/TrustProtection.test.tsx.snap b/src/wallet-user/trust-protection/__snapshots__/TrustProtection.test.tsx.snap index 29c49cd1..662484e3 100644 --- a/src/wallet-user/trust-protection/__snapshots__/TrustProtection.test.tsx.snap +++ b/src/wallet-user/trust-protection/__snapshots__/TrustProtection.test.tsx.snap @@ -1,10 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`renders accepted protection request 1`] = ` - -`; +exports[`renders accepted protection request 1`] = `null`; exports[`renders empty 1`] = ` `; -exports[`renders pending protection request 1`] = ` - -`; +exports[`renders pending protection request 1`] = `null`; exports[`renders protected 1`] = `