profiling + research + download

This commit is contained in:
Florinda
2024-11-27 09:33:08 +01:00
parent 818ed15ca0
commit ddd06350cd
15 changed files with 578 additions and 34 deletions

View File

@@ -0,0 +1,166 @@
<template>
<div>
<h1>Available Projects</h1>
</div>
<div v-if="loading" class="flex justify-center">
<ProgressSpinner style="width: 50px; height: 50px; margin-top: 50px" strokeWidth="3" fill="transparent" />
</div>
<div v-else>
<DataView :value="filter" :layout="layout" paginator :rows="8">
<template #header>
<div class="header-container">
<div class="search-bar">
<i class="pi pi-search search-icon"></i>
<InputText class="search-input" type="search" placeholder="Search" v-model="data.search"
size="medium" variant="filled" />
</div>
<SelectButton v-model="layout" :options="options" :allowEmpty="false" class="layout-switch">
<template #option="{ option }">
<i :class="[option === 'list' ? 'pi pi-bars' : 'pi pi-table']" />
</template>
</SelectButton>
</div>
</template>
<template #list="slotProps">
<div class="flex flex-col space-y-4 mt-2">
<div v-for="(item, index) in slotProps.items" :key="index">
<div class="flex flex-col sm:flex-row sm:items-center p-6 gap-4 bg-white dark:bg-gray-800 rounded-lg shadow-md"
:class="{ 'border-t border-gray-200 dark:border-gray-700': index !== 0 }">
<div class="flex flex-col flex-grow">
<h3 class="text-lg font-medium text-gray-900 dark:text-gray-100">{{ item.fe_name }}</h3>
<p class="text-sm font-medium text-gray-500 dark:text-gray-400 mt-2">{{ item.description
}}</p>
</div>
<div class="mt-auto flex justify-end">
<Button @click="openProject(item)" label="Load"
class="flex-auto md:flex-initial text-white">
<ChevronRightIcon
class="w-5 h-10 text-white transition-transform transform hover:translate-x-1" />
</Button>
</div>
</div>
</div>
</div>
</template>
<template #grid="slotProps">
<div class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-4 gap-4 mt-2">
<div v-for="(item, index) in slotProps.items" :key="index" class="p-2">
<div class="bg-white dark:bg-gray-800 rounded-lg shadow-md flex flex-col h-full">
<div class="p-4 flex flex-col flex-grow">
<h3 class="text-lg font-medium text-gray-900 dark:text-gray-100">{{ item.fe_name }}</h3>
<p class="text-sm font-medium text-gray-500 dark:text-gray-400 mt-2">{{ item.description
}}</p>
</div>
<div class="p-2 border-t border-gray-200 dark:border-gray-700 flex justify-end">
<Button @click="openProject(item)" size="small" label="Load"
class="flex-auto md:flex-initial text-white">
<ChevronRightIcon
class="w-6 h-5 text-white transition-transform transform hover:translate-x-1" />
</Button>
</div>
</div>
</div>
</div>
</template>
</DataView>
</div>
</template>
<script setup>
import { ChevronRightIcon } from '@heroicons/vue/24/solid';
import { useAuth } from '@websanova/vue-auth/src/v3.js';
import DataView from 'primevue/dataview';
import ProgressSpinner from 'primevue/progressspinner';
import { computed, onMounted, reactive, ref } from 'vue';
import { useRouter } from 'vue-router';
import { LoadingStore } from '../../stores/LoadingStore.js';
import { UserPrefStore } from '../../stores/UserPrefStore.js';
const loadingStore = LoadingStore()
const userPrefStore = UserPrefStore();
const auth = useAuth();
const user = computed(() => auth.user());
const router = useRouter()
const layout = ref('grid');
const options = ref(['list', 'grid']);
const loading = ref(false)
onMounted(() => {
data.projects = user.value.lstProjects;
});
const data = reactive({
search: null,
projects: []
})
const filter = computed(() => {
if (data.search) {
return data.projects.filter((item) => {
return data.search
.toLowerCase()
.split(" ")
.every((v) => item.name.toLowerCase().includes(v));
});
} else {
return data.projects;
}
});
const openProject = async (project) => {
try {
// Esegui l'update del progetto
await userPrefStore.updateSelectedProject(project);
console.log('Progetto aggiornato e dati utente ricaricati');
router.push({ path: '/ksdocuments' });
} catch (error) {
console.error('Errore nel cambio progetto:', error);
}
}
</script>
<style scoped>
.header-container {
display: flex;
justify-content: space-between;
align-items: center;
}
.search-bar {
display: flex;
align-items: center;
}
.search-icon {
color: #334155;
margin-right: 5px;
}
.search-input {
border: none;
outline: none;
box-shadow: none;
flex: 1;
}
.search-input:focus {
border: none;
box-shadow: none;
outline: none;
}
</style>

