Created
February 24, 2026 15:37
-
-
Save jwmatthews/52b18a0a20a2814a3bf8eaee2a20f26d to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!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 → 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