Browse Source

Refactor: improve dialog logic and entity handling

- Split openDialog into separate methods to improve code readability and maintainability through method extraction
- Add receiver name fallback in GiftedDialog when receiver exists but has no name
- Enhance shouldShowYouEntity to prevent selecting "You" as both giver and recipient
- Improve labeling of "(No name)" entities while retaining original entity object properties
- Apply special styling to "Unnamed" and "(No Name)" entities
pull/155/head
Jose Olarte III 5 days ago
parent
commit
ec1a725832
  1. 36
      src/components/EntitySummaryButton.vue
  2. 13
      src/components/GiftedDialog.vue
  3. 22
      src/components/PersonCard.vue
  4. 194
      src/views/ContactGiftingView.vue

36
src/components/EntitySummaryButton.vue

@ -42,8 +42,8 @@ computed CSS properties * * @author Matthew Raymer */
<p class="text-xs text-slate-500 leading-1 -mb-1 uppercase"> <p class="text-xs text-slate-500 leading-1 -mb-1 uppercase">
{{ label }} {{ label }}
</p> </p>
<h3 class="font-semibold truncate"> <h3 :class="nameClasses">
{{ entity?.name || "Unnamed" }} {{ displayName }}
</h3> </h3>
</div> </div>
@ -138,6 +138,38 @@ export default class EntitySummaryButton extends Vue {
return this.editable ? "text-blue-500" : "text-slate-400"; return this.editable ? "text-blue-500" : "text-slate-400";
} }
/**
* Computed CSS classes for the entity name
*/
get nameClasses(): string {
const baseClasses = "font-semibold truncate";
// Add italic styling for special "Unnamed" or entities without set names
if (!this.entity?.name || this.entity?.did === "") {
return `${baseClasses} italic text-slate-500`;
}
return baseClasses;
}
/**
* Computed display name for the entity
*/
get displayName(): string {
// If the entity has a set name, use that name
if (this.entity?.name) {
return this.entity.name;
}
// If the entity is the special "Unnamed", use "Unnamed"
if (this.entity?.did === "") {
return "Unnamed";
}
// If the entity does not have a set name, but is not the special "Unnamed", use their DID
return this.entity?.did;
}
/** /**
* Handle click event - only call function prop if editable * Handle click event - only call function prop if editable
* Allows parent to control edit behavior and validation * Allows parent to control edit behavior and validation

13
src/components/GiftedDialog.vue

@ -226,14 +226,7 @@ export default class GiftedDialog extends Vue {
this.allMyDids = await retrieveAccountDids(); this.allMyDids = await retrieveAccountDids();
if (this.giver && !this.giver.name) {
this.giver.name = didInfo(
this.giver.did,
this.activeDid,
this.allMyDids,
this.allContacts,
);
}
if ( if (
this.giverEntityType === "project" || this.giverEntityType === "project" ||
@ -457,7 +450,7 @@ export default class GiftedDialog extends Vue {
if (contact) { if (contact) {
this.giver = { this.giver = {
did: contact.did, did: contact.did,
name: contact.name || contact.did, name: contact.name,
}; };
} else { } else {
// Only set to "Unnamed" if no giver is currently set // Only set to "Unnamed" if no giver is currently set
@ -519,7 +512,7 @@ export default class GiftedDialog extends Vue {
if (contact) { if (contact) {
this.receiver = { this.receiver = {
did: contact.did, did: contact.did,
name: contact.name || contact.did, name: contact.name,
}; };
} else { } else {
// Only set to "Unnamed" if no receiver is currently set // Only set to "Unnamed" if no receiver is currently set

22
src/components/PersonCard.vue

@ -25,7 +25,7 @@ conflict detection. * * @author Matthew Raymer */
</div> </div>
<h3 :class="nameClasses"> <h3 :class="nameClasses">
{{ person.name || person.did || "Unnamed" }} {{ displayName }}
</h3> </h3>
</li> </li>
</template> </template>
@ -98,9 +98,27 @@ export default class PersonCard extends Vue {
return `${baseClasses} text-slate-400`; return `${baseClasses} text-slate-400`;
} }
// Add italic styling for entities without set names
if (!this.person.name) {
return `${baseClasses} italic text-slate-500`;
}
return baseClasses; return baseClasses;
} }
/**
* Computed display name for the person
*/
get displayName(): string {
// If the entity has a set name, use that name
if (this.person.name) {
return this.person.name;
}
// If the entity does not have a set name
return this.person.did;
}
/** /**
* Handle card click - emit if selectable and not conflicted, show warning if conflicted * Handle card click - emit if selectable and not conflicted, show warning if conflicted
*/ */
@ -114,7 +132,7 @@ export default class PersonCard extends Vue {
group: "alert", group: "alert",
type: "warning", type: "warning",
title: "Cannot Select", title: "Cannot Select",
text: `You cannot select "${this.person.name || this.person.did || "Unnamed"}" because they are already selected as the ${this.conflictContext}.`, text: `You cannot select "${this.displayName}" because they are already selected as the ${this.conflictContext}.`,
}, },
3000, 3000,
); );

194
src/views/ContactGiftingView.vue

@ -21,8 +21,8 @@
<li v-if="shouldShowYouEntity" class="border-b border-slate-300 py-3"> <li v-if="shouldShowYouEntity" class="border-b border-slate-300 py-3">
<h2 class="text-base flex gap-4 items-center"> <h2 class="text-base flex gap-4 items-center">
<span class="grow flex gap-2 items-center font-medium"> <span class="grow flex gap-2 items-center font-medium">
<font-awesome icon="hand" class="text-blue-500 text-4xl" /> <font-awesome icon="hand" class="text-blue-500 text-4xl shrink-0" />
<span class="text-blue-500">You</span> <span class="text-ellipsis overflow-hidden text-blue-500">You</span>
</span> </span>
<span class="text-right"> <span class="text-right">
<button <button
@ -40,9 +40,9 @@
<span class="grow flex gap-2 items-center font-medium"> <span class="grow flex gap-2 items-center font-medium">
<font-awesome <font-awesome
icon="circle-question" icon="circle-question"
class="text-slate-400 text-4xl" class="text-slate-400 text-4xl shrink-0"
/> />
<span class="italic text-slate-400">(Unnamed/Unknown)</span> <span class="text-ellipsis overflow-hidden italic text-slate-500">(Unnamed/Unknown)</span>
</span> </span>
<span class="text-right"> <span class="text-right">
<button <button
@ -61,14 +61,14 @@
class="border-b border-slate-300 py-3" class="border-b border-slate-300 py-3"
> >
<h2 class="text-base flex gap-4 items-center"> <h2 class="text-base flex gap-4 items-center">
<span class="grow flex gap-2 items-center font-medium"> <span class="grow flex gap-2 items-center font-medium overflow-hidden">
<EntityIcon <EntityIcon
:contact="contact" :contact="contact"
:icon-size="34" :icon-size="34"
class="inline-block align-middle border border-slate-300 rounded-full overflow-hidden" class="inline-block align-middle border border-slate-300 rounded-full overflow-hidden shrink-0"
/> />
<span v-if="contact.name">{{ contact.name }}</span> <span v-if="contact.name" class="text-ellipsis overflow-hidden">{{ contact.name }}</span>
<span v-else class="italic text-slate-400">(No name)</span> <span v-else class="text-ellipsis overflow-hidden italic text-slate-500">{{ contact.did }}</span>
</span> </span>
<span class="text-right"> <span class="text-right">
<button <button
@ -208,59 +208,13 @@ export default class ContactGiftingView extends Vue {
} }
openDialog(contact?: GiverReceiverInputInfo | "Unnamed" | "You") { openDialog(contact?: GiverReceiverInputInfo | "Unnamed" | "You") {
if (contact === "Unnamed") { // Determine the selected entity based on contact type
// Special case: Handle "Unnamed" contacts for both givers and recipients const selectedEntity = this.createEntityFromContact(contact);
let recipient: GiverReceiverInputInfo;
let giver: GiverReceiverInputInfo | undefined;
if (this.stepType === "giver") { // Create giver and recipient based on step type and selected entity
// We're selecting a giver, so preserve the existing recipient from context const { giver, recipient } = this.createGiverAndRecipient(selectedEntity);
if (this.recipientEntityType === "project") {
recipient = {
did: this.recipientProjectHandleId,
name: this.recipientProjectName,
image: this.recipientProjectImage,
handleId: this.recipientProjectHandleId,
};
} else {
// Preserve the existing recipient from context
if (this.recipientDid === this.activeDid) {
// Recipient was "You"
recipient = { did: this.activeDid, name: "You" };
} else if (this.recipientDid) {
// Recipient was a regular contact
recipient = {
did: this.recipientDid,
name: this.recipientProjectName || "Someone",
};
} else {
// Fallback to "You" if no recipient was previously selected
recipient = { did: this.activeDid, name: "You" };
}
}
giver = undefined; // Will be set to "Unnamed" in GiftedDialog
} else {
// We're selecting a recipient, so recipient is "Unnamed" and giver is preserved from context
recipient = { did: "", name: "Unnamed" };
// Preserve the existing giver from the context
if (this.giverEntityType === "project") {
giver = {
did: this.giverProjectHandleId,
name: this.giverProjectName,
image: this.giverProjectImage,
handleId: this.giverProjectHandleId,
};
} else if (this.giverDid) {
giver = {
did: this.giverDid,
name: this.giverProjectName || "Someone",
};
} else {
giver = { did: this.activeDid, name: "You" };
}
}
// Open the dialog
(this.$refs.giftedDialog as GiftedDialog).open( (this.$refs.giftedDialog as GiftedDialog).open(
giver, giver,
recipient, recipient,
@ -273,89 +227,117 @@ export default class ContactGiftingView extends Vue {
// Move to Step 2 - entities are already set by the open() call // Move to Step 2 - entities are already set by the open() call
(this.$refs.giftedDialog as GiftedDialog).moveToStep2(); (this.$refs.giftedDialog as GiftedDialog).moveToStep2();
} else { }
// Regular case: contact is a GiverReceiverInputInfo
let giver: GiverReceiverInputInfo;
let recipient: GiverReceiverInputInfo;
/**
* Creates an entity object from the contact parameter
*/
private createEntityFromContact(
contact?: GiverReceiverInputInfo | "Unnamed" | "You",
): GiverReceiverInputInfo | undefined {
if (contact === "You") {
return { did: this.activeDid, name: "You" };
} else if (contact === "Unnamed") {
return { did: "", name: "Unnamed" };
} else if (contact) {
// Create a copy of the contact to avoid modifying the original
return { ...contact };
}
return undefined;
}
/**
* Creates giver and recipient objects based on step type and selected entity
*/
private createGiverAndRecipient(selectedEntity?: GiverReceiverInputInfo): {
giver: GiverReceiverInputInfo | undefined;
recipient: GiverReceiverInputInfo;
} {
if (this.stepType === "giver") { if (this.stepType === "giver") {
// We're selecting a giver, so the contact becomes the giver // We're selecting a giver, so the selected entity becomes the giver
giver = contact as GiverReceiverInputInfo; // Safe because we know contact is not "Unnamed" or undefined const giver = selectedEntity;
const recipient = this.createRecipientFromContext();
return { giver, recipient };
} else {
// We're selecting a recipient, so the selected entity becomes the recipient
const recipient = selectedEntity || { did: "", name: "Unnamed" };
const giver = this.createGiverFromContext();
return { giver, recipient };
}
}
// Preserve the existing recipient from the context /**
* Creates recipient object from context (preserves existing recipient)
*/
private createRecipientFromContext(): GiverReceiverInputInfo {
if (this.recipientEntityType === "project") { if (this.recipientEntityType === "project") {
recipient = { return {
did: this.recipientProjectHandleId, did: this.recipientProjectHandleId,
name: this.recipientProjectName, name: this.recipientProjectName,
image: this.recipientProjectImage, image: this.recipientProjectImage,
handleId: this.recipientProjectHandleId, handleId: this.recipientProjectHandleId,
}; };
} else { } else {
// Check if the preserved recipient was "You" or a regular contact
if (this.recipientDid === this.activeDid) { if (this.recipientDid === this.activeDid) {
// Recipient was "You" return { did: this.activeDid, name: "You" };
recipient = { did: this.activeDid, name: "You" };
} else if (this.recipientDid) { } else if (this.recipientDid) {
// Recipient was a regular contact return {
recipient = {
did: this.recipientDid, did: this.recipientDid,
name: this.recipientProjectName || "Someone", name: this.recipientProjectName,
}; };
} else { } else {
// Fallback to "Unnamed" return { did: "", name: "Unnamed" };
recipient = { did: "", name: "Unnamed" }; }
} }
} }
} else {
// We're selecting a recipient, so the contact becomes the recipient
recipient = contact as GiverReceiverInputInfo; // Safe because we know contact is not "Unnamed" or undefined
// Preserve the existing giver from the context /**
* Creates giver object from context (preserves existing giver)
*/
private createGiverFromContext(): GiverReceiverInputInfo {
if (this.giverEntityType === "project") { if (this.giverEntityType === "project") {
giver = { return {
did: this.giverProjectHandleId, did: this.giverProjectHandleId,
name: this.giverProjectName, name: this.giverProjectName,
image: this.giverProjectImage, image: this.giverProjectImage,
handleId: this.giverProjectHandleId, handleId: this.giverProjectHandleId,
}; };
} else { } else {
// Check if the preserved giver was "You" or a regular contact
if (this.giverDid === this.activeDid) { if (this.giverDid === this.activeDid) {
// Giver was "You" return { did: this.activeDid, name: "You" };
giver = { did: this.activeDid, name: "You" };
} else if (this.giverDid) { } else if (this.giverDid) {
// Giver was a regular contact return {
giver = {
did: this.giverDid, did: this.giverDid,
name: this.giverProjectName || "Someone", name: this.giverProjectName,
}; };
} else { } else {
// Fallback to "Unnamed" return { did: "", name: "Unnamed" };
giver = { did: "", name: "Unnamed" };
} }
} }
} }
(this.$refs.giftedDialog as GiftedDialog).open( get shouldShowYouEntity(): boolean {
giver, if (this.stepType === "giver") {
recipient, // When selecting a giver, show "You" if the current recipient is not "You"
this.offerId, // This prevents selecting yourself as both giver and recipient
this.prompt, if (this.recipientEntityType === "project") {
this.description, // If recipient is a project, we can select "You" as giver
this.amountInput, return true;
this.unitCode, } else {
); // If recipient is a person, check if it's not "You"
return this.recipientDid !== this.activeDid;
// Move to Step 2 - entities are already set by the open() call }
(this.$refs.giftedDialog as GiftedDialog).moveToStep2(); } else {
// When selecting a recipient, show "You" if the current giver is not "You"
// This prevents selecting yourself as both giver and recipient
if (this.giverEntityType === "project") {
// If giver is a project, we can select "You" as recipient
return true;
} else {
// If giver is a person, check if it's not "You"
return this.giverDid !== this.activeDid;
} }
} }
get shouldShowYouEntity(): boolean {
return (
this.stepType === "recipient" ||
(this.stepType === "giver" && this.isFromProjectView)
);
} }
} }
</script> </script>

Loading…
Cancel
Save