From 0bc568f833047da0535650d77d0584dee48b252a Mon Sep 17 00:00:00 2001 From: Emanuele Ferrelli Date: Thu, 12 Jun 2025 10:18:11 +0200 Subject: [PATCH 1/5] Update dashboard placeholders --- src/views/pages/DashExecution.vue | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/views/pages/DashExecution.vue b/src/views/pages/DashExecution.vue index 1ff4b4f..75d58bc 100644 --- a/src/views/pages/DashExecution.vue +++ b/src/views/pages/DashExecution.vue @@ -17,13 +17,13 @@
- +
- +
@@ -65,7 +65,7 @@
- +
From 00069dea296cd36767f503269317f4cc9f7136cc Mon Sep 17 00:00:00 2001 From: Emanuele Ferrelli Date: Thu, 12 Jun 2025 11:10:02 +0200 Subject: [PATCH 3/5] Update dashboard --- src/views/pages/DashExecution.vue | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/views/pages/DashExecution.vue b/src/views/pages/DashExecution.vue index 204205b..673f763 100644 --- a/src/views/pages/DashExecution.vue +++ b/src/views/pages/DashExecution.vue @@ -554,7 +554,7 @@ const loadData = async () => { ? selectedProjects.value .map((id) => { const project = projectOptions.value.find((p) => p.id === id); - return project ? project.fe_name : null; + return project ? project.internal_name : null; }) .filter(Boolean) : [], @@ -607,7 +607,7 @@ const loadData = async () => { ? selectedProjects.value .map((id) => { const project = projectOptions.value.find((p) => p.id === id); - return project ? project.fe_name : null; + return project ? project.internal_name : null; }) .filter(Boolean) : [], @@ -681,7 +681,10 @@ const onApplyFilters = async () => { // Funzione per cancellare filtri const onClearFilters = () => { - dateRange.value = null; + const today = new Date(); + const sevenDaysAgo = new Date(); + sevenDaysAgo.setDate(today.getDate() - 7); + dateRange.value = [sevenDaysAgo, today]; selectedAccount.value = null; selectedProjects.value = []; selectedApplications.value = []; @@ -703,7 +706,7 @@ onMounted(async () => { const lstProjects = userPrefStore.user?.lstProjects || []; console.log('Projects loaded:', lstProjects); - projectOptions.value = lstProjects.filter((p) => p.fe_name).map((p) => ({ ...p })); + projectOptions.value = lstProjects.filter((p) => p.fe_name || p.internal_name).map((p) => ({ ...p, internal_name: p.internal_name || p.fe_name })); selectedProjects.value = []; // Popola appOptions in base alle applicazioni nei progetti From bd5dd618d0005a14b88fb0ad1d00df0ac22b5740 Mon Sep 17 00:00:00 2001 From: "mariapia.lorusso" Date: Thu, 12 Jun 2025 15:47:26 +0200 Subject: [PATCH 4/5] fix date --- src/views/pages/DashExecution.vue | 63 +++++++++---------------------- 1 file changed, 18 insertions(+), 45 deletions(-) diff --git a/src/views/pages/DashExecution.vue b/src/views/pages/DashExecution.vue index 673f763..6df9683 100644 --- a/src/views/pages/DashExecution.vue +++ b/src/views/pages/DashExecution.vue @@ -443,17 +443,6 @@ const uniqueAccounts = computed(() => { return accounts.map((acc) => ({ name: acc, id: acc })); // usa anche `id` se serve per la picklist }); -// Filter progetti per account selezionato -// const filteredProjects = computed(() => { -// if (!projectOptions.value) return [] -// let filteredList = projectOptions.value - -// if (selectedAccount.value) { -// filteredList = filteredList.filter(p => p.account === selectedAccount.value.name) -// } - -// return filteredList; -// }) const onPage = (event) => { currentPageExecutions.value = event.page + 1; @@ -533,9 +522,20 @@ const exportAggregations = () => { document.body.removeChild(link); }; -// const exportChats = () => { -// if (chatTable.value) chatTable.value.exportCSV() -// } +const formatLocalDate = (date) => { + if (!date) return null; + const year = date.getFullYear(); + const month = String(date.getMonth() + 1).padStart(2, '0'); + const day = String(date.getDate()).padStart(2, '0'); + return `${year}-${month}-${day}`; +}; + +const formatLocalDateTo = (date) => { + if (!date) return null; + const nextDay = new Date(date); + nextDay.setDate(nextDay.getDate() + 1); + return formatLocalDate(nextDay); +}; // Caricamento dati con filtri const loadData = async () => { @@ -543,8 +543,8 @@ const loadData = async () => { try { const filterParams = { // Date - dateFrom: dateRange.value?.[0] ? dateRange.value[0].toISOString().split('T')[0] : null, - dateTo: dateRange.value?.[1] ? dateRange.value[1].toISOString().split('T')[0] : null, + dateFrom: formatLocalDate(dateRange.value?.[0]), + dateTo: null ? formatLocalDateTo(dateRange.value?.[0]):formatLocalDateTo(dateRange.value?.[1]), account: selectedAccount.value || null, @@ -558,33 +558,6 @@ const loadData = async () => { }) .filter(Boolean) : [], - - // // Applicazioni - // applicationIds: selectedApplications.value.length - // ? selectedApplications.value.map(id => String(id)) - // : [], - // applicationNames: selectedApplications.value.length - // ? selectedApplications.value - // .map(id => { - // const app = appOptions.value.find(a => a.id === id) - // return app ? app.fe_name : null - // }) - // .filter(Boolean) - // : [], - - // // Utenti - // userIds: selectedUsers.value.length - // ? selectedUsers.value.map(id => String(id)) - // : [], - // userNames: selectedUsers.value.length - // ? selectedUsers.value - // .map(id => { - // const user = userOptions.value.find(u => u.id === id) - // return user ? user.username : null - // }) - // .filter(Boolean) - // : [], - // Scenari scenarioIds: selectedScenarios.value.length ? selectedScenarios.value.map((id) => String(id)) : [], scenarioNames: selectedScenarios.value.length @@ -600,8 +573,8 @@ const loadData = async () => { console.log('Filter parameters:', filterParams); const chatParams = { - dateFrom: dateRange.value?.[0] ? dateRange.value[0].toISOString().split('T')[0] : null, - dateTo: dateRange.value?.[1] ? dateRange.value[1].toISOString().split('T')[0] : null, + dateFrom: formatLocalDate(dateRange.value?.[0]), + dateTo: null ? formatLocalDateTo(dateRange.value?.[0]):formatLocalDateTo(dateRange.value?.[1]), projectIds: selectedProjects.value.length ? selectedProjects.value.map((id) => String(id)) : [], projectNames: selectedProjects.value.length ? selectedProjects.value From e4bac5b2652d50c3312978fd3cc0a10fe05f8806 Mon Sep 17 00:00:00 2001 From: Emanuele Ferrelli Date: Thu, 12 Jun 2025 17:51:54 +0200 Subject: [PATCH 5/5] Fix login --- src/views/pages/auth/Callback.vue | 90 ++++++++++++++++++++----------- 1 file changed, 60 insertions(+), 30 deletions(-) diff --git a/src/views/pages/auth/Callback.vue b/src/views/pages/auth/Callback.vue index 7242b42..868f0ca 100644 --- a/src/views/pages/auth/Callback.vue +++ b/src/views/pages/auth/Callback.vue @@ -12,12 +12,13 @@ const visible = ref(false); onMounted(async () => { console.log('[Callback] Mounted on callback'); + try { await msalInstance.initialize(); console.log('[Callback] After initialize on callback'); } catch (e) { - console.error('[Callback] Errore durante initialize MSAL:', e); - message.value = "Errore durante l'inizializzazione di MSAL."; + console.error('[Callback] Error during MSAL initialization:', e); + message.value = "Error during MSAL initialization."; visible.value = true; return; } @@ -27,66 +28,95 @@ onMounted(async () => { response = await msalInstance.handleRedirectPromise(); console.log('[Callback] handleRedirectPromise response:', response); } catch (e) { - console.error('[Callback] Errore in handleRedirectPromise:', e); - message.value = 'Errore durante la gestione del redirect.'; + console.error('[Callback] Error in handleRedirectPromise:', e); + message.value = 'Error handling the redirect.'; visible.value = true; return; } if (response && response.accessToken) { + console.log('[Callback] Access token present:', response.accessToken); + + if (!response.account) { + console.warn('[Callback] No account present in the response. Possible MSAL anomaly.'); + } else { + console.log('[Callback] Account info:', response.account); + localStorage.setItem('msalUser', JSON.stringify(response.account)); + } + + // Wait 1 second to avoid race condition + await new Promise(resolve => setTimeout(resolve, 1000)); message.value = 'Logging in to the application...'; - console.log('[Callback] AccessToken presente:', response.accessToken); - console.log('[Callback] Account info:', response.account); - localStorage.setItem('msalUser', JSON.stringify(response.account)); - try { - console.log('[Callback] Chiamata a /msauth/exchange con accessToken...'); - const res = await axios.post( - '/msauth/exchange', - {}, - { - headers: { Authorization: `Bearer ${response.accessToken}` } + // Token exchange function with retry + const tryTokenExchange = async (retry = false) => { + try { + console.log(`[Callback] Call to /msauth/exchange (retry=${retry})...`); + const res = await axios.post( + '/msauth/exchange', + {}, + { + headers: { Authorization: `Bearer ${response.accessToken}` } + } + ); + return res; + } catch (err) { + if (!retry) { + console.warn('[Callback] First attempt failed, waiting 1500ms and retrying...'); + await new Promise(resolve => setTimeout(resolve, 1500)); + return tryTokenExchange(true); + } else { + throw err; } - ); - console.log('[Callback] Risposta da /msauth/exchange:', res); + } + }; + + let exchangeResponse; + try { + exchangeResponse = await tryTokenExchange(); + console.log('[Callback] Response from /msauth/exchange:', exchangeResponse); + + if (exchangeResponse.data.token) { + console.log('[Callback] Backend token received:', exchangeResponse.data.token); + auth.token(null, exchangeResponse.data.token, false); - if (res.data.token) { - console.log('[Callback] Token backend ricevuto:', res.data.token); - auth.token(null, res.data.token, false); try { - console.log('[Callback] Chiamata a auth.fetch()...'); + console.log('[Callback] Calling auth.fetch()...'); const userResponse = await auth.fetch(); - console.log('[Callback] Risposta user fetch:', userResponse); - console.log('[Callback] userResponse.data:', userResponse.data); - console.log('[Callback] userResponse.data.data:', userResponse.data.data); + console.log('[Callback] User fetch response:', userResponse); - if (!userResponse.data.data.selectedProject) { - console.log('[Callback] Nessun progetto selezionato, redirect a projects-list'); + const userData = userResponse.data?.data; + console.log('[Callback] userResponse.data.data:', userData); + + if (!userData || !userData.selectedProject) { + console.log('[Callback] No project selected, redirecting to projects-list'); router.push({ name: 'projects-list' }); } else { - console.log('[Callback] Progetto selezionato, redirect a scenario-list'); + console.log('[Callback] Project selected, redirecting to scenario-list'); router.push({ name: 'scenario-list' }); } } catch (fetchErr) { - console.error('[Callback] Errore su fetch user dopo token exchange:', fetchErr); + console.error('[Callback] Error fetching user after token exchange:', fetchErr); message.value = 'User not configured for this application. Contact the administrator for details.'; visible.value = true; } } else { + console.error('[Callback] No token received from backend:', exchangeResponse.data); message.value = 'User not configured for this application. Contact the administrator for details.'; - console.error('[Callback] Nessun token ricevuto dal backend:', res.data); + visible.value = true; } } catch (error) { - console.error('[Callback] Error on token exchange:', error.response ? error.response.data : error); + console.error('[Callback] Error on token exchange (after retry):', error.response ? error.response.data : error); message.value = 'An error occurred during the token exchange. Please try again.'; visible.value = true; } } else { - console.error('[Callback] Invalid response o access token mancante:', response); + console.error('[Callback] Invalid response or missing access token:', response); message.value = 'Authentication failed. Please log in again.'; visible.value = true; } }); +