Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/1293 kr unit autocomplete #1322

Merged
merged 118 commits into from
Jan 31, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
118 commits
Select commit Hold shift + click to select a range
7ba4f8a
refactor action plan
kcinay055679 Jan 27, 2025
9cc7ccc
add create and update func
kcinay055679 Jan 27, 2025
33f67b6
clean up
kcinay055679 Jan 27, 2025
41aa0dc
check actions are now checkable
kcinay055679 Jan 27, 2025
0bc8599
add subject to control new items
kcinay055679 Jan 27, 2025
b86d841
fix checkin form
kcinay055679 Jan 27, 2025
aaeceb4
exclude failing e2e tests
kcinay055679 Jan 28, 2025
75fec38
use only formarray in actionPlan
kcinay055679 Jan 28, 2025
9f4fcbe
fix actionplan unit tests
kcinay055679 Jan 28, 2025
2245cc8
fix pipeline
kcinay055679 Jan 28, 2025
61b8d9a
clean up
kcinay055679 Jan 28, 2025
2d4ef4b
fix pipeline
kcinay055679 Jan 28, 2025
aafd726
make pipeline happy
kcinay055679 Jan 28, 2025
0930bf6
optionally disable movement functionality
kcinay055679 Jan 28, 2025
d0cee0f
disable cdk drag properly
kcinay055679 Jan 28, 2025
60125d2
add actionpoint validation
kcinay055679 Jan 28, 2025
6a532e2
fix styling of actionplan
kcinay055679 Jan 30, 2025
6a95caf
fix bug that did not let you delete action plans with set value
Miguel7373 Jan 30, 2025
d88dd8a
rework buttons in objective form that the e2e test goes through and c…
Miguel7373 Jan 30, 2025
783952d
remove skip of e2e test in check-in
Miguel7373 Jan 30, 2025
fd04962
action plan has min length
kcinay055679 Jan 30, 2025
b3dfa0d
Replace cy.wait 1000 with an interceptor wait
RandomTannenbaum Jan 31, 2025
1b7b49e
Remove .only
RandomTannenbaum Jan 31, 2025
d4b81e4
fix styling of action plan elem while dragging
kcinay055679 Jan 31, 2025
4a5733a
implement review
kcinay055679 Jan 31, 2025
960502f
place init logic in parent component
kcinay055679 Jan 31, 2025
4fe95e6
show only valid items in check-in form action plan
kcinay055679 Jan 31, 2025
fc6750c
items are deleted when saved
kcinay055679 Jan 31, 2025
b64c8e3
implement new delete logic in key-result form component
kcinay055679 Jan 31, 2025
d19099b
ich bin der antonn
kcinay055679 Jan 31, 2025
f6700de
refactor action plan
kcinay055679 Jan 27, 2025
bd0dd70
add customUnit class
kcinay055679 Jan 21, 2025
ddac440
create model for Unit and flyway script
kcinay055679 Jan 21, 2025
8467f45
split up sql file for better readability
kcinay055679 Jan 21, 2025
96ff358
add unit repo, persistence busineess and validator
kcinay055679 Jan 21, 2025
57bb741
fix backend unit tests
kcinay055679 Jan 21, 2025
c7c357a
fix integration tests
kcinay055679 Jan 21, 2025
ae87575
create services for uniut
kcinay055679 Jan 21, 2025
c3a9bd6
set cascading stye to merge
kcinay055679 Jan 22, 2025
2c01c63
run formatter
kcinay055679 Jan 22, 2025
5cb383d
clean up tests
kcinay055679 Jan 22, 2025
f6fd512
add negative IT test
kcinay055679 Jan 22, 2025
f8b1e11
add unit update int tests
kcinay055679 Jan 23, 2025
48e9199
add functionality for update unit
kcinay055679 Jan 23, 2025
21a865a
fix formatter
kcinay055679 Jan 23, 2025
b9d39e6
add get and delete functionality and write IT
kcinay055679 Jan 23, 2025
b98027a
fix architecture tests
kcinay055679 Jan 23, 2025
292874f
enable jpa auditing on securityconfig
kcinay055679 Jan 23, 2025
23d7ee6
add unittest 'IT' for UnitController
kcinay055679 Jan 23, 2025
8486c0b
fix formatter
kcinay055679 Jan 23, 2025
ba3fc58
finish IT for unit controller
kcinay055679 Jan 23, 2025
8a37399
add unit auth service tests
kcinay055679 Jan 23, 2025
cf26104
add business validation test
kcinay055679 Jan 23, 2025
c5ab082
add persistence IT logic to set current user
kcinay055679 Jan 24, 2025
8510d73
remove complexity of SpringSecurityAuditorAware
kcinay055679 Jan 24, 2025
b93c8e3
remove unitControllerITIT
kcinay055679 Jan 24, 2025
4d6bc85
make formatter happy
kcinay055679 Jan 24, 2025
b1bda8e
fix backend unit tests
kcinay055679 Jan 24, 2025
f714a62
add autocomplete for unit
kcinay055679 Jan 27, 2025
232ed0d
retrive units from backen
kcinay055679 Jan 27, 2025
85f0ce3
unit can now be on the fly created and are shown propperly
kcinay055679 Jan 27, 2025
270013c
refactor unit from enum to class
kcinay055679 Jan 27, 2025
555238a
show create icon only if not existing
kcinay055679 Jan 27, 2025
2b0628c
add confirm dialog before create new
kcinay055679 Jan 27, 2025
513286b
add manage units dialog
kcinay055679 Jan 28, 2025
70a0c53
add is default property to model
kcinay055679 Jan 28, 2025
2332915
add isDefault to db
kcinay055679 Jan 28, 2025
72edc5e
add isDefault into the frontend
kcinay055679 Jan 28, 2025
d46c4a2
show default units in dialog
kcinay055679 Jan 28, 2025
237a22c
add and refactor save untis method
kcinay055679 Jan 28, 2025
fbac973
refactor jest tests
kcinay055679 Jan 28, 2025
c4585b6
fix autocomplete in e2e
kcinay055679 Jan 28, 2025
b70f112
fix unit transformation pipe
kcinay055679 Jan 28, 2025
4c1d881
fix backend unit tests
kcinay055679 Jan 28, 2025
26eb519
fix unit tests
kcinay055679 Jan 28, 2025
2a1f373
add action-plan to unit management
kcinay055679 Jan 28, 2025
3a34f45
integrate actionPlan in manage metrics
kcinay055679 Jan 28, 2025
f5089f6
add submit functionality
kcinay055679 Jan 28, 2025
0c1b792
use proper base style
kcinay055679 Jan 28, 2025
3fbc0ca
finish base functionality
kcinay055679 Jan 28, 2025
949e52b
set number as default value
kcinay055679 Jan 28, 2025
8888b33
fix styling of unit management
kcinay055679 Jan 30, 2025
da21b15
fix jest tests
kcinay055679 Jan 30, 2025
2135745
fix unit tests and formatting
kcinay055679 Jan 30, 2025
c8df151
fix backen unit tests
kcinay055679 Jan 30, 2025
395c597
fix unit test
kcinay055679 Jan 30, 2025
fbbc629
fix
kcinay055679 Jan 30, 2025
26bc444
format
kcinay055679 Jan 30, 2025
2cf2b62
add manage-units jest tests
kcinay055679 Jan 30, 2025
0a2a1a8
fix jest tests
kcinay055679 Jan 30, 2025
9db1d98
add validation
kcinay055679 Jan 30, 2025
03ebfb3
fomrat
kcinay055679 Jan 30, 2025
6c27685
fix jest tests
kcinay055679 Jan 30, 2025
7eeafe0
show label
kcinay055679 Jan 30, 2025
e485ce1
fix error message in frontend
kcinay055679 Jan 30, 2025
481b416
Fix existing e2e tests and add new ones
ManuelMoeri Jan 30, 2025
6888648
fix e2e
kcinay055679 Jan 30, 2025
e5886c9
fix rebase
kcinay055679 Jan 31, 2025
4898a1f
make formatter happy
kcinay055679 Jan 31, 2025
6e59a12
fix styling
kcinay055679 Jan 31, 2025
ce8c6c7
remove translation in autocomplete
kcinay055679 Jan 31, 2025
b6eda30
rename default units
kcinay055679 Jan 31, 2025
b5bfe5b
fix jest test
kcinay055679 Jan 31, 2025
bec9c92
Implement new unit dialog class for editing and adding units and writ…
RandomTannenbaum Jan 31, 2025
c11001b
Remove unwanted .only
RandomTannenbaum Jan 31, 2025
e9121af
add runInBand to package.json
kcinay055679 Jan 31, 2025
100d0b7
fix after rebase
kcinay055679 Jan 31, 2025
f0af9ec
define initFormGroupFn once
kcinay055679 Jan 31, 2025
663e1dd
fix styling
kcinay055679 Jan 31, 2025
3b8bbb4
fix jest test
kcinay055679 Jan 31, 2025
2163948
fix capitalization of unit
kcinay055679 Jan 31, 2025
0c26ace
hups
kcinay055679 Jan 31, 2025
6acf501
Fix frontend tests
RandomTannenbaum Jan 31, 2025
145a3cc
allow enter to create new
kcinay055679 Jan 31, 2025
dba6b85
implement review
kcinay055679 Jan 31, 2025
801e881
fix rebase
kcinay055679 Jan 31, 2025
a512d3d
fix swagger
kcinay055679 Jan 31, 2025
0557177
fix backend formatter
kcinay055679 Jan 31, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions backend/src/main/java/ch/puzzle/okr/Constants.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ private Constants() {
public static final String KEY_RESULT = "KeyResult";
public static final String CHECK_IN = "Check-in";
public static final String ACTION = "Action";
public static final String UNIT = "Unit";
public static final String ALIGNMENT = "Alignment";
public static final String COMPLETED = "Completed";
public static final String QUARTER = "Quarter";
Expand Down
4 changes: 3 additions & 1 deletion backend/src/main/java/ch/puzzle/okr/ErrorKey.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ public enum ErrorKey {
ATTRIBUTE_NOT_SET,
ATTRIBUTE_CANNOT_CHANGE,
ATTRIBUTE_MUST_BE_DRAFT,
ATTRIBUTE_MUST_BE_UNIQUE,
KEY_RESULT_CONVERSION,
ALREADY_EXISTS_SAME_NAME,
CONVERT_TOKEN,
Expand All @@ -18,5 +19,6 @@ public enum ErrorKey {
NOT_AUTHORIZED_TO_DELETE,
TOKEN_NULL,
TRIED_TO_DELETE_LAST_ADMIN,
TRIED_TO_REMOVE_LAST_OKR_CHAMPION
TRIED_TO_REMOVE_LAST_OKR_CHAMPION,
MODEL_NOT_FOUND_BY_PROPERTY
}
3 changes: 2 additions & 1 deletion backend/src/main/java/ch/puzzle/okr/SecurityConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
import org.springframework.http.HttpStatus;
import org.springframework.security.authentication.AuthenticationEventPublisher;
import org.springframework.security.authentication.DefaultAuthenticationEventPublisher;
Expand All @@ -40,6 +41,7 @@
@Configuration
@EnableWebSecurity
@EnableMethodSecurity
@EnableJpaAuditing
public class SecurityConfig {
private static final Logger logger = LoggerFactory.getLogger(SecurityConfig.class);

Expand Down Expand Up @@ -126,5 +128,4 @@ private String okrPermissionPolicy() {
public AuthenticationEventPublisher authenticationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
return new DefaultAuthenticationEventPublisher(applicationEventPublisher);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package ch.puzzle.okr;

import ch.puzzle.okr.models.User;
import ch.puzzle.okr.service.authorization.AuthorizationService;
import java.util.Optional;
import org.springframework.data.domain.AuditorAware;
import org.springframework.stereotype.Component;

@Component
class SpringSecurityAuditorAware implements AuditorAware<User> {

private final AuthorizationService authorizationService;

public SpringSecurityAuditorAware(AuthorizationService authorizationService) {
this.authorizationService = authorizationService;
}

@Override
public Optional<User> getCurrentAuditor() {
return Optional.ofNullable(authorizationService.updateOrAddAuthorizationUser().user());
}
}
78 changes: 78 additions & 0 deletions backend/src/main/java/ch/puzzle/okr/controller/UnitController.java
MasterEvarior marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package ch.puzzle.okr.controller;

import ch.puzzle.okr.dto.UnitDto;
import ch.puzzle.okr.mapper.UnitMapper;
import ch.puzzle.okr.models.Unit;
import ch.puzzle.okr.service.authorization.UnitAuthorizationService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import java.util.List;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("api/v2/units")
public class UnitController {
private final UnitAuthorizationService unitAuthorizationService;
private final UnitMapper unitMapper;

public UnitController(UnitAuthorizationService unitAuthorizationService, UnitMapper unitMapper) {
this.unitAuthorizationService = unitAuthorizationService;
this.unitMapper = unitMapper;
}

@Operation(summary = "Get Units by User", description = "Retrieves a list of units associated with the currently authenticated user.")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "Successfully retrieved user's units", content = {
@Content(mediaType = "application/json", schema = @Schema(implementation = UnitDto.class)) }), })
@GetMapping("/user")
public List<UnitDto> getUnitsByUser() {
return unitAuthorizationService.getUnitsOfUser().stream().map(unitMapper::toDto).toList();
}

@Operation(summary = "Get All Units", description = "Retrieves a list of all available units.")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "Successfully retrieved all units", content = {
@Content(mediaType = "application/json", schema = @Schema(implementation = UnitDto.class)) }), })
@GetMapping
public List<UnitDto> getAllUnits() {
return unitAuthorizationService.getAllUnits().stream().map(unitMapper::toDto).toList();
}

@Operation(summary = "Create a Unit", description = "Creates a new unit with the provided details.")
@ApiResponses(value = {
@ApiResponse(responseCode = "201", description = "Unit successfully created", content = {
@Content(mediaType = "application/json", schema = @Schema(implementation = UnitDto.class)) }),
@ApiResponse(responseCode = "400", description = "Invalid input data", content = @Content) })
@PostMapping
public UnitDto createUnit(@io.swagger.v3.oas.annotations.parameters.RequestBody(description = "Unit data in JSON format.", required = true)
@RequestBody UnitDto unitDto) {
Unit unit = unitMapper.toUnit(unitDto);
return unitMapper.toDto(unitAuthorizationService.createUnit(unit));
}

@Operation(summary = "Update a Unit", description = "Updates an existing unit with new details.")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "Unit successfully updated", content = {
@Content(mediaType = "application/json", schema = @Schema(implementation = UnitDto.class)) }),
@ApiResponse(responseCode = "400", description = "Invalid input data", content = @Content),
@ApiResponse(responseCode = "404", description = "Unit not found", content = @Content) })
@PutMapping("/{unitId}")
public UnitDto updateUnit(@Parameter(description = "ID of the unit to be updated.", required = true)
@PathVariable long unitId, @io.swagger.v3.oas.annotations.parameters.RequestBody(description = "Updated unit data in JSON format.", required = true) @RequestBody UnitDto unitDto) {
Unit unit = unitMapper.toUnit(unitDto);
return unitMapper.toDto(unitAuthorizationService.updateUnit(unitId, unit));
}

