perf: 更好的 list 可视化
This commit is contained in:
@@ -1,22 +1,26 @@
|
||||
<template>
|
||||
<h3 style="margin-bottom: 8px;" v-if="iterable && metadata[metadataKey]?.type === 'object'">
|
||||
{{metadata[metadataKey]?.description }}
|
||||
{{ metadata[metadataKey]?.description }}
|
||||
</h3>
|
||||
<v-card-text>
|
||||
<div v-for="(index, key) in iterable" :key="key" style="margin-bottom: 0.5px;" v-if="metadata[metadataKey]?.type === 'object' || metadata[metadataKey]?.config_template">
|
||||
<v-alert v-if="metadata[metadataKey].items[key]?.obvious_hint && metadata[metadataKey].items[key]?.hint" style="margin-bottom: 16px"
|
||||
:text="metadata[metadataKey].items[key]?.hint" :title="'💡 关于' + metadata[metadataKey].items[key]?.description"
|
||||
type="info" variant="tonal">
|
||||
<div v-for="(index, key) in iterable" :key="key" style="margin-bottom: 0.5px;"
|
||||
v-if="metadata[metadataKey]?.type === 'object' || metadata[metadataKey]?.config_template">
|
||||
<v-alert v-if="metadata[metadataKey].items[key]?.obvious_hint && metadata[metadataKey].items[key]?.hint"
|
||||
style="margin-bottom: 16px" :text="metadata[metadataKey].items[key]?.hint"
|
||||
:title="'💡 关于' + metadata[metadataKey].items[key]?.description" type="info" variant="tonal">
|
||||
</v-alert>
|
||||
|
||||
<div style="display: flex; align-items: center; justify-content: center; gap: 16px">
|
||||
<div style="width: 100%;" v-if="metadata[metadataKey].items[key]">
|
||||
<v-select v-if="metadata[metadataKey].items[key]?.options && !metadata[metadataKey].items[key]?.invisible" v-model="iterable[key]"
|
||||
variant="outlined" :items="metadata[metadataKey].items[key]?.options"
|
||||
:label="metadata[metadataKey].items[key]?.description + '(' + key + ')'" dense :disabled="metadata[metadataKey].items[key]?.readonly"></v-select>
|
||||
<v-text-field v-else-if="metadata[metadataKey].items[key]?.type === 'string' && !metadata[metadataKey].items[key]?.invisible"
|
||||
<v-select
|
||||
v-if="metadata[metadataKey].items[key]?.options && !metadata[metadataKey].items[key]?.invisible"
|
||||
v-model="iterable[key]" variant="outlined" :items="metadata[metadataKey].items[key]?.options"
|
||||
:label="metadata[metadataKey].items[key]?.description + '(' + key + ')'" dense
|
||||
:disabled="metadata[metadataKey].items[key]?.readonly"></v-select>
|
||||
<v-text-field
|
||||
v-else-if="metadata[metadataKey].items[key]?.type === 'string' && !metadata[metadataKey].items[key]?.invisible"
|
||||
v-model="iterable[key]" :label="metadata[metadataKey].items[key]?.description + '(' + key + ')'"
|
||||
variant="outlined" dense ></v-text-field>
|
||||
variant="outlined" dense></v-text-field>
|
||||
<v-text-field
|
||||
v-else-if="(metadata[metadataKey].items[key]?.type === 'int' || metadata[metadataKey].items[key]?.type === 'float') && !metadata[metadataKey].items[key]?.invisible"
|
||||
v-model="iterable[key]" :label="metadata[metadataKey].items[key]?.description + '(' + key + ')'"
|
||||
@@ -27,17 +31,11 @@
|
||||
<v-switch v-else-if="metadata[metadataKey].items[key]?.type === 'bool' && !metadata[metadataKey].items[key]?.invisible" v-model="iterable[key]"
|
||||
:label="metadata[metadataKey].items[key]?.description + '(' + key + ')'" color="primary"
|
||||
inset></v-switch>
|
||||
<v-combobox variant="outlined" v-else-if="metadata[metadataKey].items[key]?.type === 'list' && !metadata[metadataKey].items[key]?.invisible"
|
||||
v-model="iterable[key]" chips clearable
|
||||
:label="metadata[metadataKey].items[key]?.description + '(' + key + ')'" multiple
|
||||
prepend-icon="mdi-tag-multiple-outline">
|
||||
<template v-slot:selection="{ attrs, item, select, selected }">
|
||||
<v-chip v-bind="attrs" :model-value="selected" closable @click="select"
|
||||
@click:close="remove(item)">
|
||||
<strong>{{ item }}</strong>
|
||||
</v-chip>
|
||||
</template>
|
||||
</v-combobox>
|
||||
<ListConfigItem
|
||||
v-else-if="metadata[metadataKey].items[key]?.type === 'list' && !metadata[metadataKey].items[key]?.invisible"
|
||||
:value="iterable[key]"
|
||||
:label="metadata[metadataKey].items[key]?.description + '(' + key + ')'"/>
|
||||
|
||||
<div v-else-if="metadata[metadataKey].items[key]?.type === 'object' && !metadata[metadataKey].items[key]?.invisible"
|
||||
style="border: 1px solid #e0e0e0; padding: 8px; margin-bottom: 16px; border-radius: 10px;">
|
||||
<AstrBotConfig :metadata="metadata[metadataKey].items" :iterable="iterable[key]"
|
||||
@@ -59,44 +57,47 @@
|
||||
}}</v-tooltip>
|
||||
</v-btn>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<v-chip v-if="!metadata[metadataKey].items[key]?.invisible" color="primary">{{ metadata[metadataKey].items[key]?.type }}</v-chip>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
<div v-else>
|
||||
<v-alert v-if="metadata[metadataKey]?.obvious_hint && metadata[metadataKey]?.hint" style="margin-bottom: 16px"
|
||||
:text="metadata[metadataKey]?.hint" :title="'💡 关于' + metadata[metadataKey]?.description"
|
||||
type="info" variant="tonal">
|
||||
<v-alert v-if="metadata[metadataKey]?.obvious_hint && metadata[metadataKey]?.hint"
|
||||
style="margin-bottom: 16px" :text="metadata[metadataKey]?.hint"
|
||||
:title="'💡 关于' + metadata[metadataKey]?.description" type="info" variant="tonal">
|
||||
</v-alert>
|
||||
|
||||
<div style="display: flex; align-items: center; justify-content: center; gap: 16px">
|
||||
<div style="width: 100%;">
|
||||
<v-select v-if="metadata[metadataKey]?.options && !metadata[metadataKey]?.invisible" v-model="iterable[metadataKey]"
|
||||
variant="outlined" :items="metadata[metadataKey]?.options"
|
||||
:label="metadata[metadataKey]?.description + '(' + metadataKey+ ')'" dense :disabled="metadata[metadataKey]?.readonly"></v-select>
|
||||
<v-text-field v-else-if="metadata[metadataKey]?.type === 'string' && !metadata[metadataKey]?.invisible"
|
||||
v-model="iterable[metadataKey]" :label="metadata[metadataKey]?.description + '(' + metadataKey+ ')'"
|
||||
variant="outlined" dense ></v-text-field>
|
||||
<v-select v-if="metadata[metadataKey]?.options && !metadata[metadataKey]?.invisible"
|
||||
v-model="iterable[metadataKey]" variant="outlined" :items="metadata[metadataKey]?.options"
|
||||
:label="metadata[metadataKey]?.description + '(' + metadataKey + ')'" dense
|
||||
:disabled="metadata[metadataKey]?.readonly"></v-select>
|
||||
<v-text-field
|
||||
v-else-if="metadata[metadataKey]?.type === 'string' && !metadata[metadataKey]?.invisible"
|
||||
v-model="iterable[metadataKey]"
|
||||
:label="metadata[metadataKey]?.description + '(' + metadataKey + ')'" variant="outlined"
|
||||
dense></v-text-field>
|
||||
<v-text-field
|
||||
v-else-if="(metadata[metadataKey]?.type === 'int' || metadata[metadataKey]?.type === 'float') && !metadata[metadataKey]?.invisible"
|
||||
v-model="iterable[metadataKey]" :label="metadata[metadataKey]?.description + '(' + metadataKey+ ')'"
|
||||
variant="outlined" dense></v-text-field>
|
||||
<v-textarea v-else-if="metadata[metadataKey]?.type === 'text' && !metadata[metadataKey]?.invisible" v-model="iterable[metadataKey]"
|
||||
:label="metadata[metadataKey]?.description + '(' + metadataKey+ ')'" variant="outlined"
|
||||
v-model="iterable[metadataKey]"
|
||||
:label="metadata[metadataKey]?.description + '(' + metadataKey + ')'" variant="outlined"
|
||||
dense></v-text-field>
|
||||
<v-textarea v-else-if="metadata[metadataKey]?.type === 'text' && !metadata[metadataKey]?.invisible"
|
||||
v-model="iterable[metadataKey]"
|
||||
:label="metadata[metadataKey]?.description + '(' + metadataKey + ')'" variant="outlined"
|
||||
dense></v-textarea>
|
||||
<v-switch v-else-if="metadata[metadataKey]?.type === 'bool' && !metadata[metadataKey]?.invisible" v-model="iterable[metadataKey]"
|
||||
:label="metadata[metadataKey]?.description + '(' + metadataKey+ ')'" color="primary"
|
||||
<v-switch v-else-if="metadata[metadataKey]?.type === 'bool' && !metadata[metadataKey]?.invisible"
|
||||
v-model="iterable[metadataKey]"
|
||||
:label="metadata[metadataKey]?.description + '(' + metadataKey + ')'" color="primary"
|
||||
inset></v-switch>
|
||||
<v-combobox variant="outlined" v-else-if="metadata[metadataKey]?.type === 'list' && !metadata[metadataKey]?.invisible"
|
||||
v-model="iterable[metadataKey]" chips clearable
|
||||
:label="metadata[metadataKey]?.description + '(' + metadataKey+ ')'" multiple
|
||||
prepend-icon="mdi-tag-multiple-outline">
|
||||
<template v-slot:selection="{ attrs, item, select, selected }">
|
||||
<v-chip v-bind="attrs" :model-value="selected" closable @click="select"
|
||||
@click:close="remove(item)">
|
||||
<strong>{{ item }}</strong>
|
||||
</v-chip>
|
||||
</template>
|
||||
</v-combobox>
|
||||
<ListConfigItem
|
||||
v-else-if="metadata[metadataKey]?.type === 'list' && !metadata[metadataKey]?.invisible"
|
||||
:value="iterable[metadataKey]"
|
||||
:label="metadata[metadataKey]?.description + '(' + metadataKey+ ')'"/>
|
||||
<div v-else-if="metadata[metadataKey]?.type === 'object' && !metadata[metadataKey]?.invisible"
|
||||
style="border: 1px solid #e0e0e0; padding: 8px; margin-bottom: 16px; border-radius: 10px;">
|
||||
<AstrBotConfig :metadata="metadata[metadataKey].items" :iterable="iterable[metadataKey]"
|
||||
@@ -113,6 +114,10 @@
|
||||
}}</v-tooltip>
|
||||
</v-btn>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<v-chip v-if="!metadata[metadataKey]?.invisible" color="primary">{{ metadata[metadataKey]?.type }}</v-chip>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</v-card-text>
|
||||
@@ -120,8 +125,12 @@
|
||||
|
||||
<script>
|
||||
import { readonly } from 'vue';
|
||||
import ListConfigItem from './ListConfigItem.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
ListConfigItem
|
||||
},
|
||||
props: {
|
||||
metadata: Object,
|
||||
iterable: Object,
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
<template>
|
||||
<div class="list-config-item">
|
||||
<h3>{{ label }}</h3>
|
||||
<v-list dense style="background-color: transparent;max-height: 300px; overflow-y: scroll;" >
|
||||
<v-list-item v-for="(item, index) in items" :key="index">
|
||||
<v-list-item-content style="display: flex; justify-content: space-between;">
|
||||
<v-list-item-title>
|
||||
<v-chip>{{ item }}</v-chip>
|
||||
</v-list-item-title>
|
||||
<v-btn @click="removeItem(index)" variant="plain">
|
||||
<v-icon>mdi-close</v-icon>
|
||||
</v-btn>
|
||||
</v-list-item-content>
|
||||
</v-list-item>
|
||||
</v-list>
|
||||
<v-text-field
|
||||
v-model="newItem"
|
||||
label="添加新项"
|
||||
@keyup.enter="addItem"
|
||||
clearable
|
||||
dense
|
||||
hide-details
|
||||
variant="outlined"
|
||||
></v-text-field>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'ListConfigItem',
|
||||
props: {
|
||||
value: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
label: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
newItem: '',
|
||||
items: this.value,
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
items(newVal) {
|
||||
this.$emit('input', newVal);
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
addItem() {
|
||||
if (this.newItem.trim() !== '') {
|
||||
this.items.push(this.newItem.trim());
|
||||
this.newItem = '';
|
||||
}
|
||||
},
|
||||
removeItem(index) {
|
||||
this.items.splice(index, 1);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.list-config-item {
|
||||
border: 1px solid #e0e0e0;
|
||||
padding: 16px;
|
||||
margin-bottom: 16px;
|
||||
border-radius: 10px;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
.list-config-item h3 {
|
||||
margin-top: 0;
|
||||
margin-bottom: 16px;
|
||||
font-size: 18px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.v-list-item {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.v-list-item-title {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.v-btn {
|
||||
margin-left: 8px;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user