marclundgren
6/10/2014 - 7:40 PM

Liferay Upload & Document Library Upload class abstraction

Liferay Upload & Document Library Upload class abstraction

upload-data-queue

upload-queue is different in DM. we queue every uploadData collection, and append any uploadData with the same folderId. for Liferay Upload, all uploads share the same folderId (ignoring the creation of folders from a folder drag&drop

upload-location

  • can accept a temp location. boom problem solved

DocumentLibraryUpload

  • Convert DocumentLibraryUpload into a plugin
  • plug DocumentLibrary with Plugin.DocumentLibraryUpload once the document fires a 'dragover` event

Abstract shared attributes & behaviours

  • base
  • data validation
  • data queue
  • lifeycle
  • location

Abstract specific attributes & behaviours

  • document library entry

Resources

// uploader
DEPENDENCIES: {
  [{
    name: 'liferay-upload',
    requires: [
      'liferay-upload-base'
    ]
  },
  {
    name: 'liferay-upload-base',
    requires: [
      'liferay-upload-data-queue',
      'liferay-upload-data-validation',
      'liferay-upload-lifecycle'
    ]
  {
    name: 'document-library-upload',
    requires: [
      'liferay-upload-base',

      // Document Library Upload - Specific
      'document-library-upload-entry',
      'document-library-upload-entry-status',
      'document-library-upload-entry-status-overlay',
      'document-library-upload-entry-status-progress'
    ]
  }]
};
/*******************************************
  Class abstraction : LiferayUpload
*******************************************/

// upload-base
function _renderUploader() // change this to a lazy-load attr
function bindUI()
function initializer(config)
function renderUI()

// upload-data-queue
function _queueFile(file)

// upload-data-validation
function _getValidFiles(data)

// upload-lifecycle
function _afterFilesSaved(event)
function _handleDrop(event)
function _isUploading()
function _onAllUploadsComplete(event)
function _onFileSelect(event)
function _onUploadComplete(event)
function _onUploadProgress(event)
function _onUploadStart(event)

// liferay-upload
function _cancelAllFiles()
function _clearUploads()
function _formatTempFiles(fileNames)
function _handleDeleteResponse(json, li)
function _markSelected(node)
function _renderControls()
function _renderFileList()
function _updateList(listLength, message)
function _updateManageUploadDisplay()
function _updateMetadataContainer()
function _updatePendingInfoContainer()
function _updateWarningContainer()

// liferay-upload bindUI
function _handleFileClick(event)
function _onAllRowIdsClick(event)
function _onBeforeUnload(event)
function _onCancelFileClick(currentTarget)
function _onDeleteFileClick(currentTarget)
function _onSelectFileClick(currentTarget)
/*******************************************
  Class abstraction : DocumentLibraryUpload
*******************************************/

// upload-base
function _getUploader() // convert this to an attr, the setter fn will init the YUI uploader due to lazy load
function _onFileSelect(event)
function destructor()
function initializer()

// upload-data-queue
function _addFilesToQueueBottom(files)
function _combineItemLists(itemList, queuedItems)
function _getCurrentUploadData()
function _getDataSet()
function _queueSelectedItems(target, itemsPartition, uploadFileTreeFn)
function _updateDataSetEntry(key, data, unmergedData)

// upload-data-validation
function _validateItems(data)

// upload-lifecycle
function _isUploading()
function _startNextUpload(event)
function _startUpload()

// upload-location
function _getFolderId(target)
function _getUploadURL(folderId)

// document-library-upload
function _initDLUpload()
function _getEmptyMessage()
function _attachSubscriptions(data) // try to move the need for these into upload-queue
function _detachSubscriptions() // ..

// document-library-upload-entry
function _createEntryNode(item, displayStyle)
function _createEntryRow(name, size)
function _createFolderUploadStatusUI(target)
function _createItemUploadStatusUI(target, item)
function _createUploadStatusUI(target, item)
function _destroyEntry()
function _displayEntryError(node, message, displayStyle)
function _displayError(node, message)
function _displayResult(node, displayStyle, error)
function _getDisplayStyle(style)
function _getFolderEntryNode(target)
function _getInvisibleEntry(displayStyle, isDirectory)
function _getMediaThumbnail(fileName)

// document-library-upload-entry-status 
function _detectFolderUploadError(event, data)
function _getUploadResponse(responseData)
function _getUploadStatus(key)
function _showDirectoryUploadComplete(event, uploadData, displayStyle)
function _showDirectoryUploadProgress(event, uploadData)
function _showDirectoryUploadStarting(event, uploadData)
function _showFileUploadComplete(event, displayStyle)
function _showFileUploadProgress(event)
function _showFileUploadStarting(event)
function _showFolderUploadComplete(event, uploadData, displayStyle)
function _showFolderUploadProgress(event, uploadData)
function _showFolderUploadStarting(event, uploadData)
function _updateFileLink(node, id, displayStyleList)
function _updateProgress(progressBar, value)
function _updateStatusUI(target, itemsPartition)
function _updateThumbnail(node, fileName)

// document-library-upload-entry-status-overlay
function _createOverlay(target, background) 
function _getNavigationOverlays()
function _getOverlay(host)

// document-library-upload-entry-status-progress
function _createProgressBar()
function _positionProgressBar(overlay, progressBar)

// document-library-upload bindUI
function _bindDragDropUI()
function _confirmUnload()
function _onDataRequest(event)

LiferayUpload and DocumentLibraryUpload class abstraction

Portal has two implementations of an HTML5 Uploader that share a significant codebase. Abstracting them will improve readability, increase maintainability, and simplify debugging. It also gives us a chance to apply Webkit's powerful Folder uploading without writing spaghetti code to make it work in both places.

LiferayUpload

Liferay Upload is used in a few places:

  • Document Library - Upload Multiple File Entries
  • Layouts Admin - Import Layouts Validation
  • Portlet Configuration - Import Portlet Validation
  • Wiki - Edit Page Attachment

It has a completly different UI than DocumentLibraryUpload, but behind the scenes they do share similarities in structure, data validation.

DocumentLibraryUpload

This one is powerful, but quiet. Our goal was to provide a quicker way for users to add files from their computer. Adding one file at a time can be quite tedious, and in order to achieve the goal more quickly, a user can select as many items as they would wish from their file system, and drag them into the DM portlet without having to upload each item individually. The user can use the portlet entries container as an upload target which will upload the items to current root folder.

The user can also drop items onto a folder entry (if one is visible) and the files selected will upload to that child folder instead of the relative root folder. After the user drags and drops files (and soon folders) into the DM portlet, they can watch new entries appear in the entries container as the upload makes progress.

`DocumentLibraryUpload` is only used by the Document Library Portlet. The feature not very apparent to the user. As they drag in some files from their desktop, a blue-ish outline appears on the portlet entries container. The user would have had to guess that this feature may exist, they may have been told the feature exists by a college. Now is the time to make this powerful feature more obvious. One option is to provide an alert like the empty message.

list of class abstraction

shared

  • UploadBase
  • UploadDataQueue
  • UploadDataValidation
  • UploadLifecycle
  • UploadLocation

document-library specific

  • DocumentLibraryUpload
  • DocumentLibraryUploadEntry
  • DocumentLibraryUploadEntryStatus
  • DocumentLibraryUploadEntryStatusOverlay
  • DocumentLibraryUploadEntryStatusProgress
  • DocumentLibraryUpload

LiferayUpload specific

  • LiferayUpload

/*******************************************
  Attributes
*******************************************/

// base
maxFileSize
multipleFiles
render
strings
selectFilesButton
uploader
uploaderBoundingBox
uploaderContentBox

/********************************
 * document-library-upload
 *
 * type: document-library instance (augmented)
********************************/

// upload-data-validation
invalidFileSizeText
invalidFileType
zeroByteFileText

// upload-data-queue
dataSet // [delloc]

// upload-location
folderId
uploadURL

// document-library-upload-entry
columnNames
entriesContainer
handles // entries differ, we need to manage which handles are active...try to remove this, or at least cache the subs and attach/detach
invisibleDescriptiveEntry
invisibleIconEntry
navigationOverlays // [dealloc]
viewFileEntryURL
tooltipDelegate

// document-library-upload-entry-status-progress
dimensions

// document-library
emptyMessage

// to remove
tooltipDelegates // not used, empty collection
overlayManager // not used

// referenced from doc lib main.js
appViewMove
config


/********************************
 * liferay-upload
 *
 * type: Component
********************************/


// upload-data-validation
invalidFileSizeText

// upload-location
tempFileURL
tempRandomSuffix // [tempFileURL]
uploadFile

// to remove
fallback // use uploader-flash as a fallback

// liferay-upload protected instance variables
deleteFile
metadataContainer
metadataExplanationContainer
allRowIdsCheckbox
allRowIdsCheckboxSelector
cancelButton
clearUploadsButton
fileListBuffer
fileListContent
fileListSelector
fileListTPL
filesTotal
listInfo
manageUploadTarget
metadataContainer
metadataExplanationContainer
pendingFileInfo
preventRenderHandle
renderFileListTask
selectUploadedFileCheckboxId
uploadFragment
/*******************************************
 * These items are in progress...
 * 
 * Leave feedback in the comments section.
*******************************************/