Styled book form and added an ux dropzone component.
This commit is contained in:
@@ -1,4 +1,14 @@
|
||||
{
|
||||
"controllers": [],
|
||||
"controllers": {
|
||||
"@symfony/ux-dropzone": {
|
||||
"dropzone": {
|
||||
"enabled": true,
|
||||
"fetch": "eager",
|
||||
"autoimport": {
|
||||
"@symfony/ux-dropzone/src/style.css": true
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"entrypoints": []
|
||||
}
|
||||
|
||||
36
assets/controllers/mydropzone_controller.js
Normal file
36
assets/controllers/mydropzone_controller.js
Normal file
@@ -0,0 +1,36 @@
|
||||
// mydropzone_controller.js
|
||||
|
||||
import { Controller } from '@hotwired/stimulus';
|
||||
|
||||
export default class extends Controller {
|
||||
connect() {
|
||||
this.element.addEventListener('dropzone:connect', this._onConnect);
|
||||
this.element.addEventListener('dropzone:change', this._onChange);
|
||||
this.element.addEventListener('dropzone:clear', this._onClear);
|
||||
}
|
||||
|
||||
disconnect() {
|
||||
// You should always remove listeners when the controller is disconnected to avoid side-effects
|
||||
this.element.removeEventListener('dropzone:connect', this._onConnect);
|
||||
this.element.removeEventListener('dropzone:change', this._onChange);
|
||||
this.element.removeEventListener('dropzone:clear', this._onClear);
|
||||
}
|
||||
|
||||
_onConnect(event) {
|
||||
// The dropzone was just created
|
||||
console.info(event);
|
||||
console.info('onconnect');
|
||||
}
|
||||
|
||||
_onChange(event) {
|
||||
// The dropzone just changed
|
||||
console.info(event);
|
||||
console.info('onchange');
|
||||
}
|
||||
|
||||
_onClear(event) {
|
||||
// The dropzone has just been cleared
|
||||
console.info(event);
|
||||
console.info('onclear');
|
||||
}
|
||||
}
|
||||
@@ -39,6 +39,7 @@
|
||||
"symfony/string": "6.0.*",
|
||||
"symfony/translation": "6.0.*",
|
||||
"symfony/twig-bundle": "6.0.*",
|
||||
"symfony/ux-dropzone": "^2.1",
|
||||
"symfony/validator": "6.0.*",
|
||||
"symfony/web-link": "6.0.*",
|
||||
"symfony/webapp-meta": "^1.0",
|
||||
|
||||
82
composer.lock
generated
82
composer.lock
generated
@@ -4,7 +4,7 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "2eef8acf0a01cf89e1edb8087c4d2ac3",
|
||||
"content-hash": "38958ff5221180c36bc97324f82755b6",
|
||||
"packages": [
|
||||
{
|
||||
"name": "doctrine/annotations",
|
||||
@@ -7460,6 +7460,86 @@
|
||||
],
|
||||
"time": "2022-04-03T13:04:20+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/ux-dropzone",
|
||||
"version": "v2.1.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/ux-dropzone.git",
|
||||
"reference": "e5115ed7fc894248b77bffebb7f57bc2f584d219"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/ux-dropzone/zipball/e5115ed7fc894248b77bffebb7f57bc2f584d219",
|
||||
"reference": "e5115ed7fc894248b77bffebb7f57bc2f584d219",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.2.5",
|
||||
"symfony/config": "^4.4.17|^5.0|^6.0",
|
||||
"symfony/dependency-injection": "^4.4.17|^5.0|^6.0",
|
||||
"symfony/form": "^4.4.17|^5.0|^6.0",
|
||||
"symfony/http-kernel": "^4.4.17|^5.0|^6.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/framework-bundle": "^4.4.17|^5.0|^6.0",
|
||||
"symfony/phpunit-bridge": "^5.2|^6.0",
|
||||
"symfony/twig-bundle": "^4.4.17|^5.0|^6.0",
|
||||
"symfony/var-dumper": "^4.4.17|^5.0|^6.0"
|
||||
},
|
||||
"type": "symfony-bundle",
|
||||
"extra": {
|
||||
"thanks": {
|
||||
"name": "symfony/ux",
|
||||
"url": "https://github.com/symfony/ux"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Symfony\\UX\\Dropzone\\": ""
|
||||
},
|
||||
"exclude-from-classmap": [
|
||||
"/Tests/"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Titouan Galopin",
|
||||
"email": "galopintitouan@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "File input dropzones for Symfony Forms",
|
||||
"homepage": "https://symfony.com",
|
||||
"keywords": [
|
||||
"symfony-ux"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/ux-dropzone/tree/v2.1.1"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2022-02-01T04:57:29+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/validator",
|
||||
"version": "v6.0.8",
|
||||
|
||||
@@ -6,6 +6,9 @@
|
||||
parameters:
|
||||
book_covers: '%kernel.project_dir%/public/book_covers/'
|
||||
book_files: '%kernel.project_dir%/public/book_files/'
|
||||
api_pass: 'secret_password'
|
||||
api_user: 'my_name'
|
||||
bankAccount: '1093849023/2013'
|
||||
|
||||
services:
|
||||
# default configuration for services in *this* file
|
||||
@@ -13,6 +16,8 @@ services:
|
||||
autowire: true # Automatically injects dependencies in your services.
|
||||
autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.
|
||||
|
||||
|
||||
|
||||
# makes classes in src/ available to be used as services
|
||||
# this creates a service per class whose id is the fully-qualified class name
|
||||
App\:
|
||||
@@ -22,5 +27,9 @@ services:
|
||||
- '../src/Entity/'
|
||||
- '../src/Kernel.php'
|
||||
|
||||
App\Service\FileService:
|
||||
arguments:
|
||||
$bookFiles: '%book_files%'
|
||||
|
||||
# add more service definitions when explicit configuration is needed
|
||||
# please note that last definitions always *replace* previous ones
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
"devDependencies": {
|
||||
"@hotwired/stimulus": "^3.0.0",
|
||||
"@symfony/stimulus-bridge": "^3.0.0",
|
||||
"@symfony/ux-dropzone": "file:vendor/symfony/ux-dropzone/Resources/assets",
|
||||
"@symfony/webpack-encore": "^2.0.0",
|
||||
"axios": "^0.27.2",
|
||||
"core-js": "^3.0.0",
|
||||
|
||||
@@ -44,9 +44,9 @@ class FileController extends AbstractController
|
||||
public function get(File $file)
|
||||
{
|
||||
return $this->file(
|
||||
$filePath = $this->getParameter('book_files') . '/' . 'ebook_' . $file->getBook()->getId() . '_' .
|
||||
md5($file->getFileName()) . '.' .
|
||||
$file->getExtension(),
|
||||
$this->getParameter('book_files') . '/' . 'ebook_' . $file->getBook()->getId() . '_' .
|
||||
md5($file->getFileName()) . '.' .
|
||||
$file->getExtension(),
|
||||
$file->getFileName()
|
||||
);
|
||||
}
|
||||
|
||||
36
src/Service/FileService.php
Normal file
36
src/Service/FileService.php
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace App\Service;
|
||||
|
||||
use App\Entity\File;
|
||||
use App\Repository\FileRepository;
|
||||
use Doctrine\Common\Collections\Collection;
|
||||
use Symfony\Component\Filesystem\Filesystem;
|
||||
|
||||
class FileService
|
||||
{
|
||||
private Filesystem $fileSystem;
|
||||
private string $bookFiles;
|
||||
|
||||
public function __construct(string $bookFiles, FileSystem $filesystem)
|
||||
{
|
||||
$this->bookFiles = $bookFiles;
|
||||
$this->fileSystem = $filesystem;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param File[] $files
|
||||
* @return void
|
||||
*/
|
||||
public function removeFiles(Collection $files)
|
||||
{
|
||||
foreach ($files as $file) {
|
||||
$filePath = $this->bookFiles . '/' . 'ebook_' . $file->getBook()->getId() . '_' .
|
||||
md5($file->getFileName()) . '.' .
|
||||
$file->getExtension();
|
||||
|
||||
$this->fileSystem->remove($filePath);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -462,6 +462,9 @@
|
||||
"./templates/base.html.twig"
|
||||
]
|
||||
},
|
||||
"symfony/ux-dropzone": {
|
||||
"version": "v2.1.1"
|
||||
},
|
||||
"symfony/validator": {
|
||||
"version": "6.0",
|
||||
"recipe": {
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
|
||||
{{ include('book/_form.html.twig', {'button_label': 'Update'}) }}
|
||||
|
||||
<a href="{{ path('app_book_index') }}">back to list</a>
|
||||
|
||||
{{ include('book/_delete_form.html.twig') }}
|
||||
{% endblock %}
|
||||
|
||||
@@ -3,29 +3,40 @@
|
||||
{% block title %}Book index{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<h1>Book index</h1>
|
||||
<div class="d-flex flex-row justify-content-between align-items-center">
|
||||
<div>
|
||||
<h1>Book index</h1>
|
||||
</div>
|
||||
<div>
|
||||
<a href="{{ path('app_book_new') }}" class="btn btn-primary">Create new</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Cover</th>
|
||||
<th>Id</th>
|
||||
<th>Title</th>
|
||||
<th>Language</th>
|
||||
<th>Description</th>
|
||||
<th>Publisher</th>
|
||||
<th>Publish_date</th>
|
||||
<th>actions</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Cover</th>
|
||||
<th>Id</th>
|
||||
<th>Title</th>
|
||||
<th>Language</th>
|
||||
<th>Description</th>
|
||||
<th>Publisher</th>
|
||||
<th>Publish_date</th>
|
||||
<th>actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for book in books %}
|
||||
<tr>
|
||||
<td>{% if file_exists(asset('book_covers/cover_' ~ book.id ~ '.jpg')) %}<img class="img-thumbnail" style="max-width: 80px" src="{{ asset('book_covers/cover_' ~ book.id ~ '.jpg' ) }}" /> {% endif %}</td>
|
||||
<td>{% if file_exists(asset('book_covers/cover_' ~ book.id ~ '.jpg')) %}<img class="img-thumbnail"
|
||||
style="max-width: 80px"
|
||||
src="{{ asset('book_covers/cover_' ~ book.id ~ '.jpg' ) }}" /> {% endif %}
|
||||
</td>
|
||||
<td>{{ book.id }}</td>
|
||||
<td>{{ book.Title }}</td>
|
||||
<td>{{ book.language }}</td>
|
||||
<td>{{ book.description }}</td>
|
||||
<td>{{ book.description | slice(0, 200) }}</td>
|
||||
<td>{{ book.publisher }}</td>
|
||||
<td>{{ book.publishDate ? book.publishDate|date('Y-m-d') : '' }}</td>
|
||||
<td>
|
||||
@@ -40,6 +51,4 @@
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<a href="{{ path('app_book_new') }}">Create new</a>
|
||||
{% endblock %}
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
{{ include('book/_form.html.twig') }}
|
||||
</book>
|
||||
</div>
|
||||
<a href="{{ path('app_book_index') }}">back to list</a>
|
||||
{% endblock %}
|
||||
|
||||
{% block javascripts %}
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Description</th>
|
||||
<td>{{ book.description }}</td>
|
||||
<td>{{ book.description | nl2br }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Publisher</th>
|
||||
@@ -39,7 +39,7 @@
|
||||
<tr>
|
||||
<th>Id</th>
|
||||
<th>File name</th>
|
||||
<th>File size</th>
|
||||
<th class="text-end">File size</th>
|
||||
<th>Extension</th>
|
||||
<th>Download</th>
|
||||
<th>Remove</th>
|
||||
@@ -50,7 +50,7 @@
|
||||
<tr>
|
||||
<td>{{ file.id }}</td>
|
||||
<td>{{ file.fileName }}</td>
|
||||
<td>{{ file.fileSize | bytes_format }}</td>
|
||||
<td class="text-end">{{ file.fileSize | bytes_format }}</td>
|
||||
<td>{{ file.extension }}</td>
|
||||
<td><a href="{{ path('app_file_download', {id: file.id }) }}" class="link-secondary">download</a></td>
|
||||
<td><a href="{{ path('app_file_delete', {id: file.id}) }}" class="link-danger">remove</a></td>
|
||||
|
||||
@@ -1008,6 +1008,9 @@
|
||||
loader-utils "^2.0.0"
|
||||
schema-utils "^3.0.0"
|
||||
|
||||
"@symfony/ux-dropzone@file:vendor/symfony/ux-dropzone/Resources/assets":
|
||||
version "1.1.0"
|
||||
|
||||
"@symfony/webpack-encore@^2.0.0":
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@symfony/webpack-encore/-/webpack-encore-2.1.0.tgz#353a1b8bc38022046cbbc3d627c4076aca2e28c3"
|
||||
|
||||
Reference in New Issue
Block a user