서버실의 랙배치 작업을 드래그앤 드롭을 적용하여 작업하는 코드포함하여 배포합니다.
마이앱스로 개발된 폼에서 일반적인 자바스크립트를 이용하여 확장하는 방법을 배워봅니다.
주요기능.
1. 랙구성및 서버 배치작업
2. 랙의 드래그앤 드롭으로 랙에 서버를 이동시킬수 있습니다.
3. 서버정보를 드블클릭하면 서버정보가 팝업이 됩니다.
2. 랙을 신규로 등록하고 관리합니다.
3. 서버정보를 등록합니다.
구현하기
스크립트 구현.
let dragItem ;
let overItem ;
const RackPromise = new Promise((resolv, reject)=>{
form.dataRack.addEventListener("proxyMakeDataView", e=> {
e.detail.rows.forEach(row=>{
form.serverRoom.querySelector(`.rack-room`).appendChild(createRackDiv(row));
})
resolv();
});
})
form.dataServer.addEventListener("proxyMakeDataView", e=> {
RackPromise.then(()=>{
form.serverRoom.querySelectorAll(`.rack-item`).forEach(el=>el.remove());
form.serverRoom.querySelectorAll(`.rack-base`).forEach(el=>el.setAttribute("state", "empty"));
e.detail.rows.forEach(row=>{
let rack = form.serverRoom.querySelector(`[rack_id="${row.서버랙번호}"]`);
if(!rack){
rack = form.serverRoom.querySelector(`.wait`);
}
rack.querySelector(`.rack-container`).appendChild(createServerDiv(row));
});
showPosition();
})
});
form.addEventListener("mousedown", e=>{
if(e.target.matches(".rack-item")){
e.target.setAttribute('draggable', 'true');
dragItem = e.target;
}
})
form.addEventListener("dblclick", e=>{
if(e.target.matches(".rack-item")){
let keyValue = e.target.getAttribute("keyValue");
form.dataServer.activeKey(keyValue);
form.dataServer.showPopup();
}
})
form.addEventListener('dragover', e => {
dragoverClear();
if(dragItem && e.target.matches(".rack-base") && isBaseEmptySize(e.target, parseInt(dragItem.getAttribute("u-size"))||1 )){
overItem = e.target;
}
else if(dragItem && e.target.matches(".wait .rack-container") ){
overItem = e.target;
}
if(overItem){
e.preventDefault();
e.dataTransfer.dropEffect = "move";
e.target.classList.add("hover");
}
})
form.addEventListener('drop', e => {
if(!dragItem) return;
let keyValue = dragItem.getAttribute("keyValue");
let rackNo = null;
let slotNo = null;
if(e.target.matches(".rack-base")){
rackNo = e.target.closest(".rack").getAttribute("rack_id");
slotNo = e.target.getAttribute("sno");
baseStateEmpty(dragItem);
dragItem.setAttribute("sno", slotNo);
e.target.parentElement.appendChild(dragItem);
serverDrow(dragItem);
}
else if(e.target.matches(".wait .rack-container") ){
baseStateEmpty(dragItem);
e.target.appendChild(dragItem);
}
let tr = form.dataServer.activeKey(keyValue);
tr.__ref.서버랙번호 = rackNo;
tr.__ref.선반번호 = slotNo;
dragItem = null;
})
form.addEventListener("dragend", e => {
dragoverClear();
})
function createRackDiv(row){
const rsize = row.서버탑재수||8;
const rackDiv = document.createElement("div");
rackDiv.classList.add("rack");
rackDiv.setAttribute("rack_id", row.서버랙번호);
rackDiv.setAttribute("r-size", rsize);
rackDiv.innerHTML=`
<h4 class="rack-title">${row.서버랙이름}</h4>
<div class="rack-container"></div>
<h4 class="rack-foot">${row.서버랙이름}</h4>
`;
for(let i=1; i<=rsize; i++){
const baseDiv = document.createElement("div");
baseDiv.classList.add("rack-base");
baseDiv.setAttribute("sno", i);
baseDiv.setAttribute("state", "empty");
baseDiv.innerText = `${i}`;
rackDiv.querySelector(".rack-container").appendChild(baseDiv);
}
return rackDiv;
}
function createServerDiv(row){
const serverDiv = document.createElement("div");
serverDiv.classList.add("rack-item");
serverDiv.setAttribute("keyValue", row.서버번호);
serverDiv.setAttribute("sno", row.선반번호);
serverDiv.setAttribute("u-size", row.사이즈||1);
serverDiv.innerHTML=`
${row.서버이름}
`;
const led = document.createElement("div");
led.classList.add('led');
led.innerHTML = `
<div hidden class="circle3d"></div>
<div class="circle3d green"></div>
<div class="circle3d red"></div>
`;
serverDiv.appendChild(led);
const pen = document.createElement("div");
pen.classList.add('pen');
pen.innerHTML = `
<i hidden class="fa fa-life-bouy"></i>
<i hidden class="fa fa-life-bouy fa-spin"></i>
<i class="fa fa-life-bouy fa-pulse"></i>
`;
serverDiv.appendChild(pen);
return serverDiv;
}
function showPosition(){
form.querySelectorAll(".rack[r-size]").forEach(el=>{
let rsize = parseInt(el.getAttribute("r-size"));
el.style.height = (rsize * 20 + 50) + 'px';
});
form.querySelectorAll(".rack .rack-item[sno]").forEach(el=>{
serverDrow(el);
});
form.querySelectorAll(".wait .rack-item[sno]").forEach(el=>{
let uSize = parseInt(el.getAttribute("u-size"))||1;
let height = uSize * 20;
el.style.height = height + 'px';
el.style.lineHeight = height + 'px';
});
}
function dragoverClear(){
if(overItem){
overItem.classList.remove("hover");
overItem = null;
}
}
function serverDrow(el){
let sno = parseInt(el.getAttribute("sno"));
let top = (sno-1) * 20;
el.style.top = top + 'px';
let uSize = parseInt(el.getAttribute("u-size"))||1;
let height = uSize * 20;
el.style.height = height + 'px';
el.style.lineHeight = height + 'px';
baseStateUseMark(el.parentElement, sno, uSize);
}
function baseStateUseMark(cont , sno, uSize){
for(let i=0; i < uSize; i++){
const rb = cont.querySelector(`.rack-base[sno="${ sno + i}"]`);
if(rb){
rb.setAttribute("state", "use")
}
}
}
function baseStateEmpty(item){
const cont = item.parentElement;
const sno = parseInt(item.getAttribute("sno"));
const uSize = parseInt(item.getAttribute("u-size")||1);
for(let i=0; i < uSize; i++){
const rb = cont.querySelector(`.rack-base[sno="${ sno + i}"]`);
if(rb){
rb.setAttribute("state", "empty")
}
}
}
function isBaseEmptySize(base , uSize){
const sno = parseInt(base.getAttribute("sno")||1);
const cont = base.parentElement;
let empCount = 0
for(let i=0; i < uSize; i++){
const rb = cont.querySelector(`.rack-base[sno="${ sno + i}"]`);
if(rb && rb.getAttribute("state") == "empty"){
empCount++;
}
}
return uSize == empCount;
}