mirror of
https://github.com/hansjone/dsh-ops-cron.git
synced 2026-10-08 23:20:45 +08:00
Render admin cron list as a nested directory tree.
Drop the leading-dot decoration and indent child folders/sessions with padding so user → job → run reads like a real folder hierarchy. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
040d973fdf
commit
ae4b7611ed
1 changed files with 14 additions and 22 deletions
|
|
@ -290,10 +290,7 @@ window.__ModuleLoader__.load({
|
|||
.dsh-ct-projectText{flex-direction:column;flex:1;gap:2px;min-width:0;display:flex}
|
||||
.dsh-ct-title{text-overflow:ellipsis;white-space:nowrap;min-width:0;font-size:14px;line-height:20px;overflow:hidden}
|
||||
.dsh-ct-session .dsh-ct-title{flex:1;margin:0 6px 0 4px}
|
||||
.dsh-ct-treeLead{width:16px;height:20px;flex:none;justify-content:center;align-items:center;display:inline-flex;color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:20px;letter-spacing:0.5px;opacity:.72;user-select:none}
|
||||
.dsh-ct-depth1{padding-left:20px!important}
|
||||
.dsh-ct-depth2{padding-left:36px!important}
|
||||
.dsh-ct-ownerChild{margin-left:0}
|
||||
.dsh-ct-dirChildren{padding-left:16px;box-sizing:border-box}
|
||||
.dsh-ct-time{color:var(--dsw-alias-label-tertiary);flex:none;font-size:12px;line-height:20px}
|
||||
.dsh-ct-rowActs{flex:none;align-items:center;gap:12px;display:none;height:20px}
|
||||
.dsh-ct-project:hover .dsh-ct-rowActs,.dsh-ct-session:hover .dsh-ct-rowActs{display:inline-flex}
|
||||
|
|
@ -740,22 +737,18 @@ body>.dsh-ct-main{position:fixed;top:0;right:0;bottom:0;left:var(--dsh-ct-sideba
|
|||
return name && name !== key ? `${key} · ${name}` : key
|
||||
}
|
||||
|
||||
function treeLead() {
|
||||
return h('span', { className: 'dsh-ct-treeLead', 'aria-hidden': 'true' }, '\u00b7\u00b7\u00b7')
|
||||
}
|
||||
|
||||
function renderRunRows(job, depth) {
|
||||
function renderRunRows(job) {
|
||||
const jobRuns = runs.filter((run) => run.jobId === job.id)
|
||||
return jobRuns.map((run) => {
|
||||
const selectedRun = selection?.type === 'run' && selection.runId === run.id
|
||||
return h('div', {
|
||||
key: run.id,
|
||||
className: joinClass(skin.session, depth >= 2 ? 'dsh-ct-depth2' : 'dsh-ct-depth1'),
|
||||
className: skin.session,
|
||||
role: 'treeitem',
|
||||
'aria-level': 3,
|
||||
'data-on': selectedRun ? 'true' : 'false',
|
||||
onClick: () => onSelectRun(job.id, run),
|
||||
},
|
||||
treeLead(),
|
||||
h('span', { className: skin.slot }, sessionIcon() || '·'),
|
||||
h('span', { className: skin.title }, (run.summary || run.status || '').split('\n')[0] || run.status),
|
||||
h('span', { className: skin.time }, formatTime(run.actualAt || run.scheduledAt, job.schedule?.timezone)),
|
||||
|
|
@ -763,24 +756,22 @@ body>.dsh-ct-main{position:fixed;top:0;right:0;bottom:0;left:var(--dsh-ct-sideba
|
|||
})
|
||||
}
|
||||
|
||||
// depth 0: top-level job (normal users). depth 1: job under a user folder (super/fallback).
|
||||
function renderJobGroup(job, depth = 0) {
|
||||
// Directory node: job folder → session leaves. When nestedUnderUser, this is level 2.
|
||||
function renderJobGroup(job, nestedUnderUser = false) {
|
||||
const open = expanded[job.id] === true || !!needle
|
||||
const paused = job.enabled === false
|
||||
const selectedJob = selection?.type === 'job' && selection.jobId === job.id
|
||||
const containsCurrent = selectedJob || (selection?.type === 'run' && selection.jobId === job.id)
|
||||
const nested = depth > 0
|
||||
return h('div', { className: joinClass(skin.group, nested && 'dsh-ct-ownerChild'), key: job.id },
|
||||
return h('div', { className: skin.group, key: job.id },
|
||||
h('div', {
|
||||
className: joinClass(skin.project, nested && 'dsh-ct-depth1'),
|
||||
className: skin.project,
|
||||
role: 'treeitem',
|
||||
'aria-expanded': open,
|
||||
'aria-level': nested ? 2 : 1,
|
||||
'aria-level': nestedUnderUser ? 2 : 1,
|
||||
'data-on': selectedJob ? 'true' : 'false',
|
||||
'data-paused': paused ? 'true' : 'false',
|
||||
onClick: () => onSelectJob(job.id),
|
||||
},
|
||||
nested ? treeLead() : null,
|
||||
h('span', {
|
||||
className: joinClass(skin.slot, skin.folder, open && containsCurrent ? skin.folderOn : ''),
|
||||
'data-on': open && containsCurrent ? 'true' : 'false',
|
||||
|
|
@ -811,13 +802,14 @@ body>.dsh-ct-main{position:fixed;top:0;right:0;bottom:0;left:var(--dsh-ct-sideba
|
|||
),
|
||||
),
|
||||
h('div', { className: 'dsh-ct-runs', 'data-open': open ? 'true' : 'false' },
|
||||
h('div', { className: 'dsh-ct-runsInner' },
|
||||
renderRunRows(job, nested ? 2 : 1),
|
||||
h('div', { className: joinClass('dsh-ct-runsInner', 'dsh-ct-dirChildren') },
|
||||
renderRunRows(job),
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
// Super / fallback_admin: user folder → job folder → session leaf.
|
||||
function renderGrouped() {
|
||||
const groups = new Map()
|
||||
for (const job of visibleJobs) {
|
||||
|
|
@ -862,8 +854,8 @@ body>.dsh-ct-main{position:fixed;top:0;right:0;bottom:0;left:var(--dsh-ct-sideba
|
|||
h('span', { className: skin.title }, `${group.label} · ${group.jobs.length}`)),
|
||||
),
|
||||
h('div', { className: 'dsh-ct-runs', 'data-open': open ? 'true' : 'false' },
|
||||
h('div', { className: 'dsh-ct-runsInner' },
|
||||
group.jobs.map((job) => renderJobGroup(job, 1)),
|
||||
h('div', { className: joinClass('dsh-ct-runsInner', 'dsh-ct-dirChildren') },
|
||||
group.jobs.map((job) => renderJobGroup(job, true)),
|
||||
),
|
||||
),
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue