Skip to content

Instantly share code, notes, and snippets.

@jwmatthews
Created February 24, 2026 15:37
Show Gist options
  • Select an option

  • Save jwmatthews/52b18a0a20a2814a3bf8eaee2a20f26d to your computer and use it in GitHub Desktop.

Select an option

Save jwmatthews/52b18a0a20a2814a3bf8eaee2a20f26d to your computer and use it in GitHub Desktop.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Migration Report - /home/jmatthews.linux/Shared/patternfly_experiments/pranavs_skill/playpen-pf-mig-skills/experiments/migration-skill-quipuchords-jwm/quipucords-ui</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; color: #1f2937; background: #f9fafb; line-height: 1.5; }
.container { max-width: 1200px; margin: 0 auto; padding: 24px; }
header { background: #1e293b; color: white; padding: 32px; margin: -24px -24px 24px; }
header h1 { font-size: 24px; margin-bottom: 8px; }
.header-meta { display: flex; gap: 24px; flex-wrap: wrap; font-size: 14px; color: #94a3b8; }
.header-meta span { display: flex; align-items: center; gap: 4px; }
.badge { display: inline-block; padding: 2px 10px; border-radius: 12px; font-size: 12px; font-weight: 600; text-transform: uppercase; }
.tabs { display: flex; gap: 0; border-bottom: 2px solid #e5e7eb; margin-bottom: 24px; }
.tab { background: none; border: none; padding: 12px 24px; cursor: pointer; font-size: 14px; font-weight: 500; color: #6b7280; border-bottom: 2px solid transparent; margin-bottom: -2px; }
.tab:hover { color: #1f2937; }
.tab.active { color: #2563eb; border-bottom-color: #2563eb; }
.tab-content { display: none; }
.tab-content.active { display: block; }
.banner { padding: 16px 20px; border-radius: 8px; margin-bottom: 16px; font-weight: 500; }
.banner-success { background: #dcfce7; color: #16a34a; }
.card { background: white; border-radius: 8px; padding: 16px 20px; margin-bottom: 12px; box-shadow: 0 1px 3px rgba(0,0,0,0.1); }
.card-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px; }
.card-type { font-weight: 600; font-size: 13px; text-transform: uppercase; }
.card-page { font-size: 13px; color: #6b7280; }
.recommendation { color: #4b5563; font-size: 14px; }
.details { color: #6b7280; font-size: 13px; }
.status-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 12px; margin-bottom: 24px; }
.status-item { background: white; border-radius: 8px; padding: 16px; box-shadow: 0 1px 3px rgba(0,0,0,0.1); display: flex; flex-direction: column; gap: 8px; }
.status-label { font-size: 13px; color: #6b7280; font-weight: 500; }
table { width: 100%; border-collapse: collapse; margin-bottom: 24px; background: white; border-radius: 8px; overflow: hidden; box-shadow: 0 1px 3px rgba(0,0,0,0.1); }
th { background: #f8fafc; text-align: left; padding: 10px 16px; font-size: 13px; font-weight: 600; color: #475569; border-bottom: 1px solid #e5e7eb; }
td { padding: 10px 16px; font-size: 14px; border-bottom: 1px solid #f1f5f9; }
details { margin-bottom: 24px; }
summary { cursor: pointer; font-weight: 500; padding: 8px 0; color: #2563eb; }
h3 { font-size: 18px; margin-bottom: 12px; color: #1e293b; }
.visual-page { margin-bottom: 32px; }
.screenshots { display: flex; gap: 16px; flex-wrap: wrap; }
.screenshot { flex: 1; min-width: 300px; }
.screenshot h4 { font-size: 14px; color: #6b7280; margin-bottom: 8px; }
.screenshot img { width: 100%; border: 1px solid #e5e7eb; border-radius: 8px; }
.notes { color: #6b7280; font-size: 14px; margin-bottom: 12px; }
.muted { color: #9ca3af; font-style: italic; }
.md-content { background: white; border-radius: 8px; padding: 24px; box-shadow: 0 1px 3px rgba(0,0,0,0.1); }
.md-content h2 { font-size: 20px; margin: 24px 0 12px; color: #1e293b; border-bottom: 1px solid #e5e7eb; padding-bottom: 8px; }
.md-content h3 { font-size: 16px; margin: 16px 0 8px; color: #334155; }
.md-content h4 { font-size: 14px; margin: 12px 0 6px; color: #475569; font-family: monospace; }
.md-content ul { margin: 0 0 12px 20px; }
.md-content li { margin-bottom: 6px; font-size: 14px; }
.md-content li input[type="checkbox"] { margin-right: 6px; }
.md-content code { background: #f1f5f9; padding: 1px 5px; border-radius: 3px; font-size: 13px; }
.md-content hr { border: none; border-top: 1px solid #e5e7eb; margin: 16px 0; }
.md-content p { margin-bottom: 8px; font-size: 14px; }
@media print {
body { background: white; }
.container { max-width: none; padding: 0; }
header { background: #1e293b !important; -webkit-print-color-adjust: exact; print-color-adjust: exact; }
.tab-content { display: block !important; page-break-inside: avoid; }
.tabs { display: none; }
.tab-content::before { content: attr(data-title); display: block; font-size: 20px; font-weight: 700; margin: 24px 0 12px; border-bottom: 2px solid #e5e7eb; padding-bottom: 8px; }
.screenshot img { max-height: 400px; object-fit: contain; }
}
</style>
</head>
<body>
<div class="container">
<header>
<h1>/home/jmatthews.linux/Shared/patternfly_experiments/pranavs_skill/playpen-pf-mig-skills/experiments/migration-skill-quipuchords-jwm/quipucords-ui</h1>
<div class="header-meta">
<span>PatternFly 5 &rarr; PatternFly 6</span>
<span><span class="badge" style="color:#16a34a;background:#dcfce7">complete</span></span>
<span>2026-02-23 19:32</span>
</div>
</header>
<div class="tabs">
<button class="tab active" onclick="switchTab('summary')">Migration Summary</button>
<button class="tab" onclick="switchTab('action')">Action Required</button>
</div>
<div id="summary" class="tab-content active" data-title="Migration Summary">
<div class="status-grid"><div class="status-item"><span class="status-label">Build</span><span class="badge" style="color:#16a34a;background:#dcfce7">PASS</span></div><div class="status-item"><span class="status-label">Unit Tests</span><span class="badge" style="color:#16a34a;background:#dcfce7">PASS</span></div><div class="status-item"><span class="status-label">E2E Tests</span><span class="badge" style="color:#6b7280;background:#f3f4f6">NONE</span></div><div class="status-item"><span class="status-label">Lint</span><span class="badge" style="color:#16a34a;background:#dcfce7">PASS</span></div><div class="status-item"><span class="status-label">Target Validation</span><span class="badge" style="color:#16a34a;background:#dcfce7">PASS</span></div></div><h3>Issue Groups Fixed</h3><table><thead><tr><th>Group</th><th>Status</th><th>Issues Fixed</th><th>Description</th></tr></thead><tbody><tr><td>Group 1: Deprecated Select Component Rewrite</td><td><span class="badge" style="color:#16a34a;background:#dcfce7">complete</span></td><td>2</td><td>PF6 completely removed Select from deprecated module. Rewrote filter controls using PF6 Select/SelectList/SelectOption/MenuToggle pattern.</td></tr><tr><td>Group 2: Pagination Alignment</td><td><span class="badge" style="color:#16a34a;background:#dcfce7">complete</span></td><td>1</td><td>Simple prop rename: alignRight → alignEnd in ToolbarItem.</td></tr><tr><td>Group 3: EmptyState Cleanup</td><td><span class="badge" style="color:#16a34a;background:#dcfce7">complete</span></td><td>2</td><td>Codemods handled source (EmptyStateHeader and EmptyStateIcon no longer exported), only snapshots needed update.</td></tr><tr><td>Group 4: Type Import False Positives</td><td><span class="badge" style="color:#16a34a;background:#dcfce7">complete</span></td><td>1</td><td>ESLint import/named errors for ButtonProps, PaginationProps, etc. Confirmed false positives — TypeScript resolves correctly, build passes.</td></tr><tr><td>Group 5: CSS/Token Updates</td><td><span class="badge" style="color:#16a34a;background:#dcfce7">complete</span></td><td>6</td><td>Updated pf-v5 → pf-v6 CSS class prefixes, --pf-v5-global → --pf-t--global CSS custom properties, utility classes, icon color tokens, and theme-dark references.</td></tr><tr><td>Group 6: OUIA ID Migration</td><td><span class="badge" style="color:#16a34a;background:#dcfce7">complete</span></td><td>1</td><td>PF6 uses ouiaId prop instead of data-ouia-component-id HTML attribute. Replaced on MenuToggle.</td></tr><tr><td>Group 7: Component Prop Updates</td><td><span class="badge" style="color:#16a34a;background:#dcfce7">complete</span></td><td>6</td><td>Various component API changes: MastheadBrand → MastheadLogo, isActive removed from NavItem, data-codemods cleanup, useLocation removed, ButtonVariant.control → ButtonVariant.plain, isScrollable prop removed.</td></tr><tr><td>Group 8: Test Updates</td><td><span class="badge" style="color:#16a34a;background:#dcfce7">complete</span></td><td>4</td><td>Test-specific migration: pf-v5 → pf-v6 in CSS class assertions, PF6 Dropdown findByRole, theme toggle icon-only assertions, about modal i18n keys.</td></tr><tr><td>Group 9: Lint/Formatting Cleanup</td><td><span class="badge" style="color:#16a34a;background:#dcfce7">complete</span></td><td>1</td><td>Auto-fixable Prettier formatting violations from codemod changes. ESLint --fix auto-resolved all formatting issues.</td></tr></tbody></table><h3>Fix Iteration Logs</h3><details><summary>Show all iterations</summary><table><thead><tr><th>Iteration</th><th>Group</th><th>Fixed</th><th>New Issues</th><th>Build</th><th>Tests</th></tr></thead><tbody><tr><td>1</td><td>Groups 1-9 (combined)</td><td>24</td><td>0</td><td><span class="badge" style="color:#16a34a;background:#dcfce7">PASS</span></td><td>265/265</td></tr><tr><td>2</td><td>Validation</td><td>0</td><td>0</td><td><span class="badge" style="color:#16a34a;background:#dcfce7">PASS</span></td><td>265/265</td></tr></tbody></table></details><h3>Kantra Residual (537 incidents)</h3><table><thead><tr><th>Rule</th><th>Count</th><th>Reason</th></tr></thead><tbody><tr><td>isOpen → open (component-props-00400)</td><td>99</td><td>Deprecated but functional — isOpen still works in PF6. Blind find-and-replace risks breaking local state variable names.</td></tr><tr><td>Modal title → titleText (component-props-00220 + patternfly-v6-00080)</td><td>90</td><td>Deprecated Modal API — title prop still works. Full Modal rewrite recommended as separate effort.</td></tr><tr><td>Modal composed structure (components-00020)</td><td>45</td><td>Modal uses deprecated flat API instead of composed ModalHeader/ModalBody/ModalFooter. Non-breaking.</td></tr><tr><td>Deep import paths (imports-00000)</td><td>41</td><td>Not recommended — couples code to PF internal package structure.</td></tr><tr><td>Deprecated Modal imports (deprecated-components-00050 + promoted-components-00010)</td><td>66</td><td>Modal imported from deprecated path. Non-breaking, works as-is.</td></tr><tr><td>MenuToggle icon as children → icon prop (component-props-00000 + component-props-00370)</td><td>59</td><td>Deprecated pattern — icon as children still renders correctly.</td></tr><tr><td>isDisabled → disabled (component-props-00380 + patternfly-v6-00110/00120/00150)</td><td>54</td><td>Deprecated but functional — isDisabled still works in PF6.</td></tr><tr><td>isExpanded → expanded (component-props-00390)</td><td>14</td><td>Deprecated but functional — isExpanded still works in PF6.</td></tr><tr><td>isCompact → variant='compact' (patternfly-v6-00090)</td><td>16</td><td>Deprecated but functional — isCompact still works in PF6.</td></tr><tr><td>PageSection restructure (pagesection-00020)</td><td>16</td><td>PageSection hasBodyWrapper is not a replacement for variant prop. Non-breaking.</td></tr><tr><td>ToolbarFilter chips → labels (component-props-00170 + renamed-props-00110)</td><td>15</td><td>Deprecated prop name — chips still works in PF6.</td></tr><tr><td>ButtonVariant.link → plain (component-props-00230)</td><td>7</td><td>Deprecated variant name — still functional.</td></tr><tr><td>Text → Content (components-00050)</td><td>5</td><td>Text component renamed to Content in PF6. Non-breaking, deprecated import still works.</td></tr><tr><td>isSelected removed (removed-props-00050)</td><td>5</td><td>isSelected usage detected — removed API but may be in deprecated component context.</td></tr><tr><td>Masthead structure (component-structure-00000)</td><td>4</td><td>Masthead structure changes. Non-breaking in current usage.</td></tr><tr><td>Import path deprecated (import-path-00000)</td><td>1</td><td>Single import should move from react-core to react-core/deprecated. Non-breaking.</td></tr></tbody></table>
</div>
<div id="action" class="tab-content" data-title="Action Required">
<div class="card" style="border-left:4px solid #7c3aed"><div class="card-header"><span class="card-type" style="color:#7c3aed">Manual Intervention Needed</span></div><p>Deprecated props (isOpen, isDisabled, isExpanded, isCompact) are deprecated but still functional in PF6.</p><p class="recommendation"><strong>Recommendation:</strong> Consider updating to open, disabled, expanded, variant="compact" in a future cleanup pass. Note: blind find-and-replace will break local state variable names — each file needs careful individual review.</p><p class="details">isOpen: 99 incidents, isDisabled: 30 incidents, isExpanded: 14 incidents, isCompact: 16 incidents</p></div>
<div class="card" style="border-left:4px solid #7c3aed"><div class="card-header"><span class="card-type" style="color:#7c3aed">Manual Intervention Needed</span></div><p>9 files use Modal from @patternfly/react-core/deprecated.</p><p class="recommendation"><strong>Recommendation:</strong> Consider migrating to PF6's new Modal API (composed ModalHeader, ModalBody, ModalFooter structure) in a future iteration.</p><p class="details">33 deprecated Modal import incidents, 45 Modal title → titleText incidents, 45 composed Modal structure incidents</p></div>
<div class="card" style="border-left:4px solid #d97706"><div class="card-header"><span class="card-type" style="color:#d97706">False Positive to Verify</span></div><p>Kantra suggests using deep imports (e.g., @patternfly/react-core/dist/esm/components/...).</p><p class="recommendation"><strong>Recommendation:</strong> This is NOT recommended as it couples code to PF's internal package structure.</p><p class="details">41 deep import path incidents</p></div>
<div class="card" style="border-left:4px solid #7c3aed"><div class="card-header"><span class="card-type" style="color:#7c3aed">Manual Intervention Needed</span></div><p>12 files pass icon as children of MenuToggle instead of using the icon prop.</p><p class="recommendation"><strong>Recommendation:</strong> Consider moving to the icon prop for cleaner API usage.</p><p class="details">32 MenuToggle icon incidents, 27 MenuToggle variant='plain' icon incidents</p></div>
<div class="card" style="border-left:4px solid #2563eb"><div class="card-header"><span class="card-type" style="color:#2563eb">Visual Change to Review</span></div><p>Visual comparison is limited — static build was used for post-migration screenshots (no API data).</p><p class="recommendation"><strong>Recommendation:</strong> Full visual regression testing requires the dev server. Recommend adding transpileOnly: true to the weldable/ts-loader configuration to resolve ts-loader skipLibCheck incompatibility with PF6's type declarations.</p></div>
</div>
</div>
<script>
function switchTab(id) {
document.querySelectorAll('.tab-content').forEach(el => el.classList.remove('active'));
document.querySelectorAll('.tab').forEach(el => el.classList.remove('active'));
document.getElementById(id).classList.add('active');
event.target.classList.add('active');
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment