forked from NYANDEV/forgejo
Add link to job details and tooltip to commit status in repo list in dashboard (#26326)
Tooltip: ![image](https://github.com/go-gitea/gitea/assets/18380374/237cb545-7844-424b-b995-1008eaaaedec) Link to the target job: ![image](https://github.com/go-gitea/gitea/assets/18380374/0c11a97f-6517-47f2-8773-f381488c084e)
This commit is contained in:
parent
3be80a863b
commit
f6e7798405
6 changed files with 36 additions and 10 deletions
|
@ -22,6 +22,7 @@ import (
|
||||||
"code.gitea.io/gitea/modules/setting"
|
"code.gitea.io/gitea/modules/setting"
|
||||||
api "code.gitea.io/gitea/modules/structs"
|
api "code.gitea.io/gitea/modules/structs"
|
||||||
"code.gitea.io/gitea/modules/timeutil"
|
"code.gitea.io/gitea/modules/timeutil"
|
||||||
|
"code.gitea.io/gitea/modules/translation"
|
||||||
|
|
||||||
"xorm.io/builder"
|
"xorm.io/builder"
|
||||||
"xorm.io/xorm"
|
"xorm.io/xorm"
|
||||||
|
@ -191,6 +192,11 @@ func (status *CommitStatus) APIURL(ctx context.Context) string {
|
||||||
return status.Repo.APIURL() + "/statuses/" + url.PathEscape(status.SHA)
|
return status.Repo.APIURL() + "/statuses/" + url.PathEscape(status.SHA)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// LocaleString returns the locale string name of the Status
|
||||||
|
func (status *CommitStatus) LocaleString(lang translation.Locale) string {
|
||||||
|
return lang.Tr("repo.commitstatus." + status.State.String())
|
||||||
|
}
|
||||||
|
|
||||||
// CalcCommitStatus returns commit status state via some status, the commit statues should order by id desc
|
// CalcCommitStatus returns commit status state via some status, the commit statues should order by id desc
|
||||||
func CalcCommitStatus(statuses []*CommitStatus) *CommitStatus {
|
func CalcCommitStatus(statuses []*CommitStatus) *CommitStatus {
|
||||||
var lastStatus *CommitStatus
|
var lastStatus *CommitStatus
|
||||||
|
|
|
@ -25,6 +25,10 @@ var commitStatusPriorities = map[CommitStatusState]int{
|
||||||
CommitStatusSuccess: 3,
|
CommitStatusSuccess: 3,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (css CommitStatusState) String() string {
|
||||||
|
return string(css)
|
||||||
|
}
|
||||||
|
|
||||||
// NoBetterThan returns true if this State is no better than the given State
|
// NoBetterThan returns true if this State is no better than the given State
|
||||||
// This function only handles the states defined in CommitStatusPriorities
|
// This function only handles the states defined in CommitStatusPriorities
|
||||||
func (css CommitStatusState) NoBetterThan(css2 CommitStatusState) bool {
|
func (css CommitStatusState) NoBetterThan(css2 CommitStatusState) bool {
|
||||||
|
|
|
@ -1280,6 +1280,11 @@ commit.cherry-pick = Cherry-pick
|
||||||
commit.cherry-pick-header = Cherry-pick: %s
|
commit.cherry-pick-header = Cherry-pick: %s
|
||||||
commit.cherry-pick-content = Select branch to cherry-pick onto:
|
commit.cherry-pick-content = Select branch to cherry-pick onto:
|
||||||
|
|
||||||
|
commitstatus.error = Error
|
||||||
|
commitstatus.failure = Failure
|
||||||
|
commitstatus.pending = Pending
|
||||||
|
commitstatus.success = Success
|
||||||
|
|
||||||
ext_issues = Access to External Issues
|
ext_issues = Access to External Issues
|
||||||
ext_issues.desc = Link to an external issue tracker.
|
ext_issues.desc = Link to an external issue tracker.
|
||||||
|
|
||||||
|
|
|
@ -600,6 +600,8 @@ func SearchRepo(ctx *context.Context) {
|
||||||
|
|
||||||
results := make([]*repo_service.WebSearchRepository, len(repos))
|
results := make([]*repo_service.WebSearchRepository, len(repos))
|
||||||
for i, repo := range repos {
|
for i, repo := range repos {
|
||||||
|
latestCommitStatus := git_model.CalcCommitStatus(repoToItsLatestCommitStatuses[repo.ID])
|
||||||
|
|
||||||
results[i] = &repo_service.WebSearchRepository{
|
results[i] = &repo_service.WebSearchRepository{
|
||||||
Repository: &api.Repository{
|
Repository: &api.Repository{
|
||||||
ID: repo.ID,
|
ID: repo.ID,
|
||||||
|
@ -613,7 +615,8 @@ func SearchRepo(ctx *context.Context) {
|
||||||
Link: repo.Link(),
|
Link: repo.Link(),
|
||||||
Internal: !repo.IsPrivate && repo.Owner.Visibility == api.VisibleTypePrivate,
|
Internal: !repo.IsPrivate && repo.Owner.Visibility == api.VisibleTypePrivate,
|
||||||
},
|
},
|
||||||
LatestCommitStatus: git_model.CalcCommitStatus(repoToItsLatestCommitStatuses[repo.ID]),
|
LatestCommitStatus: latestCommitStatus,
|
||||||
|
LocaleLatestCommitStatus: latestCommitStatus.LocaleString(ctx.Locale),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,8 +28,9 @@ import (
|
||||||
|
|
||||||
// WebSearchRepository represents a repository returned by web search
|
// WebSearchRepository represents a repository returned by web search
|
||||||
type WebSearchRepository struct {
|
type WebSearchRepository struct {
|
||||||
Repository *structs.Repository `json:"repository"`
|
Repository *structs.Repository `json:"repository"`
|
||||||
LatestCommitStatus *git.CommitStatus `json:"latest_commit_status"`
|
LatestCommitStatus *git.CommitStatus `json:"latest_commit_status"`
|
||||||
|
LocaleLatestCommitStatus string `json:"locale_latest_commit_status"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// WebSearchResults results of a successful web search
|
// WebSearchResults results of a successful web search
|
||||||
|
|
|
@ -69,16 +69,18 @@
|
||||||
</div>
|
</div>
|
||||||
<div v-if="repos.length" class="ui attached table segment gt-rounded-bottom">
|
<div v-if="repos.length" class="ui attached table segment gt-rounded-bottom">
|
||||||
<ul class="repo-owner-name-list">
|
<ul class="repo-owner-name-list">
|
||||||
<li class="gt-df gt-ac" v-for="repo, index in repos" :class="{'active': index === activeIndex}" :key="repo.id">
|
<li class="gt-df gt-ac gt-py-3" v-for="repo, index in repos" :class="{'active': index === activeIndex}" :key="repo.id">
|
||||||
<a class="repo-list-link muted gt-df gt-ac gt-f1" :href="repo.link">
|
<a class="repo-list-link muted gt-df gt-ac gt-f1 gt-gap-3" :href="repo.link">
|
||||||
<svg-icon :name="repoIcon(repo)" :size="16" class-name="repo-list-icon"/>
|
<svg-icon :name="repoIcon(repo)" :size="16" class-name="repo-list-icon"/>
|
||||||
<div class="text truncate">{{ repo.full_name }}</div>
|
<div class="text truncate">{{ repo.full_name }}</div>
|
||||||
<div v-if="repo.archived">
|
<div v-if="repo.archived">
|
||||||
<svg-icon name="octicon-archive" :size="16"/>
|
<svg-icon name="octicon-archive" :size="16"/>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
<!-- the commit status icon logic is taken from templates/repo/commit_status.tmpl -->
|
<a class="gt-df gt-ac" v-if="repo.latest_commit_status_state" :href="repo.latest_commit_status_state_link" :data-tooltip-content="repo.locale_latest_commit_status_state">
|
||||||
<svg-icon v-if="repo.latest_commit_status_state" :name="statusIcon(repo.latest_commit_status_state)" :class-name="'gt-ml-3 commit-status icon text ' + statusColor(repo.latest_commit_status_state)" :size="16"/>
|
<!-- the commit status icon logic is taken from templates/repo/commit_status.tmpl -->
|
||||||
|
<svg-icon :name="statusIcon(repo.latest_commit_status_state)" :class-name="'gt-ml-3 commit-status icon text ' + statusColor(repo.latest_commit_status_state)" :size="16"/>
|
||||||
|
</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<div v-if="showMoreReposLink" class="center gt-py-3 gt-border-secondary-top">
|
<div v-if="showMoreReposLink" class="center gt-py-3 gt-border-secondary-top">
|
||||||
|
@ -394,7 +396,14 @@ const sfc = {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (searchedURL === this.searchURL) {
|
if (searchedURL === this.searchURL) {
|
||||||
this.repos = json.data.map((webSearchRepo) => {return {...webSearchRepo.repository, latest_commit_status_state: webSearchRepo.latest_commit_status.State}});
|
this.repos = json.data.map((webSearchRepo) => {
|
||||||
|
return {
|
||||||
|
...webSearchRepo.repository,
|
||||||
|
latest_commit_status_state: webSearchRepo.latest_commit_status.State,
|
||||||
|
locale_latest_commit_status_state: webSearchRepo.locale_latest_commit_status,
|
||||||
|
latest_commit_status_state_link: webSearchRepo.latest_commit_status.TargetURL
|
||||||
|
};
|
||||||
|
});
|
||||||
const count = response.headers.get('X-Total-Count');
|
const count = response.headers.get('X-Total-Count');
|
||||||
if (searchedQuery === '' && searchedMode === '' && this.archivedFilter === 'both') {
|
if (searchedQuery === '' && searchedMode === '' && this.archivedFilter === 'both') {
|
||||||
this.reposTotalCount = count;
|
this.reposTotalCount = count;
|
||||||
|
@ -494,8 +503,6 @@ ul li:not(:last-child) {
|
||||||
}
|
}
|
||||||
|
|
||||||
.repo-list-link {
|
.repo-list-link {
|
||||||
padding: 6px 0;
|
|
||||||
gap: 6px;
|
|
||||||
min-width: 0; /* for text truncation */
|
min-width: 0; /* for text truncation */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue