using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Web.Mvc; using EnVisage.Code; using EnVisage.Code.BLL; using EnVisage.Code.Cache; using EnVisage.Models; using jQuery.DataTables.Mvc; using EnVisage.App_Start; using System.Web.Script.Serialization; using EnVisage.Code.Validation; namespace EnVisage.Controllers { public class PreferencesItem { public string Key { get; set; } public string Value { get; set; } } [Authorize] public class ViewController : BaseController { /// /// GET: /View/ /// /// Empty view [HttpGet] public ActionResult Index() { //if (!HtmlHelpers.CheckSecurityObjectPermission(null, Areas.Views, AccessLevel.Read)) // return Redirect("/"); return View(); } /// /// Returns JSON View list with filters and sort for jQuery DataTables /// [HttpPost] public JsonResult Index(JQueryDataTablesModel jQueryDataTablesModel) { int totalRecordCount; int searchRecordCount; var views = GetViews(startIndex: jQueryDataTablesModel.iDisplayStart, pageSize: jQueryDataTablesModel.iDisplayLength, sortedColumns: jQueryDataTablesModel.GetSortedColumns(), totalRecordCount: out totalRecordCount, searchRecordCount: out searchRecordCount, searchString: jQueryDataTablesModel.sSearch); return this.DataTablesJson(items: views, totalRecords: totalRecordCount, totalDisplayRecords: searchRecordCount, sEcho: jQueryDataTablesModel.sEcho); } private IEnumerable GetViews(int startIndex, int pageSize, IEnumerable sortedColumns, out int totalRecordCount, out int searchRecordCount, string searchString) { var query = from c in DbContext.Views select new ViewListModel() { Id = c.Id, Name = c.Name }; //filter if (!string.IsNullOrWhiteSpace(searchString)) { query = query.Where(c => c.Name.ToLower().Contains(searchString.ToLower())); } //sort foreach (var sortedColumn in sortedColumns) { switch (sortedColumn.PropertyName) { case "Id": query = sortedColumn.Direction == SortingDirection.Ascending ? query.OrderBy(c => c.Id) : query.OrderByDescending(c => c.Id); break; default: query = sortedColumn.Direction == SortingDirection.Ascending ? query.OrderBy(c => c.Name) : query.OrderByDescending(c => c.Name); break; } } totalRecordCount = DbContext.Views.Count(); searchRecordCount = query.Count(); return query.Skip(startIndex).Take(pageSize).ToList(); } // GET: /View/Edit/5 [HttpGet] public ActionResult Edit(Guid? id, string backController, string backAction) { try { var manager = new ViewManager(DbContext); var model = manager.LoadWithChildCollections(id) ?? new ViewModel(); if ((!id.HasValue) || id.Value.Equals(Guid.Empty)) { model.Watchers = new List() { new Guid(HttpContext.User.Identity.GetID()) }; } model.backController = backController; model.backAction = backAction; return PartialView("_editView", model); } catch (Exception exception) { LogException(exception); } return new HttpStatusCodeResult(HttpStatusCode.InternalServerError); } // POST: /View/Edit/5 [HttpPost] [ValidateAjax] [ValidateAntiForgeryToken] public ActionResult Edit(ViewModel model) { if (model == null) { ModelState.AddModelError(string.Empty, @"Cannot save view. Try again later."); return new FailedJsonResult(ModelState); } if (ContentLocker.IsLock("View", model.Id.ToString(), User.Identity.GetUserName())) { ModelState.AddModelError(string.Empty, @"This view is currently being updated by another user. Please attempt your edit again later."); return new FailedJsonResult(ModelState); } model.TrimStringProperties(); var userIdAsText = User.Identity.GetID(); var userId = new Guid(userIdAsText); if (((model.Teams == null) || (model.Teams.Count < 1)) && ((model.Companies == null) || (model.Companies.Count < 1))) { ModelState.AddModelError(string.Empty, @"At least one Team or Business Unit must be selected"); } if (ModelState.IsValid) { try { var manager = new ViewManager(DbContext); var savedModel = manager.Save(model, userId); DbContext.SaveChanges(); // Redirect client to recently created view, if current user is in watchers list of the view var result = new SuccessContentJsonResult(new { viewId = savedModel.Id, viewName = savedModel.Name, openView = model.Id.Equals(Guid.Empty) && model.Watchers != null && model.Watchers.Contains(userId) }); return result; } catch (BLLException blEx) // handle any system specific error { // display error message if required if (blEx.DisplayError) { ModelState.AddModelError(string.Empty, blEx.Message); } else // if display not requried then display modal form with general error message { LogException(blEx); ModelState.AddModelError(string.Empty, @"Cannot save view. Try again later."); } } catch (Exception exception) // handle any unexpected error { LogException(exception); ModelState.AddModelError(string.Empty, @"Cannot save view. Try again later."); } } return new FailedJsonResult(ModelState); } // GET: /View/Delete/5 [HttpGet] public ActionResult Delete(Guid? id) { try { var manager = new ViewManager(DbContext); var model = (ViewModel)manager.Load(id) ?? new ViewModel(); return PartialView("_deleteView", model); } catch (Exception exception) { LogException(exception); } return new HttpStatusCodeResult(HttpStatusCode.InternalServerError); } [HttpPost] [ValidateAjax] [ValidateAntiForgeryToken] public ActionResult Delete(Guid id) { try { if (ContentLocker.IsLock("View", id.ToString(), User.Identity.GetUserName())) { ModelState.AddModelError(string.Empty, @"This view is currently being updated by another user. Please attempt your delete again later."); return new FailedJsonResult(ModelState); } var manager = new ViewManager(DbContext); var dbObj = manager.Load(id, false); if (dbObj == null) { ModelState.AddModelError(string.Empty, @"System cannot find the specified view. Please reload the page and attempt your delete again later."); return new FailedJsonResult(ModelState); } // Links to view Teams and Companies are deleted by cascade delete constraints var us = DbContext.User2View.Where(u2d => u2d.ViewId == dbObj.Id).ToList(); DbContext.User2View.RemoveRange(us); DbContext.Views.Remove(dbObj); DbContext.SaveChanges(); ContentLocker.RemoveLock("View", dbObj.Id.ToString(), User.Identity.GetUserName()); return new SuccessJsonResult(); } catch (BLLException blEx) { if (blEx.DisplayError) ModelState.AddModelError(string.Empty, blEx.Message); else { LogException(blEx); ModelState.AddModelError(string.Empty, @"System cannot delete view. Try again later."); } } catch (Exception exception) { LogException(exception); ModelState.AddModelError(string.Empty, @"System cannot delete view. Try again later."); } return new FailedJsonResult(ModelState); } [AreaSecurity(area = Areas.MyViews, level = AccessLevel.Read)] public ActionResult Board(Guid? viewId, Guid? companyId) { var model = new ViewBoardModel(); var viewManager = new ViewManager(DbContext); var teamManager = new TeamManager(DbContext); var userId = Guid.Parse(User.Identity.GetID()); var user = new UsersCache().Value.FirstOrDefault(t => t.Id == userId); var views = new ViewManager(DbContext).GetViewsByOwner(userId, user == null ? true : !user.ShowAutomaticViews); if (viewId.HasValue) { var vw = views.FirstOrDefault(x => x.Id == viewId); if (vw == null) return RedirectToAccessDenied(); model.Views.Add(vw); model.IsVirtualCompanyView = vw.CompanyId.HasValue; var teams = new ViewManager(DbContext).GetTeamsWithResourcesByUser(vw.Id, userId); model.Teams = teams.OrderBy(x => x.Name).ToList(); } else if (companyId.HasValue) { var vw = views.FirstOrDefault(x => x.Id == companyId && x.CompanyId.HasValue && companyId == x.CompanyId); if (vw == null) return RedirectToAccessDenied(); model.Views.Add(vw); model.IsVirtualCompanyView = vw.CompanyId.HasValue; var teams = teamManager.GetTeamsByCompanyId(companyId.Value); model.Teams = teamManager.LoadTeamsWithResourcesByUser(userId, teams.Select(x => x.TeamId).ToList()).ToList(); } else if (views.Any()) { var defaultView = views.OrderBy(x => x.Name).FirstOrDefault(); if (defaultView == null) return RedirectToAccessDenied(); model.Views.Add(defaultView); model.IsVirtualCompanyView = defaultView.CompanyId.HasValue; var teams = viewManager.GetTeamsWithResourcesByUser(defaultView.Id, userId); model.Teams = teams.OrderBy(x => x.Name).ToList(); } SetUserSelectedViewId(model); return View(model); } /// /// Set initially selected view according to user preferences /// /// private void SetUserSelectedViewId(ViewBoardModel model) { Guid selectedViewId = Guid.Empty; string userIdAsText = User.Identity.GetID(); Guid userId = new Guid(userIdAsText); if (HttpContext.Request.Url != null) { string pageUrl = HttpContext.Request.Url.AbsolutePath; var prefRecords = DbContext.UserPreferences.Where(x => x.UserId.Equals(userId) && x.Url.Equals(pageUrl, StringComparison.InvariantCultureIgnoreCase) && x.Section.Equals("viewsBlock", StringComparison.InvariantCultureIgnoreCase)); if (prefRecords.Any()) { string prefData = prefRecords.First().Data; JavaScriptSerializer ser = new JavaScriptSerializer(); var data = ser.Deserialize>(prefData); var selectedViewPrefs = data.Where(x => x.Key.Equals("pageSelectedView", StringComparison.InvariantCultureIgnoreCase) && x.Value.Length > 0).ToList(); if (selectedViewPrefs.Count > 0) Guid.TryParse(selectedViewPrefs.First().Value, out selectedViewId); } } if (model.Views.Count > 0) { List viewIds = model.Views.Select(x => x.Id).ToList(); if (!selectedViewId.Equals(Guid.Empty) && viewIds.Contains(selectedViewId)) { model.Id = selectedViewId; model.SelectedViewName = model.Views.Where(x => x.Id.Equals(selectedViewId)).Select(x => x.Name).First(); } else { model.Id = viewIds.First(); model.SelectedViewName = model.Views.First().Name; } } } // GET: /View/Details/5 [HttpGet] public ActionResult Details(Guid? id) { if (id == null || id == Guid.Empty) return new HttpStatusCodeResult(HttpStatusCode.BadRequest); var model = new ViewModel(); try { var manager = new ViewManager(DbContext); model = (ViewModel)manager.Load(id) ?? new ViewModel(); if (model.Id == Guid.Empty) return HttpNotFound(); } catch (BLLException blEx) { if (blEx.DisplayError) SetErrorScript(message: blEx.Message); else { LogException(blEx); SetErrorScript(); } } catch (Exception exception) { LogException(exception); SetErrorScript(); } return PartialView("_details", model); } } }