Move FormData and Method types to package-exposed module.

This commit is contained in:
Dillon Kearns 2022-08-22 08:17:25 -07:00
parent 026f6defbd
commit 2804afccef
10 changed files with 75 additions and 63 deletions

File diff suppressed because one or more lines are too long

View File

@ -29,6 +29,7 @@
"Pages.Fetcher",
"Form.Field",
"Form.FieldStatus",
"Form.FormData",
"Form",
"Form.FieldView",
"Form.Value",

View File

@ -1,9 +1,7 @@
module Effect exposing (Effect(..), batch, fromCmd, map, none, perform)
import Browser.Navigation
import Bytes exposing (Bytes)
import Bytes.Decode
import FormDecoder
import Form.FormData exposing (FormData)
import Http
import Json.Decode as Decode
import Pages.Fetcher
@ -17,11 +15,11 @@ type Effect msg
| GetStargazers (Result Http.Error Int -> msg)
| SetField { formId : String, name : String, value : String }
| FetchRouteData
{ data : Maybe FormDecoder.FormData
{ data : Maybe FormData
, toMsg : Result Http.Error Url -> msg
}
| Submit
{ values : FormDecoder.FormData
{ values : FormData
, toMsg : Result Http.Error Url -> msg
}
| SubmitFetcher (Pages.Fetcher.Fetcher msg)
@ -86,12 +84,12 @@ map fn effect =
perform :
{ fetchRouteData :
{ data : Maybe FormDecoder.FormData
{ data : Maybe FormData
, toMsg : Result Http.Error Url -> pageMsg
}
-> Cmd msg
, submit :
{ values : FormDecoder.FormData
{ values : FormData
, toMsg : Result Http.Error Url -> pageMsg
}
-> Cmd msg

View File

@ -261,7 +261,7 @@ Totally customizable. Uses [`Form.FieldView`](Form-FieldView) to render all of t
import DataSource exposing (DataSource)
import Dict exposing (Dict)
import Form.Field as Field exposing (Field(..))
import Form.FieldStatus as FieldStatus
import Form.FieldStatus as FieldStatus exposing (FieldStatus)
import Form.FieldView
import Form.Validation as Validation exposing (Combined, Validation)
import Html exposing (Html)
@ -776,7 +776,8 @@ type alias AppContext app =
-- -> Pages.Fetcher.Fetcher (Result Http.Error action)
transition : Maybe Transition
, fetchers : List Pages.Transition.FetcherState
, pageFormState : Dict String FormState
, pageFormState :
Dict String { fields : Dict String { value : String, status : FieldStatus }, submitAttempted : Bool }
}

22
src/Form/FormData.elm Normal file
View File

@ -0,0 +1,22 @@
module Form.FormData exposing (FormData, Method(..))
{-|
@docs FormData, Method
-}
{-| -}
type alias FormData =
{ fields : List ( String, String )
, method : Method
, action : String
, id : Maybe String
}
{-| -}
type Method
= Get
| Post

View File

@ -1,5 +1,6 @@
module FormDecoder exposing (FormData, Method(..), encodeFormData, formDataOnSubmit, methodToString)
module FormDecoder exposing (encodeFormData, formDataOnSubmit, methodToString)
import Form.FormData as FormData exposing (FormData)
import Html
import Html.Events
import Json.Decode as Decode
@ -7,19 +8,6 @@ import Json.Encode
import Url
type alias FormData =
{ fields : List ( String, String )
, method : Method
, action : String
, id : Maybe String
}
type Method
= Get
| Post
formDataOnSubmit : Html.Attribute FormData
formDataOnSubmit =
Html.Events.preventDefaultOn "submit"
@ -46,22 +34,22 @@ formDataOnSubmit =
)
methodDecoder : Decode.Decoder Method
methodDecoder : Decode.Decoder FormData.Method
methodDecoder =
Decode.string
|> Decode.map
(\methodString ->
case methodString |> String.toUpper of
"GET" ->
Get
FormData.Get
"POST" ->
Post
FormData.Post
_ ->
-- TODO what about "dialog" method? Is it okay for that to be interpreted as GET,
-- or should there be a variant for that?
Get
FormData.Get
)
@ -84,13 +72,13 @@ tuplesDecoder =
)
methodToString : Method -> String
methodToString : FormData.Method -> String
methodToString method =
case method of
Get ->
FormData.Get ->
"GET"
Post ->
FormData.Post ->
"POST"

View File

@ -18,6 +18,7 @@ import BuildError exposing (BuildError)
import Bytes exposing (Bytes)
import Bytes.Decode
import Dict exposing (Dict)
import Form.FormData exposing (FormData, Method(..))
import FormDecoder
import Html exposing (Html)
import Html.Attributes as Attr
@ -44,7 +45,7 @@ import Url exposing (Url)
type Transition
= Loading Int Path
| Submitting FormDecoder.FormData
| Submitting FormData
{-| -}
@ -313,7 +314,7 @@ type Msg userMsg pageData actionData sharedData errorPage
| SetField { formId : String, name : String, value : String }
| UpdateCacheAndUrlNew Bool Url (Maybe userMsg) (Result Http.Error ( Url, ResponseSketch pageData actionData sharedData ))
| FetcherComplete Bool String Int (Result Http.Error (Maybe userMsg))
| FetcherStarted String Int FormDecoder.FormData Time.Posix
| FetcherStarted String Int FormData Time.Posix
| PageScrollComplete
| HotReloadCompleteNew Bytes
| ProcessFetchResponse Int (Result Http.Error ( Url, ResponseSketch pageData actionData sharedData )) (Result Http.Error ( Url, ResponseSketch pageData actionData sharedData ) -> Msg userMsg pageData actionData sharedData errorPage)
@ -350,9 +351,9 @@ type Effect userMsg pageData actionData sharedData userEffect errorPage
| BrowserLoadUrl String
| BrowserPushUrl String
| BrowserReplaceUrl String
| FetchPageData Int (Maybe FormDecoder.FormData) Url (Result Http.Error ( Url, ResponseSketch pageData actionData sharedData ) -> Msg userMsg pageData actionData sharedData errorPage)
| Submit FormDecoder.FormData
| SubmitFetcher String Int FormDecoder.FormData
| FetchPageData Int (Maybe FormData) Url (Result Http.Error ( Url, ResponseSketch pageData actionData sharedData ) -> Msg userMsg pageData actionData sharedData errorPage)
| Submit FormData
| SubmitFetcher String Int FormData
| Batch (List (Effect userMsg pageData actionData sharedData userEffect errorPage))
| UserCmd userEffect
| CancelRequest Int
@ -803,7 +804,7 @@ perform config model effect =
fetchRouteData True transitionKey toMsg config url maybeRequestInfo
Submit fields ->
if fields.method == FormDecoder.Get then
if fields.method == Get then
model.key
|> Maybe.map (\key -> Browser.Navigation.pushUrl key (appendFormQueryParams fields))
|> Maybe.withDefault Cmd.none
@ -875,14 +876,14 @@ startFetcher fetcherKey transitionId options model =
, action = ""
-- TODO remove hardcoding
, method = FormDecoder.Post
, method = Post
, id = Nothing
}
formData : { method : FormDecoder.Method, action : String, fields : List ( String, String ), id : Maybe String }
formData : { method : Method, action : String, fields : List ( String, String ), id : Maybe String }
formData =
{ -- TODO remove hardcoding
method = FormDecoder.Get
method = Get
-- TODO pass FormData directly
, action = options.url |> Maybe.withDefault model.url.path
@ -926,7 +927,7 @@ startFetcher fetcherKey transitionId options model =
]
startFetcher2 : Bool -> String -> Int -> FormDecoder.FormData -> Model userModel pageData actionData sharedData -> Cmd (Msg userMsg pageData actionData sharedData errorPage)
startFetcher2 : Bool -> String -> Int -> FormData -> Model userModel pageData actionData sharedData -> Cmd (Msg userMsg pageData actionData sharedData errorPage)
startFetcher2 fromPageReload fetcherKey transitionId formData model =
let
encodedBody : String
@ -995,7 +996,7 @@ cancelStaleFetchers model =
|> Cmd.batch
appendFormQueryParams : FormDecoder.FormData -> String
appendFormQueryParams : FormData -> String
appendFormQueryParams fields =
(fields.action
|> Url.fromString
@ -1003,15 +1004,15 @@ appendFormQueryParams fields =
|> Maybe.withDefault "/"
)
++ (case fields.method of
FormDecoder.Get ->
Get ->
"?" ++ FormDecoder.encodeFormData fields
FormDecoder.Post ->
Post ->
""
)
urlFromAction : Url -> Maybe FormDecoder.FormData -> Url
urlFromAction : Url -> Maybe FormData -> Url
urlFromAction currentUrl fetchInfo =
fetchInfo |> Maybe.map .action |> Maybe.andThen Url.fromString |> Maybe.withDefault currentUrl
@ -1105,7 +1106,7 @@ fetchRouteData :
-> (Result Http.Error ( Url, ResponseSketch pageData actionData sharedData ) -> Msg userMsg pageData actionData sharedData errorPage)
-> ProgramConfig userMsg userModel route pageData actionData sharedData effect (Msg userMsg pageData actionData sharedData errorPage) errorPage
-> Url
-> Maybe FormDecoder.FormData
-> Maybe FormData
-> Cmd (Msg userMsg pageData actionData sharedData errorPage)
fetchRouteData forPageDataReload transitionKey toMsg config url details =
{-
@ -1121,11 +1122,11 @@ fetchRouteData forPageDataReload transitionKey toMsg config url details =
-}
let
formMethod : FormDecoder.Method
formMethod : Method
formMethod =
details
|> Maybe.map .method
|> Maybe.withDefault FormDecoder.Get
|> Maybe.withDefault Get
in
Http.request
{ method = details |> Maybe.map (.method >> FormDecoder.methodToString) |> Maybe.withDefault "GET"
@ -1146,10 +1147,10 @@ fetchRouteData forPageDataReload transitionKey toMsg config url details =
|> String.join "/"
)
++ (case formMethod of
FormDecoder.Post ->
Post ->
"/"
FormDecoder.Get ->
Get ->
details
|> Maybe.map FormDecoder.encodeFormData
|> Maybe.map (\encoded -> "?" ++ encoded)
@ -1158,17 +1159,17 @@ fetchRouteData forPageDataReload transitionKey toMsg config url details =
++ (case formMethod of
-- TODO extract this to something unit testable
-- TODO make states mutually exclusive for submissions and direct URL requests (shouldn't be possible to append two query param strings)
FormDecoder.Post ->
Post ->
""
FormDecoder.Get ->
Get ->
url.query
|> Maybe.map (\encoded -> "?" ++ encoded)
|> Maybe.withDefault ""
)
, body =
case formMethod of
FormDecoder.Post ->
Post ->
let
urlEncodedFields : Maybe String
urlEncodedFields =

View File

@ -11,6 +11,7 @@ module Pages.Msg exposing
-}
import Form.FormData exposing (FormData)
import FormDecoder
import Html exposing (Attribute)
import Html.Attributes as Attr
@ -20,9 +21,9 @@ import Json.Decode
{-| -}
type Msg userMsg
= UserMsg userMsg
| Submit FormDecoder.FormData
| SubmitIfValid String FormDecoder.FormData Bool
| SubmitFetcher String FormDecoder.FormData Bool (Maybe userMsg)
| Submit FormData
| SubmitIfValid String FormData Bool
| SubmitFetcher String FormData Bool (Maybe userMsg)
| FormFieldEvent Json.Decode.Value

View File

@ -6,7 +6,7 @@ import Bytes exposing (Bytes)
import Bytes.Decode
import Bytes.Encode
import DataSource exposing (DataSource)
import FormDecoder
import Form.FormData exposing (FormData)
import Head
import Html exposing (Html)
import Http
@ -102,12 +102,12 @@ type alias ProgramConfig userMsg userModel route pageData actionData sharedData
, cmdToEffect : Cmd userMsg -> effect
, perform :
{ fetchRouteData :
{ data : Maybe FormDecoder.FormData
{ data : Maybe FormData
, toMsg : Result Http.Error Url -> userMsg
}
-> Cmd mappedMsg
, submit :
{ values : FormDecoder.FormData
{ values : FormData
, toMsg : Result Http.Error Url -> userMsg
}
-> Cmd mappedMsg

View File

@ -14,15 +14,15 @@ module Pages.Transition exposing
-}
import FormDecoder
import Form.FormData exposing (FormData)
import Path exposing (Path)
import Time
{-| -}
type Transition
= Submitting FormDecoder.FormData
| LoadAfterSubmit FormDecoder.FormData Path LoadingState
= Submitting FormData
| LoadAfterSubmit FormData Path LoadingState
| Loading Path LoadingState
@ -36,7 +36,7 @@ type LoadingState
{-| -}
type alias FetcherState =
{ status : FetcherSubmitStatus
, payload : FormDecoder.FormData
, payload : FormData
, initiatedAt : Time.Posix
}