feat(WIP): New IssueExplor PR - #412
Conversation
Signed-off-by: aceppaluni <aceppaluni@gmail.com>
✅ Deploy Preview for hiero-open-source ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
|
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
📝 WalkthroughWalkthroughAdds an "Issue Explorer" feature: a client page with debounced filters that queries a new internal API backed by GitHub search, plus TypeScript models and menu entry. Separately updates Netlify and Next.js deployment configuration to publish the Next.js output and register the Netlify Next.js plugin. ChangesBuild Configuration
Issue Explorer (feature + API + lib + UI)
Sequence DiagramsequenceDiagram
participant Client as Client (Browser)
participant Page as Issues Page
participant API as /api/issues Route
participant GitHub as GitHub REST API
Client->>Page: Visit /issues
activate Page
Page->>Page: Render filter controls
Client->>Page: Select difficulty & SDK
Page->>Page: Build query string
Page->>API: GET /api/issues?q=<encoded_query>
activate API
API->>API: Parse q, call searchIssues
API->>GitHub: GET /search/issues (Accept/User-Agent, optional Bearer)
activate GitHub
GitHub-->>API: 200 + search JSON
deactivate GitHub
API-->>Page: 200 + issues data
deactivate API
Page->>Page: Update state, dedupe, filter, render grid
Page-->>Client: Display issue cards with links
deactivate Page
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~22 minutes Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 3❌ Failed checks (1 warning, 2 inconclusive)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Tip 💬 Introducing Slack Agent: The best way for teams to turn conversations into code.Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.
Built for teams:
One agent for your entire SDLC. Right inside Slack. 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. Comment |
✅ Snyk checks have passed. No issues have been found so far.
💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse. |
Not up to standards ⛔🔴 Issues
|
| Category | Results |
|---|---|
| ErrorProne | 26 high |
| Security | 1 high |
🟢 Metrics 35 complexity · 0 duplication
Metric Results Complexity 35 Duplication 0
NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.
Signed-off-by: aceppaluni <aceppaluni@gmail.com>
Signed-off-by: aceppaluni <aceppaluni@gmail.com>
Signed-off-by: aceppaluni <aceppaluni@gmail.com>
Signed-off-by: aceppaluni <aceppaluni@gmail.com>
Signed-off-by: aceppaluni <aceppaluni@gmail.com>
Signed-off-by: aceppaluni <aceppaluni@gmail.com>
Signed-off-by: aceppaluni <aceppaluni@gmail.com>
Signed-off-by: aceppaluni <aceppaluni@gmail.com>
There was a problem hiding this comment.
Actionable comments posted: 5
🧹 Nitpick comments (4)
next.config.ts (1)
4-4: Remove commented config to avoid deployment ambiguity.Line 4 leaves
output: "export"as commented code. Since this app now relies on server runtime behavior (e.g.,src/app/api/issues/route.tsLines 1-10), keeping this commented setting is easy to misread and accidentally re-enable later.Suggested cleanup
const nextConfig: NextConfig = { - //output: "export", images: { unoptimized: true, }, };🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@next.config.ts` at line 4, Remove the commented-out Next config entry `output: "export"` from next.config.ts to prevent accidental re-enabling and deployment ambiguity; locate the commented line containing `//output: "export"` and delete it so the active server/runtime behavior (e.g., server routes under src/app/api) remains unambiguous.src/app/issues/page.tsx (2)
45-77: Remove commented-out legacy blocks.These commented sections add noise and make the active logic harder to follow.
Also applies to: 89-108
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/app/issues/page.tsx` around lines 45 - 77, Remove the commented-out legacy buildQuery block and the other commented sections referring to sdk/difficulty logic to reduce noise; specifically delete the commented function buildQuery and any commented code that references sdkMap, difficultyMap, getSdkValue/getDifficultyValue, sdk, and difficulty so only the active query-building logic remains; ensure you only remove commented legacy code and leave any live functions, imports, or variables used elsewhere intact.
30-43: Stabilize map constants to resolve Hook dependency warning cleanly.
difficultyMapandsdkMapare recreated on each render but used in Line 109 effect. Move them to module scope (or memoize) to avoid dependency ambiguity and lint noise.Also applies to: 109-151
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/app/issues/page.tsx` around lines 30 - 43, The difficultyMap and sdkMap objects are recreated every render and cause a hook dependency warning for the effect that references them (the effect around Line 109); to fix, lift difficultyMap and sdkMap out of the React component into module scope as top-level consts (or alternatively wrap them with useMemo inside the component) so they are stable references, then adjust the effect dependencies accordingly (if moved to module scope, remove them from the dependency array; if memoized, keep the memo values in the array). Ensure you update references to difficultyMap and sdkMap in the effect and elsewhere to use the new stable identifiers.src/lib/github/issues.ts (1)
34-40: Remove the library-levelGEThandler to avoid duplicated API entrypoints.This file should stay as a data client (
searchIssues) only. KeepingGEThere duplicates route concerns already handled insrc/app/api/issues/route.ts.Suggested cleanup
-export async function GET(req: Request) { - const { searchParams } = new URL(req.url); - const q = searchParams.get("q") || ""; - - const data = await searchIssues(q); - return Response.json(data); -}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/lib/github/issues.ts` around lines 34 - 40, Remove the library-level HTTP handler by deleting the exported async function GET in this module so the file only exposes the data client (searchIssues); ensure searchIssues remains exported and update any internal references to not import GET (only import searchIssues) so routing is only handled by the existing api route handler (src/app/api/issues/route.ts) and there are no duplicate entrypoints.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/app/api/issues/route.ts`:
- Around line 7-10: Wrap the await searchIssues(q) call in a try/catch inside
the route handler; if searchIssues throws, catch the error and return a JSON
response using Response.json with a body like { items: [], error: <error
message> } and an appropriate status (e.g., 500). Update the handler where
searchIssues and Response.json are used so the happy path still returns
Response.json(data) but failures return the structured JSON error shape instead.
In `@src/app/issues/page.tsx`:
- Line 174: Update the option text for the select option with value "" in the
page component so the label reads "All Repos" instead of "All Repo's"; locate
the <option value="">All Repo's</option> occurrence in the component
(page.tsx) and change the displayed string to "All Repos".
- Around line 156-180: The two <select> controls bound to state variables
difficulty (with setDifficulty) and sdk (with setSdk) lack accessible labels;
add visible <label> elements for each select and associate them via id/for
attributes (e.g., give the difficulty select an id like "filter-difficulty" and
the sdk select an id like "filter-sdk"), or alternatively add clear aria-label
attributes if visible labels are undesired, ensuring the label text (e.g.,
"Difficulty" and "SDK") uniquely identifies each control for assistive tech.
- Around line 109-151: The fetch effect can leak older responses; create a new
AbortController inside the useEffect (used by fetchIssues), pass
controller.signal into getIssues, and abort the controller in the effect cleanup
so previous requests are cancelled when difficulty/sdk change; inside
fetchIssues catch AbortError specifically and avoid calling setError or
overwriting setIssues for aborted requests, while still ensuring
setLoading(false) runs in finally. Ensure references: useEffect, buildQuery,
fetchIssues, getIssues, setLoading, setError, setIssues.
In `@src/lib/github/issues.ts`:
- Around line 25-31: Update the fetch call that assigns to const res so it uses
an AbortController with a configurable timeout (e.g., 10s) and passes
controller.signal to fetch to avoid hangs, then on non-OK responses throw an
Error that includes res.status and the response body text (await res.text()) for
debugging; locate the fetch(...) invocation and the subsequent if (!res.ok)
branch in src/lib/github/issues.ts and replace the simple throw with a
propagated error containing HTTP status and body after the timeout-enabled
request.
---
Nitpick comments:
In `@next.config.ts`:
- Line 4: Remove the commented-out Next config entry `output: "export"` from
next.config.ts to prevent accidental re-enabling and deployment ambiguity;
locate the commented line containing `//output: "export"` and delete it so the
active server/runtime behavior (e.g., server routes under src/app/api) remains
unambiguous.
In `@src/app/issues/page.tsx`:
- Around line 45-77: Remove the commented-out legacy buildQuery block and the
other commented sections referring to sdk/difficulty logic to reduce noise;
specifically delete the commented function buildQuery and any commented code
that references sdkMap, difficultyMap, getSdkValue/getDifficultyValue, sdk, and
difficulty so only the active query-building logic remains; ensure you only
remove commented legacy code and leave any live functions, imports, or variables
used elsewhere intact.
- Around line 30-43: The difficultyMap and sdkMap objects are recreated every
render and cause a hook dependency warning for the effect that references them
(the effect around Line 109); to fix, lift difficultyMap and sdkMap out of the
React component into module scope as top-level consts (or alternatively wrap
them with useMemo inside the component) so they are stable references, then
adjust the effect dependencies accordingly (if moved to module scope, remove
them from the dependency array; if memoized, keep the memo values in the array).
Ensure you update references to difficultyMap and sdkMap in the effect and
elsewhere to use the new stable identifiers.
In `@src/lib/github/issues.ts`:
- Around line 34-40: Remove the library-level HTTP handler by deleting the
exported async function GET in this module so the file only exposes the data
client (searchIssues); ensure searchIssues remains exported and update any
internal references to not import GET (only import searchIssues) so routing is
only handled by the existing api route handler (src/app/api/issues/route.ts) and
there are no duplicate entrypoints.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 1e2a1c46-c139-467f-acf0-c238da54478e
📒 Files selected for processing (6)
netlify.tomlnext.config.tssrc/app/api/issues/route.tssrc/app/issues/page.tsxsrc/components/Menu/index.tsxsrc/lib/github/issues.ts
danielmarv
left a comment
There was a problem hiding this comment.
@aceppaluni Thanks for working on the Issue Explorer. but before this is merged, please align the new /issues page with the existing layout system.
The page currently renders its content inside a plain top-level <div>. Since the project already has a reusable Container component, this page should use it to keep spacing, max-width behavior, and responsive layout consistent with the rest of the site.
Please update src/app/issues/page.tsx to import and use the shared container:
import Container from "@/components/Container";Then wrap the page content with it, for example:
return (
<Container className="py-12">
{/* Filters */}
<div className="mb-6 flex gap-4">
...
</div>
{/* Issues Grid */}
...
</Container>
);
This avoids introducing one-off layout wrappers and keeps the new Issue Explorer page consistent with the existing design system.
Please use the shared Container component here instead of a plain top-level <div>. This page is introducing a new full-page layout, so wrapping the filters and issue grid in Container will keep the width, spacing, and responsive behavior consistent with the rest of the site.
for that addressed it will good to go
Signed-off-by: aceppaluni <aceppaluni@gmail.com>
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (1)
src/app/issues/page.tsx (1)
172-198:⚠️ Potential issue | 🟠 Major | ⚡ Quick winAccessible labels for
<select>controls are still missing.Both filter selects have no associated
<label>element and noaria-label, so assistive technology cannot identify them. This was flagged in the previous review and remains unresolved.♿ Proposed fix
<div className="flex gap-4 mb-6"> + <label htmlFor="filter-difficulty" className="sr-only"> + Difficulty + </label> <select + id="filter-difficulty" value={difficulty} onChange={e => setDifficulty(e.target.value)} className="p-2 rounded border"> ... </select> + <label htmlFor="filter-sdk" className="sr-only"> + Repository + </label> <select + id="filter-sdk" value={sdk} onChange={e => setSdk(e.target.value)} className="p-2 rounded border">🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/app/issues/page.tsx` around lines 172 - 198, Add accessible labels for the two select controls that currently use value={difficulty} onChange={e => setDifficulty(e.target.value)} and value={sdk} onChange={e => setSdk(e.target.value)}: either add a visually-present <label> linked via htmlFor to each <select> id (e.g., id="difficulty-select" and id="sdk-select") or add clear aria-label attributes (e.g., aria-label="Filter by difficulty" and aria-label="Filter by repository / SDK") so screen readers can identify them; ensure IDs/labels match and keep existing className and onChange handlers.
🧹 Nitpick comments (3)
src/app/issues/page.tsx (2)
65-85: ⚡ Quick winMove
getIssuesandmatchesDifficultyto module scope to fix missinguseEffectdependencies.Both functions are declared inside the component body but close over no component state — they access only module-level
cacheand their own parameters. Because they're re-created on every render, they are technically unstable references omitted from theuseEffectdependency array at line 166, which will triggerreact-hooks/exhaustive-depswarnings. Moving them to module scope fixes the lint violation with zero behavior change.♻️ Proposed refactor
+const getIssues = async ( + query: string, + signal?: AbortSignal, +): Promise<GitHubSearchResponse> => { + if (cache.has(query)) { + return cache.get(query)!; + } + const res = await fetch(`/api/issues?q=${encodeURIComponent(query)}`, { signal }); + const data = (await res.json()) as GitHubSearchResponse; + if (!res.ok) { + throw new Error(data.error ?? "Failed to fetch issues"); + } + cache.set(query, data); + return data; +}; + +const matchesDifficulty = (issue: GitHubIssue, difficulty: string) => { + // ... same body +}; + export default function GoodFirstIssues() { // ... - const getIssues = async (...) => { ... }; - const matchesDifficulty = (...) => { ... };Also applies to: 90-108, 166-166
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/app/issues/page.tsx` around lines 65 - 85, The functions getIssues and matchesDifficulty are defined inside the component causing unstable references and ESLint exhaustives-deps warnings; move both getIssues (which uses the module-level cache and fetch) and matchesDifficulty to module scope (outside the React component) so they no longer get re-created on each render, update any imports/exports if necessary, and ensure their signatures remain the same (getIssues(query: string, signal?: AbortSignal): Promise<GitHubSearchResponse>) so existing useEffect calls can depend on stable references without behavior change.
7-17: ⚡ Quick winConsolidate shared types into a single module.
GitHubIssueandGitHubSearchResponseare now declared in three places:src/lib/github/issues.ts,src/app/api/issues/route.ts, and here. Any divergence (like theerror?field being in some but not others) will silently cause type drift. Extract to a sharedsrc/types/github.ts(or re-export from the lib) and import from one source.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/app/issues/page.tsx` around lines 7 - 17, The GitHubIssue and GitHubSearchResponse types are duplicated across the codebase; create a single shared module that exports the types (e.g., export type GitHubIssue and export type GitHubSearchResponse with the optional error? field) and update all places that currently redeclare them to import these types instead (replace local declarations in the modules that define/use GitHubIssue and GitHubSearchResponse with imports from the shared module and ensure the optional error? field is consistent everywhere).src/app/api/issues/route.ts (1)
3-18: ⚡ Quick winRemove duplicate interface definitions and the dead-code workaround.
Three problems in this block:
GitHubIssue(lines 3–8) duplicates the exported interface fromsrc/lib/github/issues.tswith identical fields.GitHubSearchResponse(lines 10–13) re-declares the lib type with onlyerror?added andtotal_countdropped — the sole reason for therawSearchIssues as SearchIssuesFncast.- Line 17 is a dead-code artifact (
/*const searchIssues = rawSearchIssues as searchIssues;*/).Import
GitHubIssuefrom the lib and define only a minimal local error-response type:♻️ Proposed refactor
-import { searchIssues as rawSearchIssues } from "src/lib/github/issues"; +import { searchIssues, GitHubIssue } from "src/lib/github/issues"; -interface GitHubIssue { - id: number; - title: string; - html_url: string; - repository_url: string; -} - -interface GitHubSearchResponse { - items: GitHubIssue[]; - error?: string; -} +interface ApiErrorResponse { + items: GitHubIssue[]; + error: string; +} -// eslint-disable-next-line `@typescript-eslint/no-unused-vars` -type SearchIssuesFn = (_query: string) => Promise<GitHubSearchResponse>; -/*const searchIssues = rawSearchIssues as searchIssues;*/ -const searchIssues = rawSearchIssues as SearchIssuesFn;Then update the error-path return to use the new type:
- return Response.json({ items: [], error: message }, { status }); + return Response.json({ items: [], error: message } satisfies ApiErrorResponse, { status });🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/app/api/issues/route.ts` around lines 3 - 18, Remove the duplicate type definitions and dead-code cast: import the existing GitHubIssue interface from the lib instead of re-declaring it, delete the locally duplicated GitHubSearchResponse, remove the commented-out workaround (/*const searchIssues...*/), and replace the local SearchIssuesFn/typed cast by declaring a minimal local error response type (e.g., { error?: string }) used only for error-path returns; keep the actual search function reference as const searchIssues = rawSearchIssues and update any error return to use the new minimal error-response type so the code no longer masks the original lib types.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/app/issues/page.tsx`:
- Around line 90-108: matchesDifficulty currently inspects issue.title for
difficulty keywords (function matchesDifficulty) which is wrong; instead remove
this client-side title filter and wire the selected difficulty into the GitHub
search query/labels when fetching issues (the issue fetcher / query builder
where issues are requested) so the API returns only issues with the appropriate
label (e.g., "good first issue" or repo-specific "skill: beginner"). Delete or
disable the map and matchesDifficulty usage and update the search parameter
construction to add label:<labelName> (or multiple label qualifiers) based on
the difficulty select value; ensure the select option values match actual repo
label names and fallback to no label when difficulty is empty.
---
Duplicate comments:
In `@src/app/issues/page.tsx`:
- Around line 172-198: Add accessible labels for the two select controls that
currently use value={difficulty} onChange={e => setDifficulty(e.target.value)}
and value={sdk} onChange={e => setSdk(e.target.value)}: either add a
visually-present <label> linked via htmlFor to each <select> id (e.g.,
id="difficulty-select" and id="sdk-select") or add clear aria-label attributes
(e.g., aria-label="Filter by difficulty" and aria-label="Filter by repository /
SDK") so screen readers can identify them; ensure IDs/labels match and keep
existing className and onChange handlers.
---
Nitpick comments:
In `@src/app/api/issues/route.ts`:
- Around line 3-18: Remove the duplicate type definitions and dead-code cast:
import the existing GitHubIssue interface from the lib instead of re-declaring
it, delete the locally duplicated GitHubSearchResponse, remove the commented-out
workaround (/*const searchIssues...*/), and replace the local
SearchIssuesFn/typed cast by declaring a minimal local error response type
(e.g., { error?: string }) used only for error-path returns; keep the actual
search function reference as const searchIssues = rawSearchIssues and update any
error return to use the new minimal error-response type so the code no longer
masks the original lib types.
In `@src/app/issues/page.tsx`:
- Around line 65-85: The functions getIssues and matchesDifficulty are defined
inside the component causing unstable references and ESLint exhaustives-deps
warnings; move both getIssues (which uses the module-level cache and fetch) and
matchesDifficulty to module scope (outside the React component) so they no
longer get re-created on each render, update any imports/exports if necessary,
and ensure their signatures remain the same (getIssues(query: string, signal?:
AbortSignal): Promise<GitHubSearchResponse>) so existing useEffect calls can
depend on stable references without behavior change.
- Around line 7-17: The GitHubIssue and GitHubSearchResponse types are
duplicated across the codebase; create a single shared module that exports the
types (e.g., export type GitHubIssue and export type GitHubSearchResponse with
the optional error? field) and update all places that currently redeclare them
to import these types instead (replace local declarations in the modules that
define/use GitHubIssue and GitHubSearchResponse with imports from the shared
module and ensure the optional error? field is consistent everywhere).
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 3f6bb07e-85ce-46e4-8bf4-99900f315566
📒 Files selected for processing (3)
src/app/api/issues/route.tssrc/app/issues/page.tsxsrc/lib/github/issues.ts
🚧 Files skipped from review as they are similar to previous changes (1)
- src/lib/github/issues.ts
Signed-off-by: aceppaluni <aceppaluni@gmail.com>
Signed-off-by: aceppaluni <aceppaluni@gmail.com>
exploreriii
left a comment
There was a problem hiding this comment.
The codacy issues here will block you
I’d recommend splitting this into smaller, more manageable units
Right now src/app/issues/page.tsx contains UI, fetch logic, caching, filtering, maps, debounce logic, and response-shape assumptions in one client component. That makes the page harder to review, test, and maintain and means if you have a codacy issue, its difficult to solve it as there are lots of other things mixed in
Suggested structure:
- move GitHub/API fetching into a helper or service module
- move
useDebouncedValueinto a shared hook - move repo/difficulty maps and filtering helpers into a separate utility file
- keep
page.tsxfocused on rendering and composing smaller components - extract filters and issue cards into separate components
- strictly type the API response and validate it before using it
There are also type-safety issues flagged by Codacy. In particular, searchIssues() currently casts the GitHub response directly to GitHubSearchResponse, and the route then trusts that shape. We should validate the JSON response before returning it.
One other issue: src/lib/github/issues.ts appears to include a GET route handler at the bottom. That should not live in the lib file; route handlers should stay under src/app/api/.../route.ts.
Additionally, I would really focus on stripping this to be simpler
- for example, do we need cache and debouncing right now?
- why filter by issue title, we can filter by the issue labels? then you don't need to add custom sort logic
- we don't need to fetch all repos
eg
Page.tsx
renders page only
separate components:
IssueFilters.tsx
IssueCard.tsx
IssueGrid.tsx
etc
separate hooks eg:
hooks/useIssues.ts
ssues/types.ts
ssues/filters.ts
Signed-off-by: aceppaluni <aceppaluni@gmail.com>
Signed-off-by: aceppaluni <aceppaluni@gmail.com>
Signed-off-by: aceppaluni <aceppaluni@gmail.com>
Signed-off-by: aceppaluni <aceppaluni@gmail.com>
Signed-off-by: aceppaluni <aceppaluni@gmail.com>
Signed-off-by: aceppaluni <aceppaluni@gmail.com>
Signed-off-by: aceppaluni <aceppaluni@gmail.com>
Signed-off-by: aceppaluni <aceppaluni@gmail.com>
Signed-off-by: aceppaluni <aceppaluni@gmail.com>
Signed-off-by: aceppaluni <aceppaluni@gmail.com>
Signed-off-by: aceppaluni <aceppaluni@gmail.com>
Signed-off-by: aceppaluni <aceppaluni@gmail.com>
Signed-off-by: aceppaluni <aceppaluni@gmail.com>
Signed-off-by: aceppaluni <aceppaluni@gmail.com>
Signed-off-by: aceppaluni <aceppaluni@gmail.com>
Signed-off-by: aceppaluni <aceppaluni@gmail.com>
Signed-off-by: aceppaluni <aceppaluni@gmail.com>
Signed-off-by: aceppaluni <aceppaluni@gmail.com>
Signed-off-by: aceppaluni <aceppaluni@gmail.com>
Signed-off-by: aceppaluni <aceppaluni@gmail.com>
Signed-off-by: aceppaluni <aceppaluni@gmail.com>
Signed-off-by: aceppaluni <aceppaluni@gmail.com>
Description
This PR aims to add the Issue Explorer Tab to help users find new tasks to work on.
Changes Made
Related Issues
Fixes: #398
Screenshots (if applicable)
Checklist
Deployment Notes
Additional Notes
Summary by CodeRabbit
New Features
Bug Fixes / Reliability