diff --git a/public/locales/en.json b/public/locales/en.json
index 0dc833fd..8efb7e5f 100644
--- a/public/locales/en.json
+++ b/public/locales/en.json
@@ -1,657 +1,657 @@
{
- "login": {
- "title": "Welcome to Maxun",
- "email": "Email",
- "password": "Password",
- "button": "Login",
- "loading": "Loading",
- "register_prompt": "Don't have an account?",
- "register_link": "Register",
- "welcome_notification": "Welcome to Maxun!",
- "validation": {
- "required_fields": "Email and password are required",
- "password_length": "Password must be at least 6 characters"
- },
- "error": {
- "user_not_found": "User does not exist",
- "invalid_credentials": "Invalid email or password",
- "server_error": "Login failed. Please try again later",
- "generic": "An error occurred. Please try again"
- }
+ "login": {
+ "title": "Welcome to Maxun",
+ "email": "Email",
+ "password": "Password",
+ "button": "Login",
+ "loading": "Loading",
+ "register_prompt": "Don't have an account?",
+ "register_link": "Register",
+ "welcome_notification": "Welcome to Maxun!",
+ "validation": {
+ "required_fields": "Email and password are required",
+ "password_length": "Password must be at least 6 characters"
},
- "register": {
- "title": "Create An Account",
- "email": "Email",
- "password": "Password",
- "button": "Register",
- "loading": "Loading",
- "register_prompt": "Already have an account?",
- "login_link": "Login",
- "welcome_notification": "Welcome to Maxun!",
- "validation": {
- "email_required": "Email is required",
- "password_requirements": "Password must be at least 6 characters"
- },
- "error": {
- "user_exists": "User with this email already exists",
- "creation_failed": "Could not create account",
- "server_error": "Server error occurred",
- "generic": "Registration failed. Please try again"
- }
+ "error": {
+ "user_not_found": "User does not exist",
+ "invalid_credentials": "Invalid email or password",
+ "server_error": "Login failed. Please try again later",
+ "generic": "An error occurred. Please try again"
+ }
+ },
+ "register": {
+ "title": "Create An Account",
+ "email": "Email",
+ "password": "Password",
+ "button": "Register",
+ "loading": "Loading",
+ "register_prompt": "Already have an account?",
+ "login_link": "Login",
+ "welcome_notification": "Welcome to Maxun!",
+ "validation": {
+ "email_required": "Email is required",
+ "password_requirements": "Password must be at least 6 characters"
},
- "recordingtable":{
- "run": "Run",
- "name": "Name",
- "schedule": "Schedule",
- "integrate": "Integrate",
- "settings": "Settings",
- "options": "Options",
- "heading":"My Robots",
- "new":"Create Robot",
- "search_criteria": "Try adjusting your search criteria",
- "placeholder": {
- "title": "You're All Set to Start",
- "body": "Robots you create will appear here. Click \"Create Robot\" to get started!",
- "search": "No robots match your search"
+ "error": {
+ "user_exists": "User with this email already exists",
+ "creation_failed": "Could not create account",
+ "server_error": "Server error occurred",
+ "generic": "Registration failed. Please try again"
+ }
+ },
+ "recordingtable": {
+ "run": "Run",
+ "name": "Name",
+ "schedule": "Schedule",
+ "integrate": "Integrate",
+ "settings": "Settings",
+ "options": "Options",
+ "heading": "My Robots",
+ "new": "Create Robot",
+ "search_criteria": "Try adjusting your search criteria",
+ "placeholder": {
+ "title": "You're All Set to Start",
+ "body": "Robots you create will appear here. Click \"Create Robot\" to get started!",
+ "search": "No robots match your search"
+ },
+ "modal": {
+ "title": "Enter the URL",
+ "login_title": "Does this website require logging in?",
+ "label": "URL",
+ "button": "Start Recording"
+ },
+ "warning_modal": {
+ "title": "Active Browser Detected",
+ "message": "There is already a browser recording session running. Would you like to discard it and create a new recording?",
+ "discard_and_create": "Discard & Create New",
+ "cancel": "Cancel"
+ },
+ "retrain": "Retrain",
+ "edit": "Edit",
+ "delete": "Delete",
+ "duplicate": "Duplicate",
+ "search": "Search Robots...",
+ "notifications": {
+ "delete_warning": "The robot has associated runs. First delete runs to delete the robot",
+ "delete_success": "Robot deleted successfully",
+ "auth_success": "Robot successfully authenticated",
+ "browser_limit_warning": "Remote browsers are currently busy. Please wait for a few minutes and try again"
+ }
+ },
+ "mainmenu": {
+ "recordings": "Robots",
+ "runs": "Runs",
+ "proxy": "Proxy",
+ "apikey": "API Key",
+ "feedback": "Join Maxun Cloud",
+ "apidocs": "Website To API"
+ },
+ "runstable": {
+ "runs": "All Runs",
+ "runStatus": "Status",
+ "runName": "Name",
+ "name": "Name",
+ "startedAt": "Started At",
+ "finishedAt": "Finished At",
+ "delete": "Delete",
+ "settings": "Settings",
+ "search": "Search Runs...",
+ "sort_tooltip": "Click to sort",
+ "placeholder": {
+ "title": "No Runs Found",
+ "body": "This is where all your robot runs will appear. Once a robot is active, its runs will be logged here.",
+ "search": "No runs match your search"
+ },
+ "notifications": {
+ "no_runs": "No runs found. Please try again.",
+ "delete_success": "Run deleted successfully"
+ }
+ },
+ "proxy": {
+ "title": "Proxy Configuration",
+ "tab_standard": "Standard Proxy",
+ "tab_rotation": "Automatic Proxy Rotation",
+ "server_url": "Proxy Server URL",
+ "server_url_helper": "Proxy to be used for all robots. HTTP and SOCKS proxies are supported. Example http://myproxy.com:3128 or socks5://myproxy.com:3128. Short form myproxy.com:3128 is considered an HTTP proxy.",
+ "requires_auth": "Requires Authentication?",
+ "username": "Username",
+ "password": "Password",
+ "add_proxy": "Add Proxy",
+ "test_proxy": "Test Proxy",
+ "remove_proxy": "Remove Proxy",
+ "table": {
+ "proxy_url": "Proxy URL",
+ "requires_auth": "Requires Authentication"
+ },
+ "coming_soon": "Coming Soon - In Open Source (Basic Rotation) & Cloud (Advanced Rotation). If you don't want to manage the infrastructure, join our cloud waitlist to get early access.",
+ "join_waitlist": "Join Maxun Cloud Waitlist",
+ "alert": {
+ "title": "If your proxy requires a username and password, always provide them separate from the proxy URL.",
+ "right_way": "The right way",
+ "wrong_way": "The wrong way",
+ "proxy_url": "Proxy URL:",
+ "username": "Username:",
+ "password": "Password:"
+ },
+ "notifications": {
+ "config_success": "Proxy saved successfully",
+ "config_error": "Failed to save proxy. Try again.",
+ "test_success": "Proxy is working",
+ "test_error": "Proxy test failed. Try again.",
+ "fetch_success": "Proxy loaded successfully",
+ "remove_success": "Proxy removed successfully",
+ "remove_error": "Failed to remove proxy. Try again."
+ }
+ },
+ "apikey": {
+ "title": "Manage Your API Key",
+ "default_name": "Maxun API Key",
+ "table": {
+ "name": "API Key Name",
+ "key": "API Key",
+ "actions": "Actions"
+ },
+ "actions": {
+ "copy": "Copy",
+ "show": "Show",
+ "hide": "Hide",
+ "delete": "Delete"
+ },
+ "no_key_message": "You haven't generated an API key yet.",
+ "generate_button": "Generate API Key",
+ "notifications": {
+ "fetch_error": "Failed to fetch API Key - {{error}}",
+ "generate_success": "Generated API Key successfully",
+ "generate_error": "Failed to generate API Key - {{error}}",
+ "delete_success": "API Key deleted successfully",
+ "delete_error": "Failed to delete API Key - {{error}}",
+ "copy_success": "Copied API Key successfully"
+ }
+ },
+ "action_description": {
+ "text": {
+ "title": "Capture Text",
+ "description": "Hover over the texts you want to extract and click to select them"
+ },
+ "screenshot": {
+ "title": "Capture Screenshot",
+ "description": "Capture a partial or full page screenshot of the current page."
+ },
+ "list": {
+ "title": "Capture List",
+ "description": "Hover over the list you want to extract. Once selected, you can hover over all texts inside the list you selected. Click to select them."
+ },
+ "default": {
+ "title": "What data do you want to extract?",
+ "description": "A robot can perform one or multiple actions. Choose from the options listed below."
+ },
+ "list_stages": {
+ "initial": "Select the list you want to extract along with the texts inside it",
+ "pagination": "Select how the robot can capture the rest of the list",
+ "limit": "Choose the number of items to extract",
+ "complete": "Capture is complete"
+ },
+ "actions": {
+ "text": "Capture Text",
+ "list": "Capture List",
+ "screenshot": "Capture Screenshot"
+ }
+ },
+ "right_panel": {
+ "buttons": {
+ "capture_list": "Capture List",
+ "capture_text": "Capture Text",
+ "capture_screenshot": "Capture Screenshot",
+ "confirm": "Confirm",
+ "discard": "Discard",
+ "confirm_capture": "Confirm Capture",
+ "confirm_pagination": "Confirm",
+ "confirm_limit": "Confirm",
+ "confirm_reset": "Confirm",
+ "finish_capture": "Finish Capture",
+ "back": "Back",
+ "reset": "Restart Recording",
+ "finish": "Finish",
+ "cancel": "Cancel",
+ "delete": "Delete"
+ },
+ "screenshot": {
+ "capture_fullpage": "Capture Fullpage",
+ "capture_visible": "Capture Visible Part",
+ "display_fullpage": "Take Fullpage Screenshot",
+ "display_visible": "Take Visible Part Screenshot"
+ },
+ "pagination": {
+ "title": "How can we find the next list item on the page?",
+ "click_next": "Click on next to navigate to the next page",
+ "click_load_more": "Click on load more to load more items",
+ "scroll_down": "Scroll down to load more items",
+ "scroll_up": "Scroll up to load more items",
+ "none": "No more items to load"
+ },
+ "limit": {
+ "title": "What is the maximum number of rows you want to extract?",
+ "custom": "Custom",
+ "enter_number": "Enter number"
+ },
+ "fields": {
+ "label": "Label",
+ "data": "Data",
+ "field_label": "Field Label",
+ "field_data": "Field Data"
+ },
+ "messages": {
+ "list_selected": "List Selected Successfully",
+ "list_empty": "List selected. Please select fields inside the list."
+ },
+ "errors": {
+ "select_pagination": "Please select a pagination type.",
+ "select_pagination_element": "Please select the pagination element first.",
+ "select_limit": "Please select a limit or enter a custom limit.",
+ "invalid_limit": "Please enter a valid limit.",
+ "confirm_text_fields": "Please confirm all text fields",
+ "unable_create_settings": "Unable to create list settings. Make sure you have defined a field for the list.",
+ "capture_text_discarded": "Capture Text Discarded",
+ "capture_list_discarded": "Capture List Discarded",
+ "label_required": "Label cannot be empty",
+ "duplicate_label": "This label already exists. Please use a unique label.",
+ "no_text_captured": "Please highlight and select text elements before confirming.",
+ "capture_list_first": "Please hover over a list and select text fields inside it first",
+ "confirm_all_list_fields": "Please confirm all captured list fields before proceeding"
+ },
+ "tooltips": {
+ "capture_list_first": "Hover over a list and select text fields inside it first",
+ "confirm_all_list_fields": "Please confirm all captured list fields before proceeding"
+ }
+ },
+ "save_recording": {
+ "title": "Save Robot",
+ "robot_name": "Name",
+ "buttons": {
+ "save": "Save",
+ "confirm": "Confirm"
+ },
+ "notifications": {
+ "save_success": "Robot saved successfully",
+ "retrain_success": "Robot retrained successfully",
+ "save_error": "Error saving robot"
+ },
+ "errors": {
+ "user_not_logged": "User not logged in. Cannot save recording.",
+ "exists_warning": "Robot with this name already exists, please confirm the Robot's overwrite.",
+ "name_exists": "A robot with this name already exists. Please choose a different name.",
+ "no_actions_performed": "Cannot save robot. Please perform at least one capture action before saving."
+ },
+ "tooltips": {
+ "saving": "Optimizing and saving the workflow"
+ }
+ },
+ "browser_recording": {
+ "modal": {
+ "confirm_discard": "Are you sure you want to discard the recording?",
+ "confirm_reset": "Are you sure you want to restart the recording?",
+ "reset_warning": "This will clear all previous captures in the current session. The recording session will restart for the same website."
+ },
+ "notifications": {
+ "terminated": "Current Recording was terminated",
+ "environment_reset": "Browser environment has been reset",
+ "reset_successful": "Successfully reset all captures and returned to initial state",
+ "timeout_discarded": "Recording session timed out after 10 minutes and was automatically discarded."
+ }
+ },
+ "interpretation_log": {
+ "titles": {
+ "output_preview": "Output Data Preview",
+ "screenshot": "Screenshot"
+ },
+ "messages": {
+ "additional_rows": "Additional rows of data will be extracted once you finish recording.",
+ "successful_training": "You've successfully trained the robot to perform actions! Click on the button below to get a preview of the data your robot will extract.",
+ "no_selection": "It looks like you have not selected anything for extraction yet. Once you do, the robot will show a preview of your selections here."
+ },
+ "data_sections": {
+ "binary_received": "---------- Binary output data received ----------",
+ "serializable_received": "---------- Serializable output data received ----------",
+ "mimetype": "mimetype: ",
+ "image_below": "Image is rendered below:",
+ "separator": "--------------------------------------------------"
+ },
+ "notifications": {
+ "reset_success": "Output Preview reset successfully"
+ }
+ },
+ "interpretation_buttons": {
+ "buttons": {
+ "preview": "Get Preview of Output Data",
+ "reset": "Reset",
+ "yes": "Yes",
+ "no": "No"
+ },
+ "messages": {
+ "extracting": "Extracting data...please wait",
+ "restart_required": "Please restart the interpretation after updating the recording",
+ "run_finished": "Run finished",
+ "run_failed": "Run failed to start"
+ },
+ "modal": {
+ "use_previous": "Do you want to use your previous selection as a condition for performing this action?",
+ "previous_action": "Your previous action was: ",
+ "element_text": "on an element with text "
+ },
+ "notifications": {
+ "reset_success": "Output Preview reset successfully"
+ }
+ },
+ "recording_page": {
+ "loader": {
+ "browser_startup": "Spinning up a browser...Hold tight"
+ }
+ },
+ "integration_settings": {
+ "title": "Integration Settings",
+ "descriptions": {
+ "authenticated_as": "Authenticated as: {{email}}"
+ },
+ "buttons": {
+ "submit": "Submit",
+ "remove_integration": "Remove Integration"
+ },
+ "google": {
+ "title": "Integrate with Google Sheet",
+ "descriptions": {
+ "sync_info": "If you enable this option, every time this robot runs a task successfully, its captured data will be appended to your Google Sheet.",
+ "authenticated_as": "Authenticated as: {{email}}"
},
- "modal":{
- "title":"Enter the URL",
- "login_title": "Does this website require logging in?",
- "label":"URL",
- "button":"Start Recording"
+ "alerts": {
+ "success": {
+ "title": "Google Sheet Integrated Successfully.",
+ "content": "Every time this robot creates a successful run, its captured data is appended to your {{sheetName}} Google Sheet. You can check the data updates",
+ "here": "here",
+ "note": "Note:",
+ "sync_limitation": "The data extracted before integrating with Google Sheets will not be synced in the Google Sheet. Only the data extracted after the integration will be synced."
+ }
},
- "warning_modal":{
- "title":"Active Browser Detected",
- "message": "There is already a browser recording session running. Would you like to discard it and create a new recording?",
- "discard_and_create":"Discard & Create New",
- "cancel":"Cancel"
+ "buttons": {
+ "authenticate": "Authenticate with Google",
+ "fetch_sheets": "Fetch Google Spreadsheets",
+ "remove_integration": "Remove Integration",
+ "submit": "Submit"
+ },
+ "fields": {
+ "select_sheet": "Select Google Sheet",
+ "selected_sheet": "Selected Sheet: {{name}} (ID: {{id}})"
+ },
+ "errors": {
+ "auth_error": "Error authenticating with Google",
+ "fetch_error": "Error fetching spreadsheet files: {{message}}",
+ "update_error": "Error updating Google Sheet ID: {{message}}",
+ "remove_error": "Error removing Google Sheets integration: {{message}}"
},
- "retrain": "Retrain",
- "edit":"Edit",
- "delete":"Delete",
- "duplicate":"Duplicate",
- "search":"Search Robots...",
"notifications": {
- "delete_warning": "The robot has associated runs. First delete runs to delete the robot",
- "delete_success": "Robot deleted successfully",
- "auth_success": "Robot successfully authenticated",
- "browser_limit_warning": "Remote browsers are currently busy. Please wait for a few minutes and try again"
+ "sheet_selected": "Google Sheet selected successfully",
+ "integration_removed": "Google Sheets integration removed successfully"
}
},
- "mainmenu":{
+ "airtable": {
+ "title": "Integrate with Airtable",
+ "descriptions": {
+ "sync_info": "If you enable this option, every time this robot runs a task successfully, its captured data will be appended to your Airtable Base.",
+ "authenticated_as": "Authenticated with Airtable successfully. You can now select the base and table to integrate with."
+ },
+ "alerts": {
+ "success": {
+ "title": "Airtable Base Integrated Successfully",
+ "content": "Every time this robot creates a successful run, its captured data is appended to your {{baseName}} Base and {{tableName}} Table. You can check updates",
+ "here": "here",
+ "note": "Note:",
+ "sync_limitation": "Only data captured after integration will be synced to Airtable."
+ }
+ },
+ "buttons": {
+ "authenticate": "Connect with Airtable",
+ "fetch_bases": "Fetch Airtable Bases",
+ "fetch_tables": "Fetch Airtable Tables",
+ "remove_integration": "Remove Integration",
+ "submit": "Select Base and Table"
+ },
+ "fields": {
+ "select_base": "Select Airtable Base",
+ "select_table": "Select Airtable Table",
+ "selected_base": "Selected Base: {{name}}",
+ "selected_table": "Selected Table: {{name}}"
+ },
+ "errors": {
+ "auth_error": "Error authenticating with Airtable",
+ "fetch_error": "Error fetching Airtable bases: {{message}}",
+ "fetch_tables_error": "Error fetching Airtable tables: {{message}}",
+ "update_error": "Error updating Airtable base: {{message}}",
+ "remove_error": "Error removing Airtable integration: {{message}}"
+ },
+ "notifications": {
+ "base_selected": "Airtable base selected successfully",
+ "table_selected": "Airtable table selected successfully",
+ "integration_removed": "Airtable integration removed successfully"
+ }
+ }
+ },
+ "robot_duplication": {
+ "title": "Duplicate Robot",
+ "descriptions": {
+ "purpose": "Robot duplication is useful to extract data from pages with the same structure.",
+ "example": "Example: If you've created a robot for <0>{{url1}}0>, you can duplicate it to scrape similar pages like <1>{{url2}}1> without training a robot from scratch.",
+ "warning": "⚠️ Ensure the new page has the same structure as the original page."
+ },
+ "fields": {
+ "target_url": "Target URL",
+ "new_name": "Robot Name"
+ },
+ "buttons": {
+ "duplicate": "Duplicate Robot",
+ "cancel": "Cancel"
+ },
+ "notifications": {
+ "robot_not_found": "Could not find robot details. Please try again.",
+ "url_required": "Target URL is required.",
+ "name_required": "Robot name is required.",
+ "duplicate_success": "Robot duplicated successfully.",
+ "duplicate_error": "Failed to update the Target URL. Please try again.",
+ "unknown_error": "An error occurred while updating the Target URL."
+ }
+ },
+ "robot_settings": {
+ "title": "Settings",
+ "target_url": "Target URL",
+ "robot_id": "Robot ID",
+ "robot_limit": "Robot Limit",
+ "created_by_user": "Created By User",
+ "created_at": "Robot Created At",
+ "compare_runs": "Enable Monitoring",
+ "errors": {
+ "robot_not_found": "Could not find robot details. Please try again."
+ },
+ "buttons": {
+ "close": "Close"
+ }
+ },
+ "robot_edit": {
+ "title": "Edit Robot",
+ "change_name": "Name",
+ "robot_limit": "Robot Limit",
+ "save": "Save Changes",
+ "cancel": "Cancel",
+ "notifications": {
+ "update_success": "Robot updated successfully.",
+ "update_failed": "Failed to update the robot. Please try again.",
+ "update_error": "An error occurred while updating the robot."
+ }
+ },
+ "schedule_settings": {
+ "title": "Schedule Settings",
+ "run_every": "Run every",
+ "start_from": "Start From",
+ "on_day": "On day",
+ "at_around": "At around",
+ "timezone": "Timezone",
+ "buttons": {
+ "delete_schedule": "Delete Schedule",
+ "save_schedule": "Save Schedule",
+ "cancel": "Cancel"
+ },
+ "labels": {
+ "in_between": "In Between",
+ "run_once_every": "Run once every",
+ "start_from_label": "Start From",
+ "on_day_of_month": "On Day of the Month",
+ "on_day": {
+ "st": "st",
+ "nd": "nd",
+ "rd": "rd",
+ "th": "th"
+ }
+ }
+ },
+ "main_page": {
+ "notifications": {
+ "interpretation_success": "Interpretation of robot {{name}} succeeded",
+ "interpretation_failed": "Failed to interpret robot {{name}}",
+ "run_started": "Running robot: {{name}}",
+ "run_start_failed": "Failed to run robot: {{name}}",
+ "schedule_success": "Robot {{name}} scheduled successfully",
+ "schedule_failed": "Failed to schedule robot {{name}}",
+ "abort_success": "Interpretation of robot {{name}} aborted successfully",
+ "abort_failed": "Failed to abort the interpretation of robot {{name}}",
+ "abort_initiated": "Aborting the interpretation of robot {{name}}"
+ },
+ "menu": {
"recordings": "Robots",
"runs": "Runs",
"proxy": "Proxy",
- "apikey": "API Key",
- "feedback":"Join Maxun Cloud",
- "apidocs":"Website To API"
- },
- "runstable":{
- "runs":"All Runs",
- "runStatus":"Status",
- "runName":"Name",
- "name":"Name",
- "startedAt":"Started At",
- "finishedAt":"Finished At",
- "delete":"Delete",
- "settings":"Settings",
- "search":"Search Runs...",
- "sort_tooltip": "Click to sort",
- "placeholder": {
- "title": "No Runs Found",
- "body": "This is where all your robot runs will appear. Once a robot is active, its runs will be logged here.",
- "search":"No runs match your search"
- },
+ "apikey": "API Key"
+ }
+ },
+ "browser_window": {
+ "attribute_modal": {
+ "title": "Select Attribute",
"notifications": {
- "no_runs": "No runs found. Please try again.",
- "delete_success": "Run deleted successfully"
+ "list_select_success": "List has been successfully selected. Please select the text data to extract.",
+ "pagination_select_success": "Pagination element has been successfully selected."
}
},
- "proxy": {
- "title": "Proxy Configuration",
- "tab_standard": "Standard Proxy",
- "tab_rotation": "Automatic Proxy Rotation",
- "server_url": "Proxy Server URL",
- "server_url_helper": "Proxy to be used for all robots. HTTP and SOCKS proxies are supported. Example http://myproxy.com:3128 or socks5://myproxy.com:3128. Short form myproxy.com:3128 is considered an HTTP proxy.",
- "requires_auth": "Requires Authentication?",
- "username": "Username",
- "password": "Password",
- "add_proxy": "Add Proxy",
- "test_proxy": "Test Proxy",
- "remove_proxy": "Remove Proxy",
- "table": {
- "proxy_url": "Proxy URL",
- "requires_auth": "Requires Authentication"
+ "attribute_options": {
+ "anchor": {
+ "text": "Text: {{text}}",
+ "url": "URL: {{url}}"
},
- "coming_soon": "Coming Soon - In Open Source (Basic Rotation) & Cloud (Advanced Rotation). If you don't want to manage the infrastructure, join our cloud waitlist to get early access.",
- "join_waitlist": "Join Maxun Cloud Waitlist",
- "alert": {
- "title": "If your proxy requires a username and password, always provide them separate from the proxy URL.",
- "right_way": "The right way",
- "wrong_way": "The wrong way",
- "proxy_url": "Proxy URL:",
- "username": "Username:",
- "password": "Password:"
- },
- "notifications": {
- "config_success": "Proxy configuration submitted successfully",
- "config_error": "Failed to submit proxy configuration. Try again.",
- "test_success": "Proxy configuration is working",
- "test_error": "Failed to test proxy configuration. Try again.",
- "fetch_success": "Proxy configuration fetched successfully",
- "remove_success": "Proxy configuration removed successfully",
- "remove_error": "Failed to remove proxy configuration. Try again."
- }
- },
- "apikey": {
- "title": "Manage Your API Key",
- "default_name": "Maxun API Key",
- "table": {
- "name": "API Key Name",
- "key": "API Key",
- "actions": "Actions"
- },
- "actions": {
- "copy": "Copy",
- "show": "Show",
- "hide": "Hide",
- "delete": "Delete"
- },
- "no_key_message": "You haven't generated an API key yet.",
- "generate_button": "Generate API Key",
- "notifications": {
- "fetch_error": "Failed to fetch API Key - {{error}}",
- "generate_success": "Generated API Key successfully",
- "generate_error": "Failed to generate API Key - {{error}}",
- "delete_success": "API Key deleted successfully",
- "delete_error": "Failed to delete API Key - {{error}}",
- "copy_success": "Copied API Key successfully"
- }
- },
- "action_description": {
- "text": {
- "title": "Capture Text",
- "description": "Hover over the texts you want to extract and click to select them"
- },
- "screenshot": {
- "title": "Capture Screenshot",
- "description": "Capture a partial or full page screenshot of the current page."
- },
- "list": {
- "title": "Capture List",
- "description": "Hover over the list you want to extract. Once selected, you can hover over all texts inside the list you selected. Click to select them."
+ "image": {
+ "alt_text": "Alt Text: {{altText}}",
+ "image_url": "Image URL: {{imageUrl}}"
},
"default": {
- "title": "What data do you want to extract?",
- "description": "A robot can perform one or multiple actions. Choose from the options listed below."
- },
- "list_stages": {
- "initial": "Select the list you want to extract along with the texts inside it",
- "pagination": "Select how the robot can capture the rest of the list",
- "limit": "Choose the number of items to extract",
- "complete": "Capture is complete"
- },
- "actions": {
- "text": "Capture Text",
- "list": "Capture List",
- "screenshot": "Capture Screenshot"
+ "text": "Text: {{text}}"
}
- },
- "right_panel": {
- "buttons": {
- "capture_list": "Capture List",
- "capture_text": "Capture Text",
- "capture_screenshot": "Capture Screenshot",
- "confirm": "Confirm",
- "discard": "Discard",
- "confirm_capture": "Confirm Capture",
- "confirm_pagination": "Confirm",
- "confirm_limit": "Confirm",
- "confirm_reset": "Confirm",
- "finish_capture": "Finish Capture",
- "back": "Back",
- "reset": "Restart Recording",
- "finish": "Finish",
- "cancel": "Cancel",
- "delete": "Delete"
- },
- "screenshot": {
- "capture_fullpage": "Capture Fullpage",
- "capture_visible": "Capture Visible Part",
- "display_fullpage": "Take Fullpage Screenshot",
- "display_visible": "Take Visible Part Screenshot"
- },
- "pagination": {
- "title": "How can we find the next list item on the page?",
- "click_next": "Click on next to navigate to the next page",
- "click_load_more": "Click on load more to load more items",
- "scroll_down": "Scroll down to load more items",
- "scroll_up": "Scroll up to load more items",
- "none": "No more items to load"
- },
- "limit": {
- "title": "What is the maximum number of rows you want to extract?",
- "custom": "Custom",
- "enter_number": "Enter number"
- },
- "fields": {
- "label": "Label",
- "data": "Data",
- "field_label": "Field Label",
- "field_data": "Field Data"
- },
- "messages": {
- "list_selected": "List Selected Successfully",
- "list_empty": "List selected. Please select fields inside the list."
- },
- "errors": {
- "select_pagination": "Please select a pagination type.",
- "select_pagination_element": "Please select the pagination element first.",
- "select_limit": "Please select a limit or enter a custom limit.",
- "invalid_limit": "Please enter a valid limit.",
- "confirm_text_fields": "Please confirm all text fields",
- "unable_create_settings": "Unable to create list settings. Make sure you have defined a field for the list.",
- "capture_text_discarded": "Capture Text Discarded",
- "capture_list_discarded": "Capture List Discarded",
- "label_required": "Label cannot be empty",
- "duplicate_label": "This label already exists. Please use a unique label.",
- "no_text_captured": "Please highlight and select text elements before confirming.",
- "capture_list_first": "Please hover over a list and select text fields inside it first",
- "confirm_all_list_fields": "Please confirm all captured list fields before proceeding"
- },
- "tooltips": {
- "capture_list_first": "Hover over a list and select text fields inside it first",
- "confirm_all_list_fields": "Please confirm all captured list fields before proceeding"
- }
- },
- "save_recording": {
- "title": "Save Robot",
- "robot_name": "Name",
- "buttons": {
- "save": "Save",
- "confirm": "Confirm"
- },
- "notifications": {
- "save_success": "Robot saved successfully",
- "retrain_success": "Robot retrained successfully",
- "save_error": "Error saving robot"
- },
- "errors": {
- "user_not_logged": "User not logged in. Cannot save recording.",
- "exists_warning": "Robot with this name already exists, please confirm the Robot's overwrite.",
- "name_exists": "A robot with this name already exists. Please choose a different name.",
- "no_actions_performed": "Cannot save robot. Please perform at least one capture action before saving."
- },
- "tooltips": {
- "saving": "Optimizing and saving the workflow"
- }
- },
- "browser_recording": {
- "modal": {
- "confirm_discard": "Are you sure you want to discard the recording?",
- "confirm_reset": "Are you sure you want to restart the recording?",
- "reset_warning": "This will clear all previous captures in the current session. The recording session will restart for the same website."
- },
- "notifications": {
- "terminated": "Current Recording was terminated",
- "environment_reset": "Browser environment has been reset",
- "reset_successful": "Successfully reset all captures and returned to initial state",
- "timeout_discarded": "Recording session timed out after 10 minutes and was automatically discarded."
- }
- },
- "interpretation_log": {
- "titles": {
- "output_preview": "Output Data Preview",
- "screenshot": "Screenshot"
- },
- "messages": {
- "additional_rows": "Additional rows of data will be extracted once you finish recording.",
- "successful_training": "You've successfully trained the robot to perform actions! Click on the button below to get a preview of the data your robot will extract.",
- "no_selection": "It looks like you have not selected anything for extraction yet. Once you do, the robot will show a preview of your selections here."
- },
- "data_sections": {
- "binary_received": "---------- Binary output data received ----------",
- "serializable_received": "---------- Serializable output data received ----------",
- "mimetype": "mimetype: ",
- "image_below": "Image is rendered below:",
- "separator": "--------------------------------------------------"
- },
- "notifications": {
- "reset_success": "Output Preview reset successfully"
- }
- },
- "interpretation_buttons": {
- "buttons": {
- "preview": "Get Preview of Output Data",
- "reset": "Reset",
- "yes": "Yes",
- "no": "No"
- },
- "messages": {
- "extracting": "Extracting data...please wait",
- "restart_required": "Please restart the interpretation after updating the recording",
- "run_finished": "Run finished",
- "run_failed": "Run failed to start"
- },
- "modal": {
- "use_previous": "Do you want to use your previous selection as a condition for performing this action?",
- "previous_action": "Your previous action was: ",
- "element_text": "on an element with text "
- },
- "notifications": {
- "reset_success": "Output Preview reset successfully"
- }
- },
- "recording_page": {
- "loader": {
- "browser_startup": "Spinning up a browser...Hold tight"
- }
- },
- "integration_settings": {
- "title": "Integration Settings",
- "descriptions": {
- "authenticated_as": "Authenticated as: {{email}}"
- },
- "buttons": {
- "submit": "Submit",
- "remove_integration": "Remove Integration"
- },
- "google": {
- "title": "Integrate with Google Sheet",
- "descriptions": {
- "sync_info": "If you enable this option, every time this robot runs a task successfully, its captured data will be appended to your Google Sheet.",
- "authenticated_as": "Authenticated as: {{email}}"
- },
- "alerts": {
- "success": {
- "title": "Google Sheet Integrated Successfully.",
- "content": "Every time this robot creates a successful run, its captured data is appended to your {{sheetName}} Google Sheet. You can check the data updates",
- "here": "here",
- "note": "Note:",
- "sync_limitation": "The data extracted before integrating with Google Sheets will not be synced in the Google Sheet. Only the data extracted after the integration will be synced."
- }
- },
- "buttons": {
- "authenticate": "Authenticate with Google",
- "fetch_sheets": "Fetch Google Spreadsheets",
- "remove_integration": "Remove Integration",
- "submit": "Submit"
- },
- "fields": {
- "select_sheet": "Select Google Sheet",
- "selected_sheet": "Selected Sheet: {{name}} (ID: {{id}})"
- },
- "errors": {
- "auth_error": "Error authenticating with Google",
- "fetch_error": "Error fetching spreadsheet files: {{message}}",
- "update_error": "Error updating Google Sheet ID: {{message}}",
- "remove_error": "Error removing Google Sheets integration: {{message}}"
- },
- "notifications": {
- "sheet_selected": "Google Sheet selected successfully",
- "integration_removed": "Google Sheets integration removed successfully"
- }
- },
- "airtable": {
- "title": "Integrate with Airtable",
- "descriptions": {
- "sync_info": "If you enable this option, every time this robot runs a task successfully, its captured data will be appended to your Airtable Base.",
- "authenticated_as": "Authenticated with Airtable successfully. You can now select the base and table to integrate with."
- },
- "alerts": {
- "success": {
- "title": "Airtable Base Integrated Successfully",
- "content": "Every time this robot creates a successful run, its captured data is appended to your {{baseName}} Base and {{tableName}} Table. You can check updates",
- "here": "here",
- "note": "Note:",
- "sync_limitation": "Only data captured after integration will be synced to Airtable."
- }
- },
- "buttons": {
- "authenticate": "Connect with Airtable",
- "fetch_bases": "Fetch Airtable Bases",
- "fetch_tables": "Fetch Airtable Tables",
- "remove_integration": "Remove Integration",
- "submit": "Select Base and Table"
- },
- "fields": {
- "select_base": "Select Airtable Base",
- "select_table": "Select Airtable Table",
- "selected_base": "Selected Base: {{name}}",
- "selected_table": "Selected Table: {{name}}"
- },
- "errors": {
- "auth_error": "Error authenticating with Airtable",
- "fetch_error": "Error fetching Airtable bases: {{message}}",
- "fetch_tables_error": "Error fetching Airtable tables: {{message}}",
- "update_error": "Error updating Airtable base: {{message}}",
- "remove_error": "Error removing Airtable integration: {{message}}"
- },
- "notifications": {
- "base_selected": "Airtable base selected successfully",
- "table_selected": "Airtable table selected successfully",
- "integration_removed": "Airtable integration removed successfully"
- }
- }
- },
- "robot_duplication": {
- "title": "Duplicate Robot",
- "descriptions": {
- "purpose": "Robot duplication is useful to extract data from pages with the same structure.",
- "example": "Example: If you've created a robot for <0>{{url1}}0>, you can duplicate it to scrape similar pages like <1>{{url2}}1> without training a robot from scratch.",
- "warning": "⚠️ Ensure the new page has the same structure as the original page."
- },
- "fields": {
- "target_url": "Target URL",
- "new_name": "Robot Name"
- },
- "buttons": {
- "duplicate": "Duplicate Robot",
- "cancel": "Cancel"
- },
- "notifications": {
- "robot_not_found": "Could not find robot details. Please try again.",
- "url_required": "Target URL is required.",
- "name_required": "Robot name is required.",
- "duplicate_success": "Robot duplicated successfully.",
- "duplicate_error": "Failed to update the Target URL. Please try again.",
- "unknown_error": "An error occurred while updating the Target URL."
- }
- },
- "robot_settings": {
- "title": "Settings",
- "target_url": "Target URL",
- "robot_id": "Robot ID",
- "robot_limit": "Robot Limit",
- "created_by_user": "Created By User",
- "created_at": "Robot Created At",
- "compare_runs": "Enable Monitoring",
- "errors": {
- "robot_not_found": "Could not find robot details. Please try again."
- },
- "buttons": {
- "close": "Close"
- }
- },
- "robot_edit": {
- "title": "Edit Robot",
- "change_name": "Name",
- "robot_limit": "Robot Limit",
- "save": "Save Changes",
- "cancel": "Cancel",
- "notifications": {
- "update_success": "Robot updated successfully.",
- "update_failed": "Failed to update the robot. Please try again.",
- "update_error": "An error occurred while updating the robot."
- }
- },
- "schedule_settings": {
- "title": "Schedule Settings",
- "run_every": "Run every",
- "start_from": "Start From",
- "on_day": "On day",
- "at_around": "At around",
- "timezone": "Timezone",
- "buttons": {
- "delete_schedule": "Delete Schedule",
- "save_schedule": "Save Schedule",
- "cancel": "Cancel"
- },
- "labels": {
- "in_between": "In Between",
- "run_once_every": "Run once every",
- "start_from_label": "Start From",
- "on_day_of_month": "On Day of the Month",
- "on_day": {
- "st": "st",
- "nd": "nd",
- "rd": "rd",
- "th": "th"
- }
- }
- },
- "main_page": {
- "notifications": {
- "interpretation_success": "Interpretation of robot {{name}} succeeded",
- "interpretation_failed": "Failed to interpret robot {{name}}",
- "run_started": "Running robot: {{name}}",
- "run_start_failed": "Failed to run robot: {{name}}",
- "schedule_success": "Robot {{name}} scheduled successfully",
- "schedule_failed": "Failed to schedule robot {{name}}",
- "abort_success": "Interpretation of robot {{name}} aborted successfully",
- "abort_failed": "Failed to abort the interpretation of robot {{name}}",
- "abort_initiated": "Aborting the interpretation of robot {{name}}"
- },
- "menu": {
- "recordings": "Robots",
- "runs": "Runs",
- "proxy": "Proxy",
- "apikey": "API Key"
- }
- },
- "browser_window": {
- "attribute_modal": {
- "title": "Select Attribute",
- "notifications": {
- "list_select_success": "List has been successfully selected. Please select the text data to extract.",
- "pagination_select_success": "Pagination element has been successfully selected."
- }
- },
- "attribute_options": {
- "anchor": {
- "text": "Text: {{text}}",
- "url": "URL: {{url}}"
- },
- "image": {
- "alt_text": "Alt Text: {{altText}}",
- "image_url": "Image URL: {{imageUrl}}"
- },
- "default": {
- "text": "Text: {{text}}"
- }
- }
- },
- "runs_table": {
- "run_type_chips": {
- "manual_run": "Manual",
- "scheduled_run": "Scheduled",
- "api": "API",
- "sdk": "SDK",
- "mcp": "MCP",
- "cli": "CLI",
- "unknown_run_type": "Unknown Run Type"
- },
- "run_status_chips": {
- "success": "Success",
- "running": "Running",
- "scheduled": "Scheduled",
- "queued": "Queued",
- "failed": "Failed",
- "aborted": "Aborted"
- },
- "run_settings_modal": {
- "title": "Run Settings",
- "labels": {
- "run_id": "Run ID",
- "run_by_user": "Run by User",
- "run_by_schedule": "Run by Schedule ID",
- "run_by_api": "Run by API",
- "run_type": "Run Type"
- }
- }
- },
- "run_content": {
- "tabs": {
- "output_data": "Output Data",
- "log": "Log"
- },
- "buttons": {
- "stop": "Stop"
- },
- "loading": "Extracting data...",
- "empty_output": "No output data available",
- "captured_data": {
- "title": "Captured Data",
- "download_csv": "Download CSV",
- "view_full": "View Full Data",
- "items": "items",
- "schema_title": "Captured Texts",
- "list_title": "Captured Lists"
- },
- "captured_screenshot": {
- "title": "Captured Screenshots",
- "download": "Download",
- "render_failed": "Failed to render screenshot"
- }
- },
- "navbar": {
- "project_name": "Maxun",
- "notifications": {
- "success": {
- "logout": "Logged out successfully"
- },
- "errors": {
- "logout": {
- "unauthorized": "You are not authorized to perform this action",
- "server": "Server error occurred during logout",
- "network": "Network error while logging out",
- "unknown": "An unexpected error occurred during logout"
- }
- }
- },
- "upgrade": {
- "button": "Upgrade",
- "modal": {
- "up_to_date": "🎉 You're up to date!",
- "new_version_available": "A new version is available: {{version}}. Upgrade to the latest version for bug fixes, enhancements and new features!",
- "view_updates": "View all the new updates",
- "view_updates_link": "here",
- "tabs": {
- "manual_setup": "Manual Setup Upgrade",
- "docker_setup": "Docker Compose Setup Upgrade"
- }
- }
- },
- "menu_items": {
- "logout": "Logout",
- "discord": "Discord",
- "youtube": "YouTube",
- "twitter": "Twitter (X)",
- "language": "Language"
- },
- "recording": {
- "discard": "Discard"
- }
- },
- "language_menu": {
- "en": "English",
- "es": "Spanish",
- "ja": "Japanese",
- "zh": "Chinese",
- "de": "German",
- "tr": "Turkish",
- "ko": "Korean",
- "he": "Hebrew",
- "az": "Azerbaijani"
}
-}
+ },
+ "runs_table": {
+ "run_type_chips": {
+ "manual_run": "Manual",
+ "scheduled_run": "Scheduled",
+ "api": "API",
+ "sdk": "SDK",
+ "mcp": "MCP",
+ "cli": "CLI",
+ "unknown_run_type": "Unknown Run Type"
+ },
+ "run_status_chips": {
+ "success": "Success",
+ "running": "Running",
+ "scheduled": "Scheduled",
+ "queued": "Queued",
+ "failed": "Failed",
+ "aborted": "Aborted"
+ },
+ "run_settings_modal": {
+ "title": "Run Settings",
+ "labels": {
+ "run_id": "Run ID",
+ "run_by_user": "Run by User",
+ "run_by_schedule": "Run by Schedule ID",
+ "run_by_api": "Run by API",
+ "run_type": "Run Type"
+ }
+ }
+ },
+ "run_content": {
+ "tabs": {
+ "output_data": "Output Data",
+ "log": "Log"
+ },
+ "buttons": {
+ "stop": "Stop"
+ },
+ "loading": "Extracting data...",
+ "empty_output": "No output data available",
+ "captured_data": {
+ "title": "Captured Data",
+ "download_csv": "Download CSV",
+ "view_full": "View Full Data",
+ "items": "items",
+ "schema_title": "Captured Texts",
+ "list_title": "Captured Lists"
+ },
+ "captured_screenshot": {
+ "title": "Captured Screenshots",
+ "download": "Download",
+ "render_failed": "Failed to render screenshot"
+ }
+ },
+ "navbar": {
+ "project_name": "Maxun",
+ "notifications": {
+ "success": {
+ "logout": "Logged out successfully"
+ },
+ "errors": {
+ "logout": {
+ "unauthorized": "You are not authorized to perform this action",
+ "server": "Server error occurred during logout",
+ "network": "Network error while logging out",
+ "unknown": "An unexpected error occurred during logout"
+ }
+ }
+ },
+ "upgrade": {
+ "button": "Upgrade",
+ "modal": {
+ "up_to_date": "🎉 You're up to date!",
+ "new_version_available": "A new version is available: {{version}}. Upgrade to the latest version for bug fixes, enhancements and new features!",
+ "view_updates": "View all the new updates",
+ "view_updates_link": "here",
+ "tabs": {
+ "manual_setup": "Manual Setup Upgrade",
+ "docker_setup": "Docker Compose Setup Upgrade"
+ }
+ }
+ },
+ "menu_items": {
+ "logout": "Logout",
+ "discord": "Discord",
+ "youtube": "YouTube",
+ "twitter": "Twitter (X)",
+ "language": "Language"
+ },
+ "recording": {
+ "discard": "Discard"
+ }
+ },
+ "language_menu": {
+ "en": "English",
+ "es": "Spanish",
+ "ja": "Japanese",
+ "zh": "Chinese",
+ "de": "German",
+ "tr": "Turkish",
+ "ko": "Korean",
+ "he": "Hebrew",
+ "az": "Azerbaijani"
+ }
+}
\ No newline at end of file
diff --git a/src/components/proxy/ProxyForm.tsx b/src/components/proxy/ProxyForm.tsx
index 3c6a427a..5f960042 100644
--- a/src/components/proxy/ProxyForm.tsx
+++ b/src/components/proxy/ProxyForm.tsx
@@ -12,7 +12,8 @@ import {
TableRow,
TableBody,
TableCell,
- Paper
+ Paper,
+ CircularProgress
} from '@mui/material';
import { sendProxyConfig, getProxyConfig, testProxyConfig, deleteProxyConfig } from '../../api/proxy';
import { useGlobalInfoStore } from '../../context/globalInfo';
@@ -37,6 +38,7 @@ const ProxyForm: React.FC = () => {
const [isProxyConfigured, setIsProxyConfigured] = useState(false);
const [proxy, setProxy] = useState({ proxy_url: '', auth: false });
const [recommendedProxiesAvailable, setRecommendedProxiesAvailable] = useState(false);
+ const [isTesting, setIsTesting] = useState(false);
const { notify } = useGlobalInfoStore();
@@ -89,6 +91,7 @@ const ProxyForm: React.FC = () => {
setIsProxyConfigured(true);
setProxy({ proxy_url: proxyConfigForm.server_url, auth: requiresAuth });
notify('success', t('proxy.notifications.config_success'));
+ // Refresh the masked config silently; the success toast above already covers this action
fetchProxyConfig();
} else {
notify('error', t('proxy.notifications.config_error'));
@@ -100,22 +103,32 @@ const ProxyForm: React.FC = () => {
};
const testProxy = async () => {
- await testProxyConfig().then((response) => {
+ if (isTesting) return;
+ setIsTesting(true);
+ try {
+ const response = await testProxyConfig();
if (response.success) {
notify('success', t('proxy.notifications.test_success'));
} else {
notify('error', t('proxy.notifications.test_error'));
}
- });
+ } catch (error: any) {
+ notify('error', t('proxy.notifications.test_error'));
+ } finally {
+ setIsTesting(false);
+ }
};
- const fetchProxyConfig = async () => {
+ // Only notifies when explicitly asked to, so loading the page stays silent
+ const fetchProxyConfig = async (showNotification: boolean = false) => {
try {
const response = await getProxyConfig();
if (response.proxy_url) {
setIsProxyConfigured(true);
setProxy(response);
- notify('success', t('proxy.notifications.fetch_success'));
+ if (showNotification) {
+ notify('success', t('proxy.notifications.fetch_success'));
+ }
}
} catch (error: any) {
notify('error', error);
@@ -204,10 +217,22 @@ const ProxyForm: React.FC = () => {
-
-
+
{t('proxy.remove_proxy')}