The frontend component of PuffPastry, meant to interface with the backend, which in turn interfaces with the smart contract.
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. ---
  2. sessionId: session-261005-172001-12ux
  3. ---
  4. # Requirements
  5. ### Overview & Goals
  6. The objective is to maximize user engagement and utility by introducing an inline "Add Comment" area within `ProposalDetail.vue`. By enabling direct inline commenting without modal disruptions, users can effortlessly discuss and provide feedback on governance proposals, reducing interaction friction and streamlining the feedback loop.
  7. ### Scope
  8. - **In Scope**:
  9. - Embedding an inline comment input area (textarea and action controls) directly inside the Comments section of `src/components/ProposalDetail.vue`.
  10. - Integrating `CommentService.addComment` from `src/generated/typescript/services/CommentService.ts` to submit comments.
  11. - Form validation (preventing empty/whitespace submissions) and loading/error states.
  12. - Refreshing or updating the comment stream upon successful submission.
  13. - Accessible styling consistent with Tailwind CSS guidelines and the existing proposal layout.
  14. - **Out of Scope**:
  15. - Modal-based comment workflows (explicitly avoided per task specification).
  16. - Editing, deleting, or nesting/threading multi-level comments in this phase.
  17. - Backend schema or API endpoint modifications.
  18. ### User Stories
  19. - **As a stakeholder**, I want to post feedback directly beneath a proposal so that I can contribute to the discussion with minimal friction and no context-switching modals.
  20. - **As a user**, I want visual feedback while my comment is being submitted (e.g., loading state, error alert on failure) so that I know the exact status of my action.
  21. - **As a keyboard user**, I want full keyboard accessibility (tab navigation, clear focus states) so that I can participate efficiently without relying solely on mouse input.
  22. ### Functional Requirements
  23. - **Inline Input Form**:
  24. - A clean, expandable textarea with placeholder text (e.g., "Add to the discussion...") rendered directly within the `<section aria-labelledby="comments-heading">` block.
  25. - An "Add Comment" (or "Post Comment") submit button and optional "Cancel" / "Clear" button.
  26. - **Validation & Form State**:
  27. - Disable the submit button when the textarea is empty, whitespace-only, or while a submission is in flight.
  28. - Display clear error messaging if the network or API call fails.
  29. - **API Dispatch**:
  30. - Construct an `AddCommentRequest` with `proposalId`, `content`, and active/fallback `userId`.
  31. - Invoke `CommentService.addComment(requestBody)`.
  32. - On success, reset the input field and update the comment list so the new comment appears immediately.
  33. ### Non-Functional Requirements
  34. - **Usability & Utility**: Minimal layout shift; smooth transition between idle, submitting, and submitted states.
  35. - **Design Consistency**: Match the Tailwind CSS design language (slate borders, amber accents, clear typography) of `ProposalDetail.vue` and `NewAmendmentModal.vue`.
  36. - **Accessibility**: Semantic HTML `<form>`, `<textarea>`, `<button>`, `<label>` with associated ARIA attributes for screen readers.
  37. # Technical Design
  38. ### Current Implementation
  39. - `src/components/ProposalDetail.vue`: Renders proposal details, amendments via `AmendmentCarousel.vue`, and voting cards. The comments section currently contains static markup with a hidden placeholder (`v-if="false"`).
  40. - `src/generated/typescript/services/CommentService.ts`: Exports `CommentService` with:
  41. - `addComment(requestBody: AddCommentRequest): CancelablePromise<SelectableComment>` (`POST /api/v1/comment/add`)
  42. - `listComments(proposalId: number): CancelablePromise<Array<CommentWithUser>>` (`GET /api/v1/comments/list`)
  43. - `src/generated/typescript/models/AddCommentRequest.ts`: Defines `{ content: string; proposalId: number; userId: number; }`.
  44. - `src/generated/typescript/models/CommentWithUser.ts`: Defines comment shape with author metadata (`id`, `content`, `createdAt`, `username`, `fullName`, `userId`, `proposalId`).
  45. ### Key Decisions
  46. 1. **Inline Placement in ProposalDetail.vue**:
  47. - *Approach*: Integrate the comment box directly below the comments header in `ProposalDetail.vue` instead of launching a modal.
  48. - *Rationale*: Maximizes utility and minimizes UX friction by keeping the proposal text in view while writing feedback.
  49. 2. **Dynamic Comments Fetch & Immediate Refresh**:
  50. - *Approach*: Load comments for `proposal.id` via `CommentService.listComments` and refresh/append on new comment creation.
  51. - *Rationale*: Provides immediate confirmation to the user that their contribution was recorded without necessitating a full page reload.
  52. 3. **Robust Input Validation & Loading States**:
  53. - *Approach*: Use reactive refs (`commentText`, `isSubmitting`, `errorMessage`) to gate form submission and provide actionable feedback.
  54. - *Rationale*: Prevents accidental duplicate requests and ensures users are informed of network or validation issues.
  55. ### Proposed Changes
  56. - **`src/components/ProposalDetail.vue`**:
  57. - Import `CommentService`, `AddCommentRequest`, and `CommentWithUser` from `../generated/typescript`.
  58. - Add reactive state: `newComment`, `isSubmitting`, `submitError`, `comments`, and `loadingComments`.
  59. - Implement `fetchComments(proposalId)` on `onMounted` and on `watch(proposalId)`.
  60. - Implement `handleAddComment()` to call `CommentService.addComment` and reset the form.
  61. - Replace placeholder section with the inline comment submission form and existing comments list.
  62. ### Data Models / Contracts
  63. ```typescript
  64. // Payload sent to CommentService.addComment
  65. const requestBody: AddCommentRequest = {
  66. proposalId: props.proposal.id,
  67. content: commentText.value.trim(),
  68. userId: activeUserId ?? 1, // Fallback/resolved user ID
  69. };
  70. ```
  71. ### Architecture Diagram
  72. ```mermaid
  73. graph TD
  74. User[User] -->|Types comment & clicks Submit| CommentForm[Inline Comment Area in ProposalDetail]
  75. CommentForm -->|addComment| CommentService[CommentService.addComment]
  76. CommentService -->|POST /api/v1/comment/add| BackendAPI[Backend API]
  77. BackendAPI -->|SelectableComment| CommentService
  78. CommentService -->|Success / New Comment| StateUpdate[Update Local Comments State & Reset Form]
  79. StateUpdate -->|Re-render| UI[Updated Discussion Stream]
  80. ```
  81. ### File Structure
  82. - `src/components/ProposalDetail.vue` (Modified): Inline form, reactive state, and `CommentService` integration.
  83. - `src/generated/typescript/services/CommentService.ts` (Referenced): Backend API client for comment actions.
  84. ### Risks & Mitigations
  85. - **Network Failure or 400/500 Errors**: Capture API errors in a dedicated `errorMessage` ref and display an inline alert without losing user input.
  86. - **Double Submissions**: Disable the submit button immediately when `isSubmitting` is true.
  87. # Testing
  88. ### Validation Approach
  89. Verification focuses on maximizing automated and interactive confidence across normal, boundary, and error conditions.
  90. ### Key Scenarios
  91. 1. **Inline Form Rendering**:
  92. - Verify textarea and "Add Comment" button render cleanly within the comments section of `ProposalDetail.vue`.
  93. - Verify placeholder text and accessible labels are present.
  94. 2. **Comment Submission Flow**:
  95. - Enter valid comment text and submit.
  96. - Verify `CommentService.addComment` is invoked with `{ proposalId, content, userId }`.
  97. - Verify textarea is cleared upon successful submission and the discussion stream updates.
  98. 3. **Empty Input Prevention**:
  99. - Ensure the submit button is disabled when the textarea is empty or contains only whitespace.
  100. 4. **Loading & Disabled States**:
  101. - Verify the submit button reflects pending state and prevents concurrent submissions.
  102. ### Edge Cases
  103. - **API Error / Server Failure**: Verify that error messages are displayed prominently inline without clearing the user's drafted text.
  104. - **Proposal ID Changes**: Verify comments state is reset and re-fetched when switching between proposals.
  105. - **Special Characters & Multiline Text**: Verify formatting and line breaks in comments are preserved.
  106. # Delivery Steps
  107. ### ✓ Step 1: Create inline comment form UI and state management
  108. Build the inline comment form UI within the Comments section of `ProposalDetail.vue`.
  109. - Add reactive state variables for comment content (`commentText`), submission loading state (`isSubmitting`), error messages (`commentError`), and comments list (`comments`, `isLoadingComments`).
  110. - Insert an inline form in the comments section with a styled `<textarea>` input, accessible labels, character/input guidance, and action controls (submit and cancel/reset buttons).
  111. - Implement input validation so that empty or whitespace-only submissions are disabled.
  112. - Add comment list rendering within the comments section using `CommentService.listComments(proposal.id)` on mount and when proposal changes, providing immediate visual feedback for existing discussions.
  113. ### ✓ Step 2: Integrate CommentService API submission and discussion refresh
  114. Connect the inline form to `CommentService.addComment` to persist user comments and refresh the discussion stream.
  115. - Implement the `submitComment` async handler calling `CommentService.addComment({ proposalId: proposal.id, content: commentText.value.trim(), userId })`.
  116. - Include robust error handling to display user-friendly inline error alerts if the API request fails.
  117. - Clear the input textarea upon successful comment submission.
  118. - Re-fetch or append the new comment into the local comments list so users immediately see their contribution without a full page reload.
  119. - Verify type checks and build via `vue-tsc -b` to guarantee seamless integration and zero regressions.