✨ Added OpenFeature card#1670
Conversation
|
👋 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! |
✅ Deploy Preview for kubestellarconsole ready!Built without sensitive environment variables
To edit notification comments on pull requests, go to your Netlify project configuration. |
There was a problem hiding this comment.
Pull request overview
Adds a new OpenFeature status dashboard card to the KubeStellar Console frontend and wires it into the card catalog/registry so it can be added from the UI (and via a preset).
Changes:
- Added
openfeature_statuscard implementation (UI + data hook + demo data). - Registered the new card type in the card registry, demo-data set, preloaders, and default widths.
- Exposed the card in the “Add Card” modal and added a CNCF preset JSON.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| web/src/components/dashboard/AddCardModal.tsx | Adds a new “App Definition” category and surfaces the OpenFeature card in the add-card catalog. |
| web/src/components/cards/openfeature_status/useOpenFeatureStatus.ts | Fetches pod data from /api/mcp/pods, detects OpenFeature-related pods, and computes simplified health/provider status. |
| web/src/components/cards/openfeature_status/OpenFeatureStatus.tsx | Renders the OpenFeature status card UI (health badge, tiles, provider list, and empty/error states). |
| web/src/components/cards/openfeature_status/demoData.ts | Provides demo-mode sample data for the OpenFeature card. |
| web/src/components/cards/openfeature_status/index.ts | Barrel export for the card component. |
| web/src/components/cards/cardRegistry.ts | Registers openfeature_status for lazy loading, demo-data tagging, preloading, and default sizing. |
| presets/cncf-openfeature.json | Adds a preset entry for OpenFeature under the “App Definition” CNCF category. |
| 'Utilities': 'utilities', | ||
| 'Misc': 'misc', | ||
| 'Runtime': 'runtime', | ||
| 'App Definition': 'appDefinition', |
There was a problem hiding this comment.
New category uses i18n key cards:categories.appDefinition, but that key doesn't exist in locale files (e.g. web/src/locales/en/cards.json). As a result, non-English locales will fall back to the raw English category label; please add appDefinition to the cards.categories section across locales (at least en) so the category is properly localized.
| 'App Definition': 'appDefinition', |
| if (isNaN(diff) || diff < 0) return t('openfeature.syncedJustNow', { defaultValue: 'just now' }) | ||
| const minute = 60_000 | ||
| const hour = 60 * minute | ||
| const day = 24 * hour | ||
| if (diff < minute) return t('openfeature.syncedJustNow', { defaultValue: 'just now' }) | ||
| if (diff < hour) return t('openfeature.syncedMinutesAgo', { count: Math.floor(diff / minute), defaultValue: `${Math.floor(diff / minute)}m ago` }) |
There was a problem hiding this comment.
This card relies heavily on t('openfeature.*', { defaultValue: ... }), and there are currently no openfeature entries in web/src/locales/en/cards.json. To keep i18n consistent with other cards (e.g., Contour/CRI-O) and avoid hardcoded English fallbacks, add the openfeature.* strings to the locale JSON files and drop the inline defaultValue usage.
clubanderson
left a comment
There was a problem hiding this comment.
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.
Review: OpenFeature Card
Good implementation! One minor note:
Suggestion
There appears to be a magic number for the error rate threshold. Per project conventions, numeric literals should use named constants with comments (e.g., const ERROR_RATE_THRESHOLD_PCT = 5 // percentage above which to show warning). Not blocking but would be nice to fix.
Approved.
clubanderson
left a comment
There was a problem hiding this comment.
Good card — follows established patterns well. A few items to address:
1. Magic number (blocking per project policy) — In OpenFeatureStatus.tsx:
{hasFlags && data.featureFlags.errorRate > 5 && (Should be a named constant:
const ERROR_RATE_WARNING_PCT = 5 // Show warning when error rate exceeds this percentage2. Missing persist: true in useCache — Every comparable status card (CRI-O, Contour, Flatcar, Thanos) passes persist: true to useCache. Without it, cached data won't survive page refreshes. Please add it.
3. Unnecessary effectiveIsDemoFallback guard — The hook does:
const effectiveIsDemoFallback = cacheResult.isDemoFallback && !cacheResult.isLoadingNo other card does this. The standard pattern passes isDemoFallback directly. Please align with:
isDemoData: cacheResult.isDemoFallback,4. Demo data magic number (minor) — 90 * 1000 in demoData.ts should be const DEMO_LAST_CHECK_OFFSET_MS = 90_000.
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
a2e0e53 to
2fdd710
Compare
clubanderson
left a comment
There was a problem hiding this comment.
Good work on the OpenFeature card — the code quality, hook wiring (isDemoData, useCache, useCardLoadingState), i18n coverage, and CNCF preset are all solid.
However, the branch has unresolved merge conflict markers in cardRegistry.ts and cards.json that break the build. Please:
- Rebase onto current
mainand resolve all merge conflicts (the Fluentd card was merged since this branch was created — both entries should coexist) - Push the rebased branch and verify CI passes
Once the conflicts are resolved, this should be ready to merge. Thanks!
2fdd710 to
df3a7c5
Compare
PR Review — OpenFeature CardCritical Issues1. Missing Fix: Add to both maps in openfeature_status: 'OpenFeature', // CARD_TITLES
openfeature_status: 'OpenFeature flag evaluation status and provider health.', // CARD_DESCRIPTIONSImportant Issues2. Duplicate i18n keys for relative-time strings 3. Missing Fix: export interface UseOpenFeatureStatusResult {
data: OpenFeatureStatus
error: boolean
isRefreshing: boolean // Add this
showSkeleton: boolean
showEmptyState: boolean
}4. Unrelated change bundled — What Looks Good
|
|
@xonas1101 Review posted above — a few items to address, the main one being a missing |
a8dd6ad to
8cd95ca
Compare
clubanderson
left a comment
There was a problem hiding this comment.
Two critical regressions need fixing before this can merge:
Critical:
-
lima_statustitle key DELETED from EN locale — The diff shows"lima_status": "Lima"was REPLACED with"openfeature_status": "OpenFeature"instead of adding alongside. This breaks the Lima card's title (it'll show the raw card type ID). Both lines must exist. -
Shared
formatters.tsi18n key change —createRelativeTimeFormatterwas changed fromcommon.justNow/common.minutesAgototime.justNow/time.minutesAgo. This is a shared utility used by other cards. Unlesstime.*keys were added tocommon.jsonin all locales, this breaks relative-time formatting across the board.
Important:
-
Missing
isDemoFallback && !isLoadingguard — The KEDA card (same author) correctly uses this guard; OpenFeature passesisDemoFallbackdirectly, which can flash demo data during initial load. -
isRefreshingexposed but not used — The hook returns it but the RefreshCw icon doesn't animate. KEDA does this correctly with${isRefreshing ? 'animate-spin' : ''}. -
Unrelated Lima locale changes — All 9 locale files have Lima section modifications/additions that aren't related to OpenFeature. These should be in a separate PR or reverted.
Please fix the lima_status deletion and the formatters.ts regression first — those affect other cards.
clubanderson
left a comment
There was a problem hiding this comment.
Card structure and code quality are solid, but there are several issues that need attention before merge:
-
Accidentally deletes Lima card's locale title — In
en/cards.json, thelima_statusentry in thetitlessection is replaced withopenfeature_statusinstead of being added alongside it. This will break the Lima card's title display. Please addopenfeature_statusas an additional entry, not a replacement. -
Missing OpenFeature locale keys in ALL 8 non-English locales — The
openfeaturetranslation section is only added toen/cards.json. None of the non-English locale files (de,es,fr,hi,it,ja,pt,zh) have theopenfeaturekeys. The component will show raw translation keys for non-English users. -
Unrelated Lima locale additions bundled in this PR — A
limasection is added to all 8 non-English locale files. This is out of scope for an OpenFeature card PR. Please remove and submit separately if needed. -
Unrelated change to
createRelativeTimeFormatterinformatters.ts— Changes i18n key prefix fromcommon.*totime.*. This is a shared utility fix that should be in its own PR. -
isRefreshingnot passed touseCardLoadingState— Same issue as your other card PRs. AddisRefreshing: cacheResult.isRefreshingto theuseCardLoadingStatecall. -
isDemoFallbacknot guarded during loading — PassisDemoData: cacheResult.isDemoFallback && !cacheResult.isLoadinginstead ofisDemoData: cacheResult.isDemoFallbackto prevent flashing demo data instead of the loading skeleton.
Please address these and re-request review.
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>
Signed-off-by: xonas1101 <aarushsingh1305@gmail.com>
Signed-off-by: xonas1101 <aarushsingh1305@gmail.com>
Signed-off-by: xonas1101 <aarushsingh1305@gmail.com>
a1d4368 to
a8af848
Compare
Signed-off-by: xonas1101 <aarushsingh1305@gmail.com>
|
/cc @clubanderson I have tried all changes with Claude Opus 4.6 this time. |
Signed-off-by: xonas1101 <aarushsingh1305@gmail.com>
|
@clubanderson checked everything for this as well. It should be fine now. |
Signed-off-by: xonas1101 <aarushsingh1305@gmail.com>
clubanderson
left a comment
There was a problem hiding this comment.
Same feedback as #1694 (KEDA card) applies here:
1. Live data is hollow
In live mode, featureFlags returns all zeros (total: 0, enabled: 0, disabled: 0, errorRate: 0), totalEvaluations: 0, and all provider evaluations: 0, cacheHitRate: 0. The only real data is pod health. The card needs to support both demo and live data — the flag counts, evaluation metrics, error rates, and cache hit rates are the most valuable parts of the card and they're all empty in live mode.
2. Scope creep in cardRegistry.ts
This PR adds lazy imports and registrations for FluentdStatus, LimaStatus — plus flatcar_status, thanos_status, contour_status, fluentd_status, lima_status entries in DEMO_DATA_CARDS, CARD_CHUNK_PRELOADERS, and CARD_DEFAULT_WIDTHS. Also adds a Runtime category in AddCardModal.tsx with wasmcloud/crio/lima. None of this belongs in an OpenFeature PR — please remove and keep this scoped to OpenFeature only.
3. Rebase needed
Build Frontend is failing — likely merge conflicts in cardRegistry.ts. Please rebase onto current main.
4. Unrelated Lima locale changes
en/cards.json modifies Lima strings (notDetectedHint, totalCpu, totalMemory, instances, openDocs) — these don't belong in this PR.
5. Non-EN locales untranslated
DE, ES, FR, HI, IT, JA openfeature.* keys have English strings for the main labels (healthy, degraded, notInstalled, providers, etc.). Only the time-relative strings are translated. Either translate properly or remove the non-EN openfeature sections and let i18next fall back to EN.
6. useFormatRelativeTime duplication (non-blocking)
Same helper duplicated across lima, fluentd, flatcar, KEDA, and now OpenFeature. Consider using the shared formatter from formatters.ts.
Consolidated Review — All Remaining Items (Final)@xonas1101 — This PR has been through 9 review rounds. Here's one consolidated checklist of everything that still needs fixing. Please address all of these in a single push to avoid further back-and-forth. Critical
Must Fix
This applies to issue kubestellar/console-marketplace#49. @clubanderson — as the issue author, please comment "approve" once the above items are addressed, or add comments on how to improve the PR. |
Add OpenFeature card that detects flagd/OpenFeature operator pods via /api/mcp/pods and displays provider health, flag stats, and evaluation counts. Review fixes: - Remove scope creep: revert changes to shared files that added entries for other cards (Fluentd, Lima, WasmCloud, CRI-O, etc.) - Revert accidental Lima locale string modifications - Revert unrelated changes to UpdateSettings, useSelfUpgrade, exec.go, analytics.ts, and other shared files - Add i18n keys for remaining hardcoded strings (evals, cache) - Add isRefreshing override to CardLoadingStateOptions for cards using useCache (returns precise refresh state) - Only register openfeature_status in card registry and AddCardModal Signed-off-by: Andrew Anderson <andy@clubanderson.com>
|
Superseded by the fix PR that was merged. Closing. |
📌 Fixes
Fixes kubestellar/console-marketplace#49
📝 Summary of Changes
Added Open Feature 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