diff --git a/electron/app/locales/en/webui.json b/electron/app/locales/en/webui.json
index 0fde7d43a..37c2b3a39 100644
--- a/electron/app/locales/en/webui.json
+++ b/electron/app/locales/en/webui.json
@@ -667,6 +667,7 @@
"ingress-design-ingress-docker-reg-secret-userpwd-help": "The password used to log in to Docker Hub.",
"ingress-design-ingress-docker-reg-secret-useremail": "Docker Hub Email Address",
"ingress-design-ingress-docker-reg-secret-useremail-help": "The email address of the user logging in to Docker Hub.",
+ "ingress-design-route-get-services-title": "Getting services for namespace {{namespace}}",
"ingress-design-ingress-routes-title": "Ingress Routes Configuration",
"ingress-design-ingress-route-virtualhost-label": "Virtual Host",
@@ -674,7 +675,11 @@
"ingress-design-ingress-route-targetservicenamespace-help": "The target service namespace value points to the namespace where the domain is running.",
"ingress-design-ingress-route-accesspoint-label": "Access Point",
"ingress-design-ingress-route-targetservice-label": "Target Service",
+ "ingress-design-ingress-route-targetservice-placeholder": "Select Domain Service",
+ "ingress-design-ingress-route-targetservice-placeholder-empty": "No Domain Services Available",
"ingress-design-ingress-route-targetport-label": "Target Port",
+ "ingress-design-ingress-route-targetport-placeholder": "Select Target Service Port",
+ "ingress-design-ingress-route-targetport-placeholder-empty": "No Target Service Selected",
"ingress-design-ingress-route-path-label": "Path Expression",
"ingress-design-ingress-route-tls-label": "Transport Options",
"ingress-design-ingress-route-tls-help": "Select the transport option for this ingress route",
diff --git a/webui/src/js/viewModels/ingress-design-view-impl.js b/webui/src/js/viewModels/ingress-design-view-impl.js
index 570be273c..a11bf91db 100644
--- a/webui/src/js/viewModels/ingress-design-view-impl.js
+++ b/webui/src/js/viewModels/ingress-design-view-impl.js
@@ -209,12 +209,11 @@ function(i18n, accUtils, ko, ArrayDataProvider, BufferingDataProvider, project,
window.api.ipc.invoke('show-error-message', title, message);
};
- async function getTargetServiceDetails (project) {
-
+ async function getTargetServiceDetails(myProject) {
const kubectlExe = k8sHelper.getKubectlExe();
const kubectlOptions = k8sHelper.getKubectlOptions();
const results = await window.api.ipc.invoke('k8s-get-service-details',
- kubectlExe, project.k8sDomain.kubernetesNamespace.value, '', kubectlOptions);
+ kubectlExe, myProject.k8sDomain.kubernetesNamespace.value, '', kubectlOptions);
let serviceLists = {};
if (results.isSuccess) {
for (const item of results.serviceDetails.items) {
@@ -230,37 +229,37 @@ function(i18n, accUtils, ko, ArrayDataProvider, BufferingDataProvider, project,
return Promise.resolve(false);
}
return Promise.resolve( { serviceList: serviceLists});
- };
+ }
this.handleEditRoute = async (event, context) => {
// using context.item.data directly was causing problems
// when project data was reloaded with matching UIDs.
const index = context.item.index;
let route = this.routes.observable()[index];
- getTargetServiceDetails(this.project).then( svc => {
- const options = {route: route, serviceList: svc.serviceList};
- dialogHelper.promptDialog('route-edit-dialog', options)
- .then(result => {
-
- // no result indicates operation was cancelled
- if (result) {
- let changed = false;
- project.ingress.ingressRouteKeys.forEach(key => {
- if ((key !== 'uid') && result.hasOwnProperty(key)) {
- route[key] = result[key];
- changed = true;
- }
- });
-
- if (changed) {
- this.routes.observable.replace(route, route);
+
+ dialogHelper.openBusyDialog(this.labelMapper('route-get-services-title',
+ { namespace: this.project.k8sDomain.kubernetesNamespace.value }));
+ const targetServiceDetails = await getTargetServiceDetails(this.project);
+ dialogHelper.closeBusyDialog();
+ if (targetServiceDetails) {
+ const options = {route: route, serviceList: targetServiceDetails.serviceList};
+ dialogHelper.promptDialog('route-edit-dialog', options).then(result => {
+ // no result indicates operation was cancelled
+ if (result) {
+ let changed = false;
+ project.ingress.ingressRouteKeys.forEach(key => {
+ if ((key !== 'uid') && result.hasOwnProperty(key)) {
+ route[key] = result[key];
+ changed = true;
}
+ });
+
+ if (changed) {
+ this.routes.observable.replace(route, route);
}
- });
+ }
+ });
}
- );
-
-
};
this.handleCancel = () => {
diff --git a/webui/src/js/viewModels/route-edit-dialog.js b/webui/src/js/viewModels/route-edit-dialog.js
index 1fdd2847f..50c99f22f 100644
--- a/webui/src/js/viewModels/route-edit-dialog.js
+++ b/webui/src/js/viewModels/route-edit-dialog.js
@@ -6,21 +6,26 @@
'use strict';
define(['accUtils', 'knockout', 'utils/i18n', 'models/wkt-project', 'utils/view-helper', 'ojs/ojarraydataprovider',
- 'ojs/ojbufferingdataprovider', 'utils/observable-properties', 'ojs/ojconverter-number', 'ojs/ojinputtext',
- 'ojs/ojlabel', 'ojs/ojbutton', 'ojs/ojdialog', 'ojs/ojformlayout', 'ojs/ojvalidationgroup', 'ojs/ojselectcombobox'],
-function(accUtils, ko, i18n, project, viewHelper, ArrayDataProvider, BufferingDataProvider, props, ojConverterNumber) {
+ 'ojs/ojbufferingdataprovider', 'utils/observable-properties', 'ojs/ojconverter-number', 'utils/wkt-logger',
+ 'ojs/ojinputtext', 'ojs/ojlabel', 'ojs/ojbutton', 'ojs/ojdialog', 'ojs/ojformlayout', 'ojs/ojvalidationgroup',
+ 'ojs/ojselectcombobox'],
+function(accUtils, ko, i18n, project, viewHelper, ArrayDataProvider, BufferingDataProvider, props,
+ ojConverterNumber) {
function RouteEditDialogModel(args) {
const DIALOG_SELECTOR = '#routeEditDialog';
- const DEFAULT_ROUTE_PORT = 0;
+ const DEFAULT_ROUTE_PORT = undefined;
// SIMPLE_PROPERTIES - names matching simple route fields
let EXCLUDE_PROPERTIES = ['uid', 'annotations'];
let SIMPLE_PROPERTIES = project.ingress.ingressRouteKeys.filter(key => !EXCLUDE_PROPERTIES.includes(key));
+ this.project = project;
+ this.route = args.route;
+ this.serviceList = args.serviceList;
+
this.connected = () => {
accUtils.announce('Route edit dialog loaded.', 'assertive');
-
// open the dialog after the current thread, which is loading this view model.
// using oj-dialog initial-visibility="show" causes vertical centering issues.
setTimeout(function() {
@@ -36,13 +41,9 @@ function(accUtils, ko, i18n, project, viewHelper, ArrayDataProvider, BufferingDa
return i18n.t(labelId, arg);
};
- this.project = project;
- this.route = args.route;
- this.serviceList = args.serviceList;
-
this.buildTargetSvcNames = () => {
let options = [];
- for(var name in this.serviceList){
+ for (const name in this.serviceList) {
options.push( { id : name, value: name, text: name});
}
return options;
@@ -52,7 +53,7 @@ function(accUtils, ko, i18n, project, viewHelper, ArrayDataProvider, BufferingDa
let options = [];
if (this.serviceList[svcName]) {
for (const port of this.serviceList[svcName].ports) {
- options.push( { id : port.port, value: port.port, text: port.port});
+ options.push( { id : port.port, value: port.port, text: port.port} );
}
}
@@ -64,7 +65,7 @@ function(accUtils, ko, i18n, project, viewHelper, ArrayDataProvider, BufferingDa
this.targetSvcPorts = ko.observableArray([] );
if (this.route.targetService) {
- this.targetSvcPorts = this.buildTargetSvcPorts(this.route.targetService);
+ this.buildTargetSvcPorts(this.route.targetService).forEach(port => this.targetSvcPorts.push(port));
}
this.savedAnnotations = args.route.annotations || {};
@@ -144,6 +145,24 @@ function(accUtils, ko, i18n, project, viewHelper, ArrayDataProvider, BufferingDa
this[propertyName] = props.createProperty(defaultValue);
});
+ this.getTargetServicePlaceholder = ko.computed(() => {
+ if (Array.isArray(this.targetSvcNames) && this.targetSvcNames.length > 0) {
+ return this.labelMapper('route-targetservice-placeholder');
+ } else {
+ return this.labelMapper('route-targetservice-placeholder-empty');
+ }
+ });
+
+ this.getTargetPortPlaceholder = ko.computed(() => {
+ console.log('targetSvcPorts is a ' + typeof(this.targetSvcPorts));
+ const ports = this.targetSvcPorts();
+ if (Array.isArray(ports) && ports.length > 0) {
+ return this.labelMapper('route-targetport-placeholder');
+ } else {
+ return this.labelMapper('route-targetport-placeholder-empty');
+ }
+ });
+
this.handleAddAnnotation = () => {
const nextIndex = this.nextAnnotationIndex();
const annotation = {uid: getAnnotationUid(nextIndex), key: `annotation-${nextIndex}`};
@@ -186,10 +205,7 @@ function(accUtils, ko, i18n, project, viewHelper, ArrayDataProvider, BufferingDa
this.targetSvcNameChanged = (event) => {
this.targetSvcPorts.removeAll();
- const list = this.buildTargetSvcPorts(event.detail.value);
- for (const item of list) {
- this.targetSvcPorts.push(item);
- }
+ this.buildTargetSvcPorts(event.detail.value).forEach(port => this.targetSvcPorts.push(port));
};
this.okInput = () => {
diff --git a/webui/src/js/views/route-edit-dialog.html b/webui/src/js/views/route-edit-dialog.html
index 98dd8ad17..3d4f05afd 100644
--- a/webui/src/js/views/route-edit-dialog.html
+++ b/webui/src/js/views/route-edit-dialog.html
@@ -36,6 +36,7 @@
+ options="[[targetServicePorts]]">