Link to home
Create AccountLog in
Avatar of AliciaVee
AliciaVee

asked on

@IsMember @UserRoles - Update Reader Field

Experts,
Users will create a document.  Users are included in "one" of 4 roles in ACL (East, West, North, South).  Documents created by users should always be read (not edited) by user (only Admin can edit docs) and a user belongs to one role, so all members of that role can also "read" (not edit) docs from each region.

What is the best way to populate (say, on compose) the DocAuthor field to make sure it captures the author, the role that author is in, and also the Admin role?  I'm thinking on query close (the button will be a submit button -- the documents will be weekly activity reports) and its important that the author username be captured just in case the user changes regions (roles).  Can anyone provide a simple solution?
Avatar of Bill-Hanson
Bill-Hanson
Flag of United States of America image

I use a Computed, multi-valued Authors field with the following formula:

authors := @Trim(@Unique(
      DefaultAuthors :
      AdditionalAuthors :
      AuthorRoles
));
authors

Where...
(1) DefaultAuthors is another field that contains my "back-door" entries such as "LocalDomainServers"
(2) AdditionalAuthors is another field that is normally empty, but can be used later to extend access to a document.
(3) AuthorRoles is another field that contains the names of the roles that can edit the document.

For the AuthorRoles field (computed when composed), I would put this formula:

regionRoles := "[North]":"[South]":"[East]":"[West]";
userRole := @Trim(@Replace(regionRoles; @Trim(@Replace(regionRoles; @UserRoles; "")); ""));
"[Admin]" : userRole;


Of course, you don't have to split the code into so many fields, but I find that maintaining applications designed like this much easier than putting it all in one field.
Avatar of AliciaVee
AliciaVee

ASKER

Bill -- okay, I think I follow you.  So, I will need to use this solution -- but apply it to "readers" fields, and not author fields -- correct?

I would put the following into a DocReaders field, computed when composed, mutl-value -- correct?

regionRoles := "[North]":"[South]":"[East]":"[West]";
userRole := @Trim(@Replace(regionRoles; @Trim(@Replace(regionRoles; @UserRoles; "")); ""));
"[Admin]" : userRole;

I'm not sure I understand the first part of your solution -- authors: and default -- so in this case you would have 3 other fields that have values and these values populate your authors field?  For readers, how can I use this to populate the author of the document.  Can I just add another reader field, say DefaultReader and list the author of the document (if they move from one region to another, I want them to still be able to read their own documents) and can I also add the Admin role as well as the domainservers -- what exactly is the syntax for this?  I'm not that great with roles and author /reader fields and I know it can be tricky if not done right.
Oh -- one more question.  What does @Trim do in your authors field (I know @Unique will not allow dupes...but are you trmming out excess space and does that happen with usernames and/or roles?)
First, I'll address the question about @Trim.  I'll respond to the other part in my next post.

Yes, @Trim simply removes empty elements from any list.  It can also trim a string by removing leading and trailing whitespace, but we are using it to trim lists of roles.

In this case, we have a list of known roles (regionRoles), and a list of roles that is not known until runtime (@UserRoles).  What we need to know is which one of the regionRoles is present in UserRoles.  To do this we need to perform a logical AND operation on the two lists.  Unfortunately, @Formula language does not include such an operation (the & operator will raise an error if you try to use it with lists).  So we have to do the logic manually.  Since "R AND U" can be converted to "!R OR !U", we can use @Replace to invert the lists and combine them (R=The Known Region Roles and U=The User's Roles).  I'll break down the formula above to make this more clear:


regionRoles := "[North]":"[South]":"[East]":"[West]";

This line is self explanatory; it's just a list of our known region roles.


invertedRegions:= @Trim(@Replace(regionRoles; @UserRoles; ""));

I broke this code out of the longest line in the example above to make the logic clearer.  It removes any of the user's roles from the known regionRoles.  So if the user is a member of these roles ("[Admin]":"[South]":"[EditHelp]"), then invertedRegions will now contain ("[North]":"[East]":"[West]").  The call to @Trim removes the "holes" left by the @Replace operation.


userRole := @Trim(@Replace(regionRoles; invertedRegions ; ""));

Now, all we need to do is to remove this list from the known region roles, and we'll have the role(s) common to both lists.  Again, the call to @Trim removes the "holes" left by the @Replace operation.


"[Admin]" : userRole;

This final line just adds the "[Admin]" role to the list.


One this to note is that if the user is (for some reason) a member of more than one region role, the result will contain all matching role names.
ASKER CERTIFIED SOLUTION
Avatar of Bill-Hanson
Bill-Hanson
Flag of United States of America image

Link to home
membership
Create an account to see this answer
Signing up is free. No credit card required.
Create Account
Bill -- wow!  This is awesome stuff!  Very very informative and helpful for someone at my skill level.  Thanks so much for sharing your knowledge -- I will put it to good use.

Okay -- so I've got the reader feilds working perfectly!  Thanks for all of your help.  On to part two of this task -- getting the alerts to work based on documents not found, which you've also answered.