129 lines
4.5 KiB
Vue
129 lines
4.5 KiB
Vue
<script setup>
|
|
import treeview from "vue3-treeview";
|
|
import "vue3-treeview/dist/style.css";
|
|
|
|
import { toRef, watch, reactive, watchEffect, onMounted } from 'vue';
|
|
import { initFlowbite } from 'flowbite';
|
|
|
|
onMounted(() => {
|
|
initFlowbite();
|
|
});
|
|
|
|
const props = defineProps({
|
|
block: { type: Object, required: true },
|
|
images: { type: Array }
|
|
});
|
|
|
|
const emit = defineEmits(['update:block']);
|
|
const local = toRef(props, 'block');
|
|
|
|
watch(local, (val) => emit('update:block', val), { deep: true });
|
|
|
|
const treeData = reactive({
|
|
nodes: {},
|
|
config: {
|
|
checkboxes: false,
|
|
dragAndDrop: false,
|
|
editable: false,
|
|
roots: []
|
|
}
|
|
});
|
|
|
|
function buildTreeNodes(images) {
|
|
const nodes = {};
|
|
const roots = [];
|
|
|
|
images.forEach(item => {
|
|
const id = `id${item.id}`
|
|
nodes[id] = {
|
|
nodeId: item.id,
|
|
text: item.name,
|
|
fs_type: item.fs_type,
|
|
fs_meta: item.fs_meta,
|
|
children: images.filter(child => child.parent_id === item.id).map(child => `id${child.id}`),
|
|
};
|
|
|
|
if (item.parent_id === null) roots.push(id);
|
|
})
|
|
|
|
return { nodes, roots };
|
|
}
|
|
|
|
const onNodeClick = (node) => {
|
|
if (node.fs_type === 'file') {
|
|
local.value.image = extractMetaValue(node, 'symbolic_name');
|
|
}
|
|
};
|
|
|
|
watchEffect(() => {
|
|
const { nodes, roots } = buildTreeNodes(props.images);
|
|
treeData.nodes = nodes;
|
|
treeData.config.roots = roots;
|
|
});
|
|
|
|
function extractMetaValue(node, key) {
|
|
let meta = JSON.parse(node.fs_meta);
|
|
return meta[key];
|
|
};
|
|
</script>
|
|
|
|
<template>
|
|
<div class="space-y-4">
|
|
<div class="mb-2">
|
|
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300">Anker navn (DOM ID)</label>
|
|
<input
|
|
type="text"
|
|
class="mt-1 block w-full rounded-md border-gray-300 dark:border-gray-600 shadow-sm focus:border-blue-500 focus:ring-blue-500 dark:bg-gray-800 dark:text-white"
|
|
v-model="local.anchorName"
|
|
/>
|
|
</div>
|
|
|
|
<div class="mb-2">
|
|
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300">Tittel</label>
|
|
<input
|
|
type="text"
|
|
class="mt-1 block w-full rounded-md border-gray-300 dark:border-gray-600 shadow-sm focus:border-blue-500 focus:ring-blue-500 dark:bg-gray-800 dark:text-white"
|
|
v-model="local.title"
|
|
/>
|
|
</div>
|
|
<div class="mb-2">
|
|
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300">Tekst</label>
|
|
<textarea
|
|
rows="3"
|
|
class="mt-1 block w-full rounded-md border-gray-300 dark:border-gray-600 shadow-sm focus:border-blue-500 focus:ring-blue-500 dark:bg-gray-800 dark:text-white"
|
|
v-model="local.text"
|
|
></textarea>
|
|
<span class="text-xs">(Dette feltet er markdown kompatibelt)</span>
|
|
</div>
|
|
|
|
<div class="mb-2">
|
|
<div class="flex">
|
|
<div class="flex items-center h-5">
|
|
<input
|
|
id="prices-checkbox"
|
|
aria-describedby="prices-checkbox-text"
|
|
type="checkbox"
|
|
v-model="local.showprices"
|
|
class="w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded-sm focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600"
|
|
>
|
|
</div>
|
|
<div class="ms-2 text-sm">
|
|
<label for="prices-checkbox" class="font-medium text-gray-900 dark:text-gray-300">Vis prissammendrag</label>
|
|
<p id="prices-checkbox-text" class="text-xs font-normal text-gray-500 dark:text-gray-300">Skru av eller på visningen av prissammendraget nederst i blokken</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div>
|
|
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300">Velg bakgrunnsbilde</label>
|
|
<treeview
|
|
v-if="images && images.length"
|
|
@nodeFocus="onNodeClick"
|
|
:nodes="treeData.nodes"
|
|
:config="treeData.config"
|
|
class="mt-4"
|
|
/>
|
|
</div>
|
|
</div>
|
|
</template>
|