Skip to content

Commit

Permalink
feat: add options for editor and templates
Browse files Browse the repository at this point in the history
  • Loading branch information
magicmatatjahu authored Dec 16, 2021
1 parent 17a8734 commit ffb1eb4
Show file tree
Hide file tree
Showing 33 changed files with 1,406 additions and 254 deletions.
8 changes: 0 additions & 8 deletions config-overrides.js

This file was deleted.

9 changes: 9 additions & 0 deletions craco.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,13 @@ module.exports = {
],
},
},
webpack: {
configure: (webpackConfig) => {
webpackConfig.module.rules.push({
test: /\.yml$/i,
loader: 'raw-loader',
});
return webpackConfig;
}
}
};
1,010 changes: 824 additions & 186 deletions package-lock.json

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@
"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 Expand Up @@ -78,6 +77,7 @@
"@semantic-release/github": "^8.0.1",
"@semantic-release/npm": "^8.0.0",
"@semantic-release/release-notes-generator": "^10.0.2",
"@tailwindcss/typography": "^0.4.1",
"@testing-library/jest-dom": "^5.14.1",
"@testing-library/react": "^11.2.7",
"@testing-library/user-event": "^12.8.3",
Expand All @@ -95,6 +95,7 @@
"eslint-plugin-sonarjs": "^0.10.0",
"markdown-toc": "^1.2.0",
"postcss": "^7.0.39",
"raw-loader": "^4.0.2",
"react-scripts": "4.0.3",
"semantic-release": "^18.0.0",
"tailwindcss": "npm:@tailwindcss/postcss7-compat@^2.2.17",
Expand Down
5 changes: 2 additions & 3 deletions src/components/Content.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import SplitPane from 'react-split-pane';
import { Editor } from './Editor/Editor';
import { Navigation } from './Navigation';
import { Template } from './Template';
import { Visualiser } from './Visualiser';
import NewFile from './NewFile';
import { VisualiserTemplate } from './Visualiser';

