mirror of
https://github.com/rjNemo/ticket_manager
synced 2026-06-06 08:46:39 +00:00
applying dto pattern
This commit is contained in:
parent
eec20793bc
commit
deb3492475
18 changed files with 102 additions and 117 deletions
|
|
@ -70,14 +70,13 @@ namespace TicketManager.Controllers
|
|||
.ThenInclude(a => a.Project)
|
||||
.Include(u => u.Activities)
|
||||
.AsNoTracking()
|
||||
.Select(u => new AppUserDTO(u))
|
||||
.FirstOrDefaultAsync(u => u.Id == id);
|
||||
|
||||
if (user == null)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
return user;
|
||||
return new AppUserDTO(user);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ namespace TicketManager.Controllers
|
|||
{
|
||||
return await _context.Projects
|
||||
.Include(p => p.Assignments)
|
||||
.ThenInclude(a => a.User)
|
||||
.ThenInclude(a => a.User)
|
||||
.Include(p => p.Tickets)
|
||||
.Include(p => p.Manager)
|
||||
.Include(p => p.Files)
|
||||
|
|
@ -76,14 +76,13 @@ namespace TicketManager.Controllers
|
|||
.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 project;
|
||||
return new ProjectDTO(project);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -247,7 +246,7 @@ namespace TicketManager.Controllers
|
|||
public async Task<ActionResult<Project>> SetProjectMembers(int id, List<AppUser> projectMembers)
|
||||
{
|
||||
Project project = await _context.Projects
|
||||
.Include(p => p.Assignments)
|
||||
// .Include(p => p.Assignments)
|
||||
.FirstOrDefaultAsync(p => p.Id == id);
|
||||
|
||||
if (project == null)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Linq;
|
||||
using TicketManager.Models;
|
||||
|
||||
namespace TicketManager.DTO
|
||||
|
|
@ -15,11 +16,11 @@ namespace TicketManager.DTO
|
|||
Presentation = user.Presentation;
|
||||
Email = user.Email;
|
||||
Phone = user.Phone;
|
||||
Created_at = user.Created_at;
|
||||
CreationDate = user.CreationDate;
|
||||
Picture = user.Picture;
|
||||
Activities = user.Activities;
|
||||
Projects = user.GetProjects();
|
||||
Tickets = user.GetTickets();
|
||||
Projects = user.GetProjects().Select(u => new ProjectDTO(u)).ToList();
|
||||
Tickets = user.GetTickets().Select(u => new TicketDTO(u)).ToList();
|
||||
}
|
||||
|
||||
public Guid Id { get; set; }
|
||||
|
|
@ -39,14 +40,14 @@ namespace TicketManager.DTO
|
|||
public string Phone { get; set; }
|
||||
|
||||
[DataType(DataType.Date)]
|
||||
public DateTime Created_at { get; private set; } = DateTime.Now;
|
||||
public DateTime CreationDate { get; private set; } = DateTime.Now;
|
||||
|
||||
public string Picture { get; set; }
|
||||
|
||||
public List<Activity> Activities { get; set; } = new List<Activity>();
|
||||
|
||||
public List<Project> Projects { get; set; } = new List<Project>();
|
||||
public List<ProjectDTO> Projects { get; set; } = new List<ProjectDTO>();
|
||||
|
||||
public List<Ticket> Tickets { get; set; } = new List<Ticket>();
|
||||
public List<TicketDTO> Tickets { get; set; } = new List<TicketDTO>();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using TicketManager.Models;
|
||||
|
||||
|
|
@ -11,12 +12,13 @@ namespace TicketManager.DTO
|
|||
Id = project.Id;
|
||||
Title = project.Title;
|
||||
Description = project.Description;
|
||||
CreatedAt = project.CreatedAt;
|
||||
CreationDate = project.CreationDate;
|
||||
EndingDate = project.EndingDate;
|
||||
Progression = project.Progression;
|
||||
Status = project.Status.ToString();
|
||||
Manager = project.Manager;
|
||||
Users = project.GetMembers();
|
||||
Tickets = project.Tickets;
|
||||
// Manager = project.Manager != null ? new AppUserDTO(project.Manager) : null;
|
||||
Users = project.GetMembers().Select(u => new AppUserDTO(u)).ToList();
|
||||
Tickets = project.Tickets.Select(t => new TicketDTO(t)).ToList();
|
||||
Activities = project.Activities;
|
||||
Files = project.Files;
|
||||
}
|
||||
|
|
@ -27,19 +29,19 @@ namespace TicketManager.DTO
|
|||
|
||||
public string Description { get; set; }
|
||||
|
||||
public DateTime CreatedAt { get; private set; } = DateTime.Now;
|
||||
public DateTime CreationDate { get; private set; } = DateTime.Now;
|
||||
|
||||
public DateTime PlannedEnding { get; set; }
|
||||
public DateTime EndingDate { get; set; }
|
||||
|
||||
public decimal Progression { get; set; }
|
||||
|
||||
public string Status { get; set; }
|
||||
|
||||
public AppUser Manager { get; set; }
|
||||
public AppUserDTO Manager { get; set; }
|
||||
|
||||
public List<AppUser> Users { get; set; } = new List<AppUser>();
|
||||
public List<AppUserDTO> Users { get; set; } = new List<AppUserDTO>();
|
||||
|
||||
public List<Ticket> Tickets { get; set; } = new List<Ticket>();
|
||||
public List<TicketDTO> Tickets { get; set; } = new List<TicketDTO>();
|
||||
|
||||
public List<Activity> Activities { get; set; } = new List<Activity>();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Linq;
|
||||
using TicketManager.Models;
|
||||
|
||||
namespace TicketManager.DTO
|
||||
|
|
@ -12,19 +13,20 @@ namespace TicketManager.DTO
|
|||
Id = ticket.Id;
|
||||
Title = ticket.Title;
|
||||
Description = ticket.Description;
|
||||
CreatedAt = ticket.CreatedAt;
|
||||
PlannedEnding = ticket.PlannedEnding;
|
||||
CreationDate = ticket.CreationDate;
|
||||
EndingDate = ticket.EndingDate;
|
||||
Status = ticket.Status.ToString();
|
||||
Impact = ticket.Impact.ToString();
|
||||
Difficulty = ticket.Difficulty.ToString();
|
||||
Category = ticket.Category.ToString();
|
||||
CreatorId = ticket.CreatorId;
|
||||
Project = ticket.Project;
|
||||
Project = new ProjectDTO(ticket.Project);
|
||||
Notes = ticket.Notes;
|
||||
Activities = ticket.Activities;
|
||||
Files = ticket.Files;
|
||||
Users = ticket.GetAssignees();
|
||||
Users = ticket.GetAssignees().Select(u => new AppUserDTO(u)).ToList();
|
||||
}
|
||||
|
||||
public int Id { get; set; }
|
||||
|
||||
public string Title { get; set; }
|
||||
|
|
@ -32,10 +34,10 @@ namespace TicketManager.DTO
|
|||
public string Description { get; set; }
|
||||
|
||||
[DataType(DataType.Date)]
|
||||
public DateTime CreatedAt { get; private set; }
|
||||
public DateTime CreationDate { get; private set; }
|
||||
|
||||
[DataType(DataType.Date)]
|
||||
public DateTime PlannedEnding { get; set; }
|
||||
public DateTime EndingDate { get; set; }
|
||||
|
||||
public string Status { get; set; }
|
||||
|
||||
|
|
@ -47,7 +49,7 @@ namespace TicketManager.DTO
|
|||
|
||||
public Guid CreatorId { get; set; }
|
||||
|
||||
public Project Project { get; set; }
|
||||
public ProjectDTO Project { get; set; }
|
||||
|
||||
public List<Note> Notes { get; set; } = new List<Note>();
|
||||
|
||||
|
|
@ -55,6 +57,6 @@ namespace TicketManager.DTO
|
|||
|
||||
public List<File> Files { get; set; } = new List<File>();
|
||||
|
||||
public List<AppUser> Users { get; set; } = new List<AppUser>();
|
||||
public List<AppUserDTO> Users { get; set; } = new List<AppUserDTO>();
|
||||
}
|
||||
}
|
||||
|
|
@ -34,7 +34,7 @@ namespace TicketManager.Models
|
|||
|
||||
[DataType(DataType.Date)]
|
||||
[Display(Name = "Member since"), DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}")]
|
||||
public DateTime Created_at { get; private set; } = DateTime.Now;
|
||||
public DateTime CreationDate { get; private set; } = DateTime.Now;
|
||||
|
||||
[Display(Name = "Avatar")]
|
||||
public string Picture { get; set; }
|
||||
|
|
|
|||
|
|
@ -20,11 +20,11 @@ namespace TicketManager.Models
|
|||
|
||||
[DataType(DataType.Date)]
|
||||
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = false)]
|
||||
public DateTime CreatedAt { get; private set; } = DateTime.Now;
|
||||
public DateTime CreationDate { get; private set; } = DateTime.Now;
|
||||
|
||||
[DataType(DataType.Date)]
|
||||
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
|
||||
public DateTime PlannedEnding { get; set; }
|
||||
public DateTime EndingDate { get; set; }
|
||||
|
||||
[Display(Name = "Progress")]
|
||||
public decimal Progression
|
||||
|
|
|
|||
|
|
@ -18,11 +18,11 @@ namespace TicketManager.Models
|
|||
|
||||
[DataType(DataType.Date)]
|
||||
[Display(Name = "Creation Date"), DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}")]
|
||||
public DateTime CreatedAt { get; private set; } = DateTime.Now;
|
||||
public DateTime CreationDate { get; private set; } = DateTime.Now;
|
||||
|
||||
[DataType(DataType.Date)]
|
||||
[Display(Name = "Estimated Ending Date"), DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}")]
|
||||
public DateTime PlannedEnding { get; set; }
|
||||
public DateTime EndingDate { get; set; }
|
||||
|
||||
public Status Status { get; set; } = Status.ToDo;
|
||||
public Impact Impact { get; set; } = Impact.Undefined;
|
||||
|
|
|
|||
|
|
@ -48,3 +48,4 @@
|
|||
- [ ] error page redirect when offline.
|
||||
- [ ] ticket/files/activities list placeholders when empty
|
||||
- [ ] think about public/private DTO's constructor, getters and setters
|
||||
- [ ] write dtos without circular dependencies
|
||||
|
|
|
|||
|
|
@ -1,47 +0,0 @@
|
|||
{
|
||||
"activities" : [],
|
||||
"plannedEnding" : "0001-01-01T00:00:00",
|
||||
"id" : 1,
|
||||
"title" : "Secret Project",
|
||||
"createdAt" : "2020-02-24T10:34:18.428046",
|
||||
"users" : [
|
||||
{
|
||||
"firstName" : "Thomas",
|
||||
"phone" : "0198237645",
|
||||
"lastName" : "Price",
|
||||
"created_at" : "2020-02-25T09:42:54.462374",
|
||||
"presentation" : "New Team?!",
|
||||
"email" : "tp@mail.com",
|
||||
"picture" : null,
|
||||
"activities" : [],
|
||||
"id" : "357727fd-5262-4522-b8a3-38271d43de84",
|
||||
"fullName" : "Thomas Price",
|
||||
"assignments" : [
|
||||
{
|
||||
"project" : {
|
||||
"assignments" : [],
|
||||
"createdAt" : "2020-02-24T10:34:18.428046",
|
||||
"title" : "Secret Project",
|
||||
"id" : 1,
|
||||
"plannedEnding" : "2020-02-17T15:51:02.787373",
|
||||
"activities" : [],
|
||||
"description" : "Shhttt Don't tell anyone",
|
||||
"status" : 1,
|
||||
"files" : [],
|
||||
"tickets" : [],
|
||||
"progression" : 0,
|
||||
"manager" : null
|
||||
},
|
||||
"userId" : "357727fd-5262-4522-b8a3-38271d43de84",
|
||||
"projectId" : 1
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"manager" : null,
|
||||
"progression" : 0,
|
||||
"tickets" : [],
|
||||
"files" : [],
|
||||
"status" : "ToDo",
|
||||
"description" : "Shhttt Don't tell anyone"
|
||||
}
|
||||
15
Startup.cs
15
Startup.cs
|
|
@ -37,9 +37,6 @@ namespace TicketManager
|
|||
options.EnableSensitiveDataLogging(true); //Remove in production.
|
||||
}
|
||||
);
|
||||
// services.AddScoped<IProjectRepository, ProjectRepository>();
|
||||
// services.AddScoped<IAppUserRepository, AppUserRepository>();
|
||||
// services.AddScoped<ITicketRepository, TicketRepository>();
|
||||
|
||||
services.AddAuthentication(options =>
|
||||
{
|
||||
|
|
@ -49,16 +46,14 @@ namespace TicketManager
|
|||
{
|
||||
options.Authority = "https://dev-fyjrvohx.auth0.com/";
|
||||
options.Audience = "https://localhost:5001/api/V1/";
|
||||
//options.Authority = $"https://{Configuration["Auth0:Domain"]}/";
|
||||
//options.Audience = Configuration["Auth0:Audience"];
|
||||
});
|
||||
|
||||
services.AddControllers()
|
||||
.AddNewtonsoftJson(options =>
|
||||
{
|
||||
options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; // avoid cycle ref errors
|
||||
}
|
||||
);
|
||||
.AddNewtonsoftJson(options =>
|
||||
{
|
||||
options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; // avoid cycle ref errors
|
||||
}
|
||||
);
|
||||
|
||||
services.AddSpaStaticFiles(configuration =>
|
||||
{
|
||||
|
|
|
|||
|
|
@ -128,13 +128,13 @@ namespace TicketManager.Tests
|
|||
Id = 1,
|
||||
Title = "Top Secret Project",
|
||||
Description = "Shht Don't Ask don't tell",
|
||||
PlannedEnding = new DateTime(2020, 7, 21)
|
||||
EndingDate = new DateTime(2020, 7, 21)
|
||||
}
|
||||
);
|
||||
|
||||
// Should Update
|
||||
Assert.Equal("Top Secret Project", context.Projects.Find(1).Title);
|
||||
Assert.Equal(new DateTime(2020, 7, 21), context.Projects.Find(1).PlannedEnding);
|
||||
Assert.Equal(new DateTime(2020, 7, 21), context.Projects.Find(1).EndingDate);
|
||||
Assert.IsType<NoContentResult>(result);
|
||||
|
||||
|
||||
|
|
@ -144,13 +144,13 @@ namespace TicketManager.Tests
|
|||
Id = 1,
|
||||
Title = "Top Secret Project",
|
||||
Description = "Shht Don't Ask don't tell",
|
||||
PlannedEnding = new DateTime(2020, 7, 21)
|
||||
EndingDate = new DateTime(2020, 7, 21)
|
||||
}
|
||||
);
|
||||
|
||||
// Should Return BadRequest
|
||||
Assert.NotEqual("Top Secret Project", context.Projects.Find(2).Title);
|
||||
Assert.NotEqual(new DateTime(2020, 7, 21), context.Projects.Find(2).CreatedAt);
|
||||
Assert.NotEqual(new DateTime(2020, 7, 21), context.Projects.Find(2).CreationDate);
|
||||
Assert.IsType<BadRequestResult>(result);
|
||||
|
||||
// Delete updated project
|
||||
|
|
@ -163,14 +163,14 @@ namespace TicketManager.Tests
|
|||
Id = 1,
|
||||
Title = "Top Secret Project",
|
||||
Description = "Shht Don't Ask don't tell",
|
||||
PlannedEnding = new DateTime(2020, 7, 21)
|
||||
EndingDate = new DateTime(2020, 7, 21)
|
||||
}
|
||||
);
|
||||
|
||||
// Should Throw
|
||||
Assert.IsType<NotFoundResult>(result);
|
||||
Assert.Equal("Top Secret Project", context.Projects.Find(1).Title);
|
||||
Assert.Equal(new DateTime(2020, 7, 21), context.Projects.Find(1).PlannedEnding);
|
||||
Assert.Equal(new DateTime(2020, 7, 21), context.Projects.Find(1).EndingDate);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -209,7 +209,7 @@ namespace TicketManager.Tests
|
|||
{
|
||||
Title = "The Third",
|
||||
Description = "Thrice in a row",
|
||||
PlannedEnding = DateTime.Now
|
||||
EndingDate = DateTime.Now
|
||||
};
|
||||
|
||||
var controller = new ProjectsController(context);
|
||||
|
|
@ -237,14 +237,14 @@ namespace TicketManager.Tests
|
|||
Id = 1,
|
||||
Title = "Secret Project",
|
||||
Description = "Shht Don't Ask don't tell",
|
||||
PlannedEnding = new DateTime(2021, 7, 21)
|
||||
EndingDate = new DateTime(2021, 7, 21)
|
||||
},
|
||||
new Project()
|
||||
{
|
||||
Id = 2,
|
||||
Title = "Public Project",
|
||||
Description = "It's quite obvious, isn't it?!",
|
||||
PlannedEnding = new DateTime(2036, 6, 16)
|
||||
EndingDate = new DateTime(2036, 6, 16)
|
||||
});
|
||||
context.SaveChanges();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,32 +9,40 @@ export default class ProjectVM {
|
|||
public id: number;
|
||||
public title: string;
|
||||
public description: string;
|
||||
public value: number;
|
||||
public tickets: Ticket[];
|
||||
public creationDate: string;
|
||||
public endingDate: string;
|
||||
public progression: number;
|
||||
public status: string;
|
||||
public manager: User;
|
||||
public users: User[];
|
||||
public tickets: Ticket[];
|
||||
public files: AppFile[];
|
||||
public activities: Activity[];
|
||||
public allUsers: User[];
|
||||
public ticketsTotalCount: number;
|
||||
public ticketsDone: number;
|
||||
public remainingDays: number;
|
||||
public files: AppFile[];
|
||||
public activities: Activity[];
|
||||
|
||||
public constructor(project: Project, allUsers: User[]) {
|
||||
this.id = project.id;
|
||||
this.title = project.title;
|
||||
this.description = project.description;
|
||||
this.creationDate = project.creationDate;
|
||||
this.endingDate = project.endingDate;
|
||||
this.progression = project.progression;
|
||||
this.status = project.status;
|
||||
this.manager = project.manager;
|
||||
this.users = project.users;
|
||||
this.allUsers = allUsers;
|
||||
this.value = project.progression;
|
||||
this.tickets = project.tickets;
|
||||
this.files = project.files;
|
||||
this.activities = project.activities;
|
||||
this.allUsers = allUsers;
|
||||
this.ticketsTotalCount =
|
||||
this.tickets === undefined ? 0 : this.tickets.length;
|
||||
this.ticketsDone =
|
||||
this.tickets === undefined
|
||||
? 0
|
||||
: this.tickets.filter(t => t.status === "Done").length;
|
||||
this.files = project.files;
|
||||
this.activities = project.activities;
|
||||
this.remainingDays = getRemainingdays(project.plannedEnding);
|
||||
this.remainingDays = getRemainingdays(project.endingDate);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import { AvatarList } from "./AvatarList";
|
|||
import { User } from "../types/User";
|
||||
import { FilterBar } from "./FilterBar";
|
||||
import { HttpResponse } from "../types/HttpResponse";
|
||||
import { get, put } from "../utils/http";
|
||||
import { get, put, patch } from "../utils/http";
|
||||
import { Constants } from "../utils/Constants";
|
||||
import { UsersModalEntry } from "./UsersModalEntry";
|
||||
import { useParams } from "react-router-dom";
|
||||
|
|
@ -38,12 +38,13 @@ export const UsersModal: FC<IProps> = ({
|
|||
) => {
|
||||
e.preventDefault();
|
||||
|
||||
const response: HttpResponse<User[]> = await put<User[]>(
|
||||
const response: HttpResponse<User[]> = await patch<User[]>(
|
||||
`${Constants.projectsURI}/${id}/members`,
|
||||
members
|
||||
);
|
||||
console.log(response);
|
||||
};
|
||||
console.log(allUsers);
|
||||
|
||||
return (
|
||||
<Modal show={show} handleClose={handleClose}>
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ export const ProjectPage: FC<IProps> = ({ viewModel }) => {
|
|||
description,
|
||||
users,
|
||||
allUsers,
|
||||
value,
|
||||
progression,
|
||||
tickets,
|
||||
ticketsDone,
|
||||
ticketsTotalCount,
|
||||
|
|
@ -49,7 +49,7 @@ export const ProjectPage: FC<IProps> = ({ viewModel }) => {
|
|||
/>
|
||||
</div>
|
||||
<ProgressBar
|
||||
value={value}
|
||||
value={progression}
|
||||
tasksDone={ticketsDone}
|
||||
tasksTotalCount={ticketsTotalCount}
|
||||
remainingDays={remainingDays}
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@ export interface Project {
|
|||
id: number;
|
||||
title: string;
|
||||
description: string;
|
||||
createdAt: string;
|
||||
plannedEnding: string;
|
||||
creationDate: string;
|
||||
endingDate: string;
|
||||
progression: number;
|
||||
status: string;
|
||||
manager: User;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,18 @@
|
|||
import { Activity } from "./Activity";
|
||||
import { Project } from "./Project";
|
||||
import { Ticket } from "./Ticket";
|
||||
|
||||
export interface User {
|
||||
id: string;
|
||||
picture: string;
|
||||
firstName: string;
|
||||
fullName?: string;
|
||||
lastName: string;
|
||||
fullName: string;
|
||||
presentation: string;
|
||||
email: string;
|
||||
phone: string;
|
||||
createdAt: string;
|
||||
picture: string;
|
||||
activities: Activity[];
|
||||
projects: Project[];
|
||||
tickets: Ticket[];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,6 +42,18 @@ export async function put<T>(
|
|||
return await http<T>(new Request(path, args));
|
||||
}
|
||||
|
||||
export async function patch<T>(
|
||||
path: string,
|
||||
body: any,
|
||||
args: RequestInit = {
|
||||
method: "patch",
|
||||
headers: headers,
|
||||
body: JSON.stringify(body)
|
||||
}
|
||||
): Promise<HttpResponse<T>> {
|
||||
return await http<T>(new Request(path, args));
|
||||
}
|
||||
|
||||
const headers: Headers = new Headers({
|
||||
Accept: "application/json",
|
||||
"Content-Type": "application/json"
|
||||
|
|
|
|||
Loading…
Reference in a new issue