@difizen/libro-lab 0.1.13 → 0.1.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/es/common/icon.d.ts +6 -0
  2. package/es/common/icon.d.ts.map +1 -1
  3. package/es/common/icon.js +326 -0
  4. package/es/kernel-and-terminal-panel/collapse/collapse-content.d.ts +11 -0
  5. package/es/kernel-and-terminal-panel/collapse/collapse-content.d.ts.map +1 -0
  6. package/es/kernel-and-terminal-panel/collapse/collapse-content.js +53 -0
  7. package/es/kernel-and-terminal-panel/collapse/index.d.ts +31 -0
  8. package/es/kernel-and-terminal-panel/collapse/index.d.ts.map +1 -0
  9. package/es/kernel-and-terminal-panel/collapse/index.js +103 -0
  10. package/es/kernel-and-terminal-panel/collapse/index.less +89 -0
  11. package/es/kernel-and-terminal-panel/collapse/kernel-collapse-content-item.d.ts +8 -0
  12. package/es/kernel-and-terminal-panel/collapse/kernel-collapse-content-item.d.ts.map +1 -0
  13. package/es/kernel-and-terminal-panel/collapse/kernel-collapse-content-item.js +79 -0
  14. package/es/kernel-and-terminal-panel/collapse/kernel-collapse-content.d.ts +9 -0
  15. package/es/kernel-and-terminal-panel/collapse/kernel-collapse-content.d.ts.map +1 -0
  16. package/es/kernel-and-terminal-panel/collapse/kernel-collapse-content.js +13 -0
  17. package/es/kernel-and-terminal-panel/collapse/page-collapse-content.d.ts +3 -0
  18. package/es/kernel-and-terminal-panel/collapse/page-collapse-content.d.ts.map +1 -0
  19. package/es/kernel-and-terminal-panel/collapse/page-collapse-content.js +38 -0
  20. package/es/kernel-and-terminal-panel/index.d.ts +2 -0
  21. package/es/kernel-and-terminal-panel/index.d.ts.map +1 -0
  22. package/es/kernel-and-terminal-panel/index.js +1 -0
  23. package/es/kernel-and-terminal-panel/index.less +5 -0
  24. package/es/kernel-and-terminal-panel/kernel-and-terminal-panel-view.d.ts +24 -0
  25. package/es/kernel-and-terminal-panel/kernel-and-terminal-panel-view.d.ts.map +1 -0
  26. package/es/kernel-and-terminal-panel/kernel-and-terminal-panel-view.js +320 -0
  27. package/es/kernel-and-terminal-panel/module.d.ts +3 -0
  28. package/es/kernel-and-terminal-panel/module.d.ts.map +1 -0
  29. package/es/kernel-and-terminal-panel/module.js +13 -0
  30. package/es/kernel-and-terminal-panel/panel-command.d.ts +18 -0
  31. package/es/kernel-and-terminal-panel/panel-command.d.ts.map +1 -0
  32. package/es/kernel-and-terminal-panel/panel-command.js +80 -0
  33. package/es/layout/layout-service.d.ts +2 -0
  34. package/es/layout/layout-service.d.ts.map +1 -1
  35. package/es/layout/layout-service.js +18 -0
  36. package/es/layout/main.d.ts.map +1 -1
  37. package/es/layout/main.js +20 -7
  38. package/es/module.d.ts.map +1 -1
  39. package/es/module.js +4 -2
  40. package/package.json +9 -8
  41. package/src/common/icon.tsx +298 -0
  42. package/src/kernel-and-terminal-panel/collapse/collapse-content.tsx +72 -0
  43. package/src/kernel-and-terminal-panel/collapse/index.less +89 -0
  44. package/src/kernel-and-terminal-panel/collapse/index.tsx +128 -0
  45. package/src/kernel-and-terminal-panel/collapse/kernel-collapse-content-item.tsx +87 -0
  46. package/src/kernel-and-terminal-panel/collapse/kernel-collapse-content.tsx +23 -0
  47. package/src/kernel-and-terminal-panel/collapse/page-collapse-content.tsx +49 -0
  48. package/src/kernel-and-terminal-panel/index.less +5 -0
  49. package/src/kernel-and-terminal-panel/index.ts +1 -0
  50. package/src/kernel-and-terminal-panel/kernel-and-terminal-panel-view.tsx +218 -0
  51. package/src/kernel-and-terminal-panel/module.ts +20 -0
  52. package/src/kernel-and-terminal-panel/panel-command.tsx +57 -0
  53. package/src/layout/layout-service.ts +17 -0
  54. package/src/layout/main.tsx +13 -1
  55. package/src/module.tsx +3 -0
