Skip to content

Commit

Permalink
Merge branch 'master' into ogp
Browse files Browse the repository at this point in the history
  • Loading branch information
KhudaDad414 authored Jun 10, 2024
2 parents 381d356 + 881c76c commit f7230cd
Show file tree
Hide file tree
Showing 11 changed files with 14,048 additions and 11,053 deletions.
4 changes: 0 additions & 4 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
# This action is centrally managed in https://github.com/asyncapi/.github/
# Don't make changes to this file in this repo as they will be overwritten with changes made to the same file in above mentioned repo

# It does magic only if there is package.json file in the root of the project
name: Release

on:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -282,4 +282,39 @@ export const NesteadArray = () => (
/>
);

export const Blank_schema = () => (
<Template
initialSchema={JSON.stringify(
{}, null, 2)}
/>
);

export const Root_string = () => (
<Template
initialSchema={JSON.stringify(
{
"type": "string"
}, null, 2)}
/>
);

export const Multiple_data_types = () => (
<Template
initialSchema={JSON.stringify(
{
type: "object",
properties: {
mixedTypeProperty: {
type: ["boolean", "integer"],
},
},
required: ["mixedTypeProperty"],
},
null,
2
)}
/>
);


export default VisualEditorStory
2 changes: 2 additions & 0 deletions packages/ui/components/DropdownMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ interface DropdownMenuProps {
items: DropdownMenuItem[]
side?: 'top' | 'right' | 'bottom' | 'left'
align?: 'start' | 'center' | 'end'
onSelect?: (options: string[]) => void
}

