diff --git a/app/Controllers/Admin/Equipment/ServerController.php b/app/Controllers/Admin/Equipment/ServerController.php index d59081f..f172000 100644 --- a/app/Controllers/Admin/Equipment/ServerController.php +++ b/app/Controllers/Admin/Equipment/ServerController.php @@ -2,14 +2,15 @@ namespace App\Controllers\Admin\Equipment; +use App\Helpers\Equipment\ServerHelper; +use App\Services\Equipment\PartService; +use App\Services\Equipment\ServerService; + use CodeIgniter\HTTP\RequestInterface; use CodeIgniter\HTTP\ResponseInterface; +use CodeIgniter\Validation\Validation; use Psr\Log\LoggerInterface; -use App\Helpers\Equipment\ServerHelper; -use App\Services\Equipment\ServerService; -use App\Services\Equipment\PartService; - class ServerController extends EquipmentController { private ?PartService $_partService = null; @@ -46,15 +47,28 @@ class ServerController extends EquipmentController } //Index,FieldForm관련 + protected function getFieldRule(string $action, string $field): string + { + if (is_array($field)) { + throw new \Exception(__FUNCTION__ . "=> field가 array 입니다.\n" . var_export($field, true)); + } + switch ($field) { + case 'cpu_partinfo_uid': + case 'ram_partinfo_uid': + case 'disk_partinfo_uid': + $rule = "if_exist|permit_empty|numeric"; + break; + default: + $rule = parent::getFieldRule($action, $field); + break; + } + return $rule; + } protected function getFormFieldOption(string $field, array $options = []): array { switch ($field) { case 'cpu_partinfo_uid': - $options[$field] = $this->getPartService()->getFormFieldOption($field); - break; case 'ram_partinfo_uid': - $options[$field] = $this->getPartService()->getFormFieldOption($field); - break; case 'disk_partinfo_uid': $options[$field] = $this->getPartService()->getFormFieldOption($field); break; @@ -64,8 +78,48 @@ class ServerController extends EquipmentController } return $options; } - + protected function setValidation(Validation $validation, string $action, string $field, ?string $rule = null): Validation + { + switch ($field) { + case 'cpu_partinfo_uid': + case 'ram_partinfo_uid': + case 'disk_partinfo_uid': + //아래 Rule Array는 필드명.* checkbox를 사용 + $validation->setRule("{$field}.*", $field, $rule); + break; + default: + $validation = parent::setValidation($validation, $action, $field, $rule); + break; + } + return $validation; + } //Index,FieldForm관련 + + protected function create_process(): mixed + { + $entity = parent::create_process(); + //변경할 UIDS + $cpu_uids = $this->request->getVar('cpu_partinfo_uid[]'); + if (!is_array($cpu_uids) || !count($cpu_uids)) { + throw new \Exception("CPU가 정의되지 않았습니다."); + } + $ram_uids = $this->request->getVar('ram_partinfo_uid[]'); + if (!is_array($ram_uids) || !count($ram_uids)) { + throw new \Exception("RAM가 정의되지 않았습니다."); + } + $disk_uids = $this->request->getVar('cpu_partinfo_uid[]'); + if (!is_array($disk_uids) || !count($disk_uids)) { + throw new \Exception("DISK가 정의되지 않았습니다."); + } + //데이터가 있는경우 Field만 처리하기위해 + $fields = []; + foreach ($this->batchjob_fields as $field) { + if ($this->request->getVar($field)) { + $fields[] = $field; + } + } + return $this->getService()->create($this->formDatas); + } protected function index_process(): array { $fields = [ diff --git a/app/Helpers/Equipment/ServerHelper.php b/app/Helpers/Equipment/ServerHelper.php index d67acfc..8919ff5 100644 --- a/app/Helpers/Equipment/ServerHelper.php +++ b/app/Helpers/Equipment/ServerHelper.php @@ -25,16 +25,24 @@ class ServerHelper extends EquipmentHelper if (!is_array($viewDatas['field_options'][$field])) { throw new \Exception(__METHOD__ . "에서 {$field}의 field_options가 array형태가 아닙니다."); } - $formOptions = array_merge( - ["" => lang($viewDatas['class_path'] . '.label.' . $field) . ' 선택'], - $viewDatas['field_options'][$field] - ); - $extra_class = isset($extras['class']) ? $extras['class'] : ""; - $form = form_dropdown($field, $formOptions, $value, ['id' => "{$field}_Select", 'class' => $extra_class, ...array_diff_key($extras, ['class' => ''])]); if (in_array($viewDatas['action'], ['create_form', 'modify_form'])) { - $form .= ""; - $form .= ""; - $form .= "
"; + $form = " "; + $form .= "
"; + $form .= "
"; + $form .= ""; + $form .= ""; + $form .= "
"; + $form .= "
"; + } else { + $formOptions = ["" => lang($viewDatas['class_path'] . '.label.' . $field) . ' 선택']; + foreach ($viewDatas['field_options'][$field] as $key => $label) { + $formOptions[$key] = $label; + } + $form = form_dropdown($field, $formOptions, $value, $extras); } break; default: diff --git a/public/css/admin/server_partinfo.css b/public/css/admin/server_partinfo.css index 0be0775..5e069fb 100644 --- a/public/css/admin/server_partinfo.css +++ b/public/css/admin/server_partinfo.css @@ -1,29 +1,56 @@ -.layer { - display: none; - position: fixed; - top: 20%; - left: 50%; - transform: translate(-50%, -20%); - background: #fff; - border: 1px solid #ccc; - padding: 20px; - box-shadow: 0 0 10px rgba(0,0,0,0.3); - z-index: 1000; +.server_partinfo_layer_btn { + background-color: #0d6efd; /* Bootstrap 5 primary color */ + color: #fff; /* 흰색 텍스트 */ + border: 1px solid #0d6efd; + padding: 0.375rem 0.75rem; /* 기본 패딩 */ + font-size: 1rem; + line-height: 1.5; + border-radius: 0.375rem; /* 기본 border-radius */ + cursor: pointer; + text-align: center; + display: inline-block; + text-decoration: none; + transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out; } + +.server_partinfo_layer_btn:hover { + background-color: #0b5ed7; + border-color: #0a58ca; +} +.server_partinfo_layer { + position: fixed; + top: 20%; + left: 50%; + transform: translateX(-50%); + background: #fff; + border: 1px solid #ccc; + padding: 20px; + z-index: 1000; + box-shadow: 0 0 10px rgba(0,0,0,0.2); +} + +.server_partinfo_layer_inner { + text-align:center; +} + +.server_partinfo_item_list li { + margin: 5px 0; +} + +.server_partinfo_item_list label { + cursor: pointer; + color: #007bff; + text-decoration: underline; +} + +.server_partinfo_items { + margin-top: 20px; +} + .server_partinfo_item { - margin: 5px 0; + padding: 5px 10px; + background: #f0f0f0; + margin: 5px 0; + display: flex; + align-items: left; } -.list-container { - margin-top: 20px; -} -.btn { - padding: 6px 10px; - margin: 5px; - background: #007BFF; - color: #fff; - border: none; - cursor: pointer; -} -.btn:hover { - background: #0056b3; -} \ No newline at end of file diff --git a/public/js/admin/server_partinfo.js b/public/js/admin/server_partinfo.js index ebbf078..16b4068 100644 --- a/public/js/admin/server_partinfo.js +++ b/public/js/admin/server_partinfo.js @@ -1,46 +1,39 @@ -function openLayer(type) { - document.getElementById(type + '_Layer').style.display = 'block'; +function openLayer(field) { + const layer = document.getElementById(`${field}_layer`); + if (layer) layer.style.display = 'block'; } -function closeLayer(type) { - document.getElementById(type + '_Layer').style.display = 'none'; +function closeLayer(field) { + const layer = document.getElementById(`${field}_layer`); + if (layer) layer.style.display = 'none'; } -function applyCheckedComponents(type) { - const checkboxes = document.querySelectorAll(`#${type}_Layer input[type="checkbox"]:checked`); - const listDiv = document.getElementById(`${type}_List`); - - checkboxes.forEach(cb => { - // 중복 방지 - const exists = listDiv.querySelector(`input[type="hidden"][value="${cb.value}"]`); - if (exists) return; +function addComponentFromLabel(field, value, text) { + const listDiv = document.getElementById(`${field}_list`); + if (!listDiv) return; const wrapper = document.createElement('div'); wrapper.className = 'server_partinfo_item'; const checkbox = document.createElement('input'); checkbox.type = 'checkbox'; - checkbox.className = `${type}_checkbox`; + checkbox.name = `${field}[]`; + checkbox.value = value; + checkbox.checked = true; - const hiddenInput = document.createElement('input'); - hiddenInput.type = 'hidden'; - hiddenInput.name = `${type}[]`; - hiddenInput.value = cb.value; + // 체크 해제되면 해당 항목 삭제 + checkbox.addEventListener('change', () => { + if (!checkbox.checked) { + wrapper.remove(); + } + }); - const span = document.createElement('span'); - span.textContent = cb.getAttribute('data-label'); + const label = document.createElement('label'); + label.textContent = text; + label.style.marginLeft = '5px'; wrapper.appendChild(checkbox); - wrapper.appendChild(hiddenInput); - wrapper.appendChild(span); + wrapper.appendChild(label); listDiv.appendChild(wrapper); - }); - - closeLayer(type); } - -function removeCheckedComponents(type) { - const checkboxes = document.querySelectorAll(`#${type}_List .${type}_checkbox:checked`); - checkboxes.forEach(cb => cb.closest('.server_partinfo_item').remove()); -} \ No newline at end of file