Переглянути джерело

日志保持滚动至底部

mxd 3 роки тому
батько
коміт
0abfc419a8

+ 14 - 2
src/components/panel/common/magic-panel-toolbar.vue

@@ -1,12 +1,22 @@
 <template>
     <ul class="magic-panel-toolbar">
-        <li v-for="(toolbar, key) in toolbars" :key="key" :title="toolbar.title" @click.stop="toolbar.disabled !== true && toolbar.onClick()" :class="{ disabled: toolbar.disabled }">
+        <li v-for="(toolbar, key) in toolbars" :key="key" :title="toolbar.title" @click.stop="onClick(toolbar)" :class="{ disabled: toolbar.disabled, selected: toolbar.selected }">
             <magic-icon :icon="toolbar.icon" />
         </li>
     </ul>
 </template>
 <script setup>
 const data = defineProps({ toolbars: Array})
+const onClick = toolbar => {
+    if(toolbar.selectable){
+        if(toolbar.disabled !== true) {
+            toolbar.selected = toolbar.selected !== true
+            toolbar.onSelect && toolbar.onSelect(toolbar.selected)
+        }
+    } else {
+        toolbar.disabled !== true && toolbar.onClick()
+    }
+}
 </script>
 <style scoped>
 .magic-panel-toolbar{
@@ -22,8 +32,10 @@ const data = defineProps({ toolbars: Array})
     height: 18px;
     line-height: 18px;
     margin:3px;
+    font-size: 0.95em;
 }
-.magic-panel-toolbar li:not(.disabled):hover{
+.magic-panel-toolbar li:not(.disabled):hover,
+.magic-panel-toolbar li:not(.disabled).selected{
     background-color: var(--main-hover-icon-background-color);
 }
 .magic-panel-toolbar li.disabled :deep(.magic-icon > *){

+ 53 - 14
src/components/panel/footer/magic-log.vue

@@ -1,7 +1,8 @@
 <template>
-	<div class="magic-log-wrapper" @contextmenu.prevent="e=> onContextMenu(e)">
+	<div class="magic-log-wrapper">
+		<magic-panel-toolbar :toolbars="toolbars"/>
 		<magic-empty v-if="!logs ||logs.length === 0" :text="$i('message.empty', $i('message.log'))"/>
-		<div v-else class="magic-log" ref="element">
+		<div v-show="logs && logs.length > 0" class="magic-log" ref="element"  @contextmenu.prevent="e=> onContextMenu(e)">
 			<div v-for="(item, key) in logs" :class="{ multiple: item.multiple, more: item.showMore }" :key="'run_log_' + key">
 				<pre v-html="item.html"></pre>
 				<span v-if="item.multiple" class="multiple" @click="item.showMore = !item.showMore">
@@ -12,13 +13,44 @@
 	</div>
 </template>
 <script setup>
-import { getCurrentInstance, nextTick, ref } from 'vue'
+import { getCurrentInstance, nextTick, onMounted, ref } from 'vue'
 import bus from '../../../scripts/bus.js'
 import $i from '../../../scripts/i18n.js'
 import Socket from '../../../scripts/constants/socket.js'
 const logs = ref([])
+const keepScroll = ref(false)
+const toolbars = ref([{
+	icon: 'expand-all',
+	title: $i('resource.header.expand'),
+	onClick: ()=> logs.value.forEach(it => it.showMore = true)
+}, {
+	icon: 'collapse-all',
+	title: $i('resource.header.collapse'),
+	onClick: ()=> logs.value.forEach(it => it.showMore = false)
+}, {
+	icon: 'delete',
+	title: $i('message.clear'),
+	onClick: ()=> logs.value.splice(0)
+}, {
+	icon: 'scroll-down',
+	title: $i('log.scrollEnd'),
+	selectable: true,
+	onSelect: (val)=> {
+		keepScroll.value = val
+		updateScroll()
+	}
+}])
 const element = ref(null)
 const { proxy } = getCurrentInstance()
+const updateScroll = () => {
+	if(keepScroll.value){
+		nextTick(() => {
+			if(element.value){
+				element.value.scrollTop = element.value.scrollHeight
+			}
+		})
+	}
+}
 const onContextMenu = event => {
 	proxy.$contextmenu({
 		event,
@@ -58,30 +90,37 @@ const _pushLog = items => {
 	})
 	if(messages){
 		logs.value.push(...messages)
-		nextTick(() => {
-			if(element.value){
-				element.value.scrollTop = element.value.scrollHeight
-			}
-		})
+		updateScroll()
 	}
 }
 bus.$event(Socket.LOGS, ([ rows ]) => _pushLog(rows))
 bus.$event(Socket.LOG, ([ row ]) => _pushLog(row))
+const observer = new IntersectionObserver(() => {
+	updateScroll()
+})
+onMounted(() => {
+	observer.observe(element.value)
+})
 
 </script>
 <style>
 .magic-log-wrapper{
-	position: relative;
-	overflow: auto;
-	width: 100%;
+	display: flex;
+	flex: 1;
 	height: 100%;
-	background: var(--run-log-background-color);
+	overflow: hidden;
+	position: relative;
 }
 .magic-log {
-	position: absolute;
 	font-size: 13.5px;
-	height: 100%;
 	padding: 5px;
+	flex: 1;
+	overflow: auto;
+	position: absolute;
+    top: 0;
+    right: 0;
+    bottom: 0;
+    left: 24px;
 }
 .magic-log > div{
 	width: 100%;

+ 6 - 0
src/icons/scroll-down.svg

@@ -0,0 +1,6 @@
+<svg  class="icon" style="width: 1em;height: 1em;vertical-align: middle;fill: currentColor;overflow: hidden;" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg">
+    <path d="M12 6L15 6 11 10 7 6 10 6 10 1 12 1z" />
+    <path d="M2 11h12v2h-12z" />
+    <path d="M2 7h4v2h-4z" />
+    <path d="M2 3h4v2h-4z" />
+</svg>

+ 2 - 1
src/scripts/i18n/en.js

@@ -305,7 +305,8 @@ export default {
     },
     log: {
         hide: 'Click to hide multiline log',
-        show: '{0} lines of log are hidden, Click to show'
+        show: '{0} lines of log are hidden, Click to show',
+        scrollEnd: 'Scroll to End'
     },
     code: {
         'error': 'Error({0})',

+ 2 - 1
src/scripts/i18n/zh-cn.js

@@ -322,7 +322,8 @@ export default {
     },
     log: {
         hide: '点击隐藏多行日志',
-        show: '有 {0} 行日志被隐藏,点击显示'
+        show: '有 {0} 行日志被隐藏,点击显示',
+        scrollEnd: '滚动至结尾'
     },
     code: {
         'error': '请求出错,异常代码({0})',