
Research
/Security News
9 Malicious NuGet Packages Deliver Time-Delayed Destructive Payloads
Socket researchers discovered nine malicious NuGet packages that use time-delayed payloads to crash applications and corrupt industrial control systems.
@bigbinary/neeto-rules-frontend
Advanced tools
A repo acts as the source of truth for the new nano's structure, configs, data etc.
The neeto-rules-nano facilitates the management of automation rules within
neeto applications. The nano exports @bigbinary/neeto-rules-frontend NPM
package and neeto-rules-engine Rails engine.
The Engine is used to manage automation rules feature within neeto applications.
Add this line to your application's Gemfile:
source "NEETO_GEM_SERVER_URL" do
# ..existing gems
gem "neeto-rules-engine"
end
And then execute:
bundle install
Add this line to your application's config/routes.rb file:
mount NeetoRulesEngine::Engine, at: "/neeto_rules"
NOTE: The mount point must be /neeto_rules and cannot be changed to any
other path.
Run the following command to copy the migrations from the engine to the host application:
bundle exec rails neeto_rules_engine:install:migrations
Add the migrations to the database:
bundle exec rails db:migrate
Install the latest neetoRules nano package using the below command:
yarn add @bigbinary/neeto-rules-frontend
Check the Frontend package development guide for step-by-step instructions to develop the frontend package.
NeetoRulesThe NeetoRules component is used to add the dashboard for automation rules.

