Merge pull request #551 from bolt/files-as-cards

Files as cards
This commit is contained in:
Bob den Otter
2019-07-29 17:28:38 +02:00
committed by GitHub
14 changed files with 220 additions and 99 deletions

View File

@@ -26,14 +26,7 @@
:class="{ 'is-selected': size === 'small' }"
@click="changeSize('small')"
>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 70 55">
<g fill-rule="nonzero">
<rect width="70" height="10" rx="3" />
<rect width="70" height="10" rx="3" transform="translate(0 15)" />
<rect width="70" height="10" rx="3" transform="translate(0 30)" />
<rect width="70" height="10" rx="3" transform="translate(0 45)" />
</g>
</svg>
<i class="fas fa-align-justify fa-fw"></i> Compact
</button>
</li>
@@ -44,13 +37,7 @@
:class="{ 'is-selected': size === 'normal' }"
@click="changeSize('normal')"
>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 70 55">
<g fill-rule="nonzero">
<rect width="70" height="15" rx="3" />
<rect width="70" height="15" rx="3" transform="translate(0 20)" />
<rect width="70" height="15" rx="3" transform="translate(0 40)" />
</g>
</svg>
<i class="fas fa-grip-lines fa-fw"></i> Expanded
</button>
</li>

View File

@@ -37,6 +37,7 @@ code {
.card {
box-shadow: $card-box-shadow;
background: #fff;
border: 1px solid #E8E8E8 !important;
.card-header {
font-weight: $font-weight-bold;

View File

@@ -78,3 +78,6 @@
opacity: 0;
}
.filepond--root {
margin-bottom: 0 !important;
}

View File

@@ -58,6 +58,7 @@
border-radius: $border-radius;
box-shadow: $card-box-shadow;
padding: $spacer / 2;
font-size: 0.9rem;
&:hover {
cursor: pointer;
@@ -67,34 +68,16 @@
&:focus {
outline: none;
box-shadow: $input-btn-focus-box-shadow;
svg,
g {
fill: theme-color('secondary');
}
}
&.is-selected {
background: var(--primary);
svg g {
fill: var(--foreground);
}
background: $disabled;
}
&.is-active {
background: var(--primary);
color: var(--foreground);
}
svg {
width: 18px;
height: 18px;
g {
fill: var(--shade);
}
}
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

@@ -13,6 +13,7 @@ use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
use Symfony\Component\Finder\Finder;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\Routing\Annotation\Route;
use Webmozart\PathUtil\Path;
@@ -21,20 +22,20 @@ use Webmozart\PathUtil\Path;
*/
class FilemanagerController extends TwigAwareController implements BackendZone
{
/**
* @var FileLocations
*/
/** @var FileLocations */
private $fileLocations;
/**
* @var MediaRepository
*/
/** @var MediaRepository */
private $mediaRepository;
public function __construct(FileLocations $fileLocations, MediaRepository $mediaRepository)
/** @var SessionInterface */
private $session;
public function __construct(FileLocations $fileLocations, MediaRepository $mediaRepository, SessionInterface $session)
{
$this->fileLocations = $fileLocations;
$this->mediaRepository = $mediaRepository;
$this->session = $session;
}
/**
@@ -47,6 +48,13 @@ class FilemanagerController extends TwigAwareController implements BackendZone
$path .= '/';
}
if ($request->query->get('view')) {
$view = $request->query->get('view') === 'cards' ? 'cards' : 'list';
$this->session->set('filemanager_view', $view);
} else {
$view = $this->session->get('filemanager_view', 'list');
}
$location = $this->fileLocations->get($location);
$finder = $this->findFiles($location->getBasepath(), $path);
@@ -63,6 +71,7 @@ class FilemanagerController extends TwigAwareController implements BackendZone
'parent' => $parent,
'media' => $media,
'allfiles' => $location->isShowAll() ? $this->buildIndex($location->getBasepath()) : false,
'view' => $view,
]);
}

View File

@@ -95,7 +95,7 @@ class ImageExtension extends AbstractExtension
return sprintf('<img src="%s" alt="%s" %s %s>', $link, $alt, (string) $width, (string) $height);
}
public function thumbnail($image, int $width = 320, int $height = 240, ?string $location = null, ?string $path = null)
public function thumbnail($image, int $width = 320, int $height = 240, ?string $location = null, ?string $path = null, ?string $fit = null)
{
$filename = $this->getFilename($image);
@@ -114,6 +114,9 @@ class ImageExtension extends AbstractExtension
if ($path) {
$params['path'] = $path;
}
if ($fit) {
$params['fit'] = $fit;
}
// Create an instance of the URL builder
$urlBuilder = UrlBuilderFactory::create('/thumbs/', $this->secret);

View File

@@ -16,7 +16,7 @@ class Html
*
* @return string Trimmed string
*/
public static function trimText(string $str, int $desiredLength, bool $hellip = true, int $cutOffCap = 10): string
public static function trimText(string $str, int $desiredLength, bool $hellip = true, int $cutOffCap = 3): string
{
if ($hellip) {
$ellipseStr = ' …';

View File

@@ -0,0 +1,117 @@
<div class="row">
{% for file in finder.files() %}
{% set extension = file.extension() %}
{% set filename = path ~ file.getRelativePathname() %}
{% set icon = 'fa-file' %}
{% set link = path('bolt_file_edit', {'location': location, 'file': filename }) %}
{% set thumbnail = '' %}
{% set title = '' %}
{% set dimensions = '' %}
{% if extension in imageformats %}
{% set thumbnail = filename|thumbnail(width = 400, height = 300, location = location, fit = 'crop') %}
{% set icon = 'fa-image' %}
{% set link = path('bolt_media_new', {'location': location, 'file': filename}) %}
{% for image in media|default([]) if image.filename in filename %}
{% set title = image.title %}
{% set dimensions = image.width ~ ' × ' ~ image.height ~ 'px' %}
{% set link = path('bolt_media_edit', {'id': image.id}) %}
{% endfor %}
{% endif %}
<div class="col-6 col-sm-4 col-xl-3 pr-0 pb-3">
<div class="card">
{%- if thumbnail -%}
<a href="{{ filename|thumbnail(width = 1000, height = 1000, location = location) }}" class="lightbox">
<img src="{{ thumbnail }}" class="card-img-top">
</a>
{% else %}
<img src="{{ asset('assets/images/placeholder.png', 'public') }}" class="card-img-top">
{%- endif -%}
<div class="card-body p-2">
<a href="{{ link }}" style="font-size: 85%;">{{ file.getRelativePathname|excerpt(15) }}</a>
<div class="btn-group float-right">
<button
type="button"
class="btn btn-sm btn-secondary edit-actions__dropdown-toggler dropdown-toggle dropdown-toggle-split"
data-toggle="dropdown"
aria-haspopup="true"
aria-expanded="false"
>
<i class="fas fa-question-circle"></i>
<span class="sr-only">Toggle Dropdown</span>
</button>
<div class="edit-actions__dropdown dropdown-menu dropdown-menu-right" style="width: 320px;">
<a class="dropdown-item" href="{{ link }}" target="_blank">
<i class="fas fa-w fa-edit"></i>
{% if extension in imageformats %}
Edit image information
{% else %}
Edit file in editor
{% endif %}
</a>
<a class="dropdown-item" href="{{ asset(file.filename, 'files') }}" target="_blank">
<i class="fas fa-w fa-external-link-square-alt"></i>
View original
</a>
<a class="dropdown-item" href="#">
<i class="far fa-w fa-copy"></i>
Duplicate {{ file.getRelativePathname|excerpt(22) }}
</a>
<a class="dropdown-item" href="#" data-confirmation="Are you sure you wish to delete this Content?">
<i class="fas fa-w fa-trash"></i>
Delete {{ file.getRelativePathname|excerpt(22) }}
</a>
<div class="dropdown-divider"></div>
<span class="dropdown-item-text">
<i class="fas fa-link fa-w"></i>
Filename: <code :title="file.fieldValues.slug">{{ file.getRelativePathname }}</code>
</span>
{% if title %}
<span class="dropdown-item-text">
<i class="fas fa-asterisk fa-w"></i>
Title: {{ title }}
</span>
{% endif %}
{% if dimensions %}
<span class="dropdown-item-text">
<i class="fas fa-asterisk fa-w"></i>
Dimensions: {{ dimensions }}
</span>
{% endif %}
<span class="dropdown-item-text">
<i class="fas fa-asterisk fa-w"></i>
Filesize: {{ file.getSize() }}&nbsp;bytes
</span>
<span class="dropdown-item-text">
<i class="far fa-calendar-alt fa-w"></i>
Created on: <strong>{{ file.getCTime()|localizeddate('short', 'short', null, 'UTC') }}</strong>
</span>
</div>
</div>
</div>
</div>
</div>
{% else %}
<div class="col-12">
<p><strong>No files are present in this folder. Select a folder to navigate to, on the right-hand side.</strong></p>
</div>
{% endfor %}
</div>

View File

@@ -10,9 +10,6 @@
<th>{{ 'actions'|trans }}</th>
</tr>
</thead>
{% set imageformats = ['gif', 'jpg', 'jpeg', 'png', 'svg'] %}
{% for file in finder.files() %}
{% set extension = file.extension() %}
@@ -24,7 +21,7 @@
{% set dimensions = '' %}
{% if extension in imageformats %}
{% set thumbnail = filename|thumbnail(width = 100, height = 72, location = location) %}
{% set thumbnail = filename|thumbnail(width = 100, height = 72, location = location, fit = 'crop') %}
{% set icon = 'fa-image' %}
{% set link = path('bolt_media_new', {'location': location, 'file': filename}) %}
@@ -47,7 +44,7 @@
</td>
<td class="listing-thumb" style="padding: 0.2em;">
{%- if thumbnail -%}
<a href="{{ filename|thumbnail(width = 1000, height = 1000, location = location) }}" class="lightbox">
<a href="{{ filename|thumbnail(width = 1000, height = 1000, location = location, fit = 'crop') }}" class="lightbox">
<img src="{{ thumbnail }}" width="100" height="72">
</a>
{%- else -%}
@@ -65,5 +62,11 @@
&nbsp;
</td>
</tr>
{% else %}
<tr>
<td colspan="6">
<p><strong>No files are present in this folder. Select a folder to navigate to, on the right-hand side.</strong></p>
</td>
</tr>
{% endfor %}
</table>

View File

@@ -1,41 +1,52 @@
<table class="table table-striped" style="background-color: #FFF;">
<thead class="thead-light">
<tr>
<th></th>
<th>{{ 'directoryname'|trans }}</th>
<th>{{ 'actions'|trans }}</th>
</tr>
</thead>
{% if path != '/' %}
<tr>
<td><i class="fas fa-folder-open"></i></td>
<td>
<b>
<a href="{{ path('bolt_filemanager', {'location': location, 'path': parent }) }}">
../
</a>
</b>
</td>
<td>
</td>
</tr>
{% endif %}
<div class="card mb-4">
<div class="card-header">
<i class="fas fa-folder"></i>
{{ 'caption.folders'|trans }}
</div>
<div class="card-body" style="padding: 0.5rem 0.5rem 0">
{% for directory in finder.directories() %}
<tr>
<td><i class="fas fa-folder"></i></td>
<td>
<b>
{% set dirname = path ~ directory.getRelativePathname() %}
<a href="{{ path('bolt_filemanager', {'location': location, 'path': dirname }) }}">
{{ directory.getRelativePathname }}/
</a>
</b>
</td>
<td>
</td>
</tr>
{% endfor %}
</table>
<table class="table table-striped" style="background-color: #FFF;">
<thead class="thead-light">
<tr>
<th></th>
<th>{{ 'directoryname'|trans }}</th>
<th>{{ 'actions'|trans }}</th>
</tr>
</thead>
{% if path != '/' %}
<tr>
<td><i class="fas fa-folder-open"></i></td>
<td>
<b>
<a href="{{ path('bolt_filemanager', {'location': location, 'path': parent }) }}">
../
</a>
</b>
</td>
<td>
</td>
</tr>
{% endif %}
{% for directory in finder.directories() %}
<tr>
<td><i class="fas fa-folder"></i></td>
<td>
<b>
{% set dirname = path ~ directory.getRelativePathname() %}
<a href="{{ path('bolt_filemanager', {'location': location, 'path': dirname }) }}">
{{ directory.getRelativePathname }}/
</a>
</b>
</td>
<td>
</td>
</tr>
{% endfor %}
</table>
</div>
</div>

View File

@@ -6,13 +6,15 @@
{% block main %}
<h2>{{ 'caption.path'|trans }}: {{ location }}{{ path }}</h2>
{% include '@bolt/finder/_quickselect.html.twig' %}
{% include '@bolt/finder/_folders.html.twig' %}
{% set imageformats = ['gif', 'jpg', 'jpeg', 'png', 'svg'] %}
{% include '@bolt/finder/_files.html.twig' %}
{% if view == 'list' %}
{% include '@bolt/finder/_files_list.html.twig' %}
{% else %}
{% include '@bolt/finder/_files_cards.html.twig' %}
{% endif %}
{% endblock %}
@@ -21,20 +23,22 @@
<div class="card mb-4">
<div class="card-header">{{ 'caption.meta_information'|trans }}</div>
<div class="card-body">
<p class="path">{{ 'caption.path'|trans }}: <code>{{ location }}{{ path }}</code></p>
View:
<div class="btn-group">
<a href="{{ path('bolt_filemanager', {'location': location, 'path': path, 'view': 'list' }) }}" class="btn btn-secondary"><i class="fas fa-list fa-fw"></i> List</a>
<a href="{{ path('bolt_filemanager', {'location': location, 'path': path, 'view': 'cards' }) }}" class="btn btn-secondary ml-1"><i class="fas fa-th fa-fw"></i>Cards</a>
</div>
</div>
</div>
{% include '@bolt/finder/_folders.html.twig' %}
{% include '@bolt/finder/_uploader.html.twig' %}
{% endblock aside %}
{% block stylesheets %}
{{ parent() }}
<style>
.filepond--root {
margin-bottom: 0 !important;
}
</style>
{% endblock %}

View File

@@ -7,13 +7,13 @@ Feature: Filemanager
| area | themes |
Then there is element "header" with text "Theme files"
And there is element "title" with text "Path: themes/"
And there is element "path" with text "Path: themes/"
When I visit the "filemanager" page with parameters:
| area | files |
Then there is element "header" with text "Content files"
And there is element "title" with text "Path: files/"
And there is element "path" with text "Path: files/"
# @todo Add tests for uploading files, and verifying that they're there

View File

@@ -7,7 +7,7 @@ class FilemanagerPage extends BasePage {
this.url = '/bolt/filemanager/:area';
this.header = $('.admin__header--title');
this.title = $('h2');
this.path = $('p.path');
}
}