From c6bb7b9d42ab2a95bd89a15dbbe671f742ceb294 Mon Sep 17 00:00:00 2001 From: Trent Larson Date: Fri, 24 Mar 2023 20:24:56 -0600 Subject: [PATCH 01/12] fix unconfirmed give display, and add alert on success --- project.yaml | 1 + src/views/ContactsView.vue | 68 ++++++++++++++++++++++---------------- 2 files changed, 40 insertions(+), 29 deletions(-) diff --git a/project.yaml b/project.yaml index 7560ea2..e459076 100644 --- a/project.yaml +++ b/project.yaml @@ -13,6 +13,7 @@ - contacts v1 : - test confirmed vs unconfirmed amounts + - allow to confirm received gives - remove 'copy' until it works - switch to prod server - 01 show gives with confirmations diff --git a/src/views/ContactsView.vue b/src/views/ContactsView.vue index 92fd648..d02d793 100644 --- a/src/views/ContactsView.vue +++ b/src/views/ContactsView.vue @@ -91,7 +91,7 @@ > {{ showGiveTotals - ? "Totals" + ? "Total" : showGiveConfirmed ? "Confirmed" : "Unconfirmed" @@ -176,7 +176,7 @@
- by: + from: {{ /* eslint-disable prettier/prettier */ this.showGiveTotals @@ -354,7 +354,7 @@ export default class ContactsView extends Vue { Authorization: "Bearer " + token, }; const resp = await this.axios.get(url, { headers }); - console.log("All your gifts:", resp.data); + console.log("All gifts you've given:", resp.data); if (resp.status === 200) { const contactDescriptions: Record = {}; const contactConfirmed: Record = {}; @@ -371,16 +371,27 @@ export default class ContactsView extends Vue { contactUnconfirmed[recipDid] = prevAmount + give.amount; } const prevDesc = contactDescriptions[recipDid] || ""; - // Since many make the tooltip too big, we'll just use the latest; + // Since many make the tooltip too big, we'll just use the latest. contactDescriptions[recipDid] = give.description || prevDesc; } } //console.log("Done retrieving gives", contactConfirmed); this.givenByMeDescriptions = contactDescriptions; this.givenByMeConfirmed = contactConfirmed; + this.givenByMeUnconfirmed = contactUnconfirmed; + } else { + console.log( + "Got bad response status & data of", + resp.status, + resp.data + ); + this.alertTitle = "Error With Server"; + this.alertMessage = + "Got an error retrieving your given time from the server."; + this.isAlertVisible = true; } } catch (error) { - this.alertTitle = "Error from Server"; + this.alertTitle = "Error With Server"; this.alertMessage = error as string; this.isAlertVisible = true; } @@ -413,16 +424,27 @@ export default class ContactsView extends Vue { contactUnconfirmed[give.agentDid] = prevAmount + give.amount; } const prevDesc = contactDescriptions[give.agentDid] || ""; - // Since many make the tooltip too big, we'll just use the latest; + // Since many make the tooltip too big, we'll just use the latest. contactDescriptions[give.agentDid] = give.description || prevDesc; } } //console.log("Done retrieving receipts", contactConfirmed); this.givenToMeDescriptions = contactDescriptions; this.givenToMeConfirmed = contactConfirmed; + this.givenToMeUnconfirmed = contactUnconfirmed; + } else { + console.log( + "Got bad response status & data of", + resp.status, + resp.data + ); + this.alertTitle = "Error With Server"; + this.alertMessage = + "Got an error retrieving your received time from the server."; + this.isAlertVisible = true; } } catch (error) { - this.alertTitle = "Error from Server"; + this.alertTitle = "Error With Server"; this.alertMessage = error as string; this.isAlertVisible = true; } @@ -518,7 +540,7 @@ export default class ContactsView extends Vue { userMessage = error as string; } // Now set that error for the user to see. - this.alertTitle = "Error with Server"; + this.alertTitle = "Error With Server"; this.alertMessage = userMessage; this.isAlertVisible = true; } @@ -548,7 +570,7 @@ export default class ContactsView extends Vue { contact.seesMe = visibility; db.contacts.update(contact.did, { seesMe: visibility }); } else { - this.alertTitle = "Error from Server"; + this.alertTitle = "Error With Server"; console.log("Bad response setting visibility: ", resp.data); if (resp.data.error?.message) { this.alertMessage = resp.data.error?.message; @@ -558,7 +580,7 @@ export default class ContactsView extends Vue { this.isAlertVisible = true; } } catch (err) { - this.alertTitle = "Error from Server"; + this.alertTitle = "Error With Server"; this.alertMessage = err as string; this.isAlertVisible = true; } @@ -594,7 +616,7 @@ export default class ContactsView extends Vue { "see your activity."; this.isAlertVisible = true; } else { - this.alertTitle = "Error from Server"; + this.alertTitle = "Error With Server"; if (resp.data.error?.message) { this.alertMessage = resp.data.error?.message; } else { @@ -603,7 +625,7 @@ export default class ContactsView extends Vue { this.isAlertVisible = true; } } catch (err) { - this.alertTitle = "Error from Server"; + this.alertTitle = "Error With Server"; this.alertMessage = err as string; this.isAlertVisible = true; } @@ -726,8 +748,9 @@ export default class ContactsView extends Vue { const resp = await this.axios.post(url, payload, { headers }); //console.log("Got resp data:", resp.data); if (resp.data?.success?.handleId) { - this.alertTitle = ""; - this.alertMessage = ""; + this.alertTitle = "Done"; + this.alertMessage = "Successfully logged time to the server."; + this.isAlertVisible = true; if (fromDid === identity.did) { this.givenByMeConfirmed[toDid] = this.givenByMeConfirmed[toDid] + amount; @@ -755,26 +778,13 @@ export default class ContactsView extends Vue { userMessage = error as string; } // Now set that error for the user to see. - this.alertTitle = "Error with Server"; + this.alertTitle = "Error With Server"; this.alertMessage = userMessage; this.isAlertVisible = true; } } } - public selectedGiveTotal( - contactGivesConfirmed: Record, - contactGivesUnconfirmed: Record, - did: string - ) { - /* eslint-disable prettier/prettier */ - this.showGiveTotals - ? ((contactGivesConfirmed[did] || 0) + (contactGivesUnconfirmed[did] || 0)) - : this.showGiveConfirmed - ? (contactGivesConfirmed[did] || 0) - : (contactGivesUnconfirmed[did] || 0); - /* eslint-enable prettier/prettier */ - } public toggleShowGiveTotals() { if (this.showGiveTotals) { this.showGiveTotals = false; @@ -817,7 +827,7 @@ export default class ContactsView extends Vue { public showGiveAmountsClassNames() { return { - "bg-slate-900": this.showGiveTotals, + "bg-slate-500": this.showGiveTotals, "bg-green-600": !this.showGiveTotals && this.showGiveConfirmed, "bg-yellow-600": !this.showGiveTotals && !this.showGiveConfirmed, }; From 9317b59231ec155c883da2b45f12e792e3e3688c Mon Sep 17 00:00:00 2001 From: Trent Larson Date: Fri, 24 Mar 2023 22:04:53 -0600 Subject: [PATCH 02/12] feat: add a page for details about contact transactions (which I'll fill in soon) --- src/router/index.ts | 34 +++++++------- src/views/CommitmentsView.vue | 3 -- src/views/ContactAmountsView.vue | 70 ++++++++++++++++++++++++++++ src/views/ContactsView.vue | 80 +++++++++++++++++++++----------- 4 files changed, 140 insertions(+), 47 deletions(-) delete mode 100644 src/views/CommitmentsView.vue create mode 100644 src/views/ContactAmountsView.vue diff --git a/src/router/index.ts b/src/router/index.ts index bc4b683..f9f5f82 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -23,12 +23,6 @@ const routes: Array = [ component: () => import(/* webpackChunkName: "about" */ "../views/AboutView.vue"), }, - { - path: "/start", - name: "start", - component: () => - import(/* webpackChunkName: "start" */ "../views/StartView.vue"), - }, { path: "/account", name: "account", @@ -43,6 +37,14 @@ const routes: Array = [ /* webpackChunkName: "confirm-contact" */ "../views/ConfirmContactView.vue" ), }, + { + path: "/contact-amounts", + name: "contact-amounts", + component: () => + import( + /* webpackChunkName: "contact-amounts" */ "../views/ContactAmountsView.vue" + ), + }, { path: "/contacts", name: "contacts", @@ -93,12 +95,6 @@ const routes: Array = [ /* webpackChunkName: "new-edit-commitment" */ "../views/NewEditCommitmentView.vue" ), }, - { - path: "/project", - name: "project", - component: () => - import(/* webpackChunkName: "project" */ "../views/ProjectViewView.vue"), - }, { path: "/new-edit-project", name: "new-edit-project", @@ -107,6 +103,12 @@ const routes: Array = [ /* webpackChunkName: "new-edit-project" */ "../views/NewEditProjectView.vue" ), }, + { + path: "/project", + name: "project", + component: () => + import(/* webpackChunkName: "project" */ "../views/ProjectViewView.vue"), + }, { path: "/projects", name: "projects", @@ -114,12 +116,10 @@ const routes: Array = [ import(/* webpackChunkName: "projects" */ "../views/ProjectsView.vue"), }, { - path: "/commitments", - name: "commitments", + path: "/start", + name: "start", component: () => - import( - /* webpackChunkName: "commitments" */ "../views/CommitmentsView.vue" - ), + import(/* webpackChunkName: "start" */ "../views/StartView.vue"), }, ]; diff --git a/src/views/CommitmentsView.vue b/src/views/CommitmentsView.vue deleted file mode 100644 index afa8167..0000000 --- a/src/views/CommitmentsView.vue +++ /dev/null @@ -1,3 +0,0 @@ - diff --git a/src/views/ContactAmountsView.vue b/src/views/ContactAmountsView.vue new file mode 100644 index 0000000..9ee06fb --- /dev/null +++ b/src/views/ContactAmountsView.vue @@ -0,0 +1,70 @@ + + + diff --git a/src/views/ContactsView.vue b/src/views/ContactsView.vue index d02d793..80ecc90 100644 --- a/src/views/ContactsView.vue +++ b/src/views/ContactsView.vue @@ -661,35 +661,61 @@ export default class ContactsView extends Vue { this.alertMessage = "No identity is available."; this.isAlertVisible = true; } else { - let toFrom; - if (fromDid == this.identity?.did) { - toFrom = "from you to " + this.nameForDid(this.contacts, toDid); - } else { - toFrom = "from " + this.nameForDid(this.contacts, fromDid) + " to you"; - } - let description; - if (this.hourDescriptionInput) { - description = " with description '" + this.hourDescriptionInput + "'"; - } else { - description = " with no description"; - } + // if they have unconfirmed amounts, ask to confirm those first + let wantsToConfirm = false; if ( - confirm( - "Are you sure you want to record " + - this.hourInput + - " hours " + - toFrom + - description + - "?" - ) + toDid == this.identity?.did && + this.givenToMeUnconfirmed[fromDid] > 0 ) { - this.createAndSubmitGive( - this.identity, - fromDid, - toDid, - parseFloat(this.hourInput), - this.hourDescriptionInput - ); + if ( + confirm( + "There are " + + this.givenToMeUnconfirmed[fromDid] + + " unconfirmed hours from them." + + " Would you like to confirm some of those hours?" + ) + ) { + wantsToConfirm = true; + } + } + if (wantsToConfirm) { + this.$router.push({ + name: "contact-amounts", + query: { contactDid: fromDid }, + }); + } else { + // ask to confirm amount + let toFrom; + if (fromDid == this.identity?.did) { + toFrom = "from you to " + this.nameForDid(this.contacts, toDid); + } else { + toFrom = + "from " + this.nameForDid(this.contacts, fromDid) + " to you"; + } + let description; + if (this.hourDescriptionInput) { + description = " with description '" + this.hourDescriptionInput + "'"; + } else { + description = " with no description"; + } + if ( + confirm( + "Are you sure you want to record " + + this.hourInput + + " hours " + + toFrom + + description + + "?" + ) + ) { + this.createAndSubmitGive( + this.identity, + fromDid, + toDid, + parseFloat(this.hourInput), + this.hourDescriptionInput + ); + } } } } From f281e41181759bf90eac0f56a9125d32e3da3d78 Mon Sep 17 00:00:00 2001 From: Trent Larson Date: Sat, 25 Mar 2023 19:03:25 -0600 Subject: [PATCH 03/12] add details on contact-specific page --- project.yaml | 1 + src/constants/app.ts | 2 +- src/libs/endorserServer.ts | 30 +++++ src/main.ts | 8 ++ src/views/ContactAmountsView.vue | 212 +++++++++++++++++++++++++++++- src/views/ContactsView.vue | 219 ++++++++++++++----------------- 6 files changed, 347 insertions(+), 125 deletions(-) create mode 100644 src/libs/endorserServer.ts diff --git a/project.yaml b/project.yaml index e459076..e341de0 100644 --- a/project.yaml +++ b/project.yaml @@ -30,6 +30,7 @@ - refactor UI : - .5 Alerts show at the top and can be missed, eg. account data download + - 01 Change alerts into a component (to cut down duplicate code) - 01 Code for "nav" tabs across the bottom is duplicated on each page. - .2 Add "copied" feedback when they click "copy" on /account diff --git a/src/constants/app.ts b/src/constants/app.ts index 719735b..60be120 100644 --- a/src/constants/app.ts +++ b/src/constants/app.ts @@ -2,7 +2,7 @@ * Generic strings that could be used throughout the app. */ export enum AppString { - APP_NAME = "Kickstart for time", + APP_NAME = "KickStart with Time", VERSION = "0.1", DEFAULT_ENDORSER_API_SERVER = "https://test.endorser.ch:8000", //DEFAULT_ENDORSER_API_SERVER = "http://localhost:3000", diff --git a/src/libs/endorserServer.ts b/src/libs/endorserServer.ts new file mode 100644 index 0000000..ee15d2a --- /dev/null +++ b/src/libs/endorserServer.ts @@ -0,0 +1,30 @@ +export const SERVICE_ID = "endorser.ch"; + +export interface GiveServerRecord { + agentDid: string; + amount: number; + confirmed: number; + description: string; + fullClaim: GiveVerifiableCredential; + handleId: string; + issuedAt: string; + recipientDid: string; + unit: string; +} + +export interface GiveVerifiableCredential { + "@context": string; + "@type": string; + agent: { identifier: string }; + description?: string; + object: { amountOfThisGood: number; unitCode: string }; + recipient: { identifier: string }; +} + +export interface RegisterVerifiableCredential { + "@context": string; + "@type": string; + agent: { identifier: string }; + object: string; + recipient: { identifier: string }; +} diff --git a/src/main.ts b/src/main.ts index 88dbedb..cdb751d 100644 --- a/src/main.ts +++ b/src/main.ts @@ -12,6 +12,7 @@ import { library } from "@fortawesome/fontawesome-svg-core"; import { faCalendar, faChevronLeft, + faCircle, faCircleCheck, faCircleQuestion, faCircleUser, @@ -19,9 +20,12 @@ import { faEllipsisVertical, faEye, faEyeSlash, + faFileLines, faFolderOpen, faHand, faHouseChimney, + faLongArrowAltLeft, + faLongArrowAltRight, faMagnifyingGlass, faPen, faPersonCircleCheck, @@ -40,6 +44,7 @@ import { library.add( faCalendar, faChevronLeft, + faCircle, faCircleCheck, faCircleQuestion, faCircleUser, @@ -47,9 +52,12 @@ library.add( faEllipsisVertical, faEye, faEyeSlash, + faFileLines, faFolderOpen, faHand, faHouseChimney, + faLongArrowAltLeft, + faLongArrowAltRight, faMagnifyingGlass, faPen, faPersonCircleCheck, diff --git a/src/views/ContactAmountsView.vue b/src/views/ContactAmountsView.vue index 9ee06fb..ebbf5e1 100644 --- a/src/views/ContactAmountsView.vue +++ b/src/views/ContactAmountsView.vue @@ -45,26 +45,232 @@

- Transactions with {{ contact?.name }} + Given with {{ contact?.name }}

-
{{ contact?.did }}
+ + +
+
+
+
from them
+
+
to them
+
+
+
+ {{ new Date(record.issuedAt).toLocaleString() }} +
+
+ +
+ {{ record.amount }} {{ record.unit }} + + + Confirmed + + + + Unconfirmed + +
+
+ {{ record.description }} +
+
+
+ + + + +            + + +
+
+ +
+ {{ record.amount }} {{ record.unit }} + + + Confirmed + + + + Unconfirmed + +
+
+ {{ record.description }} +
+
+
+
+ + diff --git a/src/views/ContactsView.vue b/src/views/ContactsView.vue index 80ecc90..86ab9c8 100644 --- a/src/views/ContactsView.vue +++ b/src/views/ContactsView.vue @@ -122,10 +122,10 @@ @click="setVisibility(contact, false)" > - Can see you + They can see you @@ -135,11 +135,11 @@
+ + + See All Given Activity + @@ -223,44 +233,20 @@ import { IIdentifier } from "@veramo/core"; import { Options, Vue } from "vue-class-component"; import { AppString } from "@/constants/app"; -import { accessToken, SimpleSigner } from "@/libs/crypto"; import { accountsDB, db } from "@/db"; import { Contact } from "@/db/tables/contacts"; import { MASTER_SETTINGS_KEY } from "@/db/tables/settings"; +import { accessToken, SimpleSigner } from "@/libs/crypto"; +import { + GiveServerRecord, + GiveVerifiableCredential, + RegisterVerifiableCredential, + SERVICE_ID, +} from "@/libs/endorserServer"; // eslint-disable-next-line @typescript-eslint/no-var-requires const Buffer = require("buffer/").Buffer; -const SERVICE_ID = "endorser.ch"; - -export interface GiveServerRecord { - agentDid: string; - amount: number; - confirmed: number; - description: string; - fullClaim: GiveVerifiableCredential; - handleId: string; - recipientDid: string; - unit: string; -} - -export interface GiveVerifiableCredential { - "@context": string; - "@type": string; - agent: { identifier: string }; - description?: string; - object: { amountOfThisGood: number; unitCode: string }; - recipient: { identifier: string }; -} - -export interface RegisterVerifiableCredential { - "@context": string; - "@type": string; - agent: { identifier: string }; - object: string; - recipient: { identifier: string }; -} - @Options({ components: {}, }) @@ -305,33 +291,6 @@ export default class ContactsView extends Vue { ); } - async onClickNewContact(): Promise { - let did = this.contactInput; - let name, publicKeyBase64; - const commaPos1 = this.contactInput.indexOf(","); - if (commaPos1 > -1) { - did = this.contactInput.substring(0, commaPos1).trim(); - name = this.contactInput.substring(commaPos1 + 1).trim(); - const commaPos2 = this.contactInput.indexOf(",", commaPos1 + 1); - if (commaPos2 > -1) { - name = this.contactInput.substring(commaPos1 + 1, commaPos2).trim(); - publicKeyBase64 = this.contactInput.substring(commaPos2 + 1).trim(); - } - } - // help with potential mistakes while this sharing requires copy-and-paste - if (publicKeyBase64 && /^[0-9A-Fa-f]{66}$/i.test(publicKeyBase64)) { - // it must be all hex (compressed public key), so convert - publicKeyBase64 = Buffer.from(publicKeyBase64, "hex").toString("base64"); - } - const newContact = { did, name, publicKeyBase64 }; - await db.contacts.add(newContact); - const allContacts = this.contacts.concat([newContact]); - this.contacts = R.sort( - (a: Contact, b) => (a.name || "").localeCompare(b.name || ""), - allContacts - ); - } - async loadGives() { if (!this.identity) { console.error( @@ -346,7 +305,7 @@ export default class ContactsView extends Vue { try { const url = endorserApiServer + - "/api/v2/report/gives?agentId=" + + "/api/v2/report/gives?agentDid=" + encodeURIComponent(this.identity?.did); const token = await accessToken(this.identity); const headers = { @@ -400,7 +359,7 @@ export default class ContactsView extends Vue { try { const url = endorserApiServer + - "/api/v2/report/gives?recipientId=" + + "/api/v2/report/gives?recipientDid=" + encodeURIComponent(this.identity.did); const token = await accessToken(this.identity); const headers = { @@ -450,6 +409,33 @@ export default class ContactsView extends Vue { } } + async onClickNewContact(): Promise { + let did = this.contactInput; + let name, publicKeyBase64; + const commaPos1 = this.contactInput.indexOf(","); + if (commaPos1 > -1) { + did = this.contactInput.substring(0, commaPos1).trim(); + name = this.contactInput.substring(commaPos1 + 1).trim(); + const commaPos2 = this.contactInput.indexOf(",", commaPos1 + 1); + if (commaPos2 > -1) { + name = this.contactInput.substring(commaPos1 + 1, commaPos2).trim(); + publicKeyBase64 = this.contactInput.substring(commaPos2 + 1).trim(); + } + } + // help with potential mistakes while this sharing requires copy-and-paste + if (publicKeyBase64 && /^[0-9A-Fa-f]{66}$/i.test(publicKeyBase64)) { + // it must be all hex (compressed public key), so convert + publicKeyBase64 = Buffer.from(publicKeyBase64, "hex").toString("base64"); + } + const newContact = { did, name, publicKeyBase64 }; + await db.contacts.add(newContact); + const allContacts = this.contacts.concat([newContact]); + this.contacts = R.sort( + (a: Contact, b) => (a.name || "").localeCompare(b.name || ""), + allContacts + ); + } + async deleteContact(contact: Contact) { if ( confirm( @@ -647,6 +633,22 @@ export default class ContactsView extends Vue { } async onClickAddGive(fromDid: string, toDid: string): Promise { + // if they have unconfirmed amounts, ask to confirm those first + if (toDid == this.identity?.did && this.givenToMeUnconfirmed[fromDid] > 0) { + if ( + confirm( + "There are " + + this.givenToMeUnconfirmed[fromDid] + + " unconfirmed hours from them." + + " Would you like to confirm some of those hours?" + ) + ) { + this.$router.push({ + name: "contact-amounts", + query: { contactDid: fromDid }, + }); + } + } if (!this.isNumeric(this.hourInput)) { this.alertTitle = "Input Error"; this.alertMessage = @@ -661,61 +663,36 @@ export default class ContactsView extends Vue { this.alertMessage = "No identity is available."; this.isAlertVisible = true; } else { - // if they have unconfirmed amounts, ask to confirm those first - let wantsToConfirm = false; - if ( - toDid == this.identity?.did && - this.givenToMeUnconfirmed[fromDid] > 0 - ) { - if ( - confirm( - "There are " + - this.givenToMeUnconfirmed[fromDid] + - " unconfirmed hours from them." + - " Would you like to confirm some of those hours?" - ) - ) { - wantsToConfirm = true; - } + // ask to confirm amount + let toFrom; + if (fromDid == this.identity?.did) { + toFrom = "from you to " + this.nameForDid(this.contacts, toDid); + } else { + toFrom = "from " + this.nameForDid(this.contacts, fromDid) + " to you"; } - if (wantsToConfirm) { - this.$router.push({ - name: "contact-amounts", - query: { contactDid: fromDid }, - }); + let description; + if (this.hourDescriptionInput) { + description = " with description '" + this.hourDescriptionInput + "'"; } else { - // ask to confirm amount - let toFrom; - if (fromDid == this.identity?.did) { - toFrom = "from you to " + this.nameForDid(this.contacts, toDid); - } else { - toFrom = - "from " + this.nameForDid(this.contacts, fromDid) + " to you"; - } - let description; - if (this.hourDescriptionInput) { - description = " with description '" + this.hourDescriptionInput + "'"; - } else { - description = " with no description"; - } - if ( - confirm( - "Are you sure you want to record " + - this.hourInput + - " hours " + - toFrom + - description + - "?" - ) - ) { - this.createAndSubmitGive( - this.identity, - fromDid, - toDid, - parseFloat(this.hourInput), - this.hourDescriptionInput - ); - } + description = " with no description"; + } + if ( + confirm( + "Are you sure you want to record " + + this.hourInput + + " hours " + + toFrom + + description + + "?" + ) + ) { + this.createAndSubmitGive( + this.identity, + fromDid, + toDid, + parseFloat(this.hourInput), + this.hourDescriptionInput + ); } } } From 25b9dce669f4ce407ae36de4f443f0f8d04824a2 Mon Sep 17 00:00:00 2001 From: Trent Larson Date: Sat, 25 Mar 2023 19:47:36 -0600 Subject: [PATCH 04/12] fix the on-screen total update for unconfirmed amount --- src/views/ContactsView.vue | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/src/views/ContactsView.vue b/src/views/ContactsView.vue index 86ab9c8..574efe3 100644 --- a/src/views/ContactsView.vue +++ b/src/views/ContactsView.vue @@ -755,17 +755,13 @@ export default class ContactsView extends Vue { this.alertMessage = "Successfully logged time to the server."; this.isAlertVisible = true; if (fromDid === identity.did) { - this.givenByMeConfirmed[toDid] = - this.givenByMeConfirmed[toDid] + amount; - // do this to update the UI (is there a better way?) - // eslint-disable-next-line no-self-assign - this.givenByMeConfirmed = this.givenByMeConfirmed; + const newList = R.clone(this.givenByMeUnconfirmed); + newList[toDid] = (newList[toDid] || 0) + amount; + this.givenByMeUnconfirmed = newList; } else { - this.givenToMeConfirmed[fromDid] = - this.givenToMeConfirmed[fromDid] + amount; - // do this to update the UI (is there a better way?) - // eslint-disable-next-line no-self-assign - this.givenToMeConfirmed = this.givenToMeConfirmed; + const newList = R.clone(this.givenToMeConfirmed); + newList[fromDid] = (newList[fromDid] || 0) + amount; + this.givenToMeConfirmed = newList; } } } catch (error) { From eadcc22e9ab97419479959d6b9e0fb35b3e92a98 Mon Sep 17 00:00:00 2001 From: Trent Larson Date: Sat, 25 Mar 2023 19:53:18 -0600 Subject: [PATCH 05/12] fix sort order of items on contact given-amounts page --- project.yaml | 1 + src/views/ContactAmountsView.vue | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/project.yaml b/project.yaml index e341de0..b6ed7a2 100644 --- a/project.yaml +++ b/project.yaml @@ -33,6 +33,7 @@ - 01 Change alerts into a component (to cut down duplicate code) - 01 Code for "nav" tabs across the bottom is duplicated on each page. - .2 Add "copied" feedback when they click "copy" on /account + - .5 Fix how icons show on top of bottom bar on ContactAmounts page - commit screen diff --git a/src/views/ContactAmountsView.vue b/src/views/ContactAmountsView.vue index ebbf5e1..5bf58d8 100644 --- a/src/views/ContactAmountsView.vue +++ b/src/views/ContactAmountsView.vue @@ -203,7 +203,8 @@ export default class ContactsView extends Vue { } const sortedResult: Array = R.sort( - (a, b) => new Date(a).getTime() - new Date(b).getTime(), + (a, b) => + new Date(b.issuedAt).getTime() - new Date(a.issuedAt).getTime(), result ); this.giveRecords = sortedResult; From 2e530518b10cb27f61f54e88ce93fb7ae17bbbbf Mon Sep 17 00:00:00 2001 From: Trent Larson Date: Sat, 25 Mar 2023 20:00:58 -0600 Subject: [PATCH 06/12] fix latest transaction description tooltip --- src/views/ContactsView.vue | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/views/ContactsView.vue b/src/views/ContactsView.vue index 574efe3..338eb55 100644 --- a/src/views/ContactsView.vue +++ b/src/views/ContactsView.vue @@ -329,9 +329,10 @@ export default class ContactsView extends Vue { const prevAmount = contactUnconfirmed[recipDid] || 0; contactUnconfirmed[recipDid] = prevAmount + give.amount; } - const prevDesc = contactDescriptions[recipDid] || ""; - // Since many make the tooltip too big, we'll just use the latest. - contactDescriptions[recipDid] = give.description || prevDesc; + if (!contactDescriptions[recipDid] && give.description) { + // Since many make the tooltip too big, we'll just use the latest. + contactDescriptions[recipDid] = give.description; + } } } //console.log("Done retrieving gives", contactConfirmed); @@ -382,9 +383,10 @@ export default class ContactsView extends Vue { const prevAmount = contactUnconfirmed[give.agentDid] || 0; contactUnconfirmed[give.agentDid] = prevAmount + give.amount; } - const prevDesc = contactDescriptions[give.agentDid] || ""; - // Since many make the tooltip too big, we'll just use the latest. - contactDescriptions[give.agentDid] = give.description || prevDesc; + if (!contactDescriptions[give.agentDid] && give.description) { + // Since many make the tooltip too big, we'll just use the latest. + contactDescriptions[give.agentDid] = give.description; + } } } //console.log("Done retrieving receipts", contactConfirmed); From 6c05d3105ff55544fe7192732c2976913b44249b Mon Sep 17 00:00:00 2001 From: Trent Larson Date: Sat, 25 Mar 2023 21:43:51 -0600 Subject: [PATCH 07/12] parameterize main identifier (to prepare the way for multiple) --- project.yaml | 2 ++ src/db/tables/accounts.ts | 3 +- src/db/tables/settings.ts | 3 +- src/test/index.ts | 12 +++---- src/views/AccountViewView.vue | 45 +++++++++++++++++-------- src/views/ContactAmountsView.vue | 17 ++++++---- src/views/ContactsView.vue | 56 ++++++++++++++++++++------------ src/views/ImportAccountView.vue | 13 +++++++- src/views/NewEditProjectView.vue | 26 ++++++++++----- src/views/ProjectViewView.vue | 18 +++++++--- src/views/ProjectsView.vue | 14 ++++++-- 11 files changed, 142 insertions(+), 67 deletions(-) diff --git a/project.yaml b/project.yaml index b6ed7a2..7cfc3cd 100644 --- a/project.yaml +++ b/project.yaml @@ -24,6 +24,8 @@ - get 'copy' to work on account page - contacts v+ : + - .2 warn about amounts when you cannot see them + - .2 confirmed direction is wrong on ContactAmounts screen - .5 make advanced "show/hide amounts" button into a nice UI toggle - .2 show error to user when adding a duplicate contact - parse input more robustly (with CSV lib and not commas) diff --git a/src/db/tables/accounts.ts b/src/db/tables/accounts.ts index 9602439..b42e55a 100644 --- a/src/db/tables/accounts.ts +++ b/src/db/tables/accounts.ts @@ -2,6 +2,7 @@ export type Account = { id?: number; // auto-generated by Dexie dateCreated: string; derivationPath: string; + did: string; identity: string; publicKeyHex: string; mnemonic: string; @@ -11,5 +12,5 @@ export type Account = { // see https://github.com/PVermeer/dexie-addon-suite-monorepo/tree/master/packages/dexie-encrypted-addon export const AccountsSchema = { accounts: - "++id, dateCreated, derivationPath, $identity, $mnemonic, publicKeyHex", + "++id, dateCreated, derivationPath, did, $identity, $mnemonic, publicKeyHex", }; diff --git a/src/db/tables/settings.ts b/src/db/tables/settings.ts index 1da602a..a2233ec 100644 --- a/src/db/tables/settings.ts +++ b/src/db/tables/settings.ts @@ -1,6 +1,7 @@ // a singleton export type Settings = { - id: number; + id: number; // there's only one entry: MASTER_SETTINGS_KEY + activeDid?: string; firstName?: string; lastName?: string; showContactGivesInline?: boolean; diff --git a/src/test/index.ts b/src/test/index.ts index fe593da..2403a9f 100644 --- a/src/test/index.ts +++ b/src/test/index.ts @@ -1,9 +1,10 @@ import axios from "axios"; import * as didJwt from "did-jwt"; import { AppString } from "@/constants/app"; -import { accountsDB } from "../db"; +import { db } from "../db"; import { SERVICE_ID } from "../libs/veramo/setup"; import { deriveAddress, newIdentifier } from "../libs/crypto"; +import { MASTER_SETTINGS_KEY } from "@/db/tables/settings"; export async function testServerRegisterUser() { const testUser0Mnem = @@ -13,9 +14,8 @@ export async function testServerRegisterUser() { const identity0 = newIdentifier(addr, publicHex, privateHex, deriPath); - await accountsDB.open(); - const accounts = await accountsDB.accounts.toArray(); - const thisIdentity = JSON.parse(accounts[0].identity); + await db.open(); + const settings = await db.settings.get(MASTER_SETTINGS_KEY); // Make a claim const vcClaim = { @@ -23,7 +23,7 @@ export async function testServerRegisterUser() { "@type": "RegisterAction", agent: { did: identity0.did }, object: SERVICE_ID, - participant: { did: thisIdentity.did }, + participant: { did: settings?.activeDid }, }; // Make a payload for the claim const vcPayload = { @@ -56,5 +56,5 @@ export async function testServerRegisterUser() { }; const resp = await axios.post(url, payload, { headers }); - console.log("Result:", resp); + console.log("User registration result:", resp); } diff --git a/src/views/AccountViewView.vue b/src/views/AccountViewView.vue index 243cc46..7546589 100644 --- a/src/views/AccountViewView.vue +++ b/src/views/AccountViewView.vue @@ -240,8 +240,11 @@