diff --git a/src/app/groups/common-resolvers/group-data-and-template.resolver.ts b/src/app/groups/common-resolvers/group-data-and-template.resolver.ts new file mode 100644 index 000000000..d54266aad --- /dev/null +++ b/src/app/groups/common-resolvers/group-data-and-template.resolver.ts @@ -0,0 +1,32 @@ +/** Angular Imports */ +import { Injectable } from '@angular/core'; +import { Resolve, ActivatedRouteSnapshot } from '@angular/router'; + +/** rxjs Imports */ +import { Observable } from 'rxjs'; + +/** Custom Services */ +import { GroupsService } from '../groups.service'; + +/** + * Groups data and template resolver. + */ +@Injectable() +export class GroupDataAndTemplateResolver implements Resolve { + + /** + * @param {GroupsService} GroupsService Groups service. + */ + constructor(private groupsService: GroupsService) { } + + /** + * Returns the Groups data and template. + * @param {ActivatedRouteSnapshot} route Route Snapshot + * @returns {Observable} + */ + resolve(route: ActivatedRouteSnapshot): Observable { + const groupId = route.paramMap.get('groupId'); + return this.groupsService.getGroupData(groupId, 'true'); + } + +} diff --git a/src/app/groups/groups-routing.module.ts b/src/app/groups/groups-routing.module.ts index 8949ef702..4d2bc90f7 100644 --- a/src/app/groups/groups-routing.module.ts +++ b/src/app/groups/groups-routing.module.ts @@ -16,6 +16,7 @@ import { NotesTabComponent } from './groups-view/notes-tab/notes-tab.component'; import { CommitteeTabComponent } from './groups-view/committee-tab/committee-tab.component'; import { CreateGroupComponent } from './create-group/create-group.component'; import { DatatableTabsComponent } from './groups-view/datatable-tabs/datatable-tabs.component'; +import { AddRoleComponent } from './groups-view/add-role/add-role.component'; /** Custom Resolvers */ import { GroupViewResolver } from './common-resolvers/group-view.resolver'; @@ -25,6 +26,7 @@ import { GroupNotesResolver } from './common-resolvers/group-notes.resolver'; import { OfficesResolver } from 'app/accounting/common-resolvers/offices.resolver'; import { GroupDatatablesResolver } from './common-resolvers/group-datatables.resolver'; import { GroupDatatableResolver } from './common-resolvers/group-datatable.resolver'; +import { GroupDataAndTemplateResolver } from './common-resolvers/group-data-and-template.resolver'; /** Groups Routes */ const routes: Routes = [ @@ -94,6 +96,23 @@ const routes: Routes = [ } ] }, + { + path: 'committee', + children: [ + { + path: '', + redirectTo: '../committee', pathMatch: 'prefix' + }, + { + path: 'add-role', + data: { title: extract('Add Role'), breadcrumb: 'Add Role', routeParamBreadcrumb: false }, + component: AddRoleComponent, + resolve: { + groupAndTemplateData: GroupDataAndTemplateResolver + } + }, + ] + }, { path: 'savingsaccounts', loadChildren: '../savings/savings.module#SavingsModule' @@ -118,6 +137,7 @@ const routes: Routes = [ GroupSummaryResolver, GroupNotesResolver, GroupDatatablesResolver, - GroupDatatableResolver] + GroupDatatableResolver, + GroupDataAndTemplateResolver] }) export class GroupsRoutingModule { } diff --git a/src/app/groups/groups-view/add-role/add-role.component.html b/src/app/groups/groups-view/add-role/add-role.component.html new file mode 100644 index 000000000..dd8d344f4 --- /dev/null +++ b/src/app/groups/groups-view/add-role/add-role.component.html @@ -0,0 +1,48 @@ +
+ + + +
+ + + +
+ + + Client + + + {{ client.displayName }} + + + + Client Member is required + + + + + Role + + + {{ role.name }} + + + + Role is required + + + +
+ +
+ + + + + + +
+ +
+ +
diff --git a/src/app/groups/groups-view/add-role/add-role.component.scss b/src/app/groups/groups-view/add-role/add-role.component.scss new file mode 100644 index 000000000..d774f68da --- /dev/null +++ b/src/app/groups/groups-view/add-role/add-role.component.scss @@ -0,0 +1,3 @@ +.container { + max-width: 37rem; +} diff --git a/src/app/groups/groups-view/add-role/add-role.component.spec.ts b/src/app/groups/groups-view/add-role/add-role.component.spec.ts new file mode 100644 index 000000000..3efbbf4bf --- /dev/null +++ b/src/app/groups/groups-view/add-role/add-role.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { AddRoleComponent } from './add-role.component'; + +describe('AddRoleComponent', () => { + let component: AddRoleComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ AddRoleComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(AddRoleComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/groups/groups-view/add-role/add-role.component.ts b/src/app/groups/groups-view/add-role/add-role.component.ts new file mode 100644 index 000000000..59c05815d --- /dev/null +++ b/src/app/groups/groups-view/add-role/add-role.component.ts @@ -0,0 +1,68 @@ +/** Angular Imports */ +import { Component, OnInit } from '@angular/core'; +import { FormGroup, FormBuilder, Validators } from '@angular/forms'; +import { ActivatedRoute, Router } from '@angular/router'; + +/** Custom Services */ +import { GroupsService } from '../../groups.service'; + +/** + * Groups Add Role Component + */ +@Component({ + selector: 'mifosx-add-role', + templateUrl: './add-role.component.html', + styleUrls: ['./add-role.component.scss'] +}) +export class AddRoleComponent implements OnInit { + + /** Groups Add Role Form */ + groupsAddRoleForm: FormGroup; + /** Client Menmber Data */ + clientMemberData: any; + /** Role Data */ + roleData: any; + /** Groups Account and Template Data */ + groupAndTemplateData: any; + + /** + * @param {FormBuilder} formBuilder Form Builder + * @param {GroupsService} groupsService Groups Service + * @param {ActivatedRoute} route Activated Route + * @param {Router} router Router + */ + constructor(private formBuilder: FormBuilder, + private groupsService: GroupsService, + private route: ActivatedRoute, + private router: Router) { + this.route.data.subscribe((data: { groupAndTemplateData: any }) => { + this.groupAndTemplateData = data.groupAndTemplateData; + }); + } + + ngOnInit() { + this.clientMemberData = this.groupAndTemplateData.activeClientMembers; + this.roleData = this.groupAndTemplateData.availableRoles; + this.createGroupsAddRoleForm(); + } + + /** + * Creates the add group role form. + */ + createGroupsAddRoleForm() { + this.groupsAddRoleForm = this.formBuilder.group({ + 'clientId': ['', Validators.required], + 'role': ['', Validators.required] + }); + } + + /** + * Submits the form and assigns the group role. + */ + submit() { + this.groupsService.executeGroupCommand(this.groupAndTemplateData.id, 'assignRole', this.groupsAddRoleForm.value).subscribe(() => { + this.router.navigate(['../'], { relativeTo: this.route }); + }); + } + +} diff --git a/src/app/groups/groups-view/committee-tab/committee-tab.component.html b/src/app/groups/groups-view/committee-tab/committee-tab.component.html index 54d509033..91bef37b0 100644 --- a/src/app/groups/groups-view/committee-tab/committee-tab.component.html +++ b/src/app/groups/groups-view/committee-tab/committee-tab.component.html @@ -6,15 +6,14 @@
- +
@@ -35,8 +34,8 @@
Name Actions - diff --git a/src/app/groups/groups-view/committee-tab/committee-tab.component.ts b/src/app/groups/groups-view/committee-tab/committee-tab.component.ts index 0d10dc58e..9c9bd5b56 100644 --- a/src/app/groups/groups-view/committee-tab/committee-tab.component.ts +++ b/src/app/groups/groups-view/committee-tab/committee-tab.component.ts @@ -1,6 +1,13 @@ /** Angular Imports */ -import { Component } from '@angular/core'; +import { Component, ViewChild } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; +import { MatDialog, MatTable } from '@angular/material'; + +/** Custom Dialogs */ +import { UnassignRoleDialogComponent } from '../custom-dialogs/unassign-role-dialog/unassign-role-dialog.component'; + +/** Custom Services */ +import { GroupsService } from 'app/groups/groups.service'; /** * Groups Committee Tab Component @@ -15,18 +22,46 @@ export class CommitteeTabComponent { /** Group Status */ groupStatus: any; /** Group Roles Data */ - groupRolesData: any; + groupRolesData: any[]; + /** Groups View Data */ + groupViewData: any; /** Columns to be Displayed for client members table */ groupRolesColumns: string[] = ['Name', 'Role', 'Client Id', 'Actions']; + /** Roles Table */ + @ViewChild('rolesTable') rolesTableRef: MatTable; + /** * Fetches groups data from parent's `resolve`. - * @param {ActivatedRoute} route Activated Route. + * @param {ActivatedRoute} route Activated Route + * @param {GroupsService} groupsService Groups Service + * @param {MatDialog} dialog Mat Dialog */ - constructor(private route: ActivatedRoute) { + constructor(private route: ActivatedRoute, + private groupsService: GroupsService, + public dialog: MatDialog) { this.route.parent.data.subscribe((data: { groupViewData: any }) => { - this.groupRolesData = data.groupViewData.groupRoles; - this.groupStatus = data.groupViewData.status.value; + this.groupViewData = data.groupViewData; + this.groupRolesData = this.groupViewData.groupRoles; + this.groupStatus = this.groupViewData.status.value; + }); + } + /** + * Unassigns a client's role. + * @param {any} clientId Client Id + * @param {any} roleId Role Id + */ + unassignRole(clientId: any, roleId: any) { + const unAssignRoleDialogRef = this.dialog.open(UnassignRoleDialogComponent, { + data: { id: clientId } + }); + unAssignRoleDialogRef.afterClosed().subscribe((response: { confirm: any }) => { + if (response.confirm) { + const clientIndex = this.groupRolesData.findIndex((client: any) => client.clientId === clientId); + this.groupRolesData.splice(clientIndex, 1); + this.rolesTableRef.renderRows(); + this.groupsService.unAssignRoleCommand(this.groupViewData.id, roleId).subscribe(() => {}); + } }); } diff --git a/src/app/groups/groups-view/custom-dialogs/unassign-role-dialog/unassign-role-dialog.component.html b/src/app/groups/groups-view/custom-dialogs/unassign-role-dialog/unassign-role-dialog.component.html new file mode 100644 index 000000000..2ec98ad19 --- /dev/null +++ b/src/app/groups/groups-view/custom-dialogs/unassign-role-dialog/unassign-role-dialog.component.html @@ -0,0 +1,8 @@ +

Unassign Role

+
+

Are you sure you want to unassign role for client member with id: {{ data.id }} ?

+
+ + + + diff --git a/src/app/groups/groups-view/custom-dialogs/unassign-role-dialog/unassign-role-dialog.component.scss b/src/app/groups/groups-view/custom-dialogs/unassign-role-dialog/unassign-role-dialog.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/src/app/groups/groups-view/custom-dialogs/unassign-role-dialog/unassign-role-dialog.component.spec.ts b/src/app/groups/groups-view/custom-dialogs/unassign-role-dialog/unassign-role-dialog.component.spec.ts new file mode 100644 index 000000000..4b5605021 --- /dev/null +++ b/src/app/groups/groups-view/custom-dialogs/unassign-role-dialog/unassign-role-dialog.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { UnassignRoleDialogComponent } from './unassign-role-dialog.component'; + +describe('UnassignRoleDialogComponent', () => { + let component: UnassignRoleDialogComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ UnassignRoleDialogComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(UnassignRoleDialogComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/groups/groups-view/custom-dialogs/unassign-role-dialog/unassign-role-dialog.component.ts b/src/app/groups/groups-view/custom-dialogs/unassign-role-dialog/unassign-role-dialog.component.ts new file mode 100644 index 000000000..9bf099141 --- /dev/null +++ b/src/app/groups/groups-view/custom-dialogs/unassign-role-dialog/unassign-role-dialog.component.ts @@ -0,0 +1,22 @@ +/** Angular Imports */ +import { Component, Inject } from '@angular/core'; +import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material'; + +/** + * Unassign role dialog component. + */ +@Component({ + selector: 'mifosx-unassign-role-dialog', + templateUrl: './unassign-role-dialog.component.html', + styleUrls: ['./unassign-role-dialog.component.scss'] +}) +export class UnassignRoleDialogComponent { + + /** + * @param {MatDialogRef} dialogRef Component reference to dialog. + * @param {any} data. + */ + constructor(public dialogRef: MatDialogRef, + @Inject(MAT_DIALOG_DATA) public data: any) { } + +} diff --git a/src/app/groups/groups.module.ts b/src/app/groups/groups.module.ts index a191dd8b1..90b50a23e 100644 --- a/src/app/groups/groups.module.ts +++ b/src/app/groups/groups.module.ts @@ -18,6 +18,8 @@ import { CreateGroupComponent } from './create-group/create-group.component'; import { DatatableTabsComponent } from './groups-view/datatable-tabs/datatable-tabs.component'; import { SingleRowComponent } from './groups-view/datatable-tabs/single-row/single-row.component'; import { MultiRowComponent } from './groups-view/datatable-tabs/multi-row/multi-row.component'; +import { AddRoleComponent } from './groups-view/add-role/add-role.component'; +import { UnassignRoleDialogComponent } from './groups-view/custom-dialogs/unassign-role-dialog/unassign-role-dialog.component'; /** * Groups Module @@ -40,7 +42,12 @@ import { MultiRowComponent } from './groups-view/datatable-tabs/multi-row/multi- CreateGroupComponent, DatatableTabsComponent, SingleRowComponent, - MultiRowComponent + MultiRowComponent, + AddRoleComponent, + UnassignRoleDialogComponent + ], + entryComponents: [ + UnassignRoleDialogComponent ], providers: [DatePipe] }) diff --git a/src/app/groups/groups.service.ts b/src/app/groups/groups.service.ts index 889de7a50..9149911ca 100644 --- a/src/app/groups/groups.service.ts +++ b/src/app/groups/groups.service.ts @@ -13,6 +13,7 @@ import { map } from 'rxjs/operators'; providedIn: 'root' }) export class GroupsService { + /** * @param {HttpClient} http Http Client to send requests. */ @@ -36,153 +37,174 @@ export class GroupsService { // filterBy: name filterBy.forEach(function (filter: any) { if (filter.value) { - console.log(filter.value); httpParams = httpParams.set(filter.type, filter.value); } }); return this.http.get('/groups', { params: httpParams }); } - /** - * @param {number} officeId Office Id of office to get groups for. - * @returns {Observable} - */ - getGroupsByOfficeId(officeId: number): Observable { - const httpParams = new HttpParams().set('officeId', officeId.toString()); - return this.http.get('/groups', { params: httpParams } ); - } + /** + * @param {number} officeId Office Id of office to get groups for. + * @returns {Observable} + */ + getGroupsByOfficeId(officeId: number): Observable { + const httpParams = new HttpParams().set('officeId', officeId.toString()); + return this.http.get('/groups', { params: httpParams } ); + } - /** - * @param groupId Group Id of group to get data for. - * @returns {Observable} Group data. - */ - getGroupData(groupId: string): Observable { - const httpParams = new HttpParams().set('associations', 'all'); - return this.http.get(`/groups/${groupId}`, { params: httpParams }); - } + /** + * @param groupId Group Id of group to get data for. + * @returns {Observable} Group data. + */ + getGroupData(groupId: string, template?: string): Observable { + let httpParams = new HttpParams().set('associations', 'all'); + httpParams = template ? httpParams.set('template', template) : httpParams; + return this.http.get(`/groups/${groupId}`, { params: httpParams }); + } - /** - * @param groupId Group Id of group to get data for. - * @returns {Observable} Group Summary data. - */ - getGroupSummary(groupId: string): Observable { - const httpParams = new HttpParams().set('R_groupId', groupId) - .set('genericResultSet', 'false'); - return this.http.get(`/runreports/GroupSummaryCounts`, { params: httpParams }); - } + /** + * @param groupId Group Id of group to get data for. + * @returns {Observable} Group Summary data. + */ + getGroupSummary(groupId: string): Observable { + const httpParams = new HttpParams().set('R_groupId', groupId) + .set('genericResultSet', 'false'); + return this.http.get(`/runreports/GroupSummaryCounts`, { params: httpParams }); + } - /** - * @param groupId Group Id of group to get data for. - * @returns {Observable} Group Accounts data. - */ - getGroupAccountsData(groupId: string): Observable { - return this.http.get(`/groups/${groupId}/accounts`); - } + /** + * @param {string} groupId Group Id + * @param {string} command Command + * @param {any} roleId Role Id + * @returns {Observable} + */ + executeGroupCommand(groupId: string, command: string, data: any): Observable { + const httpParams = new HttpParams().set('command', command); + return this.http.post(`/groups/${groupId}`, data, { params: httpParams }); + } - /** - * @param groupId Group Id of group to get data for. - * @returns {Observable} Group Notes data. - */ - getGroupNotes(groupId: string): Observable { - return this.http.get(`/groups/${groupId}/notes`); - } + /** + * @param {string} groupId Group Id + * @param {any} roleId Role Id + * @returns {Observable} + */ + unAssignRoleCommand(groupId: string, roleId: any): Observable { + const httpParams = new HttpParams().set('command', 'unassignRole') + .set('roleId', roleId); + return this.http.post(`/groups/${groupId}`, {}, { params: httpParams }); + } - /** - * @param groupId Group Id of group to create note for. - * @param noteData Note Data. - * @returns {Observable} - */ - createGroupNote(groupId: string, noteData: any): Observable { - return this.http.post(`/groups/${groupId}/notes`, noteData); - } + /** + * @param groupId Group Id of group to get data for. + * @returns {Observable} Group Accounts data. + */ + getGroupAccountsData(groupId: string): Observable { + return this.http.get(`/groups/${groupId}/accounts`); + } - /** - * @param groupId Group Id of group to edit note for. - * @param noteId Note Id - * @param noteData Note Data - * @returns {Observable} - */ - editGroupNote(groupId: string, noteId: string, noteData: any): Observable { - return this.http.put(`/groups/${groupId}/notes/${noteId}`, noteData); - } + /** + * @param groupId Group Id of group to get data for. + * @returns {Observable} Group Notes data. + */ + getGroupNotes(groupId: string): Observable { + return this.http.get(`/groups/${groupId}/notes`); + } - /** - * @param groupId Group Id of group to delete note for. - * @param noteId Note Id - * @returns {Observable} - */ - deleteGroupNote(groupId: string, noteId: string): Observable { - return this.http.delete(`/groups/${groupId}/notes/${noteId}`); - } + /** + * @param groupId Group Id of group to create note for. + * @param noteData Note Data. + * @returns {Observable} + */ + createGroupNote(groupId: string, noteData: any): Observable { + return this.http.post(`/groups/${groupId}/notes`, noteData); + } - /** - * @returns {Observable} - */ - getGroupDatatables(): Observable { - const httpParams = new HttpParams().set('apptable', 'm_group'); - return this.http.get(`/datatables`, { params: httpParams }); - } + /** + * @param groupId Group Id of group to edit note for. + * @param noteId Note Id + * @param noteData Note Data + * @returns {Observable} + */ + editGroupNote(groupId: string, noteId: string, noteData: any): Observable { + return this.http.put(`/groups/${groupId}/notes/${noteId}`, noteData); + } - /** - * @param groupId Group Id of group to get datatable for. - * @param datatableName Data table name. - * @returns {Observable} - */ - getGroupDatatable(groupId: string, datatableName: string): Observable { - const httpParams = new HttpParams().set('genericResultSet', 'true'); - return this.http.get(`/datatables/${datatableName}/${groupId}`, { params: httpParams }); - } + /** + * @param groupId Group Id of group to delete note for. + * @param noteId Note Id + * @returns {Observable} + */ + deleteGroupNote(groupId: string, noteId: string): Observable { + return this.http.delete(`/groups/${groupId}/notes/${noteId}`); + } - /** - * @param groupId Group Id of group to get add datatable entry for. - * @param datatableName Data Table name. - * @param data Data. - * @returns {Observable} - */ - addGroupDatatableEntry(groupId: string, datatableName: string, data: any): Observable { - const httpParams = new HttpParams().set('genericResultSet', 'true'); - return this.http.post(`/datatables/${datatableName}/${groupId}`, data, { params: httpParams }); - } + /** + * @returns {Observable} + */ + getGroupDatatables(): Observable { + const httpParams = new HttpParams().set('apptable', 'm_group'); + return this.http.get(`/datatables`, { params: httpParams }); + } - /** - * @param groupId Group Id of group to get add datatable entry for. - * @param datatableName Data Table name. - * @param data Data. - * @returns {Observable} - */ - editGroupDatatableEntry(groupId: string, datatableName: string, data: any): Observable { - const httpParams = new HttpParams().set('genericResultSet', 'true'); - return this.http.put(`/datatables/${datatableName}/${groupId}`, data, { params: httpParams }); - } + /** + * @param groupId Group Id of group to get datatable for. + * @param datatableName Data table name. + * @returns {Observable} + */ + getGroupDatatable(groupId: string, datatableName: string): Observable { + const httpParams = new HttpParams().set('genericResultSet', 'true'); + return this.http.get(`/datatables/${datatableName}/${groupId}`, { params: httpParams }); + } - /** - * @param groupId Group Id of group to get add datatable entry for. - * @param datatableName Data Table name. - * @returns {Observable} - */ - deleteDatatableContent(groupId: string, datatableName: string): Observable { - const httpParams = new HttpParams().set('genericResultSet', 'true'); - return this.http.delete(`/datatables/${datatableName}/${groupId}`, { params: httpParams }); - } + /** + * @param groupId Group Id of group to get add datatable entry for. + * @param datatableName Data Table name. + * @param data Data. + * @returns {Observable} + */ + addGroupDatatableEntry(groupId: string, datatableName: string, data: any): Observable { + const httpParams = new HttpParams().set('genericResultSet', 'true'); + return this.http.post(`/datatables/${datatableName}/${groupId}`, data, { params: httpParams }); + } - /** - * @param {number} officeId Office Id of office to get staff for. - * @returns {Observable} - */ - getStaff(id: number): Observable { - const httpParams = new HttpParams() - .set('officeId', id.toString()) - .set('staffInSelectedOfficeOnly', 'true'); - return this.http.get('/groups/template', { params: httpParams }); - } + /** + * @param groupId Group Id of group to get add datatable entry for. + * @param datatableName Data Table name. + * @param data Data. + * @returns {Observable} + */ + editGroupDatatableEntry(groupId: string, datatableName: string, data: any): Observable { + const httpParams = new HttpParams().set('genericResultSet', 'true'); + return this.http.put(`/datatables/${datatableName}/${groupId}`, data, { params: httpParams }); + } - /** - * @param {any} group Group to be created. - * @returns {Observable} - */ - createGroup(group: any): Observable { - return this.http.post('/groups', group); - } + /** + * @param groupId Group Id of group to get add datatable entry for. + * @param datatableName Data Table name. + * @returns {Observable} + */ + deleteDatatableContent(groupId: string, datatableName: string): Observable { + const httpParams = new HttpParams().set('genericResultSet', 'true'); + return this.http.delete(`/datatables/${datatableName}/${groupId}`, { params: httpParams }); + } + /** + * @param {number} officeId Office Id of office to get staff for. + * @returns {Observable} + */ + getStaff(id: number): Observable { + const httpParams = new HttpParams() + .set('officeId', id.toString()) + .set('staffInSelectedOfficeOnly', 'true'); + return this.http.get('/groups/template', { params: httpParams }); + } + + /** + * @param {any} group Group to be created. + * @returns {Observable} + */ + createGroup(group: any): Observable { + return this.http.post('/groups', group); + } }