feat(automations): multi-option form-field conditions (all / any / none / exact)

This commit is contained in:
2026-10-11 17:26:17 +03:30
parent f4398cdb3e
commit b43ed68e82
6 changed files with 93 additions and 16 deletions
@@ -10,6 +10,7 @@ import {
AUTOMATION_NOTIFY_CHANNEL_LABELS,
AUTOMATION_TRIGGER_LABELS,
MAX_AUTOMATION_STEPS,
formConditionValues,
isAutomationCondition,
splitAutomationBranches,
type AutomationAction,
@@ -174,7 +175,8 @@ function stepHint(step: AutomationStep) {
const opLabel = AUTOMATION_CONDITION_OP_LABELS[op];
if (step.conditionField === 'form_field') {
if (op === 'is_set' || op === 'is_empty') return opLabel;
return `${opLabel} «${step.conditionValue ?? ''}»`;
const joiner = op === 'contains_any' || op === 'not_contains' ? ' یا ' : ' و ';
return `${opLabel} ${formConditionValues(step).map((v) => `«${v}»`).join(joiner) || '«»'}`;
}
if (step.conditionField === 'deal_amount' && step.conditionValue != null) {
return `${opLabel} ${toFaDigits(Number(step.conditionValue))}`;
@@ -28,6 +28,7 @@ import {
AUTOMATION_TRIGGER_LABELS,
conditionFieldsForTrigger,
conditionOpsForField,
formConditionValues,
isAutomationCondition,
} from '@mento/shared';
@@ -127,6 +128,24 @@ function setConditionKey(step: AutomationStep, key: string) {
step.conditionKey = key || null;
const field = formFields.value.find((f) => f.key === key);
step.conditionValue = field?.options?.[0] ?? '';
step.conditionValues = step.conditionValue ? [step.conditionValue] : [];
}
function toggleConditionValue(step: AutomationStep, option: string, on: boolean) {
const cur = formConditionValues(step).filter((v) => v !== option);
if (on) cur.push(option);
const order = conditionFormField.value?.options ?? [];
cur.sort((a, b) => order.indexOf(a) - order.indexOf(b));
step.conditionValues = cur;
step.conditionValue = cur[0] ?? '';
}
function multiValueHint(op: AutomationConditionOp | undefined) {
if (op === 'contains_any') return 'کافی است حداقل یکی از این گزینه‌ها انتخاب شده باشد.';
if (op === 'not_contains') return 'هیچ‌کدام از این گزینه‌ها نباید انتخاب شده باشد.';
if (op === 'eq') return 'دقیقاً همین گزینه‌ها (نه بیشتر و نه کمتر) باید انتخاب شده باشند.';
if (op === 'neq') return 'برقرار است مگر این‌که دقیقاً همین گزینه‌ها انتخاب شده باشند.';
return 'همهٔ این گزینه‌ها باید با هم انتخاب شده باشند.';
}
const activityTypes: Array<{ value: ActivityType; label: string }> = [
@@ -155,6 +174,7 @@ function setAction(step: AutomationStep, action: AutomationAction) {
function setConditionField(step: AutomationStep, field: AutomationConditionField) {
step.conditionField = field;
step.conditionKey = null;
step.conditionValues = [];
if (field === 'deal_amount') {
step.conditionOp = 'gte';
step.conditionValue = typeof step.conditionValue === 'number' ? step.conditionValue : 0;
@@ -289,12 +309,20 @@ watch(
</select>
</label>
<template v-if="selectedStep.conditionField === 'form_field' && needsConditionValue">
<label v-if="conditionFormField?.options?.length">
گزینه
<select v-model="selectedStep.conditionValue">
<option v-for="o in conditionFormField.options" :key="o" :value="o">{{ o }}</option>
</select>
</label>
<div v-if="conditionFormField?.options?.length" class="user-picks">
<p class="field-label">گزینه‌ها (یک یا چند مورد)</p>
<label v-for="o in conditionFormField.options" :key="o" class="ch">
<input
type="checkbox"
:checked="formConditionValues(selectedStep).includes(o)"
@change="toggleConditionValue(selectedStep, o, ($event.target as HTMLInputElement).checked)"
/>
{{ o }}
</label>
<p v-if="formConditionValues(selectedStep).length > 1" class="hint">
{{ multiValueHint(selectedStep.conditionOp) }}
</p>
</div>
<label v-else>
مقدار
<input v-model.trim="selectedStep.conditionValue" type="text" maxlength="200" />