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";
|
import { NotificationIface } from "../constants/app";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* MeetingProjectDialog - Dialog for selecting a project link for a meeting
|
* ProjectSelectionDialog - Dialog for selecting a project
|
||||||
*
|
*
|
||||||
* Features:
|
* Features:
|
||||||
* - EntityGrid integration for project selection
|
* - EntityGrid integration for project selection
|
||||||
@@ -52,7 +52,7 @@ import { NotificationIface } from "../constants/app";
|
|||||||
EntityGrid,
|
EntityGrid,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
export default class MeetingProjectDialog extends Vue {
|
export default class ProjectSelectionDialog extends Vue {
|
||||||
/** Whether the dialog is visible */
|
/** Whether the dialog is visible */
|
||||||
visible = false;
|
visible = false;
|
||||||
|
|
||||||
@@ -80,6 +80,7 @@ export interface PlanActionClaim extends ClaimObject {
|
|||||||
agent?: { identifier: string };
|
agent?: { identifier: string };
|
||||||
description?: string;
|
description?: string;
|
||||||
endTime?: string;
|
endTime?: string;
|
||||||
|
fulfills?: { "@type": string; identifier?: string; lastClaimId?: string };
|
||||||
identifier?: string;
|
identifier?: string;
|
||||||
image?: string;
|
image?: string;
|
||||||
lastClaimId?: string;
|
lastClaimId?: string;
|
||||||
|
|||||||
@@ -114,6 +114,49 @@
|
|||||||
@assign="handleRepresentativeAssigned"
|
@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">
|
<div class="mb-4">
|
||||||
<p v-if="shouldShowOwnershipWarning">
|
<p v-if="shouldShowOwnershipWarning">
|
||||||
<span class="text-red-500">Beware!</span>
|
<span class="text-red-500">Beware!</span>
|
||||||
@@ -283,6 +326,7 @@ import { LeafletMouseEvent } from "leaflet";
|
|||||||
import EntityIcon from "../components/EntityIcon.vue";
|
import EntityIcon from "../components/EntityIcon.vue";
|
||||||
import ImageMethodDialog from "../components/ImageMethodDialog.vue";
|
import ImageMethodDialog from "../components/ImageMethodDialog.vue";
|
||||||
import ProjectRepresentativeDialog from "../components/ProjectRepresentativeDialog.vue";
|
import ProjectRepresentativeDialog from "../components/ProjectRepresentativeDialog.vue";
|
||||||
|
import ProjectSelectionDialog from "../components/ProjectSelectionDialog.vue";
|
||||||
import QuickNav from "../components/QuickNav.vue";
|
import QuickNav from "../components/QuickNav.vue";
|
||||||
import {
|
import {
|
||||||
AppString,
|
AppString,
|
||||||
@@ -311,6 +355,7 @@ import {
|
|||||||
PROJECT_TIMEOUT_VERY_LONG,
|
PROJECT_TIMEOUT_VERY_LONG,
|
||||||
} from "../constants/notifications";
|
} from "../constants/notifications";
|
||||||
import { PlanActionClaim } from "../interfaces/claims";
|
import { PlanActionClaim } from "../interfaces/claims";
|
||||||
|
import { PlanData } from "../interfaces/records";
|
||||||
import {
|
import {
|
||||||
createEndorserJwtVcFromClaim,
|
createEndorserJwtVcFromClaim,
|
||||||
getHeaders,
|
getHeaders,
|
||||||
@@ -378,6 +423,7 @@ import { logger } from "../utils/logger";
|
|||||||
components: {
|
components: {
|
||||||
EntityIcon,
|
EntityIcon,
|
||||||
ImageMethodDialog,
|
ImageMethodDialog,
|
||||||
|
ProjectSelectionDialog,
|
||||||
ProjectRepresentativeDialog,
|
ProjectRepresentativeDialog,
|
||||||
LMap,
|
LMap,
|
||||||
LMarker,
|
LMarker,
|
||||||
@@ -429,6 +475,8 @@ export default class NewEditProjectView extends Vue {
|
|||||||
latitude = 0;
|
latitude = 0;
|
||||||
longitude = 0;
|
longitude = 0;
|
||||||
numAccounts = 0;
|
numAccounts = 0;
|
||||||
|
parentProjectHandleId = "";
|
||||||
|
parentProjectName = "";
|
||||||
projectId = "";
|
projectId = "";
|
||||||
projectIssuerDid = "";
|
projectIssuerDid = "";
|
||||||
sendToTrustroots = false;
|
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) {
|
if (this.fullClaim.startTime) {
|
||||||
const localDateTime = DateTime.fromISO(
|
const localDateTime = DateTime.fromISO(
|
||||||
this.fullClaim.startTime as string,
|
this.fullClaim.startTime as string,
|
||||||
@@ -623,6 +675,14 @@ export default class NewEditProjectView extends Vue {
|
|||||||
} else {
|
} else {
|
||||||
delete vcClaim.agent;
|
delete vcClaim.agent;
|
||||||
}
|
}
|
||||||
|
if (this.parentProjectHandleId) {
|
||||||
|
vcClaim.fulfills = {
|
||||||
|
"@type": "PlanAction",
|
||||||
|
identifier: this.parentProjectHandleId,
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
delete vcClaim.fulfills;
|
||||||
|
}
|
||||||
if (this.imageUrl) {
|
if (this.imageUrl) {
|
||||||
vcClaim.image = this.imageUrl;
|
vcClaim.image = this.imageUrl;
|
||||||
} else {
|
} else {
|
||||||
@@ -1075,5 +1135,33 @@ export default class NewEditProjectView extends Vue {
|
|||||||
unsetRepresentative(): void {
|
unsetRepresentative(): void {
|
||||||
this.agentDid = "";
|
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>
|
</script>
|
||||||
|
|||||||
@@ -267,7 +267,7 @@
|
|||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<MeetingProjectDialog
|
<ProjectSelectionDialog
|
||||||
ref="meetingProjectDialog"
|
ref="meetingProjectDialog"
|
||||||
:active-did="activeDid"
|
:active-did="activeDid"
|
||||||
:all-my-dids="allMyDids"
|
:all-my-dids="allMyDids"
|
||||||
@@ -585,7 +585,7 @@ import TopMessage from "../components/TopMessage.vue";
|
|||||||
import MeetingMembersList from "../components/MeetingMembersList.vue";
|
import MeetingMembersList from "../components/MeetingMembersList.vue";
|
||||||
import MeetingMemberMatch from "../components/MeetingMemberMatch.vue";
|
import MeetingMemberMatch from "../components/MeetingMemberMatch.vue";
|
||||||
import MeetingExclusionGroups from "../components/MeetingExclusionGroups.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 ProjectIcon from "../components/ProjectIcon.vue";
|
||||||
import {
|
import {
|
||||||
errorStringForLog,
|
errorStringForLog,
|
||||||
@@ -637,7 +637,7 @@ interface MeetingSetupInputs {
|
|||||||
MeetingMembersList,
|
MeetingMembersList,
|
||||||
MeetingMemberMatch,
|
MeetingMemberMatch,
|
||||||
MeetingExclusionGroups,
|
MeetingExclusionGroups,
|
||||||
MeetingProjectDialog,
|
ProjectSelectionDialog,
|
||||||
ProjectIcon,
|
ProjectIcon,
|
||||||
},
|
},
|
||||||
mixins: [PlatformServiceMixin],
|
mixins: [PlatformServiceMixin],
|
||||||
@@ -1468,7 +1468,7 @@ export default class OnboardMeetingView extends Vue {
|
|||||||
* Open the project link selection dialog
|
* Open the project link selection dialog
|
||||||
*/
|
*/
|
||||||
openProjectLinkDialog(): void {
|
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"
|
class="bg-slate-100 px-4 py-3 rounded-md"
|
||||||
>
|
>
|
||||||
<h3 class="text-sm uppercase font-semibold mt-3">
|
<h3 class="text-sm uppercase font-semibold mt-3">
|
||||||
Projects That Contribute To This
|
These Projects Are Part Of This
|
||||||
</h3>
|
</h3>
|
||||||
<!--
|
<!--
|
||||||
centering because long, wrapped project names didn't left align with blank
|
centering because long, wrapped project names didn't left align with blank
|
||||||
@@ -218,7 +218,7 @@
|
|||||||
<div>
|
<div>
|
||||||
<div v-if="fulfilledByThis" class="bg-slate-100 px-4 py-3 rounded-md">
|
<div v-if="fulfilledByThis" class="bg-slate-100 px-4 py-3 rounded-md">
|
||||||
<h3 class="text-sm uppercase font-semibold mb-3">
|
<h3 class="text-sm uppercase font-semibold mb-3">
|
||||||
Projects Getting Contributions From This
|
This Project Is Part Of These
|
||||||
</h3>
|
</h3>
|
||||||
<!--
|
<!--
|
||||||
centering because long, wrapped project names didn't left align with blank
|
centering because long, wrapped project names didn't left align with blank
|
||||||
|
|||||||
Reference in New Issue
Block a user