Skip to content

Commit 1e9fbee

Browse files
[DURACOM-453] add edit item menu and data service
1 parent 23ecd1e commit 1e9fbee

9 files changed

Lines changed: 519 additions & 8 deletions

File tree

src/app/app.menus.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import { CurationMenuProvider } from './shared/menu/providers/curation.menu';
2121
import { DSpaceObjectEditMenuProvider } from './shared/menu/providers/dso-edit.menu';
2222
import { DsoOptionMenuProvider } from './shared/menu/providers/dso-option.menu';
2323
import { EditMenuProvider } from './shared/menu/providers/edit.menu';
24+
import { EditItemDetailsMenuProvider } from './shared/menu/providers/edit-item-details.menu';
2425
import { ExportMenuProvider } from './shared/menu/providers/export.menu';
2526
import { HealthMenuProvider } from './shared/menu/providers/health.menu';
2627
import { ImportMenuProvider } from './shared/menu/providers/import.menu';
@@ -104,6 +105,9 @@ export const MENUS = buildMenuStructure({
104105
ClaimMenuProvider.onRoute(
105106
MenuRoute.ITEM_PAGE,
106107
),
108+
EditItemDetailsMenuProvider.onRoute(
109+
MenuRoute.ITEM_PAGE,
110+
),
107111
]),
108112
],
109113
});

