Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,14 @@
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

import org.cibseven.webapp.auth.CIBUser;
import org.cibseven.webapp.exception.SystemException;
Expand All @@ -35,6 +38,7 @@
import org.cibseven.webapp.rest.model.TaskForm;
import org.cibseven.webapp.rest.model.TaskHistory;
import org.cibseven.webapp.rest.model.Variable;
import org.cibseven.webapp.rest.model.VariableInstance;
import org.cibseven.webapp.providers.utils.URLUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
Expand Down Expand Up @@ -184,14 +188,64 @@ public Object form(String taskId, CIBUser user) {
public Collection<Task> findTasksByFilter(TaskFiltering filters, String filterId, CIBUser user, Integer firstResult, Integer maxResults) {
String url = getEngineRestUrl(user) + "/filter/" + filterId + "/list?firstResult=" + firstResult + "&maxResults=" + maxResults;
try {
return Arrays.asList(((ResponseEntity<Task[]>) doPost(url, filters.json(), Task[].class, user)).getBody());
List<Task> tasks = new ArrayList<>(Arrays.asList(((ResponseEntity<Task[]>) doPost(url, filters.json(), Task[].class, user)).getBody()));
List<String> variableNames = filters.getVariableNames();
if (variableNames != null && !variableNames.isEmpty()) {
enrichTasksWithVariables(tasks, variableNames, user);
}
return tasks;
} catch (JsonProcessingException e) {
SystemException se = new SystemException(e);
log.info("Exception in getTasksFiltered(...):", se);
throw se;
}
}

private void enrichTasksWithVariables(List<Task> tasks, List<String> variableNames, CIBUser user) {
String processInstanceIds = tasks.stream()
.map(Task::getProcessInstanceId)
.filter(id -> id != null && !id.isEmpty())
.distinct()
.collect(Collectors.joining(","));

if (processInstanceIds.isEmpty()) return;

String url = getEngineRestUrl(user) + "/variable-instance?processInstanceIdIn="
+ processInstanceIds + "&deserializeValues=false";
try {
VariableInstance[] instances = ((ResponseEntity<VariableInstance[]>)
doGet(url, VariableInstance[].class, user, false)).getBody();
if (instances == null) return;

Map<String, Map<String, Object>> varsByInstance = new HashMap<>();
Map<String, Map<String, String>> typesByInstance = new HashMap<>();
for (VariableInstance vi : instances) {
if (variableNames.contains(vi.getName()) && vi.getProcessInstanceId() != null) {
Object displayValue = vi.getValue();
if ("Object".equals(vi.getType()) && vi.getValueInfo() != null) {
Object typeName = vi.getValueInfo().get("objectTypeName");
if (typeName != null) displayValue = typeName;
}
varsByInstance
.computeIfAbsent(vi.getProcessInstanceId(), k -> new HashMap<>())
.put(vi.getName(), displayValue);
typesByInstance
.computeIfAbsent(vi.getProcessInstanceId(), k -> new HashMap<>())
.put(vi.getName(), vi.getType());
}
}

for (Task task : tasks) {
if (task.getProcessInstanceId() != null) {
task.setVariables(varsByInstance.getOrDefault(task.getProcessInstanceId(), new HashMap<>()));
task.setVariableTypes(typesByInstance.getOrDefault(task.getProcessInstanceId(), new HashMap<>()));
}
}
} catch (Exception e) {
log.warn("Could not enrich tasks with variables: {}", e.getMessage());
}
}

@Override
public Integer findTasksCountByFilter(String filterId, CIBUser user, TaskFiltering filters) {
String url = getEngineRestUrl(user) + "/filter/" + filterId + "/count";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
*/
package org.cibseven.webapp.rest.model;

import java.util.List;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

import lombok.AllArgsConstructor;
Expand All @@ -29,4 +31,5 @@ public class FilterProperties {
private String description;
private boolean refresh;
private int priority;
private List<FilterVariable> variables;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* Copyright CIB software GmbH and/or licensed to CIB software GmbH
* under one or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information regarding copyright
* ownership. CIB software licenses this file to you under the Apache License,
* Version 2.0; you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.cibseven.webapp.rest.model;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data @AllArgsConstructor @NoArgsConstructor @JsonIgnoreProperties(ignoreUnknown = true)
public class FilterVariable {
private String name;
private String label;
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
*/
package org.cibseven.webapp.rest.model;

import java.util.Map;

import com.fasterxml.jackson.annotation.JsonAlias;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
Expand Down Expand Up @@ -47,14 +49,16 @@ public class Task {
String suspended;
String tenantId;
CamundaForm camundaFormRef;

Map<String, Object> variables;
Map<String, String> variableTypes;

@JsonProperty("created") @JsonAlias({"creationDate"}) String created;
@JsonProperty("due") @JsonAlias({"dueDate"}) String due;
@JsonProperty("followUp") @JsonAlias({"followUpDate"}) String followUp;
@JsonProperty("taskDefinitionKey") @JsonAlias({"taskDefinitionId"}) String taskDefinitionKey;
@JsonProperty("processDefinitionId") @JsonAlias({"processDefinitionKey"}) String processDefinitionId;
@JsonProperty("processInstanceId") @JsonAlias({"processInstanceKey"}) String processInstanceId;

public String json() throws JsonProcessingException {
return new ObjectMapper().writeValueAsString(this);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ public class TaskFiltering {
List<ProcessVariablesCriteria> processVariables;
List<TaskFilterQuery> orQueries;
Boolean likePatternIgnoreCase;
Boolean variableValuesIgnoreCase;
List<String> variableNames;

public String json() throws JsonProcessingException {
return new ObjectMapper().writeValueAsString(this);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ void testCreateFilter() throws Exception {
"New Filter",
"user1",
new FilterCriterias(),
new FilterProperties("blue", false, "Test Description", true, 10)
new FilterProperties("blue", false, "Test Description", true, 10, null)
);

// Load the mock response from a file
Expand Down Expand Up @@ -131,7 +131,7 @@ void testUpdateFilter() throws Exception {
"Updated Filter",
"user1",
new FilterCriterias(),
new FilterProperties("red", true, "Updated Description", true, 20)
new FilterProperties("red", true, "Updated Description", true, 20, null)
);

mockWebServer.enqueue(new MockResponse().setResponseCode(204));
Expand Down
3 changes: 2 additions & 1 deletion frontend/src/__tests__/filter.modal.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ function getWrapper() {
'b-form-select': true,
'b-button': true,
'b-form-checkbox': true,
'b-modal': true
'b-modal': true,
'b-badge': true
},
plugins: [i18n],
mocks: {
Expand Down
10 changes: 10 additions & 0 deletions frontend/src/assets/translations_de.json
Original file line number Diff line number Diff line change
Expand Up @@ -930,6 +930,16 @@
"legendExpression": "Mit \"*\" endende Schlüssel akzeptieren Ausdrücke als Wert. Z.B.: '&#36;&#123; currentUser&#40;&#41; &#125;' oder '&#36;&#123; currentUserGroups&#40;&#41; &#125;'",
"legendMultiple": "Mit \"in\" endende Schlüssel akzeptieren mehrere durch Komma getrennte Werte. Z.B.: `SchlüsselC, SchlüsselA, SchlüsselB`",
"create": "Filter erstellen",
"variablesTitle": "Variablen",
"variablesLegend": "Sie können Variablen definieren, die in der Aufgabenliste angezeigt werden.",
"showUndefinedVariable": "Undefinierte Variablen anzeigen",
"addVariable": "Variable hinzufügen",
"variable": {
"name": "Name",
"label": "Bezeichnung",
"namePlaceholder": "Variablenname",
"labelPlaceholder": "Lesbarer Name"
},
"operators": {
"eq": "=",
"neq": "≠",
Expand Down
10 changes: 10 additions & 0 deletions frontend/src/assets/translations_en.json
Original file line number Diff line number Diff line change
Expand Up @@ -930,6 +930,16 @@
"legendExpression": "Keys ending with \"*\" accept expressions as value. E.g.: '&#36;&#123; currentUser&#40;&#41; &#125;' or '&#36;&#123; currentUserGroups&#40;&#41; &#125;'",
"legendMultiple": "Keys ending with \"in\" accept multiple values separated by comma. E.g.: `keyC, keyA, keyB`",
"create": "Create filter",
"variablesTitle": "Variables",
"variablesLegend": "You can define variables shown in the tasks list.",
"showUndefinedVariable": "Show undefined variables",
"addVariable": "Add variable",
"variable": {
"name": "Name",
"label": "Label",
"namePlaceholder": "Variable name",
"labelPlaceholder": "Readable label"
},
"operators": {
"eq": "=",
"neq": "≠",
Expand Down
10 changes: 10 additions & 0 deletions frontend/src/assets/translations_es.json
Original file line number Diff line number Diff line change
Expand Up @@ -930,6 +930,16 @@
"legendExpression": "Las claves que terminan en \"*\" aceptan expresiones como valor. Por ejemplo: '&#36;&#123; currentUser&#40;&#41; &#125;' o '&#36;&#123; currentUserGroups&#40;&#41; &#125;'",
"legendMultiple": "Las claves que terminan en \"in\" aceptan múltiples valores separados por coma. Por ejemplo: `claveC, claveA, claveB`",
"create": "Crear filtro",
"variablesTitle": "Variables",
"variablesLegend": "Puede definir variables que se muestran en la lista de tareas.",
"showUndefinedVariable": "Mostrar variables no definidas",
"addVariable": "Añadir variable",
"variable": {
"name": "Nombre",
"label": "Etiqueta",
"namePlaceholder": "Nombre de variable",
"labelPlaceholder": "Etiqueta legible"
},
"operators": {
"eq": "=",
"neq": "≠",
Expand Down
10 changes: 10 additions & 0 deletions frontend/src/assets/translations_ru.json
Original file line number Diff line number Diff line change
Expand Up @@ -930,6 +930,16 @@
"legendExpression": "Свойства с окончанием \"*\" в качестве значения могут иметь выражения, например, '&#36;&#123; currentUser&#40;&#41; &#125;' или '&#36;&#123; currentUserGroups&#40;&#41; &#125;'",
"legendMultiple": "Свойства с окончанием \"in\" могут иметь несколько значений, например, список значений, разделённый запятыми, например, `keyC, keyA, keyB`",
"create": "Создать фильтр",
"variablesTitle": "Переменные",
"variablesLegend": "Вы можете задать переменные, отображаемые в списке задач.",
"showUndefinedVariable": "Показывать неопределённые переменные",
"addVariable": "Добавить переменную",
"variable": {
"name": "Имя",
"label": "Метка",
"namePlaceholder": "Имя переменной",
"labelPlaceholder": "Читаемое название"
},
"operators": {
"eq": "=",
"neq": "≠",
Expand Down
10 changes: 10 additions & 0 deletions frontend/src/assets/translations_ua.json
Original file line number Diff line number Diff line change
Expand Up @@ -930,6 +930,16 @@
"legendExpression": "Властивості з закінченням \"*\" як значення можуть мати вирази, наприклад '${ currentUser() }' або '${ currentUserGroups() }'",
"legendMultiple": "Властивості з закінченням \"in\" можуть мати кілька значень, наприклад список значень, розділений комами: `keyC, keyA, keyB`",
"create": "Створити фільтр",
"variablesTitle": "Змінні",
"variablesLegend": "Ви можете задати змінні, які відображаються у списку завдань.",
"showUndefinedVariable": "Показувати невизначені змінні",
"addVariable": "Додати змінну",
"variable": {
"name": "Ім'я",
"label": "Мітка",
"namePlaceholder": "Ім'я змінної",
"labelPlaceholder": "Читабельна назва"
},
"operators": {
"eq": "=",
"neq": "≠",
Expand Down
6 changes: 6 additions & 0 deletions frontend/src/components/process/mixins/variableUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,12 @@ export default {
return ''
},

shortValue(value) {
const str = '' + value
const dot = str.lastIndexOf('.')
return dot >= 0 && dot < str.length - 1 && /^[a-z]/.test(str) ? str.substring(dot + 1) : str
},

getFileObjects() {
return [
'de.cib.cibflow.api.files.FileValueDataFlowSource',
Expand Down
7 changes: 7 additions & 0 deletions frontend/src/components/task/TasksContent.vue
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,13 @@ export default {
filters.orQueries.push(this.$store.getters.formatedCriteriaData)
}
}
if (filters.processVariables || (filters.orQueries && filters.orQueries.some(q => q.processVariables))) {
filters.variableValuesIgnoreCase = true
}
const filterVariables = this.$store.state.filter.selected.properties?.variables
if (filterVariables && filterVariables.length > 0) {
filters.variableNames = filterVariables.map(v => v.name)
}
TaskService.findTasksByFilter(this.$store.state.filter.selected.id, filters,
{ firstResult: firstResult, maxResults: maxResults }).then(result => {
const tasks = this.tasksByPermissions(this.$root.config.permissions.displayTasks, result)
Expand Down
Loading