Skip to content

Commit

Permalink
fix(web): 优化侧边栏: 优化文件列表头部,优化文件列表搜索
Browse files Browse the repository at this point in the history
  • Loading branch information
enncy committed Mar 6, 2022
1 parent cf5dc9a commit 84acc62
Show file tree
Hide file tree
Showing 10 changed files with 360 additions and 183 deletions.
2 changes: 2 additions & 0 deletions packages/web/src/components/file/File.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ export interface FileStats {
expand: boolean;
/** 是否正在打开编辑 */
opened: boolean;
/** 是否运行中 */
running: boolean
}

/**
Expand Down
20 changes: 13 additions & 7 deletions packages/web/src/components/file/File.vue
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,17 @@
>
</Icon>
<Icon
@click="(showTerminal = true), (start = !start)"
:title="start ? '关闭' : '运行'"
:type="start ? 'icon-close-circle' : 'icon-play-circle'"
:style="{ color: start ? '#f5222d' : '#1890ff' }"
@click="
(showTerminal = true),
(file.stat.running = !file.stat.running)
"
:title="file.stat.running ? '关闭' : '运行'"
:type="
file.stat.running
? 'icon-close-circle'
: 'icon-play-circle'
"
:style="{ color: file.stat.running ? '#f5222d' : '#1890ff' }"
/>
</div>
</div>
Expand Down Expand Up @@ -108,7 +115,7 @@
<Transition name="fade">
<div v-show="showTerminal" class="h-100 iterminal overflow-hidden">
<span> 控制台 </span>
<Terminal class="h-100" :start="start" :file="file" />
<Terminal class="h-100" :running="file.stat.running" :file="file" />
</div>
</Transition>
</div>
Expand Down Expand Up @@ -146,8 +153,7 @@ try {
/** 是否显示源码 */
const showSource = ref(false);
/** 是否开始运行 */
const start = ref(false);
/** 是否显示终端 */
const showTerminal = ref(false);
/** 是否开启无痕模式 */
Expand Down
204 changes: 40 additions & 164 deletions packages/web/src/components/file/FileTree.vue
Original file line number Diff line number Diff line change
@@ -1,98 +1,43 @@
<template>
<div class="file-tree">
<a-collapse v-model:activeKey="activeKey" :bordered="false" class="text-start">
<template #expandIcon="{ isActive }">
<Icon type="icon-caret-right" :rotate="isActive ? 90 : 0" />
<ATree
class="tree"
:tree-data="files"
:expandedKeys="expandedKeys"
show-icon
@drop="onDrop"
@expand="onExpand"
>
<template #switcherIcon>
<Icon type="icon-down" />
</template>
<template #file>
<Icon type="icon-file-text" />
</template>
<template #dir>
<Icon type="icon-wenjianjia" />
</template>
<template #title="file">
<template v-if="file.stat">
<a-dropdown :trigger="['contextmenu']">
<span @click="clickFile(file)">
{{ StringUtils.maximum(file.title, 20) }}
</span>

<template #overlay>
<FileMenu :file="file"></FileMenu>
</template>
</a-dropdown>
</template>
<a-collapse-panel :key="project.title" :disabled="openSearch">
<template #header="{ isActive }">
<div class="header d-flex">
<div class="col-6 title">
{{ project.title }}
</div>
<div
v-if="isActive"
class="col-6 d-flex align-items-center justify-content-end"
>
<Icon
title="新建文件夹"
class="me-2"
type="icon-folder-plus"
@click.stop="mkdir(project.node)"
/>
<Icon
title="新建文件"
class="me-2"
type="icon-file-plus"
@click.stop="createFile(project.node)"
/>
<Icon
title="搜索文件"
:type="openSearch ? 'icon-close-circle' : 'icon-search'"
@click.stop="search"
/>
</div>
</div>
</template>

<a-input-search
v-if="openSearch"
class="rounded"
size="small"
v-model:value="searchValue"
placeholder="搜索"
/>

<template v-if="node.children && node.children.length === 0">
<div style="font-size: 11px" class="text-center p-1 text-secondary">
没有任何文件
</div>
</template>
<template v-else>
<ATree
class="tree"
v-model:tree-data="node.children"
:expandedKeys="expandedKeys"
show-icon
:draggable="node.children !== undefined"
@drop="onDrop"
@expand="onExpand"
>
<template #switcherIcon>
<Icon type="icon-down" />
</template>
<template #file>
<Icon type="icon-file-text" />
</template>
<template #dir>
<Icon type="icon-wenjianjia" />
</template>
<template #title="file">
<template v-if="file.stat">
<a-dropdown :trigger="['contextmenu']">
<span @click="clickFile(file)">
{{ StringUtils.maximum(file.title, 20) }}
</span>

