Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(dashboard): render dashboard page and repo cards #796

Merged
merged 32 commits into from
May 30, 2024
Merged
Show file tree
Hide file tree
Changes from 30 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
8ff3974
feat(dashboard): create scaffolding for a dashboard page
KellyMerrick Apr 25, 2024
bf91d67
ensure new route works
wass3rw3rk Apr 25, 2024
fdc97e3
feat(dashboard): ensure route is protected
KellyMerrick Apr 26, 2024
1bcaa01
feat(dashboard): renders unformatted dashboard and repo cards
KellyMerrick Apr 26, 2024
d4cdabe
Merge branch 'main' into feat/dashboard
KellyMerrick Apr 26, 2024
d94b7e8
feat(dashboard): most recent build info accessible
KellyMerrick Apr 29, 2024
4f11e8d
Merge branch 'feat/dashboard' of github.com:go-vela/ui into feat/dash…
KellyMerrick Apr 29, 2024
98fac96
feat(dashboard): populate all card data
KellyMerrick May 3, 2024
2852ce7
feat(dashboard): some styling progress, theme supported
KellyMerrick May 3, 2024
d8107e4
feat(dashboard): adtl general styling, icon styling
KellyMerrick May 8, 2024
a25d41c
feat(dashboard): handle RemoteData and truncate long text
KellyMerrick May 8, 2024
2dc85f7
Merge branch 'main' into feat/dashboard
wass3r May 14, 2024
aa0be75
cleaned up dashboards
wass3r May 20, 2024
408a5b5
only render tooltip fields if value is not empty
wass3r May 20, 2024
c8da938
make formatRunTime helper more resilient
wass3r May 20, 2024
58d706b
Merge branch 'main' into feat/dashboard
wass3r May 20, 2024
54b273c
improve no repos message
wass3rw3rk May 20, 2024
99dc004
lint fix
wass3rw3rk May 20, 2024
3ceed59
wasn't meant to be added
wass3rw3rk May 20, 2024
aee1d08
fix comment
wass3rw3rk May 20, 2024
7a5fd07
feat(dashboard): handle icon cyan in light theme
KellyMerrick May 21, 2024
c001f41
Merge branch 'main' of github.com:go-vela/ui into feat/dashboard
KellyMerrick May 21, 2024
14ec426
Merge branch 'main' into feat/dashboard
KellyMerrick May 21, 2024
e064a54
feat(dashboard): fix a couple linter issues
KellyMerrick May 21, 2024
b5e8bb0
Merge branch 'feat/dashboard' of github.com:go-vela/ui into feat/dash…
KellyMerrick May 21, 2024
b0860a0
feat(dashboard): handle icon cyan in light theme
KellyMerrick May 22, 2024
a6fde7f
Merge branch 'main' into feat/dashboard
KellyMerrick May 22, 2024
0095fa4
feat(dashboard): add comments for card component
KellyMerrick May 22, 2024
80302e3
Merge branch 'feat/dashboard' of github.com:go-vela/ui into feat/dash…
KellyMerrick May 22, 2024
4bf950a
feat(dashboard): elm-format
KellyMerrick May 24, 2024
84c7a6d
feat(dashboard): addressing feedback
KellyMerrick May 29, 2024
5d1e99e
fix(dashboard): linter fixes
KellyMerrick May 29, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
149 changes: 149 additions & 0 deletions cypress/fixtures/dashboard.json
Original file line number Diff line number Diff line change
@@ -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
}
]
}
18 changes: 18 additions & 0 deletions cypress/fixtures/dashboard_no_repos.json
Original file line number Diff line number Diff line change
@@ -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": []
}
}
126 changes: 126 additions & 0 deletions cypress/integration/dashboards.spec.js
Original file line number Diff line number Diff line change
@@ -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!');
});
});
});
4 changes: 4 additions & 0 deletions src/elm/Api/Endpoint.elm
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -163,6 +164,9 @@ toUrl api endpoint =
Deployments maybePage maybePerPage org repo ->
url api [ "deployments", org, repo ] <| Pagination.toQueryParams maybePage maybePerPage

Dashboard dashboard ->
url api [ "dashboards", dashboard ] []

Workers maybePage maybePerPage ->
url api [ "workers" ] <| Pagination.toQueryParams maybePage maybePerPage

Expand Down
13 changes: 13 additions & 0 deletions src/elm/Api/Operations.elm
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ module Api.Operations exposing
, getBuildStepLog
, getBuildSteps
, getCurrentUser
, getDashboard
, getOrgBuilds
, getOrgRepos
, getOrgSecret
Expand Down Expand Up @@ -1251,3 +1252,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
Loading
Loading