GitServer / src / GitServer / wwwroot / User / GroupDetail.cshtml.cs
Code · 128 lines · 3402 bytes
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128using GitServer.Data;
using GitServer.Models;
using GitServer.Services;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;

namespace GitServer.wwwroot.User;

[Authorize]
public class GroupDetailModel(AppDbContext db, UserManager<AppUser> userManager, LocalizationService L) : PageModel
{
	public AppUser? CurrentUser { get; set; }
	public Group? Group { get; set; }
	public List<GroupMember> Members { get; set; } = new();
	public string? Message { get; set; }
	public bool IsError { get; set; }

	[BindProperty] public string? MemberName { get; set; }

	private async Task<bool> LoadAsync(int id)
	{
		CurrentUser = await userManager.GetUserAsync(User);
		if (CurrentUser == null) return false;

		Group = await db.Groups.FirstOrDefaultAsync(g => g.Id == id && g.OwnerId == CurrentUser.Id);
		if (Group == null) return false;

		Members = await db.GroupMembers
			.Include(m => m.User)
			.Where(m => m.GroupId == id)
			.OrderBy(m => m.User.UserName)
			.ToListAsync();

		return true;
	}

	public async Task<IActionResult> OnGetAsync(int id)
	{
		if (!await LoadAsync(id)) return NotFound();
		return Page();
	}

	public async Task<IActionResult> OnGetSearchUsersAsync(int id, string? q)
	{
		if (!await LoadAsync(id)) return NotFound();

		q = q?.Trim();
		if (string.IsNullOrEmpty(q) || q.Length < 2) return new JsonResult(Array.Empty<object>());

		var lower = q.ToLower();
		var memberIds = Members.Select(m => m.UserId).ToHashSet();
		var results = await db.Users
			.Where(u => u.Id != CurrentUser!.Id && (
				u.UserName!.ToLower().Contains(lower) ||
				u.Email!.ToLower().Contains(lower) ||
				u.DisplayName.ToLower().Contains(lower)))
			.OrderBy(u => u.UserName)
			.Take(10)
			.Select(u => new { userName = u.UserName, displayName = u.DisplayName, email = u.Email })
			.ToListAsync();

		return new JsonResult(results);
	}

	public async Task<IActionResult> OnPostAddMemberAsync(int id)
	{
		if (!await LoadAsync(id)) return NotFound();

		var name = MemberName?.Trim();
		if (string.IsNullOrEmpty(name))
		{
			Message = L["error_collaborator_name_required"];
			IsError = true;
			return Page();
		}

		var member = await userManager.FindByNameAsync(name);
		if (member == null)
		{
			Message = L["error_user_not_found"];
			IsError = true;
			return Page();
		}

		if (member.Id == CurrentUser!.Id)
		{
			Message = L["error_group_member_is_owner"];
			IsError = true;
			return Page();
		}

		if (!Members.Any(m => m.UserId == member.Id))
		{
			db.GroupMembers.Add(new GroupMember { GroupId = Group!.Id, UserId = member.Id });
			await db.SaveChangesAsync();
		}

		Message = L["success_group_member_added"];
		return RedirectToPage(new { id });
	}

	public async Task<IActionResult> OnPostRemoveMemberAsync(int id, int memberId)
	{
		if (!await LoadAsync(id)) return NotFound();

		var member = await db.GroupMembers.FirstOrDefaultAsync(m => m.Id == memberId && m.GroupId == id);
		if (member != null)
		{
			db.GroupMembers.Remove(member);
			await db.SaveChangesAsync();
		}

		return RedirectToPage(new { id });
	}

	public async Task<IActionResult> OnPostDeleteAsync(int id)
	{
		if (!await LoadAsync(id)) return NotFound();

		db.Groups.Remove(Group!);
		await db.SaveChangesAsync();

		return RedirectToPage("/User/Groups");
	}
}