Skip to content

Commit eb6f631

Browse files
feat: sidebar group cards and toggle collapse all button [DHIS2-20773/20772] (#153)
* chore: dedupe node modules * chore: refactor dimension selection state for correct collapse all behaviour * feat: add toggle-collapse-all-button * chore: fix typo in data source TET type guard * chore: set initial dimension group state isLoading to false * chore: add string literal types for card and list keys * chore: refactor the dimension selection state slice so card collapse and list loading are completely separate * chore: adjust toggle collapse button to new state structure * chore: fix unified search input after slice changes * chore: add card components without styling * chore: add styles to the card components WIP * chore: update deps * chore: fix styles * chore: fix collapse state * chore: give data-source dropdown a max-height so all options remain visible * chore: base DataSourceFilter on DimensionType so they can be used to filter * chore: use-dimension-list WIP * chore: address some potential hook issues * chore: use-dimension-list hook unit tests WIP * chore: add use-is-card-disabled-by-filter hook * chore: remove duplicate initial fetch * chore: refactor use dimenion list hook and add many test cases * chore: add new hook to check enabled state * chore: add OpenCode config files * chore: use consistent fields and type definition for program and program-stage * chore: use Program and ProgramStage type throughout * chore: rename initialDimensions to fixedDimensions * chore: add isDisabledByFilter field to use-dimensions-list hook and remove separate hook * chore: apply client side filter when fetch completes * chore: prevent race conditions while fetching dimension lists * chore: extract disabled by filter logic for reuse in stage component * chore: add isLoadingMore to hook * chore: add skeleton chip component * chore: useDimensionList returns hasNoData * chore: dimension-list WIP * chore: dimension-list with styles * chore: make cards that are disabled by filter opaque * chore: filter fetched dimensions based on filter state * chore: make dimensionListKey optional for fixed-dimension-only cards * chore: fix disabled by filter logic for fixed-dimension-only lists * chore: pass program and stage down to dimension list item * chore: do not wrap dimension-card-subsection children in dimension-list * chore: implement enrollment card * chore: remove console.log * chore: add program stage subsection * chore: add program indicator card * chore: add tracked entity type card * chore: add event card for program without registration and extract shared logic * chore: console.error instead of throw error so the app doesn't crash when hot reloading * chore: add card other * chore: add card metadata * chore: adjust failing tests to type change * chore: ensure collapse button remains aligned with input in case of search errors * chore: add optional transformer prop to use-dimensionlist hook to deal with TETs * chore: add type card * chore: make cards container scrollable and apply scroll styles * chore: remount cards when data source changes * chore: remove redundant fields from hook result * chore: load more delay and keep showing show more if it's there * chore: do not update (redux) state after unmounting * chore: rename useEffectEvent to useStableCallback * chore: address sonarqube issues * chore: fix more sonarqube issues * chore: fix last sonarqube issue * chore: add sonarqube issue fix skill for AI agents * chore: update AI agent instructions for git and file-level checks * chore: fix focus styles and keyboard event handlers * chore: tweak lint/test AI instructions * chore: tweak AGENTS instructions * chore: use FC type for all components * chore: add bidirectional delay to isLoadingMore * chore: useDimensionList refator WIP * chore: fix useStableCallback * chore: useDimensionList refactor WIP * chore: refactor useDimensionList complete * chore: migrate unit tests to new approach using fake timers WIP * chore: refactor unit test suite for useDimensionList and its helpers * chore: add useDelayedIsLoading hook with specs * chore: update agents instructions reg tests with fake timers * chore: add spec file for useListFetchState * chore: undo redundant rename * chore: add helpers to create baseQueries with unit tests * chore: set paging to true not false in helper * chore: use useDelayedIsLoadingMore in useDimensionList and adjust some test expectations * chore: fix typo * chore: fix sonarqube issues * chore: update skill so AI knows the PR the user is talking about * chore: remove redundant and add tests for no data scenarios * chore: upgrade @dhis2/ui and dedupe deps
1 parent db00176 commit eb6f631

82 files changed

Lines changed: 7740 additions & 796 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 229 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,229 @@
1+
---
2+
name: sonarqube-fix
3+
description: Fix SonarQube quality gate issues systematically using the API
4+
license: MIT
5+
compatibility: opencode
6+
metadata:
7+
audience: developers
8+
workflow: code-quality
9+
---
10+
11+
# SonarQube Issue Resolution Workflow
12+
13+
This skill provides a systematic approach to fixing SonarQube quality gate failures by fetching issues directly from the API and addressing them in priority order.
14+
15+
**Note**: This skill is designed for **public projects only**. All DHIS2 projects on GitHub/SonarCloud are public, so this skill works perfectly for DHIS2 repositories. For private projects, authentication would be required (not covered by this skill).
16+
17+
## When to Use This Skill
18+
19+
Use this skill when:
20+
21+
- A pull request fails SonarQube quality gate checks
22+
- You need to systematically fix code quality issues
23+
- You want to fetch and prioritize SonarQube issues from the API
24+
- You need to verify all issues are resolved before merging
25+
26+
**Note**: This skill will automatically detect which PR to analyze based on your current git branch. If you're on the `main` or `master` branch, you'll be asked to choose from open PRs.
27+
28+
## SonarQube API Access
29+
30+
### Fetching Issues from SonarCloud (Public Projects)
31+
32+
All DHIS2 projects are public and can be queried without authentication:
33+
34+
```bash
35+
curl -s "https://sonarcloud.io/api/issues/search?componentKeys=<org>_<repo>&pullRequest=<pr-number>&resolved=false&ps=100"
36+
```
37+
38+
**Example for DHIS2 projects:**
39+
40+
After identifying the PR number (e.g., `153`), repository (`dhis2/event-visualizer-app`), and organization (`dhis2`):
41+
42+
```bash
43+
curl -s "https://sonarcloud.io/api/issues/search?componentKeys=dhis2_event-visualizer-app&pullRequest=153&resolved=false&ps=100"
44+
```
45+
46+
**Key Parameters:**
47+
48+
- `componentKeys`: Format is `org_repo` (e.g., `dhis2_event-visualizer-app`)
49+
- `pullRequest`: The PR number
50+
- `resolved=false`: Only show unresolved issues
51+
- `ps=100`: Page size (max 100 per request)
52+
- `statuses=OPEN,REOPENED`: Filter by status if needed
53+
54+
### Parsing Issues with jq
55+
56+
To get a readable list of issues:
57+
58+
```bash
59+
curl -s "<api-url>" | jq -r '.issues[] | "\(.severity) - \(.type) - \(.message) - \(.component):\(.line)"' | sort
60+
```
61+
62+
This outputs format: `SEVERITY - TYPE - MESSAGE - FILE:LINE`
63+
64+
### Understanding Issue Types
65+
66+
**Severities (Priority Order):**
67+
68+
1. **BLOCKER** - Must fix immediately
69+
2. **CRITICAL** - High priority, blocks merge
70+
3. **MAJOR** - Important issues
71+
4. **MINOR** - Minor improvements
72+
5. **INFO** - Informational suggestions
73+
74+
**Types:**
75+
76+
- **BUG** - Code that is wrong or will likely fail
77+
- **VULNERABILITY** - Security-related issues
78+
- **CODE_SMELL** - Maintainability issues (non-functional)
79+
- **SECURITY_HOTSPOT** - Security-sensitive code to review
80+
81+
## Systematic Fixing Workflow
82+
83+
This is an **iterative, human-in-the-loop process**. The user will commit and push changes, then ask you to refetch and continue if issues remain.
84+
85+
### Step 0: Identify the PR
86+
87+
Before fetching issues, determine which pull request to analyze:
88+
89+
1. **Check current git branch**:
90+
91+
```bash
92+
git branch --show-current
93+
```
94+
95+
2. **Identify repository**:
96+
97+
```bash
98+
git remote -v | head -1
99+
```
100+
101+
Extract the organization and repository name (e.g., `dhis2/event-visualizer-app`).
102+
103+
3. **Find matching PR**:
104+
105+
- If on a feature branch, use GitHub MCP tools (`github_list_pull_requests`) to find open PRs
106+
- Match the current branch name to a PR's `head.ref` field
107+
- Extract the PR number from the matching PR
108+
109+
4. **Handle main/master branch**:
110+
111+
- If on `main` or `master` branch, list all open PRs
112+
- Present the list to the user and ask which PR to work on
113+
- Example format:
114+
115+
```
116+
Found 3 open PRs:
117+
- PR #153: feat: sidebar group cards and toggle collapse all button [DHIS2-20773/20772]
118+
- PR #155: refactor: implement new Layout design
119+
- PR #156: chore(deps-dev): bump the dependencies group
120+
121+
Which PR would you like to fix SonarQube issues for?
122+
```
123+
124+
5. **Store key information**:
125+
- Organization (e.g., `dhis2`)
126+
- Repository (e.g., `event-visualizer-app`)
127+
- PR number (e.g., `153`)
128+
129+
This information is needed to construct the SonarQube API URL: `componentKeys=<org>_<repo>&pullRequest=<pr-number>`
130+
131+
### Step 1: Fetch and Analyze
132+
133+
1. **Fetch all issues** using the API command
134+
2. **Parse and categorize** by severity and type using jq
135+
3. **Create a todo list** with all issues using the TodoWrite tool
136+
137+
### Step 2: Fix Issues in Priority Order
138+
139+
Fix issues in this order:
140+
141+
1. **BLOCKER** and **CRITICAL** issues first (any type)
142+
2. **BUGs** before CODE_SMELLs
143+
3. **Group similar issues** together (same rule, same file)
144+
4. **High severity** before low severity within each type
145+
146+
For each issue:
147+
148+
- Read the file to understand context
149+
- Understand what SonarQube is complaining about
150+
- Apply the fix following project conventions
151+
- Mark todo as completed immediately after fixing
152+
153+
### Step 3: Test Regularly
154+
155+
After fixing a batch of related issues (3-5 fixes):
156+
157+
1. Run tests: `yarn test`
158+
2. Run linter: `yarn lint`
159+
3. Fix any breaking changes immediately
160+
161+
**Never fix all issues without testing** - you might introduce bugs!
162+
163+
### Step 4: Process Complete
164+
165+
The fixing process is complete when:
166+
167+
- ✅ **All todos are marked as completed**
168+
- ✅ **All tests pass** (`yarn test`)
169+
- ✅ **All linters pass** (`yarn lint`)
170+
171+
**Note**: The user will commit and push the changes. If SonarQube still reports issues after the push, the user will ask you to refetch and continue fixing.
172+
173+
## Key Principles
174+
175+
### Fix What's Reported
176+
177+
- Fix only what SonarQube reports - don't refactor unnecessarily
178+
- Keep changes minimal and focused
179+
- Follow project conventions and coding style
180+
- Read context before changing code to avoid breaking functionality
181+
182+
### Test Frequently
183+
184+
- Test after every 3-5 related fixes
185+
- Don't wait until all fixes are done
186+
- Catch breaking changes early
187+
188+
### Common Test Commands
189+
190+
```bash
191+
yarn test # Run all tests
192+
yarn lint # Run all linters
193+
yarn format # Auto-fix formatting (if needed)
194+
```
195+
196+
## Tips for Efficiency
197+
198+
- **Group similar issues** - fix all instances of the same rule together
199+
- **Use jq for parsing** - easier than parsing JSON manually
200+
- **Sort issues** - `| sort` makes grouping easier
201+
- **Track progress** - TodoWrite keeps work visible
202+
- **Filter by type** - add `&types=BUG` to API URL to focus on specific types
203+
204+
## Troubleshooting
205+
206+
### PR Detection Fails
207+
208+
- **No matching PR found**: Check if the branch has an associated PR. Use `gh pr list` or GitHub UI to verify.
209+
- **Multiple PRs match**: Ask the user to specify which PR number to use.
210+
- **On main/master branch**: List open PRs and ask user to choose one.
211+
212+
### Tests Failing After Fix
213+
214+
- Revert the change and understand what broke
215+
- Read error messages carefully
216+
- Check if test expectations need updating
217+
- Ask the user for guidance if stuck
218+
219+
### Issues Still Showing After Push
220+
221+
- User will refetch and provide updated issue list
222+
- SonarQube needs time to re-analyze after push
223+
- Continue with remaining issues
224+
225+
## Resources
226+
227+
- **SonarQube API Docs**: https://sonarcloud.io/web_api
228+
- **SonarQube Rules**: https://rules.sonarsource.com/
229+
- **DHIS2 Code Style**: Project follows `@dhis2/cli-style` conventions

0 commit comments

Comments
 (0)