feat(engine-v2): add platform configuration UI - #2817
Conversation
84b9344 to
4234d9b
Compare
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## staging #2817 +/- ##
===========================================
+ Coverage 46.93% 47.24% +0.31%
===========================================
Files 1263 1282 +19
Lines 27061 27601 +540
Branches 7887 8102 +215
===========================================
+ Hits 12701 13041 +340
- Misses 12194 12314 +120
- Partials 2166 2246 +80
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
200cce6 to
e140985
Compare
- guard operator queries against the undefined PostHog flag state (modal, create/settings platform routes) so flag-off orgs never hit operator endpoints and refreshes no longer bounce users off the platform step - make engine-v2 cluster creation idempotent on retry and redirect to the platform step when platform data is missing instead of failing silently - fix bool cluster-input requirements round-trip and keep requirement inputs mounted during preview refreshes (no more focus loss per keystroke) - keep cleared field values empty instead of resurrecting schema defaults; omit cleared markers from resolver and save payloads - make components without catalog fields openable so requirement-only components can be configured - exclude Stop / Upgrade K8s actions for self-managed clusters - restore bool-before-allowedValues precedence in CatalogVariableInput (blueprint regression) with a non-regression test - key PlatformConfiguration by cluster and re-seed when the template list changes; surface binding fetch errors instead of redirecting - add Back navigation to step-platform error/empty states - drop dead validationMode/componentsConfigurable props, use ts-pattern for enum mappers, import catalog types directly from util-js Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
e140985 to
a2a0d1a
Compare
RemiBonnet
left a comment
There was a problem hiding this comment.
Thanks @pggb25! I added few comments and I think you can probably share with @TheoGrandin74 to check if the UI is ok for him. I added after my comments:
- I'm not sure why I've an error when I click on the Qovery stack in the creation flow, is it something expected?
- Label aren't supported right now for this kind of cluster, could we hide it?
| } | ||
|
|
||
| // These endpoints are not generated by qovery-typescript-axios yet. Keeping the raw | ||
| // calls behind this data-access module avoids leaking their transport details into UI code. |
There was a problem hiding this comment.
When do you want to add it in the qovery-typescript-axios package?
| type PlatformComponentConfigurationPreviewRequest, | ||
| PlatformConfigurationApi, | ||
| } from 'qovery-typescript-axios' | ||
| import { isHttpStatus } from '../http/is-http-status' |
There was a problem hiding this comment.
I'm not sure to understand why do you need to return null if it's a 404? Same for cluster-operator.ts file
| enabled?: boolean | ||
| } | ||
|
|
||
| export function useClusterOperatorStatus({ organizationId, clusterId, enabled = true }: ClusterOperatorQueryProps) { |
There was a problem hiding this comment.
You need to have one file per query
| <div className="rounded-lg border border-neutral bg-surface-neutral p-5"> | ||
| <div className="mb-5 flex items-start justify-between gap-3"> | ||
| <div> | ||
| <Heading level={2}>{formatCatalogKey(component.key)}</Heading> |
There was a problem hiding this comment.
You need to have <Section> component before your Heading
| ) : null} | ||
|
|
||
| {fields.length > 0 ? ( | ||
| <section className="flex flex-col gap-3"> |
There was a problem hiding this comment.
This one should be <Section>
| const { data: binding } = usePlatformBinding({ organizationId, clusterId, suspense: true }) | ||
| const { mutate: updateBinding, isLoading: isSaving } = useUpdatePlatformBinding() | ||
|
|
||
| const [state, setState] = useState<PlatformConfigurationState | null>(() => { |
There was a problem hiding this comment.
Could you rename it with a more explicit name? platformConfigurationState and setPlatformConfigurationState, in react state is generic
| value: CatalogVariableValue | undefined | ||
| } | ||
|
|
||
| export function CatalogVariableInput({ |
There was a problem hiding this comment.
This component is not enough generic to be in the UI shared library, could you add it in a domain?
| ) | ||
| } | ||
|
|
||
| const saveConfiguration = () => |
There was a problem hiding this comment.
Inputs that are no longer required remain in customerProvidedInputs, could we filter them against preview.requirements, as we already do in the creation flow?
| })} | ||
| </Accordion.Root> | ||
|
|
||
| <div className="flex justify-between border-t border-neutral pt-4"> |
There was a problem hiding this comment.
Can users continue without validating the components of an enabled layer?
| const { data: binding } = usePlatformBinding({ organizationId, clusterId, suspense: true }) | ||
| const { mutate: updateBinding, isLoading: isSaving } = useUpdatePlatformBinding() | ||
|
|
||
| const [state, setState] = useState<PlatformConfigurationState | null>(() => { |
There was a problem hiding this comment.
The creation and settings flows duplicate template selection, preview, field updates and payload cleanup, could this shared controller logic live in a domain hook?
| const isOperatorGuideLoading = | ||
| isFeatureFlagLoading || | ||
| (canUseOperator && (isOperatorStatusLoading || (isOperatorManaged && isOperatorBootstrapLoading))) | ||
| // Only a bootstrap failure of a confirmed operator-managed cluster blocks the guide; |
There was a problem hiding this comment.
Should a status request failure fall back to the legacy guide? A transient API error could show incorrect instructions for an operator-managed cluster, I would expect an error state with Retry instead
| templateId: string | ||
| } | ||
|
|
||
| export function PlatformConfiguration({ |
There was a problem hiding this comment.
Could you add small test for this one?
Summary
Here is a PR for self-managed clusters within the scope of the engine V2 POC.
All changes is under feature flag.
Preview can be found here
https://p80-z9693eb24-z7d62c7cc-gtw.zc531a994.rustrocks.cloud/
Existing test cluster is here
https://p80-z9693eb24-z7d62c7cc-gtw.zc531a994.rustrocks.cloud/organization/460616f0-94da-4d35-b631-6fa4ed08eb9a/cluster/8a494a2b-ce45-4499-a3c2-f5c75fbd38dd/settings/platform
What we reuse from the Service Catalog is the normalized field vocabulary and the generic form renderer: field types, defaults, constraints, sensitivity, local validation, and widget selection.
The change on the Service Catalog side was mainly an extraction: Blueprint-specific field utilities and rendering were moved into shared catalog primitives. Blueprints now adapt their DTOs to those primitives, and Platform Configuration does the same with its own q-core DTOs.
The goal is to share the configuration mechanism while keeping the two domains independent.
Screenshots / Recordings
Adding new "Platform configurations" panel in the edit and creation of a self-managed cluster
The idea of the review is to check the godd separation and the good utilisation of the existing service catalogue feature
Testing
yarn testoryarn test -u(if you need to regenerate snapshots)yarn formatyarn lintPR Checklist
.cursor/rules)feat(service): add new Terraform service) - required for semantic-release