Publishing module assets

parent 7950d0dd
<template>
<div class="ckeditor">
<textarea
:name="name"
:id="id"
:value="value"
:types="types"
:config="config">
</textarea>
</div>
</template>
<script>
// Source: https://github.com/dangvanthanh/vue-ckeditor2
let inc = 0
export default {
name: 'vue-ckeditor',
props: {
name: {
type: String,
default: () => `editor-${++inc}`
},
value: {
type: String
},
id: {
type: String,
default: () => `editor-${inc}`
},
types: {
type: String,
default: () => `classic`
},
config: {
type: Object,
default: () => {}
}
},
data () {
return { destroyed: false }
},
computed: {
instance () {
return CKEDITOR.instances[this.id]
}
},
watch: {
value (val) {
let html = this.instance.getData();
if (val !== html) {
this.instance.setData(val);
}
}
},
mounted () {
if (typeof CKEDITOR === 'undefined') {
console.log('CKEDITOR is missing (http://ckeditor.com/)')
} else {
if (this.types === 'inline') {
CKEDITOR.inline(this.id, this.config)
} else {
CKEDITOR.replace(this.id, this.config)
}
this.instance.on('change', () => {
let html = this.instance.getData()
if (html !== this.value) {
this.$emit('input', html)
this.$emit('update:value', html)
}
})
this.instance.on('blur', () => {
this.$emit('blur', this.instance)
})
this.instance.on('focus', () => {
this.$emit('focus', this.instance)
})
}
},
beforeDestroy () {
if (!this.destroyed) {
this.instance.focusManager.blur(true)
this.instance.removeAllListeners()
try {
this.instance.destroy()
} catch (e) { }
this.destroyed = true
}
}
}
</script>
<style>
.ckeditor::after {
content: "";
display: table;
clear: both;
}
</style>
<template>
<button class="btn btn-danger btn-flat" @click="deleteRow"><i class="fa fa-trash"></i></button>
</template>
<script>
import Translate from '../../../../Core/Assets/js/mixins/Translate'
export default {
mixins: [Translate],
props: {
rows: {default: null},
scope: {default: null},
},
data() {
return {
deleteMessage: '',
deleteTitle: '',
}
},
methods: {
deleteRow(event) {
this.$confirm(this.deleteMessage, this.deleteTitle, {
confirmButtonText: this.translate('core', 'button.delete'),
cancelButtonText: this.translate('core', 'button.cancel'),
type: 'warning'
}).then(() => {
let vm = this;
axios.delete(this.scope.row.urls.delete_url)
.then(response => {
if (response.data.errors === false) {
vm.$message({
type: 'success',
message: response.data.message
});
vm.rows.splice(vm.scope.$index, 1);
}
})
.catch(error => {
vm.$message({
type: 'error',
message: response.data.message
});
});
}).catch(() => {
this.$message({
type: 'info',
message: this.translate('core', 'delete cancelled')
});
});
}
},
mounted() {
this.deleteMessage = this.translate('core', 'modal.confirmation-message');
this.deleteTitle = this.translate('core', 'modal.title');
}
}
</script>
export default {
methods: {
slugify(string) {
let value;
value = string.replace(/^\s+|\s+$/g, ''); // trim
value = value.toLowerCase();
// remove accents, swap ñ for n, etc
var from = "ãàáäâẽèéëêìíïîõòóöôùúüûñç·/_,:;";
var to = "aaaaaeeeeeiiiiooooouuuunc------";
for (var i = 0, l = from.length; i < l; i++) {
value = value.replace(new RegExp(from.charAt(i), 'g'), to.charAt(i));
}
value = value.replace(/[^a-z0-9 -]/g, '') // remove invalid chars
.replace(/\s+/g, '-') // collapse whitespace and replace by -
.replace(/-+/g, '-'); // collapse dashes
return value;
}
}
}
export default {
props: {
translations: {default: null}
},
methods: {
translate(namespace, name) {
return _.get(this.translations[namespace], name);
}
}
}
import PageTable from './components/PageTable.vue'
import PageTableServerSide from './components/PageTableServerSide.vue'
import PageForm from './components/PageForm.vue'
const translations = window.translations;
const locales = window.locales;
export default [
{
path: '/page/pages',
name: 'admin.page.page.index',
component: PageTableServerSide,
props: {
translations,
}
},
{
path: '/page/pages/create',
name: 'admin.page.page.create',
component: PageForm,
props: {
translations,
locales,
pageTitle: 'create page',
}
},
{
path: '/page/pages/:pageId/edit',
name: 'admin.page.page.edit',
component: PageForm,
props: {
translations,
locales,
pageTitle: 'edit page',
}
},
];
<template>
<div class="div">
<div class="content-header">
<h1>
{{ translate('page', pageTitle) }}
</h1>
<el-breadcrumb separator="/">
<el-breadcrumb-item>
<a href="/backend">Home</a>
</el-breadcrumb-item>
<el-breadcrumb-item :to="{name: 'admin.page.page.index'}">{{ translate('page', 'pages') }}
</el-breadcrumb-item>
<el-breadcrumb-item :to="{name: 'admin.page.page.create'}">{{ translate('page', pageTitle) }}
</el-breadcrumb-item>
</el-breadcrumb>
</div>
<el-form ref="form" :model="page" label-width="120px" label-position="top"
v-loading.body="loading"
@keydown="form.errors.clear($event.target.name);">
<div class="row">
<div class="col-md-10">
<div class="box box-primary">
<div class="box-body">
<el-tabs type="card">
<el-tab-pane :label="localeArray.name" v-for="(localeArray, locale) in locales"
:key="localeArray.name">
<span slot="label" :class="{'error' : form.errors.has(locale)}">{{ localeArray.name
}}</span>
<el-form-item :label="translate('page', 'title')"
:class="{'el-form-item is-error': form.errors.has(locale + '.title') }">
<el-input v-model="page[locale].title"></el-input>
<div class="el-form-item__error" v-if="form.errors.has(locale + '.title')"
v-text="form.errors.first(locale + '.title')"></div>
</el-form-item>
<el-form-item :label="translate('page', 'slug')"
:class="{'el-form-item is-error': form.errors.has(locale + '.slug') }">
<el-input v-model="page[locale].slug">
<el-button slot="prepend" @click="generateSlug($event, locale)">Generate</el-button>
</el-input>
<div class="el-form-item__error" v-if="form.errors.has(locale + '.slug')"
v-text="form.errors.first(locale + '.slug')"></div>
</el-form-item>
<el-form-item :label="translate('page', 'body')"
:class="{'el-form-item is-error': form.errors.has(locale + '.body') }">
<ckeditor v-model="page[locale].body" :value="page[locale].body">
</ckeditor>
<div class="el-form-item__error" v-if="form.errors.has(locale + '.body')"
v-text="form.errors.first(locale + '.body')"></div>
</el-form-item>
<div class="panel box box-primary">
<div class="box-header">
<h4 class="box-title">
<a class="collapsed" data-toggle="collapse" data-parent="#accordion"
:href="`#collapseMeta-${locale}`">
{{ translate('page', 'meta_data') }}
</a>
</h4>
</div>
<div style="height: 0px;" :id="`collapseMeta-${locale}`"
class="panel-collapse collapse">
<div class="box-body">
<el-form-item :label="translate('page', 'meta_title')">
<el-input v-model="page[locale].meta_title"></el-input>
</el-form-item>
<el-form-item :label="translate('page', 'meta_description')">
<el-input type="textarea"
v-model="page[locale].meta_description"></el-input>
</el-form-item>
</div>
</div>
</div>
<div class="panel box box-primary">
<div class="box-header">
<h4 class="box-title">
<a class="collapsed" data-toggle="collapse" data-parent="#accordion"
:href="`#collapseFacebook-${locale}`">
{{ translate('page', 'facebook_data') }}
</a>
</h4>
</div>
<div style="height: 0px;" :id="`collapseFacebook-${locale}`"
class="panel-collapse collapse">
<div class="box-body">
<el-form-item :label="translate('page', 'og_title')">
<el-input v-model="page[locale].og_title"></el-input>
</el-form-item>
<el-form-item :label="translate('page', 'og_description')">
<el-input type="textarea"
v-model="page[locale].og_description"></el-input>
</el-form-item>
<el-form-item :label="translate('page', 'og_type')">
<el-select v-model="page[locale].og_type"
:placeholder="translate('page', 'og_type')">
<el-option :label="translate('page', 'facebook-types.website')"
value="website"></el-option>
<el-option :label="translate('page', 'facebook-types.product')"
value="product"></el-option>
<el-option :label="translate('page', 'facebook-types.article')"
value="article"></el-option>
</el-select>
</el-form-item>
</div>
</div>
</div>
<el-form-item>
<el-button type="primary" @click="onSubmit()" :loading="loading">
{{ translate('core', 'save') }}
</el-button>
<el-button @click="onCancel()">{{ translate('core', 'button.cancel') }}
</el-button>
</el-form-item>
</el-tab-pane>
</el-tabs>
</div>
</div>
</div>
<div class="col-md-2">
<div class="box box-primary">
<div class="box-body">
<el-form-item label="">
<el-checkbox v-model="page.is_home" :true-label="1" :false-label="0" name="is_home"
:label="translate('page', 'is homepage')"></el-checkbox>
</el-form-item>
<el-form-item :label="translate('page', 'template')"
:class="{'el-form-item is-error': form.errors.has('template') }">
<el-select v-model="page.template" filterable>
<el-option v-for="(template, key) in templates" :key="template"
:label="template" :value="key"></el-option>
</el-select>
<div class="el-form-item__error" v-if="form.errors.has('template')"
v-text="form.errors.first('template')"></div>
</el-form-item>
<tags-input namespace="asgardcms/page" @input="setTags" :current-tags="tags"></tags-input>
</div>
</div>
</div>
</div>
</el-form>
</div>
</template>
<script>
import axios from 'axios'
import Translate from '../../../../Core/Assets/js/mixins/Translate'
import Slugify from '../../../../Core/Assets/js/mixins/Slugify'
import Form from 'form-backend-validation'
export default {
mixins: [Translate, Slugify],
props: {
locales: {default: null},
pageTitle: {default: null, String},
},
data() {
return {
page: _(this.locales)
.keys()
.map(locale => [locale, {
title: '',
slug: '',
body: '',
meta_title: '',
meta_description: '',
og_title: '',
og_description: '',
og_type: '',
}])
.fromPairs()
.merge({template: 'default', is_home: 0})
.value(),
templates: {
'index': 'index',
'home': 'home',
'default': 'default',
},
form: new Form(),
loading: false,
tags: {},
}
},
methods: {
onSubmit() {
this.form = new Form(_.merge(this.page, {tags: this.tags}));
this.loading = true;
this.form.post(this.getRoute())
.then(response => {
this.loading = false;
this.$message({
type: 'success',
message: response.message
});
this.$router.push({name: 'admin.page.page.index'});
})
.catch(error => {
console.log(error);
this.loading = false;
this.$notify.error({
title: 'Error',
message: 'There are some errors in the form.'
});
});
},
onCancel() {
this.$router.push({name: 'admin.page.page.index'});
},
fetchTemplates() {
axios.get(route('api.page.page-templates.index'))
.then(response => {
this.templates = response.data;
});
},
generateSlug(event, locale) {
this.page[locale].slug = this.slugify(this.page[locale].title);
},
setTags(tags) {
this.tags = tags;
},
fetchPage() {
this.loading = true;
axios.post(route('api.page.page.find', {page: this.$route.params.pageId}))
.then(response => {
this.loading = false;
this.page = response.data.data;
this.tags = response.data.data.tags;
})
.catch(error => {
})
},
getRoute() {
if (this.$route.params.pageId !== undefined) {
return route('api.page.page.update', {page: this.$route.params.pageId});
}
return route('api.page.page.store');
},
},
mounted() {
this.fetchTemplates();
if (this.$route.params.pageId !== undefined) {
this.fetchPage();
}
}
}
</script>
<template>
<div class="row">
<div class="col-xs-12">
<div class="box box-primary">
<div class="box-body">
<data-tables :data="data" :actions-def="actionsDef">
<el-table-column prop="id" label="Id" width="100">
</el-table-column>
<el-table-column prop="title" :label="translate('page', 'title')">
</el-table-column>
<el-table-column prop="slug" label="Slug">
</el-table-column>
<el-table-column prop="created_at" label="Created at">
</el-table-column>
<el-table-column fixed="right" prop="actions" label="Actions">
<template scope="scope">
<a class="btn btn-default btn-flat" @click.prevent="goToEdit(scope)"><i
class="fa fa-pencil"></i></a>
<delete-button :scope="scope" :rows="data" :translations="translations">
</delete-button>
</template>
</el-table-column>
</data-tables>
</div>
</div>
</div>
</div>
</template>
<script>
import axios from 'axios'
import Translate from '../../../../Core/Assets/js/mixins/Translate'
let data;
export default {
mixins: [Translate],
data() {
return {
data,
meta: {},
order_meta: {},
links: {},
actionsDef: {
def: [{
name: this.translate('page', 'create page'),
icon: 'edit',
handler: () => {
this.$router.push({name: 'admin.page.page.create'})
}
}]
}
}
},
methods: {
fetchData() {
axios.get(route('api.page.page.index'))
.then(response => {
this.data = response.data.data;
this.meta = response.data.meta;
this.links = response.data.links;
});
},
goToEdit(scope) {
this.$router.push({name: 'admin.page.page.edit', params: {pageId: scope.row.id}})
},
},
mounted() {
this.fetchData();
}
}
</script>
<template>
<div class="div">
<div class="content-header">
<h1>
{{ translate('page', 'pages') }}
</h1>
<el-breadcrumb separator="/">
<el-breadcrumb-item>
<a href="/backend">Home</a>
</el-breadcrumb-item>
<el-breadcrumb-item :to="{name: 'admin.page.page.index'}">{{ translate('page', 'pages') }}</el-breadcrumb-item>
</el-breadcrumb>
</div>
<div class="row">
<div class="col-xs-12">
<div class="box box-primary">
<div class="box-body">
<div class="sc-table">
<div class="tool-bar el-row" style="padding-bottom: 20px;">
<div class="actions el-col el-col-5">
<router-link :to="{name: 'admin.page.page.create'}">
<el-button type="primary"><i class="el-icon-edit"></i>
{{ translate('page', 'create page') }}
</el-button>
</router-link>
</div>
<div class="search el-col el-col-5">
<el-input icon="search" @change="performSearch" v-model="searchQuery">
</el-input>
</div>
</div>
<el-table
:data="data"
stripe
style="width: 100%"
v-loading.body="tableIsLoading"
@sort-change="handleSortChange">
<el-table-column prop="id" label="Id" width="100" sortable="custom">
</el-table-column>
<el-table-column prop="translations.title" :label="translate('page', 'title')">
</el-table-column>
<el-table-column prop="translations.slug" label="Slug">
</el-table-column>
<el-table-column prop="created_at" label="Created at" sortable="custom">
</el-table-column>
<el-table-column fixed="right" prop="actions" label="Actions">
<template scope="scope">
<a class="btn btn-default btn-flat" @click.prevent="goToEdit(scope)"><i
class="fa fa-pencil"></i></a>
<delete-button :scope="scope" :rows="data" :translations="translations">
</delete-button>
</template>
</el-table-column>
</el-table>
<div class="pagination-wrap" style="text-align: center; padding-top: 20px;">
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page.sync="meta.current_page"
:page-sizes="[10, 20, 50, 100]"
:page-size="parseInt(meta.per_page)"
layout="total, sizes, prev, pager, next, jumper"
:total="meta.total">
</el-pagination>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import axios from 'axios'
import Translate from '../../../../Core/Assets/js/mixins/Translate'
import _ from "lodash";
let data;
export default {
mixins: [Translate],
data() {
return {
data,
meta: {},
order_meta: {},
links: {},
searchQuery: '',
tableIsLoading: false,
}
},
methods: {
fetchData() {
this.tableIsLoading = true;
axios.get(route('api.page.page.indexServerSide'))
.then(response => {
this.tableIsLoading = false;
this.data = response.data.data;
this.meta = response.data.meta;
this.links = response.data.links;
});
},
goToEdit(scope) {
this.$router.push({name: 'admin.page.page.edit', params: {pageId: scope.row.id}})
},
handleSizeChange(event) {
console.log('per page :' + event);
this.tableIsLoading = true;
axios.get(route('api.page.page.indexServerSide', {
per_page: event,
page: this.meta.current_page,
order_by: this.order_meta.order_by,
order: this.order_meta.order,
}))
.then(response => {
this.tableIsLoading = false;
this.data = response.data.data;
this.meta = response.data.meta;
this.links = response.data.links;
});
},
handleCurrentChange(event) {
console.log('current page :' + event);
this.tableIsLoading = true;
axios.get(route('api.page.page.indexServerSide', {
page: event,
per_page: this.meta.per_page,
order_by: this.order_meta.order_by,
order: this.order_meta.order,
search: this.searchQuery,
}))
.then(response => {
this.tableIsLoading = false;
this.data = response.data.data;
this.meta = response.data.meta;
this.links = response.data.links;
});
},
handleSortChange(event) {
console.log('sorting', event);
this.tableIsLoading = true;
axios.get(route('api.page.page.indexServerSide', {
page: this.meta.current_page,
per_page: this.meta.per_page,
order_by: event.prop,
order: event.order,
search: this.searchQuery,
}))
.then(response => {
this.tableIsLoading = false;
this.data = response.data.data;
this.meta = response.data.meta;
this.links = response.data.links;
this.order_meta.order_by = event.prop;
this.order_meta.order = event.order;
});
},
performSearch(query) {
console.log('searching:' + query);
this.tableIsLoading = true;
axios.get(route('api.page.page.indexServerSide', {
search: query,
}))
.then(response => {
this.tableIsLoading = false;
this.data = response.data.data;
this.meta = response.data.meta;
this.links = response.data.links;
});
},
},
mounted() {
this.fetchData();
}
}
</script>
<template>
<el-form-item label="Tags">
<el-select v-model="tags" multiple filterable allow-create remote @change="triggerEvent">
<el-option v-for="tag in availableTags"
:key="tag.slug"
:label="tag.slug"
:value="tag.name">
</el-option>
</el-select>
</el-form-item>
</template>
<script>
import axios from 'axios'
export default {
props: {
namespace: {String},
currentTags: {default : null},
},
data() {
return {
tags: {},
availableTags: {},
}
},
methods: {
triggerEvent() {
this.$emit('input', this.tags);
}
},
watch: {
currentTags: function () {
if (this.currentTags !== null) {
this.tags = this.currentTags;
}
}
},
mounted() {
axios.get(route('api.tag.tag.by-namespace', {namespace: this.namespace}))
.then(response => {
this.availableTags = response.data;
});
}
}
</script>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment