Merge pull request #242 from andzejsp/fixes-today

Fixes today
This commit is contained in:
Saifeddine ALOUI 2023-06-01 20:38:42 +02:00 committed by GitHub
commit 0ea87e01fb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 196 additions and 116 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

4
web/dist/index.html vendored
View File

@ -6,8 +6,8 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>GPT4All - WEBUI</title>
<script type="module" crossorigin src="/assets/index-98fca796.js"></script>
<link rel="stylesheet" href="/assets/index-dc46040e.css">
<script type="module" crossorigin src="/assets/index-a537b6af.js"></script>
<link rel="stylesheet" href="/assets/index-0f477b42.css">
</head>
<body>
<div id="app"></div>

View File

@ -8,7 +8,7 @@
<div class="flex flex-row items-center gap-3 ">
<img :src="getImgUrl()" @error="defaultImg($event)" class="w-10 h-10 rounded-full object-fill text-red-700">
<img ref="imgElement" :src="getImgUrl()" @error="defaultImg($event)" class="w-10 h-10 rounded-full object-fill text-blue-700">
<h3 class="font-bold font-large text-lg truncate">
{{ binding.name }}
</h3>
@ -92,8 +92,8 @@ export default {
})
this.getStatus()
// Disabled for now
//this.getStatus()
},

View File

@ -13,7 +13,7 @@
</div>
<div class="flex-1" v-if="!model.isCustomModel">
<div class="flex gap-3 items-center">
<img :src="getImgUrl()" @error="defaultImg($event)" class="w-10 h-10 rounded-lg object-fill" :class="linkNotValid ? 'grayscale':''">
<img ref="imgElement" :src="getImgUrl()" @error="defaultImg($event)" class="w-10 h-10 rounded-lg object-fill" :class="linkNotValid ? 'grayscale':''">
<h3 class="font-bold font-large text-lg">
{{ title }}
</h3>

View File

@ -4,7 +4,7 @@
<div class="flex flex-row items-center flex-shrink-0 gap-3">
<img :src="getImgUrl()" @error="defaultImg($event)" class="w-10 h-10 rounded-full object-fill text-red-700">
<img ref="imgElement" :src="getImgUrl()" @error="defaultImg($event)" class="w-10 h-10 rounded-full object-fill text-red-700">
<h3 class="font-bold font-large text-lg line-clamp-3">
{{ personality.name }}
</h3>

View File

