Skip to content

Commit 78cd035

Browse files
committed
feat: add custom action handling to app store and integrate in OverView component
1 parent dea13ff commit 78cd035

File tree

2 files changed

+57
-2
lines changed

2 files changed

+57
-2
lines changed

frontend/src/stores/app.ts

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { useI18n } from 'vue-i18n'
2-
import { computed, ref } from 'vue'
2+
import { h, computed, ref, type VNode, isVNode, resolveComponent } from 'vue'
33
import { defineStore } from 'pinia'
44

55
import { useEnvStore } from './env'
@@ -41,6 +41,42 @@ export const useAppStore = defineStore('app', () => {
4141
y: 0,
4242
})
4343

44+
/* Actions */
45+
interface CustomAction {
46+
component: string
47+
componentProps?: Recordable
48+
componentSlots?: Recordable
49+
}
50+
type CustomActionSlot =
51+
| (({ h }: any) => VNode | string | number | boolean)
52+
| VNode
53+
| string
54+
| number
55+
| boolean
56+
const customActions: { [key: string]: CustomAction[] } = {
57+
core_state: [],
58+
}
59+
const addCustomActions = (target: string, actions: CustomAction | CustomAction[]) => {
60+
if (!customActions[target]) throw new Error('Target does not exist: ' + target)
61+
const _actions = Array.isArray(actions) ? actions : [actions]
62+
customActions[target].push(..._actions)
63+
const remove = () => {
64+
customActions[target] = customActions[target].filter((a) => !_actions.includes(a))
65+
}
66+
return remove
67+
}
68+
const renderCustomActionSlot = (slot: CustomActionSlot) => {
69+
let result: CustomActionSlot = slot
70+
if (typeof result === 'function') {
71+
const customH = (type: any, ...args: any[]) => h(resolveComponent(type), ...args)
72+
result = result({ h: customH })
73+
}
74+
if (isVNode(result)) {
75+
return result
76+
}
77+
return h('div', result)
78+
}
79+
4480
const { t } = useI18n()
4581
const envStore = useEnvStore()
4682

@@ -146,5 +182,8 @@ export const useAppStore = defineStore('app', () => {
146182
updatable,
147183
checkForUpdates,
148184
downloadApp,
185+
customActions,
186+
addCustomActions,
187+
renderCustomActionSlot,
149188
}
150189
})

frontend/src/views/HomeView/components/OverView.vue

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { ref, onUnmounted, h } from 'vue'
44
55
import { getKernelWS } from '@/api/kernel'
66
import { useModal } from '@/components/Modal'
7-
import { useEnvStore, useKernelApiStore } from '@/stores'
7+
import { useEnvStore, useAppStore, useKernelApiStore } from '@/stores'
88
import { ModeOptions } from '@/constant/kernel'
99
import { formatBytes, handleChangeMode, message, setIntervalImmediately } from '@/utils'
1010
@@ -24,6 +24,7 @@ const statistics = ref({
2424
2525
const { t } = useI18n()
2626
const [Modal, modalApi] = useModal({})
27+
const appStore = useAppStore()
2728
const envStore = useEnvStore()
2829
const kernelApiStore = useKernelApiStore()
2930
@@ -161,6 +162,21 @@ onUnmounted(() => {
161162
>
162163
{{ t('home.overview.tunMode') }}
163164
</Switch>
165+
<component
166+
v-for="(action, index) in appStore.customActions.core_state"
167+
:key="index"
168+
:is="action.component"
169+
v-bind="action.componentProps"
170+
class="ml-8"
171+
>
172+
<template
173+
v-for="([name, slot], index) in Object.entries(action.componentSlots || {})"
174+
:key="index"
175+
#[name]
176+
>
177+
<component :is="appStore.renderCustomActionSlot(slot)" />
178+
</template>
179+
</component>
164180
<Button
165181
@click="handleShowApiLogs"
166182
v-tips="'home.overview.viewlog'"

0 commit comments

Comments
 (0)