feat: Add Execution Response Section component and related composables for file handling and error management
- Implemented ExecutionResponseSection.vue to display execution results and handle file downloads. - Created useBase64Decoder.js for base64 decoding utilities. - Developed useChatToggle.js for managing chat panel state. - Added useErrorHandler.js for standardized error handling with toast notifications. - Introduced useFileDownload.js for various file download operations. - Created useFileProcessing.js for processing files, including zip extraction and content display. - Implemented usePolling.js for polling backend API for execution status. - Added useScenarioRating.js for managing scenario execution ratings. - Developed CSV export utilities in csvExport.js for generating and downloading CSV files. - Created formDataProcessor.js for processing and validating multiselect form data. - Implemented inputComponents.js for mapping input types to PrimeVue components. - Enhanced ScenarioExecHistory.vue to integrate new components and functionalities.
This commit is contained in:
@@ -335,143 +335,612 @@ const chatDisabled = () => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<!-- Header Section -->
|
||||
<div class="flex items-center justify-between p-1">
|
||||
<h1>{{ scenario.name }}</h1>
|
||||
</div>
|
||||
<div class="flex items-center justify-between p-1">
|
||||
<h2>{{ scenario.description }}</h2>
|
||||
</div>
|
||||
|
||||
<!-- Chat Return Button -->
|
||||
<div v-if="data_loaded && chat_enabled" class="flex mt-6 justify-center">
|
||||
<div class="card flex flex-col gap-4 w-full items-center">
|
||||
<Button label="Return to scenario" @click="chatDisabled" size="large" iconPos="right" icon="pi pi-backward" class="w-auto"></Button>
|
||||
<div class="scenario-exec-container">
|
||||
<!-- Enhanced Header Section -->
|
||||
<div v-if="scenario.name" class="header-section">
|
||||
<div class="header-content">
|
||||
<div class="header-icon">
|
||||
<i class="pi pi-bolt" style="font-size: 1.36rem"></i>
|
||||
</div>
|
||||
<div class="header-text">
|
||||
<h1 class="page-title">{{ scenario.name }}</h1>
|
||||
<p class="page-subtitle">{{ scenario.description }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Scenario Form -->
|
||||
<div v-else class="flex mt-2">
|
||||
<div class="card flex flex-col w-full">
|
||||
<MarkdownViewer :class="['markdown-content', 'ml-[-20px]']" :modelValue="scenario.hint" />
|
||||
<!-- Chat Return Button -->
|
||||
<div v-if="data_loaded && chat_enabled" class="chat-return-section">
|
||||
<div class="return-card">
|
||||
<Button label="Return to Scenario" @click="chatDisabled" size="large" iconPos="left" icon="pi pi-arrow-left" class="return-button" severity="secondary"></Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<template v-if="scenario.inputs">
|
||||
<div class="grid grid-cols-2 md:grid-cols-1">
|
||||
<div v-for="input in scenario.inputs" :key="input.name">
|
||||
<!-- Single File Upload -->
|
||||
<div v-if="input.type === 'singlefile' || input.type === 'singlefile_acceptall'">
|
||||
<ScenarioFileUpload
|
||||
:input-name="input.name"
|
||||
:label="input.label"
|
||||
tooltip-text="Upload one document from the suggested types. Mandatory if you want to execute scenario."
|
||||
:upload-url="uploadUrlPR"
|
||||
:is-multiple="false"
|
||||
:accepted-formats="acceptedFormats"
|
||||
:folder-name="folderName"
|
||||
v-model:uploaded-files="uploadedFiles"
|
||||
@upload="handleFileUpload"
|
||||
@remove="handleFileRemove"
|
||||
/>
|
||||
<!-- Enhanced Scenario Form -->
|
||||
<div v-else class="form-section">
|
||||
<div class="form-card">
|
||||
<!-- Hint Section -->
|
||||
<div v-if="scenario.hint" class="hint-section">
|
||||
<div class="hint-header">
|
||||
<i class="pi pi-info-circle"></i>
|
||||
<span>Scenario Information</span>
|
||||
</div>
|
||||
<MarkdownViewer class="hint-content" :modelValue="scenario.hint" />
|
||||
</div>
|
||||
|
||||
<!-- Inputs Section -->
|
||||
<template v-if="scenario.inputs">
|
||||
<div class="inputs-section">
|
||||
<div class="inputs-grid">
|
||||
<div v-for="input in scenario.inputs" :key="input.name" class="input-item">
|
||||
<!-- Single File Upload -->
|
||||
<div v-if="input.type === 'singlefile' || input.type === 'singlefile_acceptall'" class="input-group">
|
||||
<ScenarioFileUpload
|
||||
:input-name="input.name"
|
||||
:label="input.label"
|
||||
tooltip-text="Upload one document from the suggested types. Mandatory if you want to execute scenario."
|
||||
:upload-url="uploadUrlPR"
|
||||
:is-multiple="false"
|
||||
:accepted-formats="acceptedFormats"
|
||||
:folder-name="folderName"
|
||||
v-model:uploaded-files="uploadedFiles"
|
||||
@upload="handleFileUpload"
|
||||
@remove="handleFileRemove"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- Multi File Upload -->
|
||||
<div v-else-if="input.type === 'multifile'" class="input-group">
|
||||
<ScenarioFileUpload
|
||||
:input-name="input.name"
|
||||
:label="input.label"
|
||||
tooltip-text="Upload others documents of .docx, .msg, .text type. Optional."
|
||||
:upload-url="uploadUrlOther"
|
||||
:is-multiple="true"
|
||||
accepted-formats=".msg,.txt,.docx"
|
||||
:folder-name="folderName"
|
||||
v-model:uploaded-files="uploadedFiles"
|
||||
@upload="handleFileUpload"
|
||||
@remove="handleFileRemove"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- Multi Select with Dynamic Picker -->
|
||||
<div v-else-if="input.type === 'multiselect'" class="input-group">
|
||||
<DynamicPicker
|
||||
v-model="formData[input.name]"
|
||||
:input-name="input.name"
|
||||
:label="input.label"
|
||||
:data-source="input.dataSource || 'videoGroups'"
|
||||
:options="getOptionsForInput(input)"
|
||||
:disabled="loadingStore.exectuion_loading"
|
||||
:loading="loadingOptionsFor[input.dataSource] || false"
|
||||
:show-status="input.dataSource === 'ksDocuments'"
|
||||
no-margin
|
||||
@change="onDynamicPickerChange(input.name, $event)"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- Other Input Types -->
|
||||
<div v-else class="input-group">
|
||||
<label :for="input.name" class="input-label">
|
||||
{{ input.label }}
|
||||
</label>
|
||||
<div class="input-wrapper">
|
||||
<component :is="getInputComponent(input.type)" :id="input.name" v-model="formData[input.name]" :options="input.options" class="full-width-input" :disabled="loadingStore.exectuion_loading" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Multi File Upload -->
|
||||
<div v-else-if="input.type === 'multifile'">
|
||||
<ScenarioFileUpload
|
||||
:input-name="input.name"
|
||||
:label="input.label"
|
||||
tooltip-text="Upload others documents of .docx, .msg, .text type. Optional."
|
||||
:upload-url="uploadUrlOther"
|
||||
:is-multiple="true"
|
||||
accepted-formats=".msg,.txt,.docx"
|
||||
:folder-name="folderName"
|
||||
v-model:uploaded-files="uploadedFiles"
|
||||
@upload="handleFileUpload"
|
||||
@remove="handleFileRemove"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- Multi Select with Dynamic Picker -->
|
||||
<div v-else-if="input.type === 'multiselect'" class="mt-4">
|
||||
<DynamicPicker
|
||||
v-model="formData[input.name]"
|
||||
:input-name="input.name"
|
||||
:label="input.label"
|
||||
:data-source="input.dataSource || 'videoGroups'"
|
||||
:options="getOptionsForInput(input)"
|
||||
:disabled="loadingStore.exectuion_loading"
|
||||
:loading="loadingOptionsFor[input.dataSource] || false"
|
||||
:show-status="input.dataSource === 'ksDocuments'"
|
||||
no-margin
|
||||
@change="onDynamicPickerChange(input.name, $event)"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- Other Input Types -->
|
||||
<div v-else>
|
||||
<label :for="input.name"
|
||||
><b>{{ input.label }}</b></label
|
||||
>
|
||||
<div class="input-wrapper">
|
||||
<component :is="getInputComponent(input.type)" :id="input.name" v-model="formData[input.name]" :options="input.options" class="full-width-input" :disabled="loadingStore.exectuion_loading" />
|
||||
<!-- Enhanced Action Buttons -->
|
||||
<div class="action-buttons">
|
||||
<div v-if="data_loaded && scenario.chatEnabled && !chat_enabled" class="button-group">
|
||||
<Button
|
||||
:disabled="loadingStore.exectuion_loading || !isInputFilled"
|
||||
label="Execute Scenario"
|
||||
@click="execScenario"
|
||||
size="large"
|
||||
iconPos="right"
|
||||
icon="pi pi-play-circle"
|
||||
class="execute-button"
|
||||
severity="success"
|
||||
></Button>
|
||||
<Button label="Open Chat" @click="chatEnabled" size="large" iconPos="right" icon="pi pi-comments" severity="help"></Button>
|
||||
</div>
|
||||
<div v-else class="button-group">
|
||||
<Button
|
||||
:disabled="loadingStore.exectuion_loading || !isInputFilled"
|
||||
label="Execute Scenario"
|
||||
@click="execScenario"
|
||||
size="large"
|
||||
iconPos="right"
|
||||
icon="pi pi-play-circle"
|
||||
class="execute-button"
|
||||
severity="success"
|
||||
></Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Action Buttons -->
|
||||
<div v-if="data_loaded && scenario.chatEnabled" class="flex justify-center">
|
||||
<div v-if="!chat_enabled" class="flex gap-4 mt-6">
|
||||
<Button :disabled="loadingStore.exectuion_loading || !isInputFilled" label="Execute" @click="execScenario" size="large" iconPos="right" icon="pi pi-cog"></Button>
|
||||
<Button label="Open Chat" @click="chatEnabled" size="large" iconPos="right" icon="pi pi-comments"></Button>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="flex justify-center mt-6">
|
||||
<Button :disabled="loadingStore.exectuion_loading || !isInputFilled" label="Execute" @click="execScenario" size="large" iconPos="right" icon="pi pi-cog"></Button>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Execution Timer -->
|
||||
<ExecutionTimer :is-loading="loading_data" :message="scenario_response_message" />
|
||||
|
||||
<!-- Workflow Response Panel -->
|
||||
<div v-if="data_loaded && !chat_enabled">
|
||||
<WorkflowResponsePanel ref="responsePanel" :scenario="scenario" :scenario-output="scenario_output" :exec-id="exec_id" :error-message="error_message" :errored-execution="errored_execution" />
|
||||
</div>
|
||||
|
||||
<!-- Chat Panel -->
|
||||
<div v-if="data_loaded && chat_enabled" class="mt-4">
|
||||
<Panel class="mt-6">
|
||||
<template #header>
|
||||
<div class="flex items-center gap-2 mt-2">
|
||||
<span class="font-bold">Chat with WizardAI</span>
|
||||
</div>
|
||||
</template>
|
||||
<div class="card flex flex-col gap-4 w-full">
|
||||
<ChatClient :scenarioExecutionId="exec_id" />
|
||||
</template>
|
||||
</div>
|
||||
</Panel>
|
||||
</div>
|
||||
|
||||
<!-- Execution Timer -->
|
||||
<div class="timer-section">
|
||||
<ExecutionTimer :is-loading="loading_data" :message="scenario_response_message" />
|
||||
</div>
|
||||
|
||||
<!-- Workflow Response Panel -->
|
||||
<div v-if="data_loaded && !chat_enabled" class="response-section">
|
||||
<WorkflowResponsePanel ref="responsePanel" :scenario="scenario" :scenario-output="scenario_output" :exec-id="exec_id" :error-message="error_message" :errored-execution="errored_execution" />
|
||||
</div>
|
||||
|
||||
<!-- Enhanced Chat Panel -->
|
||||
<div v-if="data_loaded && chat_enabled" class="chat-section">
|
||||
<Panel class="chat-panel">
|
||||
<template #header>
|
||||
<div class="chat-header">
|
||||
<i class="pi pi-comments chat-icon"></i>
|
||||
<span class="chat-title">Chat with WizardAI</span>
|
||||
</div>
|
||||
</template>
|
||||
<div class="chat-content">
|
||||
<ChatClient :scenarioExecutionId="exec_id" />
|
||||
</div>
|
||||
</Panel>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.input-wrapper {
|
||||
/* Container */
|
||||
.scenario-exec-container {
|
||||
max-width: 1400px;
|
||||
margin: 0 auto;
|
||||
padding: 1.5rem;
|
||||
}
|
||||
|
||||
/* Enhanced Header Section */
|
||||
.header-section {
|
||||
margin-bottom: 2rem;
|
||||
animation: fadeInDown 0.5s ease-out;
|
||||
}
|
||||
|
||||
.header-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5em;
|
||||
margin-top: 10px;
|
||||
gap: 1.2rem;
|
||||
padding: 1.36rem;
|
||||
background: linear-gradient(135deg, #a100ff 0%, #7b00cc 100%);
|
||||
border-radius: 16px;
|
||||
box-shadow: 0 10px 30px rgba(161, 0, 255, 0.3);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.full-width-input {
|
||||
width: 100%;
|
||||
.header-icon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
background: rgba(255, 255, 255, 0.2);
|
||||
border-radius: 50%;
|
||||
backdrop-filter: blur(10px);
|
||||
}
|
||||
|
||||
.markdown-content {
|
||||
.header-text {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.page-title {
|
||||
font-size: 1.8rem !important;
|
||||
font-weight: 700 !important;
|
||||
margin: 0 0 0.5rem 0 !important;
|
||||
color: white !important;
|
||||
}
|
||||
|
||||
.page-subtitle {
|
||||
font-size: 1.1rem;
|
||||
margin: 0;
|
||||
opacity: 0.95;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
/* Chat Return Section */
|
||||
.chat-return-section {
|
||||
margin-bottom: 2rem;
|
||||
animation: fadeIn 0.5s ease-out;
|
||||
}
|
||||
|
||||
.return-card {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
padding: 2rem;
|
||||
background: white;
|
||||
border-radius: 16px;
|
||||
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
|
||||
}
|
||||
|
||||
.return-card :deep(button) {
|
||||
min-width: 250px;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.return-button {
|
||||
min-width: 250px;
|
||||
}
|
||||
|
||||
/* Form Section */
|
||||
.form-section {
|
||||
animation: fadeIn 0.5s ease-out;
|
||||
}
|
||||
|
||||
.form-card {
|
||||
background: white;
|
||||
border-radius: 16px;
|
||||
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* Hint Section */
|
||||
.hint-section {
|
||||
padding: 2rem;
|
||||
background: linear-gradient(135deg, rgba(161, 0, 255, 0.1) 0%, rgba(123, 0, 204, 0.1) 100%);
|
||||
border-bottom: 2px solid #a100ff;
|
||||
}
|
||||
|
||||
.hint-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.75rem;
|
||||
margin-bottom: 1rem;
|
||||
font-size: 1.1rem;
|
||||
font-weight: 600;
|
||||
color: #a100ff;
|
||||
}
|
||||
|
||||
.hint-header i {
|
||||
font-size: 1.3rem;
|
||||
}
|
||||
|
||||
.hint-content {
|
||||
word-wrap: break-word;
|
||||
overflow-wrap: break-word;
|
||||
max-width: 100%;
|
||||
overflow-x: auto;
|
||||
background-color: #f5f5f5;
|
||||
background: transparent !important;
|
||||
}
|
||||
|
||||
.hint-content :deep(*) {
|
||||
background: transparent !important;
|
||||
background-color: transparent !important;
|
||||
}
|
||||
|
||||
.hint-content :deep(.markdown-content) {
|
||||
background: transparent !important;
|
||||
background-color: transparent !important;
|
||||
}
|
||||
|
||||
.hint-content :deep(p),
|
||||
.hint-content :deep(div),
|
||||
.hint-content :deep(span),
|
||||
.hint-content :deep(pre),
|
||||
.hint-content :deep(code) {
|
||||
background: transparent !important;
|
||||
background-color: transparent !important;
|
||||
}
|
||||
|
||||
/* Inputs Section */
|
||||
.inputs-section {
|
||||
padding: 2rem;
|
||||
}
|
||||
|
||||
.inputs-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(450px, 1fr));
|
||||
gap: 1.5rem;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.inputs-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
.input-item {
|
||||
background: #f8f9fa;
|
||||
padding: 1.5rem;
|
||||
border-radius: 12px;
|
||||
border: 1px solid #e2e8f0;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.input-item:hover {
|
||||
transform: translateY(-3px);
|
||||
box-shadow: 0 6px 16px rgba(161, 0, 255, 0.15);
|
||||
border-color: #a100ff;
|
||||
}
|
||||
|
||||
.input-group {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.75rem;
|
||||
}
|
||||
|
||||
/* File Upload Specific Styling */
|
||||
.input-item :deep(.p-fileupload) {
|
||||
border: 2px dashed #cbd5e0;
|
||||
border-radius: 8px;
|
||||
background: white;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.input-item :deep(.p-fileupload:hover) {
|
||||
border-color: #a100ff;
|
||||
background: #f7fafc;
|
||||
}
|
||||
|
||||
.input-item :deep(.p-fileupload-buttonbar) {
|
||||
background: linear-gradient(135deg, #a100ff15 0%, #7b00cc15 100%);
|
||||
border-bottom: 1px solid #e2e8f0;
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.input-item :deep(.p-fileupload-content) {
|
||||
padding: 1.5rem;
|
||||
background: white;
|
||||
}
|
||||
|
||||
/* Upload area styling */
|
||||
.input-item :deep(.p-fileupload-choose) {
|
||||
background: #a100ff;
|
||||
border-color: #a100ff;
|
||||
}
|
||||
|
||||
.input-item :deep(.p-fileupload-choose:hover) {
|
||||
background: #5568d3;
|
||||
border-color: #5568d3;
|
||||
}
|
||||
|
||||
/* DynamicPicker Component Styling */
|
||||
.input-item :deep(.dynamic-picker-label) {
|
||||
font-weight: 600;
|
||||
font-size: 1rem;
|
||||
color: #2d3748;
|
||||
margin-bottom: 0.5rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.input-item :deep(.dynamic-picker-label::before) {
|
||||
content: '•';
|
||||
color: #a100ff;
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
|
||||
.input-label {
|
||||
font-weight: 600;
|
||||
font-size: 1rem;
|
||||
color: #2d3748;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.input-label::before {
|
||||
content: '•';
|
||||
color: #a100ff;
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
|
||||
.input-wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.full-width-input {
|
||||
width: 100%;
|
||||
transition: all 0.3s ease;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.full-width-input:focus {
|
||||
transform: scale(1.01);
|
||||
box-shadow: 0 0 0 3px rgba(161, 0, 255, 0.1);
|
||||
}
|
||||
|
||||
/* Style for all input fields within input-group */
|
||||
.input-group :deep(.p-inputtext),
|
||||
.input-group :deep(.p-textarea),
|
||||
.input-group :deep(.p-dropdown),
|
||||
.input-group :deep(.p-multiselect) {
|
||||
background: white;
|
||||
border: 1px solid #cbd5e0;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.input-group :deep(.p-inputtext:hover),
|
||||
.input-group :deep(.p-textarea:hover),
|
||||
.input-group :deep(.p-dropdown:hover),
|
||||
.input-group :deep(.p-multiselect:hover) {
|
||||
border-color: #a100ff;
|
||||
}
|
||||
|
||||
.input-group :deep(.p-inputtext:focus),
|
||||
.input-group :deep(.p-textarea:focus),
|
||||
.input-group :deep(.p-dropdown:focus),
|
||||
.input-group :deep(.p-multiselect:focus) {
|
||||
border-color: #a100ff;
|
||||
box-shadow: 0 0 0 3px rgba(161, 0, 255, 0.1);
|
||||
}
|
||||
|
||||
/* Action Buttons */
|
||||
.action-buttons {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
padding-top: 2rem;
|
||||
border-top: 2px solid #e2e8f0;
|
||||
}
|
||||
|
||||
.button-group {
|
||||
display: flex;
|
||||
gap: 1rem;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.button-group :deep(button) {
|
||||
min-width: 200px;
|
||||
font-weight: 600;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.execute-button {
|
||||
min-width: 200px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* Timer Section */
|
||||
.timer-section {
|
||||
margin: 2rem 0;
|
||||
}
|
||||
|
||||
/* Response Section */
|
||||
.response-section {
|
||||
margin-top: 2rem;
|
||||
animation: fadeInUp 0.5s ease-out;
|
||||
}
|
||||
|
||||
.response-section :deep(.card),
|
||||
.response-section :deep(.p-panel) {
|
||||
background: white;
|
||||
border-radius: 16px;
|
||||
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.response-section :deep(.p-panel-header) {
|
||||
background: linear-gradient(135deg, #a100ff15 0%, #7b00cc15 100%);
|
||||
border-bottom: 2px solid #a100ff;
|
||||
padding: 1.5rem 2rem;
|
||||
}
|
||||
|
||||
/* Chat Section */
|
||||
.chat-section {
|
||||
margin-top: 2rem;
|
||||
animation: fadeInUp 0.5s ease-out;
|
||||
}
|
||||
|
||||
.chat-panel {
|
||||
border-radius: 16px;
|
||||
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
|
||||
overflow: hidden;
|
||||
background: white;
|
||||
}
|
||||
|
||||
.chat-panel :deep(.p-panel-header) {
|
||||
background: linear-gradient(135deg, #a100ff15 0%, #7b00cc15 100%);
|
||||
border-bottom: 2px solid #a100ff;
|
||||
padding: 1.5rem 2rem;
|
||||
}
|
||||
|
||||
.chat-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.75rem;
|
||||
font-size: 1.2rem;
|
||||
font-weight: 600;
|
||||
color: #a100ff;
|
||||
}
|
||||
|
||||
.chat-icon {
|
||||
font-size: 1.4rem;
|
||||
}
|
||||
|
||||
.chat-title {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.chat-content {
|
||||
padding: 1.5rem;
|
||||
}
|
||||
|
||||
/* Animations */
|
||||
@keyframes fadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(10px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes fadeInDown {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(-20px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes fadeInUp {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(20px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
/* Responsive Design */
|
||||
@media (max-width: 768px) {
|
||||
.scenario-exec-container {
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.header-content {
|
||||
flex-direction: column;
|
||||
text-align: center;
|
||||
padding: 1.5rem;
|
||||
}
|
||||
|
||||
.scenario-title {
|
||||
font-size: 1.4rem !important;
|
||||
}
|
||||
|
||||
.scenario-description {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.inputs-section {
|
||||
padding: 1.5rem;
|
||||
}
|
||||
|
||||
.button-group {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.button-group button {
|
||||
flex: 1;
|
||||
min-width: auto;
|
||||
}
|
||||
}
|
||||
|
||||
/* Loading State */
|
||||
.full-width-input:disabled {
|
||||
opacity: 0.6;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user