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

Fix VI nomination/dismiss/select/unselect and tokens records submission #537

Merged
merged 1 commit into from
Dec 8, 2023
Merged
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
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
8 changes: 4 additions & 4 deletions src/loc/ImportItems.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 ]);

Expand Down Expand Up @@ -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,
})
};
Expand Down
59 changes: 1 addition & 58 deletions src/loc/LocContext.test.tsx
Original file line number Diff line number Diff line change
@@ -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 {
Expand All @@ -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,
Expand Down Expand Up @@ -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, <Voider/>);
await clickByName("Go");
await waitFor(() => expect(screen.getByText("Submitting...")).toBeVisible());
await thenVoided();
})
})

function givenRequest<T extends LocRequestState>(locId: string, loc: LegalOfficerCase, locStateConstructor: new () => T, linkedLocId?: string, linkedLoc?: LegalOfficerCase) {
Expand Down Expand Up @@ -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<Call>();

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 (
<div>
<button onClick={ callback }>Go</button>
<p>{ locData.voidInfo ? "Voided" : "-" }</p>
<ClientExtrinsicSubmitter
call={ call }
successMessage="Successfully closed"
onSuccess={ () => {} }
onError={ () => {} }
/>
</div>
);
}

async function thenVoided() {
expect((_locState as OpenLoc).legalOfficer.voidLoc).toBeCalled();
}
32 changes: 16 additions & 16 deletions src/loc/issuer/IssuerSelectionCheckbox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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<Status>('Idle');
const [ showUnselect, setShowUnselect ] = useState<boolean>(false);
const [ call, setCall ] = useState<Call>();

const clearState = useCallback(async () => {
setStatus('Idle');
clearSubmissionState();
}, [ clearSubmissionState ]);

const toggleSelection = useCallback(async () => {
setStatus('Confirming');
Expand All @@ -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]);

Expand Down Expand Up @@ -96,11 +100,7 @@ export default function IssuerSelectionCheckbox(props: Props) {
<p>Do you confirm you want to cancel the status of { issuerName } as a Verified Issuer <strong>for
this LOC</strong>?</p>
</> }
<ClientExtrinsicSubmitter
call={call}
onSuccess={clearState}
onError={() => setStatus('Error')}
/>
<ExtrinsicSubmissionStateView />
</Dialog>
</>)
}
1 change: 1 addition & 0 deletions src/loc/issuer/IssuerSelectionFrame.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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);
})();
}
Expand Down
32 changes: 16 additions & 16 deletions src/loc/issuer/Nominate.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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<Status>('Idle');
const [ call, setCall ] = useState<Call>();

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 => {
Expand All @@ -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 (
<>
Expand Down Expand Up @@ -92,11 +96,7 @@ export default function Nominate() {
(s)he is currently involved with.</strong></p>
<p>Do you confirm you want to cancel the Verified Issuer status for this person?</p>
</> }
<ClientExtrinsicSubmitter
call={call}
onSuccess={clearState}
onError={() => setStatus('Error')}
/>
<ExtrinsicSubmissionStateView />
</Dialog>
</>
)
Expand Down
61 changes: 28 additions & 33 deletions src/loc/record/AddTokensRecordDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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<FormValues>();
const [ file, setFile ] = useState<File>();
const [ uploadError, setUploadError ] = useState<string>();
const [ status, setStatus ] = useState<Status>('Idle');
const [ call, setCall ] = useState<Call>();
const [ fees, setFees ] = useState<Fees | null>(null);
const [ content, setContent ] = useState<HashOrContent>();

Expand All @@ -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("")
Expand Down Expand Up @@ -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 (<>
<Dialog
Expand Down Expand Up @@ -238,11 +237,7 @@ export default function AddTokensRecordDialog(props: Props) {
{ uploadError }
</Alert>
}
<ClientExtrinsicSubmitter
call={call}
onError={() => onError()}
onSuccess={clear}
/>
<ExtrinsicSubmissionStateView />
</Dialog>

<Dialog
Expand Down
4 changes: 2 additions & 2 deletions src/logion-chain/LogionChainContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -209,12 +209,12 @@ export class ExtrinsicSubmissionState {
}

isSuccessful(submissionId?: string): boolean {
const error = this.error[submissionId || CallBatch.DEFAULT_SUBMISSION_ID];
const error = this._error[submissionId || CallBatch.DEFAULT_SUBMISSION_ID];
return this._callEnded[submissionId || CallBatch.DEFAULT_SUBMISSION_ID] && error === undefined;
}

isError(submissionId?: string): boolean {
const error = this.error[submissionId || CallBatch.DEFAULT_SUBMISSION_ID];
const error = this._error[submissionId || CallBatch.DEFAULT_SUBMISSION_ID];
return this._callEnded[submissionId || CallBatch.DEFAULT_SUBMISSION_ID] && error !== undefined;
}

Expand Down
Loading
Loading