137 lines
4.3 KiB
Vue
137 lines
4.3 KiB
Vue
<template>
|
|
<q-page class="playground-page">
|
|
<div class="row q-pa-md q-gutter-md">
|
|
<!-- Component Selection Sidebar -->
|
|
<div class="col-12 col-md-3">
|
|
<q-card>
|
|
<q-card-section>
|
|
<div class="text-h6">Components</div>
|
|
<div class="text-caption text-grey">Select a component to interact with</div>
|
|
</q-card-section>
|
|
|
|
<q-list separator>
|
|
<q-item
|
|
v-for="component in availableComponents"
|
|
:key="component.code"
|
|
clickable
|
|
:active="selectedComponent === component.code"
|
|
@click="selectedComponent = component.code"
|
|
active-class="bg-primary text-white"
|
|
>
|
|
<q-item-section avatar>
|
|
<q-icon :name="component.icon" />
|
|
</q-item-section>
|
|
<q-item-section>
|
|
<q-item-label>{{ component.name }}</q-item-label>
|
|
<q-item-label caption :class="selectedComponent === component.code ? 'text-white' : 'text-grey'">
|
|
{{ component.description }}
|
|
</q-item-label>
|
|
</q-item-section>
|
|
</q-item>
|
|
</q-list>
|
|
</q-card>
|
|
|
|
<!-- Component Info Card -->
|
|
<q-card class="q-mt-md" v-if="currentComponentInfo">
|
|
<q-card-section>
|
|
<div class="text-subtitle2">Component Info</div>
|
|
</q-card-section>
|
|
<q-card-section>
|
|
<div class="text-caption">
|
|
<strong>Code:</strong> {{ currentComponentInfo.code }}
|
|
</div>
|
|
<div class="text-caption">
|
|
<strong>Class:</strong> {{ currentComponentInfo.className }}
|
|
</div>
|
|
<div class="text-caption">
|
|
<strong>Method:</strong> {{ currentComponentInfo.method }}
|
|
</div>
|
|
</q-card-section>
|
|
</q-card>
|
|
</div>
|
|
|
|
<!-- Main Component Area -->
|
|
<div class="col-12 col-md">
|
|
<q-card class="full-height">
|
|
<q-card-section>
|
|
<div class="text-h6">{{ currentComponentInfo?.name || 'Select a Component' }}</div>
|
|
<div class="text-caption text-grey" v-if="currentComponentInfo">
|
|
{{ currentComponentInfo.description }}
|
|
</div>
|
|
</q-card-section>
|
|
|
|
<q-card-section class="q-pa-md">
|
|
<component
|
|
:is="currentComponentComponent"
|
|
v-if="currentComponentComponent"
|
|
/>
|
|
<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>
|
|
</div>
|
|
</div>
|
|
</q-page>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { computed, ref, defineAsyncComponent } from 'vue';
|
|
|
|
interface ComponentInfo {
|
|
code: string;
|
|
name: string;
|
|
description: string;
|
|
icon: string;
|
|
className: string;
|
|
method: string;
|
|
component: ReturnType<typeof defineAsyncComponent>;
|
|
}
|
|
|
|
const selectedComponent = ref<string>('');
|
|
|
|
// Define available components
|
|
const availableComponents: ComponentInfo[] = [
|
|
{
|
|
code: 'calculator',
|
|
name: 'Calculator',
|
|
description: 'Perform mathematical operations on numbers',
|
|
icon: 'mdi-calculator',
|
|
className: 'S8n.Components.Basics.Calculator',
|
|
method: 'Calc',
|
|
component: defineAsyncComponent(() => import('../components_s8n/ComponentCalculator.vue')),
|
|
},
|
|
{
|
|
code: 'httprequest',
|
|
name: 'HTTP Request',
|
|
description: 'Make HTTP requests to any URL',
|
|
icon: 'mdi-web',
|
|
className: 'S8n.Components.Basics.HttpRequest',
|
|
method: 'Execute',
|
|
component: defineAsyncComponent(() => import('../components_s8n/ComponentHttpRequest.vue')),
|
|
},
|
|
];
|
|
|
|
const currentComponentInfo = computed(() => {
|
|
return availableComponents.find(c => c.code === selectedComponent.value);
|
|
});
|
|
|
|
const currentComponentComponent = computed(() => {
|
|
return currentComponentInfo.value?.component;
|
|
});
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.playground-page {
|
|
min-height: calc(100vh - 50px);
|
|
|
|
.full-height {
|
|
min-height: calc(100vh - 100px);
|
|
}
|
|
}
|
|
</style>
|