module DepartmentsHelper def render_department_rows(departments, level) html = ''.html_safe departments.each do |dept| html << render_department_row(dept, level) html << render_department_rows(dept.children.sorted, level + 1) if dept.children.any? end html end def render_department_row(dept, level) indent = ('    ' * level).html_safe prefix = level > 0 ? '└ '.html_safe : ''.html_safe leader = dept.effective_leader member_count = dept.all_members.count content_tag(:tr) do content_tag(:td) do indent + prefix + link_to(dept.name, department_path(dept), class: 'icon icon-group') end + content_tag(:td) do type_badge(dept.department_type) end + content_tag(:td) do if leader name = link_to(leader.name, user_path(leader)) badge = dept.has_acting_leader? ? content_tag(:span, '대결', style: 'background: #ffc107; color: #333; padding: 1px 5px; border-radius: 3px; font-size: 10px; margin-left: 3px;') : ''.html_safe name + badge else '-'.html_safe end end + content_tag(:td, member_count) + content_tag(:td) do link_to('관리', department_path(dept), class: 'icon icon-edit') + ' '.html_safe + link_to('수정', edit_department_path(dept), class: 'icon icon-edit') + ' '.html_safe + link_to('삭제', "/org_chart/#{dept.id}", method: :delete, data: { confirm: '정말 삭제하시겠습니까?' }, class: 'icon icon-del') end end end def type_badge(type) colors = { 'ceo' => '#dc3545', 'executive' => '#6f42c1', 'division' => '#007bff', 'team' => '#28a745' } labels = { 'ceo' => 'CEO', 'executive' => 'C-Level', 'division' => '본부', 'team' => '팀' } color = colors[type] || '#6c757d' label = labels[type] || type content_tag(:span, label, style: "background: #{color}; color: white; padding: 2px 8px; border-radius: 3px; font-size: 11px;") end # 본부와 하위 팀을 렌더링 (팀은 세로 배열) def render_org_branch(division) teams = Department.teams.where(parent_id: division.id).sorted content_tag(:div, class: 'org-node') do card = content_tag(:div, class: 'org-card org-division', onclick: "location.href='#{department_path(division)}'") do html = content_tag(:div, '본부', class: 'org-type') html += content_tag(:h4, division.name) if division.effective_leader leader_class = division.has_acting_leader? ? 'org-leader acting' : 'org-leader' leader_text = division.has_acting_leader? ? "대결: #{division.effective_leader.name}" : division.effective_leader.name html += content_tag(:div, leader_text, class: leader_class) else html += content_tag(:div, '(본부장 미지정)', class: 'org-leader no-leader') end html += content_tag(:div, "#{division.all_members.count}명", class: 'org-members') html end if teams.any? children = content_tag(:div, class: 'org-branch-children-vertical') do teams.map do |team| content_tag(:div, class: 'org-node-vertical') do content_tag(:div, class: 'org-card org-team', onclick: "location.href='#{department_path(team)}'") do t_html = content_tag(:div, '팀', class: 'org-type') t_html += content_tag(:h4, team.name) if team.effective_leader leader_class = team.has_acting_leader? ? 'org-leader acting' : 'org-leader' leader_text = team.has_acting_leader? ? "대결: #{team.effective_leader.name}" : team.effective_leader.name t_html += content_tag(:div, leader_text, class: leader_class) else t_html += content_tag(:div, '(팀장 미지정)', class: 'org-leader no-leader') end t_html += content_tag(:div, "#{team.all_members.count}명", class: 'org-members') t_html end end end.join.html_safe end card + children else card end end end end