diff --git a/src/components/EntityGrid.vue b/src/components/EntityGrid.vue
index ff995652..2fcf7acb 100644
--- a/src/components/EntityGrid.vue
+++ b/src/components/EntityGrid.vue
@@ -159,6 +159,10 @@ export default class EntityGrid extends Vue {
@Prop({ default: "other party" })
conflictContext!: string;
+ /** Whether to hide the "Show All" navigation */
+ @Prop({ default: false })
+ hideShowAll!: boolean;
+
/**
* Function to determine which entities to display (allows parent control)
*
@@ -245,7 +249,9 @@ export default class EntityGrid extends Vue {
* Whether to show the "Show All" navigation
*/
get shouldShowAll(): boolean {
- return this.entities.length > 0 && this.showAllRoute !== "";
+ return (
+ !this.hideShowAll && this.entities.length > 0 && this.showAllRoute !== ""
+ );
}
/**
@@ -304,16 +310,13 @@ export default class EntityGrid extends Vue {
/**
* Handle special entity selection from SpecialEntityCard
+ * Treat "You" and "Unnamed" as person entities
*/
- handleEntitySelected(event: {
- type: string;
- entityType: string;
- data: { did?: string; name: string };
- }): void {
+ handleEntitySelected(event: { data: { did?: string; name: string } }): void {
+ // Convert special entities to person entities since they represent people
this.emitEntitySelected({
- type: "special",
- entityType: event.entityType,
- data: event.data,
+ type: "person",
+ data: event.data as Contact,
});
}
@@ -321,13 +324,11 @@ export default class EntityGrid extends Vue {
@Emit("entity-selected")
emitEntitySelected(data: {
- type: "person" | "project" | "special";
- entityType?: string;
- data: Contact | PlanData | { did?: string; name: string };
+ type: "person" | "project";
+ data: Contact | PlanData;
}): {
- type: "person" | "project" | "special";
- entityType?: string;
- data: Contact | PlanData | { did?: string; name: string };
+ type: "person" | "project";
+ data: Contact | PlanData;
} {
return data;
}
diff --git a/src/components/EntitySelectionStep.vue b/src/components/EntitySelectionStep.vue
index 56426462..2fb6bcac 100644
--- a/src/components/EntitySelectionStep.vue
+++ b/src/components/EntitySelectionStep.vue
@@ -27,6 +27,7 @@ Matthew Raymer */
:show-all-query-params="showAllQueryParams"
:notify="notify"
:conflict-context="conflictContext"
+ :hide-show-all="hideShowAll"
@entity-selected="handleEntitySelected"
/>
@@ -55,9 +56,8 @@ interface EntityData {
* Entity selection event data structure
*/
interface EntitySelectionEvent {
- type: "person" | "project" | "special";
- entityType?: string;
- data: Contact | PlanData | EntityData;
+ type: "person" | "project";
+ data: Contact | PlanData;
}
/**
@@ -154,6 +154,10 @@ export default class EntitySelectionStep extends Vue {
@Prop()
notify?: (notification: NotificationIface, timeout?: number) => void;
+ /** Whether to hide the "Show All" navigation */
+ @Prop({ default: false })
+ hideShowAll!: boolean;
+
/**
* CSS classes for the cancel button
*/
diff --git a/src/components/EntitySummaryButton.vue b/src/components/EntitySummaryButton.vue
index 50f25078..96dae340 100644
--- a/src/components/EntitySummaryButton.vue
+++ b/src/components/EntitySummaryButton.vue
@@ -42,8 +42,8 @@ computed CSS properties * * @author Matthew Raymer */
{{ label }}
-
- {{ entity?.name || "Unnamed" }}
+
+ {{ displayName }}
@@ -138,6 +138,38 @@ export default class EntitySummaryButton extends Vue {
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
* Allows parent to control edit behavior and validation
diff --git a/src/components/GiftedDialog.vue b/src/components/GiftedDialog.vue
index 83a8b93d..ec78ddf4 100644
--- a/src/components/GiftedDialog.vue
+++ b/src/components/GiftedDialog.vue
@@ -29,6 +29,7 @@
:unit-code="unitCode"
:offer-id="offerId"
:notify="$notify"
+ :hide-show-all="hideShowAll"
@entity-selected="handleEntitySelected"
@cancel="cancel"
/>
@@ -114,6 +115,7 @@ export default class GiftedDialog extends Vue {
@Prop() fromProjectId = "";
@Prop() toProjectId = "";
@Prop() isFromProjectView = false;
+ @Prop() hideShowAll = false;
@Prop({ default: "person" }) giverEntityType = "person" as
| "person"
| "project";
@@ -224,14 +226,7 @@ export default class GiftedDialog extends Vue {
this.allMyDids = await retrieveAccountDids();
- if (this.giver && !this.giver.name) {
- this.giver.name = didInfo(
- this.giver.did,
- this.activeDid,
- this.allMyDids,
- this.allContacts,
- );
- }
+
if (
this.giverEntityType === "project" ||
@@ -455,7 +450,7 @@ export default class GiftedDialog extends Vue {
if (contact) {
this.giver = {
did: contact.did,
- name: contact.name || contact.did,
+ name: contact.name,
};
} else {
// Only set to "Unnamed" if no giver is currently set
@@ -517,7 +512,7 @@ export default class GiftedDialog extends Vue {
if (contact) {
this.receiver = {
did: contact.did,
- name: contact.name || contact.did,
+ name: contact.name,
};
} else {
// Only set to "Unnamed" if no receiver is currently set
@@ -566,20 +561,21 @@ export default class GiftedDialog extends Vue {
/**
* Handle entity selection from EntitySelectionStep
- * @param entity - The selected entity (person, project, or special) with stepType
+ * @param entity - The selected entity (person or project) with stepType
*/
handleEntitySelected(entity: {
- type: "person" | "project" | "special";
- entityType?: string;
- data: Contact | PlanData | { did?: string; name: string };
+ type: "person" | "project";
+ data: Contact | PlanData;
stepType: string;
}) {
if (entity.type === "person") {
const contact = entity.data as Contact;
+ // Apply DID-based logic for person entities
+ const processedContact = this.processPersonEntity(contact);
if (entity.stepType === "giver") {
- this.selectGiver(contact);
+ this.selectGiver(processedContact);
} else {
- this.selectRecipient(contact);
+ this.selectRecipient(processedContact);
}
} else if (entity.type === "project") {
const project = entity.data as PlanData;
@@ -588,33 +584,22 @@ export default class GiftedDialog extends Vue {
} else {
this.selectRecipientProject(project);
}
- } else if (entity.type === "special") {
- // Handle special entities like "You" and "Unnamed"
- if (entity.entityType === "you") {
- // "You" entity selected
- const youEntity = {
- did: this.activeDid,
- name: "You",
- };
- if (entity.stepType === "giver") {
- this.giver = youEntity;
- } else {
- this.receiver = youEntity;
- }
- this.firstStep = false;
- } else if (entity.entityType === "unnamed") {
- // "Unnamed" entity selected
- const unnamedEntity = {
- did: "",
- name: "Unnamed",
- };
- if (entity.stepType === "giver") {
- this.giver = unnamedEntity;
- } else {
- this.receiver = unnamedEntity;
- }
- this.firstStep = false;
- }
+ }
+ }
+
+ /**
+ * Processes person entities using DID-based logic for "You" and "Unnamed"
+ */
+ private processPersonEntity(contact: Contact): Contact {
+ if (contact.did === this.activeDid) {
+ // If DID matches active DID, create "You" entity
+ return { ...contact, name: "You" };
+ } else if (!contact.did || contact.did === "") {
+ // If DID is empty/null, create "Unnamed" entity
+ return { ...contact, name: "Unnamed" };
+ } else {
+ // Return the contact as-is
+ return contact;
}
}
diff --git a/src/components/PersonCard.vue b/src/components/PersonCard.vue
index 1f3bf595..2c6f439a 100644
--- a/src/components/PersonCard.vue
+++ b/src/components/PersonCard.vue
@@ -25,7 +25,7 @@ conflict detection. * * @author Matthew Raymer */
- {{ person.name || person.did || "Unnamed" }}
+ {{ displayName }}
@@ -98,9 +98,27 @@ export default class PersonCard extends Vue {
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;
}
+ /**
+ * 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
*/
@@ -114,7 +132,7 @@ export default class PersonCard extends Vue {
group: "alert",
type: "warning",
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,
);
diff --git a/src/components/SpecialEntityCard.vue b/src/components/SpecialEntityCard.vue
index 1d475229..e489d003 100644
--- a/src/components/SpecialEntityCard.vue
+++ b/src/components/SpecialEntityCard.vue
@@ -124,8 +124,6 @@ export default class SpecialEntityCard extends Vue {
handleClick(): void {
if (this.selectable && !this.conflicted) {
this.emitEntitySelected({
- type: "special",
- entityType: this.entityType,
data: this.entityData,
});
} else if (this.conflicted && this.notify) {
@@ -145,13 +143,7 @@ export default class SpecialEntityCard extends Vue {
// Emit methods using @Emit decorator
@Emit("entity-selected")
- emitEntitySelected(data: {
- type: string;
- entityType: string;
- data: { did?: string; name: string };
- }): {
- type: string;
- entityType: string;
+ emitEntitySelected(data: { data: { did?: string; name: string } }): {
data: { did?: string; name: string };
} {
return data;
diff --git a/src/views/ContactGiftingView.vue b/src/views/ContactGiftingView.vue
index 91d10c9c..f27abc13 100644
--- a/src/views/ContactGiftingView.vue
+++ b/src/views/ContactGiftingView.vue
@@ -17,20 +17,38 @@
+
+ -
+
+
+
+ You
+
+
+
+
+
+
-
- (Unnamed/Unknown)
+ (Unnamed/Unknown)
@@ -43,14 +61,14 @@
class="border-b border-slate-300 py-3"
>
-
+
- {{ contact.name }}
- (No name)
+ {{ contact.name }}
+ {{ contact.did }}
@@ -188,147 +207,143 @@ export default class ContactGiftingView extends Vue {
}
}
- openDialog(contact?: GiverReceiverInputInfo | "Unnamed") {
- if (contact === "Unnamed") {
- // Special case: Handle "Unnamed" contacts for both givers and recipients
- let recipient: GiverReceiverInputInfo;
- let giver: GiverReceiverInputInfo | undefined;
+ openDialog(contact?: GiverReceiverInputInfo) {
+ // Determine the selected entity based on contact type
+ const selectedEntity = this.createEntityFromContact(contact);
- if (this.stepType === "giver") {
- // We're selecting a giver, so preserve the existing recipient from context
- 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" };
+ // Create giver and recipient based on step type and selected entity
+ const { giver, recipient } = this.createGiverAndRecipient(selectedEntity);
- // 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(
+ giver,
+ recipient,
+ this.offerId,
+ this.prompt,
+ this.description,
+ this.amountInput,
+ this.unitCode,
+ );
- (this.$refs.giftedDialog as GiftedDialog).open(
- giver,
- recipient,
- this.offerId,
- this.prompt,
- this.description,
- this.amountInput,
- this.unitCode,
- );
+ // Move to Step 2 - entities are already set by the open() call
+ (this.$refs.giftedDialog as GiftedDialog).moveToStep2();
+ }
+
+ /**
+ * Creates an entity object from the contact parameter
+ * Uses DID-based logic to determine "You" and "Unnamed" entities
+ */
+ private createEntityFromContact(
+ contact?: GiverReceiverInputInfo,
+ ): GiverReceiverInputInfo | undefined {
+ if (!contact) {
+ return undefined;
+ }
- // Move to Step 2 - entities are already set by the open() call
- (this.$refs.giftedDialog as GiftedDialog).moveToStep2();
+ // Handle GiverReceiverInputInfo object
+ if (contact.did === this.activeDid) {
+ // If DID matches active DID, create "You" entity
+ return { did: this.activeDid, name: "You" };
+ } else if (!contact.did || contact.did === "") {
+ // If DID is empty/null, create "Unnamed" entity
+ return { did: "", name: "Unnamed" };
} else {
- // Regular case: contact is a GiverReceiverInputInfo
- let giver: GiverReceiverInputInfo;
- let recipient: GiverReceiverInputInfo;
+ // Create a copy of the contact to avoid modifying the original
+ return { ...contact };
+ }
+ }
- if (this.stepType === "giver") {
- // We're selecting a giver, so the contact becomes the giver
- giver = contact as GiverReceiverInputInfo; // Safe because we know contact is not "Unnamed" or 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") {
+ // We're selecting a giver, so the selected entity becomes the giver
+ 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
- if (this.recipientEntityType === "project") {
- recipient = {
- did: this.recipientProjectHandleId,
- name: this.recipientProjectName,
- image: this.recipientProjectImage,
- handleId: this.recipientProjectHandleId,
- };
- } else {
- // Check if the preserved recipient was "You" or a regular contact
- 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 "Unnamed"
- recipient = { did: "", name: "Unnamed" };
- }
- }
+ /**
+ * Creates recipient object from context (preserves existing recipient)
+ */
+ private createRecipientFromContext(): GiverReceiverInputInfo {
+ if (this.recipientEntityType === "project") {
+ return {
+ did: this.recipientProjectHandleId,
+ name: this.recipientProjectName,
+ image: this.recipientProjectImage,
+ handleId: this.recipientProjectHandleId,
+ };
+ } else {
+ if (this.recipientDid === this.activeDid) {
+ return { did: this.activeDid, name: "You" };
+ } else if (this.recipientDid) {
+ return {
+ did: this.recipientDid,
+ name: this.recipientProjectName,
+ };
} 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
- if (this.giverEntityType === "project") {
- giver = {
- did: this.giverProjectHandleId,
- name: this.giverProjectName,
- image: this.giverProjectImage,
- handleId: this.giverProjectHandleId,
- };
- } else {
- // Check if the preserved giver was "You" or a regular contact
- if (this.giverDid === this.activeDid) {
- // Giver was "You"
- giver = { did: this.activeDid, name: "You" };
- } else if (this.giverDid) {
- // Giver was a regular contact
- giver = {
- did: this.giverDid,
- name: this.giverProjectName || "Someone",
- };
- } else {
- // Fallback to "Unnamed"
- giver = { did: "", name: "Unnamed" };
- }
- }
+ return { did: "", name: "Unnamed" };
}
+ }
+ }
- (this.$refs.giftedDialog as GiftedDialog).open(
- giver,
- recipient,
- this.offerId,
- this.prompt,
- this.description,
- this.amountInput,
- this.unitCode,
- );
+ /**
+ * Creates giver object from context (preserves existing giver)
+ */
+ private createGiverFromContext(): GiverReceiverInputInfo {
+ if (this.giverEntityType === "project") {
+ return {
+ did: this.giverProjectHandleId,
+ name: this.giverProjectName,
+ image: this.giverProjectImage,
+ handleId: this.giverProjectHandleId,
+ };
+ } else {
+ if (this.giverDid === this.activeDid) {
+ return { did: this.activeDid, name: "You" };
+ } else if (this.giverDid) {
+ return {
+ did: this.giverDid,
+ name: this.giverProjectName,
+ };
+ } else {
+ return { did: "", name: "Unnamed" };
+ }
+ }
+ }
- // Move to Step 2 - entities are already set by the open() call
- (this.$refs.giftedDialog as GiftedDialog).moveToStep2();
+ get shouldShowYouEntity(): boolean {
+ if (this.stepType === "giver") {
+ // When selecting a giver, show "You" if the current recipient is not "You"
+ // This prevents selecting yourself as both giver and recipient
+ if (this.recipientEntityType === "project") {
+ // If recipient is a project, we can select "You" as giver
+ return true;
+ } else {
+ // If recipient is a person, check if it's not "You"
+ return this.recipientDid !== this.activeDid;
+ }
+ } 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;
+ }
}
}
}
diff --git a/src/views/HomeView.vue b/src/views/HomeView.vue
index 4af9b5bc..7c4789f7 100644
--- a/src/views/HomeView.vue
+++ b/src/views/HomeView.vue
@@ -1475,30 +1475,41 @@ export default class HomeView extends Vue {
* @param giver Optional contact info for giver
* @param description Optional gift description
*/
- openDialog(giver?: GiverReceiverInputInfo | "Unnamed", prompt?: string) {
- if (giver === "Unnamed") {
- // Special case: Pass undefined to trigger Step 1, but with "Unnamed" pre-selected
- (this.$refs.giftedDialog as GiftedDialog).open(
- undefined,
- {
- did: this.activeDid,
- name: "You",
- } as GiverReceiverInputInfo,
- undefined,
- prompt,
- );
- // Immediately select "Unnamed" and move to Step 2
- (this.$refs.giftedDialog as GiftedDialog).selectGiver();
+ openDialog(giver?: GiverReceiverInputInfo, prompt?: string) {
+ // Determine the giver entity based on DID logic
+ const giverEntity = this.createGiverEntity(giver);
+
+ (this.$refs.giftedDialog as GiftedDialog).open(
+ giverEntity,
+ {
+ did: this.activeDid,
+ name: "You", // In HomeView, we always use "You" as the giver
+ } as GiverReceiverInputInfo,
+ undefined,
+ prompt,
+ );
+ }
+
+ /**
+ * Creates giver entity using DID-based logic
+ */
+ private createGiverEntity(
+ giver?: GiverReceiverInputInfo,
+ ): GiverReceiverInputInfo | undefined {
+ if (!giver) {
+ return undefined;
+ }
+
+ // Handle GiverReceiverInputInfo object
+ if (giver.did === this.activeDid) {
+ // If DID matches active DID, create "You" entity
+ return { did: this.activeDid, name: "You" };
+ } else if (!giver.did || giver.did === "") {
+ // If DID is empty/null, create "Unnamed" entity
+ return { did: "", name: "Unnamed" };
} else {
- (this.$refs.giftedDialog as GiftedDialog).open(
- giver,
- {
- did: this.activeDid,
- name: "You",
- } as GiverReceiverInputInfo,
- undefined,
- prompt,
- );
+ // Return the giver as-is
+ return giver;
}
}
@@ -1627,10 +1638,7 @@ export default class HomeView extends Vue {
}
}
- openPersonDialog(
- giver?: GiverReceiverInputInfo | "Unnamed",
- prompt?: string,
- ) {
+ openPersonDialog(giver?: GiverReceiverInputInfo, prompt?: string) {
this.showProjectsDialog = false;
this.openDialog(giver, prompt);
}