diff --git a/playwright.config-local.ts b/playwright.config-local.ts index e2d63465..d9c6afc4 100644 --- a/playwright.config-local.ts +++ b/playwright.config-local.ts @@ -21,7 +21,7 @@ export default defineConfig({ /* Retry on CI only */ retries: process.env.CI ? 2 : 0, /* Opt out of parallel tests on CI. */ - workers: 4, + workers: 3, /* Reporter to use. See https://playwright.dev/docs/test-reporters */ reporter: [ ['list'], diff --git a/src/components/EntitySelectionStep.vue b/src/components/EntitySelectionStep.vue index c6f0f197..c1729b78 100644 --- a/src/components/EntitySelectionStep.vue +++ b/src/components/EntitySelectionStep.vue @@ -165,15 +165,19 @@ export default class EntitySelectionStep extends Vue { */ get stepLabel(): string { if (this.stepType === "recipient") { - return "Choose who received the gift"; - } else if (this.stepType === "giver") { if (this.shouldShowProjects) { - return "Choose a project benefitted from"; + return "Choose recipient project"; } else { - return "Choose a person received from"; + return "Choose recipient person"; + } + } else { + // this.stepType === "giver" + if (this.shouldShowProjects) { + return "Choose giving project"; + } else { + return "Choose giving person"; } } - return "Choose entity"; } /** diff --git a/src/components/EntitySummaryButton.vue b/src/components/EntitySummaryButton.vue index 80890eff..68a2baf4 100644 --- a/src/components/EntitySummaryButton.vue +++ b/src/components/EntitySummaryButton.vue @@ -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 */ - + @@ -47,14 +37,11 @@ computed CSS properties * * @author Matthew Raymer */ - - - + + + - + @@ -195,8 +168,4 @@ button { button:hover { background-color: #f1f5f9; /* hover:bg-slate-100 */ } - -div { - cursor: default; -} diff --git a/src/components/GiftDetailsStep.vue b/src/components/GiftDetailsStep.vue index 7acbc42a..7b9c609f 100644 --- a/src/components/GiftDetailsStep.vue +++ b/src/components/GiftDetailsStep.vue @@ -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" /> @@ -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 */ diff --git a/src/components/GiftedDialog.vue b/src/components/GiftedDialog.vue index a383ca09..1bfa0b00 100644 --- a/src/components/GiftedDialog.vue +++ b/src/components/GiftedDialog.vue @@ -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); } diff --git a/src/views/ContactsView.vue b/src/views/ContactsView.vue index e9e46cd3..df9917b6 100644 --- a/src/views/ContactsView.vue +++ b/src/views/ContactsView.vue @@ -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); diff --git a/src/views/OfferDetailsView.vue b/src/views/OfferDetailsView.vue index 97d022f4..34d836cc 100644 --- a/src/views/OfferDetailsView.vue +++ b/src/views/OfferDetailsView.vue @@ -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."; } /** diff --git a/test-playwright/00-noid-tests.spec.ts b/test-playwright/00-noid-tests.spec.ts index 072baf9a..61b52eae 100644 --- a/test-playwright/00-noid-tests.spec.ts +++ b/test-playwright/00-noid-tests.spec.ts @@ -282,9 +282,9 @@ test('Check User 0 can register a random person', async ({ page }) => { } catch (error) { console.log('Could not force close dialog, continuing...'); } - // Wait for Person button to be ready - simplified approach - await page.waitForSelector('button:has-text("Person")', { timeout: 10000 }); - await page.getByRole('button', { name: 'Person' }).click(); + // Wait for Thank button to be ready - simplified approach + await page.waitForSelector('button:has-text("Thank")', { timeout: 10000 }); + await page.getByRole('button', { name: 'Thank' }).click(); await page.getByRole('listitem').filter({ hasText: UNNAMED_ENTITY_NAME }).locator('svg').click(); await page.getByPlaceholder('What was given').fill('Gave me access!'); await page.getByRole('button', { name: 'Sign & Send' }).click(); diff --git a/test-playwright/30-record-gift.spec.ts b/test-playwright/30-record-gift.spec.ts index 8b560e7a..90af649c 100644 --- a/test-playwright/30-record-gift.spec.ts +++ b/test-playwright/30-record-gift.spec.ts @@ -107,7 +107,7 @@ test('Record something given', async ({ page }) => { return !document.querySelector('.dialog-overlay'); }, { timeout: 5000 }); - await page.getByRole('button', { name: 'Person' }).click(); + await page.getByRole('button', { name: 'Thank' }).click(); await page.getByRole('listitem').filter({ hasText: UNNAMED_ENTITY_NAME }).locator('svg').click(); await page.getByPlaceholder('What was given').fill(finalTitle); await page.getByRole('spinbutton').fill(randomNonZeroNumber.toString()); diff --git a/test-playwright/33-record-gift-x10.spec.ts b/test-playwright/33-record-gift-x10.spec.ts index 37c5eb02..d6452da5 100644 --- a/test-playwright/33-record-gift-x10.spec.ts +++ b/test-playwright/33-record-gift-x10.spec.ts @@ -116,7 +116,7 @@ test('Record 9 new gifts', async ({ page }) => { if (i === 0) { await page.getByTestId('closeOnboardingAndFinish').click(); } - await page.getByRole('button', { name: 'Person' }).click(); + await page.getByRole('button', { name: 'Thank' }).click(); await page.getByRole('listitem').filter({ hasText: UNNAMED_ENTITY_NAME }).locator('svg').click(); await page.getByPlaceholder('What was given').fill(finalTitles[i]); await page.getByRole('spinbutton').fill(finalNumbers[i].toString()); diff --git a/test-playwright/37-record-gift-on-project.spec.ts b/test-playwright/37-record-gift-on-project.spec.ts index e2a8629b..4b4ecd99 100644 --- a/test-playwright/37-record-gift-on-project.spec.ts +++ b/test-playwright/37-record-gift-on-project.spec.ts @@ -1,7 +1,8 @@ import { test, expect, Page } from '@playwright/test'; import { importUser } from './testUtils'; -async function testProjectGive(page: Page, selector: string) { +async function testProjectGive(page: Page, isToProject: boolean) { + const selector = isToProject ? 'gives-to' : 'gives-from'; // Generate a random string of a few characters const randomString = Math.random().toString(36).substring(2, 6); @@ -42,9 +43,9 @@ async function testProjectGive(page: Page, selector: string) { } test('Record a give to a project', async ({ page }) => { - await testProjectGive(page, 'gives-to'); + await testProjectGive(page, true); }); test('Record a give from a project', async ({ page }) => { - await testProjectGive(page, 'gives-from'); + await testProjectGive(page, false); }); diff --git a/test-playwright/40-add-contact.spec.ts b/test-playwright/40-add-contact.spec.ts index 02d01f7a..34780af2 100644 --- a/test-playwright/40-add-contact.spec.ts +++ b/test-playwright/40-add-contact.spec.ts @@ -117,7 +117,7 @@ test('Add contact, record gift, confirm gift', async ({ page }) => { // Confirm that home shows contact in "Record Something…" await page.goto('./'); await page.getByTestId('closeOnboardingAndFinish').click(); - await page.getByRole('button', { name: 'Person' }).click(); + await page.getByRole('button', { name: 'Thank' }).click(); await expect(page.locator('#sectionGiftedGiver').getByRole('listitem').filter({ hasText: contactName })).toBeVisible(); // Record something given by new contact
- + +
+