Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle HTTP errors in links #9

41 changes: 37 additions & 4 deletions components/Element/ChatbotLinkItem.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,26 @@
<div v-else>
<div class="px-4 pt-3.5 pb-4 flex items-start justify-between space-x-4
text-white"
:class="(indexed)?'bg-gradient-to-br from-slate-700 to-slate-950':'bg-gradient-to-br from-red-700 to-slate-950'">
<a class="text-lg leading-snug break-words" target="_blank" :href="item.cmetadata?.url">{{ item.cmetadata?.url }}</a>
:class="{
'bg-gradient-to-br from-slate-700 to-slate-950': (indexed && !httperror),
'bg-gradient-to-br from-orange-700 to-slate-950': (indexed && httperror),
'bg-gradient-to-br from-red-700 to-slate-950': (!indexed),
}">
<div>
<a class="text-lg leading-snug break-words" target="_blank" :href="item.cmetadata?.url">{{ item.cmetadata?.url }}</a>
<p v-if="httperror" class="text-xs italic">Errore nella lettura del contenuto - codice errore {{httperror}}</p>
</div>
<div class="px-4 flex items-start justify-between space-x-4">
<button v-if="indexed" class="button-transparent text-white hover:from-white hover:to-white hover:text-sky-500"
<button v-if="indexed && !httperror" class="button-transparent text-white hover:from-white hover:to-white hover:text-sky-500"
@click.stop.prevent="$openModal('DialogEditMetadata', {document: item})">
<Icon name="ph:code-bold" class="text-xl" />
</button>

<button v-if="indexed && httperror" class="button-transparent text-white hover:from-white hover:to-white hover:text-sky-500"
@click.stop.prevent="reindex(item.cmetadata.url, collectionid, item.cmetadata)">
<Icon name="ph:arrows-counter-clockwise-bold" class="text-xl" :class="(indexing)?'animate-spin':''"/>
</button>

<button class="text-sky-600 hover:text-sky-400" @click="editMode = true">
<Icon name="ph:pencil-simple-bold" class="text-2xl" />
<span class="sr-only">{{ $t('EDIT') }}</span>
Expand All @@ -33,7 +45,28 @@ defineProps({
required: true,
},
indexed: Boolean,
collectionid: String,
httperror: String,
});

const editMode = ref(false);
const indexing = ref(false)

const reindex = async(url: string, collection: string | undefined, metadata: any) => {
indexing.value = true;
try {
await $fetch(`/api/brevia/index/link`, {
method: 'POST',
body: {
link: url,
collection_id : collection,
metadata: metadata,
options: {},
},
});
indexing.value = false;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

after a reindex we should read the indexed document in order to see if a document has been actually indexed/updated or not

We should call GET /api/brevia/index/{collection_id}/{document_id} or GET /api/brevia/index/{collection_id}/document_metadata?document_id={document_id}

A user feedback is then needed + change of state (like http_error removal) if something has changed

} catch (err) {
console.log(err);
indexing.value = false;
}
}
</script>
75 changes: 60 additions & 15 deletions components/Element/ChatbotLinks.vue
Original file line number Diff line number Diff line change
@@ -1,26 +1,44 @@
<template>
<div class="flex flex-col space-y-10">
<!-- new -->
<div v-if="!addMode" class="flex flex-row justify-between ">
<div>
<button class="button button-secondary uppercase justify-between items-start px-3.5 text-left" @click="addMode = true" v-if="isLinkAddAllowed">
<span class="normal-case italic">{{ $t('CLIC_TO_ADD_LINK') }}</span>
<Icon name="ph:plus-bold" class="text-2xl shrink-0" />
</button>
<p class="mt-2 text-xs text-center sm:text-left text-slate-600" v-if="isDemo">
{{ $t('MAX_NUMBER_LINKS') }}: <span class="font-bold">{{ $config.public.demo.maxChatLinks }}</span>
</p>
<div class="flex md:flex-row flex-col md:justify-between gap-3">
<div v-if="!addMode" class="flex flex-row justify-between ">
<div>
<button class="button button-secondary uppercase justify-between items-start px-3.5 text-left" @click="addMode = true" v-if="isLinkAddAllowed">
<span class="normal-case italic md:text-base text-sm">{{ $t('CLIC_TO_ADD_LINK') }}</span>
<Icon name="ph:plus-bold" class="text-2xl shrink-0" />
</button>
<p class="mt-2 text-xs text-center sm:text-left text-slate-600" v-if="isDemo">
{{ $t('MAX_NUMBER_LINKS') }}: <span class="font-bold">{{ $config.public.demo.maxChatLinks }}</span>
</p>
</div>
</div>
</div>

<FormChatbotLink @close="closeForm" v-else />
<FormChatbotLink @close="closeForm" v-else />
<div class="flex flex-row gap-4 items-center">
<span class="self-center">{{ $t('FILTERS') }}</span>
<div class="w-52 h-full px-1 border rounded border-primary bg-white hover:bg-sky-100 focus:outline-primary text-primary hover:cursor-default" >
<div class="flex flex-row justify-between self-center my-2 p-1" @click="openSelect = !openSelect">
<span>{{ filterType }}</span>
<Icon class="text-xs self-center" name="ph:caret-down-bold"/>
</div>
<div v-if="openSelect" class="w-52 -mx-1 max-h-96 absolute z-50 bg-white border border-primary rounded shadow-md overflow-y-scroll">
<div
v-for="f,index in FILTERS" :class="(FILTERS[index] == filterType )?'bg-primary text-white':'hover:bg-primary hover:text-white'"
@click="filterType = FILTERS[index]; openSelect = !openSelect">
{{ f }}
</div>
</div>
</div>
</div>
</div>
<!-- existing -->
<div class="-my-6 ellipsis-loading text-sky-700"
v-if="isLoading"><span class="sr-only">loading...</span></div>
<div class="links space-y-6" v-else-if="links.length">
<div id="links" v-for="item in links" :key="item.custom_id">
<div id="links" v-for="item in filteredLinks()" :key="item.custom_id">
<div class="link" >
<ElementChatbotLinkItem :item="item" :indexed="checkindexed(item.custom_id)" @close="closeForm" />
<ElementChatbotLinkItem :item="item" :indexed="checkindexed(item.custom_id)" :httperror="checkHttpError(item.custom_id)" :collectionid="collection.uuid" @close="closeForm" />
</div>
</div>
</div>
Expand All @@ -32,12 +50,16 @@ const addMode = ref(false);
const isLoading = ref(true);
const statesStore = useStatesStore();
const collection = <any>statesStore.collection;
const FILTERS = ref(['All links', 'Indexed Links', 'Non Indexed Links', 'Error Links'])


const isDemo = statesStore.userHasRole('demo');
const isLinkAddAllowed = ref(false);
const links = ref([]);
let indexedItems = [];
const links = ref<any>([]);
let indexedItems = <any>[];
const integration = useIntegration();
const filterType = ref('All links');
const openSelect = ref(false);

const loadLinks = async () => {
isLoading.value = true;
Expand Down Expand Up @@ -72,6 +94,29 @@ const checkindexed = (id: string | undefined) => {
return true;
}

const checkHttpError = (id: string | undefined) => {
const it = indexedItems?.find((element :any) => element.custom_id == id );
if (!it) {
return null;
}
return it.cmetadata.http_error;
}

const filteredLinks = () => {
const referenceIds = indexedItems.map((item:any) => item.custom_id);
switch(filterType.value) {
case 'Indexed Links':
return links.value.filter((el:any) => referenceIds.includes(el.custom_id))
case 'Non Indexed Links':
return links.value.filter((el:any) => !referenceIds.includes(el.custom_id))
case 'Error Links':
const errorLinks = new Map(indexedItems.map((item: any) => [item.custom_id, item.cmetadata.http_error]));
return links.value.filter((el:any) => errorLinks.get(el.custom_id))
default:
return links.value;
}
}

watch(links, (newLinks) => {
isLinkAddAllowed.value = checkAddAllowed(newLinks);
});
Expand Down
1 change: 1 addition & 0 deletions locales/en/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
"FILE_TYPE_MUST_BE": "Accepted file type:",
"FILE_TYPE_NOT_ACCEPTED": "File type not supported",
"FILES": "Files",
"FILTERS": "Filters",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Intstead of Filters I would use Show as a label

"FIRST_NAME": "First name",
"FIRST_NAME_PLACEHOLDER": "Your first name",
"FIRST_NAME_ERROR": "The user name cannot be empty!",
Expand Down
1 change: 1 addition & 0 deletions locales/it/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
"FILE_TYPE_MUST_BE": "Il file deve essere in formato",
"FILE_TYPE_NOT_ACCEPTED": "Il tipo di file non è supportato",
"FILES": "File",
"FILTERS": "Filtri",
"FIRST_NAME": "Nome",
"FIRST_NAME_PLACEHOLDER": "Il tuo nome",
"FIRST_NAME_ERROR": "Il nome utente non può essere vuoto!",
Expand Down