mirror of
https://github.com/jxxghp/MoviePilot-Frontend.git
synced 2026-05-06 20:43:03 +08:00
feat: add site auth step to setup wizard
This commit is contained in:
@@ -18,6 +18,11 @@ export interface WizardData {
|
||||
proxyHost: string
|
||||
githubToken: string
|
||||
}
|
||||
siteAuth: {
|
||||
auxiliaryAuthEnable: boolean
|
||||
site: string
|
||||
params: Record<string, string | number>
|
||||
}
|
||||
storage: {
|
||||
downloadPath: string
|
||||
libraryPath: string
|
||||
@@ -85,6 +90,10 @@ export interface ConnectivityTestState {
|
||||
}
|
||||
|
||||
export interface ValidationErrorState {
|
||||
siteAuth: {
|
||||
site: boolean
|
||||
[key: string]: boolean
|
||||
}
|
||||
downloader: {
|
||||
name: boolean
|
||||
host: boolean
|
||||
@@ -114,7 +123,7 @@ export interface ValidationErrorState {
|
||||
|
||||
// 全局状态,所有组件共享
|
||||
const currentStep = ref(1)
|
||||
const totalSteps = 7
|
||||
const totalSteps = 8
|
||||
|
||||
// 加载状态
|
||||
const isLoading = ref(false)
|
||||
@@ -122,6 +131,22 @@ const isLoading = ref(false)
|
||||
// 选中的预设规则
|
||||
const selectedPreset = ref('')
|
||||
|
||||
// 可认证站点列表
|
||||
const authSites = ref<{
|
||||
[key: string]: {
|
||||
name: string
|
||||
icon: string
|
||||
params: {
|
||||
[key: string]: {
|
||||
name: string
|
||||
type: string
|
||||
placeholder?: string
|
||||
tooltip?: string
|
||||
}
|
||||
}
|
||||
}
|
||||
}>({})
|
||||
|
||||
// 向导数据
|
||||
const wizardData = ref<WizardData>({
|
||||
basic: {
|
||||
@@ -135,6 +160,11 @@ const wizardData = ref<WizardData>({
|
||||
proxyHost: '',
|
||||
githubToken: '',
|
||||
},
|
||||
siteAuth: {
|
||||
auxiliaryAuthEnable: false,
|
||||
site: '',
|
||||
params: {},
|
||||
},
|
||||
storage: {
|
||||
downloadPath: '',
|
||||
libraryPath: '',
|
||||
@@ -194,6 +224,9 @@ const connectivityTest = ref<ConnectivityTestState>({
|
||||
|
||||
// 验证错误状态
|
||||
const validationErrors = ref<ValidationErrorState>({
|
||||
siteAuth: {
|
||||
site: false,
|
||||
},
|
||||
downloader: {
|
||||
name: false,
|
||||
host: false,
|
||||
@@ -256,6 +289,7 @@ export function useSetupWizard() {
|
||||
// 步骤标题
|
||||
const stepTitles = computed(() => [
|
||||
t('setupWizard.basic.title'),
|
||||
t('setupWizard.siteAuth.title'),
|
||||
t('setupWizard.storage.title'),
|
||||
t('setupWizard.downloader.title'),
|
||||
t('setupWizard.mediaServer.title'),
|
||||
@@ -267,6 +301,7 @@ export function useSetupWizard() {
|
||||
// 步骤描述
|
||||
const stepDescriptions = computed(() => [
|
||||
t('setupWizard.basic.description'),
|
||||
t('setupWizard.siteAuth.description'),
|
||||
t('setupWizard.storage.description'),
|
||||
t('setupWizard.downloader.description'),
|
||||
t('setupWizard.mediaServer.description'),
|
||||
@@ -378,6 +413,9 @@ export function useSetupWizard() {
|
||||
|
||||
// 清除验证错误状态
|
||||
function clearValidationErrors() {
|
||||
validationErrors.value.siteAuth = {
|
||||
site: false,
|
||||
}
|
||||
validationErrors.value.downloader = {
|
||||
name: false,
|
||||
host: false,
|
||||
@@ -404,6 +442,47 @@ export function useSetupWizard() {
|
||||
}
|
||||
}
|
||||
|
||||
// 验证用户站点认证字段
|
||||
function validateSiteAuthFields(): { isValid: boolean; errors: string[] } {
|
||||
const errors: string[] = []
|
||||
clearValidationErrors()
|
||||
|
||||
if (!wizardData.value.siteAuth.site) {
|
||||
return {
|
||||
isValid: true,
|
||||
errors,
|
||||
}
|
||||
}
|
||||
|
||||
const selectedSite = authSites.value[wizardData.value.siteAuth.site]
|
||||
if (!selectedSite) {
|
||||
errors.push(t('setupWizard.siteAuth.siteConfigNotExist'))
|
||||
validationErrors.value.siteAuth.site = true
|
||||
return {
|
||||
isValid: false,
|
||||
errors,
|
||||
}
|
||||
}
|
||||
|
||||
const fields = Object.keys(selectedSite.params || {}).filter(key => {
|
||||
return selectedSite.params[key]?.name && selectedSite.params[key]?.type
|
||||
})
|
||||
|
||||
fields.forEach(key => {
|
||||
const fieldKey = `${wizardData.value.siteAuth.site.toUpperCase()}_${key.toUpperCase()}`
|
||||
const value = wizardData.value.siteAuth.params[fieldKey]
|
||||
if (value === undefined || value === null || value === '') {
|
||||
errors.push(t('setupWizard.siteAuth.fieldRequired', { name: selectedSite.params[key].name }))
|
||||
validationErrors.value.siteAuth[fieldKey] = true
|
||||
}
|
||||
})
|
||||
|
||||
return {
|
||||
isValid: errors.length === 0,
|
||||
errors,
|
||||
}
|
||||
}
|
||||
|
||||
// 验证下载器字段
|
||||
function validateDownloaderFields(): { isValid: boolean; errors: string[] } {
|
||||
const errors: string[] = []
|
||||
@@ -645,6 +724,13 @@ export function useSetupWizard() {
|
||||
break
|
||||
|
||||
case 2: // 存储设置
|
||||
if (wizardData.value.siteAuth.site) {
|
||||
const validation = validateSiteAuthFields()
|
||||
errors.push(...validation.errors)
|
||||
}
|
||||
break
|
||||
|
||||
case 3: // 存储设置
|
||||
if (!wizardData.value.storage.downloadPath) {
|
||||
errors.push(t('setupWizard.storage.downloadPathRequired'))
|
||||
}
|
||||
@@ -653,7 +739,7 @@ export function useSetupWizard() {
|
||||
}
|
||||
break
|
||||
|
||||
case 3: // 下载器设置
|
||||
case 4: // 下载器设置
|
||||
if (wizardData.value.downloader.type) {
|
||||
// 如果选择了下载器,则验证必输项
|
||||
const validation = validateDownloaderFields()
|
||||
@@ -661,7 +747,7 @@ export function useSetupWizard() {
|
||||
}
|
||||
break
|
||||
|
||||
case 4: // 媒体服务器设置
|
||||
case 5: // 媒体服务器设置
|
||||
if (wizardData.value.mediaServer.type) {
|
||||
// 如果选择了媒体服务器,则验证必输项
|
||||
const validation = validateMediaServerFields()
|
||||
@@ -669,7 +755,7 @@ export function useSetupWizard() {
|
||||
}
|
||||
break
|
||||
|
||||
case 5: // 通知设置
|
||||
case 6: // 通知设置
|
||||
if (wizardData.value.notification.type) {
|
||||
// 如果选择了通知,则验证必输项
|
||||
const validation = validateNotificationFields()
|
||||
@@ -677,14 +763,14 @@ export function useSetupWizard() {
|
||||
}
|
||||
break
|
||||
|
||||
case 6: // 智能助手设置
|
||||
case 7: // 智能助手设置
|
||||
if (wizardData.value.agent.enabled) {
|
||||
const validation = validateAgentFields()
|
||||
errors.push(...validation.errors)
|
||||
}
|
||||
break
|
||||
|
||||
case 7: // 偏好设置
|
||||
case 8: // 偏好设置
|
||||
// 偏好设置有默认值,不需要验证
|
||||
break
|
||||
}
|
||||
@@ -699,12 +785,14 @@ export function useSetupWizard() {
|
||||
function shouldPerformTest(step: number): boolean {
|
||||
switch (step) {
|
||||
case 2: // 存储目录测试 - 总是需要测试
|
||||
return false
|
||||
case 3: // 存储目录测试 - 总是需要测试
|
||||
return true
|
||||
case 3: // 下载器测试 - 只有选择了下载器才测试
|
||||
case 4: // 下载器测试 - 只有选择了下载器才测试
|
||||
return !!wizardData.value.downloader.type
|
||||
case 4: // 媒体服务器测试 - 只有选择了媒体服务器才测试
|
||||
case 5: // 媒体服务器测试 - 只有选择了媒体服务器才测试
|
||||
return !!wizardData.value.mediaServer.type
|
||||
case 5: // 消息通知测试 - 只有选择了通知才测试
|
||||
case 6: // 消息通知测试 - 只有选择了通知才测试
|
||||
return !!wizardData.value.notification.type
|
||||
default:
|
||||
return false
|
||||
@@ -724,15 +812,17 @@ export function useSetupWizard() {
|
||||
|
||||
switch (step) {
|
||||
case 2: // 存储目录测试
|
||||
break
|
||||
case 3: // 存储目录测试
|
||||
testResult = await testStorageConnectivity()
|
||||
break
|
||||
case 3: // 下载器测试
|
||||
case 4: // 下载器测试
|
||||
testResult = await testDownloaderConnectivity()
|
||||
break
|
||||
case 4: // 媒体服务器测试
|
||||
case 5: // 媒体服务器测试
|
||||
testResult = await testMediaServerConnectivity()
|
||||
break
|
||||
case 5: // 消息通知测试
|
||||
case 6: // 消息通知测试
|
||||
testResult = await testNotificationConnectivity()
|
||||
break
|
||||
}
|
||||
@@ -957,16 +1047,18 @@ export function useSetupWizard() {
|
||||
case 1:
|
||||
return await saveBasicSettings()
|
||||
case 2:
|
||||
return await saveStorageSettings()
|
||||
return await saveSiteAuthSettings()
|
||||
case 3:
|
||||
return await saveDownloaderSettings()
|
||||
return await saveStorageSettings()
|
||||
case 4:
|
||||
return await saveMediaServerSettings()
|
||||
return await saveDownloaderSettings()
|
||||
case 5:
|
||||
return await saveNotificationSettings()
|
||||
return await saveMediaServerSettings()
|
||||
case 6:
|
||||
return await saveAgentSettings()
|
||||
return await saveNotificationSettings()
|
||||
case 7:
|
||||
return await saveAgentSettings()
|
||||
case 8:
|
||||
return await savePreferenceSettings()
|
||||
}
|
||||
} catch (error) {
|
||||
@@ -1109,6 +1201,39 @@ export function useSetupWizard() {
|
||||
}
|
||||
}
|
||||
|
||||
// 保存用户站点认证设置
|
||||
async function saveSiteAuthSettings() {
|
||||
try {
|
||||
const envResponse: { [key: string]: any } = await api.post('system/env', {
|
||||
AUXILIARY_AUTH_ENABLE: wizardData.value.siteAuth.auxiliaryAuthEnable,
|
||||
})
|
||||
|
||||
if (!envResponse.success) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (!wizardData.value.siteAuth.site) {
|
||||
return true
|
||||
}
|
||||
|
||||
const response: { [key: string]: any } = await api.post('site/auth', {
|
||||
site: wizardData.value.siteAuth.site,
|
||||
params: wizardData.value.siteAuth.params,
|
||||
})
|
||||
|
||||
if (!response.success) {
|
||||
$toast.error(t('setupWizard.saveSiteAuthSettingsFailed', { message: response.message }))
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
} catch (error) {
|
||||
console.error('Save site auth settings failed:', error)
|
||||
$toast.error(t('setupWizard.saveSiteAuthSettingsFailed', { message: (error as Error).message || '' }))
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// 保存下载器配置
|
||||
async function saveDownloaderSettings() {
|
||||
if (wizardData.value.downloader.type) {
|
||||
@@ -1298,6 +1423,7 @@ export function useSetupWizard() {
|
||||
if (result.data.GITHUB_TOKEN) {
|
||||
wizardData.value.basic.githubToken = result.data.GITHUB_TOKEN
|
||||
}
|
||||
wizardData.value.siteAuth.auxiliaryAuthEnable = Boolean(result.data.AUXILIARY_AUTH_ENABLE)
|
||||
if (result.data.SUPERUSER) {
|
||||
wizardData.value.basic.username = result.data.SUPERUSER
|
||||
}
|
||||
@@ -1326,6 +1452,28 @@ export function useSetupWizard() {
|
||||
}
|
||||
}
|
||||
|
||||
// 加载用户站点认证列表
|
||||
async function loadAuthSites() {
|
||||
try {
|
||||
authSites.value = (await api.get('site/auth')) || {}
|
||||
} catch (error) {
|
||||
console.log('Load auth sites failed:', error)
|
||||
}
|
||||
}
|
||||
|
||||
// 加载用户站点认证设置
|
||||
async function loadSiteAuthSettings() {
|
||||
try {
|
||||
const result: { [key: string]: any } = await api.get('system/setting/UserSiteAuthParams')
|
||||
if (result.success && result.data?.value) {
|
||||
wizardData.value.siteAuth.site = result.data.value.site || ''
|
||||
wizardData.value.siteAuth.params = result.data.value.params || {}
|
||||
}
|
||||
} catch (error) {
|
||||
console.log('Load site auth settings failed:', error)
|
||||
}
|
||||
}
|
||||
|
||||
// 加载存储设置
|
||||
async function loadStorageSettings() {
|
||||
try {
|
||||
@@ -1395,6 +1543,8 @@ export function useSetupWizard() {
|
||||
isLoading.value = true
|
||||
try {
|
||||
await loadSystemSettings()
|
||||
await loadAuthSites()
|
||||
await loadSiteAuthSettings()
|
||||
await loadStorageSettings()
|
||||
await loadDownloaderSettings()
|
||||
await loadMediaServerSettings()
|
||||
@@ -1411,6 +1561,7 @@ export function useSetupWizard() {
|
||||
stepTitles,
|
||||
stepDescriptions,
|
||||
wizardData,
|
||||
authSites,
|
||||
selectedPreset,
|
||||
connectivityTest,
|
||||
validationErrors,
|
||||
@@ -1425,6 +1576,7 @@ export function useSetupWizard() {
|
||||
selectPreset,
|
||||
updatePreferences,
|
||||
validateCurrentStep,
|
||||
validateSiteAuthFields,
|
||||
validateDownloaderFields,
|
||||
validateMediaServerFields,
|
||||
validateNotificationFields,
|
||||
|
||||
@@ -3183,6 +3183,7 @@ export default {
|
||||
saveMediaServerSettingsFailed: 'Failed to save media server settings',
|
||||
notificationSettingsSaved: 'Notification settings saved successfully',
|
||||
saveNotificationSettingsFailed: 'Failed to save notification settings',
|
||||
saveSiteAuthSettingsFailed: 'Failed to save user site authentication settings: {message}',
|
||||
saveAgentSettingsFailed: 'Failed to save AI assistant settings',
|
||||
preferenceSettingsSaved: 'Preference settings saved successfully',
|
||||
savePreferenceSettingsFailed: 'Failed to save preference settings',
|
||||
@@ -3205,6 +3206,17 @@ export default {
|
||||
confirmPasswordHint: 'Confirm new password',
|
||||
apiTokenRequired: 'API Token is required',
|
||||
},
|
||||
siteAuth: {
|
||||
title: 'User Authentication',
|
||||
description: 'Configure site authentication and auxiliary authentication',
|
||||
info: 'User Site Authentication',
|
||||
infoDesc:
|
||||
'Completing site authentication unlocks site capabilities and some plugin permissions. This step is optional and can also be configured later from the user menu.',
|
||||
selectSiteHint: 'Choose a supported auth site and fill in the required credentials for that site',
|
||||
submitHint: 'When you click Next, the wizard will immediately validate against the selected auth site and save the current parameters on success.',
|
||||
siteConfigNotExist: 'Authentication site configuration does not exist',
|
||||
fieldRequired: 'Please enter {name}',
|
||||
},
|
||||
storage: {
|
||||
title: 'Storage',
|
||||
description: 'Configure download directory and media library directory',
|
||||
|
||||
@@ -3147,6 +3147,7 @@ export default {
|
||||
saveMediaServerSettingsFailed: '保存媒体服务器设置失败',
|
||||
notificationSettingsSaved: '通知设置保存成功',
|
||||
saveNotificationSettingsFailed: '保存通知设置失败',
|
||||
saveSiteAuthSettingsFailed: '保存用户站点认证设置失败:{message}',
|
||||
saveAgentSettingsFailed: '保存智能助手设置失败',
|
||||
preferenceSettingsSaved: '偏好设置保存成功',
|
||||
savePreferenceSettingsFailed: '保存偏好设置失败',
|
||||
@@ -3169,6 +3170,16 @@ export default {
|
||||
confirmPasswordHint: '确认新密码',
|
||||
apiTokenRequired: 'API Token不能为空',
|
||||
},
|
||||
siteAuth: {
|
||||
title: '用户认证',
|
||||
description: '配置用户站点认证与辅助认证',
|
||||
info: '用户站点认证说明',
|
||||
infoDesc: '完成站点认证后可解锁站点能力与部分插件权限。此步骤可选,后续也可在个人菜单中继续配置。',
|
||||
selectSiteHint: '选择一个支持认证的站点,并填写该站点要求的认证参数',
|
||||
submitHint: '点击下一步时将立即向认证站点发起校验,认证成功后会保存当前参数。',
|
||||
siteConfigNotExist: '认证站点配置不存在',
|
||||
fieldRequired: '请输入{name}',
|
||||
},
|
||||
storage: {
|
||||
title: '存储',
|
||||
description: '配置下载目录和媒体库目录',
|
||||
|
||||
@@ -3148,6 +3148,7 @@ export default {
|
||||
saveMediaServerSettingsFailed: '保存媒體服務器設置失敗',
|
||||
notificationSettingsSaved: '通知設置保存成功',
|
||||
saveNotificationSettingsFailed: '保存通知設置失敗',
|
||||
saveSiteAuthSettingsFailed: '保存用戶站點認證設置失敗:{message}',
|
||||
saveAgentSettingsFailed: '保存智能助手設置失敗',
|
||||
preferenceSettingsSaved: '偏好設置保存成功',
|
||||
savePreferenceSettingsFailed: '保存偏好設置失敗',
|
||||
@@ -3170,6 +3171,16 @@ export default {
|
||||
confirmPasswordHint: '確認新密碼',
|
||||
apiTokenRequired: 'API Token 不能為空',
|
||||
},
|
||||
siteAuth: {
|
||||
title: '用戶認證',
|
||||
description: '配置用戶站點認證與輔助認證',
|
||||
info: '用戶站點認證說明',
|
||||
infoDesc: '完成站點認證後可解鎖站點能力與部分插件權限。此步驟可選,後續也可在個人選單中繼續配置。',
|
||||
selectSiteHint: '選擇一個支援認證的站點,並填寫該站點要求的認證參數',
|
||||
submitHint: '點擊下一步時將立即向認證站點發起校驗,認證成功後會保存當前參數。',
|
||||
siteConfigNotExist: '認證站點配置不存在',
|
||||
fieldRequired: '請輸入{name}',
|
||||
},
|
||||
storage: {
|
||||
title: '儲存',
|
||||
description: '設定下載目錄和媒體庫目錄',
|
||||
|
||||
@@ -4,6 +4,7 @@ import { useI18n } from 'vue-i18n'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { useSetupWizard } from '@/composables/useSetupWizard'
|
||||
import BasicSettingsStep from '@/views/setup/BasicSettingsStep.vue'
|
||||
import SiteAuthSettingsStep from '@/views/setup/SiteAuthSettingsStep.vue'
|
||||
import StorageSettingsStep from '@/views/setup/StorageSettingsStep.vue'
|
||||
import DownloaderSettingsStep from '@/views/setup/DownloaderSettingsStep.vue'
|
||||
import MediaServerSettingsStep from '@/views/setup/MediaServerSettingsStep.vue'
|
||||
@@ -102,33 +103,38 @@ onMounted(async () => {
|
||||
<BasicSettingsStep />
|
||||
</VStepperWindowItem>
|
||||
|
||||
<!-- 步骤2:存储目录 -->
|
||||
<!-- 步骤2:用户认证 -->
|
||||
<VStepperWindowItem :value="2">
|
||||
<SiteAuthSettingsStep />
|
||||
</VStepperWindowItem>
|
||||
|
||||
<!-- 步骤3:存储目录 -->
|
||||
<VStepperWindowItem :value="3">
|
||||
<StorageSettingsStep />
|
||||
</VStepperWindowItem>
|
||||
|
||||
<!-- 步骤3:下载器 -->
|
||||
<VStepperWindowItem :value="3">
|
||||
<!-- 步骤4:下载器 -->
|
||||
<VStepperWindowItem :value="4">
|
||||
<DownloaderSettingsStep />
|
||||
</VStepperWindowItem>
|
||||
|
||||
<!-- 步骤4:媒体服务器 -->
|
||||
<VStepperWindowItem :value="4">
|
||||
<!-- 步骤5:媒体服务器 -->
|
||||
<VStepperWindowItem :value="5">
|
||||
<MediaServerSettingsStep />
|
||||
</VStepperWindowItem>
|
||||
|
||||
<!-- 步骤5:通知 -->
|
||||
<VStepperWindowItem :value="5">
|
||||
<!-- 步骤6:通知 -->
|
||||
<VStepperWindowItem :value="6">
|
||||
<NotificationSettingsStep />
|
||||
</VStepperWindowItem>
|
||||
|
||||
<!-- 步骤6:智能助手 -->
|
||||
<VStepperWindowItem :value="6">
|
||||
<!-- 步骤7:智能助手 -->
|
||||
<VStepperWindowItem :value="7">
|
||||
<AgentSettingsStep />
|
||||
</VStepperWindowItem>
|
||||
|
||||
<!-- 步骤7:资源偏好 -->
|
||||
<VStepperWindowItem :value="7">
|
||||
<!-- 步骤8:资源偏好 -->
|
||||
<VStepperWindowItem :value="8">
|
||||
<PreferencesSettingsStep />
|
||||
</VStepperWindowItem>
|
||||
</VStepperWindow>
|
||||
|
||||
103
src/views/setup/SiteAuthSettingsStep.vue
Normal file
103
src/views/setup/SiteAuthSettingsStep.vue
Normal file
@@ -0,0 +1,103 @@
|
||||
<script lang="ts" setup>
|
||||
import { computed } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useSetupWizard } from '@/composables/useSetupWizard'
|
||||
|
||||
const { t } = useI18n()
|
||||
const { wizardData, authSites, validationErrors } = useSetupWizard()
|
||||
|
||||
const siteItems = computed(() => {
|
||||
return Object.keys(authSites.value).map(key => ({
|
||||
key,
|
||||
name: authSites.value[key].name,
|
||||
prependAvatar: authSites.value[key].icon,
|
||||
}))
|
||||
})
|
||||
|
||||
const formFields = computed(() => {
|
||||
const site = authSites.value[wizardData.value.siteAuth.site]
|
||||
return Object.keys(site?.params || {})
|
||||
.filter(key => site.params[key]?.name && site.params[key]?.type)
|
||||
.map(key => ({
|
||||
key,
|
||||
site: wizardData.value.siteAuth.site,
|
||||
name: site.params[key].name,
|
||||
type: site.params[key].type,
|
||||
placeholder: site.params[key].placeholder,
|
||||
tooltip: site.params[key].tooltip,
|
||||
}))
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VCard variant="outlined">
|
||||
<VCardText>
|
||||
<div class="text-center mb-6">
|
||||
<h3 class="text-h4 mb-2">{{ t('setupWizard.siteAuth.title') }}</h3>
|
||||
<p class="text-body-1 text-medium-emphasis">{{ t('setupWizard.siteAuth.description') }}</p>
|
||||
</div>
|
||||
|
||||
<VRow>
|
||||
<VCol cols="12">
|
||||
<VAlert type="info" variant="tonal" class="mb-4">
|
||||
<VAlertTitle>{{ t('setupWizard.siteAuth.info') }}</VAlertTitle>
|
||||
{{ t('setupWizard.siteAuth.infoDesc') }}
|
||||
</VAlert>
|
||||
</VCol>
|
||||
|
||||
<VCol cols="12">
|
||||
<VSwitch
|
||||
v-model="wizardData.siteAuth.auxiliaryAuthEnable"
|
||||
:label="t('setting.system.auxAuthEnable')"
|
||||
:hint="t('setting.system.auxAuthEnableHint')"
|
||||
persistent-hint
|
||||
color="primary"
|
||||
/>
|
||||
</VCol>
|
||||
|
||||
<VCol cols="12">
|
||||
<VSelect
|
||||
v-model="wizardData.siteAuth.site"
|
||||
:items="siteItems"
|
||||
item-value="key"
|
||||
item-title="name"
|
||||
item-props
|
||||
:label="t('dialog.userAuth.selectSite')"
|
||||
:hint="t('setupWizard.siteAuth.selectSiteHint')"
|
||||
:error="validationErrors.siteAuth.site"
|
||||
:error-messages="validationErrors.siteAuth.site ? [t('dialog.userAuth.selectSiteRequired')] : []"
|
||||
persistent-hint
|
||||
prepend-inner-icon="mdi-web"
|
||||
clearable
|
||||
/>
|
||||
</VCol>
|
||||
|
||||
<template v-if="wizardData.siteAuth.site">
|
||||
<VCol cols="12">
|
||||
<VAlert type="warning" variant="tonal">
|
||||
{{ t('setupWizard.siteAuth.submitHint') }}
|
||||
</VAlert>
|
||||
</VCol>
|
||||
|
||||
<VCol v-for="param in formFields" :key="param.key" cols="12" md="6">
|
||||
<VTextField
|
||||
v-model="wizardData.siteAuth.params[param.site.toUpperCase() + '_' + param.key.toUpperCase()]"
|
||||
:type="param.type"
|
||||
:label="param.name"
|
||||
:placeholder="param.placeholder"
|
||||
:hint="param.tooltip"
|
||||
:error="validationErrors.siteAuth[param.site.toUpperCase() + '_' + param.key.toUpperCase()]"
|
||||
:error-messages="
|
||||
validationErrors.siteAuth[param.site.toUpperCase() + '_' + param.key.toUpperCase()]
|
||||
? [t('setupWizard.siteAuth.fieldRequired', { name: param.name })]
|
||||
: []
|
||||
"
|
||||
clearable
|
||||
persistent-hint
|
||||
/>
|
||||
</VCol>
|
||||
</template>
|
||||
</VRow>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</template>
|
||||
Reference in New Issue
Block a user