diff --git a/src/Umbraco.Web.UI.Client/src/common/resources/legacy.resource.js b/src/Umbraco.Web.UI.Client/src/common/resources/legacy.resource.js index db35b16c86..2083b3e21a 100644 --- a/src/Umbraco.Web.UI.Client/src/common/resources/legacy.resource.js +++ b/src/Umbraco.Web.UI.Client/src/common/resources/legacy.resource.js @@ -10,8 +10,8 @@ function legacyResource($q, $http, umbRequestHelper) { /** Loads in the data to display the section list */ deleteItem: function (args) { - if (!args.nodeId || !args.nodeType) { - throw "The args parameter is not formatted correct, it requires properties: nodeId, nodeType"; + if (!args.nodeId || !args.nodeType || !args.alias) { + throw "The args parameter is not formatted correct, it requires properties: nodeId, nodeType, alias"; } return umbRequestHelper.resourcePromise( @@ -19,7 +19,7 @@ function legacyResource($q, $http, umbRequestHelper) { umbRequestHelper.getApiUrl( "legacyApiBaseUrl", "DeleteLegacyItem", - [{ nodeId: args.nodeId }, { nodeType: args.nodeType }])), + [{ nodeId: args.nodeId }, { nodeType: args.nodeType }, { alias: args.alias }])), 'Failed to delete item ' + args.nodeId); } diff --git a/src/Umbraco.Web.UI.Client/src/views/common/dialogs/legacydelete.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/dialogs/legacydelete.controller.js index ea50b85d6d..c5bdc92526 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/dialogs/legacydelete.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/dialogs/legacydelete.controller.js @@ -15,7 +15,8 @@ function LegacyDeleteController($scope, legacyResource, treeService, navigationS legacyResource.deleteItem({ nodeId: $scope.currentNode.id, - nodeType: $scope.currentNode.nodetype + nodeType: $scope.currentNode.nodetype, + alias: $scope.currentNode.name, }).then(function () { $scope.currentNode.loading = false; //TODO: Need to sync tree, etc... diff --git a/src/Umbraco.Web.UI.Client/src/views/member/edit.html b/src/Umbraco.Web.UI.Client/src/views/member/edit.html index a5b220e62a..856304e157 100644 --- a/src/Umbraco.Web.UI.Client/src/views/member/edit.html +++ b/src/Umbraco.Web.UI.Client/src/views/member/edit.html @@ -3,7 +3,7 @@ ng-show="loaded" ng-submit="save()" val-form-manager> - +
diff --git a/src/Umbraco.Web/Editors/BackOfficeController.cs b/src/Umbraco.Web/Editors/BackOfficeController.cs index c292b4ceb6..1cae76c3c9 100644 --- a/src/Umbraco.Web/Editors/BackOfficeController.cs +++ b/src/Umbraco.Web/Editors/BackOfficeController.cs @@ -101,7 +101,7 @@ namespace Umbraco.Web.Editors }, { "legacyApiBaseUrl", Url.GetUmbracoApiServiceBaseUrl( - controller => controller.DeleteLegacyItem(null, null)) + controller => controller.DeleteLegacyItem(null, null, null)) }, { "entityApiBaseUrl", Url.GetUmbracoApiServiceBaseUrl( diff --git a/src/Umbraco.Web/Editors/LegacyController.cs b/src/Umbraco.Web/Editors/LegacyController.cs index a319425919..3c3240bd4c 100644 --- a/src/Umbraco.Web/Editors/LegacyController.cs +++ b/src/Umbraco.Web/Editors/LegacyController.cs @@ -1,4 +1,5 @@ -using System.Net; +using System; +using System.Net; using System.Net.Http; using System.Web; using System.Web.Http; @@ -40,26 +41,37 @@ namespace Umbraco.Web.Editors /// has functionality included in the ui.xml structure. /// /// - public HttpResponseMessage DeleteLegacyItem(string nodeId, string nodeType) + public HttpResponseMessage DeleteLegacyItem(string nodeId, string alias, string nodeType) { - //TODO: Detect recycle bin node ids and delete permanently! + //U4-2686 - alias is html encoded, make sure to decode + alias = HttpUtility.HtmlDecode(alias); //In order to process this request we MUST have an HttpContext available var httpContextAttempt = TryGetHttpContext(); if (httpContextAttempt.Success) { + //this is a hack check based on legacy + if (nodeType == "memberGroup") + { + LegacyDialogHandler.Delete(httpContextAttempt.Result, UmbracoUser, nodeType, 0, alias); + return Request.CreateResponse(HttpStatusCode.OK); + } + int id; if (int.TryParse(nodeId, out id)) { - LegacyDialogHandler.Delete(httpContextAttempt.Result, UmbracoUser, nodeType, id, ""); - return new HttpResponseMessage(HttpStatusCode.OK); + LegacyDialogHandler.Delete(httpContextAttempt.Result, UmbracoUser, nodeType, id, alias); + return Request.CreateResponse(HttpStatusCode.OK); } - //We must have an integer id for this to work - throw new HttpResponseException(HttpStatusCode.PreconditionFailed); - } - //We must have an HttpContext available for this to work. - throw new HttpResponseException(HttpStatusCode.PreconditionFailed); + //the way this legacy stuff used to work is that if the node id didn't parse, we would + //pass the node id as the alias with an id of zero = sure whatevs. + LegacyDialogHandler.Delete(httpContextAttempt.Result, UmbracoUser, nodeType, 0, nodeId); + return Request.CreateResponse(HttpStatusCode.OK); + } + + //We must have an HttpContext available for this to work. + return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, new InvalidOperationException("No HttpContext found in the current request")); } } diff --git a/src/Umbraco.Web/Trees/ApplicationTreeExtensions.cs b/src/Umbraco.Web/Trees/ApplicationTreeExtensions.cs index 381c92b2cd..f51fbb43d3 100644 --- a/src/Umbraco.Web/Trees/ApplicationTreeExtensions.cs +++ b/src/Umbraco.Web/Trees/ApplicationTreeExtensions.cs @@ -82,7 +82,7 @@ namespace Umbraco.Web.Trees return Attempt.Fail(xmlTreeNodeAttempt.Exception); } return Attempt.Succeed( - LegacyTreeDataConverter.ConvertFromLegacy(xmlTreeNodeAttempt.Result.NodeID, xmlTreeNodeAttempt.Result, urlHelper, currentSection, isRoot: true)); + LegacyTreeDataConverter.ConvertFromLegacy(xmlTreeNodeAttempt.Result.NodeID, xmlTreeNodeAttempt.Result, urlHelper, currentSection, formCollection, isRoot: true)); } internal static Attempt TryGetRootXmlNodeFromLegacyTree(this ApplicationTree appTree, FormDataCollection formCollection, UrlHelper urlHelper) @@ -115,7 +115,7 @@ namespace Umbraco.Web.Trees { return Attempt.Fail(xTreeAttempt.Exception); } - return Attempt.Succeed(LegacyTreeDataConverter.ConvertFromLegacy(id, xTreeAttempt.Result, urlHelper, currentSection)); + return Attempt.Succeed(LegacyTreeDataConverter.ConvertFromLegacy(id, xTreeAttempt.Result, urlHelper, currentSection, formCollection)); } internal static Attempt TryGetMenuFromLegacyTreeRootNode(this ApplicationTree appTree, FormDataCollection formCollection, UrlHelper urlHelper) diff --git a/src/Umbraco.Web/Trees/LegacyTreeDataConverter.cs b/src/Umbraco.Web/Trees/LegacyTreeDataConverter.cs index 8f37574d9e..5886dbcbd6 100644 --- a/src/Umbraco.Web/Trees/LegacyTreeDataConverter.cs +++ b/src/Umbraco.Web/Trees/LegacyTreeDataConverter.cs @@ -312,7 +312,20 @@ namespace Umbraco.Web.Trees return Attempt.Fail(); } - internal static TreeNode ConvertFromLegacy(string parentId, XmlTreeNode xmlTreeNode, UrlHelper urlHelper, string currentSection, bool isRoot = false) + /// + /// Converts a legacy XmlTreeNode to a new TreeNode + /// + /// + /// + /// + /// + /// + /// The current query strings for the request - this is used to append the query strings to the menu URL of the item being rendered since the menu + /// actually belongs to this same node (request) the query strings need to exist so the menu can be rendered in some cases. + /// + /// + /// + internal static TreeNode ConvertFromLegacy(string parentId, XmlTreeNode xmlTreeNode, UrlHelper urlHelper, string currentSection, FormDataCollection currentQueryStrings, bool isRoot = false) { // /umbraco/tree.aspx?rnd=d0d0ff11a1c347dabfaa0fc75effcc2a&id=1046&treeType=content&contextMenu=false&isDialog=false @@ -328,14 +341,28 @@ namespace Umbraco.Web.Trees //for the menu source we need to detect if this is a root node since we'll need to set the parentId and id to -1 // for which we'll handle correctly on the server side. - var menuSource = urlHelper.GetUmbracoApiService("GetMenu"); - menuSource = menuSource.AppendQueryStringToUrl(new[] + //if there are no menu items, then this will be empty + var menuSource = ""; + if (xmlTreeNode.Menu != null && xmlTreeNode.Menu.Any()) + { + menuSource = urlHelper.GetUmbracoApiService("GetMenu"); + //these are the absolute required query strings + var menuQueryStrings = new Dictionary + { + {"id", (isRoot ? "-1" : xmlTreeNode.NodeID)}, + {"treeType", xmlTreeNode.TreeType}, + {"parentId", (isRoot ? "-1" : parentId)}, + {"section", currentSection} + }; + //append the extra ones on this request + foreach (var i in currentQueryStrings.Where(x => menuQueryStrings.Keys.Contains(x.Key) == false)) { - "id=" + (isRoot ? "-1" : xmlTreeNode.NodeID), - "treeType=" + xmlTreeNode.TreeType, - "parentId=" + (isRoot ? "-1" : parentId), - "section=" + currentSection - }); + menuQueryStrings.Add(i.Key, i.Value); + } + + menuSource = menuSource.AppendQueryStringToUrl(menuQueryStrings.ToQueryString()); + } + //TODO: Might need to add stuff to additional attributes @@ -362,7 +389,7 @@ namespace Umbraco.Web.Trees return node; } - internal static TreeNodeCollection ConvertFromLegacy(string parentId, XmlTree xmlTree, UrlHelper urlHelper, string currentSection) + internal static TreeNodeCollection ConvertFromLegacy(string parentId, XmlTree xmlTree, UrlHelper urlHelper, string currentSection, FormDataCollection currentQueryStrings) { //TODO: Once we get the editor URL stuff working we'll need to figure out how to convert // that over to use the old school ui.xml stuff for these old trees and however the old menu items worked. @@ -370,7 +397,7 @@ namespace Umbraco.Web.Trees var collection = new TreeNodeCollection(); foreach (var x in xmlTree.treeCollection) { - collection.Add(ConvertFromLegacy(parentId, x, urlHelper, currentSection)); + collection.Add(ConvertFromLegacy(parentId, x, urlHelper, currentSection, currentQueryStrings)); } return collection; } diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/loadPackager.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/loadPackager.cs index 19d303cbc2..a8cfcc12c5 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/loadPackager.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/loadPackager.cs @@ -61,6 +61,18 @@ namespace umbraco set { _app = value; } } + protected override void CreateAllowedActions(ref List actions) + { + actions.Clear(); + actions.Add(umbraco.BusinessLogic.Actions.ActionRefresh.Instance); + } + + protected override void CreateRootNodeActions(ref List actions) + { + actions.Clear(); + actions.Add(umbraco.BusinessLogic.Actions.ActionRefresh.Instance); + } + /// /// Renders the Javascript. /// @@ -76,18 +88,16 @@ namespace umbraco /// /// Renders the specified tree item. /// - /// The tree. + /// The tree. public override void Render(ref XmlTree tree) - { - - + { string[,] items = { { "BrowseRepository.aspx", "Install from repository" }, { "CreatePackage.aspx", "Createdjjj Packages" }, { "installedPackages.aspx", "Installedjj packages" }, { "StarterKits.aspx", "Starter kit" }, { "installer.aspx", "Install local package" } }; for (int i = 0; i <= items.GetUpperBound(0); i++) { XmlTreeNode xNode = XmlTreeNode.Create(this); - xNode.NodeID = "-1"; + xNode.NodeID = (i + 1).ToInvariantString(); xNode.Text = items[i, 1]; xNode.Icon = "icon-folder"; xNode.OpenIcon = "icon-folder"; @@ -97,11 +107,11 @@ namespace umbraco switch (items[i, 0]) { case "installedPackages.aspx": + if (cms.businesslogic.packager.InstalledPackage.GetAllInstalledPackages().Count > 0) { xNode.Source = "tree.aspx?app=" + this._app + "&id=" + this._id + "&treeType=packagerPackages&packageType=installed" + "&rnd=" + Guid.NewGuid(); - xNode.NodeType = "installedPackages"; - xNode.Menu.Add(umbraco.BusinessLogic.Actions.ActionRefresh.Instance); + xNode.NodeType = "installedPackages"; xNode.Text = ui.Text("treeHeaders", "installedPackages"); xNode.HasChildren = true; } @@ -115,16 +125,14 @@ namespace umbraco case "BrowseRepository.aspx": //Gets all the repositories registered in umbracoSettings.config - List repos = cms.businesslogic.packager.repositories.Repository.getAll(); - - + var repos = cms.businesslogic.packager.repositories.Repository.getAll(); + //if more then one repo, then list them as child nodes under the "Install from repository" node. // the repositories will then be fetched from the loadPackages class. if (repos.Count > 1) { xNode.Source = "tree.aspx?app=" + this._app + "&id=" + this._id + "&treeType=packagerPackages&packageType=repositories" + "&rnd=" + Guid.NewGuid(); - xNode.NodeType = "packagesRepositories"; - xNode.Menu.Add(umbraco.BusinessLogic.Actions.ActionRefresh.Instance); + xNode.NodeType = "packagesRepositories"; xNode.Text = ui.Text("treeHeaders", "repositories"); xNode.HasChildren = true; } @@ -136,7 +144,6 @@ namespace umbraco xNode.Text = repos[0].Name; xNode.Source = "tree.aspx?app=" + this._app + "&id=" + this._id + "&treeType=packagerPackages&packageType=repository&repoGuid=" + repos[0].Guid + "&rnd=" + Guid.NewGuid(); xNode.NodeType = "packagesRepository"; - xNode.Menu.Add(umbraco.BusinessLogic.Actions.ActionRefresh.Instance); xNode.Action = "javascript:openPackageCategory('BrowseRepository.aspx?repoGuid=" + repos[0].Guid + "');"; xNode.Icon = "icon-server-alt"; xNode.HasChildren = true; @@ -154,19 +161,21 @@ namespace umbraco case "CreatePackage.aspx": xNode.Source = "tree.aspx?app=" + this._app + "&id=" + this._id + "&treeType=packagerPackages&packageType=created" + "&rnd=" + Guid.NewGuid(); xNode.NodeType = "createdPackages"; + xNode.Menu.Clear(); xNode.Menu.Add(umbraco.BusinessLogic.Actions.ActionNew.Instance); xNode.Menu.Add(umbraco.BusinessLogic.Actions.ActionRefresh.Instance); xNode.Text = ui.Text("treeHeaders", "createdPackages"); xNode.HasChildren = true; + break; case "installer.aspx": xNode.Source = ""; xNode.NodeType = "uploadPackage"; - //treeElement.SetAttribute("menu", ""); xNode.Icon = "icon-page-up"; xNode.Action = "javascript:openPackageCategory('" + items[i, 0] + "');"; xNode.Text = ui.Text("treeHeaders", "localPackage"); + xNode.Menu.Clear(); break; case "StarterKits.aspx": @@ -175,7 +184,7 @@ namespace umbraco xNode.Action = "javascript:openPackageCategory('" + items[i, 0] + "');"; xNode.Icon = "icon-flash"; xNode.Text = ui.Text("treeHeaders", "installStarterKit"); - + xNode.Menu.Clear(); break; default: diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/loadPackages.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/loadPackages.cs index 9fa426669b..4ae493b038 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/loadPackages.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/loadPackages.cs @@ -25,10 +25,10 @@ namespace umbraco } - private int m_id; - private string m_app; - private string m_packageType = ""; - private string m_repoGuid = ""; + private int _id; + private string _app; + private string _packageType = ""; + private string _repoGuid = ""; public override void RenderJS(ref StringBuilder Javascript) { @@ -42,12 +42,17 @@ namespace umbraco "); } + protected override void CreateAllowedActions(ref List actions) + { + actions.Clear(); + } + public override void Render(ref XmlTree tree) { - m_packageType = HttpContext.Current.Request.QueryString["packageType"]; + _packageType = HttpContext.Current.Request.QueryString["packageType"]; - switch (m_packageType) + switch (_packageType) { case "installed": Version v; @@ -66,13 +71,12 @@ namespace umbraco xNode.Icon = "icon-box"; xNode.OpenIcon = "icon-box"; xNode.NodeType = "createdPackageInstance"; - xNode.Menu = null; tree.Add(xNode); } break; case "created": - foreach (cms.businesslogic.packager.CreatedPackage p in cms.businesslogic.packager.CreatedPackage.GetAllCreatedPackages()) + foreach (CreatedPackage p in CreatedPackage.GetAllCreatedPackages()) { XmlTreeNode xNode = XmlTreeNode.Create(this); @@ -82,8 +86,7 @@ namespace umbraco xNode.Icon = "icon-box"; xNode.OpenIcon = "icon-box"; xNode.NodeType = "createdPackageInstance"; -// xNode.Menu.Add( umbraco.BusinessLogic.Actions.ActionDelete.Instance ); - + xNode.Menu.Add(umbraco.BusinessLogic.Actions.ActionDelete.Instance); tree.Add(xNode); } break; @@ -100,28 +103,16 @@ namespace umbraco xNode.OpenIcon = "icon-server-alt"; xNode.NodeType = "packagesRepo" + repo.Guid; xNode.Menu.Add( umbraco.BusinessLogic.Actions.ActionRefresh.Instance ); - xNode.Source = "tree.aspx?app=" + this.m_app + "&id=" + this.m_id + "&treeType=packagerPackages&packageType=repository&repoGuid=" + repo.Guid + "&rnd=" + Guid.NewGuid(); + xNode.Source = "tree.aspx?app=" + this._app + "&id=" + this._id + "&treeType=packagerPackages&packageType=repository&repoGuid=" + repo.Guid + "&rnd=" + Guid.NewGuid(); tree.Add(xNode); - /* - XmlElement catElement = Tree.CreateElement("tree"); - catElement.SetAttribute("text", repo.Name); - catElement.SetAttribute("menu", "L"); - - catElement.SetAttribute("icon", "icon-server-alt"); - catElement.SetAttribute("openIcon", "icon-server-alt"); - - catElement.SetAttribute("nodeType", "packagesRepo" + repo.Guid); - catElement.SetAttribute("src", "tree.aspx?app=" + this.m_app + "&id=" + this.m_id + "&treeType=packagerPackages&packageType=repository&repoGuid=" + repo.Guid + "&rnd=" + Guid.NewGuid()); - catElement.SetAttribute("action", "javascript:openPackageCategory('BrowseRepository.aspx?repoGuid=" + repo.Guid + "');"); - root.AppendChild(catElement); - * */ + } break; case "repository": - m_repoGuid = HttpContext.Current.Request.QueryString["repoGuid"]; - var currentRepo = cms.businesslogic.packager.repositories.Repository.getByGuid(m_repoGuid); + _repoGuid = HttpContext.Current.Request.QueryString["repoGuid"]; + var currentRepo = cms.businesslogic.packager.repositories.Repository.getByGuid(_repoGuid); if (currentRepo != null) { @@ -145,121 +136,4 @@ namespace umbraco } - public class _loadPackages : ITree - { - - private int m_id; - private string m_app; - private string m_packageType = ""; - private string m_repoGuid = ""; - - int ITree.id - { - set { m_id = value; } - } - - string ITree.app - { - set { m_app = value; } - } - - - void ITree.Render(ref XmlDocument Tree) - { - m_packageType = HttpContext.Current.Request.QueryString["packageType"]; - XmlNode root = Tree.DocumentElement; - - switch (m_packageType) - { - case "installed": - foreach (cms.businesslogic.packager.InstalledPackage p in cms.businesslogic.packager.InstalledPackage.GetAllInstalledPackages()) - { - XmlElement treeElement = Tree.CreateElement("tree"); - treeElement.SetAttribute("nodeID", "package_" + p.Data.Id.ToString()); - treeElement.SetAttribute("text", p.Data.Name); - treeElement.SetAttribute("action", "javascript:openInstalledPackage('" + p.Data.Id.ToString() + "');"); - treeElement.SetAttribute("menu", ""); - //treeElement.SetAttribute("src", ""); - treeElement.SetAttribute("icon", "icon-box"); - treeElement.SetAttribute("openIcon", "icon-box"); - treeElement.SetAttribute("nodeType", "createdPackageInstance"); - root.AppendChild(treeElement); - } - break; - - case "created": - foreach (cms.businesslogic.packager.CreatedPackage p in cms.businesslogic.packager.CreatedPackage.GetAllCreatedPackages()) - { - XmlElement treeElement = Tree.CreateElement("tree"); - treeElement.SetAttribute("nodeID", "package_" + p.Data.Id.ToString()); - treeElement.SetAttribute("text", p.Data.Name); - treeElement.SetAttribute("action", "javascript:openCreatedPackage('" + p.Data.Id.ToString() + "');"); - treeElement.SetAttribute("menu", "D"); - treeElement.SetAttribute("src", ""); - treeElement.SetAttribute("icon", "icon-box"); - treeElement.SetAttribute("openIcon", "icon-box"); - treeElement.SetAttribute("nodeType", "createdPackageInstance"); - root.AppendChild(treeElement); - } - break; - - case "repositories": - List repos = cms.businesslogic.packager.repositories.Repository.getAll(); - - foreach (cms.businesslogic.packager.repositories.Repository repo in repos) - { - XmlElement catElement = Tree.CreateElement("tree"); - catElement.SetAttribute("text", repo.Name); - catElement.SetAttribute("menu", "L"); - - catElement.SetAttribute("icon", "icon-server-alt"); - catElement.SetAttribute("openIcon", "icon-server-alt"); - - catElement.SetAttribute("nodeType", "packagesRepo" + repo.Guid); - catElement.SetAttribute("src", "tree.aspx?app=" + this.m_app + "&id=" + this.m_id + "&treeType=packagerPackages&packageType=repository&repoGuid=" + repo.Guid + "&rnd=" + Guid.NewGuid()); - catElement.SetAttribute("action", "javascript:openPackageCategory('BrowseRepository.aspx?repoGuid=" + repo.Guid + "');"); - root.AppendChild(catElement); - } - - break; - case "repository": - - m_repoGuid = HttpContext.Current.Request.QueryString["repoGuid"]; - var currentRepo = cms.businesslogic.packager.repositories.Repository.getByGuid(m_repoGuid); - if (currentRepo != null) - { - - foreach (cms.businesslogic.packager.repositories.Category cat in currentRepo.Webservice.Categories(currentRepo.Guid)) - { - XmlElement catElement = Tree.CreateElement("tree"); - catElement.SetAttribute("text", cat.Text); - //catElement.SetAttribute("menu", ""); - catElement.SetAttribute("icon", "icon-folder"); - catElement.SetAttribute("openIcon", "icon-folder"); - catElement.SetAttribute("nodeType", "packagesCategory" + cat.Id); - catElement.SetAttribute("action", "javascript:openPackageCategory('BrowseRepository.aspx?category=" + cat.Id + "&repoGuid=" + currentRepo.Guid + "');"); - root.AppendChild(catElement); - } - } - break; - } - - //SD: Commented this out... not sure why it was here?? - //throw new Exception("The method or operation is not implemented."); - } - - public void RenderJS(ref System.Text.StringBuilder Javascript) - { - Javascript.Append(@" - function openCreatedPackage(id) { - UmbClientMgr.contentFrame('developer/packages/editPackage.aspx?id=' + id); - } - function openInstalledPackage(id) { - UmbClientMgr.contentFrame('developer/packages/installedPackage.aspx?id=' + id); - } - "); - } - - } - }