add project selection for one that this 'fulfills'
This commit is contained in:
@@ -39,7 +39,7 @@ import { PlanData } from "../interfaces/records";
|
||||
import { NotificationIface } from "../constants/app";
|
||||
|
||||
/**
|
||||
* MeetingProjectDialog - Dialog for selecting a project link for a meeting
|
||||
* ProjectSelectionDialog - Dialog for selecting a project
|
||||
*
|
||||
* Features:
|
||||
* - EntityGrid integration for project selection
|
||||
@@ -52,7 +52,7 @@ import { NotificationIface } from "../constants/app";
|
||||
EntityGrid,
|
||||
},
|
||||
})
|
||||
export default class MeetingProjectDialog extends Vue {
|
||||
export default class ProjectSelectionDialog extends Vue {
|
||||
/** Whether the dialog is visible */
|
||||
visible = false;
|
||||
|
||||
@@ -80,6 +80,7 @@ export interface PlanActionClaim extends ClaimObject {
|
||||
agent?: { identifier: string };
|
||||
description?: string;
|
||||
endTime?: string;
|
||||
fulfills?: { "@type": string; identifier?: string; lastClaimId?: string };
|
||||
identifier?: string;
|
||||
image?: string;
|
||||
lastClaimId?: string;
|
||||
|
||||
@@ -114,6 +114,49 @@
|
||||
@assign="handleRepresentativeAssigned"
|
||||
/>
|
||||
|
||||
<!-- Parent Project Selection -->
|
||||
<div class="w-full flex items-stretch my-4">
|
||||
<div
|
||||
class="flex items-center gap-2 grow border border-slate-400 border-r-0 last:border-r px-3 py-2 rounded-l last:rounded overflow-hidden cursor-pointer hover:bg-slate-100"
|
||||
@click="openParentProjectDialog"
|
||||
>
|
||||
<div>
|
||||
<font-awesome icon="folder" class="text-slate-400" />
|
||||
</div>
|
||||
<div class="overflow-hidden">
|
||||
<div
|
||||
:class="{
|
||||
'text-sm font-semibold': parentProjectHandleId,
|
||||
'text-slate-400': !parentProjectHandleId,
|
||||
}"
|
||||
class="truncate"
|
||||
>
|
||||
{{
|
||||
parentProjectHandleId
|
||||
? parentProjectName || "Parent Project"
|
||||
: "Select Parent Project\u2026"
|
||||
}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
v-if="parentProjectHandleId"
|
||||
class="text-rose-600 px-3 py-2 border border-slate-400 border-l-0 rounded-r hover:bg-rose-600 hover:text-white hover:border-rose-600"
|
||||
@click="unsetParentProject"
|
||||
>
|
||||
<font-awesome icon="trash-can" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<ProjectSelectionDialog
|
||||
ref="parentProjectDialog"
|
||||
:active-did="activeDid"
|
||||
:all-my-dids="allMyDids"
|
||||
:all-contacts="allContacts"
|
||||
:notify="$notify"
|
||||
@assign="handleParentProjectSelected"
|
||||
/>
|
||||
|
||||
<div class="mb-4">
|
||||
<p v-if="shouldShowOwnershipWarning">
|
||||
<span class="text-red-500">Beware!</span>
|
||||
@@ -283,6 +326,7 @@ import { LeafletMouseEvent } from "leaflet";
|
||||
import EntityIcon from "../components/EntityIcon.vue";
|
||||
import ImageMethodDialog from "../components/ImageMethodDialog.vue";
|
||||
import ProjectRepresentativeDialog from "../components/ProjectRepresentativeDialog.vue";
|
||||
import ProjectSelectionDialog from "../components/ProjectSelectionDialog.vue";
|
||||
import QuickNav from "../components/QuickNav.vue";
|
||||
import {
|
||||
AppString,
|
||||
@@ -311,6 +355,7 @@ import {
|
||||
PROJECT_TIMEOUT_VERY_LONG,
|
||||
} from "../constants/notifications";
|
||||
import { PlanActionClaim } from "../interfaces/claims";
|
||||
import { PlanData } from "../interfaces/records";
|
||||
import {
|
||||
createEndorserJwtVcFromClaim,
|
||||
getHeaders,
|
||||
@@ -378,6 +423,7 @@ import { logger } from "../utils/logger";
|
||||
components: {
|
||||
EntityIcon,
|
||||
ImageMethodDialog,
|
||||
ProjectSelectionDialog,
|
||||
ProjectRepresentativeDialog,
|
||||
LMap,
|
||||
LMarker,
|
||||
@@ -429,6 +475,8 @@ export default class NewEditProjectView extends Vue {
|
||||
latitude = 0;
|
||||
longitude = 0;
|
||||
numAccounts = 0;
|
||||
parentProjectHandleId = "";
|
||||
parentProjectName = "";
|
||||
projectId = "";
|
||||
projectIssuerDid = "";
|
||||
sendToTrustroots = false;
|
||||
@@ -510,6 +558,10 @@ export default class NewEditProjectView extends Vue {
|
||||
);
|
||||
}
|
||||
}
|
||||
if (this.fullClaim?.fulfills?.identifier) {
|
||||
this.parentProjectHandleId = this.fullClaim.fulfills.identifier;
|
||||
this.loadParentProjectName(this.parentProjectHandleId);
|
||||
}
|
||||
if (this.fullClaim.startTime) {
|
||||
const localDateTime = DateTime.fromISO(
|
||||
this.fullClaim.startTime as string,
|
||||
@@ -623,6 +675,14 @@ export default class NewEditProjectView extends Vue {
|
||||
} else {
|
||||
delete vcClaim.agent;
|
||||
}
|
||||
if (this.parentProjectHandleId) {
|
||||
vcClaim.fulfills = {
|
||||
"@type": "PlanAction",
|
||||
identifier: this.parentProjectHandleId,
|
||||
};
|
||||
} else {
|
||||
delete vcClaim.fulfills;
|
||||
}
|
||||
if (this.imageUrl) {
|
||||
vcClaim.image = this.imageUrl;
|
||||
} else {
|
||||
@@ -1075,5 +1135,33 @@ export default class NewEditProjectView extends Vue {
|
||||
unsetRepresentative(): void {
|
||||
this.agentDid = "";
|
||||
}
|
||||
|
||||
openParentProjectDialog(): void {
|
||||
(this.$refs.parentProjectDialog as ProjectSelectionDialog).open();
|
||||
}
|
||||
|
||||
handleParentProjectSelected(project: PlanData): void {
|
||||
this.parentProjectHandleId = project.handleId;
|
||||
this.parentProjectName = project.name;
|
||||
}
|
||||
|
||||
unsetParentProject(): void {
|
||||
this.parentProjectHandleId = "";
|
||||
this.parentProjectName = "";
|
||||
}
|
||||
|
||||
private async loadParentProjectName(handleId: string): Promise<void> {
|
||||
try {
|
||||
const url =
|
||||
this.apiServer + "/api/claim/byHandle/" + encodeURIComponent(handleId);
|
||||
const headers = await getHeaders(this.activeDid);
|
||||
const resp = await this.axios.get(url, { headers });
|
||||
if (resp.status === 200 && resp.data?.claim?.name) {
|
||||
this.parentProjectName = resp.data.claim.name;
|
||||
}
|
||||
} catch {
|
||||
// Parent project name will remain empty
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -267,7 +267,7 @@
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<MeetingProjectDialog
|
||||
<ProjectSelectionDialog
|
||||
ref="meetingProjectDialog"
|
||||
:active-did="activeDid"
|
||||
:all-my-dids="allMyDids"
|
||||
@@ -585,7 +585,7 @@ import TopMessage from "../components/TopMessage.vue";
|
||||
import MeetingMembersList from "../components/MeetingMembersList.vue";
|
||||
import MeetingMemberMatch from "../components/MeetingMemberMatch.vue";
|
||||
import MeetingExclusionGroups from "../components/MeetingExclusionGroups.vue";
|
||||
import MeetingProjectDialog from "../components/MeetingProjectDialog.vue";
|
||||
import ProjectSelectionDialog from "../components/ProjectSelectionDialog.vue";
|
||||
import ProjectIcon from "../components/ProjectIcon.vue";
|
||||
import {
|
||||
errorStringForLog,
|
||||
@@ -637,7 +637,7 @@ interface MeetingSetupInputs {
|
||||
MeetingMembersList,
|
||||
MeetingMemberMatch,
|
||||
MeetingExclusionGroups,
|
||||
MeetingProjectDialog,
|
||||
ProjectSelectionDialog,
|
||||
ProjectIcon,
|
||||
},
|
||||
mixins: [PlatformServiceMixin],
|
||||
@@ -1468,7 +1468,7 @@ export default class OnboardMeetingView extends Vue {
|
||||
* Open the project link selection dialog
|
||||
*/
|
||||
openProjectLinkDialog(): void {
|
||||
(this.$refs.meetingProjectDialog as MeetingProjectDialog).open();
|
||||
(this.$refs.meetingProjectDialog as ProjectSelectionDialog).open();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -193,7 +193,7 @@
|
||||
class="bg-slate-100 px-4 py-3 rounded-md"
|
||||
>
|
||||
<h3 class="text-sm uppercase font-semibold mt-3">
|
||||
Projects That Contribute To This
|
||||
These Projects Are Part Of This
|
||||
</h3>
|
||||
<!--
|
||||
centering because long, wrapped project names didn't left align with blank
|
||||
@@ -218,7 +218,7 @@
|
||||
<div>
|
||||
<div v-if="fulfilledByThis" class="bg-slate-100 px-4 py-3 rounded-md">
|
||||
<h3 class="text-sm uppercase font-semibold mb-3">
|
||||
Projects Getting Contributions From This
|
||||
This Project Is Part Of These
|
||||
</h3>
|
||||
<!--
|
||||
centering because long, wrapped project names didn't left align with blank
|
||||
|
||||
Reference in New Issue
Block a user