diff --git a/Dockerfile b/Dockerfile index 3479e19..65e4781 100644 --- a/Dockerfile +++ b/Dockerfile @@ -5,13 +5,13 @@ WORKDIR /app ENV NPM_CONFIG_PREFIX=/home/node/.npm-global -RUN wget "https://github.com/elm/compiler/releases/download/0.19.0/binaries-for-linux.tar.gz" && \ - tar xzf binaries-for-linux.tar.gz && \ - mv elm /usr/local/bin/ +RUN wget "https://github.com/elm/compiler/releases/download/0.19.1/binary-for-linux-64-bit.gz" && \ + gunzip binary-for-linux-64-bit.gz && \ + mv binary-for-linux-64-bit /usr/local/bin/elm USER node -RUN mkdir ~/.npm-global && npm install -g elm@latest-0.19.0 +RUN mkdir ~/.npm-global && npm install -g elm@latest-0.19.1 ENV PATH="/home/node/.npm-global/bin:${PATH}" RUN npm install -g uglify-js diff --git a/dist.sh b/dist.sh index 5eb71c7..bc9a885 100755 --- a/dist.sh +++ b/dist.sh @@ -13,7 +13,7 @@ rm -rf /app/dist/* # compile and minify the Elm application bundle cd /app && elm make src/Main.elm --output=/app/optimized.js --optimize -uglifyjs optimized.js --compress 'pure_funcs="F2,F3,F4,F5,F6,F7,F8,F9,A2,A3,A4,A5,A6,A7,A8,A9",pure_getters,keep_fargs=false,unsafe_comps,unsafe' | uglifyjs --mangle --output /app/dist/elm.js +uglifyjs /app/optimized.js --compress 'pure_funcs="F2,F3,F4,F5,F6,F7,F8,F9,A2,A3,A4,A5,A6,A7,A8,A9",pure_getters,keep_fargs=false,unsafe_comps,unsafe' | uglifyjs --mangle --output /app/dist/elm.js # copy over other static assets cp -r assets dist/assets diff --git a/elm.json b/elm.json index 4216aee..e135775 100644 --- a/elm.json +++ b/elm.json @@ -3,7 +3,7 @@ "source-directories": [ "src" ], - "elm-version": "0.19.0", + "elm-version": "0.19.1", "dependencies": { "direct": { "NoRedInk/elm-json-decode-pipeline": "1.0.0", @@ -17,6 +17,7 @@ "elm/url": "1.0.0", "elm-community/list-extra": "8.0.0", "elm-explorations/markdown": "1.0.0", + "mcordova47/elm-natural-ordering": "1.0.5", "rtfeldman/elm-css": "16.1.0", "rtfeldman/elm-iso8601-date-strings": "1.0.0" }, @@ -24,8 +25,10 @@ "Janiczek/cmd-extra": "1.0.0", "billstclair/elm-port-funnel": "1.0.2", "elm/parser": "1.0.0", + "elm/regex": "1.0.0", "elm/virtual-dom": "1.0.0", "elm-community/dict-extra": "2.3.1", + "kuon/elm-string-normalize": "1.0.2", "rtfeldman/elm-hex": "1.0.0" } }, diff --git a/src/Data/Package.elm b/src/Data/Package.elm index 2394404..724550a 100644 --- a/src/Data/Package.elm +++ b/src/Data/Package.elm @@ -1,4 +1,4 @@ -module Data.Package exposing (BuildStatus(..), Package, buildStatusDecoder, packageDecoder, packagesDecoder, retrievePackages) +module Data.Package exposing (BuildStatus(..), Package, sortPackages, buildStatusDecoder, packageDecoder, packagesDecoder, retrievePackages) import Data.Guid exposing (Guid, decoder) import Data.ResourceId exposing (ResourceId, decoder) @@ -6,11 +6,13 @@ import Html exposing (..) import Http import Json.Decode exposing (Decoder, fail, float, int, list, nullable, string, succeed, bool) import Json.Decode.Pipeline exposing (hardcoded, optional, required) - +import NaturalOrdering +import Array type BuildStatus = Ready | Building + | Failed | Processing @@ -25,6 +27,59 @@ type alias Package = , buildStatus : BuildStatus } +type alias Version = + { a: Int + , b: Int + , c: Int + } + + +safeGet index arr = + case Array.get index arr of + Just v + -> Maybe.withDefault 0 (String.toInt v) + Nothing + -> 0 + +parseVersion : String -> Version +parseVersion v = + let + parts = String.split v "." |> Array.fromList + in + Version (safeGet 0 parts) (safeGet 1 parts) (safeGet 2 parts) + +compareVersion : Version -> Version -> Order +compareVersion a b = + case compare a.a b.a of + EQ -> + case compare a.b b.b of + EQ -> + compare a.c b.c + LT -> + LT + GT -> + GT + LT -> + LT + GT -> + GT + +packageCompare : Package -> Package -> Order +packageCompare a b = + case NaturalOrdering.compare a.title b.title of + EQ -> + let + v1 = parseVersion a.version + v2 = parseVersion b.version + in + compareVersion v1 v2 + + LT -> LT + GT -> GT + +sortPackages : (List Package) -> (List Package) +sortPackages packages = + List.sortWith packageCompare packages retrievePackages token baseUrl = let @@ -65,6 +120,9 @@ buildStatusDecoder = "READY" -> succeed Ready + "FAILED" -> + succeed Failed + "BUILDING" -> succeed Building diff --git a/src/Page.elm b/src/Page.elm index e9b6e9a..90856a2 100644 --- a/src/Page.elm +++ b/src/Page.elm @@ -44,12 +44,12 @@ view page { title, content } context = let body = toUnstyled - (div [ class "layout" ] + (Html.Styled.div [ class "layout" ] [ viewMenuToggle , viewMenu page context - , div [ class "main" ] - [ div [ class "header" ] [ h3 [] [ text title ] ] - , div [ class "content" ] [ content ] + , Html.Styled.div [ class "main" ] + [ Html.Styled.div [ class "header" ] [ Html.Styled.h3 [] [ Html.Styled.text title ] ] + , Html.Styled.div [ class "content" ] [ content ] ] ] ) @@ -61,7 +61,7 @@ view page { title, content } context = viewMenuToggle : Html msg viewMenuToggle = - a [ href "#menu", class "menuLink", class "menu-link" ] [ span [] [] ] + Html.Styled.a [ href "#menu", class "menuLink", class "menu-link" ] [ Html.Styled.span [] [] ] menuStyle themeType theme = @@ -100,14 +100,14 @@ viewMenu page context = linkTo = navbarLink page context.theme in - div [ class "menu ", tcss context.theme menuStyle ] - [ div [ class "pure-menu", tcss context.theme pureMenuStyle ] - [ a [ class "pure-menu-heading", href "#" ] [ text "Admin " ] - , ul [ class "pure-menu-list " ] - [ linkTo Route.Home [ text "Home" ] - , linkTo Route.Packages [ text "Packages" ] - , linkTo Route.UserSessions [ text "Sessions" ] - , linkTo Route.Users [ text "Users " ] + Html.Styled.div [ class "menu ", tcss context.theme menuStyle ] + [ Html.Styled.div [ class "pure-menu", tcss context.theme pureMenuStyle ] + [ Html.Styled.a [ class "pure-menu-heading", href "#" ] [ Html.Styled.text "Admin " ] + , Html.Styled.ul [ class "pure-menu-list " ] + [ linkTo Route.Home [ Html.Styled.text "Home" ] + , linkTo Route.Packages [ Html.Styled.text "Packages" ] + , linkTo Route.UserSessions [ Html.Styled.text "Sessions" ] + , linkTo Route.Users [ Html.Styled.text "Users " ] ] ] @@ -118,8 +118,8 @@ viewMenu page context = navbarLink : Page -> Theme.Theme -> Route -> List (Html msg) -> Html msg navbarLink page theme route linkContent = - li [ classList [ ( "pure-menu-item", True ), ( "pure-menu-selected", isActive page route ) ] ] - [ a [ class "pure-menu-link", Route.href route ] linkContent ] + Html.Styled.li [ classList [ ( "pure-menu-item", True ), ( "pure-menu-selected", isActive page route ) ] ] + [ Html.Styled.a [ class "pure-menu-link", Route.href route ] linkContent ] diff --git a/src/Page/PackageDetails.elm b/src/Page/PackageDetails.elm index 64e52ce..d28a48d 100644 --- a/src/Page/PackageDetails.elm +++ b/src/Page/PackageDetails.elm @@ -179,7 +179,7 @@ viewDetails details model = , button [ class "pure-button pure-button-primary" , css [ marginRight (px 10) ] - , disabled (model.clonePackageId == "" && model.cloneStatus /= ClonePending) + , Html.Styled.Attributes.disabled (model.clonePackageId == "" && model.cloneStatus /= ClonePending) ] [ text "Clone" ] ] diff --git a/src/Page/Packages.elm b/src/Page/Packages.elm index 264a318..019ecdd 100644 --- a/src/Page/Packages.elm +++ b/src/Page/Packages.elm @@ -2,7 +2,7 @@ module Page.Packages exposing (Model, Msg, init, subscriptions, toContext, updat import AppContext exposing (AppContext) import Browser.Navigation as Nav -import Data.Package as Package exposing (Package, retrievePackages) +import Data.Package as Package exposing (Package, retrievePackages, sortPackages) import Data.ResourceId exposing (ResourceId) import Data.Username as Username exposing (Username) import Html.Styled exposing (Html, a, button, div, span, form, fieldset, h1, input, li, text, b, textarea, toUnstyled, ul) @@ -165,7 +165,7 @@ update : Msg -> Model -> ( Model, Cmd Msg ) update msg model = case msg of RetrievedPackages (Ok packages) -> - ( { model | status = Loaded packages } + ( { model | status = Loaded (Package.sortPackages packages) } , Cmd.none ) diff --git a/src/Page/UserSessions.elm b/src/Page/UserSessions.elm index 2e4b532..2fae8a4 100644 --- a/src/Page/UserSessions.elm +++ b/src/Page/UserSessions.elm @@ -167,7 +167,7 @@ viewSessions userSessions = ) userSessions in - table [ class "pure-table" ] + Html.Styled.table [ class "pure-table" ] [ thead [] [ tr [] [ th [] [ text "Username" ]