Skip to content

Commit 3c93381

Browse files
Added ability to hide "End-to-End Attribute Flows" sections.
The "Hide Default Sync Rules" option selection now hides the OOB rules when not only the rule is not changed at all but also when only precedence number or tag is changed (due to upgrade / forest addition). The visibility control checkboxes are now enabled only after the browser loads the report completely.
1 parent a6fe670 commit 3c93381

8 files changed

Lines changed: 118 additions & 37 deletions

File tree

ChangeLog.md

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,18 @@ All notable changes to AADConnectConfigDocumenter project will be documented in
55
### Version [Unreleased]
66

77
* Support for adding report metadata to include section / concept contents.
8-
* Support for ignoring change to OOB rules if only precedence number is changed (due to upgrade / forest addition).
8+
9+
------------
10+
11+
### Version 1.18.0302.0
12+
13+
#### Changed
14+
- The "Hide Default Sync Rules" option selection now hides the OOB rules when not only the rule is not changed at all but also when only precedence number or tag is changed (due to upgrade / forest addition).
15+
- The visibility control checkboxes are now enabled only after the browser loads the report completely.
16+
17+
#### Added
18+
- Added ability to hide "End-to-End Attribute Flows" sections.
19+
920
------------
1021

1122
### Version 1.18.0131.0

src/AzureADConnectSyncDocumenter/ConnectorDocumenter.cs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1022,6 +1022,13 @@ protected void ProcessConnectorAttributeFlowsSummary()
10221022

10231023
try
10241024
{
1025+
this.ReportWriter.WriteBeginTag("div");
1026+
this.ReportWriter.WriteAttribute("class", "EndToEndFlowsSummary");
1027+
this.ReportWriter.Write(HtmlTextWriter.TagRightChar);
1028+
this.ReportToCWriter.WriteBeginTag("div");
1029+
this.ReportToCWriter.WriteAttribute("class", "EndToEndFlowsSummary");
1030+
this.ReportToCWriter.Write(HtmlTextWriter.TagRightChar);
1031+
10251032
var sectionTitle = "End-to-End Attribute Flows Summary";
10261033

10271034
Logger.Instance.WriteInfo("Processing " + sectionTitle + ".");
@@ -1063,6 +1070,9 @@ orderby objectType
10631070
}
10641071
finally
10651072
{
1073+
this.ReportWriter.WriteEndTag("div");
1074+
this.ReportToCWriter.WriteEndTag("div");
1075+
10661076
Logger.Instance.WriteMethodExit();
10671077
}
10681078
}
@@ -1411,6 +1421,12 @@ orderby outboundSyncRulePrecedence
14111421
var outboundSyncRuleGuid = (string)outboundSyncRule.Element("id");
14121422
var outboundConnectorGuid = ((string)outboundSyncRule.Element("connector") ?? string.Empty).ToUpperInvariant();
14131423
var outboundConnectorName = (string)config.XPathSelectElement(Documenter.GetConnectorXmlRootXPath(pilotConfig) + "/ma-data[translate(id, '" + Documenter.LowercaseLetters + "', '" + Documenter.UppercaseLetters + "') = '" + outboundConnectorGuid + "']/name");
1424+
if (string.IsNullOrEmpty(outboundConnectorName))
1425+
{
1426+
Logger.Instance.WriteWarning(string.Format(CultureInfo.InvariantCulture, "Unable to dereferece connector: '{0}'. The documentation of outbound flows will be skipped for this connector. PilotConfig: '{1}'.", outboundConnectorGuid, pilotConfig));
1427+
continue;
1428+
}
1429+
14141430
++outboundSyncRuleRank; // Used only for sorting, not displayed on the report
14151431

14161432
var targetAttributeMapping = outboundSyncRule.XPathSelectElement("attribute-mappings/mapping[./src/attr = '" + metaverseAttribute + "' or contains(expression, '[" + metaverseAttribute + "]')]");
@@ -1881,6 +1897,12 @@ orderby inboundSyncRulePrecedence
18811897
var inboundSyncRuleGuid = (string)inboundSyncRule.Element("id");
18821898
var inboundConnectorGuid = ((string)inboundSyncRule.Element("connector") ?? string.Empty).ToUpperInvariant();
18831899
var inboundConnectorName = (string)config.XPathSelectElement(Documenter.GetConnectorXmlRootXPath(pilotConfig) + "/ma-data[translate(id, '" + Documenter.LowercaseLetters + "', '" + Documenter.UppercaseLetters + "') = '" + inboundConnectorGuid + "']/name");
1900+
if (string.IsNullOrEmpty(inboundConnectorName))
1901+
{
1902+
Logger.Instance.WriteWarning(string.Format(CultureInfo.InvariantCulture, "Unable to dereferece connector: '{0}'. The documentation of inbound flows will be skipped for this connector. PilotConfig: '{1}'.", inboundConnectorGuid, pilotConfig));
1903+
continue;
1904+
}
1905+
18841906
++inboundSyncRuleRank; // Used only for sorting, not displayed on the report
18851907

18861908
var metaverseAttributeMapping = inboundSyncRule.XPathSelectElement("attribute-mappings/mapping[dest = '" + metaverseAttribute + "' or contains(expression, '[" + metaverseAttribute + "]')]");

src/AzureADConnectSyncDocumenter/Documenter.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1470,6 +1470,7 @@ protected void WriteDocumenterInfo()
14701470
this.ReportWriter.WriteBeginTag("input");
14711471
this.ReportWriter.WriteAttribute("type", "checkbox");
14721472
this.ReportWriter.WriteAttribute("id", "OnlyShowChanges");
1473+
this.ReportWriter.WriteAttribute("disabled", null);
14731474
this.ReportWriter.WriteAttribute("onclick", "ToggleVisibility();");
14741475
this.ReportWriter.WriteLine(HtmlTextWriter.SelfClosingTagEnd);
14751476

@@ -1491,9 +1492,21 @@ protected void WriteDocumenterInfo()
14911492
this.ReportWriter.WriteBeginTag("input");
14921493
this.ReportWriter.WriteAttribute("type", "checkbox");
14931494
this.ReportWriter.WriteAttribute("id", "HideDefaultSyncRules");
1495+
this.ReportWriter.WriteAttribute("disabled", null);
14941496
this.ReportWriter.WriteAttribute("onclick", "ToggleDefaultRuleVisibility();");
14951497
this.ReportWriter.WriteLine(HtmlTextWriter.SelfClosingTagEnd);
14961498

1499+
this.ReportWriter.WriteFullBeginTag("strong");
1500+
this.ReportWriter.Write("Hide End-to-end Summary Flows:");
1501+
this.ReportWriter.WriteEndTag("strong");
1502+
1503+
this.ReportWriter.WriteBeginTag("input");
1504+
this.ReportWriter.WriteAttribute("type", "checkbox");
1505+
this.ReportWriter.WriteAttribute("id", "HideEndToEndFlowsSummary");
1506+
this.ReportWriter.WriteAttribute("disabled", null);
1507+
this.ReportWriter.WriteAttribute("onclick", "ToggleEndToEndFlowsSummaryVisibility();");
1508+
this.ReportWriter.WriteLine(HtmlTextWriter.SelfClosingTagEnd);
1509+
14971510
this.WriteBreakTag();
14981511

14991512
this.ReportWriter.WriteFullBeginTag("strong");

src/AzureADConnectSyncDocumenter/MetaverseDocumenter.cs

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,12 @@ orderby precedence
434434
var connector = ((string)syncRule.Element("connector") ?? string.Empty).ToUpperInvariant();
435435

436436
var connectorName = (string)config.XPathSelectElement(Documenter.GetConnectorXmlRootXPath(pilotConfig) + "/ma-data[translate(id, '" + Documenter.LowercaseLetters + "', '" + Documenter.UppercaseLetters + "') = '" + connector + "']/name");
437+
if (string.IsNullOrEmpty(connectorName))
438+
{
439+
Logger.Instance.WriteWarning(string.Format(CultureInfo.InvariantCulture, "Unable to dereferece connector: '{0}'. The documentation of inbound flows will be skipped for this connector. PilotConfig: '{1}'.", connector, pilotConfig));
440+
continue;
441+
}
442+
437443
var syncRuleName = (string)syncRule.Element("name");
438444
row2[2] = connectorName;
439445
row2[3] = syncRuleName;
@@ -594,11 +600,17 @@ private void PrintMetaverseObjectType()
594600

595601
this.WriteSectionHeader(sectionTitle, 4);
596602

