Skip to content

Commit

Permalink
feat(manager): refactor to manager accessor
Browse files Browse the repository at this point in the history
  • Loading branch information
shigma committed Jun 2, 2024
1 parent 9491ac7 commit aaaa366
Show file tree
Hide file tree
Showing 9 changed files with 79 additions and 100 deletions.
42 changes: 15 additions & 27 deletions plugins/manager/client/components/index.vue
Original file line number Diff line number Diff line change
@@ -1,29 +1,29 @@
<template>
<k-layout menu="config.tree" :menu-data="current">
<k-layout menu="config.tree" :menu-data="currentEntry">
<template #header>
<!-- root -->
<template v-if="!current">插件配置</template>
<template v-if="!currentEntry">插件配置</template>

<!-- group -->
<template v-else-if="current.isGroup">
分组:{{ current.label || current.id }}
<template v-else-if="currentEntry.isGroup">
分组:{{ currentEntry.label || currentEntry.id }}
</template>

<!-- plugin -->
<template v-else>
{{ current.label || current.name }}
{{ currentEntry.label || currentEntry.name }}
</template>
</template>

<template #left>
<tree-view ref="tree" v-model="path"></tree-view>
<tree-view ref="tree"></tree-view>
</template>

<k-empty v-if="!current">
<k-empty v-if="!currentEntry">
<div>请在左侧选择插件</div>
</k-empty>
<k-content v-else class="plugin-view" :key="path">
<plugin-settings v-model="config"></plugin-settings>
<plugin-settings></plugin-settings>
</k-content>

