MCPcopy
hub / github.com/github/awesome-copilot / planTab

Function planTab

extensions/java-modernization-studio/renderer.mjs:598–668  ·  view source on GitHub ↗
(s)

Source from the content-addressed store, hash-verified

596 }
597
598 function planTab(s) {
599 const usingProgress = !!(s.progress && s.progress.steps.length);
600 const steps = (usingProgress ? s.progress.steps : (s.plan ? s.plan.steps : [])) || [];
601 if (!steps.length) {
602 return emptyState(
603 "No plan yet",
604 "Run an assessment or generate an upgrade plan. App Modernization writes <code>plan.md</code> and a <code>progress.md</code> checklist, and your steps land here — each unchecked one becomes a button that hands that exact step to the agent.",
605 btn("Run assessment", "start_assessment", {}, { primary: true }) + btn("Generate upgrade plan", "generate_plan", { targetJava: 21 })
606 );
607 }
608 const src = usingProgress ? "progress.md" : "plan.md";
609 const total = steps.length;
610 const done = steps.filter((x) => x.status === "done").length;
611 const ord = s.ordering || { activeRank: null, activePhase: null };
612
613 // Intro + overall progress + legend.
614 let html = '<div class="card"><h2>Plan &amp; Progress <span class="muted" style="font-weight:400">' + esc(src) + "</span><span class=\"spacer\"></span>" + statusBadge(s.status) + "</h2>";
615 html += '<p class="muted" style="margin:0 0 10px">Your live modernization checklist. Each unchecked step has a <b>Work on this</b> button that hands just that step to the agent in this session — it checks the box here when the step is done.</p>';
616 html += '<div class="progress"><span style="width:' + (s.percent || 0) + '%"></span></div>';
617 html += '<p class="muted" style="margin:6px 0 0">' + done + " of " + total + " steps done · " + (s.percent || 0) + "% complete</p>";
618 html += '<div class="legend"><span><span class="dot done"></span>Done</span><span><span class="dot in_progress"></span>In progress</span><span><span class="dot pending"></span>To do</span><span>🔒 Do later</span></div>';
619 html += "</div>";
620
621 // Recommended-order guide so users don't work steps out of sequence.
622 html += approachGuide(ord);
623
624 // Autopilot: hand the whole phase to the agent instead of clicking each step.
625 html += autopilotCard(s);
626
627 // "Continue here" — the recommended next step: first not-done step in the
628 // active phase (falls back to the first not-done step overall).
629 const next = steps.find((x) => x.status !== "done" && (ord.activeRank == null || x.rank === ord.activeRank)) || steps.find((x) => x.status !== "done");
630 if (next) {
631 html +=
632 '<div class="hero"><div class="eyebrow">Continue here · recommended next step</div>' +
633 '<div class="htitle">' + esc(next.title) + "</div>" +
634 (next.section ? '<div class="hbody">Phase: ' + esc(next.section) + "</div>" : "") +
635 '<div class="actions">' + stepAction(next) + (next.section && /validation|gates/i.test(next.section) ? btn("Open Validation", "goto:validation") : "") + "</div></div>";
636 } else {
637 html += '<div class="banner">✓ Every step is checked off. Re-run the validation gates, then open a pull request.</div>';
638 }
639
640 // Steps grouped by their phase/section.
641 const groups = [];
642 const idx = {};
643 steps.forEach((st) => {
644 const key = st.section || "Steps";
645 if (idx[key] == null) { idx[key] = groups.length; groups.push({ name: key, items: [], rank: st.rank }); }
646 groups[idx[key]].items.push(st);
647 });
648
649 groups.forEach((g) => {
650 const gdone = g.items.filter((x) => x.status === "done").length;
651 const isValidation = /validation|gates/i.test(g.name);
652 const gLocked = ord.activeRank != null && g.rank != null && g.rank > ord.activeRank;
653 html += '<div class="card' + (gLocked ? " locked" : "") + '"><h2>' + (gLocked ? "🔒 " : "") + esc(g.name) + ' <span class="badge ' + (gdone === g.items.length && g.items.length ? "b-green" : "b-gray") + '">' + gdone + "/" + g.items.length + "</span>";
654 if (isValidation) html += '<span class="spacer"></span>' + btn("Open Validation →", "goto:validation");
655 else if (gLocked) html += '<span class="spacer"></span><span class="smuted">after ' + esc(shortPhase(ord.activePhase)) + "</span>";

Callers

nothing calls this directly

Calls 9

emptyStateFunction · 0.85
btnFunction · 0.85
escFunction · 0.85
statusBadgeFunction · 0.85
approachGuideFunction · 0.85
autopilotCardFunction · 0.85
stepActionFunction · 0.85
shortPhaseFunction · 0.85
stepRowActionFunction · 0.85

Tested by

no test coverage detected