603+
this.ReportWriter.WriteBeginTag("div");
604+
this.ReportWriter.WriteAttribute("class", "EndToEndFlowsSummary");
605+
this.ReportWriter.Write(HtmlTextWriter.TagRightChar);
606+
597607
var headerTable = this.GetMetaverseObjectTypeHeaderTable();
598608
this.WriteTable(this.DiffgramDataSet.Tables[0], headerTable, HtmlTableSize.Huge);
599609
}
600610
finally
601611
{
612+
this.ReportWriter.WriteEndTag("div");
613+
602614
this.ResetDiffgram(); // reset the diffgram variables
603615
Logger.Instance.WriteMethodExit();
604616
}
@@ -838,14 +850,19 @@ private void FillMetaverseObjectDeletionRuleDataSet(string objectType, bool pilo
838850
var deletionRuleGuid = (string)deletionRule.Element("id");
839851
var deletionRuleLinkType = (string)deletionRule.Element("linkType");
840852
var connectorGuid = (string)deletionRule.Element("connector");
841-
var connectorName = from connectorData in config.XPathSelectElements(Documenter.GetConnectorXmlRootXPath(pilotConfig) + "/ma-data")
853+
var connectorName = (from connectorData in config.XPathSelectElements(Documenter.GetConnectorXmlRootXPath(pilotConfig) + "/ma-data")
842854
where ((string)connectorData.Element("id") ?? string.Empty).Equals(connectorGuid, StringComparison.OrdinalIgnoreCase)
843-
select (string)connectorData.Element("name");
855+
select (string)connectorData.Element("name")).FirstOrDefault();
856+
if (string.IsNullOrEmpty(connectorName))
857+
{
858+
Logger.Instance.WriteWarning(string.Format(CultureInfo.InvariantCulture, "Unable to dereferece connector: '{0}'. The documentation of deletion rules will be skipped for this connector. PilotConfig: '{1}'.", connectorGuid, pilotConfig));
859+
continue;
860+
}
844861

845862
var row2 = table2.NewRow();
846863

847864
row2[0] = objectType;
848-
row2[1] = connectorName.FirstOrDefault();
865+
row2[1] = connectorName;
849866
row2[2] = connectorGuid;
850867

851868
// Expected that this is likely to result in Contraint violation
@@ -858,7 +875,7 @@ private void FillMetaverseObjectDeletionRuleDataSet(string objectType, bool pilo
858875
var row3 = table3.NewRow();
859876

860877
row3[0] = objectType;
861-
row3[1] = connectorName.FirstOrDefault();
878+
row3[1] = connectorName;
862879
row3[2] = deletionRuleName;
863880
row3[3] = deletionRuleLinkType;
864881
row3[4] = connectorGuid;

src/AzureADConnectSyncDocumenter/Scripts/Documenter.js

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
1-
function ToggleVisibility() {
1+
window.onload = function (e) {
2+
document.getElementById("OnlyShowChanges").disabled = false;
3+
document.getElementById("HideDefaultSyncRules").disabled = false;
4+
document.getElementById("HideEndToEndFlowsSummary").disabled = false;
5+
}
6+
7+
function ToggleVisibility() {
28
var x = document.getElementById("OnlyShowChanges");
39
var elements = document.getElementsByClassName("CanHide");
410
for (var i = 0; i < elements.length; ++i) {
@@ -33,6 +39,19 @@ function ToggleDefaultRuleVisibility() {
3339
}
3440
}
3541

42+
function ToggleEndToEndFlowsSummaryVisibility() {
43+
var x = document.getElementById("HideEndToEndFlowsSummary");
44+
var elements = document.getElementsByClassName("EndToEndFlowsSummary");
45+
for (var i = 0; i < elements.length; ++i) {
46+
if (x.checked == true) {
47+
elements[i].style.display = "none";
48+
}
49+
else {
50+
elements[i].style.display = "";
51+
}
52+
}
53+
}
54+
3655
function DownloadScript(downloadLink) {
3756
var scripts = document.getElementsByClassName("PowerShellScript");
3857
var data = "";

src/AzureADConnectSyncDocumenter/StyleCop.Cache

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,7 @@
246246
<timestamps>
247247
<styleCop>2016/11/09 21:13:02.000</styleCop>
248248
<settingsFile>2017/04/16 06:55:54.094</settingsFile>
249-
<sourceFile>2018/01/31 18:50:34.544</sourceFile>
249+
<sourceFile>2018/03/02 08:48:07.208</sourceFile>
250250
<parser>2016/11/09 21:13:02.000</parser>
251251
<StyleCop.CSharp.DocumentationRules>2016/11/09 21:13:02.000</StyleCop.CSharp.DocumentationRules>
252252
<StyleCop.CSharp.DocumentationRules.FilesHashCode>-277821146</StyleCop.CSharp.DocumentationRules.FilesHashCode>
@@ -269,7 +269,7 @@
269269
<timestamps>
270270
<styleCop>2016/11/09 21:13:02.000</styleCop>
271271
<settingsFile>2017/04/16 06:55:54.094</settingsFile>
272-
<sourceFile>2018/01/31 18:52:05.258</sourceFile>
272+
<sourceFile>2018/03/02 09:55:34.888</sourceFile>
273273
<parser>2016/11/09 21:13:02.000</parser>
274274
<StyleCop.CSharp.DocumentationRules>2016/11/09 21:13:02.000</StyleCop.CSharp.DocumentationRules>
275275
<StyleCop.CSharp.DocumentationRules.FilesHashCode>-277821146</StyleCop.CSharp.DocumentationRules.FilesHashCode>
@@ -430,7 +430,7 @@
430430
<timestamps>
431431
<styleCop>2016/11/09 21:13:02.000</styleCop>
432432
<settingsFile>2017/04/16 06:55:54.094</settingsFile>
433-
<sourceFile>2018/01/31 16:43:17.242</sourceFile>
433+
<sourceFile>2018/03/02 08:52:22.581</sourceFile>
434434
<parser>2016/11/09 21:13:02.000</parser>
435435
<StyleCop.CSharp.DocumentationRules>2016/11/09 21:13:02.000</StyleCop.CSharp.DocumentationRules>
436436
<StyleCop.CSharp.DocumentationRules.FilesHashCode>-277821146</StyleCop.CSharp.DocumentationRules.FilesHashCode>
@@ -499,7 +499,7 @@
499499
<timestamps>
500500
<styleCop>2016/11/09 21:13:02.000</styleCop>
501501
<settingsFile>2017/04/16 06:55:54.094</settingsFile>
502-
<sourceFile>2018/01/31 18:43:31.852</sourceFile>
502+
<sourceFile>2018/02/04 13:41:17.230</sourceFile>
503503
<parser>2016/11/09 21:13:02.000</parser>
504504
<StyleCop.CSharp.DocumentationRules>2016/11/09 21:13:02.000</StyleCop.CSharp.DocumentationRules>
505505
<StyleCop.CSharp.DocumentationRules.FilesHashCode>-277821146</StyleCop.CSharp.DocumentationRules.FilesHashCode>
@@ -522,7 +522,7 @@
522522
<timestamps>
523523
<styleCop>2016/11/09 21:13:02.000</styleCop>
524524
<settingsFile>2017/04/16 06:55:54.094</settingsFile>
525-
<sourceFile>2018/01/31 19:27:13.692</sourceFile>
525+
<sourceFile>2018/03/02 08:36:53.915</sourceFile>
526526
<parser>2016/11/09 21:13:02.000</parser>
527527
<StyleCop.CSharp.DocumentationRules>2016/11/09 21:13:02.000</StyleCop.CSharp.DocumentationRules>
528528
<StyleCop.CSharp.DocumentationRules.FilesHashCode>-277821146</StyleCop.CSharp.DocumentationRules.FilesHashCode>

src/AzureADConnectSyncDocumenter/SyncRuleDocumenter.cs

Lines changed: 23 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,12 @@ internal class SyncRuleDocumenter : ConnectorDocumenter
5454
private SyncRuleReportType syncRuleReportType;
5555

5656
/// <summary>
57-
/// Indicates if the the synchronization rule is inferred as a default sync rule can be made invisible
57+
/// Indicates if the synchronization rule is inferred as a default sync rule
58+
/// </summary>
59+
private bool defaultSyncRule;
60+
61+
/// <summary>
62+
/// Indicates if the default synchronization rule has to be visible all the time
5863
/// </summary>
5964
private bool defaultSyncRuleVisibility;
6065

@@ -76,6 +81,7 @@ public SyncRuleDocumenter(XElement pilotXml, XElement productionXml, string sync
7681
{
7782
this.SyncRuleName = syncRuleName;
7883
this.SyncRuleGuid = syncRuleGuid;
84+
this.defaultSyncRule = false;
7985
this.defaultSyncRuleVisibility = false;
8086
this.ReportFileName = Documenter.GetTempFilePath(this.SyncRuleGuid + ".tmp.html");
8187
this.ReportToCFileName = Documenter.GetTempFilePath(this.SyncRuleGuid + ".TOC.tmp.html");
@@ -195,7 +201,19 @@ public Tuple<string, string> GetReport(SyncRuleReportType reportType)
195201
this.ProcessConnectorSyncRuleTransformations();
196202
}
197203

198-
var noHide = this.DiffgramDataSets.Any(dataSet => !(bool)dataSet.ExtendedProperties[Documenter.CanHide]);
204+
// for default rule it can be hidden if the only change is to the precedence number
205+
if (this.defaultSyncRule)
206+
{
207+
var filterExpression = "[Column2] <> 'Precedence' AND [Column2] <> 'Tag' AND [" + Documenter.OldColumnPrefix + "Column3] <> [Column3]";
208+
var defaultSyncRuleDescriptionChanged = this.DiffgramDataSets.Count > 0 && this.DiffgramDataSets[0].Tables[0].Select(filterExpression).Count() != 0;
209+
var defaultSyncRuleScopingFilterChanged = this.DiffgramDataSets.Count > 1 && !(bool)this.DiffgramDataSets[1].ExtendedProperties[Documenter.CanHide];
210+
var defaultSyncRuleJoinRulesChanged = this.DiffgramDataSets.Count > 2 && !(bool)this.DiffgramDataSets[2].ExtendedProperties[Documenter.CanHide];
211+
var defaultSyncRuleTransformationsChanged = this.DiffgramDataSets.Count > 3 && !(bool)this.DiffgramDataSets[3].ExtendedProperties[Documenter.CanHide];
212+
213+
this.defaultSyncRuleVisibility = defaultSyncRuleDescriptionChanged || defaultSyncRuleScopingFilterChanged || defaultSyncRuleJoinRulesChanged || defaultSyncRuleTransformationsChanged;
214+
}
215+
216+
var noHide = this.defaultSyncRule ? this.defaultSyncRuleVisibility != false : this.DiffgramDataSets.Any(dataSet => !(bool)dataSet.ExtendedProperties[Documenter.CanHide]);
199217

200218
if (noHide)
201219
{
@@ -236,7 +254,7 @@ public Tuple<string, string> GetReport(SyncRuleReportType reportType)
236254
}
237255
finally
238256
{
239-
if (!this.defaultSyncRuleVisibility)
257+
if (this.defaultSyncRule && this.defaultSyncRuleVisibility == false)
240258
{
241259
this.ReportWriter.WriteEndTag("div");
242260
this.ReportToCWriter.WriteEndTag("div");
@@ -279,7 +297,7 @@ private void WriteSyncRuleReportHeader()
279297
this.ReportWriter = new XhtmlTextWriter(new StreamWriter(this.ReportFileName));
280298
this.ReportToCWriter = new XhtmlTextWriter(new StreamWriter(this.ReportToCFileName));
281299

282-
if (!this.defaultSyncRuleVisibility)
300+
if (this.defaultSyncRule && this.defaultSyncRuleVisibility == false)
283301
{
284302
this.ReportWriter.WriteBeginTag("div");
285303
this.ReportWriter.WriteAttribute("class", "DefaultRuleCanHide");
@@ -390,21 +408,7 @@ private void FillConnectorSyncRuleDescriptionDataSet(bool pilotConfig)
390408
var table = dataSet.Tables[0];
391409

392410
this.syncRuleDirection = (SyncRuleDirection)Enum.Parse(typeof(SyncRuleDirection), (string)syncRule.Element("direction"), true);
393-
var defaultSyncRule = ((string)syncRule.Element("immutable-tag") ?? string.Empty).StartsWith("Microsoft.", StringComparison.OrdinalIgnoreCase);
394-
395-
// Only turn the visibility on and never off.
396-
if (this.defaultSyncRuleVisibility == false)
397-
{
398-
this.defaultSyncRuleVisibility = !defaultSyncRule;
399-
}
400-
401-
// Any disabled rule will also be always visible.
402-
// Ideally we should have any unsupported customisation to default sync rule always visible
403-
// as well but for now depend on the PowerShell script to flag that
404-
if (((string)syncRule.Element("disabled") ?? string.Empty).Equals("true", StringComparison.OrdinalIgnoreCase))
405-
{
406-
this.defaultSyncRuleVisibility = true;
407-
}
411+
this.defaultSyncRule = ((string)syncRule.Element("immutable-tag") ?? string.Empty).StartsWith("Microsoft.", StringComparison.OrdinalIgnoreCase);
408412

409413
var setting = (string)syncRule.Element("name");
410414
Documenter.AddRow(table, new object[] { 0, "Name", setting });
@@ -456,11 +460,6 @@ private void FillConnectorSyncRuleDescriptionDataSet(bool pilotConfig)
456460

457461
table.AcceptChanges();
458462
}
459-
else
460-
{
461-
// The missing rule in either of the environments will make the rule always visible
462-
this.defaultSyncRuleVisibility = true;
463-
}
464463
}
465464
}
466465
finally

0 commit comments

Comments
 (0)