fix(inbounds): hide node UI when no enabled node exists
The Deploy-to selector, node column, node stat row, and node filter all appeared whenever a node row existed in the DB. Local-only deployments with no nodes (or only disabled nodes) saw a dropdown that only had "Local Panel" and a filter that did nothing. useNodeList now exposes hasActive (any node with enable === true). Inbounds form and list gate node UI on hasActive instead of map size.
This commit is contained in:
@@ -36,7 +36,9 @@ export function useNodeList() {
|
||||
return n != null && n.enable && n.status === 'online';
|
||||
}
|
||||
|
||||
const hasActive = computed(() => nodes.value.some((n) => n.enable));
|
||||
|
||||
onMounted(refresh);
|
||||
|
||||
return { nodes, fetched, refresh, byId, nameFor, isOnline };
|
||||
return { nodes, fetched, refresh, byId, nameFor, isOnline, hasActive };
|
||||
}
|
||||
|
||||
@@ -582,7 +582,7 @@ watch(
|
||||
<a-form-item :label="t('pages.inbounds.remark')">
|
||||
<a-input v-model:value="dbForm.remark" />
|
||||
</a-form-item>
|
||||
<a-form-item :label="t('pages.inbounds.deployTo')">
|
||||
<a-form-item v-if="selectableNodes.length > 0" :label="t('pages.inbounds.deployTo')">
|
||||
<a-select v-model:value="dbForm.nodeId" :disabled="mode === 'edit'"
|
||||
:placeholder="t('pages.inbounds.localPanel')" allow-clear>
|
||||
<a-select-option :value="null">{{ t('pages.inbounds.localPanel') }}</a-select-option>
|
||||
|
||||
@@ -49,6 +49,7 @@ const props = defineProps({
|
||||
// Map node id -> node row, supplied by the parent page so each
|
||||
// inbound row can render its node name without an extra fetch.
|
||||
nodesById: { type: Map, default: () => new Map() },
|
||||
hasActiveNode: { type: Boolean, default: false },
|
||||
});
|
||||
|
||||
const emit = defineEmits([
|
||||
@@ -234,7 +235,7 @@ const desktopColumns = computed(() => {
|
||||
if (hasAnyRemark.value) {
|
||||
cols.push(sortableCol({ title: t('pages.inbounds.remark'), dataIndex: 'remark', key: 'remark', align: 'center', width: 60 }, 'remark'));
|
||||
}
|
||||
if (props.nodesById.size > 0) {
|
||||
if (props.hasActiveNode) {
|
||||
cols.push(sortableCol({ title: t('pages.inbounds.node'), key: 'node', align: 'center', width: 60 }, 'node'));
|
||||
}
|
||||
cols.push(
|
||||
@@ -374,7 +375,7 @@ function showQrCodeMenu(dbInbound) {
|
||||
{{ protocol }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
<a-select v-if="nodeOptions.length > 0" v-model:value="nodeFilter" allow-clear
|
||||
<a-select v-if="hasActiveNode && nodeOptions.length > 0" v-model:value="nodeFilter" allow-clear
|
||||
:placeholder="t('pages.inbounds.node')" :size="isMobile ? 'small' : 'middle'" :style="{ width: '170px' }">
|
||||
<a-select-option v-for="node in nodeOptions" :key="node.value" :value="node.value">
|
||||
{{ node.label }}
|
||||
@@ -466,7 +467,7 @@ function showQrCodeMenu(dbInbound) {
|
||||
<span class="stat-label">{{ t('pages.inbounds.port') }}</span>
|
||||
<a-tag>{{ record.port }}</a-tag>
|
||||
</div>
|
||||
<div v-if="nodesById.size > 0" class="stat-row">
|
||||
<div v-if="hasActiveNode" class="stat-row">
|
||||
<span class="stat-label">{{ t('pages.inbounds.node') }}</span>
|
||||
<a-tag v-if="record.nodeId == null" color="default">
|
||||
{{ t('pages.inbounds.localPanel') }}
|
||||
|
||||
@@ -66,7 +66,7 @@ useWebSocket({
|
||||
const { isMobile } = useMediaQuery();
|
||||
// Node list lives on the central panel; the Inbounds page consumes
|
||||
// the id→node map for the new "Node" column. Fetched once on mount.
|
||||
const { byId: nodesById } = useNodeList();
|
||||
const { byId: nodesById, hasActive: hasActiveNode } = useNodeList();
|
||||
|
||||
const basePath = window.X_UI_BASE_PATH || '';
|
||||
const requestUri = window.location.pathname;
|
||||
@@ -647,7 +647,8 @@ function onRowAction({ key, dbInbound }) {
|
||||
<InboundList :db-inbounds="dbInbounds" :client-count="clientCount" :online-clients="onlineClients"
|
||||
:last-online-map="lastOnlineMap" :is-dark-theme="themeState.isDark" :expire-diff="expireDiff"
|
||||
:traffic-diff="trafficDiff" :page-size="pageSize" :is-mobile="isMobile"
|
||||
:sub-enable="subSettings.enable" :nodes-by-id="nodesById" @refresh="refresh"
|
||||
:sub-enable="subSettings.enable" :nodes-by-id="nodesById" :has-active-node="hasActiveNode"
|
||||
@refresh="refresh"
|
||||
@add-inbound="onAddInbound" @general-action="onGeneralAction" @row-action="onRowAction"
|
||||
@edit-client="onEditClient" @qrcode-client="onQrcodeClient" @info-client="onInfoClient"
|
||||
@reset-traffic-client="onResetTrafficClient" @delete-client="onDeleteClient"
|
||||
|
||||
Reference in New Issue
Block a user