View File

@@ -4,29 +4,49 @@ import { useAuth } from '@websanova/vue-auth/src/v3.js';
import { computed, ref } from 'vue';
//import logo from '@/assets/Logo_Apollo_Transparent.png';
import logo from '@/assets/apollo.jpg';
import { useRouter } from 'vue-router';
const auth = useAuth();
const { isDarkTheme } = useLayout();
const username = ref('');
const password = ref('');
const logoSrc = ref(logo);
const router = useRouter();
const logoUrl = computed(() => {
return `/layout/images/${isDarkTheme ? 'logo-white' : 'logo-dark'}.svg`;
});
const login = () => {
console.log('Username: ', username.value);
const login = async () => {
try {
await auth.login({
data: {
"username": username.value,
"password": password.value
},
fetchUser: true
}).then((response) => {
console.log("1 user :", response.data.data);
auth.login({
data: {
"username": username.value,
"password": password.value
},
redirect: '/ksdocuments',
fetchUser: true,
//url: '/api/auth/login'
});
if (!response.data.data.selectedProject) {
router.push({ name: 'projects-list' });
} else {
router.push({ path: '/ksdocuments' });
}
console.log("response", response);
}).catch((err) => {
console.log("error", err);
error.value = 'Incorrect username or password. Please try again.';
visible.value = true;
setTimeout(() => {
visible.value = false;
}, 3500);
});
} catch (err) {
console.log('Error ' + err);
}
}
</script>

View File

@@ -2,7 +2,7 @@
<div class="card">
<Toast />
<ConfirmPopup></ConfirmPopup>
<div v-if="loading" class="loading-container">
<div v-if="loadingStore.another_loading" class="loading-container">
<div class="spinner-container">
<ProgressSpinner class="spinner" />
<p class="loading-text">Loading data...</p>
@@ -10,7 +10,7 @@
</div>
<DataTable v-model:filters="filters" :value="ksdocuments" paginator showGridlines :rows="10" dataKey="id"
filterDisplay="menu" :loading="loading"
filterDisplay="menu" :loading="loadingStore.another_loading"
:globalFilterFields="['ingestionInfo.metadata.KsApplicationName', 'ingestionInfo.metadata.KsFileSources', 'ingestionInfo.metadata.KsDocSource', 'ingestionStatus', 'ingestionDateFormat']">
<template #header>
<div class="flex items-center justify-between gap-4 p-4 ">
@@ -103,6 +103,12 @@
v-tooltip="'Delete the ingested Record'"
:disabled="slotProps.data.ingestionStatus === 'NEW'"
:class="{ 'p-button-danger': slotProps.data.ingestionStatus === 'NEW' }" />
<Button type="button" icon="pi pi-search" rounded @click="openSimilaritySearch(slotProps.data)"
v-tooltip="'Similarity Search'" :disabled="slotProps.data.ingestionStatus === 'NEW'"
:class="{ 'p-button-danger': slotProps.data.ingestionStatus === 'NEW' }" />
<Button type="button" icon="pi pi-download" rounded @click="downloadFile(slotProps.data)"
v-tooltip="'Download file'" :disabled="slotProps.data.ingestionStatus === 'NEW'"
:class="{ 'p-button-danger': slotProps.data.ingestionStatus === 'NEW' }" />
</div>
</template>
</Column>
@@ -120,7 +126,7 @@ import axios from 'axios';
import moment from 'moment';
import { useConfirm } from "primevue/useconfirm";
import { useToast } from 'primevue/usetoast';
import { computed, onMounted, ref } from 'vue';
import { computed, onMounted, ref, watch } from 'vue';
import { useRouter } from 'vue-router';
import Button from 'primevue/button';
@@ -132,7 +138,10 @@ import InputText from 'primevue/inputtext';
import ProgressSpinner from 'primevue/progressspinner';
import Select from 'primevue/select';
import Tag from 'primevue/tag';
import { KsDocumentService } from '../../../service/KsDocumentService';
import { KsDocumentStore } from '../../../stores/KsDocumentStore';
import { LoadingStore } from '../../../stores/LoadingStore';
import { UserPrefStore } from '../../../stores/UserPrefStore';
const router = useRouter()
const ksdocuments = ref(null);
@@ -143,6 +152,9 @@ const confirm = useConfirm();
const ingestionDialogVisible = ref(false);
const ingestionResult = ref('');
const filters = ref();
const userPrefStore = UserPrefStore();
const ksDocumentStore = KsDocumentStore();
const loadingStore = LoadingStore();
const initFilters = () => {
filters.value = {
@@ -161,14 +173,29 @@ initFilters();
const statuses = ref(['NEW', 'INGESTED', 'FAILED']); // Add your statuses here
onMounted(() => {
axios.get('/fe-api/ksdocuments')
.then(response => {
ksdocuments.value = getCustomDatewithAllResponse(response.data);
console.log(ksdocuments.value);
loading.value = false;
});
userPrefStore.fetchUserData().then(() => {
updateDocuments();
});
});
watch(() => userPrefStore.getSelApp, updateDocuments, { immediate: true });
function updateDocuments() {
//loading.value = true;
ksDocumentStore.fetchKsDocument().then(() => {
ksdocuments.value = getCustomDatewithAllResponse();
//loading.value = false;
});
};
// Computed property to check if all documents are ingested
const allDocumentsIngested = computed(() => {
return ksdocuments.value && ksdocuments.value.every(doc => doc.ingestionStatus === 'INGESTED');
@@ -185,8 +212,8 @@ const getStatus = (data) => {
}
}
const getCustomDatewithAllResponse = (data) => {
return [...(data || [])].map((d) => {
const getCustomDatewithAllResponse = () => {
return [...(ksDocumentStore.ksDocument || [])].map((d) => {
d.ingestionDateFormat = new Date(d.ingestionDateFormat);
return d;
});
@@ -196,11 +223,69 @@ const updateFilterModel = () => {
console.log("updateFilterModel")
}
// Variabile reattiva per il nome del file
const filename = ref("");
// Funzione per scaricare il file
const downloadFile = async (doc) => {
/*if (!filename.value) {
alert("Inserisci il nome del file.");
return;
}*/
console.log("doc", doc)
try {
//const response = await axios.post('/fe-api/ksdocuments/downloadKSDocument', doc, { responseType: "blob", });
const response = await KsDocumentService.downloadKsDocument(doc);
console.log("response download", response);
const contentType = response.headers['content-type']; // Tipo MIME dinamico
const blob = new Blob([response.data], { type: contentType });
// Crea un URL temporaneo per il download
const url = window.URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
const fileName = doc.fileName;
console.log("fileName", fileName)
// Imposta il nome e avvia il download
link.setAttribute('download', fileName);
document.body.appendChild(link);
link.click();
link.remove();
// Crea un URL temporaneo per il download del file
/*console.log("response download", response);
const url = window.URL.createObjectURL(new Blob([response.data]));
const link = document.createElement("a");
link.href = url;
link.setAttribute("download", filename.value); // Imposta il nome del file
document.body.appendChild(link);
link.click();
link.remove();*/
} catch (error) {
console.error("Errore durante il download:", error);
alert("Errore durante il download. Controlla il nome del file.");
}
};
const editKsDocument = (data) => {
console.log(data);
router.push({ name: 'ks-document-edit', params: { id: data.id } });
}
const openSimilaritySearch = (doc) => {
console.log("doc", doc)
ksDocumentStore.setSelectedKsDocument(doc).then(() => {
router.push({ name: 'ks_similarity_search' });
});
}
const confirmDelete = (id) => {
console.log("id", id);

View File

@@ -25,13 +25,15 @@
<div class="col-12 md:col-6 mb-4">
<span class="p-float-label">
<label for="ksProjectName" v-tooltip="'Enter the project name here.'">KS Project Name</label>
<InputText id="ksProjectName" v-model="formData.ksProjectName" required class="w-full" />
<InputText id="ksProjectName" v-model="userPrefStore.selectedProject.internal_name" required
class="w-full" />
</span>
</div>
<div class="col-12 md:col-6 mb-4">
<span class="p-float-label">
<label for="ksApplicationName" v-tooltip="'Enter the application name here.'">KS Application Name</label>
<InputText id="ksApplicationName" v-model="formData.ksApplicationName" required class="w-full" />
<InputText id="ksApplicationName" v-model="userPrefStore.getSelApp.internal_name" required
class="w-full" />
</span>
</div>
@@ -105,10 +107,11 @@ import axios from 'axios';
import { useToast } from 'primevue/usetoast';
import { ref } from 'vue';
import { useRouter } from 'vue-router';
import { UserPrefStore } from '../../../stores/UserPrefStore';
const toast = useToast();
const router = useRouter();
const userPrefStore = UserPrefStore();
const documentTypeOptions = ref([
{ name: 'Functional', value: 'functional' },
{ name: 'Code Instruction', value: 'code_instruction' },
@@ -145,8 +148,8 @@ const submitForm = async () => {
formDataToSend.append('description', formData.value.description);
formDataToSend.append('type', formData.value.type);
formDataToSend.append('ksApplicationName', formData.value.ksApplicationName);
formDataToSend.append('ksProjectName', formData.value.ksProjectName);
formDataToSend.append('ksApplicationName', userPrefStore.selectedProject.internal_name);
formDataToSend.append('ksProjectName', userPrefStore.getSelApp.internal_name);
formDataToSend.append('ksDocType', formData.value.ksDocType.value);
formDataToSend.append('ksDocSource', formData.value.ksDocSource);
formDataToSend.append('defaultChunkSize', formData.value.defaultChunkSize);

View File

@@ -35,13 +35,22 @@ import Card from 'primevue/card';
import ScrollPanel from 'primevue/scrollpanel';
import { useToast } from 'primevue/usetoast';
import { ref, watch } from 'vue';
import { KsDocumentStore } from '../../../stores/KsDocumentStore';
const query = ref('');
const dropdownItem = ref(null);
const messages = ref([]);
const toast = useToast();
const dynamicCode = ref('');
const filterQuery = ref("'KsApplicationName' == 'ATF'")
const ksDocumentStore = KsDocumentStore();
const doc = ksDocumentStore.getSelectedKsDocument;
//const filterQuery = ref("'KsApplicationName' == 'ATF'")
const filterQuery = ref("'KsApplicationName' == '" + doc.ingestionInfo.metadata.KsApplicationName
+ "' AND " + "'KsProjectName' == '" + doc.ingestionInfo.metadata.KsProjectName
+ "' AND " + "'KsFileSource' == '" + doc.ingestionInfo.metadata.KsFileSource
+ "' AND " + "'KsDocSource' == '" + doc.ingestionInfo.metadata.KsDocSource
+ "' AND " + "'KsDoctype' == '" + doc.ingestionInfo.metadata.KsDoctype + "'"
)
const dropdownItems = [
{ name: 'Documentation', code: 'setup-documentation' },