Skip to content

Commit 884953c

Browse files
authored
ui: add button in zone physical network list (#8028)
Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>
1 parent cc6f21b commit 884953c

File tree

2 files changed

+150
-3
lines changed

2 files changed

+150
-3
lines changed

ui/public/locales/en.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2361,6 +2361,8 @@
23612361
"message.add.network.failed": "Adding network failed.",
23622362
"message.add.network.processing": "Adding network...",
23632363
"message.add.new.gateway.to.vpc": "Please specify the information to add a new gateway to this VPC.",
2364+
"message.add.physical.network.failed": "Adding physical network failed",
2365+
"message.add.physical.network.processing": "Adding a new physical network...",
23642366
"message.add.pod": "Add a new pod for zone <b><span id=\"add_pod_zone_name\"></span></b>",
23652367
"message.add.pod.during.zone.creation": "Each zone must contain one or more pods. We will add the first pod now. A pod contains hosts and primary storage servers, which you will add in a later step. First, configure a range of reserved IP addresses for CloudStack's internal management traffic. The reserved IP range must be unique for each zone in the cloud.",
23662368
"message.add.port.forward.failed": "Adding new port forwarding rule failed.",
@@ -2955,6 +2957,7 @@
29552957
"message.success.add.network.acl": "Successfully added Network ACL list",
29562958
"message.success.add.network.static.route": "Successfully added network Static Route",
29572959
"message.success.add.network.permissions": "Successfully added network permissions",
2960+
"message.success.add.physical.network": "Successfully added Physical network",
29582961
"message.success.add.policy.rule": "Successfully added Policy rule",
29592962
"message.success.add.port.forward": "Successfully added new port forwarding rule",
29602963
"message.success.add.private.gateway": "Successfully added private gateway",

ui/src/views/infra/zone/PhysicalNetworksTab.vue

Lines changed: 147 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,14 @@
1717

1818
<template>
1919
<a-spin :spinning="fetchLoading">
20+
<a-button
21+
type="primary"
22+
style="width: 100%; margin-bottom: 10px"
23+
@click="showAddPhyNetModal"
24+
:loading="loading"
25+
:disabled="!('createPhysicalNetwork' in $store.getters.apis)">
26+
<template #icon><plus-outlined /></template> {{ $t('label.add.physical.network') }}
27+
</a-button>
2028
<a-list class="list">
2129
<a-list-item v-for="network in networks" :key="network.id" class="list__item">
2230
<div class="list__item-outer-container">
@@ -65,17 +73,94 @@
6573
</div>
6674
</a-list-item>
6775
</a-list>
76+
<a-modal
77+
:visible="addPhyNetModal"
78+
:title="$t('label.add.physical.network')"
79+
:maskClosable="false"
80+
:closable="true"
81+
:footer="null"
82+
@cancel="closeModals">
83+
<a-form
84+
:ref="formRef"
85+
:model="form"
86+
:rules="rules"
87+
@finish="handleAddPhyNet"
88+
v-ctrl-enter="handleAddPhyNet"
89+
layout="vertical"
90+
class="form"
91+
92+
>
93+
<a-form-item name="name" ref="name">
94+
<template #label>
95+
<tooltip-label :title="$t('label.name')" :tooltip="apiParams.name.description"/>
96+
</template>
97+
<a-input v-model:value="form.name" :placeholder="apiParams.name.description" />
98+
</a-form-item>
99+
<a-form-item name="isolationmethods" ref="isolationmethods">
100+
<template #label>
101+
<tooltip-label :title="$t('label.isolationmethods')" :tooltip="apiParams.isolationmethods.description"/>
102+
</template>
103+
<a-select
104+
v-model:value="form.isolationmethods"
105+
showSearch
106+
optionFilterProp="label"
107+
:filterOption="(input, option) => {
108+
return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0
109+
}"
110+
v-focus="true"
111+
:placeholder="apiParams.isolationmethods.description">
112+
<a-select-option v-for="i in isolationMethods" :key="i" :value="i" :label="i">{{ i }}</a-select-option>
113+
</a-select>
114+
</a-form-item>
115+
<a-form-item name="vlan" ref="vlan">
116+
<template #label>
117+
<tooltip-label :title="$t('label.vlan')" :tooltip="apiParams.vlan.description"/>
118+
</template>
119+
<a-input v-model:value="form.vlan" :placeholder="apiParams.vlan.description" />
120+
</a-form-item>
121+
<a-form-item name="tags" ref="tags">
122+
<template #label>
123+
<tooltip-label :title="$t('label.tags')" :tooltip="apiParams.tags.description"/>
124+
</template>
125+
<a-select
126+
mode="tags"
127+
v-model:value="form.tags"
128+
:placeholder="apiParams.tags.description">
129+
</a-select>
130+
</a-form-item>
131+
<a-form-item name="networkspeed" ref="networkspeed">
132+
<template #label>
133+
<tooltip-label :title="$t('label.networkspeed')" :tooltip="apiParams.networkspeed.description"/>
134+
</template>
135+
<a-input v-model:value="form.networkspeed" :placeholder="apiParams.networkspeed.description" />
136+
</a-form-item>
137+
<a-form-item name="broadcastdomainrange" ref="broadcastdomainrange">
138+
<template #label>
139+
<tooltip-label :title="$t('label.broadcastdomainrange')" :tooltip="apiParams.broadcastdomainrange.description"/>
140+
</template>
141+
<a-input v-model:value="form.broadcastdomainrange" :placeholder="apiParams.broadcastdomainrange.description" />
142+
</a-form-item>
143+
144+
<div :span="24" class="action-button">
145+
<a-button @click="closeModals">{{ $t('label.cancel') }}</a-button>
146+
<a-button type="primary" ref="submit" @click="handleAddPhyNet">{{ $t('label.ok') }}</a-button>
147+
</div>
148+
</a-form>
149+
</a-modal>
68150
</a-spin>
69151
</template>
70152

