mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-02 17:30:23 +08:00
feat: add select all to access limit dropdowns
This commit is contained in:
@@ -55,6 +55,26 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="max-h-48 overflow-y-auto">
|
<div class="max-h-48 overflow-y-auto">
|
||||||
|
<div
|
||||||
|
v-if="hasOptions"
|
||||||
|
class="sticky top-0 z-10 flex cursor-pointer items-center gap-2 border-b bg-popover/95 px-3 py-2 backdrop-blur hover:bg-muted/50 supports-[backdrop-filter]:bg-popover/85"
|
||||||
|
@click="toggleAll"
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
:checked="isAllSelected"
|
||||||
|
:indeterminate="isPartiallySelected"
|
||||||
|
aria-label="全选"
|
||||||
|
class="h-4 w-4 shrink-0 cursor-pointer rounded border-gray-300"
|
||||||
|
@click.stop
|
||||||
|
@change="toggleAll"
|
||||||
|
>
|
||||||
|
<span class="min-w-0 truncate text-sm">全选</span>
|
||||||
|
<span class="ml-auto shrink-0 text-xs text-muted-foreground">
|
||||||
|
{{ selectedOptionCount }}/{{ options.length }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
v-for="item in filteredInvalidItems"
|
v-for="item in filteredInvalidItems"
|
||||||
:key="'invalid-' + item"
|
:key="'invalid-' + item"
|
||||||
@@ -152,6 +172,20 @@ const invalidItems = computed(() =>
|
|||||||
|
|
||||||
const totalCount = computed(() => props.options.length + invalidItems.value.length)
|
const totalCount = computed(() => props.options.length + invalidItems.value.length)
|
||||||
|
|
||||||
|
const hasOptions = computed(() => props.options.length > 0)
|
||||||
|
|
||||||
|
const selectedOptionCount = computed(
|
||||||
|
() => new Set(props.modelValue.filter(v => validValues.value.has(v))).size,
|
||||||
|
)
|
||||||
|
|
||||||
|
const isAllSelected = computed(
|
||||||
|
() => hasOptions.value && selectedOptionCount.value === props.options.length,
|
||||||
|
)
|
||||||
|
|
||||||
|
const isPartiallySelected = computed(
|
||||||
|
() => selectedOptionCount.value > 0 && !isAllSelected.value,
|
||||||
|
)
|
||||||
|
|
||||||
const showSearch = computed(
|
const showSearch = computed(
|
||||||
() => props.searchable && totalCount.value >= props.searchThreshold,
|
() => props.searchable && totalCount.value >= props.searchThreshold,
|
||||||
)
|
)
|
||||||
@@ -205,4 +239,18 @@ function toggle(value: string) {
|
|||||||
function remove(value: string) {
|
function remove(value: string) {
|
||||||
emit('update:modelValue', props.modelValue.filter(v => v !== value))
|
emit('update:modelValue', props.modelValue.filter(v => v !== value))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function toggleAll() {
|
||||||
|
const invalidValues = props.modelValue.filter(v => !validValues.value.has(v))
|
||||||
|
|
||||||
|
if (isAllSelected.value) {
|
||||||
|
emit('update:modelValue', invalidValues)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
emit('update:modelValue', [
|
||||||
|
...invalidValues,
|
||||||
|
...props.options.map(option => option.value),
|
||||||
|
])
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -104,9 +104,9 @@
|
|||||||
<span class="text-sm font-medium">访问限制</span>
|
<span class="text-sm font-medium">访问限制</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Provider -->
|
<!-- 提供商 -->
|
||||||
<div class="space-y-2">
|
<div class="space-y-2">
|
||||||
<Label class="text-sm font-medium">允许的 Provider</Label>
|
<Label class="text-sm font-medium">允许的提供商</Label>
|
||||||
<div class="flex items-center gap-3">
|
<div class="flex items-center gap-3">
|
||||||
<div class="flex-1 min-w-0">
|
<div class="flex-1 min-w-0">
|
||||||
<MultiSelect
|
<MultiSelect
|
||||||
@@ -115,9 +115,9 @@
|
|||||||
:search-threshold="0"
|
:search-threshold="0"
|
||||||
:disabled="form.provider_unrestricted"
|
:disabled="form.provider_unrestricted"
|
||||||
:placeholder="form.provider_unrestricted ? '不限制' : '未选择(全部禁用)'"
|
:placeholder="form.provider_unrestricted ? '不限制' : '未选择(全部禁用)'"
|
||||||
empty-text="暂无可用 Provider"
|
empty-text="暂无可用提供商"
|
||||||
no-results-text="未找到匹配的 Provider"
|
no-results-text="未找到匹配的提供商"
|
||||||
search-placeholder="搜索 Provider 名称..."
|
search-placeholder="搜索提供商名称..."
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<Switch
|
<Switch
|
||||||
@@ -127,9 +127,9 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- API 格式 -->
|
<!-- 端点 -->
|
||||||
<div class="space-y-2">
|
<div class="space-y-2">
|
||||||
<Label class="text-sm font-medium">允许的 API 格式</Label>
|
<Label class="text-sm font-medium">允许的端点</Label>
|
||||||
<div class="flex items-center gap-3">
|
<div class="flex items-center gap-3">
|
||||||
<div class="flex-1 min-w-0">
|
<div class="flex-1 min-w-0">
|
||||||
<MultiSelect
|
<MultiSelect
|
||||||
@@ -138,9 +138,9 @@
|
|||||||
:search-threshold="0"
|
:search-threshold="0"
|
||||||
:disabled="form.api_format_unrestricted"
|
:disabled="form.api_format_unrestricted"
|
||||||
:placeholder="form.api_format_unrestricted ? '不限制' : '未选择(全部禁用)'"
|
:placeholder="form.api_format_unrestricted ? '不限制' : '未选择(全部禁用)'"
|
||||||
empty-text="暂无可用 API 格式"
|
empty-text="暂无可用端点"
|
||||||
no-results-text="未找到匹配的 API 格式"
|
no-results-text="未找到匹配的端点"
|
||||||
search-placeholder="搜索 API 格式..."
|
search-placeholder="搜索端点..."
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<Switch
|
<Switch
|
||||||
|
|||||||
@@ -188,9 +188,9 @@
|
|||||||
<span class="text-sm font-medium">访问限制</span>
|
<span class="text-sm font-medium">访问限制</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Provider -->
|
<!-- 提供商 -->
|
||||||
<div class="space-y-2">
|
<div class="space-y-2">
|
||||||
<Label class="text-sm font-medium">允许的 Provider</Label>
|
<Label class="text-sm font-medium">允许的提供商</Label>
|
||||||
<div class="flex items-center gap-3">
|
<div class="flex items-center gap-3">
|
||||||
<div class="flex-1 min-w-0">
|
<div class="flex-1 min-w-0">
|
||||||
<MultiSelect
|
<MultiSelect
|
||||||
@@ -199,9 +199,9 @@
|
|||||||
:search-threshold="0"
|
:search-threshold="0"
|
||||||
:disabled="form.provider_unrestricted"
|
:disabled="form.provider_unrestricted"
|
||||||
:placeholder="form.provider_unrestricted ? '不限制' : '未选择(全部禁用)'"
|
:placeholder="form.provider_unrestricted ? '不限制' : '未选择(全部禁用)'"
|
||||||
empty-text="暂无可用 Provider"
|
empty-text="暂无可用提供商"
|
||||||
no-results-text="未找到匹配的 Provider"
|
no-results-text="未找到匹配的提供商"
|
||||||
search-placeholder="搜索 Provider 名称..."
|
search-placeholder="搜索提供商名称..."
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<Switch
|
<Switch
|
||||||
@@ -211,9 +211,9 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- API 格式 -->
|
<!-- 端点 -->
|
||||||
<div class="space-y-2">
|
<div class="space-y-2">
|
||||||
<Label class="text-sm font-medium">允许的 API 格式</Label>
|
<Label class="text-sm font-medium">允许的端点</Label>
|
||||||
<div class="flex items-center gap-3">
|
<div class="flex items-center gap-3">
|
||||||
<div class="flex-1 min-w-0">
|
<div class="flex-1 min-w-0">
|
||||||
<MultiSelect
|
<MultiSelect
|
||||||
@@ -222,9 +222,9 @@
|
|||||||
:search-threshold="0"
|
:search-threshold="0"
|
||||||
:disabled="form.api_format_unrestricted"
|
:disabled="form.api_format_unrestricted"
|
||||||
:placeholder="form.api_format_unrestricted ? '不限制' : '未选择(全部禁用)'"
|
:placeholder="form.api_format_unrestricted ? '不限制' : '未选择(全部禁用)'"
|
||||||
empty-text="暂无可用 API 格式"
|
empty-text="暂无可用端点"
|
||||||
no-results-text="未找到匹配的 API 格式"
|
no-results-text="未找到匹配的端点"
|
||||||
search-placeholder="搜索 API 格式..."
|
search-placeholder="搜索端点..."
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<Switch
|
<Switch
|
||||||
|
|||||||
Reference in New Issue
Block a user