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

feat: custom extension rendering #994

Open
wants to merge 36 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
db17606
Custom extension value render
Apr 19, 2024
a52c230
Merge branch 'master' into feat/custom-extension-value-render
asyncapi-bot Apr 24, 2024
22f07b3
Add parent to ExtensionComponentProps and move changes to Extensions …
Apr 25, 2024
18654d2
Merge remote-tracking branch 'origin/feat/custom-extension-value-rend…
Apr 25, 2024
9b978b8
Address Sonar issue
Apr 25, 2024
de451e8
Merge branch 'master' into feat/custom-extension-value-render
ductaily Apr 30, 2024
13a8a6c
Apply suggestions from code review
ductaily Apr 30, 2024
23401a9
Clean up Extension class
Apr 30, 2024
6c4f19f
Merge branch 'refs/heads/master' into feat/custom-extension-value-render
May 2, 2024
37bc952
Merge branch 'master' into feat/custom-extension-value-render
ductaily May 2, 2024
3b19209
Merge remote-tracking branch 'origin/feat/custom-extension-value-rend…
May 2, 2024
95bfa86
Merge branch 'master' into feat/custom-extension-value-render
derberg May 13, 2024
8492e7a
Merge branch 'master' into feat/custom-extension-value-render
asyncapi-bot May 13, 2024
389e407
Merge remote-tracking branch 'origin/feat/custom-extension-value-rend…
May 13, 2024
973c1da
Address eslint errors
May 13, 2024
4b03c14
Fix handling of concatenatedConfig for extensions
May 21, 2024
3b548f5
Add config modification docs
May 21, 2024
cae5861
Add test
May 22, 2024
8caea6e
Add example for x-x extension
May 22, 2024
f986398
Add viewBox to x logo
May 22, 2024
979777d
Merge branch 'master' into feat/custom-extension-value-render
ductaily Jun 12, 2024
a34f50a
Update package-lock.json
Jun 19, 2024
32cf262
Fix lint error
Jun 19, 2024
c630f89
Merge branch 'master' into feat/custom-extension-value-render
pavelkornev Jun 19, 2024
eed70c4
Merge branch 'refs/heads/master' into feat/custom-extension-value-render
Jul 23, 2024
350646a
Merge remote-tracking branch 'origin/feat/custom-extension-value-rend…
Jul 23, 2024
d91df2a
Merge branch 'master' into feat/custom-extension-value-render
ductaily Jul 31, 2024
3e57a3f
Add x-x extensions example.
Jul 31, 2024
1740980
Merge branch 'master' into feat/custom-extension-value-render
asyncapi-bot Jul 31, 2024
361a2c2
Merge branch 'master' into feat/custom-extension-value-render
ductaily Sep 2, 2024
aa7423b
Merge branch 'master' into feat/custom-extension-value-render
pavelkornev Sep 2, 2024
8384cd8
Merge branch 'master' into feat/custom-extension-value-render
Dec 16, 2024
3563ab1
Add x-x extensions example in info component
Dec 17, 2024
df932da
Merge branch 'master' into feat/custom-extension-value-render
AceTheCreator Dec 19, 2024
a25f1d2
Address review comments
Dec 19, 2024
ec52216
Merge remote-tracking branch 'origin/feat/custom-extension-value-rend…
Dec 19, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 84 additions & 6 deletions library/src/components/Extensions.tsx
Original file line number Diff line number Diff line change
@@ -1,34 +1,112 @@
/* eslint-disable @typescript-eslint/no-unsafe-return */
/* eslint-disable @typescript-eslint/no-unsafe-assignment */

import React from 'react';
import React, { useContext, useState } from 'react';
ductaily marked this conversation as resolved.
Show resolved Hide resolved

import { Schema } from './Schema';

import { SchemaHelpers } from '../helpers';
import { AsyncAPIDocumentInterface, BaseModel } from '@asyncapi/parser';
import { useConfig, useSpec } from '../contexts';
import { CollapseButton } from './CollapseButton';

interface Props {
name?: string;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
item: any;
}

export interface ExtensionComponentProps<V = any> {
propertyName: string;
propertyValue: V;
document: AsyncAPIDocumentInterface;
parent: BaseModel;
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should probably move this to the types file.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I moved it into the types file

const SchemaContext = React.createContext({
reverse: false,
});
ductaily marked this conversation as resolved.
Show resolved Hide resolved

export const Extensions: React.FunctionComponent<Props> = ({
name = 'Extensions',
item,
}) => {
const { reverse } = useContext(SchemaContext);
ductaily marked this conversation as resolved.
Show resolved Hide resolved
const [expanded, setExpanded] = useState(false);
const [deepExpand, setDeepExpand] = useState(false);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This deepExpand is set but seems like an incomplete functionality. I think you should remove it if you don't see it adding any functionality to your changes.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with you. I removed deepExpand.


const config = useConfig();
const document = useSpec();

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

const schema = SchemaHelpers.jsonToSchema(extensions);
if (!config.extensions || !Object.keys(config.extensions).length) {
const schema = SchemaHelpers.jsonToSchema(extensions);
return (
schema && (
<div className="mt-2">
<Schema schemaName={name} schema={schema} onlyTitle={true} />
</div>
)
);
}

return (
schema && (
<div className="mt-2">
<Schema schemaName={name} schema={schema} onlyTitle />
<div>
<div className="flex py-2">
<div className="min-w-1/4">
<>
<CollapseButton
onClick={() => setExpanded(prev => !prev)}
expanded={expanded}
>
<span className={`break-anywhere text-sm ${name}`}>{name}</span>
</CollapseButton>
<button
type="button"
onClick={() => setDeepExpand(prev => !prev)}
className="ml-1 text-sm text-gray-500"
>
{deepExpand ? 'Collapse all' : 'Expand all'}
</button>
</>
</div>
</div>
<div
className={`rounded p-4 py-2 border bg-gray-100 ${
reverse ? 'bg-gray-200' : ''
} ${expanded ? 'block' : 'hidden'}`}
>
{Object.keys(extensions)
.sort((extension1, extension2) =>
extension1.localeCompare(extension2),
)
.map(extensionKey => {
if (config.extensions && config.extensions[extensionKey]) {
const CustomExtensionComponent = config.extensions[extensionKey];
return (
<CustomExtensionComponent
propertyName={extensionKey}
propertyValue={extensions[extensionKey]}
document={document}
parent={item}
/>
);
} else {
const extensionSchema = SchemaHelpers.jsonToSchema(
extensions[extensionKey],
);
return (
<div className="mt-2">
<Schema schemaName={extensionKey} schema={extensionSchema} />
</div>
);
}
})}
</div>
)
</div>
);
};
3 changes: 3 additions & 0 deletions library/src/config/config.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { ExtensionComponentProps } from '../components';

export interface ConfigInterface {
schemaID?: string;
show?: ShowConfig;
Expand All @@ -11,6 +13,7 @@ export interface ConfigInterface {
receiveLabel?: string;
requestLabel?: string;
replyLabel?: string;
extensions?: Record<string, React.ComponentType<ExtensionComponentProps>>;
}

export interface ShowConfig {
Expand Down
1 change: 1 addition & 0 deletions library/src/config/default.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,5 @@ export const defaultConfig: ConfigInterface = {
receiveLabel: RECEIVE_TEXT_LABEL_DEFAULT_TEXT,
requestLabel: REQUEST_LABEL_DEFAULT_TEXT,
replyLabel: REPLIER_LABEL_DEFAULT_TEXT,
extensions: {},
};
Loading