Skip to content

Commit

Permalink
feat(config): add fork management dialog
Browse files Browse the repository at this point in the history
  • Loading branch information
shigma committed Dec 17, 2023
1 parent 81b6d66 commit 7e90ec4
Show file tree
Hide file tree
Showing 8 changed files with 206 additions and 71 deletions.
114 changes: 114 additions & 0 deletions plugins/config/client/components/forks.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
<template>
<el-dialog
:model-value="!!dialogFork"
@update:model-value="dialogFork = null"
class="dialog-config-fork"
destroy-on-close>
<template #header="{ titleId, titleClass }">
<span :id="titleId" :class="titleClass">
{{ dialogFork + (local?.workspace ? ' (工作区)' : '') }}
</span>
</template>
<table>
<tr v-for="id in plugins.forks[shortname]" :key="id">
<td class="text-left">
<span class="status-light" :class="getStatus(plugins.paths[id])"></span>
<span class="path">{{ getFullPath(plugins.paths[id]) }}</span>
</td>
<td class="text-right">
<span class="actions">
<span class="action" @click.stop="configure(id)"><k-icon name="arrow-right"></k-icon></span>
<span class="action" @click.stop="removeItem(plugins.paths[id])"><k-icon name="delete"></k-icon></span>
</span>
</td>
</tr>
</table>
<template #footer>
<el-button @click.stop="configure()">添加新配置</el-button>
</template>
</el-dialog>
</template>

<script setup lang="ts">
import { computed } from 'vue'
import { store, send, router } from '@koishijs/client'
import { dialogFork, plugins, getStatus, removeItem, Tree } from './utils'
const shortname = computed(() => dialogFork.value?.replace(/(koishi-|^@koishijs\/)plugin-/, ''))
const local = computed(() => store.packages[dialogFork.value])
function getLabel(tree: Tree) {
return `${tree.label ? `${tree.label} ` : ''}[${tree.path}]`
}
function getFullPath(tree: Tree) {
const path = [getLabel(tree)]
while (tree.parent) {
tree = tree.parent
path.unshift(getLabel(tree))
}
path.shift()
return path.join(' > ')
}
async function configure(key?: string) {
const target = shortname.value
if (!key) {
key = Math.random().toString(36).slice(2, 8)
send('manager/unload', '', target + ':' + key, {})
}
await router.push('/plugins/' + key)
dialogFork.value = null
}
</script>

