mirror of
https://github.com/ParisNeo/lollms-webui.git
synced 2024-12-20 04:47:55 +00:00
enhanced ui
This commit is contained in:
parent
4c46dbf094
commit
f6991ecb44
10
app.py
10
app.py
@ -174,6 +174,10 @@ class LoLLMsWebUI(LoLLMsAPPI):
|
|||||||
self.add_endpoint(
|
self.add_endpoint(
|
||||||
"/list_bindings", "list_bindings", self.list_bindings, methods=["GET"]
|
"/list_bindings", "list_bindings", self.list_bindings, methods=["GET"]
|
||||||
)
|
)
|
||||||
|
self.add_endpoint(
|
||||||
|
"/list_extensions", "list_extensions", self.list_extensions, methods=["GET"]
|
||||||
|
)
|
||||||
|
|
||||||
self.add_endpoint(
|
self.add_endpoint(
|
||||||
"/list_models", "list_models", self.list_models, methods=["GET"]
|
"/list_models", "list_models", self.list_models, methods=["GET"]
|
||||||
)
|
)
|
||||||
@ -677,6 +681,10 @@ class LoLLMsWebUI(LoLLMsAPPI):
|
|||||||
print(f"Couldn't load backend card : {f}\n\t{ex}")
|
print(f"Couldn't load backend card : {f}\n\t{ex}")
|
||||||
return jsonify(bindings)
|
return jsonify(bindings)
|
||||||
|
|
||||||
|
def list_extensions(self):
|
||||||
|
return jsonify([])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def list_models(self):
|
def list_models(self):
|
||||||
if self.binding is not None:
|
if self.binding is not None:
|
||||||
@ -1312,7 +1320,7 @@ class LoLLMsWebUI(LoLLMsAPPI):
|
|||||||
def upload_avatar(self):
|
def upload_avatar(self):
|
||||||
file = request.files['avatar']
|
file = request.files['avatar']
|
||||||
file.save(self.lollms_paths.personal_user_infos_path/file.filename)
|
file.save(self.lollms_paths.personal_user_infos_path/file.filename)
|
||||||
return jsonify({"status": True,"file":file.filename})
|
return jsonify({"status": True,"fileName":file.filename})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
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
4
web/dist/index.html
vendored
@ -6,8 +6,8 @@
|
|||||||
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>LoLLMS WebUI - Welcome</title>
|
<title>LoLLMS WebUI - Welcome</title>
|
||||||
<script type="module" crossorigin src="/assets/index-45195456.js"></script>
|
<script type="module" crossorigin src="/assets/index-4c5ae20c.js"></script>
|
||||||
<link rel="stylesheet" href="/assets/index-2014a4be.css">
|
<link rel="stylesheet" href="/assets/index-562b86e9.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="app"></div>
|
<div id="app"></div>
|
||||||
|
@ -27,8 +27,7 @@ export const store = createStore({
|
|||||||
diskUsage:null,
|
diskUsage:null,
|
||||||
ramUsage:null,
|
ramUsage:null,
|
||||||
vramUsage:null,
|
vramUsage:null,
|
||||||
|
extensionsZoo:null,
|
||||||
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mutations: {
|
mutations: {
|
||||||
@ -63,6 +62,9 @@ export const store = createStore({
|
|||||||
state.vramUsage = vramUsage;
|
state.vramUsage = vramUsage;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setExtensionsZoo(state, extensionsZoo) {
|
||||||
|
state.extensionsZoo = extensionsZoo;
|
||||||
|
},
|
||||||
setModelsZoo(state, modelsZoo) {
|
setModelsZoo(state, modelsZoo) {
|
||||||
state.models_zoo = modelsZoo;
|
state.models_zoo = modelsZoo;
|
||||||
},
|
},
|
||||||
@ -104,6 +106,9 @@ export const store = createStore({
|
|||||||
getModelsZoo(state) {
|
getModelsZoo(state) {
|
||||||
return state.models_zoo;
|
return state.models_zoo;
|
||||||
},
|
},
|
||||||
|
getExtensionsZoo(state) {
|
||||||
|
return state.extensionsZoo;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
|
|
||||||
@ -192,6 +197,10 @@ export const store = createStore({
|
|||||||
let modelsArr = await api_get_req("list_models")
|
let modelsArr = await api_get_req("list_models")
|
||||||
commit('setModelsArr',modelsArr)
|
commit('setModelsArr',modelsArr)
|
||||||
},
|
},
|
||||||
|
async refreshExtensionsZoo({ commit }) {
|
||||||
|
let extensionsZoo = await api_get_req("list_extensions")
|
||||||
|
commit('setExtensionsZoo',extensionsZoo)
|
||||||
|
},
|
||||||
|
|
||||||
async refreshDiskUsage({ commit }) {
|
async refreshDiskUsage({ commit }) {
|
||||||
this.state.diskUsage = await api_get_req("disk_usage")
|
this.state.diskUsage = await api_get_req("disk_usage")
|
||||||
@ -350,6 +359,8 @@ app.mixin({
|
|||||||
this.$store.dispatch('refreshRamUsage');
|
this.$store.dispatch('refreshRamUsage');
|
||||||
this.$store.dispatch('refreshVramUsage');
|
this.$store.dispatch('refreshVramUsage');
|
||||||
this.$store.dispatch('refreshModelsZoo');
|
this.$store.dispatch('refreshModelsZoo');
|
||||||
|
this.$store.dispatch('refreshExtensionsZoo');
|
||||||
|
|
||||||
|
|
||||||
this.$store.state.ready = true
|
this.$store.state.ready = true
|
||||||
console.log("done loading data")
|
console.log("done loading data")
|
||||||
|
@ -50,9 +50,10 @@
|
|||||||
<div class=" sticky z-10 top-0 bg-bg-light-tone dark:bg-bg-dark-tone shadow-md">
|
<div class=" sticky z-10 top-0 bg-bg-light-tone dark:bg-bg-dark-tone shadow-md">
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!-- CONTROL PANEL -->
|
<!-- CONTROL PANEL -->
|
||||||
<div class="flex-row p-4 flex items-center gap-3 flex-0">
|
<div class="flex-row p-4 flex items-center gap-3 flex-0">
|
||||||
|
|
||||||
<!-- MAIN BUTTONS -->
|
<!-- MAIN BUTTONS -->
|
||||||
<button class="text-2xl hover:text-secondary duration-75 active:scale-90" title="Create new discussion"
|
<button class="text-2xl hover:text-secondary duration-75 active:scale-90" title="Create new discussion"
|
||||||
type="button" @click="createNewDiscussion()">
|
type="button" @click="createNewDiscussion()">
|
||||||
@ -84,6 +85,21 @@
|
|||||||
type="button" @click="isSearch = !isSearch" :class="isSearch ? 'text-secondary' : ''">
|
type="button" @click="isSearch = !isSearch" :class="isSearch ? 'text-secondary' : ''">
|
||||||
<i data-feather="search"></i>
|
<i data-feather="search"></i>
|
||||||
</button>
|
</button>
|
||||||
|
<button v-if="!showConfirmation" title="Save configuration" class="text-2xl hover:text-secondary duration-75 active:scale-90"
|
||||||
|
@click="showConfirmation = true">
|
||||||
|
<i data-feather="save"></i>
|
||||||
|
</button>
|
||||||
|
<!-- SAVE CONFIG -->
|
||||||
|
<div v-if="showConfirmation" class="flex gap-3 flex-1 items-center duration-75">
|
||||||
|
<button class="text-2xl hover:text-red-600 duration-75 active:scale-90 " title="Cancel" type="button"
|
||||||
|
@click.stop="showConfirmation = false">
|
||||||
|
<i data-feather="x"></i>
|
||||||
|
</button>
|
||||||
|
<button class="text-2xl hover:text-secondary duration-75 active:scale-90" title="Confirm save changes"
|
||||||
|
type="button" @click.stop="save_configuration()">
|
||||||
|
<i data-feather="check"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
<div v-if="loading" title="Loading.." class="flex flex-row flex-grow justify-end">
|
<div v-if="loading" title="Loading.." class="flex flex-row flex-grow justify-end">
|
||||||
<!-- SPINNER -->
|
<!-- SPINNER -->
|
||||||
<div role="status">
|
<div role="status">
|
||||||
@ -252,6 +268,7 @@
|
|||||||
|
|
||||||
<Toast ref="toast">
|
<Toast ref="toast">
|
||||||
</Toast>
|
</Toast>
|
||||||
|
<MessageBox ref="messageBox" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
||||||
@ -382,6 +399,26 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
save_configuration() {
|
||||||
|
this.showConfirmation = false
|
||||||
|
axios.post('/save_settings', {})
|
||||||
|
.then((res) => {
|
||||||
|
if (res) {
|
||||||
|
if (res.status) {
|
||||||
|
// this.$refs.messageBox.showMessage("Settings saved!")
|
||||||
|
}
|
||||||
|
else
|
||||||
|
this.$refs.messageBox.showMessage("Error: Couldn't save settings!")
|
||||||
|
return res.data;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.log(error.message, 'save_configuration')
|
||||||
|
this.$refs.messageBox.showMessage("Couldn't save settings!")
|
||||||
|
return { 'status': false }
|
||||||
|
});
|
||||||
|
|
||||||
|
},
|
||||||
showToastMessage(text){
|
showToastMessage(text){
|
||||||
console.log("sending",text)
|
console.log("sending",text)
|
||||||
this.$refs.toast.showToast(text, 4, true)
|
this.$refs.toast.showToast(text, 4, true)
|
||||||
@ -809,7 +846,7 @@ export default {
|
|||||||
|
|
||||||
let responseMessage = {
|
let responseMessage = {
|
||||||
//content:msgObj.data,
|
//content:msgObj.data,
|
||||||
content: "✍ please stand by ...",//msgObj.message,
|
content: msgObj.message,// "✍ please stand by ...",//msgObj.message,
|
||||||
created_at:msgObj.created_at,
|
created_at:msgObj.created_at,
|
||||||
binding:msgObj.binding,
|
binding:msgObj.binding,
|
||||||
model:msgObj.model,
|
model:msgObj.model,
|
||||||
@ -820,7 +857,6 @@ export default {
|
|||||||
sender: msgObj.bot,
|
sender: msgObj.bot,
|
||||||
type:msgObj.type,
|
type:msgObj.type,
|
||||||
steps: []
|
steps: []
|
||||||
//type: msgObj.type
|
|
||||||
|
|
||||||
}
|
}
|
||||||
this.discussionArr.push(responseMessage)
|
this.discussionArr.push(responseMessage)
|
||||||
@ -1398,9 +1434,13 @@ export default {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
getAvatar(sender) {
|
getAvatar(sender) {
|
||||||
|
if (sender.toLowerCase().trim() == this.$store.state.config.user_name.toLowerCase().trim()){
|
||||||
|
return "user_infos/"+this.$store.state.config.user_avatar
|
||||||
|
}
|
||||||
const index = this.personalityAvatars.findIndex((x) => x.name === sender)
|
const index = this.personalityAvatars.findIndex((x) => x.name === sender)
|
||||||
const pers = this.personalityAvatars[index]
|
const pers = this.personalityAvatars[index]
|
||||||
if (pers) {
|
if (pers) {
|
||||||
|
console.log("Avatar",pers.avatar)
|
||||||
return pers.avatar
|
return pers.avatar
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1584,6 +1624,7 @@ import Message from '../components/Message.vue'
|
|||||||
import ChatBox from '../components/ChatBox.vue'
|
import ChatBox from '../components/ChatBox.vue'
|
||||||
import WelcomeComponent from '../components/WelcomeComponent.vue'
|
import WelcomeComponent from '../components/WelcomeComponent.vue'
|
||||||
import Toast from '../components/Toast.vue'
|
import Toast from '../components/Toast.vue'
|
||||||
|
import MessageBox from "@/components/MessageBox.vue";
|
||||||
import DragDrop from '../components/DragDrop.vue'
|
import DragDrop from '../components/DragDrop.vue'
|
||||||
import feather from 'feather-icons'
|
import feather from 'feather-icons'
|
||||||
|
|
||||||
|
@ -1,16 +1,41 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
Extensions
|
<div v-for="extension in activeExtensions" :key="extension.name" @click="showExtensionPage(extension)">
|
||||||
|
<div :class="{ 'active-tab': extension === activeExtension }">{{ extension.name }}</div>
|
||||||
|
</div>
|
||||||
|
<div v-if="activeExtension">
|
||||||
|
<!-- Render the selected extension's page here -->
|
||||||
|
<iframe :src="activeExtension.page" width="100%" height="500px" frameborder="0"></iframe>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
setup () {
|
data() {
|
||||||
|
return {
|
||||||
|
activeExtension: null,
|
||||||
return {}
|
};
|
||||||
}
|
},
|
||||||
}
|
computed: {
|
||||||
|
activeExtensions() {
|
||||||
|
// Filter the extensions to get only active ones
|
||||||
|
return this.$store.state.extensionsZoo.filter((extension) => extension.is_active);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
showExtensionPage(extension) {
|
||||||
|
// Set the selected extension as active to render its page
|
||||||
|
this.activeExtension = extension;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.active-tab {
|
||||||
|
/* Style the active tab as you like */
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -533,7 +533,28 @@
|
|||||||
|
|
||||||
|
|
||||||
<table style="width: 100%;">
|
<table style="width: 100%;">
|
||||||
<!-- Row 1 -->
|
<tr>
|
||||||
|
<td style="min-width: 200px;">
|
||||||
|
<label for="enable_gpu" class="text-sm font-bold" style="margin-right: 1rem;">Enable GPU:</label>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
id="enable_gpu"
|
||||||
|
required
|
||||||
|
v-model="enable_gpu"
|
||||||
|
class="mt-1 px-2 py-1 border border-gray-300 rounded"
|
||||||
|
>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<button
|
||||||
|
class="hover:text-secondary bg-blue-100 m-2 p-2 duration-75 flex justify-center w-full hover:bg-bg-light-tone hover:dark:bg-bg-dark-tone rounded-lg"
|
||||||
|
@click="update_setting('enable_gpu', enable_gpu)"
|
||||||
|
>
|
||||||
|
<i data-feather="check"></i>
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td style="min-width: 200px;">
|
<td style="min-width: 200px;">
|
||||||
<label for="auto_update" class="text-sm font-bold" style="margin-right: 1rem;">Auto update:</label>
|
<label for="auto_update" class="text-sm font-bold" style="margin-right: 1rem;">Auto update:</label>
|
||||||
@ -547,12 +568,12 @@
|
|||||||
class="mt-1 px-2 py-1 border border-gray-300 rounded"
|
class="mt-1 px-2 py-1 border border-gray-300 rounded"
|
||||||
>
|
>
|
||||||
</td>
|
</td>
|
||||||
<td style="min-width: 300px;">
|
<td>
|
||||||
<button
|
<button
|
||||||
class="hover:text-secondary bg-blue-100 m-2 p-2 duration-75 flex justify-center w-full hover:bg-bg-light-tone hover:dark:bg-bg-dark-tone rounded-lg"
|
class="hover:text-secondary bg-blue-100 m-2 p-2 duration-75 flex justify-center w-full hover:bg-bg-light-tone hover:dark:bg-bg-dark-tone rounded-lg"
|
||||||
@click="update_setting('auto_update', auto_update)"
|
@click="update_setting('auto_update', auto_update)"
|
||||||
>
|
>
|
||||||
Validate
|
<i data-feather="check"></i>
|
||||||
</button>
|
</button>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -571,12 +592,12 @@
|
|||||||
class="w-full mt-1 px-2 py-1 border border-gray-300 rounded"
|
class="w-full mt-1 px-2 py-1 border border-gray-300 rounded"
|
||||||
>
|
>
|
||||||
</td>
|
</td>
|
||||||
<td style="min-width: 300px;">
|
<td>
|
||||||
<button
|
<button
|
||||||
class="hover:text-secondary bg-blue-100 m-2 p-2 duration-75 flex justify-center w-full hover:bg-bg-light-tone hover:dark:bg-bg-dark-tone rounded-lg"
|
class="hover:text-secondary bg-blue-100 m-2 p-2 duration-75 flex justify-center w-full hover:bg-bg-light-tone hover:dark:bg-bg-dark-tone rounded-lg"
|
||||||
@click="update_setting('db_path', db_path)"
|
@click="update_setting('db_path', db_path)"
|
||||||
>
|
>
|
||||||
Select Database
|
<i data-feather="check"></i>
|
||||||
</button>
|
</button>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -595,12 +616,12 @@
|
|||||||
class="w-full mt-1 px-2 py-1 border border-gray-300 rounded"
|
class="w-full mt-1 px-2 py-1 border border-gray-300 rounded"
|
||||||
>
|
>
|
||||||
</td>
|
</td>
|
||||||
<td style="min-width: 300px;">
|
<td>
|
||||||
<button
|
<button
|
||||||
class="hover:text-secondary bg-blue-100 m-2 p-2 duration-75 flex justify-center w-full hover:bg-bg-light-tone hover:dark:bg-bg-dark-tone rounded-lg"
|
class="hover:text-secondary bg-blue-100 m-2 p-2 duration-75 flex justify-center w-full hover:bg-bg-light-tone hover:dark:bg-bg-dark-tone rounded-lg"
|
||||||
@click="update_setting('user_name', userName)"
|
@click="update_setting('user_name', userName)"
|
||||||
>
|
>
|
||||||
Validate
|
<i data-feather="check"></i>
|
||||||
</button>
|
</button>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -615,12 +636,12 @@
|
|||||||
</label>
|
</label>
|
||||||
<input type="file" id="avatar-upload" style="display: none" @change="uploadAvatar">
|
<input type="file" id="avatar-upload" style="display: none" @change="uploadAvatar">
|
||||||
</td>
|
</td>
|
||||||
<td style="min-width: 300px;">
|
<td>
|
||||||
<button
|
<button
|
||||||
class="hover:text-secondary bg-blue-100 m-2 p-2 duration-75 flex justify-center w-full hover:bg-bg-light-tone hover:dark:bg-bg-dark-tone rounded-lg"
|
class="hover:text-secondary bg-blue-100 m-2 p-2 duration-75 flex justify-center w-full hover:bg-bg-light-tone hover:dark:bg-bg-dark-tone rounded-lg"
|
||||||
@click="update_setting('user_name', userName)"
|
@click="update_setting('user_name', userName)"
|
||||||
>
|
>
|
||||||
Validate
|
<i data-feather="check"></i>
|
||||||
</button>
|
</button>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -638,12 +659,12 @@
|
|||||||
class=" mt-1 px-2 py-1 border border-gray-300 rounded"
|
class=" mt-1 px-2 py-1 border border-gray-300 rounded"
|
||||||
>
|
>
|
||||||
</td>
|
</td>
|
||||||
<td style="min-width: 300px;">
|
<td>
|
||||||
<button
|
<button
|
||||||
class="hover:text-secondary bg-blue-100 m-2 p-2 duration-75 flex justify-center w-full hover:bg-bg-light-tone hover:dark:bg-bg-dark-tone rounded-lg"
|
class="hover:text-secondary bg-blue-100 m-2 p-2 duration-75 flex justify-center w-full hover:bg-bg-light-tone hover:dark:bg-bg-dark-tone rounded-lg"
|
||||||
@click="update_setting('use_user_name_in_discussions', use_user_name_in_discussions)"
|
@click="update_setting('use_user_name_in_discussions', use_user_name_in_discussions)"
|
||||||
>
|
>
|
||||||
Validate
|
<i data-feather="check"></i>
|
||||||
</button>
|
</button>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -1644,8 +1665,10 @@ export default {
|
|||||||
axios.post('/upload_avatar', formData)
|
axios.post('/upload_avatar', formData)
|
||||||
.then(response => {
|
.then(response => {
|
||||||
console.log("Avatar uploaded successfully")
|
console.log("Avatar uploaded successfully")
|
||||||
|
this.$refs.toast.showToast("Avatar uploaded successfully!", 4, true)
|
||||||
// Assuming the server responds with the file name after successful upload
|
// Assuming the server responds with the file name after successful upload
|
||||||
const fileName = response.fileName;
|
const fileName = response.data.fileName;
|
||||||
|
console.log("response",response);
|
||||||
this.user_avatar = fileName; // Update the user_avatar value with the file name
|
this.user_avatar = fileName; // Update the user_avatar value with the file name
|
||||||
this.update_setting("user_avatar", fileName, ()=>{}).then(()=>{})
|
this.update_setting("user_avatar", fileName, ()=>{}).then(()=>{})
|
||||||
})
|
})
|
||||||
@ -2355,8 +2378,13 @@ export default {
|
|||||||
if (res) {
|
if (res) {
|
||||||
this.isLoading = false
|
this.isLoading = false
|
||||||
console.log('update_setting', res)
|
console.log('update_setting', res)
|
||||||
|
if(res['status']){
|
||||||
|
this.$refs.toast.showToast("Setting updated successfully.\nDon't forget to save to keep the setting permanently.", 4, true)
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
this.$refs.toast.showToast("Setting update failed.\nPlease view the console for more details.", 4, false)
|
||||||
|
}
|
||||||
if (next !== undefined) {
|
if (next !== undefined) {
|
||||||
|
|
||||||
next(res)
|
next(res)
|
||||||
}
|
}
|
||||||
return res.data;
|
return res.data;
|
||||||
@ -2869,6 +2897,17 @@ export default {
|
|||||||
this.$store.state.config.user_avatar = value
|
this.$store.state.config.user_avatar = value
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
enable_gpu:{
|
||||||
|
get() {
|
||||||
|
return this.$store.state.config.enable_gpu;
|
||||||
|
},
|
||||||
|
set(value) {
|
||||||
|
// You should not set the value directly here; use the updateSetting method instead
|
||||||
|
this.$store.state.config.enable_gpu = value
|
||||||
|
},
|
||||||
|
|
||||||
|
},
|
||||||
auto_update:{
|
auto_update:{
|
||||||
get() {
|
get() {
|
||||||
return this.$store.state.config.auto_update;
|
return this.$store.state.config.auto_update;
|
||||||
|
Loading…
Reference in New Issue
Block a user