Skip to content

Commit

Permalink
Add thumbnail view for folder list admin view (updated) (#1255)
Browse files Browse the repository at this point in the history
* Add thumbnail view for folder list admin view

* Cherry-pick changes from PR  1076

add thumbnail view for folder list admin view

cherry-pick changes from #1076

fix small details (js tests, isort, flake8)

maybe a solution to #723 ?

* Add trans tags to directory_thumbnail_list.html template

* Fix select all from all pages functionality on folder view

* Fixes after code review

* (re) compile css

* MAINT: update css for thumbnail view

* MAINT: use svg images

* FIX: replace old img tag by file_icon templatetag

Co-authored-by: Mateusz Kamycki <[email protected]>
  • Loading branch information
corentinbettiol and Mateusz Kamycki authored Jan 20, 2023
1 parent 672d00b commit 95cdf42
Show file tree
Hide file tree
Showing 17 changed files with 519 additions and 14 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,4 @@ pep8.txt
share/
.python-version
data
local.sqlite
6 changes: 5 additions & 1 deletion filer/admin/folderadmin.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@
from .permissions import PrimitivePermissionAwareModelAdmin
from .tools import (
AdminContext, admin_url_params_encoded, check_files_edit_permissions, check_files_read_permissions,
check_folder_edit_permissions, check_folder_read_permissions, popup_status, userperms_for_request,
check_folder_edit_permissions, check_folder_read_permissions, get_directory_listing_type, popup_status,
userperms_for_request,
)


Expand Down Expand Up @@ -406,6 +407,7 @@ def directory_listing(self, request, folder_id=None, viewtype=None):
except EmptyPage:
paginated_items = paginator.page(paginator.num_pages)

list_type = get_directory_listing_type(request) or settings.FILER_FOLDER_ADMIN_DEFAULT_LIST_TYPE
context = self.admin_site.each_context(request)
context.update({
'folder': folder,
Expand Down Expand Up @@ -436,6 +438,8 @@ def directory_listing(self, request, folder_id=None, viewtype=None):
'actions_selection_counter': self.actions_selection_counter,
'selection_note': _('0 of %(cnt)s selected') % {'cnt': len(paginated_items.object_list)},
'selection_note_all': selection_note_all % {'total_count': paginator.count},
'list_type': list_type,
'list_type_template': settings.FILER_FOLDER_ADMIN_LIST_TYPE_SWITCHER_SETTINGS[list_type]['template'],
'media': self.media,
'enable_permissions': settings.FILER_ENABLE_PERMISSIONS,
'can_make_folder': request.user.is_superuser or (folder.is_root and settings.FILER_ALLOW_REGULAR_USERS_TO_ADD_ROOT_FOLDERS) or permissions.get("has_add_children_permission"),
Expand Down
12 changes: 12 additions & 0 deletions filer/admin/tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
from django.core.exceptions import PermissionDenied
from django.utils.http import urlencode

from .. import settings


ALLOWED_PICK_TYPES = ('folder', 'file')

Expand Down Expand Up @@ -64,6 +66,13 @@ def popup_pick_type(request):
return None


def get_directory_listing_type(request):
list_type = request.GET.get('_list_type', None)
if list_type not in settings.FILER_FOLDER_ADMIN_LIST_TYPE_CHOICES:
return
return list_type


def admin_url_params(request, params=None):
"""
given a request, looks at GET and POST values to determine which params
Expand All @@ -75,6 +84,9 @@ def admin_url_params(request, params=None):
pick_type = popup_pick_type(request)
if pick_type:
params['_pick'] = pick_type
list_type = get_directory_listing_type(request)
if list_type and '_list_type' not in params.keys():
params['_list_type'] = list_type
return params


Expand Down
12 changes: 12 additions & 0 deletions filer/private/sass/components/_base.scss
Original file line number Diff line number Diff line change
Expand Up @@ -139,3 +139,15 @@ body {
box-shadow: 0 0 10px -2px rgba(black, 0.2);
background-color: $white;
}

.navigator .actions span.all,
.navigator .actions span.clear,
.navigator .actions span.question {
font-size: 13px;
margin: 0 0.5em;
display: none;
}

#all-items-action-toggle {
display: none !important;
}
138 changes: 137 additions & 1 deletion filer/private/sass/components/_navigator.scss
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,19 @@ body {
border-bottom: solid 2px $color-primary;
pointer-events: none;
z-index: 100;
display: none;
}

.thumbnail-drag-hover-border {
border: solid 2px $color-primary;
}
.filebrowser .navigator-list,
.filebrowser .navigator-table {
// required for django CMS <= 3.1 #673
width: 100%;
margin: 0;
border-top: solid 1px $gray-lighter !important;
border-collapse: collapse !important;
.navigator-header,
thead th,
tbody td {
text-align: left;
Expand All @@ -45,6 +50,7 @@ body {
color: $gray-darkest !important;
}
}
.navigator-body,
.unfiled td {
padding: 12px 5px !important;
background-color: $gray-super-light !important;
Expand Down Expand Up @@ -284,6 +290,7 @@ body {
width: calc(100% - 30px);
}
}

.navigator-tools {
@include clearfix;
white-space: nowrap;
Expand Down Expand Up @@ -340,6 +347,23 @@ body {
border-left: solid 1px $gray-lighter;
}
}
.filer-list-type-switcher-wrapper {
display: inline-block;
line-height: 34px;
vertical-align: middle;
padding: 0 15px;
border-left: 1px solid $gray-lighter;
border-right: 1px solid $gray-lighter;
margin-right: 10px;
a {
font-size: 17px;
color: $gray !important;
cursor: pointer;
}
@media screen and (max-width: $screen-tablet) {
margin-top: 10px;
}
}
}
@media screen and (max-width: $screen-tablet) {
.navigator-top-nav {
Expand Down Expand Up @@ -682,3 +706,115 @@ body {
display: table-cell;
vertical-align: middle;
}

.filebrowser .navigator-thumbnail-list {
overflow: hidden;
.navigator-list {
border-top: 0 !important;
}
.navigator-thumbnail-list-header {
& > * {
display: inline-block;
text-transform: uppercase;
margin: 0;
padding: 0;
padding-left: 10px;
}
.navigator-checkbox {
float: right;
text-transform: initial;
color: $color-primary;
input[type="checkbox"] {
margin-left: 5px;
vertical-align: middle;
}
}
}
.navigator-body {
@include clearfix;
padding: 0 !important;
}
.thumbnail-item {
float: left;
display: inline-block;
padding: 10px;
width: 125px;
height: 125px;
border: 1px solid $gray-lighter;
margin: 16px 12px;
background-color: $white;
position: relative;
overflow: hidden;
.thumbnail-file-item-box {
padding: 10px;
width: 125px;
height: 125px;
border: 1px solid $gray-lighter;
margin: 16px 12px;
background-color: $white;
&:hover {
background-color: #f1faff;
}
}
.navigator-checkbox {
position: absolute;
top: 5px;
left: 5px;
input {
margin: 0;
vertical-align: top;
}
}
.item-thumbnail,
.item-icon {
height: 50%;
width: 50%;
margin: 10px auto;
margin-bottom: 18px;
a {
display: block;
height: 100%;
width: 100%;
}
img {
width: 100%;
height: 100%;
}
}
.item-name {
background: transparent;
text-align: center;
word-break: break-word;
}
}
.thumbnail-virtual-item {
background-color: initial;
}
.thumbnail-folder-item {
&:hover {
background-color: #f1faff;
}
}
.thumbnail-file-item {
float: none;
width: 147px;
height: 200px;
border: 0;
padding: 0;
background-color: transparent;
.thumbnail-file-item-box {
float: none;
margin: 0;
margin-bottom: 5px;
}
.item-thumbnail {
margin: 0;
height: 100%;
width: 100%;
}
.item-name {
position: relative;
word-break: break-word;
}
}
}
24 changes: 24 additions & 0 deletions filer/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from django.conf import settings
from django.core.exceptions import ImproperlyConfigured
from django.core.files.storage import get_storage_class
from django.utils.translation import ugettext_lazy as _

from .utils.loader import load_object
from .utils.recursive_dictionary import RecursiveDictionaryWithExcludes
Expand Down Expand Up @@ -250,3 +251,26 @@ def update_server_settings(settings, defaults, s, t):
FILER_DUMP_PAYLOAD = getattr(settings, 'FILER_DUMP_PAYLOAD', False) # Whether the filer shall dump the files payload

FILER_CANONICAL_URL = getattr(settings, 'FILER_CANONICAL_URL', 'canonical/')

TABLE_LIST_TYPE = 'tb'
THUMBNAIL_LIST_TYPE = 'th'
FILER_FOLDER_ADMIN_LIST_TYPE_CHOICES = (
TABLE_LIST_TYPE,
THUMBNAIL_LIST_TYPE,
)
FILER_FOLDER_ADMIN_DEFAULT_LIST_TYPE = getattr(settings, 'FILER_FOLDER_ADMIN_DEFAULT_LIST_TYPE', TABLE_LIST_TYPE)
if FILER_FOLDER_ADMIN_DEFAULT_LIST_TYPE not in FILER_FOLDER_ADMIN_LIST_TYPE_CHOICES:
FILER_FOLDER_ADMIN_DEFAULT_LIST_TYPE = TABLE_LIST_TYPE

FILER_FOLDER_ADMIN_LIST_TYPE_SWITCHER_SETTINGS = {
TABLE_LIST_TYPE: {
'icon': 'th-list',
'tooltip_text': _('Show table view'),
'template': 'admin/filer/folder/directory_table_list.html',
},
THUMBNAIL_LIST_TYPE: {
'icon': 'th-large',
'tooltip_text': _('Show thumbnail view'),
'template': 'admin/filer/folder/directory_thumbnail_list.html',
},
}
2 changes: 1 addition & 1 deletion filer/static/filer/css/admin_filer.css

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion filer/static/filer/css/maps/admin_filer.css.map

Large diffs are not rendered by default.

10 changes: 7 additions & 3 deletions filer/static/filer/js/addons/table-dropzone.js
Original file line number Diff line number Diff line change
Expand Up @@ -129,12 +129,16 @@ if (django.jQuery) {
var folderTitle = $(dragEvent.target).closest(dropzoneSelector).data('folder-name');
var dropzoneFolder = dropzone.hasClass('js-filer-dropzone-folder');
var dropzoneBoundingRect = dropzone[0].getBoundingClientRect();
var borderSize = $('.drag-hover-border').css('border-top-width');
var topBorderSize = $('.drag-hover-border').css('border-top-width');
var leftBorderSize = $('.drag-hover-border').css('border-left-width');
var dropzonePosition = {
top: dropzoneBoundingRect.top,
bottom: dropzoneBoundingRect.bottom,
width: dropzoneBoundingRect.width,
height: dropzoneBoundingRect.height - (parseInt(borderSize, 10) * 2)
left: dropzoneBoundingRect.left,
right: dropzoneBoundingRect.right,
width: dropzoneBoundingRect.width - parseInt(leftBorderSize, 10) * 2,
height: dropzoneBoundingRect.height - parseInt(topBorderSize, 10) * 2,
display: 'block'
};
if (dropzoneFolder) {
dragHoverBorder.css(dropzonePosition);
Expand Down
60 changes: 57 additions & 3 deletions filer/static/filer/js/base.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,11 @@ Cl.mediator = new Mediator();

// show counter if file is selected
(function () {
var navigatorTable = $('.navigator-table').find('tr');
var navigatorTable = $('.navigator-table, .navigator-list').find('tr, .list-item');
var actionList = $('.actions-wrapper');
var actionSelect = $('.action-select, #action-toggle, .actions .clear a');
var actionSelect = $(
'.action-select, #action-toggle, #files-action-toggle, #folders-action-toggle, .actions .clear a'
);

// timeout is needed to wait until table row has class selected.
setTimeout(function () {
Expand Down Expand Up @@ -120,7 +122,7 @@ Cl.mediator = new Mediator();
var valueDelete = 'delete_files_or_folders';
var valueCopy = 'copy_files_and_folders';
var valueMove = 'move_files_and_folders';
var navigatorTable = $('.navigator-table').find('tr');
var navigatorTable = $('.navigator-table, .navigator-list').find('tr, .list-item');

// triggers delete copy and move actions on separate buttons
function actionsButton(optionValue, actionButton) {
Expand Down Expand Up @@ -206,5 +208,57 @@ Cl.mediator = new Mediator();
});

}());
// thumbnail folder admin view
(function () {
$(document).ready(function () {
var $actionEls = $('.navigator-list .list-item input.action-select'),
foldersActionCheckboxes = '.navigator-list .navigator-folders-body .list-item input.action-select',
filesActionCheckboxes = '.navigator-list .navigator-files-body .list-item input.action-select',
$allFilesToggle = $('#files-action-toggle'),
$allFoldersToggle = $('#folders-action-toggle');

if ($actionEls.length > 0) {
$actionEls.actions({
allToggle: '#all-items-action-toggle'
});
}

$allFoldersToggle.on('click', function () {
if (!!$(this).prop('checked')) {
$(foldersActionCheckboxes).filter(':not(:checked)').trigger('click');
} else {
$(foldersActionCheckboxes).filter(':checked').trigger('click');
}
});
$allFilesToggle.on('click', function () {
if (!!$(this).prop('checked')) {
$(filesActionCheckboxes).filter(':not(:checked)').trigger('click');
} else {
$(filesActionCheckboxes).filter(':checked').trigger('click');
}
});
$actionEls.on('click', function () {
if (!$(this).prop('checked')) {
if (!!$(filesActionCheckboxes).filter(':not(:checked)').length) {
$allFilesToggle.prop('checked', false);
}
if (!!$(foldersActionCheckboxes).filter(':not(:checked)').length) {
$allFoldersToggle.prop('checked', false);
}
} else {
if (!$(filesActionCheckboxes).filter(':not(:checked)').length) {
$allFilesToggle.prop('checked', true);
}
if (!$(foldersActionCheckboxes).filter(':not(:checked)').length) {
$allFoldersToggle.prop('checked', true);
}
}
});
$('.navigator .actions .clear a').on('click', function () {
$allFoldersToggle.prop('checked', false);
$allFilesToggle.prop('checked', false);
});
});
})();
});
})(djQuery);
Loading

0 comments on commit 95cdf42

Please sign in to comment.