From af305225bd02ff2a5d194edfef6ffdc0df17b47b Mon Sep 17 00:00:00 2001 From: catosaurusrex2003 Date: Sat, 11 Jan 2025 14:51:44 +0530 Subject: [PATCH 01/41] tinkering with stuff --- library/package.json | 4 +- library/src/components/CollapseButton.tsx | 6 +- library/src/components/Payload.tsx | 460 ++++++++++++++++++++ library/src/components/Schema.tsx | 32 +- library/src/components/payload/Payload2.tsx | 51 +++ library/src/containers/Messages/Message.tsx | 6 +- library/src/helpers/schema.ts | 21 +- playground/utils/defaultConfig.ts | 8 +- 8 files changed, 573 insertions(+), 15 deletions(-) create mode 100644 library/src/components/Payload.tsx create mode 100644 library/src/components/payload/Payload2.tsx diff --git a/library/package.json b/library/package.json index 811a94201..9267f0a51 100644 --- a/library/package.json +++ b/library/package.json @@ -53,7 +53,7 @@ "build:standalone": "cross-env BUILD_MODE=standalone webpack", "build:types": "tsc -p tsconfig.types.json", "build:styles": "npm run build:styles:dev && npm run build:styles:prod", - "build:styles:dev": "cross-env NODE_ENV=production postcss src/styles/default.css -o styles/default.css --verbose", + "build:styles:dev": "cross-env NODE_ENV=development postcss src/styles/default.css -o styles/default.css --verbose & cross-env NODE_ENV=development postcss src/styles/default.css -o styles/default.min.css --verbose", "build:styles:prod": "cross-env NODE_ENV=production MINIFY_STYLES=true postcss src/styles/default.css -o styles/default.min.css --verbose", "test": "npm run test:unit && npm run test:e2e", "test:unit": "jest --detectOpenHandles", @@ -117,4 +117,4 @@ "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/library/src/components/CollapseButton.tsx b/library/src/components/CollapseButton.tsx index bea5a7a00..f8eb723d9 100644 --- a/library/src/components/CollapseButton.tsx +++ b/library/src/components/CollapseButton.tsx @@ -3,9 +3,10 @@ import React, { ButtonHTMLAttributes, SVGAttributes } from 'react'; interface Props extends ButtonHTMLAttributes { chevronProps?: SVGAttributes; expanded?: boolean; + rotateAngle?: number; } -const HiChevronRight = (props: SVGAttributes = {}) => ( +export const HiChevronRight = (props: SVGAttributes = {}) => ( // Copied from https://icon-sets.iconify.design/heroicons-solid/chevron-right/ = ({ chevronProps, expanded = false, children, + rotateAngle = 90, ...rest }) => ( diff --git a/library/src/components/Payload.tsx b/library/src/components/Payload.tsx new file mode 100644 index 000000000..d7fc4bf3c --- /dev/null +++ b/library/src/components/Payload.tsx @@ -0,0 +1,460 @@ +import React, { useState, useEffect, useContext } from 'react'; +import { SchemaInterface } from '@asyncapi/parser'; + +import { Href, CollapseButton, Markdown, Extensions } from './index'; +import { SchemaHelpers } from '../helpers'; + +interface Props { + schemaName?: React.ReactNode; + schema?: SchemaInterface; + showSchemaType?: boolean; + required?: boolean; + isPatternProperty?: boolean; + isProperty?: boolean; + isCircular?: boolean; + dependentRequired?: string[]; + expanded?: boolean; + onlyTitle?: boolean; + isArray?: boolean; +} + +const PayloadSchemaContext = React.createContext({ + reverse: false, + deepExpanded: false, +}); + +export const Payload: React.FunctionComponent = ({ + schemaName, + schema, + showSchemaType = true, + required = false, + isPatternProperty = false, + isProperty = false, + isCircular = false, + dependentRequired, + expanded: propExpanded = false, + onlyTitle = false, + isArray = false, + // eslint-disable-next-line sonarjs/cognitive-complexity +}) => { + // if (schemaName == "Payload") { + // console.log("schema = ",schema) + // } + const { reverse, deepExpanded } = useContext(PayloadSchemaContext); + const [expanded, setExpanded] = useState(propExpanded || isArray); + const [deepExpand, setDeepExpand] = useState(false); + + useEffect(() => { + if (!isArray) { + setDeepExpand(deepExpanded); + } + }, [isArray, deepExpanded, setDeepExpand]); + + useEffect(() => { + if (!isArray) { + setExpanded(deepExpand); + } + }, [isArray, deepExpand, setExpanded]); + + if ( + !schema || + (typeof schemaName === 'string' && + (schemaName?.startsWith('x-parser-') || + schemaName?.startsWith('x-schema-private-'))) + ) { + return null; + } + + const dependentSchemas = SchemaHelpers.getDependentSchemas(schema); + + const constraints = SchemaHelpers.humanizeConstraints(schema); + const externalDocs = schema.externalDocs(); + + const rawValueExt = schema.extensions().get(SchemaHelpers.extRawValue); + const rawValue = rawValueExt?.value() === true; + + const parameterLocationExt = schema + .extensions() + .get(SchemaHelpers.extParameterLocation); + const parameterLocation = parameterLocationExt?.value() === true; + + const schemaType = SchemaHelpers.toSchemaType(schema); + const isExpandable = SchemaHelpers.isExpandable(schema) || dependentSchemas; + + isCircular = isCircular || schema.isCircular() || false; + const uid = schema.$id(); + const styledSchemaName = isProperty ? 'italic' : ''; + const renderedSchemaName = + typeof schemaName === 'string' ? ( + + {schemaName} + + ) : ( + schemaName + ); + + if (schemaName == "dependencies") { + console.log("schema = ",schema) + } + + return ( + +
+ {/* Header Section */} +
+
+
+ {isExpandable && !isCircular && !isArray ? ( +
+ setExpanded((prev) => !prev)} + expanded={expanded} + > + {renderedSchemaName} + + +
+ ) : ( + + {schemaName} + + )} + + {isCircular ? `${schemaType} [CIRCULAR]` : schemaType} + +
+
+ + {/* Field Status Indicators */} + {required || + schema.deprecated() || + schema.writeOnly() || + (schema.readOnly() && ( +
+ {required && ( + + required + + )} + {schema.deprecated() && ( + + deprecated + + )} + {schema.writeOnly() && ( + + write-only + + )} + {schema.readOnly() && ( + + read-only + + )} +
+ ))} + {/* Description */} + {schema.description() && ( +
+ {schema.description()} +
+ )} +
+ + {/* Expandable Content */} + {!isCircular && isExpandable && expanded && ( +
+ {/* Rules Section */} + {(constraints.length > 0 || schema.enum() || schema.const()) && ( +
+

+ Rules & Constraints +

+
+ {constraints.map((constraint) => ( +
+ {constraint} +
+ ))} + {schema.enum() && ( +
+ Allowed values: + {schema.enum()?.map((e, idx) => ( + + {SchemaHelpers.prettifyValue(e)} + + ))} +
+ )} + {schema.const() !== undefined && ( +
+ Constant value: + + {SchemaHelpers.prettifyValue(schema.const())} + +
+ )} +
+
+ )} + + {/* Conditions Section */} + {(schema.if() || + schema.then() || + schema.else() || + schema.oneOf()?.length || + dependentSchemas) && ( +
+

+ Conditions +

+
+ {schema.oneOf()?.length && ( +
+
+ Can be One Of these: +
+ {schema + .oneOf() + ?.map((s, idx) => ( + + ))} +
+ )} + + {schema.if() && ( + + )} + {schema.then() && ( + + )} + {schema.else() && ( + + )} + {dependentSchemas && ( + + )} +
+
+ )} + + {/* Properties Section */} + + + {/* Array Items Section */} + + + {/* Additional Properties/Items Section */} +
+ + +
+ + {/* Extensions Section */} + +
+ )} +
+
+ ); +}; + +interface SchemaPropertiesProps { + schema: SchemaInterface; +} + +const SchemaProperties: React.FunctionComponent = ({ + schema, +}) => { + const properties = schema.properties(); + if (properties === undefined || !Object.keys(properties)) { + return null; + } + + const required = schema.required() ?? []; + const patternProperties = schema.patternProperties(); + + return ( + <> + {Object.entries(properties).map(([propertyName, property]) => ( + + ))} + {Object.entries(patternProperties ?? {}).map( + ([propertyName, property]) => ( + + ), + )} + + ); +}; + +interface AdditionalPropertiesProps { + schema: SchemaInterface; +} + +const AdditionalProperties: React.FunctionComponent< + AdditionalPropertiesProps +> = ({ schema }) => { + if ( + schema.extensions().get(SchemaHelpers.extRenderAdditionalInfo)?.value() === + false + ) { + return null; + } + + const type = schema.type(); + if (!type?.includes('object')) { + return null; + } + + const additionalProperties = schema.additionalProperties(); + if (additionalProperties === true || additionalProperties === undefined) { + return ( +

+ Additional properties are allowed. +

+ ); + } + if (additionalProperties === false) { + return ( +

+ Additional properties are NOT allowed. +

+ ); + } + return ( + + ); +}; + +interface SchemaItemsProps { + schema: SchemaInterface; +} + +const SchemaItems: React.FunctionComponent = ({ schema }) => { + const type = schema.type(); + if (!type?.includes('array')) { + return null; + } + const items = schema.items(); + + // object in items + if ( + items && + !Array.isArray(items) && + Object.keys(items.properties() ?? {}).length + ) { + return ; + } else if (Array.isArray(items)) { + return ( + <> + SchemaItems + {items.map((item, idx) => ( + + ))} + + ); + } + return ; +}; + +interface AdditionalItemsProps { + schema: SchemaInterface; +} + +const AdditionalItems: React.FunctionComponent = ({ + schema, +}) => { + if ( + schema.extensions().get(SchemaHelpers.extRenderAdditionalInfo)?.value() === + false + ) { + return null; + } + + const type = schema.type(); + if (!type?.includes('array')) { + return null; + } + if (!Array.isArray(schema.items())) { + return null; + } + + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-explicit-any + const additionalItems = schema.additionalItems() as any; + if (additionalItems === true || additionalItems === undefined) { + return ( +

+ Additional items are allowed. +

+ ); + } + if (additionalItems === false) { + return ( +

+ Additional items are NOT allowed. +

+ ); + } + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + return ; +}; diff --git a/library/src/components/Schema.tsx b/library/src/components/Schema.tsx index 8ec964f8a..5aa7c8da1 100644 --- a/library/src/components/Schema.tsx +++ b/library/src/components/Schema.tsx @@ -94,7 +94,9 @@ export const Schema: React.FunctionComponent = ({ >
+ {/* the top tile */}
+ {/* Schema Name with collapse button */} {isExpandable && !isCircular && !isArray ? ( <> = ({ ) : (
+ {/* Schema Type */}
{isCircular ? `${schemaType} [CIRCULAR]` : schemaType}
+
+ {/* The tags */} {schema.format() && ( format: {schema.format()} @@ -182,7 +187,6 @@ export const Schema: React.FunctionComponent = ({ )} - {/* constraints */} {!!constraints.length && constraints.map((c) => ( = ({ )}
+ {/* Description */} {schema.description() !== undefined && (
{schema.description()}
)} + {/* About values */} {schema.default() !== undefined && (
Default value: @@ -235,6 +241,7 @@ export const Schema: React.FunctionComponent = ({ ))} )} + {parameterLocation && (
Parameter location:{' '} @@ -271,6 +278,22 @@ export const Schema: React.FunctionComponent = ({ )}
+ {/* {!!constraints.length && ( +
+ Rules + {!!constraints.length && + constraints.map((c) => ( + + {c} constraint + + ))} +
+ )} */} + + {/* the expandable part */} {isCircular || !isExpandable ? null : (
= ({ )} /> ))} + {schema .anyOf() ?.map((s, idx) => ( @@ -308,6 +332,7 @@ export const Schema: React.FunctionComponent = ({ )} /> ))} + {schema .allOf() ?.map((s, idx) => ( @@ -322,6 +347,7 @@ export const Schema: React.FunctionComponent = ({ )} /> ))} + {schema.not() && ( )} @@ -332,6 +358,7 @@ export const Schema: React.FunctionComponent = ({ schemaName="Property names must adhere to:" /> )} + {schema.contains() && ( = ({ {schema.if() && ( )} + {schema.then() && ( )} + {schema.else() && ( )} @@ -362,6 +391,7 @@ export const Schema: React.FunctionComponent = ({ +
)} diff --git a/library/src/components/payload/Payload2.tsx b/library/src/components/payload/Payload2.tsx new file mode 100644 index 000000000..69a1cec65 --- /dev/null +++ b/library/src/components/payload/Payload2.tsx @@ -0,0 +1,51 @@ +import React, { useState, useEffect, useContext } from 'react'; +import { SchemaInterface } from '@asyncapi/parser'; +import { CollapseButton, HiChevronRight } from '../CollapseButton'; + +interface props { + schemaName?: string; + schema: SchemaInterface; +} + +const PayloadContext = React.createContext({ + reverse: false, + deepExpanded: false, +}); + +export const Payload2 = ({ schema, schemaName = 'Payload' }: props) => { + // const { reverse, deepExpanded } = useContext(PayloadContext); + const [expanded, setExpanded] = useState(false); + const [deepExpand, setDeepExpand] = useState(false); + + return ( +
+
+
+ setExpanded((prev) => !prev)} + expanded={expanded} + > + Payload + + +
+ +
+ setExpanded((prev) => !prev)} + expanded={expanded} + rotateAngle={180} + > + Conditions + +
+
+
+ ); +}; diff --git a/library/src/containers/Messages/Message.tsx b/library/src/containers/Messages/Message.tsx index f7466e57e..ae36efef9 100644 --- a/library/src/containers/Messages/Message.tsx +++ b/library/src/containers/Messages/Message.tsx @@ -17,6 +17,8 @@ import { CONTENT_TYPES_SITE, EXTERAL_DOCUMENTATION_TEXT, } from '../../constants'; +import { Payload } from '../../components/Payload'; +import { Payload2 } from '../../components/payload/Payload2'; interface Props { message: MessageInterface; @@ -133,7 +135,9 @@ export const Message: React.FunctionComponent = ({ : undefined } > - + {/* */} + + {/* */}
)} {headers && ( diff --git a/library/src/helpers/schema.ts b/library/src/helpers/schema.ts index 12846eab9..21a67336c 100644 --- a/library/src/helpers/schema.ts +++ b/library/src/helpers/schema.ts @@ -465,17 +465,28 @@ export class SchemaHelpers { let numberRange; if (hasMin && hasMax) { - numberRange = hasExclusiveMin ? '( ' : '[ '; + // below is code for "[ 0 .. 1 ]"" + // numberRange = hasExclusiveMin ? '( ' : '[ '; + // numberRange += hasExclusiveMin ? exclusiveMin : min; + // numberRange += ' .. '; + // numberRange += hasExclusiveMax ? exclusiveMax : max; + // numberRange += hasExclusiveMax ? ' )' : ' ]'; + + // below is code for "0 <= value <= 1" + numberRange = "" numberRange += hasExclusiveMin ? exclusiveMin : min; - numberRange += ' .. '; + numberRange += hasExclusiveMin ? ' < ' : ' <= '; + numberRange += "value"; + numberRange += hasExclusiveMax ? ' < ' : ' <= '; numberRange += hasExclusiveMax ? exclusiveMax : max; - numberRange += hasExclusiveMax ? ' )' : ' ]'; } else if (hasMin) { - numberRange = hasExclusiveMin ? '> ' : '>= '; + numberRange = 'value '; + numberRange += hasExclusiveMin ? '> ' : '>= '; numberRange += hasExclusiveMin ? exclusiveMin : min; } else if (hasMax) { + numberRange = 'value '; numberRange = hasExclusiveMax ? '< ' : '<= '; - numberRange += hasExclusiveMax ? exclusiveMax : max; + numberRange += 'value ' + hasExclusiveMax ? exclusiveMax : max; } return numberRange; } diff --git a/playground/utils/defaultConfig.ts b/playground/utils/defaultConfig.ts index b95e0bd20..e84a5cda3 100644 --- a/playground/utils/defaultConfig.ts +++ b/playground/utils/defaultConfig.ts @@ -1,11 +1,11 @@ export const defaultConfig = `{ "show": { "sidebar": false, - "info": true, - "operations": true, - "servers": true, + "info": false, + "operations": false, + "servers": false, "messages": true, - "schemas": true, + "schemas": false, "errors": true }, "expand":{ From e1563fbd9a639def3ad0b17626c196fb8cc3cdb3 Mon Sep 17 00:00:00 2001 From: catosaurusrex2003 Date: Sat, 11 Jan 2025 14:55:37 +0530 Subject: [PATCH 02/41] added todo --- playground/utils/defaultConfig.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/playground/utils/defaultConfig.ts b/playground/utils/defaultConfig.ts index e84a5cda3..c2a37eedb 100644 --- a/playground/utils/defaultConfig.ts +++ b/playground/utils/defaultConfig.ts @@ -1,3 +1,4 @@ +// TODO: CHANGE THIS BACK TO ORIGINAL CONFIG export const defaultConfig = `{ "show": { "sidebar": false, From 9f6879a0aea0a335fcdf58925b74a3b39da11585 Mon Sep 17 00:00:00 2001 From: catosaurusrex2003 Date: Sun, 12 Jan 2025 00:15:31 +0530 Subject: [PATCH 03/41] more support --- library/src/components/Payload.tsx | 110 ++- library/src/components/Schema.tsx | 1 + playground/app/page.tsx | 3 +- playground/specs/index.ts | 1 + .../specs/overcomplicated-streetlight.ts | 629 ++++++++++++++++++ 5 files changed, 718 insertions(+), 26 deletions(-) create mode 100644 playground/specs/overcomplicated-streetlight.ts diff --git a/library/src/components/Payload.tsx b/library/src/components/Payload.tsx index d7fc4bf3c..006a59d86 100644 --- a/library/src/components/Payload.tsx +++ b/library/src/components/Payload.tsx @@ -79,10 +79,12 @@ export const Payload: React.FunctionComponent = ({ const parameterLocation = parameterLocationExt?.value() === true; const schemaType = SchemaHelpers.toSchemaType(schema); - const isExpandable = SchemaHelpers.isExpandable(schema) || dependentSchemas; isCircular = isCircular || schema.isCircular() || false; + console.log('isCircular: ', isCircular); + const uid = schema.$id(); + const styledSchemaName = isProperty ? 'italic' : ''; const renderedSchemaName = typeof schemaName === 'string' ? ( @@ -93,19 +95,35 @@ export const Payload: React.FunctionComponent = ({ schemaName ); - if (schemaName == "dependencies") { - console.log("schema = ",schema) - } + // string pattern, constraints, enum, const -> come in Rules and Constraints section + const showRules = + schema.pattern() || + constraints.length > 0 || + schema.contentEncoding() || + schema.enum() || + schema.const(); + + // oneOf, if, then, else, dependentSchemas -> come in Conditions section + const showConditions = + schema.oneOf()?.length || + schema.if() || + schema.then() || + schema.else() || + dependentSchemas; + + // we want the expanding dropdown to be present if schema has got other stuff, rules or conditions + const isExpandable = + SchemaHelpers.isExpandable(schema) || showRules || showConditions; return ( -
+
{/* Header Section */}
-
+
{isExpandable && !isCircular && !isArray ? (
= ({ > {renderedSchemaName} -
) : ( @@ -130,6 +141,31 @@ export const Payload: React.FunctionComponent = ({ {isCircular ? `${schemaType} [CIRCULAR]` : schemaType} + {schema.format() && ( + + format: {schema.format()} + + )} + {schema.contentMediaType() !== undefined && ( + + media type: {schema.contentMediaType()} + + )} + {uid && !uid.startsWith(' + uid: {uid} + + )} + + {isExpandable && !isCircular && !isArray && ( + + )}
@@ -167,25 +203,53 @@ export const Payload: React.FunctionComponent = ({ {schema.description()}
)} + {parameterLocation && ( +
+ Parameter location:{' '} + + {parameterLocation} + +
+ )} + {externalDocs && ( + + + Documentation + + + )}
{/* Expandable Content */} {!isCircular && isExpandable && expanded && (
- {/* Rules Section */} - {(constraints.length > 0 || schema.enum() || schema.const()) && ( + {/* Rules Section: it generally doesnt have any recursion in it */} + {showRules && (

Rules & Constraints

-
+
+ {schema.pattern() !== undefined && ( + + must match: {schema.pattern()} + + )} + {schema.contentEncoding() !== undefined && ( + + encoding: {schema.contentEncoding()} + + )} {constraints.map((constraint) => ( -
{constraint} -
+
))} {schema.enum() && (
@@ -212,19 +276,15 @@ export const Payload: React.FunctionComponent = ({
)} - {/* Conditions Section */} - {(schema.if() || - schema.then() || - schema.else() || - schema.oneOf()?.length || - dependentSchemas) && ( + {/* Conditions Section: has hella recursion in it*/} + {showConditions && (

Conditions

{schema.oneOf()?.length && ( -
+
Can be One Of these:
diff --git a/library/src/components/Schema.tsx b/library/src/components/Schema.tsx index 5aa7c8da1..cddcae57b 100644 --- a/library/src/components/Schema.tsx +++ b/library/src/components/Schema.tsx @@ -77,6 +77,7 @@ export const Schema: React.FunctionComponent = ({ const isExpandable = SchemaHelpers.isExpandable(schema) || dependentSchemas; isCircular = isCircular || schema.isCircular() || false; + console.log('isCircular: ', isCircular); const uid = schema.$id(); const styledSchemaName = isProperty ? 'italic' : ''; const renderedSchemaName = diff --git a/playground/app/page.tsx b/playground/app/page.tsx index 66c128f42..d66e21c6d 100644 --- a/playground/app/page.tsx +++ b/playground/app/page.tsx @@ -17,7 +17,8 @@ import { import { defaultConfig, parse, debounce } from '@/utils'; import * as specs from '@/specs'; -const defaultSchema = specs.streetlights; +// const defaultSchema = specs.streetlights; +const defaultSchema = specs.overcomplicatedStreetlights; interface State { schema: string; diff --git a/playground/specs/index.ts b/playground/specs/index.ts index a2d734318..63fd02f77 100644 --- a/playground/specs/index.ts +++ b/playground/specs/index.ts @@ -11,3 +11,4 @@ export * from './rpc-client'; export * from './rpc-server'; export * from './slack-rtm'; export * from './streetlights'; +export * from './overcomplicated-streetlight'; \ No newline at end of file diff --git a/playground/specs/overcomplicated-streetlight.ts b/playground/specs/overcomplicated-streetlight.ts new file mode 100644 index 000000000..fab8350d2 --- /dev/null +++ b/playground/specs/overcomplicated-streetlight.ts @@ -0,0 +1,629 @@ +export const overcomplicatedStreetlights = `asyncapi: '2.6.0' +id: 'urn:com:smartylighting:streetlights:server' +info: + title: Streetlights API + version: '1.0.0' + description: | + The Smartylighting Streetlights API allows you to remotely manage the city lights. + + ### Check out its awesome features: + + * Turn a specific streetlight on/off 🌃 + * Dim a specific streetlight 😎 + * Receive real-time information about environmental lighting conditions 📈 + + termsOfService: http://asyncapi.org/terms/ + contact: + name: API Support + url: http://www.asyncapi.org/support + email: support@asyncapi.org + license: + name: Apache 2.0 + url: http://www.apache.org/licenses/LICENSE-2.0.html +tags: + - name: root-tag1 + externalDocs: + description: External docs description 1 + url: https://www.asyncapi.com/ + - name: root-tag2 + description: Description 2 + externalDocs: + url: "https://www.asyncapi.com/" + - name: root-tag3 + - name: root-tag4 + description: Description 4 + - name: root-tag5 + externalDocs: + url: "https://www.asyncapi.com/" +externalDocs: + description: Find more info here + url: https://example.com +defaultContentType: application/json + +servers: + production: + url: api.streetlights.smartylighting.com:{port} + protocol: mqtt + description: | + Private server that requires authorization. + Once the socket is open you can subscribe to private-data channels by sending an authenticated subscribe request message. + + The API client must request an authentication "token" via the following REST API endpoint "GetWebSocketsToken" to connect to WebSockets Private endpoints. For more details read https://support.kraken.com/hc/en-us/articles/360034437672-How-to-retrieve-a-WebSocket-authentication-token-Example-code-in-Python-3 + + The resulting token must be provided in the "token" field of any new private WebSocket feed subscription: + \`\`\`json + { + "event": "subscribe", + "subscription": + { + "name": "ownTrades", + "token": "WW91ciBhdXRoZW50aWNhdGlvbiB0b2tlbiBnb2VzIGhlcmUu" + } + } + \`\`\` + + \`\`\`elixir + defmodule Hello do + def world do + IO.puts("hello") + end + end + \`\`\` + variables: + port: + description: Secure connection (TLS) is available through port 8883. + default: '1883' + enum: + - '1883' + - '8883' + tags: + - name: 'env:production' + security: + - apiKey: [] + - supportedOauthFlows: + - streetlights:on + - streetlights:off + - streetlights:dim + - openIdConnectWellKnown: [] + dummy-mqtt: + url: mqtt://localhost + protocol: mqtt + description: | + Private server + + \`\`\`csharp + using System; + + namespace HelloWorld + { + class Program + { + static void Main(string[] args) + { + Console.WriteLine("Hello World!"); + } + } + } + \`\`\` + bindings: + mqtt: + clientId: guest + cleanSession: false + keepAlive: 60 + bindingVersion: 0.1.0 + lastWill: + topic: smartylighting/streetlights/1/0/lastwill + qos: 1 + message: so long and thanks for all the fish + retain: false + dummy-amqp: + url: amqp://localhost:{port} + protocol: amqp + description: dummy AMQP broker + protocolVersion: "0.9.1" + variables: + port: + enum: + - '15672' + - '5672' + dommy-kafka: + url: http://localhost:{port} + protocol: kafka + description: dummy Kafka broker + variables: + port: + default: '9092' + +channels: + smartylighting/streetlights/1/0/event/{streetlightId}/lighting/measured: + x-security: + $ref: '#/components/securitySchemes/supportedOauthFlows/flows/clientCredentials' + description: The topic on which measured values may be produced and consumed. + parameters: + streetlightId: + $ref: '#/components/parameters/streetlightId' + servers: + - production + - dommy-kafka + subscribe: + summary: Receive information about environmental lighting conditions of a particular streetlight. + operationId: receiveLightMeasurement + externalDocs: + description: Find more info here + url: https://example.com + traits: + - $ref: '#/components/operationTraits/kafka' + message: + $ref: '#/components/messages/lightMeasured' + bindings: + mqtt: + qos: 1 + bindingVersion: 0.1.0 + http: + type: request + method: GET + query: + type: object + required: + - companyId + properties: + companyId: + type: number + minimum: 1 + description: The Id of the company. + additionalProperties: false + + smartylighting/streetlights/1/0/action/{streetlightId}/turn/on: + parameters: + streetlightId: + $ref: '#/components/parameters/streetlightId' + servers: + - production + - dummy-amqp + publish: + operationId: turnOn + security: + - supportedOauthFlows: + - streetlights:on + externalDocs: + description: Find more info here + url: https://example.com + traits: + - $ref: '#/components/operationTraits/kafka' + message: + $ref: '#/components/messages/turnOnOff' + + smartylighting/streetlights/1/0/action/{streetlightId}/turn/off: + parameters: + streetlightId: + $ref: '#/components/parameters/streetlightId' + publish: + traits: + - $ref: '#/components/operationTraits/kafka' + message: + $ref: '#/components/messages/turnOnOff' + + smartylighting/streetlights/1/0/action/{streetlightId}/dim: + parameters: + streetlightId: + $ref: '#/components/parameters/streetlightId' + servers: + - production + - dummy-amqp + publish: + operationId: dimLight + traits: + - $ref: '#/components/operationTraits/kafka' + message: + $ref: '#/components/messages/dimLight' + +components: + messages: + lightMeasured: + messageId: lightMeasured Message ID + name: lightMeasured + title: Light measured + summary: Inform about environmental lighting conditions for a particular streetlight. + contentType: application/json + correlationId: + $ref: "#/components/correlationIds/sentAtCorrelator" + externalDocs: + url: "https://www.asyncapi.com/" + traits: + - $ref: '#/components/messageTraits/commonHeaders' + payload: + $ref: "#/components/schemas/lightMeasuredPayload" + bindings: + mqtt: + bindingVersion: 0.1.0 + examples: + - headers: + my-app-header: 12 + payload: + lumens: 1 + sentAt: "2020-01-31T13:24:53Z" + - headers: + my-app-header: 13 + - payload: + lumens: 3 + sentAt: "2020-10-31T13:24:53Z" + x-schema-extensions-as-object: + type: object + properties: + prop1: + type: string + prop2: + type: integer + minimum: 0 + x-schema-extensions-as-primitive: dummy + x-schema-extensions-as-array: + - "item1" + - "item2" + LwM2mOjbects: + payload: + type: object + properties: + objectLinks: + type: string + example: + objectLinks: "lwm2m=1.1, , ;ssid=1, , " + turnOnOff: + name: turnOnOff + title: Turn on/off + summary: Command a particular streetlight to turn the lights on or off. + payload: + $ref: "#/components/schemas/turnOnOffPayload" + headers: + type: object + properties: + $ref: '#/components/schemas/streamHeaders' + dimLight: + name: dimLight + title: Dim light + summary: Command a particular streetlight to dim the lights. + correlationId: + $ref: "#/components/correlationIds/sentAtCorrelator" + externalDocs: + url: "https://www.asyncapi.com/" + tags: + - name: operation-tag1 + externalDocs: + description: External docs description 1 + url: https://www.asyncapi.com/ + - name: operation-tag2 + description: Description 2 + externalDocs: + url: "https://www.asyncapi.com/" + - name: operation-tag3 + - name: operation-tag4 + description: Description 4 + - name: operation-tag5 + externalDocs: + url: "https://www.asyncapi.com/" + traits: + - $ref: '#/components/messageTraits/commonHeaders' + payload: + $ref: "#/components/schemas/dimLightPayload" + + schemas: + lightMeasuredPayload: + $id: "#lightMeasuredID" + type: object + properties: + lumens: + type: integer + description: Light intensity measured in lumens. + writeOnly: true + oneOf: + - minimum: 0 + maximum: 5 + - minimum: 10 + maximum: 20 + externalDocs: + url: "https://www.asyncapi.com/" + sentAt: + $ref: "#/components/schemas/sentAt" + location: + type: string + pattern: "^[A-Z]{2}-[0-9]{5}$" # This will match patterns like "NY-12345" + description: Location code for the streetlight following format XX-12345 + ifElseThen: + type: integer + minimum: 1 + maximum: 1000 + if: + minimum: 100 + then: + multipleOf: 100 + else: + if: + minimum: 10 + then: + multipleOf: 10 + dependencies: + $ref: "#/components/schemas/dependenciesObject" + anySchema: true + cannotBeDefined: false + restrictedAny: + minimum: 1 + maximum: 1000 + required: + - lumens + x-schema-extensions-as-object: + type: object + properties: + prop1: + type: string + prop2: + type: integer + minimum: 0 + x-schema-extensions-as-primitive: dummy + x-schema-extensions-as-array: + - "item1" + - "item2" + turnOnOffPayload: + type: object + properties: + command: + type: string + enum: + - on + - off + description: Whether to turn on or off the light. + sentAt: + $ref: "#/components/schemas/sentAt" + arrayRank: + $ref: '#/components/schemas/arrayRank' + additionalProperties: + type: string + + dimLightPayload: + type: object + properties: + percentage: + type: integer + description: Percentage to which the light should be dimmed to. + minimum: 0 + maximum: 100 + readOnly: true + sentAt: + $ref: "#/components/schemas/sentAt" + key: + type: integer + not: + minimum: 3 + patternProperties: + ^S_: + type: string + ^I_: + type: integer + additionalProperties: false + sentAt: + type: string + format: date-time + description: Date and time when the message was sent. + union: + type: [string, number] + objectWithKey: + title: objectWithKey + type: object + propertyNames: + format: email + properties: + key: + type: string + objectWithKey2: + type: object + properties: + key2: + type: string + format: time + oneOfSchema: + oneOf: + - $ref: "#/components/schemas/objectWithKey" + - $ref: "#/components/schemas/objectWithKey2" + anyOfSchema: + anyOf: + - $ref: "#/components/schemas/objectWithKey" + - $ref: "#/components/schemas/objectWithKey2" + allOfSchema: + allOf: + - $ref: "#/components/schemas/objectWithKey" + - $ref: "#/components/schemas/objectWithKey2" + arrayContains: + type: array + contains: + type: integer + dependenciesObject: + type: object + properties: + name: + type: string + credit_card: + type: integer + billing_address: + type: string + schema_dependency: + type: string + required: + - name + dependencies: + credit_card: + properties: + billing_address: + type: string + billing_address2: + type: string + required: + - billing_address + dependencies: + billing_address2: + properties: + billing_address3: + type: string + required: + - billing_address3 + + subscriptionStatus: + type: object + oneOf: + - properties: + channelID: + type: integer + description: ChannelID on successful subscription, applicable to public messages only. + channelName: + type: string + description: Channel Name on successful subscription. For payloads 'ohlc' and 'book', respective interval or depth will be added as suffix. + - properties: + errorMessage: + type: string + properties: + event: + type: string + const: subscriptionStatus + subscription: + type: object + properties: + depth: + type: string + interval: + type: string + required: + - name + required: + - event + + arrayRank: + type: object + properties: + valueRank: + $ref: '#/components/schemas/arrayValueRank' + arrayDimensions: + $ref: '#/components/schemas/arrayArrayDimensions' + + arrayValueRank: + description: > + This Attribute indicates whether the val Attribute of the datapoint is an + array and how many dimensions the array has. + type: integer + default: -1 + examples: + - 2 + oneOf: + - const: -1 + description: 'Scalar: The value is not an array.' + - const: 0 + description: 'OneOrMoreDimensions: The value is an array with one or more dimensions.' + - const: 1 + description: 'OneDimension: The value is an array with one dimension.' + - const: 2 + description: 'The value is an array with two dimensions.' + + arrayArrayDimensions: + type: array + items: + type: integer + minimum: 0 + examples: + - [3, 5] + + streamHeaders: + Etag: + type: string + description: | + The RFC7232 ETag header field in a response provides the current entity- + tag for the selected resource. An entity-tag is an opaque identifier for + different versions of a resource over time, regardless whether multiple + versions are valid at the same time. An entity-tag consists of an opaque + quoted string, possibly prefixed by a weakness indicator. + example: 411a + Cache-Control: + description: The Cache-Control HTTP header holds directives (instructions) for caching in request. + type: string + example: no-cache, no-store, must-revalidate + + securitySchemes: + apiKey: + type: apiKey + in: user + description: Provide your API key as the user and leave the password empty. + supportedOauthFlows: + type: oauth2 + description: Flows to support OAuth 2.0 + flows: + implicit: + authorizationUrl: 'https://authserver.example/auth' + scopes: + 'streetlights:on': Ability to switch lights on + 'streetlights:off': Ability to switch lights off + 'streetlights:dim': Ability to dim the lights + password: + tokenUrl: 'https://authserver.example/token' + scopes: + 'streetlights:on': Ability to switch lights on + 'streetlights:off': Ability to switch lights off + 'streetlights:dim': Ability to dim the lights + clientCredentials: + tokenUrl: 'https://authserver.example/token' + scopes: + 'streetlights:on': Ability to switch lights on + 'streetlights:off': Ability to switch lights off + 'streetlights:dim': Ability to dim the lights + authorizationCode: + authorizationUrl: 'https://authserver.example/auth' + tokenUrl: 'https://authserver.example/token' + refreshUrl: 'https://authserver.example/refresh' + scopes: + 'streetlights:on': Ability to switch lights on + 'streetlights:off': Ability to switch lights off + 'streetlights:dim': Ability to dim the lights + openIdConnectWellKnown: + type: openIdConnect + openIdConnectUrl: 'https://authserver.example/.well-known' + + parameters: + streetlightId: + description: The ID of the streetlight. + schema: + type: string + location: "$message.payload#/user/id" + Location: + description: The physical location coordinates of the streetlight + schema: + type: object + properties: + latitude: + type: number + minimum: -90 + maximum: 90 + longitude: + type: number + minimum: -180 + maximum: 180 + required: + - latitude + - longitude + + correlationIds: + sentAtCorrelator: + description: Data from message payload used as correlation ID + location: $message.payload#/sentAt + + messageTraits: + commonHeaders: + headers: + type: object + properties: + my-app-header: + type: integer + minimum: 0 + maximum: 100 + required: + - my-app-header + + operationTraits: + kafka: + bindings: + kafka: + clientId: my-app-id +`; From 9a9faa72a13d62806c7f056efe85b09cc797552f Mon Sep 17 00:00:00 2001 From: catosaurusrex2003 Date: Sun, 12 Jan 2025 14:30:22 +0530 Subject: [PATCH 04/41] almost everything added --- library/src/components/Payload.tsx | 93 ++++++++++++++++++++++++++---- 1 file changed, 82 insertions(+), 11 deletions(-) diff --git a/library/src/components/Payload.tsx b/library/src/components/Payload.tsx index 006a59d86..ea2a8a876 100644 --- a/library/src/components/Payload.tsx +++ b/library/src/components/Payload.tsx @@ -156,6 +156,13 @@ export const Payload: React.FunctionComponent = ({ uid: {uid} )} + {/* TODO: find out if below is really needed ?? + cuz schema.const() is already shown in a strict manner in Rules and Constraints */} + {SchemaHelpers.prettifyValue(schema.const(), false) && ( + + {SchemaHelpers.prettifyValue(schema.const(), false)} + + )} {isExpandable && !isCircular && !isArray && ( -
- -
- setExpanded((prev) => !prev)} - expanded={expanded} - rotateAngle={180} - > - Conditions - -
-
-
- ); -}; diff --git a/library/src/containers/Messages/Message.tsx b/library/src/containers/Messages/Message.tsx index ae36efef9..f44503b30 100644 --- a/library/src/containers/Messages/Message.tsx +++ b/library/src/containers/Messages/Message.tsx @@ -18,7 +18,6 @@ import { EXTERAL_DOCUMENTATION_TEXT, } from '../../constants'; import { Payload } from '../../components/Payload'; -import { Payload2 } from '../../components/payload/Payload2'; interface Props { message: MessageInterface; @@ -137,7 +136,6 @@ export const Message: React.FunctionComponent = ({ > {/* */} - {/* */}
)} {headers && ( From f3809c0735211e26d0b12924e46049e35466bfc6 Mon Sep 17 00:00:00 2001 From: catosaurusrex2003 Date: Sun, 12 Jan 2025 20:54:48 +0530 Subject: [PATCH 09/41] sonar cloud issues fixed --- library/src/components/Payload.tsx | 41 ++++++++++++++---------------- 1 file changed, 19 insertions(+), 22 deletions(-) diff --git a/library/src/components/Payload.tsx b/library/src/components/Payload.tsx index 2f7b3a1c0..c1b865013 100644 --- a/library/src/components/Payload.tsx +++ b/library/src/components/Payload.tsx @@ -37,12 +37,26 @@ export const Payload: React.FunctionComponent = ({ isArray = false, // eslint-disable-next-line sonarjs/cognitive-complexity }) => { - // if (schemaName == "Payload") { - // console.log("schema = ",schema) - // } const { reverse, deepExpanded } = useContext(PayloadSchemaContext); const [expanded, setExpanded] = useState(propExpanded || isArray); const [deepExpand, setDeepExpand] = useState(false); + const [tabOpen, setTabOpen] = useState<'Rules' | 'Conditions'>('Rules'); + + useEffect(() => { + if (!isArray) { + setDeepExpand(deepExpanded); + } + }, [isArray, deepExpanded, setDeepExpand]); + + useEffect(() => { + if (!isArray) { + setExpanded(deepExpand); + } + }, [isArray, deepExpand, setExpanded]); + + useEffect(() => { + setTabOpen(showRules ? 'Rules' : 'Conditions'); + }, [schema]); if ( !schema || @@ -69,7 +83,6 @@ export const Payload: React.FunctionComponent = ({ const schemaType = SchemaHelpers.toSchemaType(schema); isCircular = isCircular || schema.isCircular() || false; - console.log('isCircular: ', isCircular); const uid = schema.$id(); @@ -108,22 +121,6 @@ export const Payload: React.FunctionComponent = ({ const isExpandable = SchemaHelpers.isExpandable(schema) || showRules || showConditions; - const [tabOpen, setTabOpen] = useState<'Rules' | 'Conditions'>( - showRules ? 'Rules' : 'Conditions', - ); - - useEffect(() => { - if (!isArray) { - setDeepExpand(deepExpanded); - } - }, [isArray, deepExpanded, setDeepExpand]); - - useEffect(() => { - if (!isArray) { - setExpanded(deepExpand); - } - }, [isArray, deepExpand, setExpanded]); - return ( = ({ )}
{/* Rules Section: it generally doesnt have any recursion in it */} - {showRules && tabOpen=="Rules" && ( + {showRules && tabOpen == 'Rules' && (
{schema.pattern() !== undefined && ( @@ -308,7 +305,7 @@ export const Payload: React.FunctionComponent = ({ )} {/* Conditions Section: has hella recursion in it*/} - {showConditions && tabOpen=="Conditions" && ( + {showConditions && tabOpen == 'Conditions' && (
{schema.oneOf()?.length && ( From d1eabf44dcf939eb7717e97e594978d4a8efddac Mon Sep 17 00:00:00 2001 From: catosaurusrex2003 Date: Sun, 12 Jan 2025 20:59:40 +0530 Subject: [PATCH 10/41] sonar cloud again --- library/src/components/Payload.tsx | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/library/src/components/Payload.tsx b/library/src/components/Payload.tsx index c1b865013..e8b020aef 100644 --- a/library/src/components/Payload.tsx +++ b/library/src/components/Payload.tsx @@ -241,20 +241,26 @@ export const Payload: React.FunctionComponent = ({
{showRules && ( -

setTabOpen('Rules')} + role="tab" + aria-selected={tabOpen === 'Rules'} + aria-controls="rules-panel" > Rules -

+ )} {showConditions && ( -

setTabOpen('Conditions')} + role="tab" + aria-selected={tabOpen === 'Conditions'} + aria-controls="conditions-panel" > Conditions -

+ )}
{/* Rules Section: it generally doesnt have any recursion in it */} From 33d68ce00e6a24c6d268c047af560d6e7479dc4d Mon Sep 17 00:00:00 2001 From: catosaurusrex2003 Date: Sun, 12 Jan 2025 22:26:28 +0530 Subject: [PATCH 11/41] .. --- library/src/components/Schema.tsx | 31 ------------------------------- 1 file changed, 31 deletions(-) diff --git a/library/src/components/Schema.tsx b/library/src/components/Schema.tsx index cddcae57b..44d9bf39b 100644 --- a/library/src/components/Schema.tsx +++ b/library/src/components/Schema.tsx @@ -77,7 +77,6 @@ export const Schema: React.FunctionComponent = ({ const isExpandable = SchemaHelpers.isExpandable(schema) || dependentSchemas; isCircular = isCircular || schema.isCircular() || false; - console.log('isCircular: ', isCircular); const uid = schema.$id(); const styledSchemaName = isProperty ? 'italic' : ''; const renderedSchemaName = @@ -95,9 +94,7 @@ export const Schema: React.FunctionComponent = ({ >
- {/* the top tile */}
- {/* Schema Name with collapse button */} {isExpandable && !isCircular && !isArray ? ( <> = ({ ) : (
- {/* Schema Type */}
{isCircular ? `${schemaType} [CIRCULAR]` : schemaType}
- {/* The tags */} {schema.format() && ( format: {schema.format()} @@ -205,14 +200,12 @@ export const Schema: React.FunctionComponent = ({ )}
- {/* Description */} {schema.description() !== undefined && (
{schema.description()}
)} - {/* About values */} {schema.default() !== undefined && (
Default value: @@ -242,7 +235,6 @@ export const Schema: React.FunctionComponent = ({ ))} )} - {parameterLocation && (
Parameter location:{' '} @@ -279,22 +271,6 @@ export const Schema: React.FunctionComponent = ({ )}
- {/* {!!constraints.length && ( -
- Rules - {!!constraints.length && - constraints.map((c) => ( - - {c} constraint - - ))} -
- )} */} - - {/* the expandable part */} {isCircular || !isExpandable ? null : (
= ({ )} /> ))} - {schema .anyOf() ?.map((s, idx) => ( @@ -333,7 +308,6 @@ export const Schema: React.FunctionComponent = ({ )} /> ))} - {schema .allOf() ?.map((s, idx) => ( @@ -348,7 +322,6 @@ export const Schema: React.FunctionComponent = ({ )} /> ))} - {schema.not() && ( )} @@ -359,7 +332,6 @@ export const Schema: React.FunctionComponent = ({ schemaName="Property names must adhere to:" /> )} - {schema.contains() && ( = ({ {schema.if() && ( )} - {schema.then() && ( )} - {schema.else() && ( )} @@ -392,7 +362,6 @@ export const Schema: React.FunctionComponent = ({ -
)} From ff94361498fdae0e598bedadcac4fddf04b566be Mon Sep 17 00:00:00 2001 From: catosaurusrex2003 Date: Sun, 12 Jan 2025 22:27:24 +0530 Subject: [PATCH 12/41] . --- library/src/components/Schema.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/src/components/Schema.tsx b/library/src/components/Schema.tsx index 44d9bf39b..8ec964f8a 100644 --- a/library/src/components/Schema.tsx +++ b/library/src/components/Schema.tsx @@ -158,7 +158,6 @@ export const Schema: React.FunctionComponent = ({
{isCircular ? `${schemaType} [CIRCULAR]` : schemaType}
-
{schema.format() && ( @@ -183,6 +182,7 @@ export const Schema: React.FunctionComponent = ({ )} + {/* constraints */} {!!constraints.length && constraints.map((c) => ( Date: Sun, 12 Jan 2025 23:08:00 +0530 Subject: [PATCH 13/41] --- library/src/components/Payload.tsx | 34 ++++++++++++------- library/src/helpers/schema.ts | 7 ++-- .../specs/overcomplicated-streetlight.ts | 3 +- 3 files changed, 28 insertions(+), 16 deletions(-) diff --git a/library/src/components/Payload.tsx b/library/src/components/Payload.tsx index e8b020aef..ac318f3af 100644 --- a/library/src/components/Payload.tsx +++ b/library/src/components/Payload.tsx @@ -98,6 +98,7 @@ export const Payload: React.FunctionComponent = ({ // comes in Rules section const showRules = + schema.format() || schema.pattern() || constraints.length > 0 || schema.contentEncoding() || @@ -147,11 +148,6 @@ export const Payload: React.FunctionComponent = ({ {isCircular ? `${schemaType} [CIRCULAR]` : schemaType} - {schema.format() && ( - - format: {schema.format()} - - )} {schema.contentMediaType() !== undefined && ( media type: {schema.contentMediaType()} @@ -267,15 +263,29 @@ export const Payload: React.FunctionComponent = ({ {showRules && tabOpen == 'Rules' && (
- {schema.pattern() !== undefined && ( - - must match: {schema.pattern()} - + {schema.format() && ( + + format:{' '} + + {schema.format()} + + + )} + {schema.pattern() && ( + + must match:{' '} + + {schema.pattern()} + + )} {schema.contentEncoding() !== undefined && ( - - encoding: {schema.contentEncoding()} - + + encoding:{' '} + + {schema.contentEncoding()} + + )} {constraints.map((constraint) => ( -
+
{schema.format() && ( format:{' '} @@ -297,7 +297,7 @@ export const Payload: React.FunctionComponent = ({ ))} {schema.const() !== undefined && (
- Constant value: + Constant value: {SchemaHelpers.prettifyValue(schema.const())} @@ -305,11 +305,11 @@ export const Payload: React.FunctionComponent = ({ )} {schema.enum() && (
- Allowed values: + Allowed values: {schema.enum()?.map((e, idx) => ( {SchemaHelpers.prettifyValue(e)} @@ -327,7 +327,7 @@ export const Payload: React.FunctionComponent = ({ {schema.oneOf()?.length && (
- Can be One Of these: + Can be One Of the following:
{schema .oneOf() @@ -337,8 +337,8 @@ export const Payload: React.FunctionComponent = ({ schema={s} schemaName={SchemaHelpers.applicatorSchemaName( idx, - 'Adheres to', - 'Or to', + '', + '', s.title() ?? s.id(), )} /> @@ -349,7 +349,7 @@ export const Payload: React.FunctionComponent = ({ {schema.anyOf()?.length && (
- Can be Any Of these: + Can be Any Of the following:
{schema .anyOf() @@ -359,8 +359,8 @@ export const Payload: React.FunctionComponent = ({ schema={s} schemaName={SchemaHelpers.applicatorSchemaName( idx, - 'Can adhere to', - 'Or to', + '', + '', s.title() ?? s.id(), )} /> @@ -371,7 +371,7 @@ export const Payload: React.FunctionComponent = ({ {schema.allOf()?.length && (
- Must consist All Of these: + Must consist All Of the following:
{schema .allOf() @@ -381,8 +381,8 @@ export const Payload: React.FunctionComponent = ({ schema={s} schemaName={SchemaHelpers.applicatorSchemaName( idx, - 'Consists of', - 'And of', + '', + '', s.title() ?? s.id(), )} /> @@ -393,7 +393,7 @@ export const Payload: React.FunctionComponent = ({ {schema.not() && ( )} From ad591552ff20475f90ebbd206c703f9231a8e4e9 Mon Sep 17 00:00:00 2001 From: catosaurusrex2003 Date: Tue, 14 Jan 2025 19:45:28 +0530 Subject: [PATCH 15/41] feild status indicator correct conditional --- library/src/components/Payload.tsx | 57 +++++++++++++++--------------- 1 file changed, 29 insertions(+), 28 deletions(-) diff --git a/library/src/components/Payload.tsx b/library/src/components/Payload.tsx index 3fbedd622..eeed48537 100644 --- a/library/src/components/Payload.tsx +++ b/library/src/components/Payload.tsx @@ -166,6 +166,35 @@ export const Payload: React.FunctionComponent = ({ )} + {/* Field Status Indicators */} + {(required || + schema.deprecated() || + schema.writeOnly() || + schema.readOnly()) && ( +
+ {required && ( + + required + + )} + {schema.deprecated() && ( + + deprecated + + )} + {schema.writeOnly() && ( + + write-only + + )} + {schema.readOnly() && ( + + read-only + + )} +
+ )} + {isExpandable && !isCircular && !isArray && (
- {/* Field Status Indicators */} - {required || - schema.deprecated() || - schema.writeOnly() || - (schema.readOnly() && ( -
- {required && ( - - required - - )} - {schema.deprecated() && ( - - deprecated - - )} - {schema.writeOnly() && ( - - write-only - - )} - {schema.readOnly() && ( - - read-only - - )} -
- ))} {/* Description */} {schema.description() && (
From eb8698235fca9d252249c1f62cb54f2e89561d29 Mon Sep 17 00:00:00 2001 From: catosaurusrex2003 Date: Tue, 14 Jan 2025 20:25:03 +0530 Subject: [PATCH 16/41] mkdir --- library/src/components/{ => Payload}/Payload.tsx | 4 ++-- library/src/containers/Messages/Message.tsx | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) rename library/src/components/{ => Payload}/Payload.tsx (99%) diff --git a/library/src/components/Payload.tsx b/library/src/components/Payload/Payload.tsx similarity index 99% rename from library/src/components/Payload.tsx rename to library/src/components/Payload/Payload.tsx index eeed48537..1f8accad3 100644 --- a/library/src/components/Payload.tsx +++ b/library/src/components/Payload/Payload.tsx @@ -1,8 +1,8 @@ import React, { useState, useEffect, useContext } from 'react'; import { SchemaInterface } from '@asyncapi/parser'; -import { Href, CollapseButton, Markdown, Extensions } from './index'; -import { SchemaHelpers } from '../helpers'; +import { Href, CollapseButton, Markdown, Extensions } from '../index'; +import { SchemaHelpers } from '../../helpers'; interface Props { schemaName?: React.ReactNode; diff --git a/library/src/containers/Messages/Message.tsx b/library/src/containers/Messages/Message.tsx index f44503b30..3b85e6f43 100644 --- a/library/src/containers/Messages/Message.tsx +++ b/library/src/containers/Messages/Message.tsx @@ -17,7 +17,7 @@ import { CONTENT_TYPES_SITE, EXTERAL_DOCUMENTATION_TEXT, } from '../../constants'; -import { Payload } from '../../components/Payload'; +import { Payload } from '../../components/Payload/Payload'; interface Props { message: MessageInterface; From f4551f1a23d28db78a5fd5126c4e4f3b56441692 Mon Sep 17 00:00:00 2001 From: catosaurusrex2003 Date: Tue, 14 Jan 2025 21:33:43 +0530 Subject: [PATCH 17/41] exmaples, corrected conditional again --- library/src/components/Payload/IfThenElse.tsx | 12 +++++++++ library/src/components/Payload/Payload.tsx | 27 ++++++++++++++++--- 2 files changed, 35 insertions(+), 4 deletions(-) create mode 100644 library/src/components/Payload/IfThenElse.tsx diff --git a/library/src/components/Payload/IfThenElse.tsx b/library/src/components/Payload/IfThenElse.tsx new file mode 100644 index 000000000..fbd6430f0 --- /dev/null +++ b/library/src/components/Payload/IfThenElse.tsx @@ -0,0 +1,12 @@ +import React, { useState, useEffect, useContext } from 'react'; +import { SchemaInterface } from '@asyncapi/parser'; + +interface props { + ifSchema: SchemaInterface | undefined; + thenSchema: SchemaInterface | undefined; + elseSchema: SchemaInterface | undefined; +} + +export const IfThenElse = ({ ifSchema, thenSchema, elseSchema }: props) => { + return
TODO
; +}; diff --git a/library/src/components/Payload/Payload.tsx b/library/src/components/Payload/Payload.tsx index 1f8accad3..bce80dfce 100644 --- a/library/src/components/Payload/Payload.tsx +++ b/library/src/components/Payload/Payload.tsx @@ -103,7 +103,7 @@ export const Payload: React.FunctionComponent = ({ constraints.length > 0 || schema.contentEncoding() || schema.enum() || - schema.const(); + schema.const() !== undefined; // comes in Conditions section const showConditions = @@ -160,17 +160,18 @@ export const Payload: React.FunctionComponent = ({ )} {/* TODO: find out if below is really needed ?? cuz schema.const() is already shown in a strict manner in Rules */} - {SchemaHelpers.prettifyValue(schema.const(), false) && ( + {/* {SchemaHelpers.prettifyValue(schema.const(), false) && ( {SchemaHelpers.prettifyValue(schema.const(), false)} - )} + )} */} {/* Field Status Indicators */} {(required || schema.deprecated() || schema.writeOnly() || - schema.readOnly()) && ( + schema.readOnly() || + isPatternProperty) && (
{required && ( @@ -182,6 +183,11 @@ export const Payload: React.FunctionComponent = ({ deprecated )} + {isPatternProperty && ( +
+ (pattern property) +
+ )} {schema.writeOnly() && ( write-only @@ -213,6 +219,19 @@ export const Payload: React.FunctionComponent = ({ {schema.description()}
)} + {schema.examples() && ( +
    + Examples values:{' '} + {schema.examples()?.map((e, idx) => ( +
  • + {SchemaHelpers.prettifyValue(e)} +
  • + ))} +
+ )} {parameterLocation && (
Parameter location:{' '} From 364417365286df796bba1535cc9612e57eb2e3ab Mon Sep 17 00:00:00 2001 From: catosaurusrex2003 Date: Mon, 20 Jan 2025 21:05:19 +0530 Subject: [PATCH 18/41] ... --- library/src/components/Payload/IfThenElse.tsx | 12 - library/src/components/Payload/Payload.tsx | 10 +- playground/app/page.tsx | 1 + playground/specs/complex-schema.ts | 253 ++++++++++++++++++ playground/specs/index.ts | 3 +- 5 files changed, 261 insertions(+), 18 deletions(-) delete mode 100644 library/src/components/Payload/IfThenElse.tsx create mode 100644 playground/specs/complex-schema.ts diff --git a/library/src/components/Payload/IfThenElse.tsx b/library/src/components/Payload/IfThenElse.tsx deleted file mode 100644 index fbd6430f0..000000000 --- a/library/src/components/Payload/IfThenElse.tsx +++ /dev/null @@ -1,12 +0,0 @@ -import React, { useState, useEffect, useContext } from 'react'; -import { SchemaInterface } from '@asyncapi/parser'; - -interface props { - ifSchema: SchemaInterface | undefined; - thenSchema: SchemaInterface | undefined; - elseSchema: SchemaInterface | undefined; -} - -export const IfThenElse = ({ ifSchema, thenSchema, elseSchema }: props) => { - return
TODO
; -}; diff --git a/library/src/components/Payload/Payload.tsx b/library/src/components/Payload/Payload.tsx index bce80dfce..0b68681d6 100644 --- a/library/src/components/Payload/Payload.tsx +++ b/library/src/components/Payload/Payload.tsx @@ -282,9 +282,9 @@ export const Payload: React.FunctionComponent = ({ {/* Rules Section: it generally doesnt have any recursion in it */} {showRules && tabOpen == 'Rules' && (
-
+
{schema.format() && ( - + format:{' '} {schema.format()} @@ -292,7 +292,7 @@ export const Payload: React.FunctionComponent = ({ )} {schema.pattern() && ( - + must match:{' '} {schema.pattern()} @@ -300,7 +300,7 @@ export const Payload: React.FunctionComponent = ({ )} {schema.contentEncoding() !== undefined && ( - + encoding:{' '} {schema.contentEncoding()} @@ -310,7 +310,7 @@ export const Payload: React.FunctionComponent = ({ {constraints.map((constraint) => ( {constraint} diff --git a/playground/app/page.tsx b/playground/app/page.tsx index d66e21c6d..651a2f078 100644 --- a/playground/app/page.tsx +++ b/playground/app/page.tsx @@ -19,6 +19,7 @@ import * as specs from '@/specs'; // const defaultSchema = specs.streetlights; const defaultSchema = specs.overcomplicatedStreetlights; +// const defaultSchema = specs.complexSchema; interface State { schema: string; diff --git a/playground/specs/complex-schema.ts b/playground/specs/complex-schema.ts new file mode 100644 index 000000000..9f4196367 --- /dev/null +++ b/playground/specs/complex-schema.ts @@ -0,0 +1,253 @@ +export const complexSchema = ` +asyncapi: 3.0.0 +info: + title: Complex Schema Demo API + version: 1.0.0 + description: Demonstrates various schema combinations and corner cases + contact: + name: API Support + email: support@example.com + url: 'https://example.com/support' + license: + name: Apache 2.0 + url: 'https://www.apache.org/licenses/LICENSE-2.0' +servers: + production: + host: broker.example.com + protocol: mqtt + description: Production MQTT Broker + security: + - $ref: '#/components/securitySchemes/userPassword' + bindings: + mqtt: + clientId: demo-client + cleanSession: true + keepAlive: 60 + bindingVersion: 0.2.0 +channels: + user/events: + address: user/events + messages: + publishUserEvent.message: + name: UserEvent + title: User Event Message + contentType: application/json + correlationId: + location: $message.header#/correlationId + headers: + type: object + properties: + correlationId: + type: string + format: uuid + payload: + $ref: '#/components/schemas/ComplexUserPayload' + traits: + - $ref: '#/components/messageTraits/CommonHeaders' + receiveUserEvent.message: + $ref: '#/components/messages/UserEventMessage' +operations: + publishUserEvent: + action: receive + channel: + $ref: '#/channels/user~1events' + summary: User-related events + messages: + - $ref: '#/channels/user~1events/messages/publishUserEvent.message' + receiveUserEvent: + action: send + channel: + $ref: '#/channels/user~1events' + summary: Receive user events + messages: + - $ref: '#/channels/user~1events/messages/receiveUserEvent.message' +components: + schemas: + ComplexUserPayload: + type: object + properties: + id: + type: string + format: uuid + basicTypes: + type: object + properties: + stringField: + type: string + minLength: 1 + maxLength: 100 + pattern: '^[A-Za-z0-9]+$' + integerField: + type: integer + minimum: 0 + maximum: 1000 + multipleOf: 5 + numberField: + type: number + format: float + exclusiveMinimum: 0 + exclusiveMaximum: 100 + booleanField: + type: boolean + nullableField: + type: + - string + - 'null' + enumField: + type: string + enum: + - PENDING + - ACTIVE + - SUSPENDED + arrays: + type: object + properties: + simpleArray: + type: array + items: + type: string + minItems: 1 + maxItems: 10 + uniqueItems: true + tupleArray: + type: array + items: + - type: string + - type: integer + - type: boolean + additionalItems: false + complexArray: + type: array + items: + type: object + properties: + name: + type: string + value: + type: integer + conditionalLogic: + type: object + if: + properties: + userType: + const: premium + then: + properties: + features: + type: array + items: + type: string + minItems: 3 + else: + properties: + features: + type: array + items: + type: string + maxItems: 2 + oneOfExample: + oneOf: + - type: object + properties: + type: + const: personal + personalEmail: + type: string + format: email + - type: object + properties: + type: + const: business + companyEmail: + type: string + format: email + department: + type: string + anyOfExample: + anyOf: + - type: object + properties: + phone: + type: string + pattern: '^\+[1-9]\d{1,14}$' + - type: object + properties: + email: + type: string + format: email + allOfExample: + allOf: + - type: object + properties: + baseField: + type: string + - type: object + properties: + extendedField: + type: integer + notExample: + not: + type: object + properties: + restricted: + const: true + dateTimeFields: + type: object + properties: + created: + type: string + format: date-time + date: + type: string + format: date + time: + type: string + format: time + additionalProperties: + type: object + additionalProperties: + type: string + patternProperties: + type: object + patternProperties: + '^[A-Z][a-z]+$': + type: string + dependencies: + type: object + dependencies: + creditCard: + required: + - billingAddress + required: + - id + - basicTypes + - arrays + messageTraits: + CommonHeaders: + headers: + type: object + properties: + messageId: + type: string + format: uuid + timestamp: + type: string + format: date-time + version: + type: string + required: + - messageId + - timestamp + messages: + UserEventMessage: + name: UserEvent + title: User Event Message + summary: A message containing user event information + contentType: application/json + payload: + $ref: '#/components/schemas/ComplexUserPayload' + securitySchemes: + userPassword: + type: userPassword + description: Basic user/password authentication +`; diff --git a/playground/specs/index.ts b/playground/specs/index.ts index 63fd02f77..f4d2bb114 100644 --- a/playground/specs/index.ts +++ b/playground/specs/index.ts @@ -11,4 +11,5 @@ export * from './rpc-client'; export * from './rpc-server'; export * from './slack-rtm'; export * from './streetlights'; -export * from './overcomplicated-streetlight'; \ No newline at end of file +export * from './overcomplicated-streetlight'; +export * from './complex-schema' \ No newline at end of file From c4c649863722880ffc747b629dc11aea04480fb9 Mon Sep 17 00:00:00 2001 From: catosaurusrex2003 Date: Mon, 27 Jan 2025 21:24:18 +0530 Subject: [PATCH 19/41] conditions sidebar --- library/src/components/Payload/Payload.tsx | 582 +++++++++++++-------- library/src/containers/AsyncApi/Layout.tsx | 41 +- library/src/contexts/conditionsSidebar.tsx | 30 ++ 3 files changed, 414 insertions(+), 239 deletions(-) create mode 100644 library/src/contexts/conditionsSidebar.tsx diff --git a/library/src/components/Payload/Payload.tsx b/library/src/components/Payload/Payload.tsx index 0b68681d6..20a0ac099 100644 --- a/library/src/components/Payload/Payload.tsx +++ b/library/src/components/Payload/Payload.tsx @@ -1,8 +1,21 @@ -import React, { useState, useEffect, useContext } from 'react'; +import React, { + useState, + useEffect, + useContext, + useRef, + useLayoutEffect, +} from 'react'; import { SchemaInterface } from '@asyncapi/parser'; -import { Href, CollapseButton, Markdown, Extensions } from '../index'; +import { + Href, + CollapseButton, + Markdown, + Extensions, + HiChevronRight, +} from '../index'; import { SchemaHelpers } from '../../helpers'; +import { useSidebarContext } from '../../contexts/conditionsSidebar'; interface Props { schemaName?: React.ReactNode; @@ -16,6 +29,8 @@ interface Props { expanded?: boolean; onlyTitle?: boolean; isArray?: boolean; + showConditionSidebar?: boolean; + recursionCounter?: number; } const PayloadSchemaContext = React.createContext({ @@ -35,12 +50,19 @@ export const Payload: React.FunctionComponent = ({ expanded: propExpanded = false, onlyTitle = false, isArray = false, + recursionCounter = 0, // eslint-disable-next-line sonarjs/cognitive-complexity }) => { const { reverse, deepExpanded } = useContext(PayloadSchemaContext); const [expanded, setExpanded] = useState(propExpanded || isArray); const [deepExpand, setDeepExpand] = useState(false); const [tabOpen, setTabOpen] = useState<'Rules' | 'Conditions'>('Rules'); + const { conditionsSidebarOpen, toggleSidebar } = useSidebarContext(); + const [conditionsHeight, setConditionsHeight] = useState(0); + const conditionsDivRef = useRef(null); + + const floatConditionsToRight = + isProperty && recursionCounter == 2 && conditionsSidebarOpen; useEffect(() => { if (!isArray) { @@ -48,6 +70,10 @@ export const Payload: React.FunctionComponent = ({ } }, [isArray, deepExpanded, setDeepExpand]); + // useEffect(() => { + // setConditionsSidebarOpen(showConditionsSidebar); + // }, [showConditionsSidebar, conditionsSidebarOpen, setConditionsSidebarOpen]); + useEffect(() => { if (!isArray) { setExpanded(deepExpand); @@ -58,6 +84,29 @@ export const Payload: React.FunctionComponent = ({ setTabOpen(showRules ? 'Rules' : 'Conditions'); }, [schema]); + useEffect(() => { + setTimeout(() => { + console.log('conditionsDivRef.current ', conditionsDivRef.current); + if (conditionsDivRef.current) { + console.log( + 'height ', + schemaName, + ' ', + conditionsDivRef.current.getBoundingClientRect().height, + ); + setConditionsHeight( + conditionsDivRef.current.getBoundingClientRect().height, + ); + } + }, 500); + }, []); + // useLayoutEffect(() => { + // if (conditionsDivRef.current) { + // console.log("height ",schemaName , " ", conditionsDivRef.current.getBoundingClientRect().height) + // setConditionsHeight(conditionsDivRef.current.getBoundingClientRect().height); + // } + // }, []); + if ( !schema || (typeof schemaName === 'string' && @@ -124,226 +173,260 @@ export const Payload: React.FunctionComponent = ({ return ( -
- {/* Header Section */} -
-
-
- {isExpandable && !isCircular && !isArray ? ( -
- setExpanded((prev) => !prev)} - expanded={expanded} - > - {renderedSchemaName} - -
- ) : ( - - {schemaName} - - )} - - {isCircular ? `${schemaType} [CIRCULAR]` : schemaType} - - {schema.contentMediaType() !== undefined && ( - - media type: {schema.contentMediaType()} - - )} - {uid && !uid.startsWith(' - uid: {uid} +
+
+ {/* Header Section */} +
+
+
+ {isExpandable && !isCircular && !isArray ? ( + // TODO: make this sticky +
+ setExpanded((prev) => !prev)} + expanded={expanded} + > + {renderedSchemaName} + +
+ ) : ( + + {schemaName} + + )} + + {isCircular ? `${schemaType} [CIRCULAR]` : schemaType} - )} - {/* TODO: find out if below is really needed ?? + {schema.contentMediaType() !== undefined && ( + + media type: {schema.contentMediaType()} + + )} + {uid && !uid.startsWith(' + uid: {uid} + + )} + {/* TODO: find out if below is really needed ?? cuz schema.const() is already shown in a strict manner in Rules */} - {/* {SchemaHelpers.prettifyValue(schema.const(), false) && ( + {/* {SchemaHelpers.prettifyValue(schema.const(), false) && ( {SchemaHelpers.prettifyValue(schema.const(), false)} )} */} - {/* Field Status Indicators */} - {(required || - schema.deprecated() || - schema.writeOnly() || - schema.readOnly() || - isPatternProperty) && ( -
- {required && ( - - required - - )} - {schema.deprecated() && ( - - deprecated - - )} - {isPatternProperty && ( -
- (pattern property) -
- )} - {schema.writeOnly() && ( - - write-only - + {/* Field Status Indicators */} + {(required || + schema.deprecated() || + schema.writeOnly() || + schema.readOnly() || + isPatternProperty) && ( +
+ {required && ( + + required + + )} + {schema.deprecated() && ( + + deprecated + + )} + {isPatternProperty && ( +
+ (pattern property) +
+ )} + {schema.writeOnly() && ( + + write-only + + )} + {schema.readOnly() && ( + + read-only + + )} +
+ )} + +
+ {isExpandable && !isCircular && !isArray && ( + )} - {schema.readOnly() && ( - - read-only - + {recursionCounter == 0 && ( + )}
- )} +
+
- {isExpandable && !isCircular && !isArray && ( - - )} -
+ Documentation + + + )}
- {/* Description */} - {schema.description() && ( -
- {schema.description()} -
- )} - {schema.examples() && ( -
    - Examples values:{' '} - {schema.examples()?.map((e, idx) => ( -
  • - {SchemaHelpers.prettifyValue(e)} -
  • - ))} -
- )} - {parameterLocation && ( -
- Parameter location:{' '} - - {parameterLocation} - -
- )} - {externalDocs && ( - - +
- Documentation - - - )} -
- - {/* Expandable Content */} - {!isCircular && isExpandable && expanded && ( -
-
- {showRules && ( - - )} - {showConditions && ( - - )} -
- {/* Rules Section: it generally doesnt have any recursion in it */} - {showRules && tabOpen == 'Rules' && ( -
-
- {schema.format() && ( - - format:{' '} - - {schema.format()} - - - )} - {schema.pattern() && ( - - must match:{' '} - - {schema.pattern()} - - - )} - {schema.contentEncoding() !== undefined && ( - - encoding:{' '} - - {schema.contentEncoding()} - - - )} - {constraints.map((constraint) => ( - - {constraint} - - ))} - {schema.const() !== undefined && ( -
- Constant value: - - {SchemaHelpers.prettifyValue(schema.const())} - -
- )} - {schema.enum() && ( -
- Allowed values: - {schema.enum()?.map((e, idx) => ( - - {SchemaHelpers.prettifyValue(e)} + {showRules && ( + + )} + {/* {showConditions && ( + + )} */} +
+
+ {/* Rules Section: it generally doesnt have any recursion in it */} + {showRules && tabOpen == 'Rules' && ( +
+
+ {schema.format() && ( + + format:{' '} + + {schema.format()} + + + )} + {schema.pattern() && ( + + must match:{' '} + + {schema.pattern()} + + )} + {schema.contentEncoding() !== undefined && ( + + encoding:{' '} + + {schema.contentEncoding()} + + + )} + {constraints.map((constraint) => ( + + {constraint} + ))} + {schema.const() !== undefined && ( +
+ Constant value: + + {SchemaHelpers.prettifyValue(schema.const())} + +
+ )} + {schema.enum() && ( +
+ Allowed values: + {schema.enum()?.map((e, idx) => ( + + {SchemaHelpers.prettifyValue(e)} + + ))} +
+ )}
- )} -
-
- )} - - {/* Conditions Section: has hella recursion in it*/} - {showConditions && tabOpen == 'Conditions' && ( -
-
+
+ )} + + {/* Conditions Section: has hella recursion in it*/} + {/* {showConditions && tabOpen == 'Conditions' && ( */} +
{schema.oneOf()?.length && (
@@ -361,6 +444,7 @@ export const Payload: React.FunctionComponent = ({ '', s.title() ?? s.id(), )} + recursionCounter={recursionCounter + 1} /> ))}
@@ -383,6 +467,7 @@ export const Payload: React.FunctionComponent = ({ '', s.title() ?? s.id(), )} + recursionCounter={recursionCounter + 1} /> ))}
@@ -405,6 +490,7 @@ export const Payload: React.FunctionComponent = ({ '', s.title() ?? s.id(), )} + recursionCounter={recursionCounter + 1} /> ))}
@@ -414,6 +500,7 @@ export const Payload: React.FunctionComponent = ({ )} @@ -421,6 +508,7 @@ export const Payload: React.FunctionComponent = ({ )} @@ -428,6 +516,7 @@ export const Payload: React.FunctionComponent = ({ )} @@ -435,41 +524,68 @@ export const Payload: React.FunctionComponent = ({ )} {schema.then() && ( )} {schema.else() && ( - + )} {dependentSchemas && ( )}
+ {/* )} */}
- )} - - {/* Properties Section */} - - {/* Array Items Section */} - + {/* Properties Section */} + + + {/* Array Items Section */} + + + {/* Additional Properties/Items Section */} +
+ + +
- {/* Additional Properties/Items Section */} -
- - + {/* Extensions Section */} +
+ )} +
- {/* Extensions Section */} - + {/* right side conditions sidebar */} + {conditionsSidebarOpen && recursionCounter == 0 && ( +
+ Conditions Sidebar
)}
@@ -479,10 +595,12 @@ export const Payload: React.FunctionComponent = ({ interface SchemaPropertiesProps { schema: SchemaInterface; + recursionCounter?: number; } const SchemaProperties: React.FunctionComponent = ({ schema, + recursionCounter = 0, }) => { const properties = schema.properties(); if (properties === undefined || !Object.keys(properties)) { @@ -506,6 +624,7 @@ const SchemaProperties: React.FunctionComponent = ({ schema, )} key={propertyName} + recursionCounter={recursionCounter + 1} /> ))} {Object.entries(patternProperties ?? {}).map( @@ -517,6 +636,7 @@ const SchemaProperties: React.FunctionComponent = ({ isProperty isCircular={property.isCircular()} key={propertyName} + recursionCounter={recursionCounter + 1} /> ), )} @@ -526,11 +646,12 @@ const SchemaProperties: React.FunctionComponent = ({ interface AdditionalPropertiesProps { schema: SchemaInterface; + recursionCounter?: number; } const AdditionalProperties: React.FunctionComponent< AdditionalPropertiesProps -> = ({ schema }) => { +> = ({ schema, recursionCounter = 0 }) => { if ( schema.extensions().get(SchemaHelpers.extRenderAdditionalInfo)?.value() === false @@ -562,15 +683,20 @@ const AdditionalProperties: React.FunctionComponent< ); }; interface SchemaItemsProps { schema: SchemaInterface; + recursionCounter?: number; } -const SchemaItems: React.FunctionComponent = ({ schema }) => { +const SchemaItems: React.FunctionComponent = ({ + schema, + recursionCounter = 0, +}) => { const type = schema.type(); if (!type?.includes('array')) { return null; @@ -594,20 +720,30 @@ const SchemaItems: React.FunctionComponent = ({ schema }) => { isArray schemaName={`${idx + 1} item:`} key={idx} + recursionCounter={recursionCounter + 1} /> ))} ); } - return ; + return ( + + ); }; interface AdditionalItemsProps { schema: SchemaInterface; + recursionCounter?: number; } const AdditionalItems: React.FunctionComponent = ({ schema, + recursionCounter = 0, }) => { if ( schema.extensions().get(SchemaHelpers.extRenderAdditionalInfo)?.value() === @@ -641,5 +777,11 @@ const AdditionalItems: React.FunctionComponent = ({ ); } // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment - return ; + return ( + + ); }; diff --git a/library/src/containers/AsyncApi/Layout.tsx b/library/src/containers/AsyncApi/Layout.tsx index b6105b392..a21ab6ecc 100644 --- a/library/src/containers/AsyncApi/Layout.tsx +++ b/library/src/containers/AsyncApi/Layout.tsx @@ -12,6 +12,7 @@ import { Schemas } from '../Schemas/Schemas'; import { ConfigInterface } from '../../config'; import { SpecificationContext, ConfigContext } from '../../contexts'; import AsyncApiErrorBoundary from '../ApplicationErrorHandler/ErrorBoundary'; +import { SidebarProvider } from '../../contexts/conditionsSidebar'; interface Props { asyncapi: AsyncAPIDocumentInterface; @@ -44,27 +45,29 @@ const AsyncApiLayout: React.FunctionComponent = ({ return ( -
- -
- {configShow.sidebar && } -
-
- {configShow.info && } - {configShow.servers && } - {configShow.operations && } - {configShow.messages && } - {configShow.schemas && } + +
+ +
+ {configShow.sidebar && } +
+
+ {configShow.info && } + {configShow.servers && } + {configShow.operations && } + {configShow.messages && } + {configShow.schemas && } +
+
-
-
- -
+ +
+
); diff --git a/library/src/contexts/conditionsSidebar.tsx b/library/src/contexts/conditionsSidebar.tsx new file mode 100644 index 000000000..9b5650a64 --- /dev/null +++ b/library/src/contexts/conditionsSidebar.tsx @@ -0,0 +1,30 @@ +import React, { createContext, useState, useContext, ReactNode } from 'react'; + +interface SidebarContextType { + conditionsSidebarOpen: boolean; + toggleSidebar: () => void; +} + +const SidebarContext = createContext(undefined); + +export const SidebarProvider = ({ children }: { children: ReactNode }) => { + const [conditionsSidebarOpen, setConditionsSidebarOpen] = + useState(false); + + const toggleSidebar = () => setConditionsSidebarOpen((prev) => !prev); + + return ( + + {children} + + ); +}; + +// Custom hook +export const useSidebarContext = (): SidebarContextType => { + const context = useContext(SidebarContext); + if (!context) { + throw new Error('useSidebarContext must be used within a SidebarProvider'); + } + return context; +}; From f79c77f19a41c696516d44d5988a61b15cee9ce2 Mon Sep 17 00:00:00 2001 From: catosaurusrex2003 Date: Tue, 28 Jan 2025 23:35:58 +0530 Subject: [PATCH 20/41] rules and conditions side by side now with height adjusting --- library/src/components/Payload/Payload.tsx | 368 ++++++++++----------- library/src/hooks/useElementSize.tsx | 47 +++ 2 files changed, 215 insertions(+), 200 deletions(-) create mode 100644 library/src/hooks/useElementSize.tsx diff --git a/library/src/components/Payload/Payload.tsx b/library/src/components/Payload/Payload.tsx index 20a0ac099..6db1c00ec 100644 --- a/library/src/components/Payload/Payload.tsx +++ b/library/src/components/Payload/Payload.tsx @@ -2,8 +2,6 @@ import React, { useState, useEffect, useContext, - useRef, - useLayoutEffect, } from 'react'; import { SchemaInterface } from '@asyncapi/parser'; @@ -16,6 +14,7 @@ import { } from '../index'; import { SchemaHelpers } from '../../helpers'; import { useSidebarContext } from '../../contexts/conditionsSidebar'; +import { useElementSize } from '../../hooks/useElementSize'; interface Props { schemaName?: React.ReactNode; @@ -58,8 +57,8 @@ export const Payload: React.FunctionComponent = ({ const [deepExpand, setDeepExpand] = useState(false); const [tabOpen, setTabOpen] = useState<'Rules' | 'Conditions'>('Rules'); const { conditionsSidebarOpen, toggleSidebar } = useSidebarContext(); - const [conditionsHeight, setConditionsHeight] = useState(0); - const conditionsDivRef = useRef(null); + const [setConditionsRef, conditionsSize] = useElementSize(); + const [setRulesRef, rulesSize] = useElementSize(); const floatConditionsToRight = isProperty && recursionCounter == 2 && conditionsSidebarOpen; @@ -70,10 +69,6 @@ export const Payload: React.FunctionComponent = ({ } }, [isArray, deepExpanded, setDeepExpand]); - // useEffect(() => { - // setConditionsSidebarOpen(showConditionsSidebar); - // }, [showConditionsSidebar, conditionsSidebarOpen, setConditionsSidebarOpen]); - useEffect(() => { if (!isArray) { setExpanded(deepExpand); @@ -84,29 +79,6 @@ export const Payload: React.FunctionComponent = ({ setTabOpen(showRules ? 'Rules' : 'Conditions'); }, [schema]); - useEffect(() => { - setTimeout(() => { - console.log('conditionsDivRef.current ', conditionsDivRef.current); - if (conditionsDivRef.current) { - console.log( - 'height ', - schemaName, - ' ', - conditionsDivRef.current.getBoundingClientRect().height, - ); - setConditionsHeight( - conditionsDivRef.current.getBoundingClientRect().height, - ); - } - }, 500); - }, []); - // useLayoutEffect(() => { - // if (conditionsDivRef.current) { - // console.log("height ",schemaName , " ", conditionsDivRef.current.getBoundingClientRect().height) - // setConditionsHeight(conditionsDivRef.current.getBoundingClientRect().height); - // } - // }, []); - if ( !schema || (typeof schemaName === 'string' && @@ -180,7 +152,7 @@ export const Payload: React.FunctionComponent = ({ >
{/* Header Section */}
@@ -215,12 +187,14 @@ export const Payload: React.FunctionComponent = ({ )} {/* TODO: find out if below is really needed ?? - cuz schema.const() is already shown in a strict manner in Rules */} - {/* {SchemaHelpers.prettifyValue(schema.const(), false) && ( - - {SchemaHelpers.prettifyValue(schema.const(), false)} - - )} */} + cuz schema.const() is already shown in a strict manner in Rules */} + {/* + {SchemaHelpers.prettifyValue(schema.const(), false) && ( + + {SchemaHelpers.prettifyValue(schema.const(), false)} + + )} + */} {/* Field Status Indicators */} {(required || @@ -271,12 +245,14 @@ export const Payload: React.FunctionComponent = ({ @@ -326,38 +302,21 @@ export const Payload: React.FunctionComponent = ({ {/* Expandable Content */} {!isCircular && isExpandable && expanded && ( -
+
- {showRules && ( - - )} - {/* {showConditions && ( - - )} */} -
-
{/* Rules Section: it generally doesnt have any recursion in it */} {showRules && tabOpen == 'Rules' && ( -
+
+

+ Rules +

{schema.format() && ( @@ -417,139 +376,150 @@ export const Payload: React.FunctionComponent = ({ )} {/* Conditions Section: has hella recursion in it*/} - {/* {showConditions && tabOpen == 'Conditions' && ( */} -
- {schema.oneOf()?.length && ( -
-
- Can be One Of the following: -
- {schema - .oneOf() - ?.map((s, idx) => ( - - ))} -
- )} + {showConditions && ( +
+

+ Conditions +

+
+ {schema.oneOf()?.length && ( +
+
+ Can be One Of the following: +
+ {schema + .oneOf() + ?.map((s, idx) => ( + + ))} +
+ )} - {schema.anyOf()?.length && ( -
-
- Can be Any Of the following: -
- {schema - .anyOf() - ?.map((s, idx) => ( - - ))} -
- )} + {schema.anyOf()?.length && ( +
+
+ Can be Any Of the following: +
+ {schema + .anyOf() + ?.map((s, idx) => ( + + ))} +
+ )} - {schema.allOf()?.length && ( -
-
- Must consist All Of the following: -
- {schema - .allOf() - ?.map((s, idx) => ( - - ))} -
- )} + {schema.allOf()?.length && ( +
+
+ Must consist All Of the following: +
+ {schema + .allOf() + ?.map((s, idx) => ( + + ))} +
+ )} - {schema.not() && ( - - )} + {schema.not() && ( + + )} - {schema.propertyNames() && ( - - )} + {schema.propertyNames() && ( + + )} - {schema.contains() && ( - - )} + {schema.contains() && ( + + )} - {schema.if() && ( - - )} - {schema.then() && ( - - )} - {schema.else() && ( - - )} - {dependentSchemas && ( - - )} -
- {/* )} */} + {schema.if() && ( + + )} + {schema.then() && ( + + )} + {schema.else() && ( + + )} + {dependentSchemas && ( + + )} +
+
+ )}
{/* Properties Section */} @@ -583,10 +553,8 @@ export const Payload: React.FunctionComponent = ({
{/* right side conditions sidebar */} - {conditionsSidebarOpen && recursionCounter == 0 && ( -
- Conditions Sidebar -
+ {expanded && conditionsSidebarOpen && recursionCounter == 0 && ( +
)}
diff --git a/library/src/hooks/useElementSize.tsx b/library/src/hooks/useElementSize.tsx new file mode 100644 index 000000000..e49d6bfda --- /dev/null +++ b/library/src/hooks/useElementSize.tsx @@ -0,0 +1,47 @@ +import { useCallback, useEffect, useLayoutEffect, useState } from 'react'; +export interface Size { + width: number; + height: number; +} + +/** + * `useElementSize` is a hook to measure the size of a DOM element. + * It tracks the width and height of the element and updates them on window resize or element changes. + * + * @param ref - The React ref object attached to the element to measure. + * @return - An object containing the `width` and `height` of the element. + */ + +function useElementSize(): [ + (node: T | null) => void, + Size, +] { + const [ref, setRef] = useState(null); + const [size, setSize] = useState({ width: 0, height: 0 }); + + const handleSize = useCallback(() => { + if (ref) { + setSize({ + width: ref.offsetWidth, + height: ref.offsetHeight, + }); + } + }, [ref]); + + const useEnviromentEffect = typeof window !== 'undefined' ? useLayoutEffect : useEffect; + + useEnviromentEffect(() => { + if (!ref) return; + + handleSize(); + + const resizeObserver = new ResizeObserver(handleSize); + resizeObserver.observe(ref); + + return () => resizeObserver.disconnect(); + }, [ref, handleSize]); + + return [setRef, size]; +} + +export { useElementSize }; \ No newline at end of file From a9a9e130839d64112f1a0ad20f08b8b232a4929c Mon Sep 17 00:00:00 2001 From: catosaurusrex2003 Date: Fri, 31 Jan 2025 20:43:49 +0530 Subject: [PATCH 21/41] fixed conditionsRightShift bug, completely replaced Schema with Payload, split stuff into seperate components --- library/src/components/Extensions.tsx | 9 +- .../components/Payload/AdditionalItems.tsx | 54 ++ .../Payload/AdditionalProperties.tsx | 48 ++ .../Payload/Conditions/Conditions.tsx | 149 ++++++ .../Payload/FeildStatusIndicators.tsx | 46 ++ library/src/components/Payload/Payload.tsx | 502 ++---------------- .../src/components/Payload/Rules/Rules.tsx | 83 +++ .../src/components/Payload/SchemaItems.tsx | 50 ++ .../components/Payload/SchemaProperties.tsx | 55 ++ library/src/components/Schema.tsx | 5 +- library/src/containers/Messages/Message.tsx | 4 +- playground/app/page.tsx | 4 +- playground/utils/defaultConfig.ts | 9 +- 13 files changed, 559 insertions(+), 459 deletions(-) create mode 100644 library/src/components/Payload/AdditionalItems.tsx create mode 100644 library/src/components/Payload/AdditionalProperties.tsx create mode 100644 library/src/components/Payload/Conditions/Conditions.tsx create mode 100644 library/src/components/Payload/FeildStatusIndicators.tsx create mode 100644 library/src/components/Payload/Rules/Rules.tsx create mode 100644 library/src/components/Payload/SchemaItems.tsx create mode 100644 library/src/components/Payload/SchemaProperties.tsx diff --git a/library/src/components/Extensions.tsx b/library/src/components/Extensions.tsx index b98d44c00..cc6613f5c 100644 --- a/library/src/components/Extensions.tsx +++ b/library/src/components/Extensions.tsx @@ -11,11 +11,13 @@ interface Props { name?: string; // eslint-disable-next-line @typescript-eslint/no-explicit-any item: any; + recursionCounter?: number; } export const Extensions: React.FunctionComponent = ({ name = 'Extensions', item, + recursionCounter = 0, }) => { const extensions = SchemaHelpers.getCustomExtensions(item); if (!extensions || !Object.keys(extensions).length) { @@ -27,7 +29,12 @@ export const Extensions: React.FunctionComponent = ({ return ( schema && (
- +
) ); diff --git a/library/src/components/Payload/AdditionalItems.tsx b/library/src/components/Payload/AdditionalItems.tsx new file mode 100644 index 000000000..f60c7bab4 --- /dev/null +++ b/library/src/components/Payload/AdditionalItems.tsx @@ -0,0 +1,54 @@ +import React from 'react'; +import { SchemaInterface } from '@asyncapi/parser'; +import { SchemaHelpers } from '../../helpers'; +import { Payload } from './Payload'; + +interface AdditionalItemsProps { + schema: SchemaInterface; + recursionCounter?: number; +} + +export const AdditionalItems: React.FunctionComponent = ({ + schema, + recursionCounter = 0, +}) => { + if ( + schema.extensions().get(SchemaHelpers.extRenderAdditionalInfo)?.value() === + false + ) { + return null; + } + + const type = schema.type(); + if (!type?.includes('array')) { + return null; + } + if (!Array.isArray(schema.items())) { + return null; + } + + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-explicit-any + const additionalItems = schema.additionalItems() as any; + if (additionalItems === true || additionalItems === undefined) { + return ( +

+ Additional items are allowed. +

+ ); + } + if (additionalItems === false) { + return ( +

+ Additional items are NOT allowed. +

+ ); + } + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + return ( + + ); +}; diff --git a/library/src/components/Payload/AdditionalProperties.tsx b/library/src/components/Payload/AdditionalProperties.tsx new file mode 100644 index 000000000..f48c5f88f --- /dev/null +++ b/library/src/components/Payload/AdditionalProperties.tsx @@ -0,0 +1,48 @@ +import React from 'react'; +import { SchemaInterface } from '@asyncapi/parser'; +import { SchemaHelpers } from '../../helpers'; +import { Payload } from './Payload'; + +interface AdditionalPropertiesProps { + schema: SchemaInterface; + recursionCounter?: number; +} + +export const AdditionalProperties: React.FunctionComponent< + AdditionalPropertiesProps +> = ({ schema, recursionCounter = 0 }) => { + if ( + schema.extensions().get(SchemaHelpers.extRenderAdditionalInfo)?.value() === + false + ) { + return null; + } + + const type = schema.type(); + if (!type?.includes('object')) { + return null; + } + + const additionalProperties = schema.additionalProperties(); + if (additionalProperties === true || additionalProperties === undefined) { + return ( +

+ Additional properties are allowed. +

+ ); + } + if (additionalProperties === false) { + return ( +

+ Additional properties are NOT allowed. +

+ ); + } + return ( + + ); +}; diff --git a/library/src/components/Payload/Conditions/Conditions.tsx b/library/src/components/Payload/Conditions/Conditions.tsx new file mode 100644 index 000000000..a86990f9d --- /dev/null +++ b/library/src/components/Payload/Conditions/Conditions.tsx @@ -0,0 +1,149 @@ +import React from 'react'; +import { SchemaInterface } from '@asyncapi/parser'; +import { Payload } from '../Payload'; +import { SchemaHelpers } from '../../../helpers'; + +interface ConditionsProps { + schema: SchemaInterface; + recursionCounter?: number; + dependentSchemas?: SchemaInterface +} + +export const Conditions = ({ + schema, + recursionCounter = 0, + dependentSchemas +}: ConditionsProps) => { + return ( + <> +

+ Conditions +

+
+ {schema.oneOf()?.length && ( +
+
+ Can be One Of the following: +
+ {schema + .oneOf() + ?.map((s, idx) => ( + + ))} +
+ )} + + {schema.anyOf()?.length && ( +
+
+ Can be Any Of the following: +
+ {schema + .anyOf() + ?.map((s, idx) => ( + + ))} +
+ )} + + {schema.allOf()?.length && ( +
+
+ Must consist All Of the following: +
+ {schema + .allOf() + ?.map((s, idx) => ( + + ))} +
+ )} + + {schema.not() && ( + + )} + + {schema.propertyNames() && ( + + )} + + {schema.contains() && ( + + )} + + {schema.if() && ( + + )} + {schema.then() && ( + + )} + {schema.else() && ( + + )} + {dependentSchemas && ( + + )} +
+ + ); +}; diff --git a/library/src/components/Payload/FeildStatusIndicators.tsx b/library/src/components/Payload/FeildStatusIndicators.tsx new file mode 100644 index 000000000..616b64313 --- /dev/null +++ b/library/src/components/Payload/FeildStatusIndicators.tsx @@ -0,0 +1,46 @@ +import React from 'react'; +import { SchemaInterface } from '@asyncapi/parser'; + +interface FeildStatusIndicatorProps { + schema: SchemaInterface; + required?: boolean; + isPatternProperty?: boolean; +} + +export const FeildStatusIndicator = ({ + schema, + required = false, + isPatternProperty +}: FeildStatusIndicatorProps) => { + return ( + <> + {(required || + schema.deprecated() || + schema.writeOnly() || + schema.readOnly() || + isPatternProperty) && ( +
+ {required && ( + required + )} + {schema.deprecated() && ( + + deprecated + + )} + {isPatternProperty && ( +
+ (pattern property) +
+ )} + {schema.writeOnly() && ( + write-only + )} + {schema.readOnly() && ( + read-only + )} +
+ )} + + ); +}; diff --git a/library/src/components/Payload/Payload.tsx b/library/src/components/Payload/Payload.tsx index 6db1c00ec..0ee3375d6 100644 --- a/library/src/components/Payload/Payload.tsx +++ b/library/src/components/Payload/Payload.tsx @@ -1,8 +1,4 @@ -import React, { - useState, - useEffect, - useContext, -} from 'react'; +import React, { useState, useEffect, useContext } from 'react'; import { SchemaInterface } from '@asyncapi/parser'; import { @@ -15,6 +11,13 @@ import { import { SchemaHelpers } from '../../helpers'; import { useSidebarContext } from '../../contexts/conditionsSidebar'; import { useElementSize } from '../../hooks/useElementSize'; +import { SchemaItems } from './SchemaItems'; +import { AdditionalItems } from './AdditionalItems'; +import { SchemaProperties } from './SchemaProperties'; +import { AdditionalProperties } from './AdditionalProperties'; +import { Conditions } from './Conditions/Conditions'; +import { Rules } from './Rules/Rules'; +import { FeildStatusIndicator } from './FeildStatusIndicators'; interface Props { schemaName?: React.ReactNode; @@ -55,13 +58,12 @@ export const Payload: React.FunctionComponent = ({ const { reverse, deepExpanded } = useContext(PayloadSchemaContext); const [expanded, setExpanded] = useState(propExpanded || isArray); const [deepExpand, setDeepExpand] = useState(false); - const [tabOpen, setTabOpen] = useState<'Rules' | 'Conditions'>('Rules'); const { conditionsSidebarOpen, toggleSidebar } = useSidebarContext(); const [setConditionsRef, conditionsSize] = useElementSize(); const [setRulesRef, rulesSize] = useElementSize(); const floatConditionsToRight = - isProperty && recursionCounter == 2 && conditionsSidebarOpen; + isProperty && recursionCounter >= 2 && conditionsSidebarOpen; useEffect(() => { if (!isArray) { @@ -75,10 +77,6 @@ export const Payload: React.FunctionComponent = ({ } }, [isArray, deepExpand, setExpanded]); - useEffect(() => { - setTabOpen(showRules ? 'Rules' : 'Conditions'); - }, [schema]); - if ( !schema || (typeof schemaName === 'string' && @@ -118,16 +116,17 @@ export const Payload: React.FunctionComponent = ({ ); // comes in Rules section - const showRules = + const rulesExist = schema.format() || schema.pattern() || constraints.length > 0 || schema.contentEncoding() || schema.enum() || + schema.default() !== undefined || schema.const() !== undefined; // comes in Conditions section - const showConditions = + const conditionsExist = schema.oneOf()?.length || schema.anyOf()?.length || schema.allOf()?.length || @@ -141,7 +140,16 @@ export const Payload: React.FunctionComponent = ({ // we want the expanding dropdown to be present if schema has got other stuff, rules or conditions const isExpandable = - SchemaHelpers.isExpandable(schema) || showRules || showConditions; + SchemaHelpers.isExpandable(schema) || rulesExist || conditionsExist; + + // TODO: check recursiveley to see if any of the children have any conditions present in them. + // this is neccesary to conditionally render the conditions sidebar toggle button + // will need some functions in SchemaHelpers something like jsonFieldToSchema or something + const childrenHaveConditions = true; // hardcoding for now + + // this is the ammount of shift it needs to be moved to the right in px + // by absolute when the components gets nested a lot + const conditionsRightShift = 30 + 10 * (recursionCounter - 1); return ( = ({ )} {/* TODO: find out if below is really needed ?? - cuz schema.const() is already shown in a strict manner in Rules */} + cuz schema.const() is already shown in a strict manner in Rules */} {/* {SchemaHelpers.prettifyValue(schema.const(), false) && ( @@ -197,39 +205,11 @@ export const Payload: React.FunctionComponent = ({ */} {/* Field Status Indicators */} - {(required || - schema.deprecated() || - schema.writeOnly() || - schema.readOnly() || - isPatternProperty) && ( -
- {required && ( - - required - - )} - {schema.deprecated() && ( - - deprecated - - )} - {isPatternProperty && ( -
- (pattern property) -
- )} - {schema.writeOnly() && ( - - write-only - - )} - {schema.readOnly() && ( - - read-only - - )} -
- )} +
{isExpandable && !isCircular && !isArray && ( @@ -241,11 +221,11 @@ export const Payload: React.FunctionComponent = ({ {deepExpand ? 'Collapse all' : 'Expand all'} )} - {recursionCounter == 0 && ( + {childrenHaveConditions && recursionCounter == 0 && (
@@ -560,196 +361,3 @@ export const Payload: React.FunctionComponent = ({
); }; - -interface SchemaPropertiesProps { - schema: SchemaInterface; - recursionCounter?: number; -} - -const SchemaProperties: React.FunctionComponent = ({ - schema, - recursionCounter = 0, -}) => { - const properties = schema.properties(); - if (properties === undefined || !Object.keys(properties)) { - return null; - } - - const required = schema.required() ?? []; - const patternProperties = schema.patternProperties(); - - return ( - <> - {Object.entries(properties).map(([propertyName, property]) => ( - - ))} - {Object.entries(patternProperties ?? {}).map( - ([propertyName, property]) => ( - - ), - )} - - ); -}; - -interface AdditionalPropertiesProps { - schema: SchemaInterface; - recursionCounter?: number; -} - -const AdditionalProperties: React.FunctionComponent< - AdditionalPropertiesProps -> = ({ schema, recursionCounter = 0 }) => { - if ( - schema.extensions().get(SchemaHelpers.extRenderAdditionalInfo)?.value() === - false - ) { - return null; - } - - const type = schema.type(); - if (!type?.includes('object')) { - return null; - } - - const additionalProperties = schema.additionalProperties(); - if (additionalProperties === true || additionalProperties === undefined) { - return ( -

- Additional properties are allowed. -

- ); - } - if (additionalProperties === false) { - return ( -

- Additional properties are NOT allowed. -

- ); - } - return ( - - ); -}; - -interface SchemaItemsProps { - schema: SchemaInterface; - recursionCounter?: number; -} - -const SchemaItems: React.FunctionComponent = ({ - schema, - recursionCounter = 0, -}) => { - const type = schema.type(); - if (!type?.includes('array')) { - return null; - } - const items = schema.items(); - - // object in items - if ( - items && - !Array.isArray(items) && - Object.keys(items.properties() ?? {}).length - ) { - return ; - } else if (Array.isArray(items)) { - return ( - <> - SchemaItems - {items.map((item, idx) => ( - - ))} - - ); - } - return ( - - ); -}; - -interface AdditionalItemsProps { - schema: SchemaInterface; - recursionCounter?: number; -} - -const AdditionalItems: React.FunctionComponent = ({ - schema, - recursionCounter = 0, -}) => { - if ( - schema.extensions().get(SchemaHelpers.extRenderAdditionalInfo)?.value() === - false - ) { - return null; - } - - const type = schema.type(); - if (!type?.includes('array')) { - return null; - } - if (!Array.isArray(schema.items())) { - return null; - } - - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-explicit-any - const additionalItems = schema.additionalItems() as any; - if (additionalItems === true || additionalItems === undefined) { - return ( -

- Additional items are allowed. -

- ); - } - if (additionalItems === false) { - return ( -

- Additional items are NOT allowed. -

- ); - } - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment - return ( - - ); -}; diff --git a/library/src/components/Payload/Rules/Rules.tsx b/library/src/components/Payload/Rules/Rules.tsx new file mode 100644 index 000000000..d9f873ab7 --- /dev/null +++ b/library/src/components/Payload/Rules/Rules.tsx @@ -0,0 +1,83 @@ +import React from 'react'; +import { SchemaInterface } from '@asyncapi/parser'; +import { SchemaHelpers } from '../../../helpers'; + +interface RulesProps { + schema: SchemaInterface; + constraints: string[]; +} + +export const Rules = ({ schema, constraints }: RulesProps) => { + return ( + <> +

+ Rules +

+
+ {schema.format() && ( + + format:{' '} + + {schema.format()} + + + )} + {schema.pattern() && ( + + must match:{' '} + + {schema.pattern()} + + + )} + {schema.contentEncoding() !== undefined && ( + + encoding:{' '} + + {schema.contentEncoding()} + + + )} + {constraints.map((constraint) => ( + + {constraint} + + ))} + {schema.default() !== undefined && ( +
+ Default value: + + {SchemaHelpers.prettifyValue(schema.default())} + +
+ )} + {schema.const() !== undefined && ( +
+ Constant value: + + {SchemaHelpers.prettifyValue(schema.const())} + +
+ )} + {schema.enum() && ( +
+ Allowed values: + {schema.enum()?.map((e, idx) => ( + + {SchemaHelpers.prettifyValue(e)} + + ))} +
+ )} +
+ + ); +}; diff --git a/library/src/components/Payload/SchemaItems.tsx b/library/src/components/Payload/SchemaItems.tsx new file mode 100644 index 000000000..98002873a --- /dev/null +++ b/library/src/components/Payload/SchemaItems.tsx @@ -0,0 +1,50 @@ +import React from 'react'; +import { SchemaInterface } from '@asyncapi/parser'; +import { Payload } from './Payload'; + +interface SchemaItemsProps { + schema: SchemaInterface; + recursionCounter?: number; +} + +export const SchemaItems: React.FunctionComponent = ({ + schema, + recursionCounter = 0, +}) => { + const type = schema.type(); + if (!type?.includes('array')) { + return null; + } + const items = schema.items(); + + // object in items + if ( + items && + !Array.isArray(items) && + Object.keys(items.properties() ?? {}).length + ) { + return ; + } else if (Array.isArray(items)) { + return ( + <> + {items.map((item, idx) => ( + + ))} + + ); + } + return ( + + ); +}; diff --git a/library/src/components/Payload/SchemaProperties.tsx b/library/src/components/Payload/SchemaProperties.tsx new file mode 100644 index 000000000..67babb26c --- /dev/null +++ b/library/src/components/Payload/SchemaProperties.tsx @@ -0,0 +1,55 @@ +import React from "react" +import { SchemaInterface } from "@asyncapi/parser"; +import { SchemaHelpers } from "../../helpers"; +import { Payload } from "./Payload"; + +interface SchemaPropertiesProps { + schema: SchemaInterface; + recursionCounter?: number; +} + +export const SchemaProperties: React.FunctionComponent = ({ + schema, + recursionCounter = 0, +}) => { + const properties = schema.properties(); + if (properties === undefined || !Object.keys(properties)) { + return null; + } + + const required = schema.required() ?? []; + const patternProperties = schema.patternProperties(); + + return ( + <> + {Object.entries(properties).map(([propertyName, property]) => ( + + ))} + {Object.entries(patternProperties ?? {}).map( + ([propertyName, property]) => ( + + ), + )} + + ); +}; diff --git a/library/src/components/Schema.tsx b/library/src/components/Schema.tsx index 8ec964f8a..91a48c278 100644 --- a/library/src/components/Schema.tsx +++ b/library/src/components/Schema.tsx @@ -3,6 +3,7 @@ import { SchemaInterface } from '@asyncapi/parser'; import { Href, CollapseButton, Markdown, Extensions } from './index'; import { SchemaHelpers } from '../helpers'; +import { Payload } from './Payload/Payload'; interface Props { schemaName?: React.ReactNode; @@ -22,7 +23,9 @@ const SchemaContext = React.createContext({ deepExpanded: false, }); -export const Schema: React.FunctionComponent = ({ +export const Schema = Payload + +export const SchemaOld: React.FunctionComponent = ({ schemaName, schema, required = false, diff --git a/library/src/containers/Messages/Message.tsx b/library/src/containers/Messages/Message.tsx index 3b85e6f43..f7466e57e 100644 --- a/library/src/containers/Messages/Message.tsx +++ b/library/src/containers/Messages/Message.tsx @@ -17,7 +17,6 @@ import { CONTENT_TYPES_SITE, EXTERAL_DOCUMENTATION_TEXT, } from '../../constants'; -import { Payload } from '../../components/Payload/Payload'; interface Props { message: MessageInterface; @@ -134,8 +133,7 @@ export const Message: React.FunctionComponent = ({ : undefined } > - {/* */} - +
)} {headers && ( diff --git a/playground/app/page.tsx b/playground/app/page.tsx index 651a2f078..9d155905a 100644 --- a/playground/app/page.tsx +++ b/playground/app/page.tsx @@ -17,8 +17,8 @@ import { import { defaultConfig, parse, debounce } from '@/utils'; import * as specs from '@/specs'; -// const defaultSchema = specs.streetlights; -const defaultSchema = specs.overcomplicatedStreetlights; +const defaultSchema = specs.streetlights; +// const defaultSchema = specs.overcomplicatedStreetlights; // const defaultSchema = specs.complexSchema; interface State { diff --git a/playground/utils/defaultConfig.ts b/playground/utils/defaultConfig.ts index c2a37eedb..b95e0bd20 100644 --- a/playground/utils/defaultConfig.ts +++ b/playground/utils/defaultConfig.ts @@ -1,12 +1,11 @@ -// TODO: CHANGE THIS BACK TO ORIGINAL CONFIG export const defaultConfig = `{ "show": { "sidebar": false, - "info": false, - "operations": false, - "servers": false, + "info": true, + "operations": true, + "servers": true, "messages": true, - "schemas": false, + "schemas": true, "errors": true }, "expand":{ From 4c4ae9a923150955a70a5d2fd1b3947141f08b7b Mon Sep 17 00:00:00 2001 From: catosaurusrex2003 Date: Sun, 2 Feb 2025 14:14:22 +0530 Subject: [PATCH 22/41] formatted --- library/package.json | 2 +- .../components/Payload/Conditions/Conditions.tsx | 4 ++-- .../components/Payload/FeildStatusIndicators.tsx | 2 +- library/src/components/Payload/Payload.tsx | 6 +++--- .../src/components/Payload/SchemaProperties.tsx | 15 +++++++-------- library/src/components/Schema.tsx | 2 +- library/src/helpers/common.ts | 8 ++++---- library/src/hooks/useElementSize.tsx | 5 +++-- library/src/styles/default.css | 2 +- playground/specs/index.ts | 2 +- web-component/src/AsyncApiWebComponent.tsx | 2 +- 11 files changed, 25 insertions(+), 25 deletions(-) diff --git a/library/package.json b/library/package.json index a12ec8f2f..86f8d863a 100644 --- a/library/package.json +++ b/library/package.json @@ -117,4 +117,4 @@ "publishConfig": { "access": "public" } -} \ No newline at end of file +} diff --git a/library/src/components/Payload/Conditions/Conditions.tsx b/library/src/components/Payload/Conditions/Conditions.tsx index a86990f9d..9455b1124 100644 --- a/library/src/components/Payload/Conditions/Conditions.tsx +++ b/library/src/components/Payload/Conditions/Conditions.tsx @@ -6,13 +6,13 @@ import { SchemaHelpers } from '../../../helpers'; interface ConditionsProps { schema: SchemaInterface; recursionCounter?: number; - dependentSchemas?: SchemaInterface + dependentSchemas?: SchemaInterface; } export const Conditions = ({ schema, recursionCounter = 0, - dependentSchemas + dependentSchemas, }: ConditionsProps) => { return ( <> diff --git a/library/src/components/Payload/FeildStatusIndicators.tsx b/library/src/components/Payload/FeildStatusIndicators.tsx index 616b64313..07994bfd5 100644 --- a/library/src/components/Payload/FeildStatusIndicators.tsx +++ b/library/src/components/Payload/FeildStatusIndicators.tsx @@ -10,7 +10,7 @@ interface FeildStatusIndicatorProps { export const FeildStatusIndicator = ({ schema, required = false, - isPatternProperty + isPatternProperty, }: FeildStatusIndicatorProps) => { return ( <> diff --git a/library/src/components/Payload/Payload.tsx b/library/src/components/Payload/Payload.tsx index 0ee3375d6..b24e4ef89 100644 --- a/library/src/components/Payload/Payload.tsx +++ b/library/src/components/Payload/Payload.tsx @@ -19,7 +19,7 @@ import { Conditions } from './Conditions/Conditions'; import { Rules } from './Rules/Rules'; import { FeildStatusIndicator } from './FeildStatusIndicators'; -interface Props { +export interface Props { schemaName?: React.ReactNode; schema?: SchemaInterface; showSchemaType?: boolean; @@ -91,8 +91,8 @@ export const Payload: React.FunctionComponent = ({ const constraints = SchemaHelpers.humanizeConstraints(schema); const externalDocs = schema.externalDocs(); - const rawValueExt = schema.extensions().get(SchemaHelpers.extRawValue); - const rawValue = rawValueExt?.value() === true; + // const rawValueExt = schema.extensions().get(SchemaHelpers.extRawValue); + // const rawValue = rawValueExt?.value() === true; const parameterLocationExt = schema .extensions() diff --git a/library/src/components/Payload/SchemaProperties.tsx b/library/src/components/Payload/SchemaProperties.tsx index 67babb26c..aa87516ef 100644 --- a/library/src/components/Payload/SchemaProperties.tsx +++ b/library/src/components/Payload/SchemaProperties.tsx @@ -1,17 +1,16 @@ -import React from "react" -import { SchemaInterface } from "@asyncapi/parser"; -import { SchemaHelpers } from "../../helpers"; -import { Payload } from "./Payload"; +import React from 'react'; +import { SchemaInterface } from '@asyncapi/parser'; +import { SchemaHelpers } from '../../helpers'; +import { Payload } from './Payload'; interface SchemaPropertiesProps { schema: SchemaInterface; recursionCounter?: number; } -export const SchemaProperties: React.FunctionComponent = ({ - schema, - recursionCounter = 0, -}) => { +export const SchemaProperties: React.FunctionComponent< + SchemaPropertiesProps +> = ({ schema, recursionCounter = 0 }) => { const properties = schema.properties(); if (properties === undefined || !Object.keys(properties)) { return null; diff --git a/library/src/components/Schema.tsx b/library/src/components/Schema.tsx index 91a48c278..267fdc5e9 100644 --- a/library/src/components/Schema.tsx +++ b/library/src/components/Schema.tsx @@ -23,7 +23,7 @@ const SchemaContext = React.createContext({ deepExpanded: false, }); -export const Schema = Payload +export const Schema = Payload; export const SchemaOld: React.FunctionComponent = ({ schemaName, diff --git a/library/src/helpers/common.ts b/library/src/helpers/common.ts index 3a44bde57..be2b2be91 100644 --- a/library/src/helpers/common.ts +++ b/library/src/helpers/common.ts @@ -76,8 +76,8 @@ export class CommonHelpers { borderColor: 'border-green-600 text-green-600', backgroundColor: 'bg-green-600', typeLabel: !isAsyncAPIv2 - ? config.receiveLabel ?? RECEIVE_TEXT_LABEL_DEFAULT_TEXT - : config.publishLabel ?? PUBLISH_LABEL_DEFAULT_TEXT, + ? (config.receiveLabel ?? RECEIVE_TEXT_LABEL_DEFAULT_TEXT) + : (config.publishLabel ?? PUBLISH_LABEL_DEFAULT_TEXT), }; } if (type === PayloadType.REPLY) { @@ -98,8 +98,8 @@ export class CommonHelpers { borderColor: 'border-blue-600 text-blue-500', backgroundColor: 'bg-blue-600', typeLabel: !isAsyncAPIv2 - ? config.sendLabel ?? SEND_LABEL_DEFAULT_TEXT - : config.subscribeLabel ?? SUBSCRIBE_LABEL_DEFAULT_TEXT, + ? (config.sendLabel ?? SEND_LABEL_DEFAULT_TEXT) + : (config.subscribeLabel ?? SUBSCRIBE_LABEL_DEFAULT_TEXT), }; } } diff --git a/library/src/hooks/useElementSize.tsx b/library/src/hooks/useElementSize.tsx index e49d6bfda..9aeed2da1 100644 --- a/library/src/hooks/useElementSize.tsx +++ b/library/src/hooks/useElementSize.tsx @@ -28,7 +28,8 @@ function useElementSize(): [ } }, [ref]); - const useEnviromentEffect = typeof window !== 'undefined' ? useLayoutEffect : useEffect; + const useEnviromentEffect = + typeof window !== 'undefined' ? useLayoutEffect : useEffect; useEnviromentEffect(() => { if (!ref) return; @@ -44,4 +45,4 @@ function useElementSize(): [ return [setRef, size]; } -export { useElementSize }; \ No newline at end of file +export { useElementSize }; diff --git a/library/src/styles/default.css b/library/src/styles/default.css index 75e8f4ef7..903968243 100644 --- a/library/src/styles/default.css +++ b/library/src/styles/default.css @@ -13,7 +13,7 @@ @apply lg:relative lg:block lg:w-64 lg:h-auto; } - .container\:xl .sidebar--wrapper{ + .container\:xl .sidebar--wrapper { @apply xl:w-full; @apply sm:w-full; } diff --git a/playground/specs/index.ts b/playground/specs/index.ts index f4d2bb114..b17ed9ecc 100644 --- a/playground/specs/index.ts +++ b/playground/specs/index.ts @@ -12,4 +12,4 @@ export * from './rpc-server'; export * from './slack-rtm'; export * from './streetlights'; export * from './overcomplicated-streetlight'; -export * from './complex-schema' \ No newline at end of file +export * from './complex-schema'; diff --git a/web-component/src/AsyncApiWebComponent.tsx b/web-component/src/AsyncApiWebComponent.tsx index 9bcb139ab..8c2d5d8b8 100644 --- a/web-component/src/AsyncApiWebComponent.tsx +++ b/web-component/src/AsyncApiWebComponent.tsx @@ -39,7 +39,7 @@ function retrieveSchemaProp( // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment const schemaRequestOptions = schemaFetchOptions ? JSON.parse(JSON.stringify(schemaFetchOptions)) - : (schema as FetchingSchemaInterface).requestOptions ?? {}; + : ((schema as FetchingSchemaInterface).requestOptions ?? {}); // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment schema = { url: schemaUrl, requestOptions: schemaRequestOptions }; } From 1c24a9ba050382c2095b17ed2fdf9bc356fc0c0c Mon Sep 17 00:00:00 2001 From: catosaurusrex2003 Date: Mon, 3 Feb 2025 21:01:56 +0530 Subject: [PATCH 23/41] rules and conditions swapped --- library/src/components/Payload/Payload.tsx | 28 +++++++++++----------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/library/src/components/Payload/Payload.tsx b/library/src/components/Payload/Payload.tsx index b24e4ef89..718ec8f09 100644 --- a/library/src/components/Payload/Payload.tsx +++ b/library/src/components/Payload/Payload.tsx @@ -301,19 +301,23 @@ export const Payload: React.FunctionComponent = ({ minHeight: Math.max(conditionsSize.height, rulesSize.height), }} > - {/* Rules Section: it generally doesnt have any recursion in it */} - {rulesExist && ( -
- -
- )} - {/* Conditions Section: has hella recursion in it*/} {conditionsExist && ( +
+ +
+ )} + + {/* Rules Section: it generally doesnt have any recursion in it */} + {rulesExist && (
= ({ } : {} } - ref={setConditionsRef} + ref={setRulesRef} > - +
)}
From 5ca02fbe849de65e372d3133e4deb9288f7ba0f3 Mon Sep 17 00:00:00 2001 From: catosaurusrex2003 Date: Mon, 3 Feb 2025 21:50:15 +0530 Subject: [PATCH 24/41] sidebar toggle localised, payload header w-full --- .../Payload/Conditions/Conditions.tsx | 51 +++--- library/src/components/Payload/Payload.tsx | 158 +++++++++--------- .../src/components/Payload/Rules/Rules.tsx | 2 +- library/src/containers/AsyncApi/Layout.tsx | 3 - library/src/contexts/conditionsSidebar.tsx | 30 ---- 5 files changed, 109 insertions(+), 135 deletions(-) delete mode 100644 library/src/contexts/conditionsSidebar.tsx diff --git a/library/src/components/Payload/Conditions/Conditions.tsx b/library/src/components/Payload/Conditions/Conditions.tsx index 9455b1124..459f8ed8d 100644 --- a/library/src/components/Payload/Conditions/Conditions.tsx +++ b/library/src/components/Payload/Conditions/Conditions.tsx @@ -21,9 +21,9 @@ export const Conditions = ({ > Conditions

-
+
{schema.oneOf()?.length && ( -
+
Can be One Of the following:
@@ -46,7 +46,7 @@ export const Conditions = ({ )} {schema.anyOf()?.length && ( -
+
Can be Any Of the following:
@@ -69,7 +69,7 @@ export const Conditions = ({ )} {schema.allOf()?.length && ( -
+
Must consist All Of the following:
@@ -116,26 +116,31 @@ export const Conditions = ({ )} {schema.if() && ( - - )} - {schema.then() && ( - - )} - {schema.else() && ( - +
+ {schema.if() && ( + + )} + {schema.then() && ( + + )} + {schema.else() && ( + + )} +
)} + {dependentSchemas && ( = ({ const { reverse, deepExpanded } = useContext(PayloadSchemaContext); const [expanded, setExpanded] = useState(propExpanded || isArray); const [deepExpand, setDeepExpand] = useState(false); - const { conditionsSidebarOpen, toggleSidebar } = useSidebarContext(); + // rulesSidebarOpen state is usefull only when recursionCounter is 0, else it is redundant + const [rulesSidebarOpen, setRulesSidebarOpen] = useState(false); const [setConditionsRef, conditionsSize] = useElementSize(); const [setRulesRef, rulesSize] = useElementSize(); const floatConditionsToRight = - isProperty && recursionCounter >= 2 && conditionsSidebarOpen; + isProperty && recursionCounter >= 2 && rulesSidebarOpen; useEffect(() => { if (!isArray) { @@ -159,11 +159,9 @@ export const Payload: React.FunctionComponent = ({ }} >
-
+
{/* Header Section */} -
+
{isExpandable && !isCircular && !isArray ? ( @@ -224,15 +222,13 @@ export const Payload: React.FunctionComponent = ({ {childrenHaveConditions && recursionCounter == 0 && ( @@ -280,83 +276,89 @@ export const Payload: React.FunctionComponent = ({ )}
- {/* Expandable Content */} - {!isCircular && isExpandable && expanded && ( -
- {/* Properties Section */} - - - {/* Array Items Section */} - - +
+ {/* Expandable Content */} + {!isCircular && isExpandable && expanded && (
- {/* Conditions Section: has hella recursion in it*/} - {conditionsExist && ( -
- -
- )} - - {/* Rules Section: it generally doesnt have any recursion in it */} - {rulesExist && ( -
- -
- )} -
- - {/* Additional Properties/Items Section */} -
- - -
- {/* Extensions Section */} - -
- )} -
+
+ {/* Conditions Section: has hella recursion in it*/} + {conditionsExist && ( +
+ +
+ )} + + {/* Rules Section: it generally doesnt have any recursion in it */} + {rulesExist && ( +
+ +
+ )} +
+ + {/* Additional Properties/Items Section */} +
+ + +
- {/* right side conditions sidebar */} - {expanded && conditionsSidebarOpen && recursionCounter == 0 && ( -
- )} + {/* Extensions Section */} + +
+ )} + {/* right side conditions sidebar */} + {expanded && rulesSidebarOpen && recursionCounter == 0 && ( +
+ )} +
+
); diff --git a/library/src/components/Payload/Rules/Rules.tsx b/library/src/components/Payload/Rules/Rules.tsx index d9f873ab7..9f63154aa 100644 --- a/library/src/components/Payload/Rules/Rules.tsx +++ b/library/src/components/Payload/Rules/Rules.tsx @@ -15,7 +15,7 @@ export const Rules = ({ schema, constraints }: RulesProps) => { > Rules

-
+
{schema.format() && ( format:{' '} diff --git a/library/src/containers/AsyncApi/Layout.tsx b/library/src/containers/AsyncApi/Layout.tsx index a21ab6ecc..6409061c9 100644 --- a/library/src/containers/AsyncApi/Layout.tsx +++ b/library/src/containers/AsyncApi/Layout.tsx @@ -12,7 +12,6 @@ import { Schemas } from '../Schemas/Schemas'; import { ConfigInterface } from '../../config'; import { SpecificationContext, ConfigContext } from '../../contexts'; import AsyncApiErrorBoundary from '../ApplicationErrorHandler/ErrorBoundary'; -import { SidebarProvider } from '../../contexts/conditionsSidebar'; interface Props { asyncapi: AsyncAPIDocumentInterface; @@ -45,7 +44,6 @@ const AsyncApiLayout: React.FunctionComponent = ({ return ( -
= ({
-
); diff --git a/library/src/contexts/conditionsSidebar.tsx b/library/src/contexts/conditionsSidebar.tsx deleted file mode 100644 index 9b5650a64..000000000 --- a/library/src/contexts/conditionsSidebar.tsx +++ /dev/null @@ -1,30 +0,0 @@ -import React, { createContext, useState, useContext, ReactNode } from 'react'; - -interface SidebarContextType { - conditionsSidebarOpen: boolean; - toggleSidebar: () => void; -} - -const SidebarContext = createContext(undefined); - -export const SidebarProvider = ({ children }: { children: ReactNode }) => { - const [conditionsSidebarOpen, setConditionsSidebarOpen] = - useState(false); - - const toggleSidebar = () => setConditionsSidebarOpen((prev) => !prev); - - return ( - - {children} - - ); -}; - -// Custom hook -export const useSidebarContext = (): SidebarContextType => { - const context = useContext(SidebarContext); - if (!context) { - throw new Error('useSidebarContext must be used within a SidebarProvider'); - } - return context; -}; From b834a1b50e0cc6947c54164c259bc94f36384291 Mon Sep 17 00:00:00 2001 From: catosaurusrex2003 Date: Mon, 3 Feb 2025 22:37:57 +0530 Subject: [PATCH 25/41] logic for childrenHaveConditions added --- library/src/components/Payload/Payload.tsx | 29 ++---------- library/src/helpers/schema.ts | 53 ++++++++++++++++++++++ 2 files changed, 57 insertions(+), 25 deletions(-) diff --git a/library/src/components/Payload/Payload.tsx b/library/src/components/Payload/Payload.tsx index 0f56e8cc2..5598f97b4 100644 --- a/library/src/components/Payload/Payload.tsx +++ b/library/src/components/Payload/Payload.tsx @@ -116,36 +116,15 @@ export const Payload: React.FunctionComponent = ({ ); // comes in Rules section - const rulesExist = - schema.format() || - schema.pattern() || - constraints.length > 0 || - schema.contentEncoding() || - schema.enum() || - schema.default() !== undefined || - schema.const() !== undefined; - + const rulesExist = SchemaHelpers.hasRules(schema, constraints); // comes in Conditions section - const conditionsExist = - schema.oneOf()?.length || - schema.anyOf()?.length || - schema.allOf()?.length || - schema.not() || - schema.propertyNames() || - schema.contains() || - schema.if() || - schema.then() || - schema.else() || - dependentSchemas; + const conditionsExist = SchemaHelpers.hasConditions(schema); // we want the expanding dropdown to be present if schema has got other stuff, rules or conditions const isExpandable = SchemaHelpers.isExpandable(schema) || rulesExist || conditionsExist; - // TODO: check recursiveley to see if any of the children have any conditions present in them. - // this is neccesary to conditionally render the conditions sidebar toggle button - // will need some functions in SchemaHelpers something like jsonFieldToSchema or something - const childrenHaveConditions = true; // hardcoding for now + const childrenHaveConditions = SchemaHelpers.childrenHaveConditions(schema); // this is the ammount of shift it needs to be moved to the right in px // by absolute when the components gets nested a lot @@ -225,7 +204,7 @@ export const Payload: React.FunctionComponent = ({ onClick={() => setRulesSidebarOpen((prev) => !prev)} className="flex items-center text-sm p-1 rounded" > - Conditions + Rules 0 || + schema.contentEncoding() || + schema.enum() || + schema.default() !== undefined || + schema.const() !== undefined + ); + } + + public static hasConditions(schema: SchemaInterface) { + const dependentSchemas = this.getDependentSchemas(schema); + return ( + schema.oneOf()?.length || + schema.anyOf()?.length || + schema.allOf()?.length || + schema.not() || + schema.propertyNames() || + schema.contains() || + schema.if() || + schema.then() || + schema.else() || + dependentSchemas + ); + } + + // checks if any of the nested schema children has got conditions in it + public static childrenHaveConditions( + schema: SchemaInterface, + visited: WeakSet = new WeakSet(), + ): boolean { + if (visited.has(schema)) { + return false; + } + visited.add(schema); + const children = schema.properties(); + if (!children) { + return false; + } + const childArray = Object.values(children); + for (const child of childArray) { + if ( + this.hasConditions(child) || + this.childrenHaveConditions(child, visited) + ) { + return true; + } + } + return false; + } } From 4f3d60b36ce150fd3b708dca57ba583e87e621cb Mon Sep 17 00:00:00 2001 From: catosaurusrex2003 Date: Tue, 4 Feb 2025 19:28:18 +0530 Subject: [PATCH 26/41] back to tabs, chucked sidebar --- .../Payload/Conditions/Conditions.tsx | 245 +++++++++--------- library/src/components/Payload/Payload.tsx | 88 ++++--- .../src/components/Payload/Rules/Rules.tsx | 125 +++++---- library/src/helpers/schema.ts | 46 ++-- library/src/hooks/useElementSize.tsx | 96 +++---- 5 files changed, 298 insertions(+), 302 deletions(-) diff --git a/library/src/components/Payload/Conditions/Conditions.tsx b/library/src/components/Payload/Conditions/Conditions.tsx index 459f8ed8d..7ee75fe82 100644 --- a/library/src/components/Payload/Conditions/Conditions.tsx +++ b/library/src/components/Payload/Conditions/Conditions.tsx @@ -15,140 +15,133 @@ export const Conditions = ({ dependentSchemas, }: ConditionsProps) => { return ( - <> -

- Conditions -

-
- {schema.oneOf()?.length && ( -
-
- Can be One Of the following: -
- {schema - .oneOf() - ?.map((s, idx) => ( - - ))} -
- )} - - {schema.anyOf()?.length && ( -
-
- Can be Any Of the following: -
- {schema - .anyOf() - ?.map((s, idx) => ( - - ))} -
- )} - - {schema.allOf()?.length && ( -
-
- Must consist All Of the following: -
- {schema - .allOf() - ?.map((s, idx) => ( - - ))} -
- )} - - {schema.not() && ( - - )} - - {schema.propertyNames() && ( - - )} - - {schema.contains() && ( - - )} - - {schema.if() && ( -
- {schema.if() && ( +
+ {schema.oneOf()?.length && ( +
+
+ Can be One Of the following: +
+ {schema + .oneOf() + ?.map((s, idx) => ( - )} - {schema.then() && ( + ))} +
+ )} + + {schema.anyOf()?.length && ( +
+
+ Can be Any Of the following: +
+ {schema + .anyOf() + ?.map((s, idx) => ( - )} - {schema.else() && ( + ))} +
+ )} + + {schema.allOf()?.length && ( +
+
+ Must consist All Of the following: +
+ {schema + .allOf() + ?.map((s, idx) => ( - )} -
- )} - - {dependentSchemas && ( - - )} -
- + ))} +
+ )} + + {schema.not() && ( + + )} + + {schema.propertyNames() && ( + + )} + + {schema.contains() && ( + + )} + + {schema.if() && ( +
+ {schema.if() && ( + + )} + {schema.then() && ( + + )} + {schema.else() && ( + + )} +
+ )} + + {dependentSchemas && ( + + )} +
); }; diff --git a/library/src/components/Payload/Payload.tsx b/library/src/components/Payload/Payload.tsx index 5598f97b4..e8a6dd28d 100644 --- a/library/src/components/Payload/Payload.tsx +++ b/library/src/components/Payload/Payload.tsx @@ -6,10 +6,10 @@ import { CollapseButton, Markdown, Extensions, - HiChevronRight, + // HiChevronRight, } from '../index'; import { SchemaHelpers } from '../../helpers'; -import { useElementSize } from '../../hooks/useElementSize'; +// import { useElementSize } from '../../hooks/useElementSize'; import { SchemaItems } from './SchemaItems'; import { AdditionalItems } from './AdditionalItems'; import { SchemaProperties } from './SchemaProperties'; @@ -57,13 +57,14 @@ export const Payload: React.FunctionComponent = ({ const { reverse, deepExpanded } = useContext(PayloadSchemaContext); const [expanded, setExpanded] = useState(propExpanded || isArray); const [deepExpand, setDeepExpand] = useState(false); + const [tabOpen, setTabOpen] = useState<'RULES' | 'CONDITIONS'>('RULES'); // rulesSidebarOpen state is usefull only when recursionCounter is 0, else it is redundant - const [rulesSidebarOpen, setRulesSidebarOpen] = useState(false); - const [setConditionsRef, conditionsSize] = useElementSize(); - const [setRulesRef, rulesSize] = useElementSize(); + // const [rulesSidebarOpen, setRulesSidebarOpen] = useState(false); + // const [setConditionsRef, conditionsSize] = useElementSize(); + // const [setRulesRef, rulesSize] = useElementSize(); - const floatConditionsToRight = - isProperty && recursionCounter >= 2 && rulesSidebarOpen; + // const floatConditionsToRight = + // isProperty && recursionCounter >= 2 && rulesSidebarOpen; useEffect(() => { if (!isArray) { @@ -124,11 +125,15 @@ export const Payload: React.FunctionComponent = ({ const isExpandable = SchemaHelpers.isExpandable(schema) || rulesExist || conditionsExist; - const childrenHaveConditions = SchemaHelpers.childrenHaveConditions(schema); + // const childrenHaveConditions = SchemaHelpers.childrenHaveConditions(schema); // this is the ammount of shift it needs to be moved to the right in px // by absolute when the components gets nested a lot - const conditionsRightShift = 30 + 10 * (recursionCounter - 1); + // const conditionsRightShift = 30 + 10 * (recursionCounter - 1); + + useEffect(() => { + if (!rulesExist) setTabOpen('CONDITIONS'); + }, []); return ( = ({ {deepExpand ? 'Collapse all' : 'Expand all'} )} - {childrenHaveConditions && recursionCounter == 0 && ( + {/* {childrenHaveConditions && recursionCounter == 0 && ( - )} + )} */}
@@ -259,7 +264,8 @@ export const Payload: React.FunctionComponent = ({ {/* Expandable Content */} {!isCircular && isExpandable && expanded && (
{/* Properties Section */} = ({ recursionCounter={recursionCounter + 1} /> -
+
+
+ {rulesExist && ( + + )} + {conditionsExist && ( + + )} +
{/* Conditions Section: has hella recursion in it*/} - {conditionsExist && ( -
+ {conditionsExist && tabOpen == 'CONDITIONS' && ( +
= ({ )} {/* Rules Section: it generally doesnt have any recursion in it */} - {rulesExist && ( -
+ {rulesExist && tabOpen == 'RULES' && ( +
)} @@ -333,9 +343,9 @@ export const Payload: React.FunctionComponent = ({
)} {/* right side conditions sidebar */} - {expanded && rulesSidebarOpen && recursionCounter == 0 && ( + {/* {expanded && rulesSidebarOpen && recursionCounter == 0 && (
- )} + )} */}
diff --git a/library/src/components/Payload/Rules/Rules.tsx b/library/src/components/Payload/Rules/Rules.tsx index 9f63154aa..827e23a47 100644 --- a/library/src/components/Payload/Rules/Rules.tsx +++ b/library/src/components/Payload/Rules/Rules.tsx @@ -9,75 +9,68 @@ interface RulesProps { export const Rules = ({ schema, constraints }: RulesProps) => { return ( - <> -

- Rules -

-
- {schema.format() && ( - - format:{' '} - - {schema.format()} - +
+ {schema.format() && ( + + format:{' '} + + {schema.format()} - )} - {schema.pattern() && ( - - must match:{' '} - - {schema.pattern()} - + + )} + {schema.pattern() && ( + + must match:{' '} + + {schema.pattern()} - )} - {schema.contentEncoding() !== undefined && ( - - encoding:{' '} - - {schema.contentEncoding()} - + + )} + {schema.contentEncoding() !== undefined && ( + + encoding:{' '} + + {schema.contentEncoding()} - )} - {constraints.map((constraint) => ( - - {constraint} - - ))} - {schema.default() !== undefined && ( -
- Default value: - - {SchemaHelpers.prettifyValue(schema.default())} - -
- )} - {schema.const() !== undefined && ( -
- Constant value: - - {SchemaHelpers.prettifyValue(schema.const())} + + )} + {constraints.map((constraint) => ( + + {constraint} + + ))} + {schema.default() !== undefined && ( +
+ Default value: + + {SchemaHelpers.prettifyValue(schema.default())} + +
+ )} + {schema.const() !== undefined && ( +
+ Constant value: + + {SchemaHelpers.prettifyValue(schema.const())} + +
+ )} + {schema.enum() && ( +
+ Allowed values: + {schema.enum()?.map((e, idx) => ( + + {SchemaHelpers.prettifyValue(e)} -
- )} - {schema.enum() && ( -
- Allowed values: - {schema.enum()?.map((e, idx) => ( - - {SchemaHelpers.prettifyValue(e)} - - ))} -
- )} -
- + ))} +
+ )} +
); }; diff --git a/library/src/helpers/schema.ts b/library/src/helpers/schema.ts index fea4f35f4..24daa918c 100644 --- a/library/src/helpers/schema.ts +++ b/library/src/helpers/schema.ts @@ -632,27 +632,27 @@ export class SchemaHelpers { } // checks if any of the nested schema children has got conditions in it - public static childrenHaveConditions( - schema: SchemaInterface, - visited: WeakSet = new WeakSet(), - ): boolean { - if (visited.has(schema)) { - return false; - } - visited.add(schema); - const children = schema.properties(); - if (!children) { - return false; - } - const childArray = Object.values(children); - for (const child of childArray) { - if ( - this.hasConditions(child) || - this.childrenHaveConditions(child, visited) - ) { - return true; - } - } - return false; - } + // public static childrenHaveConditions( + // schema: SchemaInterface, + // visited: WeakSet = new WeakSet(), + // ): boolean { + // if (visited.has(schema)) { + // return false; + // } + // visited.add(schema); + // const children = schema.properties(); + // if (!children) { + // return false; + // } + // const childArray = Object.values(children); + // for (const child of childArray) { + // if ( + // this.hasConditions(child) || + // this.childrenHaveConditions(child, visited) + // ) { + // return true; + // } + // } + // return false; + // } } diff --git a/library/src/hooks/useElementSize.tsx b/library/src/hooks/useElementSize.tsx index 9aeed2da1..24c4e40a2 100644 --- a/library/src/hooks/useElementSize.tsx +++ b/library/src/hooks/useElementSize.tsx @@ -1,48 +1,48 @@ -import { useCallback, useEffect, useLayoutEffect, useState } from 'react'; -export interface Size { - width: number; - height: number; -} - -/** - * `useElementSize` is a hook to measure the size of a DOM element. - * It tracks the width and height of the element and updates them on window resize or element changes. - * - * @param ref - The React ref object attached to the element to measure. - * @return - An object containing the `width` and `height` of the element. - */ - -function useElementSize(): [ - (node: T | null) => void, - Size, -] { - const [ref, setRef] = useState(null); - const [size, setSize] = useState({ width: 0, height: 0 }); - - const handleSize = useCallback(() => { - if (ref) { - setSize({ - width: ref.offsetWidth, - height: ref.offsetHeight, - }); - } - }, [ref]); - - const useEnviromentEffect = - typeof window !== 'undefined' ? useLayoutEffect : useEffect; - - useEnviromentEffect(() => { - if (!ref) return; - - handleSize(); - - const resizeObserver = new ResizeObserver(handleSize); - resizeObserver.observe(ref); - - return () => resizeObserver.disconnect(); - }, [ref, handleSize]); - - return [setRef, size]; -} - -export { useElementSize }; +// import { useCallback, useEffect, useLayoutEffect, useState } from 'react'; +// export interface Size { +// width: number; +// height: number; +// } + +// /** +// * `useElementSize` is a hook to measure the size of a DOM element. +// * It tracks the width and height of the element and updates them on window resize or element changes. +// * +// * @param ref - The React ref object attached to the element to measure. +// * @return - An object containing the `width` and `height` of the element. +// */ + +// function useElementSize(): [ +// (node: T | null) => void, +// Size, +// ] { +// const [ref, setRef] = useState(null); +// const [size, setSize] = useState({ width: 0, height: 0 }); + +// const handleSize = useCallback(() => { +// if (ref) { +// setSize({ +// width: ref.offsetWidth, +// height: ref.offsetHeight, +// }); +// } +// }, [ref]); + +// const useEnviromentEffect = +// typeof window !== 'undefined' ? useLayoutEffect : useEffect; + +// useEnviromentEffect(() => { +// if (!ref) return; + +// handleSize(); + +// const resizeObserver = new ResizeObserver(handleSize); +// resizeObserver.observe(ref); + +// return () => resizeObserver.disconnect(); +// }, [ref, handleSize]); + +// return [setRef, size]; +// } + +// export { useElementSize }; From 41eb1a2870328105d2d5cf10ad7beb5f494b2a46 Mon Sep 17 00:00:00 2001 From: catosaurusrex2003 Date: Fri, 28 Feb 2025 02:25:12 +0530 Subject: [PATCH 27/41] removed recursioncounter, comments --- library/src/components/Extensions.tsx | 3 -- .../components/Payload/AdditionalItems.tsx | 3 -- .../Payload/AdditionalProperties.tsx | 4 +- .../Payload/Conditions/Conditions.tsx | 12 ----- library/src/components/Payload/Payload.tsx | 48 +------------------ .../src/components/Payload/SchemaItems.tsx | 4 -- .../components/Payload/SchemaProperties.tsx | 5 +- .../src/containers/Operations/Operation.tsx | 3 +- library/src/helpers/schema.ts | 29 +---------- library/src/hooks/useElementSize.tsx | 48 ------------------- playground/app/page.tsx | 2 - 11 files changed, 8 insertions(+), 153 deletions(-) delete mode 100644 library/src/hooks/useElementSize.tsx diff --git a/library/src/components/Extensions.tsx b/library/src/components/Extensions.tsx index cc6613f5c..1f64943bd 100644 --- a/library/src/components/Extensions.tsx +++ b/library/src/components/Extensions.tsx @@ -11,13 +11,11 @@ interface Props { name?: string; // eslint-disable-next-line @typescript-eslint/no-explicit-any item: any; - recursionCounter?: number; } export const Extensions: React.FunctionComponent = ({ name = 'Extensions', item, - recursionCounter = 0, }) => { const extensions = SchemaHelpers.getCustomExtensions(item); if (!extensions || !Object.keys(extensions).length) { @@ -32,7 +30,6 @@ export const Extensions: React.FunctionComponent = ({
diff --git a/library/src/components/Payload/AdditionalItems.tsx b/library/src/components/Payload/AdditionalItems.tsx index f60c7bab4..6594932d4 100644 --- a/library/src/components/Payload/AdditionalItems.tsx +++ b/library/src/components/Payload/AdditionalItems.tsx @@ -5,12 +5,10 @@ import { Payload } from './Payload'; interface AdditionalItemsProps { schema: SchemaInterface; - recursionCounter?: number; } export const AdditionalItems: React.FunctionComponent = ({ schema, - recursionCounter = 0, }) => { if ( schema.extensions().get(SchemaHelpers.extRenderAdditionalInfo)?.value() === @@ -48,7 +46,6 @@ export const AdditionalItems: React.FunctionComponent = ({ ); }; diff --git a/library/src/components/Payload/AdditionalProperties.tsx b/library/src/components/Payload/AdditionalProperties.tsx index f48c5f88f..9c626a121 100644 --- a/library/src/components/Payload/AdditionalProperties.tsx +++ b/library/src/components/Payload/AdditionalProperties.tsx @@ -5,12 +5,11 @@ import { Payload } from './Payload'; interface AdditionalPropertiesProps { schema: SchemaInterface; - recursionCounter?: number; } export const AdditionalProperties: React.FunctionComponent< AdditionalPropertiesProps -> = ({ schema, recursionCounter = 0 }) => { +> = ({ schema }) => { if ( schema.extensions().get(SchemaHelpers.extRenderAdditionalInfo)?.value() === false @@ -42,7 +41,6 @@ export const AdditionalProperties: React.FunctionComponent< ); }; diff --git a/library/src/components/Payload/Conditions/Conditions.tsx b/library/src/components/Payload/Conditions/Conditions.tsx index 7ee75fe82..064c95ba2 100644 --- a/library/src/components/Payload/Conditions/Conditions.tsx +++ b/library/src/components/Payload/Conditions/Conditions.tsx @@ -5,13 +5,11 @@ import { SchemaHelpers } from '../../../helpers'; interface ConditionsProps { schema: SchemaInterface; - recursionCounter?: number; dependentSchemas?: SchemaInterface; } export const Conditions = ({ schema, - recursionCounter = 0, dependentSchemas, }: ConditionsProps) => { return ( @@ -33,7 +31,6 @@ export const Conditions = ({ '', s.title() ?? s.id(), )} - recursionCounter={recursionCounter + 1} /> ))}
@@ -56,7 +53,6 @@ export const Conditions = ({ '', s.title() ?? s.id(), )} - recursionCounter={recursionCounter + 1} /> ))}
@@ -79,7 +75,6 @@ export const Conditions = ({ '', s.title() ?? s.id(), )} - recursionCounter={recursionCounter + 1} /> ))}
@@ -89,7 +84,6 @@ export const Conditions = ({ )} @@ -97,7 +91,6 @@ export const Conditions = ({ )} @@ -105,7 +98,6 @@ export const Conditions = ({ )} @@ -115,21 +107,18 @@ export const Conditions = ({ )} {schema.then() && ( )} {schema.else() && ( )}
@@ -139,7 +128,6 @@ export const Conditions = ({ )}
diff --git a/library/src/components/Payload/Payload.tsx b/library/src/components/Payload/Payload.tsx index e8a6dd28d..d7c5332ea 100644 --- a/library/src/components/Payload/Payload.tsx +++ b/library/src/components/Payload/Payload.tsx @@ -9,7 +9,6 @@ import { // HiChevronRight, } from '../index'; import { SchemaHelpers } from '../../helpers'; -// import { useElementSize } from '../../hooks/useElementSize'; import { SchemaItems } from './SchemaItems'; import { AdditionalItems } from './AdditionalItems'; import { SchemaProperties } from './SchemaProperties'; @@ -31,7 +30,6 @@ export interface Props { onlyTitle?: boolean; isArray?: boolean; showConditionSidebar?: boolean; - recursionCounter?: number; } const PayloadSchemaContext = React.createContext({ @@ -51,20 +49,12 @@ export const Payload: React.FunctionComponent = ({ expanded: propExpanded = false, onlyTitle = false, isArray = false, - recursionCounter = 0, // eslint-disable-next-line sonarjs/cognitive-complexity }) => { const { reverse, deepExpanded } = useContext(PayloadSchemaContext); const [expanded, setExpanded] = useState(propExpanded || isArray); const [deepExpand, setDeepExpand] = useState(false); const [tabOpen, setTabOpen] = useState<'RULES' | 'CONDITIONS'>('RULES'); - // rulesSidebarOpen state is usefull only when recursionCounter is 0, else it is redundant - // const [rulesSidebarOpen, setRulesSidebarOpen] = useState(false); - // const [setConditionsRef, conditionsSize] = useElementSize(); - // const [setRulesRef, rulesSize] = useElementSize(); - - // const floatConditionsToRight = - // isProperty && recursionCounter >= 2 && rulesSidebarOpen; useEffect(() => { if (!isArray) { @@ -92,9 +82,6 @@ export const Payload: React.FunctionComponent = ({ const constraints = SchemaHelpers.humanizeConstraints(schema); const externalDocs = schema.externalDocs(); - // const rawValueExt = schema.extensions().get(SchemaHelpers.extRawValue); - // const rawValue = rawValueExt?.value() === true; - const parameterLocationExt = schema .extensions() .get(SchemaHelpers.extParameterLocation); @@ -125,12 +112,6 @@ export const Payload: React.FunctionComponent = ({ const isExpandable = SchemaHelpers.isExpandable(schema) || rulesExist || conditionsExist; - // const childrenHaveConditions = SchemaHelpers.childrenHaveConditions(schema); - - // this is the ammount of shift it needs to be moved to the right in px - // by absolute when the components gets nested a lot - // const conditionsRightShift = 30 + 10 * (recursionCounter - 1); - useEffect(() => { if (!rulesExist) setTabOpen('CONDITIONS'); }, []); @@ -203,20 +184,6 @@ export const Payload: React.FunctionComponent = ({ {deepExpand ? 'Collapse all' : 'Expand all'} )} - {/* {childrenHaveConditions && recursionCounter == 0 && ( - - )} */}
@@ -264,19 +231,16 @@ export const Payload: React.FunctionComponent = ({ {/* Expandable Content */} {!isCircular && isExpandable && expanded && (
{/* Properties Section */} {/* Array Items Section */}
@@ -304,18 +268,17 @@ export const Payload: React.FunctionComponent = ({ )}
- {/* Conditions Section: has hella recursion in it*/} + {/* Conditions Section: has deep recursions */} {conditionsExist && tabOpen == 'CONDITIONS' && (
)} - {/* Rules Section: it generally doesnt have any recursion in it */} + {/* Rules Section: typically does not involve recursion */} {rulesExist && tabOpen == 'RULES' && (
@@ -327,25 +290,18 @@ export const Payload: React.FunctionComponent = ({
{/* Extensions Section */}
)} - {/* right side conditions sidebar */} - {/* {expanded && rulesSidebarOpen && recursionCounter == 0 && ( -
- )} */}
diff --git a/library/src/components/Payload/SchemaItems.tsx b/library/src/components/Payload/SchemaItems.tsx index 98002873a..31d633f09 100644 --- a/library/src/components/Payload/SchemaItems.tsx +++ b/library/src/components/Payload/SchemaItems.tsx @@ -4,12 +4,10 @@ import { Payload } from './Payload'; interface SchemaItemsProps { schema: SchemaInterface; - recursionCounter?: number; } export const SchemaItems: React.FunctionComponent = ({ schema, - recursionCounter = 0, }) => { const type = schema.type(); if (!type?.includes('array')) { @@ -33,7 +31,6 @@ export const SchemaItems: React.FunctionComponent = ({ isArray schemaName={`${idx + 1} item:`} key={idx} - recursionCounter={recursionCounter + 1} /> ))} @@ -44,7 +41,6 @@ export const SchemaItems: React.FunctionComponent = ({ schema={items} isArray schemaName="Items:" - recursionCounter={recursionCounter + 1} /> ); }; diff --git a/library/src/components/Payload/SchemaProperties.tsx b/library/src/components/Payload/SchemaProperties.tsx index aa87516ef..2e3e0272f 100644 --- a/library/src/components/Payload/SchemaProperties.tsx +++ b/library/src/components/Payload/SchemaProperties.tsx @@ -5,12 +5,11 @@ import { Payload } from './Payload'; interface SchemaPropertiesProps { schema: SchemaInterface; - recursionCounter?: number; } export const SchemaProperties: React.FunctionComponent< SchemaPropertiesProps -> = ({ schema, recursionCounter = 0 }) => { +> = ({ schema}) => { const properties = schema.properties(); if (properties === undefined || !Object.keys(properties)) { return null; @@ -33,7 +32,6 @@ export const SchemaProperties: React.FunctionComponent< schema, )} key={propertyName} - recursionCounter={recursionCounter + 1} /> ))} {Object.entries(patternProperties ?? {}).map( @@ -45,7 +43,6 @@ export const SchemaProperties: React.FunctionComponent< isProperty isCircular={property.isCircular()} key={propertyName} - recursionCounter={recursionCounter + 1} /> ), )} diff --git a/library/src/containers/Operations/Operation.tsx b/library/src/containers/Operations/Operation.tsx index cb1b76bf6..91cf09819 100644 --- a/library/src/containers/Operations/Operation.tsx +++ b/library/src/containers/Operations/Operation.tsx @@ -53,12 +53,13 @@ export const Operation: React.FunctionComponent = (props) => { {servers.map((server) => (
  • + MEOW {server.id()}
  • diff --git a/library/src/helpers/schema.ts b/library/src/helpers/schema.ts index 24daa918c..262d6826e 100644 --- a/library/src/helpers/schema.ts +++ b/library/src/helpers/schema.ts @@ -466,14 +466,14 @@ export class SchemaHelpers { let numberRange; if (hasMin && hasMax) { - // below is code for "[ 0 .. 1 ]"" + // Alternative number range format: "[ 0 .. 1 ]" // numberRange = hasExclusiveMin ? '( ' : '[ '; // numberRange += hasExclusiveMin ? exclusiveMin : min; // numberRange += ' .. '; // numberRange += hasExclusiveMax ? exclusiveMax : max; // numberRange += hasExclusiveMax ? ' )' : ' ]'; - // below is code for "0 <= value <= 1" + // Alternative number range format: "0 <= value <= 1" numberRange = ''; numberRange += hasExclusiveMin ? exclusiveMin : min; numberRange += hasExclusiveMin ? ' < ' : ' <= '; @@ -630,29 +630,4 @@ export class SchemaHelpers { dependentSchemas ); } - - // checks if any of the nested schema children has got conditions in it - // public static childrenHaveConditions( - // schema: SchemaInterface, - // visited: WeakSet = new WeakSet(), - // ): boolean { - // if (visited.has(schema)) { - // return false; - // } - // visited.add(schema); - // const children = schema.properties(); - // if (!children) { - // return false; - // } - // const childArray = Object.values(children); - // for (const child of childArray) { - // if ( - // this.hasConditions(child) || - // this.childrenHaveConditions(child, visited) - // ) { - // return true; - // } - // } - // return false; - // } } diff --git a/library/src/hooks/useElementSize.tsx b/library/src/hooks/useElementSize.tsx deleted file mode 100644 index 24c4e40a2..000000000 --- a/library/src/hooks/useElementSize.tsx +++ /dev/null @@ -1,48 +0,0 @@ -// import { useCallback, useEffect, useLayoutEffect, useState } from 'react'; -// export interface Size { -// width: number; -// height: number; -// } - -// /** -// * `useElementSize` is a hook to measure the size of a DOM element. -// * It tracks the width and height of the element and updates them on window resize or element changes. -// * -// * @param ref - The React ref object attached to the element to measure. -// * @return - An object containing the `width` and `height` of the element. -// */ - -// function useElementSize(): [ -// (node: T | null) => void, -// Size, -// ] { -// const [ref, setRef] = useState(null); -// const [size, setSize] = useState({ width: 0, height: 0 }); - -// const handleSize = useCallback(() => { -// if (ref) { -// setSize({ -// width: ref.offsetWidth, -// height: ref.offsetHeight, -// }); -// } -// }, [ref]); - -// const useEnviromentEffect = -// typeof window !== 'undefined' ? useLayoutEffect : useEffect; - -// useEnviromentEffect(() => { -// if (!ref) return; - -// handleSize(); - -// const resizeObserver = new ResizeObserver(handleSize); -// resizeObserver.observe(ref); - -// return () => resizeObserver.disconnect(); -// }, [ref, handleSize]); - -// return [setRef, size]; -// } - -// export { useElementSize }; diff --git a/playground/app/page.tsx b/playground/app/page.tsx index 9d155905a..66c128f42 100644 --- a/playground/app/page.tsx +++ b/playground/app/page.tsx @@ -18,8 +18,6 @@ import { defaultConfig, parse, debounce } from '@/utils'; import * as specs from '@/specs'; const defaultSchema = specs.streetlights; -// const defaultSchema = specs.overcomplicatedStreetlights; -// const defaultSchema = specs.complexSchema; interface State { schema: string; From d70336defac7a3184888dab63f3bfeb95eeec1c9 Mon Sep 17 00:00:00 2001 From: catosaurusrex2003 Date: Fri, 28 Feb 2025 02:53:15 +0530 Subject: [PATCH 28/41] code quality improved --- library/src/components/Payload/Payload.tsx | 32 +++++++--------------- 1 file changed, 10 insertions(+), 22 deletions(-) diff --git a/library/src/components/Payload/Payload.tsx b/library/src/components/Payload/Payload.tsx index d7c5332ea..aac9877cc 100644 --- a/library/src/components/Payload/Payload.tsx +++ b/library/src/components/Payload/Payload.tsx @@ -68,6 +68,10 @@ export const Payload: React.FunctionComponent = ({ } }, [isArray, deepExpand, setExpanded]); + useEffect(() => { + if (!rulesExist) setTabOpen('CONDITIONS'); + }, []); + if ( !schema || (typeof schemaName === 'string' && @@ -112,10 +116,6 @@ export const Payload: React.FunctionComponent = ({ const isExpandable = SchemaHelpers.isExpandable(schema) || rulesExist || conditionsExist; - useEffect(() => { - if (!rulesExist) setTabOpen('CONDITIONS'); - }, []); - return ( = ({
    {/* Expandable Content */} {!isCircular && isExpandable && expanded && ( -
    +
    {/* Properties Section */} - + {/* Array Items Section */} - +
    @@ -288,18 +282,12 @@ export const Payload: React.FunctionComponent = ({ {/* Additional Properties/Items Section */}
    - - + +
    {/* Extensions Section */} - +
    )}
    From 6653b294a527547a5066d0f8275e57020e017f51 Mon Sep 17 00:00:00 2001 From: catosaurusrex2003 Date: Mon, 10 Mar 2025 16:19:41 +0530 Subject: [PATCH 29/41] testing --- library/src/components/Payload/Payload.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/library/src/components/Payload/Payload.tsx b/library/src/components/Payload/Payload.tsx index aac9877cc..4b48bb9dd 100644 --- a/library/src/components/Payload/Payload.tsx +++ b/library/src/components/Payload/Payload.tsx @@ -37,6 +37,7 @@ const PayloadSchemaContext = React.createContext({ deepExpanded: false, }); + export const Payload: React.FunctionComponent = ({ schemaName, schema, From 286e4c0cd2ea0e2bd98f3da2db2bd8567cd86df5 Mon Sep 17 00:00:00 2001 From: catosaurusrex2003 Date: Mon, 10 Mar 2025 16:57:14 +0530 Subject: [PATCH 30/41] number range test cases --- library/src/helpers/__tests__/schema.test.ts | 12 +++++------ library/src/helpers/schema.ts | 21 ++++++++------------ 2 files changed, 14 insertions(+), 19 deletions(-) diff --git a/library/src/helpers/__tests__/schema.test.ts b/library/src/helpers/__tests__/schema.test.ts index 637674997..e60997db0 100644 --- a/library/src/helpers/__tests__/schema.test.ts +++ b/library/src/helpers/__tests__/schema.test.ts @@ -219,37 +219,37 @@ describe('SchemaHelpers', () => { test('should handle number/integer inclusive range', () => { const schema = new Schema({ minimum: 2, maximum: 5 }); const result = SchemaHelpers.humanizeConstraints(schema); - expect(result).toEqual(['[ 2 .. 5 ]']); + expect(result).toEqual(['2 <= value <= 5']); }); test('should handle number/integer exclusive range', () => { const schema = new Schema({ minimum: 2, exclusiveMaximum: 5 }); const result = SchemaHelpers.humanizeConstraints(schema); - expect(result).toEqual(['[ 2 .. 5 )']); + expect(result).toEqual(['2 <= value < 5']); }); test('should handle inclusive minimum', () => { const schema = new Schema({ minimum: 2 }); const result = SchemaHelpers.humanizeConstraints(schema); - expect(result).toEqual(['>= 2']); + expect(result).toEqual(['2 <= value']); }); test('should handle inclusive maximum', () => { const schema = new Schema({ maximum: 2 }); const result = SchemaHelpers.humanizeConstraints(schema); - expect(result).toEqual(['<= 2']); + expect(result).toEqual(['value <= 2']); }); test('should handle exclusive minimum', () => { const schema = new Schema({ exclusiveMinimum: 5 }); const result = SchemaHelpers.humanizeConstraints(schema); - expect(result).toEqual(['> 5']); + expect(result).toEqual(['5 < value']); }); test('should handle exclusive maximum', () => { const schema = new Schema({ exclusiveMaximum: 5 }); const result = SchemaHelpers.humanizeConstraints(schema); - expect(result).toEqual(['< 5']); + expect(result).toEqual(['value < 5']); }); test('should handle integer multipleOf', () => { diff --git a/library/src/helpers/schema.ts b/library/src/helpers/schema.ts index 262d6826e..7b35f0fc3 100644 --- a/library/src/helpers/schema.ts +++ b/library/src/helpers/schema.ts @@ -466,14 +466,7 @@ export class SchemaHelpers { let numberRange; if (hasMin && hasMax) { - // Alternative number range format: "[ 0 .. 1 ]" - // numberRange = hasExclusiveMin ? '( ' : '[ '; - // numberRange += hasExclusiveMin ? exclusiveMin : min; - // numberRange += ' .. '; - // numberRange += hasExclusiveMax ? exclusiveMax : max; - // numberRange += hasExclusiveMax ? ' )' : ' ]'; - - // Alternative number range format: "0 <= value <= 1" + // number range format: "0 <= value <= 1" numberRange = ''; numberRange += hasExclusiveMin ? exclusiveMin : min; numberRange += hasExclusiveMin ? ' < ' : ' <= '; @@ -481,13 +474,15 @@ export class SchemaHelpers { numberRange += hasExclusiveMax ? ' < ' : ' <= '; numberRange += hasExclusiveMax ? exclusiveMax : max; } else if (hasMin) { - numberRange = 'value '; - numberRange += hasExclusiveMin ? '> ' : '>= '; + numberRange = ''; numberRange += hasExclusiveMin ? exclusiveMin : min; + numberRange += hasExclusiveMin ? ' < ' : ' <= '; + numberRange += 'value'; } else if (hasMax) { - numberRange = 'value '; - numberRange = hasExclusiveMax ? '< ' : '<= '; - numberRange += 'value ' + hasExclusiveMax ? exclusiveMax : max; + numberRange = ''; + numberRange += 'value'; + numberRange += hasExclusiveMax ? ' < ' : ' <= '; + numberRange += hasExclusiveMax ? exclusiveMax : max; } return numberRange; } From bbee4d9268d5edeeaa69b90b094d2a337f810356 Mon Sep 17 00:00:00 2001 From: catosaurusrex2003 Date: Tue, 11 Mar 2025 23:30:06 +0530 Subject: [PATCH 31/41] other tests added --- .../components/__tests__/Bindings.test.tsx | 18 ++++++++++--- .../components/__tests__/Extensions.test.tsx | 18 ++++++++----- .../src/components/__tests__/Schema.test.tsx | 27 ++++++++++++++++--- 3 files changed, 49 insertions(+), 14 deletions(-) diff --git a/library/src/components/__tests__/Bindings.test.tsx b/library/src/components/__tests__/Bindings.test.tsx index b7321dee3..2214dcd27 100644 --- a/library/src/components/__tests__/Bindings.test.tsx +++ b/library/src/components/__tests__/Bindings.test.tsx @@ -5,7 +5,7 @@ /* eslint-disable sonarjs/no-duplicate-string */ import React from 'react'; -import { render, screen } from '@testing-library/react'; +import { fireEvent, render, screen } from '@testing-library/react'; import { BindingV2 as BindingSchema, BindingsV2 as BindingsSchema, @@ -41,14 +41,19 @@ describe('Bindings component', () => { }; render(); + const expandAllButtons = screen.getAllByRole('button', { + name: 'Expand all', + }); + expandAllButtons.forEach((button) => fireEvent.click(button)); + expect(screen.getAllByText('Binding specific information')).toBeDefined(); expect(screen.getAllByText('Binding specific information')).toHaveLength(2); expect(screen.getByText('mqtt')).toBeDefined(); expect(screen.getByText('fooMqtt')).toBeDefined(); - expect(screen.getByText('barMqtt')).toBeDefined(); + expect(screen.getByText('"barMqtt"')).toBeDefined(); expect(screen.getByText('kafka')).toBeDefined(); expect(screen.getByText('fooKafka')).toBeDefined(); - expect(screen.getByText('barKafka')).toBeDefined(); + expect(screen.getByText('"barKafka"')).toBeDefined(); }); test('should render empty binding as string', () => { @@ -61,11 +66,16 @@ describe('Bindings component', () => { }; render(); + const expandAllButtons = screen.getAllByRole('button', { + name: 'Expand all', + }); + expandAllButtons.forEach((button) => fireEvent.click(button)); + expect(screen.getAllByText('Binding specific information')).toBeDefined(); expect(screen.getAllByText('Binding specific information')).toHaveLength(3); expect(screen.getByText('mqtt')).toBeDefined(); expect(screen.getByText('foo')).toBeDefined(); - expect(screen.getByText('bar')).toBeDefined(); + expect(screen.getByText('"bar"')).toBeDefined(); expect(screen.getByText('kafka')).toBeDefined(); expect(screen.getByText('http')).toBeDefined(); expect(screen.queryByText('undefined')).toEqual(null); diff --git a/library/src/components/__tests__/Extensions.test.tsx b/library/src/components/__tests__/Extensions.test.tsx index d7e5e5e41..bd7176128 100644 --- a/library/src/components/__tests__/Extensions.test.tsx +++ b/library/src/components/__tests__/Extensions.test.tsx @@ -3,7 +3,7 @@ */ import React from 'react'; -import { render, screen } from '@testing-library/react'; +import { fireEvent, render, screen } from '@testing-library/react'; import { SchemaV2 as SchemaModel } from '@asyncapi/parser'; @@ -18,11 +18,13 @@ describe('Extensions component', () => { const schemaModel = new SchemaModel(schema); render(); + fireEvent.click(screen.getByRole('button', { name: 'Expand all' })); + expect(screen.getByText('Extensions')).toBeDefined(); expect(screen.getByText('x-foo')).toBeDefined(); - expect(screen.getByText('xBar')).toBeDefined(); + expect(screen.getByText('"xBar"')).toBeDefined(); expect(screen.getByText('x-bar')).toBeDefined(); - expect(screen.getByText('xFoo')).toBeDefined(); + expect(screen.getByText('"xFoo"')).toBeDefined(); }); test('should filter non extensions', () => { @@ -38,12 +40,14 @@ describe('Extensions component', () => { }; const schemaModel = new SchemaModel(schema); render(); + + fireEvent.click(screen.getByRole('button', { name: 'Expand all' })); expect(screen.getByText('Extensions')).toBeDefined(); expect(screen.getByText('x-foo')).toBeDefined(); - expect(screen.getByText('xBar')).toBeDefined(); + expect(screen.getByText('"xBar"')).toBeDefined(); expect(screen.getByText('x-bar')).toBeDefined(); - expect(screen.getByText('xFoo')).toBeDefined(); + expect(screen.getByText('"xFoo"')).toBeDefined(); expect(screen.queryByText('foo')).toEqual(null); expect(screen.queryByText('bar')).toEqual(null); }); @@ -57,9 +61,11 @@ describe('Extensions component', () => { const schemaModel = new SchemaModel(schema); render(); + fireEvent.click(screen.getByRole('button', { name: 'Expand all' })); + expect(screen.getByText('Extensions')).toBeDefined(); expect(screen.getByText('x-foo')).toBeDefined(); - expect(screen.getByText('xBar')).toBeDefined(); + expect(screen.getByText('"xBar"')).toBeDefined(); expect(screen.getByText('x-bar')).toBeDefined(); expect(screen.getByText('x-foobar')).toBeDefined(); expect(screen.queryByText('undefined')).toEqual(null); diff --git a/library/src/components/__tests__/Schema.test.tsx b/library/src/components/__tests__/Schema.test.tsx index 9222fbffc..6b668390a 100644 --- a/library/src/components/__tests__/Schema.test.tsx +++ b/library/src/components/__tests__/Schema.test.tsx @@ -3,9 +3,8 @@ */ import React from 'react'; -import { render, screen } from '@testing-library/react'; +import { fireEvent, render, screen } from '@testing-library/react'; import { SchemaV2 as SchemaModel } from '@asyncapi/parser'; - import { Schema } from '../Schema'; describe('Schema component', () => { @@ -41,6 +40,8 @@ describe('Schema component', () => { render(); + fireEvent.click(screen.getByRole('button', { name: 'Expand all' })); + // properties expect(screen.getByText('nonCircular')).toBeDefined(); expect(screen.getByText('circular')).toBeDefined(); @@ -69,6 +70,8 @@ describe('Schema component', () => { render(); + fireEvent.click(screen.getByRole('button', { name: 'Expand all' })); + expect(screen.getByText('true')).toBeDefined(); expect(screen.getByText('false')).toBeDefined(); }); @@ -91,6 +94,12 @@ describe('Schema component', () => { render(); + fireEvent.click(screen.getByRole('button', { name: 'Expand all' })); + + const constantValueElements = screen.getAllByText('Constant value:'); + expect(constantValueElements).toBeDefined(); + expect(constantValueElements).toHaveLength(2); + expect(screen.getByText('true')).toBeDefined(); expect(screen.getByText('false')).toBeDefined(); }); @@ -147,8 +156,18 @@ describe('Schema component', () => { render(); - expect(screen.getByText('Adheres to Cat:')).toBeDefined(); - expect(screen.getByText('Or to Dog:')).toBeDefined(); + fireEvent.click(screen.getByRole('button', { name: 'Expand all' })); + + fireEvent.click(screen.getByRole('button', { name: 'Expand all' })); + + expect( + screen.getAllByRole('heading', { + name: /can be one of the following/i, + }), + ).toBeDefined(); + + expect(screen.getByText('Cat:')).toBeDefined(); + expect(screen.getByText('Dog:')).toBeDefined(); }); }); }); From 9204c8fc98280d3910e11a2e5408a1c893e395ca Mon Sep 17 00:00:00 2001 From: catosaurusrex2003 Date: Tue, 25 Mar 2025 20:14:35 +0530 Subject: [PATCH 32/41] correct linting --- .../components/Payload/AdditionalItems.tsx | 7 +--- .../Payload/Conditions/Conditions.tsx | 30 +++------------ .../Payload/FeildStatusIndicators.tsx | 16 +++++--- library/src/components/Payload/Payload.tsx | 9 ++--- .../src/components/Payload/SchemaItems.tsx | 8 +--- .../components/Payload/SchemaProperties.tsx | 2 +- .../components/__tests__/Extensions.test.tsx | 12 ++++-- .../src/components/__tests__/Schema.test.tsx | 14 ++++--- library/src/containers/AsyncApi/Layout.tsx | 38 +++++++++---------- library/src/helpers/schema.ts | 6 ++- playground/specs/complex-schema.ts | 2 +- 11 files changed, 66 insertions(+), 78 deletions(-) diff --git a/library/src/components/Payload/AdditionalItems.tsx b/library/src/components/Payload/AdditionalItems.tsx index 6594932d4..1e9b5cb1e 100644 --- a/library/src/components/Payload/AdditionalItems.tsx +++ b/library/src/components/Payload/AdditionalItems.tsx @@ -42,10 +42,5 @@ export const AdditionalItems: React.FunctionComponent = ({ ); } // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment - return ( - - ); + return ; }; diff --git a/library/src/components/Payload/Conditions/Conditions.tsx b/library/src/components/Payload/Conditions/Conditions.tsx index 064c95ba2..0a4b641dc 100644 --- a/library/src/components/Payload/Conditions/Conditions.tsx +++ b/library/src/components/Payload/Conditions/Conditions.tsx @@ -8,10 +8,7 @@ interface ConditionsProps { dependentSchemas?: SchemaInterface; } -export const Conditions = ({ - schema, - dependentSchemas, -}: ConditionsProps) => { +export const Conditions = ({ schema, dependentSchemas }: ConditionsProps) => { return (
    {schema.oneOf()?.length && ( @@ -81,10 +78,7 @@ export const Conditions = ({ )} {schema.not() && ( - + )} {schema.propertyNames() && ( @@ -104,31 +98,19 @@ export const Conditions = ({ {schema.if() && (
    {schema.if() && ( - + )} {schema.then() && ( - + )} {schema.else() && ( - + )}
    )} {dependentSchemas && ( - + )}
    ); diff --git a/library/src/components/Payload/FeildStatusIndicators.tsx b/library/src/components/Payload/FeildStatusIndicators.tsx index 07994bfd5..4a6a16177 100644 --- a/library/src/components/Payload/FeildStatusIndicators.tsx +++ b/library/src/components/Payload/FeildStatusIndicators.tsx @@ -12,13 +12,19 @@ export const FeildStatusIndicator = ({ required = false, isPatternProperty, }: FeildStatusIndicatorProps) => { + const isRequired = required ?? false; + const isDeprecated = schema.deprecated() ?? false; + const isWriteOnly = schema.writeOnly() ?? false; + const isReadOnly = schema.readOnly() ?? false; + const isPattern = isPatternProperty ?? false; + return ( <> - {(required || - schema.deprecated() || - schema.writeOnly() || - schema.readOnly() || - isPatternProperty) && ( + {(isRequired || + isDeprecated || + isWriteOnly || + isReadOnly || + isPattern) && (
    {required && ( required diff --git a/library/src/components/Payload/Payload.tsx b/library/src/components/Payload/Payload.tsx index 4b48bb9dd..e37023f34 100644 --- a/library/src/components/Payload/Payload.tsx +++ b/library/src/components/Payload/Payload.tsx @@ -37,18 +37,17 @@ const PayloadSchemaContext = React.createContext({ deepExpanded: false, }); - export const Payload: React.FunctionComponent = ({ schemaName, schema, - showSchemaType = true, + // showSchemaType = true, required = false, isPatternProperty = false, isProperty = false, isCircular = false, - dependentRequired, + // dependentRequired, expanded: propExpanded = false, - onlyTitle = false, + // onlyTitle = false, isArray = false, // eslint-disable-next-line sonarjs/cognitive-complexity }) => { @@ -71,7 +70,7 @@ export const Payload: React.FunctionComponent = ({ useEffect(() => { if (!rulesExist) setTabOpen('CONDITIONS'); - }, []); + }, []); // eslint-disable-line react-hooks/exhaustive-deps if ( !schema || diff --git a/library/src/components/Payload/SchemaItems.tsx b/library/src/components/Payload/SchemaItems.tsx index 31d633f09..81689f87d 100644 --- a/library/src/components/Payload/SchemaItems.tsx +++ b/library/src/components/Payload/SchemaItems.tsx @@ -36,11 +36,5 @@ export const SchemaItems: React.FunctionComponent = ({ ); } - return ( - - ); + return ; }; diff --git a/library/src/components/Payload/SchemaProperties.tsx b/library/src/components/Payload/SchemaProperties.tsx index 2e3e0272f..3351b0f10 100644 --- a/library/src/components/Payload/SchemaProperties.tsx +++ b/library/src/components/Payload/SchemaProperties.tsx @@ -9,7 +9,7 @@ interface SchemaPropertiesProps { export const SchemaProperties: React.FunctionComponent< SchemaPropertiesProps -> = ({ schema}) => { +> = ({ schema }) => { const properties = schema.properties(); if (properties === undefined || !Object.keys(properties)) { return null; diff --git a/library/src/components/__tests__/Extensions.test.tsx b/library/src/components/__tests__/Extensions.test.tsx index bd7176128..032cc57cd 100644 --- a/library/src/components/__tests__/Extensions.test.tsx +++ b/library/src/components/__tests__/Extensions.test.tsx @@ -9,6 +9,10 @@ import { SchemaV2 as SchemaModel } from '@asyncapi/parser'; import { Extensions } from '../Extensions'; +const expandAll = () => { + fireEvent.click(screen.getByRole('button', { name: 'Expand all' })); +}; + describe('Extensions component', () => { test('should work with simple data', () => { const schema = { @@ -18,7 +22,7 @@ describe('Extensions component', () => { const schemaModel = new SchemaModel(schema); render(); - fireEvent.click(screen.getByRole('button', { name: 'Expand all' })); + expandAll(); expect(screen.getByText('Extensions')).toBeDefined(); expect(screen.getByText('x-foo')).toBeDefined(); @@ -40,8 +44,8 @@ describe('Extensions component', () => { }; const schemaModel = new SchemaModel(schema); render(); - - fireEvent.click(screen.getByRole('button', { name: 'Expand all' })); + + expandAll(); expect(screen.getByText('Extensions')).toBeDefined(); expect(screen.getByText('x-foo')).toBeDefined(); @@ -61,7 +65,7 @@ describe('Extensions component', () => { const schemaModel = new SchemaModel(schema); render(); - fireEvent.click(screen.getByRole('button', { name: 'Expand all' })); + expandAll(); expect(screen.getByText('Extensions')).toBeDefined(); expect(screen.getByText('x-foo')).toBeDefined(); diff --git a/library/src/components/__tests__/Schema.test.tsx b/library/src/components/__tests__/Schema.test.tsx index 6b668390a..d7eeb51ac 100644 --- a/library/src/components/__tests__/Schema.test.tsx +++ b/library/src/components/__tests__/Schema.test.tsx @@ -7,6 +7,10 @@ import { fireEvent, render, screen } from '@testing-library/react'; import { SchemaV2 as SchemaModel } from '@asyncapi/parser'; import { Schema } from '../Schema'; +const expandAll = () => { + fireEvent.click(screen.getByRole('button', { name: 'Expand all' })); +}; + describe('Schema component', () => { // eslint-disable-next-line jest/expect-expect test('should work with true schema', () => { @@ -40,7 +44,7 @@ describe('Schema component', () => { render(); - fireEvent.click(screen.getByRole('button', { name: 'Expand all' })); + expandAll(); // properties expect(screen.getByText('nonCircular')).toBeDefined(); @@ -70,7 +74,7 @@ describe('Schema component', () => { render(); - fireEvent.click(screen.getByRole('button', { name: 'Expand all' })); + expandAll(); expect(screen.getByText('true')).toBeDefined(); expect(screen.getByText('false')).toBeDefined(); @@ -94,7 +98,7 @@ describe('Schema component', () => { render(); - fireEvent.click(screen.getByRole('button', { name: 'Expand all' })); + expandAll(); const constantValueElements = screen.getAllByText('Constant value:'); expect(constantValueElements).toBeDefined(); @@ -156,9 +160,9 @@ describe('Schema component', () => { render(); - fireEvent.click(screen.getByRole('button', { name: 'Expand all' })); + expandAll(); - fireEvent.click(screen.getByRole('button', { name: 'Expand all' })); + expandAll(); expect( screen.getAllByRole('heading', { diff --git a/library/src/containers/AsyncApi/Layout.tsx b/library/src/containers/AsyncApi/Layout.tsx index 6409061c9..b6105b392 100644 --- a/library/src/containers/AsyncApi/Layout.tsx +++ b/library/src/containers/AsyncApi/Layout.tsx @@ -44,27 +44,27 @@ const AsyncApiLayout: React.FunctionComponent = ({ return ( -
    - -
    - {configShow.sidebar && } -
    -
    - {configShow.info && } - {configShow.servers && } - {configShow.operations && } - {configShow.messages && } - {configShow.schemas && } -
    -
    +
    + +
    + {configShow.sidebar && } +
    +
    + {configShow.info && } + {configShow.servers && } + {configShow.operations && } + {configShow.messages && } + {configShow.schemas && }
    +
    - -
    +
    + +
    ); diff --git a/library/src/helpers/schema.ts b/library/src/helpers/schema.ts index 7b35f0fc3..783335239 100644 --- a/library/src/helpers/schema.ts +++ b/library/src/helpers/schema.ts @@ -112,7 +112,7 @@ export class SchemaHelpers { otherCases: string, title?: string, ) { - var suffix = title ? ` ${title}:` : ':'; + let suffix = title ? ` ${title}:` : ':'; if (suffix.startsWith(' 0 || @@ -607,12 +608,14 @@ export class SchemaHelpers { schema.enum() || schema.default() !== undefined || schema.const() !== undefined + /* eslint-disable @typescript-eslint/prefer-nullish-coalescing */ ); } public static hasConditions(schema: SchemaInterface) { const dependentSchemas = this.getDependentSchemas(schema); return ( + /* eslint-disable @typescript-eslint/prefer-nullish-coalescing */ schema.oneOf()?.length || schema.anyOf()?.length || schema.allOf()?.length || @@ -623,6 +626,7 @@ export class SchemaHelpers { schema.then() || schema.else() || dependentSchemas + /* eslint-disable @typescript-eslint/prefer-nullish-coalescing */ ); } } diff --git a/playground/specs/complex-schema.ts b/playground/specs/complex-schema.ts index 9f4196367..f7d06e0ed 100644 --- a/playground/specs/complex-schema.ts +++ b/playground/specs/complex-schema.ts @@ -169,7 +169,7 @@ components: properties: phone: type: string - pattern: '^\+[1-9]\d{1,14}$' + pattern: '^+[1-9]d{1,14}$' - type: object properties: email: From 31357323da3f5fdf652ef9aff3b89e3ec69abb37 Mon Sep 17 00:00:00 2001 From: catosaurusrex2003 Date: Tue, 25 Mar 2025 20:30:07 +0530 Subject: [PATCH 33/41] weird prettier fail fix --- library/src/helpers/common.ts | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/library/src/helpers/common.ts b/library/src/helpers/common.ts index be2b2be91..c04d45828 100644 --- a/library/src/helpers/common.ts +++ b/library/src/helpers/common.ts @@ -76,8 +76,10 @@ export class CommonHelpers { borderColor: 'border-green-600 text-green-600', backgroundColor: 'bg-green-600', typeLabel: !isAsyncAPIv2 - ? (config.receiveLabel ?? RECEIVE_TEXT_LABEL_DEFAULT_TEXT) - : (config.publishLabel ?? PUBLISH_LABEL_DEFAULT_TEXT), + ? (config.receiveLabel ?? + RECEIVE_TEXT_LABEL_DEFAULT_TEXT) + : (config.publishLabel ?? + PUBLISH_LABEL_DEFAULT_TEXT), }; } if (type === PayloadType.REPLY) { @@ -98,8 +100,10 @@ export class CommonHelpers { borderColor: 'border-blue-600 text-blue-500', backgroundColor: 'bg-blue-600', typeLabel: !isAsyncAPIv2 - ? (config.sendLabel ?? SEND_LABEL_DEFAULT_TEXT) - : (config.subscribeLabel ?? SUBSCRIBE_LABEL_DEFAULT_TEXT), + ? (config.sendLabel ?? + SEND_LABEL_DEFAULT_TEXT) + : (config.subscribeLabel ?? + SUBSCRIBE_LABEL_DEFAULT_TEXT), }; } } From 28b6d244429bb158de5ad99b8fb65e9808876f41 Mon Sep 17 00:00:00 2001 From: catosaurusrex2003 Date: Tue, 25 Mar 2025 20:45:28 +0530 Subject: [PATCH 34/41] weird prettier fail fix 2 --- library/src/helpers/common.ts | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/library/src/helpers/common.ts b/library/src/helpers/common.ts index c04d45828..be2b2be91 100644 --- a/library/src/helpers/common.ts +++ b/library/src/helpers/common.ts @@ -76,10 +76,8 @@ export class CommonHelpers { borderColor: 'border-green-600 text-green-600', backgroundColor: 'bg-green-600', typeLabel: !isAsyncAPIv2 - ? (config.receiveLabel ?? - RECEIVE_TEXT_LABEL_DEFAULT_TEXT) - : (config.publishLabel ?? - PUBLISH_LABEL_DEFAULT_TEXT), + ? (config.receiveLabel ?? RECEIVE_TEXT_LABEL_DEFAULT_TEXT) + : (config.publishLabel ?? PUBLISH_LABEL_DEFAULT_TEXT), }; } if (type === PayloadType.REPLY) { @@ -100,10 +98,8 @@ export class CommonHelpers { borderColor: 'border-blue-600 text-blue-500', backgroundColor: 'bg-blue-600', typeLabel: !isAsyncAPIv2 - ? (config.sendLabel ?? - SEND_LABEL_DEFAULT_TEXT) - : (config.subscribeLabel ?? - SUBSCRIBE_LABEL_DEFAULT_TEXT), + ? (config.sendLabel ?? SEND_LABEL_DEFAULT_TEXT) + : (config.subscribeLabel ?? SUBSCRIBE_LABEL_DEFAULT_TEXT), }; } } From cd383526a414d5b2fac40d29d2c0cf9d3506ebed Mon Sep 17 00:00:00 2001 From: catosaurusrex2003 Date: Tue, 25 Mar 2025 20:51:46 +0530 Subject: [PATCH 35/41] remove parenthesis to fix prettier errors --- library/src/helpers/common.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/library/src/helpers/common.ts b/library/src/helpers/common.ts index be2b2be91..3a44bde57 100644 --- a/library/src/helpers/common.ts +++ b/library/src/helpers/common.ts @@ -76,8 +76,8 @@ export class CommonHelpers { borderColor: 'border-green-600 text-green-600', backgroundColor: 'bg-green-600', typeLabel: !isAsyncAPIv2 - ? (config.receiveLabel ?? RECEIVE_TEXT_LABEL_DEFAULT_TEXT) - : (config.publishLabel ?? PUBLISH_LABEL_DEFAULT_TEXT), + ? config.receiveLabel ?? RECEIVE_TEXT_LABEL_DEFAULT_TEXT + : config.publishLabel ?? PUBLISH_LABEL_DEFAULT_TEXT, }; } if (type === PayloadType.REPLY) { @@ -98,8 +98,8 @@ export class CommonHelpers { borderColor: 'border-blue-600 text-blue-500', backgroundColor: 'bg-blue-600', typeLabel: !isAsyncAPIv2 - ? (config.sendLabel ?? SEND_LABEL_DEFAULT_TEXT) - : (config.subscribeLabel ?? SUBSCRIBE_LABEL_DEFAULT_TEXT), + ? config.sendLabel ?? SEND_LABEL_DEFAULT_TEXT + : config.subscribeLabel ?? SUBSCRIBE_LABEL_DEFAULT_TEXT, }; } } From 83c3e053ed02f1218d72f04964956348f49a54d8 Mon Sep 17 00:00:00 2001 From: catosaurusrex2003 Date: Tue, 25 Mar 2025 20:59:04 +0530 Subject: [PATCH 36/41] inconsistencies fixed --- web-component/src/AsyncApiWebComponent.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web-component/src/AsyncApiWebComponent.tsx b/web-component/src/AsyncApiWebComponent.tsx index 8c2d5d8b8..9bcb139ab 100644 --- a/web-component/src/AsyncApiWebComponent.tsx +++ b/web-component/src/AsyncApiWebComponent.tsx @@ -39,7 +39,7 @@ function retrieveSchemaProp( // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment const schemaRequestOptions = schemaFetchOptions ? JSON.parse(JSON.stringify(schemaFetchOptions)) - : ((schema as FetchingSchemaInterface).requestOptions ?? {}); + : (schema as FetchingSchemaInterface).requestOptions ?? {}; // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment schema = { url: schemaUrl, requestOptions: schemaRequestOptions }; } From d27020ef1eee0c51118ddb9cfab794fdcdca36ea Mon Sep 17 00:00:00 2001 From: catosaurusrex2003 Date: Tue, 8 Apr 2025 23:02:46 +0530 Subject: [PATCH 37/41] removed old implementation of schema --- library/src/components/Bindings.tsx | 2 +- library/src/components/Extensions.tsx | 4 +- library/src/components/Schema.tsx | 537 ------------------ .../{Payload => Schema}/AdditionalItems.tsx | 4 +- .../AdditionalProperties.tsx | 4 +- .../Conditions/Conditions.tsx | 22 +- .../FeildStatusIndicators.tsx | 0 .../{Payload => Schema}/Rules/Rules.tsx | 0 .../Payload.tsx => Schema/Schema.tsx} | 10 +- .../{Payload => Schema}/SchemaItems.tsx | 8 +- .../{Payload => Schema}/SchemaProperties.tsx | 6 +- .../src/components/__tests__/Schema.test.tsx | 2 +- library/src/components/index.ts | 2 +- 13 files changed, 31 insertions(+), 570 deletions(-) delete mode 100644 library/src/components/Schema.tsx rename library/src/components/{Payload => Schema}/AdditionalItems.tsx (91%) rename library/src/components/{Payload => Schema}/AdditionalProperties.tsx (95%) rename library/src/components/{Payload => Schema}/Conditions/Conditions.tsx (83%) rename library/src/components/{Payload => Schema}/FeildStatusIndicators.tsx (100%) rename library/src/components/{Payload => Schema}/Rules/Rules.tsx (100%) rename library/src/components/{Payload/Payload.tsx => Schema/Schema.tsx} (97%) rename library/src/components/{Payload => Schema}/SchemaItems.tsx (81%) rename library/src/components/{Payload => Schema}/SchemaProperties.tsx (94%) diff --git a/library/src/components/Bindings.tsx b/library/src/components/Bindings.tsx index a6c8fcc39..7965e7862 100644 --- a/library/src/components/Bindings.tsx +++ b/library/src/components/Bindings.tsx @@ -1,6 +1,6 @@ /* eslint-disable @typescript-eslint/no-unsafe-assignment */ import React from 'react'; -import { Schema } from './Schema'; +import { Schema } from './Schema/Schema'; import { SchemaHelpers } from '../helpers'; import { BindingsInterface } from '@asyncapi/parser'; diff --git a/library/src/components/Extensions.tsx b/library/src/components/Extensions.tsx index f71ae4081..5894e613b 100644 --- a/library/src/components/Extensions.tsx +++ b/library/src/components/Extensions.tsx @@ -2,9 +2,7 @@ /* eslint-disable @typescript-eslint/no-unsafe-assignment */ import React, { useState } from 'react'; - -import { Schema } from './Schema'; - +import { Schema } from './Schema/Schema'; import { SchemaHelpers } from '../helpers'; import { useConfig, useSpec } from '../contexts'; import { CollapseButton } from './CollapseButton'; diff --git a/library/src/components/Schema.tsx b/library/src/components/Schema.tsx deleted file mode 100644 index 267fdc5e9..000000000 --- a/library/src/components/Schema.tsx +++ /dev/null @@ -1,537 +0,0 @@ -import React, { useState, useEffect, useContext } from 'react'; -import { SchemaInterface } from '@asyncapi/parser'; - -import { Href, CollapseButton, Markdown, Extensions } from './index'; -import { SchemaHelpers } from '../helpers'; -import { Payload } from './Payload/Payload'; - -interface Props { - schemaName?: React.ReactNode; - schema?: SchemaInterface; - required?: boolean; - isPatternProperty?: boolean; - isProperty?: boolean; - isCircular?: boolean; - dependentRequired?: string[]; - expanded?: boolean; - onlyTitle?: boolean; - isArray?: boolean; -} - -const SchemaContext = React.createContext({ - reverse: false, - deepExpanded: false, -}); - -export const Schema = Payload; - -export const SchemaOld: React.FunctionComponent = ({ - schemaName, - schema, - required = false, - isPatternProperty = false, - isProperty = false, - isCircular = false, - dependentRequired, - expanded: propExpanded = false, - onlyTitle = false, - isArray = false, - // eslint-disable-next-line sonarjs/cognitive-complexity -}) => { - const { reverse, deepExpanded } = useContext(SchemaContext); - const [expanded, setExpanded] = useState(propExpanded || isArray); - const [deepExpand, setDeepExpand] = useState(false); - - useEffect(() => { - if (!isArray) { - setDeepExpand(deepExpanded); - } - }, [isArray, deepExpanded, setDeepExpand]); - - useEffect(() => { - if (!isArray) { - setExpanded(deepExpand); - } - }, [isArray, deepExpand, setExpanded]); - - if ( - !schema || - (typeof schemaName === 'string' && - (schemaName?.startsWith('x-parser-') || - schemaName?.startsWith('x-schema-private-'))) - ) { - return null; - } - - const dependentSchemas = SchemaHelpers.getDependentSchemas(schema); - - const constraints = SchemaHelpers.humanizeConstraints(schema); - const externalDocs = schema.externalDocs(); - - const rawValueExt = schema.extensions().get(SchemaHelpers.extRawValue); - const rawValue = rawValueExt?.value() === true; - - const parameterLocationExt = schema - .extensions() - .get(SchemaHelpers.extParameterLocation); - const parameterLocation = parameterLocationExt?.value() === true; - - const schemaType = SchemaHelpers.toSchemaType(schema); - const isExpandable = SchemaHelpers.isExpandable(schema) || dependentSchemas; - - isCircular = isCircular || schema.isCircular() || false; - const uid = schema.$id(); - const styledSchemaName = isProperty ? 'italic' : ''; - const renderedSchemaName = - typeof schemaName === 'string' ? ( - - {schemaName} - - ) : ( - schemaName - ); - - return ( - -
    -
    -
    - {isExpandable && !isCircular && !isArray ? ( - <> - setExpanded((prev) => !prev)} - expanded={expanded} - > - {renderedSchemaName} - - - - ) : ( - - {schemaName} - - )} - {isPatternProperty && ( -
    - (pattern property) -
    - )} - {required &&
    required
    } - {dependentRequired && ( - <> -
    - required when defined: -
    -
    - {dependentRequired.join(', ')} -
    - - )} - {schema.deprecated() && ( -
    deprecated
    - )} - {schema.writeOnly() && ( -
    write-only
    - )} - {schema.readOnly() && ( -
    read-only
    - )} -
    - {rawValue ? ( -
    -
    - {SchemaHelpers.prettifyValue(schema.const(), false)} -
    -
    - ) : ( -
    -
    -
    - {isCircular ? `${schemaType} [CIRCULAR]` : schemaType} -
    -
    - {schema.format() && ( - - format: {schema.format()} - - )} - - {/* related to string */} - {schema.pattern() !== undefined && ( - - must match: {schema.pattern()} - - )} - {schema.contentMediaType() !== undefined && ( - - media type: {schema.contentMediaType()} - - )} - {schema.contentEncoding() !== undefined && ( - - encoding: {schema.contentEncoding()} - - )} - - {/* constraints */} - {!!constraints.length && - constraints.map((c) => ( - - {c} - - ))} - - {uid && !uid.startsWith(' - uid: {uid} - - )} -
    - - {schema.description() !== undefined && ( -
    - {schema.description()} -
    - )} - - {schema.default() !== undefined && ( -
    - Default value: - - {SchemaHelpers.prettifyValue(schema.default())} - -
    - )} - {schema.const() !== undefined && ( -
    - Const: - - {SchemaHelpers.prettifyValue(schema.const())} - -
    - )} - {schema.enum() && ( -
      - Allowed values:{' '} - {schema.enum()?.map((e, idx) => ( -
    • - {SchemaHelpers.prettifyValue(e)} -
    • - ))} -
    - )} - {parameterLocation && ( -
    - Parameter location:{' '} - - {parameterLocation} - -
    - )} - {externalDocs && ( - - - Documentation - - - )} - {schema.examples() && ( -
      - Examples values:{' '} - {schema.examples()?.map((e, idx) => ( -
    • - {SchemaHelpers.prettifyValue(e)} -
    • - ))} -
    - )} -
    -
    - )} -
    - - {isCircular || !isExpandable ? null : ( -
    - - - - {schema - .oneOf() - ?.map((s, idx) => ( - - ))} - {schema - .anyOf() - ?.map((s, idx) => ( - - ))} - {schema - .allOf() - ?.map((s, idx) => ( - - ))} - {schema.not() && ( - - )} - - {schema.propertyNames() && ( - - )} - {schema.contains() && ( - - )} - - {schema.if() && ( - - )} - {schema.then() && ( - - )} - {schema.else() && ( - - )} - - {dependentSchemas && ( - - )} - - - - - -
    - )} -
    -
    - ); -}; - -interface SchemaPropertiesProps { - schema: SchemaInterface; -} - -const SchemaProperties: React.FunctionComponent = ({ - schema, -}) => { - const properties = schema.properties(); - if (properties === undefined || !Object.keys(properties)) { - return null; - } - - const required = schema.required() ?? []; - const patternProperties = schema.patternProperties(); - - return ( - <> - {Object.entries(properties).map(([propertyName, property]) => ( - - ))} - {Object.entries(patternProperties ?? {}).map( - ([propertyName, property]) => ( - - ), - )} - - ); -}; - -interface AdditionalPropertiesProps { - schema: SchemaInterface; -} - -const AdditionalProperties: React.FunctionComponent< - AdditionalPropertiesProps -> = ({ schema }) => { - if ( - schema.extensions().get(SchemaHelpers.extRenderAdditionalInfo)?.value() === - false - ) { - return null; - } - - const type = schema.type(); - if (!type?.includes('object')) { - return null; - } - - const additionalProperties = schema.additionalProperties(); - if (additionalProperties === true || additionalProperties === undefined) { - return ( -

    - Additional properties are allowed. -

    - ); - } - if (additionalProperties === false) { - return ( -

    - Additional properties are NOT allowed. -

    - ); - } - return ( - - ); -}; - -interface SchemaItemsProps { - schema: SchemaInterface; -} - -const SchemaItems: React.FunctionComponent = ({ schema }) => { - const type = schema.type(); - if (!type?.includes('array')) { - return null; - } - const items = schema.items(); - - // object in items - if ( - items && - !Array.isArray(items) && - Object.keys(items.properties() ?? {}).length - ) { - return ; - } else if (Array.isArray(items)) { - return ( - <> - {items.map((item, idx) => ( - - ))} - - ); - } - return ; -}; - -interface AdditionalItemsProps { - schema: SchemaInterface; -} - -const AdditionalItems: React.FunctionComponent = ({ - schema, -}) => { - if ( - schema.extensions().get(SchemaHelpers.extRenderAdditionalInfo)?.value() === - false - ) { - return null; - } - - const type = schema.type(); - if (!type?.includes('array')) { - return null; - } - if (!Array.isArray(schema.items())) { - return null; - } - - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-explicit-any - const additionalItems = schema.additionalItems() as any; - if (additionalItems === true || additionalItems === undefined) { - return ( -

    - Additional items are allowed. -

    - ); - } - if (additionalItems === false) { - return ( -

    - Additional items are NOT allowed. -

    - ); - } - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment - return ; -}; diff --git a/library/src/components/Payload/AdditionalItems.tsx b/library/src/components/Schema/AdditionalItems.tsx similarity index 91% rename from library/src/components/Payload/AdditionalItems.tsx rename to library/src/components/Schema/AdditionalItems.tsx index 1e9b5cb1e..7bda52121 100644 --- a/library/src/components/Payload/AdditionalItems.tsx +++ b/library/src/components/Schema/AdditionalItems.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { SchemaInterface } from '@asyncapi/parser'; import { SchemaHelpers } from '../../helpers'; -import { Payload } from './Payload'; +import { Schema } from './Schema'; interface AdditionalItemsProps { schema: SchemaInterface; @@ -42,5 +42,5 @@ export const AdditionalItems: React.FunctionComponent = ({ ); } // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment - return ; + return ; }; diff --git a/library/src/components/Payload/AdditionalProperties.tsx b/library/src/components/Schema/AdditionalProperties.tsx similarity index 95% rename from library/src/components/Payload/AdditionalProperties.tsx rename to library/src/components/Schema/AdditionalProperties.tsx index 9c626a121..f0818942a 100644 --- a/library/src/components/Payload/AdditionalProperties.tsx +++ b/library/src/components/Schema/AdditionalProperties.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { SchemaInterface } from '@asyncapi/parser'; import { SchemaHelpers } from '../../helpers'; -import { Payload } from './Payload'; +import { Schema } from './Schema'; interface AdditionalPropertiesProps { schema: SchemaInterface; @@ -38,7 +38,7 @@ export const AdditionalProperties: React.FunctionComponent< ); } return ( - diff --git a/library/src/components/Payload/Conditions/Conditions.tsx b/library/src/components/Schema/Conditions/Conditions.tsx similarity index 83% rename from library/src/components/Payload/Conditions/Conditions.tsx rename to library/src/components/Schema/Conditions/Conditions.tsx index 0a4b641dc..78fdd2d8d 100644 --- a/library/src/components/Payload/Conditions/Conditions.tsx +++ b/library/src/components/Schema/Conditions/Conditions.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { SchemaInterface } from '@asyncapi/parser'; -import { Payload } from '../Payload'; +import { Schema } from '../Schema'; import { SchemaHelpers } from '../../../helpers'; interface ConditionsProps { @@ -19,7 +19,7 @@ export const Conditions = ({ schema, dependentSchemas }: ConditionsProps) => { {schema .oneOf() ?.map((s, idx) => ( - { {schema .anyOf() ?.map((s, idx) => ( - { {schema .allOf() ?.map((s, idx) => ( - { )} {schema.not() && ( - + )} {schema.propertyNames() && ( - )} {schema.contains() && ( - @@ -98,19 +98,19 @@ export const Conditions = ({ schema, dependentSchemas }: ConditionsProps) => { {schema.if() && (
    {schema.if() && ( - + )} {schema.then() && ( - + )} {schema.else() && ( - + )}
    )} {dependentSchemas && ( - + )}
    ); diff --git a/library/src/components/Payload/FeildStatusIndicators.tsx b/library/src/components/Schema/FeildStatusIndicators.tsx similarity index 100% rename from library/src/components/Payload/FeildStatusIndicators.tsx rename to library/src/components/Schema/FeildStatusIndicators.tsx diff --git a/library/src/components/Payload/Rules/Rules.tsx b/library/src/components/Schema/Rules/Rules.tsx similarity index 100% rename from library/src/components/Payload/Rules/Rules.tsx rename to library/src/components/Schema/Rules/Rules.tsx diff --git a/library/src/components/Payload/Payload.tsx b/library/src/components/Schema/Schema.tsx similarity index 97% rename from library/src/components/Payload/Payload.tsx rename to library/src/components/Schema/Schema.tsx index e37023f34..3568738f6 100644 --- a/library/src/components/Payload/Payload.tsx +++ b/library/src/components/Schema/Schema.tsx @@ -32,12 +32,12 @@ export interface Props { showConditionSidebar?: boolean; } -const PayloadSchemaContext = React.createContext({ +const SchemaContext = React.createContext({ reverse: false, deepExpanded: false, }); -export const Payload: React.FunctionComponent = ({ +export const Schema: React.FunctionComponent = ({ schemaName, schema, // showSchemaType = true, @@ -51,7 +51,7 @@ export const Payload: React.FunctionComponent = ({ isArray = false, // eslint-disable-next-line sonarjs/cognitive-complexity }) => { - const { reverse, deepExpanded } = useContext(PayloadSchemaContext); + const { reverse, deepExpanded } = useContext(SchemaContext); const [expanded, setExpanded] = useState(propExpanded || isArray); const [deepExpand, setDeepExpand] = useState(false); const [tabOpen, setTabOpen] = useState<'RULES' | 'CONDITIONS'>('RULES'); @@ -117,7 +117,7 @@ export const Payload: React.FunctionComponent = ({ SchemaHelpers.isExpandable(schema) || rulesExist || conditionsExist; return ( - = ({
    -
    + ); }; diff --git a/library/src/components/Payload/SchemaItems.tsx b/library/src/components/Schema/SchemaItems.tsx similarity index 81% rename from library/src/components/Payload/SchemaItems.tsx rename to library/src/components/Schema/SchemaItems.tsx index 81689f87d..22e91d1bf 100644 --- a/library/src/components/Payload/SchemaItems.tsx +++ b/library/src/components/Schema/SchemaItems.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { SchemaInterface } from '@asyncapi/parser'; -import { Payload } from './Payload'; +import { Schema } from './Schema'; interface SchemaItemsProps { schema: SchemaInterface; @@ -21,12 +21,12 @@ export const SchemaItems: React.FunctionComponent = ({ !Array.isArray(items) && Object.keys(items.properties() ?? {}).length ) { - return ; + return ; } else if (Array.isArray(items)) { return ( <> {items.map((item, idx) => ( - = ({ ); } - return ; + return ; }; diff --git a/library/src/components/Payload/SchemaProperties.tsx b/library/src/components/Schema/SchemaProperties.tsx similarity index 94% rename from library/src/components/Payload/SchemaProperties.tsx rename to library/src/components/Schema/SchemaProperties.tsx index 3351b0f10..6f54dcff0 100644 --- a/library/src/components/Payload/SchemaProperties.tsx +++ b/library/src/components/Schema/SchemaProperties.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { SchemaInterface } from '@asyncapi/parser'; import { SchemaHelpers } from '../../helpers'; -import { Payload } from './Payload'; +import { Schema } from './Schema'; interface SchemaPropertiesProps { schema: SchemaInterface; @@ -21,7 +21,7 @@ export const SchemaProperties: React.FunctionComponent< return ( <> {Object.entries(properties).map(([propertyName, property]) => ( - ( - { fireEvent.click(screen.getByRole('button', { name: 'Expand all' })); diff --git a/library/src/components/index.ts b/library/src/components/index.ts index 4fddf52ef..76eeb98d0 100644 --- a/library/src/components/index.ts +++ b/library/src/components/index.ts @@ -4,6 +4,6 @@ export * from './JSONSnippet'; export * from './Extensions'; export * from './Href'; export * from './Markdown'; -export * from './Schema'; +export * from './Schema/Schema'; export * from './Tag'; export * from './Tags'; From f3b5d3eaf34fdd8e60780d4c700e5c01ef70662d Mon Sep 17 00:00:00 2001 From: catosaurusrex2003 Date: Tue, 8 Apr 2025 23:08:41 +0530 Subject: [PATCH 38/41] newline --- library/src/components/Schema/AdditionalProperties.tsx | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/library/src/components/Schema/AdditionalProperties.tsx b/library/src/components/Schema/AdditionalProperties.tsx index f0818942a..c768b1686 100644 --- a/library/src/components/Schema/AdditionalProperties.tsx +++ b/library/src/components/Schema/AdditionalProperties.tsx @@ -38,9 +38,6 @@ export const AdditionalProperties: React.FunctionComponent< ); } return ( - + ); }; From 6e49a66e6d1cf8527ace65446938067c0c1f533b Mon Sep 17 00:00:00 2001 From: catosaurusrex2003 Date: Fri, 11 Apr 2025 19:25:45 +0530 Subject: [PATCH 39/41] removed useless css --- library/src/components/CollapseButton.tsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/library/src/components/CollapseButton.tsx b/library/src/components/CollapseButton.tsx index f8eb723d9..7f1d8f9fc 100644 --- a/library/src/components/CollapseButton.tsx +++ b/library/src/components/CollapseButton.tsx @@ -3,7 +3,6 @@ import React, { ButtonHTMLAttributes, SVGAttributes } from 'react'; interface Props extends ButtonHTMLAttributes { chevronProps?: SVGAttributes; expanded?: boolean; - rotateAngle?: number; } export const HiChevronRight = (props: SVGAttributes = {}) => ( @@ -30,7 +29,6 @@ export const CollapseButton: React.FunctionComponent = ({ chevronProps, expanded = false, children, - rotateAngle = 90, ...rest }) => ( From 3fb3a2fa6ec877a32296a435155e91879f717a91 Mon Sep 17 00:00:00 2001 From: catosaurusrex2003 Date: Fri, 11 Apr 2025 19:31:32 +0530 Subject: [PATCH 40/41] removed unused imports --- library/src/components/CollapseButton.tsx | 4 ++-- library/src/components/Schema/Schema.tsx | 8 +------- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/library/src/components/CollapseButton.tsx b/library/src/components/CollapseButton.tsx index 7f1d8f9fc..bea5a7a00 100644 --- a/library/src/components/CollapseButton.tsx +++ b/library/src/components/CollapseButton.tsx @@ -5,7 +5,7 @@ interface Props extends ButtonHTMLAttributes { expanded?: boolean; } -export const HiChevronRight = (props: SVGAttributes = {}) => ( +const HiChevronRight = (props: SVGAttributes = {}) => ( // Copied from https://icon-sets.iconify.design/heroicons-solid/chevron-right/ = ({ diff --git a/library/src/components/Schema/Schema.tsx b/library/src/components/Schema/Schema.tsx index 3568738f6..e5b347142 100644 --- a/library/src/components/Schema/Schema.tsx +++ b/library/src/components/Schema/Schema.tsx @@ -1,13 +1,7 @@ import React, { useState, useEffect, useContext } from 'react'; import { SchemaInterface } from '@asyncapi/parser'; -import { - Href, - CollapseButton, - Markdown, - Extensions, - // HiChevronRight, -} from '../index'; +import { Href, CollapseButton, Markdown, Extensions } from '../index'; import { SchemaHelpers } from '../../helpers'; import { SchemaItems } from './SchemaItems'; import { AdditionalItems } from './AdditionalItems'; From 9e1b8c1ace916deb5319f75730b909448e1daf16 Mon Sep 17 00:00:00 2001 From: catosaurusrex2003 Date: Sat, 24 May 2025 14:17:52 +0530 Subject: [PATCH 41/41] better script to run dev server --- library/package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/package.json b/library/package.json index b0132a263..639b8eaed 100644 --- a/library/package.json +++ b/library/package.json @@ -44,7 +44,7 @@ "./styles/default.min.css" ], "scripts": { - "start": "tsc -p tsconfig.esm.json --watch", + "start": "npm run build:styles:dev && tsc -p tsconfig.esm.json --watch", "build:dev": "npm run build:esm && npm run build:types && npm run build:styles", "build:prod": "npm run build:esm && npm run build:cjs && npm run build:umd && npm run build:standalone && npm run build:types && npm run build:styles", "build:esm": "tsc -p tsconfig.esm.json", @@ -117,4 +117,4 @@ "publishConfig": { "access": "public" } -} +} \ No newline at end of file