mirror of
https://github.com/go-gitea/gitea.git
synced 2026-08-13 19:01:20 +00:00
enhance: Adjust Workflow Graph styling (#37497)
- Fix workflow dependency graph overflow by making the graph container scrollable (no more clipped DAGs; addresses #37493). - Improve Actions job list readability by keeping durations fixed-width/right-aligned so long times don’t squeeze job names. - Make workflow graph layout more intuitive by vertically centering shorter columns to reduce misleading “looks like it depends on” alignments (addresses #37395). ### Screenshot <img width="966" height="439" src="https://github.com/user-attachments/assets/c180c5a2-4f56-4287-bcaa-f2735ba72949" /> <img width="949" height="559" src="https://github.com/user-attachments/assets/a383511d-a962-4920-b792-69f556847eff" /> Fixes #37493 Fixes #37395 --------- Co-authored-by: silverwind <me@silverwind.io> Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com> Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
This commit is contained in:
@@ -26,7 +26,6 @@ const {currentRun: run, runArtifacts: artifacts} = toRefs(store.viewData);
|
||||
type JobListItem = {
|
||||
job: ActionsJob;
|
||||
depth: number;
|
||||
hasChildren: boolean;
|
||||
};
|
||||
|
||||
// Caller jobs default to collapsed. Membership in this set means "user has manually expanded this caller"
|
||||
@@ -71,9 +70,8 @@ const visibleJobListItems = computed<JobListItem[]>(() => {
|
||||
while (stack.length > 0) {
|
||||
const {job, depth} = stack.pop()!;
|
||||
const children = childrenByParent.get(job.id) || [];
|
||||
const hasChildren = children.length > 0;
|
||||
result.push({job, depth, hasChildren});
|
||||
if (hasChildren && isJobCollapsed(job.id)) continue;
|
||||
result.push({job, depth});
|
||||
if (children.length > 0 && isJobCollapsed(job.id)) continue;
|
||||
for (let i = children.length - 1; i >= 0; i--) stack.push({job: children[i], depth: depth + 1});
|
||||
}
|
||||
return result;
|
||||
@@ -216,24 +214,28 @@ async function deleteArtifact(name: string) {
|
||||
v-for="item in visibleJobListItems"
|
||||
:key="item.job.id"
|
||||
>
|
||||
<a class="tw-contents silenced" :href="item.job.link">
|
||||
<ActionStatusIcon :locale-status="locale.status[item.job.status]" :status="item.job.status" icon-variant="circle-fill"/>
|
||||
<span class="tw-min-w-0 gt-ellipsis">{{ item.job.name }}</span>
|
||||
<SvgIcon name="octicon-sync" role="button" :data-tooltip-content="locale.rerun" class="job-rerun-button tw-cursor-pointer link-action interact-fg" :data-url="`${run.link}/jobs/${item.job.id}/rerun`" v-if="item.job.canRerun"/>
|
||||
<span class="job-duration">{{ item.job.duration }}</span>
|
||||
</a>
|
||||
<!-- Callers have no log page of their own; the whole row toggles expansion
|
||||
(matches GitHub Actions, where caller rows are not navigation targets). -->
|
||||
<button
|
||||
v-if="item.hasChildren"
|
||||
v-if="item.job.isReusableCaller"
|
||||
type="button"
|
||||
class="job-brief-toggle"
|
||||
:class="{'collapsed': isJobCollapsed(item.job.id)}"
|
||||
class="tw-contents caller-row-toggle"
|
||||
@click="toggleExpandedJob(item.job.id)"
|
||||
:title="isJobCollapsed(item.job.id) ? locale.expandCallerJobs : locale.collapseCallerJobs"
|
||||
:aria-label="isJobCollapsed(item.job.id) ? locale.expandCallerJobs : locale.collapseCallerJobs"
|
||||
:aria-expanded="!isJobCollapsed(item.job.id)"
|
||||
>
|
||||
<SvgIcon name="octicon-chevron-down" :size="14"/>
|
||||
<ActionStatusIcon :locale-status="locale.status[item.job.status]" :status="item.job.status" icon-variant="circle-fill"/>
|
||||
<span class="tw-min-w-0 gt-ellipsis">{{ item.job.name }}</span>
|
||||
<span class="job-duration">{{ item.job.duration }}</span>
|
||||
<SvgIcon name="octicon-chevron-down" :size="14" class="job-brief-toggle-icon" :class="{'collapsed': isJobCollapsed(item.job.id)}"/>
|
||||
</button>
|
||||
<a v-else class="tw-contents silenced" :href="item.job.link">
|
||||
<ActionStatusIcon :locale-status="locale.status[item.job.status]" :status="item.job.status" icon-variant="circle-fill"/>
|
||||
<span class="tw-min-w-0 gt-ellipsis">{{ item.job.name }}</span>
|
||||
<SvgIcon name="octicon-sync" role="button" :data-tooltip-content="locale.rerun" class="job-rerun-button tw-cursor-pointer link-action interact-fg" :data-url="`${run.link}/jobs/${item.job.id}/rerun`" v-if="item.job.canRerun"/>
|
||||
<span class="job-duration">{{ item.job.duration }}</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -258,7 +260,7 @@ async function deleteArtifact(name: string) {
|
||||
<SvgIcon name="octicon-trash"/>
|
||||
</a>
|
||||
</template>
|
||||
<span v-else class="flex-text-block tw-flex-1 tw-text-text-light-2">
|
||||
<span v-else class="flex-text-block tw-flex-1 tw-min-w-0 tw-text-text-light-2">
|
||||
<SvgIcon name="octicon-file-removed"/>
|
||||
<span class="tw-flex-1 gt-ellipsis">{{ artifact.name }}</span>
|
||||
<span class="ui label tw-flex-shrink-0">{{ locale.artifactExpired }}</span>
|
||||
@@ -406,23 +408,23 @@ async function deleteArtifact(name: string) {
|
||||
background-color: var(--color-active);
|
||||
}
|
||||
|
||||
.job-brief-toggle {
|
||||
.caller-row-toggle {
|
||||
border: none;
|
||||
padding: 0;
|
||||
background: transparent;
|
||||
cursor: pointer;
|
||||
color: inherit;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
text-align: inherit;
|
||||
}
|
||||
|
||||
.job-brief-toggle-icon {
|
||||
flex-shrink: 0;
|
||||
/* the icon is always chevron-down; flip to chevron-up when expanded */
|
||||
transition: transform 0.15s ease;
|
||||
/* sit right after the job name; rerun/duration float to the right via auto-margin */
|
||||
/* sit between name and duration; duration uses order:2 with margin-left:auto to float right */
|
||||
order: 1;
|
||||
}
|
||||
|
||||
.job-brief-toggle:not(.collapsed) {
|
||||
.job-brief-toggle-icon:not(.collapsed) {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user