Skip to content

Actions JS Console #1853

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
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
Event handlers for all components.
  • Loading branch information
kamalqureshi authored and raheeliftikhar5 committed Jul 22, 2025
commit 79b5e83bbdda8d0e2bf11d1fe97f433678c4c0bc
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export const actionCategories: ActionCategory[] = [
{
key: 'layout',
label: 'Layout',
actions: [changeLayoutAction, updateDynamicLayoutAction]
actions: [updateDynamicLayoutAction]
},
{
key: 'events',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,182 @@
/**
* Event Names:
* - click: Triggered when component is clicked
* - change: Triggered when component value changes
* - focus: Triggered when component gains focus
* - blur: Triggered when component loses focus
* - submit: Triggered when form is submitted
* - refresh: Triggered when component is refreshed
*
* Action Types:
* - executeQuery: Run a data query
* - message: Show a notification message
* - setTempState: Set a temporary state value
* - runScript: Execute JavaScript code
* - executeComp: Control another component
* - goToURL: Navigate to a URL
* - copyToClipboard: Copy data to clipboard
* - download: Download data as file
* - triggerModuleEvent: Trigger a module event
* - openAppPage: Navigate to another app page
*/

import { message } from "antd";
import { ActionConfig, ActionExecuteParams } from "../types";
import { getEditorComponentInfo } from "../utils";
import { pushAction } from "comps/generators/list";

export const addEventHandlerAction: ActionConfig = {
key: 'add-event-handler',
label: 'Add event handler',
category: 'events',
requiresEditorComponentSelection: true,
requiresInput: true,
inputPlaceholder: 'Enter event handler code (JavaScript)',
inputType: 'textarea',
inputPlaceholder: 'Format: eventName: actionType (e.g., "click: message", "change: executeQuery", "focus: setTempState")',
inputType: 'text',
validation: (value: string) => {
const [eventName, actionType] = value.split(':').map(s => s.trim());
if (!eventName || !actionType) {
return 'Please provide both event name and action type separated by colon (e.g., "click: message")';
}

const validActionTypes = [
'executeQuery', 'message', 'setTempState', 'runScript',
'executeComp', 'goToURL', 'copyToClipboard', 'download',
'triggerModuleEvent', 'openAppPage'
];

if (!validActionTypes.includes(actionType)) {
return `Invalid action type. Valid types: ${validActionTypes.join(', ')}`;
}

return null;
},
execute: async (params: ActionExecuteParams) => {
const { selectedEditorComponent, actionValue } = params;
const { selectedEditorComponent, actionValue, editorState } = params;

const componentInfo = getEditorComponentInfo(editorState, selectedEditorComponent as string);

if (!componentInfo) {
message.error(`Component "${selectedEditorComponent}" not found`);
return;
}

const { allAppComponents } = componentInfo;
const targetComponent = allAppComponents.find(comp => comp.name === selectedEditorComponent);

if (!targetComponent?.comp?.children?.onEvent) {
message.error(`Component "${selectedEditorComponent}" does not support event handlers`);
return;
}

// ----- To be Removed after n8n integration ------ //
const [eventName, actionType] = actionValue.split(':').map(s => s.trim());

if (!eventName || !actionType) {
message.error('Please provide event name and action type in format: "eventName: actionType"');
return;
}
const eventConfigs = targetComponent.comp.children.onEvent.getEventNames?.() || [];
const availableEvents = eventConfigs.map((config: any) => config.value);

if (!availableEvents.includes(eventName)) {
const availableEventsList = availableEvents.length > 0 ? availableEvents.join(', ') : 'none';
message.error(`Event "${eventName}" is not available for this component. Available events: ${availableEventsList}`);
return;
}
// ----- To be Removed after n8n integration ------ //


const eventHandler = {
name: eventName,
handler: {
compType: actionType,
comp: getActionConfig(actionType, editorState)
}
};

try {
targetComponent.comp.children.onEvent.dispatch(pushAction(eventHandler));
message.success(`Event handler for "${eventName}" with action "${actionType}" added successfully!`);
} catch (error) {
console.error('Error adding event handler:', error);
message.error('Failed to add event handler. Please try again.');
}
}
};

// A Hardcoded function to get action configuration based on action type
// This will be removed after n8n integration
function getActionConfig(actionType: string, editorState: any) {
switch (actionType) {
case 'executeQuery':
const queryVariables = editorState
?.selectedOrFirstQueryComp()
?.children.variables.toJsonValue();

return {
queryName: editorState
?.selectedOrFirstQueryComp()
?.children.name.getView(),
queryVariables: queryVariables?.map((variable: any) => ({...variable, value: ''})),
};

case 'message':
return {
text: "Event triggered!",
level: "info",
duration: 3000
};

case 'setTempState':
return {
state: "tempState",
value: "{{eventData}}"
};

case 'runScript':
return {
script: "console.log('Event triggered:', eventData);"
};

case 'executeComp':
return {
compName: "",
methodName: "",
params: []
};

case 'goToURL':
return {
url: "https://example.com",
openInNewTab: false
};

case 'copyToClipboard':
return {
value: "{{eventData}}"
};

case 'download':
return {
data: "{{eventData}}",
fileName: "download.txt",
fileType: "text/plain"
};

case 'triggerModuleEvent':
return {
name: "moduleEvent"
};

console.log('Adding event handler to component:', selectedEditorComponent, 'with code:', actionValue);
message.info(`Event handler added to component "${selectedEditorComponent}"`);
case 'openAppPage':
return {
appId: "",
queryParams: [],
hashParams: []
};

// TODO: Implement actual event handler logic
default:
return {};
}
};
}