<style lang="scss">
.dialog-config-fork {
.el-dialog__header .el-dialog__title {
font-weight: 500;
color: var(--fg1);
margin-right: 0.5rem;
flex: 0 0 auto;
}
.text-left {
text-align: left;
}
.text-right {
text-align: right;
}
.status-light {
margin-right: 0.75rem;
}
.actions {
display: flex;
gap: 0 0.5rem;
align-items: center;
justify-content: flex-end;
}
.action {
display: inline-flex;
width: 1.25rem;
justify-content: center;
cursor: pointer;
color: var(--fg2);
transition: var(--color-transition);
&:hover {
color: var(--fg1);
}
}
.el-dialog__footer {
text-align: left;
}
}
</style>
8 changes: 4 additions & 4 deletions plugins/config/client/components/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
@closed="remove = null"
>
<template v-if="remove">
确定要移除{{ remove.children ? `分组 ${remove.alias}` : `插件 ${remove.name}` }} 吗?此操作不可撤销!
确定要移除{{ remove.children ? `分组 ${remove.label || remove.path}` : `插件 ${remove.label || remove.name}` }} 吗?此操作不可撤销!
</template>
<template #footer>
<el-button @click="showRemove = false">取消</el-button>
Expand Down Expand Up @@ -62,7 +62,7 @@
import { computed, ref, watch } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { clone, message, send, store, useContext, Schema } from '@koishijs/client'
import { Tree, getFullName, addItem, hasCoreDeps, current, plugins, removeItem, select } from './utils'
import { Tree, getFullName, addItem, hasCoreDeps, current, plugins, removeItem, dialogSelect } from './utils'
import GlobalSettings from './global.vue'
import GroupSettings from './group.vue'
import TreeView from './tree.vue'
Expand Down Expand Up @@ -109,7 +109,7 @@ ctx.define('config.tree', current)
ctx.action('config.tree.add-plugin', {
disabled: ({ config }) => config.tree.path && !config.tree.children,
action: ({ config }) => select.value = config.tree,
action: ({ config }) => dialogSelect.value = config.tree,
})
ctx.action('config.tree.add-group', {
Expand All @@ -120,7 +120,7 @@ ctx.action('config.tree.add-group', {
ctx.action('config.tree.rename', {
disabled: ({ config }) => !config.tree.path,
action: ({ config }) => {
input.value = config.tree.label || (config.tree.name === 'group' ? config.tree.alias : config.tree.name)
input.value = config.tree.label || (config.tree.name === 'group' ? config.tree.path : config.tree.name)
rename.value = config.tree
},
})
Expand Down
25 changes: 15 additions & 10 deletions plugins/config/client/components/plugin.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,8 @@
</k-comment>

<k-slot v-else name="plugin-details" :data="data">
<!-- reusability -->
<k-slot-item :order="800">
<k-comment v-if="local.runtime.id && !local.runtime.forkable && current.disabled" type="warning">
<p>此插件已在运行且不可重用,启用可能会导致非预期的问题。</p>
</k-comment>
</k-slot-item>

<!-- dependency -->
<k-slot-item :order="600">
<k-slot-item :order="800">
<k-slot name="plugin-dependency" single :data="data">
<k-comment
v-for="({ required, active }, name) in env.peer" :key="name"
Expand All @@ -36,7 +29,7 @@
</k-slot-item>

<!-- implements -->
<k-slot-item :order="400">
<k-slot-item :order="600">
<template v-for="name in env.impl" :key="name">
<k-comment v-if="name in store.services && data.current.disabled" type="warning">
<p>此插件将会提供 {{ name }} 服务,但此服务已被其他插件实现。</p>
Expand All @@ -47,6 +40,16 @@
</template>
</k-slot-item>

<!-- reusability -->
<k-slot-item :order="400">
<k-comment v-if="local.runtime.id && !local.runtime.forkable && current.disabled" type="warning">
<p>此插件已在运行且不可重用,启用可能会导致非预期的问题。</p>
</k-comment>
<k-comment v-if="plugins.forks[shortname]?.length > 1" type="primary">
<p>此插件存在多份配置,<span class="k-link" @click.stop="dialogFork = name">点击前往管理</span>。</p>
</k-comment>
</k-slot-item>

<!-- implements -->
<k-slot-item :order="300">
<template v-for="(activity, key) in activities" :key="key">
Expand Down Expand Up @@ -94,7 +97,7 @@
import { activities, store, send } from '@koishijs/client'
import { computed, provide, watch } from 'vue'
import { envMap, name, SettingsData, Tree } from './utils'
import { envMap, name, plugins, SettingsData, dialogFork, Tree } from './utils'
import KModifier from './modifier.vue'
const props = defineProps<{
Expand All @@ -109,6 +112,8 @@ const config = computed({
set: value => emit('update:modelValue', value),
})
const shortname = computed(() => name.value.replace(/(koishi-|^@koishijs\/)plugin-/, ''))
const env = computed(() => envMap.value[name.value])
const local = computed(() => store.packages[name.value])
const hint = computed(() => local.value.workspace ? '请检查插件源代码。' : '请联系插件作者并反馈此问题。')
Expand Down
12 changes: 6 additions & 6 deletions plugins/config/client/components/select.vue
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<template>
<el-dialog
v-if="store.packages"
:modelValue="!!select"
@update:modelValue="select = null"
:modelValue="!!dialogSelect"
@update:modelValue="dialogSelect = null"
class="plugin-select"
>
<template #header>
Expand Down Expand Up @@ -30,7 +30,7 @@
import { router, send, store, useI18nText } from '@koishijs/client'
import { computed, inject, nextTick, ref, watch } from 'vue'
import { PackageProvider } from '@koishijs/plugin-config'
import { select } from './utils'
import { dialogSelect } from './utils'
const tt = useI18nText()
Expand All @@ -44,14 +44,14 @@ const packages = computed(() => Object.values(store.packages).filter(({ name, sh
}))
function configure(shortname: string) {
const path = select.value.path
const path = dialogSelect.value.path
const ident = Math.random().toString(36).slice(2, 8)
select.value = null
dialogSelect.value = null
send('manager/unload', path, shortname + ':' + ident, {})
router.push('/plugins/' + ident)
}
watch(select, async (value) => {
watch(dialogSelect, async (value) => {
if (!value) return
await nextTick()
await input.value.focus()
Expand Down
50 changes: 4 additions & 46 deletions plugins/config/client/components/tree.vue
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
{{ getLabel(node) }}
</div>
<div class="right">
<span class="status" :class="getStatus(node)"></span>
<span class="status-light ignore-disabled" :class="getStatus(node.data)"></span>
</div>
</div>
</el-tree>
Expand All @@ -38,9 +38,8 @@
<script lang="ts" setup>
import { ref, computed, onActivated, nextTick, watch } from 'vue'
import { send, store, useMenu } from '@koishijs/client'
import { ScopeStatus } from 'cordis'
import { Tree, getFullName, plugins } from './utils'
import { send, useMenu } from '@koishijs/client'
import { Tree, getStatus, plugins } from './utils'
const props = defineProps<{
modelValue: string
Expand Down Expand Up @@ -70,22 +69,12 @@ interface Node {
function getLabel(node: Node) {
if (node.data.name === 'group') {
return '分组:' + (node.label || node.data.alias)
return '分组:' + (node.label || node.data.path)
} else {
return node.label || node.data.name || '待添加'
}
}
function getStatus(node: Node) {
switch (store.packages?.[getFullName(node.data.name)]?.runtime?.forks?.[node.data.path]?.status) {
case ScopeStatus.PENDING: return 'pending'
case ScopeStatus.LOADING: return 'loading'
case ScopeStatus.ACTIVE: return 'active'
case ScopeStatus.FAILED: return 'failed'
case ScopeStatus.DISPOSED: return 'disposed'
}
}
function allowDrag(node: Node) {
return node.data.path !== ''
}
Expand Down Expand Up @@ -187,39 +176,8 @@ onActivated(async () => {
.right {
height: 100%;
margin: 0 1.5rem 0 0.5rem;
> span.status {
display: inline-block;
width: 0.625rem;
height: 0.625rem;
border-radius: 100%;
transition: var(--color-transition);
&.active {
background-color: var(--k-color-success);
}
&.pending {
background-color: var(--k-color-warning);
}
&.loading {
animation: status-flash 1s infinite;
background-color: var(--k-color-warning);
}
&.failed {
background-color: var(--k-color-danger);
}
}
}
}
}
@keyframes status-flash {
0%, 100% {
opacity: 0;
}
50% {
opacity: 1;
}
}
</style>
Loading

0 comments on commit 7e90ec4

Please sign in to comment.