This is an automated email from the ASF dual-hosted git repository.

jialiang pushed a commit to branch frontend-refactor
in repository https://gitbox.apache.org/repos/asf/ambari.git


The following commit(s) were added to refs/heads/frontend-refactor by this push:
     new 7586b3bdbc AMBARI-26175 Register version capabilities in Ambari Admin 
(#3971)
7586b3bdbc is described below

commit 7586b3bdbc33c3791a1c5287498e82f9d8afdb65
Author: vanshuhassija <[email protected]>
AuthorDate: Sun Nov 9 07:21:22 2025 +0530

    AMBARI-26175 Register version capabilities in Ambari Admin (#3971)
    
    Replace stack
    Fix typescript changes
---
 .../src/__mocks__/mockOperatingSystems.ts          |  620 ++++++++++
 .../src/components/AddVersionModal/index.tsx       |  116 ++
 .../src/components/LostNetworkModal/index.tsx      |   56 +
 .../components/RedhatSatelliteInfoModal/index.tsx  |   56 +
 .../resources/ui/ambari-admin/src/constants.ts     |   21 +
 .../ui/ambari-admin/src/router/RoutesList.tsx      |    8 +-
 .../src/screens/StackVersions/Register.tsx         | 1287 ++++++++++++++++++++
 .../src/tests/StackVersions/Register.test.tsx      |  398 ++++++
 8 files changed, 2559 insertions(+), 3 deletions(-)

diff --git 
a/ambari-admin/src/main/resources/ui/ambari-admin/src/__mocks__/mockOperatingSystems.ts
 
b/ambari-admin/src/main/resources/ui/ambari-admin/src/__mocks__/mockOperatingSystems.ts
new file mode 100644
index 0000000000..8c519c43b6
--- /dev/null
+++ 
b/ambari-admin/src/main/resources/ui/ambari-admin/src/__mocks__/mockOperatingSystems.ts
@@ -0,0 +1,620 @@
+/**
+ * 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.
+ */
+export default {
+    "href": 
"http://example.com/api/v1/stacks/STACK/versions/3.3?fields=operating_systems/repositories/Repositories";,
+    "Versions": {
+        "stack_name": "STACK",
+        "stack_version": "3.3"
+    },
+    "operating_systems": [
+        {
+            "href": 
"http://example.com/api/v1/stacks/STACK/versions/3.3/operating_systems/amazonlinux2";,
+            "OperatingSystems": {
+                "os_type": "amazonlinux2",
+                "stack_name": "STACK",
+                "stack_version": "3.3"
+            },
+            "repositories": [
+                {
+                    "href": 
"http://example.com/api/v1/stacks/STACK/versions/3.3/operating_systems/amazonlinux2/repositories/STACK-3.3";,
+                    "Repositories": {
+                        "applicable_services": [],
+                        "base_url": 
"https://ad-STACK.s3.us-west-1.amazonaws.com/STACK/amazonlinux2/3.x/updates/3.3.0.0";,
+                        "components": null,
+                        "default_base_url": 
"https://ad-STACK.s3.us-west-1.amazonaws.com/STACK/amazonlinux2/3.x/updates/3.3.0.0";,
+                        "distribution": null,
+                        "mirrors_list": null,
+                        "os_type": "amazonlinux2",
+                        "repo_id": "STACK-3.3",
+                        "repo_name": "STACK",
+                        "stack_name": "STACK",
+                        "stack_version": "3.3",
+                        "tags": [],
+                        "unique": false
+                    }
+                },
+                {
+                    "href": 
"http://example.com/api/v1/stacks/STACK/versions/3.3/operating_systems/amazonlinux2/repositories/STACK-3.3-GPL";,
+                    "Repositories": {
+                        "applicable_services": [],
+                        "base_url": 
"https://ad-STACK.s3.us-west-1.amazonaws.com/STACK-GPL/amazonlinux2/3.x/updates/3.3.0.0";,
+                        "components": null,
+                        "default_base_url": 
"https://ad-STACK.s3.us-west-1.amazonaws.com/STACK-GPL/amazonlinux2/3.x/updates/3.3.0.0";,
+                        "distribution": null,
+                        "mirrors_list": null,
+                        "os_type": "amazonlinux2",
+                        "repo_id": "STACK-3.3-GPL",
+                        "repo_name": "STACK-GPL",
+                        "stack_name": "STACK",
+                        "stack_version": "3.3",
+                        "tags": [
+                            "GPL"
+                        ],
+                        "unique": false
+                    }
+                },
+                {
+                    "href": 
"http://example.com/api/v1/stacks/STACK/versions/3.3/operating_systems/amazonlinux2/repositories/STACK-UTILS-1.1.0.22";,
+                    "Repositories": {
+                        "applicable_services": [],
+                        "base_url": 
"https://ad-STACK.s3.us-west-1.amazonaws.com/STACK-UTILS-1.1.0.22/repos/amazonlinux2";,
+                        "components": null,
+                        "default_base_url": 
"https://ad-STACK.s3.us-west-1.amazonaws.com/STACK-UTILS-1.1.0.22/repos/amazonlinux2";,
+                        "distribution": null,
+                        "mirrors_list": null,
+                        "os_type": "amazonlinux2",
+                        "repo_id": "STACK-UTILS-1.1.0.22",
+                        "repo_name": "STACK-UTILS",
+                        "stack_name": "STACK",
+                        "stack_version": "3.3",
+                        "tags": [],
+                        "unique": false
+                    }
+                }
+            ]
+        },
+        {
+            "href": 
"http://example.com/api/v1/stacks/STACK/versions/3.3/operating_systems/debian9";,
+            "OperatingSystems": {
+                "os_type": "debian9",
+                "stack_name": "STACK",
+                "stack_version": "3.3"
+            },
+            "repositories": [
+                {
+                    "href": 
"http://example.com/api/v1/stacks/STACK/versions/3.3/operating_systems/debian9/repositories/STACK-3.3";,
+                    "Repositories": {
+                        "applicable_services": [],
+                        "base_url": 
"https://ad-STACK.s3.us-west-1.amazonaws.com/STACK/debian9/3.x/updates/3.3.0.0";,
+                        "components": null,
+                        "default_base_url": 
"https://ad-STACK.s3.us-west-1.amazonaws.com/STACK/debian9/3.x/updates/3.3.0.0";,
+                        "distribution": null,
+                        "mirrors_list": null,
+                        "os_type": "debian9",
+                        "repo_id": "STACK-3.3",
+                        "repo_name": "STACK",
+                        "stack_name": "STACK",
+                        "stack_version": "3.3",
+                        "tags": [],
+                        "unique": false
+                    }
+                },
+                {
+                    "href": 
"http://example.com/api/v1/stacks/STACK/versions/3.3/operating_systems/debian9/repositories/STACK-3.3-GPL";,
+                    "Repositories": {
+                        "applicable_services": [],
+                        "base_url": 
"https://ad-STACK.s3.us-west-1.amazonaws.com/STACK-GPL/debian9/3.x/updates/3.3.0.0";,
+                        "components": null,
+                        "default_base_url": 
"https://ad-STACK.s3.us-west-1.amazonaws.com/STACK-GPL/debian9/3.x/updates/3.3.0.0";,
+                        "distribution": null,
+                        "mirrors_list": null,
+                        "os_type": "debian9",
+                        "repo_id": "STACK-3.3-GPL",
+                        "repo_name": "STACK-GPL",
+                        "stack_name": "STACK",
+                        "stack_version": "3.3",
+                        "tags": [
+                            "GPL"
+                        ],
+                        "unique": false
+                    }
+                },
+                {
+                    "href": 
"http://example.com/api/v1/stacks/STACK/versions/3.3/operating_systems/debian9/repositories/STACK-UTILS-1.1.0.22";,
+                    "Repositories": {
+                        "applicable_services": [],
+                        "base_url": 
"https://ad-STACK.s3.us-west-1.amazonaws.com/STACK-UTILS-1.1.0.22/repos/debian9";,
+                        "components": null,
+                        "default_base_url": 
"https://ad-STACK.s3.us-west-1.amazonaws.com/STACK-UTILS-1.1.0.22/repos/debian9";,
+                        "distribution": null,
+                        "mirrors_list": null,
+                        "os_type": "debian9",
+                        "repo_id": "STACK-UTILS-1.1.0.22",
+                        "repo_name": "STACK-UTILS",
+                        "stack_name": "STACK",
+                        "stack_version": "3.3",
+                        "tags": [],
+                        "unique": false
+                    }
+                }
+            ]
+        },
+        {
+            "href": 
"http://example.com/api/v1/stacks/STACK/versions/3.3/operating_systems/redhat-ppc7";,
+            "OperatingSystems": {
+                "os_type": "redhat-ppc7",
+                "stack_name": "STACK",
+                "stack_version": "3.3"
+            },
+            "repositories": [
+                {
+                    "href": 
"http://example.com/api/v1/stacks/STACK/versions/3.3/operating_systems/redhat-ppc7/repositories/STACK-3.3";,
+                    "Repositories": {
+                        "applicable_services": [],
+                        "base_url": 
"https://ad-STACK.s3.us-west-1.amazonaws.com/STACK/centos7-ppc/3.x/updates/3.3.0.0";,
+                        "components": null,
+                        "default_base_url": 
"https://ad-STACK.s3.us-west-1.amazonaws.com/STACK/centos7-ppc/3.x/updates/3.3.0.0";,
+                        "distribution": null,
+                        "mirrors_list": null,
+                        "os_type": "redhat-ppc7",
+                        "repo_id": "STACK-3.3",
+                        "repo_name": "STACK",
+                        "stack_name": "STACK",
+                        "stack_version": "3.3",
+                        "tags": [],
+                        "unique": false
+                    }
+                },
+                {
+                    "href": 
"http://example.com/api/v1/stacks/STACK/versions/3.3/operating_systems/redhat-ppc7/repositories/STACK-3.3-GPL";,
+                    "Repositories": {
+                        "applicable_services": [],
+                        "base_url": 
"https://ad-STACK.s3.us-west-1.amazonaws.com/STACK-GPL/centos7-ppc/3.x/updates/3.3.0.0";,
+                        "components": null,
+                        "default_base_url": 
"https://ad-STACK.s3.us-west-1.amazonaws.com/STACK-GPL/centos7-ppc/3.x/updates/3.3.0.0";,
+                        "distribution": null,
+                        "mirrors_list": null,
+                        "os_type": "redhat-ppc7",
+                        "repo_id": "STACK-3.3-GPL",
+                        "repo_name": "STACK-GPL",
+                        "stack_name": "STACK",
+                        "stack_version": "3.3",
+                        "tags": [
+                            "GPL"
+                        ],
+                        "unique": false
+                    }
+                },
+                {
+                    "href": 
"http://example.com/api/v1/stacks/STACK/versions/3.3/operating_systems/redhat-ppc7/repositories/STACK-UTILS-1.1.0.22";,
+                    "Repositories": {
+                        "applicable_services": [],
+                        "base_url": 
"https://ad-STACK.s3.us-west-1.amazonaws.com/STACK-UTILS-1.1.0.22/repos/centos7-ppc";,
+                        "components": null,
+                        "default_base_url": 
"https://ad-STACK.s3.us-west-1.amazonaws.com/STACK-UTILS-1.1.0.22/repos/centos7-ppc";,
+                        "distribution": null,
+                        "mirrors_list": null,
+                        "os_type": "redhat-ppc7",
+                        "repo_id": "STACK-UTILS-1.1.0.22",
+                        "repo_name": "STACK-UTILS",
+                        "stack_name": "STACK",
+                        "stack_version": "3.3",
+                        "tags": [],
+                        "unique": false
+                    }
+                }
+            ]
+        },
+        {
+            "href": 
"http://example.com/api/v1/stacks/STACK/versions/3.3/operating_systems/redhat7";,
+            "OperatingSystems": {
+                "os_type": "redhat7",
+                "stack_name": "STACK",
+                "stack_version": "3.3"
+            },
+            "repositories": [
+                {
+                    "href": 
"http://example.com/api/v1/stacks/STACK/versions/3.3/operating_systems/redhat7/repositories/STACK-3.3";,
+                    "Repositories": {
+                        "applicable_services": [],
+                        "base_url": 
"https://ad-STACK.s3.us-west-1.amazonaws.com/STACK/centos7/3.x/updates/3.3.0.0";,
+                        "components": null,
+                        "default_base_url": 
"https://ad-STACK.s3.us-west-1.amazonaws.com/STACK/centos7/3.x/updates/3.3.0.0";,
+                        "distribution": null,
+                        "mirrors_list": null,
+                        "os_type": "redhat7",
+                        "repo_id": "STACK-3.3",
+                        "repo_name": "STACK",
+                        "stack_name": "STACK",
+                        "stack_version": "3.3",
+                        "tags": [],
+                        "unique": false
+                    }
+                },
+                {
+                    "href": 
"http://example.com/api/v1/stacks/STACK/versions/3.3/operating_systems/redhat7/repositories/STACK-3.3-GPL";,
+                    "Repositories": {
+                        "applicable_services": [],
+                        "base_url": 
"https://ad-STACK.s3.us-west-1.amazonaws.com/STACK-GPL/centos7/3.x/updates/3.3.0.0";,
+                        "components": null,
+                        "default_base_url": 
"https://ad-STACK.s3.us-west-1.amazonaws.com/STACK-GPL/centos7/3.x/updates/3.3.0.0";,
+                        "distribution": null,
+                        "mirrors_list": null,
+                        "os_type": "redhat7",
+                        "repo_id": "STACK-3.3-GPL",
+                        "repo_name": "STACK-GPL",
+                        "stack_name": "STACK",
+                        "stack_version": "3.3",
+                        "tags": [
+                            "GPL"
+                        ],
+                        "unique": false
+                    }
+                },
+                {
+                    "href": 
"http://example.com/api/v1/stacks/STACK/versions/3.3/operating_systems/redhat7/repositories/STACK-UTILS-1.1.0.22";,
+                    "Repositories": {
+                        "applicable_services": [],
+                        "base_url": 
"https://ad-STACK.s3.us-west-1.amazonaws.com/STACK-UTILS-1.1.0.22/repos/centos7";,
+                        "components": null,
+                        "default_base_url": 
"https://ad-STACK.s3.us-west-1.amazonaws.com/STACK-UTILS-1.1.0.22/repos/centos7";,
+                        "distribution": null,
+                        "mirrors_list": null,
+                        "os_type": "redhat7",
+                        "repo_id": "STACK-UTILS-1.1.0.22",
+                        "repo_name": "STACK-UTILS",
+                        "stack_name": "STACK",
+                        "stack_version": "3.3",
+                        "tags": [],
+                        "unique": false
+                    }
+                }
+            ]
+        },
+        {
+            "href": 
"http://example.com/api/v1/stacks/STACK/versions/3.3/operating_systems/redhat8";,
+            "OperatingSystems": {
+                "os_type": "redhat8",
+                "stack_name": "STACK",
+                "stack_version": "3.3"
+            },
+            "repositories": [
+                {
+                    "href": 
"http://example.com/api/v1/stacks/STACK/versions/3.3/operating_systems/redhat8/repositories/STACK-3.3";,
+                    "Repositories": {
+                        "applicable_services": [],
+                        "base_url": 
"https://ad-STACK.s3.us-west-1.amazonaws.com/STACK/redhat8/3.x/updates/3.3.0.0";,
+                        "components": null,
+                        "default_base_url": 
"https://ad-STACK.s3.us-west-1.amazonaws.com/STACK/redhat8/3.x/updates/3.3.0.0";,
+                        "distribution": null,
+                        "mirrors_list": null,
+                        "os_type": "redhat8",
+                        "repo_id": "STACK-3.3",
+                        "repo_name": "STACK",
+                        "stack_name": "STACK",
+                        "stack_version": "3.3",
+                        "tags": [],
+                        "unique": false
+                    }
+                },
+                {
+                    "href": 
"http://example.com/api/v1/stacks/STACK/versions/3.3/operating_systems/redhat8/repositories/STACK-3.3-GPL";,
+                    "Repositories": {
+                        "applicable_services": [],
+                        "base_url": 
"https://ad-STACK.s3.us-west-1.amazonaws.com/STACK-GPL/redhat8/3.x/updates/3.3.0.0";,
+                        "components": null,
+                        "default_base_url": 
"https://ad-STACK.s3.us-west-1.amazonaws.com/STACK-GPL/redhat8/3.x/updates/3.3.0.0";,
+                        "distribution": null,
+                        "mirrors_list": null,
+                        "os_type": "redhat8",
+                        "repo_id": "STACK-3.3-GPL",
+                        "repo_name": "STACK-GPL",
+                        "stack_name": "STACK",
+                        "stack_version": "3.3",
+                        "tags": [
+                            "GPL"
+                        ],
+                        "unique": false
+                    }
+                },
+                {
+                    "href": 
"http://example.com/api/v1/stacks/STACK/versions/3.3/operating_systems/redhat8/repositories/STACK-UTILS-1.1.0.22";,
+                    "Repositories": {
+                        "applicable_services": [],
+                        "base_url": 
"https://ad-STACK.s3.us-west-1.amazonaws.com/STACK-UTILS-1.1.0.22/repos/redhat8";,
+                        "components": null,
+                        "default_base_url": 
"https://ad-STACK.s3.us-west-1.amazonaws.com/STACK-UTILS-1.1.0.22/repos/redhat8";,
+                        "distribution": null,
+                        "mirrors_list": null,
+                        "os_type": "redhat8",
+                        "repo_id": "STACK-UTILS-1.1.0.22",
+                        "repo_name": "STACK-UTILS",
+                        "stack_name": "STACK",
+                        "stack_version": "3.3",
+                        "tags": [],
+                        "unique": false
+                    }
+                }
+            ]
+        },
+        {
+            "href": 
"http://example.com/api/v1/stacks/STACK/versions/3.3/operating_systems/suse12";,
+            "OperatingSystems": {
+                "os_type": "suse12",
+                "stack_name": "STACK",
+                "stack_version": "3.3"
+            },
+            "repositories": [
+                {
+                    "href": 
"http://example.com/api/v1/stacks/STACK/versions/3.3/operating_systems/suse12/repositories/STACK-3.3";,
+                    "Repositories": {
+                        "applicable_services": [],
+                        "base_url": 
"https://ad-STACK.s3.us-west-1.amazonaws.com/STACK/sles12/3.x/updates/3.3.0.0";,
+                        "components": null,
+                        "default_base_url": 
"https://ad-STACK.s3.us-west-1.amazonaws.com/STACK/sles12/3.x/updates/3.3.0.0";,
+                        "distribution": null,
+                        "mirrors_list": null,
+                        "os_type": "suse12",
+                        "repo_id": "STACK-3.3",
+                        "repo_name": "STACK",
+                        "stack_name": "STACK",
+                        "stack_version": "3.3",
+                        "tags": [],
+                        "unique": false
+                    }
+                },
+                {
+                    "href": 
"http://example.com/api/v1/stacks/STACK/versions/3.3/operating_systems/suse12/repositories/STACK-3.3-GPL";,
+                    "Repositories": {
+                        "applicable_services": [],
+                        "base_url": 
"https://ad-STACK.s3.us-west-1.amazonaws.com/STACK-GPL/sles12/3.x/updates/3.3.0.0";,
+                        "components": null,
+                        "default_base_url": 
"https://ad-STACK.s3.us-west-1.amazonaws.com/STACK-GPL/sles12/3.x/updates/3.3.0.0";,
+                        "distribution": null,
+                        "mirrors_list": null,
+                        "os_type": "suse12",
+                        "repo_id": "STACK-3.3-GPL",
+                        "repo_name": "STACK-GPL",
+                        "stack_name": "STACK",
+                        "stack_version": "3.3",
+                        "tags": [
+                            "GPL"
+                        ],
+                        "unique": false
+                    }
+                },
+                {
+                    "href": 
"http://example.com/api/v1/stacks/STACK/versions/3.3/operating_systems/suse12/repositories/STACK-UTILS-1.1.0.22";,
+                    "Repositories": {
+                        "applicable_services": [],
+                        "base_url": 
"https://ad-STACK.s3.us-west-1.amazonaws.com/STACK-UTILS-1.1.0.22/repos/sles12";,
+                        "components": null,
+                        "default_base_url": 
"https://ad-STACK.s3.us-west-1.amazonaws.com/STACK-UTILS-1.1.0.22/repos/sles12";,
+                        "distribution": null,
+                        "mirrors_list": null,
+                        "os_type": "suse12",
+                        "repo_id": "STACK-UTILS-1.1.0.22",
+                        "repo_name": "STACK-UTILS",
+                        "stack_name": "STACK",
+                        "stack_version": "3.3",
+                        "tags": [],
+                        "unique": false
+                    }
+                }
+            ]
+        },
+        {
+            "href": 
"http://example.com/api/v1/stacks/STACK/versions/3.3/operating_systems/ubuntu14";,
+            "OperatingSystems": {
+                "os_type": "ubuntu14",
+                "stack_name": "STACK",
+                "stack_version": "3.3"
+            },
+            "repositories": [
+                {
+                    "href": 
"http://example.com/api/v1/stacks/STACK/versions/3.3/operating_systems/ubuntu14/repositories/STACK-3.3";,
+                    "Repositories": {
+                        "applicable_services": [],
+                        "base_url": 
"https://ad-STACK.s3.us-west-1.amazonaws.com/STACK/ubuntu14/3.x/updates/3.3.0.0";,
+                        "components": null,
+                        "default_base_url": 
"https://ad-STACK.s3.us-west-1.amazonaws.com/STACK/ubuntu14/3.x/updates/3.3.0.0";,
+                        "distribution": null,
+                        "mirrors_list": null,
+                        "os_type": "ubuntu14",
+                        "repo_id": "STACK-3.3",
+                        "repo_name": "STACK",
+                        "stack_name": "STACK",
+                        "stack_version": "3.3",
+                        "tags": [],
+                        "unique": false
+                    }
+                },
+                {
+                    "href": 
"http://example.com/api/v1/stacks/STACK/versions/3.3/operating_systems/ubuntu14/repositories/STACK-3.3-GPL";,
+                    "Repositories": {
+                        "applicable_services": [],
+                        "base_url": 
"https://ad-STACK.s3.us-west-1.amazonaws.com/STACK-GPL/ubuntu14/3.x/updates/3.3.0.0";,
+                        "components": null,
+                        "default_base_url": 
"https://ad-STACK.s3.us-west-1.amazonaws.com/STACK-GPL/ubuntu14/3.x/updates/3.3.0.0";,
+                        "distribution": null,
+                        "mirrors_list": null,
+                        "os_type": "ubuntu14",
+                        "repo_id": "STACK-3.3-GPL",
+                        "repo_name": "STACK-GPL",
+                        "stack_name": "STACK",
+                        "stack_version": "3.3",
+                        "tags": [
+                            "GPL"
+                        ],
+                        "unique": false
+                    }
+                },
+                {
+                    "href": 
"http://example.com/api/v1/stacks/STACK/versions/3.3/operating_systems/ubuntu14/repositories/STACK-UTILS-1.1.0.22";,
+                    "Repositories": {
+                        "applicable_services": [],
+                        "base_url": 
"https://ad-STACK.s3.us-west-1.amazonaws.com/STACK-UTILS-1.1.0.22/repos/ubuntu14";,
+                        "components": null,
+                        "default_base_url": 
"https://ad-STACK.s3.us-west-1.amazonaws.com/STACK-UTILS-1.1.0.22/repos/ubuntu14";,
+                        "distribution": null,
+                        "mirrors_list": null,
+                        "os_type": "ubuntu14",
+                        "repo_id": "STACK-UTILS-1.1.0.22",
+                        "repo_name": "STACK-UTILS",
+                        "stack_name": "STACK",
+                        "stack_version": "3.3",
+                        "tags": [],
+                        "unique": false
+                    }
+                }
+            ]
+        },
+        {
+            "href": 
"http://example.com/api/v1/stacks/STACK/versions/3.3/operating_systems/ubuntu16";,
+            "OperatingSystems": {
+                "os_type": "ubuntu16",
+                "stack_name": "STACK",
+                "stack_version": "3.3"
+            },
+            "repositories": [
+                {
+                    "href": 
"http://example.com/api/v1/stacks/STACK/versions/3.3/operating_systems/ubuntu16/repositories/STACK-3.3";,
+                    "Repositories": {
+                        "applicable_services": [],
+                        "base_url": 
"https://ad-STACK.s3.us-west-1.amazonaws.com/STACK/ubuntu16/3.x/updates/3.3.0.0";,
+                        "components": null,
+                        "default_base_url": 
"https://ad-STACK.s3.us-west-1.amazonaws.com/STACK/ubuntu16/3.x/updates/3.3.0.0";,
+                        "distribution": null,
+                        "mirrors_list": null,
+                        "os_type": "ubuntu16",
+                        "repo_id": "STACK-3.3",
+                        "repo_name": "STACK",
+                        "stack_name": "STACK",
+                        "stack_version": "3.3",
+                        "tags": [],
+                        "unique": false
+                    }
+                },
+                {
+                    "href": 
"http://example.com/api/v1/stacks/STACK/versions/3.3/operating_systems/ubuntu16/repositories/STACK-3.3-GPL";,
+                    "Repositories": {
+                        "applicable_services": [],
+                        "base_url": 
"https://ad-STACK.s3.us-west-1.amazonaws.com/STACK-GPL/ubuntu16/3.x/updates/3.3.0.0";,
+                        "components": null,
+                        "default_base_url": 
"https://ad-STACK.s3.us-west-1.amazonaws.com/STACK-GPL/ubuntu16/3.x/updates/3.3.0.0";,
+                        "distribution": null,
+                        "mirrors_list": null,
+                        "os_type": "ubuntu16",
+                        "repo_id": "STACK-3.3-GPL",
+                        "repo_name": "STACK-GPL",
+                        "stack_name": "STACK",
+                        "stack_version": "3.3",
+                        "tags": [
+                            "GPL"
+                        ],
+                        "unique": false
+                    }
+                },
+                {
+                    "href": 
"http://example.com/api/v1/stacks/STACK/versions/3.3/operating_systems/ubuntu16/repositories/STACK-UTILS-1.1.0.22";,
+                    "Repositories": {
+                        "applicable_services": [],
+                        "base_url": 
"https://ad-STACK.s3.us-west-1.amazonaws.com/STACK-UTILS-1.1.0.22/repos/ubuntu16";,
+                        "components": null,
+                        "default_base_url": 
"https://ad-STACK.s3.us-west-1.amazonaws.com/STACK-UTILS-1.1.0.22/repos/ubuntu16";,
+                        "distribution": null,
+                        "mirrors_list": null,
+                        "os_type": "ubuntu16",
+                        "repo_id": "STACK-UTILS-1.1.0.22",
+                        "repo_name": "STACK-UTILS",
+                        "stack_name": "STACK",
+                        "stack_version": "3.3",
+                        "tags": [],
+                        "unique": false
+                    }
+                }
+            ]
+        },
+        {
+            "href": 
"http://example.com/api/v1/stacks/STACK/versions/3.3/operating_systems/ubuntu18";,
+            "OperatingSystems": {
+                "os_type": "ubuntu18",
+                "stack_name": "STACK",
+                "stack_version": "3.3"
+            },
+            "repositories": [
+                {
+                    "href": 
"http://example.com/api/v1/stacks/STACK/versions/3.3/operating_systems/ubuntu18/repositories/STACK-3.3";,
+                    "Repositories": {
+                        "applicable_services": [],
+                        "base_url": 
"https://ad-STACK.s3.us-west-1.amazonaws.com/STACK/ubuntu18/3.x/updates/3.3.0.0";,
+                        "components": null,
+                        "default_base_url": 
"https://ad-STACK.s3.us-west-1.amazonaws.com/STACK/ubuntu18/3.x/updates/3.3.0.0";,
+                        "distribution": null,
+                        "mirrors_list": null,
+                        "os_type": "ubuntu18",
+                        "repo_id": "STACK-3.3",
+                        "repo_name": "STACK",
+                        "stack_name": "STACK",
+                        "stack_version": "3.3",
+                        "tags": [],
+                        "unique": false
+                    }
+                },
+                {
+                    "href": 
"http://example.com/api/v1/stacks/STACK/versions/3.3/operating_systems/ubuntu18/repositories/STACK-3.3-GPL";,
+                    "Repositories": {
+                        "applicable_services": [],
+                        "base_url": 
"https://ad-STACK.s3.us-west-1.amazonaws.com/STACK-GPL/ubuntu18/3.x/updates/3.3.0.0";,
+                        "components": null,
+                        "default_base_url": 
"https://ad-STACK.s3.us-west-1.amazonaws.com/STACK-GPL/ubuntu18/3.x/updates/3.3.0.0";,
+                        "distribution": null,
+                        "mirrors_list": null,
+                        "os_type": "ubuntu18",
+                        "repo_id": "STACK-3.3-GPL",
+                        "repo_name": "STACK-GPL",
+                        "stack_name": "STACK",
+                        "stack_version": "3.3",
+                        "tags": [
+                            "GPL"
+                        ],
+                        "unique": false
+                    }
+                },
+                {
+                    "href": 
"http://example.com/api/v1/stacks/STACK/versions/3.3/operating_systems/ubuntu18/repositories/STACK-UTILS-1.1.0.22";,
+                    "Repositories": {
+                        "applicable_services": [],
+                        "base_url": 
"https://ad-STACK.s3.us-west-1.amazonaws.com/STACK-UTILS-1.1.0.22/repos/ubuntu18";,
+                        "components": null,
+                        "default_base_url": 
"https://ad-STACK.s3.us-west-1.amazonaws.com/STACK-UTILS-1.1.0.22/repos/ubuntu18";,
+                        "distribution": null,
+                        "mirrors_list": null,
+                        "os_type": "ubuntu18",
+                        "repo_id": "STACK-UTILS-1.1.0.22",
+                        "repo_name": "STACK-UTILS",
+                        "stack_name": "STACK",
+                        "stack_version": "3.3",
+                        "tags": [],
+                        "unique": false
+                    }
+                }
+            ]
+        }
+    ]
+}
\ No newline at end of file
diff --git 
a/ambari-admin/src/main/resources/ui/ambari-admin/src/components/AddVersionModal/index.tsx
 
b/ambari-admin/src/main/resources/ui/ambari-admin/src/components/AddVersionModal/index.tsx
new file mode 100644
index 0000000000..1380807872
--- /dev/null
+++ 
b/ambari-admin/src/main/resources/ui/ambari-admin/src/components/AddVersionModal/index.tsx
@@ -0,0 +1,116 @@
+import { ChangeEvent, useState } from 'react'
+import { Button, Form, FormControl, Modal } from 'react-bootstrap'
+import toast from 'react-hot-toast'
+import { get } from 'lodash'
+import DefaultButton from '../DefaultButton'
+import VersionsApi from '../../api/versions'
+import { ReadOptions } from '../../constants'
+
+type ModalProps = {
+  isOpen: boolean
+  onClose: () => void
+  onReadVersion: (versionResources: unknown) => void
+}
+
+const AddVersionModal = ({ isOpen, onClose, onReadVersion }: ModalProps) => {
+  const [uploadOption, setUploadOption] = 
useState<ReadOptions>(ReadOptions.FILE)
+  const [file, setFile] = useState<File | undefined>()
+  const [fileUrl, setFileUrl] = useState<string>('')
+
+  const readVersionInfo = async () => {
+    try {
+      if (uploadOption === ReadOptions.FILE && file) {
+        const reader = new FileReader()
+        reader.onload = async (event: ProgressEvent<FileReader>) => {
+          const fileContents = get(event, 'target.result', undefined)
+          const versionResources = await VersionsApi.readVersionInfo(
+            fileContents,
+            {
+              'Content-Type': 'text/xml',
+            },
+          )
+          onReadVersion(versionResources)
+        }
+        reader.readAsText(file)
+      } else if (uploadOption === ReadOptions.URL && fileUrl) {
+        const versionResources = await VersionsApi.readVersionInfo({
+          VersionDefinition: {
+            version_url: fileUrl,
+          },
+        })
+        onReadVersion(versionResources)
+      }
+    } catch (err) {
+      toast.error('Could not read version definition')
+    }
+  }
+
+  const handleClose = () => {
+    setFile(undefined)
+    setFileUrl('')
+    onClose()
+  }
+
+  return (
+    <Modal show={isOpen} onHide={onClose} data-testid="add-version-modal">
+      <Modal.Header>
+        <Modal.Title>Add Version</Modal.Title>
+      </Modal.Header>
+      <Modal.Body>
+        <Form.Check
+          checked={uploadOption === ReadOptions.FILE}
+          type="radio"
+          id={ReadOptions.FILE}
+          onChange={() => {
+            setUploadOption(ReadOptions.FILE)
+          }}
+          label="Upload Version Definition File"
+          className="px-0"
+        />
+        <FormControl
+          type="file"
+          className="py-1"
+          onChange={(event: ChangeEvent<HTMLInputElement>) => {
+            setFile(event?.target?.files?.[0])
+          }}
+          disabled={uploadOption !== ReadOptions.FILE}
+        />
+        <Form.Check
+          id={ReadOptions.URL}
+          checked={uploadOption === ReadOptions.URL}
+          onChange={() => {
+            setUploadOption(ReadOptions.URL)
+          }}
+          type="radio"
+          label="Version Definition File URL"
+          className="px-0 mt-3"
+        />
+        <FormControl
+          type="text"
+          className="py-1"
+          disabled={uploadOption !== ReadOptions.URL}
+          placeholder="Enter URL to Version Definition File"
+          value={fileUrl}
+          onChange={(e: ChangeEvent<HTMLInputElement>) => {
+            setFileUrl(e.target.value)
+          }}
+        />
+      </Modal.Body>
+      <Modal.Footer>
+        <DefaultButton size="sm" onClick={handleClose}>
+          CANCEL
+        </DefaultButton>
+        <Button
+          variant="success"
+          size="sm"
+          onClick={readVersionInfo}
+          disabled={!file && !fileUrl}
+        >
+          READ VERSION INFO
+        </Button>
+      </Modal.Footer>
+    </Modal>
+  )
+}
+
+export default AddVersionModal
diff --git 
a/ambari-admin/src/main/resources/ui/ambari-admin/src/components/LostNetworkModal/index.tsx
 
b/ambari-admin/src/main/resources/ui/ambari-admin/src/components/LostNetworkModal/index.tsx
new file mode 100644
index 0000000000..2d19e57c2e
--- /dev/null
+++ 
b/ambari-admin/src/main/resources/ui/ambari-admin/src/components/LostNetworkModal/index.tsx
@@ -0,0 +1,56 @@
+/**
+ * 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.
+ */
+import { Button, Modal } from "react-bootstrap";
+
+type PropTypes = {
+  onClose: () => void;
+  isOpen: boolean;
+};
+
+const LostNetworkModal = ({ onClose, isOpen }: PropTypes) => {
+  const options = [
+    "Configure your hosts for access to the Internet.",
+    " If you are using an Internet Proxy, refer to the Ambari Documentation on 
how to configure Ambari to use the Internet Proxy.",
+    "Use the Local Repository option.",
+  ];
+  return (
+    <Modal show={isOpen} onHide={onClose} size="lg">
+      <Modal.Header closeButton>
+        <Modal.Title>Public Repository Option Disabled</Modal.Title>
+      </Modal.Header>
+      <Modal.Body className="fs-12">
+        Ambari does not have access to the Internet and cannot use the Public
+        Repository for installing the software. Your Options:
+        <ul>
+          {options.map((opt:string)=>{
+            return <li key="opt" className="mt-2" style={{fontSize:12}}>
+              {opt}
+            </li>
+          })}
+        </ul>
+      </Modal.Body>
+      <Modal.Footer>
+        <Button variant="success" onClick={onClose}>
+          OK
+        </Button>
+      </Modal.Footer>
+    </Modal>
+  );
+};
+
+export default LostNetworkModal;
\ No newline at end of file
diff --git 
a/ambari-admin/src/main/resources/ui/ambari-admin/src/components/RedhatSatelliteInfoModal/index.tsx
 
b/ambari-admin/src/main/resources/ui/ambari-admin/src/components/RedhatSatelliteInfoModal/index.tsx
new file mode 100644
index 0000000000..2fcf27e514
--- /dev/null
+++ 
b/ambari-admin/src/main/resources/ui/ambari-admin/src/components/RedhatSatelliteInfoModal/index.tsx
@@ -0,0 +1,56 @@
+/**
+ * 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.
+ */
+import { Button, Modal } from "react-bootstrap";
+import DefaultButton from "../DefaultButton";
+
+type PropTypes = {
+  isOpen: boolean;
+  onClose: () => void;
+  onCancel: () => void;
+};
+
+const RedhatSatelliteUsageInfo = ({ isOpen, onClose, onCancel }: PropTypes) => 
{
+  return (
+    <Modal show={isOpen} onHide={onClose}>
+      <Modal.Header closeButton>
+        <Modal.Title>Use RedHat Satellite/Spacewalk</Modal.Title>
+      </Modal.Header>
+      <Modal.Body>
+        In order for Ambari to install packages from the right repositories, it
+        is recommended that you edit the names of the repo's for each operating
+        system so they match the channel names in your RedHat
+        Satellite/Spacewalk instance.
+      </Modal.Body>
+      <Modal.Footer>
+        <DefaultButton size="sm" onClick={onCancel}>
+          Cancel
+        </DefaultButton>
+        <Button
+          variant="success"
+          size="sm"
+          onClick={onClose}
+          className="rounded-1"
+        >
+          OK
+        </Button>
+      </Modal.Footer>
+    </Modal>
+  );
+};
+
+export default RedhatSatelliteUsageInfo;
\ No newline at end of file
diff --git a/ambari-admin/src/main/resources/ui/ambari-admin/src/constants.ts 
b/ambari-admin/src/main/resources/ui/ambari-admin/src/constants.ts
new file mode 100644
index 0000000000..1fd158b47e
--- /dev/null
+++ b/ambari-admin/src/main/resources/ui/ambari-admin/src/constants.ts
@@ -0,0 +1,21 @@
+/**
+ * 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.
+ */
+export enum ReadOptions {
+    FILE = "file",
+    URL = "url",
+  }
\ No newline at end of file
diff --git 
a/ambari-admin/src/main/resources/ui/ambari-admin/src/router/RoutesList.tsx 
b/ambari-admin/src/main/resources/ui/ambari-admin/src/router/RoutesList.tsx
index 6c68f3a70c..c49cc2dbad 100644
--- a/ambari-admin/src/main/resources/ui/ambari-admin/src/router/RoutesList.tsx
+++ b/ambari-admin/src/main/resources/ui/ambari-admin/src/router/RoutesList.tsx
@@ -18,6 +18,8 @@
 import { Redirect } from "react-router-dom";
 import Users from "../screens/Users";
 import WIP from "../components/WIP";
+import Register from "../screens/StackVersions/Register";
+import { VersionsList } from "../screens/StackVersions";
 
 
 
@@ -43,19 +45,19 @@ export default [
   {
     path: "/stackVersions/create",
     exact: true,
-    Element: () => <WIP />,
+    Element: () => <Register readOnly={false} />,
     name: "Stack Versions",
   },
   {
     path: "/stackVersions/:stack/:version/edit",
     exact: true,
-    Element: () => <WIP />,
+    Element: () => <Register readOnly />,
     name: "Stack Versions",
   },
   {
     path: "/stackVersions",
     exact: true,
-    Element: () => <WIP />,
+    Element: () => <VersionsList />,
     name: "Stack Versions",
   },
   {
diff --git 
a/ambari-admin/src/main/resources/ui/ambari-admin/src/screens/StackVersions/Register.tsx
 
b/ambari-admin/src/main/resources/ui/ambari-admin/src/screens/StackVersions/Register.tsx
new file mode 100644
index 0000000000..8e7f74e739
--- /dev/null
+++ 
b/ambari-admin/src/main/resources/ui/ambari-admin/src/screens/StackVersions/Register.tsx
@@ -0,0 +1,1287 @@
+/**
+ * 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.
+ */
+/* eslint-disable no-useless-escape */
+/* eslint-disable no-unsafe-optional-chaining */
+/* eslint-disable @typescript-eslint/ban-ts-comment */
+/* eslint-disable @typescript-eslint/no-explicit-any */
+import { useContext, useEffect, useState } from "react";
+import {
+  Item,
+  VersionDefinition,
+  VersionDefinitionResponse,
+} from "./types/VersionDefinitions";
+import { Link, useHistory, useParams } from "react-router-dom";
+import {
+  Col,
+  Dropdown,
+  DropdownButton,
+  Nav,
+  Row,
+  Tab,
+  Form,
+  OverlayTrigger,
+  Alert,
+  Button,
+  Tooltip,
+  InputGroup,
+} from "react-bootstrap";
+import { TransformedOperatingSystem, TransformedRepo } from "./types/Os";
+import find from "lodash/find";
+import set from "lodash/set";
+import cloneDeep from "lodash/cloneDeep";
+import isEmpty from "lodash/isEmpty";
+import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
+import {
+  faAdd,
+  faMinus,
+  faPencil,
+  faQuestionCircle,
+  faUndo,
+} from "@fortawesome/free-solid-svg-icons";
+import toast from "react-hot-toast";
+import AppContent from "../../context/AppContext";
+import DefaultButton from "../../components/DefaultButton";
+import Table from "../../components/Table";
+import ConfirmationModal from "../../components/ConfirmationModal";
+import Spinner from "../../components/Spinner";
+import VersionsApi from "../../api/versions";
+import AddVersionModal from "../../components/AddVersionModal";
+import RedhatSatelliteUsageInfo from 
"../../components/RedhatSatelliteInfoModal";
+import LostNetworkModal from "../../components/LostNetworkModal";
+
+enum RepositoryType {
+  PUBLIC = "public",
+  LOCAL = "local",
+}
+
+enum OSOperations {
+  GET = "get",
+  EDITALL = "editall",
+}
+
+const Register = ({ readOnly }: { readOnly: boolean }): JSX.Element => {
+  const [versionDefinitions, setVersionDefinitions] = useState<Item[]>([]);
+  const [selectedVersion, setSelectedVersion] = useState<any>({});
+  const [networkLost, setNetworkLost] = useState<boolean>(false);
+  const [showRegistrationModal, setShowRegistrationModal] =
+    useState<boolean>(false);
+  const [selectedStack, setSelectedStack] = useState<VersionDefinition>(
+    {} as VersionDefinition
+  );
+  const history = useHistory();
+  const [selectedChoice, setSelectedChoice] = useState<string>(
+    RepositoryType.PUBLIC
+  );
+  const {
+    cluster: { cluster_name: clusterName },
+    setSelectedOption,
+  } = useContext(AppContent);
+  const { stack, version } = useParams<any>();
+  const [versionNumber, setVersionNumber] = useState(
+    version?.substring(4, version.length) || ""
+  );
+  const [versionValidationError, setVersionValidationError] = useState(false);
+  const [showNetworkModal, setShowNetworkModal] = useState<boolean>(false);
+  const [skipValidation, setSkipValidation] = useState<boolean>(false);
+  const [redhatSatellite, setRedhatSatellite] = useState<boolean>(false);
+  const [repoInfo, setRepoInfo] = useState<{ status: string }>(
+    {} as { status: string }
+  );
+  const [savedRepositoryVersionDetails, setSavedRepositoryVersionDetails] =
+    useState<any>({});
+  const [showRepoValidationBanner, setShowRepoValidationBanner] =
+    useState<boolean>(false);
+  const [showRedhatInfoModal, setShowRedhatInfoModal] =
+    useState<boolean>(false);
+  const [showAddVersionModal, setShowAddVersionModal] = useState(false);
+  const [addedVersions, setAddedVersions] = useState<{
+    [key: string]: { label: string; value: string }[];
+  }>({});
+  const [operatingSystems, setOperatingSystems] = useState<{
+    [key: string]: TransformedOperatingSystem[];
+  }>({});
+  const [confirmDeregister, setConfirmDeregister] = useState<boolean>(false);
+
+  console.log("Added Versions", addedVersions, selectedStack);
+
+  const selectNewVersion = (
+    version: VersionDefinition,
+    newVersion?: { label: string; value: string },
+    newVersionDefinition?: VersionDefinition
+  ) => {
+    if (version.id) {
+      const addedVersionsCopy: {
+        [key: string]: { label: string; value: any }[];
+      } = cloneDeep(addedVersions);
+      const defaultVersion = {
+        label: `${version.id} (Default Version definition)`,
+        value: version,
+      };
+      if (addedVersionsCopy[version.id]) {
+        if (newVersion)
+          addedVersionsCopy[version.id] = [
+            ...addedVersionsCopy[version.id],
+            newVersion,
+          ];
+      } else {
+        if (newVersion) {
+          addedVersionsCopy[version.id] = [defaultVersion, newVersion];
+        } else {
+          addedVersionsCopy[version.id] = [defaultVersion];
+        }
+      }
+      setAddedVersions(addedVersionsCopy);
+      setSelectedVersion(newVersionDefinition ? newVersionDefinition : 
version);
+    }
+  };
+
+  useEffect(() => {
+    setSelectedOption("Versions");
+    async function getVersionDefinitions() {
+      const definitions: VersionDefinitionResponse =
+        await VersionsApi.getVersionDefinitions();
+      const sortedItems = definitions.items.sort((a: any, b: any) => {
+        const versionA = parseFloat(a.VersionDefinition.id.split("-")[1]);
+        const versionB = parseFloat(b.VersionDefinition.id.split("-")[1]);
+
+        return versionB - versionA;
+      });
+      setVersionDefinitions(sortedItems);
+      setNetworkIssues(definitions.items);
+      //@ts-ignore
+      setSelectedStack(sortedItems[0]?.VersionDefinition);
+      //@ts-ignore
+      selectNewVersion(sortedItems[0]?.VersionDefinition);
+    }
+    getVersionDefinitions();
+  }, []);
+
+  useEffect(() => {
+    async function getReposData() {
+      const stackVersion = await VersionsApi.versionsList(
+        savedRepositoryVersionDetails.id,
+        clusterName
+      );
+      const repoStackVersion = stackVersion?.items?.[0];
+      setRepoInfo({
+        ...repoInfo,
+        status: repoStackVersion?.ClusterStackVersions.state,
+      });
+    }
+    if (!isEmpty(savedRepositoryVersionDetails)) {
+      getReposData();
+    }
+  }, [savedRepositoryVersionDetails]);
+
+  useEffect(() => {
+    if (!versionNumber) {
+      setVersionValidationError(false);
+    } else {
+      // Pattern for two numbers separated by a dot
+      const twoNumbersPattern = /^\d+\.\d+$/;
+      // Pattern for three numbers separated by a dot and a dash
+      const threeNumbersPattern = /^\d+\.\d+-\d+$/;
+
+      // Check if the string matches any of the patterns
+      if (
+        twoNumbersPattern.test(versionNumber) ||
+        threeNumbersPattern.test(versionNumber)
+      ) {
+        setVersionValidationError(false);
+      } else {
+        setVersionValidationError(true);
+      }
+    }
+  }, [versionNumber]);
+
+  useEffect(() => {
+    if (redhatSatellite) {
+      setShowRedhatInfoModal(true);
+      const updatedOs = editAllRepos("isEditable", false);
+      setOperatingSystems(updatedOs);
+    } else {
+      const updatedOs = editAllRepos("isEditable", true);
+      setOperatingSystems(updatedOs);
+    }
+  }, [redhatSatellite]);
+
+  const getOsfromRepoDetails = (oSystem: string, alreadyAddedOs: any) => {
+    let operatingSystem;
+    for (const addedOs of alreadyAddedOs?.[0]?.repository_versions?.[0]
+      ?.operating_systems) {
+      if (addedOs.OperatingSystems.os_type === oSystem) {
+        operatingSystem = addedOs;
+      }
+    }
+    return operatingSystem;
+  };
+
+  useEffect(() => {
+    async function getVersionOs() {
+      const versionOperatingSystems =
+        await VersionsApi.getVersionOperatingSystems(
+          selectedStack.stack_version
+        );
+      let alreadyAddedOs: any = [];
+      if (readOnly) {
+        const repoDetails = await VersionsApi.getRepoDetails(stack, version);
+        setSavedRepositoryVersionDetails(
+          repoDetails?.items?.[0]?.repository_versions?.[0]?.RepositoryVersions
+        );
+        alreadyAddedOs = repoDetails.items;
+      }
+      const allOs: TransformedOperatingSystem[] =
+        versionOperatingSystems.operating_systems.map((os: any) => {
+          const defaultRepos = os.repositories.map((repo: any) => {
+            return {
+              id: repo.Repositories.repo_id,
+              defaultId: repo.Repositories.repo_id,
+              baseUrl: repo?.Repositories?.base_url,
+              name: repo?.Repositories?.repo_name,
+              defaultUrl: repo?.Repositories?.default_base_url,
+            };
+          });
+          const matchingOs = readOnly
+            ? getOsfromRepoDetails(os.OperatingSystems.os_type, alreadyAddedOs)
+            : undefined;
+          const isOsAdded = readOnly ? (matchingOs ? true : false) : true;
+          return {
+            os: os.OperatingSystems.os_type,
+            isAdded: isOsAdded,
+            repos: readOnly
+              ? matchingOs
+                ? matchingOs.repositories.map((repo: any) => {
+                    return {
+                      id: repo.Repositories.repo_id,
+                      defaultId: repo.Repositories.repo_id,
+                      baseUrl: repo?.Repositories?.base_url,
+                      name: repo?.Repositories?.repo_name,
+                      defaultUrl: repo?.Repositories?.base_url,
+                    };
+                  })
+                : defaultRepos
+              : defaultRepos,
+          };
+        });
+      const operatingSystemsCopy = cloneDeep(operatingSystems);
+      operatingSystemsCopy[selectedVersion.id] = [...allOs];
+      setOperatingSystems(operatingSystemsCopy);
+    }
+    if (
+      selectedStack &&
+      selectedVersion &&
+      selectedVersion.id &&
+      !operatingSystems[selectedVersion.id]
+    ) {
+      getVersionOs();
+    }
+  }, [selectedVersion]);
+
+  function getColumns() {
+    return [
+      {
+        header: "",
+        accessorKey: "display_name",
+        id: "name",
+      },
+      {
+        header: "",
+        id: "versions",
+        cell: (info: any) => {
+          const allVersions = info.row.original.versions;
+          return allVersions.join(",");
+        },
+      },
+    ];
+  }
+
+  const getSystemsWithKeyValue = (
+    key: string,
+    value: any,
+    osOperation: string
+  ) => {
+    const osCopy = cloneDeep(operatingSystems);
+    switch (osOperation) {
+      case OSOperations.GET:
+        return osCopy?.[selectedVersion.id]?.filter(
+          (oSystem: TransformedOperatingSystem) =>
+            oSystem[key as keyof TransformedOperatingSystem] === value
+        );
+      case OSOperations.EDITALL:
+        return osCopy?.[selectedVersion]?.map(
+          (oSystem: TransformedOperatingSystem) => {
+            //@ts-ignore
+            oSystem[key as keyof TransformedOperatingSystem] = value;
+            return oSystem;
+          }
+        );
+    }
+  };
+
+  const redirectToList = () => {
+    history.push("/stackVersions");
+  };
+
+  const deRegisterVersion = async () => {
+    if (repoInfo?.status == "CURRENT" || repoInfo?.status == "INSTALLED") {
+      toast.error("The version cannot be deregistered.");
+    } else {
+      try {
+        await VersionsApi.deleteRepositoryVersion(
+          savedRepositoryVersionDetails.stack_name,
+          savedRepositoryVersionDetails.stack_version,
+          savedRepositoryVersionDetails.id
+        );
+        toast.success("Version Deleted Successfully");
+        redirectToList();
+      } catch (err) {
+        toast.error("Version Delete Error");
+      }
+    }
+  };
+
+  const getAddableOperatingSystems = () => {
+    const addableSystems = getSystemsWithKeyValue(
+      "isAdded",
+      false,
+      OSOperations.GET
+    );
+    return addableSystems || [];
+  };
+
+  const handleModalVisibility = (show: boolean) => {
+    setShowNetworkModal(show);
+  };
+
+  const setNetworkIssues = (versions: any[]) => {
+    const isNetworkLost = !versions.find(
+      (_version) => !_version.VersionDefinition.stack_default
+    );
+
+    if (isNetworkLost) {
+      setSelectedChoice(RepositoryType.LOCAL);
+      // clearRepoVersions();
+    }
+    setNetworkLost(isNetworkLost);
+  };
+
+  const addBackOperatingSystem = (os: TransformedOperatingSystem) => {
+    const osCopy = cloneDeep(operatingSystems);
+    if (osCopy?.[selectedVersion.id]) {
+      const matchingOs = osCopy?.[selectedVersion.id].find(
+        (oSystem) => oSystem.os === os.os
+      );
+      if (matchingOs) {
+        matchingOs.isAdded = true;
+        setOperatingSystems(osCopy);
+      }
+    }
+  };
+
+  const osListHeaders = [
+    {
+      label: "OS",
+      columnCount: 3,
+    },
+    {
+      label: "name",
+      columnCount: 3,
+    },
+    { label: "Base URL", columnCount: 5 },
+    {
+      columnCount: 1,
+      label: (
+        <Dropdown>
+          <Dropdown.Toggle
+            className="btn-default"
+            as={Button}
+            variant="secondary"
+            size="sm"
+          >
+            <FontAwesomeIcon className="me-2" icon={faAdd} />
+            Add
+          </Dropdown.Toggle>
+
+          <Dropdown.Menu>
+            {getAddableOperatingSystems()?.map((oSystem) => {
+              return (
+                <Dropdown.Item
+                  onClick={() => {
+                    addBackOperatingSystem(oSystem);
+                  }}
+                  key={oSystem.os}
+                  className="text-dark"
+                >
+                  {oSystem.os}
+                </Dropdown.Item>
+              );
+            })}
+          </Dropdown.Menu>
+        </Dropdown>
+      ),
+    },
+  ];
+
+  const isAllOsValidated = () => {
+    let allOsRemoved = true;
+    const remotePattern =
+      
/^(?:(?:https?|ftp):\/{2})(?:\S+(?::\S*)?@)?(?:(?:(?:[\w\-.]))*)(?::[0-9]+)?(?:\/\S*)?$/;
+    const localPattern =
+      /^file:\/{2,3}([a-zA-Z][:|]\/){0,1}[\w~!*'();@&=\/\\\-+$,?%#.\[\]]+$/;
+    if (operatingSystems?.[selectedVersion.id]) {
+      for (const oSystem of operatingSystems?.[selectedVersion.id]) {
+        if (oSystem.isAdded) {
+          allOsRemoved = false;
+        }
+        for (const repo of oSystem.repos) {
+          if (
+            oSystem.isAdded &&
+            !(
+              remotePattern.test(repo.baseUrl) ||
+              localPattern.test(repo.baseUrl)
+            )
+          ) {
+            return false;
+          }
+        }
+      }
+      return allOsRemoved ? false : true;
+    }
+    return false;
+  };
+
+  function editAllRepos(key: string, value: any) {
+    const operatingSystemsCopy = cloneDeep(operatingSystems);
+    const allOs = operatingSystemsCopy?.[selectedVersion.id];
+    allOs?.map((os: TransformedOperatingSystem) => {
+      os.repos.map((repo) => {
+        //@ts-ignore
+        repo[key as keyof TransformedRepo] = value;
+        return repo;
+      });
+      return os;
+    });
+    return operatingSystemsCopy;
+  }
+
+  function editOsOrRepo(
+    operatingSystem: string,
+    repoId: string,
+    key: string,
+    value: any
+  ) {
+    const operatingSystemsCopy = cloneDeep(operatingSystems);
+    const matchingOperatingSystem = find(
+      operatingSystemsCopy?.[selectedVersion.id],
+      {
+        os: operatingSystem,
+      }
+    );
+
+    if (matchingOperatingSystem) {
+      if (repoId) {
+        const matchingRepo = find(matchingOperatingSystem.repos, {
+          id: repoId,
+        });
+
+        if (matchingRepo) {
+          //@ts-ignore
+          matchingRepo[key as keyof TransformedRepo] =
+            value as TransformedRepo[keyof TransformedRepo];
+          matchingRepo.hasError = false;
+          setOperatingSystems(operatingSystemsCopy);
+        }
+      } else {
+        set(matchingOperatingSystem, key, value);
+        setOperatingSystems(operatingSystemsCopy);
+      }
+    }
+  }
+
+  async function saveVersion() {
+    let createdVersionDefinition: any = {};
+    if (!readOnly)
+      try {
+        createdVersionDefinition = await VersionsApi.readVersionInfo(
+          {
+            VersionDefinition: {
+              available: selectedStack.id,
+              display_name: `${selectedStack.id}.${versionNumber}`,
+            },
+          },
+          {},
+          false
+        );
+      } catch (err) {
+        toast.error("Could not read version info");
+      }
+    const addedOs = operatingSystems?.[selectedVersion.id]?.filter(
+      (os: TransformedOperatingSystem) => os.isAdded
+    );
+    let payload = {};
+
+    payload = {
+      ...(readOnly && {
+        RepositoryVersions: savedRepositoryVersionDetails,
+      }),
+      operating_systems: addedOs?.map((os: TransformedOperatingSystem) => {
+        return {
+          OperatingSystems: {
+            os_type: os.os,
+            ambari_managed_repositories: skipValidation,
+            stack_name: selectedStack.stack_name,
+            stack_version: selectedStack.stack_version,
+            ...(readOnly && {
+              repository_version_id: savedRepositoryVersionDetails.id,
+            }),
+            ...(!readOnly && { version_defintion_id: selectedStack.id }),
+          },
+          repositories: os.repos.map((repo: TransformedRepo) => {
+            return {
+              Repositories: {
+                applicable_services: [],
+                base_url: repo.baseUrl,
+                components: null,
+                default_base_url: "",
+                distribution: null,
+                intial_base_url: repo.defaultUrl,
+                initial__repo_id: selectedStack.id,
+                mirrors_list: null,
+                os_type: os.os,
+                stack_name: selectedStack.stack_name,
+                stack_version: selectedStack.stack_version,
+                tags: [],
+                unique: false,
+                version_defintion_id: selectedStack.id,
+                repo_id: repo.id,
+                repo_name: repo.name,
+              },
+              hasError: false,
+              invalidBaseUrl: false,
+            };
+          }),
+          selected: true,
+        };
+      }),
+    };
+    try {
+      await VersionsApi.saveRepoVersions(
+        selectedStack.stack_name,
+        selectedStack.stack_version,
+        readOnly
+          ? savedRepositoryVersionDetails?.id
+          : //@ts-ignore
+            createdVersionDefinition?.resources?.[0]?.VersionDefinition?.id,
+        payload
+      );
+      toast.success("Version saved successfully");
+      redirectToList();
+    } catch (err: any) {
+      const errorMessage = err?.response?.data?.message;
+      if (
+        errorMessage?.includes(
+          "is already defined for another repository version"
+        )
+      ) {
+        setShowRegistrationModal(true);
+        await VersionsApi.deleteRepositoryVersion(
+          selectedStack.stack_name,
+          selectedStack.stack_version,
+          createdVersionDefinition?.resources?.[0]?.VersionDefinition?.id
+        );
+      }
+      // toast.error("Could not save version");
+    }
+  }
+
+  async function validateRepos() {
+    if (!isAllOsValidated) {
+      return;
+    }
+    if (skipValidation) {
+      saveVersion();
+    } else {
+      const operatingSystemsCopy = cloneDeep(operatingSystems);
+      let allOsValidated = false;
+      const versionValidationPromises = [];
+      const allAddedOs = operatingSystemsCopy?.[selectedVersion.id].filter(
+        (oSystem) => oSystem.isAdded
+      );
+      for (const oSystem of allAddedOs) {
+        const repos = oSystem.repos;
+        for (const repo of repos) {
+          versionValidationPromises.push(
+            VersionsApi.validateRepos(
+              selectedStack.stack_version,
+              selectedStack.stack_version,
+              oSystem.os,
+              repo.id,
+              {
+                base_url: repo.baseUrl,
+                repo_name: repo.name,
+              }
+            )
+          );
+        }
+      }
+      try {
+        const validationResponses = await Promise.allSettled(
+          versionValidationPromises
+        );
+        //In the response array map the response operation to corresponding 
repo via matching index
+        //If the response at nth index is empty then the nth repo is valid add 
a key called hasError false
+        //If the response at nth index is not empty then the nth repo is 
invalid add a key called hasError true
+        const osWithValidationStatus = allAddedOs.map((os, osIndex) => {
+          os.repos.map((repo, repoIndex) => {
+            if (
+              validationResponses[osIndex * os.repos.length + repoIndex]
+                ?.status === "rejected"
+            ) {
+              allOsValidated = false;
+              repo.hasError = true;
+            } else {
+              repo.hasError = false;
+            }
+            return repo;
+          });
+          return os;
+        });
+        const osCopy = cloneDeep(operatingSystems);
+        osCopy[selectedVersion.id].map((oSystem) => {
+          const matchingOs = osWithValidationStatus.find(
+            (os) => os.os === oSystem.os
+          );
+          if (matchingOs) {
+            oSystem.repos = matchingOs.repos;
+          }
+          return oSystem;
+        });
+        if (!allOsValidated) {
+          setShowRepoValidationBanner(true);
+        } else {
+          setShowRepoValidationBanner(false);
+          saveVersion();
+        }
+        setOperatingSystems({
+          ...operatingSystems,
+          [selectedVersion.id]: osCopy[selectedVersion.id],
+        });
+      } catch (error) {
+        console.log("Error", error);
+      }
+    }
+  }
+
+  const readVersionCallback = async (versionResources: any) => {
+    try {
+      const addedVersionOperatingSystems =
+        versionResources?.resources?.[0]?.operating_systems;
+      const addedVersion = versionResources?.resources?.[0]?.VersionDefinition;
+
+      const versionOperatingSystems =
+        await VersionsApi.getVersionOperatingSystems(
+          selectedStack.stack_version
+        );
+      const newVersion = {
+        label: `${addedVersion.stack_name}-${addedVersion.repository_version}`,
+        value: {
+          ...addedVersion,
+          id: addedVersion.repository_version,
+          defaultId: addedVersion.repository_version,
+        },
+      };
+      const stackVersion = addedVersion.stack_version;
+      const belongingStack = versionDefinitions.find((definition) => {
+        return definition.VersionDefinition.stack_version === stackVersion;
+      });
+      const addedOperatingSystems = addedVersionOperatingSystems.map(
+        (os: any) => {
+          return os.OperatingSystems.os_type;
+        }
+      );
+      const allOs: TransformedOperatingSystem[] =
+        versionOperatingSystems.operating_systems.map((os: any) => {
+          const matchingOs =
+            versionResources?.resources?.[0]?.operating_systems.find(
+              (oS: any) => {
+                return (
+                  oS.OperatingSystems.os_type === os.OperatingSystems.os_type
+                );
+              }
+            );
+          return {
+            os: os.OperatingSystems.os_type,
+            isAdded: 
addedOperatingSystems.includes(os.OperatingSystems.os_type)
+              ? true
+              : false,
+            repos: (addedOperatingSystems.includes(os.OperatingSystems.os_type)
+              ? matchingOs
+              : os
+            ).repositories.map((repo: any) => {
+              return {
+                id: repo.Repositories.repo_id,
+                defaultId: repo.Repositories.repo_id,
+                baseUrl: repo?.Repositories?.base_url,
+                name: repo?.Repositories?.repo_name,
+                defaultUrl: repo?.Repositories?.default_base_url || "",
+              };
+            }),
+          };
+        });
+
+      const operatingSystemsCopy = cloneDeep(operatingSystems);
+      operatingSystemsCopy[addedVersion.repository_version] = [...allOs];
+      setOperatingSystems(operatingSystemsCopy);
+
+      setSelectedStack(belongingStack?.VersionDefinition as VersionDefinition);
+      selectNewVersion(
+        belongingStack?.VersionDefinition as VersionDefinition,
+        newVersion,
+        {
+          ...addedVersion,
+          id: addedVersion.repository_version,
+        }
+      );
+      const addedVersionName = addedVersion.repository_version.split(".");
+      setVersionNumber(
+        addedVersionName.splice(2, addedVersionName.length).join(".")
+      );
+      setShowAddVersionModal(false);
+    } catch (err) {
+      toast.error("Could not read version");
+      console.log("Error", err);
+    }
+  };
+
+  const readOnlyRepoProperties = [
+    {
+      label: "Stack",
+      value: 
`${savedRepositoryVersionDetails?.stack_name}-${savedRepositoryVersionDetails?.stack_version}`,
+    },
+    {
+      label: "Name",
+      value: savedRepositoryVersionDetails?.display_name,
+    },
+    {
+      label: "Version",
+      value: savedRepositoryVersionDetails?.repository_version,
+    },
+  ];
+
+  if (!versionDefinitions.length || isEmpty(operatingSystems)) {
+    return <Spinner />;
+  }
+
+  return (
+    <>
+      <ConfirmationModal
+        isOpen={confirmDeregister}
+        onClose={() => {
+          setConfirmDeregister(false);
+        }}
+        modalTitle="Deregister Version"
+        modalBody={`Are you sure you want to deregister the version 
${savedRepositoryVersionDetails.stack_name}-${savedRepositoryVersionDetails.repository_version}?`}
+        successCallback={deRegisterVersion}
+      />
+      <AddVersionModal
+        isOpen={showAddVersionModal}
+        onReadVersion={readVersionCallback}
+        onClose={() => {
+          setShowAddVersionModal(false);
+        }}
+      />
+      <LostNetworkModal
+        isOpen={showNetworkModal}
+        onClose={() => {
+          handleModalVisibility(false);
+        }}
+      ></LostNetworkModal>
+      <RedhatSatelliteUsageInfo
+        isOpen={showRedhatInfoModal}
+        onCancel={() => {
+          setShowRedhatInfoModal(false);
+          setRedhatSatellite(false);
+        }}
+        onClose={() => {
+          setShowRedhatInfoModal(false);
+        }}
+      />
+      <ConfirmationModal
+        modalTitle="Unable to Register"
+        modalBody="You are attempting to register a version with a Base URL 
that is already in use with an existing registered version. You *must* review 
your Base URLs and confirm they are unique for the version you are trying to 
register."
+        isOpen={showRegistrationModal}
+        successCallback={() => {
+          setShowRegistrationModal(false);
+        }}
+        onClose={() => {
+          setShowRegistrationModal(false);
+        }}
+      />
+      <div
+        className="breadcrumb d-flex border-bottom pb-2"
+        style={{ flexWrap: "nowrap" }}
+      >
+        <Link to="/stackVersions">
+          {" "}
+          <h3>Versions</h3>
+        </Link>
+        <div className="mx-2">
+          <h3 className="text-muted">/</h3>
+        </div>
+        <div className="d-flex justify-content-between w-100 
align-items-center">
+          <div className="text-muted d-flex align-items-center">
+            <h3>
+              {readOnly
+                ? savedRepositoryVersionDetails?.display_name
+                : "Register Version"}
+            </h3>
+            {readOnly ? (
+              <h5 className="ms-2">
+                ({savedRepositoryVersionDetails?.stack_name}-
+                {savedRepositoryVersionDetails?.repository_version})
+              </h5>
+            ) : null}
+          </div>
+          {readOnly ? (
+            <Button
+              variant="danger"
+              size="sm"
+              onClick={() => {
+                setConfirmDeregister(true);
+              }}
+              disabled={
+                repoInfo?.status == "CURRENT" || repoInfo?.status == 
"INSTALLED"
+              }
+            >
+              DEREGISTER VERSION
+            </Button>
+          ) : null}
+        </div>
+      </div>
+      <Row style={{ height: "35vh" }}>
+        {readOnly ? (
+          <Col
+            sm={3}
+            className="alert alert-info d-flex flex-column px-3 rounded-1 me-4"
+            style={{ height: "40%" }}
+          >
+            {readOnlyRepoProperties.map((property) => {
+              return (
+                <div className="d-flex justify-content-between mt-3">
+                  <div>{property.label}</div>
+                  <div>{property.value}</div>
+                </div>
+              );
+            })}
+          </Col>
+        ) : (
+          <Tab.Container>
+            <Col sm={2}>
+              <Nav variant="pills" className="flex-column">
+                {versionDefinitions.map((definition) => {
+                  return (
+                    <Nav.Item
+                      data-testid="version-definition"
+                      onClick={() => {
+                        selectNewVersion(definition.VersionDefinition);
+                        setSelectedStack(definition.VersionDefinition);
+                      }}
+                      className={`mt-3 ${
+                        selectedStack.id === definition.VersionDefinition.id
+                          ? "border-bottom border-2 border-success"
+                          : "muted-text"
+                      }`}
+                    >
+                      <Nav.Link
+                        className={`nowrap text-decoration-none ${
+                          selectedStack.id === definition.VersionDefinition.id
+                            ? "text-dark"
+                            : "muted-text"
+                        } `}
+                      >
+                        {definition.VersionDefinition.id}
+                      </Nav.Link>
+                    </Nav.Item>
+                  );
+                })}
+              </Nav>
+            </Col>
+          </Tab.Container>
+        )}
+        {/* <Col sm={1}></Col> */}
+        <Col
+          sm={readOnly ? 8 : 9}
+          className="border p-3 ms-5"
+          style={{ maxHeight: "100%", overflow: "hidden" }}
+        >
+          {readOnly ? null : (
+            <div className="d-flex justify-content-between">
+              <Dropdown>
+                <DropdownButton
+                  size="sm"
+                  variant="info"
+                  id="dropdown-basic"
+                  data-testid="version-dropdown"
+                  title={
+                    selectedVersion.id || selectedVersion.repository_version
+                  }
+                >
+                  {addedVersions[selectedStack.id]
+                    ? addedVersions?.[selectedStack.id]?.map((vers, index) => {
+                        return (
+                          <Dropdown.Item
+                            key={index}
+                            className="text-dark"
+                            onClick={() => {
+                              setSelectedVersion(vers.value);
+                            }}
+                          >
+                            {vers.label}
+                          </Dropdown.Item>
+                        );
+                      })
+                    : null}
+                  <Dropdown.Item
+                    className="text-dark"
+                    onClick={() => {
+                      setShowAddVersionModal(true);
+                    }}
+                    data-testid="add-version"
+                  >
+                    Add Version
+                  </Dropdown.Item>
+                </DropdownButton>
+              </Dropdown>
+              {readOnly ? null : (
+                <Form.Group className="d-flex align-items-center">
+                  <Form.Label className="nowrap">
+                    {" "}
+                    Name: {selectedStack.stack_name}-
+                    {selectedStack.stack_version}.
+                  </Form.Label>
+                  <InputGroup className="d-flex flex-column w-100">
+                    <Form.Control
+                      data-testid="version-input"
+                      type="text"
+                      className={`w-100 ${
+                        versionValidationError ? "border border-danger" : ""
+                      }`}
+                      placeholder="Version Number (0.0)"
+                      value={versionNumber}
+                      onChange={(e) => {
+                        setVersionNumber(e.target.value);
+                      }}
+                    />
+                    <div
+                      className={`text-danger ${
+                        versionValidationError ? "visible" : "invisible"
+                      }`}
+                    >
+                      {selectedStack.stack_name}-{selectedStack.stack_version}.
+                      {versionNumber} invalid
+                    </div>
+                  </InputGroup>
+                </Form.Group>
+              )}
+            </div>
+          )}
+          <div
+            className="border mt-2 overflow-auto"
+            style={{ maxHeight: "100%" }}
+          >
+            <Table
+              striped
+              columns={getColumns()}
+              data-testid="stack-services"
+              data={
+                (versionDefinitions?.find(
+                  (definition) =>
+                    definition.VersionDefinition.stack_version ===
+                    selectedVersion.stack_version
+                )?.VersionDefinition.stack_services as unknown[]) || []
+              }
+            />
+          </div>
+        </Col>
+      </Row>
+      <Row className="mt-4">
+        <div className="d-flex ps-0">
+          <Form.Check
+            type="radio"
+            disabled={networkLost}
+            label="Use Public repository"
+            checked={selectedChoice === RepositoryType.PUBLIC}
+          />
+          {networkLost ? (
+            <div
+              className="ms-2 custom-link cursor-pointer"
+              onClick={() => {
+                handleModalVisibility(true);
+              }}
+            >
+              Why is this disabled?
+            </div>
+          ) : null}
+        </div>
+
+        <Form.Check
+          checked={selectedChoice === RepositoryType.LOCAL}
+          type="radio"
+          label="Use Local repository"
+        />
+      </Row>
+      <Row className="border mx-2">
+        <div className="border-bottom bg-light">
+          <div className="p-3 fs-6">Repositories</div>
+        </div>
+        <div className="p-3">
+          <Alert variant="info" className="">
+            Provide Base URLs for the Operating Systems you are configuring.
+          </Alert>
+
+          {showRepoValidationBanner ? (
+            <Alert variant="warning" className="">
+              Some of the repositories failed validation. Make changes to the
+              base url or skip validation if you are sure that urls are correct
+            </Alert>
+          ) : null}
+          <Row className="align-items-center py-3 border-bottom">
+            {osListHeaders.map((header) => {
+              return <Col md={header.columnCount}>{header.label}</Col>;
+            })}
+          </Row>
+          {operatingSystems?.[selectedVersion.id]
+            ?.filter((oSystem: TransformedOperatingSystem) => oSystem.isAdded)
+            ?.map((oSystem: any) => {
+              return (
+                <Row
+                  className="border-bottom py-4"
+                  data-testid="operating-systems"
+                >
+                  <Col md={3}>{oSystem.os}</Col>
+                  <Col md={8}>
+                    {oSystem?.repos?.map((repo: any, index: any) => {
+                      return (
+                        <Row
+                          className={`d-flex align-items-center nowrap ${
+                            index > 0 ? "mt-4" : ""
+                          }`}
+                        >
+                          {" "}
+                          <Col
+                            md={4}
+                            className={`d-flex align-items-center ${
+                              repo.hasError ? "text-danger" : ""
+                            }`}
+                          >
+                            {repo.isEditing ? (
+                              <Form
+                                onSubmit={(e) => {
+                                  e.preventDefault();
+                                  editOsOrRepo(
+                                    oSystem.os,
+                                    repo.id,
+                                    "isEditing",
+                                    false
+                                  );
+                                }}
+                              >
+                                <Form.Control
+                                  value={repo.id}
+                                  onChange={(e) => {
+                                    editOsOrRepo(
+                                      oSystem.os,
+                                      repo.id,
+                                      "id",
+                                      e.target.value
+                                    );
+                                  }}
+                                  type="text"
+                                  data-testid="repo-id-input"
+                                ></Form.Control>
+                              </Form>
+                            ) : (
+                              repo.id
+                            )}
+                            {redhatSatellite && !repo.isEditing ? (
+                              <FontAwesomeIcon
+                                data-testid="pencil-icon"
+                                className="ms-2"
+                                icon={faPencil}
+                                onClick={() => {
+                                  editOsOrRepo(
+                                    oSystem.os,
+                                    repo.id,
+                                    "isEditing",
+                                    true
+                                  );
+                                }}
+                              />
+                            ) : null}
+                            {repo.isEditing && repo.id !== repo.defaultId ? (
+                              <FontAwesomeIcon
+                                icon={faUndo}
+                                className="text-warning ms-2"
+                                onClick={() => {
+                                  editOsOrRepo(
+                                    oSystem.os,
+                                    repo.id,
+                                    "id",
+                                    repo.defaultId
+                                  );
+                                }}
+                              ></FontAwesomeIcon>
+                            ) : null}
+                          </Col>
+                          <Col md={8} className="d-flex align-items-center">
+                            <Form.Control
+                              onChange={(e) => {
+                                editOsOrRepo(
+                                  oSystem.os,
+                                  repo.id,
+                                  "baseUrl",
+                                  e.target.value
+                                );
+                              }}
+                              value={repo.baseUrl}
+                              type="text"
+                              className={`${
+                                repo.hasError ? "border border-danger" : ""
+                              }`}
+                              disabled={repo.isEditable === false}
+                              placeholder="Enter Base URL or remove this OS"
+                              data-testid="repo-base-url-input"
+                            ></Form.Control>
+                            {repo.baseUrl !== repo.defaultUrl ? (
+                              <FontAwesomeIcon
+                                icon={faUndo}
+                                className="text-warning ms-2 cursor-pointer"
+                                onClick={() => {
+                                  editOsOrRepo(
+                                    oSystem.os,
+                                    repo.id,
+                                    "baseUrl",
+                                    repo.defaultUrl
+                                  );
+                                }}
+                              />
+                            ) : (
+                              <div className="ms-4"></div>
+                            )}
+                          </Col>
+                        </Row>
+                      );
+                    })}
+                  </Col>
+                  <Col md={1} className="mt-2">
+                    <div
+                      className="text-danger cursor-pointer"
+                      onClick={() => {
+                        editOsOrRepo(oSystem.os, "", "isAdded", false);
+                      }}
+                    >
+                      <FontAwesomeIcon
+                        icon={faMinus}
+                        className="me-2 cursor-pointer"
+                      />
+                      Remove
+                    </div>
+                  </Col>
+                </Row>
+              );
+            })}
+        </div>
+        <div className="repo-configs">
+          <Form>
+            <Form.Check
+              checked={skipValidation}
+              type="checkbox"
+              id="skipValidation"
+              data-testid="skipValidationCheckbox"
+              onChange={() => {
+                setSkipValidation(!skipValidation);
+              }}
+              label={
+                <div style={{ marginTop: 2 }}>
+                  Skip Repository Base URL validation (Advanced)
+                  <OverlayTrigger
+                    placement="right"
+                    delay={{ show: 250, hide: 400 }}
+                    overlay={
+                      <Tooltip>
+                        Warning! This is for advanced users only. Use this
+                        optionif you want to skip validation for Repository 
Base
+                        URLs.
+                      </Tooltip>
+                    }
+                  >
+                    <FontAwesomeIcon className="ms-2" icon={faQuestionCircle} 
/>
+                  </OverlayTrigger>
+                </div>
+              }
+            ></Form.Check>
+          </Form>
+          <Form.Check
+            type="checkbox"
+            checked={redhatSatellite}
+            id="disableLocal"
+            data-testid="redhatSatelliteCheckbox"
+            onChange={() => {
+              setRedhatSatellite(!redhatSatellite);
+            }}
+            label={
+              <div style={{ marginTop: 2 }}>
+                Use RedHat Satellite/Spacewalk
+                <OverlayTrigger
+                  placement="right"
+                  delay={{ show: 250, hide: 400 }}
+                  overlay={
+                    <Tooltip>
+                      Disable distributed repositories and use RedHat
+                      Satellite/Spacewalk channels instead
+                    </Tooltip>
+                  }
+                >
+                  <FontAwesomeIcon className="ms-2" icon={faQuestionCircle} />
+                </OverlayTrigger>
+              </div>
+            }
+          ></Form.Check>
+        </div>
+      </Row>
+      <div className="d-flex justify-content-end mt-2 me-2">
+        <Link to="/stackVersions">
+          <DefaultButton>CANCEL</DefaultButton>
+        </Link>
+        <Button
+          variant="success"
+          size="sm"
+          className="ms-2"
+          onClick={validateRepos}
+          disabled={
+            !isAllOsValidated() || !versionNumber || versionValidationError
+          }
+        >
+          SAVE
+        </Button>
+      </div>
+    </>
+  );
+};
+
+export default Register;
\ No newline at end of file
diff --git 
a/ambari-admin/src/main/resources/ui/ambari-admin/src/tests/StackVersions/Register.test.tsx
 
b/ambari-admin/src/main/resources/ui/ambari-admin/src/tests/StackVersions/Register.test.tsx
new file mode 100644
index 0000000000..1f81084412
--- /dev/null
+++ 
b/ambari-admin/src/main/resources/ui/ambari-admin/src/tests/StackVersions/Register.test.tsx
@@ -0,0 +1,398 @@
+/**
+ * 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.
+ */
+import { describe, it, beforeEach, expect } from "vitest";
+import { render, waitFor, screen, fireEvent } from "@testing-library/react";
+import { createMemoryHistory } from "history";
+import { Router } from "react-router-dom";
+import "@testing-library/jest-dom/vitest";
+import VersionsApi from "../../api/versions";
+import mockVersionDefinitions from "../../__mocks__/mockVersionDefinitions";
+import mockRepoDetails from "../../__mocks__/mockRepoDetails";
+import AppContent from "../../context/AppContext";
+import Register from "../../screens/StackVersions/Register";
+import mockOperatingSystems from "../../__mocks__/mockOperatingSystems";
+
+describe("Register Component", () => {
+  const mockClusterName = "testCluster";
+  const mockContext = {
+    cluster: { cluster_name: mockClusterName },
+    setSelectedOption: () => "Versions",
+  };
+
+  beforeEach(async () => {
+    VersionsApi.getVersionOperatingSystems = async () => mockOperatingSystems;
+    VersionsApi.getVersionDefinitions = async () => mockVersionDefinitions;
+    VersionsApi.getRepoDetails = async () => mockRepoDetails;
+  });
+
+
+  it("renders without crashing", () => {
+    render(
+      <AppContent.Provider value={mockContext}>
+        <Router history={createMemoryHistory()}>
+          <Register readOnly={false} />
+        </Router>
+      </AppContent.Provider>
+    );
+  });
+
+  it("Check for all Version Definitions to be present on screen", async () => {
+    render(
+      <AppContent.Provider value={mockContext}>
+        <Router history={createMemoryHistory()}>
+          <Register readOnly={false} />
+        </Router>
+      </AppContent.Provider>
+    );
+    await waitFor(() => screen.getAllByTestId("version-definition"));
+    const versionDefinitions = screen.getAllByTestId("version-definition");
+    
expect(versionDefinitions.length).toBe(mockVersionDefinitions.items.length);
+  });
+
+  it("Check for Stack Services Table to be present on the screen", async () => 
{
+    render(
+      <AppContent.Provider value={mockContext}>
+        <Router history={createMemoryHistory()}>
+          <Register readOnly={false} />
+        </Router>
+      </AppContent.Provider>
+    );
+    await waitFor(() => screen.getByTestId("stack-services"));
+    const stackVersionTable = screen.getByTestId("stack-services");
+    expect(stackVersionTable).toBeInTheDocument();
+  });
+
+  it("Check for Operating Systems to be present on the screen", async () => {
+    render(
+      <AppContent.Provider value={mockContext}>
+        <Router history={createMemoryHistory()}>
+          <Register readOnly={false} />
+        </Router>
+      </AppContent.Provider>
+    );
+    await waitFor(() => screen.getAllByTestId("operating-systems"));
+    const allOs = screen.getAllByTestId("operating-systems");
+    expect(allOs.length).toBe(mockOperatingSystems.operating_systems.length);
+  });
+
+
+  it("renders operating systems with repositories", async () => {
+    render(
+      <AppContent.Provider value={mockContext}>
+        <Router history={createMemoryHistory()}>
+          <Register readOnly={false} />
+        </Router>
+      </AppContent.Provider>
+    );
+    await waitFor(() => screen.getAllByTestId("operating-systems"));
+    const operatingSystems = screen.getAllByTestId("operating-systems");
+    
expect(operatingSystems.length).toBe(mockOperatingSystems.operating_systems.length);
+
+    mockOperatingSystems.operating_systems.forEach((os, index) => {
+      const osElement = operatingSystems[index];
+      const expectedOsName = `${os.OperatingSystems.os_type} 
${os.repositories.map(repo=>{
+        return `${repo.Repositories.repo_id}`
+      }).join(" ")}Remove`;
+
+      expect(osElement).toHaveTextContent(expectedOsName);
+    });
+  });
+
+  it('should add an operating system when the dropdown option is clicked', 
async () => {
+      render(
+          <AppContent.Provider value={mockContext}>
+          <Router history={createMemoryHistory()}>
+              <Register readOnly={false} />
+          </Router>
+          </AppContent.Provider>
+      );
+      await waitFor(() => expect(screen.getByRole('button', { name: /Add/i 
})).toBeInTheDocument());
+      const dropdownButton = screen.getByRole('button', { name: /Add/i });
+      fireEvent.click(dropdownButton);
+
+      const addableOs = screen.getByText('amazonlinux2');
+      fireEvent.click(addableOs);
+
+      expect(screen.getByText('amazonlinux2')).toBeInTheDocument();
+  })
+
+  it("should only show the operating systems to be added when remove was 
clicked", async () => {
+    render(
+        <AppContent.Provider value={mockContext}>
+          <Router history={createMemoryHistory()}>
+            <Register readOnly={false} />
+          </Router>
+        </AppContent.Provider>
+    );
+    await waitFor(() => expect(screen.getByRole('button', { name: /Add/i 
})).toBeInTheDocument());
+    //const osRow = 
screen.getByTestId('operating-systems').querySelector('div:contains("amazonlinux2")');
+    const osRow = screen.getByText('amazonlinux2').closest('.border-bottom');
+    if (!osRow) {
+      throw new Error("osRow should not be null");
+    }
+    const removeButton = osRow.querySelector('div.text-danger.cursor-pointer');
+    if (!removeButton) {
+      throw new Error("removeButton should not be null");
+    }
+    fireEvent.click(removeButton);
+    await waitFor(() => 
expect(screen.queryByText('amazonlinux2')).not.toBeInTheDocument());
+
+    const addButton = screen.getByRole('button', { name: /Add/i });
+    fireEvent.click(addButton);
+
+    const addableOs = screen.getByText('amazonlinux2');
+    fireEvent.click(addableOs);
+
+    // Verify the operating system is added back
+    await waitFor(() => 
expect(screen.getByText('amazonlinux2')).toBeInTheDocument());
+  })
+
+  it('should  render modal on clicking why is this disabled', async () => {
+    render(
+        <AppContent.Provider value={mockContext}>
+          <Router history={createMemoryHistory()}>
+            <Register readOnly={false} />
+          </Router>
+        </AppContent.Provider>
+    );
+    await waitFor(() => screen.getAllByTestId("operating-systems"));
+    const info =  screen.getByText(/Why is this/i);
+    fireEvent.click(info);
+    expect(screen.getByText('Public Repository Option 
Disabled')).toBeInTheDocument();
+  });
+
+  //it should render Use Local repository
+  it('should render Use Local Repository when the checkbox is clicked', async 
() => {
+      render(
+          <AppContent.Provider value={mockContext}>
+          <Router history={createMemoryHistory()}>
+              <Register readOnly={false} />
+          </Router>
+          </AppContent.Provider>
+      );
+
+      await waitFor( () => expect(screen.getByText(/Use Local 
Repository/i)).toBeInTheDocument());
+  });
+  //initially skip validation should be unchecked
+  it('should render Skip Validation as unchecked by default', async () => {
+      render(
+          <AppContent.Provider value={mockContext}>
+          <Router history={createMemoryHistory()}>
+              <Register readOnly={false} />
+          </Router>
+          </AppContent.Provider>
+      );
+    await waitFor(() => screen.getByTestId('skipValidationCheckbox'));
+    await waitFor(() => 
expect(screen.getByTestId('skipValidationCheckbox')).not.toBeChecked());
+  });
+
+  it('should render Use RedHat Satellite/Spacewalk as unchecked by default', 
async () => {
+    render(
+        <AppContent.Provider value={mockContext}>
+          <Router history={createMemoryHistory()}>
+            <Register readOnly={false} />
+          </Router>
+        </AppContent.Provider>
+    );
+    await waitFor(() => screen.getByTestId('redhatSatelliteCheckbox'));
+    await waitFor(() => 
expect(screen.getByTestId('redhatSatelliteCheckbox')).not.toBeChecked());
+  });
+
+  it('should check and uncheck the Skip Validation checkbox', async () => {
+    render(
+        <AppContent.Provider value={mockContext}>
+          <Router history={createMemoryHistory()}>
+            <Register readOnly={false} />
+          </Router>
+        </AppContent.Provider>
+    );
+    const skipValidationCheckbox = await waitFor(() => 
screen.getByTestId('skipValidationCheckbox'));
+    // Initial state should be unchecked
+    expect(skipValidationCheckbox).not.toBeChecked();
+
+    // Click the checkbox to toggle its state
+    fireEvent.click(skipValidationCheckbox);
+
+    // Verify the checkbox is now checked
+    expect(skipValidationCheckbox).toBeChecked();
+  })
+
+  it('should check and uncheck the RedHat Satellite/Spacewalk checkbox', async 
() => {
+    render(
+        <AppContent.Provider value={mockContext}>
+          <Router history={createMemoryHistory()}>
+            <Register readOnly={false} />
+          </Router>
+        </AppContent.Provider>
+    );
+    const redhatSatteliteCheckBox = await waitFor(() => 
screen.getByTestId('redhatSatelliteCheckbox'));
+    // Initial state should be unchecked
+    expect(redhatSatteliteCheckBox).not.toBeChecked();
+
+    // Click the checkbox to toggle its state
+    fireEvent.click(redhatSatteliteCheckBox);
+
+    // Verify the checkbox is now checked
+    expect(redhatSatteliteCheckBox).toBeChecked();
+  })
+
+  it('should render the modal when the checkbox is clicked', async () => {
+      render(
+          <AppContent.Provider value={mockContext}>
+            <Router history={createMemoryHistory()}>
+              <Register readOnly={false} />
+            </Router>
+          </AppContent.Provider>
+      );
+
+      const redhatSatteliteCheckBox = await waitFor(() => 
screen.getByTestId('redhatSatelliteCheckbox'));
+      fireEvent.click(redhatSatteliteCheckBox);
+      await waitFor(() => expect(screen.getByText(/In order for 
Ambari/i)).toBeInTheDocument());
+  })
+
+  //TODO: Add test for the Add Version Modal
+  //the test should render the Add Version Modal when Add Version option is 
clicked
+  // it('should render the AddVersionModal when Add Version option is 
clicked', async () => {
+  //   render(
+  //       <AppContent.Provider value={mockContext}>
+  //         <Router history={createMemoryHistory()}>
+  //           <Register readOnly={false} />
+  //         </Router>
+  //       </AppContent.Provider>
+  //   );
+  //   await waitFor(() => screen.getByTestId('version-dropdown'));
+  //   fireEvent.click(screen.getByTestId('version-dropdown'));
+  //
+  //
+  //   await waitFor(() => screen.getByTestId('add-version-option'));
+  //   // Click the "Add Version" option
+  //   fireEvent.click(screen.getByTestId('add-version-option'));
+  //
+  //
+  //   // await waitFor(() => {
+  //   //   expect(screen.getByText('Upload Version 
Definition')).toBeInTheDocument();
+  //   // });
+  // });
+
+  it('should show pencil icon when redhat satellite is checked', async () => {
+    render(
+        <AppContent.Provider value={mockContext}>
+          <Router history={createMemoryHistory()}>
+            <Register readOnly={false} />
+          </Router>
+        </AppContent.Provider>
+    );
+    const redhatSatteliteCheckBox = await waitFor(() => 
screen.getByTestId('redhatSatelliteCheckbox'));
+    expect(redhatSatteliteCheckBox).toBeInTheDocument();
+    fireEvent.click(redhatSatteliteCheckBox);
+
+    const pencilIcons = await waitFor(() => 
screen.getAllByTestId('pencil-icon'));
+
+    expect(pencilIcons.length).toBeGreaterThan(0); // Check that there is at 
least one pencil icon
+    pencilIcons.forEach(icon => {
+      expect(icon).toBeInTheDocument(); // Verify each pencil icon is in the 
document
+    });
+
+  });
+
+  it('should render the cancel button', async () => {
+      render(
+          <AppContent.Provider value={mockContext}>
+          <Router history={createMemoryHistory()}>
+              <Register readOnly={false} />
+          </Router>
+          </AppContent.Provider>
+      );
+
+      await waitFor(() => expect(screen.getByRole('button', { name: /Cancel/i 
})).toBeInTheDocument());
+  });
+
+  it('should render repo-base-url-input when there is no base url', async () 
=> {
+    render(
+        <AppContent.Provider value={mockContext}>
+          <Router history={createMemoryHistory()}>
+            <Register readOnly={false} />
+          </Router>
+        </AppContent.Provider>
+    );
+
+    const baseUrlInputs = await waitFor(() => 
screen.getAllByTestId('repo-base-url-input'));
+    expect(baseUrlInputs.length).toBeGreaterThan(0); // Check that there is at 
least one pencil icon
+    baseUrlInputs.forEach(icon => {
+      expect(icon).toBeInTheDocument(); // Verify each pencil icon is in the 
document
+    });
+  });
+
+  it('should click on save button when Version number is valid and also ' +
+      'display invalid when Version Number is invalid', async () => {
+      render(
+          <AppContent.Provider value={mockContext}>
+          <Router history={createMemoryHistory()}>
+              <Register readOnly={false} />
+          </Router>
+          </AppContent.Provider>
+      );
+
+      const versionInput = await waitFor(() => 
screen.getByTestId('version-input'));
+      fireEvent.change(versionInput, { target: { value: '1.1.0' } });
+
+      // Check for the invalid message
+      const invalidMessage = screen.getByText(/invalid/i);
+      expect(invalidMessage).toBeInTheDocument();
+
+      // Change the input to a valid version number
+      fireEvent.change(versionInput, { target: { value: '1.0' } });
+
+      const saveButton = await waitFor(() => screen.getByRole('button', { 
name: /Save/i }));
+      fireEvent.click(saveButton);
+  });
+
+  it('should click on checkbox skip repository url validation and click on 
save', async () => {
+      render(
+          <AppContent.Provider value={mockContext}>
+          <Router history={createMemoryHistory()}>
+              <Register readOnly={false} />
+          </Router>
+          </AppContent.Provider>
+      );
+
+      const versionInput = await waitFor(() => 
screen.getByTestId('version-input'));
+      fireEvent.change(versionInput, { target: { value: '1.0' } });
+
+      const skipValidationCheckbox = await waitFor(() => 
screen.getByTestId('skipValidationCheckbox'));
+      fireEvent.click(skipValidationCheckbox);
+
+      const saveButton = await waitFor(() => screen.getByRole('button', { 
name: /Save/i }));
+      fireEvent.click(saveButton);
+  });
+
+  it('should click on version-dropdown', async () => {
+      render(
+          <AppContent.Provider value={mockContext}>
+          <Router history={createMemoryHistory()}>
+              <Register readOnly={false} />
+          </Router>
+          </AppContent.Provider>
+      );
+      const versionInput = await waitFor(() => 
screen.getByTestId('version-input'));
+      fireEvent.change(versionInput, { target: { value: '1.1' } });
+
+      const versionDropdown = await waitFor(() => 
screen.getByTestId('version-dropdown'));
+      fireEvent.click(versionDropdown);
+  });
+});
\ No newline at end of file


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to