Skip to content

chore: epic comment add action rework#113

Merged
hmbanan666 merged 1 commit into
mainfrom
epic-comment
Aug 29, 2025
Merged

chore: epic comment add action rework#113
hmbanan666 merged 1 commit into
mainfrom
epic-comment

Conversation

@hmbanan666
Copy link
Copy Markdown
Collaborator

@hmbanan666 hmbanan666 commented Aug 29, 2025

Summary by CodeRabbit

  • New Features
    • Epic comments are now created via a modal with a dedicated form; successful submission closes the modal.
  • Bug Fixes
    • Comment text is trimmed on submit to prevent whitespace-only entries.
  • Refactor
    • Cards are now native buttons for improved focus and keyboard interaction.
    • Inline epic comment form on the epic page replaced with a modal flow.
  • Style
    • Section layout updated with relative positioning.
  • Chores
    • Added Russian translations for epic comment creation (button and title).

@hmbanan666 hmbanan666 self-assigned this Aug 29, 2025
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Aug 29, 2025

Walkthrough

Shifts epic comment creation to a modal-driven UForm workflow with validation. Updates page to open a modal, adds a new modal component, refactors the form, trims text on the server, removes store.addComment, and applies small UI/semantic tweaks (button card, relative section). Adds ru-RU translations.

Changes

Cohort / File(s) Summary
UI semantics/behavior tweaks
apps/atrium-telegram/app/components/ActiveCard.vue, apps/atrium-telegram/app/components/Section.vue
ActiveCard root changed from div to button with accessibility/interaction classes; retains click vibration. Section root gains relative class to establish positioning context.
Form refactor to validated UForm
apps/atrium-telegram/app/components/form/CreateEpicComment.vue
Replaces manual form with UForm + schema validator. Uses centralized state, emits submitted and success, posts to API with Authorization, updates stores, triggers feedback, and simplifies UI to a submit button. Adds epicId prop.
New modal component for comment creation
apps/atrium-telegram/app/components/modal/CreateEpicComment.vue
Introduces CreateEpicComment modal. Renders UModal with localized title, embeds FormCreateEpicComment, closes overlays on @submitted/@success. Accepts epicId prop.
Page workflow change to modal
apps/atrium-telegram/app/pages/epic/[epicId]/index.vue
Replaces inline form with CreateCard that opens ModalCreateEpicComment via overlay. Imports modal component and instantiates with overlay.create(...).
Store API contraction
apps/atrium-telegram/app/stores/epic.ts
Removes addComment method from store and from returned API; update and removeComment unchanged.
i18n additions
apps/atrium-telegram/i18n/locales/ru-RU.json
Adds app.create.epic-comment.{button,title} keys for Russian locale.
Server-side input handling
apps/atrium-telegram/server/api/epic/id/[epicId]/comment.post.ts
Sends text: data.text.trim() explicitly to createComment; drops extra fields and ensures trimmed text.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor U as User
  participant P as Epic Page
  participant O as Overlay Controller
  participant M as ModalCreateEpicComment
  participant F as FormCreateEpicComment
  participant S as Server API (/api/epic/id/:id/comment)
  participant ES as Epic Store
  participant US as User Store

  U->>P: Click "Create comment" card
  P->>O: overlay.create(ModalCreateEpicComment)
  P->>M: Open with { epicId }
  M->>F: Render form (UForm + validator)
  U->>F: Enter text + Submit
  F->>S: POST { epicId, text } with Authorization
  S-->>F: 200 OK (created)
  F->>ES: update()
  F->>US: update()
  F-->>M: emit submitted
  F-->>M: emit success
  M->>O: closeAll()
  O-->>U: Modal closes

  alt Error
    S-->>F: 4xx/5xx
    F-->>U: Feedback error vibration
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • chore: visual rework #112 — Also modifies apps/atrium-telegram/app/components/ActiveCard.vue, overlapping on interaction/visual behavior.
  • chore: feedback rework #99 — Relates to haptic feedback changes; this PR triggers vibrate() on interactions consistent with that update.

Poem

A tap, a modal, a comment takes flight,
I thump my paws—submit feels right.
Trimmed words hop neat to server glen,
Stores refresh; all’s crisp again.
В тишине UI, I twitch with delight—
New flows, soft glow, in moonlit byte. 🐇✨

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch epic-comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbit in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbit in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbit gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbit read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbit help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbit ignore or @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbit summary or @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbit or @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@sonarqubecloud
Copy link
Copy Markdown

@hmbanan666 hmbanan666 merged commit d961aac into main Aug 29, 2025
7 of 8 checks passed
@hmbanan666 hmbanan666 deleted the epic-comment branch August 29, 2025 14:20
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

🧹 Nitpick comments (2)
apps/atrium-telegram/app/pages/epic/[epicId]/index.vue (1)

26-29: Two nits: redundant check and Cyrillic letter typo.

  • length >= 0 is always true; use > 0 or drop the v-if.
  • Replace "комментарий" with "комментарий" (proper "й").

Apply this diff:

