diff --git a/modules/webapp/src/main/elm/Api.elm b/modules/webapp/src/main/elm/Api.elm index 2ef008d5..c36c709f 100644 --- a/modules/webapp/src/main/elm/Api.elm +++ b/modules/webapp/src/main/elm/Api.elm @@ -21,6 +21,7 @@ module Api exposing , deleteAttachment , deleteCustomField , deleteCustomValue + , deleteCustomValueMultiple , deleteEquip , deleteFolder , deleteImapSettings @@ -80,6 +81,7 @@ module Api exposing , postTag , putCustomField , putCustomValue + , putCustomValueMultiple , putUser , refreshSession , register @@ -159,6 +161,7 @@ import Api.Model.ItemSearch exposing (ItemSearch) import Api.Model.ItemUploadMeta exposing (ItemUploadMeta) import Api.Model.ItemsAndDate exposing (ItemsAndDate) import Api.Model.ItemsAndDirection exposing (ItemsAndDirection) +import Api.Model.ItemsAndFieldValue exposing (ItemsAndFieldValue) import Api.Model.ItemsAndName exposing (ItemsAndName) import Api.Model.ItemsAndRef exposing (ItemsAndRef) import Api.Model.ItemsAndRefs exposing (ItemsAndRefs) @@ -211,6 +214,34 @@ import Util.Http as Http2 --- Custom Fields +putCustomValueMultiple : + Flags + -> ItemsAndFieldValue + -> (Result Http.Error BasicResult -> msg) + -> Cmd msg +putCustomValueMultiple flags data receive = + Http2.authPut + { url = flags.config.baseUrl ++ "/api/v1/sec/items/customfield" + , account = getAccount flags + , body = Http.jsonBody (Api.Model.ItemsAndFieldValue.encode data) + , expect = Http.expectJson receive Api.Model.BasicResult.decoder + } + + +deleteCustomValueMultiple : + Flags + -> ItemsAndName + -> (Result Http.Error BasicResult -> msg) + -> Cmd msg +deleteCustomValueMultiple flags data receive = + Http2.authPost + { url = flags.config.baseUrl ++ "/api/v1/sec/items/customfieldremove" + , account = getAccount flags + , body = Http.jsonBody (Api.Model.ItemsAndName.encode data) + , expect = Http.expectJson receive Api.Model.BasicResult.decoder + } + + deleteCustomValue : Flags -> String diff --git a/modules/webapp/src/main/elm/Comp/CustomFieldMultiInput.elm b/modules/webapp/src/main/elm/Comp/CustomFieldMultiInput.elm index 4eb85ced..a64413d8 100644 --- a/modules/webapp/src/main/elm/Comp/CustomFieldMultiInput.elm +++ b/modules/webapp/src/main/elm/Comp/CustomFieldMultiInput.elm @@ -3,6 +3,7 @@ module Comp.CustomFieldMultiInput exposing , Model , Msg , UpdateResult + , ViewSettings , init , initCmd , initWith @@ -287,25 +288,46 @@ update msg model = UpdateResult model_ (Cmd.batch cmdList) Sub.none NoResult -view : String -> Model -> Html Msg -view classes model = - div [ class classes ] - (viewMenuBar model + +--- View + + +type alias ViewSettings = + { showAddButton : Bool + , classes : String + } + + +view : ViewSettings -> Model -> Html Msg +view viewSettings model = + div [ class viewSettings.classes ] + (viewMenuBar viewSettings model :: List.map (viewCustomField model) model.visibleFields ) -viewMenuBar : Model -> Html Msg -viewMenuBar model = +viewMenuBar : ViewSettings -> Model -> Html Msg +viewMenuBar viewSettings model = let { dropdown, selected } = model.fieldSelect in - div [ class "ui action input field" ] - [ Html.map FieldSelectMsg - (Comp.FixedDropdown.viewStyled "fluid" (Maybe.map mkItem selected) dropdown) - , addFieldLink "" model + div + [ classList + [ ( "field", True ) + , ( "ui action input", viewSettings.showAddButton ) + ] ] + (Html.map FieldSelectMsg + (Comp.FixedDropdown.viewStyled "fluid" (Maybe.map mkItem selected) dropdown) + :: (if viewSettings.showAddButton then + [ addFieldLink "" model + ] + + else + [] + ) + ) viewCustomField : Model -> CustomField -> Html Msg diff --git a/modules/webapp/src/main/elm/Comp/ItemDetail/EditMenu.elm b/modules/webapp/src/main/elm/Comp/ItemDetail/EditMenu.elm index 161b5871..c919fe92 100644 --- a/modules/webapp/src/main/elm/Comp/ItemDetail/EditMenu.elm +++ b/modules/webapp/src/main/elm/Comp/ItemDetail/EditMenu.elm @@ -18,6 +18,7 @@ import Api.Model.ItemProposals exposing (ItemProposals) import Api.Model.ReferenceList exposing (ReferenceList) import Api.Model.Tag exposing (Tag) import Api.Model.TagList exposing (TagList) +import Comp.CustomFieldMultiInput exposing (FieldResult(..)) import Comp.DatePicker import Comp.DetailEdit import Comp.Dropdown exposing (isDropdownChangeMsg) @@ -77,6 +78,7 @@ type alias Model = , concEquipModel : Comp.Dropdown.Model IdName , modalEdit : Maybe Comp.DetailEdit.Model , tagEditMode : TagEditMode + , customFieldModel : Comp.CustomFieldMultiInput.Model } @@ -102,6 +104,7 @@ type Msg | GetPersonResp (Result Http.Error ReferenceList) | GetEquipResp (Result Http.Error EquipmentList) | GetFolderResp (Result Http.Error FolderList) + | CustomFieldMsg Comp.CustomFieldMultiInput.Msg init : Model @@ -155,6 +158,7 @@ init = , dueDatePicker = Comp.DatePicker.emptyModel , modalEdit = Nothing , tagEditMode = AddTags + , customFieldModel = Comp.CustomFieldMultiInput.initWith [] } @@ -170,6 +174,7 @@ loadModel flags = , Api.getPersonsLight flags GetPersonResp , Api.getEquipments flags "" GetEquipResp , Api.getFolders flags "" False GetFolderResp + , Cmd.map CustomFieldMsg (Comp.CustomFieldMultiInput.initCmd flags) , Cmd.map ItemDatePickerMsg dpc , Cmd.map DueDatePickerMsg dpc ] @@ -547,6 +552,36 @@ update flags msg model = in UpdateResult newModel cmd sub NoFormChange + CustomFieldMsg lm -> + let + res = + Comp.CustomFieldMultiInput.update lm model.customFieldModel + + model_ = + { model | customFieldModel = res.model } + + cmd_ = + Cmd.map CustomFieldMsg res.cmd + + sub_ = + Sub.map CustomFieldMsg res.subs + + change = + case res.result of + NoResult -> + NoFormChange + + FieldValueRemove cf -> + RemoveCustomValue cf + + FieldValueChange cf value -> + CustomValueChange cf value + + FieldCreateNew -> + NoFormChange + in + UpdateResult model_ cmd_ sub_ change + nameThrottleSub : Model -> Sub Msg nameThrottleSub model = @@ -614,6 +649,9 @@ renderEditForm cfg settings model = ReplaceTags -> "Tags chosen here *replace* those on selected items." + + customFieldSettings = + Comp.CustomFieldMultiInput.ViewSettings False "field" in div [ class cfg.menuClass ] [ div [ class "ui form warning" ] @@ -687,13 +725,18 @@ item visible. This message will disappear then. """ ] ] - , optional [ Data.Fields.Direction ] <| - div [ class "field" ] - [ label [] - [ Icons.directionIcon "grey" - , text "Direction" - ] - , Html.map DirDropdownMsg (Comp.Dropdown.view settings model.directionModel) + , optional [ Data.Fields.CustomFields ] <| + h4 [ class "ui dividing header" ] + [ Icons.customFieldIcon "" + , text "Custom Fields" + ] + , optional [ Data.Fields.CustomFields ] <| + Html.map CustomFieldMsg + (Comp.CustomFieldMultiInput.view customFieldSettings model.customFieldModel) + , optional [ Data.Fields.Date, Data.Fields.DueDate ] <| + h4 [ class "ui dividing header" ] + [ Icons.itemDatesIcon "" + , text "Item Dates" ] , optional [ Data.Fields.Date ] <| div [ class "field" ] @@ -701,7 +744,7 @@ item visible. This message will disappear then. [ Icons.dateIcon "grey" , text "Date" ] - , div [ class "ui action input" ] + , div [ class "ui left icon action input" ] [ Html.map ItemDatePickerMsg (Comp.DatePicker.viewTime model.itemDate @@ -711,6 +754,7 @@ item visible. This message will disappear then. , a [ class "ui icon button", href "", onClick RemoveDate ] [ i [ class "trash alternate outline icon" ] [] ] + , Icons.dateIcon "" ] ] , optional [ Data.Fields.DueDate ] <| @@ -719,7 +763,7 @@ item visible. This message will disappear then. [ Icons.dueDateIcon "grey" , text "Due Date" ] - , div [ class "ui action input" ] + , div [ class "ui left icon action input" ] [ Html.map DueDatePickerMsg (Comp.DatePicker.viewTime model.dueDate @@ -728,6 +772,7 @@ item visible. This message will disappear then. ) , a [ class "ui icon button", href "", onClick RemoveDueDate ] [ i [ class "trash alternate outline icon" ] [] ] + , Icons.dueDateIcon "" ] ] , optional [ Data.Fields.CorrOrg, Data.Fields.CorrPerson ] <| @@ -772,6 +817,14 @@ item visible. This message will disappear then. ] , Html.map ConcEquipMsg (Comp.Dropdown.view settings model.concEquipModel) ] + , optional [ Data.Fields.Direction ] <| + div [ class "field" ] + [ label [] + [ Icons.directionIcon "grey" + , text "Direction" + ] + , Html.map DirDropdownMsg (Comp.Dropdown.view settings model.directionModel) + ] ] ] diff --git a/modules/webapp/src/main/elm/Comp/ItemDetail/FormChange.elm b/modules/webapp/src/main/elm/Comp/ItemDetail/FormChange.elm index b7521ba4..2bb39e91 100644 --- a/modules/webapp/src/main/elm/Comp/ItemDetail/FormChange.elm +++ b/modules/webapp/src/main/elm/Comp/ItemDetail/FormChange.elm @@ -5,9 +5,12 @@ module Comp.ItemDetail.FormChange exposing import Api import Api.Model.BasicResult exposing (BasicResult) +import Api.Model.CustomField exposing (CustomField) +import Api.Model.CustomFieldValue exposing (CustomFieldValue) import Api.Model.IdName exposing (IdName) import Api.Model.ItemsAndDate exposing (ItemsAndDate) import Api.Model.ItemsAndDirection exposing (ItemsAndDirection) +import Api.Model.ItemsAndFieldValue exposing (ItemsAndFieldValue) import Api.Model.ItemsAndName exposing (ItemsAndName) import Api.Model.ItemsAndRef exposing (ItemsAndRef) import Api.Model.ItemsAndRefs exposing (ItemsAndRefs) @@ -33,6 +36,8 @@ type FormChange | DueDateChange (Maybe Int) | NameChange String | ConfirmChange Bool + | CustomValueChange CustomField String + | RemoveCustomValue CustomField multiUpdate : @@ -47,6 +52,20 @@ multiUpdate flags ids change receive = Set.toList ids in case change of + CustomValueChange field value -> + let + data = + ItemsAndFieldValue items (CustomFieldValue field.id value) + in + Api.putCustomValueMultiple flags data receive + + RemoveCustomValue field -> + let + data = + ItemsAndName items field.id + in + Api.deleteCustomValueMultiple flags data receive + ReplaceTagChange tags -> let data = diff --git a/modules/webapp/src/main/elm/Comp/ItemDetail/View.elm b/modules/webapp/src/main/elm/Comp/ItemDetail/View.elm index 7b4e43ec..ddff5af6 100644 --- a/modules/webapp/src/main/elm/Comp/ItemDetail/View.elm +++ b/modules/webapp/src/main/elm/Comp/ItemDetail/View.elm @@ -728,6 +728,9 @@ renderEditForm settings model = else span [ class "invisible hidden" ] [] + + customFieldSettings = + Comp.CustomFieldMultiInput.ViewSettings True "field" in div [ class "ui attached segment" ] [ div [ class "ui form warning" ] @@ -781,11 +784,11 @@ item visible. This message will disappear then. ] , optional [ Data.Fields.CustomFields ] <| Html.map CustomFieldMsg - (Comp.CustomFieldMultiInput.view "field" model.customFieldsModel) + (Comp.CustomFieldMultiInput.view customFieldSettings model.customFieldsModel) , optional [ Data.Fields.DueDate, Data.Fields.Date ] <| h4 [ class "ui dividing header" ] - [ Icons.dateIcon "" - , text "Dates" + [ Icons.itemDatesIcon "" + , text "Item Dates" ] , optional [ Data.Fields.Date ] <| div [ class "field" ] diff --git a/modules/webapp/src/main/elm/Data/Icons.elm b/modules/webapp/src/main/elm/Data/Icons.elm index f970ae2f..375f11ef 100644 --- a/modules/webapp/src/main/elm/Data/Icons.elm +++ b/modules/webapp/src/main/elm/Data/Icons.elm @@ -19,6 +19,7 @@ module Data.Icons exposing , equipmentIcon , folder , folderIcon + , itemDatesIcon , organization , organizationIcon , person @@ -85,6 +86,20 @@ correspondentIcon classes = i [ class (correspondent ++ " " ++ classes) ] [] +itemDates : String +itemDates = + "calendar alternate outline icon" + + +itemDatesIcon : String -> Html msg +itemDatesIcon classes = + i + [ class classes + , class itemDates + ] + [] + + date : String date = "calendar outline icon"