...
 
Commits (13)
package ee.ria.riha.domain.model;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
import lombok.*;
import java.time.LocalDate;
import java.util.Date;
......@@ -20,6 +17,7 @@ import static ee.ria.riha.domain.model.IssueEntityType.ISSUE;
@Setter
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class Issue implements IssueEntity {
private Long id;
......
package ee.ria.riha.domain.model;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
import lombok.*;
import java.util.Date;
......@@ -18,6 +15,7 @@ import static ee.ria.riha.domain.model.IssueEntityType.ISSUE_COMMENT;
@Setter
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class IssueComment implements IssueEntity {
private Long id;
......
package ee.ria.riha.web;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import javax.servlet.http.HttpServletRequest;
import ee.ria.riha.authentication.RihaUserDetails;
import ee.ria.riha.service.UserService;
import ee.ria.riha.storage.util.*;
import ee.ria.riha.web.model.UserDetailsModel;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
......@@ -17,17 +15,11 @@ import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import ee.ria.riha.service.UserService;
import ee.ria.riha.storage.util.ApiPageableAndCompositeRequestParams;
import ee.ria.riha.storage.util.CompositeFilterRequest;
import ee.ria.riha.storage.util.PageRequest;
import ee.ria.riha.storage.util.Pageable;
import ee.ria.riha.storage.util.PagedResponse;
import ee.ria.riha.web.model.UserDetailsModel;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import javax.servlet.http.HttpServletRequest;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static ee.ria.riha.conf.ApplicationProperties.API_V1_PREFIX;
......@@ -38,16 +30,18 @@ import static ee.ria.riha.conf.ApplicationProperties.API_V1_PREFIX;
public class OrganizationController {
private static final String SORT_DELIMITER = "-";
private static final Map<String, Function<UserDetailsModel, ? extends Comparable>> sortFunctions;
static final Map<String, Comparator<UserDetailsModel>> USER_DETAILS_COMPARATORS;
static {
sortFunctions = new HashMap<>();
sortFunctions.put("firstName", UserDetailsModel::getFirstName);
sortFunctions.put("lastName", UserDetailsModel::getLastName);
sortFunctions.put("email", UserDetailsModel::getEmail);
sortFunctions.put("approver", UserDetailsModel::getApprover);
sortFunctions.put("producer", UserDetailsModel::getProducer);
USER_DETAILS_COMPARATORS = new HashMap<>();
USER_DETAILS_COMPARATORS.put("firstName", Comparator.comparing(UserDetailsModel::getFirstName, Comparator.nullsLast(String::compareToIgnoreCase)));
USER_DETAILS_COMPARATORS.put("lastName", Comparator.comparing(UserDetailsModel::getLastName, Comparator.nullsLast(String::compareToIgnoreCase)));
USER_DETAILS_COMPARATORS.put("email", Comparator.comparing(UserDetailsModel::getEmail, Comparator.nullsLast(String::compareToIgnoreCase)));
USER_DETAILS_COMPARATORS.put("approver", Comparator.comparing(UserDetailsModel::getApprover, Comparator.nullsLast(Boolean::compareTo)));
USER_DETAILS_COMPARATORS.put("producer", Comparator.comparing(UserDetailsModel::getProducer, Comparator.nullsLast(Boolean::compareTo)));
}
@Autowired
private UserService userService;
......@@ -64,7 +58,15 @@ public class OrganizationController {
List<UserDetailsModel> users = userService.getUsersByOrganization(rihaUserDetails.getActiveOrganization().getCode());
int totalUsers = users.size();
sortUsers(filterRequest, users);
String sortParameter = getSortFieldFromFilterRequest(filterRequest);
Comparator<UserDetailsModel> sortFunction =
sortParameter != null
? USER_DETAILS_COMPARATORS.get(sortParameter.replace(SORT_DELIMITER, ""))
: null;
if (sortParameter != null && sortFunction != null) {
sortUsers(users, sortFunction, sortParameter.startsWith(SORT_DELIMITER));
}
users = applyPaging(pageable, users);
return ResponseEntity.ok(new PagedResponse(
......@@ -73,17 +75,14 @@ public class OrganizationController {
users));
}
private void sortUsers(CompositeFilterRequest filterRequest, List<UserDetailsModel> users) {
List<String> sortParameters = filterRequest.getSortParameters();
if (!sortParameters.isEmpty()) {
String sort = sortParameters.get(0);
Function<UserDetailsModel, ? extends Comparable> sortFunction = sortFunctions.get(sort.replace(SORT_DELIMITER, ""));
if (sortFunction == null) {
return;
}
Comparator<UserDetailsModel> comparator = Comparator.comparing(sortFunction);
users.sort(sort.startsWith(SORT_DELIMITER) ? comparator.reversed() : comparator);
}
private String getSortFieldFromFilterRequest(CompositeFilterRequest filterRequest) {
return filterRequest != null && filterRequest.getSortParameters() != null && !filterRequest.getSortParameters().isEmpty()
? filterRequest.getSortParameters().get(0)
: null;
}
static void sortUsers(List<UserDetailsModel> users, Comparator<UserDetailsModel> sortFunction, boolean reverseSort) {
users.sort(reverseSort ? sortFunction.reversed() : sortFunction);
}
private List<UserDetailsModel> applyPaging(Pageable pageable, List<UserDetailsModel> users) {
......
......@@ -4,6 +4,7 @@ import ee.ria.riha.domain.model.IssueResolutionType;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* Model of an issue approval decision request
......@@ -13,6 +14,7 @@ import lombok.Data;
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class IssueApprovalDecisionModel {
private String comment;
private IssueResolutionType decisionType;
......
......@@ -3,6 +3,7 @@ package ee.ria.riha.web.model;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* Model of an issue comment request
......@@ -12,6 +13,7 @@ import lombok.Data;
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class IssueCommentModel {
private String comment;
}
......@@ -5,6 +5,7 @@ import ee.ria.riha.domain.model.IssueStatus;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* Model of an issue status update request
......@@ -14,6 +15,7 @@ import lombok.Data;
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class IssueStatusUpdateModel {
private String comment;
private IssueStatus status;
......
package ee.ria.riha.web.model;
import ee.ria.riha.domain.model.RelationType;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
import lombok.*;
/**
* Model of info system relationship request.
......@@ -15,6 +12,7 @@ import lombok.Setter;
@Setter
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class RelationModel {
private Long id;
private String infoSystemShortName;
......
package ee.ria.riha.web.model;
import ee.ria.riha.domain.model.RelationType;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
import lombok.*;
import java.util.UUID;
......@@ -17,6 +14,7 @@ import java.util.UUID;
@Setter
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class RelationSummaryModel {
private Long id;
private UUID infoSystemUuid;
......
package ee.ria.riha.web;
import ee.ria.riha.storage.util.CompositeFilterRequest;
import ee.ria.riha.web.model.UserDetailsModel;
import org.junit.Test;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.nullValue;
public class OrganizationControllerTest {
@Test
public void sortUsers() {
List<UserDetailsModel> testUsers = Arrays.asList(
UserDetailsModel.builder().email("test0@test.aa").build(),
UserDetailsModel.builder().email(null).build(),
UserDetailsModel.builder().email("test1@test.aa").build(),
UserDetailsModel.builder().email("test2@test.aa").build()
);
CompositeFilterRequest filterRequest = new CompositeFilterRequest(Collections.emptyList(), Collections.singletonList("asc"));
OrganizationController.sortUsers(testUsers, OrganizationController.USER_DETAILS_COMPARATORS.get("email"),false);
assertThat(testUsers.get(3).getEmail(), nullValue());
OrganizationController.sortUsers(testUsers, OrganizationController.USER_DETAILS_COMPARATORS.get("email"),true);
assertThat(testUsers.get(0).getEmail(), nullValue());
}
}
\ No newline at end of file
......@@ -72,7 +72,6 @@ sudo npm install -g karma-jasmine-ajax
sudo npm install -g karma-coverage
sudo npm install -g karma-phantomjs2-launcher
sudo npm install -g coffee-script@1.8.0
sudo npm install -g bower-installer@0.8.4
~~~
## Build
......@@ -88,17 +87,6 @@ Frontend is a Angular 4 module generated by Angular CLI version 1.0.4. It can be
mvn frontend:install-node-and-yarn frontend:yarn
~~~
#### Install bower
Build process requires bower. Please note that bower can't run as root user or using sudo. If you absolutely have to, add `{ "allow_root": true }` to `~/.bowerrc`.
~~~bash
echo "{ \"allow_root\": true }" > ~/.bowerrc
~~~
Install bower
~~~bash
mvn frontend:yarn@install-bower
~~~
#### Build using maven
Build project using maven `frontend:yarn` task and calling `build` script from `package.json`. Compiled artifacts will be outputted to the `dist` directory.
~~~bash
......
......@@ -26,9 +26,10 @@ export class AppComponent {
// 'en' not supported yet
translate.use('et');
const googleAnalyticsId = this.environmentService.globalEnvironment.getGoogleAnalyticsId();
const googleAnalyticsId = this.environmentService.globalEnvironment ?
this.environmentService.globalEnvironment.getGoogleAnalyticsId() : null;
this.router.routeReuseStrategy.shouldReuseRoute = function(future, curr){
this.router.routeReuseStrategy.shouldReuseRoute = function(future, curr) {
return false;
};
......
<section>
<div class="card-deck mb-2 mb-sm-3">
<div *ngFor="let card of cards" class="card feature">
<div class="card-block">
<div class="card-body">
<h4 class="card-title">
<span class="fa" [ngClass]="card.iconType">
</span>{{card.title}}</h4>
......
......@@ -51,7 +51,7 @@ export class ProducerListComponent implements OnInit, AfterViewInit, DoCheck {
return;
}
const params = filters;
const params = filters? filters: [];
params.searchText = this.searchText;
delete params.ownerName;
delete params.ownerCode;
......@@ -104,7 +104,7 @@ export class ProducerListComponent implements OnInit, AfterViewInit, DoCheck {
getOwnSystems(page?): void {
this._loadSystems(this.filterPanel.getFilters(), page);
this._loadSystems(this.filterPanel ? this.filterPanel.getFilters() : null, page);
}
openOrganizationsModal() {
......@@ -118,7 +118,7 @@ export class ProducerListComponent implements OnInit, AfterViewInit, DoCheck {
}
hasActiveFilters(): boolean{
return this.filterPanel.hasActiveFilters();
return this.filterPanel && this.filterPanel.hasActiveFilters();
}
clearFilters(){
......
......@@ -41,7 +41,7 @@
<a class="nav-link" [routerLink]="'/Avaleht'">Avaleht</a>
</li>
<li class="nav-item" [ngClass]="{'active': isListOrSubView()}">
<a class="nav-link" [routerLink]="'/Infosüsteemid'" [queryParams]="{_dc: getRand()}">RIHA kataloog</a>
<a class="nav-link" [routerLink]="'/Infosüsteemid'" [queryParams]="{_dc: _dc}">RIHA kataloog</a>
</li>
<li *ngIf="environmentService.getUserMatrix().hasApproverRole" class="nav-item" routerLinkActive="active">
<a class="nav-link" [routerLink]="'/Hinda'">Hinda</a>
......
import {Component, OnInit} from '@angular/core';
import {AfterContentChecked, Component, OnInit} from '@angular/core';
import {EnvironmentService} from '../../services/environment.service';
import {User} from '../../models/user';
import {ModalHelperService} from '../../services/modal-helper.service';
......@@ -13,14 +13,15 @@ import * as $ from 'jquery';
templateUrl: './riha-navbar.component.html',
styleUrls: ['./riha-navbar.component.scss']
})
export class RihaNavbarComponent implements OnInit {
export class RihaNavbarComponent implements OnInit, AfterContentChecked {
public activeUser: User = null;
public _dc: number = 0;
isUserLoggedIn(): boolean {
return this.environmentService.getActiveUser() != null;
}
getRand(){
getRand() {
return new Date().getSeconds();
}
......@@ -33,19 +34,19 @@ export class RihaNavbarComponent implements OnInit {
* in version 4.1.3 it seems to be broken when working with queryParams,
* even with applied [routerLinkActiveOptions]="{exact: false}
*/
isListOrSubView(){
isListOrSubView() {
const cat = encodeURI('/Infosüsteemid?');
const obj = encodeURI('/Andmeobjektid');
const sub = encodeURI('/Infosüsteemid/Vaata');
const full = encodeURI('/Infosüsteemid');
if (this.router.url && typeof this.router.url === 'string'){
if (this.router.url && typeof this.router.url === 'string') {
return (-1 != this.router.url.indexOf(cat) || -1 != this.router.url.indexOf(obj) || -1 != this.router.url.indexOf(sub) || this.router.url === full);
} else {
return false;
}
}
logout(){
logout() {
this.environmentService.doLogout().subscribe(res => {
this.environmentService.loadEnvironmentData().subscribe(env => {
this.sessionHelperService.refreshSessionTimer();
......@@ -59,7 +60,7 @@ export class RihaNavbarComponent implements OnInit {
return false;
}
openNoOrganizationWarningModal() :boolean {
openNoOrganizationWarningModal(): boolean {
const modalRef = this.modalService.open(NoOrganizationModalComponent);
return false;
}
......@@ -102,6 +103,10 @@ export class RihaNavbarComponent implements OnInit {
ngOnInit() {
}
ngAfterContentChecked() {
this._dc = this.getRand();
}
openNavigationMenu() {
$('body').toggleClass('nav-open');
}
......
......@@ -42,7 +42,7 @@ export class EnvironmentService {
}
public getSessionTimeoutInterval(): number{
return this.globalEnvironment.getSessionMaxInactiveInterval();
return this.globalEnvironment.getSessionMaxInactiveInterval();
}
public getUserMatrix(): UserMatrix{
......@@ -106,9 +106,12 @@ export class EnvironmentService {
}
public onAppStart(): Promise<any> {
return this.loadEnvironmentData().toPromise().then(env => {
const promise = this.loadEnvironmentData().toPromise();
promise.then(env => {
this.runTrackingScripts(new Environment(env));
});
return promise;
}
public loadClassifiers(): Promise<any> {
......@@ -120,7 +123,6 @@ export class EnvironmentService {
public loadEnvironmentData(): Observable<Environment> {
const observable = this.http.get<Environment>(this.environmentUrl);
observable.subscribe(env => {
console.log('loadEnvironmentData type', typeof env, env);
this.globalEnvironment = new Environment(env);
});
......
......@@ -274,11 +274,11 @@ export class SystemsService {
return this.http.post<System>(this.systemsUrl, system);
}
public postDataFile(file, reference): Observable<String> {
public postDataFile(file, reference): Observable<string> {
const formData = new FormData();
formData.append('file', file);
return this.http.post<String>(this.systemsUrl + `/${ reference }/files`, formData);
return this.http.post(this.systemsUrl + `/${ reference }/files`, formData, { responseType: 'text' });
}
public updateSystem(updatedData, reference?): Observable<System> {
......
......@@ -64,7 +64,7 @@ $popover-arrow-width: 10px !default;
$popover-arrow-color: $popover-bg !default;
$popover-arrow-outer-width: $popover-arrow-width !default;
/* Custom control */
$custom-control-gutter: 1.563rem !default;
$custom-control-gutter: 0.5625rem !default;
$custom-control-spacer-x: 11px !default;
$custom-control-spacer-y: 10px !default;
$custom-control-indicator-size: 1rem !default;
......
......@@ -134,6 +134,7 @@ textarea {
font-size: 14px;
line-height: 20px;
margin-right: 20px;
margin-bottom: 10px;
input {
&:disabled {
&~.custom-control-indicator {
......