Create document picklist and refactor axios call
This commit is contained in:
@@ -148,12 +148,18 @@
|
||||
</div>
|
||||
</div>
|
||||
<div v-else-if="input.type === 'multiselect'" class="mt-4">
|
||||
<label :for="input.name">
|
||||
<b>{{ input.label }}</b>
|
||||
</label>
|
||||
<div class="input-wrapper">
|
||||
<MultiSelect v-model="formData[input.name]" :options="videoGroups" optionLabel="name" filter placeholder="Select VideoGroups" class="w-full md:w-80" />
|
||||
</div>
|
||||
<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>
|
||||
<div v-else>
|
||||
<label :for="input.name"
|
||||
@@ -276,11 +282,14 @@
|
||||
<script setup>
|
||||
import ChangeImpactOutputViewer from '@/components/ChangeImpactOutputViewer.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 { LoadingStore } from '@/stores/LoadingStore';
|
||||
import { ScenarioExecutionStore } from '@/stores/ScenarioExecutionStore';
|
||||
import { UserPrefStore } from '@/stores/UserPrefStore';
|
||||
import { useAuth } from '@websanova/vue-auth/src/v3.js';
|
||||
import axios from 'axios';
|
||||
import JsonEditorVue from 'json-editor-vue';
|
||||
import JSZip from 'jszip';
|
||||
import { marked } from 'marked';
|
||||
@@ -294,12 +303,14 @@ import Select from 'primevue/select';
|
||||
import Textarea from 'primevue/textarea';
|
||||
import { useConfirm } from 'primevue/useconfirm';
|
||||
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 { JellyfishLoader } from 'vue3-spinner';
|
||||
import { ScenarioService } from '../../service/ScenarioService';
|
||||
|
||||
const loadingStore = LoadingStore();
|
||||
const scenarioExecutionStore = ScenarioExecutionStore();
|
||||
const fileUploadStore = FileUploadStore();
|
||||
const toast = useToast();
|
||||
const zip = ref(null);
|
||||
const route = useRoute();
|
||||
@@ -316,6 +327,8 @@ const formData = ref({});
|
||||
const exec_id = ref(null);
|
||||
const exec_scenario = ref({});
|
||||
const debug_modal = ref(false);
|
||||
const loadingOptionsFor = reactive({});
|
||||
const ksDocuments = ref([]);
|
||||
let pollingInterval = null;
|
||||
const folderName = ref('');
|
||||
const fileNamesOutput = ref([]);
|
||||
@@ -368,13 +381,20 @@ const isInputFilled = computed(() => {
|
||||
return false;
|
||||
}
|
||||
scenario.value.inputs.forEach((input) => {
|
||||
if (formData.value[input.name] === undefined || formData.value[input.name] === '') {
|
||||
console.log('Input not filled: ', input.name);
|
||||
isFilled = false;
|
||||
} else {
|
||||
const processedData = { ...formData.value };
|
||||
if (processedData.input_multiselect) {
|
||||
processedData.input_multiselect = JSON.stringify(processedData.input_multiselect.map((item) => item.id));
|
||||
const inputValue = formData.value[input.name];
|
||||
|
||||
// Controllo per input multiselect
|
||||
if (input.type === 'multiselect') {
|
||||
if (!inputValue || !Array.isArray(inputValue) || inputValue.length === 0) {
|
||||
console.log('Multiselect input not filled: ', input.name);
|
||||
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(() => {
|
||||
fetchScenario(route.params.id);
|
||||
loadVideoGroups();
|
||||
const timestamp = Date.now(); // Ottiene il timestamp corrente
|
||||
const randomNumber = Math.floor(Math.random() * 1000);
|
||||
folderName.value = `${timestamp}_${randomNumber}`;
|
||||
const newFolderName = fileUploadStore.generateUniqueFolderId();
|
||||
folderName.value = newFolderName;
|
||||
uploadUrl.value = uploadUrlBase + '/uploadListFiles/' + folderName.value;
|
||||
uploadUrlPR.value = uploadUrl.value + '/PR';
|
||||
uploadUrlOther.value = uploadUrl.value + '/OTHER';
|
||||
@@ -410,37 +428,38 @@ const loadVideoGroups = async () => {
|
||||
watch(() => route.params.id, fetchScenario);
|
||||
|
||||
//Function to fetch scenarios
|
||||
function fetchScenario(id) {
|
||||
async function fetchScenario(id) {
|
||||
chatDisabled();
|
||||
scenario.value.inputs = null;
|
||||
data_loaded.value = false;
|
||||
formData.value = {};
|
||||
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')) {
|
||||
reqMultiFile.value = true;
|
||||
}
|
||||
if (scenario.value.inputs.some((input) => input.type === 'singlefile_acceptall')) {
|
||||
reqMultiFile.value = false;
|
||||
acceptedFormats.value = '';
|
||||
//acceptedFormats.value = '.doc,.docx,.pdf,.msg,.txt,.xlx,.xlxs,.logs,.pptx,.json,.odt,.rtf,.xml,.html';
|
||||
}
|
||||
if (scenario.value.inputs.some((input) => input.type === 'singlefile')) {
|
||||
reqMultiFile.value = false;
|
||||
acceptedFormats.value = '.docx';
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Error fetching scenario:', error);
|
||||
})
|
||||
.finally(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
try {
|
||||
const response = await scenarioExecutionStore.fetchScenario(id);
|
||||
scenario.value = response;
|
||||
console.log('Scenario fetched:', scenario.value);
|
||||
|
||||
// Carica le opzioni necessarie basate sui dataSource presenti negli inputs
|
||||
await loadOptionsForScenario();
|
||||
|
||||
if (scenario.value.inputs.some((input) => input.name === 'MultiFileUpload' || input.name === 'SingleFileUpload')) {
|
||||
reqMultiFile.value = true;
|
||||
}
|
||||
if (scenario.value.inputs.some((input) => input.type === 'singlefile_acceptall')) {
|
||||
reqMultiFile.value = false;
|
||||
acceptedFormats.value = '';
|
||||
//acceptedFormats.value = '.doc,.docx,.pdf,.msg,.txt,.xlx,.xlxs,.logs,.pptx,.json,.odt,.rtf,.xml,.html';
|
||||
}
|
||||
if (scenario.value.inputs.some((input) => input.type === 'singlefile')) {
|
||||
reqMultiFile.value = false;
|
||||
acceptedFormats.value = '.docx';
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error fetching scenario:', error);
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
const onBeforeSend = (event) => {
|
||||
@@ -473,7 +492,7 @@ const chatDisabled = () => {
|
||||
chat_enabled.value = false;
|
||||
};
|
||||
|
||||
const execScenario = () => {
|
||||
const execScenario = async () => {
|
||||
if (numberPrFiles.value !== 1 && reqMultiFile.value) {
|
||||
toast.add({
|
||||
severity: 'warn', // Tipo di notifica (errore)
|
||||
@@ -490,10 +509,23 @@ const execScenario = () => {
|
||||
|
||||
// Crea una copia dei dati del form
|
||||
const processedData = { ...formData.value };
|
||||
if (processedData.input_multiselect) {
|
||||
processedData.input_multiselect_id = JSON.stringify(processedData.input_multiselect.map((item) => item.id));
|
||||
processedData.input_multiselect_name = JSON.stringify(processedData.input_multiselect.map((item) => item.name));
|
||||
delete processedData.input_multiselect;
|
||||
|
||||
// Elabora tutti i multiselect dinamici
|
||||
if (scenario.value.inputs) {
|
||||
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 = {
|
||||
@@ -501,55 +533,58 @@ const execScenario = () => {
|
||||
inputs: processedData
|
||||
};
|
||||
|
||||
axios
|
||||
.post('/scenarios/execute-async', data)
|
||||
.then((response) => {
|
||||
console.log('Response data exec 1:', response.data);
|
||||
scenario_response.value = response.data;
|
||||
scenario_response_message.value = response.data.message;
|
||||
scenario_output.value = response.data.stringOutput;
|
||||
exec_id.value = response.data.scenarioExecution_id;
|
||||
loadingStore.setIdExecLoading(exec_id.value);
|
||||
startPolling();
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Error executing scenario:', error);
|
||||
loadingStore.exectuion_loading = false;
|
||||
});
|
||||
try {
|
||||
const response = await scenarioExecutionStore.executeScenario(data);
|
||||
console.log('Response data exec 1:', response);
|
||||
scenario_response.value = response;
|
||||
scenario_response_message.value = response.message;
|
||||
scenario_output.value = response.stringOutput;
|
||||
exec_id.value = response.scenarioExecution_id;
|
||||
loadingStore.setIdExecLoading(exec_id.value);
|
||||
startPolling();
|
||||
} catch (error) {
|
||||
console.error('Error executing scenario:', error);
|
||||
loadingStore.exectuion_loading = false;
|
||||
}
|
||||
}
|
||||
};
|
||||
const openDebug = () => {
|
||||
axios.get('/scenarios/execute/' + exec_id.value).then((resp) => {
|
||||
exec_scenario.value = resp.data;
|
||||
const openDebug = async () => {
|
||||
try {
|
||||
const resp = await scenarioExecutionStore.getScenarioExecution(exec_id.value);
|
||||
exec_scenario.value = resp;
|
||||
debug_modal.value = true;
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Error opening debug:', error);
|
||||
}
|
||||
};
|
||||
|
||||
const pollBackendAPI = () => {
|
||||
const pollBackendAPI = async () => {
|
||||
errored_execution.value = false;
|
||||
axios.get('/scenarios/getExecutionProgress/' + exec_id.value).then((response) => {
|
||||
if (response.data.status == 'OK' || response.data.status == 'ERROR') {
|
||||
try {
|
||||
const response = await scenarioExecutionStore.getExecutionProgress(exec_id.value);
|
||||
|
||||
if (response.status == 'OK' || response.status == 'ERROR') {
|
||||
console.log('Condition met, stopping polling.');
|
||||
stopPolling();
|
||||
|
||||
stopTimer();
|
||||
|
||||
if(response.data.status == 'ERROR') {
|
||||
if (response.status == 'ERROR') {
|
||||
errored_execution.value = true;
|
||||
error_message.value = response.data.message;
|
||||
error_message.value = response.message;
|
||||
}
|
||||
|
||||
loading_data.value = false;
|
||||
data_loaded.value = true;
|
||||
scenario_output.value = response.data.stringOutput;
|
||||
console.log('Response data exec 2:', response.data);
|
||||
exec_id.value = response.data.scenarioExecution_id;
|
||||
scenario_output.value = response.stringOutput;
|
||||
console.log('Response data exec 2:', response);
|
||||
exec_id.value = response.scenarioExecution_id;
|
||||
scenario_response_message.value = null; //if != null, next scenario starts with old message
|
||||
console.log('Scenario 3:', scenario.value);
|
||||
|
||||
// Controlla se l'array `inputs` contiene un elemento con `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`
|
||||
const firstStep = scenario.value.steps[0];
|
||||
if (firstStep?.attributes?.['codegenie_output_type']) {
|
||||
@@ -569,10 +604,12 @@ const pollBackendAPI = () => {
|
||||
}
|
||||
} else {
|
||||
console.log('Condition not met, polling continues.');
|
||||
scenario_response.value = response.data;
|
||||
scenario_response_message.value = response.data.message;
|
||||
scenario_response.value = response;
|
||||
scenario_response_message.value = response.message;
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Error polling backend API:', error);
|
||||
}
|
||||
};
|
||||
|
||||
const showFileContent = (base64String, type) => {
|
||||
@@ -691,66 +728,53 @@ function generateUniqueId() {
|
||||
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;
|
||||
console.log('Removing file:', folderName.value);
|
||||
|
||||
try {
|
||||
axios
|
||||
.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);
|
||||
const response = await fileUploadStore.deleteFile(file.name, folderName.value);
|
||||
|
||||
// Mostra notifica di successo
|
||||
toast.add({
|
||||
severity: 'success',
|
||||
summary: 'Success',
|
||||
detail: 'File removed successfully!',
|
||||
life: 3000
|
||||
});
|
||||
if (response.status === 200) {
|
||||
console.log('File removed successfully:', response.data);
|
||||
|
||||
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) => {
|
||||
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
|
||||
});
|
||||
// Mostra notifica di successo
|
||||
toast.add({
|
||||
severity: 'success',
|
||||
summary: 'Success',
|
||||
detail: 'File removed successfully!',
|
||||
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) {
|
||||
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]}`;
|
||||
};
|
||||
|
||||
// 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>
|
||||
|
||||
<style scoped>
|
||||
|
||||
Reference in New Issue
Block a user