diff --git a/plugins/config-schema/src/components/SchemaViewer/SchemaViewer.tsx b/plugins/config-schema/src/components/SchemaViewer/SchemaViewer.tsx
index 3f4c11fc31..db29e5acbe 100644
--- a/plugins/config-schema/src/components/SchemaViewer/SchemaViewer.tsx
+++ b/plugins/config-schema/src/components/SchemaViewer/SchemaViewer.tsx
@@ -14,13 +14,270 @@
* limitations under the License.
*/
import React from 'react';
-import { CodeSnippet } from '@backstage/core';
import { Schema } from 'jsonschema';
+import {
+ Box,
+ Chip,
+ Divider,
+ Paper,
+ Table,
+ TableBody,
+ TableCell,
+ TableRow,
+ Typography,
+} from '@material-ui/core';
+import { JsonValue } from '@backstage/config';
+
+interface SchemaViewProps {
+ path: string;
+ depth: number;
+ schema: Schema;
+}
+
+export interface MetadataViewRowProps {
+ label: string;
+ text?: string;
+ data?: JsonValue;
+}
+
+export function MetadataViewRow({ label, text, data }: MetadataViewRowProps) {
+ if (text === undefined && data === undefined) {
+ return null;
+ }
+ return (
+
+
+
+ {label}
+
+
+
+
+ {data ? JSON.stringify(data) : text}
+
+
+
+ );
+}
+
+export function MetadataView({ schema }: { schema: Schema }) {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export function ScalarView({ schema }: SchemaViewProps) {
+ return (
+ <>
+ {schema.description && (
+
+ {schema.description}
+
+ )}
+
+ >
+ );
+}
+
+function isRequired(name: string, required?: boolean | string[]) {
+ if (required === true) {
+ return true;
+ }
+ if (Array.isArray(required)) {
+ return required.includes(name);
+ }
+ return false;
+}
+
+function titleVariant(depth: number) {
+ if (depth <= 1) {
+ return 'h2';
+ } else if (depth === 2) {
+ return 'h3';
+ } else if (depth === 3) {
+ return 'h4';
+ } else if (depth === 4) {
+ return 'h5';
+ }
+ return 'h6';
+}
+
+export function VisibilityView({ schema }: { schema: Schema }) {
+ const { visibility } = schema as { visibility?: string };
+ if (visibility === 'frontend') {
+ return (
+ }
+ />
+ );
+ } else if (visibility === 'secret') {
+ return (
+ }
+ />
+ );
+ }
+ return null;
+}
+
+export function ArrayView({ path, depth, schema }: SchemaViewProps) {
+ const itemDepth = depth + 1;
+ const itemPath = path ? `${path}[]` : '[]';
+ const itemSchema = schema.items;
+
+ return (
+ <>
+
+ {schema.description && (
+
+ {schema.description}
+
+ )}
+
+
+ Items
+
+
+
+
+
+ {itemPath}
+
+
+ {itemSchema && (
+
+ )}
+
+
+ >
+ );
+}
+
+export function ObjectView({ path, depth, schema }: SchemaViewProps) {
+ const properties = Object.entries(schema.properties ?? {});
+ return (
+ <>
+ {depth > 0 && (
+
+ {schema.description && (
+
+ {schema.description}
+
+ )}
+
+
+ )}
+ {properties.length > 0 && (
+ <>
+ {depth > 0 && Properties}
+ {properties.map(([name, propSchema], index) => {
+ const propDepth = depth + 1;
+ const propPath = path ? `${path}.${name}` : name;
+
+ return (
+
+
+
+
+
+ {propPath}
+
+ {isRequired(name, schema.required) && (
+
+
+ required
+
+
+ )}
+
+
+
+
+
+ );
+ })}
+ >
+ )}
+ >
+ );
+}
+
+export function SchemaView(props: SchemaViewProps) {
+ // TODO(Rugvip): allOf, anyOf, oneOf
+ switch (props.schema.type) {
+ case 'array':
+ return ;
+ case 'object':
+ case undefined:
+ return ;
+ default:
+ return ;
+ }
+}
export interface SchemaViewerProps {
schema: Schema;
}
export const SchemaViewer = ({ schema }: SchemaViewerProps) => {
- return ;
+ return ;
};