2020-03-31 03:22:27 +00:00
|
|
|
|
module Main exposing (main)
|
2020-03-28 04:09:01 +00:00
|
|
|
|
|
2020-05-08 13:24:58 +00:00
|
|
|
|
--exposing (UrlRequest(..))
|
|
|
|
|
|
|
|
|
|
import Browser
|
|
|
|
|
import Browser.Navigation
|
2020-03-31 03:22:27 +00:00
|
|
|
|
import Html
|
|
|
|
|
exposing
|
|
|
|
|
( Html
|
2020-04-10 08:13:50 +00:00
|
|
|
|
, a
|
2020-03-31 03:22:27 +00:00
|
|
|
|
, div
|
2020-04-10 08:13:50 +00:00
|
|
|
|
, footer
|
2020-03-31 03:22:27 +00:00
|
|
|
|
, header
|
2020-04-10 08:13:50 +00:00
|
|
|
|
, img
|
2020-03-31 03:22:27 +00:00
|
|
|
|
, li
|
2020-06-04 23:13:52 +00:00
|
|
|
|
, span
|
2020-03-31 03:22:27 +00:00
|
|
|
|
, text
|
|
|
|
|
, ul
|
|
|
|
|
)
|
|
|
|
|
import Html.Attributes
|
|
|
|
|
exposing
|
|
|
|
|
( class
|
2020-05-08 13:24:58 +00:00
|
|
|
|
, classList
|
2020-04-10 08:13:50 +00:00
|
|
|
|
, href
|
2020-06-04 23:13:52 +00:00
|
|
|
|
, id
|
2020-04-10 08:13:50 +00:00
|
|
|
|
, src
|
2020-03-31 03:22:27 +00:00
|
|
|
|
)
|
2020-05-08 13:24:58 +00:00
|
|
|
|
import Page.Home
|
|
|
|
|
import Page.Options
|
|
|
|
|
import Page.Packages
|
|
|
|
|
import Route
|
2020-06-03 23:33:54 +00:00
|
|
|
|
import Search
|
2020-05-08 13:24:58 +00:00
|
|
|
|
import Url
|
2020-06-10 12:03:44 +00:00
|
|
|
|
import Url.Builder
|
2020-03-28 04:09:01 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-- MODEL
|
|
|
|
|
|
|
|
|
|
|
2020-04-07 05:05:50 +00:00
|
|
|
|
type alias Flags =
|
2020-06-03 23:33:54 +00:00
|
|
|
|
{ elasticsearchMappingSchemaVersion : Int
|
|
|
|
|
, elasticsearchUrl : String
|
2020-04-07 05:05:50 +00:00
|
|
|
|
, elasticsearchUsername : String
|
|
|
|
|
, elasticsearchPassword : String
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2020-03-28 04:09:01 +00:00
|
|
|
|
type alias Model =
|
2020-05-08 13:24:58 +00:00
|
|
|
|
{ navKey : Browser.Navigation.Key
|
|
|
|
|
, url : Url.Url
|
2020-06-03 19:02:12 +00:00
|
|
|
|
, elasticsearch : Search.Options
|
2020-03-28 04:09:01 +00:00
|
|
|
|
, page : Page
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
type Page
|
2020-05-08 13:24:58 +00:00
|
|
|
|
= NotFound
|
|
|
|
|
| Home Page.Home.Model
|
|
|
|
|
| Packages Page.Packages.Model
|
|
|
|
|
| Options Page.Options.Model
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
init :
|
|
|
|
|
Flags
|
|
|
|
|
-> Url.Url
|
|
|
|
|
-> Browser.Navigation.Key
|
|
|
|
|
-> ( Model, Cmd Msg )
|
|
|
|
|
init flags url navKey =
|
2020-04-10 08:13:50 +00:00
|
|
|
|
let
|
|
|
|
|
model =
|
2020-05-08 13:24:58 +00:00
|
|
|
|
{ navKey = navKey
|
|
|
|
|
, url = url
|
|
|
|
|
, elasticsearch =
|
2020-06-03 19:02:12 +00:00
|
|
|
|
Search.Options
|
2020-06-03 23:33:54 +00:00
|
|
|
|
flags.elasticsearchMappingSchemaVersion
|
2020-05-08 13:24:58 +00:00
|
|
|
|
flags.elasticsearchUrl
|
|
|
|
|
flags.elasticsearchUsername
|
|
|
|
|
flags.elasticsearchPassword
|
|
|
|
|
, page = NotFound
|
2020-04-10 08:13:50 +00:00
|
|
|
|
}
|
|
|
|
|
in
|
2020-05-08 13:24:58 +00:00
|
|
|
|
changeRouteTo model url
|
2020-04-10 08:13:50 +00:00
|
|
|
|
|
|
|
|
|
|
2020-03-28 04:09:01 +00:00
|
|
|
|
|
|
|
|
|
-- UPDATE
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
type Msg
|
2020-05-08 13:24:58 +00:00
|
|
|
|
= ChangedUrl Url.Url
|
|
|
|
|
| ClickedLink Browser.UrlRequest
|
|
|
|
|
| HomeMsg Page.Home.Msg
|
|
|
|
|
| PackagesMsg Page.Packages.Msg
|
|
|
|
|
| OptionsMsg Page.Options.Msg
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
updateWith :
|
|
|
|
|
(subModel -> Page)
|
|
|
|
|
-> (subMsg -> Msg)
|
|
|
|
|
-> Model
|
|
|
|
|
-> ( subModel, Cmd subMsg )
|
|
|
|
|
-> ( Model, Cmd Msg )
|
|
|
|
|
updateWith toPage toMsg model ( subModel, subCmd ) =
|
|
|
|
|
( { model | page = toPage subModel }
|
|
|
|
|
, Cmd.map toMsg subCmd
|
|
|
|
|
)
|
2020-04-07 05:05:50 +00:00
|
|
|
|
|
|
|
|
|
|
2020-05-08 13:24:58 +00:00
|
|
|
|
submitQuery :
|
|
|
|
|
Model
|
|
|
|
|
-> ( Model, Cmd Msg )
|
|
|
|
|
-> ( Model, Cmd Msg )
|
|
|
|
|
submitQuery old ( new, cmd ) =
|
|
|
|
|
let
|
2020-06-10 12:03:44 +00:00
|
|
|
|
triggerSearch _ newModel msg makeRequest =
|
2020-06-12 10:57:47 +00:00
|
|
|
|
if newModel.query /= Nothing && newModel.query /= Just "" then
|
2020-05-08 13:24:58 +00:00
|
|
|
|
( new
|
|
|
|
|
, Cmd.batch
|
|
|
|
|
[ cmd
|
2020-05-08 14:56:14 +00:00
|
|
|
|
, makeRequest
|
2020-05-08 13:24:58 +00:00
|
|
|
|
new.elasticsearch
|
2020-05-11 20:42:57 +00:00
|
|
|
|
newModel.channel
|
2020-05-08 13:24:58 +00:00
|
|
|
|
(Maybe.withDefault "" newModel.query)
|
2020-05-11 19:56:10 +00:00
|
|
|
|
newModel.from
|
|
|
|
|
newModel.size
|
2020-05-08 14:56:14 +00:00
|
|
|
|
|> Cmd.map msg
|
2020-05-08 13:24:58 +00:00
|
|
|
|
]
|
|
|
|
|
)
|
2020-05-08 21:59:14 +00:00
|
|
|
|
|
|
|
|
|
else
|
|
|
|
|
( new, cmd )
|
2020-05-08 13:24:58 +00:00
|
|
|
|
in
|
|
|
|
|
case ( old.page, new.page ) of
|
|
|
|
|
( Packages oldModel, Packages newModel ) ->
|
|
|
|
|
triggerSearch oldModel newModel PackagesMsg Page.Packages.makeRequest
|
2020-04-07 05:05:50 +00:00
|
|
|
|
|
2020-05-08 21:59:14 +00:00
|
|
|
|
( NotFound, Packages newModel ) ->
|
|
|
|
|
triggerSearch newModel newModel PackagesMsg Page.Packages.makeRequest
|
|
|
|
|
|
2020-05-08 13:24:58 +00:00
|
|
|
|
( Options oldModel, Options newModel ) ->
|
|
|
|
|
triggerSearch oldModel newModel OptionsMsg Page.Options.makeRequest
|
2020-04-07 05:05:50 +00:00
|
|
|
|
|
2020-05-08 21:59:14 +00:00
|
|
|
|
( NotFound, Options newModel ) ->
|
|
|
|
|
triggerSearch newModel newModel OptionsMsg Page.Options.makeRequest
|
|
|
|
|
|
2020-05-08 13:24:58 +00:00
|
|
|
|
( _, _ ) ->
|
|
|
|
|
( new, cmd )
|
2020-04-07 05:05:50 +00:00
|
|
|
|
|
|
|
|
|
|
2020-06-11 16:29:51 +00:00
|
|
|
|
changeRouteTo :
|
|
|
|
|
Model
|
|
|
|
|
-> Url.Url
|
|
|
|
|
-> ( Model, Cmd Msg )
|
2020-05-08 13:24:58 +00:00
|
|
|
|
changeRouteTo model url =
|
|
|
|
|
let
|
|
|
|
|
newModel =
|
|
|
|
|
{ model | url = url }
|
2020-04-07 05:05:50 +00:00
|
|
|
|
|
2020-05-08 13:24:58 +00:00
|
|
|
|
maybeRoute =
|
|
|
|
|
Route.fromUrl url
|
|
|
|
|
in
|
|
|
|
|
case maybeRoute of
|
|
|
|
|
Nothing ->
|
|
|
|
|
( { newModel
|
|
|
|
|
| page = NotFound
|
|
|
|
|
}
|
|
|
|
|
, Cmd.none
|
|
|
|
|
)
|
2020-04-07 05:05:50 +00:00
|
|
|
|
|
2020-05-08 13:24:58 +00:00
|
|
|
|
Just Route.NotFound ->
|
|
|
|
|
( { newModel
|
|
|
|
|
| page = NotFound
|
|
|
|
|
}
|
|
|
|
|
, Cmd.none
|
|
|
|
|
)
|
2020-04-07 05:05:50 +00:00
|
|
|
|
|
2020-05-08 13:24:58 +00:00
|
|
|
|
Just Route.Home ->
|
|
|
|
|
-- Always redirect to /packages until we have something to show
|
|
|
|
|
-- on the home page
|
|
|
|
|
( newModel, Browser.Navigation.pushUrl newModel.navKey "/packages" )
|
2020-04-07 05:05:50 +00:00
|
|
|
|
|
2020-06-10 12:15:54 +00:00
|
|
|
|
Just (Route.Packages channel query show from size) ->
|
2020-06-11 16:29:51 +00:00
|
|
|
|
let
|
|
|
|
|
modelPage =
|
|
|
|
|
case newModel.page of
|
|
|
|
|
Packages x ->
|
|
|
|
|
Just x
|
|
|
|
|
|
|
|
|
|
_ ->
|
|
|
|
|
Nothing
|
|
|
|
|
in
|
|
|
|
|
Page.Packages.init channel query show from size modelPage
|
2020-05-08 13:24:58 +00:00
|
|
|
|
|> updateWith Packages PackagesMsg newModel
|
|
|
|
|
|> submitQuery newModel
|
2020-04-07 05:05:50 +00:00
|
|
|
|
|
2020-06-10 12:15:54 +00:00
|
|
|
|
Just (Route.Options channel query show from size) ->
|
2020-06-11 16:29:51 +00:00
|
|
|
|
let
|
|
|
|
|
modelPage =
|
|
|
|
|
case newModel.page of
|
|
|
|
|
Options x ->
|
|
|
|
|
Just x
|
|
|
|
|
|
|
|
|
|
_ ->
|
|
|
|
|
Nothing
|
|
|
|
|
in
|
|
|
|
|
Page.Options.init channel query show from size modelPage
|
2020-05-08 13:24:58 +00:00
|
|
|
|
|> updateWith Options OptionsMsg newModel
|
|
|
|
|
|> submitQuery newModel
|
2020-04-07 05:05:50 +00:00
|
|
|
|
|
|
|
|
|
|
2020-03-28 04:09:01 +00:00
|
|
|
|
update : Msg -> Model -> ( Model, Cmd Msg )
|
2020-05-08 13:24:58 +00:00
|
|
|
|
update msg model =
|
|
|
|
|
case ( msg, model.page ) of
|
|
|
|
|
( ClickedLink urlRequest, _ ) ->
|
|
|
|
|
case urlRequest of
|
|
|
|
|
Browser.Internal url ->
|
2020-03-31 00:59:06 +00:00
|
|
|
|
( model
|
2020-05-11 19:56:10 +00:00
|
|
|
|
, if url.fragment == Just "disabled" then
|
|
|
|
|
Cmd.none
|
|
|
|
|
|
|
|
|
|
else
|
|
|
|
|
Browser.Navigation.pushUrl model.navKey <| Url.toString url
|
2020-03-31 00:59:06 +00:00
|
|
|
|
)
|
2020-03-28 04:09:01 +00:00
|
|
|
|
|
2020-05-08 13:24:58 +00:00
|
|
|
|
Browser.External href ->
|
2020-04-10 08:13:50 +00:00
|
|
|
|
( model
|
2020-05-08 13:24:58 +00:00
|
|
|
|
, Browser.Navigation.load href
|
2020-04-10 08:13:50 +00:00
|
|
|
|
)
|
|
|
|
|
|
2020-05-08 13:24:58 +00:00
|
|
|
|
( ChangedUrl url, _ ) ->
|
|
|
|
|
changeRouteTo model url
|
2020-04-10 08:13:50 +00:00
|
|
|
|
|
2020-05-08 13:24:58 +00:00
|
|
|
|
( HomeMsg subMsg, Home subModel ) ->
|
|
|
|
|
Page.Home.update subMsg subModel
|
|
|
|
|
|> updateWith Home HomeMsg model
|
|
|
|
|
|
|
|
|
|
( PackagesMsg subMsg, Packages subModel ) ->
|
|
|
|
|
Page.Packages.update model.navKey subMsg subModel
|
|
|
|
|
|> updateWith Packages PackagesMsg model
|
|
|
|
|
|
|
|
|
|
( OptionsMsg subMsg, Options subModel ) ->
|
|
|
|
|
Page.Options.update model.navKey subMsg subModel
|
|
|
|
|
|> updateWith Options OptionsMsg model
|
|
|
|
|
|
|
|
|
|
( _, _ ) ->
|
|
|
|
|
-- Disregard messages that arrived for the wrong page.
|
|
|
|
|
( model, Cmd.none )
|
2020-04-10 08:13:50 +00:00
|
|
|
|
|
2020-03-28 04:09:01 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-- VIEW
|
|
|
|
|
|
|
|
|
|
|
2020-06-12 10:20:28 +00:00
|
|
|
|
view :
|
|
|
|
|
Model
|
|
|
|
|
->
|
|
|
|
|
{ title : String
|
|
|
|
|
, body : List (Html Msg)
|
|
|
|
|
}
|
2020-03-28 04:09:01 +00:00
|
|
|
|
view model =
|
2020-06-12 10:20:28 +00:00
|
|
|
|
let
|
|
|
|
|
title =
|
|
|
|
|
case model.page of
|
|
|
|
|
Packages _ ->
|
|
|
|
|
"NixOS Search - Packages"
|
|
|
|
|
|
|
|
|
|
Options _ ->
|
|
|
|
|
"NixOS Search - Options"
|
|
|
|
|
|
|
|
|
|
_ ->
|
|
|
|
|
"NixOS Search"
|
|
|
|
|
in
|
|
|
|
|
{ title = title
|
|
|
|
|
, body =
|
|
|
|
|
[ div []
|
|
|
|
|
[ header []
|
|
|
|
|
[ div [ class "navbar navbar-static-top" ]
|
|
|
|
|
[ div [ class "navbar-inner" ]
|
|
|
|
|
[ div [ class "container" ]
|
|
|
|
|
[ a [ class "brand", href "https://nixos.org" ]
|
|
|
|
|
[ img [ src "https://nixos.org/logo/nix-wiki.png", class "logo" ] []
|
|
|
|
|
]
|
|
|
|
|
, div [ class "nav-collapse collapse" ]
|
|
|
|
|
[ ul [ class "nav pull-left" ]
|
|
|
|
|
(viewNavigation model.page model.url)
|
|
|
|
|
]
|
2020-06-11 07:14:21 +00:00
|
|
|
|
]
|
2020-04-10 08:13:50 +00:00
|
|
|
|
]
|
|
|
|
|
]
|
|
|
|
|
]
|
2020-06-12 10:20:28 +00:00
|
|
|
|
, div [ class "container main" ]
|
|
|
|
|
[ div [ id "content" ] [ viewPage model ]
|
|
|
|
|
, footer
|
|
|
|
|
[ class "container text-center" ]
|
|
|
|
|
[ div []
|
|
|
|
|
[ span [] [ text "Elasticsearch instance graciously provided by " ]
|
|
|
|
|
, a [ href "https://bonsai.io" ] [ text "Bonsai" ]
|
|
|
|
|
, span [] [ text "." ]
|
|
|
|
|
]
|
|
|
|
|
, div []
|
|
|
|
|
[ span [] [ text "❤️ Thank you ❤️ " ]
|
|
|
|
|
]
|
2020-06-04 23:13:52 +00:00
|
|
|
|
]
|
|
|
|
|
]
|
2020-03-28 04:09:01 +00:00
|
|
|
|
]
|
|
|
|
|
]
|
2020-06-12 10:20:28 +00:00
|
|
|
|
}
|
2020-03-28 04:09:01 +00:00
|
|
|
|
|
|
|
|
|
|
2020-06-11 07:14:21 +00:00
|
|
|
|
viewNavigation : Page -> Url.Url -> List (Html Msg)
|
2020-06-10 12:03:44 +00:00
|
|
|
|
viewNavigation page url =
|
|
|
|
|
let
|
|
|
|
|
preserveSearchOptions =
|
|
|
|
|
case page of
|
|
|
|
|
Packages model ->
|
|
|
|
|
model.query
|
|
|
|
|
|> Maybe.map (\q -> [ Url.Builder.string "query" q ])
|
|
|
|
|
|> Maybe.withDefault []
|
|
|
|
|
|> List.append [ Url.Builder.string "channel" model.channel ]
|
|
|
|
|
|
|
|
|
|
Options model ->
|
|
|
|
|
model.query
|
|
|
|
|
|> Maybe.map (\q -> [ Url.Builder.string "query" q ])
|
|
|
|
|
|> Maybe.withDefault []
|
|
|
|
|
|> List.append [ Url.Builder.string "channel" model.channel ]
|
|
|
|
|
|
|
|
|
|
_ ->
|
|
|
|
|
[]
|
|
|
|
|
|
|
|
|
|
createUrl path =
|
|
|
|
|
[]
|
|
|
|
|
|> List.append preserveSearchOptions
|
|
|
|
|
|> Url.Builder.absolute [ path ]
|
|
|
|
|
in
|
2020-06-11 07:14:21 +00:00
|
|
|
|
List.map
|
|
|
|
|
(viewNavigationItem url)
|
|
|
|
|
[ ( "https://nixos.org", "Back to nixos.org" )
|
|
|
|
|
, ( createUrl "packages", "Packages" )
|
|
|
|
|
, ( createUrl "options", "Options" )
|
|
|
|
|
]
|
2020-04-07 05:05:50 +00:00
|
|
|
|
|
|
|
|
|
|
2020-05-08 13:24:58 +00:00
|
|
|
|
viewNavigationItem :
|
|
|
|
|
Url.Url
|
|
|
|
|
-> ( String, String )
|
|
|
|
|
-> Html Msg
|
|
|
|
|
viewNavigationItem url ( path, title ) =
|
|
|
|
|
li
|
|
|
|
|
[ classList [ ( "active", path == url.path ) ] ]
|
|
|
|
|
[ a [ href path ] [ text title ] ]
|
2020-04-07 05:05:50 +00:00
|
|
|
|
|
2020-04-10 09:04:03 +00:00
|
|
|
|
|
2020-05-08 13:24:58 +00:00
|
|
|
|
viewPage : Model -> Html Msg
|
|
|
|
|
viewPage model =
|
|
|
|
|
case model.page of
|
|
|
|
|
NotFound ->
|
|
|
|
|
div [] [ text "Not Found" ]
|
2020-03-28 04:09:01 +00:00
|
|
|
|
|
2020-05-08 13:24:58 +00:00
|
|
|
|
Home _ ->
|
|
|
|
|
div [] [ text "Welcome" ]
|
2020-03-28 04:09:01 +00:00
|
|
|
|
|
2020-05-08 13:24:58 +00:00
|
|
|
|
Packages packagesModel ->
|
|
|
|
|
Html.map (\m -> PackagesMsg m) <| Page.Packages.view packagesModel
|
2020-04-10 08:13:50 +00:00
|
|
|
|
|
2020-05-08 13:24:58 +00:00
|
|
|
|
Options optionsModel ->
|
|
|
|
|
Html.map (\m -> OptionsMsg m) <| Page.Options.view optionsModel
|
2020-04-07 05:05:50 +00:00
|
|
|
|
|
2020-03-31 03:22:27 +00:00
|
|
|
|
|
2020-05-08 13:24:58 +00:00
|
|
|
|
|
|
|
|
|
-- SUBSCRIPTIONS
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
subscriptions : Model -> Sub Msg
|
|
|
|
|
subscriptions _ =
|
|
|
|
|
Sub.none
|
2020-03-28 04:09:01 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-- MAIN
|
|
|
|
|
|
|
|
|
|
|
2020-04-07 05:05:50 +00:00
|
|
|
|
main : Program Flags Model Msg
|
2020-03-28 04:09:01 +00:00
|
|
|
|
main =
|
|
|
|
|
Browser.application
|
|
|
|
|
{ init = init
|
2020-05-08 13:24:58 +00:00
|
|
|
|
, onUrlRequest = ClickedLink
|
|
|
|
|
, onUrlChange = ChangedUrl
|
|
|
|
|
, subscriptions = subscriptions
|
2020-03-28 04:09:01 +00:00
|
|
|
|
, update = update
|
2020-06-12 10:20:28 +00:00
|
|
|
|
, view = view
|
2020-03-28 04:09:01 +00:00
|
|
|
|
}
|