diff --git a/src/layout/AppMenu.vue b/src/layout/AppMenu.vue index 79ee3d2..7fa6fe7 100644 --- a/src/layout/AppMenu.vue +++ b/src/layout/AppMenu.vue @@ -6,8 +6,7 @@ import { UserPrefStore } from '../stores/UserPrefStore.js'; import AppMenuItem from './AppMenuItem.vue'; const userPrefStore = UserPrefStore(); -const route = useRouter() - +const route = useRouter(); const model = ref([ @@ -18,7 +17,7 @@ const model = ref([ { label: 'Execution List', icon: 'pi pi-fw pi-list', command: () => { route.push({path: '/executions/all'}); } }, - ] }, + ] }, { label: '', items: [] } , @@ -30,22 +29,25 @@ const model = ref([ label: 'Chat', items: [{ label: 'Chat', icon: 'pi pi-fw pi-comments', to: '/chat' }] } - + ]); -// onMounted(() => { - // if(userPrefStore.user.role == 'ADMIN'){ - // model.value.push({ - // label: 'Chat', - // items: [{ label: 'Chat', icon: 'pi pi-fw pi-comments', to: '/chat' }] - // }); - // } -// }); +onMounted(() => { + if(userPrefStore.user.role === 'ADMIN'){ + model.value[0].items.push({ + label: 'Dashboard', + icon: 'pi pi-fw pi-chart-bar', + command: () => { + route.push({ path: '/dashboard' }); + } + }); + } + }); // Funzione per aggiornare la sezione "Your Applications" in base a selectedApp function updateApplicationsMenu() { const selectedApp = userPrefStore.getSelApp; - console.log("selectedApp", selectedApp); + console.log('selectedApp', selectedApp); if (selectedApp != null) { //Aggiorna il label dell'app @@ -58,7 +60,7 @@ function updateApplicationsMenu() { const groupedScenarios = {}; //Raggruppa gli scenari per categoria (solo se type non è null) - selectedApp.available_scenarios.forEach(app => { + selectedApp.available_scenarios.forEach((app) => { if (app.type) { const type = app.type.trim(); if (!groupedScenarios[type]) { @@ -70,30 +72,31 @@ function updateApplicationsMenu() { model.value[1].items.push(createScenarioItem(app)); } }); - - //Creazione del menu in base ai gruppi - Object.keys(groupedScenarios).forEach(type => { + + //Creazione del menu in base ai gruppi + Object.keys(groupedScenarios).forEach((type) => { const scenarios = groupedScenarios[type]; if (scenarios.length >= 2) { - //Se ci sono almeno 2 scenari nella stessa categoria, creiamo un gruppo + //Se ci sono almeno 2 scenari nella stessa categoria, creiamo un gruppo const typeItem = { label: type, icon: 'pi pi-fw pi-folder', items: [] }; - scenarios.forEach(app => { + scenarios.forEach((app) => { typeItem.items.push(createScenarioItem(app)); }); model.value[1].items.push(typeItem); - }else { + } else { //Se c'è solo un elemento, lo aggiungiamo direttamente model.value[1].items.push(createScenarioItem(scenarios[0])); } }); - + + //Aggiungi "Rev Eng Code" alla fine della lista model.value[1].items.push({ label: 'Application Code', @@ -108,14 +111,10 @@ function updateApplicationsMenu() { model.value[1].label = ''; model.value[1].items = []; } - - } - function createScenarioItem(app) { - - if(app.associate_exec_list === 'Y'){ + if (app.associate_exec_list === 'Y') { return { label: app.label, icon: 'pi pi-fw pi-wrench', @@ -133,8 +132,7 @@ function createScenarioItem(app) { route.push({ path: `/home/scenario/exec/${app.scenario_id}` }); } }; - - }else{ + } else { return { label: app.label, icon: 'pi pi-fw pi-wrench', @@ -143,14 +141,8 @@ function createScenarioItem(app) { } }; } - - } - - - - // Monitora i cambiamenti in selectedApp dallo store watch(() => userPrefStore.getSelApp, updateApplicationsMenu, { immediate: true }); diff --git a/src/service/ScenarioService.js b/src/service/ScenarioService.js index aeb5bc7..99306bb 100644 --- a/src/service/ScenarioService.js +++ b/src/service/ScenarioService.js @@ -17,14 +17,6 @@ export const ScenarioService = { return axios.get('/scenariosCross') }, - - // getExecScenariosByUser(page = 0, size = 10) { - // return axios.get('/executions', { - // params: { - // page: page, - // size: size } - // }); - // } getExecScenariosByUser(page = 0, size = 10, filters = {}, sortField, sortOrder) { // Filtri potrebbero essere vuoti, quindi rimuoviamoli se non necessari @@ -38,6 +30,10 @@ export const ScenarioService = { }, updateScenarioExecRating(id, rating) { return axios.get('/updateRating?id=' + id + '&rating=' + rating) + }, + + getExecScenarioByProject () { + return axios.get('/getExecScenarioByProject') } } \ No newline at end of file diff --git a/src/service/dashboard/DashboardScenarioService.js b/src/service/dashboard/DashboardScenarioService.js new file mode 100644 index 0000000..6c221d2 --- /dev/null +++ b/src/service/dashboard/DashboardScenarioService.js @@ -0,0 +1,79 @@ +import axios from 'axios'; +export const DashboardScenarioService = { + + getExecScenarioByProject (project) { + return axios.get('/getExecScenarioByProject', { + params: project + }); + }, + + //funzione per recuperare la lista con TUTTI i progetti + getProjects() { + return axios.get('/projects'); + }, + + + getExecutions(filters) { + return axios.post('/executions-dash', { + dateFrom: filters.dateFrom, + dateTo: filters.dateTo, + projectNameList: filters.projectNames, + scenarioNameList: filters.scenarioNames + } + ); + }, + + getExecutionsStats(filters) { + return axios.post('/executions-stats-dash', { + dateFrom: filters.dateFrom, + dateTo: filters.dateTo, + projectNameList: filters.projectNames, + scenarioNameList: filters.scenarioNames + } + ); + }, + + + getUsers(filters) { + return axios.get('/users-by-projects', { + params: { + projectIdsArr: filters + } + }); + + }, + + getScenarios(filters) { + return axios.get('/scenarios-filter', { + params: { + selectedAccount: filters + } + }); + }, + + + getChats(filters) { + return axios.get('/chats', { + params: { + dateFrom: filters.dateFrom, + dateTo: filters.dateTo, + projectId: filters.projectId, + user: filters.user + } + }); + + }, + + getChatStats(filters) { + return axios.post('/dashboard-chat-stats', { + dateFrom: filters.dateFrom, + dateTo: filters.dateTo, + projectNameList: filters.projectNames, + scenarioIdList: filters.scenarioId + } + ); + }, + + + +}; \ No newline at end of file diff --git a/src/stores/UserPrefStore.js b/src/stores/UserPrefStore.js index ab32b7f..17069f7 100644 --- a/src/stores/UserPrefStore.js +++ b/src/stores/UserPrefStore.js @@ -13,20 +13,25 @@ export const UserPrefStore = defineStore('userpref_store', () => { const selectedFileRE = ref(null) const selectedScenario = ref(null) - async function fetchUserData(){ - - const auth = useAuth(); - loadingStore.user_loading = true; - await auth.fetch().then((fetchedUser) => { - user.value = fetchedUser.data.data; - selectedApp.value = user.value.selectedApplication; - userLoaded.value = true; - loadingStore.user_loading = false; - }).catch((error) => { - reject(error); - }); - }; + async function fetchUserData() { + const auth = useAuth(); + loadingStore.user_loading = true; + try { + const fetchedUser = await auth.fetch(); + user.value = fetchedUser.data.data; + selectedApp.value = user.value.selectedApplication; + userLoaded.value = true; + } catch (error) { + console.error('Errore nel recupero dei dati utente:', error); + // Puoi anche lanciare un errore se vuoi gestirlo in modo diverso altrove + throw error; // Lancia l'errore per gestirlo fuori dalla funzione, se necessario + } finally { + loadingStore.user_loading = false; + } +} + + async function updateSelectedProject(project) { try { loadingStore.user_loading = true; diff --git a/src/stores/dashboard/DashboardScenarioStore.js b/src/stores/dashboard/DashboardScenarioStore.js new file mode 100644 index 0000000..5580891 --- /dev/null +++ b/src/stores/dashboard/DashboardScenarioStore.js @@ -0,0 +1,166 @@ +import { defineStore } from 'pinia' +import { computed, ref } from 'vue' +import { DashboardScenarioService } from '../../service/dashboard/DashboardScenarioService' + +import { LoadingStore } from '../../stores/LoadingStore' +import { UserPrefStore } from '../../stores/UserPrefStore' + +export const DashboardScenarioStore = defineStore('dashboard_scenario_store', () => { + + const projectScenarios = ref([]) + const globalScenarios = ref([]) + const applicationScenarios = ref([]) + const filterString = ref('') + const allScenarios = ref([]) + const typeFilter = ref({ name: 'All', value: 'all' }) + const scenariosForRE = ref([]) + const projects = ref([]) + const executions = ref([]) + const chats = ref([]) + const error = ref(null) + const users = ref([]) + const dashboardResponse = ref(null) + const totalExecutions = ref(0); + const totalTokens = ref(0); + + + const userPrefStore = UserPrefStore() + const loadingStore = LoadingStore() + + async function fetchExecutionForProject() { //funzione che recupera le esecuzioni dei progetti + loadingStore.scenario_loading = true; + await DashboardScenarioService.getExecScenarioByProject(userPrefStore.selectedProject).then(resp => { + projectScenarios.value = resp.data; + allScenarios.value = [...projectScenarios.value] + loadingStore.scenario_loading = false; + }); + } + + //funzioni per la dashboard + async function loadProjects() { //carica tutti i progetti + try { + loadingStore.scenario_loading = true; + const response = await DashboardScenarioService.getProjects(); // prende i progetti dal back + projects.value = response.data; + } catch (err) { + console.error('Errore caricamento progetti:', err); + error.value = err.message || 'Errore durante il caricamento dei progetti'; + } finally { + loadingStore.scenario_loading = false; + } + } + + async function loadExecutions(filters) { //carica i dati per le esecuzioni + try { + loadingStore.scenario_loading = true; + const response = await DashboardScenarioService.getExecutions(filters); + + console.log("RISPOSTA RAW DA API:", response) + + executions.value = response.data + + } catch (err) { + console.error('Errore caricamento executions:', err); + error.value = err.message || 'Errore durante il caricamento delle esecuzioni'; + } finally { + loadingStore.scenario_loading = false; + } + } + + async function loadExecutionsStats (filters) { + try { + loadingStore.scenario_loading = true; + const response = await DashboardScenarioService.getExecutionsStats(filters); + + console.log("RISPOSTA RAW DA API:", response) + + dashboardResponse.value = response.data + + } catch (err) { + console.error('Errore caricamento executions:', err); + error.value = err.message || 'Errore durante il caricamento delle esecuzioni'; + } finally { + loadingStore.scenario_loading = false; + } + } + + async function loadUsers(filters) { + try { + loadingStore.scenario_loading = true; + const response = await DashboardScenarioService.getUsers(filters); + users.value = response.data; + return response; + } catch (err) { + console.error('Errore caricamento users:', err); + error.value = err.message || 'Errore durante il caricamento delle esecuzioni'; + } finally { + loadingStore.scenario_loading = false; + } + } + + async function loadChats(filters) { //carica i dati per la tabella della chat + try { + loadingStore.scenario_loading = true; + const response = await DashboardScenarioService.getChats(filters); + chats.value = response.data; + } catch (err) { + console.error('Errore caricamento chats:', err); + error.value = err.message || 'Errore durante il caricamento delle chat'; + } finally { + loadingStore.scenario_loading = false; + } + } + + async function loadScenarios(filters) { + try { + loadingStore.scenario_loading = true; + const response = await DashboardScenarioService.getScenarios(filters); + allScenarios.value = response.data; + return response; + } catch (err) { + console.error('Errore caricamento scenari:', err); + error.value = err.message || 'Errore durante il caricamento degli scenari'; + } finally { + loadingStore.scenario_loading = false; + } + } + + async function loadChatStats(filters) { + try { + loadingStore.scenario_loading = true; + const response = await DashboardScenarioService.getChatStats(filters); + + console.log("RISPOSTA :", response) + + chatStats.value = response.data + + } catch (err) { + console.error('Errore caricamento chat:', err); + error.value = err.message || 'Errore durante il caricamento delle chat'; + } finally { + loadingStore.scenario_loading = false; + } + } + + + + return { + fetchExecutionForProject, + projects, + executions, + chats, + error, + loadProjects, + loadExecutions, + loadChats, + loadUsers, + loadScenarios, + allScenarios, + dashboardResponse, + totalExecutions, + totalTokens, + loadExecutionsStats, + loadChatStats, + chatStats + } +}) \ No newline at end of file diff --git a/src/views/pages/DashExecution.vue b/src/views/pages/DashExecution.vue new file mode 100644 index 0000000..93fa7b7 --- /dev/null +++ b/src/views/pages/DashExecution.vue @@ -0,0 +1,1110 @@ + + + + Dashboard + + + + + + + + + + Date Range: + + + + + Account: + + + + + + Project: + + + + + + + + + Scenario: + + + + + + + + + + + + + + + + + + + + + + Executions Stats + + + + + + + {{ slotProps.data.projectName }} + + + + + + {{ slotProps.data.scenarioInternalName }} + + + + + + {{ slotProps.data.totalExecutions }} + + + + + + {{ slotProps.data.totalTokens }} + + + + + + {{ slotProps.data.totalChatInteractions }} + + + + + + + + + + + + Execution List + + + + + + + {{ moment(slotProps.data.startDate).format('DD-MM-YYYY HH:mm:ss') }} + + + + + + {{ slotProps.data.executedByUsername }} + + + + + + {{ slotProps.data.execSharedMap?.user_input?.selected_project || '' }} + + + + + + {{ slotProps.data.execSharedMap?.user_input?.selected_application || '' }} + + + + + + {{ slotProps.data.scenario?.name || '' }} + + + + + + + {{ slotProps.data.scenario?.category || '' }} + + + + + + + + {{ slotProps.data.scenario?.aiModel?.model || '' }} + + + + + + {{ slotProps.data.usedTokens || '' }} + + + + + + + + + + + + {{ + formatElapsed( + (new Date(slotProps.data.endDate) - new Date(slotProps.data.startDate)) / 1000 + ) + }} + + + + + + {{ slotProps.data.latestStepStatus === 'ERROR' ? 'N' : 'Y' }} + + + + + + No execution found + + + + + + + + + + + Chat List + + + + + + + + + + + + + No chat found + + + + + + + + + + + + + + + + + \ No newline at end of file