101 lines
2.2 KiB
Vue
101 lines
2.2 KiB
Vue
<script setup lang="ts">
|
|
import { ref, onMounted } from 'vue';
|
|
import { useIntegrationStore } from '@KTXC/stores/integrationStore';
|
|
import type { User } from '@/types';
|
|
|
|
interface SecurityPanel {
|
|
id: string;
|
|
label: string;
|
|
icon?: string;
|
|
priority: number;
|
|
component: any;
|
|
}
|
|
|
|
const props = defineProps<{
|
|
user: User;
|
|
}>();
|
|
|
|
const emit = defineEmits<{
|
|
update: [];
|
|
}>();
|
|
|
|
const integrationStore = useIntegrationStore();
|
|
const panels = ref<SecurityPanel[]>([]);
|
|
const loading = ref(false);
|
|
|
|
// Load panels from integration store and resolve component promises
|
|
const loadPanels = async () => {
|
|
const integrations = integrationStore.getItems('user_manager_security_panels');
|
|
const components = [];
|
|
|
|
for (const panel of integrations) {
|
|
try {
|
|
if (panel.component) {
|
|
const module = await panel.component();
|
|
components.push({
|
|
id: panel.id,
|
|
label: panel.label || panel.id,
|
|
icon: panel.icon,
|
|
priority: panel.priority ?? 100,
|
|
component: module.default
|
|
});
|
|
}
|
|
} catch (error) {
|
|
console.error('[UserManager] Failed to load security panel component for', panel.id, ':', error);
|
|
}
|
|
}
|
|
|
|
panels.value = components.sort((a, b) => a.priority - b.priority);
|
|
};
|
|
|
|
const handleUpdate = () => {
|
|
emit('update');
|
|
};
|
|
|
|
onMounted(async () => {
|
|
await loadPanels();
|
|
});
|
|
</script>
|
|
|
|
<template>
|
|
<div>
|
|
<VRow v-if="loading" class="mb-4">
|
|
<VCol cols="12">
|
|
<VProgressCircular indeterminate color="primary" />
|
|
</VCol>
|
|
</VRow>
|
|
|
|
<VRow v-else-if="panels.length === 0">
|
|
<VCol cols="12">
|
|
<VAlert type="info">
|
|
No security management options are available.
|
|
</VAlert>
|
|
</VCol>
|
|
</VRow>
|
|
|
|
<div v-else class="security-panels-container">
|
|
<VRow>
|
|
<VCol
|
|
v-for="panel in panels"
|
|
:key="panel.id"
|
|
cols="12"
|
|
md="6"
|
|
>
|
|
<component
|
|
:is="panel.component"
|
|
:user="user"
|
|
@update="handleUpdate"
|
|
/>
|
|
</VCol>
|
|
</VRow>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<style scoped>
|
|
.security-panels-container {
|
|
max-height: 600px;
|
|
overflow-y: auto;
|
|
}
|
|
</style>
|