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: adding new page that allows users to select template (#147) #158

Merged
merged 18 commits into from
Nov 30, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
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