Merge pull request 'Homepage re-jig' (#32) from filter-rejig into main
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
Reviewed-on: #32
This commit is contained in:
commit
41ccf212a9
1
elm.json
1
elm.json
|
@ -16,6 +16,7 @@
|
||||||
"elm/url": "1.0.0",
|
"elm/url": "1.0.0",
|
||||||
"elm-community/json-extra": "4.3.0",
|
"elm-community/json-extra": "4.3.0",
|
||||||
"elm-community/string-extra": "4.0.1",
|
"elm-community/string-extra": "4.0.1",
|
||||||
|
"fapian/elm-html-aria": "1.4.0",
|
||||||
"pablohirafuji/elm-markdown": "2.0.5"
|
"pablohirafuji/elm-markdown": "2.0.5"
|
||||||
},
|
},
|
||||||
"indirect": {
|
"indirect": {
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -30,6 +30,6 @@
|
||||||
"npm-run-all": "4.1.5"
|
"npm-run-all": "4.1.5"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"elm-format": "^0.8.5"
|
"elm-format": "^0.8.6"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,27 @@ i.fas, i.fab {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Categories */
|
/* Filtering */
|
||||||
|
|
||||||
|
#filter {
|
||||||
|
position: fixed;
|
||||||
|
left: 0;
|
||||||
|
background-color: var(--light-blue);
|
||||||
|
padding-top: 1rem;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#filter > form > div {
|
||||||
|
margin: 1rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#filter h3 {
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#filter label {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
.category-tile {
|
.category-tile {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
@ -41,6 +61,12 @@ i.fas, i.fab {
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Intro */
|
||||||
|
|
||||||
|
.card#intro {
|
||||||
|
margin: 1em 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Cards */
|
/* Cards */
|
||||||
|
|
||||||
.app-category {
|
.app-category {
|
||||||
|
@ -100,31 +126,6 @@ i.fas, i.fab {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Search bar*/
|
|
||||||
|
|
||||||
.search-bar-container {
|
|
||||||
margin: 2em;
|
|
||||||
display: flex;
|
|
||||||
flex-flow: row wrap;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.search-bar-input, .search-dropdown {
|
|
||||||
margin: 0.5em;
|
|
||||||
height: calc(1.5em + .75rem + 2px);
|
|
||||||
background-color: var(--white);
|
|
||||||
border: 1px solid var(--dark-pink);
|
|
||||||
border-radius: .5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.search-bar-input {
|
|
||||||
width: 30rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.search-dropdown {
|
|
||||||
width: 10rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Navbar */
|
/* Navbar */
|
||||||
.navbar-text {
|
.navbar-text {
|
||||||
color: var(--dark-blue);
|
color: var(--dark-blue);
|
||||||
|
@ -146,3 +147,10 @@ i.fas, i.fab {
|
||||||
.card-body p {
|
.card-body p {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
#filter {
|
||||||
|
width: 100%;
|
||||||
|
position: relative;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
|
@ -272,9 +272,9 @@ viewApp app readme =
|
||||||
]
|
]
|
||||||
, div [ class "card-footer" ]
|
, div [ class "card-footer" ]
|
||||||
[ h5 [] [ text "Versions" ]
|
[ h5 [] [ text "Versions" ]
|
||||||
, ul [] (
|
, ul []
|
||||||
List.map (\version -> li [] [ text (version) ]) app.versions
|
(List.map (\version -> li [] [ text version ]) app.versions)
|
||||||
)]
|
]
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -319,8 +319,6 @@ featuresDecoder =
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
versionsDecoder : Decode.Decoder (List String)
|
versionsDecoder : Decode.Decoder (List String)
|
||||||
versionsDecoder =
|
versionsDecoder =
|
||||||
Decode.list (Decode.keyValuePairs Decode.value)
|
Decode.list (Decode.keyValuePairs Decode.value)
|
||||||
|
@ -332,7 +330,6 @@ buildVersions versions =
|
||||||
List.concatMap (List.map (\( version, _ ) -> version)) versions
|
List.concatMap (List.map (\( version, _ ) -> version)) versions
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
appDecoder : Decode.Decoder App
|
appDecoder : Decode.Decoder App
|
||||||
appDecoder =
|
appDecoder =
|
||||||
Decode.succeed App
|
Decode.succeed App
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
module Pages.Top exposing (Model, Msg, Params, page)
|
module Pages.Top exposing (Model, Msg, Params, page)
|
||||||
|
|
||||||
import Enum exposing (Enum)
|
import Enum exposing (Enum)
|
||||||
import Html exposing (Html, a, button, div, h2, h5, i, img, li, p, span, text, ul, form, label, select, option, input)
|
import Html exposing (Html, a, button, div, form, h2, h3, h5, i, img, input, label, li, option, p, select, span, text, ul)
|
||||||
import Html.Attributes exposing (alt, class, href, src, style, id, for, value)
|
import Html.Attributes exposing (alt, class, for, href, id, src, style, value)
|
||||||
|
import Html.Attributes.Aria exposing (ariaLabel)
|
||||||
import Html.Events exposing (onClick, onInput)
|
import Html.Events exposing (onClick, onInput)
|
||||||
import Http
|
import Http
|
||||||
import Json.Decode as Decode
|
import Json.Decode as Decode
|
||||||
|
@ -26,6 +27,7 @@ page =
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-- INIT
|
-- INIT
|
||||||
|
|
||||||
|
|
||||||
|
@ -52,8 +54,8 @@ type alias Model =
|
||||||
, filter_category : Maybe Category
|
, filter_category : Maybe Category
|
||||||
, filter_text : Maybe String
|
, filter_text : Maybe String
|
||||||
, status : Status
|
, status : Status
|
||||||
, apps : (List App)
|
, apps : List App
|
||||||
, results : (List App)
|
, results : List App
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -77,11 +79,10 @@ categories =
|
||||||
[ ( "Apps", Apps )
|
[ ( "Apps", Apps )
|
||||||
, ( "Utilities", Utilities )
|
, ( "Utilities", Utilities )
|
||||||
, ( "Development", Development )
|
, ( "Development", Development )
|
||||||
, ("All", All)
|
, ( "All", All )
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
init : Url Params -> ( Model, Cmd Msg )
|
init : Url Params -> ( Model, Cmd Msg )
|
||||||
init { params } =
|
init { params } =
|
||||||
( default_model, loadApps )
|
( default_model, loadApps )
|
||||||
|
@ -94,8 +95,14 @@ default_image =
|
||||||
|
|
||||||
default_model : Model
|
default_model : Model
|
||||||
default_model =
|
default_model =
|
||||||
{ filter_score = Nothing, filter_category = Nothing, filter_text = Nothing,
|
{ filter_score = Nothing
|
||||||
status = Loading, apps = [], results = [] }
|
, filter_category = Nothing
|
||||||
|
, filter_text = Nothing
|
||||||
|
, status = Loading
|
||||||
|
, apps = []
|
||||||
|
, results = []
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-- UPDATE
|
-- UPDATE
|
||||||
|
@ -113,41 +120,55 @@ filterAppsScore : List App -> Maybe Int -> List App
|
||||||
filterAppsScore apps score =
|
filterAppsScore apps score =
|
||||||
case score of
|
case score of
|
||||||
Just s ->
|
Just s ->
|
||||||
List.filter (\app ->
|
List.filter
|
||||||
|
(\app ->
|
||||||
app.status >= s
|
app.status >= s
|
||||||
) apps
|
)
|
||||||
|
apps
|
||||||
|
|
||||||
Nothing ->
|
Nothing ->
|
||||||
apps
|
apps
|
||||||
|
|
||||||
|
|
||||||
filterAppsCategory : List App -> Maybe Category -> List App
|
filterAppsCategory : List App -> Maybe Category -> List App
|
||||||
filterAppsCategory apps category =
|
filterAppsCategory apps category =
|
||||||
case category of
|
case category of
|
||||||
Just c ->
|
Just c ->
|
||||||
if c == All then
|
if c == All then
|
||||||
apps
|
apps
|
||||||
|
|
||||||
else
|
else
|
||||||
List.filter (\app ->
|
List.filter
|
||||||
app.category == categories.toString c
|
(\app ->
|
||||||
) apps
|
app.category == categories.toString c
|
||||||
|
)
|
||||||
|
apps
|
||||||
|
|
||||||
Nothing ->
|
Nothing ->
|
||||||
apps
|
apps
|
||||||
|
|
||||||
|
|
||||||
filterAppsText : List App -> Maybe String -> List App
|
filterAppsText : List App -> Maybe String -> List App
|
||||||
filterAppsText apps text =
|
filterAppsText apps text =
|
||||||
case text of
|
case text of
|
||||||
Just "" ->
|
Just "" ->
|
||||||
apps
|
apps
|
||||||
|
|
||||||
Just t ->
|
Just t ->
|
||||||
List.filter (\app ->
|
List.filter
|
||||||
String.contains (String.toLower t) (
|
(\app ->
|
||||||
String.toLower app.name ++ String.toLower (
|
String.contains (String.toLower t)
|
||||||
Maybe.withDefault "" app.description
|
(String.toLower app.name
|
||||||
)
|
++ String.toLower
|
||||||
|
(Maybe.withDefault "" app.description)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
) apps
|
apps
|
||||||
|
|
||||||
Nothing ->
|
Nothing ->
|
||||||
apps
|
apps
|
||||||
|
|
||||||
|
|
||||||
update : Msg -> Model -> ( Model, Cmd Msg )
|
update : Msg -> Model -> ( Model, Cmd Msg )
|
||||||
update msg model =
|
update msg model =
|
||||||
case msg of
|
case msg of
|
||||||
|
@ -156,51 +177,71 @@ update msg model =
|
||||||
|
|
||||||
FilterScore filter ->
|
FilterScore filter ->
|
||||||
let
|
let
|
||||||
filter_score = String.toInt filter
|
filter_score =
|
||||||
|
String.toInt filter
|
||||||
in
|
in
|
||||||
( { model
|
( { model
|
||||||
| filter_score = filter_score
|
| filter_score = filter_score
|
||||||
, results = filterAppsScore (
|
, results =
|
||||||
filterAppsCategory (
|
filterAppsScore
|
||||||
filterAppsText model.apps model.filter_text
|
(filterAppsCategory
|
||||||
) model.filter_category
|
(filterAppsText model.apps model.filter_text)
|
||||||
) (String.toInt filter)
|
model.filter_category
|
||||||
}, Cmd.none )
|
)
|
||||||
|
(String.toInt filter)
|
||||||
|
}
|
||||||
|
, Cmd.none
|
||||||
|
)
|
||||||
|
|
||||||
FilterCategory filter ->
|
FilterCategory filter ->
|
||||||
let
|
let
|
||||||
category = categories.fromString filter
|
category =
|
||||||
|
categories.fromString filter
|
||||||
in
|
in
|
||||||
( { model
|
( { model
|
||||||
| filter_category = category
|
| filter_category = category
|
||||||
, results = filterAppsCategory (
|
, results =
|
||||||
filterAppsScore (
|
filterAppsCategory
|
||||||
filterAppsText model.apps model.filter_text
|
(filterAppsScore
|
||||||
)model.filter_score
|
(filterAppsText model.apps model.filter_text)
|
||||||
) category
|
model.filter_score
|
||||||
}, Cmd.none )
|
)
|
||||||
|
category
|
||||||
|
}
|
||||||
|
, Cmd.none
|
||||||
|
)
|
||||||
|
|
||||||
FilterText filter ->
|
FilterText filter ->
|
||||||
( { model
|
( { model
|
||||||
| filter_text = Just filter
|
| filter_text = Just filter
|
||||||
, results = filterAppsText (
|
, results =
|
||||||
filterAppsScore (
|
filterAppsText
|
||||||
filterAppsCategory model.apps model.filter_category
|
(filterAppsScore
|
||||||
) model.filter_score
|
(filterAppsCategory model.apps model.filter_category)
|
||||||
) (Just filter)
|
model.filter_score
|
||||||
}, Cmd.none )
|
)
|
||||||
|
(Just filter)
|
||||||
|
}
|
||||||
|
, Cmd.none
|
||||||
|
)
|
||||||
|
|
||||||
GotApps result ->
|
GotApps result ->
|
||||||
case result of
|
case result of
|
||||||
Ok apps ->
|
Ok apps ->
|
||||||
( { default_model
|
( { default_model
|
||||||
| status = Success
|
| status = Success
|
||||||
, apps = apps
|
, apps = apps
|
||||||
, results = apps }, Cmd.none )
|
, results = apps
|
||||||
|
}
|
||||||
|
, Cmd.none
|
||||||
|
)
|
||||||
|
|
||||||
Err _ ->
|
Err _ ->
|
||||||
( { default_model
|
( { default_model
|
||||||
| status = Failure}, Cmd.none )
|
| status = Failure
|
||||||
|
}
|
||||||
|
, Cmd.none
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
subscriptions : Model -> Sub Msg
|
subscriptions : Model -> Sub Msg
|
||||||
|
@ -221,7 +262,7 @@ view model =
|
||||||
|
|
||||||
body : Model -> Html Msg
|
body : Model -> Html Msg
|
||||||
body model =
|
body model =
|
||||||
div [ class "pt-3" ]
|
div []
|
||||||
[ viewApps model
|
[ viewApps model
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -247,7 +288,7 @@ viewStatusBadge app =
|
||||||
"badge-dark"
|
"badge-dark"
|
||||||
in
|
in
|
||||||
span [ class ("card-link badge " ++ status_class) ]
|
span [ class ("card-link badge " ++ status_class) ]
|
||||||
[ text ("Status: " ++ String.fromInt app.status) ]
|
[ text ("Score: " ++ String.fromInt app.status) ]
|
||||||
|
|
||||||
|
|
||||||
viewApp : App -> Html Msg
|
viewApp : App -> Html Msg
|
||||||
|
@ -303,16 +344,14 @@ viewApp app =
|
||||||
, p [ class "card-description" ] [ text (ellipsis 100 (withDefault "" app.description)) ]
|
, p [ class "card-description" ] [ text (ellipsis 100 (withDefault "" app.description)) ]
|
||||||
]
|
]
|
||||||
, div [ class "footer" ]
|
, div [ class "footer" ]
|
||||||
[ viewStatusBadge app, span [ class "badge app-category" ] [ text app.category ]]
|
[ viewStatusBadge app, span [ class "badge app-category" ] [ text app.category ] ]
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
viewCategories : ( String, Category ) -> Html Msg
|
||||||
viewCategories : (String, Category) -> Html Msg
|
|
||||||
viewCategories category =
|
viewCategories category =
|
||||||
div [ class "category-tile", onClick (FilterCategory (Tuple.first category)) ] [text (Tuple.first category)]
|
div [ class "category-tile", onClick (FilterCategory (Tuple.first category)) ] [ text (Tuple.first category) ]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
viewApps : Model -> Html Msg
|
viewApps : Model -> Html Msg
|
||||||
|
@ -335,32 +374,52 @@ viewApps model =
|
||||||
|
|
||||||
Success ->
|
Success ->
|
||||||
div [ class "row justify-content-center" ]
|
div [ class "row justify-content-center" ]
|
||||||
[ div [ class "col-md-3" ] [
|
[ div [ class "col-md-3", id "filter" ]
|
||||||
h2 [ class "app-headings" ] [text "Categories"]
|
[ h2 [ class "app-headings" ] [ text "Finding things" ]
|
||||||
, div [] (List.map viewCategories categories.list)
|
, form []
|
||||||
]
|
[ div []
|
||||||
, div [ class "col-md-6" ]
|
[ h3 [] [ text "Categories" ]
|
||||||
[ div [ class "row" ]
|
, div [] (List.map viewCategories categories.list)
|
||||||
[ div [ class "col-sm-12" ] [
|
]
|
||||||
div [] [
|
, div []
|
||||||
form [ class "search-bar-container" ] [
|
[ h3 [] [ text "Search" ]
|
||||||
label [ for "text" ] [ text "Search" ]
|
, input [ ariaLabel "search", id "text", onInput FilterText ] []
|
||||||
, input [ class "search-bar-input", id "text", onInput FilterText ] []
|
]
|
||||||
, label [ for "level" ] [ text " and show only items that have at least " ]
|
, div []
|
||||||
, select [ class "search-dropdown", id "level", onInput FilterScore ] [
|
[ h3 [] [ text "Status" ]
|
||||||
option [ ] [ text "any" ]
|
, label [ for "level" ] [ text "Minimum score:" ]
|
||||||
, option [ value "5" ] [ text "5 (production)" ]
|
, select [ class "search-dropdown", id "level", onInput FilterScore ]
|
||||||
, option [ value "4" ] [ text "4 (beta)" ]
|
[ option [] [ text "any" ]
|
||||||
, option [ value "3" ] [ text "3 (alpha)" ]
|
, option [ value "5" ] [ text "5 (amazing)" ]
|
||||||
, option [ value "2" ] [ text "2 (pre-alpha)" ]
|
, option [ value "4" ] [ text "4 (good)" ]
|
||||||
, option [ value "1" ] [ text "1 (work-in-progress)" ]
|
, option [ value "3" ] [ text "3 (ok)" ]
|
||||||
]
|
, option [ value "2" ] [ text "2 (basic)" ]
|
||||||
, text "builds "
|
, option [ value "1" ] [ text "1 (chaos)" ]
|
||||||
]
|
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
, h2 [ class "app-headings" ] [ text "Apps" ]
|
]
|
||||||
|
, div [ class "col-md-6 offset-md-3" ]
|
||||||
|
[ div [ class "row" ]
|
||||||
|
[ div [ class "col-sm-12" ]
|
||||||
|
[ div []
|
||||||
|
[]
|
||||||
|
]
|
||||||
|
]
|
||||||
|
, div [ id "intro", class "card" ] [ div [ class "card-body" ] [
|
||||||
|
h2 [ class "app-headings card-title" ] [ text "Co-op Cloud Recipe Catalogue" ]
|
||||||
|
, text "You can use these recipes ("
|
||||||
|
, a [ href
|
||||||
|
"https://docs.coopcloud.tech/glossary/#recipe" ] [
|
||||||
|
text "What's a recipe?"
|
||||||
|
]
|
||||||
|
, text ") with "
|
||||||
|
, a [ href "https://coopcloud.tech" ] [
|
||||||
|
text "Co-op Cloud"
|
||||||
|
]
|
||||||
|
, text "."
|
||||||
|
]
|
||||||
|
]
|
||||||
, div [ class "row" ]
|
, div [ class "row" ]
|
||||||
(List.map viewApp
|
(List.map viewApp
|
||||||
(model.results
|
(model.results
|
||||||
|
@ -371,9 +430,11 @@ viewApps model =
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
, div [class "col-md-3"] []
|
, div [ class "col-md-3" ] []
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-- HTTP
|
-- HTTP
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue