Skip to content

Commit 0ecb3bd

Browse files
committed
feat: apiDocPage && unitTest init
1 parent 4f9bb66 commit 0ecb3bd

File tree

7 files changed

+288
-21
lines changed

7 files changed

+288
-21
lines changed

website/src/components/tabs/index.tsx

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,7 @@ const Tabs = ({ data }: IProps) => {
2626
};
2727
return (
2828
<div>
29-
<Prevent
30-
onContextMenu={() => {
31-
console.log('11');
32-
}}
33-
>
29+
<Prevent>
3430
<Header className="tabs-header" trackStyle={{ height: 3 }}>
3531
{data.map((p) => (
3632
<PanelItem

website/src/extensions/main/index.tsx

Lines changed: 185 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,14 @@
1-
import { IContributeType, IExtension, components } from '@dtinsight/molecule';
1+
import {
2+
IContributeType,
3+
IEditorTab,
4+
IExtension,
5+
IMoleculeContext,
6+
TabGroup,
7+
UniqueId
8+
} from '@dtinsight/molecule';
9+
import lips from '@jcubic/lips';
10+
11+
import * as monaco from 'monaco-editor';
212

313
import Welcome from '@/workbench/welcome';
414
import {
@@ -14,6 +24,15 @@ import QuickGithub from '@/workbench/quickGithub';
1424
import SourceSpace from '@/workbench/sourceSpace';
1525
import UnitTest from '@/workbench/unitTest';
1626
import ApiDocPage from '@/workbench/apiDocPage';
27+
import { debounce } from '@/utils/tool';
28+
import { LanguageService } from '../../../../esm/languageService';
29+
import { ParseError } from 'dt-sql-parser';
30+
import { ProblemsPaneView } from '@/workbench/problems';
31+
import ProblemStore from '@/workbench/problems/clients/problemStore';
32+
import { ProblemsService } from '@/workbench/problems/services';
33+
import { ProblemsController } from '@/workbench/problems/controllers';
34+
35+
const problemsService = new ProblemsService();
1736

1837
export const mainExt: IExtension = {
1938
id: 'mainExt',
@@ -22,8 +41,15 @@ export const mainExt: IExtension = {
2241
[IContributeType.Modules]: {
2342
menuBar: null
2443
}
44+
// [IContributeType.Grammar]: grammars
2545
},
2646
activate(molecule) {
47+
const languageService = new LanguageService();
48+
problemsService.onSelect((item) => {
49+
// 写入展开的数组内; 当展开的时候 root 的icon 进行变换
50+
problemsService.toggleRoot(item);
51+
});
52+
2753
molecule.colorTheme.update('Default Dark+', (data) => ({
2854
colors: {
2955
...data.colors,
@@ -170,7 +196,17 @@ export const mainExt: IExtension = {
170196
id: 'problem',
171197
name: '问题',
172198
sortIndex: 2,
173-
render: () => <div style={{ padding: 20 }}>Test</div>
199+
render: () => {
200+
return (
201+
<ProblemStore
202+
value={{
203+
onselect: new ProblemsController().onSelect
204+
}}
205+
>
206+
<ProblemsPaneView problemsService={problemsService} />
207+
</ProblemStore>
208+
);
209+
}
174210
});
175211

176212
molecule.statusBar.add({
@@ -195,5 +231,152 @@ export const mainExt: IExtension = {
195231

196232
molecule.activityBar.setCurrent(ACTIVITY_FOLDER);
197233
molecule.sidebar.setCurrent(ACTIVITY_FOLDER);
234+
235+
molecule.editor.onCurrentChange((tab) => {
236+
const language = (tab.tabId as string)?.split('_')?.[0];
237+
const groups = molecule.editor.getGroups();
238+
const fileData = groups[0]?.data?.find((item) => item.id === tab.tabId);
239+
molecule.output.setState({ value: '' });
240+
241+
if (fileData?.model) {
242+
monaco.editor.setModelLanguage(fileData.model, language);
243+
analyzeProblems({ fileData, molecule, tab });
244+
}
245+
activeExplore(tab, molecule);
246+
});
247+
248+
molecule.editor.onContextMenu((pos, tabId, groupId) => {
249+
molecule.editor.setCurrent(tabId, groupId);
250+
molecule.contextMenu.open(
251+
[
252+
{
253+
id: 'parse',
254+
name: 'parse'
255+
}
256+
],
257+
pos,
258+
{
259+
name: molecule.builtin.getConstants().CONTEXTMENU_ITEM_EDITOR,
260+
item: { tabId, groupId }
261+
}
262+
);
263+
});
264+
265+
molecule.editor.onContextMenuClick((item, tabId, groupId) => {
266+
switch (item.id) {
267+
case 'parse': {
268+
parseToAST(molecule, languageService);
269+
break;
270+
}
271+
default:
272+
break;
273+
}
274+
});
275+
276+
molecule.editor.onFocus((item) => {
277+
const groupId = (molecule.editor.getCurrentGroup() || -1) as UniqueId;
278+
const tab = molecule.editor.getCurrentTab();
279+
if (tab?.id && tab.language) {
280+
molecule.editor.setCurrent(tab?.id, groupId);
281+
}
282+
});
283+
284+
molecule.editor.onUpdateState((item) => {
285+
const tab = molecule.editor.getCurrentTab();
286+
const groups = molecule.editor.getGroups();
287+
const fileData = groups[0]?.data?.find((item) => item.id === tab?.id);
288+
analyzeProblems({ fileData, molecule, tab });
289+
});
290+
}
291+
};
292+
293+
const analyzeProblems = debounce((info: any) => {
294+
const { fileData, molecule, tab } = info || {};
295+
const { value: sql, language } = fileData || {};
296+
// todo: 一定要 active Tab 才能获取到 language
297+
if (!language) return;
298+
const languageService = new LanguageService();
299+
languageService.valid(language.toLocaleLowerCase(), fileData.model).then((res) => {
300+
const problems = convertMsgToProblemItem(tab, sql, res);
301+
302+
molecule.panel.update({
303+
id: 'problem',
304+
data: problems.value
305+
});
306+
problems.icon = 'chevron-right';
307+
problemsService.update(problems);
308+
});
309+
}, 200);
310+
311+
const convertMsgToProblemItem = (tab: IEditorTab<any>, code: string, msgs: ParseError[] = []) => {
312+
const rootId = tab?.id;
313+
const rootName = `${tab.name || ''}`;
314+
const languageProblems = {
315+
id: rootId,
316+
name: rootName,
317+
isLeaf: false,
318+
value: {
319+
code: rootName,
320+
message: '',
321+
startLineNumber: 0,
322+
startColumn: 1,
323+
endLineNumber: 0,
324+
endColumn: 1,
325+
status: monaco.MarkerSeverity.Hint
326+
},
327+
children: []
328+
} as any;
329+
330+
languageProblems.children = msgs.map((msg: any, index: number) => {
331+
return {
332+
id: `${rootId}-${index}`,
333+
name: msg.code || '',
334+
isLeaf: true,
335+
value: {
336+
code: msg.code,
337+
message: msg.message,
338+
startLineNumber: Number(msg.startLine),
339+
startColumn: Number(msg.startCol),
340+
endLineNumber: Number(msg.endLine),
341+
endColumn: Number(msg.endCol),
342+
status: monaco.MarkerSeverity.Error
343+
},
344+
children: []
345+
};
346+
});
347+
348+
return languageProblems;
349+
};
350+
351+
const activeExplore = (tab: Partial<TabGroup>, molecule: IMoleculeContext) => {
352+
const language = (tab.tabId as string)?.split('_')?.[0];
353+
const curActiveExplore = molecule.explorer.getActive() || [];
354+
const isExist = curActiveExplore
355+
.map((item) => (item as string).toLocaleLowerCase())
356+
.includes(language?.toLocaleLowerCase());
357+
if (!isExist && language) {
358+
const activeExploreId = SQL_LANGUAGES.find(
359+
(item) => item.toLocaleLowerCase() === language.toLocaleLowerCase()
360+
) as string;
361+
molecule.explorer.setActive([...curActiveExplore, activeExploreId]?.filter(Boolean));
362+
}
363+
};
364+
365+
const parseToAST = (molecule: IMoleculeContext, languageService: LanguageService) => {
366+
const sql = molecule.editor.getCurrentGroup()?.editorInstance?.getValue();
367+
368+
const curActiveTab = molecule.editor.getCurrentTab();
369+
const lang = curActiveTab?.language?.toLocaleLowerCase();
370+
if (lang && sql) {
371+
languageService.parserTreeToString(lang, sql).then((res) => {
372+
const pre = res?.replace(/(\(|\))/g, '$1\n');
373+
const format = new lips.Formatter(pre);
374+
const formatted = format.format({
375+
indent: 2,
376+
offset: 2
377+
});
378+
molecule.panel.setCurrent(molecule.builtin.getConstants().PANEL_ITEM_OUTPUT);
379+
molecule.output.setState({ value: formatted });
380+
});
198381
}
199382
};
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { getFiles } from '@/utils';
2+
import { IExtension } from '@dtinsight/molecule';
3+
4+
export const ExtendsFolderTree: IExtension = {
5+
id: 'ExtendsFolderTree',
6+
name: 'Extend The Default Folder Tree',
7+
contributes: {},
8+
activate: function (molecule): void {
9+
molecule.folderTree.onLoad((id) => {
10+
molecule.folderTree.addLoading(id);
11+
getFiles(id as string)
12+
.then(([folder, files]) => {
13+
molecule.folderTree.update({
14+
id,
15+
children: [...folder, ...files]
16+
});
17+
})
18+
.catch((err) => {
19+
molecule.layout.setNotification(true);
20+
molecule.notification.add({
21+
id: `getFiles${id}`,
22+
value: err.message
23+
});
24+
})
25+
.finally(() => {
26+
molecule.folderTree.removeLoading(id);
27+
});
28+
});
29+
}
30+
};

website/src/utils/index.ts

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { tree } from '@dtinsight/molecule';
1+
import { IMoleculeContext, tree } from '@dtinsight/molecule';
22

33
export function getWorkspace(): Promise<tree.TreeNodeModel<any>> {
44
return fetch('/api/getWorkspace')
@@ -59,3 +59,44 @@ export function searchFileContents(value: string) {
5959
}) => data
6060
);
6161
}
62+
63+
export function openFile(treeNode: any, molecule: IMoleculeContext) {
64+
molecule.editor.setLoading(true);
65+
getFileContent(treeNode.id as string)
66+
.then((data) => {
67+
const tabData = {
68+
id: treeNode.id,
69+
name: treeNode.name,
70+
icon: treeNode.icon || 'file',
71+
value: data,
72+
language: (() => {
73+
const name = treeNode.name;
74+
if (typeof name !== 'string') return 'plain';
75+
if (name.endsWith('.md')) return 'markdown';
76+
if (name.endsWith('.yml')) return 'yml';
77+
if (name.endsWith('.js')) return 'javascript';
78+
if (name.endsWith('.ts')) return 'typescript';
79+
if (name.endsWith('.tsx')) return 'typescriptreact';
80+
if (name.endsWith('.json')) return 'json';
81+
if (name.endsWith('.scss')) return 'css';
82+
if (name.endsWith('.html')) return 'html';
83+
return 'plain';
84+
})(),
85+
breadcrumb: (treeNode.id as string)
86+
.split('/')
87+
.filter(Boolean)
88+
.map((i) => ({ id: i, name: i }))
89+
};
90+
molecule.editor.open(tabData, molecule.editor.getState().groups?.at(0)?.id);
91+
})
92+
.catch((err) => {
93+
molecule.layout.setNotification(true);
94+
molecule.notification.add({
95+
id: `getFileContent_${treeNode.id}`,
96+
value: err.message
97+
});
98+
})
99+
.finally(() => {
100+
molecule.editor.setLoading(false);
101+
});
102+
}

website/src/workbench/apiDocPage/index.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
1-
// 接口文档 sql-parser 的
1+
// sql-parser 的 接口文档
22

33
import { IMoleculeContext } from '@dtinsight/molecule';
44

5-
// sql-parser 的 unit 文档
65
const ApiDocPage = ({ molecule }: { molecule: IMoleculeContext }) => {
76
return <div>接口文档</div>;
87
};

website/src/workbench/problems/clients/paneView/index.tsx

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,6 @@ function ProblemsPaneView({ problemsService }: { problemsService: any }) {
2525
const context = useContext(Context);
2626
const { onselect } = context;
2727

28-
useEffect(() => {
29-
console.log('组件重新渲染');
30-
}, [data]);
31-
3228
if (!data?.length) {
3329
return (
3430
<div style={{ margin: '0 18px', userSelect: 'none' }}>

0 commit comments

Comments
 (0)