base_automation/static/src/base_automation_trigger_selection_field.js

125 lines
4.4 KiB
JavaScript

/** @odoo-module */
import { useState } from "@odoo/owl";
import { _lt, _t } from "@web/core/l10n/translation";
import { registry } from "@web/core/registry";
import { useRecordObserver } from "@web/model/relational_model/utils";
import { selectionField, SelectionField } from "@web/views/fields/selection/selection_field";
import { TRIGGER_FILTERS } from "./utils";
import { useService } from "@web/core/utils/hooks";
const OPT_GROUPS = [
{
group: { sequence: 10, key: "values", name: _lt("Values Updated") },
triggers: [
"on_stage_set",
"on_user_set",
"on_tag_set",
"on_state_set",
"on_priority_set",
"on_archive",
"on_unarchive",
],
},
{
group: { sequence: 30, key: "timing", name: _lt("Timing Conditions") },
triggers: ["on_time", "on_time_created", "on_time_updated"],
},
{
group: { sequence: 40, key: "custom", name: _lt("Custom") },
triggers: ["on_create_or_write", "on_unlink", "on_change"],
},
{
group: { sequence: 50, key: "external", name: _lt("External") },
triggers: ["on_webhook"],
},
{
group: { sequence: 20, key: "mail", name: _t("Email Events") },
triggers: ["on_message_sent", "on_message_received"],
},
{
group: { sequence: 60, key: "deprecated", name: _lt("Deprecated (do not use)") },
triggers: ["on_create", "on_write"],
},
];
function computeDerivedOptions(options, fields, currentSelection, { excludeGroups = [] } = {}) {
// filter options to display, derived from the current value and the model fields
const derivedOptions = [];
for (const [value, label] of options) {
const { group, triggers } = OPT_GROUPS.find((g) => g.triggers.includes(value));
if (
(group.key === "deprecated" && !triggers.includes(currentSelection)) ||
excludeGroups.includes(group.key)
) {
// skip deprecated triggers if the current value is not deprecated
continue;
}
const filterFn = TRIGGER_FILTERS[value];
if (filterFn) {
const triggerFields = fields.filter(filterFn);
if (triggerFields.length === 0) {
// skip triggers that don't have any corresponding field
continue;
}
}
const option = { group, value, label };
derivedOptions.push(option);
}
return derivedOptions;
}
export class TriggerSelectionField extends SelectionField {
static template = "base_automation.TriggerSelectionField";
setup() {
super.setup();
this.groupedOptions = useState([]);
const orm = useService("orm");
let lastRelatedModelId;
let relatedModelFields;
useRecordObserver(async (record) => {
const { data, fields } = record;
const modelId = data.model_id?.[0];
if (lastRelatedModelId !== modelId) {
lastRelatedModelId = modelId;
relatedModelFields = await orm.searchRead(
"ir.model.fields",
[["model_id", "=", modelId]],
["field_description", "name", "ttype", "relation"]
);
}
// first, compute the derived options
const derivedOptions = computeDerivedOptions(
fields[this.props.name].selection,
relatedModelFields,
data[this.props.name],
{ excludeGroups: data.model_is_mail_thread ? [] : ["mail"] }
);
// then group and sort them
this.groupedOptions.length = 0;
for (const option of derivedOptions) {
const group = this.groupedOptions.find((g) => g.key === option.group.key) ?? {
...option.group,
options: [],
};
group.options.push(option);
if (!this.groupedOptions.includes(group)) {
this.groupedOptions.push(group);
}
}
this.groupedOptions.sort((a, b) => a.sequence - b.sequence);
});
}
}
export const triggerSelectionField = {
...selectionField,
component: TriggerSelectionField,
fieldDependencies: [{ name: "model_is_mail_thread", type: "boolean" }],
};
registry.category("fields").add("base_automation_trigger_selection", triggerSelectionField);