Merge remote-tracking branch 'origin/main' into CST-5733-router-loading

# Conflicts:
#	src/app/admin/admin-sidebar/admin-sidebar.component.ts
This commit is contained in:
Giuseppe Digilio
2022-04-26 17:04:09 +02:00
399 changed files with 2109 additions and 1503 deletions

View File

@@ -72,6 +72,9 @@ jobs:
- name: Run lint - name: Run lint
run: yarn run lint --quiet run: yarn run lint --quiet
- name: Check for circular dependencies
run: yarn run check-circ-deps
- name: Run build - name: Run build
run: yarn run build:prod run: yarn run build:prod

View File

@@ -79,6 +79,10 @@
{ {
"replace": "src/environments/environment.ts", "replace": "src/environments/environment.ts",
"with": "src/environments/environment.production.ts" "with": "src/environments/environment.production.ts"
},
{
"replace": "src/config/store/devtools.ts",
"with": "src/config/store/devtools.prod.ts"
} }
], ],
"optimization": true, "optimization": true,
@@ -204,6 +208,10 @@
{ {
"replace": "src/environments/environment.ts", "replace": "src/environments/environment.ts",
"with": "src/environments/environment.production.ts" "with": "src/environments/environment.production.ts"
},
{
"replace": "src/config/store/devtools.ts",
"with": "src/config/store/devtools.prod.ts"
} }
] ]
} }

View File

