group.rb 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. # Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
  2. class FormUpdater::Relation::Group < FormUpdater::Relation
  3. attr_accessor :lookup_parent_child_groups, :root_groups
  4. def initialize(...)
  5. super(...)
  6. @root_groups = []
  7. @lookup_parent_child_groups = {}
  8. end
  9. def options
  10. # If we have no child groups in the current list, we can handle it in a easy way, because
  11. # we have only a flat structure.
  12. if items.none? { |item| item.parent_id.present? }
  13. options = []
  14. items.each do |item|
  15. options.push({ value: item.id, label: display_name(item) })
  16. end
  17. return options
  18. end
  19. options_tree_preparation
  20. options_tree
  21. end
  22. private
  23. def relation_type
  24. ::Group
  25. end
  26. def order
  27. { name: :asc }
  28. end
  29. def display_name(item)
  30. item.name_last
  31. end
  32. def usable_group_ids
  33. @usable_group_ids ||= items.pluck(:id)
  34. end
  35. def options_tree_preparation
  36. items.each do |item|
  37. next if root_group?(item)
  38. prepare_lookup_parent_child_groups(item)
  39. end
  40. end
  41. def prepare_lookup_parent_child_groups(item)
  42. last_item = item
  43. item.all_parents.each do |parent|
  44. if !lookup_parent_child_groups.key?(parent.id)
  45. lookup_parent_child_groups[parent.id] = []
  46. end
  47. parent_child_group?(parent, last_item)
  48. last_item = parent
  49. root_group?(parent)
  50. end
  51. end
  52. def parent_child_group?(parent, item)
  53. return false if lookup_parent_child_groups[parent.id].include?(item)
  54. lookup_parent_child_groups[parent.id].push(item)
  55. true
  56. end
  57. def root_group?(item)
  58. return false if item.parent_id.present? || root_groups.include?(item)
  59. root_groups.push(item)
  60. true
  61. end
  62. def options_tree(groups = root_groups)
  63. groups.each_with_object([]) do |group, options|
  64. children = []
  65. if lookup_parent_child_groups.key?(group.id)
  66. children = options_tree(lookup_parent_child_groups[group.id])
  67. end
  68. options.push(option_array_resolved(display_name(group), group.id, usable_group_ids.exclude?(group.id), children))
  69. end
  70. end
  71. def option_array_resolved(label, value, disabled, children)
  72. resolved_option = {
  73. value: value,
  74. label: label,
  75. disabled: disabled,
  76. }
  77. if children.any?
  78. resolved_option[:children] = children
  79. end
  80. resolved_option
  81. end
  82. end