redmine-org-chart/app/views/departments/show.html.erb
ioresponse b50ab25083 Initial commit: Redmine Organization Chart Plugin
🤖 Generated with Claude Code
2025-12-23 00:21:49 +09:00

180 lines
6.9 KiB
Plaintext

<h2><%= @department.name %> <span style="color: #666; font-size: 14px;">(<%= @department.type_name %>)</span></h2>
<% if @department.parent %>
<p><strong>상위 부서:</strong> <%= link_to @department.parent.name, department_path(@department.parent) %></p>
<% end %>
<% if @department.description.present? %>
<p><strong>설명:</strong> <%= @department.description %></p>
<% end %>
<hr />
<h3>리더</h3>
<table class="list" style="width: auto;">
<tr>
<th style="width: 100px;">팀장</th>
<td>
<% if @department.leader %>
<%= link_to @department.leader.name, user_path(@department.leader) %>
<span style="background: #28a745; color: white; padding: 2px 8px; border-radius: 3px; font-size: 11px; margin-left: 5px;">팀장</span>
<% else %>
<em style="color: #999;">미지정</em>
<% end %>
</td>
</tr>
<tr>
<th>대결자</th>
<td>
<% if @department.acting_leader && @department.leader.nil? %>
<%= link_to @department.acting_leader.name, user_path(@department.acting_leader) %>
<span style="background: #ffc107; color: #333; padding: 2px 8px; border-radius: 3px; font-size: 11px; margin-left: 5px;">대결</span>
<% elsif @department.acting_leader %>
<%= link_to @department.acting_leader.name, user_path(@department.acting_leader) %>
<span style="background: #6c757d; color: white; padding: 2px 8px; border-radius: 3px; font-size: 11px; margin-left: 5px;">대결 (비활성)</span>
<% else %>
<em style="color: #999;">미지정</em>
<% end %>
</td>
</tr>
</table>
<% if @department.leader || @department.acting_leader %>
<p>
<%= link_to '리더 해제', clear_leader_department_path(@department), method: :patch, class: 'icon icon-del',
data: { confirm: '리더를 해제하시겠습니까?' } %>
</p>
<% end %>
<hr />
<h3>구성원 (<%= @members.count %>명)</h3>
<% if @members.any? %>
<table class="list">
<thead>
<tr>
<th>이름</th>
<th>역할</th>
<th>작업</th>
</tr>
</thead>
<tbody>
<% @members.each do |member| %>
<tr>
<td>
<%= link_to member.user.name, user_path(member.user) %>
<% if @department.leader_id == member.user_id %>
<span style="background: #28a745; color: white; padding: 2px 8px; border-radius: 3px; font-size: 11px; margin-left: 5px;">팀장</span>
<% elsif @department.acting_leader_id == member.user_id %>
<span style="background: #ffc107; color: #333; padding: 2px 8px; border-radius: 3px; font-size: 11px; margin-left: 5px;">대결</span>
<% end %>
</td>
<td><%= member.user.login %></td>
<td>
<% unless @department.leader_id == member.user_id %>
<%= link_to '팀장 지정', set_leader_department_path(@department, user_id: member.user_id),
method: :patch, class: 'icon icon-user', title: '팀장으로 지정' %>
<% end %>
<% unless @department.acting_leader_id == member.user_id %>
<%= link_to '대결자', set_acting_leader_department_path(@department, user_id: member.user_id),
method: :patch, class: 'icon icon-user', title: '대결자로 지정' %>
<% end %>
<%= link_to '제거', remove_member_department_path(@department, user_id: member.user_id),
method: :delete, data: { confirm: '이 구성원을 제거하시겠습니까?' }, class: 'icon icon-del' %>
</td>
</tr>
<% end %>
</tbody>
</table>
<% else %>
<p class="nodata">구성원이 없습니다.</p>
<% end %>
<hr />
<h3>구성원 추가 (LDAP 검색)</h3>
<div class="box">
<p>
<label for="ldap_search">사용자 검색:</label>
<input type="text" id="ldap_search" size="30" placeholder="이름 또는 ID로 검색..." autocomplete="off" />
<span id="search_status" style="margin-left: 10px; color: #666;"></span>
</p>
<div id="search_results" style="margin-top: 10px;"></div>
</div>
<hr />
<p>
<%= link_to '목록으로', departments_path, class: 'icon icon-back' %>
<%= link_to '수정', edit_department_path(@department), class: 'icon icon-edit' %>
</p>
<%= javascript_tag do %>
var searchTimeout = null;
$('#ldap_search').on('keyup', function() {
var query = $(this).val();
if (searchTimeout) clearTimeout(searchTimeout);
if (query.length < 2) {
$('#search_results').html('');
$('#search_status').text('');
return;
}
$('#search_status').text('검색 중...');
searchTimeout = setTimeout(function() {
$.ajax({
url: '<%= search_ldap_departments_path %>',
data: { q: query },
dataType: 'json',
success: function(data) {
$('#search_status').text(data.length + '명 발견');
var html = '';
if (data.length === 0) {
html = '<p style="color: #999;">검색 결과가 없습니다.</p>';
} else {
html = '<table class="list" style="width: auto;"><thead><tr><th>ID</th><th>이름</th><th>이메일</th><th>상태</th><th></th></tr></thead><tbody>';
data.forEach(function(user) {
html += '<tr>';
html += '<td>' + user.uid + '</td>';
html += '<td>' + user.name + '</td>';
html += '<td>' + (user.email || '-') + '</td>';
html += '<td>' + (user.exists ? '<span style="color: green;">Redmine 등록됨</span>' : '<span style="color: blue;">LDAP만</span>') + '</td>';
html += '<td>';
if (user.exists) {
html += '<form action="<%= add_member_department_path(@department) %>" method="post" style="display:inline;">';
html += '<input type="hidden" name="authenticity_token" value="' + $('meta[name="csrf-token"]').attr('content') + '">';
html += '<input type="hidden" name="user_id" value="' + user.user_id + '">';
html += '<input type="submit" value="추가" class="button-positive" style="padding: 2px 10px;">';
html += '</form>';
} else {
html += '<form action="<%= add_member_department_path(@department) %>" method="post" style="display:inline;">';
html += '<input type="hidden" name="authenticity_token" value="' + $('meta[name="csrf-token"]').attr('content') + '">';
html += '<input type="hidden" name="ldap_uid" value="' + user.uid + '">';
html += '<input type="hidden" name="ldap_id" value="' + user.ldap_id + '">';
html += '<input type="submit" value="추가 (신규생성)" class="button" style="padding: 2px 10px;">';
html += '</form>';
}
html += '</td>';
html += '</tr>';
});
html += '</tbody></table>';
}
$('#search_results').html(html);
},
error: function() {
$('#search_status').text('검색 오류');
$('#search_results').html('<p style="color: red;">검색 중 오류가 발생했습니다.</p>');
}
});
}, 300);
});
<% end %>