From 1e47a7754ca38bd1a6c74765d8378caf68ce4619 Mon Sep 17 00:00:00 2001 From: Joris Date: Sun, 26 Mar 2017 21:10:42 +0200 Subject: Separate client and server watch --- src/client/LoggedIn/Home/View/ExceedingPayers.elm | 45 ++++++ src/client/LoggedIn/Home/View/Paging.elm | 109 ++++++++++++++ src/client/LoggedIn/Home/View/Table.elm | 166 ++++++++++++++++++++++ 3 files changed, 320 insertions(+) create mode 100644 src/client/LoggedIn/Home/View/ExceedingPayers.elm create mode 100644 src/client/LoggedIn/Home/View/Paging.elm create mode 100644 src/client/LoggedIn/Home/View/Table.elm (limited to 'src/client/LoggedIn/Home/View') diff --git a/src/client/LoggedIn/Home/View/ExceedingPayers.elm b/src/client/LoggedIn/Home/View/ExceedingPayers.elm new file mode 100644 index 0000000..6f2439c --- /dev/null +++ b/src/client/LoggedIn/Home/View/ExceedingPayers.elm @@ -0,0 +1,45 @@ +module LoggedIn.Home.View.ExceedingPayers exposing + ( view + ) + +import Html exposing (..) +import Html.Attributes exposing (..) + +import Msg exposing (Msg) + +import LoggedData exposing (LoggedData) + +import LoggedIn.View.Format as Format + +import Model exposing (Model) +import Model.User exposing (getUserName) +import Model.Payment as Payment +import Model.Payer exposing (..) +import Model.Translations exposing (getMessage) + +view : LoggedData -> Html Msg +view loggedData = + let payments = Payment.punctual loggedData.payments + exceedingPayers = getOrderedExceedingPayers loggedData.currentTime loggedData.users loggedData.incomes payments + in div + [ class "exceedingPayers" ] + ( if List.isEmpty exceedingPayers + then [ text <| getMessage loggedData.translations "PaymentsAreBalanced" ] + else (List.map (exceedingPayer loggedData) exceedingPayers) + ) + +exceedingPayer : LoggedData -> ExceedingPayer -> Html Msg +exceedingPayer loggedData payer = + span + [ class "exceedingPayer" ] + [ span + [ class "userName" ] + [ payer.userId + |> getUserName loggedData.users + |> Maybe.withDefault "−" + |> text + ] + , span + [ class "amount" ] + [ text ("+ " ++ (Format.price loggedData.conf payer.amount)) ] + ] diff --git a/src/client/LoggedIn/Home/View/Paging.elm b/src/client/LoggedIn/Home/View/Paging.elm new file mode 100644 index 0000000..dffe061 --- /dev/null +++ b/src/client/LoggedIn/Home/View/Paging.elm @@ -0,0 +1,109 @@ +module LoggedIn.Home.View.Paging exposing + ( view + ) + +import Color exposing (Color) + +import FontAwesome + +import Html exposing (..) +import Html.Attributes exposing (..) +import Html.Events exposing (..) + +import LoggedData exposing (LoggedData) +import Model.Payment as Payment exposing (Payments, perPage) + +showedPages : Int +showedPages = 5 + +view : Int -> Int -> msg -> (Int -> msg) -> Html msg +view currentPage payments noOp pageMsg = + let maxPage = ceiling (toFloat payments / toFloat perPage) + pages = truncatePages currentPage (List.range 1 maxPage) + in if maxPage <= 1 + then + text "" + else + div + [ class "pages" ] + ( [ firstPage currentPage pageMsg + , previousPage currentPage noOp pageMsg + ] + ++ ( List.map (paymentsPage currentPage noOp pageMsg) pages) + ++ [ nextPage currentPage maxPage noOp pageMsg + , lastPage currentPage maxPage pageMsg + ] + ) + +truncatePages : Int -> List Int -> List Int +truncatePages currentPage pages = + let totalPages = List.length pages + showedLeftPages = ceiling ((toFloat showedPages - 1) / 2) + showedRightPages = floor ((toFloat showedPages - 1) / 2) + truncatedPages = + if currentPage <= showedLeftPages then + (List.range 1 showedPages) + else if currentPage > totalPages - showedRightPages then + (List.range (totalPages - showedPages + 1) totalPages) + else + (List.range (currentPage - showedLeftPages) (currentPage + showedRightPages)) + in List.filter (flip List.member pages) truncatedPages + +firstPage : Int -> (Int -> msg) -> Html msg +firstPage currentPage pageMsg = + button + [ classList + [ ("page", True) + , ("disable", currentPage <= 1) + ] + , onClick (pageMsg 1) + ] + [ FontAwesome.fast_backward grey 13 ] + +previousPage : Int -> msg -> (Int -> msg) -> Html msg +previousPage currentPage noOp pageMsg = + button + [ class "page" + , onClick <| + if currentPage > 1 + then (pageMsg <| currentPage - 1) + else noOp + ] + [ FontAwesome.backward grey 13 ] + +nextPage : Int -> Int -> msg -> (Int -> msg) -> Html msg +nextPage currentPage maxPage noOp pageMsg = + button + [ class "page" + , onClick <| + if currentPage < maxPage + then (pageMsg <| currentPage + 1) + else noOp + ] + [ FontAwesome.forward grey 13 ] + +lastPage : Int -> Int -> (Int -> msg) -> Html msg +lastPage currentPage maxPage pageMsg = + button + [ class "page" + , onClick (pageMsg maxPage) + ] + [ FontAwesome.fast_forward grey 13 ] + +paymentsPage : Int -> msg -> (Int -> msg) -> Int -> Html msg +paymentsPage currentPage noOp pageMsg page = + let onCurrentPage = page == currentPage + in button + [ classList + [ ("page", True) + , ("current", onCurrentPage) + ] + , onClick <| + if onCurrentPage + then noOp + else pageMsg page + ] + [ text (toString page) ] + +grey : Color +grey = Color.greyscale 0.35 diff --git a/src/client/LoggedIn/Home/View/Table.elm b/src/client/LoggedIn/Home/View/Table.elm new file mode 100644 index 0000000..8828488 --- /dev/null +++ b/src/client/LoggedIn/Home/View/Table.elm @@ -0,0 +1,166 @@ +module LoggedIn.Home.View.Table exposing + ( view + ) + +import Date exposing (Date) +import Dict exposing (..) +import String exposing (append) + +import FontAwesome +import View.Color as Color + +import Html exposing (..) +import Html.Attributes exposing (..) +import Html.Events exposing (..) + +import Dialog +import Dialog.AddPayment.Model as AddPayment +import Dialog.AddPayment.View as AddPayment + +import Tooltip + +import Msg exposing (Msg) + +import LoggedData exposing (LoggedData) + +import LoggedIn.Msg as LoggedInMsg + +import LoggedIn.Home.Model as Home +import LoggedIn.View.Format as Format +import View.Date as Date + +import Model.Payment as Payment exposing (..) +import Model.PaymentCategory as PaymentCategory +import Model.Translations exposing (getMessage) +import Model.User exposing (getUserName) + +view : LoggedData -> Home.Model -> Payments -> Frequency -> Html Msg +view loggedData homeModel payments frequency = + let visiblePayments = + payments + |> List.drop ((homeModel.currentPage - 1) * perPage) + |> List.take perPage + in div + [ class "table" ] + [ div + [ class "lines" ] + ( headerLine loggedData frequency :: List.map (paymentLine loggedData homeModel frequency) visiblePayments ) + , if List.isEmpty visiblePayments + then + div + [ class "emptyTableMsg" ] + [ text <| getMessage loggedData.translations "NoPayment" ] + else + text "" + ] + +headerLine : LoggedData -> Frequency -> Html Msg +headerLine loggedData frequency = + div + [ class "header" ] + [ div [ class "cell category" ] [ text <| getMessage loggedData.translations "Name" ] + , div [ class "cell cost" ] [ text <| getMessage loggedData.translations "Cost" ] + , div [ class "cell user" ] [ text <| getMessage loggedData.translations "Payer" ] + , div [ class "cell user" ] [ text <| getMessage loggedData.translations "PaymentCategory" ] + , case frequency of + Punctual -> div [ class "cell date" ] [ text <| getMessage loggedData.translations "Date" ] + Monthly -> text "" + , div [ class "cell" ] [] + , div [ class "cell" ] [] + , div [ class "cell" ] [] + ] + +paymentLine : LoggedData -> Home.Model -> Frequency -> Payment -> Html Msg +paymentLine loggedData homeModel frequency payment = + div + [ class "row" ] + [ div [ class "cell name" ] [ text payment.name ] + , div + [ classList + [ ("cell cost", True) + , ("refund", payment.cost < 0) + ] + ] + [ text (Format.price loggedData.conf payment.cost) ] + , div + [ class "cell user" ] + [ payment.userId + |> getUserName loggedData.users + |> Maybe.withDefault "−" + |> text + ] + , div + [ class "cell category" ] + ( let mbCategory = + PaymentCategory.search payment.name loggedData.paymentCategories + |> Maybe.andThen (\category -> Dict.get category loggedData.categories) + in case mbCategory of + Just category -> + [ span + [ class "tag" + , style [("background-color", category.color)] + ] + [ text category.name ] + ] + Nothing -> + [] + ) + , case frequency of + Punctual -> + div + [ class "cell date" ] + [ span + [ class "shortDate" ] + [ text (Date.shortView payment.date loggedData.translations) ] + , span + [ class "longDate" ] + [ text (Date.longView payment.date loggedData.translations) ] + ] + Monthly -> + text "" + , div + [ class "cell button" ] + [ let currentDate = Date.fromTime loggedData.currentTime + category = PaymentCategory.search payment.name loggedData.paymentCategories + in AddPayment.button + loggedData + (AddPayment.initialClone loggedData.translations currentDate category payment) + "ClonePayment" + (FontAwesome.clone Color.chestnutRose 18) + (Just (getMessage loggedData.translations "Clone")) + ] + , div + [ class "cell button" ] + [ if loggedData.me /= payment.userId + then + text "" + else + let category = PaymentCategory.search payment.name loggedData.paymentCategories + in AddPayment.button + loggedData + (AddPayment.initialEdit loggedData.translations category payment) + "EditPayment" + (FontAwesome.pencil Color.chestnutRose 18) + (Just (getMessage loggedData.translations "Edit")) + ] + , div + [ class "cell button" ] + [ if loggedData.me /= payment.userId + then + text "" + else + let dialogConfig = + { className = "deletePaymentDialog" + , title = getMessage loggedData.translations "ConfirmPaymentDelete" + , body = always <| text "" + , confirm = getMessage loggedData.translations "Confirm" + , confirmMsg = always <| Msg.Dialog <| Dialog.UpdateAndClose <| Msg.DeletePayment payment.id + , undo = getMessage loggedData.translations "Undo" + } + in button + ( Tooltip.show Msg.Tooltip (getMessage loggedData.translations "Delete") + ++ [ onClick (Msg.Dialog <| Dialog.Open dialogConfig) ] + ) + [ FontAwesome.trash Color.chestnutRose 18 ] + ] + ] -- cgit v1.2.3