Allow to reprocess single and multiple items in the ui

This commit is contained in:
Eike Kettner
2021-03-11 23:13:34 +01:00
parent 058c31e1f6
commit 76f5ab6c68
11 changed files with 382 additions and 83 deletions

View File

@ -89,6 +89,8 @@ module Api exposing
, register
, removeMember
, removeTagsMultiple
, reprocessItem
, reprocessMultiple
, sendMail
, setAttachmentName
, setCollectiveSettings
@ -1423,6 +1425,20 @@ getJobQueueStateTask flags =
--- Item (Mulit Edit)
reprocessMultiple :
Flags
-> Set String
-> (Result Http.Error BasicResult -> msg)
-> Cmd msg
reprocessMultiple flags items receive =
Http2.authPost
{ url = flags.config.baseUrl ++ "/api/v1/sec/items/reprocess"
, account = getAccount flags
, body = Http.jsonBody (Api.Model.IdList.encode (Set.toList items |> IdList))
, expect = Http.expectJson receive Api.Model.BasicResult.decoder
}
confirmMultiple :
Flags
-> Set String
@ -1637,6 +1653,21 @@ deleteAllItems flags ids receive =
--- Item
reprocessItem :
Flags
-> String
-> List String
-> (Result Http.Error BasicResult -> msg)
-> Cmd msg
reprocessItem flags itemId attachIds receive =
Http2.authPost
{ url = flags.config.baseUrl ++ "/api/v1/sec/item/" ++ itemId ++ "/reprocess"
, account = getAccount flags
, body = Http.jsonBody (Api.Model.IdList.encode (IdList attachIds))
, expect = Http.expectJson receive Api.Model.BasicResult.decoder
}
attachmentPreviewURL : String -> String
attachmentPreviewURL id =
"/api/v1/sec/attachment/" ++ id ++ "/preview?withFallback=true"

View File

@ -0,0 +1,76 @@
module Comp.ConfirmModal exposing
( Settings
, defaultSettings
, view
)
import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (onClick)
import Styles as S
type alias Settings msg =
{ enabled : Bool
, extraClass : String
, headerIcon : String
, headerClass : String
, confirmText : String
, cancelText : String
, message : String
, confirm : msg
, cancel : msg
}
defaultSettings : msg -> msg -> String -> Settings msg
defaultSettings confirm cancel confirmMsg =
{ enabled = True
, extraClass = ""
, headerIcon = "fa fa-exclamation-circle mr-3"
, headerClass = "text-2xl font-bold text-center w-full"
, confirmText = "Ok"
, cancelText = "Cancel"
, message = confirmMsg
, confirm = confirm
, cancel = cancel
}
view : Settings msg -> Html msg
view settings =
div
[ class S.dimmer
, class settings.extraClass
, classList
[ ( "hidden", not settings.enabled )
]
]
[ div [ class settings.headerClass ]
[ i
[ class settings.headerIcon
, class "text-gray-200 font-semibold"
, classList [ ( "hidden", settings.headerClass == "" ) ]
]
[]
, span [ class "text-gray-200 font-semibold" ]
[ text settings.message
]
]
, div [ class "flex flex-row space-x-2 text-xs mt-2" ]
[ a
[ class (S.primaryButton ++ "block font-semibold")
, href "#"
, onClick settings.confirm
]
[ text settings.confirmText
]
, a
[ class (S.secondaryButton ++ "block font-semibold")
, href "#"
, onClick settings.cancel
]
[ text settings.cancelText
]
]
]

View File

