Skip to content

Commit dfe87c0

Browse files
committed
Refactor directory field UI for template-based logic
Centralize field visibility/editability checks in DatabaseHelpers. Refactor Organization, ContactInfo, and Profile sections to use new logic. Simplify NewTemplateUser and ConfirmNewUser UI with section components. Add support and localization for Telephone Number field. Update imports and bump project version.
1 parent 4beacaf commit dfe87c0

File tree

11 files changed

+354
-659
lines changed

11 files changed

+354
-659
lines changed

BLAZAM/BLAZAM.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<ImplicitUsings>enable</ImplicitUsings>
77
<ServerGarbageCollection>false</ServerGarbageCollection>
88
<AssemblyVersion>1.5.1</AssemblyVersion>
9-
<Version>2026.02.16.0354</Version>
9+
<Version>2026.02.25.0040</Version>
1010
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
1111
<RootNamespace>BLAZAM</RootNamespace>
1212
<GenerateDocumentationFile>True</GenerateDocumentationFile>

BLAZAMDatabase/Helpers/DatabaseHelpers.cs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,28 @@ namespace BLAZAM.Helpers
1515
{
1616
public static class DatabaseHelpers
1717
{
18+
/// <summary>
19+
/// Checks if the given field is in the template, whether editable or not
20+
/// </summary>
21+
/// <param name="field"></param>
22+
/// <returns></returns>
23+
public static bool InTemplate(this DirectoryTemplate? template, IActiveDirectoryField field)
24+
{
25+
if (template == null)
26+
{
27+
return false;
28+
}
29+
return template.EffectiveFieldValues.Any(f => (f.Field != null && f.Field.FieldName == field.FieldName) || (f.CustomField != null && f.CustomField.FieldName == field.FieldName));
30+
31+
}
32+
33+
public static bool IsEditableField (this DirectoryTemplate template, IActiveDirectoryField field)
34+
{
35+
if (field is ActiveDirectoryField)
36+
return template.EffectiveFieldValues.Any(f => f.Field.FieldName == field.FieldName && f.Editable);
37+
else
38+
return template.EffectiveFieldValues.Any(f => f.CustomField.FieldName == field.FieldName && f.Editable);
39+
}
1840
public static long GetMembersHash(this IEnumerable<AppUser> members)
1941
{
2042
long hash = 0;

BLAZAMDatabase/Models/ActiveDirectoryFields.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,9 @@ public static class ActiveDirectoryFields
152152
FieldType = ActiveDirectoryFieldType.RawData, // SID is binary data,
153153
PropertyName = "SID"
154154
};
155-
155+
/// <summary>
156+
/// Email Address
157+
/// </summary>
156158
public static readonly ActiveDirectoryField Mail = new()
157159
{
158160
Id = 17,
@@ -225,7 +227,9 @@ public static class ActiveDirectoryFields
225227
FieldType = ActiveDirectoryFieldType.Text,
226228
PropertyName = "UserPrincipalName"
227229
};
228-
230+
/// <summary>
231+
/// Telephone Number (Not Home Phone)
232+
/// </summary>
229233
public static readonly ActiveDirectoryField TelephoneNumber = new()
230234
{
231235
Id = 25,

BLAZAMGui/UI/DirectoryModelComponentElement.cs

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,10 @@ public abstract class DirectoryModelComponentElement : AppComponentBase
66
public IDirectoryEntryAdapter Entry { get; set; }
77
[CascadingParameter]
88
public bool EditMode { get; set; }
9-
9+
[CascadingParameter]
10+
public DirectoryTemplate? Template { get; set; }
11+
[Parameter]
12+
public bool Disabled{ get; set; }
1013
protected string SectionMudStackClasses => "flex-wrap gap-1";
1114

1215
public IAccountDirectoryAdapter Account
@@ -36,5 +39,32 @@ public IGroupableDirectoryAdapter GroupableEntry
3639
{
3740
get => Entry as IGroupableDirectoryAdapter; set => Entry = value;
3841
}
42+
protected bool ShowField(IActiveDirectoryField field)
43+
{
44+
if (Template == null)
45+
{
46+
return GroupableEntry.CanReadField(field);
47+
}
48+
else
49+
{
50+
return Template.InTemplate(field);
51+
}
52+
}
53+
54+
protected bool DisableField(IActiveDirectoryField field)
55+
{
56+
if(Disabled)
57+
{
58+
return true;
59+
}
60+
if (Template == null)
61+
{
62+
return !EditMode || !GroupableEntry.CanEditField(field);
63+
}
64+
else
65+
{
66+
return !IsAdmin && !Template.IsEditableField(field);
67+
}
68+
}
3969
}
4070
}

BLAZAMGui/UI/Users/ConfirmNewUser.razor

Lines changed: 47 additions & 158 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,16 @@
1414

1515

1616
<MudTextField Label="@AppLocalization[Lang.OU]"
17-
Value="@Contact.OU.ToPrettyOu()"
18-
Disabled=true />
17+
Value="@Contact.OU.ToPrettyOu()"
18+
Disabled=true />
1919

2020
<MudTextField Label="@AppLocalization[Lang.First_Name]"
21-
Value="@Contact.GivenName"
22-
Disabled=true />
21+
Value="@Contact.GivenName"
22+
Disabled=true />
2323

2424
<MudTextField Label="@AppLocalization[Lang.Middle_Name]"
25-
Value="@Contact.MiddleName"
26-
Disabled=true />
25+
Value="@Contact.MiddleName"
26+
Disabled=true />
2727

2828
<MudTextField Label="@AppLocalization[Lang.Last_Name]"
2929
Value="@User.Sn"
@@ -39,163 +39,60 @@ Disabled=true />
3939

4040

4141

42-
<MudTextField Label="@AppLocalization[Lang.Password]"
43-
Value="@User.NewPassword.ToPlainText()"
44-
Disabled=true />
42+
<MudTextField Label="@AppLocalization[Lang.Password]"
43+
Value="@User.NewPassword.ToPlainText()"
44+
Disabled=true />
4545

4646
<MudTextField Label="@AppLocalization[Lang.Email_Address]"
47-
Value="@Contact.Email"
48-
Disabled=true />
47+
Value="@Contact.Email"
48+
Disabled=true />
49+
<CascadingValue Value="GroupableEntry">
50+
<CascadingValue Value="Entry">
51+
<CascadingValue Value="DirectoryTemplate">
52+
<OrganizationSection Disabled=true />
53+
54+
<ContactInfoSection Disabled=true />
55+
56+
57+
<ProfileSection Disabled=true />
58+
4959

5060

51-
@if (InDirectoryTemplate(ActiveDirectoryFields.EmployeeId) ||
52-
InDirectoryTemplate(ActiveDirectoryFields.Department) ||
53-
InDirectoryTemplate(ActiveDirectoryFields.Company) ||
54-
InDirectoryTemplate(ActiveDirectoryFields.Title) ||
55-
InDirectoryTemplate(ActiveDirectoryFields.PhysicalDeliveryOffice)
56-
)
57-
{
58-
<ViewSection Title=@AppLocalization[Lang.Organization]>
59-
@if (InDirectoryTemplate(ActiveDirectoryFields.EmployeeId))
60-
{
61-
<MudTextField Label="@AppLocalization[Lang.Employee_Id]"
62-
@bind-Value="@Contact.EmployeeId"
63-
Disabled=true />
64-
}
65-
@if (InDirectoryTemplate(ActiveDirectoryFields.Department))
66-
{
67-
<MudTextField Label="@AppLocalization[Lang.Department]"
68-
@bind-Value="@Contact.Department"
69-
Disabled=true />
70-
}
71-
@if (InDirectoryTemplate(ActiveDirectoryFields.Company))
72-
{
73-
<MudTextField Label="@AppLocalization[Lang.Company]"
74-
@bind-Value="@Contact.Company"
75-
Disabled=true />
76-
}
77-
@if (InDirectoryTemplate(ActiveDirectoryFields.Title))
78-
{
79-
<MudTextField Label="@AppLocalization[Lang.Job_Title]"
80-
@bind-Value="@Contact.Title"
81-
Disabled=true />
82-
}
83-
@if (InDirectoryTemplate(ActiveDirectoryFields.PhysicalDeliveryOffice))
84-
{
85-
<MudTextField Label="@AppLocalization[Lang.Office]"
86-
@bind-Value="@Contact.PhysicalDeliveryOfficeName"
87-
Disabled=true />
88-
}
89-
</ViewSection>
90-
}
9161

92-
@if (InDirectoryTemplate(ActiveDirectoryFields.HomePhone) ||
93-
InDirectoryTemplate(ActiveDirectoryFields.StreetAddress) ||
94-
InDirectoryTemplate(ActiveDirectoryFields.POBox) ||
95-
InDirectoryTemplate(ActiveDirectoryFields.City) ||
96-
InDirectoryTemplate(ActiveDirectoryFields.State) ||
97-
InDirectoryTemplate(ActiveDirectoryFields.PostalCode)
98-
)
99-
{
100-
<ViewSection Title=@AppLocalization[Lang.Contact_Info]>
10162

102-
@if (InDirectoryTemplate(ActiveDirectoryFields.HomePhone))
103-
{
104-
<MudTextField Label="@AppLocalization[Lang.Home_Phone]"
105-
@bind-Value="@Contact.HomePhone"
106-
Disabled=true />
107-
}
108-
@if (InDirectoryTemplate(ActiveDirectoryFields.StreetAddress))
109-
{
110-
<MudTextField Label="@AppLocalization[Lang.Street_Address]"
111-
@bind-Value="@Contact.StreetAddress"
112-
Disabled=true />
113-
}
114-
@if (InDirectoryTemplate(ActiveDirectoryFields.POBox))
115-
{
116-
<MudTextField Label="@AppLocalization[Lang.PO_Box]"
117-
@bind-Value="@Contact.POBox"
118-
Disabled=true />
119-
}
120-
@if (InDirectoryTemplate(ActiveDirectoryFields.City))
121-
{
122-
<MudTextField Label="@AppLocalization[Lang.City]"
123-
@bind-Value="@Contact.City"
124-
Disabled=true />
125-
}
126-
@if (InDirectoryTemplate(ActiveDirectoryFields.State))
127-
{
128-
<MudTextField Label="@AppLocalization[Lang.State]"
129-
@bind-Value="@Contact.State"
130-
Disabled=true />
131-
}
132-
@if (InDirectoryTemplate(ActiveDirectoryFields.PostalCode))
133-
{
134-
<MudTextField Label="@AppLocalization[Lang.Zip_Code]"
135-
@bind-Value="@Contact.Zip"
136-
Disabled=true />
137-
}
138-
</ViewSection>
139-
}
140-
@if (InDirectoryTemplate(ActiveDirectoryFields.Description))
141-
{
142-
<MudTextField Label="@AppLocalization[Lang.Description]"
143-
@bind-Value="@Contact.Description"
144-
Disabled=true />
145-
}
146-
@if (InDirectoryTemplate(ActiveDirectoryFields.Site))
147-
{
148-
<MudTextField Label="@AppLocalization[Lang.Site]"
149-
@bind-Value="@Contact.Site"
150-
Disabled=true />
151-
}
152-
@if (User != null)
153-
{
154-
<ViewSection Title=@AppLocalization[Lang.Profile]>
155-
@if (InDirectoryTemplate(ActiveDirectoryFields.HomeDirectory))
156-
{
157-
<MudTextField Label="@AppLocalization[Lang.Home_Directory]"
158-
Value="@User.HomeDirectory"
159-
Disabled=true />
160-
}
161-
@if (InDirectoryTemplate(ActiveDirectoryFields.HomeDrive))
162-
{
163-
<HomeDriveSelect Label="@AppLocalization[Lang.Home_Drive]"
164-
DriveLetter="@User.HomeDrive"
165-
Disabled=true />
166-
}
167-
@if (InDirectoryTemplate(ActiveDirectoryFields.ScriptPath))
168-
{
169-
<MudTextField Label="@AppLocalization[Lang.Script_Path]"
170-
Value="@User.ScriptPath"
171-
Disabled=true />
172-
}
173-
@if (InDirectoryTemplate(ActiveDirectoryFields.ProfilePath))
174-
{
175-
<MudTextField Label="@AppLocalization[Lang.Profile_Path]"
176-
Value="@User.ProfilePath"
177-
Disabled=true />
178-
}
179-
</ViewSection>
180-
}
18163

18264

18365

66+
<ViewSection Title=@AppLocalization[Lang.Groups]>
67+
@if (User.IsAGroupMember)
68+
{
69+
<MudText Class="mud-width-full" Align="Align.Center">
70+
<MemberOfList AllowNavigation="false" Model="@User" Disabled=true />
71+
</MudText>
18472

73+
}
18574

75+
</ViewSection>
76+
@if (GroupableEntry.CanReadAnyCustomFields && CustomFields != null && CustomFields.Count > 0)
77+
{
78+
<ViewSection Title=@AppLocalization[Lang.Additional_Fields]>
18679

80+
@foreach (var field in CustomFields)
81+
{
82+
@if (DirectoryTemplate.InTemplate(field))
83+
{
84+
<CustomDirectoryField Disabled=@(true) Entry="GroupableEntry" Field="@field" />
18785

188-
<ViewSection Title=@AppLocalization[Lang.Groups]>
189-
@if (User.IsAGroupMember)
190-
{
191-
<MudText Class="mud-width-full" Align="Align.Center">
192-
<MemberOfList AllowNavigation="false" Model="@User" Disabled=true />
193-
</MudText>
19486

195-
}
87+
}
88+
}
19689

197-
</ViewSection>
19890

91+
</ViewSection>
92+
}
93+
</CascadingValue>
94+
</CascadingValue>
95+
</CascadingValue>
19996
@if (!Confirmed)
20097
{
20198
<MudButton Disabled=@disableCreateUserButton
@@ -227,16 +124,8 @@ else
227124
AppModal? SendWelcomeModal;
228125
[Parameter]
229126
public EventCallback<IADUser> OnConfirmed { get; set; }
230-
/// <summary>
231-
/// Checks if the given field is in the template, whether editable or not
232-
/// </summary>
233-
/// <param name="field"></param>
234-
/// <returns></returns>
235-
bool InDirectoryTemplate(ActiveDirectoryField field)
236-
{
237-
if (DirectoryTemplate == null) return true;
238-
return DirectoryTemplate?.EffectiveFieldValues.Any(f => f.Field?.FieldName == field.FieldName) == true;
239-
}
127+
128+
240129
[Parameter]
241130
public bool Confirmed { get; set; }
242131
bool disableCreateUserButton = false;
@@ -341,5 +230,5 @@ else
341230
await JSRuntime.InvokeVoidAsync("printPage", null);
342231
}
343232

344-
233+
345234
}

0 commit comments

Comments
 (0)