@ -125,41 +125,43 @@
</div>
<div class="relative overflow-y-scroll no-scrollbar flex flex-row flex-grow" @dragover.stop.prevent="setDropZoneDiscussion()">
<div class="relative overflow-y-scroll no-scrollbar flex flex-row flex-grow"
@dragover.stop.prevent="setDropZoneDiscussion()">
<div class="z-20">
<DragDrop ref="dragdropDiscussion" @panelDrop="setFileListDiscussion">Drop your discussion file here</DragDrop>
</div >
<DragDrop ref="dragdropDiscussion" @panelDrop="setFileListDiscussion">Drop your discussion file here
</DragDrop>
</div>
<!-- DISCUSSION LIST -->
<div class="mx-4 flex-grow" :class="isDragOverDiscussion ? 'pointer-events-none' : ''">
<div class="mx-4 flex-grow" :class="isDragOverDiscussion ? 'pointer-events-none' : ''">
<div :class="filterInProgress ? 'opacity-20 pointer-events-none' : ''">
<TransitionGroup v-if="list.length > 0" name="list">
<Discussion v-for="(item, index) in list" :key="item.id" :id="item.id" :title="item.title"
:selected="currentDiscussion.id == item.id" :loading="item.loading" :isCheckbox="isCheckbox"
:checkBoxValue="item.checkBoxValue" @select="selectDiscussion(item)"
@delete="deleteDiscussion(item.id)" @editTitle="editTitle" @checked="checkUncheckDiscussion" />
</TransitionGroup>
<div v-if="list.length < 1"
class="gap-2 py-2 my-2 hover:shadow-md hover:bg-primary-light dark:hover:bg-primary rounded-md p-2 duration-75 group cursor-pointer">
<p class="px-3">No discussions are found</p>
</div>
<div
class="sticky bottom-0 bg-gradient-to-t pointer-events-none from-bg-light-tone dark:from-bg-dark-tone flex flex-grow">
<!-- FADING DISCUSSION LIST END ELEMENT -->
<div :class="filterInProgress ? 'opacity-20 pointer-events-none' : ''">
<TransitionGroup v-if="list.length > 0" name="list">
<Discussion v-for="(item, index) in list" :key="item.id" :id="item.id" :title="item.title"
:selected="currentDiscussion.id == item.id" :loading="item.loading" :isCheckbox="isCheckbox"
:checkBoxValue="item.checkBoxValue" @select="selectDiscussion(item)"
@delete="deleteDiscussion(item.id)" @editTitle="editTitle" @checked="checkUncheckDiscussion" />
</TransitionGroup>
<div v-if="list.length < 1"
class="gap-2 py-2 my-2 hover:shadow-md hover:bg-primary-light dark:hover:bg-primary rounded-md p-2 duration-75 group cursor-pointer">
<p class="px-3">No discussions are found</p>
</div>
<div
class="sticky bottom-0 bg-gradient-to-t pointer-events-none from-bg-light-tone dark:from-bg-dark-tone flex flex-grow">
<!-- FADING DISCUSSION LIST END ELEMENT -->
</div>
</div>
</div>
</div>
</div>
</div>
<div class="flex relative flex-grow overflow-y-auto scrollbar-thin scrollbar-track-bg-light-tone scrollbar-thumb-bg-light-tone-panel hover:scrollbar-thumb-primary dark:scrollbar-track-bg-dark-tone dark:scrollbar-thumb-bg-dark-tone-panel dark:hover:scrollbar-thumb-primary active:scrollbar-thumb-secondary" @dragover.stop.prevent="setDropZoneChat()">
<div id="messages-list"
class="flex relative flex-grow overflow-y-auto scrollbar-thin scrollbar-track-bg-light-tone scrollbar-thumb-bg-light-tone-panel hover:scrollbar-thumb-primary dark:scrollbar-track-bg-dark-tone dark:scrollbar-thumb-bg-dark-tone-panel dark:hover:scrollbar-thumb-primary active:scrollbar-thumb-secondary"
@dragover.stop.prevent="setDropZoneChat()">
<div class="z-20">
<DragDrop ref="dragdropChat" @panelDrop="setFileListChat"></DragDrop>
</div>
<div :class="isDragOverChat ? 'pointer-events-none' : ''"
class="container flex flex-col flex-grow "
id="messages-list">
<div :class="isDragOverChat ? 'pointer-events-none' : ''" class="container flex flex-col flex-grow ">
<!-- CHAT AREA -->
<div class="conainer flex flex-col flex-grow pt-4 pb-10 ">
@ -286,6 +288,13 @@ export default {
this.discussionArr = res.data.filter((item) => item.type == 0)
}
// nextTick(() => {
// const msgList = document.getElementById('messages-list')
// this.scrollBottom(msgList)
// })
}
} catch (error) {
console.log(error.message, 'load_discussion')
@ -644,7 +653,10 @@ export default {
if (messageItem) {
messageItem.content = msgObj.data
}
nextTick(() => {
const msgList = document.getElementById('messages-list')
this.scrollBottom(msgList)
})
}
},
@ -867,6 +879,10 @@ export default {
this.isGenerating = false
this.setDiscussionLoading(this.currentDiscussion.id, this.isGenerating)
console.log("Stopped generating")
nextTick(() => {
const msgList = document.getElementById('messages-list')
this.scrollBottom(msgList)
})
},
finalMsgEvent(msgObj) {
console.log("final", msgObj)
@ -881,6 +897,11 @@ export default {
messageItem.content = msgObj.data
}
}
nextTick(() => {
const msgList = document.getElementById('messages-list')
this.scrollBottom(msgList)
})
this.isGenerating = false
this.setDiscussionLoading(this.currentDiscussion.id, this.isGenerating)
@ -909,15 +930,15 @@ export default {
a.click();
document.body.removeChild(a);
},
parseJsonObj(obj){
parseJsonObj(obj) {
try {
const ret = JSON.parse(obj)
return ret
const ret = JSON.parse(obj)
return ret
} catch (error) {
this.$refs.toast.showToast("Could not parse JSON. \n"+error.message, 4, false)
this.$refs.toast.showToast("Could not parse JSON. \n" + error.message, 4, false)
return null
}
},
async parseJsonFile(file) {
@ -1049,10 +1070,10 @@ export default {
},
async setFileListDiscussion(files) {
if(files.length > 1){
if (files.length > 1) {
this.$refs.toast.showToast("Failed to import discussions. Too many files", 4, false)
return
return
}
const obj = await this.parseJsonFile(files[0])
@ -1098,7 +1119,7 @@ export default {
},
async activated() {
// This lifecycle hook runs every time you switch from other page back to this page (vue-router)
// To fix scrolling back to last message, this hook is needed.
// If anyone knows hor to fix scroll issue when changing pages, please do fix it :D
@ -1108,6 +1129,13 @@ export default {
if (this.isCreated) {
this.loadLastUsedDiscussion()
nextTick(() => {
const msgList = document.getElementById('messages-list')
this.scrollBottom(msgList)
})
}
},
components: {

View File

@ -79,7 +79,14 @@
<div v-if="configFile.binding"
class=" text-base font-semibold cursor-pointer select-none items-center">
{{ configFile.binding }} </div>
<div class="flex gap-1 items-center">
<img :src="imgBinding" class="w-8 h-8 rounded-full object-fill text-blue-700">
<h3 class="font-bold font-large text-lg">
{{ configFile.binding }}
</h3>
</div>
</div>
</button>
</div>
<div :class="{ 'hidden': bzc_collapsed }" class="flex flex-col mb-2 px-3 pb-0">
@ -100,11 +107,11 @@
<label for="binding" class="block ml-2 mb-2 text-sm font-medium text-gray-900 dark:text-white">
Bindings: ({{ bindings.length }})
</label>
<div ref="bindingZoo"
<div
class="overflow-y-auto no-scrollbar p-2 pb-0 grid lg:grid-cols-3 md:grid-cols-2 gap-4"
:class="bzl_collapsed ? '' : 'max-h-96'">
<TransitionGroup name="list">
<BindingEntry v-for="(binding, index) in bindings"
<BindingEntry ref="bindingZoo" v-for="(binding, index) in bindings"
:key="'index-' + index + '-' + binding.folder" :binding="binding"
:on-selected="onSelectedBinding" :selected="binding.folder === configFile.binding">
</BindingEntry>
@ -137,16 +144,27 @@
<i :data-feather="mzc_collapsed ? 'chevron-right' : 'chevron-down'" class="mr-2"></i>
<h3 class="text-lg font-semibold cursor-pointer select-none mr-2">
Models zoo</h3>
<div class="flex flex-row items-center">
<div v-if="!isModelSelected" class="text-base text-red-600 flex gap-3 items-center mr-2">
<i data-feather="alert-triangle"></i>
No model selected!
</div>
<div v-if="configFile.model" class="mr-2">|</div>
<div v-if="configFile.model"
class=" text-base font-semibold cursor-pointer select-none items-center">
{{ configFile.model }} </div> </div>
<div class="flex flex-row items-center">
<div v-if="!isModelSelected" class="text-base text-red-600 flex gap-3 items-center mr-2">
<i data-feather="alert-triangle"></i>
No model selected!
</div>
<div v-if="configFile.model" class="mr-2">|</div>
<div v-if="configFile.model"
class=" text-base font-semibold cursor-pointer select-none items-center">
<div class="flex gap-1 items-center">
<img :src="imgModel" class="w-8 h-8 rounded-lg object-fill">
<h3 class="font-bold font-large text-lg">
{{ configFile.model }}
</h3>
</div>
</div>
</div>
</button>
</div>
<div :class="{ 'hidden': mzc_collapsed }" class="flex flex-col mb-2 px-3 pb-0">
@ -172,14 +190,15 @@
Models: ({{ models.length }})
</label>
<div ref="modelZoo" class="overflow-y-auto no-scrollbar p-2 pb-0 "
:class="mzl_collapsed ? '' : 'max-h-96'">
<div class="overflow-y-auto no-scrollbar p-2 pb-0 " :class="mzl_collapsed ? '' : 'max-h-96'">
<TransitionGroup name="list">
<model-entry v-for="(model, index) in models" :key="'index-' + index + '-' + model.title"
:title="model.title" :icon="model.icon" :path="model.path" :owner="model.owner"
:owner_link="model.owner_link" :license="model.license" :description="model.description"
<model-entry ref="modelZoo" v-for="(model, index) in models"
:key="'index-' + index + '-' + model.title" :title="model.title" :icon="model.icon"
:path="model.path" :owner="model.owner" :owner_link="model.owner_link"
:license="model.license" :description="model.description"
:is-installed="model.isInstalled" :on-install="onInstall" :on-uninstall="onUninstall"
:on-selected="onSelected" :selected="model.title === configFile.model" :model="model" :model_type="model.model_type" />
:on-selected="onSelected" :selected="model.title === configFile.model" :model="model"
:model_type="model.model_type" />
</TransitionGroup>
</div>
</div>
@ -213,7 +232,15 @@
<div v-if="configFile.personality"
class=" text-base font-semibold cursor-pointer select-none items-center">
{{ configFile.personality }} </div>
<div class="flex gap-1 items-center">
<img :src="imgPersonality" class="w-8 h-8 rounded-full object-fill text-red-700">
<h3 class="font-bold font-large text-lg">
{{ configFile.personality }}
</h3>
</div>
</div>
</button>
</div>
<div :class="{ 'hidden': pzc_collapsed }" class="flex flex-col mb-2 px-3 pb-0">
@ -262,11 +289,11 @@
<label for="model" class="block ml-2 mb-2 text-sm font-medium text-gray-900 dark:text-white">
Personalities: ({{ personalitiesFiltered.length }})
</label>
<div ref="personalitiesZoo"
<div
class="overflow-y-auto no-scrollbar p-2 pb-0 grid lg:grid-cols-3 md:grid-cols-2 gap-4"
:class="pzl_collapsed ? '' : 'max-h-96'">
<TransitionGroup name="bounce">
<personality-entry v-for="(pers, index) in personalitiesFiltered"
<personality-entry ref="personalitiesZoo" v-for="(pers, index) in personalitiesFiltered"
:key="'index-' + index + '-' + pers.name" :personality="pers"
:selected="pers.name === configFile.personality && pers.category === configFile.personality_category && pers.language === configFile.personality_language"
:on-selected="onPersonalitySelected" />
@ -570,7 +597,8 @@ export default {
isLoading: false,
settingsChanged: false,
isModelSelected: false,
diskUsage: {}
diskUsage: {},
isMounted: false // Needed to wait for $refs to be rendered
}
@ -631,17 +659,17 @@ export default {
this.$refs.toast.showToast("Loading... please wait", 4, false)
}
if (pers.personality) {
if(this.configFile.personality != pers.personality.name){
if (this.configFile.personality != pers.personality.name) {
this.settingsChanged = true
const res = this.update_setting('personality', pers.personality.folder, () => {
this.$refs.toast.showToast("Selected personality:\n" + pers.personality.name, 4, true)
this.configFile.personality = pers.personality.name
this.configFile.personality_category = pers.personality.category
this.configFile.personality_language = pers.personality.language
})
}
this.settingsChanged = true
const res = this.update_setting('personality', pers.personality.folder, () => {
this.$refs.toast.showToast("Selected personality:\n" + pers.personality.name, 4, true)
this.configFile.personality = pers.personality.name
this.configFile.personality_category = pers.personality.category
this.configFile.personality_language = pers.personality.language
})
}
nextTick(() => {
feather.replace()
@ -713,9 +741,9 @@ export default {
this.showProgress = false;
model_object.installing = false
this.$refs.toast.showToast("Model:\n" + model_object.title + "\ninstalled!", 4, true)
this.api_get_req("disk_usage").then(response =>{
this.diskUsage=response
})
this.api_get_req("disk_usage").then(response => {
this.diskUsage = response
})
} else if (response.status === 'failed') {
socket.off('install_progress', progressListener);
console.log("Install failed")
@ -725,9 +753,9 @@ export default {
this.showProgress = false;
console.error('Installation failed:', response.error);
this.$refs.toast.showToast("Model:\n" + model_object.title + "\nfailed to install!", 4, false)
this.api_get_req("disk_usage").then(response =>{
this.diskUsage=response
})
this.api_get_req("disk_usage").then(response => {
this.diskUsage = response
})
}
};
@ -753,9 +781,9 @@ export default {
this.models = this.models.filter((model) => model.title !== model_object.title)
}
this.$refs.toast.showToast("Model:\n" + model_object.title + "\nwas uninstalled!", 4, true)
this.api_get_req("disk_usage").then(response =>{
this.diskUsage=response
})
this.api_get_req("disk_usage").then(response => {
this.diskUsage = response
})
} else if (response.status === 'failed') {
// Installation failed or encountered an error
model_object.uninstalling = false;
@ -764,9 +792,9 @@ export default {
// eslint-disable-next-line no-undef
console.error('Uninstallation failed:', message.error);
this.$refs.toast.showToast("Model:\n" + model_object.title + "\nfailed to uninstall!", 4, false)
this.api_get_req("disk_usage").then(response =>{
this.diskUsage=response
})
this.api_get_req("disk_usage").then(response => {
this.diskUsage = response
})
}
};
@ -775,17 +803,18 @@ export default {
socket.emit('uninstall_model', { path: model_object.path });
},
onSelectedBinding(binding_object) {
if(this.configFile.binding != binding_object.binding.folder){
if (this.configFile.binding != binding_object.binding.folder) {
if(binding_object.binding.folder ==='backend_template' || binding_object.binding.folder==='binding_template'){
this.$refs.toast.showToast("Cannot select template", 4, false)
return
// disabled for now
// if (binding_object.binding.folder === 'backend_template' || binding_object.binding.folder === 'binding_template') {
// this.$refs.toast.showToast("Cannot select template", 4, false)
// return
// }
this.update_binding(binding_object.binding.folder)
//console.log('lol',binding_object)
}
this.update_binding(binding_object.binding.folder)
//console.log('lol',binding_object)
}
},
// messagebox ok stuff
onMessageBoxOk() {
@ -818,8 +847,8 @@ if(this.configFile.binding != binding_object.binding.folder){
}
});
})
this.api_get_req("disk_usage").then(response =>{
this.diskUsage=response
this.api_get_req("disk_usage").then(response => {
this.diskUsage = response
})
this.getPersonalitiesArr()
this.fetchModels();
@ -852,7 +881,7 @@ if(this.configFile.binding != binding_object.binding.folder){
// eslint-disable-next-line no-unused-vars
this.isLoading = true
this.update_setting('binding', value, (res) => {
this.refresh();
@ -865,11 +894,11 @@ if(this.configFile.binding != binding_object.binding.folder){
})
// If binding changes then reset model
this.update_model(null)
this.configFile.model=null
this.configFile.model = null
this.api_get_req("disk_usage").then(response =>{
this.diskUsage=response
})
this.api_get_req("disk_usage").then(response => {
this.diskUsage = response
})
})
},
@ -964,7 +993,7 @@ if(this.configFile.binding != binding_object.binding.folder){
const res = await axios.get("/" + endpoint);
if (res) {
return res.data
}
@ -1012,10 +1041,11 @@ if(this.configFile.binding != binding_object.binding.folder){
this.isLoading = false
},
computedFileSize(size){
computedFileSize(size) {
return filesize(size)
},
}, async mounted() {
this.isLoading = true
nextTick(() => {
@ -1037,6 +1067,9 @@ if(this.configFile.binding != binding_object.binding.folder){
this.bindings = await this.api_get_req("list_bindings")
this.isLoading = false
this.diskUsage = await this.api_get_req("disk_usage")
this.isMounted = true
console.log('reffy', this.$refs.bindingZoo)
},
computed: {
available_space() {
@ -1047,11 +1080,30 @@ if(this.configFile.binding != binding_object.binding.folder){
},
percent_usage() {
return this.diskUsage.percent_usage
},
total_space() {
return this.computedFileSize(this.diskUsage.total_space)
},
imgBinding() {
if (!this.isMounted) {
return
}
return this.$refs.bindingZoo[this.$refs.bindingZoo.findIndex(item => item.binding.folder == this.configFile.binding)].$refs.imgElement.src
},
imgModel() {
if (!this.isMounted) {
return
}
return this.$refs.modelZoo[this.$refs.modelZoo.findIndex(item => item.title == this.configFile.model)].$refs.imgElement.src
},
imgPersonality() {
if (!this.isMounted) {
return
}
return this.$refs.personalitiesZoo[this.$refs.personalitiesZoo.findIndex(item => item.personality.name == this.configFile.personality)].$refs.imgElement.src
},
},
watch: {
bec_collapsed() {