src/app/core/data-services-map.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ import { VERSION } from './shared/version.resource-type';
5858
import { VERSION_HISTORY } from './shared/version-history.resource-type';
5959
import { USAGE_REPORT } from './statistics/models/usage-report.resource-type';
6060
import { CorrectionType } from './submission/models/correctiontype.model';
61+
import { EditItem } from './submission/models/edititem.model';
6162
import { SUBMISSION_CC_LICENSE } from './submission/models/submission-cc-licence.resource-type';
6263
import { SUBMISSION_CC_LICENSE_URL } from './submission/models/submission-cc-licence-link.resource-type';
6364
import {
@@ -138,4 +139,5 @@ export const LAZY_DATA_SERVICES: LazyDataServicesMap = new Map([
138139
[DUPLICATE.value, () => import('./submission/submission-duplicate-data.service').then(m => m.SubmissionDuplicateDataService)],
139140
[CorrectionType.type.value, () => import('./submission/correctiontype-data.service').then(m => m.CorrectionTypeDataService)],
140141
[AUDIT.value, () => import('./data/audit-data.service').then(m => m.AuditDataService)],
142+
[EditItem.type.value, () => import('./submission/edititem-data.service').then(m => m.EditItemDataService)],
141143
]);
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
/**
2+
* The contents of this file are subject to the license and copyright
3+
* detailed in the LICENSE and NOTICE files at the root of the source
4+
* tree and available online at
5+
*
6+
* http://www.dspace.org/license/
7+
*/
8+
import { TestBed } from '@angular/core/testing';
9+
import { cold } from 'jasmine-marbles';
10+
import { of } from 'rxjs';
11+
12+
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
13+
import { ObjectCacheService } from '../cache/object-cache.service';
14+
import { PaginatedList } from '../data/paginated-list.model';
15+
import { RequestService } from '../data/request.service';
16+
import { NotificationsService } from '../notification-system/notifications.service';
17+
import { HALEndpointService } from '../shared/hal-endpoint.service';
18+
import { createSuccessfulRemoteDataObject } from '../utilities/remote-data.utils';
19+
import { EditItemDataService } from './edititem-data.service';
20+
import { EditItemMode } from './models/edititem-mode.model';
21+
22+
describe('EditItemDataService', () => {
23+
24+
let service: EditItemDataService;
25+
let requestService: RequestService;
26+
27+
const requestServiceStub = jasmine.createSpyObj('RequestService', [
28+
'setStaleByHrefSubstring',
29+
]);
30+
31+
const rdbServiceStub = {} as RemoteDataBuildService;
32+
const objectCacheStub = {} as ObjectCacheService;
33+
const halServiceStub = {} as HALEndpointService;
34+
const notificationsServiceStub = {} as NotificationsService;
35+
36+
const editModes: EditItemMode[] = [
37+
{ uuid: 'mode-1', name: 'quickedit' } as EditItemMode,
38+
{ uuid: 'mode-2', name: 'full' } as EditItemMode,
39+
];
40+
41+
const paginatedList = {
42+
page: editModes,
43+
} as PaginatedList<EditItemMode>;
44+
45+
const successfulRD = createSuccessfulRemoteDataObject(paginatedList);
46+
47+
beforeEach(() => {
48+
49+
TestBed.configureTestingModule({
50+
providers: [
51+
EditItemDataService,
52+
{ provide: RequestService, useValue: requestServiceStub },
53+
{ provide: RemoteDataBuildService, useValue: rdbServiceStub },
54+
{ provide: ObjectCacheService, useValue: objectCacheStub },
55+
{ provide: HALEndpointService, useValue: halServiceStub },
56+
{ provide: NotificationsService, useValue: notificationsServiceStub },
57+
],
58+
});
59+
60+
service = TestBed.inject(EditItemDataService);
61+
62+
spyOn((service as any).searchData, 'searchBy')
63+
.and.returnValue(of(successfulRD));
64+
});
65+
66+
afterEach(() => {
67+
service = null;
68+
});
69+
70+
71+
describe('searchEditModesById', () => {
72+
73+
it('should call SearchDataImpl.searchBy with correct parameters', () => {
74+
75+
service.searchEditModesById('test-id').subscribe();
76+
77+
expect((service as any).searchData.searchBy)
78+
.toHaveBeenCalled();
79+
});
80+
81+
it('should return edit modes', () => {
82+
83+
const result = service.searchEditModesById('test-id');
84+
85+
const expected = cold('(a|)', { a: successfulRD });
86+
87+
expect(result).toBeObservable(expected);
88+
});
89+
90+
});
91+
92+
describe('checkEditModeByIdAndType', () => {
93+
94+
it('should return TRUE when edit mode exists', () => {
95+
96+
const result = service.checkEditModeByIdAndType('test-id', 'mode-1');
97+
98+
const expected = cold('(a|)', { a: true });
99+
100+
expect(result).toBeObservable(expected);
101+
});
102+
103+
it('should return FALSE when edit mode does not exist', () => {
104+
105+
const result = service.checkEditModeByIdAndType('test-id', 'unknown-mode');
106+
107+
const expected = cold('(a|)', { a: false });
108+
109+
expect(result).toBeObservable(expected);
110+
});
111+
112+
});
113+
114+
describe('invalidateItemCache', () => {
115+
116+
it('should mark requests as stale', () => {
117+
118+
service.invalidateItemCache('1234');
119+
120+
expect(requestServiceStub.setStaleByHrefSubstring)
121+
.toHaveBeenCalledWith('findModesById?uuid=1234');
122+
});
123+
124+
});
125+
126+
});
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
/**
2+
* The contents of this file are subject to the license and copyright
3+
* detailed in the LICENSE and NOTICE files at the root of the source
4+
* tree and available online at
5+
*
6+
* http://www.dspace.org/license/
7+
*/
8+
import { Injectable } from '@angular/core';
9+
import { Observable } from 'rxjs';
10+
import { map } from 'rxjs/operators';
11+
12+
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
13+
import { RequestParam } from '../cache/models/request-param.model';
14+
import { ObjectCacheService } from '../cache/object-cache.service';
15+
import { DeleteDataImpl } from '../data/base/delete-data';
16+
import { IdentifiableDataService } from '../data/base/identifiable-data.service';
17+
import { SearchDataImpl } from '../data/base/search-data';
18+
import { FindListOptions } from '../data/find-list-options.model';
19+
import { PaginatedList } from '../data/paginated-list.model';
20+
import { RemoteData } from '../data/remote-data';
21+
import { RequestService } from '../data/request.service';
22+
import { NotificationsService } from '../notification-system/notifications.service';
23+
import { HALEndpointService } from '../shared/hal-endpoint.service';
24+
import {
25+
getAllSucceededRemoteDataPayload,
26+
getPaginatedListPayload,
27+
} from '../shared/operators';
28+
import { EditItem } from './models/edititem.model';
29+
import { EditItemMode } from './models/edititem-mode.model';
30+
31+
/**
32+
* A service that provides methods to make REST requests with edititems endpoint.
33+
*/
34+
@Injectable({ providedIn: 'root' })
35+
export class EditItemDataService extends IdentifiableDataService<EditItem> {
36+
protected linkPath = 'edititems';
37+
protected searchById = 'findModesById';
38+
private searchData: SearchDataImpl<EditItemMode>;
39+
private deleteData: DeleteDataImpl<EditItem>;
40+
41+
constructor(
42+
protected requestService: RequestService,
43+
protected rdbService: RemoteDataBuildService,
44+
protected objectCache: ObjectCacheService,
45+
protected halService: HALEndpointService,
46+
protected notificationsService: NotificationsService,
47+
) {
48+
super('edititems', requestService, rdbService, objectCache, halService);
49+
50+
this.searchData = new SearchDataImpl(this.linkPath, requestService, rdbService, objectCache, halService, this.responseMsToLive);
51+
this.deleteData = new DeleteDataImpl(this.linkPath, requestService, rdbService, objectCache, halService, notificationsService, this.responseMsToLive, this.constructIdEndpoint);
52+
}
53+
54+
/**
55+
* Search for editModes from the editItem id
56+
*
57+
* @param id string id of edit item
58+
* @param useCachedVersionIfAvailable If this is true, the request will only be sent if there's
59+
* no valid cached version. Defaults to true
60+
* @param reRequestOnStale Whether or not the request should automatically be re-
61+
* requested after the response becomes stale
62+
* @return Paginated list of edit item modes
63+
*/
64+
searchEditModesById(id: string, useCachedVersionIfAvailable = true, reRequestOnStale = true): Observable<RemoteData<PaginatedList<EditItemMode>>> {
65+
const options = new FindListOptions();
66+
options.searchParams = [
67+
new RequestParam('uuid', id, false),
68+
];
69+
return this.searchData.searchBy(this.searchById, options, useCachedVersionIfAvailable, reRequestOnStale);
70+
}
71+
72+
/**
73+
* Check if editMode with id is part of the edit item with id
74+
*
75+
* @param id string id of edit item
76+
* @param editModeId string id of edit item
77+
* @return boolean
78+
*/
79+
checkEditModeByIdAndType(id: string, editModeId: string) {
80+
return this.searchEditModesById(id).pipe(
81+
getAllSucceededRemoteDataPayload(),
82+
getPaginatedListPayload(),
83+
map((editModes: EditItemMode[]) => {
84+
return !!editModes.find(editMode => editMode.uuid === editModeId);
85+
}));
86+
}
87+
88+
/**
89+
* Invalidate the cache of the editMode
90+
* @param id
91+
*/
92+
invalidateItemCache(id: string) {
93+
this.requestService.setStaleByHrefSubstring('findModesById?uuid=' + id);
94+
}
95+
96+
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/**
2+
* The contents of this file are subject to the license and copyright
3+
* detailed in the LICENSE and NOTICE files at the root of the source
4+
* tree and available online at
5+
*
6+
* http://www.dspace.org/license/
7+
*/
8+
import {
9+
autoserialize,
10+
deserialize,
11+
deserializeAs,
12+
} from 'cerialize';
13+
14+
import { typedObject } from '../../cache/builders/build-decorators';
15+
import { CacheableObject } from '../../cache/cacheable-object.model';
16+
import { IDToUUIDSerializer } from '../../cache/id-to-uuid-serializer';
17+
import { HALLink } from '../../shared/hal-link.model';
18+
import { ResourceType } from '../../shared/resource-type';
19+
import { excludeFromEquals } from '../../utilities/equals.decorators';
20+
21+
/**
22+
* Describes a EditItem mode
23+
*/
24+
@typedObject
25+
export class EditItemMode extends CacheableObject {
26+
27+
static type = new ResourceType('edititemmode');
28+
29+
/**
30+
* The object type
31+
*/
32+
@excludeFromEquals
33+
@autoserialize
34+
type: ResourceType;
35+
36+
/**
37+
* The universally unique identifier of this WorkspaceItem
38+
* This UUID is generated client-side and isn't used by the backend.
39+
* It is based on the ID, so it will be the same for each refresh.
40+
*/
41+
@deserializeAs(new IDToUUIDSerializer(EditItemMode.type.value), 'name')
42+
uuid: string;
43+
44+
/**
45+
* Name of the EditItem Mode
46+
*/
47+
@autoserialize
48+
name: string;
49+
50+
/**
51+
* Label used for i18n
52+
*/
53+
@autoserialize
54+
label: string;
55+
56+
/**
57+
* Name of the Submission Definition used
58+
* for this EditItem mode
59+
*/
60+
@autoserialize
61+
submissionDefinition: string;
62+
63+
/**
64+
* The {@link HALLink}s for this EditItemMode
65+
*/
66+
@deserialize
67+
_links: {
68+
self: HALLink;
69+
};
70+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/**
2+
* The contents of this file are subject to the license and copyright
3+
* detailed in the LICENSE and NOTICE files at the root of the source
4+
* tree and available online at
5+
*
6+
* http://www.dspace.org/license/
7+
*/
8+
import {
9+
deserializeAs,
10+
inheritSerialization,
11+
} from 'cerialize';
12+
import { Observable } from 'rxjs';
13+
14+
import {
15+
inheritLinkAnnotations,
16+
link,
17+
typedObject,
18+
} from '../../cache/builders/build-decorators';
19+
import { IDToUUIDSerializer } from '../../cache/id-to-uuid-serializer';
20+
import { PaginatedList } from '../../data/paginated-list.model';
21+
import { RemoteData } from '../../data/remote-data';
22+
import { ResourceType } from '../../shared/resource-type';
23+
import { EditItemMode } from './edititem-mode.model';
24+
import { SubmissionObject } from './submission-object.model';
25+
26+
/**
27+
* A model class for a EditItem.
28+
*/
29+
@typedObject
30+
@inheritSerialization(SubmissionObject)
31+
@inheritLinkAnnotations(SubmissionObject)
32+
export class EditItem extends SubmissionObject {
33+
static type = new ResourceType('edititem');
34+
35+
/**
36+
* The universally unique identifier of this WorkspaceItem
37+
* This UUID is generated client-side and isn't used by the backend.
38+
* It is based on the ID, so it will be the same for each refresh.
39+
*/
40+
@deserializeAs(new IDToUUIDSerializer(EditItem.type.value), 'id')
41+
uuid: string;
42+
43+
/**
44+
* Existing EditItem modes for current EditItem
45+
* Will be undefined unless the modes {@link HALLink} has been resolved.
46+
*/
47+
@link(EditItemMode.type)
48+
modes?: Observable<RemoteData<PaginatedList<EditItemMode>>>;
49+
/**
50+
* Existing EditItem modes for current EditItem
51+
* Will be undefined unless the modes {@link HALLink} has been resolved.
52+
*/
53+
@link(EditItemMode.type)
54+
edititemmodes?: Observable<RemoteData<PaginatedList<EditItemMode>>>;
55+
}

0 commit comments

Comments
 (0)