Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add friendly name to list group members response #8413

Merged
merged 7 commits into from
Dec 17, 2024

Conversation

idanovo
Copy link
Contributor

@idanovo idanovo commented Dec 11, 2024

No description provided.

@idanovo idanovo added include-changelog PR description should be included in next release changelog minor-change Used for PRs that don't require issue attached labels Dec 11, 2024
@idanovo idanovo requested a review from Isan-Rivkin December 11, 2024 10:00
@idanovo idanovo self-assigned this Dec 11, 2024
Copy link

E2E Test Results - DynamoDB Local - Local Block Adapter

13 passed

Copy link

github-actions bot commented Dec 11, 2024

E2E Test Results - Quickstart

11 passed

Copy link
Contributor

@Isan-Rivkin Isan-Rivkin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

spoke offline, please test and ask re-review when done :)

@idanovo idanovo requested a review from Isan-Rivkin December 11, 2024 15:32
@idanovo idanovo requested a review from Isan-Rivkin December 12, 2024 11:00
@idanovo idanovo requested review from guy-har and itaigilo and removed request for Isan-Rivkin December 17, 2024 09:03
Copy link
Contributor

@itaigilo itaigilo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@idanovo thanks for jumping into some UI stuff -
The code is very clear and easy to understand.

Blocking mainly for possible performance issues, since if we're indeed fetching all users, we should make sure we do it only when necessary, to prevent from extra loads.

@@ -9,9 +9,10 @@ import {SearchIcon} from "@primer/octicons-react";
import {useAPI} from "../../hooks/api";
import {Checkbox, DataTable, DebouncedFormControl, AlertError, Loading} from "../controls";

const resolveEntityDisplayName = (ent) => {
export const ResolveEntityDisplayName = (ent) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In our JS code (and in React in general), capitalize React components, while functions should be camelCased -
No matter if they are private or public.
(So this one should remain resolveEntityDisplayName.)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More important:
Now that this func is exported, it seemed to me that it should reside in some utils file.
Well, apparently, there's already utils.ts, containing a resolveDisplayName func 😄
Please unify these.

Copy link
Contributor

@guy-har guy-har Dec 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@itaigilo, I talked with Idan F2F, and mentioned that this resolver method should be provided by the caller, given the fact that this form isn't aware of the caller and that it already mixes between groups and users
WDYT

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure this is in the context of this PR...
We can chat about it f2f if you'd like to.

useEffect(() => {
setAttachError(null);
}, [refresh]);

const setAllUsersFromLakeFS = async () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not only setting the users, but mainly fetching them.
This is important, since when I'm calling this function, it should be clear that it gets data from the API.

So please rename to AllUsersFromLakeFS, or something else that will make it clear that this is about API calls.

let usersList = []
try {
do {
const results = await auth.listUsers("", after, MAX_LISTING_AMOUNT);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens after MAX_LISTING_AMOUNT?

Shouldn't we detect this scenario, and at least warn the user in some way?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I run do-while in order to list all the users with pagination

}
}
const searchUsers = async (prefix, maxResults) => {
let allUsersList = await setAllUsersFromLakeFS()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I get it right, it fetches all the search results from the API for every prefix change? No caching?
What will happen (performance-wise) in case of 1000 users, for example?

Copy link
Contributor Author

@idanovo idanovo Dec 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, only on the first time we load the "add member" pop-up
I load all the objects to the allUsers which is part of the state of this page
BTW, I've tested my PR with 10K users org and it ran pretty fast

@itaigilo
Copy link
Contributor

And if I'm taking this up one level, I'm not sure that fetching all the users in the client is the best approach here.
Another option is to change the API to support different sorting for the List Users endpoint, and sort it by friendly_name in the server-side. This should both reduce the load on the clients, and add new capabilities to our API.

Comment on lines 44 to 46
try {
do {
const results = await auth.listUsers("", after, MAX_LISTING_AMOUNT);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check out useAPIWithPagination I think it reduce a bit of code

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it's the same case.
Here, I need to load all the users, not just a specific page.
The useAPIWithPagination load each time a different page to the state which is not what I need

Comment on lines 38 to 40
if (allUsers.length > 0) {
return allUsers
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@itaigilo, isn't there some better way to force only one load, with useEffect or something?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably -
But I think that if some caching will be added here, it'll change the flow. Not sure though.

@idanovo idanovo requested review from itaigilo and guy-har December 17, 2024 12:38
@idanovo
Copy link
Contributor Author

idanovo commented Dec 17, 2024

And if I'm taking this up one level, I'm not sure that fetching all the users in the client is the best approach here. Another option is to change the API to support different sorting for the List Users endpoint, and sort it by friendly_name in the server-side. This should both reduce the load on the clients, and add new capabilities to our API.

@itaigilo We do it intentionally on the UI, the alternative for this was to change listUsers to not list users by ID (which is the key we use to save the users in the the KV).
This change will make all the listUsers calls to run slower.

Copy link
Contributor

@itaigilo itaigilo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking good 😄

Approving to unblock, but please check out my code-style comments.


export const AttachModal = ({ show, searchFn, onAttach, onHide, addText = "Add",

export const AttachModal = ({ show, searchFn, onAttach, onHide, resolveEntityFN = (ent => ent.id), addText = "Add",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit:
Should be resolveEntityFN (since we have searchFn).
I would also put but Fn params next to each other.

useEffect(() => {
setAttachError(null);
}, [refresh]);

const allUsersFromLakeFS = async (resolveUserDisplayNameFN = (user => user.id)) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is too much business logic to be in this file -
Well might be useful somewhere else.

How about extracting this?
Even into a file of its own, under components/auth, for example?

@@ -21,6 +21,12 @@ import { ConfirmationButton } from "../../../../lib/components/modals";
import { useRouter } from "../../../../lib/hooks/router";
import { Link } from "../../../../lib/components/nav";

const resolveGroupDisplayName = (group) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔥

@idanovo idanovo merged commit e74938c into master Dec 17, 2024
39 checks passed
@idanovo idanovo deleted the add-friendlyname-to-group-members-resp branch December 17, 2024 16:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
include-changelog PR description should be included in next release changelog minor-change Used for PRs that don't require issue attached
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants