mirror of
https://github.com/TheAnachronism/docspell.git
synced 2025-04-04 10:29:34 +00:00
Create shares from search and select view
This commit is contained in:
parent
189009325e
commit
aa21e7a74c
292
modules/webapp/src/main/elm/Comp/PublishItems.elm
Normal file
292
modules/webapp/src/main/elm/Comp/PublishItems.elm
Normal file
@ -0,0 +1,292 @@
|
||||
{-
|
||||
Copyright 2020 Eike K. & Contributors
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
-}
|
||||
|
||||
|
||||
module Comp.PublishItems exposing
|
||||
( Model
|
||||
, Msg
|
||||
, Outcome(..)
|
||||
, init
|
||||
, initQuery
|
||||
, update
|
||||
, view
|
||||
)
|
||||
|
||||
import Api
|
||||
import Api.Model.IdResult exposing (IdResult)
|
||||
import Api.Model.ShareDetail exposing (ShareDetail)
|
||||
import Comp.Basic as B
|
||||
import Comp.MenuBar as MB
|
||||
import Comp.ShareForm
|
||||
import Comp.ShareView
|
||||
import Data.Flags exposing (Flags)
|
||||
import Data.Icons as Icons
|
||||
import Data.ItemQuery exposing (ItemQuery)
|
||||
import Data.SearchMode exposing (SearchMode)
|
||||
import Html exposing (..)
|
||||
import Html.Attributes exposing (..)
|
||||
import Http
|
||||
import Messages.Comp.PublishItems exposing (Texts)
|
||||
import Ports
|
||||
import Styles as S
|
||||
|
||||
|
||||
|
||||
--- Model
|
||||
|
||||
|
||||
type ViewMode
|
||||
= ViewModeEdit
|
||||
| ViewModeInfo ShareDetail
|
||||
|
||||
|
||||
type FormError
|
||||
= FormErrorNone
|
||||
| FormErrorHttp Http.Error
|
||||
| FormErrorInvalid
|
||||
| FormErrorSubmit String
|
||||
|
||||
|
||||
type alias Model =
|
||||
{ formModel : Comp.ShareForm.Model
|
||||
, viewMode : ViewMode
|
||||
, formError : FormError
|
||||
, loading : Bool
|
||||
}
|
||||
|
||||
|
||||
init : ( Model, Cmd Msg )
|
||||
init =
|
||||
let
|
||||
( fm, fc ) =
|
||||
Comp.ShareForm.init
|
||||
in
|
||||
( { formModel = fm
|
||||
, viewMode = ViewModeEdit
|
||||
, formError = FormErrorNone
|
||||
, loading = False
|
||||
}
|
||||
, Cmd.map FormMsg fc
|
||||
)
|
||||
|
||||
|
||||
initQuery : ItemQuery -> ( Model, Cmd Msg )
|
||||
initQuery query =
|
||||
let
|
||||
( fm, fc ) =
|
||||
Comp.ShareForm.initQuery (Data.ItemQuery.render query)
|
||||
in
|
||||
( { formModel = fm
|
||||
, viewMode = ViewModeEdit
|
||||
, formError = FormErrorNone
|
||||
, loading = False
|
||||
}
|
||||
, Cmd.map FormMsg fc
|
||||
)
|
||||
|
||||
|
||||
|
||||
--- Update
|
||||
|
||||
|
||||
type Msg
|
||||
= FormMsg Comp.ShareForm.Msg
|
||||
| CancelPublish
|
||||
| SubmitPublish
|
||||
| PublishResp (Result Http.Error IdResult)
|
||||
| GetShareResp (Result Http.Error ShareDetail)
|
||||
|
||||
|
||||
type Outcome
|
||||
= OutcomeDone
|
||||
| OutcomeInProgress
|
||||
|
||||
|
||||
type alias UpdateResult =
|
||||
{ model : Model
|
||||
, cmd : Cmd Msg
|
||||
, outcome : Outcome
|
||||
}
|
||||
|
||||
|
||||
update : Flags -> Msg -> Model -> UpdateResult
|
||||
update flags msg model =
|
||||
case msg of
|
||||
CancelPublish ->
|
||||
{ model = model
|
||||
, cmd = Cmd.none
|
||||
, outcome = OutcomeDone
|
||||
}
|
||||
|
||||
FormMsg lm ->
|
||||
let
|
||||
( fm, fc ) =
|
||||
Comp.ShareForm.update flags lm model.formModel
|
||||
in
|
||||
{ model = { model | formModel = fm }
|
||||
, cmd = Cmd.map FormMsg fc
|
||||
, outcome = OutcomeInProgress
|
||||
}
|
||||
|
||||
SubmitPublish ->
|
||||
case Comp.ShareForm.getShare model.formModel of
|
||||
Just ( _, data ) ->
|
||||
{ model = { model | loading = True }
|
||||
, cmd = Api.addShare flags data PublishResp
|
||||
, outcome = OutcomeInProgress
|
||||
}
|
||||
|
||||
Nothing ->
|
||||
{ model = { model | formError = FormErrorInvalid }
|
||||
, cmd = Cmd.none
|
||||
, outcome = OutcomeInProgress
|
||||
}
|
||||
|
||||
PublishResp (Ok res) ->
|
||||
if res.success then
|
||||
{ model = model
|
||||
, cmd = Api.getShare flags res.id GetShareResp
|
||||
, outcome = OutcomeInProgress
|
||||
}
|
||||
|
||||
else
|
||||
{ model = { model | formError = FormErrorSubmit res.message, loading = False }
|
||||
, cmd = Cmd.none
|
||||
, outcome = OutcomeInProgress
|
||||
}
|
||||
|
||||
PublishResp (Err err) ->
|
||||
{ model = { model | formError = FormErrorHttp err, loading = False }
|
||||
, cmd = Cmd.none
|
||||
, outcome = OutcomeInProgress
|
||||
}
|
||||
|
||||
GetShareResp (Ok share) ->
|
||||
{ model =
|
||||
{ model
|
||||
| formError = FormErrorNone
|
||||
, loading = False
|
||||
, viewMode = ViewModeInfo share
|
||||
}
|
||||
, cmd = Ports.initClipboard (Comp.ShareView.clipboardData share)
|
||||
, outcome = OutcomeInProgress
|
||||
}
|
||||
|
||||
GetShareResp (Err err) ->
|
||||
{ model = { model | formError = FormErrorHttp err, loading = False }
|
||||
, cmd = Cmd.none
|
||||
, outcome = OutcomeInProgress
|
||||
}
|
||||
|
||||
|
||||
|
||||
--- View
|
||||
|
||||
|
||||
view : Texts -> Flags -> Model -> Html Msg
|
||||
view texts flags model =
|
||||
div []
|
||||
[ B.loadingDimmer
|
||||
{ active = model.loading
|
||||
, label = ""
|
||||
}
|
||||
, case model.viewMode of
|
||||
ViewModeEdit ->
|
||||
viewForm texts model
|
||||
|
||||
ViewModeInfo share ->
|
||||
viewInfo texts flags model share
|
||||
]
|
||||
|
||||
|
||||
viewInfo : Texts -> Flags -> Model -> ShareDetail -> Html Msg
|
||||
viewInfo texts flags model share =
|
||||
let
|
||||
cfg =
|
||||
{ mainClasses = ""
|
||||
, showAccessData = False
|
||||
}
|
||||
in
|
||||
div [ class "px-2 mb-4" ]
|
||||
[ h1 [ class S.header1 ]
|
||||
[ text texts.title
|
||||
]
|
||||
, div
|
||||
[ class S.infoMessage
|
||||
]
|
||||
[ text texts.infoText
|
||||
]
|
||||
, MB.view <|
|
||||
{ start =
|
||||
[ MB.SecondaryButton
|
||||
{ tagger = CancelPublish
|
||||
, title = texts.cancelPublishTitle
|
||||
, icon = Just "fa fa-arrow-left"
|
||||
, label = texts.doneLabel
|
||||
}
|
||||
]
|
||||
, end = []
|
||||
, rootClasses = "my-4"
|
||||
}
|
||||
, div []
|
||||
[ Comp.ShareView.view cfg texts.shareView flags share
|
||||
]
|
||||
]
|
||||
|
||||
|
||||
viewForm : Texts -> Model -> Html Msg
|
||||
viewForm texts model =
|
||||
div [ class "px-2 mb-4" ]
|
||||
[ h1 [ class S.header1 ]
|
||||
[ text texts.title
|
||||
]
|
||||
, div
|
||||
[ class S.infoMessage
|
||||
]
|
||||
[ text texts.infoText
|
||||
]
|
||||
, MB.view <|
|
||||
{ start =
|
||||
[ MB.PrimaryButton
|
||||
{ tagger = SubmitPublish
|
||||
, title = texts.submitPublishTitle
|
||||
, icon = Just Icons.share
|
||||
, label = texts.submitPublish
|
||||
}
|
||||
, MB.SecondaryButton
|
||||
{ tagger = CancelPublish
|
||||
, title = texts.cancelPublishTitle
|
||||
, icon = Just "fa fa-times"
|
||||
, label = texts.cancelPublish
|
||||
}
|
||||
]
|
||||
, end = []
|
||||
, rootClasses = "my-4"
|
||||
}
|
||||
, div []
|
||||
[ Html.map FormMsg (Comp.ShareForm.view texts.shareForm model.formModel)
|
||||
]
|
||||
, div
|
||||
[ classList
|
||||
[ ( "hidden", model.formError == FormErrorNone )
|
||||
]
|
||||
, class "my-2"
|
||||
, class S.errorMessage
|
||||
]
|
||||
[ case model.formError of
|
||||
FormErrorNone ->
|
||||
text ""
|
||||
|
||||
FormErrorHttp err ->
|
||||
text (texts.httpError err)
|
||||
|
||||
FormErrorInvalid ->
|
||||
text texts.correctFormErrors
|
||||
|
||||
FormErrorSubmit m ->
|
||||
text m
|
||||
]
|
||||
]
|
@ -5,7 +5,7 @@
|
||||
-}
|
||||
|
||||
|
||||
module Comp.ShareForm exposing (Model, Msg, getShare, init, setShare, update, view)
|
||||
module Comp.ShareForm exposing (Model, Msg, getShare, init, initQuery, setShare, update, view)
|
||||
|
||||
import Api.Model.ShareData exposing (ShareData)
|
||||
import Api.Model.ShareDetail exposing (ShareDetail)
|
||||
@ -36,16 +36,16 @@ type alias Model =
|
||||
}
|
||||
|
||||
|
||||
init : ( Model, Cmd Msg )
|
||||
init =
|
||||
initQuery : String -> ( Model, Cmd Msg )
|
||||
initQuery q =
|
||||
let
|
||||
( dp, dpc ) =
|
||||
Comp.DatePicker.init
|
||||
in
|
||||
( { share = Api.Model.ShareDetail.empty
|
||||
, name = Nothing
|
||||
, query = ""
|
||||
, enabled = False
|
||||
, query = q
|
||||
, enabled = True
|
||||
, passwordModel = Comp.PasswordInput.init
|
||||
, password = Nothing
|
||||
, passwordSet = False
|
||||
@ -57,6 +57,11 @@ init =
|
||||
)
|
||||
|
||||
|
||||
init : ( Model, Cmd Msg )
|
||||
init =
|
||||
initQuery ""
|
||||
|
||||
|
||||
isValid : Model -> Bool
|
||||
isValid model =
|
||||
model.query /= "" && model.untilDate /= Nothing
|
||||
@ -206,7 +211,7 @@ view texts model =
|
||||
, class S.textInput
|
||||
, classList
|
||||
[ ( S.inputErrorBorder
|
||||
, not (isValid model)
|
||||
, model.query == ""
|
||||
)
|
||||
]
|
||||
]
|
||||
@ -265,12 +270,16 @@ view texts model =
|
||||
]
|
||||
]
|
||||
]
|
||||
, div [ class "mb-2 max-w-sm" ]
|
||||
, div
|
||||
[ class "mb-2 max-w-sm"
|
||||
]
|
||||
[ label [ class S.inputLabel ]
|
||||
[ text texts.publishUntil
|
||||
, B.inputRequired
|
||||
]
|
||||
, div [ class "relative" ]
|
||||
, div
|
||||
[ class "relative"
|
||||
]
|
||||
[ Html.map UntilDateMsg
|
||||
(Comp.DatePicker.viewTimeDefault
|
||||
model.untilDate
|
||||
@ -278,5 +287,15 @@ view texts model =
|
||||
)
|
||||
, i [ class S.dateInputIcon, class "fa fa-calendar" ] []
|
||||
]
|
||||
, div
|
||||
[ classList
|
||||
[ ( "hidden"
|
||||
, model.untilDate /= Nothing
|
||||
)
|
||||
]
|
||||
, class "mt-1"
|
||||
, class S.errorText
|
||||
]
|
||||
[ text "This field is required." ]
|
||||
]
|
||||
]
|
||||
|
@ -17,12 +17,14 @@ import Comp.ItemDetail.Model exposing (Msg(..))
|
||||
import Comp.MenuBar as MB
|
||||
import Comp.ShareForm
|
||||
import Comp.ShareTable
|
||||
import Comp.ShareView
|
||||
import Data.Flags exposing (Flags)
|
||||
import Html exposing (..)
|
||||
import Html.Attributes exposing (..)
|
||||
import Html.Events exposing (onClick)
|
||||
import Http
|
||||
import Messages.Comp.ShareManage exposing (Texts)
|
||||
import Ports
|
||||
import Styles as S
|
||||
|
||||
|
||||
@ -107,7 +109,7 @@ update flags msg model =
|
||||
share =
|
||||
Api.Model.ShareDetail.empty
|
||||
in
|
||||
update flags (FormMsg (Comp.ShareForm.setShare share)) nm
|
||||
update flags (FormMsg (Comp.ShareForm.setShare { share | enabled = True })) nm
|
||||
|
||||
SetViewMode vm ->
|
||||
( { model | viewMode = vm, formError = FormErrorNone }
|
||||
@ -129,13 +131,10 @@ update flags msg model =
|
||||
let
|
||||
action =
|
||||
Comp.ShareTable.update lm
|
||||
|
||||
nextModel =
|
||||
{ model | viewMode = Form, formError = FormErrorNone }
|
||||
in
|
||||
case action of
|
||||
Comp.ShareTable.Edit share ->
|
||||
update flags (FormMsg <| Comp.ShareForm.setShare share) nextModel
|
||||
setShare share flags model
|
||||
|
||||
RequestDelete ->
|
||||
( { model | deleteConfirm = DeleteConfirmOn }, Cmd.none )
|
||||
@ -190,11 +189,7 @@ update flags msg model =
|
||||
( { model | loading = False, formError = FormErrorHttp err }, Cmd.none )
|
||||
|
||||
GetShareResp (Ok share) ->
|
||||
let
|
||||
nextModel =
|
||||
{ model | formError = FormErrorNone, loading = False }
|
||||
in
|
||||
update flags (FormMsg <| Comp.ShareForm.setShare share) nextModel
|
||||
setShare share flags model
|
||||
|
||||
GetShareResp (Err err) ->
|
||||
( { model | formError = FormErrorHttp err }, Cmd.none )
|
||||
@ -210,17 +205,32 @@ update flags msg model =
|
||||
( { model | formError = FormErrorHttp err, loading = False }, Cmd.none )
|
||||
|
||||
|
||||
setShare : ShareDetail -> Flags -> Model -> ( Model, Cmd Msg )
|
||||
setShare share flags model =
|
||||
let
|
||||
nextModel =
|
||||
{ model | formError = FormErrorNone, viewMode = Form, loading = False }
|
||||
|
||||
initClipboard =
|
||||
Ports.initClipboard (Comp.ShareView.clipboardData share)
|
||||
|
||||
( nm, nc ) =
|
||||
update flags (FormMsg <| Comp.ShareForm.setShare share) nextModel
|
||||
in
|
||||
( nm, Cmd.batch [ initClipboard, nc ] )
|
||||
|
||||
|
||||
|
||||
--- view
|
||||
|
||||
|
||||
view : Texts -> Flags -> Model -> Html Msg
|
||||
view texts _ model =
|
||||
view texts flags model =
|
||||
if model.viewMode == Table then
|
||||
viewTable texts model
|
||||
|
||||
else
|
||||
viewForm texts model
|
||||
viewForm texts flags model
|
||||
|
||||
|
||||
viewTable : Texts -> Model -> Html Msg
|
||||
@ -247,103 +257,119 @@ viewTable texts model =
|
||||
]
|
||||
|
||||
|
||||
viewForm : Texts -> Model -> Html Msg
|
||||
viewForm texts model =
|
||||
viewForm : Texts -> Flags -> Model -> Html Msg
|
||||
viewForm texts flags model =
|
||||
let
|
||||
newShare =
|
||||
model.formModel.share.id == ""
|
||||
in
|
||||
Html.form [ class "relative" ]
|
||||
[ if newShare then
|
||||
h1 [ class S.header2 ]
|
||||
[ text texts.createNewShare
|
||||
]
|
||||
|
||||
else
|
||||
h1 [ class S.header2 ]
|
||||
[ text <| Maybe.withDefault texts.noName model.formModel.share.name
|
||||
, div [ class "opacity-50 text-sm" ]
|
||||
[ text "Id: "
|
||||
, text model.formModel.share.id
|
||||
div [ class "relative" ]
|
||||
[ Html.form []
|
||||
[ if newShare then
|
||||
h1 [ class S.header2 ]
|
||||
[ text texts.createNewShare
|
||||
]
|
||||
]
|
||||
, MB.view
|
||||
{ start =
|
||||
[ MB.PrimaryButton
|
||||
{ tagger = Submit
|
||||
, title = "Submit this form"
|
||||
, icon = Just "fa fa-save"
|
||||
, label = texts.basics.submit
|
||||
}
|
||||
, MB.SecondaryButton
|
||||
{ tagger = SetViewMode Table
|
||||
, title = texts.basics.backToList
|
||||
, icon = Just "fa fa-arrow-left"
|
||||
, label = texts.basics.cancel
|
||||
}
|
||||
]
|
||||
, end =
|
||||
if not newShare then
|
||||
[ MB.DeleteButton
|
||||
{ tagger = RequestDelete
|
||||
, title = texts.deleteThisShare
|
||||
, icon = Just "fa fa-trash"
|
||||
, label = texts.basics.delete
|
||||
|
||||
else
|
||||
h1 [ class S.header2 ]
|
||||
[ text <| Maybe.withDefault texts.noName model.formModel.share.name
|
||||
, div [ class "opacity-50 text-sm" ]
|
||||
[ text "Id: "
|
||||
, text model.formModel.share.id
|
||||
]
|
||||
]
|
||||
, MB.view
|
||||
{ start =
|
||||
[ MB.PrimaryButton
|
||||
{ tagger = Submit
|
||||
, title = "Submit this form"
|
||||
, icon = Just "fa fa-save"
|
||||
, label = texts.basics.submit
|
||||
}
|
||||
, MB.SecondaryButton
|
||||
{ tagger = SetViewMode Table
|
||||
, title = texts.basics.backToList
|
||||
, icon = Just "fa fa-arrow-left"
|
||||
, label = texts.basics.cancel
|
||||
}
|
||||
]
|
||||
, end =
|
||||
if not newShare then
|
||||
[ MB.DeleteButton
|
||||
{ tagger = RequestDelete
|
||||
, title = texts.deleteThisShare
|
||||
, icon = Just "fa fa-trash"
|
||||
, label = texts.basics.delete
|
||||
}
|
||||
]
|
||||
|
||||
else
|
||||
[]
|
||||
, rootClasses = "mb-4"
|
||||
}
|
||||
, div
|
||||
[ classList
|
||||
[ ( "hidden", model.formError == FormErrorNone )
|
||||
else
|
||||
[]
|
||||
, rootClasses = "mb-4"
|
||||
}
|
||||
, div
|
||||
[ classList
|
||||
[ ( "hidden", model.formError == FormErrorNone )
|
||||
]
|
||||
, class "my-2"
|
||||
, class S.errorMessage
|
||||
]
|
||||
, class "my-2"
|
||||
, class S.errorMessage
|
||||
[ case model.formError of
|
||||
FormErrorNone ->
|
||||
text ""
|
||||
|
||||
FormErrorHttp err ->
|
||||
text (texts.httpError err)
|
||||
|
||||
FormErrorInvalid ->
|
||||
text texts.correctFormErrors
|
||||
|
||||
FormErrorSubmit m ->
|
||||
text m
|
||||
]
|
||||
, Html.map FormMsg (Comp.ShareForm.view texts.shareForm model.formModel)
|
||||
, B.loadingDimmer
|
||||
{ active = model.loading
|
||||
, label = texts.basics.loading
|
||||
}
|
||||
, B.contentDimmer
|
||||
(model.deleteConfirm == DeleteConfirmOn)
|
||||
(div [ class "flex flex-col" ]
|
||||
[ div [ class "text-lg" ]
|
||||
[ i [ class "fa fa-info-circle mr-2" ] []
|
||||
, text texts.reallyDeleteShare
|
||||
]
|
||||
, div [ class "mt-4 flex flex-row items-center" ]
|
||||
[ B.deleteButton
|
||||
{ label = texts.basics.yes
|
||||
, icon = "fa fa-check"
|
||||
, disabled = False
|
||||
, handler = onClick (DeleteShareNow model.formModel.share.id)
|
||||
, attrs = [ href "#" ]
|
||||
}
|
||||
, B.secondaryButton
|
||||
{ label = texts.basics.no
|
||||
, icon = "fa fa-times"
|
||||
, disabled = False
|
||||
, handler = onClick CancelDelete
|
||||
, attrs = [ href "#", class "ml-2" ]
|
||||
}
|
||||
]
|
||||
]
|
||||
)
|
||||
]
|
||||
[ case model.formError of
|
||||
FormErrorNone ->
|
||||
text ""
|
||||
|
||||
FormErrorHttp err ->
|
||||
text (texts.httpError err)
|
||||
|
||||
FormErrorInvalid ->
|
||||
text texts.correctFormErrors
|
||||
|
||||
FormErrorSubmit m ->
|
||||
text m
|
||||
]
|
||||
, Html.map FormMsg (Comp.ShareForm.view texts.shareForm model.formModel)
|
||||
, B.loadingDimmer
|
||||
{ active = model.loading
|
||||
, label = texts.basics.loading
|
||||
}
|
||||
, B.contentDimmer
|
||||
(model.deleteConfirm == DeleteConfirmOn)
|
||||
(div [ class "flex flex-col" ]
|
||||
[ div [ class "text-lg" ]
|
||||
[ i [ class "fa fa-info-circle mr-2" ] []
|
||||
, text texts.reallyDeleteShare
|
||||
]
|
||||
, div [ class "mt-4 flex flex-row items-center" ]
|
||||
[ B.deleteButton
|
||||
{ label = texts.basics.yes
|
||||
, icon = "fa fa-check"
|
||||
, disabled = False
|
||||
, handler = onClick (DeleteShareNow model.formModel.share.id)
|
||||
, attrs = [ href "#" ]
|
||||
}
|
||||
, B.secondaryButton
|
||||
{ label = texts.basics.no
|
||||
, icon = "fa fa-times"
|
||||
, disabled = False
|
||||
, handler = onClick CancelDelete
|
||||
, attrs = [ href "#", class "ml-2" ]
|
||||
}
|
||||
]
|
||||
]
|
||||
)
|
||||
, shareInfo texts flags model.formModel.share
|
||||
]
|
||||
|
||||
|
||||
shareInfo : Texts -> Flags -> ShareDetail -> Html Msg
|
||||
shareInfo texts flags share =
|
||||
div
|
||||
[ class "mt-6"
|
||||
, classList [ ( "hidden", share.id == "" ) ]
|
||||
]
|
||||
[ h2 [ class S.header2 ]
|
||||
[ text texts.shareInformation
|
||||
]
|
||||
, Comp.ShareView.viewDefault texts.shareView flags share
|
||||
]
|
||||
|
@ -54,7 +54,7 @@ view texts shares =
|
||||
[ text texts.basics.name
|
||||
]
|
||||
, th [ class "text-center" ]
|
||||
[ text texts.enabled
|
||||
[ text texts.active
|
||||
]
|
||||
, th [ class "text-center" ]
|
||||
[ text texts.publishUntil
|
||||
@ -79,7 +79,14 @@ renderShareLine texts share =
|
||||
[ text (Maybe.withDefault "-" share.name)
|
||||
]
|
||||
, td [ class "w-px px-2 text-center" ]
|
||||
[ Util.Html.checkbox2 share.enabled
|
||||
[ if not share.enabled then
|
||||
i [ class "fa fa-ban" ] []
|
||||
|
||||
else if share.expired then
|
||||
i [ class "fa fa-bolt text-red-600 dark:text-orange-800" ] []
|
||||
|
||||
else
|
||||
i [ class "fa fa-check" ] []
|
||||
]
|
||||
, td [ class "hidden sm:table-cell text-center" ]
|
||||
[ texts.formatDateTime share.publishUntil |> text
|
||||
|
184
modules/webapp/src/main/elm/Comp/ShareView.elm
Normal file
184
modules/webapp/src/main/elm/Comp/ShareView.elm
Normal file
@ -0,0 +1,184 @@
|
||||
{-
|
||||
Copyright 2020 Eike K. & Contributors
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
-}
|
||||
|
||||
|
||||
module Comp.ShareView exposing (ViewSettings, clipboardData, view, viewDefault)
|
||||
|
||||
import Api.Model.ShareDetail exposing (ShareDetail)
|
||||
import Data.Flags exposing (Flags)
|
||||
import Html exposing (..)
|
||||
import Html.Attributes exposing (..)
|
||||
import Messages.Comp.ShareView exposing (Texts)
|
||||
import QRCode
|
||||
import Styles as S
|
||||
|
||||
|
||||
type alias ViewSettings =
|
||||
{ mainClasses : String
|
||||
, showAccessData : Bool
|
||||
}
|
||||
|
||||
|
||||
view : ViewSettings -> Texts -> Flags -> ShareDetail -> Html msg
|
||||
view cfg texts flags share =
|
||||
if not share.enabled then
|
||||
viewDisabled cfg texts share
|
||||
|
||||
else if share.expired then
|
||||
viewExpired cfg texts share
|
||||
|
||||
else
|
||||
viewActive cfg texts flags share
|
||||
|
||||
|
||||
viewDefault : Texts -> Flags -> ShareDetail -> Html msg
|
||||
viewDefault =
|
||||
view
|
||||
{ mainClasses = ""
|
||||
, showAccessData = True
|
||||
}
|
||||
|
||||
|
||||
clipboardData : ShareDetail -> ( String, String )
|
||||
clipboardData share =
|
||||
( "app-share-" ++ share.id, "#app-share-url-copy-to-clipboard-btn-" ++ share.id )
|
||||
|
||||
|
||||
|
||||
--- Helper
|
||||
|
||||
|
||||
viewActive : ViewSettings -> Texts -> Flags -> ShareDetail -> Html msg
|
||||
viewActive cfg texts flags share =
|
||||
let
|
||||
clipboard =
|
||||
clipboardData share
|
||||
|
||||
appUrl =
|
||||
flags.config.baseUrl ++ "/app/share/" ++ share.id
|
||||
|
||||
styleUrl =
|
||||
"truncate px-2 py-2 border-0 border-t border-b border-r font-mono text-sm my-auto rounded-r border-gray-400 dark:border-bluegray-500"
|
||||
|
||||
infoLine hidden icon label value =
|
||||
div
|
||||
[ class "flex flex-row items-center"
|
||||
, classList [ ( "hidden", hidden ) ]
|
||||
]
|
||||
[ div [ class "flex mr-3" ]
|
||||
[ i [ class icon ] []
|
||||
]
|
||||
, div [ class "flex flex-col" ]
|
||||
[ div [ class "-mb-1" ]
|
||||
[ text value
|
||||
]
|
||||
, div [ class "opacity-50 text-sm" ]
|
||||
[ text label
|
||||
]
|
||||
]
|
||||
]
|
||||
in
|
||||
div
|
||||
[ class cfg.mainClasses
|
||||
, class "flex flex-col sm:flex-row "
|
||||
]
|
||||
[ div [ class "flex" ]
|
||||
[ div
|
||||
[ class S.border
|
||||
, class S.qrCode
|
||||
]
|
||||
[ qrCodeView texts appUrl
|
||||
]
|
||||
]
|
||||
, div
|
||||
[ class "flex flex-col ml-3 pr-2"
|
||||
|
||||
-- hack for the qr code that is 265px
|
||||
, style "max-width" "calc(100% - 265px)"
|
||||
]
|
||||
[ div [ class "font-medium text-2xl" ]
|
||||
[ text <| Maybe.withDefault texts.noName share.name
|
||||
]
|
||||
, div [ class "my-2" ]
|
||||
[ div [ class "flex flex-row" ]
|
||||
[ a
|
||||
[ class S.secondaryBasicButtonPlain
|
||||
, class "rounded-l border text-sm px-4 py-2"
|
||||
, title texts.copyToClipboard
|
||||
, href "#"
|
||||
, Tuple.second clipboard
|
||||
|> String.dropLeft 1
|
||||
|> id
|
||||
, attribute "data-clipboard-target" ("#" ++ Tuple.first clipboard)
|
||||
]
|
||||
[ i [ class "fa fa-copy" ] []
|
||||
]
|
||||
, a
|
||||
[ class S.secondaryBasicButtonPlain
|
||||
, class "px-4 py-2 border-0 border-t border-b border-r text-sm"
|
||||
, href appUrl
|
||||
, target "_blank"
|
||||
, title texts.openInNewTab
|
||||
]
|
||||
[ i [ class "fa fa-external-link-alt" ] []
|
||||
]
|
||||
, div
|
||||
[ id (Tuple.first clipboard)
|
||||
, class styleUrl
|
||||
]
|
||||
[ text appUrl
|
||||
]
|
||||
]
|
||||
]
|
||||
, div [ class "text-lg flex flex-col" ]
|
||||
[ infoLine False "fa fa-calendar" texts.publishUntil (texts.date share.publishUntil)
|
||||
, infoLine False
|
||||
(if share.password then
|
||||
"fa fa-lock"
|
||||
|
||||
else
|
||||
"fa fa-lock-open"
|
||||
)
|
||||
texts.passwordProtected
|
||||
(if share.password then
|
||||
texts.basics.yes
|
||||
|
||||
else
|
||||
texts.basics.no
|
||||
)
|
||||
, infoLine
|
||||
(not cfg.showAccessData)
|
||||
"fa fa-eye"
|
||||
texts.views
|
||||
(String.fromInt share.views)
|
||||
, infoLine
|
||||
(not cfg.showAccessData)
|
||||
"fa fa-calendar-check font-thin"
|
||||
texts.lastAccess
|
||||
(Maybe.map texts.date share.lastAccess |> Maybe.withDefault "-")
|
||||
]
|
||||
]
|
||||
]
|
||||
|
||||
|
||||
viewExpired : ViewSettings -> Texts -> ShareDetail -> Html msg
|
||||
viewExpired cfg texts share =
|
||||
div [ class S.warnMessage ]
|
||||
[ text texts.expiredInfo ]
|
||||
|
||||
|
||||
viewDisabled : ViewSettings -> Texts -> ShareDetail -> Html msg
|
||||
viewDisabled cfg texts share =
|
||||
div [ class S.warnMessage ]
|
||||
[ text texts.disabledInfo ]
|
||||
|
||||
|
||||
qrCodeView : Texts -> String -> Html msg
|
||||
qrCodeView texts message =
|
||||
QRCode.encode message
|
||||
|> Result.map QRCode.toSvg
|
||||
|> Result.withDefault
|
||||
(Html.text texts.qrCodeError)
|
82
modules/webapp/src/main/elm/Messages/Comp/PublishItems.elm
Normal file
82
modules/webapp/src/main/elm/Messages/Comp/PublishItems.elm
Normal file
@ -0,0 +1,82 @@
|
||||
{-
|
||||
Copyright 2020 Eike K. & Contributors
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
-}
|
||||
|
||||
|
||||
module Messages.Comp.PublishItems exposing
|
||||
( Texts
|
||||
, de
|
||||
, gb
|
||||
)
|
||||
|
||||
import Http
|
||||
import Messages.Basics
|
||||
import Messages.Comp.HttpError
|
||||
import Messages.Comp.ShareForm
|
||||
import Messages.Comp.ShareView
|
||||
import Messages.DateFormat
|
||||
import Messages.UiLanguage
|
||||
|
||||
|
||||
type alias Texts =
|
||||
{ basics : Messages.Basics.Texts
|
||||
, httpError : Http.Error -> String
|
||||
, shareForm : Messages.Comp.ShareForm.Texts
|
||||
, shareView : Messages.Comp.ShareView.Texts
|
||||
, title : String
|
||||
, infoText : String
|
||||
, formatDateLong : Int -> String
|
||||
, formatDateShort : Int -> String
|
||||
, submitPublish : String
|
||||
, cancelPublish : String
|
||||
, submitPublishTitle : String
|
||||
, cancelPublishTitle : String
|
||||
, publishSuccessful : String
|
||||
, publishInProcess : String
|
||||
, correctFormErrors : String
|
||||
, doneLabel : String
|
||||
}
|
||||
|
||||
|
||||
gb : Texts
|
||||
gb =
|
||||
{ basics = Messages.Basics.gb
|
||||
, httpError = Messages.Comp.HttpError.gb
|
||||
, shareForm = Messages.Comp.ShareForm.gb
|
||||
, shareView = Messages.Comp.ShareView.gb
|
||||
, title = "Publish Items"
|
||||
, infoText = "Publishing items creates a cryptic link, which can be used by everyone to see the selected documents. This link cannot be guessed, but is public! It exists for a certain amount of time and can be further protected using a password."
|
||||
, formatDateLong = Messages.DateFormat.formatDateLong Messages.UiLanguage.English
|
||||
, formatDateShort = Messages.DateFormat.formatDateShort Messages.UiLanguage.English
|
||||
, submitPublish = "Publish"
|
||||
, submitPublishTitle = "Publish the documents now"
|
||||
, cancelPublish = "Cancel"
|
||||
, cancelPublishTitle = "Back to select view"
|
||||
, publishSuccessful = "Items published successfully"
|
||||
, publishInProcess = "Items are published …"
|
||||
, correctFormErrors = "Please correct the errors in the form."
|
||||
, doneLabel = "Done"
|
||||
}
|
||||
|
||||
|
||||
de : Texts
|
||||
de =
|
||||
{ basics = Messages.Basics.de
|
||||
, httpError = Messages.Comp.HttpError.de
|
||||
, shareForm = Messages.Comp.ShareForm.de
|
||||
, shareView = Messages.Comp.ShareView.de
|
||||
, title = "Dokumente publizieren"
|
||||
, infoText = "Beim Publizieren der Dokumente wird ein kryptischer Link erzeugt, mit welchem jeder die dahinter publizierten Dokumente einsehen kann. Dieser Link kann nicht erraten werden, ist aber öffentlich. Er ist zeitlich begrenzt und kann zusätzlich mit einem Passwort geschützt werden."
|
||||
, formatDateLong = Messages.DateFormat.formatDateLong Messages.UiLanguage.German
|
||||
, formatDateShort = Messages.DateFormat.formatDateShort Messages.UiLanguage.German
|
||||
, submitPublish = "Publizieren"
|
||||
, submitPublishTitle = "Dokumente jetzt publizieren"
|
||||
, cancelPublish = "Abbrechen"
|
||||
, cancelPublishTitle = "Zurück zur Auswahl"
|
||||
, publishSuccessful = "Die Dokumente wurden erfolgreich publiziert."
|
||||
, publishInProcess = "Dokumente werden publiziert…"
|
||||
, correctFormErrors = "Bitte korrigiere die Fehler im Formular."
|
||||
, doneLabel = "Fertig"
|
||||
}
|
@ -16,12 +16,14 @@ import Messages.Basics
|
||||
import Messages.Comp.HttpError
|
||||
import Messages.Comp.ShareForm
|
||||
import Messages.Comp.ShareTable
|
||||
import Messages.Comp.ShareView
|
||||
|
||||
|
||||
type alias Texts =
|
||||
{ basics : Messages.Basics.Texts
|
||||
, shareTable : Messages.Comp.ShareTable.Texts
|
||||
, shareForm : Messages.Comp.ShareForm.Texts
|
||||
, shareView : Messages.Comp.ShareView.Texts
|
||||
, httpError : Http.Error -> String
|
||||
, newShare : String
|
||||
, copyToClipboard : String
|
||||
@ -33,6 +35,7 @@ type alias Texts =
|
||||
, errorGeneratingQR : String
|
||||
, correctFormErrors : String
|
||||
, noName : String
|
||||
, shareInformation : String
|
||||
}
|
||||
|
||||
|
||||
@ -42,6 +45,7 @@ gb =
|
||||
, httpError = Messages.Comp.HttpError.gb
|
||||
, shareTable = Messages.Comp.ShareTable.gb
|
||||
, shareForm = Messages.Comp.ShareForm.gb
|
||||
, shareView = Messages.Comp.ShareView.gb
|
||||
, newShare = "New share"
|
||||
, copyToClipboard = "Copy to clipboard"
|
||||
, openInNewTab = "Open in new tab/window"
|
||||
@ -52,6 +56,7 @@ gb =
|
||||
, errorGeneratingQR = "Error generating QR Code"
|
||||
, correctFormErrors = "Please correct the errors in the form."
|
||||
, noName = "No Name"
|
||||
, shareInformation = "Share Information"
|
||||
}
|
||||
|
||||
|
||||
@ -60,6 +65,7 @@ de =
|
||||
{ basics = Messages.Basics.de
|
||||
, shareTable = Messages.Comp.ShareTable.de
|
||||
, shareForm = Messages.Comp.ShareForm.de
|
||||
, shareView = Messages.Comp.ShareView.de
|
||||
, httpError = Messages.Comp.HttpError.de
|
||||
, newShare = "Neue Freigabe"
|
||||
, copyToClipboard = "In die Zwischenablage kopieren"
|
||||
@ -71,4 +77,5 @@ de =
|
||||
, errorGeneratingQR = "Fehler beim Generieren des QR-Code"
|
||||
, correctFormErrors = "Bitte korrigiere die Fehler im Formular."
|
||||
, noName = "Ohne Name"
|
||||
, shareInformation = "Informationen zur Freigabe"
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ import Messages.UiLanguage
|
||||
type alias Texts =
|
||||
{ basics : Messages.Basics.Texts
|
||||
, formatDateTime : Int -> String
|
||||
, enabled : String
|
||||
, active : String
|
||||
, publishUntil : String
|
||||
}
|
||||
|
||||
@ -28,7 +28,7 @@ gb : Texts
|
||||
gb =
|
||||
{ basics = Messages.Basics.gb
|
||||
, formatDateTime = DF.formatDateTimeLong Messages.UiLanguage.English
|
||||
, enabled = "Enabled"
|
||||
, active = "Active"
|
||||
, publishUntil = "Publish Until"
|
||||
}
|
||||
|
||||
@ -37,6 +37,6 @@ de : Texts
|
||||
de =
|
||||
{ basics = Messages.Basics.de
|
||||
, formatDateTime = DF.formatDateTimeLong Messages.UiLanguage.German
|
||||
, enabled = "Aktiv"
|
||||
, active = "Aktiv"
|
||||
, publishUntil = "Publiziert bis"
|
||||
}
|
||||
|
66
modules/webapp/src/main/elm/Messages/Comp/ShareView.elm
Normal file
66
modules/webapp/src/main/elm/Messages/Comp/ShareView.elm
Normal file
@ -0,0 +1,66 @@
|
||||
{-
|
||||
Copyright 2020 Eike K. & Contributors
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
-}
|
||||
|
||||
|
||||
module Messages.Comp.ShareView exposing
|
||||
( Texts
|
||||
, de
|
||||
, gb
|
||||
)
|
||||
|
||||
import Messages.Basics
|
||||
import Messages.DateFormat as DF
|
||||
import Messages.UiLanguage
|
||||
|
||||
|
||||
type alias Texts =
|
||||
{ basics : Messages.Basics.Texts
|
||||
, date : Int -> String
|
||||
, qrCodeError : String
|
||||
, expiredInfo : String
|
||||
, disabledInfo : String
|
||||
, noName : String
|
||||
, copyToClipboard : String
|
||||
, openInNewTab : String
|
||||
, publishUntil : String
|
||||
, passwordProtected : String
|
||||
, views : String
|
||||
, lastAccess : String
|
||||
}
|
||||
|
||||
|
||||
gb : Texts
|
||||
gb =
|
||||
{ basics = Messages.Basics.gb
|
||||
, date = DF.formatDateLong Messages.UiLanguage.English
|
||||
, qrCodeError = "Error generating QR Code."
|
||||
, expiredInfo = "This share has expired."
|
||||
, disabledInfo = "This share is disabled."
|
||||
, noName = "No Name"
|
||||
, copyToClipboard = "Copy to clipboard"
|
||||
, openInNewTab = "Open in new tab/window"
|
||||
, publishUntil = "Published Until"
|
||||
, passwordProtected = "Password protected"
|
||||
, views = "Views"
|
||||
, lastAccess = "Last Access"
|
||||
}
|
||||
|
||||
|
||||
de : Texts
|
||||
de =
|
||||
{ basics = Messages.Basics.de
|
||||
, date = DF.formatDateLong Messages.UiLanguage.German
|
||||
, qrCodeError = "Fehler beim Erzeugen des QR-Codes."
|
||||
, expiredInfo = "Diese Freigabe ist abgelaufen."
|
||||
, disabledInfo = "Diese Freigae ist nicht aktiv."
|
||||
, noName = "Ohne Name"
|
||||
, copyToClipboard = "In die Zwischenablage kopieren"
|
||||
, openInNewTab = "Im neuen Tab/Fenster öffnen"
|
||||
, publishUntil = "Publiziert bis"
|
||||
, passwordProtected = "Passwordgeschützt"
|
||||
, views = "Aufrufe"
|
||||
, lastAccess = "Letzter Zugriff"
|
||||
}
|
@ -14,6 +14,7 @@ module Messages.Page.Home exposing
|
||||
import Messages.Basics
|
||||
import Messages.Comp.ItemCardList
|
||||
import Messages.Comp.ItemMerge
|
||||
import Messages.Comp.PublishItems
|
||||
import Messages.Comp.SearchStatsView
|
||||
import Messages.Page.HomeSideMenu
|
||||
|
||||
@ -24,6 +25,7 @@ type alias Texts =
|
||||
, searchStatsView : Messages.Comp.SearchStatsView.Texts
|
||||
, sideMenu : Messages.Page.HomeSideMenu.Texts
|
||||
, itemMerge : Messages.Comp.ItemMerge.Texts
|
||||
, publishItems : Messages.Comp.PublishItems.Texts
|
||||
, contentSearch : String
|
||||
, searchInNames : String
|
||||
, selectModeTitle : String
|
||||
@ -42,6 +44,11 @@ type alias Texts =
|
||||
, resetSearchForm : String
|
||||
, exitSelectMode : String
|
||||
, mergeItemsTitle : Int -> String
|
||||
, publishItemsTitle : Int -> String
|
||||
, publishCurrentQueryTitle : String
|
||||
, nothingSelectedToShare : String
|
||||
, loadMore : String
|
||||
, thatsAll : String
|
||||
}
|
||||
|
||||
|
||||
@ -52,6 +59,7 @@ gb =
|
||||
, searchStatsView = Messages.Comp.SearchStatsView.gb
|
||||
, sideMenu = Messages.Page.HomeSideMenu.gb
|
||||
, itemMerge = Messages.Comp.ItemMerge.gb
|
||||
, publishItems = Messages.Comp.PublishItems.gb
|
||||
, contentSearch = "Content search…"
|
||||
, searchInNames = "Search in names…"
|
||||
, selectModeTitle = "Select Mode"
|
||||
@ -70,6 +78,11 @@ gb =
|
||||
, resetSearchForm = "Reset search form"
|
||||
, exitSelectMode = "Exit Select Mode"
|
||||
, mergeItemsTitle = \n -> "Merge " ++ String.fromInt n ++ " selected items"
|
||||
, publishItemsTitle = \n -> "Publish " ++ String.fromInt n ++ " selected items"
|
||||
, publishCurrentQueryTitle = "Publish current results"
|
||||
, nothingSelectedToShare = "Sharing everything doesn't work. You need to apply some criteria."
|
||||
, loadMore = "Load more…"
|
||||
, thatsAll = "That's all"
|
||||
}
|
||||
|
||||
|
||||
@ -80,6 +93,7 @@ de =
|
||||
, searchStatsView = Messages.Comp.SearchStatsView.de
|
||||
, sideMenu = Messages.Page.HomeSideMenu.de
|
||||
, itemMerge = Messages.Comp.ItemMerge.de
|
||||
, publishItems = Messages.Comp.PublishItems.de
|
||||
, contentSearch = "Volltextsuche…"
|
||||
, searchInNames = "Suche in Namen…"
|
||||
, selectModeTitle = "Auswahlmodus"
|
||||
@ -98,4 +112,9 @@ de =
|
||||
, resetSearchForm = "Suchformular zurücksetzen"
|
||||
, exitSelectMode = "Auswahlmodus verlassen"
|
||||
, mergeItemsTitle = \n -> String.fromInt n ++ " gewählte Dokumente zusammenführen"
|
||||
, publishItemsTitle = \n -> String.fromInt n ++ " gewählte Dokumente publizieren"
|
||||
, publishCurrentQueryTitle = "Aktuelle Ansicht publizieren"
|
||||
, nothingSelectedToShare = "Alles kann nicht geteilt werden; es muss etwas gesucht werden."
|
||||
, loadMore = "Mehr laden…"
|
||||
, thatsAll = "Mehr gibt es nicht"
|
||||
}
|
||||
|
@ -14,6 +14,7 @@ module Page.Home.Data exposing
|
||||
, SelectActionMode(..)
|
||||
, SelectViewModel
|
||||
, ViewMode(..)
|
||||
, createQuery
|
||||
, doSearchCmd
|
||||
, editActive
|
||||
, init
|
||||
@ -36,6 +37,7 @@ import Comp.ItemDetail.MultiEditMenu exposing (SaveNameState(..))
|
||||
import Comp.ItemMerge
|
||||
import Comp.LinkTarget exposing (LinkTarget)
|
||||
import Comp.PowerSearchInput
|
||||
import Comp.PublishItems
|
||||
import Comp.SearchMenu
|
||||
import Data.Flags exposing (Flags)
|
||||
import Data.ItemNav exposing (ItemNav)
|
||||
@ -79,6 +81,7 @@ type alias SelectViewModel =
|
||||
, confirmModal : Maybe ConfirmModalValue
|
||||
, editModel : Comp.ItemDetail.MultiEditMenu.Model
|
||||
, mergeModel : Comp.ItemMerge.Model
|
||||
, publishModel : Comp.PublishItems.Model
|
||||
, saveNameState : SaveNameState
|
||||
, saveCustomFieldState : Set String
|
||||
}
|
||||
@ -91,6 +94,7 @@ initSelectViewModel =
|
||||
, confirmModal = Nothing
|
||||
, editModel = Comp.ItemDetail.MultiEditMenu.init
|
||||
, mergeModel = Comp.ItemMerge.init []
|
||||
, publishModel = Tuple.first Comp.PublishItems.init
|
||||
, saveNameState = SaveSuccess
|
||||
, saveCustomFieldState = Set.empty
|
||||
}
|
||||
@ -100,6 +104,7 @@ type ViewMode
|
||||
= SimpleView
|
||||
| SearchView
|
||||
| SelectView SelectViewModel
|
||||
| PublishView Comp.PublishItems.Model
|
||||
|
||||
|
||||
init : Flags -> ViewMode -> Model
|
||||
@ -143,6 +148,9 @@ menuCollapsed model =
|
||||
SelectView _ ->
|
||||
False
|
||||
|
||||
PublishView _ ->
|
||||
False
|
||||
|
||||
|
||||
selectActive : Model -> Bool
|
||||
selectActive model =
|
||||
@ -153,6 +161,9 @@ selectActive model =
|
||||
SearchView ->
|
||||
False
|
||||
|
||||
PublishView _ ->
|
||||
False
|
||||
|
||||
SelectView _ ->
|
||||
True
|
||||
|
||||
@ -166,6 +177,9 @@ editActive model =
|
||||
SearchView ->
|
||||
False
|
||||
|
||||
PublishView _ ->
|
||||
False
|
||||
|
||||
SelectView svm ->
|
||||
svm.action == EditSelected
|
||||
|
||||
@ -211,6 +225,10 @@ type Msg
|
||||
| RemoveItem String
|
||||
| MergeSelectedItems
|
||||
| MergeItemsMsg Comp.ItemMerge.Msg
|
||||
| PublishSelectedItems
|
||||
| PublishItemsMsg Comp.PublishItems.Msg
|
||||
| TogglePublishCurrentQueryView
|
||||
| PublishViewMsg Comp.PublishItems.Msg
|
||||
|
||||
|
||||
type SearchType
|
||||
@ -225,6 +243,7 @@ type SelectActionMode
|
||||
| ReprocessSelected
|
||||
| RestoreSelected
|
||||
| MergeSelected
|
||||
| PublishSelected
|
||||
|
||||
|
||||
type alias SearchParam =
|
||||
@ -251,10 +270,7 @@ doSearchDefaultCmd param model =
|
||||
let
|
||||
smask =
|
||||
Q.request model.searchMenuModel.searchMode <|
|
||||
Q.and
|
||||
[ Comp.SearchMenu.getItemQuery model.searchMenuModel
|
||||
, Maybe.map Q.Fragment model.powerSearchInput.input
|
||||
]
|
||||
createQuery model
|
||||
|
||||
mask =
|
||||
{ smask
|
||||
@ -272,6 +288,14 @@ doSearchDefaultCmd param model =
|
||||
Api.itemSearch param.flags mask ItemSearchAddResp
|
||||
|
||||
|
||||
createQuery : Model -> Maybe Q.ItemQuery
|
||||
createQuery model =
|
||||
Q.and
|
||||
[ Comp.SearchMenu.getItemQuery model.searchMenuModel
|
||||
, Maybe.map Q.Fragment model.powerSearchInput.input
|
||||
]
|
||||
|
||||
|
||||
resultsBelowLimit : UiSettings -> Model -> Bool
|
||||
resultsBelowLimit settings model =
|
||||
let
|
||||
|
@ -19,6 +19,7 @@ import Comp.ItemDetail.MultiEditMenu exposing (SaveNameState(..))
|
||||
import Comp.ItemMerge
|
||||
import Comp.LinkTarget exposing (LinkTarget)
|
||||
import Comp.PowerSearchInput
|
||||
import Comp.PublishItems
|
||||
import Comp.SearchMenu
|
||||
import Data.Flags exposing (Flags)
|
||||
import Data.ItemQuery as Q
|
||||
@ -237,6 +238,9 @@ update mId key flags settings msg model =
|
||||
|
||||
SelectView _ ->
|
||||
SimpleView
|
||||
|
||||
PublishView q ->
|
||||
PublishView q
|
||||
in
|
||||
withSub
|
||||
( { model | viewMode = nextView }
|
||||
@ -255,6 +259,9 @@ update mId key flags settings msg model =
|
||||
|
||||
SelectView _ ->
|
||||
( SearchView, Cmd.none )
|
||||
|
||||
PublishView q ->
|
||||
( PublishView q, Cmd.none )
|
||||
in
|
||||
withSub
|
||||
( { model
|
||||
@ -620,6 +627,85 @@ update mId key flags settings msg model =
|
||||
_ ->
|
||||
noSub ( model, Cmd.none )
|
||||
|
||||
PublishSelectedItems ->
|
||||
case model.viewMode of
|
||||
SelectView svm ->
|
||||
if svm.action == PublishSelected then
|
||||
let
|
||||
( mm, mc ) =
|
||||
Comp.PublishItems.init
|
||||
in
|
||||
noSub
|
||||
( { model
|
||||
| viewMode =
|
||||
SelectView
|
||||
{ svm
|
||||
| action = NoneAction
|
||||
, publishModel = mm
|
||||
}
|
||||
}
|
||||
, Cmd.map PublishItemsMsg mc
|
||||
)
|
||||
|
||||
else if svm.ids == Set.empty then
|
||||
noSub ( model, Cmd.none )
|
||||
|
||||
else
|
||||
let
|
||||
( mm, mc ) =
|
||||
Comp.PublishItems.initQuery
|
||||
(Q.ItemIdIn (Set.toList svm.ids))
|
||||
in
|
||||
noSub
|
||||
( { model
|
||||
| viewMode =
|
||||
SelectView
|
||||
{ svm
|
||||
| action = PublishSelected
|
||||
, publishModel = mm
|
||||
}
|
||||
}
|
||||
, Cmd.map PublishItemsMsg mc
|
||||
)
|
||||
|
||||
_ ->
|
||||
noSub ( model, Cmd.none )
|
||||
|
||||
PublishItemsMsg lmsg ->
|
||||
case model.viewMode of
|
||||
SelectView svm ->
|
||||
let
|
||||
result =
|
||||
Comp.PublishItems.update flags lmsg svm.publishModel
|
||||
|
||||
nextView =
|
||||
case result.outcome of
|
||||
Comp.PublishItems.OutcomeDone ->
|
||||
SelectView { svm | action = NoneAction }
|
||||
|
||||
Comp.PublishItems.OutcomeInProgress ->
|
||||
SelectView { svm | publishModel = result.model }
|
||||
|
||||
model_ =
|
||||
{ model | viewMode = nextView }
|
||||
in
|
||||
if result.outcome == Comp.PublishItems.OutcomeDone then
|
||||
update mId
|
||||
key
|
||||
flags
|
||||
settings
|
||||
(DoSearch model.searchTypeDropdownValue)
|
||||
model_
|
||||
|
||||
else
|
||||
noSub
|
||||
( model_
|
||||
, Cmd.map PublishItemsMsg result.cmd
|
||||
)
|
||||
|
||||
_ ->
|
||||
noSub ( model, Cmd.none )
|
||||
|
||||
EditMenuMsg lmsg ->
|
||||
case model.viewMode of
|
||||
SelectView svm ->
|
||||
@ -786,6 +872,38 @@ update mId key flags settings msg model =
|
||||
RemoveItem id ->
|
||||
update mId key flags settings (ItemCardListMsg (Comp.ItemCardList.RemoveItem id)) model
|
||||
|
||||
TogglePublishCurrentQueryView ->
|
||||
case createQuery model of
|
||||
Just q ->
|
||||
let
|
||||
( pm, pc ) =
|
||||
Comp.PublishItems.initQuery q
|
||||
in
|
||||
noSub ( { model | viewMode = PublishView pm }, Cmd.map PublishViewMsg pc )
|
||||
|
||||
Nothing ->
|
||||
noSub ( model, Cmd.none )
|
||||
|
||||
PublishViewMsg lmsg ->
|
||||
case model.viewMode of
|
||||
PublishView inPM ->
|
||||
let
|
||||
result =
|
||||
Comp.PublishItems.update flags lmsg inPM
|
||||
in
|
||||
case result.outcome of
|
||||
Comp.PublishItems.OutcomeInProgress ->
|
||||
noSub
|
||||
( { model | viewMode = PublishView result.model }
|
||||
, Cmd.map PublishViewMsg result.cmd
|
||||
)
|
||||
|
||||
Comp.PublishItems.OutcomeDone ->
|
||||
noSub ( { model | viewMode = SearchView }, Cmd.none )
|
||||
|
||||
_ ->
|
||||
noSub ( model, Cmd.none )
|
||||
|
||||
|
||||
|
||||
--- Helpers
|
||||
|
@ -13,9 +13,12 @@ import Comp.ItemCardList
|
||||
import Comp.ItemMerge
|
||||
import Comp.MenuBar as MB
|
||||
import Comp.PowerSearchInput
|
||||
import Comp.PublishItems
|
||||
import Comp.SearchMenu
|
||||
import Comp.SearchStatsView
|
||||
import Data.Flags exposing (Flags)
|
||||
import Data.Icons as Icons
|
||||
import Data.ItemQuery as Q
|
||||
import Data.ItemSelection
|
||||
import Data.SearchMode
|
||||
import Data.UiSettings exposing (UiSettings)
|
||||
@ -63,29 +66,52 @@ viewContent texts flags settings model =
|
||||
mainView : Texts -> Flags -> UiSettings -> Model -> List (Html Msg)
|
||||
mainView texts flags settings model =
|
||||
let
|
||||
mergeView =
|
||||
otherView =
|
||||
case model.viewMode of
|
||||
SelectView svm ->
|
||||
case svm.action of
|
||||
MergeSelected ->
|
||||
Just svm
|
||||
Just
|
||||
[ div [ class "sm:relative mb-2" ]
|
||||
(itemMergeView texts settings svm)
|
||||
]
|
||||
|
||||
PublishSelected ->
|
||||
Just
|
||||
[ div [ class "sm:relative mb-2" ]
|
||||
(itemPublishView texts flags svm)
|
||||
]
|
||||
|
||||
_ ->
|
||||
Nothing
|
||||
|
||||
_ ->
|
||||
PublishView pm ->
|
||||
Just
|
||||
[ div [ class "sm:relative mb-2" ]
|
||||
(publishResults texts flags model pm)
|
||||
]
|
||||
|
||||
SimpleView ->
|
||||
Nothing
|
||||
|
||||
SearchView ->
|
||||
Nothing
|
||||
in
|
||||
case mergeView of
|
||||
Just svm ->
|
||||
[ div [ class "sm:relative mb-2" ]
|
||||
(itemMergeView texts settings svm)
|
||||
]
|
||||
case otherView of
|
||||
Just body ->
|
||||
body
|
||||
|
||||
Nothing ->
|
||||
itemCardList texts flags settings model
|
||||
|
||||
|
||||
itemPublishView : Texts -> Flags -> SelectViewModel -> List (Html Msg)
|
||||
itemPublishView texts flags svm =
|
||||
[ Html.map PublishItemsMsg
|
||||
(Comp.PublishItems.view texts.publishItems flags svm.publishModel)
|
||||
]
|
||||
|
||||
|
||||
itemMergeView : Texts -> UiSettings -> SelectViewModel -> List (Html Msg)
|
||||
itemMergeView texts settings svm =
|
||||
[ Html.map MergeItemsMsg
|
||||
@ -93,6 +119,13 @@ itemMergeView texts settings svm =
|
||||
]
|
||||
|
||||
|
||||
publishResults : Texts -> Flags -> Model -> Comp.PublishItems.Model -> List (Html Msg)
|
||||
publishResults texts flags model pm =
|
||||
[ Html.map PublishViewMsg
|
||||
(Comp.PublishItems.view texts.publishItems flags pm)
|
||||
]
|
||||
|
||||
|
||||
confirmModal : Texts -> Model -> List (Html Msg)
|
||||
confirmModal texts model =
|
||||
let
|
||||
@ -148,6 +181,9 @@ itemsBar texts flags settings model =
|
||||
SelectView svm ->
|
||||
[ editMenuBar texts model svm ]
|
||||
|
||||
PublishView query ->
|
||||
[ defaultMenuBar texts flags settings model ]
|
||||
|
||||
|
||||
defaultMenuBar : Texts -> Flags -> UiSettings -> Model -> Html Msg
|
||||
defaultMenuBar texts flags settings model =
|
||||
@ -215,6 +251,25 @@ defaultMenuBar texts flags settings model =
|
||||
MB.view
|
||||
{ end =
|
||||
[ MB.CustomElement <|
|
||||
B.secondaryBasicButton
|
||||
{ label = ""
|
||||
, icon = Icons.share
|
||||
, disabled = createQuery model == Nothing
|
||||
, handler = onClick TogglePublishCurrentQueryView
|
||||
, attrs =
|
||||
[ title <|
|
||||
if createQuery model == Nothing then
|
||||
texts.nothingSelectedToShare
|
||||
|
||||
else
|
||||
texts.publishCurrentQueryTitle
|
||||
, classList
|
||||
[ ( btnStyle, True )
|
||||
]
|
||||
, href "#"
|
||||
]
|
||||
}
|
||||
, MB.CustomElement <|
|
||||
B.secondaryBasicButton
|
||||
{ label = ""
|
||||
, icon =
|
||||
@ -332,6 +387,17 @@ editMenuBar texts model svm =
|
||||
, ( "hidden", model.searchMenuModel.searchMode == Data.SearchMode.Trashed )
|
||||
]
|
||||
}
|
||||
, MB.CustomButton
|
||||
{ tagger = PublishSelectedItems
|
||||
, label = ""
|
||||
, icon = Just Icons.share
|
||||
, title = texts.publishItemsTitle selectCount
|
||||
, inputClass =
|
||||
[ ( btnStyle, True )
|
||||
, ( "bg-gray-200 dark:bg-bluegray-600", svm.action == PublishSelected )
|
||||
, ( "hidden", model.searchMenuModel.searchMode == Data.SearchMode.Trashed )
|
||||
]
|
||||
}
|
||||
]
|
||||
, end =
|
||||
[ MB.CustomButton
|
||||
@ -413,12 +479,12 @@ itemCardList texts _ settings model =
|
||||
settings
|
||||
model.itemListModel
|
||||
)
|
||||
, loadMore settings model
|
||||
, loadMore texts settings model
|
||||
]
|
||||
|
||||
|
||||
loadMore : UiSettings -> Model -> Html Msg
|
||||
loadMore settings model =
|
||||
loadMore : Texts -> UiSettings -> Model -> Html Msg
|
||||
loadMore texts settings model =
|
||||
let
|
||||
inactive =
|
||||
not model.moreAvailable || model.moreInProgress || model.searchInProgress
|
||||
@ -430,10 +496,10 @@ loadMore settings model =
|
||||
[ B.secondaryBasicButton
|
||||
{ label =
|
||||
if model.moreAvailable then
|
||||
"Load more…"
|
||||
texts.loadMore
|
||||
|
||||
else
|
||||
"That's all"
|
||||
texts.thatsAll
|
||||
, icon =
|
||||
if model.moreInProgress then
|
||||
"fa fa-circle-notch animate-spin"
|
||||
|
@ -48,6 +48,11 @@ errorMessage =
|
||||
" border border-red-600 bg-red-50 text-red-600 dark:border-orange-800 dark:bg-orange-300 dark:text-orange-800 px-2 py-2 rounded "
|
||||
|
||||
|
||||
errorText : String
|
||||
errorText =
|
||||
" text-red-600 dark:text-orange-800 "
|
||||
|
||||
|
||||
warnMessage : String
|
||||
warnMessage =
|
||||
warnMessageColors ++ " border dark:bg-opacity-25 px-2 py-2 rounded "
|
||||
|
Loading…
x
Reference in New Issue
Block a user