1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-20 10:13:31 +00:00

[EC-15] Members Grid (#4097)

* [EC-623] Introduce shared organization module and search input component

* [EC-623] Add search input story

* [EC-15] Introduce Members module

- Add members module and members routing module
- Move members only components into the members module and folder
- Remove members only components from LooseComponents module
- Update organization routing module to lazy load members module

* [EC-15] Enable ToggleGroup component to support generic values

Using a generic type for the ToggleGroup allows using both Strings and Enums as values without causing Typescript compiler warning/errors.

* [EC-15] Force no bottom margin for Toggle button label

* [EC-15] Update Members page header

- Use bit-toggle for member status filter
- Update bit-toggle Accepted button to say Needs Confirmation
- Use bit-search-input
- Update search placeholder text
- Update invite member button style and text
- Import ToggleGroupModule into ShareModule

* [EC-15] Update members table

- Use the CL bit-table component
- Add new table headings
- Replace cog options menu with bit-menu component
- Add placeholder for groups/collection badges

* [EC-15] Specify default generic type for ToggleGroup

* [EC-15] Modify getOrganizationUsers() in Api service

- Optionally allow the Api service to fetch org user groups and/or collections
- Will eventually be moved to an organization user service, but kept here for now

* [EC-15] Update member view to fetch groups/collections for users

- Use the new Api service functionality
- Fetch the organization's list of groups and decrypted collection for rendering their names in the table

* [EC-15] Refresh table after editing user groups

* [EC-15] Move new members dialog into members module

* [EC-15] Show "All" in collections column for users with AccessAll flag

* [EC-15] Update copy after talking with design/product
This commit is contained in:
Shane Melton
2022-12-14 13:23:33 -08:00
committed by GitHub
parent 443b3e0367
commit 913af652c5
41 changed files with 584 additions and 380 deletions

View File

@@ -354,7 +354,11 @@ export abstract class ApiService {
) => Promise<OrganizationUserDetailsResponse>;
getOrganizationUserGroups: (organizationId: string, id: string) => Promise<string[]>;
getOrganizationUsers: (
organizationId: string
organizationId: string,
options?: {
includeCollections?: boolean;
includeGroups?: boolean;
}
) => Promise<ListResponse<OrganizationUserUserDetailsResponse>>;
getOrganizationUserResetPasswordDetails: (
organizationId: string,

View File

@@ -32,6 +32,8 @@ export class OrganizationUserUserDetailsResponse extends OrganizationUserRespons
email: string;
twoFactorEnabled: boolean;
usesKeyConnector: boolean;
collections: SelectionReadOnlyResponse[] = [];
groups: string[] = [];
constructor(response: any) {
super(response);
@@ -39,6 +41,14 @@ export class OrganizationUserUserDetailsResponse extends OrganizationUserRespons
this.email = this.getResponseProperty("Email");
this.twoFactorEnabled = this.getResponseProperty("TwoFactorEnabled");
this.usesKeyConnector = this.getResponseProperty("UsesKeyConnector") ?? false;
const collections = this.getResponseProperty("Collections");
if (collections != null) {
this.collections = collections.map((c: any) => new SelectionReadOnlyResponse(c));
}
const groups = this.getResponseProperty("Groups");
if (groups != null) {
this.groups = groups;
}
}
}

View File

@@ -984,11 +984,24 @@ export class ApiService implements ApiServiceAbstraction {
}
async getOrganizationUsers(
organizationId: string
organizationId: string,
options?: {
includeCollections?: boolean;
includeGroups?: boolean;
}
): Promise<ListResponse<OrganizationUserUserDetailsResponse>> {
const params = new URLSearchParams();
if (options?.includeCollections) {
params.set("includeCollections", "true");
}
if (options?.includeGroups) {
params.set("includeGroups", "true");
}
const r = await this.send(
"GET",
"/organizations/" + organizationId + "/users",
`/organizations/${organizationId}/users?${params.toString()}`,
null,
true,
true

View File

@@ -7,17 +7,17 @@ let nextId = 0;
templateUrl: "./toggle-group.component.html",
preserveWhitespaces: false,
})
export class ToggleGroupComponent {
export class ToggleGroupComponent<TValue = unknown> {
private id = nextId++;
name = `bit-toggle-group-${this.id}`;
@Input() selected?: unknown;
@Output() selectedChange = new EventEmitter<unknown>();
@Input() selected?: TValue;
@Output() selectedChange = new EventEmitter<TValue>();
@HostBinding("attr.role") role = "radiogroup";
@HostBinding("class") classList = ["tw-flex"];
onInputInteraction(value: unknown) {
onInputInteraction(value: TValue) {
this.selected = value;
this.selectedChange.emit(value);
}

View File

@@ -1,4 +1,4 @@
import { HostBinding, Component, Input } from "@angular/core";
import { Component, HostBinding, Input } from "@angular/core";
import { ToggleGroupComponent } from "./toggle-group.component";
@@ -9,12 +9,12 @@ let nextId = 0;
templateUrl: "./toggle.component.html",
preserveWhitespaces: false,
})
export class ToggleComponent {
export class ToggleComponent<TValue> {
id = nextId++;
@Input() value?: string;
@Input() value?: TValue;
constructor(private groupComponent: ToggleGroupComponent) {}
constructor(private groupComponent: ToggleGroupComponent<TValue>) {}
@HostBinding("tabIndex") tabIndex = "-1";
@HostBinding("class") classList = ["tw-group"];
@@ -67,6 +67,9 @@ export class ToggleComponent {
"tw-py-1.5",
"tw-px-3",
// Fix for bootstrap styles that add bottom margin
"!tw-mb-0",
// Fix for badge being pushed slightly lower when inside a button.
// Insipired by bootstrap, which does the same.
"[&>[bitBadge]]:tw-relative",