import React, { useState } from 'react'; import I18n from 'i18n-js'; import Select from 'react-select'; // To keep in sync with app/workflows/create_liquid_template_context_workflow.rb const tenantOptions = [ { value: '{{ tenant.site_name }}', label: 'Feedback space name' }, { value: '{{ tenant.subdomain }}', label: 'Feedback space subdomain' }, { value: '{{ tenant.custom_domain }}', label: 'Feedback space custom domain' }, ]; const boardOptions = [ { value: '{{ board.id }}', label: 'Board ID' }, { value: '{{ board.name }}', label: 'Board name' }, { value: '{{ board.description }}', label: 'Board description' }, { value: '{{ board.slug }}', label: 'Board slug' }, { value: '{{ board.created_at }}', label: 'Board created at datetime' }, { value: '{{ board.updated_at }}', label: 'Board updated at datetime' }, ]; const postStatusOptions = [ { value: '{{ post_status.id }}', label: 'Post status ID' }, { value: '{{ post_status.name }}', label: 'Post status name' }, { value: '{{ post_status.color }}', label: 'Post status color' }, { value: '{{ post_status.show_in_roadmap }}', label: 'Post status show in roadmap flag' }, { value: '{{ post_status.created_at }}', label: 'Post status created at datetime' }, { value: '{{ post_status.updated_at }}', label: 'Post status updated at datetime' }, ]; const userOptions = (userKeyValue: string, userKeyLabel: string) => [ { value: `{{ ${userKeyValue}.id }}`, label: `${userKeyLabel} ID` }, { value: `{{ ${userKeyValue}.email }}`, label: `${userKeyLabel} email` }, { value: `{{ ${userKeyValue}.full_name }}`, label: `${userKeyLabel} full name` }, { value: `{{ ${userKeyValue}.role }}`, label: `${userKeyLabel} role` }, { value: `{{ ${userKeyValue}.status }}`, label: `${userKeyLabel} status` }, { value: `{{ ${userKeyValue}.created_at }}`, label: `${userKeyLabel} created at datetime` }, { value: `{{ ${userKeyValue}.updated_at }}`, label: `${userKeyLabel} updated at datetime` }, ]; const postOptions = [ { value: '{{ post.id }}', label: 'Post ID' }, { value: '{{ post.title }}', label: 'Post title' }, { value: '{{ post.description }}', label: 'Post description' }, { value: '{{ post.slug }}', label: 'Post slug' }, { value: '{{ post.created_at }}', label: 'Post created at datetime' }, { value: '{{ post.updated_at }}', label: 'Post updated at datetime' }, { value: '{{ post.url }}', label: 'Post URL' }, ]; const commentOptions = [ { value: '{{ comment.id }}', label: 'Comment ID' }, { value: '{{ comment.body }}', label: 'Comment body' }, { value: '{{ comment.created_at }}', label: 'Comment created at datetime' }, { value: '{{ comment.updated_at }}', label: 'Comment updated at datetime' }, ]; const optionsByWebhookTrigger = { 'new_post': [ ...postOptions, ...userOptions('post_author', 'Post author'), ...boardOptions, ...tenantOptions, ], 'new_post_pending_approval': [ ...postOptions, ...userOptions('post_author', 'Post author'), ...boardOptions, ...tenantOptions, ], 'delete_post': [ // only post.id is available on delete_post postOptions.find(option => option.value === '{{ post.id }}'), ...tenantOptions, ], 'post_status_change': [ ...postOptions, ...userOptions('post_author', 'Post author'), ...boardOptions, ...postStatusOptions, ...tenantOptions, ], 'new_comment': [ ...commentOptions, ...userOptions('comment_author', 'Comment author'), ...postOptions, ...userOptions('post_author', 'Post author'), ...boardOptions, ...tenantOptions, ], 'new_vote': [ ...userOptions('vote_author', 'Vote author'), ...postOptions, ...userOptions('post_author', 'Post author'), ...boardOptions, ...tenantOptions, ], 'new_user': [ ...userOptions('user', 'User'), ...tenantOptions, ], }; // Non-exhaustive list of Liquid tags const liquidTagsOptions = { label: 'Liquid tags', options: [ { value: '{% if %}\n\n{% endif %}', label: 'If condition' }, { value: '{% for in %}\n\n{% endfor %}', label: 'For loop' }, { value: '{% tablerow in %}\n\n{% endtablerow %}', label: 'Tablerow loop' }, { value: '{% assign = %}', label: 'Assign variable' }, ] }; // Non-exhaustive list of Liquid filters const liquidFiltersOptions = { label: 'Liquid filters', options: [ { value: ' | abs', label: 'Absolute value' }, { value: ' | append: ', label: 'Append' }, { value: ' | capitalize', label: 'Capitalize' }, { value: ' | ceil', label: 'Ceil' }, { value: ' | compact', label: 'Compact' }, { value: ' | concat: ', label: 'Concat' }, { value: ' | date: ', label: 'Date' }, { value: ' | default: ', label: 'Default' }, { value: ' | divided_by: ', label: 'Divided by' }, { value: ' | downcase', label: 'Downcase' }, { value: ' | escape', label: 'Escape' }, { value: ' | escape_once', label: 'Escape once' }, { value: ' | first', label: 'First' }, { value: ' | floor', label: 'Floor' }, { value: ' | join: ', label: 'Join' }, { value: ' | last', label: 'Last' }, { value: ' | lstrip', label: 'Lstrip' }, { value: ' | map: ', label: 'Map' }, { value: ' | minus: ', label: 'Minus' }, { value: ' | modulo: ', label: 'Modulo' }, { value: ' | newline_to_br', label: 'Newline to br' }, { value: ' | plus: ', label: 'Plus' }, { value: ' | prepend: ', label: 'Prepend' }, { value: ' | remove: ', label: 'Remove' }, { value: ' | remove_first: ', label: 'Remove first' }, { value: ' | replace: , ', label: 'Replace' }, { value: ' | replace_first: , ', label: 'Replace first' }, { value: ' | replace_last: , ', label: 'Replace last' }, { value: ' | reverse', label: 'Reverse' }, { value: ' | round', label: 'Round' }, { value: ' | rstrip', label: 'Rstrip' }, { value: ' | size', label: 'Size' }, { value: ' | slice: ', label: 'Slice' }, { value: ' | sort', label: 'Sort' }, { value: ' | sort_natural', label: 'Sort natural' }, { value: ' | split: ', label: 'Split' }, { value: ' | strip', label: 'Strip' }, { value: ' | strip_html', label: 'Strip html' }, { value: ' | strip_newlines', label: 'Strip newlines' }, { value: ' | times: ', label: 'Times' }, { value: ' | truncate: ', label: 'Truncate' }, { value: ' | truncatewords: ', label: 'Truncate words' }, { value: ' | uniq', label: 'Uniq' }, { value: ' | upcase', label: 'Upcase' }, { value: ' | url_decode', label: 'Url decode' }, { value: ' | url_encode', label: 'Url encode' }, { value: ' | where: ', label: 'Where' }, ] }; // Custom Liquid filters const customLiquidFiltersOptions = { label: 'Custom Liquid filters', options: [ { value: ' | escape_json', label: 'Escape JSON' }, ] }; interface Props { webhookTrigger: string; onChange: (option: any) => void; } const TemplateVariablesSelector = ({ webhookTrigger, onChange, }: Props) => { const options = [ { label: 'Astuto variables', options: optionsByWebhookTrigger[webhookTrigger] || [], }, { label: 'Liquid tags', options: liquidTagsOptions.options, }, { label: 'Liquid filters', options: liquidFiltersOptions.options, }, { label: 'Custom Liquid filters', options: customLiquidFiltersOptions.options, }, ]; const [selectedOption, setSelectedOption] = useState(null); const handleChange = (option) => { onChange(option.value); // Reset the selection setSelectedOption(null); }; return (