So i often have to gain access to a member in Umbraco, to either make updates or help with password resets etc. So i set out to make a custom dashboard that displays the members of the site in a list, with pertinent information and a link to edit the member.
To get started with creating a dashboard, it has to be registered so it will be displayed, that can be done with a package.manifest file or a class.
Since i have the option i would always chose the class.
Initializing my dashboard
[Weight(-10)]
public class MemberDashboard : IDashboard
{
public string[] Sections => new[]
{
Umbraco.Core.Constants.Applications.Members,
};
public IAccessRule[] AccessRules
{
get
{
var rules = new IAccessRule[]
{
new AccessRule {Type = AccessRuleType.Grant, Value = Umbraco.Core.Constants.Security.AdminGroupAlias},
new AccessRule {Type = AccessRuleType.Grant, Value = Umbraco.Core.Constants.Security.EditorGroupAlias}
};
return rules;
}
}
public string Alias => "MemberDashboard";
public string View => "/App_Plugins/Dashboards/MemberDashboard/dashboard.html";
}
Sections defines where to display the dashboard.
AccessRules are for defining who will have access, here i defined that only admins and editors should have access to this.
Alias is self explanatory
View, is the html file, it has to be places in App_Plugins.
Now the rest of the files should be created.
My Filestructure
Package.manifest
The resources has to be in App_Plugin to work.
{
"javascript": [
"~/App_Plugins/Dashboards/MemberDashboard/Controller/memberController.js"
],
"css": [
"~/App_Plugins/Dashboards/MemberDashboard/Styles/style.css"
]
}
As of this post, you cannot define the javascript controller, and the styling in the class, but hopefully that will be added in the future.
Angular Controller
angular.module("umbraco").controller("my.memberDashboardController", function ($scope, $http) {
var vm = this;
$http.get("/umbraco/backoffice/api/MemberDashboardApi/GetMembers")
.then(function (response) {
vm.members = response.data;
});
});
In my controller, i simple needed to display some data, so it’s a very simple and straight forward controller.
I simply call an api controller i made, which i then add to my scope.
My view
Simply displays the data, and does nothing else.
<div ng-controller="my.memberDashboardController as vm" id="memberlist-dashboard">
<!--Repeat this-->
<umb-box>
<umb-box-content>
<div>
<table>
<tr>
<th></th>
<th>Navn</th>
<th>Sidste Login</th>
<th>Låst</th>
<th>Medlems type</th>
<th>Kontingent status</th>
<th></th>
</tr>
<tr ng-repeat="member in vm.members">
<td>
<img src="{{member.ProfilePicture}}" alt="" />
</td>
<td>
<h2>{{member.FullName}}</h2>
</td>
<td>
<p>{{member.LastLogin}}</p>
</td>
<td>
<p>{{member.Locked}}</p>
</td>
<td>
<p>{{member.MemberStatus}}</p>
</td>
<td>
<p>{{member.SubscriptionStatus}}</p>
</td>
<td>
<a href="{{member.Link}}" class="btn">Gå til medlem</a>
</td>
</tr>
</table>
</div>
</umb-box-content>
</umb-box>
<!--Repeat this-->
</div>
UmbracoAuthorizedApi Controller
And lastly my controller, here i get all my members, and parse the data i need.
[IsBackOffice]
public class MemberDashboardApiController : UmbracoAuthorizedApiController
{
private readonly UmbracoHelper umbracoHelper;
private readonly MemberGetHelper memberGetHelper;
public MemberDashboardApiController(UmbracoHelper umbracoHelper, MemberGetHelper memberGetHelper)
{
this.umbracoHelper = umbracoHelper;
this.memberGetHelper = memberGetHelper;
}
// ~/umbraco/backoffice/api/{controller}/{action}
public IEnumerable<MemberModel> GetMembers()
{
var members = this.memberGetHelper.GetAllMembers();
if (members == null)
{
return null;
}
List<MemberModel> result = new List<MemberModel>();
foreach (var member in members)
{
var model = new MemberModel()
{
ProfilePicture = member.ProfileImage != null ? member.ProfileImage.Url() : string.Empty,
FullName = $"{member.FirstName} {member.LastName}",
LastLogin = member.UmbracoMemberLastLogin.StandardDateTimeFormatWithTime(),
Locked = member.UmbracoMemberLockedOut ? "Ja" : "Nej",
MemberStatus = member.MemberStatus,
SubscriptionStatus = GetSubscriptionStatus(member),
Link = $"/umbraco#/member/member/edit/{member.Id}",
};
result.Add(model);
}
return result;
}
private string GetSubscriptionStatus(Member member)
{
if (member.MemberStatus == "Prospekt")
{
return string.Empty;
}
else
{
return member.PaymentStatus;
}
}
}
End result
In the end it looks something like this, (obfuscated since i dont own the test images)
This is only a simple and very limited view of the dashboard, but it should be helpfull on getting started.
Some Resources
- blog : https://24days.in/umbraco-cms/2019/dashboards-plus-migration/dashboards-and-sections/
- Documentation: https://our.umbraco.com/documentation/extending/Dashboards/
- Guide: https://our.umbraco.com/documentation/tutorials/Creating-a-Custom-Dashboard/
- Documentation: https://our.umbraco.com/documentation/tutorials/Creating-a-Custom-Dashboard/