Skip to content

Refactor some parts of the column filtering functionality #6152

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 20 commits into from
Feb 8, 2024
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
5 changes: 5 additions & 0 deletions ProcessMaker/Filters/Filter.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ class Filter

const TYPE_PARTICIPANTS_FULLNAME = 'ParticipantsFullName';

const TYPE_ASSIGNEES_FULLNAME = 'AssigneesFullName';

const TYPE_STATUS = 'Status';

const TYPE_FIELD = 'Field';
Expand Down Expand Up @@ -200,6 +202,9 @@ private function valueAliasMethod()
case self::TYPE_PARTICIPANTS_FULLNAME:
$method = 'valueAliasParticipantByFullName';
break;
case self::TYPE_ASSIGNEES_FULLNAME:
$method = 'valueAliasAssigneeByFullName';
break;
case self::TYPE_STATUS:
$method = 'valueAliasStatus';
break;
Expand Down
4 changes: 3 additions & 1 deletion ProcessMaker/Filters/SaveSession.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,9 @@ public static function getConfigFilter(String $name, Object $user)
{
$key = self::getKey($user, $name);

return self::get($key, []);
$default = ['filters' => []];

return self::get($key, $default);
}

/**
Expand Down
3 changes: 2 additions & 1 deletion ProcessMaker/Http/Controllers/TaskController.php
Original file line number Diff line number Diff line change
Expand Up @@ -131,8 +131,9 @@ public function edit(ProcessRequestToken $task, string $preview = '')
'lastname',
'avatar',
'timezone',
'datetime_format'
'datetime_format',
]);

return view('tasks.edit', [
'task' => $task,
'dueLabels' => self::$dueLabels,
Expand Down
40 changes: 27 additions & 13 deletions ProcessMaker/Models/ProcessRequestToken.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,12 @@
* @property string $element_id
* @property string $element_type
* @property string $status
* @property \Carbon\Carbon $completed_at
* @property \Carbon\Carbon $due_at
* @property \Carbon\Carbon $initiated_at
* @property \Carbon\Carbon $riskchanges_at
* @property \Carbon\Carbon $updated_at
* @property \Carbon\Carbon $created_at
* @property Carbon $completed_at
* @property Carbon $due_at
* @property Carbon $initiated_at
* @property Carbon $riskchanges_at
* @property Carbon $updated_at
* @property Carbon $created_at
* @property ProcessRequest $processRequest
*
* @OA\Schema(
Expand Down Expand Up @@ -332,7 +332,7 @@ public function getScreen(): ?Screen
// It uses a try-catch block to handle any exceptions that might occur, for example in test environments.
try {
$localName = $this->getBpmnDefinition()->localName;
} catch (\Throwable $t) {
} catch (Throwable $t) {
$localName = null;
}
$isManualTask = $localName === 'manualTask';
Expand Down Expand Up @@ -457,7 +457,7 @@ public function getAdvanceStatusAttribute()
/**
* Check if the user has access to reassign this task
*
* @param \ProcessMaker\Models\User $user
* @param User $user
*/
public function authorizeReassignment(User $user)
{
Expand Down Expand Up @@ -616,7 +616,7 @@ public function fieldAliasCompleted()

public function fieldAliasUser_Id()
{
return 'user_id';
return 'process_request_tokens.user_id';
}

/**
Expand Down Expand Up @@ -665,9 +665,9 @@ public function valueAliasStatus($value, $expression, $callback = null, User $us
} elseif (array_key_exists($value, $statusMap)) {
$query->where('is_self_service', 0);
if ($expression->operator == '=') {
$query->whereIn('status', $statusMap[$value]);
$query->whereIn('process_request_tokens.status', $statusMap[$value]);
} elseif ($expression->operator == '!=') {
$query->whereNotIn('status', $statusMap[$value]);
$query->whereNotIn('process_request_tokens.status', $statusMap[$value]);
}
} else {
$query->where('status', $expression->operator, $value)
Expand Down Expand Up @@ -758,6 +758,20 @@ public function valueAliasProcess_Name(string $value, Expression $expression): c
};
}

/**
* PMQL value alias for assignee field by fullname.
* @param string $value
* @return callable
*/
public function valueAliasAssigneeByFullName($value, $expression)
{
return function ($query) use ($expression, $value) {
$query->whereHas('user', function ($query) use ($expression, $value) {
$query->whereRaw("CONCAT(firstname, ' ', lastname) " . $expression->operator . ' ?', [$value]);
});
};
}

/**
* PMQL wildcard for process request & data fields
*
Expand Down Expand Up @@ -909,8 +923,8 @@ public function persistUserData($user)
/**
* Log an error when executing the token
*
* @param \Throwable $error
* @param \ProcessMaker\Nayra\Contracts\Bpmn\FlowElementInterface $bpmnElement
* @param Throwable $error
* @param FlowElementInterface $bpmnElement
*/
public function logError(Throwable $error, FlowElementInterface $bpmnElement)
{
Expand Down
114 changes: 75 additions & 39 deletions resources/js/common/PMColumnFilterPopoverCommonMixin.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { get, cloneDeep } from "lodash";

const PMColumnFilterCommonMixin = {
data() {
return {
Expand All @@ -9,6 +11,22 @@ const PMColumnFilterCommonMixin = {
};
},
methods: {
storeFilterConfiguration() {
const { order, type } = this.filterConfiguration();
let url = "users/store_filter_configuration/";
if (this.$props.columns && this.savedSearch) {
url += "savedSearch|" + this.savedSearch;
} else {
url += type;
}
let config = {
filters: this.formattedFilter(),
order
};
ProcessMaker.apiClient.put(url, config);
window.ProcessMaker.advanced_filter = config;
window.ProcessMaker.EventBus.$emit("advanced-filter-updated");
},
getViewConfigFilter() {
return [
{
Expand Down Expand Up @@ -67,15 +85,31 @@ const PMColumnFilterCommonMixin = {
}
];
},
onApply(json, index) {
let oldValue, type, value;
addAliases(json, key, label) {
let type, value;
for (let i in json) {
oldValue = json[i].subject.value;
type = this.getTypeColumnFilter(oldValue);
value = this.getAliasColumnForFilter(oldValue);
type = this.getTypeColumnFilter(key, json[i].subject.type);
value = this.getAliasColumnForFilter(key, json[i].subject.value);
json[i].subject.type = type;
json[i].subject.value = value;
json[i]._column_field = key;
json[i]._column_label = label;

if (json[i].or && json[i].or.length > 0) {
this.addAliases(json[i].or, key, label);
}
}
},
getTypeColumnFilter(field, defaultType = 'Field') {
return this.tableHeaders.find(column => column.field === field)?.filter_subject?.type || defaultType;
},
getAliasColumnForFilter(field, defaultValue) {
return this.tableHeaders.find(column => column.field === field)?.filter_subject?.value || defaultValue;
},
getAliasColumnForOrderBy(value) {
return this.tableHeaders.find(column => column.field === value)?.order_column || value;
},
onApply(json, index) {
this.advancedFilterInit();
this.advancedFilter[index] = json;
this.markStyleWhenColumnSetAFilter();
Expand All @@ -101,9 +135,20 @@ const PMColumnFilterCommonMixin = {
object.$refs.pmColumnFilterForm.setValues(this.advancedFilter[index]);
}
},
formattedFilter() {
const filterCopy = cloneDeep(this.advancedFilter);
Object.keys(filterCopy).forEach((key) => {
if (filterCopy[key].length === 0) {
delete filterCopy[key];
}
const label = this.tableHeaders.find(column => column.field === key)?.label;
this.addAliases(filterCopy[key], key, label);
});
return Object.values(filterCopy).flat(1);
},
getAdvancedFilter() {
let flat = this.json2Array(this.advancedFilter).flat(1);
return flat.length > 0 ? "&advanced_filter=" + encodeURIComponent(JSON.stringify(flat)) : "";
let formattedFilter = this.formattedFilter();
return formattedFilter.length > 0 ? "&advanced_filter=" + encodeURIComponent(JSON.stringify(formattedFilter)) : "";
},
getUrlUsers(filter) {
let page = 1;
Expand All @@ -122,8 +167,12 @@ const PMColumnFilterCommonMixin = {
let format = "string";
if (column.format) {
format = column.format;
if (format === "int") {
// We don't have a field for integers
format = "string";
}
}
if (column.field === "status" || column.field === "assignee") {
if (column.field === "status") {
format = "stringSelect";
}
return format;
Expand All @@ -133,17 +182,14 @@ const PMColumnFilterCommonMixin = {
if (column.field === "status") {
formatRange = this.getStatus();
}
if (column.field === "assignee") {
formatRange = this.viewAssignee;
}
return formatRange;
},
getOperators(column) {
let operators = [];
if (column.field === "case_title" || column.field === "name" || column.field === "process" || column.field === "task_name" || column.field === "participants") {
if (column.field === "case_title" || column.field === "name" || column.field === "process" || column.field === "task_name" || column.field === "participants" || column.field === "assignee") {
operators = ["=", "in", "contains", "regex"];
}
if (column.field === "status" || column.field === "assignee") {
if (column.field === "status") {
operators = ["=", "in"];
}
if (column.field === "initiated_at" || column.field === "completed_at" || column.field === "due_at") {
Expand Down Expand Up @@ -208,35 +254,25 @@ const PMColumnFilterCommonMixin = {
}
}
},
getFilterConfiguration(name) {
if ("filter_user" in window.Processmaker) {
this.setFilterPropsFromConfig(window.Processmaker.filter_user);
return;
}
let url = "users/get_filter_configuration/" + name;
ProcessMaker.apiClient.get(url).then(response => {
this.setFilterPropsFromConfig(response.data.data);
getFilterConfiguration() {
const filters = {};
get(window, 'ProcessMaker.advanced_filter.filters', []).forEach((filter) => {
const key = filter._column_field;
if (!(key in filters)) {
filters[key] = [];
}
filters[key].push(filter);
});
},
setFilterPropsFromConfig(config) {
if (typeof config !== "object") {
config = {};
}
if ("filter" in config && typeof config.filter === "object") {
this.advancedFilter = config.filter;
}
if (config?.order?.by && config?.order?.direction) {
this.setOrderByProps(config.order.by, config.order.direction);
this.advancedFilter = filters;

const order = get(window, 'ProcessMaker.advanced_filter.order');
if (order?.by && order?.direction) {
this.setOrderByProps(order.by, order.direction);
}

this.markStyleWhenColumnSetAFilter();
window.ProcessMaker.EventBus.$emit("advanced-filter-updated");
},
json2Array(json) {
let result = [];
for (let i in json) {
result.push(json[i]);
}
return result;
}
}
};
export default PMColumnFilterCommonMixin;
export default PMColumnFilterCommonMixin;
48 changes: 48 additions & 0 deletions resources/js/common/advancedFilterStatusMixin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { get } from "lodash";

export default {
data() {
return {
advancedFilter: [],
};
},
mounted() {
this.setAdvancedFilter();
window.ProcessMaker.EventBus.$on('advanced-filter-updated', this.setAdvancedFilter);
},
methods: {
setAdvancedFilter() {
this.advancedFilter = get(window, 'ProcessMaker.advanced_filter.filters', []);
},
formatForBadge(filters, result) {
for(const filter of filters) {
result.push([
this.formatBadgeSubject(filter),
[{name: this.formatBadgeValue(filter), advanced_filter: true}]
]);

if (filter.or && filter.or.length > 0) {
this.formatForBadge(filter.or, result);
}
}
},
formatBadgeSubject(filter) {
return get(filter, '_column_label', '');
},
formatBadgeValue(filter) {
let result = filter.operator;
result = result + " " + filter.value;
return result;
},
},
computed: {
formatAdvancedFilterForBadges() {
if (!this.advancedFilter || this.advancedFilter.length === 0) {
return [];
}
const result = [];
this.formatForBadge(this.advancedFilter, result);
return result;
},
},
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,9 @@
popoverShow: false
};
},
updated() {
this.$emit("onUpdate", this);
},
methods: {
onShown() {
this.$emit("onUpdate", this);
this.focusCancelButton();
this.closeOnBlur();
},
Expand Down
Loading