✨ Added KEDA monitoring card#1694
Conversation
✅ Deploy Preview for kubestellarconsole ready!Built without sensitive environment variables
To edit notification comments on pull requests, go to your Netlify project configuration. |
|
👋 Hey @xonas1101 — thanks for opening this PR!
This is an automated message. |
|
Welcome to KubeStellar! 🚀 Thank you for submitting this Pull Request. Before your PR can be merged, please ensure: ✅ DCO Sign-off - All commits must be signed off with ✅ PR Title - Must start with an emoji: ✨ (feature), 🐛 (bug fix), 📖 (docs), 🌱 (infra/tests), Getting Started with KubeStellar: Contributor Resources:
🌟 Help KubeStellar Grow - We Need Adopters! Our roadmap is driven entirely by adopter feedback. Whether you're using KubeStellar yourself or know someone who could benefit from multi-cluster Kubernetes: 📋 Take our Multi-Cluster Survey - Share your use cases and help shape our direction! A maintainer will review your PR soon. Feel free to ask questions in the comments or on Slack! |
clubanderson
left a comment
There was a problem hiding this comment.
1693 ✨ Added Fluentd Card xonas1101
1692 Extract hardcoded user-facing strings to i18n translations app/copilot-swe-agent
1691 Add Auto-QA checks: color contrast, bundle analysis, large file detection, import cost app/copilot-swe-agent
1690 Standardize modal visibility patterns using useModalState hook app/copilot-swe-agent
1685 Fix swallowed errors in MissionBrowser index fetch with user-facing error messages app/copilot-swe-agent
1684 Fix memory leaks: clean up setTimeout on component unmount app/copilot-swe-agent
1683 Remove debug console.log statements from production hooks app/copilot-swe-agent
1679 [Test] PAT validation - no code changes required app/copilot-swe-agent
1676 🌱 test(ui): refactor alerts, auth, and gitops component tests to use React Testing Library mrhapile
1675 🌱 test(ui): refactor core resource dashboard tests to use React Testing Library mrhapile
1670 ✨ Added OpenFeature card xonas1101
1599 ✨ Added lima card xonas1101
1525 🌱 test: enforce structural integrity of card registry and lazy-loaded c… mrhapile
There was a problem hiding this comment.
Pull request overview
This PR adds a new KEDA (Kubernetes Event-Driven Autoscaling) monitoring card to the KubeStellar Console dashboard. The card detects KEDA operator pods via the existing /api/mcp/pods backend endpoint and displays their health status, with rich demo data showing ScaledObject metrics, trigger queue depths, and replica scaling visualization. It follows the established pattern of similar status cards (CRI-O, CoreDNS, Flatcar).
Changes:
- Added a new
keda_statuscard with component, data fetching hook, demo data, and barrel export underweb/src/components/cards/keda_status/ - Registered the card in
cardRegistry.ts(lazy import, component mapping, default width) and added a new "Orchestration" category inAddCardModal.tsx - Implemented live KEDA operator pod detection via label and name matching against the
/api/mcp/podsendpoint
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
web/src/components/cards/keda_status/KedaStatus.tsx |
Main card component with health badge, stats grid, ScaledObject list, search, and skeleton/error/empty states |
web/src/components/cards/keda_status/useKedaStatus.ts |
Data fetching hook using useCache, detects KEDA pods via /api/mcp/pods |
web/src/components/cards/keda_status/demoData.ts |
Type definitions and demo data with 5 sample ScaledObjects across various triggers |
web/src/components/cards/keda_status/index.ts |
Barrel export for the KedaStatus component |
web/src/components/cards/cardRegistry.ts |
Registers keda_status as a lazy-loaded card with default width of 6 columns |
web/src/components/dashboard/AddCardModal.tsx |
Adds KEDA to the card catalog under a new "Orchestration" category |
| * Uses GET /api/mcp/pods to detect KEDA operator pods. | ||
| * ScaledObject CRD data is not available through the current stock API | ||
| * endpoints, so we surface pod health only in live mode. | ||
| */ | ||
| async function fetchKedaStatus(): Promise<KedaStatus> { | ||
| const resp = await fetch('/api/mcp/pods', { | ||
| headers: { Accept: 'application/json' }, | ||
| signal: AbortSignal.timeout(FETCH_DEFAULT_TIMEOUT_MS), | ||
| }) | ||
|
|
||
| if (!resp.ok) { | ||
| throw new Error(`HTTP ${resp.status}`) | ||
| } | ||
|
|
||
| const body: { pods?: BackendPodInfo[] } = await resp.json() | ||
| const pods = Array.isArray(body?.pods) ? body.pods : [] | ||
|
|
There was a problem hiding this comment.
The fetchKedaStatus function calls /api/mcp/pods without any query parameters, which fetches ALL pods across ALL clusters and namespaces. It then client-side filters for KEDA operator pods. Since KEDA typically installs in the keda-system namespace (or keda), this could transfer significantly more data than needed, especially in large clusters with thousands of pods.
The backend endpoint supports a namespace query parameter (see pkg/api/handlers/mcp.go:205). However, since KEDA can be installed in various namespaces and the pod name-based fallback detection on line 40-41 relies on scanning all pods, a namespace filter alone won't fully solve this. Consider using the labelSelector query parameter (also supported by the endpoint at line 206) with a KEDA-specific label like app.kubernetes.io/part-of=keda-operator as a first attempt, falling back to the unfiltered call if no pods are found.
| * Uses GET /api/mcp/pods to detect KEDA operator pods. | |
| * ScaledObject CRD data is not available through the current stock API | |
| * endpoints, so we surface pod health only in live mode. | |
| */ | |
| async function fetchKedaStatus(): Promise<KedaStatus> { | |
| const resp = await fetch('/api/mcp/pods', { | |
| headers: { Accept: 'application/json' }, | |
| signal: AbortSignal.timeout(FETCH_DEFAULT_TIMEOUT_MS), | |
| }) | |
| if (!resp.ok) { | |
| throw new Error(`HTTP ${resp.status}`) | |
| } | |
| const body: { pods?: BackendPodInfo[] } = await resp.json() | |
| const pods = Array.isArray(body?.pods) ? body.pods : [] | |
| * Prefer GET /api/mcp/pods with a KEDA-specific labelSelector to avoid | |
| * fetching all pods across all clusters/namespaces. Fall back to the | |
| * unfiltered call if no pods are found, preserving existing behavior. | |
| * ScaledObject CRD data is not available through the current stock API | |
| * endpoints, so we surface pod health only in live mode. | |
| */ | |
| async function fetchKedaStatus(): Promise<KedaStatus> { | |
| // First, try to narrow the result set using a KEDA-specific label. | |
| const labelSelector = encodeURIComponent('app.kubernetes.io/part-of=keda-operator') | |
| const filteredResp = await fetch(`/api/mcp/pods?labelSelector=${labelSelector}`, { | |
| headers: { Accept: 'application/json' }, | |
| signal: AbortSignal.timeout(FETCH_DEFAULT_TIMEOUT_MS), | |
| }) | |
| if (!filteredResp.ok) { | |
| throw new Error(`HTTP ${filteredResp.status}`) | |
| } | |
| const filteredBody: { pods?: BackendPodInfo[] } = await filteredResp.json() | |
| let pods = Array.isArray(filteredBody?.pods) ? filteredBody.pods : [] | |
| // If no pods were returned with the label selector, fall back to the | |
| // original behavior of querying all pods and filtering client-side. | |
| if (pods.length === 0) { | |
| const resp = await fetch('/api/mcp/pods', { | |
| headers: { Accept: 'application/json' }, | |
| signal: AbortSignal.timeout(FETCH_DEFAULT_TIMEOUT_MS), | |
| }) | |
| if (!resp.ok) { | |
| throw new Error(`HTTP ${resp.status}`) | |
| } | |
| const body: { pods?: BackendPodInfo[] } = await resp.json() | |
| pods = Array.isArray(body?.pods) ? body.pods : [] | |
| } |
| // CoreDNS card | ||
| const CoreDNSStatus = lazy(() => import('./coredns_status').then(m => ({ default: m.CoreDNSStatus }))) | ||
| // KEDA autoscaler card | ||
| const KedaStatus = lazy(() => import('./keda_status').then(m => ({ default: m.KedaStatus }))) |
There was a problem hiding this comment.
keda_status is missing from the CARD_CHUNK_PRELOADERS map. Every other card with a standalone lazy-loaded chunk (e.g., crio_status at line 757, wasmcloud_status at line 749, flatcar_status at line 751) has a corresponding entry here. Without it, the KEDA card won't be prefetched when the dashboard mounts, causing a skeleton flash from the React.lazy() chunk load.
Add an entry like:
keda_status: () => import('./keda_status'),
| const { t } = useTranslation('cards') | ||
| const { data, error, showSkeleton, showEmptyState } = useKedaStatus() | ||
| const [search, setSearch] = useState('') | ||
|
|
||
| // Derived stats | ||
| const stats = useMemo(() => { | ||
| const objs = data.scaledObjects | ||
| return { | ||
| total: objs.length, | ||
| ready: objs.filter(o => o.status === 'ready').length, | ||
| degradedOrError: objs.filter(o => o.status === 'degraded' || o.status === 'error').length, | ||
| paused: objs.filter(o => o.status === 'paused').length, | ||
| } | ||
| }, [data.scaledObjects]) | ||
|
|
||
| // Filtered list (local search) | ||
| const filteredObjects = useMemo(() => { | ||
| if (!search.trim()) return data.scaledObjects | ||
| const q = search.toLowerCase() | ||
| return data.scaledObjects.filter( | ||
| o => | ||
| o.name.toLowerCase().includes(q) || | ||
| o.namespace.toLowerCase().includes(q) || | ||
| o.target.toLowerCase().includes(q) || | ||
| o.triggers.some(tr => tr.type.includes(q) || tr.source.toLowerCase().includes(q)), | ||
| ) | ||
| }, [data.scaledObjects, search]) | ||
|
|
||
| // ── Loading ────────────────────────────────────────────────────────────── | ||
| if (showSkeleton) { | ||
| return ( | ||
| <div className="h-full flex flex-col min-h-card gap-4"> | ||
| <div className="flex items-center justify-between"> | ||
| <Skeleton variant="rounded" width={120} height={28} /> | ||
| <Skeleton variant="rounded" width={80} height={20} /> | ||
| </div> | ||
| <SkeletonStats className="grid-cols-4" /> | ||
| <Skeleton variant="rounded" height={32} /> | ||
| <SkeletonList items={3} className="flex-1" /> | ||
| </div> | ||
| ) | ||
| } | ||
|
|
||
| // ── Error ───────────────────────────────────────────────────────────────── | ||
| if (error && showEmptyState) { | ||
| return ( | ||
| <div className="h-full flex flex-col items-center justify-center min-h-card text-muted-foreground gap-2"> | ||
| <AlertTriangle className="w-6 h-6 text-red-400" /> | ||
| <p className="text-sm text-red-400"> | ||
| {t('keda.fetchError', 'Failed to fetch KEDA status')} | ||
| </p> | ||
| </div> | ||
| ) | ||
| } | ||
|
|
||
| // ── Not installed ───────────────────────────────────────────────────────── | ||
| if (data.health === 'not-installed') { | ||
| return ( | ||
| <div className="h-full flex flex-col items-center justify-center min-h-card text-muted-foreground gap-2"> | ||
| <Layers className="w-6 h-6 text-muted-foreground/50" /> | ||
| <p className="text-sm font-medium"> | ||
| {t('keda.notInstalled', 'KEDA not detected')} | ||
| </p> | ||
| <p className="text-xs text-center max-w-xs"> | ||
| {t( | ||
| 'keda.notInstalledHint', | ||
| 'No KEDA operator pods found. Deploy KEDA to enable event-driven autoscaling.', | ||
| )} | ||
| </p> | ||
| </div> | ||
| ) | ||
| } | ||
|
|
||
| const isHealthy = data.health === 'healthy' | ||
| const healthColorClass = isHealthy | ||
| ? 'bg-green-500/15 text-green-400' | ||
| : 'bg-yellow-500/15 text-yellow-400' | ||
|
|
||
| return ( | ||
| <div className="h-full flex flex-col min-h-card content-loaded gap-4 overflow-hidden"> | ||
| {/* ── Header: health badge + operator pods + last check ── */} | ||
| <div className="flex items-center justify-between"> | ||
| <div className="flex items-center gap-2"> | ||
| <div | ||
| className={`flex items-center gap-2 px-3 py-1.5 rounded-full text-sm font-medium ${healthColorClass}`} | ||
| > | ||
| {isHealthy ? ( | ||
| <CheckCircle className="w-4 h-4" /> | ||
| ) : ( | ||
| <AlertTriangle className="w-4 h-4" /> | ||
| )} | ||
| {isHealthy | ||
| ? t('keda.healthy', 'Healthy') | ||
| : t('keda.degraded', 'Degraded')} | ||
| </div> | ||
| <span className="text-xs text-muted-foreground flex items-center gap-1"> | ||
| <Server className="w-3 h-3" /> | ||
| {data.operatorPods.ready}/{data.operatorPods.total}{' '} | ||
| {t('keda.operatorPods', 'pods')} | ||
| </span> | ||
| </div> | ||
| <div className="flex items-center gap-1.5 text-xs text-muted-foreground"> | ||
| <RefreshCw className="w-3 h-3" /> | ||
| <span>{formatRelativeTime(data.lastCheckTime)}</span> | ||
| </div> | ||
| </div> | ||
|
|
||
| {/* ── Stats grid ── */} | ||
| {data.scaledObjects.length > 0 && ( | ||
| <div className="grid grid-cols-4 gap-2"> | ||
| <StatTile | ||
| icon={<TrendingUp className="w-4 h-4 text-blue-400" />} | ||
| label={t('keda.total', 'Total')} | ||
| value={stats.total + data.totalScaledJobs} | ||
| colorClass="text-blue-400" | ||
| borderClass="border-blue-500/20" | ||
| /> | ||
| <StatTile | ||
| icon={<CheckCircle className="w-4 h-4 text-green-400" />} | ||
| label={t('keda.ready', 'Ready')} | ||
| value={stats.ready} | ||
| colorClass="text-green-400" | ||
| borderClass="border-green-500/20" | ||
| /> | ||
| <StatTile | ||
| icon={<AlertTriangle className="w-4 h-4 text-red-400" />} | ||
| label={t('keda.issues', 'Issues')} | ||
| value={stats.degradedOrError} | ||
| colorClass="text-red-400" | ||
| borderClass="border-red-500/20" | ||
| /> | ||
| <StatTile | ||
| icon={<PauseCircle className="w-4 h-4 text-blue-400" />} | ||
| label={t('keda.paused', 'Paused')} | ||
| value={stats.paused} | ||
| colorClass="text-blue-400" | ||
| borderClass="border-blue-500/20" | ||
| /> | ||
| </div> | ||
| )} | ||
|
|
||
| {/* ── Search ── */} | ||
| {data.scaledObjects.length > 0 && ( | ||
| <CardSearchInput | ||
| value={search} | ||
| onChange={setSearch} | ||
| placeholder={t('keda.searchPlaceholder', 'Search scaled objects…')} | ||
| /> | ||
| )} | ||
|
|
||
| {/* ── ScaledObjects list ── */} | ||
| <div className="flex-1 space-y-2 overflow-y-auto"> | ||
| {filteredObjects.length > 0 ? ( | ||
| filteredObjects.map(obj => ( | ||
| <ScaledObjectRow key={`${obj.namespace}/${obj.name}`} obj={obj} /> | ||
| )) | ||
| ) : data.scaledObjects.length === 0 ? ( | ||
| // Live mode: operator running but no ScaledObjects available via API | ||
| <div className="flex flex-col items-center justify-center h-full text-muted-foreground gap-1 py-6"> | ||
| <TrendingUp className="w-6 h-6 opacity-40" /> | ||
| <p className="text-sm">{t('keda.noScaledObjects', 'Operator running')}</p> | ||
| <p className="text-xs text-center"> | ||
| {t( | ||
| 'keda.noScaledObjectsHint', | ||
| 'ScaledObject data requires the KEDA CRD API.', | ||
| )} | ||
| </p> | ||
| </div> | ||
| ) : ( | ||
| <div className="flex items-center justify-center py-6 text-xs text-muted-foreground"> | ||
| {t('keda.noSearchResults', 'No scaled objects match your search.')} | ||
| </div> | ||
| )} | ||
| </div> | ||
|
|
||
| {/* ── Footer ── */} | ||
| {data.totalScaledJobs > 0 && ( | ||
| <div className="pt-2 border-t border-border/50 text-xs text-muted-foreground"> | ||
| +{data.totalScaledJobs} ScaledJob{data.totalScaledJobs !== 1 ? 's' : ''} | ||
| </div> | ||
| )} | ||
| </div> | ||
| ) | ||
| } |
There was a problem hiding this comment.
The translation keys used in this component (e.g., keda.fetchError, keda.healthy, keda.notInstalled, keda.total, etc.) are not defined in any of the locale files (web/src/locales/*/cards.json). While the inline fallback strings prevent runtime errors, this means:
- The card text won't be translated for non-English locales.
- The card title (
titles.keda_status) and description (descriptions.keda_status) used in the Add Card modal are also missing. - The new
categories.orchestrationkey is missing from the locale files.
Following the convention of other cards (e.g., crio keys at line ~2647 in web/src/locales/en/cards.json), a "keda" section should be added to each locale file with keys matching those used in t() calls, plus titles.keda_status, descriptions.keda_status, and categories.orchestration entries.
clubanderson
left a comment
There was a problem hiding this comment.
Review: KEDA Monitoring Card
Good work adding KEDA monitoring! A few things need fixing before merge:
Required Changes
-
Missing locale entries — The card adds user-facing strings but doesn't add corresponding entries to
web/src/locales/en/common.json. All hardcoded strings in the component need i18n keys. -
Missing CNCF preset registration — New CNCF ecosystem cards should be added to the CNCF preset in
web/src/lib/presets.ts(or wherever presets are defined). -
Missing DEMO_DATA_CARDS entry — The card needs to be registered in
DEMO_DATA_CARDSso it renders properly in demo mode with sample data. -
isDemoData wiring — If the card uses
useCached*hooks, make sure to destructureisDemoDataand pass it touseCardLoadingState(). Without this, the card shows demo data without the Demo badge/yellow outline.
Please address these and update the PR. Happy to re-review!
clubanderson
left a comment
There was a problem hiding this comment.
1693 ✨ Added Fluentd Card xonas1101
1676 🌱 test(ui): refactor alerts, auth, and gitops component tests to use React Testing Library mrhapile
1675 🌱 test(ui): refactor core resource dashboard tests to use React Testing Library mrhapile
1670 ✨ Added OpenFeature card xonas1101
1599 ✨ Added lima card xonas1101
1525 🌱 test: enforce structural integrity of card registry and lazy-loaded c… mrhapile
clubanderson
left a comment
There was a problem hiding this comment.
Solid KEDA card — well-structured with good demo data. Minor items to fix:
1. Magic number in demoData.ts:
lastCheckTime: new Date(Date.now() - 45 * 1000).toISOString()Should be:
const DEMO_LAST_CHECK_OFFSET_MS = 45_000
lastCheckTime: new Date(Date.now() - DEMO_LAST_CHECK_OFFSET_MS).toISOString()2. isRefreshing exposed but unused — The hook returns isRefreshing but the component never shows a refresh indicator. Either use it (e.g., spinning icon like CoreDNS does) or remove it from the return type.
3. Consider using useFormatRelativeTime hook pattern — Other cards (CRI-O, Contour, Flatcar, Thanos) define this as a hook. The KEDA card uses a bare function. Not blocking but would improve consistency.
Otherwise the card looks great — clean types, proper useCache/useCardLoadingState wiring, and honest handling of CRD API limitations.
clubanderson
left a comment
There was a problem hiding this comment.
Great work on the KEDA card — the architecture, demo data, i18n (all 9 locales!), and hook wiring are well done and consistent with existing cards.
However, the branch has unresolved merge conflict markers in cardRegistry.ts that break the build. Please:
- Rebase onto current
mainand resolve all merge conflicts (the Fluentd card and several other changes were merged since this branch was created) - Verify
DEMO_DATA_CARDSregistration is present after rebase - Consider using
t()for status labels inSTATUS_CONFIGsince translations already exist in the locale files
Once the conflicts are resolved and build passes, this should be ready to merge. Thanks!
PR Review — KEDA Monitoring CardCritical Issues1. English locale descriptions destroyed (regression) Fix: Restore "lima_status": "Lima virtual machine instances and resource usage.",
"keda_status": "KEDA autoscaler status, scaled object metrics, and trigger queue depths."2. Missing relative-time locale keys in all locales Fix: Add these 4 keys to the Important Issues3. Trailing newline removed from en/cards.json — The diff shows 4. Unrelated change bundled — What Looks Good
|
|
@xonas1101 Hey! I've posted a review above — there are 2 critical issues to address before merge, most notably the English locale descriptions being truncated (lima_status description was replaced with just "Lima" and keda_status only has "KEDA"). Please take a look when you get a chance. |
|
/cc @clubanderson |
|
@xonas1101 — Good KEDA card, correctly implements the
|
clubanderson
left a comment
There was a problem hiding this comment.
@xonas1101 — isDemoData wiring and useCache pattern are correct. One critical data regression:
Critical
1. lima_status EN locale description destroyed + keda_status description is just "KEDA"
In web/src/locales/en/cards.json, the lima_status description was overwritten from "Lima virtual machine instances and resource usage." to just "Lima" (copy-paste error). Also keda_status description in EN is "KEDA" while all other locales have proper descriptions.
Fix: In en/cards.json descriptions section:
"lima_status": "Lima virtual machine instances and resource usage.",
"keda_status": "KEDA autoscaler status, scaled object metrics, and trigger queue depths."Important
2. Missing cardMetadata.ts entries
No keda_status entry in CARD_TITLES or CARD_DESCRIPTIONS.
Fix: Add keda_status: 'KEDA' and keda_status: 'KEDA autoscaler status, scaled object metrics, and trigger queue depths.'
clubanderson
left a comment
There was a problem hiding this comment.
Nearly ready — all previously flagged critical items are now addressed (cardMetadata.ts, isDemoData guard with && !isLoading, isRefreshing wiring with spin animation). The code quality is solid.
Minor remaining items (non-blocking):
-
STATUS_CONFIGlabels are hardcoded English ('Ready','Degraded') — locale files havekeda.healthy/keda.degradedkeys but STATUS_CONFIG is at module scope so can't use hooks. Consider computing labels inside the component. -
Duplicate
useFormatRelativeTimepattern — same function exists in lima, fluentd, flatcar, and now KEDA. Consider using the sharedcreateRelativeTimeFormatterfromformatters.tsinstead. -
Investigate the Netlify deploy failure.
/lgtm
|
/cc @clubanderson I have performed the requested changed with Claude Opus 4.6, and rebased the PR. |
|
@clubanderson Reviewed everything again. This should be fine now ig. |
Signed-off-by: xonas1101 <aarushsingh1305@gmail.com>
Signed-off-by: xonas1101 <aarushsingh1305@gmail.com>
Signed-off-by: xonas1101 <aarushsingh1305@gmail.com>
Signed-off-by: xonas1101 <aarushsingh1305@gmail.com>
Signed-off-by: xonas1101 <aarushsingh1305@gmail.com>
Signed-off-by: xonas1101 <aarushsingh1305@gmail.com>
Signed-off-by: xonas1101 <aarushsingh1305@gmail.com>
Signed-off-by: xonas1101 <aarushsingh1305@gmail.com>
clubanderson
left a comment
There was a problem hiding this comment.
The card needs to support both demo and live data for ScaledObjects/ScaledJobs — not just operator pod detection.
Currently in live mode, useKedaStatus.ts returns scaledObjects: [] because the ScaledObject CRD data isn't queried. The card should:
- Query KEDA CRDs (
scaledobjects.keda.sh,scaledjobs.keda.sh) in live mode to populate the ScaledObject list, trigger info, and replica counts with real cluster data - Fall back to demo data when clusters aren't connected (this part already works)
Without live ScaledObject data, the card only shows pod health in live mode — the stats grid, search, ScaledObject list, and trigger details are all empty. That's the most valuable part of the card.
Please investigate how other cards query CRDs (check the backend MCP handlers) and wire up live data for ScaledObjects. The demo data types and component rendering are already solid — it's just the data fetching layer that needs the live path.
|
A few more items:
|
Consolidated Review — All Remaining Items (Final)@xonas1101 — This PR has been through many review rounds. Here's one consolidated checklist of everything that still needs fixing. Please address all of these in a single push. Critical
Must Fix
This applies to issue kubestellar/console-marketplace#23. @clubanderson — as the issue author, please comment "approve" once the above items are addressed, or add comments on how to improve the PR. |
Add KEDA card that detects operator pods via label matching with a fast label-filtered query followed by unfiltered fallback. Shows broker health, scaled object stats with replica bars, consumer group lag, and trigger details. Review fixes: - Remove scope creep: revert all shared file changes for other cards - Only register keda_status in card registry and AddCardModal - Add isRefreshing override to CardLoadingStateOptions - Add i18n keys for queue/target labels - Add Orchestration category to card catalog Signed-off-by: Andrew Anderson <andy@clubanderson.com>
Add KEDA card that detects operator pods via label matching with a fast label-filtered query followed by unfiltered fallback. Shows broker health, scaled object stats with replica bars, consumer group lag, and trigger details. Review fixes: - Remove scope creep: revert all shared file changes for other cards - Only register keda_status in card registry and AddCardModal - Add isRefreshing override to CardLoadingStateOptions - Add i18n keys for queue/target labels - Add Orchestration category to card catalog Signed-off-by: Andrew Anderson <andy@clubanderson.com>
* Added KEDA monitoring card Signed-off-by: xonas1101 <aarushsingh1305@gmail.com> * Addressed feedback Signed-off-by: xonas1101 <aarushsingh1305@gmail.com> * Addressed feedback Signed-off-by: xonas1101 <aarushsingh1305@gmail.com> * Addressed feedback Signed-off-by: xonas1101 <aarushsingh1305@gmail.com> * Addressed feedback Signed-off-by: xonas1101 <aarushsingh1305@gmail.com> * Addressed feedback Signed-off-by: xonas1101 <aarushsingh1305@gmail.com> * Addressed Feedback Signed-off-by: xonas1101 <aarushsingh1305@gmail.com> * Fixed errors Signed-off-by: xonas1101 <aarushsingh1305@gmail.com> * feat: add KEDA autoscaler status card (supersedes #1694) Add KEDA card that detects operator pods via label matching with a fast label-filtered query followed by unfiltered fallback. Shows broker health, scaled object stats with replica bars, consumer group lag, and trigger details. Review fixes: - Remove scope creep: revert all shared file changes for other cards - Only register keda_status in card registry and AddCardModal - Add isRefreshing override to CardLoadingStateOptions - Add i18n keys for queue/target labels - Add Orchestration category to card catalog Signed-off-by: Andrew Anderson <andy@clubanderson.com> * 🐛 Strip scope creep, add null guards to KEDA card - Reset unrelated files (go.mod, go.sum, analytics_proxy, auth, feedback, middleware/auth, server.go, netlify functions) to main - Add null guards on data.scaledObjects, data.operatorPods, and obj.triggers throughout KedaStatus.tsx to prevent crashes when API/cache returns undefined - Guard hasAnyData in useKedaStatus.ts with optional chaining Signed-off-by: Andrew Anderson <andy@clubanderson.com> --------- Signed-off-by: xonas1101 <aarushsingh1305@gmail.com> Signed-off-by: Andrew Anderson <andy@clubanderson.com> Co-authored-by: xonas1101 <aarushsingh1305@gmail.com>
|
Superseded by the fix PR that was merged. Closing. |
📌 Fixes
Fixes kubestellar/console-marketplace#23
📝 Summary of Changes
Added KEDA monitoring card
Changes Made
Checklist
Please ensure the following before submitting your PR:
Screenshots or Logs (if applicable)
👀 Reviewer Notes
Add any special notes for the reviewer here