Skip to content

Commit

Permalink
Merge pull request #118 from szymonpoltorak/DEV-108-Timeline-view
Browse files Browse the repository at this point in the history
Dev 108 timeline view
  • Loading branch information
szymonpoltorak authored May 11, 2024
2 parents af7ea04 + ca0ae9e commit 5a952b0
Show file tree
Hide file tree
Showing 19 changed files with 642 additions and 17 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,7 @@ generated

#Files from development builds
.cache/

#Other files

auth-server/keycloak-theme/themes/corn/login/resources/css/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import static dev.corn.cornbackend.api.sprint.constants.SprintMappings.GET_SPRINT_BY_ID;
import static dev.corn.cornbackend.api.sprint.constants.SprintMappings.SPRINTS_AFTER_SPRINT;
import static dev.corn.cornbackend.api.sprint.constants.SprintMappings.SPRINTS_BEFORE_SPRINT;
import static dev.corn.cornbackend.api.sprint.constants.SprintMappings.SPRINTS_BETWEEN_DATES;
import static dev.corn.cornbackend.api.sprint.constants.SprintMappings.SPRINT_API_ENDPOINT;
import static dev.corn.cornbackend.api.sprint.constants.SprintMappings.UPDATE_SPRINTS_DESCRIPTION;
import static dev.corn.cornbackend.api.sprint.constants.SprintMappings.UPDATE_SPRINTS_END_DATE;
Expand Down Expand Up @@ -119,4 +120,13 @@ public final Page<SprintResponse> getSprintsBeforeSprint(@RequestParam long spri
return sprintService.getSprintsBeforeSprint(sprintId, pageable, user);
}