interface DropdownMenuItemComponentProps {
Expand All @@ -44,6 +45,7 @@ export const DropdownMenu: FunctionComponent<DropdownMenuProps> = ({
items,
side,
align,
onSelect
}) => {
return (
<RadixDropdownMenu.Root>
Expand Down
189 changes: 139 additions & 50 deletions packages/ui/components/VisualEditor.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import React, { useState, useEffect } from 'react';
import SchemaObject from './VisualEditor/SchemaObject';
import _ from 'lodash';
import { getColorForType } from './VisualEditor/SchemaProperty';
import { DropdownMenu, DropdownMenuItem } from './DropdownMenu';
import { IoIosArrowDropdown } from 'react-icons/io';

interface VisualEditorProps {
schema: string;
Expand All @@ -15,14 +18,7 @@ interface SchemaObjectInterface {
}

export const VisualEditor: React.FC<VisualEditorProps> = ({ schema, onSchemaChange }) => {
const selectStyle = {
backgroundColor: '#0F172A',
color: 'white',
borderRadius: '3px',
fontSize: '12px',
fontFamily: 'Inter, sans-serif'
};


const [schemaObject, setSchemaObject] = useState<SchemaObjectInterface>({});

useEffect(() => {
Expand All @@ -36,64 +32,157 @@ export const VisualEditor: React.FC<VisualEditorProps> = ({ schema, onSchemaChan
}, [schema]);

const handleSchemaChange = (updatedPart: any) => {
const updatedSchema = { ...schemaObject, ...updatedPart };
let updatedSchema = _.cloneDeep(schemaObject);
console.log("updatedPart.type", updatedPart.type)

if (updatedSchema.type === 'array') {
if (updatedPart.items && updatedPart.items.type === 'object') {
updatedSchema.items = updatedPart.items;
} else if (updatedPart?.items?.properties) {
updatedSchema.items = {
...updatedSchema.items,
properties: {
...updatedSchema.items.properties,
...updatedPart.items.properties,
},
};
} else if (updatedPart.type !== 'object' ) {
updatedSchema = { ...schemaObject, ...updatedPart };
} else if (Object.keys(updatedPart.properties).length === 0 && updatedPart?.required === undefined){
updatedSchema = { ...schemaObject, ...updatedPart };
} else {
updatedSchema.items = { ...updatedSchema.items, ...updatedPart };
}
} else {
updatedSchema = { ...schemaObject, ...updatedPart };
}

const newSchemaString = JSON.stringify(updatedSchema);
console.log('Schema updated:', newSchemaString);
setSchemaObject(updatedSchema);
onSchemaChange(newSchemaString);
};

const renderRootTypeSelector = () => (
<div>
<select
value={schemaObject.type || ''}
onChange={(e) => handleSchemaChange({ type: e.target.value })}
style={selectStyle}
>
<option value="">Select root type</option>
<option value="object">Object</option>
<option value="array">Array</option>
<option value="string">String</option>
<option value="number">Number</option>
<option value="boolean">Boolean</option>
</select>
</div>
);
const handleRootTypeDropdownSelect = (selectedOption: string) => {
if (selectedOption === 'array') {
handleSchemaChange({ type: 'array', items: { type: 'string' }, properties: undefined, required: undefined});
} else {
handleSchemaChange({ type: selectedOption, properties: undefined, required: undefined});
}
};

const handleArrayItemTypeDropdownSelect = (selectedOption: string) => {
handleSchemaChange({ items: schemaObject.items ? { ...schemaObject.items, type: selectedOption } : { type: selectedOption } });
};

const rootTypeOptions: DropdownMenuItem[] = [
{ title: 'Select Root Type',onSelect: () => {}},
{ type: 'separator'},
{ type: 'regular', title: 'Object', onSelect: () => handleRootTypeDropdownSelect('object') },
{ type: 'regular', title: 'Array', onSelect: () => handleRootTypeDropdownSelect('array') },
{ type: 'regular', title: 'String', onSelect: () => handleRootTypeDropdownSelect('string') },
{ type: 'regular', title: 'Number', onSelect: () => handleRootTypeDropdownSelect('number') },
{ type: 'regular', title: 'Boolean', onSelect: () => handleRootTypeDropdownSelect('boolean') },
];

const itemTypeOptions: DropdownMenuItem[] = [
{ title: 'Select Items Type',onSelect: () => {}},
{ type: 'separator'},
{ type: 'regular', title: 'String', onSelect: () => handleArrayItemTypeDropdownSelect('string') },
{ type: 'regular', title: 'Number', onSelect: () => handleArrayItemTypeDropdownSelect('number') },
{ type: 'regular', title: 'Boolean', onSelect: () => handleArrayItemTypeDropdownSelect('boolean') },
{ type: 'regular', title: 'Object', onSelect: () => handleArrayItemTypeDropdownSelect('object') },
];

const renderArrayItemTypeSelector = () => {
if (schemaObject.type === 'array') {
const renderRootTypeDisplay = () => {
if(schemaObject.type === 'array') {
return null;
}
const rootType = schemaObject.type || '';
const displayRootType = rootType.charAt(0).toUpperCase() + rootType.slice(1);
return (
<div className="flex items-center">
<span
style={{
color: getColorForType(rootType),
borderRadius: '3px',
padding: '2px 4px',
fontSize: '14px',
fontFamily: 'Inter, Helvetica',
}}
>
{displayRootType}
</span>
</div>
);
};

const renderArrayItemTypeDisplay = () => {
if (schemaObject.type === 'array' && schemaObject.items) {
const itemType = schemaObject.items?.type || '';
return (
<div>
<strong>Array Item Type:</strong>
<select
value={schemaObject.items?.type || ''}
onChange={(e) => handleSchemaChange({ items: { ...schemaObject.items, type: e.target.value } })}
style={selectStyle}
<div className="flex items-center">
<span
style={{
color: getColorForType('array', itemType),
borderRadius: '3px',
padding: '2px 4px',
fontSize: '14px',
fontFamily: 'Inter, Helvetica',
}}
>
<option value="">Select item type</option>
<option value="string">String</option>
<option value="number">Number</option>
<option value="boolean">Boolean</option>
<option value="object">Object</option>
<option value="array">Array</option>
</select>
{`Array<${itemType}>`}
</span>
</div>
);
}
return null;
};

return (
<div className="visual-editor" style={{ width: '45vw', minWidth: '550px', background: '#0F172A', color: '#CBD5E1', fontFamily: 'Inter, sans-serif', padding: '20px'}}>
{renderRootTypeSelector()}
{renderArrayItemTypeSelector()}

<SchemaObject
schema={schemaObject.type === 'array' ? schemaObject.items : schemaObject}
onSchemaChange={(newSchema: any) => handleSchemaChange(newSchema)}
path={schemaObject.type === 'array' ? 'items' : ''}
level={0}
/>
<div
className="visual-editor"
style={{
width: "45vw",
minWidth: "550px",
background: "#0F172A",
color: "#CBD5E1",
fontFamily: "Inter, sans-serif",
padding: "20px",
}}
>
<div className="flex items-center gap-2">
{renderRootTypeDisplay()}
{renderArrayItemTypeDisplay()}
<DropdownMenu
trigger={
<button>
<IoIosArrowDropdown />
</button>
}
items={rootTypeOptions}
/>
{schemaObject.type === "array" && (
<DropdownMenu
trigger={
<button>
<IoIosArrowDropdown />
</button>
}
items={itemTypeOptions}
/>
)}
</div>
{(schemaObject.type === "object" || (schemaObject.type === "array" && schemaObject.items.type === "object")) && (
<SchemaObject
schema={
schemaObject.type === "array" ? schemaObject.items : schemaObject
}
onSchemaChange={(newSchema: any) => handleSchemaChange(newSchema)}
path={schemaObject.type === "array" ? "items" : ""}
level={0}
/>
)}
</div>
);
};
Expand Down
3 changes: 1 addition & 2 deletions packages/ui/components/VisualEditor/CodeEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ interface CodeEditorProps {
}

export const CodeEditor: React.FC<CodeEditorProps> = ({ schema, onSchemaChange }) => {
const [value, setValue] = useState<string>(schema);
const [value, setValue] = useState(schema);
const [error, setError] = useState<string>('');

useEffect(() => {
Expand Down Expand Up @@ -37,7 +37,6 @@ export const CodeEditor: React.FC<CodeEditorProps> = ({ schema, onSchemaChange }

return (
<div className="code-editor">
<h2>Code Editor</h2>
{error && <p style={{ color: 'red' }}>Error: {error}</p>}
<textarea
value={value}
Expand Down
Loading

0 comments on commit f7230cd

Please sign in to comment.