Skip to content

Feat/issue overview#58

Merged
Flo0806 merged 8 commits intomainfrom
feat/issue-overview
Feb 13, 2026
Merged

Feat/issue overview#58
Flo0806 merged 8 commits intomainfrom
feat/issue-overview

Conversation

@Flo0806
Copy link
Contributor

@Flo0806 Flo0806 commented Feb 12, 2026

Summary

  • add issue overview page with filters, prio and list

Related issue(s)

Closes #53

Type of change

  • Bug fix
  • Feature
  • Refactor
  • Docs
  • CI

Checklist

  • Tests added/updated
  • i18n keys added/updated (if needed)
  • No breaking changes

Summary by CodeRabbit

  • New Features

    • Complete issues dashboard: repo selector, state tabs, toolbar (search, filter chips, sort) and issue list rows with labels, counts, state, milestone and assignees
    • Persistent repository preference and repo popover with open issue/PR counts and no-results handling
    • Multiple sort options including critical priority; rich filtering (unassigned, has/no PR, milestone, labels)
  • Localization

    • Added English and German translations and detailed error/loading messages for the issues UI
  • Tests

    • Added unit and integration tests for issue handling and store behavior

@vercel
Copy link

vercel bot commented Feb 12, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
flumen.dev Ready Ready Preview, Comment Feb 13, 2026 2:20pm

Request Review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 12, 2026

📝 Walkthrough

Walkthrough

Adds a full issues dashboard: Vue 3 components (repo selector, toolbar, issue row, page), a Pinia issue store with filtering/sorting and critical scoring, a server API endpoint that paginates GitHub GraphQL results with caching, shared types/utils for issue mapping, i18n entries/schema, and tests.

Changes

Cohort / File(s) Summary
Vue UI
app/components/issue/IssueRepoSelect.vue, app/components/issue/IssueRow.vue, app/components/issue/IssueToolbar.vue, app/pages/issues/index.vue
New Vue 3 + TypeScript components: repo selector (with counts and persistence), issue row (labels, avatars, meta, state icons), toolbar (search, filter chips, sort), and main issues page (tabs, loading/error/empty states).
Client store
app/stores/issues.ts
New Pinia store useIssueStore: state, filters, search, sort (includes critical score), computed selectors (availableLabels, filteredIssues), actions (fetchIssues/selectRepo/refresh), and error-key mapping.
Server API
server/api/issues/index.get.ts
New GET handler that validates repo, queries GitHub GraphQL (paginated, up to 5 pages ×100), maps nodes via toIssue, and caches results (60s) using a cached function wrapper.
Shared types & utils
shared/types/issue.ts, shared/utils/issue.ts, shared/types/settings.ts
Adds Issue, GraphQLIssueNode, GraphQLIssueSearchResult types; toIssue mapper utility; and selectedRepo field on UserSettings with default null.
i18n
i18n/locales/en.json, i18n/locales/de.json, i18n/schema.json
Adds top-level issues localization keys and schema entries: statuses, repo selector text, counts, filters, sort labels, and structured error messages.
Tests
test/nuxt/issueStore.test.ts, test/unit/issue.test.ts
Integration tests for store behaviors (selection, caching, filters, sorts, label extraction) and unit tests for toIssue mapping (author/milestone handling, counts, maintainer flag).

Sequence Diagram

sequenceDiagram
    participant User as User
    participant UI as Issues Page (Vue)
    participant Store as Issue Store (Pinia)
    participant API as Server API (/api/issues)
    participant GH as GitHub GraphQL

    User->>UI: open issues page / interact
    UI->>Store: selectRepo(repoName)
    alt repo not loaded/cached
        Store->>API: GET /api/issues?state=open&repo=repoName
        API->>GH: GraphQL ISSUES_QUERY (paginated)
        GH-->>API: issue pages (nodes)
        API->>API: toIssue(node) -> Issue[]
        API-->>Store: Issue[] (cached)
    end
    Store->>Store: compute filteredIssues (search, filters, sort)
    Store-->>UI: filteredIssues
    UI->>Store: update filters/sort/search
    Store->>Store: recompute filteredIssues
    Store-->>UI: updated list
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Suggested reviewers

  • Gonzo17

Poem

🐰 I nibble through the diff with delight,
New selectors, rows, and filters in sight,
GraphQL carrots, cached for a bite,
Issues hop tidy, sorted just right,
A rabbit applauds the dashboard's bright light.

🚥 Pre-merge checks | ✅ 4 | ❌ 2
❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 42.86% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Merge Conflict Detection ⚠️ Warning ❌ Merge conflicts detected (8 files):

⚔️ app/pages/user/[id].vue (content)
⚔️ app/stores/profile.ts (content)
⚔️ i18n/locales/de.json (content)
⚔️ i18n/locales/en.json (content)
⚔️ i18n/schema.json (content)
⚔️ shared/types/settings.ts (content)
⚔️ test/integration/apiAuth.test.ts (content)
⚔️ test/nuxt/profileStore.test.ts (content)

These conflicts must be resolved before merging into main.
Resolve conflicts locally and push changes to this branch.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Feat/issue overview' clearly summarizes the main change: introducing a new issue overview feature with filtering and prioritization.
Description check ✅ Passed The PR description follows the template with summary, related issue, type of change marked, and checklist items completed (tests and i18n updated).
Linked Issues check ✅ Passed The PR implements all core requirements from issue #53: issue list with title, number, repo name, labels, author/assignee avatars, comment counts, linked PR counts, time info, state icons, filtering (repo, state, assignment, labels, search), sorting (newest, oldest, most commented, most linked PRs, and priority-based critical sort), and responsive list layout.
Out of Scope Changes check ✅ Passed All changes directly support the issue overview feature: UI components (IssueRow, IssueToolbar, IssueRepoSelect), pages (issues/index), store logic (filtering, sorting, search), types, utilities, tests, and i18n translations are all in scope.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/issue-overview
⚔️ Resolve merge conflicts (beta)
  • Auto-commit resolved conflicts to branch feat/issue-overview
  • Create stacked PR with resolved conflicts
  • Post resolved changes as copyable diffs in a comment

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@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: 5

🤖 Fix all issues with AI agents
In `@app/components/issue/IssueRow.vue`:
- Around line 8-129: The row is missing repository name, author (avatar + name)
and relative created time; add a new computed createdAgo (e.g.
useTimeAgo(computed(() => props.issue.createdAt))) and render the repo name,
author avatar/name and createdAgo in the Row 2 meta next to the existing
number/updated items. Specifically, update IssueRow.vue to: 1) add createdAgo
computed like updatedAgo, 2) render a repository label (e.g. issue.repository or
issue.repoName) before the issue number to disambiguate cross‑repo rows, and 3)
render the author use (issue.author.login and issue.author.avatarUrl) as a small
UAvatar + name and show createdAgo (relative created time) in the meta section;
use the existing UAvatar, UTooltip and UIcon components and the props.issue
fields (createdAt, repository/repoName, author.login, author.avatarUrl) so the
new elements integrate with the current template layout.

In `@app/pages/issues/index.vue`:
- Around line 35-40: The template uses dynamic i18n keys with
t(`issues.error.${store.errorKey}.title`) and
t(`issues.error.${store.errorKey}.description`) which static analyzers can't
validate; replace this with an explicit mapping: create a computed mapping
(e.g., a computed property or helper function like getIssueI18nKeys or
issueI18nMap) that maps each known store.errorKey value ('rateLimited',
'sessionExpired', etc.) to concrete translation keys for title and description,
then pass those concrete keys to UAlert (and keep using store.errorKey for
color/icon logic). This ensures only predefined keys are used and is easily
discovered by static tools while preserving existing behavior.

In `@i18n/locales/de.json`:
- Around line 151-178: Remove or reintroduce the unused German i18n keys to
match the English cleanup: either delete the keys "issues.title",
"issues.comments", and "issues.linkedPrs" from the DE locale or wire them into
the UI the same way the EN locale uses them (ensure the component rendering
issues list looks up issues.title, issues.comments and issues.linkedPrs). Update
any code that references these keys (search for usages of issues.title,
issues.comments, issues.linkedPrs in the issues list / issue components) to
ensure consistency between locales and tests.

In `@i18n/locales/en.json`:
- Around line 151-179: CI reports that the i18n keys issues.title,
issues.comments, and issues.linkedPrs are unused; either wire them into the UI
where the issues list is rendered (use issues.title for the issues header,
issues.comments for comment counts display, and issues.linkedPrs for linked PR
counts in the issue item components) or remove these keys from the locale and
the corresponding schema/translation references (ensure you also remove or
update any references in the issues-related schema/translation lookup code such
as count/label rendering logic to avoid missing-key errors).

In `@shared/utils/issue.ts`:
- Around line 18-20: The maintainerCommented boolean is unreliable because the
GraphQL field comments(first: 100) only returns the first 100 comment nodes;
update the logic that sets maintainerCommented to page through comments (use
comments.pageInfo.hasNextPage and pageInfo.endCursor) or request a larger limit
until you either find a comment by maintainerLogin or exhaust pages. Locate the
object building maintainerCommented in shared/utils/issue.ts and replace the
single-page check (comments.nodes.some(...)) with a loop/function that queries
comments(first, after) repeatedly (or a helper like
fetchCommentsUntilFoundMaintainer) and short-circuits when a maintainer comment
is found, then set maintainerCommented accordingly.
🧹 Nitpick comments (2)
server/api/issues/index.get.ts (1)

27-28: Optimize comments query to reduce payload size.

The query fetches comments(first: 100) { totalCount nodes { author { login } } } but this retrieves up to 100 comment nodes per issue just to check if the maintainer commented. For issues with many comments, this significantly inflates the response payload.

Consider fetching only the first few comments or restructuring the maintainer-check logic server-side if possible.

♻️ Proposed optimization
-        comments(first: 100) { totalCount nodes { author { login } } }
+        comments(first: 20) { totalCount nodes { author { login } } }

Note: This trades completeness (may miss maintainer comments beyond first 20) for performance. Consider if that tradeoff is acceptable for your use case.

app/components/issue/IssueRepoSelect.vue (1)

30-37: Consider adding error handling for initial fetch.

If repoStore.fetchAll() fails, the component continues without handling the error. The user may see an empty state without understanding why.

🛡️ Proposed error handling
 onMounted(async () => {
-  await repoStore.fetchAll()
-  const saved = settings.value?.selectedRepo
-  if (saved && repoStore.repos.some(r => r.fullName === saved)) {
-    await issueStore.selectRepo(saved)
+  try {
+    await repoStore.fetchAll()
+    const saved = settings.value?.selectedRepo
+    if (saved && repoStore.repos.some(r => r.fullName === saved)) {
+      await issueStore.selectRepo(saved)
+    }
+  } catch (err) {
+    // Error should be handled by the parent page or store's error state
+    console.error('Failed to load repositories', err)
   }
 })

Comment on lines +8 to +129
const { t } = useI18n()
const updatedAgo = useTimeAgo(computed(() => props.issue.updatedAt))

const stateIcon = computed(() => {
if (props.issue.state === 'OPEN') return 'i-lucide-circle-dot'
if (props.issue.stateReason === 'NOT_PLANNED') return 'i-lucide-circle-slash'
return 'i-lucide-check-circle'
})

const stateColor = computed(() => {
if (props.issue.state === 'OPEN') return 'text-emerald-500'
if (props.issue.stateReason === 'NOT_PLANNED') return 'text-neutral-400'
return 'text-violet-500'
})
</script>

<template>
<a
:href="issue.url"
target="_blank"
rel="noopener noreferrer"
class="flex items-start gap-3 px-4 py-3 hover:bg-elevated transition-colors"
>
<!-- State icon -->
<UIcon
:name="stateIcon"
class="size-5 mt-0.5 shrink-0"
:class="stateColor"
/>

<!-- Content -->
<div class="min-w-0 flex-1">
<!-- Row 1: Title + labels -->
<div class="flex items-center gap-2 flex-wrap">
<span class="font-medium text-highlighted hover:underline">
{{ issue.title }}
</span>
<UBadge
v-for="label in issue.labels"
:key="label.name"
variant="subtle"
size="xs"
:style="{ backgroundColor: `#${label.color}20`, color: `#${label.color}` }"
>
{{ label.name }}
</UBadge>
</div>

<!-- Row 2: Meta -->
<div class="flex items-center gap-3 mt-1 text-xs text-muted">
<UTooltip
v-if="!issue.maintainerCommented && issue.commentCount > 0"
:text="t('issues.needsResponse')"
>
<span class="inline-flex items-center gap-0.5 text-amber-500">
<UIcon
name="i-lucide-message-circle-warning"
class="size-3.5"
/>
</span>
</UTooltip>
<span>#{{ issue.number }}</span>
<span>{{ updatedAgo }}</span>

<span
v-if="issue.commentCount"
class="inline-flex items-center gap-0.5"
>
<UIcon
name="i-lucide-message-square"
class="size-3.5"
/>
{{ issue.commentCount }}
</span>

<span
v-if="issue.linkedPrCount"
class="inline-flex items-center gap-0.5 text-blue-500"
>
<UIcon
name="i-lucide-git-pull-request"
class="size-3.5"
/>
{{ issue.linkedPrCount }}
</span>

<span
v-if="issue.state === 'CLOSED'"
class="inline-flex items-center gap-0.5"
:class="issue.stateReason === 'NOT_PLANNED' ? 'text-neutral-400' : 'text-violet-500'"
>
{{ issue.stateReason === 'NOT_PLANNED' ? t('issues.closedAsNotPlanned') : t('issues.closedAs') }}
</span>

<span
v-if="issue.milestone"
class="inline-flex items-center gap-0.5"
>
<UIcon
name="i-lucide-milestone"
class="size-3.5"
/>
{{ issue.milestone }}
</span>
</div>
</div>

<!-- Right side: Assignees + author -->
<div class="flex items-center gap-1 shrink-0">
<UTooltip
v-for="assignee in issue.assignees"
:key="assignee.login"
:text="assignee.login"
>
<UAvatar
:src="assignee.avatarUrl"
:alt="assignee.login"
size="xs"
/>
</UTooltip>
</div>
</a>
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Missing required row metadata (repo, author, created time).

PR objectives call for repository name, author avatar/name, and relative created time in each row. Currently only updated time and assignees are rendered, so the overview can’t disambiguate cross‑repo issues or show author/created info.

💡 Minimal sketch of the missing metadata wiring
<script setup lang="ts">
@@
 const { t } = useI18n()
 const updatedAgo = useTimeAgo(computed(() => props.issue.updatedAt))
+const createdAgo = useTimeAgo(computed(() => props.issue.createdAt))
@@
</script>
<!-- Row 2: Meta -->
 <div class="flex items-center gap-3 mt-1 text-xs text-muted">
+  <span class="inline-flex items-center gap-1">
+    <UIcon name="i-lucide-book" class="size-3.5" />
+    {{ issue.repository.nameWithOwner }}
+  </span>
+  <span class="inline-flex items-center gap-1">
+    <UAvatar :src="issue.author.avatarUrl" :alt="issue.author.login" size="xs" />
+    {{ issue.author.login }}
+  </span>
   <span>#{{ issue.number }}</span>
+  <span>{{ createdAgo }}</span>
   <span>{{ updatedAgo }}</span>
   ...
 </div>
🤖 Prompt for AI Agents
In `@app/components/issue/IssueRow.vue` around lines 8 - 129, The row is missing
repository name, author (avatar + name) and relative created time; add a new
computed createdAgo (e.g. useTimeAgo(computed(() => props.issue.createdAt))) and
render the repo name, author avatar/name and createdAgo in the Row 2 meta next
to the existing number/updated items. Specifically, update IssueRow.vue to: 1)
add createdAgo computed like updatedAgo, 2) render a repository label (e.g.
issue.repository or issue.repoName) before the issue number to disambiguate
cross‑repo rows, and 3) render the author use (issue.author.login and
issue.author.avatarUrl) as a small UAvatar + name and show createdAgo (relative
created time) in the meta section; use the existing UAvatar, UTooltip and UIcon
components and the props.issue fields (createdAt, repository/repoName,
author.login, author.avatarUrl) so the new elements integrate with the current
template layout.

