From 458b8308ae60c5708ec1204d7f33dda43c595fe6 Mon Sep 17 00:00:00 2001 From: "Daniel J. Summers" Date: Fri, 11 Nov 2016 16:28:15 -0600 Subject: [PATCH] Page / Post edit pages work Category in work --- src/MyWebLog.App/PageModule.fs | 30 ++++--- src/MyWebLog.App/PostModule.fs | 5 +- src/MyWebLog.App/ViewModels.fs | 23 +++-- src/MyWebLog.Data.RethinkDB/Category.fs | 96 +++++++++++---------- src/MyWebLog.Data.RethinkDB/Page.fs | 2 + src/MyWebLog.Data.RethinkDB/Post.fs | 4 +- src/MyWebLog.Resources/en-US.json | 5 +- src/myWebLog/views/admin/category/edit.html | 3 + src/myWebLog/views/admin/page/edit.html | 10 ++- src/myWebLog/views/admin/post/edit.html | 11 ++- 10 files changed, 115 insertions(+), 74 deletions(-) diff --git a/src/MyWebLog.App/PageModule.fs b/src/MyWebLog.App/PageModule.fs index 368f8b7..b78d9de 100644 --- a/src/MyWebLog.App/PageModule.fs +++ b/src/MyWebLog.App/PageModule.fs @@ -53,22 +53,26 @@ type PageModule (data : IMyWebLogData, clock : IClock) as this = let pageId = parameters.["id"].ToString () let form = this.Bind () let now = clock.GetCurrentInstant().ToUnixTimeTicks () - match pageId with "new" -> Some Page.Empty | _ -> tryFindPage data this.WebLog.Id pageId + match pageId with "new" -> Some Page.Empty | _ -> tryFindPage data this.WebLog.Id pageId |> function | Some p -> let page = match pageId with "new" -> { p with WebLogId = this.WebLog.Id } | _ -> p - let pId = { p with - Title = form.Title - Permalink = form.Permalink - PublishedOn = match pageId with "new" -> now | _ -> page.PublishedOn - UpdatedOn = now - Text = match form.Source with - | RevisionSource.Markdown -> (* Markdown.TransformHtml *) form.Text - | _ -> form.Text - Revisions = { AsOf = now - SourceType = form.Source - Text = form.Text } :: page.Revisions } - |> savePage data + let pId = + { p with + Title = form.Title + Permalink = form.Permalink + PublishedOn = match pageId with "new" -> now | _ -> page.PublishedOn + UpdatedOn = now + ShowInPageList = form.ShowInPageList + Text = match form.Source with + | RevisionSource.Markdown -> (* Markdown.TransformHtml *) form.Text + | _ -> form.Text + Revisions = { AsOf = now + SourceType = form.Source + Text = form.Text + } :: page.Revisions + } + |> savePage data let model = MyWebLogModel (this.Context, this.WebLog) { UserMessage.Empty with Level = Level.Info diff --git a/src/MyWebLog.App/PostModule.fs b/src/MyWebLog.App/PostModule.fs index 0a241e2..a83efeb 100644 --- a/src/MyWebLog.App/PostModule.fs +++ b/src/MyWebLog.App/PostModule.fs @@ -269,7 +269,7 @@ type PostModule(data : IMyWebLogData, clock : IClock) as this = match postId with "new" -> Some Post.Empty | _ -> tryFindPost data this.WebLog.Id postId |> function | Some p -> - let justPublished = p.PublishedOn = int64 0 && form.PublishNow + let justPublished = p.PublishedOn = 0L && form.PublishNow let post = match postId with | "new" -> { p with WebLogId = this.WebLog.Id @@ -281,7 +281,7 @@ type PostModule(data : IMyWebLogData, clock : IClock) as this = Status = match form.PublishNow with true -> PostStatus.Published | _ -> PostStatus.Draft Title = form.Title Permalink = form.Permalink - PublishedOn = match justPublished with true -> now | _ -> int64 0 + PublishedOn = match justPublished with true -> now | _ -> post.PublishedOn UpdatedOn = now Text = match form.Source with | RevisionSource.Markdown -> (* Markdown.TransformHtml *) form.Text @@ -289,6 +289,7 @@ type PostModule(data : IMyWebLogData, clock : IClock) as this = CategoryIds = Array.toList form.Categories Tags = form.Tags.Split ',' |> Seq.map (fun t -> t.Trim().ToLowerInvariant ()) + |> Seq.sort |> Seq.toList Revisions = { AsOf = now SourceType = form.Source diff --git a/src/MyWebLog.App/ViewModels.fs b/src/MyWebLog.App/ViewModels.fs index 675d9e4..137216f 100644 --- a/src/MyWebLog.App/ViewModels.fs +++ b/src/MyWebLog.App/ViewModels.fs @@ -220,6 +220,8 @@ type CategoryEditModel (ctx, webLog, category) = inherit MyWebLogModel (ctx, webLog) /// The form with the category information member val Form = CategoryForm (category) with get, set + /// The category being edited + member val Category = category /// The categories member val Categories : IndentedCategory list = [] with get, set @@ -336,9 +338,15 @@ type PostForDisplay (webLog : WebLog, post : Post) = /// The time zone for the web log to which this post belongs member this.TimeZone = webLog.TimeZone /// The date the post was published - member this.PublishedDate = FormatDateTime.longDate this.TimeZone this.Post.PublishedOn + member this.PublishedDate = + match this.Post.Status with + | PostStatus.Published -> FormatDateTime.longDate this.TimeZone this.Post.PublishedOn + | _ -> FormatDateTime.longDate this.TimeZone this.Post.UpdatedOn /// The time the post was published - member this.PublishedTime = FormatDateTime.time this.TimeZone this.Post.PublishedOn + member this.PublishedTime = + match this.Post.Status with + | PostStatus.Published -> FormatDateTime.time this.TimeZone this.Post.PublishedOn + | _ -> FormatDateTime.time this.TimeZone this.Post.UpdatedOn /// Tags member this.Tags = match List.length this.Post.Tags with @@ -389,14 +397,17 @@ type EditPostForm () = /// The selected category Ids for the post member val Categories : string[] = [||] with get, set /// Whether the post should be published - member val PublishNow = true with get, set + member val PublishNow = false with get, set /// Fill the form with applicable values from a post member this.ForPost (post : Post) = this.Title <- post.Title this.Permalink <- post.Permalink - this.Tags <- List.reduce (fun acc x -> sprintf "%s, %s" acc x) post.Tags + this.Tags <- match List.isEmpty post.Tags with + | true -> "" + | _ -> List.reduce (fun acc x -> sprintf "%s, %s" acc x) post.Tags this.Categories <- List.toArray post.CategoryIds + this.PublishNow <- post.Status = PostStatus.Published || "new" = post.Id this /// Fill the form with applicable values from a revision @@ -412,7 +423,7 @@ type DisplayCategory = { Name : string Description : string IsChecked : bool - } + } with /// Create a display category static member Create (cat : Category, indent) isChecked = @@ -442,6 +453,8 @@ type EditPostModel (ctx, webLog, post, revision) = member this.PublishedDate = this.DisplayLongDate this.Post.PublishedOn /// The published time member this.PublishedTime = this.DisplayTime this.Post.PublishedOn + /// The "checked" attribute for the Publish Now box + member this.PublishNowCheckedAttr = match this.Form.PublishNow with true -> "checked=\"checked\"" | _ -> "" // ---- User models ---- diff --git a/src/MyWebLog.Data.RethinkDB/Category.fs b/src/MyWebLog.Data.RethinkDB/Category.fs index 79eef22..94c13cc 100644 --- a/src/MyWebLog.Data.RethinkDB/Category.fs +++ b/src/MyWebLog.Data.RethinkDB/Category.fs @@ -5,12 +5,6 @@ open RethinkDb.Driver.Ast let private r = RethinkDb.Driver.RethinkDB.R -/// Shorthand to get a category by Id and filter by web log Id -let private category (webLogId : string) (catId : string) = - r.Table(Table.Category) - .Get(catId) - .Filter(ReqlFunction1 (fun c -> upcast c.["WebLogId"].Eq webLogId)) - /// Get all categories for a web log let getAllCategories conn (webLogId : string) = async { @@ -24,10 +18,16 @@ let getAllCategories conn (webLogId : string) = /// Get a specific category by its Id let tryFindCategory conn webLogId catId : Category option = async { - let! catt = (category webLogId catId).RunResultAsync conn - return catt - |> box - |> function null -> None | cat -> Some <| unbox cat + let! c = + r.Table(Table.Category) + .Get(catId) + .RunResultAsync conn + return + match box c with + | null -> None + | catt -> + let cat : Category = unbox catt + match cat.WebLogId = webLogId with true -> Some cat | _ -> None } |> Async.RunSynchronously @@ -48,53 +48,63 @@ type CategoryUpdateRecord = } /// Update a category let updateCategory conn (cat : Category) = - async { - do! (category cat.WebLogId cat.Id) - .Update({ CategoryUpdateRecord.Name = cat.Name + match tryFindCategory conn cat.WebLogId cat.Id with + | Some _ -> + async { + do! r.Table(Table.Category) + .Get(cat.Id) + .Update( + { CategoryUpdateRecord.Name = cat.Name Slug = cat.Slug Description = cat.Description ParentId = cat.ParentId }) - .RunResultAsync conn - } - |> Async.RunSynchronously + .RunResultAsync conn + } + |> Async.RunSynchronously + | _ -> () -type CategoryChildrenUpdateRecord = - { Children : string list } /// Update a category's children let updateChildren conn webLogId parentId (children : string list) = - async { - do! (category webLogId parentId) - .Update({ CategoryChildrenUpdateRecord.Children = children }) - .RunResultAsync conn - } - |> Async.RunSynchronously + match tryFindCategory conn webLogId parentId with + | Some _ -> + async { + do! r.Table(Table.Category) + .Get(parentId) + .Update(dict [ "Children", children ]) + .RunResultAsync conn + } + |> Async.RunSynchronously + | _ -> () -type CategoryParentUpdateRecord = - { ParentId : string option } -type PostCategoriesUpdateRecord = - { CategoryIds : string list } /// Delete a category let deleteCategory conn (cat : Category) = async { // Remove the category from its parent match cat.ParentId with - | Some parentId -> match tryFindCategory conn cat.WebLogId parentId with - | Some parent -> parent.Children - |> List.filter (fun childId -> childId <> cat.Id) - |> updateChildren conn cat.WebLogId parentId - | _ -> () + | Some parentId -> + match tryFindCategory conn cat.WebLogId parentId with + | Some parent -> parent.Children + |> List.filter (fun childId -> childId <> cat.Id) + |> updateChildren conn cat.WebLogId parentId + | _ -> () | _ -> () // Move this category's children to its parent - let newParent = { CategoryParentUpdateRecord.ParentId = cat.ParentId } cat.Children |> List.map (fun childId -> - async { - do! (category cat.WebLogId childId) - .Update(newParent) - .RunResultAsync conn - }) - |> List.iter Async.RunSynchronously + match tryFindCategory conn cat.WebLogId childId with + | Some _ -> + async { + do! r.Table(Table.Category) + .Get(childId) + .Update(dict [ "ParentId", cat.ParentId ]) + .RunResultAsync conn + } + |> Some + | _ -> None) + |> List.filter Option.isSome + |> List.map Option.get + |> List.iter Async.RunSynchronously // Remove the category from posts where it is assigned let! posts = r.Table(Table.Post) @@ -105,13 +115,9 @@ let deleteCategory conn (cat : Category) = posts |> List.map (fun post -> async { - let newCats = - { PostCategoriesUpdateRecord.CategoryIds = post.CategoryIds - |> List.filter (fun c -> c <> cat.Id) - } do! r.Table(Table.Post) .Get(post.Id) - .Update(newCats) + .Update(dict [ "CategoryIds", post.CategoryIds |> List.filter (fun c -> c <> cat.Id) ]) .RunResultAsync conn }) |> List.iter Async.RunSynchronously diff --git a/src/MyWebLog.Data.RethinkDB/Page.fs b/src/MyWebLog.Data.RethinkDB/Page.fs index 8cb0fb2..34db086 100644 --- a/src/MyWebLog.Data.RethinkDB/Page.fs +++ b/src/MyWebLog.Data.RethinkDB/Page.fs @@ -62,6 +62,7 @@ type PageUpdateRecord = Permalink : string PublishedOn : int64 UpdatedOn : int64 + ShowInPageList : bool Text : string Revisions : Revision list } /// Update a page @@ -75,6 +76,7 @@ let updatePage conn (page : Page) = Permalink = page.Permalink PublishedOn = page.PublishedOn UpdatedOn = page.UpdatedOn + ShowInPageList = page.ShowInPageList Text = page.Text Revisions = page.Revisions }) .RunResultAsync conn diff --git a/src/MyWebLog.Data.RethinkDB/Post.fs b/src/MyWebLog.Data.RethinkDB/Post.fs index 9eb5eaa..b946ed9 100644 --- a/src/MyWebLog.Data.RethinkDB/Post.fs +++ b/src/MyWebLog.Data.RethinkDB/Post.fs @@ -85,10 +85,12 @@ let tryFindOlderTaggedPost conn (tag : string) post = let findPageOfAllPosts conn (webLogId : string) pageNbr nbrPerPage = // FIXME: sort unpublished posts by their last updated date async { + // .orderBy(r.desc(r.branch(r.row("Status").eq("Published"), r.row("PublishedOn"), r.row("UpdatedOn")))) return! r.Table(Table.Post) .GetAll(webLogId).OptArg("index", "WebLogId") - .OrderBy(r.Desc "PublishedOn") + .OrderBy(r.Desc (ReqlFunction1 (fun p -> + upcast r.Branch (p.["Status"].Eq("Published"), p.["PublishedOn"], p.["UpdatedOn"])))) .Slice((pageNbr - 1) * nbrPerPage, pageNbr * nbrPerPage) .RunResultAsync conn } diff --git a/src/MyWebLog.Resources/en-US.json b/src/MyWebLog.Resources/en-US.json index f308d25..d5b98d1 100644 --- a/src/MyWebLog.Resources/en-US.json +++ b/src/MyWebLog.Resources/en-US.json @@ -8,6 +8,9 @@ "AndPublished": " and Published", "andXMore": "and {0} more...", "at": "at", + "BackToCategoryList": "Back to Category List", + "BackToPageList": "Back to Page List", + "BackToPostList": "Back to Post List", "Categories": "Categories", "Category": "Category", "CategoryDeleteWarning": "Are you sure you wish to delete the category", @@ -36,7 +39,7 @@ "MsgLogOffSuccess": "Log off successful | Have a nice day!", "MsgLogOnSuccess": "Log on successful | Welcome to myWebLog!", "MsgPageDeleted": "Deleted page successfully", - "MsgPageEditSuccess": "{0} edited successfully", + "MsgPageEditSuccess": "{0} page successfully", "MsgPostEditSuccess": "{0}{1} post successfully", "Name": "Name", "NewerPosts": "Newer Posts", diff --git a/src/myWebLog/views/admin/category/edit.html b/src/myWebLog/views/admin/category/edit.html index 279dfd8..ca39310 100644 --- a/src/myWebLog/views/admin/category/edit.html +++ b/src/myWebLog/views/admin/category/edit.html @@ -5,6 +5,9 @@ @AntiForgeryToken
+ + @Translate.BackToCategoryList +
diff --git a/src/myWebLog/views/admin/page/edit.html b/src/myWebLog/views/admin/page/edit.html index 081fbd3..facb824 100644 --- a/src/myWebLog/views/admin/page/edit.html +++ b/src/myWebLog/views/admin/page/edit.html @@ -5,6 +5,9 @@ @AntiForgeryToken
+ + @Translate.BackToPageList +
@@ -12,10 +15,11 @@
-

@Translate.startingWith http://@Model.WebLog.UrlBase/

+

@Translate.startingWith //@Model.WebLog.UrlBase/

-
+ +
@@ -34,7 +38,7 @@
@EndIf
- +  
diff --git a/src/myWebLog/views/admin/post/edit.html b/src/myWebLog/views/admin/post/edit.html index 24a5357..39963c7 100644 --- a/src/myWebLog/views/admin/post/edit.html +++ b/src/myWebLog/views/admin/post/edit.html @@ -5,6 +5,9 @@ @AntiForgeryToken
+ + @Translate.BackToPostList +
@@ -12,10 +15,10 @@
- -

@Translate.startingWith http://@Model.WebLog.UrlBase/

+

@Translate.startingWith //@Model.WebLog.UrlBase/

+
@@ -49,7 +52,7 @@
@Each.Categories @Current.Indent - +  
@@ -62,7 +65,7 @@ @EndIf @IfNot.IsPublished
- +  
@EndIf