Forráskód Böngészése

update 2024-04-30

junggilpark 1 éve
szülő
commit
f5833f9c4e
5 módosított fájl, 390 hozzáadás és 99 törlés
  1. 62 0
      package-lock.json
  2. 1 0
      package.json
  3. 163 41
      src/app.js
  4. 1 1
      src/static/styles/custom.css
  5. 163 57
      src/views/hello.html

+ 62 - 0
package-lock.json

@@ -23,6 +23,7 @@
                 "express": "^4.19.2",
                 "express-session": "^1.18.0",
                 "fs": "^0.0.1-security",
+                "jszip": "^3.10.1",
                 "multer": "^1.4.5-lts.1",
                 "path": "^0.12.7",
                 "restify": "^11.1.0",
@@ -1999,6 +2000,11 @@
             "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==",
             "dev": true
         },
+        "node_modules/immediate": {
+            "version": "3.0.6",
+            "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz",
+            "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ=="
+        },
         "node_modules/inflight": {
             "version": "1.0.6",
             "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
@@ -2223,6 +2229,44 @@
                 "verror": "1.10.0"
             }
         },
+        "node_modules/jszip": {
+            "version": "3.10.1",
+            "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz",
+            "integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==",
+            "dependencies": {
+                "lie": "~3.3.0",
+                "pako": "~1.0.2",
+                "readable-stream": "~2.3.6",
+                "setimmediate": "^1.0.5"
+            }
+        },
+        "node_modules/jszip/node_modules/readable-stream": {
+            "version": "2.3.8",
+            "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
+            "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
+            "dependencies": {
+                "core-util-is": "~1.0.0",
+                "inherits": "~2.0.3",
+                "isarray": "~1.0.0",
+                "process-nextick-args": "~2.0.0",
+                "safe-buffer": "~5.1.1",
+                "string_decoder": "~1.1.1",
+                "util-deprecate": "~1.0.1"
+            }
+        },
+        "node_modules/jszip/node_modules/safe-buffer": {
+            "version": "5.1.2",
+            "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+            "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
+        },
+        "node_modules/jszip/node_modules/string_decoder": {
+            "version": "1.1.1",
+            "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+            "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+            "dependencies": {
+                "safe-buffer": "~5.1.0"
+            }
+        },
         "node_modules/jwa": {
             "version": "2.0.0",
             "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz",
@@ -2288,6 +2332,14 @@
                 "safe-buffer": "~5.1.0"
             }
         },
+        "node_modules/lie": {
+            "version": "3.3.0",
+            "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz",
+            "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==",
+            "dependencies": {
+                "immediate": "~3.0.5"
+            }
+        },
         "node_modules/lodash": {
             "version": "4.17.21",
             "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
@@ -2589,6 +2641,11 @@
                 "url": "https://github.com/sponsors/sindresorhus"
             }
         },
+        "node_modules/pako": {
+            "version": "1.0.11",
+            "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
+            "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw=="
+        },
         "node_modules/parseurl": {
             "version": "1.3.3",
             "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
@@ -3128,6 +3185,11 @@
                 "node": ">= 0.4"
             }
         },
+        "node_modules/setimmediate": {
+            "version": "1.0.5",
+            "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
+            "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA=="
+        },
         "node_modules/setprototypeof": {
             "version": "1.2.0",
             "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",

+ 1 - 0
package.json

@@ -21,6 +21,7 @@
         "express": "^4.19.2",
         "express-session": "^1.18.0",
         "fs": "^0.0.1-security",
+        "jszip": "^3.10.1",
         "multer": "^1.4.5-lts.1",
         "path": "^0.12.7",
         "restify": "^11.1.0",

+ 163 - 41
src/app.js

@@ -9,10 +9,12 @@ const authProvider = require('./auth/AuthProvider');
 const {getFetch, updateFetch} = require('./fetch');
 const bodyParser = require('body-parser');
 const https = require('https');
+const JSZIP = require('jszip');
 require('dotenv').config({ path: './env/.env.test' });
 const session = require('express-session');
 const multer  = require('multer');
 const { throws } = require('assert');
+let _ZIP;
 const storage =  multer.diskStorage({
   destination: function (req, file, cb) { 
     cb(null, 'uploads/')  
@@ -301,18 +303,14 @@ serverApp.post('/uploadItems', upload.array('file'),
           let beforeUri = '';
           let beforeItemId = '';
           for (let item of folder) {
-            console.log('beforeUri', beforeUri);
-            console.log('beforeItemId', beforeItemId);
             const fileInfo = JSON.parse(item);
             const param = {...folderParam};
             param.name = fileInfo.name;
-            console.log('param :', param);
             let folderPath = '';
             if (fileInfo.path) {
               folderPath = ':' + fileInfo.path; 
             }
             let uri = endPoint + "/sites/"+ siteId + path + folderPath;
-            console.log('folderPath :',folderPath);
             try {
               
               let itemId = '';
@@ -354,8 +352,6 @@ serverApp.post('/uploadItems', upload.array('file'),
                   if (filePath.length > 1) {
                     req.body[ fileName + "_path"] = filePath.splice(1); 
                   }
-                  console.log('splice After', req.body[ fileName + "_path"]);
-                  console.log('formatPath : ', formatPath);
                 }
                 else if (filePath.trim()){
                   formatPath = ":" + filePath;
@@ -424,49 +420,175 @@ serverApp.post('/uploadItems', upload.array('file'),
 
     // }
 })
+serverApp.post('/api/download',
+  isAuthenticated,
+  (req, res, next)=>{
+    if (!req.session.accessToken) {
+      return authProvider.acquireToken({
+        scopes: ['.default'],
+        redirectUri: 'https://localhost:53000/redirect',
+        successRedirect: '/api/download'
+      })(req, res, next);
+    }
+    next();
+  },
+  async (req, res, next)=>{
+    if (req.body) {
+      const {siteId, path, fileIds, zipName} = req.body;
+      if (siteId && path && fileIds) {
+        const options = {
+          headers: {
+            Authorization: `Bearer ${req.session.accessToken}`,
+          },
+        };
+        const arr = JSON.parse(fileIds);
+        if (arr.length === 1) {
+          const sitesInfo = await axios.get(endPoint + "/sites/"+ siteId + "/drive/items/" + arr[0], options);
+          if (sitesInfo && sitesInfo.data) {
+            const data = sitesInfo.data;
+            if (data.folder) {
+              const folderObj = await getFolderItems(endPoint + "/sites/"+ siteId + "/drive/items/", arr, options);
+              const zip = new JSZIP();
+              if (folderObj) {
+                createZipFile(folderObj, zip);
+                const now = new Date();
+                const year = now.getFullYear().toString();
+                let month = now.getMonth() + 1;
+                if (month < 10) month = "0" + month;
+                let date = now.getDate();
+                if (date < 10) date = "0" + date;
+                zip.generateAsync({
+                  type: 'nodebuffer',
+                  mimeType: 'application/epub+zip',
+                  compression: 'DEFLATE',
+                  compressionOptions: {
+                    level: 9
+                  },
+                }).then((resZip)=>{
+                  return res.json({success: 'S', data: resZip, name: data.name + '_' + year + '-' + month + '-' + date + '.zip'});
+                })
+                .catch((error)=>{
+                  console.log(error);
+                  return res.json({success: 'F', message:'파일 다운로드 중 오류가 발생하였습니다.', error: error});
+                });
+              }
+            }
+            else {
+              const dataUrl = data['@microsoft.graph.downloadUrl'];
+              const response = await axios.get(dataUrl, {responseType: 'arraybuffer', headers: {
+                withCredentials:true,
+              },});
+              if (response.data) {
+                const file = response.data;
+                return res.json({success: 'S', data: file, type: data.file.mimeType, name: data.name});
+              }
+              else {
+                return res.json({message:'파일 다운로드에 실패하였습니다.', success:'F'})
+              }
+            }
+          }
+        }
+        else {
+            try {
+              const url = endPoint + "/sites/"+ siteId + "/drive/items/";
+              const zip = new JSZIP();
+              const downObj = await getFolderItems(url, arr, options);
+              if (downObj) {
+                createZipFile(downObj, zip);
+                const now = new Date();
+                const year = now.getFullYear().toString();
+                let month = now.getMonth() + 1;
+                if (month < 10) month = "0" + month;
+                let date = now.getDate();
+                if (date < 10) date = "0" + date;
+                zip.generateAsync({
+                  type: 'nodebuffer',
+                  mimeType: 'application/epub+zip',
+                  compression: 'DEFLATE',
+                  compressionOptions: {
+                    level: 9
+                  },
+                }).then((resZip)=>{
+                  return res.json({success: 'S', data: resZip, name: zipName + '_' + year + '-' + month + '-' + date + '.zip'});
+                })
+                .catch((error)=>{
+                  console.log(error);
+                  return res.json({success: 'F', message:'파일 다운로드 중 오류가 발생하였습니다.', error: error});
+                });
+              }
+            }
+            catch(err) {
+              // console.log(sitesInfo.data);
+              console.log(err);
+            }
+          // }
+        }
+      }
+      else {
+        return res.json({message:'다운로드 파일 정보를 확인 할 수 없습니다.', success:'F'})
+      }
+    }
+  }
+)
 
-function uploadFIles(uri, token, mimeType, file) {
-  return fetch(uri, {
-    method : 'PUT',
-    headers: {
-      Authorization: `Bearer ${token}`,
-      "Content-Type" : mimeType
-    },
-    data : file,
-  })
+function createZipFile(obj, zip) {
+  
+  if (obj.files.length > 0) {
+    for (let file of obj.files) {
+      zip.file(file.name, file.data);
+    }
+  }
+
+  if (obj.folder.length > 0) {
+    for (let folder of obj.folder) {
+      zip.folder(folder.name);
+      if (folder.subFolder) {
+        createZipFile(folder.subFolder, zip.folder(folder.name));
+      }
+    }
+  }
 }
 
-async function uploadItems(array, path, siteId, options) { 
-    for (let item of array) { 
-      try{
-        if (item) {
-          const param  = item.param;
-          console.log("============================ param ===============================");
-          console.log(param);
-          console.log("============================ param ===============================");
-          const sitesInfo = await axios.get(endPoint + "/sites/"+ siteId + path, options);
-          const itemId = sitesInfo.data.id;
-          console.log("============================ sitesInfo ===============================");
-          console.log(sitesInfo.data);
-          console.log("============================ sitesInfo ===============================");
-          if (sitesInfo.data) {
-            if (param.folder) {
-              await axios.post(endPoint + "/sites/"+ siteId +"/drive/items/" + itemId +"/children", param, options);
-            }
-            else if (param.file) {
-              await axios.put(endPoint + "/sites/"+ siteId +"/drive/items/"+itemId+':/'+param.name+':/content', param, options);
-            }
-            
-            if (item.subfolder && item.subfolder.length > 0) {
-              await uploadItems(item.subfolder, path + '/' + param.name, siteId, options);
+async function getFolderItems(url, array, options) {
+  const files = [];
+  // let subFolder = [];
+  let folder = [];
+  
+  for (let fileId of array) {
+    const sitesInfo = await axios.get(url + fileId, options);
+    const data = sitesInfo.data;
+    if (data) {
+      if (data.folder) {
+        const folderObj = {name : data.name, subFolder : []};
+        if (data.folder.childCount) {
+          const itemsData = await axios.get(url + fileId + '/children', options);
+          if (itemsData && itemsData.data && itemsData.data.value.length > 0) {
+            const idArr = [];
+            for (let children of itemsData.data.value) {
+              idArr.push(children.id);
             }
+            let result = await getFolderItems(url, idArr, options);
+            // subFolder.push(result);
+            folderObj.subFolder = result;
           }
         }
-      } catch(error) {
-        console.log(error);
-        return error;
+        folder.push(folderObj);
+      }
+      else {
+        const dataUrl = data['@microsoft.graph.downloadUrl'];
+        const response = await axios.get(dataUrl, {responseType: 'arraybuffer', headers: {
+          withCredentials:true,
+        },});
+
+        files.push({name : data.name, data : response.data, type: data.file.mimeType});
       }
     }
+  }
+  const resultObj = {
+    folder : folder,
+    files : files,
+  };
+  return resultObj;
 }
 
 serverApp.post('/deleteItems', 

+ 1 - 1
src/static/styles/custom.css

@@ -446,7 +446,7 @@ li {
   left: 0;
   position: fixed;
   display: block;
-  opacity: 0.8;
+  opacity: 0.5;
   background: white;
   z-index: 99;
   text-align: center;

+ 163 - 57
src/views/hello.html

@@ -51,10 +51,10 @@
                         <div style="width: 160px;" onclick="openFile(event)">파일</div>
                       </div> 
                     </div>
-                    <input type="file" style="display: none;" id="folder-upload" name="folder" onchange="uploadFolders(event)" webkitdirectory multiple >
-                    <input type="file" style="display: none;" id="file-upload" name="file" onchange="uploadFiles(event)" multiple >
                     <div onclick="refreshDrive()">새로고침</div>
                     <div class="one-drive-button">OneDrive에서 열기</div>
+                    <input type="file" style="display: none;" id="folder-upload" name="folder" onchange="uploadFolders(event)" webkitdirectory multiple >
+                    <input type="file" style="display: none;" id="file-upload" name="file" onchange="uploadFiles(event)" multiple >
                 </div>
                 <div class="panel"></div>
                 <div class="file-title">
@@ -77,6 +77,13 @@
   const groupMap = new Map();
   let _selectedData = [];
   let _listData = [];
+  $(document).ajaxStart(()=>{
+      $('body').append(`<div id="load">
+        <img src="/static/images/Settings.gif" alt="loading">
+      </div>`);
+    }).ajaxStop(()=>{
+      $('#load').remove();
+  });
   $(()=>{
     microsoftTeams.appInitialization.notifySuccess();
     getGroupList();
@@ -87,6 +94,7 @@
     window.addEventListener('click', function() {
       $('.click-menu').css('display', 'none');
     })
+    
 
   });
   function openFolder(event) {
@@ -151,9 +159,9 @@
     _formData.append('siteId', siteId);
     _formData.append('path', sitePath);
           // _formData.getAll()
-    $('body').append(`<div id="load">
-      <img src="/static/images/Settings.gif" alt="loading">
-    </div>`);
+    // $('body').append(`<div id="load">
+    //   <img src="/static/images/Settings.gif" alt="loading">
+    // </div>`);
 
     $.ajax({
       method: 'post',
@@ -162,7 +170,7 @@
       data : _formData,
       url : '/uploadItems',
       success: (res) => {
-        $('#load').remove();
+        // $('#load').remove();
         let str = res.message;
         
         if (res.error) {
@@ -176,7 +184,7 @@
         
       },
       error: (error) => {
-        $('#load').remove();
+        // $('#load').remove();
         alertMessage(alertTitle, error, null);
         // console.log('==============error=============\n');
         // console.log(error);
@@ -226,7 +234,7 @@
           jsonData.value.forEach((obj, idx)=>{
             dragAndDrop();
             let images = "/static/images/";
-            
+            let imageName = "";
 
             let modifyName = "";
             if (obj.lastModifiedBy && obj.lastModifiedBy.user) {
@@ -234,8 +242,10 @@
             }
             if (obj.folder || obj.driveType) {
               images += "folder.png";
+              imageName = "폴더 이미지";
             }
             else if (obj.file && obj.name) {
+              imageName = "파일 이미지";
               let ext = obj.name.substring(obj.name.lastIndexOf('.') + 1);
               let imageExt = ".svg";
               //photo 
@@ -318,8 +328,8 @@
             str += `
               <div id="row_${idx}">
                 <div>
-                  <input type="checkbox" name="row_${idx}" value="${obj.id}" onclick="event.stopPropagation()">
-                  <img src="${images}" width="32" height="32" alt="폴더 이미지">
+                  <input type="checkbox" name="row_${idx}" value="${obj.id}" onchange="checkState(event)" onclick="event.stopPropagation()">
+                  <img src="${images}" width="32" height="32" alt="${imageName}">
                 </div>
                 <div class="file_name"><span class="sp-name" onclick="${method}">${obj.name}</span></div>
                 <div>${amount}</div>
@@ -359,16 +369,35 @@
               }
 
               const {clientX, clientY} = e;
-                const toggleBox = $(`<div class="toggle-box" style="position:absolute; top:${clientY}; left: ${clientX}">
-                    <div>편집</div>
-                    <div>탭으로 설정</div>
-                    <div>다운로드</div>
-                    <div onclick="deleteItem()">삭제</div>
-                    <div>이동</div>
-                    <div>복사</div>
-                    <div onclick="nameChange()">이름 바꾸기</div>
-                  </div>`);
-                  $('body').append(toggleBox);
+              const array = $('.file-content input[type="checkbox"]');
+              let str = `<div>편집</div>
+                  <div>탭으로 설정</div>
+                  <div onclick="download()">다운로드</div>
+                  <div onclick="deleteItem()">삭제</div>
+                  <div>이동</div>
+                  <div>복사</div>
+                  <div onclick="nameChange()">이름 바꾸기</div>`;
+              if (array && array.length > 0) {
+                let checkCnt = 0;
+                for (let ii = 0; ii < array.length; ii++) {
+                  if(array.eq(ii).is(':checked')) {
+                    checkCnt++;
+                  }
+                }
+
+                if (checkCnt > 1) {
+                  str = `<div>편집</div>
+                  <div>탭으로 설정</div>
+                  <div onclick="download()">다운로드</div>
+                  <div onclick="deleteItem()">삭제</div>
+                  <div>이동</div>
+                  <div>복사</div>`;
+                }
+              }
+              const toggleBox = $(`<div class="toggle-box" style="position:absolute; top:${clientY}; left: ${clientX}">
+                  ${str}
+                </div>`);
+                $('body').append(toggleBox);
             }
           });
         }
@@ -407,6 +436,16 @@
         }
     }
 
+    function checkState(event){
+      const $target = $(event.target);
+      const $row = $('#'+$target.attr('name'));
+      let method = 'removeClass';
+      if ($target.is(':checked')) {
+        method = 'addClass';
+      }
+      $row[method]('on');
+    }
+
     //삭제 이벤트
     function deleteItem() {
       const checkArr = $('.file-content input[type="checkbox"]');
@@ -462,6 +501,70 @@
       }
     }
 
+    function getDrivePath() {
+      console.log($('.panel-item'));
+      let path = '/drive/root';
+      if ($('.panel-item').length > 1) {
+        path += ':';
+        for (let ii = 1; ii < $('.panel-item').length; ii++) {
+            path += '/' + $('.panel-item').eq(ii).text();
+        }
+      }
+
+      return path;
+    }
+
+    //다운로드 이벤트
+    function download(){
+      const fileArr = $('.file-content input[type="checkbox"]');
+      if (fileArr || fileArr.length) {
+        const fileIdArr = [];
+        for (let ii = 0; ii < fileArr.length; ii++) {
+            const isChecked = fileArr.eq(ii).is(':checked');
+            if (isChecked) {
+              fileIdArr.push(fileArr.eq(ii).val());
+            }
+        }
+        if (fileIdArr.length === 0) return alertMessage('다운로드', '다운로드 할 파일을 선택해주세요.');
+
+        $.ajax({
+          method: 'post',
+          url : '/api/download',
+          data : {
+            siteId : getSitesId(),
+            path : getDrivePath(),
+            fileIds : JSON.stringify(fileIdArr),
+            zipName : $('.panel-item.on').text().trim(),
+          },
+          success: (res)=>{
+            if (res.success === 'S') {
+              const dataUrl = window.URL.createObjectURL(new Blob([new Uint8Array(res.data.data).buffer]));
+              const link = document.createElement('a');
+              link.href = dataUrl;
+              link.download = res.name;
+              link.style.display = 'none';
+              $('body').append(link);
+              link.click();
+              link.remove();
+            }
+            else {
+              let message = res.message;
+              if (res.error) {
+                console.log(res.error);
+                message += '<br>' + res.error;
+              }
+              alertMessage('다운로드',message);
+            }
+          },
+          error : (error) => {
+            console.log(error);
+          }
+
+          
+        })
+      }
+    }
+
     function drawPath(path, siteId, name) {
       let imgSrc = '';
       let panelStr = '';
@@ -509,10 +612,10 @@
       return panelStr;
     }
 
-    function nameChange() {
-        if ($('.file-content > .on .file_name')[0]) {
-        }
-    }
+    // function nameChange() {
+    //     if ($('.file-content > .on .file_name')[0]) {
+    //     }
+    // }
 
     
     function dragAndDrop() {
@@ -574,10 +677,9 @@
 
           _formData.append('siteId', siteId);
           _formData.append('path', sitePath);
-          // _formData.getAll()
-          $('body').append(`<div id="load">
-            <img src="/static/images/Settings.gif" alt="loading">
-          </div>`)
+          // $('body').append(`<div id="load">
+          //   <img src="/static/images/Settings.gif" alt="loading">
+          // </div>`)
           $.ajax({
             method: 'post',
             processData : false,
@@ -585,7 +687,7 @@
             data : _formData,
             url : '/uploadItems',
             success: (res) => {
-              $('#load').remove();
+              // $('#load').remove();
               let str = res.message;
               if (res.error) {
                 str += '<br>오류 : ' + res.error;
@@ -599,7 +701,7 @@
               
             },
             error: (error) => {
-              $('#load').remove();
+              // $('#load').remove();
               alertMessage(alertTitle, error, null);
               // console.log('==============error=============\n');
               // console.log(error);
@@ -827,6 +929,11 @@
               const $fileContent = $('.file-content');
               const $panel = $('.panel');
               $oneDriveBtn.off('click');
+              let text = name;
+              if (name !== 'One Drive') {
+                text = 'SharePoint'
+              }
+              $oneDriveBtn.text(text+'에서 열기');
               if (jsonData.webUrl){
                 $oneDriveBtn.on('click', ()=>{
                   window.open(jsonData.webUrl);
@@ -928,7 +1035,6 @@
             joinedTeams.teams.forEach((team)=>{
               const items = joinedTeams.items[team.id];
               let siteId = team.sharePoint.siteId;
-              // onclick="siteDriveChildrenItems('${siteId}', '/drive/root', '${team.displayName}', '${siteId}', event)"
               str += `<li id="${siteId}_li">
                         <input type="checkbox" checked="false" id="${siteId}_check" value="${siteId}">
                         <label for="${siteId}_check"><img width="24" height="24" src="${team.sharePoint.siteUrl}${groupImageUrl}" alt="이미지">&nbsp;${team.displayName}</label>
@@ -947,10 +1053,6 @@
             const {teams, items} = oneDrive;
             const sharePoint = teams.sharePoint;
             siteId = sharePoint.siteId;
-              // str += `<div>
-              //           <input type="checkbox" checked="false" id="${siteId}" value="${siteId}" onclick="siteDriveChildrenItems('${siteId}', '/drive/root', 'One Drive', '${siteId}', event)">
-              //           <label for="${siteId}"><img width="24" height="24" src="${sharePoint.siteUrl}${groupImageUrl}" alt="그룹 이미지">&nbsp;One Drive</label>
-              //         </div>`;
               str += `<div id="${siteId}_li" onclick="siteDriveChildrenItems('${siteId}', '/drive/root', 'One Drive', '${siteId}', event)">
                         <img width="24" height="24" src="${sharePoint.siteUrl}${groupImageUrl}" alt="그룹 이미지">&nbsp;One Drive
                       </div>`;
@@ -962,20 +1064,10 @@
                 teams = [teams];
               }
               for (let team of teams) {
-                // const items = sites.items[team.id];
                 let siteId = team.sharePoint.siteId;
                 let path;
                 let imageUrl;
-                  // str += `<li>
-                  //         <input type="checkbox" checked="false" id="${siteId}" value="${siteId}" onclick="siteDriveChildrenItems('${siteId}', '/drive/root', '${team.displayName}', '${siteId}', event)">
-                  //         <label for="${siteId}"><img width="24" height="24" src="${team.sharePoint.siteUrl}${groupImageUrl}" alt="이미지">&nbsp;${team.displayName}</label>
-                  //         <ul>`;
-                  //         if (items && items.length > 0) {
-                  //           items.forEach((item)=>{
-                  //             str +=`<li id="${item.id}" onclick="siteDriveChildrenItems('${siteId}', '/drive/root:/${item.name}', '${team.displayName}', null, event)">${item.name}</li>`
-                  //           })
-                  //         }
-                  // str +=`</ul></li>`;
+                console.log(team.displayName);
                   str += `
                         <div id="${siteId}_li" onclick="siteDriveChildrenItems('${siteId}', '/drive/root', '${team.displayName}', '${siteId}', event)">
                           <img width="24" height="24" src="${team.sharePoint.siteUrl}${groupImageUrl}" alt="그룹 이미지">&nbsp;${team.displayName}
@@ -1010,13 +1102,6 @@
         _selectedData.value.sort(function (a, b){
           return a[type] > b[type] ? first : a[type] === b[type] ? 0 : end;
         });
-
-        if ($('.panel').children().first().text() === 'One Drive') {
-          drawOneDrive(_selectedData);
-        }
-        else {
-
-        }
       }
   }
   $('.tree.group input[type="checkbox"]').on('change', function(event){
@@ -1127,26 +1212,47 @@
     return siteId;
   }
 
-  function changeNames() {
+  function nameChange() {
+    const $checkbox = $('.file-content > div.on input[type="checkbox"]');
+    if ($checkbox.length > 1) return;
+    if (!$('.file-content > div.on .file_name')[0]) return;
+    const siteId = getSitesId();
+    const itemId = $checkbox.val();
+    const name = $('.file-content > div.on .file_name').text();
+    let ext = "";
+    let inputVal = name;
+    let width = '100%';
+    if(name.includes(".")) {
+      inputVal = name.substring(0, name.lastIndexOf("."));
+      ext = name.substring(name.lastIndexOf("."));
+      width = 'calc(100% - 35px)';
+    }
+    callApi('get', "/sites/"+ siteId + "/drive/items/" + itemId, (jsonData)=>{
+      console.log(jsonData);
+    })
+  
     const modalContainer = $(
       `<div class="modal" style="display: flex;">
           <div class="modal-box">
               <div class="header">
                 <div class="title">이름 바꾸기</div>
                 <div class="x-button">
-                  <span><img src="/static/images/x-button.png" width="15" height="15" alt="닫기 버튼"></span>
+                  <span><img src="/static/images/x-button.png" width="15" height="15" alt="닫기 버튼" onclick="$('.modal').remove()"></span>
                 </div>
               </div>
               <div class="modal-content">
                 <div>이름</div>
-                <input type="text" name="file_name" id="" value="">
+                <div style="display:flex; align-items:flex-end;">
+                  <input type="text" style="width:${width};" name="change_name" id="${itemId}" value="${inputVal}">&nbsp;${ext}
+                </div>
               </div>
               <div class="button-box">
                   <div class="name-btn">이름 바꾸기</div>
-                  <div class="name-btn">취소</div>
+                  <div class="cancel-btn" onclick="$('.modal').remove()">취소</div>
               </div>
           </div>
       </div>`);
+      $('body').append(modalContainer);
   }
 
 </script>