feat(interconnect): enable sync panel and add demo mode restriction for role selection

This commit is contained in:
duorameng
2026-06-25 23:50:31 +08:00
parent a227666960
commit 898cb64085
2 changed files with 29 additions and 9 deletions
@@ -1,13 +1,13 @@
<script setup lang="ts">
import { ref, onMounted } from 'vue'
import { Plus, RefreshCw, Search } from 'lucide-vue-next'
import { Plus, RefreshCw, Search, Server, ArrowRightLeft } from 'lucide-vue-next'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
// import { Tabs, TabsList, TabsTrigger } from '@/components/ui/tabs'
import { Tabs, TabsList, TabsTrigger } from '@/components/ui/tabs'
import { toast } from 'vue-sonner'
import * as interconnectApi from '@/api/interconnect'
// import SyncPanel from './SyncPanel.vue'
import SyncPanel from './SyncPanel.vue'
import MasterList from './MasterList.vue'
const emit = defineEmits<{
@@ -71,8 +71,7 @@ onMounted(() => {
<Plus class="h-4 w-4 md:mr-1.5" /> <span class="hidden md:inline">添加子节点</span>
</Button>
<!-- Tabs 切换 (暂时隐藏同步功能) -->
<!--
<!-- Tabs 切换 -->
<Tabs :model-value="activeTab" @update:model-value="(v: string | number) => activeTab = String(v)" class="shrink-0 flex-1 sm:flex-none min-w-[120px]">
<TabsList class="h-9 p-0.5 bg-muted/20 border border-border/40 rounded-lg w-full flex">
<TabsTrigger value="nodes" class="flex-1 sm:flex-none px-3 h-8 text-xs gap-1.5 font-medium transition-all">
@@ -85,13 +84,12 @@ onMounted(() => {
</TabsTrigger>
</TabsList>
</Tabs>
-->
</div>
</div>
</div>
<!-- 内容区域 -->
<MasterList v-if="activeTab === 'nodes'" ref="masterListRef" :nodes="nodes" :loading="loading" :search-query="searchQuery" @refresh="fetchNodes" />
<!-- <SyncPanel v-if="activeTab === 'sync'" :nodes="nodes" /> -->
<SyncPanel v-if="activeTab === 'sync'" :nodes="nodes" />
</div>
</template>
@@ -1,9 +1,31 @@
<script setup lang="ts">
import { ref, onMounted } from 'vue'
import { Network } from 'lucide-vue-next'
import { api } from '@/api'
import { toast } from 'vue-sonner'
const emit = defineEmits<{
(e: 'select', role: 'master' | 'child'): void
}>()
const demoMode = ref(false)
onMounted(async () => {
try {
const publicSite = await api.settings.getPublicSite()
demoMode.value = publicSite.demo_mode || false
} catch (e) {
// ignore
}
})
function handleSelect(role: 'master' | 'child') {
if (demoMode.value) {
toast.error('演示模式下禁止修改互联角色')
return
}
emit('select', role)
}
</script>
<template>
@@ -19,7 +41,7 @@ const emit = defineEmits<{
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 w-full max-w-3xl px-4 mt-2">
<!-- Master Card -->
<div class="border rounded-xl p-5 hover:border-amber-500 hover:ring-1 hover:ring-amber-500/30 cursor-pointer transition-all hover:shadow-sm bg-card space-y-2.5 group" @click="emit('select', 'master')">
<div class="border rounded-xl p-5 hover:border-amber-500 hover:ring-1 hover:ring-amber-500/30 cursor-pointer transition-all hover:shadow-sm bg-card space-y-2.5 group" @click="handleSelect('master')">
<div class="h-10 w-10 rounded-lg bg-amber-500/10 flex items-center justify-center text-amber-500 group-hover:scale-110 transition-transform duration-300">
<Network class="h-5 w-5" />
</div>
@@ -29,7 +51,7 @@ const emit = defineEmits<{
</p>
</div>
<!-- Child Card -->
<div class="border rounded-xl p-5 hover:border-green-500 hover:ring-1 hover:ring-green-500/30 cursor-pointer transition-all hover:shadow-sm bg-card space-y-2.5 group" @click="emit('select', 'child')">
<div class="border rounded-xl p-5 hover:border-green-500 hover:ring-1 hover:ring-green-500/30 cursor-pointer transition-all hover:shadow-sm bg-card space-y-2.5 group" @click="handleSelect('child')">
<div class="h-10 w-10 rounded-lg bg-green-500/10 flex items-center justify-center text-green-500 group-hover:scale-110 transition-transform duration-300">
<Network class="h-5 w-5" />
</div>