<template #overlay>
<FileMenu :file="file"></FileMenu>
</template>
</a-dropdown>
</template>
<template v-else>
<span>{{ StringUtils.maximum(file.title, 20) }}</span>
</template>
</template>
</ATree>
</template>
</a-collapse-panel>
</a-collapse>
</div>
<template v-else>
<span>{{ StringUtils.maximum(file.title, 20) }}</span>
</template>
</template>
</ATree>
</template>

<script setup lang="ts">
import { ref, toRefs, watch } from "vue";
import { FileNode, fs, path, createFile, mkdir, flatFiles } from "./File";
import { FileNode, fs, path, flatFiles } from "./File";
import Icon from "../Icon.vue";
import { StringUtils } from "../../utils/string";
import FileMenu from "./FileMenu.vue";
Expand All @@ -104,26 +49,17 @@ import { Project } from "../project";
import ATree from "ant-design-vue/lib/tree";
interface FileTreeProps {
project: Project;
files: FileNode[];
}
const props = withDefaults(defineProps<FileTreeProps>(), {});
const { project } = toRefs(props);
const { files } = toRefs(props);
const activeKey = ref([project.value.title]);
const expandedKeys = ref(
flatFiles(project.value.node.children || [])
flatFiles(files?.value || [])
.filter((file) => file.stat.expand)
.map((file) => file.key)
);
const node = project.value.node;
// 打开文件搜索
const openSearch = ref(false);
// 搜索值
const searchValue = ref("");
// 搜索结果
const resultList = ref<TreeDataItem[]>([]);
/**
* 拖动文件
Expand Down Expand Up @@ -175,7 +111,7 @@ function onDrop(info: any) {
}
});
};
const data = [...(node.children || [])];
const data = [...(files.value || [])];
// Find dragObject
let dragObj: TreeDataItem = {};
Expand Down Expand Up @@ -218,7 +154,7 @@ function onDrop(info: any) {
}
}
node.children = data;
files.value = data;
} catch (e) {
notify("移动文件时出错", e, "file-move", { copy: true, type: "error" });
remote.logger.call(
Expand All @@ -228,33 +164,13 @@ function onDrop(info: any) {
}
}
/**
* 文件搜索
*/
watch(searchValue, (value) => {
resultList.value = [];
if (value) {
let _files = JSON.parse(JSON.stringify(node.children));
while (_files.length !== 0) {
let item = _files.shift();
if (item && item.title?.includes(value)) {
resultList.value.push(item);
}
if (item?.children) {
_files = _files.concat(item.children);
}
}
}
});
/**
* 点击文件
*/
function clickFile(file: FileNode) {
if (file.stat.isDirectory) {
file.stat.expand = !file.stat.expand;
expandedKeys.value = flatFiles(project.value.node.children || [])
expandedKeys.value = flatFiles(files.value || [])
.filter((file) => file.stat.expand)
.map((file) => file.key);
} else {
Expand All @@ -273,14 +189,6 @@ function clickFile(file: FileNode) {
}
}
/** 如果搜索关闭,则清空搜索框 */
function search() {
openSearch.value = !openSearch.value;
if (openSearch.value === false) {
searchValue.value = "";
}
}
function onExpand(keys: string[], e: { expanded: boolean; node: any }) {
expandedKeys.value = keys;
e.node.dataRef.stat.expand = e.expanded;
Expand All @@ -289,33 +197,6 @@ function onExpand(keys: string[], e: { expanded: boolean; node: any }) {

<style scope lang="less">
#app .file-tree {
.header {
white-space: nowrap;
.title {
font-size: 12px;
}
}
.ant-collapse > .ant-collapse-item > .ant-collapse-header .ant-collapse-arrow {
left: 4px;
}
.ant-collapse > .ant-collapse-item > .ant-collapse-header {
border-radius: 4px;
background-color: #f8f8f8;
padding: 0px 4px 0px 20px;
}
.ant-collapse-content > .ant-collapse-content-box {
padding: 0;
}
.ant-collapse-borderless {
background-color: white;
}
.ant-collapse-item {
border: none;
}
.ant-tree {
max-height: 100vh;
overflow: auto;
Expand Down Expand Up @@ -371,9 +252,4 @@ function onExpand(keys: string[], e: { expanded: boolean; node: any }) {
font-size: 11px;
}
}
em {
background-color: yellow;
font-weight: bold;
}
</style>
Loading

0 comments on commit 84acc62

Please sign in to comment.