feat: remove the 'lock' from the giving & receiving sides

This commit is contained in:
2025-12-20 18:58:18 -07:00
parent ffeac44b39
commit b864f1632d
5 changed files with 24 additions and 130 deletions

View File

@@ -1,16 +1,6 @@
/** * EntitySummaryButton.vue - Displays selected entity with edit capability *
* Extracted from GiftedDialog.vue to handle entity summary display in the gift *
details step with edit functionality. * * Features: * - Shows entity avatar
(person or project) * - Displays entity name and role label * - Handles editable
vs locked states * - Function props for parent control over edit behavior * -
Supports both person and project entity types * - Template streamlined with
computed CSS properties * * @author Matthew Raymer */
/* EntitySummaryButton.vue - Displays selected entity with edit capability */
<template>
<component
:is="editable ? 'button' : 'div'"
:class="containerClasses"
@click="handleClick"
>
<button :class="containerClasses" @click="handleClick">
<!-- Entity Icon/Avatar -->
<div>
<template v-if="entityType === 'project'">
@@ -47,14 +37,11 @@ computed CSS properties * * @author Matthew Raymer */
</h3>
</div>
<!-- Edit/Lock Icon -->
<p class="ms-auto text-sm pe-1" :class="iconClasses">
<font-awesome
:icon="editable ? 'pen' : 'lock'"
:title="editable ? 'Change' : 'Can\'t be changed'"
/>
<!-- Edit Icon -->
<p class="ms-auto text-sm pe-1 text-blue-500">
<font-awesome icon="pen" title="Change" />
</p>
</component>
</button>
</template>
<script lang="ts">
@@ -75,12 +62,12 @@ interface EntityData {
}
/**
* EntitySummaryButton - Displays selected entity with optional edit capability
* EntitySummaryButton - Displays selected entity with edit capability
*
* Features:
* - Shows entity avatar (person or project)
* - Displays entity name and role label
* - Handles editable vs locked states
* - Always editable - click to change entity
* - Function props for parent control over edit behavior
* - Supports both person and project entity types
* - Template streamlined with computed CSS properties
@@ -104,13 +91,9 @@ export default class EntitySummaryButton extends Vue {
@Prop({ required: true })
label!: string;
/** Whether the entity can be edited */
@Prop({ default: true })
editable!: boolean;
/**
* Function prop for handling edit requests
* Called when the button is clicked and editable, allowing parent to control edit behavior
* Called when the button is clicked, allowing parent to control edit behavior
*/
@Prop({ type: Function, default: () => {} })
onEditRequested!: (data: {
@@ -132,13 +115,6 @@ export default class EntitySummaryButton extends Vue {
return this.entity !== null && "profileImageUrl" in this.entity;
}
/**
* Computed CSS classes for the edit/lock icon
*/
get iconClasses(): string {
return this.editable ? "text-blue-500" : "text-slate-400";
}
/**
* Computed CSS classes for the entity name
*/
@@ -172,16 +148,13 @@ export default class EntitySummaryButton extends Vue {
}
/**
* Handle click event - only call function prop if editable
* Allows parent to control edit behavior and validation
* Handle click event - call function prop to allow parent to control edit behavior
*/
handleClick(): void {
if (this.editable) {
this.onEditRequested({
entityType: this.entityType,
entity: this.entity,
});
}
this.onEditRequested({
entityType: this.entityType,
entity: this.entity,
});
}
}
</script>
@@ -195,8 +168,4 @@ button {
button:hover {
background-color: #f1f5f9; /* hover:bg-slate-100 */
}
div {
cursor: default;
}
</style>

View File

@@ -16,7 +16,6 @@ control over updates and validation * * @author Matthew Raymer */
:entity="giver"
:entity-type="giverEntityType"
:label="giverLabel"
:editable="canEditGiver"
:on-edit-requested="handleEditGiver"
/>
@@ -25,7 +24,6 @@ control over updates and validation * * @author Matthew Raymer */
:entity="receiver"
:entity-type="recipientEntityType"
:label="recipientLabel"
:editable="canEditRecipient"
:on-edit-requested="handleEditRecipient"
/>
</div>
@@ -188,14 +186,6 @@ export default class GiftDetailsStep extends Vue {
@Prop({ default: "" })
toProjectId!: string;
/** Whether the giver is locked and cannot be edited */
@Prop({ default: false })
isGiverLocked!: boolean;
/** Whether the recipient is locked and cannot be edited */
@Prop({ default: false })
isRecipientLocked!: boolean;
/**
* Function prop for handling description updates
* Called when the description input changes, allowing parent to control validation
@@ -281,21 +271,6 @@ export default class GiftDetailsStep extends Vue {
: "Given to:";
}
/**
* Whether the giver can be edited
*/
get canEditGiver(): boolean {
// If giver is locked via prop, it cannot be edited
return !this.isGiverLocked;
}
/**
* Whether the recipient can be edited
*/
get canEditRecipient(): boolean {
return !this.isRecipientLocked;
}
/**
* Computed CSS classes for submit button
*/

View File

@@ -48,8 +48,6 @@
:offer-id="offerId"
:from-project-id="fromProjectId"
:to-project-id="toProjectId"
:is-giver-locked="isGiverLocked"
:is-recipient-locked="isRecipientLocked"
:on-update-description="(desc: string) => (description = desc)"
:on-update-amount="handleAmountUpdate"
:on-update-unit-code="(code: string) => (unitCode = code)"
@@ -140,23 +138,11 @@ export default class GiftedDialog extends Vue {
stepType = "giver";
unitCode = "HUR";
visible = false;
isGiverLocked = false;
isRecipientLocked = false;
libsUtil = libsUtil;
didInfo = didInfo;
// Computed property to help debug template logic
get shouldShowProjects() {
const result =
(this.stepType === "giver" &&
this.currentGiverEntityType === "project") ||
(this.stepType === "recipient" &&
this.currentRecipientEntityType === "project");
return result;
}
// Computed property to check if current selection would create a conflict
get hasPersonConflict() {
// Only check for conflicts when both entities are persons
@@ -265,40 +251,13 @@ export default class GiftedDialog extends Vue {
const activeIdentity = await (this as any).$getActiveIdentity();
this.activeDid = activeIdentity.activeDid || "";
// Determine if entities should be locked
// An entity is locked if it's provided as an input property (has did or handleId)
// For persons: locked if did is provided and not "You" (activeDid)
// For projects: locked if handleId is provided
// When entities come from ContactsView, ContactGiftingView, or ProjectViewView context,
// they should be locked if they have a valid identifier (did or handleId)
const isGiverProvided =
giver &&
((giver.did && giver.did !== this.activeDid) ||
(giver.handleId && giver.handleId !== ""));
const isReceiverProvided =
receiver &&
((receiver.did && receiver.did !== this.activeDid) ||
(receiver.handleId && receiver.handleId !== ""));
// Lock entities that are provided (from context or explicitly set)
// This ensures that when entities are chosen from ContactsView, ContactGiftingView,
// or ProjectViewView, the other entity (giver or recipient) that was already set
// from context is locked
this.isGiverLocked = !!isGiverProvided;
this.isRecipientLocked = !!isReceiverProvided;
// Determine if receiver should be locked (for step navigation logic)
// Receiver is locked only if it's provided AND it's not "You" (activeDid)
// "You" is treated as a default that can be changed
const isReceiverLocked =
receiver && receiver.did && receiver.did !== this.activeDid;
// Only skip Step 1 if both giver and receiver are provided AND receiver is locked
// If receiver is "You" (default), still show Step 1 so user can change it
this.firstStep = !(giver && isReceiverLocked);
// If giver is provided but receiver is not locked, start with recipient selection
// Otherwise, start with giver selection
this.stepType = giver && !isReceiverLocked ? "recipient" : "giver";
// Skip Step 1 if both giver and receiver are provided
const hasGiver = giver && (!!giver.did || !!giver.handleId);
const hasReceiver = receiver && (!!receiver.did || !!receiver.handleId);
this.firstStep = !hasGiver || !hasReceiver;
if (this.firstStep) {
this.stepType = giver ? "receiver" : "giver";
}
logger.debug("[GiftedDialog] Settings received:", {
activeDid: this.activeDid,
@@ -357,9 +316,6 @@ export default class GiftedDialog extends Vue {
this.firstStep = true;
// Reset to initial prop values
this.currentGiverEntityType = this.initialGiverEntityType;
// Reset lock states
this.isGiverLocked = false;
this.isRecipientLocked = false;
}
async confirm() {
@@ -692,13 +648,7 @@ export default class GiftedDialog extends Vue {
entityType: string;
currentEntity: { did: string; name: string };
}) {
// Prevent editing if the entity is locked
if (data.entityType === "giver" && this.isGiverLocked) {
return;
}
if (data.entityType === "recipient" && this.isRecipientLocked) {
return;
}
// Always allow editing - go back to Step 1 to select a new entity
this.goBackToStep1(data.entityType);
}

View File

@@ -1088,7 +1088,7 @@ export default class ContactsView extends Vue {
{
group: "modal",
type: "confirm",
title: "Delete",
title: "Confirm First?",
text: message,
onNo: async () => {
this.showGiftedDialog(giverDid, recipientDid);

View File

@@ -331,7 +331,7 @@ export default class OfferDetailsView extends Vue {
get recipientAssignmentLabel() {
return this.recipientDid
? `This is offered to ${this.recipientName}`
: "No recipient was chosen.";
: "No named individual recipient was chosen.";
}
/**