mirror of
https://github.com/jumpserver/lina.git
synced 2025-11-19 06:29:54 +00:00
Compare commits
4 Commits
pr@dev@k8s
...
perf_termi
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4917212fff | ||
|
|
d84a7c824b | ||
|
|
56f4f3f144 | ||
|
|
fea1d35981 |
@@ -33,7 +33,7 @@
|
||||
<!-- eslint-disable-next-line -->
|
||||
<div class="divider"></div>
|
||||
<p>
|
||||
<MessageText :message="item.reasoning" />
|
||||
<MessageText :message="item.reasoning" @insert-code="handleInsertCode" />
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
<span v-if="isServerError" class="error">
|
||||
{{ isServerError }}
|
||||
</span>
|
||||
<MessageText :message="item.result" />
|
||||
<MessageText :message="item.result" @insert-code="handleInsertCode" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -142,6 +142,9 @@ export default {
|
||||
if (value === 'copy') {
|
||||
copy(this.item.result.content)
|
||||
}
|
||||
},
|
||||
handleInsertCode(code) {
|
||||
this.$emit('insert-code', code)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,26 +69,61 @@ export default {
|
||||
this.markdown.use(mdKatex, { blockClass: 'katexmath-block rounded-md', errorColor: ' #cc0000' })
|
||||
},
|
||||
highlightBlock(str, lang) {
|
||||
return `<pre class="code-block-wrapper"><div class="code-block-header"><span class="code-block-header__lang">${lang}</span><span class="code-block-header__copy">${'Copy'}</span></div><code class="hljs code-block-body ${lang}">${str}</code></pre>`
|
||||
return `<pre class="code-block-wrapper">
|
||||
<div class="code-block-header">
|
||||
<span class="code-block-header__lang">${lang}</span>
|
||||
<span class="code-block-header__actions">
|
||||
<span class="code-block-header__insert">${'insert'}</span>
|
||||
<span class="code-block-header__copy">${'Copy'}</span>
|
||||
</span>
|
||||
</div>
|
||||
<code class="hljs code-block-body ${lang}">${str}</code></pre>`
|
||||
},
|
||||
addCopyEvents() {
|
||||
const copyBtn = document.querySelectorAll('.code-block-header__copy')
|
||||
copyBtn.forEach((btn) => {
|
||||
btn.addEventListener('click', () => {
|
||||
const code = btn.parentElement?.nextElementSibling?.textContent
|
||||
if (code) {
|
||||
copy(code)
|
||||
}
|
||||
this.addBtnClickEvents('.code-block-header__copy', this.handlerClickCopy)
|
||||
this.addBtnClickEvents('.code-block-header__insert', this.handlerClickInsert)
|
||||
},
|
||||
|
||||
handlerClickCopy(event) {
|
||||
const wrapper = event.target.closest('.code-block-wrapper')
|
||||
if (wrapper) {
|
||||
// 查找里面的 code 元素
|
||||
const codeElement = wrapper.querySelector('code.code-block-body')
|
||||
if (codeElement) {
|
||||
const codeText = codeElement.textContent
|
||||
copy(codeText)
|
||||
}
|
||||
}
|
||||
},
|
||||
handlerClickInsert(event) {
|
||||
const wrapper = event.target.closest('.code-block-wrapper')
|
||||
if (wrapper) {
|
||||
// 查找里面的 code 元素
|
||||
const codeElement = wrapper.querySelector('code.code-block-body')
|
||||
if (codeElement) {
|
||||
const codeText = codeElement.textContent
|
||||
console.log('insert code', codeText)
|
||||
this.$emit('insert-code', codeText)
|
||||
}
|
||||
}
|
||||
},
|
||||
addBtnClickEvents(selector, callback) {
|
||||
const buttons = this.$refs.textRef.querySelectorAll(selector)
|
||||
buttons.forEach((btn) => {
|
||||
btn.addEventListener('click', callback)
|
||||
})
|
||||
},
|
||||
removeBtnClickEvent(selector) {
|
||||
const buttons = this.$refs.textRef.querySelectorAll(selector)
|
||||
buttons.forEach((btn) => {
|
||||
btn.removeEventListener('click', () => {
|
||||
})
|
||||
})
|
||||
},
|
||||
removeCopyEvents() {
|
||||
if (this.$refs.textRef) {
|
||||
const copyBtn = this.$refs.textRef.querySelectorAll('.code-block-header__copy')
|
||||
copyBtn.forEach((btn) => {
|
||||
btn.removeEventListener('click', () => {
|
||||
})
|
||||
})
|
||||
this.removeBtnClickEvent('.code-block-header__copy')
|
||||
this.addBtnClickEvents('.code-block-header__insert')
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -115,26 +150,46 @@ export default {
|
||||
|
||||
&::v-deep .code-block-wrapper {
|
||||
background: #1F2329;
|
||||
padding: 2px 6px;
|
||||
padding: 0;
|
||||
margin: 5px 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
|
||||
.code-block-body {
|
||||
padding: 5px 10px 0;
|
||||
padding: 5px 10px;
|
||||
}
|
||||
;
|
||||
|
||||
.code-block-header {
|
||||
margin-bottom: 4px;
|
||||
overflow: hidden;
|
||||
background: #353946;
|
||||
color: #c2d1e1;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 4px 8px;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
|
||||
.code-block-header__copy {
|
||||
float: right;
|
||||
cursor: pointer;
|
||||
.code-block-header__actions {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
|
||||
&:hover {
|
||||
color: #6e747b;
|
||||
.code-block-header__copy {
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
color: #6e747b;
|
||||
}
|
||||
}
|
||||
|
||||
.code-block-header__insert {
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
color: #6e747b;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -178,6 +233,7 @@ export default {
|
||||
0% {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
100% {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<ChatMessage v-for="(item, index) in activeChat.chats" :key="index" :item="item" />
|
||||
<ChatMessage v-for="(item, index) in activeChat.chats" :key="index" :item="item" @insert-code="insertCode" />
|
||||
</div>
|
||||
<div class="input-box">
|
||||
<el-button
|
||||
@@ -60,6 +60,10 @@ export default {
|
||||
expanded: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
terminalContent: {
|
||||
type: Object,
|
||||
default: null
|
||||
}
|
||||
},
|
||||
data() {
|
||||
@@ -68,7 +72,8 @@ export default {
|
||||
prompt: '',
|
||||
conversationId: '',
|
||||
showIntroduction: false,
|
||||
introduction: []
|
||||
introduction: [],
|
||||
terminalContext: this.terminalContent || null
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@@ -204,7 +209,11 @@ export default {
|
||||
sendIntroduction(item) {
|
||||
this.showIntroduction = false
|
||||
this.onSendHandle(item.content)
|
||||
},
|
||||
insertCode(code) {
|
||||
console.log(' receive insertCode', code)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -76,7 +76,8 @@ export default {
|
||||
robotUrl: require('@/assets/img/robot-assistant.png'),
|
||||
height: '400px',
|
||||
expanded: false,
|
||||
clientOffset: {}
|
||||
clientOffset: {},
|
||||
currentTerminalContent: {}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
@@ -89,6 +90,15 @@ export default {
|
||||
window.addEventListener('message', (event) => {
|
||||
if (event.data === 'show-chat-panel') {
|
||||
this.$refs.drawer.show = true
|
||||
return
|
||||
}
|
||||
const msg = event.data
|
||||
switch (msg.name) {
|
||||
case 'current_terminal_content':
|
||||
// {content: '...', terminalId: '',sessionId: '',viewId: '',viewName: ''}
|
||||
this.$log.debug('current_terminal_content', msg)
|
||||
this.currentTerminalContent = msg.data
|
||||
break
|
||||
}
|
||||
})
|
||||
},
|
||||
@@ -96,6 +106,11 @@ export default {
|
||||
this.$refs.drawer.handleHeaderMoveDown(event)
|
||||
},
|
||||
handleMouseMoveUp(event) {
|
||||
// Prevent the new chat button from triggering the header move up
|
||||
const newButton = event.target.closest('.new')
|
||||
if (newButton) {
|
||||
return
|
||||
}
|
||||
this.$refs.drawer.handleHeaderMoveUp(event)
|
||||
},
|
||||
initWebSocket() {
|
||||
|
||||
Reference in New Issue
Block a user