Section 8 (Lesson 4/10): This lesson focuses on admin privacy. We’ll get started by copying some design work from the demo app to paste into our current app. Then we’ll reconnect some data and talk about ways to exclude certain search results from a search.
We’ll be covering:
Issue checker: How to use to the issue checker to resolve issues quickly.
Privacy rules: How to add admin privacy rules to all data types to make sure that admins have access to all available data.
The filtered operator: How to filter dropdown results to exclude options that we don’t want.
Resources folder: ➡ https://e6387a14ba6d0bf3e823090f8d959...
Bubble editor: ➡ https://bubble.io/page?type=page&name...
Transcript
In this lesson, we're going to head over to the demo app, copy across the Users and Jobs views, and just paste them into our app because I want to focus on privacy for this lesson, and we've built many dashboards thus far in this course. So let's jump in and I'll talk through the process!
So the link is above for the demo app. Head over to the admin page, open up the Layers for Group Container, and then let's have a look at Group Users. I'm going to click on Group Users, choose "Edit", "Copy to another app". Now I'm going to open up my current app and choose "Edit", "Paste".
Okay, so let's just make sure that we close down what we don't need. So currently I'm in Group overview. Just going to have a look at Group Account. Okay, so Group Account we don't need so I'm going to right-click and choose Delete. I'll leave Group Application for now, we'll come back to that.
Okay, so in your Elements Tree, please highlight Group Container, right-click, and paste! There are Group Users, and if we double-click in Group Users, have a look at the Conditional tab, it's currently set to navigate to users. Perfect.
Let's now connect all of our data, we can see that we have 6 issues. So I'm going to open up Group Users, open up the Group Container, open up Group Table, and let's get a view of our table element. On the Appearance tab, we are searching for Users, and we have some data here. So User Type, so we've copied this from another app, we just need to make sure that everything is how it should be. Let's have a look through some of this data.
So first of all, on the dropdown. So what we are doing is we're looking for a dynamic choice. Of course it's dynamic, we're pulling it from a User Type Option set. Okay, I just want you to clear the expression in here (the Choices source). I want to talk you through this. So what we're going to do is say "All User Type", so go and grab all of those different types of users. We currently have three. Now, I don't want to see my own account, and I'm an Admin. So what I'm going to do is I'm going to say :filtered and let's add a new constraint. Let's say we want all of the User Types but we don't want Admin. So I'm going to click to add a constraint, and the constraint will read, "This User Type is not Admin", which means that the dropdown will only show "Company" and "Candidates". I'm not going to set a default value because I'd like to see all of the Users first.
Okay, what else have we done? We are pointing to the count, and on the table, we are simply searching for Users, we have the "Any field contains," the input search. Now, we don't have the buttons here to basically do a search. We're going to leave this out for this lesson, we don't need to repeat what we've already learned. So in Search for Users, I'm just going to remove that.
What I am interested in is this Dropdown User type's value. And on the Conditional tab, I'm saying that Table job posts is only visible when the count is greater than zero. We've talked through the various options here: first item is not empty, is not zero, etc., they all do the same thing.
Okay, and let's see the type of data we have. User's avatar, we've got email address, all right, that is potentially sensitive data, and before we go any further, let's have a quick review of our issues. Okay, so we know that these issues belong on the admin page. If I click on this one here, it takes me to the issue! So this will read, "Here are your latest signups," and then Current User's first name. So it will say, "Here are your latest sign ups, Current User's Name first."
I'm going to click on the next one. Next one says that "Dynamic data in text boxes must be printable as text". Okay, click on that, and here we go, we just need to reconnect some of this data. So click on the Name text and choose Current row's User's Name first. And I'm going to click across to Company, that looks good.
Go click across to the avatar, make sure that that's connected to the Current row's User, because this is a reusable element in here. Actually, is it a reusable element? I think it might not be and maybe we should actually just delete it out of there, and then go find the Avatar reusable element, click once, drop it inside, and then connect the Data source to the Current row's User. And on the Layout tab, we choose in the center.
Going to have a look at the email address next: Current row's User's email. Signup date will stay the same, and all of our issues have now been resolved.
Now, the critical part, let's actually preview this page! Going to refresh, head over to the Users, and can you see that we currently have one result? And if I select this dropdown, let's just click "Company," we don't have any results. (All right, we obviously need to fix this little bug here where it says "You've not received any applications yet".) If I choose instead "Candidate" from the dropdown, well, we don't have any candidates either. I can only see myself. I think you know the reason for this is because this user data is private and we have not set up privacy rules for an Admin. So let's go ahead and do that!
I'm going to head over to the Data tab, please do the same. Head over to Privacy and under User, let's just first see what we have here. So we have a rule called "Company access": This User's Applied companies contains Current User's Company. So we've matched a Company within a list of Companies. And now a Company can see Users that have applied to Jobs that those Companies have posted to Workplace.
The "User's own data" rule is set up by Bubble automatically for us. This basically says a user can see their own data. Everyone else, access to nothing, just how we want it.
Let's now define a new rule. Let's call this "Admin access" and then create. Now, as an admin, I want access to everything. So I'm going to say when Current User - that's me - when Current User's User Type is Admin, then an admin can basically do everything. We are the developers, the app owners, so yes, we can get the data anyway in the database. So we're just going to choose the default: access to everything.
Okay, what about Transaction data? Well, this is definitely secure data that only us as Admins should access. Define a new rule on the Transaction data type called "Admin access". Create. When a Current User, when their User Type is Admin - and I'm going to right-click copy this expression because we need to add it to different places - then we can do everything. And let's uncheck "View all fields" in the Everyone else (default permissions) section, this financial data belongs to us as Admin access. So only we get access.
We're going to do the same for Job, Company, and Application, and then we're going to view our User table. Define a new rule called "Admin access" in the Job data type. Create, paste that in. That's all we need to do. Just going to update this to access as well. Company, create a new rule. We need access to everything. Paste it in: Current User's User Type is Admin. One more, we need to be able to see all Applications. "Admin access", create, and paste. Looking good!
Let's go back our dashboard and see if we can view the User data, because on a User, we've said that if I'm an admin, which I am, I'm logged in with admin, I should be able to view all fields. Refresh the page, and voila! There is all of my users with their email addresses. And now, if I select a User Type such as a Company, there is Hana, Candidates, there are the other three, and here is everyone else including myself down here. I just excluded Admin from an option over here, but not from this actual table.
What we can do, though, is since I don't want to see myself, if I go back in the Design tab, double-click on Table Job posts, bring up the Property Editor, open up the data source Search for Users where we can access the constraints section, and we have User Type equals the dropdown, but we have ignore empty constraints. So I'm going to add another constraint here, and I'm going to say User Type, and now we're used to using this equals operator, but we have another one down here (<>), and this one basically means "is not equal". When you select that, "User Type is not equal to Admin," and that will then exclude our own User row from that table.
All right, let's test this! Refresh, here I am down here. And I am gone, and we're down to four results.
Okay, let's get Jobs in as well. Head over to the demo app, the link is above. I'm going to close Group Users and I'm going to bring up Group Jobs. Okay, I'm going to choose "Edit", "Copy to another app". Going to head back to my own app. I'm going to scroll up and I'm going to close everything. I'm going to find my Group Container, right-click, and paste!
Okay, we have some issues, so let's fix those. Seven issues, let's have a look. So Search for Jobs constraint field is empty, and that is referring to this dropdown over here. But let's rather, instead of using the Issue Checker, let's just walk through what we've done here.
So go ahead, open up the Table Job posts and let's just look at all the data. So first of all, we have selected Company. Okay, this is where we need to fix some stuff. So Type of choices, go down to your Data Types and look for Company, let's reconnect that. We're going to say, Search for Companys in the Choices source and close. Then we're going to pull the name of the company into the dropdown options with no default value. We have some conditions here, that's just for focus, that's fine. Okay, so we fixed that.
Let's now open up the Table Job posts, and on the table, we're searching for Jobs. Any field contains the search. We're not dealing with search, let's rather just add a new fresh constraint, which refers to the Company. This is this dropdown on the right-hand side, so when you select the dropdown, when you select Orbit or Bubble or something else, then it will filter our results.
So Company equals Dropdown Company. You can see how Bubble has greyed out the Dropdown User Type. And that is because on this dropdown, we have a Type of choice Company. And on this table, we're trying to match Company with something, and the dropdown is the same data type.
On the Conditional tab, all right, we know about that, and let's just go through some dynamic data here. So we're trying to pull in the logos. I'm going to choose Current row's Job's, then Company, and then Logo (Current row's Job's Company's Logo). The name is the Current row's Job's Company's Name. Bubble is actually connecting this faster than I can get to it!
Current row's Job's Title, this is a link element, and actually this needs to be resolved. So where would it send us? If this is a table of jobs, it's going to go to the actual job itself. So it will be an internal page, but that needs to go to the job page, and we need to send data because the job page has page data. It's expecting us to send the Job from the database to populate that page. So it's just a Current row's Job. Bubble knows what to do next, and we're going to open that in a new tab.
After that, we look at the Full time, so this is the Job's Term. Bubble has put in this display for us. Starting salary, Current row's Job's Salary, and then we select :min, and then I'll just add some formatting there that should be retained.
And then Applied, so Applied is a little bit different because we're not getting applied from the "Current row". We have to go search for Applications, and Applications is a separate data type. So yes, so we can mix and match data, we can do a search for within tables themselves for other data types. And that's exactly what we're doing here. But now we need to set up our constraint to say only search for Applications in this field or in this row that pertains to the Company of this Job.
I've clicked on the text. I'm going to choose Search for Applications and let's just first go see how we match an Application with a Job. I'm going to go to the Data tab under Data types. I'm going to look at Application, and we can see under Application that we have a field called Job. So we can do this. We can now say Search for Applications where the Job equals Current row's Job. Simple as that. How many applications have been made for this job? And then bring back the :count. Okay, the Posted date is fine, and that's all good. Let's test this.
Actually, one thing we do need to do, sorry, before we test it, is just remove this "New job" button. Not interested in that for this lesson. All right, let's go test this.
Refresh the page. Head over to Jobs and there we go. There is all of our Jobs. We've got 11 results. We don't have pagination. That is a slightly more intermediate to advanced technique, but there's a lot on the forum that can help you get up and running with pagination. I'm going to select Orbit, got 4 results. Bubble, 1 result.
Okay, one more thing I wanted to do before the break is just have a look at on Group Users, the null data. Let's just sort this out. Open up Group Users, scroll to the bottom of Group Users to find "Group no data". I just want to tidy this up quickly. "You've not received any applications yet," we can instead simply say, "No users found".
Things are really coming together! One more thing we need to do when we get back, and then after that, we start to get into the real fun stuff, such as optimizations and third-party integrations, and deployment. So I'll see you in the next lesson!