Comment on lines +35 to +40
<UAlert
:title="t(`issues.error.${store.errorKey}.title`)"
:description="t(`issues.error.${store.errorKey}.description`)"
:color="store.errorKey === 'rateLimited' ? 'warning' : 'error'"
:icon="store.errorKey === 'sessionExpired' ? 'i-lucide-log-out' : store.errorKey === 'rateLimited' ? 'i-lucide-clock' : 'i-lucide-alert-triangle'"
/>
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Address pipeline warning: dynamic i18n keys may not be statically analyzable.

The pipeline flagged dynamic translation keys. While this works at runtime, static analysis tools can't verify these keys exist. Consider using a type-safe approach or explicitly listing the possible keys.

🔧 Proposed fix using explicit key mapping
+const errorConfig = computed(() => {
+  const configs: Record<string, { title: string; description: string; color: string; icon: string }> = {
+    sessionExpired: {
+      title: t('issues.error.sessionExpired.title'),
+      description: t('issues.error.sessionExpired.description'),
+      color: 'error',
+      icon: 'i-lucide-log-out',
+    },
+    rateLimited: {
+      title: t('issues.error.rateLimited.title'),
+      description: t('issues.error.rateLimited.description'),
+      color: 'warning',
+      icon: 'i-lucide-clock',
+    },
+    fetchError: {
+      title: t('issues.error.fetchError.title'),
+      description: t('issues.error.fetchError.description'),
+      color: 'error',
+      icon: 'i-lucide-alert-triangle',
+    },
+  }
+  return store.errorKey ? configs[store.errorKey] : null
+})

Then update template:

-        <UAlert
-          :title="t(`issues.error.${store.errorKey}.title`)"
-          :description="t(`issues.error.${store.errorKey}.description`)"
-          :color="store.errorKey === 'rateLimited' ? 'warning' : 'error'"
-          :icon="store.errorKey === 'sessionExpired' ? 'i-lucide-log-out' : store.errorKey === 'rateLimited' ? 'i-lucide-clock' : 'i-lucide-alert-triangle'"
-        />
+        <UAlert
+          v-if="errorConfig"
+          :title="errorConfig.title"
+          :description="errorConfig.description"
+          :color="errorConfig.color"
+          :icon="errorConfig.icon"
+        />
🤖 Prompt for AI Agents
In `@app/pages/issues/index.vue` around lines 35 - 40, The template uses dynamic
i18n keys with t(`issues.error.${store.errorKey}.title`) and
t(`issues.error.${store.errorKey}.description`) which static analyzers can't
validate; replace this with an explicit mapping: create a computed mapping
(e.g., a computed property or helper function like getIssueI18nKeys or
issueI18nMap) that maps each known store.errorKey value ('rateLimited',
'sessionExpired', etc.) to concrete translation keys for title and description,
then pass those concrete keys to UAlert (and keep using store.errorKey for
color/icon logic). This ensures only predefined keys are used and is easily
discovered by static tools while preserving existing behavior.

