From 518d6911f076bb10a0d2d92773048eb9b8f03461 Mon Sep 17 00:00:00 2001 From: Eike Kettner Date: Wed, 29 Jan 2020 21:57:02 +0100 Subject: [PATCH] Edit notes in a larger area --- .../webapp/src/main/elm/Comp/ItemDetail.elm | 139 +++++++++++++++--- .../src/main/elm/Comp/MarkdownInput.elm | 131 +++++++++++++++++ modules/webapp/src/main/webjar/docspell.css | 22 +++ 3 files changed, 269 insertions(+), 23 deletions(-) create mode 100644 modules/webapp/src/main/elm/Comp/MarkdownInput.elm diff --git a/modules/webapp/src/main/elm/Comp/ItemDetail.elm b/modules/webapp/src/main/elm/Comp/ItemDetail.elm index fe4d03df..2d71e324 100644 --- a/modules/webapp/src/main/elm/Comp/ItemDetail.elm +++ b/modules/webapp/src/main/elm/Comp/ItemDetail.elm @@ -25,6 +25,7 @@ import Browser.Navigation as Nav import Comp.DatePicker import Comp.Dropdown exposing (isDropdownChangeMsg) import Comp.ItemMail +import Comp.MarkdownInput import Comp.SentMails import Comp.YesNoDimmer import Data.Direction exposing (Direction) @@ -55,7 +56,7 @@ type alias Model = , concEquipModel : Comp.Dropdown.Model IdName , nameModel : String , notesModel : Maybe String - , notesHidden : Bool + , notesField : NotesField , deleteConfirm : Comp.YesNoDimmer.Model , itemDatePicker : DatePicker , itemDate : Maybe Int @@ -71,6 +72,25 @@ type alias Model = } +type NotesField + = ViewNotes + | EditNotes Comp.MarkdownInput.Model + | HideNotes + + +isEditNotes : NotesField -> Bool +isEditNotes field = + case field of + EditNotes _ -> + True + + ViewNotes -> + False + + HideNotes -> + False + + emptyModel : Model emptyModel = { item = Api.Model.ItemDetail.empty @@ -120,7 +140,7 @@ emptyModel = } , nameModel = "" , notesModel = Nothing - , notesHidden = False + , notesField = ViewNotes , deleteConfirm = Comp.YesNoDimmer.emptyModel , itemDatePicker = Comp.DatePicker.emptyModel , itemDate = Nothing @@ -156,6 +176,8 @@ type Msg | SaveName | SetNotes String | ToggleNotes + | ToggleEditNotes + | NotesEditMsg Comp.MarkdownInput.Msg | SaveNotes | ConfirmItem | UnconfirmItem @@ -387,6 +409,7 @@ update key flags next msg model = | item = item , nameModel = item.name , notesModel = item.notes + , notesField = ViewNotes , itemDate = item.itemDate , dueDate = item.dueDate } @@ -541,10 +564,43 @@ update key flags next msg model = ) ToggleNotes -> - ( { model | notesHidden = not model.notesHidden } + ( { model + | notesField = + if model.notesField == ViewNotes then + HideNotes + + else + ViewNotes + } , Cmd.none ) + ToggleEditNotes -> + ( { model + | notesField = + if isEditNotes model.notesField then + ViewNotes + + else + EditNotes Comp.MarkdownInput.init + } + , Cmd.none + ) + + NotesEditMsg lm -> + case model.notesField of + EditNotes em -> + let + ( lm2, str ) = + Comp.MarkdownInput.update (Maybe.withDefault "" model.notesModel) lm em + in + ( { model | notesField = EditNotes lm2, notesModel = Util.Maybe.fromString str } + , Cmd.none + ) + + _ -> + ( model, Cmd.none ) + SaveNotes -> ( model, setNotes flags model ) @@ -945,36 +1001,73 @@ renderIdInfo model = renderNotes : Model -> List (Html Msg) renderNotes model = - case model.item.notes of - Nothing -> - [] + case model.notesField of + HideNotes -> + case model.item.notes of + Nothing -> + [] - Just str -> - if model.notesHidden then - [ div [ class "ui segment" ] + Just str -> + [ div [ class "ui segment" ] + [ a + [ class "ui top left attached label" + , onClick ToggleNotes + , href "#" + ] + [ i [ class "eye icon" ] [] + , text "Show notes…" + ] + ] + ] + + ViewNotes -> + case model.item.notes of + Nothing -> + [] + + Just str -> + [ div [ class "ui segment" ] + [ Markdown.toHtml [ class "item-notes" ] str + , a + [ class "ui left corner label" + , onClick ToggleNotes + , href "#" + ] + [ i [ class "eye slash icon" ] [] + ] + , a + [ class "ui right corner label" + , onClick ToggleEditNotes + , href "#" + ] + [ i [ class "edit icon" ] [] + ] + ] + ] + + EditNotes mm -> + [ div [ class "ui segment" ] + [ Html.map NotesEditMsg (Comp.MarkdownInput.view (Maybe.withDefault "" model.notesModel) mm) + , div [ class "ui secondary menu" ] [ a - [ class "ui top left attached label" - , onClick ToggleNotes + [ class "link item" , href "#" + , onClick SaveNotes ] - [ i [ class "eye icon" ] [] - , text "Show notes…" + [ i [ class "save outline icon" ] [] + , text "Save" ] - ] - ] - - else - [ div [ class "ui segment" ] - [ Markdown.toHtml [ class "item-notes" ] str , a - [ class "ui right corner label" - , onClick ToggleNotes + [ class "link item" , href "#" + , onClick ToggleEditNotes ] - [ i [ class "eye slash icon" ] [] + [ i [ class "cancel icon" ] [] + , text "Cancel" ] ] ] + ] renderAttachmentsTabMenu : Model -> Html Msg @@ -1329,7 +1422,7 @@ renderEditForm model = , Maybe.withDefault "" model.notesModel |> value ] [] - , button [ class "ui icon button", onClick SaveNotes ] + , button [ class "ui icon button", onClick ToggleEditNotes ] [ i [ class "save outline icon" ] [] ] ] diff --git a/modules/webapp/src/main/elm/Comp/MarkdownInput.elm b/modules/webapp/src/main/elm/Comp/MarkdownInput.elm new file mode 100644 index 00000000..4439c0a5 --- /dev/null +++ b/modules/webapp/src/main/elm/Comp/MarkdownInput.elm @@ -0,0 +1,131 @@ +module Comp.MarkdownInput exposing + ( Model + , Msg + , init + , update + , view + ) + +import Html exposing (..) +import Html.Attributes exposing (..) +import Html.Events exposing (onClick, onInput) +import Markdown + + +type Display + = Edit + | Preview + | Split + + +type alias Model = + { display : Display + , cheatSheetUrl : String + } + + +init : Model +init = + { display = Split + , cheatSheetUrl = "https://www.markdownguide.org/cheat-sheet" + } + + +type Msg + = SetText String + | SetDisplay Display + + +update : String -> Msg -> Model -> ( Model, String ) +update txt msg model = + case msg of + SetText str -> + ( model, str ) + + SetDisplay dsp -> + ( { model | display = dsp }, txt ) + + +view : String -> Model -> Html Msg +view txt model = + div [] + [ div [ class "ui top attached tabular mini menu" ] + [ a + [ classList + [ ( "ui link item", True ) + , ( "active", model.display == Edit ) + ] + , onClick (SetDisplay Edit) + , href "#" + ] + [ text "Edit" + ] + , a + [ classList + [ ( "ui link item", True ) + , ( "active", model.display == Preview ) + ] + , onClick (SetDisplay Preview) + , href "#" + ] + [ text "Preview" + ] + , a + [ classList + [ ( "ui link item", True ) + , ( "active", model.display == Split ) + ] + , onClick (SetDisplay Split) + , href "#" + ] + [ text "Split" + ] + , a + [ class "ui right floated help-link link item" + , target "_new" + , href model.cheatSheetUrl + ] + [ i [ class "ui help icon" ] [] + , text "Supports Markdown" + ] + ] + , div [ class "ui bottom attached segment" ] + [ case model.display of + Edit -> + editDisplay txt + + Preview -> + previewDisplay txt + + Split -> + splitDisplay txt + ] + ] + + +editDisplay : String -> Html Msg +editDisplay txt = + textarea + [ class "markdown-editor" + , onInput SetText + ] + [ text txt ] + + +previewDisplay : String -> Html Msg +previewDisplay txt = + Markdown.toHtml [ class "markdown-preview" ] txt + + +splitDisplay : String -> Html Msg +splitDisplay txt = + div [ class "ui grid" ] + [ div [ class "row" ] + [ div [ class "eight wide column markdown-split" ] + [ editDisplay txt + ] + , div [ class "eight wide column markdown-split" ] + [ previewDisplay txt + ] + ] + ] diff --git a/modules/webapp/src/main/webjar/docspell.css b/modules/webapp/src/main/webjar/docspell.css index e715e63c..a569bf5c 100644 --- a/modules/webapp/src/main/webjar/docspell.css +++ b/modules/webapp/src/main/webjar/docspell.css @@ -35,6 +35,28 @@ width: auto; } +.default-layout .ui.segment .item-notes { + padding: 0 1em; +} + +.markdown-preview { + overflow: auto; + max-height: 300px; +} +.markdown-split > textarea.markdown-editor { + height: 100%; + max-height: 300px; + width: 100%; + border: 0; + border-right: 1px solid #00000060 +} +textarea.markdown-editor { + height: 100%; + max-height: 300px; + width: 100%; + border: 0; + min-height: 10em; +} .default-layout .job-log { background: #181819;