Index: openacs-4/packages/ajax-filestorage-ui/www/resources/ajaxfs.js =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ajax-filestorage-ui/www/resources/ajaxfs.js,v diff -u -r1.5 -r1.6 --- openacs-4/packages/ajax-filestorage-ui/www/resources/ajaxfs.js 14 Nov 2007 04:19:54 -0000 1.5 +++ openacs-4/packages/ajax-filestorage-ui/www/resources/ajaxfs.js 26 Nov 2007 12:52:43 -0000 1.6 @@ -1,650 +1,562 @@ /* - Ajax File Storage + Ajax File Storage 1.0 @author Hamilton Chua (ham@solutiongrove.com) - @creation-date 2007-06-03 + @creation-date 2007-11-18 + */ -/********** UTILS *********************/ +/********** AJAXFS Class ***********/ -/* readCookie -read value of a cookie */ -function readCookie(name) { - var ca = document.cookie.split(';'); - var nameEQ = name + "="; - for(var i=0; i < ca.length; i++) { - var c = ca[i]; - while (c.charAt(0)==' ') c = c.substring(1, c.length); //delete spaces - if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length); - } - return null; -} +Ext.namespace('ajaxfs'); +Ext.BLANK_IMAGE_URL = '/resources/ajaxhelper/ext2/resources/images/default/s.gif'; -/* createCookie -used to maintain state, e.g. when login expires */ -function createCookie(name, value, days){ - if (days) { - var date = new Date(); - date.setTime(date.getTime()+(days*24*60*60*1000)); - var expires = "; expires="+date.toGMTString(); - } - else var expires = ""; - document.cookie = name+"="+value+expires+"; path=/"; -} +ajaxfs = function(configObj) { -/* read query string -read the value of a querystring */ -function readQs(q) { - var query = window.location.search.substring(1); - var parms = query.split('&'); - for (var i=0; i 0) { - var key = parms[i].substring(0,pos); - var val = parms[i].substring(pos+1); - if (key == q) { - return val; - } - } - } - return null; -} + // ******** properties ********* -/* check Flash Version */ -function checkFlashVersion() { + // ** configObj ** + // ajaxFs expects a config object that may have the following properites + // - configObj.package_ids : the package_id or a comma separated list of package_ids of the current ajaxFs Instance + // - configObj.initOpenFolder : if this value is not null, it should contain the folder id to open when object is instantiated + // - configObj.layoutdiv : the div container where we put the layout, if none is provided then document.body is used + // - configObj.xmlhttpurl : just in case ajaxfs is mounted elsewhere other than /ajaxfs + // - configObj.createUrl : do we show the createurl button in the toolbar - var x; - var pluginversion; + // ** properties ** - if(navigator.plugins && navigator.mimeTypes.length){ - x = navigator.plugins["Shockwave Flash"]; - if(x && x.description) x = x.description; - } else if (Ext.isIE){ - try { - x = new ActiveXObject("ShockwaveFlash.ShockwaveFlash"); - x = x.GetVariable("$version"); - } catch(e){} - } + // url of xmlhttp files from ajaxfs, defaults to /ajaxfs/xmlhttp + this.xmlhttpurl = '/ajaxfs/xmlhttp/'; - pluginVersion = (typeof(x) == 'string') ? parseInt(x.match(/\d+/)[0]) : 0; + // do we or do we not allow creating url's in fs, defaults to true + this.create_url_p = true; - return pluginVersion; -} + // holds an object with configruation settings for this instance + // of ajaxfs, this variable is set only if configObj exists and is passed + this.config = null; -// check if the string argument is a url -function isURL(argvalue) { + // holds a reference to the layout for the center page + this.layout = null; + + // reference to the tree edito for the treepanel + this.te = null; - if (argvalue.indexOf(" ") != -1) - return false; - else if (argvalue.indexOf("http://") == -1) - return false; - else if (argvalue == "http://") - return false; - else if (argvalue.indexOf("http://") > 0) - return false; + // holds the id of the currently selected node in the tree + this.currentfolder = null; - argvalue = argvalue.substring(7, argvalue.length); - if (argvalue.indexOf(".") == -1) - return false; - else if (argvalue.indexOf(".") == 0) - return false; - else if (argvalue.charAt(argvalue.length - 1) == ".") - return false; + // currently selected tag + this.currenttag = null; - if (argvalue.indexOf("/") != -1) { - argvalue = argvalue.substring(0, argvalue.indexOf("/")); - if (argvalue.charAt(argvalue.length - 1) == ".") - return false; - } + // reusable aync data connection + this.asyncCon = new Ext.data.Connection(); - if (argvalue.indexOf(":") != -1) { - if (argvalue.indexOf(":") == (argvalue.length - 1)) - return false; - else if (argvalue.charAt(argvalue.indexOf(":") + 1) == ".") - return false; - argvalue = argvalue.substring(0, argvalue.indexOf(":")); - if (argvalue.charAt(argvalue.length - 1) == ".") - return false; - } + // reference to messagebox + this.msgbox = Ext.MessageBox; - return true; + // create upload dialog + this.upldWindow = null; -} + // tagdialog + this.tagWindow = null; -/********** FLASH UPLOAD *********/ + // create ur dialog + this.createurlWindow = null; + // reference to contextmenu + this.contextmenu = null; -function FileProgress(fileObj, target_id) { - this.file_progress_id = fileObj.id; + // reference to an instance of the swfuploader + // used for ajaxfs + this.swfu = null; - this.opacity = 100; - this.height = 0; - this.fileProgressWrapper = document.getElementById(this.file_progress_id); - if (!this.fileProgressWrapper) { - this.fileProgressWrapper = document.createElement("div"); - this.fileProgressWrapper.className = "progressWrapper"; - this.fileProgressWrapper.id = this.file_progress_id; + //********* initialize ********* - this.fileProgressElement = document.createElement("div"); - this.fileProgressElement.className = "progressContainer"; + this.initObj = function() { - var progressCancel = document.createElement("a"); - progressCancel.className = "progressCancel"; - progressCancel.href = "#"; - progressCancel.style.visibility = "hidden"; - progressCancel.appendChild(document.createTextNode(" ")); + // check if ExtJs is loaded before anything else - var progressText = document.createElement("div"); - progressText.className = "progressName"; - progressText.appendChild(document.createTextNode(fileObj.name)); + if (typeof(Ext.DomHelper) != "undefined") { - var progressBar = document.createElement("div"); - progressBar.className = "progressBarInProgress"; + // ExtJs is loaded + // check for config + if (configObj) { - var progressStatus = document.createElement("div"); - progressStatus.className = "progressBarStatus"; - progressStatus.innerHTML = " "; + this.config = configObj; + if(this.config.xmlhttpurl) { this.xmlhttpurl = this.config.xmlhttpurl } + if(this.config.create_url && this.config.create_url == 0) { this.create_url_p = false } - this.fileProgressElement.appendChild(progressCancel); - this.fileProgressElement.appendChild(progressText); - this.fileProgressElement.appendChild(progressStatus); - this.fileProgressElement.appendChild(progressBar); + // generic listener to check if + // the connection has returned a login form + // in which case we need to redirect the user + // to a login form + // this listener is activated only if the fs instance + // is not a public instance - this.fileProgressWrapper.appendChild(this.fileProgressElement); + if(!this.config.ispublic) { + Ext.Ajax.on("requestcomplete", this.isSessionExpired, this); + } + + } - document.getElementById(target_id).appendChild(this.fileProgressWrapper); - } else { - this.fileProgressElement = this.fileProgressWrapper.firstChild; - } + // initialize tooltips + Ext.QuickTips.init(); - this.height = this.fileProgressWrapper.offsetHeight; + // setup the layout and panels + this.initLayout(); -} -FileProgress.prototype.SetProgress = function(percentage) { - this.fileProgressElement.className = "progressContainer green"; - this.fileProgressElement.childNodes[3].className = "progressBarInProgress"; - this.fileProgressElement.childNodes[3].style.width = percentage + "%"; -} -FileProgress.prototype.SetComplete = function() { - this.fileProgressElement.className = "progressContainer blue"; - this.fileProgressElement.childNodes[3].className = "progressBarComplete"; - this.fileProgressElement.childNodes[3].style.width = ""; + } - var oSelf = this; - setTimeout(function() { oSelf.Disappear(); }, 10000); -} -FileProgress.prototype.SetError = function() { - this.fileProgressElement.className = "progressContainer red"; - this.fileProgressElement.childNodes[3].className = "progressBarError"; - this.fileProgressElement.childNodes[3].style.width = ""; + } - var oSelf = this; - setTimeout(function() { oSelf.Disappear(); }, 5000); -} -FileProgress.prototype.SetCancelled = function() { - this.fileProgressElement.className = "progressContainer"; - this.fileProgressElement.childNodes[3].className = "progressBarError"; - this.fileProgressElement.childNodes[3].style.width = ""; + Ext.onReady(this.initObj,this,true); - var oSelf = this; - setTimeout(function() { oSelf.Disappear(); }, 2000); } -FileProgress.prototype.SetStatus = function(status) { - this.fileProgressElement.childNodes[2].innerHTML = status; -} -FileProgress.prototype.ToggleCancel = function(show, upload_obj) { - this.fileProgressElement.childNodes[0].style.visibility = show ? "visible" : "hidden"; - if (upload_obj) { - var file_id = this.file_progress_id; - this.fileProgressElement.childNodes[0].onclick = function() { upload_obj.cancelUpload(file_id); return false; }; - } -} +ajaxfs.prototype = { -FileProgress.prototype.Disappear = function() { + // check if login has expired - var reduce_opacity_by = 15; - var reduce_height_by = 4; - var rate = 30; // 15 fps + isSessionExpired : function(conn,response,options) { - if (this.opacity > 0) { - this.opacity -= reduce_opacity_by; - if (this.opacity < 0) this.opacity = 0; - - if (this.fileProgressWrapper.filters) { - try { - this.fileProgressWrapper.filters.item("DXImageTransform.Microsoft.Alpha").opacity = this.opacity; - } catch (e) { - // If it is not set initially, the browser will throw an error. This will set it if it is not set yet. - this.fileProgressWrapper.style.filter = 'progid:DXImageTransform.Microsoft.Alpha(opacity=' + this.opacity + ')'; + // check if we are still logged in + if ( readCookie("ad_user_login") == null ) { + Ext.get(document.body).mask(acs_lang_text.sessionexpired || "Your session has expired. You need to login again.
You will be redirected to a login page shortly"); + var params = ''; + if(this.currentfolder != null) { + var params = "?folder_id="+this.currentfolder; } - } else { - this.fileProgressWrapper.style.opacity = this.opacity / 100; + window.location="/register/?return_url="+this.config.package_url+params; } - } - if (this.height > 0) { - this.height -= reduce_height_by; - if (this.height < 0) this.height = 0; + }, - this.fileProgressWrapper.style.height = this.height + "px"; - } + // recursive expand in case folder id is not on the first level + asyncExpand : function(x) { + var treepanel = this.layout.findById('treepanel'); + var node = treepanel.getNodeById(this.config.initOpenFolder); + if(!node) { + var x = x+1; + var nextnodeid = this.config.pathToFolder[x]; + var nextnode = treepanel.getNodeById(nextnodeid); + nextnode.on("expand",asyncExpand.createDelegate(this,[x]), this, {single:true}); + nextnode.expand(true); + } else { + node.select() + node.fireEvent("click",node); + } + }, - if (this.height > 0 || this.opacity > 0) { - var oSelf = this; - setTimeout(function() { oSelf.Disappear(); }, rate); - } else { - this.fileProgressWrapper.style.display = "none"; - } -} + // if we get an initOpenFolder config, + // expand the provided initOpenFolder id + selectInitFolder : function() { + var treepanel = this.layout.findById('treepanel'); + if(this.config.initOpenFolder) { + var initNode = treepanel.getNodeById(this.config.initOpenFolder); + if(initNode) { + initNode.expand(); + initNode.fireEvent("click",initNode) + } else { + // recursively expand based on the list of folder_ids in pathToFolder + var x = 1; + var nextnode = treepanel.getNodeById(this.config.pathToFolder[x]); + nextnode.on("expand",this.asyncExpand.createDelegate(this,[x]), this, {single:true}); + nextnode.expand(true); + } + } else { + treepanel.fireEvent("click",treepanel.getRootNode()); + } + }, -function uploadStart(fileObj,ajaxfsobj) { - var upload_txt = acs_lang_text.for_upload_to || "for upload to"; - var zip_txt = acs_lang_text.zip_extracted || "Zip File (Will be extracted after upload)"; - try { - // You might include code here that prevents the form from being submitted while the upload is in - // progress. Then you'll want to put code in the Queue Complete handler to "unblock" the form - var folderid = ajaxfsobj.currentfolder; - var foldername = ajaxfsobj.treepanel.getNodeById(folderid).text; - var progress = new FileProgress(fileObj, this.getSetting("progress_target")); - progress.SetStatus( upload_txt + ""+foldername+"
Title: (optional)
"+ zip_txt); - progress.ToggleCancel(true, this); - this.addFileParam(fileObj.id, "folder_id", folderid); - ajaxfsobj.upldDialog.buttons[0].enable(); - } catch (ex) { this.debugMessage(ex); } -} + // creates the main layout for ajaxfs -function uploadProgress(fileObj, bytesLoaded) { - try { - var percent = Math.ceil((bytesLoaded / fileObj.size) * 100) - var progress = new FileProgress(fileObj, this.getSetting("progress_target")); - progress.SetProgress(percent); - progress.SetStatus(acs_lang_text.uploading || "Uploading..."); - } catch (ex) { this.debugMessage(ex); } -} + initLayout : function() { -function uploadFileComplete(fileObj) { - try { - var progress = new FileProgress(fileObj, this.getSetting("progress_target")); - progress.SetComplete(); - progress.SetStatus(acs_lang_text.complete || "Complete."); - progress.ToggleCancel(false); + /* Load the UI in document.body if a layoutdiv is not provided */ - } catch (ex) { this.debugMessage(ex); } -} + var layoutitems = [this.createLeft(),this.createRight()] -function uploadComplete(fileObj) { - try { - var progress = new FileProgress(fileObj, this.getSetting("progress_target")); - progress.SetComplete(); - progress.SetStatus(acs_lang_text.complete || "Complete."); - progress.ToggleCancel(false); + if (this.config != null && this.config.layoutdiv) { - } catch (ex) { this.debugMessage(ex); } -} + this.layout = new Ext.Panel({ + id:"fs-ui", + layout:'border', + applyTo:this.config.layoutdiv, + tbar:this.createToolbar(), + items: layoutitems + }) -function uploadQueueComplete(fileidx,ajaxfsobj) { - ajaxfsobj.upldDialog.buttons[0].disable(); - var currentTreeNode = ajaxfsobj.treepanel.getNodeById(ajaxfsobj.currentfolder); - currentTreeNode.fireEvent("click",currentTreeNode); -} + } else { -function uploadError(error_code, fileObj, message) { - try { - if (error_code == SWFUpload.ERROR_CODE_QUEUE_LIMIT_EXCEEDED) { - Ext.Msg.alert(acs_lang_text.alert || "Alert","You have attempted to queue too many files.\n" + (message == 0 ? "You have reached the upload limit." : "You may select " + (message > 1 ? "up to " + message + " files." : "one file."))); - return; + this.layout = new Ext.Viewport({ + id:"fs-ui", + layout:'border', + tbar:this.createToolbar(), + items: layoutitems + }); + } - var progress = new FileProgress(fileObj, this.getSetting("progress_target")); - progress.SetError(); - progress.ToggleCancel(false); + }, - switch(error_code) { - case SWFUpload.ERROR_CODE_HTTP_ERROR: - progress.SetStatus("Upload Error"); - this.debugMessage("Error Code: HTTP Error, File name: " + file.name + ", Message: " + message); - break; - case SWFUpload.ERROR_CODE_MISSING_UPLOAD_TARGET: - progress.SetStatus("Configuration Error"); - this.debugMessage("Error Code: No backend file, File name: " + file.name + ", Message: " + message); - break; - case SWFUpload.ERROR_CODE_UPLOAD_FAILED: - progress.SetStatus("Upload Failed."); - this.debugMessage("Error Code: Upload Failed, File name: " + file.name + ", File size: " + file.size + ", Message: " + message); - break; - case SWFUpload.ERROR_CODE_IO_ERROR: - progress.SetStatus("Server (IO) Error"); - this.debugMessage("Error Code: IO Error, File name: " + file.name + ", Message: " + message); - break; - case SWFUpload.ERROR_CODE_SECURITY_ERROR: - progress.SetStatus("Security Error"); - this.debugMessage("Error Code: Security Error, File name: " + file.name + ", Message: " + message); - break; - case SWFUpload.ERROR_CODE_FILE_EXCEEDS_SIZE_LIMIT: - progress.SetStatus("File is too big."); - this.debugMessage("Error Code: File too big, File name: " + file.name + ", File size: " + file.size + ", Message: " + message); - break; - case SWFUpload.ERROR_CODE_ZERO_BYTE_FILE: - progress.SetStatus("Cannot upload Zero Byte files."); - this.debugMessage("Error Code: Zero byte file, File name: " + file.name + ", File size: " + file.size + ", Message: " + message); - break; - case SWFUpload.ERROR_CODE_UPLOAD_LIMIT_EXCEEDED: - progress.SetStatus("Upload limit exceeded."); - this.debugMessage("Error Code: Upload Limit Exceeded, File name: " + file.name + ", File size: " + file.size + ", Message: " + message); - break; - default: - progress.SetStatus("Unhandled Error"); - this.debugMessage("Error Code: " + error_code + ", File name: " + file.name + ", File size: " + file.size + ", Message: " + message); - break; + // create the toolbar for this instance of ajaxfs + + createToolbar : function() { + var rootnode = this.config.treerootnode; + var toolbar = []; + if(rootnode.attributes["write_p"] == 't') { + var toolbar = [ + ' ', + {text: acs_lang_text.newfolder || 'New Folder', tooltip: acs_lang_text.newfolder || 'New Folder', icon: '/resources/ajaxhelper/icons/folder_add.png', cls : 'x-btn-text-icon', handler: this.addFolder.createDelegate(this)}, + {text: acs_lang_text.uploadfile || 'Upload Files', tooltip: acs_lang_text.uploadfile || 'Upload Files', icon: '/resources/ajaxhelper/icons/page_add.png', cls : 'x-btn-text-icon', handler: this.addFile.createDelegate(this)} + ]; + if(this.create_url_p) { + toolbar.push({text: acs_lang_text.createurl || 'Create Url',tooltip: acs_lang_text.createurl || 'Create Url', icon: '/resources/ajaxhelper/icons/page_link.png', cls : 'x-btn-text-icon', handler: this.addUrl.createDelegate(this)}); + } + toolbar.push({text: acs_lang_text.deletefs || 'Delete', tooltip: acs_lang_text.deletefs || 'Delete', icon: '/resources/ajaxhelper/icons/delete.png', cls : 'x-btn-text-icon', handler: this.delItem.createDelegate(this)}); + toolbar.push('->'); } - } catch (ex) { - this.debugMessage(ex); - } -} + toolbar.push({tooltip: 'This may take a few minutes if you have a lot of files', text: acs_lang_text.download_archive || 'Download Archive', icon: '/resources/ajaxhelper/icons/arrow_down.png', cls : 'x-btn-text-icon', handler: this.downloadArchive.createDelegate(this,[rootnode.id],false)}); + return toolbar; + }, -function uploadCancel(fileObj) { - try { - var progress = new FileProgress(fileObj, this.getSetting("progress_target")); - progress.SetCancelled(); - progress.SetStatus(acs_lang_text.uploadcancel || "Cancelled (This item will be removed shortly)"); - progress.ToggleCancel(false); + // creates the left panel as an accordon, top panel has the folders, bottom panel has the tags - } - catch (ex) { - this.debugMessage(ex); - } -} + createLeft : function() { + var panel = new Ext.Panel ({ + id:'leftpanel', + region:'west', + collapsible:true, + titlebar:true, + title:' ', + layout:'accordion', + split:true, + width:300, + items:[this.createTreePanel(),this.createTagPanel()] + }); + return panel; + }, -/********** AjaxFS Objects ***********/ + // creates the right panel which lists the files inside a folder -function ajaxfs(configObj) { + createTreePanel : function() { - // ** configObj ** - // ajaxFs expects a config object that may have the following properites - // configObj.package_ids : the package_id or a comma separated list of package_ids of the current ajaxFs Instance - // configObj.initOpenFolder : if this value is not null, it should contain the folder id to open when object is instantiated - // configOjb.layoutdiv : the div container where we put the layout, if none is provided then document.body is used + // build the tree - // ** properties ** + var rootnode = new Ext.tree.AsyncTreeNode({ + text: this.config.treerootnode.text, + draggable:false, + id:this.config.treerootnode.id, + singeClickExpand: true, + expanded:true, + attributes: this.config.treerootnode.attributes + }); - // where to get + var loader = new Ext.tree.TreeLoader({ + dataUrl:this.xmlhttpurl+'load-treenodes', + baseParams: { package_id:this.config.package_id } + }); - // url of xmlhttp files from ajaxfs - this.xmlhttpurl = '/ajaxfs2/xmlhttp/'; + var treepanel = new Ext.tree.TreePanel({ + id:'treepanel', + title:'Folders', + autoScroll:true, + animate:true, + enableDrag:false, + enableDrop:true, + loadMask:true, + loader: loader, + root: rootnode, + ddAppendOnly: true, + containerScroll: true, + dropConfig: { + dropAllowed: true, + ddGroup:'fileDD', + onNodeOver : function(treenode,source,e,data) { - // holds an object with configruation settings for this instance - // of ajaxfs, this variable is set only if configObj exists and is passed - this.config = null; + // DO NOT ALLOW DROP TO CURRENT FOLDER + // check if the id of target node to be dropped + // is the same as the currently selected tree node + if (treenode.node.id == treenode.node.ownerTree.getSelectionModel().getSelectedNode().id) { + return false; + } - // holds a reference to the layout for the center page - this.layout = null; + // DO NOT ALLOW TO DROP A FOLDER TO ITSELF IN THE TREE + // check if the id of any of the nodes to be dropped + // is the same as the id on the tree + if(source.dragData.selections) { + for (var x=0; x"+err_msg_txt2); + } + } + + Ext.Ajax.request({ + url:this.xmlhttpurl+"move-fsitem", + success: moveSuccess, failure: function() { + // ajax failed, revert value + Ext.Msg.alert(acs_lang_text.error || "Error",err_msg_txt+"
"+err_msg_txt2); + }, params: { folder_target_id:folder_target_id,file_ids:file_ids } + }); - // currently selected tag - this.currenttag = null; + return true; - // reusable aync data connection - this.asyncCon = new Ext.data.Connection(); + }.createDelegate(this) + } + }); - // reference to messagebox - this.msgbox = Ext.MessageBox; + // ** allow renaming folders on tree ** - // create upload dialog - this.upldDialog = null; + this.enableTreeFolderRename(treepanel); - // create ur dialog - this.createurlDialog = null; + // ** listeners ** - // permissions dialog - this.permsDialog = null; + rootnode.on("expand",this.selectInitFolder,this,{single:true}); - /// revisions dialog - this.revisionsDialog = null; + treepanel.on("click",this.loadFoldercontents,this); - // reference to contextmenu - this.contextmenu = null; + return treepanel; + }, - // reference to an instance of the swfuploader - // used for ajaxfs - this.swfu = null; + // enable renaming of tree folder + enableTreeFolderRename : function(treepanel) { - // ** methods ** + // ** create editor *** - // check if the string has the login form - // redirects to login form if true, does nothing if not - this.isSessionExpired = function() { - // check if the string has method="post" name="login" - if ( readCookie("ad_user_login") == null ) { - Ext.get(document.body).mask(acs_lang_text.sessionexpired || "Your session has expired. You need to login again.
You will be redirected to a login page shortly"); - var params = "package_id="+this.config.package_id; - if(this.currentfolder != null) { - params = params + "&folder_id="+this.currentfolder; - } - window.location="/register/?return_url="+window.location; - return 1 - } - return 0 - } + this.te = new Ext.tree.TreeEditor(treepanel, { + allowBlank:false, + blankText: acs_lang_text.folder_name_required || 'A folder name is required', + editDelay:20, + ignoreNoChange:true + }); - // check the permissions, returns either true or false - this.isPermitted = function(objid,perm) { - - var callback = function(option,success,response) { - if(success) { - return response.responseText; + // ** listeners ** + + // check if user has premission to rename + // permissions are checked again on the server when request is submitted + this.te.on("beforestartedit", function(node,el,oldname) { + if (node.editNode.attributes.attributes.write_p == "t") { + return true; } else { - return 0; + Ext.Msg.alert(acs_lang_text.permission_denied || "Permission Denied", acs_lang_text.permission_denied || "Sorry, you do not have permission to rename this folder"); + return false; } - } + }, this, true); - this.asyncCon.request({url:this.xmlhttpurl+"checkperms", - params: "object_id="+objid+"&perm="+perm, - method:"POST", - callback: callback, - scope: this - }); + // reject if the folder name is already being used by a sibling + this.te.on("beforecomplete",function(node,newval,oldval) { + var parent = node.editNode.parentNode; + if(parent) { + var children = parent.childNodes; + for(x=0;x
"+resultObj.error+"

"+err_msg_txt2); + node.editNode.setText(oldval); + } + }, failure: function() { + // ajax failed, revert value + Ext.Msg.alert(acs_lang_text.error || "Error",err_msg_txt+"
"+err_msg_txt2); + node.editNode.setText(oldval); + }, params: { newname:newval, object_id:node.editNode.id, type:"folder" } }); - var prompt_text_el = YAHOO.util.Dom.getElementsByClassName('ext-mb-input', 'input','x-msg-box'); - prompt_text_el[0].select(); - } - } + + }, this, true); - // rename a file or folder in the right panel - this.fileRename = function() { + }, - var node = this.filegrid.getSelectionModel().getSelected(); - var nodeurl = node.get("url"); - var nodetype = node.get("type"); - var nodeid = node.get("id"); - var nodesubtitle = node.get("filename"); + // creates the right panel which lists the files inside a folder - var handleRename = function(btn, text) { - if(btn=='ok') { - if(text != '') { - if(text.length > 100) { - Ext.Msg.alert(acs_lang_text.alert || "Alert",acs_lang_text.limitto100 || "Please limit your name to 100 characters or less."); - return false; - } else { - var callback = function(option,success,response) { - var err_msg_txt = acs_lang_text.an_error_occurred || "An error occurred"; - var err_msg_txt2 = acs_lang_text.reverted || "Your changes have been reverted"; - if (success) { - if (response.responseText != 1) { - Ext.Msg.alert(acs_lang_text.error || "Error",err_msg_txt + ":

"+response.responseText+"

"+err_msg_txt2); - } else { - if(nodetype!="folder"&&nodesubtitle===" ") { - nodesubtitle = node.get("title"); - node.set("filename",nodesubtitle); - } - if(nodetype=="folder") { this.treepanel.getNodeById(nodeid).setText(text) } - nodetags = node.get("tags"); - if(nodetags != "") { - var taghtml = "
Tags:
"+nodetags+"
"; - } else { - var taghtml = "
";; - } - node.set("title",text); - node.set("title_and_name",""+text+"
"+nodesubtitle+""+taghtml) - node.commit(); - } - } else { - Ext.Msg.alert(acs_lang_text.error || "Error",err_msg_txt+":

"+response.responseText+"

"+err_msg_txt2); - } - } - - this.asyncCon.request({url:this.xmlhttpurl+"editname", - params: "newname="+text+"&object_id="+nodeid+"&type="+nodetype+"&url="+nodeurl, - method:"POST", - callback: callback, - scope: this - }); - } - } else { - Ext.Msg.alert(acs_lang_text.alert || "Alert",acs_lang_text.enter_new_name || "Please enter a new name."); - return false; + createTagPanel : function() { + + var panel = new Ext.Panel({ + id:'tagcloudpanel', + title:'Tags', + frame:false, + loadMask:true, + autoLoad:{url:this.xmlhttpurl+'get-tagcloud',params:{package_id:this.config.package_id}} + }); + + var listenTagClick = function() { + + var ajaxfsObj = this; + var currenttag = ajaxfsObj.currenttag; + + panel.body.on("click",function(obj,el) { + if(el.tagName == "A") { + if (currenttag != null) { Ext.get(currenttag).setStyle('font-weight','normal') } + Ext.get(el).setStyle('font-weight','bold'); + currenttag = el.id; + this.loadTaggedFiles(el.id); } - } + },this); + } - // Ext.MessageBox.prompt('Rename', 'Please enter a new name for
'+view.jsonData[node.nodeIndex].title+':', handleRename.createDelegate(this)); - Ext.Msg.show({ - title: acs_lang_text.rename || 'Rename', - prompt: true, - msg: acs_lang_text.enter_new_name || 'Please enter a new name for ... ', - value: node.get("title"), - buttons: Ext.Msg.OKCANCEL, - fn: handleRename.createDelegate(this) - }); - var prompt_text_el = YAHOO.util.Dom.getElementsByClassName('ext-mb-input', 'input','x-msg-box'); - prompt_text_el[0].select(); - } + panel.on("render", listenTagClick,this); - // permissions dialog - this.permsRedirect = function() { - var node = this.filegrid.getSelectionModel().getSelected(); - var object_id = node.get("id"); - var newwindow = window.open(window.location.protocol+"//"+window.location.hostname+":"+window.location.port+this.config.package_url+"permissions?object_id="+object_id+"&return_url="+window.location.pathname+"?package_id="+this.config.package_id+"&folder_id="+this.currentfolder); - newwindow.focus(); - } + return panel; + }, - // redirect to file properties - this.propertiesRedirect = function() { - var node = this.filegrid.getSelectionModel().getSelected(); - var object_id = node.get("id"); - var newwindow = window.open(window.location.protocol+"//"+window.location.hostname+":"+window.location.port+this.config.package_url+"file?file_id="+object_id); - newwindow.focus(); - } + // loads the objects associted with a tag + loadTaggedFiles : function (tagid) { - // redirect to object views for a file - this.viewsRedirect = function() { - var node = this.filegrid.getSelectionModel().getSelected(); - var object_id = node.get("id"); - window.open(window.location.protocol+"//"+window.location.hostname+"/o/"+object_id+"/info"); - window.focus(); - } + this.layout.findById("treepanel").getSelectionModel().clearSelections(); + var id = tagid.substring(3,tagid.length); + this.layout.findById("filepanel").store.baseParams['tag_id'] = id; + this.layout.findById("filepanel").store.load(); + this.layout.findById("filepanel").store.baseParams['tag_id'] = ''; + }, - // prompt to enter a tag for the selected fs element - this.promptTag = function() { - var ajaxfsobj = this; - var node = ajaxfsobj.filegrid.getSelectionModel().getSelected(); - var object_id = node.get("id"); + // creates the right panel which lists the files inside a folder + createRight : function() { - Ext.Msg.prompt('Tag', 'Enter or edit one or more tags. Seperate tags with commas (,):', function(btn, text) { - if (btn == 'ok') { - // process text value ... - var callback = function(option,success,response) { - if(success) { - node.set('tags',text); - Ext.get("tagscontainer_"+object_id).update("Tag:"+text+""); - this.tagcloudpanel.load("/ajaxfs2/xmlhttp/tagcloud?package_id="+this.config.package_id); + var cols = [{header: "", width: 30,sortable: true, dataIndex: 'icon'}, + {header: acs_lang_text.filename || "Filename", id:'filename', sortable: true, dataIndex: 'title'}, + {header: acs_lang_text.size || "Size", sortable: true, dataIndex: 'size'}, + {header: acs_lang_text.lastmodified || "Last Modified", sortable: true, dataIndex: 'lastmodified'}]; + + var reader = new Ext.data.JsonReader( + {totalProperty: 'total', root: 'foldercontents', id: 'id'}, [ + {name:'id', type: 'int'}, + {name:'icon'}, + {name:'title'}, + {name:'filename'}, + {name:'type'}, + {name:'tags'}, + {name:'url'}, + {name:'write_p'}, + {name:'size'}, + {name:'lastmodified'}] ); + + + var proxy = new Ext.data.HttpProxy( { + url : this.xmlhttpurl+ 'get-foldercontents' + } ); + + + var colModel = new Ext.grid.ColumnModel(cols); + + var dataModel = new Ext.data.Store({proxy: proxy, reader: reader, remoteSort: true}); + + var gridpanel = new Ext.grid.GridPanel( { + store: dataModel, + cm: colModel, + id:'filepanel', + ddGroup:'fileDD', + region:'center', + split:true, + autoScroll:true, + autoExpandColumn:'filename', + collapsible:true, + enableDragDrop:true, + width:250, + loadMask:true, + frame:false, + viewConfig: { + forceFit: false, + enableRowBody:true, + showPreview:true, + getRowClass: function(record,rowIndex,p,ds) { + var xf = Ext.util.Format; + if (record.data.tags!= "") { + p.body = "
Tags: " + xf.ellipsis(xf.stripTags(record.data.tags), 200) + "
"; + } else { + p.body = "
"; } + return 'x-grid3-row-expanded'; } - ajaxfsobj.asyncCon.request({url:ajaxfsobj.xmlhttpurl+"addtag", - params: "object_id="+object_id+"&tags="+text+"&package_id="+ajaxfsobj.config.package_id, - method:"POST", - callback: callback, - scope: ajaxfsobj - }); } }); - if (document.getElementById("tagslist_"+object_id)) { - var prompt_text_el = YAHOO.util.Dom.getElementsByClassName('ext-mb-input', 'input','x-msg-box'); - prompt_text_el[0].value=document.getElementById("tagslist_"+object_id).innerHTML; - prompt_text_el[0].select(); - } + // listeners - } + gridpanel.on("rowdblclick",this.openItem,this,true); - // download archive function - this.downloadArchive = function() { - var node = this.filegrid.getSelectionModel().getSelected(); - var object_id = node.get("id"); - top.location.href="download-archive/?object_id="+object_id; - } + gridpanel.on("rowcontextmenu",this.showRowContext,this,true); - // generate a context bar - this.showContext = function(grid,i,e) { + return gridpanel; + }, + + // generate the contextbar for the file panel + showRowContext : function(grid,i,e) { + e.stopEvent(); - var dm = grid.getDataSource(); + var dm = grid.store; var record = dm.getAt(i); var object_type = record.get("type"); var recordid = record.get("id"); @@ -661,48 +573,48 @@ items: [ new Ext.menu.Item({ text: openitem_txt, - icon: "/resources/ajax-filestorage-ui/icons/page_white.png", - handler: this.itemDblClick.createDelegate(this,[grid, i, e],false) + icon: '/resources/ajaxhelper/icons/page_white.png', + handler: this.openItem.createDelegate(this,[grid, i, e],false) }), new Ext.menu.Item({ text: 'Tag', - icon: '/resources/ajax-filestorage-ui/icons/tag_blue.png', - handler: this.promptTag.createDelegate(this) + icon: '/resources/ajaxhelper/icons/tag_blue.png', + handler: this.tagFsitem.createDelegate(this,[grid, i, e],false) }), new Ext.menu.Item({ text: 'Views', - icon: '/resources/ajax-filestorage-ui/icons/camera.png', - handler: this.viewsRedirect.createDelegate(this) + icon: '/resources/ajaxhelper/icons/camera.png', + handler: this.redirectViews.createDelegate(this,[grid, i, e],false) }), new Ext.menu.Item({ text: acs_lang_text.deletefs || 'Delete', - icon: '/resources/ajax-filestorage-ui/icons/delete.png', - handler: this.confirmDel.createDelegate(this) + icon: '/resources/ajaxhelper/icons/delete.png', + handler: this.delItem.createDelegate(this,[grid,i,e],false) }), new Ext.menu.Item({ text: acs_lang_text.rename || 'Rename', - icon: '/resources/ajax-filestorage-ui/icons/page_edit.png', - handler: this.fileRename.createDelegate(this) + icon: '/resources/ajaxhelper/icons/page_edit.png', + handler: this.renameItem.createDelegate(this,[grid,i,e],false) }), new Ext.menu.Item({ text: acs_lang_text.linkaddress || 'Copy Link Address', - icon: '/resources/ajax-filestorage-ui/icons/page_copy.png', - handler: this.linkCopy.createDelegate(this) + icon: '/resources/ajaxhelper/icons/page_copy.png', + handler: this.copyLink.createDelegate(this,[grid,i,e],false) }), new Ext.menu.Item({ text: acs_lang_text.permissions || 'Permissions', - icon: '/resources/ajax-filestorage-ui/icons/group_key.png', - handler: this.permsRedirect.createDelegate(this) + icon: '/resources/ajaxhelper/icons/group_key.png', + handler: this.redirectPerms.createDelegate(this,[grid, i, e],false) }), new Ext.menu.Item({ text: acs_lang_text.properties || 'Properties', - icon: '/resources/ajax-filestorage-ui/icons/page_edit.png', - handler: this.propertiesRedirect.createDelegate(this) + icon: '/resources/ajaxhelper/icons/page_edit.png', + handler: this.redirectProperties.createDelegate(this,[grid, i, e],false) }), new Ext.menu.Item({ text: acs_lang_text.download_archive || 'Download archive', - icon: '/resources/ajax-filestorage-ui/icons/arrow_down.png', - handler: this.downloadArchive.createDelegate(this) + icon: '/resources/ajaxhelper/icons/arrow_down.png', + handler: this.downloadArchive.createDelegate(this,[recordid],false) }) ] }); @@ -734,155 +646,84 @@ this.contextmenu.items.items[8].hide(); } } - + var coords = e.getXY(); this.contextmenu.rowid = i; this.contextmenu.showAt([coords[0], coords[1]]); - } - // handle file upload - this.uploadFile = function(e) { + }, - if(document.getElementById("upload_file").value != "" && document.getElementById("filetitle").value != "") { + // load content of folder in file pane + // called from treepanel listener - var callback = { - success: function() { - }, upload: function() { - this.treepanel.getSelectionModel().getSelectedNode().loaded=false; - this.treepanel.getSelectionModel().getSelectedNode().fireEvent("click",this.treepanel.getSelectionModel().getSelectedNode()); - this.upldDialog.getEl().unmask(); - this.upldDialog.hide(); - }, failure: function() { - Ext.Msg.alert(acs_lang_text.error || "Error", acs_lang_text.upload_failed || "Upload failed, please try again later."); - }, scope: this - } + loadFoldercontents : function(node, e) { - var loading_msg = acs_lang_text.loading || "One moment. This may take a while depending on how large your upload is." - this.upldDialog.getEl().mask(" "+loading_msg); + // currently selected folder + this.currentfolder = node.id; - YAHOO.util.Connect.setForm("newfileform", true, true); + // get filepanel + var gridpanel = this.layout.findById('filepanel'); - var cObj = YAHOO.util.Connect.asyncRequest("POST", this.xmlhttpurl+"file-add", callback); - - } else { + // fetch the folder contents - Ext.Msg.alert(acs_lang_text.alert || "Alert", acs_lang_text.file_required || "Title and File to upload are required."); + gridpanel.store.baseParams['folder_id'] = node.id; + // gridpanel.store.baseParams['tag_id'] = ''; + // if the tree node is still loading, wait for it to expand before loading the grid + if(node.loading) { + node.on("expand", function() { this.store.load() }, gridpanel, {single:true}); + } else{ + gridpanel.store.load(); } - } + }, - // create the url - this.createUrl = function(e) { - if(document.getElementById("fsurl").value != "" && document.getElementById("fstitle").value != "") { - if (isURL(document.getElementById("fsurl").value)) { - var callback = { - success: function() { - this.treepanel.getSelectionModel().getSelectedNode().loaded=false; - this.treepanel.getSelectionModel().getSelectedNode().fireEvent("click",this.treepanel.getSelectionModel().getSelectedNode()); - this.createurlDialog.getEl().unmask(); - this.createurlDialog.hide(); - },failure: function() { - this.createurlDialog.getEl().unmask(); - Ext.Msg.alert(acs_lang_text.error || "Error",acs_lang_text.createurl_failed || "Create URL failed, please try again later."); - }, scope: this - } - - this.createurlDialog.getEl().mask(" One moment."); - - YAHOO.util.Connect.setForm("simple-add"); - - var cObj = YAHOO.util.Connect.asyncRequest("POST", this.xmlhttpurl+"url-add", callback); - } else { - Ext.Msg.alert(acs_lang_text.alert || "Alert", acs_lang_text.invalid_url || "URL is not a valid url."); - } - } else { + // executes an action depending on the type of fs item + // - folders : open the folder in the tree + // - file : download the file + // - url : open the url in a new window + openItem : function(grid,i,e) { - Ext.Msg.alert(acs_lang_text.alert || "Alert", acs_lang_text.invalid_url || "Title and URL are required."); - + var treepanel = this.layout.findById('treepanel'); + var dm = grid.store; + var record = dm.getAt(i); + if(record.get("type") == "folder") { + var node = treepanel.getNodeById(record.get("id")); + if(!node.parentNode.isExpanded()) { node.parentNode.expand() } + node.fireEvent("click",node); + node.expand(); + } else { + // this is a file, let the user download + window.open(record.get("url")); + window.focus(); } - } - // shows the create url dialog - this.showCreateUrldialog = function() { - if(!this.createurlDialog.buttons) { - this.createurlDialog.addButton({text:acs_lang_text.ok || 'Ok',icon:"/resources/ajax-filestorage-ui/icons/page_add.png",cls:"x-btn-text-icon"}, this.createUrl, this); - this.createurlDialog.addButton({text:acs_lang_text.cancel ||'Cancel',icon:"/resources/ajax-filestorage-ui/icons/cancel.png",cls:"x-btn-text-icon"}, this.createurlDialog.hide, this.createurlDialog); - } - this.createurlDialog.setTitle(acs_lang_text.createurl || "Create URL"); - this.createurlDialog.body.update("

Title


URL


Description :

"); - this.createurlDialog.body.setStyle("font","normal 12px tahoma, arial, helvetica, sans-serif"); - this.createurlDialog.body.setStyle("background-color","#ffffff"); - this.createurlDialog.body.setStyle("border","1px solid #e2e2e2"); - this.createurlDialog.body.setStyle("padding","3px"); - this.createurlDialog.show(); - } + }, - // shows the upload dialog, - // check if user has flash 8 or higher - // creates the upload form or - // shows the flash upload dialog - this.showUplddialog = function() { - this.upldDialog.setTitle(acs_lang_text.uploadfile || "Upload Files"); - if(checkFlashVersion() < 8) { - var msg1=acs_lang_text.file_to_upload || "File to upload"; - var msg2=acs_lang_text.file_title || "Title"; - var msg3=acs_lang_text.file_description || "Description"; - var msg4=acs_lang_text.multiple_files || "Multiple Files"; - var msg5=acs_lang_text.multiple_files_msg || "This is a ZIPfile containing multiple files."; - this.upldDialog.body.update("

"+msg1+"


"+msg2+"


"+msg3+" :

"+msg4+" :

"+msg5+"

"); - if(!this.upldDialog.buttons) { - this.upldDialog.addButton({text:acs_lang_text.upload || 'Upload',icon:"/resources/ajax-filestorage-ui/icons/page_add.png",cls:"x-btn-text-icon"}, this.uploadFile, this); - this.upldDialog.addButton({text:acs_lang_text.cancel || 'Cancel',icon:"/resources/ajax-filestorage-ui/icons/cancel.png",cls:"x-btn-text-icon"}, this.upldDialog.hide, this.upldDialog); + // deletes an fs item (folder, file or url) + delItem : function(grid,i,e) { + + var err_msg_txt = acs_lang_text.confirm_delete || "Are you sure you want to delete "; + var err_msg_txt2 = acs_lang_text.foldercontains || "This folder contains"; + var treepanel = this.layout.findById('treepanel'); + if(grid.id=="filepanel") { + var filepanel = grid; + if(filepanel.getSelectionModel().getCount()<=1) { + filepanel.getSelectionModel().selectRow(i); } - } else { - if(this.swfu == null) { - var err_msg_txt = acs_lang_text.upload_intro || "Click Browse to select a file to upload to the selected folder."; - this.upldDialog.body.update("
"+err_msg_txt+"
"); - var package_id = String(this.config.package_id); - var user_id = String(this.config.user_id); - var folder_id = String(this.currentfolder); - var max_file_size = String(this.config.max_file_size) || 5000000; - this.swfu = new SWFUpload({ - debug: false, - upload_target_url: "/ajaxfs2/xmlhttp/file-add-flash", - upload_params: {user_id:user_id,package_id:package_id}, - file_types : "*.*", - file_size_limit : max_file_size, - file_queue_limit : 3, - begin_upload_on_queue: false, - file_progress_handler : uploadProgress, - file_cancelled_handler : uploadCancel, - file_complete_handler : uploadComplete, - queue_complete_handler : uploadQueueComplete, - error_handler : uploadError, - flash_url : "/resources/ajax-filestorage-ui/swfupload/swfupload.swf" - }); - this.swfu.fileQueued = uploadStart.createDelegate(this.swfu,[this],true); - this.swfu.fileProgress = uploadProgress.createDelegate(this.swfu,[this],true); - this.swfu.fileComplete = uploadComplete.createDelegate(this.swfu,[this],true); - this.swfu.fileCancelled = uploadCancel.createDelegate(this.swfu,[this],true); - this.swfu.queueComplete = uploadQueueComplete.createDelegate(this.swfu,[this],true); - this.swfu.addSetting("progress_target", "fsuploadprogress"); - this.upldDialog.addButton({text:acs_lang_text.upload || 'Upload',disabled:true,icon:"/resources/ajax-filestorage-ui/icons/arrow_up.png",cls:"x-btn-text-icon"}, this.swfu.startUpload.createDelegate(this.swfu,[null,this],false), this); - this.upldDialog.addButton({text:acs_lang_text.browse || 'Browse',icon:"/resources/ajax-filestorage-ui/icons/page_add.png",cls:"x-btn-text-icon"}, this.swfu.browse, this.swfu); - this.upldDialog.addButton({text:acs_lang_text.close || 'Close',icon:"/resources/ajax-filestorage-ui/icons/cross.png",cls:"x-btn-text-icon"}, this.upldDialog.hide, this.upldDialog); - } + } else { + var filepanel = this.layout.findById('filepanel'); } - this.upldDialog.body.setStyle("font","normal 12px tahoma, arial, helvetica, sans-serif"); - this.upldDialog.body.setStyle("background-color","#ffffff"); - this.upldDialog.body.setStyle("border","1px solid #e2e2e2"); - this.upldDialog.body.setStyle("padding","3px"); - this.upldDialog.show(); - } + var selectedRows = filepanel.getSelectionModel().getSelections(); + var delfromtree = true; - // determine whether to delete from the jsonview or from the tree - this.confirmDel = function() { - var err_msg_txt = acs_lang_text.confirm_delete || "Are you sure you want to delete" - var err_msg_txt2 = acs_lang_text.foldercontains || "This folder contains" - // check if there is a selected file in the jsonview - var selectedRows = this.filegrid.getSelectionModel().getSelections(); + // build the warning message, we want the delete to be intuitive + // determine if we're deleting from tree panel or from file panel + if (selectedRows.length > 0) { - // ** delete from grid ** + + delfromtree = false; + + // ** delete item from grid ** if (selectedRows.length == 1) { var filetodel = selectedRows[0].get("title"); if(selectedRows[0].get("type") === "folder") { @@ -891,770 +732,920 @@ var msg = ""; } var msg = msg + err_msg_txt+" "+filetodel+" ?"; + var object_id = selectedRows[0].get("id"); } else { - var msg = err_msg_txt + ":

" + var msg = err_msg_txt + ":

"; + var object_id = []; for(var x=0; x" + selectedRows[x].get("title") + " "; if(selectedRows[x].get("type") === "folder") { msg=msg+"("+selectedRows[x].get("size")+")"; } msg=msg+"
"; + object_id[x] = selectedRows[x].get("id"); } } - this.msgbox.confirm(acs_lang_text.confirm || 'Confirm', msg, this.delFsitems,this); + } else { - // ** delete from tree ** + + delfromtree = true; + + // ** delete item from tree (tree only shows folders) ** // we can't delete the root node - var selectednode = this.treepanel.getSelectionModel().getSelectedNode(); - var rootnode = this.treepanel.getRootNode(); + var selectednode = treepanel.getSelectionModel().getSelectedNode(); + var object_id = selectednode.attributes["id"]; + var rootnode = treepanel.getRootNode(); if(selectednode.attributes["id"] == rootnode.attributes["id"]) { Ext.Msg.alert(acs_lang_text.alert || "Alert",acs_lang_text.cant_del_root || "The root folder can not be deleted."); + return; } else { - // return a confirmation message - this.msgbox.confirm(acs_lang_text.confirm || 'Confirm', err_msg_txt+' '+selectednode.attributes["text"]+'?', this.delFolder,this); + // confirmation message + var msg = err_msg_txt+' '+selectednode.attributes["text"]+'?'; } + } - } - // delete one or more folder or files - this.delFsitems = function(choice) { + var doDelete = function(choice) { + if (choice === "yes") { + Ext.Ajax.request({ + url:this.xmlhttpurl+"delete-fsitem", + success: function(response) { + var resultObj = Ext.decode(response.responseText); + if(resultObj.success) { + if(delfromtree) { + var selectednode = treepanel.getSelectionModel().getSelectedNode(); + var parentnode = selectednode.parentNode; + parentnode.fireEvent("click",parentnode); + parentnode.removeChild(selectednode); + } else { + for(var x=0; x
"+resultObj.error+""); + }, params: { object_id: object_id } + }); + } + } - // get the rows to delete - var selectedRows = this.filegrid.getSelectionModel().getSelections(); + Ext.MessageBox.confirm(acs_lang_text.confirm || 'Confirm',msg,doDelete,this); - // arrays for use later - var object_id = []; + }, - // get all node id's from json view into array - for(var x=0; x
"+resultObj.error+""); } - // clear selections after delete - this.filegrid.getSelectionModel().clearSelections(); - } else { - Ext.Msg.alert(acs_lang_text.error || "Error",err_msg_txt+"

"+response.responseText+""); - } - this.filegrid.container.unmask(); - } + }, failure: function(response) { + var resultObj = Ext.decode(response.responseText); + Ext.Msg.alert(acs_lang_text.error || "Error",error_msg_txt + "

"+resultObj.error+""); + }, params: { folder_id: currentTreeNode.attributes["id"] } + }); - var params = "object_id="+object_id - var url = this.xmlhttpurl+"delete"; + }, - if (choice === "yes") { - this.filegrid.container.mask('Deleting'); - this.asyncCon.request({url:url, - params: params, - method:"POST", - callback: callback, - scope: this - }); - } - } + createSwfObj : function() { - // deletes a folder - this.delFolder = function(choice) { + var ajaxfsobj = this; + var treepanel = ajaxfsobj.layout.findById('treepanel'); + var currentfolder = ajaxfsobj.currentfolder; - var selectednode = this.treepanel.getSelectionModel().getSelectedNode(); - var parentnode = selectednode.parentNode; - var id = selectednode.attributes["id"]; + if(this.swfu == null) { - var callback = function(option,success,response) { - var err_msg_txt = acs_lang_text.delete_error || "Sorry, there was an error trying to delete this item." - if(success) { - if (response.responseText != "1") { - Ext.Msg.alert(acs_lang_text.error || "Error",err_msg_txt + "

"+response.responseText+""); - } else { - parentnode.fireEvent("click",parentnode); - parentnode.removeChild(selectednode); + var package_id = String(this.config.package_id); + var user_id = String(this.config.user_id); + var folder_id = String(this.currentfolder); + var max_file_size = String(this.config.max_file_size); + + var uploadProgress = function (fileObj, bytesLoaded) { + try { + var percent = Math.ceil((bytesLoaded / fileObj.size) * 100) + var progress = new FileProgress(fileObj, this.getSetting("progress_target")); + progress.SetProgress(percent); + progress.SetStatus(acs_lang_text.uploading || "Uploading..."); + } catch (ex) { this.debugMessage(ex); } + } + + var uploadCancel = function(fileObj) { + try { + var progress = new FileProgress(fileObj, this.getSetting("progress_target")); + progress.SetCancelled(); + progress.SetStatus(acs_lang_text.uploadcancel || "Cancelled (This item will be removed shortly)"); + progress.ToggleCancel(false); + } - } else { - // delete didn't work, return error - Ext.Msg.alert(acs_lang_text.error || "Error",err_msg_txt+"

"+response.responseText+""); + catch (ex) { this.debugMessage(ex) } } - } - if (choice === "yes") { - this.asyncCon.request({url:this.xmlhttpurl+"delete", - params: "object_id="+id, - method:"POST", - callback: callback, - scope: this - }); - } + var uploadComplete = function(fileObj) { + try { + var progress = new FileProgress(fileObj, this.getSetting("progress_target")); + progress.SetComplete(); + progress.SetStatus(acs_lang_text.complete || "Complete."); + progress.ToggleCancel(false); + + } catch (ex) { this.debugMessage(ex); } + } - } + var uploadQueueComplete = function(fileidx) { + var currentTreeNode = treepanel.getNodeById(ajaxfsobj.currentfolder); + currentTreeNode.fireEvent("click",currentTreeNode); + } - // creates a new folder in the db - // inserts a blank folder in the ui ready for user to enter name - this.newFolder = function() { - - // get currently selected folder - var te = this.te; - var tree = this.treepanel; - var currentTreeNode = tree.getSelectionModel().getSelectedNode(); - currentTreeNode.expand(); - - var callback = function(option,success,response) { - var error_msg_txt = acs_lang_text.new_folder_error || "Sorry, there was an error trying to create your new folder."; - if(success) { - if (response.responseText) { - var result_obj = eval(response.responseText); - if(parseInt(result_obj[0].id) != 0) { - // create a new blank node on the currently selected one - var newnode = currentTreeNode.appendChild(new Ext.tree.TreeNode({text:result_obj[0].pretty_folder_name,id:result_obj[0].id,iconCls:'folder',singleClickExpand:true,attributes:{write_p:'t'}})); - tree.getSelectionModel().select(newnode); - newnode.loaded=true; - newnode.fireEvent("click",newnode); - setTimeout(function(){ - te.editNode = newnode; - te.startEdit(newnode.ui.textNode); - }, 10); - } else { - Ext.Msg.alert(acs_lang_text.error || "Error",error_msg_txt + "

"+response.responseText+""); + var uploadError = function(error_code, fileObj, message) { + try { + if (error_code == SWFUpload.ERROR_CODE_QUEUE_LIMIT_EXCEEDED) { + Ext.Msg.alert(acs_lang_text.alert || "Alert","You have attempted to queue too many files.\n" + (message == 0 ? "You have reached the upload limit." : "You may select " + (message > 1 ? "up to " + message + " files." : "one file."))); + return; } + + var progress = new FileProgress(fileObj, this.getSetting("progress_target")); + progress.SetError(); + progress.ToggleCancel(false); + + switch(error_code) { + case SWFUpload.ERROR_CODE_HTTP_ERROR: + progress.SetStatus("Upload Error"); + this.debugMessage("Error Code: HTTP Error, File name: " + file.name + ", Message: " + message); + break; + case SWFUpload.ERROR_CODE_MISSING_UPLOAD_TARGET: + progress.SetStatus("Configuration Error"); + this.debugMessage("Error Code: No backend file, File name: " + file.name + ", Message: " + message); + break; + case SWFUpload.ERROR_CODE_UPLOAD_FAILED: + progress.SetStatus("Upload Failed."); + this.debugMessage("Error Code: Upload Failed, File name: " + file.name + ", File size: " + file.size + ", Message: " + message); + break; + case SWFUpload.ERROR_CODE_IO_ERROR: + progress.SetStatus("Server (IO) Error"); + this.debugMessage("Error Code: IO Error, File name: " + file.name + ", Message: " + message); + break; + case SWFUpload.ERROR_CODE_SECURITY_ERROR: + progress.SetStatus("Security Error"); + this.debugMessage("Error Code: Security Error, File name: " + file.name + ", Message: " + message); + break; + case SWFUpload.ERROR_CODE_FILE_EXCEEDS_SIZE_LIMIT: + progress.SetStatus("File is too big."); + this.debugMessage("Error Code: File too big, File name: " + file.name + ", File size: " + file.size + ", Message: " + message); + break; + case SWFUpload.ERROR_CODE_ZERO_BYTE_FILE: + progress.SetStatus("Cannot upload Zero Byte files."); + this.debugMessage("Error Code: Zero byte file, File name: " + file.name + ", File size: " + file.size + ", Message: " + message); + break; + case SWFUpload.ERROR_CODE_UPLOAD_LIMIT_EXCEEDED: + progress.SetStatus("Upload limit exceeded."); + this.debugMessage("Error Code: Upload Limit Exceeded, File name: " + file.name + ", File size: " + file.size + ", Message: " + message); + break; + default: + progress.SetStatus("Unhandled Error"); + this.debugMessage("Error Code: " + error_code + ", File name: " + file.name + ", File size: " + file.size + ", Message: " + message); + break; + } + } catch (ex) { + this.debugMessage(ex); } - } else { - Ext.Msg.alert(acs_lang_text.error || "Error",error_msg_txt + "

"+response.responseText+""); } - } - this.asyncCon.request({url:this.xmlhttpurl+"newblankfolder", - params: "folder_id="+currentTreeNode.attributes["id"], - method:"POST", - callback: callback, - scope: this - }); - } + var uploadStart = function (fileObj) { + var upload_txt = acs_lang_text.for_upload_to || "for upload to"; + var zip_txt = acs_lang_text.zip_extracted || "Zip File (Will be extracted after upload)"; + try { + var folderid = ajaxfsobj.currentfolder; + var foldername = treepanel.getNodeById(folderid).text; + var progress = new FileProgress(fileObj, this.getSetting("progress_target")); + progress.SetStatus( upload_txt + " "+foldername+"
Title: (optional)
"+ zip_txt); + progress.ToggleCancel(true, this); + this.addFileParam(fileObj.id, "folder_id", folderid); + } catch (ex) { this.debugMessage(ex); } + } - // when a node item is double clicked - this.itemDblClick= function(grid,i,e) { - var dm = grid.getDataSource(); - var record = dm.getAt(i); - if(record.get("type") == "folder") { - var node = this.treepanel.getNodeById(record.get("id")); - if(!node.parentNode.isExpanded()) { node.parentNode.expand() } - node.fireEvent("click",node); - node.expand(); - } else { - // this is a file, let the user download - window.open(record.get("url")); - window.focus(); + // FIXME (SECURITY): we are getting the user_id from the config, + // since we're using flash there's the current session is not used when the upload is done + // we can't trust the config because malicious javascript might try to insert a different user_id + this.swfu = new SWFUpload({ + debug: false, + upload_target_url: this.xmlhttpurl + "add-file-flash", + upload_params: {user_id:user_id,package_id:package_id}, + file_types : "*.*", + file_size_limit : max_file_size, + file_queue_limit : 0, + file_upload_limit : 10, + begin_upload_on_queue: false, + file_queued_handler : uploadStart, + file_progress_handler : uploadProgress, + file_cancelled_handler : uploadCancel, + file_complete_handler : uploadComplete, + queue_complete_handler : uploadQueueComplete, + error_handler : uploadError, + flash_url : "/resources/ajax-filestorage-ui/swfupload/swfupload.swf" + }); + } - } + }, - // creates the file grid, if it's not yet created - this.createFileGrid = function() { - var cols = [{header: "", width: 50,sortable: true, dataIndex: 'icon'}, - {header: acs_lang_text.filename || "Filename", id:'filename', width: 200, sortable: true, dataIndex: 'title_and_name'}, - {header: acs_lang_text.size || "Size", sortable: true, dataIndex: 'size'}, - {header: acs_lang_text.lastmodified || "Last Modified", sortable: true, dataIndex: 'lastmodified'}]; + addFile : function() { - var colModel = new Ext.grid.ColumnModel(cols); - colModel.defaultSortable=true; + if(this.upldWindow == null) { - var reader = new Ext.data.JsonReader({totalProperty: 'total', root: 'foldercontents', id: 'id'}, [ - {name:'id', type: 'int'}, - {name:'icon'}, - {name:'title'}, - {name:'filename'}, - {name:'type'}, - {name:'tags'}, - {name:'url'}, - {name:'write_p'}, - {name:'title_and_name'}, - {name:'size'}, - {name:'lastmodified'}] ); + if (!this.config.multi_file_upload || checkFlashVersion() < 9 || Ext.isLinux) { + /*** Single File Upload *******/ - var proxy = new Ext.data.HttpProxy( { - url : this.xmlhttpurl+ 'foldercontents' - } ); + var msg1=acs_lang_text.file_to_upload || "File to upload"; + var msg2=acs_lang_text.file_title || "Title"; + var msg3=acs_lang_text.file_description || "Description"; + var msg4=acs_lang_text.multiple_files || "Multiple Files"; + var msg5=acs_lang_text.multiple_files_msg || "This is a ZIPfile containing multiple files."; + var modal = true; + var title = "Upload a File"; - var dataModel = new Ext.data.Store({proxy: proxy, reader: reader, remoteSort: true}); + var uploadBody = new Ext.Panel({ + id:'form_addfile', + align:'left', + frame:true, + html: "

"+msg1+"


"+msg2+"


"+msg3+" :

"+msg4+" :

"+msg5+"

" + }); + var uploadBtns = [{ + text: 'Upload', + handler: this.uploadOneFile.createDelegate(this), + icon:"/resources/ajaxhelper/icons/arrow_up.png", + cls:"x-btn-text-icon" + },{ + text: 'Close', + handler: function(){ + this.upldWindow.hide(); + }.createDelegate(this), + icon:"/resources/ajaxhelper/icons/cross.png", + cls:"x-btn-text-icon" + }] - this.filegrid = new Ext.grid.Grid('files',{ - ds: dataModel, - cm: colModel, - autoHeight: false, - autoWidth: true, - autoSizeColumns: false, - trackMouseOver: true, - autoExpandColumn: 'filename', - enableColumnMove: false, - enableColLock: false, - enableColumnHide: false, - loadMask: true, - monitorWindowResize: true, - enableDragDrop: true, - ddGroup:'fileDD' - }); + } else { - // grid listeners + /*** Multi File Upload *******/ - // Row Click - // when a grid row is clicked, change the highlight on the currently selected folder - // this is similar to windows explorer behavior - this.filegrid.on("rowclick",function() { - this.treepanel.getSelectionModel().getSelectedNode().getUI().removeClass("x-tree-selected"); - this.treepanel.getSelectionModel().getSelectedNode().getUI().addClass("x-tree-grayselected"); - }, this,true); + this.createSwfObj(); - // Row Double Click - this.filegrid.on("rowdblclick",this.itemDblClick,this,true); + var msg_txt = acs_lang_text.upload_intro || "Click Browse to select a file to upload to the selected folder on the tree."; + var modal = false; + var title = "Upload Files"; - // Row Right Click - this.filegrid.on("rowcontextmenu",this.showContext,this,true); + var uploadBody = new Ext.Panel({ + id:'form_multi_addfile', + autoScroll:true, + frame:true, + html: "
"+msg_txt+"
" + }); - // Sort Rows via Drag & Drop - var thegrid = this.filegrid; - var ajaxfsobj = this; - var ddrow = new Ext.dd.DropTarget(thegrid.container, { - ddGroup : 'fileDD', - copy:false, - notifyDrop : function(dd, e, data){ - var ds=thegrid.getDataSource(); - var sm=thegrid.getSelectionModel(); - var rows=sm.getSelections(); - if(dd.getDragData(e)) { - var cindex=dd.getDragData(e).rowIndex; - if(typeof(cindex) != "undefined") { - if (!this.copy){ - for(i = 0; i < rows.length; i++) { - ds.remove(ds.getById(rows[i].id)); - } - } - ds.insert(cindex,data.selections); - sm.clearSelections(); - } + uploadBody.on("render",function() { + this.swfu.addSetting("progress_target", "fsuploadprogress"); + },this); - // ** CSM SPECIFIC ** - // send an xmlhttp request to update the order_n of fs_objects - /* - var params = ""; - var dm = thegrid.getDataSource(); - for(var i = 0;i
"+loading_msg); + + YAHOO.util.Connect.setForm("newfileform", true, true); + + var cObj = YAHOO.util.Connect.asyncRequest("POST", this.xmlhttpurl+"add-file", callback); + + } else { + + Ext.Msg.alert(acs_lang_text.alert || "Alert", acs_lang_text.file_required || "Title and File to upload are required."); + } + }, - // fetch the folder contents + // create add url dialog + addUrl : function() { - this.filegrid.getDataSource().baseParams['folder_id'] = node.id; - this.filegrid.getDataSource().baseParams['tag_id'] = ''; + if (this.createurlWindow == null) { - // if the tree node is still loading, wait for it to expand before loading the grid - if(node.loading) { - node.on("expand", function(){this.filegrid.getDataSource().load()}.createDelegate(this), true, {single:true}); - } else{ - this.filegrid.getDataSource().load(); + this.createurlWindow = new Ext.Window({ + id:'createurl-win', + layout:'fit', + width:400, + height:180, + title:'Create URL', + closeAction:'hide', + modal:true, + plain:true, + resizable:false, + items: new Ext.FormPanel({ + id:'form_create_url', + align:'left', + autoScroll:true, + closable:true, + layout:'form', + defaults: {width: 230}, + frame:true, + buttonAlign:'left', + items: [ + {xtype:'textfield',fieldLabel: 'Title',allowBlank:false,name:'fstitle',tabIndex:1}, + {xtype:'textfield',fieldLabel: 'URL',allowBlank:false,name:'fsurl',tabIndex:2}, + {xtype:'textfield',fieldLabel: 'Description',name:'fsdescription',tabIndex:3} + ] + }), buttons: [{ + text:'Submit', + handler: function() { + this.createurlWindow.findById('form_create_url').getForm().submit( { + url:this.xmlhttpurl+"add-url", + waitMsg:'One moment ....', + params: {package_id:this.config.package_id,folder_id:this.currentfolder}, + reset: true, + scope: this, + success: function(form,action) { + if(action.result) { + this.createurlWindow.hide(); + } else { + Ext.MessageBox.alert('Error','Sorry an error occured.
'+action.result.error); + } + }, failure: function(form,action) { + if(action.result) { + Ext.MessageBox.alert('Error',action.result.error); + } + } + } ) + }.createDelegate(this), + icon:"/resources/ajaxhelper/icons/disk.png", + cls:"x-btn-text-icon" + },{ + text: 'Close', + handler: function(){ + this.createurlWindow.hide(); + }.createDelegate(this), + icon:"/resources/ajaxhelper/icons/cross.png", + cls:"x-btn-text-icon" + }] + }); + } - } - // get the root folder of this file storage instance - // and creates a root node for the Ext tree - this.renderTree = function() { + this.createurlWindow.show(); - var callback = function(option,success,response) { - if(success) { - rootfolderobj = eval('('+response.responseText+')'); + }, - // set the root node - this.rootfolder = new Ext.tree.AsyncTreeNode({ - text: rootfolderobj.text, - draggable:false, - id: rootfolderobj.id, - singeClickExpand: true, - attributes: rootfolderobj.attributes - }); + // rename a file or folder in the right panel + renameItem : function(grid,i,e) { - // ********** TOOLBAR ***************** + var filepanel = grid; + var treepanel = this.layout.findById('treepanel'); + var node = filepanel.store.getAt(i); + var nodeurl = node.get("url"); + var nodetype = node.get("type"); + var nodeid = node.get("id"); + var nodesubtitle = node.get("filename"); + var successRename = function(response) { + var err_msg_txt = acs_lang_text.an_error_occurred || "An error occurred"; + var err_msg_txt2 = acs_lang_text.reverted || "Your changes have been reverted"; + var resultObj = Ext.decode(response.responseText); + if (!resultObj.success) { + Ext.Msg.alert(acs_lang_text.error || "Error",err_msg_txt + ":

"+resultObj.error+"

"+err_msg_txt2); + } else { - // if the current user has write, then we create the toolbar that allows - // uploading files, creating new folders and deleting - if (rootfolderobj.attributes["write_p"] == "t") { - // setup the toolbar on the header - this.toolbar = new Ext.Toolbar ("headerpanel"); - this.toolbar.addButton({text: acs_lang_text.newfolder || 'New Folder', icon: '/resources/ajax-filestorage-ui/icons/folder_add.png', cls : 'x-btn-text-icon', handler: this.newFolder.createDelegate(this), scope: this}); - this.toolbar.addButton({text: acs_lang_text.uploadfile || 'Upload Files', icon: '/resources/ajax-filestorage-ui/icons/add.png', cls : 'x-btn-text-icon', handler: this.showUplddialog.createDelegate(this), scope: this}); - if (create_url_p) { - this.toolbar.addButton({text: acs_lang_text.createurl || 'Create Url', icon: '/resources/ajax-filestorage-ui/icons/page_link.png', cls : 'x-btn-text-icon', handler: this.showCreateUrldialog.createDelegate(this), scope: this}); - } - this.toolbar.addButton({text: acs_lang_text.deletefs || 'Delete', icon: '/resources/ajax-filestorage-ui/icons/delete.png', cls : 'x-btn-text-icon', handler: this.confirmDel.createDelegate(this), scope: this}); + if(nodetype=="folder") { treepanel.getNodeById(nodeid).setText(resultObj.newname) } + + if(nodetype!="folder"&&nodesubtitle===" ") { + nodesubtitle = node.get("title"); + node.set("filename",nodesubtitle); } - this.toolbar.addButton({text: acs_lang_text.download_archive || 'Download Archive', icon: '/resources/ajax-filestorage-ui/icons/arrow_down.png', cls : 'x-btn-text-icon', handler: function(){top.location.href="download-archive/index?object_id="+rootfolderobj.id}.createDelegate(this),scrope:this}); - - // render the tree - this.treepanel.setRootNode(this.rootfolder); - this.treepanel.render(); + node.set("title",resultObj.newname); + node.commit(); + } + }; - // ********** OPEN INITIAL FOLDER ***************** + var handleRename = function(btn, text) { + if(btn=='ok') { - // recursive expand in case folder id is not on the first level - var asyncExpand = function(x) { - var node = this.treepanel.getNodeById(this.config.initOpenFolder); - if(!node) { - var x = x+1; - var nextnodeid = this.config.pathToFolder[x]; - var nextnode = this.treepanel.getNodeById(nextnodeid); - nextnode.on("expand",asyncExpand.createDelegate(this,[x]), this, {single:true}); - nextnode.expand(true); - } else { - node.select() - node.fireEvent("click",node); - } - } + if(text != '') { - // if we get an initOpenFolder config, - // expand the provided initOpenFolder id - var selectInitFolder = function() { - if(this.config.initOpenFolder) { - var initNode = this.treepanel.getNodeById(this.config.initOpenFolder); - if(initNode) { - initNode.expand(); - initNode.fireEvent("click",initNode) - } else { - // recursively expand based on the list of folder_ids in pathToFolder - var x = 1; - var nextnode = this.treepanel.getNodeById(this.config.pathToFolder[x]); - nextnode.on("expand",asyncExpand.createDelegate(this,[x]), this, {single:true}); - nextnode.expand(true); - } + if(text.length > 100) { + + Ext.Msg.alert(acs_lang_text.alert || "Alert",acs_lang_text.limitto100 || "Please limit your name to 100 characters or less."); + return false; + } else { - this.treepanel.fireEvent("click",this.rootfolder); + + Ext.Ajax.request({ + url:this.xmlhttpurl+"edit-name", + success: successRename, + failure: function(response) { + var resultObj = Ext.decode(response.responseText); + Ext.Msg.alert(acs_lang_text.error || "Error",error_msg_txt + "

"+resultObj.error+""); + }, params: { newname:text,object_id:nodeid,type:nodetype,url:nodeurl} + }); + } - } - this.rootfolder.on("expand", selectInitFolder, this, {single:true}) + } else { - // expand and select the root folder - this.rootfolder.expand(); + Ext.Msg.alert(acs_lang_text.alert || "Alert",acs_lang_text.enter_new_name || "Please enter a new name."); + return false; - } else { - Ext.Msg.alert(acs_lang_text.error || "Error", acs_lang_text.tree_render_error || "Sorry, we encountered an error rendering the tree panel"); + } + } - } + }; - // check if we are passed a root folder_id - var params = "package_id="+this.config.package_id; - if (this.config.rootfolder) { - params = params + "&root_folder_id="+ this.config.rootfolder; - } - - this.asyncCon.request({url:this.xmlhttpurl+"getrootfolder", - params: params, - method:"POST", - callback: callback, - scope: this + Ext.Msg.show({ + title: acs_lang_text.rename || 'Rename', + prompt: true, + msg: acs_lang_text.enter_new_name || 'Please enter a new name for ... ', + value: node.get("title"), + buttons: Ext.Msg.OKCANCEL, + fn: handleRename.createDelegate(this) }); - } + var prompt_text_el = YAHOO.util.Dom.getElementsByClassName('ext-mb-input', 'input'); + prompt_text_el[0].select(); - // create and load the treepanel - this.loadTreepanel = function() { + }, - // create a div inside the left panel to create a tree - var folderEl = Ext.get('folderpanel').createChild({tag:'div',id:'folders'}); + // tag a file - // ******** create the tree ************** - this.treepanel = new Ext.tree.TreePanel('folders', { - animate: true, - loader: new Ext.tree.TreeLoader({ dataUrl:this.xmlhttpurl+'loadnodes', - baseParams: { package_id:this.config.package_id} - }), - enableDD:true, - ddGroup:'fileDD', - ddAppendOnly: true, - containerScroll: true, - rootVisible:true + tagFsitem : function(grid,i,e) { + + var filepanel = grid; + var node = filepanel.store.getAt(i); + var object_id = node.get("id"); + var taglist = node.get("tags"); + var package_id = this.config.package_id; + var tagcloudpanel = this.layout.findById("tagcloudpanel"); + var xmlhttpurl = this.xmlhttpurl; + var tagWindow = this.tagWindow; + + var savetags = function() { + + Ext.Ajax.request({ + url:this.xmlhttpurl+"add-tag", + success: function() { + node.data.tags = Ext.get('fstags').getValue(); + node.commit(); + tagcloudpanel.load({url:xmlhttpurl+'get-tagcloud',params:{package_id:package_id}}); + tagWindow.hide(); + }, failure: function(response) { + Ext.Msg.alert(acs_lang_text.error || "Error","Sorry, we encountered an error."); + }, params: { object_id:node.id,package_id:package_id,tags:Ext.get('fstags').getValue()} }); - // ******** folder rename ***************** - this.te = new Ext.tree.TreeEditor(this.treepanel, { - allowBlank:false, - blankText: acs_lang_text.folder_name_required || 'A folder name is required', - selectOnFocus:true - }); + }; - // check if user has premission to rename - this.te.on("beforestartedit", function(node,el,oldname) { - if (node.editNode.attributes.attributes.write_p == "t") { - return true; - } else { - Ext.Msg.alert(acs_lang_text.permission_denied || "Permission Denied", acs_lang_text.permission_denied || "Sorry, you do not have permission to rename this folder"); - return false; - } - }, this, true); + if(tagWindow == null) { - // reject if the folder name is already taken - this.te.on("beforecomplete",function(node,newval,oldval) { - var parent = node.editNode.parentNode; - var children = parent.childNodes; - for(x=0;x

Enter or edit one or more tags. Use commas (,) to separate the tags:

" + }); + + var tagBtns = [{ + text: 'Ok', + icon:"/resources/ajaxhelper/icons/disk.png", + cls:"x-btn-text-icon", + handler:savetags.createDelegate(this) + },{ + text: 'Cancel', + icon:"/resources/ajaxhelper/icons/cross.png", + cls:"x-btn-text-icon", + handler: function(){ + tagWindow.hide(); + }.createDelegate(this) + }]; - // send the update to server and validate - this.te.on("complete", function(node,newval,oldval) { - var callback = function(option,success,response) { - var err_msg_txt = acs_lang_text.an_error_occurred || "An error occurred"; - var err_msg_txt2 = acs_lang_text.reverted || "Your changes have been reverted"; - if (success) { - if (response.responseText != 1) { - Ext.Msg.alert(acs_lang_text.error || "Error",err_msg_txt+":

"+response.responseText+"

"+err_msg_txt2); - node.editNode.setText(oldval); - } - } else { - // ajax failed, revert value - Ext.Msg.alert(acs_lang_text.error || "Error",err_msg_txt+":

"+response.responseText+"

"+err_msg_txt2); - node.editNode.setText(oldval); - } + tagWindow = new Ext.Window({ + id:'tag-win', + layout:'fit', + width:450, + height:300, + title:"Tags", + closeAction:'hide', + modal:true, + plain:true, + autoScroll:false, + resizable:false, + items: tagformBody, + buttons: tagBtns + }); + + } else { + + } + + tagWindow.show(); + this.initTagAutoComplete(); + }, + + initTagAutoComplete : function() { + var oAutoComp1DS = new YAHOO.widget.DS_JSArray(oAutoCompArr); + if(document.getElementById("fstags")) { + var oAutoComp1 = new YAHOO.widget.AutoComplete('fstags','oAutoCompContainer1', oAutoComp1DS); + oAutoComp1.animHoriz=false; + oAutoComp1.animVert=false; + oAutoComp1.queryDelay=0; + oAutoComp1.maxResultsDisplayed=10; + oAutoComp1.useIFrame=true; + oAutoComp1.delimChar=","; + oAutoComp1.allowBrowserAutocomplete=false; + oAutoComp1.typeAhead=true; + oAutoComp1.formatResult=function(oResultItem, sQuery) { + var sMarkup=oResultItem[0]; + return sMarkup; } - this.asyncCon.request({url:this.xmlhttpurl+"editname", - params: "newname="+newval+"&object_id="+node.editNode.id+"&type=folder", - method:"POST", - callback: callback, - scope: this + } + }, + + // download archive function + downloadArchive : function(object_id) { + if(object_id) { + top.location.href="download-archive/?object_id="+object_id; + } + }, + + // redirect to object views for a file + redirectViews : function(grid,i,e) { + var filepanel = grid; + var node = filepanel.store.getAt(i); + var object_id = node.get("id"); + window.open(window.location.protocol+"//"+window.location.hostname+"/o/"+object_id+"/info"); + window.focus(); + }, + + + // redirect to permissions + redirectPerms : function(grid,i,e) { + var filepanel = grid; + var node = filepanel.store.getAt(i); + var object_id = node.get("id"); + var newwindow = window.open(window.location.protocol+"//"+window.location.hostname+":"+window.location.port+this.config.package_url+"permissions?object_id="+object_id+"&return_url="+window.location.pathname+"?package_id="+this.config.package_id+"&folder_id="+this.currentfolder); + newwindow.focus(); + }, + + + // redirect to file properties + redirectProperties : function(grid,i,e) { + var filepanel = grid; + var node = filepanel.store.getAt(i); + var object_id = node.get("id"); + var newwindow = window.open(window.location.protocol+"//"+window.location.hostname+":"+window.location.port+this.config.package_url+"file?file_id="+object_id); + newwindow.focus(); + }, + + // generates a url to the currently selected file storage item + // if it's a file : download + // if it's a folder : append folder_id to the current url + copyLink : function(grid,i,e) { + var filepanel = grid; + var node = filepanel.store.getAt(i); + var nodetype = node.get("type"); + if (nodetype === "folder") { + // generate the url to a folder + var copytext = window.location.protocol+"//"+window.location.hostname+":"+window.location.port+this.config.package_url+"?package_id="+this.config.package_id+"&folder_id="+node.get("id"); + } else if (nodetype === "url") { + var copytext = node.get("url"); + } else { + var copytext = window.location.protocol+"//"+window.location.hostname+node.get("url"); + } + if(Ext.isIE) { + window.clipboardData.setData("text",copytext); + } else { + var copyprompt = Ext.Msg.show({ + title: acs_lang_text.linkaddress || 'Copy Link Address', + prompt: true, + msg: acs_lang_text.copyhighlighted || 'Copy the highlighted text to your clipboard.', + value: copytext, + buttons: Ext.Msg.OK }); - }, this, true); + var prompt_text_el = YAHOO.util.Dom.getElementsByClassName('ext-mb-input', 'input'); + prompt_text_el[0].select(); + } + } - // ********** CLICK ***************** +} - // assign a listener to listen for node clicks - // this will fire the proc to load the right panel - // to fetch the fs items in that folder - this.treepanel.on("click",this.loadFoldercontents,this,true) +/********** UTILS *********************/ - // ********** Grid Row DRAGDROP **************** +/* readCookie +read value of a cookie */ +function readCookie(name) { + var ca = document.cookie.split(';'); + var nameEQ = name + "="; + for(var i=0; i < ca.length; i++) { + var c = ca[i]; + while (c.charAt(0)==' ') { c = c.substring(1, c.length) } + if (c.indexOf(nameEQ) == 0) { return c.substring(nameEQ.length, c.length) } + } + return null; +} - // check if the file/folder can be dropped on a node +/* createCookie +used to maintain state, e.g. when login expires */ +function createCookie(name, value, days){ + if (days) { + var date = new Date(); + date.setTime(date.getTime()+(days*24*60*60*1000)); + var expires = "; expires="+date.toGMTString(); + } else { var expires = "" } + document.cookie = name+"="+value+expires+"; path=/"; +} - this.treepanel.on("nodedragover",function(e){ - // DO NOT ALLOW DROP TO CURRENT FOLDER - // check if the id of target node to be dropped - // is the same as the currently selected tree node - if (e.target.id == this.treepanel.getSelectionModel().getSelectedNode().id) { - return false; +/* read query string +read the value of a querystring */ +function readQs(q) { + var query = window.location.search.substring(1); + var parms = query.split('&'); + for (var i=0; i 0) { + var key = parms[i].substring(0,pos); + var val = parms[i].substring(pos+1); + if (key == q) { + return val; } - // DO NOT ALLOW TO DROP A NODE TO ITSELF - // check if the id of any of the nodes to be dropped - // is the same as the id on the tree - if(e.source.dragData.selections) { - for (var x=0; x
"+response.responseText+"

"+err_msg_txt2); - error = true; - } - } else { - // ajax failed, revert value - Ext.Msg.alert(acs_lang_text.error || "Error", acs_lang_text.error_and_reverted || "An error occurred. Your changes have been reverted"); - error = true; - } - // if move encountered an error, revert the change - if (error) { - option.target.removeChild(option.thenode); - option.parent.appendChild(option.thenode); - option.parent.loaded=false; - option.parent.expand(); - } else { - option.target.loaded=false; - option.target.fireEvent("click",option.target); - option.target.expand(); - } - } - - var params = "file_ids="+draggedObj+"&folder_target_id="+target; - var url = this.xmlhttpurl+"move"; +// check if the string argument is a url +function isURL(argvalue) { - this.asyncCon.request({url:url, - params: params, - method:"POST", - callback: callback, - scope: this, - target: t, - parent: p, - thenode: n - }); + if (argvalue.indexOf(" ") != -1) + return false; + else if (argvalue.indexOf("http://") == -1) + return false; + else if (argvalue == "http://") + return false; + else if (argvalue.indexOf("http://") > 0) + return false; - } else { - - // we dropped a row from the grid - var folder_target_id = ddobj.target.id; - var file_ids = []; - for(var x=0;x 0) { + this.opacity -= reduce_opacity_by; + if (this.opacity < 0) this.opacity = 0; + + if (this.fileProgressWrapper.filters) { + try { + this.fileProgressWrapper.filters.item("DXImageTransform.Microsoft.Alpha").opacity = this.opacity; + } catch (e) { + // If it is not set initially, the browser will throw an error. This will set it if it is not set yet. + this.fileProgressWrapper.style.filter = 'progid:DXImageTransform.Microsoft.Alpha(opacity=' + this.opacity + ')'; + } + } else { + this.fileProgressWrapper.style.opacity = this.opacity / 100; } - // ExtJs has not been loaded, do nothing } - // ** initialize ** + if (this.height > 0) { + this.height -= reduce_height_by; + if (this.height < 0) this.height = 0; - Ext.EventManager.onDocumentReady(this.initObj,this,true); + this.fileProgressWrapper.style.height = this.height + "px"; + } + + if (this.height > 0 || this.opacity > 0) { + var oSelf = this; + setTimeout(function() { oSelf.Disappear(); }, rate); + } else { + this.fileProgressWrapper.style.display = "none"; + } } \ No newline at end of file