Skip to content

Commit 4a2b0a5

Browse files
committed
add support for dedicated IP
1 parent 753da65 commit 4a2b0a5

File tree

3 files changed

+129
-109
lines changed

3 files changed

+129
-109
lines changed

vmm/ui/src/components/PortMappingEditor.ts

Lines changed: 48 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -10,37 +10,49 @@ type PortEntry = {
1010
custom_ip?: string; // User-entered IP for custom mode
1111
};
1212

13+
// ... keep your types as-is ...
14+
1315
type ComponentInstance = {
1416
ports: PortEntry[];
17+
normalizePort: (p: PortEntry) => void;
1518
};
1619

1720
const PortMappingEditorComponent = {
1821
name: 'PortMappingEditor',
1922
props: {
23+
ports: { type: Array, required: true },
24+
},
25+
26+
// ✅ NEW: normalize on initial load
27+
created(this: ComponentInstance) {
28+
this.ports.forEach((p) => this.normalizePort(p));
29+
},
30+
31+
// ✅ NEW: normalize again if parent replaces ports array (e.g. after refresh)
32+
watch: {
2033
ports: {
21-
type: Array,
22-
required: true,
34+
deep: true,
35+
handler(this: ComponentInstance, newPorts: PortEntry[]) {
36+
newPorts.forEach((p) => this.normalizePort(p));
37+
},
2338
},
2439
},
40+
2541
template: /* html */ `
2642
<div class="port-mapping-editor">
2743
<label>Port Mappings</label>
2844
<div v-for="(port, index) in ports" :key="index" class="port-row">
29-
30-
<!-- protocol -->
3145
<select v-model="port.protocol">
3246
<option value="tcp">TCP</option>
3347
<option value="udp">UDP</option>
3448
</select>
3549
36-
<!-- address mode selector -->
3750
<select v-model="port.host_address_mode" @change="onModeChange(port)">
3851
<option value="local">Local</option>
3952
<option value="public">Public</option>
4053
<option value="custom">Custom</option>
4154
</select>
4255
43-
<!-- custom IP input -->
4456
<input
4557
v-if="port.host_address_mode === 'custom'"
4658
type="text"
@@ -49,24 +61,32 @@ const PortMappingEditorComponent = {
4961
@input="onCustomIPChange(port)"
5062
/>
5163
52-
<!-- ports -->
5364
<input type="number" v-model.number="port.host_port" placeholder="Host Port" required>
5465
<input type="number" v-model.number="port.vm_port" placeholder="VM Port" required>
55-
56-
<!-- remove -->
57-
<button type="button" class="action-btn danger" @click="removePort(index)">
58-
Remove
59-
</button>
66+
<button type="button" class="action-btn danger" @click="removePort(index)">Remove</button>
6067
</div>
61-
62-
<!-- add -->
63-
<button type="button" class="action-btn" @click="addPort">
64-
Add Port
65-
</button>
68+
<button type="button" class="action-btn" @click="addPort">Add Port</button>
6669
</div>
6770
`,
6871

6972
methods: {
73+
// ✅ NEW: derives mode + custom_ip from host_address when editing existing VMs
74+
normalizePort(this: ComponentInstance, port: PortEntry) {
75+
// If mode already set, keep it (don’t fight the user while editing)
76+
if (port.host_address_mode) return;
77+
78+
if (port.host_address === '127.0.0.1') {
79+
port.host_address_mode = 'local';
80+
port.custom_ip = '';
81+
} else if (port.host_address === '0.0.0.0') {
82+
port.host_address_mode = 'public';
83+
port.custom_ip = '';
84+
} else {
85+
port.host_address_mode = 'custom';
86+
port.custom_ip = port.host_address; // show dedicated IP in input
87+
}
88+
},
89+
7090
addPort(this: ComponentInstance) {
7191
this.ports.push({
7292
protocol: 'tcp',
@@ -82,20 +102,25 @@ const PortMappingEditorComponent = {
82102
this.ports.splice(index, 1);
83103
},
84104

85-
// Called when switching between Local / Public / Custom
86105
onModeChange(port: PortEntry) {
87106
if (port.host_address_mode === 'local') {
88107
port.host_address = '127.0.0.1';
89-
}
90-
else if (port.host_address_mode === 'public') {
108+
port.custom_ip = '';
109+
} else if (port.host_address_mode === 'public') {
91110
port.host_address = '0.0.0.0';
92-
}
93-
else if (port.host_address_mode === 'custom') {
111+
port.custom_ip = '';
112+
} else if (port.host_address_mode === 'custom') {
113+
// if coming from existing custom, keep it; otherwise start empty
114+
if (!port.custom_ip || port.custom_ip === '') {
115+
// if host_address already contains a non-standard IP, reuse it
116+
if (port.host_address !== '127.0.0.1' && port.host_address !== '0.0.0.0') {
117+
port.custom_ip = port.host_address;
118+
}
119+
}
94120
port.host_address = port.custom_ip || '';
95121
}
96122
},
97123

98-
// Called when user types a custom IP
99124
onCustomIPChange(port: PortEntry) {
100125
if (port.host_address_mode === 'custom') {
101126
port.host_address = port.custom_ip || '';

vmm/ui/src/styles/main.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1522,7 +1522,7 @@ h1, h2, h3, h4, h5, h6 {
15221522
}
15231523

15241524
.port-row {
1525-
grid-template-columns: 90px 100px 120px 120px 100px;
1525+
grid-template-columns: 90px 100px 120px 120px 160px 100px;
15261526
}
15271527

15281528
.gpu-config-items {

0 commit comments

Comments
 (0)