@Operation(summary = "Delete a Unit", description = "Deletes an existing unit by its ID.")
@ApiResponses(value = { @ApiResponse(responseCode = "200", description = "Unit successfully deleted"),
@ApiResponse(responseCode = "404", description = "Unit not found") })
@DeleteMapping("/{unitId}")
public void deleteUnitById(@Parameter(description = "ID of the unit to be deleted.", required = true)
@PathVariable long unitId) {
unitAuthorizationService.deleteUnitById(unitId);
}
}
4 changes: 4 additions & 0 deletions backend/src/main/java/ch/puzzle/okr/dto/UnitDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package ch.puzzle.okr.dto;

public record UnitDto(Long id, String unitName, UserDto owner, boolean isDefault) {
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
package ch.puzzle.okr.dto.keyresult;

import ch.puzzle.okr.dto.ActionDto;
import ch.puzzle.okr.models.Unit;
import ch.puzzle.okr.dto.UnitDto;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import java.time.LocalDateTime;
import java.util.List;

@JsonDeserialize(as = KeyResultMetricDto.class)
public record KeyResultMetricDto(Long id, int version, String keyResultType, String title, String description,
Double baseline, Double stretchGoal, Unit unit, KeyResultUserDto owner, KeyResultObjectiveDto objective,
Double baseline, Double stretchGoal, UnitDto unit, KeyResultUserDto owner, KeyResultObjectiveDto objective,
KeyResultLastCheckInMetricDto lastCheckIn, LocalDateTime createdOn, LocalDateTime modifiedOn,
boolean isWriteable, List<ActionDto> actionList) implements KeyResultDto {
@Override
Expand Down
28 changes: 28 additions & 0 deletions backend/src/main/java/ch/puzzle/okr/mapper/UnitMapper.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package ch.puzzle.okr.mapper;

import ch.puzzle.okr.dto.UnitDto;
import ch.puzzle.okr.models.Unit;
import org.springframework.stereotype.Component;

@Component
public class UnitMapper {

private final UserMapper userMapper;

public UnitMapper(UserMapper userMapper) {
this.userMapper = userMapper;
}

public UnitDto toDto(Unit unit) {
return new UnitDto(unit.getId(), unit.getUnitName(), userMapper.toDto(unit.getCreatedBy()), unit.isDefault());
}

public Unit toUnit(UnitDto objectiveDto) {
return Unit.Builder
.builder()
.id(objectiveDto.id())
.unitName(objectiveDto.unitName())
.isDefault(objectiveDto.isDefault())
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@

import ch.puzzle.okr.dto.keyresult.*;
import ch.puzzle.okr.mapper.ActionMapper;
import ch.puzzle.okr.mapper.UnitMapper;
import ch.puzzle.okr.models.Action;
import ch.puzzle.okr.models.checkin.CheckIn;
import ch.puzzle.okr.models.checkin.CheckInMetric;
import ch.puzzle.okr.models.keyresult.KeyResult;
import ch.puzzle.okr.models.keyresult.KeyResultMetric;
import ch.puzzle.okr.service.business.CheckInBusinessService;
import ch.puzzle.okr.service.business.ObjectiveBusinessService;
import ch.puzzle.okr.service.business.UnitBusinessService;
import ch.puzzle.okr.service.business.UserBusinessService;
import java.util.List;
import org.springframework.stereotype.Component;
Expand All @@ -20,14 +22,19 @@ public class KeyResultMetricMapper {
private final ObjectiveBusinessService objectiveBusinessService;
private final CheckInBusinessService checkInBusinessService;
private final ActionMapper actionMapper;
private final UnitBusinessService unitBusinessService;
private final UnitMapper unitMapper;

public KeyResultMetricMapper(UserBusinessService userBusinessService,
ObjectiveBusinessService objectiveBusinessService,
CheckInBusinessService checkInBusinessService, ActionMapper actionMapper) {
CheckInBusinessService checkInBusinessService, ActionMapper actionMapper,
UnitBusinessService unitBusinessService, UnitMapper unitMapper) {
this.userBusinessService = userBusinessService;
this.objectiveBusinessService = objectiveBusinessService;
this.checkInBusinessService = checkInBusinessService;
this.actionMapper = actionMapper;
this.unitBusinessService = unitBusinessService;
this.unitMapper = unitMapper;
}

public KeyResultDto toDto(KeyResultMetric keyResult, List<Action> actionList) {
Expand Down Expand Up @@ -57,7 +64,7 @@ public KeyResultDto toDto(KeyResultMetric keyResult, List<Action> actionList) {
keyResult.getDescription(), //
keyResult.getBaseline(), //
keyResult.getStretchGoal(), //
keyResult.getUnit(), //
unitMapper.toDto(keyResult.getUnit()), //
ownerDto,
objectiveDto, //
lastCheckInDto, //
Expand All @@ -72,7 +79,7 @@ public KeyResult toKeyResultMetric(KeyResultMetricDto keyResultMetricDto) {
.builder() //
.withBaseline(keyResultMetricDto.baseline()) //
.withStretchGoal(keyResultMetricDto.stretchGoal()) //
.withUnit(keyResultMetricDto.unit()) //
.withUnit(unitBusinessService.findUnitByName(keyResultMetricDto.unit().unitName()))
.withId(keyResultMetricDto.id()) //
.withVersion(keyResultMetricDto.version()) //
.withObjective(objectiveBusinessService.getEntityById(keyResultMetricDto.objective().id())) //
Expand Down
Loading
Loading