Skip to content

Commit e4b2814

Browse files
Merge branch 'main' of https://bitbucket.org/4Science/dspace-angular into CST-12109-WITHDRAWN-REINSTATE-requests
2 parents 447b275 + 91a419f commit e4b2814

80 files changed

Lines changed: 2912 additions & 760 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.

config/config.example.yml

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ submission:
136136
# NOTE: example of configuration
137137
# # NOTE: metadata name
138138
# - name: dc.author
139-
# # NOTE: fontawesome (v5.x) icon classes and bootstrap utility classes can be used
139+
# # NOTE: fontawesome (v6.x) icon classes and bootstrap utility classes can be used
140140
# style: fas fa-user
141141
- name: dc.author
142142
style: fas fa-user
@@ -147,18 +147,40 @@ submission:
147147
confidence:
148148
# NOTE: example of configuration
149149
# # NOTE: confidence value
150-
# - name: dc.author
151-
# # NOTE: fontawesome (v5.x) icon classes and bootstrap utility classes can be used
152-
# style: fa-user
150+
# - value: 600
151+
# # NOTE: fontawesome (v6.x) icon classes and bootstrap utility classes can be used
152+
# style: text-success
153+
# icon: fa-circle-check
154+
# # NOTE: the class configured in property style is used by default, the icon property could be used in component
155+
# configured to use a 'icon mode' display (mainly in edit-item page)
153156
- value: 600
154157
style: text-success
158+
icon: fa-circle-check
155159
- value: 500
156160
style: text-info
161+
icon: fa-gear
157162
- value: 400
158163
style: text-warning
164+
icon: fa-circle-question
165+
- value: 300
166+
style: text-muted
167+
icon: fa-thumbs-down
168+
- value: 200
169+
style: text-muted
170+
icon: fa-circle-exclamation
171+
- value: 100
172+
style: text-muted
173+
icon: fa-circle-stop
174+
- value: 0
175+
style: text-muted
176+
icon: fa-ban
177+
- value: -1
178+
style: text-muted
179+
icon: fa-circle-xmark
159180
# default configuration
160181
- value: default
161182
style: text-muted
183+
icon: fa-circle-xmark
162184

163185
# Default Language in which the UI will be rendered if the user's browser language is not an active language
164186
defaultLanguage: en
@@ -272,6 +294,8 @@ homePage:
272294
# No. of communities to list per page on the home page
273295
# This will always round to the nearest number from the list of page sizes. e.g. if you set it to 7 it'll use 10
274296
pageSize: 5
297+
# Enable or disable the Discover filters on the homepage
298+
showDiscoverFilters: false
275299

276300
# Item Config
277301
item:
@@ -400,3 +424,12 @@ comcolSelectionSort:
400424
# suggestion:
401425
# - collectionId: 8f7df5ca-f9c2-47a4-81ec-8a6393d6e5af
402426
# source: "openaire"
427+
428+
429+
# Search settings
430+
search:
431+
# Settings to enable/disable or configure advanced search filters.
432+
advancedFilters:
433+
enabled: false
434+
# List of filters to enable in "Advanced Search" dropdown
435+
filter: [ 'title', 'author', 'subject', 'entityType' ]

src/app/collection-page/collection-page.component.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,4 +58,4 @@
5858
<ds-themed-loading *ngIf="collectionRD?.isLoading"
5959
message="{{'loading.collection' | translate}}"></ds-themed-loading>
6060
</div>
61-
</div>
61+
</div>