-      <div v-if="epic?.comments && epic?.comments.length >= 0" class="flex flex-row items-center gap-2">
+      <div v-if="epic?.comments && epic?.comments.length > 0" class="flex flex-row items-center gap-2">
         <UIcon name="i-lucide-message-circle" class="size-5" />
-        {{ epic.comments.length }} {{ pluralizationRu(epic.comments.length, ['комментарий', 'комментария', 'комментариев']) }}
+        {{ epic.comments.length }} {{ pluralizationRu(epic.comments.length, ['комментарий', 'комментария', 'комментариев']) }}
       </div>
apps/atrium-telegram/app/components/form/CreateEpicComment.vue (1)

18-28: Disable submit on whitespace-only input.

Current check !state.text enables the button for " ". Use a trimmed check to align with server-side guard.

Apply this diff:

-      :disabled="!state.text"
+      :disabled="!(state.text && state.text.trim().length > 0)"
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 7454424 and dc5598f.

📒 Files selected for processing (8)
  • apps/atrium-telegram/app/components/ActiveCard.vue (1 hunks)
  • apps/atrium-telegram/app/components/Section.vue (1 hunks)
  • apps/atrium-telegram/app/components/form/CreateEpicComment.vue (1 hunks)
  • apps/atrium-telegram/app/components/modal/CreateEpicComment.vue (1 hunks)
  • apps/atrium-telegram/app/pages/epic/[epicId]/index.vue (2 hunks)
  • apps/atrium-telegram/app/stores/epic.ts (0 hunks)
  • apps/atrium-telegram/i18n/locales/ru-RU.json (1 hunks)
  • apps/atrium-telegram/server/api/epic/id/[epicId]/comment.post.ts (1 hunks)
💤 Files with no reviewable changes (1)
  • apps/atrium-telegram/app/stores/epic.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build
🔇 Additional comments (4)
apps/atrium-telegram/app/components/Section.vue (1)

2-2: Confirm positioning context change is intended

Making Section’s root relative means absolutely positioned children will anchor to Section (not the outer card). Verify this won’t shift overlays/badges now that ActiveCard’s wrapper is also relative.

apps/atrium-telegram/app/components/ActiveCard.vue (1)

2-6: ActiveCard usage audit: no nested interactive controls detected
Repository-wide search confirmed no <ActiveCard> instances wrap <button>, <a>, <input>, <select>, or <textarea>, nor appear inside <form> elements.

apps/atrium-telegram/server/api/epic/id/[epicId]/comment.post.ts (1)

23-24: Assert authenticated user exists (defensive).

This assumes event.context.user.id is always set. If a route-level guard isn’t guaranteed, add an explicit 401 or assert here.

Would you confirm this endpoint is behind auth middleware that always populates event.context.user?

apps/atrium-telegram/app/pages/epic/[epicId]/index.vue (1)

41-46: LGTM: Modal trigger wiring looks correct.

overlay.create(ModalCreateEpicComment) + .open({ epicId }) is consistent with the new flow.

@@ -1,9 +1,9 @@
<template>
<div class="relative active:scale-95 duration-200" @click="vibrate()">
<button class="relative w-full active:scale-95 duration-200 text-left cursor-pointer outline-0" @click="vibrate()">
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Add type="button" to prevent unintended form submissions

Without an explicit type, buttons default to submit inside forms.

Apply this diff:

-  <button class="relative w-full active:scale-95 duration-200 text-left cursor-pointer outline-0" @click="vibrate()">
+  <button type="button" class="relative w-full active:scale-95 duration-200 text-left cursor-pointer outline-0" @click="vibrate()">
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<button class="relative w-full active:scale-95 duration-200 text-left cursor-pointer outline-0" @click="vibrate()">
<button type="button" class="relative w-full active:scale-95 duration-200 text-left cursor-pointer outline-0" @click="vibrate()">
🤖 Prompt for AI Agents
In apps/atrium-telegram/app/components/ActiveCard.vue around line 2, the button
lacks an explicit type so it will default to "submit" when placed inside a form;
update the button element to include type="button" to prevent unintended form
submissions while preserving existing classes and the @click handler.

🛠️ Refactor suggestion

Restore visible focus styles; replace outline-0 with a custom focus-visible ring (and smooth the scale animation)

outline-0 removes the default focus indicator; add an explicit focus style. Also add transition-transform so active:scale-95 animates.

Apply this diff:

-  <button type="button" class="relative w-full active:scale-95 duration-200 text-left cursor-pointer outline-0" @click="vibrate()">
+  <button type="button" class="relative w-full active:scale-95 transition-transform duration-200 text-left focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-indigo-500" @click="vibrate()">

If you have design tokens (e.g., tg- colors), swap indigo-500/offsets accordingly.

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In apps/atrium-telegram/app/components/ActiveCard.vue around line 2, the button
currently removes the browser focus indicator with outline-0 and lacks a
transform transition; restore an accessible visible focus style and smooth the
active scale by replacing outline-0 with a focus-visible ring class (e.g.,
focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-indigo-500
focus-visible:ring-offset-white or the equivalent tg- token colors) and add
transition-transform to the class list so active:scale-95 animates smoothly;
ensure ring-offset color matches the component background and adjust token names
to your design system if present.

