From d0772caf86c2bc46d938df1551b531ddbffb00d5 Mon Sep 17 00:00:00 2001 From: trendschau Date: Thu, 13 Jul 2023 15:11:46 +0200 Subject: [PATCH] Medialib finished --- content/00-welcome/05-todos.txt | 2 +- media/files/filerestrictions.yaml | 1 + media/tmp/screenshot-typemill-startpage.png | Bin 0 -> 107495 bytes system/typemill/Controllers/Controller.php | 2 - .../Controllers/ControllerApiAuthorMeta.php | 158 +--- .../Controllers/ControllerApiFile.php | 152 ++-- .../Controllers/ControllerApiImage.php | 236 ++--- system/typemill/Models/ProcessFile.php | 86 -- system/typemill/Models/ProcessImage.php | 129 +-- system/typemill/Models/Storage.php | 248 +++++- system/typemill/author/css/custom.css | 389 +------- system/typemill/author/css/output.css | 267 +++--- .../typemill/author/js/vue-blox-components.js | 71 +- system/typemill/author/js/vue-medialib.js | 835 +++++++++--------- system/typemill/author/js/vue-meta.js | 2 +- .../author/layouts/layoutContent.twig | 1 + .../typemill/author/layouts/layoutSystem.twig | 1 + system/typemill/routes/api.php | 15 +- 18 files changed, 1075 insertions(+), 1520 deletions(-) create mode 100644 media/tmp/screenshot-typemill-startpage.png diff --git a/content/00-welcome/05-todos.txt b/content/00-welcome/05-todos.txt index 9a4099c..9e30b0f 100644 --- a/content/00-welcome/05-todos.txt +++ b/content/00-welcome/05-todos.txt @@ -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 "] \ No newline at end of file +["# 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 "] \ No newline at end of file diff --git a/media/files/filerestrictions.yaml b/media/files/filerestrictions.yaml index 2b22b99..08e86cd 100644 --- a/media/files/filerestrictions.yaml +++ b/media/files/filerestrictions.yaml @@ -1 +1,2 @@ media/files/typemill-v2-navigation.gif: member +media/files/markdown.png: member diff --git a/media/tmp/screenshot-typemill-startpage.png b/media/tmp/screenshot-typemill-startpage.png new file mode 100644 index 0000000000000000000000000000000000000000..3aef5e2e35d39ddbc8b8fb55e0b7371551964221 GIT binary patch literal 107495 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%0D2$N{l+)dvV(PZzX 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%0AD&hR^E4Dx!77O}fh(jED_ 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 literal 0 HcmV?d00001 diff --git a/system/typemill/Controllers/Controller.php b/system/typemill/Controllers/Controller.php index 60d546e..3d85cbd 100644 --- a/system/typemill/Controllers/Controller.php +++ b/system/typemill/Controllers/Controller.php @@ -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'); } diff --git a/system/typemill/Controllers/ControllerApiAuthorMeta.php b/system/typemill/Controllers/ControllerApiAuthorMeta.php index ec4dd07..45f4460 100644 --- a/system/typemill/Controllers/ControllerApiAuthorMeta.php +++ b/system/typemill/Controllers/ControllerApiAuthorMeta.php @@ -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 '

';
-		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)
 	{
diff --git a/system/typemill/Controllers/ControllerApiFile.php b/system/typemill/Controllers/ControllerApiFile.php
index 08ce8dc..7aa7294 100644
--- a/system/typemill/Controllers/ControllerApiFile.php
+++ b/system/typemill/Controllers/ControllerApiFile.php
@@ -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
diff --git a/system/typemill/Controllers/ControllerApiImage.php b/system/typemill/Controllers/ControllerApiImage.php
index db0b12b..315d2ca 100644
--- a/system/typemill/Controllers/ControllerApiImage.php
+++ b/system/typemill/Controllers/ControllerApiImage.php
@@ -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'] = '![' . $class . '-video](' . $imageUrl . ' "click to load video"){#' . $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);
 	}
-
-
 }
diff --git a/system/typemill/Models/ProcessFile.php b/system/typemill/Models/ProcessFile.php
index a8d18e1..cb9f0eb 100644
--- a/system/typemill/Models/ProcessFile.php
+++ b/system/typemill/Models/ProcessFile.php
@@ -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;
-	}
-
 }
\ No newline at end of file
diff --git a/system/typemill/Models/ProcessImage.php b/system/typemill/Models/ProcessImage.php
index 638d52a..d57eac0 100644
--- a/system/typemill/Models/ProcessImage.php
+++ b/system/typemill/Models/ProcessImage.php
@@ -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()
 	{
diff --git a/system/typemill/Models/Storage.php b/system/typemill/Models/Storage.php
index 8657acf..f61f710 100644
--- a/system/typemill/Models/Storage.php
+++ b/system/typemill/Models/Storage.php
@@ -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);
+			}
+		}
+	}
 
 
 
diff --git a/system/typemill/author/css/custom.css b/system/typemill/author/css/custom.css
index 1921edd..5e96bd6 100644
--- a/system/typemill/author/css/custom.css
+++ b/system/typemill/author/css/custom.css
@@ -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;
-}
-*/
\ No newline at end of file
+}
\ No newline at end of file
diff --git a/system/typemill/author/css/output.css b/system/typemill/author/css/output.css
index 9e979fc..5737b3a 100644
--- a/system/typemill/author/css/output.css
+++ b/system/typemill/author/css/output.css
@@ -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;
 }
