Each {@linkplain ColumnHeader} represents a {@linkplain TimeInterval}
*/
public class ClassificationCategoryReport
extends Report Each {@linkplain Row} represents a {@linkplain Classification}.
+ *
+ * Each {@linkplain ColumnHeader} represents a {@linkplain TimeInterval}.
*/
public class ClassificationReport extends Report Each {@linkplain ColumnHeader} represents a {@linkplain TimeInterval}.
*/
public static class DetailedClassificationReport
extends Report Each {@linkplain Row} represents a value of the requested {@linkplain TaskCustomField}.
+ *
+ * Each {@linkplain ColumnHeader} represents a {@linkplain TimeInterval}.
*/
public class TaskCustomFieldValueReport extends Report Each {@linkplain Row} represents a {@linkplain Workbasket}.
+ *
+ * Each {@linkplain ColumnHeader} represents a {@linkplain TaskState}.
*/
public class TaskStatusReport extends Report The created report contains only tasks with a {@linkplain
+ * Task#getCustomAttribute(TaskCustomField) custom attribute} value exactly matching one of the
+ * items in the list.
+ *
+ * @param customField the specified {@linkplain TaskCustomField}
+ * @param strings the values the specified {@linkplain Task#getCustomAttribute(TaskCustomField)
+ * custom attribute} should match
+ * @return the modified {@linkplain TimeIntervalReportBuilder}
+ * @throws InvalidArgumentException if filter values are not given
*/
- B customAttributeFilterIn(Map The created report contains only tasks with a {@linkplain
+ * Task#getCustomAttribute(TaskCustomField) custom attribute} value not matching one of the
+ * items in the list.
+ *
+ * @param customField the specified {@linkplain TaskCustomField}
+ * @param strings the values the specified {@linkplain Task#getCustomAttribute(TaskCustomField)
+ * custom attribute} should not match
+ * @return the modified {@linkplain TimeIntervalReportBuilder}
+ * @throws InvalidArgumentException if filter values are not given
+ */
+ B customAttributeNotIn(TaskCustomField customField, String... strings)
+ throws InvalidArgumentException;
+
+ /**
+ * Adds the values of a certain {@linkplain TaskCustomField} for pattern matching to the builder.
+ *
+ * The created report contains only tasks with a {@linkplain
+ * Task#getCustomAttribute(TaskCustomField) custom attribute} value pattern-matching one of the
+ * items in the list. They will be compared in SQL with the LIKE operator. You may use a wildcard
+ * like % to specify the pattern. If you specify multiple arguments they are combined with the OR
+ * keyword.
+ *
+ * @param customField the specified {@linkplain TaskCustomField}
+ * @param strings the values the specified {@linkplain Task#getCustomAttribute(TaskCustomField)
+ * custom attribute} should match
+ * @return the modified {@linkplain TimeIntervalReportBuilder}
+ * @throws InvalidArgumentException if filter values are not given
+ */
+ B customAttributeLike(TaskCustomField customField, String... strings)
+ throws InvalidArgumentException;
/**
* Returns a list of all taskIds of the report that are in the list of selected items.
diff --git a/lib/taskana-core/src/main/java/pro/taskana/monitor/api/reports/TimestampReport.java b/lib/taskana-core/src/main/java/pro/taskana/monitor/api/reports/TimestampReport.java
index 9a5f30e90..2c793ede7 100644
--- a/lib/taskana-core/src/main/java/pro/taskana/monitor/api/reports/TimestampReport.java
+++ b/lib/taskana-core/src/main/java/pro/taskana/monitor/api/reports/TimestampReport.java
@@ -2,14 +2,26 @@ package pro.taskana.monitor.api.reports;
import java.util.List;
+import pro.taskana.common.api.TimeInterval;
import pro.taskana.common.api.exceptions.InvalidArgumentException;
import pro.taskana.common.api.exceptions.NotAuthorizedException;
import pro.taskana.monitor.api.TaskTimestamp;
+import pro.taskana.monitor.api.reports.header.ColumnHeader;
import pro.taskana.monitor.api.reports.header.TimeIntervalColumnHeader;
import pro.taskana.monitor.api.reports.item.TimestampQueryItem;
+import pro.taskana.monitor.api.reports.row.FoldableRow;
import pro.taskana.monitor.api.reports.row.TimestampRow;
+import pro.taskana.task.api.models.Task;
+import pro.taskana.workbasket.api.models.Workbasket;
-/** A {@link TimestampReport} displays created and competed tasks for a specific dates. */
+/**
+ * A TimestampReport aggregates {@linkplain Task} related data.
+ *
+ * Each {@linkplain FoldableRow} represents a {@linkplain TaskTimestamp} and can be expanded to
+ * display the four organization levels of the corresponding {@linkplain Workbasket}.
+ *
+ * Each {@linkplain ColumnHeader} represents a {@linkplain TimeInterval}.
+ */
public class TimestampReport extends Report Each {@linkplain Row} represents a {@linkplain Workbasket}.
+ *
+ * Each {@linkplain ColumnHeader} represents a {@linkplain TimeInterval}.
*/
public class WorkbasketReport extends Report Each Row represents a Workbasket.
+ *
+ * Each Column Header represents a Time Interval.
+ *
+ * @title Compute a Workbasket Report
+ * @param filterParameter the filter parameters
+ * @param taskTimestamp determine which Task Timestamp should be used for comparison
+ * @return the computed Report
+ * @throws NotAuthorizedException if the current user is not authorized to compute the Report
+ * @throws InvalidArgumentException TODO: this is never thrown ...
+ */
+ @GetMapping(path = RestEndpoints.URL_MONITOR_WORKBASKET_REPORT)
+ @Transactional(readOnly = true, rollbackFor = Exception.class)
+ public ResponseEntity Each Row represents a Classification category.
+ *
+ * Each Column Header represents a Time Interval.
+ *
+ * @title Compute a Classification Category Report
+ * @param filterParameter the filter parameters
+ * @param taskTimestamp determine which Task Timestamp should be used for comparison
+ * @return the computed Report
+ * @throws NotAuthorizedException if the current user is not authorized to compute the Report
+ * @throws InvalidArgumentException TODO: this is never thrown ...
+ */
+ @GetMapping(path = RestEndpoints.URL_MONITOR_CLASSIFICATION_CATEGORY_REPORT)
+ @Transactional(readOnly = true, rollbackFor = Exception.class)
+ public ResponseEntity Each Row represents a Classification.
+ *
+ * Each Column Header represents a Time Interval.
+ *
+ * @title Compute a Classification Report
+ * @param filterParameter the filter parameters
+ * @param taskTimestamp determine which Task Timestamp should be used for comparison
+ * @return the computed Report
+ * @throws NotAuthorizedException if the current user is not authorized to compute the Report
+ * @throws InvalidArgumentException TODO: this is never thrown
+ */
+ @GetMapping(path = RestEndpoints.URL_MONITOR_CLASSIFICATION_REPORT)
+ @Transactional(readOnly = true, rollbackFor = Exception.class)
+ public ResponseEntity Each Foldable Row represents a Classification and can be expanded to show the Classification
+ * of Attachments.
+ *
+ * Each Column Header represents a Time Interval.
+ *
+ * @title Compute a Detailed Classification Report
+ * @param filterParameter the filter parameters
+ * @param taskTimestamp determine which Task Timestamp should be used for comparison
+ * @return the computed Report
+ * @throws NotAuthorizedException if the current user is not authorized to compute the Report
+ * @throws InvalidArgumentException TODO: this is never thrown
+ */
+ @GetMapping(path = RestEndpoints.URL_MONITOR_DETAILED_CLASSIFICATION_REPORT)
+ @Transactional(readOnly = true, rollbackFor = Exception.class)
+ public ResponseEntity Each Row represents a value of the requested Task Custom Field.
+ *
+ * Each Column Header represents a Time Interval
+ *
+ * @title Compute a Detailed Classification Report
+ * @param customField the Task Custom Field whose values are of interest
+ * @param filterParameter the filter parameters
+ * @param taskTimestamp determine which Task Timestamp should be used for comparison
+ * @return the computed Report
+ * @throws NotAuthorizedException if the current user is not authorized to compute the Report
+ * @throws InvalidArgumentException TODO: this is never thrown
+ */
+ @GetMapping(path = RestEndpoints.URL_MONITOR_TASK_CUSTOM_FIELD_VALUE_REPORT)
+ @Transactional(readOnly = true, rollbackFor = Exception.class)
+ public ResponseEntity A Task Status Report contains the total number of tasks, clustered in their Task States and
- * grouped by Workbaskets. Each row represents a Workbasket while each column represents a Task
- * State.
+ * Each Row represents a Workbasket.
*
- * @title Get a Task Status Report
+ * Each Column Header represents a Task State
+ *
+ * @title Compute a Task Status Report
* @param domains Filter the report values by domains.
* @param states Filter the report values by Task states.
* @param workbasketIds Filter the report values by Workbasket Ids.
* @param priorityMinimum Filter the report values by a minimum priority.
- * @return the computed TaskStatusReport
- * @throws NotAuthorizedException if the current user is not authorized to compute the report
+ * @return the computed Report
+ * @throws NotAuthorizedException if the current user is not authorized to compute the Report
*/
- @GetMapping(path = RestEndpoints.URL_MONITOR_TASKS_STATUS_REPORT)
+ @GetMapping(path = RestEndpoints.URL_MONITOR_TASK_STATUS_REPORT)
@Transactional(readOnly = true, rollbackFor = Exception.class)
- public ResponseEntity A WorkbasketReport contains the total numbers of tasks, clustered by the a Task Timestamp
- * date range and grouped by Workbaskets. Each row represents a Workbasket while each column
- * represents a date range.
- *
- * @title Get a Workbasket Report
- * @param states Filter the report by task states
- * @param taskTimestamp determine which task timestamp should be used for comparison
- * @return the computed report
- * @throws NotAuthorizedException if the current user is not authorized to compute the report
- * @throws InvalidArgumentException TODO: this is never thrown ...
- */
- @GetMapping(path = RestEndpoints.URL_MONITOR_TASKS_WORKBASKET_REPORT)
- @Transactional(readOnly = true, rollbackFor = Exception.class)
- public ResponseEntity A Classification Report contains the total numbers of tasks, clustered by the Task Timestamp
- * date range and grouped by Classifications. Each row represents a Classification while each
- * column represents a date range.
- *
- * @title Get a Classification Report
- * @param taskTimestamp determine which Task Timestamp should be used for comparison
- * @return the computed report
- * @throws NotAuthorizedException if the current user is not authorized to compute the report
- * @throws InvalidArgumentException TODO: this is never thrown
- */
- @GetMapping(path = RestEndpoints.URL_MONITOR_TASKS_CLASSIFICATION_REPORT)
- @Transactional(readOnly = true, rollbackFor = Exception.class)
- public ResponseEntity A Timestamp Report contains the total number of tasks, clustered by date range and grouped
- * by its Task Status. Each row represents a Task Status while each column represents a date
- * range. Each row can be expanded to further group the tasks by their Org Level (1-4)
+ * Each Foldable Row represents a TaskTimestamp and can be expanded to display the four
+ * organization levels of the corresponding Workbasket.
+ *
+ * Each Column Header represents a TimeInterval.
*
* @title Get a Timestamp Report
+ * @param filterParameter the filter parameter
+ * @param timestamps Filter by the Task Timestamp of the task
* @return the computed report
* @throws NotAuthorizedException if the current user is not authorized to compute the report
* @throws InvalidArgumentException TODO: this is never thrown
*/
@GetMapping(path = RestEndpoints.URL_MONITOR_TIMESTAMP_REPORT)
@Transactional(readOnly = true, rollbackFor = Exception.class)
- public ResponseEntity, R> {
+public interface QueryParameter
, S extends QuerySortBy
}
@Override
- public Void applyToQuery(Q query) {
+ public Void apply(Q query) {
if (sortBy != null) {
for (int i = 0; i < sortBy.size(); i++) {
SortDirection sortDirection =
@@ -49,7 +49,7 @@ public class QuerySortParameter
, S extends QuerySortBy
// this method is only static because there exists no query for the task comment entity
public static