diff --git a/src/elm/Layouts/Default/Repo.elm b/src/elm/Layouts/Default/Repo.elm index 3727ff4a..f5f5fccb 100644 --- a/src/elm/Layouts/Default/Repo.elm +++ b/src/elm/Layouts/Default/Repo.elm @@ -15,16 +15,21 @@ import Dict exposing (Dict) import Effect exposing (Effect) import Html exposing (Html, main_) import Html.Attributes exposing (class) +import Http +import Http.Detailed import Layout exposing (Layout) import Layouts.Default +import RemoteData exposing (RemoteData, WebData) import Route exposing (Route) import Route.Path import Shared import Time import Url exposing (Url) +import Utils.Errors as Errors import Utils.Favicons as Favicons import Utils.Favorites as Favorites import Utils.Interval as Interval +import Vela import View exposing (View) @@ -77,7 +82,7 @@ layout props shared route = {-| Model : alias for a model object for the default repo layout. -} type alias Model = - { tabHistory : Dict String Url } + { tabHistory : Dict String Url, repo : WebData Vela.Repository } {-| init : takes in properties, shared model, route, and a content object and returns a model and effect. @@ -85,10 +90,18 @@ type alias Model = init : Props contentMsg -> Shared.Model -> Route () -> () -> ( Model, Effect Msg ) init props shared route _ = ( { tabHistory = Dict.empty + , repo = RemoteData.NotAsked } , Effect.batch [ Effect.updateFavicon { favicon = Favicons.defaultFavicon } , Effect.getCurrentUserShared {} + , Effect.getRepo + { baseUrl = shared.velaAPIBaseURL + , session = shared.session + , onResponse = GetRepoResponse + , org = props.org + , repo = props.repo + } , Effect.getRepoBuildsShared { pageNumber = Nothing , perPage = Nothing @@ -116,6 +129,8 @@ init props shared route _ = type Msg = -- BROWSER OnUrlChanged { from : Route (), to : Route () } + -- REPO + | GetRepoResponse (Result (Http.Detailed.Error String) ( Http.Metadata, Vela.Repository )) -- FAVORITES | ToggleFavorite String (Maybe String) -- REFRESH @@ -136,6 +151,27 @@ update props route msg model = , Effect.replaceRouteRemoveTabHistorySkipDomFocus route ) + -- REPO + GetRepoResponse response -> + case response of + Ok ( _, repo ) -> + ( { model + | repo = RemoteData.Success repo + } + , Effect.none + ) + + Err error -> + ( { model | repo = Errors.toFailure error } + , Effect.batch + [ Effect.handleHttpError + { error = error + , shouldShowAlertFn = Errors.showAlertAlways + } + , Effect.none + ] + ) + -- FAVORITES ToggleFavorite org maybeRepo -> ( model @@ -183,6 +219,49 @@ subscriptions model = -- VIEW +toT : WebData Vela.Repository -> Html msg +toT data = + case data of + RemoteData.NotAsked -> + Html.text "" + + RemoteData.Loading -> + Html.text "" + + RemoteData.Failure _ -> + Html.text "" + + RemoteData.Success r -> + if r.install_id == 0 then + installBanner r + + else + Html.text "" + + +installBanner : Vela.Repository -> Html msg +installBanner repo = + Html.div + [ class "banner" ] + [ Html.div [ Html.Attributes.class "warning" ] + [ Html.text "Please " + , Html.a + [ Html.Attributes.href "https://git.target.com/github-apps/vela-local/installations/new" + ] + [ Html.text "install" ] + , Html.text " the Vela GitHub App to this organization and make sure the repository is added." + ] + , Html.div [] + [ Html.text "If you've already added this repository to the installation, try clicking \"Sync Install\" in " + , Html.a + [ Route.Path.href <| Route.Path.Org__Repo__Settings { org = repo.org, repo = repo.name } + ] + [ Html.text "Settings" ] + , Html.text "." + ] + ] + + {-| view : takes in properties, shared model, route, and a content object and returns a view. -} view : Props contentMsg -> Shared.Model -> Route () -> { toContentMsg : Msg -> contentMsg, content : View contentMsg, model : Model } -> View contentMsg @@ -203,6 +282,7 @@ view props shared route { toContentMsg, model, content } = :: props.navButtons , crumbs = Components.Crumbs.view route.path props.crumbs } + , toT model.repo , main_ [ class "content-wrap" ] (Components.Util.view shared route diff --git a/src/elm/Pages/Org_/Repo_/Settings.elm b/src/elm/Pages/Org_/Repo_/Settings.elm index 09f9e6af..d6088cf9 100644 --- a/src/elm/Pages/Org_/Repo_/Settings.elm +++ b/src/elm/Pages/Org_/Repo_/Settings.elm @@ -1201,6 +1201,23 @@ viewAdminActions repo disableRepoMsg enableRepoMsg chownRepoMsg repairRepoMsg = ] , viewEnableButton (disableRepoMsg { repo = repo }) (enableRepoMsg { repo = repo }) repo ] + , div [ class "admin-action-container" ] + [ div [ class "admin-action-description" ] + [ text "Sync GitHub App Integration" + , small [] + [ em [] [ text "This will synchronize the Vela repository with installations and access given to the GitHub App.", + text " It will start the installation flow in the browser if GitHub changes are required." ] ] + ] + , button + [ class "button" + , class "-outline" + , attribute "aria-label" <| "sync the repo with the app installation for " ++ repo.full_name + , Util.testAttribute "repo-install-sync" + -- , onClick (chownRepoMsg { repo = repo }) + ] + [ text "Sync" ] + -- , viewEnableButton (disableRepoMsg { repo = repo }) (enableRepoMsg { repo = repo }) repo + ] ] diff --git a/src/scss/_main.scss b/src/scss/_main.scss index 161127ba..20b9d449 100644 --- a/src/scss/_main.scss +++ b/src/scss/_main.scss @@ -1781,3 +1781,30 @@ code.shell { content: '$'; } } + +.banner { + display: flex; + justify-content: space-between; + align-items: center; + padding: 1rem 0rem 1rem 1rem; + margin-top: 1rem; + + background-color: var(--color-bg-dark); + + border-top: 2px solid var(--color-yellow); + border-bottom: 2px solid var(--color-yellow); + display: flex; + flex-direction: column; + align-items: flex-start; + div { + margin-left: 1.2rem; + } + .warning::before{ + position: absolute; + left: 0.6rem; + content :'⚠️'; + } + & > *:not(:first-child) { + margin-top: 0.5rem; + } +} \ No newline at end of file