@@ -0,0 +1,72 @@
1
+ import { CloseOutlined } from '@ant-design/icons';
2
+ import { TerminalCommands } from '@difizen/libro-terminal';
3
+ import { CommandRegistry, useInject } from '@difizen/mana-app';
4
+ import React from 'react';
5
+
6
+ import {
7
+ existedLSP,
8
+ openedPage,
9
+ runningKernel,
10
+ runningTerminal,
11
+ } from '../../common/icon.js';
12
+
13
+ import { LibroPanelCollapseItemType } from './index.js';
14
+ import type { LibroPanelCollapseItem } from './index.js';
15
+
16
+ export const getIcon = (type: LibroPanelCollapseItemType) => {
17
+ switch (type) {
18
+ case LibroPanelCollapseItemType.PAGE:
19
+ return openedPage();
20
+ case LibroPanelCollapseItemType.KERNEL:
21
+ return runningKernel();
22
+ case LibroPanelCollapseItemType.TERMINAL:
23
+ return runningTerminal();
24
+ case LibroPanelCollapseItemType.LSP:
25
+ return existedLSP();
26
+ }
27
+ };
28
+
29
+ interface Props {
30
+ type: LibroPanelCollapseItemType;
31
+ items: LibroPanelCollapseItem[];
32
+ }
33
+
34
+ export const LibroCollapseContent: React.FC<Props> = (props: Props) => {
35
+ const commandRegistry = useInject<CommandRegistry>(CommandRegistry);
36
+
37
+ return (
38
+ <>
39
+ {props.items.map((item) => {
40
+ return (
41
+ <div
42
+ className="libro-panel-collapse-item"
43
+ key={item.id}
44
+ onClick={() => {
45
+ if (props.type === LibroPanelCollapseItemType.TERMINAL) {
46
+ commandRegistry.executeCommand(
47
+ TerminalCommands['OpenTerminal'].id,
48
+ item.name,
49
+ );
50
+ }
51
+ }}
52
+ >
53
+ <div className="libro-panel-collapse-item-icon">{getIcon(props.type)}</div>
54
+ <div className="libro-panel-collapse-item-label">{item.name}</div>
55
+ <div
56
+ className="libro-panel-collapse-item-close"
57
+ onClick={(e) => {
58
+ e.stopPropagation();
59
+ e.preventDefault();
60
+ if (item.shutdown) {
61
+ item.shutdown();
62
+ }
63
+ }}
64
+ >
65
+ <CloseOutlined />
66
+ </div>
67
+ </div>
68
+ );
69
+ })}
70
+ </>
71
+ );
72
+ };
@@ -0,0 +1,89 @@
1
+ .libro-panel-collapse-container {
2
+ width: 100%;
3
+ margin-bottom: 16px;
4
+ }
5
+
6
+ .libro-panel-collapse-header {
7
+ user-select: none; // 双击不选中文本
8
+ color: rgba(0, 10, 26, 68%);
9
+ font-size: 12px;
10
+
11
+ .libro-panel-collapse-header-left {
12
+ display: inline-block;
13
+ cursor: pointer;
14
+
15
+ .libro-panel-collapse-header-icon {
16
+ display: inline-block;
17
+ margin-right: 5px;
18
+ }
19
+
20
+ .libro-panel-collapse-header-label {
21
+ display: inline-block;
22
+ }
23
+ }
24
+
25
+ .libro-panel-collapse-header-closeAll {
26
+ // display: inline-block;
27
+ cursor: pointer;
28
+ color: rgba(0, 10, 26, 47%);
29
+ float: right;
30
+ }
31
+ }
32
+
33
+ .libro-panel-collapse-kernel-item-container {
34
+ margin-left: 15px;
35
+ }
36
+
37
+ .libro-panel-collapse-content,
38
+ .libro-panel-collapse-kernel-item-container {
39
+ .libro-panel-collapse-item,
40
+ .libro-panel-collapse-kernel-item {
41
+ cursor: pointer;
42
+ user-select: none; // 双击不选中文本
43
+ color: rgba(0, 10, 26, 65%);
44
+ font-size: 12px;
45
+ margin: 8px 0;
46
+ padding: 0 10px;
47
+ display: flex;
48
+
49
+ .libro-panel-collapse-item-toggle {
50
+ display: inline-block;
51
+ margin: auto 5px auto 0;
52
+ }
53
+
54
+ .libro-panel-collapse-item-icon,
55
+ .libro-panel-collapse-kernel-item-icon {
56
+ display: inline-block;
57
+ margin: auto 5px auto 0;
58
+
59
+ & > :first-child {
60
+ vertical-align: middle;
61
+ }
62
+ }
63
+
64
+ .libro-panel-collapse-item-label,
65
+ .libro-panel-collapse-kernel-item-name {
66
+ display: inline-block;
67
+ min-width: 50px;
68
+ white-space: nowrap; /* 避免文本换行 */
69
+ overflow: hidden; /* 隐藏超出div的内容 */
70
+ text-overflow: ellipsis; /* 在文本超出宽度时显示省略号 */
71
+ margin: auto 0;
72
+ }
73
+
74
+ .libro-panel-collapse-item-close {
75
+ // display: inline-block;
76
+ margin: auto 0 auto auto;
77
+ }
78
+
79
+ .libro-panel-collapse-item-close:hover {
80
+ background: rgba(0, 10, 26, 15%);
81
+ border-radius: 4px;
82
+ }
83
+ }
84
+
85
+ .libro-panel-collapse-item:hover {
86
+ background: rgba(0, 10, 26, 5%);
87
+ border-radius: 4px;
88
+ }
89
+ }
@@ -0,0 +1,128 @@
1
+ import { CaretDownOutlined, CaretRightOutlined } from '@ant-design/icons';
2
+ import { ViewContext } from '@difizen/mana-app';
3
+ import { Empty, Popconfirm } from 'antd';
4
+ import React, { useState } from 'react';
5
+
6
+ import type { SaveableTabView } from '../../index.js';
7
+
8
+ import { LibroCollapseContent } from './collapse-content.js';
9
+
10
+ import './index.less';
11
+ import { LibroKernelCollapseContent } from './kernel-collapse-content.js';
12
+ import { OpenedTabs } from './page-collapse-content.js';
13
+
14
+ export enum LibroPanelCollapseItemType {
15
+ PAGE = 'Page',
16
+ KERNEL = 'Kernel',
17
+ TERMINAL = 'Terminal',
18
+ LSP = 'LSP',
19
+ }
20
+
21
+ export interface LibroPanelCollapseItem {
22
+ id: string;
23
+ name: string;
24
+ shutdown?: () => Promise<void>;
25
+ restart?: () => Promise<void>;
26
+ }
27
+
28
+ export interface LibroPanelCollapseKernelItem extends LibroPanelCollapseItem {
29
+ notebooks: { sessionId: string; name: string; path: string }[];
30
+ }
31
+
32
+ interface Props {
33
+ type: LibroPanelCollapseItemType;
34
+ items: LibroPanelCollapseItem[] | undefined;
35
+ tabView?: SaveableTabView;
36
+ shutdownAll?: () => Promise<void>;
37
+ }
38
+
39
+ const getCollapseContentView = (
40
+ type: LibroPanelCollapseItemType,
41
+ items: LibroPanelCollapseItem[] | undefined,
42
+ tabView?: SaveableTabView,
43
+ ) => {
44
+ if (!items) {
45
+ return (
46
+ <Empty
47
+ image={Empty.PRESENTED_IMAGE_SIMPLE}
48
+ description="暂无内容"
49
+ className="kernel-and-terminal-panel-empty"
50
+ />
51
+ );
52
+ }
53
+
54
+ switch (type) {
55
+ case LibroPanelCollapseItemType.PAGE:
56
+ return (
57
+ <ViewContext view={tabView!}>
58
+ <OpenedTabs />
59
+ </ViewContext>
60
+ );
61
+
62
+ case LibroPanelCollapseItemType.KERNEL:
63
+ return (
64
+ <LibroKernelCollapseContent
65
+ type={type}
66
+ items={items as LibroPanelCollapseKernelItem[]}
67
+ />
68
+ );
69
+ case LibroPanelCollapseItemType.TERMINAL:
70
+ case LibroPanelCollapseItemType.LSP:
71
+ return <LibroCollapseContent type={type} items={items!} />;
72
+ }
73
+ };
74
+
75
+ const getCollapseHeaderLabel = (type: LibroPanelCollapseItemType) => {
76
+ switch (type) {
77
+ case LibroPanelCollapseItemType.PAGE:
78
+ return '已开启的标签页';
79
+ case LibroPanelCollapseItemType.KERNEL:
80
+ return '运行的内核';
81
+ case LibroPanelCollapseItemType.TERMINAL:
82
+ return '运行的终端';
83
+ case LibroPanelCollapseItemType.LSP:
84
+ return '语言服务';
85
+ }
86
+ };
87
+
88
+ export const LibroCollapse: React.FC<Props> = (props: Props) => {
89
+ const [open, setOpen] = useState<boolean>(true);
90
+ return (
91
+ <div className="libro-panel-collapse-container" key={props.type}>
92
+ <div className="libro-panel-collapse-header">
93
+ <div
94
+ className="libro-panel-collapse-header-left"
95
+ onClick={() => {
96
+ setOpen(!open);
97
+ }}
98
+ >
99
+ <div className="libro-panel-collapse-header-icon">
100
+ {open ? <CaretDownOutlined /> : <CaretRightOutlined />}
101
+ </div>
102
+ <div className="libro-panel-collapse-header-label">
103
+ {getCollapseHeaderLabel(props.type)}
104
+ </div>
105
+ </div>
106
+ <div className="libro-panel-collapse-header-closeAll">
107
+ <Popconfirm
108
+ title="你确定要关闭全部吗?"
109
+ okText="确定"
110
+ cancelText="取消"
111
+ onConfirm={() => {
112
+ if (props.shutdownAll) {
113
+ props.shutdownAll();
114
+ }
115
+ }}
116
+ >
117
+ 关闭全部
118
+ </Popconfirm>
119
+ </div>
120
+ </div>
121
+ {open && (
122
+ <div className="libro-panel-collapse-content">
123
+ {getCollapseContentView(props.type, props.items, props.tabView)}
124
+ </div>
125
+ )}
126
+ </div>
127
+ );
128
+ };
@@ -0,0 +1,87 @@
1
+ import {
2
+ CaretDownOutlined,
3
+ CaretRightOutlined,
4
+ CloseOutlined,
5
+ } from '@ant-design/icons';
6
+ import { OpenerService, URI, useInject } from '@difizen/mana-app';
7
+ import React, { useState } from 'react';
8
+
9
+ import { fileUnderKernel, runningKernel } from '../../common/icon.js';
10
+
11
+ import type { LibroPanelCollapseKernelItem } from './index.js';
12
+
13
+ interface Props {
14
+ item: LibroPanelCollapseKernelItem;
15
+ }
16
+
17
+ export const LibroKernelCollapseContentItem: React.FC<Props> = (props: Props) => {
18
+ const item = props.item;
19
+ const [open, setOpen] = useState<boolean>(true);
20
+ const openService = useInject<OpenerService>(OpenerService);
21
+
22
+ return (
23
+ <>
24
+ <div
25
+ className="libro-panel-collapse-item"
26
+ key={item.id}
27
+ onClick={() => {
28
+ setOpen(!open);
29
+ }}
30
+ >
31
+ <div className="libro-panel-collapse-item-toggle">
32
+ {open ? <CaretDownOutlined /> : <CaretRightOutlined />}
33
+ </div>
34
+ <div className="libro-panel-collapse-item-icon">{runningKernel()}</div>
35
+ <div className="libro-panel-collapse-item-label">{item.name}</div>
36
+ <div
37
+ className="libro-panel-collapse-item-close"
38
+ onClick={(e) => {
39
+ if (item.shutdown) {
40
+ item.shutdown();
41
+ }
42
+ e.preventDefault();
43
+ e.stopPropagation();
44
+ }}
45
+ >
46
+ <CloseOutlined />
47
+ </div>
48
+ </div>
49
+ {open && (
50
+ <div className="libro-panel-collapse-kernel-item-container">
51
+ {item.notebooks.map((notebook) => (
52
+ <div
53
+ className="libro-panel-collapse-kernel-item"
54
+ key={notebook.sessionId}
55
+ onClick={() => {
56
+ const uri = new URI(notebook.path);
57
+ const name = notebook.name;
58
+ openService
59
+ .getOpener(uri)
60
+ .then((opener) => {
61
+ if (opener) {
62
+ opener.open(uri, {
63
+ viewOptions: {
64
+ name: name,
65
+ },
66
+ });
67
+ }
68
+ return;
69
+ })
70
+ .catch((e) => {
71
+ console.error(e);
72
+ });
73
+ }}
74
+ >
75
+ <div className="libro-panel-collapse-kernel-item-icon">
76
+ {fileUnderKernel()}
77
+ </div>
78
+ <div className="libro-panel-collapse-kernel-item-name">
79
+ {notebook.name}
80
+ </div>
81
+ </div>
82
+ ))}
83
+ </div>
84
+ )}
85
+ </>
86
+ );
87
+ };
@@ -0,0 +1,23 @@
1
+ import React from 'react';
2
+
3
+ import { LibroKernelCollapseContentItem } from './kernel-collapse-content-item.js';
4
+
5
+ import type {
6
+ LibroPanelCollapseItemType,
7
+ LibroPanelCollapseKernelItem,
8
+ } from './index.js';
9
+
10
+ interface Props {
11
+ type: LibroPanelCollapseItemType;
12
+ items: LibroPanelCollapseKernelItem[];
13
+ }
14
+
15
+ export const LibroKernelCollapseContent: React.FC<Props> = (props: Props) => {
16
+ return (
17
+ <>
18
+ {props.items.map((item) => {
19
+ return <LibroKernelCollapseContentItem item={item} key={item.id} />;
20
+ })}
21
+ </>
22
+ );
23
+ };
@@ -0,0 +1,49 @@
1
+ import { CloseOutlined } from '@ant-design/icons';
2
+ import { renderNode, useInject, ViewContext, ViewInstance } from '@difizen/mana-app';
3
+
4
+ import type { SaveableTabView } from '../../index.js';
5
+
6
+ export const OpenedTabs: React.FC = () => {
7
+ const tabs = useInject<SaveableTabView>(ViewInstance);
8
+
9
+ const renderTitleIcon = renderNode;
10
+ const renderTitleLabel = renderNode;
11
+
12
+ return (
13
+ <>
14
+ {tabs.children.map((item) => {
15
+ return (
16
+ <ViewContext view={item} key={item.id}>
17
+ <div
18
+ title={item.title.caption}
19
+ className="libro-panel-collapse-item"
20
+ onClick={() => {
21
+ tabs.onChange(item.id);
22
+ }}
23
+ >
24
+ {item.title.icon && (
25
+ <span className="libro-panel-collapse-item-icon">
26
+ {renderTitleIcon(item.title.icon)}
27
+ </span>
28
+ )}
29
+ <div className="libro-panel-collapse-item-label">
30
+ {renderTitleLabel(item.title.label)}
31
+ </div>
32
+ {item.title.closable && (
33
+ <div
34
+ className="libro-panel-collapse-item-close"
35
+ onClick={(e) => {
36
+ e.stopPropagation();
37
+ item.dispose();
38
+ }}
39
+ >
40
+ <CloseOutlined />
41
+ </div>
42
+ )}
43
+ </div>
44
+ </ViewContext>
45
+ );
46
+ })}
47
+ </>
48
+ );
49
+ };
@@ -0,0 +1,5 @@
1
+ .kernel-and-terminal-panel {
2
+ height: 100%;
3
+ padding: 0 10px;
4
+ overflow-y: scroll;
5
+ }
@@ -0,0 +1 @@
1
+ export * from './module.js';
@@ -0,0 +1,218 @@
1
+ import { LibroKernelManager, LibroSessionManager } from '@difizen/libro-kernel';
2
+ import type { ILanguageServerManager, TLanguageServerId } from '@difizen/libro-lsp';
3
+ import { ILSPDocumentConnectionManager } from '@difizen/libro-lsp';
4
+ import { TerminalManager } from '@difizen/libro-terminal';
5
+ import {
6
+ BaseView,
7
+ inject,
8
+ singleton,
9
+ useInject,
10
+ view,
11
+ ViewInstance,
12
+ ViewManager,
13
+ } from '@difizen/mana-app';
14
+ import { useEffect, useState } from 'react';
15
+
16
+ import { KernelAndTerminal } from '../common/index.js';
17
+ import type { SaveableTabView } from '../index.js';
18
+ import { LibroLabLayoutSlots } from '../index.js';
19
+ import { LayoutService } from '../layout/layout-service.js';
20
+
21
+ import type {
22
+ LibroPanelCollapseItem,
23
+ LibroPanelCollapseKernelItem,
24
+ } from './collapse/index.js';
25
+ import { LibroPanelCollapseItemType, LibroCollapse } from './collapse/index.js';
26
+
27
+ import './index.less';
28
+
29
+ const PanelRender: React.FC = () => {
30
+ const instance = useInject<KernelAndTerminalPanelView>(ViewInstance);
31
+ const openedTabView = instance.getAllOpenedTabView();
32
+
33
+ const {
34
+ libroKernelManager,
35
+ libroSessionManager,
36
+ terminalManager,
37
+ lspManager,
38
+ lspConnectionManager,
39
+ } = instance;
40
+
41
+ const [kernelItems, setKernelItems] = useState<
42
+ LibroPanelCollapseKernelItem[] | undefined
43
+ >();
44
+
45
+ const [terminalItems, setTerminalItems] = useState<
46
+ LibroPanelCollapseItem[] | undefined
47
+ >();
48
+
49
+ // const lspManager = useInject<ILSPDocumentConnectionManager>(
50
+ // DocumentConnectionManager,
51
+ // ).languageServerManager;
52
+
53
+ const [lspItems, setLSPItems] = useState<LibroPanelCollapseItem[] | undefined>();
54
+
55
+ lspManager.sessionsChanged(() => {
56
+ const sessions = lspManager.sessions;
57
+
58
+ const items = [] as LibroPanelCollapseItem[];
59
+
60
+ sessions.forEach((session: any, key: string) => {
61
+ items.push({
62
+ id: key,
63
+ name: `${key} (${session.spec.languages.join('/')})`,
64
+ shutdown: async () =>
65
+ lspConnectionManager.disconnectServer(key as TLanguageServerId),
66
+ });
67
+ });
68
+
69
+ setLSPItems(items);
70
+ });
71
+
72
+ useEffect(() => {
73
+ if (
74
+ !libroSessionManager.running ||
75
+ (libroSessionManager.running && libroSessionManager.running.size === 0)
76
+ ) {
77
+ setKernelItems(undefined);
78
+ return;
79
+ }
80
+
81
+ // kernelId -> item
82
+ const items = new Map<string, LibroPanelCollapseKernelItem>();
83
+
84
+ const runningSessions = libroSessionManager.running.values();
85
+
86
+ for (const session of runningSessions) {
87
+ const kernel = session.kernel!;
88
+ if (items.has(kernel.id)) {
89
+ items.get(kernel.id)?.notebooks.push({
90
+ sessionId: session.id,
91
+ name: session.name,
92
+ path: session.path,
93
+ });
94
+ } else {
95
+ items.set(kernel.id, {
96
+ id: kernel.id,
97
+ name: kernel.name,
98
+ shutdown: async () => libroKernelManager.shutdown(kernel.id),
99
+ notebooks: [
100
+ { sessionId: session.id, name: session.name, path: session.path },
101
+ ],
102
+ });
103
+ }
104
+ }
105
+
106
+ setKernelItems(Array.from(items.values()));
107
+ }, [libroKernelManager, libroSessionManager.running]);
108
+
109
+ useEffect(() => {
110
+ if (
111
+ !terminalManager.runningModels ||
112
+ (terminalManager.runningModels && terminalManager.runningModels.length === 0)
113
+ ) {
114
+ setTerminalItems(undefined);
115
+ return;
116
+ }
117
+
118
+ const items = [];
119
+ for (const terminal of terminalManager.runningModels) {
120
+ items.push({
121
+ id: 'terminal/' + terminal,
122
+ name: terminal,
123
+ shutdown: async () => terminalManager.shutdown(terminal),
124
+ });
125
+ }
126
+
127
+ setTerminalItems(items);
128
+
129
+ // eslint-disable-next-line react-hooks/exhaustive-deps
130
+ }, [terminalManager.runningModels]);
131
+
132
+ return (
133
+ <div className="kernel-and-terminal-panel">
134
+ <LibroCollapse
135
+ type={LibroPanelCollapseItemType.PAGE}
136
+ items={openedTabView.children.map((item) => {
137
+ return {
138
+ id: item.id + '',
139
+ name: item.title.label as string,
140
+ };
141
+ })}
142
+ tabView={openedTabView}
143
+ shutdownAll={async () => {
144
+ // dispose会影响原始数组,这里使用解构赋值copy一份数组。
145
+ for (const item of [...openedTabView.children]) {
146
+ if (item.title.closable) {
147
+ item.dispose();
148
+ }
149
+ }
150
+ }}
151
+ />
152
+ <LibroCollapse
153
+ type={LibroPanelCollapseItemType.KERNEL}
154
+ items={kernelItems}
155
+ shutdownAll={async () => {
156
+ await libroKernelManager.shutdownAll();
157
+ libroSessionManager.refreshRunning();
158
+ }}
159
+ />
160
+ <LibroCollapse
161
+ type={LibroPanelCollapseItemType.TERMINAL}
162
+ items={terminalItems}
163
+ shutdownAll={() => terminalManager.shutdownAll()}
164
+ />
165
+ <LibroCollapse
166
+ type={LibroPanelCollapseItemType.LSP}
167
+ items={lspItems}
168
+ shutdownAll={async () => lspConnectionManager.disconnectAllServers()}
169
+ />
170
+ </div>
171
+ );
172
+ };
173
+
174
+ export const KernelAndTerminalPanelViewId = 'libro-kernel-and-terminal-view';
175
+
176
+ @singleton()
177
+ @view(KernelAndTerminalPanelViewId)
178
+ export class KernelAndTerminalPanelView extends BaseView {
179
+ override view = PanelRender;
180
+ @inject(ViewManager) protected viewManager: ViewManager;
181
+ @inject(LayoutService) protected layoutService: LayoutService;
182
+
183
+ libroKernelManager: LibroKernelManager;
184
+ libroSessionManager: LibroSessionManager;
185
+ terminalManager: TerminalManager;
186
+ lspConnectionManager: ILSPDocumentConnectionManager;
187
+ lspManager: ILanguageServerManager;
188
+
189
+ constructor(
190
+ @inject(LibroKernelManager) libroKernelManager: LibroKernelManager,
191
+ @inject(LibroSessionManager) libroSessionManager: LibroSessionManager,
192
+ @inject(TerminalManager) terminalManager: TerminalManager,
193
+ @inject(ILSPDocumentConnectionManager)
194
+ lspDocumentConnectionManager: ILSPDocumentConnectionManager,
195
+ ) {
196
+ super();
197
+ this.title.icon = <KernelAndTerminal />;
198
+ this.title.label = '运行的终端和内核';
199
+
200
+ this.libroKernelManager = libroKernelManager;
201
+ this.libroSessionManager = libroSessionManager;
202
+ this.terminalManager = terminalManager;
203
+ this.lspConnectionManager = lspDocumentConnectionManager;
204
+ this.lspManager = lspDocumentConnectionManager.languageServerManager;
205
+ }
206
+
207
+ getAllOpenedTabView(): SaveableTabView {
208
+ return this.layoutService.getAllSlotView(
209
+ LibroLabLayoutSlots.content,
210
+ ) as SaveableTabView;
211
+ }
212
+
213
+ refresh() {
214
+ this.libroSessionManager.refreshRunning();
215
+ this.terminalManager.refreshRunning();
216
+ this.lspManager.refreshRunning();
217
+ }
218
+ }
@@ -0,0 +1,20 @@
1
+ import { createViewPreference, ManaModule } from '@difizen/mana-app';
2
+
3
+ import { LibroLabLayoutSlots } from '../layout/protocol.js';
4
+
5
+ import { KernelAndTerminalPanelView } from './kernel-and-terminal-panel-view.js';
6
+ import { PanelCommandContribution } from './panel-command.js';
7
+
8
+ export const LibroKernelAndTerminalPanelModule = ManaModule.create().register(
9
+ PanelCommandContribution,
10
+ KernelAndTerminalPanelView,
11
+ createViewPreference({
12
+ view: KernelAndTerminalPanelView,
13
+ slot: LibroLabLayoutSlots.navigator,
14
+ autoCreate: true,
15
+ openOptions: {
16
+ reveal: true,
17
+ order: 'kernel',
18
+ },
19
+ }),
20
+ );