Drag-drop items into folders in list view

This commit is contained in:
Eike Kettner 2020-08-08 14:03:36 +02:00
parent 9c50a85363
commit d6d16e39bd
7 changed files with 189 additions and 106 deletions

View File

@ -12,8 +12,8 @@ import Api.Model.FolderItem exposing (FolderItem)
import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (onClick)
import Html5.DragDrop as DD
import Util.ExpandCollapse
import Util.ItemDragDrop as DD
import Util.List
@ -39,7 +39,7 @@ init all =
type Msg
= Toggle FolderItem
| ToggleExpand
| FolderDDMsg (DD.Msg String String)
| FolderDDMsg DD.Msg
update : Msg -> Model -> ( Model, Maybe FolderItem )
@ -52,10 +52,10 @@ update msg model =
updateDrop :
DD.Model String String
DD.Model
-> Msg
-> Model
-> ( Model, Maybe FolderItem, DD.Model String String )
-> ( Model, Maybe FolderItem, DD.DragDropData )
updateDrop dropModel msg model =
case msg of
Toggle item ->
@ -70,35 +70,20 @@ updateDrop dropModel msg model =
model_ =
{ model | selected = selection }
in
( model_, selectedFolder model_, dropModel )
( model_, selectedFolder model_, DD.DragDropData dropModel Nothing )
ToggleExpand ->
( { model | expanded = not model.expanded }
, selectedFolder model
, dropModel
, DD.DragDropData dropModel Nothing
)
FolderDDMsg lm ->
let
( dm_, result ) =
ddd =
DD.update lm dropModel
_ =
case result of
Just ( item, folder, _ ) ->
let
_ =
Debug.log "item menu" item
_ =
Debug.log "folder menu" folder
in
Cmd.none
Nothing ->
Cmd.none
in
( model, selectedFolder model, dm_ )
( model, selectedFolder model, ddd )
selectedFolder : Model -> Maybe FolderItem
@ -119,13 +104,23 @@ view =
viewDrop DD.init
viewDrop : DD.Model String String -> Int -> Model -> Html Msg
viewDrop : DD.Model -> Int -> Model -> Html Msg
viewDrop dropModel constr model =
let
highlightDrop =
DD.getDropId dropModel == Just DD.FolderRemove
in
div [ class "ui list" ]
[ div [ class "item" ]
[ i [ class "folder open icon" ] []
, div [ class "content" ]
[ div [ class "header" ]
[ div
(classList
[ ( "header", True )
, ( "current-drop-target", highlightDrop )
]
:: DD.droppable FolderDDMsg DD.FolderRemove
)
[ text "Folders"
]
, div [ class "ui relaxed list" ]
@ -135,7 +130,7 @@ viewDrop dropModel constr model =
]
renderItems : DD.Model String String -> Int -> Model -> List (Html Msg)
renderItems : DD.Model -> Int -> Model -> List (Html Msg)
renderItems dropModel constr model =
if constr <= 0 then
List.map (viewItem dropModel model) model.all
@ -163,7 +158,7 @@ collapseToggle max model =
ToggleExpand
viewItem : DD.Model String String -> Model -> FolderItem -> Html Msg
viewItem : DD.Model -> Model -> FolderItem -> Html Msg
viewItem dropModel model item =
let
selected =
@ -177,7 +172,7 @@ viewItem dropModel model item =
"folder outline icon"
highlightDrop =
DD.getDropId dropModel == Just item.id
DD.getDropId dropModel == Just (DD.Folder item.id)
in
a
([ classList
@ -188,7 +183,7 @@ viewItem dropModel model item =
, href "#"
, onClick (Toggle item)
]
++ DD.droppable FolderDDMsg item.id
++ DD.droppable FolderDDMsg (DD.Folder item.id)
)
[ i [ class icon ] []
, div [ class "content" ]

View File

@ -21,8 +21,8 @@ import Data.UiSettings exposing (UiSettings)
import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (onClick)
import Html5.DragDrop as DD
import Markdown
import Util.ItemDragDrop as DD
import Util.List
import Util.String
import Util.Time
@ -37,7 +37,7 @@ type Msg
= SetResults ItemLightList
| AddResults ItemLightList
| SelectItem ItemLight
| ItemDDMsg (DD.Msg String String)
| ItemDDMsg DD.Msg
init : Model
@ -75,12 +75,12 @@ type alias UpdateResult =
{ model : Model
, cmd : Cmd Msg
, selected : Maybe ItemLight
, dragModel : DD.Model String String
, dragModel : DD.Model
}
updateDrag :
DD.Model String String
DD.Model
-> Flags
-> Msg
-> Model
@ -110,25 +110,10 @@ updateDrag dm _ msg model =
ItemDDMsg lm ->
let
( dm_, result ) =
ddd =
DD.update lm dm
_ =
case result of
Just ( item, folder, _ ) ->
let
_ =
Debug.log "item card" item
_ =
Debug.log "folder card" folder
in
Cmd.none
Nothing ->
Cmd.none
in
UpdateResult model Cmd.none Nothing dm_
UpdateResult model Cmd.none Nothing ddd.model

View File

@ -1,6 +1,5 @@
module Comp.SearchMenu exposing
( DragDropData
, Model
( Model
, Msg(..)
, NextState
, getItemSearch
@ -32,11 +31,10 @@ import DatePicker exposing (DatePicker)
import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (onCheck, onClick, onInput)
import Html5.DragDrop as DD
import Http
import Util.Html exposing (KeyCode(..))
import Util.ItemDragDrop as DD
import Util.Maybe
import Util.Update
@ -222,26 +220,21 @@ type Msg
| GetFolderResp (Result Http.Error FolderList)
type alias DragDropData =
{ folderDrop : DD.Model String String
}
type alias NextState =
{ model : Model
, cmd : Cmd Msg
, stateChange : Bool
, dragDrop : DragDropData
, dragDrop : DD.DragDropData
}
update : Flags -> UiSettings -> Msg -> Model -> NextState
update =
updateDrop (DragDropData DD.init)
updateDrop DD.init
updateDrop : DragDropData -> Flags -> UiSettings -> Msg -> Model -> NextState
updateDrop dd flags settings msg model =
updateDrop : DD.Model -> Flags -> UiSettings -> Msg -> Model -> NextState
updateDrop ddm flags settings msg model =
case msg of
Init ->
let
@ -279,7 +272,7 @@ updateDrop dd flags settings msg model =
, cdp
]
, stateChange = False
, dragDrop = dd
, dragDrop = DD.DragDropData ddm Nothing
}
ResetForm ->
@ -302,14 +295,14 @@ updateDrop dd flags settings msg model =
{ model = model_
, cmd = Cmd.none
, stateChange = False
, dragDrop = dd
, dragDrop = DD.DragDropData ddm Nothing
}
GetTagsResp (Err _) ->
{ model = model
, cmd = Cmd.none
, stateChange = False
, dragDrop = dd
, dragDrop = DD.DragDropData ddm Nothing
}
GetEquipResp (Ok equips) ->
@ -323,7 +316,7 @@ updateDrop dd flags settings msg model =
{ model = model
, cmd = Cmd.none
, stateChange = False
, dragDrop = dd
, dragDrop = DD.DragDropData ddm Nothing
}
GetOrgResp (Ok orgs) ->
@ -337,7 +330,7 @@ updateDrop dd flags settings msg model =
{ model = model
, cmd = Cmd.none
, stateChange = False
, dragDrop = dd
, dragDrop = DD.DragDropData ddm Nothing
}
GetPersonResp (Ok ps) ->
@ -346,10 +339,10 @@ updateDrop dd flags settings msg model =
Comp.Dropdown.SetOptions ps.items
next1 =
updateDrop dd flags settings (CorrPersonMsg opts) model
updateDrop ddm flags settings (CorrPersonMsg opts) model
next2 =
updateDrop next1.dragDrop flags settings (ConcPersonMsg opts) next1.model
updateDrop next1.dragDrop.model flags settings (ConcPersonMsg opts) next1.model
in
next2
@ -357,7 +350,7 @@ updateDrop dd flags settings msg model =
{ model = model
, cmd = Cmd.none
, stateChange = False
, dragDrop = dd
, dragDrop = DD.DragDropData ddm Nothing
}
TagSelectMsg m ->
@ -372,7 +365,7 @@ updateDrop dd flags settings msg model =
}
, cmd = Cmd.none
, stateChange = sel /= model.tagSelection
, dragDrop = dd
, dragDrop = DD.DragDropData ddm Nothing
}
DirectionMsg m ->
@ -383,7 +376,7 @@ updateDrop dd flags settings msg model =
{ model = { model | directionModel = m2 }
, cmd = Cmd.map DirectionMsg c2
, stateChange = isDropdownChangeMsg m
, dragDrop = dd
, dragDrop = DD.DragDropData ddm Nothing
}
OrgMsg m ->
@ -394,7 +387,7 @@ updateDrop dd flags settings msg model =
{ model = { model | orgModel = m2 }
, cmd = Cmd.map OrgMsg c2
, stateChange = isDropdownChangeMsg m
, dragDrop = dd
, dragDrop = DD.DragDropData ddm Nothing
}
CorrPersonMsg m ->
@ -405,7 +398,7 @@ updateDrop dd flags settings msg model =
{ model = { model | corrPersonModel = m2 }
, cmd = Cmd.map CorrPersonMsg c2
, stateChange = isDropdownChangeMsg m
, dragDrop = dd
, dragDrop = DD.DragDropData ddm Nothing
}
ConcPersonMsg m ->
@ -416,7 +409,7 @@ updateDrop dd flags settings msg model =
{ model = { model | concPersonModel = m2 }
, cmd = Cmd.map ConcPersonMsg c2
, stateChange = isDropdownChangeMsg m
, dragDrop = dd
, dragDrop = DD.DragDropData ddm Nothing
}
ConcEquipmentMsg m ->
@ -427,7 +420,7 @@ updateDrop dd flags settings msg model =
{ model = { model | concEquipmentModel = m2 }
, cmd = Cmd.map ConcEquipmentMsg c2
, stateChange = isDropdownChangeMsg m
, dragDrop = dd
, dragDrop = DD.DragDropData ddm Nothing
}
ToggleInbox ->
@ -438,7 +431,7 @@ updateDrop dd flags settings msg model =
{ model = { model | inboxCheckbox = not current }
, cmd = Cmd.none
, stateChange = True
, dragDrop = dd
, dragDrop = DD.DragDropData ddm Nothing
}
FromDateMsg m ->
@ -457,7 +450,7 @@ updateDrop dd flags settings msg model =
{ model = { model | fromDateModel = dp, fromDate = nextDate }
, cmd = Cmd.none
, stateChange = model.fromDate /= nextDate
, dragDrop = dd
, dragDrop = DD.DragDropData ddm Nothing
}
UntilDateMsg m ->
@ -476,7 +469,7 @@ updateDrop dd flags settings msg model =
{ model = { model | untilDateModel = dp, untilDate = nextDate }
, cmd = Cmd.none
, stateChange = model.untilDate /= nextDate
, dragDrop = dd
, dragDrop = DD.DragDropData ddm Nothing
}
FromDueDateMsg m ->
@ -495,7 +488,7 @@ updateDrop dd flags settings msg model =
{ model = { model | fromDueDateModel = dp, fromDueDate = nextDate }
, cmd = Cmd.none
, stateChange = model.fromDueDate /= nextDate
, dragDrop = dd
, dragDrop = DD.DragDropData ddm Nothing
}
UntilDueDateMsg m ->
@ -514,7 +507,7 @@ updateDrop dd flags settings msg model =
{ model = { model | untilDueDateModel = dp, untilDueDate = nextDate }
, cmd = Cmd.none
, stateChange = model.untilDueDate /= nextDate
, dragDrop = dd
, dragDrop = DD.DragDropData ddm Nothing
}
SetName str ->
@ -525,7 +518,7 @@ updateDrop dd flags settings msg model =
{ model = { model | nameModel = next }
, cmd = Cmd.none
, stateChange = False
, dragDrop = dd
, dragDrop = DD.DragDropData ddm Nothing
}
SetAllName str ->
@ -536,7 +529,7 @@ updateDrop dd flags settings msg model =
{ model = { model | allNameModel = next }
, cmd = Cmd.none
, stateChange = False
, dragDrop = dd
, dragDrop = DD.DragDropData ddm Nothing
}
SetFulltext str ->
@ -547,28 +540,28 @@ updateDrop dd flags settings msg model =
{ model = { model | fulltextModel = next }
, cmd = Cmd.none
, stateChange = False
, dragDrop = dd
, dragDrop = DD.DragDropData ddm Nothing
}
KeyUpMsg (Just Enter) ->
{ model = model
, cmd = Cmd.none
, stateChange = True
, dragDrop = dd
, dragDrop = DD.DragDropData ddm Nothing
}
KeyUpMsg _ ->
{ model = model
, cmd = Cmd.none
, stateChange = False
, dragDrop = dd
, dragDrop = DD.DragDropData ddm Nothing
}
ToggleNameHelp ->
{ model = { model | showNameHelp = not model.showNameHelp }
, cmd = Cmd.none
, stateChange = False
, dragDrop = dd
, dragDrop = DD.DragDropData ddm Nothing
}
GetFolderResp (Ok fs) ->
@ -579,20 +572,20 @@ updateDrop dd flags settings msg model =
{ model = model_
, cmd = Cmd.none
, stateChange = False
, dragDrop = dd
, dragDrop = DD.DragDropData ddm Nothing
}
GetFolderResp (Err _) ->
{ model = model
, cmd = Cmd.none
, stateChange = False
, dragDrop = dd
, dragDrop = DD.DragDropData ddm Nothing
}
FolderSelectMsg lm ->
let
( fsm, sel, dd_ ) =
Comp.FolderSelect.updateDrop dd.folderDrop lm model.folderList
( fsm, sel, ddd ) =
Comp.FolderSelect.updateDrop ddm lm model.folderList
in
{ model =
{ model
@ -601,7 +594,7 @@ updateDrop dd flags settings msg model =
}
, cmd = Cmd.none
, stateChange = model.selectedFolder /= sel
, dragDrop = { dd | folderDrop = dd_ }
, dragDrop = ddd
}
@ -611,10 +604,10 @@ updateDrop dd flags settings msg model =
view : Flags -> UiSettings -> Model -> Html Msg
view =
viewDrop (DragDropData DD.init)
viewDrop (DD.DragDropData DD.init Nothing)
viewDrop : DragDropData -> Flags -> UiSettings -> Model -> Html Msg
viewDrop : DD.DragDropData -> Flags -> UiSettings -> Model -> Html Msg
viewDrop ddd flags settings model =
let
formHeader icon headline =
@ -648,7 +641,7 @@ viewDrop ddd flags settings model =
[ Html.map TagSelectMsg (Comp.TagSelect.viewTags settings model.tagSelectModel)
, Html.map TagSelectMsg (Comp.TagSelect.viewCats settings model.tagSelectModel)
, Html.map FolderSelectMsg
(Comp.FolderSelect.viewDrop ddd.folderDrop settings.searchMenuFolderCount model.folderList)
(Comp.FolderSelect.viewDrop ddd.model settings.searchMenuFolderCount model.folderList)
]
, div [ class segmentClass ]
[ formHeader (Icons.correspondentIcon "")

View File

@ -16,14 +16,14 @@ import Api.Model.ItemLightList exposing (ItemLightList)
import Api.Model.ItemSearch
import Comp.FixedDropdown
import Comp.ItemCardList
import Comp.SearchMenu exposing (DragDropData)
import Comp.SearchMenu
import Data.Flags exposing (Flags)
import Data.Items
import Data.UiSettings exposing (UiSettings)
import Html5.DragDrop as DD
import Http
import Throttle exposing (Throttle)
import Util.Html exposing (KeyCode(..))
import Util.ItemDragDrop as DD
type alias Model =
@ -40,7 +40,7 @@ type alias Model =
, searchType : SearchType
, searchTypeForm : SearchType
, contentOnlySearch : Maybe String
, dragDropData : DragDropData
, dragDropData : DD.DragDropData
}
@ -70,8 +70,7 @@ init flags =
, searchTypeForm = defaultSearchType flags
, contentOnlySearch = Nothing
, dragDropData =
{ folderDrop = DD.init
}
DD.DragDropData DD.init Nothing
}

View File

@ -6,12 +6,12 @@ import Comp.ItemCardList
import Comp.SearchMenu
import Data.Flags exposing (Flags)
import Data.UiSettings exposing (UiSettings)
import Html5.DragDrop as DD
import Page exposing (Page(..))
import Page.Home.Data exposing (..)
import Throttle
import Time
import Util.Html exposing (KeyCode(..))
import Util.ItemDragDrop as DD
import Util.Maybe
import Util.String
import Util.Update
@ -41,12 +41,24 @@ update key flags settings msg model =
let
nextState =
Comp.SearchMenu.updateDrop
model.dragDropData
model.dragDropData.model
flags
settings
m
model.searchMenuModel
dropCmd =
case nextState.dragDrop.dropped of
Just dropped ->
let
_ =
Debug.log "item/folder" dropped
in
DD.makeUpdateCmd flags (\_ -> DoSearch) nextState.dragDrop.dropped
Nothing ->
Cmd.none
newModel =
{ model
| searchMenuModel = nextState.model
@ -64,6 +76,7 @@ update key flags settings msg model =
, Cmd.batch
[ c2
, Cmd.map SearchMenuMsg nextState.cmd
, dropCmd
]
, s2
)
@ -71,7 +84,7 @@ update key flags settings msg model =
ItemCardListMsg m ->
let
result =
Comp.ItemCardList.updateDrag model.dragDropData.folderDrop
Comp.ItemCardList.updateDrag model.dragDropData.model
flags
m
model.itemListModel
@ -87,7 +100,7 @@ update key flags settings msg model =
withSub
( { model
| itemListModel = result.model
, dragDropData = { folderDrop = result.dragModel }
, dragDropData = DD.DragDropData result.dragModel Nothing
}
, Cmd.batch [ Cmd.map ItemCardListMsg result.cmd, cmd ]
)

View File

@ -0,0 +1,98 @@
module Util.ItemDragDrop exposing
( DragDropData
, Dropped
, ItemDrop(..)
, Model
, Msg
, draggable
, droppable
, getDropId
, init
, makeUpdateCmd
, update
)
import Api
import Api.Model.BasicResult exposing (BasicResult)
import Api.Model.OptionalId exposing (OptionalId)
import Data.Flags exposing (Flags)
import Html exposing (Attribute)
import Html5.DragDrop as DD
import Http
type ItemDrop
= Tag String
| Folder String
| FolderRemove
type alias Model =
DD.Model String ItemDrop
type alias Msg =
DD.Msg String ItemDrop
type alias Dropped =
{ itemId : String
, target : ItemDrop
}
type alias DragDropData =
{ model : Model
, dropped : Maybe Dropped
}
init : Model
init =
DD.init
update : Msg -> Model -> DragDropData
update msg model =
let
( m, res ) =
DD.update msg model
in
DragDropData m (Maybe.map (\( id, t, _ ) -> Dropped id t) res)
makeUpdateCmd :
Flags
-> (Result Http.Error BasicResult -> msg)
-> Maybe Dropped
-> Cmd msg
makeUpdateCmd flags receive droppedMaybe =
case droppedMaybe of
Just dropped ->
case dropped.target of
Folder fid ->
Api.setFolder flags dropped.itemId (OptionalId (Just fid)) receive
FolderRemove ->
Api.setFolder flags dropped.itemId (OptionalId Nothing) receive
Tag _ ->
Cmd.none
Nothing ->
Cmd.none
droppable : (Msg -> msg) -> ItemDrop -> List (Attribute msg)
droppable tagger dropId =
DD.droppable tagger dropId
draggable : (Msg -> msg) -> String -> List (Attribute msg)
draggable tagger itemId =
DD.draggable tagger itemId
getDropId : Model -> Maybe ItemDrop
getDropId model =
DD.getDropId model

View File

@ -166,7 +166,7 @@ textarea.markdown-editor {
background: rgba(240,248,255,0.4);
}
.default-layout .ui.menu .item.current-drop-target, a.item.current-drop-target {
.default-layout .ui.menu .item.current-drop-target, .header.current-drop-target, .item.current-drop-target {
background: rgba(0,0,0,0.2);
}