Files
S8n.MySolutionTemplate/QuasarFrontend/src/pages/PlaygroundPage.vue
2026-02-10 19:12:31 +03:00

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>