From 84aef212916ab40c63e73cf1f3b305d533710f68 Mon Sep 17 00:00:00 2001 From: Perplexity Date: Sun, 11 Oct 2026 17:47:05 +0000 Subject: [PATCH] Render proposals section-by-section ProposalDetail now displays the structured fields captured by the creation wizard as labeled sections instead of a flat paragraph list: - Decision requested, rationale, scope (included/excluded), risks with mitigations, responsible party, and conflict disclosure from commonData - Funding details (formatted maximum authorization, target completion, milestones) and finished criteria from typeData for funding proposals - Policy details (supersedes, effective date) for policy proposals - Free-form narrative blocks remain as an 'Additional context' section, separated from the structured data by a rule only when both exist Each section uses the app's existing pattern of a bold header heading with a small uppercase eyebrow label, and empty sections are omitted so older proposals render unchanged. --- src/components/ProposalDetail.vue | 73 +++++- src/components/ProposalSection.vue | 32 +++ src/components/ProposalStructuredSections.vue | 215 ++++++++++++++++++ tsconfig.app.tsbuildinfo | 2 +- 4 files changed, 309 insertions(+), 13 deletions(-) create mode 100644 src/components/ProposalSection.vue create mode 100644 src/components/ProposalStructuredSections.vue diff --git a/src/components/ProposalDetail.vue b/src/components/ProposalDetail.vue index e3bca04..28e6f83 100644 --- a/src/components/ProposalDetail.vue +++ b/src/components/ProposalDetail.vue @@ -143,22 +143,54 @@ role="tabpanel" aria-labelledby="proposal-tab-proposal" > -
+

Proposal details

-
-

-

-
+ + + + +
+
+

+ Additional context +