Comment on lines +2 to +4
<UForm
:validate="createValidator(createEpicCommentSchema)"
:state="state"
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Missing/implicit createValidator import — verify auto-import.

createValidator is used but not imported; unless auto-imported, this will throw at runtime.

Run to locate its definition and usages:

If not auto-imported, add the proper import path used elsewhere in the project.


🏁 Script executed:

#!/bin/bash
# Find a definition/export of createValidator
rg -nP 'export\s+(?:const|function)\s+createValidator\b|createValidator:\s*' -C2
# Check for a Nuxt auto-import declaration
rg -nP 'autoImports|imports:\s*\{[^}]*imports' -g '!**/node_modules/**' -C3
# Where else is it used (to infer import style)
rg -nP '\bcreateValidator\s*\(' -g '!**/node_modules/**' -C2

Length of output: 19492


Add missing createValidator import
In apps/atrium-telegram/app/components/form/CreateEpicComment.vue’s <script setup> block, add:

import { createValidator } from '~/utils/ui'

createValidator is exported from app/utils/ui.ts and must be imported here to avoid a runtime error.

🤖 Prompt for AI Agents
In apps/atrium-telegram/app/components/form/CreateEpicComment.vue around lines 2
to 4, the template uses createValidator(createEpicCommentSchema) but the
createValidator function is not imported; add an import statement in the <script
setup> block: import { createValidator } from '~/utils/ui' so the component can
call createValidator at runtime without error.

Comment on lines +4 to +8
<FormCreateEpicComment
:epic-id="epicId"
@submitted="overlay.closeAll"
@success="overlay.closeAll"
/>
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Don’t close the modal on submit start; close only on success.

Closing on @submitted hides errors and prevents retry UX.

Apply this diff:

       <FormCreateEpicComment
         :epic-id="epicId"
-        @submitted="overlay.closeAll"
         @success="overlay.closeAll"
       />
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<FormCreateEpicComment
:epic-id="epicId"
@submitted="overlay.closeAll"
@success="overlay.closeAll"
/>
<FormCreateEpicComment
:epic-id="epicId"
@success="overlay.closeAll"
/>
🤖 Prompt for AI Agents
In apps/atrium-telegram/app/components/modal/CreateEpicComment.vue around lines
4 to 8, the modal is being closed on the `@submitted` event which hides
validation/errors and blocks retry; remove the `@submitted="overlay.closeAll"`
binding and only call `overlay.closeAll` on the `@success` event so the modal
stays open while submission is in progress or failed and only closes after a
confirmed success.

Comment on lines +43 to +46
"epic-comment": {
"button": "Создать комментарий",
"title": "Создание комментария"
},
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix Cyrillic letter in “комментарий” (combining mark currently used).

The button label uses "комментарий" (и + combining breve). Replace with the correct single character "й".

Apply this diff:

       "epic-comment": {
-        "button": "Создать комментарий",
+        "button": "Создать комментарий",
         "title": "Создание комментария"
       },
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"epic-comment": {
"button": "Создать комментарий",
"title": "Создание комментария"
},
"epic-comment": {
"button": "Создать комментарий",
"title": "Создание комментария"
},
🤖 Prompt for AI Agents
In apps/atrium-telegram/i18n/locales/ru-RU.json around lines 43-46, the button
label uses a Cyrillic "и" followed by a combining breve (resulting in
"комментарий"); replace that sequence with the single precomposed Cyrillic
character "й" so the string becomes "Создать комментарий". Ensure the file is
saved with UTF-8 encoding and no combining marks remain in the value.

Comment on lines 21 to 25
const comment = await repository.epic.createComment({
...data,
text: data.text.trim(),
userId: event.context.user.id,
epicId,
})
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Prevent whitespace-only comments (trim happens after validation).

If the schema allows a single character, strings like " " will pass validation and be saved as empty after trim. Trim first and reject empty.

Apply this diff:

-    const comment = await repository.epic.createComment({
-      text: data.text.trim(),
-      userId: event.context.user.id,
-      epicId,
-    })
+    const text = data.text.trim()
+    if (!text) {
+      throw createError({ statusCode: 400, message: 'Text is required' })
+    }
+    const comment = await repository.epic.createComment({
+      text,
+      userId: event.context.user.id,
+      epicId,
+    })
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const comment = await repository.epic.createComment({
...data,
text: data.text.trim(),
userId: event.context.user.id,
epicId,
})
// Trim input and reject empty text before creation
const text = data.text.trim()
if (!text) {
throw createError({ statusCode: 400, message: 'Text is required' })
}
const comment = await repository.epic.createComment({
text,
userId: event.context.user.id,
epicId,
})
🤖 Prompt for AI Agents
In apps/atrium-telegram/server/api/epic/id/[epicId]/comment.post.ts around lines
21-25, the code trims the comment text only when creating the record which
allows whitespace-only strings to pass earlier validation; change the flow to
trim data.text immediately (e.g., const text = (data.text || "").trim()),
validate that text is non-empty and reject with a 4xx error if empty, then pass
the trimmed text into repository.epic.createComment so only non-empty, trimmed
comments are persisted.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant