import { AntiDebug } from '../../anti_debugging.js'; let antiDebug = new AntiDebug(); import { vars } from './archive/variable.js'; import { Permission } from './archive/userPermission.js'; import { docVars } from './officialDoc/docVariable.js'; import { overviewVars } from './overview/overviewVariable.js'; import {getMyDownloadList} from './archive/common.js'; // import iconv from 'https://cdn.jsdelivr.net/npm/iconv-lite@0.6.3/lib/index.min.js'; import { initProjectSetting } from './archive/projectSetting.js'; document.addEventListener('DOMContentLoaded', async function() { //// .env파일에 저장된 배포 타입, 클라우드 타입 가져와서 전역변수에 storageType, cloudType 으로 저장 let getEnvDataRes = await axios.get('/common/getEnvData'); vars.storageType = getEnvDataRes.data.deploymentType; vars.cloudType = getEnvDataRes.data.cloudType; vars.serviceName = getEnvDataRes.data.serviceName; docVars.storageType = getEnvDataRes.data.deploymentType; //// 프로젝트 정보 가져와서 전역변수에 저장 let projectRes = await axios.get('/common/getProject'); for (let project of projectRes.data.data) { vars.allProject[project.project_id] = project; } vars.project = vars.allProject[vars.project_id]; //// 타이틀 설정 await setTitle(); //// 프로젝트별 최대 용량 설정 vars.bucketMaxSize = (vars.project) ? parseInt(vars.project.storage_byte) * 1024 * 1024 * 1024 : 0; //// 유저 정보 객체 가져와서 스트링으로 전역 변수에 저장 let authStatusRes = await axios.get('/auth/status',{ params: { project_id: vars.project_id } }); let userInfo = authStatusRes.data.user; vars.userInfoString = JSON.stringify(userInfo); //////// pm-bcmf 연결용 테스트 코드 - BCMF 유저 정보 생성, 타이틀 커서 스타일 변경, 자동 경로 이동용 변수 설정 let getBcmfUrlQueryRes = await axios.get('/auth/getBcmfUrlQuery'); if (getBcmfUrlQueryRes.data.bcmfId && getBcmfUrlQueryRes.data.bcmfId.includes('bcmf-')) { // BCMF 유저 정보 생성 let permission = (getBcmfUrlQueryRes.data.bcmfId.split('-')[1] == 'viewer') ? 1 : 7 userInfo = { user_id: getBcmfUrlQueryRes.data.bcmfId, user_nm: "BCMF", company: "BCMF", dept: "대산당진 2공구", position: "", group: "bcmf", is_resigned: false, permission: permission, bookmark: null, } vars.userInfoString = JSON.stringify(userInfo); // 타이틀에 마우스 올렸을 때 기본 커서로 표시 document.querySelector('body > .header .left .title').style.cursor = 'default'; // bcmf에서 iframe으로 pm 화면 연결하는 경우 헤더, 푸터 숨김 document.querySelector('body > .header').style.display = 'none'; document.querySelector('body > .footer').style.display = 'none'; // 헤더가 숨겨져 있으므로 높이에서 footer height(2.25rem)만 빼고, top은 0으로 설정 document.querySelectorAll('body > .main').forEach(main => { main.style.height = '100dvh'; main.style.top = '0'; }) // 시작경로를 파라미터로 전달한 경우 해당 경로로 자동 이동을 위한 변수 설정 if (getBcmfUrlQueryRes.data.startPath) { let startPath = getBcmfUrlQueryRes.data.startPath; let startPathSplit = startPath.split('/'); vars.startPathDepth1 = startPathSplit[0]; vars.startPathDepth2 = startPathSplit[1]; vars.startPathDepth3 = startPathSplit[2]; } } if (checkProjectInactive()) setProjectInactive('lock'); // vars.allProject에서 각 프로젝트별 배너 공지(banner_notice) 사용해서 배너 공지 표시/해제 설정 toggleBannerNoticeArea(); //// 접속 인원 모달창에 프로젝트 담당자 표시 // let projectManagerName = document.querySelector('.archive-modal .modal-header > .title .right-wrap .project-manager-name'); let projectManagerName = document.querySelector('.archive-modal .modal-wrap .modal-body .connected-users-wrap .project-setting-wrap .project-manager-wrap .project-manager-name'); projectManagerName.textContent = (vars.project) ? `${vars.project.user_nm} ${vars.project.position}` : '-'; if (vars.project && !vars.project.user_nm) projectManagerName.textContent = '-'; // 유저 정보로 permission 객체 생성 vars.permission = new Permission(); //permission 객체 수정 못하도록 freeze Object.freeze(vars.permission); Object.freeze(Object.prototype); // 조건 위치를 permission 객체 함수를 사용하기 위해 객체 생성 이후로 위치 조정 main.js/33 -> main.js/47 // 개발자 계정인 경우 if (vars.permission.checkPermission('project-inactive-sign')) { // 프로젝트가 비활성화 상태이면 project-inactive-sign on if (!vars.project.is_active) { document.querySelector('.project-inactive-sign').style.display = 'flex'; } } //// 각 페이지별 index.js 임포트 const archiveIndex = await import(`./archive/index.js`); if (!archiveIndex.isLoaded) { archiveIndex.loadArchive(); } // 과업개요 index.js 임포트 if(vars.project && vars.project.overview) await import(`./overview/index.js`); //// 유저 권한에 따라 초기 dom객체 표시 or 삭제 await removeDomByPermission(userInfo); //// 컴포넌트 초기 설정 await componentsInit(); //// 실시간 마우스 표시 document.addEventListener('mousemove', throttle((event) => { vars.socket.emit('setMouseInfo', { x: event.clientX / window.innerWidth, y: event.clientY / window.innerHeight, }); }, 10)); vars.socket.on('setMouse', (data) => { // 자신의 커서는 생성하거나 업데이트하지 않음 if (data.clientId === vars.socket.id) { return; } if (!vars.cursors[data.clientId]) { // 새로운 클라이언트 ID에 대한 커서 생성 let cursor = document.createElement('div'); cursor.className = 'cursor'; let wrap = document.createElement('div'); wrap.className = 'wrap'; let userInfo = data; let userColor = data.userColor; let userText = document.createElement('div'); userText.className = 'user-text'; userText.textContent = `${userInfo.user_nm} ${userInfo.position}`; // userText.style.color = userColor; userText.style.background = userColor; let cursorSvg = ` `; // let cursorSvg = ` // // // // `; cursor.innerHTML = cursorSvg; wrap.appendChild(userText); cursor.appendChild(wrap); document.body.appendChild(cursor); vars.cursors[data.clientId] = cursor; vars.cursors[data.clientId].id = data.clientId; vars.cursors[data.clientId].timer = setTimeout(() => { if (vars.cursors[clientId]) { vars.cursors[clientId].remove(); delete vars.cursors[clientId]; } }, 3000); } // 커서 위치 업데이트 vars.cursors[data.clientId].style.left = (data.x * window.innerWidth - 7) + 'px'; vars.cursors[data.clientId].style.top = data.y * window.innerHeight + 'px'; //타이머 재설정 if (vars.cursors[data.clientId].timer) { clearTimeout(vars.cursors[data.clientId].timer); } vars.cursors[data.clientId].timer = setTimeout(() => { if (vars.cursors[data.clientId]) { vars.cursors[data.clientId].remove(); delete vars.cursors[data.clientId]; } }, 3000); }); vars.socket.on('userDisconnected', (clientId) => { // 연결이 끊긴 클라이언트의 커서 제거 if (vars.cursors[clientId]) { vars.cursors[clientId].remove(); delete vars.cursors[clientId]; } }); save_user(); }); // ** 권한 관련 async function removeDomByPermission(userInfo) { if (userInfo.permission != undefined || userInfo.permission != null || userInfo.permission != '') { // 기능별 권한이 변경될 경우를 고려해서 각자 개별 분리 시켜주었습니다. // 개발자도구 모달 const devMenuModal = document.querySelector('.dev-menu-modal'); // 개발자도구 모달은 키는 함수가 따로 있기 때문에 권한이 없다면 DOM 삭제만 진행 if(devMenuModal){ if(!vars.permission.checkPermission('dev-menu')) devMenuModal.remove(); } // 헤더 폴더 추가 버튼 (부관리자 이상) const headerMenuAddBtn = document.querySelector('.menu-add'); if(headerMenuAddBtn){ if(vars.permission.checkPermission('set-user-permission')){ headerMenuAddBtn.style.setProperty('display', 'flex', 'important'); } else { headerMenuAddBtn.remove(); } } // 유저 권한 설정 버튼 (부관리자 이상) const setUserPermissionBtn = document.querySelector('.set-user-permission-btn'); if(setUserPermissionBtn){ if(vars.permission.checkPermission('set-user-permission')){ setUserPermissionBtn.style.setProperty('display', 'flex', 'important'); } else { setUserPermissionBtn.remove(); } } // 과업개요 왼쪽 영역 수정 버튼 (부관리자 이상) const overviewSectionLeftBtn = document.querySelector('.overview .section-left-edit'); if(overviewSectionLeftBtn){ if(vars.permission.checkPermission('overview-left-edit')){ overviewSectionLeftBtn.style.setProperty('display', 'flex', 'important'); } else { overviewSectionLeftBtn.remove(); } } // 과업개요 가운데 영역 수정 버튼 (부관리자 이상) const overviewSectionMiddleBtn = document.querySelector('.overview .section-middle-edit'); if(overviewSectionMiddleBtn){ if(vars.permission.checkPermission('overview-middle-edit')){ overviewSectionMiddleBtn.style.setProperty('display', 'flex', 'important'); } else { overviewSectionMiddleBtn.remove(); } } // 과업개요 주요 현안 및 이슈 수정 버튼 (부관리자 이상) const overviewIssueBtn = document.querySelector('.overview .issue-edit'); if(overviewIssueBtn){ if(vars.permission.checkPermission('overview-issue-edit')){ overviewIssueBtn.style.setProperty('display', 'flex', 'important'); } else { overviewIssueBtn.remove(); } } // 과업개요 - 과업기간 - 변동내역 모달 - 리스트 추가 버튼 (부관리자 이상) const overviewTaskHistoryAddBtn = document.querySelector('.overview-modal .task-history-add'); if(overviewTaskHistoryAddBtn){ if(vars.permission.checkPermission('overview-task-history-add')){ overviewTaskHistoryAddBtn.style.setProperty('display', 'flex', 'important'); } else { overviewTaskHistoryAddBtn.remove(); } } // 과업개요 - 과업기간 - 변동내역 모달 - 저장 버튼 (부관리자 이상) const overviewTaskHistorySaveBtn = document.querySelector('.overview-modal .task-history-save'); if(overviewTaskHistorySaveBtn){ if(vars.permission.checkPermission('overview-task-history-save')){ overviewTaskHistorySaveBtn.style.setProperty('display', 'flex', 'important'); } else { overviewTaskHistorySaveBtn.remove(); } } // 과업개요 - 주요일정 - 일정 추가버튼 (일반 참여자 이상) const overviewScheduleAddBtn = document.querySelector('.overview .add-schedule-btn'); if(overviewScheduleAddBtn){ if(vars.permission.checkPermission('overview-schedule-add')){ overviewScheduleAddBtn.style.setProperty('display', 'flex', 'important'); } else { overviewScheduleAddBtn.remove(); } } // 아카이브 - 메모 - AI버튼 (일반 참여자 이상) const memoAiBtn = document.querySelector('.memo .ai-btn'); if(memoAiBtn){ if(vars.permission.checkPermission('memo-ai')){ memoAiBtn.style.setProperty('display', 'flex', 'important'); } else { memoAiBtn.remove(); } } // 아카이브 - 메모 - 수정버튼 (일반 참여자 이상) const memoEditBtn = document.querySelector('.memo .edit-btn'); if(memoEditBtn){ if(vars.permission.checkPermission('memo-edit')){ memoEditBtn.style.setProperty('display', 'flex', 'important'); } else { memoEditBtn.remove(); } } // 폴더 다운로드 버튼 - 관리자 이상 const downloadFolderBtn = document.querySelector('.header .download-btn'); if(downloadFolderBtn){ if(vars.permission.checkPermission('download-folder')){ await getMyDownloadList(); downloadFolderBtn.style.setProperty('display', 'flex', 'important'); } else { downloadFolderBtn.remove(); } } // 프로젝트 step, type, name 변경 - 관리자 이상 const projectStepBtn = document.getElementById('project-step-btn'); const projectStepCapsule = document.getElementById('project-step-capsule'); const projectTypeBtn = document.getElementById('project-type-btn'); const projectTypeCapsule = document.getElementById('project-type-capsule'); if(projectStepBtn && projectStepCapsule && projectTypeBtn && projectTypeCapsule) { if(vars.project.category === 'overseas') { initProjectSetting('overseas'); } else if (vars.project.category === 'bimproject') { initProjectSetting('bimproject'); } else { initProjectSetting(); } } // if(projectStepBtn && projectStepCapsule && projectTypeBtn && projectTypeCapsule && (window.location.href.toLowerCase().includes('bim.') || window.location.href.toLowerCase().includes('overseas.'))){ // if(projectStepBtn && projectStepCapsule && projectTypeBtn && projectTypeCapsule && (window.location.href.toLowerCase().includes('172.') || window.location.href.toLowerCase().includes('overseas.'))){ // initProjectSetting(); // } //#임시# 프로젝트 step, type 변경 - 관리자 이상 //step // const projectStepBtn = document.getElementById('project-step-btn'); // const projectStepCapsule = document.getElementById('project-step-capsule'); // if(projectStepBtn && projectStepCapsule && (window.location.href.toLowerCase().includes('bim.') || window.location.href.toLowerCase().includes('overseas.'))){ // if(vars.permission.checkPermission('change-project-step')) { // projectStepCapsule.remove(); // projectStepBtn.innerHTML = ` //
${typeStep2Kor(vars.project.step)}
// `; // } else { // projectStepBtn.remove(); // projectStepCapsule.innerHTML = typeStep2Kor(vars.project.step); // projectStepCapsule.classList.add(`--step-capsule__${vars.project.step}`); // } // }else{ // projectStepCapsule.remove(); // projectStepBtn.remove(); // } // //type // const projectTypeBtn = document.getElementById('project-type-btn'); // const projectTypeCapsule = document.getElementById('project-type-capsule'); // if(projectTypeBtn && projectTypeCapsule && window.location.href.toLowerCase().includes('bim.')){ // if(vars.permission.checkPermission('change-project-type')) { // projectTypeCapsule.remove(); // projectTypeBtn.innerHTML = ` //
${typeStep2Kor(vars.project.project_type)}
// `; // } else { // projectTypeBtn.remove(); // projectTypeCapsule.innerHTML = typeStep2Kor(vars.project.project_type); // } // }else{ // projectTypeCapsule.remove(); // projectTypeBtn.remove(); // } // //// 권한이 개발자인 경우 // document.querySelectorAll('.permission-min-dev').forEach(elem => { // if (vars.permission.checkPermission('dev-menu')) { // 나중에 개발자 코드 변경될 예정 // Permission Class Test 250621 // if (elem.classList.contains('dev-menu-modal')) return; // 개발자 메뉴 모달은 바로 flex로 설정할 필요 없으므로 제외 // elem.style.setProperty('display', 'flex', 'important'); // } else { // elem.remove(); // } // }) //// 권한이 부관리자 이상인 경우 // document.querySelectorAll('.permission-min-sub-master').forEach(elem => { // if (vars.permission.checkPermission('permission-btn') || vars.permission.checkPermission('overview-left-edit')) { // elem.style.setProperty('display', 'flex', 'important'); // } else { // elem.remove(); // } // }) // //// 권한이 보안참여자 미만인 경우 // document.querySelectorAll('.permission-min-security-worker').forEach(elem => { // if (userInfo.permission < 15) { // elem.remove(); // } else { // elem.style.setProperty('display', 'flex', 'important'); // } // }) // //// 권한이 일반참여자 미만인 경우 // document.querySelectorAll('.permission-min-worker').forEach(elem => { // // 현재 main.html에서 .ai-btn, .edit-btn (메모 ai, 수정 버튼)클래스에 permission-min-worker 추가 // if (userInfo.permission < 7) { // elem.remove(); // } else { // elem.style.setProperty('display', 'flex', 'important'); // } // }) } } //type, step 한글화 export function typeStep2Kor(param){ let result = undefined; switch(param){ case 'done': result = '완료'; break; case 'active': result = '진행'; break; case 'stop': result = '중지'; break; case 'wait': result = '대기'; break; case 'construction': result = '시공'; break; case 'design': result = '설계'; break; case 'surgest': result = '제안'; break; case 'research': result = '연구'; break; case 'support': result = '지원'; break; case 'center': result = '센터'; break; case 'survey': result = '측량'; break; // case 'ETC': // result = '기타'; // break; case 'MP': result = 'MP (기본계획)'; break; case 'DD': result = 'DD (실시설계)'; break; case 'FS': result = 'FS (타당성조사)'; break; case 'PD': result = 'PD (기본설계)'; break; case 'DS': result = 'DS (설계감리)'; break; case 'CS': result = 'CS (시공감리)'; break; case 'PMC': result = 'PMC (실시설계)'; break; case 'IDC': result = 'IDC (타당성조사)'; break; case 'DR': result = 'DR (설계검토)'; break; case 'ETC': result = 'ETC (기타)'; break; default: result = '없음'; break; } return result; } async function setTitle() { // 타이틀 카테고리 이미지 및 프로젝트명 설정 후 마르퀴효과 적용 // document.querySelector('.header .left .title .marquee-track .category').src = `/main/img/header/header-logo-${vars.project.category}.svg`; let category = '-'; let projectNm = '-'; if (vars.project) { category = vars.project.category.toUpperCase(); projectNm = vars.project.project_nm; } document.querySelector('.header .left .title .marquee-track .category').innerHTML = category; document.querySelector('.header .left .title .marquee-track .project-name').innerHTML = projectNm; if (vars.project) await startMarquee('title'); } async function componentsInit() { // 헤더 - 프로젝트에 포함되지 않은 계정인 경우 헤더 버튼 삭제 // 헤더 - 프로젝트 db에서 과업개요, 공문, 위치기반모델 사용 여부에 따라 헤더 버튼 삭제 // 푸터 - 프로젝트에 포함되지 않은 계정인 경우 푸터 저장공간/활동로그 삭제 // 프로젝트가 비활성화 상태면 리턴 if (checkProjectInactive()) return; let overviewMain = document.querySelector('.overview-main'); let overviewBtn = document.querySelector('.header .overview-btn'); let overviewModalWrapper = document.querySelector('.overview-modal-wrapper'); let officialDocMain = document.querySelector('.official-doc-main'); let officialDocBtn = document.querySelector('.header .official-doc-btn'); let officialDocModalBackground = document.querySelector('.official-doc-modal-background'); let officialDocModalAll = document.querySelectorAll('.official-doc-modal'); let modelBtn = document.querySelector('.header .model-btn'); let mainNotice = document.querySelector('.main-notice'); let userInfo = JSON.parse(vars.userInfoString); if ((userInfo.permission == null && typeof userInfo.permission != 'number')) { // 프로젝트에 포함되어 있지 않은 사용자는 프로젝트 비활성화 setProjectInactive('permission'); } else { // ** 권한 관련 // 참관자 권한일 때 활동로그 삭제 // if (userInfo.permission == 1) logWrap.remove(); // 프로젝트 db에서 과업개요, 공문, 위치기반모델 사용 여부에 따라 버튼 삭제 if (vars.project.overview) { overviewBtn.style.display = 'flex'; } else { if (overviewMain) overviewMain.remove(); if (overviewBtn) overviewBtn.remove(); if (overviewModalWrapper) overviewModalWrapper.remove(); } if (vars.project.official_doc) { officialDocBtn.style.display = 'flex'; } else { if (officialDocMain) officialDocMain.remove(); if (officialDocBtn) officialDocBtn.remove(); if (officialDocModalBackground) officialDocModalBackground.remove(); if (officialDocModalAll.length != 0) { officialDocModalAll.forEach(elem => { elem.remove(); }) } } if (vars.project.gsim) modelBtn.style.display = 'flex'; else modelBtn.remove(); } } async function startMarquee(type) { let trackContainer; if (type == 'title') trackContainer = document.querySelector('body > .header .left .title'); if (type == 'bannerNotice') trackContainer = document.querySelector('body > .banner-notice-area .content'); let originalTrack = trackContainer.querySelector('.marquee-track'); if(window.location.origin.includes('gtb.')){ // gtb 임시코드 // document.querySelectorAll('.marquee-track-wrap .pm, .marquee-track-wrap .symbol, .marquee-track-wrap .category').forEach(e=>e.style.display='none'); originalTrack.querySelector('.pm').style.display = 'none'; originalTrack.querySelectorAll('.symbol').forEach(e => e.style.display = 'none'); originalTrack.querySelector('.category').style.display = 'none'; } const createMarqueeInstance = async (container, originalTrack) => { const wrap = document.createElement('div'); wrap.classList.add('marquee-track-wrap'); const cloneTrack1 = originalTrack.cloneNode(true); const cloneTrack2 = originalTrack.cloneNode(true); wrap.appendChild(originalTrack.cloneNode(true)); wrap.appendChild(cloneTrack1); wrap.appendChild(cloneTrack2); container.innerHTML = ''; container.appendChild(wrap); const setMarquee = (entries, wrap) => { const pixelsPerSecond = 40; const firstTrack = wrap.querySelector('.marquee-track:first-child'); if (!firstTrack) return; const trackWidth = firstTrack.getBoundingClientRect().width; if (trackWidth === 0) return; const duration = trackWidth / pixelsPerSecond; wrap.style.setProperty('--duration', `${duration}s`); wrap.style.setProperty('--translateX', `-${trackWidth}px`); }; // 초기 마르퀴 설정 // setTimeout(async function () { // await setMarquee(null, wrap); // }, 500); // 타이틀/배너 공지 크기 변화 감지되면 다시 마르퀴 설정 setTimeout(async function () { let observer = new ResizeObserver(async (entries, observer) => { await setMarquee(entries, wrap); }); observer.observe(container); }, 500); //// 초기 마르퀴 설정 안해도 정상 작동? }; createMarqueeInstance(trackContainer, originalTrack); } //user정보 저장 function save_user() { if (vars.lastHeaderBtn) { let me = JSON.parse(vars.userInfoString); me.project_id = vars.project_id; me.userColor = getRandomColor(); me.curPath = vars.lastHeaderBtn.dataset.resourcePath; me.origin = window.location.origin; vars.socket.emit('setUser', { me: me, stat: 'first', origin: window.location.origin}); } } export function checkProjectInactive() { // vars.project.is_active는 프로젝트가 활성화 되어 있으면 true, 비활성화 되어 있으면 false // checkProjectInactive() 함수는 프로젝트가 비활성화 상태인지를 체크하는 함수이므로 // 활성화 되어 있으면 true, 비활성화 되어 있으면 false를 리턴해야됨 (vars.project.is_active와 반대) // 비활성화 된 프로젝트 배열 안에 현재 프로젝트 아이디가 포함되어 있으면 비활성화 상태(true)로 리턴 let result = (vars.project) ? !vars.project.is_active : false; // 관리자 계정인 경우 무조건 활성화 상태(false)로 리턴 if (JSON.parse(vars.userInfoString).group == 'dev') result = false; return result; } export async function toggleBannerNoticeArea() { let userInfo = JSON.parse(vars.userInfoString); let userId = userInfo.user_id; // if (userId.includes('bcmf-')) { // } else { let bannerNoticeArea = document.querySelector('body > .banner-notice-area'); let bannerNoticeContent = bannerNoticeArea.querySelector('.content'); let header = document.querySelector('body > .header'); let mainAll = document.querySelectorAll('body > .main'); bannerNoticeArea.style.justifyContent = 'center'; bannerNoticeContent.innerHTML = ''; let textWrap = document.createElement('div'); textWrap.classList.add('text-wrap'); let text = document.createElement('div'); text.classList.add('text'); textWrap.appendChild(text); bannerNoticeContent.appendChild(textWrap); let noticeText = (vars.project) ? vars.project.banner_notice : ''; if (noticeText == '' || noticeText == undefined || noticeText == null) { bannerNoticeArea.style.display = 'none'; text.innerHTML = ''; header.style.top = '0'; mainAll.forEach(main => { if (userId.includes('bcmf-')) { // bcmf에서 iframe으로 pm 화면 연결하는 경우 헤더, 푸터가 숨겨져 있으므로 높이는 100dvh로, top은 0으로 설정 main.style.height = '100dvh'; main.style.top = '0'; } else { main.style.height = 'calc(100dvh - 2.25rem - 2.25rem)'; main.style.top = '2.25rem'; } }) } else { bannerNoticeArea.style.display = 'flex'; text.innerHTML = noticeText; header.style.top = '2.25rem'; mainAll.forEach(main => { if (userId.includes('bcmf-')) { // bcmf에서 iframe으로 pm 화면 연결하는 경우 헤더, 푸터가 숨겨져 있으므로 높이에서 banner-notice-area height(2.25rem) 빼고, top은 2.25rem으로 설정 main.style.height = 'calc(100dvh - 2.25rem)'; main.style.top = '2.25rem'; } else { main.style.height = 'calc(100dvh - 2.25rem - 2.25rem - 2.25rem)'; main.style.top = '4.5rem'; } }) if (textWrap.getBoundingClientRect().width > bannerNoticeArea.getBoundingClientRect().width - 10) { textWrap.classList.add('marquee-track'); bannerNoticeArea.style.justifyContent = 'flex-start'; await startMarquee('bannerNotice'); } } // } } export function setProjectInactive(type, text) { // 프로젝트 비활성화 된 경우 초기 프로그레스 종료 document.querySelector('.init-progress').style.display = 'none'; let archiveMain = document.querySelector('.archive-main'); let permissionModal = document.querySelector('.permission-modal'); let overviewMain = document.querySelector('.overview-main'); let overviewBtn = document.querySelector('.header .overview-btn'); let overviewModalWrapper = document.querySelector('.overview-modal-wrapper'); let officialDocMain = document.querySelector('.official-doc-main'); let officialDocBtn = document.querySelector('.header .official-doc-btn'); let officialDocModalBackground = document.querySelector('.official-doc-modal-background'); let officialDocModalAll = document.querySelectorAll('.official-doc-modal'); let headerCenterLeft = document.querySelector('.header > .center .left.wrap'); let headerCenterRight = document.querySelector('.header > .center .right.wrap'); let sizeWrap = document.querySelector('.footer .size-wrap'); let logWrap = document.querySelector('.footer .log-wrap'); let setUserPermissionBtn = document.querySelector('.archive-modal .set-user-permission-btn'); let mainNotice = document.querySelector('.main-notice'); if (archiveMain) archiveMain.remove(); if (permissionModal) permissionModal.remove(); if (overviewMain) overviewMain.remove(); if (overviewBtn) overviewBtn.remove(); if (overviewModalWrapper) overviewModalWrapper.remove(); if (officialDocMain) officialDocMain.remove(); if (officialDocBtn) officialDocBtn.remove(); if (officialDocModalBackground) officialDocModalBackground.remove(); if (officialDocModalAll.length != 0) { officialDocModalAll.forEach(elem => { elem.remove(); }) } if (headerCenterLeft) headerCenterLeft.remove(); if (headerCenterRight) headerCenterRight.remove(); if (sizeWrap) sizeWrap.remove(); if (logWrap) logWrap.remove(); if (setUserPermissionBtn) setUserPermissionBtn.remove(); let mainNoticeText = ''; if (type == 'permission') { // mainNoticeText = ` //
${JSON.parse(vars.userInfoString).user_nm} 님은 ${vars.project.project_nm} 프로젝트에 포함되어 있지 않습니다.
//
프로젝트 참가 신청 또는 문의사항은 프로젝트 담당자에게 연락해 주시기 바랍니다.
//
프로젝트 담당자 : ${vars.project.user_nm} ${vars.project.position}
// `; mainNoticeText = `
${JSON.parse(vars.userInfoString).user_nm} 님은 프로젝트에 포함되어 있지 않습니다.
`; } if (type == 'lock') { if (text) { mainNoticeText = text; } else { mainNoticeText = `
프로젝트가 비활성화 상태입니다.
`; } } mainNotice.style.display = 'flex'; mainNotice.innerHTML = mainNoticeText; } export function getRandomColor() { let r, g, b; let brightness; while (true) { r = Math.floor(Math.random() * 256); g = Math.floor(Math.random() * 256); b = Math.floor(Math.random() * 256); // 밝기 계산 (0 ~ 255) brightness = (r * 299 + g * 587 + b * 114) / 1000; // 너무 밝거나 어두운 색상 필터링 if (brightness > 0 && brightness < 150) { // 각 색상 채널의 차이가 너무 작으면 필터링 if (Math.abs(r - g) > 20 || Math.abs(r - b) > 20 || Math.abs(g - b) > 20) { break; // 조건을 만족하면 루프 종료 } } } // 16진수 문자열로 변환 const hexR = r.toString(16).padStart(2, '0'); const hexG = g.toString(16).padStart(2, '0'); const hexB = b.toString(16).padStart(2, '0'); return `#${hexR}${hexG}${hexB}`; } // 임시 스로틀 export function throttle(func, limit) { let lastFunc; let lastRan; return function (...args) { const context = this; if (!lastRan) { func.apply(context, args); lastRan = Date.now(); } else { clearTimeout(lastFunc); lastFunc = setTimeout(function () { if ((Date.now() - lastRan) >= limit) { func.apply(context, args); lastRan = Date.now(); } }, limit - (Date.now() - lastRan)); } }; } window.dtest = async function() { let res = await axios.post(`${vars.path_name}/dtest`); console.log(res.data.message); } window.otest = async function() { let res = await axios.post(`${vars.path_name}/otest`); console.log(res.data.message); }