@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.
- package/es/common/icon.d.ts +6 -0
- package/es/common/icon.d.ts.map +1 -1
- package/es/common/icon.js +326 -0
- package/es/kernel-and-terminal-panel/collapse/collapse-content.d.ts +11 -0
- package/es/kernel-and-terminal-panel/collapse/collapse-content.d.ts.map +1 -0
- package/es/kernel-and-terminal-panel/collapse/collapse-content.js +53 -0
- package/es/kernel-and-terminal-panel/collapse/index.d.ts +31 -0
- package/es/kernel-and-terminal-panel/collapse/index.d.ts.map +1 -0
- package/es/kernel-and-terminal-panel/collapse/index.js +103 -0
- package/es/kernel-and-terminal-panel/collapse/index.less +89 -0
- package/es/kernel-and-terminal-panel/collapse/kernel-collapse-content-item.d.ts +8 -0
- package/es/kernel-and-terminal-panel/collapse/kernel-collapse-content-item.d.ts.map +1 -0
- package/es/kernel-and-terminal-panel/collapse/kernel-collapse-content-item.js +79 -0
- package/es/kernel-and-terminal-panel/collapse/kernel-collapse-content.d.ts +9 -0
- package/es/kernel-and-terminal-panel/collapse/kernel-collapse-content.d.ts.map +1 -0
- package/es/kernel-and-terminal-panel/collapse/kernel-collapse-content.js +13 -0
- package/es/kernel-and-terminal-panel/collapse/page-collapse-content.d.ts +3 -0
- package/es/kernel-and-terminal-panel/collapse/page-collapse-content.d.ts.map +1 -0
- package/es/kernel-and-terminal-panel/collapse/page-collapse-content.js +38 -0
- package/es/kernel-and-terminal-panel/index.d.ts +2 -0
- package/es/kernel-and-terminal-panel/index.d.ts.map +1 -0
- package/es/kernel-and-terminal-panel/index.js +1 -0
- package/es/kernel-and-terminal-panel/index.less +5 -0
- package/es/kernel-and-terminal-panel/kernel-and-terminal-panel-view.d.ts +24 -0
- package/es/kernel-and-terminal-panel/kernel-and-terminal-panel-view.d.ts.map +1 -0
- package/es/kernel-and-terminal-panel/kernel-and-terminal-panel-view.js +320 -0
- package/es/kernel-and-terminal-panel/module.d.ts +3 -0
- package/es/kernel-and-terminal-panel/module.d.ts.map +1 -0
- package/es/kernel-and-terminal-panel/module.js +13 -0
- package/es/kernel-and-terminal-panel/panel-command.d.ts +18 -0
- package/es/kernel-and-terminal-panel/panel-command.d.ts.map +1 -0
- package/es/kernel-and-terminal-panel/panel-command.js +80 -0
- package/es/layout/layout-service.d.ts +2 -0
- package/es/layout/layout-service.d.ts.map +1 -1
- package/es/layout/layout-service.js +18 -0
- package/es/layout/main.d.ts.map +1 -1
- package/es/layout/main.js +20 -7
- package/es/module.d.ts.map +1 -1
- package/es/module.js +4 -2
- package/package.json +9 -8
- package/src/common/icon.tsx +298 -0
- package/src/kernel-and-terminal-panel/collapse/collapse-content.tsx +72 -0
- package/src/kernel-and-terminal-panel/collapse/index.less +89 -0
- package/src/kernel-and-terminal-panel/collapse/index.tsx +128 -0
- package/src/kernel-and-terminal-panel/collapse/kernel-collapse-content-item.tsx +87 -0
- package/src/kernel-and-terminal-panel/collapse/kernel-collapse-content.tsx +23 -0
- package/src/kernel-and-terminal-panel/collapse/page-collapse-content.tsx +49 -0
- package/src/kernel-and-terminal-panel/index.less +5 -0
- package/src/kernel-and-terminal-panel/index.ts +1 -0
- package/src/kernel-and-terminal-panel/kernel-and-terminal-panel-view.tsx +218 -0
- package/src/kernel-and-terminal-panel/module.ts +20 -0
- package/src/kernel-and-terminal-panel/panel-command.tsx +57 -0
- package/src/layout/layout-service.ts +17 -0
- package/src/layout/main.tsx +13 -1
- 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 @@
|
|
|
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
|
+
);
|