mirror of
https://github.com/typemill/typemill.git
synced 2025-07-26 00:31:38 +02:00
Medialib finished
This commit is contained in:
@@ -1 +1 @@
|
||||
["# ToDos Version 2","[TOC]","## Visual Editor","* FIXED: File is not published from tmp to media\/files if you save the block.","## Raw Editor","* DONE ready","## Medialib","* Please do next","## Posts","* Setup","## Plugins","* Asset Class","## Frontend","* DONE\n* DONE: Test restrictions","## ToDos","Biig blocks:","* Media Library\n* Posts\n* Recover Password","Small features:","* Sitemap and ping\n* Captcha\n* Clear Cache\n* Security Log\n* Backend fields\n* Proxy\n* DONE: Session handling: csrf fail and session start error if restrictions are active\n* Editor: Warn if open another block","Cleanups:","* Events\n* Error messages\n* Translations","## Select userroles","* Userroles for file restriction: in vue-blox-components loaded via api\n* Userroles for userfields: in php model user getUserFields()\n* Userroles for meta: in php controller apiAuthorMeta getMeta()\n* Plugins and themes: in php model extension getThemeDefinitions()","## License Check","* On activation in apiControllerExtension. It checks the license in yaml.\n* In plugin php code with setPremiumLicense\n* In static plugins, it checks manual premium list and method setPremiumLicense and more "]
|
||||
["# ToDos Version 2","[TOC]","## Visual Editor","* FIXED: File is not published from tmp to media\/files if you save the block.","## Raw Editor","* DONE ready","## Medialib","* DONE","## Posts","* Setup","## Plugins","* Asset Class","## Frontend","* DONE\n* DONE: Test restrictions","## ToDos","Biig blocks:","* DONE: Media Library\n* Posts\n* Recover Password","Small features:","* Sitemap and ping\n* Captcha\n* Clear Cache\n* Security Log\n* Backend fields\n* Proxy\n* DONE: Session handling: csrf fail and session start error if restrictions are active\n* Editor: Warn if open another block\n* Image generation on the fly\n* Assets","Cleanups:","* Events\n* Error messages\n* Translations","## Select userroles","* Userroles for file restriction: in vue-blox-components loaded via api\n* Userroles for userfields: in php model user getUserFields()\n* Userroles for meta: in php controller apiAuthorMeta getMeta()\n* Plugins and themes: in php model extension getThemeDefinitions()","## License Check","* On activation in apiControllerExtension. It checks the license in yaml.\n* In plugin php code with setPremiumLicense\n* In static plugins, it checks manual premium list and method setPremiumLicense and more "]
|
@@ -1 +1,2 @@
|
||||
media/files/typemill-v2-navigation.gif: member
|
||||
media/files/markdown.png: member
|
||||
|
BIN
media/tmp/screenshot-typemill-startpage.png
Normal file
BIN
media/tmp/screenshot-typemill-startpage.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 105 KiB |
@@ -32,8 +32,6 @@ abstract class Controller
|
||||
|
||||
$this->routeParser = $container->get('routeParser');
|
||||
|
||||
# $this->csrf = $container->get('csrf');
|
||||
|
||||
$this->c->get('dispatcher')->dispatch(new OnTwigLoaded(false), 'onTwigLoaded');
|
||||
}
|
||||
|
||||
|
@@ -6,10 +6,8 @@ use Psr\Http\Message\ServerRequestInterface as Request;
|
||||
use Psr\Http\Message\ResponseInterface as Response;
|
||||
use Slim\Routing\RouteContext;
|
||||
use Typemill\Models\Validation;
|
||||
use Typemill\Models\Content;
|
||||
use Typemill\Models\Navigation;
|
||||
use Typemill\Models\Meta;
|
||||
use Typemill\Static\Slug;
|
||||
|
||||
class ControllerApiAuthorMeta extends Controller
|
||||
{
|
||||
@@ -97,7 +95,7 @@ class ControllerApiAuthorMeta extends Controller
|
||||
return $response->withHeader('Content-Type', 'application/json');
|
||||
}
|
||||
|
||||
public function updateMetaData(Request $request, Response $response, $args)
|
||||
public function updateMeta(Request $request, Response $response, $args)
|
||||
{
|
||||
$validRights = $this->validateRights($request->getAttribute('c_userrole'), 'content', 'update');
|
||||
if(!$validRights)
|
||||
@@ -325,160 +323,6 @@ class ControllerApiAuthorMeta extends Controller
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
# get the standard meta-definitions and the meta-definitions from plugins (same for all sites)
|
||||
public function aggregateMetaDefinitions($folder = null)
|
||||
{
|
||||
$metatabs = $this->meta->getMetaDefinitions();
|
||||
|
||||
# the fields for user or role based access
|
||||
if(!isset($this->settings['pageaccess']) || $this->settings['pageaccess'] === NULL )
|
||||
{
|
||||
unset($metatabs['meta']['fields']['fieldsetrights']);
|
||||
}
|
||||
|
||||
# add radio buttons to choose posts or pages for folder.
|
||||
if(!$folder)
|
||||
{
|
||||
unset($metatabs['meta']['fields']['contains']);
|
||||
}
|
||||
|
||||
echo '<pre>';
|
||||
print_r($metatabs);
|
||||
die();
|
||||
|
||||
# loop through all plugins
|
||||
if(!empty($this->settings['plugins']))
|
||||
{
|
||||
foreach($this->settings['plugins'] as $name => $plugin)
|
||||
{
|
||||
if($plugin['active'])
|
||||
{
|
||||
$pluginSettings = \Typemill\Settings::getObjectSettings('plugins', $name);
|
||||
if($pluginSettings && isset($pluginSettings['metatabs']))
|
||||
{
|
||||
$metatabs = array_merge_recursive($metatabs, $pluginSettings['metatabs']);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# add the meta from theme settings here
|
||||
$themeSettings = \Typemill\Settings::getObjectSettings('themes', $this->settings['theme']);
|
||||
|
||||
if($themeSettings && isset($themeSettings['metatabs']))
|
||||
{
|
||||
$metatabs = array_merge_recursive($metatabs, $themeSettings['metatabs']);
|
||||
}
|
||||
|
||||
# dispatch meta
|
||||
# $metatabs = $this->c->dispatcher->dispatch('onMetaDefinitionsLoaded', new OnMetaDefinitionsLoaded($metatabs))->getData();
|
||||
|
||||
return $metatabs;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
public function publishArticle(Request $request, Response $response, $args)
|
||||
{
|
||||
$validRights = $this->validateRights($request->getAttribute('c_userrole'), 'content', 'update');
|
||||
if(!$validRights)
|
||||
{
|
||||
$response->getBody()->write(json_encode([
|
||||
'message' => 'You do not have enough rights.',
|
||||
]));
|
||||
|
||||
return $response->withHeader('Content-Type', 'application/json')->withStatus(422);
|
||||
}
|
||||
|
||||
$params = $request->getParsedBody();
|
||||
$validate = new Validation();
|
||||
$validInput = $validate->articlePublish($params);
|
||||
if($validInput !== true)
|
||||
{
|
||||
$errors = $validate->returnFirstValidationErrors($validInput);
|
||||
$response->getBody()->write(json_encode([
|
||||
'message' => reset($errors),
|
||||
'errors' => $errors
|
||||
]));
|
||||
|
||||
return $response->withHeader('Content-Type', 'application/json')->withStatus(400);
|
||||
}
|
||||
|
||||
$navigation = new Navigation();
|
||||
$urlinfo = $this->c->get('urlinfo');
|
||||
$item = $this->getItem($navigation, $params['url'], $urlinfo);
|
||||
if(!$item)
|
||||
{
|
||||
$response->getBody()->write(json_encode([
|
||||
'message' => 'page not found',
|
||||
]));
|
||||
|
||||
return $response->withHeader('Content-Type', 'application/json')->withStatus(404);
|
||||
}
|
||||
|
||||
# publish content
|
||||
$content = new Content($urlinfo['baseurl']);
|
||||
$draftMarkdown = $content->getDraftMarkdown($item);
|
||||
$content->publishMarkdown($item, $draftMarkdown);
|
||||
|
||||
# refresh navigation and item
|
||||
$navigation->clearNavigation();
|
||||
$draftNavigation = $navigation->getDraftNavigation($urlinfo, $this->settings['langattr']);
|
||||
$draftNavigation = $navigation->setActiveNaviItems($draftNavigation, $item->keyPathArray);
|
||||
$item = $navigation->getItemWithKeyPath($draftNavigation, $item->keyPathArray);
|
||||
|
||||
$response->getBody()->write(json_encode([
|
||||
'navigation' => $draftNavigation,
|
||||
'item' => $item
|
||||
]));
|
||||
|
||||
return $response->withHeader('Content-Type', 'application/json');
|
||||
}
|
||||
|
||||
# get the standard meta-definitions and the meta-definitions from plugins (same for all sites)
|
||||
public function getMetaDefinitions(Request $request, Response $response, $args)
|
||||
{
|
||||
$validRights = $this->validateRights($request->getAttribute('c_userrole'), 'content', 'update');
|
||||
if(!$validRights)
|
||||
{
|
||||
$response->getBody()->write(json_encode([
|
||||
'message' => 'You do not have enough rights.',
|
||||
]));
|
||||
|
||||
return $response->withHeader('Content-Type', 'application/json')->withStatus(422);
|
||||
}
|
||||
|
||||
$metatabs = $this->aggregateMetaDefinitions();
|
||||
|
||||
$response->getBody()->write(json_encode([
|
||||
'definitions' => $metatabs
|
||||
]));
|
||||
|
||||
return $response->withHeader('Content-Type', 'application/json');
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
# we have to flatten field definitions for tabs if there are fieldsets in it
|
||||
public function flattenTabFields($tabfields, $flattab, $fieldset = null)
|
||||
{
|
||||
|
@@ -9,6 +9,57 @@ use Typemill\Models\StorageWrapper;
|
||||
|
||||
class ControllerApiFile extends Controller
|
||||
{
|
||||
public function getFiles(Request $request, Response $response, $args)
|
||||
{
|
||||
$url = $request->getQueryParams()['url'] ?? false;
|
||||
$path = $request->getQueryParams()['path'] ?? false;
|
||||
|
||||
$storage = new StorageWrapper('\Typemill\Models\Storage');
|
||||
|
||||
$filelist = $storage->getFileList();
|
||||
|
||||
$response->getBody()->write(json_encode([
|
||||
'files' => $filelist,
|
||||
]));
|
||||
|
||||
return $response->withHeader('Content-Type', 'application/json');
|
||||
}
|
||||
|
||||
public function getFile(Request $request, Response $response, $args)
|
||||
{
|
||||
$name = $request->getQueryParams()['name'] ?? false;
|
||||
|
||||
# VALIDATE NAME
|
||||
|
||||
if(!$name)
|
||||
{
|
||||
$response->getBody()->write(json_encode([
|
||||
'message' => 'Filename is missing.',
|
||||
]));
|
||||
|
||||
return $response->withHeader('Content-Type', 'application/json')->withStatus(400);
|
||||
}
|
||||
|
||||
$storage = new StorageWrapper('\Typemill\Models\Storage');
|
||||
|
||||
$filedetails = $storage->getFileDetails($name);
|
||||
|
||||
if(!$filedetails)
|
||||
{
|
||||
$response->getBody()->write(json_encode([
|
||||
'message' => 'No File found.',
|
||||
]));
|
||||
|
||||
return $response->withHeader('Content-Type', 'application/json')->withStatus(400);
|
||||
}
|
||||
|
||||
$response->getBody()->write(json_encode([
|
||||
'file' => $filedetails,
|
||||
]));
|
||||
|
||||
return $response->withHeader('Content-Type', 'application/json');
|
||||
}
|
||||
|
||||
public function getFileRestrictions(Request $request, Response $response, $args)
|
||||
{
|
||||
$params = $request->getQueryParams();
|
||||
@@ -238,96 +289,39 @@ class ControllerApiFile extends Controller
|
||||
return $response->withHeader('Content-Type', 'application/json');
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public function getMediaLibFiles(Request $request, Response $response, $args)
|
||||
{
|
||||
# get params from call
|
||||
$this->params = $request->getParsedBody();
|
||||
$this->uri = $request->getUri()->withUserInfo('');
|
||||
|
||||
$fileProcessor = new ProcessFile();
|
||||
if(!$fileProcessor->checkFolders())
|
||||
{
|
||||
return $response->withJson(['errors' => 'Please check if your media-folder exists and all folders inside are writable.'], 500);
|
||||
}
|
||||
|
||||
$filelist = $fileProcessor->scanFilesFlat();
|
||||
|
||||
$response->getBody()->write(json_encode([
|
||||
'files' => $filelist
|
||||
]));
|
||||
|
||||
return $response->withHeader('Content-Type', 'application/json')->withStatus(200);
|
||||
}
|
||||
|
||||
public function getFile(Request $request, Response $response, $args)
|
||||
{
|
||||
# get params from call
|
||||
$this->params = $request->getParams();
|
||||
$this->uri = $request->getUri()->withUserInfo('');
|
||||
|
||||
$this->setStructureDraft();
|
||||
|
||||
$fileProcessor = new ProcessFile();
|
||||
if(!$fileProcessor->checkFolders())
|
||||
{
|
||||
return $response->withJson(['errors' => 'Please check if your media-folder exists and all folders inside are writable.'], 500);
|
||||
}
|
||||
|
||||
$fileDetails = $fileProcessor->getFileDetails($this->params['name'], $this->structureDraft);
|
||||
|
||||
if($fileDetails)
|
||||
{
|
||||
return $response->withJson(['file' => $fileDetails]);
|
||||
}
|
||||
|
||||
return $response->withJson(['errors' => 'file not found or file name invalid'],404);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function deleteFile(Request $request, Response $response, $args)
|
||||
{
|
||||
# get params from call
|
||||
$this->params = $request->getParams();
|
||||
$this->uri = $request->getUri()->withUserInfo('');
|
||||
$params = $request->getParsedBody();
|
||||
|
||||
# minimum permission is that user is allowed to delete content
|
||||
if(!$this->c->acl->isAllowed($_SESSION['role'], 'content', 'delete'))
|
||||
if(!isset($params['name']))
|
||||
{
|
||||
return $response->withJson(array('data' => false, 'errors' => 'You are not allowed to delete files.'), 403);
|
||||
$response->getBody()->write(json_encode([
|
||||
'message' => 'Filename is missing.'
|
||||
]));
|
||||
|
||||
return $response->withHeader('Content-Type', 'application/json')->withStatus(422);
|
||||
}
|
||||
|
||||
if(!isset($this->params['name']))
|
||||
$storage = new StorageWrapper('\Typemill\Models\Storage');
|
||||
|
||||
$deleted = $storage->deleteMediaFile($params['name']);
|
||||
|
||||
if($deleted)
|
||||
{
|
||||
return $response->withJson(['errors' => 'file name is missing'],500);
|
||||
$response->getBody()->write(json_encode([
|
||||
'message' => 'File deleted successfully.'
|
||||
]));
|
||||
|
||||
return $response->withHeader('Content-Type', 'application/json');
|
||||
}
|
||||
|
||||
$fileProcessor = new ProcessFile();
|
||||
$response->getBody()->write(json_encode([
|
||||
'message' => $storage->getError()
|
||||
]));
|
||||
|
||||
if($fileProcessor->deleteFile($this->params['name']))
|
||||
{
|
||||
return $response->withJson(['errors' => false]);
|
||||
}
|
||||
|
||||
return $response->withJson(['errors' => 'could not delete the file'],500);
|
||||
return $response->withHeader('Content-Type', 'application/json')->withStatus(422);
|
||||
}
|
||||
|
||||
|
||||
# https://www.sitepoint.com/mime-types-complete-list/
|
||||
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types
|
||||
# https://wiki.selfhtml.org/wiki/MIME-Type/%C3%9Cbersicht
|
||||
|
@@ -6,6 +6,7 @@ use Psr\Http\Message\ServerRequestInterface as Request;
|
||||
use Psr\Http\Message\ResponseInterface as Response;
|
||||
use Typemill\Models\ProcessImage;
|
||||
use Typemill\Models\StorageWrapper;
|
||||
use Typemill\Extensions\ParsedownExtension;
|
||||
|
||||
|
||||
# use Typemill\Models\ProcessFile;
|
||||
@@ -21,6 +22,110 @@ class ControllerApiImage extends Controller
|
||||
# return error messages and display in image component
|
||||
# check if resized is bigger than original, then use original
|
||||
|
||||
public function getPagemedia(Request $request, Response $response, $args)
|
||||
{
|
||||
$url = $request->getQueryParams()['url'] ?? false;
|
||||
$path = $request->getQueryParams()['path'] ?? false;
|
||||
$pagemedia = [];
|
||||
|
||||
if(!$path)
|
||||
{
|
||||
$response->getBody()->write(json_encode([
|
||||
'message' => 'Path is missing.',
|
||||
]));
|
||||
|
||||
return $response->withHeader('Content-Type', 'application/json')->withStatus(400);
|
||||
}
|
||||
|
||||
$storage = new StorageWrapper('\Typemill\Models\Storage');
|
||||
|
||||
$markdown = $storage->getFile('contentFolder', '', $path . '.txt');
|
||||
if($markdown)
|
||||
{
|
||||
$markdownArray = json_decode($markdown);
|
||||
$parsedown = new ParsedownExtension();
|
||||
$markdown = $parsedown->arrayBlocksToMarkdown($markdownArray);
|
||||
}
|
||||
else
|
||||
{
|
||||
$markdown = $storage->getFile('contentFolder', '', $path . '.md');
|
||||
}
|
||||
|
||||
$mdmedia = $this->findMediaInText($markdown);
|
||||
|
||||
$meta = $storage->getFile('contentFolder', '', $path . '.yaml');
|
||||
|
||||
$mtmedia = $this->findMediaInText($meta);
|
||||
|
||||
$pagemedia = array_merge($mdmedia[2], $mtmedia[2]);
|
||||
|
||||
$response->getBody()->write(json_encode([
|
||||
'pagemedia' => $pagemedia
|
||||
]));
|
||||
|
||||
return $response->withHeader('Content-Type', 'application/json');
|
||||
}
|
||||
|
||||
protected function findMediaInText($text)
|
||||
{
|
||||
preg_match_all('/media\/(live|files)\/(.+?\.[a-zA-Z]{2,4})/', $text, $matches);
|
||||
|
||||
return $matches;
|
||||
}
|
||||
|
||||
public function getImages(Request $request, Response $response, $args)
|
||||
{
|
||||
$url = $request->getQueryParams()['url'] ?? false;
|
||||
$path = $request->getQueryParams()['path'] ?? false;
|
||||
$pagemedia = [];
|
||||
|
||||
$storage = new StorageWrapper('\Typemill\Models\Storage');
|
||||
|
||||
$imagelist = $storage->getImageList();
|
||||
|
||||
$response->getBody()->write(json_encode([
|
||||
'images' => $imagelist
|
||||
]));
|
||||
|
||||
return $response->withHeader('Content-Type', 'application/json');
|
||||
}
|
||||
|
||||
public function getImage(Request $request, Response $response, $args)
|
||||
{
|
||||
$name = $request->getQueryParams()['name'] ?? false;
|
||||
|
||||
# VALIDATE NAME
|
||||
|
||||
if(!$name)
|
||||
{
|
||||
$response->getBody()->write(json_encode([
|
||||
'message' => 'Imagename is missing.',
|
||||
]));
|
||||
|
||||
return $response->withHeader('Content-Type', 'application/json')->withStatus(400);
|
||||
}
|
||||
|
||||
$storage = new StorageWrapper('\Typemill\Models\Storage');
|
||||
|
||||
$imagedetails = $storage->getImageDetails($name);
|
||||
|
||||
if(!$imagedetails)
|
||||
{
|
||||
$response->getBody()->write(json_encode([
|
||||
'message' => 'No image found.',
|
||||
]));
|
||||
|
||||
return $response->withHeader('Content-Type', 'application/json')->withStatus(400);
|
||||
}
|
||||
|
||||
$response->getBody()->write(json_encode([
|
||||
'image' => $imagedetails,
|
||||
]));
|
||||
|
||||
return $response->withHeader('Content-Type', 'application/json');
|
||||
}
|
||||
|
||||
|
||||
public function saveImage(Request $request, Response $response, $args)
|
||||
{
|
||||
$params = $request->getParsedBody();
|
||||
@@ -283,127 +388,38 @@ class ControllerApiImage extends Controller
|
||||
]));
|
||||
|
||||
return $response->withHeader('Content-Type', 'application/json')->withStatus(500);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
$imageData64 = 'data:image/jpeg;base64,' . base64_encode($imageData);
|
||||
$desiredSizes = ['live' => ['width' => 560, 'height' => 315]];
|
||||
$imageProcessor = new ProcessImage($this->settings['images']);
|
||||
if(!$imageProcessor->checkFolders())
|
||||
{
|
||||
return $response->withJson(['errors' => ['message' => 'Please check if your media-folder exists and all folders inside are writable.']], 500);
|
||||
}
|
||||
|
||||
$tmpImage = $imageProcessor->createImage($imageData64, $videoID, $desiredSizes);
|
||||
|
||||
if(!$tmpImage)
|
||||
{
|
||||
return $response->withJson(array('errors' => 'could not create temporary image'));
|
||||
}
|
||||
|
||||
$imageUrl = $imageProcessor->publishImage();
|
||||
if($imageUrl)
|
||||
{
|
||||
$this->params['markdown'] = '{#' . $videoID. ' .' . $class . '}';
|
||||
|
||||
$request = $request->withParsedBody($this->params);
|
||||
$block = new ControllerAuthorBlockApi($this->c);
|
||||
if($this->params['new'])
|
||||
{
|
||||
return $block->addBlock($request, $response, $args);
|
||||
}
|
||||
return $block->updateBlock($request, $response, $args);
|
||||
}
|
||||
|
||||
return $response->withJson(array('errors' => 'could not store the preview image'));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public function getMediaLibImages(Request $request, Response $response, $args)
|
||||
{
|
||||
# get params from call
|
||||
$this->params = $request->getParsedBody();
|
||||
$this->uri = $request->getUri()->withUserInfo('');
|
||||
|
||||
$imageProcessor = new ProcessImage($this->settings['images']);
|
||||
if(!$imageProcessor->checkFolders('images'))
|
||||
{
|
||||
return $response->withJson(['errors' => 'Please check if your media-folder exists and all folders inside are writable.'], 500);
|
||||
}
|
||||
|
||||
$imagelist = $imageProcessor->scanMediaFlat();
|
||||
|
||||
$response->getBody()->write(json_encode([
|
||||
'images' => $imagelist
|
||||
]));
|
||||
|
||||
return $response->withHeader('Content-Type', 'application/json')->withStatus(200);
|
||||
}
|
||||
|
||||
public function getImage(Request $request, Response $response, $args)
|
||||
{
|
||||
# get params from call
|
||||
$this->params = $request->getParsedBody();
|
||||
$this->uri = $request->getUri()->withUserInfo('');
|
||||
|
||||
$this->setStructureDraft();
|
||||
|
||||
$imageProcessor = new ProcessImage($this->settings['images']);
|
||||
if(!$imageProcessor->checkFolders('images'))
|
||||
{
|
||||
return $response->withJson(['errors' => 'Please check if your media-folder exists and all folders inside are writable.'], 500);
|
||||
}
|
||||
|
||||
$imageDetails = $imageProcessor->getImageDetails($this->params['name'], $this->structureDraft);
|
||||
|
||||
if($imageDetails)
|
||||
{
|
||||
return $response->withJson(['image' => $imageDetails]);
|
||||
}
|
||||
|
||||
return $response->withJson(['errors' => 'Image not found or image name not valid.'], 404);
|
||||
}
|
||||
|
||||
public function deleteImage(Request $request, Response $response, $args)
|
||||
{
|
||||
# get params from call
|
||||
$this->params = $request->getParams();
|
||||
$this->uri = $request->getUri()->withUserInfo('');
|
||||
$params = $request->getParsedBody();
|
||||
|
||||
# minimum permission is that user is allowed to delete content
|
||||
if(!$this->c->acl->isAllowed($_SESSION['role'], 'content', 'delete'))
|
||||
if(!isset($params['name']))
|
||||
{
|
||||
return $response->withJson(array('data' => false, 'errors' => 'You are not allowed to delete images.'), 403);
|
||||
$response->getBody()->write(json_encode([
|
||||
'message' => 'Imagename is missing.'
|
||||
]));
|
||||
|
||||
return $response->withHeader('Content-Type', 'application/json')->withStatus(422);
|
||||
}
|
||||
|
||||
if(!isset($this->params['name']))
|
||||
$storage = new StorageWrapper('\Typemill\Models\Storage');
|
||||
|
||||
$deleted = $storage->deleteImage($params['name']);
|
||||
|
||||
if($deleted)
|
||||
{
|
||||
return $response->withJson(['errors' => 'image name is missing'],500);
|
||||
$response->getBody()->write(json_encode([
|
||||
'message' => 'Image deleted successfully.'
|
||||
]));
|
||||
|
||||
return $response->withHeader('Content-Type', 'application/json');
|
||||
}
|
||||
|
||||
$imageProcessor = new ProcessImage($this->settings['images']);
|
||||
if(!$imageProcessor->checkFolders('images'))
|
||||
{
|
||||
return $response->withJson(['errors' => 'Please check if your media-folder exists and all folders inside are writable.'], 500);
|
||||
}
|
||||
$response->getBody()->write(json_encode([
|
||||
'message' => $storage->getError()
|
||||
]));
|
||||
|
||||
if($imageProcessor->deleteImage($this->params['name']))
|
||||
{
|
||||
return $response->withJson(['errors' => false]);
|
||||
}
|
||||
|
||||
return $response->withJson(['errors' => 'Oops, looks like we could not delete all sizes of that image.'], 500);
|
||||
return $response->withHeader('Content-Type', 'application/json')->withStatus(422);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@@ -62,90 +62,4 @@ class ProcessFile extends ProcessAssets
|
||||
|
||||
return $this->getFullName();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public function deleteFile($name)
|
||||
{
|
||||
# validate name
|
||||
$name = basename($name);
|
||||
|
||||
if(file_exists($this->fileFolder . $name) && unlink($this->fileFolder . $name))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public function deleteFileWithName($name)
|
||||
{
|
||||
# e.g. delete $name = 'logo';
|
||||
|
||||
$name = basename($name);
|
||||
|
||||
if($name != '' && !in_array($name, array(".","..")))
|
||||
{
|
||||
foreach(glob($this->fileFolder . $name) as $file)
|
||||
{
|
||||
unlink($file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* scans content of a folder (without recursion)
|
||||
* vars: folder path as string
|
||||
* returns: one-dimensional array with names of folders and files
|
||||
*/
|
||||
public function scanFilesFlat()
|
||||
{
|
||||
$files = scandir($this->fileFolder);
|
||||
$filelist = array();
|
||||
|
||||
foreach ($files as $key => $name)
|
||||
{
|
||||
if (!in_array($name, array(".","..","filerestrictions.yaml")) && file_exists($this->fileFolder . $name))
|
||||
{
|
||||
$filelist[] = [
|
||||
'name' => $name,
|
||||
'timestamp' => filemtime($this->fileFolder . $name),
|
||||
'info' => pathinfo($this->fileFolder . $name),
|
||||
'url' => 'media/files/' . $name,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
$filelist = Helpers::array_sort($filelist, 'timestamp', SORT_DESC);
|
||||
|
||||
return $filelist;
|
||||
}
|
||||
|
||||
|
||||
public function getFileDetails($name, $structure)
|
||||
{
|
||||
$name = basename($name);
|
||||
|
||||
if (!in_array($name, array(".","..")) && file_exists($this->fileFolder . $name))
|
||||
{
|
||||
$filedetails = [
|
||||
'name' => $name,
|
||||
'timestamp' => filemtime($this->fileFolder . $name),
|
||||
'bytes' => filesize($this->fileFolder . $name),
|
||||
'info' => pathinfo($this->fileFolder . $name),
|
||||
'url' => 'media/files/' . $name,
|
||||
'pages' => $this->findPagesWithUrl($structure, $name, $result = [])
|
||||
];
|
||||
|
||||
return $filedetails;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
@@ -229,7 +229,6 @@ class ProcessImage extends ProcessAssets
|
||||
}
|
||||
|
||||
|
||||
# publish image function is moved to storage model
|
||||
|
||||
|
||||
|
||||
@@ -241,62 +240,10 @@ class ProcessImage extends ProcessAssets
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# MOVE TO STORAGE ??
|
||||
public function deleteImage($name)
|
||||
{
|
||||
# validate name
|
||||
$name = basename($name);
|
||||
|
||||
if(!file_exists($this->originalFolder . $name) OR !unlink($this->originalFolder . $name))
|
||||
{
|
||||
$this->errors[] = "We could not delete the original image";
|
||||
}
|
||||
|
||||
if(!file_exists($this->liveFolder . $name) OR !unlink($this->liveFolder . $name))
|
||||
{
|
||||
$this->errors[] = "We could not delete the live image";
|
||||
}
|
||||
|
||||
if(!file_exists($this->thumbFolder . $name) OR !unlink($this->thumbFolder . $name))
|
||||
{
|
||||
$this->errors[] = "we could not delete the thumb image";
|
||||
}
|
||||
|
||||
# delete custom images (resized and grayscaled) array_map('unlink', glob("some/dir/*.txt"));
|
||||
$pathinfo = pathinfo($name);
|
||||
foreach(glob($this->customFolder . $pathinfo['filename'] . '\-*.' . $pathinfo['extension']) as $image)
|
||||
{
|
||||
# you could check if extension is the same here
|
||||
if(!unlink($image))
|
||||
{
|
||||
$this->errors[] = "we could not delete a custom image (grayscale or resized)";
|
||||
}
|
||||
}
|
||||
|
||||
if(empty($this->errors))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
# in use ??
|
||||
public function deleteImageWithName($name)
|
||||
{
|
||||
die("processImage model deleteImageWithName please check method.");
|
||||
# e.g. delete $name = 'logo...';
|
||||
|
||||
$name = basename($name);
|
||||
@@ -321,6 +268,8 @@ class ProcessImage extends ProcessAssets
|
||||
# in use ??
|
||||
public function copyImage($name,$sourcefolder,$targetfolder)
|
||||
{
|
||||
die("processImage model copyImage please check method.");
|
||||
|
||||
copy($sourcefolder . $name, $targetfolder . $name);
|
||||
}
|
||||
|
||||
@@ -389,78 +338,6 @@ class ProcessImage extends ProcessAssets
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* scans content of a folder (without recursion)
|
||||
* vars: folder path as string
|
||||
* returns: one-dimensional array with names of folders and files
|
||||
*/
|
||||
public function scanMediaFlat()
|
||||
{
|
||||
$thumbs = array_diff(scandir($this->thumbFolder), array('..', '.'));
|
||||
$imagelist = array();
|
||||
|
||||
foreach ($thumbs as $key => $name)
|
||||
{
|
||||
if (file_exists($this->liveFolder . $name))
|
||||
{
|
||||
$imagelist[] = [
|
||||
'name' => $name,
|
||||
'timestamp' => filemtime($this->liveFolder . $name),
|
||||
'src_thumb' => 'media/thumbs/' . $name,
|
||||
'src_live' => 'media/live/' . $name,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
$imagelist = Helpers::array_sort($imagelist, 'timestamp', SORT_DESC);
|
||||
|
||||
return $imagelist;
|
||||
}
|
||||
|
||||
|
||||
# get details from existing image for media library
|
||||
public function getImageDetails($name, $structure)
|
||||
{
|
||||
$name = basename($name);
|
||||
|
||||
if (!in_array($name, array(".","..")) && file_exists($this->liveFolder . $name))
|
||||
{
|
||||
$imageinfo = getimagesize($this->liveFolder . $name);
|
||||
|
||||
if(!$imageinfo && pathinfo($this->liveFolder . $name, PATHINFO_EXTENSION) == 'svg')
|
||||
{
|
||||
$imagedetails = [
|
||||
'name' => $name,
|
||||
'timestamp' => filemtime($this->liveFolder . $name),
|
||||
'bytes' => filesize($this->liveFolder . $name),
|
||||
'width' => '---',
|
||||
'height' => '---',
|
||||
'type' => 'svg',
|
||||
'src_thumb' => 'media/thumbs/' . $name,
|
||||
'src_live' => 'media/live/' . $name,
|
||||
'pages' => $this->findPagesWithUrl($structure, $name, $result = [])
|
||||
];
|
||||
}
|
||||
else
|
||||
{
|
||||
$imagedetails = [
|
||||
'name' => $name,
|
||||
'timestamp' => filemtime($this->liveFolder . $name),
|
||||
'bytes' => filesize($this->liveFolder . $name),
|
||||
'width' => $imageinfo[0],
|
||||
'height' => $imageinfo[1],
|
||||
'type' => $imageinfo['mime'],
|
||||
'src_thumb' => 'media/thumbs/' . $name,
|
||||
'src_live' => 'media/live/' . $name,
|
||||
'pages' => $this->findPagesWithUrl($structure, $name, $result = [])
|
||||
];
|
||||
}
|
||||
|
||||
return $imagedetails;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function generateThumbs()
|
||||
{
|
||||
|
@@ -2,6 +2,8 @@
|
||||
|
||||
namespace Typemill\Models;
|
||||
|
||||
use Typemill\Static\Helpers;
|
||||
|
||||
class Storage
|
||||
{
|
||||
public $error = false;
|
||||
@@ -332,6 +334,11 @@ class Storage
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
##################
|
||||
## IMAGES ##
|
||||
##################
|
||||
|
||||
public function createUniqueImageName($filename, $extension)
|
||||
{
|
||||
$defaultfilename = $filename;
|
||||
@@ -347,36 +354,6 @@ class Storage
|
||||
return $filename;
|
||||
}
|
||||
|
||||
public function publishFile($name)
|
||||
{
|
||||
$pathinfo = pathinfo($name);
|
||||
if(!$pathinfo)
|
||||
{
|
||||
$this->error = 'Could not read pathinfo.';
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$filename = $pathinfo['filename'] . '.' . $pathinfo['extension'];
|
||||
$filepath = $this->tmpFolder . $filename;
|
||||
|
||||
if(!file_exists($this->tmpFolder . $filename))
|
||||
{
|
||||
$this->error = "We did not find the file in the tmp-folder or could not read it.";
|
||||
return false;
|
||||
}
|
||||
|
||||
$success = rename($this->tmpFolder . $filename, $this->fileFolder . $filename);
|
||||
|
||||
if($success === true)
|
||||
{
|
||||
# return true;
|
||||
return 'media/files/' . $filename;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function publishImage($name, $noresize = false)
|
||||
{
|
||||
$pathinfo = pathinfo($name);
|
||||
@@ -489,10 +466,221 @@ class Storage
|
||||
|
||||
}
|
||||
|
||||
public function getImageList()
|
||||
{
|
||||
$thumbs = array_diff(scandir($this->thumbsFolder), array('..', '.'));
|
||||
$imagelist = array();
|
||||
|
||||
foreach ($thumbs as $key => $name)
|
||||
{
|
||||
if (file_exists($this->liveFolder . $name))
|
||||
{
|
||||
$imagelist[] = [
|
||||
'name' => $name,
|
||||
'timestamp' => filemtime($this->liveFolder . $name),
|
||||
'src_thumb' => 'media/thumbs/' . $name,
|
||||
'src_live' => 'media/live/' . $name,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
$imagelist = Helpers::array_sort($imagelist, 'timestamp', SORT_DESC);
|
||||
|
||||
return $imagelist;
|
||||
}
|
||||
|
||||
# get details from existing image for media library
|
||||
public function getImageDetails($name)
|
||||
{
|
||||
$name = basename($name);
|
||||
|
||||
if (!in_array($name, array(".","..")) && file_exists($this->liveFolder . $name))
|
||||
{
|
||||
$imageinfo = getimagesize($this->liveFolder . $name);
|
||||
|
||||
if(!$imageinfo && pathinfo($this->liveFolder . $name, PATHINFO_EXTENSION) == 'svg')
|
||||
{
|
||||
$imagedetails = [
|
||||
'name' => $name,
|
||||
'timestamp' => filemtime($this->liveFolder . $name),
|
||||
'bytes' => filesize($this->liveFolder . $name),
|
||||
'width' => '---',
|
||||
'height' => '---',
|
||||
'type' => 'svg',
|
||||
'src_thumb' => 'media/thumbs/' . $name,
|
||||
'src_live' => 'media/live/' . $name,
|
||||
];
|
||||
}
|
||||
else
|
||||
{
|
||||
$imagedetails = [
|
||||
'name' => $name,
|
||||
'timestamp' => filemtime($this->liveFolder . $name),
|
||||
'bytes' => filesize($this->liveFolder . $name),
|
||||
'width' => $imageinfo[0],
|
||||
'height' => $imageinfo[1],
|
||||
'type' => $imageinfo['mime'],
|
||||
'src_thumb' => 'media/thumbs/' . $name,
|
||||
'src_live' => 'media/live/' . $name,
|
||||
];
|
||||
}
|
||||
|
||||
return $imagedetails;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function deleteImage($name)
|
||||
{
|
||||
# validate name
|
||||
$name = basename($name);
|
||||
|
||||
if(!file_exists($this->liveFolder . $name) OR !unlink($this->liveFolder . $name))
|
||||
{
|
||||
$this->error .= "We could not delete the live image. ";
|
||||
}
|
||||
|
||||
if(!file_exists($this->thumbsFolder . $name) OR !unlink($this->thumbsFolder . $name))
|
||||
{
|
||||
$this->error .= "We could not delete the thumb image. ";
|
||||
}
|
||||
|
||||
# delete custom images (resized and grayscaled) array_map('unlink', glob("some/dir/*.txt"));
|
||||
$pathinfo = pathinfo($name);
|
||||
|
||||
foreach(glob($this->originalFolder . $pathinfo['filename'] . '\.*') as $image)
|
||||
{
|
||||
# you could check if extension is the same here
|
||||
if(!unlink($image))
|
||||
{
|
||||
$this->error = "We could not delete the original image in $this->originalFolder $image. ";
|
||||
}
|
||||
}
|
||||
|
||||
foreach(glob($this->customFolder . $pathinfo['filename'] . '\-*.' . $pathinfo['extension']) as $image)
|
||||
{
|
||||
# you could check if extension is the same here
|
||||
if(!unlink($image))
|
||||
{
|
||||
$this->error .= "we could not delete a custom image (grayscale or resized). ";
|
||||
}
|
||||
}
|
||||
|
||||
if(!$this->error)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
##################
|
||||
## FILES ##
|
||||
##################
|
||||
|
||||
public function publishFile($name)
|
||||
{
|
||||
$pathinfo = pathinfo($name);
|
||||
if(!$pathinfo)
|
||||
{
|
||||
$this->error = 'Could not read pathinfo.';
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$filename = $pathinfo['filename'] . '.' . $pathinfo['extension'];
|
||||
$filepath = $this->tmpFolder . $filename;
|
||||
|
||||
if(!file_exists($this->tmpFolder . $filename))
|
||||
{
|
||||
$this->error = "We did not find the file in the tmp-folder or could not read it.";
|
||||
return false;
|
||||
}
|
||||
|
||||
$success = rename($this->tmpFolder . $filename, $this->fileFolder . $filename);
|
||||
|
||||
if($success === true)
|
||||
{
|
||||
# return true;
|
||||
return 'media/files/' . $filename;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getFileList()
|
||||
{
|
||||
$files = scandir($this->fileFolder);
|
||||
$filelist = array();
|
||||
|
||||
foreach ($files as $key => $name)
|
||||
{
|
||||
if (!in_array($name, array(".","..","filerestrictions.yaml")) && file_exists($this->fileFolder . $name))
|
||||
{
|
||||
$filelist[] = [
|
||||
'name' => $name,
|
||||
'timestamp' => filemtime($this->fileFolder . $name),
|
||||
'bytes' => filesize($this->fileFolder . $name),
|
||||
'info' => pathinfo($this->fileFolder . $name),
|
||||
'url' => 'media/files/' . $name,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
$filelist = Helpers::array_sort($filelist, 'timestamp', SORT_DESC);
|
||||
|
||||
return $filelist;
|
||||
}
|
||||
|
||||
public function getFileDetailsBREAK($name)
|
||||
{
|
||||
$name = basename($name);
|
||||
|
||||
if (!in_array($name, array(".","..")) && file_exists($this->fileFolder . $name))
|
||||
{
|
||||
$filedetails = [
|
||||
'name' => $name,
|
||||
'timestamp' => filemtime($this->fileFolder . $name),
|
||||
'bytes' => filesize($this->fileFolder . $name),
|
||||
'info' => pathinfo($this->fileFolder . $name),
|
||||
'url' => 'media/files/' . $name,
|
||||
];
|
||||
|
||||
return $filedetails;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function deleteMediaFile($name)
|
||||
{
|
||||
# validate name
|
||||
$name = basename($name);
|
||||
|
||||
if(file_exists($this->fileFolder . $name) && unlink($this->fileFolder . $name))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public function deleteFileWithName($name)
|
||||
{
|
||||
# e.g. delete $name = 'logo';
|
||||
|
||||
$name = basename($name);
|
||||
|
||||
if($name != '' && !in_array($name, array(".","..")))
|
||||
{
|
||||
foreach(glob($this->fileFolder . $name) as $file)
|
||||
{
|
||||
unlink($file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@@ -15,6 +15,11 @@
|
||||
position: relative;
|
||||
}
|
||||
|
||||
|
||||
/********************
|
||||
* VUE *
|
||||
********************/
|
||||
|
||||
[v-cloak] {
|
||||
display: none;
|
||||
}
|
||||
@@ -22,12 +27,25 @@
|
||||
.initial-leave-active {
|
||||
transition: opacity 0.2s ease;
|
||||
}
|
||||
|
||||
.initial-enter-from,
|
||||
.initial-leave-to {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
|
||||
.fade-enter-active {
|
||||
transition: opacity 0.2s ease;
|
||||
}
|
||||
.fade-enter-from{
|
||||
opacity: 0;
|
||||
}
|
||||
.list-enter-active {
|
||||
transition: opacity 0.2s ease;
|
||||
}
|
||||
.list-enter-from{
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
/* CODEAREA */
|
||||
|
||||
.codearea{
|
||||
@@ -449,57 +467,6 @@
|
||||
font-weight:300;
|
||||
}
|
||||
|
||||
/*** BLOX EDITOR ***
|
||||
|
||||
.edit .blox-editor .h1,
|
||||
.edit .blox-editor .h2,
|
||||
.edit .blox-editor .h3,
|
||||
.edit .blox-editor .h4,
|
||||
.edit .blox-editor .h5,
|
||||
.edit .blox-editor .h6{
|
||||
line-height: 1em;
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.edit .blox-editor .h1{
|
||||
font-weight: 700;
|
||||
font-size: 2.2em;
|
||||
padding-top: 0.6em;
|
||||
padding-bottom: 0.6em;
|
||||
}
|
||||
.edit .blox-editor .h2{
|
||||
font-weight: 700;
|
||||
font-size: 1.6em;
|
||||
padding-top: 1.3em;
|
||||
padding-bottom: 0.6em;
|
||||
}
|
||||
.edit .blox-editor .h3{
|
||||
font-weight: 700;
|
||||
font-size: 1.3em;
|
||||
text-transform: none;
|
||||
padding-top: 1.2em;
|
||||
padding-bottom: 0.6em;
|
||||
}
|
||||
.edit .blox-editor .h4{
|
||||
font-weight: 700;
|
||||
font-size: 1.1em;
|
||||
padding-top: 1.2em;
|
||||
padding-bottom: 0.6em;
|
||||
}
|
||||
.edit .blox-editor .h5{
|
||||
font-weight: 700;
|
||||
font-size: 1em;
|
||||
padding-top: 1.2em;
|
||||
padding-bottom: 0.6em;
|
||||
}
|
||||
.edit .blox-editor .h6{
|
||||
font-size: 1em;
|
||||
font-style: italic;
|
||||
font-weight:300;
|
||||
padding-top: 1em;
|
||||
padding-bottom: 0.6em;
|
||||
}
|
||||
|
||||
|
||||
/************************
|
||||
** INLINE FORMATG BAR **
|
||||
@@ -561,320 +528,4 @@
|
||||
.blox-editor input.urlinput:focus{
|
||||
outline: 0px;
|
||||
border: 0px;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
.title input{
|
||||
font-size: 2.2em;
|
||||
font-weight: 700;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.imageupload{
|
||||
width: 50%;
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
border-right: 1px dotted grey;
|
||||
box-sizing:border-box;
|
||||
}
|
||||
|
||||
|
||||
.imageselect{
|
||||
width: 50%;
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
box-sizing:border-box;
|
||||
border:0px;
|
||||
padding: 0 0 0 0;
|
||||
margin: 0 0 0 0;
|
||||
min-height: 70px;
|
||||
background: #f9f8f6;
|
||||
font-family: Helvetica, Calibri, Arial, sans-serif;
|
||||
}
|
||||
.dropbox{
|
||||
min-height: 70px;
|
||||
background: #f9f8f6;
|
||||
padding: 0px;
|
||||
box-sizing: border-box;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.dropbox p{
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
line-height: 70px;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
box-sizing:border-box;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
.dropbox input, .dropbox select{
|
||||
background-color: #fff;
|
||||
width: 80%;
|
||||
margin: 2px 0;
|
||||
display: inline-block;
|
||||
}
|
||||
.video input{
|
||||
width: 75%;
|
||||
margin: 15px 0;
|
||||
}
|
||||
.dropbox select{
|
||||
background-image: linear-gradient(45deg, transparent 50%, #444 50%), linear-gradient(135deg, #444 50%, transparent 50%), linear-gradient(to right, #fff, #fff);
|
||||
}
|
||||
.dropbox label{
|
||||
width: 20%;
|
||||
display: inline-block;
|
||||
}
|
||||
.video label{
|
||||
text-align: right;
|
||||
padding-right: 10px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.dropbox .imgmeta{
|
||||
padding: 30px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.dropbox .input-file{
|
||||
opacity: 0;
|
||||
width: 100%;
|
||||
height: 70px;
|
||||
position: absolute;
|
||||
cursor: pointer;
|
||||
z-index: 1;
|
||||
}
|
||||
.medialib{
|
||||
margin: auto;
|
||||
width: 100%;
|
||||
height: 80%;
|
||||
overflow: auto;
|
||||
background: #f9f8f6;
|
||||
max-width: 1200px;
|
||||
}
|
||||
.imagecard{
|
||||
margin: 10px;
|
||||
box-shadow:0 2px 5px rgba(22,23,26,.05);
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
sup{}
|
||||
cite{}
|
||||
abbr{}
|
||||
hr{
|
||||
background: #ddd;
|
||||
height: 2px;
|
||||
margin: 20px 0;
|
||||
border: 0px;
|
||||
}
|
||||
.setupWrapper a, .setupWrapper a:link, .setupWrapper a:visited
|
||||
{
|
||||
text-decoration: none;
|
||||
color: #444;
|
||||
}
|
||||
.setupWrapper a:focus, .setupWrapper a:hover, .setupWrapper a:active
|
||||
{
|
||||
color: #e0474c;
|
||||
}
|
||||
.mbfix{ margin-bottom: 0px!important; }
|
||||
|
||||
.slugbutton{
|
||||
right: 20px;
|
||||
height: 52px;
|
||||
width: 150px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
.blox-body{
|
||||
position: relative;
|
||||
padding: 18px 20px
|
||||
}
|
||||
.blox-overlay{
|
||||
position:absolute;
|
||||
display: block;
|
||||
z-index: 10;
|
||||
box-sizing: border-box;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background: #FFF;
|
||||
background: rgba(255,255,255,0.8);
|
||||
}
|
||||
.blox-editor{
|
||||
position: relative;
|
||||
}
|
||||
.blox-buttons{
|
||||
position: absolute;
|
||||
bottom: -15px;
|
||||
text-align: right;
|
||||
right: 25px;
|
||||
width: 200px;
|
||||
z-index: 99;
|
||||
}
|
||||
.blox-buttons button{
|
||||
display: inline-block;
|
||||
box-sizing: border-box;
|
||||
margin: 2px;
|
||||
padding: 3px 6px;
|
||||
width: 80px;
|
||||
text-align: center;
|
||||
color: #444;
|
||||
background: #f9f8f6;
|
||||
border: 2px solid #fff;
|
||||
border-radius: 2px;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
.blox-buttons button.edit{
|
||||
background: #70c1b3;
|
||||
color: #fff;
|
||||
}
|
||||
.blox-buttons button.edit:hover{
|
||||
background: #4D978A;
|
||||
}
|
||||
.blox-buttons button.cancel:hover{
|
||||
background: #e0474c;
|
||||
color: #fff;
|
||||
}
|
||||
.blox-buttons button.edit:disabled, .blox-buttons button.cancel:disabled{
|
||||
background: #eee;
|
||||
color: #444;
|
||||
border: 1px solid #eee;
|
||||
}
|
||||
|
||||
|
||||
.sideaction{
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
font-size: 0.8em;
|
||||
right: -22px;
|
||||
}
|
||||
.sideaction button{
|
||||
display: block;
|
||||
font-weight: 300;
|
||||
font-size: 0.9em;
|
||||
background: #fff;
|
||||
color: #fff;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
line-height: 25px;
|
||||
text-align: center;
|
||||
padding: 0px;
|
||||
margin: 1px;
|
||||
border: 0px;
|
||||
border-radius: 1px;
|
||||
}
|
||||
.blox-wrapper{
|
||||
position: relative;
|
||||
}
|
||||
.editactive .sideaction button,
|
||||
.blox-wrapper:hover button.add,
|
||||
.blox-wrapper:hover button.delete{
|
||||
background-color: #f9f8f6;
|
||||
color: #666;
|
||||
}
|
||||
.sideaction:hover ~ .background-helper {
|
||||
background-color: #f9f8f6;
|
||||
}
|
||||
.editactive .background-helper{
|
||||
background-color: transparent!important;
|
||||
}
|
||||
.blox-wrapper button.add:hover{
|
||||
background: #66b0a3;
|
||||
color: #fff;
|
||||
}
|
||||
.blox-wrapper button.delete:hover{
|
||||
background: #e0474c;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.blox-editor textarea{
|
||||
font-family: arial;
|
||||
line-height: 1.5em;
|
||||
font-size: 16px;
|
||||
padding-left: 20px;
|
||||
padding-right: 20px;
|
||||
box-sizing: border-box;
|
||||
min-height: 40px;
|
||||
}
|
||||
.blox-editor textarea:focus, .blox-editor input:focus{
|
||||
box-shadow: none;
|
||||
outline: none;
|
||||
}
|
||||
.blox-editor input.mdcontent.h2,.blox-editor input.mdcontent.h3,.blox-editor input.mdcontent.h4,.blox-editor input.mdcontent.h5,.blox-editor input.mdcontent.h6{
|
||||
padding-left: 35px;
|
||||
height: auto;
|
||||
}
|
||||
.blox-editor input.mdcontent.h2{
|
||||
font-size: 1.6em;
|
||||
font-weight: 700;
|
||||
}
|
||||
.blox-editor input.mdcontent.h3{
|
||||
font-size: 1.3em;
|
||||
font-weight: 700;
|
||||
}
|
||||
.blox-editor input.mdcontent.h4{
|
||||
font-size: 1.1em;
|
||||
font-weight: 700;
|
||||
}
|
||||
.blox-editor input.mdcontent.h5{
|
||||
font-size: 1em;
|
||||
font-weight: 700;
|
||||
}
|
||||
.blox-editor input.mdcontent.h6{
|
||||
font-size: 1em;
|
||||
font-weight: 300;
|
||||
font-style: italic;
|
||||
}
|
||||
button.hdown{
|
||||
position: absolute;
|
||||
padding: 8px;
|
||||
top: 1px;
|
||||
bottom: 1px;
|
||||
left: 0px;
|
||||
font-size: 1em;
|
||||
font-weight: 700;
|
||||
border: 0px solid #fff;
|
||||
border-right: 1px solid #fff;
|
||||
}
|
||||
button.hdown.headline{
|
||||
color: #f9f8f6;
|
||||
background: #66b0a3;
|
||||
}
|
||||
.blox-editor .contenttype {
|
||||
position: absolute;
|
||||
top: 15px;
|
||||
left: -25px;
|
||||
color: #666;
|
||||
}
|
||||
.visible{
|
||||
display: block;
|
||||
}
|
||||
.hidden{
|
||||
visibility: hidden;
|
||||
}
|
||||
.hidden .blox:hover{
|
||||
background: #fff;
|
||||
}
|
||||
.component{
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
z-index:9;
|
||||
}
|
||||
*/
|
||||
}
|
@@ -690,6 +690,10 @@ video {
|
||||
left: 3rem;
|
||||
}
|
||||
|
||||
.right-0 {
|
||||
right: 0px;
|
||||
}
|
||||
|
||||
.-bottom-3 {
|
||||
bottom: -0.75rem;
|
||||
}
|
||||
@@ -706,20 +710,16 @@ video {
|
||||
left: 50%;
|
||||
}
|
||||
|
||||
.right-0 {
|
||||
right: 0px;
|
||||
}
|
||||
|
||||
.bottom-3 {
|
||||
bottom: 0.75rem;
|
||||
}
|
||||
|
||||
.top-1 {
|
||||
top: 0.25rem;
|
||||
.top-12 {
|
||||
top: 3rem;
|
||||
}
|
||||
|
||||
.right-1 {
|
||||
right: 0.25rem;
|
||||
.top-10 {
|
||||
top: 2.5rem;
|
||||
}
|
||||
|
||||
.z-20 {
|
||||
@@ -776,16 +776,16 @@ video {
|
||||
margin-bottom: 0.25rem;
|
||||
}
|
||||
|
||||
.my-4 {
|
||||
margin-top: 1rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.my-3 {
|
||||
margin-top: 0.75rem;
|
||||
margin-bottom: 0.75rem;
|
||||
}
|
||||
|
||||
.my-4 {
|
||||
margin-top: 1rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.mt-6 {
|
||||
margin-top: 1.5rem;
|
||||
}
|
||||
@@ -794,10 +794,6 @@ video {
|
||||
margin-bottom: 0.25rem;
|
||||
}
|
||||
|
||||
.mb-16 {
|
||||
margin-bottom: 4rem;
|
||||
}
|
||||
|
||||
.mb-2 {
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
@@ -830,10 +826,18 @@ video {
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
|
||||
.mb-16 {
|
||||
margin-bottom: 4rem;
|
||||
}
|
||||
|
||||
.mr-3 {
|
||||
margin-right: 0.75rem;
|
||||
}
|
||||
|
||||
.mb-8 {
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.mt-5 {
|
||||
margin-top: 1.25rem;
|
||||
}
|
||||
@@ -846,6 +850,22 @@ video {
|
||||
margin-left: 0.5rem;
|
||||
}
|
||||
|
||||
.ml-5 {
|
||||
margin-left: 1.25rem;
|
||||
}
|
||||
|
||||
.mr-5 {
|
||||
margin-right: 1.25rem;
|
||||
}
|
||||
|
||||
.mb-10 {
|
||||
margin-bottom: 2.5rem;
|
||||
}
|
||||
|
||||
.mt-8 {
|
||||
margin-top: 2rem;
|
||||
}
|
||||
|
||||
.mb-3 {
|
||||
margin-bottom: 0.75rem;
|
||||
}
|
||||
@@ -858,10 +878,6 @@ video {
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
.mt-8 {
|
||||
margin-top: 2rem;
|
||||
}
|
||||
|
||||
.mt-7 {
|
||||
margin-top: 1.75rem;
|
||||
}
|
||||
@@ -870,10 +886,6 @@ video {
|
||||
margin-right: 1rem;
|
||||
}
|
||||
|
||||
.mb-8 {
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.block {
|
||||
display: block;
|
||||
}
|
||||
@@ -934,6 +946,14 @@ video {
|
||||
height: 2rem;
|
||||
}
|
||||
|
||||
.h-full {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.h-32 {
|
||||
height: 8rem;
|
||||
}
|
||||
|
||||
.h-0 {
|
||||
height: 0px;
|
||||
}
|
||||
@@ -1030,6 +1050,14 @@ video {
|
||||
width: 60%;
|
||||
}
|
||||
|
||||
.w-3\/4 {
|
||||
width: 75%;
|
||||
}
|
||||
|
||||
.w-60 {
|
||||
width: 15rem;
|
||||
}
|
||||
|
||||
.w-0 {
|
||||
width: 0px;
|
||||
}
|
||||
@@ -1042,10 +1070,6 @@ video {
|
||||
width: 91.666667%;
|
||||
}
|
||||
|
||||
.w-3\/4 {
|
||||
width: 75%;
|
||||
}
|
||||
|
||||
.max-w-md {
|
||||
max-width: 28rem;
|
||||
}
|
||||
@@ -1058,6 +1082,10 @@ video {
|
||||
max-width: 56rem;
|
||||
}
|
||||
|
||||
.max-w-7xl {
|
||||
max-width: 80rem;
|
||||
}
|
||||
|
||||
.max-w-6xl {
|
||||
max-width: 72rem;
|
||||
}
|
||||
@@ -1136,6 +1164,10 @@ video {
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.justify-start {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.justify-end {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
@@ -1202,30 +1234,30 @@ video {
|
||||
border-right-width: 8px;
|
||||
}
|
||||
|
||||
.border-l {
|
||||
border-left-width: 1px;
|
||||
.border-b-2 {
|
||||
border-bottom-width: 2px;
|
||||
}
|
||||
|
||||
.border-t {
|
||||
border-top-width: 1px;
|
||||
}
|
||||
|
||||
.border-r {
|
||||
border-right-width: 1px;
|
||||
}
|
||||
|
||||
.border-r-2 {
|
||||
border-right-width: 2px;
|
||||
}
|
||||
|
||||
.border-b-2 {
|
||||
border-bottom-width: 2px;
|
||||
}
|
||||
|
||||
.border-b {
|
||||
border-bottom-width: 1px;
|
||||
}
|
||||
|
||||
.border-r {
|
||||
border-right-width: 1px;
|
||||
}
|
||||
|
||||
.border-l {
|
||||
border-left-width: 1px;
|
||||
}
|
||||
|
||||
.border-l-4 {
|
||||
border-left-width: 4px;
|
||||
}
|
||||
@@ -1246,10 +1278,6 @@ video {
|
||||
border-bottom-width: 4px;
|
||||
}
|
||||
|
||||
.border-l-2 {
|
||||
border-left-width: 2px;
|
||||
}
|
||||
|
||||
.border-solid {
|
||||
border-style: solid;
|
||||
}
|
||||
@@ -1263,11 +1291,6 @@ video {
|
||||
border-color: rgb(209 213 219 / var(--tw-border-opacity));
|
||||
}
|
||||
|
||||
.border-stone-100 {
|
||||
--tw-border-opacity: 1;
|
||||
border-color: rgb(245 245 244 / var(--tw-border-opacity));
|
||||
}
|
||||
|
||||
.border-stone-200 {
|
||||
--tw-border-opacity: 1;
|
||||
border-color: rgb(231 229 228 / var(--tw-border-opacity));
|
||||
@@ -1300,12 +1323,7 @@ video {
|
||||
|
||||
.border-stone-100 {
|
||||
--tw-border-opacity: 1;
|
||||
border-color: rgb(250 204 21 / var(--tw-border-opacity));
|
||||
}
|
||||
|
||||
.border-rose-500 {
|
||||
--tw-border-opacity: 1;
|
||||
border-color: rgb(244 63 94 / var(--tw-border-opacity));
|
||||
border-color: rgb(245 245 244 / var(--tw-border-opacity));
|
||||
}
|
||||
|
||||
.border-rose-500 {
|
||||
@@ -1397,11 +1415,6 @@ video {
|
||||
background-color: rgb(20 184 166 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.bg-rose-500 {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(244 63 94 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.bg-red-100 {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(254 226 226 / var(--tw-bg-opacity));
|
||||
@@ -1417,6 +1430,15 @@ video {
|
||||
background-color: rgb(87 83 78 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.bg-rose-500 {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(244 63 94 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.bg-black\/75 {
|
||||
background-color: rgb(0 0 0 / 0.75);
|
||||
}
|
||||
|
||||
.bg-yellow-500 {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(234 179 8 / var(--tw-bg-opacity));
|
||||
@@ -1426,12 +1448,12 @@ video {
|
||||
--tw-bg-opacity: 0.9;
|
||||
}
|
||||
|
||||
.bg-clip-padding {
|
||||
background-clip: padding-box;
|
||||
.bg-cover {
|
||||
background-size: cover;
|
||||
}
|
||||
|
||||
.bg-center {
|
||||
background-position: center;
|
||||
.bg-clip-padding {
|
||||
background-clip: padding-box;
|
||||
}
|
||||
|
||||
.p-3 {
|
||||
@@ -1483,6 +1505,16 @@ video {
|
||||
padding-bottom: 0.75rem;
|
||||
}
|
||||
|
||||
.px-4 {
|
||||
padding-left: 1rem;
|
||||
padding-right: 1rem;
|
||||
}
|
||||
|
||||
.py-2 {
|
||||
padding-top: 0.5rem;
|
||||
padding-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.px-12 {
|
||||
padding-left: 3rem;
|
||||
padding-right: 3rem;
|
||||
@@ -1503,11 +1535,6 @@ video {
|
||||
padding-right: 0.5rem;
|
||||
}
|
||||
|
||||
.py-2 {
|
||||
padding-top: 0.5rem;
|
||||
padding-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.px-1 {
|
||||
padding-left: 0.25rem;
|
||||
padding-right: 0.25rem;
|
||||
@@ -1523,14 +1550,19 @@ video {
|
||||
padding-right: 2rem;
|
||||
}
|
||||
|
||||
.px-5 {
|
||||
padding-left: 1.25rem;
|
||||
padding-right: 1.25rem;
|
||||
}
|
||||
|
||||
.px-16 {
|
||||
padding-left: 4rem;
|
||||
padding-right: 4rem;
|
||||
}
|
||||
|
||||
.py-12 {
|
||||
padding-top: 3rem;
|
||||
padding-bottom: 3rem;
|
||||
.py-16 {
|
||||
padding-top: 4rem;
|
||||
padding-bottom: 4rem;
|
||||
}
|
||||
|
||||
.py-4 {
|
||||
@@ -1538,21 +1570,6 @@ video {
|
||||
padding-bottom: 1rem;
|
||||
}
|
||||
|
||||
.px-4 {
|
||||
padding-left: 1rem;
|
||||
padding-right: 1rem;
|
||||
}
|
||||
|
||||
.px-20 {
|
||||
padding-left: 5rem;
|
||||
padding-right: 5rem;
|
||||
}
|
||||
|
||||
.py-16 {
|
||||
padding-top: 4rem;
|
||||
padding-bottom: 4rem;
|
||||
}
|
||||
|
||||
.pr-6 {
|
||||
padding-right: 1.5rem;
|
||||
}
|
||||
@@ -1617,14 +1634,22 @@ video {
|
||||
padding-top: 0.5rem;
|
||||
}
|
||||
|
||||
.pt-4 {
|
||||
padding-top: 1rem;
|
||||
.pt-6 {
|
||||
padding-top: 1.5rem;
|
||||
}
|
||||
|
||||
.pb-3 {
|
||||
padding-bottom: 0.75rem;
|
||||
}
|
||||
|
||||
.pt-3 {
|
||||
padding-top: 0.75rem;
|
||||
}
|
||||
|
||||
.pt-4 {
|
||||
padding-top: 1rem;
|
||||
}
|
||||
|
||||
.text-left {
|
||||
text-align: left;
|
||||
}
|
||||
@@ -1684,11 +1709,6 @@ video {
|
||||
line-height: 1.75rem;
|
||||
}
|
||||
|
||||
.text-2xl {
|
||||
font-size: 1.5rem;
|
||||
line-height: 2rem;
|
||||
}
|
||||
|
||||
.text-3xl {
|
||||
font-size: 1.875rem;
|
||||
line-height: 2.25rem;
|
||||
@@ -1812,11 +1832,6 @@ video {
|
||||
color: rgb(244 63 94 / var(--tw-text-opacity));
|
||||
}
|
||||
|
||||
.text-cyan-500 {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(6 182 212 / var(--tw-text-opacity));
|
||||
}
|
||||
|
||||
.underline {
|
||||
-webkit-text-decoration-line: underline;
|
||||
text-decoration-line: underline;
|
||||
@@ -1890,6 +1905,12 @@ video {
|
||||
transition-duration: 150ms;
|
||||
}
|
||||
|
||||
.transition-opacity {
|
||||
transition-property: opacity;
|
||||
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
||||
transition-duration: 150ms;
|
||||
}
|
||||
|
||||
.\!transition {
|
||||
transition-property: color, background-color, border-color, fill, stroke, opacity, box-shadow, transform, filter, -webkit-text-decoration-color, -webkit-backdrop-filter !important;
|
||||
transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter !important;
|
||||
@@ -1910,8 +1931,9 @@ video {
|
||||
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
||||
}
|
||||
|
||||
.hover\:border-b-4:hover {
|
||||
border-bottom-width: 4px;
|
||||
.hover\:border-stone-700:hover {
|
||||
--tw-border-opacity: 1;
|
||||
border-color: rgb(68 64 60 / var(--tw-border-opacity));
|
||||
}
|
||||
|
||||
.hover\:border-stone-200:hover {
|
||||
@@ -1919,11 +1941,6 @@ video {
|
||||
border-color: rgb(231 229 228 / var(--tw-border-opacity));
|
||||
}
|
||||
|
||||
.hover\:border-stone-700:hover {
|
||||
--tw-border-opacity: 1;
|
||||
border-color: rgb(68 64 60 / var(--tw-border-opacity));
|
||||
}
|
||||
|
||||
.hover\:border-rose-500:hover {
|
||||
--tw-border-opacity: 1;
|
||||
border-color: rgb(244 63 94 / var(--tw-border-opacity));
|
||||
@@ -1974,6 +1991,11 @@ video {
|
||||
background-color: rgb(214 211 209 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.hover\:bg-rose-700:hover {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(190 18 60 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.hover\:bg-stone-50:hover {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(250 250 249 / var(--tw-bg-opacity));
|
||||
@@ -1994,21 +2016,6 @@ video {
|
||||
background-color: rgb(202 138 4 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.hover\:bg-rose-700:hover {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(190 18 60 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.hover\:bg-cyan-500:hover {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(6 182 212 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.hover\:bg-stone-50:hover {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(250 250 249 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.hover\:text-stone-50:hover {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(250 250 249 / var(--tw-text-opacity));
|
||||
@@ -2034,6 +2041,10 @@ video {
|
||||
text-decoration-line: underline;
|
||||
}
|
||||
|
||||
.hover\:opacity-100:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.focus\:border-blue-600:focus {
|
||||
--tw-border-opacity: 1;
|
||||
border-color: rgb(37 99 235 / var(--tw-border-opacity));
|
||||
@@ -2084,19 +2095,14 @@ video {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.disabled\:bg-stone-50:disabled {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(250 250 249 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.disabled\:bg-stone-200:disabled {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(231 229 228 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.disabled\:text-stone-900:disabled {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(28 25 23 / var(--tw-text-opacity));
|
||||
.disabled\:bg-stone-50:disabled {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(250 250 249 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.disabled\:text-stone-800:disabled {
|
||||
@@ -2104,6 +2110,11 @@ video {
|
||||
color: rgb(41 37 36 / var(--tw-text-opacity));
|
||||
}
|
||||
|
||||
.disabled\:text-stone-900:disabled {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(28 25 23 / var(--tw-text-opacity));
|
||||
}
|
||||
|
||||
.group:hover .group-hover\:visible {
|
||||
visibility: visible;
|
||||
}
|
||||
|
@@ -1294,6 +1294,9 @@ bloxeditor.component('inline-formats', {
|
||||
|
||||
bloxeditor.component('image-component', {
|
||||
props: ['markdown', 'disabled', 'index'],
|
||||
components: {
|
||||
medialib: medialib
|
||||
},
|
||||
template: `<div class="dropbox pb-6">
|
||||
<input type="hidden" ref="markdown" :value="markdown" :disabled="disabled" @input="updatemarkdown" />
|
||||
<div class="flex">
|
||||
@@ -1303,13 +1306,14 @@ bloxeditor.component('image-component', {
|
||||
</div>
|
||||
<button class="imageselect w-1/2 text-center p-6" @click.prevent="openmedialib()"><svg class="icon icon-image"><use xlink:href="#icon-image"></use></svg> select from medialib</button>
|
||||
</div>
|
||||
<!--
|
||||
<transition name="fade-editor">
|
||||
<div v-if="showmedialib" class="modalWindow">
|
||||
<medialib parentcomponent="images"></medialib>
|
||||
|
||||
<Transition name="initial" appear>
|
||||
<div v-if="showmedialib" class="fixed top-0 left-0 right-0 bottom-0 bg-stone-100 z-50">
|
||||
<button class="w-full bg-stone-200 hover:bg-rose-500 hover:text-white p-2 transition duration-100" @click.prevent="showmedialib = false">{{ $filters.translate('close library') }}</button>
|
||||
<medialib parentcomponent="images" @addFromMedialibEvent="addFromMedialibFunction"></medialib>
|
||||
</div>
|
||||
</transition>
|
||||
-->
|
||||
</Transition>
|
||||
|
||||
<div class="absolute top-3 -left-5 text-stone-400">
|
||||
<svg class="icon icon-image">
|
||||
<use xlink:href="#icon-image"></use>
|
||||
@@ -1490,6 +1494,19 @@ bloxeditor.component('image-component', {
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
closemedialib()
|
||||
{
|
||||
this.showmedialib = false;
|
||||
},
|
||||
addFromMedialibFunction(value)
|
||||
{
|
||||
this.imgfile = value;
|
||||
this.imgpreview = data.urlinfo.baseurl + '/' + value;
|
||||
this.showmedialib = false;
|
||||
this.saveimage = false;
|
||||
|
||||
this.createmarkdown();
|
||||
},
|
||||
updatemarkdown(event)
|
||||
{
|
||||
this.$emit('updateMarkdownEvent', event.target.value);
|
||||
@@ -1619,19 +1636,10 @@ bloxeditor.component('image-component', {
|
||||
errors = this.$filters.translate('Maximum size of image caption is 140 characters');
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
if(this.noresize === true)
|
||||
{
|
||||
imgmarkdown = imgmarkdown + '|noresize';
|
||||
}
|
||||
*/
|
||||
|
||||
if(errors)
|
||||
{
|
||||
console.info(errors);
|
||||
// this.$parent.freezePage();
|
||||
// publishController.errors.message = errors;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1692,7 +1700,7 @@ bloxeditor.component('image-component', {
|
||||
{
|
||||
this.showresize = false;
|
||||
this.noresize = false;
|
||||
this.showmedialib = true;
|
||||
this.showmedialib = true;
|
||||
},
|
||||
isChecked(classname)
|
||||
{
|
||||
@@ -1806,6 +1814,9 @@ bloxeditor.component('image-component', {
|
||||
|
||||
bloxeditor.component('file-component', {
|
||||
props: ['markdown', 'disabled', 'index'],
|
||||
components: {
|
||||
medialib: medialib
|
||||
},
|
||||
template: `<div class="dropbox">
|
||||
<input type="hidden" ref="markdown" :value="markdown" :disabled="disabled" @input="updatemarkdown" />
|
||||
<div class="flex">
|
||||
@@ -1825,13 +1836,14 @@ bloxeditor.component('file-component', {
|
||||
{{ $filters.translate('select from medialib') }}
|
||||
</button>
|
||||
</div>
|
||||
<!--
|
||||
<transition name="fade-editor">
|
||||
<div v-if="showmedialib" class="modalWindow">
|
||||
<medialib parentcomponent="files"></medialib>
|
||||
|
||||
<Transition name="initial" appear>
|
||||
<div v-if="showmedialib" class="fixed top-0 left-0 right-0 bottom-0 bg-stone-100 z-50">
|
||||
<button class="w-full bg-stone-200 hover:bg-rose-500 hover:text-white p-2 transition duration-100" @click.prevent="showmedialib = false">{{ $filters.translate('close library') }}</button>
|
||||
<medialib parentcomponent="files" @addFromMedialibEvent="addFromMedialibFunction"></medialib>
|
||||
</div>
|
||||
</transition>
|
||||
-->
|
||||
</Transition>
|
||||
|
||||
<div class="absolute top-3 -left-5 text-stone-400">
|
||||
<svg class="icon icon-paperclip">
|
||||
<use xlink:href="#icon-paperclip"></use>
|
||||
@@ -1906,6 +1918,18 @@ bloxeditor.component('file-component', {
|
||||
this.getrestriction();
|
||||
},
|
||||
methods: {
|
||||
addFromMedialibFunction(file)
|
||||
{
|
||||
this.showmedialib = false;
|
||||
this.savefile = false;
|
||||
this.fileurl = file.url;
|
||||
this.filemeta = true;
|
||||
this.filetitle = file.name;
|
||||
this.fileextension = file.info.extension;
|
||||
|
||||
this.createmarkdown();
|
||||
this.getrestriction(file.url);
|
||||
},
|
||||
openmedialib: function()
|
||||
{
|
||||
this.showmedialib = true;
|
||||
@@ -2168,8 +2192,6 @@ bloxeditor.component('video-component', {
|
||||
},
|
||||
parseUrl(url)
|
||||
{
|
||||
alert("parse: " + url);
|
||||
|
||||
let urlparts = url.split('?');
|
||||
let urlParams = new URLSearchParams(urlparts[1]);
|
||||
|
||||
@@ -2189,7 +2211,6 @@ bloxeditor.component('video-component', {
|
||||
},
|
||||
updatemarkdown(url)
|
||||
{
|
||||
alert("update: " + url);
|
||||
this.edited = true;
|
||||
this.url = url;
|
||||
this.parseUrl(url);
|
||||
|
@@ -1,229 +1,320 @@
|
||||
const medialib = {
|
||||
props: ['parentcomponent'],
|
||||
template: `<div class="medialib">
|
||||
<div class="mt3">
|
||||
<div class="w-30 dib v-top ph4 pv3">
|
||||
<button class="f6 link br0 ba ph3 pv2 mb2 w-100 dim white bn bg-tm-red" @click.prevent="closemedialib()">{{ $filters.translate('close library') }}</button>
|
||||
<div class="w-100 relative">
|
||||
<div><input v-model="search" class="w-100 border-box pa2 mb3 br0 ba b--light-silver"><svg class="icon icon-search absolute top-1 right-1 pa1 gray"><use xlink:href="#icon-search"></use></svg></div>
|
||||
</div>
|
||||
<button @click.prevent="showImages()" class="link br0 ba ph3 pv2 mv2 mr1" :class="isImagesActive()">{{ $filters.translate('Images') }}</button>
|
||||
<button @click.prevent="showFiles()" class="link br0 ba ph3 pv2 mv2 ml1" :class="isFilesActive()">{{ $filters.translate('Files') }}</button>
|
||||
template: `<div class="max-w-7xl mx-auto p-8 overflow-auto h-full">
|
||||
<div class="flex">
|
||||
<div class="w-1/4">
|
||||
<div class="w-full relative">
|
||||
<div class="flex">
|
||||
<input v-model="search" class="h-12 px-2 py-3 border border-stone-300 bg-stone-200">
|
||||
<div class="w-1/4 h-12 px-2 py-3 center bg-stone-700 hover:bg-stone-900 text-white">
|
||||
<svg class="icon icon-search">
|
||||
<use xlink:href="#icon-search"></use>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="showimages">
|
||||
<h3 class="border-b-2 border-stone-700 pt-6 pb-3">Images</h3>
|
||||
<div class="my-3">
|
||||
<button @click.prevent="showImages('pageImages')" :class="isActive('pageImages')" class="px-2 py-1 mr-2 hover:bg-stone-700 hover:text-stone-50 transition duration-100">{{ $filters.translate('this page') }}</button>
|
||||
<button @click.prevent="showImages('allImages')" :class="isActive('allImages')" class="px-2 py-1 hover:bg-stone-700 hover:text-stone-50 transition duration-100">{{ $filters.translate('all pages') }}</button>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="showfiles">
|
||||
<h3 class="border-b-2 border-stone-700 pt-3 pb-3">Files</h3>
|
||||
<div class="my-3">
|
||||
<button @click.prevent="showFiles('pageFiles')" :class="isActive('pageFiles')" class="px-2 py-1 mr-2 hover:bg-stone-700 hover:text-stone-50 transition duration-100">{{ $filters.translate('this page') }}</button>
|
||||
<button @click.prevent="showFiles('allFiles')" :class="isActive('allFiles')" class="px-2 py-1 mr-2 hover:bg-stone-700 hover:text-stone-50 transition duration-100">{{ $filters.translate('all pages') }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-70 dib v-top center">
|
||||
<div v-if="errors" class="w-95 mv3 white bg-tm-red tc f5 lh-copy pa3">{{errors}}</div>
|
||||
<transition-group name="list">
|
||||
<div class="w-29 ma3 dib v-top bg-white shadow-tm overflow-hidden" v-for="(image, index) in filteredImages" :key="image.name" v-if="showimages">
|
||||
<a href="#" @click.prevent="selectImage(image)" :style="getBackgroundImage(image)" class="link mw5 dt hide-child cover bg-center">
|
||||
<span class="white dtc v-mid center w-100 h-100 child bg-black-80 pa5"><svg class="icon icon-check baseline"><use xlink:href="#icon-check"></use></svg> click to select</span>
|
||||
</a>
|
||||
<div>
|
||||
<div class="w-70 dib v-top pl3 pv3 f6 truncate"><strong>{{ image.name }}</strong></div>
|
||||
<button @click.prevent="showImageDetails(image,index)" class="w-15 center dib link bn v-mid pv3 bg-white hover-bg-tm-green hover-white"><svg class="icon icon-info baseline"><use xlink:href="#icon-info"></use></svg></button>
|
||||
<button @click.prevent="deleteImage(image,index)" class="w-15 center dib link bn v-mid pv3 bg-white hover-bg-tm-red hover-white"><svg class="icon icon-trash-o baseline"><use xlink:href="#icon-trash-o"></use></svg></button>
|
||||
<div class="w-3/4">
|
||||
<div v-if="errors" class="w-full mb-4 p-2 bg-rose-500 text-stone-50">{{errors}}</div>
|
||||
<div class="flex flex-wrap justify-start px-5">
|
||||
<TransitionGroup name="list">
|
||||
<div v-for="(image, index) in filteredImages" :key="image.name" v-if="showimages" class="w-60 ml-5 mr-5 mb-10 shadow-md overflow-hidden bg-stone-50">
|
||||
<a href="#" @click.prevent="selectImage(image)" :style="getBackgroundImage(image)" class="inline-block bg-cover">
|
||||
<span class="transition-opacity duration-100 opacity-0 hover:opacity-100 flex items-center justify-center h-32 bg-black/75 text-white">
|
||||
<svg class="icon icon-check">
|
||||
<use xlink:href="#icon-check"></use>
|
||||
</svg> click to select
|
||||
</span>
|
||||
</a>
|
||||
<div class="flex">
|
||||
<div class="w-3/4 truncate p-3">{{ image.name }}</div>
|
||||
<div class="w-1/4 flex">
|
||||
<button @click.prevent="showImageDetails(image,index)" class="w-1/2 bg-stone-50 hover:bg-teal-500 hover:text-white transition duration-100">
|
||||
<svg class="icon icon-info">
|
||||
<use xlink:href="#icon-info"></use>
|
||||
</svg>
|
||||
</button>
|
||||
<button @click.prevent="deleteImage(image,index)" class="w-1/2 hover:bg-rose-500 hover:text-white transition duration-100">
|
||||
<svg class="icon icon-trash-o">
|
||||
<use xlink:href="#icon-trash-o"></use>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</transition-group>
|
||||
<div class="w-95 dib v-top bg-white mv3 relative" v-if="showimagedetails">
|
||||
<div class="flex flex-wrap item-start">
|
||||
<div class="w-50">
|
||||
<div class="w6 h6 bg-black-40 dtc v-mid bg-chess">
|
||||
<img :src="getImageUrl(imagedetaildata.src_live)" class="mw6 max-h6 dt center">
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-50 pa3 lh-copy f7 relative">
|
||||
<div class="black-30 mt3 mb1">Name</div><div class="b">{{ imagedetaildata.name}}</div>
|
||||
<div class="black-30 mt3 mb1">URL</div><div class="b">{{ getImageUrl(imagedetaildata.src_live)}}</div>
|
||||
<div class="flex flex-wrap item-start">
|
||||
<div class="w-50">
|
||||
<div class="black-30 mt3 mb1">Size</div><div class="b">{{ getSize(imagedetaildata.bytes) }}</div>
|
||||
</div>
|
||||
<div class="w-50">
|
||||
<div class="black-30 mt3 mb1">Dimensions</div><div class="b">{{ imagedetaildata.width }}x{{ imagedetaildata.height }} px</div>
|
||||
</div>
|
||||
<div class="w-50">
|
||||
<div class="black-30 mt3 mb1">Type</div><div class="b">{{ imagedetaildata.type }}</div>
|
||||
</div>
|
||||
<div class="w-50">
|
||||
<div class="black-30 mt3 mb1">Date</div><div class="b">{{ getDate(imagedetaildata.timestamp) }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="absolute w-90 bottom-0 flex justify-between">
|
||||
<button @click.prevent="selectImage(imagedetaildata)" class="w-50 mr1 pa2 link bn bg-light-gray hover-bg-tm-green hover-white"><svg class="icon icon-check baseline"><use xlink:href="#icon-check"></use></svg> select</button>
|
||||
<button @click.prevent="deleteImage(imagedetaildata, detailindex)" class="w-50 ml1 pa2 link bn bg-light-gray hover-bg-tm-red hover-white"><svg class="icon icon-trash-o baseline"><use xlink:href="#icon-trash-o"></use></svg> delete</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button class="f7 link br0 ba ph3 pv2 dim white bn bg-tm-red absolute top-0 right-0" @click.prevent="showImages()">close details</button>
|
||||
<div class="pa3">
|
||||
<h4>Image used in:</h4>
|
||||
<ul class="ma0 pa0" v-if="imagedetaildata.pages && imagedetaildata.pages.length > 0">
|
||||
<li class="list pa1" v-for="page in imagedetaildata.pages">
|
||||
<a class="link tm-red" :href="adminurl + page">{{ page }}</a>
|
||||
</li>
|
||||
</ul>
|
||||
<div v-else>No pages found.</div>'+
|
||||
</div>
|
||||
</TransitionGroup>
|
||||
</div>
|
||||
<transition-group name="list">
|
||||
<div class="w-29 ma3 dib v-top bg-white shadow-tm overflow-hidden" v-for="(file, index) in filteredFiles" :key="file.name" v-if="showfiles">
|
||||
<a href="#" @click.prevent="selectFile(file)" class="w-100 link cover bg-tm-green bg-center relative dt">
|
||||
<div class="absolute w-100 tc white f1 top-3 h0 ttu" v-html="file.info.extension"></div>
|
||||
<div class="link dt hide-child w-100">
|
||||
<span class="white dtc v-top center w-100 h-100 child pt6 pb3 tc"><svg class="icon icon-check baseline"><use xlink:href="#icon-check"></use></svg> click to select</span>
|
||||
</div>
|
||||
</a>
|
||||
<div>
|
||||
<div class="w-70 dib v-top pl3 pv3 f6 truncate"><strong>{{ file.name }}</strong></div>
|
||||
<button @click.prevent="showFileDetails(file,index)" class="w-15 center dib link bn v-mid pv3 bg-white hover-bg-tm-green hover-white"><svg class="icon icon-info baseline"><use xlink:href="#icon-info"></use></svg></button>
|
||||
<button @click.prevent="deleteFile(file,index)" class="w-15 center dib link bn v-mid pv3 bg-white hover-bg-tm-red hover-white"><svg class="icon icon-trash-o baseline"><use xlink:href="#icon-trash-o"></use></svg></button>
|
||||
</div>
|
||||
</div>
|
||||
</transition-group>
|
||||
<div class="w-95 dib v-top bg-white mv3 relative" v-if="showfiledetails">
|
||||
<div class="flex flex-wrap item-start">
|
||||
<div class="w-50">
|
||||
<div class="w6 h6 bg-black-40 dtc v-mid bg-tm-green tc">
|
||||
<div class="w-100 dt center white f1 ttu">{{ filedetaildata.info.extension }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-50 pa3 lh-copy f7 relative">
|
||||
<div class="black-30 mt3 mb1">Name</div><div class="b">{{ filedetaildata.name}}</div>
|
||||
<div class="black-30 mt3 mb1">URL</div><div class="b">{{ filedetaildata.url}}</div>
|
||||
<div class="flex flex-wrap item-start">
|
||||
<div class="w-50">
|
||||
<div class="black-30 mt3 mb1">Size</div><div class="b">{{ getSize(filedetaildata.bytes) }}</div>
|
||||
</div>
|
||||
<div class="w-50">
|
||||
<div class="black-30 mt3 mb1">Type</div><div class="b">{{ filedetaildata.info.extension }}</div>
|
||||
</div>
|
||||
<div class="w-50">
|
||||
<div class="black-30 mt3 mb1">Date</div><div class="b">{{ getDate(filedetaildata.timestamp) }}</div>
|
||||
<Transition name="fade">
|
||||
<div class="px-5" v-if="showimagedetails">
|
||||
<div class="flex flex-wrap item-start relative">
|
||||
<div class="w-1/2 bg-stone-50">
|
||||
<div class="w-80 h-80 table-cell align-middle bg-chess">
|
||||
<img :src="getImageUrl(imagedetaildata.src_live)" class="max-w-xs max-h-80 table mx-auto">
|
||||
</div>
|
||||
</div>
|
||||
<div class="absolute w-90 bottom-0 flex justify-between">
|
||||
<button @click.prevent="selectFile(filedetaildata)" class="w-50 mr1 pa2 link bn bg-light-gray hover-bg-tm-green hover-white"><svg class="icon icon-check baseline"><use xlink:href="#icon-check"></use></svg> select</button>
|
||||
<button @click.prevent="deleteFile(filedetaildata, detailindex)" class="w-50 ml1 pa2 link bn bg-light-gray hover-bg-tm-red hover-white"><svg class="icon icon-trash-o baseline"><use xlink:href="#icon-trash-o"></use></svg> delete</button>
|
||||
<div class="w-1/2 bg-stone-50 p-4 text-xs">
|
||||
<div class="text-stone-500 mt-3 mb-1">Name</div>
|
||||
<div class="font-bold">{{ imagedetaildata.name}}</div>
|
||||
<div class="text-stone-500 mt-3 mb-1">URL</div>
|
||||
<div class="font-bold">{{ getImageUrl(imagedetaildata.src_live)}}</div>
|
||||
<div class="flex flex-wrap item-start">
|
||||
<div class="w-1/2">
|
||||
<div class="text-stone-500 mt-3 mb-1">Size</div>
|
||||
<div class="font-bold">{{ getSize(imagedetaildata.bytes) }}</div>
|
||||
</div>
|
||||
<div class="w-1/2">
|
||||
<div class="text-stone-500 mt-3 mb-1">Dimensions</div>
|
||||
<div class="font-bold">{{ imagedetaildata.width }}x{{ imagedetaildata.height }} px</div>
|
||||
</div>
|
||||
<div class="w-1/2">
|
||||
<div class="text-stone-500 mt-3 mb-1">Type</div>
|
||||
<div class="font-bold">{{ imagedetaildata.type }}</div>
|
||||
</div>
|
||||
<div class="w-1/2">
|
||||
<div class="text-stone-500 mt-3 mb-1">Date</div>
|
||||
<div class="font-bold">{{ getDate(imagedetaildata.timestamp) }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-full flex justify-between mt-8">
|
||||
<button @click.prevent="selectImage(imagedetaildata)" class="w-1/2 p-2 mr-2 bg-stone-200 hover:bg-teal-500 hover:text-white transition duration-100">
|
||||
<svg class="icon icon-check">
|
||||
<use xlink:href="#icon-check"></use>
|
||||
</svg> select
|
||||
</button>
|
||||
<button @click.prevent="deleteImage(imagedetaildata, detailindex)" class="w-1/2 p-2 bg-stone-200 hover:bg-rose-500 hover:text-white transition duration-100">
|
||||
<svg class="icon icon-trash-o baseline">
|
||||
<use xlink:href="#icon-trash-o"></use>
|
||||
</svg> delete
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<button class="text-xs px-3 py-2 text-stone-50 bg-rose-500 hover:bg-rose-700 absolute top-0 right-0" @click.prevent="showImages()">close details</button>
|
||||
</div>
|
||||
</div>
|
||||
<button class="f7 link br0 ba ph3 pv2 dim white bn bg-tm-red absolute top-0 right-0" @click.prevent="showFiles()">close details</button>
|
||||
<div class="pa3">
|
||||
<h4>File used in:</h4>
|
||||
<ul class="ma0 pa0" v-if="filedetaildata.pages && filedetaildata.pages.length > 0">
|
||||
<li class="list pa1" v-for="page in filedetaildata.pages">
|
||||
<a class="link tm-red" :href="adminurl + page">{{ page }}</a>
|
||||
</li>
|
||||
</ul>
|
||||
<div v-else>No pages found.</div>'+
|
||||
</div>
|
||||
</Transition>
|
||||
<div class="flex flex-wrap justify-start px-5">
|
||||
<TransitionGroup name="list">
|
||||
<div v-for="(file, index) in filteredFiles" :key="file.name" v-if="showfiles" class="w-60 ml-5 mr-5 mb-10 shadow-md overflow-hidden bg-stone-50">
|
||||
<a href="#" @click.prevent="selectFile(file)" class="w-full bg-teal-500 inline-block bg-cover relative">
|
||||
<div class="absolute top-10 w-full text-white text-4xl uppercase text-center">{{ file.info.extension }}</div>
|
||||
<span class="relative transition-opacity duration-100 opacity-0 hover:opacity-100 flex items-center justify-center h-32 bg-black/75 text-white">
|
||||
<svg class="icon icon-check">
|
||||
<use xlink:href="#icon-check"></use>
|
||||
</svg> click to select
|
||||
</span>
|
||||
</a>
|
||||
<div class="flex">
|
||||
<div class="w-3/4 truncate p-3">{{ file.name }}</div>
|
||||
<div class="w-1/4 flex">
|
||||
<button @click.prevent="showFileDetails(file,index)" class="w-1/2 bg-stone-50 hover:bg-teal-500 hover:text-white transition duration-100">
|
||||
<svg class="icon icon-info">
|
||||
<use xlink:href="#icon-info"></use>
|
||||
</svg>
|
||||
</button>
|
||||
<button @click.prevent="deleteFile(file,index)" class="w-1/2 hover:bg-rose-500 hover:text-white transition duration-100">
|
||||
<svg class="icon icon-trash-o">
|
||||
<use xlink:href="#icon-trash-o"></use>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</TransitionGroup>
|
||||
</div>
|
||||
<Transition name="fade">
|
||||
<div class="px-5" v-if="showfiledetails">
|
||||
<div class="flex flex-wrap item-start relative">
|
||||
<div class="w-1/2 bg-stone-50">
|
||||
<div class="w-80 h-80 table-cell align-middle bg-teal-500">
|
||||
<div class="w-full text-white text-4xl uppercase text-center">{{ filedetaildata.info.extension }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-1/2 bg-stone-50 p-4 text-xs">
|
||||
<div class="text-stone-500 mt-3 mb-1">Name</div>
|
||||
<div class="font-bold">{{ filedetaildata.name}}</div>
|
||||
<div class="text-stone-500 mt-3 mb-1">URL</div>
|
||||
<div class="font-bold">{{ filedetaildata.url }}</div>
|
||||
<div class="flex flex-wrap item-start">
|
||||
<div class="w-1/2">
|
||||
<div class="text-stone-500 mt-3 mb-1">Size</div>
|
||||
<div class="font-bold">{{ getSize(filedetaildata.bytes) }}</div>
|
||||
</div>
|
||||
<div class="w-1/2">
|
||||
<div class="text-stone-500 mt-3 mb-1">Type</div>
|
||||
<div class="font-bold">{{ filedetaildata.info.extension }}</div>
|
||||
</div>
|
||||
<div class="w-1/2">
|
||||
<div class="text-stone-500 mt-3 mb-1">Date</div>
|
||||
<div class="font-bold">{{ getDate(filedetaildata.timestamp) }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-full flex justify-between mt-8">
|
||||
<button @click.prevent="selectFile(filedetaildata)" class="w-1/2 p-2 mr-2 bg-stone-200 hover:bg-teal-500 hover:text-white transition duration-100">
|
||||
<svg class="icon icon-check">
|
||||
<use xlink:href="#icon-check"></use>
|
||||
</svg> select
|
||||
</button>
|
||||
<button @click.prevent="deleteFile(filedetaildata, detailindex)" class="w-1/2 p-2 bg-stone-200 hover:bg-rose-500 hover:text-white transition duration-100">
|
||||
<svg class="icon icon-trash-o baseline">
|
||||
<use xlink:href="#icon-trash-o"></use>
|
||||
</svg> delete
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<button class="text-xs px-3 py-2 text-stone-50 bg-rose-500 hover:bg-rose-700 absolute top-0 right-0" @click.prevent="showFiles('all')">close details</button>
|
||||
</div>
|
||||
</div>
|
||||
</Transition>
|
||||
</div>
|
||||
</div>
|
||||
</div>`,
|
||||
data: function(){
|
||||
return {
|
||||
imagedata: false,
|
||||
showimages: true,
|
||||
imagedetaildata: false,
|
||||
showimagedetails: false,
|
||||
filedata: false,
|
||||
showfiles: false,
|
||||
filedetaildata: false,
|
||||
showfiledetails: false,
|
||||
detailindex: false,
|
||||
load: false,
|
||||
baseurl: myaxios.defaults.baseURL,
|
||||
adminurl: false,
|
||||
search: '',
|
||||
errors: false,
|
||||
active: false,
|
||||
imagedata: false,
|
||||
pagemedia: false,
|
||||
showimages: true,
|
||||
imagedetaildata: false,
|
||||
showimagedetails: false,
|
||||
filedata: false,
|
||||
showfiles: false,
|
||||
filedetaildata: false,
|
||||
showfiledetails: false,
|
||||
detailindex: false,
|
||||
load: false,
|
||||
adminurl: false,
|
||||
baseurl: data.urlinfo.baseurl,
|
||||
search: '',
|
||||
errors: false,
|
||||
}
|
||||
},
|
||||
mounted: function(){
|
||||
|
||||
|
||||
this.errors = false;
|
||||
|
||||
var self = this;
|
||||
|
||||
tmaxios.get('/api/v1/pagemedia',{
|
||||
params: {
|
||||
'url': data.urlinfo.route,
|
||||
'path': data.item.pathWithoutType
|
||||
}
|
||||
})
|
||||
.then(function (response)
|
||||
{
|
||||
self.pagemedia = response.data.pagemedia;
|
||||
})
|
||||
.catch(function (error)
|
||||
{
|
||||
if(error.response)
|
||||
{
|
||||
self.errors = error.response.data.errors;
|
||||
}
|
||||
});
|
||||
|
||||
if(this.parentcomponent == 'files')
|
||||
{
|
||||
this.showFiles();
|
||||
this.active = 'pageFiles';
|
||||
}
|
||||
if(this.parentcomponent == 'images')
|
||||
{
|
||||
this.showImages();
|
||||
this.active = 'pageImages';
|
||||
}
|
||||
|
||||
this.errors = false;
|
||||
var self = this;
|
||||
|
||||
myaxios.get('/api/v1/medialib/images',{
|
||||
params: {
|
||||
'url': document.getElementById("path").value,
|
||||
}
|
||||
})
|
||||
.then(function (response)
|
||||
{
|
||||
self.imagedata = response.data.images;
|
||||
})
|
||||
.catch(function (error)
|
||||
{
|
||||
if(error.response)
|
||||
{
|
||||
self.errors = error.response.data.errors;
|
||||
}
|
||||
});
|
||||
},
|
||||
computed: {
|
||||
filteredImages() {
|
||||
computed: {
|
||||
filteredImages() {
|
||||
|
||||
var searchimages = this.search;
|
||||
var filteredImages = {};
|
||||
var images = this.imagedata;
|
||||
if(images)
|
||||
{
|
||||
Object.keys(images).forEach(function(key) {
|
||||
var searchindex = key + ' ' + images[key].name;
|
||||
if(searchindex.toLowerCase().indexOf(searchimages.toLowerCase()) !== -1)
|
||||
{
|
||||
filteredImages[key] = images[key];
|
||||
}
|
||||
});
|
||||
}
|
||||
return filteredImages;
|
||||
},
|
||||
filteredFiles() {
|
||||
var searchimages = this.search;
|
||||
var filteredImages = {};
|
||||
var images = this.imagedata;
|
||||
var pagemedia = this.pagemedia;
|
||||
var active = this.active;
|
||||
|
||||
var searchfiles = this.search;
|
||||
var filteredFiles = {};
|
||||
var files = this.filedata;
|
||||
if(files)
|
||||
{
|
||||
Object.keys(files).forEach(function(key) {
|
||||
var searchindex = key + ' ' + files[key].name;
|
||||
if(searchindex.toLowerCase().indexOf(searchfiles.toLowerCase()) !== -1)
|
||||
{
|
||||
filteredFiles[key] = files[key];
|
||||
}
|
||||
});
|
||||
}
|
||||
return filteredFiles;
|
||||
}
|
||||
},
|
||||
if(images)
|
||||
{
|
||||
if(active == 'pageImages')
|
||||
{
|
||||
Object.keys(images).forEach(function(key) {
|
||||
var imagename = images[key].name;
|
||||
if(pagemedia.indexOf(imagename) !== -1)
|
||||
{
|
||||
filteredImages[key] = images[key];
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
Object.keys(images).forEach(function(key) {
|
||||
var searchindex = key + ' ' + images[key].name;
|
||||
if(searchindex.toLowerCase().indexOf(searchimages.toLowerCase()) !== -1)
|
||||
{
|
||||
filteredImages[key] = images[key];
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
return filteredImages;
|
||||
},
|
||||
filteredFiles() {
|
||||
|
||||
var searchfiles = this.search;
|
||||
var filteredFiles = {};
|
||||
var files = this.filedata;
|
||||
var pagemedia = this.pagemedia;
|
||||
var active = this.active;
|
||||
|
||||
if(files)
|
||||
{
|
||||
if(active == 'pageFiles')
|
||||
{
|
||||
Object.keys(files).forEach(function(key) {
|
||||
var filename = files[key].name;
|
||||
if(pagemedia.indexOf(filename) !== -1)
|
||||
{
|
||||
filteredFiles[key] = files[key];
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
Object.keys(files).forEach(function(key) {
|
||||
var searchindex = key + ' ' + files[key].name;
|
||||
if(searchindex.toLowerCase().indexOf(searchfiles.toLowerCase()) !== -1)
|
||||
{
|
||||
filteredFiles[key] = files[key];
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
return filteredFiles;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
isImagesActive: function()
|
||||
isActive(activestring)
|
||||
{
|
||||
if(this.showimages)
|
||||
if(this.active == activestring)
|
||||
{
|
||||
return 'bg-tm-green white';
|
||||
return 'bg-stone-700 text-stone-50';
|
||||
}
|
||||
return 'bg-light-gray black';
|
||||
return 'bg-stone-200';
|
||||
},
|
||||
isFilesActive: function()
|
||||
{
|
||||
if(this.showfiles)
|
||||
{
|
||||
return 'bg-tm-green white';
|
||||
}
|
||||
return 'bg-light-gray black';
|
||||
},
|
||||
closemedialib: function()
|
||||
{
|
||||
this.$parent.showmedialib = false;
|
||||
},
|
||||
getBackgroundImage: function(image)
|
||||
getBackgroundImage(image)
|
||||
{
|
||||
return 'background-image: url(' + this.baseurl + '/' + image.src_thumb + ');width:250px';
|
||||
},
|
||||
@@ -231,238 +322,184 @@ const medialib = {
|
||||
{
|
||||
return this.baseurl + '/' + relativeUrl;
|
||||
},
|
||||
showImages: function()
|
||||
showImages(pagesOrAll)
|
||||
{
|
||||
this.errors = false;
|
||||
this.showimages = true;
|
||||
this.showfiles = false;
|
||||
this.showimagedetails = false;
|
||||
this.showfiledetails = false;
|
||||
this.imagedetaildata = false;
|
||||
this.detailindex = false;
|
||||
},
|
||||
showFiles: function()
|
||||
{
|
||||
this.showimages = false;
|
||||
this.showfiles = true;
|
||||
this.showimagedetails = false;
|
||||
this.showfiledetails = false;
|
||||
this.imagedetaildata = false;
|
||||
this.filedetaildata = false;
|
||||
this.detailindex = false;
|
||||
this.active = pagesOrAll;
|
||||
this.errors = false;
|
||||
this.showimages = true;
|
||||
this.showfiles = false;
|
||||
this.showimagedetails = false;
|
||||
this.showfiledetails = false;
|
||||
this.imagedetaildata = false;
|
||||
this.detailindex = false;
|
||||
|
||||
if(!this.imagedata)
|
||||
{
|
||||
this.errors = false;
|
||||
|
||||
if(!this.files)
|
||||
var imageself = this;
|
||||
|
||||
tmaxios.get('/api/v1/images',{
|
||||
params: {
|
||||
'url': data.urlinfo.route,
|
||||
'path': data.item.pathWithoutType
|
||||
}
|
||||
})
|
||||
.then(function (response)
|
||||
{
|
||||
imageself.imagedata = response.data.images;
|
||||
})
|
||||
.catch(function (error)
|
||||
{
|
||||
if(error.response)
|
||||
{
|
||||
imageself.errors = error.response.data.errors;
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
showFiles(pagesOrAll)
|
||||
{
|
||||
this.active = pagesOrAll;
|
||||
this.showimages = false;
|
||||
this.showfiles = true;
|
||||
this.showimagedetails = false;
|
||||
this.showfiledetails = false;
|
||||
this.imagedetaildata = false;
|
||||
this.filedetaildata = false;
|
||||
this.detailindex = false;
|
||||
|
||||
if(!this.filedata)
|
||||
{
|
||||
this.errors = false;
|
||||
var filesself = this;
|
||||
|
||||
myaxios.get('/api/v1/medialib/files',{
|
||||
params: {
|
||||
'url': document.getElementById("path").value,
|
||||
'csrf_name': document.getElementById("csrf_name").value,
|
||||
'csrf_value': document.getElementById("csrf_value").value,
|
||||
}
|
||||
tmaxios.get('/api/v1/files',{
|
||||
params: {
|
||||
'url': data.urlinfo.route,
|
||||
}
|
||||
})
|
||||
.then(function (response)
|
||||
{
|
||||
filesself.filedata = response.data.files;
|
||||
})
|
||||
.catch(function (error)
|
||||
{
|
||||
if(error.response)
|
||||
{
|
||||
filesself.errors = error.response.data.errors;
|
||||
}
|
||||
});
|
||||
.then(function (response)
|
||||
{
|
||||
filesself.filedata = response.data.files;
|
||||
})
|
||||
.catch(function (error)
|
||||
{
|
||||
if(error.response)
|
||||
{
|
||||
filesself.errors = error.response.data.errors;
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
showImageDetails: function(image,index)
|
||||
showImageDetails(image,index)
|
||||
{
|
||||
this.errors = false;
|
||||
this.showimages = false;
|
||||
this.showfiles = false;
|
||||
this.showimagedetails = true;
|
||||
this.detailindex = index;
|
||||
this.adminurl = myaxios.defaults.baseURL + '/tm/content/visual';
|
||||
this.errors = false;
|
||||
this.showimages = false;
|
||||
this.showfiles = false;
|
||||
this.showimagedetails = true;
|
||||
this.showfiledetails = false;
|
||||
this.detailindex = index;
|
||||
this.adminurl = this.baseurl + '/tm/content/visual';
|
||||
|
||||
var imageself = this;
|
||||
|
||||
myaxios.get('/api/v1/image',{
|
||||
params: {
|
||||
'url': document.getElementById("path").value,
|
||||
'name': image.name,
|
||||
'csrf_name': document.getElementById("csrf_name").value,
|
||||
'csrf_value': document.getElementById("csrf_value").value,
|
||||
}
|
||||
})
|
||||
.then(function (response)
|
||||
{
|
||||
imageself.imagedetaildata = response.data.image;
|
||||
})
|
||||
.catch(function (error)
|
||||
{
|
||||
if(error.response)
|
||||
{
|
||||
imageself.errors = error.response.data.errors;
|
||||
}
|
||||
});
|
||||
},
|
||||
showFileDetails: function(file,index)
|
||||
{
|
||||
this.errors = false;
|
||||
this.showimages = false;
|
||||
this.showfiles = false;
|
||||
this.showimagedetails = false;
|
||||
this.showfiledetails = true;
|
||||
this.detailindex = index;
|
||||
|
||||
this.adminurl = myaxios.defaults.baseURL + '/tm/content/visual';
|
||||
|
||||
var fileself = this;
|
||||
|
||||
myaxios.get('/api/v1/file',{
|
||||
params: {
|
||||
'url': document.getElementById("path").value,
|
||||
'name': file.name,
|
||||
'csrf_name': document.getElementById("csrf_name").value,
|
||||
'csrf_value': document.getElementById("csrf_value").value,
|
||||
}
|
||||
})
|
||||
.then(function (response)
|
||||
{
|
||||
fileself.filedetaildata = response.data.file;
|
||||
})
|
||||
.catch(function (error)
|
||||
{
|
||||
if(error.response)
|
||||
{
|
||||
fileself.errors = error.response.data.errors;
|
||||
}
|
||||
});
|
||||
},
|
||||
selectImage: function(image)
|
||||
{
|
||||
this.showImages();
|
||||
|
||||
if(this.parentcomponent == 'images')
|
||||
{
|
||||
var imgmarkdown = {target: {value: '' }};
|
||||
|
||||
this.$parent.imgfile = image.src_live;
|
||||
this.$parent.imgpreview = this.baseurl + '/' + image.src_live;
|
||||
this.$parent.imgmeta = true;
|
||||
|
||||
this.$parent.showmedialib = false;
|
||||
|
||||
this.$parent.createmarkdown(image.src_live);
|
||||
/* this.$parent.updatemarkdown(imgmarkdown, image.src_live); */
|
||||
}
|
||||
if(this.parentcomponent == 'files')
|
||||
{
|
||||
var filemarkdown = {target: {value: '[' + image.name + '](' + image.src_live +'){.tm-download}' }};
|
||||
|
||||
this.$parent.filemeta = true;
|
||||
this.$parent.filetitle = image.name;
|
||||
|
||||
this.$parent.showmedialib = false;
|
||||
|
||||
this.$parent.updatemarkdown(filemarkdown, image.src_live);
|
||||
}
|
||||
},
|
||||
selectFile: function(file)
|
||||
{
|
||||
/* if image component is open */
|
||||
if(this.parentcomponent == 'images')
|
||||
{
|
||||
var imgextensions = ['png','jpg', 'jpeg', 'gif', 'svg', 'webp'];
|
||||
if(imgextensions.indexOf(file.info.extension) == -1)
|
||||
{
|
||||
this.errors = "you cannot insert a file into an image component";
|
||||
return;
|
||||
tmaxios.get('/api/v1/image',{
|
||||
params: {
|
||||
'url': data.urlinfo.route,
|
||||
'name': image.name,
|
||||
}
|
||||
var imgmarkdown = {target: {value: '' }};
|
||||
|
||||
this.$parent.imgfile = file.url;
|
||||
this.$parent.imgpreview = this.baseurl + '/' + file.url;
|
||||
this.$parent.imgmeta = true;
|
||||
|
||||
this.$parent.showmedialib = false;
|
||||
|
||||
this.$parent.createmarkdown(file.url);
|
||||
/* this.$parent.updatemarkdown(imgmarkdown, file.url);*/
|
||||
}
|
||||
if(this.parentcomponent == 'files')
|
||||
})
|
||||
.then(function (response)
|
||||
{
|
||||
var filemarkdown = {target: {value: '['+ file.name +']('+ file.url +'){.tm-download file-' + file.info.extension + '}' }};
|
||||
imageself.imagedetaildata = response.data.image;
|
||||
})
|
||||
.catch(function (error)
|
||||
{
|
||||
if(error.response)
|
||||
{
|
||||
imageself.errors = error.response.data.errors;
|
||||
}
|
||||
});
|
||||
},
|
||||
showFileDetails(file,index)
|
||||
{
|
||||
this.errors = false;
|
||||
this.showimages = false;
|
||||
this.showfiles = false;
|
||||
this.showimagedetails = false;
|
||||
this.showfiledetails = true;
|
||||
this.filedetaildata = file;
|
||||
this.detailindex = index;
|
||||
this.adminurl = this.baseurl + '/tm/content/visual';
|
||||
},
|
||||
selectImage(image)
|
||||
{
|
||||
this.$emit('addFromMedialibEvent', image.src_live);
|
||||
},
|
||||
selectFile(file)
|
||||
{
|
||||
let extension = file.info.extension.toUpperCase();
|
||||
let size = this.getSize(file.bytes);
|
||||
file.name = file.name + ' (' + extension + ', ' + size + ')';
|
||||
|
||||
this.$parent.showmedialib = false;
|
||||
|
||||
this.$parent.filemeta = true;
|
||||
this.$parent.filetitle = file.info.filename + ' (' + file.info.extension.toUpperCase() + ')';
|
||||
|
||||
this.$parent.updatemarkdown(filemarkdown, file.url);
|
||||
}
|
||||
this.showFiles();
|
||||
},
|
||||
removeImage: function(index)
|
||||
this.$emit('addFromMedialibEvent', file);
|
||||
},
|
||||
removeImage(index)
|
||||
{
|
||||
this.imagedata.splice(index,1);
|
||||
},
|
||||
removeFile: function(index)
|
||||
removeFile(index)
|
||||
{
|
||||
this.filedata.splice(index,1);
|
||||
},
|
||||
deleteImage: function(image, index)
|
||||
deleteImage(image, index)
|
||||
{
|
||||
imageself = this;
|
||||
|
||||
myaxios.delete('/api/v1/image',{
|
||||
data: {
|
||||
'url': document.getElementById("path").value,
|
||||
'name': image.name,
|
||||
'index': index,
|
||||
'csrf_name': document.getElementById("csrf_name").value,
|
||||
'csrf_value': document.getElementById("csrf_value").value,
|
||||
}
|
||||
tmaxios.delete('/api/v1/image',{
|
||||
data: {
|
||||
'url': data.urlinfo.route,
|
||||
'name': image.name,
|
||||
'index': index,
|
||||
}
|
||||
})
|
||||
.then(function (response)
|
||||
{
|
||||
.then(function (response)
|
||||
{
|
||||
imageself.showImages();
|
||||
imageself.removeImage(index);
|
||||
})
|
||||
.catch(function (error)
|
||||
{
|
||||
if(error.response)
|
||||
{
|
||||
imageself.errors = error.response.data.errors;
|
||||
}
|
||||
});
|
||||
imageself.removeImage(index);
|
||||
})
|
||||
.catch(function (error)
|
||||
{
|
||||
if(error.response)
|
||||
{
|
||||
imageself.errors = error.response.data.errors;
|
||||
}
|
||||
});
|
||||
},
|
||||
deleteFile: function(file, index)
|
||||
deleteFile(file, index)
|
||||
{
|
||||
fileself = this;
|
||||
|
||||
myaxios.delete('/api/v1/file',{
|
||||
data: {
|
||||
'url': document.getElementById("path").value,
|
||||
'name': file.name,
|
||||
'index': index,
|
||||
'csrf_name': document.getElementById("csrf_name").value,
|
||||
'csrf_value': document.getElementById("csrf_value").value,
|
||||
}
|
||||
tmaxios.delete('/api/v1/file',{
|
||||
data: {
|
||||
'url': data.urlinfo.route,
|
||||
'name': file.name,
|
||||
'index': index,
|
||||
}
|
||||
})
|
||||
.then(function (response)
|
||||
{
|
||||
fileself.showFiles();
|
||||
fileself.removeFile(index);
|
||||
})
|
||||
.catch(function (error)
|
||||
{
|
||||
if(error.response)
|
||||
{
|
||||
fileself.errors = error.response.data.errors;
|
||||
}
|
||||
});
|
||||
.then(function (response)
|
||||
{
|
||||
fileself.showFiles();
|
||||
fileself.removeFile(index);
|
||||
})
|
||||
.catch(function (error)
|
||||
{
|
||||
if(error.response)
|
||||
{
|
||||
fileself.errors = error.response.data.errors;
|
||||
}
|
||||
});
|
||||
},
|
||||
getDate(timestamp)
|
||||
{
|
||||
@@ -480,12 +517,12 @@ const medialib = {
|
||||
},
|
||||
getSize(bytes)
|
||||
{
|
||||
var i = Math.floor(Math.log(bytes) / Math.log(1024)),
|
||||
sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
|
||||
var i = Math.floor(Math.log(bytes) / Math.log(1024)),
|
||||
sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
|
||||
|
||||
return (bytes / Math.pow(1024, i)).toFixed(2) * 1 + ' ' + sizes[i];
|
||||
return (bytes / Math.pow(1024, i)).toFixed(2) * 1 + ' ' + sizes[i];
|
||||
},
|
||||
isChecked: function(classname)
|
||||
isChecked(classname)
|
||||
{
|
||||
if(this.imgclass == classname)
|
||||
{
|
||||
|
@@ -121,7 +121,7 @@ const app = Vue.createApp({
|
||||
this.saved = false;
|
||||
|
||||
self = this;
|
||||
tmaxios.post('/api/v1/metadata',{
|
||||
tmaxios.post('/api/v1/meta',{
|
||||
'url': data.urlinfo.route,
|
||||
'tab': self.currentTab,
|
||||
'data': self.formData[self.currentTab]
|
||||
|
@@ -60,6 +60,7 @@
|
||||
<script src="{{ base_url() }}/system/typemill/author/js/vue.js?v={{ settings.version }}"></script>
|
||||
<script src="{{ base_url() }}/system/typemill/author/js/vue-eventbus.js?v={{ settings.version }}"></script>
|
||||
<script src="{{ base_url() }}/system/typemill/author/js/vue-shared.js?v={{ settings.version }}"></script>
|
||||
<script src="{{ base_url() }}/system/typemill/author/js/vue-medialib.js?v={{ settings.version }}"></script>
|
||||
<script src="{{ base_url() }}/system/typemill/author/js/sortable.min.js?v={{ settings.version }}"></script>
|
||||
<script src="{{ base_url() }}/system/typemill/author/js/vuedraggable.umd.min.js?v={{ settings.version }}"></script>
|
||||
<script src="{{ base_url() }}/system/typemill/author/js/vue-contentnavi.js?v={{ settings.version }}"></script>
|
||||
|
@@ -65,6 +65,7 @@
|
||||
<script src="{{ base_url() }}/system/typemill/author/js/vue.js?v={{ settings.version }}"></script>
|
||||
<script src="{{ base_url() }}/system/typemill/author/js/vue-eventbus.js?v={{ settings.version }}"></script>
|
||||
<script src="{{ base_url() }}/system/typemill/author/js/vue-shared.js?v={{ settings.version }}"></script>
|
||||
<script src="{{ base_url() }}/system/typemill/author/js/vue-medialib.js?v={{ settings.version }}"></script>
|
||||
<script>
|
||||
/* kixote.mount('#kixote'); */
|
||||
</script>
|
||||
|
@@ -40,18 +40,21 @@ $app->group('/api/v1', function (RouteCollectorProxy $group) use ($acl) {
|
||||
$group->delete('/user', ControllerApiSystemUsers::class . ':deleteUser')->setName('api.user.delete')->add(new ApiAuthorization($acl, 'account', 'delete')); # member
|
||||
|
||||
# IMAGES
|
||||
$group->get('/pagemedia', ControllerApiImage::class . ':getPagemedia')->setName('api.image.pagemedia')->add(new ApiAuthorization($acl, 'mycontent', 'read'));
|
||||
$group->get('/images', ControllerApiImage::class . ':getImages')->setName('api.image.images')->add(new ApiAuthorization($acl, 'mycontent', 'read'));
|
||||
$group->post('/image', ControllerApiImage::class . ':saveImage')->setName('api.image.create')->add(new ApiAuthorization($acl, 'mycontent', 'create'));
|
||||
$group->put('/image', ControllerApiImage::class . ':publishImage')->setName('api.image.publish')->add(new ApiAuthorization($acl, 'mycontent', 'create'));
|
||||
# $group->get('/image', ControllerApiMedia::class . ':getImage')->setName('api.image.get');
|
||||
# $group->delete('/image', ControllerApiMedia::class . ':deleteImage')->setName('api.image.delete');
|
||||
$group->get('/image', ControllerApiImage::class . ':getImage')->setName('api.image.get')->add(new ApiAuthorization($acl, 'mycontent', 'read'));
|
||||
$group->delete('/image', ControllerApiImage::class . ':deleteImage')->setName('api.image.delete')->add(new ApiAuthorization($acl, 'mycontent', 'delete'));
|
||||
|
||||
# FILES
|
||||
$group->get('/filerestrictions', ControllerApiFile::class . ':getFileRestrictions')->setName('api.file.getrestrictions')->add(new ApiAuthorization($acl, 'mycontent', 'create'));
|
||||
$group->post('/filerestrictions', ControllerApiFile::class . ':updateFileRestrictions')->setName('api.file.updaterestrictions')->add(new ApiAuthorization($acl, 'mycontent', 'create'));
|
||||
$group->post('/file', ControllerApiFile::class . ':uploadFile')->setName('api.file.upload')->add(new ApiAuthorization($acl, 'mycontent', 'create'));
|
||||
$group->put('/file', ControllerApiFile::class . ':publishFile')->setName('api.file.publish')->add(new ApiAuthorization($acl, 'mycontent', 'update'));
|
||||
# $group->get('/api/v1/file', ControllerAuthorMediaApi::class . ':getFile')->setName('api.file.get')->add(new RestrictApiAccess($container['router']));
|
||||
# $app->delete('/api/v1/file', ControllerAuthorMediaApi::class . ':deleteFile')->setName('api.file.delete')->add(new RestrictApiAccess($container['router']));
|
||||
$group->get('/files', ControllerApiFile::class . ':getFiles')->setName('api.files.get')->add(new ApiAuthorization($acl, 'mycontent', 'read'));
|
||||
$group->get('/file', ControllerApiFile::class . ':getFile')->setName('api.file.get')->add(new ApiAuthorization($acl, 'mycontent', 'read'));
|
||||
$group->delete('/file', ControllerApiFile::class . ':deleteFile')->setName('api.file.delete')->add(new ApiAuthorization($acl, 'mycontent', 'read'));
|
||||
|
||||
# ARTICLE
|
||||
$group->post('/article/sort', ControllerApiAuthorArticle::class . ':sortArticle')->setName('api.article.sort')->add(new ApiAuthorization($acl, 'content', 'create')); # author
|
||||
@@ -75,9 +78,7 @@ $app->group('/api/v1', function (RouteCollectorProxy $group) use ($acl) {
|
||||
$group->get('/shortcodedata', ControllerApiAuthorShortcode::class . ':getShortcodeData')->setName('api.shortcodedata.get')->add(new ApiAuthorization($acl, 'mycontent', 'view'));
|
||||
|
||||
# META
|
||||
$group->get('/metadata', ControllerApiAuthorMeta::class . ':getMetaData')->setName('api.metadata.get')->add(new ApiAuthorization($acl, 'mycontent', 'view'));
|
||||
$group->get('/metadefinitions', ControllerApiAuthorMeta::class . ':getMetaDefinitions')->setName('api.definitions.get')->add(new ApiAuthorization($acl, 'mycontent', 'view'));
|
||||
$group->post('/metadata', ControllerApiAuthorMeta::class . ':updateMetaData')->setName('api.metadata.update')->add(new ApiAuthorization($acl, 'mycontent', 'update'));
|
||||
$group->get('/meta', ControllerApiAuthorMeta::class . ':getMeta')->setName('api.meta.get')->add(new ApiAuthorization($acl, 'mycontent', 'view'));
|
||||
$group->post('/meta', ControllerApiAuthorMeta::class . ':updateMeta')->setName('api.metadata.update')->add(new ApiAuthorization($acl, 'mycontent', 'update'));
|
||||
|
||||
})->add(new ApiAuthentication());
|
Reference in New Issue
Block a user