126 lines
3.1 KiB
Vue
126 lines
3.1 KiB
Vue
|
|
<template>
|
||
|
|
<q-card class="full-height">
|
||
|
|
<q-card-section class="row items-center justify-between">
|
||
|
|
<div>
|
||
|
|
<div class="text-h6">{{ componentInfo?.name || 'Select a Component' }}</div>
|
||
|
|
<div class="text-caption text-grey" v-if="componentInfo">
|
||
|
|
{{ componentInfo.description }}
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
<div class="row items-center q-gutter-xs">
|
||
|
|
<q-btn
|
||
|
|
v-if="componentInfo"
|
||
|
|
color="primary"
|
||
|
|
@click="executeComponent"
|
||
|
|
:loading="isRunning"
|
||
|
|
size="lg"
|
||
|
|
icon="mdi-play"
|
||
|
|
label="Execute"
|
||
|
|
/>
|
||
|
|
<q-btn
|
||
|
|
v-if="componentInfo"
|
||
|
|
color="secondary"
|
||
|
|
@click="toggleSidebar"
|
||
|
|
flat
|
||
|
|
:icon="sidebarOpen ? 'mdi-chevron-right' : 'mdi-chevron-left'"
|
||
|
|
size="lg"
|
||
|
|
:title="sidebarOpen ? 'Hide sidebar' : 'Show sidebar'"
|
||
|
|
/>
|
||
|
|
</div>
|
||
|
|
</q-card-section>
|
||
|
|
|
||
|
|
<q-card-section class="q-pa-md">
|
||
|
|
<component
|
||
|
|
:is="componentComponent"
|
||
|
|
v-if="componentComponent"
|
||
|
|
ref="componentRef"
|
||
|
|
/>
|
||
|
|
<div v-else class="text-center text-grey q-pa-xl">
|
||
|
|
<q-icon name="mdi-cube-outline" size="64px" class="q-mb-md" />
|
||
|
|
<div class="text-h6">Welcome to S8n Playground</div>
|
||
|
|
<div class="text-body1">
|
||
|
|
Select a component from the sidebar to start interacting with it.
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</q-card-section>
|
||
|
|
<q-card-section>
|
||
|
|
<div
|
||
|
|
class="row q-pa-md"
|
||
|
|
style="background-color: rgba(130, 130, 130, 0.3)"
|
||
|
|
v-if="componentInfo?.methods"
|
||
|
|
>
|
||
|
|
<q-btn
|
||
|
|
v-for="method in customActions"
|
||
|
|
:key="method"
|
||
|
|
color="secondary"
|
||
|
|
@click="executeCustomAction(method)"
|
||
|
|
:loading="isRunning"
|
||
|
|
size="md"
|
||
|
|
:icon="actionIcon(method)"
|
||
|
|
:label="method"
|
||
|
|
/>
|
||
|
|
</div>
|
||
|
|
</q-card-section>
|
||
|
|
</q-card>
|
||
|
|
</template>
|
||
|
|
|
||
|
|
<script setup lang="ts">
|
||
|
|
import { computed, ref, type Component } from 'vue'
|
||
|
|
import type { ComponentInfo } from 'src/composables/useComponentStore'
|
||
|
|
|
||
|
|
interface ComponentInstance {
|
||
|
|
execute: (method: string) => Promise<unknown>
|
||
|
|
running: boolean
|
||
|
|
error?: string
|
||
|
|
duration?: number
|
||
|
|
inputs: unknown
|
||
|
|
outputs?: unknown
|
||
|
|
statusCode?: number
|
||
|
|
}
|
||
|
|
|
||
|
|
const props = defineProps<{
|
||
|
|
componentInfo: ComponentInfo | undefined
|
||
|
|
componentComponent: Component | undefined
|
||
|
|
sidebarOpen: boolean
|
||
|
|
isRunning: boolean
|
||
|
|
}>()
|
||
|
|
|
||
|
|
const emit = defineEmits<{
|
||
|
|
execute: []
|
||
|
|
toggleSidebar: []
|
||
|
|
customAction: [method: string]
|
||
|
|
}>()
|
||
|
|
|
||
|
|
const componentRef = ref<ComponentInstance>()
|
||
|
|
|
||
|
|
const customActions = computed(() => {
|
||
|
|
const methods = props.componentInfo?.methods ?? []
|
||
|
|
return methods.filter((m) => m !== 'Execute')
|
||
|
|
})
|
||
|
|
|
||
|
|
const actionIcon = (method: string) => {
|
||
|
|
const icons: Record<string, string> = {
|
||
|
|
Reset: 'mdi-refresh',
|
||
|
|
Clear: 'mdi-close',
|
||
|
|
Default: 'mdi-cog',
|
||
|
|
}
|
||
|
|
return icons[method] || 'mdi-cog'
|
||
|
|
}
|
||
|
|
|
||
|
|
const executeComponent = () => {
|
||
|
|
emit('execute')
|
||
|
|
}
|
||
|
|
|
||
|
|
const toggleSidebar = () => {
|
||
|
|
emit('toggleSidebar')
|
||
|
|
}
|
||
|
|
|
||
|
|
const executeCustomAction = (method: string) => {
|
||
|
|
emit('customAction', method)
|
||
|
|
}
|
||
|
|
|
||
|
|
defineExpose({
|
||
|
|
componentRef,
|
||
|
|
})
|
||
|
|
</script>
|