Browse Source
Replace Project Link text input with interactive selection dialog using new MeetingProjectDialog component. Dialog displays user's projects with icons and issuer information, following the same pattern as ProjectRepresentativeDialog. - Create MeetingProjectDialog with EntityGrid integration - Add clickable project field with icon, name, and issuer display - Load projects from /api/v2/report/plansByIssuer endpoint - Show issuer name instead of handleId for better UX - Refactor loadProjects to remove unused rowId fieldpull/222/head
3 changed files with 296 additions and 9 deletions
@ -0,0 +1,123 @@ |
|||
<template> |
|||
<div v-if="visible" class="dialog-overlay"> |
|||
<div class="dialog"> |
|||
<!-- Header --> |
|||
<h2 class="text-lg font-semibold leading-[1.25] mb-4">Select Project</h2> |
|||
|
|||
<!-- EntityGrid for projects --> |
|||
<EntityGrid |
|||
:entity-type="'projects'" |
|||
:entities="allProjects" |
|||
: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="'project'" |
|||
@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 { PlanData } from "../interfaces/records"; |
|||
import { NotificationIface } from "../constants/app"; |
|||
|
|||
/** |
|||
* MeetingProjectDialog - Dialog for selecting a project link for a meeting |
|||
* |
|||
* Features: |
|||
* - EntityGrid integration for project selection |
|||
* - No special entities (You, Unnamed) |
|||
* - Immediate assignment on project selection |
|||
* - Cancel button to close without selection |
|||
*/ |
|||
@Component({ |
|||
components: { |
|||
EntityGrid, |
|||
}, |
|||
}) |
|||
export default class MeetingProjectDialog extends Vue { |
|||
/** Whether the dialog is visible */ |
|||
visible = false; |
|||
|
|||
/** Array of available projects */ |
|||
@Prop({ required: true }) |
|||
allProjects!: PlanData[]; |
|||
|
|||
/** Active user's DID */ |
|||
@Prop({ required: true }) |
|||
activeDid!: string; |
|||
|
|||
/** All user's DIDs */ |
|||
@Prop({ required: true }) |
|||
allMyDids!: string[]; |
|||
|
|||
/** All contacts */ |
|||
@Prop({ required: true }) |
|||
allContacts!: Contact[]; |
|||
|
|||
/** Notification function from parent component */ |
|||
@Prop() |
|||
notify?: (notification: NotificationIface, timeout?: number) => void; |
|||
|
|||
/** |
|||
* Handle entity selection from EntityGrid |
|||
* Immediately assigns the selected project and closes the dialog |
|||
*/ |
|||
handleEntitySelected(event: { |
|||
type: "person" | "project"; |
|||
data: Contact | PlanData; |
|||
}) { |
|||
const project = event.data as PlanData; |
|||
this.emitAssign(project); |
|||
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(project: PlanData): PlanData { |
|||
return project; |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style scoped></style> |
|||
Loading…
Reference in new issue