From c5c8c45bab33d11c40550657d04f4950b8d51679 Mon Sep 17 00:00:00 2001 From: Thomas Rittson <31796059+eliykat@users.noreply.github.com> Date: Fri, 26 Jul 2024 07:46:11 +1000 Subject: [PATCH] [AC-2924] Remove GroupsComponentRefactor flag (#10259) * Remove feature flag and old component --- .../manage/groups.component.html | 175 ++++++------ .../organizations/manage/groups.component.ts | 251 +++++------------ .../manage/new-groups.component.html | 109 -------- .../manage/new-groups.component.ts | 255 ------------------ .../organization-routing.module.ts | 24 +- .../organizations/organization.module.ts | 3 +- libs/common/src/enums/feature-flag.enum.ts | 2 - 7 files changed, 167 insertions(+), 652 deletions(-) delete mode 100644 apps/web/src/app/admin-console/organizations/manage/new-groups.component.html delete mode 100644 apps/web/src/app/admin-console/organizations/manage/new-groups.component.ts diff --git a/apps/web/src/app/admin-console/organizations/manage/groups.component.html b/apps/web/src/app/admin-console/organizations/manage/groups.component.html index 2ebafb38fc..1254d48cc7 100644 --- a/apps/web/src/app/admin-console/organizations/manage/groups.component.html +++ b/apps/web/src/app/admin-console/organizations/manage/groups.component.html @@ -1,7 +1,7 @@ + +

{{ "noGroupsInList" | i18n }}

+ + + + + + + + + + {{ "name" | i18n }} + {{ "collections" | i18n }} + + - - + + + + + + + + + + + - - - -
- - - - - - - - - - - - - + + + + + + - - - - - - - - - - + + + + + + + + + + + - diff --git a/apps/web/src/app/admin-console/organizations/manage/groups.component.ts b/apps/web/src/app/admin-console/organizations/manage/groups.component.ts index 7c86ac2849..dfb6f349eb 100644 --- a/apps/web/src/app/admin-console/organizations/manage/groups.component.ts +++ b/apps/web/src/app/admin-console/organizations/manage/groups.component.ts @@ -1,4 +1,6 @@ -import { Component, OnDestroy, OnInit, ViewChild, ViewContainerRef } from "@angular/core"; +import { Component } from "@angular/core"; +import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; +import { FormControl } from "@angular/forms"; import { ActivatedRoute } from "@angular/router"; import { BehaviorSubject, @@ -7,21 +9,15 @@ import { from, lastValueFrom, map, - Subject, switchMap, - takeUntil, tap, } from "rxjs"; -import { first } from "rxjs/operators"; +import { debounceTime, first } from "rxjs/operators"; -import { SearchPipe } from "@bitwarden/angular/pipes/search.pipe"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; -import { SearchService } from "@bitwarden/common/abstractions/search.service"; import { ListResponse } from "@bitwarden/common/models/response/list.response"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; -import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; -import { Utils } from "@bitwarden/common/platform/misc/utils"; import { CollectionService } from "@bitwarden/common/vault/abstractions/collection.service"; import { CollectionData } from "@bitwarden/common/vault/models/data/collection.data"; import { Collection } from "@bitwarden/common/vault/models/domain/collection"; @@ -30,7 +26,7 @@ import { CollectionResponse, } from "@bitwarden/common/vault/models/response/collection.response"; import { CollectionView } from "@bitwarden/common/vault/models/view/collection.view"; -import { DialogService } from "@bitwarden/components"; +import { DialogService, TableDataSource, ToastService } from "@bitwarden/components"; import { InternalGroupService as GroupService, GroupView } from "../core"; @@ -40,21 +36,7 @@ import { openGroupAddEditDialog, } from "./group-add-edit.component"; -type CollectionViewMap = { - [id: string]: CollectionView; -}; - type GroupDetailsRow = { - /** - * Group Id (used for searching) - */ - id: string; - - /** - * Group name (used for searching) - */ - name: string; - /** * Details used for displaying group information */ @@ -72,59 +54,38 @@ type GroupDetailsRow = { }; /** - * @deprecated To be replaced with NewGroupsComponent which significantly refactors this component. - * The GroupsComponentRefactor flag switches between the old and new components; this component will be removed when - * the feature flag is removed. + * Custom filter predicate that filters the groups table by id and name only. + * This is required because the default implementation searches by all properties, which can unintentionally match + * with members' names (who are assigned to the group) or collection names (which the group has access to). */ +const groupsFilter = (filter: string) => { + const transformedFilter = filter.trim().toLowerCase(); + return (data: GroupDetailsRow) => { + const group = data.details; + + return ( + group.id.toLowerCase().indexOf(transformedFilter) != -1 || + group.name.toLowerCase().indexOf(transformedFilter) != -1 + ); + }; +}; + @Component({ - selector: "app-org-groups", templateUrl: "groups.component.html", }) -export class GroupsComponent implements OnInit, OnDestroy { - @ViewChild("addEdit", { read: ViewContainerRef, static: true }) addEditModalRef: ViewContainerRef; - @ViewChild("usersTemplate", { read: ViewContainerRef, static: true }) - usersModalRef: ViewContainerRef; - +export class GroupsComponent { loading = true; organizationId: string; - groups: GroupDetailsRow[]; - protected didScroll = false; - protected pageSize = 100; + protected dataSource = new TableDataSource(); + protected searchControl = new FormControl(""); + + // Fixed sizes used for cdkVirtualScroll + protected rowHeight = 46; + protected rowHeightClass = `tw-h-[46px]`; + protected ModalTabType = GroupAddEditTabType; - - private pagedGroupsCount = 0; - private pagedGroups: GroupDetailsRow[]; - private searchedGroups: GroupDetailsRow[]; - private _searchText$ = new BehaviorSubject(""); - private destroy$ = new Subject(); private refreshGroups$ = new BehaviorSubject(null); - private isSearching: boolean = false; - - get searchText() { - return this._searchText$.value; - } - set searchText(value: string) { - this._searchText$.next(value); - // Manually update as we are not using the search pipe in the template - this.updateSearchedGroups(); - } - - /** - * The list of groups that should be visible in the table. - * This is needed as there are two modes (paging/searching) and - * we need a reference to the currently visible groups for - * the Select All checkbox - */ - get visibleGroups(): GroupDetailsRow[] { - if (this.isPaging()) { - return this.pagedGroups; - } - if (this.isSearching) { - return this.searchedGroups; - } - return this.groups; - } constructor( private apiService: ApiService, @@ -132,14 +93,10 @@ export class GroupsComponent implements OnInit, OnDestroy { private route: ActivatedRoute, private i18nService: I18nService, private dialogService: DialogService, - private platformUtilsService: PlatformUtilsService, - private searchService: SearchService, private logService: LogService, private collectionService: CollectionService, - private searchPipe: SearchPipe, - ) {} - - async ngOnInit() { + private toastService: ToastService, + ) { this.route.params .pipe( tap((params) => (this.organizationId = params.organizationId)), @@ -156,68 +113,31 @@ export class GroupsComponent implements OnInit, OnDestroy { ]), ), map(([collectionMap, groups]) => { - return groups - .sort(Utils.getSortFunction(this.i18nService, "name")) - .map((g) => ({ - id: g.id, - name: g.name, - details: g, - checked: false, - collectionNames: g.collections - .map((c) => collectionMap[c.id]?.name) - .sort(this.i18nService.collator?.compare), - })); + return groups.map((g) => ({ + id: g.id, + name: g.name, + details: g, + checked: false, + collectionNames: g.collections + .map((c) => collectionMap[c.id]?.name) + .sort(this.i18nService.collator?.compare), + })); }), - takeUntil(this.destroy$), + takeUntilDestroyed(), ) .subscribe((groups) => { - this.groups = groups; - this.resetPaging(); - this.updateSearchedGroups(); + this.dataSource.data = groups; this.loading = false; }); - this.route.queryParams - .pipe( - first(), - concatMap(async (qParams) => { - this.searchText = qParams.search; - }), - takeUntil(this.destroy$), - ) - .subscribe(); + // Connect the search input to the table dataSource filter input + this.searchControl.valueChanges + .pipe(debounceTime(200), takeUntilDestroyed()) + .subscribe((v) => (this.dataSource.filter = groupsFilter(v))); - this._searchText$ - .pipe( - switchMap((searchText) => this.searchService.isSearchable(searchText)), - takeUntil(this.destroy$), - ) - .subscribe((isSearchable) => { - this.isSearching = isSearchable; - }); - } - - ngOnDestroy() { - this.destroy$.next(); - this.destroy$.complete(); - } - - loadMore() { - if (!this.groups || this.groups.length <= this.pageSize) { - return; - } - const pagedLength = this.pagedGroups.length; - let pagedSize = this.pageSize; - if (pagedLength === 0 && this.pagedGroupsCount > this.pageSize) { - pagedSize = this.pagedGroupsCount; - } - if (this.groups.length > pagedLength) { - this.pagedGroups = this.pagedGroups.concat( - this.groups.slice(pagedLength, pagedLength + pagedSize), - ); - } - this.pagedGroupsCount = this.pagedGroups.length; - this.didScroll = this.pagedGroups.length > this.pageSize; + this.route.queryParams.pipe(first(), takeUntilDestroyed()).subscribe((qParams) => { + this.searchControl.setValue(qParams.search); + }); } async edit( @@ -237,14 +157,12 @@ export class GroupsComponent implements OnInit, OnDestroy { if (result == GroupAddEditDialogResultType.Saved) { this.refreshGroups$.next(); } else if (result == GroupAddEditDialogResultType.Deleted) { - this.removeGroup(group.details.id); + this.removeGroup(group); } } - add() { - // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. - // eslint-disable-next-line @typescript-eslint/no-floating-promises - this.edit(null); + async add() { + await this.edit(null); } async delete(groupRow: GroupDetailsRow) { @@ -259,19 +177,19 @@ export class GroupsComponent implements OnInit, OnDestroy { try { await this.groupService.delete(this.organizationId, groupRow.details.id); - this.platformUtilsService.showToast( - "success", - null, - this.i18nService.t("deletedGroupId", groupRow.details.name), - ); - this.removeGroup(groupRow.details.id); + this.toastService.showToast({ + variant: "success", + title: null, + message: this.i18nService.t("deletedGroupId", groupRow.details.name), + }); + this.removeGroup(groupRow); } catch (e) { this.logService.error(e); } } async deleteAllSelected() { - const groupsToDelete = this.groups.filter((g) => g.checked); + const groupsToDelete = this.dataSource.data.filter((g) => g.checked); if (groupsToDelete.length == 0) { return; @@ -295,46 +213,31 @@ export class GroupsComponent implements OnInit, OnDestroy { this.organizationId, groupsToDelete.map((g) => g.details.id), ); - this.platformUtilsService.showToast( - "success", - null, - this.i18nService.t("deletedManyGroups", groupsToDelete.length.toString()), - ); + this.toastService.showToast({ + variant: "success", + title: null, + message: this.i18nService.t("deletedManyGroups", groupsToDelete.length.toString()), + }); - groupsToDelete.forEach((g) => this.removeGroup(g.details.id)); + groupsToDelete.forEach((g) => this.removeGroup(g)); } catch (e) { this.logService.error(e); } } - resetPaging() { - this.pagedGroups = []; - this.loadMore(); - } - check(groupRow: GroupDetailsRow) { groupRow.checked = !groupRow.checked; } toggleAllVisible(event: Event) { - this.visibleGroups.forEach((g) => (g.checked = (event.target as HTMLInputElement).checked)); + this.dataSource.filteredData.forEach( + (g) => (g.checked = (event.target as HTMLInputElement).checked), + ); } - isPaging() { - const searching = this.isSearching; - if (searching && this.didScroll) { - this.resetPaging(); - } - return !searching && this.groups && this.groups.length > this.pageSize; - } - - private removeGroup(id: string) { - const index = this.groups.findIndex((g) => g.details.id === id); - if (index > -1) { - this.groups.splice(index, 1); - this.resetPaging(); - this.updateSearchedGroups(); - } + private removeGroup(groupRow: GroupDetailsRow) { + // Assign a new array to dataSource.data to trigger the setters and update the table + this.dataSource.data = this.dataSource.data.filter((g) => g !== groupRow); } private async toCollectionMap(response: ListResponse) { @@ -344,21 +247,9 @@ export class GroupsComponent implements OnInit, OnDestroy { const decryptedCollections = await this.collectionService.decryptMany(collections); // Convert to an object using collection Ids as keys for faster name lookups - const collectionMap: CollectionViewMap = {}; + const collectionMap: Record = {}; decryptedCollections.forEach((c) => (collectionMap[c.id] = c)); return collectionMap; } - - private updateSearchedGroups() { - if (this.isSearching) { - // Making use of the pipe in the component as we need know which groups where filtered - this.searchedGroups = this.searchPipe.transform( - this.groups, - this.searchText, - (group) => group.details.name, - (group) => group.details.id, - ); - } - } } diff --git a/apps/web/src/app/admin-console/organizations/manage/new-groups.component.html b/apps/web/src/app/admin-console/organizations/manage/new-groups.component.html deleted file mode 100644 index 1254d48cc7..0000000000 --- a/apps/web/src/app/admin-console/organizations/manage/new-groups.component.html +++ /dev/null @@ -1,109 +0,0 @@ - - - - - - - - {{ "loading" | i18n }} - - -

{{ "noGroupsInList" | i18n }}

- - - - - - - - - - {{ "name" | i18n }} - {{ "collections" | i18n }} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
diff --git a/apps/web/src/app/admin-console/organizations/manage/new-groups.component.ts b/apps/web/src/app/admin-console/organizations/manage/new-groups.component.ts deleted file mode 100644 index e5e99333e6..0000000000 --- a/apps/web/src/app/admin-console/organizations/manage/new-groups.component.ts +++ /dev/null @@ -1,255 +0,0 @@ -import { Component } from "@angular/core"; -import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; -import { FormControl } from "@angular/forms"; -import { ActivatedRoute } from "@angular/router"; -import { - BehaviorSubject, - combineLatest, - concatMap, - from, - lastValueFrom, - map, - switchMap, - tap, -} from "rxjs"; -import { debounceTime, first } from "rxjs/operators"; - -import { ApiService } from "@bitwarden/common/abstractions/api.service"; -import { ListResponse } from "@bitwarden/common/models/response/list.response"; -import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; -import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; -import { CollectionService } from "@bitwarden/common/vault/abstractions/collection.service"; -import { CollectionData } from "@bitwarden/common/vault/models/data/collection.data"; -import { Collection } from "@bitwarden/common/vault/models/domain/collection"; -import { - CollectionDetailsResponse, - CollectionResponse, -} from "@bitwarden/common/vault/models/response/collection.response"; -import { CollectionView } from "@bitwarden/common/vault/models/view/collection.view"; -import { DialogService, TableDataSource, ToastService } from "@bitwarden/components"; - -import { InternalGroupService as GroupService, GroupView } from "../core"; - -import { - GroupAddEditDialogResultType, - GroupAddEditTabType, - openGroupAddEditDialog, -} from "./group-add-edit.component"; - -type GroupDetailsRow = { - /** - * Details used for displaying group information - */ - details: GroupView; - - /** - * True if the group is selected in the table - */ - checked?: boolean; - - /** - * A list of collection names the group has access to - */ - collectionNames?: string[]; -}; - -/** - * Custom filter predicate that filters the groups table by id and name only. - * This is required because the default implementation searches by all properties, which can unintentionally match - * with members' names (who are assigned to the group) or collection names (which the group has access to). - */ -const groupsFilter = (filter: string) => { - const transformedFilter = filter.trim().toLowerCase(); - return (data: GroupDetailsRow) => { - const group = data.details; - - return ( - group.id.toLowerCase().indexOf(transformedFilter) != -1 || - group.name.toLowerCase().indexOf(transformedFilter) != -1 - ); - }; -}; - -@Component({ - templateUrl: "new-groups.component.html", -}) -export class NewGroupsComponent { - loading = true; - organizationId: string; - - protected dataSource = new TableDataSource(); - protected searchControl = new FormControl(""); - - // Fixed sizes used for cdkVirtualScroll - protected rowHeight = 46; - protected rowHeightClass = `tw-h-[46px]`; - - protected ModalTabType = GroupAddEditTabType; - private refreshGroups$ = new BehaviorSubject(null); - - constructor( - private apiService: ApiService, - private groupService: GroupService, - private route: ActivatedRoute, - private i18nService: I18nService, - private dialogService: DialogService, - private logService: LogService, - private collectionService: CollectionService, - private toastService: ToastService, - ) { - this.route.params - .pipe( - tap((params) => (this.organizationId = params.organizationId)), - switchMap(() => - combineLatest([ - // collectionMap - from(this.apiService.getCollections(this.organizationId)).pipe( - concatMap((response) => this.toCollectionMap(response)), - ), - // groups - this.refreshGroups$.pipe( - switchMap(() => this.groupService.getAll(this.organizationId)), - ), - ]), - ), - map(([collectionMap, groups]) => { - return groups.map((g) => ({ - id: g.id, - name: g.name, - details: g, - checked: false, - collectionNames: g.collections - .map((c) => collectionMap[c.id]?.name) - .sort(this.i18nService.collator?.compare), - })); - }), - takeUntilDestroyed(), - ) - .subscribe((groups) => { - this.dataSource.data = groups; - this.loading = false; - }); - - // Connect the search input to the table dataSource filter input - this.searchControl.valueChanges - .pipe(debounceTime(200), takeUntilDestroyed()) - .subscribe((v) => (this.dataSource.filter = groupsFilter(v))); - - this.route.queryParams.pipe(first(), takeUntilDestroyed()).subscribe((qParams) => { - this.searchControl.setValue(qParams.search); - }); - } - - async edit( - group: GroupDetailsRow, - startingTabIndex: GroupAddEditTabType = GroupAddEditTabType.Info, - ) { - const dialogRef = openGroupAddEditDialog(this.dialogService, { - data: { - initialTab: startingTabIndex, - organizationId: this.organizationId, - groupId: group != null ? group.details.id : null, - }, - }); - - const result = await lastValueFrom(dialogRef.closed); - - if (result == GroupAddEditDialogResultType.Saved) { - this.refreshGroups$.next(); - } else if (result == GroupAddEditDialogResultType.Deleted) { - this.removeGroup(group); - } - } - - async add() { - await this.edit(null); - } - - async delete(groupRow: GroupDetailsRow) { - const confirmed = await this.dialogService.openSimpleDialog({ - title: groupRow.details.name, - content: { key: "deleteGroupConfirmation" }, - type: "warning", - }); - if (!confirmed) { - return false; - } - - try { - await this.groupService.delete(this.organizationId, groupRow.details.id); - this.toastService.showToast({ - variant: "success", - title: null, - message: this.i18nService.t("deletedGroupId", groupRow.details.name), - }); - this.removeGroup(groupRow); - } catch (e) { - this.logService.error(e); - } - } - - async deleteAllSelected() { - const groupsToDelete = this.dataSource.data.filter((g) => g.checked); - - if (groupsToDelete.length == 0) { - return; - } - - const deleteMessage = groupsToDelete.map((g) => g.details.name).join(", "); - const confirmed = await this.dialogService.openSimpleDialog({ - title: { - key: "deleteMultipleGroupsConfirmation", - placeholders: [groupsToDelete.length.toString()], - }, - content: deleteMessage, - type: "warning", - }); - if (!confirmed) { - return false; - } - - try { - await this.groupService.deleteMany( - this.organizationId, - groupsToDelete.map((g) => g.details.id), - ); - this.toastService.showToast({ - variant: "success", - title: null, - message: this.i18nService.t("deletedManyGroups", groupsToDelete.length.toString()), - }); - - groupsToDelete.forEach((g) => this.removeGroup(g)); - } catch (e) { - this.logService.error(e); - } - } - - check(groupRow: GroupDetailsRow) { - groupRow.checked = !groupRow.checked; - } - - toggleAllVisible(event: Event) { - this.dataSource.filteredData.forEach( - (g) => (g.checked = (event.target as HTMLInputElement).checked), - ); - } - - private removeGroup(groupRow: GroupDetailsRow) { - // Assign a new array to dataSource.data to trigger the setters and update the table - this.dataSource.data = this.dataSource.data.filter((g) => g !== groupRow); - } - - private async toCollectionMap(response: ListResponse) { - const collections = response.data.map( - (r) => new Collection(new CollectionData(r as CollectionDetailsResponse)), - ); - const decryptedCollections = await this.collectionService.decryptMany(collections); - - // Convert to an object using collection Ids as keys for faster name lookups - const collectionMap: Record = {}; - decryptedCollections.forEach((c) => (collectionMap[c.id] = c)); - - return collectionMap; - } -} diff --git a/apps/web/src/app/admin-console/organizations/organization-routing.module.ts b/apps/web/src/app/admin-console/organizations/organization-routing.module.ts index 2c8c52efc6..538cc45ac6 100644 --- a/apps/web/src/app/admin-console/organizations/organization-routing.module.ts +++ b/apps/web/src/app/admin-console/organizations/organization-routing.module.ts @@ -2,7 +2,6 @@ import { NgModule } from "@angular/core"; import { RouterModule, Routes } from "@angular/router"; import { authGuard } from "@bitwarden/angular/auth/guards"; -import { featureFlaggedRoute } from "@bitwarden/angular/platform/utils/feature-flagged-route"; import { canAccessOrgAdmin, canAccessGroupsTab, @@ -12,16 +11,15 @@ import { canAccessSettingsTab, } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; import { Organization } from "@bitwarden/common/admin-console/models/domain/organization"; -import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; import { organizationPermissionsGuard } from "../../admin-console/organizations/guards/org-permissions.guard"; import { organizationRedirectGuard } from "../../admin-console/organizations/guards/org-redirect.guard"; import { OrganizationLayoutComponent } from "../../admin-console/organizations/layouts/organization-layout.component"; -import { GroupsComponent } from "../../admin-console/organizations/manage/groups.component"; -import { NewGroupsComponent } from "../../admin-console/organizations/manage/new-groups.component"; import { deepLinkGuard } from "../../auth/guards/deep-link.guard"; import { VaultModule } from "../../vault/org-vault/vault.module"; +import { GroupsComponent } from "./manage/groups.component"; + const routes: Routes = [ { path: ":organizationId", @@ -49,18 +47,14 @@ const routes: Routes = [ path: "members", loadChildren: () => import("./members").then((m) => m.MembersModule), }, - ...featureFlaggedRoute({ - defaultComponent: GroupsComponent, - flaggedComponent: NewGroupsComponent, - featureFlag: FeatureFlag.GroupsComponentRefactor, - routeOptions: { - path: "groups", - canActivate: [organizationPermissionsGuard(canAccessGroupsTab)], - data: { - titleId: "groups", - }, + { + component: GroupsComponent, + path: "groups", + canActivate: [organizationPermissionsGuard(canAccessGroupsTab)], + data: { + titleId: "groups", }, - }), + }, { path: "reporting", loadChildren: () => diff --git a/apps/web/src/app/admin-console/organizations/organization.module.ts b/apps/web/src/app/admin-console/organizations/organization.module.ts index 79f3a8e5f7..459948d0f1 100644 --- a/apps/web/src/app/admin-console/organizations/organization.module.ts +++ b/apps/web/src/app/admin-console/organizations/organization.module.ts @@ -6,7 +6,6 @@ import { LooseComponentsModule } from "../../shared"; import { CoreOrganizationModule } from "./core"; import { GroupAddEditComponent } from "./manage/group-add-edit.component"; import { GroupsComponent } from "./manage/groups.component"; -import { NewGroupsComponent } from "./manage/new-groups.component"; import { OrganizationsRoutingModule } from "./organization-routing.module"; import { SharedOrganizationModule } from "./shared"; import { AccessSelectorModule } from "./shared/components/access-selector"; @@ -20,6 +19,6 @@ import { AccessSelectorModule } from "./shared/components/access-selector"; LooseComponentsModule, ScrollingModule, ], - declarations: [GroupsComponent, NewGroupsComponent, GroupAddEditComponent], + declarations: [GroupsComponent, GroupAddEditComponent], }) export class OrganizationModule {} diff --git a/libs/common/src/enums/feature-flag.enum.ts b/libs/common/src/enums/feature-flag.enum.ts index 0e70e6db44..ce00640fa9 100644 --- a/libs/common/src/enums/feature-flag.enum.ts +++ b/libs/common/src/enums/feature-flag.enum.ts @@ -22,7 +22,6 @@ export enum FeatureFlag { TwoFactorComponentRefactor = "two-factor-component-refactor", EnableTimeThreshold = "PM-5864-dollar-threshold", InlineMenuPositioningImprovements = "inline-menu-positioning-improvements", - GroupsComponentRefactor = "groups-component-refactor", ProviderClientVaultPrivacyBanner = "ac-2833-provider-client-vault-privacy-banner", VaultBulkManagementAction = "vault-bulk-management-action", AC2828_ProviderPortalMembersPage = "AC-2828_provider-portal-members-page", @@ -60,7 +59,6 @@ export const DefaultFeatureFlagValue = { [FeatureFlag.TwoFactorComponentRefactor]: FALSE, [FeatureFlag.EnableTimeThreshold]: FALSE, [FeatureFlag.InlineMenuPositioningImprovements]: FALSE, - [FeatureFlag.GroupsComponentRefactor]: FALSE, [FeatureFlag.ProviderClientVaultPrivacyBanner]: FALSE, [FeatureFlag.VaultBulkManagementAction]: FALSE, [FeatureFlag.AC2828_ProviderPortalMembersPage]: FALSE,