124 lines
3.8 KiB
Vue
124 lines
3.8 KiB
Vue
<script setup lang="ts">
|
|
import { ref, computed, watch } from 'vue'
|
|
import { useIntegrationStore } from '@KTXC/stores/integrationStore'
|
|
import type { ServiceLocation } from '@MailManager/types/service'
|
|
|
|
const props = defineProps<{
|
|
providerId: string
|
|
discoveredLocation?: ServiceLocation
|
|
modelValue?: ServiceLocation | null
|
|
}>()
|
|
|
|
const emit = defineEmits<{
|
|
'update:modelValue': [value: ServiceLocation]
|
|
'valid': [value: boolean]
|
|
}>()
|
|
|
|
const integrationStore = useIntegrationStore()
|
|
|
|
const loadedPanels = new Map<string, any>()
|
|
const currentProviderPanel = ref<any>(null)
|
|
const loadingPanel = ref(false)
|
|
const localLocation = ref<ServiceLocation | undefined>(props.modelValue || props.discoveredLocation)
|
|
|
|
// The full integration ID (e.g., "provider_jmapc.jmap")
|
|
const effectiveIntegrationId = computed(() => {
|
|
return props.providerId
|
|
})
|
|
|
|
// Load provider panel dynamically using the integration ID
|
|
async function loadProviderPanel(integrationId: string) {
|
|
if (loadedPanels.has(integrationId)) {
|
|
currentProviderPanel.value = loadedPanels.get(integrationId)
|
|
return
|
|
}
|
|
|
|
loadingPanel.value = true
|
|
|
|
// Try to find panel - integration IDs are prefixed with module handle
|
|
// so we need to search for panels that match the provider ID
|
|
const panels = integrationStore.getItems('mail_account_config_panels')
|
|
const panelConfig = panels.find((panel: any) => {
|
|
// Check if the ID ends with the provider ID (e.g., "provider_jmapc.jmap" contains "jmap")
|
|
return panel.id === integrationId || panel.id.endsWith(`.${integrationId}`)
|
|
})
|
|
|
|
if (!panelConfig?.component) {
|
|
console.warn(`No config panel found for provider ID: ${integrationId}`)
|
|
console.warn(`Available panels:`, panels.map((p: any) => p.id))
|
|
currentProviderPanel.value = null
|
|
loadingPanel.value = false
|
|
return
|
|
}
|
|
|
|
try {
|
|
const module = await panelConfig.component()
|
|
const component = module.default || module
|
|
loadedPanels.set(integrationId, component)
|
|
currentProviderPanel.value = component
|
|
} catch (error) {
|
|
console.error(`Failed to load panel for ${integrationId}:`, error)
|
|
currentProviderPanel.value = null
|
|
} finally {
|
|
loadingPanel.value = false
|
|
}
|
|
}
|
|
|
|
watch(effectiveIntegrationId, (newIntegrationId, oldIntegrationId) => {
|
|
if (newIntegrationId && newIntegrationId !== oldIntegrationId) {
|
|
loadProviderPanel(newIntegrationId)
|
|
}
|
|
}, { immediate: true })
|
|
|
|
function handleLocationUpdate(location: ServiceLocation) {
|
|
localLocation.value = location
|
|
emit('update:modelValue', location)
|
|
// Emit valid when location is provided
|
|
emit('valid', !!location)
|
|
}
|
|
|
|
// Watch for prop changes
|
|
watch(() => props.modelValue, (newValue) => {
|
|
if (newValue) {
|
|
localLocation.value = newValue
|
|
}
|
|
})
|
|
|
|
watch(() => props.discoveredLocation, (newValue) => {
|
|
if (newValue && !props.modelValue) {
|
|
localLocation.value = newValue
|
|
emit('update:modelValue', newValue)
|
|
emit('valid', true)
|
|
}
|
|
})
|
|
</script>
|
|
|
|
<template>
|
|
<div class="provider-config-step">
|
|
<h3 class="text-h6 mb-2">Protocol Configuration</h3>
|
|
<p class="text-body-2 text-medium-emphasis mb-6">
|
|
Configure the connection settings for your mail service
|
|
</p>
|
|
|
|
<!-- Dynamic Provider Panel -->
|
|
<component
|
|
v-if="currentProviderPanel"
|
|
:is="currentProviderPanel"
|
|
v-model="localLocation"
|
|
:discovered-location="discoveredLocation"
|
|
@update:model-value="handleLocationUpdate"
|
|
/>
|
|
|
|
<!-- Loading state for panel -->
|
|
<div v-else-if="loadingPanel" class="text-center py-8">
|
|
<v-progress-circular indeterminate color="primary" />
|
|
<p class="text-caption text-medium-emphasis mt-2">Loading configuration panel...</p>
|
|
</div>
|
|
|
|
<!-- No panel available -->
|
|
<v-alert v-else type="info" variant="tonal">
|
|
<v-icon start>mdi-information</v-icon>
|
|
No configuration panel available for this provider
|
|
</v-alert>
|
|
</div>
|
|
</template> |