Show a preview image in builtin attachment select autocomplete.

This commit is contained in:
Jan Böhmer 2020-06-01 14:51:38 +02:00
parent aa95f130db
commit f0d0a78f65
6 changed files with 65 additions and 6 deletions

View file

@ -772,6 +772,9 @@ div.dataTables_wrapper div.dataTables_info {
-webkit-box-shadow: 0 5px 10px rgba(0,0,0,.2);
-moz-box-shadow: 0 5px 10px rgba(0,0,0,.2);
box-shadow: 0 5px 10px rgba(0,0,0,.2);
max-height: 200px;
overflow-y: auto;
}
.tt-suggestion {
@ -875,3 +878,10 @@ div.dataTables_wrapper div.dataTables_info {
.carousel:hover .carousel-control {
display: flex;
}
/***********************************************
* Typeahead image
***********************************************/
.typeahead-image {
width: 100%;
}

View file

@ -432,6 +432,7 @@ $(document).on("ajaxUI:reload ajaxUI:start attachment:create", function () {
}
});
//@ts-ignore
$(this).typeahead({
hint: true,
highlight: true,
@ -439,7 +440,18 @@ $(document).on("ajaxUI:reload ajaxUI:start attachment:create", function () {
},
{
name: 'states',
source: engine
source: engine,
limit: 250,
templates: {
suggestion: function(data) {
if (typeof data === "string") {
return "<div>" + data + "</div>";
} else if(typeof data === "object" && typeof data.image === "string") {
return "<div class='row m-0'><div class='col-2 pl-0 pr-1'><img class='typeahead-image' src='" + data.image + "'/></div><div class='col-10'>" + data.name + "</div></div>"
}
},
},
display: 'name',
});
//Make the typeahead input fill the container (remove block-inline attr)

View file

@ -42,9 +42,11 @@ declare(strict_types=1);
namespace App\Controller;
use App\Services\Attachments\AttachmentURLGenerator;
use App\Services\Attachments\BuiltinAttachmentsFinder;
use App\Services\TagFinder;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Asset\Packages;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
@ -59,6 +61,15 @@ use Symfony\Component\Serializer\Serializer;
*/
class TypeaheadController extends AbstractController
{
protected $urlGenerator;
protected $assets;
public function __construct(AttachmentURLGenerator $URLGenerator, Packages $assets)
{
$this->urlGenerator = $URLGenerator;
$this->assets = $assets;
}
/**
* @Route("/builtInResources/search", name="typeahead_builtInRessources")
*
@ -69,6 +80,15 @@ class TypeaheadController extends AbstractController
$query = $request->get('query');
$array = $finder->find($query);
$result = [];
foreach ($array as $path) {
$result[] = [
'name' => $path,
'image' => $this->assets->getUrl($this->urlGenerator->placeholderPathToAssetPath($path)),
];
}
$normalizers = [
new ObjectNormalizer(),
];
@ -76,7 +96,7 @@ class TypeaheadController extends AbstractController
new JsonEncoder(),
];
$serializer = new Serializer($normalizers, $encoders);
$data = $serializer->serialize($array, 'json');
$data = $serializer->serialize($result, 'json');
return new JsonResponse($data, 200, [], true);
}

View file

@ -101,6 +101,7 @@ class AttachmentPathResolver
/**
* Converts a path passed by parameter from services.yaml (which can be an absolute path or relative to project dir)
* to an absolute path. When a relative path is passed, the directory must exist or null is returned.
* Returns an absolute path with "/" no matter, what system is used.
*
* @internal
*
@ -132,8 +133,8 @@ class AttachmentPathResolver
return null;
}
//Otherwise return resolved path
return $tmp;
//Normalize file path (use / instead of \)
return str_replace('\\', '/', $tmp);
}
/**

View file

@ -91,6 +91,8 @@ class AttachmentURLGenerator
$public_path = $this->public_path;
}
//Our absolute path must begin with public path or we can not use it for asset pathes.
if (0 !== strpos($absolute_path, $public_path)) {
return null;
@ -100,6 +102,19 @@ class AttachmentURLGenerator
return substr($absolute_path, strlen($public_path) + 1);
}
/**
* Converts a placeholder path to a path to a image path.
*
* @param string $placeholder_path the placeholder path that should be converted
*
* @return string|null
*/
public function placeholderPathToAssetPath(string $placeholder_path): ?string
{
$absolute_path = $this->pathResolver->placeholderToRealPath($placeholder_path);
return $this->absolutePathToAssetPath($absolute_path);
}
/**
* Returns a URL under which the attachment file can be viewed.
*/

View file

@ -87,8 +87,9 @@ class AttachmentPathResolverTest extends WebTestCase
$this->assertSame(self::$projectDir_orig, self::$service->parameterToAbsolutePath(self::$projectDir));
//Relative pathes should be resolved
$this->assertSame(self::$projectDir_orig.DIRECTORY_SEPARATOR.'src', self::$service->parameterToAbsolutePath('src'));
$this->assertSame(self::$projectDir_orig.DIRECTORY_SEPARATOR.'src', self::$service->parameterToAbsolutePath('./src'));
$expected = str_replace('\\', '/',self::$projectDir_orig.DIRECTORY_SEPARATOR.'src');
$this->assertSame($expected, self::$service->parameterToAbsolutePath('src'));
$this->assertSame($expected, self::$service->parameterToAbsolutePath('./src'));
//Invalid pathes should return null
$this->assertNull(self::$service->parameterToAbsolutePath('/this/path/does/not/exist'));