diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 80e35cd1c2..eeab584e40 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -43,6 +43,7 @@ import { GroupsComponent as OrgGroupsComponent } from './organizations/manage/gr import { ManageComponent as OrgManageComponent } from './organizations/manage/manage.component'; import { PeopleComponent as OrgPeopleComponent } from './organizations/manage/people.component'; import { UserAddEditComponent as OrgUserAddEditComponent } from './organizations/manage/user-add-edit.component'; +import { UserGroupsComponent as OrgUserGroupsComponent } from './organizations/manage/user-groups.component'; import { ExportComponent as OrgExportComponent } from './organizations/tools/export.component'; import { ImportComponent as OrgImportComponent } from './organizations/tools/import.component'; @@ -189,6 +190,7 @@ import { SearchPipe } from 'jslib/angular/pipes/search.pipe'; OrgPeopleComponent, OrgToolsComponent, OrgUserAddEditComponent, + OrgUserGroupsComponent, OrganizationsComponent, OrganizationLayoutComponent, OrgVaultComponent, @@ -240,6 +242,7 @@ import { SearchPipe } from 'jslib/angular/pipes/search.pipe'; OrgEntityUsersComponent, OrgGroupAddEditComponent, OrgUserAddEditComponent, + OrgUserGroupsComponent, PasswordGeneratorHistoryComponent, PurgeVaultComponent, ShareComponent, diff --git a/src/app/organizations/manage/people.component.ts b/src/app/organizations/manage/people.component.ts index ba596747fd..4d255ba8cc 100644 --- a/src/app/organizations/manage/people.component.ts +++ b/src/app/organizations/manage/people.component.ts @@ -23,6 +23,7 @@ import { Utils } from 'jslib/misc/utils'; import { ModalComponent } from '../../modal.component'; import { UserAddEditComponent } from './user-add-edit.component'; +import { UserGroupsComponent } from './user-groups.component'; @Component({ selector: 'app-org-people', @@ -92,6 +93,28 @@ export class PeopleComponent implements OnInit { this.edit(null); } + groups(user: OrganizationUserUserDetailsResponse) { + if (this.modal != null) { + this.modal.close(); + } + + const factory = this.componentFactoryResolver.resolveComponentFactory(ModalComponent); + this.modal = this.groupsModalRef.createComponent(factory).instance; + const childComponent = this.modal.show( + UserGroupsComponent, this.groupsModalRef); + + childComponent.name = user != null ? user.name || user.email : null; + childComponent.organizationId = this.organizationId; + childComponent.organizationUserId = user != null ? user.id : null; + childComponent.onSavedUser.subscribe(() => { + this.modal.close(); + }); + + this.modal.onClosed.subscribe(() => { + this.modal = null; + }); + } + async remove(user: OrganizationUserUserDetailsResponse) { const confirmed = await this.platformUtilsService.showDialog( this.i18nService.t('removeUserConfirmation'), user.name || user.email, diff --git a/src/app/organizations/manage/user-groups.component.html b/src/app/organizations/manage/user-groups.component.html new file mode 100644 index 0000000000..b2089b2e10 --- /dev/null +++ b/src/app/organizations/manage/user-groups.component.html @@ -0,0 +1,49 @@ + diff --git a/src/app/organizations/manage/user-groups.component.ts b/src/app/organizations/manage/user-groups.component.ts new file mode 100644 index 0000000000..c913b71547 --- /dev/null +++ b/src/app/organizations/manage/user-groups.component.ts @@ -0,0 +1,79 @@ +import { + Component, + EventEmitter, + Input, + OnInit, + Output, +} from '@angular/core'; + +import { ToasterService } from 'angular2-toaster'; +import { Angulartics2 } from 'angulartics2'; + +import { ApiService } from 'jslib/abstractions/api.service'; +import { I18nService } from 'jslib/abstractions/i18n.service'; + +import { OrganizationUserUpdateGroupsRequest } from 'jslib/models/request/organizationUserUpdateGroupsRequest'; +import { GroupResponse } from 'jslib/models/response/groupResponse'; + +@Component({ + selector: 'app-user-groups', + templateUrl: 'user-groups.component.html', +}) +export class UserGroupsComponent implements OnInit { + @Input() name: string; + @Input() organizationUserId: string; + @Input() organizationId: string; + @Output() onSavedUser = new EventEmitter(); + + loading = true; + groups: GroupResponse[] = []; + formPromise: Promise; + + constructor(private apiService: ApiService, private i18nService: I18nService, + private analytics: Angulartics2, private toasterService: ToasterService) { } + + async ngOnInit() { + const groupsResponse = await this.apiService.getGroups(this.organizationId); + this.groups = groupsResponse.data.map((r) => r); + + try { + const userGroups = await this.apiService.getOrganizationUserGroups( + this.organizationId, this.organizationUserId); + if (userGroups != null && this.groups != null) { + userGroups.forEach((ug) => { + const group = this.groups.filter((g) => g.id === ug); + if (group != null && group.length > 0) { + (group[0] as any).checked = true; + } + }); + } + } catch { } + + this.loading = false; + } + + check(g: GroupResponse, select?: boolean) { + (g as any).checked = select == null ? !(g as any).checked : select; + if (!(g as any).checked) { + (g as any).readOnly = false; + } + } + + selectAll(select: boolean) { + this.groups.forEach((g) => this.check(g, select)); + } + + async submit() { + const request = new OrganizationUserUpdateGroupsRequest(); + request.groupIds = this.groups.filter((g) => (g as any).checked).map((g) => g.id); + + try { + this.formPromise = this.apiService.putOrganizationUserGroups(this.organizationId, this.organizationUserId, + request); + await this.formPromise; + this.analytics.eventTrack.next({ action: 'Edited User Groups' }); + this.toasterService.popAsync('success', null, this.i18nService.t('editedGroupsForUser', this.name)); + this.onSavedUser.emit(); + } catch { } + } +} diff --git a/src/locales/en/messages.json b/src/locales/en/messages.json index f8ca02d88d..4646324dc8 100644 --- a/src/locales/en/messages.json +++ b/src/locales/en/messages.json @@ -2048,6 +2048,9 @@ "groupAccess": { "message": "Group Access" }, + "groupAccessUserDesc": { + "message": "Edit the groups that this user belongs to." + }, "invitedUsers": { "message": "Invited user(s)." }