Skip to content

Commit

Permalink
feat: adding new page that allows users to select template (#147) (#158)
Browse files Browse the repository at this point in the history
Co-authored-by: David Boyne <[email protected]>
Co-authored-by: Maciej Urbańczyk <[email protected]>
  • Loading branch information
3 people authored Nov 30, 2021
1 parent 8940afc commit 3847a33
Show file tree
Hide file tree
Showing 15 changed files with 1,870 additions and 30 deletions.
8 changes: 8 additions & 0 deletions config-overrides.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
module.exports = function override(config) {
config.module.rules.push({
test: /\.yml$/i,
loader: 'raw-loader',
});

return config;
};
32 changes: 24 additions & 8 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
"js-yaml": "^4.1.0",
"monaco-editor": "^0.28.1",
"monaco-yaml": "^2.5.1",
"raw-loader": "^4.0.2",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-flow-renderer": "^9.6.9",
Expand Down
47 changes: 27 additions & 20 deletions src/components/Content.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { Editor } from './Editor/Editor';
import { Navigation } from './Navigation';
import { Template } from './Template';
import { Visualiser } from './Visualiser';
import NewFile from './NewFile';

import { debounce } from '../helpers';
import state from '../state';
Expand All @@ -16,6 +17,7 @@ export const Content: React.FunctionComponent<ContentProps> = () => { // eslint-

const navigationEnabled = sidebarState.panels.navigation.get();
const editorEnabled = sidebarState.panels.editor.get();
const newFileEnabled = sidebarState.panels.newFile.get();
const viewEnabled = sidebarState.panels.view.get();
const viewType = sidebarState.panels.viewType.get();

Expand Down Expand Up @@ -48,26 +50,31 @@ export const Content: React.FunctionComponent<ContentProps> = () => { // eslint-
return (
<div className="flex flex-1 flex-row relative">
<div className="flex flex-1 flex-row relative">
<SplitPane
size={viewEnabled ? secondPaneSize : 0}
minSize={0}
maxSize={secondPaneMaxSize}
pane1Style={
navigationEnabled || editorEnabled ? undefined : { width: '0px' }
}
pane2Style={
viewEnabled ? { overflow: 'auto' } : { width: '0px' }
}
primary={viewEnabled ? 'first' : 'second'}
defaultSize={localStorageRightPaneSize}
onChange={debounce((size: string) => {
localStorage.setItem(splitPosRight, String(size));
}, 100)}
>
{navigationAndEditor}
{viewType === 'template' && <Template />}
{viewType === 'visualiser' && <Visualiser />}
</SplitPane>

{newFileEnabled && <NewFile />}

{!newFileEnabled &&
<SplitPane
size={viewEnabled ? secondPaneSize : 0}
minSize={0}
maxSize={secondPaneMaxSize}
pane1Style={
navigationEnabled || editorEnabled ? undefined : { width: '0px' }
}
pane2Style={
viewEnabled ? { overflow: 'auto' } : { width: '0px' }
}
primary={viewEnabled ? 'first' : 'second'}
defaultSize={localStorageRightPaneSize}
onChange={debounce((size: string) => {
localStorage.setItem(splitPosRight, String(size));
}, 100)}
>
{navigationAndEditor}
{viewType === 'template' && <Template />}
{viewType === 'visualiser' && <Visualiser />}
</SplitPane>
}
</div>
</div>
);
Expand Down
77 changes: 77 additions & 0 deletions src/components/NewFile/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import React from 'react';
import examples from '../../examples';

import { EditorService } from '../../services';
import state from '../../state';

const NewFile = () => {
const handleTemplateClick = (template: string) => {
EditorService.updateState({ content: template, updateModel: true });

const panels = state.sidebar.panels;
panels.merge({
newFile: false,
});
};

const realLifeExamples = examples.filter((template) => template.type === 'real-example');
const templates = examples.filter((template) => template.type === 'protocol-example');

return (
<div className="bg-gray-800 w-full overflow-auto">
<div className="max-w-5xl mx-auto py-10">
<div className="flex">
<div className="w-1/4 pr-10 space-y-4">
<span className="uppercase text-white text-md font-bold">Quick Start</span>
<span className="block text-gray-300 text-md leading-5">To get started please select a template.</span>
</div>
<div className="px-4 w-full overflow-auto space-y-8 ">
<div>
<span className="uppercase text-gray-100 text-md font-bold">Templates</span>
<div className="grid grid-cols-3 gap-4 py-4">
{templates.map(({ title, description: Description, template }) => {
return (
<button
onClick={() => handleTemplateClick(template)}
key={title}
className="text-left flex flex-col cursor-pointer rounded-lg p-4 pb-6 transform transition duration-200 border-2 border-gray-400 hover:scale-105 hover:border-pink-500 bg-gray-100"
>
<span className="block text-md text-gray-800 font-bold leading-0 ">{title}</span>
<span className="block text-sm text-gray-500 font-light mt-1">
<Description />
</span>
</button>
);
})}
</div>
</div>
<div>
<span className="uppercase text-gray-100 text-md font-bold">Real world Examples</span>
<div className="grid grid-cols-3 gap-4 py-4">
{realLifeExamples.map(({ title, description: Description, template }) => {
return (
<button
onClick={() => handleTemplateClick(template)}
key={title}
className="text-left flex flex-col cursor-pointer rounded-lg p-4 pb-6 transform transition duration-200 border-2 border-gray-400 hover:scale-105 hover:border-pink-500 bg-gray-100"
>
<span className="block text-md text-gray-800 font-bold">{title}</span>
<span className="block text-sm text-gray-500 font-light mt-1">
<Description />
</span>
</button>
);
})}
</div>
</div>
<span className=" text-xs block text-white ">
Don&apos;t see what you&apos;re looking for? <a target="_blank" href="https://github.com/asyncapi/studio/issues/new?assignees=&labels=enhancement&template=enhancement.md&title=Template%20Request:%20{%20template%20name%20and%20type%20}" className="underline text-pink-500" rel="noreferrer">Request a template or add one to the list &rarr;</a>
</span>
</div>
</div>
</div>
</div>
);
};

export default NewFile;
8 changes: 7 additions & 1 deletion src/components/Sidebar.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react';
import { VscListSelection, VscCode, VscOpenPreview, VscGraph } from 'react-icons/vsc';
import { VscListSelection, VscCode, VscOpenPreview, VscGraph, VscNewFile } from 'react-icons/vsc';

import state from '../state';

Expand Down Expand Up @@ -41,6 +41,7 @@ function setActiveNav(navItem: NavItemType) {
});
return;
}

panels.set(newState);
}

