add ability to give to fulfill an offer; adjust visibility of claim actions

This commit is contained in:
2024-01-12 15:54:45 -07:00
parent cb1f38c182
commit acaaf8776d
7 changed files with 178 additions and 76 deletions

View File

@@ -17,34 +17,55 @@
</div>
<!-- Details -->
<div class="bg-slate-100 rounded-md overflow-hidden px-4 py-3 mb-4">
<div>
<div class="block flex gap-4 overflow-hidden">
<div class="overflow-hidden">
<h2 class="text-md font-bold">{{ veriClaim.id }}</h2>
<div class="text-sm">
<div>
{{ veriClaim.claimType }}
</div>
<div>
<fa icon="message" class="fa-fw text-slate-400"></fa>
{{ veriClaim.claim?.description }}
</div>
<div>
<fa icon="user" class="fa-fw text-slate-400"></fa>
{{ veriClaim.issuer }}
</div>
<div>
<fa icon="calendar" class="fa-fw text-slate-400"></fa>
{{ veriClaim.issuedAt?.replace(/T/, " ").replace(/Z/, " UTC") }}
</div>
<div class="h-32 bg-slate-100 rounded-md overflow-hidden px-4 py-3 mb-4">
<div class="block flex gap-4 overflow-hidden">
<div class="overflow-hidden">
<h2 class="text-md font-bold">{{ veriClaim.id }}</h2>
<div class="text-sm">
<div>
{{ capitalizeAndInsertSpacesBeforeCaps(veriClaim.claimType) }}
</div>
<div>
<fa icon="message" class="fa-fw text-slate-400"></fa>
{{ veriClaim.claim?.description }}
</div>
<div>
<fa icon="user" class="fa-fw text-slate-400"></fa>
{{ veriClaim.issuer }}
</div>
<div>
<fa icon="calendar" class="fa-fw text-slate-400"></fa>
{{ veriClaim.issuedAt?.replace(/T/, " ").replace(/Z/, " UTC") }}
</div>
</div>
</div>
</div>
</div>
<div>
<div class="h-6 columns-3">
<button
class="col-span-1 bg-blue-600 text-white px-4 py-2 rounded-md"
v-if="userCanConfirm()"
@click="confirmClaim(veriClaim.id)"
>
Confirm
</button>
<button
v-if="canFulfillOffer()"
@click="openGiftDialog()"
class="col-span-1 block w-fit text-center text-md bg-blue-600 text-white px-1.5 py-2 rounded-md"
>
Record Some Delivered
</button>
</div>
<GiftedDialog
ref="customGiveDialog"
message="Offer fulfilled by"
:offerId="veriClaim.handleId"
/>
<div v-if="isConfirmable()">
<h2 class="font-bold uppercase text-xl mt-8 mb-2">Confirmations</h2>
<span v-if="totalConfirmers() === 0">Nobody has confirmed this.</span>
@@ -71,7 +92,7 @@
</div>
<div v-if="confirmerIdList.length > 0">
The following people have issued or confirmed this claim.
<ul>
<ul class="ml-4">
<li
v-for="confirmerId in confirmerIdList"
:key="confirmerId"
@@ -98,7 +119,7 @@
<div v-if="confsVisibleToIdList.length > 0">
The following people can connect you with people who have issued or
confirmed this claim.
<ul>
<ul class="ml-4">
<li
v-for="confsVisibleTo in confsVisibleToIdList"
:key="confsVisibleTo"
@@ -116,27 +137,22 @@
</div>
</div>
<div class="mt-4">
<div v-if="confirmerIdList.includes(activeDid)">
You have confirmed this claim.
</div>
<div v-else-if="containsHiddenDid(veriClaim.claim)">
You cannot confirm this claim because it contains data that is hidden
from you.
</div>
<div v-else>
<button
class="bg-blue-600 text-white mt-4 px-4 py-2 rounded-md mb-4"
@click="confirmClaim(veriClaim.id)"
>
Confirm Claim
</button>
</div>
<!-- explain if user cannot confirm -->
<!-- Note that these conditions are mirrored in userCanConfirm(). -->
<div v-if="confirmerIdList.includes(activeDid)">
You have confirmed this claim.
</div>
<div v-else-if="veriClaim.issuer == activeDid">
You cannot confirm this because you issued this claim, so you already
count as confirming it.
</div>
<div v-else-if="containsHiddenDid(veriClaim.claim)">
You cannot confirm this because it contains hidden identifiers.
</div>
</div>
<div>
<h2 class="font-bold uppercase text-xl mt-8 mb-2">Claim</h2>
<h2 class="font-bold uppercase text-xl mt-8 mb-2">Visible Details</h2>
<pre
class="text-sm overflow-x-scroll px-4 py-3 bg-slate-100 rounded-md"
>{{ veriClaimDump }}</pre
@@ -192,6 +208,7 @@ import * as serverUtil from "@/libs/endorserServer";
import QuickNav from "@/components/QuickNav.vue";
import EntityIcon from "@/components/EntityIcon.vue";
import { Account } from "@/db/tables/accounts";
import { GiverInputInfo } from "@/libs/endorserServer";
interface Notification {
group: string;
@@ -210,9 +227,9 @@ export default class ClaimView extends Vue {
allMyDids: Array<string> = [];
allContacts: Array<Contact> = [];
apiServer = "";
confirmerIdList = []; // list of DIDs that have confirmed this claim excluding the issuer
confirmerIdList: string[] = []; // list of DIDs that have confirmed this claim excluding the issuer
confsVisibleErrorMessage = "";
confsVisibleToIdList = []; // list of DIDs that can see any confirmer
confsVisibleToIdList: string[] = []; // list of DIDs that can see any confirmer
fullClaim = null;
fullClaimDump = "";
fullClaimMessage = "";
@@ -242,7 +259,7 @@ export default class ClaimView extends Vue {
let claimId;
if (pathParam) {
claimId = decodeURIComponent(pathParam);
this.loadClaim(claimId, identity);
await this.loadClaim(claimId, identity);
} else {
this.$notify(
{
@@ -256,6 +273,50 @@ export default class ClaimView extends Vue {
}
}
// insert a space before any capital letters except the initial letter
// (and capitalize initial letter, just in case)
capitalizeAndInsertSpacesBeforeCaps(text: string) {
return !text
? ""
: 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 (
this.veriClaim.claim.offeredBy?.identifier &&
!serverUtil.isHiddenDid(
this.veriClaim.claim.offeredBy.identifier as string,
)
) {
giver = this.veriClaim.claim.offeredBy.identifier;
} else if (
this.veriClaim.issuer &&
!serverUtil.isHiddenDid(this.veriClaim.issuer)
) {
giver = this.veriClaim.issuer;
}
return giver;
}
canFulfillOffer() {
return this.veriClaim.claimType === "Offer" && this.offerGiverDid();
}
totalConfirmers() {
return (
this.numConfsNotVisible +
@@ -313,7 +374,7 @@ export default class ClaimView extends Vue {
this.veriClaimDump = yaml.dump(this.veriClaim);
} else {
// actually, axios typically throws an error so we never get here
console.log("Error getting claim:", resp);
console.error("Error getting claim:", resp);
this.$notify(
{
group: "alert",
@@ -393,7 +454,7 @@ export default class ClaimView extends Vue {
this.fullClaimDump = yaml.dump(this.fullClaim);
} else {
// actually, axios typically throws an error so we never get here
console.log("Error getting full claim:", resp);
console.error("Error getting full claim:", resp);
this.$notify(
{
group: "alert",
@@ -466,7 +527,7 @@ export default class ClaimView extends Vue {
5000,
);
} else {
console.log("Got error submitting the confirmation:", result);
console.error("Got error submitting the confirmation:", result);
this.$notify(
{
group: "alert",
@@ -479,5 +540,12 @@ export default class ClaimView extends Vue {
}
}
}
openGiftDialog() {
const giver: GiverInputInfo = {
did: this.offerGiverDid(),
};
(this.$refs.customGiveDialog as GiftedDialog).open(giver);
}
}
</script>