src/app/collection-page/edit-collection-page/collection-source/collection-source-controls/collection-source-controls.component.spec.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ describe('CollectionSourceControlsComponent', () => {
8888
invoke: createSuccessfulRemoteDataObject$(process),
8989
});
9090
processDataService = jasmine.createSpyObj('processDataService', {
91-
findById: createSuccessfulRemoteDataObject$(process),
91+
autoRefreshUntilCompletion: createSuccessfulRemoteDataObject$(process),
9292
});
9393
bitstreamService = jasmine.createSpyObj('bitstreamService', {
9494
findByHref: createSuccessfulRemoteDataObject$(bitstream),
@@ -137,7 +137,7 @@ describe('CollectionSourceControlsComponent', () => {
137137
{name: '-i', value: new ContentSourceSetSerializer().Serialize(contentSource.oaiSetId)},
138138
], []);
139139

140-
expect(processDataService.findById).toHaveBeenCalledWith(process.processId, false);
140+
expect(processDataService.autoRefreshUntilCompletion).toHaveBeenCalledWith(process.processId);
141141
expect(bitstreamService.findByHref).toHaveBeenCalledWith(process._links.output.href);
142142
expect(notificationsService.info).toHaveBeenCalledWith(jasmine.anything() as any, 'Script text');
143143
});
@@ -151,7 +151,7 @@ describe('CollectionSourceControlsComponent', () => {
151151
{name: '-r', value: null},
152152
{name: '-c', value: collection.uuid},
153153
], []);
154-
expect(processDataService.findById).toHaveBeenCalledWith(process.processId, false);
154+
expect(processDataService.autoRefreshUntilCompletion).toHaveBeenCalledWith(process.processId);
155155
expect(notificationsService.success).toHaveBeenCalled();
156156
});
157157
});
@@ -164,7 +164,7 @@ describe('CollectionSourceControlsComponent', () => {
164164
{name: '-o', value: null},
165165
{name: '-c', value: collection.uuid},
166166
], []);
167-
expect(processDataService.findById).toHaveBeenCalledWith(process.processId, false);
167+
expect(processDataService.autoRefreshUntilCompletion).toHaveBeenCalledWith(process.processId);
168168
expect(notificationsService.success).toHaveBeenCalled();
169169
});
170170
});

src/app/collection-page/edit-collection-page/collection-source/collection-source-controls/collection-source-controls.component.ts

