diff --git a/src/components/DynamicPicker.vue b/src/components/DynamicPicker.vue index b12f8fe..1fbc51b 100644 --- a/src/components/DynamicPicker.vue +++ b/src/components/DynamicPicker.vue @@ -60,6 +60,63 @@ + + + + + + + + +
+
+ + {{ folder.name }} + +
+
+ - + { return Array.isArray(props.options) ? props.options : []; }); +// Funzione per rimuovere una folder dalla selezione +const removeFolder = (folderToRemove) => { + if (!selectedValue.value || !Array.isArray(selectedValue.value)) return; + + const newValue = selectedValue.value.filter(folder => { + const currentPath = folder.path || folder.id || folder; + const removePathKey = folderToRemove.path || folderToRemove.id || folderToRemove; + return currentPath !== removePathKey; + }); + + selectedValue.value = newValue; + emit('change', newValue); +}; + const getFileIcon = (document) => { if (!document) return 'pi pi-file'; @@ -228,7 +299,7 @@ const onSelectionChange = (event) => { diff --git a/src/components/ExecutionInputTable.vue b/src/components/ExecutionInputTable.vue index ce6d159..2d2e23d 100644 --- a/src/components/ExecutionInputTable.vue +++ b/src/components/ExecutionInputTable.vue @@ -17,9 +17,15 @@ const emit = defineEmits(['download-file']); const filteredInputs = computed(() => { const filtered = {}; for (const [key, value] of Object.entries(props.inputs)) { - if (!(key.includes('input_multiselect') && key.endsWith('_id'))) { - filtered[key] = value; + // Escludi le chiavi _id per multiselect + if (key.includes('input_multiselect') && key.endsWith('_id')) { + continue; } + // Escludi selectedFolders_name e selectedFolders_id + if (key === 'selectedFolders_name' || key === 'selectedFolders_id') { + continue; + } + filtered[key] = value; } return filtered; }); diff --git a/src/views/pages/ScenarioExec.vue b/src/views/pages/ScenarioExec.vue index 1efb6e0..75a7d64 100644 --- a/src/views/pages/ScenarioExec.vue +++ b/src/views/pages/ScenarioExec.vue @@ -55,6 +55,8 @@ const uploadUrlOther = computed(() => `${uploadUrlBase}/uploadListFiles/${folder const loadingOptionsFor = reactive({}); const ksDocuments = ref([]); const videoGroups = ref([]); +const ksFolders = ref([]); +const folderToItemsMap = ref({}); // ============= File Output State ============= const fileType = ref(''); @@ -135,6 +137,122 @@ const loadVideoGroups = async () => { videoGroups.value = await Promise.all(videoGroups.value); }; +// Estrae tutte le folder/subfolder uniche dai documenti e video +const extractFoldersFromItems = (items) => { + const folderMap = {}; + const folderSet = new Set(); + + items.forEach((item) => { + // Filtra solo gli items che hanno il campo ingestionStatusV2 + if (!item.ingestionStatusV2) { + return; + } + + const path = item.ingestionInfo?.metadata?.ksKnowledgePath; + + // Gestisci item nella root (senza path o con path vuoto o "/") + if (!path || path === '/' || path.trim() === '') { + const rootPath = '/'; + folderSet.add(rootPath); + + if (!folderMap[rootPath]) { + folderMap[rootPath] = []; + } + + folderMap[rootPath].push({ + id: item.id, + type: item.fileName ? 'document' : 'video', + name: item.fileName || item.name + }); + return; + } + + // Rimuovi il leading slash se presente + const cleanPath = path.startsWith('/') ? path.substring(1) : path; + if (!cleanPath) { + const rootPath = '/'; + folderSet.add(rootPath); + + if (!folderMap[rootPath]) { + folderMap[rootPath] = []; + } + + folderMap[rootPath].push({ + id: item.id, + type: item.fileName ? 'document' : 'video', + name: item.fileName || item.name + }); + return; + } + + // Dividi il path in parti + const parts = cleanPath.split('/'); + + // Crea tutte le combinazioni di folder/subfolder + let currentPath = ''; + parts.forEach((part, index) => { + currentPath = index === 0 ? part : `${currentPath}/${part}`; + const fullPath = `/${currentPath}`; + + folderSet.add(fullPath); + + if (!folderMap[fullPath]) { + folderMap[fullPath] = []; + } + + if (fullPath === path) { + folderMap[fullPath].push({ + id: item.id, + type: item.fileName ? 'document' : 'video', + name: item.fileName || item.name + }); + } + }); + }); + + return { folders: Array.from(folderSet).sort(), folderMap }; +}; + +const loadKsFolders = async () => { + try { + const docsResponse = await KSDocumentService.getKSDocuments(); + const documents = docsResponse.data || []; + + const allItems = [...documents, ...videoGroups.value]; + const { folders, folderMap } = extractFoldersFromItems(allItems); + + // Calcola il numero di subfolder per ogni folder + const subfolderCounts = {}; + folders.forEach((folderPath) => { + const subfolderCount = folders.filter((otherPath) => { + if (otherPath === folderPath) return false; + + if (folderPath === '/') { + return otherPath !== '/' && otherPath.substring(1).indexOf('/') === -1; + } + + const relativePath = otherPath.substring(folderPath.length); + return relativePath.startsWith('/') && relativePath.substring(1).split('/').length === 1; + }).length; + subfolderCounts[folderPath] = subfolderCount; + }); + + ksFolders.value = folders.map((path) => ({ + id: path, + name: path === '/' ? '/ (Root)' : path, + path: path, + itemCount: folderMap[path]?.length || 0, + subfolderCount: subfolderCounts[path] || 0 + })); + + folderToItemsMap.value = folderMap; + + console.log(`Loaded ${ksFolders.value.length} folders with items:`, folderToItemsMap.value); + } catch (error) { + console.error('Error loading KS folders:', error); + } +}; + const loadOptionsForScenario = async () => { if (!scenario.value.inputs) return; @@ -160,6 +278,13 @@ const loadOptionsForScenario = async () => { break; } + case 'ksFolders': + if (videoGroups.value.length === 0) { + await loadVideoGroups(); + } + await loadKsFolders(); + break; + default: console.warn(`Unknown dataSource: ${dataSource}`); } @@ -179,6 +304,8 @@ const getOptionsForInput = (input) => { return videoGroups.value; case 'ksDocuments': return ksDocuments.value; + case 'ksFolders': + return ksFolders.value; default: return []; } @@ -195,8 +322,37 @@ const getInputComponent = (type) => { return components[type] || InputText; }; -const onDynamicPickerChange = (inputName, value) => { - formData.value[inputName] = value; +const onDynamicPickerChange = (inputName, value, dataSource) => { + console.log(`Dynamic picker changed for ${inputName}:`, value); + + // Gestione speciale per ksFolders: espande automaticamente le subfolder + if (dataSource === 'ksFolders' && Array.isArray(value)) { + const expandedSelection = new Set(); + + // Aggiungi tutte le folder selezionate dall'utente + value.forEach(folder => { + const folderPath = folder.path || folder.id || folder; + expandedSelection.add(folderPath); + + // Trova e aggiungi tutte le subfolder ricorsivamente + ksFolders.value.forEach(subfolder => { + const subfolderPath = subfolder.path; + if (subfolderPath !== folderPath && subfolderPath.startsWith(folderPath + '/')) { + expandedSelection.add(subfolderPath); + } + }); + }); + + // Converti il Set in un array di oggetti folder completi + const expandedFolders = Array.from(expandedSelection).map(path => + ksFolders.value.find(f => f.path === path) + ).filter(f => f !== undefined); + + console.log(`Expanded selection from ${value.length} to ${expandedFolders.length} folders`); + formData.value[inputName] = expandedFolders; + } else { + formData.value[inputName] = value; + } }; // ============= File Upload Handlers ============= @@ -265,8 +421,32 @@ const processFormData = () => { const selectedItems = processedData[input.name]; if (Array.isArray(selectedItems) && selectedItems.length > 0) { - 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)); + // Elaborazione speciale per ksFolders + if (input.dataSource === 'ksFolders') { + const allItemIds = []; + const allItemNames = []; + + selectedItems.forEach((folder) => { + const folderPath = folder.path || folder.id || folder; + const items = folderToItemsMap.value[folderPath] || []; + + items.forEach((item) => { + allItemIds.push(item.id); + allItemNames.push(item.name); + }); + }); + + processedData[`${input.name}_id`] = JSON.stringify(allItemIds); + processedData[`${input.name}_name`] = JSON.stringify(allItemNames); + processedData[`${input.name}_folders`] = JSON.stringify(selectedItems.map((item) => item.path || item.id || item)); + + console.log(`Folder selection - Total items: ${allItemIds.length}`, allItemIds); + } else { + // Elaborazione standard per videoGroups e ksDocuments + 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)); + } + delete processedData[input.name]; } } @@ -432,7 +612,7 @@ const chatDisabled = () => { :loading="loadingOptionsFor[input.dataSource] || false" :show-status="input.dataSource === 'ksDocuments'" no-margin - @change="onDynamicPickerChange(input.name, $event)" + @change="onDynamicPickerChange(input.name, $event, input.dataSource)" />