feat(admin): add compact proxy IP resource link
Add a low-visibility proxy IP resource link near proxy-related controls. - Show the link beside account proxy selectors - Show the link in the create proxy dialog tab row - Keep the entry inline to avoid interrupting form workflows
This commit is contained in:
parent
3c5a444802
commit
0430899748
@ -2439,7 +2439,10 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label class="input-label">{{ t('admin.accounts.proxy') }}</label>
|
<div class="mb-1 flex items-center gap-2">
|
||||||
|
<label class="input-label mb-0">{{ t('admin.accounts.proxy') }}</label>
|
||||||
|
<ProxyAdBanner />
|
||||||
|
</div>
|
||||||
<ProxySelector v-model="form.proxy_id" :proxies="proxies" />
|
<ProxySelector v-model="form.proxy_id" :proxies="proxies" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -3152,6 +3155,7 @@ import ConfirmDialog from '@/components/common/ConfirmDialog.vue'
|
|||||||
import Select from '@/components/common/Select.vue'
|
import Select from '@/components/common/Select.vue'
|
||||||
import Icon from '@/components/icons/Icon.vue'
|
import Icon from '@/components/icons/Icon.vue'
|
||||||
import ProxySelector from '@/components/common/ProxySelector.vue'
|
import ProxySelector from '@/components/common/ProxySelector.vue'
|
||||||
|
import ProxyAdBanner from '@/components/common/ProxyAdBanner.vue'
|
||||||
import GroupSelector from '@/components/common/GroupSelector.vue'
|
import GroupSelector from '@/components/common/GroupSelector.vue'
|
||||||
import ModelWhitelistSelector from '@/components/account/ModelWhitelistSelector.vue'
|
import ModelWhitelistSelector from '@/components/account/ModelWhitelistSelector.vue'
|
||||||
import QuotaLimitCard from '@/components/account/QuotaLimitCard.vue'
|
import QuotaLimitCard from '@/components/account/QuotaLimitCard.vue'
|
||||||
|
|||||||
@ -1258,7 +1258,10 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label class="input-label">{{ t('admin.accounts.proxy') }}</label>
|
<div class="mb-1 flex items-center gap-2">
|
||||||
|
<label class="input-label mb-0">{{ t('admin.accounts.proxy') }}</label>
|
||||||
|
<ProxyAdBanner />
|
||||||
|
</div>
|
||||||
<ProxySelector v-model="form.proxy_id" :proxies="proxies" />
|
<ProxySelector v-model="form.proxy_id" :proxies="proxies" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -2224,6 +2227,7 @@ import ConfirmDialog from '@/components/common/ConfirmDialog.vue'
|
|||||||
import Select from '@/components/common/Select.vue'
|
import Select from '@/components/common/Select.vue'
|
||||||
import Icon from '@/components/icons/Icon.vue'
|
import Icon from '@/components/icons/Icon.vue'
|
||||||
import ProxySelector from '@/components/common/ProxySelector.vue'
|
import ProxySelector from '@/components/common/ProxySelector.vue'
|
||||||
|
import ProxyAdBanner from '@/components/common/ProxyAdBanner.vue'
|
||||||
import GroupSelector from '@/components/common/GroupSelector.vue'
|
import GroupSelector from '@/components/common/GroupSelector.vue'
|
||||||
import ModelWhitelistSelector from '@/components/account/ModelWhitelistSelector.vue'
|
import ModelWhitelistSelector from '@/components/account/ModelWhitelistSelector.vue'
|
||||||
import QuotaLimitCard from '@/components/account/QuotaLimitCard.vue'
|
import QuotaLimitCard from '@/components/account/QuotaLimitCard.vue'
|
||||||
|
|||||||
18
frontend/src/components/common/ProxyAdBanner.vue
Normal file
18
frontend/src/components/common/ProxyAdBanner.vue
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<template>
|
||||||
|
<a
|
||||||
|
class="inline-flex max-w-full shrink-0 items-center gap-1 truncate text-xs font-normal text-primary-600 transition-colors hover:underline focus:outline-none focus:ring-2 focus:ring-primary-400 focus:ring-offset-2 dark:text-primary-400 dark:focus:ring-offset-dark-800"
|
||||||
|
href="https://bestproxy.com/?keyword=a2e8iuol"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
>
|
||||||
|
<span class="truncate">{{ t('admin.proxies.ad.inline') }}</span>
|
||||||
|
<Icon name="externalLink" size="xs" />
|
||||||
|
</a>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { useI18n } from 'vue-i18n'
|
||||||
|
import Icon from '@/components/icons/Icon.vue'
|
||||||
|
|
||||||
|
const { t } = useI18n()
|
||||||
|
</script>
|
||||||
@ -4002,6 +4002,9 @@ export default {
|
|||||||
createProxy: 'Create Proxy',
|
createProxy: 'Create Proxy',
|
||||||
editProxy: 'Edit Proxy',
|
editProxy: 'Edit Proxy',
|
||||||
deleteProxy: 'Delete Proxy',
|
deleteProxy: 'Delete Proxy',
|
||||||
|
ad: {
|
||||||
|
inline: 'Need proxy IP?'
|
||||||
|
},
|
||||||
dataImport: 'Import',
|
dataImport: 'Import',
|
||||||
dataExportSelected: 'Export Selected',
|
dataExportSelected: 'Export Selected',
|
||||||
dataImportTitle: 'Import Proxies',
|
dataImportTitle: 'Import Proxies',
|
||||||
|
|||||||
@ -4097,6 +4097,9 @@ export default {
|
|||||||
createProxy: '添加代理',
|
createProxy: '添加代理',
|
||||||
editProxy: '编辑代理',
|
editProxy: '编辑代理',
|
||||||
deleteProxy: '删除代理',
|
deleteProxy: '删除代理',
|
||||||
|
ad: {
|
||||||
|
inline: '正在寻找合适的代理 IP?'
|
||||||
|
},
|
||||||
deleteConfirmMessage: "确定要删除代理 '{name}' 吗?",
|
deleteConfirmMessage: "确定要删除代理 '{name}' 吗?",
|
||||||
testProxy: '测试代理',
|
testProxy: '测试代理',
|
||||||
dataImport: '导入',
|
dataImport: '导入',
|
||||||
|
|||||||
@ -357,45 +357,50 @@
|
|||||||
@close="closeCreateModal"
|
@close="closeCreateModal"
|
||||||
>
|
>
|
||||||
<!-- Tab Switch -->
|
<!-- Tab Switch -->
|
||||||
<div class="mb-6 flex border-b border-gray-200 dark:border-dark-600">
|
<div
|
||||||
<button
|
class="mb-6 flex items-center justify-between gap-3 border-b border-gray-200 dark:border-dark-600"
|
||||||
type="button"
|
>
|
||||||
@click="createMode = 'standard'"
|
<div class="flex min-w-0 shrink-0">
|
||||||
:class="[
|
<button
|
||||||
'-mb-px border-b-2 px-4 py-2 text-sm font-medium transition-colors',
|
type="button"
|
||||||
createMode === 'standard'
|
@click="createMode = 'standard'"
|
||||||
? 'border-primary-500 text-primary-600 dark:text-primary-400'
|
:class="[
|
||||||
: 'border-transparent text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-300'
|
'-mb-px border-b-2 px-4 py-2 text-sm font-medium transition-colors',
|
||||||
]"
|
createMode === 'standard'
|
||||||
>
|
? 'border-primary-500 text-primary-600 dark:text-primary-400'
|
||||||
<Icon name="plus" size="sm" class="mr-1.5 inline" />
|
: 'border-transparent text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-300'
|
||||||
{{ t('admin.proxies.standardAdd') }}
|
]"
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
@click="createMode = 'batch'"
|
|
||||||
:class="[
|
|
||||||
'-mb-px border-b-2 px-4 py-2 text-sm font-medium transition-colors',
|
|
||||||
createMode === 'batch'
|
|
||||||
? 'border-primary-500 text-primary-600 dark:text-primary-400'
|
|
||||||
: 'border-transparent text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-300'
|
|
||||||
]"
|
|
||||||
>
|
|
||||||
<svg
|
|
||||||
class="mr-1.5 inline h-4 w-4"
|
|
||||||
fill="none"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
stroke="currentColor"
|
|
||||||
stroke-width="1.5"
|
|
||||||
>
|
>
|
||||||
<path
|
<Icon name="plus" size="sm" class="mr-1.5 inline" />
|
||||||
stroke-linecap="round"
|
{{ t('admin.proxies.standardAdd') }}
|
||||||
stroke-linejoin="round"
|
</button>
|
||||||
d="M3.75 12h16.5m-16.5 3.75h16.5M3.75 19.5h16.5M5.625 4.5h12.75a1.875 1.875 0 010 3.75H5.625a1.875 1.875 0 010-3.75z"
|
<button
|
||||||
/>
|
type="button"
|
||||||
</svg>
|
@click="createMode = 'batch'"
|
||||||
{{ t('admin.proxies.batchAdd') }}
|
:class="[
|
||||||
</button>
|
'-mb-px border-b-2 px-4 py-2 text-sm font-medium transition-colors',
|
||||||
|
createMode === 'batch'
|
||||||
|
? 'border-primary-500 text-primary-600 dark:text-primary-400'
|
||||||
|
: 'border-transparent text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-300'
|
||||||
|
]"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
class="mr-1.5 inline h-4 w-4"
|
||||||
|
fill="none"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-width="1.5"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
d="M3.75 12h16.5m-16.5 3.75h16.5M3.75 19.5h16.5M5.625 4.5h12.75a1.875 1.875 0 010 3.75H5.625a1.875 1.875 0 010-3.75z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
{{ t('admin.proxies.batchAdd') }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<ProxyAdBanner />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Standard Add Form -->
|
<!-- Standard Add Form -->
|
||||||
@ -887,6 +892,7 @@ import ConfirmDialog from '@/components/common/ConfirmDialog.vue'
|
|||||||
import EmptyState from '@/components/common/EmptyState.vue'
|
import EmptyState from '@/components/common/EmptyState.vue'
|
||||||
import ImportDataModal from '@/components/admin/proxy/ImportDataModal.vue'
|
import ImportDataModal from '@/components/admin/proxy/ImportDataModal.vue'
|
||||||
import Select from '@/components/common/Select.vue'
|
import Select from '@/components/common/Select.vue'
|
||||||
|
import ProxyAdBanner from '@/components/common/ProxyAdBanner.vue'
|
||||||
import Icon from '@/components/icons/Icon.vue'
|
import Icon from '@/components/icons/Icon.vue'
|
||||||
import PlatformTypeBadge from '@/components/common/PlatformTypeBadge.vue'
|
import PlatformTypeBadge from '@/components/common/PlatformTypeBadge.vue'
|
||||||
import { useClipboard } from '@/composables/useClipboard'
|
import { useClipboard } from '@/composables/useClipboard'
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user