Browse Source

Many fixes -- especially and endorserServer

search-bbox
Matthew Raymer 1 year ago
parent
commit
5501ac1a2f
  1. 47
      src/components/AlertMessage.vue
  2. 2
      src/components/EntityIcon.vue
  3. 173
      src/libs/endorserServer.ts
  4. 16
      src/views/AccountViewView.vue
  5. 18
      src/views/ContactAmountsView.vue
  6. 23
      src/views/ContactGiftingView.vue
  7. 9
      src/views/ContactQRScanShowView.vue
  8. 18
      src/views/ContactsView.vue
  9. 15
      src/views/DiscoverView.vue
  10. 23
      src/views/HomeView.vue
  11. 19
      src/views/IdentitySwitcherView.vue
  12. 21
      src/views/NewEditProjectView.vue
  13. 81
      src/views/ProjectViewView.vue
  14. 16
      src/views/ProjectsView.vue
  15. 21
      src/views/SeedBackupView.vue
  16. 16
      src/views/StatisticsView.vue
  17. 76
      tsconfig.json

47
src/components/AlertMessage.vue

@ -1,47 +0,0 @@
<template>
<div v-bind:class="computedAlertClassNames()">
<button
class="close-button bg-amber-400 w-8 leading-loose rounded-full absolute top-2 right-2"
@click="onClickClose()"
>
<fa icon="xmark"></fa>
</button>
<h4 class="font-bold pr-5">{{ alertTitle }}</h4>
<p>{{ alertMessage }}</p>
</div>
</template>
<script lang="ts">
import { Component, Prop, Vue } from "vue-facing-decorator";
@Component
export default class AlertMessage extends Vue {
@Prop alertTitle = "";
@Prop alertMessage = "";
isAlertVisible = this.alertMessage;
public onClickClose() {
this.isAlertVisible = false;
}
public computedAlertClassNames() {
return {
hidden: !this.isAlertVisible,
"dismissable-alert": true,
"bg-amber-200": true,
"p-5": true,
rounded: true,
"drop-shadow-lg": true,
fixed: true,
"top-3": true,
"inset-x-3": true,
"transition-transform": true,
"ease-in": true,
"duration-300": true,
};
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped></style>

2
src/components/EntityIcon.vue

@ -8,7 +8,7 @@ import { toSvg } from "jdenticon";
@Component @Component
export default class EntityIcon extends Vue { export default class EntityIcon extends Vue {
@Prop entityId = ""; @Prop entityId = "";
@Prop iconSize = ""; @Prop iconSize = 0;
generateIdenticon() { generateIdenticon() {
const svgString = toSvg(this.entityId, this.iconSize); const svgString = toSvg(this.entityId, this.iconSize);

173
src/libs/endorserServer.ts

@ -75,7 +75,7 @@ export interface InternalError {
// See https://github.com/trentlarson/endorser-ch/blob/0cb626f803028e7d9c67f095858a9fc8542e3dbd/server/api/services/util.js#L6 // See https://github.com/trentlarson/endorser-ch/blob/0cb626f803028e7d9c67f095858a9fc8542e3dbd/server/api/services/util.js#L6
const HIDDEN_DID = "did:none:HIDDEN"; const HIDDEN_DID = "did:none:HIDDEN";
export function isHiddenDid(did) { export function isHiddenDid(did: string) {
return did === HIDDEN_DID; return did === HIDDEN_DID;
} }
@ -88,7 +88,7 @@ export function didInfo(
allMyDids: Array<string>, allMyDids: Array<string>,
contacts: Array<Contact>, contacts: Array<Contact>,
): string { ): string {
const myId: string | undefined = R.find(R.equals(did), allMyDids, did); const myId: string | undefined = R.find(R.equals(did), allMyDids);
if (myId) { if (myId) {
return "You" + (myId !== activeDid ? " (Alt ID)" : ""); return "You" + (myId !== activeDid ? " (Alt ID)" : "");
} else { } else {
@ -105,6 +105,18 @@ export function didInfo(
} }
} }
interface SuccessResult {
type: "success";
response: AxiosResponse<ClaimResult>;
}
interface ErrorResult {
type: "error";
error: InternalError;
}
type CreateAndSubmitGiveResult = SuccessResult | ErrorResult;
/** /**
* For result, see https://api.endorser.ch/api-docs/#/claims/post_api_v2_claim * For result, see https://api.endorser.ch/api-docs/#/claims/post_api_v2_claim
* *
@ -123,71 +135,108 @@ export async function createAndSubmitGive(
description: string, description: string,
hours: number, hours: number,
fulfillsProjectHandleId?: string, fulfillsProjectHandleId?: string,
): Promise<AxiosResponse<ClaimResult> | InternalError> { ): Promise<CreateAndSubmitGiveResult> {
// Make a claim try {
const vcClaim: GiveVerifiableCredential = { // Make a claim
"@context": "https://schema.org", const vcClaim: GiveVerifiableCredential = {
"@type": "GiveAction", "@context": "https://schema.org",
recipient: { identifier: toDid }, "@type": "GiveAction",
}; recipient: { identifier: toDid },
if (fromDid) {
vcClaim.agent = { identifier: fromDid };
}
if (description) {
vcClaim.description = description;
}
if (hours) {
vcClaim.object = { amountOfThisGood: hours, unitCode: "HUR" };
}
if (fulfillsProjectHandleId) {
vcClaim.fulfills = {
"@type": "PlanAction",
identifier: fulfillsProjectHandleId,
}; };
} if (fromDid) {
// Make a payload for the claim vcClaim.agent = { identifier: fromDid };
const vcPayload = { }
vc: { if (description) {
"@context": ["https://www.w3.org/2018/credentials/v1"], vcClaim.description = description;
type: ["VerifiableCredential"], }
credentialSubject: vcClaim, if (hours) {
}, vcClaim.object = { amountOfThisGood: hours, unitCode: "HUR" };
}; }
// Create a signature using private key of identity if (fulfillsProjectHandleId) {
if (identity.keys[0].privateKeyHex == null) { vcClaim.fulfills = {
return new Promise<InternalError>((resolve, reject) => { "@type": "PlanAction",
reject({ identifier: fulfillsProjectHandleId,
};
}
// Make a payload for the claim
const vcPayload = {
vc: {
"@context": ["https://www.w3.org/2018/credentials/v1"],
type: ["VerifiableCredential"],
credentialSubject: vcClaim,
},
};
// Create a signature using private key of identity
const firstKey = identity.keys[0];
if (!firstKey || !firstKey.privateKeyHex) {
throw {
error: "No private key",
message: `Your identifier ${identity.did} is not configured correctly. Use a different identifier.`,
};
}
const privateKeyHex = firstKey.privateKeyHex;
if (!privateKeyHex) {
throw {
error: "No private key", error: "No private key",
message: message: `Your identifier ${identity.did} is not configured correctly. Use a different identifier.`,
"Your identifier " + };
identity.did + }
" is not configured correctly. Use a different identifier.",
}); const signer = await SimpleSigner(privateKeyHex);
const alg = undefined;
// Create a JWT for the request
const vcJwt: string = await didJwt.createJWT(vcPayload, {
alg: alg,
issuer: identity.did,
signer: signer,
}); });
}
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion // Make the xhr request payload
const privateKeyHex: string = identity.keys[0].privateKeyHex!;
const signer = await SimpleSigner(privateKeyHex);
const alg = undefined;
// Create a JWT for the request
const vcJwt: string = await didJwt.createJWT(vcPayload, {
alg: alg,
issuer: identity.did,
signer: signer,
});
// Make the xhr request payload
const payload = JSON.stringify({ jwtEncoded: vcJwt });
const url = apiServer + "/api/v2/claim";
const token = await accessToken(identity);
const headers = {
"Content-Type": "application/json",
Authorization: "Bearer " + token,
};
return axios.post(url, payload, { headers }); const payload = JSON.stringify({ jwtEncoded: vcJwt });
const url = apiServer + "/api/v2/claim";
const token = await accessToken(identity);
const headers = {
"Content-Type": "application/json",
Authorization: "Bearer " + token,
};
const response = await axios.post(url, payload, { headers });
return {
type: "success",
response,
};
} catch (error: unknown) {
let errorMessage: string;
if (error instanceof Error) {
// If it's a JavaScript Error object
errorMessage = error.message;
} else if (
typeof error === "object" &&
error !== null &&
"message" in error
) {
// If it's an object that has a 'message' property
errorMessage = (error as { message: string }).message;
} else {
// Unknown error shape, default message
errorMessage = "Unknown error";
}
return {
type: "error",
error: {
error: errorMessage,
userMessage: "Failed to create and submit the claim",
},
};
}
} }
// from https://stackoverflow.com/a/175787/845494 // from https://stackoverflow.com/a/175787/845494

16
src/views/AccountViewView.vue

@ -286,10 +286,6 @@
</button> </button>
</div> </div>
</div> </div>
<AlertMessage
:alertTitle="alertTitle"
:alertMessage="alertMessage"
></AlertMessage>
</section> </section>
</template> </template>
@ -303,15 +299,23 @@ import { db, accountsDB } from "@/db";
import { MASTER_SETTINGS_KEY } from "@/db/tables/settings"; import { MASTER_SETTINGS_KEY } from "@/db/tables/settings";
import { accessToken } from "@/libs/crypto"; import { accessToken } from "@/libs/crypto";
import { AxiosError } from "axios/index"; import { AxiosError } from "axios/index";
import AlertMessage from "@/components/AlertMessage";
import QuickNav from "@/components/QuickNav"; import QuickNav from "@/components/QuickNav";
import { IIdentifier } from "@veramo/core"; import { IIdentifier } from "@veramo/core";
// eslint-disable-next-line @typescript-eslint/no-var-requires // eslint-disable-next-line @typescript-eslint/no-var-requires
const Buffer = require("buffer/").Buffer; const Buffer = require("buffer/").Buffer;
@Component({ components: { AlertMessage, QuickNav } }) interface Notification {
group: string;
type: string;
title: string;
text: string;
}
@Component({ components: { QuickNav } })
export default class AccountViewView extends Vue { export default class AccountViewView extends Vue {
$notify!: (notification: Notification, timeout?: number) => void;
Constants = AppString; Constants = AppString;
activeDid = ""; activeDid = "";

18
src/views/ContactAmountsView.vue

@ -90,10 +90,6 @@
</tr> </tr>
</tbody> </tbody>
</table> </table>
<AlertMessage
:alertTitle="alertTitle"
:alertMessage="alertMessage"
></AlertMessage>
</section> </section>
</template> </template>
@ -113,17 +109,23 @@ import {
} from "@/libs/endorserServer"; } from "@/libs/endorserServer";
import * as didJwt from "did-jwt"; import * as didJwt from "did-jwt";
import { AxiosError } from "axios"; import { AxiosError } from "axios";
import AlertMessage from "@/components/AlertMessage";
import QuickNav from "@/components/QuickNav"; import QuickNav from "@/components/QuickNav";
@Component({ components: { AlertMessage, QuickNav } }) interface Notification {
group: string;
type: string;
title: string;
text: string;
}
@Component({ components: { QuickNav } })
export default class ContactsView extends Vue { export default class ContactsView extends Vue {
$notify!: (notification: Notification, timeout?: number) => void;
activeDid = ""; activeDid = "";
apiServer = ""; apiServer = "";
contact: Contact | null = null; contact: Contact | null = null;
giveRecords: Array<GiveServerRecord> = []; giveRecords: Array<GiveServerRecord> = [];
alertTitle = "";
alertMessage = "";
numAccounts = 0; numAccounts = 0;
async beforeCreate() { async beforeCreate() {

23
src/views/ContactGiftingView.vue

@ -76,10 +76,6 @@
message="Received from" message="Received from"
> >
</GiftedDialog> </GiftedDialog>
<AlertMessage
:alertTitle="alertTitle"
:alertMessage="alertMessage"
></AlertMessage>
</section> </section>
</template> </template>
@ -93,21 +89,27 @@ import { accessToken } from "@/libs/crypto";
import { createAndSubmitGive } from "@/libs/endorserServer"; import { createAndSubmitGive } from "@/libs/endorserServer";
import { Account } from "@/db/tables/accounts"; import { Account } from "@/db/tables/accounts";
import { Contact } from "@/db/tables/contacts"; import { Contact } from "@/db/tables/contacts";
import AlertMessage from "@/components/AlertMessage";
import QuickNav from "@/components/QuickNav"; import QuickNav from "@/components/QuickNav";
import EntityIcon from "@/components/EntityIcon"; import EntityIcon from "@/components/EntityIcon";
interface Notification {
group: string;
type: string;
title: string;
text: string;
}
@Component({ @Component({
components: { GiftedDialog, AlertMessage, QuickNav, EntityIcon }, components: { GiftedDialog, QuickNav, EntityIcon },
}) })
export default class HomeView extends Vue { export default class HomeView extends Vue {
$notify!: (notification: Notification, timeout?: number) => void;
activeDid = ""; activeDid = "";
allAccounts: Array<Account> = []; allAccounts: Array<Account> = [];
allContacts: Array<Contact> = []; allContacts: Array<Contact> = [];
apiServer = ""; apiServer = "";
isHiddenSpinner = true; isHiddenSpinner = true;
alertTitle = "";
alertMessage = "";
accounts: AccountsSchema; accounts: AccountsSchema;
numAccounts = 0; numAccounts = 0;
@ -289,11 +291,6 @@ export default class HomeView extends Vue {
} }
} }
private setAlert(title, message) {
this.alertTitle = title;
this.alertMessage = message;
}
// Helper functions for readability // Helper functions for readability
isGiveCreationError(result) { isGiveCreationError(result) {

9
src/views/ContactQRScanShowView.vue

@ -34,6 +34,13 @@ import { Account } from "@/db/tables/accounts";
// eslint-disable-next-line @typescript-eslint/no-var-requires // eslint-disable-next-line @typescript-eslint/no-var-requires
const Buffer = require("buffer/").Buffer; const Buffer = require("buffer/").Buffer;
interface Notification {
group: string;
type: string;
title: string;
text: string;
}
@Component({ @Component({
components: { components: {
QRCodeVue3, QRCodeVue3,
@ -41,6 +48,8 @@ const Buffer = require("buffer/").Buffer;
}, },
}) })
export default class ContactQRScanShow extends Vue { export default class ContactQRScanShow extends Vue {
$notify!: (notification: Notification, timeout?: number) => void;
activeDid = ""; activeDid = "";
apiServer = ""; apiServer = "";
qrValue = ""; qrValue = "";

18
src/views/ContactsView.vue

@ -202,10 +202,6 @@
</li> </li>
</ul> </ul>
<p v-else>This identity has no contacts.</p> <p v-else>This identity has no contacts.</p>
<AlertMessage
:alertTitle="alertTitle"
:alertMessage="alertMessage"
></AlertMessage>
</section> </section>
</template> </template>
@ -224,17 +220,25 @@ import {
SERVICE_ID, SERVICE_ID,
} from "@/libs/endorserServer"; } from "@/libs/endorserServer";
import { Component, Vue } from "vue-facing-decorator"; import { Component, Vue } from "vue-facing-decorator";
import AlertMessage from "@/components/AlertMessage";
import QuickNav from "@/components/QuickNav"; import QuickNav from "@/components/QuickNav";
import EntityIcon from "@/components/EntityIcon"; import EntityIcon from "@/components/EntityIcon";
// eslint-disable-next-line @typescript-eslint/no-var-requires // eslint-disable-next-line @typescript-eslint/no-var-requires
const Buffer = require("buffer/").Buffer; const Buffer = require("buffer/").Buffer;
interface Notification {
group: string;
type: string;
title: string;
text: string;
}
@Component({ @Component({
components: { AlertMessage, QuickNav, EntityIcon }, components: { QuickNav, EntityIcon },
}) })
export default class ContactsView extends Vue { export default class ContactsView extends Vue {
$notify!: (notification: Notification, timeout?: number) => void;
activeDid = ""; activeDid = "";
apiServer = ""; apiServer = "";
contacts: Array<Contact> = []; contacts: Array<Contact> = [];
@ -256,8 +260,6 @@ export default class ContactsView extends Vue {
showGiveNumbers = false; showGiveNumbers = false;
showGiveTotals = true; showGiveTotals = true;
showGiveConfirmed = true; showGiveConfirmed = true;
alertTitle = "";
alertMessage = "";
async created() { async created() {
await db.open(); await db.open();

15
src/views/DiscoverView.vue

@ -181,8 +181,6 @@
/> />
</l-map> </l-map>
</div> </div>
<AlertMessage :alertTitle="alertTitle" :alertMessage="alertMessage" />
</section> </section>
</template> </template>
@ -201,7 +199,6 @@ import { Contact } from "@/db/tables/contacts";
import { BoundingBox, MASTER_SETTINGS_KEY } from "@/db/tables/settings"; import { BoundingBox, MASTER_SETTINGS_KEY } from "@/db/tables/settings";
import { accessToken } from "@/libs/crypto"; import { accessToken } from "@/libs/crypto";
import { didInfo, ProjectData } from "@/libs/endorserServer"; import { didInfo, ProjectData } from "@/libs/endorserServer";
import AlertMessage from "@/components/AlertMessage";
import QuickNav from "@/components/QuickNav"; import QuickNav from "@/components/QuickNav";
import InfiniteScroll from "@/components/InfiniteScroll"; import InfiniteScroll from "@/components/InfiniteScroll";
import EntityIcon from "@/components/EntityIcon"; import EntityIcon from "@/components/EntityIcon";
@ -210,10 +207,16 @@ const DEFAULT_LAT_LONG_DIFF = 0.01;
const WORLD_ZOOM = 2; const WORLD_ZOOM = 2;
const DEFAULT_ZOOM = 2; const DEFAULT_ZOOM = 2;
interface Notification {
group: string;
type: string;
title: string;
text: string;
}
@Component({ @Component({
components: { components: {
LRectangle, LRectangle,
AlertMessage,
QuickNav, QuickNav,
InfiniteScroll, InfiniteScroll,
EntityIcon, EntityIcon,
@ -223,13 +226,13 @@ const DEFAULT_ZOOM = 2;
}, },
}) })
export default class DiscoverView extends Vue { export default class DiscoverView extends Vue {
$notify!: (notification: Notification, timeout?: number) => void;
activeDid = ""; activeDid = "";
allContacts: Array<Contact> = []; allContacts: Array<Contact> = [];
allMyDids: Array<string> = []; allMyDids: Array<string> = [];
apiServer = ""; apiServer = "";
searchTerms = ""; searchTerms = "";
alertMessage = "";
alertTitle = "";
projects: ProjectData[] = []; projects: ProjectData[] = [];
isChoosingSearchBox = false; isChoosingSearchBox = false;
isLocalActive = true; isLocalActive = true;

23
src/views/HomeView.vue

@ -196,10 +196,6 @@
</li> </li>
</ul> </ul>
</div> </div>
<AlertMessage
:alertTitle="alertTitle"
:alertMessage="alertMessage"
></AlertMessage>
</section> </section>
</template> </template>
@ -211,14 +207,22 @@ import { MASTER_SETTINGS_KEY } from "@/db/tables/settings";
import { accessToken } from "@/libs/crypto"; import { accessToken } from "@/libs/crypto";
import { createAndSubmitGive, didInfo } from "@/libs/endorserServer"; import { createAndSubmitGive, didInfo } from "@/libs/endorserServer";
import { Contact } from "@/db/tables/contacts"; import { Contact } from "@/db/tables/contacts";
import AlertMessage from "@/components/AlertMessage";
import QuickNav from "@/components/QuickNav"; import QuickNav from "@/components/QuickNav";
import EntityIcon from "@/components/EntityIcon"; import EntityIcon from "@/components/EntityIcon";
interface Notification {
group: string;
type: string;
title: string;
text: string;
}
@Component({ @Component({
components: { GiftedDialog, AlertMessage, QuickNav, EntityIcon }, components: { GiftedDialog, QuickNav, EntityIcon },
}) })
export default class HomeView extends Vue { export default class HomeView extends Vue {
$notify!: (notification: Notification, timeout?: number) => void;
activeDid = ""; activeDid = "";
allContacts: Array<Contact> = []; allContacts: Array<Contact> = [];
allMyDids: Array<string> = []; allMyDids: Array<string> = [];
@ -228,8 +232,6 @@ export default class HomeView extends Vue {
feedPreviousOldestId = null; feedPreviousOldestId = null;
feedLastViewedId = null; feedLastViewedId = null;
isHiddenSpinner = true; isHiddenSpinner = true;
alertTitle = "";
alertMessage = "";
numAccounts = 0; numAccounts = 0;
async beforeCreate() { async beforeCreate() {
@ -509,11 +511,6 @@ export default class HomeView extends Vue {
} }
} }
private setAlert(title, message) {
this.alertTitle = title;
this.alertMessage = message;
}
// Helper functions for readability // Helper functions for readability
isGiveCreationError(result) { isGiveCreationError(result) {

19
src/views/IdentitySwitcherView.vue

@ -62,11 +62,6 @@
> >
No Identity No Identity
</a> </a>
<AlertMessage
:alertTitle="alertTitle"
:alertMessage="alertMessage"
></AlertMessage>
</section> </section>
</template> </template>
<script lang="ts"> <script lang="ts">
@ -75,18 +70,24 @@ import { AppString } from "@/constants/app";
import { db, accountsDB } from "@/db"; import { db, accountsDB } from "@/db";
import { AccountsSchema } from "@/db/tables/accounts"; import { AccountsSchema } from "@/db/tables/accounts";
import { MASTER_SETTINGS_KEY } from "@/db/tables/settings"; import { MASTER_SETTINGS_KEY } from "@/db/tables/settings";
import AlertMessage from "@/components/AlertMessage";
import QuickNav from "@/components/QuickNav"; import QuickNav from "@/components/QuickNav";
@Component({ components: { AlertMessage, QuickNav } }) interface Notification {
group: string;
type: string;
title: string;
text: string;
}
@Component({ components: { QuickNav } })
export default class IdentitySwitcherView extends Vue { export default class IdentitySwitcherView extends Vue {
$notify!: (notification: Notification, timeout?: number) => void;
Constants = AppString; Constants = AppString;
public accounts: AccountsSchema; public accounts: AccountsSchema;
public activeDid; public activeDid;
public firstName; public firstName;
public lastName; public lastName;
public alertTitle;
public alertMessage;
public otherIdentities = []; public otherIdentities = [];
public async getIdentity(activeDid) { public async getIdentity(activeDid) {

21
src/views/NewEditProjectView.vue

@ -97,10 +97,6 @@
Cancel Cancel
</button> </button>
</div> </div>
<AlertMessage
:alertTitle="alertTitle"
:alertMessage="alertMessage"
></AlertMessage>
</section> </section>
</template> </template>
@ -116,15 +112,21 @@ import { MASTER_SETTINGS_KEY } from "@/db/tables/settings";
import { accessToken, SimpleSigner } from "@/libs/crypto"; import { accessToken, SimpleSigner } from "@/libs/crypto";
import { useAppStore } from "@/store/app"; import { useAppStore } from "@/store/app";
import { IIdentifier } from "@veramo/core"; import { IIdentifier } from "@veramo/core";
import AlertMessage from "@/components/AlertMessage";
interface Notification {
group: string;
type: string;
title: string;
text: string;
}
@Component({ @Component({
components: { AlertMessage, LMap, LMarker, LTileLayer }, components: { LMap, LMarker, LTileLayer },
}) })
export default class NewEditProjectView extends Vue { export default class NewEditProjectView extends Vue {
$notify!: (notification: Notification, timeout?: number) => void;
activeDid = ""; activeDid = "";
alertTitle = "";
alertMessage = "";
apiServer = ""; apiServer = "";
description = ""; description = "";
errorMessage = ""; errorMessage = "";
@ -270,8 +272,7 @@ export default class NewEditProjectView extends Vue {
// version shows up here: https://api.endorser.ch/api-docs/ // version shows up here: https://api.endorser.ch/api-docs/
if (resp.data?.success?.handleId || resp.data?.success?.fullIri) { if (resp.data?.success?.handleId || resp.data?.success?.fullIri) {
this.errorMessage = ""; this.errorMessage = "";
this.alertTitle = "";
this.alertMessage = "";
// handleId is new in server v release-1.6.0; remove fullIri when that // handleId is new in server v release-1.6.0; remove fullIri when that
// version shows up here: https://api.endorser.ch/api-docs/ // version shows up here: https://api.endorser.ch/api-docs/
useAppStore().setProjectId( useAppStore().setProjectId(

81
src/views/ProjectViewView.vue

@ -200,10 +200,6 @@
message="Received from" message="Received from"
> >
</GiftedDialog> </GiftedDialog>
<AlertMessage
:alertTitle="alertTitle"
:alertMessage="alertMessage"
></AlertMessage>
</section> </section>
</template> </template>
@ -226,10 +222,19 @@ import {
import QuickNav from "@/components/QuickNav"; import QuickNav from "@/components/QuickNav";
import EntityIcon from "@/components/EntityIcon"; import EntityIcon from "@/components/EntityIcon";
interface Notification {
group: string;
type: string;
title: string;
text: string;
}
@Component({ @Component({
components: { GiftedDialog, QuickNav, EntityIcon }, components: { GiftedDialog, QuickNav, EntityIcon },
}) })
export default class ProjectViewView extends Vue { export default class ProjectViewView extends Vue {
$notify!: (notification: Notification, timeout?: number) => void;
activeDid = ""; activeDid = "";
allMyDids: Array<string> = []; allMyDids: Array<string> = [];
allContacts: Array<Contact> = []; allContacts: Array<Contact> = [];
@ -339,7 +344,7 @@ export default class ProjectViewView extends Vue {
this.longitude = resp.data.claim?.location?.geo?.longitude || 0; this.longitude = resp.data.claim?.location?.geo?.longitude || 0;
} else if (resp.status === 404) { } else if (resp.status === 404) {
// actually, axios throws an error so we never get here // actually, axios throws an error so we never get here
(this as any).$notify( this.$notify(
{ {
group: "alert", group: "alert",
type: "danger", type: "danger",
@ -352,7 +357,7 @@ export default class ProjectViewView extends Vue {
} catch (error: unknown) { } catch (error: unknown) {
const serverError = error as AxiosError; const serverError = error as AxiosError;
if (serverError.response?.status === 404) { if (serverError.response?.status === 404) {
(this as any).$notify( this.$notify(
{ {
group: "alert", group: "alert",
type: "danger", type: "danger",
@ -362,7 +367,7 @@ export default class ProjectViewView extends Vue {
-1, -1,
); );
} else { } else {
(this as any).$notify( this.$notify(
{ {
group: "alert", group: "alert",
type: "danger", type: "danger",
@ -384,7 +389,7 @@ export default class ProjectViewView extends Vue {
if (resp.status === 200 && resp.data.data) { if (resp.status === 200 && resp.data.data) {
this.givesToThis = resp.data.data; this.givesToThis = resp.data.data;
} else { } else {
(this as any).$notify( this.$notify(
{ {
group: "alert", group: "alert",
type: "danger", type: "danger",
@ -396,7 +401,7 @@ export default class ProjectViewView extends Vue {
} }
} catch (error: unknown) { } catch (error: unknown) {
const serverError = error as AxiosError; const serverError = error as AxiosError;
(this as any).$notify( this.$notify(
{ {
group: "alert", group: "alert",
type: "danger", type: "danger",
@ -420,7 +425,7 @@ export default class ProjectViewView extends Vue {
if (resp.status === 200 && resp.data.data) { if (resp.status === 200 && resp.data.data) {
this.givesByThis = resp.data.data; this.givesByThis = resp.data.data;
} else { } else {
(this as any).$notify( this.$notify(
{ {
group: "alert", group: "alert",
type: "danger", type: "danger",
@ -432,7 +437,7 @@ export default class ProjectViewView extends Vue {
} }
} catch (error: unknown) { } catch (error: unknown) {
const serverError = error as AxiosError; const serverError = error as AxiosError;
(this as any).$notify( this.$notify(
{ {
group: "alert", group: "alert",
type: "danger", type: "danger",
@ -485,7 +490,7 @@ export default class ProjectViewView extends Vue {
*/ */
async recordGive(giverDid, description: string, hours: number) { async recordGive(giverDid, description: string, hours: number) {
if (!this.activeDid) { if (!this.activeDid) {
(this as any).$notify( this.$notify(
{ {
group: "alert", group: "alert",
type: "danger", type: "danger",
@ -498,7 +503,7 @@ export default class ProjectViewView extends Vue {
} }
if (!description && !hours) { if (!description && !hours) {
(this as any).$notify( this.$notify(
{ {
group: "alert", group: "alert",
type: "danger", type: "danger",
@ -507,10 +512,7 @@ export default class ProjectViewView extends Vue {
}, },
-1, -1,
); );
return; } else {
}
try {
const identity = await this.getIdentity(this.activeDid); const identity = await this.getIdentity(this.activeDid);
const result = await createAndSubmitGive( const result = await createAndSubmitGive(
this.axios, this.axios,
@ -522,22 +524,23 @@ export default class ProjectViewView extends Vue {
hours, hours,
this.projectId, this.projectId,
); );
if (result.type == "success") {
if (result.status !== 201 || result.data?.error) {
console.log("Error with give result:", result); console.log("Error with give result:", result);
(this as any).$notify( if ("data" in result) {
{ this.$notify(
group: "alert", {
type: "danger", group: "alert",
title: "Error", type: "danger",
text: title: "Error",
result.data?.error?.message || text:
"There was an error recording the give.", result.data?.error?.message ||
}, "There was an error recording the give.",
-1, },
); -1,
} else { );
(this as any).$notify( }
} else if (result.type == "error") {
this.$notify(
{ {
group: "alert", group: "alert",
type: "success", type: "success",
@ -547,20 +550,6 @@ export default class ProjectViewView extends Vue {
-1, -1,
); );
} }
} catch (e) {
console.log("Error with give caught:", e);
(this as any).$notify(
{
group: "alert",
type: "danger",
title: "Error",
text:
e?.userMessage ||
e?.response?.data?.error?.message ||
"There was an error recording the give.",
},
-1,
);
} }
} }
} }

16
src/views/ProjectsView.vue

@ -67,10 +67,6 @@
</li> </li>
</ul> </ul>
</InfiniteScroll> </InfiniteScroll>
<AlertMessage
:alertTitle="alertTitle"
:alertMessage="alertMessage"
></AlertMessage>
</section> </section>
</template> </template>
@ -81,14 +77,22 @@ import { MASTER_SETTINGS_KEY } from "@/db/tables/settings";
import { accessToken } from "@/libs/crypto"; import { accessToken } from "@/libs/crypto";
import { IIdentifier } from "@veramo/core"; import { IIdentifier } from "@veramo/core";
import InfiniteScroll from "@/components/InfiniteScroll"; import InfiniteScroll from "@/components/InfiniteScroll";
import AlertMessage from "@/components/AlertMessage";
import QuickNav from "@/components/QuickNav"; import QuickNav from "@/components/QuickNav";
import EntityIcon from "@/components/EntityIcon"; import EntityIcon from "@/components/EntityIcon";
interface Notification {
group: string;
type: string;
title: string;
text: string;
}
@Component({ @Component({
components: { InfiniteScroll, AlertMessage, QuickNav, EntityIcon }, components: { InfiniteScroll, QuickNav, EntityIcon },
}) })
export default class ProjectsView extends Vue { export default class ProjectsView extends Vue {
$notify!: (notification: Notification, timeout?: number) => void;
apiServer = ""; apiServer = "";
projects: ProjectData[] = []; projects: ProjectData[] = [];
current: IIdentifier; current: IIdentifier;

21
src/views/SeedBackupView.vue

@ -50,10 +50,6 @@
</div> </div>
</div> </div>
<div v-else>You do not have an active identity.</div> <div v-else>You do not have an active identity.</div>
<AlertMessage
:alertTitle="alertTitle"
:alertMessage="alertMessage"
></AlertMessage>
</section> </section>
</template> </template>
@ -64,9 +60,22 @@ import * as R from "ramda";
import { MASTER_SETTINGS_KEY } from "@/db/tables/settings"; import { MASTER_SETTINGS_KEY } from "@/db/tables/settings";
import QuickNav from "@/components/QuickNav.vue"; import QuickNav from "@/components/QuickNav.vue";
interface Account {
mnemonic: string;
}
interface Notification {
group: string;
type: string;
title: string;
text: string;
}
@Component({ components: { QuickNav } }) @Component({ components: { QuickNav } })
export default class SeedBackupView extends Vue { export default class SeedBackupView extends Vue {
activeAccount = null; $notify!: (notification: Notification, timeout?: number) => void;
activeAccount: Account | null | undefined = null;
numAccounts = 0; numAccounts = 0;
showSeed = false; showSeed = false;
@ -83,7 +92,7 @@ export default class SeedBackupView extends Vue {
this.activeAccount = R.find((acc) => acc.did === activeDid, accounts); this.activeAccount = R.find((acc) => acc.did === activeDid, accounts);
} catch (err: unknown) { } catch (err: unknown) {
console.error("Got an error loading an identity:", err); console.error("Got an error loading an identity:", err);
(this as any).$notify( this.$notify(
{ {
group: "alert", group: "alert",
type: "danger", type: "danger",

16
src/views/StatisticsView.vue

@ -39,7 +39,7 @@
<script lang="ts"> <script lang="ts">
import { SVGRenderer } from "three/addons/renderers/SVGRenderer.js"; import { SVGRenderer } from "three/addons/renderers/SVGRenderer.js";
import { Component, Vue } from "vue-facing-decorator"; import { Component, Vue } from "vue-facing-decorator";
import { World } from "components/World/World.js"; import { World } from "@/components/World/World.js";
import QuickNav from "@/components/QuickNav.vue"; import QuickNav from "@/components/QuickNav.vue";
interface RendererSVGType { interface RendererSVGType {
@ -50,8 +50,17 @@ interface Dictionary<T> {
[key: string]: T; [key: string]: T;
} }
interface Notification {
group: string;
type: string;
title: string;
text: string;
}
@Component({ components: { World, QuickNav } }) @Component({ components: { World, QuickNav } })
export default class StatisticsView extends Vue { export default class StatisticsView extends Vue {
$notify!: (notification: Notification, timeout?: number) => void;
world: World; world: World;
worldProperties: Dictionary<number> = {}; worldProperties: Dictionary<number> = {};
@ -61,9 +70,9 @@ export default class StatisticsView extends Vue {
const newWorld = new World(container, this); const newWorld = new World(container, this);
newWorld.start(); newWorld.start();
this.world = newWorld; this.world = newWorld;
} catch (err : unknown) { } catch (err: unknown) {
const error = err as Error; const error = err as Error;
(this as any).$notify( this.$notify(
{ {
group: "alert", group: "alert",
type: "danger", type: "danger",
@ -91,7 +100,6 @@ export default class StatisticsView extends Vue {
} }
} }
function ExportToSVG(rendererSVG: RendererSVGType, filename: string) { function ExportToSVG(rendererSVG: RendererSVGType, filename: string) {
const XMLS = new XMLSerializer(); const XMLS = new XMLSerializer();
const svgfile = XMLS.serializeToString(rendererSVG.domElement); const svgfile = XMLS.serializeToString(rendererSVG.domElement);

76
tsconfig.json

@ -1,41 +1,43 @@
{ {
"compilerOptions": { "compilerOptions": {
"target": "esnext", "allowJs": true,
"module": "esnext", "target": "esnext",
"strict": true, "module": "esnext",
"jsx": "preserve", "strict": true,
"moduleResolution": "node", "strictPropertyInitialization": false,
"experimentalDecorators": true, "jsx": "preserve",
"skipLibCheck": true, "moduleResolution": "node",
"esModuleInterop": true, "experimentalDecorators": true,
"allowSyntheticDefaultImports": true, "skipLibCheck": true,
"forceConsistentCasingInFileNames": true, "esModuleInterop": true,
"useDefineForClassFields": true, "allowSyntheticDefaultImports": true,
"sourceMap": true, "forceConsistentCasingInFileNames": true,
"baseUrl": ".", "useDefineForClassFields": true,
"types": [ "sourceMap": true,
"webpack-env" "baseUrl": ".",
], "types": [
"paths": { "webpack-env"
"@/*": [ ],
"src/*" "paths": {
] "@/*": [
"src/*"
]
},
"lib": [
"esnext",
"dom",
"dom.iterable",
"scripthost"
]
}, },
"lib": [ "include": [
"esnext", "src/**/*.ts",
"dom", "src/**/*.tsx",
"dom.iterable", "src/**/*.vue",
"scripthost" "tests/**/*.ts",
"tests/**/*.tsx"
],
"exclude": [
"node_modules"
] ]
},
"include": [
"src/**/*.ts",
"src/**/*.tsx",
"src/**/*.vue",
"tests/**/*.ts",
"tests/**/*.tsx"
],
"exclude": [
"node_modules"
]
} }

Loading…
Cancel
Save