From 8ff39745a5b3fb3361edf28ccb8a4df9787d943a Mon Sep 17 00:00:00 2001 From: Kelly Merrick Date: Thu, 25 Apr 2024 12:06:00 -0500 Subject: [PATCH 01/23] feat(dashboard): create scaffolding for a dashboard page --- elm-land.json | 7 +++ src/elm/Main.elm | 52 +++++++++++++++++ src/elm/Main/Pages/Model.elm | 2 + src/elm/Main/Pages/Msg.elm | 2 + src/elm/Pages/Dashboards/Dashboard_.elm | 75 +++++++++++++++++++++++++ src/elm/Route/Path.elm | 10 ++++ 6 files changed, 148 insertions(+) create mode 100644 elm-land.json create mode 100644 src/elm/Pages/Dashboards/Dashboard_.elm diff --git a/elm-land.json b/elm-land.json new file mode 100644 index 000000000..f73c99500 --- /dev/null +++ b/elm-land.json @@ -0,0 +1,7 @@ +{ + "app":{ + "config":{ + "router":{} + } + } +} \ No newline at end of file diff --git a/src/elm/Main.elm b/src/elm/Main.elm index e9543ebc7..cc936ae88 100644 --- a/src/elm/Main.elm +++ b/src/elm/Main.elm @@ -41,6 +41,7 @@ import Pages.Dash.Secrets.Engine_.Repo.Org_.Repo_.Name_ import Pages.Dash.Secrets.Engine_.Shared.Org_.Team_ import Pages.Dash.Secrets.Engine_.Shared.Org_.Team_.Add import Pages.Dash.Secrets.Engine_.Shared.Org_.Team_.Name_ +import Pages.Dashboards.Dashboard_ import Pages.Home_ import Pages.NotFound_ import Pages.Org_ @@ -744,6 +745,26 @@ initPageAndLayout model = } ) + Route.Path.Dashboards_Dashboard_ params -> + let + page : Page.Page Pages.Dashboards.Dashboard_.Model Pages.Dashboards.Dashboard_.Msg + page = + Pages.Dashboards.Dashboard_.page model.shared (Route.fromUrl params model.url) + + ( pageModel, pageEffect ) = + Page.init page () + in + { page = + Tuple.mapBoth + (Main.Pages.Model.Dashboards_Dashboard_ params) + (Effect.map Main.Pages.Msg.Dashboards_Dashboard_ >> fromPageEffect model) + ( pageModel, pageEffect ) + , layout = + Page.layout pageModel page + |> Maybe.map (Layouts.map (Main.Pages.Msg.Dashboards_Dashboard_ >> Page)) + |> Maybe.map (initLayout model) + } + Route.Path.Org_ params -> runWhenAuthenticatedWithLayout model @@ -1502,6 +1523,12 @@ updateFromPage msg model = (Page.update (Pages.Dash.Secrets.Engine_.Shared.Org_.Team_.Name_.page user model.shared (Route.fromUrl params model.url)) pageMsg pageModel) ) + ( Main.Pages.Msg.Dashboards_Dashboard_ pageMsg, Main.Pages.Model.Dashboards_Dashboard_ params pageModel ) -> + Tuple.mapBoth + (Main.Pages.Model.Dashboards_Dashboard_ params) + (Effect.map Main.Pages.Msg.Dashboards_Dashboard_ >> fromPageEffect model) + (Page.update (Pages.Dashboards.Dashboard_.page model.shared (Route.fromUrl params model.url)) pageMsg pageModel) + ( Main.Pages.Msg.Org_ pageMsg, Main.Pages.Model.Org_ params pageModel ) -> runWhenAuthenticated model @@ -1830,6 +1857,12 @@ toLayoutFromPage model = |> Maybe.andThen (Page.layout pageModel) |> Maybe.map (Layouts.map (Main.Pages.Msg.Dash_Secrets_Engine__Shared_Org__Team__Name_ >> Page)) + Main.Pages.Model.Dashboards_Dashboard_ params pageModel -> + Route.fromUrl params model.url + |> Pages.Dashboards.Dashboard_.page model.shared + |> Page.layout pageModel + |> Maybe.map (Layouts.map (Main.Pages.Msg.Dashboards_Dashboard_ >> Page)) + Main.Pages.Model.Org_ params pageModel -> Route.fromUrl params model.url |> toAuthProtectedPage model Pages.Org_.page @@ -2100,6 +2133,11 @@ subscriptions model = ) (Auth.onPageLoad model.shared (Route.fromUrl () model.url)) + Main.Pages.Model.Dashboards_Dashboard_ params pageModel -> + Page.subscriptions (Pages.Dashboards.Dashboard_.page model.shared (Route.fromUrl params model.url)) pageModel + |> Sub.map Main.Pages.Msg.Dashboards_Dashboard_ + |> Sub.map Page + Main.Pages.Model.Org_ params pageModel -> Auth.Action.subscriptions (\user -> @@ -2540,6 +2578,11 @@ viewPage model = ) (Auth.onPageLoad model.shared (Route.fromUrl () model.url)) + Main.Pages.Model.Dashboards_Dashboard_ params pageModel -> + Page.view (Pages.Dashboards.Dashboard_.page model.shared (Route.fromUrl params model.url)) pageModel + |> View.map Main.Pages.Msg.Dashboards_Dashboard_ + |> View.map Page + Main.Pages.Model.Org_ params pageModel -> Auth.Action.view (View.map never (Auth.viewCustomPage model.shared (Route.fromUrl () model.url))) (\user -> @@ -2883,6 +2926,12 @@ toPageUrlHookCmd model routes = ) (Auth.onPageLoad model.shared (Route.fromUrl () model.url)) + Main.Pages.Model.Dashboards_Dashboard_ params pageModel -> + Page.toUrlMessages routes (Pages.Dashboards.Dashboard_.page model.shared (Route.fromUrl params model.url)) + |> List.map Main.Pages.Msg.Dashboards_Dashboard_ + |> List.map Page + |> toCommands + Main.Pages.Model.Org_ params pageModel -> Auth.Action.command (\user -> @@ -3214,6 +3263,9 @@ isAuthProtected routePath = Route.Path.Dash_Secrets_Engine__Shared_Org__Team__Name_ _ -> True + Route.Path.Dashboards_Dashboard_ _ -> + False + Route.Path.Org_ _ -> True diff --git a/src/elm/Main/Pages/Model.elm b/src/elm/Main/Pages/Model.elm index 84eed9ef2..f4794ced2 100644 --- a/src/elm/Main/Pages/Model.elm +++ b/src/elm/Main/Pages/Model.elm @@ -19,6 +19,7 @@ import Pages.Dash.Secrets.Engine_.Repo.Org_.Repo_.Name_ import Pages.Dash.Secrets.Engine_.Shared.Org_.Team_ import Pages.Dash.Secrets.Engine_.Shared.Org_.Team_.Add import Pages.Dash.Secrets.Engine_.Shared.Org_.Team_.Name_ +import Pages.Dashboards.Dashboard_ import Pages.Home_ import Pages.NotFound_ import Pages.Org_ @@ -56,6 +57,7 @@ type Model | Dash_Secrets_Engine__Shared_Org__Team_ { engine : String, org : String, team : String } Pages.Dash.Secrets.Engine_.Shared.Org_.Team_.Model | Dash_Secrets_Engine__Shared_Org__Team__Add { engine : String, org : String, team : String } Pages.Dash.Secrets.Engine_.Shared.Org_.Team_.Add.Model | Dash_Secrets_Engine__Shared_Org__Team__Name_ { engine : String, org : String, team : String, name : String } Pages.Dash.Secrets.Engine_.Shared.Org_.Team_.Name_.Model + | Dashboards_Dashboard_ { dashboard : String } Pages.Dashboards.Dashboard_.Model | Org_ { org : String } Pages.Org_.Model | Org__Builds { org : String } Pages.Org_.Builds.Model | Org__Repo_ { org : String, repo : String } Pages.Org_.Repo_.Model diff --git a/src/elm/Main/Pages/Msg.elm b/src/elm/Main/Pages/Msg.elm index 88a25dfe0..33c64f82d 100644 --- a/src/elm/Main/Pages/Msg.elm +++ b/src/elm/Main/Pages/Msg.elm @@ -19,6 +19,7 @@ import Pages.Dash.Secrets.Engine_.Repo.Org_.Repo_.Name_ import Pages.Dash.Secrets.Engine_.Shared.Org_.Team_ import Pages.Dash.Secrets.Engine_.Shared.Org_.Team_.Add import Pages.Dash.Secrets.Engine_.Shared.Org_.Team_.Name_ +import Pages.Dashboards.Dashboard_ import Pages.Home_ import Pages.NotFound_ import Pages.Org_ @@ -55,6 +56,7 @@ type Msg | Dash_Secrets_Engine__Shared_Org__Team_ Pages.Dash.Secrets.Engine_.Shared.Org_.Team_.Msg | Dash_Secrets_Engine__Shared_Org__Team__Add Pages.Dash.Secrets.Engine_.Shared.Org_.Team_.Add.Msg | Dash_Secrets_Engine__Shared_Org__Team__Name_ Pages.Dash.Secrets.Engine_.Shared.Org_.Team_.Name_.Msg + | Dashboards_Dashboard_ Pages.Dashboards.Dashboard_.Msg | Org_ Pages.Org_.Msg | Org__Builds Pages.Org_.Builds.Msg | Org__Repo_ Pages.Org_.Repo_.Msg diff --git a/src/elm/Pages/Dashboards/Dashboard_.elm b/src/elm/Pages/Dashboards/Dashboard_.elm new file mode 100644 index 000000000..cb5bf4885 --- /dev/null +++ b/src/elm/Pages/Dashboards/Dashboard_.elm @@ -0,0 +1,75 @@ +{-- +SPDX-License-Identifier: Apache-2.0 +--} + + +module Pages.Dashboards.Dashboard_ exposing (Model, Msg, page) + +import Effect exposing (Effect) +import Html +import Page exposing (Page) +import Route exposing (Route) +import Shared +import View exposing (View) + + +page : Shared.Model -> Route { dashboard : String } -> Page Model Msg +page shared route = + Page.new + { init = init + , update = update + , subscriptions = subscriptions + , view = view + } + + + +-- INIT + + +type alias Model = + {} + + +init : () -> ( Model, Effect Msg ) +init () = + ( {} + , Effect.none + ) + + + +-- UPDATE + + +type Msg + = NoOp + + +update : Msg -> Model -> ( Model, Effect Msg ) +update msg model = + case msg of + NoOp -> + ( model + , Effect.none + ) + + + +-- SUBSCRIPTIONS + + +subscriptions : Model -> Sub Msg +subscriptions model = + Sub.none + + + +-- VIEW + + +view : Model -> View Msg +view model = + { title = "Pages.Dashboards.Dashboard_" + , body = [ Html.text "/dashboards/:dashboard" ] + } diff --git a/src/elm/Route/Path.elm b/src/elm/Route/Path.elm index bb5e5fd81..d5145d495 100644 --- a/src/elm/Route/Path.elm +++ b/src/elm/Route/Path.elm @@ -27,6 +27,7 @@ type Path | Dash_Secrets_Engine__Shared_Org__Team_ { engine : String, org : String, team : String } | Dash_Secrets_Engine__Shared_Org__Team__Add { engine : String, org : String, team : String } | Dash_Secrets_Engine__Shared_Org__Team__Name_ { engine : String, org : String, team : String, name : String } + | Dashboards_Dashboard_ { dashboard : String } | Org_ { org : String } | Org__Builds { org : String } | Org__Repo_ { org : String, repo : String } @@ -152,6 +153,12 @@ fromString urlPath = } |> Just + "dashboards" :: dashboard_ :: [] -> + Dashboards_Dashboard_ + { dashboard = dashboard_ + } + |> Just + org_ :: [] -> Org_ { org = org_ @@ -327,6 +334,9 @@ toString path = Dash_Secrets_Engine__Shared_Org__Team__Name_ params -> [ "-", "secrets", params.engine, "shared", params.org, params.team, params.name ] + Dashboards_Dashboard_ params -> + [ "dashboards", params.dashboard ] + Org_ params -> [ params.org ] From bf91d67eb8e4325260b970bb55712a1eaca74886 Mon Sep 17 00:00:00 2001 From: wass3rw3rk <49894298+wass3rw3rk@users.noreply.github.com> Date: Thu, 25 Apr 2024 14:13:47 -0500 Subject: [PATCH 02/23] ensure new route works --- src/elm/Main.elm | 86 +++++++++++++++---------- src/elm/Pages/Dashboards/Dashboard_.elm | 35 +++++++--- 2 files changed, 80 insertions(+), 41 deletions(-) diff --git a/src/elm/Main.elm b/src/elm/Main.elm index cc936ae88..53c4fb743 100644 --- a/src/elm/Main.elm +++ b/src/elm/Main.elm @@ -746,24 +746,28 @@ initPageAndLayout model = ) Route.Path.Dashboards_Dashboard_ params -> - let - page : Page.Page Pages.Dashboards.Dashboard_.Model Pages.Dashboards.Dashboard_.Msg - page = - Pages.Dashboards.Dashboard_.page model.shared (Route.fromUrl params model.url) + runWhenAuthenticatedWithLayout + model + (\user -> + let + page : Page.Page Pages.Dashboards.Dashboard_.Model Pages.Dashboards.Dashboard_.Msg + page = + Pages.Dashboards.Dashboard_.page user model.shared (Route.fromUrl params model.url) - ( pageModel, pageEffect ) = - Page.init page () - in - { page = - Tuple.mapBoth - (Main.Pages.Model.Dashboards_Dashboard_ params) - (Effect.map Main.Pages.Msg.Dashboards_Dashboard_ >> fromPageEffect model) - ( pageModel, pageEffect ) - , layout = - Page.layout pageModel page - |> Maybe.map (Layouts.map (Main.Pages.Msg.Dashboards_Dashboard_ >> Page)) - |> Maybe.map (initLayout model) - } + ( pageModel, pageEffect ) = + Page.init page () + in + { page = + Tuple.mapBoth + (Main.Pages.Model.Dashboards_Dashboard_ params) + (Effect.map Main.Pages.Msg.Dashboards_Dashboard_ >> fromPageEffect model) + ( pageModel, pageEffect ) + , layout = + Page.layout pageModel page + |> Maybe.map (Layouts.map (Main.Pages.Msg.Dashboards_Dashboard_ >> Page)) + |> Maybe.map (initLayout model) + } + ) Route.Path.Org_ params -> runWhenAuthenticatedWithLayout @@ -1524,10 +1528,14 @@ updateFromPage msg model = ) ( Main.Pages.Msg.Dashboards_Dashboard_ pageMsg, Main.Pages.Model.Dashboards_Dashboard_ params pageModel ) -> - Tuple.mapBoth - (Main.Pages.Model.Dashboards_Dashboard_ params) - (Effect.map Main.Pages.Msg.Dashboards_Dashboard_ >> fromPageEffect model) - (Page.update (Pages.Dashboards.Dashboard_.page model.shared (Route.fromUrl params model.url)) pageMsg pageModel) + runWhenAuthenticated + model + (\user -> + Tuple.mapBoth + (Main.Pages.Model.Dashboards_Dashboard_ params) + (Effect.map Main.Pages.Msg.Dashboards_Dashboard_ >> fromPageEffect model) + (Page.update (Pages.Dashboards.Dashboard_.page user model.shared (Route.fromUrl params model.url)) pageMsg pageModel) + ) ( Main.Pages.Msg.Org_ pageMsg, Main.Pages.Model.Org_ params pageModel ) -> runWhenAuthenticated @@ -1859,8 +1867,8 @@ toLayoutFromPage model = Main.Pages.Model.Dashboards_Dashboard_ params pageModel -> Route.fromUrl params model.url - |> Pages.Dashboards.Dashboard_.page model.shared - |> Page.layout pageModel + |> toAuthProtectedPage model Pages.Dashboards.Dashboard_.page + |> Maybe.andThen (Page.layout pageModel) |> Maybe.map (Layouts.map (Main.Pages.Msg.Dashboards_Dashboard_ >> Page)) Main.Pages.Model.Org_ params pageModel -> @@ -2134,9 +2142,13 @@ subscriptions model = (Auth.onPageLoad model.shared (Route.fromUrl () model.url)) Main.Pages.Model.Dashboards_Dashboard_ params pageModel -> - Page.subscriptions (Pages.Dashboards.Dashboard_.page model.shared (Route.fromUrl params model.url)) pageModel - |> Sub.map Main.Pages.Msg.Dashboards_Dashboard_ - |> Sub.map Page + Auth.Action.subscriptions + (\user -> + Page.subscriptions (Pages.Dashboards.Dashboard_.page user model.shared (Route.fromUrl params model.url)) pageModel + |> Sub.map Main.Pages.Msg.Dashboards_Dashboard_ + |> Sub.map Page + ) + (Auth.onPageLoad model.shared (Route.fromUrl () model.url)) Main.Pages.Model.Org_ params pageModel -> Auth.Action.subscriptions @@ -2579,9 +2591,13 @@ viewPage model = (Auth.onPageLoad model.shared (Route.fromUrl () model.url)) Main.Pages.Model.Dashboards_Dashboard_ params pageModel -> - Page.view (Pages.Dashboards.Dashboard_.page model.shared (Route.fromUrl params model.url)) pageModel - |> View.map Main.Pages.Msg.Dashboards_Dashboard_ - |> View.map Page + Auth.Action.view (View.map never (Auth.viewCustomPage model.shared (Route.fromUrl () model.url))) + (\user -> + Page.view (Pages.Dashboards.Dashboard_.page user model.shared (Route.fromUrl params model.url)) pageModel + |> View.map Main.Pages.Msg.Dashboards_Dashboard_ + |> View.map Page + ) + (Auth.onPageLoad model.shared (Route.fromUrl () model.url)) Main.Pages.Model.Org_ params pageModel -> Auth.Action.view (View.map never (Auth.viewCustomPage model.shared (Route.fromUrl () model.url))) @@ -2927,10 +2943,14 @@ toPageUrlHookCmd model routes = (Auth.onPageLoad model.shared (Route.fromUrl () model.url)) Main.Pages.Model.Dashboards_Dashboard_ params pageModel -> - Page.toUrlMessages routes (Pages.Dashboards.Dashboard_.page model.shared (Route.fromUrl params model.url)) - |> List.map Main.Pages.Msg.Dashboards_Dashboard_ - |> List.map Page - |> toCommands + Auth.Action.command + (\user -> + Page.toUrlMessages routes (Pages.Dashboards.Dashboard_.page user model.shared (Route.fromUrl params model.url)) + |> List.map Main.Pages.Msg.Dashboards_Dashboard_ + |> List.map Page + |> toCommands + ) + (Auth.onPageLoad model.shared (Route.fromUrl () model.url)) Main.Pages.Model.Org_ params pageModel -> Auth.Action.command diff --git a/src/elm/Pages/Dashboards/Dashboard_.elm b/src/elm/Pages/Dashboards/Dashboard_.elm index cb5bf4885..a8c7ea2cc 100644 --- a/src/elm/Pages/Dashboards/Dashboard_.elm +++ b/src/elm/Pages/Dashboards/Dashboard_.elm @@ -5,21 +5,40 @@ SPDX-License-Identifier: Apache-2.0 module Pages.Dashboards.Dashboard_ exposing (Model, Msg, page) +import Auth import Effect exposing (Effect) import Html +import Layouts import Page exposing (Page) import Route exposing (Route) import Shared import View exposing (View) -page : Shared.Model -> Route { dashboard : String } -> Page Model Msg -page shared route = +page : Auth.User -> Shared.Model -> Route { dashboard : String } -> Page Model Msg +page user shared route = Page.new - { init = init + { init = init shared , update = update , subscriptions = subscriptions - , view = view + , view = view shared route + } + |> Page.withLayout (toLayout user) + + + +-- LAYOUT + + +toLayout : Auth.User -> Model -> Layouts.Layout Msg +toLayout user model = + Layouts.Default + { helpCommands = + [ { name = "" + , content = "resources on this page not yet supported via the CLI" + , docs = Nothing + } + ] } @@ -31,8 +50,8 @@ type alias Model = {} -init : () -> ( Model, Effect Msg ) -init () = +init : Shared.Model -> () -> ( Model, Effect Msg ) +init shared () = ( {} , Effect.none ) @@ -68,8 +87,8 @@ subscriptions model = -- VIEW -view : Model -> View Msg -view model = +view : Shared.Model -> Route { dashboard : String } -> Model -> View Msg +view shared route model = { title = "Pages.Dashboards.Dashboard_" , body = [ Html.text "/dashboards/:dashboard" ] } From fdc97e39a8e9e0c8e709a99b4b8c244feb16b64e Mon Sep 17 00:00:00 2001 From: Kelly Merrick Date: Fri, 26 Apr 2024 10:10:13 -0500 Subject: [PATCH 03/23] feat(dashboard): ensure route is protected --- src/elm/Main.elm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/elm/Main.elm b/src/elm/Main.elm index 53c4fb743..ddc2b608a 100644 --- a/src/elm/Main.elm +++ b/src/elm/Main.elm @@ -3284,7 +3284,7 @@ isAuthProtected routePath = True Route.Path.Dashboards_Dashboard_ _ -> - False + True Route.Path.Org_ _ -> True From 1bcaa013e77e1eb78adff4fe897eaa8cc92c3dfd Mon Sep 17 00:00:00 2001 From: Kelly Merrick Date: Fri, 26 Apr 2024 16:21:49 -0500 Subject: [PATCH 04/23] feat(dashboard): renders unformatted dashboard and repo cards --- src/elm/Api/Endpoint.elm | 4 + src/elm/Api/Operations.elm | 13 +++ src/elm/Components/DashboardRepoCard.elm | 20 +++++ src/elm/Effect.elm | 20 ++++- src/elm/Main/Pages/Model.elm | 2 +- src/elm/Pages/Dashboards/Dashboard_.elm | 109 ++++++++++++++++++++--- src/elm/Route/Path.elm | 6 +- src/elm/Vela.elm | 98 ++++++++++++++++++++ 8 files changed, 255 insertions(+), 17 deletions(-) create mode 100644 src/elm/Components/DashboardRepoCard.elm diff --git a/src/elm/Api/Endpoint.elm b/src/elm/Api/Endpoint.elm index a72ce8b12..ec4bf2067 100644 --- a/src/elm/Api/Endpoint.elm +++ b/src/elm/Api/Endpoint.elm @@ -25,6 +25,7 @@ type Endpoint | Login | Logout | CurrentUser + | Dashboard String | Deployment Vela.Org Vela.Repo (Maybe String) | Deployments (Maybe Pagination.Page) (Maybe Pagination.PerPage) Vela.Org Vela.Repo | Token @@ -161,6 +162,9 @@ toUrl api endpoint = Deployments maybePage maybePerPage org repo -> url api [ "deployments", org, repo ] <| Pagination.toQueryParams maybePage maybePerPage + Dashboard dashboardId -> + url api [ "dashboards", dashboardId ] [] + {-| url : creates a URL string with the given path segments and query parameters -} diff --git a/src/elm/Api/Operations.elm b/src/elm/Api/Operations.elm index 48bfbcbec..b4fc68aba 100644 --- a/src/elm/Api/Operations.elm +++ b/src/elm/Api/Operations.elm @@ -27,6 +27,7 @@ module Api.Operations exposing , getBuildStepLog , getBuildSteps , getCurrentUser + , getDashboard , getOrgBuilds , getOrgRepos , getOrgSecret @@ -1198,3 +1199,15 @@ deleteSharedSecret baseUrl session options = ) Json.Decode.string |> withAuth session + + +{-| getDashboard : retrieve a dashboard. +-} +getDashboard : String -> Session -> { a | dashboardId : String } -> Request Vela.Dashboard +getDashboard baseUrl session options = + get baseUrl + (Api.Endpoint.Dashboard + options.dashboardId + ) + Vela.decodeDashboard + |> withAuth session diff --git a/src/elm/Components/DashboardRepoCard.elm b/src/elm/Components/DashboardRepoCard.elm new file mode 100644 index 000000000..e104c414b --- /dev/null +++ b/src/elm/Components/DashboardRepoCard.elm @@ -0,0 +1,20 @@ +{-- +SPDX-License-Identifier: Apache-2.0 +--} + + +module Components.DashboardRepoCard exposing (view) + +import Html exposing (Html, div, text) +import Shared +import Vela + + +type alias Props = + { card : Vela.DashboardRepoCard + } + + +view : Shared.Model -> Props -> Html msg +view shared props = + div [] [ text <| "Future " ++ props.card.org ++ "/" ++ props.card.name ++ " card" ] diff --git a/src/elm/Effect.elm b/src/elm/Effect.elm index fb29c2363..2a888a5ab 100644 --- a/src/elm/Effect.elm +++ b/src/elm/Effect.elm @@ -9,7 +9,7 @@ module Effect exposing , sendCmd, sendMsg , pushRoute, replaceRoute, loadExternalUrl , map, toCmd - , addAlertError, addAlertSuccess, addDeployment, addFavorites, addOrgSecret, addRepoSchedule, addRepoSecret, addSharedSecret, alertsUpdate, approveBuild, cancelBuild, chownRepo, clearRedirect, deleteOrgSecret, deleteRepoSchedule, deleteRepoSecret, deleteSharedSecret, disableRepo, downloadFile, enableRepo, expandPipelineConfig, finishAuthentication, focusOn, getBuild, getBuildGraph, getBuildServiceLog, getBuildServices, getBuildStepLog, getBuildSteps, getCurrentUser, getOrgBuilds, getOrgRepos, getOrgSecret, getOrgSecrets, getPipelineConfig, getPipelineTemplates, getRepo, getRepoBuilds, getRepoBuildsShared, getRepoDeployments, getRepoHooks, getRepoHooksShared, getRepoSchedule, getRepoSchedules, getRepoSecret, getRepoSecrets, getSharedSecret, getSharedSecrets, handleHttpError, logout, pushPath, redeliverHook, repairRepo, replacePath, replaceRouteRemoveTabHistorySkipDomFocus, restartBuild, setRedirect, setTheme, updateFavicon, updateFavorite, updateOrgSecret, updateRepo, updateRepoSchedule, updateRepoSecret, updateSharedSecret, updateSourceReposShared + , addAlertError, addAlertSuccess, addDeployment, addFavorites, addOrgSecret, addRepoSchedule, addRepoSecret, addSharedSecret, alertsUpdate, approveBuild, cancelBuild, chownRepo, clearRedirect, deleteOrgSecret, deleteRepoSchedule, deleteRepoSecret, deleteSharedSecret, disableRepo, downloadFile, enableRepo, expandPipelineConfig, finishAuthentication, focusOn, getBuild, getBuildGraph, getBuildServiceLog, getBuildServices, getBuildStepLog, getBuildSteps, getCurrentUser, getDashboard, getOrgBuilds, getOrgRepos, getOrgSecret, getOrgSecrets, getPipelineConfig, getPipelineTemplates, getRepo, getRepoBuilds, getRepoBuildsShared, getRepoDeployments, getRepoHooks, getRepoHooksShared, getRepoSchedule, getRepoSchedules, getRepoSecret, getRepoSecrets, getSharedSecret, getSharedSecrets, handleHttpError, logout, pushPath, redeliverHook, repairRepo, replacePath, replaceRouteRemoveTabHistorySkipDomFocus, restartBuild, setRedirect, setTheme, updateFavicon, updateFavorite, updateOrgSecret, updateRepo, updateRepoSchedule, updateRepoSecret, updateSharedSecret, updateSourceReposShared ) {-| @@ -1251,3 +1251,21 @@ replaceRouteRemoveTabHistorySkipDomFocus route = else none + + +getDashboard : + { baseUrl : String + , session : Auth.Session.Session + , onResponse : Result (Http.Detailed.Error String) ( Http.Metadata, Vela.Dashboard ) -> msg + , dashboardId : String + } + -> Effect msg +getDashboard options = + Api.try + options.onResponse + (Api.Operations.getDashboard + options.baseUrl + options.session + options + ) + |> sendCmd diff --git a/src/elm/Main/Pages/Model.elm b/src/elm/Main/Pages/Model.elm index f4794ced2..7006b9bc7 100644 --- a/src/elm/Main/Pages/Model.elm +++ b/src/elm/Main/Pages/Model.elm @@ -57,7 +57,7 @@ type Model | Dash_Secrets_Engine__Shared_Org__Team_ { engine : String, org : String, team : String } Pages.Dash.Secrets.Engine_.Shared.Org_.Team_.Model | Dash_Secrets_Engine__Shared_Org__Team__Add { engine : String, org : String, team : String } Pages.Dash.Secrets.Engine_.Shared.Org_.Team_.Add.Model | Dash_Secrets_Engine__Shared_Org__Team__Name_ { engine : String, org : String, team : String, name : String } Pages.Dash.Secrets.Engine_.Shared.Org_.Team_.Name_.Model - | Dashboards_Dashboard_ { dashboard : String } Pages.Dashboards.Dashboard_.Model + | Dashboards_Dashboard_ { dashboardId : String } Pages.Dashboards.Dashboard_.Model | Org_ { org : String } Pages.Org_.Model | Org__Builds { org : String } Pages.Org_.Builds.Model | Org__Repo_ { org : String, repo : String } Pages.Org_.Repo_.Model diff --git a/src/elm/Pages/Dashboards/Dashboard_.elm b/src/elm/Pages/Dashboards/Dashboard_.elm index a8c7ea2cc..bf10e50aa 100644 --- a/src/elm/Pages/Dashboards/Dashboard_.elm +++ b/src/elm/Pages/Dashboards/Dashboard_.elm @@ -6,19 +6,40 @@ SPDX-License-Identifier: Apache-2.0 module Pages.Dashboards.Dashboard_ exposing (Model, Msg, page) import Auth +import Components.Crumbs +import Components.DashboardRepoCard +import Components.Nav import Effect exposing (Effect) import Html + exposing + ( div + , h1 + , main_ + , p + , text + ) +import Html.Attributes + exposing + ( class + ) +import Http +import Http.Detailed import Layouts import Page exposing (Page) +import RemoteData exposing (WebData) import Route exposing (Route) +import Route.Path import Shared +import Utils.Errors as Errors +import Utils.Helpers as Util +import Vela import View exposing (View) -page : Auth.User -> Shared.Model -> Route { dashboard : String } -> Page Model Msg +page : Auth.User -> Shared.Model -> Route { dashboardId : String } -> Page Model Msg page user shared route = Page.new - { init = init shared + { init = init shared route , update = update , subscriptions = subscriptions , view = view shared route @@ -47,13 +68,19 @@ toLayout user model = type alias Model = - {} - - -init : Shared.Model -> () -> ( Model, Effect Msg ) -init shared () = - ( {} - , Effect.none + { dashboard : WebData Vela.Dashboard } + + +init : Shared.Model -> Route { dashboardId : String } -> () -> ( Model, Effect Msg ) +init shared route () = + ( { dashboard = RemoteData.Loading } + , Effect.getDashboard + { baseUrl = shared.velaAPIBaseURL + , session = shared.session + , onResponse = + GetDashboardResponse + , dashboardId = route.params.dashboardId + } ) @@ -63,6 +90,7 @@ init shared () = type Msg = NoOp + | GetDashboardResponse (Result (Http.Detailed.Error String) ( Http.Metadata, Vela.Dashboard )) update : Msg -> Model -> ( Model, Effect Msg ) @@ -73,6 +101,21 @@ update msg model = , Effect.none ) + GetDashboardResponse response -> + case response of + Ok ( _, dashboard ) -> + ( { model | dashboard = RemoteData.Success dashboard } + , Effect.none + ) + + Err error -> + ( { model | dashboard = Errors.toFailure error } + , Effect.handleHttpError + { error = error + , shouldShowAlertFn = Errors.showAlertAlways + } + ) + -- SUBSCRIPTIONS @@ -87,8 +130,50 @@ subscriptions model = -- VIEW -view : Shared.Model -> Route { dashboard : String } -> Model -> View Msg +view : Shared.Model -> Route { dashboardId : String } -> Model -> View Msg view shared route model = - { title = "Pages.Dashboards.Dashboard_" - , body = [ Html.text "/dashboards/:dashboard" ] + let + crumbs = + [ ( "Overview", Just Route.Path.Home_ ) + , ( "Dashboard", Nothing ) + , ( route.params.dashboardId, Nothing ) + ] + in + { title = "Dashboard" + , body = + [ Components.Nav.view + shared + route + { buttons = [] + , crumbs = Components.Crumbs.view route.path crumbs + } + , main_ [ class "content-wrap" ] + [ div [ Util.testAttribute "dashboard" ] + [ case model.dashboard of + RemoteData.Loading -> + div [] [ text "Loading..." ] + + RemoteData.NotAsked -> + div [] [ text "Not Asked" ] + + RemoteData.Failure error -> + div [] [ text "failed like no one has failed before" ] + + RemoteData.Success dashboard -> + div [] <| + [ h1 [] [ text dashboard.dashboard.name ] + , p [] + [ text "This is a placeholder for future content." + ] + ] + ++ List.map + (\repo -> + Components.DashboardRepoCard.view shared + { card = repo + } + ) + dashboard.repos + ] + ] + ] } diff --git a/src/elm/Route/Path.elm b/src/elm/Route/Path.elm index d5145d495..15473d3ac 100644 --- a/src/elm/Route/Path.elm +++ b/src/elm/Route/Path.elm @@ -27,7 +27,7 @@ type Path | Dash_Secrets_Engine__Shared_Org__Team_ { engine : String, org : String, team : String } | Dash_Secrets_Engine__Shared_Org__Team__Add { engine : String, org : String, team : String } | Dash_Secrets_Engine__Shared_Org__Team__Name_ { engine : String, org : String, team : String, name : String } - | Dashboards_Dashboard_ { dashboard : String } + | Dashboards_Dashboard_ { dashboardId : String } | Org_ { org : String } | Org__Builds { org : String } | Org__Repo_ { org : String, repo : String } @@ -155,7 +155,7 @@ fromString urlPath = "dashboards" :: dashboard_ :: [] -> Dashboards_Dashboard_ - { dashboard = dashboard_ + { dashboardId = dashboard_ } |> Just @@ -335,7 +335,7 @@ toString path = [ "-", "secrets", params.engine, "shared", params.org, params.team, params.name ] Dashboards_Dashboard_ params -> - [ "dashboards", params.dashboard ] + [ "dashboards", params.dashboardId ] Org_ params -> [ params.org ] diff --git a/src/elm/Vela.elm b/src/elm/Vela.elm index 6eda58ebe..5957daab8 100644 --- a/src/elm/Vela.elm +++ b/src/elm/Vela.elm @@ -12,6 +12,8 @@ module Vela exposing , BuildGraphInteraction , BuildGraphNode , BuildNumber + , Dashboard + , DashboardRepoCard , Deployment , DeploymentPayload , EnableRepoPayload @@ -53,6 +55,7 @@ module Vela exposing , decodeBuild , decodeBuildGraph , decodeBuilds + , decodeDashboard , decodeDeployment , decodeDeployments , decodeGraphInteraction @@ -161,6 +164,101 @@ type alias Ref = +-- DASHBOARD + + +type alias Dashboard = + { dashboard : DashboardItem + , repos : List DashboardRepoCard + } + + +type alias DashboardItem = + { id : String + , name : String + , created_at : Int + , created_by : String + , updated_at : Int + , updated_by : String + , admins : List User + , repos : List DashboardRepo + } + + +type alias DashboardRepo = + { id : Int + , name : String + , branches : List String + , events : List String + } + + +type alias DashboardRepoCard = + { org : String + , name : String + , counter : Int + , builds : List DashboardRepoCardBuild + } + + +type alias DashboardRepoCardBuild = + { number : Int + , started : Int + , finished : Int + , sender : String + , status : Status + } + + +decodeDashboard : Decoder Dashboard +decodeDashboard = + Json.Decode.succeed Dashboard + |> optional "dashboard" decodeDashboardItem (DashboardItem "" "" 0 "" 0 "" [] []) + |> optional "repos" (Json.Decode.list decodeDashboardRepoCard) [] + + +decodeDashboardItem : Decoder DashboardItem +decodeDashboardItem = + Json.Decode.succeed DashboardItem + |> optional "id" string "" + |> optional "name" string "" + |> optional "created_at" int -1 + |> optional "created_by" string "" + |> optional "updated_at" int -1 + |> optional "updated_by" string "" + |> optional "admins" (Json.Decode.list decodeUser) [] + |> optional "repos" (Json.Decode.list decodeDashboardRepo) [] + + +decodeDashboardRepoCard : Decoder DashboardRepoCard +decodeDashboardRepoCard = + Json.Decode.succeed DashboardRepoCard + |> optional "org" string "" + |> optional "name" string "" + |> optional "counter" int -1 + |> optional "builds" (Json.Decode.list decodeDashboardRepoCardBuild) [] + + +decodeDashboardRepo : Decoder DashboardRepo +decodeDashboardRepo = + Json.Decode.succeed DashboardRepo + |> optional "id" int -1 + |> optional "name" string "" + |> optional "branches" (Json.Decode.list string) [] + |> optional "events" (Json.Decode.list string) [] + + +decodeDashboardRepoCardBuild : Decoder DashboardRepoCardBuild +decodeDashboardRepoCardBuild = + Json.Decode.succeed DashboardRepoCardBuild + |> optional "number" int -1 + |> optional "started" int -1 + |> optional "finished" int -1 + |> optional "sender" string "" + |> optional "status" buildStatusDecoder Pending + + + -- USER From d94b7e85b9b298292d11751cd14671e9f7a3d2bb Mon Sep 17 00:00:00 2001 From: Kelly Merrick Date: Mon, 29 Apr 2024 15:29:31 -0500 Subject: [PATCH 05/23] feat(dashboard): most recent build info accessible --- src/elm/Components/DashboardRepoCard.elm | 40 ++++++++++++++++++++++-- src/elm/Vela.elm | 6 ++++ 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/src/elm/Components/DashboardRepoCard.elm b/src/elm/Components/DashboardRepoCard.elm index e104c414b..1bfa14650 100644 --- a/src/elm/Components/DashboardRepoCard.elm +++ b/src/elm/Components/DashboardRepoCard.elm @@ -5,8 +5,14 @@ SPDX-License-Identifier: Apache-2.0 module Components.DashboardRepoCard exposing (view) -import Html exposing (Html, div, text) +import Html exposing (Html, a, div, text) +import Html.Attributes + exposing + ( class + ) +import Route.Path import Shared +import Utils.Helpers as Util import Vela @@ -17,4 +23,34 @@ type alias Props = view : Shared.Model -> Props -> Html msg view shared props = - div [] [ text <| "Future " ++ props.card.org ++ "/" ++ props.card.name ++ " card" ] + div [ class "item" ] + [ a + [ Route.Path.href <| + Route.Path.Org_ + { org = props.card.org + } + ] + [ text props.card.org ] + , a + [ Route.Path.href <| + Route.Path.Org__Repo_ + { org = props.card.org + , repo = props.card.name + } + ] + [ text props.card.name ] + , div [] <| + case List.head props.card.builds of + Just build -> + [ text <| "status: " ++ Vela.statusToString build.status + , text <| "build: " ++ String.fromInt build.number + , text <| "sender: " ++ build.sender + , text <| "branch: " ++ build.branch + , text <| "event: " ++ build.event + , text <| "started: " ++ Util.humanReadableDateWithDefault shared.zone build.started + , text <| "duration: " ++ Util.formatRunTime shared.time build.started build.finished + ] + + Nothing -> + [ text "No builds found" ] + ] diff --git a/src/elm/Vela.elm b/src/elm/Vela.elm index 5957daab8..e28d3602f 100644 --- a/src/elm/Vela.elm +++ b/src/elm/Vela.elm @@ -207,6 +207,9 @@ type alias DashboardRepoCardBuild = , finished : Int , sender : String , status : Status + , event : String + , branch : String + , link : String } @@ -256,6 +259,9 @@ decodeDashboardRepoCardBuild = |> optional "finished" int -1 |> optional "sender" string "" |> optional "status" buildStatusDecoder Pending + |> optional "event" string "" + |> optional "branch" string "" + |> optional "link" string "" From 98fac96c805150c51d47af3efda7e77f32a93113 Mon Sep 17 00:00:00 2001 From: Kelly Merrick Date: Fri, 3 May 2024 11:32:40 -0500 Subject: [PATCH 06/23] feat(dashboard): populate all card data --- src/elm/Components/DashboardRepoCard.elm | 125 ++++++++++++++++++----- src/elm/Pages/Dashboards/Dashboard_.elm | 11 +- src/elm/Vela.elm | 29 +----- src/scss/_dashboards.scss | 60 +++++++++++ src/scss/_variables.scss | 1 + src/scss/style.scss | 1 + 6 files changed, 166 insertions(+), 61 deletions(-) create mode 100644 src/scss/_dashboards.scss diff --git a/src/elm/Components/DashboardRepoCard.elm b/src/elm/Components/DashboardRepoCard.elm index 1bfa14650..f8430be38 100644 --- a/src/elm/Components/DashboardRepoCard.elm +++ b/src/elm/Components/DashboardRepoCard.elm @@ -5,13 +5,20 @@ SPDX-License-Identifier: Apache-2.0 module Components.DashboardRepoCard exposing (view) -import Html exposing (Html, a, div, text) +import Components.RecentBuilds +import Components.Svgs +import DateFormat.Relative +import FeatherIcons +import Html exposing (Html, a, div, span, text) import Html.Attributes exposing - ( class + ( attribute + , class ) +import RemoteData import Route.Path import Shared +import Time import Utils.Helpers as Util import Vela @@ -23,34 +30,96 @@ type alias Props = view : Shared.Model -> Props -> Html msg view shared props = - div [ class "item" ] - [ a - [ Route.Path.href <| - Route.Path.Org_ - { org = props.card.org - } - ] - [ text props.card.org ] - , a - [ Route.Path.href <| - Route.Path.Org__Repo_ - { org = props.card.org - , repo = props.card.name - } - ] - [ text props.card.name ] - , div [] <| + let + cardProps = case List.head props.card.builds of Just build -> - [ text <| "status: " ++ Vela.statusToString build.status - , text <| "build: " ++ String.fromInt build.number - , text <| "sender: " ++ build.sender - , text <| "branch: " ++ build.branch - , text <| "event: " ++ build.event - , text <| "started: " ++ Util.humanReadableDateWithDefault shared.zone build.started - , text <| "duration: " ++ Util.formatRunTime shared.time build.started build.finished - ] + { icon = Components.Svgs.recentBuildStatusToIcon build.status 0 + , build = a [ Route.Path.href <| Route.Path.Org__Repo__Build_ { org = props.card.org, repo = props.card.name, build = String.fromInt build.number } ] [ text <| "#" ++ String.fromInt build.number ] + , event = build.event + , branch = build.branch + , sender = build.sender + , age = + let + buildStartedPosix = + Time.millisToPosix <| Util.secondsToMillis build.started + in + DateFormat.Relative.relativeTime shared.time <| buildStartedPosix + , duration = Util.formatRunTime shared.time build.started build.finished + , recentBuilds = + div + [ class "dashboard-recent-builds" ] + [ Components.RecentBuilds.view shared + { builds = RemoteData.succeed props.card.builds + , build = RemoteData.succeed build + , num = 5 + , toPath = \_ -> Route.Path.Home_ + } + ] + } Nothing -> - [ text "No builds found" ] + { icon = Components.Svgs.recentBuildStatusToIcon Vela.Pending 0 + , build = span [] [ text "-" ] + , event = "-" + , branch = "-" + , age = "-" + , sender = "-" + , duration = "-" + , recentBuilds = div [ class "build-data-right" ] [ text "waiting for builds" ] + } + in + div [ class "cards" ] + [ div [ class "card" ] + [ div [] + [ div [ class "card-org-repo" ] + [ a + [ Route.Path.href <| + Route.Path.Org_ + { org = props.card.org + } + ] + [ text props.card.org ] + ] + , div [ class "card-org-repo" ] + [ a + [ Route.Path.href <| + Route.Path.Org__Repo_ + { org = props.card.org + , repo = props.card.name + } + ] + [ text props.card.name ] + ] + ] + , div [ class "build-data" ] <| + [ div [] [ cardProps.icon ] + , div [ class "build-status" ] + [ div [ class "build-data-left" ] + -- build link + [ div [] + [ span [] [ FeatherIcons.cornerDownRight |> FeatherIcons.withSize 20 |> FeatherIcons.toHtml [ attribute "aria-label" "go-to-build icon" ] ] + , cardProps.build + ] + + -- event + , div [] [ span [] [ FeatherIcons.send |> FeatherIcons.withSize 20 |> FeatherIcons.toHtml [ attribute "aria-label" "event icon" ] ], text <| cardProps.event ] + + -- branch + , div [] [ span [] [ FeatherIcons.gitBranch |> FeatherIcons.withSize 20 |> FeatherIcons.toHtml [ attribute "aria-label" "branch icon" ] ], text <| cardProps.branch ] + ] + , div [ class "build-data-right" ] + -- sender + [ div [] [ text <| cardProps.sender, span [] [ FeatherIcons.user |> FeatherIcons.withSize 20 |> FeatherIcons.toHtml [ attribute "aria-label" "build-sender icon" ] ] ] + + -- age + , div [] [ text <| cardProps.age, span [] [ FeatherIcons.calendar |> FeatherIcons.withSize 20 |> FeatherIcons.toHtml [ attribute "aria-label" "time-started icon" ] ] ] + + -- duration + , div [] [ text <| cardProps.age, span [] [ FeatherIcons.clock |> FeatherIcons.withSize 20 |> FeatherIcons.toHtml [ attribute "aria-label" "duration icon" ] ] ] + ] + ] + , cardProps.recentBuilds + ] + ] ] diff --git a/src/elm/Pages/Dashboards/Dashboard_.elm b/src/elm/Pages/Dashboards/Dashboard_.elm index bf10e50aa..c2ebe9825 100644 --- a/src/elm/Pages/Dashboards/Dashboard_.elm +++ b/src/elm/Pages/Dashboards/Dashboard_.elm @@ -160,19 +160,18 @@ view shared route model = div [] [ text "failed like no one has failed before" ] RemoteData.Success dashboard -> - div [] <| + div [] [ h1 [] [ text dashboard.dashboard.name ] - , p [] - [ text "This is a placeholder for future content." - ] - ] - ++ List.map + , div [ class "cards" ] + (List.map (\repo -> Components.DashboardRepoCard.view shared { card = repo } ) dashboard.repos + ) + ] ] ] ] diff --git a/src/elm/Vela.elm b/src/elm/Vela.elm index e28d3602f..f9b4c3dd8 100644 --- a/src/elm/Vela.elm +++ b/src/elm/Vela.elm @@ -197,19 +197,7 @@ type alias DashboardRepoCard = { org : String , name : String , counter : Int - , builds : List DashboardRepoCardBuild - } - - -type alias DashboardRepoCardBuild = - { number : Int - , started : Int - , finished : Int - , sender : String - , status : Status - , event : String - , branch : String - , link : String + , builds : List Build } @@ -239,7 +227,7 @@ decodeDashboardRepoCard = |> optional "org" string "" |> optional "name" string "" |> optional "counter" int -1 - |> optional "builds" (Json.Decode.list decodeDashboardRepoCardBuild) [] + |> optional "builds" (Json.Decode.list decodeBuild) [] decodeDashboardRepo : Decoder DashboardRepo @@ -251,19 +239,6 @@ decodeDashboardRepo = |> optional "events" (Json.Decode.list string) [] -decodeDashboardRepoCardBuild : Decoder DashboardRepoCardBuild -decodeDashboardRepoCardBuild = - Json.Decode.succeed DashboardRepoCardBuild - |> optional "number" int -1 - |> optional "started" int -1 - |> optional "finished" int -1 - |> optional "sender" string "" - |> optional "status" buildStatusDecoder Pending - |> optional "event" string "" - |> optional "branch" string "" - |> optional "link" string "" - - -- USER diff --git a/src/scss/_dashboards.scss b/src/scss/_dashboards.scss new file mode 100644 index 000000000..b5df2930a --- /dev/null +++ b/src/scss/_dashboards.scss @@ -0,0 +1,60 @@ + +// SPDX-License-Identifier: Apache-2.0 + +// styles for the dashboard pages + +.cards { + display: flex; + flex-wrap: wrap; +} + +.card { + flex-basis: 100%; + margin: 0.5rem; + + background-color: var(--color-bg-dark); +} + +.card-org-repo { + display: flex; + flex-direction: column; + padding: 0 0 0 1rem; + + background-color: var(--color-bg-darker); +} + +.build-data { + display: flex; + flex-direction: column; + margin: 0.5rem 0 0 0; + padding: 0 0 0 1rem; + + background-color: var(--color-coal-darker); +} + +.build-status { + display: flex; + flex-direction: row; + justify-content: space-between; +} + +.build-data-left { + display: flex; + flex-direction: column; + align-items: flex-start; + margin: 0.5rem 0; + padding: 0 0 0 1rem; + + background-color: var(--color-coal-darker); +} + +.build-data-right { + display: flex; + flex-direction: column; + align-items: flex-end; + + margin: 0.5rem 0; + padding: 0 1rem 0 1rem; + + background-color: var(--color-coal-kinda-dark); +} diff --git a/src/scss/_variables.scss b/src/scss/_variables.scss index 5be5e8a33..600879dcf 100644 --- a/src/scss/_variables.scss +++ b/src/scss/_variables.scss @@ -13,6 +13,7 @@ // grays --color-coal-dark: hsl(0, 0%, 12%); + --color-coal-darker: hsl(0, 0%, 10%); --color-coal: hsl(0, 0%, 16%); // main dark bg --color-coal-light: hsl(0, 0%, 34%); diff --git a/src/scss/style.scss b/src/scss/style.scss index 1ccf0ca30..245da2544 100644 --- a/src/scss/style.scss +++ b/src/scss/style.scss @@ -23,6 +23,7 @@ @import 'settings'; @import 'pipelines'; @import 'graph'; +@import 'dashboards'; // general @import 'main'; From 2852ce785a9a9d6d042c7ec84d10da47af0c927d Mon Sep 17 00:00:00 2001 From: Kelly Merrick Date: Fri, 3 May 2024 16:29:38 -0500 Subject: [PATCH 07/23] feat(dashboard): some styling progress, theme supported --- src/elm/Components/DashboardRepoCard.elm | 63 ++++++++++++------------ src/elm/Components/Header.elm | 2 +- src/elm/Components/RecentBuilds.elm | 13 ++++- src/elm/Layouts/Default/Build.elm | 1 + src/scss/_dashboards.scss | 49 +++++++++--------- src/scss/_main.scss | 2 +- src/scss/_themes.scss | 2 + src/scss/_variables.scss | 2 +- 8 files changed, 71 insertions(+), 63 deletions(-) diff --git a/src/elm/Components/DashboardRepoCard.elm b/src/elm/Components/DashboardRepoCard.elm index f8430be38..6b09f6943 100644 --- a/src/elm/Components/DashboardRepoCard.elm +++ b/src/elm/Components/DashboardRepoCard.elm @@ -9,7 +9,7 @@ import Components.RecentBuilds import Components.Svgs import DateFormat.Relative import FeatherIcons -import Html exposing (Html, a, div, span, text) +import Html exposing (Html, a, br, div, header, li, p, section, span, text, ul) import Html.Attributes exposing ( attribute @@ -54,6 +54,7 @@ view shared props = , build = RemoteData.succeed build , num = 5 , toPath = \_ -> Route.Path.Home_ + , showTitle = False } ] } @@ -66,13 +67,14 @@ view shared props = , age = "-" , sender = "-" , duration = "-" - , recentBuilds = div [ class "build-data-right" ] [ text "waiting for builds" ] + , recentBuilds = div [ class "no-builds" ] [ text "waiting for builds" ] } in div [ class "cards" ] - [ div [ class "card" ] - [ div [] - [ div [ class "card-org-repo" ] + [ section [ class "card" ] + [ header [ class "card-org-repo" ] + [ cardProps.icon + , p [] [ a [ Route.Path.href <| Route.Path.Org_ @@ -80,9 +82,8 @@ view shared props = } ] [ text props.card.org ] - ] - , div [ class "card-org-repo" ] - [ a + , br [] [] + , a [ Route.Path.href <| Route.Path.Org__Repo_ { org = props.card.org @@ -92,34 +93,32 @@ view shared props = [ text props.card.name ] ] ] - , div [ class "build-data" ] <| - [ div [] [ cardProps.icon ] - , div [ class "build-status" ] - [ div [ class "build-data-left" ] - -- build link - [ div [] - [ span [] [ FeatherIcons.cornerDownRight |> FeatherIcons.withSize 20 |> FeatherIcons.toHtml [ attribute "aria-label" "go-to-build icon" ] ] - , cardProps.build - ] + , ul [ class "build-data" ] <| + -- build link + [ li [] [ FeatherIcons.cornerDownRight |> FeatherIcons.withSize 20 |> FeatherIcons.toHtml [ attribute "aria-label" "go-to-build icon" ], cardProps.build ] - -- event - , div [] [ span [] [ FeatherIcons.send |> FeatherIcons.withSize 20 |> FeatherIcons.toHtml [ attribute "aria-label" "event icon" ] ], text <| cardProps.event ] + -- event + , li [] + [ FeatherIcons.send |> FeatherIcons.withSize 20 |> FeatherIcons.toHtml [ attribute "aria-label" "event icon" ] + , text <| cardProps.event + ] - -- branch - , div [] [ span [] [ FeatherIcons.gitBranch |> FeatherIcons.withSize 20 |> FeatherIcons.toHtml [ attribute "aria-label" "branch icon" ] ], text <| cardProps.branch ] - ] - , div [ class "build-data-right" ] - -- sender - [ div [] [ text <| cardProps.sender, span [] [ FeatherIcons.user |> FeatherIcons.withSize 20 |> FeatherIcons.toHtml [ attribute "aria-label" "build-sender icon" ] ] ] + -- branch + , li [] + [ FeatherIcons.gitBranch |> FeatherIcons.withSize 20 |> FeatherIcons.toHtml [ attribute "aria-label" "branch icon" ] + , text <| cardProps.branch + ] - -- age - , div [] [ text <| cardProps.age, span [] [ FeatherIcons.calendar |> FeatherIcons.withSize 20 |> FeatherIcons.toHtml [ attribute "aria-label" "time-started icon" ] ] ] + -- sender + , li [] [ text <| cardProps.sender, FeatherIcons.user |> FeatherIcons.withSize 20 |> FeatherIcons.toHtml [ attribute "aria-label" "build-sender icon" ] ] - -- duration - , div [] [ text <| cardProps.age, span [] [ FeatherIcons.clock |> FeatherIcons.withSize 20 |> FeatherIcons.toHtml [ attribute "aria-label" "duration icon" ] ] ] - ] - ] - , cardProps.recentBuilds + -- age + , li [] [ text <| cardProps.age, FeatherIcons.calendar |> FeatherIcons.withSize 20 |> FeatherIcons.toHtml [ attribute "aria-label" "time-started icon" ] ] + + -- duration + , li [] + [ text <| cardProps.duration, FeatherIcons.clock |> FeatherIcons.withSize 20 |> FeatherIcons.toHtml [ attribute "aria-label" "duration icon" ] ] ] + , cardProps.recentBuilds ] ] diff --git a/src/elm/Components/Header.elm b/src/elm/Components/Header.elm index 6c1cd9129..9b9b483a6 100644 --- a/src/elm/Components/Header.elm +++ b/src/elm/Components/Header.elm @@ -52,7 +52,7 @@ view shared props = identityAttributeList = Util.open props.showId in - header [] + header [ class "main-header" ] [ div [ class "identity", id "identity", Util.testAttribute "identity" ] [ a [ Route.Path.href Route.Path.Home_ diff --git a/src/elm/Components/RecentBuilds.elm b/src/elm/Components/RecentBuilds.elm index b939e7d79..f226877f0 100644 --- a/src/elm/Components/RecentBuilds.elm +++ b/src/elm/Components/RecentBuilds.elm @@ -5,6 +5,8 @@ SPDX-License-Identifier: Apache-2.0 module Components.RecentBuilds exposing (view) +-- import Utils.Errors exposing (showAlertAlways) + import Components.Loading import Components.Svgs import Html exposing (Html, a, div, em, li, p, span, text, ul) @@ -25,6 +27,7 @@ type alias Props = , build : WebData Vela.Build , num : Int , toPath : String -> Route.Path.Path + , showTitle : Bool } @@ -34,11 +37,19 @@ type alias Props = view : Shared.Model -> Props -> Html msg view shared props = + let + viewTitle = + if props.showTitle then + p [ class "build-history-title" ] [ text "Recent Builds" ] + + else + text "" + in case props.builds of RemoteData.Success builds -> if List.length builds > 0 then div [ class "build-history" ] - [ p [ class "build-history-title" ] [ text "Recent Builds" ] + [ viewTitle , ul [ Util.testAttribute "build-history", class "previews" ] <| List.indexedMap (viewRecentBuild shared props) <| List.take props.num builds diff --git a/src/elm/Layouts/Default/Build.elm b/src/elm/Layouts/Default/Build.elm index 5412d5fa1..92d4011c3 100644 --- a/src/elm/Layouts/Default/Build.elm +++ b/src/elm/Layouts/Default/Build.elm @@ -428,6 +428,7 @@ view props shared route { toContentMsg, model, content } = , build = model.build , num = 10 , toPath = props.toBuildPath + , showTitle = True } , Components.Build.view shared { build = model.build diff --git a/src/scss/_dashboards.scss b/src/scss/_dashboards.scss index b5df2930a..5f7348d16 100644 --- a/src/scss/_dashboards.scss +++ b/src/scss/_dashboards.scss @@ -10,51 +10,46 @@ .card { flex-basis: 100%; - margin: 0.5rem; + margin: 0.5rem; background-color: var(--color-bg-dark); } .card-org-repo { display: flex; - flex-direction: column; - padding: 0 0 0 1rem; + align-items: center; + gap: .5rem; - background-color: var(--color-bg-darker); + background-color: var(--color-bg-darkest); } .build-data { - display: flex; - flex-direction: column; - margin: 0.5rem 0 0 0; - padding: 0 0 0 1rem; - - background-color: var(--color-coal-darker); + columns: 2; + list-style-type: none; + padding: 0.5rem; } -.build-status { +.build-data li{ display: flex; - flex-direction: row; - justify-content: space-between; + // flex-direction: column; + align-items: center; + gap: .5rem; } -.build-data-left { - display: flex; - flex-direction: column; - align-items: flex-start; - margin: 0.5rem 0; - padding: 0 0 0 1rem; +.build-data li:nth-child(n + 4){ + justify-content: right; - background-color: var(--color-coal-darker); } -.build-data-right { - display: flex; - flex-direction: column; - align-items: flex-end; +.dashboard-recent-builds { + margin: 0.5rem; + padding: 0 1rem; - margin: 0.5rem 0; - padding: 0 1rem 0 1rem; + background-color: var(--color-bg-darkest); +} +.no-builds { + margin: 0.5rem; + padding: 0 1rem; - background-color: var(--color-coal-kinda-dark); + background-color: var(--color-bg-darkest); } diff --git a/src/scss/_main.scss b/src/scss/_main.scss index 7bff3c41e..8dc900f24 100644 --- a/src/scss/_main.scss +++ b/src/scss/_main.scss @@ -30,7 +30,7 @@ a { } } -header { +.main-header { display: flex; align-items: center; justify-content: space-between; diff --git a/src/scss/_themes.scss b/src/scss/_themes.scss index f3dbd88ac..5a7880f2a 100644 --- a/src/scss/_themes.scss +++ b/src/scss/_themes.scss @@ -6,6 +6,7 @@ // dark theme (default) body, body.theme-dark { + --color-bg-darkest: var(--color-coal-darkest); --color-bg-dark: var(--color-coal-dark); --color-bg: var(--color-coal); --color-bg-light: var(--color-coal-light); @@ -27,6 +28,7 @@ body.theme-dark { // light theme body.theme-light { + --color-bg-darkest: var(--color-gray-lightest); --color-bg-dark: var(--color-gray-light); --color-bg: var(--color-offwhite); // --color-bg-light: var(--color-white); diff --git a/src/scss/_variables.scss b/src/scss/_variables.scss index 600879dcf..6406d867b 100644 --- a/src/scss/_variables.scss +++ b/src/scss/_variables.scss @@ -12,8 +12,8 @@ --color-lavender-light: hsl(286, 29%, 65%); // good for text on coal // grays + --color-coal-darkest: hsl(0, 0%, 10%); --color-coal-dark: hsl(0, 0%, 12%); - --color-coal-darker: hsl(0, 0%, 10%); --color-coal: hsl(0, 0%, 16%); // main dark bg --color-coal-light: hsl(0, 0%, 34%); From d8107e43cac25e526c0457de16dcf32902442e2b Mon Sep 17 00:00:00 2001 From: Kelly Merrick Date: Tue, 7 May 2024 22:51:20 -0500 Subject: [PATCH 08/23] feat(dashboard): adtl general styling, icon styling --- src/elm/Components/DashboardRepoCard.elm | 88 ++++++------- src/elm/Pages/Dashboards/Dashboard_.elm | 38 ++++-- src/scss/_dashboards.scss | 149 +++++++++++++++++++++-- src/scss/_main.scss | 94 +++++++------- 4 files changed, 255 insertions(+), 114 deletions(-) diff --git a/src/elm/Components/DashboardRepoCard.elm b/src/elm/Components/DashboardRepoCard.elm index 6b09f6943..b7660c795 100644 --- a/src/elm/Components/DashboardRepoCard.elm +++ b/src/elm/Components/DashboardRepoCard.elm @@ -67,58 +67,58 @@ view shared props = , age = "-" , sender = "-" , duration = "-" - , recentBuilds = div [ class "no-builds" ] [ text "waiting for builds" ] + , recentBuilds = div [ class "dashboard-no-builds" ] [ text "waiting for builds" ] } in - div [ class "cards" ] - [ section [ class "card" ] - [ header [ class "card-org-repo" ] - [ cardProps.icon - , p [] - [ a - [ Route.Path.href <| - Route.Path.Org_ - { org = props.card.org - } - ] - [ text props.card.org ] - , br [] [] - , a - [ Route.Path.href <| - Route.Path.Org__Repo_ - { org = props.card.org - , repo = props.card.name - } - ] - [ text props.card.name ] + section [ class "card" ] + [ header [ class "card-org-repo card-org-repo.padding-none" ] + [ cardProps.icon + , p [] + [ a + [ class "card-org" + , Route.Path.href <| + Route.Path.Org_ + { org = props.card.org + } + ] + [ text props.card.org ] + , br [] [] + , a + [ class "card-repo" + , Route.Path.href <| + Route.Path.Org__Repo_ + { org = props.card.org + , repo = props.card.name + } ] + [ text props.card.name ] ] - , ul [ class "build-data" ] <| - -- build link - [ li [] [ FeatherIcons.cornerDownRight |> FeatherIcons.withSize 20 |> FeatherIcons.toHtml [ attribute "aria-label" "go-to-build icon" ], cardProps.build ] + ] + , ul [ class "card-build-data" ] <| + [ -- build link + li [] [ FeatherIcons.cornerDownRight |> FeatherIcons.withSize 20 |> FeatherIcons.toHtml [ attribute "aria-label" "go-to-build icon" ], cardProps.build ] - -- event - , li [] - [ FeatherIcons.send |> FeatherIcons.withSize 20 |> FeatherIcons.toHtml [ attribute "aria-label" "event icon" ] - , text <| cardProps.event - ] + -- event + , li [] + [ FeatherIcons.send |> FeatherIcons.withSize 20 |> FeatherIcons.toHtml [ attribute "aria-label" "event icon" ] + , text <| cardProps.event + ] - -- branch - , li [] - [ FeatherIcons.gitBranch |> FeatherIcons.withSize 20 |> FeatherIcons.toHtml [ attribute "aria-label" "branch icon" ] - , text <| cardProps.branch - ] + -- branch + , li [] + [ FeatherIcons.gitBranch |> FeatherIcons.withSize 20 |> FeatherIcons.toHtml [ attribute "aria-label" "branch icon" ] + , text <| cardProps.branch + ] - -- sender - , li [] [ text <| cardProps.sender, FeatherIcons.user |> FeatherIcons.withSize 20 |> FeatherIcons.toHtml [ attribute "aria-label" "build-sender icon" ] ] + -- sender + , li [] [ text <| cardProps.sender, FeatherIcons.user |> FeatherIcons.withSize 20 |> FeatherIcons.toHtml [ attribute "aria-label" "build-sender icon" ] ] - -- age - , li [] [ text <| cardProps.age, FeatherIcons.calendar |> FeatherIcons.withSize 20 |> FeatherIcons.toHtml [ attribute "aria-label" "time-started icon" ] ] + -- age + , li [] [ text <| cardProps.age, FeatherIcons.calendar |> FeatherIcons.withSize 20 |> FeatherIcons.toHtml [ attribute "aria-label" "time-started icon" ] ] - -- duration - , li [] - [ text <| cardProps.duration, FeatherIcons.clock |> FeatherIcons.withSize 20 |> FeatherIcons.toHtml [ attribute "aria-label" "duration icon" ] ] - ] - , cardProps.recentBuilds + -- duration + , li [] + [ text <| cardProps.duration, FeatherIcons.clock |> FeatherIcons.withSize 20 |> FeatherIcons.toHtml [ attribute "aria-label" "duration icon" ] ] ] + , cardProps.recentBuilds ] diff --git a/src/elm/Pages/Dashboards/Dashboard_.elm b/src/elm/Pages/Dashboards/Dashboard_.elm index c2ebe9825..ed9c5ee86 100644 --- a/src/elm/Pages/Dashboards/Dashboard_.elm +++ b/src/elm/Pages/Dashboards/Dashboard_.elm @@ -30,8 +30,10 @@ import RemoteData exposing (WebData) import Route exposing (Route) import Route.Path import Shared +import Time import Utils.Errors as Errors import Utils.Helpers as Util +import Utils.Interval as Interval import Vela import View exposing (View) @@ -40,19 +42,19 @@ page : Auth.User -> Shared.Model -> Route { dashboardId : String } -> Page Model page user shared route = Page.new { init = init shared route - , update = update + , update = update shared route , subscriptions = subscriptions , view = view shared route } - |> Page.withLayout (toLayout user) + |> Page.withLayout (toLayout user route) -- LAYOUT -toLayout : Auth.User -> Model -> Layouts.Layout Msg -toLayout user model = +toLayout : Auth.User -> Route { dashboardId : String } -> Model -> Layouts.Layout Msg +toLayout user route model = Layouts.Default { helpCommands = [ { name = "" @@ -91,10 +93,12 @@ init shared route () = type Msg = NoOp | GetDashboardResponse (Result (Http.Detailed.Error String) ( Http.Metadata, Vela.Dashboard )) + -- REFRESH + | Tick { time : Time.Posix, interval : Interval.Interval } -update : Msg -> Model -> ( Model, Effect Msg ) -update msg model = +update : Shared.Model -> Route { dashboardId : String } -> Msg -> Model -> ( Model, Effect Msg ) +update shared route msg model = case msg of NoOp -> ( model @@ -116,6 +120,16 @@ update msg model = } ) + Tick options -> + ( model + , Effect.getDashboard + { baseUrl = shared.velaAPIBaseURL + , session = shared.session + , onResponse = GetDashboardResponse + , dashboardId = route.params.dashboardId + } + ) + -- SUBSCRIPTIONS @@ -123,7 +137,9 @@ update msg model = subscriptions : Model -> Sub Msg subscriptions model = - Sub.none + Sub.batch + [ Interval.tickEveryFiveSeconds Tick + ] @@ -135,11 +151,11 @@ view shared route model = let crumbs = [ ( "Overview", Just Route.Path.Home_ ) - , ( "Dashboard", Nothing ) + , ( "Dashboards", Nothing ) , ( route.params.dashboardId, Nothing ) ] in - { title = "Dashboard" + { title = "Dashboards" , body = [ Components.Nav.view shared @@ -148,7 +164,7 @@ view shared route model = , crumbs = Components.Crumbs.view route.path crumbs } , main_ [ class "content-wrap" ] - [ div [ Util.testAttribute "dashboard" ] + [ div [ class "dashboard", Util.testAttribute "dashboard" ] [ case model.dashboard of RemoteData.Loading -> div [] [ text "Loading..." ] @@ -161,7 +177,7 @@ view shared route model = RemoteData.Success dashboard -> div [] - [ h1 [] [ text dashboard.dashboard.name ] + [ h1 [ class "dashboard-title" ] [ text dashboard.dashboard.name ] , div [ class "cards" ] (List.map (\repo -> diff --git a/src/scss/_dashboards.scss b/src/scss/_dashboards.scss index 5f7348d16..fe7d121cb 100644 --- a/src/scss/_dashboards.scss +++ b/src/scss/_dashboards.scss @@ -3,14 +3,24 @@ // styles for the dashboard pages +.dashboard-title { + border-bottom: var(--line-width) solid var(--color-secondary); +} + +.dashboard { + +} + .cards { display: flex; flex-wrap: wrap; } .card { - flex-basis: 100%; - margin: 0.5rem; + flex: 0 0 26rem; + margin-right: 2rem; + margin-bottom: 2rem; + padding: .5rem; background-color: var(--color-bg-dark); } @@ -19,37 +29,152 @@ display: flex; align-items: center; gap: .5rem; + line-height: 1.25; + width: calc(100% + 1rem); + margin: -0.5rem -0.5rem 0 -0.5rem; // to ignore .card padding + padding: 0 1rem; background-color: var(--color-bg-darkest); + + .-icon { + width: 2.5rem; + height: 2.5rem; + + &.-pending { + background-color: var(--color-bg-light); + stroke: var(--color-bg-darkest); + } + + &.-running { + background-color: var(--color-yellow); + stroke: var(--color-bg-darkest); + } + + &.-success { + background-color: var(--color-green); + stroke: var(--color-bg-darkest); + } + + &.-failure { + background-color: var(--color-red); + stroke: var(--color-bg-darkest); + } + + &.-canceled { + background-color: var(--color-cyan-dark); + stroke: var(--color-bg-darkest); + } + + &.-error { + background-color: var(--color-red); + stroke: var(--color-bg-darkest); + } + } +} + +.card-org { + font-size: smaller; + padding-left: .5rem; } -.build-data { +.card-repo { + font-weight: bold; + padding-left: .5rem; +} + +.card-icon-nothing { + background-color: var(--color-coal-light); +} + +.card-build-data { columns: 2; list-style-type: none; padding: 0.5rem; + margin: 0; } -.build-data li{ +.card-build-data li { display: flex; - // flex-direction: column; + margin: 0; align-items: center; gap: .5rem; -} -.build-data li:nth-child(n + 4){ - justify-content: right; + &:not(:last-child) { + margin-bottom: .5rem; + } + &:nth-child(n + 4) { + justify-content: right; + } } .dashboard-recent-builds { margin: 0.5rem; - padding: 0 1rem; - background-color: var(--color-bg-darkest); + background-color: var(--color-bg-dark); + + .recent-build:first-child .recent-build-link.-current{ + margin: 0; + } + + .recent-build:first-child .-icon{ + stroke-width: 1px; + } + + .recent-build:not(:first-child) .-icon { + background-color: var(--color-bg-dark); // too many levels + stroke: var(--color-green); + stroke-width: 1px; + + &.-pending { // def too many levels + stroke: var(--color-bg-darkest); + border-top: 2px solid var(--color-green); + border-bottom: 2px solid var(--color-green); + } + + &.-running { + stroke: var(--color-bg-yellow); + border-top: 2px solid var(--color-yellow); + border-bottom: 2px solid var(--color-yellow); + } + + &.-success { + stroke: var(--color-green); + border-top: 2px solid var(--color-green); + border-bottom: 2px solid var(--color-green); + } + + &.-failure { + stroke: var(--color-red); + border-top: 2px solid var(--color-red); + border-bottom: 2px solid var(--color-red); + } + + &.-canceled { + stroke: var(--color-cyan-dark); + border-top: 2px solid var(--color-cyan-dark); + border-bottom: 2px solid var(--color-cyan-dark); + } + + &.-error { + stroke: var(--color-red); + border-top: 2px solid var(--color-red); + border-bottom: 2px solid var(--color-red); + } + } + + .-icon { + width: 5rem; + height: 5rem; + + } } -.no-builds { + +.dashboard-no-builds { margin: 0.5rem; - padding: 0 1rem; + padding: 1.75rem 1rem 1rem 1rem; + height: 5rem; + text-align: center; background-color: var(--color-bg-darkest); } diff --git a/src/scss/_main.scss b/src/scss/_main.scss index 8dc900f24..217856ab7 100644 --- a/src/scss/_main.scss +++ b/src/scss/_main.scss @@ -809,6 +809,52 @@ details.build-toggle { font-size: 0.8em; } +.-icon { + fill: none; + stroke: var(--color-primary); + + &.-check { + background-color: var(--color-primary); + + stroke: var(--color-bg); + } + + &.-check, + &.-radio { + fill: none; + } + + &.-success { + stroke: var(--color-green); + } + + &.-running { + stroke: var(--color-yellow); + } + + &.-failure, + &.-error { + stroke: var(--color-red); + } + + &.-canceled { + stroke: var(--color-cyan-dark); + } + + &.-pending { + fill: var(--color-bg-light); + stroke: var(--color-bg-light); + } + + .-inner { + fill: var(--color-primary); + } + + &.-skip { + stroke: var(--color-lavender); + } +} + .recent-build { position: relative; @@ -833,7 +879,7 @@ details.build-toggle { margin: 0 0.2rem 0 0; } -.build-history .recent-build-link .-icon { +.recent-build-link .-icon { fill: none; stroke: var(--color-bg); @@ -1301,52 +1347,6 @@ details.build-toggle { justify-content: space-around; } -.-icon { - fill: none; - stroke: var(--color-primary); - - &.-check { - background-color: var(--color-primary); - - stroke: var(--color-bg); - } - - &.-check, - &.-radio { - fill: none; - } - - &.-success { - stroke: var(--color-green); - } - - &.-running { - stroke: var(--color-yellow); - } - - &.-failure, - &.-error { - stroke: var(--color-red); - } - - &.-canceled { - stroke: var(--color-cyan-dark); - } - - &.-pending { - fill: var(--color-bg-light); - stroke: var(--color-bg-light); - } - - .-inner { - fill: var(--color-primary); - } - - &.-skip { - stroke: var(--color-lavender); - } -} - .pager-actions { display: flex; justify-content: flex-end; From a25d41c50c2de40432ab1b53ed9fa18072cc519c Mon Sep 17 00:00:00 2001 From: Kelly Merrick Date: Wed, 8 May 2024 15:43:16 -0500 Subject: [PATCH 09/23] feat(dashboard): handle RemoteData and truncate long text --- src/elm/Components/DashboardRepoCard.elm | 12 +++---- src/elm/Pages/Dashboards/Dashboard_.elm | 42 ++++++++++++++---------- src/scss/_dashboards.scss | 18 +++++++++- 3 files changed, 48 insertions(+), 24 deletions(-) diff --git a/src/elm/Components/DashboardRepoCard.elm b/src/elm/Components/DashboardRepoCard.elm index b7660c795..334b24dfe 100644 --- a/src/elm/Components/DashboardRepoCard.elm +++ b/src/elm/Components/DashboardRepoCard.elm @@ -66,7 +66,7 @@ view shared props = , branch = "-" , age = "-" , sender = "-" - , duration = "-" + , duration = "--:--" , recentBuilds = div [ class "dashboard-no-builds" ] [ text "waiting for builds" ] } in @@ -84,7 +84,7 @@ view shared props = [ text props.card.org ] , br [] [] , a - [ class "card-repo" + [ class "card-repo card-repo-truncate-text" , Route.Path.href <| Route.Path.Org__Repo_ { org = props.card.org @@ -101,20 +101,20 @@ view shared props = -- event , li [] [ FeatherIcons.send |> FeatherIcons.withSize 20 |> FeatherIcons.toHtml [ attribute "aria-label" "event icon" ] - , text <| cardProps.event + , span [ class "card-truncate-text" ] [ text <| cardProps.event ] ] -- branch , li [] [ FeatherIcons.gitBranch |> FeatherIcons.withSize 20 |> FeatherIcons.toHtml [ attribute "aria-label" "branch icon" ] - , text <| cardProps.branch + , span [ class "card-truncate-text" ] [ text <| cardProps.branch ] ] -- sender - , li [] [ text <| cardProps.sender, FeatherIcons.user |> FeatherIcons.withSize 20 |> FeatherIcons.toHtml [ attribute "aria-label" "build-sender icon" ] ] + , li [] [ span [ class "card-truncate-text" ] [ text <| cardProps.sender ], FeatherIcons.user |> FeatherIcons.withSize 20 |> FeatherIcons.toHtml [ attribute "aria-label" "build-sender icon" ] ] -- age - , li [] [ text <| cardProps.age, FeatherIcons.calendar |> FeatherIcons.withSize 20 |> FeatherIcons.toHtml [ attribute "aria-label" "time-started icon" ] ] + , li [] [ span [ class "card-truncate-text" ] [ text <| cardProps.age ], FeatherIcons.calendar |> FeatherIcons.withSize 20 |> FeatherIcons.toHtml [ attribute "aria-label" "time-started icon" ] ] -- duration , li [] diff --git a/src/elm/Pages/Dashboards/Dashboard_.elm b/src/elm/Pages/Dashboards/Dashboard_.elm index ed9c5ee86..4267f349c 100644 --- a/src/elm/Pages/Dashboards/Dashboard_.elm +++ b/src/elm/Pages/Dashboards/Dashboard_.elm @@ -8,6 +8,7 @@ module Pages.Dashboards.Dashboard_ exposing (Model, Msg, page) import Auth import Components.Crumbs import Components.DashboardRepoCard +import Components.Loading import Components.Nav import Effect exposing (Effect) import Html @@ -15,7 +16,7 @@ import Html ( div , h1 , main_ - , p + , span , text ) import Html.Attributes @@ -91,8 +92,7 @@ init shared route () = type Msg - = NoOp - | GetDashboardResponse (Result (Http.Detailed.Error String) ( Http.Metadata, Vela.Dashboard )) + = GetDashboardResponse (Result (Http.Detailed.Error String) ( Http.Metadata, Vela.Dashboard )) -- REFRESH | Tick { time : Time.Posix, interval : Interval.Interval } @@ -100,11 +100,6 @@ type Msg update : Shared.Model -> Route { dashboardId : String } -> Msg -> Model -> ( Model, Effect Msg ) update shared route msg model = case msg of - NoOp -> - ( model - , Effect.none - ) - GetDashboardResponse response -> case response of Ok ( _, dashboard ) -> @@ -166,15 +161,6 @@ view shared route model = , main_ [ class "content-wrap" ] [ div [ class "dashboard", Util.testAttribute "dashboard" ] [ case model.dashboard of - RemoteData.Loading -> - div [] [ text "Loading..." ] - - RemoteData.NotAsked -> - div [] [ text "Not Asked" ] - - RemoteData.Failure error -> - div [] [ text "failed like no one has failed before" ] - RemoteData.Success dashboard -> div [] [ h1 [ class "dashboard-title" ] [ text dashboard.dashboard.name ] @@ -188,6 +174,28 @@ view shared route model = dashboard.repos ) ] + + RemoteData.Failure error -> + span [] + [ text <| + case error of + Http.BadStatus statusCode -> + case statusCode of + 401 -> + "Unauthorized to retrieve dashboard" + + 404 -> + "No dashboard found" + + _ -> + "No dashboard found; there was an error with the server" + + _ -> + "No dashboard found; there was an error with the server" + ] + + _ -> + Components.Loading.viewSmallLoader ] ] ] diff --git a/src/scss/_dashboards.scss b/src/scss/_dashboards.scss index fe7d121cb..3b9be8c43 100644 --- a/src/scss/_dashboards.scss +++ b/src/scss/_dashboards.scss @@ -82,12 +82,21 @@ padding-left: .5rem; } +.card-repo-truncate-text { + display: inline-block; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + max-width: 25ch; +} + .card-icon-nothing { background-color: var(--color-coal-light); } .card-build-data { columns: 2; + column-gap: 0rem; list-style-type: none; padding: 0.5rem; margin: 0; @@ -106,6 +115,13 @@ &:nth-child(n + 4) { justify-content: right; } + + .card-truncate-text { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + max-width: 15ch; + } } .dashboard-recent-builds { @@ -133,7 +149,7 @@ } &.-running { - stroke: var(--color-bg-yellow); + stroke: var(--color-yellow); border-top: 2px solid var(--color-yellow); border-bottom: 2px solid var(--color-yellow); } From aa0be75beacf42b76ad6c63fa436c357bca93d2a Mon Sep 17 00:00:00 2001 From: wass3r <1301201+wass3r@users.noreply.github.com> Date: Mon, 20 May 2024 00:52:58 -0500 Subject: [PATCH 10/23] cleaned up dashboards --- cypress/fixtures/dashboard.json | 149 ++++++++ cypress/fixtures/dashboard_no_repos.json | 18 + cypress/integration/dashboards.spec.js | 126 +++++++ src/elm/Components/DashboardRepoCard.elm | 130 +++++-- src/elm/Main.elm | 462 +++++++++++++---------- src/elm/Main/Pages/Model.elm | 16 +- src/elm/Main/Pages/Msg.elm | 14 +- src/elm/Pages/Dashboards.elm | 156 ++++++++ src/elm/Pages/Dashboards/Dashboard_.elm | 109 ++++-- src/elm/Route.elm | 4 +- src/elm/Route/Path.elm | 13 +- src/elm/Route/Query.elm | 6 +- src/scss/_dashboards.scss | 237 +++++++----- src/scss/_main.scss | 22 ++ src/scss/_mixins.scss | 13 + 15 files changed, 1100 insertions(+), 375 deletions(-) create mode 100644 cypress/fixtures/dashboard.json create mode 100644 cypress/fixtures/dashboard_no_repos.json create mode 100644 cypress/integration/dashboards.spec.js create mode 100644 src/elm/Pages/Dashboards.elm diff --git a/cypress/fixtures/dashboard.json b/cypress/fixtures/dashboard.json new file mode 100644 index 000000000..a11573558 --- /dev/null +++ b/cypress/fixtures/dashboard.json @@ -0,0 +1,149 @@ +{ + "dashboard": { + "id": "86671eb5-a3ff-49e1-ad85-c3b2f648dcb2", + "name": "example", + "created_at": 1715749911, + "created_by": "CookieCat", + "updated_at": 1715749911, + "updated_by": "CookieCat", + "admins": [ + { + "id": 1, + "name": "CookieCat", + "active": true + } + ], + "repos": [ + { + "id": 2, + "name": "github/repo1" + }, + { + "id": 1, + "name": "github/repo2" + } + ] + }, + "repos": [ + { + "org": "github", + "name": "repo1", + "counter": 25, + "active": true, + "builds": [ + { + "number": 25, + "started": 1715965620, + "finished": 1715965674, + "sender": "github", + "status": "success", + "event": "push", + "branch": "main", + "link": "/github/repo1/25" + }, + { + "number": 24, + "started": 1715965597, + "finished": 1715965620, + "sender": "github", + "status": "canceled", + "event": "push", + "branch": "main", + "link": "/github/repo1/24" + }, + { + "number": 23, + "started": 1715964030, + "finished": 1715964083, + "sender": "github", + "status": "success", + "event": "push", + "branch": "main", + "link": "/github/repo1/23" + }, + { + "number": 22, + "started": 1715963978, + "finished": 1715964028, + "sender": "github", + "status": "success", + "event": "push", + "branch": "main", + "link": "/github/repo1/22" + }, + { + "number": 21, + "started": 1715919426, + "finished": 1715919479, + "sender": "github", + "status": "success", + "event": "push", + "branch": "main", + "link": "/github/repo1/21" + } + ] + }, + { + "org": "github", + "name": "repo2", + "active": true, + "builds": [ + { + "number": 15, + "started": 1715965620, + "finished": 1715965674, + "sender": "github", + "status": "failure", + "event": "push", + "branch": "main", + "link": "/github/repo2/15" + }, + { + "number": 14, + "started": 1715965597, + "finished": 1715965620, + "sender": "github", + "status": "canceled", + "event": "push", + "branch": "main", + "link": "/github/repo2/14" + }, + { + "number": 13, + "started": 1715964030, + "finished": 1715964083, + "sender": "github", + "status": "success", + "event": "push", + "branch": "main", + "link": "/github/repo2/13" + }, + { + "number": 12, + "started": 1715963978, + "finished": 1715964028, + "sender": "github", + "status": "success", + "event": "push", + "branch": "main", + "link": "/github/repo2/12" + }, + { + "number": 11, + "started": 1715919426, + "finished": 1715919479, + "sender": "github", + "status": "success", + "event": "push", + "branch": "main", + "link": "/github/repo2/11" + } + ] + }, + { + "org": "github", + "name": "repo3", + "active": true + } + ] +} diff --git a/cypress/fixtures/dashboard_no_repos.json b/cypress/fixtures/dashboard_no_repos.json new file mode 100644 index 000000000..ca3bd8c09 --- /dev/null +++ b/cypress/fixtures/dashboard_no_repos.json @@ -0,0 +1,18 @@ +{ + "dashboard": { + "id": "86671eb5-a3ff-49e1-ad85-c3b2f648dcb2", + "name": "example2", + "created_at": 1715749911, + "created_by": "CookieCat", + "updated_at": 1715749911, + "updated_by": "CookieCat", + "admins": [ + { + "id": 1, + "name": "CookieCat", + "active": true + } + ], + "repos": [] + } +} diff --git a/cypress/integration/dashboards.spec.js b/cypress/integration/dashboards.spec.js new file mode 100644 index 000000000..2ca8896b7 --- /dev/null +++ b/cypress/integration/dashboards.spec.js @@ -0,0 +1,126 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + */ + +context('Dashboards', () => { + context('server returns dashboard with 3 cards, one without builds', () => { + beforeEach(() => { + cy.server(); + cy.route( + 'GET', + '*api/v1/dashboards/86671eb5-a3ff-49e1-ad85-c3b2f648dcb2', + 'fixture:dashboard.json', + ); + cy.login('/dashboards/86671eb5-a3ff-49e1-ad85-c3b2f648dcb2'); + }); + + it('shows 3 dashboard cards', () => { + cy.get('[data-test=dashboard-card]').should('have.length', 3); + }); + + it('shows an empty state when there are no builds', () => { + cy.get('[data-test=dashboard-card]') + .last() + .contains('waiting for builds'); + }); + + it('shows success build icon in header in the first card', () => { + cy.get('[data-test=dashboard-card]') + .first() + .within(() => { + cy.get('.-icon').should('have.class', '-success'); + }); + }); + + it('shows failure build icon in header in the first card', () => { + cy.get('[data-test=dashboard-card]') + .eq(1) + .within(() => { + cy.get('.-icon').should('have.class', '-failure'); + }); + }); + + it('org link in card header goes to org page', () => { + cy.get('[data-test=dashboard-card]') + .first() + .within(() => { + cy.get('.card-org').click(); + cy.location('pathname').should('eq', '/github'); + }); + }); + + it('repo link in card header goes to repo page', () => { + cy.get('[data-test=dashboard-card]') + .first() + .within(() => { + cy.get('.card-repo').click(); + cy.location('pathname').should('eq', '/github/repo1'); + }); + }); + + it('build link in card goes to build page', () => { + cy.get('[data-test=dashboard-card]') + .first() + .within(() => { + cy.get('.card-build-data li:first-child a').click(); + cy.location('pathname').should('eq', '/github/repo1/25'); + }); + }); + + it('recent build link goes to respective build page', () => { + cy.get('[data-test=recent-build-link-25]').click(); + cy.location('pathname').should('eq', '/github/repo1/25'); + }); + }); + + context('server returning dashboard without repos', () => { + beforeEach(() => { + cy.server(); + cy.route( + 'GET', + '*api/v1/dashboards/86671eb5-a3ff-49e1-ad85-c3b2f648dcb2', + 'fixture:dashboard_no_repos.json', + ); + cy.login('/dashboards/86671eb5-a3ff-49e1-ad85-c3b2f648dcb2'); + }); + + it('shows message when there are no repositories added', () => { + cy.get('[data-test=dashboard]').contains( + `This dashboard doesn't have repositories added yet`, + ); + }); + }); + + context('dashboard not found', () => { + beforeEach(() => { + cy.server(); + cy.route({ + method: 'GET', + status: 404, + url: '*api/v1/dashboards/deadbeef', + response: { + error: + 'unable to read dashboard deadbeef: ERROR: invalid input syntax for type uuid: "deadbeef" (SQLSTATE 22P02)', + }, + }); + cy.login('/dashboards/deadbeef'); + }); + + it('shows a not found message', () => { + cy.get('[data-test=dashboard]').contains( + 'Dashboard "deadbeef" not found. Please check the URL.', + ); + }); + }); + + context('main dashboards page shows message', () => { + beforeEach(() => { + cy.server(); + cy.login('/dashboards'); + }); + + it('shows the welcome message', () => { + cy.get('[data-test=dashboards]').contains('Welcome to dashboards!'); + }); + }); +}); diff --git a/src/elm/Components/DashboardRepoCard.elm b/src/elm/Components/DashboardRepoCard.elm index 334b24dfe..69f1794a7 100644 --- a/src/elm/Components/DashboardRepoCard.elm +++ b/src/elm/Components/DashboardRepoCard.elm @@ -9,11 +9,28 @@ import Components.RecentBuilds import Components.Svgs import DateFormat.Relative import FeatherIcons -import Html exposing (Html, a, br, div, header, li, p, section, span, text, ul) +import Html + exposing + ( Html + , a + , br + , code + , div + , header + , li + , p + , section + , small + , span + , strong + , text + , ul + ) import Html.Attributes exposing ( attribute , class + , title ) import RemoteData import Route.Path @@ -34,18 +51,37 @@ view shared props = cardProps = case List.head props.card.builds of Just build -> + let + relativeAge = + build.started + |> Util.secondsToMillis + |> Time.millisToPosix + |> DateFormat.Relative.relativeTime shared.time + + runtime = + Util.formatRunTime shared.time build.started build.finished + in { icon = Components.Svgs.recentBuildStatusToIcon build.status 0 - , build = a [ Route.Path.href <| Route.Path.Org__Repo__Build_ { org = props.card.org, repo = props.card.name, build = String.fromInt build.number } ] [ text <| "#" ++ String.fromInt build.number ] + , build = + a + [ Route.Path.href <| + Route.Path.Org__Repo__Build_ + { org = props.card.org + , repo = props.card.name + , build = String.fromInt build.number + } + ] + [ text <| "#" ++ String.fromInt build.number ] , event = build.event , branch = build.branch , sender = build.sender , age = - let - buildStartedPosix = - Time.millisToPosix <| Util.secondsToMillis build.started - in - DateFormat.Relative.relativeTime shared.time <| buildStartedPosix - , duration = Util.formatRunTime shared.time build.started build.finished + if build.started > 0 then + relativeAge + + else + "-" + , duration = runtime , recentBuilds = div [ class "dashboard-recent-builds" ] @@ -53,25 +89,35 @@ view shared props = { builds = RemoteData.succeed props.card.builds , build = RemoteData.succeed build , num = 5 - , toPath = \_ -> Route.Path.Home_ + , toPath = + \b -> + Route.Path.Org__Repo__Build_ + { org = props.card.org + , repo = props.card.name + , build = b + } , showTitle = False } ] } Nothing -> + let + dash = + "-" + in { icon = Components.Svgs.recentBuildStatusToIcon Vela.Pending 0 - , build = span [] [ text "-" ] - , event = "-" - , branch = "-" - , age = "-" - , sender = "-" + , build = span [] [ text dash ] + , event = dash + , branch = dash + , age = dash + , sender = dash , duration = "--:--" - , recentBuilds = div [ class "dashboard-no-builds" ] [ text "waiting for builds" ] + , recentBuilds = div [ class "dashboard-recent-builds", class "-none" ] [ text "waiting for builds" ] } in - section [ class "card" ] - [ header [ class "card-org-repo card-org-repo.padding-none" ] + section [ class "card", Util.testAttribute "dashboard-card" ] + [ header [ class "card-header" ] [ cardProps.icon , p [] [ a @@ -81,44 +127,72 @@ view shared props = { org = props.card.org } ] - [ text props.card.org ] + [ small [] [ text props.card.org ] ] , br [] [] , a - [ class "card-repo card-repo-truncate-text" + [ class "card-repo -truncate" , Route.Path.href <| Route.Path.Org__Repo_ { org = props.card.org , repo = props.card.name } ] - [ text props.card.name ] + [ strong + [ Util.attrIf (String.length props.card.name > 25) (title props.card.name) ] + [ text props.card.name ] + ] ] ] , ul [ class "card-build-data" ] <| [ -- build link - li [] [ FeatherIcons.cornerDownRight |> FeatherIcons.withSize 20 |> FeatherIcons.toHtml [ attribute "aria-label" "go-to-build icon" ], cardProps.build ] + li [] + [ FeatherIcons.cornerDownRight + |> FeatherIcons.withSize 20 + |> FeatherIcons.toHtml [ attribute "aria-label" "go-to-build icon" ] + , cardProps.build + ] -- event , li [] - [ FeatherIcons.send |> FeatherIcons.withSize 20 |> FeatherIcons.toHtml [ attribute "aria-label" "event icon" ] - , span [ class "card-truncate-text" ] [ text <| cardProps.event ] + [ FeatherIcons.send + |> FeatherIcons.withSize 20 + |> FeatherIcons.toHtml [ attribute "aria-label" "event icon" ] + , span [] [ text <| cardProps.event ] ] -- branch , li [] - [ FeatherIcons.gitBranch |> FeatherIcons.withSize 20 |> FeatherIcons.toHtml [ attribute "aria-label" "branch icon" ] - , span [ class "card-truncate-text" ] [ text <| cardProps.branch ] + [ FeatherIcons.gitBranch + |> FeatherIcons.withSize 20 + |> FeatherIcons.toHtml [ attribute "aria-label" "branch icon" ] + , span + [ Util.attrIf (String.length cardProps.branch > 15) (title cardProps.branch) ] + [ text <| cardProps.branch ] ] -- sender - , li [] [ span [ class "card-truncate-text" ] [ text <| cardProps.sender ], FeatherIcons.user |> FeatherIcons.withSize 20 |> FeatherIcons.toHtml [ attribute "aria-label" "build-sender icon" ] ] + , li [] + [ span [] [ text <| cardProps.sender ] + , FeatherIcons.user + |> FeatherIcons.withSize 20 + |> FeatherIcons.toHtml [ attribute "aria-label" "build-sender icon" ] + ] -- age - , li [] [ span [ class "card-truncate-text" ] [ text <| cardProps.age ], FeatherIcons.calendar |> FeatherIcons.withSize 20 |> FeatherIcons.toHtml [ attribute "aria-label" "time-started icon" ] ] + , li [] + [ span [] [ text <| cardProps.age ] + , FeatherIcons.calendar + |> FeatherIcons.withSize 20 + |> FeatherIcons.toHtml [ attribute "aria-label" "time-started icon" ] + ] -- duration , li [] - [ text <| cardProps.duration, FeatherIcons.clock |> FeatherIcons.withSize 20 |> FeatherIcons.toHtml [ attribute "aria-label" "duration icon" ] ] + [ code [] [ text <| cardProps.duration ] + , FeatherIcons.clock + |> FeatherIcons.withSize 20 + |> FeatherIcons.toHtml [ attribute "aria-label" "duration icon" ] + ] ] , cardProps.recentBuilds ] diff --git a/src/elm/Main.elm b/src/elm/Main.elm index ddc2b608a..b1561dc3f 100644 --- a/src/elm/Main.elm +++ b/src/elm/Main.elm @@ -27,6 +27,7 @@ import Main.Pages.Model import Main.Pages.Msg import Maybe.Extra import Page +import Pages.Home_ import Pages.Account.Authenticate import Pages.Account.Login import Pages.Account.Logout @@ -41,16 +42,11 @@ import Pages.Dash.Secrets.Engine_.Repo.Org_.Repo_.Name_ import Pages.Dash.Secrets.Engine_.Shared.Org_.Team_ import Pages.Dash.Secrets.Engine_.Shared.Org_.Team_.Add import Pages.Dash.Secrets.Engine_.Shared.Org_.Team_.Name_ +import Pages.Dashboards import Pages.Dashboards.Dashboard_ -import Pages.Home_ -import Pages.NotFound_ import Pages.Org_ import Pages.Org_.Builds import Pages.Org_.Repo_ -import Pages.Org_.Repo_.Build_ -import Pages.Org_.Repo_.Build_.Graph -import Pages.Org_.Repo_.Build_.Pipeline -import Pages.Org_.Repo_.Build_.Services import Pages.Org_.Repo_.Deployments import Pages.Org_.Repo_.Deployments.Add import Pages.Org_.Repo_.Hooks @@ -60,6 +56,12 @@ import Pages.Org_.Repo_.Schedules.Add import Pages.Org_.Repo_.Schedules.Name_ import Pages.Org_.Repo_.Settings import Pages.Org_.Repo_.Tags +import Pages.Org_.Repo_.Build_ +import Pages.Org_.Repo_.Build_.Graph +import Pages.Org_.Repo_.Build_.Pipeline +import Pages.Org_.Repo_.Build_.Services +import Pages.NotFound_ +import Pages.NotFound_ import Route exposing (Route) import Route.Path import Shared @@ -113,10 +115,10 @@ init json url key = , shared = sharedModel } , Cmd.batch - [ Tuple.second page - , layout |> Maybe.map Tuple.second |> Maybe.withDefault Cmd.none - , fromSharedEffect { key = key, url = url, shared = sharedModel } sharedEffect - ] + [ Tuple.second page + , layout |> Maybe.map Tuple.second |> Maybe.withDefault Cmd.none + , fromSharedEffect { key = key, url = url, shared = sharedModel } sharedEffect + ] ) @@ -231,10 +233,9 @@ initLayout model layout = Layout.init defaultLayout () in ( Main.Layouts.Model.Default_Build { default = defaultLayoutModel, build = buildLayoutModel } - , Cmd.batch - [ fromLayoutEffect model (Effect.map Main.Layouts.Msg.Default_Build buildLayoutEffect) - , fromLayoutEffect model (Effect.map Main.Layouts.Msg.Default defaultLayoutEffect) - ] + , Cmd.batch [ fromLayoutEffect model (Effect.map Main.Layouts.Msg.Default_Build buildLayoutEffect) + , fromLayoutEffect model (Effect.map Main.Layouts.Msg.Default defaultLayoutEffect) + ] ) ( Layouts.Default_Org props, Just (Main.Layouts.Model.Default existing) ) -> @@ -309,10 +310,9 @@ initLayout model layout = Layout.init defaultLayout () in ( Main.Layouts.Model.Default_Org { default = defaultLayoutModel, org = orgLayoutModel } - , Cmd.batch - [ fromLayoutEffect model (Effect.map Main.Layouts.Msg.Default_Org orgLayoutEffect) - , fromLayoutEffect model (Effect.map Main.Layouts.Msg.Default defaultLayoutEffect) - ] + , Cmd.batch [ fromLayoutEffect model (Effect.map Main.Layouts.Msg.Default_Org orgLayoutEffect) + , fromLayoutEffect model (Effect.map Main.Layouts.Msg.Default defaultLayoutEffect) + ] ) ( Layouts.Default_Repo props, Just (Main.Layouts.Model.Default existing) ) -> @@ -387,10 +387,9 @@ initLayout model layout = Layout.init defaultLayout () in ( Main.Layouts.Model.Default_Repo { default = defaultLayoutModel, repo = repoLayoutModel } - , Cmd.batch - [ fromLayoutEffect model (Effect.map Main.Layouts.Msg.Default_Repo repoLayoutEffect) - , fromLayoutEffect model (Effect.map Main.Layouts.Msg.Default defaultLayoutEffect) - ] + , Cmd.batch [ fromLayoutEffect model (Effect.map Main.Layouts.Msg.Default_Repo repoLayoutEffect) + , fromLayoutEffect model (Effect.map Main.Layouts.Msg.Default defaultLayoutEffect) + ] ) @@ -409,12 +408,12 @@ initPageAndLayout model = ( pageModel, pageEffect ) = Page.init page () in - { page = + { page = Tuple.mapBoth Main.Pages.Model.Home_ (Effect.map Main.Pages.Msg.Home_ >> fromPageEffect model) ( pageModel, pageEffect ) - , layout = + , layout = Page.layout pageModel page |> Maybe.map (Layouts.map (Main.Pages.Msg.Home_ >> Page)) |> Maybe.map (initLayout model) @@ -430,12 +429,12 @@ initPageAndLayout model = ( pageModel, pageEffect ) = Page.init page () in - { page = + { page = Tuple.mapBoth Main.Pages.Model.Account_Authenticate (Effect.map Main.Pages.Msg.Account_Authenticate >> fromPageEffect model) ( pageModel, pageEffect ) - , layout = + , layout = Page.layout pageModel page |> Maybe.map (Layouts.map (Main.Pages.Msg.Account_Authenticate >> Page)) |> Maybe.map (initLayout model) @@ -450,12 +449,12 @@ initPageAndLayout model = ( pageModel, pageEffect ) = Page.init page () in - { page = + { page = Tuple.mapBoth Main.Pages.Model.Account_Login (Effect.map Main.Pages.Msg.Account_Login >> fromPageEffect model) ( pageModel, pageEffect ) - , layout = + , layout = Page.layout pageModel page |> Maybe.map (Layouts.map (Main.Pages.Msg.Account_Login >> Page)) |> Maybe.map (initLayout model) @@ -470,12 +469,12 @@ initPageAndLayout model = ( pageModel, pageEffect ) = Page.init page () in - { page = + { page = Tuple.mapBoth Main.Pages.Model.Account_Logout (Effect.map Main.Pages.Msg.Account_Logout >> fromPageEffect model) ( pageModel, pageEffect ) - , layout = + , layout = Page.layout pageModel page |> Maybe.map (Layouts.map (Main.Pages.Msg.Account_Logout >> Page)) |> Maybe.map (initLayout model) @@ -493,12 +492,12 @@ initPageAndLayout model = ( pageModel, pageEffect ) = Page.init page () in - { page = + { page = Tuple.mapBoth Main.Pages.Model.Account_Settings (Effect.map Main.Pages.Msg.Account_Settings >> fromPageEffect model) ( pageModel, pageEffect ) - , layout = + , layout = Page.layout pageModel page |> Maybe.map (Layouts.map (Main.Pages.Msg.Account_Settings >> Page)) |> Maybe.map (initLayout model) @@ -517,12 +516,12 @@ initPageAndLayout model = ( pageModel, pageEffect ) = Page.init page () in - { page = + { page = Tuple.mapBoth Main.Pages.Model.Account_SourceRepos (Effect.map Main.Pages.Msg.Account_SourceRepos >> fromPageEffect model) ( pageModel, pageEffect ) - , layout = + , layout = Page.layout pageModel page |> Maybe.map (Layouts.map (Main.Pages.Msg.Account_SourceRepos >> Page)) |> Maybe.map (initLayout model) @@ -541,12 +540,12 @@ initPageAndLayout model = ( pageModel, pageEffect ) = Page.init page () in - { page = + { page = Tuple.mapBoth (Main.Pages.Model.Dash_Secrets_Engine__Org_Org_ params) (Effect.map Main.Pages.Msg.Dash_Secrets_Engine__Org_Org_ >> fromPageEffect model) ( pageModel, pageEffect ) - , layout = + , layout = Page.layout pageModel page |> Maybe.map (Layouts.map (Main.Pages.Msg.Dash_Secrets_Engine__Org_Org_ >> Page)) |> Maybe.map (initLayout model) @@ -565,12 +564,12 @@ initPageAndLayout model = ( pageModel, pageEffect ) = Page.init page () in - { page = + { page = Tuple.mapBoth (Main.Pages.Model.Dash_Secrets_Engine__Org_Org__Add params) (Effect.map Main.Pages.Msg.Dash_Secrets_Engine__Org_Org__Add >> fromPageEffect model) ( pageModel, pageEffect ) - , layout = + , layout = Page.layout pageModel page |> Maybe.map (Layouts.map (Main.Pages.Msg.Dash_Secrets_Engine__Org_Org__Add >> Page)) |> Maybe.map (initLayout model) @@ -589,12 +588,12 @@ initPageAndLayout model = ( pageModel, pageEffect ) = Page.init page () in - { page = + { page = Tuple.mapBoth (Main.Pages.Model.Dash_Secrets_Engine__Org_Org__Name_ params) (Effect.map Main.Pages.Msg.Dash_Secrets_Engine__Org_Org__Name_ >> fromPageEffect model) ( pageModel, pageEffect ) - , layout = + , layout = Page.layout pageModel page |> Maybe.map (Layouts.map (Main.Pages.Msg.Dash_Secrets_Engine__Org_Org__Name_ >> Page)) |> Maybe.map (initLayout model) @@ -613,12 +612,12 @@ initPageAndLayout model = ( pageModel, pageEffect ) = Page.init page () in - { page = + { page = Tuple.mapBoth (Main.Pages.Model.Dash_Secrets_Engine__Repo_Org__Repo_ params) (Effect.map Main.Pages.Msg.Dash_Secrets_Engine__Repo_Org__Repo_ >> fromPageEffect model) ( pageModel, pageEffect ) - , layout = + , layout = Page.layout pageModel page |> Maybe.map (Layouts.map (Main.Pages.Msg.Dash_Secrets_Engine__Repo_Org__Repo_ >> Page)) |> Maybe.map (initLayout model) @@ -637,12 +636,12 @@ initPageAndLayout model = ( pageModel, pageEffect ) = Page.init page () in - { page = + { page = Tuple.mapBoth (Main.Pages.Model.Dash_Secrets_Engine__Repo_Org__Repo__Add params) (Effect.map Main.Pages.Msg.Dash_Secrets_Engine__Repo_Org__Repo__Add >> fromPageEffect model) ( pageModel, pageEffect ) - , layout = + , layout = Page.layout pageModel page |> Maybe.map (Layouts.map (Main.Pages.Msg.Dash_Secrets_Engine__Repo_Org__Repo__Add >> Page)) |> Maybe.map (initLayout model) @@ -661,12 +660,12 @@ initPageAndLayout model = ( pageModel, pageEffect ) = Page.init page () in - { page = + { page = Tuple.mapBoth (Main.Pages.Model.Dash_Secrets_Engine__Repo_Org__Repo__Name_ params) (Effect.map Main.Pages.Msg.Dash_Secrets_Engine__Repo_Org__Repo__Name_ >> fromPageEffect model) ( pageModel, pageEffect ) - , layout = + , layout = Page.layout pageModel page |> Maybe.map (Layouts.map (Main.Pages.Msg.Dash_Secrets_Engine__Repo_Org__Repo__Name_ >> Page)) |> Maybe.map (initLayout model) @@ -685,12 +684,12 @@ initPageAndLayout model = ( pageModel, pageEffect ) = Page.init page () in - { page = + { page = Tuple.mapBoth (Main.Pages.Model.Dash_Secrets_Engine__Shared_Org__Team_ params) (Effect.map Main.Pages.Msg.Dash_Secrets_Engine__Shared_Org__Team_ >> fromPageEffect model) ( pageModel, pageEffect ) - , layout = + , layout = Page.layout pageModel page |> Maybe.map (Layouts.map (Main.Pages.Msg.Dash_Secrets_Engine__Shared_Org__Team_ >> Page)) |> Maybe.map (initLayout model) @@ -709,12 +708,12 @@ initPageAndLayout model = ( pageModel, pageEffect ) = Page.init page () in - { page = + { page = Tuple.mapBoth (Main.Pages.Model.Dash_Secrets_Engine__Shared_Org__Team__Add params) (Effect.map Main.Pages.Msg.Dash_Secrets_Engine__Shared_Org__Team__Add >> fromPageEffect model) ( pageModel, pageEffect ) - , layout = + , layout = Page.layout pageModel page |> Maybe.map (Layouts.map (Main.Pages.Msg.Dash_Secrets_Engine__Shared_Org__Team__Add >> Page)) |> Maybe.map (initLayout model) @@ -733,18 +732,42 @@ initPageAndLayout model = ( pageModel, pageEffect ) = Page.init page () in - { page = + { page = Tuple.mapBoth (Main.Pages.Model.Dash_Secrets_Engine__Shared_Org__Team__Name_ params) (Effect.map Main.Pages.Msg.Dash_Secrets_Engine__Shared_Org__Team__Name_ >> fromPageEffect model) ( pageModel, pageEffect ) - , layout = + , layout = Page.layout pageModel page |> Maybe.map (Layouts.map (Main.Pages.Msg.Dash_Secrets_Engine__Shared_Org__Team__Name_ >> Page)) |> Maybe.map (initLayout model) } ) + Route.Path.Dashboards -> + runWhenAuthenticatedWithLayout + model + (\user -> + let + page : Page.Page Pages.Dashboards.Model Pages.Dashboards.Msg + page = + Pages.Dashboards.page user model.shared (Route.fromUrl () model.url) + + ( pageModel, pageEffect ) = + Page.init page () + in + { page = + Tuple.mapBoth + Main.Pages.Model.Dashboards + (Effect.map Main.Pages.Msg.Dashboards >> fromPageEffect model) + ( pageModel, pageEffect ) + , layout = + Page.layout pageModel page + |> Maybe.map (Layouts.map (Main.Pages.Msg.Dashboards >> Page)) + |> Maybe.map (initLayout model) + } + ) + Route.Path.Dashboards_Dashboard_ params -> runWhenAuthenticatedWithLayout model @@ -757,12 +780,12 @@ initPageAndLayout model = ( pageModel, pageEffect ) = Page.init page () in - { page = + { page = Tuple.mapBoth (Main.Pages.Model.Dashboards_Dashboard_ params) (Effect.map Main.Pages.Msg.Dashboards_Dashboard_ >> fromPageEffect model) ( pageModel, pageEffect ) - , layout = + , layout = Page.layout pageModel page |> Maybe.map (Layouts.map (Main.Pages.Msg.Dashboards_Dashboard_ >> Page)) |> Maybe.map (initLayout model) @@ -781,12 +804,12 @@ initPageAndLayout model = ( pageModel, pageEffect ) = Page.init page () in - { page = + { page = Tuple.mapBoth (Main.Pages.Model.Org_ params) (Effect.map Main.Pages.Msg.Org_ >> fromPageEffect model) ( pageModel, pageEffect ) - , layout = + , layout = Page.layout pageModel page |> Maybe.map (Layouts.map (Main.Pages.Msg.Org_ >> Page)) |> Maybe.map (initLayout model) @@ -805,12 +828,12 @@ initPageAndLayout model = ( pageModel, pageEffect ) = Page.init page () in - { page = + { page = Tuple.mapBoth (Main.Pages.Model.Org__Builds params) (Effect.map Main.Pages.Msg.Org__Builds >> fromPageEffect model) ( pageModel, pageEffect ) - , layout = + , layout = Page.layout pageModel page |> Maybe.map (Layouts.map (Main.Pages.Msg.Org__Builds >> Page)) |> Maybe.map (initLayout model) @@ -829,12 +852,12 @@ initPageAndLayout model = ( pageModel, pageEffect ) = Page.init page () in - { page = + { page = Tuple.mapBoth (Main.Pages.Model.Org__Repo_ params) (Effect.map Main.Pages.Msg.Org__Repo_ >> fromPageEffect model) ( pageModel, pageEffect ) - , layout = + , layout = Page.layout pageModel page |> Maybe.map (Layouts.map (Main.Pages.Msg.Org__Repo_ >> Page)) |> Maybe.map (initLayout model) @@ -853,12 +876,12 @@ initPageAndLayout model = ( pageModel, pageEffect ) = Page.init page () in - { page = + { page = Tuple.mapBoth (Main.Pages.Model.Org__Repo__Deployments params) (Effect.map Main.Pages.Msg.Org__Repo__Deployments >> fromPageEffect model) ( pageModel, pageEffect ) - , layout = + , layout = Page.layout pageModel page |> Maybe.map (Layouts.map (Main.Pages.Msg.Org__Repo__Deployments >> Page)) |> Maybe.map (initLayout model) @@ -877,12 +900,12 @@ initPageAndLayout model = ( pageModel, pageEffect ) = Page.init page () in - { page = + { page = Tuple.mapBoth (Main.Pages.Model.Org__Repo__Deployments_Add params) (Effect.map Main.Pages.Msg.Org__Repo__Deployments_Add >> fromPageEffect model) ( pageModel, pageEffect ) - , layout = + , layout = Page.layout pageModel page |> Maybe.map (Layouts.map (Main.Pages.Msg.Org__Repo__Deployments_Add >> Page)) |> Maybe.map (initLayout model) @@ -901,12 +924,12 @@ initPageAndLayout model = ( pageModel, pageEffect ) = Page.init page () in - { page = + { page = Tuple.mapBoth (Main.Pages.Model.Org__Repo__Hooks params) (Effect.map Main.Pages.Msg.Org__Repo__Hooks >> fromPageEffect model) ( pageModel, pageEffect ) - , layout = + , layout = Page.layout pageModel page |> Maybe.map (Layouts.map (Main.Pages.Msg.Org__Repo__Hooks >> Page)) |> Maybe.map (initLayout model) @@ -922,12 +945,12 @@ initPageAndLayout model = ( pageModel, pageEffect ) = Page.init page () in - { page = + { page = Tuple.mapBoth (Main.Pages.Model.Org__Repo__Pulls params) (Effect.map Main.Pages.Msg.Org__Repo__Pulls >> fromPageEffect model) ( pageModel, pageEffect ) - , layout = + , layout = Page.layout pageModel page |> Maybe.map (Layouts.map (Main.Pages.Msg.Org__Repo__Pulls >> Page)) |> Maybe.map (initLayout model) @@ -945,12 +968,12 @@ initPageAndLayout model = ( pageModel, pageEffect ) = Page.init page () in - { page = + { page = Tuple.mapBoth (Main.Pages.Model.Org__Repo__Schedules params) (Effect.map Main.Pages.Msg.Org__Repo__Schedules >> fromPageEffect model) ( pageModel, pageEffect ) - , layout = + , layout = Page.layout pageModel page |> Maybe.map (Layouts.map (Main.Pages.Msg.Org__Repo__Schedules >> Page)) |> Maybe.map (initLayout model) @@ -969,12 +992,12 @@ initPageAndLayout model = ( pageModel, pageEffect ) = Page.init page () in - { page = + { page = Tuple.mapBoth (Main.Pages.Model.Org__Repo__Schedules_Add params) (Effect.map Main.Pages.Msg.Org__Repo__Schedules_Add >> fromPageEffect model) ( pageModel, pageEffect ) - , layout = + , layout = Page.layout pageModel page |> Maybe.map (Layouts.map (Main.Pages.Msg.Org__Repo__Schedules_Add >> Page)) |> Maybe.map (initLayout model) @@ -993,12 +1016,12 @@ initPageAndLayout model = ( pageModel, pageEffect ) = Page.init page () in - { page = + { page = Tuple.mapBoth (Main.Pages.Model.Org__Repo__Schedules_Name_ params) (Effect.map Main.Pages.Msg.Org__Repo__Schedules_Name_ >> fromPageEffect model) ( pageModel, pageEffect ) - , layout = + , layout = Page.layout pageModel page |> Maybe.map (Layouts.map (Main.Pages.Msg.Org__Repo__Schedules_Name_ >> Page)) |> Maybe.map (initLayout model) @@ -1017,12 +1040,12 @@ initPageAndLayout model = ( pageModel, pageEffect ) = Page.init page () in - { page = + { page = Tuple.mapBoth (Main.Pages.Model.Org__Repo__Settings params) (Effect.map Main.Pages.Msg.Org__Repo__Settings >> fromPageEffect model) ( pageModel, pageEffect ) - , layout = + , layout = Page.layout pageModel page |> Maybe.map (Layouts.map (Main.Pages.Msg.Org__Repo__Settings >> Page)) |> Maybe.map (initLayout model) @@ -1038,12 +1061,12 @@ initPageAndLayout model = ( pageModel, pageEffect ) = Page.init page () in - { page = + { page = Tuple.mapBoth (Main.Pages.Model.Org__Repo__Tags params) (Effect.map Main.Pages.Msg.Org__Repo__Tags >> fromPageEffect model) ( pageModel, pageEffect ) - , layout = + , layout = Page.layout pageModel page |> Maybe.map (Layouts.map (Main.Pages.Msg.Org__Repo__Tags >> Page)) |> Maybe.map (initLayout model) @@ -1061,12 +1084,12 @@ initPageAndLayout model = ( pageModel, pageEffect ) = Page.init page () in - { page = + { page = Tuple.mapBoth (Main.Pages.Model.Org__Repo__Build_ params) (Effect.map Main.Pages.Msg.Org__Repo__Build_ >> fromPageEffect model) ( pageModel, pageEffect ) - , layout = + , layout = Page.layout pageModel page |> Maybe.map (Layouts.map (Main.Pages.Msg.Org__Repo__Build_ >> Page)) |> Maybe.map (initLayout model) @@ -1085,12 +1108,12 @@ initPageAndLayout model = ( pageModel, pageEffect ) = Page.init page () in - { page = + { page = Tuple.mapBoth (Main.Pages.Model.Org__Repo__Build__Graph params) (Effect.map Main.Pages.Msg.Org__Repo__Build__Graph >> fromPageEffect model) ( pageModel, pageEffect ) - , layout = + , layout = Page.layout pageModel page |> Maybe.map (Layouts.map (Main.Pages.Msg.Org__Repo__Build__Graph >> Page)) |> Maybe.map (initLayout model) @@ -1109,12 +1132,12 @@ initPageAndLayout model = ( pageModel, pageEffect ) = Page.init page () in - { page = + { page = Tuple.mapBoth (Main.Pages.Model.Org__Repo__Build__Pipeline params) (Effect.map Main.Pages.Msg.Org__Repo__Build__Pipeline >> fromPageEffect model) ( pageModel, pageEffect ) - , layout = + , layout = Page.layout pageModel page |> Maybe.map (Layouts.map (Main.Pages.Msg.Org__Repo__Build__Pipeline >> Page)) |> Maybe.map (initLayout model) @@ -1133,12 +1156,12 @@ initPageAndLayout model = ( pageModel, pageEffect ) = Page.init page () in - { page = + { page = Tuple.mapBoth (Main.Pages.Model.Org__Repo__Build__Services params) (Effect.map Main.Pages.Msg.Org__Repo__Build__Services >> fromPageEffect model) ( pageModel, pageEffect ) - , layout = + , layout = Page.layout pageModel page |> Maybe.map (Layouts.map (Main.Pages.Msg.Org__Repo__Build__Services >> Page)) |> Maybe.map (initLayout model) @@ -1154,12 +1177,12 @@ initPageAndLayout model = ( pageModel, pageEffect ) = Page.init page () in - { page = + { page = Tuple.mapBoth Main.Pages.Model.NotFound_ (Effect.map Main.Pages.Msg.NotFound_ >> fromPageEffect model) ( pageModel, pageEffect ) - , layout = + , layout = Page.layout pageModel page |> Maybe.map (Layouts.map (Main.Pages.Msg.NotFound_ >> Page)) |> Maybe.map (initLayout model) @@ -1198,7 +1221,7 @@ runWhenAuthenticatedWithLayout model toRecord = toRecord user Auth.Action.LoadCustomPage -> - { page = + { page = ( Main.Pages.Model.Loading_ , Cmd.none ) @@ -1206,35 +1229,35 @@ runWhenAuthenticatedWithLayout model toRecord = } Auth.Action.ReplaceRoute options -> - { page = + { page = ( Main.Pages.Model.Redirecting_ , Cmd.batch - [ toCmd (Effect.replaceRoute options) - , Maybe.Extra.unwrap - Cmd.none - (\from -> Interop.setRedirect <| Json.Encode.string from) - (Dict.get "from" options.query) - ] + [ toCmd (Effect.replaceRoute options) + , Maybe.Extra.unwrap + Cmd.none + (\from -> Interop.setRedirect <| Json.Encode.string from) + (Dict.get "from" options.query) + ] ) , layout = Nothing } Auth.Action.PushRoute options -> - { page = + { page = ( Main.Pages.Model.Redirecting_ , Cmd.batch - [ toCmd (Effect.pushRoute options) - , Maybe.Extra.unwrap - Cmd.none - (\from -> Interop.setRedirect <| Json.Encode.string from) - (Dict.get "from" options.query) - ] + [ toCmd (Effect.pushRoute options) + , Maybe.Extra.unwrap + Cmd.none + (\from -> Interop.setRedirect <| Json.Encode.string from) + (Dict.get "from" options.query) + ] ) , layout = Nothing } Auth.Action.LoadExternalUrl externalUrl -> - { page = + { page = ( Main.Pages.Model.Redirecting_ , Browser.Navigation.load externalUrl ) @@ -1281,16 +1304,15 @@ update msg model = in ( newModel , Cmd.batch - [ toPageUrlHookCmd newModel - { from = Route.fromUrl () model.url - , to = Route.fromUrl () newModel.url - } - , toLayoutUrlHookCmd model - newModel - { from = Route.fromUrl () model.url - , to = Route.fromUrl () newModel.url - } - ] + [ toPageUrlHookCmd newModel + { from = Route.fromUrl () model.url + , to = Route.fromUrl () newModel.url + } + , toLayoutUrlHookCmd model newModel + { from = Route.fromUrl () model.url + , to = Route.fromUrl () newModel.url + } + ] ) else @@ -1314,14 +1336,13 @@ update msg model = in ( newModel , Cmd.batch - [ pageCmd - , layoutCmd - , toLayoutUrlHookCmd model - newModel - { from = Route.fromUrl () model.url - , to = Route.fromUrl () newModel.url - } - ] + [ pageCmd + , layoutCmd + , toLayoutUrlHookCmd model newModel + { from = Route.fromUrl () model.url + , to = Route.fromUrl () newModel.url + } + ] ) Page pageMsg -> @@ -1352,7 +1373,7 @@ update msg model = , Auth.onPageLoad sharedModel (Route.fromUrl () model.url) ) in - if isAuthProtected (Route.fromUrl () model.url).path && hasActionTypeChanged oldAction newAction then + if isAuthProtected (Route.fromUrl () model.url).path && (hasActionTypeChanged oldAction newAction) then let { layout, page } = initPageAndLayout { key = model.key, shared = sharedModel, url = model.url, layout = model.layout } @@ -1367,10 +1388,10 @@ update msg model = in ( { model | shared = sharedModel, page = pageModel, layout = layoutModel } , Cmd.batch - [ pageCmd - , layoutCmd - , fromSharedEffect { model | shared = sharedModel } sharedEffect - ] + [ pageCmd + , layoutCmd + , fromSharedEffect { model | shared = sharedModel } sharedEffect + ] ) else @@ -1381,8 +1402,8 @@ update msg model = Batch messages -> ( model , messages - |> List.map (Task.succeed >> Task.perform identity) - |> Cmd.batch + |> List.map (Task.succeed >> Task.perform identity) + |> Cmd.batch ) @@ -1527,6 +1548,16 @@ updateFromPage msg model = (Page.update (Pages.Dash.Secrets.Engine_.Shared.Org_.Team_.Name_.page user model.shared (Route.fromUrl params model.url)) pageMsg pageModel) ) + ( Main.Pages.Msg.Dashboards pageMsg, Main.Pages.Model.Dashboards pageModel ) -> + runWhenAuthenticated + model + (\user -> + Tuple.mapBoth + Main.Pages.Model.Dashboards + (Effect.map Main.Pages.Msg.Dashboards >> fromPageEffect model) + (Page.update (Pages.Dashboards.page user model.shared (Route.fromUrl () model.url)) pageMsg pageModel) + ) + ( Main.Pages.Msg.Dashboards_Dashboard_ pageMsg, Main.Pages.Model.Dashboards_Dashboard_ params pageModel ) -> runWhenAuthenticated model @@ -1865,6 +1896,12 @@ toLayoutFromPage model = |> Maybe.andThen (Page.layout pageModel) |> Maybe.map (Layouts.map (Main.Pages.Msg.Dash_Secrets_Engine__Shared_Org__Team__Name_ >> Page)) + Main.Pages.Model.Dashboards pageModel -> + Route.fromUrl () model.url + |> toAuthProtectedPage model Pages.Dashboards.page + |> Maybe.andThen (Page.layout pageModel) + |> Maybe.map (Layouts.map (Main.Pages.Msg.Dashboards >> Page)) + Main.Pages.Model.Dashboards_Dashboard_ params pageModel -> Route.fromUrl params model.url |> toAuthProtectedPage model Pages.Dashboards.Dashboard_.page @@ -2008,7 +2045,7 @@ hasActionTypeChanged oldAction newAction = ( Auth.Action.LoadExternalUrl _, Auth.Action.LoadExternalUrl _ ) -> False - ( _, _ ) -> + ( _, _ ) -> True @@ -2141,6 +2178,15 @@ subscriptions model = ) (Auth.onPageLoad model.shared (Route.fromUrl () model.url)) + Main.Pages.Model.Dashboards pageModel -> + Auth.Action.subscriptions + (\user -> + Page.subscriptions (Pages.Dashboards.page user model.shared (Route.fromUrl () model.url)) pageModel + |> Sub.map Main.Pages.Msg.Dashboards + |> Sub.map Page + ) + (Auth.onPageLoad model.shared (Route.fromUrl () model.url)) + Main.Pages.Model.Dashboards_Dashboard_ params pageModel -> Auth.Action.subscriptions (\user -> @@ -2321,11 +2367,11 @@ subscriptions model = in Sub.batch [ Layout.subscriptions (Layouts.Default.layout defaultProps model.shared route) layoutModel.default - |> Sub.map Main.Layouts.Msg.Default - |> Sub.map Layout + |> Sub.map Main.Layouts.Msg.Default + |> Sub.map Layout , Layout.subscriptions (Layouts.Default.Build.layout props model.shared route) layoutModel.build - |> Sub.map Main.Layouts.Msg.Default_Build - |> Sub.map Layout + |> Sub.map Main.Layouts.Msg.Default_Build + |> Sub.map Layout ] ( Just (Layouts.Default_Org props), Just (Main.Layouts.Model.Default_Org layoutModel) ) -> @@ -2336,11 +2382,11 @@ subscriptions model = in Sub.batch [ Layout.subscriptions (Layouts.Default.layout defaultProps model.shared route) layoutModel.default - |> Sub.map Main.Layouts.Msg.Default - |> Sub.map Layout + |> Sub.map Main.Layouts.Msg.Default + |> Sub.map Layout , Layout.subscriptions (Layouts.Default.Org.layout props model.shared route) layoutModel.org - |> Sub.map Main.Layouts.Msg.Default_Org - |> Sub.map Layout + |> Sub.map Main.Layouts.Msg.Default_Org + |> Sub.map Layout ] ( Just (Layouts.Default_Repo props), Just (Main.Layouts.Model.Default_Repo layoutModel) ) -> @@ -2351,11 +2397,11 @@ subscriptions model = in Sub.batch [ Layout.subscriptions (Layouts.Default.layout defaultProps model.shared route) layoutModel.default - |> Sub.map Main.Layouts.Msg.Default - |> Sub.map Layout + |> Sub.map Main.Layouts.Msg.Default + |> Sub.map Layout , Layout.subscriptions (Layouts.Default.Repo.layout props model.shared route) layoutModel.repo - |> Sub.map Main.Layouts.Msg.Default_Repo - |> Sub.map Layout + |> Sub.map Main.Layouts.Msg.Default_Repo + |> Sub.map Layout ] _ -> @@ -2363,7 +2409,7 @@ subscriptions model = in Sub.batch [ Shared.subscriptions route model.shared - |> Sub.map Shared + |> Sub.map Shared , subscriptionsFromPage , subscriptionsFromLayout ] @@ -2413,7 +2459,7 @@ toView model = (Layouts.Default.layout defaultProps model.shared route) { model = layoutModel.default , toContentMsg = Main.Layouts.Msg.Default >> Layout - , content = + , content = Layout.view (Layouts.Default.Build.layout props model.shared route) { model = layoutModel.build @@ -2432,7 +2478,7 @@ toView model = (Layouts.Default.layout defaultProps model.shared route) { model = layoutModel.default , toContentMsg = Main.Layouts.Msg.Default >> Layout - , content = + , content = Layout.view (Layouts.Default.Org.layout props model.shared route) { model = layoutModel.org @@ -2451,7 +2497,7 @@ toView model = (Layouts.Default.layout defaultProps model.shared route) { model = layoutModel.default , toContentMsg = Main.Layouts.Msg.Default >> Layout - , content = + , content = Layout.view (Layouts.Default.Repo.layout props model.shared route) { model = layoutModel.repo @@ -2590,6 +2636,15 @@ viewPage model = ) (Auth.onPageLoad model.shared (Route.fromUrl () model.url)) + Main.Pages.Model.Dashboards pageModel -> + Auth.Action.view (View.map never (Auth.viewCustomPage model.shared (Route.fromUrl () model.url))) + (\user -> + Page.view (Pages.Dashboards.page user model.shared (Route.fromUrl () model.url)) pageModel + |> View.map Main.Pages.Msg.Dashboards + |> View.map Page + ) + (Auth.onPageLoad model.shared (Route.fromUrl () model.url)) + Main.Pages.Model.Dashboards_Dashboard_ params pageModel -> Auth.Action.view (View.map never (Auth.viewCustomPage model.shared (Route.fromUrl () model.url))) (\user -> @@ -2807,7 +2862,7 @@ toPageUrlHookCmd model routes = Main.Pages.Model.Home_ pageModel -> Auth.Action.command (\user -> - Page.toUrlMessages routes (Pages.Home_.page user model.shared (Route.fromUrl () model.url)) + Page.toUrlMessages routes (Pages.Home_.page user model.shared (Route.fromUrl () model.url)) |> List.map Main.Pages.Msg.Home_ |> List.map Page |> toCommands @@ -2815,19 +2870,19 @@ toPageUrlHookCmd model routes = (Auth.onPageLoad model.shared (Route.fromUrl () model.url)) Main.Pages.Model.Account_Authenticate pageModel -> - Page.toUrlMessages routes (Pages.Account.Authenticate.page model.shared (Route.fromUrl () model.url)) + Page.toUrlMessages routes (Pages.Account.Authenticate.page model.shared (Route.fromUrl () model.url)) |> List.map Main.Pages.Msg.Account_Authenticate |> List.map Page |> toCommands Main.Pages.Model.Account_Login pageModel -> - Page.toUrlMessages routes (Pages.Account.Login.page model.shared (Route.fromUrl () model.url)) + Page.toUrlMessages routes (Pages.Account.Login.page model.shared (Route.fromUrl () model.url)) |> List.map Main.Pages.Msg.Account_Login |> List.map Page |> toCommands Main.Pages.Model.Account_Logout pageModel -> - Page.toUrlMessages routes (Pages.Account.Logout.page model.shared (Route.fromUrl () model.url)) + Page.toUrlMessages routes (Pages.Account.Logout.page model.shared (Route.fromUrl () model.url)) |> List.map Main.Pages.Msg.Account_Logout |> List.map Page |> toCommands @@ -2835,7 +2890,7 @@ toPageUrlHookCmd model routes = Main.Pages.Model.Account_Settings pageModel -> Auth.Action.command (\user -> - Page.toUrlMessages routes (Pages.Account.Settings.page user model.shared (Route.fromUrl () model.url)) + Page.toUrlMessages routes (Pages.Account.Settings.page user model.shared (Route.fromUrl () model.url)) |> List.map Main.Pages.Msg.Account_Settings |> List.map Page |> toCommands @@ -2845,7 +2900,7 @@ toPageUrlHookCmd model routes = Main.Pages.Model.Account_SourceRepos pageModel -> Auth.Action.command (\user -> - Page.toUrlMessages routes (Pages.Account.SourceRepos.page user model.shared (Route.fromUrl () model.url)) + Page.toUrlMessages routes (Pages.Account.SourceRepos.page user model.shared (Route.fromUrl () model.url)) |> List.map Main.Pages.Msg.Account_SourceRepos |> List.map Page |> toCommands @@ -2855,7 +2910,7 @@ toPageUrlHookCmd model routes = Main.Pages.Model.Dash_Secrets_Engine__Org_Org_ params pageModel -> Auth.Action.command (\user -> - Page.toUrlMessages routes (Pages.Dash.Secrets.Engine_.Org.Org_.page user model.shared (Route.fromUrl params model.url)) + Page.toUrlMessages routes (Pages.Dash.Secrets.Engine_.Org.Org_.page user model.shared (Route.fromUrl params model.url)) |> List.map Main.Pages.Msg.Dash_Secrets_Engine__Org_Org_ |> List.map Page |> toCommands @@ -2865,7 +2920,7 @@ toPageUrlHookCmd model routes = Main.Pages.Model.Dash_Secrets_Engine__Org_Org__Add params pageModel -> Auth.Action.command (\user -> - Page.toUrlMessages routes (Pages.Dash.Secrets.Engine_.Org.Org_.Add.page user model.shared (Route.fromUrl params model.url)) + Page.toUrlMessages routes (Pages.Dash.Secrets.Engine_.Org.Org_.Add.page user model.shared (Route.fromUrl params model.url)) |> List.map Main.Pages.Msg.Dash_Secrets_Engine__Org_Org__Add |> List.map Page |> toCommands @@ -2875,7 +2930,7 @@ toPageUrlHookCmd model routes = Main.Pages.Model.Dash_Secrets_Engine__Org_Org__Name_ params pageModel -> Auth.Action.command (\user -> - Page.toUrlMessages routes (Pages.Dash.Secrets.Engine_.Org.Org_.Name_.page user model.shared (Route.fromUrl params model.url)) + Page.toUrlMessages routes (Pages.Dash.Secrets.Engine_.Org.Org_.Name_.page user model.shared (Route.fromUrl params model.url)) |> List.map Main.Pages.Msg.Dash_Secrets_Engine__Org_Org__Name_ |> List.map Page |> toCommands @@ -2885,7 +2940,7 @@ toPageUrlHookCmd model routes = Main.Pages.Model.Dash_Secrets_Engine__Repo_Org__Repo_ params pageModel -> Auth.Action.command (\user -> - Page.toUrlMessages routes (Pages.Dash.Secrets.Engine_.Repo.Org_.Repo_.page user model.shared (Route.fromUrl params model.url)) + Page.toUrlMessages routes (Pages.Dash.Secrets.Engine_.Repo.Org_.Repo_.page user model.shared (Route.fromUrl params model.url)) |> List.map Main.Pages.Msg.Dash_Secrets_Engine__Repo_Org__Repo_ |> List.map Page |> toCommands @@ -2895,7 +2950,7 @@ toPageUrlHookCmd model routes = Main.Pages.Model.Dash_Secrets_Engine__Repo_Org__Repo__Add params pageModel -> Auth.Action.command (\user -> - Page.toUrlMessages routes (Pages.Dash.Secrets.Engine_.Repo.Org_.Repo_.Add.page user model.shared (Route.fromUrl params model.url)) + Page.toUrlMessages routes (Pages.Dash.Secrets.Engine_.Repo.Org_.Repo_.Add.page user model.shared (Route.fromUrl params model.url)) |> List.map Main.Pages.Msg.Dash_Secrets_Engine__Repo_Org__Repo__Add |> List.map Page |> toCommands @@ -2905,7 +2960,7 @@ toPageUrlHookCmd model routes = Main.Pages.Model.Dash_Secrets_Engine__Repo_Org__Repo__Name_ params pageModel -> Auth.Action.command (\user -> - Page.toUrlMessages routes (Pages.Dash.Secrets.Engine_.Repo.Org_.Repo_.Name_.page user model.shared (Route.fromUrl params model.url)) + Page.toUrlMessages routes (Pages.Dash.Secrets.Engine_.Repo.Org_.Repo_.Name_.page user model.shared (Route.fromUrl params model.url)) |> List.map Main.Pages.Msg.Dash_Secrets_Engine__Repo_Org__Repo__Name_ |> List.map Page |> toCommands @@ -2915,7 +2970,7 @@ toPageUrlHookCmd model routes = Main.Pages.Model.Dash_Secrets_Engine__Shared_Org__Team_ params pageModel -> Auth.Action.command (\user -> - Page.toUrlMessages routes (Pages.Dash.Secrets.Engine_.Shared.Org_.Team_.page user model.shared (Route.fromUrl params model.url)) + Page.toUrlMessages routes (Pages.Dash.Secrets.Engine_.Shared.Org_.Team_.page user model.shared (Route.fromUrl params model.url)) |> List.map Main.Pages.Msg.Dash_Secrets_Engine__Shared_Org__Team_ |> List.map Page |> toCommands @@ -2925,7 +2980,7 @@ toPageUrlHookCmd model routes = Main.Pages.Model.Dash_Secrets_Engine__Shared_Org__Team__Add params pageModel -> Auth.Action.command (\user -> - Page.toUrlMessages routes (Pages.Dash.Secrets.Engine_.Shared.Org_.Team_.Add.page user model.shared (Route.fromUrl params model.url)) + Page.toUrlMessages routes (Pages.Dash.Secrets.Engine_.Shared.Org_.Team_.Add.page user model.shared (Route.fromUrl params model.url)) |> List.map Main.Pages.Msg.Dash_Secrets_Engine__Shared_Org__Team__Add |> List.map Page |> toCommands @@ -2935,17 +2990,27 @@ toPageUrlHookCmd model routes = Main.Pages.Model.Dash_Secrets_Engine__Shared_Org__Team__Name_ params pageModel -> Auth.Action.command (\user -> - Page.toUrlMessages routes (Pages.Dash.Secrets.Engine_.Shared.Org_.Team_.Name_.page user model.shared (Route.fromUrl params model.url)) + Page.toUrlMessages routes (Pages.Dash.Secrets.Engine_.Shared.Org_.Team_.Name_.page user model.shared (Route.fromUrl params model.url)) |> List.map Main.Pages.Msg.Dash_Secrets_Engine__Shared_Org__Team__Name_ |> List.map Page |> toCommands ) (Auth.onPageLoad model.shared (Route.fromUrl () model.url)) + Main.Pages.Model.Dashboards pageModel -> + Auth.Action.command + (\user -> + Page.toUrlMessages routes (Pages.Dashboards.page user model.shared (Route.fromUrl () model.url)) + |> List.map Main.Pages.Msg.Dashboards + |> List.map Page + |> toCommands + ) + (Auth.onPageLoad model.shared (Route.fromUrl () model.url)) + Main.Pages.Model.Dashboards_Dashboard_ params pageModel -> Auth.Action.command (\user -> - Page.toUrlMessages routes (Pages.Dashboards.Dashboard_.page user model.shared (Route.fromUrl params model.url)) + Page.toUrlMessages routes (Pages.Dashboards.Dashboard_.page user model.shared (Route.fromUrl params model.url)) |> List.map Main.Pages.Msg.Dashboards_Dashboard_ |> List.map Page |> toCommands @@ -2955,7 +3020,7 @@ toPageUrlHookCmd model routes = Main.Pages.Model.Org_ params pageModel -> Auth.Action.command (\user -> - Page.toUrlMessages routes (Pages.Org_.page user model.shared (Route.fromUrl params model.url)) + Page.toUrlMessages routes (Pages.Org_.page user model.shared (Route.fromUrl params model.url)) |> List.map Main.Pages.Msg.Org_ |> List.map Page |> toCommands @@ -2965,7 +3030,7 @@ toPageUrlHookCmd model routes = Main.Pages.Model.Org__Builds params pageModel -> Auth.Action.command (\user -> - Page.toUrlMessages routes (Pages.Org_.Builds.page user model.shared (Route.fromUrl params model.url)) + Page.toUrlMessages routes (Pages.Org_.Builds.page user model.shared (Route.fromUrl params model.url)) |> List.map Main.Pages.Msg.Org__Builds |> List.map Page |> toCommands @@ -2975,7 +3040,7 @@ toPageUrlHookCmd model routes = Main.Pages.Model.Org__Repo_ params pageModel -> Auth.Action.command (\user -> - Page.toUrlMessages routes (Pages.Org_.Repo_.page user model.shared (Route.fromUrl params model.url)) + Page.toUrlMessages routes (Pages.Org_.Repo_.page user model.shared (Route.fromUrl params model.url)) |> List.map Main.Pages.Msg.Org__Repo_ |> List.map Page |> toCommands @@ -2985,7 +3050,7 @@ toPageUrlHookCmd model routes = Main.Pages.Model.Org__Repo__Deployments params pageModel -> Auth.Action.command (\user -> - Page.toUrlMessages routes (Pages.Org_.Repo_.Deployments.page user model.shared (Route.fromUrl params model.url)) + Page.toUrlMessages routes (Pages.Org_.Repo_.Deployments.page user model.shared (Route.fromUrl params model.url)) |> List.map Main.Pages.Msg.Org__Repo__Deployments |> List.map Page |> toCommands @@ -2995,7 +3060,7 @@ toPageUrlHookCmd model routes = Main.Pages.Model.Org__Repo__Deployments_Add params pageModel -> Auth.Action.command (\user -> - Page.toUrlMessages routes (Pages.Org_.Repo_.Deployments.Add.page user model.shared (Route.fromUrl params model.url)) + Page.toUrlMessages routes (Pages.Org_.Repo_.Deployments.Add.page user model.shared (Route.fromUrl params model.url)) |> List.map Main.Pages.Msg.Org__Repo__Deployments_Add |> List.map Page |> toCommands @@ -3005,7 +3070,7 @@ toPageUrlHookCmd model routes = Main.Pages.Model.Org__Repo__Hooks params pageModel -> Auth.Action.command (\user -> - Page.toUrlMessages routes (Pages.Org_.Repo_.Hooks.page user model.shared (Route.fromUrl params model.url)) + Page.toUrlMessages routes (Pages.Org_.Repo_.Hooks.page user model.shared (Route.fromUrl params model.url)) |> List.map Main.Pages.Msg.Org__Repo__Hooks |> List.map Page |> toCommands @@ -3013,7 +3078,7 @@ toPageUrlHookCmd model routes = (Auth.onPageLoad model.shared (Route.fromUrl () model.url)) Main.Pages.Model.Org__Repo__Pulls params pageModel -> - Page.toUrlMessages routes (Pages.Org_.Repo_.Pulls.page model.shared (Route.fromUrl params model.url)) + Page.toUrlMessages routes (Pages.Org_.Repo_.Pulls.page model.shared (Route.fromUrl params model.url)) |> List.map Main.Pages.Msg.Org__Repo__Pulls |> List.map Page |> toCommands @@ -3021,7 +3086,7 @@ toPageUrlHookCmd model routes = Main.Pages.Model.Org__Repo__Schedules params pageModel -> Auth.Action.command (\user -> - Page.toUrlMessages routes (Pages.Org_.Repo_.Schedules.page user model.shared (Route.fromUrl params model.url)) + Page.toUrlMessages routes (Pages.Org_.Repo_.Schedules.page user model.shared (Route.fromUrl params model.url)) |> List.map Main.Pages.Msg.Org__Repo__Schedules |> List.map Page |> toCommands @@ -3031,7 +3096,7 @@ toPageUrlHookCmd model routes = Main.Pages.Model.Org__Repo__Schedules_Add params pageModel -> Auth.Action.command (\user -> - Page.toUrlMessages routes (Pages.Org_.Repo_.Schedules.Add.page user model.shared (Route.fromUrl params model.url)) + Page.toUrlMessages routes (Pages.Org_.Repo_.Schedules.Add.page user model.shared (Route.fromUrl params model.url)) |> List.map Main.Pages.Msg.Org__Repo__Schedules_Add |> List.map Page |> toCommands @@ -3041,7 +3106,7 @@ toPageUrlHookCmd model routes = Main.Pages.Model.Org__Repo__Schedules_Name_ params pageModel -> Auth.Action.command (\user -> - Page.toUrlMessages routes (Pages.Org_.Repo_.Schedules.Name_.page user model.shared (Route.fromUrl params model.url)) + Page.toUrlMessages routes (Pages.Org_.Repo_.Schedules.Name_.page user model.shared (Route.fromUrl params model.url)) |> List.map Main.Pages.Msg.Org__Repo__Schedules_Name_ |> List.map Page |> toCommands @@ -3051,7 +3116,7 @@ toPageUrlHookCmd model routes = Main.Pages.Model.Org__Repo__Settings params pageModel -> Auth.Action.command (\user -> - Page.toUrlMessages routes (Pages.Org_.Repo_.Settings.page user model.shared (Route.fromUrl params model.url)) + Page.toUrlMessages routes (Pages.Org_.Repo_.Settings.page user model.shared (Route.fromUrl params model.url)) |> List.map Main.Pages.Msg.Org__Repo__Settings |> List.map Page |> toCommands @@ -3059,7 +3124,7 @@ toPageUrlHookCmd model routes = (Auth.onPageLoad model.shared (Route.fromUrl () model.url)) Main.Pages.Model.Org__Repo__Tags params pageModel -> - Page.toUrlMessages routes (Pages.Org_.Repo_.Tags.page model.shared (Route.fromUrl params model.url)) + Page.toUrlMessages routes (Pages.Org_.Repo_.Tags.page model.shared (Route.fromUrl params model.url)) |> List.map Main.Pages.Msg.Org__Repo__Tags |> List.map Page |> toCommands @@ -3067,7 +3132,7 @@ toPageUrlHookCmd model routes = Main.Pages.Model.Org__Repo__Build_ params pageModel -> Auth.Action.command (\user -> - Page.toUrlMessages routes (Pages.Org_.Repo_.Build_.page user model.shared (Route.fromUrl params model.url)) + Page.toUrlMessages routes (Pages.Org_.Repo_.Build_.page user model.shared (Route.fromUrl params model.url)) |> List.map Main.Pages.Msg.Org__Repo__Build_ |> List.map Page |> toCommands @@ -3077,7 +3142,7 @@ toPageUrlHookCmd model routes = Main.Pages.Model.Org__Repo__Build__Graph params pageModel -> Auth.Action.command (\user -> - Page.toUrlMessages routes (Pages.Org_.Repo_.Build_.Graph.page user model.shared (Route.fromUrl params model.url)) + Page.toUrlMessages routes (Pages.Org_.Repo_.Build_.Graph.page user model.shared (Route.fromUrl params model.url)) |> List.map Main.Pages.Msg.Org__Repo__Build__Graph |> List.map Page |> toCommands @@ -3087,7 +3152,7 @@ toPageUrlHookCmd model routes = Main.Pages.Model.Org__Repo__Build__Pipeline params pageModel -> Auth.Action.command (\user -> - Page.toUrlMessages routes (Pages.Org_.Repo_.Build_.Pipeline.page user model.shared (Route.fromUrl params model.url)) + Page.toUrlMessages routes (Pages.Org_.Repo_.Build_.Pipeline.page user model.shared (Route.fromUrl params model.url)) |> List.map Main.Pages.Msg.Org__Repo__Build__Pipeline |> List.map Page |> toCommands @@ -3097,7 +3162,7 @@ toPageUrlHookCmd model routes = Main.Pages.Model.Org__Repo__Build__Services params pageModel -> Auth.Action.command (\user -> - Page.toUrlMessages routes (Pages.Org_.Repo_.Build_.Services.page user model.shared (Route.fromUrl params model.url)) + Page.toUrlMessages routes (Pages.Org_.Repo_.Build_.Services.page user model.shared (Route.fromUrl params model.url)) |> List.map Main.Pages.Msg.Org__Repo__Build__Services |> List.map Page |> toCommands @@ -3105,7 +3170,7 @@ toPageUrlHookCmd model routes = (Auth.onPageLoad model.shared (Route.fromUrl () model.url)) Main.Pages.Model.NotFound_ pageModel -> - Page.toUrlMessages routes (Pages.NotFound_.page model.shared (Route.fromUrl () model.url)) + Page.toUrlMessages routes (Pages.NotFound_.page model.shared (Route.fromUrl () model.url)) |> List.map Main.Pages.Msg.NotFound_ |> List.map Page |> toCommands @@ -3153,13 +3218,13 @@ toLayoutUrlHookCmd oldModel model routes = in Cmd.batch [ Layout.toUrlMessages routes (Layouts.Default.layout defaultProps model.shared route) - |> List.map Main.Layouts.Msg.Default - |> List.map Layout - |> toCommands + |> List.map Main.Layouts.Msg.Default + |> List.map Layout + |> toCommands , Layout.toUrlMessages routes (Layouts.Default.Build.layout props model.shared route) - |> List.map Main.Layouts.Msg.Default_Build - |> List.map Layout - |> toCommands + |> List.map Main.Layouts.Msg.Default_Build + |> List.map Layout + |> toCommands ] ( Just (Layouts.Default_Org props), Just (Main.Layouts.Model.Default_Org layoutModel) ) -> @@ -3170,13 +3235,13 @@ toLayoutUrlHookCmd oldModel model routes = in Cmd.batch [ Layout.toUrlMessages routes (Layouts.Default.layout defaultProps model.shared route) - |> List.map Main.Layouts.Msg.Default - |> List.map Layout - |> toCommands + |> List.map Main.Layouts.Msg.Default + |> List.map Layout + |> toCommands , Layout.toUrlMessages routes (Layouts.Default.Org.layout props model.shared route) - |> List.map Main.Layouts.Msg.Default_Org - |> List.map Layout - |> toCommands + |> List.map Main.Layouts.Msg.Default_Org + |> List.map Layout + |> toCommands ] ( Just (Layouts.Default_Repo props), Just (Main.Layouts.Model.Default_Repo layoutModel) ) -> @@ -3187,13 +3252,13 @@ toLayoutUrlHookCmd oldModel model routes = in Cmd.batch [ Layout.toUrlMessages routes (Layouts.Default.layout defaultProps model.shared route) - |> List.map Main.Layouts.Msg.Default - |> List.map Layout - |> toCommands + |> List.map Main.Layouts.Msg.Default + |> List.map Layout + |> toCommands , Layout.toUrlMessages routes (Layouts.Default.Repo.layout props model.shared route) - |> List.map Main.Layouts.Msg.Default_Repo - |> List.map Layout - |> toCommands + |> List.map Main.Layouts.Msg.Default_Repo + |> List.map Layout + |> toCommands ] _ -> @@ -3283,6 +3348,9 @@ isAuthProtected routePath = Route.Path.Dash_Secrets_Engine__Shared_Org__Team__Name_ _ -> True + Route.Path.Dashboards -> + True + Route.Path.Dashboards_Dashboard_ _ -> True diff --git a/src/elm/Main/Pages/Model.elm b/src/elm/Main/Pages/Model.elm index 7006b9bc7..b82e27738 100644 --- a/src/elm/Main/Pages/Model.elm +++ b/src/elm/Main/Pages/Model.elm @@ -5,6 +5,7 @@ SPDX-License-Identifier: Apache-2.0 module Main.Pages.Model exposing (Model(..)) +import Pages.Home_ import Pages.Account.Authenticate import Pages.Account.Login import Pages.Account.Logout @@ -19,16 +20,11 @@ import Pages.Dash.Secrets.Engine_.Repo.Org_.Repo_.Name_ import Pages.Dash.Secrets.Engine_.Shared.Org_.Team_ import Pages.Dash.Secrets.Engine_.Shared.Org_.Team_.Add import Pages.Dash.Secrets.Engine_.Shared.Org_.Team_.Name_ +import Pages.Dashboards import Pages.Dashboards.Dashboard_ -import Pages.Home_ -import Pages.NotFound_ import Pages.Org_ import Pages.Org_.Builds import Pages.Org_.Repo_ -import Pages.Org_.Repo_.Build_ -import Pages.Org_.Repo_.Build_.Graph -import Pages.Org_.Repo_.Build_.Pipeline -import Pages.Org_.Repo_.Build_.Services import Pages.Org_.Repo_.Deployments import Pages.Org_.Repo_.Deployments.Add import Pages.Org_.Repo_.Hooks @@ -38,6 +34,11 @@ import Pages.Org_.Repo_.Schedules.Add import Pages.Org_.Repo_.Schedules.Name_ import Pages.Org_.Repo_.Settings import Pages.Org_.Repo_.Tags +import Pages.Org_.Repo_.Build_ +import Pages.Org_.Repo_.Build_.Graph +import Pages.Org_.Repo_.Build_.Pipeline +import Pages.Org_.Repo_.Build_.Services +import Pages.NotFound_ import View exposing (View) @@ -57,7 +58,8 @@ type Model | Dash_Secrets_Engine__Shared_Org__Team_ { engine : String, org : String, team : String } Pages.Dash.Secrets.Engine_.Shared.Org_.Team_.Model | Dash_Secrets_Engine__Shared_Org__Team__Add { engine : String, org : String, team : String } Pages.Dash.Secrets.Engine_.Shared.Org_.Team_.Add.Model | Dash_Secrets_Engine__Shared_Org__Team__Name_ { engine : String, org : String, team : String, name : String } Pages.Dash.Secrets.Engine_.Shared.Org_.Team_.Name_.Model - | Dashboards_Dashboard_ { dashboardId : String } Pages.Dashboards.Dashboard_.Model + | Dashboards Pages.Dashboards.Model + | Dashboards_Dashboard_ { dashboard : String } Pages.Dashboards.Dashboard_.Model | Org_ { org : String } Pages.Org_.Model | Org__Builds { org : String } Pages.Org_.Builds.Model | Org__Repo_ { org : String, repo : String } Pages.Org_.Repo_.Model diff --git a/src/elm/Main/Pages/Msg.elm b/src/elm/Main/Pages/Msg.elm index 33c64f82d..c63d82b45 100644 --- a/src/elm/Main/Pages/Msg.elm +++ b/src/elm/Main/Pages/Msg.elm @@ -5,6 +5,7 @@ SPDX-License-Identifier: Apache-2.0 module Main.Pages.Msg exposing (Msg(..)) +import Pages.Home_ import Pages.Account.Authenticate import Pages.Account.Login import Pages.Account.Logout @@ -19,16 +20,11 @@ import Pages.Dash.Secrets.Engine_.Repo.Org_.Repo_.Name_ import Pages.Dash.Secrets.Engine_.Shared.Org_.Team_ import Pages.Dash.Secrets.Engine_.Shared.Org_.Team_.Add import Pages.Dash.Secrets.Engine_.Shared.Org_.Team_.Name_ +import Pages.Dashboards import Pages.Dashboards.Dashboard_ -import Pages.Home_ -import Pages.NotFound_ import Pages.Org_ import Pages.Org_.Builds import Pages.Org_.Repo_ -import Pages.Org_.Repo_.Build_ -import Pages.Org_.Repo_.Build_.Graph -import Pages.Org_.Repo_.Build_.Pipeline -import Pages.Org_.Repo_.Build_.Services import Pages.Org_.Repo_.Deployments import Pages.Org_.Repo_.Deployments.Add import Pages.Org_.Repo_.Hooks @@ -38,6 +34,11 @@ import Pages.Org_.Repo_.Schedules.Add import Pages.Org_.Repo_.Schedules.Name_ import Pages.Org_.Repo_.Settings import Pages.Org_.Repo_.Tags +import Pages.Org_.Repo_.Build_ +import Pages.Org_.Repo_.Build_.Graph +import Pages.Org_.Repo_.Build_.Pipeline +import Pages.Org_.Repo_.Build_.Services +import Pages.NotFound_ type Msg @@ -56,6 +57,7 @@ type Msg | Dash_Secrets_Engine__Shared_Org__Team_ Pages.Dash.Secrets.Engine_.Shared.Org_.Team_.Msg | Dash_Secrets_Engine__Shared_Org__Team__Add Pages.Dash.Secrets.Engine_.Shared.Org_.Team_.Add.Msg | Dash_Secrets_Engine__Shared_Org__Team__Name_ Pages.Dash.Secrets.Engine_.Shared.Org_.Team_.Name_.Msg + | Dashboards Pages.Dashboards.Msg | Dashboards_Dashboard_ Pages.Dashboards.Dashboard_.Msg | Org_ Pages.Org_.Msg | Org__Builds Pages.Org_.Builds.Msg diff --git a/src/elm/Pages/Dashboards.elm b/src/elm/Pages/Dashboards.elm new file mode 100644 index 000000000..09c63b37f --- /dev/null +++ b/src/elm/Pages/Dashboards.elm @@ -0,0 +1,156 @@ +{-- +SPDX-License-Identifier: Apache-2.0 +--} + + +module Pages.Dashboards exposing (Model, Msg, page) + +import Auth +import Components.Crumbs +import Components.Nav +import Effect exposing (Effect) +import Html exposing (code, h1, h2, main_, p, text) +import Html.Attributes exposing (class) +import Layouts +import Page exposing (Page) +import Route exposing (Route) +import Route.Path +import Shared +import Utils.Helpers as Util +import View exposing (View) + + +{-| page : takes user, shared model, route, and returns the dashboards page. +-} +page : Auth.User -> Shared.Model -> Route () -> Page Model Msg +page user shared route = + Page.new + { init = init shared route + , update = update shared route + , subscriptions = subscriptions + , view = view shared route + } + |> Page.withLayout (toLayout user route) + + + +-- LAYOUT + + +{-| toLayout : takes user, model, and passes the dashboards page info to Layouts. +-} +toLayout : Auth.User -> Route () -> Model -> Layouts.Layout Msg +toLayout user route model = + Layouts.Default + { helpCommands = + [ { name = "List Dashboards" + , content = "vela get dashboards" + , docs = Just "dashboard/get" + } + , { name = "Add Dashboard" + , content = "vela add dashboard --name MyDashboard" + , docs = Just "dashboard/add" + } + , { name = "Add Dashboard With Repositories" + , content = "vela add dashboard --name MyDashboard --repos org1/repo1,org2/repo1" + , docs = Just "dashboard/add" + } + , { name = "Add Dashboard With Repositories And Filters" + , content = "vela add dashboard --name MyDashboard --repos org1/repo1,org2/repo1 --branch main --event push" + , docs = Just "dashboard/add" + } + , { name = "Add Dashboard With Multiple Admins" + , content = "vela add dashboard --name MyDashboard --admins username1,username2" + , docs = Just "dashboard/add" + } + ] + } + + + +-- INIT + + +{-| Model : alias for a model object for the dashboards page. +-} +type alias Model = + {} + + +{-| init : takes shared model and initializes dashboards page input arguments. +-} +init : Shared.Model -> Route () -> () -> ( Model, Effect Msg ) +init shared route () = + ( {} + , Effect.none + ) + + + +-- UPDATE + + +{-| Msg : custom type with possible messages. +-} +type Msg + = NoOp + + +{-| update : takes current model, message, and returns an updated model and effect. +-} +update : Shared.Model -> Route () -> Msg -> Model -> ( Model, Effect Msg ) +update shared route msg model = + case msg of + NoOp -> + ( model + , Effect.none + ) + + + +-- SUBSCRIPTIONS + + +{-| subscriptions : takes model and returns the subscriptions for auto refreshing the page. +-} +subscriptions : Model -> Sub Msg +subscriptions model = + Sub.none + + + +-- VIEW + + +{-| view : takes models, route, and creates the html for the dashboards page. +-} +view : Shared.Model -> Route () -> Model -> View Msg +view shared route model = + let + crumbs = + [ ( "Overview", Just Route.Path.Home_ ) + , ( "Dashboards", Nothing ) + ] + in + { title = "Dashboards" + , body = + [ Components.Nav.view + shared + route + { buttons = [] + , crumbs = Components.Crumbs.view route.path crumbs + } + , main_ [ class "content-wrap", Util.testAttribute "dashboards" ] + [ h1 [] [ text "Welcome to dashboards!" ] + , h2 [] [ text "✨ Want to create a new dashboard?" ] + , p [] [ text "Use the Vela CLI to add a new dashboard:" ] + , code [ class "shell" ] [ text "vela add dashboard --help" ] + , h2 [] [ text "🚀 Already have a dashboard?" ] + , p [] [ text "Check your available dashboards with:" ] + , code [ class "shell" ] [ text "vela get dashboards" ] + , p [] [ text "Take note of your dashboard ID you are interested in and and add it to the current URL to view it." ] + , h2 [] [ text "💬 Got Feedback?" ] + , p [] [ text "Follow the link in the top right to let us know your thoughts and ideas." ] + ] + ] + } diff --git a/src/elm/Pages/Dashboards/Dashboard_.elm b/src/elm/Pages/Dashboards/Dashboard_.elm index 4267f349c..68c978475 100644 --- a/src/elm/Pages/Dashboards/Dashboard_.elm +++ b/src/elm/Pages/Dashboards/Dashboard_.elm @@ -39,7 +39,9 @@ import Vela import View exposing (View) -page : Auth.User -> Shared.Model -> Route { dashboardId : String } -> Page Model Msg +{-| page : takes user, shared model, route, and returns the dashboard page. +-} +page : Auth.User -> Shared.Model -> Route { dashboard : String } -> Page Model Msg page user shared route = Page.new { init = init shared route @@ -54,13 +56,38 @@ page user shared route = -- LAYOUT -toLayout : Auth.User -> Route { dashboardId : String } -> Model -> Layouts.Layout Msg +{-| toLayout : takes user, model, and passes the dashboard page info to Layouts. +-} +toLayout : Auth.User -> Route { dashboard : String } -> Model -> Layouts.Layout Msg toLayout user route model = Layouts.Default { helpCommands = - [ { name = "" - , content = "resources on this page not yet supported via the CLI" - , docs = Nothing + [ { name = "View Dashboard" + , content = + "vela view dashboard --id " + ++ route.params.dashboard + , docs = Just "dashboard/view" + } + , { name = "Update Dashboard To Change Name" + , content = + "vela update dashboard --id " + ++ route.params.dashboard + ++ " --name new-name" + , docs = Just "dashboard/update" + } + , { name = "Update Dashboard To Add A Repository" + , content = + "vela update dashboard --id " + ++ route.params.dashboard + ++ " --add-repos org/repo" + , docs = Just "dashboard/update" + } + , { name = "Update Dashboard To Add An Admin" + , content = + "vela update dashboard --id " + ++ route.params.dashboard + ++ " --add-admins username" + , docs = Just "dashboard/update" } ] } @@ -70,19 +97,22 @@ toLayout user route model = -- INIT +{-| Model : alias for a model object for the dashboard page. +-} type alias Model = { dashboard : WebData Vela.Dashboard } -init : Shared.Model -> Route { dashboardId : String } -> () -> ( Model, Effect Msg ) +{-| init : takes shared model and initializes dashboard page input arguments. +-} +init : Shared.Model -> Route { dashboard : String } -> () -> ( Model, Effect Msg ) init shared route () = ( { dashboard = RemoteData.Loading } , Effect.getDashboard { baseUrl = shared.velaAPIBaseURL , session = shared.session - , onResponse = - GetDashboardResponse - , dashboardId = route.params.dashboardId + , onResponse = GetDashboardResponse + , dashboardId = route.params.dashboard } ) @@ -91,13 +121,17 @@ init shared route () = -- UPDATE +{-| Msg : custom type with possible messages. +-} type Msg = GetDashboardResponse (Result (Http.Detailed.Error String) ( Http.Metadata, Vela.Dashboard )) -- REFRESH | Tick { time : Time.Posix, interval : Interval.Interval } -update : Shared.Model -> Route { dashboardId : String } -> Msg -> Model -> ( Model, Effect Msg ) +{-| update : takes current model, message, and returns an updated model and effect. +-} +update : Shared.Model -> Route { dashboard : String } -> Msg -> Model -> ( Model, Effect Msg ) update shared route msg model = case msg of GetDashboardResponse response -> @@ -121,7 +155,7 @@ update shared route msg model = { baseUrl = shared.velaAPIBaseURL , session = shared.session , onResponse = GetDashboardResponse - , dashboardId = route.params.dashboardId + , dashboardId = route.params.dashboard } ) @@ -130,6 +164,8 @@ update shared route msg model = -- SUBSCRIPTIONS +{-| subscriptions : takes model and returns the subscriptions for auto refreshing the page. +-} subscriptions : Model -> Sub Msg subscriptions model = Sub.batch @@ -141,16 +177,32 @@ subscriptions model = -- VIEW -view : Shared.Model -> Route { dashboardId : String } -> Model -> View Msg +{-| view : takes models, route, and creates the html for the dashboard page. +-} +view : Shared.Model -> Route { dashboard : String } -> Model -> View Msg view shared route model = let + dashboardName = + case model.dashboard of + RemoteData.Success dashboard -> + dashboard.dashboard.name + + RemoteData.Loading -> + "" + + _ -> + "Unknown" + + pageTitle = + dashboardName ++ " Dashboard" + crumbs = [ ( "Overview", Just Route.Path.Home_ ) , ( "Dashboards", Nothing ) - , ( route.params.dashboardId, Nothing ) + , ( dashboardName, Nothing ) ] in - { title = "Dashboards" + { title = pageTitle , body = [ Components.Nav.view shared @@ -160,23 +212,29 @@ view shared route model = } , main_ [ class "content-wrap" ] [ div [ class "dashboard", Util.testAttribute "dashboard" ] - [ case model.dashboard of + (case model.dashboard of RemoteData.Success dashboard -> - div [] - [ h1 [ class "dashboard-title" ] [ text dashboard.dashboard.name ] - , div [ class "cards" ] - (List.map + [ h1 [ class "dashboard-title" ] [ text dashboard.dashboard.name ] + , div [ class "cards" ] + (if List.isEmpty dashboard.repos then + [ span + [] + [ text "This dashboard doesn't have repositories added yet." ] + ] + + else + List.map (\repo -> Components.DashboardRepoCard.view shared { card = repo } ) dashboard.repos - ) - ] + ) + ] RemoteData.Failure error -> - span [] + [ span [] [ text <| case error of Http.BadStatus statusCode -> @@ -185,7 +243,7 @@ view shared route model = "Unauthorized to retrieve dashboard" 404 -> - "No dashboard found" + "Dashboard \"" ++ route.params.dashboard ++ "\" not found. Please check the URL." _ -> "No dashboard found; there was an error with the server" @@ -193,10 +251,11 @@ view shared route model = _ -> "No dashboard found; there was an error with the server" ] + ] _ -> - Components.Loading.viewSmallLoader - ] + [ Components.Loading.viewSmallLoader ] + ) ] ] } diff --git a/src/elm/Route.elm b/src/elm/Route.elm index 9468bbafb..aaa807a92 100644 --- a/src/elm/Route.elm +++ b/src/elm/Route.elm @@ -44,6 +44,6 @@ toString route = [ Route.Path.toString route.path , Route.Query.toString route.query , route.hash - |> Maybe.map (String.append "#") - |> Maybe.withDefault "" + |> Maybe.map (String.append "#") + |> Maybe.withDefault "" ] diff --git a/src/elm/Route/Path.elm b/src/elm/Route/Path.elm index 15473d3ac..09d42269c 100644 --- a/src/elm/Route/Path.elm +++ b/src/elm/Route/Path.elm @@ -27,7 +27,8 @@ type Path | Dash_Secrets_Engine__Shared_Org__Team_ { engine : String, org : String, team : String } | Dash_Secrets_Engine__Shared_Org__Team__Add { engine : String, org : String, team : String } | Dash_Secrets_Engine__Shared_Org__Team__Name_ { engine : String, org : String, team : String, name : String } - | Dashboards_Dashboard_ { dashboardId : String } + | Dashboards + | Dashboards_Dashboard_ { dashboard : String } | Org_ { org : String } | Org__Builds { org : String } | Org__Repo_ { org : String, repo : String } @@ -153,9 +154,12 @@ fromString urlPath = } |> Just + "dashboards" :: [] -> + Just Dashboards + "dashboards" :: dashboard_ :: [] -> Dashboards_Dashboard_ - { dashboardId = dashboard_ + { dashboard = dashboard_ } |> Just @@ -334,8 +338,11 @@ toString path = Dash_Secrets_Engine__Shared_Org__Team__Name_ params -> [ "-", "secrets", params.engine, "shared", params.org, params.team, params.name ] + Dashboards -> + [ "dashboards" ] + Dashboards_Dashboard_ params -> - [ "dashboards", params.dashboardId ] + [ "dashboards", params.dashboard ] Org_ params -> [ params.org ] diff --git a/src/elm/Route/Query.elm b/src/elm/Route/Query.elm index 0cfabb738..d7ecd4991 100644 --- a/src/elm/Route/Query.elm +++ b/src/elm/Route/Query.elm @@ -7,8 +7,8 @@ module Route.Query exposing (fromUrl, toString) import Dict exposing (Dict) import Url exposing (Url) -import Url.Builder exposing (QueryParameter) import Url.Parser exposing (query) +import Url.Builder exposing (QueryParameter) fromUrl : Url -> Dict String String @@ -28,7 +28,7 @@ fromUrl url = |> Dict.fromList -queryPiecesToTuple : List String -> Maybe ( String, String ) +queryPiecesToTuple : List String -> Maybe (String, String) queryPiecesToTuple pieces = case pieces of [] -> @@ -55,6 +55,6 @@ toString queryParameterList = |> Url.Builder.toQuery -tupleToQueryPiece : ( String, String ) -> QueryParameter +tupleToQueryPiece : (String, String) -> QueryParameter tupleToQueryPiece ( key, value ) = Url.Builder.string key value diff --git a/src/scss/_dashboards.scss b/src/scss/_dashboards.scss index 3b9be8c43..f4b5325bd 100644 --- a/src/scss/_dashboards.scss +++ b/src/scss/_dashboards.scss @@ -1,4 +1,3 @@ - // SPDX-License-Identifier: Apache-2.0 // styles for the dashboard pages @@ -7,190 +6,220 @@ border-bottom: var(--line-width) solid var(--color-secondary); } -.dashboard { - -} - +// holds all the dashboard cards .cards { display: flex; flex-wrap: wrap; } +// an individual dashboard card .card { - flex: 0 0 26rem; + flex: 0 0 27rem; margin-right: 2rem; margin-bottom: 2rem; - padding: .5rem; + padding: 0.5rem; background-color: var(--color-bg-dark); } -.card-org-repo { +// a dashboard card header containing org, repo, and status icon +.card-header { display: flex; + gap: 1rem; align-items: center; - gap: .5rem; - line-height: 1.25; - width: calc(100% + 1rem); margin: -0.5rem -0.5rem 0 -0.5rem; // to ignore .card padding padding: 0 1rem; + line-height: 1.25; + background-color: var(--color-bg-darkest); + // custon styling for the status icon .-icon { width: 2.5rem; height: 2.5rem; - + &.-pending { background-color: var(--color-bg-light); + stroke: var(--color-bg-darkest); } &.-running { background-color: var(--color-yellow); + stroke: var(--color-bg-darkest); - } + } &.-success { background-color: var(--color-green); - stroke: var(--color-bg-darkest); - } - &.-failure { - background-color: var(--color-red); stroke: var(--color-bg-darkest); } &.-canceled { background-color: var(--color-cyan-dark); + stroke: var(--color-bg-darkest); } + &.-failure, &.-error { background-color: var(--color-red); + stroke: var(--color-bg-darkest); } } } -.card-org { - font-size: smaller; - padding-left: .5rem; -} - -.card-repo { - font-weight: bold; - padding-left: .5rem; -} - -.card-repo-truncate-text { - display: inline-block; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - max-width: 25ch; -} - -.card-icon-nothing { - background-color: var(--color-coal-light); +// truncate repo name to avoid overflow +// max characters for repo is 100 on GitHub +.card-repo.-truncate { + @include truncate(25, false); } .card-build-data { + margin: 0; + padding: 0.5rem; + columns: 2; - column-gap: 0rem; + column-gap: 0; + list-style-type: none; - padding: 0.5rem; - margin: 0; } +// styling for the build data list items .card-build-data li { display: flex; - margin: 0; + gap: 0.5rem; align-items: center; - gap: .5rem; + margin: 0; + // add vertical padding to list items, + // except the last one because it will throw off spacing &:not(:last-child) { - margin-bottom: .5rem; + margin-bottom: 0.5rem; } + // 4th+ list item are right aligned &:nth-child(n + 4) { - justify-content: right; + justify-content: flex-end; } - .card-truncate-text { - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - max-width: 15ch; + // all nodes other than the icon are truncated + :not(svg) { + @include truncate(); } } +// wraps the recent builds component .dashboard-recent-builds { margin: 0.5rem; - background-color: var(--color-bg-dark); + // modifier for recent builds if there are no builds yet + &.-none { + display: flex; + align-items: center; + justify-content: center; + height: 5rem; - .recent-build:first-child .recent-build-link.-current{ - margin: 0; + background-color: var(--color-bg-darkest); } - .recent-build:first-child .-icon{ - stroke-width: 1px; - } - - .recent-build:not(:first-child) .-icon { - background-color: var(--color-bg-dark); // too many levels - stroke: var(--color-green); - stroke-width: 1px; - - &.-pending { // def too many levels - stroke: var(--color-bg-darkest); - border-top: 2px solid var(--color-green); - border-bottom: 2px solid var(--color-green); - } - - &.-running { - stroke: var(--color-yellow); - border-top: 2px solid var(--color-yellow); - border-bottom: 2px solid var(--color-yellow); - } - - &.-success { - stroke: var(--color-green); - border-top: 2px solid var(--color-green); - border-bottom: 2px solid var(--color-green); - } - - &.-failure { - stroke: var(--color-red); - border-top: 2px solid var(--color-red); - border-bottom: 2px solid var(--color-red); - } - - &.-canceled { - stroke: var(--color-cyan-dark); - border-top: 2px solid var(--color-cyan-dark); - border-bottom: 2px solid var(--color-cyan-dark); - } - - &.-error { - stroke: var(--color-red); - border-top: 2px solid var(--color-red); - border-bottom: 2px solid var(--color-red); - } + .build-history { + background-color: var(--color-bg-darkest); } + // icons for recent builds are larger .-icon { width: 5rem; height: 5rem; - } -} -.dashboard-no-builds { - margin: 0.5rem; - padding: 1.75rem 1rem 1rem 1rem; - height: 5rem; - text-align: center; + // overrides for recent builds component due to custom styling + .recent-build:not(:first-child) .-icon { + background-color: var(--color-bg-darkest); // too many levels + border-style: solid; + border-width: 2px 0; - background-color: var(--color-bg-darkest); + &.-pending { + border-color: var(--color-bg-light); + + stroke: var(--color-bg-darkest); + } + + &.-running { + border-color: var(--color-yellow); + + stroke: var(--color-yellow); + } + + &.-success { + border-color: var(--color-green); + + stroke: var(--color-green); + } + + &.-canceled { + border-color: var(--color-cyan-dark); + + stroke: var(--color-cyan-dark); + } + + &.-failure, + &.-error { + border-color: var(--color-red); + + stroke: var(--color-red); + } + } + + // zero out margin for first box for + // this implementation of recent build component + .recent-build:first-child .recent-build-link.-current { + margin: 0; + } + + // add a triangle pointer to the most recent build status + .recent-build-link.-current::before { + position: absolute; + top: -0.4rem; + left: 50%; + + display: block; + width: 0.8rem; + + transform: translateX(-50%); + + content: ''; + clip-path: polygon(50% 0, 100% 100%, 0 100%); + aspect-ratio: 1 / 0.5; + } + + // color the pointer based on the respective status + // using lookahead to check for status class; + // browser support: https://caniuse.com/css-has + // unsupported browsers won't show the pointer + .recent-build-link.-current { + &:has(.-success)::before { + background-color: var(--color-green); + } + + &:has(.-pending)::before { + background-color: var(--color-bg-light); + } + + &:has(.-running)::before { + background-color: var(--color-yellow); + } + + &:has(.-canceled)::before { + background-color: var(--color-cyan-dark); + } + + &:has(.-error)::before, + &:has(.-failure)::before { + background-color: var(--color-red); + } + } } diff --git a/src/scss/_main.scss b/src/scss/_main.scss index 217856ab7..4e0fdaee6 100644 --- a/src/scss/_main.scss +++ b/src/scss/_main.scss @@ -1745,3 +1745,25 @@ details.build-toggle { .overflow-auto { overflow: auto; } + +code.shell { + position: relative; + + padding: 0.75rem 1rem 0.75rem 2rem; + + background-color: var(--color-bg-dark); + + &::before { + position: absolute; + top: 50%; + left: 0.8rem; + + display: block; + + color: var(--color-green); + + transform: translateY(-50%); + + content: '$'; + } +} diff --git a/src/scss/_mixins.scss b/src/scss/_mixins.scss index 2f6e72c17..58f83b3df 100644 --- a/src/scss/_mixins.scss +++ b/src/scss/_mixins.scss @@ -36,3 +36,16 @@ } } } + +// truncate text with ellipsis, units in characters +@mixin truncate($chars: 15, $isBlock: true) { + @if $isBlock == false { + display: inline-block; + } + + max-width: $chars * 1ch; + overflow: hidden; + + white-space: nowrap; + text-overflow: ellipsis; +} From 408a5b5d354d1daa8828d25b3a08b7ab9d7de806 Mon Sep 17 00:00:00 2001 From: wass3r <1301201+wass3r@users.noreply.github.com> Date: Mon, 20 May 2024 00:53:24 -0500 Subject: [PATCH 11/23] only render tooltip fields if value is not empty --- src/elm/Components/RecentBuilds.elm | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/elm/Components/RecentBuilds.elm b/src/elm/Components/RecentBuilds.elm index bc349dc22..814c12b99 100644 --- a/src/elm/Components/RecentBuilds.elm +++ b/src/elm/Components/RecentBuilds.elm @@ -156,7 +156,11 @@ buildInfo build = -} viewTooltipField : String -> String -> Html msg viewTooltipField key value = - li [ class "line" ] - [ span [] [ text key ] - , span [] [ text value ] - ] + if String.isEmpty value then + text "" + + else + li [ class "line" ] + [ span [] [ text key ] + , span [] [ text value ] + ] From c8da938f58b000d253fdba1bf865281868a04731 Mon Sep 17 00:00:00 2001 From: wass3r <1301201+wass3r@users.noreply.github.com> Date: Mon, 20 May 2024 00:54:14 -0500 Subject: [PATCH 12/23] make formatRunTime helper more resilient --- src/elm/Utils/Helpers.elm | 44 +++++++++++++++------ tests/HelpersTest.elm | 81 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 113 insertions(+), 12 deletions(-) create mode 100644 tests/HelpersTest.elm diff --git a/src/elm/Utils/Helpers.elm b/src/elm/Utils/Helpers.elm index f6e22f573..fc2e622e4 100644 --- a/src/elm/Utils/Helpers.elm +++ b/src/elm/Utils/Helpers.elm @@ -230,7 +230,12 @@ formatRunTime now started finished = seconds = runTimeSeconds runtime in - String.join ":" [ minutes, seconds ] + -- smallest units is seconds + if minutes == "00" && seconds == "00" then + "--:--" + + else + String.join ":" [ minutes, seconds ] {-| buildRunTime : calculates build runtime using current application time and build times, returned in seconds. @@ -238,18 +243,33 @@ formatRunTime now started finished = buildRunTime : Posix -> Int -> Int -> Int buildRunTime now started finished = let - start = - started - - end = - if finished /= 0 then - finished + isValid : Int -> Bool + isValid value = + value > 0 + + ( start, end ) = + case ( isValid started, isValid finished ) of + -- neither started nor finished + ( False, False ) -> + ( 0, 0 ) + + -- if finished but not started, we won't know duration + ( False, True ) -> + ( 0, 0 ) + + -- started, but not finished + ( True, False ) -> + ( started, millisToSeconds <| posixToMillis now ) + + -- both started and finished are legit + -- if it finished before it started, something is very wrong + -- otherwise, return started and finished + ( True, True ) -> + if started > finished then + ( 0, 0 ) - else if started == 0 then - start - - else - millisToSeconds <| posixToMillis now + else + ( started, finished ) in end - start diff --git a/tests/HelpersTest.elm b/tests/HelpersTest.elm new file mode 100644 index 000000000..e31b2d32f --- /dev/null +++ b/tests/HelpersTest.elm @@ -0,0 +1,81 @@ +{-- +SPDX-License-Identifier: Apache-2.0 +--} + + +module HelpersTest exposing (..) + +import Expect +import Test exposing (..) +import Time +import Utils.Helpers + + + +-- FormatRunTime Tests + + +currentTime : Int +currentTime = + 1715840944 + + +currentTimeMillis : Int +currentTimeMillis = + Utils.Helpers.secondsToMillis currentTime + + +testFormatRunTimeFinishedInvalid : Test +testFormatRunTimeFinishedInvalid = + test "formatRunTime: started 1 second ago, finished is invalid (-1)" <| + \_ -> + Utils.Helpers.formatRunTime (Time.millisToPosix currentTimeMillis) (currentTime - 1) -1 + |> Expect.equal "00:01" + + +testFormatRunTimeFinishedInvalid2 : Test +testFormatRunTimeFinishedInvalid2 = + test "formatRunTime: started 1 second ago, finished is invalid (0)" <| + \_ -> + Utils.Helpers.formatRunTime (Time.millisToPosix currentTimeMillis) (currentTime - 1) 0 + |> Expect.equal "00:01" + + +testFormatRunTimeStartAndFinishedInvalid : Test +testFormatRunTimeStartAndFinishedInvalid = + test "formatRunTime: started and finished have invalid value (-1)" <| + \_ -> + Utils.Helpers.formatRunTime (Time.millisToPosix currentTimeMillis) -1 -1 + |> Expect.equal "--:--" + + +testFormatRunTimeStartAndFinishedInvalid2 : Test +testFormatRunTimeStartAndFinishedInvalid2 = + test "formatRunTime: started and finished have invalid value (0)" <| + \_ -> + Utils.Helpers.formatRunTime (Time.millisToPosix currentTimeMillis) 0 0 + |> Expect.equal "--:--" + + +testFormatRunTimeStartedInvalid : Test +testFormatRunTimeStartedInvalid = + test "formatRunTime: started is invalid (0), finished one second ago" <| + \_ -> + Utils.Helpers.formatRunTime (Time.millisToPosix currentTimeMillis) 0 (currentTime - 1) + |> Expect.equal "--:--" + + +testFormatRunTimeStartedInvalid2 : Test +testFormatRunTimeStartedInvalid2 = + test "formatRunTime: started is invalid (-1), finished one second ago" <| + \_ -> + Utils.Helpers.formatRunTime (Time.millisToPosix currentTimeMillis) -1 (currentTime - 1) + |> Expect.equal "--:--" + + +testFormatRunTimeFinishedBeforeStarted : Test +testFormatRunTimeFinishedBeforeStarted = + test "formatRunTime: finished time is before started time" <| + \_ -> + Utils.Helpers.formatRunTime (Time.millisToPosix currentTimeMillis) (currentTime - 1) (currentTime - 2) + |> Expect.equal "--:--" From 54b273c9ac70dc8fa0eba598abae1ac37f928c0f Mon Sep 17 00:00:00 2001 From: wass3rw3rk <49894298+wass3rw3rk@users.noreply.github.com> Date: Mon, 20 May 2024 10:04:18 -0500 Subject: [PATCH 13/23] improve no repos message --- src/elm/Pages/Dashboards/Dashboard_.elm | 11 +++++++++-- src/scss/_main.scss | 6 ++++-- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/elm/Pages/Dashboards/Dashboard_.elm b/src/elm/Pages/Dashboards/Dashboard_.elm index 68c978475..4782c5c13 100644 --- a/src/elm/Pages/Dashboards/Dashboard_.elm +++ b/src/elm/Pages/Dashboards/Dashboard_.elm @@ -16,6 +16,7 @@ import Html ( div , h1 , main_ + , code , span , text ) @@ -37,6 +38,8 @@ import Utils.Helpers as Util import Utils.Interval as Interval import Vela import View exposing (View) +import Html exposing (p) +import Html exposing (br) {-| page : takes user, shared model, route, and returns the dashboard page. @@ -217,9 +220,13 @@ view shared route model = [ h1 [ class "dashboard-title" ] [ text dashboard.dashboard.name ] , div [ class "cards" ] (if List.isEmpty dashboard.repos then - [ span + [ p [] - [ text "This dashboard doesn't have repositories added yet." ] + [ text "This dashboard doesn't have repositories added yet. Add some with the CLI:" + , br [] [] + , code [ class "shell" ] + [ text ("vela update dashboard --id " ++ route.params.dashboard ++ " --add-repos org/repo") ] + ] ] else diff --git a/src/scss/_main.scss b/src/scss/_main.scss index 4e0fdaee6..e865af718 100644 --- a/src/scss/_main.scss +++ b/src/scss/_main.scss @@ -1749,15 +1749,17 @@ details.build-toggle { code.shell { position: relative; + display: inline-block; + margin: 1rem 0; padding: 0.75rem 1rem 0.75rem 2rem; - + background-color: var(--color-bg-dark); &::before { position: absolute; top: 50%; left: 0.8rem; - + display: block; color: var(--color-green); From 99dc0047bae4a0a710039a35130eabd7d9d8e905 Mon Sep 17 00:00:00 2001 From: wass3rw3rk <49894298+wass3rw3rk@users.noreply.github.com> Date: Mon, 20 May 2024 10:07:05 -0500 Subject: [PATCH 14/23] lint fix --- src/elm/Main.elm | 396 ++++++++++++------------ src/elm/Main/Pages/Model.elm | 12 +- src/elm/Main/Pages/Msg.elm | 12 +- src/elm/Pages/Dashboards/Dashboard_.elm | 10 +- src/elm/Route.elm | 4 +- src/elm/Route/Query.elm | 6 +- src/scss/_main.scss | 4 +- src/scss/_variables.scss | 2 +- 8 files changed, 225 insertions(+), 221 deletions(-) diff --git a/src/elm/Main.elm b/src/elm/Main.elm index 514448c3f..501d7e659 100644 --- a/src/elm/Main.elm +++ b/src/elm/Main.elm @@ -28,7 +28,6 @@ import Main.Pages.Model import Main.Pages.Msg import Maybe.Extra import Page -import Pages.Home_ import Pages.Account.Authenticate import Pages.Account.Login import Pages.Account.Logout @@ -47,9 +46,15 @@ import Pages.Dash.Secrets.Engine_.Shared.Org_.Team_.Add import Pages.Dash.Secrets.Engine_.Shared.Org_.Team_.Name_ import Pages.Dashboards import Pages.Dashboards.Dashboard_ +import Pages.Home_ +import Pages.NotFound_ import Pages.Org_ import Pages.Org_.Builds import Pages.Org_.Repo_ +import Pages.Org_.Repo_.Build_ +import Pages.Org_.Repo_.Build_.Graph +import Pages.Org_.Repo_.Build_.Pipeline +import Pages.Org_.Repo_.Build_.Services import Pages.Org_.Repo_.Deployments import Pages.Org_.Repo_.Deployments.Add import Pages.Org_.Repo_.Hooks @@ -59,12 +64,6 @@ import Pages.Org_.Repo_.Schedules.Add import Pages.Org_.Repo_.Schedules.Name_ import Pages.Org_.Repo_.Settings import Pages.Org_.Repo_.Tags -import Pages.Org_.Repo_.Build_ -import Pages.Org_.Repo_.Build_.Graph -import Pages.Org_.Repo_.Build_.Pipeline -import Pages.Org_.Repo_.Build_.Services -import Pages.NotFound_ -import Pages.NotFound_ import Route exposing (Route) import Route.Path import Shared @@ -118,10 +117,10 @@ init json url key = , shared = sharedModel } , Cmd.batch - [ Tuple.second page - , layout |> Maybe.map Tuple.second |> Maybe.withDefault Cmd.none - , fromSharedEffect { key = key, url = url, shared = sharedModel } sharedEffect - ] + [ Tuple.second page + , layout |> Maybe.map Tuple.second |> Maybe.withDefault Cmd.none + , fromSharedEffect { key = key, url = url, shared = sharedModel } sharedEffect + ] ) @@ -351,9 +350,10 @@ initLayout model layout = Layout.init defaultLayout () in ( Main.Layouts.Model.Default_Build { default = defaultLayoutModel, build = buildLayoutModel } - , Cmd.batch [ fromLayoutEffect model (Effect.map Main.Layouts.Msg.Default_Build buildLayoutEffect) - , fromLayoutEffect model (Effect.map Main.Layouts.Msg.Default defaultLayoutEffect) - ] + , Cmd.batch + [ fromLayoutEffect model (Effect.map Main.Layouts.Msg.Default_Build buildLayoutEffect) + , fromLayoutEffect model (Effect.map Main.Layouts.Msg.Default defaultLayoutEffect) + ] ) ( Layouts.Default_Org props, Just (Main.Layouts.Model.Default existing) ) -> @@ -444,9 +444,10 @@ initLayout model layout = Layout.init defaultLayout () in ( Main.Layouts.Model.Default_Org { default = defaultLayoutModel, org = orgLayoutModel } - , Cmd.batch [ fromLayoutEffect model (Effect.map Main.Layouts.Msg.Default_Org orgLayoutEffect) - , fromLayoutEffect model (Effect.map Main.Layouts.Msg.Default defaultLayoutEffect) - ] + , Cmd.batch + [ fromLayoutEffect model (Effect.map Main.Layouts.Msg.Default_Org orgLayoutEffect) + , fromLayoutEffect model (Effect.map Main.Layouts.Msg.Default defaultLayoutEffect) + ] ) ( Layouts.Default_Repo props, Just (Main.Layouts.Model.Default existing) ) -> @@ -537,9 +538,10 @@ initLayout model layout = Layout.init defaultLayout () in ( Main.Layouts.Model.Default_Repo { default = defaultLayoutModel, repo = repoLayoutModel } - , Cmd.batch [ fromLayoutEffect model (Effect.map Main.Layouts.Msg.Default_Repo repoLayoutEffect) - , fromLayoutEffect model (Effect.map Main.Layouts.Msg.Default defaultLayoutEffect) - ] + , Cmd.batch + [ fromLayoutEffect model (Effect.map Main.Layouts.Msg.Default_Repo repoLayoutEffect) + , fromLayoutEffect model (Effect.map Main.Layouts.Msg.Default defaultLayoutEffect) + ] ) @@ -558,12 +560,12 @@ initPageAndLayout model = ( pageModel, pageEffect ) = Page.init page () in - { page = + { page = Tuple.mapBoth Main.Pages.Model.Home_ (Effect.map Main.Pages.Msg.Home_ >> fromPageEffect model) ( pageModel, pageEffect ) - , layout = + , layout = Page.layout pageModel page |> Maybe.map (Layouts.map (Main.Pages.Msg.Home_ >> Page)) |> Maybe.map (initLayout model) @@ -579,12 +581,12 @@ initPageAndLayout model = ( pageModel, pageEffect ) = Page.init page () in - { page = + { page = Tuple.mapBoth Main.Pages.Model.Account_Authenticate (Effect.map Main.Pages.Msg.Account_Authenticate >> fromPageEffect model) ( pageModel, pageEffect ) - , layout = + , layout = Page.layout pageModel page |> Maybe.map (Layouts.map (Main.Pages.Msg.Account_Authenticate >> Page)) |> Maybe.map (initLayout model) @@ -599,12 +601,12 @@ initPageAndLayout model = ( pageModel, pageEffect ) = Page.init page () in - { page = + { page = Tuple.mapBoth Main.Pages.Model.Account_Login (Effect.map Main.Pages.Msg.Account_Login >> fromPageEffect model) ( pageModel, pageEffect ) - , layout = + , layout = Page.layout pageModel page |> Maybe.map (Layouts.map (Main.Pages.Msg.Account_Login >> Page)) |> Maybe.map (initLayout model) @@ -619,12 +621,12 @@ initPageAndLayout model = ( pageModel, pageEffect ) = Page.init page () in - { page = + { page = Tuple.mapBoth Main.Pages.Model.Account_Logout (Effect.map Main.Pages.Msg.Account_Logout >> fromPageEffect model) ( pageModel, pageEffect ) - , layout = + , layout = Page.layout pageModel page |> Maybe.map (Layouts.map (Main.Pages.Msg.Account_Logout >> Page)) |> Maybe.map (initLayout model) @@ -642,12 +644,12 @@ initPageAndLayout model = ( pageModel, pageEffect ) = Page.init page () in - { page = + { page = Tuple.mapBoth Main.Pages.Model.Account_Settings (Effect.map Main.Pages.Msg.Account_Settings >> fromPageEffect model) ( pageModel, pageEffect ) - , layout = + , layout = Page.layout pageModel page |> Maybe.map (Layouts.map (Main.Pages.Msg.Account_Settings >> Page)) |> Maybe.map (initLayout model) @@ -666,12 +668,12 @@ initPageAndLayout model = ( pageModel, pageEffect ) = Page.init page () in - { page = + { page = Tuple.mapBoth Main.Pages.Model.Account_SourceRepos (Effect.map Main.Pages.Msg.Account_SourceRepos >> fromPageEffect model) ( pageModel, pageEffect ) - , layout = + , layout = Page.layout pageModel page |> Maybe.map (Layouts.map (Main.Pages.Msg.Account_SourceRepos >> Page)) |> Maybe.map (initLayout model) @@ -738,12 +740,12 @@ initPageAndLayout model = ( pageModel, pageEffect ) = Page.init page () in - { page = + { page = Tuple.mapBoth (Main.Pages.Model.Dash_Secrets_Engine__Org_Org_ params) (Effect.map Main.Pages.Msg.Dash_Secrets_Engine__Org_Org_ >> fromPageEffect model) ( pageModel, pageEffect ) - , layout = + , layout = Page.layout pageModel page |> Maybe.map (Layouts.map (Main.Pages.Msg.Dash_Secrets_Engine__Org_Org_ >> Page)) |> Maybe.map (initLayout model) @@ -762,12 +764,12 @@ initPageAndLayout model = ( pageModel, pageEffect ) = Page.init page () in - { page = + { page = Tuple.mapBoth (Main.Pages.Model.Dash_Secrets_Engine__Org_Org__Add params) (Effect.map Main.Pages.Msg.Dash_Secrets_Engine__Org_Org__Add >> fromPageEffect model) ( pageModel, pageEffect ) - , layout = + , layout = Page.layout pageModel page |> Maybe.map (Layouts.map (Main.Pages.Msg.Dash_Secrets_Engine__Org_Org__Add >> Page)) |> Maybe.map (initLayout model) @@ -786,12 +788,12 @@ initPageAndLayout model = ( pageModel, pageEffect ) = Page.init page () in - { page = + { page = Tuple.mapBoth (Main.Pages.Model.Dash_Secrets_Engine__Org_Org__Name_ params) (Effect.map Main.Pages.Msg.Dash_Secrets_Engine__Org_Org__Name_ >> fromPageEffect model) ( pageModel, pageEffect ) - , layout = + , layout = Page.layout pageModel page |> Maybe.map (Layouts.map (Main.Pages.Msg.Dash_Secrets_Engine__Org_Org__Name_ >> Page)) |> Maybe.map (initLayout model) @@ -810,12 +812,12 @@ initPageAndLayout model = ( pageModel, pageEffect ) = Page.init page () in - { page = + { page = Tuple.mapBoth (Main.Pages.Model.Dash_Secrets_Engine__Repo_Org__Repo_ params) (Effect.map Main.Pages.Msg.Dash_Secrets_Engine__Repo_Org__Repo_ >> fromPageEffect model) ( pageModel, pageEffect ) - , layout = + , layout = Page.layout pageModel page |> Maybe.map (Layouts.map (Main.Pages.Msg.Dash_Secrets_Engine__Repo_Org__Repo_ >> Page)) |> Maybe.map (initLayout model) @@ -834,12 +836,12 @@ initPageAndLayout model = ( pageModel, pageEffect ) = Page.init page () in - { page = + { page = Tuple.mapBoth (Main.Pages.Model.Dash_Secrets_Engine__Repo_Org__Repo__Add params) (Effect.map Main.Pages.Msg.Dash_Secrets_Engine__Repo_Org__Repo__Add >> fromPageEffect model) ( pageModel, pageEffect ) - , layout = + , layout = Page.layout pageModel page |> Maybe.map (Layouts.map (Main.Pages.Msg.Dash_Secrets_Engine__Repo_Org__Repo__Add >> Page)) |> Maybe.map (initLayout model) @@ -858,12 +860,12 @@ initPageAndLayout model = ( pageModel, pageEffect ) = Page.init page () in - { page = + { page = Tuple.mapBoth (Main.Pages.Model.Dash_Secrets_Engine__Repo_Org__Repo__Name_ params) (Effect.map Main.Pages.Msg.Dash_Secrets_Engine__Repo_Org__Repo__Name_ >> fromPageEffect model) ( pageModel, pageEffect ) - , layout = + , layout = Page.layout pageModel page |> Maybe.map (Layouts.map (Main.Pages.Msg.Dash_Secrets_Engine__Repo_Org__Repo__Name_ >> Page)) |> Maybe.map (initLayout model) @@ -882,12 +884,12 @@ initPageAndLayout model = ( pageModel, pageEffect ) = Page.init page () in - { page = + { page = Tuple.mapBoth (Main.Pages.Model.Dash_Secrets_Engine__Shared_Org__Team_ params) (Effect.map Main.Pages.Msg.Dash_Secrets_Engine__Shared_Org__Team_ >> fromPageEffect model) ( pageModel, pageEffect ) - , layout = + , layout = Page.layout pageModel page |> Maybe.map (Layouts.map (Main.Pages.Msg.Dash_Secrets_Engine__Shared_Org__Team_ >> Page)) |> Maybe.map (initLayout model) @@ -906,12 +908,12 @@ initPageAndLayout model = ( pageModel, pageEffect ) = Page.init page () in - { page = + { page = Tuple.mapBoth (Main.Pages.Model.Dash_Secrets_Engine__Shared_Org__Team__Add params) (Effect.map Main.Pages.Msg.Dash_Secrets_Engine__Shared_Org__Team__Add >> fromPageEffect model) ( pageModel, pageEffect ) - , layout = + , layout = Page.layout pageModel page |> Maybe.map (Layouts.map (Main.Pages.Msg.Dash_Secrets_Engine__Shared_Org__Team__Add >> Page)) |> Maybe.map (initLayout model) @@ -930,12 +932,12 @@ initPageAndLayout model = ( pageModel, pageEffect ) = Page.init page () in - { page = + { page = Tuple.mapBoth (Main.Pages.Model.Dash_Secrets_Engine__Shared_Org__Team__Name_ params) (Effect.map Main.Pages.Msg.Dash_Secrets_Engine__Shared_Org__Team__Name_ >> fromPageEffect model) ( pageModel, pageEffect ) - , layout = + , layout = Page.layout pageModel page |> Maybe.map (Layouts.map (Main.Pages.Msg.Dash_Secrets_Engine__Shared_Org__Team__Name_ >> Page)) |> Maybe.map (initLayout model) @@ -954,12 +956,12 @@ initPageAndLayout model = ( pageModel, pageEffect ) = Page.init page () in - { page = + { page = Tuple.mapBoth Main.Pages.Model.Dashboards (Effect.map Main.Pages.Msg.Dashboards >> fromPageEffect model) ( pageModel, pageEffect ) - , layout = + , layout = Page.layout pageModel page |> Maybe.map (Layouts.map (Main.Pages.Msg.Dashboards >> Page)) |> Maybe.map (initLayout model) @@ -978,12 +980,12 @@ initPageAndLayout model = ( pageModel, pageEffect ) = Page.init page () in - { page = + { page = Tuple.mapBoth (Main.Pages.Model.Dashboards_Dashboard_ params) (Effect.map Main.Pages.Msg.Dashboards_Dashboard_ >> fromPageEffect model) ( pageModel, pageEffect ) - , layout = + , layout = Page.layout pageModel page |> Maybe.map (Layouts.map (Main.Pages.Msg.Dashboards_Dashboard_ >> Page)) |> Maybe.map (initLayout model) @@ -1002,12 +1004,12 @@ initPageAndLayout model = ( pageModel, pageEffect ) = Page.init page () in - { page = + { page = Tuple.mapBoth (Main.Pages.Model.Org_ params) (Effect.map Main.Pages.Msg.Org_ >> fromPageEffect model) ( pageModel, pageEffect ) - , layout = + , layout = Page.layout pageModel page |> Maybe.map (Layouts.map (Main.Pages.Msg.Org_ >> Page)) |> Maybe.map (initLayout model) @@ -1026,12 +1028,12 @@ initPageAndLayout model = ( pageModel, pageEffect ) = Page.init page () in - { page = + { page = Tuple.mapBoth (Main.Pages.Model.Org__Builds params) (Effect.map Main.Pages.Msg.Org__Builds >> fromPageEffect model) ( pageModel, pageEffect ) - , layout = + , layout = Page.layout pageModel page |> Maybe.map (Layouts.map (Main.Pages.Msg.Org__Builds >> Page)) |> Maybe.map (initLayout model) @@ -1050,12 +1052,12 @@ initPageAndLayout model = ( pageModel, pageEffect ) = Page.init page () in - { page = + { page = Tuple.mapBoth (Main.Pages.Model.Org__Repo_ params) (Effect.map Main.Pages.Msg.Org__Repo_ >> fromPageEffect model) ( pageModel, pageEffect ) - , layout = + , layout = Page.layout pageModel page |> Maybe.map (Layouts.map (Main.Pages.Msg.Org__Repo_ >> Page)) |> Maybe.map (initLayout model) @@ -1074,12 +1076,12 @@ initPageAndLayout model = ( pageModel, pageEffect ) = Page.init page () in - { page = + { page = Tuple.mapBoth (Main.Pages.Model.Org__Repo__Deployments params) (Effect.map Main.Pages.Msg.Org__Repo__Deployments >> fromPageEffect model) ( pageModel, pageEffect ) - , layout = + , layout = Page.layout pageModel page |> Maybe.map (Layouts.map (Main.Pages.Msg.Org__Repo__Deployments >> Page)) |> Maybe.map (initLayout model) @@ -1098,12 +1100,12 @@ initPageAndLayout model = ( pageModel, pageEffect ) = Page.init page () in - { page = + { page = Tuple.mapBoth (Main.Pages.Model.Org__Repo__Deployments_Add params) (Effect.map Main.Pages.Msg.Org__Repo__Deployments_Add >> fromPageEffect model) ( pageModel, pageEffect ) - , layout = + , layout = Page.layout pageModel page |> Maybe.map (Layouts.map (Main.Pages.Msg.Org__Repo__Deployments_Add >> Page)) |> Maybe.map (initLayout model) @@ -1122,12 +1124,12 @@ initPageAndLayout model = ( pageModel, pageEffect ) = Page.init page () in - { page = + { page = Tuple.mapBoth (Main.Pages.Model.Org__Repo__Hooks params) (Effect.map Main.Pages.Msg.Org__Repo__Hooks >> fromPageEffect model) ( pageModel, pageEffect ) - , layout = + , layout = Page.layout pageModel page |> Maybe.map (Layouts.map (Main.Pages.Msg.Org__Repo__Hooks >> Page)) |> Maybe.map (initLayout model) @@ -1143,12 +1145,12 @@ initPageAndLayout model = ( pageModel, pageEffect ) = Page.init page () in - { page = + { page = Tuple.mapBoth (Main.Pages.Model.Org__Repo__Pulls params) (Effect.map Main.Pages.Msg.Org__Repo__Pulls >> fromPageEffect model) ( pageModel, pageEffect ) - , layout = + , layout = Page.layout pageModel page |> Maybe.map (Layouts.map (Main.Pages.Msg.Org__Repo__Pulls >> Page)) |> Maybe.map (initLayout model) @@ -1166,12 +1168,12 @@ initPageAndLayout model = ( pageModel, pageEffect ) = Page.init page () in - { page = + { page = Tuple.mapBoth (Main.Pages.Model.Org__Repo__Schedules params) (Effect.map Main.Pages.Msg.Org__Repo__Schedules >> fromPageEffect model) ( pageModel, pageEffect ) - , layout = + , layout = Page.layout pageModel page |> Maybe.map (Layouts.map (Main.Pages.Msg.Org__Repo__Schedules >> Page)) |> Maybe.map (initLayout model) @@ -1190,12 +1192,12 @@ initPageAndLayout model = ( pageModel, pageEffect ) = Page.init page () in - { page = + { page = Tuple.mapBoth (Main.Pages.Model.Org__Repo__Schedules_Add params) (Effect.map Main.Pages.Msg.Org__Repo__Schedules_Add >> fromPageEffect model) ( pageModel, pageEffect ) - , layout = + , layout = Page.layout pageModel page |> Maybe.map (Layouts.map (Main.Pages.Msg.Org__Repo__Schedules_Add >> Page)) |> Maybe.map (initLayout model) @@ -1214,12 +1216,12 @@ initPageAndLayout model = ( pageModel, pageEffect ) = Page.init page () in - { page = + { page = Tuple.mapBoth (Main.Pages.Model.Org__Repo__Schedules_Name_ params) (Effect.map Main.Pages.Msg.Org__Repo__Schedules_Name_ >> fromPageEffect model) ( pageModel, pageEffect ) - , layout = + , layout = Page.layout pageModel page |> Maybe.map (Layouts.map (Main.Pages.Msg.Org__Repo__Schedules_Name_ >> Page)) |> Maybe.map (initLayout model) @@ -1238,12 +1240,12 @@ initPageAndLayout model = ( pageModel, pageEffect ) = Page.init page () in - { page = + { page = Tuple.mapBoth (Main.Pages.Model.Org__Repo__Settings params) (Effect.map Main.Pages.Msg.Org__Repo__Settings >> fromPageEffect model) ( pageModel, pageEffect ) - , layout = + , layout = Page.layout pageModel page |> Maybe.map (Layouts.map (Main.Pages.Msg.Org__Repo__Settings >> Page)) |> Maybe.map (initLayout model) @@ -1259,12 +1261,12 @@ initPageAndLayout model = ( pageModel, pageEffect ) = Page.init page () in - { page = + { page = Tuple.mapBoth (Main.Pages.Model.Org__Repo__Tags params) (Effect.map Main.Pages.Msg.Org__Repo__Tags >> fromPageEffect model) ( pageModel, pageEffect ) - , layout = + , layout = Page.layout pageModel page |> Maybe.map (Layouts.map (Main.Pages.Msg.Org__Repo__Tags >> Page)) |> Maybe.map (initLayout model) @@ -1282,12 +1284,12 @@ initPageAndLayout model = ( pageModel, pageEffect ) = Page.init page () in - { page = + { page = Tuple.mapBoth (Main.Pages.Model.Org__Repo__Build_ params) (Effect.map Main.Pages.Msg.Org__Repo__Build_ >> fromPageEffect model) ( pageModel, pageEffect ) - , layout = + , layout = Page.layout pageModel page |> Maybe.map (Layouts.map (Main.Pages.Msg.Org__Repo__Build_ >> Page)) |> Maybe.map (initLayout model) @@ -1306,12 +1308,12 @@ initPageAndLayout model = ( pageModel, pageEffect ) = Page.init page () in - { page = + { page = Tuple.mapBoth (Main.Pages.Model.Org__Repo__Build__Graph params) (Effect.map Main.Pages.Msg.Org__Repo__Build__Graph >> fromPageEffect model) ( pageModel, pageEffect ) - , layout = + , layout = Page.layout pageModel page |> Maybe.map (Layouts.map (Main.Pages.Msg.Org__Repo__Build__Graph >> Page)) |> Maybe.map (initLayout model) @@ -1330,12 +1332,12 @@ initPageAndLayout model = ( pageModel, pageEffect ) = Page.init page () in - { page = + { page = Tuple.mapBoth (Main.Pages.Model.Org__Repo__Build__Pipeline params) (Effect.map Main.Pages.Msg.Org__Repo__Build__Pipeline >> fromPageEffect model) ( pageModel, pageEffect ) - , layout = + , layout = Page.layout pageModel page |> Maybe.map (Layouts.map (Main.Pages.Msg.Org__Repo__Build__Pipeline >> Page)) |> Maybe.map (initLayout model) @@ -1354,12 +1356,12 @@ initPageAndLayout model = ( pageModel, pageEffect ) = Page.init page () in - { page = + { page = Tuple.mapBoth (Main.Pages.Model.Org__Repo__Build__Services params) (Effect.map Main.Pages.Msg.Org__Repo__Build__Services >> fromPageEffect model) ( pageModel, pageEffect ) - , layout = + , layout = Page.layout pageModel page |> Maybe.map (Layouts.map (Main.Pages.Msg.Org__Repo__Build__Services >> Page)) |> Maybe.map (initLayout model) @@ -1375,12 +1377,12 @@ initPageAndLayout model = ( pageModel, pageEffect ) = Page.init page () in - { page = + { page = Tuple.mapBoth Main.Pages.Model.NotFound_ (Effect.map Main.Pages.Msg.NotFound_ >> fromPageEffect model) ( pageModel, pageEffect ) - , layout = + , layout = Page.layout pageModel page |> Maybe.map (Layouts.map (Main.Pages.Msg.NotFound_ >> Page)) |> Maybe.map (initLayout model) @@ -1419,7 +1421,7 @@ runWhenAuthenticatedWithLayout model toRecord = toRecord user Auth.Action.LoadCustomPage -> - { page = + { page = ( Main.Pages.Model.Loading_ , Cmd.none ) @@ -1427,35 +1429,35 @@ runWhenAuthenticatedWithLayout model toRecord = } Auth.Action.ReplaceRoute options -> - { page = + { page = ( Main.Pages.Model.Redirecting_ , Cmd.batch - [ toCmd (Effect.replaceRoute options) - , Maybe.Extra.unwrap - Cmd.none - (\from -> Interop.setRedirect <| Json.Encode.string from) - (Dict.get "from" options.query) - ] + [ toCmd (Effect.replaceRoute options) + , Maybe.Extra.unwrap + Cmd.none + (\from -> Interop.setRedirect <| Json.Encode.string from) + (Dict.get "from" options.query) + ] ) , layout = Nothing } Auth.Action.PushRoute options -> - { page = + { page = ( Main.Pages.Model.Redirecting_ , Cmd.batch - [ toCmd (Effect.pushRoute options) - , Maybe.Extra.unwrap - Cmd.none - (\from -> Interop.setRedirect <| Json.Encode.string from) - (Dict.get "from" options.query) - ] + [ toCmd (Effect.pushRoute options) + , Maybe.Extra.unwrap + Cmd.none + (\from -> Interop.setRedirect <| Json.Encode.string from) + (Dict.get "from" options.query) + ] ) , layout = Nothing } Auth.Action.LoadExternalUrl externalUrl -> - { page = + { page = ( Main.Pages.Model.Redirecting_ , Browser.Navigation.load externalUrl ) @@ -1502,15 +1504,16 @@ update msg model = in ( newModel , Cmd.batch - [ toPageUrlHookCmd newModel - { from = Route.fromUrl () model.url - , to = Route.fromUrl () newModel.url - } - , toLayoutUrlHookCmd model newModel - { from = Route.fromUrl () model.url - , to = Route.fromUrl () newModel.url - } - ] + [ toPageUrlHookCmd newModel + { from = Route.fromUrl () model.url + , to = Route.fromUrl () newModel.url + } + , toLayoutUrlHookCmd model + newModel + { from = Route.fromUrl () model.url + , to = Route.fromUrl () newModel.url + } + ] ) else @@ -1534,13 +1537,14 @@ update msg model = in ( newModel , Cmd.batch - [ pageCmd - , layoutCmd - , toLayoutUrlHookCmd model newModel - { from = Route.fromUrl () model.url - , to = Route.fromUrl () newModel.url - } - ] + [ pageCmd + , layoutCmd + , toLayoutUrlHookCmd model + newModel + { from = Route.fromUrl () model.url + , to = Route.fromUrl () newModel.url + } + ] ) Page pageMsg -> @@ -1571,7 +1575,7 @@ update msg model = , Auth.onPageLoad sharedModel (Route.fromUrl () model.url) ) in - if isAuthProtected (Route.fromUrl () model.url).path && (hasActionTypeChanged oldAction newAction) then + if isAuthProtected (Route.fromUrl () model.url).path && hasActionTypeChanged oldAction newAction then let { layout, page } = initPageAndLayout { key = model.key, shared = sharedModel, url = model.url, layout = model.layout } @@ -1586,10 +1590,10 @@ update msg model = in ( { model | shared = sharedModel, page = pageModel, layout = layoutModel } , Cmd.batch - [ pageCmd - , layoutCmd - , fromSharedEffect { model | shared = sharedModel } sharedEffect - ] + [ pageCmd + , layoutCmd + , fromSharedEffect { model | shared = sharedModel } sharedEffect + ] ) else @@ -1600,8 +1604,8 @@ update msg model = Batch messages -> ( model , messages - |> List.map (Task.succeed >> Task.perform identity) - |> Cmd.batch + |> List.map (Task.succeed >> Task.perform identity) + |> Cmd.batch ) @@ -2292,7 +2296,7 @@ hasActionTypeChanged oldAction newAction = ( Auth.Action.LoadExternalUrl _, Auth.Action.LoadExternalUrl _ ) -> False - ( _, _ ) -> + ( _, _ ) -> True @@ -2647,11 +2651,11 @@ subscriptions model = in Sub.batch [ Layout.subscriptions (Layouts.Default.layout defaultProps model.shared route) layoutModel.default - |> Sub.map Main.Layouts.Msg.Default - |> Sub.map Layout + |> Sub.map Main.Layouts.Msg.Default + |> Sub.map Layout , Layout.subscriptions (Layouts.Default.Build.layout props model.shared route) layoutModel.build - |> Sub.map Main.Layouts.Msg.Default_Build - |> Sub.map Layout + |> Sub.map Main.Layouts.Msg.Default_Build + |> Sub.map Layout ] ( Just (Layouts.Default_Org props), Just (Main.Layouts.Model.Default_Org layoutModel) ) -> @@ -2662,11 +2666,11 @@ subscriptions model = in Sub.batch [ Layout.subscriptions (Layouts.Default.layout defaultProps model.shared route) layoutModel.default - |> Sub.map Main.Layouts.Msg.Default - |> Sub.map Layout + |> Sub.map Main.Layouts.Msg.Default + |> Sub.map Layout , Layout.subscriptions (Layouts.Default.Org.layout props model.shared route) layoutModel.org - |> Sub.map Main.Layouts.Msg.Default_Org - |> Sub.map Layout + |> Sub.map Main.Layouts.Msg.Default_Org + |> Sub.map Layout ] ( Just (Layouts.Default_Repo props), Just (Main.Layouts.Model.Default_Repo layoutModel) ) -> @@ -2677,11 +2681,11 @@ subscriptions model = in Sub.batch [ Layout.subscriptions (Layouts.Default.layout defaultProps model.shared route) layoutModel.default - |> Sub.map Main.Layouts.Msg.Default - |> Sub.map Layout + |> Sub.map Main.Layouts.Msg.Default + |> Sub.map Layout , Layout.subscriptions (Layouts.Default.Repo.layout props model.shared route) layoutModel.repo - |> Sub.map Main.Layouts.Msg.Default_Repo - |> Sub.map Layout + |> Sub.map Main.Layouts.Msg.Default_Repo + |> Sub.map Layout ] _ -> @@ -2689,7 +2693,7 @@ subscriptions model = in Sub.batch [ Shared.subscriptions route model.shared - |> Sub.map Shared + |> Sub.map Shared , subscriptionsFromPage , subscriptionsFromLayout ] @@ -2758,7 +2762,7 @@ toView model = (Layouts.Default.layout defaultProps model.shared route) { model = layoutModel.default , toContentMsg = Main.Layouts.Msg.Default >> Layout - , content = + , content = Layout.view (Layouts.Default.Build.layout props model.shared route) { model = layoutModel.build @@ -2777,7 +2781,7 @@ toView model = (Layouts.Default.layout defaultProps model.shared route) { model = layoutModel.default , toContentMsg = Main.Layouts.Msg.Default >> Layout - , content = + , content = Layout.view (Layouts.Default.Org.layout props model.shared route) { model = layoutModel.org @@ -2796,7 +2800,7 @@ toView model = (Layouts.Default.layout defaultProps model.shared route) { model = layoutModel.default , toContentMsg = Main.Layouts.Msg.Default >> Layout - , content = + , content = Layout.view (Layouts.Default.Repo.layout props model.shared route) { model = layoutModel.repo @@ -3179,7 +3183,7 @@ toPageUrlHookCmd model routes = Main.Pages.Model.Home_ pageModel -> Auth.Action.command (\user -> - Page.toUrlMessages routes (Pages.Home_.page user model.shared (Route.fromUrl () model.url)) + Page.toUrlMessages routes (Pages.Home_.page user model.shared (Route.fromUrl () model.url)) |> List.map Main.Pages.Msg.Home_ |> List.map Page |> toCommands @@ -3187,19 +3191,19 @@ toPageUrlHookCmd model routes = (Auth.onPageLoad model.shared (Route.fromUrl () model.url)) Main.Pages.Model.Account_Authenticate pageModel -> - Page.toUrlMessages routes (Pages.Account.Authenticate.page model.shared (Route.fromUrl () model.url)) + Page.toUrlMessages routes (Pages.Account.Authenticate.page model.shared (Route.fromUrl () model.url)) |> List.map Main.Pages.Msg.Account_Authenticate |> List.map Page |> toCommands Main.Pages.Model.Account_Login pageModel -> - Page.toUrlMessages routes (Pages.Account.Login.page model.shared (Route.fromUrl () model.url)) + Page.toUrlMessages routes (Pages.Account.Login.page model.shared (Route.fromUrl () model.url)) |> List.map Main.Pages.Msg.Account_Login |> List.map Page |> toCommands Main.Pages.Model.Account_Logout pageModel -> - Page.toUrlMessages routes (Pages.Account.Logout.page model.shared (Route.fromUrl () model.url)) + Page.toUrlMessages routes (Pages.Account.Logout.page model.shared (Route.fromUrl () model.url)) |> List.map Main.Pages.Msg.Account_Logout |> List.map Page |> toCommands @@ -3207,7 +3211,7 @@ toPageUrlHookCmd model routes = Main.Pages.Model.Account_Settings pageModel -> Auth.Action.command (\user -> - Page.toUrlMessages routes (Pages.Account.Settings.page user model.shared (Route.fromUrl () model.url)) + Page.toUrlMessages routes (Pages.Account.Settings.page user model.shared (Route.fromUrl () model.url)) |> List.map Main.Pages.Msg.Account_Settings |> List.map Page |> toCommands @@ -3217,7 +3221,7 @@ toPageUrlHookCmd model routes = Main.Pages.Model.Account_SourceRepos pageModel -> Auth.Action.command (\user -> - Page.toUrlMessages routes (Pages.Account.SourceRepos.page user model.shared (Route.fromUrl () model.url)) + Page.toUrlMessages routes (Pages.Account.SourceRepos.page user model.shared (Route.fromUrl () model.url)) |> List.map Main.Pages.Msg.Account_SourceRepos |> List.map Page |> toCommands @@ -3247,7 +3251,7 @@ toPageUrlHookCmd model routes = Main.Pages.Model.Dash_Secrets_Engine__Org_Org_ params pageModel -> Auth.Action.command (\user -> - Page.toUrlMessages routes (Pages.Dash.Secrets.Engine_.Org.Org_.page user model.shared (Route.fromUrl params model.url)) + Page.toUrlMessages routes (Pages.Dash.Secrets.Engine_.Org.Org_.page user model.shared (Route.fromUrl params model.url)) |> List.map Main.Pages.Msg.Dash_Secrets_Engine__Org_Org_ |> List.map Page |> toCommands @@ -3257,7 +3261,7 @@ toPageUrlHookCmd model routes = Main.Pages.Model.Dash_Secrets_Engine__Org_Org__Add params pageModel -> Auth.Action.command (\user -> - Page.toUrlMessages routes (Pages.Dash.Secrets.Engine_.Org.Org_.Add.page user model.shared (Route.fromUrl params model.url)) + Page.toUrlMessages routes (Pages.Dash.Secrets.Engine_.Org.Org_.Add.page user model.shared (Route.fromUrl params model.url)) |> List.map Main.Pages.Msg.Dash_Secrets_Engine__Org_Org__Add |> List.map Page |> toCommands @@ -3267,7 +3271,7 @@ toPageUrlHookCmd model routes = Main.Pages.Model.Dash_Secrets_Engine__Org_Org__Name_ params pageModel -> Auth.Action.command (\user -> - Page.toUrlMessages routes (Pages.Dash.Secrets.Engine_.Org.Org_.Name_.page user model.shared (Route.fromUrl params model.url)) + Page.toUrlMessages routes (Pages.Dash.Secrets.Engine_.Org.Org_.Name_.page user model.shared (Route.fromUrl params model.url)) |> List.map Main.Pages.Msg.Dash_Secrets_Engine__Org_Org__Name_ |> List.map Page |> toCommands @@ -3277,7 +3281,7 @@ toPageUrlHookCmd model routes = Main.Pages.Model.Dash_Secrets_Engine__Repo_Org__Repo_ params pageModel -> Auth.Action.command (\user -> - Page.toUrlMessages routes (Pages.Dash.Secrets.Engine_.Repo.Org_.Repo_.page user model.shared (Route.fromUrl params model.url)) + Page.toUrlMessages routes (Pages.Dash.Secrets.Engine_.Repo.Org_.Repo_.page user model.shared (Route.fromUrl params model.url)) |> List.map Main.Pages.Msg.Dash_Secrets_Engine__Repo_Org__Repo_ |> List.map Page |> toCommands @@ -3287,7 +3291,7 @@ toPageUrlHookCmd model routes = Main.Pages.Model.Dash_Secrets_Engine__Repo_Org__Repo__Add params pageModel -> Auth.Action.command (\user -> - Page.toUrlMessages routes (Pages.Dash.Secrets.Engine_.Repo.Org_.Repo_.Add.page user model.shared (Route.fromUrl params model.url)) + Page.toUrlMessages routes (Pages.Dash.Secrets.Engine_.Repo.Org_.Repo_.Add.page user model.shared (Route.fromUrl params model.url)) |> List.map Main.Pages.Msg.Dash_Secrets_Engine__Repo_Org__Repo__Add |> List.map Page |> toCommands @@ -3297,7 +3301,7 @@ toPageUrlHookCmd model routes = Main.Pages.Model.Dash_Secrets_Engine__Repo_Org__Repo__Name_ params pageModel -> Auth.Action.command (\user -> - Page.toUrlMessages routes (Pages.Dash.Secrets.Engine_.Repo.Org_.Repo_.Name_.page user model.shared (Route.fromUrl params model.url)) + Page.toUrlMessages routes (Pages.Dash.Secrets.Engine_.Repo.Org_.Repo_.Name_.page user model.shared (Route.fromUrl params model.url)) |> List.map Main.Pages.Msg.Dash_Secrets_Engine__Repo_Org__Repo__Name_ |> List.map Page |> toCommands @@ -3307,7 +3311,7 @@ toPageUrlHookCmd model routes = Main.Pages.Model.Dash_Secrets_Engine__Shared_Org__Team_ params pageModel -> Auth.Action.command (\user -> - Page.toUrlMessages routes (Pages.Dash.Secrets.Engine_.Shared.Org_.Team_.page user model.shared (Route.fromUrl params model.url)) + Page.toUrlMessages routes (Pages.Dash.Secrets.Engine_.Shared.Org_.Team_.page user model.shared (Route.fromUrl params model.url)) |> List.map Main.Pages.Msg.Dash_Secrets_Engine__Shared_Org__Team_ |> List.map Page |> toCommands @@ -3317,7 +3321,7 @@ toPageUrlHookCmd model routes = Main.Pages.Model.Dash_Secrets_Engine__Shared_Org__Team__Add params pageModel -> Auth.Action.command (\user -> - Page.toUrlMessages routes (Pages.Dash.Secrets.Engine_.Shared.Org_.Team_.Add.page user model.shared (Route.fromUrl params model.url)) + Page.toUrlMessages routes (Pages.Dash.Secrets.Engine_.Shared.Org_.Team_.Add.page user model.shared (Route.fromUrl params model.url)) |> List.map Main.Pages.Msg.Dash_Secrets_Engine__Shared_Org__Team__Add |> List.map Page |> toCommands @@ -3327,7 +3331,7 @@ toPageUrlHookCmd model routes = Main.Pages.Model.Dash_Secrets_Engine__Shared_Org__Team__Name_ params pageModel -> Auth.Action.command (\user -> - Page.toUrlMessages routes (Pages.Dash.Secrets.Engine_.Shared.Org_.Team_.Name_.page user model.shared (Route.fromUrl params model.url)) + Page.toUrlMessages routes (Pages.Dash.Secrets.Engine_.Shared.Org_.Team_.Name_.page user model.shared (Route.fromUrl params model.url)) |> List.map Main.Pages.Msg.Dash_Secrets_Engine__Shared_Org__Team__Name_ |> List.map Page |> toCommands @@ -3337,7 +3341,7 @@ toPageUrlHookCmd model routes = Main.Pages.Model.Dashboards pageModel -> Auth.Action.command (\user -> - Page.toUrlMessages routes (Pages.Dashboards.page user model.shared (Route.fromUrl () model.url)) + Page.toUrlMessages routes (Pages.Dashboards.page user model.shared (Route.fromUrl () model.url)) |> List.map Main.Pages.Msg.Dashboards |> List.map Page |> toCommands @@ -3347,7 +3351,7 @@ toPageUrlHookCmd model routes = Main.Pages.Model.Dashboards_Dashboard_ params pageModel -> Auth.Action.command (\user -> - Page.toUrlMessages routes (Pages.Dashboards.Dashboard_.page user model.shared (Route.fromUrl params model.url)) + Page.toUrlMessages routes (Pages.Dashboards.Dashboard_.page user model.shared (Route.fromUrl params model.url)) |> List.map Main.Pages.Msg.Dashboards_Dashboard_ |> List.map Page |> toCommands @@ -3357,7 +3361,7 @@ toPageUrlHookCmd model routes = Main.Pages.Model.Org_ params pageModel -> Auth.Action.command (\user -> - Page.toUrlMessages routes (Pages.Org_.page user model.shared (Route.fromUrl params model.url)) + Page.toUrlMessages routes (Pages.Org_.page user model.shared (Route.fromUrl params model.url)) |> List.map Main.Pages.Msg.Org_ |> List.map Page |> toCommands @@ -3367,7 +3371,7 @@ toPageUrlHookCmd model routes = Main.Pages.Model.Org__Builds params pageModel -> Auth.Action.command (\user -> - Page.toUrlMessages routes (Pages.Org_.Builds.page user model.shared (Route.fromUrl params model.url)) + Page.toUrlMessages routes (Pages.Org_.Builds.page user model.shared (Route.fromUrl params model.url)) |> List.map Main.Pages.Msg.Org__Builds |> List.map Page |> toCommands @@ -3377,7 +3381,7 @@ toPageUrlHookCmd model routes = Main.Pages.Model.Org__Repo_ params pageModel -> Auth.Action.command (\user -> - Page.toUrlMessages routes (Pages.Org_.Repo_.page user model.shared (Route.fromUrl params model.url)) + Page.toUrlMessages routes (Pages.Org_.Repo_.page user model.shared (Route.fromUrl params model.url)) |> List.map Main.Pages.Msg.Org__Repo_ |> List.map Page |> toCommands @@ -3387,7 +3391,7 @@ toPageUrlHookCmd model routes = Main.Pages.Model.Org__Repo__Deployments params pageModel -> Auth.Action.command (\user -> - Page.toUrlMessages routes (Pages.Org_.Repo_.Deployments.page user model.shared (Route.fromUrl params model.url)) + Page.toUrlMessages routes (Pages.Org_.Repo_.Deployments.page user model.shared (Route.fromUrl params model.url)) |> List.map Main.Pages.Msg.Org__Repo__Deployments |> List.map Page |> toCommands @@ -3397,7 +3401,7 @@ toPageUrlHookCmd model routes = Main.Pages.Model.Org__Repo__Deployments_Add params pageModel -> Auth.Action.command (\user -> - Page.toUrlMessages routes (Pages.Org_.Repo_.Deployments.Add.page user model.shared (Route.fromUrl params model.url)) + Page.toUrlMessages routes (Pages.Org_.Repo_.Deployments.Add.page user model.shared (Route.fromUrl params model.url)) |> List.map Main.Pages.Msg.Org__Repo__Deployments_Add |> List.map Page |> toCommands @@ -3407,7 +3411,7 @@ toPageUrlHookCmd model routes = Main.Pages.Model.Org__Repo__Hooks params pageModel -> Auth.Action.command (\user -> - Page.toUrlMessages routes (Pages.Org_.Repo_.Hooks.page user model.shared (Route.fromUrl params model.url)) + Page.toUrlMessages routes (Pages.Org_.Repo_.Hooks.page user model.shared (Route.fromUrl params model.url)) |> List.map Main.Pages.Msg.Org__Repo__Hooks |> List.map Page |> toCommands @@ -3415,7 +3419,7 @@ toPageUrlHookCmd model routes = (Auth.onPageLoad model.shared (Route.fromUrl () model.url)) Main.Pages.Model.Org__Repo__Pulls params pageModel -> - Page.toUrlMessages routes (Pages.Org_.Repo_.Pulls.page model.shared (Route.fromUrl params model.url)) + Page.toUrlMessages routes (Pages.Org_.Repo_.Pulls.page model.shared (Route.fromUrl params model.url)) |> List.map Main.Pages.Msg.Org__Repo__Pulls |> List.map Page |> toCommands @@ -3423,7 +3427,7 @@ toPageUrlHookCmd model routes = Main.Pages.Model.Org__Repo__Schedules params pageModel -> Auth.Action.command (\user -> - Page.toUrlMessages routes (Pages.Org_.Repo_.Schedules.page user model.shared (Route.fromUrl params model.url)) + Page.toUrlMessages routes (Pages.Org_.Repo_.Schedules.page user model.shared (Route.fromUrl params model.url)) |> List.map Main.Pages.Msg.Org__Repo__Schedules |> List.map Page |> toCommands @@ -3433,7 +3437,7 @@ toPageUrlHookCmd model routes = Main.Pages.Model.Org__Repo__Schedules_Add params pageModel -> Auth.Action.command (\user -> - Page.toUrlMessages routes (Pages.Org_.Repo_.Schedules.Add.page user model.shared (Route.fromUrl params model.url)) + Page.toUrlMessages routes (Pages.Org_.Repo_.Schedules.Add.page user model.shared (Route.fromUrl params model.url)) |> List.map Main.Pages.Msg.Org__Repo__Schedules_Add |> List.map Page |> toCommands @@ -3443,7 +3447,7 @@ toPageUrlHookCmd model routes = Main.Pages.Model.Org__Repo__Schedules_Name_ params pageModel -> Auth.Action.command (\user -> - Page.toUrlMessages routes (Pages.Org_.Repo_.Schedules.Name_.page user model.shared (Route.fromUrl params model.url)) + Page.toUrlMessages routes (Pages.Org_.Repo_.Schedules.Name_.page user model.shared (Route.fromUrl params model.url)) |> List.map Main.Pages.Msg.Org__Repo__Schedules_Name_ |> List.map Page |> toCommands @@ -3453,7 +3457,7 @@ toPageUrlHookCmd model routes = Main.Pages.Model.Org__Repo__Settings params pageModel -> Auth.Action.command (\user -> - Page.toUrlMessages routes (Pages.Org_.Repo_.Settings.page user model.shared (Route.fromUrl params model.url)) + Page.toUrlMessages routes (Pages.Org_.Repo_.Settings.page user model.shared (Route.fromUrl params model.url)) |> List.map Main.Pages.Msg.Org__Repo__Settings |> List.map Page |> toCommands @@ -3461,7 +3465,7 @@ toPageUrlHookCmd model routes = (Auth.onPageLoad model.shared (Route.fromUrl () model.url)) Main.Pages.Model.Org__Repo__Tags params pageModel -> - Page.toUrlMessages routes (Pages.Org_.Repo_.Tags.page model.shared (Route.fromUrl params model.url)) + Page.toUrlMessages routes (Pages.Org_.Repo_.Tags.page model.shared (Route.fromUrl params model.url)) |> List.map Main.Pages.Msg.Org__Repo__Tags |> List.map Page |> toCommands @@ -3469,7 +3473,7 @@ toPageUrlHookCmd model routes = Main.Pages.Model.Org__Repo__Build_ params pageModel -> Auth.Action.command (\user -> - Page.toUrlMessages routes (Pages.Org_.Repo_.Build_.page user model.shared (Route.fromUrl params model.url)) + Page.toUrlMessages routes (Pages.Org_.Repo_.Build_.page user model.shared (Route.fromUrl params model.url)) |> List.map Main.Pages.Msg.Org__Repo__Build_ |> List.map Page |> toCommands @@ -3479,7 +3483,7 @@ toPageUrlHookCmd model routes = Main.Pages.Model.Org__Repo__Build__Graph params pageModel -> Auth.Action.command (\user -> - Page.toUrlMessages routes (Pages.Org_.Repo_.Build_.Graph.page user model.shared (Route.fromUrl params model.url)) + Page.toUrlMessages routes (Pages.Org_.Repo_.Build_.Graph.page user model.shared (Route.fromUrl params model.url)) |> List.map Main.Pages.Msg.Org__Repo__Build__Graph |> List.map Page |> toCommands @@ -3489,7 +3493,7 @@ toPageUrlHookCmd model routes = Main.Pages.Model.Org__Repo__Build__Pipeline params pageModel -> Auth.Action.command (\user -> - Page.toUrlMessages routes (Pages.Org_.Repo_.Build_.Pipeline.page user model.shared (Route.fromUrl params model.url)) + Page.toUrlMessages routes (Pages.Org_.Repo_.Build_.Pipeline.page user model.shared (Route.fromUrl params model.url)) |> List.map Main.Pages.Msg.Org__Repo__Build__Pipeline |> List.map Page |> toCommands @@ -3499,7 +3503,7 @@ toPageUrlHookCmd model routes = Main.Pages.Model.Org__Repo__Build__Services params pageModel -> Auth.Action.command (\user -> - Page.toUrlMessages routes (Pages.Org_.Repo_.Build_.Services.page user model.shared (Route.fromUrl params model.url)) + Page.toUrlMessages routes (Pages.Org_.Repo_.Build_.Services.page user model.shared (Route.fromUrl params model.url)) |> List.map Main.Pages.Msg.Org__Repo__Build__Services |> List.map Page |> toCommands @@ -3507,7 +3511,7 @@ toPageUrlHookCmd model routes = (Auth.onPageLoad model.shared (Route.fromUrl () model.url)) Main.Pages.Model.NotFound_ pageModel -> - Page.toUrlMessages routes (Pages.NotFound_.page model.shared (Route.fromUrl () model.url)) + Page.toUrlMessages routes (Pages.NotFound_.page model.shared (Route.fromUrl () model.url)) |> List.map Main.Pages.Msg.NotFound_ |> List.map Page |> toCommands @@ -3572,13 +3576,13 @@ toLayoutUrlHookCmd oldModel model routes = in Cmd.batch [ Layout.toUrlMessages routes (Layouts.Default.layout defaultProps model.shared route) - |> List.map Main.Layouts.Msg.Default - |> List.map Layout - |> toCommands + |> List.map Main.Layouts.Msg.Default + |> List.map Layout + |> toCommands , Layout.toUrlMessages routes (Layouts.Default.Build.layout props model.shared route) - |> List.map Main.Layouts.Msg.Default_Build - |> List.map Layout - |> toCommands + |> List.map Main.Layouts.Msg.Default_Build + |> List.map Layout + |> toCommands ] ( Just (Layouts.Default_Org props), Just (Main.Layouts.Model.Default_Org layoutModel) ) -> @@ -3589,13 +3593,13 @@ toLayoutUrlHookCmd oldModel model routes = in Cmd.batch [ Layout.toUrlMessages routes (Layouts.Default.layout defaultProps model.shared route) - |> List.map Main.Layouts.Msg.Default - |> List.map Layout - |> toCommands + |> List.map Main.Layouts.Msg.Default + |> List.map Layout + |> toCommands , Layout.toUrlMessages routes (Layouts.Default.Org.layout props model.shared route) - |> List.map Main.Layouts.Msg.Default_Org - |> List.map Layout - |> toCommands + |> List.map Main.Layouts.Msg.Default_Org + |> List.map Layout + |> toCommands ] ( Just (Layouts.Default_Repo props), Just (Main.Layouts.Model.Default_Repo layoutModel) ) -> @@ -3606,13 +3610,13 @@ toLayoutUrlHookCmd oldModel model routes = in Cmd.batch [ Layout.toUrlMessages routes (Layouts.Default.layout defaultProps model.shared route) - |> List.map Main.Layouts.Msg.Default - |> List.map Layout - |> toCommands + |> List.map Main.Layouts.Msg.Default + |> List.map Layout + |> toCommands , Layout.toUrlMessages routes (Layouts.Default.Repo.layout props model.shared route) - |> List.map Main.Layouts.Msg.Default_Repo - |> List.map Layout - |> toCommands + |> List.map Main.Layouts.Msg.Default_Repo + |> List.map Layout + |> toCommands ] _ -> diff --git a/src/elm/Main/Pages/Model.elm b/src/elm/Main/Pages/Model.elm index 011ae8081..c9d771308 100644 --- a/src/elm/Main/Pages/Model.elm +++ b/src/elm/Main/Pages/Model.elm @@ -5,7 +5,6 @@ SPDX-License-Identifier: Apache-2.0 module Main.Pages.Model exposing (Model(..)) -import Pages.Home_ import Pages.Account.Authenticate import Pages.Account.Login import Pages.Account.Logout @@ -24,9 +23,15 @@ import Pages.Dash.Secrets.Engine_.Shared.Org_.Team_.Add import Pages.Dash.Secrets.Engine_.Shared.Org_.Team_.Name_ import Pages.Dashboards import Pages.Dashboards.Dashboard_ +import Pages.Home_ +import Pages.NotFound_ import Pages.Org_ import Pages.Org_.Builds import Pages.Org_.Repo_ +import Pages.Org_.Repo_.Build_ +import Pages.Org_.Repo_.Build_.Graph +import Pages.Org_.Repo_.Build_.Pipeline +import Pages.Org_.Repo_.Build_.Services import Pages.Org_.Repo_.Deployments import Pages.Org_.Repo_.Deployments.Add import Pages.Org_.Repo_.Hooks @@ -36,11 +41,6 @@ import Pages.Org_.Repo_.Schedules.Add import Pages.Org_.Repo_.Schedules.Name_ import Pages.Org_.Repo_.Settings import Pages.Org_.Repo_.Tags -import Pages.Org_.Repo_.Build_ -import Pages.Org_.Repo_.Build_.Graph -import Pages.Org_.Repo_.Build_.Pipeline -import Pages.Org_.Repo_.Build_.Services -import Pages.NotFound_ import View exposing (View) diff --git a/src/elm/Main/Pages/Msg.elm b/src/elm/Main/Pages/Msg.elm index 9dae985a8..84e1f3f5c 100644 --- a/src/elm/Main/Pages/Msg.elm +++ b/src/elm/Main/Pages/Msg.elm @@ -5,7 +5,6 @@ SPDX-License-Identifier: Apache-2.0 module Main.Pages.Msg exposing (Msg(..)) -import Pages.Home_ import Pages.Account.Authenticate import Pages.Account.Login import Pages.Account.Logout @@ -24,9 +23,15 @@ import Pages.Dash.Secrets.Engine_.Shared.Org_.Team_.Add import Pages.Dash.Secrets.Engine_.Shared.Org_.Team_.Name_ import Pages.Dashboards import Pages.Dashboards.Dashboard_ +import Pages.Home_ +import Pages.NotFound_ import Pages.Org_ import Pages.Org_.Builds import Pages.Org_.Repo_ +import Pages.Org_.Repo_.Build_ +import Pages.Org_.Repo_.Build_.Graph +import Pages.Org_.Repo_.Build_.Pipeline +import Pages.Org_.Repo_.Build_.Services import Pages.Org_.Repo_.Deployments import Pages.Org_.Repo_.Deployments.Add import Pages.Org_.Repo_.Hooks @@ -36,11 +41,6 @@ import Pages.Org_.Repo_.Schedules.Add import Pages.Org_.Repo_.Schedules.Name_ import Pages.Org_.Repo_.Settings import Pages.Org_.Repo_.Tags -import Pages.Org_.Repo_.Build_ -import Pages.Org_.Repo_.Build_.Graph -import Pages.Org_.Repo_.Build_.Pipeline -import Pages.Org_.Repo_.Build_.Services -import Pages.NotFound_ type Msg diff --git a/src/elm/Pages/Dashboards/Dashboard_.elm b/src/elm/Pages/Dashboards/Dashboard_.elm index 4782c5c13..4ee5a03d4 100644 --- a/src/elm/Pages/Dashboards/Dashboard_.elm +++ b/src/elm/Pages/Dashboards/Dashboard_.elm @@ -13,10 +13,12 @@ import Components.Nav import Effect exposing (Effect) import Html exposing - ( div + ( br + , code + , div , h1 , main_ - , code + , p , span , text ) @@ -38,8 +40,6 @@ import Utils.Helpers as Util import Utils.Interval as Interval import Vela import View exposing (View) -import Html exposing (p) -import Html exposing (br) {-| page : takes user, shared model, route, and returns the dashboard page. @@ -224,7 +224,7 @@ view shared route model = [] [ text "This dashboard doesn't have repositories added yet. Add some with the CLI:" , br [] [] - , code [ class "shell" ] + , code [ class "shell" ] [ text ("vela update dashboard --id " ++ route.params.dashboard ++ " --add-repos org/repo") ] ] ] diff --git a/src/elm/Route.elm b/src/elm/Route.elm index aaa807a92..9468bbafb 100644 --- a/src/elm/Route.elm +++ b/src/elm/Route.elm @@ -44,6 +44,6 @@ toString route = [ Route.Path.toString route.path , Route.Query.toString route.query , route.hash - |> Maybe.map (String.append "#") - |> Maybe.withDefault "" + |> Maybe.map (String.append "#") + |> Maybe.withDefault "" ] diff --git a/src/elm/Route/Query.elm b/src/elm/Route/Query.elm index d7ecd4991..0cfabb738 100644 --- a/src/elm/Route/Query.elm +++ b/src/elm/Route/Query.elm @@ -7,8 +7,8 @@ module Route.Query exposing (fromUrl, toString) import Dict exposing (Dict) import Url exposing (Url) -import Url.Parser exposing (query) import Url.Builder exposing (QueryParameter) +import Url.Parser exposing (query) fromUrl : Url -> Dict String String @@ -28,7 +28,7 @@ fromUrl url = |> Dict.fromList -queryPiecesToTuple : List String -> Maybe (String, String) +queryPiecesToTuple : List String -> Maybe ( String, String ) queryPiecesToTuple pieces = case pieces of [] -> @@ -55,6 +55,6 @@ toString queryParameterList = |> Url.Builder.toQuery -tupleToQueryPiece : (String, String) -> QueryParameter +tupleToQueryPiece : ( String, String ) -> QueryParameter tupleToQueryPiece ( key, value ) = Url.Builder.string key value diff --git a/src/scss/_main.scss b/src/scss/_main.scss index e865af718..81f6e4218 100644 --- a/src/scss/_main.scss +++ b/src/scss/_main.scss @@ -1752,14 +1752,14 @@ code.shell { display: inline-block; margin: 1rem 0; padding: 0.75rem 1rem 0.75rem 2rem; - + background-color: var(--color-bg-dark); &::before { position: absolute; top: 50%; left: 0.8rem; - + display: block; color: var(--color-green); diff --git a/src/scss/_variables.scss b/src/scss/_variables.scss index 6406d867b..6f4e130a6 100644 --- a/src/scss/_variables.scss +++ b/src/scss/_variables.scss @@ -12,7 +12,7 @@ --color-lavender-light: hsl(286, 29%, 65%); // good for text on coal // grays - --color-coal-darkest: hsl(0, 0%, 10%); + --color-coal-darkest: hsl(0, 0%, 10%); --color-coal-dark: hsl(0, 0%, 12%); --color-coal: hsl(0, 0%, 16%); // main dark bg --color-coal-light: hsl(0, 0%, 34%); From 3ceed599bb63f8ee58acb0f2eeea7488770d20c1 Mon Sep 17 00:00:00 2001 From: wass3rw3rk <49894298+wass3rw3rk@users.noreply.github.com> Date: Mon, 20 May 2024 15:31:21 -0500 Subject: [PATCH 15/23] wasn't meant to be added --- elm-land.json | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 elm-land.json diff --git a/elm-land.json b/elm-land.json deleted file mode 100644 index f73c99500..000000000 --- a/elm-land.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "app":{ - "config":{ - "router":{} - } - } -} \ No newline at end of file From aee1d088b76385b4367881fccb959d35791f4e17 Mon Sep 17 00:00:00 2001 From: wass3rw3rk <49894298+wass3rw3rk@users.noreply.github.com> Date: Mon, 20 May 2024 15:38:56 -0500 Subject: [PATCH 16/23] fix comment --- src/elm/Utils/Helpers.elm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/elm/Utils/Helpers.elm b/src/elm/Utils/Helpers.elm index fc2e622e4..470bf98ff 100644 --- a/src/elm/Utils/Helpers.elm +++ b/src/elm/Utils/Helpers.elm @@ -230,7 +230,7 @@ formatRunTime now started finished = seconds = runTimeSeconds runtime in - -- smallest units is seconds + -- treating 00:00 as an unreasonable runtime state if minutes == "00" && seconds == "00" then "--:--" From 7a5fd075e752ab7d1b716c11f66fd0c2dd320a07 Mon Sep 17 00:00:00 2001 From: Kelly Merrick Date: Tue, 21 May 2024 14:41:59 -0500 Subject: [PATCH 17/23] feat(dashboard): handle icon cyan in light theme --- src/scss/_themes.scss | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/scss/_themes.scss b/src/scss/_themes.scss index 5a7880f2a..c646a00a2 100644 --- a/src/scss/_themes.scss +++ b/src/scss/_themes.scss @@ -249,4 +249,19 @@ body.theme-light { } } +// dashboards +.theme-light .card-header .-canceled { + background-color: var(--color-cyan-semi-dark); +} + +.theme-light .dashboard-recent-builds .recent-build:not(:first-child) .-canceled { + background-color: var(--color-gray-lightest); + border-color: (--color-cyan-semi-dark); + stroke: var(--color-cyan-semi-dark); +} + +.theme-light .recent-build-link.-current:has(.-canceled)::before { + background-color: var(--color-cyan-semi-dark); +} + /*! purgecss end ignore */ From e064a54b596428a14fa30fa7ecacdac40c473828 Mon Sep 17 00:00:00 2001 From: Kelly Merrick Date: Tue, 21 May 2024 15:06:20 -0500 Subject: [PATCH 18/23] feat(dashboard): fix a couple linter issues --- src/scss/_themes.scss | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/scss/_themes.scss b/src/scss/_themes.scss index c646a00a2..837040807 100644 --- a/src/scss/_themes.scss +++ b/src/scss/_themes.scss @@ -256,7 +256,8 @@ body.theme-light { .theme-light .dashboard-recent-builds .recent-build:not(:first-child) .-canceled { background-color: var(--color-gray-lightest); - border-color: (--color-cyan-semi-dark); + border-color: var(--color-cyan-semi-dark); + stroke: var(--color-cyan-semi-dark); } From b0860a07f53eb1c7ef1ebc293e4c19e53504e266 Mon Sep 17 00:00:00 2001 From: Kelly Merrick Date: Wed, 22 May 2024 12:02:01 -0500 Subject: [PATCH 19/23] feat(dashboard): handle icon cyan in light theme --- src/scss/_themes.scss | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/src/scss/_themes.scss b/src/scss/_themes.scss index 837040807..8a8ba52b3 100644 --- a/src/scss/_themes.scss +++ b/src/scss/_themes.scss @@ -40,7 +40,7 @@ body.theme-light { --color-primary: var(--color-lavender); // ok for text --color-primary-light: var(--color-lavender-light); - --color-secondary-dark: var(--color-cyan-dark); + --color-secondary-dark: var(--color-cyan-semi-dark); --color-secondary: var(--color-cyan); --color-secondary-light: var(--color-cyan-light); @@ -65,16 +65,16 @@ body.theme-light { } .status.-canceled { - background-color: var(--color-cyan-semi-dark); + background-color: var(--color-secondary-dark); } .recent-build-link .-icon.-canceled { - background-color: var(--color-cyan-semi-dark); + background-color: var(--color-secondary-dark); } .steps .-icon.-canceled, .services .-icon.-canceled { - stroke: var(--color-cyan-semi-dark); + stroke: var(--color-secondary-dark); } .hooks { @@ -254,15 +254,21 @@ body.theme-light { background-color: var(--color-cyan-semi-dark); } -.theme-light .dashboard-recent-builds .recent-build:not(:first-child) .-canceled { +/* stylelint-disable selector-max-compound-selectors */ +.theme-light + .dashboard-recent-builds + .recent-build:not(:first-child) + .-canceled { background-color: var(--color-gray-lightest); - border-color: var(--color-cyan-semi-dark); + border-color: var(--color-secondary-dark); - stroke: var(--color-cyan-semi-dark); + stroke: var(--color-secondary-dark); } +/* stylelint-enable selector-max-compound-selectors */ + .theme-light .recent-build-link.-current:has(.-canceled)::before { - background-color: var(--color-cyan-semi-dark); + background-color: var(--color-secondary-dark); } /*! purgecss end ignore */ From 0095fa4ee087465eb738363069b2bf542c336d7d Mon Sep 17 00:00:00 2001 From: Kelly Merrick Date: Wed, 22 May 2024 12:51:19 -0500 Subject: [PATCH 20/23] feat(dashboard): add comments for card component --- src/elm/Components/DashboardRepoCard.elm | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/elm/Components/DashboardRepoCard.elm b/src/elm/Components/DashboardRepoCard.elm index 69f1794a7..557ecc95f 100644 --- a/src/elm/Components/DashboardRepoCard.elm +++ b/src/elm/Components/DashboardRepoCard.elm @@ -40,11 +40,14 @@ import Utils.Helpers as Util import Vela +{-| Props : alias for an object representing properties for a dashboard repo card component. +-} type alias Props = { card : Vela.DashboardRepoCard } - +{-| view : renders a dashboard repo card component. +-} view : Shared.Model -> Props -> Html msg view shared props = let From 4bf950a0886c0d57308adc95388d47dfc3b0cf20 Mon Sep 17 00:00:00 2001 From: Kelly Merrick Date: Fri, 24 May 2024 13:34:26 -0500 Subject: [PATCH 21/23] feat(dashboard): elm-format --- src/elm/Components/DashboardRepoCard.elm | 1 + 1 file changed, 1 insertion(+) diff --git a/src/elm/Components/DashboardRepoCard.elm b/src/elm/Components/DashboardRepoCard.elm index 557ecc95f..abfe8db13 100644 --- a/src/elm/Components/DashboardRepoCard.elm +++ b/src/elm/Components/DashboardRepoCard.elm @@ -46,6 +46,7 @@ type alias Props = { card : Vela.DashboardRepoCard } + {-| view : renders a dashboard repo card component. -} view : Shared.Model -> Props -> Html msg From 84c7a6d0f2f449e615599fabd3c5c3b8f96c9ad7 Mon Sep 17 00:00:00 2001 From: Kelly Merrick Date: Wed, 29 May 2024 09:41:16 -0500 Subject: [PATCH 22/23] feat(dashboard): addressing feedback --- src/elm/Components/DashboardRepoCard.elm | 3 ++- src/elm/Components/RecentBuilds.elm | 1 - src/elm/Pages/Dashboards.elm | 2 +- src/elm/Pages/Dashboards/Dashboard_.elm | 4 ++-- src/scss/_dashboards.scss | 2 +- src/scss/_main.scss | 19 +++++++++++++++++-- 6 files changed, 23 insertions(+), 8 deletions(-) diff --git a/src/elm/Components/DashboardRepoCard.elm b/src/elm/Components/DashboardRepoCard.elm index abfe8db13..df62dc0a3 100644 --- a/src/elm/Components/DashboardRepoCard.elm +++ b/src/elm/Components/DashboardRepoCard.elm @@ -176,7 +176,8 @@ view shared props = -- sender , li [] - [ span [] [ text <| cardProps.sender ] + [ span + [ Util.attrIf (String.length cardProps.sender > 15) (title cardProps.sender) ] [ text <| cardProps.sender ] , FeatherIcons.user |> FeatherIcons.withSize 20 |> FeatherIcons.toHtml [ attribute "aria-label" "build-sender icon" ] diff --git a/src/elm/Components/RecentBuilds.elm b/src/elm/Components/RecentBuilds.elm index 814c12b99..855c23114 100644 --- a/src/elm/Components/RecentBuilds.elm +++ b/src/elm/Components/RecentBuilds.elm @@ -5,7 +5,6 @@ SPDX-License-Identifier: Apache-2.0 module Components.RecentBuilds exposing (view) --- import Utils.Errors exposing (showAlertAlways) import Components.Loading import Components.Svgs diff --git a/src/elm/Pages/Dashboards.elm b/src/elm/Pages/Dashboards.elm index 09c63b37f..1e4b36d75 100644 --- a/src/elm/Pages/Dashboards.elm +++ b/src/elm/Pages/Dashboards.elm @@ -62,7 +62,7 @@ toLayout user route model = , { name = "Add Dashboard With Multiple Admins" , content = "vela add dashboard --name MyDashboard --admins username1,username2" , docs = Just "dashboard/add" - } + } ] } diff --git a/src/elm/Pages/Dashboards/Dashboard_.elm b/src/elm/Pages/Dashboards/Dashboard_.elm index 4ee5a03d4..1f37abfdf 100644 --- a/src/elm/Pages/Dashboards/Dashboard_.elm +++ b/src/elm/Pages/Dashboards/Dashboard_.elm @@ -253,10 +253,10 @@ view shared route model = "Dashboard \"" ++ route.params.dashboard ++ "\" not found. Please check the URL." _ -> - "No dashboard found; there was an error with the server" + "No dashboard found, there was an error with the server" _ -> - "No dashboard found; there was an error with the server" + "No dashboard found, there was an error with the server" ] ] diff --git a/src/scss/_dashboards.scss b/src/scss/_dashboards.scss index f4b5325bd..a7eaeda9b 100644 --- a/src/scss/_dashboards.scss +++ b/src/scss/_dashboards.scss @@ -34,7 +34,7 @@ background-color: var(--color-bg-darkest); - // custon styling for the status icon + // custom styling for the status icon .-icon { width: 2.5rem; height: 2.5rem; diff --git a/src/scss/_main.scss b/src/scss/_main.scss index 93cb34b7c..ffeddad75 100644 --- a/src/scss/_main.scss +++ b/src/scss/_main.scss @@ -1419,21 +1419,36 @@ details.build-toggle { } .cmd { + position: relative; display: flex; justify-content: space-between; + + &::before { + position: absolute; + top: 52%; + left: 0.5rem; + + display: block; + + color: var(--color-green); + + transform: translateY(-52%); + + content: '$'; + } } .cmd-text { flex: 1; margin: 0.2rem 0; - padding: 0.5rem; + padding: 0.5rem 0.5rem 0.5rem 1.5rem; color: var(--color-text); background-color: var(--color-bg); border: none; - + .button { + + .vert-icon-container { margin-left: 0.5rem; } } From 5d1e99e70a28a81e758daf7db6708032e7f320f6 Mon Sep 17 00:00:00 2001 From: Kelly Merrick Date: Wed, 29 May 2024 10:41:13 -0500 Subject: [PATCH 23/23] fix(dashboard): linter fixes --- src/elm/Components/DashboardRepoCard.elm | 3 ++- src/elm/Components/RecentBuilds.elm | 1 - src/elm/Pages/Dashboards.elm | 2 +- src/scss/_main.scss | 1 + 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/elm/Components/DashboardRepoCard.elm b/src/elm/Components/DashboardRepoCard.elm index df62dc0a3..4314849c1 100644 --- a/src/elm/Components/DashboardRepoCard.elm +++ b/src/elm/Components/DashboardRepoCard.elm @@ -177,7 +177,8 @@ view shared props = -- sender , li [] [ span - [ Util.attrIf (String.length cardProps.sender > 15) (title cardProps.sender) ] [ text <| cardProps.sender ] + [ Util.attrIf (String.length cardProps.sender > 15) (title cardProps.sender) ] + [ text <| cardProps.sender ] , FeatherIcons.user |> FeatherIcons.withSize 20 |> FeatherIcons.toHtml [ attribute "aria-label" "build-sender icon" ] diff --git a/src/elm/Components/RecentBuilds.elm b/src/elm/Components/RecentBuilds.elm index 855c23114..14ffbffc7 100644 --- a/src/elm/Components/RecentBuilds.elm +++ b/src/elm/Components/RecentBuilds.elm @@ -5,7 +5,6 @@ SPDX-License-Identifier: Apache-2.0 module Components.RecentBuilds exposing (view) - import Components.Loading import Components.Svgs import Html exposing (Html, a, div, em, li, p, span, text, ul) diff --git a/src/elm/Pages/Dashboards.elm b/src/elm/Pages/Dashboards.elm index 1e4b36d75..09c63b37f 100644 --- a/src/elm/Pages/Dashboards.elm +++ b/src/elm/Pages/Dashboards.elm @@ -62,7 +62,7 @@ toLayout user route model = , { name = "Add Dashboard With Multiple Admins" , content = "vela add dashboard --name MyDashboard --admins username1,username2" , docs = Just "dashboard/add" - } + } ] } diff --git a/src/scss/_main.scss b/src/scss/_main.scss index ffeddad75..161127bad 100644 --- a/src/scss/_main.scss +++ b/src/scss/_main.scss @@ -1420,6 +1420,7 @@ details.build-toggle { .cmd { position: relative; + display: flex; justify-content: space-between;