diff --git a/src/components/EntityGrid.vue b/src/components/EntityGrid.vue
index 795d0639..30de3cc9 100644
--- a/src/components/EntityGrid.vue
+++ b/src/components/EntityGrid.vue
@@ -14,6 +14,8 @@ projects, and special entities with selection. * * @author Matthew Raymer */
:selectable="youSelectable"
:conflicted="youConflicted"
:entity-data="youEntityData"
+ :notify="notify"
+ :conflict-context="conflictContext"
@entity-selected="handleEntitySelected"
/>
@@ -23,6 +25,8 @@ projects, and special entities with selection. * * @author Matthew Raymer */
label="Unnamed"
icon="circle-question"
:entity-data="unnamedEntityData"
+ :notify="notify"
+ :conflict-context="conflictContext"
@entity-selected="handleEntitySelected"
/>
@@ -38,23 +42,27 @@ projects, and special entities with selection. * * @author Matthew Raymer */
@@ -77,6 +85,7 @@ import SpecialEntityCard from "./SpecialEntityCard.vue";
import ShowAllCard from "./ShowAllCard.vue";
import { Contact } from "../db/tables/contacts";
import { PlanData } from "../interfaces/records";
+import { NotificationIface } from "../constants/app";
/**
* EntityGrid - Unified grid layout for displaying people or projects
@@ -88,6 +97,7 @@ import { PlanData } from "../interfaces/records";
* - Empty state messaging
* - Show All navigation
* - Event delegation for entity selection
+ * - Warning notifications for conflicted entities
*/
@Component({
components: {
@@ -142,6 +152,14 @@ export default class EntityGrid extends Vue {
@Prop({ default: () => ({}) })
showAllQueryParams!: Record;
+ /** Notification function from parent component */
+ @Prop()
+ notify?: (notification: NotificationIface, timeout?: number) => void;
+
+ /** Context for conflict messages (e.g., "giver", "recipient") */
+ @Prop({ default: "other party" })
+ conflictContext!: string;
+
/**
* Computed CSS classes for the grid layout
*/
@@ -241,7 +259,7 @@ export default class EntityGrid extends Vue {
handleEntitySelected(event: {
type: string;
entityType: string;
- data: any;
+ data: { did?: string; name: string };
}): void {
this.emitEntitySelected({
type: "special",
@@ -253,7 +271,15 @@ export default class EntityGrid extends Vue {
// Emit methods using @Emit decorator
@Emit("entity-selected")
- emitEntitySelected(data: any): any {
+ emitEntitySelected(data: {
+ type: "person" | "project" | "special";
+ entityType?: string;
+ data: Contact | PlanData | { did?: string; name: string };
+ }): {
+ type: "person" | "project" | "special";
+ entityType?: string;
+ data: Contact | PlanData | { did?: string; name: string };
+ } {
return data;
}
}
diff --git a/src/components/EntitySelectionStep.vue b/src/components/EntitySelectionStep.vue
index 9798f42c..3c415ce2 100644
--- a/src/components/EntitySelectionStep.vue
+++ b/src/components/EntitySelectionStep.vue
@@ -19,6 +19,8 @@ with dynamic labeling and grid display. * * @author Matthew Raymer */
:you-selectable="youSelectable"
:show-all-route="showAllRoute"
:show-all-query-params="showAllQueryParams"
+ :notify="notify"
+ :conflict-context="conflictContext"
@entity-selected="handleEntitySelected"
/>
@@ -36,6 +38,7 @@ import { Component, Prop, Vue, Emit } from "vue-facing-decorator";
import EntityGrid from "./EntityGrid.vue";
import { Contact } from "../db/tables/contacts";
import { PlanData } from "../interfaces/records";
+import { NotificationIface } from "../constants/app";
/**
* Entity data interface for giver/receiver
@@ -67,6 +70,7 @@ interface EntitySelectionEvent {
* - Show All navigation with context preservation
* - Cancel functionality
* - Event delegation for entity selection
+ * - Warning notifications for conflicted entities
*/
@Component({
components: {
@@ -130,6 +134,10 @@ export default class EntitySelectionStep extends Vue {
@Prop()
receiver?: EntityData | null;
+ /** Notification function from parent component */
+ @Prop()
+ notify?: (notification: NotificationIface, timeout?: number) => void;
+
/**
* Computed step label based on context
*/
@@ -143,6 +151,17 @@ export default class EntitySelectionStep extends Vue {
}
}
+ /**
+ * Computed conflict context for better error messages
+ */
+ get conflictContext(): string {
+ if (this.stepType === "giver") {
+ return "recipient";
+ } else {
+ return "giver";
+ }
+ }
+
/**
* Whether to show projects in the grid
*/
diff --git a/src/components/GiftedDialog.vue b/src/components/GiftedDialog.vue
index 4748414f..8237bbe8 100644
--- a/src/components/GiftedDialog.vue
+++ b/src/components/GiftedDialog.vue
@@ -18,6 +18,7 @@
:to-project-id="toProjectId"
:giver="giver"
:receiver="receiver"
+ :notify="$notify"
@entity-selected="handleEntitySelected"
@cancel="cancel"
/>
diff --git a/src/components/PersonCard.vue b/src/components/PersonCard.vue
index e391cfff..1f3bf595 100644
--- a/src/components/PersonCard.vue
+++ b/src/components/PersonCard.vue
@@ -34,6 +34,7 @@ conflict detection. * * @author Matthew Raymer */
import { Component, Prop, Vue, Emit } from "vue-facing-decorator";
import EntityIcon from "./EntityIcon.vue";
import { Contact } from "../db/tables/contacts";
+import { NotificationIface } from "../constants/app";
/**
* PersonCard - Individual person display with selection capability
@@ -44,6 +45,7 @@ import { Contact } from "../db/tables/contacts";
* - Time icon overlay for contacts
* - Click event handling
* - Emits click events for parent handling
+ * - Warning notifications for conflicted entities
*/
@Component({
components: {
@@ -67,6 +69,14 @@ export default class PersonCard extends Vue {
@Prop({ default: false })
showTimeIcon!: boolean;
+ /** Notification function from parent component */
+ @Prop()
+ notify?: (notification: NotificationIface, timeout?: number) => void;
+
+ /** Context for conflict messages (e.g., "giver", "recipient") */
+ @Prop({ default: "other party" })
+ conflictContext!: string;
+
/**
* Computed CSS classes for the card
*/
@@ -92,11 +102,22 @@ export default class PersonCard extends Vue {
}
/**
- * Handle card click - only emit if selectable and not conflicted
+ * Handle card click - emit if selectable and not conflicted, show warning if conflicted
*/
handleClick(): void {
if (this.selectable && !this.conflicted) {
this.emitPersonSelected(this.person);
+ } else if (this.conflicted && this.notify) {
+ // Show warning notification for conflicted entity
+ this.notify(
+ {
+ 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}.`,
+ },
+ 3000,
+ );
}
}
diff --git a/src/components/SpecialEntityCard.vue b/src/components/SpecialEntityCard.vue
index 79bc2bc0..1d475229 100644
--- a/src/components/SpecialEntityCard.vue
+++ b/src/components/SpecialEntityCard.vue
@@ -13,6 +13,7 @@ conflict detection and selection capability. * * @author Matthew Raymer */