asyncapi / asyncapi-react

React component for rendering documentation from your specification in real-time in the browser. It also provides a WebComponent and bundle for Angular and Vue
https://asyncapi.github.io/asyncapi-react/
Apache License 2.0
174 stars 107 forks source link

React Components for extensions Catalog #819

Open sambhavgupta0705 opened 10 months ago

sambhavgupta0705 commented 10 months ago

Description As part of the "MVP integration of extensions catalog with AsyncAPI tools to make extension catalog useful" mentorhsip program, detailed here https://github.com/asyncapi/extensions-catalog/issues/78. We would like to add react component to visualize the extensions catalog.

Reasons

Extensions are part of the spec. So we need to create react component to compile theses extensions as a part of the AsyncAPI spec. So basically, this functionnality allow us to have suggestions on the existed extensions and to be able to add them when we are writing our code.

We would like to know how and where in the code would be the best way to provide extensions-related components. Now we are working on the twitter extension, we want to expose at the first time this one, you can check it here : https://github.com/asyncapi/extensions-catalog/pull/112 ( we are still working on their format).

github-actions[bot] commented 10 months ago

Welcome to AsyncAPI. Thanks a lot for reporting your first issue. Please check out our contributors guide and the instructions about a basic recommended setup useful for opening a pull request.
Keep in mind there are also other channels you can use to interact with AsyncAPI community. For more details check out this issue.

magicmatatjahu commented 9 months ago

The best place to write components will be there https://github.com/asyncapi/asyncapi-react/blob/master/library/src/components/Extensions.tsx However props to the component (root component, not mentioned in link) should have also option to pass custom components to render another extensions, written by user of component.

My idea:

cc @derberg @Min2who @sambhavgupta0705

derberg commented 9 months ago

sounds good to me, @sambhavgupta0705 feel free to ask more followup questions

sambhavgupta0705 commented 9 months ago

@magicmatatjahu is there any previous work or PR from which I can better understand about this

sambhavgupta0705 commented 9 months ago

just a friendly reminder @magicmatatjahu

magicmatatjahu commented 9 months ago

@sambhavgupta0705 Nope, maybe there was but I wasn't involved.

sambhavgupta0705 commented 8 months ago

@magicmatatjahu need more clarification on these two points

magicmatatjahu commented 8 months ago

@sambhavgupta0705

component has registry of extension components, like TwitterExtension - we can add extensions property on the config to the AsyncAPIComponent. It should be simple JS object.

To the AsyncAPIComponent you can pass config property, we need to extend shape (interface) of that property with extensions field so https://github.com/asyncapi/asyncapi-react/blob/master/library/src/config/config.ts#L1 should has additional field:

extensions: Record<string, React.ComponentType<ExtensionComponentProps>>;

Have in mind that types can be wrong, however I hope you will understand idea.

pass to the custom component, the extension value, asyncapi document, maybe also config passed to the root component and parent model (where extensions are defined) from parser-js

To the React components you can pass properties, we need to define ExtensionComponentProps interface with shape:

interface ExtensionComponentProps {
  key: string; // extension key
  value: any; // extension value
  document: AsyncAPIDocument // value from `useSpec()` hook
  config: ConfigInterface // config from `useConfig()` hook
  parent: any // parent model
}

so every extension component will have that values, passed from https://github.com/asyncapi/asyncapi-react/blob/master/library/src/components/Extensions.tsx component perspective.

Any additional questions?

sambhavgupta0705 commented 8 months ago

To the AsyncAPIComponent you can pass config property, we need to extend shape (interface) of that property with extensions field so https://github.com/asyncapi/asyncapi-react/blob/master/library/src/config/config.ts#L1 should has additional field:

for this I added extensions in configInterface is that correct?

image

derberg commented 8 months ago

@magicmatatjahu for MVP wouldn't it be better if by config, people just pass an array of extension names, and we internally handle it, understand and apply certain component? So MVP would be without enabling to pass a custom component to AsyncAPIComponent?

