Restructure client code
This commit is contained in:
parent
9ce0f974fb
commit
05724dbaab
130
elm/Main.elm
130
elm/Main.elm
@ -95,14 +95,14 @@ decodeOI = Dec.succeed OverviewItem
|
|||||||
|> requiredAt ["item", "bought"] Dec.string
|
|> requiredAt ["item", "bought"] Dec.string
|
||||||
|> requiredAt ["overview", "activeMappings"] Dec.int
|
|> requiredAt ["overview", "activeMappings"] Dec.int
|
||||||
|
|
||||||
getSnacksByItemId : Int -> Cmd Msg
|
getSnacksByItem : OverviewItem -> Cmd Msg
|
||||||
getSnacksByItemId itemId = rpc
|
getSnacksByItem item = rpc
|
||||||
{ func = "getSnacksByItemId"
|
{ func = "getSnacksByItemId"
|
||||||
, args = Enc.object
|
, args = Enc.object
|
||||||
[ ("item", Enc.int itemId)
|
[ ("item", Enc.int item.id)
|
||||||
]
|
]
|
||||||
, expect = Dec.list decodeSnack
|
, expect = Dec.list decodeSnack
|
||||||
} RcvSnacks
|
} (RcvSnacks item)
|
||||||
|
|
||||||
type alias Snack =
|
type alias Snack =
|
||||||
{ id : Int
|
{ id : Int
|
||||||
@ -136,82 +136,85 @@ type alias Location =
|
|||||||
, name : String
|
, name : String
|
||||||
}
|
}
|
||||||
|
|
||||||
type alias Model =
|
type OuterState
|
||||||
{ state : State
|
|
||||||
}
|
|
||||||
|
|
||||||
type State
|
|
||||||
= LoadingLocations
|
= LoadingLocations
|
||||||
| LocationSelector (List Location)
|
| LocationSelector (List Location)
|
||||||
| Overview
|
| Initialized { locations : List Location, location : Location } State
|
||||||
{ location : Location
|
|
||||||
, selectedItems : Set Int
|
type State
|
||||||
|
= Overview
|
||||||
|
{ selectedItems : Set Int
|
||||||
, desiredInventory : Dict Int Int
|
, desiredInventory : Dict Int Int
|
||||||
, overviewItems : List OverviewItem
|
, overviewItems : List OverviewItem
|
||||||
}
|
}
|
||||||
| SnacksEditor
|
| SnacksEditor
|
||||||
{ snacks : List Snack
|
{ item : OverviewItem
|
||||||
|
, snacks : List Snack
|
||||||
}
|
}
|
||||||
|
|
||||||
type Msg
|
type Msg
|
||||||
= SelectItem Int Bool
|
= SelectLocation Location
|
||||||
|
| SelectItem Int Bool
|
||||||
|
| ChangeLocation
|
||||||
| SetDesiredInventory Int String
|
| SetDesiredInventory Int String
|
||||||
| SelectLocation Location
|
|
||||||
| TransferInventory Int
|
| TransferInventory Int
|
||||||
|
| GoBack
|
||||||
-- RPC calls
|
-- RPC calls
|
||||||
| CallDisableItems (List Int)
|
| CallDisableItems (List Int)
|
||||||
| CallAdjustInventory Int Int String
|
| CallAdjustInventory Int Int String
|
||||||
| CallGetSnacksById Int
|
| CallGetSnacksById OverviewItem
|
||||||
-- Responses
|
-- Responses
|
||||||
| RcvLocations (Result Http.Error (List Location))
|
| RcvLocations (Result Http.Error (List Location))
|
||||||
| RcvOverview (Result Http.Error (List OverviewItem))
|
| RcvOverview (Result Http.Error (List OverviewItem))
|
||||||
| RcvSnacks (Result Http.Error (List Snack))
|
| RcvSnacks OverviewItem (Result Http.Error (List Snack))
|
||||||
| RcvOther
|
| RcvOther
|
||||||
|
|
||||||
init = ({ state = LoadingLocations }, getLocations)
|
init = (LoadingLocations, getLocations)
|
||||||
|
|
||||||
update msg global = case msg of
|
update msg outerState = case msg of
|
||||||
CallAdjustInventory item amount desc -> (global, adjustInventory item amount desc)
|
CallAdjustInventory item amount desc -> (outerState, adjustInventory item amount desc)
|
||||||
CallDisableItems items -> (global, disableItems items)
|
CallDisableItems items -> (outerState, disableItems items)
|
||||||
CallGetSnacksById itemId -> (global, getSnacksByItemId itemId)
|
CallGetSnacksById item -> (outerState, getSnacksByItem item)
|
||||||
_ ->
|
_ -> case outerState of
|
||||||
let
|
|
||||||
(newState, cmd) = stateMachine msg global global.state
|
|
||||||
in
|
|
||||||
({ global | state = newState }, cmd)
|
|
||||||
|
|
||||||
stateMachine msg global state = case state of
|
|
||||||
LoadingLocations -> case msg of
|
LoadingLocations -> case msg of
|
||||||
RcvLocations (Ok locations) ->
|
RcvLocations (Ok locations) ->
|
||||||
(LocationSelector locations, Cmd.none)
|
(LocationSelector locations, Cmd.none)
|
||||||
_ ->
|
_ ->
|
||||||
(state, Cmd.none)
|
(outerState, Cmd.none)
|
||||||
LocationSelector locations -> case msg of
|
LocationSelector locations -> case msg of
|
||||||
SelectLocation location ->
|
SelectLocation location ->
|
||||||
(Overview
|
(Initialized { locations = locations, location = location } <| Overview
|
||||||
{ location = location
|
{ selectedItems = Set.empty
|
||||||
, selectedItems = Set.empty
|
|
||||||
, desiredInventory = Dict.empty
|
, desiredInventory = Dict.empty
|
||||||
, overviewItems = []
|
, overviewItems = []
|
||||||
}
|
}
|
||||||
, getOverviewItems location.id
|
, getOverviewItems location.id
|
||||||
)
|
)
|
||||||
_ ->
|
_ ->
|
||||||
(state, Cmd.none)
|
(outerState, Cmd.none)
|
||||||
|
Initialized global state -> case msg of
|
||||||
|
ChangeLocation ->
|
||||||
|
(LocationSelector global.locations, Cmd.none)
|
||||||
|
_ ->
|
||||||
|
let
|
||||||
|
(newState, cmd) = stateMachine msg global state
|
||||||
|
in
|
||||||
|
(Initialized global newState, cmd)
|
||||||
|
|
||||||
|
stateMachine msg global state = case state of
|
||||||
Overview model -> case msg of
|
Overview model -> case msg of
|
||||||
RcvOverview (Ok overviewItems) ->
|
RcvOverview (Ok overviewItems) ->
|
||||||
(Overview
|
(Overview
|
||||||
{ location = model.location
|
{ selectedItems = Set.empty
|
||||||
, selectedItems = Set.empty
|
|
||||||
, desiredInventory = Dict.empty
|
, desiredInventory = Dict.empty
|
||||||
, overviewItems = overviewItems
|
, overviewItems = overviewItems
|
||||||
}
|
}
|
||||||
, Cmd.none
|
, Cmd.none
|
||||||
)
|
)
|
||||||
RcvSnacks (Ok snacks) ->
|
RcvSnacks item (Ok snacks) ->
|
||||||
(SnacksEditor { snacks = snacks }, Cmd.none)
|
(SnacksEditor { item = item, snacks = snacks }, Cmd.none)
|
||||||
RcvOther ->
|
RcvOther ->
|
||||||
(state, getOverviewItems model.location.id)
|
(state, getOverviewItems global.location.id)
|
||||||
SelectItem itemId selected ->
|
SelectItem itemId selected ->
|
||||||
(Overview { model | selectedItems = setSelect itemId selected model.selectedItems }, Cmd.none)
|
(Overview { model | selectedItems = setSelect itemId selected model.selectedItems }, Cmd.none)
|
||||||
SetDesiredInventory itemId invStr -> case String.toInt invStr of
|
SetDesiredInventory itemId invStr -> case String.toInt invStr of
|
||||||
@ -231,10 +234,13 @@ stateMachine msg global state = case state of
|
|||||||
(state, transferInventory transfers)
|
(state, transferInventory transfers)
|
||||||
_ ->
|
_ ->
|
||||||
(state, Cmd.none)
|
(state, Cmd.none)
|
||||||
SnacksEditor { snacks } ->
|
SnacksEditor { snacks } -> case msg of
|
||||||
|
GoBack ->
|
||||||
|
(Overview { selectedItems = Set.empty, desiredInventory = Dict.empty, overviewItems = [] }, getOverviewItems global.location.id)
|
||||||
|
_ ->
|
||||||
(state, Cmd.none)
|
(state, Cmd.none)
|
||||||
|
|
||||||
view { state } = case state of
|
view outerState = case outerState of
|
||||||
LoadingLocations -> progress [] []
|
LoadingLocations -> progress [] []
|
||||||
LocationSelector locations ->
|
LocationSelector locations ->
|
||||||
let
|
let
|
||||||
@ -245,7 +251,17 @@ view { state } = case state of
|
|||||||
[ p [] [ text "Raum auswählen:" ]
|
[ p [] [ text "Raum auswählen:" ]
|
||||||
, div [] <| List.map viewLocationButton locations
|
, div [] <| List.map viewLocationButton locations
|
||||||
]
|
]
|
||||||
Overview { location, selectedItems, desiredInventory, overviewItems } ->
|
Initialized global state ->
|
||||||
|
div []
|
||||||
|
[ h2 []
|
||||||
|
[ text <| "Inventar " ++ global.location.name ++ " "
|
||||||
|
, button [ onClick ChangeLocation ] [ text "Raum ändern" ]
|
||||||
|
]
|
||||||
|
, viewState global state
|
||||||
|
]
|
||||||
|
|
||||||
|
viewState global state = case state of
|
||||||
|
Overview { selectedItems, desiredInventory, overviewItems } ->
|
||||||
let
|
let
|
||||||
header = tableCells th <| List.map text [ "", "ID", "Artikel", "Barcode", "Preis", "Kaufdatum", "Snackeinträge", "Soll-Inv.", "Ist-Inv.", "Aktionen" ]
|
header = tableCells th <| List.map text [ "", "ID", "Artikel", "Barcode", "Preis", "Kaufdatum", "Snackeinträge", "Soll-Inv.", "Ist-Inv.", "Aktionen" ]
|
||||||
viewOverviewItem oi =
|
viewOverviewItem oi =
|
||||||
@ -277,7 +293,7 @@ view { state } = case state of
|
|||||||
, text <| String.fromInt oi.id
|
, text <| String.fromInt oi.id
|
||||||
, text oi.name
|
, text oi.name
|
||||||
, code [] [ text oi.barcode ]
|
, code [] [ text oi.barcode ]
|
||||||
, text <| String.fromFloat oi.price
|
, text <| showEuros oi.price
|
||||||
, text <| Tuple.first <| splitAt 'T' oi.bought
|
, text <| Tuple.first <| splitAt 'T' oi.bought
|
||||||
, text <| String.fromInt oi.activeMappings
|
, text <| String.fromInt oi.activeMappings
|
||||||
, text <| String.fromInt oi.unitsLeft
|
, text <| String.fromInt oi.unitsLeft
|
||||||
@ -303,32 +319,31 @@ view { state } = case state of
|
|||||||
then [ disabled True ]
|
then [ disabled True ]
|
||||||
else [ onClick <| TransferInventory oi.id ])
|
else [ onClick <| TransferInventory oi.id ])
|
||||||
[ text <| String.fromInt sumSelected ++ " Einheiten umbuchen" ]
|
[ text <| String.fromInt sumSelected ++ " Einheiten umbuchen" ]
|
||||||
, button
|
, button [ onClick <| CallGetSnacksById oi ] [ text "Snackeinträge bearbeiten" ]
|
||||||
(if oi.activeMappings == 0
|
|
||||||
then [ disabled True ]
|
|
||||||
else [ onClick <| CallGetSnacksById oi.id ])
|
|
||||||
[ text "Snackeinträge bearbeiten" ]
|
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
in
|
in
|
||||||
div []
|
div []
|
||||||
[ h2 [] [ text <| "Inventar " ++ location.name ]
|
[ table [] <| [header] ++ List.map viewOverviewItem overviewItems
|
||||||
, table [] <| [header] ++ List.map viewOverviewItem overviewItems
|
|
||||||
]
|
]
|
||||||
SnacksEditor { snacks } ->
|
SnacksEditor { item, snacks } ->
|
||||||
let
|
let
|
||||||
header = tableCells th <| List.map text [ "ID", "Artikel", "Barcode", "Brutto" ]
|
header = tableCells th <| List.map text [ "ID", "Artikel", "Barcode", "Brutto" ]
|
||||||
viewSnack snack = tableCells td
|
viewSnack snack = tableCells td
|
||||||
[ text <| String.fromInt snack.id
|
[ text <| String.fromInt snack.id
|
||||||
, text snack.name
|
, text snack.name
|
||||||
, text snack.barcode
|
, text snack.barcode
|
||||||
, text <| String.fromFloat snack.price
|
, text <| showEuros snack.price
|
||||||
]
|
]
|
||||||
in
|
in
|
||||||
table []
|
div []
|
||||||
|
[ button [ onClick GoBack ] [ text "Zurück" ]
|
||||||
|
, p [] [ text <| "Snackeinträge für Inventareintrag " ++ String.fromInt item.id ++ " (" ++ showEuros item.price ++ " Netto)" ]
|
||||||
|
, table []
|
||||||
[ thead [] [ header ]
|
[ thead [] [ header ]
|
||||||
, tbody [] <| List.map viewSnack snacks
|
, tbody [] <| List.map viewSnack snacks
|
||||||
]
|
]
|
||||||
|
]
|
||||||
|
|
||||||
-- utils
|
-- utils
|
||||||
|
|
||||||
@ -354,4 +369,11 @@ splitAt delim str =
|
|||||||
|
|
||||||
firstOcc = locate delim str
|
firstOcc = locate delim str
|
||||||
in
|
in
|
||||||
(String.slice 0 firstOcc str, String.slice firstOcc (String.length str) str)
|
(String.slice 0 firstOcc str, String.slice (firstOcc + 1) (String.length str) str)
|
||||||
|
|
||||||
|
showEuros : Float -> String
|
||||||
|
showEuros x =
|
||||||
|
let
|
||||||
|
(whole, fractional) = splitAt '.' (String.fromFloat x)
|
||||||
|
in
|
||||||
|
whole ++ "," ++ String.slice 0 2 (fractional ++ "00") ++ "€"
|
||||||
|
@ -1,3 +1,11 @@
|
|||||||
|
html {
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
button, input {
|
||||||
|
font-size: 0.8rem;
|
||||||
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
font-family: Arial, Helvetica, sans-serif;
|
font-family: Arial, Helvetica, sans-serif;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user