Expand Down Expand Up @@ -84,6 +85,11 @@ export const Sidebar: React.FunctionComponent<SidebarProps> = () => {
state: () => sidebarState.panels.view.get() && sidebarState.panels.viewType.get() === 'visualiser',
icon: <VscGraph className="w-5 h-5" />,
},
{
name: 'newFile',
state: () => sidebarState.panels.newFile.get(),
icon: <VscNewFile className="w-5 h-5" />,
},
];

return (
Expand Down
67 changes: 67 additions & 0 deletions src/examples/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
// @ts-nocheck

// protocol examples
import kafka from '!!raw-loader!./streetlights-kafka.yml';
import websocket from '!!raw-loader!./websocket-gemini.yml';
import mqtt from '!!raw-loader!./streetlights-mqtt.yml';
import simple from '!!raw-loader!./simple.yml';

// real world examples
import slack from '!!raw-loader!./real-world/slack-rtm.yml';
import gitterStreaming from '!!raw-loader!./real-world/gitter-streaming.yml';

const templateTypes = {
protocol: 'protocol-example',
realExample: 'real-example'
};

export default [
{
title: 'Simple Example',
description: () => <>A basic example of a service that is in charge of processing user signups. Great place to start learning AsyncAPI.</>,
template: simple,
type: templateTypes.protocol
},
{
title: 'Simple Hello World',
description: () => <>A basic example of a service that is in charge of processing user signups. Great place to start learning AsyncAPI.</>,
template: simple,
type: templateTypes.protocol
},
{
title: 'Apache Kafka',
description: () => <>A framework implementation of a software bus using stream-processing. Open Source developed by the Apache Software Foundation.</>,
template: kafka,
type: templateTypes.protocol
},
{
title: 'WebSocket',
description: () => <>A computer communications protocol, providing full-duplex communication channels over a single TCP connection.</>,
template: websocket,
type: templateTypes.protocol
},
{
title: 'MQTT',
description: () => <>A protocol for fetching resources. It is the foundation of any data exchange on the Web and it is a client-server protocol.</>,
template: mqtt,
type: templateTypes.protocol
},
{
title: 'HTTP',
description: () => <>A protocol for fetching resources. It is the foundation of any data exchange on the Web and it is a client-server protocol.</>,
template: gitterStreaming,
type: templateTypes.protocol
},
{
title: 'Slack Real Time Messaging API',
description: () => <>Slack Real time messaging API. Using HTTP protocol.</>,
template: slack,
type: templateTypes.realExample
},
{
title: 'Glitter Streaming API',
description: () => <>Gitter Streaming API from https://stream.gitter.im. Using HTTP protocol.</>,
template: gitterStreaming,
type: templateTypes.realExample
}
];
Loading

0 comments on commit 3847a33

Please sign in to comment.