1
0
mirror of https://github.com/typemill/typemill.git synced 2025-08-06 14:16:46 +02:00

test php 8.2.11 and fill meta on publish

This commit is contained in:
trendschau
2023-10-16 16:50:40 +02:00
parent fafc05886e
commit 6c6e7b1a92
28 changed files with 160 additions and 137 deletions

View File

@@ -1 +0,0 @@
["# ToDos Version 2","[TOC]","## System settings","* DONE: Migrate from backend to frontend with vue and api\n* DONE: Redesign\n* DONE: License feature\n* DONE: Enhance with plugins","## Visual Editor","* DONE: Refactor and redesign\n* DONE: Fix toc component in new block\n* DONE: Fix hr component in new block\n* DONE: finish shortcode component\n* DONE: Fix inline formats\n* DONE: fix lenght of page\n* DONE: Fix design of new block at the end (background color)\n* DONE: Move Block\n* DONE: Fix headline design\n* DONE: Fix save on two enter\n* DONE: fix quote design\n* DONE: Fix toc preview\n* DONE: disable enable \n* DONE: Add load sign (from navigation)\n* DONE: File is not published from tmp to media\/files if you save the block.","## Raw Editor","* DONE: Refactor and redesign\n* DONE: Integrate highlighting","## Navigation","* DONE: Refactor and redesign\n* DONE: fix status in navigation\n* DONE: refresh navigation after changes","## Publish Controller","* DONE: Refactor and redesign\n* DONE: Create \n* DONE: publish\n* DONE: unpublish\n* DONE: discard\n* DONE: delete\n* DONE: save draft\n* DONE: switch to raw","## Meta Tabs","* DONE: Refactor and redesign\n* DONE: Enhance with plugins","## Medialib","* DONE: Refactor and redesign","## Posts","* DONE: Refactor and redesign","## Plugins","* Asset Class in progress","## Frontend","* DONE: Refactor\n* DONE: Test restrictions","## Other big tasks","* DONE: System setup\n* DONE: Recover Password","## Medium tasks","* DONE: Merge processAssets modell\n* DONE: Table of content duplicated for published pages\n* DONE: Session handling: csrf fail and session start error if restrictions are active\n* DONE: Image and files for meta","## Open tasks","* DONE: Sitemap and ping\n* DONE: Version check\n* DONE: Proxy support\n* DONE: SVG checker: https:\/\/github.com\/TribalSystems\/SVG-Sanitizer\n* DONE: Backend form builder\n* DONE: Image generation on the fly\n* DONE: Delete folder in base level\n* DONE: Make folder delete easier with glob or scandir\n* DONE: fix error messages (check models)\n* DONE: error status codes (check middleware)\n* DONE: Warn if open another block\n* DONE: Customfields not styled yet\n* DOING: Fix error api systemnavi + validate\n* FIXED: System stores html or sends wrong error messsages\n* FIXED: Wrong frontend navigation if unpublished pages\n* DONE: Icon for hidden pages\n* DOING: Responsive design\n* DONE: Captcha integration\n* DONE: Solution for logo and favicon\n* FIXED: Raw editor jumps if you edit long text at the end\n* Reference feature\n* Typemill Utilities\n* Markdown secure rendering\n* finish youtube component\n* Handle formdata centrally ???\n* BUG: Error fields in account form not styled correctly\n* DONE: Update CSS for themes\n* BUG: Codefield jumps on editing\n* False for owner on live?","## later","* Clear cache\n* Show security Log\n* User search only for +10 users\n* For api translations should be done completely in backoffice\n* Change translation files so they are loaded in settings instead of adding them manually to settings-defaults.yaml","## Cleanups:","* DONE: Events\n* DONE: Error messages\n* DONE: Translations","## Info: 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()","## Info: 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 ","## Plugins","* MAKER: Rebuild search\n* MAKER: Rebuild contactform with shortcode","## Status codes","| Status code | Description | \n|---|---|\n| 200 ok | cell | \n| 400 bad request | The request was unacceptable due to missing or invalid parameter. | \n| 401 unauthorized | The request requires an authorization. | \n| (402 request failed) | The parameters where there but the request failed for other reasons. | \n| 403 forbidden | The user is authenticated but he has not enough rights. | \n| 404 not found | new | \n| 500 internal server error | new |","## Upgrade","* Delete content of system folder\n* Upload new content of system folder with folders typemill and vendor\n* Backup and delete settings file \n* upload new index.php file\n* Upload new htaccess file\n* Delete theme folder\n* Uplload new cyanine-theme\n* Deactivate and delete all plugins."]

View File

@@ -111,6 +111,9 @@
* finish youtube component
* Handle formdata centrally ???
* BUG: Error fields in account form not styled correctly
* DONE: Update CSS for themes
* BUG: Codefield jumps on editing
* False for owner on live?
## later
@@ -160,7 +163,10 @@
* Delete content of system folder
* Upload new content of system folder with folders typemill and vendor
* Delete settings file
* Backup and delete settings file
* upload new index.php file
* Upload new htaccess file
* Delete theme folder
* Uplload new cyanine-theme
* Deactivate and delete all plugins.

File diff suppressed because one or more lines are too long

View File

@@ -32,13 +32,13 @@
navtitle: 'markdown test'
hide: false
noindex: false
path: /00-welcome/04-markdown-test.md
path: /00-welcome/05-markdown-test.md
keyPath: '0.4'
/welcome/todos:
navtitle: 'To Dos'
hide: false
noindex: false
path: /00-welcome/05-todos.txtmd
path: /00-welcome/06-todos.md
keyPath: '0.5'
/cyanine-theme:
navtitle: 'cyanine theme'

File diff suppressed because one or more lines are too long

View File

@@ -75,7 +75,7 @@ class ControllerApiAuthorArticle extends Controller
# refresh navigation and item
$navigation->clearNavigation();
$draftNavigation = $navigation->getDraftNavigation($urlinfo, $this->settings['langattr']);
$draftNavigation = $navigation->setActiveNaviItems($draftNavigation, $item->keyPathArray);
$draftNavigation = $navigation->setActiveNaviItemsWithKeyPath($draftNavigation, $item->keyPathArray);
$item = $navigation->getItemWithKeyPath($draftNavigation, $item->keyPathArray);
$sitemap = new Sitemap();
@@ -84,20 +84,21 @@ class ControllerApiAuthorArticle extends Controller
# META is important e.g. for newsletter, so send it, too
$meta = new Meta();
$metadata = $meta->getMetaData($item);
$metadata = $meta->addMetaDefaults($metadata, $item, $this->settings['author']);
# $metadata = $meta->addMetaTitleDescription($metadata, $item, $markdownArray);
$metadata = $meta->addMetaDefaults($metadata, $item, $this->settings['author'], $request->getAttribute('c_username'));
$metadata = $meta->addMetaTitleDescription($metadata, $item, $draftMarkdown);
# dispatch event, e.g. send newsletter and more
$data = [
'markdown' => $draftMarkdown,
'item' => $item,
'meta' => $metadata
'metadata' => $metadata
];
$this->c->get('dispatcher')->dispatch(new OnPagePublished($data), 'onPagePublished');
$response->getBody()->write(json_encode([
'navigation' => $draftNavigation,
'item' => $item
'item' => $item,
'metadata' => $metadata
]));
return $response->withHeader('Content-Type', 'application/json');
@@ -149,7 +150,7 @@ class ControllerApiAuthorArticle extends Controller
# refresh navigation and item
$navigation->clearNavigation();
$draftNavigation = $navigation->getDraftNavigation($urlinfo, $this->settings['langattr']);
$draftNavigation = $navigation->setActiveNaviItems($draftNavigation, $item->keyPathArray);
$draftNavigation = $navigation->setActiveNaviItemsWithKeyPath($draftNavigation, $item->keyPathArray);
$item = $navigation->getItemWithKeyPath($draftNavigation, $item->keyPathArray);
$sitemap = new Sitemap();
@@ -227,7 +228,7 @@ class ControllerApiAuthorArticle extends Controller
# refresh navigation and item
$navigation->clearNavigation();
$draftNavigation = $navigation->getDraftNavigation($urlinfo, $this->settings['langattr']);
$draftNavigation = $navigation->setActiveNaviItems($draftNavigation, $item->keyPathArray);
$draftNavigation = $navigation->setActiveNaviItemsWithKeyPath($draftNavigation, $item->keyPathArray);
$item = $navigation->getItemWithKeyPath($draftNavigation, $item->keyPathArray);
# refresh content
@@ -290,7 +291,7 @@ class ControllerApiAuthorArticle extends Controller
# refresh navigation and item
$navigation->clearNavigation();
$draftNavigation = $navigation->getDraftNavigation($urlinfo, $this->settings['langattr']);
$draftNavigation = $navigation->setActiveNaviItems($draftNavigation, $item->keyPathArray);
$draftNavigation = $navigation->setActiveNaviItemsWithKeyPath($draftNavigation, $item->keyPathArray);
$item = $navigation->getItemWithKeyPath($draftNavigation, $item->keyPathArray);
$sitemap = new Sitemap();
@@ -368,7 +369,7 @@ class ControllerApiAuthorArticle extends Controller
# refresh navigation and item
$navigation->clearNavigation();
$draftNavigation = $navigation->getDraftNavigation($urlinfo, $this->settings['langattr']);
$draftNavigation = $navigation->setActiveNaviItems($draftNavigation, $item->keyPathArray);
$draftNavigation = $navigation->setActiveNaviItemsWithKeyPath($draftNavigation, $item->keyPathArray);
$item = $navigation->getItemWithKeyPath($draftNavigation, $item->keyPathArray);
# refresh content

View File

@@ -96,7 +96,7 @@ class ControllerApiAuthorBlock extends Controller
$navigation->clearNavigation();
$draftNavigation = $navigation->getDraftNavigation($urlinfo, $this->settings['langattr']);
$draftNavigation = $navigation->setActiveNaviItems($draftNavigation, $item->keyPathArray);
$draftNavigation = $navigation->setActiveNaviItemsWithKeyPath($draftNavigation, $item->keyPathArray);
$item = $navigation->getItemWithKeyPath($draftNavigation, $item->keyPathArray);
$response->getBody()->write(json_encode([
@@ -189,7 +189,7 @@ class ControllerApiAuthorBlock extends Controller
$navigation->clearNavigation();
$draftNavigation = $navigation->getDraftNavigation($urlinfo, $this->settings['langattr']);
$draftNavigation = $navigation->setActiveNaviItems($draftNavigation, $item->keyPathArray);
$draftNavigation = $navigation->setActiveNaviItemsWithKeyPath($draftNavigation, $item->keyPathArray);
$item = $navigation->getItemWithKeyPath($draftNavigation, $item->keyPathArray);
$response->getBody()->write(json_encode([
@@ -295,7 +295,7 @@ class ControllerApiAuthorBlock extends Controller
$navigation->clearNavigation();
$draftNavigation = $navigation->getDraftNavigation($urlinfo, $this->settings['langattr']);
$draftNavigation = $navigation->setActiveNaviItems($draftNavigation, $item->keyPathArray);
$draftNavigation = $navigation->setActiveNaviItemsWithKeyPath($draftNavigation, $item->keyPathArray);
$item = $navigation->getItemWithKeyPath($draftNavigation, $item->keyPathArray);
$response->getBody()->write(json_encode([
@@ -392,7 +392,7 @@ class ControllerApiAuthorBlock extends Controller
$navigation->clearNavigation();
$draftNavigation = $navigation->getDraftNavigation($urlinfo, $this->settings['langattr']);
$draftNavigation = $navigation->setActiveNaviItems($draftNavigation, $item->keyPathArray);
$draftNavigation = $navigation->setActiveNaviItemsWithKeyPath($draftNavigation, $item->keyPathArray);
$item = $navigation->getItemWithKeyPath($draftNavigation, $item->keyPathArray);
$response->getBody()->write(json_encode([

View File

@@ -310,7 +310,7 @@ class ControllerApiAuthorMeta extends Controller
if($store === true)
{
$draftNavigation = $navigation->getDraftNavigation($urlinfo, $this->settings['langattr']);
$draftNavigation = $navigation->setActiveNaviItems($draftNavigation, $item->keyPathArray);
$draftNavigation = $navigation->setActiveNaviItemsWithKeyPath($draftNavigation, $item->keyPathArray);
$item = $navigation->getItemWithKeyPath($draftNavigation, $item->keyPathArray);
$response->getBody()->write(json_encode([

View File

@@ -119,7 +119,7 @@ class ControllerWebAuthor extends Controller
# extend : $request->getAttribute('c_userrole')
$draftNavigation = $navigation->getDraftNavigation($urlinfo, $langattr);
$draftNavigation = $navigation->setActiveNaviItems($draftNavigation, $keyPathArray);
$draftNavigation = $navigation->setActiveNaviItemsWithKeyPath($draftNavigation, $keyPathArray);
$draftNavigation = $this->c->get('dispatcher')->dispatch(new OnPagetreeLoaded($draftNavigation), 'onPagetreeLoaded')->getData();
$item = $navigation->getItemWithKeyPath($draftNavigation, $keyPathArray);

View File

@@ -83,14 +83,17 @@ class ControllerWebFrontend extends Controller
$breadcrumb = $this->c->get('dispatcher')->dispatch(new OnBreadcrumbLoaded($breadcrumb), 'onBreadcrumbLoaded')->getData();
# CHECK IF WHOLE TREE IS PUBLISHED
foreach($breadcrumb as $page)
if($breadcrumb)
{
if($page->status == 'unpublished')
foreach($breadcrumb as $page)
{
return $this->c->get('view')->render($response->withStatus(404), '404.twig', [
'title' => 'Page not found',
'description' => 'We did not find the page you where looking for.'
]);
if($page->status == 'unpublished')
{
return $this->c->get('view')->render($response->withStatus(404), '404.twig', [
'title' => 'Page not found',
'description' => 'We did not find the page you where looking for.'
]);
}
}
}

View File

@@ -361,7 +361,8 @@ class ParsedownExtension extends \ParsedownExtra
}
$text = trim($Line['text'], '#');
$headline = Slug::createSlug($Line['text'], $this->settings['langattr']);
$lang = $this->settings['langattr'] ?? false;
$headline = Slug::createSlug($Line['text'], $lang);
if ($this->strictMode and isset($text[0]) and $text[0] !== ' ')
{

View File

@@ -368,25 +368,28 @@ class Navigation extends Folder
# used with scan folder that generates own indexes for live version
public function setActiveNaviItems($navigation, $breadcrumb)
{
foreach($breadcrumb as $crumbkey => $page)
if($breadcrumb)
{
foreach($navigation as $itemkey => $item)
foreach($breadcrumb as $crumbkey => $page)
{
if($page->urlRelWoF == $item->urlRelWoF)
foreach($navigation as $itemkey => $item)
{
unset($breadcrumb[$crumbkey]);
if(empty($breadcrumb))
if($page->urlRelWoF == $item->urlRelWoF)
{
$navigation[$itemkey]->active = true;
}
elseif(isset($navigation[$itemkey]->folderContent))
{
$navigation[$itemkey]->activeParent = true;
$navigation[$itemkey]->folderContent = $this->setActiveNaviItems($navigation[$itemkey]->folderContent, $breadcrumb);
}
unset($breadcrumb[$crumbkey]);
break;
if(empty($breadcrumb))
{
$navigation[$itemkey]->active = true;
}
elseif(isset($navigation[$itemkey]->folderContent))
{
$navigation[$itemkey]->activeParent = true;
$navigation[$itemkey]->folderContent = $this->setActiveNaviItems($navigation[$itemkey]->folderContent, $breadcrumb);
}
break;
}
}
}
}

View File

@@ -2124,6 +2124,11 @@ video {
border-color: rgb(87 83 78 / var(--tw-border-opacity));
}
.dark .dark\:border-stone-700 {
--tw-border-opacity: 1;
border-color: rgb(68 64 60 / var(--tw-border-opacity));
}
.dark .dark\:bg-stone-600 {
--tw-bg-opacity: 1;
background-color: rgb(87 83 78 / var(--tw-bg-opacity));
@@ -2134,51 +2139,46 @@ video {
background-color: rgb(68 64 60 / var(--tw-bg-opacity));
}
.dark .dark\:bg-stone-900 {
--tw-bg-opacity: 1;
background-color: rgb(28 25 23 / var(--tw-bg-opacity));
}
.dark .dark\:bg-stone-200 {
--tw-bg-opacity: 1;
background-color: rgb(231 229 228 / var(--tw-bg-opacity));
}
.dark .dark\:bg-stone-900 {
--tw-bg-opacity: 1;
background-color: rgb(28 25 23 / var(--tw-bg-opacity));
}
.dark .dark\:text-gray-400 {
--tw-text-opacity: 1;
color: rgb(156 163 175 / var(--tw-text-opacity));
}
.dark .dark\:text-stone-50 {
--tw-text-opacity: 1;
color: rgb(250 250 249 / var(--tw-text-opacity));
}
.dark .dark\:text-stone-200 {
--tw-text-opacity: 1;
color: rgb(231 229 228 / var(--tw-text-opacity));
}
.dark .dark\:text-stone-50 {
--tw-text-opacity: 1;
color: rgb(250 250 249 / var(--tw-text-opacity));
}
.dark .dark\:text-stone-900 {
--tw-text-opacity: 1;
color: rgb(28 25 23 / var(--tw-text-opacity));
}
.dark .hover\:dark\:border-stone-600:hover {
--tw-border-opacity: 1;
border-color: rgb(87 83 78 / var(--tw-border-opacity));
}
.dark .hover\:dark\:border-teal-500:hover {
--tw-border-opacity: 1;
border-color: rgb(20 184 166 / var(--tw-border-opacity));
}
.dark .hover\:dark\:border-stone-200:hover {
--tw-border-opacity: 1;
border-color: rgb(231 229 228 / var(--tw-border-opacity));
}
.dark .hover\:dark\:border-stone-600:hover {
--tw-border-opacity: 1;
border-color: rgb(87 83 78 / var(--tw-border-opacity));
}
.dark .hover\:dark\:bg-stone-900:hover {
--tw-bg-opacity: 1;
background-color: rgb(28 25 23 / var(--tw-bg-opacity));
@@ -2189,6 +2189,16 @@ video {
background-color: rgb(231 229 228 / var(--tw-bg-opacity));
}
.dark .dark\:hover\:bg-teal-500:hover {
--tw-bg-opacity: 1;
background-color: rgb(20 184 166 / var(--tw-bg-opacity));
}
.dark .dark\:hover\:bg-stone-200:hover {
--tw-bg-opacity: 1;
background-color: rgb(231 229 228 / var(--tw-bg-opacity));
}
.dark .hover\:dark\:text-stone-900:hover {
--tw-text-opacity: 1;
color: rgb(28 25 23 / var(--tw-text-opacity));

View File

@@ -1,13 +1,13 @@
const navigation = Vue.createApp({
template: `
<div class="mr-3">
<div class="mr-3 dark:text-stone-200">
<div class="flex w-100 mb-8">
<button class="w-1/2 hover:bg-stone-700 hover:border-stone-700 hover:text-stone-50 border-b-2 border-stone-200 px-2 py-2 transition duration-100" @click.prevent="collapseNavigation()">{{ $filters.translate('collapse all') }}</button>
<button class="w-1/2 hover:bg-stone-700 hover:border-stone-700 hover:text-stone-50 border-b-2 border-stone-200 px-2 py-2 transition duration-100" @click.prevent="expandNavigation()">{{ $filters.translate('expand all') }}</button>
<button class="w-1/2 hover:bg-stone-700 hover:border-stone-700 hover:text-stone-50 border-b-2 border-stone-200 dark:border-stone-600 px-2 py-2 transition duration-100" @click.prevent="collapseNavigation()">{{ $filters.translate('collapse all') }}</button>
<button class="w-1/2 hover:bg-stone-700 hover:border-stone-700 hover:text-stone-50 border-b-2 border-stone-200 dark:border-stone-600 px-2 py-2 transition duration-100" @click.prevent="expandNavigation()">{{ $filters.translate('expand all') }}</button>
</div>
<div class="flex w-full my-px border-y border-stone-200 font-bold">
<div class="flex w-full my-px border-y border-stone-200 dark:border-stone-900 font-bold">
<div class="border-l-4" :class="getStatusClass(home.status)"></div>
<a :href="getUrl(home.urlRelWoF)" class="flex-grow p-1 pl-3 border-l-2 border-stone-50 hover:bg-teal-500 hover:text-stone-50" :class="home.active ? 'text-stone-50 bg-teal-500' : ''">
<a :href="getUrl(home.urlRelWoF)" class="flex-grow p-1 pl-3 border-stone-50 hover:bg-teal-500 hover:text-stone-50 dark:hover:bg-stone-200 hover:dark:text-stone-900" :class="home.active ? 'text-stone-50 bg-teal-500' : ''">
{{ $filters.translate(home.name) }}
</a>
</div>
@@ -153,9 +153,9 @@ navigation.component('navilevel',{
>
<template #item="{ element }">
<li :class="element.elementType" :id="element.keyPath" :data-url="element.urlRelWoF" :data-active="element.active" :data-hide="element.hide">
<div class="flex w-full my-px border-b border-stone-200 relative" :class="element.elementType == 'folder' ? 'font-bold' : ''">
<div class="border-l-4" :class="getStatusClass(element.status)"></div>
<a :href="getUrl(element.urlRelWoF)" class="flex-grow border-l-2 border-stone-50 p-1 hover:bg-teal-500 hover:text-stone-50" :class="getNaviClass(element.active, element.activeParent, element.keyPathArray)">
<div class="flex w-full my-px border-b border-stone-200 dark:border-stone-900 hover:dark:text-stone-900 hover:bg-teal-500 hover:text-stone-50 dark:bg-stone-700 hover:dark:bg-stone-200 hover:dark:text-stone-900 relative transition duration-100" :class="getNaviClass(element.active, element.activeParent, element.elementType)">
<div class="border-l-4" :class="getStatusClass(element.status, element.keyPathArray)"></div>
<a :href="getUrl(element.urlRelWoF)" class="flex-grow p-1">
{{ element.name }}
</a>
<div v-if="load == element.keyPath" class="p-1 absolute right-0">
@@ -248,22 +248,7 @@ navigation.component('navilevel',{
},
methods:
{
getStatusClass(status)
{
if(status == 'published')
{
return "border-teal-500";
}
else if(status == 'unpublished')
{
return "border-rose-500";
}
else if(status == 'modified')
{
return "border-yellow-400";
}
},
getNaviClass(active, activeParent, keyPathArray)
getStatusClass(status, keyPathArray)
{
var level = 3;
if(keyPathArray.length > 1)
@@ -272,16 +257,38 @@ navigation.component('navilevel',{
}
let naviclass = 'pl-' + level;
this.navilevel = naviclass;
if(status == 'published')
{
return naviclass += " border-teal-500";
}
else if(status == 'unpublished')
{
return naviclass += " border-rose-500";
}
else if(status == 'modified')
{
return naviclass += " border-yellow-400";
}
},
getNaviClass(active, activeParent, type)
{
let fontweight = 'font-normal';
if(type == 'folder')
{
fontweight = 'font-bold'
}
if(activeParent)
{
naviclass += " activeParent";
return fontweight += " activeParent";
}
else if(active)
{
naviclass += " text-stone-50 bg-teal-500";
return fontweight += " text-stone-50 bg-teal-500 dark:text-stone-900 dark:bg-stone-200";
}
return naviclass;
return fontweight;
},
getNaviInputLevel(keyPathArray)
{

View File

@@ -111,14 +111,9 @@ const app = Vue.createApp({
this.formData[this.currentTab][formdata.name] = formdata.value;
});
/*
update values that are objects
this.someObject = Object.assign({}, this.someObject, { a: 1, b: 2 })
eventBus.$on('forminputobject', formdata => {
this.formData[this.currentTab][formdata.name] = Object.assign({}, this.formData[this.currentTab][formdata.name], formdata.value);
eventBus.$on('meta', metadata => {
this.formData.meta = metadata.meta;
});
*/
},
methods: {
saveForm: function()

View File

@@ -2,7 +2,7 @@ const app = Vue.createApp({
template: `<Transition name="initial" appear>
<div class="w-full">
<ul>
<li v-for="(plugin,pluginname) in formDefinitions" class="w-full my-8 bg-stone-100 border border-stone-200">
<li v-for="(plugin,pluginname) in formDefinitions" class="w-full my-8 bg-stone-100 dark:bg-stone-600 border border-stone-200">
<p v-if="versions[pluginname] !== undefined"><a href="https://plugins.typemill.net" class="block p-2 text-center bg-rose-500 text-white">Please update to version {{ versions[pluginname].version }}</a></p>
<div class="flex justify-between w-full px-8 py-3 border-b border-white" :class="getActiveClass(pluginname)">
<p class="py-2">License: {{ plugin.license }}</p>
@@ -137,7 +137,7 @@ const app = Vue.createApp({
{
if(this.formData[pluginname]['active'])
{
return 'bg-stone-200';
return 'bg-stone-200 dark:bg-stone-900';
}
},
getLinkToLicense()

View File

@@ -260,6 +260,7 @@ const publisher = Vue.createApp({
self.clearPublisher();
eventBus.$emit('item', response.data.item);
eventBus.$emit('navigation', response.data.navigation);
eventBus.$emit('meta', response.data.metadata);
})
.catch(function (error)
{

View File

@@ -2,7 +2,7 @@ const modal = {
props: ['labelconfirm', 'labelcancel'],
template: `<transition name="initial" appear>
<div class="fixed w-full h-100 inset-0 z-50 overflow-hidden flex justify-center items-center bg-stone-700 bg-opacity-90">
<div class="border border-teal-500 shadow-lg bg-white w-11/12 md:max-w-md mx-auto shadow-lg z-50 overflow-y-auto">
<div class="border border-teal-500 dark:border-stone-200 shadow-lg bg-white dark:bg-stone-600 w-11/12 md:max-w-md mx-auto shadow-lg z-50 overflow-y-auto">
<div class="text-left p-6">
<div class="text-2xl font-bold">
<slot name="header">
@@ -71,7 +71,7 @@ function handleErrorMessage(error)
const loginform = Vue.createApp({
template: `<transition name="initial" appear>
<div v-if="show" class="fixed w-full h-100 inset-0 z-50 overflow-hidden flex justify-center items-center bg-stone-700 bg-opacity-90">
<div class="border border-teal-500 shadow-lg bg-white w-11/12 md:max-w-md mx-auto shadow-lg z-50 overflow-y-auto">
<div class="border border-teal-500 dark:border-stone-200 shadow-lg bg-white dark:bg-stone-600 w-11/12 md:max-w-md mx-auto shadow-lg z-50 overflow-y-auto">
<div class="text-left p-6">
<div class="text-2xl font-bold"><h2>You are logged out</h2></div>
<div class="my-5">

View File

@@ -27,7 +27,7 @@ const app = Vue.createApp({
</div>
<div class="my-5">
<div :class="messageClass" class="block w-full h-8 px-3 py-1 my-1 text-white transition duration-100">{{ $filters.translate(message) }}</div>
<button type="submit" @click.prevent="save()" class="w-full p-3 my-1 bg-stone-700 hover:bg-stone-900 text-white cursor-pointer transition duration-100">{{ $filters.translate('Save') }}</button>
<button type="submit" @click.prevent="save()" class="w-full p-3 my-1 bg-stone-700 hover:bg-stone-900 text-white dark:bg-stone-600 hover:dark:bg-stone-900 cursor-pointer transition duration-100">{{ $filters.translate('Save') }}</button>
</div>
</form>
<div class="my-5 text-center">

View File

@@ -3,7 +3,7 @@ const app = Vue.createApp({
<div class="w-full">
<div class="mt-5 mb-5">
<label for="roleselector" class="block mb-1 font-medium">{{ $filters.translate("Select a role") }}</label>
<select class="form-select block w-full border border-stone-300 bg-stone-200 px-2 py-3 h-12 transition ease-in-out"
<select class="form-select block w-full border border-stone-300 bg-stone-200 text-stone-900 px-2 py-3 h-12 transition ease-in-out"
v-model="selectedrole"
@change="generateForm()">
<option disabled value="">Please select</option>
@@ -36,7 +36,7 @@ const app = Vue.createApp({
</div>
<div class="my-5">
<div :class="messageClass" class="block w-full h-8 px-3 py-1 my-1 text-white transition duration-100">{{ $filters.translate(message) }}</div>
<button type="submit" @click.prevent="save()" class="w-full p-3 my-1 bg-stone-700 hover:bg-stone-900 text-white cursor-pointer transition duration-100">{{ $filters.translate('Save') }}</button>
<button type="submit" @click.prevent="save()" class="w-full p-3 my-1 dark:bg-stone-600 hover:dark:bg-stone-900 bg-stone-700 hover:bg-stone-900 text-white cursor-pointer transition duration-100">{{ $filters.translate('Save') }}</button>
</div>
</form>
</div>

View File

@@ -187,10 +187,10 @@ app.component('searchbox', {
<select v-if="this.filter == 'userrole'" v-model="searchterm" class="lg:w-3/4 w-full h-12 px-2 py-3 border border-stone-300 bg-stone-200">
<option v-for="role in userroles">{{role}}</option>
</select>
<input v-else type="text" v-model="searchterm" class="lg:w-3/4 w-full h-12 px-2 py-3 border border-stone-300 bg-stone-200">
<input v-else type="text" v-model="searchterm" class="lg:w-3/4 w-full h-12 px-2 py-3 border border-stone-300 bg-stone-200 text-stone-900">
<div class="lg:w-1/4 lg:mt-0 mt-2 w-full flex justify-around">
<button class="p-2 w-1/2 bg-stone-200 hover:bg-stone-100" @click.prevent="clearSearch()">{{ $filters.translate('Clear') }}</button>
<button class="p-2 w-1/2 bg-stone-700 hover:bg-stone-900 text-white" @click.prevent="startSearch()">{{ $filters.translate('Search') }}</button>
<button class="p-2 w-1/2 bg-stone-200 hover:bg-stone-100 text-stone-900" @click.prevent="clearSearch()">{{ $filters.translate('Clear') }}</button>
<button class="p-2 w-1/2 bg-stone-700 hover:bg-stone-900 dark:bg-stone-600 hover:dark:bg-stone-900 text-white" @click.prevent="startSearch()">{{ $filters.translate('Search') }}</button>
</div>
</div>
<div v-if="error" class="error pt1 f6">{{error}}</div>
@@ -230,9 +230,9 @@ app.component('searchbox', {
{
if(this.filter == filter)
{
return 'border-stone-700 bg-stone-200';
return 'border-stone-700 bg-stone-200 dark:text-stone-900';
}
return 'border-stone-100 bg-stone-100';
return 'border-stone-100 bg-stone-100 dark:bg-stone-600 hover:dark:bg-stone-200 hover:dark:text-stone-900 dark:border-stone-700';
}
}
})
@@ -242,24 +242,24 @@ app.component('usertable', {
template: `<table class="w-full mt-8" cellspacing="0">
<thead>
<tr>
<th class="p-3 bg-stone-200 border-2 border-stone-50">{{ $filters.translate('Username') }}</th>
<th class="p-3 bg-stone-200 border-2 border-stone-50">{{ $filters.translate('Userrole') }}</th>
<th class="p-3 bg-stone-200 border-2 border-stone-50">{{ $filters.translate('E-Mail') }}</th>
<th class="p-3 bg-stone-200 border-2 border-stone-50">{{ $filters.translate('Edit') }}</th>
<th class="p-3 bg-stone-200 dark:bg-stone-900 border-2 border-stone-50 dark:border-stone-600">{{ $filters.translate('Username') }}</th>
<th class="p-3 bg-stone-200 dark:bg-stone-900 border-2 border-stone-50 dark:border-stone-600">{{ $filters.translate('Userrole') }}</th>
<th class="p-3 bg-stone-200 dark:bg-stone-900 border-2 border-stone-50 dark:border-stone-600">{{ $filters.translate('E-Mail') }}</th>
<th class="p-3 bg-stone-200 dark:bg-stone-900 border-2 border-stone-50 dark:border-stone-600">{{ $filters.translate('Edit') }}</th>
</tr>
</thead>
<tbody>
<tr v-for="user,index in userdata" key="username">
<td class="p-3 bg-stone-100 border-2 border-white">{{ user.username }}</td>
<td class="p-3 bg-stone-100 border-2 border-white">{{ user.userrole }}</td>
<td class="p-3 bg-stone-100 border-2 border-white">{{ user.email }}</td>
<td class="bg-stone-100 border-2 border-white text-center hover:bg-teal-500 hover:text-white pointer transition duration-100"><a :href="getEditLink(user.username)" class="block w-full p-3">{{ $filters.translate('edit') }}</a></td>
<td class="p-3 bg-stone-100 dark:bg-stone-700 border-2 border-white dark:border-stone-600">{{ user.username }}</td>
<td class="p-3 bg-stone-100 dark:bg-stone-700 border-2 border-white dark:border-stone-600">{{ user.userrole }}</td>
<td class="p-3 bg-stone-100 dark:bg-stone-700 border-2 border-white dark:border-stone-600">{{ user.email }}</td>
<td class="bg-stone-100 dark:bg-stone-700 border-2 border-white dark:border-stone-600 text-center hover:bg-teal-500 dark:hover:bg-teal-500 hover:text-white pointer transition duration-100"><a :href="getEditLink(user.username)" class="block w-full p-3">{{ $filters.translate('edit') }}</a></td>
</tr>
<tr>
<td class="p-3 bg-stone-100 border-2 border-white"><a class="text-teal-500 hover:underline" :href="getNewUserLink()">{{ $filters.translate('New user') }}</a></td>
<td class="p-3 bg-stone-100 border-2 border-white"></td>
<td class="p-3 bg-stone-100 border-2 border-white"></td>
<td class="bg-stone-100 border-2 border-white text-center text-teal-500 hover:bg-teal-500 hover:text-white transition duration-100"><a class="block w-full p-3" :href="getNewUserLink()">{{ $filters.translate('add') }}</a></td>
<td class="p-3 bg-stone-100 dark:bg-stone-700 border-2 border-white dark:border-stone-600"><a class="text-teal-500 hover:underline" :href="getNewUserLink()">{{ $filters.translate('New user') }}</a></td>
<td class="p-3 bg-stone-100 dark:bg-stone-700 border-2 border-white dark:border-stone-600"></td>
<td class="p-3 bg-stone-100 dark:bg-stone-700 border-2 border-white dark:border-stone-600"></td>
<td class="bg-stone-100 dark:bg-stone-700 border-2 border-white dark:border-stone-600 text-center text-teal-500 hover:bg-teal-500 dark:hover:bg-teal-500 hover:text-white transition duration-100"><a class="block w-full p-3" :href="getNewUserLink()">{{ $filters.translate('add') }}</a></td>
</tr>
</tbody>
</table>`,
@@ -275,7 +275,7 @@ app.component('usertable', {
app.component('pagination', {
props: ['page'],
template: '<li><button class="p-1 border-2 border-stone-50 hover:bg-stone-200" :class="checkActive()" @click="goto(page)">{{ page }}</button></li>',
template: '<li><button class="p-1 dark:bg-stone-700 border-2 border-stone-50 dark:border-stone-600 hover:bg-stone-200" :class="checkActive()" @click="goto(page)">{{ page }}</button></li>',
methods: {
goto: function(page){

View File

@@ -1,5 +1,5 @@
<!DOCTYPE html>
<html lang="en" class="{{ settings.darkmode ? 'dark' :'darkmodeoff' }}" >
<html lang="en" class="{{ settings.darkmode ? 'dark' : 'darkmodeoff' }}" >
<head>
<meta charset="UTF-8">
<title>{% block title %}{% endblock %}</title>
@@ -24,11 +24,11 @@
{{ assets.renderCSS() }}
</head>
<body class="bg-stone-100">
<body class="bg-stone-100 dark:bg-stone-900">
{% include 'partials/symbols.twig' %}
<header class="border-b-2 border-stone-200">
<header class="border-b-2 border-stone-200 dark:border-stone-600">
{% include 'partials/mainNavi.twig' %}
</header>

View File

@@ -1,5 +1,5 @@
<!DOCTYPE html>
<html lang="en" class="{{ settings.darkmode ? 'dark' :'darkmodeoff' }}" >
<html lang="en" class="{{ settings.darkmode ? 'dark' : 'darkmodeoff' }}" >
<head>
<meta charset="UTF-8">
<title>{% block title %}{% endblock %}</title>
@@ -32,8 +32,6 @@
{% include 'partials/mainNavi.twig' %}
</header>
{% include 'partials/flash.twig' %}
<div class="max-w-6xl m-auto mt-7 flex flex-col lg:flex-row justify-between" id="main" data-url="{{ base_url() }}">
<aside class="lg:w-1/4">
{% include 'partials/systemNavi.twig' %}
@@ -54,7 +52,6 @@
<script>
const tmaxios = axios.create();
tmaxios.defaults.baseURL = "{{ base_url() }}";
/* header for session authentication in middleware */
tmaxios.defaults.headers.common['X-Session-Auth'] = "true";
</script>
<script src="{{ base_url() }}/system/typemill/author/js/vue.js?v={{ settings.version }}"></script>
@@ -63,7 +60,6 @@
<script src="{{ base_url() }}/system/typemill/author/js/vue-systemnavi.js?v={{ settings.version }}"></script>
<script src="{{ base_url() }}/system/typemill/author/js/vue-medialib.js?v={{ settings.version }}"></script>
<script>
/* kixote.mount('#kixote'); */
systemnavi.config.globalProperties.$filters = translatefilter;
systemnavi.mount('#systemNavigation');
@@ -71,6 +67,8 @@
loginform.config.globalProperties.$filters = translatefilter;
loginform.mount("#loginform");
/* kixote.mount('#kixote'); */
</script>
{% block javascript %}{% endblock %}

View File

@@ -24,11 +24,11 @@
{{ assets.renderCSS() }}
</head>
<body class="bg-stone-100">
<body class="bg-stone-100 dark:bg-stone-900">
{% include 'partials/symbols.twig' %}
<header class="border-b-2 border-stone-200">
<header class="border-b-2 border-stone-200 dark:border-stone-600">
{% include 'partials/mainNavi.twig' %}
</header>
@@ -36,7 +36,7 @@
<aside class="lg:w-1/4">
{% include 'partials/systemNavi.twig' %}
</aside>
<article class="lg:w-3/4 bg-stone-50 shadow-md p-8">
<article class="lg:w-3/4 bg-stone-50 dark:bg-stone-700 dark:text-stone-200 shadow-md p-8">
<div id="system" v-cloak></div>
</article>
</div>

View File

@@ -53,11 +53,11 @@ fieldsetsystem:
label: Google sitemap (readonly)
css: lg:w-half
disabled: true
# darkmode:
# type: checkbox
# label: Darkmode
# checkboxlabel: Switch to darkmode for the authoring area
# css: lg:w-half
darkmode:
type: checkbox
label: Darkmode
checkboxlabel: Switch to darkmode for the authoring area
css: lg:w-half
fieldsetmedia:
type: fieldset
legend: Media