mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 01:54:15 +00:00
Merge pull request #1634 from 4Science/CST-5738
Add special groups list to the profile page
This commit is contained in:
@@ -12,13 +12,13 @@ import { AuthStatus } from './models/auth-status.model';
|
|||||||
import { ShortLivedToken } from './models/short-lived-token.model';
|
import { ShortLivedToken } from './models/short-lived-token.model';
|
||||||
import { URLCombiner } from '../url-combiner/url-combiner';
|
import { URLCombiner } from '../url-combiner/url-combiner';
|
||||||
import { RestRequest } from '../data/rest-request.model';
|
import { RestRequest } from '../data/rest-request.model';
|
||||||
|
import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstract service to send authentication requests
|
* Abstract service to send authentication requests
|
||||||
*/
|
*/
|
||||||
export abstract class AuthRequestService {
|
export abstract class AuthRequestService {
|
||||||
protected linkName = 'authn';
|
protected linkName = 'authn';
|
||||||
protected browseEndpoint = '';
|
|
||||||
protected shortlivedtokensEndpoint = 'shortlivedtokens';
|
protected shortlivedtokensEndpoint = 'shortlivedtokens';
|
||||||
|
|
||||||
constructor(protected halService: HALEndpointService,
|
constructor(protected halService: HALEndpointService,
|
||||||
@@ -27,14 +27,21 @@ export abstract class AuthRequestService {
|
|||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected fetchRequest(request: RestRequest): Observable<RemoteData<AuthStatus>> {
|
protected fetchRequest(request: RestRequest, ...linksToFollow: FollowLinkConfig<AuthStatus>[]): Observable<RemoteData<AuthStatus>> {
|
||||||
return this.rdbService.buildFromRequestUUID<AuthStatus>(request.uuid).pipe(
|
return this.rdbService.buildFromRequestUUID<AuthStatus>(request.uuid, ...linksToFollow).pipe(
|
||||||
getFirstCompletedRemoteData(),
|
getFirstCompletedRemoteData(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected getEndpointByMethod(endpoint: string, method: string): string {
|
protected getEndpointByMethod(endpoint: string, method: string, ...linksToFollow: FollowLinkConfig<AuthStatus>[]): string {
|
||||||
return isNotEmpty(method) ? `${endpoint}/${method}` : `${endpoint}`;
|
let url = isNotEmpty(method) ? `${endpoint}/${method}` : `${endpoint}`;
|
||||||
|
if (linksToFollow?.length > 0) {
|
||||||
|
linksToFollow.forEach((link: FollowLinkConfig<AuthStatus>, index: number) => {
|
||||||
|
url += ((index === 0) ? '?' : '&') + `embed=${link.name}`;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return url;
|
||||||
}
|
}
|
||||||
|
|
||||||
public postToEndpoint(method: string, body?: any, options?: HttpOptions): Observable<RemoteData<AuthStatus>> {
|
public postToEndpoint(method: string, body?: any, options?: HttpOptions): Observable<RemoteData<AuthStatus>> {
|
||||||
@@ -48,14 +55,14 @@ export abstract class AuthRequestService {
|
|||||||
distinctUntilChanged());
|
distinctUntilChanged());
|
||||||
}
|
}
|
||||||
|
|
||||||
public getRequest(method: string, options?: HttpOptions): Observable<RemoteData<AuthStatus>> {
|
public getRequest(method: string, options?: HttpOptions, ...linksToFollow: FollowLinkConfig<any>[]): Observable<RemoteData<AuthStatus>> {
|
||||||
return this.halService.getEndpoint(this.linkName).pipe(
|
return this.halService.getEndpoint(this.linkName).pipe(
|
||||||
filter((href: string) => isNotEmpty(href)),
|
filter((href: string) => isNotEmpty(href)),
|
||||||
map((endpointURL) => this.getEndpointByMethod(endpointURL, method)),
|
map((endpointURL) => this.getEndpointByMethod(endpointURL, method, ...linksToFollow)),
|
||||||
distinctUntilChanged(),
|
distinctUntilChanged(),
|
||||||
map((endpointURL: string) => new GetRequest(this.requestService.generateRequestId(), endpointURL, undefined, options)),
|
map((endpointURL: string) => new GetRequest(this.requestService.generateRequestId(), endpointURL, undefined, options)),
|
||||||
tap((request: GetRequest) => this.requestService.send(request)),
|
tap((request: GetRequest) => this.requestService.send(request)),
|
||||||
mergeMap((request: GetRequest) => this.fetchRequest(request)),
|
mergeMap((request: GetRequest) => this.fetchRequest(request, ...linksToFollow)),
|
||||||
distinctUntilChanged());
|
distinctUntilChanged());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -32,6 +32,8 @@ import { TranslateService } from '@ngx-translate/core';
|
|||||||
import { getMockTranslateService } from '../../shared/mocks/translate.service.mock';
|
import { getMockTranslateService } from '../../shared/mocks/translate.service.mock';
|
||||||
import { NotificationsServiceStub } from '../../shared/testing/notifications-service.stub';
|
import { NotificationsServiceStub } from '../../shared/testing/notifications-service.stub';
|
||||||
import { SetUserAsIdleAction, UnsetUserAsIdleAction } from './auth.actions';
|
import { SetUserAsIdleAction, UnsetUserAsIdleAction } from './auth.actions';
|
||||||
|
import { SpecialGroupDataMock, SpecialGroupDataMock$ } from '../../shared/testing/special-group.mock';
|
||||||
|
import { cold } from 'jasmine-marbles';
|
||||||
|
|
||||||
describe('AuthService test', () => {
|
describe('AuthService test', () => {
|
||||||
|
|
||||||
@@ -56,6 +58,13 @@ describe('AuthService test', () => {
|
|||||||
let linkService;
|
let linkService;
|
||||||
let hardRedirectService;
|
let hardRedirectService;
|
||||||
|
|
||||||
|
const AuthStatusWithSpecialGroups = Object.assign(new AuthStatus(), {
|
||||||
|
uuid: 'test',
|
||||||
|
authenticated: true,
|
||||||
|
okay: true,
|
||||||
|
specialGroups: SpecialGroupDataMock$
|
||||||
|
});
|
||||||
|
|
||||||
function init() {
|
function init() {
|
||||||
mockStore = jasmine.createSpyObj('store', {
|
mockStore = jasmine.createSpyObj('store', {
|
||||||
dispatch: {},
|
dispatch: {},
|
||||||
@@ -511,6 +520,19 @@ describe('AuthService test', () => {
|
|||||||
expect((authService as any).navigateToRedirectUrl).toHaveBeenCalled();
|
expect((authService as any).navigateToRedirectUrl).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('getSpecialGroupsFromAuthStatus', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
spyOn(authRequest, 'getRequest').and.returnValue(createSuccessfulRemoteDataObject$(AuthStatusWithSpecialGroups));
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should call navigateToRedirectUrl with no url', () => {
|
||||||
|
const expectRes = cold('(a|)', {
|
||||||
|
a: SpecialGroupDataMock
|
||||||
|
});
|
||||||
|
expect(authService.getSpecialGroupsFromAuthStatus()).toBeObservable(expectRes);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('when user is not logged in', () => {
|
describe('when user is not logged in', () => {
|
||||||
|
@@ -44,13 +44,18 @@ import {
|
|||||||
import { NativeWindowRef, NativeWindowService } from '../services/window.service';
|
import { NativeWindowRef, NativeWindowService } from '../services/window.service';
|
||||||
import { RouteService } from '../services/route.service';
|
import { RouteService } from '../services/route.service';
|
||||||
import { EPersonDataService } from '../eperson/eperson-data.service';
|
import { EPersonDataService } from '../eperson/eperson-data.service';
|
||||||
import { getAllSucceededRemoteDataPayload } from '../shared/operators';
|
import { getAllSucceededRemoteDataPayload, getFirstCompletedRemoteData } from '../shared/operators';
|
||||||
import { AuthMethod } from './models/auth.method';
|
import { AuthMethod } from './models/auth.method';
|
||||||
import { HardRedirectService } from '../services/hard-redirect.service';
|
import { HardRedirectService } from '../services/hard-redirect.service';
|
||||||
import { RemoteData } from '../data/remote-data';
|
import { RemoteData } from '../data/remote-data';
|
||||||
import { environment } from '../../../environments/environment';
|
import { environment } from '../../../environments/environment';
|
||||||
import { NotificationsService } from '../../shared/notifications/notifications.service';
|
import { NotificationsService } from '../../shared/notifications/notifications.service';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
|
import { buildPaginatedList, PaginatedList } from '../data/paginated-list.model';
|
||||||
|
import { Group } from '../eperson/models/group.model';
|
||||||
|
import { createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils';
|
||||||
|
import { PageInfo } from '../shared/page-info.model';
|
||||||
|
import { followLink } from '../../shared/utils/follow-link-config.model';
|
||||||
|
|
||||||
export const LOGIN_ROUTE = '/login';
|
export const LOGIN_ROUTE = '/login';
|
||||||
export const LOGOUT_ROUTE = '/logout';
|
export const LOGOUT_ROUTE = '/logout';
|
||||||
@@ -211,6 +216,22 @@ export class AuthService {
|
|||||||
this.store.dispatch(new CheckAuthenticationTokenAction());
|
this.store.dispatch(new CheckAuthenticationTokenAction());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the special groups list embedded in the AuthStatus model
|
||||||
|
*/
|
||||||
|
public getSpecialGroupsFromAuthStatus(): Observable<RemoteData<PaginatedList<Group>>> {
|
||||||
|
return this.authRequestService.getRequest('status', null, followLink('specialGroups')).pipe(
|
||||||
|
getFirstCompletedRemoteData(),
|
||||||
|
switchMap((status: RemoteData<AuthStatus>) => {
|
||||||
|
if (status.hasSucceeded) {
|
||||||
|
return status.payload.specialGroups;
|
||||||
|
} else {
|
||||||
|
return createSuccessfulRemoteDataObject$(buildPaginatedList(new PageInfo(),[]));
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if token is present into storage and is not expired
|
* Checks if token is present into storage and is not expired
|
||||||
*/
|
*/
|
||||||
|
@@ -5,6 +5,8 @@ import { IDToUUIDSerializer } from '../../cache/id-to-uuid-serializer';
|
|||||||
import { RemoteData } from '../../data/remote-data';
|
import { RemoteData } from '../../data/remote-data';
|
||||||
import { EPerson } from '../../eperson/models/eperson.model';
|
import { EPerson } from '../../eperson/models/eperson.model';
|
||||||
import { EPERSON } from '../../eperson/models/eperson.resource-type';
|
import { EPERSON } from '../../eperson/models/eperson.resource-type';
|
||||||
|
import { Group } from '../../eperson/models/group.model';
|
||||||
|
import { GROUP } from '../../eperson/models/group.resource-type';
|
||||||
import { HALLink } from '../../shared/hal-link.model';
|
import { HALLink } from '../../shared/hal-link.model';
|
||||||
import { ResourceType } from '../../shared/resource-type';
|
import { ResourceType } from '../../shared/resource-type';
|
||||||
import { excludeFromEquals } from '../../utilities/equals.decorators';
|
import { excludeFromEquals } from '../../utilities/equals.decorators';
|
||||||
@@ -13,6 +15,7 @@ import { AUTH_STATUS } from './auth-status.resource-type';
|
|||||||
import { AuthTokenInfo } from './auth-token-info.model';
|
import { AuthTokenInfo } from './auth-token-info.model';
|
||||||
import { AuthMethod } from './auth.method';
|
import { AuthMethod } from './auth.method';
|
||||||
import { CacheableObject } from '../../cache/cacheable-object.model';
|
import { CacheableObject } from '../../cache/cacheable-object.model';
|
||||||
|
import { PaginatedList } from '../../data/paginated-list.model';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Object that represents the authenticated status of a user
|
* Object that represents the authenticated status of a user
|
||||||
@@ -61,6 +64,7 @@ export class AuthStatus implements CacheableObject {
|
|||||||
_links: {
|
_links: {
|
||||||
self: HALLink;
|
self: HALLink;
|
||||||
eperson: HALLink;
|
eperson: HALLink;
|
||||||
|
specialGroups: HALLink;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -70,6 +74,13 @@ export class AuthStatus implements CacheableObject {
|
|||||||
@link(EPERSON)
|
@link(EPERSON)
|
||||||
eperson?: Observable<RemoteData<EPerson>>;
|
eperson?: Observable<RemoteData<EPerson>>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The SpecialGroup of this auth status
|
||||||
|
* Will be undefined unless the SpecialGroup {@link HALLink} has been resolved.
|
||||||
|
*/
|
||||||
|
@link(GROUP, true)
|
||||||
|
specialGroups?: Observable<RemoteData<PaginatedList<Group>>>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* True if the token is valid, false if there was no token or the token wasn't valid
|
* True if the token is valid, false if there was no token or the token wasn't valid
|
||||||
*/
|
*/
|
||||||
|
@@ -22,12 +22,21 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ng-container *ngVar="(groupsRD$ | async)?.payload?.page as groups">
|
<ng-container *ngVar="(groupsRD$ | async)?.payload?.page as groups">
|
||||||
<div *ngIf="groups">
|
<div *ngIf="groups?.length > 0">
|
||||||
<h3 class="mt-4">{{'profile.groups.head' | translate}}</h3>
|
<h3 class="mt-4">{{'profile.groups.head' | translate}}</h3>
|
||||||
<ul class="list-group list-group-flush">
|
<ul class="list-group list-group-flush">
|
||||||
<li *ngFor="let group of groups" class="list-group-item">{{group.name}}</li>
|
<li *ngFor="let group of groups" class="list-group-item">{{group.name}}</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
|
<ng-container *ngVar="(specialGroupsRD$ | async)?.payload?.page as specialGroups">
|
||||||
|
<div *ngIf="specialGroups?.length > 0" data-test="specialGroups">
|
||||||
|
<h3 class="mt-4">{{'profile.special.groups.head' | translate}}</h3>
|
||||||
|
<ul class="list-group list-group-flush">
|
||||||
|
<li *ngFor="let specialGroup of specialGroups" class="list-group-item">{{specialGroup.name}}</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</ng-container>
|
||||||
</div>
|
</div>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
@@ -20,6 +20,7 @@ import { provideMockStore } from '@ngrx/store/testing';
|
|||||||
import { AuthorizationDataService } from '../core/data/feature-authorization/authorization-data.service';
|
import { AuthorizationDataService } from '../core/data/feature-authorization/authorization-data.service';
|
||||||
import { getTestScheduler } from 'jasmine-marbles';
|
import { getTestScheduler } from 'jasmine-marbles';
|
||||||
import { By } from '@angular/platform-browser';
|
import { By } from '@angular/platform-browser';
|
||||||
|
import { EmptySpecialGroupDataMock$, SpecialGroupDataMock$ } from '../shared/testing/special-group.mock';
|
||||||
|
|
||||||
describe('ProfilePageComponent', () => {
|
describe('ProfilePageComponent', () => {
|
||||||
let component: ProfilePageComponent;
|
let component: ProfilePageComponent;
|
||||||
@@ -54,7 +55,8 @@ describe('ProfilePageComponent', () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
authService = jasmine.createSpyObj('authService', {
|
authService = jasmine.createSpyObj('authService', {
|
||||||
getAuthenticatedUserFromStore: observableOf(user)
|
getAuthenticatedUserFromStore: observableOf(user),
|
||||||
|
getSpecialGroupsFromAuthStatus: SpecialGroupDataMock$
|
||||||
});
|
});
|
||||||
epersonService = jasmine.createSpyObj('epersonService', {
|
epersonService = jasmine.createSpyObj('epersonService', {
|
||||||
findById: createSuccessfulRemoteDataObject$(user),
|
findById: createSuccessfulRemoteDataObject$(user),
|
||||||
@@ -235,4 +237,25 @@ describe('ProfilePageComponent', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('check for specialGroups', () => {
|
||||||
|
it('should contains specialGroups list', () => {
|
||||||
|
const specialGroupsEle = fixture.debugElement.query(By.css('[data-test="specialGroups"]'));
|
||||||
|
expect(specialGroupsEle).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not contains specialGroups list', () => {
|
||||||
|
component.specialGroupsRD$ = null;
|
||||||
|
fixture.detectChanges();
|
||||||
|
const specialGroupsEle = fixture.debugElement.query(By.css('[data-test="specialGroups"]'));
|
||||||
|
expect(specialGroupsEle).toBeFalsy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not contains specialGroups list', () => {
|
||||||
|
component.specialGroupsRD$ = EmptySpecialGroupDataMock$;
|
||||||
|
fixture.detectChanges();
|
||||||
|
const specialGroupsEle = fixture.debugElement.query(By.css('[data-test="specialGroups"]'));
|
||||||
|
expect(specialGroupsEle).toBeFalsy();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@@ -9,11 +9,7 @@ import { RemoteData } from '../core/data/remote-data';
|
|||||||
import { PaginatedList } from '../core/data/paginated-list.model';
|
import { PaginatedList } from '../core/data/paginated-list.model';
|
||||||
import { filter, switchMap, tap } from 'rxjs/operators';
|
import { filter, switchMap, tap } from 'rxjs/operators';
|
||||||
import { EPersonDataService } from '../core/eperson/eperson-data.service';
|
import { EPersonDataService } from '../core/eperson/eperson-data.service';
|
||||||
import {
|
import { getAllSucceededRemoteData, getFirstCompletedRemoteData, getRemoteDataPayload } from '../core/shared/operators';
|
||||||
getAllSucceededRemoteData,
|
|
||||||
getRemoteDataPayload,
|
|
||||||
getFirstCompletedRemoteData
|
|
||||||
} from '../core/shared/operators';
|
|
||||||
import { hasValue, isNotEmpty } from '../shared/empty.util';
|
import { hasValue, isNotEmpty } from '../shared/empty.util';
|
||||||
import { followLink } from '../shared/utils/follow-link-config.model';
|
import { followLink } from '../shared/utils/follow-link-config.model';
|
||||||
import { AuthService } from '../core/auth/auth.service';
|
import { AuthService } from '../core/auth/auth.service';
|
||||||
@@ -45,6 +41,11 @@ export class ProfilePageComponent implements OnInit {
|
|||||||
*/
|
*/
|
||||||
groupsRD$: Observable<RemoteData<PaginatedList<Group>>>;
|
groupsRD$: Observable<RemoteData<PaginatedList<Group>>>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The special groups the user belongs to
|
||||||
|
*/
|
||||||
|
specialGroupsRD$: Observable<RemoteData<PaginatedList<Group>>>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prefix for the notification messages of this component
|
* Prefix for the notification messages of this component
|
||||||
*/
|
*/
|
||||||
@@ -88,6 +89,7 @@ export class ProfilePageComponent implements OnInit {
|
|||||||
);
|
);
|
||||||
this.groupsRD$ = this.user$.pipe(switchMap((user: EPerson) => user.groups));
|
this.groupsRD$ = this.user$.pipe(switchMap((user: EPerson) => user.groups));
|
||||||
this.canChangePassword$ = this.user$.pipe(switchMap((user: EPerson) => this.authorizationService.isAuthorized(FeatureID.CanChangePassword, user._links.self.href)));
|
this.canChangePassword$ = this.user$.pipe(switchMap((user: EPerson) => this.authorizationService.isAuthorized(FeatureID.CanChangePassword, user._links.self.href)));
|
||||||
|
this.specialGroupsRD$ = this.authService.getSpecialGroupsFromAuthStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -34,6 +34,9 @@ export class AuthRequestServiceStub {
|
|||||||
},
|
},
|
||||||
eperson: {
|
eperson: {
|
||||||
href: this.mockUser._links.self.href
|
href: this.mockUser._links.self.href
|
||||||
|
},
|
||||||
|
specialGroups: {
|
||||||
|
href: this.mockUser._links.self.href
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
@@ -62,6 +65,9 @@ export class AuthRequestServiceStub {
|
|||||||
},
|
},
|
||||||
eperson: {
|
eperson: {
|
||||||
href: this.mockUser._links.self.href
|
href: this.mockUser._links.self.href
|
||||||
|
},
|
||||||
|
specialGroups: {
|
||||||
|
href: this.mockUser._links.self.href
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
|
56
src/app/shared/testing/special-group.mock.ts
Normal file
56
src/app/shared/testing/special-group.mock.ts
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
import { Observable } from 'rxjs';
|
||||||
|
|
||||||
|
import { EPersonMock } from './eperson.mock';
|
||||||
|
import { PageInfo } from '../../core/shared/page-info.model';
|
||||||
|
import { buildPaginatedList, PaginatedList } from '../../core/data/paginated-list.model';
|
||||||
|
import { Group } from '../../core/eperson/models/group.model';
|
||||||
|
import { createSuccessfulRemoteDataObject, createSuccessfulRemoteDataObject$ } from '../remote-data.utils';
|
||||||
|
import { RemoteData } from '../../core/data/remote-data';
|
||||||
|
|
||||||
|
export const SpecialGroupMock2: Group = Object.assign(new Group(), {
|
||||||
|
handle: null,
|
||||||
|
subgroups: [],
|
||||||
|
epersons: [],
|
||||||
|
permanent: true,
|
||||||
|
selfRegistered: false,
|
||||||
|
_links: {
|
||||||
|
self: {
|
||||||
|
href: 'https://rest.api/server/api/eperson/specialGroups/testgroupid2',
|
||||||
|
},
|
||||||
|
subgroups: { href: 'https://rest.api/server/api/eperson/specialGroups/testgroupid2/subgroups' },
|
||||||
|
object: { href: 'https://rest.api/server/api/eperson/specialGroups/testgroupid2/object' },
|
||||||
|
epersons: { href: 'https://rest.api/server/api/eperson/specialGroups/testgroupid2/epersons' }
|
||||||
|
},
|
||||||
|
_name: 'testgroupname2',
|
||||||
|
id: 'testgroupid2',
|
||||||
|
uuid: 'testgroupid2',
|
||||||
|
type: 'specialGroups',
|
||||||
|
// object: createSuccessfulRemoteDataObject$({ name: 'testspecialGroupsid2objectName'})
|
||||||
|
});
|
||||||
|
|
||||||
|
export const SpecialGroupMock: Group = Object.assign(new Group(), {
|
||||||
|
handle: null,
|
||||||
|
subgroups: [SpecialGroupMock2],
|
||||||
|
epersons: [EPersonMock],
|
||||||
|
selfRegistered: false,
|
||||||
|
permanent: false,
|
||||||
|
_links: {
|
||||||
|
self: {
|
||||||
|
href: 'https://rest.api/server/api/eperson/specialGroups/testgroupid',
|
||||||
|
},
|
||||||
|
subgroups: { href: 'https://rest.api/server/api/eperson/specialGroups/testgroupid/subgroups' },
|
||||||
|
object: { href: 'https://rest.api/server/api/eperson/specialGroups/testgroupid2/object' },
|
||||||
|
epersons: { href: 'https://rest.api/server/api/eperson/specialGroups/testgroupid/epersons' }
|
||||||
|
},
|
||||||
|
_name: 'testgroupname',
|
||||||
|
id: 'testgroupid',
|
||||||
|
uuid: 'testgroupid',
|
||||||
|
type: 'specialGroups',
|
||||||
|
});
|
||||||
|
|
||||||
|
export const SpecialGroupDataMock: RemoteData<PaginatedList<Group>> = createSuccessfulRemoteDataObject(buildPaginatedList(new PageInfo(), [SpecialGroupMock2,SpecialGroupMock]));
|
||||||
|
export const SpecialGroupDataMock$: Observable<RemoteData<PaginatedList<Group>>> = createSuccessfulRemoteDataObject$(buildPaginatedList(new PageInfo(), [SpecialGroupMock2,SpecialGroupMock]));
|
||||||
|
export const EmptySpecialGroupDataMock$: Observable<RemoteData<PaginatedList<Group>>> = createSuccessfulRemoteDataObject$(buildPaginatedList(new PageInfo(), []));
|
||||||
|
|
||||||
|
|
||||||
|
|
@@ -2886,6 +2886,8 @@
|
|||||||
|
|
||||||
"profile.groups.head": "Authorization groups you belong to",
|
"profile.groups.head": "Authorization groups you belong to",
|
||||||
|
|
||||||
|
"profile.special.groups.head": "Authorization special groups you belong to",
|
||||||
|
|
||||||
"profile.head": "Update Profile",
|
"profile.head": "Update Profile",
|
||||||
|
|
||||||
"profile.metadata.form.error.firstname.required": "First Name is required",
|
"profile.metadata.form.error.firstname.required": "First Name is required",
|
||||||
|
Reference in New Issue
Block a user