diff --git a/.gitignore b/.gitignore index 34ca015..f7577c8 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,9 @@ Migrations/ app.db* .DS_Store app.db +Data/Interfaces +Data/UnitOfWork.cs +Data/*Repository.cs # client client/src/pages/TestPage.tsx diff --git a/Controllers/AppUsersController.cs b/Controllers/AppUsersController.cs index d3ed49a..98262ef 100644 --- a/Controllers/AppUsersController.cs +++ b/Controllers/AppUsersController.cs @@ -1,38 +1,78 @@ using System; using System.Collections.Generic; using System.Threading.Tasks; +using System.Linq; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Http; using TicketManager.Data; using TicketManager.Models; -using Microsoft.AspNetCore.Authorization; +using TicketManager.DTO; + namespace TicketManager.Controllers { // [Authorize] + [Produces("application/json")] [Route("api/v1/users")] [ApiController] public class UsersController : ControllerBase { - private readonly IAppUserRepository _users; + private readonly AppDbContext _context; - public UsersController(IAppUserRepository users) + public UsersController(AppDbContext context) { - _users = users; + _context = context; } - // GET: api/Users + /// + /// Returns all Users stored in the database. + /// + /// + /// Sample request: + /// + /// GET: api/v1/Users + /// + /// + /// Returns a list of users [HttpGet] - public async Task> GetUsers() + [ProducesResponseType(StatusCodes.Status200OK)] + public async Task> GetUsers() { - return await _users.List(); + return await _context.AppUsers + .Include(u => u.Assignments) + .ThenInclude(a => a.Project) + .Include(u => u.Activities) + .AsNoTracking() + .Select(u => new AppUserDTO(u)) + .ToListAsync(); } - // GET: api/Users/5 + /// + /// Locate a specific User stored in the database by its Id + /// + /// + /// Sample request: + /// + /// GET: api/v1/Users/2 + /// + /// + /// Returns a User object + /// If the required User is null [HttpGet("{id}")] - public async Task> GetUser(Guid id) + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + public async Task> GetUser(Guid id) { - var user = await _users.GetUser(id); + var user = await _context.AppUsers + .Include(u => u.Assignments) + .ThenInclude(a => a.Project) + .Include(u => u.Activities) + .AsNoTracking() + .Select(u => new AppUserDTO(u)) + .FirstOrDefaultAsync(u => u.Id == id); + if (user == null) { return NotFound(); @@ -40,23 +80,44 @@ namespace TicketManager.Controllers return user; } - // PUT: api/Users/5 - // To protect from overposting attacks, please enable the specific properties you want to bind to, for - // more details see https://aka.ms/RazorPagesCRUD. + /// + /// Updates the specific project with Id. + /// + /// + /// Sample request: + /// + /// PUT: api/v1/Projects/3 + /// { + /// "id": "357727fd-5262-4522-b8a3-38271d43de84", + /// "firstName": "Thomas", + /// "lastName": "Price", + /// "presentation": "New Team?!", + /// "email": "tp@mail.com", + /// "phone": "0198237645" + /// } + /// + /// + /// Request was succesful but no content is changed + /// If the required project is null [HttpPut("{id}")] + [ProducesResponseType(StatusCodes.Status204NoContent)] + [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task PutUser(Guid id, AppUser user) { if (id != user.Id) { return BadRequest(); } + + _context.Entry(user).State = EntityState.Modified; + try { - await _users.Update(user); + await _context.SaveChangesAsync(); } catch (DbUpdateConcurrencyException) { - if (!_users.Exists(id)) + if (!UserExists(id)) { return NotFound(); } @@ -68,49 +129,101 @@ namespace TicketManager.Controllers return NoContent(); } - // POST: api/Users - // To protect from overposting attacks, please enable the specific properties you want to bind to, for - // more details see https://aka.ms/RazorPagesCRUD. + /// + /// Creates a project. + /// + /// + /// Sample request: + /// + /// POST: api/v1/Projects/ + /// { + /// "firstName": "Thomas", + /// "lastName": "Price", + /// "presentation": "New Team?!", + /// "email": "tp@mail.com", + /// "phone": "0198237645" + /// } + /// + /// + /// Returns the created project [HttpPost] - public async Task> PostUser(AppUser user) + [ProducesResponseType(StatusCodes.Status201Created)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + public async Task> PostUser(AppUser user) { - await _users.Add(user); - return CreatedAtAction("GetUser", new { id = user.Id }, user); + if (!ModelState.IsValid) + { + return BadRequest(); + } + + _context.AppUsers.Add(user); + await _context.SaveChangesAsync(); + + var dto = new AppUserDTO(user); + + return CreatedAtAction("GetUser", new { id = user.Id }, dto); } - // DELETE: api/Users/5 + /// + /// Deletes the project identified by its Id + /// + /// + /// Sample request: + /// + /// DELETE: api/v1/Projects/5 + /// + /// + /// Returns the deleted project + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status404NotFound)] [HttpDelete("{id}")] - public async Task> DeleteUser(Guid id) + public async Task> DeleteUser(Guid id) { - var user = await _users.GetUser(id); + var user = await _context.AppUsers.FindAsync(id); if (user == null) { return NotFound(); } - await _users.Delete(user); - return user; + _context.AppUsers.Remove(user); + await _context.SaveChangesAsync(); + var dto = new AppUserDTO(user); + return Ok(user); } [HttpGet("{id}/projects")] - public async Task>> GetAppUserProjects(Guid id) + public async Task>> GetAppUserProjects(Guid id) { - AppUser user = await _users.GetUser(id); + var user = await _context.AppUsers + .Include(u => u.Assignments) + .ThenInclude(a => a.Project) + .AsNoTracking() + .FirstOrDefaultAsync(u => u.Id == id); if (user == null) { return BadRequest(); } - return user.GetProjects(); + return user.GetProjects().Select(p => new ProjectDTO(p)).ToList(); } [HttpGet("{id}/tickets/")] - public async Task>> GetAppUserTickets(Guid id) + public async Task>> GetAppUserTickets(Guid id) { - AppUser user = await _users.GetUser(id); + var user = await _context.AppUsers + .Include(u => u.Assignments) + .ThenInclude(a => a.Project) + .ThenInclude(p => p.Tickets) + .AsNoTracking() + .FirstOrDefaultAsync(u => u.Id == id); if (user == null) { return BadRequest(); } - return user.GetTickets(); + return user.GetTickets().Select(t => new TicketDTO(t)).ToList(); + } + + private bool UserExists(Guid id) + { + return _context.AppUsers.Any(e => e.Id == id); } } } diff --git a/Controllers/ProjectsController.cs b/Controllers/ProjectsController.cs index d8232d9..33d4891 100644 --- a/Controllers/ProjectsController.cs +++ b/Controllers/ProjectsController.cs @@ -18,10 +18,11 @@ namespace TicketManager.Controllers [ApiController] public class ProjectsController : ControllerBase { - private IProjectRepository _projects; - public ProjectsController(IProjectRepository context) + private readonly AppDbContext _context; + + public ProjectsController(AppDbContext context) { - _projects = context; + _context = context; } /// @@ -36,10 +37,18 @@ namespace TicketManager.Controllers /// Returns a list of projects [HttpGet] [ProducesResponseType(StatusCodes.Status200OK)] - public async Task> GetProjects() + public async Task> GetProjects() { - - return await _projects.List(); + return await _context.Projects + .Include(p => p.Assignments) + .ThenInclude(a => a.User) + .Include(p => p.Tickets) + .Include(p => p.Manager) + .Include(p => p.Files) + .Include(p => p.Activities) + .AsNoTracking() + .Select(p => new ProjectDTO(p)) + .ToListAsync(); } /// @@ -58,12 +67,22 @@ namespace TicketManager.Controllers [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task> GetProject(int id) { - Project project = await _projects.Get(id); + var project = await _context.Projects + .Include(p => p.Assignments) + .ThenInclude(a => a.User) + .Include(p => p.Tickets) + .Include(p => p.Manager) + .Include(p => p.Files) + .Include(p => p.Activities) + .AsNoTracking() + .Select(p => new ProjectDTO(p)) + .FirstOrDefaultAsync(p => p.Id == id); + if (project == null) { return NotFound(); } - return new ProjectDTO(project); + return project; } /// @@ -90,15 +109,25 @@ namespace TicketManager.Controllers [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task PutProject(int id, Project project) { - if (id != project.Id) { return BadRequest(); } + if (id != project.Id) + { + return BadRequest(); + } + _context.Entry(project).State = EntityState.Modified; try { - await _projects.Update(project); + await _context.SaveChangesAsync(); } catch (DbUpdateConcurrencyException) { - if (!_projects.Exists(id)) { return NotFound(); } - else { throw; } + if (!ProjectExists(id)) + { + return NotFound(); + } + else + { + throw; + } } return NoContent(); } @@ -123,11 +152,16 @@ namespace TicketManager.Controllers [HttpPost] [ProducesResponseType(StatusCodes.Status201Created)] [ProducesResponseType(StatusCodes.Status404NotFound)] - public async Task> PostProject(Project project) + public async Task> PostProject(Project project) { - if (!ModelState.IsValid) { return BadRequest(); } - await _projects.Add(project); - return CreatedAtAction("GetProject", new { id = project.Id }, project); + if (!ModelState.IsValid) + { + return BadRequest(); + } + _context.Projects.Add(project); + await _context.SaveChangesAsync(); + var dto = new ProjectDTO(project); + return CreatedAtAction("GetProject", new { id = project.Id }, dto); } /// @@ -145,13 +179,15 @@ namespace TicketManager.Controllers [HttpDelete("{id}")] public async Task DeleteProject(int id) { - var project = await _projects.Get(id); + var project = await _context.Projects.FindAsync(id); if (project == null) { return NotFound(); } - await _projects.Delete(project); - return Ok(); + _context.Projects.Remove(project); + await _context.SaveChangesAsync(); + var dto = new ProjectDTO(project); + return Ok(dto); } /// @@ -169,9 +205,20 @@ namespace TicketManager.Controllers [HttpGet("{id}/members")] public async Task>> GetProjectMembers(int id) { - var project = await _projects.Get(id); + Project project = await _context.Projects + .Include(p => p.Assignments) + .ThenInclude(a => a.User) + .Include(p => p.Tickets) + .Include(p => p.Manager) + .Include(p => p.Files) + .Include(p => p.Activities) + .AsNoTracking() + .FirstOrDefaultAsync(p => p.Id == id); + if (project == null) - { return NotFound(); } + { + return NotFound(); + } return project.GetMembers(); } @@ -198,15 +245,21 @@ namespace TicketManager.Controllers [HttpPut("{id}/members")] public async Task> SetProjectMembers(int id, List projectMembers) { - Project project = await _projects.Get(id); + Project project = await _context.Projects + .Include(p => p.Assignments) + .FirstOrDefaultAsync(p => p.Id == id); + if (project == null) { return NotFound(); } + project.SetMembers(projectMembers); + _context.Entry(project).State = EntityState.Modified; try { - await _projects.Update(project); + + await _context.SaveChangesAsync(); } catch (DbUpdateException /* ex */) { @@ -218,86 +271,9 @@ namespace TicketManager.Controllers return NoContent(); } - // // /// - // // /// Assign a user to a project. - // // /// - // // /// - // // /// Sample request: - // // /// - // // /// POST: api/v1/Projects/addmembers - // // /// [{ - // // /// "id": "357727fd-5262-4522-b8a3-38271d43de84", - // // /// "firstName": "Thomas", - // // /// "lastName": "Price", - // // /// "presentation": "New Team?!", - // // /// "email": "tp@mail.com", - // // /// "phone": "0198237645" - // // /// }] - // // /// - // // /// - // // /// Returns the created project - // // [ProducesResponseType(StatusCodes.Status204NoContent)] - // // [ProducesResponseType(StatusCodes.Status404NotFound)] - // // [HttpPut("{id}/addMembers")] - // // public async Task> AddMembersToProject(int id, List usersToAdd) - // // { - // // if (usersToAdd == null) - // // { - // // return BadRequest(); - // // } - // // Project project = await GetProjectByIdAsync(id); - // // project.AddMembers(usersToAdd); - // // try - // // { - // // await _context.SaveChangesAsync(); - // // } - // // catch (DbUpdateException /* ex */) - // // { - // // //Log the error (uncomment ex variable name and write a log.) - // // ModelState.AddModelError("", "Unable to save changes. " + - // // "Try again, and if the problem persists, " + - // // "see your system administrator."); - // // } - // // return NoContent(); - // // } - - // // /// - // // /// Remove a user to a project. - // // /// - // // /// - // // /// Sample request: - // // /// - // // /// PUT: api/v1/Projects/removemembers - // // /// [{ - // // /// "id": "357727fd-5262-4522-b8a3-38271d43de84", - // // /// "firstName": "Thomas", - // // /// "lastName": "Price", - // // /// "presentation": "New Team?!", - // // /// "email": "tp@mail.com", - // // /// "phone": "0198237645" - // // /// }] - // // /// - // // /// - // // /// Returns the created project - // // [ProducesResponseType(StatusCodes.Status204NoContent)] - // // [ProducesResponseType(StatusCodes.Status404NotFound)] - // // [HttpPut("{id}/removeMembers")] - // // public async Task> RemoveMembersFromProject(int id, List usersToRemove) - // // { - // // Project project = await GetProjectByIdAsync(id); - // // project.RemoveMembers(usersToRemove); - // // try - // // { - // // await _context.SaveChangesAsync(); - // // } - // // catch (DbUpdateException /* ex */) - // // { - // // //Log the error (uncomment ex variable name and write a log.) - // // ModelState.AddModelError("", "Unable to save changes. " + - // // "Try again, and if the problem persists, " + - // // "see your system administrator."); - // // } - // // return NoContent(); - // // } + private bool ProjectExists(int id) + { + return _context.Projects.Any(e => e.Id == id); + } } } diff --git a/Controllers/TicketsController.cs b/Controllers/TicketsController.cs index 90844f0..cc94ec6 100644 --- a/Controllers/TicketsController.cs +++ b/Controllers/TicketsController.cs @@ -1,9 +1,11 @@ using System.Collections.Generic; +using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using TicketManager.Data; +using TicketManager.DTO; using TicketManager.Models; namespace TicketManager.Controllers @@ -13,25 +15,40 @@ namespace TicketManager.Controllers [ApiController] public class TicketsController : ControllerBase { - private readonly ITicketRepository _tickets; + private readonly AppDbContext _context; - public TicketsController(ITicketRepository tickets) + public TicketsController(AppDbContext context) { - _tickets = tickets; + _context = context; } // GET: api/Tickets [HttpGet] - public async Task> GetTickets() + public async Task> GetTickets() { - return await _tickets.List(); + return await _context.Tickets + .Include(t => t.Project) + .Include(t => t.Files) + .Include(t => t.Activities) + .Include(t => t.Notes) + .AsNoTracking() + .Select(t => new TicketDTO(t)) + .ToListAsync(); } // GET: api/Tickets/5 [HttpGet("{id}")] - public async Task> GetTicket(int id) + public async Task> GetTicket(int id) { - var ticket = await _tickets.Get(id); + var ticket = await _context.Tickets + .Include(t => t.Project) + .Include(t => t.Files) + .Include(t => t.Activities) + .Include(t => t.Notes) + .AsNoTracking() + .Select(t => new TicketDTO(t)) + .FirstOrDefaultAsync(t => t.Id == id); + if (ticket == null) { return NotFound(); @@ -49,13 +66,14 @@ namespace TicketManager.Controllers { return BadRequest(); } + _context.Entry(ticket).State = EntityState.Modified; try { - await _tickets.Update(ticket); + await _context.SaveChangesAsync(); } catch (DbUpdateConcurrencyException) { - if (!_tickets.Exists(id)) + if (!TicketExists(id)) { return NotFound(); } @@ -73,36 +91,56 @@ namespace TicketManager.Controllers [HttpPost] public async Task> PostTicket(Ticket ticket) { - await _tickets.Add(ticket); - return CreatedAtAction("GetTicket", new { id = ticket.Id }, ticket); + _context.Tickets.Add(ticket); + await _context.SaveChangesAsync(); + + var dto = new TicketDTO(ticket); + return CreatedAtAction("GetTicket", new { id = ticket.Id }, dto); } // DELETE: api/Tickets/5 [HttpDelete("{id}")] - public async Task> DeleteTicket(int id) + public async Task> DeleteTicket(int id) { - var ticket = await _tickets.Get(id); + var ticket = await _context.Tickets.FindAsync(id); if (ticket == null) { return NotFound(); } - await _tickets.Delete(ticket); - return ticket; + + _context.Tickets.Remove(ticket); + await _context.SaveChangesAsync(); + + var dto = new TicketDTO(ticket); + return Ok(dto); } [HttpGet("{id}/assignees")] - public async Task>> GetTicketAssignees(int id) + public async Task>> GetTicketAssignees(int id) { - Ticket ticket = await _tickets.Get(id); - return ticket.GetAssignees(); + Ticket ticket = await _context.Tickets + .Include(t => t.Project) + .ThenInclude(p => p.Assignments) + .ThenInclude(a => a.User) + .AsNoTracking() + .FirstOrDefaultAsync(t => t.Id == id); + + return ticket.GetAssignees().Select(u => new AppUserDTO(u)).ToList(); } [HttpPut("{id}/closed")] public async Task CloseTicket(int id) { - Ticket ticket = await _tickets.Get(id); + Ticket ticket = await _context.Tickets.FindAsync(id); ticket.Close(); + // _context.Entry(ticket).State = EntityState.Modified; + return await PutTicket(ticket.Id, ticket); } + + private bool TicketExists(int id) + { + return _context.Tickets.Any(e => e.Id == id); + } } } diff --git a/Data/AppUserRepository.cs b/Data/AppUserRepository.cs deleted file mode 100644 index a8b4a62..0000000 --- a/Data/AppUserRepository.cs +++ /dev/null @@ -1,37 +0,0 @@ -using System.Threading.Tasks; -using TicketManager.Models; -using System.Linq; -using System; -using Microsoft.EntityFrameworkCore; -using System.Collections.Generic; - -namespace TicketManager.Data -{ - public class AppUserRepository : GenericRepository, IAppUserRepository - { - private readonly IQueryable _query; - public AppUserRepository(AppDbContext context) : base(context) - { - _query = _dbSet - .Include(p => p.Assignments) - .ThenInclude(a => a.Project) - .ThenInclude(p => p.Tickets) - .Include(p => p.Activities); - } - - public async Task GetUser(Guid id) - { - return await _query.FirstOrDefaultAsync(p => p.Id == id); - } - - public override async Task> List() - { - return await _query.ToListAsync(); - } - - public bool Exists(Guid id) - { - return _dbSet.Any(e => e.Id == id); - } - } -} \ No newline at end of file diff --git a/Data/GenericRepository.cs b/Data/GenericRepository.cs deleted file mode 100644 index 1a90aa1..0000000 --- a/Data/GenericRepository.cs +++ /dev/null @@ -1,55 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Linq.Expressions; -using System.Threading.Tasks; -using Microsoft.EntityFrameworkCore; - -namespace TicketManager.Data -{ - public class GenericRepository : IGenericRepository where T : class - { - protected readonly AppDbContext _context; - protected readonly DbSet _dbSet; - public GenericRepository(AppDbContext context) - { - _context = context; - _dbSet = _context.Set(); - } - - public async Task Add(T entity) - { - _dbSet.Add(entity); - return await _context.SaveChangesAsync(); - } - - public async Task Delete(T entity) - { - if (_context.Entry(entity).State == EntityState.Detached) - { _dbSet.Attach(entity); } - _dbSet.Remove(entity); - return await _context.SaveChangesAsync(); - } - - public async Task> Find(int id, Expression> expr) - { - return await _dbSet.Where(expr).AsNoTracking().ToListAsync(); - } - - public virtual async Task Get(int id) - { - return await _dbSet.FindAsync(id); - } - public virtual async Task> List() - { - return await _dbSet.AsNoTracking().ToListAsync(); - } - - public async Task Update(T entity) - { - _dbSet.Attach(entity); - _context.Entry(entity).State = EntityState.Modified; - return await _context.SaveChangesAsync(); - } - } -} \ No newline at end of file diff --git a/Data/Interfaces/IAppUserRepository.cs b/Data/Interfaces/IAppUserRepository.cs deleted file mode 100644 index ab57db3..0000000 --- a/Data/Interfaces/IAppUserRepository.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; -using System.Threading.Tasks; -using TicketManager.Models; - -namespace TicketManager.Data -{ - public interface IAppUserRepository : IGenericRepository - { - Task GetUser(Guid id); - bool Exists(Guid id); - } -} \ No newline at end of file diff --git a/Data/Interfaces/IGenericRepository.cs b/Data/Interfaces/IGenericRepository.cs deleted file mode 100644 index 915ef12..0000000 --- a/Data/Interfaces/IGenericRepository.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System; -using System.Linq.Expressions; -using System.Collections.Generic; -using System.Threading.Tasks; - -namespace TicketManager.Data -{ - public interface IGenericRepository where T : class - { - Task> List(); - Task Get(int id); - Task> Find(int id, Expression> expr); - - Task Add(T entity); - - Task Update(T entity); - - Task Delete(T entity); - } -} \ No newline at end of file diff --git a/Data/Interfaces/IProjectRepository.cs b/Data/Interfaces/IProjectRepository.cs deleted file mode 100644 index ea8c756..0000000 --- a/Data/Interfaces/IProjectRepository.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System.Collections.Generic; -using System.Threading.Tasks; -using TicketManager.Models; - -namespace TicketManager.Data -{ - public interface IProjectRepository : IGenericRepository - { - bool Exists(int id); - Task> GetMembers(int id); - Task SetMembers(int id, List usersToAdd); - } -} \ No newline at end of file diff --git a/Data/Interfaces/ITicketRepository.cs b/Data/Interfaces/ITicketRepository.cs deleted file mode 100644 index de8af26..0000000 --- a/Data/Interfaces/ITicketRepository.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System.Collections.Generic; -using System.Threading.Tasks; -using TicketManager.Models; - -namespace TicketManager.Data -{ - public interface ITicketRepository : IGenericRepository - { - bool Exists(int id); - } -} \ No newline at end of file diff --git a/Data/Interfaces/IUnitOfWork.cs b/Data/Interfaces/IUnitOfWork.cs deleted file mode 100644 index eab4e21..0000000 --- a/Data/Interfaces/IUnitOfWork.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System; -using System.Threading.Tasks; - -namespace TicketManager.Data -{ - public interface IUnitOfWork : IDisposable - { - IProjectRepository Projects { get; } - IAppUserRepository AppUsers { get; } - ITicketRepository Tickets { get; } - Task Complete(); - } -} \ No newline at end of file diff --git a/Data/ProjectRepository.cs b/Data/ProjectRepository.cs deleted file mode 100644 index ec8dede..0000000 --- a/Data/ProjectRepository.cs +++ /dev/null @@ -1,47 +0,0 @@ -using System.Threading.Tasks; -using TicketManager.Models; -using System.Linq; -using Microsoft.EntityFrameworkCore; -using System.Collections.Generic; - -namespace TicketManager.Data -{ - public class ProjectRepository : GenericRepository, IProjectRepository - { - private readonly IQueryable _query; - public ProjectRepository(AppDbContext context) : base(context) - { - _query = _dbSet - .Include(p => p.Assignments).ThenInclude(a => a.User) - .Include(p => p.Tickets) - .Include(p => p.Manager) - .Include(p => p.Files); - } - - public override async Task Get(int id) - { - return await _query.FirstOrDefaultAsync(p => p.Id == id); - } - - public override async Task> List() - { - return await _query.ToListAsync(); - } - - public bool Exists(int id) - { - return _dbSet.Any(e => e.Id == id); - } - - public async Task> GetMembers(int id) - { - Project project = await Get(id); - return project.GetMembers(); - } - public async Task SetMembers(int id, List usersToAdd) - { - Project project = await Get(id); - project.SetMembers(usersToAdd); - } - } -} \ No newline at end of file diff --git a/Data/TicketRepository.cs b/Data/TicketRepository.cs deleted file mode 100644 index e142c8f..0000000 --- a/Data/TicketRepository.cs +++ /dev/null @@ -1,40 +0,0 @@ -using System.Collections.Generic; -using System.Threading.Tasks; -using System.Linq; -using TicketManager.Models; -using Microsoft.EntityFrameworkCore; - -namespace TicketManager.Data -{ - public class TicketRepository : GenericRepository, ITicketRepository - { - private IQueryable _query; - public TicketRepository(AppDbContext context) : base(context) - { - _query = _dbSet - .Include(p => p.Project) - .ThenInclude(a => a.Assignments) - .ThenInclude(p => p.User) - // .Include(p => p.Edits) - // .Include(p => p.Notes) - // .Include(p => p.Files) - // .Include(p => p.Creator) - ; - } - - public override async Task Get(int id) - { - return await _query.FirstOrDefaultAsync(p => p.Id == id); - } - - public override async Task> List() - { - return await _query.ToListAsync(); - } - - public bool Exists(int id) - { - return _dbSet.Any(e => e.Id == id); - } - } -} \ No newline at end of file diff --git a/Data/UnitOfWork.cs b/Data/UnitOfWork.cs deleted file mode 100644 index 1a0e21a..0000000 --- a/Data/UnitOfWork.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System; -using System.Threading.Tasks; - -namespace TicketManager.Data -{ - public class UnitOfWork : IUnitOfWork - { - private readonly AppDbContext _context; - public UnitOfWork(AppDbContext context) - { - _context = context; - Projects = new ProjectRepository(_context); - Tickets = new TicketRepository(_context); - AppUsers = new AppUserRepository(_context); - } - - public IProjectRepository Projects { get; private set; } - - public IAppUserRepository AppUsers { get; private set; } - - public ITicketRepository Tickets { get; private set; } - - public async Task Complete() - { - return await _context.SaveChangesAsync(); - } - public void Dispose() - { - _context.DisposeAsync(); - } - } -} \ No newline at end of file diff --git a/DataTransfertObjects/AppUserDTO.cs b/DataTransfertObjects/AppUserDTO.cs new file mode 100644 index 0000000..250fbcc --- /dev/null +++ b/DataTransfertObjects/AppUserDTO.cs @@ -0,0 +1,53 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using TicketManager.Models; + +namespace TicketManager.DTO +{ + public class AppUserDTO + { + public AppUserDTO(AppUser user) + { + Id = user.Id; + FirstName = user.FirstName; + LastName = user.LastName; + Presentation = user.Presentation; + Email = user.Email; + Phone = user.Phone; + Created_at = user.Created_at; + Picture = user.Picture; + Activities = user.Activities; + Projects = user.GetProjects(); + Tickets = user.GetTickets(); + } + + public Guid Id { get; set; } + + public string FirstName { get; set; } + + public string LastName { get; set; } + + public string FullName => $"{FirstName} {LastName}"; + + public string Presentation { get; set; } + + [DataType(DataType.EmailAddress)] + public string Email { get; set; } + + [DataType(DataType.PhoneNumber)] + public string Phone { get; set; } + + [DataType(DataType.Date)] + public DateTime Created_at { get; private set; } = DateTime.Now; + + public string Picture { get; set; } + + public List Activities { get; set; } = new List(); + + public List Projects { get; set; } = new List(); + + public List Tickets { get; set; } = new List(); + + } +} \ No newline at end of file diff --git a/DataTransfertObjects/TicketDTO.cs b/DataTransfertObjects/TicketDTO.cs new file mode 100644 index 0000000..4ff3bae --- /dev/null +++ b/DataTransfertObjects/TicketDTO.cs @@ -0,0 +1,51 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using TicketManager.Models; + +namespace TicketManager.DTO +{ + public class TicketDTO + { + public TicketDTO(Ticket ticket) + { + Id = ticket.Id; + Title = ticket.Title; + Description = ticket.Description; + CreatedAt = ticket.CreatedAt; + PlannedEnding = ticket.PlannedEnding; + Status = ticket.Status.ToString(); + Impact = ticket.Impact.ToString(); + Difficulty = ticket.Difficulty.ToString(); + Category = ticket.Category.ToString(); + CreatorId = ticket.CreatorId; + Project = ticket.Project; + Notes = ticket.Notes; + Activities = ticket.Activities; + Files = ticket.Files; + Users = ticket.GetAssignees(); + } + public int Id { get; set; } + + public string Title { get; set; } + + public string Description { get; set; } + + [DataType(DataType.Date)] + public DateTime CreatedAt { get; private set; } + + [DataType(DataType.Date)] + public DateTime PlannedEnding { get; set; } + + public string Status { get; set; } + public string Impact { get; set; } + public string Difficulty { get; set; } + public string Category { get; set; } + public Guid CreatorId { get; set; } + public Project Project { get; set; } + public List Notes { get; set; } = new List(); + public List Activities { get; set; } = new List(); + public List Files { get; set; } = new List(); + public List Users { get; set; } = new List(); + } +} \ No newline at end of file diff --git a/Models/AppUser.cs b/Models/AppUser.cs index aa762d9..ceb557b 100644 --- a/Models/AppUser.cs +++ b/Models/AppUser.cs @@ -37,7 +37,7 @@ namespace TicketManager.Models public DateTime Created_at { get; private set; } = DateTime.Now; [Display(Name = "Avatar")] - public byte[] Picture { get; set; } + public string Picture { get; set; } public List Assignments { get; set; } = new List(); diff --git a/README.md b/README.md index 17b770b..73fc768 100644 --- a/README.md +++ b/README.md @@ -47,3 +47,4 @@ - [ ] check useRef, useReducer, dispatch - [ ] error page redirect when offline. - [ ] ticket/files/activities list placeholders when empty +- [ ] think about public/private DTO's constructor, getters and setters