pages関連
This commit is contained in:
@@ -45,36 +45,10 @@
|
||||
</div>
|
||||
|
||||
<div v-else-if="tab === 'contents'">
|
||||
<div>
|
||||
<XBlocks v-model="content" class="content" :hpml="hpml"/>
|
||||
<div :class="$style.contents">
|
||||
<XBlocks v-model="content" class="content"/>
|
||||
|
||||
<MkButton v-if="!readonly" @click="add()"><i class="ti ti-plus"></i></MkButton>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-else-if="tab === 'variables'">
|
||||
<div class="qmuvgica">
|
||||
<Sortable v-show="variables.length > 0" v-model="variables" tag="div" class="variables" item-key="name" handle=".drag-handle" :group="{ name: 'variables' }" animation="150" swap-threshold="0.5">
|
||||
<template #item="{element}">
|
||||
<XVariable
|
||||
:model-value="element"
|
||||
:removable="true"
|
||||
:hpml="hpml"
|
||||
:name="element.name"
|
||||
:title="element.name"
|
||||
:draggable="true"
|
||||
@remove="() => removeVariable(element)"
|
||||
/>
|
||||
</template>
|
||||
</Sortable>
|
||||
|
||||
<MkButton v-if="!readonly" class="add" @click="addVariable()"><i class="ti ti-plus"></i></MkButton>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-else-if="tab === 'script'">
|
||||
<div>
|
||||
<MkTextarea v-model="script" class="_code"/>
|
||||
<MkButton v-if="!readonly" rounded class="add" @click="add()"><i class="ti ti-plus"></i></MkButton>
|
||||
</div>
|
||||
</div>
|
||||
</MkSpacer>
|
||||
@@ -83,31 +57,20 @@
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { defineAsyncComponent, computed, provide, watch } from 'vue';
|
||||
import 'prismjs';
|
||||
import { highlight, languages } from 'prismjs/components/prism-core';
|
||||
import 'prismjs/components/prism-clike';
|
||||
import 'prismjs/components/prism-javascript';
|
||||
import 'prismjs/themes/prism-okaidia.css';
|
||||
import 'vue-prism-editor/dist/prismeditor.min.css';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
import XVariable from './page-editor.script-block.vue';
|
||||
import XBlocks from './page-editor.blocks.vue';
|
||||
import MkTextarea from '@/components/form/textarea.vue';
|
||||
import MkButton from '@/components/MkButton.vue';
|
||||
import MkSelect from '@/components/form/select.vue';
|
||||
import MkSwitch from '@/components/form/switch.vue';
|
||||
import MkInput from '@/components/form/input.vue';
|
||||
import { blockDefs } from '@/scripts/hpml/index';
|
||||
import { HpmlTypeChecker } from '@/scripts/hpml/type-checker';
|
||||
import { url } from '@/config';
|
||||
import { collectPageVars } from '@/scripts/collect-page-vars';
|
||||
import * as os from '@/os';
|
||||
import { selectFile } from '@/scripts/select-file';
|
||||
import { mainRouter } from '@/router';
|
||||
import { i18n } from '@/i18n';
|
||||
import { definePageMetadata } from '@/scripts/page-metadata';
|
||||
import { $i } from '@/account';
|
||||
const Sortable = defineAsyncComponent(() => import('vuedraggable').then(x => x.default));
|
||||
|
||||
const props = defineProps<{
|
||||
initPageId?: string;
|
||||
@@ -130,12 +93,8 @@ let font = $ref('sans-serif');
|
||||
let content = $ref([]);
|
||||
let alignCenter = $ref(false);
|
||||
let hideTitleWhenPinned = $ref(false);
|
||||
let variables = $ref([]);
|
||||
let hpml = $ref(null);
|
||||
let script = $ref('');
|
||||
|
||||
provide('readonly', readonly);
|
||||
provide('getScriptBlockList', getScriptBlockList);
|
||||
provide('getPageBlockList', getPageBlockList);
|
||||
|
||||
watch($$(eyeCatchingImageId), async () => {
|
||||
@@ -154,11 +113,11 @@ function getSaveOptions() {
|
||||
name: name.trim(),
|
||||
summary: summary,
|
||||
font: font,
|
||||
script: script,
|
||||
script: '',
|
||||
hideTitleWhenPinned: hideTitleWhenPinned,
|
||||
alignCenter: alignCenter,
|
||||
content: content,
|
||||
variables: variables,
|
||||
variables: [],
|
||||
eyeCatchingImageId: eyeCatchingImageId,
|
||||
};
|
||||
}
|
||||
@@ -243,7 +202,7 @@ async function add() {
|
||||
const { canceled, result: type } = await os.select({
|
||||
type: null,
|
||||
title: i18n.ts._pages.chooseBlock,
|
||||
groupedItems: getPageBlockList(),
|
||||
items: getPageBlockList(),
|
||||
});
|
||||
if (canceled) return;
|
||||
|
||||
@@ -251,97 +210,13 @@ async function add() {
|
||||
content.push({ id, type });
|
||||
}
|
||||
|
||||
async function addVariable() {
|
||||
let { canceled, result: name } = await os.inputText({
|
||||
title: i18n.ts._pages.enterVariableName,
|
||||
});
|
||||
if (canceled) return;
|
||||
|
||||
name = name.trim();
|
||||
|
||||
if (hpml.isUsedName(name)) {
|
||||
os.alert({
|
||||
type: 'error',
|
||||
text: i18n.ts._pages.variableNameIsAlreadyUsed,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const id = uuid();
|
||||
variables.push({ id, name, type: null });
|
||||
}
|
||||
|
||||
function removeVariable(v) {
|
||||
variables = variables.filter(x => x.name !== v.name);
|
||||
}
|
||||
|
||||
function getPageBlockList() {
|
||||
return [{
|
||||
label: i18n.ts._pages.contentBlocks,
|
||||
items: [
|
||||
{ value: 'section', text: i18n.ts._pages.blocks.section },
|
||||
{ value: 'text', text: i18n.ts._pages.blocks.text },
|
||||
{ value: 'image', text: i18n.ts._pages.blocks.image },
|
||||
{ value: 'textarea', text: i18n.ts._pages.blocks.textarea },
|
||||
{ value: 'note', text: i18n.ts._pages.blocks.note },
|
||||
{ value: 'canvas', text: i18n.ts._pages.blocks.canvas },
|
||||
],
|
||||
}, {
|
||||
label: i18n.ts._pages.inputBlocks,
|
||||
items: [
|
||||
{ value: 'button', text: i18n.ts._pages.blocks.button },
|
||||
{ value: 'radioButton', text: i18n.ts._pages.blocks.radioButton },
|
||||
{ value: 'textInput', text: i18n.ts._pages.blocks.textInput },
|
||||
{ value: 'textareaInput', text: i18n.ts._pages.blocks.textareaInput },
|
||||
{ value: 'numberInput', text: i18n.ts._pages.blocks.numberInput },
|
||||
{ value: 'switch', text: i18n.ts._pages.blocks.switch },
|
||||
{ value: 'counter', text: i18n.ts._pages.blocks.counter },
|
||||
],
|
||||
}, {
|
||||
label: i18n.ts._pages.specialBlocks,
|
||||
items: [
|
||||
{ value: 'if', text: i18n.ts._pages.blocks.if },
|
||||
{ value: 'post', text: i18n.ts._pages.blocks.post },
|
||||
],
|
||||
}];
|
||||
}
|
||||
|
||||
function getScriptBlockList(type: string = null) {
|
||||
const list = [];
|
||||
|
||||
const blocks = blockDefs.filter(block => type == null || block.out == null || block.out === type || typeof block.out === 'number');
|
||||
|
||||
for (const block of blocks) {
|
||||
const category = list.find(x => x.category === block.category);
|
||||
if (category) {
|
||||
category.items.push({
|
||||
value: block.type,
|
||||
text: i18n.t(`_pages.script.blocks.${block.type}`),
|
||||
});
|
||||
} else {
|
||||
list.push({
|
||||
category: block.category,
|
||||
label: i18n.t(`_pages.script.categories.${block.category}`),
|
||||
items: [{
|
||||
value: block.type,
|
||||
text: i18n.t(`_pages.script.blocks.${block.type}`),
|
||||
}],
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const userFns = variables.filter(x => x.type === 'fn');
|
||||
if (userFns.length > 0) {
|
||||
list.unshift({
|
||||
label: i18n.t('_pages.script.categories.fn'),
|
||||
items: userFns.map(v => ({
|
||||
value: 'fn:' + v.name,
|
||||
text: v.name,
|
||||
})),
|
||||
});
|
||||
}
|
||||
|
||||
return list;
|
||||
return [
|
||||
{ value: 'section', text: i18n.ts._pages.blocks.section },
|
||||
{ value: 'text', text: i18n.ts._pages.blocks.text },
|
||||
{ value: 'image', text: i18n.ts._pages.blocks.image },
|
||||
{ value: 'note', text: i18n.ts._pages.blocks.note },
|
||||
];
|
||||
}
|
||||
|
||||
function setEyeCatchingImage(img) {
|
||||
@@ -354,21 +229,7 @@ function removeEyeCatchingImage() {
|
||||
eyeCatchingImageId = null;
|
||||
}
|
||||
|
||||
function highlighter(code) {
|
||||
return highlight(code, languages.js, 'javascript');
|
||||
}
|
||||
|
||||
async function init() {
|
||||
hpml = new HpmlTypeChecker();
|
||||
|
||||
watch($$(variables), () => {
|
||||
hpml.variables = variables;
|
||||
}, { deep: true });
|
||||
|
||||
watch($$(content), () => {
|
||||
hpml.pageVars = collectPageVars(content);
|
||||
}, { deep: true });
|
||||
|
||||
if (props.initPageId) {
|
||||
page = await os.api('pages/show', {
|
||||
pageId: props.initPageId,
|
||||
@@ -389,11 +250,9 @@ async function init() {
|
||||
currentName = page.name;
|
||||
summary = page.summary;
|
||||
font = page.font;
|
||||
script = page.script;
|
||||
hideTitleWhenPinned = page.hideTitleWhenPinned;
|
||||
alignCenter = page.alignCenter;
|
||||
content = page.content;
|
||||
variables = page.variables;
|
||||
eyeCatchingImageId = page.eyeCatchingImageId;
|
||||
} else {
|
||||
const id = uuid();
|
||||
@@ -417,14 +276,6 @@ const headerTabs = $computed(() => [{
|
||||
key: 'contents',
|
||||
title: i18n.ts._pages.contents,
|
||||
icon: 'fas fa-sticky-note',
|
||||
}, {
|
||||
key: 'variables',
|
||||
title: i18n.ts._pages.variables,
|
||||
icon: 'fas fa-magic',
|
||||
}, {
|
||||
key: 'script',
|
||||
title: i18n.ts.script,
|
||||
icon: 'ti ti-code',
|
||||
}]);
|
||||
|
||||
definePageMetadata(computed(() => {
|
||||
@@ -442,8 +293,20 @@ definePageMetadata(computed(() => {
|
||||
}));
|
||||
</script>
|
||||
|
||||
<style lang="scss" module>
|
||||
.contents {
|
||||
&:global {
|
||||
> .add {
|
||||
margin: 16px auto 0 auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.jqqmcavi {
|
||||
margin-bottom: 16px;
|
||||
|
||||
> .button {
|
||||
& + .button {
|
||||
margin-left: 8px;
|
||||
|
Reference in New Issue
Block a user