Skip to content

Commit

Permalink
refa: migrate config menu to action api
Browse files Browse the repository at this point in the history
  • Loading branch information
shigma committed May 28, 2023
1 parent 78cdff6 commit c13e463
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 98 deletions.
6 changes: 5 additions & 1 deletion plugins/config/client/components/global.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

<script lang="ts" setup>
import { store } from '@koishijs/client'
import { send, store, useAction } from '@koishijs/client'
import { computed } from 'vue'
import { Tree } from './utils'
Expand All @@ -20,4 +20,8 @@ const config = computed({
set: value => emit('update:modelValue', value),
})
useAction('config.save', {
action: () => send('manager/app-reload', config.value),
})
</script>
98 changes: 16 additions & 82 deletions plugins/config/client/components/index.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<template>
<k-layout :menu="menu">
<k-layout menu="config">
<template #header>
<!-- root -->
<template v-if="!current.path">
Expand Down Expand Up @@ -38,11 +38,11 @@
<plugin-settings v-else :current="current" v-model="config"></plugin-settings>
</k-content>

<el-dialog v-model="showDialog" title="确认移除" destroy-on-close>
<el-dialog v-model="showRemove" title="确认移除" destroy-on-close>
确定要移除{{ current.children ? `分组 ${current.alias}` : `插件 ${current.label}` }} 吗?此操作不可撤销!
<template #footer>
<el-button @click="showDialog = false">取消</el-button>
<el-button type="danger" @click="(showDialog = false, removeItem(current.path))">确定</el-button>
<el-button @click="showRemove = false">取消</el-button>
<el-button type="danger" @click="(showRemove = false, removeItem(current.path))">确定</el-button>
</template>
</el-dialog>
</k-layout>
Expand All @@ -52,14 +52,13 @@
import { computed, ref, watch } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { addItem, envMap, plugins, removeItem, splitPath, Tree, coreDeps } from './utils'
import { clone, store, useAction } from '@koishijs/client'
import { addItem, current, plugins, removeItem, showSelect, Tree } from './utils'
import GlobalSettings from './global.vue'
import GroupSettings from './group.vue'
import TreeView from './tree.vue'
import PluginSettings from './plugin.vue'
import KAlias from './alias.vue'
import { clone, message, send, store } from '@koishijs/client'
import { showSelect } from './utils'
const route = useRoute()
const router = useRouter()
Expand All @@ -75,95 +74,30 @@ const path = computed<string>({
},
})
const current = ref<Tree>()
const config = ref()
const showDialog = ref(false)
const showRemove = ref(false)
watch(() => plugins.value.paths[path.value], (value) => {
current.value = value
config.value = clone(value.config)
}, { immediate: true })
const name = computed(() => {
const { label, target } = current.value
const shortname = target || label
if (shortname.includes('/')) {
const [left, right] = shortname.split('/')
return [`${left}/koishi-plugin-${right}`].find(name => name in store.packages)
}
return [
`@koishijs/plugin-${shortname}`,
`koishi-plugin-${shortname}`,
].find(name => name in store.packages)
useAction('config.remove', {
disabled: () => !current.value.path,
action: () => showRemove.value = true,
})
const type = computed(() => {
const env = envMap.value[name.value]
if (!env) return
if (env.warning && current.value.disabled) return 'warning'
for (const name in env.using) {
if (store.services?.[name]) {
if (env.impl.includes(name)) return 'warning'
} else {
if (env.using[name].required) return 'warning'
}
}
useAction('config.add-plugin', {
disabled: () => current.value.path && !current.value.children,
action: () => showSelect.value = true,
})
const menu = computed(() => {
const isGlobal = current.value.path === ''
const isGroup = !!current.value.children
const isDisabled = current.value.disabled
return [{
icon: isDisabled ? 'play' : 'stop',
label: isDisabled ? '启用插件' : '停用插件',
disabled: isGroup || !name.value || coreDeps.includes(name.value),
action: async () => {
await execute(isDisabled ? 'reload' : 'unload')
message.success(isDisabled ? '插件已启用。' : '插件已停用。')
},
}, {
type: isDisabled ? type.value : '',
icon: isDisabled ? 'save' : 'check',
label: isDisabled ? '保存配置' : '重载配置',
disabled: !isGroup && !name.value,
async action() {
if (isGlobal) {
send('manager/app-reload', config.value)
} else {
await execute(isDisabled ? 'unload' : 'reload')
message.success(isDisabled ? '配置已保存。' : '配置已重载。')
}
},
}, {
type: 'danger',
icon: 'trash-can',
label: isGroup ? '移除分组' : '移除插件',
disabled: isGlobal,
action: () => showDialog.value = true,
}, {
icon: 'add-plugin',
label: '添加插件',
disabled: !isGroup,
action: () => showSelect.value = true,
}, {
icon: 'add-group',
label: '添加分组',
disabled: !isGroup,
action: () => addItem(current.value.path, 'group', 'group'),
}]
useAction('config.add-group', {
disabled: () => current.value.path && !current.value.children,
action: () => addItem(current.value.path, 'group', 'group'),
})
async function execute(event: 'unload' | 'reload') {
await send(`manager/${event}`, current.value.path, config.value, current.value.target)
if (current.value.target) {
const segments = splitPath(current.value.path)
segments[segments.length - 1] = current.value.target
router.replace('/plugins/' + segments.join('/'))
}
}
</script>

<style lang="scss">
Expand Down
45 changes: 30 additions & 15 deletions plugins/config/client/components/plugin.vue
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,10 @@

<script lang="ts" setup>
import { store, send } from '@koishijs/client'
import { store, send, useAction, message } from '@koishijs/client'
import { computed, provide, watch } from 'vue'
import { envMap, SettingsData, Tree } from './utils'
import { useRouter } from 'vue-router'
import { coreDeps, envMap, name, SettingsData, splitPath, Tree } from './utils'
import KModifier from './modifier.vue'
const props = defineProps<{
Expand All @@ -97,19 +98,6 @@ const config = computed({
set: value => emit('update:modelValue', value),
})
const name = computed(() => {
const { label, target } = props.current
const shortname = target || label
if (shortname.includes('/')) {
const [left, right] = shortname.split('/')
return [`${left}/koishi-plugin-${right}`].find(name => name in store.packages)
}
return [
`@koishijs/plugin-${shortname}`,
`koishi-plugin-${shortname}`,
].find(name => name in store.packages)
})
const env = computed(() => envMap.value[name.value])
const local = computed(() => store.packages[name.value])
const hint = computed(() => local.value.workspace ? '请检查插件源代码。' : '请联系插件作者并反馈此问题。')
Expand All @@ -131,6 +119,33 @@ const data = computed<SettingsData>(() => ({
current: props.current,
}))
const router = useRouter()
useAction('config.save', {
disabled: () => !name.value,
action: async () => {
await execute(props.current.disabled ? 'unload' : 'reload')
message.success(props.current.disabled ? '配置已保存。' : '配置已重载。')
},
})
useAction('config.toggle', {
disabled: () => !name.value || coreDeps.includes(name.value),
action: async () => {
await execute(props.current.disabled ? 'reload' : 'unload')
message.success(props.current.disabled ? '插件已启用。' : '插件已停用。')
},
})
async function execute(event: 'unload' | 'reload') {
await send(`manager/${event}`, props.current.path, config.value, props.current.target)
if (props.current.target) {
const segments = splitPath(props.current.path)
segments[segments.length - 1] = props.current.target
router.replace('/plugins/' + segments.join('/'))
}
}
</script>

<style lang="scss">
Expand Down
29 changes: 29 additions & 0 deletions plugins/config/client/components/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,35 @@ export interface Tree {
children?: Tree[]
}

export const current = ref<Tree>()

export const name = computed(() => {
if (!current.value) return
const { label, target } = current.value
const shortname = target || label
if (shortname.includes('/')) {
const [left, right] = shortname.split('/')
return [`${left}/koishi-plugin-${right}`].find(name => name in store.packages)
}
return [
`@koishijs/plugin-${shortname}`,
`koishi-plugin-${shortname}`,
].find(name => name in store.packages)
})

export const type = computed(() => {
const env = envMap.value[name.value]
if (!env) return
if (env.warning && current.value.disabled) return 'warning'
for (const name in env.using) {
if (store.services?.[name]) {
if (env.impl.includes(name)) return 'warning'
} else {
if (env.using[name].required) return 'warning'
}
}
})

function getTree(parent: Tree, plugins: any): Tree[] {
const trees: Tree[] = []
for (let key in plugins) {
Expand Down
25 changes: 25 additions & 0 deletions plugins/config/client/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Context } from '@koishijs/client'
import { defineComponent, h, resolveComponent } from 'vue'
import type {} from '@koishijs/plugin-config'
import { current, type } from './components/utils'
import Settings from './components/index.vue'
import Select from './components/select.vue'
import './icons'
Expand Down Expand Up @@ -36,4 +37,28 @@ export default (ctx: Context) => {
fields: ['config', 'packages', 'services'],
component: Settings,
})

ctx.menu('config', [{
id: 'config.toggle',
type: () => current.value?.disabled ? '' : type.value,
icon: () => current.value?.disabled ? 'play' : 'stop',
label: () => current.value?.disabled ? '启用插件' : '停用插件',
}, {
id: 'config.save',
icon: () => current.value?.disabled ? 'save' : 'check',
label: () => current.value?.disabled ? '保存配置' : '重载配置',
}, {
id: 'config.remove',
type: 'danger',
icon: 'trash-can',
label: current.value?.children ? '移除分组' : '移除插件',
}, {
id: 'config.add-plugin',
icon: 'add-plugin',
label: '添加插件',
}, {
id: 'config.add-group',
icon: 'add-group',
label: '添加分组',
}])
}

0 comments on commit c13e463

Please sign in to comment.