33
44type PortEntry = {
55 protocol : string ;
6- host_address : string ;
6+ host_address : string ; // Actual address sent to backend
7+ host_address_mode ?: string ; // "local" | "public" | "custom"
78 host_port : number | null ;
89 vm_port : number | null ;
10+ custom_ip ?: string ; // User-entered IP for custom mode
911} ;
1012
1113type ComponentInstance = {
@@ -24,33 +26,81 @@ const PortMappingEditorComponent = {
2426 <div class="port-mapping-editor">
2527 <label>Port Mappings</label>
2628 <div v-for="(port, index) in ports" :key="index" class="port-row">
29+
30+ <!-- protocol -->
2731 <select v-model="port.protocol">
2832 <option value="tcp">TCP</option>
2933 <option value="udp">UDP</option>
3034 </select>
31- <select v-model="port.host_address">
32- <option value="127.0.0.1">Local</option>
33- <option value="0.0.0.0">Public</option>
35+
36+ <!-- address mode selector -->
37+ <select v-model="port.host_address_mode" @change="onModeChange(port)">
38+ <option value="local">Local</option>
39+ <option value="public">Public</option>
40+ <option value="custom">Custom</option>
3441 </select>
42+
43+ <!-- custom IP input -->
44+ <input
45+ v-if="port.host_address_mode === 'custom'"
46+ type="text"
47+ v-model="port.custom_ip"
48+ placeholder="Enter IP address"
49+ @input="onCustomIPChange(port)"
50+ />
51+
52+ <!-- ports -->
3553 <input type="number" v-model.number="port.host_port" placeholder="Host Port" required>
3654 <input type="number" v-model.number="port.vm_port" placeholder="VM Port" required>
37- <button type="button" class="action-btn danger" @click="removePort(index)">Remove</button>
55+
56+ <!-- remove -->
57+ <button type="button" class="action-btn danger" @click="removePort(index)">
58+ Remove
59+ </button>
3860 </div>
39- <button type="button" class="action-btn" @click="addPort">Add Port</button>
61+
62+ <!-- add -->
63+ <button type="button" class="action-btn" @click="addPort">
64+ Add Port
65+ </button>
4066 </div>
4167 ` ,
68+
4269 methods : {
4370 addPort ( this : ComponentInstance ) {
4471 this . ports . push ( {
4572 protocol : 'tcp' ,
4673 host_address : '127.0.0.1' ,
74+ host_address_mode : 'local' ,
75+ custom_ip : '' ,
4776 host_port : null ,
4877 vm_port : null ,
4978 } ) ;
5079 } ,
80+
5181 removePort ( this : ComponentInstance , index : number ) {
5282 this . ports . splice ( index , 1 ) ;
5383 } ,
84+
85+ // Called when switching between Local / Public / Custom
86+ onModeChange ( port : PortEntry ) {
87+ if ( port . host_address_mode === 'local' ) {
88+ port . host_address = '127.0.0.1' ;
89+ }
90+ else if ( port . host_address_mode === 'public' ) {
91+ port . host_address = '0.0.0.0' ;
92+ }
93+ else if ( port . host_address_mode === 'custom' ) {
94+ port . host_address = port . custom_ip || '' ;
95+ }
96+ } ,
97+
98+ // Called when user types a custom IP
99+ onCustomIPChange ( port : PortEntry ) {
100+ if ( port . host_address_mode === 'custom' ) {
101+ port . host_address = port . custom_ip || '' ;
102+ }
103+ } ,
54104 } ,
55105} ;
56106
0 commit comments