parent
ace632d814
commit
2aeb815d8e
|
|
@ -1,369 +1,369 @@
|
||||||
package pro.taskana.rest;
|
package pro.taskana.rest;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.hateoas.PagedResources;
|
import org.springframework.hateoas.PagedResources;
|
||||||
import org.springframework.hateoas.PagedResources.PageMetadata;
|
import org.springframework.hateoas.PagedResources.PageMetadata;
|
||||||
import org.springframework.hateoas.config.EnableHypermediaSupport;
|
import org.springframework.hateoas.config.EnableHypermediaSupport;
|
||||||
import org.springframework.hateoas.config.EnableHypermediaSupport.HypermediaType;
|
import org.springframework.hateoas.config.EnableHypermediaSupport.HypermediaType;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
import org.springframework.util.MultiValueMap;
|
import org.springframework.util.MultiValueMap;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.PathVariable;
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
import org.springframework.web.bind.annotation.PutMapping;
|
import org.springframework.web.bind.annotation.PutMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestBody;
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestMethod;
|
import org.springframework.web.bind.annotation.RequestMethod;
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
import pro.taskana.BaseQuery.SortDirection;
|
import pro.taskana.BaseQuery.SortDirection;
|
||||||
import pro.taskana.KeyDomain;
|
import pro.taskana.KeyDomain;
|
||||||
import pro.taskana.Task;
|
import pro.taskana.Task;
|
||||||
import pro.taskana.TaskQuery;
|
import pro.taskana.TaskQuery;
|
||||||
import pro.taskana.TaskService;
|
import pro.taskana.TaskService;
|
||||||
import pro.taskana.TaskState;
|
import pro.taskana.TaskState;
|
||||||
import pro.taskana.TaskSummary;
|
import pro.taskana.TaskSummary;
|
||||||
import pro.taskana.exceptions.AttachmentPersistenceException;
|
import pro.taskana.exceptions.AttachmentPersistenceException;
|
||||||
import pro.taskana.exceptions.ClassificationNotFoundException;
|
import pro.taskana.exceptions.ClassificationNotFoundException;
|
||||||
import pro.taskana.exceptions.ConcurrencyException;
|
import pro.taskana.exceptions.ConcurrencyException;
|
||||||
import pro.taskana.exceptions.InvalidArgumentException;
|
import pro.taskana.exceptions.InvalidArgumentException;
|
||||||
import pro.taskana.exceptions.InvalidOwnerException;
|
import pro.taskana.exceptions.InvalidOwnerException;
|
||||||
import pro.taskana.exceptions.InvalidStateException;
|
import pro.taskana.exceptions.InvalidStateException;
|
||||||
import pro.taskana.exceptions.InvalidWorkbasketException;
|
import pro.taskana.exceptions.InvalidWorkbasketException;
|
||||||
import pro.taskana.exceptions.NotAuthorizedException;
|
import pro.taskana.exceptions.NotAuthorizedException;
|
||||||
import pro.taskana.exceptions.TaskAlreadyExistException;
|
import pro.taskana.exceptions.TaskAlreadyExistException;
|
||||||
import pro.taskana.exceptions.TaskNotFoundException;
|
import pro.taskana.exceptions.TaskNotFoundException;
|
||||||
import pro.taskana.exceptions.WorkbasketNotFoundException;
|
import pro.taskana.exceptions.WorkbasketNotFoundException;
|
||||||
import pro.taskana.rest.resource.TaskResource;
|
import pro.taskana.rest.resource.TaskResource;
|
||||||
import pro.taskana.rest.resource.TaskSummaryResource;
|
import pro.taskana.rest.resource.TaskSummaryResource;
|
||||||
import pro.taskana.rest.resource.assembler.TaskResourceAssembler;
|
import pro.taskana.rest.resource.assembler.TaskResourceAssembler;
|
||||||
import pro.taskana.rest.resource.assembler.TaskSummaryResourcesAssembler;
|
import pro.taskana.rest.resource.assembler.TaskSummaryResourcesAssembler;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Controller for all {@link Task} related endpoints.
|
* Controller for all {@link Task} related endpoints.
|
||||||
*/
|
*/
|
||||||
@RestController
|
@RestController
|
||||||
@EnableHypermediaSupport(type = HypermediaType.HAL)
|
@EnableHypermediaSupport(type = HypermediaType.HAL)
|
||||||
@RequestMapping(path = "/v1/tasks", produces = "application/hal+json")
|
@RequestMapping(path = "/v1/tasks", produces = "application/hal+json")
|
||||||
public class TaskController extends AbstractPagingController {
|
public class TaskController extends AbstractPagingController {
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(TaskController.class);
|
private static final Logger LOGGER = LoggerFactory.getLogger(TaskController.class);
|
||||||
|
|
||||||
private static final String STATE = "state";
|
private static final String STATE = "state";
|
||||||
private static final String STATE_VALUE_CLAIMED = "CLAIMED";
|
private static final String STATE_VALUE_CLAIMED = "CLAIMED";
|
||||||
private static final String STATE_VALUE_COMPLETED = "COMPLETED";
|
private static final String STATE_VALUE_COMPLETED = "COMPLETED";
|
||||||
private static final String STATE_VALUE_READY = "READY";
|
private static final String STATE_VALUE_READY = "READY";
|
||||||
private static final String PRIORITY = "priority";
|
private static final String PRIORITY = "priority";
|
||||||
private static final String NAME = "name";
|
private static final String NAME = "name";
|
||||||
private static final String OWNER = "owner";
|
private static final String OWNER = "owner";
|
||||||
private static final String DOMAIN = "domain";
|
private static final String DOMAIN = "domain";
|
||||||
private static final String WORKBASKET_ID = "workbasket-id";
|
private static final String WORKBASKET_ID = "workbasket-id";
|
||||||
private static final String WORKBASKET_KEY = "workbasket-key";
|
private static final String WORKBASKET_KEY = "workbasket-key";
|
||||||
private static final String CLASSIFICATION_KEY = "classification.key";
|
private static final String CLASSIFICATION_KEY = "classification.key";
|
||||||
private static final String POR_VALUE = "por.value";
|
private static final String POR_VALUE = "por.value";
|
||||||
private static final String POR_TYPE = "por.type";
|
private static final String POR_TYPE = "por.type";
|
||||||
private static final String POR_SYSTEM_INSTANCE = "por.instance";
|
private static final String POR_SYSTEM_INSTANCE = "por.instance";
|
||||||
private static final String POR_SYSTEM = "por.system";
|
private static final String POR_SYSTEM = "por.system";
|
||||||
private static final String POR_COMPANY = "por.company";
|
private static final String POR_COMPANY = "por.company";
|
||||||
private static final String DUE = "due";
|
private static final String DUE = "due";
|
||||||
private static final String PLANNED = "planned";
|
private static final String PLANNED = "planned";
|
||||||
|
|
||||||
private static final String SORT_BY = "sortBy";
|
private static final String SORT_BY = "sortBy";
|
||||||
private static final String SORT_DIRECTION = "order";
|
private static final String SORT_DIRECTION = "order";
|
||||||
|
|
||||||
private static final String PAGING_PAGE = "page";
|
private static final String PAGING_PAGE = "page";
|
||||||
private static final String PAGING_PAGE_SIZE = "page-size";
|
private static final String PAGING_PAGE_SIZE = "page-size";
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private TaskService taskService;
|
private TaskService taskService;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private TaskResourceAssembler taskResourceAssembler;
|
private TaskResourceAssembler taskResourceAssembler;
|
||||||
|
|
||||||
@GetMapping
|
@GetMapping
|
||||||
@Transactional(readOnly = true, rollbackFor = Exception.class)
|
@Transactional(readOnly = true, rollbackFor = Exception.class)
|
||||||
public ResponseEntity<PagedResources<TaskSummaryResource>> getTasks(
|
public ResponseEntity<PagedResources<TaskSummaryResource>> getTasks(
|
||||||
@RequestParam MultiValueMap<String, String> params) throws InvalidArgumentException, NotAuthorizedException {
|
@RequestParam MultiValueMap<String, String> params) throws InvalidArgumentException, NotAuthorizedException {
|
||||||
|
|
||||||
TaskQuery query = taskService.createTaskQuery();
|
TaskQuery query = taskService.createTaskQuery();
|
||||||
query = applyFilterParams(query, params);
|
query = applyFilterParams(query, params);
|
||||||
query = applySortingParams(query, params);
|
query = applySortingParams(query, params);
|
||||||
|
|
||||||
PageMetadata pageMetadata = null;
|
PageMetadata pageMetadata = null;
|
||||||
List<TaskSummary> taskSummaries = null;
|
List<TaskSummary> taskSummaries = null;
|
||||||
String page = params.getFirst(PAGING_PAGE);
|
String page = params.getFirst(PAGING_PAGE);
|
||||||
String pageSize = params.getFirst(PAGING_PAGE_SIZE);
|
String pageSize = params.getFirst(PAGING_PAGE_SIZE);
|
||||||
params.remove(PAGING_PAGE);
|
params.remove(PAGING_PAGE);
|
||||||
params.remove(PAGING_PAGE_SIZE);
|
params.remove(PAGING_PAGE_SIZE);
|
||||||
validateNoInvalidParameterIsLeft(params);
|
validateNoInvalidParameterIsLeft(params);
|
||||||
if (page != null && pageSize != null) {
|
if (page != null && pageSize != null) {
|
||||||
// paging
|
// paging
|
||||||
long totalElements = query.count();
|
long totalElements = query.count();
|
||||||
pageMetadata = initPageMetadata(pageSize, page,
|
pageMetadata = initPageMetadata(pageSize, page,
|
||||||
totalElements);
|
totalElements);
|
||||||
taskSummaries = query.listPage((int) pageMetadata.getNumber(),
|
taskSummaries = query.listPage((int) pageMetadata.getNumber(),
|
||||||
(int) pageMetadata.getSize());
|
(int) pageMetadata.getSize());
|
||||||
} else if (page == null && pageSize == null) {
|
} else if (page == null && pageSize == null) {
|
||||||
// not paging
|
// not paging
|
||||||
taskSummaries = query.list();
|
taskSummaries = query.list();
|
||||||
} else {
|
} else {
|
||||||
throw new InvalidArgumentException("Paging information is incomplete.");
|
throw new InvalidArgumentException("Paging information is incomplete.");
|
||||||
}
|
}
|
||||||
|
|
||||||
TaskSummaryResourcesAssembler taskSummaryResourcesAssembler = new TaskSummaryResourcesAssembler();
|
TaskSummaryResourcesAssembler taskSummaryResourcesAssembler = new TaskSummaryResourcesAssembler();
|
||||||
PagedResources<TaskSummaryResource> pagedResources = taskSummaryResourcesAssembler.toResources(taskSummaries,
|
PagedResources<TaskSummaryResource> pagedResources = taskSummaryResourcesAssembler.toResources(taskSummaries,
|
||||||
pageMetadata);
|
pageMetadata);
|
||||||
|
|
||||||
return new ResponseEntity<>(pagedResources, HttpStatus.OK);
|
return new ResponseEntity<>(pagedResources, HttpStatus.OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping(path = "/{taskId}")
|
@GetMapping(path = "/{taskId}")
|
||||||
@Transactional(readOnly = true, rollbackFor = Exception.class)
|
@Transactional(readOnly = true, rollbackFor = Exception.class)
|
||||||
public ResponseEntity<TaskResource> getTask(@PathVariable String taskId)
|
public ResponseEntity<TaskResource> getTask(@PathVariable String taskId)
|
||||||
throws TaskNotFoundException, NotAuthorizedException {
|
throws TaskNotFoundException, NotAuthorizedException {
|
||||||
Task task = taskService.getTask(taskId);
|
Task task = taskService.getTask(taskId);
|
||||||
ResponseEntity<TaskResource> result = new ResponseEntity<>(taskResourceAssembler.toResource(task),
|
ResponseEntity<TaskResource> result = new ResponseEntity<>(taskResourceAssembler.toResource(task),
|
||||||
HttpStatus.OK);
|
HttpStatus.OK);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping(path = "/{taskId}/claim")
|
@PostMapping(path = "/{taskId}/claim")
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public ResponseEntity<TaskResource> claimTask(@PathVariable String taskId, @RequestBody String userName)
|
public ResponseEntity<TaskResource> claimTask(@PathVariable String taskId, @RequestBody String userName)
|
||||||
throws TaskNotFoundException, InvalidStateException, InvalidOwnerException, NotAuthorizedException {
|
throws TaskNotFoundException, InvalidStateException, InvalidOwnerException, NotAuthorizedException {
|
||||||
// TODO verify user
|
// TODO verify user
|
||||||
taskService.claim(taskId);
|
taskService.claim(taskId);
|
||||||
Task updatedTask = taskService.getTask(taskId);
|
Task updatedTask = taskService.getTask(taskId);
|
||||||
ResponseEntity<TaskResource> result = new ResponseEntity<>(taskResourceAssembler.toResource(updatedTask),
|
ResponseEntity<TaskResource> result = new ResponseEntity<>(taskResourceAssembler.toResource(updatedTask),
|
||||||
HttpStatus.OK);
|
HttpStatus.OK);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping(method = RequestMethod.POST, value = "/{taskId}/complete")
|
@RequestMapping(method = RequestMethod.POST, value = "/{taskId}/complete")
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public ResponseEntity<TaskResource> completeTask(@PathVariable String taskId)
|
public ResponseEntity<TaskResource> completeTask(@PathVariable String taskId)
|
||||||
throws TaskNotFoundException, InvalidOwnerException, InvalidStateException, NotAuthorizedException {
|
throws TaskNotFoundException, InvalidOwnerException, InvalidStateException, NotAuthorizedException {
|
||||||
taskService.forceCompleteTask(taskId);
|
taskService.forceCompleteTask(taskId);
|
||||||
Task updatedTask = taskService.getTask(taskId);
|
Task updatedTask = taskService.getTask(taskId);
|
||||||
ResponseEntity<TaskResource> result = new ResponseEntity<>(taskResourceAssembler.toResource(updatedTask),
|
ResponseEntity<TaskResource> result = new ResponseEntity<>(taskResourceAssembler.toResource(updatedTask),
|
||||||
HttpStatus.OK);
|
HttpStatus.OK);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping(method = RequestMethod.DELETE, value = "/{taskId}")
|
@RequestMapping(method = RequestMethod.DELETE, value = "/{taskId}")
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public ResponseEntity<TaskResource> deleteTask(@PathVariable String taskId)
|
public ResponseEntity<TaskResource> deleteTask(@PathVariable String taskId)
|
||||||
throws TaskNotFoundException, InvalidStateException, NotAuthorizedException {
|
throws TaskNotFoundException, InvalidStateException, NotAuthorizedException {
|
||||||
taskService.forceDeleteTask(taskId);
|
taskService.forceDeleteTask(taskId);
|
||||||
ResponseEntity<TaskResource> result = new ResponseEntity<>(HttpStatus.OK);
|
ResponseEntity<TaskResource> result = new ResponseEntity<>(HttpStatus.OK);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping(method = RequestMethod.POST)
|
@RequestMapping(method = RequestMethod.POST)
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public ResponseEntity<TaskResource> createTask(@RequestBody TaskResource taskResource)
|
public ResponseEntity<TaskResource> createTask(@RequestBody TaskResource taskResource)
|
||||||
throws WorkbasketNotFoundException, ClassificationNotFoundException, NotAuthorizedException,
|
throws WorkbasketNotFoundException, ClassificationNotFoundException, NotAuthorizedException,
|
||||||
TaskAlreadyExistException, InvalidWorkbasketException, InvalidArgumentException {
|
TaskAlreadyExistException, InvalidWorkbasketException, InvalidArgumentException {
|
||||||
Task createdTask = taskService.createTask(taskResourceAssembler.toModel(taskResource));
|
Task createdTask = taskService.createTask(taskResourceAssembler.toModel(taskResource));
|
||||||
ResponseEntity<TaskResource> result = new ResponseEntity<>(taskResourceAssembler.toResource(createdTask),
|
ResponseEntity<TaskResource> result = new ResponseEntity<>(taskResourceAssembler.toResource(createdTask),
|
||||||
HttpStatus.CREATED);
|
HttpStatus.CREATED);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping(path = "/{taskId}/transfer/{workbasketKey}")
|
@RequestMapping(path = "/{taskId}/transfer/{workbasketId}")
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public ResponseEntity<TaskResource> transferTask(@PathVariable String taskId, @PathVariable String workbasketKey)
|
public ResponseEntity<TaskResource> transferTask(@PathVariable String taskId, @PathVariable String workbasketId)
|
||||||
throws TaskNotFoundException, WorkbasketNotFoundException, NotAuthorizedException, InvalidWorkbasketException,
|
throws TaskNotFoundException, WorkbasketNotFoundException, NotAuthorizedException, InvalidWorkbasketException,
|
||||||
InvalidStateException {
|
InvalidStateException {
|
||||||
Task updatedTask = taskService.transfer(taskId, workbasketKey);
|
Task updatedTask = taskService.transfer(taskId, workbasketId);
|
||||||
ResponseEntity<TaskResource> result = new ResponseEntity<>(taskResourceAssembler.toResource(updatedTask),
|
ResponseEntity<TaskResource> result = new ResponseEntity<>(taskResourceAssembler.toResource(updatedTask),
|
||||||
HttpStatus.OK);
|
HttpStatus.OK);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@PutMapping(path = "/{taskId}")
|
@PutMapping(path = "/{taskId}")
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public ResponseEntity<TaskResource> updateTask(
|
public ResponseEntity<TaskResource> updateTask(
|
||||||
@PathVariable(value = "taskId") String taskId,
|
@PathVariable(value = "taskId") String taskId,
|
||||||
@RequestBody TaskResource taskResource) throws TaskNotFoundException, WorkbasketNotFoundException,
|
@RequestBody TaskResource taskResource) throws TaskNotFoundException, WorkbasketNotFoundException,
|
||||||
ClassificationNotFoundException, InvalidArgumentException, ConcurrencyException, InvalidWorkbasketException,
|
ClassificationNotFoundException, InvalidArgumentException, ConcurrencyException, InvalidWorkbasketException,
|
||||||
NotAuthorizedException, AttachmentPersistenceException {
|
NotAuthorizedException, AttachmentPersistenceException {
|
||||||
ResponseEntity<TaskResource> result;
|
ResponseEntity<TaskResource> result;
|
||||||
if (taskId.equals(taskResource.getTaskId())) {
|
if (taskId.equals(taskResource.getTaskId())) {
|
||||||
Task task = taskResourceAssembler.toModel(taskResource);
|
Task task = taskResourceAssembler.toModel(taskResource);
|
||||||
task = taskService.updateTask(task);
|
task = taskService.updateTask(task);
|
||||||
result = ResponseEntity.ok(taskResourceAssembler.toResource(task));
|
result = ResponseEntity.ok(taskResourceAssembler.toResource(task));
|
||||||
} else {
|
} else {
|
||||||
throw new InvalidArgumentException(
|
throw new InvalidArgumentException(
|
||||||
"TaskId ('" + taskId
|
"TaskId ('" + taskId
|
||||||
+ "') is not identical with the taskId of to object in the payload which should be updated. ID=('"
|
+ "') is not identical with the taskId of to object in the payload which should be updated. ID=('"
|
||||||
+ taskResource.getTaskId() + "')");
|
+ taskResource.getTaskId() + "')");
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private TaskQuery applyFilterParams(TaskQuery taskQuery, MultiValueMap<String, String> params)
|
private TaskQuery applyFilterParams(TaskQuery taskQuery, MultiValueMap<String, String> params)
|
||||||
throws NotAuthorizedException, InvalidArgumentException {
|
throws NotAuthorizedException, InvalidArgumentException {
|
||||||
|
|
||||||
// apply filters
|
// apply filters
|
||||||
if (params.containsKey(NAME)) {
|
if (params.containsKey(NAME)) {
|
||||||
String[] names = extractCommaSeparatedFields(params.get(NAME));
|
String[] names = extractCommaSeparatedFields(params.get(NAME));
|
||||||
taskQuery.nameIn(names);
|
taskQuery.nameIn(names);
|
||||||
params.remove(NAME);
|
params.remove(NAME);
|
||||||
}
|
}
|
||||||
if (params.containsKey(PRIORITY)) {
|
if (params.containsKey(PRIORITY)) {
|
||||||
String[] prioritesInString = extractCommaSeparatedFields(params.get(PRIORITY));
|
String[] prioritesInString = extractCommaSeparatedFields(params.get(PRIORITY));
|
||||||
int[] priorites = extractPriorities(prioritesInString);
|
int[] priorites = extractPriorities(prioritesInString);
|
||||||
taskQuery.priorityIn(priorites);
|
taskQuery.priorityIn(priorites);
|
||||||
params.remove(PRIORITY);
|
params.remove(PRIORITY);
|
||||||
}
|
}
|
||||||
if (params.containsKey(STATE)) {
|
if (params.containsKey(STATE)) {
|
||||||
TaskState[] states = extractStates(params);
|
TaskState[] states = extractStates(params);
|
||||||
taskQuery.stateIn(states);
|
taskQuery.stateIn(states);
|
||||||
params.remove(STATE);
|
params.remove(STATE);
|
||||||
}
|
}
|
||||||
if (params.containsKey(CLASSIFICATION_KEY)) {
|
if (params.containsKey(CLASSIFICATION_KEY)) {
|
||||||
String[] classificationKeys = extractCommaSeparatedFields(params.get(CLASSIFICATION_KEY));
|
String[] classificationKeys = extractCommaSeparatedFields(params.get(CLASSIFICATION_KEY));
|
||||||
taskQuery.classificationKeyIn(classificationKeys);
|
taskQuery.classificationKeyIn(classificationKeys);
|
||||||
params.remove(CLASSIFICATION_KEY);
|
params.remove(CLASSIFICATION_KEY);
|
||||||
}
|
}
|
||||||
if (params.containsKey(WORKBASKET_ID)) {
|
if (params.containsKey(WORKBASKET_ID)) {
|
||||||
String[] workbaskets = extractCommaSeparatedFields(params.get(WORKBASKET_ID));
|
String[] workbaskets = extractCommaSeparatedFields(params.get(WORKBASKET_ID));
|
||||||
taskQuery.workbasketIdIn(workbaskets);
|
taskQuery.workbasketIdIn(workbaskets);
|
||||||
params.remove(WORKBASKET_ID);
|
params.remove(WORKBASKET_ID);
|
||||||
}
|
}
|
||||||
if (params.containsKey(WORKBASKET_KEY)) {
|
if (params.containsKey(WORKBASKET_KEY)) {
|
||||||
String[] domains = null;
|
String[] domains = null;
|
||||||
if (params.get(DOMAIN) != null) {
|
if (params.get(DOMAIN) != null) {
|
||||||
domains = extractCommaSeparatedFields(params.get(DOMAIN));
|
domains = extractCommaSeparatedFields(params.get(DOMAIN));
|
||||||
}
|
}
|
||||||
if (domains == null || domains.length != 1) {
|
if (domains == null || domains.length != 1) {
|
||||||
throw new InvalidArgumentException("workbasket-key requires excactly one domain as second parameter.");
|
throw new InvalidArgumentException("workbasket-key requires excactly one domain as second parameter.");
|
||||||
}
|
}
|
||||||
String[] workbasketKeys = extractCommaSeparatedFields(params.get(WORKBASKET_KEY));
|
String[] workbasketKeys = extractCommaSeparatedFields(params.get(WORKBASKET_KEY));
|
||||||
KeyDomain[] keyDomains = new KeyDomain[workbasketKeys.length];
|
KeyDomain[] keyDomains = new KeyDomain[workbasketKeys.length];
|
||||||
for (int i = 0; i < workbasketKeys.length; i++) {
|
for (int i = 0; i < workbasketKeys.length; i++) {
|
||||||
keyDomains[i] = new KeyDomain(workbasketKeys[i], domains[0]);
|
keyDomains[i] = new KeyDomain(workbasketKeys[i], domains[0]);
|
||||||
}
|
}
|
||||||
taskQuery.workbasketKeyDomainIn(keyDomains);
|
taskQuery.workbasketKeyDomainIn(keyDomains);
|
||||||
params.remove(WORKBASKET_KEY);
|
params.remove(WORKBASKET_KEY);
|
||||||
params.remove(DOMAIN);
|
params.remove(DOMAIN);
|
||||||
}
|
}
|
||||||
if (params.containsKey(OWNER)) {
|
if (params.containsKey(OWNER)) {
|
||||||
String[] owners = extractCommaSeparatedFields(params.get(OWNER));
|
String[] owners = extractCommaSeparatedFields(params.get(OWNER));
|
||||||
taskQuery.ownerIn(owners);
|
taskQuery.ownerIn(owners);
|
||||||
params.remove(OWNER);
|
params.remove(OWNER);
|
||||||
}
|
}
|
||||||
if (params.containsKey(POR_COMPANY)) {
|
if (params.containsKey(POR_COMPANY)) {
|
||||||
String[] companies = extractCommaSeparatedFields(params.get(POR_COMPANY));
|
String[] companies = extractCommaSeparatedFields(params.get(POR_COMPANY));
|
||||||
taskQuery.primaryObjectReferenceCompanyIn(companies);
|
taskQuery.primaryObjectReferenceCompanyIn(companies);
|
||||||
params.remove(POR_COMPANY);
|
params.remove(POR_COMPANY);
|
||||||
}
|
}
|
||||||
if (params.containsKey(POR_SYSTEM)) {
|
if (params.containsKey(POR_SYSTEM)) {
|
||||||
String[] systems = extractCommaSeparatedFields(params.get(POR_SYSTEM));
|
String[] systems = extractCommaSeparatedFields(params.get(POR_SYSTEM));
|
||||||
taskQuery.primaryObjectReferenceSystemIn(systems);
|
taskQuery.primaryObjectReferenceSystemIn(systems);
|
||||||
params.remove(POR_SYSTEM);
|
params.remove(POR_SYSTEM);
|
||||||
}
|
}
|
||||||
if (params.containsKey(POR_SYSTEM_INSTANCE)) {
|
if (params.containsKey(POR_SYSTEM_INSTANCE)) {
|
||||||
String[] systemInstances = extractCommaSeparatedFields(params.get(POR_SYSTEM_INSTANCE));
|
String[] systemInstances = extractCommaSeparatedFields(params.get(POR_SYSTEM_INSTANCE));
|
||||||
taskQuery.primaryObjectReferenceSystemInstanceIn(systemInstances);
|
taskQuery.primaryObjectReferenceSystemInstanceIn(systemInstances);
|
||||||
params.remove(POR_SYSTEM_INSTANCE);
|
params.remove(POR_SYSTEM_INSTANCE);
|
||||||
}
|
}
|
||||||
if (params.containsKey(POR_TYPE)) {
|
if (params.containsKey(POR_TYPE)) {
|
||||||
String[] types = extractCommaSeparatedFields(params.get(POR_TYPE));
|
String[] types = extractCommaSeparatedFields(params.get(POR_TYPE));
|
||||||
taskQuery.primaryObjectReferenceTypeIn(types);
|
taskQuery.primaryObjectReferenceTypeIn(types);
|
||||||
params.remove(POR_TYPE);
|
params.remove(POR_TYPE);
|
||||||
}
|
}
|
||||||
if (params.containsKey(POR_VALUE)) {
|
if (params.containsKey(POR_VALUE)) {
|
||||||
String[] values = extractCommaSeparatedFields(params.get(POR_VALUE));
|
String[] values = extractCommaSeparatedFields(params.get(POR_VALUE));
|
||||||
taskQuery.primaryObjectReferenceValueIn(values);
|
taskQuery.primaryObjectReferenceValueIn(values);
|
||||||
params.remove(POR_VALUE);
|
params.remove(POR_VALUE);
|
||||||
}
|
}
|
||||||
return taskQuery;
|
return taskQuery;
|
||||||
}
|
}
|
||||||
|
|
||||||
private TaskQuery applySortingParams(TaskQuery taskQuery, MultiValueMap<String, String> params)
|
private TaskQuery applySortingParams(TaskQuery taskQuery, MultiValueMap<String, String> params)
|
||||||
throws NotAuthorizedException, InvalidArgumentException {
|
throws NotAuthorizedException, InvalidArgumentException {
|
||||||
|
|
||||||
// sorting
|
// sorting
|
||||||
String sortBy = params.getFirst(SORT_BY);
|
String sortBy = params.getFirst(SORT_BY);
|
||||||
if (sortBy != null) {
|
if (sortBy != null) {
|
||||||
SortDirection sortDirection;
|
SortDirection sortDirection;
|
||||||
if (params.getFirst(SORT_DIRECTION) != null && "desc".equals(params.getFirst(SORT_DIRECTION))) {
|
if (params.getFirst(SORT_DIRECTION) != null && "desc".equals(params.getFirst(SORT_DIRECTION))) {
|
||||||
sortDirection = SortDirection.DESCENDING;
|
sortDirection = SortDirection.DESCENDING;
|
||||||
} else {
|
} else {
|
||||||
sortDirection = SortDirection.ASCENDING;
|
sortDirection = SortDirection.ASCENDING;
|
||||||
}
|
}
|
||||||
switch (sortBy) {
|
switch (sortBy) {
|
||||||
case (CLASSIFICATION_KEY):
|
case (CLASSIFICATION_KEY):
|
||||||
taskQuery = taskQuery.orderByClassificationKey(sortDirection);
|
taskQuery = taskQuery.orderByClassificationKey(sortDirection);
|
||||||
break;
|
break;
|
||||||
case (POR_TYPE):
|
case (POR_TYPE):
|
||||||
taskQuery = taskQuery.orderByPrimaryObjectReferenceType(sortDirection);
|
taskQuery = taskQuery.orderByPrimaryObjectReferenceType(sortDirection);
|
||||||
break;
|
break;
|
||||||
case (POR_VALUE):
|
case (POR_VALUE):
|
||||||
taskQuery = taskQuery.orderByPrimaryObjectReferenceValue(sortDirection);
|
taskQuery = taskQuery.orderByPrimaryObjectReferenceValue(sortDirection);
|
||||||
break;
|
break;
|
||||||
case (STATE):
|
case (STATE):
|
||||||
taskQuery = taskQuery.orderByState(sortDirection);
|
taskQuery = taskQuery.orderByState(sortDirection);
|
||||||
break;
|
break;
|
||||||
case (NAME):
|
case (NAME):
|
||||||
taskQuery = taskQuery.orderByName(sortDirection);
|
taskQuery = taskQuery.orderByName(sortDirection);
|
||||||
break;
|
break;
|
||||||
case (DUE):
|
case (DUE):
|
||||||
taskQuery = taskQuery.orderByDue(sortDirection);
|
taskQuery = taskQuery.orderByDue(sortDirection);
|
||||||
break;
|
break;
|
||||||
case (PLANNED):
|
case (PLANNED):
|
||||||
taskQuery = taskQuery.orderByPlanned(sortDirection);
|
taskQuery = taskQuery.orderByPlanned(sortDirection);
|
||||||
break;
|
break;
|
||||||
case (PRIORITY):
|
case (PRIORITY):
|
||||||
taskQuery = taskQuery.orderByPriority(sortDirection);
|
taskQuery = taskQuery.orderByPriority(sortDirection);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new InvalidArgumentException("Unknown filter attribute: " + sortBy);
|
throw new InvalidArgumentException("Unknown filter attribute: " + sortBy);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
params.remove(SORT_BY);
|
params.remove(SORT_BY);
|
||||||
params.remove(SORT_DIRECTION);
|
params.remove(SORT_DIRECTION);
|
||||||
return taskQuery;
|
return taskQuery;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int[] extractPriorities(String[] prioritesInString) {
|
private int[] extractPriorities(String[] prioritesInString) {
|
||||||
int[] priorites = new int[prioritesInString.length];
|
int[] priorites = new int[prioritesInString.length];
|
||||||
for (int i = 0; i < prioritesInString.length; i++) {
|
for (int i = 0; i < prioritesInString.length; i++) {
|
||||||
priorites[i] = Integer.getInteger(prioritesInString[i]);
|
priorites[i] = Integer.getInteger(prioritesInString[i]);
|
||||||
}
|
}
|
||||||
return priorites;
|
return priorites;
|
||||||
}
|
}
|
||||||
|
|
||||||
private TaskState[] extractStates(MultiValueMap<String, String> params) throws InvalidArgumentException {
|
private TaskState[] extractStates(MultiValueMap<String, String> params) throws InvalidArgumentException {
|
||||||
List<TaskState> states = new ArrayList<>();
|
List<TaskState> states = new ArrayList<>();
|
||||||
for (String item : params.get(STATE)) {
|
for (String item : params.get(STATE)) {
|
||||||
for (String state : item.split(",")) {
|
for (String state : item.split(",")) {
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case STATE_VALUE_READY:
|
case STATE_VALUE_READY:
|
||||||
states.add(TaskState.READY);
|
states.add(TaskState.READY);
|
||||||
break;
|
break;
|
||||||
case STATE_VALUE_COMPLETED:
|
case STATE_VALUE_COMPLETED:
|
||||||
states.add(TaskState.COMPLETED);
|
states.add(TaskState.COMPLETED);
|
||||||
break;
|
break;
|
||||||
case STATE_VALUE_CLAIMED:
|
case STATE_VALUE_CLAIMED:
|
||||||
states.add(TaskState.CLAIMED);
|
states.add(TaskState.CLAIMED);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new InvalidArgumentException("Unknown status '" + state + "'");
|
throw new InvalidArgumentException("Unknown status '" + state + "'");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return states.toArray(new TaskState[0]);
|
return states.toArray(new TaskState[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,9 +17,6 @@ import {WorkbasketResource} from '../../models/workbasket-resource';
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class WorkbasketService {
|
export class WorkbasketService {
|
||||||
|
|
||||||
workbasketKey: string;
|
|
||||||
workbasketName: string;
|
|
||||||
|
|
||||||
public workBasketSelected = new Subject<string>();
|
public workBasketSelected = new Subject<string>();
|
||||||
public workBasketSaved = new Subject<number>();
|
public workBasketSaved = new Subject<number>();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div *ngIf="currentRoute === 'tasks'" class="center-block no-detail">
|
<div *ngIf="currentRoute === 'tasks'" class="center-block no-detail">
|
||||||
<h3 class="grey">Select a Task</h3>
|
<h3 class="grey">Select a Task</h3>
|
||||||
<!--TODO: ICON for task?-->
|
<span class="glyphicon glyphicon-object-align-bottom"></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -4,16 +4,31 @@ import {HttpClient} from '@angular/common/http';
|
||||||
import {Injectable} from '@angular/core';
|
import {Injectable} from '@angular/core';
|
||||||
import {environment} from 'app/../environments/environment';
|
import {environment} from 'app/../environments/environment';
|
||||||
import {TaskResource} from 'app/workplace/models/task-resource';
|
import {TaskResource} from 'app/workplace/models/task-resource';
|
||||||
|
import {Subject} from 'rxjs/Subject';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class TaskService {
|
export class TaskService {
|
||||||
url = `${environment.taskanaRestUrl}/v1/tasks`;
|
url = `${environment.taskanaRestUrl}/v1/tasks`;
|
||||||
|
|
||||||
|
taskChangedSource = new Subject<Task>();
|
||||||
|
taskChangedStream = this.taskChangedSource.asObservable();
|
||||||
|
|
||||||
|
taskDeletedSource = new Subject<Task>();
|
||||||
|
taskDeletedStream = this.taskDeletedSource.asObservable();
|
||||||
|
|
||||||
|
publishUpdatedTask(task: Task) {
|
||||||
|
this.taskChangedSource.next(task);
|
||||||
|
}
|
||||||
|
|
||||||
|
publishDeletedTask(task: Task) {
|
||||||
|
this.taskDeletedSource.next(task);
|
||||||
|
}
|
||||||
|
|
||||||
constructor(private httpClient: HttpClient) {
|
constructor(private httpClient: HttpClient) {
|
||||||
}
|
}
|
||||||
|
|
||||||
findTasksWithWorkbasket(basketKey: string): Observable<TaskResource> {
|
findTasksWithWorkbasket(basketId: string): Observable<TaskResource> {
|
||||||
return this.httpClient.get<TaskResource>(`${this.url}?workbasket-id=${basketKey}`);
|
return this.httpClient.get<TaskResource>(`${this.url}?workbasket-id=${basketId}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
getTask(id: string): Observable<Task> {
|
getTask(id: string): Observable<Task> {
|
||||||
|
|
@ -28,11 +43,15 @@ export class TaskService {
|
||||||
return this.httpClient.post<Task>(`${this.url}/${id}/claim`, 'test');
|
return this.httpClient.post<Task>(`${this.url}/${id}/claim`, 'test');
|
||||||
}
|
}
|
||||||
|
|
||||||
transferTask(taskId: string, workbasketKey: string): Observable<Task> {
|
transferTask(taskId: string, workbasketId: string): Observable<Task> {
|
||||||
return this.httpClient.post<Task>(`${this.url}/${taskId}/transfer/${workbasketKey}`, '');
|
return this.httpClient.post<Task>(`${this.url}/${taskId}/transfer/${workbasketId}`, '');
|
||||||
}
|
}
|
||||||
|
|
||||||
updateTask(task: Task): Observable<Task> {
|
updateTask(task: Task): Observable<Task> {
|
||||||
return this.httpClient.put<Task>(`${this.url}/${task.taskId}`, task);
|
return this.httpClient.put<Task>(`${this.url}/${task.taskId}`, task);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
deleteTask(task: Task): Observable<Task> {
|
||||||
|
return this.httpClient.delete<Task>(`${this.url}/${task.taskId}`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,22 +1,32 @@
|
||||||
<taskana-spinner [isRunning]="requestInProgress" ></taskana-spinner>
|
<taskana-spinner [isRunning]="requestInProgress"></taskana-spinner>
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
<div class="pull-right">
|
<div class="pull-right">
|
||||||
<div class="col-md-6">
|
<button type="button" (click)="navigateBack()" class="btn btn-default"><span title="Cancel and return to task detail"
|
||||||
<input class="form-control" auto-complete [(ngModel)]="workbasket" [source]="autoCompleteData"
|
class="glyphicon glyphicon-arrow-left text-muted"></span>
|
||||||
placeholder="Transfer ..."/>
|
</button>
|
||||||
|
|
||||||
|
<div class="dropdown" style="display: inline">
|
||||||
|
<button type="button" data-toggle="dropdown" aria-expanded="true" class="btn btn-default dropdown-toggle">
|
||||||
|
<span
|
||||||
|
title="Transfer task to another workbasket"
|
||||||
|
class="glyphicon glyphicon-transfer text-muted"></span>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<ul class="dropdown-menu dropdown-menu-right">
|
||||||
|
<li *ngFor="let workbasket of workbaskets">
|
||||||
|
<a class="dropdown-item" (click)="transferTask(workbasket)">
|
||||||
|
<label>{{workbasket.name}}</label>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<button (click)="transferTask()" class="btn-link"><span title="Transfer task to another workbasket"
|
<button type="button" (click)="completeTask()" class="btn btn-default"><span
|
||||||
class="glyphicon glyphicon-new-window text-muted"></span>
|
title="Complete task and return to task list"
|
||||||
</button>
|
class="glyphicon glyphicon-ok blue text-success"></span>
|
||||||
<button (click)="cancelTask()" class="btn-link"><span title="Cancel task and return to task list"
|
|
||||||
class="glyphicon glyphicon-remove-circle text-muted"></span>
|
|
||||||
</button>
|
|
||||||
<button (click)="completeTask()" class="btn-link"><span title="Complete task and return to task list"
|
|
||||||
class="glyphicon glyphicon-ok-circle text-success"></span>
|
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<h4 class="panel-header"><b>{{task?.name}}</b></h4>
|
<div class="panel-header"><h4><b>{{task?.name}}</b></h4></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="panel-body" *ngIf="task">
|
<div class="panel-body" *ngIf="task">
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,11 @@
|
||||||
import {Component, OnInit} from '@angular/core';
|
import {Component, OnDestroy, OnInit} from '@angular/core';
|
||||||
import {ActivatedRoute, Router} from '@angular/router';
|
import {ActivatedRoute, Router} from '@angular/router';
|
||||||
import {Task} from 'app/workplace/models/task';
|
import {Task} from 'app/workplace/models/task';
|
||||||
import {Workbasket} from 'app/models/workbasket';
|
import {Workbasket} from 'app/models/workbasket';
|
||||||
import {DomSanitizer, SafeResourceUrl} from '@angular/platform-browser';
|
import {DomSanitizer, SafeResourceUrl} from '@angular/platform-browser';
|
||||||
import {TaskService} from 'app/workplace/services/task.service';
|
import {TaskService} from 'app/workplace/services/task.service';
|
||||||
import {WorkbasketService} from 'app/services/workbasket/workbasket.service';
|
import {WorkbasketService} from 'app/services/workbasket/workbasket.service';
|
||||||
|
import {Subscription} from 'rxjs/Subscription';
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
|
|
@ -12,15 +13,17 @@ import {WorkbasketService} from 'app/services/workbasket/workbasket.service';
|
||||||
templateUrl: './task.component.html',
|
templateUrl: './task.component.html',
|
||||||
styleUrls: ['./task.component.scss']
|
styleUrls: ['./task.component.scss']
|
||||||
})
|
})
|
||||||
export class TaskComponent implements OnInit {
|
export class TaskComponent implements OnInit, OnDestroy {
|
||||||
task: Task = null;
|
|
||||||
|
routeSubscription: Subscription;
|
||||||
|
requestInProgress = false;
|
||||||
|
|
||||||
address = 'https://bing.com';
|
address = 'https://bing.com';
|
||||||
link: SafeResourceUrl = this.sanitizer.bypassSecurityTrustResourceUrl(this.address);
|
link: SafeResourceUrl = this.sanitizer.bypassSecurityTrustResourceUrl(this.address);
|
||||||
autoCompleteData: string[] = [];
|
|
||||||
workbasket: string = null;
|
task: Task = null;
|
||||||
workbasketKey: string;
|
|
||||||
workbaskets: Workbasket[];
|
workbaskets: Workbasket[];
|
||||||
requestInProgress = false;
|
|
||||||
|
|
||||||
constructor(private taskService: TaskService,
|
constructor(private taskService: TaskService,
|
||||||
private workbasketService: WorkbasketService,
|
private workbasketService: WorkbasketService,
|
||||||
|
|
@ -30,8 +33,10 @@ export class TaskComponent implements OnInit {
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
const id = this.route.snapshot.params['id'];
|
this.routeSubscription = this.route.params.subscribe(params => {
|
||||||
this.getTask(id);
|
const id = params['id'];
|
||||||
|
this.getTask(id);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
getTask(id: string) {
|
getTask(id: string) {
|
||||||
|
|
@ -41,36 +46,35 @@ export class TaskComponent implements OnInit {
|
||||||
this.requestInProgress = false;
|
this.requestInProgress = false;
|
||||||
this.task = task;
|
this.task = task;
|
||||||
this.link = this.sanitizer.bypassSecurityTrustResourceUrl(`${this.address}/?q=${this.task.name}`);
|
this.link = this.sanitizer.bypassSecurityTrustResourceUrl(`${this.address}/?q=${this.task.name}`);
|
||||||
this.workbasketService.getAllWorkBaskets().subscribe(workbaskets => {
|
this.getWorkbaskets();
|
||||||
this.workbaskets = workbaskets._embedded ? workbaskets._embedded.workbaskets : [];
|
|
||||||
this.workbaskets.forEach(workbasket => {
|
|
||||||
if (workbasket.key !== this.task.workbasketSummaryResource.key) {
|
|
||||||
this.autoCompleteData.push(workbasket.name);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
transferTask() {
|
getWorkbaskets() {
|
||||||
if (this.workbasket) {
|
this.requestInProgress = true;
|
||||||
this.workbaskets.forEach(workbasket => {
|
this.workbasketService.getAllWorkBaskets().subscribe(workbaskets => {
|
||||||
if (workbasket.name === this.workbasket) {
|
this.requestInProgress = false;
|
||||||
this.workbasketKey = workbasket.key;
|
this.workbaskets = workbaskets._embedded ? workbaskets._embedded.workbaskets : [];
|
||||||
|
|
||||||
|
let index = -1;
|
||||||
|
for (let i = 0; i < this.workbaskets.length; i++) {
|
||||||
|
if (this.workbaskets[i].name === this.task.workbasketSummaryResource.name) {
|
||||||
|
index = i;
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
if (index !== -1) {
|
||||||
this.requestInProgress = true;
|
this.workbaskets.splice(index, 1);
|
||||||
this.taskService.transferTask(this.task.taskId, this.workbasketKey).subscribe(
|
}
|
||||||
task => {
|
});
|
||||||
this.requestInProgress = false;
|
|
||||||
this.task = task
|
|
||||||
});
|
|
||||||
this.navigateBack();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cancelTask() {
|
transferTask(workbasket: Workbasket) {
|
||||||
|
this.requestInProgress = true;
|
||||||
|
this.taskService.transferTask(this.task.taskId, workbasket.workbasketId).subscribe(
|
||||||
|
task => {
|
||||||
|
this.requestInProgress = false;
|
||||||
|
this.task = task
|
||||||
|
});
|
||||||
this.navigateBack();
|
this.navigateBack();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -79,12 +83,19 @@ export class TaskComponent implements OnInit {
|
||||||
this.taskService.completeTask(this.task.taskId).subscribe(
|
this.taskService.completeTask(this.task.taskId).subscribe(
|
||||||
task => {
|
task => {
|
||||||
this.requestInProgress = false;
|
this.requestInProgress = false;
|
||||||
this.task = task
|
this.task = task;
|
||||||
|
this.taskService.publishUpdatedTask(task);
|
||||||
|
this.navigateBack();
|
||||||
});
|
});
|
||||||
this.navigateBack();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private navigateBack() {
|
navigateBack() {
|
||||||
this.router.navigate([{outlets: {detail: `taskdetail/${this.task.taskId}`}}], {relativeTo: this.route.parent});
|
this.router.navigate([{outlets: {detail: `taskdetail/${this.task.taskId}`}}], {relativeTo: this.route.parent});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ngOnDestroy(): void {
|
||||||
|
if (this.routeSubscription) {
|
||||||
|
this.routeSubscription.unsubscribe();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,17 @@
|
||||||
<taskana-spinner [isRunning]="requestInProgress" ></taskana-spinner>
|
<taskana-spinner [isRunning]="requestInProgress"></taskana-spinner>
|
||||||
<div class="panel panel-default" *ngIf="task">
|
<div class="panel panel-default" *ngIf="task && !requestInProgress">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
<div class="pull-right">
|
<div class="pull-right">
|
||||||
<button type="button" title="Open task to work on it" class="btn btn-default" aria-label="Left Align"
|
<button type="button" title="Open task to work on it" class="btn btn-default" aria-label="Left Align"
|
||||||
(click)="openTask(task.taskId)">
|
[disabled]="workOnTaskDisabled()" (click)="openTask(task.taskId)">
|
||||||
<span class="glyphicon glyphicon-new-window" aria-hidden="true"></span>
|
<span class="glyphicon glyphicon-new-window" aria-hidden="true"></span>
|
||||||
</button>
|
</button>
|
||||||
<button type="button" title="Update Task" class="btn btn-default" (click)="updateTask()">
|
<button type="button" title="Update Task" class="btn btn-default btn-primary" (click)="updateTask()">
|
||||||
<span class="glyphicon glyphicon-saved" aria-hidden="true"></span>
|
<span class="glyphicon glyphicon-saved" aria-hidden="true"></span>
|
||||||
</button>
|
</button>
|
||||||
|
<button type="button" title="Delete Task" class="btn btn-default btn-danger" (click)="deleteTask()">
|
||||||
|
<span class="glyphicon glyphicon-remove"></span>
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<h4 class="panel-header"><b>{{task?.name}}</b></h4>
|
<h4 class="panel-header"><b>{{task?.name}}</b></h4>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -18,9 +21,9 @@
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="task-description" class="control-label">Description</label>
|
<label for="task-description" class="control-label">Description</label>
|
||||||
<input type="text" class="form-control" id="task-description" placeholder="Description"
|
<textarea type="text" class="form-control" id="task-description" placeholder="Description"
|
||||||
[(ngModel)]="task.description"
|
[(ngModel)]="task.description"
|
||||||
name="task.description">
|
name="task.description"></textarea>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="task-owner" class="control-label">Owner</label>
|
<label for="task-owner" class="control-label">Owner</label>
|
||||||
|
|
@ -63,7 +66,7 @@
|
||||||
name="task.due">
|
name="task.due">
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="task-priority" class="control-label">Priority</label>
|
<label for="task-priority" disabled class="control-label">Priority</label>
|
||||||
<input type="text" class="form-control" id="task-priority" placeholder="no priotity set"
|
<input type="text" class="form-control" id="task-priority" placeholder="no priotity set"
|
||||||
[(ngModel)]="task.priority"
|
[(ngModel)]="task.priority"
|
||||||
name="task.priority">
|
name="task.priority">
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
.list-group {
|
.list-group {
|
||||||
max-height: 84vh;
|
max-height: 85vh;
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
overflow:scroll;
|
overflow: hidden;
|
||||||
-webkit-overflow-scrolling: touch;
|
overflow-y: scroll;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,16 @@
|
||||||
import {Component, OnInit} from '@angular/core';
|
import {Component, OnDestroy, OnInit} from '@angular/core';
|
||||||
import {Task} from '../models/task';
|
import {Task} from 'app/workplace/models/task';
|
||||||
import {ActivatedRoute, Router} from '@angular/router';
|
import {ActivatedRoute, Router} from '@angular/router';
|
||||||
import {TaskService} from '../services/task.service';
|
import {TaskService} from 'app/workplace/services/task.service';
|
||||||
import {Subscription} from 'rxjs/Subscription';
|
import {Subscription} from 'rxjs/Subscription';
|
||||||
|
import {Location} from '@angular/common';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'taskana-task-details',
|
selector: 'taskana-task-details',
|
||||||
templateUrl: './taskdetails.component.html',
|
templateUrl: './taskdetails.component.html',
|
||||||
styleUrls: ['./taskdetails.component.scss']
|
styleUrls: ['./taskdetails.component.scss']
|
||||||
})
|
})
|
||||||
export class TaskdetailsComponent implements OnInit {
|
export class TaskdetailsComponent implements OnInit, OnDestroy {
|
||||||
task: Task = null;
|
task: Task = null;
|
||||||
requestInProgress = false;
|
requestInProgress = false;
|
||||||
|
|
||||||
|
|
@ -17,7 +18,8 @@ export class TaskdetailsComponent implements OnInit {
|
||||||
|
|
||||||
constructor(private route: ActivatedRoute,
|
constructor(private route: ActivatedRoute,
|
||||||
private taskService: TaskService,
|
private taskService: TaskService,
|
||||||
private router: Router) {
|
private router: Router,
|
||||||
|
private location: Location) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
|
|
@ -40,10 +42,28 @@ export class TaskdetailsComponent implements OnInit {
|
||||||
this.taskService.updateTask(this.task).subscribe(task => {
|
this.taskService.updateTask(this.task).subscribe(task => {
|
||||||
this.requestInProgress = false;
|
this.requestInProgress = false;
|
||||||
this.task = task;
|
this.task = task;
|
||||||
|
this.taskService.publishUpdatedTask(task);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
openTask(taskId: string) {
|
openTask(taskId: string) {
|
||||||
this.router.navigate([{outlets: {detail: `task/${taskId}`}}], {relativeTo: this.route.parent});
|
this.router.navigate([{outlets: {detail: `task/${taskId}`}}], {relativeTo: this.route.parent});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
workOnTaskDisabled(): boolean {
|
||||||
|
return this.task ? this.task.state === 'COMPLETED' : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteTask(): void {
|
||||||
|
this.taskService.deleteTask(this.task).subscribe();
|
||||||
|
this.taskService.publishDeletedTask(this.task);
|
||||||
|
this.task = null;
|
||||||
|
this.router.navigate([`/workplace/tasks`]);
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnDestroy(): void {
|
||||||
|
if (this.routeSubscription) {
|
||||||
|
this.routeSubscription.unsubscribe();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,11 @@
|
||||||
<div class="task-list-full-height">
|
<div class="task-list-full-height">
|
||||||
<taskana-workbasket-selector (tasksChanged)="loadTasks($event)"></taskana-workbasket-selector>
|
<taskana-workbasket-selector (tasksChanged)="loadTasks($event)"></taskana-workbasket-selector>
|
||||||
<!--TODO: add toolbar for sorting, also add pagination-->
|
<!--TODO: add toolbar for sorting, also add pagination-->
|
||||||
<div>
|
<div>
|
||||||
<ul #taskList id="task-list-container" class="list-group">
|
<ul #taskList id="task-list-container" class="list-group">
|
||||||
<li class="list-group-item" *ngIf="tasks === undefined || tasks.length === 0" type="text"> There are no Tasks for this workbasket </li>
|
<li class="list-group-item" *ngIf="tasks === undefined || tasks.length === 0" type="text">
|
||||||
|
<b>This Workbasket has no Tasks</b>
|
||||||
|
</li>
|
||||||
<li class="list-group-item" *ngFor="let task of tasks" [class.active]="task.taskId == selectedId"
|
<li class="list-group-item" *ngFor="let task of tasks" [class.active]="task.taskId == selectedId"
|
||||||
type="text" (click)="selectTask(task.taskId)">
|
type="text" (click)="selectTask(task.taskId)">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
.clickable {
|
.clickable {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.task-list-full-height{
|
.task-list-full-height {
|
||||||
height: calc(100vh - 55px);
|
height: calc(100vh - 55px);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -18,14 +18,15 @@
|
||||||
ul {
|
ul {
|
||||||
max-height: 90vh;
|
max-height: 90vh;
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
overflow:scroll;
|
overflow: hidden;
|
||||||
-webkit-overflow-scrolling: touch;
|
overflow-y: scroll;
|
||||||
}
|
}
|
||||||
|
|
||||||
a > label{
|
a > label {
|
||||||
height: 2em;
|
height: 2em;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
dd, dt {
|
dd, dt {
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
|
@ -42,6 +43,7 @@ dt > i {
|
||||||
li > div.row > dl {
|
li > div.row > dl {
|
||||||
margin-bottom: 0px;
|
margin-bottom: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
li > div.row > dl:first-child {
|
li > div.row > dl:first-child {
|
||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,22 +1,41 @@
|
||||||
import {Component, Input, OnInit} from '@angular/core';
|
import {Component, Input, OnDestroy, OnInit} from '@angular/core';
|
||||||
import {Task} from '../models/task';
|
import {Task} from 'app/workplace/models/task';
|
||||||
import {ActivatedRoute, Router} from '@angular/router';
|
import {ActivatedRoute, Router} from '@angular/router';
|
||||||
|
import {TaskService} from 'app/workplace/services/task.service';
|
||||||
|
import {Subscription} from 'rxjs/Subscription';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'taskana-task-list',
|
selector: 'taskana-task-list',
|
||||||
templateUrl: './tasklist.component.html',
|
templateUrl: './tasklist.component.html',
|
||||||
styleUrls: ['./tasklist.component.scss']
|
styleUrls: ['./tasklist.component.scss']
|
||||||
})
|
})
|
||||||
export class TasklistComponent implements OnInit {
|
export class TasklistComponent implements OnInit, OnDestroy {
|
||||||
|
|
||||||
private columnForOrdering: string;
|
private columnForOrdering: string;
|
||||||
|
private taskChangeSubscription: Subscription;
|
||||||
|
private taskDeletedSubscription: Subscription;
|
||||||
|
|
||||||
selectedId = '';
|
selectedId = '';
|
||||||
@Input() tasks: Task[];
|
@Input() tasks: Task[];
|
||||||
|
|
||||||
constructor(private router: Router,
|
constructor(private router: Router,
|
||||||
private route: ActivatedRoute) {
|
private route: ActivatedRoute,
|
||||||
|
private taskService: TaskService) {
|
||||||
this.columnForOrdering = 'id'; // default: order tasks by id
|
this.columnForOrdering = 'id'; // default: order tasks by id
|
||||||
|
this.taskChangeSubscription = this.taskService.taskChangedStream.subscribe(task => {
|
||||||
|
for (let i = 0; i < this.tasks.length; i++) {
|
||||||
|
if (this.tasks[i].taskId === task.taskId) {
|
||||||
|
this.tasks[i] = task;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.taskDeletedSubscription = this.taskService.taskDeletedStream.subscribe(task => {
|
||||||
|
for (let i = 0; i < this.tasks.length; i++) {
|
||||||
|
if (this.tasks[i].taskId === task.taskId) {
|
||||||
|
this.tasks.splice(i, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
|
|
@ -34,4 +53,9 @@ export class TasklistComponent implements OnInit {
|
||||||
this.selectedId = taskId;
|
this.selectedId = taskId;
|
||||||
this.router.navigate([{outlets: {detail: `taskdetail/${this.selectedId}`}}], {relativeTo: this.route});
|
this.router.navigate([{outlets: {detail: `taskdetail/${this.selectedId}`}}], {relativeTo: this.route});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ngOnDestroy(): void {
|
||||||
|
this.taskChangeSubscription.unsubscribe();
|
||||||
|
this.taskDeletedSubscription.unsubscribe();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,14 @@
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-12">
|
<div class="col-md-12">
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<input class="form-control dropdown-toggle" auto-complete [(ngModel)]="result" [source]="autoCompleteData"
|
<input [(ngModel)]="result" [typeahead]="workbasketNames" class="form-control"
|
||||||
|
(typeaheadOnSelect)="workbasketSelected = true" (typeaheadNoResults)="workbasketSelected = false"
|
||||||
placeholder="Search for Workbasket ..."/>
|
placeholder="Search for Workbasket ..."/>
|
||||||
<span class="input-group-btn">
|
<span class="input-group-btn">
|
||||||
<button class="btn btn-primary" type="button" (click)="searchBasket()"
|
<button class="btn btn-primary" type="button" (click)="searchBasket()"
|
||||||
[disabled]="result.length==0">Go!</button>
|
[disabled]="!workbasketSelected">Go!</button>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<!-- /input-group -->
|
|
||||||
</div>
|
</div>
|
||||||
<!-- /.col-lg-18 -->
|
|
||||||
</div>
|
</div>
|
||||||
<!-- /.row -->
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,11 +14,13 @@ export class SelectorComponent implements OnInit {
|
||||||
tasksChanged = new EventEmitter<Task[]>();
|
tasksChanged = new EventEmitter<Task[]>();
|
||||||
|
|
||||||
tasks: Task[] = [];
|
tasks: Task[] = [];
|
||||||
|
workbasketNames: string[] = [];
|
||||||
autoCompleteData: string[] = [];
|
|
||||||
result = '';
|
result = '';
|
||||||
resultKey: string;
|
resultId = '';
|
||||||
workbaskets: Workbasket[];
|
workbaskets: Workbasket[];
|
||||||
|
currentBasket: Workbasket;
|
||||||
|
|
||||||
|
workbasketSelected = false;
|
||||||
|
|
||||||
constructor(private taskService: TaskService,
|
constructor(private taskService: TaskService,
|
||||||
private workbasketService: WorkbasketService) {
|
private workbasketService: WorkbasketService) {
|
||||||
|
|
@ -28,34 +30,37 @@ export class SelectorComponent implements OnInit {
|
||||||
this.workbasketService.getAllWorkBaskets().subscribe(workbaskets => {
|
this.workbasketService.getAllWorkBaskets().subscribe(workbaskets => {
|
||||||
this.workbaskets = workbaskets._embedded ? workbaskets._embedded.workbaskets : [];
|
this.workbaskets = workbaskets._embedded ? workbaskets._embedded.workbaskets : [];
|
||||||
this.workbaskets.forEach(workbasket => {
|
this.workbaskets.forEach(workbasket => {
|
||||||
this.autoCompleteData.push(workbasket.name);
|
this.workbasketNames.push(workbasket.name);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
if (this.workbasketService.workbasketKey) {
|
|
||||||
this.getTasks(this.workbasketService.workbasketKey);
|
|
||||||
this.result = this.workbasketService.workbasketName;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
searchBasket() {
|
searchBasket() {
|
||||||
if (this.workbaskets) {
|
if (this.workbaskets) {
|
||||||
this.workbaskets.forEach(workbasket => {
|
this.workbaskets.forEach(workbasket => {
|
||||||
if (workbasket.name === this.result) {
|
if (workbasket.name === this.result) {
|
||||||
this.resultKey = workbasket.workbasketId;
|
this.resultId = workbasket.workbasketId;
|
||||||
|
this.currentBasket = workbasket;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
this.getTasks(this.resultKey);
|
|
||||||
this.workbasketService.workbasketKey = this.resultKey;
|
if (this.resultId.length > 0) {
|
||||||
this.workbasketService.workbasketName = this.result;
|
this.getTasks(this.resultId);
|
||||||
this.tasksChanged.emit(this.tasks);
|
this.tasksChanged.emit(this.tasks);
|
||||||
|
} else {
|
||||||
|
this.tasks = [];
|
||||||
|
this.tasksChanged.emit(this.tasks);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
this.resultId = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
getTasks(workbasketKey: string) {
|
getTasks(workbasketId: string) {
|
||||||
this.taskService.findTasksWithWorkbasket(workbasketKey).subscribe(
|
this.taskService.findTasksWithWorkbasket(workbasketId).subscribe(
|
||||||
tasks => {
|
tasks => {
|
||||||
|
this.tasks.length = 0;
|
||||||
if (!tasks || tasks._embedded === undefined) {
|
if (!tasks || tasks._embedded === undefined) {
|
||||||
this.tasks.length = 0;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
tasks._embedded.tasks.forEach(e => this.tasks.push(e));
|
tasks._embedded.tasks.forEach(e => this.tasks.push(e));
|
||||||
|
|
|
||||||
|
|
@ -1,20 +1,19 @@
|
||||||
import {CommonModule} from '@angular/common';
|
import {CommonModule} from '@angular/common';
|
||||||
import {NgModule} from '@angular/core';
|
import {NgModule} from '@angular/core';
|
||||||
import {FormsModule} from '@angular/forms';
|
import {FormsModule} from '@angular/forms';
|
||||||
import {Ng2AutoCompleteModule} from 'ng2-auto-complete';
|
|
||||||
import {HTTP_INTERCEPTORS, HttpClientModule} from '@angular/common/http';
|
import {HTTP_INTERCEPTORS, HttpClientModule} from '@angular/common/http';
|
||||||
import {AngularSvgIconModule} from 'angular-svg-icon';
|
import {AngularSvgIconModule} from 'angular-svg-icon';
|
||||||
import {WorkplaceRoutingModule} from './workplace-routing.module';
|
import {WorkplaceRoutingModule} from './workplace-routing.module';
|
||||||
import {AlertModule} from 'ngx-bootstrap';
|
import {AlertModule, TypeaheadModule} from 'ngx-bootstrap';
|
||||||
|
|
||||||
import { SelectorComponent } from './workbasket-selector/workbasket-selector.component';
|
import {SelectorComponent} from './workbasket-selector/workbasket-selector.component';
|
||||||
import { TasklistComponent } from './tasklist/tasklist.component';
|
import {TasklistComponent} from './tasklist/tasklist.component';
|
||||||
import { TaskdetailsComponent } from './taskdetails/taskdetails.component';
|
import {TaskdetailsComponent} from './taskdetails/taskdetails.component';
|
||||||
import { TaskComponent } from './task/task.component';
|
import {TaskComponent} from './task/task.component';
|
||||||
import { CodeComponent } from './components/code/code.component';
|
import {CodeComponent} from './components/code/code.component';
|
||||||
|
|
||||||
|
|
||||||
import { OrderTasksByPipe } from './util/orderTasksBy.pipe';
|
import {OrderTasksByPipe} from './util/orderTasksBy.pipe';
|
||||||
|
|
||||||
import {TaskService} from './services/task.service';
|
import {TaskService} from './services/task.service';
|
||||||
import {WorkbasketService} from 'app/services/workbasket/workbasket.service';
|
import {WorkbasketService} from 'app/services/workbasket/workbasket.service';
|
||||||
|
|
@ -23,9 +22,9 @@ import {CustomHttpClientInterceptor} from './services/custom-http-interceptor/cu
|
||||||
|
|
||||||
|
|
||||||
const MODULES = [
|
const MODULES = [
|
||||||
|
TypeaheadModule.forRoot(),
|
||||||
CommonModule,
|
CommonModule,
|
||||||
FormsModule,
|
FormsModule,
|
||||||
Ng2AutoCompleteModule,
|
|
||||||
HttpClientModule,
|
HttpClientModule,
|
||||||
AngularSvgIconModule,
|
AngularSvgIconModule,
|
||||||
WorkplaceRoutingModule,
|
WorkplaceRoutingModule,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue