Skip to content

Commit 0025567

Browse files
committed
Merge remote-tracking branch 'origin/main' into CST-6685
2 parents fadcd2e + 7b42446 commit 0025567

53 files changed

Lines changed: 5677 additions & 2428 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

server.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,10 @@ export function app() {
7676
*/
7777
const server = express();
7878

79+
// Tell Express to trust X-FORWARDED-* headers from proxies
80+
// See https://expressjs.com/en/guide/behind-proxies.html
81+
server.set('trust proxy', environment.ui.useProxies);
82+
7983
/*
8084
* If production mode is enabled in the environment file:
8185
* - Enable Angular's production mode

src/app/community-page/edit-community-page/community-roles/community-roles.component.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<ds-comcol-role
2-
*ngFor="let comcolRole of getComcolRoles$() | async"
2+
*ngFor="let comcolRole of comcolRoles$ | async"
33
[dso]="community$ | async"
44
[comcolRole]="comcolRole"
55
>

src/app/community-page/edit-community-page/community-roles/community-roles.component.spec.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,9 @@ describe('CommunityRolesComponent', () => {
7878
fixture.detectChanges();
7979
});
8080

81-
it('should display a community admin role component', () => {
81+
it('should display a community admin role component', (done) => {
8282
expect(de.query(By.css('ds-comcol-role .community-admin')))
8383
.toBeTruthy();
84+
done();
8485
});
8586
});

src/app/community-page/edit-community-page/community-roles/community-roles.component.ts

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -19,28 +19,14 @@ export class CommunityRolesComponent implements OnInit {
1919
dsoRD$: Observable<RemoteData<Community>>;
2020

2121
/**
22-
* The community to manage, as an observable.
22+
* The different roles for the community, as an observable.
2323
*/
24-
get community$(): Observable<Community> {
25-
return this.dsoRD$.pipe(
26-
getFirstSucceededRemoteData(),
27-
getRemoteDataPayload(),
28-
);
29-
}
24+
comcolRoles$: Observable<HALLink[]>;
3025

3126
/**
32-
* The different roles for the community.
27+
* The community to manage, as an observable.
3328
*/
34-
getComcolRoles$(): Observable<HALLink[]> {
35-
return this.community$.pipe(
36-
map((community) => [
37-
{
38-
name: 'community-admin',
39-
href: community._links.adminGroup.href,
40-
},
41-
]),
42-
);
43-
}
29+
community$: Observable<Community>;
4430

4531
constructor(
4632
protected route: ActivatedRoute,
@@ -52,5 +38,22 @@ export class CommunityRolesComponent implements OnInit {
5238
first(),
5339
map((data) => data.dso),
5440
);
41+
42+
this.community$ = this.dsoRD$.pipe(
43+
getFirstSucceededRemoteData(),
44+
getRemoteDataPayload(),
45+
);
46+
47+
/**
48+
* The different roles for the community.
49+
*/
50+
this.comcolRoles$ = this.community$.pipe(
51+
map((community) => [
52+
{
53+
name: 'community-admin',
54+
href: community._links.adminGroup.href,
55+
},
56+
]),
57+
);
5558
}
5659
}

src/app/core/cache/object-cache.actions.ts

Lines changed: 49 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@ export const ObjectCacheActionTypes = {
1313
REMOVE: type('dspace/core/cache/object/REMOVE'),
1414
RESET_TIMESTAMPS: type('dspace/core/cache/object/RESET_TIMESTAMPS'),
1515
ADD_PATCH: type('dspace/core/cache/object/ADD_PATCH'),
16-
APPLY_PATCH: type('dspace/core/cache/object/APPLY_PATCH')
16+
APPLY_PATCH: type('dspace/core/cache/object/APPLY_PATCH'),
17+
ADD_DEPENDENTS: type('dspace/core/cache/object/ADD_DEPENDENTS'),
18+
REMOVE_DEPENDENTS: type('dspace/core/cache/object/REMOVE_DEPENDENTS')
1719
};
1820