@ -28,6 +28,7 @@ import Api.Model.SentMails exposing (SentMails)
import Api.Model.Tag exposing (Tag)
import Api.Model.TagList exposing (TagList)
import Comp.AttachmentMeta
import Comp.ConfirmModal
import Comp.CustomFieldMultiInput
import Comp.DatePicker
import Comp.DetailEdit
@ -72,7 +73,7 @@ type alias Model =
, nameSaveThrottle : Throttle Msg
, notesModel : Maybe String
, notesField : NotesField
, deleteItemConfirm : Comp.YesNoDimmer.Model
, itemModal : Maybe (Comp.ConfirmModal.Settings Msg)
, itemDatePicker : DatePicker
, itemDate : Maybe Int
, itemProposals : ItemProposals
@ -87,7 +88,7 @@ type alias Model =
, attachMeta : Dict String Comp.AttachmentMeta.Model
, attachMetaOpen : Bool
, pdfNativeView : Maybe Bool
, deleteAttachConfirm : Comp.YesNoDimmer.Model
, attachModal : Maybe (Comp.ConfirmModal.Settings Msg)
, addFilesOpen : Bool
, addFilesModel : Comp.Dropzone.Model
, selectedFiles : List File
@ -180,7 +181,7 @@ emptyModel =
, nameSaveThrottle = Throttle.create 1
, notesModel = Nothing
, notesField = ViewNotes
, deleteItemConfirm = Comp.YesNoDimmer.emptyModel
, itemModal = Nothing
, itemDatePicker = Comp.DatePicker.emptyModel
, itemDate = Nothing
, itemProposals = Api.Model.ItemProposals.empty
@ -195,7 +196,7 @@ emptyModel =
, attachMeta = Dict.empty
, attachMetaOpen = False
, pdfNativeView = Nothing
, deleteAttachConfirm = Comp.YesNoDimmer.emptyModel
, attachModal = Nothing
, addFilesOpen = False
, addFilesModel = Comp.Dropzone.init []
, selectedFiles = []
@ -247,7 +248,8 @@ type Msg
| SetDueDateSuggestion Int
| ItemDatePickerMsg Comp.DatePicker.Msg
| DueDatePickerMsg Comp.DatePicker.Msg
| DeleteItemConfirm Comp.YesNoDimmer.Msg
| DeleteItemConfirmed
| ItemModalCancelled
| RequestDelete
| SaveResp (Result Http.Error BasicResult)
| DeleteResp (Result Http.Error BasicResult)
@ -265,7 +267,8 @@ type Msg
| AttachMetaMsg String Comp.AttachmentMeta.Msg
| TogglePdfNativeView Bool
| RequestDeleteAttachment String
| DeleteAttachConfirm String Comp.YesNoDimmer.Msg
| DeleteAttachConfirmed String
| AttachModalCancelled
| DeleteAttachResp (Result Http.Error BasicResult)
| AddFilesToggle
| AddFilesMsg Comp.Dropzone.Msg
@ -304,6 +307,11 @@ type Msg
| ToggleAttachmentDropdown
| ToggleAkkordionTab String
| ToggleOpenAllAkkordionTabs
| RequestReprocessFile String
| ReprocessFileConfirmed String
| ReprocessFileResp (Result Http.Error BasicResult)
| RequestReprocessItem
| ReprocessItemConfirmed
type SaveNameState

View File

@ -3,6 +3,7 @@ module Comp.ItemDetail.SingleAttachment exposing (view)
import Api
import Api.Model.Attachment exposing (Attachment)
import Comp.AttachmentMeta
import Comp.ConfirmModal
import Comp.ItemDetail.Model
exposing
( Model
@ -11,7 +12,6 @@ import Comp.ItemDetail.Model
, SaveNameState(..)
)
import Comp.MenuBar as MB
import Comp.YesNoDimmer
import Data.UiSettings exposing (UiSettings)
import Dict
import Html exposing (..)
@ -37,12 +37,7 @@ view settings model pos attach =
[ ( "hidden", not (attachmentVisible model pos) )
]
]
[ Html.map (DeleteAttachConfirm attach.id)
(Comp.YesNoDimmer.viewN
True
(Comp.YesNoDimmer.defaultSettings2 "Really delete this file?")
model.deleteAttachConfirm
)
[ renderModal model
, div
[ class "flex flex-row px-2 py-2 text-sm"
, class S.border
@ -213,6 +208,13 @@ attachHeader settings model _ attach =
, href "#"
]
}
, { icon = "fa fa-redo-alt"
, label = "Re-process this file"
, attrs =
[ onClick (RequestReprocessFile attach.id)
, href "#"
]
}
, { icon = "fa fa-trash"
, label = "Delete this file"
, attrs =
@ -344,3 +346,13 @@ menuItem model pos attach =
|> text
]
]
renderModal : Model -> Html Msg
renderModal model =
case model.attachModal of
Just confirmModal ->
Comp.ConfirmModal.view confirmModal
Nothing ->
span [ class "hidden" ] []

