forked from jsnbuchanan/crowd-funder-for-time-pwa
add ability to confirm give directly from a project
This commit is contained in:
@@ -47,7 +47,7 @@
|
||||
<div class="columns-3">
|
||||
<button
|
||||
class="col-span-1 bg-blue-600 text-white px-4 py-2 rounded-md"
|
||||
v-if="userCanConfirm()"
|
||||
v-if="userCanConfirm(veriClaim, activeDid, confirmerIdList)"
|
||||
@click="confirmClaim(veriClaim.id)"
|
||||
>
|
||||
Confirm
|
||||
@@ -67,7 +67,7 @@
|
||||
:offerId="veriClaim.handleId"
|
||||
/>
|
||||
|
||||
<div v-if="isConfirmable()">
|
||||
<div v-if="isConfirmable(veriClaim)">
|
||||
<h2 class="font-bold uppercase text-xl mt-8 mb-2">Confirmations</h2>
|
||||
|
||||
<span v-if="totalConfirmers() === 0">Nobody has confirmed this.</span>
|
||||
@@ -197,7 +197,6 @@ import { AxiosError, RawAxiosRequestHeaders } from "axios";
|
||||
import * as yaml from "js-yaml";
|
||||
import * as R from "ramda";
|
||||
import { IIdentifier } from "@veramo/core";
|
||||
import * as util from "util";
|
||||
import { Component, Vue } from "vue-facing-decorator";
|
||||
|
||||
import GiftedDialog from "@/components/GiftedDialog.vue";
|
||||
@@ -207,6 +206,7 @@ import { Contact } from "@/db/tables/contacts";
|
||||
import { MASTER_SETTINGS_KEY, Settings } from "@/db/tables/settings";
|
||||
import { accessToken } from "@/libs/crypto";
|
||||
import * as serverUtil from "@/libs/endorserServer";
|
||||
import { isConfirmable, userCanConfirm } from "@/libs/util";
|
||||
import QuickNav from "@/components/QuickNav.vue";
|
||||
import EntityIcon from "@/components/EntityIcon.vue";
|
||||
import { Account } from "@/db/tables/accounts";
|
||||
@@ -239,9 +239,10 @@ export default class ClaimView extends Vue {
|
||||
veriClaim = serverUtil.BLANK_GENERIC_SERVER_RECORD;
|
||||
veriClaimDump = "";
|
||||
|
||||
util = util;
|
||||
yaml = yaml;
|
||||
containsHiddenDid = serverUtil.containsHiddenDid;
|
||||
isConfirmable = isConfirmable;
|
||||
userCanConfirm = userCanConfirm;
|
||||
|
||||
async created() {
|
||||
await db.open();
|
||||
@@ -283,20 +284,6 @@ export default class ClaimView extends Vue {
|
||||
: text[0].toUpperCase() + text.substr(1).replace(/([A-Z])/g, " $1");
|
||||
}
|
||||
|
||||
isConfirmable() {
|
||||
return this.veriClaim.claimType === "GiveAction";
|
||||
}
|
||||
|
||||
userCanConfirm() {
|
||||
// Note that this logic is mirrored in the template. Look for "userCanConfirm"
|
||||
return (
|
||||
this.isConfirmable() &&
|
||||
!this.confirmerIdList.includes(this.activeDid) &&
|
||||
this.veriClaim.issuer !== this.activeDid &&
|
||||
!this.containsHiddenDid(this.veriClaim.claim)
|
||||
);
|
||||
}
|
||||
|
||||
offerGiverDid(): string | undefined {
|
||||
let giver;
|
||||
if (
|
||||
@@ -492,6 +479,7 @@ export default class ClaimView extends Vue {
|
||||
}
|
||||
}
|
||||
|
||||
// similar code is found in ProjectViewView
|
||||
async confirmClaim() {
|
||||
if (confirm("Do you personally confirm that this is true?")) {
|
||||
// similar logic is found in endorser-mobile
|
||||
|
||||
@@ -743,7 +743,9 @@ export default class ContactsView extends Vue {
|
||||
group: "alert",
|
||||
type: "info",
|
||||
title: "Registration Success",
|
||||
text: contact.name + " has been registered.",
|
||||
text:
|
||||
(contact.name || "That unnamed person") +
|
||||
" has been registered.",
|
||||
},
|
||||
-1,
|
||||
);
|
||||
|
||||
@@ -182,7 +182,12 @@
|
||||
<span>
|
||||
<fa icon="user" class="fa-fw text-slate-400"></fa>
|
||||
{{
|
||||
didInfo(offer.offeredByDid, activeDid, allMyDids, allContacts)
|
||||
serverUtil.didInfo(
|
||||
offer.offeredByDid,
|
||||
activeDid,
|
||||
allMyDids,
|
||||
allContacts,
|
||||
)
|
||||
}}
|
||||
</span>
|
||||
<a @click="onClickLoadClaim(offer.jwtId)">
|
||||
@@ -219,11 +224,15 @@
|
||||
<div class="flex justify-between gap-4">
|
||||
<span
|
||||
><fa icon="user" class="fa-fw text-slate-400"></fa>
|
||||
{{ didInfo(give.agentDid, activeDid, allMyDids, allContacts) }}
|
||||
{{
|
||||
serverUtil.didInfo(
|
||||
give.agentDid,
|
||||
activeDid,
|
||||
allMyDids,
|
||||
allContacts,
|
||||
)
|
||||
}}
|
||||
</span>
|
||||
<a @click="onClickLoadClaim(give.jwtId)">
|
||||
<fa icon="circle-info" class="pl-2 pt-1 text-slate-500"></fa>
|
||||
</a>
|
||||
<span v-if="give.amount">
|
||||
<fa
|
||||
:icon="iconForUnitCode(give.unit)"
|
||||
@@ -235,6 +244,14 @@
|
||||
<fa icon="comment" class="fa-fw text-slate-400"></fa>
|
||||
{{ give.description }}
|
||||
</div>
|
||||
<div class="flex justify-between">
|
||||
<a @click="onClickLoadClaim(give.jwtId)">
|
||||
<fa icon="circle-info" class="text-blue-500"></fa>
|
||||
</a>
|
||||
<a v-if="checkIsConfirmable(give)" @click="confirmClaim(give)">
|
||||
<fa icon="circle-check" class="text-blue-500"></fa>
|
||||
</a>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
@@ -292,14 +309,16 @@ import { accountsDB, db } from "@/db/index";
|
||||
import { Contact } from "@/db/tables/contacts";
|
||||
import { MASTER_SETTINGS_KEY, Settings } from "@/db/tables/settings";
|
||||
import { accessToken } from "@/libs/crypto";
|
||||
import { isGlobalUri } from "@/libs/util";
|
||||
import * as libsUtil from "@/libs/util";
|
||||
import {
|
||||
didInfo,
|
||||
BLANK_GENERIC_SERVER_RECORD,
|
||||
GenericServerRecord,
|
||||
GiverInputInfo,
|
||||
GiveServerRecord,
|
||||
OfferServerRecord,
|
||||
PlanServerRecord,
|
||||
} from "@/libs/endorserServer";
|
||||
import * as serverUtil from "@/libs/endorserServer";
|
||||
import QuickNav from "@/components/QuickNav.vue";
|
||||
import EntityIcon from "@/components/EntityIcon.vue";
|
||||
import { Account } from "@/db/tables/accounts";
|
||||
@@ -338,6 +357,8 @@ export default class ProjectViewView extends Vue {
|
||||
truncateLength = 40;
|
||||
url = "";
|
||||
|
||||
serverUtil = serverUtil;
|
||||
|
||||
async created() {
|
||||
await db.open();
|
||||
const settings = (await db.settings.get(MASTER_SETTINGS_KEY)) as Settings;
|
||||
@@ -356,7 +377,7 @@ export default class ProjectViewView extends Vue {
|
||||
if (pathParam) {
|
||||
this.projectId = decodeURIComponent(pathParam);
|
||||
}
|
||||
this.LoadProject(this.projectId, identity);
|
||||
this.loadProject(this.projectId, identity);
|
||||
}
|
||||
|
||||
public async getIdentity(activeDid: string) {
|
||||
@@ -387,15 +408,6 @@ export default class ProjectViewView extends Vue {
|
||||
}
|
||||
|
||||
// Isn't there a better way to make this available to the template?
|
||||
didInfo(
|
||||
did: string,
|
||||
activeDid: string,
|
||||
dids: Array<string>,
|
||||
contacts: Array<Contact>,
|
||||
) {
|
||||
return didInfo(did, activeDid, dids, contacts);
|
||||
}
|
||||
|
||||
expandText() {
|
||||
this.expanded = true;
|
||||
}
|
||||
@@ -404,7 +416,7 @@ export default class ProjectViewView extends Vue {
|
||||
this.expanded = false;
|
||||
}
|
||||
|
||||
async LoadProject(projectId: string, identity: IIdentifier) {
|
||||
async loadProject(projectId: string, identity: IIdentifier) {
|
||||
this.projectId = projectId;
|
||||
|
||||
const url =
|
||||
@@ -628,7 +640,7 @@ export default class ProjectViewView extends Vue {
|
||||
path: "/project/" + encodeURIComponent(projectId),
|
||||
};
|
||||
this.$router.push(route);
|
||||
this.LoadProject(projectId, await this.getIdentity(this.activeDid));
|
||||
this.loadProject(projectId, await this.getIdentity(this.activeDid));
|
||||
}
|
||||
|
||||
getOpenStreetMapUrl() {
|
||||
@@ -681,7 +693,7 @@ export default class ProjectViewView extends Vue {
|
||||
|
||||
// return an HTTPS URL if it's not a global URL
|
||||
addScheme(url: string) {
|
||||
if (!isGlobalUri(url)) {
|
||||
if (!libsUtil.isGlobalUri(url)) {
|
||||
return "https://" + url;
|
||||
}
|
||||
return url;
|
||||
@@ -706,5 +718,70 @@ export default class ProjectViewView extends Vue {
|
||||
return url;
|
||||
}
|
||||
}
|
||||
|
||||
checkIsConfirmable(give: GiveServerRecord) {
|
||||
const giveDetails: GenericServerRecord = {
|
||||
...BLANK_GENERIC_SERVER_RECORD,
|
||||
claim: give.fullClaim,
|
||||
claimType: "GiveAction",
|
||||
issuer: give.agentDid,
|
||||
};
|
||||
return libsUtil.userCanConfirm(giveDetails, this.activeDid);
|
||||
}
|
||||
|
||||
// similar code is found in ClaimView
|
||||
async confirmClaim(give: GiveServerRecord) {
|
||||
if (confirm("Do you personally confirm that this is true?")) {
|
||||
// similar logic is found in endorser-mobile
|
||||
const goodClaim = serverUtil.removeSchemaContext(
|
||||
serverUtil.removeVisibleToDids(
|
||||
serverUtil.addLastClaimOrHandleAsIdIfMissing(
|
||||
give.fullClaim,
|
||||
give.jwtId,
|
||||
give.handleId,
|
||||
),
|
||||
),
|
||||
);
|
||||
const confirmationClaim: serverUtil.GenericVerifiableCredential & {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
object: any;
|
||||
} = {
|
||||
"@context": "https://schema.org",
|
||||
"@type": "AgreeAction",
|
||||
object: goodClaim,
|
||||
};
|
||||
const result = await serverUtil.createAndSubmitClaim(
|
||||
confirmationClaim,
|
||||
await this.getIdentity(this.activeDid),
|
||||
this.apiServer,
|
||||
this.axios,
|
||||
);
|
||||
if (result.type === "success") {
|
||||
this.$notify(
|
||||
{
|
||||
group: "alert",
|
||||
type: "success",
|
||||
title: "Success",
|
||||
text: "Confirmation submitted.",
|
||||
},
|
||||
5000,
|
||||
);
|
||||
} else {
|
||||
console.error("Got error submitting the confirmation:", result);
|
||||
const message =
|
||||
(result.error?.error as string) ||
|
||||
"There was a problem submitting the confirmation. See logs for more info.";
|
||||
this.$notify(
|
||||
{
|
||||
group: "alert",
|
||||
type: "danger",
|
||||
title: "Error",
|
||||
text: message,
|
||||
},
|
||||
-1,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user