diff --git a/Controllers/AppUsersController.cs b/Controllers/AppUsersController.cs index b12ad0e..f93ade2 100644 --- a/Controllers/AppUsersController.cs +++ b/Controllers/AppUsersController.cs @@ -8,12 +8,12 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using TicketManager.Data; using TicketManager.Models; -using TicketManager.DTO; +using TicketManager.Resources; namespace TicketManager.Controllers { - // [Authorize] + [Authorize] [Produces("application/json")] [Route("api/v1/users")] [ApiController] diff --git a/Controllers/ProjectsController.cs b/Controllers/ProjectsController.cs index 083eae4..c06bfb0 100644 --- a/Controllers/ProjectsController.cs +++ b/Controllers/ProjectsController.cs @@ -7,13 +7,13 @@ using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using TicketManager.Data; using TicketManager.Models; -using TicketManager.DTO; +using TicketManager.Resources; using System; namespace TicketManager.Controllers { // [Authorize(Roles = "Admin")] - // [Authorize] + [Authorize] [Produces("application/json")] [Route("api/v1/[controller]")] [ApiController] @@ -180,6 +180,9 @@ namespace TicketManager.Controllers EndingDate = projectDto.EndingDate, Manager = await _context.AppUsers.FindAsync(projectDto.ManagerId) }; + // project.LogAction( + // $"{project.Title} has been created by {project.Manager.FullName}.", + // ActivityType.StartTask); _context.Projects.Add(project); await _context.SaveChangesAsync(); diff --git a/Controllers/TicketsController.cs b/Controllers/TicketsController.cs index 7ee7035..4895621 100644 --- a/Controllers/TicketsController.cs +++ b/Controllers/TicketsController.cs @@ -5,12 +5,12 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using TicketManager.Data; -using TicketManager.DTO; +using TicketManager.Resources; using TicketManager.Models; namespace TicketManager.Controllers { - // [Authorize] + [Authorize] [Route("api/v1/[controller]")] [ApiController] public class TicketsController : ControllerBase diff --git a/Models/Activity.cs b/Models/Activity.cs index 549adf2..60a98a9 100644 --- a/Models/Activity.cs +++ b/Models/Activity.cs @@ -8,7 +8,7 @@ namespace TicketManager.Models public string Description { get; set; } public DateTime UpdateDate { get; private set; } = DateTime.Now; public ActivityType ActivityType { get; set; } = ActivityType.Undefined; - public AppUser User { get; set; } - public int UserId { get; set; } + // public Guid UserId { get; set; } + public int TaskId { get; set; } } } \ No newline at end of file diff --git a/Models/AppUser.cs b/Models/AppUser.cs index 28c0660..9dd2315 100644 --- a/Models/AppUser.cs +++ b/Models/AppUser.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; +using System.Text.Json.Serialization; namespace TicketManager.Models { @@ -39,6 +40,7 @@ namespace TicketManager.Models [Display(Name = "Avatar")] public string Picture { get; set; } + [JsonIgnore] public List Assignments { get; set; } = new List(); [Display(Name = "Activity")] diff --git a/Models/Interfaces/ITask.cs b/Models/Interfaces/ITask.cs index eba4cf7..fd86e71 100644 --- a/Models/Interfaces/ITask.cs +++ b/Models/Interfaces/ITask.cs @@ -3,25 +3,13 @@ using System.Collections.Generic; namespace TicketManager.Models { - // public interface ITask - public abstract class ITask + public interface ITask { int Id { get; set; } string Title { get; set; } string Description { get; set; } DateTime CreationDate { get; } - DateTime PlannedEnding { get; set; } + DateTime EndingDate { get; set; } List Activities { get; set; } - - public virtual void AddLogEntry(string description)//, User user) - { - Activity Activity = new Activity() - { - Description = description, - ActivityType = ActivityType.Undefined, - // User = user, - }; - Activities.Add(Activity); - } } } diff --git a/Models/Project.cs b/Models/Project.cs index cf32255..e8b3ec3 100644 --- a/Models/Project.cs +++ b/Models/Project.cs @@ -2,7 +2,7 @@ using System; using System.Collections.Generic; using System.Linq; using System.ComponentModel.DataAnnotations; -using TicketManager.DTO; +using System.Text.Json.Serialization; namespace TicketManager.Models { @@ -20,11 +20,13 @@ namespace TicketManager.Models public string Description { get; set; } [DataType(DataType.Date)] - [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = false)] + [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", + ApplyFormatInEditMode = false)] public DateTime CreationDate { get; private set; } = DateTime.Now; [DataType(DataType.Date)] - [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)] + [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", + ApplyFormatInEditMode = true)] public DateTime EndingDate { get; set; } [Display(Name = "Progress")] @@ -45,6 +47,7 @@ namespace TicketManager.Models [Display(Name = "Project Manager")] public AppUser Manager { get; set; } + [JsonIgnore] public List Assignments { get; set; } = new List(); public List Tickets { get; set; } = new List(); @@ -109,5 +112,17 @@ namespace TicketManager.Models { this.Status = Status.Done; } + + public void LogAction(string description, ActivityType type = ActivityType.Undefined)//, Guid userId) + { + Activity Activity = new Activity() + { + Description = description, + ActivityType = type, + TaskId = this.Id, + // UserId = userId + }; + Activities.Add(Activity); + } } } \ No newline at end of file diff --git a/README.md b/README.md index 0eb16a8..a01d101 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,6 @@ - `React` client on the front-end (TypeScript) - [Materialize](https://materializecss.com) CSS librairy for styling -- API: Newtonsoft.Json, to avoid cycle errors - Hosting: ? - Authentication : [Auth0](https://auth0.com/) - Analytics : Google Analytics & Mixpanel @@ -48,6 +47,6 @@ - [ ] error page redirect when offline. - [x] ticket/files/activities list placeholders when empty - [ ] think about public/private DTO's constructor, getters and setters -- [x] write dtos without circular dependencies +- [X] write dtos without circular dependencies. - [ ] use dtoRequest for PutProjects - [ ] render avatarlist after UserModal Update diff --git a/DTOs/AppUser/AppUserDTO.cs b/Resources/AppUser/AppUserDTO.cs similarity index 97% rename from DTOs/AppUser/AppUserDTO.cs rename to Resources/AppUser/AppUserDTO.cs index da918b7..c942884 100644 --- a/DTOs/AppUser/AppUserDTO.cs +++ b/Resources/AppUser/AppUserDTO.cs @@ -4,7 +4,7 @@ using System.ComponentModel.DataAnnotations; using System.Linq; using TicketManager.Models; -namespace TicketManager.DTO +namespace TicketManager.Resources { public class AppUserDTO { diff --git a/DTOs/AppUser/AppUserDTORead.cs b/Resources/AppUser/AppUserDTORead.cs similarity index 97% rename from DTOs/AppUser/AppUserDTORead.cs rename to Resources/AppUser/AppUserDTORead.cs index a814720..494476a 100644 --- a/DTOs/AppUser/AppUserDTORead.cs +++ b/Resources/AppUser/AppUserDTORead.cs @@ -4,7 +4,7 @@ using System.ComponentModel.DataAnnotations; using System.Linq; using TicketManager.Models; -namespace TicketManager.DTO +namespace TicketManager.Resources { public class AppUserDTORead { diff --git a/DTOs/AppUser/NewAppUserDTO.cs b/Resources/AppUser/NewAppUserDTO.cs similarity index 92% rename from DTOs/AppUser/NewAppUserDTO.cs rename to Resources/AppUser/NewAppUserDTO.cs index f99ae3d..824e8fe 100644 --- a/DTOs/AppUser/NewAppUserDTO.cs +++ b/Resources/AppUser/NewAppUserDTO.cs @@ -1,6 +1,6 @@ using System.ComponentModel.DataAnnotations; -namespace TicketManager.DTO +namespace TicketManager.Resources { public class NewAppUserDTO { diff --git a/DTOs/Project/NewProjectDTO.cs b/Resources/Project/NewProjectDTO.cs similarity index 90% rename from DTOs/Project/NewProjectDTO.cs rename to Resources/Project/NewProjectDTO.cs index b696398..e6d1bf9 100644 --- a/DTOs/Project/NewProjectDTO.cs +++ b/Resources/Project/NewProjectDTO.cs @@ -1,7 +1,7 @@ using System; using System.ComponentModel.DataAnnotations; -namespace TicketManager.DTO +namespace TicketManager.Resources { public class NewProjectDTO { diff --git a/DTOs/Project/ProjectDTO.cs b/Resources/Project/ProjectDTO.cs similarity index 97% rename from DTOs/Project/ProjectDTO.cs rename to Resources/Project/ProjectDTO.cs index 6be538a..5da13c7 100644 --- a/DTOs/Project/ProjectDTO.cs +++ b/Resources/Project/ProjectDTO.cs @@ -3,7 +3,7 @@ using System.Linq; using System.Collections.Generic; using TicketManager.Models; -namespace TicketManager.DTO +namespace TicketManager.Resources { public class ProjectDTO { diff --git a/DTOs/Project/ProjectDTORequest.cs b/Resources/Project/ProjectDTORequest.cs similarity index 96% rename from DTOs/Project/ProjectDTORequest.cs rename to Resources/Project/ProjectDTORequest.cs index 374c051..ea14bae 100644 --- a/DTOs/Project/ProjectDTORequest.cs +++ b/Resources/Project/ProjectDTORequest.cs @@ -3,7 +3,7 @@ using System.Linq; using System.Collections.Generic; using TicketManager.Models; -namespace TicketManager.DTO +namespace TicketManager.Resources { public class ProjectDTORequest { diff --git a/DTOs/Tickets/NewTicketDTO.cs b/Resources/Tickets/NewTicketDTO.cs similarity index 94% rename from DTOs/Tickets/NewTicketDTO.cs rename to Resources/Tickets/NewTicketDTO.cs index ef7629c..45864d2 100644 --- a/DTOs/Tickets/NewTicketDTO.cs +++ b/Resources/Tickets/NewTicketDTO.cs @@ -4,7 +4,7 @@ using System.ComponentModel.DataAnnotations; using System.Linq; using TicketManager.Models; -namespace TicketManager.DTO +namespace TicketManager.Resources { public class NewTicketDTO { diff --git a/DTOs/Tickets/TicketDTO.cs b/Resources/Tickets/TicketDTO.cs similarity index 93% rename from DTOs/Tickets/TicketDTO.cs rename to Resources/Tickets/TicketDTO.cs index 3d7154f..46cfe75 100644 --- a/DTOs/Tickets/TicketDTO.cs +++ b/Resources/Tickets/TicketDTO.cs @@ -4,7 +4,7 @@ using System.ComponentModel.DataAnnotations; using System.Linq; using TicketManager.Models; -namespace TicketManager.DTO +namespace TicketManager.Resources { public class TicketDTO { @@ -20,7 +20,7 @@ namespace TicketManager.DTO Difficulty = ticket.Difficulty.ToString(); Category = ticket.Category.ToString(); CreatorId = ticket.CreatorId; - Project = new ProjectDTORequest(ticket.Project); + Project = ticket.Project != null ? new ProjectDTORequest(ticket.Project) : null; Notes = ticket.Notes; Activities = ticket.Activities; Files = ticket.Files; diff --git a/DTOs/Tickets/TicketDTORead.cs b/Resources/Tickets/TicketDTORead.cs similarity index 97% rename from DTOs/Tickets/TicketDTORead.cs rename to Resources/Tickets/TicketDTORead.cs index edf131d..620a044 100644 --- a/DTOs/Tickets/TicketDTORead.cs +++ b/Resources/Tickets/TicketDTORead.cs @@ -4,7 +4,7 @@ using System.ComponentModel.DataAnnotations; using System.Linq; using TicketManager.Models; -namespace TicketManager.DTO +namespace TicketManager.Resources { public class TicketDTORead { diff --git a/Startup.cs b/Startup.cs index 0d096d2..e358b50 100644 --- a/Startup.cs +++ b/Startup.cs @@ -12,9 +12,7 @@ using Microsoft.Extensions.Logging; using Microsoft.AspNetCore.SpaServices.ReactDevelopmentServer; using Microsoft.EntityFrameworkCore; using Microsoft.OpenApi.Models; -using Microsoft.AspNetCore.Mvc.NewtonsoftJson; using Microsoft.AspNetCore.Authentication.JwtBearer; -using Newtonsoft.Json; using TicketManager.Data; [assembly: ApiController] @@ -48,12 +46,7 @@ namespace TicketManager options.Audience = "https://localhost:5001/api/V1/"; }); - services.AddControllers() - .AddNewtonsoftJson(options => - { - options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; // avoid cycle ref errors - } - ); + services.AddControllers(); services.AddSpaStaticFiles(configuration => { diff --git a/Tests/TicketManager.Tests/UnitTests/ControllersTests/ProjectControllerTests.cs b/Tests/TicketManager.Tests/UnitTests/ControllersTests/ProjectControllerTests.cs index 43892b1..8748691 100644 --- a/Tests/TicketManager.Tests/UnitTests/ControllersTests/ProjectControllerTests.cs +++ b/Tests/TicketManager.Tests/UnitTests/ControllersTests/ProjectControllerTests.cs @@ -8,7 +8,7 @@ using Microsoft.Data.Sqlite; using TicketManager.Controllers; using TicketManager.Data; using TicketManager.Models; -using TicketManager.DTO; +using TicketManager.Resources; namespace TicketManager.Tests diff --git a/client/src/components/UsersModal.tsx b/client/src/components/UsersModal.tsx index 3507907..7d88fd7 100644 --- a/client/src/components/UsersModal.tsx +++ b/client/src/components/UsersModal.tsx @@ -1,4 +1,4 @@ -import React, { FC, useState, ChangeEvent, useEffect, FormEvent } from "react"; +import React, { FC, useState, ChangeEvent, FormEvent, useEffect } from "react"; import { Modal } from "./Modal"; import { AvatarList } from "./AvatarList"; import { User } from "../types/User"; @@ -10,9 +10,9 @@ import { useParams } from "react-router-dom"; interface IProps { show: boolean; - handleClose: () => void; users: User[]; allUsers: User[]; + handleClose(): void; } export const UsersModal: FC = ({ diff --git a/client/src/controllers/ErrorController.tsx b/client/src/controllers/ErrorController.tsx index 4376691..0f00683 100644 --- a/client/src/controllers/ErrorController.tsx +++ b/client/src/controllers/ErrorController.tsx @@ -2,7 +2,7 @@ import React, { FC } from "react"; import { Redirect } from "react-router-dom"; interface IProps { - error: any; + error: string; } export const ErrorController: FC = ({ error }) => { @@ -10,6 +10,9 @@ export const ErrorController: FC = ({ error }) => { case "Bad Request": return ; + case "Unauthorized": + return ; + case "Not Found": return ; diff --git a/client/src/controllers/ProjectController.tsx b/client/src/controllers/ProjectController.tsx index 6db808b..0252cd5 100644 --- a/client/src/controllers/ProjectController.tsx +++ b/client/src/controllers/ProjectController.tsx @@ -28,6 +28,7 @@ export const ProjectController: FC = () => { setIsLoading(false); } } catch (ex) { + console.error(ex); setHasError(true); setError(ex); } @@ -42,8 +43,8 @@ export const ProjectController: FC = () => { setAllUsers((response.parsedBody as unknown) as User[]); } } catch (ex) { - // setHasError(true); - // setError(ex); + setHasError(true); + setError(ex); } } diff --git a/client/src/utils/http.ts b/client/src/utils/http.ts index a600ab9..e3bc88e 100644 --- a/client/src/utils/http.ts +++ b/client/src/utils/http.ts @@ -56,5 +56,7 @@ export async function patch( const headers: Headers = new Headers({ Accept: "application/json", - "Content-Type": "application/json" + "Content-Type": "application/json", + Authorization: + "Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6Ik1UWkNSRFEzUkRnd1FUQXlNRFExTmtOQ09UQXlSamhGTURaRU1Ea3pNRGxHUkRrelFqZENSZyJ9.eyJpc3MiOiJodHRwczovL2Rldi1meWpydm9oeC5hdXRoMC5jb20vIiwic3ViIjoiR3dlZTlGUnN3ejNWNE5vZFVRTjJIcjJyQjJTMDI1UmZAY2xpZW50cyIsImF1ZCI6Imh0dHBzOi8vbG9jYWxob3N0OjUwMDEvYXBpL1YxLyIsImlhdCI6MTU4Mjk3MTQyMSwiZXhwIjoxNTgzMDU3ODIxLCJhenAiOiJHd2VlOUZSc3d6M1Y0Tm9kVVFOMkhyMnJCMlMwMjVSZiIsImd0eSI6ImNsaWVudC1jcmVkZW50aWFscyJ9.mH_ejE0gpMXrMIVUV7afuagTopCxm2x7F7Ash9L7zfOCQnw71E7NPsEh8w2_nFFz3lwm988vGbJhB_1G0oetK3VnqgahHn-ZJfk8RhQeKZQtCddbFCXSZzbsvi8XekpN2qLSZswrfxM4hiNfedQW1sM6wSbVbv4q6MrpPrtnepOo5lu67b9eHQZA5MQGqCLqqAZtEAa4Z8bVUCUcf3wU4e9W38LngrMSEMN62_ZZ8AVnjFVQ97zWEadJhYT54S9tVioY8jNR-38qjuYH_ZP3mVQg8INza9YFiYzIsIgdYufhorb_cSXc1qK1ZhHf4kRHaiHCYan-c9nN9SM9MCYA9A" }); diff --git a/client/src/utils/router.tsx b/client/src/utils/router.tsx index 6b88795..8d99a96 100644 --- a/client/src/utils/router.tsx +++ b/client/src/utils/router.tsx @@ -39,7 +39,7 @@ export const AppRouter = () => { */} - +