feat: replace authorized representative input with contact selection dialog #219
Open
jose
wants to merge 4 commits from project-representative-dialog into master
3 changed files with 251 additions and 21 deletions
@ -0,0 +1,117 @@ |
|||||
|
<template> |
||||
|
<div v-if="visible" class="dialog-overlay"> |
||||
|
<div class="dialog"> |
||||
|
<!-- Header --> |
||||
|
<h2 class="text-lg font-semibold leading-[1.25] mb-4"> |
||||
|
Select Representative |
||||
|
</h2> |
||||
|
|
||||
|
<!-- EntityGrid for contacts --> |
||||
|
<EntityGrid |
||||
|
:entity-type="'people'" |
||||
|
:entities="allContacts" |
||||
|
:active-did="activeDid" |
||||
|
:all-my-dids="allMyDids" |
||||
|
:all-contacts="allContacts" |
||||
|
:conflict-checker="() => false" |
||||
|
:show-you-entity="false" |
||||
|
:show-unnamed-entity="false" |
||||
|
:notify="notify" |
||||
|
:conflict-context="'representative'" |
||||
|
@entity-selected="handleEntitySelected" |
||||
|
/> |
||||
|
|
||||
|
<!-- Cancel Button --> |
||||
|
<div class="flex gap-2 mt-4"> |
||||
|
<button |
||||
|
class="block w-full text-center text-md uppercase bg-gradient-to-b from-slate-400 to-slate-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-2 py-2 rounded-md" |
||||
|
@click="handleCancel" |
||||
|
> |
||||
|
Cancel |
||||
|
</button> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script lang="ts"> |
||||
|
import { Component, Prop, Vue, Emit } from "vue-facing-decorator"; |
||||
|
import EntityGrid from "./EntityGrid.vue"; |
||||
|
import { Contact } from "../db/tables/contacts"; |
||||
|
import { NotificationIface } from "../constants/app"; |
||||
|
|
||||
|
/** |
||||
|
* ProjectRepresentativeDialog - Dialog for selecting an authorized representative |
||||
|
* |
||||
|
* Features: |
||||
|
* - EntityGrid integration for contact selection |
||||
|
* - No special entities (You, Unnamed) |
||||
|
* - Immediate assignment on contact selection |
||||
|
* - Cancel button to close without selection |
||||
|
*/ |
||||
|
@Component({ |
||||
|
components: { |
||||
|
EntityGrid, |
||||
|
}, |
||||
|
}) |
||||
|
export default class ProjectRepresentativeDialog extends Vue { |
||||
|
/** Whether the dialog is visible */ |
||||
|
visible = false; |
||||
|
|
||||
|
/** Array of available contacts */ |
||||
|
@Prop({ required: true }) |
||||
|
allContacts!: Contact[]; |
||||
|
|
||||
|
/** Active user's DID */ |
||||
|
@Prop({ required: true }) |
||||
|
activeDid!: string; |
||||
|
|
||||
|
/** All user's DIDs */ |
||||
|
@Prop({ required: true }) |
||||
|
allMyDids!: string[]; |
||||
|
|
||||
|
/** Notification function from parent component */ |
||||
|
@Prop() |
||||
|
notify?: (notification: NotificationIface, timeout?: number) => void; |
||||
|
|
||||
|
/** |
||||
|
* Handle entity selection from EntityGrid |
||||
|
* Immediately assigns the selected contact and closes the dialog |
||||
|
*/ |
||||
|
handleEntitySelected(event: { type: "person" | "project"; data: Contact }) { |
||||
|
const contact = event.data as Contact; |
||||
|
this.emitAssign(contact); |
||||
|
this.close(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Handle cancel button click |
||||
|
*/ |
||||
|
handleCancel(): void { |
||||
|
this.close(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Open the dialog |
||||
|
*/ |
||||
|
open(): void { |
||||
|
this.visible = true; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Close the dialog |
||||
|
*/ |
||||
|
close(): void { |
||||
|
this.visible = false; |
||||
|
} |
||||
|
|
||||
|
// Emit methods using @Emit decorator |
||||
|
|
||||
|
@Emit("assign") |
||||
|
emitAssign(contact: Contact): Contact { |
||||
|
return contact; |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style scoped></style> |
||||
Loading…
Reference in new issue