Merge pull request 'issue-10' (#17) from issue-10 into master
Reviewed-on: Sebastian/TimeManager#17
This commit is contained in:
commit
4cab32fae3
@ -10,3 +10,5 @@ npm install @openapitools/openapi-generator-cli -g
|
|||||||
```bash
|
```bash
|
||||||
npx @openapitools/openapi-generator-cli generate -i openapi.yaml -g typescript-angular -o frontend/src/api/
|
npx @openapitools/openapi-generator-cli generate -i openapi.yaml -g typescript-angular -o frontend/src/api/
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Notiz: Angular Calendar https://www.npmjs.com/package/angular-calendar
|
File diff suppressed because it is too large
Load Diff
@ -1,2 +0,0 @@
|
|||||||
#n:information_schema
|
|
||||||
!<md> [null, 0, null, null, -2147483648, -2147483648]
|
|
@ -1,2 +0,0 @@
|
|||||||
#n:mysql
|
|
||||||
!<md> [null, 0, null, null, -2147483648, -2147483648]
|
|
@ -1,2 +0,0 @@
|
|||||||
#n:performance_schema
|
|
||||||
!<md> [null, 0, null, null, -2147483648, -2147483648]
|
|
@ -1,2 +0,0 @@
|
|||||||
#n:restservice
|
|
||||||
!<md> [1695647618000, 0, null, null, -2147483648, -2147483648]
|
|
@ -9,4 +9,7 @@
|
|||||||
</option>
|
</option>
|
||||||
</component>
|
</component>
|
||||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="17" project-jdk-type="JavaSDK" />
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="17" project-jdk-type="JavaSDK" />
|
||||||
|
<component name="ProjectType">
|
||||||
|
<option name="id" value="jpab" />
|
||||||
|
</component>
|
||||||
</project>
|
</project>
|
@ -4,19 +4,46 @@
|
|||||||
<option name="autoReloadType" value="SELECTIVE" />
|
<option name="autoReloadType" value="SELECTIVE" />
|
||||||
</component>
|
</component>
|
||||||
<component name="ChangeListManager">
|
<component name="ChangeListManager">
|
||||||
<list default="true" id="3a869f59-290a-4ab2-b036-a878ce801bc4" name="Changes" comment="Structure Taskgroups in Hierarchies">
|
<list default="true" id="3a869f59-290a-4ab2-b036-a878ce801bc4" name="Changes" comment="Delete and clear Tasks (Frontend)">
|
||||||
|
<change afterPath="$PROJECT_DIR$/src/main/java/core/api/models/timemanager/taskgroup/TaskgroupDetailInfo.java" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/src/main/java/core/api/models/timemanager/taskgroup/TaskgroupShortInfo.java" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/../frontend/src/app/taskgroups/taskgroup-creation/taskgroup-creation.component.ts" beforeDir="false" afterPath="$PROJECT_DIR$/../frontend/src/app/taskgroups/taskgroup-creation/taskgroup-creation.component.ts" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/src/main/java/core/api/controller/TaskgroupController.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/core/api/controller/TaskgroupController.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/main/java/core/api/models/timemanager/taskgroup/TaskgroupEntityInfo.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/core/api/models/timemanager/taskgroup/TaskgroupEntityInfo.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/main/java/core/entities/timemanager/Taskgroup.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/core/entities/timemanager/Taskgroup.java" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/../frontend/src/api/.openapi-generator/FILES" beforeDir="false" afterPath="$PROJECT_DIR$/../frontend/src/api/.openapi-generator/FILES" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/../frontend/src/api/api/taskgroup.service.ts" beforeDir="false" afterPath="$PROJECT_DIR$/../frontend/src/api/api/taskgroup.service.ts" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/../frontend/src/api/model/models.ts" beforeDir="false" afterPath="$PROJECT_DIR$/../frontend/src/api/model/models.ts" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/../frontend/src/app/app.module.ts" beforeDir="false" afterPath="$PROJECT_DIR$/../frontend/src/app/app.module.ts" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/../frontend/src/app/taskgroups/taskgroup-dashboard/taskgroup-dashboard.component.css" beforeDir="false" afterPath="$PROJECT_DIR$/../frontend/src/app/taskgroups/taskgroup-dashboard/taskgroup-dashboard.component.css" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/../frontend/src/app/taskgroups/taskgroup-dashboard/taskgroup-dashboard.component.html" beforeDir="false" afterPath="$PROJECT_DIR$/../frontend/src/app/taskgroups/taskgroup-dashboard/taskgroup-dashboard.component.html" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/../frontend/src/app/taskgroups/taskgroup-dashboard/taskgroup-dashboard.component.ts" beforeDir="false" afterPath="$PROJECT_DIR$/../frontend/src/app/taskgroups/taskgroup-dashboard/taskgroup-dashboard.component.ts" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/../frontend/src/app/taskgroups/taskgroup-dashboard/taskgroup-dashboard.component.ts" beforeDir="false" afterPath="$PROJECT_DIR$/../frontend/src/app/taskgroups/taskgroup-dashboard/taskgroup-dashboard.component.ts" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/../openapi.yaml" beforeDir="false" afterPath="$PROJECT_DIR$/../openapi.yaml" afterDir="false" />
|
||||||
</list>
|
</list>
|
||||||
<option name="SHOW_DIALOG" value="false" />
|
<option name="SHOW_DIALOG" value="false" />
|
||||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||||
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
||||||
<option name="LAST_RESOLUTION" value="IGNORE" />
|
<option name="LAST_RESOLUTION" value="IGNORE" />
|
||||||
</component>
|
</component>
|
||||||
|
<component name="FileTemplateManagerImpl">
|
||||||
|
<option name="RECENT_TEMPLATES">
|
||||||
|
<list>
|
||||||
|
<option value="Interface" />
|
||||||
|
<option value="Class" />
|
||||||
|
</list>
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
<component name="Git.Settings">
|
<component name="Git.Settings">
|
||||||
|
<option name="RECENT_BRANCH_BY_REPOSITORY">
|
||||||
|
<map>
|
||||||
|
<entry key="$PROJECT_DIR$/.." value="master" />
|
||||||
|
</map>
|
||||||
|
</option>
|
||||||
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$/.." />
|
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$/.." />
|
||||||
</component>
|
</component>
|
||||||
|
<component name="JpbToolWindowState">
|
||||||
|
<option name="isToolWindowVisible" value="false" />
|
||||||
|
</component>
|
||||||
<component name="ProjectColorInfo">{
|
<component name="ProjectColorInfo">{
|
||||||
"customColor": "",
|
"customColor": "",
|
||||||
"associatedIndex": 6
|
"associatedIndex": 6
|
||||||
@ -35,11 +62,14 @@
|
|||||||
"RunOnceActivity.OpenProjectViewOnStart": "true",
|
"RunOnceActivity.OpenProjectViewOnStart": "true",
|
||||||
"RunOnceActivity.ShowReadmeOnStart": "true",
|
"RunOnceActivity.ShowReadmeOnStart": "true",
|
||||||
"WebServerToolWindowFactoryState": "false",
|
"WebServerToolWindowFactoryState": "false",
|
||||||
"git-widget-placeholder": "issue-7",
|
"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.eslint": "true",
|
||||||
"node.js.detected.package.tslint": "true",
|
"node.js.detected.package.tslint": "true",
|
||||||
"node.js.selected.package.eslint": "(autodetect)",
|
"node.js.selected.package.eslint": "(autodetect)",
|
||||||
"node.js.selected.package.tslint": "(autodetect)",
|
"node.js.selected.package.tslint": "(autodetect)",
|
||||||
|
"settings.editor.selected.configurable": "preferences.lookFeel",
|
||||||
"vue.rearranger.settings.migration": "true"
|
"vue.rearranger.settings.migration": "true"
|
||||||
},
|
},
|
||||||
"keyToStringList": {
|
"keyToStringList": {
|
||||||
@ -67,6 +97,12 @@
|
|||||||
<updated>1695647243767</updated>
|
<updated>1695647243767</updated>
|
||||||
<workItem from="1695647249321" duration="397000" />
|
<workItem from="1695647249321" duration="397000" />
|
||||||
<workItem from="1696183811713" duration="4994000" />
|
<workItem from="1696183811713" duration="4994000" />
|
||||||
|
<workItem from="1696399523081" duration="666000" />
|
||||||
|
<workItem from="1696517800445" duration="3887000" />
|
||||||
|
<workItem from="1696573678147" duration="111000" />
|
||||||
|
<workItem from="1697923629354" duration="3164000" />
|
||||||
|
<workItem from="1697958018921" duration="91000" />
|
||||||
|
<workItem from="1697958118995" duration="5749000" />
|
||||||
</task>
|
</task>
|
||||||
<task id="LOCAL-00001" summary="Structure Taskgroups in Hierarchies">
|
<task id="LOCAL-00001" summary="Structure Taskgroups in Hierarchies">
|
||||||
<option name="closed" value="true" />
|
<option name="closed" value="true" />
|
||||||
@ -76,7 +112,39 @@
|
|||||||
<option name="project" value="LOCAL" />
|
<option name="project" value="LOCAL" />
|
||||||
<updated>1696188127467</updated>
|
<updated>1696188127467</updated>
|
||||||
</task>
|
</task>
|
||||||
<option name="localTasksCounter" value="2" />
|
<task id="LOCAL-00002" summary="Datastructure for Tasks">
|
||||||
|
<option name="closed" value="true" />
|
||||||
|
<created>1696233406235</created>
|
||||||
|
<option name="number" value="00002" />
|
||||||
|
<option name="presentableId" value="LOCAL-00002" />
|
||||||
|
<option name="project" value="LOCAL" />
|
||||||
|
<updated>1696233406235</updated>
|
||||||
|
</task>
|
||||||
|
<task id="LOCAL-00003" summary="Implementing edit route for tasks">
|
||||||
|
<option name="closed" value="true" />
|
||||||
|
<created>1697929392755</created>
|
||||||
|
<option name="number" value="00003" />
|
||||||
|
<option name="presentableId" value="LOCAL-00003" />
|
||||||
|
<option name="project" value="LOCAL" />
|
||||||
|
<updated>1697929392755</updated>
|
||||||
|
</task>
|
||||||
|
<task id="LOCAL-00004" summary="Delete and clear Tasks">
|
||||||
|
<option name="closed" value="true" />
|
||||||
|
<created>1697962016013</created>
|
||||||
|
<option name="number" value="00004" />
|
||||||
|
<option name="presentableId" value="LOCAL-00004" />
|
||||||
|
<option name="project" value="LOCAL" />
|
||||||
|
<updated>1697962016013</updated>
|
||||||
|
</task>
|
||||||
|
<task id="LOCAL-00005" summary="Delete and clear Tasks (Frontend)">
|
||||||
|
<option name="closed" value="true" />
|
||||||
|
<created>1697962125518</created>
|
||||||
|
<option name="number" value="00005" />
|
||||||
|
<option name="presentableId" value="LOCAL-00005" />
|
||||||
|
<option name="project" value="LOCAL" />
|
||||||
|
<updated>1697962125518</updated>
|
||||||
|
</task>
|
||||||
|
<option name="localTasksCounter" value="6" />
|
||||||
<servers />
|
<servers />
|
||||||
</component>
|
</component>
|
||||||
<component name="TypeScriptGeneratedFilesManager">
|
<component name="TypeScriptGeneratedFilesManager">
|
||||||
@ -84,7 +152,12 @@
|
|||||||
</component>
|
</component>
|
||||||
<component name="VcsManagerConfiguration">
|
<component name="VcsManagerConfiguration">
|
||||||
<MESSAGE value="Structure Taskgroups in Hierarchies" />
|
<MESSAGE value="Structure Taskgroups in Hierarchies" />
|
||||||
<option name="LAST_COMMIT_MESSAGE" value="Structure Taskgroups in Hierarchies" />
|
<MESSAGE value="Update gitignore for idea folder" />
|
||||||
|
<MESSAGE value="Datastructure for Tasks" />
|
||||||
|
<MESSAGE value="Implementing edit route for tasks" />
|
||||||
|
<MESSAGE value="Delete and clear Tasks" />
|
||||||
|
<MESSAGE value="Delete and clear Tasks (Frontend)" />
|
||||||
|
<option name="LAST_COMMIT_MESSAGE" value="Delete and clear Tasks (Frontend)" />
|
||||||
</component>
|
</component>
|
||||||
<component name="XDebuggerManager">
|
<component name="XDebuggerManager">
|
||||||
<breakpoint-manager>
|
<breakpoint-manager>
|
||||||
|
@ -0,0 +1,99 @@
|
|||||||
|
package core.api.controller;
|
||||||
|
|
||||||
|
import core.api.models.auth.SimpleStatusResponse;
|
||||||
|
import core.api.models.timemanager.tasks.TaskEntityInfo;
|
||||||
|
import core.api.models.timemanager.tasks.TaskFieldInfo;
|
||||||
|
import core.entities.timemanager.Task;
|
||||||
|
import core.entities.timemanager.Taskgroup;
|
||||||
|
import core.services.*;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import javax.validation.Valid;
|
||||||
|
|
||||||
|
@CrossOrigin(origins = "*", maxAge = 3600)
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api")
|
||||||
|
public class TaskController {
|
||||||
|
|
||||||
|
private final TaskService taskService;
|
||||||
|
private final TaskgroupService taskgroupService;
|
||||||
|
|
||||||
|
public TaskController(@Autowired TaskService taskService, @Autowired TaskgroupService taskgroupService) {
|
||||||
|
this.taskService = taskService;
|
||||||
|
this.taskgroupService = taskgroupService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/tasks/{taskgroupID}/{status}")
|
||||||
|
public ResponseEntity<?> listTasksOfTaskgroup(@PathVariable long taskgroupID, @PathVariable String status) {
|
||||||
|
PermissionResult<Taskgroup> taskgroupPermissionResult = taskgroupService.getTaskgroupByIDAndUsername(taskgroupID, SecurityContextHolder.getContext().getAuthentication().getName());
|
||||||
|
if(!taskgroupPermissionResult.isHasPermissions()) {
|
||||||
|
return ResponseEntity.status(403).body(new SimpleStatusResponse("failed"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(taskgroupPermissionResult.getExitCode() == ServiceExitCode.MISSING_ENTITY) {
|
||||||
|
return ResponseEntity.status(404).body(new SimpleStatusResponse("failed"));
|
||||||
|
}
|
||||||
|
|
||||||
|
return ResponseEntity.ok(taskgroupPermissionResult.getResult().getTasks().stream().map(TaskEntityInfo::new));
|
||||||
|
}
|
||||||
|
|
||||||
|
@PutMapping("/tasks/{taskgroupID}")
|
||||||
|
public ResponseEntity<?> createTask(@PathVariable long taskgroupID, @RequestBody @Valid TaskFieldInfo taskFieldInfo) {
|
||||||
|
PermissionResult<Taskgroup> taskgroupPermissionResult = taskgroupService.getTaskgroupByIDAndUsername(taskgroupID, SecurityContextHolder.getContext().getAuthentication().getName());
|
||||||
|
if(!taskgroupPermissionResult.isHasPermissions()) {
|
||||||
|
return ResponseEntity.status(403).body(new SimpleStatusResponse("failed"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(taskgroupPermissionResult.getExitCode() == ServiceExitCode.MISSING_ENTITY) {
|
||||||
|
return ResponseEntity.status(404).body(new SimpleStatusResponse("failed"));
|
||||||
|
}
|
||||||
|
|
||||||
|
ServiceResult<Task> creationResult = taskService.createTask(taskgroupPermissionResult.getResult(), taskFieldInfo);
|
||||||
|
if(creationResult.getExitCode() == ServiceExitCode.ENTITY_ALREADY_EXIST) {
|
||||||
|
return ResponseEntity.status(409).body(new SimpleStatusResponse("failed"));
|
||||||
|
} else {
|
||||||
|
return ResponseEntity.ok(new TaskEntityInfo(creationResult.getResult()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/tasks/{taskID}")
|
||||||
|
public ResponseEntity<?> editTask(@PathVariable long taskID, @RequestBody @Valid TaskFieldInfo taskFieldInfo) {
|
||||||
|
PermissionResult<Task> taskPermissionResult = taskService.getTaskPermissions(taskID, SecurityContextHolder.getContext().getAuthentication().getName());
|
||||||
|
if (!taskPermissionResult.isHasPermissions()) {
|
||||||
|
return ResponseEntity.status(403).body(new SimpleStatusResponse("failed"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (taskPermissionResult.getExitCode() == ServiceExitCode.MISSING_ENTITY) {
|
||||||
|
return ResponseEntity.status(404).body(new SimpleStatusResponse("failed"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(taskFieldInfo.getStartDate().isAfter(taskFieldInfo.getDeadline())) {
|
||||||
|
return ResponseEntity.status(400).body(new SimpleStatusResponse("failed"));
|
||||||
|
}
|
||||||
|
|
||||||
|
ServiceResult<Task> editorResult = taskService.editTask(taskPermissionResult.getResult(), taskFieldInfo);
|
||||||
|
if (editorResult.getExitCode() == ServiceExitCode.OK) {
|
||||||
|
return ResponseEntity.ok(new SimpleStatusResponse("success"));
|
||||||
|
} else {
|
||||||
|
return ResponseEntity.status(409).body(new SimpleStatusResponse("failed"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@DeleteMapping("/tasks/{taskID}")
|
||||||
|
public ResponseEntity<?> deleteTask(@PathVariable long taskID) {
|
||||||
|
PermissionResult<Task> taskPermissionResult = taskService.getTaskPermissions(taskID, SecurityContextHolder.getContext().getAuthentication().getName());
|
||||||
|
if (!taskPermissionResult.isHasPermissions()) {
|
||||||
|
return ResponseEntity.status(403).body(new SimpleStatusResponse("failed"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (taskPermissionResult.getExitCode() == ServiceExitCode.MISSING_ENTITY) {
|
||||||
|
return ResponseEntity.status(404).body(new SimpleStatusResponse("failed"));
|
||||||
|
}
|
||||||
|
|
||||||
|
taskService.deleteTask(taskPermissionResult.getResult());
|
||||||
|
return ResponseEntity.ok(new SimpleStatusResponse("success"));
|
||||||
|
}
|
||||||
|
}
|
@ -1,16 +1,13 @@
|
|||||||
package core.api.controller;
|
package core.api.controller;
|
||||||
|
|
||||||
import core.api.models.auth.SimpleStatusResponse;
|
import core.api.models.auth.SimpleStatusResponse;
|
||||||
|
import core.api.models.timemanager.taskgroup.TaskgroupDetailInfo;
|
||||||
import core.api.models.timemanager.taskgroup.TaskgroupEntityInfo;
|
import core.api.models.timemanager.taskgroup.TaskgroupEntityInfo;
|
||||||
import core.api.models.timemanager.taskgroup.TaskgroupFieldInfo;
|
import core.api.models.timemanager.taskgroup.TaskgroupFieldInfo;
|
||||||
import core.entities.timemanager.Taskgroup;
|
import core.entities.timemanager.Taskgroup;
|
||||||
import core.services.PermissionResult;
|
import core.services.*;
|
||||||
import core.services.ServiceExitCode;
|
|
||||||
import core.services.ServiceResult;
|
|
||||||
import core.services.TaskgroupService;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.scheduling.config.Task;
|
|
||||||
import org.springframework.security.core.context.SecurityContextHolder;
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
@ -24,9 +21,11 @@ import java.util.Set;
|
|||||||
public class TaskgroupController {
|
public class TaskgroupController {
|
||||||
|
|
||||||
private final TaskgroupService taskgroupService;
|
private final TaskgroupService taskgroupService;
|
||||||
|
private final TaskService taskService;
|
||||||
|
|
||||||
public TaskgroupController(@Autowired TaskgroupService taskgroupService) {
|
public TaskgroupController(@Autowired TaskgroupService taskgroupService, @Autowired TaskService taskService) {
|
||||||
this.taskgroupService = taskgroupService;
|
this.taskgroupService = taskgroupService;
|
||||||
|
this.taskService = taskService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@PutMapping("/taskgroups")
|
@PutMapping("/taskgroups")
|
||||||
@ -92,7 +91,21 @@ public class TaskgroupController {
|
|||||||
return ResponseEntity.status(404).body(new SimpleStatusResponse("failed"));
|
return ResponseEntity.status(404).body(new SimpleStatusResponse("failed"));
|
||||||
}
|
}
|
||||||
|
|
||||||
Set<Taskgroup> children = taskgroupPermissionResult.getResult().getChildren();
|
return ResponseEntity.ok(new TaskgroupDetailInfo(taskgroupPermissionResult.getResult()));
|
||||||
return ResponseEntity.ok(children.stream().map(TaskgroupEntityInfo::new));
|
}
|
||||||
|
|
||||||
|
@DeleteMapping("/taskgroups/{taskgroupID}/clear")
|
||||||
|
public ResponseEntity<?> clearTasks(@PathVariable long taskgroupID) {
|
||||||
|
PermissionResult<Taskgroup> taskgroupPermissionResult = taskgroupService.getTaskgroupByIDAndUsername(taskgroupID, SecurityContextHolder.getContext().getAuthentication().getName());
|
||||||
|
if (!taskgroupPermissionResult.isHasPermissions()) {
|
||||||
|
return ResponseEntity.status(403).body(new SimpleStatusResponse("failed"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (taskgroupPermissionResult.getExitCode() == ServiceExitCode.MISSING_ENTITY) {
|
||||||
|
return ResponseEntity.status(404).body(new SimpleStatusResponse("failed"));
|
||||||
|
}
|
||||||
|
|
||||||
|
taskService.clearTasks(taskgroupPermissionResult.getResult());
|
||||||
|
return ResponseEntity.ok(new SimpleStatusResponse("success"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,45 @@
|
|||||||
|
package core.api.models.timemanager.taskgroup;
|
||||||
|
|
||||||
|
import core.entities.timemanager.Taskgroup;
|
||||||
|
import org.springframework.scheduling.config.Task;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class TaskgroupDetailInfo {
|
||||||
|
|
||||||
|
private List<TaskgroupEntityInfo> children;
|
||||||
|
private List<TaskgroupEntityInfo> ancestors;
|
||||||
|
private TaskgroupEntityInfo taskgroupInfo;
|
||||||
|
|
||||||
|
public TaskgroupDetailInfo(Taskgroup taskgroup) {
|
||||||
|
this.children = taskgroup.getChildren().stream().map(TaskgroupEntityInfo::new).toList();
|
||||||
|
List<Taskgroup> ancestorList = Taskgroup.getAncestorList(taskgroup);
|
||||||
|
this.ancestors = ancestorList.stream().map(TaskgroupEntityInfo::new).toList();
|
||||||
|
this.taskgroupInfo = new TaskgroupEntityInfo(taskgroup);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<TaskgroupEntityInfo> getChildren() {
|
||||||
|
return children;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setChildren(List<TaskgroupEntityInfo> children) {
|
||||||
|
this.children = children;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<TaskgroupEntityInfo> getAncestors() {
|
||||||
|
return ancestors;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAncestors(List<TaskgroupEntityInfo> ancestors) {
|
||||||
|
this.ancestors = ancestors;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TaskgroupEntityInfo getTaskgroupInfo() {
|
||||||
|
return taskgroupInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTaskgroupInfo(TaskgroupEntityInfo taskgroupInfo) {
|
||||||
|
this.taskgroupInfo = taskgroupInfo;
|
||||||
|
}
|
||||||
|
}
|
@ -7,17 +7,9 @@ public class TaskgroupEntityInfo {
|
|||||||
private long taskgroupID;
|
private long taskgroupID;
|
||||||
private String taskgroupName;
|
private String taskgroupName;
|
||||||
|
|
||||||
private TaskgroupEntityInfo parentTaskgroup;
|
|
||||||
|
|
||||||
public TaskgroupEntityInfo(Taskgroup taskgroup) {
|
public TaskgroupEntityInfo(Taskgroup taskgroup) {
|
||||||
this.taskgroupID = taskgroup.getTaskgroupID();
|
this.taskgroupID = taskgroup.getTaskgroupID();
|
||||||
this.taskgroupName = taskgroup.getTaskgroupName();
|
this.taskgroupName = taskgroup.getTaskgroupName();
|
||||||
|
|
||||||
if(taskgroup.getParent() == null) {
|
|
||||||
this.parentTaskgroup = null;
|
|
||||||
} else {
|
|
||||||
this.parentTaskgroup = new TaskgroupEntityInfo(taskgroup.getParent());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getTaskgroupID() {
|
public long getTaskgroupID() {
|
||||||
@ -35,12 +27,4 @@ public class TaskgroupEntityInfo {
|
|||||||
public void setTaskgroupName(String taskgroupName) {
|
public void setTaskgroupName(String taskgroupName) {
|
||||||
this.taskgroupName = taskgroupName;
|
this.taskgroupName = taskgroupName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TaskgroupEntityInfo getParentTaskgroup() {
|
|
||||||
return parentTaskgroup;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setParentTaskgroup(TaskgroupEntityInfo parentTaskgroup) {
|
|
||||||
this.parentTaskgroup = parentTaskgroup;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,7 @@
|
|||||||
|
package core.api.models.timemanager.taskgroup;
|
||||||
|
|
||||||
|
public class TaskgroupShortInfo {
|
||||||
|
|
||||||
|
private long taskgroupID;
|
||||||
|
private String taskgroupName;
|
||||||
|
}
|
@ -0,0 +1,88 @@
|
|||||||
|
package core.api.models.timemanager.tasks;
|
||||||
|
|
||||||
|
import core.api.models.timemanager.taskgroup.TaskgroupEntityInfo;
|
||||||
|
import core.entities.timemanager.Task;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
|
|
||||||
|
public class TaskEntityInfo {
|
||||||
|
|
||||||
|
private long taskID;
|
||||||
|
private String taskName;
|
||||||
|
|
||||||
|
private int eta;
|
||||||
|
|
||||||
|
private LocalDate startDate;
|
||||||
|
|
||||||
|
private LocalDate deadline;
|
||||||
|
|
||||||
|
private boolean overdue;
|
||||||
|
|
||||||
|
private boolean finished;
|
||||||
|
|
||||||
|
public TaskEntityInfo(Task task) {
|
||||||
|
this.taskID = task.getTaskID();
|
||||||
|
this.taskName = task.getTaskName();
|
||||||
|
this.eta = task.getEta();
|
||||||
|
this.startDate = task.getStartDate();
|
||||||
|
this.deadline = task.getDeadline();
|
||||||
|
this.overdue = LocalDate.now().isAfter(task.getDeadline());
|
||||||
|
this.finished = task.isFinished();
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getTaskID() {
|
||||||
|
return taskID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTaskID(long taskID) {
|
||||||
|
this.taskID = taskID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTaskName() {
|
||||||
|
return taskName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTaskName(String taskName) {
|
||||||
|
this.taskName = taskName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getEta() {
|
||||||
|
return eta;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEta(int eta) {
|
||||||
|
this.eta = eta;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LocalDate getStartDate() {
|
||||||
|
return startDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStartDate(LocalDate startDate) {
|
||||||
|
this.startDate = startDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LocalDate getDeadline() {
|
||||||
|
return deadline;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDeadline(LocalDate deadline) {
|
||||||
|
this.deadline = deadline;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isOverdue() {
|
||||||
|
return overdue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOverdue(boolean overdue) {
|
||||||
|
this.overdue = overdue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isFinished() {
|
||||||
|
return finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFinished(boolean finished) {
|
||||||
|
this.finished = finished;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,48 @@
|
|||||||
|
package core.api.models.timemanager.tasks;
|
||||||
|
|
||||||
|
import org.hibernate.validator.constraints.Length;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotBlank;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
|
||||||
|
public class TaskFieldInfo {
|
||||||
|
|
||||||
|
@NotBlank
|
||||||
|
@Length(max = 255)
|
||||||
|
private String taskName;
|
||||||
|
private int eta;
|
||||||
|
private LocalDate startDate;
|
||||||
|
private LocalDate deadline;
|
||||||
|
|
||||||
|
public String getTaskName() {
|
||||||
|
return taskName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTaskName(String taskName) {
|
||||||
|
this.taskName = taskName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getEta() {
|
||||||
|
return eta;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEta(int eta) {
|
||||||
|
this.eta = eta;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LocalDate getStartDate() {
|
||||||
|
return startDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStartDate(LocalDate startDate) {
|
||||||
|
this.startDate = startDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LocalDate getDeadline() {
|
||||||
|
return deadline;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDeadline(LocalDate deadline) {
|
||||||
|
this.deadline = deadline;
|
||||||
|
}
|
||||||
|
}
|
108
backend/src/main/java/core/entities/timemanager/Task.java
Normal file
108
backend/src/main/java/core/entities/timemanager/Task.java
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
package core.entities.timemanager;
|
||||||
|
|
||||||
|
import javax.persistence.*;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "tasks")
|
||||||
|
public class Task {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||||
|
private long taskID;
|
||||||
|
|
||||||
|
@ManyToOne
|
||||||
|
@JoinColumn(name = "taskgroup_id")
|
||||||
|
private Taskgroup taskgroup;
|
||||||
|
private String taskName;
|
||||||
|
|
||||||
|
private LocalDate startDate;
|
||||||
|
|
||||||
|
private LocalDate deadline;
|
||||||
|
|
||||||
|
private int eta;
|
||||||
|
|
||||||
|
private boolean finished;
|
||||||
|
|
||||||
|
public Task(Taskgroup taskgroup, String taskName, LocalDate startDate, LocalDate deadline, int eta) {
|
||||||
|
this.taskgroup = taskgroup;
|
||||||
|
this.taskName = taskName;
|
||||||
|
this.startDate = startDate;
|
||||||
|
this.deadline = deadline;
|
||||||
|
this.eta = eta;
|
||||||
|
this.finished = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getTaskID() {
|
||||||
|
return taskID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Taskgroup getTaskgroup() {
|
||||||
|
return taskgroup;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTaskgroup(Taskgroup taskgroup) {
|
||||||
|
this.taskgroup = taskgroup;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTaskName() {
|
||||||
|
return taskName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTaskName(String taskName) {
|
||||||
|
this.taskName = taskName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LocalDate getStartDate() {
|
||||||
|
return startDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStartDate(LocalDate startDate) {
|
||||||
|
this.startDate = startDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LocalDate getDeadline() {
|
||||||
|
return deadline;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDeadline(LocalDate deadline) {
|
||||||
|
this.deadline = deadline;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getEta() {
|
||||||
|
return eta;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEta(int eta) {
|
||||||
|
this.eta = eta;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void finish() {
|
||||||
|
this.finished = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isFinished() {
|
||||||
|
return finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFinished(boolean finished) {
|
||||||
|
this.finished = finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
Task task = (Task) o;
|
||||||
|
return taskID == task.taskID;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(taskID);
|
||||||
|
}
|
||||||
|
}
|
@ -4,7 +4,7 @@ import core.entities.User;
|
|||||||
|
|
||||||
import javax.persistence.*;
|
import javax.persistence.*;
|
||||||
import javax.validation.constraints.NotBlank;
|
import javax.validation.constraints.NotBlank;
|
||||||
import java.util.Set;
|
import java.util.*;
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name= "taskgroups")
|
@Table(name= "taskgroups")
|
||||||
@ -29,6 +29,9 @@ public class Taskgroup {
|
|||||||
@JoinColumn(name = "parent_id")
|
@JoinColumn(name = "parent_id")
|
||||||
private Taskgroup parent;
|
private Taskgroup parent;
|
||||||
|
|
||||||
|
@OneToMany(mappedBy = "taskgroup", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
|
||||||
|
private Set<Task> tasks;
|
||||||
|
|
||||||
public Taskgroup(String taskgroupName, User user) {
|
public Taskgroup(String taskgroupName, User user) {
|
||||||
this.taskgroupName = taskgroupName;
|
this.taskgroupName = taskgroupName;
|
||||||
this.user = user;
|
this.user = user;
|
||||||
@ -76,4 +79,22 @@ public class Taskgroup {
|
|||||||
public void setParent(Taskgroup parent) {
|
public void setParent(Taskgroup parent) {
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Set<Task> getTasks() {
|
||||||
|
return tasks;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTasks(Set<Task> tasks) {
|
||||||
|
this.tasks = tasks;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<Taskgroup> getAncestorList(Taskgroup taskgroup) {
|
||||||
|
List<Taskgroup> ancestors = new ArrayList<>();
|
||||||
|
Taskgroup currentTaskgroup = taskgroup;
|
||||||
|
while(currentTaskgroup.parent != null) {
|
||||||
|
ancestors.add(currentTaskgroup.parent);
|
||||||
|
currentTaskgroup = currentTaskgroup.parent;
|
||||||
|
}
|
||||||
|
return ancestors;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,24 @@
|
|||||||
|
package core.repositories.timemanager;
|
||||||
|
|
||||||
|
import core.entities.timemanager.Task;
|
||||||
|
import core.entities.timemanager.Taskgroup;
|
||||||
|
import org.springframework.data.jpa.repository.Modifying;
|
||||||
|
import org.springframework.data.jpa.repository.Query;
|
||||||
|
import org.springframework.data.repository.CrudRepository;
|
||||||
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
|
import javax.transaction.Transactional;
|
||||||
|
|
||||||
|
@Repository
|
||||||
|
public interface TaskRepository extends CrudRepository<Task, Long> {
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
@Modifying
|
||||||
|
@Query(value = "DELETE FROM Task t WHERE t.taskgroup = ?1")
|
||||||
|
void deleteAllByTaskgroup(Taskgroup taskgroup);
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
@Modifying
|
||||||
|
@Query(value = "DELETE FROM Task t WHERE t.taskID = ?1")
|
||||||
|
void deleteByTaskID(long taskID);
|
||||||
|
}
|
76
backend/src/main/java/core/services/TaskService.java
Normal file
76
backend/src/main/java/core/services/TaskService.java
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
package core.services;
|
||||||
|
|
||||||
|
import core.api.models.timemanager.tasks.TaskFieldInfo;
|
||||||
|
import core.entities.timemanager.Task;
|
||||||
|
import core.entities.timemanager.Taskgroup;
|
||||||
|
import core.repositories.timemanager.TaskRepository;
|
||||||
|
import core.repositories.timemanager.TaskgroupRepository;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class TaskService {
|
||||||
|
|
||||||
|
private final TaskRepository taskRepository;
|
||||||
|
private final TaskgroupRepository taskgroupRepository;
|
||||||
|
|
||||||
|
public TaskService(@Autowired TaskRepository taskRepository,
|
||||||
|
TaskgroupRepository taskgroupRepository) {
|
||||||
|
this.taskRepository = taskRepository;
|
||||||
|
this.taskgroupRepository = taskgroupRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ServiceResult<Task> createTask(Taskgroup taskgroup, TaskFieldInfo taskFieldInfo) {
|
||||||
|
if(existTaskByName(taskgroup.getTasks(), taskFieldInfo.getTaskName())) {
|
||||||
|
return new ServiceResult<>(ServiceExitCode.ENTITY_ALREADY_EXIST);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Task task = new Task(taskgroup, taskFieldInfo.getTaskName(), taskFieldInfo.getStartDate(), taskFieldInfo.getDeadline(), taskFieldInfo.getEta());
|
||||||
|
taskgroup.getTasks().add(task);
|
||||||
|
taskRepository.save(task);
|
||||||
|
|
||||||
|
return new ServiceResult<>(task);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean existTaskByName(Collection<Task> tasks, String name) {
|
||||||
|
for(Task task : tasks) {
|
||||||
|
if(task.getTaskName().equals(name)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PermissionResult<Task> getTaskPermissions(long taskID, String name) {
|
||||||
|
Optional<Task> task = taskRepository.findById(taskID);
|
||||||
|
return task.map(value -> new PermissionResult<>(value, value.getTaskgroup().getUser().getUsername().equals(name))).orElseGet(() ->
|
||||||
|
new PermissionResult<>(ServiceExitCode.MISSING_ENTITY));
|
||||||
|
}
|
||||||
|
|
||||||
|
public ServiceResult<Task> editTask(Task task, TaskFieldInfo taskFieldInfo) {
|
||||||
|
if(!task.getTaskName().equals(taskFieldInfo.getTaskName()) && !existTaskByName(task.getTaskgroup().getTasks(), taskFieldInfo.getTaskName())) {
|
||||||
|
task.setTaskName(taskFieldInfo.getTaskName());
|
||||||
|
|
||||||
|
} else if(!task.getTaskName().equals(taskFieldInfo.getTaskName()) && existTaskByName(task.getTaskgroup().getTasks(), taskFieldInfo.getTaskName())) {
|
||||||
|
return new ServiceResult<>(ServiceExitCode.ENTITY_ALREADY_EXIST);
|
||||||
|
}
|
||||||
|
task.setEta(taskFieldInfo.getEta());
|
||||||
|
task.setStartDate(taskFieldInfo.getStartDate());
|
||||||
|
task.setDeadline(taskFieldInfo.getDeadline());
|
||||||
|
taskRepository.save(task);
|
||||||
|
return new ServiceResult<>(task);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void deleteTask(Task task) {
|
||||||
|
taskRepository.deleteByTaskID(task.getTaskID());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clearTasks(Taskgroup taskgroup) {
|
||||||
|
taskRepository.deleteAllByTaskgroup(taskgroup);
|
||||||
|
}
|
||||||
|
}
|
@ -1,16 +0,0 @@
|
|||||||
# This file is used by the build system to adjust CSS and JS output to support the specified browsers below.
|
|
||||||
# For additional information regarding the format and rule options, please see:
|
|
||||||
# https://github.com/browserslist/browserslist#queries
|
|
||||||
|
|
||||||
# For the full list of supported browsers by the Angular framework, please see:
|
|
||||||
# https://angular.io/guide/browser-support
|
|
||||||
|
|
||||||
# You can see what browsers were selected by your queries by running:
|
|
||||||
# npx browserslist
|
|
||||||
|
|
||||||
last 1 Chrome version
|
|
||||||
last 1 Firefox version
|
|
||||||
last 2 Edge major versions
|
|
||||||
last 2 Safari major versions
|
|
||||||
last 2 iOS major versions
|
|
||||||
Firefox ESR
|
|
@ -103,6 +103,5 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
"defaultProject": "frontend"
|
|
||||||
}
|
}
|
||||||
|
18182
frontend/package-lock.json
generated
18182
frontend/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -10,24 +10,28 @@
|
|||||||
},
|
},
|
||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@angular/animations": "~13.2.0",
|
"@angular-material-components/datetime-picker": "^16.0.1",
|
||||||
"@angular/cdk": "^13.2.2",
|
"@angular-material-components/moment-adapter": "^16.0.1",
|
||||||
"@angular/common": "~13.2.0",
|
"@angular/animations": "^16.2.7",
|
||||||
"@angular/compiler": "~13.2.0",
|
"@angular/cdk": "^16.2.6",
|
||||||
"@angular/core": "~13.2.0",
|
"@angular/common": "^16.2.7",
|
||||||
"@angular/forms": "~13.2.0",
|
"@angular/compiler": "^16.2.7",
|
||||||
"@angular/material": "^13.2.2",
|
"@angular/core": "^16.2.7",
|
||||||
"@angular/platform-browser": "~13.2.0",
|
"@angular/forms": "^16.2.7",
|
||||||
"@angular/platform-browser-dynamic": "~13.2.0",
|
"@angular/material": "^16.2.6",
|
||||||
"@angular/router": "~13.2.0",
|
"@angular/material-moment-adapter": "^16.2.7",
|
||||||
|
"@angular/platform-browser": "^16.2.7",
|
||||||
|
"@angular/platform-browser-dynamic": "^16.2.7",
|
||||||
|
"@angular/router": "^16.2.7",
|
||||||
|
"moment": "^2.29.4",
|
||||||
"rxjs": "~7.5.0",
|
"rxjs": "~7.5.0",
|
||||||
"tslib": "^2.3.0",
|
"tslib": "^2.3.0",
|
||||||
"zone.js": "~0.11.4"
|
"zone.js": "~0.13.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@angular-devkit/build-angular": "~13.2.2",
|
"@angular-devkit/build-angular": "^16.2.4",
|
||||||
"@angular/cli": "~13.2.2",
|
"@angular/cli": "^16.2.4",
|
||||||
"@angular/compiler-cli": "~13.2.0",
|
"@angular/compiler-cli": "^16.2.7",
|
||||||
"@types/jasmine": "~3.10.0",
|
"@types/jasmine": "~3.10.0",
|
||||||
"@types/node": "^12.11.1",
|
"@types/node": "^12.11.1",
|
||||||
"jasmine-core": "~4.0.0",
|
"jasmine-core": "~4.0.0",
|
||||||
@ -36,6 +40,6 @@
|
|||||||
"karma-coverage": "~2.1.0",
|
"karma-coverage": "~2.1.0",
|
||||||
"karma-jasmine": "~4.0.0",
|
"karma-jasmine": "~4.0.0",
|
||||||
"karma-jasmine-html-reporter": "~1.7.0",
|
"karma-jasmine-html-reporter": "~1.7.0",
|
||||||
"typescript": "~4.5.2"
|
"typescript": "~5.1.6"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -5,6 +5,7 @@ api/account.service.ts
|
|||||||
api/api.ts
|
api/api.ts
|
||||||
api/login.service.ts
|
api/login.service.ts
|
||||||
api/properties.service.ts
|
api/properties.service.ts
|
||||||
|
api/task.service.ts
|
||||||
api/taskgroup.service.ts
|
api/taskgroup.service.ts
|
||||||
api/users.service.ts
|
api/users.service.ts
|
||||||
configuration.ts
|
configuration.ts
|
||||||
@ -25,6 +26,10 @@ model/propertiesInfo.ts
|
|||||||
model/propertyInfo.ts
|
model/propertyInfo.ts
|
||||||
model/propertyUpdateRequest.ts
|
model/propertyUpdateRequest.ts
|
||||||
model/signUpRequest.ts
|
model/signUpRequest.ts
|
||||||
|
model/simpleStatusResponse.ts
|
||||||
|
model/taskEntityInfo.ts
|
||||||
|
model/taskFieldInfo.ts
|
||||||
|
model/taskgroupDetailInfo.ts
|
||||||
model/taskgroupEntityInfo.ts
|
model/taskgroupEntityInfo.ts
|
||||||
model/taskgroupFieldInfo.ts
|
model/taskgroupFieldInfo.ts
|
||||||
model/userAddInfo.ts
|
model/userAddInfo.ts
|
||||||
|
@ -5,6 +5,7 @@ import { HttpClient } from '@angular/common/http';
|
|||||||
import { AccountService } from './api/account.service';
|
import { AccountService } from './api/account.service';
|
||||||
import { LoginService } from './api/login.service';
|
import { LoginService } from './api/login.service';
|
||||||
import { PropertiesService } from './api/properties.service';
|
import { PropertiesService } from './api/properties.service';
|
||||||
|
import { TaskService } from './api/task.service';
|
||||||
import { TaskgroupService } from './api/taskgroup.service';
|
import { TaskgroupService } from './api/taskgroup.service';
|
||||||
import { UsersService } from './api/users.service';
|
import { UsersService } from './api/users.service';
|
||||||
|
|
||||||
|
@ -4,8 +4,10 @@ export * from './login.service';
|
|||||||
import { LoginService } from './login.service';
|
import { LoginService } from './login.service';
|
||||||
export * from './properties.service';
|
export * from './properties.service';
|
||||||
import { PropertiesService } from './properties.service';
|
import { PropertiesService } from './properties.service';
|
||||||
|
export * from './task.service';
|
||||||
|
import { TaskService } from './task.service';
|
||||||
export * from './taskgroup.service';
|
export * from './taskgroup.service';
|
||||||
import { TaskgroupService } from './taskgroup.service';
|
import { TaskgroupService } from './taskgroup.service';
|
||||||
export * from './users.service';
|
export * from './users.service';
|
||||||
import { UsersService } from './users.service';
|
import { UsersService } from './users.service';
|
||||||
export const APIS = [AccountService, LoginService, PropertiesService, TaskgroupService, UsersService];
|
export const APIS = [AccountService, LoginService, PropertiesService, TaskService, TaskgroupService, UsersService];
|
||||||
|
363
frontend/src/api/api/task.service.ts
Normal file
363
frontend/src/api/api/task.service.ts
Normal file
@ -0,0 +1,363 @@
|
|||||||
|
/**
|
||||||
|
* API Title
|
||||||
|
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||||
|
*
|
||||||
|
* The version of the OpenAPI document: 1.0
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
|
||||||
|
* https://openapi-generator.tech
|
||||||
|
* Do not edit the class manually.
|
||||||
|
*/
|
||||||
|
/* tslint:disable:no-unused-variable member-ordering */
|
||||||
|
|
||||||
|
import { Inject, Injectable, Optional } from '@angular/core';
|
||||||
|
import { HttpClient, HttpHeaders, HttpParams,
|
||||||
|
HttpResponse, HttpEvent, HttpParameterCodec, HttpContext
|
||||||
|
} from '@angular/common/http';
|
||||||
|
import { CustomHttpParameterCodec } from '../encoder';
|
||||||
|
import { Observable } from 'rxjs';
|
||||||
|
|
||||||
|
import { InlineResponse403 } from '../model/models';
|
||||||
|
import { SimpleStatusResponse } from '../model/models';
|
||||||
|
import { TaskEntityInfo } from '../model/models';
|
||||||
|
import { TaskFieldInfo } from '../model/models';
|
||||||
|
|
||||||
|
import { BASE_PATH, COLLECTION_FORMATS } from '../variables';
|
||||||
|
import { Configuration } from '../configuration';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root'
|
||||||
|
})
|
||||||
|
export class TaskService {
|
||||||
|
|
||||||
|
protected basePath = 'http://localhost:8080/api';
|
||||||
|
public defaultHeaders = new HttpHeaders();
|
||||||
|
public configuration = new Configuration();
|
||||||
|
public encoder: HttpParameterCodec;
|
||||||
|
|
||||||
|
constructor(protected httpClient: HttpClient, @Optional()@Inject(BASE_PATH) basePath: string, @Optional() configuration: Configuration) {
|
||||||
|
if (configuration) {
|
||||||
|
this.configuration = configuration;
|
||||||
|
}
|
||||||
|
if (typeof this.configuration.basePath !== 'string') {
|
||||||
|
if (typeof basePath !== 'string') {
|
||||||
|
basePath = this.basePath;
|
||||||
|
}
|
||||||
|
this.configuration.basePath = basePath;
|
||||||
|
}
|
||||||
|
this.encoder = this.configuration.encoder || new CustomHttpParameterCodec();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private addToHttpParams(httpParams: HttpParams, value: any, key?: string): HttpParams {
|
||||||
|
if (typeof value === "object" && value instanceof Date === false) {
|
||||||
|
httpParams = this.addToHttpParamsRecursive(httpParams, value);
|
||||||
|
} else {
|
||||||
|
httpParams = this.addToHttpParamsRecursive(httpParams, value, key);
|
||||||
|
}
|
||||||
|
return httpParams;
|
||||||
|
}
|
||||||
|
|
||||||
|
private addToHttpParamsRecursive(httpParams: HttpParams, value?: any, key?: string): HttpParams {
|
||||||
|
if (value == null) {
|
||||||
|
return httpParams;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof value === "object") {
|
||||||
|
if (Array.isArray(value)) {
|
||||||
|
(value as any[]).forEach( elem => httpParams = this.addToHttpParamsRecursive(httpParams, elem, key));
|
||||||
|
} else if (value instanceof Date) {
|
||||||
|
if (key != null) {
|
||||||
|
httpParams = httpParams.append(key,
|
||||||
|
(value as Date).toISOString().substr(0, 10));
|
||||||
|
} else {
|
||||||
|
throw Error("key may not be null if value is Date");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Object.keys(value).forEach( k => httpParams = this.addToHttpParamsRecursive(
|
||||||
|
httpParams, value[k], key != null ? `${key}.${k}` : k));
|
||||||
|
}
|
||||||
|
} else if (key != null) {
|
||||||
|
httpParams = httpParams.append(key, value);
|
||||||
|
} else {
|
||||||
|
throw Error("key may not be null if value is not object or array");
|
||||||
|
}
|
||||||
|
return httpParams;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* edits an existing task
|
||||||
|
* edits an existing task
|
||||||
|
* @param taskID internal id of task
|
||||||
|
* @param taskFieldInfo
|
||||||
|
* @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 tasksTaskIDDelete(taskID: number, taskFieldInfo?: TaskFieldInfo, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<SimpleStatusResponse>;
|
||||||
|
public tasksTaskIDDelete(taskID: number, taskFieldInfo?: TaskFieldInfo, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<HttpResponse<SimpleStatusResponse>>;
|
||||||
|
public tasksTaskIDDelete(taskID: number, taskFieldInfo?: TaskFieldInfo, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<HttpEvent<SimpleStatusResponse>>;
|
||||||
|
public tasksTaskIDDelete(taskID: number, taskFieldInfo?: TaskFieldInfo, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<any> {
|
||||||
|
if (taskID === null || taskID === undefined) {
|
||||||
|
throw new Error('Required parameter taskID was null or undefined when calling tasksTaskIDDelete.');
|
||||||
|
}
|
||||||
|
|
||||||
|
let localVarHeaders = this.defaultHeaders;
|
||||||
|
|
||||||
|
let localVarCredential: string | undefined;
|
||||||
|
// authentication (API_TOKEN) required
|
||||||
|
localVarCredential = this.configuration.lookupCredential('API_TOKEN');
|
||||||
|
if (localVarCredential) {
|
||||||
|
localVarHeaders = localVarHeaders.set('Authorization', 'Bearer ' + localVarCredential);
|
||||||
|
}
|
||||||
|
|
||||||
|
let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept;
|
||||||
|
if (localVarHttpHeaderAcceptSelected === undefined) {
|
||||||
|
// to determine the Accept header
|
||||||
|
const httpHeaderAccepts: string[] = [
|
||||||
|
'application/json'
|
||||||
|
];
|
||||||
|
localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts);
|
||||||
|
}
|
||||||
|
if (localVarHttpHeaderAcceptSelected !== undefined) {
|
||||||
|
localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected);
|
||||||
|
}
|
||||||
|
|
||||||
|
let localVarHttpContext: HttpContext | undefined = options && options.context;
|
||||||
|
if (localVarHttpContext === undefined) {
|
||||||
|
localVarHttpContext = new HttpContext();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// to determine the Content-Type header
|
||||||
|
const consumes: string[] = [
|
||||||
|
'application/json'
|
||||||
|
];
|
||||||
|
const httpContentTypeSelected: string | undefined = this.configuration.selectHeaderContentType(consumes);
|
||||||
|
if (httpContentTypeSelected !== undefined) {
|
||||||
|
localVarHeaders = localVarHeaders.set('Content-Type', httpContentTypeSelected);
|
||||||
|
}
|
||||||
|
|
||||||
|
let responseType_: 'text' | 'json' = 'json';
|
||||||
|
if(localVarHttpHeaderAcceptSelected && localVarHttpHeaderAcceptSelected.startsWith('text')) {
|
||||||
|
responseType_ = 'text';
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.httpClient.delete<SimpleStatusResponse>(`${this.configuration.basePath}/tasks/${encodeURIComponent(String(taskID))}`,
|
||||||
|
{
|
||||||
|
context: localVarHttpContext,
|
||||||
|
responseType: <any>responseType_,
|
||||||
|
withCredentials: this.configuration.withCredentials,
|
||||||
|
headers: localVarHeaders,
|
||||||
|
observe: observe,
|
||||||
|
reportProgress: reportProgress
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* edits an existing task
|
||||||
|
* edits an existing task
|
||||||
|
* @param taskID internal id of task
|
||||||
|
* @param taskFieldInfo
|
||||||
|
* @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 tasksTaskIDPost(taskID: number, taskFieldInfo?: TaskFieldInfo, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<TaskEntityInfo>;
|
||||||
|
public tasksTaskIDPost(taskID: number, taskFieldInfo?: TaskFieldInfo, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<HttpResponse<TaskEntityInfo>>;
|
||||||
|
public tasksTaskIDPost(taskID: number, taskFieldInfo?: TaskFieldInfo, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<HttpEvent<TaskEntityInfo>>;
|
||||||
|
public tasksTaskIDPost(taskID: number, taskFieldInfo?: TaskFieldInfo, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<any> {
|
||||||
|
if (taskID === null || taskID === undefined) {
|
||||||
|
throw new Error('Required parameter taskID was null or undefined when calling tasksTaskIDPost.');
|
||||||
|
}
|
||||||
|
|
||||||
|
let localVarHeaders = this.defaultHeaders;
|
||||||
|
|
||||||
|
let localVarCredential: string | undefined;
|
||||||
|
// authentication (API_TOKEN) required
|
||||||
|
localVarCredential = this.configuration.lookupCredential('API_TOKEN');
|
||||||
|
if (localVarCredential) {
|
||||||
|
localVarHeaders = localVarHeaders.set('Authorization', 'Bearer ' + localVarCredential);
|
||||||
|
}
|
||||||
|
|
||||||
|
let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept;
|
||||||
|
if (localVarHttpHeaderAcceptSelected === undefined) {
|
||||||
|
// to determine the Accept header
|
||||||
|
const httpHeaderAccepts: string[] = [
|
||||||
|
'application/json'
|
||||||
|
];
|
||||||
|
localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts);
|
||||||
|
}
|
||||||
|
if (localVarHttpHeaderAcceptSelected !== undefined) {
|
||||||
|
localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected);
|
||||||
|
}
|
||||||
|
|
||||||
|
let localVarHttpContext: HttpContext | undefined = options && options.context;
|
||||||
|
if (localVarHttpContext === undefined) {
|
||||||
|
localVarHttpContext = new HttpContext();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// to determine the Content-Type header
|
||||||
|
const consumes: string[] = [
|
||||||
|
'application/json'
|
||||||
|
];
|
||||||
|
const httpContentTypeSelected: string | undefined = this.configuration.selectHeaderContentType(consumes);
|
||||||
|
if (httpContentTypeSelected !== undefined) {
|
||||||
|
localVarHeaders = localVarHeaders.set('Content-Type', httpContentTypeSelected);
|
||||||
|
}
|
||||||
|
|
||||||
|
let responseType_: 'text' | 'json' = 'json';
|
||||||
|
if(localVarHttpHeaderAcceptSelected && localVarHttpHeaderAcceptSelected.startsWith('text')) {
|
||||||
|
responseType_ = 'text';
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.httpClient.post<TaskEntityInfo>(`${this.configuration.basePath}/tasks/${encodeURIComponent(String(taskID))}`,
|
||||||
|
taskFieldInfo,
|
||||||
|
{
|
||||||
|
context: localVarHttpContext,
|
||||||
|
responseType: <any>responseType_,
|
||||||
|
withCredentials: this.configuration.withCredentials,
|
||||||
|
headers: localVarHeaders,
|
||||||
|
observe: observe,
|
||||||
|
reportProgress: reportProgress
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* creates a new task
|
||||||
|
* creates tasks
|
||||||
|
* @param taskgroupID internal id of taskgroup
|
||||||
|
* @param taskFieldInfo
|
||||||
|
* @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 tasksTaskgroupIDPut(taskgroupID: number, taskFieldInfo?: TaskFieldInfo, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<TaskEntityInfo>;
|
||||||
|
public tasksTaskgroupIDPut(taskgroupID: number, taskFieldInfo?: TaskFieldInfo, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<HttpResponse<TaskEntityInfo>>;
|
||||||
|
public tasksTaskgroupIDPut(taskgroupID: number, taskFieldInfo?: TaskFieldInfo, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<HttpEvent<TaskEntityInfo>>;
|
||||||
|
public tasksTaskgroupIDPut(taskgroupID: number, taskFieldInfo?: TaskFieldInfo, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<any> {
|
||||||
|
if (taskgroupID === null || taskgroupID === undefined) {
|
||||||
|
throw new Error('Required parameter taskgroupID was null or undefined when calling tasksTaskgroupIDPut.');
|
||||||
|
}
|
||||||
|
|
||||||
|
let localVarHeaders = this.defaultHeaders;
|
||||||
|
|
||||||
|
let localVarCredential: string | undefined;
|
||||||
|
// authentication (API_TOKEN) required
|
||||||
|
localVarCredential = this.configuration.lookupCredential('API_TOKEN');
|
||||||
|
if (localVarCredential) {
|
||||||
|
localVarHeaders = localVarHeaders.set('Authorization', 'Bearer ' + localVarCredential);
|
||||||
|
}
|
||||||
|
|
||||||
|
let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept;
|
||||||
|
if (localVarHttpHeaderAcceptSelected === undefined) {
|
||||||
|
// to determine the Accept header
|
||||||
|
const httpHeaderAccepts: string[] = [
|
||||||
|
'application/json'
|
||||||
|
];
|
||||||
|
localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts);
|
||||||
|
}
|
||||||
|
if (localVarHttpHeaderAcceptSelected !== undefined) {
|
||||||
|
localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected);
|
||||||
|
}
|
||||||
|
|
||||||
|
let localVarHttpContext: HttpContext | undefined = options && options.context;
|
||||||
|
if (localVarHttpContext === undefined) {
|
||||||
|
localVarHttpContext = new HttpContext();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// to determine the Content-Type header
|
||||||
|
const consumes: string[] = [
|
||||||
|
'application/json'
|
||||||
|
];
|
||||||
|
const httpContentTypeSelected: string | undefined = this.configuration.selectHeaderContentType(consumes);
|
||||||
|
if (httpContentTypeSelected !== undefined) {
|
||||||
|
localVarHeaders = localVarHeaders.set('Content-Type', httpContentTypeSelected);
|
||||||
|
}
|
||||||
|
|
||||||
|
let responseType_: 'text' | 'json' = 'json';
|
||||||
|
if(localVarHttpHeaderAcceptSelected && localVarHttpHeaderAcceptSelected.startsWith('text')) {
|
||||||
|
responseType_ = 'text';
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.httpClient.put<TaskEntityInfo>(`${this.configuration.basePath}/tasks/${encodeURIComponent(String(taskgroupID))}`,
|
||||||
|
taskFieldInfo,
|
||||||
|
{
|
||||||
|
context: localVarHttpContext,
|
||||||
|
responseType: <any>responseType_,
|
||||||
|
withCredentials: this.configuration.withCredentials,
|
||||||
|
headers: localVarHeaders,
|
||||||
|
observe: observe,
|
||||||
|
reportProgress: reportProgress
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* list tasks
|
||||||
|
* list tasks
|
||||||
|
* @param taskgroupID internal id of taskgroup
|
||||||
|
* @param status scope of listed tasks
|
||||||
|
* @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 tasksTaskgroupIDStatusGet(taskgroupID: number, status: 'all' | 'overdue' | 'upcoming', observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<Array<TaskEntityInfo>>;
|
||||||
|
public tasksTaskgroupIDStatusGet(taskgroupID: number, status: 'all' | 'overdue' | 'upcoming', observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<HttpResponse<Array<TaskEntityInfo>>>;
|
||||||
|
public tasksTaskgroupIDStatusGet(taskgroupID: number, status: 'all' | 'overdue' | 'upcoming', observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<HttpEvent<Array<TaskEntityInfo>>>;
|
||||||
|
public tasksTaskgroupIDStatusGet(taskgroupID: number, status: 'all' | 'overdue' | 'upcoming', observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<any> {
|
||||||
|
if (taskgroupID === null || taskgroupID === undefined) {
|
||||||
|
throw new Error('Required parameter taskgroupID was null or undefined when calling tasksTaskgroupIDStatusGet.');
|
||||||
|
}
|
||||||
|
if (status === null || status === undefined) {
|
||||||
|
throw new Error('Required parameter status was null or undefined when calling tasksTaskgroupIDStatusGet.');
|
||||||
|
}
|
||||||
|
|
||||||
|
let localVarHeaders = this.defaultHeaders;
|
||||||
|
|
||||||
|
let localVarCredential: string | undefined;
|
||||||
|
// authentication (API_TOKEN) required
|
||||||
|
localVarCredential = this.configuration.lookupCredential('API_TOKEN');
|
||||||
|
if (localVarCredential) {
|
||||||
|
localVarHeaders = localVarHeaders.set('Authorization', 'Bearer ' + localVarCredential);
|
||||||
|
}
|
||||||
|
|
||||||
|
let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept;
|
||||||
|
if (localVarHttpHeaderAcceptSelected === undefined) {
|
||||||
|
// to determine the Accept header
|
||||||
|
const httpHeaderAccepts: string[] = [
|
||||||
|
'application/json'
|
||||||
|
];
|
||||||
|
localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts);
|
||||||
|
}
|
||||||
|
if (localVarHttpHeaderAcceptSelected !== undefined) {
|
||||||
|
localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected);
|
||||||
|
}
|
||||||
|
|
||||||
|
let localVarHttpContext: HttpContext | undefined = options && options.context;
|
||||||
|
if (localVarHttpContext === undefined) {
|
||||||
|
localVarHttpContext = new HttpContext();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
let responseType_: 'text' | 'json' = 'json';
|
||||||
|
if(localVarHttpHeaderAcceptSelected && localVarHttpHeaderAcceptSelected.startsWith('text')) {
|
||||||
|
responseType_ = 'text';
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.httpClient.get<Array<TaskEntityInfo>>(`${this.configuration.basePath}/tasks/${encodeURIComponent(String(taskgroupID))}/${encodeURIComponent(String(status))}`,
|
||||||
|
{
|
||||||
|
context: localVarHttpContext,
|
||||||
|
responseType: <any>responseType_,
|
||||||
|
withCredentials: this.configuration.withCredentials,
|
||||||
|
headers: localVarHeaders,
|
||||||
|
observe: observe,
|
||||||
|
reportProgress: reportProgress
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -20,6 +20,8 @@ import { Observable } from 'rxjs';
|
|||||||
|
|
||||||
import { InlineResponse200 } from '../model/models';
|
import { InlineResponse200 } from '../model/models';
|
||||||
import { InlineResponse403 } from '../model/models';
|
import { InlineResponse403 } from '../model/models';
|
||||||
|
import { SimpleStatusResponse } from '../model/models';
|
||||||
|
import { TaskgroupDetailInfo } from '../model/models';
|
||||||
import { TaskgroupEntityInfo } from '../model/models';
|
import { TaskgroupEntityInfo } from '../model/models';
|
||||||
import { TaskgroupFieldInfo } from '../model/models';
|
import { TaskgroupFieldInfo } from '../model/models';
|
||||||
|
|
||||||
@ -264,6 +266,65 @@ export class TaskgroupService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clears tasks
|
||||||
|
* Deletes all tasks of that taskgroup
|
||||||
|
* @param taskgroupID internal id of taskgroup
|
||||||
|
* @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 taskgroupsTaskgroupIDClearDelete(taskgroupID: number, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<SimpleStatusResponse>;
|
||||||
|
public taskgroupsTaskgroupIDClearDelete(taskgroupID: number, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<HttpResponse<SimpleStatusResponse>>;
|
||||||
|
public taskgroupsTaskgroupIDClearDelete(taskgroupID: number, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<HttpEvent<SimpleStatusResponse>>;
|
||||||
|
public taskgroupsTaskgroupIDClearDelete(taskgroupID: number, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<any> {
|
||||||
|
if (taskgroupID === null || taskgroupID === undefined) {
|
||||||
|
throw new Error('Required parameter taskgroupID was null or undefined when calling taskgroupsTaskgroupIDClearDelete.');
|
||||||
|
}
|
||||||
|
|
||||||
|
let localVarHeaders = this.defaultHeaders;
|
||||||
|
|
||||||
|
let localVarCredential: string | undefined;
|
||||||
|
// authentication (API_TOKEN) required
|
||||||
|
localVarCredential = this.configuration.lookupCredential('API_TOKEN');
|
||||||
|
if (localVarCredential) {
|
||||||
|
localVarHeaders = localVarHeaders.set('Authorization', 'Bearer ' + localVarCredential);
|
||||||
|
}
|
||||||
|
|
||||||
|
let localVarHttpHeaderAcceptSelected: string | undefined = options && options.httpHeaderAccept;
|
||||||
|
if (localVarHttpHeaderAcceptSelected === undefined) {
|
||||||
|
// to determine the Accept header
|
||||||
|
const httpHeaderAccepts: string[] = [
|
||||||
|
'application/json'
|
||||||
|
];
|
||||||
|
localVarHttpHeaderAcceptSelected = this.configuration.selectHeaderAccept(httpHeaderAccepts);
|
||||||
|
}
|
||||||
|
if (localVarHttpHeaderAcceptSelected !== undefined) {
|
||||||
|
localVarHeaders = localVarHeaders.set('Accept', localVarHttpHeaderAcceptSelected);
|
||||||
|
}
|
||||||
|
|
||||||
|
let localVarHttpContext: HttpContext | undefined = options && options.context;
|
||||||
|
if (localVarHttpContext === undefined) {
|
||||||
|
localVarHttpContext = new HttpContext();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
let responseType_: 'text' | 'json' = 'json';
|
||||||
|
if(localVarHttpHeaderAcceptSelected && localVarHttpHeaderAcceptSelected.startsWith('text')) {
|
||||||
|
responseType_ = 'text';
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.httpClient.delete<SimpleStatusResponse>(`${this.configuration.basePath}/taskgroups/${encodeURIComponent(String(taskgroupID))}/clear`,
|
||||||
|
{
|
||||||
|
context: localVarHttpContext,
|
||||||
|
responseType: <any>responseType_,
|
||||||
|
withCredentials: this.configuration.withCredentials,
|
||||||
|
headers: localVarHeaders,
|
||||||
|
observe: observe,
|
||||||
|
reportProgress: reportProgress
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* deletes taskgroup
|
* deletes taskgroup
|
||||||
* deletes taskgroup
|
* deletes taskgroup
|
||||||
@ -330,9 +391,9 @@ export class TaskgroupService {
|
|||||||
* @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
|
* @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.
|
* @param reportProgress flag to report request and response progress.
|
||||||
*/
|
*/
|
||||||
public taskgroupsTaskgroupIDGet(taskgroupID: number, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<Array<TaskgroupEntityInfo>>;
|
public taskgroupsTaskgroupIDGet(taskgroupID: number, observe?: 'body', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<TaskgroupDetailInfo>;
|
||||||
public taskgroupsTaskgroupIDGet(taskgroupID: number, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<HttpResponse<Array<TaskgroupEntityInfo>>>;
|
public taskgroupsTaskgroupIDGet(taskgroupID: number, observe?: 'response', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<HttpResponse<TaskgroupDetailInfo>>;
|
||||||
public taskgroupsTaskgroupIDGet(taskgroupID: number, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<HttpEvent<Array<TaskgroupEntityInfo>>>;
|
public taskgroupsTaskgroupIDGet(taskgroupID: number, observe?: 'events', reportProgress?: boolean, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<HttpEvent<TaskgroupDetailInfo>>;
|
||||||
public taskgroupsTaskgroupIDGet(taskgroupID: number, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<any> {
|
public taskgroupsTaskgroupIDGet(taskgroupID: number, observe: any = 'body', reportProgress: boolean = false, options?: {httpHeaderAccept?: 'application/json', context?: HttpContext}): Observable<any> {
|
||||||
if (taskgroupID === null || taskgroupID === undefined) {
|
if (taskgroupID === null || taskgroupID === undefined) {
|
||||||
throw new Error('Required parameter taskgroupID was null or undefined when calling taskgroupsTaskgroupIDGet.');
|
throw new Error('Required parameter taskgroupID was null or undefined when calling taskgroupsTaskgroupIDGet.');
|
||||||
@ -370,7 +431,7 @@ export class TaskgroupService {
|
|||||||
responseType_ = 'text';
|
responseType_ = 'text';
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.httpClient.get<Array<TaskgroupEntityInfo>>(`${this.configuration.basePath}/taskgroups/${encodeURIComponent(String(taskgroupID))}`,
|
return this.httpClient.get<TaskgroupDetailInfo>(`${this.configuration.basePath}/taskgroups/${encodeURIComponent(String(taskgroupID))}`,
|
||||||
{
|
{
|
||||||
context: localVarHttpContext,
|
context: localVarHttpContext,
|
||||||
responseType: <any>responseType_,
|
responseType: <any>responseType_,
|
||||||
|
@ -11,6 +11,10 @@ export * from './propertiesInfo';
|
|||||||
export * from './propertyInfo';
|
export * from './propertyInfo';
|
||||||
export * from './propertyUpdateRequest';
|
export * from './propertyUpdateRequest';
|
||||||
export * from './signUpRequest';
|
export * from './signUpRequest';
|
||||||
|
export * from './simpleStatusResponse';
|
||||||
|
export * from './taskEntityInfo';
|
||||||
|
export * from './taskFieldInfo';
|
||||||
|
export * from './taskgroupDetailInfo';
|
||||||
export * from './taskgroupEntityInfo';
|
export * from './taskgroupEntityInfo';
|
||||||
export * from './taskgroupFieldInfo';
|
export * from './taskgroupFieldInfo';
|
||||||
export * from './userAddInfo';
|
export * from './userAddInfo';
|
||||||
|
28
frontend/src/api/model/simpleStatusResponse.ts
Normal file
28
frontend/src/api/model/simpleStatusResponse.ts
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
/**
|
||||||
|
* API Title
|
||||||
|
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||||
|
*
|
||||||
|
* The version of the OpenAPI document: 1.0
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
|
||||||
|
* https://openapi-generator.tech
|
||||||
|
* Do not edit the class manually.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
export interface SimpleStatusResponse {
|
||||||
|
/**
|
||||||
|
* Response Status der Request
|
||||||
|
*/
|
||||||
|
status: SimpleStatusResponse.StatusEnum;
|
||||||
|
}
|
||||||
|
export namespace SimpleStatusResponse {
|
||||||
|
export type StatusEnum = 'success' | 'failed';
|
||||||
|
export const StatusEnum = {
|
||||||
|
Success: 'success' as StatusEnum,
|
||||||
|
Failed: 'failed' as StatusEnum
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
44
frontend/src/api/model/taskEntityInfo.ts
Normal file
44
frontend/src/api/model/taskEntityInfo.ts
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
/**
|
||||||
|
* API Title
|
||||||
|
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||||
|
*
|
||||||
|
* The version of the OpenAPI document: 1.0
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
|
||||||
|
* https://openapi-generator.tech
|
||||||
|
* Do not edit the class manually.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
export interface TaskEntityInfo {
|
||||||
|
/**
|
||||||
|
* internal id of task
|
||||||
|
*/
|
||||||
|
taskID: number;
|
||||||
|
/**
|
||||||
|
* name of task
|
||||||
|
*/
|
||||||
|
taskName: string;
|
||||||
|
/**
|
||||||
|
* expected time to finish task
|
||||||
|
*/
|
||||||
|
eta: number;
|
||||||
|
/**
|
||||||
|
* date from which the task can be started
|
||||||
|
*/
|
||||||
|
startDate: string;
|
||||||
|
/**
|
||||||
|
* date until the task has to be finished
|
||||||
|
*/
|
||||||
|
deadline: string;
|
||||||
|
/**
|
||||||
|
* determines whether the task is overdue
|
||||||
|
*/
|
||||||
|
overdue: boolean;
|
||||||
|
/**
|
||||||
|
* determines whether the task is finished
|
||||||
|
*/
|
||||||
|
finished: boolean;
|
||||||
|
}
|
||||||
|
|
32
frontend/src/api/model/taskFieldInfo.ts
Normal file
32
frontend/src/api/model/taskFieldInfo.ts
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
/**
|
||||||
|
* API Title
|
||||||
|
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||||
|
*
|
||||||
|
* The version of the OpenAPI document: 1.0
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
|
||||||
|
* https://openapi-generator.tech
|
||||||
|
* Do not edit the class manually.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
export interface TaskFieldInfo {
|
||||||
|
/**
|
||||||
|
* name of task
|
||||||
|
*/
|
||||||
|
taskName: string;
|
||||||
|
/**
|
||||||
|
* expected time to finish task
|
||||||
|
*/
|
||||||
|
eta: number;
|
||||||
|
/**
|
||||||
|
* date from which the task can be started
|
||||||
|
*/
|
||||||
|
startDate: string;
|
||||||
|
/**
|
||||||
|
* date until the task has to be finished
|
||||||
|
*/
|
||||||
|
deadline: string;
|
||||||
|
}
|
||||||
|
|
20
frontend/src/api/model/taskgroupDetailInfo.ts
Normal file
20
frontend/src/api/model/taskgroupDetailInfo.ts
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
/**
|
||||||
|
* API Title
|
||||||
|
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||||
|
*
|
||||||
|
* The version of the OpenAPI document: 1.0
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
|
||||||
|
* https://openapi-generator.tech
|
||||||
|
* Do not edit the class manually.
|
||||||
|
*/
|
||||||
|
import { TaskgroupEntityInfo } from './taskgroupEntityInfo';
|
||||||
|
|
||||||
|
|
||||||
|
export interface TaskgroupDetailInfo {
|
||||||
|
children: Array<TaskgroupEntityInfo>;
|
||||||
|
ancestors: Array<TaskgroupEntityInfo>;
|
||||||
|
taskgroupInfo: TaskgroupEntityInfo;
|
||||||
|
}
|
||||||
|
|
@ -20,6 +20,5 @@ export interface TaskgroupEntityInfo {
|
|||||||
* name of taskgroup
|
* name of taskgroup
|
||||||
*/
|
*/
|
||||||
taskgroupName: string;
|
taskgroupName: string;
|
||||||
parentTaskgroup: TaskgroupEntityInfo;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { Component, OnInit } from '@angular/core';
|
import { Component, OnInit } from '@angular/core';
|
||||||
import {PropertiesInfo, PropertiesService, PropertyInfo, UserInfo} from "../../../api";
|
import {PropertiesInfo, PropertiesService, PropertyInfo, UserInfo} from "../../../api";
|
||||||
import {Router} from "@angular/router";
|
import {Router} from "@angular/router";
|
||||||
import {MatSnackBar} from "@angular/material/snack-bar";
|
import {MatLegacySnackBar as MatSnackBar} from "@angular/material/legacy-snack-bar";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-settings',
|
selector: 'app-settings',
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import {Component, Inject, OnInit, Output} from '@angular/core';
|
import {Component, Inject, OnInit, Output} from '@angular/core';
|
||||||
import {MAT_DIALOG_DATA, MatDialogRef} from "@angular/material/dialog";
|
import {MAT_LEGACY_DIALOG_DATA as MAT_DIALOG_DATA, MatLegacyDialogRef as MatDialogRef} from "@angular/material/legacy-dialog";
|
||||||
import {UserInfo, UsersService} from "../../../../api";
|
import {UserInfo, UsersService} from "../../../../api";
|
||||||
import {LoginInfoTypes} from "../../../auth/login/login.component";
|
import {LoginInfoTypes} from "../../../auth/login/login.component";
|
||||||
import {MatSnackBar} from "@angular/material/snack-bar";
|
import {MatLegacySnackBar as MatSnackBar} from "@angular/material/legacy-snack-bar";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-delete-confirmation',
|
selector: 'app-delete-confirmation',
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import {Component, Inject, OnInit} from '@angular/core';
|
import {Component, Inject, OnInit} from '@angular/core';
|
||||||
import {MAT_DIALOG_DATA, MatDialogRef} from "@angular/material/dialog";
|
import {MAT_DIALOG_DATA as MAT_DIALOG_DATA, MatDialogRef as MatDialogRef} from "@angular/material/dialog";
|
||||||
import {UserInfo, UsersService} from "../../../../api";
|
import {UserInfo, UsersService} from "../../../../api";
|
||||||
import {MatSnackBar} from "@angular/material/snack-bar";
|
import {MatSnackBar as MatSnackBar} from "@angular/material/snack-bar";
|
||||||
import {AbstractControl, FormControl, ValidationErrors, Validators} from "@angular/forms";
|
import {AbstractControl, UntypedFormControl, ValidationErrors, Validators} from "@angular/forms";
|
||||||
import {EditData} from "./edit-data";
|
import {EditData} from "./edit-data";
|
||||||
|
|
||||||
|
|
||||||
@ -24,22 +24,22 @@ export class EditComponent implements OnInit {
|
|||||||
|
|
||||||
adminUpdateDisabled: boolean = false;
|
adminUpdateDisabled: boolean = false;
|
||||||
|
|
||||||
usernameFormControl = new FormControl('', [Validators.required, Validators.minLength(3), Validators.maxLength(32)])
|
usernameFormControl = new UntypedFormControl('', [Validators.required, Validators.minLength(3), Validators.maxLength(32)])
|
||||||
emailFormControl = new FormControl('', [Validators.required, Validators.email])
|
emailFormControl = new UntypedFormControl('', [Validators.required, Validators.email])
|
||||||
|
|
||||||
passwordEditControl = new FormControl('', [
|
passwordEditControl = new UntypedFormControl('', [
|
||||||
(control: AbstractControl): ValidationErrors | null => {
|
(control: AbstractControl): ValidationErrors | null => {
|
||||||
return control.value.length > 0 && control.value.length < 6 ? {minlength: {value: control.value}} : null
|
return control.value.length > 0 && control.value.length < 6 ? {minlength: {value: control.value}} : null
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
passwordAddControl = new FormControl('', [Validators.required, Validators.minLength(6)])
|
passwordAddControl = new UntypedFormControl('', [Validators.required, Validators.minLength(6)])
|
||||||
|
|
||||||
passwordDuplicateEditControl = new FormControl('', [
|
passwordDuplicateEditControl = new UntypedFormControl('', [
|
||||||
(control: AbstractControl): ValidationErrors | null => {
|
(control: AbstractControl): ValidationErrors | null => {
|
||||||
return control.value != this.password ? {duplicate: {value: control.value}} : null
|
return control.value != this.password ? {duplicate: {value: control.value}} : null
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
passwordDuplicateAddControl = new FormControl('', [
|
passwordDuplicateAddControl = new UntypedFormControl('', [
|
||||||
Validators.required,
|
Validators.required,
|
||||||
Validators.minLength(6),
|
Validators.minLength(6),
|
||||||
(control: AbstractControl): ValidationErrors | null => {
|
(control: AbstractControl): ValidationErrors | null => {
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
import {ChangeDetectorRef, Component, OnInit} from '@angular/core';
|
import {ChangeDetectorRef, Component, OnInit} from '@angular/core';
|
||||||
import {UserInfo, UsersService} from "../../../api";
|
import {UserInfo, UsersService} from "../../../api";
|
||||||
import {MatDialog} from "@angular/material/dialog";
|
import {MatDialog as MatDialog} from "@angular/material/dialog";
|
||||||
import {LoginComponent} from "../../auth/login/login.component";
|
import {LoginComponent} from "../../auth/login/login.component";
|
||||||
import {DeleteConfirmationComponent} from "./delete-confirmation/delete-confirmation.component";
|
import {DeleteConfirmationComponent} from "./delete-confirmation/delete-confirmation.component";
|
||||||
import {CollectionViewer, DataSource} from "@angular/cdk/collections";
|
import {CollectionViewer, DataSource} from "@angular/cdk/collections";
|
||||||
import {Observable} from "rxjs";
|
import {Observable} from "rxjs";
|
||||||
import {MatTableDataSource} from "@angular/material/table";
|
import {MatTableDataSource as MatTableDataSource} from "@angular/material/table";
|
||||||
import {EditComponent} from "./edit/edit.component";
|
import {EditComponent} from "./edit/edit.component";
|
||||||
import {EditData} from "./edit/edit-data";
|
import {EditData} from "./edit/edit-data";
|
||||||
|
|
||||||
|
@ -9,25 +9,22 @@ import {HttpClient, HttpClientModule, HttpHandler} from "@angular/common/http";
|
|||||||
import {ApiModule, Configuration} from "../api";
|
import {ApiModule, Configuration} from "../api";
|
||||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||||
import {MatToolbarModule} from "@angular/material/toolbar";
|
import {MatToolbarModule} from "@angular/material/toolbar";
|
||||||
import {MatButtonModule} from "@angular/material/button";
|
|
||||||
import {MatIconModule} from "@angular/material/icon";
|
import {MatIconModule} from "@angular/material/icon";
|
||||||
import {MatDialogModule} from "@angular/material/dialog";
|
import {MatDialogModule as MatDialogModule} from "@angular/material/dialog";
|
||||||
import {MatFormFieldModule} from "@angular/material/form-field";
|
import {MatFormFieldModule as MatFormFieldModule} from "@angular/material/form-field";
|
||||||
import {MatInputModule} from "@angular/material/input";
|
import {MatInputModule as MatInputModule} from "@angular/material/input";
|
||||||
import {MatProgressSpinnerModule} from "@angular/material/progress-spinner";
|
import {MatProgressSpinnerModule as MatProgressSpinnerModule} from "@angular/material/progress-spinner";
|
||||||
import {MatSnackBar, MatSnackBarModule} from "@angular/material/snack-bar";
|
import {MatSnackBar as MatSnackBar, MatSnackBarModule as MatSnackBarModule} from "@angular/material/snack-bar";
|
||||||
import {MatMenuModule} from "@angular/material/menu";
|
|
||||||
import { AdminDashboardComponent } from './admin-dashboard/admin-dashboard.component';
|
import { AdminDashboardComponent } from './admin-dashboard/admin-dashboard.component';
|
||||||
import { MainComponent } from './main/main.component';
|
import { MainComponent } from './main/main.component';
|
||||||
import { UsermanagementComponent } from './admin-dashboard/usermanagement/usermanagement.component';
|
import { UsermanagementComponent } from './admin-dashboard/usermanagement/usermanagement.component';
|
||||||
import {MatTabsModule} from "@angular/material/tabs";
|
|
||||||
import {AuthService} from "./auth.service";
|
import {AuthService} from "./auth.service";
|
||||||
import {environment} from "../environments/environment";
|
import {environment} from "../environments/environment";
|
||||||
import {MatTableModule} from "@angular/material/table";
|
|
||||||
import {MatCheckboxModule} from "@angular/material/checkbox";
|
|
||||||
import { DeleteConfirmationComponent } from './admin-dashboard/usermanagement/delete-confirmation/delete-confirmation.component';
|
import { DeleteConfirmationComponent } from './admin-dashboard/usermanagement/delete-confirmation/delete-confirmation.component';
|
||||||
import { EditComponent } from './admin-dashboard/usermanagement/edit/edit.component';
|
import { EditComponent } from './admin-dashboard/usermanagement/edit/edit.component';
|
||||||
import {MatCardModule} from "@angular/material/card";
|
|
||||||
import {UserSettingsComponent} from "./user-settings/user-settings.component";
|
import {UserSettingsComponent} from "./user-settings/user-settings.component";
|
||||||
import {AccountSettingsComponent} from "./user-settings/account-settings/account-settings.component";
|
import {AccountSettingsComponent} from "./user-settings/account-settings/account-settings.component";
|
||||||
import { ChangePasswordComponent } from './user-settings/account-settings/change-password/change-password.component';
|
import { ChangePasswordComponent } from './user-settings/account-settings/change-password/change-password.component';
|
||||||
@ -35,10 +32,27 @@ import { ManageEmailComponent } from './user-settings/account-settings/manage-em
|
|||||||
import { DeleteAccountComponent } from './user-settings/account-settings/delete-account/delete-account.component';
|
import { DeleteAccountComponent } from './user-settings/account-settings/delete-account/delete-account.component';
|
||||||
import { RegistrationComponent } from './auth/registration/registration.component';
|
import { RegistrationComponent } from './auth/registration/registration.component';
|
||||||
import { SettingsComponent } from './admin-dashboard/settings/settings.component';
|
import { SettingsComponent } from './admin-dashboard/settings/settings.component';
|
||||||
import {MatListModule} from "@angular/material/list";
|
|
||||||
import { TaskgroupDashboardComponent } from './taskgroups/taskgroup-dashboard/taskgroup-dashboard.component';
|
import { TaskgroupDashboardComponent } from './taskgroups/taskgroup-dashboard/taskgroup-dashboard.component';
|
||||||
import { TaskgroupCreationComponent } from './taskgroups/taskgroup-creation/taskgroup-creation.component';
|
import { TaskgroupCreationComponent } from './taskgroups/taskgroup-creation/taskgroup-creation.component';
|
||||||
import { TaskgroupDeletionComponent } from './taskgroups/taskgroup-deletion/taskgroup-deletion.component';
|
import { TaskgroupDeletionComponent } from './taskgroups/taskgroup-deletion/taskgroup-deletion.component';
|
||||||
|
import { TaskEditorComponent } from './tasks/task-editor/task-editor.component';
|
||||||
|
import {MatDatepickerModule} from "@angular/material/datepicker";
|
||||||
|
import {MatButtonModule} from "@angular/material/button";
|
||||||
|
import {MatMenuModule} from "@angular/material/menu";
|
||||||
|
import {MatTabsModule} from "@angular/material/tabs";
|
||||||
|
import {MatTableModule} from "@angular/material/table";
|
||||||
|
import {MatCheckboxModule} from "@angular/material/checkbox";
|
||||||
|
import {MatCardModule} from "@angular/material/card";
|
||||||
|
import {MatListModule} from "@angular/material/list";
|
||||||
|
import {DateAdapter, MAT_DATE_FORMATS, MAT_DATE_LOCALE, MatNativeDateModule} from "@angular/material/core";
|
||||||
|
import {MatMomentDateModule, MomentDateModule} from "@angular/material-moment-adapter";
|
||||||
|
import { TaskDashboardComponent } from './tasks/task-dashboard/task-dashboard.component';
|
||||||
|
import {MatSlideToggleModule} from "@angular/material/slide-toggle";
|
||||||
|
import {MatSortModule} from "@angular/material/sort";
|
||||||
|
import {MatPaginatorModule} from "@angular/material/paginator";
|
||||||
|
import { ClearTaskDialogComponent } from './tasks/clear-task-dialog/clear-task-dialog.component';
|
||||||
|
import { NavigationLinkListComponent } from './navigation-link-list/navigation-link-list.component';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [
|
declarations: [
|
||||||
@ -58,7 +72,11 @@ import { TaskgroupDeletionComponent } from './taskgroups/taskgroup-deletion/task
|
|||||||
SettingsComponent,
|
SettingsComponent,
|
||||||
TaskgroupDashboardComponent,
|
TaskgroupDashboardComponent,
|
||||||
TaskgroupCreationComponent,
|
TaskgroupCreationComponent,
|
||||||
TaskgroupDeletionComponent
|
TaskgroupDeletionComponent,
|
||||||
|
TaskEditorComponent,
|
||||||
|
TaskDashboardComponent,
|
||||||
|
ClearTaskDialogComponent,
|
||||||
|
NavigationLinkListComponent
|
||||||
],
|
],
|
||||||
imports: [
|
imports: [
|
||||||
BrowserModule,
|
BrowserModule,
|
||||||
@ -81,7 +99,15 @@ import { TaskgroupDeletionComponent } from './taskgroups/taskgroup-deletion/task
|
|||||||
MatCheckboxModule,
|
MatCheckboxModule,
|
||||||
MatCardModule,
|
MatCardModule,
|
||||||
ReactiveFormsModule,
|
ReactiveFormsModule,
|
||||||
MatListModule
|
MatListModule,
|
||||||
|
MatDatepickerModule,
|
||||||
|
MatInputModule,
|
||||||
|
MatDatepickerModule,
|
||||||
|
MatMomentDateModule,
|
||||||
|
FormsModule,
|
||||||
|
MatSlideToggleModule,
|
||||||
|
MatSortModule,
|
||||||
|
MatPaginatorModule
|
||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
HttpClientModule,
|
HttpClientModule,
|
||||||
@ -108,8 +134,7 @@ import { TaskgroupDeletionComponent } from './taskgroups/taskgroup-deletion/task
|
|||||||
),
|
),
|
||||||
deps: [AuthService],
|
deps: [AuthService],
|
||||||
multi: false
|
multi: false
|
||||||
}
|
},
|
||||||
|
|
||||||
],
|
],
|
||||||
bootstrap: [AppComponent]
|
bootstrap: [AppComponent]
|
||||||
})
|
})
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import {Component, Inject, OnInit} from '@angular/core';
|
import {Component, Inject, OnInit} from '@angular/core';
|
||||||
import {LoginService, PropertiesService} from "../../../api";
|
import {LoginService, PropertiesService} from "../../../api";
|
||||||
import {MAT_DIALOG_DATA, MatDialog, MatDialogRef} from "@angular/material/dialog";
|
import {MAT_DIALOG_DATA as MAT_DIALOG_DATA, MatDialog as MatDialog, MatDialogRef as MatDialogRef} from "@angular/material/dialog";
|
||||||
import {Router} from "@angular/router";
|
import {Router} from "@angular/router";
|
||||||
import {MatSnackBar} from "@angular/material/snack-bar";
|
import {MatSnackBar as MatSnackBar} from "@angular/material/snack-bar";
|
||||||
import {AuthService} from "../../auth.service";
|
import {AuthService} from "../../auth.service";
|
||||||
import {RegistrationComponent} from "../registration/registration.component";
|
import {RegistrationComponent} from "../registration/registration.component";
|
||||||
|
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
import { Component, OnInit } from '@angular/core';
|
import { Component, OnInit } from '@angular/core';
|
||||||
import {MatDialog, MatDialogRef} from "@angular/material/dialog";
|
import {MatDialog as MatDialog, MatDialogRef as MatDialogRef} from "@angular/material/dialog";
|
||||||
import {LoginService} from "../../../api";
|
import {LoginService} from "../../../api";
|
||||||
import {Router} from "@angular/router";
|
import {Router} from "@angular/router";
|
||||||
import {MatSnackBar} from "@angular/material/snack-bar";
|
import {MatSnackBar as MatSnackBar} from "@angular/material/snack-bar";
|
||||||
import {AuthService} from "../../auth.service";
|
import {AuthService} from "../../auth.service";
|
||||||
import {LoginComponent} from "../login/login.component";
|
import {LoginComponent} from "../login/login.component";
|
||||||
import {LoginDialogServiceService} from "../../login-dialog-service.service";
|
import {LoginDialogServiceService} from "../../login-dialog-service.service";
|
||||||
import {AbstractControl, FormControl, ValidationErrors, Validators} from "@angular/forms";
|
import {AbstractControl, UntypedFormControl, ValidationErrors, Validators} from "@angular/forms";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-registration',
|
selector: 'app-registration',
|
||||||
@ -23,10 +23,10 @@ export class RegistrationComponent implements OnInit {
|
|||||||
pending: boolean = false;
|
pending: boolean = false;
|
||||||
isAuth: boolean = false;
|
isAuth: boolean = false;
|
||||||
|
|
||||||
usernameControl = new FormControl('', [Validators.required, Validators.minLength(3)]);
|
usernameControl = new UntypedFormControl('', [Validators.required, Validators.minLength(3)]);
|
||||||
emailControl = new FormControl('', [Validators.required, Validators.email])
|
emailControl = new UntypedFormControl('', [Validators.required, Validators.email])
|
||||||
passwordControl = new FormControl('', [Validators.required, Validators.minLength(6)]);
|
passwordControl = new UntypedFormControl('', [Validators.required, Validators.minLength(6)]);
|
||||||
passwordDuplicateControl = new FormControl('', [
|
passwordDuplicateControl = new UntypedFormControl('', [
|
||||||
Validators.required,
|
Validators.required,
|
||||||
Validators.minLength(6),
|
Validators.minLength(6),
|
||||||
(control: AbstractControl): ValidationErrors | null => {
|
(control: AbstractControl): ValidationErrors | null => {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import {MatDialog} from "@angular/material/dialog";
|
import {MatDialog as MatDialog} from "@angular/material/dialog";
|
||||||
import {LoginComponent, LoginInfoTypes} from "./auth/login/login.component";
|
import {LoginComponent, LoginInfoTypes} from "./auth/login/login.component";
|
||||||
import {Observable} from "rxjs";
|
import {Observable} from "rxjs";
|
||||||
|
|
||||||
|
@ -0,0 +1,23 @@
|
|||||||
|
|
||||||
|
.navLink {
|
||||||
|
text-decoration: underline;
|
||||||
|
color: black;
|
||||||
|
margin-right: 5px;
|
||||||
|
margin-left: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navLink-disabled {
|
||||||
|
text-decoration: none;
|
||||||
|
color: grey;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.navLink-bar {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.link-separation {
|
||||||
|
text-decoration: none;
|
||||||
|
padding-right: 5px;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,8 @@
|
|||||||
|
<mat-card class="navLink-bar">
|
||||||
|
<mat-card-content>
|
||||||
|
<span *ngFor="let navigationLink of navigationLinks; index as i">
|
||||||
|
<span class="link-seperation" *ngIf="i !== 0">/</span>
|
||||||
|
<a class="navLink" [routerLink]="navigationLink.routerLink" [class.navLink-disabled]="i == navigationLinks.length-1">{{navigationLink.linkText}}</a>
|
||||||
|
</span>
|
||||||
|
</mat-card-content>
|
||||||
|
</mat-card>
|
@ -0,0 +1,21 @@
|
|||||||
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { NavigationLinkListComponent } from './navigation-link-list.component';
|
||||||
|
|
||||||
|
describe('NavigationLinkListComponent', () => {
|
||||||
|
let component: NavigationLinkListComponent;
|
||||||
|
let fixture: ComponentFixture<NavigationLinkListComponent>;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [NavigationLinkListComponent]
|
||||||
|
});
|
||||||
|
fixture = TestBed.createComponent(NavigationLinkListComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
@ -0,0 +1,40 @@
|
|||||||
|
import {Component, Input, OnInit} from '@angular/core';
|
||||||
|
|
||||||
|
export interface NavigationLink {
|
||||||
|
routerLink: string[],
|
||||||
|
linkText: string
|
||||||
|
}
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-navigation-link-list',
|
||||||
|
templateUrl: './navigation-link-list.component.html',
|
||||||
|
styleUrls: ['./navigation-link-list.component.css']
|
||||||
|
})
|
||||||
|
export class NavigationLinkListComponent implements OnInit{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Input() navigationLinks: NavigationLink[] = []
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
addNavigationLink(linkText: string, link: string[]) {
|
||||||
|
const navigationLink: NavigationLink = {
|
||||||
|
linkText: linkText,
|
||||||
|
routerLink: link
|
||||||
|
}
|
||||||
|
|
||||||
|
if(this.navigationLinks.find(searchedLink => searchedLink.linkText === linkText) === undefined) {
|
||||||
|
this.navigationLinks.push(navigationLink);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
removeLink(linkText: string) {
|
||||||
|
this.navigationLinks = this.navigationLinks.filter(link => link.linkText === linkText);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -1,12 +1,11 @@
|
|||||||
import {Component, Inject, OnInit} from '@angular/core';
|
import {Component, Inject, OnInit} from '@angular/core';
|
||||||
import {FormControl, Validators} from "@angular/forms";
|
import {UntypedFormControl, Validators} from "@angular/forms";
|
||||||
import {MAT_DIALOG_DATA, MatDialogRef} from "@angular/material/dialog";
|
import {MAT_DIALOG_DATA as MAT_DIALOG_DATA, MatDialogRef as MatDialogRef} from "@angular/material/dialog";
|
||||||
import {TaskgroupEntityInfo, TaskgroupService} from "../../../api";
|
import {TaskgroupService} from "../../../api";
|
||||||
import {error} from "@angular/compiler/src/util";
|
import {MatSnackBar as MatSnackBar} from "@angular/material/snack-bar";
|
||||||
import {MatSnackBar} from "@angular/material/snack-bar";
|
|
||||||
import {ActivatedRoute} from "@angular/router";
|
|
||||||
import {TaskgroupCreationData} from "./TaskgroupCreationData";
|
import {TaskgroupCreationData} from "./TaskgroupCreationData";
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-taskgroup-creation',
|
selector: 'app-taskgroup-creation',
|
||||||
templateUrl: './taskgroup-creation.component.html',
|
templateUrl: './taskgroup-creation.component.html',
|
||||||
@ -14,7 +13,7 @@ import {TaskgroupCreationData} from "./TaskgroupCreationData";
|
|||||||
})
|
})
|
||||||
export class TaskgroupCreationComponent implements OnInit {
|
export class TaskgroupCreationComponent implements OnInit {
|
||||||
|
|
||||||
nameCtrl = new FormControl('', [Validators.required, Validators.maxLength(255)])
|
nameCtrl = new UntypedFormControl('', [Validators.required, Validators.maxLength(255)])
|
||||||
pending: boolean = false
|
pending: boolean = false
|
||||||
|
|
||||||
constructor(private dialogRef: MatDialogRef<TaskgroupCreationComponent>,
|
constructor(private dialogRef: MatDialogRef<TaskgroupCreationComponent>,
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
.container {
|
.container {
|
||||||
margin: 20px auto;
|
margin: 20px auto;
|
||||||
width: 60%;
|
width: 70%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.spacer {
|
.spacer {
|
||||||
@ -15,27 +15,23 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.navLink {
|
|
||||||
text-decoration: underline;
|
|
||||||
color: black;
|
|
||||||
margin-right: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.navLink-disabled {
|
|
||||||
text-decoration: none;
|
|
||||||
color: grey;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
.navLink-bar {
|
|
||||||
margin-bottom: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#addTaskgroupBtn {
|
#addTaskgroupBtn {
|
||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
#addTaskBtn {
|
||||||
|
margin-top: 20px;
|
||||||
|
float: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
.edit-btn {
|
.edit-btn {
|
||||||
background-color: #6e6e6e;
|
background-color: #6e6e6e;
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#task-dashboard-container {
|
||||||
|
width: 100%;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -1,10 +1,5 @@
|
|||||||
<div class="container">
|
<div class="container">
|
||||||
<mat-card class="navLink-bar">
|
<app-navigation-link-list #navLinkList [navigationLinks]="defaultNavigationLinkPath"></app-navigation-link-list>
|
||||||
<mat-card-content>
|
|
||||||
<a class="navLink" routerLink="/">Dashboard</a>
|
|
||||||
<a class="navLink-disabled">/ Taskgroups</a>
|
|
||||||
</mat-card-content>
|
|
||||||
</mat-card>
|
|
||||||
|
|
||||||
<mat-card *ngFor="let taskgroup of taskgroups">
|
<mat-card *ngFor="let taskgroup of taskgroups">
|
||||||
<mat-card-content>
|
<mat-card-content>
|
||||||
@ -15,5 +10,16 @@
|
|||||||
</mat-card-content>
|
</mat-card-content>
|
||||||
|
|
||||||
</mat-card>
|
</mat-card>
|
||||||
<button id="addTaskgroupBtn" mat-raised-button color="primary" (click)="openTaskgroupCreation()">Create new Taskgroup</button>
|
|
||||||
|
<mat-card style="width: 100%" *ngIf="taskgroupID >= 0">
|
||||||
|
<mat-card-content>
|
||||||
|
<app-task-dashboard #taskDashboard [taskgroupID]="taskgroupID"></app-task-dashboard>
|
||||||
|
</mat-card-content>
|
||||||
|
</mat-card>
|
||||||
|
<div style="width: 100%">
|
||||||
|
<button id="addTaskBtn" *ngIf="taskgroupID >= 0" mat-raised-button color="primary" (click)="openTaskCreation()">Create New Task</button>
|
||||||
|
<button id="addTaskgroupBtn" mat-raised-button color="primary" (click)="openTaskgroupCreation()">Create new Taskgroup</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,9 +1,13 @@
|
|||||||
import { Component, OnInit } from '@angular/core';
|
import {Component, OnInit, ViewChild} from '@angular/core';
|
||||||
import {MatDialog} from "@angular/material/dialog";
|
import {MatDialog as MatDialog} from "@angular/material/dialog";
|
||||||
import {TaskgroupCreationComponent} from "../taskgroup-creation/taskgroup-creation.component";
|
import {TaskgroupCreationComponent} from "../taskgroup-creation/taskgroup-creation.component";
|
||||||
import {TaskgroupEntityInfo, TaskgroupService} from "../../../api";
|
import {TaskgroupEntityInfo, TaskgroupService} from "../../../api";
|
||||||
import {TaskgroupDeletionComponent} from "../taskgroup-deletion/taskgroup-deletion.component";
|
import {TaskgroupDeletionComponent} from "../taskgroup-deletion/taskgroup-deletion.component";
|
||||||
import {ActivatedRoute} from "@angular/router";
|
import {ActivatedRoute} from "@angular/router";
|
||||||
|
import {TaskEditorComponent} from "../../tasks/task-editor/task-editor.component";
|
||||||
|
import {TaskEditorData} from "../../tasks/task-editor/TaskEditorData";
|
||||||
|
import {TaskDashboardComponent} from "../../tasks/task-dashboard/task-dashboard.component";
|
||||||
|
import {NavigationLink, NavigationLinkListComponent} from "../../navigation-link-list/navigation-link-list.component";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-taskgroup-dashboard',
|
selector: 'app-taskgroup-dashboard',
|
||||||
@ -17,7 +21,21 @@ export class TaskgroupDashboardComponent implements OnInit {
|
|||||||
private activatedRoute: ActivatedRoute) { }
|
private activatedRoute: ActivatedRoute) { }
|
||||||
|
|
||||||
taskgroups: TaskgroupEntityInfo[] = []
|
taskgroups: TaskgroupEntityInfo[] = []
|
||||||
|
taskgroup: TaskgroupEntityInfo | undefined
|
||||||
|
taskgroupPath: TaskgroupEntityInfo[] = []
|
||||||
taskgroupID: number = -1;
|
taskgroupID: number = -1;
|
||||||
|
@ViewChild("taskDashboard") taskDashboard: TaskDashboardComponent | undefined
|
||||||
|
@ViewChild('navLinkList') navLinkListComponent: NavigationLinkListComponent | undefined
|
||||||
|
defaultNavigationLinkPath: NavigationLink[] = [
|
||||||
|
{
|
||||||
|
linkText: "Dashboard",
|
||||||
|
routerLink: ['/']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
linkText: "Taskgroups",
|
||||||
|
routerLink: ["/taskgroups"]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.activatedRoute.paramMap.subscribe(params => {
|
this.activatedRoute.paramMap.subscribe(params => {
|
||||||
@ -25,7 +43,13 @@ export class TaskgroupDashboardComponent implements OnInit {
|
|||||||
this.taskgroupID = Number(params.get('taskgroupID'));
|
this.taskgroupID = Number(params.get('taskgroupID'));
|
||||||
this.taskgroupService.taskgroupsTaskgroupIDGet(this.taskgroupID).subscribe({
|
this.taskgroupService.taskgroupsTaskgroupIDGet(this.taskgroupID).subscribe({
|
||||||
next: resp => {
|
next: resp => {
|
||||||
this.taskgroups = resp
|
this.taskgroups = resp.children
|
||||||
|
this.taskgroupPath = resp.ancestors
|
||||||
|
this.taskgroup = resp.taskgroupInfo;
|
||||||
|
this.navLinkListComponent!.addNavigationLink(this.taskgroup.taskgroupName, ['/taskgroups', this.taskgroup.taskgroupID.toString()])
|
||||||
|
this.taskgroupPath.forEach(taskgroupEntity => {
|
||||||
|
this.navLinkListComponent!.addNavigationLink(taskgroupEntity.taskgroupName, ['/taskgroups', taskgroupEntity.taskgroupID.toString()]);
|
||||||
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
@ -65,4 +89,17 @@ export class TaskgroupDashboardComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
openTaskCreation() {
|
||||||
|
const editorData: TaskEditorData = {
|
||||||
|
task: undefined,
|
||||||
|
taskgroupID: this.taskgroupID
|
||||||
|
}
|
||||||
|
const dialogRef = this.dialog.open(TaskEditorComponent, {data: editorData, width: "600px"})
|
||||||
|
dialogRef.afterClosed().subscribe(res => {
|
||||||
|
if(res != undefined) {
|
||||||
|
this.taskDashboard!.addTask(res);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import {Component, Inject, OnInit} from '@angular/core';
|
import {Component, Inject, OnInit} from '@angular/core';
|
||||||
import {MAT_DIALOG_DATA, MatDialogRef} from "@angular/material/dialog";
|
import {MAT_DIALOG_DATA as MAT_DIALOG_DATA, MatDialogRef as MatDialogRef} from "@angular/material/dialog";
|
||||||
import {TaskgroupEntityInfo, TaskgroupService} from "../../../api";
|
import {TaskgroupEntityInfo, TaskgroupService} from "../../../api";
|
||||||
import {MatSnackBar} from "@angular/material/snack-bar";
|
import {MatSnackBar as MatSnackBar} from "@angular/material/snack-bar";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-taskgroup-deletion',
|
selector: 'app-taskgroup-deletion',
|
||||||
|
@ -0,0 +1,3 @@
|
|||||||
|
.deleteSetttings {
|
||||||
|
margin-right: 20px;
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
<h1 mat-dialog-title>Clear Tasks ({{editorData.taskgroupID}})</h1>
|
||||||
|
<div mat-dialog-content>
|
||||||
|
<p>Are you sure you want to clear the Tasks? This <b>cannot</b> be <b>undone!</b></p>
|
||||||
|
<mat-slide-toggle class="deleteSetttings">Finished Tasks <b>( {{finishedTasks}}Tasks)</b></mat-slide-toggle>
|
||||||
|
<mat-slide-toggle class="deleteSetttings">Overdue Tasks <b>({{overdueTasks}} Tasks)</b></mat-slide-toggle>
|
||||||
|
<mat-slide-toggle class="deleteSetttings">Unfinished Tasks <b>( {{unfinishedTasks}}Tasks)</b></mat-slide-toggle>
|
||||||
|
<mat-slide-toggle class="deleteSetttings">Upcoming Tasks <b>({{upcomingTasks}} Tasks)</b></mat-slide-toggle>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div mat-dialog-actions align="end">
|
||||||
|
<button mat-raised-button (click)="cancel()">Cancel</button>
|
||||||
|
<button mat-raised-button color="warn" (click)="clearTasks()"><mat-icon>delete</mat-icon>Clear</button>
|
||||||
|
</div>
|
@ -0,0 +1,21 @@
|
|||||||
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { ClearTaskDialogComponent } from './clear-task-dialog.component';
|
||||||
|
|
||||||
|
describe('ClearTaskDialogComponent', () => {
|
||||||
|
let component: ClearTaskDialogComponent;
|
||||||
|
let fixture: ComponentFixture<ClearTaskDialogComponent>;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ClearTaskDialogComponent]
|
||||||
|
});
|
||||||
|
fixture = TestBed.createComponent(ClearTaskDialogComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
@ -0,0 +1,69 @@
|
|||||||
|
import {Component, Inject, OnInit} from '@angular/core';
|
||||||
|
import {TaskEditorData} from "../task-editor/TaskEditorData";
|
||||||
|
import {TaskEntityInfo, TaskgroupService} from "../../../api";
|
||||||
|
import {MAT_DIALOG_DATA, MatDialogRef} from "@angular/material/dialog";
|
||||||
|
import {MatSnackBar} from "@angular/material/snack-bar";
|
||||||
|
|
||||||
|
export interface ClearTaskDialogData {
|
||||||
|
taskgroupID: number,
|
||||||
|
tasks: TaskEntityInfo[]
|
||||||
|
}
|
||||||
|
@Component({
|
||||||
|
selector: 'app-clear-task-dialog',
|
||||||
|
templateUrl: './clear-task-dialog.component.html',
|
||||||
|
styleUrls: ['./clear-task-dialog.component.css']
|
||||||
|
})
|
||||||
|
export class ClearTaskDialogComponent implements OnInit{
|
||||||
|
|
||||||
|
finishedTasks: number = 0;
|
||||||
|
unfinishedTasks: number = 0;
|
||||||
|
overdueTasks: number = 0;
|
||||||
|
upcomingTasks: number = 0;
|
||||||
|
|
||||||
|
constructor(@Inject(MAT_DIALOG_DATA) public editorData: ClearTaskDialogData,
|
||||||
|
private taskgroupService: TaskgroupService,
|
||||||
|
private dialogRef: MatDialogRef<ClearTaskDialogComponent>,
|
||||||
|
private snackbar: MatSnackBar) {
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
this.editorData.tasks.forEach(task => {
|
||||||
|
if(task.overdue) {
|
||||||
|
this.overdueTasks +=1;
|
||||||
|
} else {
|
||||||
|
this.upcomingTasks += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(task.finished) {
|
||||||
|
this.finishedTasks += 1;
|
||||||
|
} else {
|
||||||
|
this.unfinishedTasks += 1;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
cancel() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
clearTasks() {
|
||||||
|
this.taskgroupService.taskgroupsTaskgroupIDClearDelete(this.editorData.taskgroupID).subscribe({
|
||||||
|
next: resp => {
|
||||||
|
if(resp.status == "success") {
|
||||||
|
const deletedTasks = this.editorData.tasks;
|
||||||
|
this.dialogRef.close(deletedTasks);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error: err => {
|
||||||
|
if(err.status == 403) {
|
||||||
|
this.snackbar.open("No permission", "", {duration: 2000});
|
||||||
|
} else if(err.status == 404) {
|
||||||
|
this.snackbar.open("Not found", "", {duration: 2000});
|
||||||
|
} else {
|
||||||
|
this.snackbar.open("Unexpected error", "", {duration: 2000});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
|
||||||
|
|
||||||
|
mat-form-field {
|
||||||
|
width: 80%;
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
td, th {
|
||||||
|
width: 25%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-indicator {
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
border-radius: 50%;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mat-column-status, .mat-column-eta {
|
||||||
|
width: 32px;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mat-column-edit, .mat-column-delete, .mat-column-finished {
|
||||||
|
width: 32px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#clear-tasks-btn {
|
||||||
|
float: right;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
@ -0,0 +1,61 @@
|
|||||||
|
<mat-form-field appearance="fill">
|
||||||
|
<mat-label>Search</mat-label>
|
||||||
|
<input matInput (keyup)="applyFilter($event)" placeholder="Search for Taskname" #input>
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
<!--<mat-slide-toggle style="margin-left: 20px">Show finished tasks</mat-slide-toggle>-->
|
||||||
|
<button id="clear-tasks-btn" (click)="clearTasks()" mat-raised-button color="warn"><mat-icon>delete</mat-icon>Clear Tasks</button>
|
||||||
|
|
||||||
|
<div class="mat-elevation-z8">
|
||||||
|
<table mat-table [dataSource]="datasource" matSort>
|
||||||
|
<ng-container matColumnDef="name">
|
||||||
|
<th mat-header-cell *matHeaderCellDef mat-sort-header> Name </th>
|
||||||
|
<td mat-cell *matCellDef="let task"> {{task.taskName}} </td>
|
||||||
|
</ng-container>
|
||||||
|
<ng-container matColumnDef="eta">
|
||||||
|
<th mat-header-cell *matHeaderCellDef mat-sort-header> ETA </th>
|
||||||
|
<td mat-cell *matCellDef="let task"> {{task.eta}} </td>
|
||||||
|
</ng-container>
|
||||||
|
<ng-container matColumnDef="start">
|
||||||
|
<th mat-header-cell *matHeaderCellDef mat-sort-header> Start </th>
|
||||||
|
<td mat-cell *matCellDef="let task"> {{task.startDate}} </td>
|
||||||
|
</ng-container>
|
||||||
|
<ng-container matColumnDef="deadline">
|
||||||
|
<th mat-header-cell *matHeaderCellDef mat-sort-header> Deadline </th>
|
||||||
|
<td mat-cell *matCellDef="let task"> {{task.deadline}} </td>
|
||||||
|
</ng-container>
|
||||||
|
<ng-container matColumnDef="finished">
|
||||||
|
<th mat-header-cell *matHeaderCellDef mat-sort-header> Finished </th>
|
||||||
|
<td mat-cell *matCellDef="let task">
|
||||||
|
<mat-checkbox [value]="task.finished" [contentEditable]="false" disableRipple="true" (click)="$event.preventDefault()"></mat-checkbox>
|
||||||
|
</td>
|
||||||
|
</ng-container>
|
||||||
|
<ng-container matColumnDef="status">
|
||||||
|
<th mat-header-cell *matHeaderCellDef mat-sort-header> Status </th>
|
||||||
|
<td mat-cell *matCellDef="let task">
|
||||||
|
<div class="status-indicator" [style.background-color]="getStatusOfTask(task)"></div>
|
||||||
|
</td>
|
||||||
|
</ng-container>
|
||||||
|
<ng-container matColumnDef="edit">
|
||||||
|
<th mat-header-cell *matHeaderCellDef mat-sort-header></th>
|
||||||
|
<td mat-cell *matCellDef="let task">
|
||||||
|
<button mat-icon-button color="primary" (click)="editTask(task)"><mat-icon>edit</mat-icon></button>
|
||||||
|
</td>
|
||||||
|
</ng-container>
|
||||||
|
<ng-container matColumnDef="delete">
|
||||||
|
<th mat-header-cell *matHeaderCellDef mat-sort-header></th>
|
||||||
|
<td mat-cell *matCellDef="let task">
|
||||||
|
<button mat-icon-button color="warn" (click)="deleteTask(task)"><mat-icon>delete</mat-icon></button>
|
||||||
|
</td>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
|
|
||||||
|
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||||
|
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
|
||||||
|
<!-- Row shown when there is no matching data. -->
|
||||||
|
<tr class="mat-row" *matNoDataRow>
|
||||||
|
<td class="mat-cell" colspan="4">No data matching the filter "{{input.value}}"</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<mat-paginator [pageSizeOptions]="[5, 10, 25, 100]" aria-label="Select page of users"></mat-paginator>
|
||||||
|
</div>
|
@ -0,0 +1,21 @@
|
|||||||
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { TaskDashboardComponent } from './task-dashboard.component';
|
||||||
|
|
||||||
|
describe('TaskDashboardComponent', () => {
|
||||||
|
let component: TaskDashboardComponent;
|
||||||
|
let fixture: ComponentFixture<TaskDashboardComponent>;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [TaskDashboardComponent]
|
||||||
|
});
|
||||||
|
fixture = TestBed.createComponent(TaskDashboardComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
@ -0,0 +1,102 @@
|
|||||||
|
import {Component, Input, OnChanges, ViewChild} from '@angular/core';
|
||||||
|
import {TaskEntityInfo, TaskService} from "../../../api";
|
||||||
|
import {MatPaginator} from "@angular/material/paginator";
|
||||||
|
import {MatSort} from "@angular/material/sort";
|
||||||
|
import {MatTableDataSource} from "@angular/material/table";
|
||||||
|
import {TaskEditorComponent} from "../task-editor/task-editor.component";
|
||||||
|
import {TaskEditorData} from "../task-editor/TaskEditorData";
|
||||||
|
import {MatDialog} from "@angular/material/dialog";
|
||||||
|
import {MatSnackBar} from "@angular/material/snack-bar";
|
||||||
|
import {ClearTaskDialogComponent, ClearTaskDialogData} from "../clear-task-dialog/clear-task-dialog.component";
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-task-dashboard',
|
||||||
|
templateUrl: './task-dashboard.component.html',
|
||||||
|
styleUrls: ['./task-dashboard.component.css']
|
||||||
|
})
|
||||||
|
export class TaskDashboardComponent implements OnChanges{
|
||||||
|
ngOnChanges(): void {
|
||||||
|
if(this.taskgroupID != undefined) {
|
||||||
|
this.taskService.tasksTaskgroupIDStatusGet(this.taskgroupID!, "all").subscribe({
|
||||||
|
next: resp => {
|
||||||
|
this.datasource = new MatTableDataSource<TaskEntityInfo>(resp);
|
||||||
|
this.datasource.paginator = this.paginator!;
|
||||||
|
this.datasource.sort = this.sort!;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Input("taskgroupID") taskgroupID: number | undefined
|
||||||
|
@ViewChild(MatPaginator) paginator: MatPaginator | undefined
|
||||||
|
@ViewChild(MatSort) sort: MatSort | undefined
|
||||||
|
|
||||||
|
displayedColumns: string[] = ['status', 'name', 'eta', 'start', 'deadline', 'finished', 'edit', 'delete'];
|
||||||
|
datasource: MatTableDataSource<TaskEntityInfo> = new MatTableDataSource<TaskEntityInfo>();
|
||||||
|
|
||||||
|
constructor(private taskService: TaskService,
|
||||||
|
private dialog: MatDialog,
|
||||||
|
private snackbar: MatSnackBar) {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
applyFilter(event: Event) {
|
||||||
|
const filterValue = (event.target as HTMLInputElement).value;
|
||||||
|
this.datasource.filter = filterValue.trim().toLowerCase();
|
||||||
|
|
||||||
|
if (this.datasource.paginator) {
|
||||||
|
this.datasource.paginator.firstPage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getStatusOfTask(task: TaskEntityInfo) {
|
||||||
|
return "green";
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteTask(deletedTask: TaskEntityInfo) {
|
||||||
|
this.taskService.tasksTaskIDDelete(deletedTask.taskID).subscribe({
|
||||||
|
next: resp => {
|
||||||
|
if(resp.status == "success") {
|
||||||
|
this.datasource.data = this.datasource.data.filter(task => task.taskID !== deletedTask.taskID);
|
||||||
|
} else {
|
||||||
|
this.snackbar.open("Unexpected behavior", "", {duration: 2000});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error: err => {
|
||||||
|
if(err.status == 403) {
|
||||||
|
this.snackbar.open("No permission", "", {duration: 2000});
|
||||||
|
} else if(err.status == 404) {
|
||||||
|
this.snackbar.open("Task not found", "", {duration: 2000});
|
||||||
|
} else {
|
||||||
|
this.snackbar.open("Unexpected error", "", {duration: 2000});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
editTask(task: TaskEntityInfo) {
|
||||||
|
const taskEditorInfo: TaskEditorData = {
|
||||||
|
task: task,
|
||||||
|
taskgroupID: this.taskgroupID!
|
||||||
|
};
|
||||||
|
const dialogRef = this.dialog.open(TaskEditorComponent, {data: taskEditorInfo, minWidth: "400px"})
|
||||||
|
}
|
||||||
|
|
||||||
|
clearTasks() {
|
||||||
|
const clearTaskData: ClearTaskDialogData = {
|
||||||
|
tasks: this.datasource.data,
|
||||||
|
taskgroupID: this.taskgroupID!
|
||||||
|
}
|
||||||
|
const dialogRef = this.dialog.open(ClearTaskDialogComponent, {data: clearTaskData, width: "600px"});
|
||||||
|
dialogRef.afterClosed().subscribe(res => {
|
||||||
|
if(res != undefined) {
|
||||||
|
this.datasource.data = this.datasource.data.filter(task => !res.includes(task));
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
addTask(task: TaskEntityInfo) {
|
||||||
|
const data = this.datasource.data;
|
||||||
|
data.push(task)
|
||||||
|
this.datasource.data = data;
|
||||||
|
}
|
||||||
|
}
|
6
frontend/src/app/tasks/task-editor/TaskEditorData.ts
Normal file
6
frontend/src/app/tasks/task-editor/TaskEditorData.ts
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
import {TaskEntityInfo} from "../../../api";
|
||||||
|
|
||||||
|
export interface TaskEditorData {
|
||||||
|
taskgroupID: number;
|
||||||
|
task: TaskEntityInfo | undefined
|
||||||
|
}
|
15
frontend/src/app/tasks/task-editor/task-editor.component.css
Normal file
15
frontend/src/app/tasks/task-editor/task-editor.component.css
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
.long-form {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.date-form {
|
||||||
|
width: 49%;
|
||||||
|
}
|
||||||
|
#startDate {
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endDate {
|
||||||
|
float: right;
|
||||||
|
}
|
@ -0,0 +1,32 @@
|
|||||||
|
<h1 mat-dialog-title *ngIf="editorData.task != undefined">Edit Task ({{editorData.task!.taskName}})</h1>
|
||||||
|
<h1 mat-dialog-title *ngIf="editorData.task == undefined">Create New Task</h1>
|
||||||
|
<div mat-dialog-content>
|
||||||
|
<mat-form-field appearance="outline" class="long-form">
|
||||||
|
<mat-label>Name</mat-label>
|
||||||
|
<input matInput [formControl]="nameCtrl">
|
||||||
|
<mat-hint align="end">{{nameCtrl.value.length}} / 255</mat-hint>
|
||||||
|
</mat-form-field>
|
||||||
|
<mat-form-field appearance="outline" class="long-form">
|
||||||
|
<mat-label>ETA</mat-label>
|
||||||
|
<input matInput type="number" [formControl]="etaCtrl" min="0">
|
||||||
|
</mat-form-field>
|
||||||
|
<mat-form-field class="date-form" id="startDate">
|
||||||
|
<mat-label>Startdate</mat-label>
|
||||||
|
<input matInput [matDatepicker]="startpicker" [formControl]="startDate">
|
||||||
|
<mat-hint>MM/DD/YYYY</mat-hint>
|
||||||
|
<mat-datepicker-toggle matIconSuffix [for]="startpicker"></mat-datepicker-toggle>
|
||||||
|
<mat-datepicker #startpicker></mat-datepicker>
|
||||||
|
</mat-form-field>
|
||||||
|
<mat-form-field class="date-form" id="endDate">
|
||||||
|
<mat-label>Deadline</mat-label>
|
||||||
|
<input matInput [matDatepicker]="deadlinepicker" [formControl]="endDate">
|
||||||
|
<mat-hint>MM/DD/YYYY</mat-hint>
|
||||||
|
<mat-datepicker-toggle matIconSuffix [for]="deadlinepicker"></mat-datepicker-toggle>
|
||||||
|
<mat-datepicker #deadlinepicker></mat-datepicker>
|
||||||
|
</mat-form-field>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div mat-dialog-actions align="end">
|
||||||
|
<button mat-raised-button (click)="cancel()">Cancel</button>
|
||||||
|
<button mat-raised-button color="primary" (click)="submit()">{{editorData.task == undefined? 'Add Task': 'Edit Task'}}</button>
|
||||||
|
</div>
|
@ -0,0 +1,25 @@
|
|||||||
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { TaskEditorComponent } from './task-editor.component';
|
||||||
|
|
||||||
|
describe('TaskEditorComponent', () => {
|
||||||
|
let component: TaskEditorComponent;
|
||||||
|
let fixture: ComponentFixture<TaskEditorComponent>;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await TestBed.configureTestingModule({
|
||||||
|
declarations: [ TaskEditorComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(TaskEditorComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
101
frontend/src/app/tasks/task-editor/task-editor.component.ts
Normal file
101
frontend/src/app/tasks/task-editor/task-editor.component.ts
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
import {Component, Inject, OnInit} from '@angular/core';
|
||||||
|
import {FormControl, UntypedFormControl, Validators} from "@angular/forms";
|
||||||
|
import * as _moment from 'moment';
|
||||||
|
import {DateAdapter, MAT_DATE_FORMATS, MAT_DATE_LOCALE} from "@angular/material/core";
|
||||||
|
import {MomentDateAdapter} from "@angular/material-moment-adapter";
|
||||||
|
import {MAT_DIALOG_DATA, MatDialogRef} from "@angular/material/dialog";
|
||||||
|
import {TaskService} from "../../../api";
|
||||||
|
import {TaskEditorData} from "./TaskEditorData";
|
||||||
|
import {MatSnackBar} from "@angular/material/snack-bar";
|
||||||
|
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-task-editor',
|
||||||
|
templateUrl: './task-editor.component.html',
|
||||||
|
styleUrls: ['./task-editor.component.css'],
|
||||||
|
})
|
||||||
|
export class TaskEditorComponent implements OnInit {
|
||||||
|
|
||||||
|
nameCtrl: FormControl = new FormControl('', [Validators.required, Validators.maxLength(255)])
|
||||||
|
etaCtrl: FormControl = new FormControl(0, [Validators.required, Validators.min(0)])
|
||||||
|
startDate: FormControl = new FormControl(Date.now(), [Validators.required])
|
||||||
|
endDate: FormControl = new FormControl('');
|
||||||
|
constructor(private dialog: MatDialogRef<TaskEditorComponent>,
|
||||||
|
private taskService: TaskService,
|
||||||
|
@Inject(MAT_DIALOG_DATA) public editorData: TaskEditorData,
|
||||||
|
private snackbar: MatSnackBar) { }
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
if(this.editorData.task != undefined) {
|
||||||
|
this.nameCtrl.setValue(this.editorData.task.taskName);
|
||||||
|
this.etaCtrl.setValue(this.editorData.task.eta)
|
||||||
|
this.startDate.setValue(this.editorData.task.startDate);
|
||||||
|
this.endDate.setValue(this.editorData.task.deadline);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cancel() {
|
||||||
|
this.dialog.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
submit() {
|
||||||
|
|
||||||
|
if(this.editorData.task != undefined) {
|
||||||
|
this.editTask()
|
||||||
|
} else {
|
||||||
|
this.createTask();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
createTask() {
|
||||||
|
this.taskService.tasksTaskgroupIDPut(this.editorData.taskgroupID, {
|
||||||
|
taskName: this.nameCtrl.value,
|
||||||
|
eta: this.etaCtrl.value,
|
||||||
|
startDate: this.startDate.value,
|
||||||
|
deadline: this.endDate.value
|
||||||
|
}).subscribe({
|
||||||
|
next: resp => {
|
||||||
|
this.dialog.close(resp);
|
||||||
|
},
|
||||||
|
error: err => {
|
||||||
|
if(err.status == 403) {
|
||||||
|
this.snackbar.open("No permission", "", {duration: 2000});
|
||||||
|
} else if(err.status == 404) {
|
||||||
|
this.snackbar.open("Taskgroup not found", "", {duration: 2000});
|
||||||
|
} else if(err.status == 409) {
|
||||||
|
this.snackbar.open("Task already exists", "", {duration: 2000});
|
||||||
|
} else {
|
||||||
|
this.snackbar.open("Unexpected error", "", {duration: 3000});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
editTask() {
|
||||||
|
this.taskService.tasksTaskIDPost(this.editorData.task!.taskID, {
|
||||||
|
taskName: this.nameCtrl.value,
|
||||||
|
eta: this.etaCtrl.value,
|
||||||
|
startDate: this.startDate.value,
|
||||||
|
deadline: this.endDate.value
|
||||||
|
}).subscribe({
|
||||||
|
next: resp => {
|
||||||
|
this.editorData.task!.taskName = this.nameCtrl.value;
|
||||||
|
this.editorData.task!.eta = this.etaCtrl.value;
|
||||||
|
this.editorData.task!.startDate = this.startDate.value;
|
||||||
|
this.editorData.task!.deadline = this.endDate.value;
|
||||||
|
this.dialog.close(true);
|
||||||
|
},
|
||||||
|
error: err => {
|
||||||
|
if(err.status == 403) {
|
||||||
|
this.snackbar.open("No permission", "", {duration: 2000});
|
||||||
|
} else if(err.status == 404) {
|
||||||
|
this.snackbar.open("Taskgroup not found", "", {duration: 2000});
|
||||||
|
} else if(err.status == 409) {
|
||||||
|
this.snackbar.open("Task already exists", "", {duration: 2000});
|
||||||
|
} else {
|
||||||
|
this.snackbar.open("Unexpected error", "", {duration: 3000});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
@ -1,7 +1,7 @@
|
|||||||
import { Component, OnInit } from '@angular/core';
|
import { Component, OnInit } from '@angular/core';
|
||||||
import {AbstractControl, FormControl, ValidationErrors, Validators} from "@angular/forms";
|
import {AbstractControl, UntypedFormControl, ValidationErrors, Validators} from "@angular/forms";
|
||||||
import {AccountService} from "../../../../api";
|
import {AccountService} from "../../../../api";
|
||||||
import {MatSnackBar} from "@angular/material/snack-bar";
|
import {MatSnackBar as MatSnackBar} from "@angular/material/snack-bar";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-change-password',
|
selector: 'app-change-password',
|
||||||
@ -14,9 +14,9 @@ export class ChangePasswordComponent implements OnInit {
|
|||||||
|
|
||||||
hide: boolean = true;
|
hide: boolean = true;
|
||||||
pending: boolean = false;
|
pending: boolean = false;
|
||||||
oldPasswordControl = new FormControl('', [Validators.required])
|
oldPasswordControl = new UntypedFormControl('', [Validators.required])
|
||||||
newPasswordControl = new FormControl('', [Validators.required, Validators.minLength(6)])
|
newPasswordControl = new UntypedFormControl('', [Validators.required, Validators.minLength(6)])
|
||||||
duplicatePasswordControl = new FormControl('', [
|
duplicatePasswordControl = new UntypedFormControl('', [
|
||||||
Validators.required,
|
Validators.required,
|
||||||
(control: AbstractControl): ValidationErrors | null => {
|
(control: AbstractControl): ValidationErrors | null => {
|
||||||
return control.value != this.newPassword ? {duplicate: {value: control.value}} : null
|
return control.value != this.newPassword ? {duplicate: {value: control.value}} : null
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import { Component, OnInit } from '@angular/core';
|
import { Component, OnInit } from '@angular/core';
|
||||||
import {FormControl, Validators} from "@angular/forms";
|
import {UntypedFormControl, Validators} from "@angular/forms";
|
||||||
import {AccountService} from "../../../../api";
|
import {AccountService} from "../../../../api";
|
||||||
import {Router} from "@angular/router";
|
import {Router} from "@angular/router";
|
||||||
import {AuthService} from "../../../auth.service";
|
import {AuthService} from "../../../auth.service";
|
||||||
import {MatSnackBar} from "@angular/material/snack-bar";
|
import {MatSnackBar as MatSnackBar} from "@angular/material/snack-bar";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-delete-account',
|
selector: 'app-delete-account',
|
||||||
@ -14,7 +14,7 @@ export class DeleteAccountComponent implements OnInit {
|
|||||||
password: string = "";
|
password: string = "";
|
||||||
|
|
||||||
hide: boolean = true;
|
hide: boolean = true;
|
||||||
passwordControl = new FormControl('', [Validators.required]);
|
passwordControl = new UntypedFormControl('', [Validators.required]);
|
||||||
pending: boolean = false;
|
pending: boolean = false;
|
||||||
|
|
||||||
constructor(private accountService: AccountService, private router: Router, private auth: AuthService, private snackbar: MatSnackBar) { }
|
constructor(private accountService: AccountService, private router: Router, private auth: AuthService, private snackbar: MatSnackBar) { }
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { Component, OnInit } from '@angular/core';
|
import { Component, OnInit } from '@angular/core';
|
||||||
import {AccountService} from "../../../../api";
|
import {AccountService} from "../../../../api";
|
||||||
import {FormControl, Validators} from "@angular/forms";
|
import {UntypedFormControl, Validators} from "@angular/forms";
|
||||||
import {MatSnackBar} from "@angular/material/snack-bar";
|
import {MatSnackBar as MatSnackBar} from "@angular/material/snack-bar";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-manage-email',
|
selector: 'app-manage-email',
|
||||||
@ -12,8 +12,8 @@ export class ManageEmailComponent implements OnInit {
|
|||||||
email : string = "";
|
email : string = "";
|
||||||
password: string = "";
|
password: string = "";
|
||||||
|
|
||||||
emailControl = new FormControl('', [Validators.required, Validators.email]);
|
emailControl = new UntypedFormControl('', [Validators.required, Validators.email]);
|
||||||
passwordControl = new FormControl('', [Validators.required])
|
passwordControl = new UntypedFormControl('', [Validators.required])
|
||||||
hide: boolean = true;
|
hide: boolean = true;
|
||||||
pending: boolean = false;
|
pending: boolean = false;
|
||||||
|
|
||||||
|
@ -7,20 +7,8 @@ import {
|
|||||||
platformBrowserDynamicTesting
|
platformBrowserDynamicTesting
|
||||||
} from '@angular/platform-browser-dynamic/testing';
|
} from '@angular/platform-browser-dynamic/testing';
|
||||||
|
|
||||||
declare const require: {
|
|
||||||
context(path: string, deep?: boolean, filter?: RegExp): {
|
|
||||||
<T>(id: string): T;
|
|
||||||
keys(): string[];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
// First, initialize the Angular testing environment.
|
// First, initialize the Angular testing environment.
|
||||||
getTestBed().initTestEnvironment(
|
getTestBed().initTestEnvironment(
|
||||||
BrowserDynamicTestingModule,
|
BrowserDynamicTestingModule,
|
||||||
platformBrowserDynamicTesting(),
|
platformBrowserDynamicTesting(),
|
||||||
);
|
);
|
||||||
|
|
||||||
// Then we find all the tests.
|
|
||||||
const context = require.context('./', true, /\.spec\.ts$/);
|
|
||||||
// And load the modules.
|
|
||||||
context.keys().map(context);
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
{
|
{
|
||||||
"compileOnSave": false,
|
"compileOnSave": false,
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"baseUrl": "./",
|
"baseUrl": "src",
|
||||||
"outDir": "./dist/out-tsc",
|
"outDir": "./dist/out-tsc",
|
||||||
"forceConsistentCasingInFileNames": true,
|
"forceConsistentCasingInFileNames": true,
|
||||||
"strict": true,
|
"strict": true,
|
||||||
@ -16,12 +16,13 @@
|
|||||||
"experimentalDecorators": true,
|
"experimentalDecorators": true,
|
||||||
"moduleResolution": "node",
|
"moduleResolution": "node",
|
||||||
"importHelpers": true,
|
"importHelpers": true,
|
||||||
"target": "es2017",
|
"target": "ES2022",
|
||||||
"module": "es2020",
|
"module": "es2020",
|
||||||
"lib": [
|
"lib": [
|
||||||
"es2020",
|
"es2020",
|
||||||
"dom"
|
"dom"
|
||||||
]
|
],
|
||||||
|
"useDefineForClassFields": false
|
||||||
},
|
},
|
||||||
"angularCompilerOptions": {
|
"angularCompilerOptions": {
|
||||||
"enableI18nLegacyMessageIdFormat": false,
|
"enableI18nLegacyMessageIdFormat": false,
|
||||||
|
402
openapi.yaml
402
openapi.yaml
@ -654,9 +654,8 @@ paths:
|
|||||||
content:
|
content:
|
||||||
'application/json':
|
'application/json':
|
||||||
schema:
|
schema:
|
||||||
type: array
|
type: object
|
||||||
items:
|
$ref: '#/components/schemas/TaskgroupDetailInfo'
|
||||||
$ref: '#/components/schemas/TaskgroupEntityInfo'
|
|
||||||
403:
|
403:
|
||||||
description: No permission
|
description: No permission
|
||||||
content:
|
content:
|
||||||
@ -829,6 +828,303 @@ paths:
|
|||||||
example: "failed"
|
example: "failed"
|
||||||
enum:
|
enum:
|
||||||
- "failed"
|
- "failed"
|
||||||
|
/taskgroups/{taskgroupID}/clear:
|
||||||
|
delete:
|
||||||
|
security:
|
||||||
|
- API_TOKEN: []
|
||||||
|
tags:
|
||||||
|
- taskgroup
|
||||||
|
summary: clears tasks
|
||||||
|
description: Deletes all tasks of that taskgroup
|
||||||
|
parameters:
|
||||||
|
- name: taskgroupID
|
||||||
|
in: path
|
||||||
|
description: internal id of taskgroup
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: number
|
||||||
|
example: 1
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
description: Anfrage erfolgreich
|
||||||
|
content:
|
||||||
|
'application/json':
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
$ref: "#/components/schemas/SimpleStatusResponse"
|
||||||
|
403:
|
||||||
|
description: No permission
|
||||||
|
content:
|
||||||
|
'application/json':
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
$ref: "#/components/schemas/SimpleStatusResponse"
|
||||||
|
404:
|
||||||
|
description: Taskgroup does not exist
|
||||||
|
content:
|
||||||
|
'application/json':
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
$ref: "#/components/schemas/SimpleStatusResponse"
|
||||||
|
/tasks/{taskgroupID}/{status}:
|
||||||
|
get:
|
||||||
|
security:
|
||||||
|
- API_TOKEN: []
|
||||||
|
tags:
|
||||||
|
- task
|
||||||
|
summary: list tasks
|
||||||
|
description: list tasks
|
||||||
|
parameters:
|
||||||
|
- name: taskgroupID
|
||||||
|
in: path
|
||||||
|
description: internal id of taskgroup
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: number
|
||||||
|
example: 1
|
||||||
|
- name: status
|
||||||
|
in: path
|
||||||
|
description: scope of listed tasks
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
enum:
|
||||||
|
- all
|
||||||
|
- overdue
|
||||||
|
- upcoming
|
||||||
|
example: all
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
description: Anfrage erfolgreich
|
||||||
|
content:
|
||||||
|
'application/json':
|
||||||
|
schema:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/TaskEntityInfo'
|
||||||
|
403:
|
||||||
|
description: No permission
|
||||||
|
content:
|
||||||
|
'application/json':
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- status
|
||||||
|
properties:
|
||||||
|
status:
|
||||||
|
type: string
|
||||||
|
description: Status
|
||||||
|
example: "failed"
|
||||||
|
enum:
|
||||||
|
- "failed"
|
||||||
|
404:
|
||||||
|
description: Taskgroup does not exist
|
||||||
|
content:
|
||||||
|
'application/json':
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- status
|
||||||
|
properties:
|
||||||
|
status:
|
||||||
|
type: string
|
||||||
|
description: Status
|
||||||
|
example: "failed"
|
||||||
|
enum:
|
||||||
|
- "failed"
|
||||||
|
/tasks/{taskgroupID}:
|
||||||
|
put:
|
||||||
|
security:
|
||||||
|
- API_TOKEN: []
|
||||||
|
tags:
|
||||||
|
- task
|
||||||
|
summary: creates a new task
|
||||||
|
description: creates tasks
|
||||||
|
parameters:
|
||||||
|
- name: taskgroupID
|
||||||
|
in: path
|
||||||
|
description: internal id of taskgroup
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: number
|
||||||
|
example: 1
|
||||||
|
requestBody:
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/TaskFieldInfo'
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
description: Anfrage erfolgreich
|
||||||
|
content:
|
||||||
|
'application/json':
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
$ref: '#/components/schemas/TaskEntityInfo'
|
||||||
|
403:
|
||||||
|
description: No permission
|
||||||
|
content:
|
||||||
|
'application/json':
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- status
|
||||||
|
properties:
|
||||||
|
status:
|
||||||
|
type: string
|
||||||
|
description: Status
|
||||||
|
example: "failed"
|
||||||
|
enum:
|
||||||
|
- "failed"
|
||||||
|
404:
|
||||||
|
description: Taskgroup does not exist
|
||||||
|
content:
|
||||||
|
'application/json':
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- status
|
||||||
|
properties:
|
||||||
|
status:
|
||||||
|
type: string
|
||||||
|
description: Status
|
||||||
|
example: "failed"
|
||||||
|
enum:
|
||||||
|
- "failed"
|
||||||
|
409:
|
||||||
|
description: Task already exist
|
||||||
|
content:
|
||||||
|
'application/json':
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- status
|
||||||
|
properties:
|
||||||
|
status:
|
||||||
|
type: string
|
||||||
|
description: Status
|
||||||
|
example: "failed"
|
||||||
|
enum:
|
||||||
|
- "failed"
|
||||||
|
/tasks/{taskID}:
|
||||||
|
post:
|
||||||
|
security:
|
||||||
|
- API_TOKEN: []
|
||||||
|
tags:
|
||||||
|
- task
|
||||||
|
summary: edits an existing task
|
||||||
|
description: edits an existing task
|
||||||
|
parameters:
|
||||||
|
- name: taskID
|
||||||
|
in: path
|
||||||
|
description: internal id of task
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: number
|
||||||
|
example: 1
|
||||||
|
requestBody:
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/TaskFieldInfo'
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
description: Anfrage erfolgreich
|
||||||
|
content:
|
||||||
|
'application/json':
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
$ref: '#/components/schemas/TaskEntityInfo'
|
||||||
|
403:
|
||||||
|
description: No permission
|
||||||
|
content:
|
||||||
|
'application/json':
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- status
|
||||||
|
properties:
|
||||||
|
status:
|
||||||
|
type: string
|
||||||
|
description: Status
|
||||||
|
example: "failed"
|
||||||
|
enum:
|
||||||
|
- "failed"
|
||||||
|
404:
|
||||||
|
description: Taskgroup does not exist
|
||||||
|
content:
|
||||||
|
'application/json':
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- status
|
||||||
|
properties:
|
||||||
|
status:
|
||||||
|
type: string
|
||||||
|
description: Status
|
||||||
|
example: "failed"
|
||||||
|
enum:
|
||||||
|
- "failed"
|
||||||
|
409:
|
||||||
|
description: Task already exist
|
||||||
|
content:
|
||||||
|
'application/json':
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- status
|
||||||
|
properties:
|
||||||
|
status:
|
||||||
|
type: string
|
||||||
|
description: Status
|
||||||
|
example: "failed"
|
||||||
|
enum:
|
||||||
|
- "failed"
|
||||||
|
delete:
|
||||||
|
security:
|
||||||
|
- API_TOKEN: []
|
||||||
|
tags:
|
||||||
|
- task
|
||||||
|
summary: edits an existing task
|
||||||
|
description: edits an existing task
|
||||||
|
parameters:
|
||||||
|
- name: taskID
|
||||||
|
in: path
|
||||||
|
description: internal id of task
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: number
|
||||||
|
example: 1
|
||||||
|
requestBody:
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/TaskFieldInfo'
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
description: Anfrage erfolgreich
|
||||||
|
content:
|
||||||
|
'application/json':
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
$ref: "#/components/schemas/SimpleStatusResponse"
|
||||||
|
403:
|
||||||
|
description: No permission
|
||||||
|
content:
|
||||||
|
'application/json':
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
$ref: "#/components/schemas/SimpleStatusResponse"
|
||||||
|
404:
|
||||||
|
description: Taskgroup does not exist
|
||||||
|
content:
|
||||||
|
'application/json':
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
$ref: "#/components/schemas/SimpleStatusResponse"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
components:
|
components:
|
||||||
securitySchemes:
|
securitySchemes:
|
||||||
API_TOKEN:
|
API_TOKEN:
|
||||||
@ -836,6 +1132,18 @@ components:
|
|||||||
scheme: bearer
|
scheme: bearer
|
||||||
bearerFormat: JWT
|
bearerFormat: JWT
|
||||||
schemas:
|
schemas:
|
||||||
|
SimpleStatusResponse:
|
||||||
|
required:
|
||||||
|
- status
|
||||||
|
additionalProperties: false
|
||||||
|
properties:
|
||||||
|
status:
|
||||||
|
type: string
|
||||||
|
description: Response Status der Request
|
||||||
|
example: "failed"
|
||||||
|
enum:
|
||||||
|
- success
|
||||||
|
- failed
|
||||||
LoginRequest:
|
LoginRequest:
|
||||||
required:
|
required:
|
||||||
- username
|
- username
|
||||||
@ -1019,7 +1327,6 @@ components:
|
|||||||
required:
|
required:
|
||||||
- taskgroupID
|
- taskgroupID
|
||||||
- taskgroupName
|
- taskgroupName
|
||||||
- parentTaskgroup
|
|
||||||
additionalProperties: false
|
additionalProperties: false
|
||||||
properties:
|
properties:
|
||||||
taskgroupID:
|
taskgroupID:
|
||||||
@ -1032,9 +1339,6 @@ components:
|
|||||||
example: Taskgroup 1
|
example: Taskgroup 1
|
||||||
maxLength: 255
|
maxLength: 255
|
||||||
minLength: 1
|
minLength: 1
|
||||||
parentTaskgroup:
|
|
||||||
type: object
|
|
||||||
$ref: '#/components/schemas/TaskgroupEntityInfo'
|
|
||||||
TaskgroupFieldInfo:
|
TaskgroupFieldInfo:
|
||||||
required:
|
required:
|
||||||
- name
|
- name
|
||||||
@ -1051,4 +1355,86 @@ components:
|
|||||||
type: number
|
type: number
|
||||||
description: internal id of parent Taskgroup
|
description: internal id of parent Taskgroup
|
||||||
example: 1
|
example: 1
|
||||||
|
TaskgroupDetailInfo:
|
||||||
|
required:
|
||||||
|
- children
|
||||||
|
- ancestors
|
||||||
|
- taskgroupInfo
|
||||||
|
additionalProperties: false
|
||||||
|
properties:
|
||||||
|
children:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/TaskgroupEntityInfo'
|
||||||
|
ancestors:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/TaskgroupEntityInfo'
|
||||||
|
taskgroupInfo:
|
||||||
|
type: object
|
||||||
|
$ref: '#/components/schemas/TaskgroupEntityInfo'
|
||||||
|
TaskEntityInfo:
|
||||||
|
required:
|
||||||
|
- taskID
|
||||||
|
- taskName
|
||||||
|
- eta
|
||||||
|
- startDate
|
||||||
|
- deadline
|
||||||
|
- overdue
|
||||||
|
- finished
|
||||||
|
additionalProperties: false
|
||||||
|
properties:
|
||||||
|
taskID:
|
||||||
|
type: number
|
||||||
|
description: internal id of task
|
||||||
|
example: 1
|
||||||
|
taskName:
|
||||||
|
type: string
|
||||||
|
description: name of task
|
||||||
|
example: Vorlesung schauen
|
||||||
|
eta:
|
||||||
|
type: number
|
||||||
|
description: expected time to finish task
|
||||||
|
example: 10
|
||||||
|
minimum: 0
|
||||||
|
startDate:
|
||||||
|
type: string
|
||||||
|
format: date
|
||||||
|
description: date from which the task can be started
|
||||||
|
deadline:
|
||||||
|
type: string
|
||||||
|
format: date
|
||||||
|
description: date until the task has to be finished
|
||||||
|
overdue:
|
||||||
|
type: boolean
|
||||||
|
description: determines whether the task is overdue
|
||||||
|
example: True
|
||||||
|
finished:
|
||||||
|
type: boolean
|
||||||
|
description: determines whether the task is finished
|
||||||
|
example: True
|
||||||
|
TaskFieldInfo:
|
||||||
|
required:
|
||||||
|
- taskName
|
||||||
|
- eta
|
||||||
|
- startDate
|
||||||
|
- deadline
|
||||||
|
additionalProperties: false
|
||||||
|
properties:
|
||||||
|
taskName:
|
||||||
|
type: string
|
||||||
|
description: name of task
|
||||||
|
example: Vorlesung schauen
|
||||||
|
eta:
|
||||||
|
type: number
|
||||||
|
description: expected time to finish task
|
||||||
|
example: 10
|
||||||
|
minimum: 0
|
||||||
|
startDate:
|
||||||
|
type: string
|
||||||
|
format: date
|
||||||
|
description: date from which the task can be started
|
||||||
|
deadline:
|
||||||
|
type: string
|
||||||
|
format: date
|
||||||
|
description: date until the task has to be finished
|
Loading…
Reference in New Issue
Block a user