adds AutoCompletion and Modal
This commit is contained in:
@@ -29,6 +29,8 @@ type alias State =
|
|||||||
, mode : ActionMode
|
, mode : ActionMode
|
||||||
, error : Maybe String
|
, error : Maybe String
|
||||||
, notification : Maybe String
|
, notification : Maybe String
|
||||||
|
, autoComplete : Loot
|
||||||
|
, newItem : Maybe Item
|
||||||
|
|
||||||
-- Fetched on init
|
-- Fetched on init
|
||||||
, player : Api.Player
|
, player : Api.Player
|
||||||
@@ -56,7 +58,7 @@ type alias Model =
|
|||||||
init (Player navKey playerId) =
|
init (Player navKey playerId) =
|
||||||
( Model
|
( Model
|
||||||
navKey
|
navKey
|
||||||
(State False NoMode Nothing Nothing Api.blankPlayer [] [] [] [])
|
(State False NoMode Nothing Nothing [] Nothing Api.blankPlayer [] [] [] [])
|
||||||
Route.PlayerLoot
|
Route.PlayerLoot
|
||||||
Nothing
|
Nothing
|
||||||
""
|
""
|
||||||
@@ -137,7 +139,7 @@ viewHeaderBar title model =
|
|||||||
[ div [ class "navbar-brand" ]
|
[ div [ class "navbar-brand" ]
|
||||||
[ a [ class "navbar-item", href "/" ]
|
[ a [ class "navbar-item", href "/" ]
|
||||||
[ renderIcon { icon = "fab fa-d-and-d", size = "medium", ratio = "2x" }
|
[ renderIcon { icon = "fab fa-d-and-d", size = "medium", ratio = "2x" }
|
||||||
, span [ class "title is-4" ] [ text title ]
|
, span [ class "title is-4", style "padding-left" "0.4em" ] [ text title ]
|
||||||
]
|
]
|
||||||
, a [ class "navbar-burger is-active" ]
|
, a [ class "navbar-burger is-active" ]
|
||||||
[ span [ attribute "aria-hidden" "true" ] []
|
[ span [ attribute "aria-hidden" "true" ] []
|
||||||
@@ -283,7 +285,7 @@ view model =
|
|||||||
activeMode ->
|
activeMode ->
|
||||||
Just (rowRendererForMode activeMode)
|
Just (rowRendererForMode activeMode)
|
||||||
in
|
in
|
||||||
[ viewHeaderBar model.state.player.name model
|
[ viewHeaderBar "Mon coffre" model
|
||||||
, viewPlayerBar model.state.player renderControls
|
, viewPlayerBar model.state.player renderControls
|
||||||
, main_
|
, main_
|
||||||
[ class "container" ]
|
[ class "container" ]
|
||||||
@@ -450,20 +452,87 @@ viewItemTableRow isSelected canSelect rowRenderer item =
|
|||||||
--
|
--
|
||||||
|
|
||||||
|
|
||||||
|
fromListModal isActive =
|
||||||
|
div [ class "modal", classList [ ( "is-active", isActive ) ] ]
|
||||||
|
[ div [ class "modal-background" ] []
|
||||||
|
, div [ class "modal-card" ]
|
||||||
|
[ header [ class "modal-card-head" ] [ p [ class "modal-card-title" ] [ text "Liste d'objets" ] ]
|
||||||
|
, div [ class "modal-card-body" ]
|
||||||
|
[ textarea [ class "textarea" ] []
|
||||||
|
]
|
||||||
|
, div [ class "modal-card-foot" ]
|
||||||
|
[ button [ class "button" ] [ text "Ok" ]
|
||||||
|
, button [ class "button" ] [ text "Annuler" ]
|
||||||
|
]
|
||||||
|
]
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
viewCompletionDropdown : Bool -> Loot -> Html Msg
|
||||||
|
viewCompletionDropdown shown results =
|
||||||
|
div
|
||||||
|
[ class "dropdown"
|
||||||
|
, classList [ ( "is-active", shown ) ]
|
||||||
|
]
|
||||||
|
[ div [ class "dropdown-menu" ]
|
||||||
|
[ div [ class "dropdown-content" ]
|
||||||
|
(List.map
|
||||||
|
(\item ->
|
||||||
|
a
|
||||||
|
[ class "dropdown-item"
|
||||||
|
, onClick (SetNewItem item)
|
||||||
|
]
|
||||||
|
[ text item.name ]
|
||||||
|
)
|
||||||
|
results
|
||||||
|
)
|
||||||
|
]
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
viewAddLoot : Model -> Html Msg
|
viewAddLoot : Model -> Html Msg
|
||||||
viewAddLoot model =
|
viewAddLoot model =
|
||||||
let
|
let
|
||||||
|
autoResults =
|
||||||
|
model.state.autoComplete
|
||||||
|
|
||||||
showCompletionTips =
|
showCompletionTips =
|
||||||
|
if List.length autoResults > 0 && newItem.base_price == 0 then
|
||||||
|
True
|
||||||
|
|
||||||
|
else
|
||||||
|
False
|
||||||
|
|
||||||
|
showModal =
|
||||||
False
|
False
|
||||||
|
|
||||||
newItem =
|
newItem =
|
||||||
Item 0 "New one #1" 2000
|
case model.state.newItem of
|
||||||
|
Just item ->
|
||||||
|
item
|
||||||
|
|
||||||
|
Nothing ->
|
||||||
|
Item 0 "" 0
|
||||||
|
|
||||||
itemIsValid =
|
itemIsValid =
|
||||||
False
|
if nameValid && priceValid then
|
||||||
|
True
|
||||||
|
|
||||||
|
else
|
||||||
|
False
|
||||||
|
|
||||||
|
nameValid =
|
||||||
|
newItem.name /= ""
|
||||||
|
|
||||||
|
priceValid =
|
||||||
|
newItem.base_price > 0
|
||||||
|
|
||||||
|
doesNotYetExists =
|
||||||
|
newItem.id == 0
|
||||||
in
|
in
|
||||||
div [ class "box is-primary" ]
|
div [ class "box is-primary" ]
|
||||||
[ div [ class "field is-horizontal" ]
|
[ fromListModal showModal
|
||||||
|
, div [ class "field is-horizontal" ]
|
||||||
[ div [ class "field-label is-medium" ] [ label [ class "label" ] [ text "Source du loot" ] ]
|
[ div [ class "field-label is-medium" ] [ label [ class "label" ] [ text "Source du loot" ] ]
|
||||||
, div [ class "field-body" ]
|
, div [ class "field-body" ]
|
||||||
[ div [ class "field" ]
|
[ div [ class "field" ]
|
||||||
@@ -486,19 +555,26 @@ viewAddLoot model =
|
|||||||
[ div [ class "control" ]
|
[ div [ class "control" ]
|
||||||
[ input
|
[ input
|
||||||
[ class "input"
|
[ class "input"
|
||||||
|
, classList [ ( "is-success", nameValid ), ( "is-danger", not nameValid ) ]
|
||||||
, type_ "text"
|
, type_ "text"
|
||||||
, value newItem.name
|
, value newItem.name
|
||||||
|
, onInput NewItemNameChanged
|
||||||
]
|
]
|
||||||
[]
|
[]
|
||||||
]
|
]
|
||||||
, div
|
, if showCompletionTips then
|
||||||
[ class "dropdown"
|
viewCompletionDropdown showCompletionTips autoResults
|
||||||
, classList [ ( "is-active", showCompletionTips ) ]
|
|
||||||
]
|
else
|
||||||
[ div [ class "dropdown-menu" ]
|
text ""
|
||||||
[ div [ class "dropdown-content" ]
|
, p [ class "help has-text-warning" ]
|
||||||
[ a [ class "dropdown-item" ] [ text "item" ] ]
|
[ text
|
||||||
]
|
(if nameValid && doesNotYetExists then
|
||||||
|
"Cet objet n'existe pas dans l'inventaire. Il y sera ajouté si vous validez."
|
||||||
|
|
||||||
|
else
|
||||||
|
""
|
||||||
|
)
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
, div [ class "field is-narrow" ]
|
, div [ class "field is-narrow" ]
|
||||||
@@ -509,17 +585,27 @@ viewAddLoot model =
|
|||||||
[ type_ "number"
|
[ type_ "number"
|
||||||
, class "input"
|
, class "input"
|
||||||
, value <| String.fromInt newItem.base_price
|
, value <| String.fromInt newItem.base_price
|
||||||
, classList [ ( "is-danger", True ) ]
|
, onInput NewItemPriceChanged
|
||||||
|
, classList [ ( "is-danger", not priceValid ), ( "is-success", priceValid ) ]
|
||||||
]
|
]
|
||||||
[]
|
[]
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
, p [ class "help has-text-danger" ] [ text "Vous devez renseigner le prix !" ]
|
, p [ class "help has-text-danger" ]
|
||||||
|
[ text
|
||||||
|
(if priceValid then
|
||||||
|
""
|
||||||
|
|
||||||
|
else
|
||||||
|
"Vous devez renseigner le prix !"
|
||||||
|
)
|
||||||
|
]
|
||||||
]
|
]
|
||||||
, div [ class "field is-narrow" ]
|
, div [ class "field is-narrow" ]
|
||||||
[ div [ class "control" ]
|
[ div [ class "control" ]
|
||||||
[ button
|
[ button
|
||||||
[ class "button is-primary"
|
[ class "button"
|
||||||
|
, classList [ ( "is-primary", not doesNotYetExists ), ( "is-warning", doesNotYetExists ) ]
|
||||||
, disabled <| not itemIsValid
|
, disabled <| not itemIsValid
|
||||||
, onClick <| NewItemAdded newItem
|
, onClick <| NewItemAdded newItem
|
||||||
]
|
]
|
||||||
@@ -602,6 +688,14 @@ type Msg
|
|||||||
| ModeSwitched ActionMode
|
| ModeSwitched ActionMode
|
||||||
| ConfirmAction
|
| ConfirmAction
|
||||||
| NewItemAdded Item
|
| NewItemAdded Item
|
||||||
|
| NewItemNameChanged String
|
||||||
|
| NewItemPriceChanged String
|
||||||
|
| SetNewItem Item
|
||||||
|
|
||||||
|
|
||||||
|
insensitiveContains : String -> String -> Bool
|
||||||
|
insensitiveContains substring string =
|
||||||
|
String.contains (String.toLower substring) (String.toLower string)
|
||||||
|
|
||||||
|
|
||||||
update : Msg -> Model -> ( Model, Cmd Msg )
|
update : Msg -> Model -> ( Model, Cmd Msg )
|
||||||
@@ -614,6 +708,50 @@ update msg model =
|
|||||||
in
|
in
|
||||||
( { model | state = { state | newLoot = item :: state.newLoot } }, Cmd.none )
|
( { model | state = { state | newLoot = item :: state.newLoot } }, Cmd.none )
|
||||||
|
|
||||||
|
SetNewItem item ->
|
||||||
|
let
|
||||||
|
state =
|
||||||
|
model.state
|
||||||
|
in
|
||||||
|
( { model | state = { state | newItem = Just item } }, Cmd.none )
|
||||||
|
|
||||||
|
NewItemPriceChanged price ->
|
||||||
|
case String.toInt price of
|
||||||
|
Just newPrice ->
|
||||||
|
let
|
||||||
|
newItem =
|
||||||
|
case model.state.newItem of
|
||||||
|
Just item ->
|
||||||
|
{ item | base_price = newPrice }
|
||||||
|
|
||||||
|
Nothing ->
|
||||||
|
Item 0 "" newPrice
|
||||||
|
in
|
||||||
|
update (SetNewItem newItem) model
|
||||||
|
|
||||||
|
Nothing ->
|
||||||
|
( model, Cmd.none )
|
||||||
|
|
||||||
|
NewItemNameChanged itemName ->
|
||||||
|
let
|
||||||
|
state =
|
||||||
|
model.state
|
||||||
|
|
||||||
|
autoState =
|
||||||
|
model.state.autoComplete
|
||||||
|
|
||||||
|
-- For now, merchantLoot *IS* the inventory
|
||||||
|
results =
|
||||||
|
model.state.merchantLoot
|
||||||
|
|> List.filter (\i -> insensitiveContains itemName i.name)
|
||||||
|
in
|
||||||
|
{ model
|
||||||
|
| state =
|
||||||
|
{ state | autoComplete = results }
|
||||||
|
}
|
||||||
|
-- Update newItem field and erase other (outdated) values
|
||||||
|
|> update (SetNewItem <| Item 0 itemName 0)
|
||||||
|
|
||||||
ApiMsg apiMsg ->
|
ApiMsg apiMsg ->
|
||||||
case apiMsg of
|
case apiMsg of
|
||||||
Api.GotActionResult response ->
|
Api.GotActionResult response ->
|
||||||
|
|||||||
Reference in New Issue
Block a user