Lines changed: 55 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
1-
import { Component, Input, OnDestroy } from '@angular/core';
1+
import { Component, Input, OnDestroy, OnInit } from '@angular/core';
22
import { ScriptDataService } from '../../../../core/data/processes/script-data.service';
33
import { ContentSource } from '../../../../core/shared/content-source.model';
44
import { ProcessDataService } from '../../../../core/data/processes/process-data.service';
55
import {
6-
getAllCompletedRemoteData,
76
getAllSucceededRemoteDataPayload,
87
getFirstCompletedRemoteData,
98
getFirstSucceededRemoteDataPayload
109
} from '../../../../core/shared/operators';
1110
import { filter, map, switchMap, tap } from 'rxjs/operators';
12-
import { hasValue, hasValueOperator } from '../../../../shared/empty.util';
11+
import { hasValue } from '../../../../shared/empty.util';
1312
import { ProcessStatus } from '../../../../process-page/processes/process-status.model';
1413
import { BehaviorSubject, Observable, Subscription } from 'rxjs';
1514
import { RequestService } from '../../../../core/data/request.service';
@@ -30,7 +29,7 @@ import { ContentSourceSetSerializer } from '../../../../core/shared/content-sour
3029
styleUrls: ['./collection-source-controls.component.scss'],
3130
templateUrl: './collection-source-controls.component.html',
3231
})
33-
export class CollectionSourceControlsComponent implements OnDestroy {
32+
export class CollectionSourceControlsComponent implements OnInit, OnDestroy {
3433

3534
/**
3635
* Should the controls be enabled.
@@ -49,6 +48,7 @@ export class CollectionSourceControlsComponent implements OnDestroy {
4948

5049
contentSource$: Observable<ContentSource>;
5150
private subs: Subscription[] = [];
51+
private autoRefreshIDs: string[] = [];
5252

5353
testConfigRunning$ = new BehaviorSubject(false);
5454
importRunning$ = new BehaviorSubject(false);
@@ -95,36 +95,28 @@ export class CollectionSourceControlsComponent implements OnDestroy {
9595
}),
9696
// filter out responses that aren't successful since the pinging of the process only needs to happen when the invocation was successful.
9797
filter((rd) => rd.hasSucceeded && hasValue(rd.payload)),
98-
switchMap((rd) => this.processDataService.findById(rd.payload.processId, false)),
99-
getAllCompletedRemoteData(),
100-
filter((rd) => !rd.isStale && (rd.hasSucceeded || rd.hasFailed)),
101-
map((rd) => rd.payload),
102-
hasValueOperator(),
98+
switchMap((rd) => {
99+
this.autoRefreshIDs.push(rd.payload.processId);
100+
return this.processDataService.autoRefreshUntilCompletion(rd.payload.processId);
101+
}),
102+
map((rd) => rd.payload)
103103
).subscribe((process: Process) => {
104-
if (process.processStatus.toString() !== ProcessStatus[ProcessStatus.COMPLETED].toString() &&
105-
process.processStatus.toString() !== ProcessStatus[ProcessStatus.FAILED].toString()) {
106-
// Ping the current process state every 5s
107-
setTimeout(() => {
108-
this.requestService.setStaleByHrefSubstring(process._links.self.href);
109-
}, 5000);
110-
}
111-
if (process.processStatus.toString() === ProcessStatus[ProcessStatus.FAILED].toString()) {
112-
this.notificationsService.error(this.translateService.get('collection.source.controls.test.failed'));
113-
this.testConfigRunning$.next(false);
114-
}
115-
if (process.processStatus.toString() === ProcessStatus[ProcessStatus.COMPLETED].toString()) {
116-
this.bitstreamService.findByHref(process._links.output.href).pipe(getFirstSucceededRemoteDataPayload()).subscribe((bitstream) => {
117-
this.httpClient.get(bitstream._links.content.href, {responseType: 'text'}).subscribe((data: any) => {
118-
const output = data.replaceAll(new RegExp('.*\\@(.*)', 'g'), '$1')
119-
.replaceAll('The script has started', '')
120-
.replaceAll('The script has completed', '');
121-
this.notificationsService.info(this.translateService.get('collection.source.controls.test.completed'), output);
122-
});
104+
if (process.processStatus.toString() === ProcessStatus[ProcessStatus.FAILED].toString()) {
105+
this.notificationsService.error(this.translateService.get('collection.source.controls.test.failed'));
106+
this.testConfigRunning$.next(false);
107+
}
108+
if (process.processStatus.toString() === ProcessStatus[ProcessStatus.COMPLETED].toString()) {
109+
this.bitstreamService.findByHref(process._links.output.href).pipe(getFirstSucceededRemoteDataPayload()).subscribe((bitstream) => {
110+
this.httpClient.get(bitstream._links.content.href, {responseType: 'text'}).subscribe((data: any) => {
111+
const output = data.replaceAll(new RegExp('.*\\@(.*)', 'g'), '$1')
112+
.replaceAll('The script has started', '')
113+
.replaceAll('The script has completed', '');
114+
this.notificationsService.info(this.translateService.get('collection.source.controls.test.completed'), output);
123115
});
124-
this.testConfigRunning$.next(false);
125-
}
116+
});
117+
this.testConfigRunning$.next(false);
126118
}
127-
));
119+
}));
128120
}
129121

130122
/**
@@ -147,31 +139,22 @@ export class CollectionSourceControlsComponent implements OnDestroy {
147139
}
148140
}),
149141
filter((rd) => rd.hasSucceeded && hasValue(rd.payload)),
150-
switchMap((rd) => this.processDataService.findById(rd.payload.processId, false)),
151-
getAllCompletedRemoteData(),
152-
filter((rd) => !rd.isStale && (rd.hasSucceeded || rd.hasFailed)),
153-
map((rd) => rd.payload),
154-
hasValueOperator(),
142+
switchMap((rd) => {
143+
this.autoRefreshIDs.push(rd.payload.processId);
144+
return this.processDataService.autoRefreshUntilCompletion(rd.payload.processId);
145+
}),
146+
map((rd) => rd.payload)
155147
).subscribe((process) => {
156-
if (process.processStatus.toString() !== ProcessStatus[ProcessStatus.COMPLETED].toString() &&
157-
process.processStatus.toString() !== ProcessStatus[ProcessStatus.FAILED].toString()) {
158-
// Ping the current process state every 5s
159-
setTimeout(() => {
160-
this.requestService.setStaleByHrefSubstring(process._links.self.href);
161-
this.requestService.setStaleByHrefSubstring(this.collection._links.self.href);
162-
}, 5000);
163-
}
164-
if (process.processStatus.toString() === ProcessStatus[ProcessStatus.FAILED].toString()) {
165-
this.notificationsService.error(this.translateService.get('collection.source.controls.import.failed'));
166-
this.importRunning$.next(false);
167-
}
168-
if (process.processStatus.toString() === ProcessStatus[ProcessStatus.COMPLETED].toString()) {
169-
this.notificationsService.success(this.translateService.get('collection.source.controls.import.completed'));
170-
this.requestService.setStaleByHrefSubstring(this.collection._links.self.href);
171-
this.importRunning$.next(false);
172-
}
148+
if (process.processStatus.toString() === ProcessStatus[ProcessStatus.FAILED].toString()) {
149+
this.notificationsService.error(this.translateService.get('collection.source.controls.import.failed'));
150+
this.importRunning$.next(false);
151+
}
152+
if (process.processStatus.toString() === ProcessStatus[ProcessStatus.COMPLETED].toString()) {
153+
this.notificationsService.success(this.translateService.get('collection.source.controls.import.completed'));
154+
this.requestService.setStaleByHrefSubstring(this.collection._links.self.href);
155+
this.importRunning$.next(false);
173156
}
174-
));
157+
}));
175158
}
176159

177160
/**
@@ -194,31 +177,22 @@ export class CollectionSourceControlsComponent implements OnDestroy {
194177
}
195178
}),
196179
filter((rd) => rd.hasSucceeded && hasValue(rd.payload)),
197-
switchMap((rd) => this.processDataService.findById(rd.payload.processId, false)),
198-
getAllCompletedRemoteData(),
199-
filter((rd) => !rd.isStale && (rd.hasSucceeded || rd.hasFailed)),
200-
map((rd) => rd.payload),
201-
hasValueOperator(),
180+
switchMap((rd) => {
181+
this.autoRefreshIDs.push(rd.payload.processId);
182+
return this.processDataService.autoRefreshUntilCompletion(rd.payload.processId);
183+
}),
184+
map((rd) => rd.payload)
202185
).subscribe((process) => {
203-
if (process.processStatus.toString() !== ProcessStatus[ProcessStatus.COMPLETED].toString() &&
204-
process.processStatus.toString() !== ProcessStatus[ProcessStatus.FAILED].toString()) {
205-
// Ping the current process state every 5s
206-
setTimeout(() => {
207-
this.requestService.setStaleByHrefSubstring(process._links.self.href);
208-
this.requestService.setStaleByHrefSubstring(this.collection._links.self.href);
209-
}, 5000);
210-
}
211-
if (process.processStatus.toString() === ProcessStatus[ProcessStatus.FAILED].toString()) {
212-
this.notificationsService.error(this.translateService.get('collection.source.controls.reset.failed'));
213-
this.reImportRunning$.next(false);
214-
}
215-
if (process.processStatus.toString() === ProcessStatus[ProcessStatus.COMPLETED].toString()) {
216-
this.notificationsService.success(this.translateService.get('collection.source.controls.reset.completed'));
217-
this.requestService.setStaleByHrefSubstring(this.collection._links.self.href);
218-
this.reImportRunning$.next(false);
219-
}
186+
if (process.processStatus.toString() === ProcessStatus[ProcessStatus.FAILED].toString()) {
187+
this.notificationsService.error(this.translateService.get('collection.source.controls.reset.failed'));
188+
this.reImportRunning$.next(false);
220189
}
221-
));
190+
if (process.processStatus.toString() === ProcessStatus[ProcessStatus.COMPLETED].toString()) {
191+
this.notificationsService.success(this.translateService.get('collection.source.controls.reset.completed'));
192+
this.requestService.setStaleByHrefSubstring(this.collection._links.self.href);
193+
this.reImportRunning$.next(false);
194+
}
195+
}));
222196
}
223197

224198
ngOnDestroy(): void {
@@ -227,5 +201,9 @@ export class CollectionSourceControlsComponent implements OnDestroy {
227201
sub.unsubscribe();
228202
}
229203
});
204+
205+
this.autoRefreshIDs.forEach((id) => {
206+
this.processDataService.stopAutoRefreshing(id);
207+
});
230208
}
231209
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { Bitstream } from '../core/shared/bitstream.model';
77
import { Community } from '../core/shared/community.model';
88
import { fadeInOut } from '../shared/animations/fade';
99
import { hasValue } from '../shared/empty.util';
10-
import { getAllSucceededRemoteDataPayload} from '../core/shared/operators';
10+
import { getAllSucceededRemoteDataPayload } from '../core/shared/operators';
1111
import { AuthService } from '../core/auth/auth.service';
1212
import { AuthorizationDataService } from '../core/data/feature-authorization/authorization-data.service';
1313
import { FeatureID } from '../core/data/feature-authorization/feature-id';

src/app/core/cache/builders/remote-data-build.service.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -273,12 +273,13 @@ export class RemoteDataBuildService {
273273
return isStale(r2.state) ? r1 : r2;
274274
}
275275
}),
276-
distinctUntilKeyChanged('lastUpdated')
277276
);
278277

279278
const payload$ = this.buildPayload<T>(requestEntry$, href$, ...linksToFollow);
280279

281-
return this.toRemoteDataObservable<T>(requestEntry$, payload$);
280+
return this.toRemoteDataObservable<T>(requestEntry$, payload$).pipe(
281+
distinctUntilKeyChanged('lastUpdated'),
282+
);
282283
}
283284

284285
/**

0 commit comments

Comments
 (0)