redmine-org-chart/app/helpers/departments_helper.rb
ioresponse b50ab25083 Initial commit: Redmine Organization Chart Plugin
🤖 Generated with Claude Code
2025-12-23 00:21:49 +09:00

107 lines
4.2 KiB
Ruby

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 = ('&nbsp;&nbsp;&nbsp;&nbsp;' * 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