Refactor on LiveEditor

pull/1055/head
mertsincan 2021-03-17 14:29:01 +03:00
parent da1cb32e63
commit 025214889f
8 changed files with 224 additions and 509 deletions

View File

@ -2,9 +2,12 @@ import Prism from 'prismjs';
const CodeHighlight = {
beforeMount(el, binding) {
if (binding.modifiers.script)
const modifiers = binding.modifiers;
const value = binding.value;
if (modifiers.script || value === 'script')
el.className = 'language-javascript';
else if (binding.modifiers.css)
else if (modifiers.css || value === 'css')
el.className = 'language-css';
else
el.className = 'language-markup';

88
src/AppDocumentation.vue Normal file
View File

@ -0,0 +1,88 @@
<script>
import LiveEditor from './views/liveeditor/LiveEditor';
import { services, data } from './views/liveeditor/LiveEditorData';
export default {
name: 'appdoc',
props: {
name: null,
sources: null,
service: null,
data: null,
dependencies: null,
extPages: null
},
methods: {
renderPanels() {
let tabs = [];
if (this.$slots.default) {
tabs.push(<TabPanel header="Documentation">{this.$slots.default()}</TabPanel>);
}
if (this.sources) {
const sourceType = this.$appState.sourceType; //options-api or composition-api
/* eslint-disable */
tabs.push(
<TabPanel header={this.sources[sourceType].tabName}>
<LiveEditor name={this.name} sources={this.sources} service={this.service} data={this.data} dependencies={this.dependencies} extPages={this.extPages}/>
<pre v-code><code>
{this.sources[sourceType].content.replace('<\\/script>', '<\/script>')}
</code></pre>
</TabPanel>
);
}
if (this.extPages) {
/* eslint-disable */
this.extPages.forEach(file => {
tabs.push(
<TabPanel key={file.tabName} header={file.tabName}>
<pre v-code><code>
{file.content.replace('<\\/script>', '<\/script>')}
</code></pre>
</TabPanel>
);
});
}
if (this.service) {
/* eslint-disable */
tabs.push(
<TabPanel key="service" header={`${this.service}.js`}>
<pre v-code="script"><code>
{services[this.service]}
</code></pre>
</TabPanel>
);
}
if (this.data) {
const dataArr = this.data.split(',');
dataArr.forEach((el, i) => {
tabs.push(
<TabPanel key={`${el}_i`} header={`${el}.json`}>
<pre v-code="script" style={{maxHeight: '500px'}}><code>
{data[el]}
</code></pre>
</TabPanel>
)
});
}
return tabs;
}
},
render() {
return (
<div class="content-section documentation">
<TabView>
{
this.renderPanels()
}
</TabView>
</div>
);
}
}
</script>

View File

@ -95,6 +95,7 @@ import TriStateCheckbox from './components/tristatecheckbox/TriStateCheckbox';
import Galleria from './components/galleria/Galleria';
import AppInputStyleSwitch from './AppInputStyleSwitch';
import AppDocumentation from './AppDocumentation';
import CodeHighlight from './AppCodeHighlight';
import './assets/styles/primevue.css';
@ -110,7 +111,7 @@ router.beforeEach(function (to, from, next) {
const app = createApp(App);
app.config.globalProperties.$appState = reactive({inputStyle: 'outlined', darkTheme: false, codeSandbox: true});
app.config.globalProperties.$appState = reactive({inputStyle: 'outlined', darkTheme: false, codeSandbox: true, sourceType: 'options-api'});
app.use(PrimeVue, {ripple: true});
app.use(ToastService);
@ -208,6 +209,7 @@ app.component('TriStateCheckbox', TriStateCheckbox);
app.component('Galleria', Galleria);
app.component('AppInputStyleSwitch', AppInputStyleSwitch);
app.component('AppDoc', AppDocumentation);
app.directive('code', CodeHighlight);
app.mount('#app');

View File

@ -18,72 +18,14 @@
</div>
</div>
<div class="content-section documentation">
<TabView>
<TabPanel header="Source">
<div class="p-d-flex p-jc-end">
<LiveEditor name="DataTableDemo" :sources="sources" service="ProductService" data="products-small" :components="['Column']" />
</div>
<pre v-code><code><template v-pre>
&lt;DataTable :value="products"&gt;
&lt;Column field="code" header="Code"&gt;&lt;/Column&gt;
&lt;Column field="name" header="Name"&gt;&lt;/Column&gt;
&lt;Column field="category" header="Category"&gt;&lt;/Column&gt;
&lt;Column field="quantity" header="Quantity"&gt;&lt;/Column&gt;
&lt;/DataTable&gt;
</template>
</code></pre>
<pre v-code.script><code>
import ProductService from '../../service/ProductService';
export default {
data() {
return {
products: null
}
},
productService: null,
created() {
this.productService = new ProductService();
},
mounted() {
this.productService.getProductsSmall().then(data => this.products = data);
}
}
</code></pre>
</TabPanel>
</TabView>
</div>
<DataTableBasicDoc />
</div>
</template>
<script>
import ProductService from '../../service/ProductService';
import LiveEditor from '../liveeditor/LiveEditor';
export default {
data() {
return {
products: null,
sources: {
'template': {
content: `<template>
<div class="layout-content">
<div class="content-section implementation">
<div class="card">
<DataTable :value="products">
<Column field="code" header="Code"></Column>
<Column field="name" header="Name"></Column>
<Column field="category" header="Category"></Column>
<Column field="quantity" header="Quantity"></Column>
</DataTable>
</div>
</div>
</div>
</template>
<script>
import ProductService from '../service/ProductService';
import DataTableBasicDoc from './DataTableBasicDoc';
export default {
data() {
return {
@ -94,23 +36,11 @@ export default {
created() {
this.productService = new ProductService();
},
mounted() {
this.productService.getProductsSmall().then(data => this.products = data);
}
}`
}
}
}
},
productService: null,
created() {
this.productService = new ProductService();
},
mounted() {
this.productService.getProductsSmall().then(data => this.products = data);
},
components: {
LiveEditor
DataTableBasicDoc
}
}
</script>

View File

@ -0,0 +1,50 @@
<template>
<AppDoc :sources="sources" service="ProductService" data="products-small" />
</template>
<script>
export default {
data() {
return {
sources: {
'options-api': {
tabName: 'Source',
content: `
<template>
<div>
<div class="card">
<DataTable :value="products">
<Column field="code" header="Code"></Column>
<Column field="name" header="Name"></Column>
<Column field="category" header="Category"></Column>
<Column field="quantity" header="Quantity"></Column>
</DataTable>
</div>
</div>
</template>
<script>
import ProductService from '../../service/ProductService';
export default {
data() {
return {
products: null
}
},
productService: null,
created() {
this.productService = new ProductService();
},
mounted() {
this.productService.getProductsSmall().then(data => this.products = data);
}
}
<\\/script>
`
}
}
}
}
}
</script>

View File

@ -1,7 +1,7 @@
<template>
<span v-if="showEditor">
<template v-if="!editComposition">
<Button @click="postSandboxParameters('core')" label="Edit in CodeSandbox" class="liveEditorButton" />
<Button @click="postSandboxParameters('core')" label="Edit in CodeSandbox" class="liveEditorButton" />
</template>
<template v-else>
<SplitButton :model="items" label="Edit in CodeSandbox" class="liveEditorSplitButton" />
@ -147,10 +147,11 @@ export default {
},
getSandboxParameters(sourceType) {
/* eslint-disable */
let name = this.name;
let extension = '.vue';
let extDependencies = this.dependencies || {};
let content = this.sources.template.content;
let content = this.sources.template.content.replace('<\\/script>', '<\/script>');
let style = this.sources.template.style || '';
let api = this.sources.api ? this.sources.api.content : '';
let apiStyle = this.sources.api && this.sources.api.style ? this.sources.api.style : '';
@ -160,10 +161,7 @@ export default {
if(sourceType === 'core') {
_files[`src/components/${name}${extension}`] = {
content: `${content}
</${scriptText}>
${style}`
content: `${content}`
}
}
@ -585,11 +583,10 @@ img.flag {
if(pages) {
extDependencies['vue-router'] = "^4.0.0-0";
const routes = [];
/* eslint-disable */
pages.forEach((page, i) => {
_files[`src/components/${page.name}.vue`] = {
'content': `${page.template}
</${scriptText}>`
'content': `${page.template.replace('<\\/script>', '<\/script>')}`
}
let route = '';

View File

@ -1,8 +1,6 @@
<template>
<div class="content-section documentation">
<TabView>
<TabPanel header="Documentation">
<h5>Import</h5>
<AppDoc :sources="sources" :extPages="pages">
<h5>Import</h5>
<pre v-code.script><code>
import Steps from 'primevue/steps';
@ -121,29 +119,33 @@ export default {
<h5>Dependencies</h5>
<p>None.</p>
</TabPanel>
<TabPanel header="Source">
<div class="p-d-flex p-jc-between">
<a href="https://github.com/primefaces/primevue/tree/master/src/views/tabmenu" class="btn-viewsource" target="_blank" rel="noopener noreferrer">
<span>View on GitHub</span>
</a>
<LiveEditor name="StepsDemo" :sources="sources" :toastService="true" :router="true" :components="['Card', 'InputText', 'InputNumber', 'Button', 'Dropdown', 'InputMask', 'Checkbox']" />
</div>
<pre v-code><code><template v-pre>
&lt;div class="card"&gt;
&lt;Steps :model="items" :readonly="true" /&gt;
&lt;/div&gt;
&lt;router-view v-slot="{Component}" :formData="formObject" @prev-page="prevPage($event)" @next-page="nextPage($event)" @complete="complete"&gt;
&lt;keep-alive&gt;
&lt;component :is="Component" /&gt;
&lt;/keep-alive&gt;
&lt;/router-view&gt;
</AppDoc>
</template>
</code></pre>
<pre v-code.script><code>
<script>
export default {
data() {
return {
sources: {
'options-api': {
tabName: 'Source',
content: `
<template>
<div>
<div class="card">
<Steps :model="items" :readonly="true" />
</div>
<router-view v-slot="{Component}" :formData="formObject" @prev-page="prevPage($event)" @next-page="nextPage($event)" @complete="complete">
<keep-alive>
<component :is="Component" />
</keep-alive>
</router-view>
</div>
</template>
<script>
export default {
data() {
return {
@ -166,9 +168,6 @@ export default {
formObject: {}
}
},
components: {
'StepsDoc': StepsDoc
},
methods: {
nextPage(event) {
for (let field in event.formData) {
@ -185,382 +184,25 @@ export default {
}
}
}
<\\/script>
</code></pre>
</TabPanel>
<TabPanel header="Personal">
<pre v-code><code><template v-pre>
&lt;div class="stepsdemo-content"&gt;
&lt;Card&gt;
&lt;template v-slot:title&gt;
Personal Information
&lt;/template&gt;
&lt;template v-slot:subtitle&gt;
Enter your personal information
&lt;/template&gt;
&lt;template v-slot:content&gt;
&lt;div class="p-fluid"&gt;
&lt;div class="p-field"&gt;
&lt;label for="firstname"&gt;Firstname&lt;/label&gt;
&lt;InputText id="firstname" v-model="firstname" :class="{'p-invalid': validationErrors.firstname && submitted}" /&gt;
&lt;small v-show="validationErrors.firstname && submitted" class="p-error"&gt;Firstname is required.&lt;/small&gt;
&lt;/div&gt;
&lt;div class="p-field"&gt;
&lt;label for="lastname"&gt;Lastname&lt;/label&gt;
&lt;InputText id="lastname" v-model="lastname" :class="{'p-invalid': validationErrors.lastname && submitted}" /&gt;
&lt;small v-show="validationErrors.lastname && submitted" class="p-error"&gt;Lastname is required.&lt;/small&gt;
&lt;/div&gt;
&lt;div class="p-field"&gt;
&lt;label for="age"&gt;Age&lt;/label&gt;
&lt;InputNumber id="age" v-model="age" /&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/template&gt;
&lt;template v-slot:footer&gt;
&lt;div class="p-grid p-nogutter p-justify-between"&gt;
&lt;i&gt;&lt;/i&gt;
&lt;Button label="Next" @click="nextPage()" icon="pi pi-angle-right" iconPos="right" /&gt;
&lt;/div&gt;
&lt;/template&gt;
&lt;/Card&gt;
&lt;/div&gt;
</template>
</code></pre>
<pre v-code.script><code>
export default {
data () {
return {
firstname: '',
lastname: '',
age: null,
submitted: false,
validationErrors: {}
}
},
methods: {
nextPage() {
this.submitted = true;
if (this.validateForm() ) {
this.$emit('next-page', {formData: {firstname: this.firstname, lastname: this.lastname, age: this.age}, pageIndex: 0});
}
},
validateForm() {
if (!this.firstname.trim())
this.validationErrors['firstname'] = true;
else
delete this.validationErrors['firstname'];
if (!this.lastname.trim())
this.validationErrors['lastname'] = true;
else
delete this.validationErrors['lastname'];
return !Object.keys(this.validationErrors).length;
}
}
<style scoped lang="scss">
::v-deep(b) {
display: block;
}
</code></pre>
</TabPanel>
<TabPanel header="Seat">
<pre v-code><code><template v-pre>
&lt;div class="stepsdemo-content"&gt;
&lt;Card&gt;
&lt;template #title&gt;
Seat Information
&lt;/template&gt;
&lt;template #subtitle&gt;
Choose your seat
&lt;/template&gt;
&lt;template #content&gt;
&lt;div class="p-fluid p-formgrid p-grid"&gt;
&lt;div class="p-field p-col-12 p-md-6"&gt;
&lt;label for="class"&gt;Class&lt;/label&gt;
&lt;Dropdown inputId="class" v-model="selectedClass" :options="classes" @change="setVagons($event)" optionLabel="name" placeholder="Select a Class" /&gt;
&lt;/div&gt;
&lt;div class="p-field p-col-12 p-md-6"&gt;
&lt;label for="lastname"&gt;Wagon&lt;/label&gt;
&lt;Dropdown inputId="wagon" v-model="selectedVagon" :options="vagons" @change="setSeats($event)" optionLabel="vagon" placeholder="Select a Vagon" /&gt;
&lt;/div&gt;
&lt;div class="p-field p-col-12"&gt;
&lt;label for="seat"&gt;Seat&lt;/label&gt;
&lt;Dropdown inputId="seat" v-model="selectedSeat" :options="seats" optionLabel="seat" placeholder="Select a Seat" /&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/template&gt;
&lt;template #footer&gt;
&lt;div class="p-grid p-nogutter p-justify-between"&gt;
&lt;Button label="Back" @click="prevPage()" icon="pi pi-angle-left" /&gt;
&lt;Button label="Next" @click="nextPage()" icon="pi pi-angle-right" iconPos="right" /&gt;
&lt;/div&gt;
&lt;/template&gt;
&lt;/Card&gt;
&lt;/div&gt;
</template>
</code></pre>
<pre v-code.script><code>
export default {
data () {
return {
selectedClass: '',
classes: [
{name: 'First Class', code: 'A', factor: 1},
{name: 'Second Class', code: 'B', factor: 2},
{name: 'Third Class', code: 'C', factor: 3}
],
vagons: [],
selectedVagon: '',
seats: [],
selectedSeat: ''
}
},
methods: {
setVagons(event) {
if (this.selectedClass && event.value) {
this.vagons = [];
this.seats = [];
for (let i = 1; i &lt; 3 * event.value.factor; i++) {
this.vagons.push({vagon: i + event.value.code, type: event.value.name, factor: event.value.factor});
::v-deep(.p-card-body) {
padding: 2rem;
}
</style>
`
}
}
},
setSeats(event) {
if (this.selectedVagon && event.value) {
this.seats = [];
for (let i = 1; i &lt; 10 * event.value.factor; i++) {
this.seats.push({seat: i, type: event.value.type});
}
}
},
nextPage() {
this.$emit('next-page', {formData: {class: this.selectedClass.name, vagon: this.selectedVagon.vagon, seat: this.selectedSeat.seat}, pageIndex: 1});
},
prevPage() {
this.$emit('prev-page', {pageIndex: 1});
}
}
}
</code></pre>
</TabPanel>
<TabPanel header="Payment">
<pre v-code><code><template v-pre>
&lt;div class="stepsdemo-content"&gt;
&lt;Card&gt;
&lt;template #title&gt;
Payment Information
&lt;/template&gt;
&lt;template #subtitle&gt;
Enter your card details
&lt;/template&gt;
&lt;template #content&gt;
&lt;div class="p-fluid p-formgrid p-grid"&gt;
&lt;div class="p-field p-col-12"&gt;
&lt;label for="class"&gt;Class&lt;/label&gt;
&lt;InputText type="text" v-model="cardholderName" /&gt;
&lt;/div&gt;
&lt;div class="p-field p-col-8"&gt;
&lt;label id="number" for="lastname"&gt;Number&lt;/label&gt;
&lt;InputMask id="number" mask="9999-9999-9999-9999" v-model="cardholderNumber" /&gt;
&lt;/div&gt;
&lt;div class="p-field p-col-2"&gt;
&lt;label id="date" for="date"&gt;Date&lt;/label&gt;
&lt;InputMask id="date" mask="99/99" v-model="date" /&gt;
&lt;/div&gt;
&lt;div class="p-field p-col-2"&gt;
&lt;label for="cvv"&gt;CVV&lt;/label&gt;
&lt;InputMask id="cvv" mask="999" v-model="cvv" /&gt;
&lt;/div&gt;
&lt;div class="p-field-checkbox p-col-12"&gt;
&lt;Checkbox id="remember" v-model="remember" :binary="true" /&gt;
&lt;label for="remember" class="p-checkbox-label"&gt;Save credit card information for future&lt;/label&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/template&gt;
&lt;template #footer&gt;
&lt;div class="p-grid p-nogutter p-justify-between"&gt;
&lt;Button label="Back" @click="prevPage()" icon="pi pi-angle-left" /&gt;
&lt;Button label="Next" @click="nextPage()" icon="pi pi-angle-right" iconPos="right" /&gt;
&lt;/div&gt;
&lt;/template&gt;
&lt;/Card&gt;
&lt;/div&gt;
</template>
</code></pre>
<pre v-code.script><code>
export default {
data () {
return {
cardholderName:'',
cardholderNumber:'',
date:'',
cvv:'',
remember:false
}
},
methods: {
nextPage() {
this.$emit('next-page', {formData: {cardholderName: this.cardholderName, cardholderNumber: this.cardholderNumber, date: this.date, cvv: this.cvv}, pageIndex: 2});
},
prevPage() {
this.$emit('prev-page', {pageIndex: 2});
}
}
}
</code></pre>
</TabPanel>
<TabPanel header="Confirmation">
<pre v-code><code><template v-pre>
&lt;div class="stepsdemo-content"&gt;
&lt;Card&gt;
&lt;template #title&gt;
Confirmation
&lt;/template&gt;
&lt;template #content&gt;
&lt;div class="p-field p-col-12"&gt;
&lt;label for="class"&gt;Name&lt;/label&gt;
&lt;b&gt;{{formData.firstname ? formData.firstname : '-'}} {{formData.lastname ? formData.lastname : '-'}}&lt;/b&gt;
&lt;/div&gt;
&lt;div class="p-field p-col-12"&gt;
&lt;label for="Age"&gt;Age&lt;/label&gt;
&lt;b&gt;{{formData.age ? formData.age : '-'}}&lt;/b&gt;
&lt;/div&gt;
&lt;div class="p-field p-col-12"&gt;
&lt;label for="Age"&gt;Seat Class&lt;/label&gt;
&lt;b&gt;{{formData.class ? formData.class : '-'}}&lt;/b&gt;
&lt;/div&gt;
&lt;div class="p-field p-col-12"&gt;
&lt;label for="Age"&gt;Wagon Number&lt;/label&gt;
&lt;b&gt;{{formData.vagon ? formData.vagon : '-'}}&lt;/b&gt;
&lt;/div&gt;
&lt;div class="p-field p-col-12"&gt;
&lt;label for="Age"&gt;Seat&lt;/label&gt;
&lt;b&gt;{{formData.seat ? formData.seat : '-'}}&lt;/b&gt;
&lt;/div&gt;
&lt;div class="p-field p-col-12"&gt;
&lt;label for="Age"&gt;Cardholder Name&lt;/label&gt;
&lt;b&gt;{{formData.cardholderName ? formData.cardholderName : '-'}}&lt;/b&gt;
&lt;/div&gt;
&lt;div class="p-field p-col-12"&gt;
&lt;label for="Age"&gt;Card Number&lt;/label&gt;
&lt;b&gt;{{formData.cardholderNumber ? formData.cardholderNumber : '-'}}&lt;/b&gt;
&lt;/div&gt;
&lt;div class="p-field p-col-12"&gt;
&lt;label for="Age"&gt;Date&lt;/label&gt;
&lt;b&gt;{{formData.date ? formData.date : '-'}}&lt;/b&gt;
&lt;/div&gt;
&lt;div class="p-field p-col-12"&gt;
&lt;label for="Age"&gt;CVV&lt;/label&gt;
&lt;b&gt;{{formData.cvv && formData.cvv.length === 3 ? '**' + formData.cvv[2] : '-'}}&lt;/b&gt;
&lt;/div&gt;
&lt;/template&gt;
&lt;template #footer&gt;
&lt;div class="p-grid p-nogutter p-justify-between"&gt;
&lt;Button label="Back" @click="prevPage()" icon="pi pi-angle-left" /&gt;
&lt;Button label="Complete" @click="complete()" icon="pi pi-check" iconPos="right" class="p-button-success"/&gt;
&lt;/div&gt;
&lt;/template&gt;
&lt;/Card&gt;
&lt;/div&gt;
</template>
</code></pre>
<pre v-code.script><code>
export default {
props: {
formData: Object
},
methods: {
prevPage() {
this.$emit('prev-page', {pageIndex: 3});
},
complete() {
this.$emit('complete');
}
}
}
</code></pre>
</TabPanel>
</TabView>
</div>
</template>
<script>
import LiveEditor from '../liveeditor/LiveEditor';
export default {
data() {
return {
sources: {
'template': {
content: `<template>
<div class="layout-content">
<Toast />
<div class="content-section implementation">
<div class="card">
<Steps :model="items" :readonly="true" />
</div>
<router-view v-slot="{Component}" :formData="formObject" @prevPage="prevPage($event)" @nextPage="nextPage($event)" @complete="complete">
<keep-alive>
<component :is="Component" />
</keep-alive>
</router-view>
</div>
</div>
</template>
<script>
export default {
data() {
return {
items: [{
label: 'Personal',
to: "/"
},
{
label: 'Seat',
to: "/seat",
},
{
label: 'Payment',
to: "/payment",
},
{
label: 'Confirmation',
to: "/confirmation",
}],
formObject: {}
}
},
methods: {
nextPage(event) {
for (let field in event.formData) {
this.formObject[field] = event.formData[field];
}
this.$router.push(this.items[event.pageIndex + 1].to);
},
prevPage(event) {
this.$router.push(this.items[event.pageIndex - 1].to);
},
complete() {
this.$toast.add({severity:'success', summary:'Order submitted', detail: 'Dear, ' + this.formObject.firstname + ' ' + this.formObject.lastname + ' your order completed.'});
}
}
}`
},
'pages': [
pages: [
{
'name': 'PersonalDemo',
'template': `<template>
tabName: 'PersonalDemo',
content: `
<template>
<div class="stepsdemo-content">
<Card>
<template v-slot:title>
@ -630,11 +272,13 @@ export default {
}
}
}
<\\/script>
`
},
{
'name': 'SeatDemo',
'template': `<template>
tabName: 'SeatDemo',
content: `
<template>
<div class="stepsdemo-content">
<Card>
<template v-slot:title>
@ -711,11 +355,13 @@ export default {
}
}
}
<\\/script>
`
},
{
'name': 'PaymentDemo',
'template': `<template>
tabName: 'PaymentDemo',
content: `
<template>
<div class="stepsdemo-content">
<Card>
<template v-slot:title>
@ -778,11 +424,13 @@ export default {
}
}
}
<\\/script>
`
},
{
'name': 'ConfirmationDemo',
'template': `<template>
tabName: 'ConfirmationDemo',
content: `
<template>
<div class="stepsdemo-content">
<Card>
<template v-slot:title>
@ -850,14 +498,11 @@ export default {
}
}
}
<\\/script>
`
}
]
}
}
]
}
},
components: {
LiveEditor
}
}
</script>