feat(admin): Add group filtering for account listings
- Add groupID parameter to ListAccounts and ListWithFilters methods - Implement account filtering by group ID in repository query - Add group query parameter parsing in account handler - Update all ListAccounts/ListWithFilters call sites with groupID parameter - Add group filter UI component to AccountTableFilters - Add i18n translations for group filter label in English and Chinese - Update API contract and test stubs to reflect new signature - Enable filtering accounts by their assigned groups in admin panel
This commit is contained in:
@@ -32,6 +32,7 @@ export async function list(
|
||||
platform?: string
|
||||
type?: string
|
||||
status?: string
|
||||
group?: string
|
||||
search?: string
|
||||
},
|
||||
options?: {
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
>
|
||||
<div class="mb-2 flex items-center justify-between">
|
||||
<span class="text-xs font-medium text-gray-500 dark:text-gray-400">
|
||||
{{ t('admin.accounts.allGroups', { count: groups.length }) }}
|
||||
{{ t('admin.accounts.groupCountTotal', { count: groups.length }) }}
|
||||
</span>
|
||||
<button
|
||||
@click="showPopover = false"
|
||||
|
||||
@@ -10,16 +10,21 @@
|
||||
<Select :model-value="filters.platform" class="w-40" :options="pOpts" @update:model-value="updatePlatform" @change="$emit('change')" />
|
||||
<Select :model-value="filters.type" class="w-40" :options="tOpts" @update:model-value="updateType" @change="$emit('change')" />
|
||||
<Select :model-value="filters.status" class="w-40" :options="sOpts" @update:model-value="updateStatus" @change="$emit('change')" />
|
||||
<Select :model-value="filters.group" class="w-40" :options="gOpts" @update:model-value="updateGroup" @change="$emit('change')" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue'; import { useI18n } from 'vue-i18n'; import Select from '@/components/common/Select.vue'; import SearchInput from '@/components/common/SearchInput.vue'
|
||||
const props = defineProps(['searchQuery', 'filters']); const emit = defineEmits(['update:searchQuery', 'update:filters', 'change']); const { t } = useI18n()
|
||||
import type { AdminGroup } from '@/types'
|
||||
const props = defineProps<{ searchQuery: string; filters: Record<string, any>; groups?: AdminGroup[] }>()
|
||||
const emit = defineEmits(['update:searchQuery', 'update:filters', 'change']); const { t } = useI18n()
|
||||
const updatePlatform = (value: string | number | boolean | null) => { emit('update:filters', { ...props.filters, platform: value }) }
|
||||
const updateType = (value: string | number | boolean | null) => { emit('update:filters', { ...props.filters, type: value }) }
|
||||
const updateStatus = (value: string | number | boolean | null) => { emit('update:filters', { ...props.filters, status: value }) }
|
||||
const updateGroup = (value: string | number | boolean | null) => { emit('update:filters', { ...props.filters, group: value }) }
|
||||
const pOpts = computed(() => [{ value: '', label: t('admin.accounts.allPlatforms') }, { value: 'anthropic', label: 'Anthropic' }, { value: 'openai', label: 'OpenAI' }, { value: 'gemini', label: 'Gemini' }, { value: 'antigravity', label: 'Antigravity' }])
|
||||
const tOpts = computed(() => [{ value: '', label: t('admin.accounts.allTypes') }, { value: 'oauth', label: t('admin.accounts.oauthType') }, { value: 'setup-token', label: t('admin.accounts.setupToken') }, { value: 'apikey', label: t('admin.accounts.apiKey') }])
|
||||
const sOpts = computed(() => [{ value: '', label: t('admin.accounts.allStatus') }, { value: 'active', label: t('admin.accounts.status.active') }, { value: 'inactive', label: t('admin.accounts.status.inactive') }, { value: 'error', label: t('admin.accounts.status.error') }, { value: 'rate_limited', label: t('admin.accounts.status.rateLimited') }])
|
||||
const gOpts = computed(() => [{ value: '', label: t('admin.accounts.allGroups') }, ...(props.groups || []).map(g => ({ value: String(g.id), label: g.name }))])
|
||||
</script>
|
||||
|
||||
@@ -1335,6 +1335,7 @@ export default {
|
||||
allPlatforms: 'All Platforms',
|
||||
allTypes: 'All Types',
|
||||
allStatus: 'All Status',
|
||||
allGroups: 'All Groups',
|
||||
oauthType: 'OAuth',
|
||||
setupToken: 'Setup Token',
|
||||
apiKey: 'API Key',
|
||||
@@ -1344,7 +1345,7 @@ export default {
|
||||
schedulableEnabled: 'Scheduling enabled',
|
||||
schedulableDisabled: 'Scheduling disabled',
|
||||
failedToToggleSchedulable: 'Failed to toggle scheduling status',
|
||||
allGroups: '{count} groups total',
|
||||
groupCountTotal: '{count} groups total',
|
||||
platforms: {
|
||||
anthropic: 'Anthropic',
|
||||
claude: 'Claude',
|
||||
|
||||
@@ -1426,6 +1426,7 @@ export default {
|
||||
allPlatforms: '全部平台',
|
||||
allTypes: '全部类型',
|
||||
allStatus: '全部状态',
|
||||
allGroups: '全部分组',
|
||||
oauthType: 'OAuth',
|
||||
// Schedulable toggle
|
||||
schedulable: '参与调度',
|
||||
@@ -1433,7 +1434,7 @@ export default {
|
||||
schedulableEnabled: '调度已开启',
|
||||
schedulableDisabled: '调度已关闭',
|
||||
failedToToggleSchedulable: '切换调度状态失败',
|
||||
allGroups: '共 {count} 个分组',
|
||||
groupCountTotal: '共 {count} 个分组',
|
||||
columns: {
|
||||
name: '名称',
|
||||
platformType: '平台/类型',
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
<AccountTableFilters
|
||||
v-model:searchQuery="params.search"
|
||||
:filters="params"
|
||||
:groups="groups"
|
||||
@update:filters="(newFilters) => Object.assign(params, newFilters)"
|
||||
@change="debouncedReload"
|
||||
@update:searchQuery="debouncedReload"
|
||||
@@ -439,7 +440,7 @@ const isColumnVisible = (key: string) => !hiddenColumns.has(key)
|
||||
|
||||
const { items: accounts, loading, params, pagination, load, reload, debouncedReload, handlePageChange, handlePageSizeChange } = useTableLoader<Account, any>({
|
||||
fetchFn: adminAPI.accounts.list,
|
||||
initialParams: { platform: '', type: '', status: '', search: '' }
|
||||
initialParams: { platform: '', type: '', status: '', group: '', search: '' }
|
||||
})
|
||||
|
||||
const isAnyModalOpen = computed(() => {
|
||||
|
||||
Reference in New Issue
Block a user