diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/umbgroupsbuilder.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/umbgroupsbuilder.directive.js index 07d4ed5177..b412a8309f 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/umbgroupsbuilder.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/umbgroupsbuilder.directive.js @@ -7,8 +7,8 @@ function link(scope, element) { - const TYPE_GROUP = 0; - const TYPE_TAB = 1; + const TYPE_GROUP = contentTypeHelper.TYPE_GROUP; + const TYPE_TAB = contentTypeHelper.TYPE_TAB; var eventBindings = []; var validationTranslated = ""; @@ -164,7 +164,11 @@ const group = groupKey ? scope.model.groups.find(group => group.key === groupKey) : {}; if (group) { - scope.convertGroupToTab(group); + contentTypeHelper.convertGroupToTab(scope.model.groups, group); + + scope.tabs.push(group); + scope.$broadcast('umbOverflowChecker.checkOverflow'); + scope.$broadcast('umbOverflowChecker.scrollTo', { position: 'end' }); } } }; @@ -185,7 +189,7 @@ const newAlias = contentTypeHelper.updateParentAlias(group.alias || null, hoveredTabAlias); // Check alias is unique - if (group.alias !== newAlias && isAliasUnique(newAlias) === false) { + if (group.alias !== newAlias && contentTypeHelper.isAliasUnique(scope.model.groups, newAlias) === false) { // TODO: Missing UI indication of why you cant move here. return; } @@ -596,18 +600,6 @@ } }; - function isAliasUnique(alias) { - return scope.model.groups.find(group => group.alias === alias) ? false : true; - } - - function createUniqueAlias(alias) { - let i = 1; - while(isAliasUnique(alias + i.toString()) === false) { - i++; - } - return alias + i.toString(); - } - /** Universal method for updating group alias (for tabs, field-sets etc.) */ function updateGroupAlias(group) { const localAlias = contentTypeHelper.generateLocalAlias(group.name), @@ -615,8 +607,8 @@ let newAlias = contentTypeHelper.updateLocalAlias(oldAlias, localAlias); // Ensure unique alias, otherwise we would be transforming groups of other parents, we do not want this. - if(isAliasUnique(newAlias) === false) { - newAlias = createUniqueAlias(newAlias); + if(contentTypeHelper.isAliasUnique(scope.model.groups, newAlias) === false) { + newAlias = contentTypeHelper.createUniqueAlias(scope.model.groups, newAlias); } group.alias = newAlias; @@ -784,20 +776,6 @@ scope.model.groups = [...otherGroups, ...sortedGroups]; }; - scope.convertGroupToTab = function (group) { - if (!group) { - return; - } - - group.type = TYPE_TAB; - const newAlias = contentTypeHelper.generateLocalAlias(group.name); - group.alias = createUniqueAlias(newAlias); - group.parentAlias = null; - scope.tabs.push(group); - scope.$broadcast('umbOverflowChecker.checkOverflow'); - scope.$broadcast('umbOverflowChecker.scrollTo', { position: 'end' }); - } - /* ---------- PROPERTIES ---------- */ scope.addPropertyToActiveGroup = () => { let activeGroup = scope.model.groups.find(group => group.tabState === "active"); diff --git a/src/Umbraco.Web.UI.Client/src/common/services/contenttypehelper.service.js b/src/Umbraco.Web.UI.Client/src/common/services/contenttypehelper.service.js index 5e76d5911a..e8c67e0f6e 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/contenttypehelper.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/contenttypehelper.service.js @@ -7,6 +7,21 @@ function contentTypeHelper(contentTypeResource, dataTypeResource, $filter, $inje var contentTypeHelperService = { + TYPE_GROUP: 0, + TYPE_TAB: 1, + + isAliasUnique(groups, alias) { + return groups.find(group => group.alias === alias) ? false : true; + }, + + createUniqueAlias(groups, alias) { + let i = 1; + while(this.isAliasUnique(groups, alias + i.toString()) === false) { + i++; + } + return alias + i.toString(); + }, + generateLocalAlias: function(name) { return name ? name.toUmbracoAlias() : String.CreateGuid(); }, @@ -74,6 +89,21 @@ function contentTypeHelper(contentTypeResource, dataTypeResource, $filter, $inje }); }, + convertGroupToTab: function (groups, group) { + group.convertingToTab = true; + + group.type = this.TYPE_TAB; + + const newAlias = this.generateLocalAlias(group.name); + // when checking for alias uniqueness we need to exclude the current group or the alias would get a + 1 + const otherGroups = [...groups].filter(groupCopy => !groupCopy.convertingToTab); + + group.alias = this.isAliasUnique(otherGroups, newAlias) ? newAlias : this.createUniqueAlias(otherGroups, newAlias); + group.parentAlias = null; + + group.convertingToTab = false; + }, + createIdArray: function (array) { var newArray = []; diff --git a/src/Umbraco.Web.UI.Client/test/unit/common/services/content-type-helper.spec.js b/src/Umbraco.Web.UI.Client/test/unit/common/services/content-type-helper.spec.js index faf1cd61c7..5add5a4129 100644 --- a/src/Umbraco.Web.UI.Client/test/unit/common/services/content-type-helper.spec.js +++ b/src/Umbraco.Web.UI.Client/test/unit/common/services/content-type-helper.spec.js @@ -16,6 +16,48 @@ describe('contentTypeHelper tests', function () { q = $injector.get('$q'); })); + describe('Group type', function () { + it('should return the group type', function () { + var groupType = contentTypeHelper.TYPE_GROUP; + expect(groupType).toBe(0); + }); + }); + + describe('Tab type', function () { + it('should return the tab type', function () { + var tabType = contentTypeHelper.TYPE_TAB; + expect(tabType).toBe(1); + }); + }); + + describe('isAliasUnique', function () { + const groups = [{ alias: 'alias' }]; + + it('should return true when alias is unique', function () { + var isUnique = contentTypeHelper.isAliasUnique(groups, 'uniqueAlias'); + expect(isUnique).toBe(true); + }); + + it('should return false when alias is not unique', function () { + var isUnique = contentTypeHelper.isAliasUnique(groups, 'alias'); + expect(isUnique).toBe(false); + }); + }); + + describe('createUniqueAlias', function () { + + it('should generate a unique alias', function () { + const groups = [{ alias: 'alias' }, { alias: 'otherAlias' }, { alias: 'otherAlias1' }]; + + var alias = contentTypeHelper.createUniqueAlias(groups, 'alias'); + expect(alias).toBe('alias1'); + + alias = contentTypeHelper.createUniqueAlias(groups, 'otherAlias'); + expect(alias).toBe('otherAlias2'); + }); + + }); + describe('generateLocalAlias', function () { it('should generate an alias when given a name', function () { @@ -129,4 +171,24 @@ describe('contentTypeHelper tests', function () { }); + describe('convertGroupToTab', function () { + + const groups = [ + { type: 0, alias: 'hero', name: 'Hero' }, + { type: 0, alias: 'content' }, + { type: 0, alias: 'footer' } + ]; + + it('should convert group to tab', function () { + const newTab = groups[0]; + + contentTypeHelper.convertGroupToTab(groups, newTab); + + expect(newTab.type).toBe(contentTypeHelper.TYPE_TAB); + expect(newTab.alias).toBe('hero'); + expect(newTab.parentAlias).toBeNull(); + }); + + }); + });