View File

@ -16,6 +16,7 @@ import Api.Model.ReferenceList exposing (ReferenceList)
import Api.Model.Tag exposing (Tag)
import Browser.Navigation as Nav
import Comp.AttachmentMeta
import Comp.ConfirmModal
import Comp.CustomFieldMultiInput
import Comp.DatePicker
import Comp.DetailEdit
@ -43,7 +44,6 @@ import Comp.MarkdownInput
import Comp.OrgForm
import Comp.PersonForm
import Comp.SentMails
import Comp.YesNoDimmer
import Data.CustomFieldChange exposing (CustomFieldChange(..))
import Data.Direction
import Data.Fields exposing (Field)
@ -532,22 +532,28 @@ update key flags inav settings msg model =
RemoveDueDate ->
resultModelCmd ( { model | dueDate = Nothing }, setDueDate flags model Nothing )
DeleteItemConfirm m ->
DeleteItemConfirmed ->
let
( cm, confirmed ) =
Comp.YesNoDimmer.update m model.deleteItemConfirm
cmd =
if confirmed then
Api.deleteItem flags model.item.id DeleteResp
else
Cmd.none
Api.deleteItem flags model.item.id DeleteResp
in
resultModelCmd ( { model | deleteItemConfirm = cm }, cmd )
resultModelCmd ( { model | itemModal = Nothing }, cmd )
ItemModalCancelled ->
resultModel { model | itemModal = Nothing }
RequestDelete ->
update key flags inav settings (DeleteItemConfirm Comp.YesNoDimmer.activate) model
let
confirmMsg =
"Really delete this item? This cannot be undone."
confirm =
Comp.ConfirmModal.defaultSettings
DeleteItemConfirmed
ItemModalCancelled
confirmMsg
in
resultModel { model | itemModal = Just confirm }
SetCorrOrgSuggestion idname ->
resultModelCmd ( model, setCorrOrg flags model (Just idname) )
@ -913,19 +919,15 @@ update key flags inav settings msg model =
, attachmentDropdownOpen = False
}
DeleteAttachConfirm attachId lmsg ->
DeleteAttachConfirmed attachId ->
let
( cm, confirmed ) =
Comp.YesNoDimmer.update lmsg model.deleteAttachConfirm
cmd =
if confirmed then
Api.deleteAttachment flags attachId DeleteAttachResp
else
Cmd.none
Api.deleteAttachment flags attachId DeleteAttachResp
in
resultModelCmd ( { model | deleteAttachConfirm = cm }, cmd )
resultModelCmd ( { model | attachModal = Nothing }, cmd )
AttachModalCancelled ->
resultModel { model | attachModal = Nothing }
DeleteAttachResp (Ok res) ->
if res.success then
@ -938,12 +940,20 @@ update key flags inav settings msg model =
resultModel model
RequestDeleteAttachment id ->
update key
flags
inav
settings
(DeleteAttachConfirm id Comp.YesNoDimmer.activate)
{ model | attachmentDropdownOpen = False }
let
confirmModal =
Comp.ConfirmModal.defaultSettings
(DeleteAttachConfirmed id)
AttachModalCancelled
"Really delete this file?"
model_ =
{ model
| attachmentDropdownOpen = False
, attachModal = Just confirmModal
}
in
resultModel model_
AddFilesToggle ->
resultModel
@ -1508,6 +1518,73 @@ update key flags inav settings msg model =
in
resultModel { model | editMenuTabsOpen = next }
RequestReprocessFile id ->
let
confirmMsg =
if model.item.state == "created" then
"Reprocessing this file may change metadata of "
++ "this item, since it is unconfirmed. Do you want to proceed?"
else
"Reprocessing this file will not change metadata of "
++ "this item, since it has been confirmed. Do you want to proceed?"
confirmModal =
Comp.ConfirmModal.defaultSettings
(ReprocessFileConfirmed id)
AttachModalCancelled
confirmMsg
model_ =
{ model
| attachmentDropdownOpen = False
, attachModal = Just confirmModal
}
in
resultModel model_
ReprocessFileConfirmed id ->
let
cmd =
Api.reprocessItem flags model.item.id [ id ] ReprocessFileResp
in
resultModelCmd ( { model | attachModal = Nothing }, cmd )
ReprocessFileResp _ ->
resultModel model
RequestReprocessItem ->
let
confirmMsg =
if model.item.state == "created" then
"Reprocessing this item may change its metadata, "
++ "since it is unconfirmed. Do you want to proceed?"
else
"Reprocessing this item will not change its metadata, "
++ "since it has been confirmed. Do you want to proceed?"
confirmModal =
Comp.ConfirmModal.defaultSettings
ReprocessItemConfirmed
ItemModalCancelled
confirmMsg
model_ =
{ model
| attachmentDropdownOpen = False
, itemModal = Just confirmModal
}
in
resultModel model_
ReprocessItemConfirmed ->
let
cmd =
Api.reprocessItem flags model.item.id [] ReprocessFileResp
in
resultModelCmd ( { model | itemModal = Nothing }, cmd )
--- Helper

