Skip to content

[T16] Export to CSV (5 doi tuong) - #3

Merged
thanhnv-3702 merged 5 commits into
developfrom
feature/T16-export-csv
Jul 3, 2026
Merged

[T16] Export to CSV (5 doi tuong)#3
thanhnv-3702 merged 5 commits into
developfrom
feature/T16-export-csv

Conversation

@thanhnv-3702

@thanhnv-3702 thanhnv-3702 commented Jun 29, 2026

Copy link
Copy Markdown
Collaborator

Mục tiêu

Export dữ liệu ra CSV (UTF-8) cho 5 đối tượng: User (kèm skills), Position, Skill, Team, Project (kèm members).

Thay đổi

  • CsvUtil: sinh CSV theo RFC 4180 (escape , " \n), CRLF, BOM UTF-8.
  • CsvExportService: exportUsers/Positions/Skills/Teams/Projects (readOnly tx; gom skills/members bằng group-by tránh N+1).
  • AdminExportController: GET /admin/export/{entity}.csvtext/csv; charset=UTF-8 + Content-Disposition: attachment.
  • Nút Export CSV trên 5 trang list admin.

Kiểm thử (đã verify)

Endpoint Kết quả
/admin/export/users.csv 200, có cột Skills
/admin/export/positions.csv 200
/admin/export/skills.csv 200
/admin/export/teams.csv 200, có MemberCount
/admin/export/projects.csv 200, có cột Members
Tất cả text/csv; charset=UTF-8, BOM efbbbf, attachment
USER role 403

DoD

✅ Tải về được CSV đúng dữ liệu cho 5 đối tượng, UTF-8 hiển thị tiếng Việt chuẩn.

image Screenshot 2026-06-29 at 13 07 03 image image image

thanhnv-3702 and others added 5 commits June 26, 2026 15:59
- ClientTeamService: list team phan trang, dem thanh vien theo team, chi tiet team
- ClientTeamController: GET /teams + GET /teams/{id}
- Templates client/teams/list.html (card grid + pagination) + detail.html (members + projects)
- TeamRepository.findWithLeaderById @EntityGraph(leader)
- UserRepository.findByTeamIdOrderByNameAsc @EntityGraph(position) + countGroupedByTeam
- Navbar: link Teams -> /teams

Verified: list 2 teams + member count; detail hien members/projects dung; anon -> login
Co-authored-by: Cursor <cursoragent@cursor.com>
[T13] Client: List all teams (pagination + members)
- ClientMemberController: GET /teams/{teamId}/members (phan trang) + GET /members/{id} (profile cong khai)
- ClientTeamService.getMembers(teamId, Pageable)
- UserRepository.findByTeamId(Long, Pageable) @EntityGraph(position)
- Templates: client/teams/members.html + client/members/profile.html
- Team detail: ten thanh vien link sang /members/{id} + nut "Xem tat ca"

Verified: list phan trang, profile thanh vien (info/projects/skills), anon -> login
Co-authored-by: Cursor <cursoragent@cursor.com>
[T14] Client: List members in a team (pagination + profile)
- CsvUtil: sinh CSV RFC4180 (escape, CRLF, BOM UTF-8)
- CsvExportService: export Users(+skills)/Positions/Skills/Teams/Projects(+members)
- AdminExportController GET /admin/export/{entity}.csv (text/csv; attachment)
- Nut Export CSV tren 5 trang list admin

Verified: 5 file 200 + text/csv UTF-8 + BOM + header dung; USER 403
Co-authored-by: Cursor <cursoragent@cursor.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR adds CSV export capabilities for multiple admin-managed entities (via new controller/service/util) and wires the export actions into the admin list pages. It also introduces a client-facing Teams browsing flow (navbar link + new client controllers/templates).

Changes:

  • Add CSV generation utility and export service for Users/Positions/Skills/Teams/Projects, and expose them via /admin/export/*.csv.
  • Add Export CSV buttons to 5 admin list pages.
  • Add client Teams navigation + pages (teams list/detail/members) and member profile page.

Reviewed changes

Copilot reviewed 18 out of 18 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
src/main/resources/templates/fragments/client-navbar.html Enables client Teams navigation link.
src/main/resources/templates/client/teams/members.html New client page: paginated team members list.
src/main/resources/templates/client/teams/list.html New client page: teams listing with member counts.
src/main/resources/templates/client/teams/detail.html New client page: team detail with members/projects preview.
src/main/resources/templates/client/members/profile.html New client page: member profile (projects + skills).
src/main/resources/templates/admin/users/list.html Adds Export CSV button for users.
src/main/resources/templates/admin/teams/list.html Adds Export CSV button for teams.
src/main/resources/templates/admin/skills/list.html Adds Export CSV button for skills.
src/main/resources/templates/admin/projects/list.html Adds Export CSV button for projects.
src/main/resources/templates/admin/positions/list.html Adds Export CSV button for positions.
src/main/java/com/slearn/membermanagement/util/CsvUtil.java New CSV builder (BOM + CRLF + escaping).
src/main/java/com/slearn/membermanagement/service/CsvExportService.java New export service building CSV for 5 entities.
src/main/java/com/slearn/membermanagement/service/ClientTeamService.java New client service for teams, members, projects, member counts.
src/main/java/com/slearn/membermanagement/repository/UserRepository.java Adds entity graphs + grouped count query for team member counts.
src/main/java/com/slearn/membermanagement/repository/TeamRepository.java Adds entity graph query for fetching team + leader by id.
src/main/java/com/slearn/membermanagement/controller/ClientTeamController.java New client controller for teams list/detail.
src/main/java/com/slearn/membermanagement/controller/ClientMemberController.java New client controller for team members list + member profile.
src/main/java/com/slearn/membermanagement/controller/admin/AdminExportController.java New admin controller exposing CSV download endpoints.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +37 to +44
private static String escape(String value) {
String v = (value == null) ? "" : value;
boolean mustQuote = v.contains(",") || v.contains("\"") || v.contains("\n") || v.contains("\r");
if (mustQuote) {
return "\"" + v.replace("\"", "\"\"") + "\"";
}
return v;
}
Comment on lines +102 to +115
@Transactional(readOnly = true)
public String exportTeams() {
List<List<String>> rows = new ArrayList<>();
for (Team t : teamRepository.findAll(BY_ID)) {
rows.add(List.of(
str(t.getId()),
nz(t.getName()),
nz(t.getDescription()),
t.getLeader() != null ? nz(t.getLeader().getName()) : "",
str(userRepository.countByTeamId(t.getId()))
));
}
return CsvUtil.build(List.of("ID", "Name", "Description", "Leader", "MemberCount"), rows);
}

import com.slearn.membermanagement.entity.Position;
import com.slearn.membermanagement.entity.Project;
import com.slearn.membermanagement.entity.ProjectMember;
Comment on lines 22 to 25
@Override
@EntityGraph(attributePaths = {"team", "position"})
Page<User> findAll(Pageable pageable);

Comment on lines 13 to 15
@Override
@EntityGraph(attributePaths = "leader")
Page<Team> findAll(Pageable pageable);
</li>
<li class="nav-item">
<a class="nav-link" href="#"
<a class="nav-link" th:href="@{/teams}"
@thanhnv-3702
thanhnv-3702 merged commit 7709cc2 into develop Jul 3, 2026
1 check passed
@thanhnv-3702
thanhnv-3702 deleted the feature/T16-export-csv branch July 3, 2026 05:19
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.

2 participants