Skip to content

Commit 99b5d7e

Browse files
committed
feat: assignee board view ok + view function modularized.
1 parent 6be0c8c commit 99b5d7e

File tree

3 files changed

+327
-319
lines changed

3 files changed

+327
-319
lines changed

Diff for: assets/sass/fractal6.scss

+2-5
Original file line numberDiff line numberDiff line change
@@ -2610,14 +2610,11 @@ i.is-liked {
26102610

26112611
#searchBarTensions {
26122612
& > .field {
2613-
margin-bottom: 0.25rem !important;
2613+
margin-bottom: 0.25rem;
26142614
}
26152615

26162616
.tabs {
2617-
margin-bottom: 0.75rem !important;
2618-
li.is-active a {
2619-
font-weight: 600 !important;
2620-
}
2617+
margin-bottom: 0;
26212618
}
26222619
}
26232620

Diff for: src/Bulk/Board.elm

+211
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,211 @@
1+
{-
2+
Fractale - Self-organisation for humans.
3+
Copyright (C) 2023 Fractale Co
4+
5+
This file is part of Fractale.
6+
7+
This program is free software: you can redistribute it and/or modify
8+
it under the terms of the GNU Affero General Public License as
9+
published by the Free Software Foundation, either version 3 of the
10+
License, or (at your option) any later version.
11+
12+
This program is distributed in the hope that it will be useful,
13+
but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
GNU Affero General Public License for more details.
16+
17+
You should have received a copy of the GNU Affero General Public License
18+
along with Fractale. If not, see <http://www.gnu.org/licenses/>.
19+
-}
20+
21+
22+
module Bulk.Board exposing (..)
23+
24+
import Assets as A
25+
import Bulk exposing (UserState(..), getParentFragmentFromRole)
26+
import Bulk.Codecs exposing (NodeFocus, uriFromNameid, uriFromUsername)
27+
import Bulk.View exposing (mediaTension)
28+
import Dict exposing (Dict)
29+
import Extra exposing (colorAttr, ternary, upH)
30+
import Extra.Date exposing (formatDate)
31+
import Extra.Events exposing (onClickPD, onDragEnd, onDragEnter, onDragLeave, onDragStart, onDrop, onEnter, onKeydown, onTab)
32+
import Fractal.Enum.BlobType as BlobType
33+
import Fractal.Enum.Lang as Lang
34+
import Fractal.Enum.NodeMode as NodeMode
35+
import Fractal.Enum.NodeType as NodeType
36+
import Fractal.Enum.NodeVisibility as NodeVisibility
37+
import Fractal.Enum.RoleType as RoleType
38+
import Fractal.Enum.TensionAction as TensionAction
39+
import Fractal.Enum.TensionStatus as TensionStatus
40+
import Fractal.Enum.TensionType as TensionType
41+
import Generated.Route as Route exposing (toHref)
42+
import Html exposing (Html, a, br, button, div, hr, i, p, span, sub, text)
43+
import Html.Attributes exposing (attribute, class, classList, disabled, href, id, style, title)
44+
import Html.Events exposing (onClick)
45+
import Html.Lazy as Lazy
46+
import Identicon
47+
import List.Extra as LE
48+
import Markdown exposing (renderMarkdown)
49+
import Maybe exposing (withDefault)
50+
import ModelSchema exposing (Tension)
51+
import Session exposing (Conf)
52+
import String.Extra as SE
53+
import Text as T
54+
import Time
55+
56+
57+
type alias Op msg =
58+
{ hasTaskMove : Bool
59+
, conf : Conf
60+
, node_focus : NodeFocus
61+
, boardId : String
62+
, boardHeight : Maybe Float
63+
, movingTension : Maybe Tension
64+
, movingHoverC : Maybe { pos : Int, to_receiverid : String }
65+
, movingHoverT : Maybe { pos : Int, tid : String, to_receiverid : String }
66+
67+
-- Board Msg
68+
, onColumnHover : Maybe String -> msg
69+
, onMove : { pos : Int, to_receiverid : String } -> Tension -> msg
70+
, onCancelHov : msg
71+
, onEndMove : msg
72+
, onMoveEnterC : { pos : Int, to_receiverid : String } -> Bool -> msg
73+
, onMoveLeaveC : msg
74+
, onMoveEnterT : { pos : Int, tid : String, to_receiverid : String } -> msg
75+
, onMoveDrop : String -> msg
76+
, onNoTask : msg
77+
}
78+
79+
80+
viewBoard : Op msg -> (String -> Maybe Tension -> Html msg) -> List String -> Dict String (List Tension) -> Html msg
81+
viewBoard op header keys data =
82+
keys
83+
|> List.indexedMap
84+
(\i n ->
85+
let
86+
tensions =
87+
Dict.get n data |> withDefault []
88+
89+
j_last =
90+
List.length tensions - 1
91+
92+
t_m =
93+
List.head tensions
94+
in
95+
[ div
96+
([ class "column is-3" ]
97+
++ ternary op.hasTaskMove
98+
[ onDragEnter (op.onMoveEnterC { pos = i, to_receiverid = n } False)
99+
, onDragLeave op.onMoveLeaveC
100+
101+
-- @DEBUG doesn't work
102+
--, onDrop (OnMoveDrop n)
103+
, attribute "ondragover" "return false"
104+
105+
--, onMouseEnter (OnColumnHover (Just n)
106+
]
107+
[]
108+
)
109+
[ div [ class "subtitle is-aligned-center mb-0 pb-3" ] [ header n t_m ]
110+
, tensions
111+
--|> List.sortBy .createdAt
112+
--|> (\l -> ternary (model.sortFilter == defaultSortFilter) l (List.reverse l))
113+
|> List.indexedMap
114+
(\j t ->
115+
let
116+
draggedTid =
117+
Maybe.map .id op.movingTension
118+
119+
itemDragged =
120+
draggedTid == Just t.id
121+
122+
upperTid =
123+
LE.getAt (j - 1) tensions |> Maybe.map .id
124+
125+
isHoveredUp =
126+
-- exclude the dragged item
127+
not itemDragged
128+
-- hovered tension
129+
&& (Maybe.map .tid op.movingHoverT == Just t.id)
130+
-- exclude if the dragged item is next
131+
&& (draggedTid /= upperTid)
132+
133+
hasLastColumn =
134+
-- exclude the dragged item
135+
not itemDragged
136+
-- nothing to drag
137+
&& (op.movingHoverT == Nothing)
138+
-- last item
139+
&& (j_last == j && Maybe.map .pos op.movingHoverC == Just i)
140+
141+
draggingDiv =
142+
div
143+
[ class "box is-shrinked2 mb-2 mx-2 is-dragging is-growing"
144+
, style "opacity" "0.6"
145+
146+
--, style "height" "0rem"
147+
]
148+
[]
149+
in
150+
ternary isHoveredUp
151+
[ draggingDiv ]
152+
[]
153+
++ [ div
154+
([ class "box is-shrinked2 mb-2 mx-2"
155+
]
156+
++ ternary op.hasTaskMove
157+
[ classList [ ( "is-dragging", op.movingHoverT /= Nothing ) ]
158+
, attribute "draggable" "true"
159+
, attribute "ondragstart" "event.dataTransfer.setData(\"text/plain\", \"dummy\")"
160+
, onDragStart <| op.onMove { pos = i, to_receiverid = t.receiver.nameid } t
161+
, onDragEnd op.onEndMove
162+
, onDragEnter (op.onMoveEnterT { pos = j, tid = t.id, to_receiverid = t.receiver.nameid })
163+
]
164+
[]
165+
++ (if j_last == j && op.hasTaskMove then
166+
-- reset hoverT to draw below
167+
[ onDragLeave (op.onMoveEnterC { pos = i, to_receiverid = t.receiver.nameid } True) ]
168+
169+
else
170+
[]
171+
)
172+
)
173+
[ mediaTension op.conf op.node_focus t True False "is-size-6" ]
174+
]
175+
++ ternary hasLastColumn
176+
[ draggingDiv ]
177+
[]
178+
)
179+
|> List.concat
180+
|> div [ class "content scrollbar-thin" ]
181+
]
182+
, div [ class "divider is-vertical2 is-small is-hidden-mobile" ] []
183+
]
184+
)
185+
|> List.concat
186+
|> (\x ->
187+
if List.length x == 0 then
188+
[ div [ class "ml-6 p-6" ]
189+
[ text T.noTensionsAssigneesYet
190+
, ternary (op.node_focus.nameid /= op.node_focus.rootnameid)
191+
(span [ class "help-label button-light is-h is-discrete", onClick op.onNoTask ] [ A.icon "arrow-up", text T.goRoot ])
192+
(text "")
193+
]
194+
]
195+
196+
else
197+
x
198+
)
199+
|> div
200+
[ id op.boardId
201+
, class "columns is-fullwidth is-marginless is-mobile kb-board"
202+
203+
--, onMouseLeave (OnColumnHover Nothing)
204+
, attribute "style" <|
205+
case op.boardHeight of
206+
Just h ->
207+
"overflow-y: hidden; overflow-x: auto; height:" ++ String.fromFloat h ++ "px;"
208+
209+
Nothing ->
210+
"overflow-y: hidden; overflow-x: auto;"
211+
]

0 commit comments

Comments
 (0)