|
|
|
|
@@ -24,6 +24,7 @@
|
|
|
|
|
:paginatorTemplate="paginatorTemplate"
|
|
|
|
|
:totalRecords="scenario_execution_store.scenariosExecution.length"
|
|
|
|
|
:first="first"
|
|
|
|
|
filterDisplay="menu"
|
|
|
|
|
@page="onPage" :globalFilterFields="['id', 'scenario.name', 'execSharedMap.user_input.selected_project', 'execSharedMap.user_input.selected_application']">
|
|
|
|
|
|
|
|
|
|
<template #header>
|
|
|
|
|
@@ -37,41 +38,132 @@
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<!-- <Column field="id" header="Execution ID"></Column> -->
|
|
|
|
|
<Column field="scenario.name" header="Scenario Name">
|
|
|
|
|
|
|
|
|
|
<Column field="scenario.name" header="Scenario Name" sortable
|
|
|
|
|
style="min-width: 12rem">
|
|
|
|
|
<template #body="slotProps">
|
|
|
|
|
<div class="flex items-center gap-2">
|
|
|
|
|
{{ slotProps.data.scenario.name }}
|
|
|
|
|
{{ slotProps.data.scenario?.name }}
|
|
|
|
|
<i
|
|
|
|
|
class="pi pi-info-circle text-blue-500 cursor-pointer"
|
|
|
|
|
v-tooltip="slotProps.data.scenario.description"
|
|
|
|
|
class="pi pi-info-circle text-violet-600 cursor-pointer"
|
|
|
|
|
v-tooltip="slotProps.data?.scenario?.description || 'No description available'"
|
|
|
|
|
></i>
|
|
|
|
|
<!-- controllare il tooltip -->
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
<template #filter="{ filterModel, filterCallback }">
|
|
|
|
|
<InputText v-model="filterModel.value" type="text" @input="filterCallback()"
|
|
|
|
|
placeholder="Search by File" />
|
|
|
|
|
</template>
|
|
|
|
|
</Column>
|
|
|
|
|
<Column field="execSharedMap.user_input.selected_project" header="Project Input"></Column>
|
|
|
|
|
<Column field="execSharedMap.user_input.selected_application" header="Application Input"></Column>
|
|
|
|
|
<Column header="Start Date">
|
|
|
|
|
<Column field="execSharedMap.user_input.selected_project" header="Project Input" sortable
|
|
|
|
|
style="min-width: 12rem">
|
|
|
|
|
<template #body="slotProps">
|
|
|
|
|
<div class="flex items-center gap-2">
|
|
|
|
|
{{ slotProps.data.execSharedMap?.user_input?.selected_project }}
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
<template #filter="{ filterModel, filterCallback }">
|
|
|
|
|
<InputText v-model="filterModel.value" type="text" @input="filterCallback()"
|
|
|
|
|
placeholder="Search by File" />
|
|
|
|
|
</template>
|
|
|
|
|
</Column>
|
|
|
|
|
<Column field="execSharedMap.user_input.selected_application" header="Application Input" sortable
|
|
|
|
|
style="min-width: 12rem">
|
|
|
|
|
<template #body="slotProps">
|
|
|
|
|
<div class="flex items-center gap-2">
|
|
|
|
|
{{ slotProps.data.execSharedMap?.user_input?.selected_application }}
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
<template #filter="{ filterModel, filterCallback }">
|
|
|
|
|
<InputText v-model="filterModel.value" type="text" @input="filterCallback()"
|
|
|
|
|
placeholder="Search by File" />
|
|
|
|
|
</template>
|
|
|
|
|
</Column>
|
|
|
|
|
<Column field="formattedEndDate"
|
|
|
|
|
filterField="endDate" header="Start Date" sortable
|
|
|
|
|
style="min-width: 12rem">
|
|
|
|
|
<template #body="slotProps">
|
|
|
|
|
<div class="flex items-center gap-2">
|
|
|
|
|
{{ moment(slotProps.data.startDate).format('DD-MM-YYYY HH:mm:ss') }}
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
<template #filter="{ filterModel, filterCallback }">
|
|
|
|
|
<Calendar
|
|
|
|
|
v-model="filterModel.value"
|
|
|
|
|
@input="(value) => {
|
|
|
|
|
filterModel.value = new Date(value); // Converte in oggetto Date
|
|
|
|
|
filterCallback();
|
|
|
|
|
}"
|
|
|
|
|
dateFormat="yy-mm-dd"
|
|
|
|
|
placeholder="Filter by Date"
|
|
|
|
|
/>
|
|
|
|
|
</template>
|
|
|
|
|
</Column>
|
|
|
|
|
<Column header="End Date">
|
|
|
|
|
<Column field="endDate"
|
|
|
|
|
header="End Date" sortable
|
|
|
|
|
style="min-width: 12rem">
|
|
|
|
|
<template #body="slotProps">
|
|
|
|
|
<div class="flex items-center gap-2">
|
|
|
|
|
{{ moment(slotProps.data.endDate).format('DD-MM-YYYY HH:mm:ss') }}
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
<template #filter="{ filterModel, filterCallback }">
|
|
|
|
|
<InputText v-model="filterModel.value" type="text" @input="filterCallback()"
|
|
|
|
|
placeholder="Search by File" />
|
|
|
|
|
</template>
|
|
|
|
|
</Column>
|
|
|
|
|
<Column field="scenario.aiModel.apiProvider" header="Model AI"></Column>
|
|
|
|
|
<Column field="scenario.aiModel.model" header="Version"></Column>
|
|
|
|
|
<Column field="usedTokens" header="Tokens used"></Column>
|
|
|
|
|
<Column header="Output Type">
|
|
|
|
|
<Column field="scenario.aiModel.apiProvider" header="Model AI" sortable
|
|
|
|
|
style="min-width: 12rem">
|
|
|
|
|
<template #body="slotProps">
|
|
|
|
|
{{ slotProps.data.scenario.outputType || 'text' }}
|
|
|
|
|
<div class="flex items-center gap-2">
|
|
|
|
|
{{ slotProps.data.scenario?.aiModel?.apiProvider }}
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
<template #filter="{ filterModel, filterCallback }">
|
|
|
|
|
<InputText v-model="filterModel.value" type="text" @input="filterCallback()"
|
|
|
|
|
placeholder="Search by File" />
|
|
|
|
|
</template>
|
|
|
|
|
</Column>
|
|
|
|
|
<Column field="scenario.aiModel.model" header="Version" sortable
|
|
|
|
|
style="min-width: 12rem">
|
|
|
|
|
<template #body="slotProps">
|
|
|
|
|
<div class="flex items-center gap-2">
|
|
|
|
|
{{ slotProps.data.scenario?.aiModel?.model || 'N/A' }}
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
<template #filter="{ filterModel, filterCallback }">
|
|
|
|
|
<InputText v-model="filterModel.value" type="text" @input="filterCallback()"
|
|
|
|
|
placeholder="Search by File" />
|
|
|
|
|
</template>
|
|
|
|
|
</Column>
|
|
|
|
|
<Column field="usedTokens" header="Tokens used" sortable
|
|
|
|
|
style="min-width: 12rem">
|
|
|
|
|
<template #body="slotProps">
|
|
|
|
|
<div class="flex items-center gap-2">
|
|
|
|
|
{{ slotProps.data.usedTokens || 'N/A' }}
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
<template #filter="{ filterModel, filterCallback }">
|
|
|
|
|
<InputText v-model="filterModel.value" type="text" @input="filterCallback()"
|
|
|
|
|
placeholder="Search by File" />
|
|
|
|
|
</template>
|
|
|
|
|
</Column>
|
|
|
|
|
<Column filterField="outputTypeFilter" header="Output Type" sortable
|
|
|
|
|
style="min-width: 12rem">
|
|
|
|
|
<template #body="slotProps">
|
|
|
|
|
<div class="flex items-center gap-2">
|
|
|
|
|
{{ slotProps.data.scenario?.outputType || 'text' }}
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
<template #filter="{ filterModel, filterCallback }">
|
|
|
|
|
<InputText v-model="filterModel.value" type="text" @input="filterCallback()"
|
|
|
|
|
placeholder="Search by File" />
|
|
|
|
|
</template>
|
|
|
|
|
</Column>
|
|
|
|
|
<Column field="rating" header="Rating">
|
|
|
|
|
<template #body="slotProps">
|
|
|
|
|
<Rating :value="slotProps.data.rating" :stars="5" readonly cancel="false" />
|
|
|
|
|
<Rating :modelValue="slotProps.data.rating" :stars="5" @change="updateRating(slotProps.data, $event)" />
|
|
|
|
|
</template>
|
|
|
|
|
</Column>
|
|
|
|
|
<Column field="id" :style="{ position: 'sticky', right: '0', zIndex: '1', background: '#f3f3f3'}">
|
|
|
|
|
@@ -97,13 +189,15 @@
|
|
|
|
|
|
|
|
|
|
<script setup>
|
|
|
|
|
|
|
|
|
|
import { FilterMatchMode } from '@primevue/core/api';
|
|
|
|
|
import { FilterMatchMode, FilterOperator } from '@primevue/core/api';
|
|
|
|
|
import 'md-editor-v3/lib/style.css';
|
|
|
|
|
import moment from 'moment';
|
|
|
|
|
import ProgressSpinner from 'primevue/progressspinner';
|
|
|
|
|
import { useToast } from 'primevue/usetoast';
|
|
|
|
|
import { onMounted, ref } from 'vue';
|
|
|
|
|
import { useRoute, useRouter } from 'vue-router';
|
|
|
|
|
import { ScenarioService } from '../../service/ScenarioService.js';
|
|
|
|
|
import { ScenarioExecutionStore } from '../../stores/ScenarioExecutionStore.js';
|
|
|
|
|
import moment from 'moment';
|
|
|
|
|
|
|
|
|
|
const first = ref(0);
|
|
|
|
|
const router = useRouter();
|
|
|
|
|
@@ -121,19 +215,95 @@ const debug_modal = ref(false);
|
|
|
|
|
const execution_id = ref("");
|
|
|
|
|
const listScenarios = ref([]);
|
|
|
|
|
const scenario_execution_store = ScenarioExecutionStore();
|
|
|
|
|
const toast = useToast();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const filters = ref({
|
|
|
|
|
global: { value: null, matchMode: FilterMatchMode.CONTAINS },
|
|
|
|
|
'id': { value: null, matchMode: FilterMatchMode.CONTAINS },
|
|
|
|
|
'scenario.name': { value: null, matchMode: FilterMatchMode.CONTAINS },
|
|
|
|
|
'execSharedMap.user_input.selected_project': { value: null, matchMode: FilterMatchMode.CONTAINS },
|
|
|
|
|
'execSharedMap.user_input.selected_application': { value: null, matchMode: FilterMatchMode.CONTAINS }
|
|
|
|
|
'scenario.name': {
|
|
|
|
|
operator: FilterOperator.AND,
|
|
|
|
|
constraints: [{ value: null, matchMode: FilterMatchMode.CONTAINS }]
|
|
|
|
|
},
|
|
|
|
|
'execSharedMap.user_input.selected_project': {
|
|
|
|
|
operator: FilterOperator.AND,
|
|
|
|
|
constraints: [{value: null, matchMode: FilterMatchMode.CONTAINS }]
|
|
|
|
|
},
|
|
|
|
|
'execSharedMap.user_input.selected_application': {
|
|
|
|
|
operator: FilterOperator.AND,
|
|
|
|
|
constraints: [{
|
|
|
|
|
value: null, matchMode: FilterMatchMode.CONTAINS
|
|
|
|
|
}]
|
|
|
|
|
},
|
|
|
|
|
'scenario.aiModel.apiProvider': {
|
|
|
|
|
operator: FilterOperator.AND,
|
|
|
|
|
constraints: [{ value: null, matchMode: FilterMatchMode.CONTAINS }]
|
|
|
|
|
},
|
|
|
|
|
'scenario.aiModel.model': {
|
|
|
|
|
operator: FilterOperator.AND,
|
|
|
|
|
constraints: [{ value: null, matchMode: FilterMatchMode.CONTAINS }]
|
|
|
|
|
},
|
|
|
|
|
'usedTokens': {
|
|
|
|
|
operator: FilterOperator.AND,
|
|
|
|
|
constraints: [{ value: null, matchMode: FilterMatchMode.CONTAINS }]
|
|
|
|
|
},
|
|
|
|
|
outputTypeFilter: {
|
|
|
|
|
operator: FilterOperator.AND,
|
|
|
|
|
constraints: [{ value: null, matchMode: FilterMatchMode.CONTAINS }]
|
|
|
|
|
},
|
|
|
|
|
'startDate': {
|
|
|
|
|
operator: FilterOperator.AND,
|
|
|
|
|
constraints: [{ value: null, matchMode: FilterMatchMode.DATE_IS }]
|
|
|
|
|
},
|
|
|
|
|
'endDate': {
|
|
|
|
|
operator: FilterOperator.AND,
|
|
|
|
|
constraints: [{ value: null, matchMode: FilterMatchMode.DATE_IS }]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
onMounted(() => {
|
|
|
|
|
scenario_execution_store.fetchScenariosExecution()
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
async function updateRating(rowData, newRating) {
|
|
|
|
|
|
|
|
|
|
// Aggiorna il rating nell'oggetto prima di inviarlo
|
|
|
|
|
rowData.rating = newRating.value;
|
|
|
|
|
console.log('data rating:', rowData);
|
|
|
|
|
// Mostra un loader se necessario
|
|
|
|
|
loading_data.value = true;
|
|
|
|
|
ScenarioService.updateScenarioExecRating(rowData).then((response) => {
|
|
|
|
|
|
|
|
|
|
console.log('response:', response);
|
|
|
|
|
if (response.data === "OK") {
|
|
|
|
|
console.log('Rating aggiornato con successo:', response.data);
|
|
|
|
|
scenario_execution_store.fetchScenariosExecution()
|
|
|
|
|
toast.add({
|
|
|
|
|
severity: 'success', // Tipo di notifica (successo)
|
|
|
|
|
summary: 'Successo', // Titolo della notifica
|
|
|
|
|
detail: 'Rating updated with success.', // Messaggio dettagliato
|
|
|
|
|
life: 3000 // Durata della notifica in millisecondi
|
|
|
|
|
});
|
|
|
|
|
} else {
|
|
|
|
|
console.error('Errore nell\'aggiornamento del rating', response.data);
|
|
|
|
|
toast.add({
|
|
|
|
|
severity: 'error', // Tipo di notifica (errore)
|
|
|
|
|
summary: 'Errore', // Titolo della notifica
|
|
|
|
|
detail: 'Error updating rating. Try later.', // Messaggio dettagliato
|
|
|
|
|
life: 3000 // Durata della notifica in millisecondi
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}).catch((error) => {
|
|
|
|
|
console.error('Errore durante la chiamata al backend:', error);
|
|
|
|
|
}).finally(() => {
|
|
|
|
|
loading_data.value = false;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const goToScenarioExec = (execScenarioItem) => {
|
|
|
|
|
console.log(execScenarioItem);
|
|
|
|
|
|