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": []
|
"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/string": "6.0.*",
|
||||||
"symfony/translation": "6.0.*",
|
"symfony/translation": "6.0.*",
|
||||||
"symfony/twig-bundle": "6.0.*",
|
"symfony/twig-bundle": "6.0.*",
|
||||||
|
"symfony/ux-dropzone": "^2.1",
|
||||||
"symfony/validator": "6.0.*",
|
"symfony/validator": "6.0.*",
|
||||||
"symfony/web-link": "6.0.*",
|
"symfony/web-link": "6.0.*",
|
||||||
"symfony/webapp-meta": "^1.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",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "2eef8acf0a01cf89e1edb8087c4d2ac3",
|
"content-hash": "38958ff5221180c36bc97324f82755b6",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "doctrine/annotations",
|
"name": "doctrine/annotations",
|
||||||
@@ -7460,6 +7460,86 @@
|
|||||||
],
|
],
|
||||||
"time": "2022-04-03T13:04:20+00:00"
|
"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",
|
"name": "symfony/validator",
|
||||||
"version": "v6.0.8",
|
"version": "v6.0.8",
|
||||||
|
|||||||
@@ -6,6 +6,9 @@
|
|||||||
parameters:
|
parameters:
|
||||||
book_covers: '%kernel.project_dir%/public/book_covers/'
|
book_covers: '%kernel.project_dir%/public/book_covers/'
|
||||||
book_files: '%kernel.project_dir%/public/book_files/'
|
book_files: '%kernel.project_dir%/public/book_files/'
|
||||||
|
api_pass: 'secret_password'
|
||||||
|
api_user: 'my_name'
|
||||||
|
bankAccount: '1093849023/2013'
|
||||||
|
|
||||||
services:
|
services:
|
||||||
# default configuration for services in *this* file
|
# default configuration for services in *this* file
|
||||||
@@ -13,6 +16,8 @@ services:
|
|||||||
autowire: true # Automatically injects dependencies in your services.
|
autowire: true # Automatically injects dependencies in your services.
|
||||||
autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.
|
autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# makes classes in src/ available to be used as services
|
# makes classes in src/ available to be used as services
|
||||||
# this creates a service per class whose id is the fully-qualified class name
|
# this creates a service per class whose id is the fully-qualified class name
|
||||||
App\:
|
App\:
|
||||||
@@ -22,5 +27,9 @@ services:
|
|||||||
- '../src/Entity/'
|
- '../src/Entity/'
|
||||||
- '../src/Kernel.php'
|
- '../src/Kernel.php'
|
||||||
|
|
||||||
|
App\Service\FileService:
|
||||||
|
arguments:
|
||||||
|
$bookFiles: '%book_files%'
|
||||||
|
|
||||||
# add more service definitions when explicit configuration is needed
|
# add more service definitions when explicit configuration is needed
|
||||||
# please note that last definitions always *replace* previous ones
|
# please note that last definitions always *replace* previous ones
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@hotwired/stimulus": "^3.0.0",
|
"@hotwired/stimulus": "^3.0.0",
|
||||||
"@symfony/stimulus-bridge": "^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",
|
"@symfony/webpack-encore": "^2.0.0",
|
||||||
"axios": "^0.27.2",
|
"axios": "^0.27.2",
|
||||||
"core-js": "^3.0.0",
|
"core-js": "^3.0.0",
|
||||||
|
|||||||
@@ -44,9 +44,9 @@ class FileController extends AbstractController
|
|||||||
public function get(File $file)
|
public function get(File $file)
|
||||||
{
|
{
|
||||||
return $this->file(
|
return $this->file(
|
||||||
$filePath = $this->getParameter('book_files') . '/' . 'ebook_' . $file->getBook()->getId() . '_' .
|
$this->getParameter('book_files') . '/' . 'ebook_' . $file->getBook()->getId() . '_' .
|
||||||
md5($file->getFileName()) . '.' .
|
md5($file->getFileName()) . '.' .
|
||||||
$file->getExtension(),
|
$file->getExtension(),
|
||||||
$file->getFileName()
|
$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"
|
"./templates/base.html.twig"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"symfony/ux-dropzone": {
|
||||||
|
"version": "v2.1.1"
|
||||||
|
},
|
||||||
"symfony/validator": {
|
"symfony/validator": {
|
||||||
"version": "6.0",
|
"version": "6.0",
|
||||||
"recipe": {
|
"recipe": {
|
||||||
|
|||||||
@@ -7,7 +7,6 @@
|
|||||||
|
|
||||||
{{ include('book/_form.html.twig', {'button_label': 'Update'}) }}
|
{{ include('book/_form.html.twig', {'button_label': 'Update'}) }}
|
||||||
|
|
||||||
<a href="{{ path('app_book_index') }}">back to list</a>
|
|
||||||
|
|
||||||
{{ include('book/_delete_form.html.twig') }}
|
{{ include('book/_delete_form.html.twig') }}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
@@ -3,29 +3,40 @@
|
|||||||
{% block title %}Book index{% endblock %}
|
{% block title %}Book index{% endblock %}
|
||||||
|
|
||||||
{% block body %}
|
{% 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">
|
<table class="table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Cover</th>
|
<th>Cover</th>
|
||||||
<th>Id</th>
|
<th>Id</th>
|
||||||
<th>Title</th>
|
<th>Title</th>
|
||||||
<th>Language</th>
|
<th>Language</th>
|
||||||
<th>Description</th>
|
<th>Description</th>
|
||||||
<th>Publisher</th>
|
<th>Publisher</th>
|
||||||
<th>Publish_date</th>
|
<th>Publish_date</th>
|
||||||
<th>actions</th>
|
<th>actions</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for book in books %}
|
{% for book in books %}
|
||||||
<tr>
|
<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.id }}</td>
|
||||||
<td>{{ book.Title }}</td>
|
<td>{{ book.Title }}</td>
|
||||||
<td>{{ book.language }}</td>
|
<td>{{ book.language }}</td>
|
||||||
<td>{{ book.description }}</td>
|
<td>{{ book.description | slice(0, 200) }}</td>
|
||||||
<td>{{ book.publisher }}</td>
|
<td>{{ book.publisher }}</td>
|
||||||
<td>{{ book.publishDate ? book.publishDate|date('Y-m-d') : '' }}</td>
|
<td>{{ book.publishDate ? book.publishDate|date('Y-m-d') : '' }}</td>
|
||||||
<td>
|
<td>
|
||||||
@@ -40,6 +51,4 @@
|
|||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<a href="{{ path('app_book_new') }}">Create new</a>
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
@@ -9,7 +9,6 @@
|
|||||||
{{ include('book/_form.html.twig') }}
|
{{ include('book/_form.html.twig') }}
|
||||||
</book>
|
</book>
|
||||||
</div>
|
</div>
|
||||||
<a href="{{ path('app_book_index') }}">back to list</a>
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block javascripts %}
|
{% block javascripts %}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Description</th>
|
<th>Description</th>
|
||||||
<td>{{ book.description }}</td>
|
<td>{{ book.description | nl2br }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Publisher</th>
|
<th>Publisher</th>
|
||||||
@@ -39,7 +39,7 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<th>Id</th>
|
<th>Id</th>
|
||||||
<th>File name</th>
|
<th>File name</th>
|
||||||
<th>File size</th>
|
<th class="text-end">File size</th>
|
||||||
<th>Extension</th>
|
<th>Extension</th>
|
||||||
<th>Download</th>
|
<th>Download</th>
|
||||||
<th>Remove</th>
|
<th>Remove</th>
|
||||||
@@ -50,7 +50,7 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<td>{{ file.id }}</td>
|
<td>{{ file.id }}</td>
|
||||||
<td>{{ file.fileName }}</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>{{ 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_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>
|
<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"
|
loader-utils "^2.0.0"
|
||||||
schema-utils "^3.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":
|
"@symfony/webpack-encore@^2.0.0":
|
||||||
version "2.1.0"
|
version "2.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/@symfony/webpack-encore/-/webpack-encore-2.1.0.tgz#353a1b8bc38022046cbbc3d627c4076aca2e28c3"
|
resolved "https://registry.yarnpkg.com/@symfony/webpack-encore/-/webpack-encore-2.1.0.tgz#353a1b8bc38022046cbbc3d627c4076aca2e28c3"
|
||||||
|
|||||||
Reference in New Issue
Block a user