Module: ForestAdminDatasourceZendesk::Plugins::CreateTicketWithNotification::FormBuilder
- Defined in:
- lib/forest_admin_datasource_zendesk/plugins/create_ticket_with_notification/form_builder.rb
Constant Summary collapse
- FieldType =
ForestAdminDatasourceCustomizer::Decorators::Action::Types::FieldType
- NO_TEMPLATE =
'No template'.freeze
- TOKEN_RE =
/\{\{\s*record\.([a-zA-Z_][a-zA-Z0-9_]*)\s*\}\}/
Class Method Summary collapse
- .body_fields(opts) ⇒ Object
-
.build(opts) ⇒ Object
ActionCollectionDecorator rejects forms that mix Page elements with non-Page elements, so each mode (flat / wizard) stays homogeneous.
- .fetch_record(context) ⇒ Object
- .internal_note_field ⇒ Object
-
.interpolate(template, record, escape_html:) ⇒ Object
Message ships as html_body — unescaped ‘<` or `&` from a record value would break the outbound email or smuggle markup into it.
- .message_field(default_message, templates) ⇒ Object
-
.message_value(templates) ⇒ Object
Returns nil unless Template was just changed, so set_watch_changes carries over the user’s current Message edits between renders.
- .present?(value) ⇒ Boolean
- .priority_field ⇒ Object
- .requester_default(value) ⇒ Object
- .requester_field(default) ⇒ Object
- .subject_field(default_subject) ⇒ Object
- .template_default(template, escape_html:) ⇒ Object
- .template_field(templates) ⇒ Object
- .type_field ⇒ Object
Class Method Details
.body_fields(opts) ⇒ Object
28 29 30 31 32 33 34 35 36 |
# File 'lib/forest_admin_datasource_zendesk/plugins/create_ticket_with_notification/form_builder.rb', line 28 def body_fields(opts) fields = [requester_field(opts[:requester_email_default]), subject_field(opts[:default_subject]), (opts[:default_message], opts[:email_templates])] fields << priority_field unless present?(opts[:priority_override]) fields << type_field unless present?(opts[:type_override]) fields << internal_note_field if opts[:show_internal_note] fields end |
.build(opts) ⇒ Object
ActionCollectionDecorator rejects forms that mix Page elements with non-Page elements, so each mode (flat / wizard) stays homogeneous.
16 17 18 19 20 21 22 23 24 25 26 |
# File 'lib/forest_admin_datasource_zendesk/plugins/create_ticket_with_notification/form_builder.rb', line 16 def build(opts) body = body_fields(opts) return body if opts[:email_templates].empty? [ { type: 'Layout', component: 'Page', next_button_label: 'Continue', elements: [template_field(opts[:email_templates])] }, { type: 'Layout', component: 'Page', previous_button_label: 'Back', elements: body } ] end |
.fetch_record(context) ⇒ Object
122 123 124 125 126 127 128 129 |
# File 'lib/forest_admin_datasource_zendesk/plugins/create_ticket_with_notification/form_builder.rb', line 122 def fetch_record(context) context.get_record([]) || {} rescue StandardError => e ForestAdminDatasourceZendesk.logger.warn( "[forest_admin_datasource_zendesk] failed to fetch record for token interpolation: #{e.class}: #{e.}" ) {} end |
.internal_note_field ⇒ Object
77 78 79 80 81 |
# File 'lib/forest_admin_datasource_zendesk/plugins/create_ticket_with_notification/form_builder.rb', line 77 def internal_note_field { type: FieldType::BOOLEAN, label: 'Send as internal note', description: 'When checked, the first comment is private and no email is sent to the requester.', default_value: false } end |
.interpolate(template, record, escape_html:) ⇒ Object
Message ships as html_body — unescaped ‘<` or `&` from a record value would break the outbound email or smuggle markup into it.
133 134 135 136 137 138 139 140 141 |
# File 'lib/forest_admin_datasource_zendesk/plugins/create_ticket_with_notification/form_builder.rb', line 133 def interpolate(template, record, escape_html:) template.gsub(TOKEN_RE) do key = ::Regexp.last_match(1) value = record[key] next '' if value.nil? escape_html ? CGI.escapeHTML(value.to_s) : value.to_s end end |
.message_field(default_message, templates) ⇒ Object
56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/forest_admin_datasource_zendesk/plugins/create_ticket_with_notification/form_builder.rb', line 56 def (, templates) field = { type: FieldType::STRING, label: 'Message', widget: 'RichText', is_required: true, description: 'Sent as the ticket\'s first comment (HTML). Public comments trigger the ' \ 'default Zendesk notification email to the requester.' } return field.merge(default_value: template_default(, escape_html: true)) if templates.empty? # `value:` (not `default_value:`) — drop_default runs once (data # key sticks after the first render); drop_deferred re-evaluates # on every fetch, so Template changes re-fire the message proc. field.merge(value: (templates)) end |
.message_value(templates) ⇒ Object
Returns nil unless Template was just changed, so set_watch_changes carries over the user’s current Message edits between renders.
107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
# File 'lib/forest_admin_datasource_zendesk/plugins/create_ticket_with_notification/form_builder.rb', line 107 def (templates) by_title = templates.to_h { |t| [t[:title], t[:content].to_s] } lambda do |context| return nil unless context.field_changed?('Template') title = context.get_form_value('Template') return '' if title == NO_TEMPLATE content = by_title[title].to_s return content unless content.match?(TOKEN_RE) interpolate(content, fetch_record(context), escape_html: true) end end |
.present?(value) ⇒ Boolean
143 144 145 |
# File 'lib/forest_admin_datasource_zendesk/plugins/create_ticket_with_notification/form_builder.rb', line 143 def present?(value) !value.nil? && value.to_s != '' end |
.priority_field ⇒ Object
68 69 70 71 |
# File 'lib/forest_admin_datasource_zendesk/plugins/create_ticket_with_notification/form_builder.rb', line 68 def priority_field { type: FieldType::ENUM, label: 'Priority', enum_values: TicketEnums::PRIORITY, default_value: 'normal' } end |
.requester_default(value) ⇒ Object
83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
# File 'lib/forest_admin_datasource_zendesk/plugins/create_ticket_with_notification/form_builder.rb', line 83 def requester_default(value) return nil if value.nil? return template_default(value, escape_html: false) if value.is_a?(String) lambda do |context| record = fetch_record(context) record.empty? ? nil : value.call(record) rescue StandardError => e ForestAdminDatasourceZendesk.logger.warn( "[forest_admin_datasource_zendesk] requester_email_default resolver raised: #{e.class}: #{e.}" ) nil end end |
.requester_field(default) ⇒ Object
38 39 40 41 42 |
# File 'lib/forest_admin_datasource_zendesk/plugins/create_ticket_with_notification/form_builder.rb', line 38 def requester_field(default) { type: FieldType::STRING, label: 'Requester email', is_required: true, description: 'Email of the Zendesk requester. Pre-filled from the selected record when available.', default_value: requester_default(default) } end |
.subject_field(default_subject) ⇒ Object
51 52 53 54 |
# File 'lib/forest_admin_datasource_zendesk/plugins/create_ticket_with_notification/form_builder.rb', line 51 def subject_field(default_subject) { type: FieldType::STRING, label: 'Subject', is_required: true, default_value: template_default(default_subject, escape_html: false) } end |
.template_default(template, escape_html:) ⇒ Object
98 99 100 101 102 103 |
# File 'lib/forest_admin_datasource_zendesk/plugins/create_ticket_with_notification/form_builder.rb', line 98 def template_default(template, escape_html:) return nil unless present?(template) return template unless template.match?(TOKEN_RE) ->(context) { interpolate(template, fetch_record(context), escape_html: escape_html) } end |
.template_field(templates) ⇒ Object
44 45 46 47 48 49 |
# File 'lib/forest_admin_datasource_zendesk/plugins/create_ticket_with_notification/form_builder.rb', line 44 def template_field(templates) { type: FieldType::ENUM, label: 'Template', is_required: true, enum_values: [NO_TEMPLATE] + templates.map { |t| t[:title] }, default_value: NO_TEMPLATE, description: 'Pick a template to pre-fill the Message on the next page.' } end |
.type_field ⇒ Object
73 74 75 |
# File 'lib/forest_admin_datasource_zendesk/plugins/create_ticket_with_notification/form_builder.rb', line 73 def type_field { type: FieldType::ENUM, label: 'Type', enum_values: TicketEnums::TYPE } end |