public async Task <ActionResult> Create(PageEditorVM vm) { if (!ModelState.IsValid) { return(await ViewEditorFormAsync(vm)); } try { var page = await _pages.CreateAsync(vm, User); await _db.SaveChangesAsync(); await _search.AddPageAsync(page); _alarm.FireTreeLayoutRegenerationRequired(); return(RedirectToSuccess("Страница создана")); } catch (ValidationException ex) { SetModelState(ex); return(await ViewEditorFormAsync(vm)); } }
/// <summary> /// Updates the existing draft state. /// </summary> public async Task <PageDraftInfoVM> UpdatePageDraftAsync(PageEditorVM vm, ClaimsPrincipal principal) { var userId = _userMgr.GetUserId(principal); var pageId = vm.Id == Guid.Empty ? null : (Guid?)vm.Id; var draft = await _db.PageDrafts .FirstOrDefaultAsync(x => x.PageId == pageId && x.UserId == userId); if (draft == null) { draft = new PageDraft { Id = Guid.NewGuid(), PageId = pageId, UserId = userId }; _db.PageDrafts.Add(draft); } draft.Content = JsonConvert.SerializeObject(vm); draft.LastUpdateDate = DateTimeOffset.Now; return(new PageDraftInfoVM { LastUpdateDate = draft.LastUpdateDate }); }
/// <summary> /// Displays the editor form. /// </summary> private async Task <ActionResult> ViewEditorFormAsync(PageEditorVM vm, string tab = null, bool displayDraft = false) { var groups = FactDefinitions.Groups[vm.Type]; var editorTpls = groups.SelectMany(x => x.Defs) .Select(x => x.Kind) .Distinct() .Select(x => $"~/Areas/Admin/Views/Pages/Facts/{x.Name}.cshtml") .ToList(); var errorFields = ModelState.Where(x => x.Value.ValidationState == ModelValidationState.Invalid) .Select(x => FieldCaptions.TryGetValue(x.Key)) .JoinString(", "); var photoThumbUrl = await GetMainPhotoThumbnailUrlAsync(vm.MainPhotoKey); var draft = await _pages.GetPageDraftAsync(vm.Id, User); ViewBag.Data = new PageEditorDataVM { IsNew = vm.Id == Guid.Empty, PageTypes = ViewHelper.GetEnumSelectList(vm.Type), FactGroups = groups, EditorTemplates = editorTpls, Tab = StringHelper.Coalesce(tab, "main"), ErrorFields = errorFields, MainPhotoThumbnailUrl = photoThumbUrl, DraftId = draft?.Id, DraftLastUpdateDate = draft?.LastUpdateDate, DraftDisplayNotification = draft != null && displayDraft }; return(View("Editor", vm)); }
/// <summary> /// Creates a default page for the user. /// </summary> public async Task <Page> CreateDefaultUserPageAsync(RegisterUserVM vm, ClaimsPrincipal principal) { var name = new[] { vm.LastName, vm.FirstName, vm.MiddleName } .Where(x => !string.IsNullOrWhiteSpace(x)) .Select(x => x.Trim()) .JoinString(" "); var createVm = new PageEditorVM { Title = name, Description = name, Type = PageType.Person, Facts = new JObject { ["Birth.Date"] = new JObject { ["Value"] = vm.Birthday }, ["Main.Name"] = new JObject { ["Values"] = new JArray { new JObject { ["FirstName"] = vm.FirstName, ["MiddleName"] = vm.MiddleName, ["LastName"] = vm.LastName } } } }.ToString() }; return(await CreateAsync(createVm, principal)); }
public async Task <ActionResult> Update(PageEditorVM vm, string tab) { if (!ModelState.IsValid) { return(await ViewEditorFormAsync(vm, tab)); } try { var page = await _pages.UpdateAsync(vm, User); await _db.SaveChangesAsync(); await _elastic.AddPageAsync(page); _alarm.FireTreeLayoutRegenerationRequired(); return(RedirectToSuccess("Страница обновлена")); } catch (ValidationException ex) { SetModelState(ex); return(await ViewEditorFormAsync(vm, tab)); } }
/// <summary> /// Creates the new page. /// </summary> public async Task <Page> CreateAsync(PageEditorVM vm, ClaimsPrincipal principal) { await ValidateRequestAsync(vm); var key = PageHelper.EncodeTitle(vm.Title); var existingRemoved = await _db.Pages .Where(x => x.Key == key && x.IsDeleted == true) .Select(x => new { x.Id }) .FirstOrDefaultAsync(); if (existingRemoved != null) { return(await UpdateAsync(vm, principal, pageId : existingRemoved.Id)); } var page = _mapper.Map <Page>(vm); page.Id = Guid.NewGuid(); page.CreationDate = DateTimeOffset.Now; page.MainPhoto = await FindMainPhotoAsync(vm.MainPhotoKey); await _validator.ValidateAsync(page, vm.Facts); var changeset = await GetChangesetAsync(null, _mapper.Map <PageEditorVM>(page), page.Id, principal, null); _db.Changes.Add(changeset); _db.Pages.Add(page); _db.PageAliases.AddRange(GetPageAliases(vm.Aliases, vm.Title, page)); _db.PageReferences.AddRange(await GetPageReferencesAsync(vm.Description, page)); await DiscardPageDraftAsync(null, principal); return(page); }
public async Task <ActionResult> Update(PageEditorVM vm) { var info = await _pages.UpdatePageDraftAsync(vm, User); await _db.SaveChangesAsync(); return(Json(info)); }
/// <summary> /// Creates the new page. /// </summary> public async Task <Page> CreateAsync(PageEditorVM vm, ClaimsPrincipal principal) { await ValidateRequestAsync(vm); var key = PageHelper.EncodeTitle(vm.Title); var existingRemoved = await _db.Pages .Where(x => x.Key == key && x.IsDeleted == true) .Select(x => new { x.Id }) .FirstOrDefaultAsync(); if (existingRemoved != null) { return(await UpdateAsync(vm, principal, pageId : existingRemoved.Id)); } var page = _mapper.Map <Page>(vm); page.Id = Guid.NewGuid(); page.CreationDate = DateTimeOffset.Now; page.MainPhoto = await FindMainPhotoAsync(vm.MainPhotoKey); await _validator.ValidateAsync(page, vm.Facts); var changeset = await GetChangesetAsync(null, vm, page.Id, principal, null); _db.Changes.Add(changeset); _db.Pages.Add(page); var aliasValues = JsonConvert.DeserializeObject <List <string> >(vm.Aliases ?? "[]"); if (!aliasValues.Contains(vm.Title)) { aliasValues.Add(vm.Title); } _db.PageAliases.AddRange( aliasValues.Select((x, idx) => new PageAlias { Id = Guid.NewGuid(), Page = page, Key = PageHelper.EncodeTitle(x).ToLowerInvariant(), Title = x, Order = idx } ) ); await DiscardPageDraftAsync(null, principal); return(page); }
/// <summary> /// Updates the changes to a page. /// </summary> public async Task <Page> UpdateAsync(PageEditorVM vm, ClaimsPrincipal principal, Guid?revertedChangeId = null, Guid?pageId = null) { await ValidateRequestAsync(vm); if (pageId == null) { pageId = vm.Id; } var page = await _db.Pages .Include(x => x.Aliases) .Include(x => x.MainPhoto) .GetAsync(x => x.Id == pageId, "Страница не найдена"); await _validator.ValidateAsync(page, vm.Facts); var prevVm = page.IsDeleted ? null : _mapper.Map <PageEditorVM>(page); var changeset = await GetChangesetAsync(prevVm, vm, pageId.Value, principal, revertedChangeId); _db.Changes.Add(changeset); _mapper.Map(vm, page); page.MainPhotoId = (await FindMainPhotoAsync(vm.MainPhotoKey))?.Id; page.IsDeleted = false; await _db.PageAliases.RemoveWhereAsync(x => x.Page.Id == pageId); _db.PageAliases.AddRange(GetPageAliases(vm.Aliases, vm.Title, page)); await _db.PageReferences.RemoveWhereAsync(x => x.SourceId == pageId); _db.PageReferences.AddRange(await GetPageReferencesAsync(vm.Description, page)); if (prevVm?.Title != vm.Title || prevVm?.Facts != vm.Facts) { _cache.Clear(); } else { _cache.Remove <PageDescriptionVM>(page.Key); _cache.Remove <InfoBlockVM>(page.Key); } if (revertedChangeId == null) { await DiscardPageDraftAsync(vm.Id, principal); } return(page); }
/// <summary> /// Creates the new page. /// </summary> public async Task <Page> CreateAsync(PageEditorVM vm, ClaimsPrincipal principal) { await ValidateRequestAsync(vm); var page = _mapper.Map <Page>(vm); page.Id = Guid.NewGuid(); page.CreationDate = DateTimeOffset.Now; page.MainPhoto = await FindMainPhotoAsync(vm.MainPhotoKey); await _validator.ValidateAsync(page, vm.Facts); var changeset = await GetChangesetAsync(null, vm, page.Id, principal, null); _db.Changes.Add(changeset); _db.Pages.Add(page); var aliasValues = JsonConvert.DeserializeObject <List <string> >(vm.Aliases ?? "[]"); if (!aliasValues.Contains(vm.Title)) { aliasValues.Add(vm.Title); } _db.PageAliases.AddRange( aliasValues.Select((x, idx) => new PageAlias { Id = Guid.NewGuid(), Page = page, Key = PageHelper.EncodeTitle(x).ToLowerInvariant(), Title = x, Order = idx } ) ); _cache.Remove <TreeVM>(); await DiscardPageDraftAsync(null, principal); return(page); }
/// <summary> /// Checks if the create/update request contains valid data. /// </summary> private async Task ValidateRequestAsync(PageEditorVM vm) { var val = new Validator(); if (vm.Description == null) { vm.Description = string.Empty; } var key = PageHelper.EncodeTitle(vm.Title).ToLowerInvariant(); var otherPage = await _db.PageAliases .AnyAsync(x => x.Key == key && x.Page.Id != vm.Id); if (otherPage) { val.Add(nameof(PageEditorVM.Title), "Страница с таким названием уже существует."); } if (!string.IsNullOrEmpty(vm.Aliases)) { var aliases = TryDeserialize <List <string> >(vm.Aliases)?.Select(x => x.ToLowerInvariant()); if (aliases == null) { val.Add(nameof(PageEditorVM.Aliases), "Ссылки указаны неверно!"); } else { var otherAliases = await _db.PageAliases .Where(x => aliases.Contains(x.Key) && x.Page.Id != vm.Id) .Select(x => x.Title) .ToListAsync(); if (otherAliases.Any()) { val.Add(nameof(PageEditorVM.Aliases), "Ссылки уже заняты другими страницами: " + otherAliases.JoinString(", ")); } } } val.ThrowIfInvalid(); }
/// <summary> /// Gets the changeset for updates. /// </summary> private async Task <Changeset> GetChangesetAsync(PageEditorVM prev, PageEditorVM next, Guid id, ClaimsPrincipal principal, Guid?revertedId) { if (prev == null && next == null) { throw new ArgumentNullException(nameof(next), "Either prev or next must be provided."); } var user = await _userMgr.GetUserAsync(principal, "Пользователь не найден"); return(new Changeset { Id = Guid.NewGuid(), RevertedChangesetId = revertedId, ChangeType = ChangesetHelper.GetChangeType(prev, next, revertedId), EntityType = ChangesetEntityType.Page, Date = DateTime.Now, EditedPageId = id, Author = user, UpdatedState = next == null ? null : JsonConvert.SerializeObject(next), }); }
/// <summary> /// Gets the changeset for updates. /// </summary> private async Task <Changeset> GetChangesetAsync(PageEditorVM prev, PageEditorVM next, Guid id, ClaimsPrincipal principal, Guid?revertedId) { if (prev == null && next == null) { throw new ArgumentNullException(); } var userId = _userMgr.GetUserId(principal); var user = await _db.Users.GetAsync(x => x.Id == userId, "Пользователь не найден"); return(new Changeset { Id = Guid.NewGuid(), RevertedChangesetId = revertedId, Type = ChangesetEntityType.Page, Date = DateTime.Now, EditedPageId = id, Author = user, OriginalState = prev == null ? null : JsonConvert.SerializeObject(prev), UpdatedState = next == null ? null : JsonConvert.SerializeObject(next), }); }
/// <summary> /// Updates the changes to a page. /// </summary> public async Task <Page> UpdateAsync(PageEditorVM vm, ClaimsPrincipal principal, Guid?revertedId = null) { await ValidateRequestAsync(vm); var page = await _db.Pages .Include(x => x.Aliases) .Include(x => x.MainPhoto) .GetAsync(x => x.Id == vm.Id && (x.IsDeleted == false || revertedId != null), "Страница не найдена"); await _validator.ValidateAsync(page, vm.Facts); var prevVm = page.IsDeleted ? null : _mapper.Map <PageEditorVM>(page); var changeset = await GetChangesetAsync(prevVm, vm, vm.Id, principal, revertedId); _db.Changes.Add(changeset); _mapper.Map(vm, page); page.MainPhotoId = (await FindMainPhotoAsync(vm.MainPhotoKey))?.Id; if (revertedId != null) { page.IsDeleted = false; } await _db.PageAliases.RemoveWhereAsync(x => x.Page.Id == vm.Id); var aliasValues = JsonConvert.DeserializeObject <List <string> >(vm.Aliases ?? "[]"); if (!aliasValues.Contains(vm.Title)) { aliasValues.Add(vm.Title); } _db.PageAliases.AddRange( aliasValues.Select((x, idx) => new PageAlias { Id = Guid.NewGuid(), Key = PageHelper.EncodeTitle(x).ToLowerInvariant(), Page = page, Order = idx, Title = x }) ); if (prevVm?.Title != vm.Title || prevVm?.Facts != vm.Facts) { _cache.Clear(); } else { _cache.Remove <PageDescriptionVM>(page.Key); _cache.Remove <InfoBlockVM>(page.Key); } if (revertedId == null) { await DiscardPageDraftAsync(vm.Id, principal); } return(page); }