mirror of
https://github.com/typemill/typemill.git
synced 2025-07-30 19:00:32 +02:00
open modal if logged out
This commit is contained in:
@@ -33,7 +33,7 @@ class ControllerApiSystemSettings extends Controller
|
||||
$validator = new Validation();
|
||||
$validatedOutput = $validator->recursiveValidation($formdefinitions, $settingsinput);
|
||||
|
||||
if(!empty($valiator->errors))
|
||||
if(!empty($validator->errors))
|
||||
{
|
||||
$response->getBody()->write(json_encode([
|
||||
'message' => Translations::translate('Please correct errors in form.'),
|
||||
|
@@ -193,7 +193,7 @@ bloxeditor.component('new-block',{
|
||||
|
||||
eventBus.$emit('publisherclear');
|
||||
|
||||
tmaxios.post('/api/v1/block',{
|
||||
tmaxios.post('/api/v1/block',{
|
||||
'url': data.urlinfo.route,
|
||||
'block_id': this.index,
|
||||
'markdown': this.newblockmarkdown.trim(),
|
||||
@@ -216,7 +216,11 @@ bloxeditor.component('new-block',{
|
||||
{
|
||||
if(error.response)
|
||||
{
|
||||
eventBus.$emit('publishermessage', error.response.data.message);
|
||||
let message = handleErrorMessage(error);
|
||||
if(message)
|
||||
{
|
||||
eventBus.$emit('publishermessage', message);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
@@ -236,9 +240,9 @@ bloxeditor.component('content-block', {
|
||||
<new-block :index="index"></new-block>
|
||||
</div>
|
||||
<div class="relative blox-wrapper mb-1">
|
||||
<div v-if="index != 0" class="sideaction hidden absolute -top-3 left-1/2 -translate-x-1/2 z-10 text-xs">
|
||||
<div v-if="index != 0" class="sideaction hidden absolute -top-3 left-1/2 -translate-x-1/2 z-10 text-xs">
|
||||
<button class="delete w-16 p-1 border-r border-stone-700 bg-stone-200 hover:bg-rose-500 hover:text-white transition-1" @mousedown.prevent="disableSort()" @click.prevent="deleteBlock">{{ $filters.translate('delete') }}</button>
|
||||
<button class="add w-16 p-1 border-l border-stone-700 bg-stone-200 hover:bg-teal-500 hover:text-white transition-1" :disabled="disabled" @mousedown.prevent="disableSort()" @click.prevent="openNewBlock">{{ $filters.translate('add') }}</button>
|
||||
<button class="add w-16 p-1 border-l border-stone-700 bg-stone-200 hover:bg-teal-500 hover:text-white transition-1" :disabled="disabled" @mousedown.prevent="disableSort()" @click.prevent="openNewBlock">{{ $filters.translate('add') }}</button>
|
||||
</div>
|
||||
<div v-if="!edit" class="blox-preview px-6 py-3 hover:bg-stone-100 overflow-hidden transition-1" @click="showEditor" v-html="getHtml(element.html)"></div>
|
||||
<div v-else class="blox-editor bg-stone-100">
|
||||
@@ -247,7 +251,7 @@ bloxeditor.component('content-block', {
|
||||
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
|
||||
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
<component ref="activeComponent" :disabled="disabled" :markdown="updatedmarkdown" :index="index" @saveBlockEvent="saveBlock" @updateMarkdownEvent="updateMarkdownFunction" :is="componentType"></component>
|
||||
<div class="edit-buttons absolute -bottom-3 right-4 z-10 text-xs">
|
||||
<button class="cancel w-20 p-1 border-r border-stone-700 bg-stone-200 hover:bg-rose-500 hover:text-white transition-1" :disabled="disabled" @click.prevent="closeEditor">{{ $filters.translate('cancel') }}</button>
|
||||
@@ -382,7 +386,7 @@ bloxeditor.component('content-block', {
|
||||
|
||||
eventBus.$emit('publisherclear');
|
||||
|
||||
tmaxios.delete('/api/v1/block',{
|
||||
tmaxios.delete('/api/v1/block',{
|
||||
data: {
|
||||
'url': data.urlinfo.route,
|
||||
'block_id': this.index,
|
||||
@@ -407,7 +411,11 @@ bloxeditor.component('content-block', {
|
||||
self.load = false;
|
||||
if(error.response)
|
||||
{
|
||||
eventBus.$emit('publishermessage', error.response.data.message);
|
||||
let message = handleErrorMessage(error);
|
||||
if(message)
|
||||
{
|
||||
eventBus.$emit('publishermessage', message);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
@@ -441,7 +449,7 @@ bloxeditor.component('content-block', {
|
||||
this.load = true;
|
||||
eventBus.$emit('publisherclear');
|
||||
|
||||
tmaxios.put('/api/v1/block',{
|
||||
tmaxios.put('/api/v1/block',{
|
||||
'url': data.urlinfo.route,
|
||||
'block_id': this.index,
|
||||
'markdown': this.updatedmarkdown.trim(),
|
||||
@@ -466,7 +474,11 @@ bloxeditor.component('content-block', {
|
||||
self.load = false;
|
||||
if(error.response)
|
||||
{
|
||||
eventBus.$emit('publishermessage', error.response.data.message);
|
||||
let message = handleErrorMessage(error);
|
||||
if(message)
|
||||
{
|
||||
eventBus.$emit('publishermessage', message);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
@@ -10,7 +10,7 @@ const navigation = Vue.createApp({
|
||||
<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' : ''">
|
||||
{{ $filters.translate(home.name) }}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pl-2 pl-3 pl-4 pl-6 pl-8 pl-9 pl-10 pl-12 pl-15 text-stone-50"></div>
|
||||
<navilevel :navigation="navigation" :expanded="expanded" />
|
||||
</div>`,
|
||||
@@ -151,7 +151,7 @@ navigation.component('navilevel',{
|
||||
}"
|
||||
:expanded="expanded"
|
||||
>
|
||||
<template #item="{ element }">
|
||||
<template #item="{ element }">
|
||||
<li :class="element.elementType" :id="element.keyPath" :data-url="element.urlRelWoF" :data-active="element.active">
|
||||
<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>
|
||||
@@ -163,7 +163,7 @@ navigation.component('navilevel',{
|
||||
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
|
||||
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="element.elementType == 'folder' && element.contains == 'pages'" class=" p-1 bg-transparent absolute right-0" @click="callToggle(element.name)">
|
||||
<svg v-if="isExpanded(element.name)" class="icon icon-cheveron-up">
|
||||
<use xlink:href="#icon-cheveron-up"></use>
|
||||
@@ -365,10 +365,15 @@ navigation.component('navilevel',{
|
||||
})
|
||||
.catch(function (error)
|
||||
{
|
||||
if(error.response.data.errors.message)
|
||||
if(error.response)
|
||||
{
|
||||
eventBus.$emit('revertNavigation');
|
||||
// publishController.errors.message = error.response.data.errors;
|
||||
|
||||
let message = handleErrorMessage(error);
|
||||
if(message)
|
||||
{
|
||||
eventBus.$emit('publishermessage', message);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
@@ -408,7 +413,14 @@ navigation.component('navilevel',{
|
||||
})
|
||||
.catch(function (error)
|
||||
{
|
||||
eventBus.$emit('publishermessage', error.response.data.message);
|
||||
if(error.response)
|
||||
{
|
||||
let message = handleErrorMessage(error);
|
||||
if(message)
|
||||
{
|
||||
eventBus.$emit('publishermessage', message);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
emitter(value) {
|
||||
|
@@ -1,31 +1,31 @@
|
||||
class Event{
|
||||
constructor(){
|
||||
this.events = {};
|
||||
}
|
||||
constructor(){
|
||||
this.events = {};
|
||||
}
|
||||
|
||||
$on(eventName, fn) {
|
||||
this.events[eventName] = this.events[eventName] || [];
|
||||
this.events[eventName].push(fn);
|
||||
}
|
||||
$on(eventName, fn) {
|
||||
this.events[eventName] = this.events[eventName] || [];
|
||||
this.events[eventName].push(fn);
|
||||
}
|
||||
|
||||
$off(eventName, fn) {
|
||||
if (this.events[eventName]) {
|
||||
for (var i = 0; i < this.events[eventName].length; i++) {
|
||||
if (this.events[eventName][i] === fn) {
|
||||
this.events[eventName].splice(i, 1);
|
||||
break;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
$off(eventName, fn) {
|
||||
if (this.events[eventName]) {
|
||||
for (var i = 0; i < this.events[eventName].length; i++) {
|
||||
if (this.events[eventName][i] === fn) {
|
||||
this.events[eventName].splice(i, 1);
|
||||
break;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
$emit(eventName, data) {
|
||||
if (this.events[eventName]) {
|
||||
this.events[eventName].forEach(function(fn) {
|
||||
fn(data);
|
||||
});
|
||||
}
|
||||
}
|
||||
$emit(eventName, data) {
|
||||
if (this.events[eventName]) {
|
||||
this.events[eventName].forEach(function(fn) {
|
||||
fn(data);
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const eventBus = new Event();
|
||||
const eventBus = new Event();
|
@@ -27,7 +27,7 @@ const app = Vue.createApp({
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<form v-else class="inline-block w-full">
|
||||
<form v-else class="inline-block w-full">
|
||||
<div>
|
||||
<p>Buy a typemill-license and enjoy our flatrate-model for plugins and -themes.</p><p>We offer two types of subscription-based licenses:</p>
|
||||
<div class="flex flex-wrap justify-between">
|
||||
@@ -48,23 +48,23 @@ const app = Vue.createApp({
|
||||
<fieldset class="flex flex-wrap justify-between border-2 border-stone-200 p-4 my-8" v-if="fieldDefinition.type == 'fieldset'">
|
||||
<legend class="text-lg font-medium">{{ fieldDefinition.legend }}</legend>
|
||||
<component v-for="(subfieldDefinition, subfieldname) in fieldDefinition.fields"
|
||||
:key="subfieldname"
|
||||
:is="selectComponent(subfieldDefinition.type)"
|
||||
:errors="errors"
|
||||
:name="subfieldname"
|
||||
:userroles="userroles"
|
||||
:value="formData[subfieldname]"
|
||||
v-bind="subfieldDefinition">
|
||||
:key="subfieldname"
|
||||
:is="selectComponent(subfieldDefinition.type)"
|
||||
:errors="errors"
|
||||
:name="subfieldname"
|
||||
:userroles="userroles"
|
||||
:value="formData[subfieldname]"
|
||||
v-bind="subfieldDefinition">
|
||||
</component>
|
||||
</fieldset>
|
||||
<component v-else
|
||||
:key="fieldname"
|
||||
:is="selectComponent(fieldDefinition.type)"
|
||||
:errors="errors"
|
||||
:name="fieldname"
|
||||
:userroles="userroles"
|
||||
:value="formData[fieldname]"
|
||||
v-bind="fieldDefinition">
|
||||
:key="fieldname"
|
||||
:is="selectComponent(fieldDefinition.type)"
|
||||
:errors="errors"
|
||||
:name="fieldname"
|
||||
:userroles="userroles"
|
||||
:value="formData[fieldname]"
|
||||
v-bind="fieldDefinition">
|
||||
</component>
|
||||
</div>
|
||||
<div class="my-5">
|
||||
@@ -72,8 +72,8 @@ const app = Vue.createApp({
|
||||
<input type="submit" @click.prevent="save()" value="save" class="w-full p-3 my-1 bg-stone-700 hover:bg-stone-900 text-white cursor-pointer transition duration-100">
|
||||
</div>
|
||||
-->
|
||||
</form>
|
||||
</Transition>`,
|
||||
</form>
|
||||
</Transition>`,
|
||||
data() {
|
||||
return {
|
||||
licenseData: data.licensedata,
|
||||
@@ -111,13 +111,14 @@ const app = Vue.createApp({
|
||||
})
|
||||
.catch(function (error)
|
||||
{
|
||||
self.messageClass = 'bg-rose-500';
|
||||
self.message = error.response.data.message;
|
||||
|
||||
/* form validation errors */
|
||||
if(error.response.data.errors !== undefined)
|
||||
if(error.response)
|
||||
{
|
||||
self.errors = error.response.data.errors;
|
||||
self.message = handleErrorMessage(error);
|
||||
self.messageClass = 'bg-rose-500';
|
||||
if(error.response.data.errors !== undefined)
|
||||
{
|
||||
self.errors = error.response.data.errors;
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -97,9 +97,14 @@ const app = Vue.createApp({
|
||||
})
|
||||
.catch(function (error)
|
||||
{
|
||||
if(error.response)
|
||||
{
|
||||
}
|
||||
if(error.response)
|
||||
{
|
||||
let message = handleErrorMessage(error);
|
||||
if(message)
|
||||
{
|
||||
eventBus.$emit('publishermessage', message);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
eventBus.$on('forminput', formdata => {
|
||||
@@ -146,9 +151,18 @@ const app = Vue.createApp({
|
||||
{
|
||||
if(error.response)
|
||||
{
|
||||
self.formErrors = error.response.data.errors;
|
||||
self.message = 'please correct the errors above';
|
||||
self.messageClass = 'bg-rose-500';
|
||||
self.formErrors = error.response.data.errors;
|
||||
|
||||
let message = handleErrorMessage(error);
|
||||
|
||||
/* does it make sense to change logic and show errors in publisher?
|
||||
if(message)
|
||||
{
|
||||
eventBus.$emit('publishermessage', message);
|
||||
}
|
||||
*/
|
||||
}
|
||||
});
|
||||
},
|
||||
@@ -175,7 +189,7 @@ app.component('tab-meta', {
|
||||
class="h-12 w-3/4 border px-2 py-3 border-stone-300 bg-stone-200"
|
||||
type="text"
|
||||
v-model="slug"
|
||||
pattern="[a-z0-9\- ]"
|
||||
pattern="[a-z0-9]"
|
||||
@input="changeSlug()"
|
||||
/>
|
||||
<button
|
||||
@@ -281,9 +295,17 @@ app.component('tab-meta', {
|
||||
})
|
||||
.catch(function (error)
|
||||
{
|
||||
eventBus.$emit('publishermessage', error.response.data.message);
|
||||
if(error.response)
|
||||
{
|
||||
let message = handleErrorMessage(error);
|
||||
|
||||
if(message)
|
||||
{
|
||||
eventBus.$emit('publishermessage', message);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
@@ -8,12 +8,12 @@ const app = Vue.createApp({
|
||||
<p class="py-2">License: {{ plugin.license }}</p>
|
||||
<div class="flex">
|
||||
<label :for="pluginname" class="p-2">{{ $filters.translate('active') }}</label>
|
||||
<input type="checkbox" class="w-6 h-6 my-2 accent-white"
|
||||
:name="pluginname"
|
||||
v-model="formData[pluginname]['active']"
|
||||
@change="activate(pluginname)">
|
||||
<input type="checkbox" class="w-6 h-6 my-2 accent-white"
|
||||
:name="pluginname"
|
||||
v-model="formData[pluginname]['active']"
|
||||
@change="activate(pluginname)">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-full p-8">
|
||||
<div class="w-full">
|
||||
<h2 class="text-xl font-bold mb-3">{{plugin.name}}</h2>
|
||||
@@ -34,23 +34,23 @@ const app = Vue.createApp({
|
||||
<fieldset class="flex flex-wrap justify-between border-2 border-stone-200 p-4 my-8" v-if="fieldDefinition.type == 'fieldset'">
|
||||
<legend class="text-lg font-medium">{{ fieldDefinition.legend }}</legend>
|
||||
<component v-for="(subfieldDefinition, subfieldname) in fieldDefinition.fields"
|
||||
:key="subfieldname"
|
||||
:is="selectComponent(subfieldDefinition.type)"
|
||||
:errors="errors"
|
||||
:name="subfieldname"
|
||||
:userroles="userroles"
|
||||
:value="formData[pluginname][subfieldname]"
|
||||
v-bind="subfieldDefinition">
|
||||
:key="subfieldname"
|
||||
:is="selectComponent(subfieldDefinition.type)"
|
||||
:errors="errors"
|
||||
:name="subfieldname"
|
||||
:userroles="userroles"
|
||||
:value="formData[pluginname][subfieldname]"
|
||||
v-bind="subfieldDefinition">
|
||||
</component>
|
||||
</fieldset>
|
||||
<component v-else
|
||||
:key="fieldname"
|
||||
:is="selectComponent(fieldDefinition.type)"
|
||||
:errors="errors"
|
||||
:name="fieldname"
|
||||
:userroles="userroles"
|
||||
:value="formData[pluginname][fieldname]"
|
||||
v-bind="fieldDefinition">
|
||||
:key="fieldname"
|
||||
:is="selectComponent(fieldDefinition.type)"
|
||||
:errors="errors"
|
||||
:name="fieldname"
|
||||
:userroles="userroles"
|
||||
:value="formData[pluginname][fieldname]"
|
||||
v-bind="fieldDefinition">
|
||||
</component>
|
||||
</div>
|
||||
<div class="my-5">
|
||||
@@ -66,15 +66,15 @@ const app = Vue.createApp({
|
||||
</ul>
|
||||
<div class="my-5 text-center">
|
||||
<modal v-if="showModal" @close="showModal = false">
|
||||
<template #header>
|
||||
<h3>{{ $filters.translate('License required') }}</h3>
|
||||
</template>
|
||||
<template #body>
|
||||
<p>{{ $filters.translate(modalMessage) }}</p>
|
||||
</template>
|
||||
<template #button>
|
||||
<a :href="getLinkToLicense()" class="focus:outline-none px-4 p-3 mr-3 text-white bg-teal-500 hover:bg-teal-700 transition duration-100">{{ $filters.translate('Check your license') }}</a>
|
||||
</template>
|
||||
<template #header>
|
||||
<h3>{{ $filters.translate('License required') }}</h3>
|
||||
</template>
|
||||
<template #body>
|
||||
<p>{{ $filters.translate(modalMessage) }}</p>
|
||||
</template>
|
||||
<template #button>
|
||||
<a :href="getLinkToLicense()" class="focus:outline-none px-4 p-3 mr-3 text-white bg-teal-500 hover:bg-teal-700 transition duration-100">{{ $filters.translate('Check your license') }}</a>
|
||||
</template>
|
||||
</modal>
|
||||
</div>
|
||||
</div>
|
||||
@@ -124,8 +124,11 @@ const app = Vue.createApp({
|
||||
})
|
||||
.catch(function (error)
|
||||
{
|
||||
self.messageClass = 'bg-rose-500';
|
||||
self.message = error.response.data.message;
|
||||
if(error.response)
|
||||
{
|
||||
self.message = handleErrorMessage(error);
|
||||
self.messageClass = 'bg-rose-500';
|
||||
}
|
||||
});
|
||||
|
||||
},
|
||||
@@ -167,9 +170,12 @@ const app = Vue.createApp({
|
||||
})
|
||||
.catch(function (error)
|
||||
{
|
||||
self.formData[pluginname]['active'] = false;
|
||||
self.modalMessage = error.response.data.message;
|
||||
self.showModal = true;
|
||||
if(error.response)
|
||||
{
|
||||
self.formData[pluginname]['active'] = false;
|
||||
self.modalMessage = handleErrorMessage(error);
|
||||
self.showModal = true;
|
||||
}
|
||||
});
|
||||
},
|
||||
setCurrent: function(name)
|
||||
@@ -203,11 +209,14 @@ const app = Vue.createApp({
|
||||
})
|
||||
.catch(function (error)
|
||||
{
|
||||
self.messageClass = 'bg-rose-500';
|
||||
self.message = error.response.data.message;
|
||||
if(error.response.data.errors !== undefined)
|
||||
if(error.response)
|
||||
{
|
||||
self.errors = error.response.data.errors;
|
||||
self.message = handleErrorMessage(error);
|
||||
self.messageClass = 'bg-rose-500';
|
||||
if(error.response.data.errors !== undefined)
|
||||
{
|
||||
self.errors = error.response.data.errors;
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
@@ -1,5 +1,5 @@
|
||||
const posts = Vue.createApp({
|
||||
template: `<section id="posts" v-if="showPosts" class="px-12 py-8 bg-stone-50 shadow-md mb-16">
|
||||
template: `<section id="posts" v-if="showPosts" class="px-12 py-8 bg-stone-50 shadow-md mb-16">
|
||||
<div class="w-full relative">
|
||||
<label class="block mb-1 font-medium">{{ $filters.translate('Short title for post') }}</label>
|
||||
<div class="flex">
|
||||
@@ -86,61 +86,66 @@ const posts = Vue.createApp({
|
||||
|
||||
var self = this;
|
||||
|
||||
tmaxios.post('/api/v1/post',{
|
||||
tmaxios.post('/api/v1/post',{
|
||||
'folder_id': this.item.keyPath,
|
||||
'item_name': this.posttitle,
|
||||
'type': 'file',
|
||||
})
|
||||
.then(function (response)
|
||||
{
|
||||
if(response.data.item)
|
||||
{
|
||||
self.posts = response.data.item.folderContent;
|
||||
self.posttitle = '';
|
||||
}
|
||||
})
|
||||
.catch(function (error)
|
||||
{
|
||||
if(error.response)
|
||||
{
|
||||
eventBus.$emit('publishermessage', error.response.data.errors);
|
||||
}
|
||||
});
|
||||
.then(function (response)
|
||||
{
|
||||
if(response.data.item)
|
||||
{
|
||||
self.posts = response.data.item.folderContent;
|
||||
self.posttitle = '';
|
||||
}
|
||||
})
|
||||
.catch(function (error)
|
||||
{
|
||||
if(error.response)
|
||||
{
|
||||
let message = handleErrorMessage(error);
|
||||
|
||||
if(message)
|
||||
{
|
||||
eventBus.$emit('publishermessage', message);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
posts.component('single-post',{
|
||||
props: ['post', 'baseurl', 'editormode'],
|
||||
template: `<div class="my-4">
|
||||
<a :href="getUrl(post.urlRelWoF)" :class="getBorderStyle(post.status)" class="border-l border-l-4 w-full inline-block p-4 bg-stone-100 hover:bg-stone-200 transition duration-100">
|
||||
<h4 class="text-l font-bold">{{ post.name }} <span class="float-right text-xs font-normal">{{ getDate(post.order) }}</span></h4>
|
||||
</a>
|
||||
</div>`,
|
||||
methods: {
|
||||
getBorderStyle(status)
|
||||
{
|
||||
if(status == 'published')
|
||||
{
|
||||
return "border-teal-500";
|
||||
}
|
||||
if(status == 'modified')
|
||||
{
|
||||
return "border-yellow-400";
|
||||
}
|
||||
if(status == 'unpublished')
|
||||
{
|
||||
return "border-rose-500";
|
||||
}
|
||||
},
|
||||
getUrl(posturl)
|
||||
{
|
||||
props: ['post', 'baseurl', 'editormode'],
|
||||
template: `<div class="my-4">
|
||||
<a :href="getUrl(post.urlRelWoF)" :class="getBorderStyle(post.status)" class="border-l border-l-4 w-full inline-block p-4 bg-stone-100 hover:bg-stone-200 transition duration-100">
|
||||
<h4 class="text-l font-bold">{{ post.name }} <span class="float-right text-xs font-normal">{{ getDate(post.order) }}</span></h4>
|
||||
</a>
|
||||
</div>`,
|
||||
methods: {
|
||||
getBorderStyle(status)
|
||||
{
|
||||
if(status == 'published')
|
||||
{
|
||||
return "border-teal-500";
|
||||
}
|
||||
if(status == 'modified')
|
||||
{
|
||||
return "border-yellow-400";
|
||||
}
|
||||
if(status == 'unpublished')
|
||||
{
|
||||
return "border-rose-500";
|
||||
}
|
||||
},
|
||||
getUrl(posturl)
|
||||
{
|
||||
return this.baseurl + '/tm/content/' + this.editormode + this.post.urlRelWoF;
|
||||
},
|
||||
getDate(str)
|
||||
{
|
||||
var cleandate = [str.slice(0,4), str.slice(4,6), str.slice(6,8)];
|
||||
return cleandate.join("-");
|
||||
}
|
||||
}
|
||||
},
|
||||
getDate(str)
|
||||
{
|
||||
var cleandate = [str.slice(0,4), str.slice(4,6), str.slice(6,8)];
|
||||
return cleandate.join("-");
|
||||
}
|
||||
}
|
||||
})
|
@@ -86,48 +86,48 @@ const publisher = Vue.createApp({
|
||||
</div>
|
||||
<transition name="fade">
|
||||
<modal v-if="showModal == 'discard'" @close="showModal = false">
|
||||
<template #header>
|
||||
<h3>{{ $filters.translate('Discard changes') }}</h3>
|
||||
</template>
|
||||
<template #body>
|
||||
<p>{{ $filters.translate('Do you want to discard your changes and set the content back to the live version') }}?</p>
|
||||
</template>
|
||||
<template #button>
|
||||
<button @click="discardChanges" class="focus:outline-none px-4 p-3 mr-3 text-white bg-rose-500 hover:bg-rose-700 transition duration-100">{{ $filters.translate('Discard changes') }}</button>
|
||||
</template>
|
||||
<template #header>
|
||||
<h3>{{ $filters.translate('Discard changes') }}</h3>
|
||||
</template>
|
||||
<template #body>
|
||||
<p>{{ $filters.translate('Do you want to discard your changes and set the content back to the live version') }}?</p>
|
||||
</template>
|
||||
<template #button>
|
||||
<button @click="discardChanges" class="focus:outline-none px-4 p-3 mr-3 text-white bg-rose-500 hover:bg-rose-700 transition duration-100">{{ $filters.translate('Discard changes') }}</button>
|
||||
</template>
|
||||
</modal>
|
||||
</transition>
|
||||
<transition name="fade">
|
||||
<modal v-if="showModal == 'delete'" @close="showModal = false">
|
||||
<template #header>
|
||||
<h3>{{ $filters.translate('Delete page') }}</h3>
|
||||
</template>
|
||||
<template #body>
|
||||
<p>
|
||||
{{ $filters.translate('Do you really want to delete this page') }}?
|
||||
{{ $filters.translate('Please confirm') }}.
|
||||
</p>
|
||||
</template>
|
||||
<template #button>
|
||||
<button @click="deleteArticle" class="focus:outline-none px-4 p-3 mr-3 text-white bg-rose-500 hover:bg-rose-700 transition duration-100">{{ $filters.translate('Delete page') }}</button>
|
||||
</template>
|
||||
<template #header>
|
||||
<h3>{{ $filters.translate('Delete page') }}</h3>
|
||||
</template>
|
||||
<template #body>
|
||||
<p>
|
||||
{{ $filters.translate('Do you really want to delete this page') }}?
|
||||
{{ $filters.translate('Please confirm') }}.
|
||||
</p>
|
||||
</template>
|
||||
<template #button>
|
||||
<button @click="deleteArticle" class="focus:outline-none px-4 p-3 mr-3 text-white bg-rose-500 hover:bg-rose-700 transition duration-100">{{ $filters.translate('Delete page') }}</button>
|
||||
</template>
|
||||
</modal>
|
||||
</transition>
|
||||
<transition name="fade">
|
||||
<modal v-if="showModal == 'unpublish'" @close="showModal = false">
|
||||
<template #header>
|
||||
<h3>{{ $filters.translate('Unpublish page') }}</h3>
|
||||
</template>
|
||||
<template #body>
|
||||
<p>
|
||||
{{ $filters.translate('This page has been modified') }}.
|
||||
{{ $filters.translate('If you unpublish the page, then we will delete the published version and keep the modified version') }}.
|
||||
{{ $filters.translate('Please confirm') }}.
|
||||
</p>
|
||||
</template>
|
||||
<template #button>
|
||||
<button @click="unpublishArticle" class="focus:outline-none px-4 p-3 mr-3 text-white bg-rose-500 hover:bg-rose-700 transition duration-100">{{ $filters.translate('Unpublish page') }}</button>
|
||||
</template>
|
||||
<template #header>
|
||||
<h3>{{ $filters.translate('Unpublish page') }}</h3>
|
||||
</template>
|
||||
<template #body>
|
||||
<p>
|
||||
{{ $filters.translate('This page has been modified') }}.
|
||||
{{ $filters.translate('If you unpublish the page, then we will delete the published version and keep the modified version') }}.
|
||||
{{ $filters.translate('Please confirm') }}.
|
||||
</p>
|
||||
</template>
|
||||
<template #button>
|
||||
<button @click="unpublishArticle" class="focus:outline-none px-4 p-3 mr-3 text-white bg-rose-500 hover:bg-rose-700 transition duration-100">{{ $filters.translate('Unpublish page') }}</button>
|
||||
</template>
|
||||
</modal>
|
||||
</transition>
|
||||
</div>`,
|
||||
@@ -175,47 +175,47 @@ const publisher = Vue.createApp({
|
||||
isPublished()
|
||||
{
|
||||
return this.item.status == 'published' ? true : false;
|
||||
},
|
||||
},
|
||||
isModified()
|
||||
{
|
||||
return this.item.status == 'modified' ? true : false;
|
||||
},
|
||||
},
|
||||
isUnpublished()
|
||||
{
|
||||
return this.item.status == 'unpublished' ? true : false;
|
||||
},
|
||||
publishClass()
|
||||
{
|
||||
if(this.item.status == 'unpublished')
|
||||
{
|
||||
return 'bg-teal-500 hover:bg-teal-600';
|
||||
}
|
||||
else
|
||||
{
|
||||
return 'bg-yellow-500 hover:bg-yellow-600';
|
||||
}
|
||||
/*
|
||||
if(this.item.status == 'modified')
|
||||
{
|
||||
return 'bg-yellow-500 hover:bg-yellow-600';
|
||||
}*/
|
||||
},
|
||||
nopublish()
|
||||
{
|
||||
if(this.item.status != 'published')
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return this.nochanges;
|
||||
},
|
||||
rawUrl()
|
||||
{
|
||||
return data.urlinfo.baseurl + '/tm/content/raw' + this.item.urlRelWoF;
|
||||
},
|
||||
visualUrl()
|
||||
{
|
||||
return data.urlinfo.baseurl + '/tm/content/visual' + this.item.urlRelWoF;
|
||||
},
|
||||
},
|
||||
publishClass()
|
||||
{
|
||||
if(this.item.status == 'unpublished')
|
||||
{
|
||||
return 'bg-teal-500 hover:bg-teal-600';
|
||||
}
|
||||
else
|
||||
{
|
||||
return 'bg-yellow-500 hover:bg-yellow-600';
|
||||
}
|
||||
/*
|
||||
if(this.item.status == 'modified')
|
||||
{
|
||||
return 'bg-yellow-500 hover:bg-yellow-600';
|
||||
}*/
|
||||
},
|
||||
nopublish()
|
||||
{
|
||||
if(this.item.status != 'published')
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return this.nochanges;
|
||||
},
|
||||
rawUrl()
|
||||
{
|
||||
return data.urlinfo.baseurl + '/tm/content/raw' + this.item.urlRelWoF;
|
||||
},
|
||||
visualUrl()
|
||||
{
|
||||
return data.urlinfo.baseurl + '/tm/content/visual' + this.item.urlRelWoF;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
clearPublisher()
|
||||
@@ -224,14 +224,14 @@ const publisher = Vue.createApp({
|
||||
this.messageClass = false;
|
||||
this.showModal = false;
|
||||
},
|
||||
markChanges()
|
||||
{
|
||||
this.nochanges = false;
|
||||
},
|
||||
unmarkChanges()
|
||||
{
|
||||
this.nochanges = true;
|
||||
},
|
||||
markChanges()
|
||||
{
|
||||
this.nochanges = false;
|
||||
},
|
||||
unmarkChanges()
|
||||
{
|
||||
this.nochanges = true;
|
||||
},
|
||||
getStatusClass(status)
|
||||
{
|
||||
if(status == 'published')
|
||||
@@ -265,8 +265,13 @@ const publisher = Vue.createApp({
|
||||
{
|
||||
if(error.response)
|
||||
{
|
||||
self.message = error.response.data.message;
|
||||
self.messageClass = "bg-rose-500";
|
||||
let message = handleErrorMessage(error);
|
||||
|
||||
if(message)
|
||||
{
|
||||
self.message = message;
|
||||
self.messageClass = "bg-rose-500";
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
@@ -286,7 +291,7 @@ const publisher = Vue.createApp({
|
||||
{
|
||||
self = this;
|
||||
|
||||
tmaxios.delete('/api/v1/article/unpublish',{
|
||||
tmaxios.delete('/api/v1/article/unpublish',{
|
||||
data: {
|
||||
'url': data.urlinfo.route,
|
||||
'item_id': this.item.keyPath,
|
||||
@@ -300,10 +305,17 @@ const publisher = Vue.createApp({
|
||||
})
|
||||
.catch(function (error)
|
||||
{
|
||||
self.showModal = false;
|
||||
|
||||
if(error.response)
|
||||
{
|
||||
self.message = error.response.data.message;
|
||||
self.messageClass = "bg-rose-500";
|
||||
let message = handleErrorMessage(error);
|
||||
|
||||
if(message)
|
||||
{
|
||||
self.message = message;
|
||||
self.messageClass = "bg-rose-500";
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
@@ -317,7 +329,7 @@ const publisher = Vue.createApp({
|
||||
'item_id': this.item.keyPath,
|
||||
}
|
||||
})
|
||||
.then(function (response)
|
||||
.then(function (response)
|
||||
{
|
||||
self.clearPublisher();
|
||||
eventBus.$emit('item', response.data.item);
|
||||
@@ -326,10 +338,17 @@ const publisher = Vue.createApp({
|
||||
})
|
||||
.catch(function (error)
|
||||
{
|
||||
self.showModal = false;
|
||||
|
||||
if(error.response)
|
||||
{
|
||||
self.message = error.response.data.message;
|
||||
self.messageClass = "bg-rose-500";
|
||||
let message = handleErrorMessage(error);
|
||||
|
||||
if(message)
|
||||
{
|
||||
self.message = message;
|
||||
self.messageClass = "bg-rose-500";
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
@@ -345,23 +364,29 @@ const publisher = Vue.createApp({
|
||||
{
|
||||
var self = this;
|
||||
|
||||
tmaxios.delete('/api/v1/article',{
|
||||
tmaxios.delete('/api/v1/article',{
|
||||
data: {
|
||||
'url': data.urlinfo.route,
|
||||
'item_id': this.item.keyPath,
|
||||
}
|
||||
})
|
||||
.then(function (response)
|
||||
{
|
||||
.then(function (response)
|
||||
{
|
||||
window.location.replace(response.data.url);
|
||||
})
|
||||
})
|
||||
.catch(function (error)
|
||||
{
|
||||
self.showModal = false;
|
||||
|
||||
if(error.response)
|
||||
{
|
||||
self.showModal = false;
|
||||
self.message = error.response.data.message;
|
||||
self.messageClass = "bg-rose-500";
|
||||
let message = handleErrorMessage(error);
|
||||
|
||||
if(message)
|
||||
{
|
||||
self.message = message;
|
||||
self.messageClass = "bg-rose-500";
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
@@ -130,7 +130,14 @@ const raweditor = Vue.createApp({
|
||||
})
|
||||
.catch(function (error)
|
||||
{
|
||||
|
||||
if(error.response)
|
||||
{
|
||||
let message = handleErrorMessage(error);
|
||||
if(message)
|
||||
{
|
||||
eventBus.$emit('publishermessage', message);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
publishDraft()
|
||||
@@ -150,7 +157,14 @@ const raweditor = Vue.createApp({
|
||||
})
|
||||
.catch(function (error)
|
||||
{
|
||||
|
||||
if(error.response)
|
||||
{
|
||||
let message = handleErrorMessage(error);
|
||||
if(message)
|
||||
{
|
||||
eventBus.$emit('publishermessage', message);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
|
@@ -51,3 +51,76 @@ const translatefilter = {
|
||||
}
|
||||
}
|
||||
|
||||
function handleErrorMessage(error)
|
||||
{
|
||||
if(error.response)
|
||||
{
|
||||
if(error.response.status == 401)
|
||||
{
|
||||
eventBus.$emit('loginform', false);
|
||||
}
|
||||
else if(error.response.data.message)
|
||||
{
|
||||
return error.response.data.message;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
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="text-left p-6">
|
||||
<div class="text-2xl font-bold"><h2>You are logged out</h2></div>
|
||||
<div class="my-5">
|
||||
<p>You can visit the login page and authenticate again. Or you can close this window but you cannot perform any actions.</p>
|
||||
</div>
|
||||
<div class="flex justify-end pt-2">
|
||||
<a :href="loginurl" class="focus:outline-none px-4 p-3 mr-3 text-black bg-stone-200 hover:bg-stone-300 transition duration-100">login page</a>
|
||||
<button class="focus:outline-none px-4 p-3 mr-3 text-black bg-stone-200 hover:bg-stone-300 transition duration-100" @click="show = false">close window</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</transition>`,
|
||||
data() {
|
||||
return {
|
||||
show: false,
|
||||
errors: {},
|
||||
username: '',
|
||||
password: '',
|
||||
loginurl: data.urlinfo.baseurl + '/tm/login'
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
eventBus.$on('loginform', content => {
|
||||
this.show = true;
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
login: function()
|
||||
{
|
||||
var self = this;
|
||||
|
||||
tmaxios.post('/api/v1/authenticate',{
|
||||
'username': this.username,
|
||||
'password': this.password
|
||||
})
|
||||
.then(function (response)
|
||||
{
|
||||
self.show = false;
|
||||
})
|
||||
.catch(function (error)
|
||||
{
|
||||
self.messageClass = 'bg-rose-500';
|
||||
self.message = error.response.data.message;
|
||||
if(error.response.data.errors !== undefined)
|
||||
{
|
||||
self.errors = error.response.data.errors;
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
})
|
@@ -1,6 +1,6 @@
|
||||
const app = Vue.createApp({
|
||||
template: `<Transition name="initial" appear>
|
||||
<form class="inline-block w-full">
|
||||
<form class="inline-block w-full">
|
||||
<p v-if="version.system !== undefined"><a href="https://typemill.net" class="block p-2 text-center bg-rose-500 text-white">Please update typemill to version {{ version.system }}</a></p>
|
||||
<ul class="flex mt-4 mb-4">
|
||||
<li v-for="tab in tabs" class="">
|
||||
@@ -24,8 +24,8 @@ const app = Vue.createApp({
|
||||
<div :class="messageClass" class="block w-full h-8 px-3 py-1 my-1 text-white transition duration-100">{{ $filters.translate(message) }}</div>
|
||||
<input type="submit" @click.prevent="save()" :value="$filters.translate('save')" class="w-full p-3 my-1 bg-stone-700 hover:bg-stone-900 text-white cursor-pointer transition duration-100">
|
||||
</div>
|
||||
</form>
|
||||
</Transition>`,
|
||||
</form>
|
||||
</Transition>`,
|
||||
data() {
|
||||
return {
|
||||
currentTab: 'System',
|
||||
@@ -65,13 +65,15 @@ const app = Vue.createApp({
|
||||
if(response.data.system)
|
||||
{
|
||||
self.version = response.data.system;
|
||||
console.info(self.version);
|
||||
}
|
||||
})
|
||||
.catch(function (error)
|
||||
{
|
||||
self.messageClass = 'bg-rose-500';
|
||||
self.message = error.response.data.message;
|
||||
if(error.response)
|
||||
{
|
||||
self.message = handleErrorMessage(error);
|
||||
self.messageClass = 'bg-rose-500';
|
||||
}
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
@@ -98,11 +100,14 @@ const app = Vue.createApp({
|
||||
})
|
||||
.catch(function (error)
|
||||
{
|
||||
self.messageClass = 'bg-rose-500';
|
||||
self.message = error.response.data.message;
|
||||
if(error.response.data.errors !== undefined)
|
||||
if(error.response)
|
||||
{
|
||||
self.errors = error.response.data.errors;
|
||||
self.message = handleErrorMessage(error);
|
||||
self.messageClass = 'bg-rose-500';
|
||||
if(error.response.data.errors !== undefined)
|
||||
{
|
||||
self.errors = error.response.data.errors;
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
@@ -8,12 +8,12 @@ const app = Vue.createApp({
|
||||
<p class="py-2">License: {{ theme.license }}</p>
|
||||
<div class="flex">
|
||||
<label :for="themename" class="p-2">{{ $filters.translate('active') }}</label>
|
||||
<input type="checkbox" class="w-6 h-6 my-2 accent-white"
|
||||
:name="themename"
|
||||
v-model="formData[themename]['active']"
|
||||
@change="activate(themename)">
|
||||
<input type="checkbox" class="w-6 h-6 my-2 accent-white"
|
||||
:name="themename"
|
||||
v-model="formData[themename]['active']"
|
||||
@change="activate(themename)">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-full p-8">
|
||||
<div class="flex pb-4">
|
||||
<div class="w-1/2">
|
||||
@@ -71,15 +71,15 @@ const app = Vue.createApp({
|
||||
</ul>
|
||||
<div class="my-5 text-center">
|
||||
<modal v-if="showModal" @close="showModal = false">
|
||||
<template #header>
|
||||
<h3>{{ $filters.translate('License required') }}</h3>
|
||||
</template>
|
||||
<template #body>
|
||||
<p>{{ $filters.translate(modalMessage) }}</p>
|
||||
</template>
|
||||
<template #button>
|
||||
<a :href="getLinkToLicense()" class="focus:outline-none px-4 p-3 mr-3 text-white bg-teal-500 hover:bg-teal-700 transition duration-100">{{ $filters.translate('Check your license') }}</a>
|
||||
</template>
|
||||
<template #header>
|
||||
<h3>{{ $filters.translate('License required') }}</h3>
|
||||
</template>
|
||||
<template #body>
|
||||
<p>{{ $filters.translate(modalMessage) }}</p>
|
||||
</template>
|
||||
<template #button>
|
||||
<a :href="getLinkToLicense()" class="focus:outline-none px-4 p-3 mr-3 text-white bg-teal-500 hover:bg-teal-700 transition duration-100">{{ $filters.translate('Check your license') }}</a>
|
||||
</template>
|
||||
</modal>
|
||||
</div>
|
||||
</div>
|
||||
@@ -132,8 +132,11 @@ const app = Vue.createApp({
|
||||
})
|
||||
.catch(function (error)
|
||||
{
|
||||
self.messageClass = 'bg-rose-500';
|
||||
self.message = error.response.data.message;
|
||||
if(error.response)
|
||||
{
|
||||
self.messageClass = 'bg-rose-500';
|
||||
self.message = handleErrorMessage(error);
|
||||
}
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
@@ -182,8 +185,12 @@ const app = Vue.createApp({
|
||||
})
|
||||
.catch(function (error)
|
||||
{
|
||||
self.modalMessage = error.response.data.message;
|
||||
self.showModal = true;
|
||||
if(error.response)
|
||||
{
|
||||
self.showModal = true;
|
||||
self.modalMessage = handleErrorMessage(error);
|
||||
self.messageClass = 'bg-rose-500';
|
||||
}
|
||||
});
|
||||
},
|
||||
setCurrent: function(name)
|
||||
@@ -219,11 +226,14 @@ const app = Vue.createApp({
|
||||
})
|
||||
.catch(function (error)
|
||||
{
|
||||
self.messageClass = 'bg-rose-500';
|
||||
self.message = error.response.data.message;
|
||||
if(error.response.data.errors !== undefined)
|
||||
if(error.response)
|
||||
{
|
||||
self.errors = error.response.data.errors;
|
||||
self.message = handleErrorMessage(error);
|
||||
self.messageClass = 'bg-rose-500';
|
||||
if(error.response.data.errors !== undefined)
|
||||
{
|
||||
self.errors = error.response.data.errors;
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
@@ -6,23 +6,23 @@ const app = Vue.createApp({
|
||||
<fieldset class="flex flex-wrap justify-between border-2 border-stone-200 p-4 my-8" v-if="fieldDefinition.type == 'fieldset'">
|
||||
<legend class="text-lg font-medium">{{ $filters.translate(fieldDefinition.legend) }}</legend>
|
||||
<component v-for="(subfieldDefinition, subfieldname) in fieldDefinition.fields"
|
||||
:key="subfieldname"
|
||||
:is="selectComponent(subfieldDefinition.type)"
|
||||
:errors="errors"
|
||||
:name="subfieldname"
|
||||
:userroles="userroles"
|
||||
:value="formData[subfieldname]"
|
||||
v-bind="subfieldDefinition">
|
||||
:key="subfieldname"
|
||||
:is="selectComponent(subfieldDefinition.type)"
|
||||
:errors="errors"
|
||||
:name="subfieldname"
|
||||
:userroles="userroles"
|
||||
:value="formData[subfieldname]"
|
||||
v-bind="subfieldDefinition">
|
||||
</component>
|
||||
</fieldset>
|
||||
<component v-else
|
||||
:key="fieldname"
|
||||
:is="selectComponent(fieldDefinition.type)"
|
||||
:errors="errors"
|
||||
:name="fieldname"
|
||||
:userroles="userroles"
|
||||
:value="formData[fieldname]"
|
||||
v-bind="fieldDefinition">
|
||||
:key="fieldname"
|
||||
:is="selectComponent(fieldDefinition.type)"
|
||||
:errors="errors"
|
||||
:name="fieldname"
|
||||
:userroles="userroles"
|
||||
:value="formData[fieldname]"
|
||||
v-bind="fieldDefinition">
|
||||
</component>
|
||||
</div>
|
||||
<div class="my-5">
|
||||
@@ -33,15 +33,15 @@ const app = Vue.createApp({
|
||||
<div class="my-5 text-center">
|
||||
<button @click.prevent="showModal = true" class="p-3 px-4 text-rose-500 border border-rose-100 hover:border-rose-500 cursor-pointer transition duration-100">{{ $filters.translate('delete user') }}</button>
|
||||
<modal v-if="showModal" @close="showModal = false">
|
||||
<template #header>
|
||||
<h3>{{ $filters.translate('Delete user') }}</h3>
|
||||
</template>
|
||||
<template #body>
|
||||
<p>{{ $filters.translate('Do you really want to delete this user') }}?</p>
|
||||
</template>
|
||||
<template #button>
|
||||
<button @click="deleteuser()" class="focus:outline-none px-4 p-3 mr-3 text-white bg-rose-500 hover:bg-rose-700 transition duration-100">{{ $filters.translate('delete user') }}</button>
|
||||
</template>
|
||||
<template #header>
|
||||
<h3>{{ $filters.translate('Delete user') }}</h3>
|
||||
</template>
|
||||
<template #body>
|
||||
<p>{{ $filters.translate('Do you really want to delete this user') }}?</p>
|
||||
</template>
|
||||
<template #button>
|
||||
<button @click="deleteuser()" class="focus:outline-none px-4 p-3 mr-3 text-white bg-rose-500 hover:bg-rose-700 transition duration-100">{{ $filters.translate('delete user') }}</button>
|
||||
</template>
|
||||
</modal>
|
||||
</div>
|
||||
</div>
|
||||
@@ -89,11 +89,14 @@ const app = Vue.createApp({
|
||||
})
|
||||
.catch(function (error)
|
||||
{
|
||||
self.messageClass = 'bg-rose-500';
|
||||
self.message = error.response.data.message;
|
||||
if(error.response.data.errors !== undefined)
|
||||
if(error.response)
|
||||
{
|
||||
self.errors = error.response.data.errors;
|
||||
self.messageClass = 'bg-rose-500';
|
||||
self.message = handleErrorMessage(error);
|
||||
if(error.response.data.errors !== undefined)
|
||||
{
|
||||
self.errors = error.response.data.errors;
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
@@ -117,12 +120,15 @@ const app = Vue.createApp({
|
||||
})
|
||||
.catch(function (error)
|
||||
{
|
||||
self.showModal = false;
|
||||
self.messageClass = 'bg-rose-500';
|
||||
self.message = error.response.data.message;
|
||||
if(error.response.data.errors !== undefined)
|
||||
if(error.response)
|
||||
{
|
||||
self.errors = error.response.data.errors;
|
||||
self.showModal = false;
|
||||
self.messageClass = 'bg-rose-500';
|
||||
self.message = handleErrorMessage(error);
|
||||
if(error.response.data.errors !== undefined)
|
||||
{
|
||||
self.errors = error.response.data.errors;
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
@@ -10,28 +10,28 @@ const app = Vue.createApp({
|
||||
<option v-for="option,optionkey in userroles">{{option}}</option>
|
||||
</select>
|
||||
</div>
|
||||
<form v-if="formDefinitions" class="w-full my-8">
|
||||
<form v-if="formDefinitions" class="w-full my-8">
|
||||
<div v-for="(fieldDefinition, fieldname) in formDefinitions">
|
||||
<fieldset class="flex flex-wrap justify-between border-2 border-stone-200 p-4 my-8" v-if="fieldDefinition.type == 'fieldset'">
|
||||
<legend class="text-lg font-medium">{{ fieldDefinition.legend }}</legend>
|
||||
<component v-for="(subfieldDefinition, subfieldname) in fieldDefinition.fields"
|
||||
:key="subfieldname"
|
||||
:is="selectComponent(subfieldDefinition.type)"
|
||||
:errors="errors"
|
||||
:name="subfieldname"
|
||||
:userroles="userroles"
|
||||
:value="formData[subfieldname]"
|
||||
v-bind="subfieldDefinition">
|
||||
:key="subfieldname"
|
||||
:is="selectComponent(subfieldDefinition.type)"
|
||||
:errors="errors"
|
||||
:name="subfieldname"
|
||||
:userroles="userroles"
|
||||
:value="formData[subfieldname]"
|
||||
v-bind="subfieldDefinition">
|
||||
</component>
|
||||
</fieldset>
|
||||
<component v-else
|
||||
:key="fieldname"
|
||||
:is="selectComponent(fieldDefinition.type)"
|
||||
:errors="errors"
|
||||
:name="fieldname"
|
||||
:userroles="userroles"
|
||||
:value="formData[fieldname]"
|
||||
v-bind="fieldDefinition">
|
||||
:key="fieldname"
|
||||
:is="selectComponent(fieldDefinition.type)"
|
||||
:errors="errors"
|
||||
:name="fieldname"
|
||||
:userroles="userroles"
|
||||
:value="formData[fieldname]"
|
||||
v-bind="fieldDefinition">
|
||||
</component>
|
||||
</div>
|
||||
<div class="my-5">
|
||||
@@ -67,10 +67,10 @@ const app = Vue.createApp({
|
||||
this.reset();
|
||||
var self = this;
|
||||
|
||||
tmaxios.get('/api/v1/userform',{
|
||||
params: {
|
||||
tmaxios.get('/api/v1/userform',{
|
||||
params: {
|
||||
'userrole': this.selectedrole
|
||||
}
|
||||
}
|
||||
})
|
||||
.then(function (response)
|
||||
{
|
||||
@@ -79,13 +79,16 @@ const app = Vue.createApp({
|
||||
})
|
||||
.catch(function (error)
|
||||
{
|
||||
self.messageClass = 'bg-rose-500';
|
||||
self.message = error.response.data.message;
|
||||
if(error.response.data.errors !== undefined)
|
||||
if(error.response)
|
||||
{
|
||||
self.errors = error.response.data.errors;
|
||||
self.messageClass = 'bg-rose-500';
|
||||
self.message = handleErrorMessage(error);
|
||||
if(error.response.data.errors !== undefined)
|
||||
{
|
||||
self.errors = error.response.data.errors;
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
save: function()
|
||||
{
|
||||
@@ -104,11 +107,14 @@ const app = Vue.createApp({
|
||||
})
|
||||
.catch(function (error)
|
||||
{
|
||||
self.messageClass = 'bg-rose-500';
|
||||
self.message = error.response.data.message;
|
||||
if(error.response.data.errors !== undefined)
|
||||
if(error.response)
|
||||
{
|
||||
self.errors = error.response.data.errors;
|
||||
self.messageClass = 'bg-rose-500';
|
||||
self.message = handleErrorMessage(error);
|
||||
if(error.response.data.errors !== undefined)
|
||||
{
|
||||
self.errors = error.response.data.errors;
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
@@ -4,10 +4,10 @@ const app = Vue.createApp({
|
||||
<searchbox :error="error"></searchbox>
|
||||
</Transition>
|
||||
</div>
|
||||
<div class="w-full overflow-auto">
|
||||
<div class="w-full overflow-auto">
|
||||
<Transition name="initial" appear>
|
||||
<usertable :userdata="userdata"></usertable>
|
||||
</Transition>
|
||||
<usertable :userdata="userdata"></usertable>
|
||||
</Transition>
|
||||
</div>
|
||||
<ul class="w-full flex mt-4" v-if="showpagination">
|
||||
<pagination
|
||||
@@ -33,8 +33,8 @@ const app = Vue.createApp({
|
||||
this.calculatepages();
|
||||
},
|
||||
computed: {
|
||||
showpagination: function () {
|
||||
return this.pages != 1;
|
||||
showpagination: function () {
|
||||
return this.pages != 1;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
@@ -53,27 +53,30 @@ const app = Vue.createApp({
|
||||
this.pages = Math.ceil(this.usernames.length / this.pagesize);
|
||||
this.pagenumber = 1;
|
||||
},
|
||||
getusernamesforpage: function() {
|
||||
// human-readable page numbers usually start with 1, so we reduce 1 in the first argument
|
||||
return this.usernames.slice((this.pagenumber - 1) * this.pagesize, this.pagenumber * this.pagesize);
|
||||
getusernamesforpage: function() {
|
||||
// human-readable page numbers usually start with 1, so we reduce 1 in the first argument
|
||||
return this.usernames.slice((this.pagenumber - 1) * this.pagesize, this.pagenumber * this.pagesize);
|
||||
},
|
||||
getuserdata: function(usernames)
|
||||
{
|
||||
var self = this;
|
||||
|
||||
tmaxios.get('/api/v1/users/getbynames',{
|
||||
params: {
|
||||
'usernames': usernames,
|
||||
}
|
||||
tmaxios.get('/api/v1/users/getbynames',{
|
||||
params: {
|
||||
'usernames': usernames,
|
||||
}
|
||||
})
|
||||
.then(function (response) {
|
||||
self.userdata = response.data.userdata;
|
||||
})
|
||||
.catch(function (error)
|
||||
{
|
||||
self.messageClass = 'bg-rose-500';
|
||||
self.message = error.response.data.message;
|
||||
});
|
||||
.then(function (response) {
|
||||
self.userdata = response.data.userdata;
|
||||
})
|
||||
.catch(function (error)
|
||||
{
|
||||
if(error.response)
|
||||
{
|
||||
self.messageClass = 'bg-rose-500';
|
||||
self.message = handleErrorMessage(error);
|
||||
}
|
||||
});
|
||||
},
|
||||
search: function(term,filter)
|
||||
{
|
||||
@@ -98,25 +101,31 @@ const app = Vue.createApp({
|
||||
|
||||
var self = this;
|
||||
|
||||
tmaxios.get('/api/v1/users/getbyemail',{
|
||||
params: {
|
||||
'email': term,
|
||||
}
|
||||
tmaxios.get('/api/v1/users/getbyemail',{
|
||||
params: {
|
||||
'email': term,
|
||||
}
|
||||
})
|
||||
.then(function (response)
|
||||
{
|
||||
self.userdata = response.data.userdata;
|
||||
for(var x = 0; x <= self.userdata.length; x++)
|
||||
{
|
||||
self.usernames.push(self.userdata[x].username);
|
||||
}
|
||||
self.calculatepages();
|
||||
})
|
||||
.catch(function (error)
|
||||
{
|
||||
self.messageClass = 'bg-rose-500';
|
||||
self.message = error.response.data.message;
|
||||
});
|
||||
.then(function (response)
|
||||
{
|
||||
self.userdata = response.data.userdata;
|
||||
if(self.userdata.length > 0)
|
||||
{
|
||||
for(var x = 0; x <= self.userdata.length; x++)
|
||||
{
|
||||
self.usernames.push(self.userdata[x].username);
|
||||
}
|
||||
self.calculatepages();
|
||||
}
|
||||
})
|
||||
.catch(function (error)
|
||||
{
|
||||
if(error.response)
|
||||
{
|
||||
self.messageClass = 'bg-rose-500';
|
||||
self.message = handleErrorMessage(error);
|
||||
}
|
||||
});
|
||||
}
|
||||
else if(filter == 'userrole')
|
||||
{
|
||||
@@ -126,57 +135,60 @@ const app = Vue.createApp({
|
||||
|
||||
var self = this;
|
||||
|
||||
tmaxios.get('/api/v1/users/getbyrole',{
|
||||
params: {
|
||||
'role': term,
|
||||
}
|
||||
tmaxios.get('/api/v1/users/getbyrole',{
|
||||
params: {
|
||||
'role': term,
|
||||
}
|
||||
})
|
||||
.then(function (response)
|
||||
{
|
||||
self.userdata = response.data.userdata;
|
||||
for(var x = 0; x <= self.userdata.length; x++)
|
||||
{
|
||||
self.usernames.push(self.userdata[x].username);
|
||||
}
|
||||
.then(function (response)
|
||||
{
|
||||
self.userdata = response.data.userdata;
|
||||
for(var x = 0; x <= self.userdata.length; x++)
|
||||
{
|
||||
self.usernames.push(self.userdata[x].username);
|
||||
}
|
||||
self.calculatepages();
|
||||
})
|
||||
.catch(function (error)
|
||||
{
|
||||
self.messageClass = 'bg-rose-500';
|
||||
self.message = error.response.data.message;
|
||||
});
|
||||
})
|
||||
.catch(function (error)
|
||||
{
|
||||
if(error.response)
|
||||
{
|
||||
self.messageClass = 'bg-rose-500';
|
||||
self.message = handleErrorMessage(error);
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
filterItems: function(arr, query)
|
||||
{
|
||||
return arr.filter(function(el){
|
||||
return el.toLowerCase().indexOf(query.toLowerCase()) !== -1
|
||||
return el.toLowerCase().indexOf(query.toLowerCase()) !== -1
|
||||
})
|
||||
},
|
||||
}
|
||||
})
|
||||
|
||||
app.component('searchbox', {
|
||||
props: ['usernames', 'error'],
|
||||
data: function () {
|
||||
props: ['usernames', 'error'],
|
||||
data: function () {
|
||||
return {
|
||||
filter: 'username',
|
||||
searchterm: '',
|
||||
userroles: data.userroles,
|
||||
filter: 'username',
|
||||
searchterm: '',
|
||||
userroles: data.userroles,
|
||||
}
|
||||
},
|
||||
template: `<div>
|
||||
<div>
|
||||
<button @click.prevent="setFilter('username')" :class="checkActive('username')" class="px-2 py-2 border-b-4 hover:bg-stone-200 hover:border-stone-700 transition duration-100">{{ $filters.translate('username') }}</button>
|
||||
template: `<div>
|
||||
<div>
|
||||
<button @click.prevent="setFilter('username')" :class="checkActive('username')" class="px-2 py-2 border-b-4 hover:bg-stone-200 hover:border-stone-700 transition duration-100">{{ $filters.translate('username') }}</button>
|
||||
<button @click.prevent="setFilter('userrole')" :class="checkActive('userrole')" class="px-2 py-2 border-b-4 hover:bg-stone-200 hover:border-stone-700 transition duration-100">{{ $filters.translate('userrole') }}</button>
|
||||
<button @click.prevent="setFilter('usermail')" :class="checkActive('usermail')" class="px-2 py-2 border-b-4 hover:bg-stone-200 hover:border-stone-700 transition duration-100">{{ $filters.translate('e-mail') }}</button>
|
||||
</div>
|
||||
<div class="w-100 flex">
|
||||
<div class="w-100 flex">
|
||||
<select v-if="this.filter == 'userrole'" v-model="searchterm" class="w-3/4 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="w-3/4 h-12 px-2 py-3 border border-stone-300 bg-stone-200">
|
||||
<div class="w-1/4 flex justify-around">
|
||||
<input v-else type="text" v-model="searchterm" class="w-3/4 h-12 px-2 py-3 border border-stone-300 bg-stone-200">
|
||||
<div class="w-1/4 flex justify-around">
|
||||
<button class="w-half bg-stone-200 hover:bg-stone-100" @click.prevent="clearSearch()">{{ $filters.translate('Clear') }}</button>
|
||||
<button class="w-half bg-stone-700 hover:bg-stone-900 text-white" @click.prevent="startSearch()">{{ $filters.translate('Search') }}</button>
|
||||
</div>
|
||||
@@ -184,96 +196,96 @@ app.component('searchbox', {
|
||||
<div v-if="error" class="error pt1 f6">{{error}}</div>
|
||||
<div v-if="this.filter == \'usermail\'" class="text-xs">{{ $filters.translate('You can use the asterisk (*) wildcard to search for name@* or *@domain.com') }}.</div>
|
||||
</div>`,
|
||||
methods: {
|
||||
startSearch: function()
|
||||
{
|
||||
this.$root.error = false;
|
||||
|
||||
if(this.searchterm.trim() != '')
|
||||
{
|
||||
if(this.searchterm.trim().length < 3)
|
||||
{
|
||||
this.$root.error = 'Please enter at least 3 characters';
|
||||
return;
|
||||
}
|
||||
this.$root.search(this.searchterm, this.filter);
|
||||
}
|
||||
},
|
||||
clearSearch: function()
|
||||
{
|
||||
this.$root.error = false;
|
||||
this.searchterm = '';
|
||||
this.$root.clear(this.filter);
|
||||
},
|
||||
setFilter: function(filter)
|
||||
{
|
||||
this.searchterm = '';
|
||||
this.filter = filter;
|
||||
if(filter == 'userrole')
|
||||
{
|
||||
this.searchterm = this.userroles[0];
|
||||
}
|
||||
},
|
||||
checkActive: function(filter)
|
||||
{
|
||||
if(this.filter == filter)
|
||||
{
|
||||
return 'border-stone-700 bg-stone-200';
|
||||
}
|
||||
return 'border-stone-100 bg-stone-100';
|
||||
}
|
||||
}
|
||||
methods: {
|
||||
startSearch: function()
|
||||
{
|
||||
this.$root.error = false;
|
||||
|
||||
if(this.searchterm.trim() != '')
|
||||
{
|
||||
if(this.searchterm.trim().length < 3)
|
||||
{
|
||||
this.$root.error = 'Please enter at least 3 characters';
|
||||
return;
|
||||
}
|
||||
this.$root.search(this.searchterm, this.filter);
|
||||
}
|
||||
},
|
||||
clearSearch: function()
|
||||
{
|
||||
this.$root.error = false;
|
||||
this.searchterm = '';
|
||||
this.$root.clear(this.filter);
|
||||
},
|
||||
setFilter: function(filter)
|
||||
{
|
||||
this.searchterm = '';
|
||||
this.filter = filter;
|
||||
if(filter == 'userrole')
|
||||
{
|
||||
this.searchterm = this.userroles[0];
|
||||
}
|
||||
},
|
||||
checkActive: function(filter)
|
||||
{
|
||||
if(this.filter == filter)
|
||||
{
|
||||
return 'border-stone-700 bg-stone-200';
|
||||
}
|
||||
return 'border-stone-100 bg-stone-100';
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
app.component('usertable', {
|
||||
props: ['userdata'],
|
||||
template: `<table class="w-full mt-8" cellspacing="0">
|
||||
props: ['userdata'],
|
||||
template: `<table class="w-full mt-8" cellspacing="0">
|
||||
<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>
|
||||
</tr>
|
||||
<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>
|
||||
</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>
|
||||
</tr>
|
||||
<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>
|
||||
</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>
|
||||
</tr>
|
||||
</table>`,
|
||||
methods: {
|
||||
methods: {
|
||||
getEditLink: function(username){
|
||||
return tmaxios.defaults.baseURL + '/tm/user/' + username;
|
||||
},
|
||||
getNewUserLink: function(){
|
||||
return tmaxios.defaults.baseURL + '/tm/user/new';
|
||||
},
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
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>',
|
||||
methods: {
|
||||
goto: function(page){
|
||||
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>',
|
||||
methods: {
|
||||
goto: function(page){
|
||||
|
||||
this.$root.$data.pagenumber = page;
|
||||
let usernames = this.$root.getusernamesforpage();
|
||||
this.$root.getuserdata(usernames);
|
||||
},
|
||||
checkActive: function()
|
||||
{
|
||||
if(this.page == this.$root.$data.pagenumber)
|
||||
{
|
||||
return 'bg-stone-200';
|
||||
}
|
||||
return 'bg-stone-100';
|
||||
}
|
||||
}
|
||||
},
|
||||
checkActive: function()
|
||||
{
|
||||
if(this.page == this.$root.$data.pagenumber)
|
||||
{
|
||||
return 'bg-stone-200';
|
||||
}
|
||||
return 'bg-stone-100';
|
||||
}
|
||||
}
|
||||
})
|
@@ -42,6 +42,7 @@
|
||||
{% block content %}{% endblock %}
|
||||
</article>
|
||||
</div>
|
||||
<div id="loginform"></div>
|
||||
|
||||
<!-- < csrf() | raw > -->
|
||||
|
||||
@@ -67,6 +68,7 @@
|
||||
<script>
|
||||
navigation.config.globalProperties.$filters = translatefilter;
|
||||
navigation.mount('#contentNavigation');
|
||||
loginform.mount("#loginform");
|
||||
</script>
|
||||
{% block javascript %}{% endblock %}
|
||||
|
||||
|
@@ -42,7 +42,7 @@
|
||||
{% block content %}{% endblock %}
|
||||
</article>
|
||||
</div>
|
||||
|
||||
<div id="loginform"></div>
|
||||
<!-- < csrf() | raw > -->
|
||||
|
||||
<script>
|
||||
@@ -64,6 +64,7 @@
|
||||
<script src="{{ base_url() }}/system/typemill/author/js/vue-medialib.js?v={{ settings.version }}"></script>
|
||||
<script>
|
||||
/* kixote.mount('#kixote'); */
|
||||
loginform.mount("#loginform");
|
||||
</script>
|
||||
{% block javascript %}{% endblock %}
|
||||
|
||||
|
@@ -45,7 +45,8 @@
|
||||
</article>
|
||||
|
||||
</div>
|
||||
|
||||
<div id="loginform"></div>
|
||||
|
||||
<script>
|
||||
|
||||
const data = {{ jsdata | json_encode() | raw }};
|
||||
@@ -73,6 +74,8 @@
|
||||
app.config.globalProperties.$filters = translatefilter;
|
||||
app.mount('#system');
|
||||
|
||||
loginform.mount("#loginform");
|
||||
|
||||
/* kixote.mount('#kixote'); */
|
||||
|
||||
</script>
|
||||
|
@@ -32,7 +32,7 @@ fieldsetsystem:
|
||||
maxlength: 4
|
||||
language:
|
||||
type: select
|
||||
label: Language (admin ui)
|
||||
label: Language (author area)
|
||||
css: w-half
|
||||
maxlength: 60
|
||||
options:
|
||||
|
Reference in New Issue
Block a user