71153
<script>
154+
import { ref, reactive, toRaw } from 'vue'
72155
import { api } from '@/api'
73156
import Status from '@/components/widgets/Status'
157+
import TooltipLabel from '@/components/widgets/TooltipLabel'
74158
75159
export default {
76160
name: 'PhysicalNetworksTab',
77161
components: {
78-
Status
162+
Status,
163+
TooltipLabel
79164
},
80165
props: {
81166
resource: {
@@ -90,11 +175,17 @@ export default {
90175
data () {
91176
return {
92177
networks: [],
93-
fetchLoading: false
178+
fetchLoading: false,
179+
addPhyNetModal: false
94180
}
95181
},
182+
beforeCreate () {
183+
this.apiParams = this.$getApiParams('createPhysicalNetwork')
184+
console.log(this.apiParams)
185+
},
96186
created () {
97187
this.fetchData()
188+
this.initAddPhyNetForm()
98189
},
99190
watch: {
100191
resource: {
@@ -107,6 +198,11 @@ export default {
107198
}
108199
}
109200
},
201+
computed: {
202+
isolationMethods () {
203+
return ['VLAN', 'VXLAN', 'GRE', 'STT', 'BCF_SEGMENT', 'SSP', 'ODL', 'L3VPN', 'VCS']
204+
}
205+
},
110206
methods: {
111207
fetchData () {
112208
this.fetchLoading = true
@@ -122,7 +218,9 @@ export default {
122218
for (const network of this.networks) {
123219
promises.push(new Promise((resolve, reject) => {
124220
api('listTrafficTypes', { physicalnetworkid: network.id }).then(json => {
125-
network.traffictype = json.listtraffictypesresponse.traffictype.filter(e => { return e.traffictype }).map(e => { return e.traffictype }).join(', ')
221+
if (json.listtraffictypesresponse.traffictype) {
222+
network.traffictype = json.listtraffictypesresponse.traffictype.filter(e => { return e.traffictype }).map(e => { return e.traffictype }).join(', ')
223+
}
126224
resolve()
127225
}).catch(error => {
128226
this.$notifyError(error)
@@ -133,6 +231,52 @@ export default {
133231
Promise.all(promises).finally(() => {
134232
this.fetchLoading = false
135233
})
234+
},
235+
showAddPhyNetModal () {
236+
this.addPhyNetModal = true
237+
},
238+
initAddPhyNetForm () {
239+
this.formRef = ref()
240+
this.form = reactive({})
241+
this.rules = reactive({
242+
name: [{ required: true, message: this.$t('label.required') }]
243+
})
244+
},
245+
handleAddPhyNet () {
246+
this.formRef.value.validate().then(() => {
247+
const values = toRaw(this.form)
248+
values.zoneid = this.resource.id
249+
if (values.tags) {
250+
values.tags = values.tags.join()
251+
}
252+
console.log(values)
253+
api('createPhysicalNetwork', values).then(response => {
254+
this.$pollJob({
255+
jobId: response.createphysicalnetworkresponse.jobid,
256+
successMessage: this.$t('message.success.add.physical.network'),
257+
successMethod: () => {
258+
this.fetchData()
259+
this.closeModals()
260+
},
261+
errorMessage: this.$t('message.add.physical.network.failed'),
262+
errorMethod: () => {
263+
this.fetchData()
264+
this.closeModals()
265+
},
266+
loadingMessage: this.$t('message.add.physical.network.processing'),
267+
catchMessage: this.$t('error.fetching.async.job.result'),
268+
catchMethod: () => {
269+
this.fetchData()
270+
this.closeModals()
271+
}
272+
})
273+
}).catch(error => {
274+
this.$notifyError(error)
275+
})
276+
})
277+
},
278+
closeModals () {
279+
this.addPhyNetModal = false
136280
}
137281
}
138282
}

0 commit comments

Comments
 (0)