View File

@ -1,6 +1,7 @@
module Comp.ItemDetail.View2 exposing (view)
import Comp.Basic as B
import Comp.ConfirmModal
import Comp.DetailEdit
import Comp.ItemDetail.AddFilesForm
import Comp.ItemDetail.ItemInfoHeader
@ -16,7 +17,6 @@ import Comp.ItemDetail.SingleAttachment
import Comp.ItemMail
import Comp.MenuBar as MB
import Comp.SentMails
import Comp.YesNoDimmer
import Data.Icons as Icons
import Data.ItemNav exposing (ItemNav)
import Data.UiSettings exposing (UiSettings)
@ -34,15 +34,20 @@ view inav settings model =
[ header settings model
, menuBar inav settings model
, body inav settings model
, Html.map DeleteItemConfirm
(Comp.YesNoDimmer.viewN
True
(Comp.YesNoDimmer.defaultSettings2 "Really delete the complete item?")
model.deleteItemConfirm
)
, itemModal model
]
itemModal : Model -> Html Msg
itemModal model =
case model.itemModal of
Just confirm ->
Comp.ConfirmModal.view confirm
Nothing ->
span [ class "hidden" ] []
header : UiSettings -> Model -> Html Msg
header settings model =
div [ class "my-3" ]
@ -166,6 +171,15 @@ menuBar inav settings model =
]
[ i [ class "fa fa-eye-slash font-thin" ] []
]
, MB.CustomElement <|
a
[ class S.secondaryBasicButton
, href "#"
, onClick RequestReprocessItem
, title "Reprocess this item"
]
[ i [ class "fa fa-redo" ] []
]
, MB.CustomElement <|
a
[ class S.deleteButton

View File

@ -22,6 +22,7 @@ import Api.Model.BasicResult exposing (BasicResult)
import Api.Model.ItemLightList exposing (ItemLightList)
import Api.Model.SearchStats exposing (SearchStats)
import Browser.Dom as Dom
import Comp.ConfirmModal
import Comp.FixedDropdown
import Comp.ItemCardList
import Comp.ItemDetail.FormChange exposing (FormChange)
@ -64,7 +65,7 @@ type alias Model =
type alias SelectViewModel =
{ ids : Set String
, action : SelectActionMode
, deleteAllConfirm : Comp.YesNoDimmer.Model
, confirmModal : Maybe (Comp.ConfirmModal.Settings Msg)
, editModel : Comp.ItemDetail.MultiEditMenu.Model
, saveNameState : SaveNameState
, saveCustomFieldState : Set String
@ -75,7 +76,7 @@ initSelectViewModel : SelectViewModel
initSelectViewModel =
{ ids = Set.empty
, action = NoneAction
, deleteAllConfirm = Comp.YesNoDimmer.initActive
, confirmModal = Nothing
, editModel = Comp.ItemDetail.MultiEditMenu.init
, saveNameState = SaveSuccess
, saveCustomFieldState = Set.empty
@ -187,7 +188,8 @@ type Msg
| SelectAllItems
| SelectNoItems
| RequestDeleteSelected
| DeleteSelectedConfirmMsg Comp.YesNoDimmer.Msg
| DeleteSelectedConfirmed
| CloseConfirmModal
| EditSelectedItems
| EditMenuMsg Comp.ItemDetail.MultiEditMenu.Msg
| MultiUpdateResp FormChange (Result Http.Error BasicResult)
@ -199,6 +201,8 @@ type Msg
| TogglePreviewFullWidth
| PowerSearchMsg Comp.PowerSearchInput.Msg
| KeyUpPowerSearchbarMsg (Maybe KeyCode)
| RequestReprocessSelected
| ReprocessSelectedConfirmed
type SearchType
@ -210,6 +214,7 @@ type SelectActionMode
= NoneAction
| DeleteSelected
| EditSelected
| ReprocessSelected
type alias SearchParam =

View File

@ -3,6 +3,7 @@ module Page.Home.Update exposing (update)
import Api
import Api.Model.ItemLightList exposing (ItemLightList)
import Browser.Navigation as Nav
import Comp.ConfirmModal
import Comp.FixedDropdown
import Comp.ItemCardList
import Comp.ItemDetail.FormChange exposing (FormChange(..))
@ -10,7 +11,6 @@ import Comp.ItemDetail.MultiEditMenu exposing (SaveNameState(..))
import Comp.LinkTarget exposing (LinkTarget)
import Comp.PowerSearchInput
import Comp.SearchMenu
import Comp.YesNoDimmer
import Data.Flags exposing (Flags)
import Data.ItemQuery as Q
import Data.ItemSelection
@ -358,34 +358,20 @@ update mId key flags settings msg model =
_ ->
noSub ( model, Cmd.none )
DeleteSelectedConfirmMsg lmsg ->
DeleteSelectedConfirmed ->
case model.viewMode of
SelectView svm ->
let
( confirmModel, confirmed ) =
Comp.YesNoDimmer.update lmsg svm.deleteAllConfirm
cmd =
if confirmed then
Api.deleteAllItems flags svm.ids DeleteAllResp
else
Cmd.none
act =
if confirmModel.active || confirmed then
DeleteSelected
else
NoneAction
Api.deleteAllItems flags svm.ids DeleteAllResp
in
noSub
( { model
| viewMode =
SelectView
{ svm
| deleteAllConfirm = confirmModel
, action = act
| confirmModal = Nothing
, action = DeleteSelected
}
}
, cmd
@ -416,6 +402,74 @@ update mId key flags settings msg model =
DeleteAllResp (Err _) ->
noSub ( model, Cmd.none )
RequestReprocessSelected ->
case model.viewMode of
SelectView svm ->
if svm.ids == Set.empty then
noSub ( model, Cmd.none )
else
let
lmsg =
Comp.ConfirmModal.defaultSettings
ReprocessSelectedConfirmed
CloseConfirmModal
"Really reprocess all selected items? Metadata of unconfirmed items may change."
model_ =
{ model
| viewMode =
SelectView
{ svm
| action = ReprocessSelected
, confirmModal = Just lmsg
}
}
in
noSub ( model_, Cmd.none )
_ ->
noSub ( model, Cmd.none )
CloseConfirmModal ->
case model.viewMode of
SelectView svm ->
noSub
( { model
| viewMode = SelectView { svm | confirmModal = Nothing, action = NoneAction }
}
, Cmd.none
)
_ ->
noSub ( model, Cmd.none )
ReprocessSelectedConfirmed ->
case model.viewMode of
SelectView svm ->
if svm.ids == Set.empty then
noSub ( model, Cmd.none )
else
let
cmd =
Api.reprocessMultiple flags svm.ids DeleteAllResp
in
noSub
( { model
| viewMode =
SelectView
{ svm
| confirmModal = Nothing
, action = ReprocessSelected
}
}
, cmd
)
_ ->
noSub ( model, Cmd.none )
RequestDeleteSelected ->
case model.viewMode of
SelectView svm ->
@ -425,12 +479,22 @@ update mId key flags settings msg model =
else
let
lmsg =
DeleteSelectedConfirmMsg Comp.YesNoDimmer.activate
Comp.ConfirmModal.defaultSettings
DeleteSelectedConfirmed
CloseConfirmModal
"Really delete all selected items?"
model_ =
{ model | viewMode = SelectView { svm | action = DeleteSelected } }
{ model
| viewMode =
SelectView
{ svm
| action = DeleteSelected
, confirmModal = Just lmsg
}
}
in
update mId key flags settings lmsg model_
noSub ( model_, Cmd.none )
_ ->
noSub ( model, Cmd.none )

View File

@ -1,6 +1,7 @@
module Page.Home.View2 exposing (viewContent, viewSidebar)
import Comp.Basic as B
import Comp.ConfirmModal
import Comp.ItemCardList
import Comp.MenuBar as MB
import Comp.PowerSearchInput
@ -67,13 +68,13 @@ deleteSelectedDimmer model =
in
case model.viewMode of
SelectView svm ->
[ Html.map DeleteSelectedConfirmMsg
(Comp.YesNoDimmer.viewN
(selectAction == DeleteSelected)
deleteAllDimmer
svm.deleteAllConfirm
)
]
case svm.confirmModal of
Just confirm ->
[ Comp.ConfirmModal.view confirm
]
Nothing ->
[]
_ ->
[]
@ -219,6 +220,16 @@ editMenuBar model svm =
, ( "bg-gray-200 dark:bg-bluegray-600", svm.action == EditSelected )
]
}
, MB.CustomButton
{ tagger = RequestReprocessSelected
, label = ""
, icon = Just "fa fa-redo"
, title = "Reprocess " ++ selectCount ++ " selected items"
, inputClass =
[ ( btnStyle, True )
, ( "bg-gray-200 dark:bg-bluegray-600", svm.action == ReprocessSelected )
]
}
, MB.CustomButton
{ tagger = RequestDeleteSelected
, label = ""

View File

@ -313,7 +313,7 @@ editLinkTableCellStyle =
dimmer : String
dimmer =
" absolute top-0 left-0 w-full h-full bg-black bg-opacity-90 dark:bg-bluegray-900 dark:bg-opacity-90 z-50 flex flex-col items-center justify-center px-4 py-2 "
" absolute top-0 left-0 w-full h-full bg-black bg-opacity-90 dark:bg-bluegray-900 dark:bg-opacity-90 z-50 flex flex-col items-center justify-center px-4 md:px-8 py-2 "
dimmerLight : String