+
diff --git a/modelina-website/src/components/layouts/StickyNavbar.tsx b/modelina-website/src/components/layouts/StickyNavbar.tsx
index 98687b213c..411d977e7c 100644
--- a/modelina-website/src/components/layouts/StickyNavbar.tsx
+++ b/modelina-website/src/components/layouts/StickyNavbar.tsx
@@ -1,9 +1,3 @@
export default function StickyNavbar({ children, className = '' }: any) {
- return (
-
- {children}
-
- );
+ return
{children}
;
}
diff --git a/modelina-website/src/components/playground/Content.tsx b/modelina-website/src/components/playground/Content.tsx
index 465ed7bba3..c9c584a2d8 100644
--- a/modelina-website/src/components/playground/Content.tsx
+++ b/modelina-website/src/components/playground/Content.tsx
@@ -1,30 +1,24 @@
'use client';
-import { FunctionComponent, useMemo } from 'react';
-import { PlaygroundGeneratedContext } from '../contexts/PlaygroundGeneratedContext';
+import clsx from 'clsx';
+import type { FunctionComponent } from 'react';
+import { useMemo } from 'react';
+
import { usePlaygroundContext } from '../contexts/PlaygroundContext';
-import MonacoEditorWrapper from '../MonacoEditorWrapper';
+import { PlaygroundGeneratedContext } from '../contexts/PlaygroundGeneratedContext';
import CustomError from '../CustomError';
-import OutputNavigation from './OutputNavigation';
-import { OptionsNavigation } from './OptionsNavigation';
+import MonacoEditorWrapper from '../MonacoEditorWrapper';
import GeneratedModelsComponent from './GeneratedModels';
-import clsx from 'clsx';
+import { OptionsNavigation } from './OptionsNavigation';
+import OutputNavigation from './OutputNavigation';
interface ContentProps {
- setNewConfig: (
- config: string,
- configValue: any,
- updateCode?: boolean
- ) => void;
+ setNewConfig: (config: string, configValue: any, updateCode?: boolean) => void;
setNewQuery: (queryKey: string, queryValue: any) => void;
generateNewCode: (input: string) => void;
}
-export const Content: FunctionComponent
= ({
- setNewConfig,
- setNewQuery,
- generateNewCode
-}) => {
+export const Content: FunctionComponent = ({ setNewConfig, setNewQuery, generateNewCode }) => {
const {
config,
input,
@@ -49,36 +43,30 @@ export const Content: FunctionComponent = ({
);
return (
-
+
-
+
{
@@ -88,26 +76,21 @@ export const Content: FunctionComponent = ({
editorDidMount={() => {
setLoaded({ ...loaded, editorLoaded: true });
}}
- language="json"
+ language='json'
/>
{error ? (
) : (
-
+
)}
diff --git a/modelina-website/src/components/playground/GeneratedModels.tsx b/modelina-website/src/components/playground/GeneratedModels.tsx
index d20e95e990..c363323106 100644
--- a/modelina-website/src/components/playground/GeneratedModels.tsx
+++ b/modelina-website/src/components/playground/GeneratedModels.tsx
@@ -1,17 +1,15 @@
import React, { useContext, useEffect, useState } from 'react';
+
+import { usePlaygroundContext } from '../contexts/PlaygroundContext';
import { PlaygroundGeneratedContext } from '../contexts/PlaygroundGeneratedContext';
import MonacoEditorWrapper from '../MonacoEditorWrapper';
-import { usePlaygroundContext } from '../contexts/PlaygroundContext';
interface GeneratedModelsComponentProps {
showAllInOneFile?: boolean;
setNewQuery?: (queryKey: string, queryValue: any) => void;
}
-const GeneratedModelsComponent: React.FC = ({
- showAllInOneFile,
- setNewQuery,
-}) => {
+const GeneratedModelsComponent: React.FC = ({ showAllInOneFile, setNewQuery }) => {
const context = useContext(PlaygroundGeneratedContext);
const [selectedModel, setSelectedModel] = useState('');
const { setRenderModels, generatorCode, showGeneratorCode, setShowGeneratorCode } = usePlaygroundContext();
@@ -32,8 +30,9 @@ const GeneratedModelsComponent: React.FC = ({
}
}
- if (selectedCode === '' && (context.models && context.models.length > 0)) {
+ if (selectedCode === '' && context.models && context.models.length > 0) {
const defaultModel = context.models[0];
+
selectedCode = defaultModel.code;
updatedSelectedModel = defaultModel.name;
}
@@ -42,15 +41,17 @@ const GeneratedModelsComponent: React.FC = ({
return { selectedCode, updatedSelectedModel };
};
- const renderModels = (selectedModel = '') => {
+ const renderModels = (currentSelectedModel = '') => {
if (context?.models) {
return context?.models.map((model) => {
let backgroundColor;
- if (!showGeneratorCode && model.name === selectedModel) {
+
+ if (!showGeneratorCode && model.name === currentSelectedModel) {
backgroundColor = 'bg-[#3c4450]';
} else {
backgroundColor = '';
}
+
return (
= ({
setSelectedModel(model.name);
setShowGeneratorCode(false);
}}
- className={`${backgroundColor} hover:bg-[#4b5563] px-2 py-2 w-full text-left`}
+ className={`${backgroundColor} w-full p-2 text-left hover:bg-[#4b5563]`}
>
-
{model.name}
+ {model.name}
);
});
}
+
+ return null;
};
const { selectedCode, updatedSelectedModel } = toShow();
useEffect(() => {
const modelsToRender = renderModels(updatedSelectedModel);
+
setRenderModels(modelsToRender);
}, [updatedSelectedModel, showGeneratorCode]);
if (showAllInOneFile === true) {
return (
-
-
+
+
);
}
return (
-
-
+
+
= ({
);
};
-export default GeneratedModelsComponent;
\ No newline at end of file
+export default GeneratedModelsComponent;
diff --git a/modelina-website/src/components/playground/OptionsNavigation.tsx b/modelina-website/src/components/playground/OptionsNavigation.tsx
index 899c7d0d54..ad7bad7d59 100644
--- a/modelina-website/src/components/playground/OptionsNavigation.tsx
+++ b/modelina-website/src/components/playground/OptionsNavigation.tsx
@@ -1,20 +1,21 @@
-import React from "react";
+import React from 'react';
+
import {
- PlaygroundTypeScriptConfigContext,
+ PlaygroundCplusplusConfigContext,
PlaygroundCSharpConfigContext,
PlaygroundDartConfigContext,
+ PlaygroundGeneralConfigContext,
PlaygroundGoConfigContext,
PlaygroundJavaConfigContext,
PlaygroundJavaScriptConfigContext,
PlaygroundKotlinConfigContext,
+ PlaygroundPhpConfigContext,
PlaygroundPythonConfigContext,
- PlaygroundScalaConfigContext,
PlaygroundRustConfigContext,
- PlaygroundCplusplusConfigContext,
- PlaygroundGeneralConfigContext,
- PlaygroundPhpConfigContext
+ PlaygroundScalaConfigContext,
+ PlaygroundTypeScriptConfigContext
} from '../contexts/PlaygroundConfigContext';
-import { usePlaygroundContext } from "../contexts/PlaygroundContext";
+import { usePlaygroundContext } from '../contexts/PlaygroundContext';
import PlaygroundOptions from './PlaygroundOptions';
interface OptionsNavigationProps {
@@ -23,8 +24,9 @@ interface OptionsNavigationProps {
export const OptionsNavigation: React.FunctionComponent = ({ setNewConfig }) => {
const { config } = usePlaygroundContext();
+
return (
-
+
@@ -53,5 +55,5 @@ export const OptionsNavigation: React.FunctionComponent
- )
-}
+ );
+};
diff --git a/modelina-website/src/components/playground/OutputNavigation.tsx b/modelina-website/src/components/playground/OutputNavigation.tsx
index 700b00c8e6..87234cc8f6 100644
--- a/modelina-website/src/components/playground/OutputNavigation.tsx
+++ b/modelina-website/src/components/playground/OutputNavigation.tsx
@@ -1,26 +1,30 @@
-import { usePlaygroundContext } from "../contexts/PlaygroundContext";
-import InfoModal from "../InfoModal";
+import { usePlaygroundContext } from '../contexts/PlaygroundContext';
+import InfoModal from '../InfoModal';
-interface OutputProps { }
+interface OutputProps {}
const OutputNavigation: React.FunctionComponent
= () => {
const { renderModels, showGeneratorCode, setShowGeneratorCode } = usePlaygroundContext();
+
return (
-
-
+
+
-
-
-
- This list contains all the generated models, select one to show their generated code.
-
+
+
+ This list contains all the generated models, select one to show their generated code.
-
Generated Models
+
Generated Models
{renderModels}
- )
-}
+ );
+};
-export default OutputNavigation;
\ No newline at end of file
+export default OutputNavigation;
diff --git a/modelina-website/src/components/playground/Playground.tsx b/modelina-website/src/components/playground/Playground.tsx
index 5f269da3af..5843f5d6a1 100644
--- a/modelina-website/src/components/playground/Playground.tsx
+++ b/modelina-website/src/components/playground/Playground.tsx
@@ -1,22 +1,25 @@
-import React, { useEffect, useState } from 'react';
-import Router, { withRouter, NextRouter } from 'next/router';
import { encode } from 'js-base64';
-import { ModelinaQueryOptions, GenerateMessage, UpdateMessage } from '@/types';
-import { getTypeScriptGeneratorCode } from '@/helpers/GeneratorCode/TypeScriptGenerator';
-import { getJavaScriptGeneratorCode } from '@/helpers/GeneratorCode/JavaScriptGenerator';
-import { getJavaGeneratorCode } from '@/helpers/GeneratorCode/JavaGenerator';
-import { getGoGeneratorCode } from '@/helpers/GeneratorCode/GoGenerator';
+import type { NextRouter } from 'next/router';
+import Router, { withRouter } from 'next/router';
+import React, { useEffect, useState } from 'react';
+
+import { getCplusplusGeneratorCode } from '@/helpers/GeneratorCode/CplusplusGenerator';
import { getCSharpGeneratorCode } from '@/helpers/GeneratorCode/CSharpGenerator';
-import { getRustGeneratorCode } from '@/helpers/GeneratorCode/RustGenerator';
-import { getScalaGeneratorCode } from '@/helpers/GeneratorCode/ScalaGenerator';
-import { getPythonGeneratorCode } from '@/helpers/GeneratorCode/PythonGenerator';
import { getDartGeneratorCode } from '@/helpers/GeneratorCode/DartGenerator';
-import { getCplusplusGeneratorCode } from '@/helpers/GeneratorCode/CplusplusGenerator';
+import { getGoGeneratorCode } from '@/helpers/GeneratorCode/GoGenerator';
+import { getJavaGeneratorCode } from '@/helpers/GeneratorCode/JavaGenerator';
+import { getJavaScriptGeneratorCode } from '@/helpers/GeneratorCode/JavaScriptGenerator';
import { getKotlinGeneratorCode } from '@/helpers/GeneratorCode/KotlinGenerator';
import { getPhpGeneratorCode } from '@/helpers/GeneratorCode/PhpGenerator';
+import { getPythonGeneratorCode } from '@/helpers/GeneratorCode/PythonGenerator';
+import { getRustGeneratorCode } from '@/helpers/GeneratorCode/RustGenerator';
+import { getScalaGeneratorCode } from '@/helpers/GeneratorCode/ScalaGenerator';
+import { getTypeScriptGeneratorCode } from '@/helpers/GeneratorCode/TypeScriptGenerator';
+import type { GenerateMessage, ModelinaQueryOptions, UpdateMessage } from '@/types';
+
import { usePlaygroundContext } from '../contexts/PlaygroundContext';
-import { Sidebar } from './Sidebar';
import { Content } from './Content';
+import { Sidebar } from './Sidebar';
interface WithRouterProps {
router: NextRouter;
@@ -46,6 +49,92 @@ const Playground: React.FC
= (props) => {
// To avoid hydration error
const [isMounted, setIsMounted] = useState(false);
+ /**
+ * Tell the socket io server that we want some code
+ */
+ const generateNewCode = (inputArgs: string) => {
+ try {
+ const message: GenerateMessage = {
+ ...config,
+ input: encode(JSON.stringify(JSON.parse(inputArgs)))
+ };
+
+ if (message.input.length > (props.maxInputSize || 30000)) {
+ console.error('Input too large, use a smaller example');
+ setError(true);
+ setErrorMessage('Input too large, use a smaller example');
+ setStatusCode(400);
+ } else {
+ const generators: { [key: string]: Function } = {
+ typescript: getTypeScriptGeneratorCode,
+ javascript: getJavaScriptGeneratorCode,
+ java: getJavaGeneratorCode,
+ go: getGoGeneratorCode,
+ csharp: getCSharpGeneratorCode,
+ rust: getRustGeneratorCode,
+ scala: getScalaGeneratorCode,
+ python: getPythonGeneratorCode,
+ dart: getDartGeneratorCode,
+ cplusplus: getCplusplusGeneratorCode,
+ kotlin: getKotlinGeneratorCode,
+ php: getPhpGeneratorCode
+ };
+
+ const generatorCode = generators[config.language](message);
+
+ fetch(`${process.env.NEXT_PUBLIC_API_PATH}/generate`, {
+ body: JSON.stringify(message),
+ method: 'POST'
+ })
+ .then(async (res) => {
+ if (!res.ok) {
+ throw new Error(res.statusText);
+ }
+
+ const response: UpdateMessage = await res.json();
+
+ setGeneratorCode(generatorCode);
+ setModels(response.models);
+ setLoaded({
+ ...loaded,
+ hasReceivedCode: true
+ });
+ setError(false);
+ setStatusCode(200);
+ setErrorMessage('');
+ })
+ .catch((error) => {
+ console.error(error);
+ setError(true);
+ setErrorMessage('Input is not a correct AsyncAPI document, so it cannot be processed.');
+ setStatusCode(500);
+ });
+ }
+ } catch (e: any) {
+ console.error(e);
+ setError(true);
+ setErrorMessage('Input is not a correct AsyncAPI document, so it cannot be processed.');
+ setStatusCode(400);
+ }
+ };
+
+ /**
+ * Set a query key and value
+ */
+ const setNewQuery = (queryKey: string, queryValue: any) => {
+ const newQuery = {
+ query: { ...props.router.query }
+ };
+
+ if (queryValue === false) {
+ delete newQuery.query[queryKey];
+ } else {
+ newQuery.query[queryKey] = String(queryValue);
+ }
+
+ Router.push(newQuery, undefined, { scroll: false });
+ };
+
useEffect(() => {
setIsMounted(true);
}, []);
@@ -53,9 +142,11 @@ const Playground: React.FC = (props) => {
useEffect(() => {
const isHardLoaded = loaded.hasReceivedCode;
const isSoftLoaded = loaded.editorLoaded;
+
setIsLoaded(isHardLoaded && isSoftLoaded);
const query = props.router.query as ModelinaQueryOptions;
+
if (query.language !== undefined) {
setConfig({ ...config, language: query.language as any });
}
@@ -238,109 +329,14 @@ const Playground: React.FC = (props) => {
}
}, [props.router.isReady, hasLoadedQuery]);
- const setNewConfig = (
- configName: string,
- configValue: any,
- updateCode?: boolean
- ) => {
+ const setNewConfig = (configName: string, configValue: any, updateCode?: boolean) => {
setNewQuery(configName, configValue);
- /* eslint-disable-next-line security/detect-object-injection */
(config as any)[configName] = configValue;
if (updateCode === true || updateCode === undefined) {
generateNewCode(input);
}
};
- /**
- * Set a query key and value
- */
- const setNewQuery = (queryKey: string, queryValue: any) => {
- const newQuery = {
- query: { ...props.router.query }
- };
-
- if (queryValue === false) {
- delete newQuery.query[queryKey];
- } else {
- /* eslint-disable-next-line security/detect-object-injection */
- newQuery.query[queryKey] = String(queryValue);
- }
-
- Router.push(newQuery, undefined, { scroll: false });
- };
-
- /**
- * Tell the socket io server that we want some code
- */
- const generateNewCode = (input: string) => {
- try {
- const message: GenerateMessage = {
- ...config,
- input: encode(JSON.stringify(JSON.parse(input)))
- };
-
- if (message.input.length > (props.maxInputSize || 30000)) {
- console.error('Input too large, use a smaller example');
- setError(true);
- setErrorMessage('Input too large, use a smaller example');
- setStatusCode(400);
- } else {
- const generators: { [key: string]: Function } = {
- typescript: getTypeScriptGeneratorCode,
- javascript: getJavaScriptGeneratorCode,
- java: getJavaGeneratorCode,
- go: getGoGeneratorCode,
- csharp: getCSharpGeneratorCode,
- rust: getRustGeneratorCode,
- scala: getScalaGeneratorCode,
- python: getPythonGeneratorCode,
- dart: getDartGeneratorCode,
- cplusplus: getCplusplusGeneratorCode,
- kotlin: getKotlinGeneratorCode,
- php: getPhpGeneratorCode
- };
-
- const generatorCode = generators[config.language](message);
-
- fetch(`${process.env.NEXT_PUBLIC_API_PATH}/generate`, {
- body: JSON.stringify(message),
- method: 'POST'
- })
- .then(async (res) => {
- if (!res.ok) {
- throw new Error(res.statusText);
- }
-
- const response: UpdateMessage = await res.json();
- setGeneratorCode(generatorCode);
- setModels(response.models);
- setLoaded({
- ...loaded,
- hasReceivedCode: true
- });
- setError(false);
- setStatusCode(200);
- setErrorMessage('');
- })
- .catch((error) => {
- console.error(error);
- setError(true);
- setErrorMessage(
- 'Input is not a correct AsyncAPI document, so it cannot be processed.'
- );
- setStatusCode(500);
- });
- }
- } catch (e: any) {
- console.error(e);
- setError(true);
- setErrorMessage(
- 'Input is not a correct AsyncAPI document, so it cannot be processed.'
- );
- setStatusCode(400);
- }
- };
-
if (!isMounted) {
return null;
}
@@ -348,17 +344,13 @@ const Playground: React.FC = (props) => {
return (
{isLoaded ? (
-
+
Loading Modelina Playground. Rendering playground components...
) : (
-
diff --git a/modelina-website/src/components/playground/PlaygroundOptions.tsx b/modelina-website/src/components/playground/PlaygroundOptions.tsx
index 74bbee1130..bfd51049bd 100644
--- a/modelina-website/src/components/playground/PlaygroundOptions.tsx
+++ b/modelina-website/src/components/playground/PlaygroundOptions.tsx
@@ -1,18 +1,19 @@
import React, { useContext, useEffect, useState } from 'react';
+
import { PlaygroundGeneralConfigContext } from '../contexts/PlaygroundConfigContext';
-import TypeScriptGeneratorOptions from './options/TypeScriptGeneratorOptions';
-import GeneralOptions from './options/GeneralOptions';
-import JavaScriptGeneratorOptions from './options/JavaScriptGeneratorOptions';
+import CplusplusGeneratorOptions from './options/CplusplusGeneratorOptions';
import CSharpGeneratorOptions from './options/CSharpGeneratorOptions';
import DartGeneratorOptions from './options/DartGeneratorOptions';
+import GeneralOptions from './options/GeneralOptions';
import GoGeneratorOptions from './options/GoGeneratorOptions';
import JavaGeneratorOptions from './options/JavaGeneratorOptions';
+import JavaScriptGeneratorOptions from './options/JavaScriptGeneratorOptions';
import KotlinGeneratorOptions from './options/KotlinGeneratorOptions';
+import PhpGeneratorOptions from './options/PhpGeneratorOptions';
+import PythonGeneratorOptions from './options/PythonGeneratorOptions';
import RustGeneratorOptions from './options/RustGeneratorOptions';
import ScalaGeneratorOptions from './options/ScalaGeneratorOptions';
-import PythonGeneratorOptions from './options/PythonGeneratorOptions';
-import CplusplusGeneratorOptions from './options/CplusplusGeneratorOptions';
-import PhpGeneratorOptions from './options/PhpGeneratorOptions';
+import TypeScriptGeneratorOptions from './options/TypeScriptGeneratorOptions';
interface PlaygroundOptionsProps {
setNewConfig?: (queryKey: string, queryValue: any) => void;
@@ -25,7 +26,7 @@ const PlaygroundOptions: React.FC
= ({ setNewConfig }) =
const handleLanguageChange = () => {
switch (context?.language) {
case 'typescript':
- setGeneratorOptions(prevOptions => );
+ setGeneratorOptions(() => );
break;
case 'javascript':
setGeneratorOptions();
@@ -61,21 +62,21 @@ const PlaygroundOptions: React.FC = ({ setNewConfig }) =
setGeneratorOptions();
break;
default:
- setGeneratorOptions(prevOptions => null);
+ setGeneratorOptions(() => null);
break;
}
- }
+ };
useEffect(() => {
handleLanguageChange();
- }, [])
+ }, []);
useEffect(() => {
handleLanguageChange();
}, [context?.language, setNewConfig]);
return (
-
+
{generatorOptions}
diff --git a/modelina-website/src/components/playground/Sidebar.tsx b/modelina-website/src/components/playground/Sidebar.tsx
index 16f3496de1..b4762bc312 100644
--- a/modelina-website/src/components/playground/Sidebar.tsx
+++ b/modelina-website/src/components/playground/Sidebar.tsx
@@ -1,10 +1,11 @@
+import clsx from 'clsx';
import React from 'react';
import { IoOptionsOutline } from 'react-icons/io5';
-import { VscListSelection } from 'react-icons/vsc';
import { LuFileInput, LuFileOutput } from 'react-icons/lu';
-import { Tooltip } from './Tooltip';
+import { VscListSelection } from 'react-icons/vsc';
+
import { usePlaygroundContext } from '../contexts/PlaygroundContext';
-import clsx from 'clsx';
+import { Tooltip } from './Tooltip';
interface SidebarItem {
name: string;
@@ -20,13 +21,8 @@ interface SidebarItem {
interface SidebarProps {}
export const Sidebar: React.FunctionComponent
= () => {
- const {
- setShowOptions,
- setShowOutputNavigation,
- setShowInputEditor,
- showInputEditor,
- showOptions
- } = usePlaygroundContext();
+ const { setShowOptions, setShowOutputNavigation, setShowInputEditor, showInputEditor, showOptions } =
+ usePlaygroundContext();
const sidebarItems: SidebarItem[] = [
// Input/Output Editor
{
@@ -40,11 +36,7 @@ export const Sidebar: React.FunctionComponent = () => {
setShowOutputNavigation(false);
setShowOptions(false);
},
- icon: showInputEditor ? (
-
- ) : (
-
- ),
+ icon: showInputEditor ? : ,
tooltip: `Show ${showInputEditor ? 'Input Editor' : 'Output Editor'}`
},
// Options
@@ -57,7 +49,7 @@ export const Sidebar: React.FunctionComponent = () => {
onClick: () => {
setShowOptions((prevShowOptions) => !prevShowOptions);
},
- icon: