Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

React Components for extensions Catalog #819

Open
sambhavgupta0705 opened this issue Oct 18, 2023 · 16 comments
Open

React Components for extensions Catalog #819

sambhavgupta0705 opened this issue Oct 18, 2023 · 16 comments

Comments

@sambhavgupta0705
Copy link
Member

Description
As part of the "MVP integration of extensions catalog with AsyncAPI tools to make extension catalog useful" mentorhsip program, detailed here asyncapi/extensions-catalog#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 : asyncapi/extensions-catalog#112 ( we are still working on their format).

@github-actions
Copy link

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.

@sambhavgupta0705 sambhavgupta0705 changed the title React Components fot extensions Catalog React Components for extensions Catalog Oct 18, 2023
@magicmatatjahu
Copy link
Member

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:

  • 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.

  • inside Extensions component we try to retrieve the proper component for given extension:

    const { extensions } = useConfig()
    const ExtensionComponent = extensions[extension]

    of course we need to change the logic in the current Extensions component

  • 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

  • when registry won't have custom component, we should render extension as normal JSON Schema - like here https://github.com/asyncapi/asyncapi-react/blob/master/library/src/components/Extensions.tsx#L25

cc @derberg @Min2who @sambhavgupta0705

@derberg
Copy link
Member

derberg commented Nov 30, 2023

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

@sambhavgupta0705
Copy link
Member Author

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

@sambhavgupta0705
Copy link
Member Author

just a friendly reminder @magicmatatjahu

@magicmatatjahu
Copy link
Member

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

@sambhavgupta0705
Copy link
Member Author

@magicmatatjahu need more clarification on these two points

  • 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.
  • 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

@magicmatatjahu
Copy link
Member

magicmatatjahu commented Dec 15, 2023

@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
Copy link
Member Author

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
Copy link
Member

derberg commented Dec 21, 2023

@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
Copy link
Member

@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
Copy link
Contributor

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:

  • /good-first-issue {js | ts | java | go | docs | design | ci-cd} or /gfi {js | ts | java | go | docs | design | ci-cd} - label an issue as a good first issue.
    example: /gfi js or /good-first-issue ci-cd

Copy link

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

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 ❤️

@github-actions github-actions bot added the stale label Apr 21, 2024
@sambhavgupta0705
Copy link
Member Author

still relevant
I won't be working on this

Copy link

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

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 ❤️

@github-actions github-actions bot added the stale label Aug 21, 2024
@sambhavgupta0705
Copy link
Member Author

Still relevant

@github-actions github-actions bot removed the stale label Aug 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants