Repository navigation
Add ouId prop to GroupMembers #146
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -13,6 +13,7 @@ import { | |
| getUsers, | ||
| removeGroupMembers, | ||
| resolveManagedIdentityName, | ||
| toEqualityFilter, | ||
| toManagementErrorMessage, | ||
| } from '@thunderid/browser'; | ||
| import type { | ||
|
|
@@ -41,6 +42,7 @@ type GroupMembersProps = Readonly<{ | |
| description: string | undefined; | ||
| editable: boolean; | ||
| groupId: string; | ||
| ouId: string | undefined; | ||
| preferences: Preferences | undefined; | ||
| title: string | undefined; | ||
| }>; | ||
|
|
@@ -50,6 +52,14 @@ interface GroupMembersVariables { | |
| members: Pick<GroupMember, 'id' | 'type'>[]; | ||
| } | ||
|
|
||
| /** | ||
| * A candidate page with the filter it was listed with. | ||
| */ | ||
| interface FilteredPage<T> { | ||
| filter: string | undefined; | ||
| page: T; | ||
| } | ||
|
|
||
| /** | ||
| * Lists a group's members and, unless `editable` is `false`, lets the signed-in user add users and | ||
| * agents to it or remove members. | ||
|
|
@@ -75,6 +85,10 @@ const GroupMembers: Component = defineComponent({ | |
| editable: {default: false, type: Boolean}, | ||
| /** Identifier of the group. */ | ||
| groupId: {required: true, type: String}, | ||
| /** | ||
| * Organization unit the users and agents offered for adding are listed from. | ||
| */ | ||
| ouId: {default: undefined, type: String}, | ||
| /** Component-level preferences, for example `i18n.bundles` overrides. */ | ||
| preferences: {default: undefined, type: Object as PropType<Preferences>}, | ||
| /** Heading of the section. Pass an empty string to hide it. */ | ||
|
|
@@ -98,14 +112,23 @@ const GroupMembers: Component = defineComponent({ | |
| (fetcher) => getGroupMembers({...groupsEndpoint, fetcher, groupId: props.groupId, limit: 100}), | ||
| {enabled: () => Boolean(props.groupId)}, | ||
| ); | ||
| const users: ResourceQueryResult<ManagedUserListResponse> = useResourceQuery( | ||
| () => [UserQueryKeys.USERS, {limit: 100}], | ||
| (fetcher) => getUsers({...usersEndpoint, fetcher, limit: 100}), | ||
| const filter = (): string | undefined => toEqualityFilter('ouId', props.ouId); | ||
| const users: ResourceQueryResult<FilteredPage<ManagedUserListResponse>> = useResourceQuery( | ||
| () => [UserQueryKeys.USERS, {filter: filter(), limit: 100}], | ||
| async (fetcher) => { | ||
| const listed: string | undefined = filter(); | ||
|
|
||
| return {filter: listed, page: await getUsers({...usersEndpoint, fetcher, filter: listed, limit: 100})}; | ||
| }, | ||
| {enabled: editable}, | ||
| ); | ||
| const agents: ResourceQueryResult<AgentListResponse> = useResourceQuery( | ||
| () => [AgentQueryKeys.AGENTS, {limit: 100}], | ||
| (fetcher) => getAgents({...agentsEndpoint, fetcher, limit: 100}), | ||
| const agents: ResourceQueryResult<FilteredPage<AgentListResponse>> = useResourceQuery( | ||
| () => [AgentQueryKeys.AGENTS, {filter: filter(), limit: 100}], | ||
| async (fetcher) => { | ||
| const listed: string | undefined = filter(); | ||
|
|
||
| return {filter: listed, page: await getAgents({...agentsEndpoint, fetcher, filter: listed, limit: 100})}; | ||
| }, | ||
|
Comment on lines
+128
to
+131
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| {enabled: editable}, | ||
| ); | ||
| const add: ResourceMutationResult<Group, GroupMembersVariables> = useResourceMutation( | ||
|
|
@@ -125,13 +148,17 @@ const GroupMembers: Component = defineComponent({ | |
| invalidatedByMembership, | ||
| ); | ||
|
|
||
| // A page listed for an earlier ouId stays in a query until the next one succeeds, so it is not offered. | ||
| const current = <T>(data: FilteredPage<T> | undefined): T | undefined => | ||
| data && data.filter === filter() ? data.page : undefined; | ||
|
|
||
| return (): VNode => { | ||
| const candidates: Partial<Record<'user' | 'agent', IdentityCandidate[]>> = { | ||
| agent: (agents.data.value?.agents ?? []).map((agent: BasicAgent) => ({ | ||
| agent: (current(agents.data.value)?.agents ?? []).map((agent: BasicAgent) => ({ | ||
| id: agent.id, | ||
| label: getAgentName(agent), | ||
| })), | ||
| user: (users.data.value?.users ?? []).map((user: ManagedUser) => ({ | ||
| user: (current(users.data.value)?.users ?? []).map((user: ManagedUser) => ({ | ||
| id: user.id, | ||
| label: resolveManagedIdentityName(user), | ||
| })), | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Script executed:
Repository: thunder-id/javascript-sdks
Length of output: 5569
Show candidate-list errors in the group member picker.
When the users or agents query fails with no prior data for the current
ouId, the picker stays empty and shows no message.GroupMemberspasses onlymembers.error,add.error, andremove.errortoBaseGroupMembers, soagents.errorandusers.errornever reach the UI.Include the candidate query errors in the
errorprop, for example throughtoManagementErrorMessage. Add a candidate-list message key to every shipped locale, and use that key for this fallback.