diff --git a/package.json b/package.json index 308b7275..93f4f3fa 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ "dependencies": { "@craco/craco": "^6.4.5", "@creativecommons/cc-assets": "^0.1.0", - "@logion/client-browser": "^0.2.0", + "@logion/client-browser": "^0.3.0-4", "@logion/crossmint": "^0.1.29", "@logion/extension": "^0.7.3", "@logion/multiversx": "^0.1.10", diff --git a/src/loc/ImportItems.tsx b/src/loc/ImportItems.tsx index b37921f8..afce4afd 100644 --- a/src/loc/ImportItems.tsx +++ b/src/loc/ImportItems.tsx @@ -80,9 +80,9 @@ export default function ImportItems() { itemFiles: item.files, restrictedDelivery: item.restrictedDelivery, itemToken: item.token, - logionClassification: item.logionClassification, + logionClassification: item.logionClassification?.parameters, specificLicenses: item.specificLicense ? [ item.specificLicense ] : undefined, - creativeCommons: item.creativeCommons, + creativeCommons: item.creativeCommons?.parameters, }); }, [ locState ]); @@ -120,9 +120,9 @@ export default function ImportItems() { itemFiles: item.files, restrictedDelivery: item.restrictedDelivery, itemToken: item.token, - logionClassification: item.logionClassification, + logionClassification: item.logionClassification?.parameters, specificLicenses: item.specificLicense ? [ item.specificLicense ] : undefined, - creativeCommons: item.creativeCommons, + creativeCommons: item.creativeCommons?.parameters, callback, }) }; diff --git a/src/loc/LocContext.test.tsx b/src/loc/LocContext.test.tsx index f169ca59..a2d306e6 100644 --- a/src/loc/LocContext.test.tsx +++ b/src/loc/LocContext.test.tsx @@ -1,5 +1,5 @@ import { AxiosInstance } from "axios"; -import { useCallback, useState } from "react"; +import { useCallback } from "react"; import { render, screen, waitFor } from "@testing-library/react"; import { UUID, LegalOfficerCase, Hash } from '@logion/node-api'; import { @@ -17,8 +17,6 @@ import { LocContextProvider, useLocContext } from "./LocContext" import { buildLocRequest } from "./TestData"; import { setClientMock } from "src/logion-chain/__mocks__/LogionChainMock"; import { LocRequestState, EditableRequest, OpenLoc, ClosedLoc } from "src/__mocks__/LogionClientMock"; -import { useLogionChain } from "src/logion-chain"; -import ClientExtrinsicSubmitter, { Call } from "src/ClientExtrinsicSubmitter"; import { mockValidPolkadotAccountId, api, @@ -60,15 +58,6 @@ describe("LocContext", () => { await clickByName("Go"); await thenItemsDeleted(); }) - - it("voids", async () => { - givenRequest(OPEN_IDENTITY_LOC_ID, OPEN_IDENTITY_LOC, OpenLoc); - resetDefaultMocks(); - whenRenderingInContext(_locState, ); - await clickByName("Go"); - await waitFor(() => expect(screen.getByText("Submitting...")).toBeVisible()); - await thenVoided(); - }) }) function givenRequest(locId: string, loc: LegalOfficerCase, locStateConstructor: new () => T, linkedLocId?: string, linkedLoc?: LegalOfficerCase) { @@ -335,49 +324,3 @@ async function thenItemsDeleted() { expect((_locState as OpenLoc).deleteFile).toBeCalled(); expect((_locState as OpenLoc).deleteLink).toBeCalled(); } - -function Voider() { - const { signer } = useLogionChain(); - const { loc: locData, mutateLocState } = useLocContext(); - const [ call, setCall ] = useState(); - - const callback = useCallback(() => { - const call: Call = async callback => - mutateLocState(async current => { - if(signer && current instanceof OpenLoc) { - return current.legalOfficer.voidLoc({ - locState: current, - voidInfo: { - reason: "Some reason" - }, - signer, - callback, - }); - } else { - return current; - } - }); - setCall(() => call); - }, [ mutateLocState ]); - - if(!locData) { - return null; - } - - return ( -
- -

{ locData.voidInfo ? "Voided" : "-" }

- {} } - onError={ () => {} } - /> -
- ); -} - -async function thenVoided() { - expect((_locState as OpenLoc).legalOfficer.voidLoc).toBeCalled(); -} diff --git a/src/loc/issuer/IssuerSelectionCheckbox.tsx b/src/loc/issuer/IssuerSelectionCheckbox.tsx index aba4d6c6..9e06b7db 100644 --- a/src/loc/issuer/IssuerSelectionCheckbox.tsx +++ b/src/loc/issuer/IssuerSelectionCheckbox.tsx @@ -3,8 +3,8 @@ import { useCallback, useMemo, useState } from "react"; import { OpenLoc, ClosedCollectionLoc, VerifiedIssuerWithSelect } from "@logion/client"; import { useLocContext } from "../LocContext"; import Dialog from "../../common/Dialog"; -import ClientExtrinsicSubmitter, { Call, CallCallback } from "src/ClientExtrinsicSubmitter"; -import { useLogionChain } from "src/logion-chain"; +import { CallCallback, useLogionChain } from "src/logion-chain"; +import ExtrinsicSubmissionStateView from "src/ExtrinsicSubmissionStateView"; export interface Props { issuerSelection: VerifiedIssuerWithSelect @@ -14,11 +14,15 @@ type Status = 'Idle' | 'Selected' | 'Confirming' | 'Error'; export default function IssuerSelectionCheckbox(props: Props) { const { issuerSelection } = props; - const { signer } = useLogionChain(); + const { signer, submitCall, clearSubmissionState } = useLogionChain(); const { mutateLocState } = useLocContext(); const [ status, setStatus ] = useState('Idle'); const [ showUnselect, setShowUnselect ] = useState(false); - const [ call, setCall ] = useState(); + + const clearState = useCallback(async () => { + setStatus('Idle'); + clearSubmissionState(); + }, [ clearSubmissionState ]); const toggleSelection = useCallback(async () => { setStatus('Confirming'); @@ -39,13 +43,13 @@ export default function IssuerSelectionCheckbox(props: Props) { return current; } }); - setCall(() => call); - }, [ mutateLocState, issuerSelection, signer ]); - - const clearState = useCallback(async () => { - setStatus('Idle'); - setCall(undefined); - }, []); + try { + await submitCall(call); + clearState(); + } catch(e) { + setStatus('Error'); + } + }, [ mutateLocState, issuerSelection, signer, submitCall, clearState ]); const issuerName = useMemo(() => `${ issuerSelection.firstName } ${ issuerSelection.lastName }`, [issuerSelection]); @@ -96,11 +100,7 @@ export default function IssuerSelectionCheckbox(props: Props) {

Do you confirm you want to cancel the status of { issuerName } as a Verified Issuer for this LOC?

} - setStatus('Error')} - /> + ) } diff --git a/src/loc/issuer/IssuerSelectionFrame.tsx b/src/loc/issuer/IssuerSelectionFrame.tsx index e4a0dfee..040aaa62 100644 --- a/src/loc/issuer/IssuerSelectionFrame.tsx +++ b/src/loc/issuer/IssuerSelectionFrame.tsx @@ -20,6 +20,7 @@ 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/loc/issuer/Nominate.tsx b/src/loc/issuer/Nominate.tsx index e94983cb..6e8867e7 100644 --- a/src/loc/issuer/Nominate.tsx +++ b/src/loc/issuer/Nominate.tsx @@ -4,21 +4,25 @@ import Button from "../../common/Button"; import Icon from "../../common/Icon"; import Dialog from "../../common/Dialog"; import { useLocContext } from "../LocContext"; -import { useLogionChain } from "../../logion-chain"; +import { CallCallback, useLogionChain } from "../../logion-chain"; import { ClosedLoc } from "@logion/client"; import './Nominate.css'; -import ClientExtrinsicSubmitter, { Call, CallCallback } from "src/ClientExtrinsicSubmitter"; +import ExtrinsicSubmissionStateView from "src/ExtrinsicSubmissionStateView"; type Status = 'Idle' | 'Selected' | 'Confirming' | 'Error'; export default function Nominate() { const { loc, mutateLocState } = useLocContext(); - const { signer } = useLogionChain(); + const { signer, submitCall, clearSubmissionState } = useLogionChain(); const [ status, setStatus ] = useState('Idle'); - const [ call, setCall ] = useState(); const isIssuer = useMemo(() => loc?.verifiedIssuer || false, [ loc ]); + const clearState = useCallback(async () => { + setStatus('Idle'); + clearSubmissionState(); + }, [ clearSubmissionState ]); + const changeIssuer = useCallback(async () => { setStatus('Confirming'); const call = async (callback: CallCallback) => mutateLocState(async current => { @@ -38,13 +42,13 @@ export default function Nominate() { return current; } }); - setCall(() => call); - }, [ mutateLocState, isIssuer, signer ]); - - const clearState = useCallback(async () => { - setStatus('Idle'); - setCall(undefined); - }, []); + try { + await submitCall(call); + clearState(); + } catch(e) { + setStatus("Error"); + } + }, [ mutateLocState, isIssuer, signer, clearState, submitCall ]); return ( <> @@ -92,11 +96,7 @@ export default function Nominate() { (s)he is currently involved with.

Do you confirm you want to cancel the Verified Issuer status for this person?

} - setStatus('Error')} - /> + ) diff --git a/src/loc/record/AddTokensRecordDialog.tsx b/src/loc/record/AddTokensRecordDialog.tsx index 5c27926b..c3077658 100644 --- a/src/loc/record/AddTokensRecordDialog.tsx +++ b/src/loc/record/AddTokensRecordDialog.tsx @@ -2,18 +2,18 @@ import { HashOrContent, TokensRecord, ClosedCollectionLoc } from "@logion/client import { useCallback, useState } from "react"; import { Form, Spinner } from "react-bootstrap"; import { Controller, useForm } from "react-hook-form"; -import ClientExtrinsicSubmitter, { Call, CallCallback } from "src/ClientExtrinsicSubmitter"; import Alert from "src/common/Alert"; import { useCommonContext } from "src/common/CommonContext"; import Dialog from "src/common/Dialog"; import FileSelectorButton from "src/common/FileSelectorButton"; import FormGroup from "src/common/FormGroup"; import Icon from "src/common/Icon"; -import { useLogionChain } from "src/logion-chain"; +import { CallCallback, useLogionChain } from "src/logion-chain"; import { useLocContext } from "../LocContext"; import { BrowserFile } from "@logion/client-browser"; import EstimatedFees from "../fees/EstimatedFees"; import { Fees } from "@logion/node-api"; +import ExtrinsicSubmissionStateView from "src/ExtrinsicSubmissionStateView"; export interface Props { show: boolean; @@ -32,12 +32,11 @@ type Status = 'Idle' | 'Hashing' | 'Confirming' | 'Uploading' | 'Error'; export default function AddTokensRecordDialog(props: Props) { const { colorTheme } = useCommonContext(); const { mutateLocState, locState } = useLocContext(); - const { signer } = useLogionChain(); + const { signer, submitCall, clearSubmissionState } = useLogionChain(); const { control, handleSubmit, formState: { errors }, reset, setValue, getValues } = useForm(); const [ file, setFile ] = useState(); const [ uploadError, setUploadError ] = useState(); const [ status, setStatus ] = useState('Idle'); - const [ call, setCall ] = useState(); const [ fees, setFees ] = useState(null); const [ content, setContent ] = useState(); @@ -53,14 +52,14 @@ export default function AddTokensRecordDialog(props: Props) { }, []); const clear = useCallback(() => { - setCall(undefined); + clearSubmissionState(); setStatus('Idle'); setUploadError(""); setFees(null); setContent(undefined); reset(); props.hide(); - }, [ props, reset ]); + }, [ props, reset, clearSubmissionState ]); const estimateFees = useCallback(async (formValues: FormValues) => { setUploadError("") @@ -94,31 +93,31 @@ export default function AddTokensRecordDialog(props: Props) { setUploadError("") if (content) { const hash = content.contentHash; - setStatus('Uploading') + setStatus('Uploading'); + const call = async (callback: CallCallback) => await mutateLocState(async current => { + if (signer && current instanceof ClosedCollectionLoc) { + const formValues = getValues(); + await current.addTokensRecord({ + recordId: hash, + description: formValues.description, + files: [ content ], + signer, + callback, + }); + const currentLoc = current.getCurrentState() as ClosedCollectionLoc; + return currentLoc.refresh(); + } else { + return current; + } + }); try { - const call: Call = async (callback: CallCallback) => await mutateLocState(async current => { - if (signer && current instanceof ClosedCollectionLoc) { - const formValues = getValues(); - await current.addTokensRecord({ - recordId: hash, - description: formValues.description, - files: [ content ], - signer, - callback, - }); - const currentLoc = current.getCurrentState() as ClosedCollectionLoc; - return currentLoc.refresh(); - } else { - return current; - } - }); - setCall(() => call); - } catch (error: any) { - const errorMessage = error?.response?.data?.errorMessage; - onError(`${ error }: ${ errorMessage }`); + await submitCall(call); + clear(); + } catch (error) { + onError(); } } - }, [ mutateLocState, onError, signer, getValues, content ]); + }, [ mutateLocState, onError, signer, getValues, content, submitCall, clear ]); return (<> } - onError()} - onSuccess={clear} - /> +