Merge branch 'main' into feature/antigravity_auth
This commit is contained in:
@@ -1,5 +1,10 @@
|
||||
<template>
|
||||
<Modal :show="show" :title="t('admin.accounts.usageStatistics')" size="2xl" @close="handleClose">
|
||||
<BaseDialog
|
||||
:show="show"
|
||||
:title="t('admin.accounts.usageStatistics')"
|
||||
width="extra-wide"
|
||||
@close="handleClose"
|
||||
>
|
||||
<div class="space-y-6">
|
||||
<!-- Account Info Header -->
|
||||
<div
|
||||
@@ -521,7 +526,7 @@
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
</Modal>
|
||||
</BaseDialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
@@ -539,7 +544,7 @@ import {
|
||||
Filler
|
||||
} from 'chart.js'
|
||||
import { Line } from 'vue-chartjs'
|
||||
import Modal from '@/components/common/Modal.vue'
|
||||
import BaseDialog from '@/components/common/BaseDialog.vue'
|
||||
import LoadingSpinner from '@/components/common/LoadingSpinner.vue'
|
||||
import ModelDistributionChart from '@/components/charts/ModelDistributionChart.vue'
|
||||
import { adminAPI } from '@/api/admin'
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<template>
|
||||
<Modal
|
||||
<BaseDialog
|
||||
:show="show"
|
||||
:title="t('admin.accounts.testAccountConnection')"
|
||||
size="md"
|
||||
width="normal"
|
||||
@close="handleClose"
|
||||
>
|
||||
<div class="space-y-4">
|
||||
@@ -273,13 +273,13 @@
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
</Modal>
|
||||
</BaseDialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, watch, nextTick } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import Modal from '@/components/common/Modal.vue'
|
||||
import BaseDialog from '@/components/common/BaseDialog.vue'
|
||||
import { useClipboard } from '@/composables/useClipboard'
|
||||
import { adminAPI } from '@/api/admin'
|
||||
import type { Account, ClaudeModel } from '@/types'
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
<template>
|
||||
<Modal :show="show" :title="t('admin.accounts.bulkEdit.title')" size="lg" @close="handleClose">
|
||||
<form class="space-y-5" @submit.prevent="handleSubmit">
|
||||
<BaseDialog
|
||||
:show="show"
|
||||
:title="t('admin.accounts.bulkEdit.title')"
|
||||
width="wide"
|
||||
@close="handleClose"
|
||||
>
|
||||
<form id="bulk-edit-account-form" class="space-y-5" @submit.prevent="handleSubmit">
|
||||
<!-- Info -->
|
||||
<div class="rounded-lg bg-blue-50 p-4 dark:bg-blue-900/20">
|
||||
<p class="text-sm text-blue-700 dark:text-blue-400">
|
||||
@@ -19,20 +24,30 @@
|
||||
<!-- Base URL (API Key only) -->
|
||||
<div class="border-t border-gray-200 pt-4 dark:border-dark-600">
|
||||
<div class="mb-3 flex items-center justify-between">
|
||||
<label class="input-label mb-0">{{ t('admin.accounts.baseUrl') }}</label>
|
||||
<label
|
||||
id="bulk-edit-base-url-label"
|
||||
class="input-label mb-0"
|
||||
for="bulk-edit-base-url-enabled"
|
||||
>
|
||||
{{ t('admin.accounts.baseUrl') }}
|
||||
</label>
|
||||
<input
|
||||
v-model="enableBaseUrl"
|
||||
id="bulk-edit-base-url-enabled"
|
||||
type="checkbox"
|
||||
aria-controls="bulk-edit-base-url"
|
||||
class="rounded border-gray-300 text-primary-600 focus:ring-primary-500"
|
||||
/>
|
||||
</div>
|
||||
<input
|
||||
v-model="baseUrl"
|
||||
id="bulk-edit-base-url"
|
||||
type="text"
|
||||
:disabled="!enableBaseUrl"
|
||||
class="input"
|
||||
:class="!enableBaseUrl && 'cursor-not-allowed opacity-50'"
|
||||
:placeholder="t('admin.accounts.bulkEdit.baseUrlPlaceholder')"
|
||||
aria-labelledby="bulk-edit-base-url-label"
|
||||
/>
|
||||
<p class="input-hint">
|
||||
{{ t('admin.accounts.bulkEdit.baseUrlNotice') }}
|
||||
@@ -42,15 +57,28 @@
|
||||
<!-- Model restriction -->
|
||||
<div class="border-t border-gray-200 pt-4 dark:border-dark-600">
|
||||
<div class="mb-3 flex items-center justify-between">
|
||||
<label class="input-label mb-0">{{ t('admin.accounts.modelRestriction') }}</label>
|
||||
<label
|
||||
id="bulk-edit-model-restriction-label"
|
||||
class="input-label mb-0"
|
||||
for="bulk-edit-model-restriction-enabled"
|
||||
>
|
||||
{{ t('admin.accounts.modelRestriction') }}
|
||||
</label>
|
||||
<input
|
||||
v-model="enableModelRestriction"
|
||||
id="bulk-edit-model-restriction-enabled"
|
||||
type="checkbox"
|
||||
aria-controls="bulk-edit-model-restriction-body"
|
||||
class="rounded border-gray-300 text-primary-600 focus:ring-primary-500"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div :class="!enableModelRestriction && 'pointer-events-none opacity-50'">
|
||||
<div
|
||||
id="bulk-edit-model-restriction-body"
|
||||
:class="!enableModelRestriction && 'pointer-events-none opacity-50'"
|
||||
role="group"
|
||||
aria-labelledby="bulk-edit-model-restriction-label"
|
||||
>
|
||||
<!-- Mode Toggle -->
|
||||
<div class="mb-4 flex gap-2">
|
||||
<button
|
||||
@@ -267,19 +295,27 @@
|
||||
<div class="border-t border-gray-200 pt-4 dark:border-dark-600">
|
||||
<div class="mb-3 flex items-center justify-between">
|
||||
<div>
|
||||
<label class="input-label mb-0">{{ t('admin.accounts.customErrorCodes') }}</label>
|
||||
<label
|
||||
id="bulk-edit-custom-error-codes-label"
|
||||
class="input-label mb-0"
|
||||
for="bulk-edit-custom-error-codes-enabled"
|
||||
>
|
||||
{{ t('admin.accounts.customErrorCodes') }}
|
||||
</label>
|
||||
<p class="mt-1 text-xs text-gray-500 dark:text-gray-400">
|
||||
{{ t('admin.accounts.customErrorCodesHint') }}
|
||||
</p>
|
||||
</div>
|
||||
<input
|
||||
v-model="enableCustomErrorCodes"
|
||||
id="bulk-edit-custom-error-codes-enabled"
|
||||
type="checkbox"
|
||||
aria-controls="bulk-edit-custom-error-codes-body"
|
||||
class="rounded border-gray-300 text-primary-600 focus:ring-primary-500"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div v-if="enableCustomErrorCodes" class="space-y-3">
|
||||
<div v-if="enableCustomErrorCodes" id="bulk-edit-custom-error-codes-body" class="space-y-3">
|
||||
<div class="rounded-lg bg-amber-50 p-3 dark:bg-amber-900/20">
|
||||
<p class="text-xs text-amber-700 dark:text-amber-400">
|
||||
<svg
|
||||
@@ -321,11 +357,13 @@
|
||||
<div class="flex items-center gap-2">
|
||||
<input
|
||||
v-model="customErrorCodeInput"
|
||||
id="bulk-edit-custom-error-code-input"
|
||||
type="number"
|
||||
min="100"
|
||||
max="599"
|
||||
class="input flex-1"
|
||||
:placeholder="t('admin.accounts.enterErrorCode')"
|
||||
aria-labelledby="bulk-edit-custom-error-codes-label"
|
||||
@keyup.enter="addCustomErrorCode"
|
||||
/>
|
||||
<button type="button" class="btn btn-secondary px-3" @click="addCustomErrorCode">
|
||||
@@ -374,20 +412,26 @@
|
||||
<div class="border-t border-gray-200 pt-4 dark:border-dark-600">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex-1 pr-4">
|
||||
<label class="input-label mb-0">{{
|
||||
t('admin.accounts.interceptWarmupRequests')
|
||||
}}</label>
|
||||
<label
|
||||
id="bulk-edit-intercept-warmup-label"
|
||||
class="input-label mb-0"
|
||||
for="bulk-edit-intercept-warmup-enabled"
|
||||
>
|
||||
{{ t('admin.accounts.interceptWarmupRequests') }}
|
||||
</label>
|
||||
<p class="mt-1 text-xs text-gray-500 dark:text-gray-400">
|
||||
{{ t('admin.accounts.interceptWarmupRequestsDesc') }}
|
||||
</p>
|
||||
</div>
|
||||
<input
|
||||
v-model="enableInterceptWarmup"
|
||||
id="bulk-edit-intercept-warmup-enabled"
|
||||
type="checkbox"
|
||||
aria-controls="bulk-edit-intercept-warmup-body"
|
||||
class="rounded border-gray-300 text-primary-600 focus:ring-primary-500"
|
||||
/>
|
||||
</div>
|
||||
<div v-if="enableInterceptWarmup" class="mt-3">
|
||||
<div v-if="enableInterceptWarmup" id="bulk-edit-intercept-warmup-body" class="mt-3">
|
||||
<button
|
||||
type="button"
|
||||
:class="[
|
||||
@@ -409,15 +453,27 @@
|
||||
<!-- Proxy -->
|
||||
<div class="border-t border-gray-200 pt-4 dark:border-dark-600">
|
||||
<div class="mb-3 flex items-center justify-between">
|
||||
<label class="input-label mb-0">{{ t('admin.accounts.proxy') }}</label>
|
||||
<label
|
||||
id="bulk-edit-proxy-label"
|
||||
class="input-label mb-0"
|
||||
for="bulk-edit-proxy-enabled"
|
||||
>
|
||||
{{ t('admin.accounts.proxy') }}
|
||||
</label>
|
||||
<input
|
||||
v-model="enableProxy"
|
||||
id="bulk-edit-proxy-enabled"
|
||||
type="checkbox"
|
||||
aria-controls="bulk-edit-proxy-body"
|
||||
class="rounded border-gray-300 text-primary-600 focus:ring-primary-500"
|
||||
/>
|
||||
</div>
|
||||
<div :class="!enableProxy && 'pointer-events-none opacity-50'">
|
||||
<ProxySelector v-model="proxyId" :proxies="proxies" />
|
||||
<div id="bulk-edit-proxy-body" :class="!enableProxy && 'pointer-events-none opacity-50'">
|
||||
<ProxySelector
|
||||
v-model="proxyId"
|
||||
:proxies="proxies"
|
||||
aria-labelledby="bulk-edit-proxy-label"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -425,38 +481,58 @@
|
||||
<div class="grid grid-cols-2 gap-4 border-t border-gray-200 pt-4 dark:border-dark-600">
|
||||
<div>
|
||||
<div class="mb-3 flex items-center justify-between">
|
||||
<label class="input-label mb-0">{{ t('admin.accounts.concurrency') }}</label>
|
||||
<label
|
||||
id="bulk-edit-concurrency-label"
|
||||
class="input-label mb-0"
|
||||
for="bulk-edit-concurrency-enabled"
|
||||
>
|
||||
{{ t('admin.accounts.concurrency') }}
|
||||
</label>
|
||||
<input
|
||||
v-model="enableConcurrency"
|
||||
id="bulk-edit-concurrency-enabled"
|
||||
type="checkbox"
|
||||
aria-controls="bulk-edit-concurrency"
|
||||
class="rounded border-gray-300 text-primary-600 focus:ring-primary-500"
|
||||
/>
|
||||
</div>
|
||||
<input
|
||||
v-model.number="concurrency"
|
||||
id="bulk-edit-concurrency"
|
||||
type="number"
|
||||
min="1"
|
||||
:disabled="!enableConcurrency"
|
||||
class="input"
|
||||
:class="!enableConcurrency && 'cursor-not-allowed opacity-50'"
|
||||
aria-labelledby="bulk-edit-concurrency-label"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<div class="mb-3 flex items-center justify-between">
|
||||
<label class="input-label mb-0">{{ t('admin.accounts.priority') }}</label>
|
||||
<label
|
||||
id="bulk-edit-priority-label"
|
||||
class="input-label mb-0"
|
||||
for="bulk-edit-priority-enabled"
|
||||
>
|
||||
{{ t('admin.accounts.priority') }}
|
||||
</label>
|
||||
<input
|
||||
v-model="enablePriority"
|
||||
id="bulk-edit-priority-enabled"
|
||||
type="checkbox"
|
||||
aria-controls="bulk-edit-priority"
|
||||
class="rounded border-gray-300 text-primary-600 focus:ring-primary-500"
|
||||
/>
|
||||
</div>
|
||||
<input
|
||||
v-model.number="priority"
|
||||
id="bulk-edit-priority"
|
||||
type="number"
|
||||
min="1"
|
||||
:disabled="!enablePriority"
|
||||
class="input"
|
||||
:class="!enablePriority && 'cursor-not-allowed opacity-50'"
|
||||
aria-labelledby="bulk-edit-priority-label"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -464,39 +540,69 @@
|
||||
<!-- Status -->
|
||||
<div class="border-t border-gray-200 pt-4 dark:border-dark-600">
|
||||
<div class="mb-3 flex items-center justify-between">
|
||||
<label class="input-label mb-0">{{ t('common.status') }}</label>
|
||||
<label
|
||||
id="bulk-edit-status-label"
|
||||
class="input-label mb-0"
|
||||
for="bulk-edit-status-enabled"
|
||||
>
|
||||
{{ t('common.status') }}
|
||||
</label>
|
||||
<input
|
||||
v-model="enableStatus"
|
||||
id="bulk-edit-status-enabled"
|
||||
type="checkbox"
|
||||
aria-controls="bulk-edit-status"
|
||||
class="rounded border-gray-300 text-primary-600 focus:ring-primary-500"
|
||||
/>
|
||||
</div>
|
||||
<div :class="!enableStatus && 'pointer-events-none opacity-50'">
|
||||
<Select v-model="status" :options="statusOptions" />
|
||||
<div id="bulk-edit-status" :class="!enableStatus && 'pointer-events-none opacity-50'">
|
||||
<Select
|
||||
v-model="status"
|
||||
:options="statusOptions"
|
||||
aria-labelledby="bulk-edit-status-label"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Groups -->
|
||||
<div class="border-t border-gray-200 pt-4 dark:border-dark-600">
|
||||
<div class="mb-3 flex items-center justify-between">
|
||||
<label class="input-label mb-0">{{ t('nav.groups') }}</label>
|
||||
<label
|
||||
id="bulk-edit-groups-label"
|
||||
class="input-label mb-0"
|
||||
for="bulk-edit-groups-enabled"
|
||||
>
|
||||
{{ t('nav.groups') }}
|
||||
</label>
|
||||
<input
|
||||
v-model="enableGroups"
|
||||
id="bulk-edit-groups-enabled"
|
||||
type="checkbox"
|
||||
aria-controls="bulk-edit-groups"
|
||||
class="rounded border-gray-300 text-primary-600 focus:ring-primary-500"
|
||||
/>
|
||||
</div>
|
||||
<div :class="!enableGroups && 'pointer-events-none opacity-50'">
|
||||
<GroupSelector v-model="groupIds" :groups="groups" />
|
||||
<div id="bulk-edit-groups" :class="!enableGroups && 'pointer-events-none opacity-50'">
|
||||
<GroupSelector
|
||||
v-model="groupIds"
|
||||
:groups="groups"
|
||||
aria-labelledby="bulk-edit-groups-label"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<!-- Action buttons -->
|
||||
<div class="flex justify-end gap-3 pt-4">
|
||||
<template #footer>
|
||||
<div class="flex justify-end gap-3">
|
||||
<button type="button" class="btn btn-secondary" @click="handleClose">
|
||||
{{ t('common.cancel') }}
|
||||
</button>
|
||||
<button type="submit" :disabled="submitting" class="btn btn-primary">
|
||||
<button
|
||||
type="submit"
|
||||
form="bulk-edit-account-form"
|
||||
:disabled="submitting"
|
||||
class="btn btn-primary"
|
||||
>
|
||||
<svg
|
||||
v-if="submitting"
|
||||
class="-ml-1 mr-2 h-4 w-4 animate-spin"
|
||||
@@ -522,8 +628,8 @@
|
||||
}}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</Modal>
|
||||
</template>
|
||||
</BaseDialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
@@ -532,7 +638,7 @@ import { useI18n } from 'vue-i18n'
|
||||
import { useAppStore } from '@/stores/app'
|
||||
import { adminAPI } from '@/api/admin'
|
||||
import type { Proxy, Group } from '@/types'
|
||||
import Modal from '@/components/common/Modal.vue'
|
||||
import BaseDialog from '@/components/common/BaseDialog.vue'
|
||||
import Select from '@/components/common/Select.vue'
|
||||
import ProxySelector from '@/components/common/ProxySelector.vue'
|
||||
import GroupSelector from '@/components/common/GroupSelector.vue'
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
<template>
|
||||
<Modal :show="show" :title="t('admin.accounts.createAccount')" size="xl" @close="handleClose">
|
||||
<BaseDialog
|
||||
:show="show"
|
||||
:title="t('admin.accounts.createAccount')"
|
||||
width="wide"
|
||||
@close="handleClose"
|
||||
>
|
||||
<!-- Step Indicator for OAuth accounts -->
|
||||
<div v-if="isOAuthFlow" class="mb-6 flex items-center justify-center">
|
||||
<div class="flex items-center space-x-4">
|
||||
@@ -34,7 +39,12 @@
|
||||
</div>
|
||||
|
||||
<!-- Step 1: Basic Info -->
|
||||
<form v-if="step === 1" @submit.prevent="handleSubmit" class="space-y-5">
|
||||
<form
|
||||
v-if="step === 1"
|
||||
id="create-account-form"
|
||||
@submit.prevent="handleSubmit"
|
||||
class="space-y-5"
|
||||
>
|
||||
<div>
|
||||
<label class="input-label">{{ t('admin.accounts.accountName') }}</label>
|
||||
<input
|
||||
@@ -1018,11 +1028,40 @@
|
||||
<!-- Group Selection -->
|
||||
<GroupSelector v-model="form.group_ids" :groups="groups" :platform="form.platform" />
|
||||
|
||||
<div class="flex justify-end gap-3 pt-4">
|
||||
</form>
|
||||
|
||||
<!-- Step 2: OAuth Authorization -->
|
||||
<div v-else class="space-y-5">
|
||||
<OAuthAuthorizationFlow
|
||||
ref="oauthFlowRef"
|
||||
:add-method="form.platform === 'anthropic' ? addMethod : 'oauth'"
|
||||
:auth-url="currentAuthUrl"
|
||||
:session-id="currentSessionId"
|
||||
:loading="currentOAuthLoading"
|
||||
:error="currentOAuthError"
|
||||
:show-help="form.platform === 'anthropic'"
|
||||
:show-proxy-warning="form.platform !== 'openai' && !!form.proxy_id"
|
||||
:allow-multiple="form.platform === 'anthropic'"
|
||||
:show-cookie-option="form.platform === 'anthropic'"
|
||||
:platform="form.platform"
|
||||
:show-project-id="geminiOAuthType === 'code_assist'"
|
||||
@generate-url="handleGenerateUrl"
|
||||
@cookie-auth="handleCookieAuth"
|
||||
/>
|
||||
|
||||
</div>
|
||||
|
||||
<template #footer>
|
||||
<div v-if="step === 1" class="flex justify-end gap-3">
|
||||
<button @click="handleClose" type="button" class="btn btn-secondary">
|
||||
{{ t('common.cancel') }}
|
||||
</button>
|
||||
<button type="submit" :disabled="submitting" class="btn btn-primary">
|
||||
<button
|
||||
type="submit"
|
||||
form="create-account-form"
|
||||
:disabled="submitting"
|
||||
class="btn btn-primary"
|
||||
>
|
||||
<svg
|
||||
v-if="submitting"
|
||||
class="-ml-1 mr-2 h-4 w-4 animate-spin"
|
||||
@@ -1052,28 +1091,7 @@
|
||||
}}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<!-- Step 2: OAuth Authorization -->
|
||||
<div v-else class="space-y-5">
|
||||
<OAuthAuthorizationFlow
|
||||
ref="oauthFlowRef"
|
||||
:add-method="form.platform === 'anthropic' ? addMethod : 'oauth'"
|
||||
:auth-url="currentAuthUrl"
|
||||
:session-id="currentSessionId"
|
||||
:loading="currentOAuthLoading"
|
||||
:error="currentOAuthError"
|
||||
:show-help="form.platform === 'anthropic'"
|
||||
:show-proxy-warning="form.platform !== 'openai' && !!form.proxy_id"
|
||||
:allow-multiple="form.platform === 'anthropic'"
|
||||
:show-cookie-option="form.platform === 'anthropic'"
|
||||
:platform="form.platform"
|
||||
:show-project-id="geminiOAuthType === 'code_assist'"
|
||||
@generate-url="handleGenerateUrl"
|
||||
@cookie-auth="handleCookieAuth"
|
||||
/>
|
||||
|
||||
<div class="flex justify-between gap-3 pt-4">
|
||||
<div v-else class="flex justify-between gap-3">
|
||||
<button type="button" class="btn btn-secondary" @click="goBackToBasicInfo">
|
||||
{{ t('common.back') }}
|
||||
</button>
|
||||
@@ -1111,8 +1129,8 @@
|
||||
}}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</Modal>
|
||||
</template>
|
||||
</BaseDialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
@@ -1129,7 +1147,7 @@ import { useOpenAIOAuth } from '@/composables/useOpenAIOAuth'
|
||||
import { useGeminiOAuth } from '@/composables/useGeminiOAuth'
|
||||
import { useAntigravityOAuth } from '@/composables/useAntigravityOAuth'
|
||||
import type { Proxy, Group, AccountPlatform, AccountType } from '@/types'
|
||||
import Modal from '@/components/common/Modal.vue'
|
||||
import BaseDialog from '@/components/common/BaseDialog.vue'
|
||||
import ProxySelector from '@/components/common/ProxySelector.vue'
|
||||
import GroupSelector from '@/components/common/GroupSelector.vue'
|
||||
import OAuthAuthorizationFlow from './OAuthAuthorizationFlow.vue'
|
||||
|
||||
@@ -1,6 +1,16 @@
|
||||
<template>
|
||||
<Modal :show="show" :title="t('admin.accounts.editAccount')" size="xl" @close="handleClose">
|
||||
<form v-if="account" @submit.prevent="handleSubmit" class="space-y-5">
|
||||
<BaseDialog
|
||||
:show="show"
|
||||
:title="t('admin.accounts.editAccount')"
|
||||
width="wide"
|
||||
@close="handleClose"
|
||||
>
|
||||
<form
|
||||
v-if="account"
|
||||
id="edit-account-form"
|
||||
@submit.prevent="handleSubmit"
|
||||
class="space-y-5"
|
||||
>
|
||||
<div>
|
||||
<label class="input-label">{{ t('common.name') }}</label>
|
||||
<input v-model="form.name" type="text" required class="input" />
|
||||
@@ -459,11 +469,19 @@
|
||||
<!-- Group Selection -->
|
||||
<GroupSelector v-model="form.group_ids" :groups="groups" :platform="account?.platform" />
|
||||
|
||||
<div class="flex justify-end gap-3 pt-4">
|
||||
</form>
|
||||
|
||||
<template #footer>
|
||||
<div v-if="account" class="flex justify-end gap-3">
|
||||
<button @click="handleClose" type="button" class="btn btn-secondary">
|
||||
{{ t('common.cancel') }}
|
||||
</button>
|
||||
<button type="submit" :disabled="submitting" class="btn btn-primary">
|
||||
<button
|
||||
type="submit"
|
||||
form="edit-account-form"
|
||||
:disabled="submitting"
|
||||
class="btn btn-primary"
|
||||
>
|
||||
<svg
|
||||
v-if="submitting"
|
||||
class="-ml-1 mr-2 h-4 w-4 animate-spin"
|
||||
@@ -487,8 +505,8 @@
|
||||
{{ submitting ? t('admin.accounts.updating') : t('common.update') }}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</Modal>
|
||||
</template>
|
||||
</BaseDialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
@@ -497,7 +515,7 @@ import { useI18n } from 'vue-i18n'
|
||||
import { useAppStore } from '@/stores/app'
|
||||
import { adminAPI } from '@/api/admin'
|
||||
import type { Account, Proxy, Group } from '@/types'
|
||||
import Modal from '@/components/common/Modal.vue'
|
||||
import BaseDialog from '@/components/common/BaseDialog.vue'
|
||||
import Select from '@/components/common/Select.vue'
|
||||
import ProxySelector from '@/components/common/ProxySelector.vue'
|
||||
import GroupSelector from '@/components/common/GroupSelector.vue'
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div
|
||||
class="rounded-lg border border-blue-200 bg-blue-50 p-6 dark:border-blue-700 dark:bg-blue-900/30"
|
||||
class="rounded-lg border border-blue-200 bg-blue-50 p-4 dark:border-blue-700 dark:bg-blue-900/30"
|
||||
>
|
||||
<div class="flex items-start gap-4">
|
||||
<div class="flex h-10 w-10 flex-shrink-0 items-center justify-center rounded-lg bg-blue-500">
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<template>
|
||||
<Modal
|
||||
<BaseDialog
|
||||
:show="show"
|
||||
:title="t('admin.accounts.reAuthorizeAccount')"
|
||||
size="lg"
|
||||
width="wide"
|
||||
@close="handleClose"
|
||||
>
|
||||
<div v-if="account" class="space-y-5">
|
||||
<div v-if="account" class="space-y-4">
|
||||
<!-- Account Info -->
|
||||
<div
|
||||
class="rounded-lg border border-gray-200 bg-gray-50 p-4 dark:border-dark-600 dark:bg-dark-700"
|
||||
@@ -53,8 +53,8 @@
|
||||
</div>
|
||||
|
||||
<!-- Add Method Selection (Claude only) -->
|
||||
<div v-if="isAnthropic">
|
||||
<label class="input-label">{{ t('admin.accounts.oauth.authMethod') }}</label>
|
||||
<fieldset v-if="isAnthropic" class="border-0 p-0">
|
||||
<legend class="input-label">{{ t('admin.accounts.oauth.authMethod') }}</legend>
|
||||
<div class="mt-2 flex gap-4">
|
||||
<label class="flex cursor-pointer items-center">
|
||||
<input
|
||||
@@ -79,11 +79,11 @@
|
||||
}}</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<!-- Gemini OAuth Type Selection -->
|
||||
<div v-if="isGemini">
|
||||
<label class="input-label">{{ t('admin.accounts.oauth.gemini.oauthTypeLabel') }}</label>
|
||||
<fieldset v-if="isGemini" class="border-0 p-0">
|
||||
<legend class="input-label">{{ t('admin.accounts.oauth.gemini.oauthTypeLabel') }}</legend>
|
||||
<div class="mt-2 grid grid-cols-2 gap-3">
|
||||
<button
|
||||
type="button"
|
||||
@@ -187,7 +187,7 @@
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<OAuthAuthorizationFlow
|
||||
ref="oauthFlowRef"
|
||||
@@ -207,7 +207,10 @@
|
||||
@cookie-auth="handleCookieAuth"
|
||||
/>
|
||||
|
||||
<div class="flex justify-between gap-3 pt-4">
|
||||
</div>
|
||||
|
||||
<template #footer>
|
||||
<div v-if="account" class="flex justify-between gap-3">
|
||||
<button type="button" class="btn btn-secondary" @click="handleClose">
|
||||
{{ t('common.cancel') }}
|
||||
</button>
|
||||
@@ -245,8 +248,8 @@
|
||||
}}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</Modal>
|
||||
</template>
|
||||
</BaseDialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
@@ -262,7 +265,7 @@ import {
|
||||
import { useOpenAIOAuth } from '@/composables/useOpenAIOAuth'
|
||||
import { useGeminiOAuth } from '@/composables/useGeminiOAuth'
|
||||
import type { Account } from '@/types'
|
||||
import Modal from '@/components/common/Modal.vue'
|
||||
import BaseDialog from '@/components/common/BaseDialog.vue'
|
||||
import OAuthAuthorizationFlow from './OAuthAuthorizationFlow.vue'
|
||||
|
||||
// Type for exposed OAuthAuthorizationFlow component
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
<template>
|
||||
<Modal
|
||||
<BaseDialog
|
||||
:show="show"
|
||||
:title="t('admin.accounts.syncFromCrsTitle')"
|
||||
size="lg"
|
||||
width="normal"
|
||||
close-on-click-outside
|
||||
@close="handleClose"
|
||||
>
|
||||
<div class="space-y-4">
|
||||
<form id="sync-from-crs-form" class="space-y-4" @submit.prevent="handleSync">
|
||||
<div class="text-sm text-gray-600 dark:text-dark-300">
|
||||
{{ t('admin.accounts.syncFromCrsDesc') }}
|
||||
</div>
|
||||
@@ -84,25 +84,30 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<template #footer>
|
||||
<div class="flex justify-end gap-3">
|
||||
<button class="btn btn-secondary" :disabled="syncing" @click="handleClose">
|
||||
<button class="btn btn-secondary" type="button" :disabled="syncing" @click="handleClose">
|
||||
{{ t('common.cancel') }}
|
||||
</button>
|
||||
<button class="btn btn-primary" :disabled="syncing" @click="handleSync">
|
||||
<button
|
||||
class="btn btn-primary"
|
||||
type="submit"
|
||||
form="sync-from-crs-form"
|
||||
:disabled="syncing"
|
||||
>
|
||||
{{ syncing ? t('admin.accounts.syncing') : t('admin.accounts.syncNow') }}
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
</Modal>
|
||||
</BaseDialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, reactive, ref, watch } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import Modal from '@/components/common/Modal.vue'
|
||||
import BaseDialog from '@/components/common/BaseDialog.vue'
|
||||
import { useAppStore } from '@/stores/app'
|
||||
import { adminAPI } from '@/api/admin'
|
||||
|
||||
|
||||
Reference in New Issue
Block a user