238 lines
6.6 KiB
Vue
238 lines
6.6 KiB
Vue
<script setup>
|
|
import { useConfigStore } from '@/stores/config.js'
|
|
import { NButton } from 'naive-ui'
|
|
import { Add, Pencil, Play, Folder, TrashOutline, Archive } from '@vicons/ionicons5'
|
|
|
|
const notification = useNotification()
|
|
|
|
const config_store = useConfigStore()
|
|
const conf = config_store.config
|
|
const instance_name_input_refs = ref([])
|
|
const update_instance_name_index = ref(null)
|
|
const migrate_options = [
|
|
{
|
|
label: '迁移单开配置',
|
|
key: 'default'
|
|
},
|
|
{
|
|
label: '迁移多开配置',
|
|
key: 'instances'
|
|
}
|
|
]
|
|
const check_all = computed(
|
|
() => conf.instances.length > 0 && conf.instances.every((item) => item.checked)
|
|
)
|
|
const check_part = computed(() => !check_all.value && conf.instances.some((item) => item.checked))
|
|
function click_check_all(ckecked) {
|
|
if (ckecked) {
|
|
conf.instances.forEach((item) => {
|
|
item.checked = true
|
|
})
|
|
} else {
|
|
conf.instances.forEach((item) => {
|
|
item.checked = false
|
|
})
|
|
}
|
|
}
|
|
function setInstanceNameInputRef(el, index) {
|
|
if (el) {
|
|
instance_name_input_refs.value[index] = el
|
|
}
|
|
}
|
|
async function add_instance() {
|
|
const instance_path = await pywebview.api.add_instance()
|
|
conf.instances.push({
|
|
checked: false,
|
|
name: '新实例',
|
|
path: instance_path
|
|
})
|
|
}
|
|
async function delete_instance(index, path) {
|
|
await pywebview.api.delete_instance(path)
|
|
conf.instances.splice(index, 1)
|
|
}
|
|
|
|
function start_update_instance_name(index) {
|
|
update_instance_name_index.value = index
|
|
nextTick(() => {
|
|
instance_name_input_refs.value[index]?.focus()
|
|
})
|
|
}
|
|
function end_update_instance_name() {
|
|
update_instance_name_index.value = null
|
|
}
|
|
function open_folder(path) {
|
|
pywebview.api.open_folder(path)
|
|
}
|
|
function start_instance(instance) {
|
|
pywebview.api.run('webview', 'mower-ng', {
|
|
instance_path: instance.path
|
|
})
|
|
}
|
|
function start_checked_instance() {
|
|
pywebview.api.start_checked_instance()
|
|
}
|
|
async function handle_migrate(key) {
|
|
if (key == 'default') {
|
|
const response = await pywebview.api.migrate_default_instance()
|
|
console.log(response)
|
|
if (response.status) {
|
|
conf.instances.push({
|
|
checked: false,
|
|
name: '默认实例',
|
|
path: response.data
|
|
})
|
|
notification['success']({
|
|
content: '信息',
|
|
meta: response.message,
|
|
duration: 3000
|
|
})
|
|
} else {
|
|
notification['error']({
|
|
content: '错误',
|
|
meta: response.message,
|
|
duration: 3000
|
|
})
|
|
}
|
|
} else {
|
|
const response = await pywebview.api.migrate_instances_config()
|
|
console.log('多开配置内容:', response)
|
|
if (response.data) {
|
|
await config_store.load_config()
|
|
conf.instances = [...config_store.config.instances]
|
|
}
|
|
if (response.status) {
|
|
notification['info']({
|
|
title: '信息',
|
|
content: response.message,
|
|
duration: 3000
|
|
})
|
|
} else {
|
|
notification['error']({
|
|
title: '错误',
|
|
content: response.message,
|
|
duration: 3000
|
|
})
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<n-flex vertical style="gap: 16px; height: 100%; padding: 16px; box-sizing: border-box">
|
|
<n-space class="top" justify="space-between">
|
|
<n-space>
|
|
<n-button class="launch-btn" type="primary" secondary @click="add_instance">
|
|
<template #icon>
|
|
<n-icon :component="Add"></n-icon>
|
|
</template>
|
|
添加实例
|
|
</n-button>
|
|
<n-button
|
|
class="launch-btn"
|
|
type="primary"
|
|
secondary
|
|
@click="start_checked_instance"
|
|
:disabled="!check_all && !check_part"
|
|
>
|
|
<template #icon>
|
|
<n-icon :component="Play"></n-icon>
|
|
</template>
|
|
启动所选实例
|
|
</n-button>
|
|
<n-dropdown trigger="click" :options="migrate_options" @select="handle_migrate">
|
|
<n-button class="launch-btn" type="primary" secondary>
|
|
<template #icon>
|
|
<n-icon :component="Archive"></n-icon>
|
|
</template>
|
|
迁移配置
|
|
</n-button>
|
|
</n-dropdown>
|
|
</n-space>
|
|
|
|
<div class="is_show_log_switch">
|
|
<n-switch v-model:value="conf.is_show_log" />
|
|
显示日志
|
|
</div>
|
|
</n-space>
|
|
<n-list class="instance-list" bordered>
|
|
<n-list-item>
|
|
<template #prefix>
|
|
<n-checkbox
|
|
v-model:checked="check_all"
|
|
:indeterminate="check_part"
|
|
style="white-space: nowrap"
|
|
@update:checked="click_check_all"
|
|
>全选</n-checkbox
|
|
>
|
|
</template>
|
|
</n-list-item>
|
|
<n-list-item v-for="(item, index) in conf.instances" :key="index">
|
|
<template #prefix>
|
|
<n-checkbox v-model:checked="item.checked"></n-checkbox>
|
|
</template>
|
|
<n-space vertical>
|
|
<n-space v-if="update_instance_name_index != index">
|
|
<n-text>{{ item.name }}</n-text>
|
|
<n-button size="tiny" @click="start_update_instance_name(index)">
|
|
<template #icon>
|
|
<n-icon :component="Pencil"></n-icon>
|
|
</template>
|
|
</n-button>
|
|
<n-button @click="open_folder(item.path)" size="tiny">
|
|
<template #icon>
|
|
<n-icon :component="Folder"></n-icon>
|
|
</template>
|
|
</n-button>
|
|
</n-space>
|
|
<n-input
|
|
v-else
|
|
:ref="(el) => setInstanceNameInputRef(el, index)"
|
|
v-model:value="item.name"
|
|
@blur="end_update_instance_name"
|
|
></n-input>
|
|
</n-space>
|
|
<template #suffix>
|
|
<n-space :wrap="false">
|
|
<n-button type="primary" size="small" @click="start_instance(item)">
|
|
<template #icon>
|
|
<n-icon :component="Play"></n-icon>
|
|
</template>
|
|
</n-button>
|
|
<n-popconfirm @positive-click="delete_instance(index, item.path)">
|
|
<template #trigger>
|
|
<n-button type="error" ghost size="small">
|
|
<template #icon>
|
|
<n-icon :component="TrashOutline"></n-icon>
|
|
</template>
|
|
</n-button>
|
|
</template>
|
|
删除操作将导致实例配置丢失,请谨慎操作。
|
|
</n-popconfirm>
|
|
</n-space>
|
|
</template>
|
|
</n-list-item>
|
|
</n-list>
|
|
<log-component v-show="conf.is_show_log" class="log" />
|
|
</n-flex>
|
|
</template>
|
|
|
|
<style scoped>
|
|
.launch-btn {
|
|
height: 38px;
|
|
}
|
|
.instance-list {
|
|
overflow: auto;
|
|
}
|
|
.log {
|
|
min-height: 40vh;
|
|
max-height: 40vh;
|
|
margin-top: auto;
|
|
}
|
|
.top {
|
|
align-items: center;
|
|
}
|
|
.is_show_log_switch {
|
|
margin-right: 20px;
|
|
}
|
|
</style>
|