@@ -36,7 +36,8 @@
"merge-i18n": "ts-node --project ./tsconfig.ts-node.json scripts/merge-i18n-files.ts", "merge-i18n": "ts-node --project ./tsconfig.ts-node.json scripts/merge-i18n-files.ts",
"cypress:open": "cypress open", "cypress:open": "cypress open",
"cypress:run": "cypress run", "cypress:run": "cypress run",
"env:yaml": "ts-node --project ./tsconfig.ts-node.json scripts/env-to-yaml.ts" "env:yaml": "ts-node --project ./tsconfig.ts-node.json scripts/env-to-yaml.ts",
"check-circ-deps": "npx madge --exclude '(bitstream|bundle|collection|config-submission-form|eperson|item|version)\\.model\\.ts$' --circular --extensions ts ./"
}, },
"browser": { "browser": {
"fs": false, "fs": false,

View File

@@ -9,7 +9,6 @@ import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
import { TranslateLoader, TranslateModule, TranslateService } from '@ngx-translate/core'; import { TranslateLoader, TranslateModule, TranslateService } from '@ngx-translate/core';
import { buildPaginatedList, PaginatedList } from '../../core/data/paginated-list.model'; import { buildPaginatedList, PaginatedList } from '../../core/data/paginated-list.model';
import { RemoteData } from '../../core/data/remote-data'; import { RemoteData } from '../../core/data/remote-data';
import { FindListOptions } from '../../core/data/request.models';
import { EPersonDataService } from '../../core/eperson/eperson-data.service'; import { EPersonDataService } from '../../core/eperson/eperson-data.service';
import { EPerson } from '../../core/eperson/models/eperson.model'; import { EPerson } from '../../core/eperson/models/eperson.model';
import { PageInfo } from '../../core/shared/page-info.model'; import { PageInfo } from '../../core/shared/page-info.model';
@@ -27,6 +26,7 @@ import { AuthorizationDataService } from '../../core/data/feature-authorization/
import { RequestService } from '../../core/data/request.service'; import { RequestService } from '../../core/data/request.service';
import { PaginationService } from '../../core/pagination/pagination.service'; import { PaginationService } from '../../core/pagination/pagination.service';
import { PaginationServiceStub } from '../../shared/testing/pagination-service.stub'; import { PaginationServiceStub } from '../../shared/testing/pagination-service.stub';
import { FindListOptions } from '../../core/data/find-list-options.model';
describe('EPeopleRegistryComponent', () => { describe('EPeopleRegistryComponent', () => {
let component: EPeopleRegistryComponent; let component: EPeopleRegistryComponent;

View File

@@ -8,7 +8,6 @@ import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
import { TranslateLoader, TranslateModule } from '@ngx-translate/core'; import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
import { buildPaginatedList, PaginatedList } from '../../../core/data/paginated-list.model'; import { buildPaginatedList, PaginatedList } from '../../../core/data/paginated-list.model';
import { RemoteData } from '../../../core/data/remote-data'; import { RemoteData } from '../../../core/data/remote-data';
import { FindListOptions } from '../../../core/data/request.models';
import { EPersonDataService } from '../../../core/eperson/eperson-data.service'; import { EPersonDataService } from '../../../core/eperson/eperson-data.service';
import { EPerson } from '../../../core/eperson/models/eperson.model'; import { EPerson } from '../../../core/eperson/models/eperson.model';
import { PageInfo } from '../../../core/shared/page-info.model'; import { PageInfo } from '../../../core/shared/page-info.model';
@@ -29,6 +28,7 @@ import { createPaginatedList } from '../../../shared/testing/utils.test';
import { RequestService } from '../../../core/data/request.service'; import { RequestService } from '../../../core/data/request.service';
import { PaginationService } from '../../../core/pagination/pagination.service'; import { PaginationService } from '../../../core/pagination/pagination.service';
import { PaginationServiceStub } from '../../../shared/testing/pagination-service.stub'; import { PaginationServiceStub } from '../../../shared/testing/pagination-service.stub';
import { FindListOptions } from '../../../core/data/find-list-options.model';
import { ValidateEmailNotTaken } from './validators/email-taken.validator'; import { ValidateEmailNotTaken } from './validators/email-taken.validator';
import { EpersonRegistrationService } from '../../../core/data/eperson-registration.service'; import { EpersonRegistrationService } from '../../../core/data/eperson-registration.service';

View File

@@ -25,9 +25,9 @@ import {
import { createPaginatedList } from '../../../shared/testing/utils.test'; import { createPaginatedList } from '../../../shared/testing/utils.test';
import { PaginationComponentOptions } from '../../../shared/pagination/pagination-component-options.model'; import { PaginationComponentOptions } from '../../../shared/pagination/pagination-component-options.model';
import { SortDirection, SortOptions } from '../../../core/cache/models/sort-options.model'; import { SortDirection, SortOptions } from '../../../core/cache/models/sort-options.model';
import { FindListOptions } from '../../../core/data/request.models';
import { PaginationService } from '../../../core/pagination/pagination.service'; import { PaginationService } from '../../../core/pagination/pagination.service';
import { PaginationServiceStub } from '../../../shared/testing/pagination-service.stub'; import { PaginationServiceStub } from '../../../shared/testing/pagination-service.stub';
import { FindListOptions } from '../../../core/data/find-list-options.model';
describe('BitstreamFormatsComponent', () => { describe('BitstreamFormatsComponent', () => {
let comp: BitstreamFormatsComponent; let comp: BitstreamFormatsComponent;

View File

@@ -5,7 +5,6 @@ import { PaginatedList } from '../../../core/data/paginated-list.model';
import { PaginationComponentOptions } from '../../../shared/pagination/pagination-component-options.model'; import { PaginationComponentOptions } from '../../../shared/pagination/pagination-component-options.model';
import { BitstreamFormat } from '../../../core/shared/bitstream-format.model'; import { BitstreamFormat } from '../../../core/shared/bitstream-format.model';
import { BitstreamFormatDataService } from '../../../core/data/bitstream-format-data.service'; import { BitstreamFormatDataService } from '../../../core/data/bitstream-format-data.service';
import { FindListOptions } from '../../../core/data/request.models';
import { map, switchMap, take } from 'rxjs/operators'; import { map, switchMap, take } from 'rxjs/operators';
import { hasValue } from '../../../shared/empty.util'; import { hasValue } from '../../../shared/empty.util';
import { NotificationsService } from '../../../shared/notifications/notifications.service'; import { NotificationsService } from '../../../shared/notifications/notifications.service';
@@ -13,6 +12,7 @@ import { Router } from '@angular/router';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { NoContent } from '../../../core/shared/NoContent.model'; import { NoContent } from '../../../core/shared/NoContent.model';
import { PaginationService } from '../../../core/pagination/pagination.service'; import { PaginationService } from '../../../core/pagination/pagination.service';
import { FindListOptions } from '../../../core/data/find-list-options.model';
/** /**
* This component renders a list of bitstream formats * This component renders a list of bitstream formats

View File

@@ -21,8 +21,8 @@ import { createSuccessfulRemoteDataObject$ } from '../../../shared/remote-data.u
import { PaginationService } from '../../../core/pagination/pagination.service'; import { PaginationService } from '../../../core/pagination/pagination.service';
import { PaginationComponentOptions } from '../../../shared/pagination/pagination-component-options.model'; import { PaginationComponentOptions } from '../../../shared/pagination/pagination-component-options.model';
import { SortDirection, SortOptions } from '../../../core/cache/models/sort-options.model'; import { SortDirection, SortOptions } from '../../../core/cache/models/sort-options.model';
import { FindListOptions } from '../../../core/data/request.models';
import { PaginationServiceStub } from '../../../shared/testing/pagination-service.stub'; import { PaginationServiceStub } from '../../../shared/testing/pagination-service.stub';
import { FindListOptions } from '../../../core/data/find-list-options.model';
describe('MetadataRegistryComponent', () => { describe('MetadataRegistryComponent', () => {
let comp: MetadataRegistryComponent; let comp: MetadataRegistryComponent;

View File

@@ -25,9 +25,9 @@ import { createSuccessfulRemoteDataObject$ } from '../../../shared/remote-data.u
import { VarDirective } from '../../../shared/utils/var.directive'; import { VarDirective } from '../../../shared/utils/var.directive';
import { PaginationComponentOptions } from '../../../shared/pagination/pagination-component-options.model'; import { PaginationComponentOptions } from '../../../shared/pagination/pagination-component-options.model';
import { SortDirection, SortOptions } from '../../../core/cache/models/sort-options.model'; import { SortDirection, SortOptions } from '../../../core/cache/models/sort-options.model';
import { FindListOptions } from '../../../core/data/request.models';
import { PaginationService } from '../../../core/pagination/pagination.service'; import { PaginationService } from '../../../core/pagination/pagination.service';
import { PaginationServiceStub } from '../../../shared/testing/pagination-service.stub'; import { PaginationServiceStub } from '../../../shared/testing/pagination-service.stub';
import { FindListOptions } from '../../../core/data/find-list-options.model';
describe('MetadataSchemaComponent', () => { describe('MetadataSchemaComponent', () => {
let comp: MetadataSchemaComponent; let comp: MetadataSchemaComponent;

View File

@@ -1,10 +1,10 @@
import { Component, Inject, Injector, OnInit } from '@angular/core'; import { Component, Inject, Injector, OnInit } from '@angular/core';
import { MenuSectionComponent } from '../../../shared/menu/menu-section/menu-section.component'; import { MenuSectionComponent } from '../../../shared/menu/menu-section/menu-section.component';
import { MenuID } from '../../../shared/menu/initial-menus-state';
import { MenuService } from '../../../shared/menu/menu.service'; import { MenuService } from '../../../shared/menu/menu.service';
import { rendersSectionForMenu } from '../../../shared/menu/menu-section.decorator'; import { rendersSectionForMenu } from '../../../shared/menu/menu-section.decorator';
import { LinkMenuItemModel } from '../../../shared/menu/menu-item/models/link.model'; import { LinkMenuItemModel } from '../../../shared/menu/menu-item/models/link.model';
import { MenuSection } from '../../../shared/menu/menu.reducer'; import { MenuSection } from '../../../shared/menu/menu-section.model';
import { MenuID } from '../../../shared/menu/menu-id.model';
import { isNotEmpty } from '../../../shared/empty.util'; import { isNotEmpty } from '../../../shared/empty.util';
import { Router } from '@angular/router'; import { Router } from '@angular/router';

View File

@@ -237,7 +237,24 @@ describe('AdminSidebarComponent', () => {
expect(menuService.addSection).toHaveBeenCalledWith(comp.menuID, jasmine.objectContaining({ expect(menuService.addSection).toHaveBeenCalledWith(comp.menuID, jasmine.objectContaining({
parentID: 'access_control', visible: false, parentID: 'access_control', visible: false,
})); }));
});
// We check that the menu section has not been called with visible set to true
// The reason why we don't check if it has been called with visible set to false
// Is because the function does not get called unless a user is authorised
it('should not show the import section', () => {
expect(menuService.addSection).not.toHaveBeenCalledWith(comp.menuID, jasmine.objectContaining({
id: 'import', visible: true,
}));
});
// We check that the menu section has not been called with visible set to true
// The reason why we don't check if it has been called with visible set to false
// Is because the function does not get called unless a user is authorised
it('should not show the export section', () => {
expect(menuService.addSection).not.toHaveBeenCalledWith(comp.menuID, jasmine.objectContaining({
id: 'export', visible: true,
}));
}); });
}); });
@@ -268,6 +285,15 @@ describe('AdminSidebarComponent', () => {
expect(menuService.addSection).toHaveBeenCalledWith(comp.menuID, jasmine.objectContaining({ expect(menuService.addSection).toHaveBeenCalledWith(comp.menuID, jasmine.objectContaining({
id: 'workflow', visible: true, id: 'workflow', visible: true,
})); }));
expect(menuService.addSection).toHaveBeenCalledWith(comp.menuID, jasmine.objectContaining({
id: 'workflow', visible: true,
}));
expect(menuService.addSection).toHaveBeenCalledWith(comp.menuID, jasmine.objectContaining({
id: 'import', visible: true,
}));
expect(menuService.addSection).toHaveBeenCalledWith(comp.menuID, jasmine.objectContaining({
id: 'export', visible: true,
}));
}); });
}); });

View File

@@ -1,9 +1,13 @@
import { Component, HostListener, Injector, OnInit } from '@angular/core'; import { Component, HostListener, Injector, OnInit } from '@angular/core';
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
import { BehaviorSubject, combineLatest as observableCombineLatest, combineLatest, Observable } from 'rxjs'; import { BehaviorSubject, combineLatest as observableCombineLatest, combineLatest, Observable } from 'rxjs';
import { debounceTime, distinctUntilChanged, first, map, take, withLatestFrom } from 'rxjs/operators'; import { debounceTime, distinctUntilChanged, filter, first, map, take, withLatestFrom } from 'rxjs/operators';
import { AuthService } from '../../core/auth/auth.service'; import { AuthService } from '../../core/auth/auth.service';
import { ScriptDataService } from '../../core/data/processes/script-data.service'; import {
METADATA_EXPORT_SCRIPT_NAME,
METADATA_IMPORT_SCRIPT_NAME,
ScriptDataService
} from '../../core/data/processes/script-data.service';
import { slideHorizontal, slideSidebar } from '../../shared/animations/slide'; import { slideHorizontal, slideSidebar } from '../../shared/animations/slide';
import { import {
CreateCollectionParentSelectorComponent CreateCollectionParentSelectorComponent
@@ -26,7 +30,6 @@ import {
import { import {
ExportMetadataSelectorComponent ExportMetadataSelectorComponent
} from '../../shared/dso-selector/modal-wrappers/export-metadata-selector/export-metadata-selector.component'; } from '../../shared/dso-selector/modal-wrappers/export-metadata-selector/export-metadata-selector.component';
import { MenuID, MenuItemType } from '../../shared/menu/initial-menus-state';
import { LinkMenuItemModel } from '../../shared/menu/menu-item/models/link.model'; import { LinkMenuItemModel } from '../../shared/menu/menu-item/models/link.model';
import { OnClickMenuItemModel } from '../../shared/menu/menu-item/models/onclick.model'; import { OnClickMenuItemModel } from '../../shared/menu/menu-item/models/onclick.model';
import { TextMenuItemModel } from '../../shared/menu/menu-item/models/text.model'; import { TextMenuItemModel } from '../../shared/menu/menu-item/models/text.model';
@@ -35,6 +38,8 @@ import { MenuService } from '../../shared/menu/menu.service';
import { CSSVariableService } from '../../shared/sass-helper/sass-helper.service'; import { CSSVariableService } from '../../shared/sass-helper/sass-helper.service';
import { AuthorizationDataService } from '../../core/data/feature-authorization/authorization-data.service'; import { AuthorizationDataService } from '../../core/data/feature-authorization/authorization-data.service';
import { FeatureID } from '../../core/data/feature-authorization/feature-id'; import { FeatureID } from '../../core/data/feature-authorization/feature-id';
import { MenuID } from '../../shared/menu/menu-id.model';
import { MenuItemType } from '../../shared/menu/menu-item-type.model';
import { ActivatedRoute } from '@angular/router'; import { ActivatedRoute } from '@angular/router';
/** /**
@@ -335,19 +340,6 @@ export class AdminSidebarComponent extends MenuComponent implements OnInit {
*/ */
createExportMenuSections() { createExportMenuSections() {
const menuList = [ const menuList = [
/* Export */
{
id: 'export',
active: false,
visible: true,
model: {
type: MenuItemType.TEXT,
text: 'menu.section.export'
} as TextMenuItemModel,
icon: 'file-export',
index: 3,
shouldPersistOnRouteChange: true
},
// TODO: enable this menu item once the feature has been implemented // TODO: enable this menu item once the feature has been implemented
// { // {
// id: 'export_community', // id: 'export_community',
@@ -390,14 +382,28 @@ export class AdminSidebarComponent extends MenuComponent implements OnInit {
]; ];
menuList.forEach((menuSection) => this.menuService.addSection(this.menuID, menuSection)); menuList.forEach((menuSection) => this.menuService.addSection(this.menuID, menuSection));
observableCombineLatest( observableCombineLatest([
this.authorizationService.isAuthorized(FeatureID.AdministratorOf), this.authorizationService.isAuthorized(FeatureID.AdministratorOf),
// this.scriptDataService.scriptWithNameExistsAndCanExecute(METADATA_EXPORT_SCRIPT_NAME) this.scriptDataService.scriptWithNameExistsAndCanExecute(METADATA_EXPORT_SCRIPT_NAME)
).pipe( ]).pipe(
// TODO uncomment when #635 (https://github.com/DSpace/dspace-angular/issues/635) is fixed; otherwise even in production mode, the metadata export button is only available after a refresh (and not in dev mode) filter(([authorized, metadataExportScriptExists]: boolean[]) => authorized && metadataExportScriptExists),
// filter(([authorized, metadataExportScriptExists]: boolean[]) => authorized && metadataExportScriptExists),
take(1) take(1)
).subscribe(() => { ).subscribe(() => {
// Hides the export menu for unauthorised people
// If in the future more sub-menus are added,
// it should be reviewed if they need to be in this subscribe
this.menuService.addSection(this.menuID, {
id: 'export',
active: false,
visible: true,
model: {
type: MenuItemType.TEXT,
text: 'menu.section.export'
} as TextMenuItemModel,
icon: 'file-export',
index: 3,
shouldPersistOnRouteChange: true
});
this.menuService.addSection(this.menuID, { this.menuService.addSection(this.menuID, {
id: 'export_metadata', id: 'export_metadata',
parentID: 'export', parentID: 'export',
@@ -421,18 +427,6 @@ export class AdminSidebarComponent extends MenuComponent implements OnInit {
*/ */
createImportMenuSections() { createImportMenuSections() {
const menuList = [ const menuList = [
/* Import */
{
id: 'import',
active: false,
visible: true,
model: {
type: MenuItemType.TEXT,
text: 'menu.section.import'
} as TextMenuItemModel,
icon: 'file-import',
index: 2
},
// TODO: enable this menu item once the feature has been implemented // TODO: enable this menu item once the feature has been implemented
// { // {
// id: 'import_batch', // id: 'import_batch',
@@ -450,14 +444,27 @@ export class AdminSidebarComponent extends MenuComponent implements OnInit {
shouldPersistOnRouteChange: true shouldPersistOnRouteChange: true
}))); })));
observableCombineLatest( observableCombineLatest([
this.authorizationService.isAuthorized(FeatureID.AdministratorOf), this.authorizationService.isAuthorized(FeatureID.AdministratorOf),
// this.scriptDataService.scriptWithNameExistsAndCanExecute(METADATA_IMPORT_SCRIPT_NAME) this.scriptDataService.scriptWithNameExistsAndCanExecute(METADATA_IMPORT_SCRIPT_NAME)
).pipe( ]).pipe(
// TODO uncomment when #635 (https://github.com/DSpace/dspace-angular/issues/635) is fixed filter(([authorized, metadataImportScriptExists]: boolean[]) => authorized && metadataImportScriptExists),
// filter(([authorized, metadataImportScriptExists]: boolean[]) => authorized && metadataImportScriptExists),
take(1) take(1)
).subscribe(() => { ).subscribe(() => {
// Hides the import menu for unauthorised people
// If in the future more sub-menus are added,
// it should be reviewed if they need to be in this subscribe
this.menuService.addSection(this.menuID, {
id: 'import',
active: false,
visible: true,
model: {
type: MenuItemType.TEXT,
text: 'menu.section.import'
} as TextMenuItemModel,
icon: 'file-import',
index: 2
});
this.menuService.addSection(this.menuID, { this.menuService.addSection(this.menuID, {
id: 'import_metadata', id: 'import_metadata',
parentID: 'import', parentID: 'import',
@@ -566,10 +573,10 @@ export class AdminSidebarComponent extends MenuComponent implements OnInit {
* Create menu sections dependent on whether or not the current user can manage access control groups * Create menu sections dependent on whether or not the current user can manage access control groups
*/ */
createAccessControlMenuSections() { createAccessControlMenuSections() {
observableCombineLatest( observableCombineLatest([
this.authorizationService.isAuthorized(FeatureID.AdministratorOf), this.authorizationService.isAuthorized(FeatureID.AdministratorOf),
this.authorizationService.isAuthorized(FeatureID.CanManageGroups) this.authorizationService.isAuthorized(FeatureID.CanManageGroups)
).subscribe(([isSiteAdmin, canManageGroups]) => { ]).subscribe(([isSiteAdmin, canManageGroups]) => {
const menuList = [ const menuList = [
/* Access Control */ /* Access Control */
{ {

View File

@@ -4,11 +4,11 @@ import { AdminSidebarSectionComponent } from '../admin-sidebar-section/admin-sid
import { slide } from '../../../shared/animations/slide'; import { slide } from '../../../shared/animations/slide';
import { CSSVariableService } from '../../../shared/sass-helper/sass-helper.service'; import { CSSVariableService } from '../../../shared/sass-helper/sass-helper.service';
import { bgColor } from '../../../shared/animations/bgColor'; import { bgColor } from '../../../shared/animations/bgColor';
import { MenuID } from '../../../shared/menu/initial-menus-state';
import { MenuService } from '../../../shared/menu/menu.service'; import { MenuService } from '../../../shared/menu/menu.service';
import { combineLatest as combineLatestObservable, Observable } from 'rxjs'; import { combineLatest as combineLatestObservable, Observable } from 'rxjs';
import { map } from 'rxjs/operators'; import { map } from 'rxjs/operators';
import { rendersSectionForMenu } from '../../../shared/menu/menu-section.decorator'; import { rendersSectionForMenu } from '../../../shared/menu/menu-section.decorator';
import { MenuID } from '../../../shared/menu/menu-id.model';
import { Router } from '@angular/router'; import { Router } from '@angular/router';
/** /**

View File

@@ -8,7 +8,6 @@ import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
import { EffectsModule } from '@ngrx/effects'; import { EffectsModule } from '@ngrx/effects';
import { RouterStateSerializer, StoreRouterConnectingModule } from '@ngrx/router-store'; import { RouterStateSerializer, StoreRouterConnectingModule } from '@ngrx/router-store';
import { MetaReducer, Store, StoreModule, USER_PROVIDED_META_REDUCERS } from '@ngrx/store'; import { MetaReducer, Store, StoreModule, USER_PROVIDED_META_REDUCERS } from '@ngrx/store';
import { StoreDevtoolsModule } from '@ngrx/store-devtools';
import { import {
DYNAMIC_ERROR_MESSAGES_MATCHER, DYNAMIC_ERROR_MESSAGES_MATCHER,
DYNAMIC_MATCHER_PROVIDERS, DYNAMIC_MATCHER_PROVIDERS,
@@ -61,6 +60,8 @@ import { ThemedAdminSidebarComponent } from './admin/admin-sidebar/themed-admin-
import { APP_CONFIG, AppConfig } from '../config/app-config.interface'; import { APP_CONFIG, AppConfig } from '../config/app-config.interface';
import { NgxMaskModule } from 'ngx-mask'; import { NgxMaskModule } from 'ngx-mask';
import { StoreDevModules } from '../config/store/devtools';
export function getConfig() { export function getConfig() {
return environment; return environment;
} }
@@ -96,15 +97,9 @@ const IMPORTS = [
StoreModule.forRoot(appReducers, storeModuleConfig), StoreModule.forRoot(appReducers, storeModuleConfig),
StoreRouterConnectingModule.forRoot(), StoreRouterConnectingModule.forRoot(),
ThemedEntryComponentModule.withEntryComponents(), ThemedEntryComponentModule.withEntryComponents(),
StoreDevModules,
]; ];
IMPORTS.push(
StoreDevtoolsModule.instrument({
maxAge: 1000,
logOnly: environment.production,
})
);
const PROVIDERS = [ const PROVIDERS = [
{ {
provide: APP_CONFIG, provide: APP_CONFIG,

View File

@@ -22,7 +22,7 @@ import {
nameVariantReducer nameVariantReducer
} from './shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/name-variant.reducer'; } from './shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/name-variant.reducer';
import { formReducer, FormState } from './shared/form/form.reducer'; import { formReducer, FormState } from './shared/form/form.reducer';
import { menusReducer, MenusState } from './shared/menu/menu.reducer'; import { menusReducer} from './shared/menu/menu.reducer';
import { import {
notificationsReducer, notificationsReducer,
NotificationsState NotificationsState
@@ -49,6 +49,7 @@ import {
import { sidebarReducer, SidebarState } from './shared/sidebar/sidebar.reducer'; import { sidebarReducer, SidebarState } from './shared/sidebar/sidebar.reducer';
import { truncatableReducer, TruncatablesState } from './shared/truncatable/truncatable.reducer'; import { truncatableReducer, TruncatablesState } from './shared/truncatable/truncatable.reducer';
import { ThemeState, themeReducer } from './shared/theme-support/theme.reducer'; import { ThemeState, themeReducer } from './shared/theme-support/theme.reducer';
import { MenusState } from './shared/menu/menus-state.model';
import { correlationIdReducer } from './correlation-id/correlation-id.reducer'; import { correlationIdReducer } from './correlation-id/correlation-id.reducer';
export interface AppState { export interface AppState {

View File

@@ -2,8 +2,8 @@ import { LegacyBitstreamUrlResolver } from './legacy-bitstream-url.resolver';
import { of as observableOf, EMPTY } from 'rxjs'; import { of as observableOf, EMPTY } from 'rxjs';
import { BitstreamDataService } from '../core/data/bitstream-data.service'; import { BitstreamDataService } from '../core/data/bitstream-data.service';
import { RemoteData } from '../core/data/remote-data'; import { RemoteData } from '../core/data/remote-data';
import { RequestEntryState } from '../core/data/request.reducer';
import { TestScheduler } from 'rxjs/testing'; import { TestScheduler } from 'rxjs/testing';
import { RequestEntryState } from '../core/data/request-entry-state.model';
describe(`LegacyBitstreamUrlResolver`, () => { describe(`LegacyBitstreamUrlResolver`, () => {
let resolver: LegacyBitstreamUrlResolver; let resolver: LegacyBitstreamUrlResolver;

View File

@@ -20,9 +20,9 @@ import { VarDirective } from '../../shared/utils/var.directive';
import { createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils'; import { createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils';
import { PaginationComponentOptions } from '../../shared/pagination/pagination-component-options.model'; import { PaginationComponentOptions } from '../../shared/pagination/pagination-component-options.model';
import { SortDirection, SortOptions } from '../../core/cache/models/sort-options.model'; import { SortDirection, SortOptions } from '../../core/cache/models/sort-options.model';
import { FindListOptions } from '../../core/data/request.models';
import { PaginationService } from '../../core/pagination/pagination.service'; import { PaginationService } from '../../core/pagination/pagination.service';
import { PaginationServiceStub } from '../../shared/testing/pagination-service.stub'; import { PaginationServiceStub } from '../../shared/testing/pagination-service.stub';
import { FindListOptions } from '../../core/data/find-list-options.model';
describe('BrowseByDatePageComponent', () => { describe('BrowseByDatePageComponent', () => {
let comp: BrowseByDatePageComponent; let comp: BrowseByDatePageComponent;

View File

@@ -20,9 +20,9 @@ import { VarDirective } from '../../shared/utils/var.directive';
import { createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils'; import { createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils';
import { PaginationComponentOptions } from '../../shared/pagination/pagination-component-options.model'; import { PaginationComponentOptions } from '../../shared/pagination/pagination-component-options.model';
import { SortDirection, SortOptions } from '../../core/cache/models/sort-options.model'; import { SortDirection, SortOptions } from '../../core/cache/models/sort-options.model';
import { FindListOptions } from '../../core/data/request.models';
import { PaginationService } from '../../core/pagination/pagination.service'; import { PaginationService } from '../../core/pagination/pagination.service';
import { PaginationServiceStub } from '../../shared/testing/pagination-service.stub'; import { PaginationServiceStub } from '../../shared/testing/pagination-service.stub';
import { FindListOptions } from '../../core/data/find-list-options.model';
describe('BrowseByTitlePageComponent', () => { describe('BrowseByTitlePageComponent', () => {
let comp: BrowseByTitlePageComponent; let comp: BrowseByTitlePageComponent;

View File

@@ -16,7 +16,7 @@ import { Collection } from '../../core/shared/collection.model';
import { RemoteData } from '../../core/data/remote-data'; import { RemoteData } from '../../core/data/remote-data';
import { PaginationComponentOptions } from '../../shared/pagination/pagination-component-options.model'; import { PaginationComponentOptions } from '../../shared/pagination/pagination-component-options.model';
import { SortDirection, SortOptions } from '../../core/cache/models/sort-options.model'; import { SortDirection, SortOptions } from '../../core/cache/models/sort-options.model';
import { EventEmitter } from '@angular/core'; import { ChangeDetectionStrategy, EventEmitter } from '@angular/core';
import { HostWindowService } from '../../shared/host-window.service'; import { HostWindowService } from '../../shared/host-window.service';
import { HostWindowServiceStub } from '../../shared/testing/host-window-service.stub'; import { HostWindowServiceStub } from '../../shared/testing/host-window-service.stub';
import { By } from '@angular/platform-browser'; import { By } from '@angular/platform-browser';
@@ -41,6 +41,8 @@ import {
} from '../../shared/remote-data.utils'; } from '../../shared/remote-data.utils';
import { createPaginatedList } from '../../shared/testing/utils.test'; import { createPaginatedList } from '../../shared/testing/utils.test';
import { AuthorizationDataService } from '../../core/data/feature-authorization/authorization-data.service'; import { AuthorizationDataService } from '../../core/data/feature-authorization/authorization-data.service';
import { MyDSpacePageComponent, SEARCH_CONFIG_SERVICE } from '../../my-dspace-page/my-dspace-page.component';
import { SearchConfigurationServiceStub } from '../../shared/testing/search-configuration-service.stub';
describe('CollectionItemMapperComponent', () => { describe('CollectionItemMapperComponent', () => {
let comp: CollectionItemMapperComponent; let comp: CollectionItemMapperComponent;
@@ -159,6 +161,14 @@ describe('CollectionItemMapperComponent', () => {
{ provide: RouteService, useValue: routeServiceStub }, { provide: RouteService, useValue: routeServiceStub },
{ provide: AuthorizationDataService, useValue: authorizationDataService } { provide: AuthorizationDataService, useValue: authorizationDataService }
] ]
}).overrideComponent(CollectionItemMapperComponent, {
set: {
providers: [
{
provide: SEARCH_CONFIG_SERVICE,
useClass: SearchConfigurationServiceStub
}
] }
}).compileComponents(); }).compileComponents();
})); }));

View File

@@ -18,9 +18,9 @@ import {
COLLECTION_CREATE_PATH COLLECTION_CREATE_PATH
} from './collection-page-routing-paths'; } from './collection-page-routing-paths';
import { CollectionPageAdministratorGuard } from './collection-page-administrator.guard'; import { CollectionPageAdministratorGuard } from './collection-page-administrator.guard';
import { MenuItemType } from '../shared/menu/initial-menus-state';
import { LinkMenuItemModel } from '../shared/menu/menu-item/models/link.model'; import { LinkMenuItemModel } from '../shared/menu/menu-item/models/link.model';
import { ThemedCollectionPageComponent } from './themed-collection-page.component'; import { ThemedCollectionPageComponent } from './themed-collection-page.component';
import { MenuItemType } from '../shared/menu/menu-item-type.model';
@NgModule({ @NgModule({
imports: [ imports: [

View File

@@ -16,7 +16,6 @@ import { Item } from '../core/shared/item.model';
import { import {
getAllSucceededRemoteDataPayload, getAllSucceededRemoteDataPayload,
getFirstSucceededRemoteData, getFirstSucceededRemoteData,
redirectOn4xx,
toDSpaceObjectListRD toDSpaceObjectListRD
} from '../core/shared/operators'; } from '../core/shared/operators';
@@ -28,6 +27,7 @@ import { PaginationService } from '../core/pagination/pagination.service';
import { AuthorizationDataService } from '../core/data/feature-authorization/authorization-data.service'; import { AuthorizationDataService } from '../core/data/feature-authorization/authorization-data.service';
import { FeatureID } from '../core/data/feature-authorization/feature-id'; import { FeatureID } from '../core/data/feature-authorization/feature-id';
import { getCollectionPageRoute } from './collection-page-routing-paths'; import { getCollectionPageRoute } from './collection-page-routing-paths';
import { redirectOn4xx } from '../core/shared/authorized.operators';
@Component({ @Component({
selector: 'ds-collection-page', selector: 'ds-collection-page',

View File

@@ -9,7 +9,6 @@ import { ContentSource, ContentSourceHarvestType } from '../../../core/shared/co
import { ObjectUpdatesService } from '../../../core/data/object-updates/object-updates.service'; import { ObjectUpdatesService } from '../../../core/data/object-updates/object-updates.service';
import { INotification, Notification } from '../../../shared/notifications/models/notification.model'; import { INotification, Notification } from '../../../shared/notifications/models/notification.model';
import { NotificationType } from '../../../shared/notifications/models/notification-type'; import { NotificationType } from '../../../shared/notifications/models/notification-type';
import { FieldUpdate } from '../../../core/data/object-updates/object-updates.reducer';
import { NotificationsService } from '../../../shared/notifications/notifications.service'; import { NotificationsService } from '../../../shared/notifications/notifications.service';
import { DynamicFormControlModel, DynamicFormService } from '@ng-dynamic-forms/core'; import { DynamicFormControlModel, DynamicFormService } from '@ng-dynamic-forms/core';
import { hasValue } from '../../../shared/empty.util'; import { hasValue } from '../../../shared/empty.util';
@@ -20,6 +19,7 @@ import { Collection } from '../../../core/shared/collection.model';
import { CollectionDataService } from '../../../core/data/collection-data.service'; import { CollectionDataService } from '../../../core/data/collection-data.service';
import { RequestService } from '../../../core/data/request.service'; import { RequestService } from '../../../core/data/request.service';
import { createSuccessfulRemoteDataObject, createSuccessfulRemoteDataObject$ } from '../../../shared/remote-data.utils'; import { createSuccessfulRemoteDataObject, createSuccessfulRemoteDataObject$ } from '../../../shared/remote-data.utils';
import { FieldUpdate } from '../../../core/data/object-updates/field-update.model';
const infoNotification: INotification = new Notification('id', NotificationType.Info, 'info'); const infoNotification: INotification = new Notification('id', NotificationType.Info, 'info');
const warningNotification: INotification = new Notification('id', NotificationType.Warning, 'warning'); const warningNotification: INotification = new Notification('id', NotificationType.Warning, 'warning');

View File

@@ -23,7 +23,6 @@ import { RemoteData } from '../../../core/data/remote-data';
import { Collection } from '../../../core/shared/collection.model'; import { Collection } from '../../../core/shared/collection.model';
import { first, map, switchMap, take } from 'rxjs/operators'; import { first, map, switchMap, take } from 'rxjs/operators';
import { ActivatedRoute, Router } from '@angular/router'; import { ActivatedRoute, Router } from '@angular/router';
import { FieldUpdate, FieldUpdates } from '../../../core/data/object-updates/object-updates.reducer';
import { cloneDeep } from 'lodash'; import { cloneDeep } from 'lodash';
import { CollectionDataService } from '../../../core/data/collection-data.service'; import { CollectionDataService } from '../../../core/data/collection-data.service';
import { getFirstSucceededRemoteData, getFirstCompletedRemoteData } from '../../../core/shared/operators'; import { getFirstSucceededRemoteData, getFirstCompletedRemoteData } from '../../../core/shared/operators';
@@ -31,6 +30,8 @@ import { MetadataConfig } from '../../../core/shared/metadata-config.model';
import { INotification } from '../../../shared/notifications/models/notification.model'; import { INotification } from '../../../shared/notifications/models/notification.model';
import { RequestService } from '../../../core/data/request.service'; import { RequestService } from '../../../core/data/request.service';
import { environment } from '../../../../environments/environment'; import { environment } from '../../../../environments/environment';
import { FieldUpdate } from '../../../core/data/object-updates/field-update.model';
import { FieldUpdates } from '../../../core/data/object-updates/field-updates.model';
/** /**
* Component for managing the content source of the collection * Component for managing the content source of the collection

View File

@@ -1,9 +1,10 @@
import { FindListOptions } from '../core/data/request.models';
import { hasValue } from '../shared/empty.util'; import { hasValue } from '../shared/empty.util';
import { CommunityListService, FlatNode } from './community-list-service'; import { CommunityListService} from './community-list-service';
import { CollectionViewer, DataSource } from '@angular/cdk/collections'; import { CollectionViewer, DataSource } from '@angular/cdk/collections';
import { BehaviorSubject, Observable, Subscription } from 'rxjs'; import { BehaviorSubject, Observable, Subscription } from 'rxjs';
import { finalize } from 'rxjs/operators'; import { finalize } from 'rxjs/operators';
import { FlatNode } from './flat-node.model';
import { FindListOptions } from '../core/data/find-list-options.model';
/** /**
* DataSource object needed by a CDK Tree to render its nodes. * DataSource object needed by a CDK Tree to render its nodes.

View File

@@ -7,13 +7,14 @@ import { SortDirection, SortOptions } from '../core/cache/models/sort-options.mo
import { buildPaginatedList } from '../core/data/paginated-list.model'; import { buildPaginatedList } from '../core/data/paginated-list.model';
import { createFailedRemoteDataObject$, createSuccessfulRemoteDataObject$ } from '../shared/remote-data.utils'; import { createFailedRemoteDataObject$, createSuccessfulRemoteDataObject$ } from '../shared/remote-data.utils';
import { StoreMock } from '../shared/testing/store.mock'; import { StoreMock } from '../shared/testing/store.mock';
import { CommunityListService, FlatNode, toFlatNode } from './community-list-service'; import { CommunityListService, toFlatNode } from './community-list-service';
import { CollectionDataService } from '../core/data/collection-data.service'; import { CollectionDataService } from '../core/data/collection-data.service';
import { CommunityDataService } from '../core/data/community-data.service'; import { CommunityDataService } from '../core/data/community-data.service';
import { Community } from '../core/shared/community.model'; import { Community } from '../core/shared/community.model';
import { Collection } from '../core/shared/collection.model'; import { Collection } from '../core/shared/collection.model';
import { FindListOptions } from '../core/data/request.models';
import { PageInfo } from '../core/shared/page-info.model'; import { PageInfo } from '../core/shared/page-info.model';
import { FlatNode } from './flat-node.model';
import { FindListOptions } from '../core/data/find-list-options.model';
describe('CommunityListService', () => { describe('CommunityListService', () => {
let store: StoreMock<AppState>; let store: StoreMock<AppState>;

View File

@@ -7,45 +7,22 @@ import { filter, map, switchMap } from 'rxjs/operators';
import { AppState } from '../app.reducer'; import { AppState } from '../app.reducer';
import { CommunityDataService } from '../core/data/community-data.service'; import { CommunityDataService } from '../core/data/community-data.service';
import { FindListOptions } from '../core/data/request.models';
import { Community } from '../core/shared/community.model'; import { Community } from '../core/shared/community.model';
import { Collection } from '../core/shared/collection.model'; import { Collection } from '../core/shared/collection.model';
import { PageInfo } from '../core/shared/page-info.model'; import { PageInfo } from '../core/shared/page-info.model';
import { hasValue, isNotEmpty } from '../shared/empty.util'; import { hasValue, isNotEmpty } from '../shared/empty.util';
import { RemoteData } from '../core/data/remote-data'; import { RemoteData } from '../core/data/remote-data';
import { PaginatedList, buildPaginatedList } from '../core/data/paginated-list.model'; import { buildPaginatedList, PaginatedList } from '../core/data/paginated-list.model';
import { CollectionDataService } from '../core/data/collection-data.service'; import { CollectionDataService } from '../core/data/collection-data.service';
import { CommunityListSaveAction } from './community-list.actions'; import { CommunityListSaveAction } from './community-list.actions';
import { CommunityListState } from './community-list.reducer'; import { CommunityListState } from './community-list.reducer';
import { getCommunityPageRoute } from '../community-page/community-page-routing-paths'; import { getCommunityPageRoute } from '../community-page/community-page-routing-paths';
import { getCollectionPageRoute } from '../collection-page/collection-page-routing-paths'; import { getCollectionPageRoute } from '../collection-page/collection-page-routing-paths';
import { getFirstSucceededRemoteData, getFirstCompletedRemoteData } from '../core/shared/operators'; import { getFirstCompletedRemoteData, getFirstSucceededRemoteData } from '../core/shared/operators';
import { followLink } from '../shared/utils/follow-link-config.model'; import { followLink } from '../shared/utils/follow-link-config.model';
import { FlatNode } from './flat-node.model';
/** import { ShowMoreFlatNode } from './show-more-flat-node.model';
* Each node in the tree is represented by a flatNode which contains info about the node itself and its position and import { FindListOptions } from '../core/data/find-list-options.model';
* state in the tree. There are nodes representing communities, collections and show more links.
*/
export interface FlatNode {
isExpandable$: Observable<boolean>;
name: string;
id: string;
level: number;
isExpanded?: boolean;
parent?: FlatNode;
payload: Community | Collection | ShowMoreFlatNode;
isShowMoreNode: boolean;
route?: string;
currentCommunityPage?: number;
currentCollectionPage?: number;
}
/**
* The show more links in the community tree are also represented by a flatNode so we know where in
* the tree it should be rendered an who its parent is (needed for the action resulting in clicking this link)
*/
export class ShowMoreFlatNode {
}
// Helper method to combine an flatten an array of observables of flatNode arrays // Helper method to combine an flatten an array of observables of flatNode arrays
export const combineAndFlatten = (obsList: Observable<FlatNode[]>[]): Observable<FlatNode[]> => export const combineAndFlatten = (obsList: Observable<FlatNode[]>[]): Observable<FlatNode[]> =>

View File

@@ -1,6 +1,6 @@
import { Action } from '@ngrx/store'; import { Action } from '@ngrx/store';
import { type } from '../shared/ngrx/type'; import { type } from '../shared/ngrx/type';
import { FlatNode } from './community-list-service'; import { FlatNode } from './flat-node.model';
/** /**
* All the action types of the community-list * All the action types of the community-list

View File

@@ -1,5 +1,5 @@
import { FlatNode } from './community-list-service';
import { CommunityListActions, CommunityListActionTypes, CommunityListSaveAction } from './community-list.actions'; import { CommunityListActions, CommunityListActionTypes, CommunityListSaveAction } from './community-list.actions';
import { FlatNode } from './flat-node.model';
/** /**
* States we wish to put in store concerning the community list * States we wish to put in store concerning the community list

View File

@@ -1,7 +1,7 @@
import { ComponentFixture, fakeAsync, inject, TestBed, tick, waitForAsync } from '@angular/core/testing'; import { ComponentFixture, fakeAsync, inject, TestBed, tick, waitForAsync } from '@angular/core/testing';
import { CommunityListComponent } from './community-list.component'; import { CommunityListComponent } from './community-list.component';
import { CommunityListService, FlatNode, showMoreFlatNode, toFlatNode } from '../community-list-service'; import { CommunityListService, showMoreFlatNode, toFlatNode } from '../community-list-service';
import { CdkTreeModule } from '@angular/cdk/tree'; import { CdkTreeModule } from '@angular/cdk/tree';
import { TranslateLoader, TranslateModule } from '@ngx-translate/core'; import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
import { TranslateLoaderMock } from '../../shared/mocks/translate-loader.mock'; import { TranslateLoaderMock } from '../../shared/mocks/translate-loader.mock';
@@ -15,6 +15,7 @@ import { Collection } from '../../core/shared/collection.model';
import { of as observableOf } from 'rxjs'; import { of as observableOf } from 'rxjs';
import { By } from '@angular/platform-browser'; import { By } from '@angular/platform-browser';
import { isEmpty, isNotEmpty } from '../../shared/empty.util'; import { isEmpty, isNotEmpty } from '../../shared/empty.util';
import { FlatNode } from '../flat-node.model';
describe('CommunityListComponent', () => { describe('CommunityListComponent', () => {
let component: CommunityListComponent; let component: CommunityListComponent;

View File

@@ -1,11 +1,12 @@
import { Component, OnDestroy, OnInit } from '@angular/core'; import { Component, OnDestroy, OnInit } from '@angular/core';
import { take } from 'rxjs/operators'; import { take } from 'rxjs/operators';
import { SortDirection, SortOptions } from '../../core/cache/models/sort-options.model'; import { SortDirection, SortOptions } from '../../core/cache/models/sort-options.model';
import { FindListOptions } from '../../core/data/request.models'; import { CommunityListService} from '../community-list-service';
import { CommunityListService, FlatNode } from '../community-list-service';
import { CommunityListDatasource } from '../community-list-datasource'; import { CommunityListDatasource } from '../community-list-datasource';
import { FlatTreeControl } from '@angular/cdk/tree'; import { FlatTreeControl } from '@angular/cdk/tree';
import { isEmpty } from '../../shared/empty.util'; import { isEmpty } from '../../shared/empty.util';
import { FlatNode } from '../flat-node.model';
import { FindListOptions } from '../../core/data/find-list-options.model';
/** /**
* A tree-structured list of nodes representing the communities, their subCommunities and collections. * A tree-structured list of nodes representing the communities, their subCommunities and collections.

View File

@@ -0,0 +1,22 @@
import { Observable } from 'rxjs';
import { Community } from '../core/shared/community.model';
import { Collection } from '../core/shared/collection.model';
import { ShowMoreFlatNode } from './show-more-flat-node.model';
/**
* Each node in the tree is represented by a flatNode which contains info about the node itself and its position and
* state in the tree. There are nodes representing communities, collections and show more links.
*/
export interface FlatNode {
isExpandable$: Observable<boolean>;
name: string;
id: string;
level: number;
isExpanded?: boolean;
parent?: FlatNode;
payload: Community | Collection | ShowMoreFlatNode;
isShowMoreNode: boolean;
route?: string;
currentCommunityPage?: number;
currentCollectionPage?: number;
}

View File

@@ -0,0 +1,6 @@
/**
* The show more links in the community tree are also represented by a flatNode so we know where in
* the tree it should be rendered an who its parent is (needed for the action resulting in clicking this link)
*/
export class ShowMoreFlatNode {
}

View File

@@ -11,9 +11,9 @@ import { DSOBreadcrumbsService } from '../core/breadcrumbs/dso-breadcrumbs.servi
import { LinkService } from '../core/cache/builders/link.service'; import { LinkService } from '../core/cache/builders/link.service';
import { COMMUNITY_EDIT_PATH, COMMUNITY_CREATE_PATH } from './community-page-routing-paths'; import { COMMUNITY_EDIT_PATH, COMMUNITY_CREATE_PATH } from './community-page-routing-paths';
import { CommunityPageAdministratorGuard } from './community-page-administrator.guard'; import { CommunityPageAdministratorGuard } from './community-page-administrator.guard';
import { MenuItemType } from '../shared/menu/initial-menus-state';
import { LinkMenuItemModel } from '../shared/menu/menu-item/models/link.model'; import { LinkMenuItemModel } from '../shared/menu/menu-item/models/link.model';
import { ThemedCommunityPageComponent } from './themed-community-page.component'; import { ThemedCommunityPageComponent } from './themed-community-page.component';
import { MenuItemType } from '../shared/menu/menu-item-type.model';
@NgModule({ @NgModule({
imports: [ imports: [

View File

@@ -13,11 +13,12 @@ import { MetadataService } from '../core/metadata/metadata.service';
import { fadeInOut } from '../shared/animations/fade'; import { fadeInOut } from '../shared/animations/fade';
import { hasValue } from '../shared/empty.util'; import { hasValue } from '../shared/empty.util';
import { getAllSucceededRemoteDataPayload, redirectOn4xx } from '../core/shared/operators'; import { getAllSucceededRemoteDataPayload} from '../core/shared/operators';
import { AuthService } from '../core/auth/auth.service'; import { AuthService } from '../core/auth/auth.service';
import { AuthorizationDataService } from '../core/data/feature-authorization/authorization-data.service'; import { AuthorizationDataService } from '../core/data/feature-authorization/authorization-data.service';
import { FeatureID } from '../core/data/feature-authorization/feature-id'; import { FeatureID } from '../core/data/feature-authorization/feature-id';
import { getCommunityPageRoute } from './community-page-routing-paths'; import { getCommunityPageRoute } from './community-page-routing-paths';
import { redirectOn4xx } from '../core/shared/authorized.operators';
@Component({ @Component({
selector: 'ds-community-page', selector: 'ds-community-page',

View File

@@ -11,7 +11,6 @@ import { CommunityPageSubCollectionListComponent } from './community-page-sub-co
import { Community } from '../../core/shared/community.model'; import { Community } from '../../core/shared/community.model';
import { SharedModule } from '../../shared/shared.module'; import { SharedModule } from '../../shared/shared.module';
import { CollectionDataService } from '../../core/data/collection-data.service'; import { CollectionDataService } from '../../core/data/collection-data.service';
import { FindListOptions } from '../../core/data/request.models';
import { createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils'; import { createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils';
import { buildPaginatedList } from '../../core/data/paginated-list.model'; import { buildPaginatedList } from '../../core/data/paginated-list.model';
import { PageInfo } from '../../core/shared/page-info.model'; import { PageInfo } from '../../core/shared/page-info.model';
@@ -25,6 +24,7 @@ import { PaginationService } from '../../core/pagination/pagination.service';
import { getMockThemeService } from '../../shared/mocks/theme-service.mock'; import { getMockThemeService } from '../../shared/mocks/theme-service.mock';
import { ThemeService } from '../../shared/theme-support/theme.service'; import { ThemeService } from '../../shared/theme-support/theme.service';
import { PaginationServiceStub } from '../../shared/testing/pagination-service.stub'; import { PaginationServiceStub } from '../../shared/testing/pagination-service.stub';
import { FindListOptions } from '../../core/data/find-list-options.model';
describe('CommunityPageSubCollectionList Component', () => { describe('CommunityPageSubCollectionList Component', () => {
let comp: CommunityPageSubCollectionListComponent; let comp: CommunityPageSubCollectionListComponent;

View File

@@ -13,7 +13,6 @@ import { buildPaginatedList } from '../../core/data/paginated-list.model';
import { PageInfo } from '../../core/shared/page-info.model'; import { PageInfo } from '../../core/shared/page-info.model';
import { SharedModule } from '../../shared/shared.module'; import { SharedModule } from '../../shared/shared.module';
import { createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils'; import { createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils';
import { FindListOptions } from '../../core/data/request.models';
import { HostWindowService } from '../../shared/host-window.service'; import { HostWindowService } from '../../shared/host-window.service';
import { HostWindowServiceStub } from '../../shared/testing/host-window-service.stub'; import { HostWindowServiceStub } from '../../shared/testing/host-window-service.stub';
import { CommunityDataService } from '../../core/data/community-data.service'; import { CommunityDataService } from '../../core/data/community-data.service';
@@ -25,6 +24,7 @@ import { PaginationService } from '../../core/pagination/pagination.service';
import { getMockThemeService } from '../../shared/mocks/theme-service.mock'; import { getMockThemeService } from '../../shared/mocks/theme-service.mock';
import { ThemeService } from '../../shared/theme-support/theme.service'; import { ThemeService } from '../../shared/theme-support/theme.service';
import { PaginationServiceStub } from '../../shared/testing/pagination-service.stub'; import { PaginationServiceStub } from '../../shared/testing/pagination-service.stub';
import { FindListOptions } from '../../core/data/find-list-options.model';
describe('CommunityPageSubCommunityListComponent Component', () => { describe('CommunityPageSubCommunityListComponent Component', () => {
let comp: CommunityPageSubCommunityListComponent; let comp: CommunityPageSubCommunityListComponent;

View File

@@ -3,7 +3,7 @@ import { distinctUntilChanged, filter, map, mergeMap, switchMap, tap } from 'rxj
import { HALEndpointService } from '../shared/hal-endpoint.service'; import { HALEndpointService } from '../shared/hal-endpoint.service';
import { RequestService } from '../data/request.service'; import { RequestService } from '../data/request.service';
import { isNotEmpty } from '../../shared/empty.util'; import { isNotEmpty } from '../../shared/empty.util';
import { GetRequest, PostRequest, RestRequest, } from '../data/request.models'; import { GetRequest, PostRequest, } from '../data/request.models';
import { HttpOptions } from '../dspace-rest/dspace-rest.service'; import { HttpOptions } from '../dspace-rest/dspace-rest.service';
import { getFirstCompletedRemoteData } from '../shared/operators'; import { getFirstCompletedRemoteData } from '../shared/operators';
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
@@ -11,6 +11,7 @@ import { RemoteData } from '../data/remote-data';
import { AuthStatus } from './models/auth-status.model'; 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';
/** /**
* Abstract service to send authentication requests * Abstract service to send authentication requests

View File

@@ -11,9 +11,9 @@ import { Observable } from 'rxjs';
import { map, find, switchMap } from 'rxjs/operators'; import { map, find, switchMap } from 'rxjs/operators';
import { select, Store } from '@ngrx/store'; import { select, Store } from '@ngrx/store';
import { CoreState } from '../core.reducers';
import { isAuthenticated, isAuthenticationLoading } from './selectors'; import { isAuthenticated, isAuthenticationLoading } from './selectors';
import { AuthService, LOGIN_ROUTE } from './auth.service'; import { AuthService, LOGIN_ROUTE } from './auth.service';
import { CoreState } from '../core-state.model';
/** /**
* Prevent unauthorized activating and loading of routes * Prevent unauthorized activating and loading of routes

View File

@@ -2,7 +2,6 @@ import { autoserialize, deserialize, deserializeAs } from 'cerialize';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { link, typedObject } from '../../cache/builders/build-decorators'; import { link, typedObject } from '../../cache/builders/build-decorators';
import { IDToUUIDSerializer } from '../../cache/id-to-uuid-serializer'; import { IDToUUIDSerializer } from '../../cache/id-to-uuid-serializer';
import { CacheableObject } from '../../cache/object-cache.reducer';
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';
@@ -13,6 +12,7 @@ import { AuthError } from './auth-error.model';
import { AUTH_STATUS } from './auth-status.resource-type'; 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';
/** /**
* Object that represents the authenticated status of a user * Object that represents the authenticated status of a user

View File

@@ -1,10 +1,10 @@
import { CacheableObject } from '../../cache/object-cache.reducer';
import { typedObject } from '../../cache/builders/build-decorators'; import { typedObject } from '../../cache/builders/build-decorators';
import { excludeFromEquals } from '../../utilities/equals.decorators'; import { excludeFromEquals } from '../../utilities/equals.decorators';
import { autoserialize, autoserializeAs, deserialize } from 'cerialize'; import { autoserialize, autoserializeAs, deserialize } from 'cerialize';
import { ResourceType } from '../../shared/resource-type'; import { ResourceType } from '../../shared/resource-type';
import { SHORT_LIVED_TOKEN } from './short-lived-token.resource-type'; import { SHORT_LIVED_TOKEN } from './short-lived-token.resource-type';
import { HALLink } from '../../shared/hal-link.model'; import { HALLink } from '../../shared/hal-link.model';
import { CacheableObject } from '../../cache/cacheable-object.model';
/** /**
* A short-lived token that can be used to authenticate a rest request * A short-lived token that can be used to authenticate a rest request

View File

@@ -8,7 +8,7 @@ import { createSelector } from '@ngrx/store';
*/ */
import { AuthState } from './auth.reducer'; import { AuthState } from './auth.reducer';
import { AppState } from '../../app.reducer'; import { AppState } from '../../app.reducer';
import { CoreState } from '../core.reducers'; import { CoreState } from '../core-state.model';
import { coreSelector } from '../core.selectors'; import { coreSelector } from '../core.selectors';
/** /**

View File

@@ -1,9 +1,9 @@
import { ResponseParsingService } from '../data/parsing.service'; import { ResponseParsingService } from '../data/parsing.service';
import { RestRequest } from '../data/request.models';
import { RawRestResponse } from '../dspace-rest/raw-rest-response.model'; import { RawRestResponse } from '../dspace-rest/raw-rest-response.model';
import { RestResponse, TokenResponse } from '../cache/response.models'; import { RestResponse, TokenResponse } from '../cache/response.models';
import { isNotEmpty } from '../../shared/empty.util'; import { isNotEmpty } from '../../shared/empty.util';
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { RestRequest } from '../data/rest-request.model';
@Injectable() @Injectable()
/** /**

View File

@@ -1,7 +1,7 @@
import { BrowseDefinitionDataService } from './browse-definition-data.service'; import { BrowseDefinitionDataService } from './browse-definition-data.service';
import { FindListOptions } from '../data/request.models';
import { followLink } from '../../shared/utils/follow-link-config.model'; import { followLink } from '../../shared/utils/follow-link-config.model';
import { EMPTY } from 'rxjs'; import { EMPTY } from 'rxjs';
import { FindListOptions } from '../data/find-list-options.model';
describe(`BrowseDefinitionDataService`, () => { describe(`BrowseDefinitionDataService`, () => {
let service: BrowseDefinitionDataService; let service: BrowseDefinitionDataService;

View File

@@ -7,7 +7,6 @@ import { BrowseDefinition } from '../shared/browse-definition.model';
import { RequestService } from '../data/request.service'; import { RequestService } from '../data/request.service';
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
import { Store } from '@ngrx/store'; import { Store } from '@ngrx/store';
import { CoreState } from '../core.reducers';
import { ObjectCacheService } from '../cache/object-cache.service'; import { ObjectCacheService } from '../cache/object-cache.service';
import { HALEndpointService } from '../shared/hal-endpoint.service'; import { HALEndpointService } from '../shared/hal-endpoint.service';
import { NotificationsService } from '../../shared/notifications/notifications.service'; import { NotificationsService } from '../../shared/notifications/notifications.service';
@@ -16,8 +15,9 @@ import { DefaultChangeAnalyzer } from '../data/default-change-analyzer.service';
import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model'; import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { RemoteData } from '../data/remote-data'; import { RemoteData } from '../data/remote-data';
import { FindListOptions } from '../data/request.models';
import { PaginatedList } from '../data/paginated-list.model'; import { PaginatedList } from '../data/paginated-list.model';
import { CoreState } from '../core-state.model';
import { FindListOptions } from '../data/find-list-options.model';
class DataServiceImpl extends DataService<BrowseDefinition> { class DataServiceImpl extends DataService<BrowseDefinition> {

View File

@@ -5,7 +5,6 @@ import { getMockRemoteDataBuildService } from '../../shared/mocks/remote-data-bu
import { getMockRequestService } from '../../shared/mocks/request.service.mock'; import { getMockRequestService } from '../../shared/mocks/request.service.mock';
import { HALEndpointServiceStub } from '../../shared/testing/hal-endpoint-service.stub'; import { HALEndpointServiceStub } from '../../shared/testing/hal-endpoint-service.stub';
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
import { RequestEntry } from '../data/request.reducer';
import { RequestService } from '../data/request.service'; import { RequestService } from '../data/request.service';
import { BrowseDefinition } from '../shared/browse-definition.model'; import { BrowseDefinition } from '../shared/browse-definition.model';
import { BrowseEntrySearchOptions } from './browse-entry-search-options.model'; import { BrowseEntrySearchOptions } from './browse-entry-search-options.model';
@@ -13,6 +12,7 @@ import { BrowseService } from './browse.service';
import { createSuccessfulRemoteDataObject, createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils'; import { createSuccessfulRemoteDataObject, createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils';
import { createPaginatedList, getFirstUsedArgumentOfSpyMethod } from '../../shared/testing/utils.test'; import { createPaginatedList, getFirstUsedArgumentOfSpyMethod } from '../../shared/testing/utils.test';
import { getMockHrefOnlyDataService } from '../../shared/mocks/href-only-data.service.mock'; import { getMockHrefOnlyDataService } from '../../shared/mocks/href-only-data.service.mock';
import { RequestEntry } from '../data/request-entry.model';
describe('BrowseService', () => { describe('BrowseService', () => {
let scheduler: TestScheduler; let scheduler: TestScheduler;

View File

@@ -4,11 +4,11 @@ import { GenericConstructor } from '../../shared/generic-constructor';
import { HALResource } from '../../shared/hal-resource.model'; import { HALResource } from '../../shared/hal-resource.model';
import { ResourceType } from '../../shared/resource-type'; import { ResourceType } from '../../shared/resource-type';
import { import {
CacheableObject,
TypedObject,
getResourceTypeValueFor getResourceTypeValueFor
} from '../object-cache.reducer'; } from '../object-cache.reducer';
import { InjectionToken } from '@angular/core'; import { InjectionToken } from '@angular/core';
import { CacheableObject } from '../cacheable-object.model';
import { TypedObject } from '../typed-object.model';
export const DATA_SERVICE_FACTORY = new InjectionToken<(resourceType: ResourceType) => GenericConstructor<any>>('getDataServiceFor', { export const DATA_SERVICE_FACTORY = new InjectionToken<(resourceType: ResourceType) => GenericConstructor<any>>('getDataServiceFor', {
providedIn: 'root', providedIn: 'root',

View File

@@ -2,13 +2,13 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { TestBed } from '@angular/core/testing'; import { TestBed } from '@angular/core/testing';
import { followLink, FollowLinkConfig } from '../../../shared/utils/follow-link-config.model'; import { followLink, FollowLinkConfig } from '../../../shared/utils/follow-link-config.model';
import { FindListOptions } from '../../data/request.models';
import { HALLink } from '../../shared/hal-link.model'; import { HALLink } from '../../shared/hal-link.model';
import { HALResource } from '../../shared/hal-resource.model'; import { HALResource } from '../../shared/hal-resource.model';
import { ResourceType } from '../../shared/resource-type'; import { ResourceType } from '../../shared/resource-type';
import { LinkService } from './link.service'; import { LinkService } from './link.service';
import { DATA_SERVICE_FACTORY, LINK_DEFINITION_FACTORY, LINK_DEFINITION_MAP_FACTORY } from './build-decorators'; import { DATA_SERVICE_FACTORY, LINK_DEFINITION_FACTORY, LINK_DEFINITION_MAP_FACTORY } from './build-decorators';
import { isEmpty } from 'rxjs/operators'; import { isEmpty } from 'rxjs/operators';
import { FindListOptions } from '../../data/find-list-options.model';
const TEST_MODEL = new ResourceType('testmodel'); const TEST_MODEL = new ResourceType('testmodel');
let result: any; let result: any;

View File

@@ -13,10 +13,11 @@ import { RequestService } from '../../data/request.service';
import { UnCacheableObject } from '../../shared/uncacheable-object.model'; import { UnCacheableObject } from '../../shared/uncacheable-object.model';
import { RemoteData } from '../../data/remote-data'; import { RemoteData } from '../../data/remote-data';
import { Observable, of as observableOf } from 'rxjs'; import { Observable, of as observableOf } from 'rxjs';
import { RequestEntry, RequestEntryState } from '../../data/request.reducer';
import { followLink, FollowLinkConfig } from '../../../shared/utils/follow-link-config.model'; import { followLink, FollowLinkConfig } from '../../../shared/utils/follow-link-config.model';
import { take } from 'rxjs/operators'; import { take } from 'rxjs/operators';
import { HALLink } from '../../shared/hal-link.model'; import { HALLink } from '../../shared/hal-link.model';
import { RequestEntryState } from '../../data/request-entry-state.model';
import { RequestEntry } from '../../data/request-entry.model';
describe('RemoteDataBuildService', () => { describe('RemoteDataBuildService', () => {
let service: RemoteDataBuildService; let service: RemoteDataBuildService;

View File

@@ -11,14 +11,7 @@ import { createSuccessfulRemoteDataObject$ } from '../../../shared/remote-data.u
import { FollowLinkConfig, followLink } from '../../../shared/utils/follow-link-config.model'; import { FollowLinkConfig, followLink } from '../../../shared/utils/follow-link-config.model';
import { PaginatedList } from '../../data/paginated-list.model'; import { PaginatedList } from '../../data/paginated-list.model';
import { RemoteData } from '../../data/remote-data'; import { RemoteData } from '../../data/remote-data';
import {
RequestEntry,
ResponseState,
RequestEntryState,
hasSucceeded
} from '../../data/request.reducer';
import { RequestService } from '../../data/request.service'; import { RequestService } from '../../data/request.service';
import { getRequestFromRequestHref, getRequestFromRequestUUID } from '../../shared/operators';
import { ObjectCacheService } from '../object-cache.service'; import { ObjectCacheService } from '../object-cache.service';
import { LinkService } from './link.service'; import { LinkService } from './link.service';
import { HALLink } from '../../shared/hal-link.model'; import { HALLink } from '../../shared/hal-link.model';
@@ -28,6 +21,10 @@ import { HALResource } from '../../shared/hal-resource.model';
import { PAGINATED_LIST } from '../../data/paginated-list.resource-type'; import { PAGINATED_LIST } from '../../data/paginated-list.resource-type';
import { getUrlWithoutEmbedParams } from '../../index/index.selectors'; import { getUrlWithoutEmbedParams } from '../../index/index.selectors';
import { getResourceTypeValueFor } from '../object-cache.reducer'; import { getResourceTypeValueFor } from '../object-cache.reducer';
import { hasSucceeded, RequestEntryState } from '../../data/request-entry-state.model';
import { getRequestFromRequestHref, getRequestFromRequestUUID } from '../../shared/request.operators';
import { RequestEntry } from '../../data/request-entry.model';
import { ResponseState } from '../../data/response-state.model';
@Injectable() @Injectable()
export class RemoteDataBuildService { export class RemoteDataBuildService {

View File

@@ -0,0 +1,22 @@
/* tslint:disable:max-classes-per-file */
import { HALResource } from '../shared/hal-resource.model';
import { HALLink } from '../shared/hal-link.model';
import { TypedObject } from './typed-object.model';
/**
* An interface to represent objects that can be cached
*
* A cacheable object should have a self link
*/
export class CacheableObject extends TypedObject implements HALResource {
uuid?: string;
handle?: string;
_links: {
self: HALLink;
};
// isNew: boolean;
// dirtyType: DirtyType;
// hasDirtyAttributes: boolean;
// changedAttributes: AttributeDiffh;
// save(): void;
}

View File

@@ -2,8 +2,8 @@
import { Action } from '@ngrx/store'; import { Action } from '@ngrx/store';
import { type } from '../../shared/ngrx/type'; import { type } from '../../shared/ngrx/type';
import { CacheableObject } from './object-cache.reducer';
import { Operation } from 'fast-json-patch'; import { Operation } from 'fast-json-patch';
import { CacheableObject } from './cacheable-object.model';
/** /**
* The list of ObjectCacheAction type definitions * The list of ObjectCacheAction type definitions

View File

@@ -1,19 +1,17 @@
/* eslint-disable max-classes-per-file */ /* eslint-disable max-classes-per-file */
import { HALLink } from '../shared/hal-link.model';
import { HALResource } from '../shared/hal-resource.model';
import { import {
AddPatchObjectCacheAction,
AddToObjectCacheAction,
ApplyPatchObjectCacheAction,
ObjectCacheAction, ObjectCacheAction,
ObjectCacheActionTypes, ObjectCacheActionTypes,
AddToObjectCacheAction,
RemoveFromObjectCacheAction, RemoveFromObjectCacheAction,
ResetObjectCacheTimestampsAction, ResetObjectCacheTimestampsAction
AddPatchObjectCacheAction,
ApplyPatchObjectCacheAction
} from './object-cache.actions'; } from './object-cache.actions';
import { hasValue, isNotEmpty } from '../../shared/empty.util'; import { hasValue, isNotEmpty } from '../../shared/empty.util';
import { CacheEntry } from './cache-entry'; import { CacheEntry } from './cache-entry';
import { ResourceType } from '../shared/resource-type';
import { applyPatch, Operation } from 'fast-json-patch'; import { applyPatch, Operation } from 'fast-json-patch';
import { CacheableObject } from './cacheable-object.model';
/** /**
* An interface to represent a JsonPatch * An interface to represent a JsonPatch
@@ -30,11 +28,6 @@ export interface Patch {
operations: Operation[]; operations: Operation[];
} }
export abstract class TypedObject {
static type: ResourceType;
type: ResourceType;
}
/** /**
* Get the string value for an object that may be a string or a ResourceType * Get the string value for an object that may be a string or a ResourceType
* *
@@ -50,24 +43,6 @@ export const getResourceTypeValueFor = (type: any): string => {
} }
}; };
/**
* An interface to represent objects that can be cached
*
* A cacheable object should have a self link
*/
export class CacheableObject extends TypedObject implements HALResource {
uuid?: string;
handle?: string;
_links: {
self: HALLink;
};
// isNew: boolean;
// dirtyType: DirtyType;
// hasDirtyAttributes: boolean;
// changedAttributes: AttributeDiffh;
// save(): void;
}
/** /**
* An entry in the ObjectCache * An entry in the ObjectCache
*/ */

View File

@@ -7,7 +7,7 @@ import { Operation } from 'fast-json-patch';
import { empty, of as observableOf } from 'rxjs'; import { empty, of as observableOf } from 'rxjs';
import { first } from 'rxjs/operators'; import { first } from 'rxjs/operators';
import { coreReducers, CoreState } from '../core.reducers'; import { coreReducers} from '../core.reducers';
import { RestRequestMethod } from '../data/rest-request-method'; import { RestRequestMethod } from '../data/rest-request-method';
import { Item } from '../shared/item.model'; import { Item } from '../shared/item.model';
import { import {
@@ -20,10 +20,11 @@ import { Patch } from './object-cache.reducer';
import { ObjectCacheService } from './object-cache.service'; import { ObjectCacheService } from './object-cache.service';
import { AddToSSBAction } from './server-sync-buffer.actions'; import { AddToSSBAction } from './server-sync-buffer.actions';
import { RemoveFromIndexBySubstringAction } from '../index/index.actions'; import { RemoveFromIndexBySubstringAction } from '../index/index.actions';
import { IndexName } from '../index/index.reducer';
import { HALLink } from '../shared/hal-link.model'; import { HALLink } from '../shared/hal-link.model';
import { storeModuleConfig } from '../../app.reducer'; import { storeModuleConfig } from '../../app.reducer';
import { TestColdObservable } from 'jasmine-marbles/src/test-observables'; import { TestColdObservable } from 'jasmine-marbles/src/test-observables';
import { IndexName } from '../index/index-name.model';
import { CoreState } from '../core-state.model';
describe('ObjectCacheService', () => { describe('ObjectCacheService', () => {
let service: ObjectCacheService; let service: ObjectCacheService;

View File

@@ -5,7 +5,7 @@ import { combineLatest as observableCombineLatest, Observable, of as observableO
import { distinctUntilChanged, filter, map, mergeMap, switchMap, take } from 'rxjs/operators'; import { distinctUntilChanged, filter, map, mergeMap, switchMap, take } from 'rxjs/operators';
import { hasValue, isNotEmpty, isEmpty } from '../../shared/empty.util'; import { hasValue, isNotEmpty, isEmpty } from '../../shared/empty.util';
import { CoreState } from '../core.reducers'; import { CoreState } from '../core-state.model';
import { coreSelector } from '../core.selectors'; import { coreSelector } from '../core.selectors';
import { RestRequestMethod } from '../data/rest-request-method'; import { RestRequestMethod } from '../data/rest-request-method';
import { import {
@@ -22,11 +22,12 @@ import {
RemoveFromObjectCacheAction RemoveFromObjectCacheAction
} from './object-cache.actions'; } from './object-cache.actions';
import { CacheableObject, ObjectCacheEntry, ObjectCacheState } from './object-cache.reducer'; import { ObjectCacheEntry, ObjectCacheState } from './object-cache.reducer';
import { AddToSSBAction } from './server-sync-buffer.actions'; import { AddToSSBAction } from './server-sync-buffer.actions';
import { RemoveFromIndexBySubstringAction } from '../index/index.actions'; import { RemoveFromIndexBySubstringAction } from '../index/index.actions';
import { IndexName } from '../index/index.reducer';
import { HALLink } from '../shared/hal-link.model'; import { HALLink } from '../shared/hal-link.model';
import { CacheableObject } from './cacheable-object.model';
import { IndexName } from '../index/index-name.model';
/** /**
* The base selector function to select the object cache in the store * The base selector function to select the object cache in the store

View File

@@ -1,10 +1,10 @@
/* eslint-disable max-classes-per-file */ /* eslint-disable max-classes-per-file */
import { RequestError } from '../data/request.models';
import { PageInfo } from '../shared/page-info.model'; import { PageInfo } from '../shared/page-info.model';
import { ConfigObject } from '../config/models/config.model'; import { ConfigObject } from '../config/models/config.model';
import { DSpaceObject } from '../shared/dspace-object.model'; import { DSpaceObject } from '../shared/dspace-object.model';
import { HALLink } from '../shared/hal-link.model'; import { HALLink } from '../shared/hal-link.model';
import { UnCacheableObject } from '../shared/uncacheable-object.model'; import { UnCacheableObject } from '../shared/uncacheable-object.model';
import { RequestError } from '../data/request-error.model';
export class RestResponse { export class RestResponse {
public toCache = true; public toCache = true;

View File

@@ -8,7 +8,6 @@ import {
EmptySSBAction, EmptySSBAction,
ServerSyncBufferActionTypes ServerSyncBufferActionTypes
} from './server-sync-buffer.actions'; } from './server-sync-buffer.actions';
import { CoreState } from '../core.reducers';
import { Action, createSelector, MemoizedSelector, select, Store } from '@ngrx/store'; import { Action, createSelector, MemoizedSelector, select, Store } from '@ngrx/store';
import { ServerSyncBufferEntry, ServerSyncBufferState } from './server-sync-buffer.reducer'; import { ServerSyncBufferEntry, ServerSyncBufferState } from './server-sync-buffer.reducer';
import { combineLatest as observableCombineLatest, Observable, of as observableOf } from 'rxjs'; import { combineLatest as observableCombineLatest, Observable, of as observableOf } from 'rxjs';
@@ -22,6 +21,7 @@ import { environment } from '../../../environments/environment';
import { ObjectCacheEntry } from './object-cache.reducer'; import { ObjectCacheEntry } from './object-cache.reducer';
import { Operation } from 'fast-json-patch'; import { Operation } from 'fast-json-patch';
import { NoOpAction } from '../../shared/ngrx/no-op.action'; import { NoOpAction } from '../../shared/ngrx/no-op.action';
import { CoreState } from '../core-state.model';
@Injectable() @Injectable()
export class ServerSyncBufferEffects { export class ServerSyncBufferEffects {

View File

@@ -0,0 +1,6 @@
import { ResourceType } from '../shared/resource-type';
export abstract class TypedObject {
static type: ResourceType;
type: ResourceType;
}

View File

@@ -3,11 +3,12 @@ import { TestScheduler } from 'rxjs/testing';
import { getMockRequestService } from '../../shared/mocks/request.service.mock'; import { getMockRequestService } from '../../shared/mocks/request.service.mock';
import { ConfigService } from './config.service'; import { ConfigService } from './config.service';
import { RequestService } from '../data/request.service'; import { RequestService } from '../data/request.service';
import { FindListOptions, GetRequest } from '../data/request.models'; import { GetRequest } from '../data/request.models';
import { HALEndpointService } from '../shared/hal-endpoint.service'; import { HALEndpointService } from '../shared/hal-endpoint.service';
import { HALEndpointServiceStub } from '../../shared/testing/hal-endpoint-service.stub'; import { HALEndpointServiceStub } from '../../shared/testing/hal-endpoint-service.stub';
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
import { getMockRemoteDataBuildService } from '../../shared/mocks/remote-data-build.service.mock'; import { getMockRemoteDataBuildService } from '../../shared/mocks/remote-data-build.service.mock';
import { FindListOptions } from '../data/find-list-options.model';
const LINK_NAME = 'test'; const LINK_NAME = 'test';
const BROWSE = 'search/findByCollection'; const BROWSE = 'search/findByCollection';

View File

@@ -7,7 +7,6 @@ import { ConfigObject } from './models/config.model';
import { RemoteData } from '../data/remote-data'; import { RemoteData } from '../data/remote-data';
import { DataService } from '../data/data.service'; import { DataService } from '../data/data.service';
import { Store } from '@ngrx/store'; import { Store } from '@ngrx/store';
import { CoreState } from '../core.reducers';
import { ObjectCacheService } from '../cache/object-cache.service'; import { ObjectCacheService } from '../cache/object-cache.service';
import { NotificationsService } from '../../shared/notifications/notifications.service'; import { NotificationsService } from '../../shared/notifications/notifications.service';
import { HttpClient } from '@angular/common/http'; import { HttpClient } from '@angular/common/http';
@@ -15,6 +14,7 @@ import { DefaultChangeAnalyzer } from '../data/default-change-analyzer.service';
import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model'; import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model';
import { getFirstCompletedRemoteData } from '../shared/operators'; import { getFirstCompletedRemoteData } from '../shared/operators';
import { map } from 'rxjs/operators'; import { map } from 'rxjs/operators';
import { CoreState } from '../core-state.model';
class DataServiceImpl extends DataService<ConfigObject> { class DataServiceImpl extends DataService<ConfigObject> {
constructor( constructor(

View File

@@ -1,8 +1,8 @@
import { autoserialize, deserialize } from 'cerialize'; import { autoserialize, deserialize } from 'cerialize';
import { CacheableObject } from '../../cache/object-cache.reducer';
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';
import { CacheableObject } from '../../cache/cacheable-object.model';
export abstract class ConfigObject implements CacheableObject { export abstract class ConfigObject implements CacheableObject {

View File

@@ -7,7 +7,6 @@ import { dataService } from '../cache/builders/build-decorators';
import { SUBMISSION_ACCESSES_TYPE } from './models/config-type'; import { SUBMISSION_ACCESSES_TYPE } from './models/config-type';
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
import { Store } from '@ngrx/store'; import { Store } from '@ngrx/store';
import { CoreState } from '../core.reducers';
import { NotificationsService } from '../../shared/notifications/notifications.service'; import { NotificationsService } from '../../shared/notifications/notifications.service';
import { HttpClient } from '@angular/common/http'; import { HttpClient } from '@angular/common/http';
import { DefaultChangeAnalyzer } from '../data/default-change-analyzer.service'; import { DefaultChangeAnalyzer } from '../data/default-change-analyzer.service';
@@ -16,6 +15,7 @@ import { SubmissionAccessesModel } from './models/config-submission-accesses.mod
import { RemoteData } from '../data/remote-data'; import { RemoteData } from '../data/remote-data';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model'; import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model';
import { CoreState } from '../core-state.model';
/** /**
* Provides methods to retrieve, from REST server, bitstream access conditions configurations applicable during the submission process. * Provides methods to retrieve, from REST server, bitstream access conditions configurations applicable during the submission process.

View File

@@ -5,7 +5,6 @@ import { RequestService } from '../data/request.service';
import { HALEndpointService } from '../shared/hal-endpoint.service'; import { HALEndpointService } from '../shared/hal-endpoint.service';
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
import { Store } from '@ngrx/store'; import { Store } from '@ngrx/store';
import { CoreState } from '../core.reducers';
import { ObjectCacheService } from '../cache/object-cache.service'; import { ObjectCacheService } from '../cache/object-cache.service';
import { NotificationsService } from '../../shared/notifications/notifications.service'; import { NotificationsService } from '../../shared/notifications/notifications.service';
import { HttpClient } from '@angular/common/http'; import { HttpClient } from '@angular/common/http';
@@ -17,6 +16,7 @@ import { SubmissionFormsModel } from './models/config-submission-forms.model';
import { RemoteData } from '../data/remote-data'; import { RemoteData } from '../data/remote-data';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model'; import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model';
import { CoreState } from '../core-state.model';
@Injectable() @Injectable()
@dataService(SUBMISSION_FORMS_TYPE) @dataService(SUBMISSION_FORMS_TYPE)

View File

@@ -7,7 +7,6 @@ import { dataService } from '../cache/builders/build-decorators';
import { SUBMISSION_UPLOADS_TYPE } from './models/config-type'; import { SUBMISSION_UPLOADS_TYPE } from './models/config-type';
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
import { Store } from '@ngrx/store'; import { Store } from '@ngrx/store';
import { CoreState } from '../core.reducers';
import { NotificationsService } from '../../shared/notifications/notifications.service'; import { NotificationsService } from '../../shared/notifications/notifications.service';
import { HttpClient } from '@angular/common/http'; import { HttpClient } from '@angular/common/http';
import { DefaultChangeAnalyzer } from '../data/default-change-analyzer.service'; import { DefaultChangeAnalyzer } from '../data/default-change-analyzer.service';
@@ -16,6 +15,7 @@ import { SubmissionUploadsModel } from './models/config-submission-uploads.model
import { RemoteData } from '../data/remote-data'; import { RemoteData } from '../data/remote-data';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model'; import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model';
import { CoreState } from '../core-state.model';
/** /**
* Provides methods to retrieve, from REST server, bitstream access conditions configurations applicable during the submission process. * Provides methods to retrieve, from REST server, bitstream access conditions configurations applicable during the submission process.

View File

@@ -0,0 +1,30 @@
import {
BitstreamFormatRegistryState
} from '../admin/admin-registries/bitstream-formats/bitstream-format.reducers';
import { ObjectCacheState } from './cache/object-cache.reducer';
import { ServerSyncBufferState } from './cache/server-sync-buffer.reducer';
import { ObjectUpdatesState } from './data/object-updates/object-updates.reducer';
import { HistoryState } from './history/history.reducer';
import { MetaIndexState } from './index/index.reducer';
import { AuthState } from './auth/auth.reducer';
import { JsonPatchOperationsState } from './json-patch/json-patch-operations.reducer';
import { MetaTagState } from './metadata/meta-tag.reducer';
import { RouteState } from './services/route.reducer';
import { RequestState } from './data/request-state.model';
/**
* The core sub-state in the NgRx store
*/
export interface CoreState {
'bitstreamFormats': BitstreamFormatRegistryState;
'cache/object': ObjectCacheState;
'cache/syncbuffer': ServerSyncBufferState;
'cache/object-updates': ObjectUpdatesState;
'data/request': RequestState;
'history': HistoryState;
'index': MetaIndexState;
'auth': AuthState;
'json/patch': JsonPatchOperationsState;
'metaTag': MetaTagState;
'route': RouteState;
}

View File

@@ -38,7 +38,7 @@ import { SubmissionSectionModel } from './config/models/config-submission-sectio
import { SubmissionUploadsModel } from './config/models/config-submission-uploads.model'; import { SubmissionUploadsModel } from './config/models/config-submission-uploads.model';
import { SubmissionFormsConfigService } from './config/submission-forms-config.service'; import { SubmissionFormsConfigService } from './config/submission-forms-config.service';
import { coreEffects } from './core.effects'; import { coreEffects } from './core.effects';
import { coreReducers, CoreState } from './core.reducers'; import { coreReducers} from './core.reducers';
import { BitstreamFormatDataService } from './data/bitstream-format-data.service'; import { BitstreamFormatDataService } from './data/bitstream-format-data.service';
import { CollectionDataService } from './data/collection-data.service'; import { CollectionDataService } from './data/collection-data.service';
import { CommunityDataService } from './data/community-data.service'; import { CommunityDataService } from './data/community-data.service';
@@ -160,6 +160,7 @@ import { RootDataService } from './data/root-data.service';
import { Root } from './data/root.model'; import { Root } from './data/root.model';
import { SearchConfig } from './shared/search/search-filters/search-config.model'; import { SearchConfig } from './shared/search/search-filters/search-config.model';
import { SequenceService } from './shared/sequence.service'; import { SequenceService } from './shared/sequence.service';
import { CoreState } from './core-state.model';
import { GroupDataService } from './eperson/group-data.service'; import { GroupDataService } from './eperson/group-data.service';
import { SubmissionAccessesModel } from './config/models/config-submission-accesses.model'; import { SubmissionAccessesModel } from './config/models/config-submission-accesses.model';

View File

@@ -1,33 +1,19 @@
import { ActionReducerMap, } from '@ngrx/store'; import { ActionReducerMap, } from '@ngrx/store';
import { objectCacheReducer, ObjectCacheState } from './cache/object-cache.reducer'; import { objectCacheReducer } from './cache/object-cache.reducer';
import { indexReducer, MetaIndexState } from './index/index.reducer'; import { indexReducer } from './index/index.reducer';
import { requestReducer, RequestState } from './data/request.reducer'; import { requestReducer } from './data/request.reducer';
import { authReducer, AuthState } from './auth/auth.reducer'; import { authReducer } from './auth/auth.reducer';
import { jsonPatchOperationsReducer, JsonPatchOperationsState } from './json-patch/json-patch-operations.reducer'; import { jsonPatchOperationsReducer } from './json-patch/json-patch-operations.reducer';
import { serverSyncBufferReducer, ServerSyncBufferState } from './cache/server-sync-buffer.reducer'; import { serverSyncBufferReducer } from './cache/server-sync-buffer.reducer';
import { objectUpdatesReducer, ObjectUpdatesState } from './data/object-updates/object-updates.reducer'; import { objectUpdatesReducer } from './data/object-updates/object-updates.reducer';
import { routeReducer, RouteState } from './services/route.reducer'; import { routeReducer } from './services/route.reducer';
import { import {
bitstreamFormatReducer, bitstreamFormatReducer
BitstreamFormatRegistryState
} from '../admin/admin-registries/bitstream-formats/bitstream-format.reducers'; } from '../admin/admin-registries/bitstream-formats/bitstream-format.reducers';
import { historyReducer, HistoryState } from './history/history.reducer'; import { historyReducer } from './history/history.reducer';
import { metaTagReducer, MetaTagState } from './metadata/meta-tag.reducer'; import { metaTagReducer } from './metadata/meta-tag.reducer';
import { CoreState } from './core-state.model';
export interface CoreState {
'bitstreamFormats': BitstreamFormatRegistryState;
'cache/object': ObjectCacheState;
'cache/syncbuffer': ServerSyncBufferState;
'cache/object-updates': ObjectUpdatesState;
'data/request': RequestState;
'history': HistoryState;
'index': MetaIndexState;
'auth': AuthState;
'json/patch': JsonPatchOperationsState;
'metaTag': MetaTagState;
'route': RouteState;
}
export const coreReducers: ActionReducerMap<CoreState> = { export const coreReducers: ActionReducerMap<CoreState> = {
'bitstreamFormats': bitstreamFormatReducer, 'bitstreamFormats': bitstreamFormatReducer,

View File

@@ -1,5 +1,5 @@
import { createFeatureSelector } from '@ngrx/store'; import { createFeatureSelector } from '@ngrx/store';
import { CoreState } from './core.reducers'; import { CoreState } from './core-state.model';
/** /**
* Base selector to select the core state from the store * Base selector to select the core state from the store

View File

@@ -1,9 +1,10 @@
/* eslint-disable max-classes-per-file */ /* eslint-disable max-classes-per-file */
import { BaseResponseParsingService } from './base-response-parsing.service'; import { BaseResponseParsingService } from './base-response-parsing.service';
import { ObjectCacheService } from '../cache/object-cache.service'; import { ObjectCacheService } from '../cache/object-cache.service';
import { CacheableObject } from '../cache/object-cache.reducer'; import { GetRequest} from './request.models';
import { GetRequest, RestRequest } from './request.models';
import { DSpaceObject } from '../shared/dspace-object.model'; import { DSpaceObject } from '../shared/dspace-object.model';
import { CacheableObject } from '../cache/cacheable-object.model';
import { RestRequest } from './rest-request.model';
class TestService extends BaseResponseParsingService { class TestService extends BaseResponseParsingService {
toCache = true; toCache = true;

View File

@@ -1,15 +1,15 @@
/* eslint-disable max-classes-per-file */ /* eslint-disable max-classes-per-file */
import { hasNoValue, hasValue, isNotEmpty } from '../../shared/empty.util'; import { hasNoValue, hasValue, isNotEmpty } from '../../shared/empty.util';
import { DSpaceSerializer } from '../dspace-rest/dspace.serializer'; import { DSpaceSerializer } from '../dspace-rest/dspace.serializer';
import { CacheableObject } from '../cache/object-cache.reducer';
import { Serializer } from '../serializer'; import { Serializer } from '../serializer';
import { PageInfo } from '../shared/page-info.model'; import { PageInfo } from '../shared/page-info.model';
import { ObjectCacheService } from '../cache/object-cache.service'; import { ObjectCacheService } from '../cache/object-cache.service';
import { GenericConstructor } from '../shared/generic-constructor'; import { GenericConstructor } from '../shared/generic-constructor';
import { PaginatedList, buildPaginatedList } from './paginated-list.model'; import { PaginatedList, buildPaginatedList } from './paginated-list.model';
import { getClassForType } from '../cache/builders/build-decorators'; import { getClassForType } from '../cache/builders/build-decorators';
import { RestRequest } from './request.models';
import { environment } from '../../../environments/environment'; import { environment } from '../../../environments/environment';
import { CacheableObject } from '../cache/cacheable-object.model';
import { RestRequest } from './rest-request.model';
/** /**

View File

@@ -9,7 +9,6 @@ import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model';
import { dataService } from '../cache/builders/build-decorators'; import { dataService } from '../cache/builders/build-decorators';
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
import { ObjectCacheService } from '../cache/object-cache.service'; import { ObjectCacheService } from '../cache/object-cache.service';
import { CoreState } from '../core.reducers';
import { Bitstream } from '../shared/bitstream.model'; import { Bitstream } from '../shared/bitstream.model';
import { BITSTREAM } from '../shared/bitstream.resource-type'; import { BITSTREAM } from '../shared/bitstream.resource-type';
import { Bundle } from '../shared/bundle.model'; import { Bundle } from '../shared/bundle.model';
@@ -20,15 +19,17 @@ import { DataService } from './data.service';
import { DSOChangeAnalyzer } from './dso-change-analyzer.service'; import { DSOChangeAnalyzer } from './dso-change-analyzer.service';
import { buildPaginatedList, PaginatedList } from './paginated-list.model'; import { buildPaginatedList, PaginatedList } from './paginated-list.model';
import { RemoteData } from './remote-data'; import { RemoteData } from './remote-data';
import { FindListOptions, PutRequest } from './request.models'; import { PutRequest } from './request.models';
import { RequestService } from './request.service'; import { RequestService } from './request.service';
import { BitstreamFormatDataService } from './bitstream-format-data.service'; import { BitstreamFormatDataService } from './bitstream-format-data.service';
import { BitstreamFormat } from '../shared/bitstream-format.model'; import { BitstreamFormat } from '../shared/bitstream-format.model';
import { HttpOptions } from '../dspace-rest/dspace-rest.service'; import { HttpOptions } from '../dspace-rest/dspace-rest.service';
import { sendRequest } from '../shared/operators';
import { createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils'; import { createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils';
import { PageInfo } from '../shared/page-info.model'; import { PageInfo } from '../shared/page-info.model';
import { RequestParam } from '../cache/models/request-param.model'; import { RequestParam } from '../cache/models/request-param.model';
import { sendRequest } from '../shared/request.operators';
import { CoreState } from '../core-state.model';
import { FindListOptions } from './find-list-options.model';
/** /**
* A service to retrieve {@link Bitstream}s from the REST API * A service to retrieve {@link Bitstream}s from the REST API

View File

@@ -1,5 +1,4 @@
import { BitstreamFormatDataService } from './bitstream-format-data.service'; import { BitstreamFormatDataService } from './bitstream-format-data.service';
import { RequestEntry } from './request.reducer';
import { RestResponse } from '../cache/response.models'; import { RestResponse } from '../cache/response.models';
import { Observable, of as observableOf } from 'rxjs'; import { Observable, of as observableOf } from 'rxjs';
import { Action, Store } from '@ngrx/store'; import { Action, Store } from '@ngrx/store';
@@ -17,8 +16,9 @@ import {
BitstreamFormatsRegistrySelectAction BitstreamFormatsRegistrySelectAction
} from '../../admin/admin-registries/bitstream-formats/bitstream-format.actions'; } from '../../admin/admin-registries/bitstream-formats/bitstream-format.actions';
import { TestScheduler } from 'rxjs/testing'; import { TestScheduler } from 'rxjs/testing';
import { CoreState } from '../core.reducers';
import { createSuccessfulRemoteDataObject } from '../../shared/remote-data.utils'; import { createSuccessfulRemoteDataObject } from '../../shared/remote-data.utils';
import { CoreState } from '../core-state.model';
import { RequestEntry } from './request-entry.model';
describe('BitstreamFormatDataService', () => { describe('BitstreamFormatDataService', () => {
let service: BitstreamFormatDataService; let service: BitstreamFormatDataService;

View File

@@ -13,18 +13,18 @@ import { NotificationsService } from '../../shared/notifications/notifications.s
import { dataService } from '../cache/builders/build-decorators'; import { dataService } from '../cache/builders/build-decorators';
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
import { ObjectCacheService } from '../cache/object-cache.service'; import { ObjectCacheService } from '../cache/object-cache.service';
import { CoreState } from '../core.reducers';
import { coreSelector } from '../core.selectors'; import { coreSelector } from '../core.selectors';
import { BitstreamFormat } from '../shared/bitstream-format.model'; import { BitstreamFormat } from '../shared/bitstream-format.model';
import { BITSTREAM_FORMAT } from '../shared/bitstream-format.resource-type'; import { BITSTREAM_FORMAT } from '../shared/bitstream-format.resource-type';
import { Bitstream } from '../shared/bitstream.model'; import { Bitstream } from '../shared/bitstream.model';
import { HALEndpointService } from '../shared/hal-endpoint.service'; import { HALEndpointService } from '../shared/hal-endpoint.service';
import { sendRequest } from '../shared/operators';
import { DataService } from './data.service'; import { DataService } from './data.service';
import { DefaultChangeAnalyzer } from './default-change-analyzer.service'; import { DefaultChangeAnalyzer } from './default-change-analyzer.service';
import { RemoteData } from './remote-data'; import { RemoteData } from './remote-data';
import { PostRequest, PutRequest } from './request.models'; import { PostRequest, PutRequest } from './request.models';
import { RequestService } from './request.service'; import { RequestService } from './request.service';
import { sendRequest } from '../shared/request.operators';
import { CoreState } from '../core-state.model';
const bitstreamFormatsStateSelector = createSelector( const bitstreamFormatsStateSelector = createSelector(
coreSelector, coreSelector,

View File

@@ -3,7 +3,6 @@ import { Store } from '@ngrx/store';
import { compare, Operation } from 'fast-json-patch'; import { compare, Operation } from 'fast-json-patch';
import { NotificationsService } from '../../shared/notifications/notifications.service'; import { NotificationsService } from '../../shared/notifications/notifications.service';
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
import { CoreState } from '../core.reducers';
import { Item } from '../shared/item.model'; import { Item } from '../shared/item.model';
import { ChangeAnalyzer } from './change-analyzer'; import { ChangeAnalyzer } from './change-analyzer';
import { getMockRequestService } from '../../shared/mocks/request.service.mock'; import { getMockRequestService } from '../../shared/mocks/request.service.mock';
@@ -13,6 +12,7 @@ import { HALLink } from '../shared/hal-link.model';
import { createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils'; import { createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils';
import { createPaginatedList } from '../../shared/testing/utils.test'; import { createPaginatedList } from '../../shared/testing/utils.test';
import { Bundle } from '../shared/bundle.model'; import { Bundle } from '../shared/bundle.model';
import { CoreState } from '../core-state.model';
class DummyChangeAnalyzer implements ChangeAnalyzer<Item> { class DummyChangeAnalyzer implements ChangeAnalyzer<Item> {
diff(object1: Item, object2: Item): Operation[] { diff(object1: Item, object2: Item): Operation[] {

View File

@@ -9,7 +9,6 @@ import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model';
import { dataService } from '../cache/builders/build-decorators'; import { dataService } from '../cache/builders/build-decorators';
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
import { ObjectCacheService } from '../cache/object-cache.service'; import { ObjectCacheService } from '../cache/object-cache.service';
import { CoreState } from '../core.reducers';
import { Bundle } from '../shared/bundle.model'; import { Bundle } from '../shared/bundle.model';
import { BUNDLE } from '../shared/bundle.resource-type'; import { BUNDLE } from '../shared/bundle.resource-type';
import { HALEndpointService } from '../shared/hal-endpoint.service'; import { HALEndpointService } from '../shared/hal-endpoint.service';
@@ -18,11 +17,13 @@ import { DataService } from './data.service';
import { DefaultChangeAnalyzer } from './default-change-analyzer.service'; import { DefaultChangeAnalyzer } from './default-change-analyzer.service';
import { PaginatedList } from './paginated-list.model'; import { PaginatedList } from './paginated-list.model';
import { RemoteData } from './remote-data'; import { RemoteData } from './remote-data';
import { FindListOptions, GetRequest } from './request.models'; import { GetRequest } from './request.models';
import { RequestService } from './request.service'; import { RequestService } from './request.service';
import { PaginatedSearchOptions } from '../../shared/search/models/paginated-search-options.model'; import { PaginatedSearchOptions } from '../../shared/search/models/paginated-search-options.model';
import { Bitstream } from '../shared/bitstream.model'; import { Bitstream } from '../shared/bitstream.model';
import { RequestEntryState } from './request.reducer'; import { RequestEntryState } from './request-entry-state.model';
import { CoreState } from '../core-state.model';
import { FindListOptions } from './find-list-options.model';
/** /**
* A service to retrieve {@link Bundle}s from the REST API * A service to retrieve {@link Bundle}s from the REST API

View File

@@ -1,6 +1,6 @@
import { Operation } from 'fast-json-patch'; import { Operation } from 'fast-json-patch';
import { TypedObject } from '../cache/object-cache.reducer'; import { TypedObject } from '../cache/typed-object.model';
/** /**
* An interface to determine what differs between two * An interface to determine what differs between two

View File

@@ -13,7 +13,6 @@ import { dataService } from '../cache/builders/build-decorators';
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
import { RequestParam } from '../cache/models/request-param.model'; import { RequestParam } from '../cache/models/request-param.model';
import { ObjectCacheService } from '../cache/object-cache.service'; import { ObjectCacheService } from '../cache/object-cache.service';
import { CoreState } from '../core.reducers';
import { HttpOptions } from '../dspace-rest/dspace-rest.service'; import { HttpOptions } from '../dspace-rest/dspace-rest.service';
import { DSpaceSerializer } from '../dspace-rest/dspace.serializer'; import { DSpaceSerializer } from '../dspace-rest/dspace.serializer';
import { Collection } from '../shared/collection.model'; import { Collection } from '../shared/collection.model';
@@ -27,9 +26,15 @@ import { CommunityDataService } from './community-data.service';
import { DSOChangeAnalyzer } from './dso-change-analyzer.service'; import { DSOChangeAnalyzer } from './dso-change-analyzer.service';
import { PaginatedList } from './paginated-list.model'; import { PaginatedList } from './paginated-list.model';
import { RemoteData } from './remote-data'; import { RemoteData } from './remote-data';
import { ContentSourceRequest, FindListOptions, RestRequest, UpdateContentSourceRequest } from './request.models'; import {
ContentSourceRequest,
UpdateContentSourceRequest
} from './request.models';
import { RequestService } from './request.service'; import { RequestService } from './request.service';
import { BitstreamDataService } from './bitstream-data.service'; import { BitstreamDataService } from './bitstream-data.service';
import { RestRequest } from './rest-request.model';
import { CoreState } from '../core-state.model';
import { FindListOptions } from './find-list-options.model';
@Injectable() @Injectable()
@dataService(COLLECTION) @dataService(COLLECTION)
@@ -282,4 +287,12 @@ export class CollectionDataService extends ComColDataService<Collection> {
return this.findAllByHref(item._links.mappedCollections.href, findListOptions); return this.findAllByHref(item._links.mappedCollections.href, findListOptions);
} }
protected getScopeCommunityHref(options: FindListOptions) {
return this.cds.getEndpoint().pipe(
map((endpoint: string) => this.cds.getIDHref(endpoint, options.scopeID)),
filter((href: string) => isNotEmpty(href)),
take(1)
);
}
} }

View File

@@ -7,13 +7,11 @@ import { getMockRequestService } from '../../shared/mocks/request.service.mock';
import { NotificationsService } from '../../shared/notifications/notifications.service'; import { NotificationsService } from '../../shared/notifications/notifications.service';
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
import { ObjectCacheService } from '../cache/object-cache.service'; import { ObjectCacheService } from '../cache/object-cache.service';
import { CoreState } from '../core.reducers';
import { Community } from '../shared/community.model'; import { Community } from '../shared/community.model';
import { HALEndpointService } from '../shared/hal-endpoint.service'; import { HALEndpointService } from '../shared/hal-endpoint.service';
import { ComColDataService } from './comcol-data.service'; import { ComColDataService } from './comcol-data.service';
import { CommunityDataService } from './community-data.service'; import { CommunityDataService } from './community-data.service';
import { DSOChangeAnalyzer } from './dso-change-analyzer.service'; import { DSOChangeAnalyzer } from './dso-change-analyzer.service';
import { FindListOptions } from './request.models';
import { RequestService } from './request.service'; import { RequestService } from './request.service';
import { import {
createFailedRemoteDataObject$, createFailedRemoteDataObject$,
@@ -22,9 +20,17 @@ import {
createSuccessfulRemoteDataObject createSuccessfulRemoteDataObject
} from '../../shared/remote-data.utils'; } from '../../shared/remote-data.utils';
import { BitstreamDataService } from './bitstream-data.service'; import { BitstreamDataService } from './bitstream-data.service';
import { CoreState } from '../core-state.model';
import { FindListOptions } from './find-list-options.model';
const LINK_NAME = 'test'; const LINK_NAME = 'test';
const scopeID = 'd9d30c0c-69b7-4369-8397-ca67c888974d';
const communitiesEndpoint = 'https://rest.api/core/communities';
const communityEndpoint = `${communitiesEndpoint}/${scopeID}`;
class TestService extends ComColDataService<any> { class TestService extends ComColDataService<any> {
constructor( constructor(
@@ -47,6 +53,11 @@ class TestService extends ComColDataService<any> {
// implementation in subclasses for communities/collections // implementation in subclasses for communities/collections
return undefined; return undefined;
} }
protected getScopeCommunityHref(options: FindListOptions): Observable<string> {
// implementation in subclasses for communities/collections
return observableOf(communityEndpoint);
}
} }
/* eslint-disable @typescript-eslint/no-shadow */ /* eslint-disable @typescript-eslint/no-shadow */
@@ -66,12 +77,9 @@ describe('ComColDataService', () => {
const http = {} as HttpClient; const http = {} as HttpClient;
const comparator = {} as any; const comparator = {} as any;
const scopeID = 'd9d30c0c-69b7-4369-8397-ca67c888974d';
const options = Object.assign(new FindListOptions(), { const options = Object.assign(new FindListOptions(), {
scopeID: scopeID scopeID: scopeID
}); });
const communitiesEndpoint = 'https://rest.api/core/communities';
const communityEndpoint = `${communitiesEndpoint}/${scopeID}`;
const scopedEndpoint = `${communityEndpoint}/${LINK_NAME}`; const scopedEndpoint = `${communityEndpoint}/${LINK_NAME}`;
const mockHalService = { const mockHalService = {

View File

@@ -4,10 +4,7 @@ import { hasValue, isEmpty, isNotEmpty } from '../../shared/empty.util';
import { ObjectCacheService } from '../cache/object-cache.service'; import { ObjectCacheService } from '../cache/object-cache.service';
import { Community } from '../shared/community.model'; import { Community } from '../shared/community.model';
import { HALLink } from '../shared/hal-link.model'; import { HALLink } from '../shared/hal-link.model';
import { CommunityDataService } from './community-data.service';
import { DataService } from './data.service'; import { DataService } from './data.service';
import { FindListOptions } from './request.models';
import { PaginatedList } from './paginated-list.model'; import { PaginatedList } from './paginated-list.model';
import { RemoteData } from './remote-data'; import { RemoteData } from './remote-data';
import { HALEndpointService } from '../shared/hal-endpoint.service'; import { HALEndpointService } from '../shared/hal-endpoint.service';
@@ -19,9 +16,9 @@ import { NoContent } from '../shared/NoContent.model';
import { createFailedRemoteDataObject$ } from '../../shared/remote-data.utils'; import { createFailedRemoteDataObject$ } from '../../shared/remote-data.utils';
import { URLCombiner } from '../url-combiner/url-combiner'; import { URLCombiner } from '../url-combiner/url-combiner';
import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model'; import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model';
import { FindListOptions } from './find-list-options.model';
export abstract class ComColDataService<T extends Community | Collection> extends DataService<T> { export abstract class ComColDataService<T extends Community | Collection> extends DataService<T> {
protected abstract cds: CommunityDataService;
protected abstract objectCache: ObjectCacheService; protected abstract objectCache: ObjectCacheService;
protected abstract halService: HALEndpointService; protected abstract halService: HALEndpointService;
protected abstract bitstreamDataService: BitstreamDataService; protected abstract bitstreamDataService: BitstreamDataService;
@@ -40,11 +37,7 @@ export abstract class ComColDataService<T extends Community | Collection> extend
if (isEmpty(options.scopeID)) { if (isEmpty(options.scopeID)) {
return this.halService.getEndpoint(linkPath); return this.halService.getEndpoint(linkPath);
} else { } else {
const scopeCommunityHrefObs = this.cds.getEndpoint().pipe( const scopeCommunityHrefObs = this.getScopeCommunityHref(options);
map((endpoint: string) => this.cds.getIDHref(endpoint, options.scopeID)),
filter((href: string) => isNotEmpty(href)),
take(1)
);
this.createAndSendGetRequest(scopeCommunityHrefObs, true); this.createAndSendGetRequest(scopeCommunityHrefObs, true);
@@ -65,6 +58,8 @@ export abstract class ComColDataService<T extends Community | Collection> extend
} }
} }
protected abstract getScopeCommunityHref(options: FindListOptions): Observable<string>;
protected abstract getFindByParentHref(parentUUID: string): Observable<string>; protected abstract getFindByParentHref(parentUUID: string): Observable<string>;
public findByParent(parentUUID: string, options: FindListOptions = {}, ...linksToFollow: FollowLinkConfig<T>[]): Observable<RemoteData<PaginatedList<T>>> { public findByParent(parentUUID: string, options: FindListOptions = {}, ...linksToFollow: FollowLinkConfig<T>[]): Observable<RemoteData<PaginatedList<T>>> {

View File

@@ -3,12 +3,11 @@ import { Injectable } from '@angular/core';
import { Store } from '@ngrx/store'; import { Store } from '@ngrx/store';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { switchMap } from 'rxjs/operators'; import { filter, map, switchMap, take } from 'rxjs/operators';
import { NotificationsService } from '../../shared/notifications/notifications.service'; import { NotificationsService } from '../../shared/notifications/notifications.service';
import { dataService } from '../cache/builders/build-decorators'; import { dataService } from '../cache/builders/build-decorators';
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
import { ObjectCacheService } from '../cache/object-cache.service'; import { ObjectCacheService } from '../cache/object-cache.service';
import { CoreState } from '../core.reducers';
import { Community } from '../shared/community.model'; import { Community } from '../shared/community.model';
import { COMMUNITY } from '../shared/community.resource-type'; import { COMMUNITY } from '../shared/community.resource-type';
import { HALEndpointService } from '../shared/hal-endpoint.service'; import { HALEndpointService } from '../shared/hal-endpoint.service';
@@ -16,17 +15,18 @@ import { ComColDataService } from './comcol-data.service';
import { DSOChangeAnalyzer } from './dso-change-analyzer.service'; import { DSOChangeAnalyzer } from './dso-change-analyzer.service';
import { PaginatedList } from './paginated-list.model'; import { PaginatedList } from './paginated-list.model';
import { RemoteData } from './remote-data'; import { RemoteData } from './remote-data';
import { FindListOptions } from './request.models';
import { RequestService } from './request.service'; import { RequestService } from './request.service';
import { BitstreamDataService } from './bitstream-data.service'; import { BitstreamDataService } from './bitstream-data.service';
import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model'; import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model';
import { isNotEmpty } from '../../shared/empty.util';
import { CoreState } from '../core-state.model';
import { FindListOptions } from './find-list-options.model';
@Injectable() @Injectable()
@dataService(COMMUNITY) @dataService(COMMUNITY)
export class CommunityDataService extends ComColDataService<Community> { export class CommunityDataService extends ComColDataService<Community> {
protected linkPath = 'communities'; protected linkPath = 'communities';
protected topLinkPath = 'search/top'; protected topLinkPath = 'search/top';
protected cds = this;
constructor( constructor(
protected requestService: RequestService, protected requestService: RequestService,
@@ -58,4 +58,11 @@ export class CommunityDataService extends ComColDataService<Community> {
); );
} }
protected getScopeCommunityHref(options: FindListOptions) {
return this.getEndpoint().pipe(
map((endpoint: string) => this.getIDHref(endpoint, options.scopeID)),
filter((href: string) => isNotEmpty(href)),
take(1)
);
}
} }

View File

@@ -7,7 +7,6 @@ import { NotificationsService } from '../../shared/notifications/notifications.s
import { dataService } from '../cache/builders/build-decorators'; import { dataService } from '../cache/builders/build-decorators';
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
import { ObjectCacheService } from '../cache/object-cache.service'; import { ObjectCacheService } from '../cache/object-cache.service';
import { CoreState } from '../core.reducers';
import { HALEndpointService } from '../shared/hal-endpoint.service'; import { HALEndpointService } from '../shared/hal-endpoint.service';
import { DataService } from './data.service'; import { DataService } from './data.service';
import { RemoteData } from './remote-data'; import { RemoteData } from './remote-data';
@@ -15,6 +14,7 @@ import { RequestService } from './request.service';
import { ConfigurationProperty } from '../shared/configuration-property.model'; import { ConfigurationProperty } from '../shared/configuration-property.model';
import { DefaultChangeAnalyzer } from './default-change-analyzer.service'; import { DefaultChangeAnalyzer } from './default-change-analyzer.service';
import { CONFIG_PROPERTY } from '../shared/config-property.resource-type'; import { CONFIG_PROPERTY } from '../shared/config-property.resource-type';
import { CoreState } from '../core-state.model';
class DataServiceImpl extends DataService<ConfigurationProperty> { class DataServiceImpl extends DataService<ConfigurationProperty> {
protected linkPath = 'properties'; protected linkPath = 'properties';

View File

@@ -4,8 +4,8 @@ import { RawRestResponse } from '../dspace-rest/raw-rest-response.model';
import { DSpaceSerializer } from '../dspace-rest/dspace.serializer'; import { DSpaceSerializer } from '../dspace-rest/dspace.serializer';
import { ContentSource } from '../shared/content-source.model'; import { ContentSource } from '../shared/content-source.model';
import { MetadataConfig } from '../shared/metadata-config.model'; import { MetadataConfig } from '../shared/metadata-config.model';
import { RestRequest } from './request.models';
import { DspaceRestResponseParsingService } from './dspace-rest-response-parsing.service'; import { DspaceRestResponseParsingService } from './dspace-rest-response-parsing.service';
import { RestRequest } from './rest-request.model';
@Injectable() @Injectable()
/** /**

View File

@@ -8,14 +8,13 @@ import { followLink } from '../../shared/utils/follow-link-config.model';
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
import { SortDirection, SortOptions } from '../cache/models/sort-options.model'; import { SortDirection, SortOptions } from '../cache/models/sort-options.model';
import { ObjectCacheService } from '../cache/object-cache.service'; import { ObjectCacheService } from '../cache/object-cache.service';
import { CoreState } from '../core.reducers';
import { DSpaceObject } from '../shared/dspace-object.model'; import { DSpaceObject } from '../shared/dspace-object.model';
import { HALEndpointService } from '../shared/hal-endpoint.service'; import { HALEndpointService } from '../shared/hal-endpoint.service';
import { Item } from '../shared/item.model'; import { Item } from '../shared/item.model';
import { createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils'; import { createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils';
import { ChangeAnalyzer } from './change-analyzer'; import { ChangeAnalyzer } from './change-analyzer';
import { DataService } from './data.service'; import { DataService } from './data.service';
import { FindListOptions, PatchRequest } from './request.models'; import { PatchRequest } from './request.models';
import { RequestService } from './request.service'; import { RequestService } from './request.service';
import { getMockRequestService } from '../../shared/mocks/request.service.mock'; import { getMockRequestService } from '../../shared/mocks/request.service.mock';
import { HALEndpointServiceStub } from '../../shared/testing/hal-endpoint-service.stub'; import { HALEndpointServiceStub } from '../../shared/testing/hal-endpoint-service.stub';
@@ -23,7 +22,9 @@ import { RequestParam } from '../cache/models/request-param.model';
import { getMockRemoteDataBuildService } from '../../shared/mocks/remote-data-build.service.mock'; import { getMockRemoteDataBuildService } from '../../shared/mocks/remote-data-build.service.mock';
import { TestScheduler } from 'rxjs/testing'; import { TestScheduler } from 'rxjs/testing';
import { RemoteData } from './remote-data'; import { RemoteData } from './remote-data';
import { RequestEntryState } from './request.reducer'; import { RequestEntryState } from './request-entry-state.model';
import { CoreState } from '../core-state.model';
import { FindListOptions } from './find-list-options.model';
const endpoint = 'https://rest.api/core'; const endpoint = 'https://rest.api/core';

View File

@@ -21,9 +21,7 @@ import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model';
import { getClassForType } from '../cache/builders/build-decorators'; import { getClassForType } from '../cache/builders/build-decorators';
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
import { RequestParam } from '../cache/models/request-param.model'; import { RequestParam } from '../cache/models/request-param.model';
import { CacheableObject } from '../cache/object-cache.reducer';
import { ObjectCacheService } from '../cache/object-cache.service'; import { ObjectCacheService } from '../cache/object-cache.service';
import { CoreState } from '../core.reducers';
import { DSpaceSerializer } from '../dspace-rest/dspace.serializer'; import { DSpaceSerializer } from '../dspace-rest/dspace.serializer';
import { DSpaceObject } from '../shared/dspace-object.model'; import { DSpaceObject } from '../shared/dspace-object.model';
import { HALEndpointService } from '../shared/hal-endpoint.service'; import { HALEndpointService } from '../shared/hal-endpoint.service';
@@ -35,7 +33,6 @@ import { RemoteData } from './remote-data';
import { import {
CreateRequest, CreateRequest,
GetRequest, GetRequest,
FindListOptions,
PatchRequest, PatchRequest,
PutRequest, PutRequest,
DeleteRequest DeleteRequest
@@ -45,6 +42,9 @@ import { RestRequestMethod } from './rest-request-method';
import { UpdateDataService } from './update-data.service'; import { UpdateDataService } from './update-data.service';
import { GenericConstructor } from '../shared/generic-constructor'; import { GenericConstructor } from '../shared/generic-constructor';
import { NoContent } from '../shared/NoContent.model'; import { NoContent } from '../shared/NoContent.model';
import { CacheableObject } from '../cache/cacheable-object.model';
import { CoreState } from '../core-state.model';
import { FindListOptions } from './find-list-options.model';
export abstract class DataService<T extends CacheableObject> implements UpdateDataService<T> { export abstract class DataService<T extends CacheableObject> implements UpdateDataService<T> {
protected abstract requestService: RequestService; protected abstract requestService: RequestService;

View File

@@ -2,7 +2,7 @@ import { Injectable } from '@angular/core';
import { RestResponse } from '../cache/response.models'; import { RestResponse } from '../cache/response.models';
import { RawRestResponse } from '../dspace-rest/raw-rest-response.model'; import { RawRestResponse } from '../dspace-rest/raw-rest-response.model';
import { ResponseParsingService } from './parsing.service'; import { ResponseParsingService } from './parsing.service';
import { RestRequest } from './request.models'; import { RestRequest } from './rest-request.model';
@Injectable() @Injectable()
export class DebugResponseParsingService implements ResponseParsingService { export class DebugResponseParsingService implements ResponseParsingService {

View File

@@ -2,9 +2,9 @@ import { Injectable } from '@angular/core';
import { compare } from 'fast-json-patch'; import { compare } from 'fast-json-patch';
import { Operation } from 'fast-json-patch'; import { Operation } from 'fast-json-patch';
import { getClassForType } from '../cache/builders/build-decorators'; import { getClassForType } from '../cache/builders/build-decorators';
import { TypedObject } from '../cache/object-cache.reducer';
import { DSpaceNotNullSerializer } from '../dspace-rest/dspace-not-null.serializer'; import { DSpaceNotNullSerializer } from '../dspace-rest/dspace-not-null.serializer';
import { ChangeAnalyzer } from './change-analyzer'; import { ChangeAnalyzer } from './change-analyzer';
import { TypedObject } from '../cache/typed-object.model';
/** /**
* A class to determine what differs between two * A class to determine what differs between two

View File

@@ -6,13 +6,13 @@ import { NotificationsService } from '../../shared/notifications/notifications.s
import { followLink } from '../../shared/utils/follow-link-config.model'; import { followLink } from '../../shared/utils/follow-link-config.model';
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
import { ObjectCacheService } from '../cache/object-cache.service'; import { ObjectCacheService } from '../cache/object-cache.service';
import { CoreState } from '../core.reducers';
import { HALEndpointService } from '../shared/hal-endpoint.service'; import { HALEndpointService } from '../shared/hal-endpoint.service';
import { DsoRedirectDataService } from './dso-redirect-data.service'; import { DsoRedirectDataService } from './dso-redirect-data.service';
import { GetRequest, IdentifierType } from './request.models'; import { GetRequest, IdentifierType } from './request.models';
import { RequestService } from './request.service'; import { RequestService } from './request.service';
import { createSuccessfulRemoteDataObject } from '../../shared/remote-data.utils'; import { createSuccessfulRemoteDataObject } from '../../shared/remote-data.utils';
import { Item } from '../shared/item.model'; import { Item } from '../shared/item.model';
import { CoreState } from '../core-state.model';
describe('DsoRedirectDataService', () => { describe('DsoRedirectDataService', () => {
let scheduler: TestScheduler; let scheduler: TestScheduler;

View File

@@ -9,7 +9,6 @@ import { NotificationsService } from '../../shared/notifications/notifications.s
import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model'; import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model';
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
import { ObjectCacheService } from '../cache/object-cache.service'; import { ObjectCacheService } from '../cache/object-cache.service';
import { CoreState } from '../core.reducers';
import { HALEndpointService } from '../shared/hal-endpoint.service'; import { HALEndpointService } from '../shared/hal-endpoint.service';
import { DataService } from './data.service'; import { DataService } from './data.service';
import { DSOChangeAnalyzer } from './dso-change-analyzer.service'; import { DSOChangeAnalyzer } from './dso-change-analyzer.service';
@@ -20,6 +19,7 @@ import { getFirstCompletedRemoteData } from '../shared/operators';
import { DSpaceObject } from '../shared/dspace-object.model'; import { DSpaceObject } from '../shared/dspace-object.model';
import { Item } from '../shared/item.model'; import { Item } from '../shared/item.model';
import { getItemPageRoute } from '../../item-page/item-page-routing-paths'; import { getItemPageRoute } from '../../item-page/item-page-routing-paths';
import { CoreState } from '../core-state.model';
@Injectable() @Injectable()
export class DsoRedirectDataService extends DataService<any> { export class DsoRedirectDataService extends DataService<any> {

View File

@@ -3,12 +3,12 @@ import { Injectable } from '@angular/core';
import { ObjectCacheService } from '../cache/object-cache.service'; import { ObjectCacheService } from '../cache/object-cache.service';
import { RawRestResponse } from '../dspace-rest/raw-rest-response.model'; import { RawRestResponse } from '../dspace-rest/raw-rest-response.model';
import { RestResponse, DSOSuccessResponse } from '../cache/response.models'; import { RestResponse, DSOSuccessResponse } from '../cache/response.models';
import { RestRequest } from './request.models';
import { ResponseParsingService } from './parsing.service'; import { ResponseParsingService } from './parsing.service';
import { BaseResponseParsingService } from './base-response-parsing.service'; import { BaseResponseParsingService } from './base-response-parsing.service';
import { hasNoValue, hasValue } from '../../shared/empty.util'; import { hasNoValue, hasValue } from '../../shared/empty.util';
import { DSpaceObject } from '../shared/dspace-object.model'; import { DSpaceObject } from '../shared/dspace-object.model';
import { RestRequest } from './rest-request.model';
@Injectable() @Injectable()
export class DSOResponseParsingService extends BaseResponseParsingService implements ResponseParsingService { export class DSOResponseParsingService extends BaseResponseParsingService implements ResponseParsingService {

View File

@@ -8,7 +8,6 @@ import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model';
import { dataService } from '../cache/builders/build-decorators'; import { dataService } from '../cache/builders/build-decorators';
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
import { ObjectCacheService } from '../cache/object-cache.service'; import { ObjectCacheService } from '../cache/object-cache.service';
import { CoreState } from '../core.reducers';
import { DSpaceObject } from '../shared/dspace-object.model'; import { DSpaceObject } from '../shared/dspace-object.model';
import { DSPACE_OBJECT } from '../shared/dspace-object.resource-type'; import { DSPACE_OBJECT } from '../shared/dspace-object.resource-type';
import { HALEndpointService } from '../shared/hal-endpoint.service'; import { HALEndpointService } from '../shared/hal-endpoint.service';
@@ -16,8 +15,9 @@ import { DataService } from './data.service';
import { DSOChangeAnalyzer } from './dso-change-analyzer.service'; import { DSOChangeAnalyzer } from './dso-change-analyzer.service';
import { RemoteData } from './remote-data'; import { RemoteData } from './remote-data';
import { RequestService } from './request.service'; import { RequestService } from './request.service';
import { FindListOptions } from './request.models';
import { PaginatedList } from './paginated-list.model'; import { PaginatedList } from './paginated-list.model';
import { CoreState } from '../core-state.model';
import { FindListOptions } from './find-list-options.model';
class DataServiceImpl extends DataService<DSpaceObject> { class DataServiceImpl extends DataService<DSpaceObject> {
protected linkPath = 'dso'; protected linkPath = 'dso';

View File

@@ -1,14 +1,12 @@
/* eslint-disable max-classes-per-file */ /* eslint-disable max-classes-per-file */
import { hasNoValue, hasValue, isNotEmpty } from '../../shared/empty.util'; import { hasNoValue, hasValue, isNotEmpty } from '../../shared/empty.util';
import { DSpaceSerializer } from '../dspace-rest/dspace.serializer'; import { DSpaceSerializer } from '../dspace-rest/dspace.serializer';
import { CacheableObject } from '../cache/object-cache.reducer';
import { Serializer } from '../serializer'; import { Serializer } from '../serializer';
import { PageInfo } from '../shared/page-info.model'; import { PageInfo } from '../shared/page-info.model';
import { ObjectCacheService } from '../cache/object-cache.service'; import { ObjectCacheService } from '../cache/object-cache.service';
import { GenericConstructor } from '../shared/generic-constructor'; import { GenericConstructor } from '../shared/generic-constructor';
import { PaginatedList, buildPaginatedList } from './paginated-list.model'; import { PaginatedList, buildPaginatedList } from './paginated-list.model';
import { getClassForType } from '../cache/builders/build-decorators'; import { getClassForType } from '../cache/builders/build-decorators';
import { RestRequest } from './request.models';
import { environment } from '../../../environments/environment'; import { environment } from '../../../environments/environment';
import { RawRestResponse } from '../dspace-rest/raw-rest-response.model'; import { RawRestResponse } from '../dspace-rest/raw-rest-response.model';
import { DSpaceObject } from '../shared/dspace-object.model'; import { DSpaceObject } from '../shared/dspace-object.model';
@@ -18,6 +16,8 @@ import { ParsedResponse } from '../cache/response.models';
import { RestRequestMethod } from './rest-request-method'; import { RestRequestMethod } from './rest-request-method';
import { getUrlWithoutEmbedParams, getEmbedSizeParams } from '../index/index.selectors'; import { getUrlWithoutEmbedParams, getEmbedSizeParams } from '../index/index.selectors';
import { URLCombiner } from '../url-combiner/url-combiner'; import { URLCombiner } from '../url-combiner/url-combiner';
import { CacheableObject } from '../cache/cacheable-object.model';
import { RestRequest } from './rest-request.model';
/** /**

View File

@@ -7,12 +7,12 @@ import {
import { hasValue } from '../../shared/empty.util'; import { hasValue } from '../../shared/empty.util';
import { getClassForType } from '../cache/builders/build-decorators'; import { getClassForType } from '../cache/builders/build-decorators';
import { GenericConstructor } from '../shared/generic-constructor'; import { GenericConstructor } from '../shared/generic-constructor';
import { RestRequest } from './request.models';
import { RawRestResponse } from '../dspace-rest/raw-rest-response.model'; import { RawRestResponse } from '../dspace-rest/raw-rest-response.model';
import { ParsedResponse } from '../cache/response.models'; import { ParsedResponse } from '../cache/response.models';
import { DSpaceObject } from '../shared/dspace-object.model'; import { DSpaceObject } from '../shared/dspace-object.model';
import { CacheableObject } from '../cache/object-cache.reducer';
import { environment } from '../../../environments/environment'; import { environment } from '../../../environments/environment';
import { CacheableObject } from '../cache/cacheable-object.model';
import { RestRequest } from './rest-request.model';
/** /**
* ResponseParsingService able to deal with HAL Endpoints that are only needed as steps * ResponseParsingService able to deal with HAL Endpoints that are only needed as steps

View File

@@ -3,14 +3,12 @@ import { DataService } from './data.service';
import { RequestService } from './request.service'; import { RequestService } from './request.service';
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
import { Store } from '@ngrx/store'; import { Store } from '@ngrx/store';
import { CoreState } from '../core.reducers';
import { HALEndpointService } from '../shared/hal-endpoint.service'; import { HALEndpointService } from '../shared/hal-endpoint.service';
import { ObjectCacheService } from '../cache/object-cache.service'; import { ObjectCacheService } from '../cache/object-cache.service';
import { NotificationsService } from '../../shared/notifications/notifications.service'; import { NotificationsService } from '../../shared/notifications/notifications.service';
import { HttpClient } from '@angular/common/http'; import { HttpClient } from '@angular/common/http';
import { DefaultChangeAnalyzer } from './default-change-analyzer.service'; import { DefaultChangeAnalyzer } from './default-change-analyzer.service';
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { FindListOptions } from './request.models';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { filter, map, switchMap, take } from 'rxjs/operators'; import { filter, map, switchMap, take } from 'rxjs/operators';
import { RemoteData } from './remote-data'; import { RemoteData } from './remote-data';
@@ -19,6 +17,8 @@ import { PaginatedList } from './paginated-list.model';
import { ItemType } from '../shared/item-relationships/item-type.model'; import { ItemType } from '../shared/item-relationships/item-type.model';
import { getFirstSucceededRemoteData, getRemoteDataPayload } from '../shared/operators'; import { getFirstSucceededRemoteData, getRemoteDataPayload } from '../shared/operators';
import { RelationshipTypeService } from './relationship-type.service'; import { RelationshipTypeService } from './relationship-type.service';
import { CoreState } from '../core-state.model';
import { FindListOptions } from './find-list-options.model';
/** /**
* Service handling all ItemType requests * Service handling all ItemType requests

View File

@@ -1,7 +1,6 @@
import { RequestService } from './request.service'; import { RequestService } from './request.service';
import { EpersonRegistrationService } from './eperson-registration.service'; import { EpersonRegistrationService } from './eperson-registration.service';
import { RestResponse } from '../cache/response.models'; import { RestResponse } from '../cache/response.models';
import { RequestEntry } from './request.reducer';
import { cold } from 'jasmine-marbles'; import { cold } from 'jasmine-marbles';
import { PostRequest } from './request.models'; import { PostRequest } from './request.models';
import { Registration } from '../shared/registration.model'; import { Registration } from '../shared/registration.model';
@@ -9,6 +8,7 @@ import { HALEndpointServiceStub } from '../../shared/testing/hal-endpoint-servic
import { createSuccessfulRemoteDataObject } from '../../shared/remote-data.utils'; import { createSuccessfulRemoteDataObject } from '../../shared/remote-data.utils';
import { of as observableOf } from 'rxjs'; import { of as observableOf } from 'rxjs';
import { TestScheduler } from 'rxjs/testing'; import { TestScheduler } from 'rxjs/testing';
import { RequestEntry } from './request-entry.model';
describe('EpersonRegistrationService', () => { describe('EpersonRegistrationService', () => {
let testScheduler; let testScheduler;

View File

@@ -4,12 +4,10 @@ import { ExternalSource } from '../shared/external-source.model';
import { RequestService } from './request.service'; import { RequestService } from './request.service';
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
import { Store } from '@ngrx/store'; import { Store } from '@ngrx/store';
import { CoreState } from '../core.reducers';
import { ObjectCacheService } from '../cache/object-cache.service'; import { ObjectCacheService } from '../cache/object-cache.service';
import { HALEndpointService } from '../shared/hal-endpoint.service'; import { HALEndpointService } from '../shared/hal-endpoint.service';
import { NotificationsService } from '../../shared/notifications/notifications.service'; import { NotificationsService } from '../../shared/notifications/notifications.service';
import { HttpClient } from '@angular/common/http'; import { HttpClient } from '@angular/common/http';
import { FindListOptions } from './request.models';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { distinctUntilChanged, map, switchMap, take } from 'rxjs/operators'; import { distinctUntilChanged, map, switchMap, take } from 'rxjs/operators';
import { PaginatedSearchOptions } from '../../shared/search/models/paginated-search-options.model'; import { PaginatedSearchOptions } from '../../shared/search/models/paginated-search-options.model';
@@ -19,6 +17,8 @@ import { PaginatedList } from './paginated-list.model';
import { ExternalSourceEntry } from '../shared/external-source-entry.model'; import { ExternalSourceEntry } from '../shared/external-source-entry.model';
import { DefaultChangeAnalyzer } from './default-change-analyzer.service'; import { DefaultChangeAnalyzer } from './default-change-analyzer.service';
import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model'; import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model';
import { CoreState } from '../core-state.model';
import { FindListOptions } from './find-list-options.model';
/** /**
* A service handling all external source requests * A service handling all external source requests

View File

@@ -3,9 +3,9 @@ import { SearchFilterConfig } from '../../shared/search/models/search-filter-con
import { ParsedResponse } from '../cache/response.models'; import { ParsedResponse } from '../cache/response.models';
import { RawRestResponse } from '../dspace-rest/raw-rest-response.model'; import { RawRestResponse } from '../dspace-rest/raw-rest-response.model';
import { DSpaceSerializer } from '../dspace-rest/dspace.serializer'; import { DSpaceSerializer } from '../dspace-rest/dspace.serializer';
import { RestRequest } from './request.models';
import { DspaceRestResponseParsingService } from './dspace-rest-response-parsing.service'; import { DspaceRestResponseParsingService } from './dspace-rest-response-parsing.service';
import { FacetConfigResponse } from '../../shared/search/models/facet-config-response.model'; import { FacetConfigResponse } from '../../shared/search/models/facet-config-response.model';
import { RestRequest } from './rest-request.model';
@Injectable() @Injectable()
export class FacetConfigResponseParsingService extends DspaceRestResponseParsingService { export class FacetConfigResponseParsingService extends DspaceRestResponseParsingService {

View File

@@ -3,9 +3,9 @@ import { FacetValue } from '../../shared/search/models/facet-value.model';
import { ParsedResponse } from '../cache/response.models'; import { ParsedResponse } from '../cache/response.models';
import { RawRestResponse } from '../dspace-rest/raw-rest-response.model'; import { RawRestResponse } from '../dspace-rest/raw-rest-response.model';
import { DSpaceSerializer } from '../dspace-rest/dspace.serializer'; import { DSpaceSerializer } from '../dspace-rest/dspace.serializer';
import { RestRequest } from './request.models';
import { FacetValues } from '../../shared/search/models/facet-values.model'; import { FacetValues } from '../../shared/search/models/facet-values.model';
import { DspaceRestResponseParsingService } from './dspace-rest-response-parsing.service'; import { DspaceRestResponseParsingService } from './dspace-rest-response-parsing.service';
import { RestRequest } from './rest-request.model';
@Injectable() @Injectable()
export class FacetValueResponseParsingService extends DspaceRestResponseParsingService { export class FacetValueResponseParsingService extends DspaceRestResponseParsingService {

View File

@@ -4,7 +4,6 @@ import { AuthService } from '../../auth/auth.service';
import { Site } from '../../shared/site.model'; import { Site } from '../../shared/site.model';
import { EPerson } from '../../eperson/models/eperson.model'; import { EPerson } from '../../eperson/models/eperson.model';
import { of as observableOf } from 'rxjs'; import { of as observableOf } from 'rxjs';
import { FindListOptions } from '../request.models';
import { FeatureID } from './feature-id'; import { FeatureID } from './feature-id';
import { hasValue } from '../../../shared/empty.util'; import { hasValue } from '../../../shared/empty.util';
import { RequestParam } from '../../cache/models/request-param.model'; import { RequestParam } from '../../cache/models/request-param.model';
@@ -12,6 +11,7 @@ import { Authorization } from '../../shared/authorization.model';
import { createFailedRemoteDataObject$, createSuccessfulRemoteDataObject$ } from '../../../shared/remote-data.utils'; import { createFailedRemoteDataObject$, createSuccessfulRemoteDataObject$ } from '../../../shared/remote-data.utils';
import { createPaginatedList } from '../../../shared/testing/utils.test'; import { createPaginatedList } from '../../../shared/testing/utils.test';
import { Feature } from '../../shared/feature.model'; import { Feature } from '../../shared/feature.model';
import { FindListOptions } from '../find-list-options.model';
describe('AuthorizationDataService', () => { describe('AuthorizationDataService', () => {
let service: AuthorizationDataService; let service: AuthorizationDataService;

View File

@@ -7,7 +7,6 @@ import { Authorization } from '../../shared/authorization.model';
import { RequestService } from '../request.service'; import { RequestService } from '../request.service';
import { RemoteDataBuildService } from '../../cache/builders/remote-data-build.service'; import { RemoteDataBuildService } from '../../cache/builders/remote-data-build.service';
import { Store } from '@ngrx/store'; import { Store } from '@ngrx/store';
import { CoreState } from '../../core.reducers';
import { ObjectCacheService } from '../../cache/object-cache.service'; import { ObjectCacheService } from '../../cache/object-cache.service';
import { HALEndpointService } from '../../shared/hal-endpoint.service'; import { HALEndpointService } from '../../shared/hal-endpoint.service';
import { NotificationsService } from '../../../shared/notifications/notifications.service'; import { NotificationsService } from '../../../shared/notifications/notifications.service';
@@ -15,7 +14,6 @@ import { HttpClient } from '@angular/common/http';
import { DSOChangeAnalyzer } from '../dso-change-analyzer.service'; import { DSOChangeAnalyzer } from '../dso-change-analyzer.service';
import { AuthService } from '../../auth/auth.service'; import { AuthService } from '../../auth/auth.service';
import { SiteDataService } from '../site-data.service'; import { SiteDataService } from '../site-data.service';
import { FindListOptions } from '../request.models';
import { followLink, FollowLinkConfig } from '../../../shared/utils/follow-link-config.model'; import { followLink, FollowLinkConfig } from '../../../shared/utils/follow-link-config.model';
import { RemoteData } from '../remote-data'; import { RemoteData } from '../remote-data';
import { PaginatedList } from '../paginated-list.model'; import { PaginatedList } from '../paginated-list.model';
@@ -26,6 +24,8 @@ import { AuthorizationSearchParams } from './authorization-search-params';
import { addSiteObjectUrlIfEmpty, oneAuthorizationMatchesFeature } from './authorization-utils'; import { addSiteObjectUrlIfEmpty, oneAuthorizationMatchesFeature } from './authorization-utils';
import { FeatureID } from './feature-id'; import { FeatureID } from './feature-id';
import { getFirstCompletedRemoteData } from '../../shared/operators'; import { getFirstCompletedRemoteData } from '../../shared/operators';
import { CoreState } from '../../core-state.model';
import { FindListOptions } from '../find-list-options.model';
/** /**
* A service to retrieve {@link Authorization}s from the REST API * A service to retrieve {@link Authorization}s from the REST API

View File

@@ -2,9 +2,9 @@ import { ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot, UrlTr
import { AuthorizationDataService } from '../authorization-data.service'; import { AuthorizationDataService } from '../authorization-data.service';
import { FeatureID } from '../feature-id'; import { FeatureID } from '../feature-id';
import { combineLatest as observableCombineLatest, Observable, of as observableOf } from 'rxjs'; import { combineLatest as observableCombineLatest, Observable, of as observableOf } from 'rxjs';
import { returnForbiddenUrlTreeOrLoginOnAllFalse } from '../../../shared/operators';
import { switchMap } from 'rxjs/operators'; import { switchMap } from 'rxjs/operators';
import { AuthService } from '../../../auth/auth.service'; import { AuthService } from '../../../auth/auth.service';
import { returnForbiddenUrlTreeOrLoginOnAllFalse } from '../../../shared/authorized.operators';
/** /**
* Abstract Guard for preventing unauthorized activating and loading of routes when a user * Abstract Guard for preventing unauthorized activating and loading of routes when a user

View File

@@ -6,12 +6,12 @@ import { Feature } from '../../shared/feature.model';
import { RequestService } from '../request.service'; import { RequestService } from '../request.service';
import { RemoteDataBuildService } from '../../cache/builders/remote-data-build.service'; import { RemoteDataBuildService } from '../../cache/builders/remote-data-build.service';
import { Store } from '@ngrx/store'; import { Store } from '@ngrx/store';
import { CoreState } from '../../core.reducers';
import { ObjectCacheService } from '../../cache/object-cache.service'; import { ObjectCacheService } from '../../cache/object-cache.service';
import { HALEndpointService } from '../../shared/hal-endpoint.service'; import { HALEndpointService } from '../../shared/hal-endpoint.service';
import { NotificationsService } from '../../../shared/notifications/notifications.service'; import { NotificationsService } from '../../../shared/notifications/notifications.service';
import { HttpClient } from '@angular/common/http'; import { HttpClient } from '@angular/common/http';
import { DSOChangeAnalyzer } from '../dso-change-analyzer.service'; import { DSOChangeAnalyzer } from '../dso-change-analyzer.service';
import { CoreState } from '../../core-state.model';
/** /**
* A service to retrieve {@link Feature}s from the REST API * A service to retrieve {@link Feature}s from the REST API

Some files were not shown because too many files have changed in this diff Show More