Create document picklist and refactor axios call
This commit is contained in:
228
src/components/DynamicPicker.vue
Normal file
228
src/components/DynamicPicker.vue
Normal file
@@ -0,0 +1,228 @@
|
|||||||
|
<template>
|
||||||
|
<div class="dynamic-picker" :class="{ 'mt-4': !noMargin }">
|
||||||
|
<label :for="inputName" v-if="label">
|
||||||
|
<b>{{ label }}</b>
|
||||||
|
</label>
|
||||||
|
<div class="input-wrapper">
|
||||||
|
<!-- Video Groups MultiSelect -->
|
||||||
|
<MultiSelect
|
||||||
|
v-if="dataSource === 'videoGroups'"
|
||||||
|
v-model="selectedValue"
|
||||||
|
:options="options"
|
||||||
|
|
||||||
|
:filter="true"
|
||||||
|
:placeholder="placeholder || 'Select VideoGroups'"
|
||||||
|
:disabled="disabled"
|
||||||
|
:loading="loading"
|
||||||
|
class="w-full md:w-80"
|
||||||
|
@change="onSelectionChange"
|
||||||
|
>
|
||||||
|
<template #option="slotProps">
|
||||||
|
<div class="flex align-items-center">
|
||||||
|
<i class="pi pi-video mr-2"></i>
|
||||||
|
<div>
|
||||||
|
<div>{{ slotProps.option.name }}</div>
|
||||||
|
<small class="text-muted" v-if="slotProps.option.description">
|
||||||
|
{{ slotProps.option.description }}
|
||||||
|
</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</MultiSelect>
|
||||||
|
|
||||||
|
<!-- KS Documents MultiSelect -->
|
||||||
|
<MultiSelect
|
||||||
|
v-else-if="dataSource === 'ksDocuments'"
|
||||||
|
v-model="selectedValue"
|
||||||
|
:options="options"
|
||||||
|
|
||||||
|
:filter="true"
|
||||||
|
:placeholder="placeholder || 'Select Documents'"
|
||||||
|
:disabled="disabled"
|
||||||
|
:loading="loading"
|
||||||
|
class="w-full md:w-80"
|
||||||
|
@change="onSelectionChange"
|
||||||
|
>
|
||||||
|
<template #option="slotProps">
|
||||||
|
<div class="flex align-items-center">
|
||||||
|
<i :class="getFileIcon(slotProps.option)" class="mr-2"></i>
|
||||||
|
<div>
|
||||||
|
<div>{{ slotProps.option.fileName }}</div>
|
||||||
|
<small class="text-muted" v-if="slotProps.option.description">
|
||||||
|
{{ slotProps.option.description }}
|
||||||
|
</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</MultiSelect>
|
||||||
|
|
||||||
|
<!-- Dropdown per selezione singola -->
|
||||||
|
<Dropdown
|
||||||
|
v-else-if="multiple === false"
|
||||||
|
v-model="selectedValue"
|
||||||
|
:options="options"
|
||||||
|
|
||||||
|
:filter="true"
|
||||||
|
:placeholder="placeholder || 'Select an option'"
|
||||||
|
:disabled="disabled"
|
||||||
|
:loading="loading"
|
||||||
|
class="w-full md:w-80"
|
||||||
|
@change="onSelectionChange"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<!-- MultiSelect generico per altri tipi -->
|
||||||
|
<MultiSelect
|
||||||
|
v-else
|
||||||
|
v-model="selectedValue"
|
||||||
|
:options="options"
|
||||||
|
|
||||||
|
:filter="true"
|
||||||
|
:placeholder="placeholder || 'Select options'"
|
||||||
|
:disabled="disabled"
|
||||||
|
:loading="loading"
|
||||||
|
class="w-full md:w-80"
|
||||||
|
@change="onSelectionChange"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Loading indicator -->
|
||||||
|
<div v-if="loading" class="text-sm text-gray-500 mt-1">
|
||||||
|
<i class="pi pi-spin pi-spinner mr-1"></i>
|
||||||
|
Loading options...
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Error message -->
|
||||||
|
<div v-if="error" class="text-red-500 text-sm mt-1">
|
||||||
|
<i class="pi pi-exclamation-triangle mr-1"></i>
|
||||||
|
{{ error }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Info message -->
|
||||||
|
<div v-if="options.length === 0 && !loading && !error" class="text-gray-500 text-sm mt-1">
|
||||||
|
<i class="pi pi-info-circle mr-1"></i>
|
||||||
|
No options available
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import Dropdown from 'primevue/dropdown';
|
||||||
|
import MultiSelect from 'primevue/multiselect';
|
||||||
|
import { computed } from 'vue';
|
||||||
|
|
||||||
|
// Props
|
||||||
|
const props = defineProps({
|
||||||
|
modelValue: {
|
||||||
|
type: [Array, Object, String, Number],
|
||||||
|
default: null
|
||||||
|
},
|
||||||
|
inputName: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
label: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
placeholder: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
dataSource: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
type: Array,
|
||||||
|
default: () => []
|
||||||
|
},
|
||||||
|
disabled: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
loading: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
error: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
multiple: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
showStatus: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
noMargin: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Emits
|
||||||
|
const emit = defineEmits(['update:modelValue', 'change']);
|
||||||
|
|
||||||
|
// Computed
|
||||||
|
const selectedValue = computed({
|
||||||
|
get() {
|
||||||
|
return props.modelValue;
|
||||||
|
},
|
||||||
|
set(value) {
|
||||||
|
emit('update:modelValue', value);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const getFileIcon = (document) => {
|
||||||
|
if (!document) return 'pi pi-file';
|
||||||
|
|
||||||
|
const fileName = document.fileName || document.name || '';
|
||||||
|
const extension = fileName.toLowerCase().split('.').pop();
|
||||||
|
|
||||||
|
switch (extension) {
|
||||||
|
case 'pdf':
|
||||||
|
return 'pi pi-file-pdf text-red-500';
|
||||||
|
case 'doc':
|
||||||
|
return 'pi pi-file-word text-blue-500';
|
||||||
|
case 'docx':
|
||||||
|
return 'pi pi-file-word text-blue-500';
|
||||||
|
case 'xls':
|
||||||
|
return 'pi pi-file-excel text-green-500';
|
||||||
|
case 'xlsx':
|
||||||
|
return 'pi pi-file-excel text-green-500';
|
||||||
|
case 'txt':
|
||||||
|
return 'pi pi-file text-gray-500';
|
||||||
|
case 'ppt':
|
||||||
|
return 'pi pi-file text-red-500';
|
||||||
|
case 'pptx':
|
||||||
|
return 'pi pi-file text-red-500';
|
||||||
|
case 'json':
|
||||||
|
return 'pi pi-file text-orange-500';
|
||||||
|
case 'gif':
|
||||||
|
return 'pi pi-image text-purple-500';
|
||||||
|
case 'rar':
|
||||||
|
return 'pi pi-file-archive text-yellow-500';
|
||||||
|
default:
|
||||||
|
return 'pi pi-file text-gray-400';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const onSelectionChange = (event) => {
|
||||||
|
emit('change', event.value);
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.input-wrapper {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.5em;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-muted {
|
||||||
|
color: #6c757d;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
21
src/service/FileUploadService.js
Normal file
21
src/service/FileUploadService.js
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
import axios from 'axios';
|
||||||
|
|
||||||
|
export const FileUploadService = {
|
||||||
|
/**
|
||||||
|
* Elimina un file dal server
|
||||||
|
* @param {string} fileName - Nome del file da eliminare
|
||||||
|
* @param {string} folderName - Nome della cartella contenente il file
|
||||||
|
* @returns {Promise} Promise con la risposta del server
|
||||||
|
*/
|
||||||
|
deleteFile(fileName, folderName) {
|
||||||
|
return axios.post(
|
||||||
|
'/deleteFile',
|
||||||
|
{ fileName, folderName },
|
||||||
|
{
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
28
src/service/KSDocumentService.js
Normal file
28
src/service/KSDocumentService.js
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
import axios from 'axios';
|
||||||
|
|
||||||
|
export const KSDocumentService = {
|
||||||
|
/**
|
||||||
|
* Recupera tutti i KSDocument per il progetto selezionato dall'utente corrente
|
||||||
|
* @returns {Promise} Promise con la lista di KSDocument
|
||||||
|
*/
|
||||||
|
getKSDocuments() {
|
||||||
|
return axios.get('/ksDocuments');
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recupera tutti i KSDocument completati per il progetto selezionato dall'utente corrente
|
||||||
|
* @returns {Promise} Promise con la lista di KSDocument completati
|
||||||
|
*/
|
||||||
|
getCompletedKSDocuments() {
|
||||||
|
return axios.get('/ksDocuments/completed');
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recupera tutti i KSDocument per un progetto specifico
|
||||||
|
* @param {string} projectId - ID del progetto
|
||||||
|
* @returns {Promise} Promise con la lista di KSDocument
|
||||||
|
*/
|
||||||
|
getKSDocumentsByProject(projectId) {
|
||||||
|
return axios.post('/ksDocuments/byProject', projectId);
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -1,39 +1,52 @@
|
|||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
export const ScenarioService = {
|
export const ScenarioService = {
|
||||||
|
|
||||||
getScenarios() {
|
getScenarios() {
|
||||||
return axios.get('/scenarios')
|
return axios.get('/scenarios');
|
||||||
|
|
||||||
},
|
},
|
||||||
getScenariosProject(projectId) {
|
getScenariosProject(projectId) {
|
||||||
return axios.post('/scenariosProject' , projectId)
|
return axios.post('/scenariosProject', projectId);
|
||||||
|
|
||||||
},
|
},
|
||||||
getScenariosApplication(app) {
|
getScenariosApplication(app) {
|
||||||
return axios.post('/scenariosByApp' , app)
|
return axios.post('/scenariosByApp', app);
|
||||||
|
|
||||||
},
|
},
|
||||||
getScenariosCross() {
|
getScenariosCross() {
|
||||||
return axios.get('/scenariosCross')
|
return axios.get('/scenariosCross');
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
getExecScenariosByUser(page = 0, size = 10, filters = {}, sortField, sortOrder) {
|
getExecScenariosByUser(page = 0, size = 10, filters = {}, sortField, sortOrder) {
|
||||||
// Filtri potrebbero essere vuoti, quindi rimuoviamoli se non necessari
|
// Filtri potrebbero essere vuoti, quindi rimuoviamoli se non necessari
|
||||||
const requestBody = { page, size, ...filters, sortField, sortOrder };
|
const requestBody = { page, size, ...filters, sortField, sortOrder };
|
||||||
return axios.post('/executions', requestBody);
|
return axios.post('/executions', requestBody);
|
||||||
}
|
|
||||||
|
|
||||||
,
|
|
||||||
getScenariosForRE(){
|
|
||||||
return axios.get('/getScenariosForRE')
|
|
||||||
},
|
|
||||||
updateScenarioExecRating(id, rating) {
|
|
||||||
return axios.get('/updateRating?id=' + id + '&rating=' + rating)
|
|
||||||
},
|
},
|
||||||
|
|
||||||
getExecScenarioByProject () {
|
getScenariosForRE() {
|
||||||
return axios.get('/getExecScenarioByProject')
|
return axios.get('/getScenariosForRE');
|
||||||
}
|
},
|
||||||
|
updateScenarioExecRating(id, rating) {
|
||||||
|
return axios.get('/updateRating?id=' + id + '&rating=' + rating);
|
||||||
|
},
|
||||||
|
|
||||||
}
|
getExecScenarioByProject() {
|
||||||
|
return axios.get('/getExecScenarioByProject');
|
||||||
|
},
|
||||||
|
|
||||||
|
// Nuovo metodo per recuperare un singolo scenario
|
||||||
|
getScenarioById(id) {
|
||||||
|
return axios.get(`/scenarios/${id}`);
|
||||||
|
},
|
||||||
|
|
||||||
|
// Nuovo metodo per eseguire uno scenario in modo asincrono
|
||||||
|
executeScenarioAsync(data) {
|
||||||
|
return axios.post('/scenarios/execute-async', data);
|
||||||
|
},
|
||||||
|
|
||||||
|
// Nuovo metodo per recuperare i dettagli di esecuzione di uno scenario
|
||||||
|
getScenarioExecution(execId) {
|
||||||
|
return axios.get('/scenarios/execute/' + execId);
|
||||||
|
},
|
||||||
|
|
||||||
|
// Nuovo metodo per recuperare il progresso di esecuzione
|
||||||
|
getExecutionProgress(execId) {
|
||||||
|
return axios.get('/scenarios/getExecutionProgress/' + execId);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|||||||
55
src/stores/FileUploadStore.js
Normal file
55
src/stores/FileUploadStore.js
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
import { defineStore } from 'pinia';
|
||||||
|
import { ref } from 'vue';
|
||||||
|
import { FileUploadService } from '../service/FileUploadService';
|
||||||
|
|
||||||
|
export const FileUploadStore = defineStore('file_upload_store', () => {
|
||||||
|
const uploadedFiles = ref([]);
|
||||||
|
const folderName = ref('');
|
||||||
|
const numberPrFiles = ref(0);
|
||||||
|
|
||||||
|
// Funzione per eliminare un file
|
||||||
|
async function deleteFile(fileName, folderName) {
|
||||||
|
try {
|
||||||
|
const response = await FileUploadService.deleteFile(fileName, folderName);
|
||||||
|
return response;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error deleting file:', error);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Funzione per generare un ID univoco per la cartella
|
||||||
|
function generateUniqueFolderId() {
|
||||||
|
const timestamp = Date.now();
|
||||||
|
const randomNumber = Math.floor(Math.random() * 1000);
|
||||||
|
const newFolderName = `${timestamp}_${randomNumber}`;
|
||||||
|
folderName.value = newFolderName;
|
||||||
|
return newFolderName;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Funzione per resettare lo store
|
||||||
|
function resetStore() {
|
||||||
|
uploadedFiles.value = [];
|
||||||
|
folderName.value = '';
|
||||||
|
numberPrFiles.value = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Funzione per aggiornare il numero di file PR
|
||||||
|
function updatePrFilesCount(increment = true) {
|
||||||
|
if (increment) {
|
||||||
|
numberPrFiles.value += 1;
|
||||||
|
} else {
|
||||||
|
numberPrFiles.value -= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
uploadedFiles,
|
||||||
|
folderName,
|
||||||
|
numberPrFiles,
|
||||||
|
deleteFile,
|
||||||
|
generateUniqueFolderId,
|
||||||
|
resetStore,
|
||||||
|
updatePrFilesCount
|
||||||
|
};
|
||||||
|
});
|
||||||
@@ -1,11 +1,15 @@
|
|||||||
import { defineStore } from 'pinia';
|
import { defineStore } from 'pinia';
|
||||||
import { computed, ref } from 'vue';
|
import { computed, ref } from 'vue';
|
||||||
import { ScenarioExecutionService } from '../service/ScenarioExecutionService';
|
import { ScenarioExecutionService } from '../service/ScenarioExecutionService';
|
||||||
|
import { ScenarioService } from '../service/ScenarioService';
|
||||||
import { LoadingStore } from './LoadingStore';
|
import { LoadingStore } from './LoadingStore';
|
||||||
|
|
||||||
export const ScenarioExecutionStore = defineStore('scenario_execution_store', () => {
|
export const ScenarioExecutionStore = defineStore('scenario_execution_store', () => {
|
||||||
const lstScenarioExecution = ref([]);
|
const lstScenarioExecution = ref([]);
|
||||||
const selectedExecScenario = ref(null);
|
const selectedExecScenario = ref(null);
|
||||||
|
const currentScenario = ref({});
|
||||||
|
const currentExecution = ref(null);
|
||||||
|
const executionProgress = ref(null);
|
||||||
const loadingStore = LoadingStore();
|
const loadingStore = LoadingStore();
|
||||||
|
|
||||||
const totalRecords = ref(0); // Numero totale di record
|
const totalRecords = ref(0); // Numero totale di record
|
||||||
@@ -30,6 +34,53 @@ export const ScenarioExecutionStore = defineStore('scenario_execution_store', ()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Funzione per recuperare un singolo scenario
|
||||||
|
async function fetchScenario(id) {
|
||||||
|
try {
|
||||||
|
const response = await ScenarioService.getScenarioById(id);
|
||||||
|
currentScenario.value = response.data;
|
||||||
|
return response.data;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error fetching scenario:', error);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Funzione per eseguire uno scenario
|
||||||
|
async function executeScenario(data) {
|
||||||
|
try {
|
||||||
|
const response = await ScenarioService.executeScenarioAsync(data);
|
||||||
|
currentExecution.value = response.data;
|
||||||
|
return response.data;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error executing scenario:', error);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Funzione per recuperare i dettagli di esecuzione
|
||||||
|
async function getScenarioExecution(execId) {
|
||||||
|
try {
|
||||||
|
const response = await ScenarioService.getScenarioExecution(execId);
|
||||||
|
return response.data;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error getting scenario execution:', error);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Funzione per recuperare il progresso di esecuzione
|
||||||
|
async function getExecutionProgress(execId) {
|
||||||
|
try {
|
||||||
|
const response = await ScenarioService.getExecutionProgress(execId);
|
||||||
|
executionProgress.value = response.data;
|
||||||
|
return response.data;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error getting execution progress:', error);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function downloadFile(filePath, executionId) {
|
async function downloadFile(filePath, executionId) {
|
||||||
loadingStore.scenario_loading = true;
|
loadingStore.scenario_loading = true;
|
||||||
try {
|
try {
|
||||||
@@ -80,6 +131,18 @@ export const ScenarioExecutionStore = defineStore('scenario_execution_store', ()
|
|||||||
return totalRecords.value;
|
return totalRecords.value;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const getCurrentScenario = computed(() => {
|
||||||
|
return currentScenario.value;
|
||||||
|
});
|
||||||
|
|
||||||
|
const getCurrentExecution = computed(() => {
|
||||||
|
return currentExecution.value;
|
||||||
|
});
|
||||||
|
|
||||||
|
const getExecutionProgressData = computed(() => {
|
||||||
|
return executionProgress.value;
|
||||||
|
});
|
||||||
|
|
||||||
const setSelectedExecScenario = (execScenario) => {
|
const setSelectedExecScenario = (execScenario) => {
|
||||||
selectedExecScenario.value = execScenario;
|
selectedExecScenario.value = execScenario;
|
||||||
};
|
};
|
||||||
@@ -96,6 +159,9 @@ export const ScenarioExecutionStore = defineStore('scenario_execution_store', ()
|
|||||||
const resetStore = () => {
|
const resetStore = () => {
|
||||||
lstScenarioExecution.value = [];
|
lstScenarioExecution.value = [];
|
||||||
selectedExecScenario.value = null;
|
selectedExecScenario.value = null;
|
||||||
|
currentScenario.value = {};
|
||||||
|
currentExecution.value = null;
|
||||||
|
executionProgress.value = null;
|
||||||
totalRecords.value = 0;
|
totalRecords.value = 0;
|
||||||
currentPage.value = 0;
|
currentPage.value = 0;
|
||||||
pageSize.value = 10;
|
pageSize.value = 10;
|
||||||
@@ -106,15 +172,22 @@ export const ScenarioExecutionStore = defineStore('scenario_execution_store', ()
|
|||||||
getCurrentPage,
|
getCurrentPage,
|
||||||
getPageSize,
|
getPageSize,
|
||||||
getTotalRecords,
|
getTotalRecords,
|
||||||
|
getCurrentScenario,
|
||||||
|
getCurrentExecution,
|
||||||
|
getExecutionProgressData,
|
||||||
fetchScenariosExecution,
|
fetchScenariosExecution,
|
||||||
|
fetchScenario,
|
||||||
|
executeScenario,
|
||||||
|
getScenarioExecution,
|
||||||
|
getExecutionProgress,
|
||||||
downloadFile,
|
downloadFile,
|
||||||
selectedExecScenario,
|
selectedExecScenario,
|
||||||
lstScenarioExecution,
|
lstScenarioExecution,
|
||||||
scenariosExecution,
|
scenariosExecution,
|
||||||
getSelectedExecScenario,
|
getSelectedExecScenario,
|
||||||
setSelectedExecScenario,
|
setSelectedExecScenario,
|
||||||
updateFilters, // Aggiunto per aggiornare i filtri
|
updateFilters,
|
||||||
filters,
|
filters,
|
||||||
resetStore // Rende disponibile i filtri come parte dello store
|
resetStore
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -148,12 +148,18 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="input.type === 'multiselect'" class="mt-4">
|
<div v-else-if="input.type === 'multiselect'" class="mt-4">
|
||||||
<label :for="input.name">
|
<DynamicPicker
|
||||||
<b>{{ input.label }}</b>
|
v-model="formData[input.name]"
|
||||||
</label>
|
:input-name="input.name"
|
||||||
<div class="input-wrapper">
|
:label="input.label"
|
||||||
<MultiSelect v-model="formData[input.name]" :options="videoGroups" optionLabel="name" filter placeholder="Select VideoGroups" class="w-full md:w-80" />
|
:data-source="input.dataSource || 'videoGroups'"
|
||||||
</div>
|
: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>
|
</div>
|
||||||
<div v-else>
|
<div v-else>
|
||||||
<label :for="input.name"
|
<label :for="input.name"
|
||||||
@@ -276,11 +282,14 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import ChangeImpactOutputViewer from '@/components/ChangeImpactOutputViewer.vue';
|
import ChangeImpactOutputViewer from '@/components/ChangeImpactOutputViewer.vue';
|
||||||
import ChatClient from '@/components/ChatClient.vue';
|
import ChatClient from '@/components/ChatClient.vue';
|
||||||
|
import DynamicPicker from '@/components/DynamicPicker.vue';
|
||||||
|
import { KSDocumentService } from '@/service/KSDocumentService';
|
||||||
|
import { FileUploadStore } from '@/stores/FileUploadStore';
|
||||||
import { KsVideoGroupStore } from '@/stores/KsVideoGroupStore';
|
import { KsVideoGroupStore } from '@/stores/KsVideoGroupStore';
|
||||||
import { LoadingStore } from '@/stores/LoadingStore';
|
import { LoadingStore } from '@/stores/LoadingStore';
|
||||||
|
import { ScenarioExecutionStore } from '@/stores/ScenarioExecutionStore';
|
||||||
import { UserPrefStore } from '@/stores/UserPrefStore';
|
import { UserPrefStore } from '@/stores/UserPrefStore';
|
||||||
import { useAuth } from '@websanova/vue-auth/src/v3.js';
|
import { useAuth } from '@websanova/vue-auth/src/v3.js';
|
||||||
import axios from 'axios';
|
|
||||||
import JsonEditorVue from 'json-editor-vue';
|
import JsonEditorVue from 'json-editor-vue';
|
||||||
import JSZip from 'jszip';
|
import JSZip from 'jszip';
|
||||||
import { marked } from 'marked';
|
import { marked } from 'marked';
|
||||||
@@ -294,12 +303,14 @@ import Select from 'primevue/select';
|
|||||||
import Textarea from 'primevue/textarea';
|
import Textarea from 'primevue/textarea';
|
||||||
import { useConfirm } from 'primevue/useconfirm';
|
import { useConfirm } from 'primevue/useconfirm';
|
||||||
import { useToast } from 'primevue/usetoast';
|
import { useToast } from 'primevue/usetoast';
|
||||||
import { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue';
|
import { computed, onBeforeUnmount, onMounted, reactive, ref, watch } from 'vue';
|
||||||
import { useRoute } from 'vue-router';
|
import { useRoute } from 'vue-router';
|
||||||
import { JellyfishLoader } from 'vue3-spinner';
|
import { JellyfishLoader } from 'vue3-spinner';
|
||||||
import { ScenarioService } from '../../service/ScenarioService';
|
import { ScenarioService } from '../../service/ScenarioService';
|
||||||
|
|
||||||
const loadingStore = LoadingStore();
|
const loadingStore = LoadingStore();
|
||||||
|
const scenarioExecutionStore = ScenarioExecutionStore();
|
||||||
|
const fileUploadStore = FileUploadStore();
|
||||||
const toast = useToast();
|
const toast = useToast();
|
||||||
const zip = ref(null);
|
const zip = ref(null);
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
@@ -316,6 +327,8 @@ const formData = ref({});
|
|||||||
const exec_id = ref(null);
|
const exec_id = ref(null);
|
||||||
const exec_scenario = ref({});
|
const exec_scenario = ref({});
|
||||||
const debug_modal = ref(false);
|
const debug_modal = ref(false);
|
||||||
|
const loadingOptionsFor = reactive({});
|
||||||
|
const ksDocuments = ref([]);
|
||||||
let pollingInterval = null;
|
let pollingInterval = null;
|
||||||
const folderName = ref('');
|
const folderName = ref('');
|
||||||
const fileNamesOutput = ref([]);
|
const fileNamesOutput = ref([]);
|
||||||
@@ -368,13 +381,20 @@ const isInputFilled = computed(() => {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
scenario.value.inputs.forEach((input) => {
|
scenario.value.inputs.forEach((input) => {
|
||||||
if (formData.value[input.name] === undefined || formData.value[input.name] === '') {
|
const inputValue = formData.value[input.name];
|
||||||
console.log('Input not filled: ', input.name);
|
|
||||||
isFilled = false;
|
// Controllo per input multiselect
|
||||||
} else {
|
if (input.type === 'multiselect') {
|
||||||
const processedData = { ...formData.value };
|
if (!inputValue || !Array.isArray(inputValue) || inputValue.length === 0) {
|
||||||
if (processedData.input_multiselect) {
|
console.log('Multiselect input not filled: ', input.name);
|
||||||
processedData.input_multiselect = JSON.stringify(processedData.input_multiselect.map((item) => item.id));
|
isFilled = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Controllo per altri tipi di input
|
||||||
|
else {
|
||||||
|
if (inputValue === undefined || inputValue === '') {
|
||||||
|
console.log('Input not filled: ', input.name);
|
||||||
|
isFilled = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -388,10 +408,8 @@ onBeforeUnmount(() => {
|
|||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
fetchScenario(route.params.id);
|
fetchScenario(route.params.id);
|
||||||
loadVideoGroups();
|
const newFolderName = fileUploadStore.generateUniqueFolderId();
|
||||||
const timestamp = Date.now(); // Ottiene il timestamp corrente
|
folderName.value = newFolderName;
|
||||||
const randomNumber = Math.floor(Math.random() * 1000);
|
|
||||||
folderName.value = `${timestamp}_${randomNumber}`;
|
|
||||||
uploadUrl.value = uploadUrlBase + '/uploadListFiles/' + folderName.value;
|
uploadUrl.value = uploadUrlBase + '/uploadListFiles/' + folderName.value;
|
||||||
uploadUrlPR.value = uploadUrl.value + '/PR';
|
uploadUrlPR.value = uploadUrl.value + '/PR';
|
||||||
uploadUrlOther.value = uploadUrl.value + '/OTHER';
|
uploadUrlOther.value = uploadUrl.value + '/OTHER';
|
||||||
@@ -410,37 +428,38 @@ const loadVideoGroups = async () => {
|
|||||||
watch(() => route.params.id, fetchScenario);
|
watch(() => route.params.id, fetchScenario);
|
||||||
|
|
||||||
//Function to fetch scenarios
|
//Function to fetch scenarios
|
||||||
function fetchScenario(id) {
|
async function fetchScenario(id) {
|
||||||
chatDisabled();
|
chatDisabled();
|
||||||
scenario.value.inputs = null;
|
scenario.value.inputs = null;
|
||||||
data_loaded.value = false;
|
data_loaded.value = false;
|
||||||
formData.value = {};
|
formData.value = {};
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
axios
|
|
||||||
.get(`/scenarios/${id}`)
|
|
||||||
.then((response) => {
|
|
||||||
scenario.value = response.data;
|
|
||||||
console.log('Scenario fetched:', scenario.value);
|
|
||||||
|
|
||||||
if (scenario.value.inputs.some((input) => input.name === 'MultiFileUpload' || input.name === 'SingleFileUpload')) {
|
try {
|
||||||
reqMultiFile.value = true;
|
const response = await scenarioExecutionStore.fetchScenario(id);
|
||||||
}
|
scenario.value = response;
|
||||||
if (scenario.value.inputs.some((input) => input.type === 'singlefile_acceptall')) {
|
console.log('Scenario fetched:', scenario.value);
|
||||||
reqMultiFile.value = false;
|
|
||||||
acceptedFormats.value = '';
|
// Carica le opzioni necessarie basate sui dataSource presenti negli inputs
|
||||||
//acceptedFormats.value = '.doc,.docx,.pdf,.msg,.txt,.xlx,.xlxs,.logs,.pptx,.json,.odt,.rtf,.xml,.html';
|
await loadOptionsForScenario();
|
||||||
}
|
|
||||||
if (scenario.value.inputs.some((input) => input.type === 'singlefile')) {
|
if (scenario.value.inputs.some((input) => input.name === 'MultiFileUpload' || input.name === 'SingleFileUpload')) {
|
||||||
reqMultiFile.value = false;
|
reqMultiFile.value = true;
|
||||||
acceptedFormats.value = '.docx';
|
}
|
||||||
}
|
if (scenario.value.inputs.some((input) => input.type === 'singlefile_acceptall')) {
|
||||||
})
|
reqMultiFile.value = false;
|
||||||
.catch((error) => {
|
acceptedFormats.value = '';
|
||||||
console.error('Error fetching scenario:', error);
|
//acceptedFormats.value = '.doc,.docx,.pdf,.msg,.txt,.xlx,.xlxs,.logs,.pptx,.json,.odt,.rtf,.xml,.html';
|
||||||
})
|
}
|
||||||
.finally(() => {
|
if (scenario.value.inputs.some((input) => input.type === 'singlefile')) {
|
||||||
loading.value = false;
|
reqMultiFile.value = false;
|
||||||
});
|
acceptedFormats.value = '.docx';
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error fetching scenario:', error);
|
||||||
|
} finally {
|
||||||
|
loading.value = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const onBeforeSend = (event) => {
|
const onBeforeSend = (event) => {
|
||||||
@@ -473,7 +492,7 @@ const chatDisabled = () => {
|
|||||||
chat_enabled.value = false;
|
chat_enabled.value = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
const execScenario = () => {
|
const execScenario = async () => {
|
||||||
if (numberPrFiles.value !== 1 && reqMultiFile.value) {
|
if (numberPrFiles.value !== 1 && reqMultiFile.value) {
|
||||||
toast.add({
|
toast.add({
|
||||||
severity: 'warn', // Tipo di notifica (errore)
|
severity: 'warn', // Tipo di notifica (errore)
|
||||||
@@ -490,10 +509,23 @@ const execScenario = () => {
|
|||||||
|
|
||||||
// Crea una copia dei dati del form
|
// Crea una copia dei dati del form
|
||||||
const processedData = { ...formData.value };
|
const processedData = { ...formData.value };
|
||||||
if (processedData.input_multiselect) {
|
|
||||||
processedData.input_multiselect_id = JSON.stringify(processedData.input_multiselect.map((item) => item.id));
|
// Elabora tutti i multiselect dinamici
|
||||||
processedData.input_multiselect_name = JSON.stringify(processedData.input_multiselect.map((item) => item.name));
|
if (scenario.value.inputs) {
|
||||||
delete processedData.input_multiselect;
|
scenario.value.inputs.forEach((input) => {
|
||||||
|
if (input.type === 'multiselect' && processedData[input.name]) {
|
||||||
|
const selectedItems = processedData[input.name];
|
||||||
|
|
||||||
|
if (Array.isArray(selectedItems) && selectedItems.length > 0) {
|
||||||
|
// Elaborazione per VideoGroups (backward compatibility)
|
||||||
|
processedData[`${input.name}_id`] = JSON.stringify(selectedItems.map((item) => item.id || item));
|
||||||
|
processedData[`${input.name}_name`] = JSON.stringify(selectedItems.map((item) => item.name || item.fileName || item));
|
||||||
|
|
||||||
|
// Rimuovi l'array originale
|
||||||
|
delete processedData[input.name];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const data = {
|
const data = {
|
||||||
@@ -501,55 +533,58 @@ const execScenario = () => {
|
|||||||
inputs: processedData
|
inputs: processedData
|
||||||
};
|
};
|
||||||
|
|
||||||
axios
|
try {
|
||||||
.post('/scenarios/execute-async', data)
|
const response = await scenarioExecutionStore.executeScenario(data);
|
||||||
.then((response) => {
|
console.log('Response data exec 1:', response);
|
||||||
console.log('Response data exec 1:', response.data);
|
scenario_response.value = response;
|
||||||
scenario_response.value = response.data;
|
scenario_response_message.value = response.message;
|
||||||
scenario_response_message.value = response.data.message;
|
scenario_output.value = response.stringOutput;
|
||||||
scenario_output.value = response.data.stringOutput;
|
exec_id.value = response.scenarioExecution_id;
|
||||||
exec_id.value = response.data.scenarioExecution_id;
|
loadingStore.setIdExecLoading(exec_id.value);
|
||||||
loadingStore.setIdExecLoading(exec_id.value);
|
startPolling();
|
||||||
startPolling();
|
} catch (error) {
|
||||||
})
|
console.error('Error executing scenario:', error);
|
||||||
.catch((error) => {
|
loadingStore.exectuion_loading = false;
|
||||||
console.error('Error executing scenario:', error);
|
}
|
||||||
loadingStore.exectuion_loading = false;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const openDebug = () => {
|
const openDebug = async () => {
|
||||||
axios.get('/scenarios/execute/' + exec_id.value).then((resp) => {
|
try {
|
||||||
exec_scenario.value = resp.data;
|
const resp = await scenarioExecutionStore.getScenarioExecution(exec_id.value);
|
||||||
|
exec_scenario.value = resp;
|
||||||
debug_modal.value = true;
|
debug_modal.value = true;
|
||||||
});
|
} catch (error) {
|
||||||
|
console.error('Error opening debug:', error);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const pollBackendAPI = () => {
|
const pollBackendAPI = async () => {
|
||||||
errored_execution.value = false;
|
errored_execution.value = false;
|
||||||
axios.get('/scenarios/getExecutionProgress/' + exec_id.value).then((response) => {
|
try {
|
||||||
if (response.data.status == 'OK' || response.data.status == 'ERROR') {
|
const response = await scenarioExecutionStore.getExecutionProgress(exec_id.value);
|
||||||
|
|
||||||
|
if (response.status == 'OK' || response.status == 'ERROR') {
|
||||||
console.log('Condition met, stopping polling.');
|
console.log('Condition met, stopping polling.');
|
||||||
stopPolling();
|
stopPolling();
|
||||||
|
|
||||||
stopTimer();
|
stopTimer();
|
||||||
|
|
||||||
if(response.data.status == 'ERROR') {
|
if (response.status == 'ERROR') {
|
||||||
errored_execution.value = true;
|
errored_execution.value = true;
|
||||||
error_message.value = response.data.message;
|
error_message.value = response.message;
|
||||||
}
|
}
|
||||||
|
|
||||||
loading_data.value = false;
|
loading_data.value = false;
|
||||||
data_loaded.value = true;
|
data_loaded.value = true;
|
||||||
scenario_output.value = response.data.stringOutput;
|
scenario_output.value = response.stringOutput;
|
||||||
console.log('Response data exec 2:', response.data);
|
console.log('Response data exec 2:', response);
|
||||||
exec_id.value = response.data.scenarioExecution_id;
|
exec_id.value = response.scenarioExecution_id;
|
||||||
scenario_response_message.value = null; //if != null, next scenario starts with old message
|
scenario_response_message.value = null; //if != null, next scenario starts with old message
|
||||||
console.log('Scenario 3:', scenario.value);
|
console.log('Scenario 3:', scenario.value);
|
||||||
|
|
||||||
// Controlla se l'array `inputs` contiene un elemento con `name = 'MultiFileUpload'`
|
// Controlla se l'array `inputs` contiene un elemento con `name = 'MultiFileUpload'`
|
||||||
if (scenario.value.inputs.some((input) => input.name === 'MultiFileUpload')) {
|
if (scenario.value.inputs.some((input) => input.name === 'MultiFileUpload')) {
|
||||||
if (response.data.status == 'OK') {
|
if (response.status == 'OK') {
|
||||||
// Accedi al primo step e controlla se esiste l'attributo `codegenie_output_type`
|
// Accedi al primo step e controlla se esiste l'attributo `codegenie_output_type`
|
||||||
const firstStep = scenario.value.steps[0];
|
const firstStep = scenario.value.steps[0];
|
||||||
if (firstStep?.attributes?.['codegenie_output_type']) {
|
if (firstStep?.attributes?.['codegenie_output_type']) {
|
||||||
@@ -569,10 +604,12 @@ const pollBackendAPI = () => {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
console.log('Condition not met, polling continues.');
|
console.log('Condition not met, polling continues.');
|
||||||
scenario_response.value = response.data;
|
scenario_response.value = response;
|
||||||
scenario_response_message.value = response.data.message;
|
scenario_response_message.value = response.message;
|
||||||
}
|
}
|
||||||
});
|
} catch (error) {
|
||||||
|
console.error('Error polling backend API:', error);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const showFileContent = (base64String, type) => {
|
const showFileContent = (base64String, type) => {
|
||||||
@@ -691,66 +728,53 @@ function generateUniqueId() {
|
|||||||
return Date.now(); // Puoi usare anche UUID.randomUUID() o una libreria simile
|
return Date.now(); // Puoi usare anche UUID.randomUUID() o una libreria simile
|
||||||
}
|
}
|
||||||
|
|
||||||
const onRemove = (event, removeUploadedFileCallback, type) => {
|
const onRemove = async (event, removeUploadedFileCallback, type) => {
|
||||||
const { file, index } = event;
|
const { file, index } = event;
|
||||||
console.log('Removing file:', folderName.value);
|
console.log('Removing file:', folderName.value);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
axios
|
const response = await fileUploadStore.deleteFile(file.name, folderName.value);
|
||||||
.post(
|
|
||||||
`/deleteFile`,
|
|
||||||
{ fileName: file.name, folderName: folderName.value }, // Invio nome del file come payload
|
|
||||||
{
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
.then((response) => {
|
|
||||||
if (response.status === 200) {
|
|
||||||
console.log('File removed successfully:', response.data);
|
|
||||||
|
|
||||||
// Mostra notifica di successo
|
if (response.status === 200) {
|
||||||
toast.add({
|
console.log('File removed successfully:', response.data);
|
||||||
severity: 'success',
|
|
||||||
summary: 'Success',
|
|
||||||
detail: 'File removed successfully!',
|
|
||||||
life: 3000
|
|
||||||
});
|
|
||||||
|
|
||||||
if (type === 'SingleFileUpload') {
|
// Mostra notifica di successo
|
||||||
numberPrFiles.value -= 1;
|
toast.add({
|
||||||
console.log('Number of PR files: ', numberPrFiles.value);
|
severity: 'success',
|
||||||
formData.value['SingleFileUpload'] = ''
|
summary: 'Success',
|
||||||
}
|
detail: 'File removed successfully!',
|
||||||
|
life: 3000
|
||||||
// Aggiorna lista dei file caricati
|
|
||||||
removeUploadedFileCallback(index);
|
|
||||||
} else {
|
|
||||||
console.error('Failed to remove file:', response.statusText);
|
|
||||||
|
|
||||||
// Mostra notifica di errore
|
|
||||||
toast.add({
|
|
||||||
severity: 'error',
|
|
||||||
summary: 'Error',
|
|
||||||
detail: `Failed to remove file. Status: ${response.statusText}`,
|
|
||||||
life: 3000
|
|
||||||
});
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
console.error('Error while removing file:', error);
|
|
||||||
|
|
||||||
// Mostra notifica di errore
|
|
||||||
toast.add({
|
|
||||||
severity: 'error',
|
|
||||||
summary: 'Error',
|
|
||||||
detail: `Error while removing file: ${error.message}`,
|
|
||||||
life: 3000
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (type === 'SingleFileUpload') {
|
||||||
|
numberPrFiles.value -= 1;
|
||||||
|
console.log('Number of PR files: ', numberPrFiles.value);
|
||||||
|
formData.value['SingleFileUpload'] = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Aggiorna lista dei file caricati
|
||||||
|
removeUploadedFileCallback(index);
|
||||||
|
} else {
|
||||||
|
console.error('Failed to remove file:', response.statusText);
|
||||||
|
|
||||||
|
// Mostra notifica di errore
|
||||||
|
toast.add({
|
||||||
|
severity: 'error',
|
||||||
|
summary: 'Error',
|
||||||
|
detail: `Failed to remove file. Status: ${response.statusText}`,
|
||||||
|
life: 3000
|
||||||
|
});
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error while removing file:', error);
|
console.error('Error while removing file:', error);
|
||||||
|
|
||||||
|
// Mostra notifica di errore
|
||||||
|
toast.add({
|
||||||
|
severity: 'error',
|
||||||
|
summary: 'Error',
|
||||||
|
detail: `Error while removing file: ${error.message}`,
|
||||||
|
life: 3000
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -859,6 +883,71 @@ const formatSize = (bytes) => {
|
|||||||
|
|
||||||
return `${truncatedSize} ${sizes[i]}`;
|
return `${truncatedSize} ${sizes[i]}`;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Metodi per la gestione delle picklist dinamiche
|
||||||
|
const getOptionsForInput = (input) => {
|
||||||
|
// Basato sul dataSource, restituisce le opzioni appropriate
|
||||||
|
switch (input.dataSource) {
|
||||||
|
case 'videoGroups':
|
||||||
|
return videoGroups.value;
|
||||||
|
case 'ksDocuments':
|
||||||
|
return ksDocuments.value;
|
||||||
|
default:
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const onDynamicPickerChange = (inputName, value) => {
|
||||||
|
console.log(`Dynamic picker changed for ${inputName}:`, value);
|
||||||
|
formData.value[inputName] = value;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Carica le opzioni necessarie basate sui dataSource presenti negli inputs dello scenario
|
||||||
|
const loadOptionsForScenario = async () => {
|
||||||
|
if (!scenario.value.inputs) return;
|
||||||
|
|
||||||
|
console.log('Loading options for scenario inputs...');
|
||||||
|
|
||||||
|
// Trova tutti i dataSource unici negli input multiselect
|
||||||
|
const dataSources = new Set();
|
||||||
|
scenario.value.inputs.forEach((input) => {
|
||||||
|
if (input.type === 'multiselect' && input.dataSource) {
|
||||||
|
dataSources.add(input.dataSource);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Crea le funzioni di caricamento per ogni dataSource
|
||||||
|
const loadingPromises = Array.from(dataSources).map(async (dataSource) => {
|
||||||
|
try {
|
||||||
|
// Imposta lo stato di loading per questo dataSource
|
||||||
|
loadingOptionsFor[dataSource] = true;
|
||||||
|
console.log(`Loading options for dataSource: ${dataSource}`);
|
||||||
|
|
||||||
|
switch (dataSource) {
|
||||||
|
case 'videoGroups':
|
||||||
|
await loadVideoGroups();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'ksDocuments':
|
||||||
|
const docsResponse = await KSDocumentService.getKSDocuments();
|
||||||
|
ksDocuments.value = docsResponse.data;
|
||||||
|
console.log(`Loaded ${ksDocuments.value.length} KS documents`);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
console.warn(`Unknown dataSource: ${dataSource}`);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Error loading options for ${dataSource}:`, error);
|
||||||
|
} finally {
|
||||||
|
// Reset lo stato di loading per questo dataSource
|
||||||
|
loadingOptionsFor[dataSource] = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Aspetta che tutti i caricamenti siano completati
|
||||||
|
await Promise.all(loadingPromises);
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|||||||
Reference in New Issue
Block a user