fix bad link to project page, fix improper action on invite-add-contact cancel
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "TimeSafari",
|
"name": "TimeSafari",
|
||||||
"version": "0.3.29",
|
"version": "0.3.30-beta",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
"serve": "vite preview",
|
"serve": "vite preview",
|
||||||
|
|||||||
@@ -2,7 +2,8 @@
|
|||||||
<template>
|
<template>
|
||||||
<div v-if="visible" class="dialog-overlay">
|
<div v-if="visible" class="dialog-overlay">
|
||||||
<div class="dialog">
|
<div class="dialog">
|
||||||
<h1 class="text-xl font-bold text-center mb-4">Contact Name</h1>
|
<h1 class="text-xl font-bold text-center mb-4">{{ title }}</h1>
|
||||||
|
{{ message }}
|
||||||
Note that their name is only stored on this device.
|
Note that their name is only stored on this device.
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
@@ -38,23 +39,38 @@ import { Vue, Component } from "vue-facing-decorator";
|
|||||||
|
|
||||||
@Component
|
@Component
|
||||||
export default class ContactNameDialog extends Vue {
|
export default class ContactNameDialog extends Vue {
|
||||||
callback: (name?: string) => void = () => {};
|
cancelCallback: () => void = () => {};
|
||||||
|
saveCallback: (name?: string) => void = () => {};
|
||||||
|
message = "";
|
||||||
newText = "";
|
newText = "";
|
||||||
|
title = "Contact Name";
|
||||||
visible = false;
|
visible = false;
|
||||||
|
|
||||||
async open(aCallback?: (name?: string) => void) {
|
async open(
|
||||||
this.callback = aCallback || this.callback;
|
title?: string,
|
||||||
|
message?: string,
|
||||||
|
saveCallback?: (name: string) => void,
|
||||||
|
cancelCallback?: () => void,
|
||||||
|
) {
|
||||||
|
this.cancelCallback = cancelCallback || this.cancelCallback;
|
||||||
|
this.saveCallback = saveCallback || this.saveCallback;
|
||||||
|
this.message = message ?? this.message;
|
||||||
|
this.title = title ?? this.title;
|
||||||
this.visible = true;
|
this.visible = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
async onClickSaveChanges() {
|
async onClickSaveChanges() {
|
||||||
this.visible = false;
|
this.visible = false;
|
||||||
this.callback(this.newText);
|
if (this.saveCallback) {
|
||||||
|
this.saveCallback(this.newText);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onClickCancel() {
|
onClickCancel() {
|
||||||
this.visible = false;
|
this.visible = false;
|
||||||
this.callback();
|
if (this.cancelCallback) {
|
||||||
|
this.cancelCallback();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1135,16 +1135,16 @@ export default class AccountViewView extends Vue {
|
|||||||
* @param {Error} error - The error object.
|
* @param {Error} error - The error object.
|
||||||
*/
|
*/
|
||||||
private handleExportError(error: unknown) {
|
private handleExportError(error: unknown) {
|
||||||
|
console.error("Export Error:", error);
|
||||||
this.$notify(
|
this.$notify(
|
||||||
{
|
{
|
||||||
group: "alert",
|
group: "alert",
|
||||||
type: "danger",
|
type: "danger",
|
||||||
title: "Export Error",
|
title: "Export Error",
|
||||||
text: "See console logs for more info.",
|
text: "There was an error exporting the data.",
|
||||||
},
|
},
|
||||||
-1,
|
-1,
|
||||||
);
|
);
|
||||||
console.error("Export Error:", error);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async uploadImportFile(event: Event) {
|
async uploadImportFile(event: Event) {
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ export default class ClaimAddRawView extends Vue {
|
|||||||
group: "alert",
|
group: "alert",
|
||||||
type: "danger",
|
type: "danger",
|
||||||
title: "Error",
|
title: "Error",
|
||||||
text: "There was a problem submitting the claim. See logs for more info.",
|
text: "There was a problem submitting the claim.",
|
||||||
},
|
},
|
||||||
-1,
|
-1,
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -36,21 +36,6 @@
|
|||||||
</button>
|
</button>
|
||||||
</h2>
|
</h2>
|
||||||
<div class="text-sm">
|
<div class="text-sm">
|
||||||
<div>
|
|
||||||
{{ veriClaim.id }}
|
|
||||||
<button
|
|
||||||
@click="
|
|
||||||
libsUtil.doCopyTwoSecRedo(
|
|
||||||
veriClaim.id as string,
|
|
||||||
() => (showIdCopy = !showIdCopy),
|
|
||||||
)
|
|
||||||
"
|
|
||||||
class="ml-2 mr-2"
|
|
||||||
>
|
|
||||||
<fa icon="copy" class="text-slate-400 fa-fw" />
|
|
||||||
</button>
|
|
||||||
<span v-show="showIdCopy">Copied ID</span>
|
|
||||||
</div>
|
|
||||||
<div data-testId="description">
|
<div data-testId="description">
|
||||||
<fa icon="message" class="fa-fw text-slate-400" />
|
<fa icon="message" class="fa-fw text-slate-400" />
|
||||||
{{
|
{{
|
||||||
@@ -88,7 +73,7 @@
|
|||||||
|
|
||||||
<div v-if="veriClaim.claimType === 'PlanAction'" class="mt-4">
|
<div v-if="veriClaim.claimType === 'PlanAction'" class="mt-4">
|
||||||
<router-link
|
<router-link
|
||||||
:to="'/project/' + encodeURIComponent(veriClaim.id)"
|
:to="'/project/' + encodeURIComponent(veriClaim.handleId)"
|
||||||
class="text-blue-500 mt-2"
|
class="text-blue-500 mt-2"
|
||||||
>
|
>
|
||||||
Go to Project page
|
Go to Project page
|
||||||
@@ -788,7 +773,7 @@ export default class ClaimView extends Vue {
|
|||||||
group: "alert",
|
group: "alert",
|
||||||
type: "danger",
|
type: "danger",
|
||||||
title: "Error",
|
title: "Error",
|
||||||
text: "There was a problem getting that claim. See logs for more info.",
|
text: "There was a problem getting that claim.",
|
||||||
},
|
},
|
||||||
-1,
|
-1,
|
||||||
);
|
);
|
||||||
@@ -810,7 +795,7 @@ export default class ClaimView extends Vue {
|
|||||||
group: "alert",
|
group: "alert",
|
||||||
type: "danger",
|
type: "danger",
|
||||||
title: "Error",
|
title: "Error",
|
||||||
text: "Something went wrong retrieving that claim. See logs for more info.",
|
text: "Something went wrong retrieving that claim.",
|
||||||
},
|
},
|
||||||
-1,
|
-1,
|
||||||
);
|
);
|
||||||
@@ -873,7 +858,7 @@ export default class ClaimView extends Vue {
|
|||||||
group: "alert",
|
group: "alert",
|
||||||
type: "danger",
|
type: "danger",
|
||||||
title: "Error",
|
title: "Error",
|
||||||
text: "There was a problem submitting the confirmation. See logs for more info.",
|
text: "There was a problem submitting the confirmation.",
|
||||||
},
|
},
|
||||||
-1,
|
-1,
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -762,7 +762,7 @@ export default class ClaimView extends Vue {
|
|||||||
group: "alert",
|
group: "alert",
|
||||||
type: "danger",
|
type: "danger",
|
||||||
title: "Error",
|
title: "Error",
|
||||||
text: "There was a problem submitting the confirmation. See logs for more info.",
|
text: "There was a problem submitting the confirmation.",
|
||||||
},
|
},
|
||||||
5000,
|
5000,
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -278,7 +278,7 @@ export default class ContactAmountssView extends Vue {
|
|||||||
(origClaim.object?.amountOfThisGood as number) || 1;
|
(origClaim.object?.amountOfThisGood as number) || 1;
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
let userMessage = "There was an error. See logs for more info.";
|
let userMessage = "There was an error.";
|
||||||
const serverError = error as AxiosError;
|
const serverError = error as AxiosError;
|
||||||
if (serverError) {
|
if (serverError) {
|
||||||
if (serverError.message) {
|
if (serverError.message) {
|
||||||
|
|||||||
@@ -362,7 +362,7 @@ export default class ContactQRScanShow extends Vue {
|
|||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error when registering:", error);
|
console.error("Error when registering:", error);
|
||||||
let userMessage = "There was an error. See logs for more info.";
|
let userMessage = "There was an error.";
|
||||||
const serverError = error as AxiosError;
|
const serverError = error as AxiosError;
|
||||||
if (serverError) {
|
if (serverError) {
|
||||||
if (serverError.response?.data?.error?.message) {
|
if (serverError.response?.data?.error?.message) {
|
||||||
|
|||||||
@@ -453,12 +453,23 @@ export default class ContactsView extends Vue {
|
|||||||
const payload: JWTPayload =
|
const payload: JWTPayload =
|
||||||
decodeEndorserJwt(importedInviteJwt).payload;
|
decodeEndorserJwt(importedInviteJwt).payload;
|
||||||
const registration = payload as VerifiableCredential;
|
const registration = payload as VerifiableCredential;
|
||||||
(this.$refs.contactNameDialog as ContactNameDialog).open((name) =>
|
(this.$refs.contactNameDialog as ContactNameDialog).open(
|
||||||
this.addContact({
|
"Contact Name",
|
||||||
did: registration.vc.credentialSubject.agent.identifier,
|
"",
|
||||||
name: name, // may be undefined if they cancel
|
(name) => {
|
||||||
registered: true,
|
this.addContact({
|
||||||
}),
|
did: registration.vc.credentialSubject.agent.identifier,
|
||||||
|
name: name,
|
||||||
|
registered: true,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
() => {
|
||||||
|
this.addContact({
|
||||||
|
did: registration.vc.credentialSubject.agent.identifier,
|
||||||
|
name: "(person who invited you)",
|
||||||
|
registered: true,
|
||||||
|
});
|
||||||
|
},
|
||||||
);
|
);
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
@@ -945,7 +956,7 @@ export default class ContactsView extends Vue {
|
|||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error when registering:", error);
|
console.error("Error when registering:", error);
|
||||||
let userMessage = "There was an error. See logs for more info.";
|
let userMessage = "There was an error.";
|
||||||
const serverError = error as AxiosError;
|
const serverError = error as AxiosError;
|
||||||
if (serverError.isAxiosError) {
|
if (serverError.isAxiosError) {
|
||||||
if (
|
if (
|
||||||
|
|||||||
@@ -163,6 +163,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Edit Name Dialog, maybe should be replaced by ContactNameDialog -->
|
||||||
<div v-if="contactEdit" class="dialog-overlay">
|
<div v-if="contactEdit" class="dialog-overlay">
|
||||||
<div class="dialog">
|
<div class="dialog">
|
||||||
<h1 class="text-xl font-bold text-center mb-4">Edit Name</h1>
|
<h1 class="text-xl font-bold text-center mb-4">Edit Name</h1>
|
||||||
@@ -439,7 +440,7 @@ export default class DIDView extends Vue {
|
|||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error when registering:", error);
|
console.error("Error when registering:", error);
|
||||||
let userMessage = "There was an error. See logs for more info.";
|
let userMessage = "There was an error.";
|
||||||
const serverError = error as AxiosError;
|
const serverError = error as AxiosError;
|
||||||
if (serverError) {
|
if (serverError) {
|
||||||
if (serverError.response?.data?.error?.message) {
|
if (serverError.response?.data?.error?.message) {
|
||||||
|
|||||||
@@ -42,22 +42,35 @@
|
|||||||
<tr
|
<tr
|
||||||
v-for="invite in invites"
|
v-for="invite in invites"
|
||||||
:key="invite.inviteIdentifier"
|
:key="invite.inviteIdentifier"
|
||||||
class="border-t"
|
class="border-t py-2"
|
||||||
>
|
>
|
||||||
<td
|
<td>
|
||||||
class="py-2 text-center text-blue-500 cursor-pointer"
|
<span
|
||||||
@click="copyInviteAndNotify(invite.inviteIdentifier, invite.jwt)"
|
v-if="!invite.redeemedAt"
|
||||||
title="{{ inviteLink(invite.jwt) }}"
|
@click="
|
||||||
>
|
copyInviteAndNotify(invite.inviteIdentifier, invite.jwt)
|
||||||
{{ getTruncatedInviteId(invite.inviteIdentifier) }}
|
"
|
||||||
|
class="text-center text-blue-500 cursor-pointer"
|
||||||
|
:title="inviteLink(invite.jwt)"
|
||||||
|
>
|
||||||
|
{{ getTruncatedInviteId(invite.inviteIdentifier) }}
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
v-else
|
||||||
|
@click="showInvite(invite.inviteIdentifier)"
|
||||||
|
class="text-center text-slate-500 cursor-pointer"
|
||||||
|
:title="inviteLink(invite.jwt)"
|
||||||
|
>
|
||||||
|
{{ getTruncatedInviteId(invite.inviteIdentifier) }}
|
||||||
|
</span>
|
||||||
</td>
|
</td>
|
||||||
<td class="py-2 text-left" :data-testId="inviteLink(invite.jwt)">
|
<td class="text-left" :data-testId="inviteLink(invite.jwt)">
|
||||||
{{ invite.notes }}
|
{{ invite.notes }}
|
||||||
</td>
|
</td>
|
||||||
<td class="py-2 text-center">
|
<td class="text-center">
|
||||||
{{ invite.expiresAt.substring(0, 10) }}
|
{{ invite.expiresAt.substring(0, 10) }}
|
||||||
</td>
|
</td>
|
||||||
<td class="py-2 text-center">
|
<td class="text-center">
|
||||||
{{ invite.redeemedAt?.substring(0, 10) }}
|
{{ invite.redeemedAt?.substring(0, 10) }}
|
||||||
<br />
|
<br />
|
||||||
{{ getTruncatedRedeemedBy(invite.redeemedBy) }}
|
{{ getTruncatedRedeemedBy(invite.redeemedBy) }}
|
||||||
@@ -159,7 +172,7 @@ export default class InviteOneView extends Vue {
|
|||||||
|
|
||||||
getTruncatedInviteId(inviteId: string): string {
|
getTruncatedInviteId(inviteId: string): string {
|
||||||
if (inviteId.length <= 9) return inviteId;
|
if (inviteId.length <= 9) return inviteId;
|
||||||
return `${inviteId.slice(0, 3)}...${inviteId.slice(-3)}`;
|
return `${inviteId.slice(0, 6)}...`;
|
||||||
}
|
}
|
||||||
|
|
||||||
getTruncatedRedeemedBy(redeemedBy: string | null): string {
|
getTruncatedRedeemedBy(redeemedBy: string | null): string {
|
||||||
@@ -174,6 +187,7 @@ export default class InviteOneView extends Vue {
|
|||||||
inviteLink(jwt: string): string {
|
inviteLink(jwt: string): string {
|
||||||
return APP_SERVER + "/contacts?inviteJwt=" + jwt;
|
return APP_SERVER + "/contacts?inviteJwt=" + jwt;
|
||||||
}
|
}
|
||||||
|
|
||||||
copyInviteAndNotify(inviteId: string, jwt: string) {
|
copyInviteAndNotify(inviteId: string, jwt: string) {
|
||||||
useClipboard().copy(this.inviteLink(jwt));
|
useClipboard().copy(this.inviteLink(jwt));
|
||||||
this.$notify(
|
this.$notify(
|
||||||
@@ -187,6 +201,19 @@ export default class InviteOneView extends Vue {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
showInvite(inviteId: string) {
|
||||||
|
useClipboard().copy(inviteId);
|
||||||
|
this.$notify(
|
||||||
|
{
|
||||||
|
group: "alert",
|
||||||
|
type: "success",
|
||||||
|
title: "Copied",
|
||||||
|
text: `The link has been used, but your clipboard now contains the invite ID ${inviteId}`,
|
||||||
|
},
|
||||||
|
5000,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
lookForErrorAndNotify(error, title, defaultMessage) {
|
lookForErrorAndNotify(error, title, defaultMessage) {
|
||||||
console.error(title, "-", error);
|
console.error(title, "-", error);
|
||||||
let message = defaultMessage;
|
let message = defaultMessage;
|
||||||
@@ -258,25 +285,29 @@ export default class InviteOneView extends Vue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
addNewContact(did) {
|
addNewContact(did) {
|
||||||
(this.$refs.contactNameDialog as ContactNameDialog).open((name) => {
|
(this.$refs.contactNameDialog as ContactNameDialog).open(
|
||||||
// the person obviously registered themselves and this user already granted visibility, so we just add them
|
"Who Sent You The Invite?",
|
||||||
const contact = {
|
"Their name will be added to your contact list.",
|
||||||
did: did,
|
(name) => {
|
||||||
name: name,
|
// the person obviously registered themselves and this user already granted visibility, so we just add them
|
||||||
registered: true,
|
const contact = {
|
||||||
};
|
did: did,
|
||||||
db.contacts.add(contact);
|
name: name,
|
||||||
this.contactsRedeemed[did] = contact;
|
registered: true,
|
||||||
this.$notify(
|
};
|
||||||
{
|
db.contacts.add(contact);
|
||||||
group: "alert",
|
this.contactsRedeemed[did] = contact;
|
||||||
type: "success",
|
this.$notify(
|
||||||
title: "Contact Added",
|
{
|
||||||
text: `${name} has been added to your contacts.`,
|
group: "alert",
|
||||||
},
|
type: "success",
|
||||||
3000,
|
title: "Contact Added",
|
||||||
);
|
text: `${name} has been added to your contacts.`,
|
||||||
});
|
},
|
||||||
|
3000,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
deleteInvite(inviteId: string, notes: string) {
|
deleteInvite(inviteId: string, notes: string) {
|
||||||
|
|||||||
@@ -566,35 +566,22 @@ export default class ProjectViewView extends Vue {
|
|||||||
group: "alert",
|
group: "alert",
|
||||||
type: "danger",
|
type: "danger",
|
||||||
title: "Error",
|
title: "Error",
|
||||||
text: "There was a problem getting that project. See logs for more info.",
|
text: "There was a problem getting that project.",
|
||||||
},
|
},
|
||||||
5000,
|
5000,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} catch (error: unknown) {
|
} catch (error: unknown) {
|
||||||
console.error("Error retrieving project:", error);
|
console.error("Error retrieving project:", error);
|
||||||
const serverError = error as AxiosError;
|
this.$notify(
|
||||||
if (serverError.response?.status === 404) {
|
{
|
||||||
this.$notify(
|
group: "alert",
|
||||||
{
|
type: "danger",
|
||||||
group: "alert",
|
title: "Error",
|
||||||
type: "danger",
|
text: "Something went wrong retrieving that project.",
|
||||||
title: "Error",
|
},
|
||||||
text: "That project does not exist.",
|
5000,
|
||||||
},
|
);
|
||||||
5000,
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
this.$notify(
|
|
||||||
{
|
|
||||||
group: "alert",
|
|
||||||
type: "danger",
|
|
||||||
title: "Error",
|
|
||||||
text: "Something went wrong retrieving that project. See logs for more info.",
|
|
||||||
},
|
|
||||||
5000,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.loadGives();
|
this.loadGives();
|
||||||
@@ -1011,7 +998,7 @@ export default class ProjectViewView extends Vue {
|
|||||||
console.error("Got error submitting the confirmation:", result);
|
console.error("Got error submitting the confirmation:", result);
|
||||||
const message =
|
const message =
|
||||||
(result.error?.error as string) ||
|
(result.error?.error as string) ||
|
||||||
"There was a problem submitting the confirmation. See logs for more info.";
|
"There was a problem submitting the confirmation.";
|
||||||
this.$notify(
|
this.$notify(
|
||||||
{
|
{
|
||||||
group: "alert",
|
group: "alert",
|
||||||
|
|||||||
Reference in New Issue
Block a user