Browse Source

add contact-methods to a contact

master
Trent Larson 2 weeks ago
parent
commit
3c1731acdf
  1. 2
      src/App.vue
  2. 7
      src/db/tables/contacts.ts
  3. 2
      src/main.ts
  4. 12
      src/views/ClaimView.vue
  5. 115
      src/views/ContactEditView.vue
  6. 7
      src/views/ContactsView.vue

2
src/App.vue

@ -332,7 +332,7 @@ export default class App extends Vue {
truncateLongWords(sentence: string) {
return sentence
.split(" ")
.map(word => (word.length > 30 ? word.slice(0, 30) + "..." : word))
.map((word) => (word.length > 30 ? word.slice(0, 30) + "..." : word))
.join(" ");
}

7
src/db/tables/contacts.ts

@ -1,5 +1,12 @@
export interface ContactMethod {
label: string;
type: string; // eg. "EMAIL", "SMS", "WHATSAPP"
value: string;
}
export interface Contact {
did: string;
contactMethods?: Array<ContactMethod>;
name?: string;
nextPubKeyHashB64?: string; // base64-encoded SHA256 hash of next public key
notes?: string;

2
src/main.ts

@ -22,6 +22,7 @@ import {
faBurst,
faCalendar,
faCamera,
faCaretDown,
faCheck,
faChevronDown,
faChevronLeft,
@ -98,6 +99,7 @@ library.add(
faBurst,
faCalendar,
faCamera,
faCaretDown,
faCheck,
faChevronDown,
faChevronLeft,

12
src/views/ClaimView.vue

@ -346,12 +346,12 @@
<!-- Note that a similar section is found in ConfirmGiftView.vue -->
<h2
class="font-bold uppercase text-xl text-blue-500 mt-8 cursor-pointer"
@click="showVeriClaimDump = !showVeriClaimDump"
>
Details
<fa v-if="showVeriClaimDump" icon="chevron-up" />
<fa v-else icon="chevron-right" />
class="font-bold uppercase text-xl text-blue-500 mt-8 cursor-pointer"
@click="showVeriClaimDump = !showVeriClaimDump"
>
Details
<fa v-if="showVeriClaimDump" icon="chevron-up" />
<fa v-else icon="chevron-right" />
</h2>
<div v-if="showVeriClaimDump">
<div

115
src/views/ContactEditView.vue

@ -44,8 +44,77 @@
></textarea>
</div>
<!-- Contact Methods -->
<div class="mt-4">
<h2 class="text-lg font-medium text-gray-700">Contact Methods</h2>
<div
v-for="(method, index) in contactMethods"
:key="index"
class="flex mt-2"
>
<input
type="text"
v-model="method.label"
class="block w-1/4 border border-gray-300 rounded-md shadow-sm focus:ring-indigo-500 focus:border-indigo-500"
placeholder="Label"
/>
<input
type="text"
v-model="method.type"
class="block ml-2 w-1/4 border border-gray-300 rounded-md shadow-sm focus:ring-indigo-500 focus:border-indigo-500"
placeholder="Type"
/>
<div class="relative">
<button
@click="toggleDropdown(index)"
class="px-2 py-1 bg-gray-200 rounded-md"
>
<fa icon="caret-down" class="fa-fw" />
</button>
<div
v-if="dropdownIndex === index"
class="absolute bg-white border border-gray-300 rounded-md mt-1"
>
<div
@click="setMethodType(index, 'CELL')"
class="px-4 py-2 hover:bg-gray-100 cursor-pointer"
>
CELL
</div>
<div
@click="setMethodType(index, 'EMAIL')"
class="px-4 py-2 hover:bg-gray-100 cursor-pointer"
>
EMAIL
</div>
<div
@click="setMethodType(index, 'WHATSAPP')"
class="px-4 py-2 hover:bg-gray-100 cursor-pointer"
>
WHATSAPP
</div>
</div>
</div>
<input
type="text"
v-model="method.value"
class="block ml-2 w-1/2 border border-gray-300 rounded-md shadow-sm focus:ring-indigo-500 focus:border-indigo-500"
placeholder="Number, email, etc."
/>
<button @click="removeContactMethod(index)" class="ml-2 text-red-500">
<fa icon="trash-can" class="fa-fw" />
</button>
</div>
<button @click="addContactMethod" class="mt-2">
<fa
icon="plus"
class="fa-fw px-2 py-2.5 bg-green-500 text-green-100 rounded-full"
/>
</button>
</div>
<!-- Save Button -->
<div class="mt-4 flex justify-between">
<div class="mt-8 flex justify-between">
<button
class="px-4 py-2 bg-blue-500 text-white rounded-md"
@click="saveEdit"
@ -63,6 +132,7 @@
</template>
<script lang="ts">
import * as R from "ramda";
import { Component, Vue } from "vue-facing-decorator";
import { RouteLocation, Router } from "vue-router";
@ -70,7 +140,7 @@ import QuickNav from "@/components/QuickNav.vue";
import TopMessage from "@/components/TopMessage.vue";
import { AppString, NotificationIface } from "@/constants/app";
import { db } from "@/db/index";
import { Contact } from "@/db/tables/contacts";
import { Contact, ContactMethod } from "@/db/tables/contacts";
@Component({
components: {
@ -88,6 +158,8 @@ export default class ContactEditView extends Vue {
};
contactName = "";
contactNotes = "";
contactMethods: Array<ContactMethod> = [];
dropdownIndex: number | null = null;
AppString = AppString;
@ -98,6 +170,7 @@ export default class ContactEditView extends Vue {
this.contact = contact;
this.contactName = contact.name || "";
this.contactNotes = contact.notes || "";
this.contactMethods = contact.contactMethods || [];
} else {
this.$notify({
group: "alert",
@ -110,16 +183,52 @@ export default class ContactEditView extends Vue {
}
}
addContactMethod() {
this.contactMethods.push({ label: "", type: "", value: "" });
}
removeContactMethod(index: number) {
this.contactMethods.splice(index, 1);
}
toggleDropdown(index: number) {
this.dropdownIndex = this.dropdownIndex === index ? null : index;
}
setMethodType(index: number, type: string) {
this.contactMethods[index].type = type;
this.dropdownIndex = null;
}
async saveEdit() {
// without this conversion, "Failed to execute 'put' on 'IDBObjectStore': [object Array] could not be cloned."
const contactMethodsObj = JSON.parse(JSON.stringify(this.contactMethods));
const contactMethods = contactMethodsObj.map((method: ContactMethod) =>
R.set(R.lensProp("type"), method.type.toUpperCase(), method),
);
if (!R.equals(contactMethodsObj, contactMethods)) {
this.contactMethods = contactMethods;
this.$notify(
{
group: "alert",
type: "warning",
title: "Contact Methods Updated",
text: "Note that some methods have been updated, such as uppercasing 'email' to 'EMAIL'. Save again if the changes are acceptable.",
},
15000,
);
return;
}
await db.contacts.update(this.contact.did, {
name: this.contactName,
notes: this.contactNotes,
contactMethods: contactMethods,
});
this.$notify({
group: "alert",
type: "success",
title: "Notes Saved",
text: "The contact notes have been updated successfully.",
text: "The contact info has been updated successfully.",
});
(this.$router as Router).push({
path: "/did/" + encodeURIComponent(this.contact.did),

7
src/views/ContactsView.vue

@ -174,7 +174,9 @@
data-testId="contactCheckOne"
/>
<h2 class="text-base font-semibold ml-2 w-1/3 truncate flex-shrink-0">
<h2
class="text-base font-semibold ml-2 w-1/3 truncate flex-shrink-0"
>
{{ contactNameNonBreakingSpace(contact.name) }}
</h2>
@ -191,8 +193,7 @@
<span class="ml-4 text-sm overflow-hidden">{{
shortDid(contact.did)
}}</span
>
}}</span>
</div>
<div class="ml-4 text-sm">
{{ contact.notes }}

Loading…
Cancel
Save