Automate block tree generation
This commit is contained in:
parent
7d6a3730c6
commit
16e0ffdd99
|
@ -1,6 +1,7 @@
|
||||||
import { Component } from 'vue';
|
import { Component } from 'vue';
|
||||||
|
|
||||||
export interface BlockTree {
|
export interface BlockTree {
|
||||||
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
icon?: string;
|
icon?: string;
|
||||||
children?: BlockTree[];
|
children?: BlockTree[];
|
||||||
|
@ -20,7 +21,7 @@ export interface BlockLibraryDefinition {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface BlockProps {
|
export interface BlockProps {
|
||||||
blockId: string;
|
id: string;
|
||||||
data: any;
|
data: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,7 +35,7 @@ export const model = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export const blockProps = {
|
export const blockProps = {
|
||||||
blockId: {
|
id: {
|
||||||
type: String,
|
type: String,
|
||||||
default: () => `${+(new Date())}`,
|
default: () => `${+(new Date())}`,
|
||||||
},
|
},
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
&_active {
|
&_active {
|
||||||
outline: 1px solid var(--grey-2);
|
outline: 4px solid var(--interact);
|
||||||
|
|
||||||
> * > .sb-toolbar {
|
> * > .sb-toolbar {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
|
@ -33,4 +33,8 @@
|
||||||
pointer-events: all;
|
pointer-events: all;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&_highlighted {
|
||||||
|
outline: 2px solid var(--interact);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ import { Block } from '../blocks';
|
||||||
import { SbMode } from '../mode';
|
import { SbMode } from '../mode';
|
||||||
import { useResizeObserver, BlockDimensions } from '../use-resize-observer';
|
import { useResizeObserver, BlockDimensions } from '../use-resize-observer';
|
||||||
import { useActivation } from '../use-activation';
|
import { useActivation } from '../use-activation';
|
||||||
|
import { useBlockTree } from '../use-block-tree';
|
||||||
import { useDynamicBlocks } from '../use-dynamic-blocks';
|
import { useDynamicBlocks } from '../use-dynamic-blocks';
|
||||||
|
|
||||||
import { SbBlockOrdering } from './BlockOrdering';
|
import { SbBlockOrdering } from './BlockOrdering';
|
||||||
|
@ -53,7 +54,11 @@ export const SbBlock = defineComponent({
|
||||||
setup(props: BlockProps, context) {
|
setup(props: BlockProps, context) {
|
||||||
const el: Ref<null|HTMLElement> = ref(null);
|
const el: Ref<null|HTMLElement> = ref(null);
|
||||||
const { mode, getBlock } = useDynamicBlocks();
|
const { mode, getBlock } = useDynamicBlocks();
|
||||||
const { isActive, activate } = useActivation(props.block.blockId);
|
const {
|
||||||
|
isActive,
|
||||||
|
activate,
|
||||||
|
isHighlighted,
|
||||||
|
} = useActivation(props.block.id);
|
||||||
const classes = computed(() => ({
|
const classes = computed(() => ({
|
||||||
'sb-block': true,
|
'sb-block': true,
|
||||||
'sb-block_active': isActive.value,
|
'sb-block_active': isActive.value,
|
||||||
|
@ -62,6 +67,10 @@ export const SbBlock = defineComponent({
|
||||||
const { triggerSizeCalculation } = useResizeObserver(el, BlockDimensions);
|
const { triggerSizeCalculation } = useResizeObserver(el, BlockDimensions);
|
||||||
watch(() => props.block.data, triggerSizeCalculation);
|
watch(() => props.block.data, triggerSizeCalculation);
|
||||||
|
|
||||||
|
const { register } = useBlockTree();
|
||||||
|
register(props.block);
|
||||||
|
watch(props.block, () => { register(props.block); });
|
||||||
|
|
||||||
const onChildUpdate = (updated: {[key: string]: any}) => {
|
const onChildUpdate = (updated: {[key: string]: any}) => {
|
||||||
props.onUpdate({
|
props.onUpdate({
|
||||||
...props.block,
|
...props.block,
|
||||||
|
@ -79,14 +88,14 @@ export const SbBlock = defineComponent({
|
||||||
const MissingBlock = SbMissingBlock[mode.value];
|
const MissingBlock = SbMissingBlock[mode.value];
|
||||||
return <MissingBlock
|
return <MissingBlock
|
||||||
name={props.block.name}
|
name={props.block.name}
|
||||||
blockId={props.block.blockId}
|
blockId={props.block.id}
|
||||||
/>;
|
/>;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mode.value === SbMode.Display) {
|
if (mode.value === SbMode.Display) {
|
||||||
return <BlockComponent
|
return <BlockComponent
|
||||||
data={props.block.data}
|
data={props.block.data}
|
||||||
blockId={props.block.blockId}
|
blockId={props.block.id}
|
||||||
/>;
|
/>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,7 +107,7 @@ export const SbBlock = defineComponent({
|
||||||
{context.slots['context-toolbar'] ? context.slots['context-toolbar']() : null}
|
{context.slots['context-toolbar'] ? context.slots['context-toolbar']() : null}
|
||||||
<BlockComponent
|
<BlockComponent
|
||||||
data={props.block.data}
|
data={props.block.data}
|
||||||
blockId={props.block.blockId}
|
blockId={props.block.id}
|
||||||
onUpdate={onChildUpdate}
|
onUpdate={onChildUpdate}
|
||||||
onPrependBlock={props.onPrependBlock}
|
onPrependBlock={props.onPrependBlock}
|
||||||
onAppendBlock={props.onAppendBlock}
|
onAppendBlock={props.onAppendBlock}
|
||||||
|
|
|
@ -28,7 +28,7 @@ export const SbBlockPicker = defineComponent({
|
||||||
open.value = false;
|
open.value = false;
|
||||||
context.emit('picked-block', {
|
context.emit('picked-block', {
|
||||||
name: block.name,
|
name: block.name,
|
||||||
blockId: `${+(new Date())}`,
|
id: `${+(new Date())}`,
|
||||||
data: block.getDefaultData(),
|
data: block.getDefaultData(),
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
|
@ -12,6 +12,10 @@
|
||||||
margin: 0;
|
margin: 0;
|
||||||
z-index: var(--z-context-menu);
|
z-index: var(--z-context-menu);
|
||||||
|
|
||||||
|
max-height: 70vh;
|
||||||
|
max-width: 100vw;
|
||||||
|
overflow: auto;
|
||||||
|
|
||||||
&[open] {
|
&[open] {
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,18 +3,19 @@ import {
|
||||||
provide,
|
provide,
|
||||||
shallowReactive,
|
shallowReactive,
|
||||||
ref,
|
ref,
|
||||||
watch,
|
|
||||||
PropType,
|
PropType,
|
||||||
Ref,
|
Ref,
|
||||||
} from 'vue';
|
} from 'vue';
|
||||||
import {
|
import {
|
||||||
model,
|
model,
|
||||||
Block,
|
Block,
|
||||||
|
BlockTree,
|
||||||
BlockDefinition,
|
BlockDefinition,
|
||||||
BlockLibraryDefinition,
|
BlockLibraryDefinition,
|
||||||
} from '../blocks';
|
} from '../blocks';
|
||||||
import { Mode, SbMode } from '../mode';
|
import { Mode, SbMode } from '../mode';
|
||||||
import { BlockLibrary } from '../use-dynamic-blocks';
|
import { BlockLibrary } from '../use-dynamic-blocks';
|
||||||
|
import { BlockTreeSym, BlockTreeRegister, BlockTreeUnregister } from '../use-block-tree';
|
||||||
import { EditorDimensions, useResizeObserver } from '../use-resize-observer';
|
import { EditorDimensions, useResizeObserver } from '../use-resize-observer';
|
||||||
import { ActiveBlock } from '../use-activation';
|
import { ActiveBlock } from '../use-activation';
|
||||||
|
|
||||||
|
@ -58,6 +59,11 @@ export const Schlechtenburg = defineComponent({
|
||||||
const activeBlock = ref(null);
|
const activeBlock = ref(null);
|
||||||
provide(ActiveBlock, activeBlock);
|
provide(ActiveBlock, activeBlock);
|
||||||
|
|
||||||
|
const blockTree = ref(null);
|
||||||
|
provide(BlockTreeSym, blockTree);
|
||||||
|
provide(BlockTreeRegister, (block: BlockTree) => { blockTree.value = block; });
|
||||||
|
provide(BlockTreeUnregister, () => { blockTree.value = null; });
|
||||||
|
|
||||||
const blockLibrary: BlockLibraryDefinition = shallowReactive({
|
const blockLibrary: BlockLibraryDefinition = shallowReactive({
|
||||||
...props.customBlocks.reduce(
|
...props.customBlocks.reduce(
|
||||||
(blocks: {[name: string]: Block<any>}, block: Block<any>) => ({ ...blocks, [block.name]: block }),
|
(blocks: {[name: string]: Block<any>}, block: Block<any>) => ({ ...blocks, [block.name]: block }),
|
||||||
|
|
|
@ -1,2 +1,38 @@
|
||||||
.sb-tree-block-select {
|
.sb-tree-block-select {
|
||||||
|
&__list {
|
||||||
|
list-style: none;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
|
||||||
|
&_base {
|
||||||
|
padding-right: 1rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__node {
|
||||||
|
}
|
||||||
|
|
||||||
|
&__block {
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
padding-left: 1rem;
|
||||||
|
|
||||||
|
&-name {
|
||||||
|
display: block;
|
||||||
|
background: transparent;
|
||||||
|
border: 0;
|
||||||
|
font: inherit;
|
||||||
|
color: inherit;
|
||||||
|
padding: 0.5rem 1rem;
|
||||||
|
width: 100%;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
&_active {
|
||||||
|
& > .sb-tree-block-select__block-name {
|
||||||
|
outline: 1px solid var(--interact);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import {
|
import {
|
||||||
computed,
|
|
||||||
defineComponent,
|
defineComponent,
|
||||||
PropType,
|
PropType,
|
||||||
} from 'vue';
|
} from 'vue';
|
||||||
|
@ -7,7 +6,8 @@ import {
|
||||||
Block,
|
Block,
|
||||||
BlockTree,
|
BlockTree,
|
||||||
} from '../blocks';
|
} from '../blocks';
|
||||||
import { useDynamicBlocks } from '../use-dynamic-blocks';
|
import { useBlockTree } from '../use-block-tree';
|
||||||
|
import { useActivation } from '../use-activation';
|
||||||
|
|
||||||
import { SbContextMenu } from './ContextMenu';
|
import { SbContextMenu } from './ContextMenu';
|
||||||
import { SbButton } from './Button';
|
import { SbButton } from './Button';
|
||||||
|
@ -21,42 +21,47 @@ interface TreeBlockSelectProps {
|
||||||
export const SbTreeBlockSelect = defineComponent({
|
export const SbTreeBlockSelect = defineComponent({
|
||||||
name: 'sb-main-menu',
|
name: 'sb-main-menu',
|
||||||
|
|
||||||
props: {
|
setup() {
|
||||||
block: {
|
const { blockTree } = useBlockTree();
|
||||||
type: (null as unknown) as PropType<Block>,
|
const {
|
||||||
required: true,
|
activate,
|
||||||
},
|
activeBlockId,
|
||||||
},
|
} = useActivation();
|
||||||
|
|
||||||
setup(props: TreeBlockSelectProps, context) {
|
const treeToHtml = (tree: BlockTree, close: Function) => <li
|
||||||
const { getBlock } = useDynamicBlocks();
|
class={{
|
||||||
|
'sb-tree-block-select__block': true,
|
||||||
const getTreeForBlock = (block: Block): BlockTree => {
|
'sb-tree-block-select__block_active': activeBlockId.value === tree.id,
|
||||||
const getBlockChildren = getBlock(block.name)?.getChildren;
|
}}
|
||||||
// TODO: vue-jxs apparently cannot parse arrow functions here
|
>
|
||||||
const getChildren = getBlockChildren || function ({ data }) { return data?.children; };
|
<button
|
||||||
const children = getChildren(block) || [];
|
class="sb-tree-block-select__block-name"
|
||||||
return {
|
onClick={() => {
|
||||||
name: block.name,
|
activate(tree.id);
|
||||||
children: children.map(getTreeForBlock),
|
close();
|
||||||
};
|
}}
|
||||||
};
|
onMouseEnter={() => activate(tree.id)}
|
||||||
|
>{tree.name}</button>
|
||||||
const tree = computed(() => getTreeForBlock(props.block));
|
{tree.children.length
|
||||||
|
? <ul class="sb-tree-block-select__list">
|
||||||
const treeToHtml = (tree: BlockTree) => <li>
|
{tree.children.map((child: BlockTree) => treeToHtml(child, close))}
|
||||||
{tree.name}
|
</ul>
|
||||||
{tree.children.length ? <ul>{tree.children.map(treeToHtml)}</ul> : null}
|
: null
|
||||||
|
}
|
||||||
</li>;
|
</li>;
|
||||||
|
|
||||||
return () => (
|
return () => (
|
||||||
<SbContextMenu
|
blockTree.value
|
||||||
class="sb-tree-block-select"
|
? <SbContextMenu
|
||||||
v-slots={{
|
class="sb-tree-block-select"
|
||||||
context: ({ toggle }) => <SbButton onClick={toggle}>Tree</SbButton>,
|
v-slots={{
|
||||||
default: () => <ul>{treeToHtml(tree.value)}</ul>,
|
context: ({ toggle }) => <SbButton onClick={toggle}>Tree</SbButton>,
|
||||||
}}
|
default: ({ close }) => <ul
|
||||||
/>
|
class="sb-tree-block-select__list sb-tree-block-select__list_base"
|
||||||
|
>{treeToHtml(blockTree.value, close)}</ul>,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
: ''
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -6,11 +6,11 @@ import {
|
||||||
} from 'vue';
|
} from 'vue';
|
||||||
|
|
||||||
export const ActiveBlock = Symbol('Schlechtenburg active block');
|
export const ActiveBlock = Symbol('Schlechtenburg active block');
|
||||||
export function useActivation(currentBlockId: string) {
|
export function useActivation(currentBlockId?: string) {
|
||||||
const activeBlockId: Ref<string|null> = inject(ActiveBlock, ref(null));
|
const activeBlockId: Ref<string|null> = inject(ActiveBlock, ref(null));
|
||||||
const isActive = computed(() => activeBlockId.value === currentBlockId);
|
const isActive = computed(() => activeBlockId.value === currentBlockId);
|
||||||
const activate = (blockId?: string|null) => {
|
const activate = (id?: string|null) => {
|
||||||
activeBlockId.value = blockId !== undefined ? blockId : currentBlockId;
|
activeBlockId.value = id !== undefined ? id : currentBlockId;
|
||||||
};
|
};
|
||||||
const requestActivation = () => {
|
const requestActivation = () => {
|
||||||
if (activeBlockId.value) {
|
if (activeBlockId.value) {
|
||||||
|
@ -21,6 +21,7 @@ export function useActivation(currentBlockId: string) {
|
||||||
};
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
activeBlockId,
|
||||||
isActive,
|
isActive,
|
||||||
activate,
|
activate,
|
||||||
requestActivation,
|
requestActivation,
|
||||||
|
|
68
packages/core/lib/use-block-tree.ts
Normal file
68
packages/core/lib/use-block-tree.ts
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
import {
|
||||||
|
Ref,
|
||||||
|
reactive,
|
||||||
|
inject,
|
||||||
|
provide,
|
||||||
|
onUnmounted,
|
||||||
|
} from 'vue';
|
||||||
|
import {
|
||||||
|
BlockTree,
|
||||||
|
Block,
|
||||||
|
} from './blocks';
|
||||||
|
|
||||||
|
export const BlockTreeSym = Symbol('Schlechtenburg block tree');
|
||||||
|
export const BlockTreeRegister = Symbol('Schlechtenburg block tree');
|
||||||
|
export const BlockTreeUnregister = Symbol('Schlechtenburg block tree');
|
||||||
|
export function useBlockTree() {
|
||||||
|
const blockTree: Ref<BlockTree|null> = inject(BlockTreeSym, null);
|
||||||
|
const registerWithParent = inject(BlockTreeRegister, (_: BlockTree) => {});
|
||||||
|
const unregisterWithParent = inject(BlockTreeUnregister, (_: BlockTree) => {});
|
||||||
|
|
||||||
|
const self: BlockTree= reactive({
|
||||||
|
id: '',
|
||||||
|
name: '',
|
||||||
|
icon: '',
|
||||||
|
children: [],
|
||||||
|
});
|
||||||
|
|
||||||
|
// Provide a registration function to child blocks
|
||||||
|
provide(BlockTreeRegister, (block: BlockTree) => {
|
||||||
|
if (self.children.find((child: BlockTree) => child.id === block.id)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.children = [
|
||||||
|
...self.children,
|
||||||
|
block,
|
||||||
|
];
|
||||||
|
});
|
||||||
|
|
||||||
|
// Provide an unregistration function to child blocks
|
||||||
|
provide(BlockTreeUnregister, ({ id }: BlockTree) => {
|
||||||
|
self.children = self.children.filter((child: BlockTree) => child.id !== id);
|
||||||
|
});
|
||||||
|
|
||||||
|
const register = (block: Block) => {
|
||||||
|
if (!block.id) {
|
||||||
|
throw new Error(`Cannot register a block without an id: ${JSON.stringify(block)}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
self.id = block.id;
|
||||||
|
self.name = block.name;
|
||||||
|
|
||||||
|
// Register ourselves at the parent block
|
||||||
|
registerWithParent(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unregister from parent when we get destroyed
|
||||||
|
onUnmounted(() => {
|
||||||
|
if (self.id) {
|
||||||
|
unregisterWithParent(self);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
blockTree,
|
||||||
|
register,
|
||||||
|
};
|
||||||
|
}
|
|
@ -40,7 +40,7 @@ export default defineComponent({
|
||||||
<div class={classes.value}>
|
<div class={classes.value}>
|
||||||
{...props.data.children.map((child) => (
|
{...props.data.children.map((child) => (
|
||||||
<SbBlock
|
<SbBlock
|
||||||
key={child.blockId}
|
key={child.id}
|
||||||
block={child}
|
block={child}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
|
|
|
@ -41,7 +41,7 @@ export default defineComponent({
|
||||||
},
|
},
|
||||||
|
|
||||||
setup(props: LayoutProps) {
|
setup(props: LayoutProps) {
|
||||||
const { activate } = useActivation(props.blockId);
|
const { activate } = useActivation(props.id);
|
||||||
|
|
||||||
const localData: LayoutData = reactive({
|
const localData: LayoutData = reactive({
|
||||||
orientation: props.data.orientation,
|
orientation: props.data.orientation,
|
||||||
|
@ -88,7 +88,7 @@ export default defineComponent({
|
||||||
block,
|
block,
|
||||||
];
|
];
|
||||||
props.onUpdate({ children: [...localData.children] });
|
props.onUpdate({ children: [...localData.children] });
|
||||||
activate(block.blockId);
|
activate(block.id);
|
||||||
};
|
};
|
||||||
|
|
||||||
const insertBlock = (index: number, block: Block) => {
|
const insertBlock = (index: number, block: Block) => {
|
||||||
|
@ -98,7 +98,7 @@ export default defineComponent({
|
||||||
...localData.children.slice(index + 1),
|
...localData.children.slice(index + 1),
|
||||||
];
|
];
|
||||||
props.onUpdate({ children: [...localData.children] });
|
props.onUpdate({ children: [...localData.children] });
|
||||||
activate(block.blockId);
|
activate(block.id);
|
||||||
};
|
};
|
||||||
|
|
||||||
const removeBlock = (index: number) => {
|
const removeBlock = (index: number) => {
|
||||||
|
@ -109,7 +109,7 @@ export default defineComponent({
|
||||||
props.onUpdate({ children: [...localData.children] });
|
props.onUpdate({ children: [...localData.children] });
|
||||||
|
|
||||||
const newActiveIndex = Math.max(index - 1, 0);
|
const newActiveIndex = Math.max(index - 1, 0);
|
||||||
activate(localData.children[newActiveIndex].blockId);
|
activate(localData.children[newActiveIndex].id);
|
||||||
};
|
};
|
||||||
|
|
||||||
const activateBlock = (index: number) => {
|
const activateBlock = (index: number) => {
|
||||||
|
@ -121,7 +121,7 @@ export default defineComponent({
|
||||||
),
|
),
|
||||||
0,
|
0,
|
||||||
);
|
);
|
||||||
activate(localData.children[safeIndex].blockId);
|
activate(localData.children[safeIndex].id);
|
||||||
};
|
};
|
||||||
|
|
||||||
const moveBackward = (index: number) => {
|
const moveBackward = (index: number) => {
|
||||||
|
@ -169,7 +169,7 @@ export default defineComponent({
|
||||||
|
|
||||||
{...localData.children.map((child, index) => (
|
{...localData.children.map((child, index) => (
|
||||||
<SbBlock
|
<SbBlock
|
||||||
{...{ key: child.blockId }}
|
{...{ key: child.id }}
|
||||||
data-order={index}
|
data-order={index}
|
||||||
block={child}
|
block={child}
|
||||||
onUpdate={(updated: Block) => onChildUpdate(child, updated)}
|
onUpdate={(updated: Block) => onChildUpdate(child, updated)}
|
||||||
|
|
|
@ -123,14 +123,14 @@ export default defineComponent({
|
||||||
|
|
||||||
const onKeydown = ($event: KeyboardEvent) => {
|
const onKeydown = ($event: KeyboardEvent) => {
|
||||||
if ($event.key === 'Enter' && !$event.shiftKey) {
|
if ($event.key === 'Enter' && !$event.shiftKey) {
|
||||||
const blockId = `${+(new Date())}`;
|
const id = `${+(new Date())}`;
|
||||||
props.onAppendBlock({
|
props.onAppendBlock({
|
||||||
blockId,
|
id,
|
||||||
name: 'sb-paragraph',
|
name: 'sb-paragraph',
|
||||||
data: getDefaultData(),
|
data: getDefaultData(),
|
||||||
});
|
});
|
||||||
|
|
||||||
activate(blockId);
|
activate(id);
|
||||||
|
|
||||||
$event.preventDefault();
|
$event.preventDefault();
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -22,7 +22,7 @@ export default defineComponent({
|
||||||
const activeTab = ref('edit');
|
const activeTab = ref('edit');
|
||||||
const block: Block<any> = reactive({
|
const block: Block<any> = reactive({
|
||||||
name: 'none',
|
name: 'none',
|
||||||
blockId: '0',
|
id: '0',
|
||||||
data: null,
|
data: null,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ export default defineComponent({
|
||||||
const res = await fetch('/initial-data.json');
|
const res = await fetch('/initial-data.json');
|
||||||
const data = await res.json();
|
const data = await res.json();
|
||||||
block.name = data.name;
|
block.name = data.name;
|
||||||
block.blockId = data.blockId;
|
block.id = data.id;
|
||||||
block.data = data.data;
|
block.data = data.data;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue