import { vars } from './variable.js';
import { toggleBannerNoticeArea } from '../main.js';
import {
addCommasToNumber,
getDepth,
// getRootFolderPath,
updatePartialPath,
splitTopPathAndTargetName,
extractPathByLength,
getDataFromTreeObject,
targetFocus
} from './common.js';
import {
removeCountdownTooltip,
preparePageRendering,
prepareRecycleBinRendering,
renderViewer,
resetViewer,
renderSizeBar,
renderLog,
renderMemo,
changeHeaderBtnStyle,
changeTreeItemStyle,
changeListItemStyle,
} from './pageRenderer.js';
import { toggleModal } from './modalManager.js'
import { mgmtFunc_addClickLog } from './managementFunctions.js';
import { updateAiButtonState } from './dataManager.js';
import { toggleArchiveMainRight } from './eventManager.js';
let archiveMain = document.querySelector('.archive-main');
let mainNotice = document.querySelector('.main-notice');
let treeContainer = document.querySelector('.archive-main-left .tree-container');
let treeNotice = document.querySelector('.archive-main-left .tree-container .tree-notice');
let treeWrap = document.querySelector('.archive-main-left .tree-container .tree-wrap');
let listContainer = document.querySelector('.archive-main-center .list-container');
let listNotice = document.querySelector('.archive-main-center .list-notice');
let listWrapBody = listContainer?.querySelector('.list-wrap.list-body');
let viewerContainer = document.querySelector('.archive-main-right .viewer-container');
let viewerNotice = document.querySelector('.archive-main-right .viewer-notice');
const socket = io();
//// 소켓은 하나만...
vars.socket = socket;
function getMyCurPath() {
if (vars.users && vars.users[socket.id] && vars.users[socket.id].curPath) {
return vars.users[socket.id].curPath;
}
if (vars.userInfoString) {
try {
return JSON.parse(vars.userInfoString).curPath || '';
} catch (e) {}
}
return '';
}
//// 접속자 정보 가져오기
export function getUsers() {
vars.socket.emit('getUsers');
}
//// 유저 정보 받기
socket.on('getUsers', async (getUsersResult) => {
let devMenuModal = document.querySelector('.dev-menu-modal');
if (devMenuModal && devMenuModal.style.display == 'flex') {
let totalUserCount = devMenuModal.querySelector('.total-user-count');
let totalUserList = devMenuModal.querySelector('.total-user-list');
// 전체 프로젝트 전역변수로 projectNameList, projectCategoryList 객체 생성
let projectNameList = {}, projectCategoryList = {};
Object.entries(vars.allProject).forEach(entry => {
let key = entry[0];
let value = entry[1];
projectNameList[key] = value.project_nm;
projectCategoryList[value.project_nm] = value.category;
})
// 소켓 getUsers로 받아온 전체 유저 데이터를 프로젝트별로 그룹화해서 groupedUsersList 객체 생성
let users = Object.values(getUsersResult);
// console.log(users);
totalUserCount.innerHTML = `전체 접속 인원 총 ${users.length} 명`;
// ecma 2024부터 Object.groupBy 사용 가능
let groupedUsersList = Object.groupBy( users, ({ project_id }) => projectNameList[project_id] || project_id );
// 접속 해제한 클라이언트 아이디를 구분하기 위해 전체 클라이언트 아이디를 담는 배열
let allClientID = [];
// 가나다순 정렬순으로 project 표시
let sortedProjectNames = Object.keys(groupedUsersList).sort((a, b) => a.localeCompare(b, 'ko'));
sortedProjectNames.forEach(projectName => {
let usersArr = groupedUsersList[projectName];
let projectDom = document.querySelector(`.dev-menu-modal .total-user-list .project[data-project-name="${projectName}"]`);
let project, projectCount, projectUserWrap;
// projectName별 dom이 존재하는지 확인해서 존재하면 기존 dom 사용하고 없으면 dom 생성
if (projectDom) {
project = projectDom;
projectCount = projectDom.querySelector('.title-wrap .count');
projectUserWrap = projectDom.querySelector('.user-wrap');
// ✅ 위치 재정렬
totalUserList.appendChild(project);
} else {
project = document.createElement('div');
project.classList.add('project');
project.dataset.projectName = projectName;
let projectTitleWrap = document.createElement('div');
projectTitleWrap.classList.add('title-wrap');
let projectText = document.createElement('div');
projectText.classList.add('text');
projectText.innerHTML = `[${projectCategoryList[projectName].toUpperCase()}] ${projectName}`;
projectCount = document.createElement('div');
projectCount.classList.add('count');
projectTitleWrap.appendChild(projectText);
projectTitleWrap.appendChild(projectCount);
projectUserWrap = document.createElement('div');
projectUserWrap.classList.add('user-wrap');
project.appendChild(projectTitleWrap);
project.appendChild(projectUserWrap);
totalUserList.appendChild(project);
}
// 프로젝트 별 접속 인원 업데이트
projectCount.innerHTML = `${usersArr.length} 명`;
// 사용자 dom 재정렬: 기존 dom 재사용 + 가나다 정렬
let existingUserDoms = Array.from(projectUserWrap.querySelectorAll('.user'));
let clientDomMap = {};
existingUserDoms.forEach(dom => {
clientDomMap[dom.dataset.clientId] = dom;
});
let currentClientId = JSON.parse(vars.userInfoString).clientId;
usersArr
.slice()
.sort((a, b) => a.user_nm.localeCompare(b.user_nm, 'ko'))
.forEach(item => {
let { clientId, user_id, user_nm, position } = item;
allClientID.push(clientId);
let userName = `${user_nm} ${position}`;
userName.trim();
let userDom = clientDomMap[clientId];
// 기존 user DOM이 없으면 생성
if (!userDom) {
userDom = document.createElement('div');
userDom.classList.add('user');
userDom.dataset.user = `${clientId}_${projectName}_${user_nm}_${position}`;
userDom.dataset.userId = user_id;
userDom.dataset.clientId = clientId;
let textWrap = document.createElement('div');
textWrap.classList.add('text-wrap');
let text = document.createElement('div');
text.classList.add('text');
text.innerHTML = `- ${user_nm} ${position}`;
let btnWrap = document.createElement('div');
btnWrap.classList.add('btn-wrap');
let message = document.createElement('div');
message.classList.add('btn');
message.classList.add('message');
let messageImg = document.createElement('div');
messageImg.classList.add('message-img');
textWrap.appendChild(text);
if (clientId == currentClientId) {
// 이름 옆에 본인 표시 추가
let meBadge = document.createElement('div');
meBadge.classList.add('me-badge');
let h6 = document.createElement('h6');
h6.innerText = '나';
meBadge.appendChild(h6);
textWrap.appendChild(meBadge);
// 본인한테는 메시지 보내지 못하도록 처리
message.classList.add('disabled');
} else {
message.addEventListener('click', function(e) {
let targetClientId = e.target.closest('.user').dataset.clientId;
let userInfo = JSON.parse(vars.userInfoString);
let sender = `${userInfo.user_nm} ${userInfo.position}`;
sender = sender.trim();
let toggleParams = {
title: '메시지 전송',
text: `메시지 내용을 입력한 후 확인을 눌러주세요.`,
type: 'sendMessage',
targetClientId: targetClientId,
sender: sender.trim()
};
toggleModal(true, toggleParams);
})
}
message.appendChild(messageImg);
btnWrap.appendChild(message);
userDom.appendChild(textWrap);
userDom.appendChild(btnWrap);
}
// 정렬된 순서대로 append (재배치)
projectUserWrap.appendChild(userDom);
});
});
// 접속중인 모든 클라이언트 아이디 배열에 포함되어 있지 않은 유저 dom 삭제
let userDoms = document.querySelectorAll('.dev-menu-modal .total-user-list .user');
for (let user of userDoms) {
let clientId = user.dataset.clientId;
if (!allClientID.includes(clientId)) user.remove();
}
// 프로젝트에 접속자가 없는 경우 해당 프로젝트 dom 삭제
let projectDoms = document.querySelectorAll('.dev-menu-modal .total-user-list .project');
for (let project of projectDoms) {
let projectName = project.dataset.projectName;
if (!groupedUsersList[projectName]) project.remove();
}
}
});
//// 프로젝트 상태 설정
socket.on('updateProject_isActive_success', async (data) => {
let { allProject, projectIdList, type, state, text } = data;
projectIdList = JSON.parse(projectIdList);
// 전체 프로젝트 정보 갱신
for (let project of allProject) {
vars.allProject[project.project_id] = project;
}
// 현재 프로젝트 정보 갱신
vars.project = vars.allProject[vars.project_id];
// 아카이브 모달 > 프로젝트 리스트 > sign 스타일 변경
for (let projectId of projectIdList) {
let projectItem = document.querySelector(`.archive-modal .project-list-wrap .${type} .project-item[data-project-id="${projectId}"]`);
if (projectItem) projectItem.querySelector('.sign').classList.toggle('inactive', !state);
}
if (projectIdList.includes(vars.project.project_id)) {
alert(text);
if (vars.permission.checkPermission('dev-menu')) {
//// 개발자 계정인 경우
// projectIdList에 현재 프로젝트 id가 포함되어 있으면 토글 상태 변경
let projectStateToggle = document.querySelector('.dev-menu-modal .modal-body .toggle-wrap .project-state-toggle');
// project-inactive-sign on/off
let projectInactiveSign = document.querySelector('.project-inactive-sign');
if (state) {
// 비활성화 -> 활성화
if (projectStateToggle) projectStateToggle.classList.remove('inactive');
if (projectInactiveSign) projectInactiveSign.style.display = 'none';
} else {
// 활성화 -> 비활성화
if (projectStateToggle) projectStateToggle.classList.add('inactive');
if (projectInactiveSign) projectInactiveSign.style.display = 'flex';
}
} else {
//// 개발자 계정 아닌 경우
// window.location.href = '/auth/logout';
window.location.href = `${window.location.origin}/user/login?path=/${vars.project.category}`;
}
}
})
//// 배너 공지 설정
socket.on('updateProject_bannerNotice_success', async (data) => {
let { allProject, projectIdList, type, state } = data;
projectIdList = JSON.parse(projectIdList);
// 전체 프로젝트 정보 갱신
for (let project of allProject) {
vars.allProject[project.project_id] = project;
}
// 현재 프로젝트 정보 갱신
vars.project = vars.allProject[vars.project_id];
// 아카이브 모달 > 프로젝트 리스트 > sign 스타일 변경
for (let projectId of projectIdList) {
let projectItem = document.querySelector(`.archive-modal .project-list-wrap .${type} .project-item[data-project-id="${projectId}"]`);
if (projectItem) projectItem.querySelector('.sign').classList.toggle('inactive', !state);
}
if (projectIdList.includes(vars.project.project_id)) {
if (vars.permission.checkPermission('dev-menu')) {
//// 개발자 계정인 경우
// projectIdList에 현재 프로젝트 id가 포함되어 있으면 토글 상태 변경
let bannerNoticeToggle = document.querySelector('.dev-menu-modal .modal-body .toggle-wrap .banner-notice-toggle');
if (state) {
// 비활성화 -> 활성화
if (bannerNoticeToggle) bannerNoticeToggle.classList.remove('inactive');
} else {
// 활성화 -> 비활성화
if (bannerNoticeToggle) bannerNoticeToggle.classList.add('inactive');
}
}
toggleBannerNoticeArea();
}
})
//// 팝업 공지 발송
socket.on('popupNotice', (data)=>{
let { text } = data;
alert(text);
})
//// 강제 로그아웃
socket.on('forcedLogout', () => {
alert('프로젝트 재시작으로 인해 자동으로 로그아웃됩니다.\n다시 로그인 후 사용해주세요.');
if (vars.permission.checkPermission('dev-menu')) return;
window.location.href = `${window.location.origin}/user/login?path=/${vars.project_id}/archive`;
})
//// 메시지 전송
socket.on('sendMessage', (data)=>{
let { sender, text } = data;
alert(`${sender} 님으로부터 메시지가 도착했습니다. \n\n ${text}`);
})
// 변환시작, 변환완료 등 상태에 따른 실시간 UI 변경 처리는 socket.on에서 처리
// 서버에 현재 변환중인 파일 경로를 보내는 등 로직 처리는 working // 변환 파일 포함 폴더 강조 기능
//// 변환 시작
socket.on('convert_start', (resultData) => {
let currProjectId = JSON.parse(vars.userInfoString).project_id;
if (currProjectId != resultData.projectId) return;
let resourcePath = resultData.resourcePath;
vars.convertingDataArr = resultData.convertingDataArr;
let state = document.querySelector(`.list-item[data-resource-path="${resourcePath}"] .state`);
if (!state) return;
state.classList.remove('convert');
state.classList.add('working');
let convertBtnText = state.querySelector('.convert-btn-text');
if (convertBtnText) convertBtnText.innerHTML = '변환중';
})
//// 변환 완료 후 변환 로그 기록 (queue.js에서 io.emit)
socket.on('convertPdf_success', async (resultData) => {
let { userInfoString, previewKey, projectId, userIp, resourcePath, dataId, storageType } = resultData;
let resultDataUserInfo = JSON.parse(resultData.userInfoString);
let varsUserInfo = JSON.parse(vars.userInfoString);
// 변환된 아이템 데이터에 previewKey 추가
let convertTarget = getDataFromTreeObject(resourcePath, 'file', vars.allTreeObject).data;
if (convertTarget && previewKey) convertTarget.previewKey = previewKey;
// 변환을 실행한 유저의 clientId와 접속중인 유저의 clientId 비교해서 같을 때 변환 로그 기록 실행
// -> clientId가 다른데 변환 로그 기록을 실행하면 소켓 이벤트를 전송받은 모든 유저가 변환 로그 기록을 실행하게 돼서 중복 기록됨
if (resultDataUserInfo.clientId != varsUserInfo.clientId) return;
let activity = 'convertPdf';
let addConvetPdfLogParams = {
projectId: projectId,
activity: activity,
userInfoString: userInfoString,
userIp: userIp,
resourcePath: resourcePath,
resourcePathArr: [resourcePath],
dataId: dataId,
dataIdArr: [dataId],
storageType: storageType,
}
await axios.post(`${vars.path_name}/addConvetPdfLog`, { params: addConvetPdfLogParams });
})
//// 변환 로그 기록 완료
socket.on('addConvetPdfLog_success', async (resultData) => {
let { projectId, userInfoString, resourcePath, dataId } = resultData;
let currProjectId = JSON.parse(vars.userInfoString).project_id;
if (currProjectId != projectId) return;
renderLog();
vars.convertingDataArr = resultData.convertingDataArr;
let state = document.querySelector(`.list-item[data-resource-path="${resourcePath}"] .state`);
if (!state) return;
state.classList.remove('working');
state.classList.add('viewable');
let stateText = state.querySelector('.state-text');
if (stateText) stateText.innerHTML = '열람가능';
let convertBtn = state.querySelector('.convert-btn');
if (convertBtn) convertBtn.remove();
// 클릭 로그 추가 (addConvetPdfLog_success)
// 변환 버튼 클릭한 유저만 실행
if (JSON.parse(userInfoString).clientId == JSON.parse(vars.userInfoString).clientId) {
// console.log('클릭 로그 추가 (addConvetPdfLog_success)');
let params = {
userInfoString: vars.userInfoString,
dataIdArr: [String(dataId)],
resourcePathArr: [resourcePath],
activity: 'click_convertBtn'
}
mgmtFunc_addClickLog(params);
}
if (vars.lastListItem) {
let lastListItemPath = vars.lastListItem.dataset.resourcePath;
if (resourcePath == lastListItemPath) {
// 변환 버튼 클릭할 때 vars.viewerConnectingTime이 0으로 설정되기 때문에
// 변환 완료 후 뷰어 실행하기 전에 vars.viewerConnectingTime을 1000으로 설정
// vars.viewerConnectingTime = vars.viewerConnectingTimeValue;
let shouldAddClickLog = false;
renderViewer(resourcePath, dataId, shouldAddClickLog);
}
}
})
//// 변환 실패 (queue.js에서 io.emit)
socket.on('convertPdf_failed', async (resultData) => {
console.log('-------- convertPdf_failed');
console.log(resultData);
let resourcePath = (resultData.jobData.resourcePath) ? resultData.jobData.resourcePath : resultData.jobProgress.resourcePath;
let dataId = (resultData.jobData.dataId) ? resultData.jobData.dataId : resultData.jobProgress.dataId;
let userInfoString = (resultData.jobData.userInfoString) ? resultData.jobData.userInfoString : resultData.jobProgress.userInfoString;
// 서버의 convertingDataArr에서 변환 실패한 파일 정보 삭제
let removeConvertingDataParams = {
resourcePath: resourcePath,
dataId: dataId,
userInfoString: userInfoString
}
let removeConvertingDataResult = await axios.post(`${vars.path_name}/removeConvertingData`, { params: removeConvertingDataParams });
console.log(removeConvertingDataResult);
// 클릭 로그 추가 (convertPdf_failed)
// 변환 버튼 클릭한 유저만 실행
if (JSON.parse(userInfoString).clientId == JSON.parse(vars.userInfoString).clientId) {
// console.log('클릭 로그 추가 (convertPdf_failed)');
let params = {
userInfoString: vars.userInfoString,
dataIdArr: [String(dataId)],
resourcePathArr: [resourcePath],
activity: 'click_convertBtn'
}
mgmtFunc_addClickLog(params);
}
})
socket.on('removeConvertingData_success', async (resultData) => {
let currProjectId = JSON.parse(vars.userInfoString).project_id;
if (currProjectId != resultData.projectId) return;
// 변환중인 파일 정보 갱신
vars.convertingDataArr = resultData.convertingDataArr;
// 변환 실패한 파일의 변환버튼 초기화
let resourcePath = resultData.resourcePath;
let state = document.querySelector(`.list-item[data-resource-path="${resourcePath}"] .state`);
if (!state) return; // 변환버튼을 클릭했던 리스트가 아닌 다른 리스트를 보고 있으면 아래 오류 모달 실행 안됨
state.classList.remove('working');
state.classList.add('convert');
let convertBtnText = state.querySelector('.convert-btn-text');
if (convertBtnText) convertBtnText.innerHTML = '변환필요';
let resultUserInfo = JSON.parse(resultData.userInfoString);
let resultUserId = resultUserInfo.user_id;
// let resultClientId = resultUserInfo.clientId;
let resultProjectId = resultUserInfo.project_id;
let currentUserInfo = JSON.parse(vars.userInfoString);
let currentUserId = currentUserInfo.user_id;
// let currentClientId = currentUserInfo.clientId;
let currentProjectId = currentUserInfo.project_id;
// console.log('@@@@@');
// console.log(resultUserId);
// console.log(resultClientId);
// console.log(resultProjectId);
// console.log('#####');
// console.log(currentUserId);
// console.log(currentClientId);
// console.log(currentProjectId);
if (resultProjectId == currentProjectId && resultUserId == currentUserId) {
let toggleParams = {
// text: `
// <오류> ${resultData.stdout}
// 오류로 인해 PDF 변환이 실패했습니다.
// GSIM 개발팀에 문의해주시기 바랍니다.
// `,
text: `
<오류> ${resultData.stdout}
오류로 인해 PDF 변환이 실패했습니다.
GSIM 개발팀에 문의해주시기 바랍니다.
`,
type: 'alertModal'
};
toggleModal(true, toggleParams);
}
})
socket.on('mgmtFunc_resetConvert_success', async (resultData) => {
let currProjectId = JSON.parse(vars.userInfoString).project_id;
if (currProjectId != resultData.projectId) return;
// console.log(resultData);
vars.convertingDataArr = resultData.convertingDataArr;
let state = document.querySelector(`.list-item[data-resource-path="${resultData.resourcePath}"] .state`);
if (!state) return; // 변환버튼을 클릭했던 리스트가 아닌 다른 리스트를 보고 있으면 아래 오류 모달 실행 안됨
state.classList.remove('working');
state.classList.add('convert');
let convertBtnText = state.querySelector('.convert-btn-text');
if (convertBtnText) convertBtnText.innerHTML = '변환필요';
})
//// 폴더 생성 완료
// 로그 작성
socket.on('createFolder_success', async (resultData) => {
// console.log('//////// 폴더 생성');
// console.log(resultData);
let currProjectId = JSON.parse(vars.userInfoString).project_id;
if (currProjectId != resultData.projectId) return;
renderLog();
let userCurPath = getMyCurPath();
let extractedPath = extractPathByLength(userCurPath, 1);
// let resourcePath = resultData.resourcePath;
// let resourcePathSplit = resourcePath.split('/');
// let extractedPath = extractPathByLength(resourcePathSplit, 1);
//// depth1 폴더 영역 렌더링
let pageRanderingOption = {
scope: 'headerBtn',
from: 'createFolder - depth1 - headerBtn',
resourcePath: userCurPath,
pushState: false,
// userCurPath: userCurPath,
}
await preparePageRendering(pageRanderingOption);
//// 마지막으로 선택된 depth1 폴더의 경로
let lastHeaderBtnPath = vars.lastHeaderBtn?vars.lastHeaderBtn.dataset.resourcePath:undefined;
let lastHeaderBtn = document.querySelector(`body > .header .center .menu-tab .btn[data-resource-path="${lastHeaderBtnPath}"]`);
//// 마지막으로 선택된 depth1 폴더의 스타일 강조
if (lastHeaderBtn) changeHeaderBtnStyle(lastHeaderBtn);
lastHeaderBtnPath = vars.lastHeaderBtn?vars.lastHeaderBtn.dataset.resourcePath:undefined;
//// depth2, depth3 폴더 생성
//// 마지막으로 선택된 depth1 폴더 안에 depth2, depth3 폴더를 생성할 때 아래 코드 실행
//// -> 다른 depth1 폴더를 보고 있는 사용자는 해당 안됨
if (extractedPath == lastHeaderBtnPath) {
//// 마지막으로 선택된 depth1 폴더의 하위 트리 폴더 렌더링
let pageRanderingOption = {
scope: 'tree',
resourcePath: extractedPath,
userCurPath: userCurPath,
pushState: false
}
await preparePageRendering(pageRanderingOption);
if (vars.lastMainTreeItem) {
let mainTreeItem = document.querySelector(`.archive-main-left .tree-container .tree-wrap .tree-item-wrap[data-resource-path="${vars.lastMainTreeItem.dataset.resourcePath}"]`)
if (mainTreeItem) changeTreeItemStyle(mainTreeItem);
}
// 폴더 생성 시 중앙 리스트 영역(list) 즉시 갱신 추가
let pageRanderingOptionList = {
scope: 'list',
resourcePath: userCurPath,
pushState: false,
debug: '폴더생성완료 - list'
}
await preparePageRendering(pageRanderingOptionList);
if (vars.lastListItem) {
let lastListItemPath = vars.lastListItem.dataset.resourcePath;
let listItem = document.querySelector(`.archive-main-center .list-container .list-body .list-item[data-resource-path="${lastListItemPath}"]`);
if (listItem) changeListItemStyle(listItem);
}
}
})
//// 업로드 완료
socket.on('uploadData_success', async (resultData) => {
// console.log('//////// 업로드');
// console.log(resultData);
let currProjectId = JSON.parse(vars.userInfoString).project_id;
if (currProjectId != resultData.projectId) return;
renderLog();
renderSizeBar();
//// 업로드 된 첫 번째 파일 경로
let firstResourcePath = resultData.resourcePathArr[0];
let firstResourcePathSplit = firstResourcePath.split('/');
//// 업로드 된 타겟의 상위 폴더(depth3) 경로
let uploadTargetTopPath = splitTopPathAndTargetName(firstResourcePath).topPath;
// 추가 파일(버전/첨부) 업로드인 경우 uploadTargetTopPath가 상위파일경로_(version/attachment)이므로
// splitTopPathAndTargetName 함수 한번 더 실행해서 depth3 폴더 경로로 설정
if (resultData.activity?.includes('addOn_')) uploadTargetTopPath = splitTopPathAndTargetName(uploadTargetTopPath).topPath;
let userCurPath;
if (vars.users[socket.id] && vars.users[socket.id].curPath) userCurPath = vars.users[socket.id].curPath;
//// vars.allTreeObject에서 depth1, depth2 폴더 데이터에 filesCount 갱신을 위해 헤더 버튼 렌더링 필요 (getTreeObject: false)
let pageRanderingOption = {
scope: 'headerBtn',
resourcePath: userCurPath,
pushState: false,
getTreeObject: false
}
await preparePageRendering(pageRanderingOption);
//// 마지막으로 선택된 depth1 폴더의 경로
let lastHeaderBtnPath = vars.lastHeaderBtn?vars.lastHeaderBtn.dataset.resourcePath:undefined;
let lastHeaderBtn = document.querySelector(`body > .header .center .menu-tab .btn[data-resource-path="${lastHeaderBtnPath}"]`);
//// 마지막으로 선택된 depth1 폴더의 스타일 강조
if (lastHeaderBtn) changeHeaderBtnStyle(lastHeaderBtn);
lastHeaderBtnPath = vars.lastHeaderBtn?vars.lastHeaderBtn.dataset.resourcePath:undefined;
// 251114 김아름
if (lastHeaderBtnPath == undefined) return;
//// depth3 폴더명 몇 파일 개수 표시 업데이트를 위해 트리 렌더링 필요
//// 선택된 헤더 버튼 경로와 treeContainer의 dataset.resourcePath가 같을 때 트리 렌더링
let extractedPath = extractPathByLength(firstResourcePathSplit, 1);
if (treeContainer.dataset.resourcePath == extractedPath) {
let pageRanderingOption = {
scope: 'tree',
resourcePath: extractedPath,
userCurPath: uploadTargetTopPath,
pushState: false,
debug: '업로드완료 - tree'
}
await preparePageRendering(pageRanderingOption);
if (vars.lastMainTreeItem) {
let lastMainTreeItemPath = vars.lastMainTreeItem.dataset.resourcePath;
let mainTreeItem = document.querySelector(`.archive-main-left .tree-container .tree-wrap .tree-item-wrap[data-resource-path="${lastMainTreeItemPath}"]`)
if (mainTreeItem) changeTreeItemStyle(mainTreeItem);
}
}
//// depth3 폴더가 선택된 상태인 경우 depth3 폴더 경로로 리스트 렌더링
/// 251104 박지은 ol 소켓처리
// fileAreaMode 체크
// let isMapMode = document.querySelector('.archive-main .archive-main-left .control-box .contents-wrap .file-area-mode-btn-wrap .file-area-mode-btn.btn.map')?.classList.contains('selected');
if (treeContainer.dataset.resourcePath == extractedPath && vars.lastMainTreeItem) {
let pageRanderingOption = {
scope: 'list',
resourcePath: vars.lastMainTreeItem.dataset.resourcePath,
pushState: false,
debug: '업로드완료 - list'
}
await preparePageRendering(pageRanderingOption);
//// depth4 파일이 선택된 상태인 경우 depth4 파일 경로로 스타일 강조
if (vars.lastListItem) {
let lastListItemPath = vars.lastListItem.dataset.resourcePath;
let listItem = document.querySelector(`.archive-main-center .list-container .list-body .list-item[data-resource-path="${lastListItemPath}"]`);
if (listItem) changeListItemStyle(listItem);
}
// 251104 박지은 ol 소켓처리
// // 위치보기(map) 모드인 경우 - 새 파일만 추가
// if (isMapMode) {
// // getTreeObject만 갱신하여 새 파일 데이터 가져오기
// let pageRanderingOption = {
// scope: 'updateTreeObject', // 새로운 scope 추가 필요
// resourcePath: vars.lastMainTreeItem.dataset.resourcePath,
// pushState: false,
// getTreeObject: true,
// debug: '업로드완료 - 위치보기 모드 데이터 갱신'
// }
// await preparePageRendering(pageRanderingOption);
// // 새로 업로드된 파일만 지도에 추가
// await createNewMapItems(resultData.resourcePathArr);
// } else {
// // 일반/그리드 모드인 경우 - 전체 리스트 렌더링
// let pageRanderingOption = {
// scope: 'list',
// resourcePath: vars.lastMainTreeItem.dataset.resourcePath,
// pushState: false,
// debug: '업로드완료 - list'
// }
// await preparePageRendering(pageRanderingOption);
// //// depth4 파일이 선택된 상태인 경우 depth4 파일 경로로 스타일 강조
// if (vars.lastListItem) {
// let lastListItemPath = vars.lastListItem.dataset.resourcePath;
// let listItem = document.querySelector(`.archive-main-center .list-container .list-body .list-item[data-resource-path="${lastListItemPath}"]`)
// if (listItem) changeListItemStyle(listItem);
// }
// }
}
})
//// gif생성 + 위치 추출
// socket.on('postProcessVideo_success', async (resultData) => {
// let dataId = resultData.dataId;
// let thumbnailKey = resultData.thumbnailKey;
// let resourcePath = resultData.resourcePath;
// let lon = resultData.lon;
// let lat = resultData.lat;
// // 동영상 후처리 된 dataId에 매칭되는 gridItem이 있는 경우 썸네일 교체
// let gridItem = document.querySelector(`.list-container.grid .grid-item[data-id="${dataId}"]`);
// if (gridItem) {
// if (lon && lat) {
// console.log(gridItem.querySelector('.gps-data'));
// gridItem.querySelector('.gps-data').classList.add('gps-data-yes');
// gridItem.querySelector('.gps-data').classList.remove('gps-data-no');
// }
// let generateDownloadUrlParams = {
// objectKey: thumbnailKey,
// resourcePath: resourcePath
// }
// let generateDownloadUrlRes = await axios.post(`${vars.path_name}/generateDownloadUrl`, generateDownloadUrlParams);
// if (generateDownloadUrlRes.data.message == 'generateDownloadUrl_success') {
// let presignedUrl = generateDownloadUrlRes.data.url;
// gridItem.querySelector('.wrap .thumbnail').src = presignedUrl;
// gridItem.querySelector('.loading-progress-wrap').remove();
// }
// }
// })
//// 위치 추출
socket.on('postProcessVideo_success', async (resultData) => {
let dataId = resultData.dataId;
let lon = resultData.lon;
let lat = resultData.lat;
// 동영상 후처리 된 dataId에 매칭되는 gridItem이 있는 경우 gpsData 아이콘 교체
let gridItem = document.querySelector(`.list-container.grid .grid-item[data-id="${dataId}"]`);
if (gridItem && lon && lat) {
gridItem.querySelector('.gps-data').classList.add('gps-data-yes');
gridItem.querySelector('.gps-data').classList.remove('gps-data-no');
}
})
//// 이름 변경
// 로그 작성
socket.on('renameTarget_success', async (resultData) => {
// console.log('//////// 이름 변경');
// console.log(resultData);
let currProjectId = JSON.parse(vars.userInfoString).project_id;
if (currProjectId != resultData.projectId) return;
renderLog();
let userCurPath;
if (vars.users[socket.id] && vars.users[socket.id].curPath) userCurPath = vars.users[socket.id].curPath;
let oldPath = resultData.oldPath;
let newPath = resultData.newPath;
let depth = getDepth(newPath);
// oldPath와 newPath의 depth는 동일
// 이 depth만큼 userCurPath를 추출
let extractedUserCurPath = extractPathByLength(userCurPath, depth);
// extractedUserCurPath와 oldPath가 같으면 userCurPath에서 oldPath 부분을 newPath로 업데이트
if (extractedUserCurPath == oldPath) userCurPath = updatePartialPath(newPath, userCurPath);
let pathSplit = userCurPath.split('/');
let depth1Path, depth2Path, depth3Path;
if (pathSplit[1]) depth1Path = `${pathSplit[0]}/${pathSplit[1]}`;
if (pathSplit[2]) depth2Path = `${depth1Path}/${pathSplit[2]}`;
if (pathSplit[3]) depth3Path = `${depth2Path}/${pathSplit[3]}`;
//// depth1 폴더 영역 렌더링
let pageRanderingOption = {
scope: 'headerBtn',
resourcePath: userCurPath,
pushState: false
}
await preparePageRendering(pageRanderingOption);
//// 마지막으로 선택된 depth1 폴더의 경로
let lastHeaderBtnPath = vars.lastHeaderBtn?vars.lastHeaderBtn.dataset.resourcePath:undefined;
let lastHeaderBtn = document.querySelector(`body > .header .center .menu-tab .btn[data-resource-path="${lastHeaderBtnPath}"]`);
//// 마지막으로 선택된 depth1 폴더의 스타일 강조
if (lastHeaderBtn) {
//// lastHeaderBtn이 있는 경우 -> 마지막으로 선택된 depth1 폴더와 다른 폴더 이름을 변경한 경우
changeHeaderBtnStyle(lastHeaderBtn);
} else {
//// lastHeaderBtn이 없는 경우 -> 마지막으로 선택된 depth1 폴더 이름을 변경한 경우
//// data-resource-path가 newPath인 delth1 폴더를 lastHeaderBtn으로 지정
lastHeaderBtn = document.querySelector(`body > .header .center .menu-tab .btn[data-resource-path="${newPath}"]`);
changeHeaderBtnStyle(lastHeaderBtn);
}
lastHeaderBtnPath = vars.lastHeaderBtn?vars.lastHeaderBtn.dataset.resourcePath:undefined;
// 251114 김아름
if (lastHeaderBtnPath == undefined) return;
//// depth1 폴더 이름을 변경할 때 아래 코드 실행
if (depth == 1) {
//// 마지막으로 선택된 depth1 폴더 경로와 변경하려는 depth1 폴더 경로가 동일할 때 아래 코드 실행
//// -> 다른 depth1 폴더를 보고 있는 사용자는 코드 실행 안됨
if (lastHeaderBtnPath == depth1Path) {
//// 마지막으로 선택된 depth1 폴더의 하위 트리 폴더 렌더링
let pageRanderingOption = {
scope: 'tree',
resourcePath: depth1Path,
userCurPath: userCurPath
}
await preparePageRendering(pageRanderingOption);
//// 마지막으로 선택된 depth3 폴더가 있을 때 아래 코드 실행
if (vars.lastMainTreeItem) {
//// 마지막으로 선택된 depth3 폴더의 경로 수정 후 스타일 강조
let lastMainTreeItemPath = vars.lastMainTreeItem.dataset.resourcePath;
lastMainTreeItemPath = updatePartialPath(depth1Path, lastMainTreeItemPath);
let mainTreeItem = document.querySelector(`.archive-main-left .tree-container .tree-wrap .tree-item-wrap[data-resource-path="${lastMainTreeItemPath}"]`)
if (mainTreeItem) changeTreeItemStyle(mainTreeItem);
//// 파일 리스트 헤더, 바디의 resourcePath 변경
document.querySelector('.archive-main-center .list-container .list-header').dataset.resourcePath = lastMainTreeItemPath;
document.querySelector('.archive-main-center .list-container .list-body').dataset.resourcePath = lastMainTreeItemPath;
// 리스트 렌더링
pageRanderingOption = {
scope: 'list',
resourcePath: lastMainTreeItemPath,
userCurPath: userCurPath
}
await preparePageRendering(pageRanderingOption);
/// 251104 박지은 ol 소켓처리
// fileAreaMode 체크
// let isMapMode = document.querySelector('.archive-main .archive-main-left .control-box .contents-wrap .file-area-mode-btn-wrap .file-area-mode-btn.btn.map')?.classList.contains('selected');
// if (!isMapMode) {
// // 일반/그리드 모드인 경우만 - 전체 리스트 렌더링
// //// 리스트 렌더링
// pageRanderingOption = {
// scope: 'list',
// resourcePath: lastMainTreeItemPath,
// userCurPath: userCurPath
// }
// await preparePageRendering(pageRanderingOption);
// }
//// 마지막으로 선택된 depth4 파일이 있을 때 아래 코드 실행
if (vars.lastListItem) {
//// 마지막으로 선택된 depth4 파일의 경로 수정 후 스타일 강조
let lastListItemPath = vars.lastListItem.dataset.resourcePath;
lastListItemPath = updatePartialPath(depth1Path, lastListItemPath);
let listItem = document.querySelector(`.archive-main-center .list-container .list-body .list-item[data-resource-path="${lastListItemPath}"]`)
if (listItem) changeListItemStyle(listItem);
}
}
}
}
//// depth2 폴더 이름을 변경할 때 아래 코드 실행
if (depth == 2) {
//// 마지막으로 선택된 depth1 폴더 경로와 변경하려는 depth2 폴더를 포함하고 있는 depth1 폴더 경로가 동일할 때 아래 코드 실행
//// -> 다른 depth1 폴더를 보고 있는 사용자는 코드 실행 안됨
if (lastHeaderBtnPath == depth1Path) {
//// 마지막으로 선택된 depth1 폴더의 하위 트리 폴더 렌더링
let pageRanderingOption = {
scope: 'tree',
resourcePath: depth1Path,
userCurPath: userCurPath
}
await preparePageRendering(pageRanderingOption);
//// 마지막으로 선택된 depth3 폴더가 있을 때 아래 코드 실행
if (vars.lastMainTreeItem) {
//// 마지막으로 선택된 depth3 폴더의 경로
let lastMainTreeItemPath = vars.lastMainTreeItem.dataset.resourcePath;
//// 마지막으로 선택된 depth3 폴더의 상위 폴더 경로
let lastMainTreeItemTopPath = splitTopPathAndTargetName(lastMainTreeItemPath).topPath;
//// 리스트 렌더링 여부 판단에 사용할 변수
let listRendering = false;
//// lastMainTreeItemTopPath와 oldPath(이름 변경 전의 depth2 폴더 경로)가 같을 때 아래 코드 실행
if (lastMainTreeItemTopPath == oldPath) {
//// 마지막으로 선택된 depth3 폴더의 경로 수정 및 리스트 렌더링 여부 변수 true로 변경
lastMainTreeItemPath = updatePartialPath(depth2Path, lastMainTreeItemPath);
listRendering = true;
}
//// 마지막으로 선택된 depth3 폴더의 스타일 강조
let mainTreeItem = document.querySelector(`.archive-main-left .tree-container .tree-wrap .tree-item-wrap[data-resource-path="${lastMainTreeItemPath}"]`)
if (mainTreeItem) changeTreeItemStyle(mainTreeItem);
//// 파일리스트 헤더, 바디의 resourcePath 변경
document.querySelector('.archive-main-center .list-container .list-header').dataset.resourcePath = lastMainTreeItemPath;
document.querySelector('.archive-main-center .list-container .list-body').dataset.resourcePath = lastMainTreeItemPath;
//// listRendering이 true일 때 아래 코드 실행
if (listRendering) {
//// 리스트 렌더링
pageRanderingOption = {
scope: 'list',
resourcePath: lastMainTreeItemPath,
userCurPath: userCurPath
}
await preparePageRendering(pageRanderingOption);
/// 251104 박지은 ol 소켓처리
// fileAreaMode 체크
// let isMapMode = document.querySelector('.archive-main .archive-main-left .control-box .contents-wrap .file-area-mode-btn-wrap .file-area-mode-btn.btn.map')?.classList.contains('selected');
// if(!isMapMode) {
// // 일반/그리드 모드인 경우만 - 전체 리스트 렌더링
// //// 리스트 렌더링
// pageRanderingOption = {
// scope: 'list',
// resourcePath: lastMainTreeItemPath,
// userCurPath: userCurPath
// }
// await preparePageRendering(pageRanderingOption);
// }
//// 마지막으로 선택된 depth4 파일이 있을 때 아래 코드 실행
if (vars.lastListItem) {
//// 마지막으로 선택된 depth4 파일의 경로 수정 후 스타일 강조
let lastListItemPath = vars.lastListItem.dataset.resourcePath;
lastListItemPath = updatePartialPath(lastMainTreeItemPath, lastListItemPath);
let listItem = document.querySelector(`.archive-main-center .list-container .list-body .list-item[data-resource-path="${lastListItemPath}"]`)
if (listItem) changeListItemStyle(listItem);
}
}
}
}
}
//// depth3 폴더 이름을 변경할 때 아래 코드 실행
if (depth == 3) {
//// 마지막으로 선택된 depth1 폴더 경로와 변경하려는 depth3 폴더를 포함하고 있는 depth1 폴더 경로가 동일할 때 아래 코드 실행
//// -> 다른 depth1 폴더를 보고 있는 사용자는 코드 실행 안됨
if (lastHeaderBtnPath == depth1Path) {
//// 마지막으로 선택된 depth1 폴더의 하위 트리 폴더 렌더링
let pageRanderingOption = {
scope: 'tree',
resourcePath: depth1Path,
userCurPath: userCurPath
}
await preparePageRendering(pageRanderingOption);
//// 마지막으로 선택된 depth3 폴더가 있을 때 아래 코드 실행
if (vars.lastMainTreeItem) {
//// 마지막으로 선택된 depth3 폴더의 경로
let lastMainTreeItemPath = vars.lastMainTreeItem.dataset.resourcePath;
//// 리스트 렌더링 여부 판단에 사용할 변수
let listRendering = false;
//// lastMainTreeItemPath와 oldPath(이름 변경 전의 depth3 폴더 경로)가 같을 때 아래 코드 실행
// console.log(lastMainTreeItemPath);
// console.log(oldPath);
if (lastMainTreeItemPath == oldPath) {
//// 마지막으로 선택된 depth3 폴더의 경로 수정 및 리스트 렌더링 여부 변수 true로 변경
lastMainTreeItemPath = updatePartialPath(depth3Path, lastMainTreeItemPath);
listRendering = true;
}
//// 마지막으로 선택된 depth3 폴더의 스타일 강조
let mainTreeItem = document.querySelector(`.archive-main-left .tree-container .tree-wrap .tree-item-wrap[data-resource-path="${lastMainTreeItemPath}"]`)
if (mainTreeItem) changeTreeItemStyle(mainTreeItem);
//// 파일리스트 헤더, 바디의 resourcePath 변경
document.querySelector('.archive-main-center .list-container .list-header').dataset.resourcePath = lastMainTreeItemPath;
document.querySelector('.archive-main-center .list-container .list-body').dataset.resourcePath = lastMainTreeItemPath;
//// listRendering이 true일 때 아래 코드 실행
if (listRendering) {
//// 리스트 렌더링
pageRanderingOption = {
scope: 'list',
resourcePath: lastMainTreeItemPath,
userCurPath: userCurPath
}
await preparePageRendering(pageRanderingOption);
/// 251104 박지은 ol 소켓처리
// fileAreaMode 체크
// let isMapMode = document.querySelector('.archive-main .archive-main-left .control-box .contents-wrap .file-area-mode-btn-wrap .file-area-mode-btn.btn.map')?.classList.contains('selected');
// if(!isMapMode) {
// //// 리스트 렌더링
// pageRanderingOption = {
// scope: 'list',
// resourcePath: lastMainTreeItemPath,
// userCurPath: userCurPath
// }
// await preparePageRendering(pageRanderingOption);
// }
//// 마지막으로 선택된 depth4 파일이 있을 때 아래 코드 실행
if (vars.lastListItem) {
//// 마지막으로 선택된 depth4 파일의 경로 수정 후 스타일 강조
let lastListItemPath = vars.lastListItem.dataset.resourcePath;
lastListItemPath = updatePartialPath(lastMainTreeItemPath, lastListItemPath);
let listItem = document.querySelector(`.archive-main-center .list-container .list-body .list-item[data-resource-path="${lastListItemPath}"]`)
if (listItem) changeListItemStyle(listItem);
}
}
}
}
}
//// depth4 파일 및 추가 파일 이름을 변경할 때 아래 코드 실행
if (depth >= 4) {
if(vars.tempMemo[oldPath]) {
vars.tempMemo[newPath] = vars.tempMemo[oldPath];
// delete vars.tempMemo[oldPath]
}
//// 마지막으로 선택된 depth1 폴더 경로와 변경하려는 depth4 파일을 포함하고 있는 depth1 폴더 경로가 동일할 때 아래 코드 실행
//// -> 다른 depth1 폴더를 보고 있는 사용자는 코드 실행 안됨
if (lastHeaderBtnPath == depth1Path) {
//// 마지막으로 선택된 depth1 폴더의 하위 트리 폴더 렌더링
let pageRanderingOption = {
scope: 'tree',
resourcePath: depth1Path,
userCurPath: userCurPath
}
await preparePageRendering(pageRanderingOption);
//// 마지막으로 선택된 depth3 폴더의 경로
let lastMainTreeItemPath = vars.lastMainTreeItem.dataset.resourcePath;
//// lastMainTreeItemPath와 oldPath(이름 변경 전의 depth4 파일 경로)의 상위 폴더 경로가 같을 때 아래 코드 실행
if (lastMainTreeItemPath == splitTopPathAndTargetName(oldPath).topPath) {
//// lastMainTreeItemPath 갱신
lastMainTreeItemPath = updatePartialPath(depth3Path, lastMainTreeItemPath);
}
//// 마지막으로 선택된 depth3 폴더의 스타일 강조
let mainTreeItem = document.querySelector(`.archive-main-left .tree-container .tree-wrap .tree-item-wrap[data-resource-path="${lastMainTreeItemPath}"]`)
if (mainTreeItem) changeTreeItemStyle(mainTreeItem);
//// 마지막으로 선택된 depth3 폴더 경로와 변경하려는 depth4 파일을 포함하고 있는 depth3 폴더 경로가 동일할 때 아래 코드 실행
//// -> 다른 depth3 폴더를 보고 있는 사용자는 코드 실행 안됨
if (lastMainTreeItemPath == depth3Path) {
//// 파일리스트 헤더, 바디의 resourcePath 변경
document.querySelector('.archive-main-center .list-container .list-header').dataset.resourcePath = depth3Path;
document.querySelector('.archive-main-center .list-container .list-body').dataset.resourcePath = depth3Path;
//// 리스트 렌더링
pageRanderingOption = {
scope: 'list',
resourcePath: depth3Path,
userCurPath: userCurPath
}
await preparePageRendering(pageRanderingOption);
/// 251104 박지은 ol 소켓처리
// // fileAreaMode 체크
// let isMapMode = document.querySelector('.archive-main .archive-main-left .control-box .contents-wrap .file-area-mode-btn-wrap .file-area-mode-btn.btn.map')?.classList.contains('selected');
// if(!isMapMode) {
// //// 리스트 렌더링
// pageRanderingOption = {
// scope: 'list',
// resourcePath: depth3Path,
// userCurPath: userCurPath
// }
// await preparePageRendering(pageRanderingOption);
// }
//// 마지막으로 선택된 depth4 파일이 있을 때 아래 코드 실행
if (vars.lastListItem) {
//// 마지막으로 선택된 depth4 파일의 경로
let lastListItemPath = vars.lastListItem.dataset.resourcePath;
//// 마지막으로 선택된 depth4 파일 이름
let lastListItemFileName = splitTopPathAndTargetName(lastListItemPath).targetName;
//// 이름 변경 전 파일 이름
let oldPathFileName = splitTopPathAndTargetName(oldPath).targetName;
//// lastListItemFileName과 oldPathFileName이 같을 때 아래 코드 실행
if (lastListItemFileName == oldPathFileName) {
lastListItemPath = updatePartialPath(newPath, lastListItemPath);
}
//// 마지막으로 선택된 depth4 파일의 스타일 강조
let listItem = document.querySelector(`.archive-main-center .list-container .list-body .list-item[data-resource-path="${lastListItemPath}"]`)
if (listItem) changeListItemStyle(listItem);
}
}
}
}
})
//// 다운로드 완료
// 로그 작성
socket.on('downloadTarget_success', async (resultData) => {
let currProjectId = JSON.parse(vars.userInfoString).project_id;
if (currProjectId != resultData.projectId) return;
renderLog();
// console.log(resultData);
})
//// 이동
// 로그 작성
socket.on('relocateTarget_success', async (resultData) => {
let currProjectId = JSON.parse(vars.userInfoString).project_id;
if (currProjectId != resultData.projectId) return;
renderLog();
let userCurPath = vars.users[socket.id].curPath;
let fromDepth1Path = extractPathByLength(resultData.resourcePathArr[0].from, 1);
let toDepth1Path = extractPathByLength(resultData.resourcePathArr[0].to, 1);
let fromDepth3Path = extractPathByLength(resultData.resourcePathArr[0].from, 3);
let toDepth3Path = extractPathByLength(resultData.resourcePathArr[0].to, 3);
//// vars.allTreeObject에서 depth1, depth2 폴더 데이터에 filesCount 갱신을 위해 헤더 버튼 렌더링 필요 (getTreeObject: false)
let pageRanderingOption = {
scope: 'headerBtn',
pushState: false,
getTreeObject: false
}
await preparePageRendering(pageRanderingOption);
//// 마지막으로 선택된 depth1 폴더의 경로
let lastHeaderBtnPath = vars.lastHeaderBtn?vars.lastHeaderBtn.dataset.resourcePath:undefined;
let lastHeaderBtn = document.querySelector(`body > .header .center .menu-tab .btn[data-resource-path="${lastHeaderBtnPath}"]`);
//// 마지막으로 선택된 depth1 폴더의 스타일 강조
if (lastHeaderBtn) changeHeaderBtnStyle(lastHeaderBtn);
lastHeaderBtnPath = vars.lastHeaderBtn?vars.lastHeaderBtn.dataset.resourcePath:undefined;
let depth1Path;
if (fromDepth1Path == lastHeaderBtnPath) depth1Path = fromDepth1Path;
if (toDepth1Path == lastHeaderBtnPath) depth1Path = toDepth1Path;
// 251114 김아름
if (lastHeaderBtnPath == undefined) return;
//// depth3 폴더명 몇 파일 개수 표시 업데이트를 위해 트리 렌더링 필요
//// 이동 전 depth1 폴더 경로 또는 이동 후 depth1 폴더 경로와 treeContainer의 dataset.resourcePath가 같을 때 트리 렌더링
if (depth1Path == lastHeaderBtnPath) {
//// 마지막으로 선택된 depth3 폴더의 경로
let lastMainTreeItemPath = vars.lastMainTreeItem?vars.lastMainTreeItem.dataset.resourcePath:undefined;
let depth3Path;
if (fromDepth3Path == lastMainTreeItemPath) depth3Path = fromDepth3Path;
if (toDepth3Path == lastMainTreeItemPath) depth3Path = toDepth3Path;
//// 마지막으로 선택된 depth1 폴더의 하위 트리 폴더 렌더링
let pageRanderingOption = {
scope: 'tree',
resourcePath: depth1Path,
userCurPath: depth3Path?depth3Path:userCurPath,
pushState: false,
}
await preparePageRendering(pageRanderingOption);
if (lastMainTreeItemPath) {
let mainTreeItem = document.querySelector(`.archive-main-left .tree-container .tree-wrap .tree-item-wrap[data-resource-path="${lastMainTreeItemPath}"]`)
if (mainTreeItem) changeTreeItemStyle(mainTreeItem);
}
//// depth3 폴더가 선택된 상태인 경우 depth3 폴더 경로로 리스트 렌더링
if (treeContainer.dataset.resourcePath == depth1Path && vars.lastMainTreeItem) {
let pageRanderingOption = {
scope: 'list',
resourcePath: vars.lastMainTreeItem.dataset.resourcePath,
pushState: false,
}
await preparePageRendering(pageRanderingOption);
/// 251104 박지은 ol 소켓처리
// fileAreaMode 체크
// let isMapMode = document.querySelector('.archive-main .archive-main-left .control-box .contents-wrap .file-area-mode-btn-wrap .file-area-mode-btn.btn.map')?.classList.contains('selected');
// if(!isMapMode) {
// let pageRanderingOption = {
// scope: 'list',
// resourcePath: vars.lastMainTreeItem.dataset.resourcePath,
// pushState: false,
// }
// await preparePageRendering(pageRanderingOption);
// } else {
// await createNewMapItems(resultData.resourcePathArr);
// }
//// depth4 파일이 선택된 상태인 경우 depth4 파일 경로로 스타일 강조
if (vars.lastListItem) {
let lastListItemPath = vars.lastListItem.dataset.resourcePath;
let listItem = document.querySelector(`.archive-main-center .list-container .list-body .list-item[data-resource-path="${lastListItemPath}"]`)
if (listItem) {
changeListItemStyle(listItem);
//// 보고있는 파일이 리스트에서 벗어난 경우 포커스
targetFocus(listItem);
} else {
//// 보고있는 파일이 이동한 경우 미리보기 종료
resetViewer();
renderMemo();
//// vars 아이템 관련 변수 초기화
// vars.lastListItem = undefined;
// vars.lastSelectTarget = undefined;
}
}
}
}
})
//// 삭제 완료
// 로그 작성
socket.on('removeTarget_success', async (resultData) => {
// console.log('//////// 삭제');
// console.log(resultData);
let currProjectId = JSON.parse(vars.userInfoString).project_id;
if (currProjectId != resultData.projectId) return;
let myId = JSON.parse(vars.userInfoString).user_id;
let userInfo = JSON.parse(resultData.userInfoString);
let removedUserId = userInfo.user_id;
// console.log('-------- removeTarget socket error');
// console.log(resultData);
renderLog();
renderSizeBar();
removeCountdownTooltip();
let userCurPath;
if (vars.users[socket.id] && vars.users[socket.id].curPath) userCurPath = vars.users[socket.id].curPath;
let resourcePath = resultData.resourcePathArr[0];
let userCurPathSplit = userCurPath.split('/');
let depth1Path, depth2Path, depth3Path;
if (userCurPathSplit[1]) depth1Path = `${userCurPathSplit[0]}/${userCurPathSplit[1]}`;
if (userCurPathSplit[2]) depth2Path = `${depth1Path}/${userCurPathSplit[2]}`;
if (userCurPathSplit[3]) depth3Path = `${depth2Path}/${userCurPathSplit[3]}`;
let depth = getDepth(userCurPath);
//// depth1 폴더 영역 렌더링
let pageRanderingOption = {
scope: 'headerBtn',
resourcePath: userCurPath,
pushState: false
// userCurPath: userCurPath
}
await preparePageRendering(pageRanderingOption);
//// 마지막으로 선택된 depth1 폴더의 경로
let lastHeaderBtnPath = vars.lastHeaderBtn?vars.lastHeaderBtn.dataset.resourcePath:undefined;
let lastHeaderBtn = document.querySelector(`body > .header .center .menu-tab .btn[data-resource-path="${lastHeaderBtnPath}"]`);
//// lastHeaderBtn이 있는 경우 -> 마지막으로 선택된 depth1 폴더와 다른 폴더를 삭제한 경우
//// 마지막으로 선택된 depth1 폴더의 스타일 강조
if (lastHeaderBtn) changeHeaderBtnStyle(lastHeaderBtn);
lastHeaderBtnPath = vars.lastHeaderBtn?vars.lastHeaderBtn.dataset.resourcePath:undefined;
if (!lastHeaderBtn) {
//// lastHeaderBtn이 없는 경우 -> 마지막으로 선택된 depth1 폴더를 삭제한 경우
//// 변수 초기화
vars.lastHeaderBtn = undefined;
lastHeaderBtnPath = undefined;
lastHeaderBtn = undefined;
//// 메인 영역 숨기고 안내문구 표시
if (treeContainer.dataset.resourcePath == resourcePath && userCurPath != '/') { // 251114 김아름, && userCurPath != '/' 추가
archiveMain.style.display = 'none';
mainNotice.style.display = 'flex';
userCurPath = '/';
// 251111 김아름
if (myId != removedUserId) {
let toggleParams = {
text: `폴더가 삭제되었습니다.${resourcePath}`,
type: 'alertModal'
};
toggleModal(true, toggleParams);
}
vars.lastSelectTarget = undefined;
delete treeContainer.dataset.resourcePath;
// 251112 김아름, 브라우저 경로 수정
let pageRanderingOption = {
resourcePath: userCurPath,
pushState: true,
}
await preparePageRendering(pageRanderingOption);
}
// 현재 경로 갱신
let pageRanderingOption = {
scope: 'headerBtn',
resourcePath: userCurPath,
pushState: false
// userCurPath: userCurPath
}
await preparePageRendering(pageRanderingOption);
}
// 251114 김아름
if (lastHeaderBtnPath == undefined) return;
//// 폴더가 자동 삭제되었고, 현재 선택되어 있는 depth1 경로와 자동 삭제된 폴더의 depth1 폴더 경로가 동일할 때 아래 코드 실행
let extractedDepth1Path = extractPathByLength(resourcePath, 1);
if (resultData.isExpiredFolder && lastHeaderBtnPath == extractedDepth1Path) {
let toggleParams = {
text: `다음 폴더는 파일 개수 미달 및 만료 기간 경과로 인해 자동으로 삭제되었습니다.${resourcePath}`,
type: 'alertModal'
};
toggleModal(true, toggleParams);
}
//// 마지막으로 선택된 depth1 폴더 경로와 삭제하려는 depth2/depth3 폴더를 포함하고 있는 depth1 폴더 경로가 동일할 때 아래 코드 실행
if (lastHeaderBtnPath == depth1Path) {
//// 마지막으로 선택된 depth1 폴더의 하위 트리 폴더 렌더링
let pageRanderingOption = {
scope: 'tree',
resourcePath: depth1Path,
userCurPath: userCurPath,
}
await preparePageRendering(pageRanderingOption);
//// 현재 표시되어 있는 파일 리스트가 삭제한 depth2/depth3 폴더 안에 포함되어 있는 경우
let listWrapBodyPath = listWrapBody.dataset.resourcePath;
let listPath;
if (depth == 2) listPath = splitTopPathAndTargetName(listWrapBodyPath).topPath;
if (depth == 3) listPath = listWrapBodyPath;
// 251107 김아름, depth2 필터링을 위한 || listPath?.startsWith(resourcePath + '/') 추가
if (resourcePath == listPath || listPath?.startsWith(resourcePath + '/')) {
//// 현재 위치 수정, 리스트 영역, 뷰어 영역 숨기고 안내문구 표시
// listWrapBody.querySelector('.list-item-wrap').innerHTML = '';
// console.log('폴더 삭제했을 때 / 권한 수정해서 권한 해당 안될 때 -> 해당 폴더에 들어와있던 유저 경로 수정 필요');
userCurPath = extractPathByLength(resourcePath, 1);
// listContainer.style.display = 'none';
// listNotice.style.display = 'flex';
// resetViewer();
// 251111 김아름
if (myId != removedUserId) {
let toggleParams = {
text: `폴더가 삭제되었습니다.${resourcePath}`,
type: 'alertModal'
};
toggleModal(true, toggleParams);
// 251112 김아름, 브라우저 경로 수정
let pageRanderingOption = {
resourcePath: userCurPath,
pushState: true,
}
await preparePageRendering(pageRanderingOption);
}
lastHeaderBtn?.click();
vars.lastSelectTarget = undefined;
}
//// 마지막으로 선택된 depth3 폴더가 있을 때 아래 코드 실행
let lastMainTreeItemPath;
if (vars.lastMainTreeItem) {
//// 마지막으로 선택된 depth3 폴더의 스타일 강조
let mainTreeItem = document.querySelector(`.archive-main-left .tree-container .tree-wrap .tree-item-wrap[data-resource-path="${vars.lastMainTreeItem.dataset.resourcePath}"]`)
if (mainTreeItem) changeTreeItemStyle(mainTreeItem);
lastMainTreeItemPath = vars.lastMainTreeItem.dataset.resourcePath;
}
//// 마지막으로 선택된 depth3 폴더 경로와 삭제하려는 depth4 파일을 포함하고 있는 depth3 폴더 경로가 동일할 때 아래 코드 실행
//// -> 다른 depth3 폴더를 보고 있는 사용자는 코드 실행 안됨
if (lastMainTreeItemPath == depth3Path && lastMainTreeItemPath != undefined && depth3Path != undefined) {
let lastTreeItemWrap = document.querySelector(`.tree-item-wrap[data-resource-path="${lastMainTreeItemPath}"]`);
if (lastTreeItemWrap) {
//// 마지막으로 보고 있던 depth3 폴더가 그대로 있는 경우 아래 코드 실행
//// 리스트 렌더링
pageRanderingOption = {
scope: 'list',
resourcePath: depth3Path,
userCurPath: userCurPath,
}
await preparePageRendering(pageRanderingOption);
//// 마지막으로 선택된 depth4 파일이 있을 때 아래 코드 실행
if (vars.lastListItem) {
let lastListItemPath = vars.lastListItem.dataset.resourcePath;
let listItem = document.querySelector(`.archive-main-center .list-container .list-body .list-item[data-resource-path="${lastListItemPath}"]`)
if (listItem) {
//// 마지막으로 선택된 depth4 파일의 스타일 강조
changeListItemStyle(listItem);
} else {
//// 현재 위치 수정, 마지막으로 선택된 depth4 파일이 없으면 뷰어 영역 숨기고 안내문구 표시
// console.log('폴더 삭제했을 때 / 권한 수정해서 권한 해당 안될 때 -> 해당 폴더에 들어와있던 유저 경로 수정 필요');
userCurPath = extractPathByLength(resourcePath, 1);
resetViewer();
}
}
} else {
//// 마지막으로 보고 있던 depth3 폴더가 없어진 경우(null) 아래 코드 실행
vars.multiSelectListItemArr = [];
vars.lastListItem = undefined;
vars.lastSelectTarget = undefined;
vars.lastListGroupTarget = undefined;
toggleArchiveMainRight(false);
}
} else {
//// depth3가 선택되어 있지 않은 경우 아래 코드 실행
vars.multiSelectListItemArr = [];
vars.lastListItem = undefined;
vars.lastSelectTarget = undefined;
vars.lastListGroupTarget = undefined;
toggleArchiveMainRight(false);
}
}
//// 유저 위치 업데이트
// console.log('폴더 삭제했을 때 / 권한 수정해서 권한 해당 안될 때 -> 해당 폴더에 들어와있던 유저 경로 수정 필요');
// console.log(userCurPath);
pageRanderingOption = {
userCurPath: userCurPath,
pushState: false,
}
await preparePageRendering(pageRanderingOption);
})
/// 251104 박지은 ol 소켓처리
// socket.on('removeTarget_success', async (resultData) => {
// let currProjectId = JSON.parse(vars.userInfoString).project_id;
// if (currProjectId != resultData.projectId) return;
// renderLog();
// renderSizeBar();
// let userCurPath;
// if (vars.users[socket.id] && vars.users[socket.id].curPath) userCurPath = vars.users[socket.id].curPath;
// let resourcePath = resultData.resourcePathArr[0];
// let userCurPathSplit = userCurPath.split('/');
// let depth1Path, depth2Path, depth3Path, depth4Path;
// if (userCurPathSplit[1]) depth1Path = `${userCurPathSplit[0]}/${userCurPathSplit[1]}`;
// if (userCurPathSplit[2]) depth2Path = `${depth1Path}/${userCurPathSplit[2]}`;
// if (userCurPathSplit[3]) depth3Path = `${depth2Path}/${userCurPathSplit[3]}`;
// if (userCurPathSplit[4]) depth4Path = `${depth3Path}/${userCurPathSplit[4]}`;
// let depth = getDepth(userCurPath);
// //// depth1 폴더 영역 렌더링
// let pageRanderingOption = {
// scope: 'headerBtn',
// resourcePath: userCurPath,
// pushState: false
// // userCurPath: userCurPath
// }
// await preparePageRendering(pageRanderingOption);
// //// 마지막으로 선택된 depth1 폴더의 경로
// let lastHeaderBtnPath = vars.lastHeaderBtn? vars.lastHeaderBtn.dataset.resourcePath : undefined;
// let lastHeaderBtn = document.querySelector(`body > .header .center .menu-tab .btn[data-resource-path="${lastHeaderBtnPath}"]`);
// //// lastHeaderBtn이 있는 경우 -> 마지막으로 선택된 depth1 폴더와 다른 폴더를 삭제한 경우
// //// 마지막으로 선택된 detph1 폴더의 스타일 강조
// if (lastHeaderBtn) changeHeaderBtnStyle(lastHeaderBtn);
// lastHeaderBtnPath = vars.lastHeaderBtn?vars.lastHeaderBtn.dataset.resourcePath:undefined;
// if (!lastHeaderBtn) {
// //// lastHeaderBtn이 없는 경우 -> 마지막으로 선택된 depth1 폴더를 삭제한 경우
// //// 변수 초기화
// vars.lastHeaderBtn = undefined;
// lastHeaderBtnPath = undefined;
// lastHeaderBtn = undefined;
// //// 메인 영역 숨기고 안내문구 표시
// if (treeContainer.dataset.resourcePath == resourcePath) {
// archiveMain.style.display = 'none';
// mainNotice.style.display = 'flex';
// userCurPath = '/';
// }
// // 현재 경로 갱신
// let pageRanderingOption = {
// scope: 'headerBtn',
// resourcePath: userCurPath,
// pushState: false
// // userCurPath: userCurPath
// }
// await preparePageRendering(pageRanderingOption);
// }
// //// 마지막으로 선택된 depth1 폴더 경로와 삭제하려는 depth2/depth3 폴더를 포함하고 있는 depth1 폴더 경로가 동일할 때 아래 코드 실행
// if (lastHeaderBtnPath == depth1Path) {
// //// 마지막으로 선택된 depth1 폴더의 하위 트리 폴더 렌더링
// let pageRanderingOption = {
// scope: 'tree',
// resourcePath: depth1Path,
// userCurPath: userCurPath,
// }
// await preparePageRendering(pageRanderingOption);
// //// 현재 표시되어 있는 파일 리스트가 삭제한 depth2/depth3 폴더 안에 포함되어 있는 경우
// let listWrapBodyPath = listWrapBody.dataset.resourcePath;
// let listPath;
// if (depth == 2) listPath = splitTopPathAndTargetName(listWrapBodyPath).topPath;
// if (depth == 3) listPath = listWrapBodyPath;
// if (resourcePath == listPath) {
// //// 현재 위치 수정, 리스트 영역, 뷰어 영역 숨기고 안내문구 표시
// // listWrapBody.querySelector('.list-item-wrap').innerHTML = '';
// // console.log('폴더 삭제했을 때 / 권한 수정해서 권한 해당 안될 때 -> 해당 폴더에 들어와있던 유저 경로 수정 필요');
// userCurPath = extractPathByLength(resourcePath, 1);
// listContainer.style.display = 'none';
// listNotice.style.display = 'flex';
// resetViewer();
// }
// //// 마지막으로 선택된 depth3 폴더가 있을 때 아래 코드 실행
// let lastMainTreeItemPath;
// if (vars.lastMainTreeItem) {
// //// 마지막으로 선택된 depth3 폴더의 스타일 강조
// let mainTreeItem = document.querySelector(`.archive-main-left .tree-container .tree-wrap .tree-item-wrap[data-resource-path="${vars.lastMainTreeItem.dataset.resourcePath}"]`)
// if (mainTreeItem) changeTreeItemStyle(mainTreeItem);
// lastMainTreeItemPath = vars.lastMainTreeItem.dataset.resourcePath;
// }
// //// 마지막으로 선택된 depth3 폴더 경로와 삭제하려는 depth4 파일을 포함하고 있는 depth3 폴더 경로가 동일할 때 아래 코드 실행
// //// -> 다른 depth3 폴더를 보고 있는 사용자는 코드 실행 안됨
// // if (lastMainTreeItemPath == depth3Path && lastMainTreeItemPath != undefined && depth3Path != undefined) {
// if (resourcePath == depth1Path) {
// //// 리스트 렌더링
// pageRanderingOption = {
// scope: 'list',
// resourcePath: depth3Path,
// userCurPath: userCurPath,
// }
// await preparePageRendering(pageRanderingOption);
// //// 마지막으로 선택된 depth4 파일이 있을 때 아래 코드 실행
// if (vars.lastListItem) {
// let lastListItemPath = vars.lastListItem.dataset.resourcePath;
// let listItem = document.querySelector(`.archive-main-center .list-container .list-body .list-item[data-resource-path="${lastListItemPath}"]`)
// if (listItem) {
// //// 마지막으로 선택된 depth4 파일의 스타일 강조
// changeListItemStyle(listItem);
// } else {
// //// 현재 위치 수정, 마지막으로 선택된 depth4 파일이 없으면 뷰어 영역 숨기고 안내문구 표시
// // console.log('폴더 삭제했을 때 / 권한 수정해서 권한 해당 안될 때 -> 해당 폴더에 들어와있던 유저 경로 수정 필요');
// userCurPath = extractPathByLength(resourcePath, 1);
// resetViewer();
// }
// }
// }
// }
// //// 유저 위치 업데이트
// // console.log('폴더 삭제했을 때 / 권한 수정해서 권한 해당 안될 때 -> 해당 폴더에 들어와있던 유저 경로 수정 필요');
// // console.log(userCurPath);
// pageRanderingOption = {
// userCurPath: userCurPath,
// pushState: false
// }
// await preparePageRendering(pageRanderingOption);
// vars.multiSelectListItemArr = [];
// })
socket.on('deleteTarget_success', async (resultData) => {
// console.log('@@@@@@@@@');
// console.log(resultData);
let currProjectId = JSON.parse(vars.userInfoString).project_id;
if (currProjectId != resultData.projectId) return;
// renderLog();
renderSizeBar();
let isRecycleBinModal = document.querySelector('.recycle-bin-modal').style.display == 'flex';
if (isRecycleBinModal) await prepareRecycleBinRendering();
})
//// 메모 데이터 저장
socket.on('saveMemo_success', async (resultData) => {
let currProjectId = JSON.parse(vars.userInfoString).project_id;
if (currProjectId != resultData.projectId) return;
let userCurPath;
if (vars.users[socket.id] && vars.users[socket.id].curPath) userCurPath = vars.users[socket.id].curPath;
// 메모가 생성된 파일의 depth3 path와 유저 현재위치 비교 후 화면에 반영
let memoDepth3Path = extractPathByLength(resultData.resourcePath, 3);
if (memoDepth3Path == userCurPath) {
let pageRanderingOption = {
scope: 'list',
resourcePath: memoDepth3Path,
}
await preparePageRendering(pageRanderingOption);
}
// renderLog();
let data;
if(vars.lastListItem) {
// console.log(resultData)
// data = vars.currentTreeObject
data = getDataFromTreeObject(resultData.resourcePath, 'file', vars.allTreeObject).data;
data.memo = resultData.memo;
if(resultData.resourcePath == vars.lastListItem.dataset.resourcePath) {
let resourcePath = splitTopPathAndTargetName(data.resourcePath).topPath;
// 추가 파일에 메모 저장하는 경우 위의 resourcePath는 depth1/depth2/depth3/파일명.txt_version 과 같은 형태로 가공된 상태
// list 렌더를 위해 필요한 resourcePath의 형태는 depth1/depth2/depth3
// 따라서 resourcePath를 접두어(_version, _attachment 등)로 split 후 배열 0번째를 구한 뒤,
// 이것을 splitTopPathAndTargetName함수를 통해 topPath를 구하면 depth1/depth2/depth3 형태로 가공됨
if (resourcePath.includes('_version')) resourcePath = splitTopPathAndTargetName(resourcePath.split('_version')[0]).topPath;
if (resourcePath.includes('_attachment')) resourcePath = splitTopPathAndTargetName(resourcePath.split('_attachment')[0]).topPath;
let pageRanderingOption = {
scope: 'list',
resourcePath: resourcePath
}
await preparePageRendering(pageRanderingOption);
}
}
})
//// 권한 설정
socket.on('setDataPermission_success', async (resultData) => {
// console.log('-------- setDataPermission socket error');
// console.log(resultData);
let currProjectId = JSON.parse(vars.userInfoString).project_id;
if (currProjectId != resultData.projectId) return;
renderLog();
let userCurPath, userCurPermission;
if (vars.users[socket.id] && vars.users[socket.id].curPath) userCurPath = vars.users[socket.id].curPath;
if (vars.users[socket.id] && vars.users[socket.id].permission) userCurPermission = vars.users[socket.id].permission; // 251107 김아름
let extractedPath = extractPathByLength(userCurPath, 1);
// 251107 김아름
let myId = JSON.parse(vars.userInfoString).user_id;
let userInfo = JSON.parse(resultData.userInfoString);
let permissionChangeUserId = userInfo.user_id;
let permissionChangedFolderPath = resultData.resourcePath;
let permissionChangedFolderDepth = getDepth(permissionChangedFolderPath);
let pathSplit = permissionChangedFolderPath.split('/');
let permissionChangedFolderDepth1Path, permissionChangedFolderDepth2Path, permissionChangedFolderDepth3Path;
if (pathSplit[1]) permissionChangedFolderDepth1Path = `${pathSplit[0]}/${pathSplit[1]}`;
if (pathSplit[2]) permissionChangedFolderDepth2Path = `${permissionChangedFolderDepth1Path}/${pathSplit[2]}`;
if (pathSplit[3]) permissionChangedFolderDepth3Path = `${permissionChangedFolderDepth2Path}/${pathSplit[3]}`;
let beforePermission = (resultData.beforePermission == 0) ? 99999 : resultData.beforePermission;
let newPermission = (resultData.newPermission == 0) ? 99999 : resultData.newPermission;
//// 마지막으로 선택된 depth1 폴더의 경로
let lastHeaderBtnPath = vars.lastHeaderBtn?vars.lastHeaderBtn.dataset.resourcePath:undefined;
let lastHeaderBtn = document.querySelector(`body > .header .center .menu-tab .btn[data-resource-path="${lastHeaderBtnPath}"]`);
//// 마지막으로 선택된 depth1 폴더의 스타일 강조
if (lastHeaderBtn) changeHeaderBtnStyle(lastHeaderBtn);
lastHeaderBtnPath = vars.lastHeaderBtn?vars.lastHeaderBtn.dataset.resourcePath:undefined;
// 251107 김아름, 내가 지금 있는 폴더와 상대방이 권한을 바꾼 폴더 비교
// 권한 변경에 영향이 있는 조건
const isAffected =
myId != permissionChangeUserId && // 권한 바꾼 사람이 내가 아닐 때
beforePermission < newPermission && // 이전 폴더 권한보다 바꾼 폴더 권한이 클때(참관자->참관자일때도 alert떠서 방지용)
userCurPermission < newPermission; // 나의 권한보다 바꾼 폴더 권한이 클때
if (isAffected) {
if (permissionChangedFolderDepth === 1 && extractedPath == permissionChangedFolderDepth1Path) {
// 권한 바뀐 폴더가 depth1인 경우 && 내 현재 위치의 depth1 폴더명이 권한 바뀐 폴더명과 같을 때
let toggleParams = {
text: `폴더의 권한이 변경되었습니다.${permissionChangedFolderDepth1Path}`,
type: 'alertModal'
};
toggleModal(true, toggleParams);
document.querySelector('.archive-main.main').style.display = 'none';
document.querySelector('.main-notice.notice').style.display = 'flex';
vars.lastMainTreeItem = undefined;
}
if (permissionChangedFolderDepth === 2 && userCurPath.startsWith(permissionChangedFolderDepth2Path + '/')) {
// 권한 바뀐 폴더가 depth2인 경우 && 내 현재 위치가 권한 바뀐 폴더의 depth2 path로 시작될 때
let toggleParams = {
text: `폴더의 권한이 변경되었습니다.${permissionChangedFolderDepth2Path}`,
type: 'alertModal'
};
toggleModal(true, toggleParams);
lastHeaderBtn?.click();
vars.lastMainTreeItem = undefined;
}
if (permissionChangedFolderDepth === 3 && userCurPath == permissionChangedFolderDepth3Path) {
// 권한 바뀐 폴더가 depth3인 경우 && 내 현재 위치가 권한 바뀐 폴더와 같을 때
let toggleParams = {
text: `폴더의 권한이 변경되었습니다.${permissionChangedFolderDepth3Path}`,
type: 'alertModal'
};
toggleModal(true, toggleParams);
lastHeaderBtn?.click();
vars.lastMainTreeItem = undefined;
}
// 251112 김아름, 브라우저 경로 수정
if (permissionChangedFolderDepth == 1) {
let pageRanderingOption = {
resourcePath: '/',
pushState: true,
}
await preparePageRendering(pageRanderingOption);
}
if (permissionChangedFolderDepth == 2 || permissionChangedFolderDepth == 3) {
let pageRanderingOption = {
resourcePath: extractedPath,
pushState: true,
}
await preparePageRendering(pageRanderingOption);
}
}
//// depth1 폴더 영역 렌더링
let pageRanderingOption = {
scope: 'headerBtn',
pushState: false
}
await preparePageRendering(pageRanderingOption);
// 251114 김아름
if (vars.lastHeaderBtn == undefined) return;
//// depth2, depth3 폴더 생성
//// 마지막으로 선택된 depth1 폴더 안에 depth2, depth3 폴더의 권한을 설정할 때 아래 코드 실행
//// -> 다른 depth1 폴더를 보고 있는 사용자는 해당 안됨
if (extractedPath == lastHeaderBtnPath) {
//// 마지막으로 선택된 depth1 폴더의 하위 트리 폴더 렌더링
let pageRanderingOption = {
scope: 'tree',
resourcePath: extractedPath,
userCurPath: userCurPath,
pushState: false
}
await preparePageRendering(pageRanderingOption);
if (vars.lastMainTreeItem) {
let mainTreeItem = document.querySelector(`.archive-main-left .tree-container .tree-wrap .tree-item-wrap[data-resource-path="${vars.lastMainTreeItem.dataset.resourcePath}"]`)
if (mainTreeItem) changeTreeItemStyle(mainTreeItem);
}
}
// console.log('폴더 삭제했을 때 / 권한 수정해서 권한 해당 안될 때 -> 해당 폴더에 들어와있던 유저 경로 수정 필요');
//// depth3 폴더가 선택된 상태이고, depth3 폴더 경로의 데이터가 존재할 때 리스트 렌더링
// if (treeContainer.dataset.resourcePath == extractedPath && vars.lastMainTreeItem) {
// let lastTreePath = vars.lastMainTreeItem.dataset.resourcePath
// let data = getDataFromTreeObject(lastTreePath, 'folder').data;
// if (data) {
// let pageRanderingOption = {
// scope: 'list',
// resourcePath: lastTreePath,
// pushState: false,
// debug: '업로드완료 - list'
// }
// await preparePageRendering(pageRanderingOption);
// //// depth4 파일이 선택된 상태인 경우 depth4 파일 경로로 스타일 강조
// if (vars.lastListItem) {
// let lastListItemPath = vars.lastListItem.dataset.resourcePath;
// let listItem = document.querySelector(`.archive-main-center .list-container .list-body .list-item[data-resource-path="${lastListItemPath}"]`)
// if (listItem) changeListItemStyle(listItem);
// }
// }
// }
})
//// 만료 기간 갱신
socket.on('renewExpiryDate_success', async (resultData) => {
// console.log('//////// 만료 기간 갱신');
// console.log(resultData);
let currProjectId = JSON.parse(vars.userInfoString).project_id;
if (currProjectId != resultData.projectId) return;
let userCurPath;
if (vars.users[socket.id] && vars.users[socket.id].curPath) userCurPath = vars.users[socket.id].curPath;
let lastHeaderBtnPath = vars.lastHeaderBtn?vars.lastHeaderBtn.dataset.resourcePath:undefined;
let pathSplit = resultData.resourcePath.split('/');
let depth1Path, depth2Path, depth3Path;
if (pathSplit[1]) depth1Path = `${pathSplit[0]}/${pathSplit[1]}`;
if (pathSplit[2]) depth2Path = `${depth1Path}/${pathSplit[2]}`;
if (pathSplit[3]) depth3Path = `${depth2Path}/${pathSplit[3]}`;
//// 마지막으로 선택된 depth1 폴더 경로와 변경하려는 depth3 폴더를 포함하고 있는 depth1 폴더 경로가 동일할 때 아래 코드 실행
//// -> 다른 depth1 폴더를 보고 있는 사용자는 코드 실행 안됨
if (lastHeaderBtnPath == depth1Path) {
//// 마지막으로 선택된 depth1 폴더의 하위 트리 폴더 렌더링
let pageRanderingOption = {
scope: 'tree',
pushState: false,
resourcePath: depth1Path,
userCurPath: userCurPath
}
await preparePageRendering(pageRanderingOption);
//// 마지막으로 선택된 depth3 폴더가 있을 때 아래 코드 실행
if (vars.lastMainTreeItem) {
//// 마지막으로 선택된 depth3 폴더의 경로
let lastMainTreeItemPath = vars.lastMainTreeItem.dataset.resourcePath;
//// 마지막으로 선택된 depth3 폴더의 스타일 강조
let mainTreeItem = document.querySelector(`.archive-main-left .tree-container .tree-wrap .tree-item-wrap[data-resource-path="${lastMainTreeItemPath}"]`)
if (mainTreeItem) changeTreeItemStyle(mainTreeItem);
}
}
})
//// 작성자 변경
socket.on('editAuthor_success', async (resultData) => {
let currProjectId = JSON.parse(vars.userInfoString).project_id;
if (currProjectId != resultData.projectId) return;
renderLog();
// vars.allTreeObject만 갱신
let pageRanderingOption = {
scope: 'updateTreeObject',
pushState: false,
resourcePath: JSON.parse(vars.userInfoString).curPath
}
await preparePageRendering(pageRanderingOption);
let extractedPath = extractPathByLength(resultData.originalResourcePathArr[0], 3);
if (listWrapBody.dataset.resourcePath == extractedPath) {
for (let dataId of resultData.dataIdArr) {
let listItem = document.querySelector(`.archive-main-center .list-container .list-body .list-item[data-id="${dataId}"]`)
if (listItem) {
let authorText = listItem.querySelector('.author .text');
authorText.innerText = resultData.newAuthorNm;
}
if (viewerContainer.dataset.dataId == dataId) {
let viewerAuthorText = viewerContainer.querySelector('.info-wrap .metadata .author .value');
viewerAuthorText.innerText = resultData.newAuthorNm;
}
}
// 작성자 정렬을 위한 리스트 렌더링
let pageRanderingOption = {
scope: 'list',
pushState: false,
resourcePath: JSON.parse(vars.userInfoString).curPath
}
await preparePageRendering(pageRanderingOption);
}
})
//// viewer 리셋
socket.on('requestResetViewer', async (resultData) => {
let resourcePath = resultData.resourcePath;
let depth = getDepth(resourcePath);
let compPath = extractPathByLength(listWrapBody.dataset.resourcePath, depth);
if (listContainer.style.display == 'flex' && compPath == resourcePath) resetViewer();
})
//// 현재 내 정보 받아오기
socket.on('returnMe', (data)=>{
let me = data;
vars.userInfoString = JSON.stringify(me);
vars.users[socket.id] = me;
})
//// 동일 프로젝트 접속자 확인 => 추후 동일 프로젝트 접속자 알림으로 사용
socket.on('connected_user', (data) => {
let {users} = data;
vars.users = users;
// console.log(data);
// console.log(users);
let connectedUsers = document.querySelector('body > .header .right .connected-users');
let connectedUsersCount = connectedUsers.querySelector('.count');
connectedUsersCount.innerHTML = '';
// let keys = Object.keys(users);
let values = Object.values(users);
connectedUsersCount.innerHTML = `${addCommasToNumber(values.length)} 명`;
// connectedUsersCount.innerHTML = `${addCommasToNumber(9806)} 명`;
let modalHeaderUsersCount = document.querySelector('.archive-modal .modal-header > .title .left-wrap .title-wrap .users-count');
modalHeaderUsersCount.innerHTML = '';
modalHeaderUsersCount.innerHTML = `${addCommasToNumber(values.length)} 명`;
let connectedUsersWrap = document.querySelector('.archive-modal .modal-body .connected-users-wrap');
let userItemWrap = connectedUsersWrap.querySelector('.user-item-wrap');
userItemWrap.innerHTML = '';
let docFragment = document.createDocumentFragment();
let userInfo = JSON.parse(vars.userInfoString);
for(let i = 0; i < values.length; i++){
let user = values[i];
let userId = user.user_id;
let userName = `${user.user_nm} ${user.position}`;
userName = userName.trim();
let userColor = user.userColor;
let userPermission = user.permission;
let userCurPath = user.curPath;
let userItem = document.createElement('div');
userItem.classList.add('user-item');
userItem.dataset.userId = userId;
let wrap = document.createElement('div');
wrap.classList.add('wrap');
let topWrap = document.createElement('div');
topWrap.classList.add('top-wrap');
let bottomWrap = document.createElement('div');
bottomWrap.classList.add('bottom-wrap');
let profileImage = document.createElement('img');
profileImage.classList.add('profile-image');
profileImage.style.outline = `2px solid ${userColor}`;
let defaultImageUrl = '/main/img/archive/empty-profile.svg';
let profileImageUrl = defaultImageUrl;
if (/^[a-zA-Z]{1}\d{5}$/.test(userId)) profileImageUrl = `http://erp.hanmaceng.co.kr/erpphoto/${userId}.jpg`;
profileImage.src = profileImageUrl;
// onerror 핸들러 바인딩 (한번만 동작하도록)
profileImage.onerror = function() {
this.onerror = null; // 무한루프 방지
this.src = defaultImageUrl;
};
let name = document.createElement('div');
name.classList.add('name');
name.innerHTML = userName;
let addPermissionBadge = false, permissionBadge, permissionEng, permissionKor;
// if (userPermission == 191) {
if (vars.permission.permissionDef[user.permission] == '관리자') {
addPermissionBadge = true;
permissionEng = 'master';
permissionKor = '관리자';
}
if (vars.permission.permissionDef[user.permission] == '부관리자') {
addPermissionBadge = true;
permissionEng = 'sub-master';
permissionKor = '부관리자';
}
if (vars.permission.permissionDef[user.permission] == '보안참여자') {
addPermissionBadge = true;
permissionEng = 'security-worker';
permissionKor = '보안참여자';
}
if (vars.permission.permissionDef[user.permission] == '일반참여자') {
addPermissionBadge = true;
permissionEng = 'worker';
permissionKor = '일반참여자';
}
if (vars.permission.permissionDef[user.permission] == '참관자') {
addPermissionBadge = true;
permissionEng = 'viewer';
permissionKor = '참관자';
}
if (addPermissionBadge) {
permissionBadge = document.createElement('div');
permissionBadge.classList.add(`user-permission-${permissionEng}`);
let h6 = document.createElement('h6');
h6.innerText = permissionKor;
permissionBadge.appendChild(h6);
}
let curPath = document.createElement('div');
curPath.classList.add('cur-path');
curPath.innerHTML = `현재 위치: ${userCurPath}`;
topWrap.appendChild(name);
if (permissionBadge) topWrap.appendChild(permissionBadge);
bottomWrap.appendChild(curPath);
wrap.appendChild(topWrap);
// 프로젝트에 포함된 사용자인 경우에만 접속 인원 모달창에서 현재 위치 표시
if (userInfo.permission != null && typeof userInfo.permission == 'number') wrap.appendChild(bottomWrap);
userItem.appendChild(profileImage);
userItem.appendChild(wrap);
docFragment.appendChild(userItem);
}
userItemWrap.appendChild(docFragment);
addMeBadge();
function addMeBadge() {
let myId = JSON.parse(vars.userInfoString).user_id;
let userItemWrap = document.querySelector('.archive-modal .modal-body .connected-users-wrap .user-item-wrap');
let myUserItem = userItemWrap.querySelector(`.user-item[data-user-id="${myId}"]`);
myUserItem.classList.add('me');
userItemWrap.insertBefore(myUserItem, userItemWrap.firstElementChild);
if (!myUserItem.querySelector('.wrap .top-wrap .me-badge')) {
let meBadge = document.createElement('div');
meBadge.classList.add('me-badge');
let h6 = document.createElement('h6');
h6.innerText = '나';
meBadge.appendChild(h6);
myUserItem.querySelector('.wrap .top-wrap').appendChild(meBadge);
}
}
})
//// 현재 파일선택한 사람들 확인
// socket.on('fileSelected', (data)=>{
// let {users} = data;
// Object.assign(vars.users, users);
// console.log(users);
// })
//folder download 준비 완료
socket.on('zip-prepared', (data)=>{
// 다운로드창 new 표시
if(document.querySelector('.download-btn .download-reddot')){
document.querySelector('.download-btn .download-reddot').style.display = 'block';
}
// console.log('다운로드 준비 완료', data);
// alert(`${data.resourcePath}의 다운로드가 준비되었습니다.`);
})
// 폴더 압축 프로그레스
socket.on('zip-progress', (data)=>{
console.log(data);
})
//// AI 요약 시작
socket.on('summarize_start', (resultData) => {
let currProjectId = JSON.parse(vars.userInfoString).project_id;
if (currProjectId != resultData.projectId) return;
let datas = resultData.summarizeAiDataArr;
datas.forEach(data => {
const { dataId, type } = data;
// 해당 파일의 버튼만 로딩 상태로 변경
updateAiButtonState(dataId, 'loading', type);
})
});
//// AI 요약 로그 기록 완료
socket.on('addSummarizeAiLog_success', async (resultData) => {
let currProjectId = JSON.parse(vars.userInfoString).project_id;
if (currProjectId != resultData.projectId) return;
const { text, dataId, type } = resultData;
renderMemo(text, dataId);
updateAiButtonState(dataId, 'initial', type);
renderLog();
let userCurPath;
if (vars.users[socket.id] && vars.users[socket.id].curPath) userCurPath = vars.users[socket.id].curPath;
// 메모가 생성된 파일의 depth3 path와 유저 현재위치 비교 후 화면에 반영
let memoDepth3Path = extractPathByLength(resultData.resourcePath, 3);
if (memoDepth3Path == userCurPath) {
let pageRanderingOption = {
scope: 'list',
resourcePath: memoDepth3Path,
}
await preparePageRendering(pageRanderingOption);
}
})
//// AI 요약 실패
socket.on('summarize_failed', async (resultData) => {
const { resourcePath, dataId, text, type } = resultData;
renderMemo(text, dataId);
updateAiButtonState(dataId, 'initial', type);
let userInfoString = vars.userInfoString;
let params = {
resourcePath: resourcePath,
memo: text,
};
let res = await axios.post(`${vars.path_name}/updateMemoInfo`, { userInfoString, params });
let addSummarizeAiLogParams = {
dataId: dataId,
isState: false
};
await axios.post(`${vars.path_name}/addSummarizeAiLog`, { addSummarizeAiLogParams});
});
// 유저권한 추가/삭제 로그 기록 완료
socket.on('addPermissionLog_success', async (resultData) => {
let currProjectId = JSON.parse(vars.userInfoString).project_id;
if (currProjectId != resultData.projectId) return;
renderLog();
});