<template>
<tiny-dialog-box
class="dialog-box"
:visible="visible"
:close-on-click-modal="false"
:append-to-body="true"
width="1000"
title="请选择生成到本地的文件"
@close="$emit('cancel')"
@open="initdialogBox"
>
<div class="dialog-grid">
<div class="tree-wrap">
<tiny-tree
ref="fileTreeRef"
:data="fileTree"
node-key="id"
:default-checked-keys="fileTreeAllCheckedKeys"
:expand-icon="expandIcon"
:shrink-icon="shrinkIcon"
show-checkbox
default-expand-all
highlight-current
:current-node-key="currentNodeKey"
@node-click="nodeClick"
></tiny-tree>
</div>
<div class="editor-wrap">
<monaco-editor
v-if="options.language"
class="code-edit-content"
:value="fileContent"
:options="options"
></monaco-editor>
</div>
</div>
<template #footer>
<tiny-button type="primary" @click="confirm">确定</tiny-button>
<tiny-button @click="$emit('cancel')">取消</tiny-button>
</template>
</tiny-dialog-box>
</template>
<script lang="ts">
/* metaService: engine.toolbars.generate-code.FileSelector */
import { DialogBox, Button, Tree } from '@opentiny/vue'
import { iconPutAway, iconExpand } from '@opentiny/vue-icon'
import { reactive, computed, ref, nextTick } from 'vue'
import { useNotify, useCanvas } from '@opentiny/tiny-engine-meta-register'
import { VueMonaco } from '@opentiny/tiny-engine-common'
export default {
components: {
MonacoEditor: VueMonaco,
TinyDialogBox: DialogBox,
TinyButton: Button,
TinyTree: Tree
},
props: {
visible: { type: Boolean, default: false },
data: {
type: Array,
default: () => []
},
treeData: {
type: Object,
default: () => ({ treeArray: [], checkedTreeData: [] })
}
},
emits: ['cancel', 'confirm'],
setup(props, { emit }) {
const shrinkIcon = iconExpand()
const expandIcon = iconPutAway()
const currentNodeKey = ref()
const fileTree = computed(() => {
return [
{
id: 'all',
label: '所有文件',
children: props.treeData.treeArray
}
]
})
const fileTreeAllCheckedKeys = computed(() => {
return ['all'].concat(props.treeData.checkedTreeData)
})
const fileTreeRef = ref<any>(null)
const options = reactive({
language: 'javascript',
readOnly: true,
minimap: {
enabled: false
},
theme: 'customTheme'
})
const fileContent = ref('')
const nodeClick = (node: any) => {
if (node?.originData) {
nextTick(() => {
fileContent.value = node.originData.fileContent
fileTreeRef.value.setCurrentKey(node.id)
})
}
}
const confirm = () => {
const selectedData = fileTreeRef.value
.getCheckedNodes()
.map((node: any) => node.originData)
.filter((node: any) => node !== undefined)
if (!selectedData?.length) {
useNotify({
type: 'error',
title: '生成代码失败',
message: '选中列表为空,请先选择需要生成到本地的文件再点击确定按钮.'
})
return
}
emit('confirm', selectedData)
}
const initdialogBox = () => {
// 初始化显示的文件
const currentPage = useCanvas().getCurrentPage()
if (currentPage) {
const initCurrentNode: any = props.data.find((item: any) => item.fileName === `${currentPage.name}.vue`)
nextTick(() => {
fileContent.value = initCurrentNode.fileContent
fileTreeRef.value.setCurrentKey(initCurrentNode.fileName)
})
}
}
return {
shrinkIcon,
expandIcon,
currentNodeKey,
fileTree,
fileTreeAllCheckedKeys,
options,
fileContent,
fileTreeRef,
nodeClick,
confirm,
initdialogBox
}
}
}
</script>
<style lang="less" scoped>
.dialog-box {
:deep(.tiny-dialog-box__body) {
height: 480px;
}
:deep(.tiny-dialog-box__content) {
background-color: var(--te-toolbars-generate-code-bg-color);
.tiny-dialog-box__header {
background-color: var(--te-toolbars-generate-code-bg-color);
.tiny-dialog-box__title {
color: var(--te-toolbars-generate-code-text-color);
}
.tiny-dialog-box__headerbtn .tiny-dialog-box__close {
fill: var(--te-toolbars-generate-code-icon-color) !important;
&:hover {
fill: var(--te-toolbars-generate-code-icon-color-primary) !important;
}
}
}
.tiny-dialog-box__footer {
.tiny-button--primary {
background-color: var(--te-toolbars-generate-code-bg-color-primary);
border: none;
}
}
}
.dialog-grid {
display: flex;
.tree-wrap {
overflow: scroll;
.tiny-tree {
width: 300px;
height: 480px;
overflow-x: scroll;
}
:deep(.tiny-tree-node__content) {
.tiny-tree-node__content-left {
background-color: transparent;
}
}
}
.editor-wrap {
width: 100%;
max-width: 744px;
.code-edit-content {
width: 100%;
height: 480px;
:deep(.monaco-editor) {
.margin-view-overlays,
.sticky-line-number,
.view-lines,
.sticky-line-content {
background-color: var(--te-common-bg-container-weaken);
}
.scrollbar.vertical,
.decorationsOverviewRuler {
width: 8px !important;
.slider {
border-radius: 4px;
width: 8px !important;
}
}
.scrollbar.horizontal {
height: 8px !important;
.slider {
border-radius: 4px;
height: 8px !important;
}
}
}
}
}
}
}
</style>