frontend_attributes.rb 3.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. # Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
  2. module Gql::Queries
  3. module ObjectManager
  4. class FrontendAttributes < BaseQueryWithPayload
  5. description 'Fetch meta information about object manager attributes for usage in frontend.'
  6. argument :object, Gql::Types::Enum::ObjectManagerObjectsType, description: 'Object name to fetch meta information for'
  7. field :attributes, [Gql::Types::ObjectManager::FrontendAttributeType, { null: false }], null: false, description: 'Attributes to be shown in the frontend'
  8. field :screens, [Gql::Types::ObjectManager::ScreenAttributesType, { null: false }], null: false, description: 'Screens with attributes to be shown in the frontend'
  9. def resolve(object:)
  10. object_manager_attributes(object)
  11. end
  12. private
  13. def object_manager_attributes(object)
  14. object_attributes = ::ObjectManager::Object.new(object).attributes(context.current_user, nil, data_only: false)
  15. frontend_attributes = []
  16. frontend_screens = {}
  17. object_attributes.each do |element|
  18. next if !check_attribute_frontend_screens(frontend_screens, element.screens, element.attribute.name)
  19. frontend_attributes << frontend_attribute_fields(element)
  20. end
  21. {
  22. attributes: frontend_attributes,
  23. screens: frontend_screens.map { |screen, attributes| { name: screen, attributes: attributes } }
  24. }
  25. end
  26. def frontend_attribute_fields(element)
  27. attribute = element.attribute
  28. add_belongs_to_for_relation_attributes(attribute)
  29. {
  30. name: attribute[:name],
  31. display: attribute[:display],
  32. data_type: attribute[:data_type],
  33. data_option: attribute[:data_option],
  34. screens: element.screens,
  35. is_internal: !attribute[:editable],
  36. }
  37. end
  38. def add_belongs_to_for_relation_attributes(attribute)
  39. return if attribute[:data_option][:relation].blank? || attribute[:data_option][:belongs_to].present?
  40. attribute[:data_option][:belongs_to] = attribute[:name].humanize(capitalize: false)
  41. end
  42. def check_attribute_frontend_screens(frontend_screens, screens, name)
  43. attribute_shown = false
  44. screens.each do |screen, screen_data|
  45. frontend_screens[screen] ||= []
  46. next if !apply_screen_filter?(screen, screen_data)
  47. frontend_screens[screen] << name
  48. attribute_shown = true
  49. end
  50. attribute_shown
  51. end
  52. def apply_screen_filter?(screen, screen_data)
  53. return false if screen_data.empty?
  54. shown = screen_data['shown']
  55. return true if shown.nil? || shown == true || core_workflow_screen?(screen)
  56. false
  57. end
  58. def core_workflow_screen?(screen)
  59. core_workflow? && object_class.core_workflow_screens.include?(screen)
  60. end
  61. def core_workflow?
  62. @core_workflow ||= object_class.included_modules.include?(ChecksCoreWorkflow)
  63. end
  64. def object_class
  65. @object_class = "::#{context[:current_arguments][:object]}".constantize
  66. end
  67. end
  68. end
  69. end