diff --git a/src/portal/src/app/base/left-side-nav/group/add-group-modal/add-group-modal.component.spec.ts b/src/portal/src/app/base/left-side-nav/group/add-group-modal/add-group-modal.component.spec.ts
index 1c50479f2..e1877fe3a 100644
--- a/src/portal/src/app/base/left-side-nav/group/add-group-modal/add-group-modal.component.spec.ts
+++ b/src/portal/src/app/base/left-side-nav/group/add-group-modal/add-group-modal.component.spec.ts
@@ -1,14 +1,11 @@
import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing';
-import { ClarityModule } from '@clr/angular';
-import { TranslateModule } from '@ngx-translate/core';
-import { CUSTOM_ELEMENTS_SCHEMA, ChangeDetectorRef } from '@angular/core';
-import { FormsModule } from '@angular/forms';
-import { GroupService } from "../group.service";
+import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { MessageHandlerService } from "../../../../shared/services/message-handler.service";
import { SessionService } from "../../../../shared/services/session.service";
import { AppConfigService } from "../../../../services/app-config.service";
import { AddGroupModalComponent } from './add-group-modal.component';
-import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
+import { UsergroupService } from "../../../../../../ng-swagger-gen/services/usergroup.service";
+import { SharedTestingModule } from "../../../../shared/shared.module";
describe('AddGroupModalComponent', () => {
let component: AddGroupModalComponent;
@@ -36,20 +33,16 @@ describe('AddGroupModalComponent', () => {
TestBed.configureTestingModule({
declarations: [AddGroupModalComponent],
imports: [
- ClarityModule,
- FormsModule,
- BrowserAnimationsModule,
- TranslateModule.forRoot()
+ SharedTestingModule
],
schemas: [
CUSTOM_ELEMENTS_SCHEMA
],
providers: [
- ChangeDetectorRef,
{ provide: MessageHandlerService, useValue: fakeMessageHandlerService },
{ provide: SessionService, useValue: fakeSessionService },
{ provide: AppConfigService, useValue: fakeAppConfigService },
- { provide: GroupService, useValue: fakeGroupService },
+ { provide: UsergroupService, useValue: fakeGroupService },
]
})
.compileComponents();
diff --git a/src/portal/src/app/base/left-side-nav/group/add-group-modal/add-group-modal.component.ts b/src/portal/src/app/base/left-side-nav/group/add-group-modal/add-group-modal.component.ts
index 8f4d4188a..d9e312df5 100644
--- a/src/portal/src/app/base/left-side-nav/group/add-group-modal/add-group-modal.component.ts
+++ b/src/portal/src/app/base/left-side-nav/group/add-group-modal/add-group-modal.component.ts
@@ -1,14 +1,12 @@
-
import { finalize } from 'rxjs/operators';
-import { Subscription } from "rxjs";
-import { Component, OnInit, EventEmitter, Output, ChangeDetectorRef, OnDestroy, ViewChild } from "@angular/core";
+import { Component, OnInit, EventEmitter, Output, OnDestroy, ViewChild } from "@angular/core";
import { NgForm } from "@angular/forms";
-import { GroupService } from "../group.service";
import { MessageHandlerService } from "../../../../shared/services/message-handler.service";
import { SessionService } from "../../../../shared/services/session.service";
-import { UserGroup } from "../group";
import { AppConfigService } from "../../../../services/app-config.service";
import { GroupType } from "../../../../shared/entities/shared.const";
+import { UserGroup } from 'ng-swagger-gen/models/user-group';
+import { UsergroupService } from "../../../../../../ng-swagger-gen/services/usergroup.service";
@Component({
selector: "hbr-add-group-modal",
@@ -21,9 +19,6 @@ export class AddGroupModalComponent implements OnInit, OnDestroy {
dnTooltip = 'TOOLTIP.ITEM_REQUIRED';
group: UserGroup;
-
- formChangeSubscription: Subscription;
-
@ViewChild('groupForm', { static: true })
groupForm: NgForm;
@@ -38,8 +33,7 @@ export class AddGroupModalComponent implements OnInit, OnDestroy {
private session: SessionService,
private msgHandler: MessageHandlerService,
private appConfigService: AppConfigService,
- private groupService: GroupService,
- private cdr: ChangeDetectorRef
+ private groupService: UsergroupService,
) { }
ngOnInit() {
@@ -52,7 +46,9 @@ export class AddGroupModalComponent implements OnInit, OnDestroy {
if (this.appConfigService.isOidcMode()) {
this.isOidcMode = true;
}
- this.group = new UserGroup(this.isLdapMode ? GroupType.LDAP_TYPE : this.isHttpAuthMode ? GroupType.HTTP_TYPE : GroupType.OIDC_TYPE);
+ this.group = {
+ group_type: this.isLdapMode ? GroupType.LDAP_TYPE : this.isHttpAuthMode ? GroupType.HTTP_TYPE : GroupType.OIDC_TYPE
+ };
}
@@ -88,8 +84,9 @@ export class AddGroupModalComponent implements OnInit, OnDestroy {
createGroup() {
let groupCopy = Object.assign({}, this.group);
- this.groupService
- .createGroup(groupCopy).pipe(
+ this.groupService.createUserGroup({
+ usergroup: groupCopy
+ }).pipe(
finalize(() => this.close()))
.subscribe(
res => {
@@ -103,7 +100,10 @@ export class AddGroupModalComponent implements OnInit, OnDestroy {
editGroup() {
let groupCopy = Object.assign({}, this.group);
this.groupService
- .editGroup(groupCopy).pipe(
+ .updateUserGroup({
+ groupId: groupCopy.id,
+ usergroup: groupCopy
+ }).pipe(
finalize(() => this.close()))
.subscribe(
res => {
@@ -115,7 +115,9 @@ export class AddGroupModalComponent implements OnInit, OnDestroy {
}
resetGroup() {
- this.group = new UserGroup(this.isLdapMode ? GroupType.LDAP_TYPE : this.isHttpAuthMode ? GroupType.HTTP_TYPE : GroupType.OIDC_TYPE);
+ this.group = {
+ group_type: this.isLdapMode ? GroupType.LDAP_TYPE : this.isHttpAuthMode ? GroupType.HTTP_TYPE : GroupType.OIDC_TYPE
+ };
this.groupForm.reset();
}
}
diff --git a/src/portal/src/app/base/left-side-nav/group/group.component.html b/src/portal/src/app/base/left-side-nav/group/group.component.html
index 5039a76a9..906604c01 100644
--- a/src/portal/src/app/base/left-side-nav/group/group.component.html
+++ b/src/portal/src/app/base/left-side-nav/group/group.component.html
@@ -1,4 +1,4 @@
-
+
{{'GROUP.GROUP' | translate}}
@@ -9,7 +9,7 @@
-
+
@@ -23,21 +23,22 @@
{{'GROUP.TYPE' | translate}}
{{'GROUP.DN' | translate}}
-
+
{{group.group_name}}
{{groupToSring(group.group_type) | translate}}
{{group.ldap_group_dn}}
-
-
+
+ {{"PAGINATION.PAGE_SIZE" | translate}}
+
{{pagination.firstItem + 1}} - {{pagination.lastItem + 1}} {{'GROUP.OF' | translate}}
- {{groups?.length}} {{'GROUP.ITEMS' | translate}}
+ {{totalCount}} {{'GROUP.ITEMS' | translate}}
-
+
diff --git a/src/portal/src/app/base/left-side-nav/group/group.component.scss b/src/portal/src/app/base/left-side-nav/group/group.component.scss
index 0d3b56629..13349265b 100644
--- a/src/portal/src/app/base/left-side-nav/group/group.component.scss
+++ b/src/portal/src/app/base/left-side-nav/group/group.component.scss
@@ -39,7 +39,9 @@
.rightPos {
position: absolute;
right: 20px;
- margin-top: -7px;
- height: 32px;
+ height:32px;
z-index: 100;
-}
\ No newline at end of file
+}
+.relative {
+ position: relative;
+}
diff --git a/src/portal/src/app/base/left-side-nav/group/group.component.spec.ts b/src/portal/src/app/base/left-side-nav/group/group.component.spec.ts
index dc907d3ca..0a4244cf5 100644
--- a/src/portal/src/app/base/left-side-nav/group/group.component.spec.ts
+++ b/src/portal/src/app/base/left-side-nav/group/group.component.spec.ts
@@ -1,16 +1,17 @@
import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing';
import { GroupComponent } from './group.component';
-import { ClarityModule } from '@clr/angular';
-import { TranslateModule, TranslateService } from '@ngx-translate/core';
-import { FormsModule } from '@angular/forms';
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { SessionService } from "../../../shared/services/session.service";
-import { GroupService } from "./group.service";
import { of } from "rxjs";
import { MessageHandlerService } from '../../../shared/services/message-handler.service';
import { AppConfigService } from '../../../services/app-config.service';
import { OperationService } from "../../../shared/components/operation/operation.service";
import { ConfirmationDialogService } from "../../global-confirmation-dialog/confirmation-dialog.service";
+import { UsergroupService } from "../../../../../ng-swagger-gen/services/usergroup.service";
+import { SharedTestingModule } from "../../../shared/shared.module";
+import { HttpHeaders, HttpResponse } from "@angular/common/http";
+import { delay } from "rxjs/operators";
+import { UserGroup } from "../../../../../ng-swagger-gen/models/user-group";
describe('GroupComponent', () => {
let component: GroupComponent;
@@ -18,12 +19,16 @@ describe('GroupComponent', () => {
let fakeMessageHandlerService = null;
let fakeOperationService = null;
let fakeGroupService = {
- getUserGroups: function () {
- return of([{
- group_name: ''
- }, {
- group_name: 'abc'
- }]);
+ listUserGroupsResponse: function () {
+ const res: HttpResponse
> = new HttpResponse>({
+ headers: new HttpHeaders({'x-total-count': '3'}),
+ body: [{
+ group_name: ''
+ }, {
+ group_name: 'abc'
+ }]
+ });
+ return of(res).pipe(delay(0));
}
};
let fakeConfirmationDialogService = {
@@ -47,18 +52,15 @@ describe('GroupComponent', () => {
TestBed.configureTestingModule({
declarations: [GroupComponent],
imports: [
- ClarityModule,
- FormsModule,
- TranslateModule.forRoot()
+ SharedTestingModule
],
schemas: [
CUSTOM_ELEMENTS_SCHEMA
],
providers: [
- TranslateService,
{ provide: MessageHandlerService, useValue: fakeMessageHandlerService },
{ provide: OperationService, useValue: fakeOperationService },
- { provide: GroupService, useValue: fakeGroupService },
+ { provide: UsergroupService, useValue: fakeGroupService },
{ provide: ConfirmationDialogService, useValue: fakeConfirmationDialogService },
{ provide: SessionService, useValue: fakeSessionService },
{ provide: AppConfigService, useValue: fakeAppConfigService }
diff --git a/src/portal/src/app/base/left-side-nav/group/group.component.ts b/src/portal/src/app/base/left-side-nav/group/group.component.ts
index fbfdbd5bb..a84b9a8ce 100644
--- a/src/portal/src/app/base/left-side-nav/group/group.component.ts
+++ b/src/portal/src/app/base/left-side-nav/group/group.component.ts
@@ -1,11 +1,9 @@
import { of, Subscription, forkJoin } from "rxjs";
-import { flatMap, catchError } from "rxjs/operators";
+import { flatMap, catchError, finalize, debounceTime, switchMap, filter } from "rxjs/operators";
import { SessionService } from "../../../shared/services/session.service";
import { TranslateService } from "@ngx-translate/core";
import { Component, OnInit, ViewChild, OnDestroy } from "@angular/core";
import { AddGroupModalComponent } from "./add-group-modal/add-group-modal.component";
-import { UserGroup } from "./group";
-import { GroupService } from "./group.service";
import { MessageHandlerService } from "../../../shared/services/message-handler.service";
import { throwError as observableThrowError } from "rxjs";
import { AppConfigService } from '../../../services/app-config.service';
@@ -20,6 +18,11 @@ import {
import { ConfirmationDialogService } from "../../global-confirmation-dialog/confirmation-dialog.service";
import { errorHandler } from "../../../shared/units/shared.utils";
import { ConfirmationMessage } from "../../global-confirmation-dialog/confirmation-message";
+import { ClrDatagridStateInterface } from "@clr/angular";
+import { DEFAULT_PAGE_SIZE } from "../../../shared/units/utils";
+import { UsergroupService } from "../../../../../ng-swagger-gen/services/usergroup.service";
+import { UserGroup } from "../../../../../ng-swagger-gen/models/user-group";
+import { FilterComponent } from "../../../shared/components/filter/filter.component";
@Component({
selector: "app-group",
@@ -27,25 +30,26 @@ import { ConfirmationMessage } from "../../global-confirmation-dialog/confirmati
styleUrls: ["./group.component.scss"]
})
export class GroupComponent implements OnInit, OnDestroy {
- searchTerm = "";
loading = true;
groups: UserGroup[] = [];
- currentPage = 1;
- totalCount = 0;
+ currentPage: number = 1;
+ totalCount: number = 0;
+ pageSize: number = DEFAULT_PAGE_SIZE;
selectedGroups: UserGroup[] = [];
currentTerm = "";
delSub: Subscription;
batchOps = 'idle';
- batchInfos = new Map();
isLdapMode: boolean;
@ViewChild(AddGroupModalComponent) newGroupModal: AddGroupModalComponent;
-
+ searchSub: Subscription;
+ @ViewChild(FilterComponent, {static: true})
+ filterComponent: FilterComponent;
constructor(
private operationService: OperationService,
private translate: TranslateService,
private operateDialogService: ConfirmationDialogService,
- private groupService: GroupService,
+ private groupService: UsergroupService,
private msgHandler: MessageHandlerService,
private session: SessionService,
private translateService: TranslateService,
@@ -53,7 +57,6 @@ export class GroupComponent implements OnInit, OnDestroy {
) { }
ngOnInit() {
- this.loadData();
if (this.appConfigService.isLdapMode()) {
this.isLdapMode = true;
}
@@ -70,25 +73,87 @@ export class GroupComponent implements OnInit, OnDestroy {
}
}
);
+ if (!this.searchSub) {
+ this.searchSub = this.filterComponent.filterTerms.pipe(
+ filter(groupName => !!groupName),
+ debounceTime(500),
+ switchMap(groupName => {
+ this.currentPage = 1;
+ this.selectedGroups = [];
+ this.loading = true;
+ return this.groupService.searchUserGroupsResponse({
+ groupname: groupName,
+ pageSize: this.pageSize,
+ page: this.currentPage
+ })
+ .pipe(finalize(() => {
+ this.loading = false;
+ }));
+ })).subscribe(response => {
+ this.totalCount = Number.parseInt(
+ response.headers.get('x-total-count'), 10
+ );
+ this.groups = response.body as UserGroup[];
+ }, error => {
+ this.msgHandler.handleError(error);
+ });
+ }
}
ngOnDestroy(): void {
this.delSub.unsubscribe();
+ if (this.searchSub) {
+ this.searchSub.unsubscribe();
+ this.searchSub = null;
+ }
}
refresh(): void {
+ this.currentPage = 1;
+ this.selectedGroups = [];
+ this.currentTerm = '';
+ this.filterComponent.currentValue = '';
this.loadData();
}
- loadData(): void {
+ loadData(state?: ClrDatagridStateInterface): void {
+ if (state && state.page) {
+ this.pageSize = state.page.size;
+ }
this.loading = true;
- this.groupService.getUserGroups().subscribe(groups => {
- this.groups = groups.filter(group => {
- if (!group.group_name) { group.group_name = ''; }
- return group.group_name.includes(this.searchTerm);
- }
- );
- this.loading = false;
- });
+ if (this.currentTerm) {
+ this.groupService.searchUserGroupsResponse({
+ groupname: encodeURIComponent(this.currentTerm),
+ page: this.currentPage,
+ pageSize: this.pageSize
+ })
+ .pipe(finalize(() => this.loading = false))
+ .subscribe(
+ response => {
+ this.totalCount = Number.parseInt(
+ response.headers.get('x-total-count'), 10
+ );
+ this.groups = response.body as UserGroup[];
+ },
+ err => {
+ this.msgHandler.error(err);
+ });
+ } else {
+ this.groupService.listUserGroupsResponse({
+ page: this.currentPage,
+ pageSize: this.pageSize
+ })
+ .pipe(finalize(() => this.loading = false))
+ .subscribe(
+ response => {
+ this.totalCount = Number.parseInt(
+ response.headers.get('x-total-count'), 10
+ );
+ this.groups = response.body as UserGroup[];
+ },
+ err => {
+ this.msgHandler.error(err);
+ });
+ }
}
addGroup(): void {
@@ -130,7 +195,9 @@ export class GroupComponent implements OnInit, OnDestroy {
this.operationService.publishInfo(operMessage);
return this.groupService
- .deleteGroup(group.id)
+ .deleteUserGroup({
+ groupId: group.id
+ })
.pipe(flatMap(response => {
return this.translate.get("BATCH.DELETED_SUCCESS").pipe(flatMap(res => {
operateChanges(operMessage, OperationState.success);
@@ -169,8 +236,10 @@ export class GroupComponent implements OnInit, OnDestroy {
}
doFilter(groupName: string): void {
- this.searchTerm = groupName;
- this.loadData();
+ if (!groupName) {
+ this.currentTerm = groupName;
+ this.loadData();
+ }
}
get canAddGroup(): boolean {
return this.session.currentUser.has_admin_role;
diff --git a/src/portal/src/app/base/left-side-nav/group/group.service.spec.ts b/src/portal/src/app/base/left-side-nav/group/group.service.spec.ts
deleted file mode 100644
index d609acc67..000000000
--- a/src/portal/src/app/base/left-side-nav/group/group.service.spec.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-import { TestBed, inject } from '@angular/core/testing';
-import { HttpClientTestingModule } from '@angular/common/http/testing';
-import { GroupService } from './group.service';
-
-describe('GroupService', () => {
- beforeEach(() => {
- TestBed.configureTestingModule({
- providers: [GroupService],
- imports: [
- HttpClientTestingModule
- ]
- });
- });
-
- it('should be created', inject([GroupService], (service: GroupService) => {
- expect(service).toBeTruthy();
- }));
-});
diff --git a/src/portal/src/app/base/left-side-nav/group/group.service.ts b/src/portal/src/app/base/left-side-nav/group/group.service.ts
deleted file mode 100644
index 4d042473a..000000000
--- a/src/portal/src/app/base/left-side-nav/group/group.service.ts
+++ /dev/null
@@ -1,67 +0,0 @@
-import {throwError as observableThrowError, Observable} from "rxjs";
-import {catchError, map} from 'rxjs/operators';
-import { Injectable } from "@angular/core";
-import { HttpClient } from "@angular/common/http";
-import { UserGroup } from "./group";
-import { CURRENT_BASE_HREF, HTTP_GET_OPTIONS, HTTP_JSON_OPTIONS } from "../../../shared/units/utils";
-
-const userGroupEndpoint = CURRENT_BASE_HREF + "/usergroups";
-const ldapGroupSearchEndpoint = CURRENT_BASE_HREF + "/ldap/groups/search?groupname=";
-
-@Injectable({
- providedIn: 'root',
-})
-export class GroupService {
- constructor(private http: HttpClient) {}
-
- private handleErrorObservable(error: Response | any) {
- console.error(error.error || error);
- return observableThrowError(error.error || error);
- }
-
- getUserGroups(): Observable {
- return this.http.get(userGroupEndpoint, HTTP_GET_OPTIONS).pipe(
- map(response => {
- return response || [];
- }),
- catchError(error => {
- return this.handleErrorObservable(error);
- }), );
- }
-
- createGroup(group: UserGroup): Observable {
- return this.http
- .post(userGroupEndpoint, group, HTTP_JSON_OPTIONS).pipe(
- map(response => {
- return response || [];
- }),
- catchError(this.handleErrorObservable), );
- }
-
- editGroup(group: UserGroup): Observable {
- return this.http
- .put(`${userGroupEndpoint}/${group.id}`, group, HTTP_JSON_OPTIONS).pipe(
- map(response => {
- return response || [];
- }),
- catchError(this.handleErrorObservable), );
- }
-
- deleteGroup(group_id: number): Observable {
- return this.http
- .delete(`${userGroupEndpoint}/${group_id}`).pipe(
- map(response => {
- return response || [];
- }),
- catchError(this.handleErrorObservable), );
- }
-
- searchGroup(group_name: string): Observable {
- return this.http
- .get(`${ldapGroupSearchEndpoint}${group_name}`, HTTP_GET_OPTIONS).pipe(
- map(response => {
- return response || [];
- }),
- catchError(this.handleErrorObservable), );
- }
-}
diff --git a/src/portal/src/app/base/left-side-nav/group/group.ts b/src/portal/src/app/base/left-side-nav/group/group.ts
deleted file mode 100644
index 2c3e417ba..000000000
--- a/src/portal/src/app/base/left-side-nav/group/group.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-export class UserGroup {
- id?: number;
- group_name?: string;
- group_type: number;
- ldap_group_dn?: string;
-
- constructor(groupType) {
- {
- this.group_type = groupType;
- }
- }
-}
diff --git a/src/portal/src/app/base/left-side-nav/user/user.component.html b/src/portal/src/app/base/left-side-nav/user/user.component.html
index 41784d06f..5cef53c99 100644
--- a/src/portal/src/app/base/left-side-nav/user/user.component.html
+++ b/src/portal/src/app/base/left-side-nav/user/user.component.html
@@ -1,4 +1,4 @@
-
+
{{'SIDE_NAV.SYSTEM_MGMT.USER' | translate}}
diff --git a/src/portal/src/app/base/left-side-nav/user/user.component.scss b/src/portal/src/app/base/left-side-nav/user/user.component.scss
index e1d94b136..c83c419b1 100644
--- a/src/portal/src/app/base/left-side-nav/user/user.component.scss
+++ b/src/portal/src/app/base/left-side-nav/user/user.component.scss
@@ -42,8 +42,6 @@
height:32px;
z-index: 100;
}
-::ng-deep harbor-user{
- >div{
- position: relative;
- }
-}
\ No newline at end of file
+.relative {
+ position: relative;
+}