/// <summary> /// Helper method for loading the portal items /// </summary> /// <param name="bw"></param> private void LoadPortalItems(BackgroundWorker bw, bool isLegacyPortal) { portalItems = new List <EditablePortalItem>(); bw.ReportProgress(0, "Loading Web pages..."); portalItems.AddRange(WebPage.GetItems(Service)); bw.ReportProgress(0, "Loading Entity forms..."); portalItems.AddRange(EntityForm.GetItems(Service, ref isLegacyPortal)); bw.ReportProgress(0, "Loading Entity lists..."); portalItems.AddRange(EntityList.GetItems(Service, ref isLegacyPortal)); bw.ReportProgress(0, "Loading Web templates..."); portalItems.AddRange(WebTemplate.GetItems(Service, ref isLegacyPortal)); bw.ReportProgress(0, "Loading Web files..."); portalItems.AddRange(WebFile.GetItems(Service)); bw.ReportProgress(0, "Loading Web form steps..."); portalItems.AddRange(WebFormStep.GetItems(Service)); bw.ReportProgress(0, "Loading Content Snippets..."); portalItems.AddRange(ContentSnippet.GetItems(Service, ref isLegacyPortal)); if (!isLegacyPortal) { bw.ReportProgress(0, "Loading Portal languages..."); ctvf.Languages = Service.RetrieveMultiple(new QueryExpression("adx_websitelanguage") { ColumnSet = new ColumnSet(true) }).Entities.ToList(); } }
private void LoadItems() { ctv.Enabled = false; WorkAsync(new WorkAsyncInfo { Message = "Loading portal items...", Work = (bw, e) => { portalItems = new List <EditablePortalItem>(); bw.ReportProgress(0, "Loading Web pages..."); portalItems.AddRange(WebPage.GetItems(Service)); bw.ReportProgress(0, "Loading Entity forms..."); portalItems.AddRange(EntityForm.GetItems(Service, ref isLegacyPortal)); bw.ReportProgress(0, "Loading Entity lists..."); portalItems.AddRange(EntityList.GetItems(Service, ref isLegacyPortal)); bw.ReportProgress(0, "Loading Web templates..."); portalItems.AddRange(WebTemplate.GetItems(Service, ref isLegacyPortal)); bw.ReportProgress(0, "Loading Web files..."); portalItems.AddRange(WebFile.GetItems(Service)); bw.ReportProgress(0, "Loading Web form steps..."); portalItems.AddRange(WebFormStep.GetItems(Service)); bw.ReportProgress(0, "Loading Content Snippets..."); portalItems.AddRange(ContentSnippet.GetItems(Service, ref isLegacyPortal)); portalItems.SelectMany(p => p.Items).ToList().ForEach(i => i.StateChanged += CodeItem_StateChanged); }, ProgressChanged = e => { SetWorkingMessage(e.UserState.ToString()); }, PostWorkCallBack = e => { if (e.Error != null) { if (((FaultException <OrganizationServiceFault>)e.Error).Detail.ErrorCode == -2147217149) { MessageBox.Show(e.Error.ToString()); var message = "Unable to load code items: Please ensure you are targeting an organization linked to a Microsoft Portal (not a legacy Adxstudio one)"; MessageBox.Show(this, message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); LogError(message); } else { MessageBox.Show(this, $"An error occured while loading code items: {e.Error.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); LogError($"An error occured while loading code items: {e.Error.ToString()}"); } } ctv.DisplayCodeItems(portalItems, isLegacyPortal); ctv.Enabled = true; } }); }
public void DisplayCodeItems(List <EditablePortalItem> items, bool isLegacyPortal) { IsLegacyPortal = isLegacyPortal; portalItems = items; tvCodeItems.Nodes.Clear(); var rootNodes = new Dictionary <Guid, TreeNode>(); if (isLegacyPortal) { rootNodes.Add(Guid.Empty, new TreeNode("(Not website related)")); } var searchText = txtSearch.Text.ToLower(); var filteredItems = items.Where(i => searchText.Length == 0 || i.Name.ToLower().Contains(searchText) || chkSearchInContent.Checked && i.Items.Any(i2 => i2.Content.ToLower().Contains(searchText))) .ToList(); if (!filteredItems.Any() && searchText.Length > 0) { txtSearch.BackColor = Color.LightCoral; return; } foreach (var item in filteredItems) { item.UpdateRequired += Item_UpdateRequired; var websiteReference = item.WebsiteReference; if (websiteReference == null) { continue; } TreeNode parentNode; if (rootNodes.ContainsKey(websiteReference.Id)) { parentNode = rootNodes[websiteReference.Id]; } else { var name = websiteReference.Id == Guid.Empty ? "(Not website related)" : websiteReference.Name; var rootNode = new TreeNode(name); rootNodes.Add(websiteReference.Id, rootNode); parentNode = rootNode; parentNode.Nodes.Add(new TreeNode("Web Pages") { Name = "WebPage" }); if (!IsLegacyPortal) { parentNode.Nodes.Add(new TreeNode("Entity Forms") { Name = "EntityForm" }); parentNode.Nodes.Add(new TreeNode("Entity Lists") { Name = "EntityList" }); parentNode.Nodes.Add(new TreeNode("Web Forms") { Name = "WebForm" }); parentNode.Nodes.Add(new TreeNode("Web Templates") { Name = "WebTemplate" }); } parentNode.Nodes.Add(new TreeNode("Web Files") { Name = "WebFile" }); } TreeNode typeNode; if (item is WebPage) { typeNode = parentNode.Nodes["WebPage"]; WebPage page = (WebPage)item; page.JavaScript.StateChanged += JavaScript_StateChanged; page.Style.StateChanged += JavaScript_StateChanged; TreeNode node; if (page.IsRoot || page.ParentPageId == Guid.Empty) { node = new TreeNode(page.Name) { Tag = item }; typeNode.Nodes.Add(node); if (isLegacyPortal) { var scriptNode = new TreeNode("JavaScript") { Tag = page.JavaScript }; page.JavaScript.Node = scriptNode; var styleNode = new TreeNode("Style") { Tag = page.Style }; page.Style.Node = styleNode; node.Nodes.Add(scriptNode); node.Nodes.Add(styleNode); } } else { var parentPageNode = typeNode.Nodes.Cast <TreeNode>().FirstOrDefault(t => ((WebPage)t.Tag).Id == page.ParentPageId); if (parentPageNode == null) { continue; } node = new TreeNode(page.Language) { Tag = item }; var scriptNode = new TreeNode("JavaScript") { Tag = page.JavaScript }; page.JavaScript.Node = scriptNode; var styleNode = new TreeNode("Style") { Tag = page.Style }; page.Style.Node = styleNode; node.Nodes.Add(scriptNode); node.Nodes.Add(styleNode); parentPageNode.Nodes.Add(node); } } else if (item is EntityForm) { typeNode = parentNode.Nodes["EntityForm"]; if (typeNode == null) { typeNode = new TreeNode("Entity Forms") { Name = "EntityForm" }; rootNodes[item.WebsiteReference.Id].Nodes.Add(typeNode); } EntityForm form = (EntityForm)item; form.JavaScript.StateChanged += JavaScript_StateChanged; var node = new TreeNode(form.Name) { Tag = form.JavaScript }; form.JavaScript.Node = node; typeNode.Nodes.Add(node); } else if (item is EntityList) { typeNode = parentNode.Nodes["EntityList"]; if (typeNode == null) { typeNode = new TreeNode("Entity Lists") { Name = "EntityList" }; rootNodes[item.WebsiteReference.Id].Nodes.Add(typeNode); } EntityList list = (EntityList)item; list.JavaScript.StateChanged += JavaScript_StateChanged; var node = new TreeNode(list.Name) { Tag = list.JavaScript }; list.JavaScript.Node = node; typeNode.Nodes.Add(node); } else if (item is WebTemplate) { typeNode = parentNode.Nodes["WebTemplate"]; if (typeNode == null) { typeNode = new TreeNode("Web Templates") { Name = "WebTemplate" }; rootNodes[item.WebsiteReference.Id].Nodes.Add(typeNode); } WebTemplate template = (WebTemplate)item; template.Code.StateChanged += JavaScript_StateChanged; var node = new TreeNode(template.Name) { Tag = template.Code }; template.Code.Node = node; typeNode.Nodes.Add(node); } else if (item is WebFile) { typeNode = parentNode.Nodes["WebFile"]; if (typeNode == null) { typeNode = new TreeNode("Web Files") { Name = "WebFile" }; rootNodes[item.WebsiteReference.Id].Nodes.Add(typeNode); } WebFile file = (WebFile)item; file.Code.StateChanged += JavaScript_StateChanged; var node = new TreeNode(file.Name) { Tag = file.Code }; file.Code.Node = node; typeNode.Nodes.Add(node); } else if (item is WebFormStep) { typeNode = parentNode.Nodes["WebForm"]; if (typeNode == null) { typeNode = new TreeNode("Web Forms") { Name = "WebForm" }; rootNodes[item.WebsiteReference.Id].Nodes.Add(typeNode); } WebFormStep wfStep = (WebFormStep)item; wfStep.JavaScript.StateChanged += JavaScript_StateChanged; var node = new TreeNode(wfStep.Name) { Tag = wfStep.JavaScript }; wfStep.JavaScript.Node = node; if (wfStep.WebFormReference != null) { TreeNode webFormNode; if (typeNode.Nodes.ContainsKey(wfStep.WebFormReference.Name)) { webFormNode = typeNode.Nodes[wfStep.WebFormReference.Name]; } else { webFormNode = new TreeNode(wfStep.WebFormReference.Name) { Name = wfStep.WebFormReference.Name }; typeNode.Nodes.Add(webFormNode); } webFormNode.Nodes.Add(node); } else { typeNode.Nodes.Add(node); } } else { throw new Exception($"Unsupported portal item type: {item.GetType().Name}"); } } foreach (var node in rootNodes.Values) { ApplyCounting(node, "WebPage"); ApplyCounting(node, "EntityForm"); ApplyCounting(node, "EntityList"); ApplyCounting(node, "WebTemplate"); ApplyCounting(node, "WebFile"); ApplyCounting(node, "WebForm"); tvCodeItems.Nodes.Add(node); node.Expand(); } }
/// <summary> /// Export the Portal contents to individual files on disk /// </summary> /// <param name="portalItems">New list of EditablePortalItem objects</param> /// <param name="exportFolder">Target folder for the export</param> /// <param name="isLegacyPortal">Flag indicating whether this is an older version of the Portal</param> /// <param name="searchText">Text to filter the list</param> /// <param name="searchInContent">Flag indicating whether to search within the Content as well as names</param> /// <param name="clearFolder">Before export, delete all contents</param> private void Export(List <EditablePortalItem> portalItems, string exportFolder, bool isLegacyPortal, string searchText = null, bool searchInContent = true, bool clearFolder = false) { // preset the filtered list to the current list of items var filteredItems = portalItems; // if search text has been provided, search the list if (searchText != null) { // search case insensitive searchText = searchText.ToLower(); filteredItems = portalItems.Where(i => searchText.Length == 0 || (i.Name?.ToLower().Contains(searchText) ?? false) || searchInContent && i.Items.Any(i2 => i2.Content?.ToLower().Contains(searchText) ?? false)) .ToList(); } // build out the folder strucure. this will mimick the tree view structure pretty closely. // delete the folders? if (clearFolder) { DirectoryInfo di = new DirectoryInfo(exportFolder); foreach (FileInfo file in di.GetFiles()) { file.Delete(); } foreach (DirectoryInfo dir in di.GetDirectories()) { dir.Delete(true); } } // keep track of the names by type by website that have been exported so we do not overrite content // might be easier to look for file... var websiteNameList = new Dictionary <Guid, Dictionary <string, Dictionary <Guid, string> > >(); // begin the work! foreach (var item in filteredItems) { var currentPath = ""; var websiteReference = item.WebsiteReference; if (websiteReference == null) { continue; } // build current folder path starting with the website, appended to the selected folder var websiteName = websiteReference.Id == Guid.Empty ? "(Not website related)" : websiteReference.Name; websiteName = EditablePortalItem.EscapeForFileName(websiteName); currentPath = Path.Combine(exportFolder, websiteName); // add a new structure to track names for this website if (!websiteNameList.ContainsKey(websiteReference.Id)) { websiteNameList.Add(websiteReference.Id, GetWebSiteNameList()); } var nameList = websiteNameList[websiteReference.Id]; if (!Directory.Exists(currentPath)) { Directory.CreateDirectory(currentPath); Directory.CreateDirectory(Path.Combine(currentPath, WebPage.NODENAME)); if (!isLegacyPortal) { Directory.CreateDirectory(Path.Combine(currentPath, ContentSnippet.NODENAME)); Directory.CreateDirectory(Path.Combine(currentPath, EntityForm.NODENAME)); Directory.CreateDirectory(Path.Combine(currentPath, EntityList.NODENAME)); Directory.CreateDirectory(Path.Combine(currentPath, WebFormStep.NODENAME)); Directory.CreateDirectory(Path.Combine(currentPath, WebTemplate.NODENAME)); } Directory.CreateDirectory(Path.Combine(websiteName, WebFile.NODENAME)); } if (item is WebPage page) { // new web page, append to the current path currentPath = AppendToPath(currentPath, WebPage.NODENAME); if (page.IsRoot || page.ParentPageId == Guid.Empty) { var name = GetItemUniqueName(nameList[WebPage.NODENAME], page, page.PartialUrl); // new folder for web page currentPath = AppendToPath(currentPath, name); if (isLegacyPortal) { // path to JS and CSS file only page.WriteContent(currentPath); } } else { // find the parent page Id to get the name of the folder // TODO - do we want to account for the root page? var parent = portalItems .FirstOrDefault(w => (w as WebPage)?.Id == page.ParentPageId) as WebPage; if (parent == null) { continue; } var name = GetItemUniqueName(nameList[WebPage.NODENAME], parent, page.PartialUrl); // new path for website and the language currentPath = AppendToPath(currentPath, name); currentPath = AppendToPath(currentPath, page.Language); // path to JS and CSS file only page.WriteContent(currentPath); } } else if (item is EntityForm form) { var name = GetItemUniqueName(nameList[EntityForm.NODENAME], form); // new entity form, append to the current path currentPath = AppendToPath(currentPath, EntityForm.NODENAME); currentPath = AppendToPath(currentPath, name); form.WriteContent(currentPath); } else if (item is EntityList list) { var name = GetItemUniqueName(nameList[EntityList.NODENAME], list); // new entity list, append to the current path currentPath = AppendToPath(currentPath, EntityList.NODENAME); currentPath = AppendToPath(currentPath, name); list.WriteContent(currentPath); } else if (item is WebTemplate template) { var name = GetItemUniqueName(nameList[WebTemplate.NODENAME], template); // new Web Template, append to the current path currentPath = AppendToPath(currentPath, WebTemplate.NODENAME); currentPath = AppendToPath(currentPath, name); template.WriteContent(currentPath); } else if (item is WebFile file) { // var name = GetItemUniqueName(nameList[WebFile.NODENAME], file); // NOTE assume the filename is unique // new Web File, append to the current path currentPath = AppendToPath(currentPath, WebFile.NODENAME); currentPath = Path.Combine(currentPath, file.Name); file.WriteContent(currentPath); } else if (item is WebFormStep wfStep) { // NOTE assume the WF Steps are unique within the WF // new Web Form Step... first, append to web forms currentPath = AppendToPath(currentPath, WebFormStep.NODENAME); // then find the web form name for the root folder if (wfStep.WebFormReference != null) { // add the web form name to the path currentPath = AppendToPath(currentPath, WebFormStep.EscapeForFileName(wfStep.WebFormReference.Name)); } // now down to the web form step name for a folder and then the js var name = wfStep.EscapeName(); currentPath = AppendToPath(currentPath, name); wfStep.WriteContent(currentPath); } else if (item is ContentSnippet snippet) { var name = GetItemUniqueName(nameList[ContentSnippet.NODENAME], snippet); // new content snippet. put all in the same folder, appending extension currentPath = AppendToPath(currentPath, ContentSnippet.NODENAME); currentPath = AppendToPath(currentPath, name); snippet.WriteContent(currentPath); } else { throw new Exception($"Unsupported portal item type: {item.GetType().Name}"); } } }