Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 | 98x 98x 98x 98x 98x 98x 98x 98x 98x 98x 98x 98x 98x 98x 98x 98x 98x 98x 98x 98x 184x 184x 98x 98x 98x 98x 98x 98x 98x 98x 98x 98x 98x 98x 12x 12x 12x 12x 12x 12x 12x 12x 12x 98x 98x 98x 98x 109x 97x 109x 98x 98x 98x 97x 98x 98x 98x 98x 98x 98x 98x 98x 98x 109x 109x 98x 98x 98x 98x 98x 98x 98x | import { SPLIT_GROUPS, FormData, NodeConfig, FlowTypes } from '../types';
import { Node } from '../../store/flow-definition.d';
import { validateWith } from '../utils';
import { buildCategoriesExitsCases } from './shared';
export const split_by_random: NodeConfig = {
type: 'split_by_random',
name: 'Random Split',
group: SPLIT_GROUPS.split,
flowTypes: [FlowTypes.VOICE, FlowTypes.MESSAGE, FlowTypes.BACKGROUND],
form: {
categories: {
type: 'array',
helpText: 'Define the buckets to randomly split contacts into',
required: true,
itemLabel: 'Bucket',
sortable: true,
minItems: 2,
maxItems: 10,
isEmptyItem: (item: any) => {
return !item.name || item.name.trim() === '';
},
itemConfig: {
name: {
type: 'text',
placeholder: 'Bucket name',
required: true
}
}
}
},
layout: ['categories'],
validate: validateWith((formData, errors) => {
if (!formData.categories || !Array.isArray(formData.categories)) return;
const categories = formData.categories.filter(
(item: any) => item?.name && item.name.trim() !== ''
);
if (categories.length < 2) {
errors.categories = 'At least 2 buckets are required for random split';
}
const duplicateCategories: string[] = [];
const lowerCaseMap = new Map<string, string[]>();
categories.forEach((category) => {
const lowerName = category.name.trim().toLowerCase();
if (!lowerCaseMap.has(lowerName)) {
lowerCaseMap.set(lowerName, []);
}
lowerCaseMap.get(lowerName).push(category.name.trim());
});
lowerCaseMap.forEach((originalNames) => {
if (originalNames.length > 1) {
duplicateCategories.push(...originalNames);
}
});
if (duplicateCategories.length > 0) {
const uniqueDuplicates = [...new Set(duplicateCategories)];
errors.categories = `Duplicate bucket names found: ${uniqueDuplicates.join(
', '
)}`;
}
}),
toFormData: (node: Node) => {
// Extract categories from the existing node structure
const categories =
node.router?.categories?.map((cat) => ({ name: cat.name })) || [];
return {
uuid: node.uuid,
categories: categories
};
},
fromFormData: (formData: FormData, originalNode: Node): Node => {
const userCategories = (formData.categories || [])
.filter((item: any) => item?.name?.trim())
.map((item: any) => item.name.trim());
const existingCategories = originalNode.router?.categories || [];
const existingExits = originalNode.exits || [];
const { categories, exits } = buildCategoriesExitsCases(
userCategories.map((name) => ({ name })),
existingCategories,
existingExits
);
return {
uuid: originalNode.uuid,
actions: originalNode.actions || [],
router: {
type: 'random',
categories
},
exits
};
},
router: {
type: 'random'
},
// Localization support for categories
localizable: 'categories'
};
|