Fix duplicate export declarations and migrate ContactsView with sub-components
- Remove duplicate NOTIFY_INVITE_MISSING and NOTIFY_INVITE_PROCESSING_ERROR exports - Update InviteOneAcceptView.vue to use correct NOTIFY_INVITE_TRUNCATED_DATA constant - Migrate ContactsView to PlatformServiceMixin and extract into modular sub-components - Resolves TypeScript compilation errors preventing web build
This commit is contained in:
182
src/components/ContactListItem.vue
Normal file
182
src/components/ContactListItem.vue
Normal file
@@ -0,0 +1,182 @@
|
||||
<template>
|
||||
<li class="border-b border-slate-300 pt-1 pb-1" data-testId="contactListItem">
|
||||
<div class="flex items-center justify-between gap-3">
|
||||
<!-- Contact Info Section -->
|
||||
<div class="flex overflow-hidden min-w-0 items-center gap-3">
|
||||
<input
|
||||
v-if="showCheckbox"
|
||||
type="checkbox"
|
||||
:checked="isSelected"
|
||||
class="ml-2 h-6 w-6 flex-shrink-0"
|
||||
data-testId="contactCheckOne"
|
||||
@click="$emit('toggle-selection', contact.did)"
|
||||
/>
|
||||
|
||||
<EntityIcon
|
||||
:contact="contact"
|
||||
:icon-size="48"
|
||||
class="shrink-0 align-text-bottom border border-slate-300 rounded cursor-pointer overflow-hidden"
|
||||
@click="$emit('show-identicon', contact)"
|
||||
/>
|
||||
|
||||
<div class="overflow-hidden">
|
||||
<h2 class="text-base font-semibold truncate">
|
||||
<router-link
|
||||
:to="{
|
||||
path: '/did/' + encodeURIComponent(contact.did),
|
||||
}"
|
||||
title="See more about this person"
|
||||
>
|
||||
{{ contactNameNonBreakingSpace(contact.name) }}
|
||||
</router-link>
|
||||
</h2>
|
||||
|
||||
<div class="flex gap-1.5 items-center overflow-hidden">
|
||||
<router-link
|
||||
:to="{
|
||||
path: '/did/' + encodeURIComponent(contact.did),
|
||||
}"
|
||||
title="See more about this person"
|
||||
>
|
||||
<font-awesome
|
||||
icon="circle-info"
|
||||
class="text-base text-blue-500"
|
||||
/>
|
||||
</router-link>
|
||||
|
||||
<span class="text-xs truncate">{{ contact.did }}</span>
|
||||
</div>
|
||||
<div class="text-sm">
|
||||
{{ contact.notes }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Contact Actions Section -->
|
||||
<div
|
||||
v-if="showActions && contact.did !== activeDid"
|
||||
class="flex gap-1.5 items-end"
|
||||
>
|
||||
<div class="text-center">
|
||||
<div class="text-xs leading-none mb-1">From/To</div>
|
||||
<div class="flex items-center">
|
||||
<button
|
||||
class="text-sm bg-gradient-to-b from-blue-400 to-blue-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-2.5 py-1.5 rounded-l-md"
|
||||
:title="getGiveDescriptionForContact(contact.did, true)"
|
||||
@click="$emit('show-gifted-dialog', contact.did, activeDid)"
|
||||
>
|
||||
{{ getGiveAmountForContact(contact.did, true) }}
|
||||
</button>
|
||||
|
||||
<button
|
||||
class="text-sm bg-gradient-to-b from-blue-400 to-blue-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-2.5 py-1.5 rounded-r-md border-l"
|
||||
:title="getGiveDescriptionForContact(contact.did, false)"
|
||||
@click="$emit('show-gifted-dialog', activeDid, contact.did)"
|
||||
>
|
||||
{{ getGiveAmountForContact(contact.did, false) }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button
|
||||
class="text-sm bg-gradient-to-b from-blue-400 to-blue-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-2 py-1.5 rounded-md"
|
||||
data-testId="offerButton"
|
||||
@click="$emit('open-offer-dialog', contact.did, contact.name)"
|
||||
>
|
||||
Offer
|
||||
</button>
|
||||
|
||||
<router-link
|
||||
:to="{
|
||||
name: 'contact-amounts',
|
||||
query: { contactDid: contact.did },
|
||||
}"
|
||||
class="text-sm bg-gradient-to-b from-slate-400 to-slate-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-2 py-1.5 rounded-md"
|
||||
title="See more given activity"
|
||||
>
|
||||
<font-awesome icon="file-lines" class="fa-fw" />
|
||||
</router-link>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { Component, Vue, Prop } from "vue-facing-decorator";
|
||||
import EntityIcon from "./EntityIcon.vue";
|
||||
import { Contact } from "../db/tables/contacts";
|
||||
import { AppString } from "../constants/app";
|
||||
|
||||
/**
|
||||
* ContactListItem - Individual contact display component
|
||||
*
|
||||
* Displays a single contact with their information, selection checkbox,
|
||||
* and action buttons. Handles contact interactions and emits events
|
||||
* for parent component handling.
|
||||
*
|
||||
* @author Matthew Raymer
|
||||
*/
|
||||
@Component({
|
||||
name: "ContactListItem",
|
||||
components: {
|
||||
EntityIcon,
|
||||
},
|
||||
})
|
||||
export default class ContactListItem extends Vue {
|
||||
@Prop({ required: true }) contact!: Contact;
|
||||
@Prop({ required: true }) activeDid!: string;
|
||||
@Prop({ default: false }) showCheckbox!: boolean;
|
||||
@Prop({ default: false }) showActions!: boolean;
|
||||
@Prop({ default: false }) isSelected!: boolean;
|
||||
@Prop({ required: true }) showGiveTotals!: boolean;
|
||||
@Prop({ required: true }) showGiveConfirmed!: boolean;
|
||||
@Prop({ required: true }) givenToMeDescriptions!: Record<string, string>;
|
||||
@Prop({ required: true }) givenToMeConfirmed!: Record<string, number>;
|
||||
@Prop({ required: true }) givenToMeUnconfirmed!: Record<string, number>;
|
||||
@Prop({ required: true }) givenByMeDescriptions!: Record<string, string>;
|
||||
@Prop({ required: true }) givenByMeConfirmed!: Record<string, number>;
|
||||
@Prop({ required: true }) givenByMeUnconfirmed!: Record<string, number>;
|
||||
|
||||
// Constants
|
||||
AppString = AppString;
|
||||
|
||||
/**
|
||||
* Format contact name with non-breaking spaces
|
||||
*/
|
||||
private contactNameNonBreakingSpace(contactName?: string): string {
|
||||
return (contactName || AppString.NO_CONTACT_NAME).replace(/\s/g, "\u00A0");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get give amount for a specific contact and direction
|
||||
*/
|
||||
private getGiveAmountForContact(contactDid: string, isGivenToMe: boolean): number {
|
||||
if (this.showGiveTotals) {
|
||||
if (isGivenToMe) {
|
||||
return (this.givenToMeConfirmed[contactDid] || 0) +
|
||||
(this.givenToMeUnconfirmed[contactDid] || 0);
|
||||
} else {
|
||||
return (this.givenByMeConfirmed[contactDid] || 0) +
|
||||
(this.givenByMeUnconfirmed[contactDid] || 0);
|
||||
}
|
||||
} else if (this.showGiveConfirmed) {
|
||||
return isGivenToMe
|
||||
? (this.givenToMeConfirmed[contactDid] || 0)
|
||||
: (this.givenByMeConfirmed[contactDid] || 0);
|
||||
} else {
|
||||
return isGivenToMe
|
||||
? (this.givenToMeUnconfirmed[contactDid] || 0)
|
||||
: (this.givenByMeUnconfirmed[contactDid] || 0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get give description for a specific contact and direction
|
||||
*/
|
||||
private getGiveDescriptionForContact(contactDid: string, isGivenToMe: boolean): string {
|
||||
return isGivenToMe
|
||||
? (this.givenToMeDescriptions[contactDid] || '')
|
||||
: (this.givenByMeDescriptions[contactDid] || '');
|
||||
}
|
||||
}
|
||||
</script>
|
||||
Reference in New Issue
Block a user