issue-35 #37

Merged
sebastian merged 4 commits from issue-35 into master 2023-10-29 16:16:34 +01:00
8 changed files with 120 additions and 54 deletions
Showing only changes of commit 513a51c3db - Show all commits

View File

@ -5,7 +5,12 @@
</component>
<component name="ChangeListManager">
<list default="true" id="3a869f59-290a-4ab2-b036-a878ce801bc4" name="Changes" comment="Forget single schedule">
<change beforePath="$PROJECT_DIR$/src/main/java/core/api/controller/ScheduleController.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/core/api/controller/ScheduleController.java" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/main/java/core/api/models/timemanager/tasks/TaskScope.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/core/api/controller/TaskController.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/core/api/controller/TaskController.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/core/repositories/timemanager/TaskRepository.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/core/repositories/timemanager/TaskRepository.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/core/services/TaskService.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/core/services/TaskService.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../openapi.yaml" beforeDir="false" afterPath="$PROJECT_DIR$/../openapi.yaml" afterDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
@ -16,8 +21,8 @@
<option name="RECENT_TEMPLATES">
<list>
<option value="Interface" />
<option value="Enum" />
<option value="Class" />
<option value="Enum" />
</list>
</option>
</component>
@ -41,33 +46,34 @@
<option name="hideEmptyMiddlePackages" value="true" />
<option name="showLibraryContents" value="true" />
</component>
<component name="PropertiesComponent">{
&quot;keyToString&quot;: {
&quot;RequestMappingsPanelOrder0&quot;: &quot;0&quot;,
&quot;RequestMappingsPanelOrder1&quot;: &quot;1&quot;,
&quot;RequestMappingsPanelWidth0&quot;: &quot;75&quot;,
&quot;RequestMappingsPanelWidth1&quot;: &quot;75&quot;,
&quot;RunOnceActivity.OpenProjectViewOnStart&quot;: &quot;true&quot;,
&quot;RunOnceActivity.ShowReadmeOnStart&quot;: &quot;true&quot;,
&quot;WebServerToolWindowFactoryState&quot;: &quot;false&quot;,
&quot;git-widget-placeholder&quot;: &quot;issue-11-angular-update&quot;,
&quot;last_directory_selection&quot;: &quot;D:/Programmierprojekte/TimeManager/backend/src/main/java/core/api/models/timemanager&quot;,
&quot;last_opened_file_path&quot;: &quot;D:/Programmierprojekte/Dicewars/client&quot;,
&quot;node.js.detected.package.eslint&quot;: &quot;true&quot;,
&quot;node.js.detected.package.tslint&quot;: &quot;true&quot;,
&quot;node.js.selected.package.eslint&quot;: &quot;(autodetect)&quot;,
&quot;node.js.selected.package.tslint&quot;: &quot;(autodetect)&quot;,
&quot;nodejs_package_manager_path&quot;: &quot;npm&quot;,
&quot;settings.editor.selected.configurable&quot;: &quot;swagger&quot;,
&quot;ts.external.directory.path&quot;: &quot;/snap/intellij-idea-ultimate/459/plugins/javascript-impl/jsLanguageServicesImpl/external&quot;,
&quot;vue.rearranger.settings.migration&quot;: &quot;true&quot;
<component name="PropertiesComponent"><![CDATA[{
"keyToString": {
"RequestMappingsPanelOrder0": "0",
"RequestMappingsPanelOrder1": "1",
"RequestMappingsPanelWidth0": "75",
"RequestMappingsPanelWidth1": "75",
"RunOnceActivity.OpenProjectViewOnStart": "true",
"RunOnceActivity.ShowReadmeOnStart": "true",
"WebServerToolWindowFactoryState": "false",
"extract.method.default.visibility": "private",
"git-widget-placeholder": "issue-11-angular-update",
"last_directory_selection": "D:/Programmierprojekte/TimeManager/backend/src/main/java/core/api/models/timemanager",
"last_opened_file_path": "D:/Programmierprojekte/Dicewars/client",
"node.js.detected.package.eslint": "true",
"node.js.detected.package.tslint": "true",
"node.js.selected.package.eslint": "(autodetect)",
"node.js.selected.package.tslint": "(autodetect)",
"nodejs_package_manager_path": "npm",
"settings.editor.selected.configurable": "swagger",
"ts.external.directory.path": "/snap/intellij-idea-ultimate/459/plugins/javascript-impl/jsLanguageServicesImpl/external",
"vue.rearranger.settings.migration": "true"
},
&quot;keyToStringList&quot;: {
&quot;DatabaseDriversLRU&quot;: [
&quot;mariadb&quot;
"keyToStringList": {
"DatabaseDriversLRU": [
"mariadb"
]
}
}</component>
}]]></component>
<component name="RunManager">
<configuration name="DemoApplication" type="SpringBootApplicationConfigurationType" factoryName="Spring Boot" nameIsGenerated="true">
<module name="demo" />

View File

@ -4,6 +4,7 @@ import core.api.models.auth.SimpleStatusResponse;
import core.api.models.timemanager.taskSchedule.ScheduleInfo;
import core.api.models.timemanager.tasks.TaskEntityInfo;
import core.api.models.timemanager.tasks.TaskFieldInfo;
import core.api.models.timemanager.tasks.TaskScope;
import core.api.models.timemanager.tasks.TaskShortInfo;
import core.entities.timemanager.Task;
import core.entities.timemanager.Taskgroup;
@ -31,22 +32,37 @@ public class TaskController {
this.taskgroupService = taskgroupService;
}
@GetMapping("/tasks/all/{finished}")
public ResponseEntity<List<TaskShortInfo>> loadAllTasks(@PathVariable boolean finished) {
List<Task> taskList = taskService.loadAllTasks(SecurityContextHolder.getContext().getAuthentication().getName(), finished);
@GetMapping("/tasks/all/{scope}/{detailed}")
public ResponseEntity<?> loadAllTasksShort(@PathVariable TaskScope scope, @PathVariable boolean detailed) {
List<Task> taskList = taskService.loadAllTasks(SecurityContextHolder.getContext().getAuthentication().getName(), scope);
List<TaskShortInfo> taskShortInfos = new ArrayList<>();
List<TaskEntityInfo> taskInfos = new ArrayList<>();
for(Task task : taskList) {
List<Taskgroup> ancestors = Taskgroup.getAncestorList(task.getTaskgroup());
ancestors.add(task.getTaskgroup());
StringBuilder builder = new StringBuilder();
for(Taskgroup taskgroup : ancestors) {
builder.append(taskgroup.getTaskgroupName()).append("/");
StringBuilder builder = loadTaskgroupPath(task);
if(!detailed) {
taskShortInfos.add(new TaskShortInfo(task.getTaskID(), builder.toString()));
} else {
taskInfos.add(new TaskEntityInfo(task));
}
builder.append(task.getTaskName());
taskShortInfos.add(new TaskShortInfo(task.getTaskID(), builder.toString()));
}
return ResponseEntity.ok(taskShortInfos);
if(detailed) {
return ResponseEntity.ok(taskInfos);
} else {
return ResponseEntity.ok(taskShortInfos);
}
}
private StringBuilder loadTaskgroupPath(Task task) {
List<Taskgroup> ancestors = Taskgroup.getAncestorList(task.getTaskgroup());
ancestors.add(task.getTaskgroup());
StringBuilder builder = new StringBuilder();
for(Taskgroup taskgroup : ancestors) {
builder.append(taskgroup.getTaskgroupName()).append("/");
}
builder.append(task.getTaskName());
return builder;
}
@GetMapping("/tasks/{taskgroupID}/{status}")

View File

@ -0,0 +1,8 @@
package core.api.models.timemanager.tasks;
public enum TaskScope {
FINISHED,
UNFINISHED,
OVERDUE;
}

View File

@ -8,6 +8,7 @@ import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
import javax.transaction.Transactional;
import java.time.LocalDate;
import java.util.List;
@Repository
@ -25,4 +26,7 @@ public interface TaskRepository extends CrudRepository<Task, Long> {
@Modifying
@Query(value = "DELETE FROM Task t WHERE t.taskID = ?1")
void deleteByTaskID(long taskID);
@Query(value = "SELECT t FROM Task t WHERE t.taskgroup.user.username = ?1 AND t is NOT NULL AND t.deadline > ?2")
List<Task> findAllOverdue(String username, LocalDate now);
}

View File

@ -1,6 +1,7 @@
package core.services;
import core.api.models.timemanager.tasks.TaskFieldInfo;
import core.api.models.timemanager.tasks.TaskScope;
import core.entities.timemanager.BasicTaskSchedule;
import core.entities.timemanager.Task;
import core.entities.timemanager.Taskgroup;
@ -10,6 +11,7 @@ import core.repositories.timemanager.TaskgroupRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
@ -99,7 +101,18 @@ public class TaskService {
}
}
public List<Task> loadAllTasks(String username, boolean finished) {
return taskRepository.findAllByUser(username, finished);
public List<Task> loadAllTasks(String username, TaskScope scope) {
switch (scope) {
case UNFINISHED, FINISHED -> {
return taskRepository.findAllByUser(username, scope.equals(TaskScope.FINISHED));
}
case OVERDUE -> {
return taskRepository.findAllOverdue(username, LocalDate.now());
}
default -> {
return new ArrayList<>();
}
}
}
}

View File

@ -92,16 +92,20 @@ export class TaskService {
/**
* edits an existing task
* edits an existing task
* @param finished fetches either finished or unfinished tasks
* @param scope defines scope of fetched tasks
* @param detailed determines whether an detailed response is required or not
* @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
* @param reportProgress flag to report request and response progress.
*/
public tasksAllFinishedGet(finished: boolean, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<Array<TaskShortInfo>>;
public tasksAllFinishedGet(finished: boolean, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<HttpResponse<Array<TaskShortInfo>>>;
public tasksAllFinishedGet(finished: boolean, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<HttpEvent<Array<TaskShortInfo>>>;
public tasksAllFinishedGet(finished: boolean, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<any> {
if (finished === null || finished === undefined) {
throw new Error('Required parameter finished was null or undefined when calling tasksAllFinishedGet.');
public tasksAllScopeDetailedGet(scope: 'FINISHED' | 'UNFINISHED' | 'OVERDUE', detailed: boolean, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<Array<TaskShortInfo> | Array<TaskEntityInfo>>;
public tasksAllScopeDetailedGet(scope: 'FINISHED' | 'UNFINISHED' | 'OVERDUE', detailed: boolean, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<HttpResponse<Array<TaskShortInfo> | Array<TaskEntityInfo>>>;
public tasksAllScopeDetailedGet(scope: 'FINISHED' | 'UNFINISHED' | 'OVERDUE', detailed: boolean, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<HttpEvent<Array<TaskShortInfo> | Array<TaskEntityInfo>>>;
public tasksAllScopeDetailedGet(scope: 'FINISHED' | 'UNFINISHED' | 'OVERDUE', detailed: boolean, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<any> {
if (scope === null || scope === undefined) {
throw new Error('Required parameter scope was null or undefined when calling tasksAllScopeDetailedGet.');
}
if (detailed === null || detailed === undefined) {
throw new Error('Required parameter detailed was null or undefined when calling tasksAllScopeDetailedGet.');
}
let localVarHeaders = this.defaultHeaders;
@ -136,7 +140,7 @@ export class TaskService {
responseType_ = 'text';
}
return this.httpClient.get<Array<TaskShortInfo>>(`${this.configuration.basePath}/tasks/all/${encodeURIComponent(String(finished))}`,
return this.httpClient.get<Array<TaskShortInfo> | Array<TaskEntityInfo>>(`${this.configuration.basePath}/tasks/all/${encodeURIComponent(String(scope))}/${encodeURIComponent(String(detailed))}`,
{
context: localVarHttpContext,
responseType: <any>responseType_,

View File

@ -30,7 +30,7 @@ export class ForgottenTaskStartDialogComponent implements OnInit{
}
ngOnInit() {
this.taskService.tasksAllFinishedGet(false).subscribe({
this.taskService.tasksAllScopeDetailedGet("UNFINISHED", false).subscribe({
next: resp => {
this.tasks = resp;
this.filteredOptions = this.myControl.valueChanges.pipe(

View File

@ -883,7 +883,7 @@ paths:
schema:
type: object
$ref: "#/components/schemas/SimpleStatusResponse"
/tasks/all/{finished}:
/tasks/all/{scope}/{detailed}:
get:
security:
- API_TOKEN: []
@ -892,11 +892,21 @@ paths:
summary: edits an existing task
description: edits an existing task
parameters:
- name: finished
- name: scope
in: path
description: fetches either finished or unfinished tasks
description: defines scope of fetched tasks
required: true
schema:
type: string
enum:
- FINISHED
- UNFINISHED
- OVERDUE
- name: detailed
in: path
description: determines whether an detailed response is required or not
required: true
schema:
type: boolean
example: true
responses:
@ -905,9 +915,14 @@ paths:
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/TaskShortInfo'
oneOf:
- type: array
items:
$ref: '#/components/schemas/TaskShortInfo'
- type: array
items:
$ref: '#/components/schemas/TaskEntityInfo'
/tasks/{taskgroupID}/{status}:
get: