diff --git a/ui/public/locales/en.json b/ui/public/locales/en.json
index d29bab3521a..89d33a97d55 100644
--- a/ui/public/locales/en.json
+++ b/ui/public/locales/en.json
@@ -558,6 +558,8 @@
"label.clear.list": "Clear list",
"label.clear.notification": "Clear notification",
"label.clientid": "Provider Client ID",
+"label.clone.compute.offering": "Clone Compute Offering",
+"label.clone.system.service.offering": "Clone System Service Offering",
"label.close": "Close",
"label.cloud.managed": "CloudManaged",
"label.cloudian.admin.password": "Admin Service Password",
@@ -3215,6 +3217,10 @@
"message.create.bucket.failed": "Failed to create bucket.",
"message.create.bucket.processing": "Bucket creation in progress",
"message.create.compute.offering": "Compute Offering created",
+"message.clone.compute.offering": "Compute Offering cloned",
+"message.clone.service.offering": "Service Offering cloned",
+"message.clone.offering.from": "Cloning from",
+"message.clone.offering.edit.hint": "All values are pre-filled from the source offering. Edit any field to customize the new offering.",
"message.create.sharedfs.failed": "Failed to create Shared FileSystem.",
"message.create.sharedfs.processing": "Shared FileSystem creation in progress.",
"message.create.tungsten.public.network": "Create Tungsten-Fabric public Network",
diff --git a/ui/src/config/section/offering.js b/ui/src/config/section/offering.js
index 4a32619b8c2..ed31e94992e 100644
--- a/ui/src/config/section/offering.js
+++ b/ui/src/config/section/offering.js
@@ -143,6 +143,14 @@ export default {
},
show: (record) => { return record.state === 'Active' },
groupMap: (selection) => { return selection.map(x => { return { id: x, state: 'Inactive' } }) }
+ }, {
+ api: 'cloneServiceOffering',
+ icon: 'copy-outlined',
+ label: 'label.clone.compute.offering',
+ docHelp: 'adminguide/service_offerings.html#creating-a-new-compute-offering',
+ dataView: true,
+ popup: true,
+ component: shallowRef(defineAsyncComponent(() => import('@/views/offering/CloneComputeOffering.vue')))
}]
},
{
@@ -225,6 +233,15 @@ export default {
},
show: (record) => { return record.state === 'Active' },
groupMap: (selection) => { return selection.map(x => { return { id: x, state: 'Inactive' } }) }
+ }, {
+ api: 'cloneServiceOffering',
+ icon: 'copy-outlined',
+ label: 'label.clone.system.service.offering',
+ docHelp: 'adminguide/service_offerings.html#creating-a-new-system-service-offering',
+ dataView: true,
+ params: { issystem: 'true' },
+ popup: true,
+ component: shallowRef(defineAsyncComponent(() => import('@/views/offering/CloneComputeOffering.vue')))
}]
},
{
diff --git a/ui/src/views/offering/CloneComputeOffering.vue b/ui/src/views/offering/CloneComputeOffering.vue
new file mode 100644
index 00000000000..11ce1d316fb
--- /dev/null
+++ b/ui/src/views/offering/CloneComputeOffering.vue
@@ -0,0 +1,1413 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+
+