diff --git a/src/Libraries/Taskist.Service/WorkItems/BacklogItemService.cs b/src/Libraries/Taskist.Service/WorkItems/BacklogItemService.cs index 3e90abe..86480a9 100644 --- a/src/Libraries/Taskist.Service/WorkItems/BacklogItemService.cs +++ b/src/Libraries/Taskist.Service/WorkItems/BacklogItemService.cs @@ -75,6 +75,7 @@ public async Task> GetPagedListAsync(int assigneeId, { return await _backlogRepository.GetAllPagedAsync(query => { + query = query.Where(x => !x.Deleted); //r if (projectId > 0) query = query.Where(x => x.ProjectId == projectId); else @@ -186,7 +187,7 @@ await _backlogCommentRepository.InsertAsync(new BacklogComment BacklogId = entity.Id, CreatedById = entity.CreatedById, CreatedOn = DateTime.UtcNow, - Comment = $"New {entity.TaskType.Name} created.", + Comment = $"New {entity.TaskType?.Name} ?? backlog created.", //r SystemComment = true }); @@ -283,6 +284,18 @@ public async Task DeleteAsync(Backlog entity) await _backlogRepository.DeleteAsync(entity); } + public async Task DeleteBacklogAsync(int id) //r + { + var entity = await _backlogRepository.GetByIdAsync(id); + if (entity == null) + throw new ArgumentNullException(nameof(entity)); + + entity.Deleted = true; + + await _backlogRepository.UpdateAsync(entity); + } + + #endregion #region Methods For Documents diff --git a/src/Libraries/Taskist.Service/WorkItems/IBacklogItemService.cs b/src/Libraries/Taskist.Service/WorkItems/IBacklogItemService.cs index 4af4334..b7b1192 100644 --- a/src/Libraries/Taskist.Service/WorkItems/IBacklogItemService.cs +++ b/src/Libraries/Taskist.Service/WorkItems/IBacklogItemService.cs @@ -51,10 +51,11 @@ Task> GetAllForExcelExportAsync(int assigneeId, Task DeleteAsync(Backlog entity); + Task DeleteBacklogAsync(int id); - #region Documents + #region Documents - Task> GetAllDocumentAsync(int backlogId); + Task> GetAllDocumentAsync(int backlogId); Task GetDocumentByIdAsync(int id); diff --git a/src/Presentation/Taskist.Web/Controllers/Masters/ProjectController.cs b/src/Presentation/Taskist.Web/Controllers/Masters/ProjectController.cs index f4f7802..1e2a0bb 100644 --- a/src/Presentation/Taskist.Web/Controllers/Masters/ProjectController.cs +++ b/src/Presentation/Taskist.Web/Controllers/Masters/ProjectController.cs @@ -184,6 +184,7 @@ public async Task AddMember(UserProjectModel model) CanReport = model.CanReport, CanEdit = model.CanEdit, CanReOpen = model.CanReOpen, + CanDelete =model.CanDelete, CanClose = model.CanClose, CanComment = model.CanComment, CanViewOthersTask = model.CanViewOthersTask, @@ -231,8 +232,19 @@ public async Task EditMember(UserProjectModel model) if (ModelState.IsValid) { var entity = await _projectService.GetMemberByIdAsync(model.Id); - entity = _mapper.Map(model, entity); - + if (entity == null) + return Json(new JsonResponseModel { Status = HttpStatusCodeEnum.NoData }); + + entity.CanReport = model.CanReport; + entity.CanEdit = model.CanEdit; + entity.CanReOpen = model.CanReOpen; + entity.CanDelete = model.CanDelete; + entity.CanClose = model.CanClose; + entity.CanComment = model.CanComment; + entity.CanViewOthersTask = model.CanViewOthersTask; + entity.CanEditOthersTask = model.CanEditOthersTask; + + await _projectService.UpdateMemberAsync(entity); await _userActivityService.InsertAsync("ProjectMember", string.Format(await _localizationService.GetResourceAsync("Log.RecordUpdated"), entity.User.Name), entity); @@ -241,7 +253,7 @@ public async Task EditMember(UserProjectModel model) { Status = HttpStatusCodeEnum.Success, Message = await _localizationService.GetResourceAsync("Message.UpdateSuccess") - }); + }); } return Json(new JsonResponseModel @@ -419,6 +431,7 @@ public async Task DataReadMember(int projectId, DataTableRequest CanReport = x.CanReport, CanEdit = x.CanEdit, CanClose = x.CanClose, + CanDelete = x.CanDelete, CanReOpen = x.CanReOpen, CanComment = x.CanComment }), diff --git a/src/Presentation/Taskist.Web/Controllers/WorkItems/BacklogController.cs b/src/Presentation/Taskist.Web/Controllers/WorkItems/BacklogController.cs index 1d9cdec..77c7a45 100644 --- a/src/Presentation/Taskist.Web/Controllers/WorkItems/BacklogController.cs +++ b/src/Presentation/Taskist.Web/Controllers/WorkItems/BacklogController.cs @@ -128,7 +128,7 @@ public async Task Create(BacklogModel model, List fieldValues.Any(y => y.CustomFieldId == x.Id && string.IsNullOrEmpty(y.Value))); @@ -193,7 +193,7 @@ public async Task Edit(int id) { var projectAccess = await GetProjectAccess(); if (projectAccess == null || !projectAccess.CanReport && !projectAccess.CanEdit && !projectAccess.CanClose) - return AccessDenied(); + return AccessDenied(); var entity = await _backlogItemService.GetByIdAsync(id); if (entity == null) @@ -202,10 +202,37 @@ public async Task Edit(int id) var model = _mapper.Map(entity); await InitModelAsync(model); + model.CanEdit = await _permissionService.AuthorizeAsync(PermissionProvider.WorkItem.MANAGE_BACKLOGLOG); + model.CanDelete = await _permissionService.AuthorizeAsync(PermissionProvider.WorkItem.MANAGE_BACKLOGLOG); return View(model); } + [HttpPost("DeleteBacklog")] + [ValidateAntiForgeryToken] + [CheckPermission(PermissionProvider.WorkItem.MANAGE_BACKLOGLOG)] + public async Task DeleteBacklogAsync(int id) + { + + // check permission + if (!await _permissionService.AuthorizeAsync(PermissionProvider.WorkItem.MANAGE_BACKLOGLOG)) + return Forbid(); + + var backlog = await _backlogItemService.GetByIdAsync(id); + if (backlog == null) + return NotFound(); + + backlog.Deleted = true; + await _backlogItemService.UpdateAsync(backlog); + + return Json(new + { + success = true, + message = true ? "Backlog File deleted!" : "Oops, unable to delete the file!" + }); + + } + public async Task Filter(int filterMode) { var model = new BacklogModel(); @@ -593,6 +620,7 @@ private async Task GetProjectAccess() CanReport = projectMap != null && projectMap.CanReport, CanEdit = projectMap != null && projectMap.CanEdit, CanClose = projectMap != null && projectMap.CanClose, + CanDelete = projectMap != null && projectMap.CanDelete, CanViewOthersTask = projectMap != null && projectMap.CanViewOthersTask, CanEditOthersTask = projectMap != null && projectMap.CanEditOthersTask }; @@ -615,6 +643,7 @@ private async Task InitModelAsync(BacklogModel model) { var access = await GetProjectAccess(); model.CanEdit = model.AssigneeId == loggedUser.Id || access.CanEditOthersTask; + model.CanDelete = access.CanDelete; } foreach (var item in taskTypes) { diff --git a/src/Presentation/Taskist.Web/Helpers/Mapping/AutoMapperProfile.cs b/src/Presentation/Taskist.Web/Helpers/Mapping/AutoMapperProfile.cs index f3df26c..5a3690e 100644 --- a/src/Presentation/Taskist.Web/Helpers/Mapping/AutoMapperProfile.cs +++ b/src/Presentation/Taskist.Web/Helpers/Mapping/AutoMapperProfile.cs @@ -59,7 +59,9 @@ public AutoMapperProfile() CreateMap().ReverseMap() .ForMember(dest => dest.Code, act => act.Ignore()) - .ForMember(dest => dest.AssigneeId, opt => opt.MapFrom(src => src.AssigneeId == -1 ? (int?)null : src.AssigneeId)); + .ForMember(dest => dest.AssigneeId, opt => opt.MapFrom(src => src.AssigneeId == -1 ? (int?)null : src.AssigneeId)) + .ForMember(dest => dest.SprintId, opt => opt.MapFrom(src => src.SprintId == -1 ? (int?)null : src.SprintId)) + .ForMember(dest => dest.ReporterId, opt => opt.MapFrom(src => src.ReporterId == -1 ? (int?)null : src.ReporterId)); CreateMap().ReverseMap(); CreateMap(); diff --git a/src/Presentation/Taskist.Web/Models/Users/UserProjectModel.cs b/src/Presentation/Taskist.Web/Models/Users/UserProjectModel.cs index 49bc739..a9d9d6e 100644 --- a/src/Presentation/Taskist.Web/Models/Users/UserProjectModel.cs +++ b/src/Presentation/Taskist.Web/Models/Users/UserProjectModel.cs @@ -27,7 +27,10 @@ public UserProjectModel() [LocalizedDisplayName("UserProjectModel.CanClose")] public bool CanClose { get; set; } - [LocalizedDisplayName("UserProjectModel.CanReOpen")] + [LocalizedDisplayName("UserProjectModel.CanDelete")] + public bool CanDelete { get; set; } + + [LocalizedDisplayName("UserProjectModel.CanReOpen")] public bool CanReOpen { get; set; } [LocalizedDisplayName("UserProjectModel.CanComment")] @@ -52,7 +55,9 @@ public class UserProjectGridModel : BaseModel public bool CanClose { get; set; } - public bool CanReOpen { get; set; } + public bool CanDelete { get; set; } + + public bool CanReOpen { get; set; } public bool CanComment { get; set; } } \ No newline at end of file diff --git a/src/Presentation/Taskist.Web/Models/WorkItems/BacklogModel.cs b/src/Presentation/Taskist.Web/Models/WorkItems/BacklogModel.cs index 4ddeda6..44324f6 100644 --- a/src/Presentation/Taskist.Web/Models/WorkItems/BacklogModel.cs +++ b/src/Presentation/Taskist.Web/Models/WorkItems/BacklogModel.cs @@ -77,6 +77,8 @@ public BacklogModel() public bool CanEdit { get; set; } + public bool CanDelete { get; set; } + [LocalizedDisplayName("BacklogTask.CreatedBy")] public int CreatedById { get; set; } diff --git a/src/Presentation/Taskist.Web/Models/WorkItems/BacklogPageModel.cs b/src/Presentation/Taskist.Web/Models/WorkItems/BacklogPageModel.cs index 570b3eb..d2a3a38 100644 --- a/src/Presentation/Taskist.Web/Models/WorkItems/BacklogPageModel.cs +++ b/src/Presentation/Taskist.Web/Models/WorkItems/BacklogPageModel.cs @@ -10,6 +10,8 @@ public class BacklogPageModel public bool CanClose { get; set; } + public bool CanDelete { get; set; } + public bool CanReOpen { get; set; } public bool CanComment { get; set; } diff --git a/src/Presentation/Taskist.Web/Views/Backlog/Edit.cshtml b/src/Presentation/Taskist.Web/Views/Backlog/Edit.cshtml index a557e51..fa2eede 100644 --- a/src/Presentation/Taskist.Web/Views/Backlog/Edit.cshtml +++ b/src/Presentation/Taskist.Web/Views/Backlog/Edit.cshtml @@ -21,6 +21,14 @@ @Localize("Button.Cancel") + @Html.AntiForgeryToken() + @if (Model.CanDelete) + { + + } + @@ -35,7 +43,40 @@ + \ No newline at end of file + + + diff --git a/src/Presentation/Taskist.Web/Views/Project/Members.cshtml b/src/Presentation/Taskist.Web/Views/Project/Members.cshtml index 83e4392..957e797 100644 --- a/src/Presentation/Taskist.Web/Views/Project/Members.cshtml +++ b/src/Presentation/Taskist.Web/Views/Project/Members.cshtml @@ -65,6 +65,10 @@ new ColumnConditionModel { Value = "true", Operator = OperatorEnum.EQUAL, Icon = "fa fa-check", TextColor = "#2eb85c" }, new ColumnConditionModel { Value = "false", Operator = OperatorEnum.EQUAL, Icon = "fa fa-times", TextColor = "#e55353" } }}, + new ColumnModel { Title = Localize("ProjectMemberGrid.CanDelete").Text, DataColumn = "CanDelete", Conditions = new List{ + new ColumnConditionModel { Value = "true", Operator = OperatorEnum.EQUAL, Icon = "fa fa-check", TextColor = "#2eb85c" }, + new ColumnConditionModel { Value = "false", Operator = OperatorEnum.EQUAL, Icon = "fa fa-times", TextColor = "#e55353" } + }}, new ColumnModel { Title = Localize("ProjectMemberGrid.CanReOpen").Text, DataColumn = "CanReOpen", Conditions = new List{ new ColumnConditionModel { Value = "true", Operator = OperatorEnum.EQUAL, Icon = "fa fa-check", TextColor = "#2eb85c" }, new ColumnConditionModel { Value = "false", Operator = OperatorEnum.EQUAL, Icon = "fa fa-times", TextColor = "#e55353" } diff --git a/src/Presentation/Taskist.Web/Views/Project/_FormMember.cshtml b/src/Presentation/Taskist.Web/Views/Project/_FormMember.cshtml index 4714f92..7b5e40b 100644 --- a/src/Presentation/Taskist.Web/Views/Project/_FormMember.cshtml +++ b/src/Presentation/Taskist.Web/Views/Project/_FormMember.cshtml @@ -37,6 +37,14 @@ +
+
+ +
+