import { debounce } from '../helpers';
import state from '../state';
Expand Down Expand Up @@ -50,7 +50,6 @@ export const Content: React.FunctionComponent<ContentProps> = () => { // eslint-
return (
<div className="flex flex-1 flex-row relative">
<div className="flex flex-1 flex-row relative">

{newFileEnabled && <NewFile />}

{!newFileEnabled &&
Expand All @@ -72,7 +71,7 @@ export const Content: React.FunctionComponent<ContentProps> = () => { // eslint-
>
{navigationAndEditor}
{viewType === 'template' && <Template />}
{viewType === 'visualiser' && <Visualiser />}
{viewType === 'visualiser' && <VisualiserTemplate />}
</SplitPane>
}
</div>
Expand Down
20 changes: 6 additions & 14 deletions src/components/Editor/MonacoWrapper.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import React, { useEffect } from 'react';
import toast from 'react-hot-toast';
import MonacoEditor, {
EditorProps as MonacoEditorProps,
} from '@monaco-editor/react';
Expand All @@ -19,6 +18,9 @@ export const MonacoWrapper: React.FunctionComponent<MonacoWrapperProps> = ({
...props
}) => {
const editorState = state.useEditorState();
const settingsState = state.useSettingsState();
const autoSaving = settingsState.editor.autoSaving.get();
const savingDelay = settingsState.editor.savingDelay.get();

async function handleEditorDidMount(
editor: monacoAPI.editor.IStandaloneCodeEditor,
Expand All @@ -31,18 +33,7 @@ export const MonacoWrapper: React.FunctionComponent<MonacoWrapperProps> = ({
// apply save command
editor.addCommand(
monacoAPI.KeyMod.CtrlCmd | monacoAPI.KeyCode.KEY_S,
() => {
const editorValue = EditorService.getValue();
localStorage.setItem('document', editorValue);
state.editor.documentFrom.set('localStorage');
toast.success(
<div>
<span className="block text-bold">
Document succesfully saved to the local storage!
</span>
</div>,
);
},
() => EditorService.saveToLocalStorage(),
);

// mark editor as loaded
Expand All @@ -51,8 +42,9 @@ export const MonacoWrapper: React.FunctionComponent<MonacoWrapperProps> = ({

const onChange = debounce((v: string) => {
EditorService.updateState({ content: v });
autoSaving && EditorService.saveToLocalStorage(v, false);
SpecificationService.parseSpec(v);
}, 625);
}, savingDelay);

useEffect(() => {
MonacoService.loadMonaco();
Expand Down
158 changes: 158 additions & 0 deletions src/components/Modals/Settings/SettingsModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
import React, { useState, useEffect } from 'react';
import toast from 'react-hot-toast';
import { VscSettingsGear } from 'react-icons/vsc';

import { SettingsTabs, SettingTab } from './SettingsTabs';

import { ConfirmModal } from '../index';
import { Switch } from '../../common';

import state from '../../../state';
import { SettingsState } from '../../../state/settings';

function saveOptions(settings: SettingsState = {} as any) {
state.settings.merge({
...settings,
});
localStorage.setItem('studio-settings', JSON.stringify(state.settings.get()));
}

export const SettingsModal: React.FunctionComponent = () => {
const settingsState = state.useSettingsState();
const [autoSaving, setAutoSaving] = useState(settingsState.editor.autoSaving.get());
const [savingDelay, setSavingDelay] = useState(settingsState.editor.savingDelay.get());
const [autoRendering, setAutoRendering] = useState(settingsState.templates.autoRendering.get());
const [confirmDisabled, setConfirmDisabled] = useState(true);

useEffect(() => {
const disable = JSON.stringify({
editor: {
autoSaving,
savingDelay,
},
templates: {
autoRendering,
}
}) === localStorage.getItem('studio-settings');
setConfirmDisabled(disable);
}, [autoSaving, savingDelay, autoRendering]);

const onSubmit = () => {
saveOptions({
editor: {
autoSaving,
savingDelay,
},
templates: {
autoRendering,
}
});
setConfirmDisabled(true);
toast.success(
<div>
<span className="block text-bold">
Settings succesfully saved!
</span>
</div>
);
};

const tabs: Array<SettingTab> = [
{
name: 'Editor',
tab: <span>Editor</span>,
content: (
<div>
<div className="flex flex-col mt-4 text-sm">
<div className="flex flex-row content-center justify-between">
<label
htmlFor="asyncapi-version"
className="flex justify-right items-center w-1/2 content-center font-medium text-gray-700"
>
Auto saving:
</label>
<Switch
toggle={autoSaving}
onChange={(v) => setAutoSaving(v)}
/>
</div>
<div className='text-gray-400 text-xs'>
Save automatically after each change in the document or manually.
</div>
</div>
<div className={`flex flex-col mt-4 text-sm pl-8 ${autoSaving ? 'opacity-1' : 'opacity-25'}`}>
<div className="flex flex-row content-center justify-between">
<label
htmlFor="template-delay"
className="flex justify-right items-center w-1/2 content-center font-medium text-gray-700"
>
Delay (in miliseconds):
</label>
<select
name="asyncapi-version"
className="shadow-sm focus:ring-pink-500 focus:border-pink-500 w-1/4 block sm:text-sm border-gray-300 rounded-md py-2 px-1 text-gray-700 border-pink-300 border-2"
onChange={e => setSavingDelay(JSON.parse(e.target.value))}
value={autoSaving ? savingDelay : ''}
disabled={!autoSaving}
>
<option value="">Please Select</option>
{[250, 500, 625, 750, 875, 1000].map(v => (
<option key={v} value={v}>
{v}
</option>
))}
</select>
</div>
<div className='text-gray-400 text-xs -mt-2'>
Delay in saving the modified document.
</div>
</div>
</div>
),
},
{
name: 'Templates',
tab: <span>Templates</span>,
content: (
<div>
<div className="flex flex-col mt-4 text-sm">
<div className="flex flex-row content-center justify-between">
<label
htmlFor="asyncapi-version"
className="flex justify-right items-center w-1/2 content-center font-medium text-gray-700"
>
Auto rendering:
</label>
<Switch
toggle={autoRendering}
onChange={(v) => setAutoRendering(v)}
/>
</div>
</div>
<div className='text-gray-400 text-xs'>
Automatic rendering after each change in the document or manually.
</div>
</div>
),
},
];

return (
<ConfirmModal
title={'Studio settings'}
confirmText="Save"
confirmDisabled={confirmDisabled}
opener={
<button
className={'flex border-l-2 text-gray-500 hover:text-white border-gray-800 focus:outline-none border-box p-4'}
type="button"
>
<VscSettingsGear className="w-5 h-5" />
</button>
}
onSubmit={onSubmit}
>
<SettingsTabs tabs={tabs} />
</ConfirmModal>
);
};
65 changes: 65 additions & 0 deletions src/components/Modals/Settings/SettingsTabs.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import React, { useState } from 'react';

export interface SettingTab {
name: string;
tab: React.ReactNode;
content: React.ReactNode;
}

interface SettingTabsProps {
tabs: Array<SettingTab>;
active?: string;
}

export const SettingsTabs: React.FunctionComponent<SettingTabsProps> = ({
tabs = [],
active = '',
}) => {
const [activeTab, setActiveTab] = useState(active || tabs[0]?.name);

if (tabs.length === 0) {
return null;
}

return (
<div>
<div
className="flex flex-row justify-between items-center border-b border-gray-300 text-white uppercase font-bold text-xs"
>
<ul className="flex flex-row">
{tabs.map(tab => (
<li
key={tab.name}
className="cursor-pointer"
onClick={() => setActiveTab(tab.name)}
>
<div
className={`p-2 hover:text-pink-500 ${
activeTab === tab.name
? 'text-pink-500 border-b-2 border-pink-500'
: 'text-gray-500'
}`}
>
{tab.tab}
</div>
</li>
))}
</ul>
</div>
<div
className="overflow-auto h-64"
>
<ul>
{tabs.map(tab => (
<li
key={tab.name}
className={`${activeTab === tab.name ? 'block' : 'hidden'}`}
>
{tab.content}
</li>
))}
</ul>
</div>
</div>
);
};
Loading

0 comments on commit ffb1eb4

Please sign in to comment.