Comment on lines +151 to +179
"issues": {
"title": "Issues",
"open": "Open",
"closed": "Closed",
"selectRepo": "Select a repository...",
"openCount": "{count} open",
"noResults": "No issues found.",
"comments": "{count} comment | {count} comments",
"linkedPrs": "{count} linked PR | {count} linked PRs",
"closedAs": "Closed",
"closedAsNotPlanned": "Not planned",
"needsResponse": "Waiting for your response",
"search": "Search issues...",
"count": "No issues | {count} issue | {count} issues",
"filter": {
"unassigned": "Unassigned",
"hasLinkedPr": "Has PR",
"noLinkedPr": "No PR",
"hasMilestone": "Milestone"
},
"sort": {
"critical": "Needs attention",
"newest": "Newest",
"oldest": "Oldest",
"mostCommented": "Most commented",
"leastCommented": "Least commented",
"recentlyUpdated": "Recently updated"
},
"error": {
Copy link
Contributor

@coderabbitai coderabbitai bot Feb 12, 2026

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Resolve unused i18n keys flagged by CI.

CI reports issues.title, issues.comments, and issues.linkedPrs as unused. Either wire them into the UI or remove them (and corresponding schema entries) to keep locales clean.

🤖 Prompt for AI Agents
In `@i18n/locales/en.json` around lines 151 - 179, CI reports that the i18n keys
issues.title, issues.comments, and issues.linkedPrs are unused; either wire them
into the UI where the issues list is rendered (use issues.title for the issues
header, issues.comments for comment counts display, and issues.linkedPrs for
linked PR counts in the issue item components) or remove these keys from the
locale and the corresponding schema/translation references (ensure you also
remove or update any references in the issues-related schema/translation lookup
code such as count/label rendering logic to avoid missing-key errors).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

used dynamically. is fine

Copy link
Contributor

Choose a reason for hiding this comment

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

@Flo0806, understood—thanks for clarifying that these keys are used dynamically. I've noted this for future reference.


✏️ Learnings added
Learnt from: Flo0806
Repo: flumen-dev/flumen.dev PR: 58
File: i18n/locales/en.json:151-176
Timestamp: 2026-02-13T14:17:04.414Z
Learning: In i18n/locales/en.json, the keys `issues.title`, `issues.comments`, and `issues.linkedPrs` are used dynamically in the issues feature code and should not be flagged as unused even if static analysis cannot detect them.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

Comment on lines +18 to +20
commentCount: node.comments.totalCount,
linkedPrCount: node.timelineItems.totalCount,
maintainerCommented: node.comments.nodes.some(c => c.author?.login === maintainerLogin),
Copy link
Contributor

@coderabbitai coderabbitai bot Feb 12, 2026

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

find . -name "index.get.ts" -path "*/api/issues/*" | head -5

Repository: flumen-dev/flumen.dev

Length of output: 97


🏁 Script executed:

cat server/api/issues/index.get.ts | head -250

Repository: flumen-dev/flumen.dev

Length of output: 2417


🏁 Script executed:

cat shared/utils/issue.ts

Repository: flumen-dev/flumen.dev

Length of output: 975


maintainerCommented may be inaccurate for issues with more than 100 comments.

The query fetches only the first 100 comment nodes via comments(first: 100). If an issue has more than 100 comments and the maintainer commented beyond that limit, maintainerCommented will incorrectly report false. Consider fetching a higher limit, paginating through all comments, or using a different approach to check maintainer participation.

linkedPrCount is correctly derived from timelineItems.totalCount and properly filtered to CROSS_REFERENCED_EVENT items, so no issue there.

🤖 Prompt for AI Agents
In `@shared/utils/issue.ts` around lines 18 - 20, The maintainerCommented boolean
is unreliable because the GraphQL field comments(first: 100) only returns the
first 100 comment nodes; update the logic that sets maintainerCommented to page
through comments (use comments.pageInfo.hasNextPage and pageInfo.endCursor) or
request a larger limit until you either find a comment by maintainerLogin or
exhaust pages. Locate the object building maintainerCommented in
shared/utils/issue.ts and replace the single-page check
(comments.nodes.some(...)) with a loop/function that queries comments(first,
after) repeatedly (or a helper like fetchCommentsUntilFoundMaintainer) and
short-circuits when a maintainer comment is found, then set maintainerCommented
accordingly.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

not this time. 100 comments are a lot... it's enough for now

Copy link
Contributor

Choose a reason for hiding this comment

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

@Flo0806, understood! That's a reasonable pragmatic decision for the current scope. 👍


🧠 Learnings used
Learnt from: Flo0806
Repo: flumen-dev/flumen.dev PR: 58
File: i18n/locales/en.json:151-176
Timestamp: 2026-02-13T14:17:04.414Z
Learning: In i18n/locales/en.json, the keys `issues.title`, `issues.comments`, and `issues.linkedPrs` are used dynamically in the issues feature code and should not be flagged as unused even if static analysis cannot detect them.

Copy link
Contributor

@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: 1

🤖 Fix all issues with AI agents
In `@app/components/issue/IssueRow.vue`:
- Around line 57-80: The meta row is missing the repository identifier; update
IssueRow.vue's template (near the span showing {{ issue.number }}) to render the
repository name (e.g., add a span like {{ issue.repository.name }} or {{
issue.repoFullName }} depending on the issue object shape) so the UI shows
"title + number + repository name"; if the issue prop doesn't currently include
repository info, ensure the parent supplies issue.repository (or repoFullName)
from the API/prop source used by IssueRow.vue (keep placement alongside {{
issue.number }} and maintain styling consistent with createdAgo/updatedAgo).
🧹 Nitpick comments (1)
app/components/issue/IssueRow.vue (1)

125-125: Stale comment: author is now in the meta row.

The comment says "Assignees + author" but author avatar/login was moved to the meta section (line 70-77). Update the comment to reflect the actual content.

✏️ Proposed fix
-    <!-- Right side: Assignees + author -->
+    <!-- Right side: Assignees -->

Comment on lines +57 to +80
<!-- Row 2: Meta -->
<div class="flex items-center gap-3 mt-1 text-xs text-muted">
<UTooltip
v-if="!issue.maintainerCommented && issue.commentCount > 0"
:text="t('issues.needsResponse')"
>
<span class="inline-flex items-center gap-0.5 text-amber-500">
<UIcon
name="i-lucide-message-circle-warning"
class="size-3.5"
/>
</span>
</UTooltip>
<span class="inline-flex items-center gap-1">
<UAvatar
:src="issue.author.avatarUrl"
:alt="issue.author.login"
size="3xs"
/>
{{ issue.author.login }}
</span>
<span>#{{ issue.number }}</span>
<span>{{ createdAgo }}</span>
<span>{{ updatedAgo }}</span>
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Repository name still missing from meta row.

PR objectives require displaying "title + number + repository name" to disambiguate issues across repositories. The author and created time from the prior feedback have been added, but the repository identifier is still absent.

🔧 Proposed fix to add repository name
       <!-- Row 2: Meta -->
       <div class="flex items-center gap-3 mt-1 text-xs text-muted">
+        <span class="inline-flex items-center gap-1">
+          <UIcon name="i-lucide-book-marked" class="size-3.5" />
+          {{ issue.repository }}
+        </span>
         <UTooltip
           v-if="!issue.maintainerCommented && issue.commentCount > 0"
           :text="t('issues.needsResponse')"
🤖 Prompt for AI Agents
In `@app/components/issue/IssueRow.vue` around lines 57 - 80, The meta row is
missing the repository identifier; update IssueRow.vue's template (near the span
showing {{ issue.number }}) to render the repository name (e.g., add a span like
{{ issue.repository.name }} or {{ issue.repoFullName }} depending on the issue
object shape) so the UI shows "title + number + repository name"; if the issue
prop doesn't currently include repository info, ensure the parent supplies
issue.repository (or repoFullName) from the API/prop source used by IssueRow.vue
(keep placement alongside {{ issue.number }} and maintain styling consistent
with createdAgo/updatedAgo).

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.

Issue list page with enriched overview

2 participants