Forráskód Böngészése

feat(clients): hide disabled inbounds in the client form selector

The attach-inbounds select in the client add/edit modal listed every inbound, so panels with many disabled inbounds had to scroll past dead entries. InboundOption now carries the inbound's enable flag and the form drops disabled inbounds from the options, keeping ones the client is already attached to so edit mode still renders existing assignments.

Closes #5645
MHSanaei 9 órája
szülő
commit
052dd85ad3

+ 6 - 0
frontend/public/openapi.json

@@ -1824,6 +1824,10 @@
       },
       "InboundOption": {
         "properties": {
+          "enable": {
+            "example": true,
+            "type": "boolean"
+          },
           "id": {
             "example": 1,
             "type": "integer"
@@ -1880,6 +1884,7 @@
           }
         },
         "required": [
+          "enable",
           "id",
           "port",
           "protocol",
@@ -2795,6 +2800,7 @@
                   "success": true,
                   "obj": [
                     {
+                      "enable": true,
                       "id": 1,
                       "listen": "",
                       "nodeAddress": "",

+ 1 - 0
frontend/src/generated/examples.ts

@@ -399,6 +399,7 @@ export const EXAMPLES: Record<string, unknown> = {
     "xver": 0
   },
   "InboundOption": {
+    "enable": true,
     "id": 1,
     "listen": "",
     "nodeAddress": "",

+ 5 - 0
frontend/src/generated/schemas.ts

@@ -1798,6 +1798,10 @@ export const SCHEMAS: Record<string, unknown> = {
   },
   "InboundOption": {
     "properties": {
+      "enable": {
+        "example": true,
+        "type": "boolean"
+      },
       "id": {
         "example": 1,
         "type": "integer"
@@ -1854,6 +1858,7 @@ export const SCHEMAS: Record<string, unknown> = {
       }
     },
     "required": [
+      "enable",
       "id",
       "port",
       "protocol",

+ 1 - 0
frontend/src/generated/types.ts

@@ -393,6 +393,7 @@ export interface InboundFallback {
 }
 
 export interface InboundOption {
+  enable: boolean;
   id: number;
   listen?: string;
   nodeAddress?: string;

+ 1 - 0
frontend/src/generated/zod.ts

@@ -420,6 +420,7 @@ export const InboundFallbackSchema = z.object({
 export type InboundFallback = z.infer<typeof InboundFallbackSchema>;
 
 export const InboundOptionSchema = z.object({
+  enable: z.boolean(),
   id: z.number().int(),
   listen: z.string().optional(),
   nodeAddress: z.string().optional(),

+ 2 - 1
frontend/src/pages/clients/ClientFormModal.tsx

@@ -376,12 +376,13 @@ export default function ClientFormModal({
   const inboundOptions = useMemo(
     () => (inbounds || [])
       .filter((ib) => MULTI_CLIENT_PROTOCOLS.has(ib.protocol || ''))
+      .filter((ib) => ib.enable || (form.inboundIds || []).includes(ib.id))
       .map((ib) => ({
         label: formatInboundLabel(ib.tag, ib.remark),
         value: ib.id,
         title: formatInboundLabel(ib.tag, ib.remark),
       })),
-    [inbounds],
+    [inbounds, form.inboundIds],
   );
 
   const linkRows = useMemo(() => form.externalLinks.filter((r) => r.kind === 'link'), [form.externalLinks]);

+ 4 - 1
internal/web/service/inbound.go

@@ -297,6 +297,7 @@ type InboundOption struct {
 	Tag            string `json:"tag" example:"in-443-tcp"`
 	Protocol       string `json:"protocol" example:"vless"`
 	Port           int    `json:"port" example:"443"`
+	Enable         bool   `json:"enable" example:"true"`
 	TlsFlowCapable bool   `json:"tlsFlowCapable" example:"true"`
 	SsMethod       string `json:"ssMethod"`
 	WgPublicKey    string `json:"wgPublicKey,omitempty"`
@@ -325,6 +326,7 @@ func (s *InboundService) GetInboundOptions(userId int) ([]InboundOption, error)
 		Tag               string `gorm:"column:tag"`
 		Protocol          string `gorm:"column:protocol"`
 		Port              int    `gorm:"column:port"`
+		Enable            bool   `gorm:"column:enable"`
 		StreamSettings    string `gorm:"column:stream_settings"`
 		Settings          string `gorm:"column:settings"`
 		Listen            string `gorm:"column:listen"`
@@ -334,7 +336,7 @@ func (s *InboundService) GetInboundOptions(userId int) ([]InboundOption, error)
 		NodeAddress       string `gorm:"column:node_address"`
 	}
 	err := db.Table("inbounds").
-		Select("inbounds.id, inbounds.remark, inbounds.tag, inbounds.protocol, inbounds.port, inbounds.stream_settings, inbounds.settings, inbounds.listen, inbounds.share_addr, inbounds.share_addr_strategy, inbounds.node_id, COALESCE(nodes.address, '') AS node_address").
+		Select("inbounds.id, inbounds.remark, inbounds.tag, inbounds.protocol, inbounds.port, inbounds.enable, inbounds.stream_settings, inbounds.settings, inbounds.listen, inbounds.share_addr, inbounds.share_addr_strategy, inbounds.node_id, COALESCE(nodes.address, '') AS node_address").
 		Joins("LEFT JOIN nodes ON nodes.id = inbounds.node_id").
 		Where("inbounds.user_id = ?", userId).
 		Order("inbounds.id ASC").
@@ -355,6 +357,7 @@ func (s *InboundService) GetInboundOptions(userId int) ([]InboundOption, error)
 			Tag:               r.Tag,
 			Protocol:          r.Protocol,
 			Port:              r.Port,
+			Enable:            r.Enable,
 			TlsFlowCapable:    inboundCanEnableTlsFlow(r.Protocol, r.StreamSettings, r.Settings),
 			SsMethod:          inboundShadowsocksMethod(r.Protocol, r.Settings),
 			WgPublicKey:       wgPublicKey,