+ + + Free-form + +
+ +
+ +
+
+
(null); const commentTree = computed(() => buildCommentTree(comments.value)); +// Narrative content blocks, ordered by index; structured wizard data renders above them +const paragraphBlocks = computed(() => + [...(props.proposal.paragraphs ?? [])].sort((a, b) => a.index - b.index), +); + +const hasStructuredContent = computed(() => { + const common = props.proposal.commonData ?? {}; + return Object.values(common).some((value) => { + if (value == null) return false; + if (typeof value === "string") return value.trim().length > 0; + if (Array.isArray(value)) return value.length > 0; + if (typeof value === "object") return Object.keys(value as object).length > 0; + return true; + }); +}); + const isSubmitDisabled = computed(() => { return !commentText.value.trim() || isSubmitting.value; }); diff --git a/src/components/ProposalSection.vue b/src/components/ProposalSection.vue new file mode 100644 index 0000000..72e85da --- /dev/null +++ b/src/components/ProposalSection.vue @@ -0,0 +1,32 @@ + + + diff --git a/src/components/ProposalStructuredSections.vue b/src/components/ProposalStructuredSections.vue new file mode 100644 index 0000000..af0c978 --- /dev/null +++ b/src/components/ProposalStructuredSections.vue @@ -0,0 +1,215 @@ + + + diff --git a/tsconfig.app.tsbuildinfo b/tsconfig.app.tsbuildinfo index a21b3a8..f110bb8 100644 --- a/tsconfig.app.tsbuildinfo +++ b/tsconfig.app.tsbuildinfo @@ -1 +1 @@ -{"root":["./src/main.ts","./src/vite-env.d.ts","./src/components/icons/index.ts","./src/components/icons/types.ts","./src/composables/useFilterNotifier.ts","./src/composables/useLoading.ts","./src/composables/useModal.ts","./src/composables/useProposalWizard.ts","./src/composables/useSession.ts","./src/generated/typescript/index.ts","./src/generated/typescript/core/ApiError.ts","./src/generated/typescript/core/ApiRequestOptions.ts","./src/generated/typescript/core/ApiResult.ts","./src/generated/typescript/core/CancelablePromise.ts","./src/generated/typescript/core/OpenAPI.ts","./src/generated/typescript/core/request.ts","./src/generated/typescript/models/AddAmendmentRequest.ts","./src/generated/typescript/models/AddCommentRequest.ts","./src/generated/typescript/models/AddProposalRequest.ts","./src/generated/typescript/models/Amendment.ts","./src/generated/typescript/models/AmendmentParagraph.ts","./src/generated/typescript/models/AmendmentStatus.ts","./src/generated/typescript/models/AmendmentVote.ts","./src/generated/typescript/models/AmendmentWithParagraphs.ts","./src/generated/typescript/models/AmendmentWithSummary.ts","./src/generated/typescript/models/Claims.ts","./src/generated/typescript/models/CommentReaction.ts","./src/generated/typescript/models/CommentReactionSummary.ts","./src/generated/typescript/models/CommentTargetType.ts","./src/generated/typescript/models/CommentWithUser.ts","./src/generated/typescript/models/EditProposalRequest.ts","./src/generated/typescript/models/FreighterLoginRequest.ts","./src/generated/typescript/models/FreighterLoginResponse.ts","./src/generated/typescript/models/FundingTypeData.ts","./src/generated/typescript/models/ListCommentsResponse.ts","./src/generated/typescript/models/LoginRequest.ts","./src/generated/typescript/models/MoneyAmount.ts","./src/generated/typescript/models/Organization.ts","./src/generated/typescript/models/PolicyTypeData.ts","./src/generated/typescript/models/Proposal.ts","./src/generated/typescript/models/ProposalCommonData.ts","./src/generated/typescript/models/ProposalEvent.ts","./src/generated/typescript/models/ProposalEventType.ts","./src/generated/typescript/models/ProposalMilestone.ts","./src/generated/typescript/models/ProposalParagraph.ts","./src/generated/typescript/models/ProposalParagraphRequest.ts","./src/generated/typescript/models/ProposalRevision.ts","./src/generated/typescript/models/ProposalRevisionBlock.ts","./src/generated/typescript/models/ProposalRevisionStatus.ts","./src/generated/typescript/models/ProposalRisk.ts","./src/generated/typescript/models/ProposalScope.ts","./src/generated/typescript/models/ProposalSponsor.ts","./src/generated/typescript/models/ProposalState.ts","./src/generated/typescript/models/ProposalVote.ts","./src/generated/typescript/models/ProposalWithParagraphs.ts","./src/generated/typescript/models/ProposalWithSummary.ts","./src/generated/typescript/models/ReactCommentRequest.ts","./src/generated/typescript/models/ReactCommentResponse.ts","./src/generated/typescript/models/ReactionType.ts","./src/generated/typescript/models/RegisterOrganizationRequest.ts","./src/generated/typescript/models/RegisterRequest.ts","./src/generated/typescript/models/RegisteredUser.ts","./src/generated/typescript/models/SelectableAmendment.ts","./src/generated/typescript/models/SelectableComment.ts","./src/generated/typescript/models/SelectableProposal.ts","./src/generated/typescript/models/SetProposalRevisionRequest.ts","./src/generated/typescript/models/SponsorProposalRequest.ts","./src/generated/typescript/models/UserAmendmentVote.ts","./src/generated/typescript/models/UserProposalVotes.ts","./src/generated/typescript/models/VoteAmendmentRequest.ts","./src/generated/typescript/models/VoteAmendmentResponse.ts","./src/generated/typescript/models/VoteChoice.ts","./src/generated/typescript/models/VoteProposalRequest.ts","./src/generated/typescript/schemas/$AddProposalRequest.ts","./src/generated/typescript/schemas/$FreighterLoginRequest.ts","./src/generated/typescript/schemas/$ListProposalsResponse.ts","./src/generated/typescript/schemas/$LoginRequest.ts","./src/generated/typescript/schemas/$ProposalItem.ts","./src/generated/typescript/schemas/$ProposalList.ts","./src/generated/typescript/schemas/$RegisterRequest.ts","./src/generated/typescript/schemas/$VisitProposalRequest.ts","./src/generated/typescript/services/AmendmentService.ts","./src/generated/typescript/services/AuthService.ts","./src/generated/typescript/services/CommentService.ts","./src/generated/typescript/services/OrganizationService.ts","./src/generated/typescript/services/ProposalService.ts","./src/router/index.ts","./src/stores/filterStore.ts","./src/types/color.ts","./src/types/comment.ts","./src/types/dropdown.ts","./src/types/headerletter.ts","./src/types/proposal.ts","./src/types/proposalWizard.ts","./src/types/user.ts","./src/types/vote.ts","./src/utils/amendment.ts","./src/utils/auth.ts","./src/utils/comments.ts","./src/utils/eventBus.ts","./src/utils/markdown.ts","./src/utils/proposalExport.ts","./src/utils/wallet.ts","./src/App.vue","./src/components/AmendmentCarousel.vue","./src/components/BrandBar.vue","./src/components/Chip.vue","./src/components/ColoredHeader.vue","./src/components/CommentThread.vue","./src/components/Dropdown.vue","./src/components/LoadingSpinner.vue","./src/components/PostBuilder.vue","./src/components/ProposalContainer.vue","./src/components/ProposalDetail.vue","./src/components/ProposalEmptyState.vue","./src/components/ProposalExportCard.vue","./src/components/ProposalRevisionDropdown.vue","./src/components/ProposalSponsorCard.vue","./src/components/ProposalVotingCard.vue","./src/components/Sidebar.vue","./src/components/Thread.vue","./src/components/icons/Abstain.vue","./src/components/icons/AppIcon.vue","./src/components/icons/Arrow.vue","./src/components/icons/Cancel.vue","./src/components/icons/Confirm.vue","./src/components/icons/DownArrow.vue","./src/components/icons/Download.vue","./src/components/icons/Filter.vue","./src/components/icons/IconBase.vue","./src/components/icons/Identification.vue","./src/components/icons/Menu.vue","./src/components/icons/Plus.vue","./src/components/icons/SpeechBubbles.vue","./src/components/icons/Stack.vue","./src/components/icons/ThumbsDown.vue","./src/components/icons/ThumbsUp.vue","./src/components/modals/AmendmentModal.vue","./src/components/modals/EditProposalModal.vue","./src/components/modals/FilterModal.vue","./src/components/modals/Modal.vue","./src/components/modals/NewAmendmentModal.vue","./src/components/modals/ProposalWizardModal.vue","./src/components/modals/RegistrationModal.vue","./src/components/wizard/ListInput.vue","./src/components/wizard/WizardBasicsStep.vue","./src/components/wizard/WizardDecisionStep.vue","./src/components/wizard/WizardFundingStep.vue","./src/components/wizard/WizardNarrativeStep.vue","./src/components/wizard/WizardPolicyStep.vue","./src/components/wizard/WizardReviewStep.vue","./src/components/wizard/WizardScopeStep.vue","./src/components/wizard/WizardStepper.vue","./src/views/HomeView.vue","./src/views/ProposalView.vue"],"version":"5.9.2"} \ No newline at end of file +{"root":["./src/main.ts","./src/vite-env.d.ts","./src/components/icons/index.ts","./src/components/icons/types.ts","./src/composables/useFilterNotifier.ts","./src/composables/useLoading.ts","./src/composables/useModal.ts","./src/composables/useProposalWizard.ts","./src/composables/useSession.ts","./src/generated/typescript/index.ts","./src/generated/typescript/core/ApiError.ts","./src/generated/typescript/core/ApiRequestOptions.ts","./src/generated/typescript/core/ApiResult.ts","./src/generated/typescript/core/CancelablePromise.ts","./src/generated/typescript/core/OpenAPI.ts","./src/generated/typescript/core/request.ts","./src/generated/typescript/models/AddAmendmentRequest.ts","./src/generated/typescript/models/AddCommentRequest.ts","./src/generated/typescript/models/AddProposalRequest.ts","./src/generated/typescript/models/Amendment.ts","./src/generated/typescript/models/AmendmentParagraph.ts","./src/generated/typescript/models/AmendmentStatus.ts","./src/generated/typescript/models/AmendmentVote.ts","./src/generated/typescript/models/AmendmentWithParagraphs.ts","./src/generated/typescript/models/AmendmentWithSummary.ts","./src/generated/typescript/models/Claims.ts","./src/generated/typescript/models/CommentReaction.ts","./src/generated/typescript/models/CommentReactionSummary.ts","./src/generated/typescript/models/CommentTargetType.ts","./src/generated/typescript/models/CommentWithUser.ts","./src/generated/typescript/models/EditProposalRequest.ts","./src/generated/typescript/models/FreighterLoginRequest.ts","./src/generated/typescript/models/FreighterLoginResponse.ts","./src/generated/typescript/models/FundingTypeData.ts","./src/generated/typescript/models/ListCommentsResponse.ts","./src/generated/typescript/models/LoginRequest.ts","./src/generated/typescript/models/MoneyAmount.ts","./src/generated/typescript/models/Organization.ts","./src/generated/typescript/models/PolicyTypeData.ts","./src/generated/typescript/models/Proposal.ts","./src/generated/typescript/models/ProposalCommonData.ts","./src/generated/typescript/models/ProposalEvent.ts","./src/generated/typescript/models/ProposalEventType.ts","./src/generated/typescript/models/ProposalMilestone.ts","./src/generated/typescript/models/ProposalParagraph.ts","./src/generated/typescript/models/ProposalParagraphRequest.ts","./src/generated/typescript/models/ProposalRevision.ts","./src/generated/typescript/models/ProposalRevisionBlock.ts","./src/generated/typescript/models/ProposalRevisionStatus.ts","./src/generated/typescript/models/ProposalRisk.ts","./src/generated/typescript/models/ProposalScope.ts","./src/generated/typescript/models/ProposalSponsor.ts","./src/generated/typescript/models/ProposalState.ts","./src/generated/typescript/models/ProposalVote.ts","./src/generated/typescript/models/ProposalWithParagraphs.ts","./src/generated/typescript/models/ProposalWithSummary.ts","./src/generated/typescript/models/ReactCommentRequest.ts","./src/generated/typescript/models/ReactCommentResponse.ts","./src/generated/typescript/models/ReactionType.ts","./src/generated/typescript/models/RegisterOrganizationRequest.ts","./src/generated/typescript/models/RegisterRequest.ts","./src/generated/typescript/models/RegisteredUser.ts","./src/generated/typescript/models/SelectableAmendment.ts","./src/generated/typescript/models/SelectableComment.ts","./src/generated/typescript/models/SelectableProposal.ts","./src/generated/typescript/models/SetProposalRevisionRequest.ts","./src/generated/typescript/models/SponsorProposalRequest.ts","./src/generated/typescript/models/UserAmendmentVote.ts","./src/generated/typescript/models/UserProposalVotes.ts","./src/generated/typescript/models/VoteAmendmentRequest.ts","./src/generated/typescript/models/VoteAmendmentResponse.ts","./src/generated/typescript/models/VoteChoice.ts","./src/generated/typescript/models/VoteProposalRequest.ts","./src/generated/typescript/schemas/$AddProposalRequest.ts","./src/generated/typescript/schemas/$FreighterLoginRequest.ts","./src/generated/typescript/schemas/$ListProposalsResponse.ts","./src/generated/typescript/schemas/$LoginRequest.ts","./src/generated/typescript/schemas/$ProposalItem.ts","./src/generated/typescript/schemas/$ProposalList.ts","./src/generated/typescript/schemas/$RegisterRequest.ts","./src/generated/typescript/schemas/$VisitProposalRequest.ts","./src/generated/typescript/services/AmendmentService.ts","./src/generated/typescript/services/AuthService.ts","./src/generated/typescript/services/CommentService.ts","./src/generated/typescript/services/OrganizationService.ts","./src/generated/typescript/services/ProposalService.ts","./src/router/index.ts","./src/stores/filterStore.ts","./src/types/color.ts","./src/types/comment.ts","./src/types/dropdown.ts","./src/types/headerletter.ts","./src/types/proposal.ts","./src/types/proposalWizard.ts","./src/types/user.ts","./src/types/vote.ts","./src/utils/amendment.ts","./src/utils/auth.ts","./src/utils/comments.ts","./src/utils/eventBus.ts","./src/utils/markdown.ts","./src/utils/proposalExport.ts","./src/utils/wallet.ts","./src/App.vue","./src/components/AmendmentCarousel.vue","./src/components/BrandBar.vue","./src/components/Chip.vue","./src/components/ColoredHeader.vue","./src/components/CommentThread.vue","./src/components/Dropdown.vue","./src/components/LoadingSpinner.vue","./src/components/PostBuilder.vue","./src/components/ProposalContainer.vue","./src/components/ProposalDetail.vue","./src/components/ProposalEmptyState.vue","./src/components/ProposalExportCard.vue","./src/components/ProposalRevisionDropdown.vue","./src/components/ProposalSection.vue","./src/components/ProposalSponsorCard.vue","./src/components/ProposalStructuredSections.vue","./src/components/ProposalVotingCard.vue","./src/components/Sidebar.vue","./src/components/Thread.vue","./src/components/icons/Abstain.vue","./src/components/icons/AppIcon.vue","./src/components/icons/Arrow.vue","./src/components/icons/Cancel.vue","./src/components/icons/Confirm.vue","./src/components/icons/DownArrow.vue","./src/components/icons/Download.vue","./src/components/icons/Filter.vue","./src/components/icons/IconBase.vue","./src/components/icons/Identification.vue","./src/components/icons/Menu.vue","./src/components/icons/Plus.vue","./src/components/icons/SpeechBubbles.vue","./src/components/icons/Stack.vue","./src/components/icons/ThumbsDown.vue","./src/components/icons/ThumbsUp.vue","./src/components/modals/AmendmentModal.vue","./src/components/modals/EditProposalModal.vue","./src/components/modals/FilterModal.vue","./src/components/modals/Modal.vue","./src/components/modals/NewAmendmentModal.vue","./src/components/modals/ProposalWizardModal.vue","./src/components/modals/RegistrationModal.vue","./src/components/wizard/ListInput.vue","./src/components/wizard/WizardBasicsStep.vue","./src/components/wizard/WizardDecisionStep.vue","./src/components/wizard/WizardFundingStep.vue","./src/components/wizard/WizardNarrativeStep.vue","./src/components/wizard/WizardPolicyStep.vue","./src/components/wizard/WizardReviewStep.vue","./src/components/wizard/WizardScopeStep.vue","./src/components/wizard/WizardStepper.vue","./src/views/HomeView.vue","./src/views/ProposalView.vue"],"version":"5.9.2"} \ No newline at end of file