diff --git a/system/typemill/author/js/vue-blox-components.js b/system/typemill/author/js/vue-blox-components.js
index 1a56b2e..8791ecb 100644
--- a/system/typemill/author/js/vue-blox-components.js
+++ b/system/typemill/author/js/vue-blox-components.js
@@ -1294,6 +1294,9 @@ bloxeditor.component('inline-formats', {
 
 bloxeditor.component('image-component', {
 	props: ['markdown', 'disabled', 'index'],
+	components: {
+		medialib: medialib
+	},	
 	template: `
@@ -1303,13 +1306,14 @@ bloxeditor.component('image-component', {
- + +
@@ -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: `
@@ -1825,13 +1836,14 @@ bloxeditor.component('file-component', { {{ $filters.translate('select from medialib') }}
- + +
@@ -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); diff --git a/system/typemill/author/js/vue-medialib.js b/system/typemill/author/js/vue-medialib.js index 35b8a69..f854432 100644 --- a/system/typemill/author/js/vue-medialib.js +++ b/system/typemill/author/js/vue-medialib.js @@ -1,229 +1,320 @@ const medialib = { props: ['parentcomponent'], - template: `
-
-
- -
-
-
- - + template: `
+
+
+
+
+ +
+ + + +
+
+
+
+

Images

+
+ + +
+
+
+

Files

+
+ + +
+
-
-
{{errors}}
- -
- - click to select - -
-
{{ image.name }}
- - +
+
{{errors}}
+
+ +
+ + + + + click to select + + +
+
{{ image.name }}
+
+ + +
+
-
- -
-
-
-
- -
-
-
-
Name
{{ imagedetaildata.name}}
-
URL
{{ getImageUrl(imagedetaildata.src_live)}}
-
-
-
Size
{{ getSize(imagedetaildata.bytes) }}
-
-
-
Dimensions
{{ imagedetaildata.width }}x{{ imagedetaildata.height }} px
-
-
-
Type
{{ imagedetaildata.type }}
-
-
-
Date
{{ getDate(imagedetaildata.timestamp) }}
-
-
-
- - -
-
-
- -
-

Image used in:

- -
No pages found.
'+ -
+
- -
- -
- -
-
-
{{ file.name }}
- - -
-
-
-
-
-
-
-
{{ filedetaildata.info.extension }}
-
-
-
-
Name
{{ filedetaildata.name}}
-
URL
{{ filedetaildata.url}}
-
-
-
Size
{{ getSize(filedetaildata.bytes) }}
-
-
-
Type
{{ filedetaildata.info.extension }}
-
-
-
Date
{{ getDate(filedetaildata.timestamp) }}
+ +
+
+
+
+
-
- - +
+
Name
+
{{ imagedetaildata.name}}
+
URL
+
{{ getImageUrl(imagedetaildata.src_live)}}
+
+
+
Size
+
{{ getSize(imagedetaildata.bytes) }}
+
+
+
Dimensions
+
{{ imagedetaildata.width }}x{{ imagedetaildata.height }} px
+
+
+
Type
+
{{ imagedetaildata.type }}
+
+
+
Date
+
{{ getDate(imagedetaildata.timestamp) }}
+
+
+
+ + +
+
- -
-

File used in:

- -
No pages found.
'+ -
+ +
+ +
+ +
{{ file.info.extension }}
+ + + + click to select + +
+
+
{{ file.name }}
+
+ + +
+
+
+
+ +
+
+
+
+
{{ filedetaildata.info.extension }}
+
+
+
+
Name
+
{{ filedetaildata.name}}
+
URL
+
{{ filedetaildata.url }}
+
+
+
Size
+
{{ getSize(filedetaildata.bytes) }}
+
+
+
Type
+
{{ filedetaildata.info.extension }}
+
+
+
Date
+
{{ getDate(filedetaildata.timestamp) }}
+
+
+
+ + +
+
+ +
+
+
`, 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: '![alt]('+ image.src_live +')' }}; - - 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: '![alt]('+ file.url +')' }}; - - 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) { diff --git a/system/typemill/author/js/vue-meta.js b/system/typemill/author/js/vue-meta.js index 26a2162..32b73d5 100644 --- a/system/typemill/author/js/vue-meta.js +++ b/system/typemill/author/js/vue-meta.js @@ -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] diff --git a/system/typemill/author/layouts/layoutContent.twig b/system/typemill/author/layouts/layoutContent.twig index 432b854..e1c607d 100644 --- a/system/typemill/author/layouts/layoutContent.twig +++ b/system/typemill/author/layouts/layoutContent.twig @@ -60,6 +60,7 @@ + diff --git a/system/typemill/author/layouts/layoutSystem.twig b/system/typemill/author/layouts/layoutSystem.twig index 1bacbb9..8fd5f50 100644 --- a/system/typemill/author/layouts/layoutSystem.twig +++ b/system/typemill/author/layouts/layoutSystem.twig @@ -65,6 +65,7 @@ + diff --git a/system/typemill/routes/api.php b/system/typemill/routes/api.php index 36bf866..514a8a4 100644 --- a/system/typemill/routes/api.php +++ b/system/typemill/routes/api.php @@ -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()); \ No newline at end of file