feat: 命令片段.
This commit is contained in:
@@ -5,6 +5,7 @@ body {
|
||||
--color-bg-content: #FEFEFE;
|
||||
--color-sidebar-icon: #737070;
|
||||
--color-sidebar-icon-bg: #D7D8DB;
|
||||
--color-sidebar-icon-checked: #CBCCCF;
|
||||
--color-sidebar-tooltip-text: rgba(255, 255, 255, .9);
|
||||
--color-sidebar-tooltip-bg: rgb(29, 33, 41);
|
||||
--color-content-text-1: rgba(0, 0, 0, .8);
|
||||
@@ -25,8 +26,9 @@ body[terminal-theme='dark'] {
|
||||
--color-bg-header: #232323;
|
||||
--color-bg-sidebar: #2C2E31;
|
||||
--color-bg-content: #1A1B1C;
|
||||
--color-sidebar-icon: #C3C8CE;
|
||||
--color-sidebar-icon-bg: #43444C;
|
||||
--color-sidebar-icon: #C3C6C9;
|
||||
--color-sidebar-icon-bg: #3D3E3F;
|
||||
--color-sidebar-icon-checked: #51525C;
|
||||
--color-sidebar-tooltip-text: rgba(255, 255, 255, .9);
|
||||
--color-sidebar-tooltip-bg: var(--color-sidebar-icon-bg);
|
||||
--color-content-text-1: rgba(255, 255, 255, .8);
|
||||
@@ -214,7 +216,7 @@ body[terminal-theme='dark'] .arco-modal-container {
|
||||
}
|
||||
|
||||
&.checked-item {
|
||||
background: var(--color-sidebar-icon-bg);
|
||||
background: var(--color-sidebar-icon-checked);
|
||||
}
|
||||
|
||||
&.disabled-item {
|
||||
|
||||
@@ -99,15 +99,20 @@
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
@transform-x: 8px;
|
||||
@container-width: 406px;
|
||||
@container-height: 448px;
|
||||
@handler-height: 44px;
|
||||
|
||||
.combined-container {
|
||||
padding: 12px;
|
||||
margin: 64px auto;
|
||||
width: 398px;
|
||||
height: 448px;
|
||||
width: @container-width;
|
||||
height: @container-height;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
box-sizing: content-box;
|
||||
overflow: hidden;
|
||||
|
||||
&:hover {
|
||||
@@ -116,20 +121,19 @@
|
||||
}
|
||||
|
||||
.combined-handler {
|
||||
width: 100%;
|
||||
width: calc(@container-width - @transform-x);
|
||||
height: @handler-height;
|
||||
border-radius: 4px;
|
||||
margin-bottom: 6px;
|
||||
color: var(--color-content-text-1);
|
||||
background-color: var(--color-fill-2);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: var(--color-content-text-1);
|
||||
cursor: pointer;
|
||||
transition: transform 0.3s ease;
|
||||
will-change: transform;
|
||||
transition: all 0.2s;
|
||||
|
||||
&:hover {
|
||||
transform: scale(1.04);
|
||||
width: @container-width;
|
||||
}
|
||||
|
||||
&-icon {
|
||||
|
||||
@@ -84,7 +84,6 @@
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
|
||||
.form-item-actions {
|
||||
display: flex;
|
||||
background-color: var(--color-fill-2);
|
||||
|
||||
@@ -119,7 +119,8 @@
|
||||
<style lang="less" scoped>
|
||||
@container-width: 418px;
|
||||
@wrapper-margin-r: 32px;
|
||||
@wrapper-width: (@container-width - @wrapper-margin-r) / 2px;
|
||||
@transform-x: 8px;
|
||||
@item-width: (@container-width - @wrapper-margin-r) / 2;
|
||||
|
||||
.setting-body {
|
||||
display: flex;
|
||||
@@ -130,23 +131,26 @@
|
||||
height: auto;
|
||||
|
||||
.actions-wrapper {
|
||||
width: @wrapper-width;
|
||||
padding-right: 8px;
|
||||
margin-right: @wrapper-margin-r;
|
||||
}
|
||||
|
||||
.action-item-wrapper {
|
||||
transition: all 0.2s;
|
||||
width: 185px;
|
||||
border-radius: 4px;
|
||||
width: calc((@item-width) - @transform-x);
|
||||
|
||||
&:hover {
|
||||
width: 192px;
|
||||
width: calc(@item-width);
|
||||
padding: 4px 0 !important;
|
||||
|
||||
.action-item{
|
||||
.action-item {
|
||||
background: var(--color-fill-3);
|
||||
}
|
||||
|
||||
.action-icon {
|
||||
background: var(--color-fill-4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -12,48 +12,23 @@
|
||||
<!-- 命令容器 -->
|
||||
<div class="snippet-container">
|
||||
<!-- 命令头部 -->
|
||||
<div class="snippet-header-container">
|
||||
<!-- 头部操作 -->
|
||||
<div class="snippet-header">
|
||||
<a-button @click="toggle">新建</a-button>
|
||||
<a-button>搜索</a-button>
|
||||
</div>
|
||||
<!-- 提示 -->
|
||||
<a-alert v-if="isNotTipped(snippetTipsKey)"
|
||||
class="snippet-tips"
|
||||
:closable="true"
|
||||
@on-close="closeTips">
|
||||
双击命令直接运行
|
||||
</a-alert>
|
||||
<div class="snippet-header">
|
||||
<!-- 创建命令 -->
|
||||
<span class="click-icon-wrapper snippet-header-icon" title="创建命令">
|
||||
<icon-plus />
|
||||
</span>
|
||||
<!-- 搜索框 -->
|
||||
<a-input-search class="snippet-header-input"
|
||||
placeholder="名称"
|
||||
allow-clear />
|
||||
</div>
|
||||
<!-- 命令片段 -->
|
||||
<div class="snippet-list-container">
|
||||
<a-collapse v-if="snippet.groups.length"
|
||||
:bordered="false">
|
||||
<a-collapse-item v-for="group in snippet.groups"
|
||||
:key="group.id"
|
||||
:header="group.name">
|
||||
<!-- 总量 -->
|
||||
<template #extra>
|
||||
{{ group.idList.length }} 条
|
||||
</template>
|
||||
{{ group }}
|
||||
</a-collapse-item>
|
||||
</a-collapse>
|
||||
<snippet-group :snippet="snippet" />
|
||||
<div>
|
||||
<div v-for="item in snippet.snippets"
|
||||
:key="item.id"
|
||||
class="snippet-item-wrapper"
|
||||
:class="[loading&&item.id===3 ? 'snippet-item-wrapper-expand' : '']">
|
||||
<div class="snippet-item">
|
||||
<span class="snippet-item-title">
|
||||
{{ item.name }}
|
||||
</span>
|
||||
<span class="snippet-item-command">
|
||||
{{ item.command }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<snippet-item v-for="item in snippet.items"
|
||||
:key="item.id"
|
||||
:item="item" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -67,96 +42,38 @@
|
||||
</script>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref } from 'vue';
|
||||
|
||||
export interface SnippetGroupResponse {
|
||||
groups: Array<SnippetGroup>;
|
||||
snippets: Array<Snippet>;
|
||||
}
|
||||
|
||||
export interface SnippetGroup {
|
||||
id: number;
|
||||
name: string;
|
||||
idList: Array<number>;
|
||||
}
|
||||
|
||||
export interface Snippet {
|
||||
id: number;
|
||||
name: string;
|
||||
command: string;
|
||||
}
|
||||
|
||||
import { useTipsStore } from '@/store';
|
||||
import type { CommandSnippetWrapperResponse } from '@/api/asset/command-snippet';
|
||||
import { onMounted, ref } from 'vue';
|
||||
import useVisible from '@/hooks/visible';
|
||||
import { snippetTipsKey } from '../../types/terminal.const';
|
||||
import useLoading from '@/hooks/loading';
|
||||
import SnippetItem from './snippet-item.vue';
|
||||
import SnippetGroup from './snippet-group.vue';
|
||||
|
||||
const { isNotTipped, setTipped } = useTipsStore();
|
||||
const { loading, toggle } = useLoading();
|
||||
const { visible, setVisible } = useVisible(true);
|
||||
const snippet = ref<SnippetGroupResponse>({
|
||||
groups: [{
|
||||
id: 1,
|
||||
name: 'group1',
|
||||
idList: [1, 2]
|
||||
}, {
|
||||
id: 2,
|
||||
name: 'group2',
|
||||
idList: [3, 4]
|
||||
}],
|
||||
snippets: [{
|
||||
id: 1,
|
||||
name: 'command1command1command1command1command1command1command1command1command1command1command1command1command1command1command1',
|
||||
command: 'echo Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ad adipisci aliquid, atque cupiditate doloribus eligendi enim fugiat itaque iusto laborum magnam maiores natus nemo, neque quae, reprehenderit sed ullam voluptatem?'
|
||||
}, {
|
||||
id: 2,
|
||||
name: 'command2',
|
||||
command: 'echo Lorem'
|
||||
}, {
|
||||
id: 3,
|
||||
name: 'command3',
|
||||
command: 'echo Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ad adipisci aliquid, atque cupiditate doloribus eligendi enim fugiat itaque iusto laborum magnam maiores natus nemo, neque quae, reprehenderit sed ullam voluptatem?'
|
||||
}, {
|
||||
id: 4,
|
||||
name: 'command4',
|
||||
command: 'echo Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ad adipisci aliquid, atque cupiditate doloribus eligendi enim fugiat itaque iusto laborum magnam maiores natus nemo, neque quae, reprehenderit sed ullam voluptatem?'
|
||||
}, {
|
||||
id: 5,
|
||||
name: 'command5',
|
||||
command: 'echo Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ad adipisci aliquid, atque cupiditate doloribus eligendi enim fugiat itaque iusto laborum magnam maiores natus nemo, neque quae, reprehenderit sed ullam voluptatem?'
|
||||
}, {
|
||||
id: 6,
|
||||
name: 'command6',
|
||||
command: 'echo Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ad adipisci aliquid, atque cupiditate doloribus eligendi enim fugiat itaque iusto laborum magnam maiores natus nemo, neque quae, reprehenderit sed ullam voluptatem?'
|
||||
}]
|
||||
const { visible, setVisible } = useVisible();
|
||||
const snippet = ref<CommandSnippetWrapperResponse>({
|
||||
groups: [],
|
||||
items: []
|
||||
});
|
||||
|
||||
// 打开
|
||||
const open = () => {
|
||||
setVisible(true);
|
||||
|
||||
console.log('loading');
|
||||
// loading
|
||||
};
|
||||
|
||||
// 关闭提示
|
||||
const closeTips = () => {
|
||||
console.log('close');
|
||||
};
|
||||
|
||||
defineExpose({ open });
|
||||
|
||||
onMounted(() => {
|
||||
open();
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
<style lang="less" scoped>
|
||||
@transform-x: 8px;
|
||||
@drawer-width: 388px;
|
||||
@item-wrapper-p-y: 4px;
|
||||
@item-wrapper-p-x: 12px;
|
||||
@item-p: 8px;
|
||||
@item-width: @drawer-width - @item-wrapper-p-x * 2;
|
||||
@item-width-transform: @item-width + @transform-x;
|
||||
@item-inline-width: @item-width - @item-p * 2;
|
||||
|
||||
.snippet-drawer-title {
|
||||
font-size: 14px;
|
||||
}
|
||||
@@ -166,104 +83,30 @@
|
||||
background: var(--color-bg-2);
|
||||
height: 100%;
|
||||
|
||||
.snippet-header-container {
|
||||
.snippet-header {
|
||||
padding: 12px;
|
||||
//height: 104px;
|
||||
height: 56px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
.snippet-header {
|
||||
&-icon {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.snippet-tips {
|
||||
margin-top: 8px;
|
||||
&-input {
|
||||
width: 220px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.snippet-list-container {
|
||||
position: relative;
|
||||
//height: calc(100% - 104px);
|
||||
height: calc(100% - 56px);
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.snippet-item-wrapper {
|
||||
padding: @item-wrapper-p-y 0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
|
||||
&-expand {
|
||||
|
||||
.snippet-item {
|
||||
width: @item-width-transform !important;
|
||||
background: var(--color-fill-3) !important;
|
||||
|
||||
:hover {
|
||||
}
|
||||
|
||||
.snippet-item-command {
|
||||
color: var(--color-text-1);
|
||||
text-overflow: unset;
|
||||
word-break: break-all;
|
||||
white-space: unset;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.snippet-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: @item-p;
|
||||
background: var(--color-fill-2);
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
width: @item-width;
|
||||
|
||||
&:hover {
|
||||
width: @item-width-transform;
|
||||
background: var(--color-fill-3);
|
||||
}
|
||||
|
||||
&-title {
|
||||
color: var(--color-text-1);
|
||||
margin-bottom: 8px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
width: @item-inline-width;
|
||||
}
|
||||
|
||||
&-command {
|
||||
color: var(--color-text-2);
|
||||
font-size: 12px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: pre;
|
||||
width: @item-inline-width;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.arco-collapse-item) {
|
||||
border: none;
|
||||
|
||||
.arco-collapse-item-header-title {
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.arco-collapse-item-header {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.arco-collapse-item-content {
|
||||
background-color: unset;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.arco-collapse-item-content-box {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
padding-bottom: 4px;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
<template>
|
||||
<a-collapse :bordered="false">
|
||||
<a-collapse-item v-for="group in snippet.groups"
|
||||
:key="group.id"
|
||||
:header="group.name">
|
||||
<!-- 总量 -->
|
||||
<template #extra>
|
||||
{{ 1 }} 条
|
||||
</template>
|
||||
<snippet-item v-for="item in snippet.items"
|
||||
:key="item.id"
|
||||
:item="item" />
|
||||
</a-collapse-item>
|
||||
</a-collapse>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
export default {
|
||||
name: 'snippetGroup'
|
||||
};
|
||||
</script>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import type { CommandSnippetWrapperResponse } from '@/api/asset/command-snippet';
|
||||
import SnippetItem from './snippet-item.vue';
|
||||
|
||||
defineProps<{
|
||||
snippet: CommandSnippetWrapperResponse
|
||||
}>();
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
:deep(.arco-collapse-item) {
|
||||
border: none;
|
||||
|
||||
.arco-collapse-item-header-title {
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.arco-collapse-item-header {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.arco-collapse-item-content {
|
||||
background-color: unset;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.arco-collapse-item-content-box {
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,95 @@
|
||||
<template>
|
||||
<div class="snippet-item-wrapper"
|
||||
:class="[!!item.expand ? 'snippet-item-wrapper-expand' : '']">
|
||||
<div class="snippet-item">
|
||||
<span class="snippet-item-title">
|
||||
{{ item.name }}
|
||||
</span>
|
||||
<span class="snippet-item-command">
|
||||
{{ item.command }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
export default {
|
||||
name: 'snippetItem'
|
||||
};
|
||||
</script>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import type { CommandSnippetQueryResponse } from '@/api/asset/command-snippet';
|
||||
|
||||
defineProps<{
|
||||
item: CommandSnippetQueryResponse
|
||||
}>();
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
@transform-x: 8px;
|
||||
@drawer-width: 388px;
|
||||
@item-wrapper-p-y: 4px;
|
||||
@item-wrapper-p-x: 12px;
|
||||
@item-p: 8px;
|
||||
@item-width: @drawer-width - @item-wrapper-p-x * 2;
|
||||
@item-width-transform: @item-width + @transform-x;
|
||||
@item-inline-width: @item-width - @item-p * 2;
|
||||
|
||||
.snippet-item-wrapper {
|
||||
padding: @item-wrapper-p-y 0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
|
||||
&-expand {
|
||||
|
||||
.snippet-item {
|
||||
width: @item-width-transform !important;
|
||||
background: var(--color-fill-3) !important;
|
||||
|
||||
.snippet-item-command {
|
||||
color: var(--color-text-1);
|
||||
text-overflow: unset;
|
||||
word-break: break-all;
|
||||
white-space: unset;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.snippet-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: @item-p;
|
||||
background: var(--color-fill-2);
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
width: @item-width;
|
||||
|
||||
&:hover {
|
||||
width: @item-width-transform;
|
||||
background: var(--color-fill-3);
|
||||
}
|
||||
|
||||
&-title {
|
||||
color: var(--color-text-1);
|
||||
margin-bottom: 8px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
width: @item-inline-width;
|
||||
}
|
||||
|
||||
&-command {
|
||||
color: var(--color-text-2);
|
||||
font-size: 12px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: pre;
|
||||
width: @item-inline-width;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -208,9 +208,6 @@ export const TerminalShortcutItems: Array<ShortcutKeyItem> = [
|
||||
},
|
||||
];
|
||||
|
||||
// 命令片段操作提示
|
||||
export const snippetTipsKey = 'snippet:opt';
|
||||
|
||||
// 打开 sshModal key
|
||||
export const openSshModalKey = Symbol();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user