<el-dialog
Expand Down Expand Up @@ -77,7 +77,7 @@
import { computed, ref, watch, nextTick } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { clone, message, send, useContext, Schema } from '@cordisjs/client'
import { message, send, useContext, Schema } from '@cordisjs/client'
import TreeView from './tree.vue'
import PluginSettings from './plugin.vue'
import { EntryData } from '../../src'
Expand All @@ -86,22 +86,15 @@ const route = useRoute()
const router = useRouter()
const ctx = useContext()
const current = computed(() => ctx.manager.current.value)
const currentEntry = computed(() => ctx.manager.currentEntry)
const plugins = computed(() => ctx.manager.plugins.value)
const path = computed<string>({
get() {
if (!route.path.startsWith('/plugins/')) return ''
if (typeof route.params.id !== 'string') return ''
return route.params.id in plugins.value.entries ? route.params.id : ''
},
set(name) {
if (!(name in plugins.value.entries)) name = ''
router.replace('/plugins/' + name)
},
const path = computed<string>(() => {
if (!route.path.startsWith('/plugins/')) return ''
if (typeof route.params.id !== 'string') return ''
return route.params.id in plugins.value.entries ? route.params.id : ''
})
const config = ref()
const input = ref('')
const inputEl = ref()
const tree = ref<InstanceType<typeof TreeView>>()
Expand All @@ -126,12 +119,7 @@ watch(rename, (value) => {
if (value) showRename.value = true
})
watch(() => plugins.value.entries[path.value], (value) => {
ctx.manager.current.value = value
if (value) config.value = clone(value.config)
}, { immediate: true })
ctx.define('config.tree', ctx.manager.current)
ctx.define('config.tree', currentEntry.value)
ctx.action('config.tree.add-plugin', {
hidden: ({ config }) => config.tree && !config.tree.isGroup,
Expand Down
23 changes: 3 additions & 20 deletions plugins/manager/client/components/plugin.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<template>
<template v-if="current && current.name in data.packages">
<template v-if="ctx.manager.currentEntry && ctx.manager.currentEntry.name in data.packages">
<k-comment v-if="!local.runtime">
<p>正在加载插件配置……</p>
</k-comment>
Expand All @@ -23,39 +23,22 @@
<script lang="ts" setup>
import { send, useContext, useRpc } from '@cordisjs/client'
import { computed, provide, watch } from 'vue'
import { computed, watch } from 'vue'
import { Data } from '../../src'
const props = defineProps<{
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 config = computed({
get: () => props.modelValue,
set: value => emit('update:modelValue', value),
})
const env = computed(() => ctx.manager.getEnvInfo(current.value)!)
const local = computed(() => data.value.packages[current.value?.name!])
const local = computed(() => data.value.packages[ctx.manager.currentEntry?.name!])
const hint = computed(() => local.value.workspace ? '请检查插件源代码。' : '请联系插件作者并反馈此问题。')
watch(local, (value) => {
if (!value || value.runtime) return
send('manager.package.runtime', { name: value.package.name })
}, { immediate: true })
provide('manager.settings.local', local)
provide('manager.settings.config', config)
provide('manager.settings.current', current)
</script>

<style lang="scss">
Expand Down
17 changes: 5 additions & 12 deletions plugins/manager/client/components/tree.vue
Original file line number Diff line number Diff line change
Expand Up @@ -42,22 +42,15 @@ import { useRoute } from 'vue-router'
import type { ElScrollbar, ElTree } from 'element-plus'
import type { FilterNodeMethodFunction, TreeOptionProps } from 'element-plus/es/components/tree/src/tree.type'
import type TreeNode from 'element-plus/es/components/tree/src/model/node'
import { send, useContext, useMenu, useRpc } from '@cordisjs/client'
import { getStatusClass } from './utils'
import { Data, EntryData } from '../../src'
import { send, router, useContext, useMenu } from '@cordisjs/client'
import { getStatusClass } from '../utils'
import { EntryData } from '../../src'
const props = defineProps<{
modelValue: string
}>()
const data = useRpc<Data>()
const ctx = useContext()
const route = useRoute()
const trigger = useMenu('config.tree')
const plugins = computed(() => ctx.manager.plugins.value)
const emit = defineEmits(['update:modelValue'])
const root = ref<InstanceType<typeof ElScrollbar>>()
const tree = ref<InstanceType<typeof ElTree>>()
const keyword = ref('')
Expand Down Expand Up @@ -117,7 +110,7 @@ function allowDrop(source: EntryNode, target: EntryNode, type: 'inner' | 'prev'
}
function handleClick(tree: EntryData, target: EntryNode, instance: any, event: MouseEvent) {
emit('update:modelValue', tree.id)
router.replace('/plugins/' + tree.id)
// el-tree will stop propagation,
// so we need to manually trigger the event
// so that context menu can be closed.
Expand Down Expand Up @@ -154,7 +147,7 @@ const optionProps: TreeOptionProps = {
const words: string[] = []
if (data.isGroup) words.push('is-group')
if (!data.isGroup && !(data.name in ctx.manager.data.value.packages)) words.push('is-disabled')
if (data.id === props.modelValue) words.push('is-active')
if (data.id === ctx.manager.currentEntry?.id) words.push('is-active')
return words.join(' ')
},
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
import { computed } from 'vue'
import { send, router, useContext } from '@cordisjs/client'
import { getStatusClass } from './utils'
import { getStatusClass } from '../utils'
import { EntryData } from '../../src'
const ctx = useContext()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,8 @@

<script lang="ts" setup>
import { router, Dict, send, useContext, useI18nText } from '@cordisjs/client'
import { computed, inject, nextTick, ref, watch } from 'vue'
import type { LocalObject } from '@cordisjs/registry'
import { router, send, useContext, useI18nText } from '@cordisjs/client'
import { computed, nextTick, ref, watch } from 'vue'
const ctx = useContext()
const tt = useI18nText()
Expand Down Expand Up @@ -79,6 +78,8 @@ watch(() => ctx.manager.dialogSelect, async (value) => {
<style lang="scss">
.plugin-select {
padding: 0;
.el-dialog__header {
margin-right: 0;
padding: 12px 20px;
Expand Down
76 changes: 45 additions & 31 deletions plugins/manager/client/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { Context, Dict, router, send, Service } from '@cordisjs/client'
import { computed, defineComponent, h, Ref, ref, resolveComponent } from 'vue'
import { Context, Dict, remove, router, send, Service } from '@cordisjs/client'
import { computed, reactive, ref, Ref } from 'vue'
import type { Data, EntryData } from '../src'
import Settings from './components/index.vue'
import Forks from './components/forks.vue'
import Select from './components/select.vue'
import Forks from './dialogs/forks.vue'
import Select from './dialogs/select.vue'
import Main from './routes/main.vue'
import Config from './routes/config.vue'

Expand Down Expand Up @@ -41,31 +41,50 @@ export interface EnvInfo {
warning?: boolean
}

export interface SubRoute {
path: string
name: string
component: any
}

export default class Manager extends Service {
static inject = {
optional: ['manager'],
}

#dialogFork = ref<string>()
#dialogSelect = ref<EntryData>()
_dialogFork = ref<string>()
_dialogSelect = ref<EntryData>()

get dialogFork() {
return this.#dialogFork.value
return this._dialogFork.value
}

set dialogFork(value) {
this.#dialogFork.value = value
this._dialogFork.value = value
}

get dialogSelect() {
return this.#dialogSelect.value
return this._dialogSelect.value
}

set dialogSelect(value) {
this.#dialogSelect.value = value
this._dialogSelect.value = value
}

current = ref<EntryData>()
get currentEntry() {
const { path } = router.currentRoute.value
if (!path.startsWith('/plugins/')) return
const [id] = path.slice(9).split('/', 1)
return this.plugins.value.entries[id]
}

get currentRoute() {
const entry = this.currentEntry
if (!entry) return
const { path } = router.currentRoute.value
const rest = path.slice(9 + entry.id.length + 1)
return this.routes.find(route => route.path === rest)
}

plugins = computed(() => {
const expanded: string[] = []
Expand All @@ -91,9 +110,9 @@ export default class Manager extends Service {
})

type = computed(() => {
const env = this.getEnvInfo(this.current.value)
const env = this.getEnvInfo(this.currentEntry)
if (!env) return
if (env.warning && this.current.value!.disabled) return 'warning'
if (env.warning && this.currentEntry!.disabled) return 'warning'
for (const name in env.using) {
if (name in this.data.value.services || {}) {
if (env.impl.includes(name)) return 'warning'
Expand All @@ -103,28 +122,16 @@ export default class Manager extends Service {
}
})

routes = reactive<SubRoute[]>([])

constructor(ctx: Context, public data: Ref<Data>) {
super(ctx, 'manager', true)
}

start() {
this.ctx.slot({
type: 'global',
component: defineComponent(() => () => {
return h(resolveComponent('k-slot'), { name: 'plugin-select', single: true })
}),
})

this.ctx.slot({
type: 'plugin-select-base',
component: Select,
order: -1000,
})

this.ctx.slot({
type: 'plugin-select',
component: Select,
order: -1000,
})

this.ctx.slot({
Expand All @@ -142,15 +149,13 @@ export default class Manager extends Service {
component: Settings,
})

this.ctx.page({
parent: 'plugins',
this.subroute({
path: '',
name: '概览',
component: Main,
})

this.ctx.page({
parent: 'plugins',
this.subroute({
path: 'config',
name: '配置',
component: Config,
Expand Down Expand Up @@ -198,6 +203,15 @@ export default class Manager extends Service {
}])
}

subroute(options: SubRoute) {
const caller = this[Context.current]
options.component = caller.wrapComponent(options.component)
return caller.effect(() => {
this.routes.push(options)
return () => remove(this.routes, options)
})
}

ensure(name: string, passive?: boolean) {
const forks = this.plugins.value.forks[name]
if (!forks?.length) {
Expand Down
10 changes: 5 additions & 5 deletions plugins/manager/client/routes/config.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<template>
<template v-if="current && local.runtime?.schema">
<k-form :schema="local.runtime.schema" :initial="current!.config" v-model="config">
<template v-if="currentEntry && local.runtime?.schema">
<k-form :schema="local.runtime.schema" :initial="currentEntry.config" v-model="config">
</k-form>
</template>
<k-empty v-else>
Expand All @@ -18,10 +18,10 @@ const ctx = useContext()
const data = useRpc<Data>()
const config = ref()
const current = computed(() => ctx.manager.current.value)
const local = computed(() => data.value.packages[current.value?.name!])
const currentEntry = computed(() => ctx.manager.currentEntry)
const local = computed(() => data.value.packages[currentEntry.value?.name!])
watch(current, (value) => {
watch(currentEntry, (value) => {
if (!value) return
config.value = clone(value.config)
}, { immediate: true })
Expand Down
2 changes: 1 addition & 1 deletion plugins/manager/client/routes/main.vue
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ import { Data } from '../../src'
const ctx = useContext()
const data = useRpc<Data>()
const current = computed(() => ctx.manager.current.value)
const current = computed(() => ctx.manager.currentEntry)
const local = computed(() => data.value.packages[current.value?.name!])
const env = computed(() => ctx.manager.getEnvInfo(current.value)!)
Expand Down
File renamed without changes.

0 comments on commit aaaa366

Please sign in to comment.