diff of 0cd25fa3332ace022d37804bd07e5359d73e23fb
0cd25fa3332ace022d37804bd07e5359d73e23fb
diff --git a/elm-frontti/src/FeedView.elm b/elm-frontti/src/FeedView.elm
index fb71e69..53b6c5f 100644
--- a/elm-frontti/src/FeedView.elm
+++ b/elm-frontti/src/FeedView.elm
@@ -12,7 +12,7 @@ import Button exposing (murja_button)
import UUID
import Article_view exposing (formatDateTime)
import FeedManager exposing (feedmanager)
-import Tab exposing (tabs)
+import Tab exposing (TabEntry, tabs)
import Random
@@ -72,13 +72,10 @@ feeds feedReaderState show_archived settings zone fs new_feed metadata =
, checked show_archived
, onClick <| ShowArchivedFeedItems (not show_archived)] []
, text "Show read items"]
- , tabs "rss-feed-tab" (readerState_str feedReaderState)
- (Dict.fromList [ ("PerFeed", "Group by feed")
- , ("SingleFeed", "Show all in a feed")
- , ("FeedManager", "Manage feeds")])
- (Dict.fromList [ ("PerFeed", perFeedView settings zone fs new_feed_state)
- , ("SingleFeed", singleFeedView settings zone fs)
- , ("FeedManager", feedmanager settings.time_format zone fs)])
+ , tabs "rss-feed-tab" (readerState_str feedReaderState) Nothing
+ (Dict.fromList [ ("PerFeed", TabEntry "Group by feed" (perFeedView settings zone fs new_feed_state) Nothing ["*"])
+ , ("SingleFeed", TabEntry "Show all in a feed" (singleFeedView settings zone fs) Nothing ["*"])
+ , ("FeedManager", TabEntry "Manage feeds" (feedmanager settings.time_format zone fs) Nothing ["*"])])
, h3 [] [ text "Add new feed?"]
, label [ for "name" ] [ text "Feed name" ]
diff --git a/elm-frontti/src/Main.elm b/elm-frontti/src/Main.elm
index e930e4c..65952fc 100644
--- a/elm-frontti/src/Main.elm
+++ b/elm-frontti/src/Main.elm
@@ -45,6 +45,7 @@ import File exposing (mime)
import FeedView
import Feeds exposing (NewFeed)
+import Tab exposing (..)
-- MAIN
@@ -637,7 +638,6 @@ update msg model =
| show_preview = selected_tab == "PreviewArticle"})
model.postEditorSettings}
, Cmd.none)
-
_ -> ( model
, alert <| "Unknown tab " ++ tab_id)
ReadFeedItem feed_id item_id is_read ->
@@ -741,7 +741,76 @@ sidebarHistory titles =
[li [] [text ("There's no year " ++ (fromInt year) ++ " in titles")]]) (keys grouped_by_year |> List.reverse)))]
-
+page_wrapper comp =
+ div [class "flex-container"]
+ [ div [class "page"]
+ comp]
+
+blog_tab settings model =
+ div []
+ (case model.view_state of
+ Loading ->
+ [div [] [text "LOADING"]]
+ PostView article ->
+ [ articleView settings model.loginState model.zone article ]
+ PageView page ->
+ let post_elements = (List.map (articleView settings model.loginState model.zone) page.posts) in
+ (List.concat [ (if post_elements /= [] then
+ post_elements
+ else
+ [ div [class "post"] [ text <| case model.loginState of
+ LoggedIn usr -> (Debug.toString usr)
+ _ -> "There are no (also: no user) posts in this instance"]])
+ , [footer [ attribute "data-testid" "page-changer"
+ , class "page-changer" ]
+ (if page.id > 1 then
+ [ a [href ("/blog/page/" ++ fromInt (page.id + 1))] [text "Older posts"]
+ , a [href ("/blog/page/" ++ fromInt (page.id - 1)), class "newer-post"] [text "Newer posts"]]
+ else
+ [a [href ("/blog/page/" ++ fromInt (page.id + 1))] [text "Older posts"]])]])
+ ShowError err ->
+ [pre [] [text err]]
+ TaggedPostsView articles ->
+ (List.map (articleView settings model.loginState model.zone) articles)
+ _ ->
+ [ div [] [ text "Unknown viewstate in blog_tab"] ])
+
+rss_tab model settings =
+ div []
+ (case model.view_state of
+ Feeds feeds show_archived -> [ FeedView.feeds model.feedReaderState show_archived settings model.zone feeds model.new_feed model.feedMetadata]
+ _ -> [ div [] [ text "Unknown viewstate in rss_tab"] ])
+
+postmanager_tab model =
+ div []
+ (case model.view_state of
+ PostEditorList titles -> [ PostsAdmin.view titles ]
+ _ -> [ div [] [ text "Unknown viewstate in postmanager_tab"] ])
+
+mediamanager_tab model =
+ div []
+ (case model.view_state of
+ MediaList -> [ medialist model.loadedImages model.medialist_state ]
+ _ -> [ div [] [ text "Unknown viewstate in mediamanager_tab"] ])
+
+settings_tab settings model =
+ div []
+ (case model.view_state of
+ SettingsEditor -> [ SettingsEditor.editor settings]
+ _ -> [ div [] [ text "Unknown viewstate in settings_tab"] ])
+
+posteditor_tab settings model =
+ div [ class "posteditor-tab" ]
+ (case model.view_state of
+ PostEditor ->
+ case model.postEditorSettings of
+ Just editorSettings ->
+ let post = editorSettings.article
+ tag_index = editorSettings.selected_tag in
+ PostEditor.postEditor post tag_index model.showImageModal model.loadedImages model.draggingImages editorSettings settings model.zone model.loginState model.searchedPosts
+ Nothing -> [ div [] [ text "No post loaded" ]]
+ _ -> [ div [] [ text "Unknown viewstate in posteditor_tab" ]])
+
view : Model -> Browser.Document Msg
view model =
case model.settings of
@@ -753,46 +822,43 @@ view model =
{ title = settings.blog_title
, body =
[ header [] [a [href "/"] [text settings.blog_title ]]
- , Topbar.topbar model.loginState
- , div [class "flex-container"]
- [ div [class "page"]
- (case model.view_state of
- Loading ->
- [div [] [text "LOADING"]]
- PostView article ->
- [ articleView settings model.loginState model.zone article ]
- PageView page ->
- let post_elements = (List.map (articleView settings model.loginState model.zone) page.posts) in
- (List.concat [ (if post_elements /= [] then
- post_elements
- else
- [ div [class "post"] [ text "There are no posts in this instance"]])
- , [footer [ attribute "data-testid" "page-changer"
- , class "page-changer" ]
- (if page.id > 1 then
- [ a [href ("/blog/page/" ++ fromInt (page.id + 1))] [text "Older posts"]
- , a [href ("/blog/page/" ++ fromInt (page.id - 1)), class "newer-post"] [text "Newer posts"]]
-
- else
- [a [href ("/blog/page/" ++ fromInt (page.id + 1))] [text "Older posts"]])]])
- ShowError err ->
- [pre [] [text err]]
- PostEditorList titles -> [ PostsAdmin.view titles ]
- TaggedPostsView articles ->
- (List.map (articleView settings model.loginState model.zone) articles)
- PostEditor ->
- case model.postEditorSettings of
- Just editorSettings ->
- let post = editorSettings.article
- tag_index = editorSettings.selected_tag in
- PostEditor.postEditor post tag_index model.showImageModal model.loadedImages model.draggingImages editorSettings settings model.zone model.loginState model.searchedPosts
- Nothing -> [ div [] [ text "No post loaded" ]]
- MediaList -> [ medialist model.loadedImages model.medialist_state ]
- SettingsEditor -> [ SettingsEditor.editor settings]
- Feeds feeds show_archived -> [ FeedView.feeds model.feedReaderState show_archived settings model.zone feeds model.new_feed model.feedMetadata])
- , div [id "sidebar"] [ User.loginView model.loginState
- , (sidebarHistory model.titles )
- , (case model.view_state of
- PostEditorList titles -> PostsAdmin.tagList titles
-
- _ -> div [] [])]]]}
+ , div [ class "sidebar-flex" ]
+ [ let tabstate = viewstate_to_tabstate model.view_state in
+ tabs "topbar" (tabstate_to_str tabstate) (case model.loginState of
+ LoggedIn usr -> Just usr
+ _ -> Nothing)
+ (Dict.fromList [ ("Blog"
+ , TabEntry "Home"
+ (blog_tab settings model)
+ (Just GoHome)
+ ["*"])
+ , ("RssFeeds"
+ , TabEntry "RSS Feeds"
+ (rss_tab model settings)
+ (Just (PushUrl "/blog/feeds"))
+ ["create-post"] ) -- <- TODO make a real permission for rss
+ , ("ManagePosts"
+ , TabEntry "Manage posts"
+ (postmanager_tab model)
+ (Just (PushUrl "/blog/postadmin"))
+ ["create-post", "delete-post", "edit-post"])
+ , ("ManageMedia"
+ , TabEntry "Manage media"
+ (mediamanager_tab model)
+ (Just (PushUrl "/blog/mediamanager"))
+ ["create-post", "delete-post", "edit-post"])
+ , ("SettingsTab"
+ , TabEntry "Settings"
+ (settings_tab settings model)
+ (Just (PushUrl "/blog/settings"))
+ ["update-settings"])
+ , ("PostEditTab"
+ , TabEntry "Post editor"
+ (posteditor_tab settings model)
+ (Just GenNewPost)
+ ["create-post", "edit-post"])])
+ , div [id "sidebar"] [ User.loginView model.loginState
+ , (sidebarHistory model.titles )
+ , (case model.view_state of
+ PostEditorList titles -> PostsAdmin.tagList titles
+ _ -> div [] [])]]]}
diff --git a/elm-frontti/src/Message.elm b/elm-frontti/src/Message.elm
index 4015a5c..cef9632 100644
--- a/elm-frontti/src/Message.elm
+++ b/elm-frontti/src/Message.elm
@@ -31,7 +31,48 @@ type ViewState
| TaggedPostsView (List Article.Article)
| SettingsEditor
| Feeds (List Feeds.Feed) Bool -- <- show_archived?
-
+
+-- a simplified version of ViewState type for the main.elm's tabcomponent
+type TabState
+ = Blog
+ | RssFeeds
+ | ManagePosts
+ | ManageMedia
+ | SettingsTab
+ | PostEditTab
+
+viewstate_to_tabstate vs =
+ case vs of
+ PageView _ -> Blog
+ PostView _ -> Blog
+ Loading -> Blog
+ ShowError _ -> Blog
+ PostEditorList _ -> ManagePosts
+ PostEditor -> PostEditTab
+ MediaList -> ManageMedia
+ TaggedPostsView _ -> Blog
+ SettingsEditor -> SettingsTab
+ Feeds _ _ -> RssFeeds
+
+tabstate_to_str tb =
+ case tb of
+ Blog -> "Blog"
+ RssFeeds -> "RssFeeds"
+ ManagePosts -> "ManagePosts"
+ ManageMedia -> "ManageMedia"
+ SettingsTab -> "SettingsTab"
+ PostEditTab -> "PostEditTab"
+
+str_to_tabstate str =
+ case str of
+ "Blog" -> Blog
+ "RssFeeds" -> RssFeeds
+ "ManagePosts" -> ManagePosts
+ "ManageMedia" -> ManageMedia
+ "SettingsTab" -> SettingsTab
+ "PostEditTab" -> PostEditTab
+ _ -> Blog
+
type alias User =
{ username : String
, nickname : String
diff --git a/elm-frontti/src/PostEditor.elm b/elm-frontti/src/PostEditor.elm
index 552e618..5b746b2 100644
--- a/elm-frontti/src/PostEditor.elm
+++ b/elm-frontti/src/PostEditor.elm
@@ -15,7 +15,7 @@ import Page as P
import Message exposing (..)
import ImageSelector exposing (imageSelector)
import Button exposing (murja_button)
-import Tab exposing (tabs)
+import Tab exposing (..)
import Dict exposing (Dict)
import File exposing (File)
@@ -50,12 +50,14 @@ tagView post selectedTag = div [class "tagview editor-grouper"]
, murja_button [ onClick (DropTag selectedTag)
, attribute "data-testid" "remove-tag"]
[text "Remove selected tag"]]
+
editor params =
- node "ace-editor"
- ( params
- ++ [ attribute "theme" "ace/theme/monokai"
- , attribute "mode" "ace/mode/html"])
- []
+ div [ class "editor-container" ]
+ [ node "ace-editor"
+ ( params
+ ++ [ attribute "theme" "ace/theme/monokai"
+ , attribute "mode" "ace/mode/html"])
+ []]
filesDecoder : D.Decoder (List File)
filesDecoder =
@@ -138,11 +140,10 @@ postEditor post tag showImageModal loadedImages draggingImages editorSettings ap
tabs "posteditor-preview-tab" (if editorSettings.show_preview then
"PreviewArticle"
else
- "EditArticle")
- (Dict.fromList [ ("EditArticle", "Edit article")
- , ("PreviewArticle", "Preview article")])
- (Dict.fromList [ ("EditArticle",
- editor [ id "editor-post-content"
+ "EditArticle") (Just user)
+ (Dict.fromList [ ("EditArticle"
+ , TabEntry "Edit article"
+ (editor [ id "editor-post-content"
, style "background-color" (if draggingImages then "#880088" else "")
, hijackOn "dragenter" (D.succeed EditorDragEnter)
, hijackOn "dragend" (D.succeed EditorDragLeave)
@@ -150,6 +151,9 @@ postEditor post tag showImageModal loadedImages draggingImages editorSettings ap
, hijackOn "dragleave" (D.succeed EditorDragLeave)
, hijackOn "drop" dropDecoder
, hijackOn "ready" (D.succeed (RunAce post.content))])
+ Nothing ["*"])
, ("PreviewArticle"
- , Article_view.articleView app_settings loginState tz post)])
+ , TabEntry "Preview article"
+ (Article_view.articleView app_settings loginState tz post)
+ Nothing ["*"])])
_ -> div [] [text "You're not logged in"]]
diff --git a/elm-frontti/src/Tab.elm b/elm-frontti/src/Tab.elm
index 695a9e5..3236694 100644
--- a/elm-frontti/src/Tab.elm
+++ b/elm-frontti/src/Tab.elm
@@ -1,21 +1,46 @@
module Tab exposing (..)
import Dict exposing (Dict)
+import Set exposing (Set)
import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (..)
import Message exposing (..)
--- tabs: String -> comparable -> Dict comparable String -> Dict comparable (Html msg) -> Html msg
-tabs tab_id selected_tab_key titles tabkey_to_page =
+type alias TabEntry =
+ { title: String
+ , component: Html Msg
+ , onclick: Maybe Msg
+ , permissions: List String}
+
+-- tabs: String -> String -> Dict String TabEntry -> Html Msg
+tabs tab_id selected_tab usr tabentries =
+ let tab_ids = ( tabentries
+ |> Dict.filter (\k -> \entry -> case usr of
+ Just user -> (( entry.permissions
+ |> Set.fromList
+ |> Set.intersect (Set.fromList user.permissions)
+ |> Set.isEmpty
+ |> not)
+ ||
+ (List.member "*" entry.permissions))
+ Nothing -> (List.member "*" entry.permissions))
+ |> Dict.keys)
+ selected_tab_component = Dict.get selected_tab tabentries
+ in
div [ class "tabs"
- , id tab_id]
+ , id tab_id ]
[ ul [ class "tab-headers" ]
- ( titles
- |> Dict.map
- (\k -> \title -> li [ class <| if selected_tab_key == k then "tab-header tab-selected" else "tab-header"
- , onClick (SelectTab tab_id k)] [ text title])
- |> Dict.values)
- , ( Dict.get selected_tab_key tabkey_to_page
- |> Maybe.withDefault (div [] [ text <| "Invalid selected tab key " ++ (Debug.toString selected_tab_key)]))]
-
+ ( tab_ids
+ |> List.map (\id ->
+ let entry_ = Dict.get id tabentries in
+ case entry_ of
+ Just entry ->
+ li [ class (if selected_tab == id then "tab-header tab-selected" else "tab-header")
+ , onClick (case entry.onclick of
+ Just oc -> oc
+ Nothing -> SelectTab tab_id id)] [ text entry.title]
+ Nothing -> li [] [ text "Unknown tab" ]))
+ , case selected_tab_component of
+ Just c -> c.component
+ Nothing -> div [] [ text <| "Invalid selected tab key " ++ (Debug.toString selected_tab)]]
diff --git a/resources/css/murja.css b/resources/css/murja.css
index cf9f0ed..bb72373 100644
--- a/resources/css/murja.css
+++ b/resources/css/murja.css
@@ -34,17 +34,12 @@ html, body {
}
#editor-post-content {
- box-sizing: border-box;
- height: 100%;
- min-width: 100%;
display: block;
- flex: 10 1;
+ position: absolute;
+ height: 100%;
+ width: 80%;
}
-/* #editor-post-save { */
-/* flex: 1 1; */
-/* } */
-
#editor-buttons * {
display: block;
}
@@ -65,7 +60,6 @@ html, body {
.left-sidebar {
flex: 1 1;
- border: 2px solid #666666;
}
.left-sidebar > ul {
@@ -89,7 +83,6 @@ html, body {
}
.post {
- border: 2px solid #666666;
width: 100%;
}
@@ -103,6 +96,10 @@ body, dialog {
color: #666666;
}
+.meta img {
+ margin: 1.5em;
+}
+
.flex-container {
display: flex;
flex-flow: row wrap;
@@ -134,8 +131,9 @@ body, dialog {
}
#sidebar {
- border: 2px solid #666666;
- flex: 1 1;
+
+ margin-top: 3em;
+ width: 25%;
}
#loginview {
@@ -320,6 +318,8 @@ header {
.tabs {
width: 100%;
height: 100%;
+ display: flex;
+ flex-direction: column;
}
.tab-headers {
@@ -345,6 +345,24 @@ header {
width: 100%;
}
+.sidebar-flex {
+ display: flex;
+ flex-direction: row;
+}
+
+.editor-container {
+ flex: 3;
+}
+
+.posteditor-tab {
+ display: flex;
+ flex-direction: column;
+}
+
+#posteditor-preview-tab {
+ flex: 3;
+}
+
@media only screen and (max-device-width:480px)
{
body {