breadcrumbs: Breadcrumbs for the header of the dashboard.
text: Text for breadcrumb itemlink: Link to breadcrumb itemallowReordering: To specify if the user can reorder the automation rules.
(Boolean).
helpPopoverProps: To add help popover for the component. Refer
HelpPopover component doc.
NOTE: href from helpLinkProps will be used for displaying the link when
showing NoData component.
rulesTableProps: Props for the table in the dashboard:
additionalColumns: To add additional columns to the table. Refer
Table component doc.const additionalColumns = [
{
title: "Operated on",
dataIndex: "recentlyModifiedTickets",
width: 160,
description:
"Number of tickets the rule has acted upon in the last 7 days",
render: recentlyModifiedTickets => (
<div className="text-center">{recentlyModifiedTickets}</div>
),
},
];
moreDropdownItems: Array of dropdown items to be added to the
MoreDropdown component in the table. Refer
MoreDropdown in table doc.const moreDropdownItems = [
{
key: "view-matching-tickets",
label: "View matching rules",
// onClick callback receives the selected rule
onClick: rule => {
setSelectedRule(rule);
setShowMatchingTickets(true);
},
},
];
onPreview: The callback function to call when the preview is clicked.const onPreview = id => {
setRuleId(id);
};
payloadKey: Key to be used in the payload object to specify the target.
If not provided uses rule by default.automationRulesPath: The path for automation rules dashboard.
Following additional routes are considered by the component:
| Routes | Description |
|---|---|
{automationRulesPath}/edit | Route to the rule edit form component. |
{automationRulesPath}/new | Route to the rule create form component. |
automationRulesEndpoint: The endpoint for automation rules.
Following endpoints will be used by the component:
| Endpoint | Action | Description |
|---|---|---|
GET {automationRulesEndpoint} | index | To fetch the list of automation rules.(Same will be used for pagination/filtering) |
POST {automationRulesEndpoint}/{id}/clone | clone | To create the clone of the automation rule. |
PATCH {automationRulesEndpoint}/{id} | update | To update the status of the automation rule. |
DELETE {automationRulesEndpoint}/{id} | destroy | To delete the automation rule. |
PATCH {automationRulesEndpoint}/reorder | reorder | To reorder the automation rules. |
updateRule: Object that define methods for update rule operation.
onSuccess: Object for handling update rule success callback.
callback: Function to be called on success. (Optional)deleteRule: Object that define methods for delete rule operation.
onSuccess: Object for handling delete rule success callback.
callback: Function to be called on success. (Optional)cloneRule: Object that define methods for clone rule operation.
allowed: To specify if the clone rule should be allowed, default true.
(Boolean)onSuccess: Object for handling clone rule success callback.
callback: Function to be called on success. (Optional)reoderRules: Function to be called on reorder success.
onSuccess: Object for handling reorder rule success callback.
callback: Function to be called on success. (Optional)headerProps: Props for the header component. Refer
Header component doc.
NeetoRulesForm
The NeetoRulesForm component is used to create and edit automation rules.
NeetoRulesForm accepts the following field types which is specified in the
initialProps
(reference):
Note: The
NeetoRulesFormcomponent includes three fields by default with the following names:name(required),descriptionandstatus.
data: The initial props for the form.children: The form fields.className: To provide external classes to form.handleSubmit: The function to handle the form submission.handleClose: The function to handle the form close.showStatusSwitch: To specify whether the status switch should be shown or
not. It is true by default.import { NeetoRulesForm } from "@bigbinary/neeto-rules-frontend";
const {
InputField,
TextareaField,
SelectField,
Events,
Card,
Conditions,
Actions,
} = NeetoRulesForm;
<NeetoRulesForm data={initialProps}>
{({ formattedValues, values, ...formikBag }) => (
<>
<InputField name="name" data={initialProps} />
<TextareaField name="description" data={initialProps} />
<SelectField name="projectId" data={initialProps} />
<Events name="events" data={initialProps} performerName="performer" />
<Card title="Conditions">
<Conditions name="conditions" data={initialProps} />
</Card>
<Actions name="actions" data={initialProps} />
</>
)}
</NeetoRulesForm>;
NeetoRulesFormNeetoRulesForm provides field components to create the automation rules form.
InputFieldimport { NeetoRulesForm } from "@bigbinary/neeto-rules-frontend";
const { InputField } = NeetoRulesForm;
const initialProps = {
...otherProps,
firstName: {
label: "First Name",
type: "text",
value: "", // Default value.
componentProps: {
placeholder: "Enter name",
},
},
};
<InputField name="firstName" data={initialProps} />;
name: Name of the field. The name should be same as that in the
initialProps.data: The same initialProps that is passed to data prop in
NeetoRulesForm.label: Label for the field.TextareaFieldimport { NeetoRulesForm } from "@bigbinary/neeto-rules-frontend";
const { TextareaField } = NeetoRulesForm;
const initialProps = {
...otherProps,
description: {
label: "Description",
type: "long-text",
value: "", // Default value.
},
};
<TextareaField name="description" data={initialProps} />;
name: Name of the field. The name should be same as that in the
initialProps.data: The same initialProps that is passed as data prop in
NeetoRulesForm.label: Label for the field.SelectFieldimport { NeetoRulesForm } from "@bigbinary/neeto-rules-frontend";
const { SelectField } = NeetoRulesForm;
const initialProps = {
...otherProps,
user: {
label: "Project",
type: "dropdown",
options: [{ label: "Oliver", value: "oliver" }],
value: "oliver", // Default selected option will be Oliver
},
};
<SelectField name="user" data={initialProps} />;
name: Name of the field. The name should be same as that in the
initialProps.data: The same initialProps that is passed to data prop in
NeetoRulesForm.label: Label for the field.options: Options for the dropdown. The options should be an array of
objects with label and value keys. [{label, value}].onChange: Callback function that is called when the value of the dropdown
changes. (value, setValue) => void setValue is to set the new value.MultiSelectFieldimport { NeetoRulesForm } from "@bigbinary/neeto-rules-frontend";
const { MultiSelectField } = NeetoRulesForm;
const initialProps = {
...otherProps,
users: {
label: "Projects",
type: "multi-select",
options: [
{ label: "Oliver", value: "oliver" },
{ label: "John", value: "john" },
],
value: ["oliver"], // Default selected option will be Oliver
},
};
<MultiSelectField name="users" data={initialProps} />;
name: Name of the field. The name should be same as that in the
initialProps.data: The same initialProps that is passed to data prop in
NeetoRulesForm.label: Label for the field.options: Options for the dropdown. The options should be an array of
objects with label and value keys. [{label, value}].onChange: Callback function that is called when the value of the dropdown
changes. (value, setValue) => void setValue is to set the new value.RadioFieldimport { NeetoRulesForm } from "@bigbinary/neeto-rules-frontend";
const { RadioField } = NeetoRulesForm;
const initialProps = {
...otherProps,
performer: {
label: "Performer",
type: "radio",
value: "any", // Default selected value will be "any"
options: [
{ label: "Admin", value: "admin" },
{ label: "Any", value: "any" },
],
},
};
<RadioField name="performer" data={initialProps} />;
name: Name of the field. The name should be same as that in the
initialProps.data: The same initialProps that is passed to data prop in
NeetoRulesForm.label: Label for the field.options: Options for the radio buttons. The options should be an array of
objects with label and value keys. [{label, value}].EventConditions
import { NeetoRulesForm } from "@bigbinary/neeto-rules-frontend";
const { EventConditions } = NeetoRulesForm;
const EVENT_OPTIONS = [
{ label: "Ticket is created", value: "created" },
{ label: "Ticket is updated", value: "updated" },
...otherOptions,
];
const PERFORMER_OPTIONS = [
{ label: "Any", value: "any" },
{ label: "Member", value: "agent" },
...otherOptions,
];
const CONDITION_OPTIONS = [
{
value: "status",
label: "Status",
type: "multi-select",
allowMatching: ["any_of", "none_of"],
dropdownOptions: [
{ label: "Open", value: "open" },
{ label: "Closed", value: "closed" },
{ label: "On hold", value: "on_hold" },
],
},
{
value: "name",
label: "Name",
allowMatching: ["is", "is_not"],
type: "text",
},
...otherOptions,
];
const DEFAULT_CONDITION_VALUE = [
{
id: "1",
field: "status",
verb: "any_of",
metadata: { values: ["open", "closed"] },
joinType: "and_operator",
},
{
id: "2",
field: "name",
verb: "is",
metadata: { value: "Test" },
joinType: "and_operator",
},
...otherConditionValues,
];
const initialProps = {
...otherProps,
events: {
label: "Events",
type: "events",
value: [{ name: EVENT_OPTIONS[0].value }],
eventOptions: EVENT_OPTIONS,
defaultData: { name: "time_based", performer: "system" },
},
performer: {
label: "Performer",
type: "dropdown",
value: "any",
options: PERFORMER_OPTIONS,
},
conditions: {
label: "Conditions",
type: "condition",
conditionOptions: CONDITION_OPTIONS,
value: DEFAULT_CONDITION_VALUE,
},
execution_delay: {
value: { value: 2, unit: "minutes" },
defaultValue: { value: 2, unit: "minutes" },
type: "execution-delay",
};
<EventConditions
name="events"
data={initialProps}
performerName="performer"
conditionsName="conditions"
/>;
name: Name of the field. The name should be same as that in the
initialProps.data: The same initialProps that is passed to data prop in
NeetoRulesForm.label: Label for the field.performerName: Name of the performer field. The performerName should be
same as that in the initialProps.conditionsName: Name of the conditions field. The conditionsName should
be same as that in the initialProps.onSelectEvent: (name, selectedOption) => void. This method will trigger
when we select an event option. The name is to refer the event in the formik
context.enableAddingDelay: Adds option to add execution delay. (Boolean). Ref:
NeetoForm PR#11704Refer to the EventCondition section for more information.
Conditionsimport { NeetoRulesForm } from "@bigbinary/neeto-rules-frontend";
const { Card, Conditions } = NeetoRulesForm;
const initialProps = {
...otherProps,
conditions: {
label: "Conditions",
type: "condition",
conditionOptions: [
{
value: "status",
label: "Status",
type: "dropdown", // Types : text, number, email, decimal, url, dropdown, multi-select, multi-select-create, date, time.
allowMatching: ["is", "is_not", "any_of", "none_of"],
dropdownOptions: [
{ label: "Open", value: "open" },
{ label: "Closed", value: "closed" },
],
additionalData: {
any_of: "multi-select",
none_of: "multi-select",
},
},
{
value: "name",
label: "Name",
type: "text",
allowMatching: ["is", "is_not"],
},
{
value: "tags",
label: "Tags",
type: "multi-select-create",
allowMatching: ["contains_any_of", "contains_none_of"],
},
],
value: [
{
id: "1",
field: "status",
verb: "is",
metadata: { value: "open" },
joinType: "and_operator",
},
{
id: "2",
field: "name",
verb: "is",
metadata: { value: "Test" },
joinType: "and_operator",
},
{
id: "3",
field: "tags",
verb: "contains_any_of",
metadata: { values: ["Test", "Open"] },
joinType: "and_operator",
},
],
},
};
<Card title="Conditions">
<Conditions name="conditions" data={initialProps} />
</Card>;
name: Name of the field. The name should be same as that in the
initialProps.data: The same initialProps that is passed to data prop in
NeetoRulesForm.label: Label for the field.onSelectCondition: (name, selectedOption) => void. This method will
trigger when we select a condition option. The name is to refer the condition
in the formik context.selectedConditionOptions: (selectedCondition)=> [{label, value}]. To
provide options for the selected condition if the type of selected condition
is dropdown, multi-select, or multi-select-create.isCallback: To specify if there is a preview callback function for the
conditions. (Boolean).previewCallback: (conditions) => void. This method will trigger when we
click on the preview button. The conditions are the selected conditions in
the formik context.Actions
import { NeetoRulesForm } from "@bigbinary/neeto-rules-frontend";
const { Actions } = NeetoRulesForm;
const initialProps = {
...otherProps,
actions: {
label: "Actions",
type: "actions",
actionOptions: [
{
value: "add_tags",
label: "Add Tags",
type: "multiSelect", // Types : emailToIds, emailTo, email, dropdown, list, multiSelect, note, date, text, textarea, decimal, number, regex, longText, sms, smsToNumbers, smsTo, sendToApi
hideSeparator: true,
placeholder: "Select tags",
dropdownOptions: [
{ label: "Open", value: "open" },
{ label: "Close", value: "close" },
{ label: "Hold", value: "hold" },
],
},
{
value: "email_to_agent",
label: "Email To Agent",
type: "emailTo",
separator: ["with the name", "with the content"],
hideSubject: true,
},
{
value: "email_to",
label: "Email To",
type: "emailToIds",
separator: "as",
hideSubject: true, // Hide subject field if this prop is true
maxLimit: 5, // Adds validation to limit up to specified number of email addresses
},
{
value: "send_sms",
label: "Send sms",
type: "longText",
},
],
value: [
{
id: "1",
name: "email_to", // Specify the value of the selected action.
metadata: { emails: ["a@a.com"], subject: "test", body: "test" },
},
{
id: "2",
name: "add_tags",
metadata: { values: ["close"] },
},
],
},
};
<Actions name="fieldName" data={initialProps} />;
name: Name of the field. The name should be same as that in the
initialProps.data: The same initialProps that is passed to data prop in
NeetoRulesForm.label: Label for the field.onSelectAction: (name, selectedOption) => void. This method will trigger
when we select an action option. The name is to refer the action in the
formik context.selectedActionOptions: (selectedAction)=> [{label, value}]. To provide
options for the selected action if the type of selected action is dropdown
or multi-select.separator: Separator to be shown between action sub items. If there is only
one sub item, provide a string value. If there are multiple sub items,
provide an array of separators.isSaveAsTemplateEnabled: To allow users to save the contents of current
message as a new template.Refer to the Actions section for more information.
neetoRulesFrontend allows to pass custom action components from host application. Below is an example for customize task component which is being sent by neeto-crm in action options.
{
label: "Add task",
value: "add_task",
placeholder: "Task",
component: TaskComponent,
validation: TASK_VALIDATION,
},
neetoRulesFrontend allows to pass predefined email, SMS and API templates from host application. This enables to use templates created using neeto-message-templates-nano. Below is an example for custom message template which is being sent by neeto-form in action options.
{
"label": "Email to responder",
"value": "email_to_responder",
"type": "emailTo",
"templates": [
{
"id": "caca1cc9-f9db-480a-a64f-6ea0c72d4b05",
"name": "Send emails to rejected candidates",
"subject": "Application Status - Screening Round Unsuccessful",
"body": "<p>Dear {{full-name}},</p><p>Thank you for your interest. Unfortunately, we regret to inform you that you did not pass the screener round.</p><p>Best regards, </p><p>Spinkart</p>"
}
]
}
To save the contents of the current message as a new template, set
isSaveAsTemplateEnabled to true. The message contents will then be available
in the values passed to the handleSubmit callback, allowing the host
application to use this data for creating new templates.
You can configure help popovers to appear next to input fields in Email, SMS,
and API actions. To do this, provide the appropriate helpPopoverProps in the
action options.
{
label: t("form.settings.automationRules.actions.sendToApi"),
value: ACTION_OPTIONS.sendToApi,
type: "sendToApi",
helpPopoverProps: {
customHeaders: {
title: "Title for custom headers popover",
description: "Description for custom headers popover.",
helpLinkProps: { href: CUSTOM_HEADERS_HELP_DOC_URL },
},
body: {
title: "Title for API payload popover",
description: "Description for API payload popover.",
helpLinkProps: { href: API_PAYLOAD_HELP_DOC_URL },
},
},
}
Below are the supported actions and fields where help popovers can be displayed:
Email actions:
template: Displays a help popover next to the template dropdownrecipientField: Displays a help popover next to the recipient selection
dropdown (lists records with emails)SMS actions:
template: Displays a help popover next to the template dropdownrecipientField: Displays a help popover next to the recipient selection
dropdown (lists records with phone numbers)API actions:
template: Displays a help popover next to the template dropdowncustomHeaders: Displays a help popover next to the custom headers labelbody: Displays a help popover next to the body labelRulePreviewThe RulePreview component is used to preview the automation rule.

ruleDetails: The rule details to be previewed.isLoading: To specify if the preview is loading. (Boolean).isOpen: To specify if the preview is open. (Boolean).onClose: The callback function to call when the preview is closed.
() => void.AUTOMATION_RULES_QUERY_KEYThe AUTOMATION_RULES_QUERY_KEY is the base query key which is being used as
key for query fetching.
reference:
CannedResponsesPaneThe CannedResponsesPane component is used to preview canned responses and
apply them.
actionNameOptions: An array of actions which any of the canned responses can
do. Each object in the array can have label, value, type, placeholder,
dropdownOptions, defaultData and variables. Out of these,
dropdownOptions, defaultData and variables are optional.areDropdownListsLoading: To specify if the dropdown lists are loading.dropdownList: It is an object of values that are used in the dropdowns. It
can have the keys tags, teams, members, fields, and status, with
their values the respective array of items.isCannedResponsePaneOpen: Boolean to specify if the canned response pane is
open.isLoadingPreview: Boolean to specify if the preview is loading.macros: An array of possible macros/canned responses that the user can
choose from.onApply: Callback function to apply the canned response.onCancel: Callback function to call when the canned response pane is closed.previewCannedResponses: Method which will be used to make the API call to
get the preview of the canned response.previewParams: Object that contains the parameters for the preview API call.variables: An array of variables that can be used in the canned response.
This is an optional prop.import { useState } from "react";
import { CannedResponsesPane } from "@bigbinary/neeto-rules-frontend";
import { usePreviewCannedResponses } from "./hooks";
const Component = ({ visitorId }) => {
const [isCannedResponsePaneOpen, setIsCannedResponsePaneOpen] =
useState(false);
const { mutate: previewCannedResponses, isLoading } =
usePreviewCannedResponses();
const dropdownList = {
status: [
{ label: "Open", value: "open" },
{ label: "Closed", value: "closed" },
],
tags: [
{ label: "Tag 1", value: "tag1" },
{ label: "Tag 2", value: "tag2" },
],
teams: [
{ label: "Team 1", value: "team1" },
{ label: "Team 2", value: "team2" },
],
};
const ACTION_NAME_OPTIONS = [
{
label: "Add reply",
value: "add_reply",
type: "note",
placeholder: "Reply",
},
{
label: "Assign member",
value: "assign_agent",
type: "dropdown",
placeholder: "Select member",
dropdownOptions: [],
defaultData: { actionable_type: "User" },
},
{
label: "Assign team",
value: "assign_group",
type: "dropdown",
placeholder: "Select team",
dropdownOptions: [],
defaultData: { actionable_type: "NeetoTeamMembersEngine::Group" },
},
];
const handleApply = ({
cannedResponse,
setCannedResponse,
onSettled,
updatedValues,
}) => {
// logic to apply canned response
};
return (
<CannedResponsesPane
{...{
dropdownList,
isCannedResponsePaneOpen,
isLoadingPreview,
previewCannedResponses,
}}
actionNameOptions={ACTION_NAME_OPTIONS}
macros={cannedResponses}
previewParams={{ visitorId }}
onApply={handleApply}
onCancel={() => setIsCannedResponsePaneOpen(false)}
/>
);
};
Consult the building and releasing packages guide for details on how to publish.
FAQs
A repo acts as the source of truth for the new nano's structure, configs, data etc.
We found that @bigbinary/neeto-rules-frontend demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 3 open source maintainers collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Research
/Security News
Socket researchers discovered nine malicious NuGet packages that use time-delayed payloads to crash applications and corrupt industrial control systems.

Security News
Socket CTO Ahmad Nassri discusses why supply chain attacks now target developer machines and what AI means for the future of enterprise security.

Security News
Learn the essential steps every developer should take to stay secure on npm and reduce exposure to supply chain attacks.