diff --git a/app/helpers/attributes_helper.rb b/app/helpers/attributes_helper.rb index a659c4f9..3b3a8f1f 100644 --- a/app/helpers/attributes_helper.rb +++ b/app/helpers/attributes_helper.rb @@ -13,4 +13,21 @@ module AttributesHelper # todo: revisit logic for is_disabled -- doesn't disable empty tabs content_tag(:li, link, class: "tab #{'disabled' if false}") end + + # Helper method to resolve linkable content types for link fields + def get_linkable_content_types(linkable_types_array) + return [] if linkable_types_array.blank? + + # Get all available content types + all_content_types = Rails.application.config.content_types[:all] + + # Filter to only include the types that are linkable for this field + all_content_types.select do |content_type| + linkable_types_array.include?(content_type.name) + end.compact + rescue => e + # Graceful degradation if there are any issues resolving content types + Rails.logger.warn "Error resolving linkable content types: #{e.message}" + [] + end end diff --git a/app/javascript/packs/template_editor.js b/app/javascript/packs/template_editor.js index 0640d18b..013f4e9e 100644 --- a/app/javascript/packs/template_editor.js +++ b/app/javascript/packs/template_editor.js @@ -645,7 +645,21 @@ function handleRemoteFormSubmit(event) { } const finalKey = keyParts[keyParts.length - 1]; - current[finalKey] = value; + + // Handle checkbox arrays (multiple values with same key) + if (current[finalKey] !== undefined) { + // If key already exists, convert to array or append to existing array + if (Array.isArray(current[finalKey])) { + if (value !== '') { // Skip empty values (Rails hidden field) + current[finalKey].push(value); + } + } else { + current[finalKey] = [current[finalKey], value].filter(v => v !== ''); + } + } else { + // First occurrence of this key - if it's empty, might be a checkbox array with no selections + current[finalKey] = value === '' && key.includes('[]') ? [] : value; + } } else { jsonData[key] = value; } @@ -985,16 +999,19 @@ window.submitFieldForm = function(event) { } const finalKey = keyParts[keyParts.length - 1]; - // Handle checkbox arrays (like linkable_types) - if (form.querySelectorAll(`[name="${key}"]`).length > 1) { - if (!current[finalKey]) { - current[finalKey] = []; - } - if (value !== '') { - current[finalKey].push(value); + // Handle checkbox arrays (multiple values with same key) + if (current[finalKey] !== undefined) { + // If key already exists, convert to array or append to existing array + if (Array.isArray(current[finalKey])) { + if (value !== '') { // Skip empty values (Rails hidden field) + current[finalKey].push(value); + } + } else { + current[finalKey] = [current[finalKey], value].filter(v => v !== ''); } } else { - current[finalKey] = value; + // First occurrence of this key - if it's empty, might be a checkbox array with no selections + current[finalKey] = value === '' && key.includes('[]') ? [] : value; } } else { jsonData[key] = value; @@ -1101,7 +1118,21 @@ window.submitCategoryForm = function(event) { current = current[part]; } const finalKey = keyParts[keyParts.length - 1]; - current[finalKey] = value; + + // Handle checkbox arrays (multiple values with same key) + if (current[finalKey] !== undefined) { + // If key already exists, convert to array or append to existing array + if (Array.isArray(current[finalKey])) { + if (value !== '') { // Skip empty values (Rails hidden field) + current[finalKey].push(value); + } + } else { + current[finalKey] = [current[finalKey], value].filter(v => v !== ''); + } + } else { + // First occurrence of this key - if it's empty, might be a checkbox array with no selections + current[finalKey] = value === '' && key.includes('[]') ? [] : value; + } } else { jsonData[key] = value; } @@ -1190,9 +1221,19 @@ function handleFieldFormSuccess(form, response) { if (!matches) return; const fieldId = matches[1]; - const fieldItem = document.querySelector(`[data-field-id="${fieldId}"]`); + const fieldItem = document.querySelector(`[data-field-id="${fieldId}"]`); if (!fieldItem) return; + + // For field updates, reload the field item with fresh server-rendered HTML + // This ensures all changes (label, linkable_types, visibility, etc.) are reflected + if (response.field && response.html) { + // Replace the existing field item with the updated one + fieldItem.outerHTML = response.html; + console.log(`Updated field "${response.field.label}" UI with server-rendered HTML`); + return; + } + // Fallback: Manual updates if no HTML provided (legacy support) // Update field display if label changed if (response.field && response.field.label) { const labelElement = fieldItem.querySelector('.field-label'); diff --git a/app/views/content/attributes/tailwind/_category_card.html.erb b/app/views/content/attributes/tailwind/_category_card.html.erb index 00790f39..31e0f25f 100644 --- a/app/views/content/attributes/tailwind/_category_card.html.erb +++ b/app/views/content/attributes/tailwind/_category_card.html.erb @@ -169,22 +169,49 @@
- -
+
+ +
+ + +
+
+ + + + +
<% Rails.application.config.content_types[:all].each do |content_type| %> -
- + - <%= content_type.icon %> - <%= content_type.name.pluralize %> - -
+ id="link_type_<%= content_type.name.downcase %>_new_<%= category.id %>" + class="h-4 w-4 border-gray-300 rounded focus:ring-2 focus:ring-offset-2 mr-3" + style="color: <%= content_type_class.hex_color %>; --tw-ring-color: <%= content_type_class.hex_color %>;"> + +
+
+ <%= content_type.icon %> +
+ +
+ <%= content_type.name.pluralize %> +
+
+ <% end %>
+

Select which page types users can link to from this field.

diff --git a/app/views/content/attributes/tailwind/_field_item.html.erb b/app/views/content/attributes/tailwind/_field_item.html.erb index 57363793..71e339a3 100644 --- a/app/views/content/attributes/tailwind/_field_item.html.erb +++ b/app/views/content/attributes/tailwind/_field_item.html.erb @@ -38,6 +38,24 @@ archive <% end %>
+ + + <% if field.field_type == 'link' && field.field_options&.dig('linkable_types')&.any? %> +
+ link + <% linkable_types = field.field_options['linkable_types'] || [] %> + <% content_types = get_linkable_content_types(linkable_types) %> + <% content_types.first(5).each do |content_type| %> + + <%= content_type.icon %> + + <% end %> + <% if content_types.length > 5 %> + +<%= content_types.length - 5 %> more + <% end %> +
+ <% end %> +
<% if field.name_field? %> Name field