1921
/**
@@ -126,13 +128,55 @@ export class ApplyPatchObjectCacheAction implements Action {
126128
}
127129
}
128130

131+
/**
132+
* An NgRx action to add dependent request UUIDs to a cached object
133+
*/
134+
export class AddDependentsObjectCacheAction implements Action {
135+
type = ObjectCacheActionTypes.ADD_DEPENDENTS;
136+
payload: {
137+
href: string;
138+
dependentRequestUUIDs: string[];
139+
};
140+
141+
/**
142+
* Create a new AddDependentsObjectCacheAction
143+
*
144+
* @param href the self link of a cached object
145+
* @param dependentRequestUUIDs the UUID of the request that depends on this object
146+
*/
147+
constructor(href: string, dependentRequestUUIDs: string[]) {
148+
this.payload = {
149+
href,
150+
dependentRequestUUIDs,
151+
};
152+
}
153+
}
154+
155+
/**
156+
* An NgRx action to remove all dependent request UUIDs from a cached object
157+
*/
158+
export class RemoveDependentsObjectCacheAction implements Action {
159+
type = ObjectCacheActionTypes.REMOVE_DEPENDENTS;
160+
payload: string;
161+
162+
/**
163+
* Create a new RemoveDependentsObjectCacheAction
164+
*
165+
* @param href the self link of a cached object for which to remove all dependent request UUIDs
166+
*/
167+
constructor(href: string) {
168+
this.payload = href;
169+
}
170+
}
129171

130172
/**
131173
* A type to encompass all ObjectCacheActions
132174
*/
133175
export type ObjectCacheAction
134176
= AddToObjectCacheAction
135-
| RemoveFromObjectCacheAction
136-
| ResetObjectCacheTimestampsAction
137-
| AddPatchObjectCacheAction
138-
| ApplyPatchObjectCacheAction;
177+
| RemoveFromObjectCacheAction
178+
| ResetObjectCacheTimestampsAction
179+
| AddPatchObjectCacheAction
180+
| ApplyPatchObjectCacheAction
181+
| AddDependentsObjectCacheAction
182+
| RemoveDependentsObjectCacheAction;

src/app/core/cache/object-cache.reducer.spec.ts

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,13 @@ import * as deepFreeze from 'deep-freeze';
22
import { Operation } from 'fast-json-patch';
33
import { Item } from '../shared/item.model';
44
import {
5+
AddDependentsObjectCacheAction,
56
AddPatchObjectCacheAction,
67
AddToObjectCacheAction,
78
ApplyPatchObjectCacheAction,
9+
RemoveDependentsObjectCacheAction,
810
RemoveFromObjectCacheAction,
9-
ResetObjectCacheTimestampsAction
11+
ResetObjectCacheTimestampsAction,
1012
} from './object-cache.actions';
1113

1214
import { objectCacheReducer } from './object-cache.reducer';
@@ -42,20 +44,22 @@ describe('objectCacheReducer', () => {
4244
timeCompleted: new Date().getTime(),
4345
msToLive: 900000,
4446
requestUUIDs: [requestUUID1],
47+
dependentRequestUUIDs: [],
4548
patches: [],
4649
isDirty: false,
4750
},
4851
[selfLink2]: {
4952
data: {
5053
type: Item.type,
51-
self: requestUUID2,
54+
self: selfLink2,
5255
foo: 'baz',
53-
_links: { self: { href: requestUUID2 } }
56+
_links: { self: { href: selfLink2 } }
5457
},
5558
alternativeLinks: [altLink3, altLink4],
5659
timeCompleted: new Date().getTime(),
5760
msToLive: 900000,
58-
requestUUIDs: [selfLink2],
61+
requestUUIDs: [requestUUID2],
62+
dependentRequestUUIDs: [requestUUID1],
5963
patches: [],
6064
isDirty: false
6165
}
@@ -189,4 +193,20 @@ describe('objectCacheReducer', () => {
189193
expect((newState[selfLink1].data as any).name).toEqual(newName);
190194
});
191195

196+
it('should add dependent requests on ADD_DEPENDENTS', () => {
197+
let newState = objectCacheReducer(testState, new AddDependentsObjectCacheAction(selfLink1, ['new', 'newer', 'newest']));
198+
expect(newState[selfLink1].dependentRequestUUIDs).toEqual(['new', 'newer', 'newest']);
199+
200+
newState = objectCacheReducer(newState, new AddDependentsObjectCacheAction(selfLink2, ['more']));
201+
expect(newState[selfLink2].dependentRequestUUIDs).toEqual([requestUUID1, 'more']);
202+
});
203+
204+
it('should clear dependent requests on REMOVE_DEPENDENTS', () => {
205+
let newState = objectCacheReducer(testState, new RemoveDependentsObjectCacheAction(selfLink1));
206+
expect(newState[selfLink1].dependentRequestUUIDs).toEqual([]);
207+
208+
newState = objectCacheReducer(newState, new RemoveDependentsObjectCacheAction(selfLink2));
209+
expect(newState[selfLink2].dependentRequestUUIDs).toEqual([]);
210+
});
211+
192212
});

src/app/core/cache/object-cache.reducer.ts

Lines changed: 64 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
/* eslint-disable max-classes-per-file */
22
import {
3+
AddDependentsObjectCacheAction,
34
AddPatchObjectCacheAction,
45
AddToObjectCacheAction,
56
ApplyPatchObjectCacheAction,
67
ObjectCacheAction,
7-
ObjectCacheActionTypes,
8+
ObjectCacheActionTypes, RemoveDependentsObjectCacheAction,
89
RemoveFromObjectCacheAction,
9-
ResetObjectCacheTimestampsAction
10+
ResetObjectCacheTimestampsAction,
1011
} from './object-cache.actions';
1112
import { hasValue, isNotEmpty } from '../../shared/empty.util';
1213
import { CacheEntry } from './cache-entry';
@@ -69,6 +70,12 @@ export class ObjectCacheEntry implements CacheEntry {
6970
*/
7071
requestUUIDs: string[];
7172

73+
/**
74+
* A list of UUIDs for the requests that depend on this object.
75+
* When this object is invalidated, these requests will be invalidated as well.
76+
*/
77+
dependentRequestUUIDs: string[];
78+
7279
/**
7380
* An array of patches that were made on the client side to this entry, but haven't been sent to the server yet
7481
*/
@@ -134,6 +141,14 @@ export function objectCacheReducer(state = initialState, action: ObjectCacheActi
134141
return applyPatchObjectCache(state, action as ApplyPatchObjectCacheAction);
135142
}
136143

144+
case ObjectCacheActionTypes.ADD_DEPENDENTS: {
145+
return addDependentsObjectCacheState(state, action as AddDependentsObjectCacheAction);
146+
}
147+
148+
case ObjectCacheActionTypes.REMOVE_DEPENDENTS: {
149+
return removeDependentsObjectCacheState(state, action as RemoveDependentsObjectCacheAction);
150+
}
151+
137152
default: {
138153
return state;
139154
}
@@ -159,6 +174,7 @@ function addToObjectCache(state: ObjectCacheState, action: AddToObjectCacheActio
159174
timeCompleted: action.payload.timeCompleted,
160175
msToLive: action.payload.msToLive,
161176
requestUUIDs: [action.payload.requestUUID, ...(existing.requestUUIDs || [])],
177+
dependentRequestUUIDs: existing.dependentRequestUUIDs || [],
162178
isDirty: isNotEmpty(existing.patches),
163179
patches: existing.patches || [],
164180
alternativeLinks: [...(existing.alternativeLinks || []), ...newAltLinks]
@@ -252,3 +268,49 @@ function applyPatchObjectCache(state: ObjectCacheState, action: ApplyPatchObject
252268
}
253269
return newState;
254270
}
271+
272+
/**
273+
* Add a list of dependent request UUIDs to a cached object, used when defining new dependencies
274+
*
275+
* @param state the current state
276+
* @param action an AddDependentsObjectCacheAction
277+
* @return the new state, with the dependent requests of the cached object updated
278+
*/
279+
function addDependentsObjectCacheState(state: ObjectCacheState, action: AddDependentsObjectCacheAction): ObjectCacheState {
280+
const href = action.payload.href;
281+
const newState = Object.assign({}, state);
282+
283+
if (hasValue(newState[href])) {
284+
newState[href] = Object.assign({}, newState[href], {
285+
dependentRequestUUIDs: [
286+
...new Set([
287+
...newState[href]?.dependentRequestUUIDs || [],
288+
...action.payload.dependentRequestUUIDs,
289+
])
290+
]
291+
});
292+
}
293+
294+
return newState;
295+
}
296+
297+
298+
/**
299+
* Remove all dependent request UUIDs from a cached object, used to clear out-of-date depedencies
300+
*
301+
* @param state the current state
302+
* @param action an AddDependentsObjectCacheAction
303+
* @return the new state, with the dependent requests of the cached object updated
304+
*/
305+
function removeDependentsObjectCacheState(state: ObjectCacheState, action: RemoveDependentsObjectCacheAction): ObjectCacheState {
306+
const href = action.payload;
307+
const newState = Object.assign({}, state);
308+
309+
if (hasValue(newState[href])) {
310+
newState[href] = Object.assign({}, newState[href], {
311+
dependentRequestUUIDs: []
312+
});
313+
}
314+
315+
return newState;
316+
}

0 commit comments

Comments
 (0)