Skip to content

Commit

Permalink
feat(config): refactor client-side code
Browse files Browse the repository at this point in the history
  • Loading branch information
shigma committed Apr 28, 2024
1 parent c453740 commit e50b923
Show file tree
Hide file tree
Showing 15 changed files with 356 additions and 366 deletions.
6 changes: 3 additions & 3 deletions packages/client/client/plugins/loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { Dict } from 'cosmokit'
declare module '../context' {
interface Context {
$loader: LoaderService
$entry?: ClientEntry
$entry?: LoadState
}
}

Expand Down Expand Up @@ -53,7 +53,7 @@ const loaders: Dict<LoaderFactory> = {
},
}

export interface ClientEntry {
export interface LoadState {
fork?: ForkScope
paths: string[]
done: Ref<boolean>
Expand All @@ -63,7 +63,7 @@ export interface ClientEntry {
export default class LoaderService extends Service {
private backendId: any

public extensions: Dict<ClientEntry> = shallowReactive({})
public extensions: Dict<LoadState> = shallowReactive({})

constructor(ctx: Context) {
super(ctx, '$loader', true)
Expand Down
26 changes: 18 additions & 8 deletions plugins/config/client/components/forks.vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@
<table>
<tr v-for="id in plugins.forks[dialogFork]" :key="id">
<td class="text-left">
<span class="status-light" :class="getStatus(plugins.paths[id])"></span>
<span class="status-light" :class="ctx.manager.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 class="action" @click.stop="ctx.manager.remove(plugins.paths[id])"><k-icon name="delete"></k-icon></span>
</span>
</td>
</tr>
Expand All @@ -42,16 +42,23 @@
<script setup lang="ts">
import { computed } from 'vue'
import { store, send, router } from '@cordisjs/client'
import { dialogFork, plugins, getStatus, removeItem, Tree } from './utils'
import { send, router, useContext } from '@cordisjs/client'
import { Node } from '..'
const local = computed(() => store.packages?.[dialogFork.value])
const ctx = useContext()
const plugins = computed(() => ctx.manager.plugins.value)
const dialogFork = computed({
get: () => ctx.manager.dialogFork.value,
set: (value) => ctx.manager.dialogFork.value = value,
})
function getLabel(tree: Tree) {
const local = computed(() => ctx.manager.data.value.packages?.[dialogFork.value])
function getLabel(tree: Node) {
return `${tree.label ? `${tree.label} ` : ''}[${tree.path}]`
}
function getFullPath(tree: Tree) {
function getFullPath(tree: Node) {
const path = [getLabel(tree)]
while (tree.parent) {
tree = tree.parent
Expand All @@ -63,7 +70,10 @@ function getFullPath(tree: Tree) {
async function configure(id?: string) {
if (!id) {
id = await send('manager/add', { name: dialogFork.value, disabled: true }, '')
id = await send('manager.config.create', {
name: dialogFork.value,
disabled: true,
})
}
await router.push('/plugins/' + id)
dialogFork.value = null
Expand Down
23 changes: 0 additions & 23 deletions plugins/config/client/components/global.vue

This file was deleted.

2 changes: 0 additions & 2 deletions plugins/config/client/components/group.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,8 @@
<script lang="ts" setup>
import { computed } from 'vue'
import { Tree } from './utils'
const props = defineProps<{
current: Tree
modelValue: any
}>()
Expand Down
64 changes: 42 additions & 22 deletions plugins/config/client/components/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@
<div>请在左侧选择插件</div>
</k-empty>
<k-content v-else class="plugin-view" :key="path">
<group-settings v-if="current.children" v-model="config" :current="current"></group-settings>
<plugin-settings v-else :current="current" v-model="config"></plugin-settings>
<group-settings v-if="current.children" v-model="config"></group-settings>
<plugin-settings v-else v-model="config"></plugin-settings>
</k-content>

<el-dialog
Expand All @@ -38,7 +38,7 @@
</template>
<template #footer>
<el-button @click="showRemove = false">取消</el-button>
<el-button type="danger" @click="(showRemove = false, removeItem(remove), tree?.activate())">确定</el-button>
<el-button type="danger" @click="(showRemove = false, ctx.manager.remove(remove), tree?.activate())">确定</el-button>
</template>
</el-dialog>

Expand Down Expand Up @@ -78,15 +78,23 @@
import { computed, ref, watch, nextTick } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { clone, message, send, store, useContext, Schema } from '@cordisjs/client'
import { Tree, hasCoreDeps, current, plugins, removeItem, dialogSelect, dialogFork } from './utils'
import { clone, message, send, useContext, Schema } from '@cordisjs/client'
import { Node } from '..'
import GroupSettings from './group.vue'
import TreeView from './tree.vue'
import PluginSettings from './plugin.vue'
const route = useRoute()
const router = useRouter()
const current = computed(() => ctx.manager.current.value)
const plugins = computed(() => ctx.manager.plugins.value)
const dialogFork = computed({
get: () => ctx.manager.dialogFork.value,
set: (value) => ctx.manager.dialogFork.value = value,
})
const path = computed<string>({
get() {
const name = route.path.slice(9)
Expand All @@ -109,9 +117,9 @@ async function handleOpen() {
inputEl.value?.focus()
}
const remove = ref<Tree>()
const remove = ref<Node>()
const showRemove = ref(false)
const rename = ref<Tree>()
const rename = ref<Node>()
const showRename = ref(false)
const groupCreate = ref<string>(null)
Expand All @@ -124,17 +132,17 @@ watch(rename, (value) => {
})
watch(() => plugins.value.paths[path.value], (value) => {
current.value = value
ctx.manager.current.value = value
if (value) config.value = clone(value.config)
}, { immediate: true })
const ctx = useContext()
ctx.define('config.tree', current)
ctx.define('config.tree', ctx.manager.current)
ctx.action('config.tree.add-plugin', {
hidden: ({ config }) => config.tree && !config.tree.children,
action: ({ config }) => dialogSelect.value = config.tree,
action: ({ config }) => ctx.manager.dialogSelect.value = config.tree,
})
ctx.action('config.tree.add-group', {
Expand All @@ -145,7 +153,11 @@ ctx.action('config.tree.add-group', {
})
async function createGroup(label: string) {
const id = await send('manager/add', { name: 'cordis/group', label }, groupCreate.value)
const id = await send('manager.config.create', {
name: 'cordis/group',
parent: groupCreate.value,
label,
})
router.replace('/plugins/' + id)
groupCreate.value = null
}
Expand All @@ -157,11 +169,13 @@ ctx.action('config.tree.clone', {
? config.tree.parent.children
: plugins.value.data.slice(1)
const index = children.findIndex(tree => tree.path === config.tree.path)
const id = await send('manager/add', {
const id = await send('manager.config.create', {
name: config.tree.name,
config: config.tree.config,
disabled: true,
}, config.tree.parent.id, index + 1)
parent: config.tree.parent.id,
position: index + 1,
})
router.replace(`/plugins/${id}`)
},
})
Expand All @@ -182,12 +196,12 @@ ctx.action('config.tree.rename', {
})
ctx.action('config.tree.remove', {
disabled: ({ config }) => !config.tree || hasCoreDeps(config.tree),
disabled: ({ config }) => !config.tree || ctx.manager.hasCoreDeps(config.tree),
action: ({ config }) => remove.value = config.tree,
})
function checkConfig(name: string) {
let schema = store.packages[name]?.runtime.schema
let schema = ctx.manager.data.value.packages[name]?.runtime.schema
if (!schema) return true
try {
(new Schema(schema))(config.value)
Expand All @@ -205,7 +219,7 @@ ctx.action('config.tree.save', {
const { disabled } = tree
if (!disabled && !checkConfig(tree.name)) return
try {
await execute(tree, disabled ? 'unload' : 'reload')
await execute(tree, disabled || null)
message.success(disabled ? '配置已保存。' : '配置已重载。')
} catch (error) {
message.error('操作失败,请检查日志!')
Expand All @@ -214,27 +228,33 @@ ctx.action('config.tree.save', {
})
ctx.action('config.tree.toggle', {
disabled: ({ config }) => !config.tree || hasCoreDeps(config.tree),
disabled: ({ config }) => !config.tree || ctx.manager.hasCoreDeps(config.tree),
action: async ({ config: { tree } }) => {
const { disabled, name } = tree
if (disabled && !checkConfig(tree.name)) return
try {
await execute(tree, disabled ? 'reload' : 'unload')
await execute(tree, !disabled || null)
message.success((name === 'group' ? '分组' : '插件') + (disabled ? '已启用。' : '已停用。'))
} catch (error) {
message.error('操作失败,请检查日志!')
}
},
})
async function execute(tree: Tree, event: 'unload' | 'reload') {
await send(`manager/${event}`, tree.id, config.value)
async function execute(tree: Node, disabled: true | null) {
await send('manager.config.update', {
id: tree.id,
disabled,
})
}
function renameItem(tree: Tree, name: string) {
async function renameItem(tree: Node, name: string) {
showRename.value = false
tree.label = name
send('manager/meta', tree.path, { $label: name || null })
await send('manager.config.update', {
id: tree.path,
label: name || null,
})
}
</script>
Expand Down
34 changes: 21 additions & 13 deletions plugins/config/client/components/plugin.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<template>
<template v-if="name">
<template v-if="current?.name in data.packages">
<k-comment v-if="!local.runtime">
<p>正在加载插件配置……</p>
</k-comment>
Expand All @@ -20,9 +20,9 @@
</k-comment>
<k-comment
v-for="({ required }, name) in env.using" :key="name"
:type="name in store.services ? 'success' : required ? 'warning' : 'primary'">
:type="name in data.services ? 'success' : required ? 'warning' : 'primary'">
<p>
{{ required ? '必需' : '可选' }}服务:{{ name }} ({{ name in store.services ? '已加载' : '未加载' }})
{{ required ? '必需' : '可选' }}服务:{{ name }} ({{ name in data.services ? '已加载' : '未加载' }})
</p>
</k-comment>
</k-slot>
Expand All @@ -31,7 +31,7 @@
<!-- implements -->
<k-slot-item :order="600">
<template v-for="name in env.impl" :key="name">
<k-comment v-if="name in store.services && current.disabled" type="warning">
<k-comment v-if="name in data.services && current.disabled" type="warning">
<p>此插件将会提供 {{ name }} 服务,但此服务已被其他插件实现。</p>
</k-comment>
<k-comment v-else :type="current.disabled ? 'primary' : 'success'">
Expand All @@ -46,14 +46,14 @@
<p>此插件已在运行且不可重用,启用可能会导致非预期的问题。</p>
</k-comment>
<k-comment v-if="plugins.forks[current.name]?.length > 1" type="primary">
<p>此插件存在多份配置,<span class="k-link" @click.stop="dialogFork = name">点击前往管理</span>。</p>
<p>此插件存在多份配置,<span class="k-link" @click.stop="dialogFork = current.name">点击前往管理</span>。</p>
</k-comment>
</k-slot-item>

<!-- implements -->
<k-slot-item :order="300">
<template v-for="(activity, key) in ctx.$router.pages" :key="key">
<k-comment type="success" v-if="activity.ctx.extension?.paths.includes(current.path) && !activity.disabled()">
<k-comment type="success" v-if="activity.ctx.$entry?.paths.includes(current.path) && !activity.disabled()">
<p>
<span>此插件提供了页面:</span>
<k-activity-link :id="activity.id" />
Expand Down Expand Up @@ -94,38 +94,46 @@

<script lang="ts" setup>
import { store, send, useContext } from '@cordisjs/client'
import { send, useContext, useRpc } from '@cordisjs/client'
import { computed, provide, watch } from 'vue'
import { envMap, name, plugins, dialogFork, Tree } from './utils'
import { Data } from '../../src'
const props = defineProps<{
current: Tree
modelValue: any
}>()
const emit = defineEmits(['update:modelValue'])
const ctx = useContext()
const data = useRpc<Data>()
const current = computed(() => ctx.manager.current.value)
const plugins = computed(() => ctx.manager.plugins.value)
const dialogFork = computed({
get: () => ctx.manager.dialogFork.value,
set: (value) => ctx.manager.dialogFork.value = value,
})
const config = computed({
get: () => props.modelValue,
set: value => emit('update:modelValue', value),
})
const env = computed(() => envMap.value[name.value])
const local = computed(() => store.packages[name.value])
const env = computed(() => ctx.manager.getEnvInfo(current.value?.name))
const local = computed(() => data.value.packages[current.value?.name])
const hint = computed(() => local.value.workspace ? '请检查插件源代码。' : '请联系插件作者并反馈此问题。')
watch(local, (value) => {
if (!value || value.runtime) return
send('config/request-runtime', value.name)
send('manager.package.runtime', value.name)
}, { immediate: true })
provide('plugin:name', name)
provide('plugin:env', env)
provide('manager.settings.local', local)
provide('manager.settings.config', config)
provide('manager.settings.current', computed(() => props.current))
provide('manager.settings.current', current)
</script>

Expand Down
Loading

0 comments on commit e50b923

Please sign in to comment.