Skip to content

Commit 7e282e6

Browse files
committed
fix icon and custom path prefix and add local storage for ide
1 parent 731ded6 commit 7e282e6

File tree

3 files changed

+134
-47
lines changed

3 files changed

+134
-47
lines changed

gatsby-node.js

+15-15
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
exports.onCreateWebpackConfig = ({ actions, stage, loaders }) => {
2-
const jsLoader = loaders.js();
3-
// if (stage === `build-javascript`) {
4-
actions.setWebpackConfig({
5-
module: {
6-
rules: [
7-
{
8-
test: /\.tsx?$/,
9-
use: [
10-
{
11-
loader: jsLoader.loader,
2+
const jsLoader = loaders.js();
3+
if (stage === 'build-javascript') {
4+
actions.setWebpackConfig({
5+
module: {
6+
rules: [
7+
{
8+
test: /\.tsx?$/,
9+
use: [
10+
{
11+
loader: jsLoader.loader
12+
}
13+
]
14+
}
15+
]
1216
}
13-
]
14-
}
15-
]
17+
});
1618
}
17-
});
18-
// }
1919
};

web/components/Editor/Editor.tsx

+102-26
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,6 @@ const adapters = {
1515
snips: snipsAdapter
1616
};
1717

18-
declare var CodeFlask;
19-
let ReactJson: any = null;
20-
2118
interface IEditorState {
2219
error: null | string;
2320
warning: null | string;
@@ -28,6 +25,17 @@ interface IEditorState {
2825
currentAdapter: 'default' | 'rasa' | 'snips';
2926
useCustomOptions: boolean;
3027
}
28+
29+
// NOTE: for SSR, wrap the require in check for window
30+
let CodeFlask = null;
31+
let ReactJson = null;
32+
if (typeof window !== `undefined`) {
33+
// tslint:disable-next-line:no-var-requires
34+
CodeFlask = require('codeflask').default;
35+
// tslint:disable-next-line:no-var-requires
36+
ReactJson = require('react-json-view').default;
37+
}
38+
3139
export default class Editor extends React.Component<{}, IEditorState> {
3240
public state: IEditorState = {
3341
error: null,
@@ -53,33 +61,40 @@ export default class Editor extends React.Component<{}, IEditorState> {
5361
return;
5462
}
5563
const validation = this.getDSLValidation(this.codeInputValue);
64+
let newState = {};
5665
if (validation && validation.error) {
57-
this.setState({ error: validation.error, warning: null });
66+
newState = { error: validation.error, warning: null };
5867
} else if (validation && validation.warning) {
59-
this.setState({ error: null, warning: validation.warning });
68+
newState = { error: null, warning: validation.warning };
6069
} else {
61-
this.setState({ error: null, warning: null });
70+
newState = { error: null, warning: null };
6271
}
72+
this.setState(newState, () => {
73+
this.saveToLocalStorage(true, false, false);
74+
});
6375
}, 300);
6476

6577
public componentDidMount() {
66-
ReactJson = require('react-json-view').default;
67-
const flask = new CodeFlask('#my-code-editor', {
68-
language: 'chatito',
69-
lineNumbers: true
70-
});
71-
flask.addLanguage('chatito', chatitoPrism);
72-
flask.onUpdate(code => {
73-
this.codeInputValue = code;
74-
this.tabs[this.state.activeTabIndex].value = code;
75-
// NOTE: ugly hack to know when codeflask is mounted (it makes 2 calls to update on mount)
76-
this.editorUpdatesSetupCount < 2 ? this.editorUpdatesSetupCount++ : this.setState({ dataset: null });
77-
this.debouncedTabDSLValidation();
78+
if (!CodeFlask) {
79+
return;
80+
}
81+
this.loadFromLocalStorage(() => {
82+
const flask = new CodeFlask('#my-code-editor', {
83+
language: 'chatito',
84+
lineNumbers: true
85+
});
86+
flask.addLanguage('chatito', chatitoPrism);
87+
flask.onUpdate(code => {
88+
this.codeInputValue = code;
89+
this.tabs[this.state.activeTabIndex].value = code;
90+
// NOTE: ugly hack to know when codeflask is mounted (it makes 2 calls to update on mount)
91+
this.editorUpdatesSetupCount < 2 ? this.editorUpdatesSetupCount++ : this.setState({ dataset: null });
92+
this.debouncedTabDSLValidation();
93+
});
94+
flask.updateCode(this.tabs[this.state.activeTabIndex].value);
95+
flask.setLineNumber();
96+
this.codeflask = flask;
7897
});
79-
flask.highlight();
80-
flask.updateCode(this.tabs[this.state.activeTabIndex].value);
81-
flask.setLineNumber();
82-
this.codeflask = flask;
8398
}
8499

85100
public render() {
@@ -212,9 +227,9 @@ export default class Editor extends React.Component<{}, IEditorState> {
212227
</es.TabButton>
213228
);
214229
};
215-
/* ================== Event Handlers ================== */
216230

217-
private onCloseDrawer = () => this.setState({ showDrawer: false });
231+
/* ================== Event Handlers ================== */
232+
private onCloseDrawer = () => this.setState({ showDrawer: false, dataset: null });
218233

219234
private onCustomOptionsCheckboxChange = e => {
220235
this.setState({ useCustomOptions: e.target.checked });
@@ -227,12 +242,16 @@ export default class Editor extends React.Component<{}, IEditorState> {
227242
} else if (e.target.value === 'snips') {
228243
adapterOptions = Object.assign({}, snipsDefaultOptions);
229244
}
230-
this.setState({ currentAdapter: e.target.value, adapterOptions, dataset: null });
245+
this.setState({ currentAdapter: e.target.value, adapterOptions, dataset: null }, () => {
246+
this.saveToLocalStorage(false, true, true);
247+
});
231248
};
232249

233250
private onEditAdapterOptions = changes => {
234251
if (changes && changes.updated_src) {
235-
this.setState({ adapterOptions: changes.updated_src });
252+
this.setState({ adapterOptions: changes.updated_src }, () => {
253+
this.saveToLocalStorage(false, true, false);
254+
});
236255
return null;
237256
}
238257
return false;
@@ -272,6 +291,63 @@ export default class Editor extends React.Component<{}, IEditorState> {
272291

273292
/* ================== Utils ================== */
274293

294+
private saveToLocalStorage = (saveTabs, saveAdapterOptions, saveCurrentAdapter) => {
295+
if (window && localStorage) {
296+
if (saveTabs) {
297+
localStorage.setItem('tabs', JSON.stringify(this.tabs));
298+
}
299+
if (saveAdapterOptions) {
300+
localStorage.setItem('adapterOptions', this.state.useCustomOptions ? JSON.stringify(this.state.adapterOptions) : '');
301+
}
302+
if (saveCurrentAdapter) {
303+
localStorage.setItem('currentAdapter', this.state.currentAdapter);
304+
}
305+
}
306+
};
307+
308+
private loadFromLocalIfPresent = (key: string, parseAsJSON: boolean) => {
309+
if (window && localStorage) {
310+
try {
311+
const item = localStorage.getItem(key);
312+
if (!parseAsJSON) {
313+
return item;
314+
}
315+
if (item) {
316+
try {
317+
return JSON.parse(item);
318+
} catch (e) {
319+
// just catch the error
320+
}
321+
}
322+
} catch (e) {
323+
// tslint:disable-next-line:no-console
324+
console.error(e);
325+
}
326+
}
327+
};
328+
329+
private loadFromLocalStorage = (cb: () => void) => {
330+
if (window && localStorage) {
331+
const newState: any = {};
332+
const localTabs = this.loadFromLocalIfPresent('tabs', true);
333+
const localAdapterOptions = this.loadFromLocalIfPresent('adapterOptions', true);
334+
const localCurrentAdapter = this.loadFromLocalIfPresent('currentAdapter', false);
335+
if (localTabs) {
336+
this.tabs = localTabs;
337+
}
338+
if (localAdapterOptions) {
339+
newState.adapterOptions = localAdapterOptions;
340+
newState.useCustomOptions = true;
341+
}
342+
if (localCurrentAdapter) {
343+
newState.currentAdapter = localCurrentAdapter;
344+
}
345+
this.setState(newState, cb);
346+
} else {
347+
cb();
348+
}
349+
};
350+
275351
private changeTab = (i: number, cb?: () => void) => {
276352
this.setState({ activeTabIndex: i }, () => {
277353
this.codeflask.updateCode(this.tabs[this.state.activeTabIndex].value);

web/pages/index.tsx

+17-6
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,30 @@ import Editor from '../components/Editor/Editor';
55
import { Header } from '../components/globalStyles';
66
import Logo from '../components/Logo';
77

8+
// NOTE: gatsby global for prefix
9+
declare var __PATH_PREFIX__;
10+
811
export default class Index extends React.Component<{}, {}> {
912
public render() {
1013
return (
1114
<div>
1215
<Helmet>
13-
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
14-
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png" />
15-
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png" />
16-
<link rel="manifest" href="/site.webmanifest" />
17-
<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#5bbad5" />
16+
<link rel="apple-touch-icon" sizes="180x180" href={`${__PATH_PREFIX__}/apple-touch-icon.png`} />
17+
<link rel="icon" type="image/png" sizes="32x32" href={`${__PATH_PREFIX__}/favicon-32x32.png`} />
18+
<link rel="icon" type="image/png" sizes="16x16" href={`${__PATH_PREFIX__}/favicon-16x16.png`} />
19+
<link rel="manifest" href={`${__PATH_PREFIX__}/site.webmanifest`} />
20+
<link rel="mask-icon" href={`${__PATH_PREFIX__}/safari-pinned-tab.svg`} color="#5bbad5" />
1821
<meta name="msapplication-TileColor" content="#da532c" />
1922
<meta name="theme-color" content="#ffffff" />
20-
<script src="https://cdn.rawgit.com/kazzkiq/CodeFlask/v1.1.0/build/codeflask.min.js" />
23+
<title>Chatito DSL - Generate dataset for chatbots</title>
24+
<meta
25+
name="keywords"
26+
content="chatbot, dataset generation, dataset generator, generate datasets, rasa nlu, snips nlu, chatbot dataset, datasets for chatbots"
27+
/>
28+
<meta
29+
name="description"
30+
content="Chatito helps you helps you generate datasets for natural language understanding models using a simple DSL"
31+
/>
2132
</Helmet>
2233
<Header>
2334
<div style={{ display: 'inline-block', width: 50, minWidth: 50, height: 43 }}>

0 commit comments

Comments
 (0)