Ejemplo n.º 1
0
        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));
            }
        }
Ejemplo n.º 2
0
        /// <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
            });
        }
Ejemplo n.º 3
0
        /// <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));
        }
Ejemplo n.º 4
0
        /// <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));
        }
Ejemplo n.º 5
0
        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));
            }
        }
Ejemplo n.º 6
0
        /// <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);
        }
Ejemplo n.º 7
0
        public async Task <ActionResult> Update(PageEditorVM vm)
        {
            var info = await _pages.UpdatePageDraftAsync(vm, User);

            await _db.SaveChangesAsync();

            return(Json(info));
        }
Ejemplo n.º 8
0
        /// <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);
        }
Ejemplo n.º 9
0
        /// <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);
        }
Ejemplo n.º 10
0
        /// <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);
        }
Ejemplo n.º 11
0
        /// <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();
        }
Ejemplo n.º 12
0
        /// <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),
            });
        }
Ejemplo n.º 13
0
        /// <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),
            });
        }
Ejemplo n.º 14
0
        /// <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);
        }