From 288ed83b7f6d8c8224fb428f3d1c2d0f67d45e8a Mon Sep 17 00:00:00 2001 From: eikek Date: Thu, 17 Mar 2022 23:25:04 +0100 Subject: [PATCH] Make ItemMerge independent from the action --- modules/webapp/src/main/elm/Api.elm | 21 +++-- .../webapp/src/main/elm/Comp/ItemMerge.elm | 86 +++++++++++-------- .../src/main/elm/Messages/Comp/ItemMerge.elm | 36 +------- .../src/main/elm/Messages/Page/Search.elm | 28 ++++++ .../src/main/elm/Page/Search/Update.elm | 9 +- .../webapp/src/main/elm/Page/Search/View2.elm | 13 ++- 6 files changed, 117 insertions(+), 76 deletions(-) diff --git a/modules/webapp/src/main/elm/Api.elm b/modules/webapp/src/main/elm/Api.elm index c8f43b96..e51c15b4 100644 --- a/modules/webapp/src/main/elm/Api.elm +++ b/modules/webapp/src/main/elm/Api.elm @@ -115,6 +115,7 @@ module Api exposing , loginSession , logout , mergeItems + , mergeItemsTask , moveAttachmentBefore , newInvite , openIdAuthLink @@ -1717,18 +1718,26 @@ getJobQueueStateTask flags = --- Item (Mulit Edit) +mergeItemsTask : Flags -> List String -> Task.Task Http.Error BasicResult +mergeItemsTask flags ids = + Http2.authTask + { url = flags.config.baseUrl ++ "/api/v1/sec/items/merge" + , account = getAccount flags + , body = Http.jsonBody (Api.Model.IdList.encode (IdList ids)) + , method = "POST" + , headers = [] + , resolver = Http2.jsonResolver Api.Model.BasicResult.decoder + , timeout = Nothing + } + + mergeItems : Flags -> List String -> (Result Http.Error BasicResult -> msg) -> Cmd msg mergeItems flags items receive = - Http2.authPost - { url = flags.config.baseUrl ++ "/api/v1/sec/items/merge" - , account = getAccount flags - , body = Http.jsonBody (Api.Model.IdList.encode (IdList items)) - , expect = Http.expectJson receive Api.Model.BasicResult.decoder - } + mergeItemsTask flags items |> Task.attempt receive reprocessMultiple : diff --git a/modules/webapp/src/main/elm/Comp/ItemMerge.elm b/modules/webapp/src/main/elm/Comp/ItemMerge.elm index 6206e03d..52241a1e 100644 --- a/modules/webapp/src/main/elm/Comp/ItemMerge.elm +++ b/modules/webapp/src/main/elm/Comp/ItemMerge.elm @@ -36,6 +36,7 @@ import Html5.DragDrop as DD import Http import Messages.Comp.ItemMerge exposing (Texts) import Styles as S +import Task exposing (Task) import Util.CustomField import Util.Item import Util.List @@ -89,18 +90,22 @@ type alias DDMsg = type FormState = FormStateInitial | FormStateHttp Http.Error - | FormStateMergeSuccessful + | FormStateActionSuccessful | FormStateError String - | FormStateMergeInProcess + | FormStateActionInProcess --- Update +type alias Action = + List String -> Task Http.Error BasicResult + + type Outcome = OutcomeCancel - | OutcomeMerged + | OutcomeActionDone | OutcomeNotYet @@ -123,15 +128,15 @@ type Msg = ItemResp (Result Http.Error ItemLightList) | ToggleInfoText | DragDrop (DD.Msg Int Int) - | SubmitMerge - | CancelMerge - | MergeResp (Result Http.Error BasicResult) + | SubmitAction + | CancelAction + | ActionResp (Result Http.Error BasicResult) | RemoveItem String | MoveItem Int Int -update : Flags -> Msg -> Model -> UpdateResult -update flags msg model = +update : Flags -> Action -> Msg -> Model -> UpdateResult +update _ action msg model = case msg of ItemResp (Ok list) -> notDoneResult ( init (flatten list), Cmd.none ) @@ -139,11 +144,11 @@ update flags msg model = ItemResp (Err err) -> notDoneResult ( { model | formState = FormStateHttp err }, Cmd.none ) - MergeResp (Ok result) -> + ActionResp (Ok result) -> if result.success then - { model = { model | formState = FormStateMergeSuccessful } + { model = { model | formState = FormStateActionSuccessful } , cmd = Cmd.none - , outcome = OutcomeMerged + , outcome = OutcomeActionDone } else @@ -152,7 +157,7 @@ update flags msg model = , outcome = OutcomeNotYet } - MergeResp (Err err) -> + ActionResp (Err err) -> { model = { model | formState = FormStateHttp err } , cmd = Cmd.none , outcome = OutcomeNotYet @@ -203,17 +208,17 @@ update flags msg model = in notDoneResult ( { model | items = items }, Cmd.none ) - SubmitMerge -> + SubmitAction -> let ids = List.map .id model.items in notDoneResult - ( { model | formState = FormStateMergeInProcess } - , Api.mergeItems flags ids MergeResp + ( { model | formState = FormStateActionInProcess } + , action ids |> Task.attempt ActionResp ) - CancelMerge -> + CancelAction -> { model = model , cmd = Cmd.none , outcome = OutcomeCancel @@ -229,14 +234,26 @@ flatten list = --- View -view : Texts -> UiSettings -> Model -> Html Msg -view texts settings model = +type alias ViewConfig = + { infoMessage : String + , warnMessage : String + , actionButton : String + , actionTitle : String + , cancelTitle : String + , actionSuccessful : String + , actionInProcess : String + } + + +view : Texts -> ViewConfig -> UiSettings -> Model -> Html Msg +view texts cfg settings model = div [ class "px-2 mb-4" ] [ h1 [ class S.header1 ] [ text texts.title , a [ class "ml-2" , class S.link + , classList [ ( "hidden", cfg.infoMessage == "" ) ] , href "#" , onClick ToggleInfoText ] @@ -245,36 +262,37 @@ view texts settings model = ] , p [ class S.infoMessage - , classList [ ( "hidden", not model.showInfoText ) ] + , classList [ ( "hidden", not model.showInfoText || cfg.infoMessage == "" ) ] ] - [ text texts.infoText + [ text cfg.infoMessage ] , p [ class S.warnMessage , class "mt-2" + , classList [ ( "hidden", cfg.warnMessage == "" ) ] ] - [ text texts.deleteWarn + [ text cfg.warnMessage ] , MB.view <| { start = [ MB.PrimaryButton - { tagger = SubmitMerge - , title = texts.submitMergeTitle + { tagger = SubmitAction + , title = cfg.actionTitle , icon = Just "fa fa-less-than" - , label = texts.submitMerge + , label = cfg.actionButton } , MB.SecondaryButton - { tagger = CancelMerge - , title = texts.cancelMergeTitle + { tagger = CancelAction + , title = cfg.cancelTitle , icon = Just "fa fa-times" - , label = texts.cancelMerge + , label = texts.cancelView } ] , end = [] , rootClasses = "my-4" , sticky = True } - , renderFormState texts model + , renderFormState texts cfg model , div [ class "flex-col px-2" ] (List.indexedMap (itemCard texts settings model) model.items) ] @@ -494,8 +512,8 @@ mainTagsAndFields2 settings item = (renderFields ++ renderTags) -renderFormState : Texts -> Model -> Html Msg -renderFormState texts model = +renderFormState : Texts -> ViewConfig -> Model -> Html Msg +renderFormState texts cfg model = case model.formState of FormStateInitial -> span [ class "hidden" ] [] @@ -516,18 +534,18 @@ renderFormState texts model = [ text (texts.httpError err) ] - FormStateMergeSuccessful -> + FormStateActionSuccessful -> div [ class S.successMessage , class "my-2" ] - [ text texts.mergeSuccessful + [ text cfg.actionSuccessful ] - FormStateMergeInProcess -> + FormStateActionInProcess -> Comp.Basic.loadingDimmer { active = True - , label = texts.mergeInProcess + , label = cfg.actionInProcess } diff --git a/modules/webapp/src/main/elm/Messages/Comp/ItemMerge.elm b/modules/webapp/src/main/elm/Messages/Comp/ItemMerge.elm index 54de08ee..20e725bc 100644 --- a/modules/webapp/src/main/elm/Messages/Comp/ItemMerge.elm +++ b/modules/webapp/src/main/elm/Messages/Comp/ItemMerge.elm @@ -24,16 +24,9 @@ type alias Texts = { basics : Messages.Basics.Texts , httpError : Http.Error -> String , title : String - , infoText : String - , deleteWarn : String , formatDateLong : Int -> String , formatDateShort : Int -> String - , submitMerge : String - , cancelMerge : String - , submitMergeTitle : String - , cancelMergeTitle : String - , mergeSuccessful : String - , mergeInProcess : String + , cancelView : String } @@ -42,16 +35,9 @@ gb tz = { basics = Messages.Basics.gb , httpError = Messages.Comp.HttpError.gb , title = "Merge Items" - , infoText = "When merging items the first item in the list acts as the target. Every other items metadata is copied into the target item. If the property is a single value (like correspondent), it is only set if not already present. Tags, custom fields and attachments are added. The items can be reordered using drag&drop." - , deleteWarn = "Note that all items but the first one is deleted after a successful merge!" , formatDateLong = Messages.DateFormat.formatDateLong Messages.UiLanguage.English tz , formatDateShort = Messages.DateFormat.formatDateShort Messages.UiLanguage.English tz - , submitMerge = "Merge" - , submitMergeTitle = "Merge the documents now" - , cancelMerge = "Cancel" - , cancelMergeTitle = "Back to select view" - , mergeSuccessful = "Items merged successfully" - , mergeInProcess = "Items are merged …" + , cancelView = "Cancel" } @@ -60,16 +46,9 @@ de tz = { basics = Messages.Basics.de , httpError = Messages.Comp.HttpError.de , title = "Dokumente zusammenführen" - , infoText = "Beim Zusammenführen der Dokumente, wird das erste in der Liste als Zieldokument verwendet. Die Metadaten der anderen Dokumente werden der Reihe nach auf des Zieldokument geschrieben. Metadaten die nur einen Wert haben, werden nur gesetzt falls noch kein Wert existiert. Tags, Benutzerfelder und Anhänge werden zu dem Zieldokument hinzugefügt. Die Einträge können mit Drag&Drop umgeordnet werden." - , deleteWarn = "Bitte beachte, dass nach erfolgreicher Zusammenführung alle anderen Dokumente gelöscht werden!" , formatDateLong = Messages.DateFormat.formatDateLong Messages.UiLanguage.German tz , formatDateShort = Messages.DateFormat.formatDateShort Messages.UiLanguage.German tz - , submitMerge = "Zusammenführen" - , submitMergeTitle = "Dokumente jetzt zusammenführen" - , cancelMerge = "Abbrechen" - , cancelMergeTitle = "Zurück zur Auswahl" - , mergeSuccessful = "Die Dokumente wurden erfolgreich zusammengeführt." - , mergeInProcess = "Dokumente werden zusammengeführt…" + , cancelView = "Abbrechen" } @@ -78,14 +57,7 @@ fr tz = { basics = Messages.Basics.fr , httpError = Messages.Comp.HttpError.fr , title = "Fusionner des documents" - , infoText = "Lors d'une fusion, le premier document sert de cible. Les métadonnées des autres documents sont ajoutées à la cible. Si la propriété est un valeur seule (comme correspondant), ceci est ajouté si pas déjà présent. Tags, champs personnalisés et pièces-jointes sont ajoutés. Les documents peuvent être réordonnés avec le glisser/déposer." - , deleteWarn = "Veuillez noter que tous les documents sont supprimés après une fusion réussie !" , formatDateLong = Messages.DateFormat.formatDateLong Messages.UiLanguage.French tz , formatDateShort = Messages.DateFormat.formatDateShort Messages.UiLanguage.French tz - , submitMerge = "Fusionner" - , submitMergeTitle = "Lancer la fusion" - , cancelMerge = "Annuler" - , cancelMergeTitle = "Annuler la fusion" - , mergeSuccessful = "Documents fusionnés avec succès" - , mergeInProcess = "Fusion en cours ..." + , cancelView = "Annuler" } diff --git a/modules/webapp/src/main/elm/Messages/Page/Search.elm b/modules/webapp/src/main/elm/Messages/Page/Search.elm index c2c70cda..c1504f03 100644 --- a/modules/webapp/src/main/elm/Messages/Page/Search.elm +++ b/modules/webapp/src/main/elm/Messages/Page/Search.elm @@ -60,6 +60,13 @@ type alias Texts = , expandCollapseRows : String , bookmarkQuery : String , nothingToBookmark : String + , submitMerge : String + , mergeInfoText : String + , mergeDeleteWarn : String + , submitMergeTitle : String + , cancelMergeTitle : String + , mergeSuccessful : String + , mergeInProcess : String } @@ -102,6 +109,13 @@ gb tz = , expandCollapseRows = "Expand/Collapse all" , bookmarkQuery = "Bookmark query" , nothingToBookmark = "Nothing selected to bookmark" + , submitMerge = "Merge" + , mergeInfoText = "When merging items the first item in the list acts as the target. Every other items metadata is copied into the target item. If the property is a single value (like correspondent), it is only set if not already present. Tags, custom fields and attachments are added. The items can be reordered using drag&drop." + , mergeDeleteWarn = "Note that all items but the first one is deleted after a successful merge!" + , submitMergeTitle = "Merge the documents now" + , cancelMergeTitle = "Back to select view" + , mergeSuccessful = "Items merged successfully" + , mergeInProcess = "Items are merged …" } @@ -144,6 +158,13 @@ de tz = , expandCollapseRows = "Alle ein-/ausklappen" , bookmarkQuery = "Abfrage merken" , nothingToBookmark = "Keine Abfrage vorhanden" + , submitMerge = "Zusammenführen" + , mergeInfoText = "Beim Zusammenführen der Dokumente, wird das erste in der Liste als Zieldokument verwendet. Die Metadaten der anderen Dokumente werden der Reihe nach auf des Zieldokument geschrieben. Metadaten die nur einen Wert haben, werden nur gesetzt falls noch kein Wert existiert. Tags, Benutzerfelder und Anhänge werden zu dem Zieldokument hinzugefügt. Die Einträge können mit Drag&Drop umgeordnet werden." + , mergeDeleteWarn = "Bitte beachte, dass nach erfolgreicher Zusammenführung alle anderen Dokumente gelöscht werden!" + , submitMergeTitle = "Dokumente jetzt zusammenführen" + , cancelMergeTitle = "Zurück zur Auswahl" + , mergeSuccessful = "Die Dokumente wurden erfolgreich zusammengeführt." + , mergeInProcess = "Dokumente werden zusammengeführt…" } @@ -186,4 +207,11 @@ fr tz = , expandCollapseRows = "Étendre/Réduire tout" , bookmarkQuery = "Requête de favoris" , nothingToBookmark = "Rien n'est sélectionné en favori" + , submitMerge = "Fusionner" + , mergeInfoText = "Lors d'une fusion, le premier document sert de cible. Les métadonnées des autres documents sont ajoutées à la cible. Si la propriété est un valeur seule (comme correspondant), ceci est ajouté si pas déjà présent. Tags, champs personnalisés et pièces-jointes sont ajoutés. Les documents peuvent être réordonnés avec le glisser/déposer." + , mergeDeleteWarn = "Veuillez noter que tous les documents sont supprimés après une fusion réussie !" + , submitMergeTitle = "Lancer la fusion" + , cancelMergeTitle = "Annuler la fusion" + , mergeSuccessful = "Documents fusionnés avec succès" + , mergeInProcess = "Fusion en cours ..." } diff --git a/modules/webapp/src/main/elm/Page/Search/Update.elm b/modules/webapp/src/main/elm/Page/Search/Update.elm index 3b1b5771..3895d359 100644 --- a/modules/webapp/src/main/elm/Page/Search/Update.elm +++ b/modules/webapp/src/main/elm/Page/Search/Update.elm @@ -600,8 +600,11 @@ update texts bookmarkId lastViewedItemId env msg model = case model.viewMode of SelectView svm -> let + action = + Api.mergeItemsTask env.flags + result = - Comp.ItemMerge.update env.flags lmsg svm.mergeModel + Comp.ItemMerge.update env.flags action lmsg svm.mergeModel nextView = case result.outcome of @@ -611,13 +614,13 @@ update texts bookmarkId lastViewedItemId env msg model = Comp.ItemMerge.OutcomeNotYet -> SelectView { svm | mergeModel = result.model } - Comp.ItemMerge.OutcomeMerged -> + Comp.ItemMerge.OutcomeActionDone -> SearchView model_ = { model | viewMode = nextView } in - if result.outcome == Comp.ItemMerge.OutcomeMerged then + if result.outcome == Comp.ItemMerge.OutcomeActionDone then update texts bookmarkId lastViewedItemId diff --git a/modules/webapp/src/main/elm/Page/Search/View2.elm b/modules/webapp/src/main/elm/Page/Search/View2.elm index 30461f18..aa5d6ee9 100644 --- a/modules/webapp/src/main/elm/Page/Search/View2.elm +++ b/modules/webapp/src/main/elm/Page/Search/View2.elm @@ -129,8 +129,19 @@ itemPublishView texts settings flags svm = itemMergeView : Texts -> UiSettings -> SelectViewModel -> List (Html Msg) itemMergeView texts settings svm = + let + cfg = + { infoMessage = texts.mergeInfoText + , warnMessage = texts.mergeDeleteWarn + , actionButton = texts.submitMerge + , actionTitle = texts.submitMergeTitle + , cancelTitle = texts.cancelMergeTitle + , actionSuccessful = texts.mergeSuccessful + , actionInProcess = texts.mergeInProcess + } + in [ Html.map MergeItemsMsg - (Comp.ItemMerge.view texts.itemMerge settings svm.mergeModel) + (Comp.ItemMerge.view texts.itemMerge cfg settings svm.mergeModel) ]