Skip to content

Commit 004124e

Browse files
authored
Merge pull request #778 from qbicsoftware/release/1.3.0
Release 1.3.0
2 parents 22c0c75 + 39e38b2 commit 004124e

File tree

48 files changed

+900
-608
lines changed

Some content is hidden

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

48 files changed

+900
-608
lines changed

identity-api/src/main/java/life/qbic/identity/api/UserInfo.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,6 @@
1010
* @since 1.0.0
1111
*/
1212
public record UserInfo(String id, String fullName, String emailAddress, String platformUserName,
13-
boolean isActive) implements Serializable {
13+
boolean isActive, String oidcId, String oidcIssuer) implements Serializable {
1414

1515
}

identity-api/src/main/java/life/qbic/identity/api/UserInformationService.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -55,5 +55,6 @@ public interface UserInformationService {
5555

5656
Optional<UserInfo> findByOidc(String oidcId, String oidcIssuer);
5757

58-
List<UserInfo> findAllActive(String filter, int offset, int limit, List<SortOrder> sortOrders);
58+
List<UserInfo> queryActiveUsersWithFilter(String filter, int offset, int limit,
59+
List<SortOrder> sortOrders);
5960
}

identity-infrastructure/src/main/java/life/qbic/identity/infrastructure/QbicUserRepo.java

+3-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import life.qbic.identity.domain.model.UserId;
99
import org.springframework.data.domain.Pageable;
1010
import org.springframework.data.jpa.repository.JpaRepository;
11+
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
1112
import org.springframework.data.repository.CrudRepository;
1213

