forked from jsnbuchanan/crowd-funder-for-time-pwa
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
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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,
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -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,154 +208,136 @@ 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
|
// Open the dialog
|
||||||
if (this.giverEntityType === "project") {
|
(this.$refs.giftedDialog as GiftedDialog).open(
|
||||||
giver = {
|
giver,
|
||||||
did: this.giverProjectHandleId,
|
recipient,
|
||||||
name: this.giverProjectName,
|
this.offerId,
|
||||||
image: this.giverProjectImage,
|
this.prompt,
|
||||||
handleId: this.giverProjectHandleId,
|
this.description,
|
||||||
};
|
this.amountInput,
|
||||||
} else if (this.giverDid) {
|
this.unitCode,
|
||||||
giver = {
|
);
|
||||||
did: this.giverDid,
|
|
||||||
name: this.giverProjectName || "Someone",
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
giver = { did: this.activeDid, name: "You" };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
(this.$refs.giftedDialog as GiftedDialog).open(
|
// Move to Step 2 - entities are already set by the open() call
|
||||||
giver,
|
(this.$refs.giftedDialog as GiftedDialog).moveToStep2();
|
||||||
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
|
||||||
|
*/
|
||||||
|
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") {
|
||||||
|
// We're selecting a giver, so the selected entity becomes the giver
|
||||||
|
const giver = selectedEntity;
|
||||||
|
const recipient = this.createRecipientFromContext();
|
||||||
|
return { giver, recipient };
|
||||||
} else {
|
} else {
|
||||||
// Regular case: contact is a GiverReceiverInputInfo
|
// We're selecting a recipient, so the selected entity becomes the recipient
|
||||||
let giver: GiverReceiverInputInfo;
|
const recipient = selectedEntity || { did: "", name: "Unnamed" };
|
||||||
let recipient: GiverReceiverInputInfo;
|
const giver = this.createGiverFromContext();
|
||||||
|
return { giver, recipient };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (this.stepType === "giver") {
|
/**
|
||||||
// We're selecting a giver, so the contact becomes the giver
|
* Creates recipient object from context (preserves existing recipient)
|
||||||
giver = contact as GiverReceiverInputInfo; // Safe because we know contact is not "Unnamed" or undefined
|
*/
|
||||||
|
private createRecipientFromContext(): GiverReceiverInputInfo {
|
||||||
// Preserve the existing recipient from the context
|
if (this.recipientEntityType === "project") {
|
||||||
if (this.recipientEntityType === "project") {
|
return {
|
||||||
recipient = {
|
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 {
|
if (this.recipientDid === this.activeDid) {
|
||||||
// Check if the preserved recipient was "You" or a regular contact
|
return { did: this.activeDid, name: "You" };
|
||||||
if (this.recipientDid === this.activeDid) {
|
} else if (this.recipientDid) {
|
||||||
// Recipient was "You"
|
return {
|
||||||
recipient = { did: this.activeDid, name: "You" };
|
did: this.recipientDid,
|
||||||
} else if (this.recipientDid) {
|
name: this.recipientProjectName,
|
||||||
// Recipient was a regular contact
|
};
|
||||||
recipient = {
|
|
||||||
did: this.recipientDid,
|
|
||||||
name: this.recipientProjectName || "Someone",
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
// Fallback to "Unnamed"
|
|
||||||
recipient = { did: "", name: "Unnamed" };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// We're selecting a recipient, so the contact becomes the recipient
|
return { did: "", name: "Unnamed" };
|
||||||
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" };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
(this.$refs.giftedDialog as GiftedDialog).open(
|
/**
|
||||||
giver,
|
* Creates giver object from context (preserves existing giver)
|
||||||
recipient,
|
*/
|
||||||
this.offerId,
|
private createGiverFromContext(): GiverReceiverInputInfo {
|
||||||
this.prompt,
|
if (this.giverEntityType === "project") {
|
||||||
this.description,
|
return {
|
||||||
this.amountInput,
|
did: this.giverProjectHandleId,
|
||||||
this.unitCode,
|
name: this.giverProjectName,
|
||||||
);
|
image: this.giverProjectImage,
|
||||||
|
handleId: this.giverProjectHandleId,
|
||||||
// Move to Step 2 - entities are already set by the open() call
|
};
|
||||||
(this.$refs.giftedDialog as GiftedDialog).moveToStep2();
|
} 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" };
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
get shouldShowYouEntity(): boolean {
|
get shouldShowYouEntity(): boolean {
|
||||||
return (
|
if (this.stepType === "giver") {
|
||||||
this.stepType === "recipient" ||
|
// When selecting a giver, show "You" if the current recipient is not "You"
|
||||||
(this.stepType === "giver" && this.isFromProjectView)
|
// 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
Reference in New Issue
Block a user