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

@ -2117,7 +2117,7 @@ paths:
If the item is not in "confirmed" state, its associated metada
is also updated. Otherwise only the file metadata is updated
(like extracted text etc).
(text analysis).
security:
- authTokenHeader: []
parameters:
@ -2519,7 +2519,8 @@ paths:
description: |
Given a list of item-ids, submits all these items for
reprocessing. All attachments of these items will be
reprocessed. Item metadata is not changed.
reprocessed. Item metadata may be changed if an item is not
confirmed. Confirmed items are not changed.
security:
- authTokenHeader: []
requestBody:

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