Service Portal - widget with sp_ng_template templates cannot be cloned easily


Description

The header menu widget cannot be cloned because it references a directive that lives in the file system that has hard-coded template names. Also, sp_ng_template records are not copied.

Steps to Reproduce

1) Widgets > Header Menu
2) Clone Widget > Creates "Copy of Header Menu"
3) Navigate to Menus > Instances with Menu
4) Find the one with Title "SP Config Menu"
5) On this menu, change the widget to "Copy of Header Menu"
6) Now navigate to sp_config page.
7) Check the Developers console and you will see multiple errors. Other functions like right click won't work.
----> You will get same errors as seen on screenshot.
 
Looked into the Header Menu Widget and found this:
 <li ng-repeat="item in data.menu.items" ng-class="{dropdown: item.items.length > 0}" ng-include="'menuTemplate'"></li>
------> it is using the "menuTemplate"
 
The cloned widget also has this piece of code. However, the templates did not get cloned over. So I believe it kept looking for this template and thus resulted in all those error messages and broken form. 
 
Actual Behavior: The sp_config page breaks if there is a custom header.
Expected Behavior: The sp_config page does not break while using custom header.

Workaround

The only known practical workaround is to:

 

1 - copy the existing sp_ng_template record(s) for the original widget,

2 - make the new records reference your cloned widget,

3- give the new sp_ng_template records a different, unique ID (e.g., "menuTemplateCustom1" for a copy of "menuTemplate"), and replace the hard-coded original template ID in your cloned widget with that new ID (e.g., replace ng-include="menuTemplate" with ng-template="menuTemplateCustom1").

4 - create a new Angular Provider record for spDropdownTreeTemplate and associate it with the header widget (in Angular-Providers related list)

Name:

spDropdownTreeTemplateCustom

 

Script:

function () {
	return {
		restrict: 'E',
		scope: {items: '='},
		replace: true,
		template: '<ul class="dropdown-menu">' +
		'<li ng-repeat="mi in items" style="min-width: 20em;" ng-class="{\'dropdown-submenu\': mi.type == \'menu\', \'dropdown-menu-line\':$index < items.length - 1}" ng-include="getURL()">' +
		'</ul>',
		link : function(scope, element, attrs, controller) {
			scope.getURL = function() {
				return 'spDropdownTreeTemplateCustom';
			}
		}
	}
};

 


Related Problem: PRB688317