PermaLink Adding an Extensible User Admin UI to Meteor.js05/03/2013
Surprisingly, there was no UI for managing users in Meteor.js, so I wrote a package named "accounts-admin-ui" for it.  This describes some of the design details that didn't belong on that package's description page.

The goal of this package was to display all the common user info that people care about and let admins find users easily. Basic functionality includes being able to delete a user and edit common information like the username/email/roles. In addition, it had to be customizable by users without changing the package.

One big issue with the current Meteor accounts system is that not all the information is stored in the same place for all the different methods of logging in. If you're using the standard accounts-password MongoDB-based method, your username is stored in profile.name and your email is stored in emails[0].address. If you're using one of the OAuth login methods, those fields are not filled in and instead, your login information is instead stored in the "services" array, but some OAuth methods store your username in services.name and others store it in service.username (I've only tested Twitter, Facebook and Google so far). That's the main reason why the adminusers.html template has sections for each OAuth type I've used; otherwise, it'd just be a simple loop through all the services.

Because of the username/email location issue, when the user information is initially displayed, it will try to display accounts-password info first. If you edit an OAuth user, the username/email info will be stored in the accounts-password fields since those are looked at first. If you're using these values in your application, you can use the functions displayName() and contactEmail() (from the user-helpers.js file in the package's common subdirectory) to get the user's name/email; these functions will try the accounts-password fields and then the services fields to find the user's username/email from all the disparate locations.

For security reasons, I used Meteor methods to make sure any updates/deletes were only done on the server instead of using the collection allow/deny technique. For something as important as user information, I thought a bit of extra paranoia wouldn't be a bad thing :-) In addition, the adminUsers collection isn't published if you don't have the user-admin role. There was also one minor quirk w/ the adminUsers collection: the currently logged in user always shows up because it's needed by the Meteor core code, so I hide this user if the user types anything into the search bar.

To keep this as extensible as possible so this package can be generic but usable by most people, I used Handlebar's nested templates feature. There are external (must be in the user's application) templates for displaying extra property columns in the user list, for displaying extra fields in the user info dialog, and for editing fields in the edit user dialog. There are also callbacks that can be added if you want to save the extra fields, prevent a save, delete related data during a user delete, or prevent the deletion of a user.

In packaging this up, I found out that it was critical to use this in your package.js if your package includes any Handlebars template .html files:
api.use('templating', 'client');
Without this, it would not be able to parse the templates in the package.

And another caveat I ran into while packaging this up is that when you add event handlers, you should qualify the selector with a container:
  'click .adminusers .icon-edit': function(event, template) {
    var id = getUIDFromEvent(event);
    if (id) {
      openEditUserDialog(id);
    }
  }
E.g., I didn't add the "adminusers" class to my container. All templates including their DOMs are loaded into the browser at the same time, so without the .adminusers qualifier, this would have added the function call to *all* buttons with the "icon-edit" class. What this means is that when you click on the edit button of one object, all objects with that button in your app would have opened up their edit dialogs :-P

Hope this is helpful in case anyone decides to improve this package...

Comments :v

1. Max Savin09/29/2017 11:54:44
Homepage: http://maxsavin.com


I just wanted to mention Meteor has come a long way with the new dynamic imports feature. There is now a drop-in admin panel that has virtually zero cost on the client:

{ Link }




Start Pages
RSS News Feed RSS Comments Feed CoComment Integrated
The BlogRoll
Calendar
June 2024
Su
Mo
Tu
We
Th
Fr
Sa
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
Search
Contact Me
About Ken
Full-stack developer (consultant) working with .Net, Java, Android, Javascript (jQuery, Meteor.js, AngularJS), Lotus Domino