Skip to content

Commit

Permalink
MDL-14636: Support table view in Filepicker, provide more info about …
Browse files Browse the repository at this point in the history
…files

- Added table view in Filepicker where for each file we show Name, Last modified, Size and Type. Sortable by column
- Preprocess list of files returned from repositories to include formatted size, dates, type and also add filetype icon
- Make sure that local repositories (coursefiles, filesystem, local, recent, user) return information about file size, datemodified, datecreated, author, license
  • Loading branch information
marinaglancy committed May 21, 2012
1 parent 2f6749f commit 5bdf63c
Show file tree
Hide file tree
Showing 12 changed files with 204 additions and 56 deletions.
1 change: 1 addition & 0 deletions lang/en/repository.php
Expand Up @@ -179,6 +179,7 @@
$string['sync'] = 'Sync';
$string['thumbview'] = 'View as icons';
$string['title'] = 'Choose a file...';
$string['type'] = 'Type';
$string['typenotvisible'] = 'Type not visible';
$string['upload'] = 'Upload this file';
$string['uploading'] = 'Uploading...';
Expand Down
3 changes: 2 additions & 1 deletion lib/outputrequirementslib.php
Expand Up @@ -439,7 +439,7 @@ protected function find_module($component) {
case 'core_filepicker':
$module = array('name' => 'core_filepicker',
'fullpath' => '/repository/filepicker.js',
'requires' => array('base', 'node', 'node-event-simulate', 'json', 'async-queue', 'io-base', 'io-upload-iframe', 'io-form', 'yui2-menu', 'yui2-treeview', 'yui2-dragdrop', 'panel', 'cookie'),
'requires' => array('base', 'node', 'node-event-simulate', 'json', 'async-queue', 'io-base', 'io-upload-iframe', 'io-form', 'yui2-menu', 'yui2-treeview', 'yui2-dragdrop', 'panel', 'cookie', 'datatable', 'datatable-sort'),
// TODO check if those all are really required
'strings' => array(array('add', 'repository'), array('back', 'repository'), array('cancel', 'moodle'), array('close', 'repository'),
array('cleancache', 'repository'), array('copying', 'repository'), array('date', 'repository'), array('downloadsucc', 'repository'),
Expand All @@ -459,6 +459,7 @@ protected function find_module($component) {
array('renameto', 'repository'), array('fileexists', 'repository'),
array('fileexistsdialogheader', 'repository'), array('fileexistsdialog_editor', 'repository'),
array('fileexistsdialog_filemanager', 'repository'), array('uselatestfile', 'repository')
array('lastmodified', 'moodle'), array('name', 'moodle'), array('type', 'repository')
));
break;
case 'core_comment':
Expand Down
11 changes: 7 additions & 4 deletions repository/coursefiles/lib.php
Expand Up @@ -105,8 +105,8 @@ public function get_listing($encodedpath = '', $page = '') {
$encodedpath = base64_encode(serialize($params));
$node = array(
'title' => $child->get_visible_name(),
'size' => 0,
'date' => '',
'datemodified' => $child->get_timemodified(),
'datecreated' => $child->get_timecreated(),
'path' => $encodedpath,
'children'=>array(),
'thumbnail' => $OUTPUT->pix_url('f/folder-32')->out(false)
Expand All @@ -116,8 +116,11 @@ public function get_listing($encodedpath = '', $page = '') {
$encodedpath = base64_encode(serialize($child->get_params()));
$node = array(
'title' => $child->get_visible_name(),
'size' => 0,
'date' => '',
'size' => $child->get_filesize(),
'author' => $child->get_author(),
'license' => $child->get_license(),
'datemodified' => $child->get_timemodified(),
'datecreated' => $child->get_timecreated(),
'source'=> $encodedpath,
'thumbnail' => $OUTPUT->pix_url(file_extension_icon($child->get_visible_name(), 32))->out(false)
);
Expand Down
122 changes: 88 additions & 34 deletions repository/filepicker.js
Expand Up @@ -350,18 +350,18 @@ M.core_filepicker.init = function(Y, options) {
build_tree: function(node, level) {
var client_id = this.options.client_id;
var dynload = this.active_repo.dynload;
var info = {
label:node.title,
filename:node.title,
source:node.source?node.source:'',
thumbnail:node.thumbnail,
path:node.path?node.path:''
};
// prepare file name with icon
var el = Y.Node.create('<div/>').setContent(M.core_filepicker.templates.listfilename);
el.one('.fp-filename').setContent(node.title);
if (node.icon && !node.children) {
el.one('.fp-icon').appendChild(Y.Node.create('<img/>').set('src', node.icon));
}
// create node
var tmpNode = new YAHOO.widget.HTMLNode(el.getContent(), level, false);
if (node.dynamicLoadComplete) {
info.dynamicLoadComplete = true;
tmpNode.dynamicLoadComplete = true;
}
var tmpNode = new YAHOO.widget.TextNode(info, level, false);
tmpNode.repo_id = node.repo_id ? node.repo_id : this.active_repo.id;
tmpNode.fileinfo = node;
tmpNode.isLeaf = node.children ? false : true;
if (!tmpNode.isLeaf) {
if(node.expanded) {
Expand All @@ -370,8 +370,7 @@ M.core_filepicker.init = function(Y, options) {
if (dynload) {
tmpNode.scope = this;
}
tmpNode.client_id = client_id;
tmpNode.path = info.path;
tmpNode.path = node.path ? node.path : '';
for(var c in node.children) {
this.build_tree(node.children[c], tmpNode);
}
Expand All @@ -385,10 +384,10 @@ M.core_filepicker.init = function(Y, options) {
} else {
this.viewbar_set_enabled(true);
this.print_path();
if (this.viewmode == 1) {
this.view_as_icons();
} else if (this.viewmode == 2) {
if (this.viewmode == 2) {
this.view_as_list();
} else if (this.viewmode == 3) {
this.view_as_table();
} else {
this.view_as_icons();
}
Expand Down Expand Up @@ -446,7 +445,7 @@ M.core_filepicker.init = function(Y, options) {
var dynload = scope.active_repo.dynload;
var list = this.filelist;
scope.viewmode = 2;
if (list && list.length==0 && (!this.filepath || !this.filepath.length)) {
if (!list || list.length==0 && (!this.filepath || !this.filepath.length)) {
this.display_error(M.str.repository.nofilesavailable, 'nofilesavailable');
return;
}
Expand Down Expand Up @@ -485,7 +484,10 @@ M.core_filepicker.init = function(Y, options) {
var root = scope.treeview.getRoot();
while (root && root.children && root.children.length) {
root = root.children[0];
if (!root.isLeaf && root.expanded && root.path != mytreeel.path) {
if (root.path == mytreeel.path) {
root.origpath = scope.filepath;
root.origlist = scope.filelist;
} else if (!root.isLeaf && root.expanded) {
scope.treeview_dynload(root, null);
}
}
Expand All @@ -498,18 +500,14 @@ M.core_filepicker.init = function(Y, options) {
}
scope.treeview.subscribe('clickEvent', function(e){
if(e.node.isLeaf){
var fileinfo = {};
fileinfo['title'] = e.node.data.filename;
fileinfo['source'] = e.node.data.source;
fileinfo['thumbnail'] = e.node.data.thumbnail;
if (e.node.parent && e.node.parent.origpath) {
// set the current path
scope.filepath = e.node.parent.origpath;
scope.filelist = e.node.parent.origlist;
scope.print_path();
}
e.node.highlight(false)
scope.select_file(fileinfo);
e.node.highlight(false);
scope.select_file(e.node.fileinfo);
} else {
// save current path and filelist (in case we want to jump to other viewmode)
scope.filepath = e.node.origpath;
Expand All @@ -524,7 +522,7 @@ M.core_filepicker.init = function(Y, options) {
var list = this.filelist;
this.viewmode = 1;

if (list && list.length==0) {
if (!list || list.length==0) {
this.display_error(M.str.repository.nofilesavailable, 'nofilesavailable');
return;
}
Expand Down Expand Up @@ -576,28 +574,84 @@ M.core_filepicker.init = function(Y, options) {
element.on('click', function(e, p) {
e.preventDefault();
if(dynload) {
var params = {'path':p.path};
scope.list(params);
scope.list({'path':p.path});
}else{
this.filepath = p.path;
this.filelist = p.children;
this.view_files();
}
}, this, node);
} else {
var fileinfo = {};
fileinfo['title'] = list[k].title;
fileinfo['source'] = list[k].source;
fileinfo['thumbnail'] = list[k].thumbnail;
fileinfo['haslicense'] = list[k].haslicense?true:false;
fileinfo['hasauthor'] = list[k].hasauthor?true:false;
element.on('click', function(e, args) {
e.preventDefault();
this.select_file(args);
}, this, fileinfo);
}, this, list[k]);
}
count++;
}
},
view_as_table: function() {
var list = this.filelist;
var client_id = this.options.client_id;
this.viewmode = 3;

if (!list || list.length==0) {
this.display_error(M.str.repository.nofilesavailable, 'nofilesavailable');
return;
}
var treeviewnode = Y.Node.create('<div/>').
setAttrs({'class':'fp-tableview', id:'tableview-'+client_id});
this.fpnode.one('.fp-content').setContent('').appendChild(treeviewnode);
var formatValue = function (o){
if (o.data[''+o.field+'_f_s']) { return o.data[''+o.field+'_f_s']; }
else if (o.data[''+o.field+'_f']) { return o.data[''+o.field+'_f']; }
else if (o.value) { return o.value; }
else { return ''; }
};
var formatTitle = function(o) {
var el = Y.Node.create('<div/>').setContent(M.core_filepicker.templates.listfilename);
el.one('.fp-filename').setContent(o.value);
el.one('.fp-icon').appendChild(Y.Node.create('<img/>').set('src', o.data['icon']));
return el.getContent();
}

var cols = [
{key: "title", label: M.str.moodle.name, sortable: true, formatter: formatTitle},
{key: "datemodified", label: M.str.moodle.lastmodified, sortable: true, formatter: formatValue},
{key: "size", label: M.str.repository.size, sortable: true, formatter: formatValue},
{key: "type", label: M.str.repository.type, sortable: true}
];
var table = new Y.DataTable.Base({
columnset: cols,
recordset: list
});
// TODO allow sorting only if repository allows it, remember last sort order
table.plug(Y.Plugin.DataTableSort/*, { lastSortedBy: {key: "title", dir: "asc"} }*/);

table.render('#tableview-'+client_id);
table.delegate('click', function (e) {
var rs = table.get('recordset');
var id = e.currentTarget.get('id'), len = rs.size(), i;
for (i = 0; i < len; ++i) {
var record = rs.item(i);
if (record.get('id') == id) {
// we found the clicked record
var data = record.getValue();
if (data.children) {
if (this.active_repo.dynload) {
this.list({'path':data.path});
} else {
this.filepath = data.path;
this.filelist = data.children;
this.view_files();
}
} else {
this.select_file(data);
}
}
}
}, 'tr', this);
},
select_file: function(args) {
this.selectui.show();
var client_id = this.options.client_id;
Expand Down Expand Up @@ -1391,7 +1445,7 @@ M.core_filepicker.init = function(Y, options) {
this.viewbar_set_enabled(false);
var repository_id = Y.Cookie.get('recentrepository');
this.viewmode = Y.Cookie.get('recentviewmode', Number);
if (this.viewmode != 1 && this.viewmode != 2 && this.viewmode != 3) {
if (this.viewmode != 2 && this.viewmode != 3) {
this.viewmode = 1;
}
if (this.options.repositories[repository_id]) {
Expand Down
1 change: 1 addition & 0 deletions repository/filesystem/lang/en/repository_filesystem.php
Expand Up @@ -30,6 +30,7 @@
$string['information'] = 'These folders are within the <b>{$a}</b> directory.';
$string['invalidpath'] = 'Invalid root path';
$string['path'] = 'Select a subdirectory';
$string['root'] = 'Root';
$string['nosubdir'] = 'You need to create at least one folder inside the <b>{$a}</b> directory so you can select it here.';
$string['pluginname_help'] = 'Create repository from local directory';
$string['pluginname'] = 'File system';
Expand Down
7 changes: 5 additions & 2 deletions repository/filesystem/lib.php
Expand Up @@ -70,7 +70,7 @@ public function get_listing($path = '', $page = '') {
$list['list'] = array();
// process breacrumb trail
$list['path'] = array(
array('name'=>'Root', 'path'=>'')
array('name'=>get_string('root', 'repository_filesystem'), 'path'=>'')
);
$trail = '';
if (!empty($path)) {
Expand Down Expand Up @@ -99,7 +99,8 @@ public function get_listing($path = '', $page = '') {
'title' => $file,
'source' => $path.'/'.$file,
'size' => filesize($this->root_path.$file),
'date' => time(),
'datecreated' => filectime($this->root_path.$file),
'datemodified' => filemtime($this->root_path.$file),
'thumbnail' => $OUTPUT->pix_url(file_extension_icon($this->root_path.$file, 32))->out(false)
);
} else {
Expand All @@ -111,6 +112,8 @@ public function get_listing($path = '', $page = '') {
$list['list'][] = array(
'title' => $file,
'children' => array(),
'datecreated' => filectime($this->root_path.$file),
'datemodified' => filemtime($this->root_path.$file),
'thumbnail' => $OUTPUT->pix_url('f/folder-32')->out(false),
'path' => $current_path
);
Expand Down
55 changes: 54 additions & 1 deletion repository/lib.php
Expand Up @@ -1780,7 +1780,60 @@ public function get_listing($path = '', $page = '') {
}

/**
* Search files in repository.
* Prepares list of files before passing it to AJAX, makes sure data is in the correct
* format and stores formatted dates.
*
* @param array $listing result of get_listing() or search()
* @return array
*/
public static function prepare_listing($listing) {
global $OUTPUT;
if (!is_array($listing) || !isset($listing['list'])) {
return $listing;
}
$len = count($listing['list']);
for ($i=0; $i<$len; $i++) {
if (isset($listing['list'][$i]['size'])) {
$listing['list'][$i]['size'] = (int)$listing['list'][$i]['size'];
$listing['list'][$i]['size_f'] = display_size($listing['list'][$i]['size']);
}
foreach (array('date', 'datemodified', 'datecreated') as $key) {
if (!isset($listing['list'][$i][$key]) && isset($listing['list'][$i]['date'])) {
$listing['list'][$i][$key] = $listing['list'][$i]['date'];
}
if (isset($listing['list'][$i][$key])) {
// must be UNIX timestamp
$listing['list'][$i][$key] = (int)$listing['list'][$i][$key];
if (!$listing['list'][$i][$key]) {
unset($listing['list'][$i][$key]);
} else {
$listing['list'][$i][$key.'_f'] = userdate($listing['list'][$i][$key], get_string('strftimedatetime', 'langconfig'));
$listing['list'][$i][$key.'_f_s'] = userdate($listing['list'][$i][$key], get_string('strftimedatetimeshort', 'langconfig'));
}
}
}
if (!isset($listing['list'][$i]['type']) && !array_key_exists('children', $listing['list'][$i]) && isset($listing['list'][$i]['title'])) {
$mimetype = mimeinfo('type', $listing['list'][$i]['title']);
if (get_string_manager()->string_exists($mimetype, 'mimetypes')) {
$mimetype = get_string($mimetype, 'mimetypes');
}
$listing['list'][$i]['type'] = $mimetype;
}
if (!isset($listing['list'][$i]['icon']) && isset($listing['list'][$i]['title'])) {
if (array_key_exists('children', $listing['list'][$i])) {
$listing['list'][$i]['icon'] = $OUTPUT->pix_url('f/folder')->out(false);
} else {
$listing['list'][$i]['icon'] = $OUTPUT->pix_url('f/'.mimeinfo('icon', $listing['list'][$i]['title']))->out(false);
}
}
}
return $listing;
}

/**
* Search files in repository
* When doing global search, $search_text will be used as
* keyword.
*
* @param string $search_text search key word
* @param int $page page
Expand Down
8 changes: 6 additions & 2 deletions repository/local/lib.php
Expand Up @@ -208,13 +208,17 @@ public function get_node() {
$encodedpath = base64_encode(serialize($this->fileinfo->get_params()));
$node = array(
'title' => $this->fileinfo->get_visible_name(),
'size' => 0,
'date' => '');
'datemodified' => $this->fileinfo->get_timemodified(),
'datecreated' => $this->fileinfo->get_timecreated()
);
if ($this->isdir) {
$node['path'] = $encodedpath;
$node['thumbnail'] = $OUTPUT->pix_url('f/folder-32')->out(false);
$node['children'] = array();
} else {
$node['size'] = $this->fileinfo->get_filesize();
$node['author'] = $this->fileinfo->get_author();
$node['license'] = $this->fileinfo->get_license();
$node['source'] = $encodedpath;
$node['thumbnail'] = $OUTPUT->pix_url(file_extension_icon($node['title'], 32))->out(false);
}
Expand Down

0 comments on commit 5bdf63c

Please sign in to comment.