diff --git a/src/components/molecules/Monaco/Monaco.tsx b/src/components/molecules/Monaco/Monaco.tsx index 17947269d7..ac3aa858ae 100644 --- a/src/components/molecules/Monaco/Monaco.tsx +++ b/src/components/molecules/Monaco/Monaco.tsx @@ -213,6 +213,22 @@ const Monaco = (props: {diffSelectedResource: () => void; applySelection: () => e.revealLineNearTop(1); e.setSelection(new monaco.Selection(0, 0, 0, 0)); setEditorMounted(true); + + // add custom opener for schema links in hover popups + let contribution: any = e.getContribution('editor.linkDetector'); + if (contribution?.openerService) { + contribution.openerService.registerOpener({ + open: (resource: string) => { + let isSchemaRequest = resource.startsWith('schema://'); + if (isSchemaRequest) { + // we should open a popup with the schema here - the actual schema can be retrieved from + // the diagnosticsOptions.schemas array + console.log('opening schema', resource, yaml.yamlDefaults.diagnosticsOptions.schemas); + } + return Promise.resolve(isSchemaRequest); + }, + }); + } }; const onChange = (newValue: any) => { diff --git a/src/hooks/useResourceYamlSchema.ts b/src/hooks/useResourceYamlSchema.ts index c296c89888..ea31a09666 100644 --- a/src/hooks/useResourceYamlSchema.ts +++ b/src/hooks/useResourceYamlSchema.ts @@ -4,11 +4,14 @@ import {languages} from 'monaco-editor/esm/vs/editor/editor.api'; import {FileMapType} from '@models/appstate'; import {K8sResource} from '@models/k8sresource'; +import {ResourceKindHandler} from '@models/resourcekindhandler'; -import {isKustomizationPatch} from '@redux/services/kustomize'; +import {isKustomizationPatch, isKustomizationResource} from '@redux/services/kustomize'; import {hasSupportedResourceContent} from '@redux/services/resource'; import {getResourceSchema, getSchemaForPath} from '@redux/services/schema'; +import {getResourceKindHandler} from '@src/kindhandlers'; + function useResourceYamlSchema( yaml: typeof languages.yaml, userDataDir: string, @@ -28,31 +31,50 @@ function useResourceYamlSchema( let resourceSchema; let validate = true; + let resourceKindHandler: ResourceKindHandler | undefined; if (resource) { resourceSchema = getResourceSchema(resource, k8sVersion, userDataDir); validate = resourceSchema && !isKustomizationPatch(resource) && hasSupportedResourceContent(resource); + resourceKindHandler = getResourceKindHandler(resource.kind); } else if (selectedPath && fileMap) { resourceSchema = getSchemaForPath(selectedPath, fileMap); validate = resourceSchema !== undefined; } - yaml && + if (yaml) { + let schemaUri = 'schema://empty'; + + if (resource?.kind) { + if (isKustomizationResource(resource)) { + schemaUri = 'schema://kustomize/Kustomize'; + } else if (resourceKindHandler && resourceKindHandler.isCustom) { + schemaUri = `schema://custom/${resourceKindHandler.kind}`; + } else { + schemaUri = `schema://kubernetes/${resource?.kind}-v${k8sVersion}`; + } + } + // for file-based schemas + else if (resourceSchema && selectedPath) { + schemaUri = `schema://local${selectedPath}`; + } + yaml.yamlDefaults.setDiagnosticsOptions({ validate, - enableSchemaRequest: true, + enableSchemaRequest: false, hover: true, completion: true, isKubernetes: Boolean(resource), format: true, schemas: [ { - uri: 'http://monokle/k8s.json', // id of the first schema + uri: schemaUri, fileMatch: ['*'], // associate with our model schema: resourceSchema || {}, }, ], }); + } // eslint-disable-next-line react-hooks/exhaustive-deps }, [resource, selectedPath, fileMap, k8sVersion]); }