@Override
@GetMapping(value = SPRINTS_BETWEEN_DATES)
public final List<SprintResponse> getSprintsBetweenDates(@RequestParam LocalDate startDate,
@RequestParam LocalDate endDate,
@RequestParam long projectId,
@JwtAuthed User user) {
return sprintService.getSprintsBetweenDates(startDate, endDate, projectId, user);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ public class SprintServiceImpl implements SprintService {
private static final String FOUND_SPRINT_TO_UPDATE = "Found sprint to update: {}";
private static final String PROJECT_NOT_FOUND = "Project with projectId: %d does not exist";
private static final String SPRINTS_ON_PAGE = "Sprints found on page : {}";
private static final String FOUND_PROJECT_WITH_ID = "Found project with id: {}";
private final SprintRepository sprintRepository;
private final ProjectRepository projectRepository;
private final BacklogItemRepository backlogItemRepository;
Expand Down Expand Up @@ -212,7 +213,7 @@ public List<SprintResponse> getCurrentAndFutureSprints(long projectId, User user

Project project = resolveProjectForProjectMember(projectId, user);

log.info("Found project with id: {}", project);
log.info(FOUND_PROJECT_WITH_ID, project);

Pageable pageable = PageRequest.of(0, FUTURE_SPRINTS_PER_PAGE, Sort.by(
Sort.Direction.ASC, SPRINT_START_DATE_FIELD_NAME)
Expand Down Expand Up @@ -258,6 +259,28 @@ public Page<SprintResponse> getSprintsBeforeSprint(long sprintId, Pageable pagea
return sprints.map(sprintMapper::toSprintResponse);
}

@Override
public final List<SprintResponse> getSprintsBetweenDates(LocalDate startDate, LocalDate endDate, long projectId,
User user) {
log.info("Getting sprints between dates: {} and {} for project with id: {}", startDate, endDate, projectId);

if(startDate.isAfter(endDate)) {
throw new SprintEndDateMustBeAfterStartDate(startDate, endDate);
}

Project project = resolveProjectForProjectMember(projectId, user);

log.info(FOUND_PROJECT_WITH_ID, project);

List<Sprint> sprints = sprintRepository.findAllBetweenDates(startDate, endDate, project);

log.info("Found and returning {} sprints", sprints.size());

return sprints.stream()
.map(sprintMapper::toSprintResponse)
.toList();
}

private Project resolveProjectForProjectMember(long projectId, User user) {
return projectRepository.findByIdWithProjectMember(projectId, user)
.orElseThrow(() -> new ProjectDoesNotExistException(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ public final class SprintMappings {

public static final String SPRINTS_BEFORE_SPRINT = "/getSprintsBeforeSprint";

public static final String SPRINTS_BETWEEN_DATES = "/getSprintsBetweenDates";

private SprintMappings() {
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -120,4 +120,6 @@ public interface SprintController {
* @return Page of sprints occurring before the specified sprint
*/
Page<SprintResponse> getSprintsBeforeSprint(long sprintId, Pageable pageable, User user);

List<SprintResponse> getSprintsBetweenDates(LocalDate startDate, LocalDate endDate, long projectId, User user);
}
Original file line number Diff line number Diff line change
Expand Up @@ -121,4 +121,6 @@ public interface SprintService {
*/
Page<SprintResponse> getSprintsBeforeSprint(long sprintId, Pageable pageable, User user);

List<SprintResponse> getSprintsBetweenDates(LocalDate startDate, LocalDate endDate, long projectId, User user);

}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import org.springframework.stereotype.Repository;

import java.time.LocalDate;
import java.util.List;
import java.util.Optional;

/**
Expand Down Expand Up @@ -128,5 +129,15 @@ select count(*) > 0 from Sprint s
*/
Page<Sprint> findAllByProjectAndEndDateBefore(Project project, LocalDate date, Pageable pageable);

@Query("""
SELECT s FROM Sprint s
WHERE s.project = :project AND
((s.startDate <= :startDate AND s.endDate >= :startDate) OR
(s.startDate <= :endDate AND s.endDate >= :endDate) OR
(s.startDate >= :startDate AND s.endDate <= :endDate))
ORDER BY s.startDate ASC
""")
List<Sprint> findAllBetweenDates(LocalDate startDate, LocalDate endDate, Project project);


}
37 changes: 30 additions & 7 deletions corn-frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions corn-frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"@angular/core": "^17.1.0",
"@angular/forms": "^17.1.0",
"@angular/material": "^17.1.1",
"@angular/material-moment-adapter": "^17.3.7",
"@angular/platform-browser": "^17.1.0",
"@angular/platform-browser-dynamic": "^17.1.0",
"@angular/router": "^17.1.0",
Expand All @@ -34,6 +35,7 @@
"@ng-icons/ux-aspects": "^26.3.0",
"keycloak-angular": "^15.1.0",
"keycloak-js": "^23.0.5",
"moment": "^2.30.1",
"rxjs": "~7.8.0",
"tslib": "^2.3.0",
"zone.js": "~0.14.3"
Expand Down
3 changes: 1 addition & 2 deletions corn-frontend/src/app/app.config.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import { APP_INITIALIZER, ApplicationConfig, importProvidersFrom, isDevMode } from '@angular/core';
import { provideRouter } from '@angular/router';

import { routes } from './app.routes';
import { provideServiceWorker } from '@angular/service-worker';
import { provideAnimations } from '@angular/platform-browser/animations';
import { HTTP_INTERCEPTORS, provideHttpClient, withInterceptorsFromDi } from '@angular/common/http';
import { ErrorInterceptor } from '@core/interceptors/error.interceptor';
import { KeycloakAngularModule, KeycloakBearerInterceptor, KeycloakService } from 'keycloak-angular';
import { provideNativeDateAdapter } from "@angular/material/core";
import { DatePipe } from "@angular/common";
import { provideNativeDateAdapter } from "@angular/material/core";

function initializeKeycloak(keycloak: KeycloakService) {
return () =>
Expand Down
1 change: 1 addition & 0 deletions corn-frontend/src/app/core/enum/api-url.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export enum ApiUrl {

GET_SPRINTS_ON_PAGE = SPRINT_API_URL + '/getSprintsOnPage',
GET_CURRENT_AND_FUTURE_SPRINTS = SPRINT_API_URL + '/currentAndFuture',
GET_SPRINTS_BETWEEN_DATES = SPRINT_API_URL + '/getSprintsBetweenDates',
DELETE_SPRINT = SPRINT_API_URL + '/deleteSprint',
UPDATE_SPRINTS_NAME = SPRINT_API_URL + '/updateSprintsName',
UPDATE_SPRINTS_START_DATE = SPRINT_API_URL + '/updateSprintsStartDate',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { Sprint } from "@interfaces/boards/backlog/sprint";
import { ApiUrl } from "@core/enum/api-url";
import { StorageService } from "@core/services/storage.service";
import { StorageKey } from "@core/enum/storage-key.enum";
import { Moment } from "moment";
import { SprintRequest } from "@interfaces/boards/backlog/sprint-request.interfaces";

@Injectable({
Expand Down Expand Up @@ -80,6 +81,16 @@ export class SprintService {
});
}

getSprintsBetweenDates(startDate: Moment, endDate: Moment): Observable<Sprint[]> {
return this.http.get<Sprint[]>(ApiUrl.GET_SPRINTS_BETWEEN_DATES, {
params: {
startDate: startDate.format('YYYY-MM-DD'),
endDate: endDate.format('YYYY-MM-DD'),
projectId: this.storage.getValueFromStorage(StorageKey.PROJECT_ID)
}
});
}

createSprint(result: SprintRequest): Observable<Sprint> {
return this.http.post<Sprint>(ApiUrl.CREATE_SPRINT, result);
}
Expand Down
27 changes: 27 additions & 0 deletions corn-frontend/src/app/pages/boards/timeline/day/day.component.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<div class="flex flex-col w-full h-full items-center justify-center border-2 border-amber-400/50">
<div class="flex flex-row w-full h-1/6 text-amber-500 items-center justify-center">
@if (day > 0) {
<h3>{{ day }}</h3>
}
</div>
<div class="flex h-5/6 w-full items-center justify-center">
@if (sprint) {
@if(isFirst) {
<div class="flex h-1/2 w-full items-center justify-start cursor-pointer bg-{{backgroundColor}}-{{color_value}} rounded-l-lg ml-2"
(mouseenter)="mouseOver()" (mouseleave)="mouseOut()" (click)="openSprint()">
<div class="ml-3">
<h3>{{ sprint.sprintName }}</h3>
</div>
</div>
} @else if(isLast) {
<div class="flex h-1/2 w-full items-center justify-start cursor-pointer bg-{{backgroundColor}}-{{color_value}} rounded-r-lg mr-2"
(mouseenter)="mouseOver()" (mouseleave)="mouseOut()" (click)="openSprint()">
</div>
} @else {
<div class="flex h-1/2 w-full items-center justify-start cursor-pointer bg-{{backgroundColor}}-{{color_value}}"
(mouseenter)="mouseOver()" (mouseleave)="mouseOut()" (click)="openSprint()">
</div>
}
}
</div>
</div>
71 changes: 71 additions & 0 deletions corn-frontend/src/app/pages/boards/timeline/day/day.component.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
.bg-red-500 {
@apply bg-red-500/50;
}

.bg-orange-500 {
@apply bg-orange-500/50;
}

.bg-yellow-500 {
@apply bg-yellow-500/50;
}

.bg-lime-500 {
@apply bg-lime-500/50;
}

.bg-green-500 {
@apply bg-green-500/50;
}

.bg-cyan-500 {
@apply bg-cyan-500/50;
}

.bg-blue-500 {
@apply bg-blue-500/50;
}

.bg-purple-500 {
@apply bg-purple-500/50;
}

.bg-pink-500 {
@apply bg-pink-500/50;
}

.bg-red-300 {
@apply bg-red-300/50;
}

.bg-orange-300 {
@apply bg-orange-300/50;
}

.bg-yellow-300 {
@apply bg-yellow-300/50;
}

.bg-lime-300 {
@apply bg-lime-300/50;
}

.bg-green-300 {
@apply bg-green-300/50;
}

.bg-cyan-300 {
@apply bg-cyan-300/50;
}

.bg-blue-300 {
@apply bg-blue-300/50;
}

.bg-purple-300 {
@apply bg-purple-300/50;
}

.bg-pink-300 {
@apply bg-pink-300/50;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { DayComponent } from './day.component';

describe('DayComponent', () => {
let component: DayComponent;
let fixture: ComponentFixture<DayComponent>;

beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [DayComponent]
})
.compileComponents();

fixture = TestBed.createComponent(DayComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});
Loading

0 comments on commit 5a952b0

Please sign in to comment.