1314
/**
@@ -21,7 +22,8 @@
2122
*
2223
* @since 1.0.0
2324
*/
24-
public interface QbicUserRepo extends JpaRepository<User, UserId> {
25+
public interface QbicUserRepo extends JpaRepository<User, UserId>,
26+
JpaSpecificationExecutor<User> {
2527

2628
/**
2729
* Find users by mail address in the persistent data storage

identity-infrastructure/src/main/java/life/qbic/identity/infrastructure/UserJpaRepository.java

+61-3
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import life.qbic.identity.domain.repository.UserDataStorage;
99
import org.springframework.beans.factory.annotation.Autowired;
1010
import org.springframework.data.domain.Pageable;
11+
import org.springframework.data.jpa.domain.Specification;
1112
import org.springframework.stereotype.Component;
1213

1314

@@ -60,13 +61,70 @@ public Optional<User> findUserByUserName(String userName) {
6061
}
6162

6263
@Override
63-
public List<User> findByUserNameContainingIgnoreCaseAndActiveTrue(String userName,
64-
Pageable pageable) {
65-
return userRepo.findAllByUserNameContainingIgnoreCaseAndActiveTrue(userName, pageable);
64+
public List<User> queryActiveUsersWithFilter(String filter, Pageable pageable) {
65+
Specification<User> userSpecification = generateUserFilterSpecification(filter);
66+
return userRepo.findAll(userSpecification, pageable).getContent();
6667
}
6768

6869
@Override
6970
public Optional<User> findByOidcIdEqualsAndOidcIssuerEquals(String oidcId, String oidcIssuer) {
7071
return userRepo.findByOidcIdEqualsAndOidcIssuerEquals(oidcId, oidcIssuer);
7172
}
73+
74+
private Specification<User> generateUserFilterSpecification(String filter) {
75+
Specification<User> isBlankSpec = UserSpec.isBlank(filter);
76+
Specification<User> isFullName = UserSpec.isFullName(filter);
77+
Specification<User> isUserNameSpec = UserSpec.isUserName(filter);
78+
Specification<User> isOidc = UserSpec.isOidc(filter);
79+
Specification<User> isOidcIssuer = UserSpec.isOidcIssuer(filter);
80+
Specification<User> isActiveSpec = UserSpec.isActive();
81+
Specification<User> filterSpecification =
82+
Specification.anyOf(isFullName,
83+
isUserNameSpec,
84+
isOidc,
85+
isOidcIssuer
86+
);
87+
return Specification.where(isBlankSpec)
88+
.and(filterSpecification)
89+
.and(isActiveSpec);
90+
}
91+
92+
private static class UserSpec {
93+
94+
//If no filter was provided return all Users
95+
public static Specification<User> isBlank(String filter) {
96+
return (root, query, builder) -> {
97+
if (filter != null && filter.isBlank()) {
98+
return builder.conjunction();
99+
}
100+
return null;
101+
};
102+
}
103+
104+
public static Specification<User> isUserName(String filter) {
105+
return (root, query, builder) ->
106+
builder.like(root.get("userName"), "%" + filter + "%");
107+
}
108+
109+
public static Specification<User> isFullName(String filter) {
110+
return (root, query, builder) ->
111+
builder.like(root.get("fullName"), "%" + filter + "%");
112+
}
113+
114+
// Should be extended if additional oidc providers are included, for now we only work with orcid
115+
public static Specification<User> isOidc(String filter) {
116+
return (root, query, builder) ->
117+
builder.like(root.get("oidcId"), "%" + filter + "%");
118+
}
119+
120+
public static Specification<User> isOidcIssuer(String filter) {
121+
return (root, query, builder) ->
122+
builder.like(root.get("oidcIssuer"), "%" + filter + "%");
123+
}
124+
125+
public static Specification<User> isActive() {
126+
return (root, query, builder) ->
127+
builder.isTrue(root.get("active"));
128+
}
129+
}
72130
}

identity/src/main/java/life/qbic/identity/application/service/BasicUserInformationService.java

+5-4
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ public boolean isEmailAvailable(String email) {
8282
}
8383

8484
@Override
85-
public List<UserInfo> findAllActive(String filter, int offset, int limit,
85+
public List<UserInfo> queryActiveUsersWithFilter(String filter, int offset, int limit,
8686
List<SortOrder> sortOrders) {
8787
List<Order> orders = sortOrders.stream().map(it -> {
8888
Order order;
@@ -93,18 +93,19 @@ public List<UserInfo> findAllActive(String filter, int offset, int limit,
9393
}
9494
return order;
9595
}).toList();
96-
return userRepository.findByUserNameContainingIgnoreCaseAndActiveTrue(
96+
return userRepository.queryActiveUsersWithFilter(
9797
filter, new OffsetBasedRequest(offset, limit, Sort.by(orders)))
9898
.stream()
9999
.map(user -> new UserInfo(user.id().get(), user.fullName().get(), user.emailAddress().get(),
100-
user.userName(), user.isActive()))
100+
user.userName(), user.isActive(), user.getOidcId().orElse(null),
101+
user.getOidcIssuer().orElse(null)))
101102
.toList();
102103
}
103104

104105
private UserInfo convert(User user) {
105106
return new UserInfo(user.id().get(), user.fullName().get(), user.emailAddress().get(),
106107
user.userName(),
107-
user.isActive());
108+
user.isActive(), user.getOidcId().orElse(null), user.getOidcIssuer().orElse(null));
108109
}
109110

110111
@Override

identity/src/main/java/life/qbic/identity/domain/repository/UserDataStorage.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ public interface UserDataStorage {
5858

5959
Optional<User> findUserByUserName(String userName);
6060

61-
List<User> findByUserNameContainingIgnoreCaseAndActiveTrue(String username, Pageable pageable);
61+
List<User> queryActiveUsersWithFilter(String filter, Pageable pageable);
6262

6363
Optional<User> findByOidcIdEqualsAndOidcIssuerEquals(String oidcId, String oidcIssuer);
6464
}

identity/src/main/java/life/qbic/identity/domain/repository/UserRepository.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -110,9 +110,9 @@ public void addUser(User user) throws UserStorageException {
110110
saveUser(user);
111111
}
112112

113-
public List<User> findByUserNameContainingIgnoreCaseAndActiveTrue(String userName,
113+
public List<User> queryActiveUsersWithFilter(String filter,
114114
Pageable pageable) {
115-
return dataStorage.findByUserNameContainingIgnoreCaseAndActiveTrue(userName, pageable);
115+
return dataStorage.queryActiveUsersWithFilter(filter, pageable);
116116
}
117117

118118
public Optional<User> findByOidc(String oidcId, String oidcIssuer) {

project-management-infrastructure/src/main/java/life/qbic/projectmanagement/infrastructure/sample/SamplePreviewJpaRepository.java

+10-4
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,9 @@ private Specification<SamplePreview> generateExperimentIdandFilterSpecification(
6868
Specification<SamplePreview> isBlankSpec = SamplePreviewSpecs.isBlank(filter);
6969
Specification<SamplePreview> experimentIdSpec = SamplePreviewSpecs.experimentIdEquals(
7070
experimentId);
71+
Specification<SamplePreview> organismIdSpec = SamplePreviewSpecs.organismIdContains(filter);
7172
Specification<SamplePreview> sampleCodeSpec = SamplePreviewSpecs.sampleCodeContains(filter);
72-
Specification<SamplePreview> sampleLabelSpec = SamplePreviewSpecs.sampleLabelContains(filter);
73+
Specification<SamplePreview> sampleNameSpec = SamplePreviewSpecs.sampleNameContains(filter);
7374
Specification<SamplePreview> batchLabelSpec = SamplePreviewSpecs.batchLabelContains(filter);
7475
Specification<SamplePreview> conditionSpec = SamplePreviewSpecs.conditionContains(filter);
7576
Specification<SamplePreview> speciesSpec = SamplePreviewSpecs.speciesContains(filter);
@@ -79,7 +80,7 @@ private Specification<SamplePreview> generateExperimentIdandFilterSpecification(
7980
filter);
8081
Specification<SamplePreview> commentSpec = SamplePreviewSpecs.commentContains(filter);
8182
Specification<SamplePreview> containsFilterSpec = Specification.anyOf(sampleCodeSpec,
82-
sampleLabelSpec, batchLabelSpec, conditionSpec, speciesSpec,
83+
sampleNameSpec, organismIdSpec, batchLabelSpec, conditionSpec, speciesSpec,
8384
specimenSpec, analyteSpec, analysisMethodContains, commentSpec);
8485
Specification<SamplePreview> isDistinctSpec = SamplePreviewSpecs.isDistinct();
8586
return Specification.where(experimentIdSpec).and(isBlankSpec)
@@ -126,9 +127,9 @@ public static Specification<SamplePreview> batchLabelContains(String filter) {
126127
builder.like(root.get("batchLabel"), "%" + filter + "%");
127128
}
128129

129-
public static Specification<SamplePreview> sampleLabelContains(String filter) {
130+
public static Specification<SamplePreview> sampleNameContains(String filter) {
130131
return (root, query, builder) ->
131-
builder.like(root.get("sampleLabel"), "%" + filter + "%");
132+
builder.like(root.get("sampleName"), "%" + filter + "%");
132133
}
133134

134135
public static Specification<SamplePreview> conditionContains(String filter) {
@@ -157,6 +158,11 @@ private static Specification<SamplePreview> ontologyColumnContains(String col, S
157158
};
158159
}
159160

161+
public static Specification<SamplePreview> organismIdContains(String filter) {
162+
return (root, query, builder) ->
163+
builder.like(root.get("organismId"), "%" + filter + "%");
164+
}
165+
160166
public static Specification<SamplePreview> speciesContains(String filter) {
161167
return ontologyColumnContains("species", filter);
162168
}

project-management/src/main/java/life/qbic/projectmanagement/application/batch/SampleUpdateRequest.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ public record SampleUpdateRequest(SampleId sampleId, SampleInformation sampleInf
1717
/**
1818
* Sample update request.
1919
* <p>
20-
* @param sampleLabel a human-readable semantic descriptor of the sample
20+
* @param sampleName a human-readable semantic descriptor of the sample
2121
* @param organismId optional identifier of the sample's source patient or organism
2222
* @param analysisMethod analysis method to be performed
2323
* @param experimentalGroup the experimental group the sample is part of
@@ -26,7 +26,7 @@ public record SampleUpdateRequest(SampleId sampleId, SampleInformation sampleInf
2626
* @param analyte the analyte the sample belongs to
2727
* @param comment comment relating to the sample
2828
*/
29-
public record SampleInformation(String sampleLabel, String organismId,
29+
public record SampleInformation(String sampleName, String organismId,
3030
AnalysisMethod analysisMethod,
3131
ExperimentalGroup experimentalGroup, OntologyTerm species,
3232
OntologyTerm specimen, OntologyTerm analyte,

project-management/src/main/java/life/qbic/projectmanagement/application/dataset/RawDataService.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ public record RawData(MeasurementCode measurementCode,
169169
* Sample Information associated with the measurements to which the {@link RawData} is linked and
170170
* meant to be employed in the frontend
171171
*/
172-
public record RawDataSampleInformation(SampleCode sampleCode, String sampleLabel) {
172+
public record RawDataSampleInformation(SampleCode sampleCode, String sampleName) {
173173

174174
}
175175

project-management/src/main/java/life/qbic/projectmanagement/application/measurement/validation/MeasurementNGSValidator.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ public ValidationResult validateUpdate(NGSMeasurementMetadata metadata, ProjectI
118118

119119
public enum NGS_PROPERTY {
120120
QBIC_SAMPLE_ID("qbic sample id"),
121-
SAMPLE_LABEL("sample label"),
121+
SAMPLE_LABEL("sample name"),
122122
ORGANISATION_ID("organisation id"),
123123
FACILITY("facility"),
124124
INSTRUMENT("instrument"),

project-management/src/main/java/life/qbic/projectmanagement/application/measurement/validation/MeasurementProteomicsValidator.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ public ValidationResult validateUpdate(ProteomicsMeasurementMetadata metadata,
129129

130130
public enum PROTEOMICS_PROPERTY {
131131
QBIC_SAMPLE_ID("qbic sample id"),
132-
SAMPLE_LABEL("sample label"),
132+
SAMPLE_LABEL("sample name"),
133133
ORGANISATION_ID("organisation id"),
134134
FACILITY("facility"),
135135
INSTRUMENT("instrument"),

project-management/src/main/java/life/qbic/projectmanagement/application/sample/SamplePreview.java

+13-13
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ public class SamplePreview {
3939
private String batchLabel;
4040

4141
@Column(name = "label")
42-
private String sampleLabel;
42+
private String sampleName;
4343

4444
@Column(name = "organism_id")
4545
private String organismId;
@@ -58,14 +58,14 @@ protected SamplePreview() {
5858
}
5959

6060
private SamplePreview(ExperimentId experimentId, SampleId sampleId, String sampleCode,
61-
String batchLabel, String sampleLabel, String organismId,
61+
String batchLabel, String sampleName, String organismId,
6262
ExperimentalGroup experimentalGroup, OntologyTerm species,
6363
OntologyTerm specimen, OntologyTerm analyte, String analysisMethod, String comment) {
6464
Objects.requireNonNull(experimentId);
6565
Objects.requireNonNull(sampleId);
6666
Objects.requireNonNull(sampleCode);
6767
Objects.requireNonNull(batchLabel);
68-
Objects.requireNonNull(sampleLabel);
68+
Objects.requireNonNull(sampleName);
6969
Objects.requireNonNull(experimentalGroup);
7070
Objects.requireNonNull(species);
7171
Objects.requireNonNull(specimen);
@@ -75,7 +75,7 @@ private SamplePreview(ExperimentId experimentId, SampleId sampleId, String sampl
7575
this.sampleId = sampleId;
7676
this.sampleCode = sampleCode;
7777
this.batchLabel = batchLabel;
78-
this.sampleLabel = sampleLabel;
78+
this.sampleName = sampleName;
7979
this.experimentalGroup = experimentalGroup;
8080
this.species = species;
8181
this.specimen = specimen;
@@ -95,7 +95,7 @@ private SamplePreview(ExperimentId experimentId, SampleId sampleId, String sampl
9595
* @param batchLabel the label of the {@link Batch} which contains the {@link Sample}
9696
* associated with this preview
9797
* associated with this preview
98-
* @param sampleLabel the label of the {@link Sample} associated with this preview
98+
* @param sampleName the name of the {@link Sample} associated with this preview
9999
* @param organismId optional identifier of the patient or organism a {@link Sample} was taken of
100100
* @param experimentalGroup the {@link ExperimentalGroup} for the {@link Sample} associated with
101101
* this preview
@@ -112,11 +112,11 @@ private SamplePreview(ExperimentId experimentId, SampleId sampleId, String sampl
112112
public static SamplePreview create(ExperimentId experimentId, SampleId sampleId,
113113
String sampleCode,
114114
String batchLabel,
115-
String sampleLabel, String organismId, ExperimentalGroup experimentalGroup,
115+
String sampleName, String organismId, ExperimentalGroup experimentalGroup,
116116
OntologyTerm species, OntologyTerm specimen, OntologyTerm analyte,
117117
String analysisMethod, String comment) {
118118
return new SamplePreview(experimentId, sampleId, sampleCode, batchLabel,
119-
sampleLabel, organismId, experimentalGroup, species, specimen, analyte, analysisMethod,
119+
sampleName, organismId, experimentalGroup, species, specimen, analyte, analysisMethod,
120120
comment);
121121
}
122122

@@ -136,8 +136,8 @@ public String batchLabel() {
136136
return batchLabel;
137137
}
138138

139-
public String sampleLabel() {
140-
return sampleLabel;
139+
public String sampleName() {
140+
return sampleName;
141141
}
142142

143143
public OntologyTerm species() {
@@ -179,8 +179,8 @@ public boolean equals(Object o) {
179179
SamplePreview that = (SamplePreview) o;
180180
return Objects.equals(experimentId, that.experimentId) && Objects.equals(
181181
sampleCode, that.sampleCode) && Objects.equals(sampleId, that.sampleId)
182-
&& Objects.equals(batchLabel, that.batchLabel) && Objects.equals(sampleLabel,
183-
that.sampleLabel) && Objects.equals(organismId, that.organismId)
182+
&& Objects.equals(batchLabel, that.batchLabel) && Objects.equals(sampleName,
183+
that.sampleName) && Objects.equals(organismId, that.organismId)
184184
&& Objects.equals(species, that.species) && Objects.equals(specimen,
185185
that.specimen) && Objects.equals(analyte, that.analyte) && Objects.equals(
186186
experimentalGroup, that.experimentalGroup) && Objects.equals(analysisMethod,
@@ -190,7 +190,7 @@ public boolean equals(Object o) {
190190
@Override
191191
public int hashCode() {
192192
return Objects.hash(experimentId, sampleCode, sampleId, batchLabel,
193-
sampleLabel, organismId,
193+
sampleName, organismId,
194194
species, specimen, analyte, experimentalGroup, analysisMethod, comment);
195195
}
196196

@@ -201,7 +201,7 @@ public String toString() {
201201
", sampleCode='" + sampleCode + '\'' +
202202
", sampleId='" + sampleId + '\'' +
203203
", batchLabel='" + batchLabel + '\'' +
204-
", sampleLabel='" + sampleLabel + '\'' +
204+
", sampleName='" + sampleName + '\'' +
205205
", organismId='" + organismId + '\'' +
206206
", species='" + species + '\'' +
207207
", specimen='" + specimen + '\'' +

project-management/src/main/java/life/qbic/projectmanagement/domain/model/sample/Sample.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ public void setSampleOrigin(SampleOrigin sampleOrigin) {
164164
}
165165

166166
public void update(SampleUpdateRequest sampleInfo) {
167-
setLabel(sampleInfo.sampleInformation().sampleLabel());
167+
setLabel(sampleInfo.sampleInformation().sampleName());
168168
setOrganismId(sampleInfo.sampleInformation().organismId());
169169
setAnalysisMethod(sampleInfo.sampleInformation().analysisMethod());
170170
setSampleOrigin(SampleOrigin.create(sampleInfo.sampleInformation().species(),

project-management/src/main/java/life/qbic/projectmanagement/domain/service/SampleDomainService.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ public void updateSamples(Project project, Collection<SampleUpdateRequest> updat
8585
var sampleInfo = updatedSamples.stream()
8686
.filter(sampleUpdateRequest -> sampleUpdateRequest.sampleId().equals(sample.sampleId()))
8787
.findFirst().orElseThrow();
88-
sample.setLabel(sampleInfo.sampleInformation().sampleLabel());
88+
sample.setLabel(sampleInfo.sampleInformation().sampleName());
8989
sample.setOrganismId(sampleInfo.sampleInformation().organismId());
9090
sample.setAnalysisMethod(sampleInfo.sampleInformation().analysisMethod());
9191
sample.setSampleOrigin(SampleOrigin.create(sampleInfo.sampleInformation().species(),

project-management/src/test/groovy/life/qbic/projectmanagement/application/measurement/validation/MeasurementProteomicsValidatorSpec.groovy

+1-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ class MeasurementMeasurementProteomicsValidatorSpec extends Specification {
4747

4848
final ProjectInformationService projectInformationService = Mock(ProjectInformationService.class)
4949

50-
final static List<String> validPXPProperties = Collections.unmodifiableList(["qbic sample id", "sample label", "organisation id", "facility", "instrument",
50+
final static List<String> validPXPProperties = Collections.unmodifiableList(["qbic sample id", "sample name", "organisation id", "facility", "instrument",
5151
"sample pool group", "cycle/fraction name", "digestion method", "digestion enzyme",
5252
"enrichment method", "injection volume (uL)", "lc column",
5353
"lcms method", "labeling type", "label", "comment"])

user-interface/frontend/themes/datamanager/components/dialog.css

+2-2
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,8 @@ Since we want to remove the spacing between the cancel and confirm button we rep
100100
}
101101

102102
.add-user-to-project-dialog::part(overlay) {
103-
height: fit-content;
104-
min-width: fit-content;
103+
height: clamp(700px, 100%, 700px);
104+
width: clamp(700px, 100%, 700px);
105105
}
106106

107107
.add-user-to-project-dialog::part(content) {

0 commit comments

Comments
 (0)