magicmatatjahu commented 8 months ago

@derberg @sambhavgupta0705

for MVP wouldn't it be better if by config, people just pass an array of extension names, and we internally handle it, understand and apply certain component? So MVP would be without enabling to pass a custom component to AsyncAPIComponent?

I would prefer to avoid this situation, because passing a map is as simple and uncomplicated as an array.

for this I added extensions in configInterface is that correct?

No, I added you good type:

extensions: Record<string, React.ComponentType<ExtensionComponentProps>>

then you should define type for properties for custom component (which is used above):

import type { AsyncAPIDocumentInterface, BaseModel } from "@asyncapi/parser"
import type { ConfigInterface } from "../config"

export interface ExtensionComponentProps<V = any> {
  key: string; // extension key
  value: V; // extension value
  document: AsyncAPIDocumentInterface // parsed spec
  config: ConfigInterface // config from `useConfig()` hook
  parent: BaseModel // parent model
}

define that type inside https://github.com/asyncapi/asyncapi-react/blob/master/library/src/components/Extensions.tsx file

Then you should write simple logic to retrieve given custom component for extension (inside https://github.com/asyncapi/asyncapi-react/blob/master/library/src/components/Extensions.tsx component). I added comments in places where you should write logic):

import React from 'react';

import { Schema } from './Schema';

import { SchemaHelpers } from '../helpers';
import { useConfig, useSpec } from '../contexts';

interface ExtensionsProps {
  name?: string;
  item: any;
}

export const Extensions: React.FunctionComponent<ExtensionsProps> = ({
  name = 'Extensions',
  item,
}) => {
  const config = useSpec();
  const document = useConfig();

  const extensionsValues = SchemaHelpers.getCustomExtensions(item);
  if (!extensionsValues || !Object.keys(extensionsValues).length) {
    return null;
  }

  const extensions = config.extensions;

  // you have config, document, parent model ("item" property).
  // you should make for loop to read all keys from "extensionsValues" and create ReactNode based on the key (the
  // component you should read from "extensions" dictionary). If you will have "undefined" for component 
  // (component won't exist), then you should use "Schema" component (used below) as the fallback

  // change return logic to render proper components
  const schema = SchemaHelpers.jsonToSchema(extensions);
  return (
    schema && (
      <div className="mt-2">
        <Schema schemaName={name} schema={schema} onlyTitle={true} />
      </div>
    )
  );
};
asyncapi-bot commented 8 months ago

Hello, @magicmatatjahu! 👋🏼

I'm 🧞🧞🧞 Genie 🧞🧞🧞 from the magic lamp. Looks like somebody needs a hand!

At the moment the following comments are supported in issues:

github-actions[bot] commented 4 months ago

This issue has been automatically marked as stale because it has not had recent activity :sleeping:

It will be closed in 120 days if no further activity occurs. To unstale this issue, add a comment with a detailed explanation.

There can be many reasons why some specific issue has no activity. The most probable cause is lack of time, not lack of interest. AsyncAPI Initiative is a Linux Foundation project not owned by a single for-profit company. It is a community-driven initiative ruled under open governance model.

Let us figure out together how to push this issue forward. Connect with us through one of many communication channels we established here.

Thank you for your patience :heart:

sambhavgupta0705 commented 4 months ago

still relevant I won't be working on this

github-actions[bot] commented 2 weeks ago

This issue has been automatically marked as stale because it has not had recent activity :sleeping:

It will be closed in 120 days if no further activity occurs. To unstale this issue, add a comment with a detailed explanation.

There can be many reasons why some specific issue has no activity. The most probable cause is lack of time, not lack of interest. AsyncAPI Initiative is a Linux Foundation project not owned by a single for-profit company. It is a community-driven initiative ruled under open governance model.

Let us figure out together how to push this issue forward. Connect with us through one of many communication channels we established here.

Thank you for your patience :heart:

sambhavgupta0705 commented 1 week ago

Still relevant